jroproc_heispectra.py
344 lines
| 10.1 KiB
| text/x-python
|
PythonLexer
|
r487 | import numpy | ||
from jroproc_base import ProcessingUnit, Operation | ||||
|
r568 | from schainpy.model.data.jrodata import SpectraHeis | ||
|
r487 | |||
class SpectraHeisProc(ProcessingUnit): | ||||
|
r897 | |||
def __init__(self, **kwargs): | ||||
ProcessingUnit.__init__(self, **kwargs) | ||||
|
r487 | # self.buffer = None | ||
# self.firstdatatime = None | ||||
# self.profIndex = 0 | ||||
self.dataOut = SpectraHeis() | ||||
|
r587 | def __updateObjFromVoltage(self): | ||
|
r897 | |||
|
r487 | self.dataOut.timeZone = self.dataIn.timeZone | ||
self.dataOut.dstFlag = self.dataIn.dstFlag | ||||
self.dataOut.errorCount = self.dataIn.errorCount | ||||
self.dataOut.useLocalTime = self.dataIn.useLocalTime | ||||
|
r897 | |||
|
r487 | 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.dtype = numpy.dtype([('real','<f4'),('imag','<f4')]) | ||||
# 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 = 1 | ||||
|
r860 | self.dataOut.ippFactor = 1 | ||
self.dataOut.noise_estimation = None | ||||
|
r487 | # self.dataOut.nProfiles = self.dataOut.nFFTPoints | ||
self.dataOut.nFFTPoints = self.dataIn.nHeights | ||||
# self.dataOut.channelIndexList = self.dataIn.channelIndexList | ||||
# self.dataOut.flagNoData = self.dataIn.flagNoData | ||||
|
r568 | self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock | ||
|
r487 | self.dataOut.utctime = self.dataIn.utctime | ||
# 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.windowOfFilter = self.dataIn.windowOfFilter | ||||
|
r897 | |||
|
r587 | # self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nIncohInt | ||
|
r487 | # self.dataOut.set=self.dataIn.set | ||
# self.dataOut.deltaHeight=self.dataIn.deltaHeight | ||||
def __updateObjFromFits(self): | ||||
|
r897 | |||
|
r487 | self.dataOut.utctime = self.dataIn.utctime | ||
|
r664 | # self.dataOut.channelIndexList = self.dataIn.channelIndexList | ||
|
r897 | |||
|
r487 | self.dataOut.channelList = self.dataIn.channelList | ||
self.dataOut.heightList = self.dataIn.heightList | ||||
self.dataOut.data_spc = self.dataIn.data | ||||
|
r587 | self.dataOut.ippSeconds = self.dataIn.ippSeconds | ||
self.dataOut.nCohInt = self.dataIn.nCohInt | ||||
self.dataOut.nIncohInt = self.dataIn.nIncohInt | ||||
# self.dataOut.timeInterval = self.dataIn.timeInterval | ||||
|
r487 | self.dataOut.timeZone = self.dataIn.timeZone | ||
self.dataOut.useLocalTime = True | ||||
# self.dataOut. | ||||
# self.dataOut. | ||||
def __getFft(self): | ||||
|
r897 | |||
|
r487 | fft_volt = numpy.fft.fft(self.dataIn.data, axis=1) | ||
fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,)) | ||||
spc = numpy.abs(fft_volt * numpy.conjugate(fft_volt))/(self.dataOut.nFFTPoints) | ||||
self.dataOut.data_spc = spc | ||||
def run(self): | ||||
self.dataOut.flagNoData = True | ||||
|
r897 | |||
|
r487 | if self.dataIn.type == "Fits": | ||
self.__updateObjFromFits() | ||||
self.dataOut.flagNoData = False | ||||
return | ||||
|
r897 | |||
|
r487 | if self.dataIn.type == "SpectraHeis": | ||
self.dataOut.copy(self.dataIn) | ||||
return | ||||
|
r897 | |||
|
r487 | if self.dataIn.type == "Voltage": | ||
|
r587 | self.__updateObjFromVoltage() | ||
|
r487 | self.__getFft() | ||
self.dataOut.flagNoData = False | ||||
|
r897 | |||
|
r487 | return | ||
|
r897 | |||
|
r487 | raise ValueError, "The type object %s is not valid"%(self.dataIn.type) | ||
|
r897 | |||
|
r487 | def selectChannels(self, channelList): | ||
|
r897 | |||
|
r487 | channelIndexList = [] | ||
|
r897 | |||
|
r487 | for channel in channelList: | ||
index = self.dataOut.channelList.index(channel) | ||||
channelIndexList.append(index) | ||||
|
r897 | |||
|
r487 | self.selectChannelsByIndex(channelIndexList) | ||
|
r897 | |||
|
r487 | def selectChannelsByIndex(self, channelIndexList): | ||
""" | ||||
|
r897 | Selecciona un bloque de datos en base a canales segun el channelIndexList | ||
|
r487 | Input: | ||
|
r897 | channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7] | ||
|
r487 | Affected: | ||
self.dataOut.data | ||||
self.dataOut.channelIndexList | ||||
self.dataOut.nChannels | ||||
self.dataOut.m_ProcessingHeader.totalSpectra | ||||
self.dataOut.systemHeaderObj.numChannels | ||||
self.dataOut.m_ProcessingHeader.blockSize | ||||
|
r897 | |||
|
r487 | Return: | ||
None | ||||
""" | ||||
|
r897 | |||
|
r487 | for channelIndex in channelIndexList: | ||
if channelIndex not in self.dataOut.channelIndexList: | ||||
print channelIndexList | ||||
raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex | ||||
|
r897 | |||
|
r487 | # nChannels = len(channelIndexList) | ||
|
r897 | |||
|
r487 | data_spc = self.dataOut.data_spc[channelIndexList,:] | ||
|
r897 | |||
|
r487 | self.dataOut.data_spc = data_spc | ||
self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList] | ||||
|
r897 | |||
|
r487 | return 1 | ||
class IncohInt4SpectraHeis(Operation): | ||||
|
r897 | |||
|
r487 | isConfig = False | ||
|
r897 | |||
|
r487 | __profIndex = 0 | ||
__withOverapping = False | ||||
|
r897 | |||
|
r487 | __byTime = False | ||
__initime = None | ||||
__lastdatatime = None | ||||
__integrationtime = None | ||||
|
r897 | |||
|
r487 | __buffer = None | ||
|
r897 | |||
|
r487 | __dataReady = False | ||
|
r897 | |||
|
r487 | n = None | ||
|
r897 | |||
def __init__(self, **kwargs): | ||||
Operation.__init__(self, **kwargs) | ||||
|
r487 | # self.isConfig = False | ||
|
r897 | |||
|
r487 | def setup(self, n=None, timeInterval=None, overlapping=False): | ||
""" | ||||
Set the parameters of the integration class. | ||||
|
r897 | |||
|
r487 | Inputs: | ||
|
r897 | |||
|
r487 | n : Number of coherent integrations | ||
timeInterval : Time of integration. If the parameter "n" is selected this one does not work | ||||
|
r897 | overlapping : | ||
|
r487 | """ | ||
|
r897 | |||
|
r487 | self.__initime = None | ||
self.__lastdatatime = 0 | ||||
self.__buffer = None | ||||
self.__dataReady = False | ||||
|
r897 | |||
|
r487 | if n == None and timeInterval == None: | ||
|
r897 | raise ValueError, "n or timeInterval should be specified ..." | ||
|
r487 | if n != None: | ||
self.n = n | ||||
self.__byTime = False | ||||
else: | ||||
self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line | ||||
self.n = 9999 | ||||
self.__byTime = True | ||||
|
r897 | |||
|
r487 | if overlapping: | ||
self.__withOverapping = True | ||||
self.__buffer = None | ||||
else: | ||||
self.__withOverapping = False | ||||
self.__buffer = 0 | ||||
|
r897 | |||
|
r487 | self.__profIndex = 0 | ||
|
r897 | |||
|
r487 | def putData(self, data): | ||
|
r897 | |||
|
r487 | """ | ||
Add a profile to the __buffer and increase in one the __profileIndex | ||||
|
r897 | |||
|
r487 | """ | ||
|
r897 | |||
|
r487 | if not self.__withOverapping: | ||
self.__buffer += data.copy() | ||||
|
r897 | self.__profIndex += 1 | ||
|
r487 | return | ||
|
r897 | |||
|
r487 | #Overlapping data | ||
nChannels, nHeis = data.shape | ||||
data = numpy.reshape(data, (1, nChannels, nHeis)) | ||||
|
r897 | |||
|
r487 | #If the buffer is empty then it takes the data value | ||
|
r611 | if self.__buffer is None: | ||
|
r487 | self.__buffer = data | ||
self.__profIndex += 1 | ||||
return | ||||
|
r897 | |||
|
r487 | #If the buffer length is lower than n then stakcing the data value | ||
if self.__profIndex < self.n: | ||||
self.__buffer = numpy.vstack((self.__buffer, data)) | ||||
self.__profIndex += 1 | ||||
return | ||||
|
r897 | |||
#If the buffer length is equal to n then replacing the last buffer value with the data value | ||||
|
r487 | self.__buffer = numpy.roll(self.__buffer, -1, axis=0) | ||
self.__buffer[self.n-1] = data | ||||
self.__profIndex = self.n | ||||
return | ||||
|
r897 | |||
|
r487 | def pushData(self): | ||
""" | ||||
Return the sum of the last profiles and the profiles used in the sum. | ||||
|
r897 | |||
|
r487 | Affected: | ||
|
r897 | |||
|
r487 | self.__profileIndex | ||
|
r897 | |||
|
r487 | """ | ||
|
r897 | |||
|
r487 | if not self.__withOverapping: | ||
data = self.__buffer | ||||
n = self.__profIndex | ||||
|
r897 | |||
|
r487 | self.__buffer = 0 | ||
self.__profIndex = 0 | ||||
|
r897 | |||
|
r487 | return data, n | ||
|
r897 | |||
|
r487 | #Integration with Overlapping | ||
data = numpy.sum(self.__buffer, axis=0) | ||||
n = self.__profIndex | ||||
|
r897 | |||
|
r487 | return data, n | ||
|
r897 | |||
|
r487 | def byProfiles(self, data): | ||
|
r897 | |||
|
r487 | self.__dataReady = False | ||
avgdata = None | ||||
# n = None | ||||
|
r897 | |||
|
r487 | self.putData(data) | ||
|
r897 | |||
|
r487 | if self.__profIndex == self.n: | ||
|
r897 | |||
|
r487 | avgdata, n = self.pushData() | ||
self.__dataReady = True | ||||
|
r897 | |||
|
r487 | return avgdata | ||
|
r897 | |||
|
r487 | def byTime(self, data, datatime): | ||
|
r897 | |||
|
r487 | self.__dataReady = False | ||
avgdata = None | ||||
n = None | ||||
|
r897 | |||
|
r487 | self.putData(data) | ||
|
r897 | |||
|
r487 | if (datatime - self.__initime) >= self.__integrationtime: | ||
avgdata, n = self.pushData() | ||||
self.n = n | ||||
self.__dataReady = True | ||||
|
r897 | |||
|
r487 | return avgdata | ||
|
r897 | |||
|
r487 | def integrate(self, data, datatime=None): | ||
|
r897 | |||
|
r487 | if self.__initime == None: | ||
self.__initime = datatime | ||||
|
r897 | |||
|
r487 | if self.__byTime: | ||
avgdata = self.byTime(data, datatime) | ||||
else: | ||||
avgdata = self.byProfiles(data) | ||||
|
r897 | |||
|
r487 | self.__lastdatatime = datatime | ||
|
r897 | |||
|
r611 | if avgdata is None: | ||
|
r487 | return None, None | ||
|
r897 | |||
|
r487 | avgdatatime = self.__initime | ||
|
r897 | |||
|
r487 | deltatime = datatime -self.__lastdatatime | ||
|
r897 | |||
|
r487 | if not self.__withOverapping: | ||
self.__initime = datatime | ||||
else: | ||||
self.__initime += deltatime | ||||
|
r897 | |||
|
r487 | return avgdata, avgdatatime | ||
|
r897 | |||
|
r954 | def run(self, dataOut, n=None, timeInterval=None, overlapping=False, **kwargs): | ||
|
r897 | |||
|
r487 | if not self.isConfig: | ||
|
r954 | self.setup(n=n, timeInterval=timeInterval, overlapping=overlapping) | ||
|
r487 | self.isConfig = True | ||
|
r897 | |||
|
r487 | avgdata, avgdatatime = self.integrate(dataOut.data_spc, dataOut.utctime) | ||
|
r897 | |||
|
r487 | # dataOut.timeInterval *= n | ||
dataOut.flagNoData = True | ||||
|
r897 | |||
|
r487 | if self.__dataReady: | ||
dataOut.data_spc = avgdata | ||||
dataOut.nIncohInt *= self.n | ||||
# dataOut.nCohInt *= self.n | ||||
dataOut.utctime = avgdatatime | ||||
|
r528 | # dataOut.timeInterval = dataOut.ippSeconds * dataOut.nIncohInt | ||
|
r487 | # dataOut.timeInterval = self.__timeInterval*self.n | ||
|
r897 | dataOut.flagNoData = False | ||