diff --git a/README b/README index 7b2047d..2d249ff 100644 --- a/README +++ b/README @@ -1,29 +1,12 @@ -Prerequisites: - -Core: - -numpy 1.8.0 - -scipy - -math - -matplotlib - -h5py - -ftplib - -paramiko (optional for SendTFilesToServer) - -stuffr (optional for jroIO_hf) - -pyfits (Fits data) - -GUI: - -PyQt4 - -wxPython - Signal Chain Installation: - 1. Install numpy, matplotlib, TKAgg + 1. Install system dependencies: python-pip python-dev gfortran libpng-dev freetype* libblas-dev liblapack-dev libatlas-base-dev python-qt4 2. Install digital_rf_hdf5 module (developed by Haystack Observatory) if you want to use USRP data 3. untar schainpy-x.x.x.tar.gz 4. cd schainpy-x.x.x 5. execute: - [hostname]$ sudo pyhon setup.py install + [hostname]$ sudo pip install ./ 6. testing gui: [hostname]$ schainGUI (enter) diff --git a/schainpy/controller.py b/schainpy/controller.py index 36d8ad8..458e919 100644 --- a/schainpy/controller.py +++ b/schainpy/controller.py @@ -343,7 +343,7 @@ class OperationConf(): self.parmConfObjList = [] - parmElementList = opElement.getiterator(ParameterConf().getElementName()) + parmElementList = opElement.iter(ParameterConf().getElementName()) for parmElement in parmElementList: parmConfObj = ParameterConf() @@ -568,7 +568,7 @@ class ProcUnitConf(): self.opConfObjList = [] - opElementList = upElement.getiterator(OperationConf().getElementName()) + opElementList = upElement.iter(OperationConf().getElementName()) for opElement in opElementList: opConfObj = OperationConf() @@ -798,7 +798,7 @@ class ReadUnitConf(ProcUnitConf): self.opConfObjList = [] - opElementList = upElement.getiterator(OperationConf().getElementName()) + opElementList = upElement.iter(OperationConf().getElementName()) for opElement in opElementList: opConfObj = OperationConf() @@ -1026,7 +1026,7 @@ class Project(): self.name = self.projectElement.get('name') self.description = self.projectElement.get('description') - readUnitElementList = self.projectElement.getiterator(ReadUnitConf().getElementName()) + readUnitElementList = self.projectElement.iter(ReadUnitConf().getElementName()) for readUnitElement in readUnitElementList: readUnitConfObj = ReadUnitConf() @@ -1037,7 +1037,7 @@ class Project(): self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj - procUnitElementList = self.projectElement.getiterator(ProcUnitConf().getElementName()) + procUnitElementList = self.projectElement.iter(ProcUnitConf().getElementName()) for procUnitElement in procUnitElementList: procUnitConfObj = ProcUnitConf() diff --git a/schainpy/model/graphics/figure.py b/schainpy/model/graphics/figure.py index beb6e88..508aa2a 100644 --- a/schainpy/model/graphics/figure.py +++ b/schainpy/model/graphics/figure.py @@ -312,7 +312,7 @@ class Axes: decimationy = None __MAXNUMX = 200 - __MAXNUMY = 400 + __MAXNUMY = 100 __MAXNUMTIME = 500 @@ -501,13 +501,15 @@ class Axes: xlen = len(x) ylen = len(y) - decimationx = numpy.floor(xlen/self.__MAXNUMX) - 1 if numpy.floor(xlen/self.__MAXNUMX)>1 else 1 - decimationy = numpy.floor(ylen/self.__MAXNUMY) + 1 - + decimationx = int(xlen/self.__MAXNUMX)+1 \ + if int(xlen/self.__MAXNUMX)>1 else 1 + decimationy = int(ylen/self.__MAXNUMY) \ + if int(ylen/self.__MAXNUMY)>1 else 1 + + x_buffer = x#[::decimationx] + y_buffer = y#[::decimationy] + z_buffer = z#[::decimationx, ::decimationy] - x_buffer = x[::decimationx] - y_buffer = y[::decimationy] - z_buffer = z[::decimationx, ::decimationy] #=================================================== if self.__firsttime: @@ -563,9 +565,9 @@ class Axes: maxNumX = self.__MAXNUMTIME if maxNumY == None: - maxNumY = self.__MAXNUMY + maxNumY = self.__MAXNUMY - if self.__firsttime: + if self.__firsttime: self.z_buffer = z self.x_buffer = numpy.hstack((self.x_buffer, x)) @@ -604,12 +606,14 @@ class Axes: xlen = len(self.x_buffer) ylen = len(y) - decimationx = numpy.floor(xlen/maxNumX) + 1 - decimationy = numpy.floor(ylen/maxNumY) + 1 + decimationx = int(xlen/self.__MAXNUMX) \ + if int(xlen/self.__MAXNUMX)>1 else 1 + decimationy = int(ylen/self.__MAXNUMY) \ + if int(ylen/self.__MAXNUMY)>1 else 1 - x_buffer = self.x_buffer[::decimationx] - y_buffer = y[::decimationy] - z_buffer = z_buffer[::decimationx, ::decimationy] + x_buffer = self.x_buffer#[::decimationx] + y_buffer = y#[::decimationy] + z_buffer = z_buffer#[::decimationx, ::decimationy] #=================================================== x_buffer, y_buffer, z_buffer = self.__fillGaps(x_buffer, y_buffer, z_buffer) diff --git a/schainpy/model/graphics/jroplot_parameters.py b/schainpy/model/graphics/jroplot_parameters.py index 0d41c05..504b64d 100644 --- a/schainpy/model/graphics/jroplot_parameters.py +++ b/schainpy/model/graphics/jroplot_parameters.py @@ -5,6 +5,8 @@ import numpy from figure import Figure, isRealtime, isTimeInHourRange from plotting_codes import * +import matplotlib.pyplot as plt + class MomentsPlot(Figure): isConfig = None @@ -446,11 +448,10 @@ class WindProfilerPlot(Figure): # tmax = None x = dataOut.getTimeRange1(dataOut.outputInterval) -# y = dataOut.heightList y = dataOut.heightList - z = dataOut.data_output.copy() nplots = z.shape[0] #Number of wind dimensions estimated + nplotsw = nplots #If there is a SNR function defined @@ -458,20 +459,21 @@ class WindProfilerPlot(Figure): nplots += 1 SNR = dataOut.data_SNR SNRavg = numpy.average(SNR, axis=0) - + SNRdB = 10*numpy.log10(SNR) SNRavgdB = 10*numpy.log10(SNRavg) - + if SNRthresh == None: SNRthresh = -5.0 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0] - + for i in range(nplotsw): z[i,ind] = numpy.nan - + # showprofile = False # thisDatetime = dataOut.datatime - thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime) + #thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime) + thisDatetime = datetime.datetime.now() title = wintitle + "Wind" xlabel = "" ylabel = "Height (km)" @@ -490,8 +492,8 @@ class WindProfilerPlot(Figure): self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange) - if ymin == None: ymin = numpy.nanmin(y) - if ymax == None: ymax = numpy.nanmax(y) + #if ymin == None: ymin = numpy.nanmin(y) + #if ymax == None: ymax = numpy.nanmax(y) if zmax == None: zmax = numpy.nanmax(abs(z[range(2),:])) #if numpy.isnan(zmax): zmax = 50 @@ -501,9 +503,9 @@ class WindProfilerPlot(Figure): if zmax_ver == None: zmax_ver = numpy.nanmax(abs(z[2,:])) if zmin_ver == None: zmin_ver = -zmax_ver - if dataOut.data_SNR is not None: - if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB) - if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB) +# if dataOut.data_SNR is not None: +# if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB) +# if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB) self.FTP_WEI = ftp_wei @@ -518,8 +520,8 @@ class WindProfilerPlot(Figure): self.setWinTitle(title) - if ((self.xmax - x[1]) < (x[1]-x[0])): - x[1] = self.xmax + #if ((self.xmax - x[1]) < (x[1]-x[0])): + # x[1] = self.xmax strWind = ['Zonal', 'Meridional', 'Vertical'] strCb = ['Velocity (m/s)','Velocity (m/s)','Velocity (cm/s)'] @@ -533,7 +535,7 @@ class WindProfilerPlot(Figure): axes = self.axesList[i*self.__nsubplots] z1 = z[i,:].reshape((1,-1))*windFactor[i] - + axes.pcolorbuffer(x, y, z1, xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i], xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True, @@ -543,9 +545,9 @@ class WindProfilerPlot(Figure): i += 1 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S")) axes = self.axesList[i*self.__nsubplots] - + SNRavgdB = SNRavgdB.reshape((1,-1)) - + axes.pcolorbuffer(x, y, SNRavgdB, xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax, xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True, @@ -561,8 +563,8 @@ class WindProfilerPlot(Figure): thisDatetime=thisDatetime, update_figfile=update_figfile) - if dataOut.ltctime + dataOut.outputInterval >= self.xmax: - self.counter_imagwr = wr_period + if False and dataOut.ltctime + dataOut.outputInterval >= self.xmax: + self.counter_imagwr = wr_period self.isConfig = False update_figfile = True @@ -778,7 +780,7 @@ class ParametersPlot(Figure): -class Parameters1Plot(Figure): +class ParametersPlot(Figure): __isConfig = None __nsubplots = None diff --git a/schainpy/model/graphics/jroplot_spectra.py b/schainpy/model/graphics/jroplot_spectra.py index e17c9a9..0f7b38d 100644 --- a/schainpy/model/graphics/jroplot_spectra.py +++ b/schainpy/model/graphics/jroplot_spectra.py @@ -86,7 +86,7 @@ class SpectraPlot(Figure): save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1, server=None, folder=None, username=None, password=None, ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False, - xaxis="frequency", colormap='jet'): + xaxis="velocity", **kwargs): """ @@ -104,6 +104,8 @@ class SpectraPlot(Figure): zmax : None """ + colormap = kwargs.get('colormap','jet') + if realtime: if not(isRealtime(utcdatatime = dataOut.utctime)): print 'Skipping this plot function' @@ -514,10 +516,10 @@ class RTIPlot(Figure): def run(self, dataOut, id, wintitle="", channelList=None, showprofile='True', xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None, - timerange=None, colormap='jet', + timerange=None, save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True, server=None, folder=None, username=None, password=None, - ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0): + ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, **kwargs): """ @@ -535,6 +537,7 @@ class RTIPlot(Figure): zmax : None """ + colormap = kwargs.get('colormap', 'jet') if not isTimeInHourRange(dataOut.datatime, xmin, xmax): return diff --git a/schainpy/model/graphics/mpldriver.py b/schainpy/model/graphics/mpldriver.py index 6749ec4..31a5b1f 100644 --- a/schainpy/model/graphics/mpldriver.py +++ b/schainpy/model/graphics/mpldriver.py @@ -18,6 +18,8 @@ from matplotlib.ticker import FuncFormatter, LinearLocator #Actualizacion de las funciones del driver ########################################### +# create jro colormap + jet_values = matplotlib.pyplot.get_cmap("jet", 100)(numpy.arange(100))[10:90] blu_values = matplotlib.pyplot.get_cmap("seismic_r", 20)(numpy.arange(20))[10:15] ncmap = matplotlib.colors.LinearSegmentedColormap.from_list("jro", numpy.vstack((blu_values, jet_values))) @@ -202,7 +204,7 @@ def createPcolor(ax, x, y, z, xmin, xmax, ymin, ymax, zmin, zmax, z = numpy.ma.masked_invalid(z) cmap=matplotlib.pyplot.get_cmap(colormap) - cmap.set_bad('white',1.) + cmap.set_bad('white', 1.) imesh = ax.pcolormesh(x,y,z.T, vmin=zmin, vmax=zmax, cmap=cmap) cb = matplotlib.pyplot.colorbar(imesh, cax=ax_cb) cb.set_label(cblabel) @@ -262,7 +264,7 @@ def addpcolorbuffer(ax, x, y, z, zmin, zmax, xlabel='', ylabel='', title='', col z = numpy.ma.masked_invalid(z) cmap=matplotlib.pyplot.get_cmap(colormap) - cmap.set_bad('white',1.) + cmap.set_bad('white', 1.) ax.pcolormesh(x,y,z.T,vmin=zmin,vmax=zmax, cmap=cmap) diff --git a/schainpy/model/io/__init__.py b/schainpy/model/io/__init__.py index 48a5868..59bf3cb 100644 --- a/schainpy/model/io/__init__.py +++ b/schainpy/model/io/__init__.py @@ -11,4 +11,4 @@ from jroIO_usrp import * from jroIO_kamisr import * from jroIO_param import * -from jroIO_hf import * \ No newline at end of file +from jroIO_hf import * diff --git a/schainpy/model/io/jroIO_param.py b/schainpy/model/io/jroIO_param.py index 9e221fa..baf24d1 100644 --- a/schainpy/model/io/jroIO_param.py +++ b/schainpy/model/io/jroIO_param.py @@ -399,70 +399,7 @@ class ParamReader(ProcessingUnit): self.listData = listdata return - def __setDataArray(self, dataset, shapes): - - nDims = shapes[0] - - nDim2 = shapes[1] #Dimension 0 - nDim1 = shapes[2] #Dimension 1, number of Points or Parameters - - nDim0 = shapes[3] #Dimension 2, number of samples or ranges - - mode = shapes[4] #Mode of storing - - blockList = self.blockList - - blocksPerFile = self.blocksPerFile - - #Depending on what mode the data was stored - if mode == 0: #Divided in channels - arrayData = dataset.value.astype(numpy.float)[0][blockList] - if mode == 1: #Divided in parameter - strds = 'table' - nDatas = nDim1 - newShapes = (blocksPerFile,nDim2,nDim0) - elif mode==2: #Concatenated in a table - strds = 'table0' - arrayData = dataset[strds].value - #Selecting part of the dataset - utctime = arrayData[:,0] - u, indices = numpy.unique(utctime, return_index=True) - - if blockList.size != indices.size: - indMin = indices[blockList[0]] - if blockList[-1] + 1 >= indices.size: - arrayData = arrayData[indMin:,:] - else: - indMax = indices[blockList[-1] + 1] - arrayData = arrayData[indMin:indMax,:] - return arrayData - - #------- One dimension --------------- - if nDims == 0: - arrayData = dataset.value.astype(numpy.float)[0][blockList] - - #------- Two dimensions ----------- - elif nDims == 2: - arrayData = numpy.zeros((blocksPerFile,nDim1,nDim0)) - newShapes = (blocksPerFile,nDim0) - nDatas = nDim1 - - for i in range(nDatas): - data = dataset[strds + str(i)].value - arrayData[:,i,:] = data[blockList,:] - - #------- Three dimensions --------- - else: - arrayData = numpy.zeros((blocksPerFile,nDim2,nDim1,nDim0)) - for i in range(nDatas): - - data = dataset[strds + str(i)].value - - for b in range(blockList.size): - arrayData[b,:,i,:] = data[:,:,blockList[b]] - - return arrayData def __setDataOut(self): listMeta = self.listMeta diff --git a/schainpy/model/io/jroIO_spectra.py b/schainpy/model/io/jroIO_spectra.py index dc9eddc..aba11f2 100644 --- a/schainpy/model/io/jroIO_spectra.py +++ b/schainpy/model/io/jroIO_spectra.py @@ -571,8 +571,10 @@ class SpectraWriter(JRODataWriter, Operation): if self.dataOut.flagDiscontinuousBlock: self.data_spc.fill(0) - self.data_cspc.fill(0) - self.data_dc.fill(0) + if self.dataOut.data_cspc is not None: + self.data_cspc.fill(0) + if self.dataOut.data_dc is not None: + self.data_dc.fill(0) self.setNextFile() if self.flagIsNewFile == 0: diff --git a/schainpy/model/proc/jroproc_base.py b/schainpy/model/proc/jroproc_base.py index 4aba04e..a9b3cb0 100644 --- a/schainpy/model/proc/jroproc_base.py +++ b/schainpy/model/proc/jroproc_base.py @@ -5,93 +5,93 @@ $Id: jroproc_base.py 1 2012-11-12 18:56:07Z murco $ ''' class ProcessingUnit(object): - + """ Esta es la clase base para el procesamiento de datos. - + Contiene el metodo "call" para llamar operaciones. Las operaciones pueden ser: - Metodos internos (callMethod) - Objetos del tipo Operation (callObject). Antes de ser llamados, estos objetos tienen que ser agreagados con el metodo "add". - + """ # objeto de datos de entrada (Voltage, Spectra o Correlation) dataIn = None dataInList = [] - + # objeto de datos de entrada (Voltage, Spectra o Correlation) dataOut = None - + operations2RunDict = None - + isConfig = False - - + + def __init__(self): - + self.dataIn = None self.dataInList = [] - + self.dataOut = None - + self.operations2RunDict = {} - + self.isConfig = False - + def addOperation(self, opObj, objId): - + """ Agrega un objeto del tipo "Operation" (opObj) a la lista de objetos "self.objectList" y retorna el - identificador asociado a este objeto. - + identificador asociado a este objeto. + Input: - + object : objeto de la clase "Operation" - + Return: - + objId : identificador del objeto, necesario para ejecutar la operacion """ - + self.operations2RunDict[objId] = opObj - + return objId - + def getOperationObj(self, objId): - + if objId not in self.operations2RunDict.keys(): return None - + return self.operations2RunDict[objId] - + def operation(self, **kwargs): - + """ Operacion directa sobre la data (dataOut.data). Es necesario actualizar los valores de los atributos del objeto dataOut - + Input: - + **kwargs : Diccionario de argumentos de la funcion a ejecutar """ - + raise NotImplementedError - + def callMethod(self, name, **kwargs): - + """ Ejecuta el metodo con el nombre "name" y con argumentos **kwargs de la propia clase. - + Input: name : nombre del metodo a ejecutar - + **kwargs : diccionario con los nombres y valores de la funcion a ejecutar. - + """ - + #Checking the inputs if name == 'run': - + if not self.checkInputs(): self.dataOut.flagNoData = True return False @@ -99,196 +99,196 @@ class ProcessingUnit(object): #Si no es un metodo RUN la entrada es la misma dataOut (interna) if self.dataOut.isEmpty(): return False - + #Getting the pointer to method methodToCall = getattr(self, name) - + #Executing the self method methodToCall(**kwargs) - + #Checkin the outputs - + # if name == 'run': # pass # else: # pass -# +# # if name != 'run': # return True - + if self.dataOut is None: return False - + if self.dataOut.isEmpty(): return False - + return True - + def callObject(self, objId, **kwargs): - + """ Ejecuta la operacion asociada al identificador del objeto "objId" - + Input: - + objId : identificador del objeto a ejecutar - + **kwargs : diccionario con los nombres y valores de la funcion a ejecutar. - + Return: - - None + + None """ - + if self.dataOut.isEmpty(): return False - + externalProcObj = self.operations2RunDict[objId] - + externalProcObj.run(self.dataOut, **kwargs) - + return True - + def call(self, opType, opName=None, opId=None, **kwargs): - + """ Return True si ejecuta la operacion interna nombrada "opName" o la operacion externa identificada con el id "opId"; con los argumentos "**kwargs". - + False si la operacion no se ha ejecutado. - + Input: - + opType : Puede ser "self" o "external" - + Depende del tipo de operacion para llamar a:callMethod or callObject: - + 1. If opType = "self": Llama a un metodo propio de esta clase: - + name_method = getattr(self, name) name_method(**kwargs) - - + + 2. If opType = "other" o"external": Llama al metodo "run()" de una instancia de la clase "Operation" o de un derivado de ella: - + instanceName = self.operationList[opId] instanceName.run(**kwargs) - + opName : Si la operacion es interna (opType = 'self'), entonces el "opName" sera usada para llamar a un metodo interno de la clase Processing - + opId : Si la operacion es externa (opType = 'other' o 'external), entonces el "opId" sera usada para llamar al metodo "run" de la clase Operation registrada anteriormente con ese Id - + Exception: Este objeto de tipo Operation debe de haber sido agregado antes con el metodo: "addOperation" e identificado con el valor "opId" = el id de la operacion. De lo contrario retornara un error del tipo ValueError - + """ - + if opType == 'self': - + if not opName: raise ValueError, "opName parameter should be defined" - + sts = self.callMethod(opName, **kwargs) - + elif opType == 'other' or opType == 'external' or opType == 'plotter': - + if not opId: raise ValueError, "opId parameter should be defined" - + if opId not in self.operations2RunDict.keys(): raise ValueError, "Any operation with id=%s has been added" %str(opId) - + sts = self.callObject(opId, **kwargs) - + else: raise ValueError, "opType should be 'self', 'external' or 'plotter'; and not '%s'" %opType - - return sts - + + return sts + def setInput(self, dataIn): - + self.dataIn = dataIn self.dataInList.append(dataIn) - + def getOutputObj(self): - + return self.dataOut - + def checkInputs(self): for thisDataIn in self.dataInList: - + if thisDataIn.isEmpty(): return False - + return True - + def setup(self): - + raise NotImplementedError - + def run(self): - + raise NotImplementedError - + def close(self): #Close every thread, queue or any other object here is it is neccesary. return - + class Operation(object): - + """ Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de acumulacion dentro de esta clase - + Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer) - + """ - + __buffer = None isConfig = False - + def __init__(self): - + self.__buffer = None self.isConfig = False - + def setup(self): - + self.isConfig = True - + raise NotImplementedError def run(self, dataIn, **kwargs): - + """ Realiza las operaciones necesarias sobre la dataIn.data y actualiza los atributos del objeto dataIn. - + Input: - + dataIn : objeto del tipo JROData - + Return: - + None - + Affected: __buffer : buffer de recepcion de datos. - + """ if not self.isConfig: self.setup(**kwargs) - + raise NotImplementedError - + def close(self): - - pass \ No newline at end of file + + pass diff --git a/schainpy/model/proc/jroproc_heispectra.py b/schainpy/model/proc/jroproc_heispectra.py index 9411b7c..2564309 100644 --- a/schainpy/model/proc/jroproc_heispectra.py +++ b/schainpy/model/proc/jroproc_heispectra.py @@ -33,6 +33,8 @@ class SpectraHeisProc(ProcessingUnit): self.dataOut.nCode = self.dataIn.nCode self.dataOut.code = self.dataIn.code # self.dataOut.nProfiles = 1 + self.dataOut.ippFactor = 1 + self.dataOut.noise_estimation = None # self.dataOut.nProfiles = self.dataOut.nFFTPoints self.dataOut.nFFTPoints = self.dataIn.nHeights # self.dataOut.channelIndexList = self.dataIn.channelIndexList diff --git a/schainpy/model/utils/__init__.py b/schainpy/model/utils/__init__.py index f8ea804..0359aa1 100644 --- a/schainpy/model/utils/__init__.py +++ b/schainpy/model/utils/__init__.py @@ -5,4 +5,4 @@ $Id: Processor.py 1 2012-11-12 18:56:07Z murco $ ''' from jroutils_ftp import * -from jroutils_publish import PublishData \ No newline at end of file +from jroutils_publish import * diff --git a/schainpy/model/utils/jroutils_publish.py b/schainpy/model/utils/jroutils_publish.py index 2007f9c..796306f 100644 --- a/schainpy/model/utils/jroutils_publish.py +++ b/schainpy/model/utils/jroutils_publish.py @@ -9,94 +9,144 @@ import paho.mqtt.client as mqtt from schainpy.model.proc.jroproc_base import Operation - class PrettyFloat(float): def __repr__(self): return '%.2f' % self + def pretty_floats(obj): if isinstance(obj, float): return PrettyFloat(obj) elif isinstance(obj, dict): return dict((k, pretty_floats(v)) for k, v in obj.items()) elif isinstance(obj, (list, tuple)): - return map(pretty_floats, obj) + return map(pretty_floats, obj) return obj + class PublishData(Operation): - + """Clase publish.""" + __MAXNUMX = 80 __MAXNUMY = 80 - + def __init__(self): - + """Inicio.""" Operation.__init__(self) - self.isConfig = False - self.client = None - - @staticmethod - def on_disconnect(client, userdata, rc): + self.client = None + + def on_disconnect(self, client, userdata, rc): if rc != 0: - print("Unexpected disconnection.") - - def setup(self, host, port=1883, username=None, password=None, **kwargs): - - self.client = mqtt.Client() + print("Unexpected disconnection.") + self.connect() + + def connect(self): + print 'trying to connect' try: - self.client.connect(host=host, port=port, keepalive=60*10, bind_address='') + self.client.connect( + host=self.host, + port=self.port, + keepalive=60*10, + bind_address='') + print "connected" + self.client.loop_start() + # self.client.publish( + # self.topic + 'SETUP', + # json.dumps(setup), + # retain=True + # ) except: + print "MQTT Conection error." self.client = False + + def setup(self, host, port=1883, username=None, password=None, **kwargs): + self.topic = kwargs.get('topic', 'schain') self.delay = kwargs.get('delay', 0) + self.plottype = kwargs.get('plottype', 'spectra') self.host = host self.port = port self.cnt = 0 - - def run(self, dataOut, host, datatype='data_spc', **kwargs): - - if not self.isConfig: + setup = [] + for plot in self.plottype: + setup.append({ + 'plot': plot, + 'topic': self.topic + plot, + 'title': getattr(self, plot + '_' + 'title', False), + 'xlabel': getattr(self, plot + '_' + 'xlabel', False), + 'ylabel': getattr(self, plot + '_' + 'ylabel', False), + 'xrange': getattr(self, plot + '_' + 'xrange', False), + 'yrange': getattr(self, plot + '_' + 'yrange', False), + 'zrange': getattr(self, plot + '_' + 'zrange', False), + }) + self.client = mqtt.Client( + client_id='jc'+self.topic + 'SCHAIN', + clean_session=True) + self.client.on_disconnect = self.on_disconnect + self.connect() + + def publish_data(self, plottype): + data = getattr(self.dataOut, 'data_spc') + if plottype == 'spectra': + z = data/self.dataOut.normFactor + zdB = 10*numpy.log10(z) + xlen, ylen = zdB[0].shape + dx = numpy.floor(xlen/self.__MAXNUMX) + 1 + dy = numpy.floor(ylen/self.__MAXNUMY) + 1 + Z = [0 for i in self.dataOut.channelList] + for i in self.dataOut.channelList: + Z[i] = zdB[i][::dx, ::dy].tolist() + payload = { + 'timestamp': self.dataOut.utctime, + 'data': pretty_floats(Z), + 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList], + 'interval': self.dataOut.getTimeInterval(), + 'xRange': [0, 80] + } + + elif plottype in ('rti', 'power'): + z = data/self.dataOut.normFactor + avg = numpy.average(z, axis=1) + avgdB = 10*numpy.log10(avg) + xlen, ylen = z[0].shape + dy = numpy.floor(ylen/self.__MAXNUMY) + 1 + AVG = [0 for i in self.dataOut.channelList] + for i in self.dataOut.channelList: + AVG[i] = avgdB[i][::dy].tolist() + payload = { + 'timestamp': self.dataOut.utctime, + 'data': pretty_floats(AVG), + 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList], + 'interval': self.dataOut.getTimeInterval(), + 'xRange': [0, 80] + } + elif plottype == 'noise': + noise = self.dataOut.getNoise()/self.dataOut.normFactor + noisedB = 10*numpy.log10(noise) + payload = { + 'timestamp': self.dataOut.utctime, + 'data': pretty_floats(noisedB.reshape(-1, 1).tolist()), + 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList], + 'interval': self.dataOut.getTimeInterval(), + 'xRange': [0, 80] + } + + print 'Publishing data to {}'.format(self.host) + print '*************************' + self.client.publish(self.topic + plottype, json.dumps(payload), qos=0) + + + def run(self, dataOut, host, **kwargs): + self.dataOut = dataOut + if not self.isConfig: self.setup(host, **kwargs) self.isConfig = True - - data = getattr(dataOut, datatype) - - z = data/dataOut.normFactor - zdB = 10*numpy.log10(z) - avg = numpy.average(z, axis=1) - avgdB = 10*numpy.log10(avg) - - xlen ,ylen = zdB[0].shape - - - dx = numpy.floor(xlen/self.__MAXNUMX) + 1 - dy = numpy.floor(ylen/self.__MAXNUMY) + 1 - - Z = [0 for i in dataOut.channelList] - AVG = [0 for i in dataOut.channelList] - - for i in dataOut.channelList: - Z[i] = zdB[i][::dx, ::dy].tolist() - AVG[i] = avgdB[i][::dy].tolist() - - payload = {'timestamp':dataOut.utctime, - 'data':pretty_floats(Z), - 'data_profile':pretty_floats(AVG), - 'channels': ['Ch %s' % ch for ch in dataOut.channelList], - 'interval': dataOut.getTimeInterval(), - } - - - #if self.cnt==self.interval and self.client: - print 'Publishing data to {}'.format(self.host) - self.client.publish(self.topic, json.dumps(payload), qos=0) - time.sleep(self.delay) - #self.cnt = 0 - #else: - # self.cnt += 1 - - + + map(self.publish_data, self.plottype) + time.sleep(self.delay) + def close(self): - - if self.client: - self.client.disconnect() \ No newline at end of file + if self.client: + self.client.loop_stop() + self.client.disconnect() diff --git a/setup.py b/setup.py index 46a06dd..6e0fa86 100644 --- a/setup.py +++ b/setup.py @@ -33,8 +33,12 @@ setup(name="schainpy", include_package_data=False, scripts =['schainpy/gui/schainGUI', 'schainpy/scripts/schain'], - install_requires=["numpy >= 1.6.0", + install_requires=[ "scipy >= 0.9.0", + "h5py >= 2.0.1", "matplotlib >= 1.0.0", + "pyfits >= 2.0.0", + "numpy >= 1.6.0", + "paramiko", ], ) \ No newline at end of file