VoltageProcessor.py
463 lines
| 14.4 KiB
| text/x-python
|
PythonLexer
|
r10 | ''' | |
Created on Feb 7, 2012 | |||
|
r16 | @author $Author$ | |
@version $Id$ | |||
|
r10 | ''' | |
|
r72 | import os, sys | |
import numpy | |||
path = os.path.split(os.getcwd())[0] | |||
sys.path.append(path) | |||
from Model.Voltage import Voltage | |||
from IO.VoltageIO import VoltageWriter | |||
from Graphics.VoltagePlot import Osciloscope | |||
|
r10 | class VoltageProcessor: | |
''' | |||
classdocs | |||
''' | |||
|
r72 | def __init__(self, voltageInObj, voltageOutObj=None): | |
|
r10 | ''' | |
Constructor | |||
''' | |||
|
r72 | ||
self.voltageInObj = voltageInObj | |||
if voltageOutObj == None: | |||
self.voltageOutObj = Voltage() | |||
else: | |||
self.voltageOutObj = voltageOutObj | |||
self.integratorIndex = None | |||
self.decoderIndex = None | |||
|
r92 | self.profSelectorIndex = None | |
|
r72 | self.writerIndex = None | |
self.plotterIndex = None | |||
self.integratorList = [] | |||
self.decoderList = [] | |||
|
r92 | self.profileSelectorList = [] | |
|
r72 | self.writerList = [] | |
self.plotterList = [] | |||
def init(self): | |||
|
r92 | ||
|
r72 | self.integratorIndex = 0 | |
self.decoderIndex = 0 | |||
|
r92 | self.profSelectorIndex = 0 | |
|
r72 | self.writerIndex = 0 | |
self.plotterIndex = 0 | |||
self.voltageOutObj.copy(self.voltageInObj) | |||
|
r92 | def addWriter(self, wrpath): | |
|
r72 | objWriter = VoltageWriter(self.voltageOutObj) | |
objWriter.setup(wrpath) | |||
self.writerList.append(objWriter) | |||
def addPlotter(self): | |||
plotObj = Osciloscope(self.voltageOutObj,self.plotterIndex) | |||
self.plotterList.append(plotObj) | |||
|
r92 | def addIntegrator(self, nCohInt): | |
|
r72 | ||
|
r92 | objCohInt = CoherentIntegrator(nCohInt) | |
|
r72 | self.integratorList.append(objCohInt) | |
|
r92 | def addDecoder(self, code, ncode, nbaud): | |
|
r72 | ||
objDecoder = Decoder(code,ncode,nbaud) | |||
self.decoderList.append(objDecoder) | |||
|
r92 | def addProfileSelector(self, nProfiles): | |
objProfSelector = ProfileSelector(nProfiles) | |||
self.profileSelectorList.append(objProfSelector) | |||
|
r72 | def writeData(self,wrpath): | |
|
r92 | ||
|
r72 | if self.voltageOutObj.flagNoData: | |
|
r92 | return 0 | |
|
r72 | ||
if len(self.writerList) <= self.writerIndex: | |||
self.addWriter(wrpath) | |||
self.writerList[self.writerIndex].putData() | |||
# myWrObj = self.writerList[self.writerIndex] | |||
# myWrObj.putData() | |||
self.writerIndex += 1 | |||
def plotData(self,idProfile, type, xmin=None, xmax=None, ymin=None, ymax=None, winTitle=''): | |||
if self.voltageOutObj.flagNoData: | |||
|
r92 | return 0 | |
|
r72 | ||
if len(self.plotterList) <= self.plotterIndex: | |||
self.addPlotter() | |||
self.plotterList[self.plotterIndex].plotData(type=type, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,winTitle=winTitle) | |||
self.plotterIndex += 1 | |||
def integrator(self, N): | |||
|
r92 | ||
|
r72 | if self.voltageOutObj.flagNoData: | |
|
r92 | return 0 | |
|
r72 | ||
if len(self.integratorList) <= self.integratorIndex: | |||
self.addIntegrator(N) | |||
myCohIntObj = self.integratorList[self.integratorIndex] | |||
myCohIntObj.exe(self.voltageOutObj.data) | |||
if myCohIntObj.flag: | |||
self.voltageOutObj.data = myCohIntObj.data | |||
self.voltageOutObj.m_ProcessingHeader.coherentInt *= N | |||
self.voltageOutObj.flagNoData = False | |||
else: | |||
self.voltageOutObj.flagNoData = True | |||
self.integratorIndex += 1 | |||
def decoder(self,code=None,type = 0): | |||
|
r92 | ||
|
r72 | if self.voltageOutObj.flagNoData: | |
|
r92 | return 0 | |
|
r72 | if code == None: | |
code = self.voltageOutObj.m_RadarControllerHeader.code | |||
ncode, nbaud = code.shape | |||
if len(self.decoderList) <= self.decoderIndex: | |||
self.addDecoder(code,ncode,nbaud) | |||
myDecodObj = self.decoderList[self.decoderIndex] | |||
myDecodObj.exe(data=self.voltageOutObj.data,type=type) | |||
if myDecodObj.flag: | |||
self.voltageOutObj.data = myDecodObj.data | |||
self.voltageOutObj.flagNoData = False | |||
else: | |||
self.voltageOutObj.flagNoData = True | |||
self.decoderIndex += 1 | |||
|
r84 | ||
|
r72 | ||
|
r84 | def filterByHei(self, window): | |
|
r72 | pass | |
|
r84 | ||
|
r72 | ||
|
r84 | def selectChannels(self, channelList): | |
""" | |||
Selecciona un bloque de datos en base a canales y pares segun el channelList y el pairList | |||
Input: | |||
|
r97 | channelList : lista sencilla de canales a seleccionar por ej. [2,3,7] | |
|
r84 | ||
Affected: | |||
|
r97 | self.dataOutObj.data | |
self.voltageOutObj.channelList | |||
|
r84 | self.dataOutObj.nChannels | |
|
r97 | self.voltageOutObj.m_ProcessingHeader.totalSpectra | |
|
r84 | self.dataOutObj.m_SystemHeader.numChannels | |
self.voltageOutObj.m_ProcessingHeader.blockSize | |||
Return: | |||
None | |||
""" | |||
|
r97 | if self.voltageOutObj.flagNoData: | |
return 0 | |||
for channel in channelList: | |||
if channel not in self.voltageOutObj.channelList: | |||
raise ValueError, "The value %d in channelList is not valid" %channel | |||
|
r84 | ||
|
r97 | nchannels = len(channelList) | |
|
r84 | profiles = self.voltageOutObj.nProfiles | |
|
r97 | heights = self.voltageOutObj.nHeights #m_ProcessingHeader.numHeights | |
|
r84 | ||
|
r97 | data = numpy.zeros( (nchannels,heights), dtype='complex' ) | |
|
r84 | for index,channel in enumerate(channelList): | |
|
r97 | data[index,:] = self.voltageOutObj.data[channel,:] | |
|
r72 | ||
|
r97 | self.voltageOutObj.data = data | |
|
r84 | self.voltageOutObj.channelList = channelList | |
self.voltageOutObj.nChannels = nchannels | |||
self.voltageOutObj.m_ProcessingHeader.totalSpectra = nchannels | |||
self.voltageOutObj.m_SystemHeader.numChannels = nchannels | |||
self.voltageOutObj.m_ProcessingHeader.blockSize = data.size | |||
|
r97 | return 1 | |
|
r72 | ||
|
r84 | def selectHeightsByValue(self, minHei, maxHei): | |
""" | |||
Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango | |||
minHei <= height <= maxHei | |||
Input: | |||
minHei : valor minimo de altura a considerar | |||
maxHei : valor maximo de altura a considerar | |||
Affected: | |||
Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex | |||
Return: | |||
|
r97 | 1 si el metodo se ejecuto con exito caso contrario devuelve 0 | |
|
r84 | """ | |
|
r97 | if self.voltageOutObj.flagNoData: | |
return 0 | |||
if (minHei < self.voltageOutObj.heightList[0]) or (minHei > maxHei): | |||
raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei) | |||
if (maxHei > self.voltageOutObj.heightList[-1]): | |||
raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei) | |||
|
r84 | minIndex = 0 | |
maxIndex = 0 | |||
|
r97 | data = self.voltageOutObj.heightList | |
|
r84 | ||
for i,val in enumerate(data): | |||
if val < minHei: | |||
continue | |||
else: | |||
minIndex = i; | |||
break | |||
for i,val in enumerate(data): | |||
if val <= maxHei: | |||
maxIndex = i; | |||
else: | |||
break | |||
self.selectHeightsByIndex(minIndex, maxIndex) | |||
|
r97 | return 1 | |
|
r84 | ||
def selectHeightsByIndex(self, minIndex, maxIndex): | |||
""" | |||
Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango | |||
minIndex <= index <= maxIndex | |||
Input: | |||
|
r97 | minIndex : valor de indice minimo de altura a considerar | |
maxIndex : valor de indice maximo de altura a considerar | |||
|
r84 | ||
Affected: | |||
|
r97 | self.voltageOutObj.data | |
self.voltageOutObj.heightList | |||
|
r84 | self.voltageOutObj.nHeights | |
|
r97 | self.voltageOutObj.m_ProcessingHeader.blockSize | |
self.voltageOutObj.m_ProcessingHeader.numHeights | |||
self.voltageOutObj.m_ProcessingHeader.firstHeight | |||
self.voltageOutObj.m_RadarControllerHeader | |||
|
r84 | ||
Return: | |||
|
r97 | 1 si el metodo se ejecuto con exito caso contrario devuelve 0 | |
|
r84 | """ | |
|
r97 | if self.voltageOutObj.flagNoData: | |
return 0 | |||
if (minIndex < 0) or (minIndex > maxIndex): | |||
raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex) | |||
if (maxIndex >= self.voltageOutObj.nHeights): | |||
raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex) | |||
nHeights = maxIndex - minIndex + 1 | |||
|
r84 | firstHeight = 0 | |
#voltage | |||
|
r97 | data = self.voltageOutObj.data[:,minIndex:maxIndex+1] | |
|
r84 | ||
|
r97 | firstHeight = self.voltageOutObj.heightList[minIndex] | |
|
r84 | ||
|
r97 | self.voltageOutObj.data = data | |
self.voltageOutObj.heightList = self.voltageOutObj.heightList[minIndex:maxIndex+1] | |||
self.voltageOutObj.nHeights = nHeights | |||
|
r84 | self.voltageOutObj.m_ProcessingHeader.blockSize = data.size | |
|
r97 | self.voltageOutObj.m_ProcessingHeader.numHeights = nHeights | |
|
r84 | self.voltageOutObj.m_ProcessingHeader.firstHeight = firstHeight | |
|
r97 | self.voltageOutObj.m_RadarControllerHeader.numHeights = nHeights | |
return 1 | |||
|
r84 | ||
|
r92 | def selectProfiles(self, minIndex, maxIndex, nProfiles): | |
|
r84 | """ | |
|
r97 | Selecciona un bloque de datos en base a un grupo indices de perfiles segun el rango | |
|
r84 | minIndex <= index <= maxIndex | |
Input: | |||
|
r97 | minIndex : valor de indice minimo de perfil a considerar | |
maxIndex : valor de indice maximo de perfil a considerar | |||
nProfiles : numero de profiles | |||
|
r84 | ||
Affected: | |||
|
r97 | self.voltageOutObj.flagNoData | |
self.profSelectorIndex | |||
|
r84 | ||
Return: | |||
|
r97 | 1 si el metodo se ejecuto con exito caso contrario devuelve 0 | |
|
r84 | """ | |
|
r92 | ||
if self.voltageOutObj.flagNoData: | |||
return 0 | |||
if self.profSelectorIndex >= len(self.profileSelectorList): | |||
self.addProfileSelector(nProfiles) | |||
profileSelectorObj = self.profileSelectorList[self.profSelectorIndex] | |||
if profileSelectorObj.isProfileInRange(minIndex, maxIndex): | |||
self.voltageOutObj.flagNoData = False | |||
self.profSelectorIndex += 1 | |||
return 1 | |||
self.voltageOutObj.flagNoData = True | |||
self.profSelectorIndex += 1 | |||
return 0 | |||
|
r72 | ||
|
r84 | def selectNtxs(self, ntx): | |
|
r72 | pass | |
class Decoder: | |||
|
r92 | ||
|
r72 | def __init__(self,code, ncode, nbaud): | |
|
r92 | ||
|
r72 | self.buffer = None | |
self.profCounter = 1 | |||
self.nCode = ncode | |||
self.nBaud = nbaud | |||
self.codeIndex = 0 | |||
self.code = code #this is a List | |||
self.fft_code = None | |||
self.flag = False | |||
self.setCodeFft = False | |||
def exe(self, data, ndata=None, type = 0): | |||
|
r92 | ||
|
r73 | if ndata == None: ndata = data.shape[1] | |
|
r72 | ||
if type == 0: | |||
self.convolutionInFreq(data,ndata) | |||
if type == 1: | |||
self.convolutionInTime(data, ndata) | |||
|
r92 | def convolutionInFreq(self,data, ndata): | |
|
r72 | ||
newcode = numpy.zeros(ndata) | |||
newcode[0:self.nBaud] = self.code[self.codeIndex] | |||
self.codeIndex += 1 | |||
|
r73 | fft_data = numpy.fft.fft(data, axis=1) | |
|
r72 | fft_code = numpy.conj(numpy.fft.fft(newcode)) | |
|
r73 | fft_code = fft_code.reshape(1,len(fft_code)) | |
|
r72 | ||
conv = fft_data.copy() | |||
conv.fill(0) | |||
conv = fft_data*fft_code # This other way to calculate multiplication between bidimensional arrays | |||
# for i in range(ndata): | |||
# conv[i,:] = fft_data[i,:]*fft_code[i] | |||
|
r73 | self.data = numpy.fft.ifft(conv,axis=1) | |
|
r72 | self.flag = True | |
if self.profCounter == self.nCode: | |||
self.profCounter = 0 | |||
self.codeIndex = 0 | |||
self.profCounter += 1 | |||
def convolutionInTime(self, data, ndata): | |||
nchannel = data.shape[1] | |||
newcode = self.code[self.codeIndex] | |||
self.codeIndex += 1 | |||
conv = data.copy() | |||
for i in range(nchannel): | |||
|
r73 | conv[i,:] = numpy.correlate(data[i,:], newcode, 'same') | |
|
r72 | ||
self.data = conv | |||
self.flag = True | |||
if self.profCounter == self.nCode: | |||
self.profCounter = 0 | |||
self.codeIndex = 0 | |||
self.profCounter += 1 | |||
class CoherentIntegrator: | |||
|
r92 | ||
|
r72 | def __init__(self, N): | |
|
r92 | ||
|
r72 | self.profCounter = 1 | |
self.data = None | |||
self.buffer = None | |||
self.flag = False | |||
self.nCohInt = N | |||
|
r92 | def exe(self, data): | |
|
r72 | ||
if self.buffer == None: | |||
self.buffer = data | |||
else: | |||
self.buffer = self.buffer + data | |||
if self.profCounter == self.nCohInt: | |||
self.data = self.buffer | |||
self.buffer = None | |||
self.profCounter = 0 | |||
self.flag = True | |||
else: | |||
self.flag = False | |||
self.profCounter += 1 | |||
|
r92 | class ProfileSelector(): | |
indexProfile = None | |||
|
r97 | # Tamanho total de los perfiles | |
|
r92 | nProfiles = None | |
def __init__(self, nProfiles): | |||
self.indexProfile = 0 | |||
self.nProfiles = nProfiles | |||
def isProfileInRange(self, minIndex, maxIndex): | |||
|
r97 | if self.indexProfile < minIndex: | |
|
r92 | self.indexProfile += 1 | |
return False | |||
|
r97 | if self.indexProfile > maxIndex: | |
|
r92 | self.indexProfile += 1 | |
return False | |||
self.indexProfile += 1 | |||
return True | |||
def isProfileInList(self, profileList): | |||
if self.indexProfile not in profileList: | |||
self.indexProfile += 1 | |||
return False | |||
self.indexProfile += 1 | |||
return True | |||
|
r72 |