diff --git a/schainpy/graphics/figure.py b/schainpy/graphics/figure.py index 2fc8641..504a538 100644 --- a/schainpy/graphics/figure.py +++ b/schainpy/graphics/figure.py @@ -2,6 +2,8 @@ import mpldriver class Figure: axesList = None + width = None + height = None def __init__(self): pass @@ -36,10 +38,12 @@ class Figure: class Axes: firsttime = None ax = None + mesh = None def __init__(self, ax): self.firsttime = True self.ax = ax + self.mesh = None def pline(self, x, y, xmin, xmax, ymin, ymax, xlabel, ylabel, title): @@ -57,5 +61,21 @@ class Axes: self.firsttime = False - def pcolor(self): - pass + def pcolor(self, x, y, z, xmin, xmax, ymin, ymax, zmin, zmax, xlabel, ylabel, title): + meshfromaxes=mpldriver.pcolor(ax=self.ax, + x=x, + y=y, + z=z, + xmin=xmin, + xmax=xmax, + ymin=ymin, + ymax=ymax, + zmin=zmin, + zmax=zmax, + xlabel=xlabel, + ylabel=ylabel, + title=title, + firsttime=self.firsttime, + mesh=self.mesh) + self.mesh = meshfromaxes + self.firsttime = False diff --git a/schainpy/graphics/mpldriver.py b/schainpy/graphics/mpldriver.py index cf00852..5a217aa 100644 --- a/schainpy/graphics/mpldriver.py +++ b/schainpy/graphics/mpldriver.py @@ -2,6 +2,7 @@ import matplotlib matplotlib.use("TKAgg") import matplotlib.pyplot import scitools.numpyutils +from mpl_toolkits.axes_grid1 import make_axes_locatable def init(idfigure, wintitle, width, height): matplotlib.pyplot.ioff() @@ -42,8 +43,32 @@ def draw(idfigure): fig = matplotlib.pyplot.figure(idfigure) fig.canvas.draw() -def pcolor(): - pass +def pcolor(ax, x, y, z, xmin, xmax, ymin, ymax, zmin, zmax, xlabel, ylabel, title, firsttime, mesh): + if firsttime: + divider = make_axes_locatable(ax) + ax_cb = divider.new_horizontal(size="5%", pad=0.05) + fig1 = ax.get_figure() + fig1.add_axes(ax_cb) + + ax.set_xlim([xmin,xmax]) + ax.set_ylim([ymin,ymax]) + ax.set_xlabel(xlabel) + ax.set_ylabel(ylabel) + ax.set_title(title) + + imesh=ax.pcolormesh(x,y,z,vmin=zmin,vmax=zmax) + matplotlib.pyplot.colorbar(imesh, cax=ax_cb) + ax_cb.yaxis.tick_right() + for tl in ax_cb.get_yticklabels(): + tl.set_visible(True) + ax_cb.yaxis.tick_right() + matplotlib.pyplot.tight_layout() + return imesh + else: + tmp = z[0:-1,0:-1] + mesh.set_array(tmp.ravel()) + + return mesh diff --git a/schainpy/model/jrodataIO.py b/schainpy/model/jrodataIO.py index 41c259e..f3ed588 100644 --- a/schainpy/model/jrodataIO.py +++ b/schainpy/model/jrodataIO.py @@ -232,7 +232,7 @@ class JRODataIO: raise ValueError, "Not implemented" - def getOuput(self): + def getOutput(self): return self.dataOut diff --git a/schainpy/model/jroplot.py b/schainpy/model/jroplot.py index 97d4990..5c64ff1 100644 --- a/schainpy/model/jroplot.py +++ b/schainpy/model/jroplot.py @@ -2,10 +2,107 @@ import numpy import datetime from graphics.figure import * +class SpectraPlot(Figure): + __isConfig = None + + def __init__(self): + self.__isConfig = False + self.width = 850 + self.height = 800 + + def getSubplots(self): + ncol = int(numpy.sqrt(self.nplots)+0.9) + nrow = int(self.nplots*1./ncol + 0.9) + return nrow, ncol + + + def setAxesWithOutProfiles(self, nrow, ncol): + colspan = 1 + rowspan = 1 + counter = 0 + + for y in range(nrow): + for x in range(ncol): + if counter < self.nplots: +# plt.subplot2grid((nrow, ncol), (y, x), colspan=colspan, rowspan=rowspan) + self.makeAxes(nrow, ncol, y, x, colspan, rowspan) + counter += 1 + + def setAxesWithProfiles(self, nrow, ncol): + colspan = 1 + rowspan = 1 + factor = 2 + ncol = ncol*factor + counter = 0 + + for y in range(nrow): + for x in range(ncol): + if counter < self.nplots*factor: +# plt.subplot2grid((nrow, ncol), (y, x), colspan=colspan, rowspan=rowspan) + self.makeAxes(nrow, ncol, y, x, colspan, rowspan) + counter += 1 + + def setup(self, idfigure, wintitle, width, height, nplots, profile): + self.init(idfigure, wintitle, width, height, nplots) + + nrow,ncol = self.getSubplots() + + if profile: + self.setAxesWithProfiles(nrow, ncol) + else: + self.setAxesWithOutProfiles(nrow, ncol) + + def run(self, dataOut, idfigure, wintitle="", channelList=None, xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None, profile=False): + if dataOut.isEmpty(): + return None + + if channelList == None: + channelList = dataOut.channelList + + nplots = len(channelList) + + z = 10.*numpy.log10(dataOut.data_spc[channelList,:,:]) + + y = dataOut.heightList + + x = numpy.arange(dataOut.nFFTPoints) + + if not self.__isConfig: + self.setup(idfigure=idfigure, + wintitle=wintitle, + width=self.width, + height=self.height, + nplots=nplots, + profile=profile) + + if xmin == None: self.xmin = numpy.min(x) + if xmax == None: self.xmax = numpy.max(x) + if ymin == None: self.ymin = numpy.min(y) + if ymax == None: self.ymax = numpy.max(y) + if zmin == None: self.zmin = 0 + if zmax == None: self.zmax = 90 + + self.__isConfig = True + + ylabel = "Range[Km]" + + xlabel = "m/s" + + for i in range(len(self.axesList)): + title = "Channel %d"%i + axes = self.axesList[i] + z2 = z[i,:,:] + axes.pcolor(x, y, z, self.xmin, self.xmax, self.ymin, self.ymax, self.zmin, self.zmax, xlabel, ylabel, title) + + + self.draw() + + + + + class Scope(Figure): __isConfig = None - width = None - height = None def __init__(self): self.__isConfig = False @@ -46,7 +143,7 @@ class Scope(Figure): if not self.__isConfig: self.setup(idfigure=idfigure, - wintitle="Figura 1", + wintitle=wintitle, width=self.width, height=self.height, nplots=nplots) diff --git a/schainpy/model/jroprocessing.py b/schainpy/model/jroprocessing.py index 324baac..2013381 100644 --- a/schainpy/model/jroprocessing.py +++ b/schainpy/model/jroprocessing.py @@ -432,4 +432,144 @@ class CohInt(Operation): dataOut.timeInterval *= self.nCohInt dataOut.nCohInt *= self.nCohInt dataOut.utctime = avgdatatime - dataOut.flagNoData = False \ No newline at end of file + dataOut.flagNoData = False + + +class SpectraProc(ProcessingUnit): + + def __init__(self): + self.objectDict = {} + self.buffer = None + self.firstdatatime = None + self.profIndex = 0 + self.dataOut = Spectra() + + def init(self, nFFTPoints=None, pairsList=None): + if self.dataIn.type == "Spectra": + self.dataOut.copy(self.dataIn) + return + + if self.dataIn.type == "Voltage": + + if nFFTPoints == None: + raise ValueError, "This SpectraProc.setup() need nFFTPoints input variable" + + if pairsList == None: + nPairs = 0 + else: + nPairs = len(pairsList) + + self.dataOut.nFFTPoints = nFFTPoints + self.dataOut.pairsList = pairsList + self.dataOut.nPairs = nPairs + + if self.buffer == None: + self.buffer = numpy.zeros((self.dataIn.nChannels, + self.dataOut.nFFTPoints, + self.dataIn.nHeights), + dtype='complex') + + + self.buffer[:,self.profIndex,:] = self.dataIn.data + self.profIndex += 1 + + if self.firstdatatime == None: + self.firstdatatime = self.dataIn.utctime + + if self.profIndex == self.dataOut.nFFTPoints: + self.__updateObjFromInput() + self.__getFft() + + self.dataOut.flagNoData = False + + self.buffer = None + self.firstdatatime = None + self.profIndex = 0 + + return + + raise ValuError, "The type object %s is not valid"%(self.dataIn.type) + + def __updateObjFromInput(self): + + self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy() + self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy() + self.dataOut.channelList = self.dataIn.channelList + self.dataOut.heightList = self.dataIn.heightList + self.dataOut.dtype = self.dataIn.dtype + self.dataOut.nHeights = self.dataIn.nHeights + self.dataOut.nChannels = self.dataIn.nChannels + self.dataOut.nBaud = self.dataIn.nBaud + self.dataOut.nCode = self.dataIn.nCode + self.dataOut.code = self.dataIn.code + self.dataOut.nProfiles = self.dataOut.nFFTPoints + self.dataOut.channelIndexList = self.dataIn.channelIndexList + self.dataOut.flagTimeBlock = self.dataIn.flagTimeBlock + self.dataOut.utctime = self.firstdatatime + self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada + self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip + self.dataOut.flagShiftFFT = self.dataIn.flagShiftFFT + self.dataOut.nCohInt = self.dataIn.nCohInt + self.dataOut.nIncohInt = 1 + self.dataOut.ippSeconds = self.dataIn.ippSeconds + self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nFFTPoints + + def __getFft(self): + """ + Convierte valores de Voltaje a Spectra + + Affected: + self.dataOut.data_spc + self.dataOut.data_cspc + self.dataOut.data_dc + self.dataOut.heightList + self.dataOut.m_BasicHeader + self.dataOut.m_ProcessingHeader + self.dataOut.radarControllerHeaderObj + self.dataOut.systemHeaderObj + self.profIndex + self.buffer + self.dataOut.flagNoData + self.dataOut.dtype + self.dataOut.nPairs + self.dataOut.nChannels + self.dataOut.nProfiles + self.dataOut.systemHeaderObj.numChannels + self.dataOut.m_ProcessingHeader.totalSpectra + self.dataOut.m_ProcessingHeader.profilesPerBlock + self.dataOut.m_ProcessingHeader.numHeights + self.dataOut.m_ProcessingHeader.spectraComb + self.dataOut.m_ProcessingHeader.shif_fft + """ + fft_volt = numpy.fft.fft(self.buffer,axis=1) + dc = fft_volt[:,0,:] + + #calculo de self-spectra + fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,)) + spc = fft_volt * numpy.conjugate(fft_volt) + spc = spc.real + + blocksize = 0 + blocksize += dc.size + blocksize += spc.size + + cspc = None + pairIndex = 0 + if self.dataOut.pairsList != None: + #calculo de cross-spectra + cspc = numpy.zeros((self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex') + for pair in self.dataOut.pairsList: + cspc[pairIndex,:,:] = numpy.abs(fft_volt[pair[0],:,:] * numpy.conjugate(fft_volt[pair[1],:,:])) + pairIndex += 1 + blocksize += cspc.size + + self.dataOut.data_spc = spc + self.dataOut.data_cspc = cspc + self.dataOut.data_dc = dc + self.dataOut.blockSize = blocksize + + +class IncohInt(Operation): + + def __init__(self): + pass \ No newline at end of file diff --git a/schainpy/test4NewSignalChain.py b/schainpy/test4NewSignalChain.py index 122cae3..ad2c73a 100644 --- a/schainpy/test4NewSignalChain.py +++ b/schainpy/test4NewSignalChain.py @@ -25,6 +25,14 @@ class Test(): opConf2 = self.upConfig.addOperation(name="Scope", priority=2, type="other") opConf2.addParameter(name="idfigure", value=1) + + self.upConfigSpc = controller.UPConf(id=2, name="spectraproc", type="spectra") + opConf = self.upConfigSpc.addOperation(name="init", priority=0) + opConf.addParameter(name="nFFTPoints", value=8) + + opConf3 = self.upConfigSpc.addOperation(name="SpectraPlot", priority=1, type="other") + opConf3.addParameter(name="idfigure", value=2) + # opConf = self.upConfig.addOperation(name="selectChannels", priority=3) # opConf.addParameter(name="channelList", value=[0,1]) @@ -32,6 +40,7 @@ class Test(): ######################################### self.objR = jrodataIO.VoltageReader() self.objP = jroprocessing.VoltageProc() + self.objSpc = jroprocessing.SpectraProc() self.objInt = jroprocessing.CohInt() @@ -41,10 +50,16 @@ class Test(): self.objP.addOperation(self.objScope, opConf2.id) + self.objSpcPlot = jroplot.SpectraPlot() + + self.objSpc.addOperation(self.objSpcPlot, opConf3.id) + self.connect(self.objR, self.objP) + self.connect(self.objP, self.objSpc) + def connect(self, obj1, obj2): - obj2.dataIn = obj1.dataOut + obj2.setInput(obj1.getOutput()) def run(self): @@ -65,6 +80,14 @@ class Test(): kwargs[parm.name]=parm.value self.objP.call(opConf,**kwargs) + + ############################ + for opConfSpc in self.upConfigSpc.getOperationObjList(): + kwargs={} + for parm in opConfSpc.getParameterObjList(): + kwargs[parm.name]=parm.value + + self.objSpc.call(opConfSpc,**kwargs) if self.objR.flagNoMoreFiles: break