##// END OF EJS Templates
HDFWriter writes standard Weather parameters/Now we can run a type OTHER Operation even if flagNoData is True
rflores -
r1459:52714d4d854d
parent child
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,834 +1,838
1 '''
1 '''
2 Created on Jul 3, 2014
2 Created on Jul 3, 2014
3
3
4 @author: roj-idl71
4 @author: roj-idl71
5 '''
5 '''
6 # SUBCHANNELS EN VEZ DE CHANNELS
6 # SUBCHANNELS EN VEZ DE CHANNELS
7 # BENCHMARKS -> PROBLEMAS CON ARCHIVOS GRANDES -> INCONSTANTE EN EL TIEMPO
7 # BENCHMARKS -> PROBLEMAS CON ARCHIVOS GRANDES -> INCONSTANTE EN EL TIEMPO
8 # ACTUALIZACION DE VERSION
8 # ACTUALIZACION DE VERSION
9 # HEADERS
9 # HEADERS
10 # MODULO DE ESCRITURA
10 # MODULO DE ESCRITURA
11 # METADATA
11 # METADATA
12
12
13 import os
13 import os
14 import time
14 import time
15 import datetime
15 import datetime
16 import numpy
16 import numpy
17 import timeit
17 import timeit
18 from fractions import Fraction
18 from fractions import Fraction
19 from time import time
19 from time import time
20 from time import sleep
20 from time import sleep
21
21
22 import schainpy.admin
22 import schainpy.admin
23 from schainpy.model.data.jroheaderIO import RadarControllerHeader, SystemHeader
23 from schainpy.model.data.jroheaderIO import RadarControllerHeader, SystemHeader
24 from schainpy.model.data.jrodata import Voltage
24 from schainpy.model.data.jrodata import Voltage
25 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
25 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
26
26
27 import pickle
27 import pickle
28 try:
28 try:
29 import digital_rf
29 import digital_rf
30 except:
30 except:
31 pass
31 pass
32
32
33
33
34 class DigitalRFReader(ProcessingUnit):
34 class DigitalRFReader(ProcessingUnit):
35 '''
35 '''
36 classdocs
36 classdocs
37 '''
37 '''
38
38
39 def __init__(self):
39 def __init__(self):
40 '''
40 '''
41 Constructor
41 Constructor
42 '''
42 '''
43
43
44 ProcessingUnit.__init__(self)
44 ProcessingUnit.__init__(self)
45
45
46 self.dataOut = Voltage()
46 self.dataOut = Voltage()
47 self.__printInfo = True
47 self.__printInfo = True
48 self.__flagDiscontinuousBlock = False
48 self.__flagDiscontinuousBlock = False
49 self.__bufferIndex = 9999999
49 self.__bufferIndex = 9999999
50 self.__codeType = 0
50 self.__codeType = 0
51 self.__ippKm = None
51 self.__ippKm = None
52 self.__nCode = None
52 self.__nCode = None
53 self.__nBaud = None
53 self.__nBaud = None
54 self.__code = None
54 self.__code = None
55 self.dtype = None
55 self.dtype = None
56 self.oldAverage = None
56 self.oldAverage = None
57 self.path = None
57 self.path = None
58
58
59 def close(self):
59 def close(self):
60 print('Average of writing to digital rf format is ', self.oldAverage * 1000)
60 print('Average of writing to digital rf format is ', self.oldAverage * 1000)
61 return
61 return
62
62
63 def __getCurrentSecond(self):
63 def __getCurrentSecond(self):
64
64
65 return self.__thisUnixSample / self.__sample_rate
65 return self.__thisUnixSample / self.__sample_rate
66
66
67 thisSecond = property(__getCurrentSecond, "I'm the 'thisSecond' property.")
67 thisSecond = property(__getCurrentSecond, "I'm the 'thisSecond' property.")
68
68
69 def __setFileHeader(self):
69 def __setFileHeader(self):
70 '''
70 '''
71 In this method will be initialized every parameter of dataOut object (header, no data)
71 In this method will be initialized every parameter of dataOut object (header, no data)
72 '''
72 '''
73 ippSeconds = 1.0 * self.__nSamples / self.__sample_rate
73 ippSeconds = 1.0 * self.__nSamples / self.__sample_rate
74 if not self.getByBlock:
74 if not self.getByBlock:
75 nProfiles = 1.0 / ippSeconds # Number of profiles in one second
75 nProfiles = 1.0 / ippSeconds # Number of profiles in one second
76 else:
76 else:
77 nProfiles = self.nProfileBlocks # Number of profiles in one block
77 nProfiles = self.nProfileBlocks # Number of profiles in one block
78
78
79 try:
79 try:
80 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(
80 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(
81 self.__radarControllerHeader)
81 self.__radarControllerHeader)
82 except:
82 except:
83 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(
83 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(
84 txA=0,
84 txA=0,
85 txB=0,
85 txB=0,
86 nWindows=1,
86 nWindows=1,
87 nHeights=self.__nSamples,
87 nHeights=self.__nSamples,
88 firstHeight=self.__firstHeigth,
88 firstHeight=self.__firstHeigth,
89 deltaHeight=self.__deltaHeigth,
89 deltaHeight=self.__deltaHeigth,
90 codeType=self.__codeType,
90 codeType=self.__codeType,
91 nCode=self.__nCode, nBaud=self.__nBaud,
91 nCode=self.__nCode, nBaud=self.__nBaud,
92 code=self.__code)
92 code=self.__code)
93
93
94 try:
94 try:
95 self.dataOut.systemHeaderObj = SystemHeader(self.__systemHeader)
95 self.dataOut.systemHeaderObj = SystemHeader(self.__systemHeader)
96 except:
96 except:
97 self.dataOut.systemHeaderObj = SystemHeader(nSamples=self.__nSamples,
97 self.dataOut.systemHeaderObj = SystemHeader(nSamples=self.__nSamples,
98 nProfiles=nProfiles,
98 nProfiles=nProfiles,
99 nChannels=len(
99 nChannels=len(
100 self.__channelList),
100 self.__channelList),
101 adcResolution=14)
101 adcResolution=14)
102 self.dataOut.type = "Voltage"
102 self.dataOut.type = "Voltage"
103
103
104 self.dataOut.data = None
104 self.dataOut.data = None
105
105
106 self.dataOut.dtype = self.dtype
106 self.dataOut.dtype = self.dtype
107
107
108 # self.dataOut.nChannels = 0
108 # self.dataOut.nChannels = 0
109
109
110 # self.dataOut.nHeights = 0
110 # self.dataOut.nHeights = 0
111
111
112 self.dataOut.nProfiles = int(nProfiles)
112 self.dataOut.nProfiles = int(nProfiles)
113
113
114 self.dataOut.heightList = self.__firstHeigth + \
114 self.dataOut.heightList = self.__firstHeigth + \
115 numpy.arange(self.__nSamples, dtype=numpy.float) * \
115 numpy.arange(self.__nSamples, dtype=numpy.float) * \
116 self.__deltaHeigth
116 self.__deltaHeigth
117
117
118 #self.dataOut.channelList = list(range(self.__num_subchannels))
118 #self.dataOut.channelList = list(range(self.__num_subchannels))
119 self.dataOut.channelList = list(range(len(self.__channelList)))
119 self.dataOut.channelList = list(range(len(self.__channelList)))
120 if not self.getByBlock:
120 if not self.getByBlock:
121
121
122 self.dataOut.blocksize = self.dataOut.nChannels * self.dataOut.nHeights
122 self.dataOut.blocksize = self.dataOut.nChannels * self.dataOut.nHeights
123 else:
123 else:
124 self.dataOut.blocksize = self.dataOut.nChannels * self.dataOut.nHeights*self.nProfileBlocks
124 self.dataOut.blocksize = self.dataOut.nChannels * self.dataOut.nHeights*self.nProfileBlocks
125
125
126 # self.dataOut.channelIndexList = None
126 # self.dataOut.channelIndexList = None
127
127
128 self.dataOut.flagNoData = True
128 self.dataOut.flagNoData = True
129 if not self.getByBlock:
129 if not self.getByBlock:
130 self.dataOut.flagDataAsBlock = False
130 self.dataOut.flagDataAsBlock = False
131 else:
131 else:
132 self.dataOut.flagDataAsBlock = True
132 self.dataOut.flagDataAsBlock = True
133 # Set to TRUE if the data is discontinuous
133 # Set to TRUE if the data is discontinuous
134 self.dataOut.flagDiscontinuousBlock = False
134 self.dataOut.flagDiscontinuousBlock = False
135
135
136 self.dataOut.utctime = None
136 self.dataOut.utctime = None
137
137
138 # timezone like jroheader, difference in minutes between UTC and localtime
138 # timezone like jroheader, difference in minutes between UTC and localtime
139 self.dataOut.timeZone = self.__timezone / 60
139 self.dataOut.timeZone = self.__timezone / 60
140
140
141 self.dataOut.dstFlag = 0
141 self.dataOut.dstFlag = 0
142
142
143 self.dataOut.errorCount = 0
143 self.dataOut.errorCount = 0
144
144
145 try:
145 try:
146 self.dataOut.nCohInt = self.fixed_metadata_dict.get(
146 self.dataOut.nCohInt = self.fixed_metadata_dict.get(
147 'nCohInt', self.nCohInt)
147 'nCohInt', self.nCohInt)
148
148
149 # asumo que la data esta decodificada
149 # asumo que la data esta decodificada
150 self.dataOut.flagDecodeData = self.fixed_metadata_dict.get(
150 self.dataOut.flagDecodeData = self.fixed_metadata_dict.get(
151 'flagDecodeData', self.flagDecodeData)
151 'flagDecodeData', self.flagDecodeData)
152
152
153 # asumo que la data esta sin flip
153 # asumo que la data esta sin flip
154 self.dataOut.flagDeflipData = self.fixed_metadata_dict['flagDeflipData']
154 self.dataOut.flagDeflipData = self.fixed_metadata_dict['flagDeflipData']
155
155
156 self.dataOut.flagShiftFFT = self.fixed_metadata_dict['flagShiftFFT']
156 self.dataOut.flagShiftFFT = self.fixed_metadata_dict['flagShiftFFT']
157
157
158 self.dataOut.useLocalTime = self.fixed_metadata_dict['useLocalTime']
158 self.dataOut.useLocalTime = self.fixed_metadata_dict['useLocalTime']
159 except:
159 except:
160 pass
160 pass
161
161
162 self.dataOut.ippSeconds = ippSeconds
162 self.dataOut.ippSeconds = ippSeconds
163
163
164 # Time interval between profiles
164 # Time interval between profiles
165 # self.dataOut.timeInterval = self.dataOut.ippSeconds * self.dataOut.nCohInt
165 # self.dataOut.timeInterval = self.dataOut.ippSeconds * self.dataOut.nCohInt
166
166
167 self.dataOut.frequency = self.__frequency
167 self.dataOut.frequency = self.__frequency
168
168
169 self.dataOut.realtime = self.__online
169 self.dataOut.realtime = self.__online
170
170
171 def findDatafiles(self, path, startDate=None, endDate=None):
171 def findDatafiles(self, path, startDate=None, endDate=None):
172
172
173 if not os.path.isdir(path):
173 if not os.path.isdir(path):
174 return []
174 return []
175
175
176 try:
176 try:
177 digitalReadObj = digital_rf.DigitalRFReader(
177 digitalReadObj = digital_rf.DigitalRFReader(
178 path, load_all_metadata=True)
178 path, load_all_metadata=True)
179 except:
179 except:
180 digitalReadObj = digital_rf.DigitalRFReader(path)
180 digitalReadObj = digital_rf.DigitalRFReader(path)
181
181
182 channelNameList = digitalReadObj.get_channels()
182 channelNameList = digitalReadObj.get_channels()
183
183
184 if not channelNameList:
184 if not channelNameList:
185 return []
185 return []
186
186
187 metadata_dict = digitalReadObj.get_rf_file_metadata(channelNameList[0])
187 metadata_dict = digitalReadObj.get_rf_file_metadata(channelNameList[0])
188
188
189 sample_rate = metadata_dict['sample_rate'][0]
189 sample_rate = metadata_dict['sample_rate'][0]
190
190
191 this_metadata_file = digitalReadObj.get_metadata(channelNameList[0])
191 this_metadata_file = digitalReadObj.get_metadata(channelNameList[0])
192
192
193 try:
193 try:
194 timezone = this_metadata_file['timezone'].value
194 timezone = this_metadata_file['timezone'].value
195 except:
195 except:
196 timezone = 0
196 timezone = 0
197
197
198 startUTCSecond, endUTCSecond = digitalReadObj.get_bounds(
198 startUTCSecond, endUTCSecond = digitalReadObj.get_bounds(
199 channelNameList[0]) / sample_rate - timezone
199 channelNameList[0]) / sample_rate - timezone
200
200
201 startDatetime = datetime.datetime.utcfromtimestamp(startUTCSecond)
201 startDatetime = datetime.datetime.utcfromtimestamp(startUTCSecond)
202 endDatatime = datetime.datetime.utcfromtimestamp(endUTCSecond)
202 endDatatime = datetime.datetime.utcfromtimestamp(endUTCSecond)
203
203
204 if not startDate:
204 if not startDate:
205 startDate = startDatetime.date()
205 startDate = startDatetime.date()
206
206
207 if not endDate:
207 if not endDate:
208 endDate = endDatatime.date()
208 endDate = endDatatime.date()
209
209
210 dateList = []
210 dateList = []
211
211
212 thisDatetime = startDatetime
212 thisDatetime = startDatetime
213
213
214 while(thisDatetime <= endDatatime):
214 while(thisDatetime <= endDatatime):
215
215
216 thisDate = thisDatetime.date()
216 thisDate = thisDatetime.date()
217
217
218 if thisDate < startDate:
218 if thisDate < startDate:
219 continue
219 continue
220
220
221 if thisDate > endDate:
221 if thisDate > endDate:
222 break
222 break
223
223
224 dateList.append(thisDate)
224 dateList.append(thisDate)
225 thisDatetime += datetime.timedelta(1)
225 thisDatetime += datetime.timedelta(1)
226
226
227 return dateList
227 return dateList
228
228
229 def setup(self, path=None,
229 def setup(self, path=None,
230 startDate=None,
230 startDate=None,
231 endDate=None,
231 endDate=None,
232 startTime=datetime.time(0, 0, 0),
232 startTime=datetime.time(0, 0, 0),
233 endTime=datetime.time(23, 59, 59),
233 endTime=datetime.time(23, 59, 59),
234 channelList=None,
234 channelList=None,
235 nSamples=None,
235 nSamples=None,
236 online=False,
236 online=False,
237 delay=60,
237 delay=60,
238 buffer_size=1024,
238 buffer_size=1024,
239 ippKm=None,
239 ippKm=None,
240 nCohInt=1,
240 nCohInt=1,
241 nCode=1,
241 nCode=1,
242 nBaud=1,
242 nBaud=1,
243 flagDecodeData=False,
243 flagDecodeData=False,
244 code=numpy.ones((1, 1), dtype=numpy.int),
244 code=numpy.ones((1, 1), dtype=numpy.int),
245 getByBlock=0,
245 getByBlock=0,
246 nProfileBlocks=1,
246 nProfileBlocks=1,
247 **kwargs):
247 **kwargs):
248 '''
248 '''
249 In this method we should set all initial parameters.
249 In this method we should set all initial parameters.
250
250
251 Inputs:
251 Inputs:
252 path
252 path
253 startDate
253 startDate
254 endDate
254 endDate
255 startTime
255 startTime
256 endTime
256 endTime
257 set
257 set
258 expLabel
258 expLabel
259 ext
259 ext
260 online
260 online
261 delay
261 delay
262 '''
262 '''
263 self.path = path
263 self.path = path
264 self.nCohInt = nCohInt
264 self.nCohInt = nCohInt
265 self.flagDecodeData = flagDecodeData
265 self.flagDecodeData = flagDecodeData
266 self.i = 0
266 self.i = 0
267
267
268 self.getByBlock = getByBlock
268 self.getByBlock = getByBlock
269 self.nProfileBlocks = nProfileBlocks
269 self.nProfileBlocks = nProfileBlocks
270 if not os.path.isdir(path):
270 if not os.path.isdir(path):
271 raise ValueError("[Reading] Directory %s does not exist" % path)
271 raise ValueError("[Reading] Directory %s does not exist" % path)
272
272
273 try:
273 try:
274 self.digitalReadObj = digital_rf.DigitalRFReader(
274 self.digitalReadObj = digital_rf.DigitalRFReader(
275 path, load_all_metadata=True)
275 path, load_all_metadata=True)
276 except:
276 except:
277 self.digitalReadObj = digital_rf.DigitalRFReader(path)
277 self.digitalReadObj = digital_rf.DigitalRFReader(path)
278
278
279 channelNameList = self.digitalReadObj.get_channels()
279 channelNameList = self.digitalReadObj.get_channels()
280
280
281 if not channelNameList:
281 if not channelNameList:
282 raise ValueError("[Reading] Directory %s does not have any files" % path)
282 raise ValueError("[Reading] Directory %s does not have any files" % path)
283
283
284 if not channelList:
284 if not channelList:
285 channelList = list(range(len(channelNameList)))
285 channelList = list(range(len(channelNameList)))
286
286
287 ########## Reading metadata ######################
287 ########## Reading metadata ######################
288
288
289 top_properties = self.digitalReadObj.get_properties(
289 top_properties = self.digitalReadObj.get_properties(
290 channelNameList[channelList[0]])
290 channelNameList[channelList[0]])
291
291
292 self.__num_subchannels = top_properties['num_subchannels']
292 self.__num_subchannels = top_properties['num_subchannels']
293 self.__sample_rate = 1.0 * \
293 self.__sample_rate = 1.0 * \
294 top_properties['sample_rate_numerator'] / \
294 top_properties['sample_rate_numerator'] / \
295 top_properties['sample_rate_denominator']
295 top_properties['sample_rate_denominator']
296 # self.__samples_per_file = top_properties['samples_per_file'][0]
296 # self.__samples_per_file = top_properties['samples_per_file'][0]
297 self.__deltaHeigth = 1e6 * 0.15 / self.__sample_rate # why 0.15?
297 self.__deltaHeigth = 1e6 * 0.15 / self.__sample_rate # why 0.15?
298
298
299 this_metadata_file = self.digitalReadObj.get_digital_metadata(
299 this_metadata_file = self.digitalReadObj.get_digital_metadata(
300 channelNameList[channelList[0]])
300 channelNameList[channelList[0]])
301 metadata_bounds = this_metadata_file.get_bounds()
301 metadata_bounds = this_metadata_file.get_bounds()
302 self.fixed_metadata_dict = this_metadata_file.read(
302 self.fixed_metadata_dict = this_metadata_file.read(
303 metadata_bounds[0])[metadata_bounds[0]] # GET FIRST HEADER
303 metadata_bounds[0])[metadata_bounds[0]] # GET FIRST HEADER
304
304
305 try:
305 try:
306 self.__processingHeader = self.fixed_metadata_dict['processingHeader']
306 self.__processingHeader = self.fixed_metadata_dict['processingHeader']
307 self.__radarControllerHeader = self.fixed_metadata_dict['radarControllerHeader']
307 self.__radarControllerHeader = self.fixed_metadata_dict['radarControllerHeader']
308 self.__systemHeader = self.fixed_metadata_dict['systemHeader']
308 self.__systemHeader = self.fixed_metadata_dict['systemHeader']
309 self.dtype = pickle.loads(self.fixed_metadata_dict['dtype'])
309 self.dtype = pickle.loads(self.fixed_metadata_dict['dtype'])
310 except:
310 except:
311 pass
311 pass
312
312
313 self.__frequency = None
313 self.__frequency = None
314
314
315 self.__frequency = self.fixed_metadata_dict.get('frequency', 1)
315 self.__frequency = self.fixed_metadata_dict.get('frequency', 1)
316
316
317 self.__timezone = self.fixed_metadata_dict.get('timezone', 18000)
317 self.__timezone = self.fixed_metadata_dict.get('timezone', 18000)
318
318
319 try:
319 try:
320 nSamples = self.fixed_metadata_dict['nSamples']
320 nSamples = self.fixed_metadata_dict['nSamples']
321 except:
321 except:
322 nSamples = None
322 nSamples = None
323
323
324 self.__firstHeigth = 0
324 self.__firstHeigth = 0
325
325
326 try:
326 try:
327 codeType = self.__radarControllerHeader['codeType']
327 codeType = self.__radarControllerHeader['codeType']
328 except:
328 except:
329 codeType = 0
329 codeType = 0
330
330
331 try:
331 try:
332 if codeType:
332 if codeType:
333 nCode = self.__radarControllerHeader['nCode']
333 nCode = self.__radarControllerHeader['nCode']
334 nBaud = self.__radarControllerHeader['nBaud']
334 nBaud = self.__radarControllerHeader['nBaud']
335 code = self.__radarControllerHeader['code']
335 code = self.__radarControllerHeader['code']
336 except:
336 except:
337 pass
337 pass
338
338
339 if not ippKm:
339 if not ippKm:
340 try:
340 try:
341 # seconds to km
341 # seconds to km
342 ippKm = self.__radarControllerHeader['ipp']
342 ippKm = self.__radarControllerHeader['ipp']
343 except:
343 except:
344 ippKm = None
344 ippKm = None
345 ####################################################
345 ####################################################
346 self.__ippKm = ippKm
346 self.__ippKm = ippKm
347 startUTCSecond = None
347 startUTCSecond = None
348 endUTCSecond = None
348 endUTCSecond = None
349
349
350 if startDate:
350 if startDate:
351 startDatetime = datetime.datetime.combine(startDate, startTime)
351 startDatetime = datetime.datetime.combine(startDate, startTime)
352 startUTCSecond = (
352 startUTCSecond = (
353 startDatetime - datetime.datetime(1970, 1, 1)).total_seconds() + self.__timezone
353 startDatetime - datetime.datetime(1970, 1, 1)).total_seconds() + self.__timezone
354
354
355 if endDate:
355 if endDate:
356 endDatetime = datetime.datetime.combine(endDate, endTime)
356 endDatetime = datetime.datetime.combine(endDate, endTime)
357 endUTCSecond = (endDatetime - datetime.datetime(1970,
357 endUTCSecond = (endDatetime - datetime.datetime(1970,
358 1, 1)).total_seconds() + self.__timezone
358 1, 1)).total_seconds() + self.__timezone
359
359
360
360
361 #print(startUTCSecond,endUTCSecond)
361 #print(startUTCSecond,endUTCSecond)
362 start_index, end_index = self.digitalReadObj.get_bounds(
362 start_index, end_index = self.digitalReadObj.get_bounds(
363 channelNameList[channelList[0]])
363 channelNameList[channelList[0]])
364
364
365 #print("*****",start_index,end_index)
365 #print("*****",start_index,end_index)
366 if not startUTCSecond:
366 if not startUTCSecond:
367 startUTCSecond = start_index / self.__sample_rate
367 startUTCSecond = start_index / self.__sample_rate
368
368
369 if start_index > startUTCSecond * self.__sample_rate:
369 if start_index > startUTCSecond * self.__sample_rate:
370 startUTCSecond = start_index / self.__sample_rate
370 startUTCSecond = start_index / self.__sample_rate
371
371
372 if not endUTCSecond:
372 if not endUTCSecond:
373 endUTCSecond = end_index / self.__sample_rate
373 endUTCSecond = end_index / self.__sample_rate
374 if end_index < endUTCSecond * self.__sample_rate:
374 if end_index < endUTCSecond * self.__sample_rate:
375 endUTCSecond = end_index / self.__sample_rate #Check UTC and LT time
375 endUTCSecond = end_index / self.__sample_rate #Check UTC and LT time
376 if not nSamples:
376 if not nSamples:
377 if not ippKm:
377 if not ippKm:
378 raise ValueError("[Reading] nSamples or ippKm should be defined")
378 raise ValueError("[Reading] nSamples or ippKm should be defined")
379 nSamples = int(ippKm / (1e6 * 0.15 / self.__sample_rate))
379 nSamples = int(ippKm / (1e6 * 0.15 / self.__sample_rate))
380
380
381 channelBoundList = []
381 channelBoundList = []
382 channelNameListFiltered = []
382 channelNameListFiltered = []
383
383
384 for thisIndexChannel in channelList:
384 for thisIndexChannel in channelList:
385 thisChannelName = channelNameList[thisIndexChannel]
385 thisChannelName = channelNameList[thisIndexChannel]
386 start_index, end_index = self.digitalReadObj.get_bounds(
386 start_index, end_index = self.digitalReadObj.get_bounds(
387 thisChannelName)
387 thisChannelName)
388 channelBoundList.append((start_index, end_index))
388 channelBoundList.append((start_index, end_index))
389 channelNameListFiltered.append(thisChannelName)
389 channelNameListFiltered.append(thisChannelName)
390
390
391 self.profileIndex = 0
391 self.profileIndex = 0
392 self.i = 0
392 self.i = 0
393 self.__delay = delay
393 self.__delay = delay
394
394
395 self.__codeType = codeType
395 self.__codeType = codeType
396 self.__nCode = nCode
396 self.__nCode = nCode
397 self.__nBaud = nBaud
397 self.__nBaud = nBaud
398 self.__code = code
398 self.__code = code
399
399
400 self.__datapath = path
400 self.__datapath = path
401 self.__online = online
401 self.__online = online
402 self.__channelList = channelList
402 self.__channelList = channelList
403 self.__channelNameList = channelNameListFiltered
403 self.__channelNameList = channelNameListFiltered
404 self.__channelBoundList = channelBoundList
404 self.__channelBoundList = channelBoundList
405 self.__nSamples = nSamples
405 self.__nSamples = nSamples
406 if self.getByBlock:
406 if self.getByBlock:
407 nSamples = nSamples*nProfileBlocks
407 nSamples = nSamples*nProfileBlocks
408
408
409
409
410 self.__samples_to_read = int(nSamples) # FIJO: AHORA 40
410 self.__samples_to_read = int(nSamples) # FIJO: AHORA 40
411 #self.__samples_to_read = int(1000000) # FIJO: AHORA 40
411 self.__nChannels = len(self.__channelList)
412 self.__nChannels = len(self.__channelList)
412 #print("------------------------------------------")
413 #print("------------------------------------------")
413 #print("self.__samples_to_read",self.__samples_to_read)
414 #print("self.__samples_to_read",self.__samples_to_read)
414 #print("self.__nSamples",self.__nSamples)
415 #print("self.__nSamples",self.__nSamples)
415 # son iguales y el buffer_index da 0
416 # son iguales y el buffer_index da 0
416 self.__startUTCSecond = startUTCSecond
417 self.__startUTCSecond = startUTCSecond
417 self.__endUTCSecond = endUTCSecond
418 self.__endUTCSecond = endUTCSecond
418
419
419 self.__timeInterval = 1.0 * self.__samples_to_read / \
420 self.__timeInterval = 1.0 * self.__samples_to_read / \
420 self.__sample_rate # Time interval
421 self.__sample_rate # Time interval
421
422
422 if online:
423 if online:
423 # self.__thisUnixSample = int(endUTCSecond*self.__sample_rate - 4*self.__samples_to_read)
424 # self.__thisUnixSample = int(endUTCSecond*self.__sample_rate - 4*self.__samples_to_read)
424 startUTCSecond = numpy.floor(endUTCSecond)
425 startUTCSecond = numpy.floor(endUTCSecond)
425
426
426 # por que en el otro metodo lo primero q se hace es sumar samplestoread
427 # por que en el otro metodo lo primero q se hace es sumar samplestoread
427 self.__thisUnixSample = int(startUTCSecond * self.__sample_rate) - self.__samples_to_read
428 self.__thisUnixSample = int(startUTCSecond * self.__sample_rate) - self.__samples_to_read
428
429
429 #self.__data_buffer = numpy.zeros(
430 #self.__data_buffer = numpy.zeros(
430 # (self.__num_subchannels, self.__samples_to_read), dtype=numpy.complex)
431 # (self.__num_subchannels, self.__samples_to_read), dtype=numpy.complex)
431 self.__data_buffer = numpy.zeros((int(len(channelList)), self.__samples_to_read), dtype=numpy.complex)
432 self.__data_buffer = numpy.zeros((int(len(channelList)), self.__samples_to_read), dtype=numpy.complex)
432
433
433
434
434 self.__setFileHeader()
435 self.__setFileHeader()
435 self.isConfig = True
436 self.isConfig = True
436
437
437 print("[Reading] Digital RF Data was found from %s to %s " % (
438 print("[Reading] Digital RF Data was found from %s to %s " % (
438 datetime.datetime.utcfromtimestamp(
439 datetime.datetime.utcfromtimestamp(
439 self.__startUTCSecond - self.__timezone),
440 self.__startUTCSecond - self.__timezone),
440 datetime.datetime.utcfromtimestamp(
441 datetime.datetime.utcfromtimestamp(
441 self.__endUTCSecond - self.__timezone)
442 self.__endUTCSecond - self.__timezone)
442 ))
443 ))
443
444
444 print("[Reading] Starting process from %s to %s" % (datetime.datetime.utcfromtimestamp(startUTCSecond - self.__timezone),
445 print("[Reading] Starting process from %s to %s" % (datetime.datetime.utcfromtimestamp(startUTCSecond - self.__timezone),
445 datetime.datetime.utcfromtimestamp(
446 datetime.datetime.utcfromtimestamp(
446 endUTCSecond - self.__timezone)
447 endUTCSecond - self.__timezone)
447 ))
448 ))
448 self.oldAverage = None
449 self.oldAverage = None
449 self.count = 0
450 self.count = 0
450 self.executionTime = 0
451 self.executionTime = 0
451
452
452 def __reload(self):
453 def __reload(self):
453 # print
454 # print
454 # print "%s not in range [%s, %s]" %(
455 # print "%s not in range [%s, %s]" %(
455 # datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
456 # datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
456 # datetime.datetime.utcfromtimestamp(self.__startUTCSecond - self.__timezone),
457 # datetime.datetime.utcfromtimestamp(self.__startUTCSecond - self.__timezone),
457 # datetime.datetime.utcfromtimestamp(self.__endUTCSecond - self.__timezone)
458 # datetime.datetime.utcfromtimestamp(self.__endUTCSecond - self.__timezone)
458 # )
459 # )
459 print("[Reading] reloading metadata ...")
460 print("[Reading] reloading metadata ...")
460
461
461 try:
462 try:
462 self.digitalReadObj.reload(complete_update=True)
463 self.digitalReadObj.reload(complete_update=True)
463 except:
464 except:
464 self.digitalReadObj = digital_rf.DigitalRFReader(self.path)
465 self.digitalReadObj = digital_rf.DigitalRFReader(self.path)
465
466
466 start_index, end_index = self.digitalReadObj.get_bounds(
467 start_index, end_index = self.digitalReadObj.get_bounds(
467 self.__channelNameList[self.__channelList[0]])
468 self.__channelNameList[self.__channelList[0]])
468
469
469 if start_index > self.__startUTCSecond * self.__sample_rate:
470 if start_index > self.__startUTCSecond * self.__sample_rate:
470 self.__startUTCSecond = 1.0 * start_index / self.__sample_rate
471 self.__startUTCSecond = 1.0 * start_index / self.__sample_rate
471
472
472 if end_index > self.__endUTCSecond * self.__sample_rate:
473 if end_index > self.__endUTCSecond * self.__sample_rate:
473 self.__endUTCSecond = 1.0 * end_index / self.__sample_rate
474 self.__endUTCSecond = 1.0 * end_index / self.__sample_rate
474 print()
475 print()
475 print("[Reading] New timerange found [%s, %s] " % (
476 print("[Reading] New timerange found [%s, %s] " % (
476 datetime.datetime.utcfromtimestamp(
477 datetime.datetime.utcfromtimestamp(
477 self.__startUTCSecond - self.__timezone),
478 self.__startUTCSecond - self.__timezone),
478 datetime.datetime.utcfromtimestamp(
479 datetime.datetime.utcfromtimestamp(
479 self.__endUTCSecond - self.__timezone)
480 self.__endUTCSecond - self.__timezone)
480 ))
481 ))
481
482
482 return True
483 return True
483
484
484 return False
485 return False
485
486
486 def timeit(self, toExecute):
487 def timeit(self, toExecute):
487 t0 = time.time()
488 t0 = time.time()
488 toExecute()
489 toExecute()
489 self.executionTime = time.time() - t0
490 self.executionTime = time.time() - t0
490 if self.oldAverage is None:
491 if self.oldAverage is None:
491 self.oldAverage = self.executionTime
492 self.oldAverage = self.executionTime
492 self.oldAverage = (self.executionTime + self.count *
493 self.oldAverage = (self.executionTime + self.count *
493 self.oldAverage) / (self.count + 1.0)
494 self.oldAverage) / (self.count + 1.0)
494 self.count = self.count + 1.0
495 self.count = self.count + 1.0
495 return
496 return
496
497
497 def __readNextBlock(self, seconds=30, volt_scale=1):
498 def __readNextBlock(self, seconds=30, volt_scale=1):
498 '''
499 '''
499 '''
500 '''
500
501
501 # Set the next data
502 # Set the next data
502 self.__flagDiscontinuousBlock = False
503 self.__flagDiscontinuousBlock = False
503 self.__thisUnixSample += self.__samples_to_read
504 self.__thisUnixSample += self.__samples_to_read
504
505
505 if self.__thisUnixSample + 2 * self.__samples_to_read > self.__endUTCSecond * self.__sample_rate:
506 if self.__thisUnixSample + 2 * self.__samples_to_read > self.__endUTCSecond * self.__sample_rate:
506 print ("[Reading] There are no more data into selected time-range")
507 print ("[Reading] There are no more data into selected time-range")
507 if self.__online:
508 if self.__online:
508 sleep(3)
509 sleep(3)
509 self.__reload()
510 self.__reload()
510 else:
511 else:
511 return False
512 return False
512
513
513 if self.__thisUnixSample + 2 * self.__samples_to_read > self.__endUTCSecond * self.__sample_rate:
514 if self.__thisUnixSample + 2 * self.__samples_to_read > self.__endUTCSecond * self.__sample_rate:
514 return False
515 return False
515 self.__thisUnixSample -= self.__samples_to_read
516 self.__thisUnixSample -= self.__samples_to_read
516
517
517 indexChannel = 0
518 indexChannel = 0
518
519
519 dataOk = False
520 dataOk = False
520
521
521 for thisChannelName in self.__channelNameList: # TODO VARIOS CHANNELS?
522 for thisChannelName in self.__channelNameList: # TODO VARIOS CHANNELS?
522 for indexSubchannel in range(self.__num_subchannels):
523 for indexSubchannel in range(self.__num_subchannels):
523 try:
524 try:
524 t0 = time()
525 t0 = time()
526 #print("Unitindex",self.__thisUnixSample)
527 #print("__samples_to_read",self.__samples_to_read)
525 result = self.digitalReadObj.read_vector_c81d(self.__thisUnixSample,
528 result = self.digitalReadObj.read_vector_c81d(self.__thisUnixSample,
526 self.__samples_to_read,
529 self.__samples_to_read,
527 thisChannelName, sub_channel=indexSubchannel)
530 thisChannelName, sub_channel=indexSubchannel)
528 self.executionTime = time() - t0
531 self.executionTime = time() - t0
529 if self.oldAverage is None:
532 if self.oldAverage is None:
530 self.oldAverage = self.executionTime
533 self.oldAverage = self.executionTime
531 self.oldAverage = (
534 self.oldAverage = (
532 self.executionTime + self.count * self.oldAverage) / (self.count + 1.0)
535 self.executionTime + self.count * self.oldAverage) / (self.count + 1.0)
533 self.count = self.count + 1.0
536 self.count = self.count + 1.0
534
537
535 except IOError as e:
538 except IOError as e:
536 # read next profile
539 # read next profile
537 self.__flagDiscontinuousBlock = True
540 self.__flagDiscontinuousBlock = True
538 print("[Reading] %s" % datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone), e)
541 print("[Reading] %s" % datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone), e)
539 break
542 break
540
543
541 if result.shape[0] != self.__samples_to_read:
544 if result.shape[0] != self.__samples_to_read:
542 self.__flagDiscontinuousBlock = True
545 self.__flagDiscontinuousBlock = True
543 print("[Reading] %s: Too few samples were found, just %d/%d samples" % (datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
546 print("[Reading] %s: Too few samples were found, just %d/%d samples" % (datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
544 result.shape[0],
547 result.shape[0],
545 self.__samples_to_read))
548 self.__samples_to_read))
546 break
549 break
547
550
548 self.__data_buffer[indexChannel, :] = result * volt_scale
551 self.__data_buffer[indexChannel, :] = result * volt_scale
549 indexChannel+=1
552 indexChannel+=1
550
553
551 dataOk = True
554 dataOk = True
552
555
553 self.__utctime = self.__thisUnixSample / self.__sample_rate
556 self.__utctime = self.__thisUnixSample / self.__sample_rate
554
557
555 if not dataOk:
558 if not dataOk:
556 return False
559 return False
557
560
558 print("[Reading] %s: %d samples <> %f sec" % (datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
561 print("[Reading] %s: %d samples <> %f sec" % (datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
559 self.__samples_to_read,
562 self.__samples_to_read,
560 self.__timeInterval))
563 self.__timeInterval))
561
564
562 self.__bufferIndex = 0
565 self.__bufferIndex = 0
563
566
564 return True
567 return True
565
568
566 def __isBufferEmpty(self):
569 def __isBufferEmpty(self):
567
570
568 return self.__bufferIndex > self.__samples_to_read - self.__nSamples # 40960 - 40
571 return self.__bufferIndex > self.__samples_to_read - self.__nSamples # 40960 - 40
569
572
570 def getData(self, seconds=30, nTries=5):
573 def getData(self, seconds=30, nTries=5):
571 '''
574 '''
572 This method gets the data from files and put the data into the dataOut object
575 This method gets the data from files and put the data into the dataOut object
573
576
574 In addition, increase el the buffer counter in one.
577 In addition, increase el the buffer counter in one.
575
578
576 Return:
579 Return:
577 data : retorna un perfil de voltages (alturas * canales) copiados desde el
580 data : retorna un perfil de voltages (alturas * canales) copiados desde el
578 buffer. Si no hay mas archivos a leer retorna None.
581 buffer. Si no hay mas archivos a leer retorna None.
579
582
580 Affected:
583 Affected:
581 self.dataOut
584 self.dataOut
582 self.profileIndex
585 self.profileIndex
583 self.flagDiscontinuousBlock
586 self.flagDiscontinuousBlock
584 self.flagIsNewBlock
587 self.flagIsNewBlock
585 '''
588 '''
586 #print("getdata")
589 #print("getdata")
587 err_counter = 0
590 err_counter = 0
588 self.dataOut.flagNoData = True
591 self.dataOut.flagNoData = True
589
592
590
593
591 if self.__isBufferEmpty():
594 if self.__isBufferEmpty():
592 #print("hi")
595 #print("hi")
593 self.__flagDiscontinuousBlock = False
596 self.__flagDiscontinuousBlock = False
594
597
595 while True:
598 while True:
596 if self.__readNextBlock():
599 if self.__readNextBlock():
597 break
600 break
598 if self.__thisUnixSample > self.__endUTCSecond * self.__sample_rate:
601 if self.__thisUnixSample > self.__endUTCSecond * self.__sample_rate:
599 raise schainpy.admin.SchainError('Error')
602 raise schainpy.admin.SchainError('Error')
600 return
603 return
601
604
602 if self.__flagDiscontinuousBlock:
605 if self.__flagDiscontinuousBlock:
603 raise schainpy.admin.SchainError('discontinuous block found')
606 raise schainpy.admin.SchainError('discontinuous block found')
604 return
607 return
605
608
606 if not self.__online:
609 if not self.__online:
607 raise schainpy.admin.SchainError('Online?')
610 raise schainpy.admin.SchainError('Online?')
608 return
611 return
609
612
610 err_counter += 1
613 err_counter += 1
611 if err_counter > nTries:
614 if err_counter > nTries:
612 raise schainpy.admin.SchainError('Max retrys reach')
615 raise schainpy.admin.SchainError('Max retrys reach')
613 return
616 return
614
617
615 print('[Reading] waiting %d seconds to read a new block' % seconds)
618 print('[Reading] waiting %d seconds to read a new block' % seconds)
616 sleep(seconds)
619 sleep(seconds)
617
620
618
621
619 if not self.getByBlock:
622 if not self.getByBlock:
620
623
621 #print("self.__bufferIndex",self.__bufferIndex)# este valor siempre es cero aparentemente
624 #print("self.__bufferIndex",self.__bufferIndex)# este valor siempre es cero aparentemente
622 self.dataOut.data = self.__data_buffer[:, self.__bufferIndex:self.__bufferIndex + self.__nSamples]
625 self.dataOut.data = self.__data_buffer[:, self.__bufferIndex:self.__bufferIndex + self.__nSamples]
623 self.dataOut.utctime = ( self.__thisUnixSample + self.__bufferIndex) / self.__sample_rate
626 self.dataOut.utctime = ( self.__thisUnixSample + self.__bufferIndex) / self.__sample_rate
624 self.dataOut.flagNoData = False
627 self.dataOut.flagNoData = False
625 self.dataOut.flagDiscontinuousBlock = self.__flagDiscontinuousBlock
628 self.dataOut.flagDiscontinuousBlock = self.__flagDiscontinuousBlock
626 self.dataOut.profileIndex = self.profileIndex
629 self.dataOut.profileIndex = self.profileIndex
627
630
628 self.__bufferIndex += self.__nSamples
631 self.__bufferIndex += self.__nSamples
629 self.profileIndex += 1
632 self.profileIndex += 1
630
633
631 if self.profileIndex == self.dataOut.nProfiles:
634 if self.profileIndex == self.dataOut.nProfiles:
632 self.profileIndex = 0
635 self.profileIndex = 0
633 else:
636 else:
634 # ojo debo anadir el readNextBLock y el __isBufferEmpty(
637 # ojo debo anadir el readNextBLock y el __isBufferEmpty(
635 self.dataOut.flagNoData = False
638 self.dataOut.flagNoData = False
636 buffer = self.__data_buffer[:,self.__bufferIndex:self.__bufferIndex + self.__samples_to_read]
639 buffer = self.__data_buffer[:,self.__bufferIndex:self.__bufferIndex + self.__samples_to_read]
640 #print("test",self.__bufferIndex)
637 buffer = buffer.reshape((self.__nChannels, self.nProfileBlocks, int(self.__samples_to_read/self.nProfileBlocks)))
641 buffer = buffer.reshape((self.__nChannels, self.nProfileBlocks, int(self.__samples_to_read/self.nProfileBlocks)))
638 self.dataOut.nProfileBlocks = self.nProfileBlocks
642 self.dataOut.nProfileBlocks = self.nProfileBlocks
639 self.dataOut.data = buffer
643 self.dataOut.data = buffer
640 self.dataOut.utctime = ( self.__thisUnixSample + self.__bufferIndex) / self.__sample_rate
644 self.dataOut.utctime = ( self.__thisUnixSample + self.__bufferIndex) / self.__sample_rate
641 self.profileIndex += self.__samples_to_read
645 self.profileIndex += self.__samples_to_read
642 self.__bufferIndex += self.__samples_to_read
646 self.__bufferIndex += self.__samples_to_read
643 self.dataOut.flagDiscontinuousBlock = self.__flagDiscontinuousBlock
647 self.dataOut.flagDiscontinuousBlock = self.__flagDiscontinuousBlock
644 return True
648 return True
645
649
646
650
647 def printInfo(self):
651 def printInfo(self):
648 '''
652 '''
649 '''
653 '''
650 if self.__printInfo == False:
654 if self.__printInfo == False:
651 return
655 return
652
656
653 # self.systemHeaderObj.printInfo()
657 # self.systemHeaderObj.printInfo()
654 # self.radarControllerHeaderObj.printInfo()
658 # self.radarControllerHeaderObj.printInfo()
655
659
656 self.__printInfo = False
660 self.__printInfo = False
657
661
658 def printNumberOfBlock(self):
662 def printNumberOfBlock(self):
659 '''
663 '''
660 '''
664 '''
661 return
665 return
662 # print self.profileIndex
666 # print self.profileIndex
663
667
664 def run(self, **kwargs):
668 def run(self, **kwargs):
665 '''
669 '''
666 This method will be called many times so here you should put all your code
670 This method will be called many times so here you should put all your code
667 '''
671 '''
668
672
669 if not self.isConfig:
673 if not self.isConfig:
670 self.setup(**kwargs)
674 self.setup(**kwargs)
671
675
672 self.getData(seconds=self.__delay)
676 self.getData(seconds=self.__delay)
673
677
674 return
678 return
675
679
676 @MPDecorator
680 @MPDecorator
677 class DigitalRFWriter(Operation):
681 class DigitalRFWriter(Operation):
678 '''
682 '''
679 classdocs
683 classdocs
680 '''
684 '''
681
685
682 def __init__(self, **kwargs):
686 def __init__(self, **kwargs):
683 '''
687 '''
684 Constructor
688 Constructor
685 '''
689 '''
686 Operation.__init__(self, **kwargs)
690 Operation.__init__(self, **kwargs)
687 self.metadata_dict = {}
691 self.metadata_dict = {}
688 self.dataOut = None
692 self.dataOut = None
689 self.dtype = None
693 self.dtype = None
690 self.oldAverage = 0
694 self.oldAverage = 0
691
695
692 def setHeader(self):
696 def setHeader(self):
693
697
694 self.metadata_dict['frequency'] = self.dataOut.frequency
698 self.metadata_dict['frequency'] = self.dataOut.frequency
695 self.metadata_dict['timezone'] = self.dataOut.timeZone
699 self.metadata_dict['timezone'] = self.dataOut.timeZone
696 self.metadata_dict['dtype'] = pickle.dumps(self.dataOut.dtype)
700 self.metadata_dict['dtype'] = pickle.dumps(self.dataOut.dtype)
697 self.metadata_dict['nProfiles'] = self.dataOut.nProfiles
701 self.metadata_dict['nProfiles'] = self.dataOut.nProfiles
698 self.metadata_dict['heightList'] = self.dataOut.heightList
702 self.metadata_dict['heightList'] = self.dataOut.heightList
699 self.metadata_dict['channelList'] = self.dataOut.channelList
703 self.metadata_dict['channelList'] = self.dataOut.channelList
700 self.metadata_dict['flagDecodeData'] = self.dataOut.flagDecodeData
704 self.metadata_dict['flagDecodeData'] = self.dataOut.flagDecodeData
701 self.metadata_dict['flagDeflipData'] = self.dataOut.flagDeflipData
705 self.metadata_dict['flagDeflipData'] = self.dataOut.flagDeflipData
702 self.metadata_dict['flagShiftFFT'] = self.dataOut.flagShiftFFT
706 self.metadata_dict['flagShiftFFT'] = self.dataOut.flagShiftFFT
703 self.metadata_dict['useLocalTime'] = self.dataOut.useLocalTime
707 self.metadata_dict['useLocalTime'] = self.dataOut.useLocalTime
704 self.metadata_dict['nCohInt'] = self.dataOut.nCohInt
708 self.metadata_dict['nCohInt'] = self.dataOut.nCohInt
705 self.metadata_dict['type'] = self.dataOut.type
709 self.metadata_dict['type'] = self.dataOut.type
706 self.metadata_dict['flagDataAsBlock']= getattr(
710 self.metadata_dict['flagDataAsBlock']= getattr(
707 self.dataOut, 'flagDataAsBlock', None) # chequear
711 self.dataOut, 'flagDataAsBlock', None) # chequear
708
712
709 def setup(self, dataOut, path, frequency, fileCadence, dirCadence, metadataCadence, set=0, metadataFile='metadata', ext='.h5'):
713 def setup(self, dataOut, path, frequency, fileCadence, dirCadence, metadataCadence, set=0, metadataFile='metadata', ext='.h5'):
710 '''
714 '''
711 In this method we should set all initial parameters.
715 In this method we should set all initial parameters.
712 Input:
716 Input:
713 dataOut: Input data will also be outputa data
717 dataOut: Input data will also be outputa data
714 '''
718 '''
715 self.setHeader()
719 self.setHeader()
716 self.__ippSeconds = dataOut.ippSeconds
720 self.__ippSeconds = dataOut.ippSeconds
717 self.__deltaH = dataOut.getDeltaH()
721 self.__deltaH = dataOut.getDeltaH()
718 self.__sample_rate = 1e6 * 0.15 / self.__deltaH
722 self.__sample_rate = 1e6 * 0.15 / self.__deltaH
719 self.__dtype = dataOut.dtype
723 self.__dtype = dataOut.dtype
720 if len(dataOut.dtype) == 2:
724 if len(dataOut.dtype) == 2:
721 self.__dtype = dataOut.dtype[0]
725 self.__dtype = dataOut.dtype[0]
722 self.__nSamples = dataOut.systemHeaderObj.nSamples
726 self.__nSamples = dataOut.systemHeaderObj.nSamples
723 self.__nProfiles = dataOut.nProfiles
727 self.__nProfiles = dataOut.nProfiles
724
728
725 if self.dataOut.type != 'Voltage':
729 if self.dataOut.type != 'Voltage':
726 raise 'Digital RF cannot be used with this data type'
730 raise 'Digital RF cannot be used with this data type'
727 self.arr_data = numpy.ones((1, dataOut.nFFTPoints * len(
731 self.arr_data = numpy.ones((1, dataOut.nFFTPoints * len(
728 self.dataOut.channelList)), dtype=[('r', self.__dtype), ('i', self.__dtype)])
732 self.dataOut.channelList)), dtype=[('r', self.__dtype), ('i', self.__dtype)])
729 else:
733 else:
730 self.arr_data = numpy.ones((self.__nSamples, len(
734 self.arr_data = numpy.ones((self.__nSamples, len(
731 self.dataOut.channelList)), dtype=[('r', self.__dtype), ('i', self.__dtype)])
735 self.dataOut.channelList)), dtype=[('r', self.__dtype), ('i', self.__dtype)])
732
736
733 file_cadence_millisecs = 1000
737 file_cadence_millisecs = 1000
734
738
735 sample_rate_fraction = Fraction(self.__sample_rate).limit_denominator()
739 sample_rate_fraction = Fraction(self.__sample_rate).limit_denominator()
736 sample_rate_numerator = int(sample_rate_fraction.numerator)
740 sample_rate_numerator = int(sample_rate_fraction.numerator)
737 sample_rate_denominator = int(sample_rate_fraction.denominator)
741 sample_rate_denominator = int(sample_rate_fraction.denominator)
738 start_global_index = dataOut.utctime * self.__sample_rate
742 start_global_index = dataOut.utctime * self.__sample_rate
739
743
740 uuid = 'prueba'
744 uuid = 'prueba'
741 compression_level = 0
745 compression_level = 0
742 checksum = False
746 checksum = False
743 is_complex = True
747 is_complex = True
744 num_subchannels = len(dataOut.channelList)
748 num_subchannels = len(dataOut.channelList)
745 is_continuous = True
749 is_continuous = True
746 marching_periods = False
750 marching_periods = False
747
751
748 self.digitalWriteObj = digital_rf.DigitalRFWriter(path, self.__dtype, dirCadence,
752 self.digitalWriteObj = digital_rf.DigitalRFWriter(path, self.__dtype, dirCadence,
749 fileCadence, start_global_index,
753 fileCadence, start_global_index,
750 sample_rate_numerator, sample_rate_denominator, uuid, compression_level, checksum,
754 sample_rate_numerator, sample_rate_denominator, uuid, compression_level, checksum,
751 is_complex, num_subchannels, is_continuous, marching_periods)
755 is_complex, num_subchannels, is_continuous, marching_periods)
752 metadata_dir = os.path.join(path, 'metadata')
756 metadata_dir = os.path.join(path, 'metadata')
753 os.system('mkdir %s' % (metadata_dir))
757 os.system('mkdir %s' % (metadata_dir))
754 self.digitalMetadataWriteObj = digital_rf.DigitalMetadataWriter(metadata_dir, dirCadence, 1, # 236, file_cadence_millisecs / 1000
758 self.digitalMetadataWriteObj = digital_rf.DigitalMetadataWriter(metadata_dir, dirCadence, 1, # 236, file_cadence_millisecs / 1000
755 sample_rate_numerator, sample_rate_denominator,
759 sample_rate_numerator, sample_rate_denominator,
756 metadataFile)
760 metadataFile)
757 self.isConfig = True
761 self.isConfig = True
758 self.currentSample = 0
762 self.currentSample = 0
759 self.oldAverage = 0
763 self.oldAverage = 0
760 self.count = 0
764 self.count = 0
761 return
765 return
762
766
763 def writeMetadata(self):
767 def writeMetadata(self):
764 start_idx = self.__sample_rate * self.dataOut.utctime
768 start_idx = self.__sample_rate * self.dataOut.utctime
765
769
766 self.metadata_dict['processingHeader'] = self.dataOut.processingHeaderObj.getAsDict(
770 self.metadata_dict['processingHeader'] = self.dataOut.processingHeaderObj.getAsDict(
767 )
771 )
768 self.metadata_dict['radarControllerHeader'] = self.dataOut.radarControllerHeaderObj.getAsDict(
772 self.metadata_dict['radarControllerHeader'] = self.dataOut.radarControllerHeaderObj.getAsDict(
769 )
773 )
770 self.metadata_dict['systemHeader'] = self.dataOut.systemHeaderObj.getAsDict(
774 self.metadata_dict['systemHeader'] = self.dataOut.systemHeaderObj.getAsDict(
771 )
775 )
772 self.digitalMetadataWriteObj.write(start_idx, self.metadata_dict)
776 self.digitalMetadataWriteObj.write(start_idx, self.metadata_dict)
773 return
777 return
774
778
775 def timeit(self, toExecute):
779 def timeit(self, toExecute):
776 t0 = time()
780 t0 = time()
777 toExecute()
781 toExecute()
778 self.executionTime = time() - t0
782 self.executionTime = time() - t0
779 if self.oldAverage is None:
783 if self.oldAverage is None:
780 self.oldAverage = self.executionTime
784 self.oldAverage = self.executionTime
781 self.oldAverage = (self.executionTime + self.count *
785 self.oldAverage = (self.executionTime + self.count *
782 self.oldAverage) / (self.count + 1.0)
786 self.oldAverage) / (self.count + 1.0)
783 self.count = self.count + 1.0
787 self.count = self.count + 1.0
784 return
788 return
785
789
786 def writeData(self):
790 def writeData(self):
787 if self.dataOut.type != 'Voltage':
791 if self.dataOut.type != 'Voltage':
788 raise 'Digital RF cannot be used with this data type'
792 raise 'Digital RF cannot be used with this data type'
789 for channel in self.dataOut.channelList:
793 for channel in self.dataOut.channelList:
790 for i in range(self.dataOut.nFFTPoints):
794 for i in range(self.dataOut.nFFTPoints):
791 self.arr_data[1][channel * self.dataOut.nFFTPoints +
795 self.arr_data[1][channel * self.dataOut.nFFTPoints +
792 i]['r'] = self.dataOut.data[channel][i].real
796 i]['r'] = self.dataOut.data[channel][i].real
793 self.arr_data[1][channel * self.dataOut.nFFTPoints +
797 self.arr_data[1][channel * self.dataOut.nFFTPoints +
794 i]['i'] = self.dataOut.data[channel][i].imag
798 i]['i'] = self.dataOut.data[channel][i].imag
795 else:
799 else:
796 for i in range(self.dataOut.systemHeaderObj.nSamples):
800 for i in range(self.dataOut.systemHeaderObj.nSamples):
797 for channel in self.dataOut.channelList:
801 for channel in self.dataOut.channelList:
798 self.arr_data[i][channel]['r'] = self.dataOut.data[channel][i].real
802 self.arr_data[i][channel]['r'] = self.dataOut.data[channel][i].real
799 self.arr_data[i][channel]['i'] = self.dataOut.data[channel][i].imag
803 self.arr_data[i][channel]['i'] = self.dataOut.data[channel][i].imag
800
804
801 def f(): return self.digitalWriteObj.rf_write(self.arr_data)
805 def f(): return self.digitalWriteObj.rf_write(self.arr_data)
802 self.timeit(f)
806 self.timeit(f)
803
807
804 return
808 return
805
809
806 def run(self, dataOut, frequency=49.92e6, path=None, fileCadence=1000, dirCadence=36000, metadataCadence=1, **kwargs):
810 def run(self, dataOut, frequency=49.92e6, path=None, fileCadence=1000, dirCadence=36000, metadataCadence=1, **kwargs):
807 '''
811 '''
808 This method will be called many times so here you should put all your code
812 This method will be called many times so here you should put all your code
809 Inputs:
813 Inputs:
810 dataOut: object with the data
814 dataOut: object with the data
811 '''
815 '''
812 # print dataOut.__dict__
816 # print dataOut.__dict__
813 self.dataOut = dataOut
817 self.dataOut = dataOut
814 if not self.isConfig:
818 if not self.isConfig:
815 self.setup(dataOut, path, frequency, fileCadence,
819 self.setup(dataOut, path, frequency, fileCadence,
816 dirCadence, metadataCadence, **kwargs)
820 dirCadence, metadataCadence, **kwargs)
817 self.writeMetadata()
821 self.writeMetadata()
818
822
819 self.writeData()
823 self.writeData()
820
824
821 ## self.currentSample += 1
825 ## self.currentSample += 1
822 # if self.dataOut.flagDataAsBlock or self.currentSample == 1:
826 # if self.dataOut.flagDataAsBlock or self.currentSample == 1:
823 # self.writeMetadata()
827 # self.writeMetadata()
824 ## if self.currentSample == self.__nProfiles: self.currentSample = 0
828 ## if self.currentSample == self.__nProfiles: self.currentSample = 0
825
829
826 return dataOut# en la version 2.7 no aparece este return
830 return dataOut# en la version 2.7 no aparece este return
827
831
828 def close(self):
832 def close(self):
829 print('[Writing] - Closing files ')
833 print('[Writing] - Closing files ')
830 print('Average of writing to digital rf format is ', self.oldAverage * 1000)
834 print('Average of writing to digital rf format is ', self.oldAverage * 1000)
831 try:
835 try:
832 self.digitalWriteObj.close()
836 self.digitalWriteObj.close()
833 except:
837 except:
834 pass
838 pass
@@ -1,714 +1,731
1 import os
1 import os
2 import time
2 import time
3 import datetime
3 import datetime
4
4
5 import numpy
5 import numpy
6 import h5py
6 import h5py
7
7
8 import schainpy.admin
8 import schainpy.admin
9 from schainpy.model.data.jrodata import *
9 from schainpy.model.data.jrodata import *
10 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
10 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
11 from schainpy.model.io.jroIO_base import *
11 from schainpy.model.io.jroIO_base import *
12 from schainpy.utils import log
12 from schainpy.utils import log
13
13
14
14
15 class HDFReader(Reader, ProcessingUnit):
15 class HDFReader(Reader, ProcessingUnit):
16 """Processing unit to read HDF5 format files
16 """Processing unit to read HDF5 format files
17
17
18 This unit reads HDF5 files created with `HDFWriter` operation contains
18 This unit reads HDF5 files created with `HDFWriter` operation contains
19 by default two groups Data and Metadata all variables would be saved as `dataOut`
19 by default two groups Data and Metadata all variables would be saved as `dataOut`
20 attributes.
20 attributes.
21 It is possible to read any HDF5 file by given the structure in the `description`
21 It is possible to read any HDF5 file by given the structure in the `description`
22 parameter, also you can add extra values to metadata with the parameter `extras`.
22 parameter, also you can add extra values to metadata with the parameter `extras`.
23
23
24 Parameters:
24 Parameters:
25 -----------
25 -----------
26 path : str
26 path : str
27 Path where files are located.
27 Path where files are located.
28 startDate : date
28 startDate : date
29 Start date of the files
29 Start date of the files
30 endDate : list
30 endDate : list
31 End date of the files
31 End date of the files
32 startTime : time
32 startTime : time
33 Start time of the files
33 Start time of the files
34 endTime : time
34 endTime : time
35 End time of the files
35 End time of the files
36 description : dict, optional
36 description : dict, optional
37 Dictionary with the description of the HDF5 file
37 Dictionary with the description of the HDF5 file
38 extras : dict, optional
38 extras : dict, optional
39 Dictionary with extra metadata to be be added to `dataOut`
39 Dictionary with extra metadata to be be added to `dataOut`
40
40
41 Examples
41 Examples
42 --------
42 --------
43
43
44 desc = {
44 desc = {
45 'Data': {
45 'Data': {
46 'data_output': ['u', 'v', 'w'],
46 'data_output': ['u', 'v', 'w'],
47 'utctime': 'timestamps',
47 'utctime': 'timestamps',
48 } ,
48 } ,
49 'Metadata': {
49 'Metadata': {
50 'heightList': 'heights'
50 'heightList': 'heights'
51 }
51 }
52 }
52 }
53
53
54 desc = {
54 desc = {
55 'Data': {
55 'Data': {
56 'data_output': 'winds',
56 'data_output': 'winds',
57 'utctime': 'timestamps'
57 'utctime': 'timestamps'
58 },
58 },
59 'Metadata': {
59 'Metadata': {
60 'heightList': 'heights'
60 'heightList': 'heights'
61 }
61 }
62 }
62 }
63
63
64 extras = {
64 extras = {
65 'timeZone': 300
65 'timeZone': 300
66 }
66 }
67
67
68 reader = project.addReadUnit(
68 reader = project.addReadUnit(
69 name='HDFReader',
69 name='HDFReader',
70 path='/path/to/files',
70 path='/path/to/files',
71 startDate='2019/01/01',
71 startDate='2019/01/01',
72 endDate='2019/01/31',
72 endDate='2019/01/31',
73 startTime='00:00:00',
73 startTime='00:00:00',
74 endTime='23:59:59',
74 endTime='23:59:59',
75 # description=json.dumps(desc),
75 # description=json.dumps(desc),
76 # extras=json.dumps(extras),
76 # extras=json.dumps(extras),
77 )
77 )
78
78
79 """
79 """
80
80
81 __attrs__ = ['path', 'startDate', 'endDate', 'startTime', 'endTime', 'description', 'extras']
81 __attrs__ = ['path', 'startDate', 'endDate', 'startTime', 'endTime', 'description', 'extras']
82
82
83 def __init__(self):
83 def __init__(self):
84 ProcessingUnit.__init__(self)
84 ProcessingUnit.__init__(self)
85 self.dataOut = Parameters()
85 self.dataOut = Parameters()
86 self.ext = ".hdf5"
86 self.ext = ".hdf5"
87 self.optchar = "D"
87 self.optchar = "D"
88 self.meta = {}
88 self.meta = {}
89 self.data = {}
89 self.data = {}
90 self.open_file = h5py.File
90 self.open_file = h5py.File
91 self.open_mode = 'r'
91 self.open_mode = 'r'
92 self.description = {}
92 self.description = {}
93 self.extras = {}
93 self.extras = {}
94 self.filefmt = "*%Y%j***"
94 self.filefmt = "*%Y%j***"
95 self.folderfmt = "*%Y%j"
95 self.folderfmt = "*%Y%j"
96 self.utcoffset = 0
96 self.utcoffset = 0
97
97
98 def setup(self, **kwargs):
98 def setup(self, **kwargs):
99
99
100 self.set_kwargs(**kwargs)
100 self.set_kwargs(**kwargs)
101 if not self.ext.startswith('.'):
101 if not self.ext.startswith('.'):
102 self.ext = '.{}'.format(self.ext)
102 self.ext = '.{}'.format(self.ext)
103
103
104 if self.online:
104 if self.online:
105 log.log("Searching files in online mode...", self.name)
105 log.log("Searching files in online mode...", self.name)
106
106
107 for nTries in range(self.nTries):
107 for nTries in range(self.nTries):
108 fullpath = self.searchFilesOnLine(self.path, self.startDate,
108 fullpath = self.searchFilesOnLine(self.path, self.startDate,
109 self.endDate, self.expLabel, self.ext, self.walk,
109 self.endDate, self.expLabel, self.ext, self.walk,
110 self.filefmt, self.folderfmt)
110 self.filefmt, self.folderfmt)
111 try:
111 try:
112 fullpath = next(fullpath)
112 fullpath = next(fullpath)
113 except:
113 except:
114 fullpath = None
114 fullpath = None
115
115
116 if fullpath:
116 if fullpath:
117 break
117 break
118
118
119 log.warning(
119 log.warning(
120 'Waiting {} sec for a valid file in {}: try {} ...'.format(
120 'Waiting {} sec for a valid file in {}: try {} ...'.format(
121 self.delay, self.path, nTries + 1),
121 self.delay, self.path, nTries + 1),
122 self.name)
122 self.name)
123 time.sleep(self.delay)
123 time.sleep(self.delay)
124
124
125 if not(fullpath):
125 if not(fullpath):
126 raise schainpy.admin.SchainError(
126 raise schainpy.admin.SchainError(
127 'There isn\'t any valid file in {}'.format(self.path))
127 'There isn\'t any valid file in {}'.format(self.path))
128
128
129 pathname, filename = os.path.split(fullpath)
129 pathname, filename = os.path.split(fullpath)
130 self.year = int(filename[1:5])
130 self.year = int(filename[1:5])
131 self.doy = int(filename[5:8])
131 self.doy = int(filename[5:8])
132 self.set = int(filename[8:11]) - 1
132 self.set = int(filename[8:11]) - 1
133 else:
133 else:
134 log.log("Searching files in {}".format(self.path), self.name)
134 log.log("Searching files in {}".format(self.path), self.name)
135 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
135 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
136 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
136 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
137
137
138 self.setNextFile()
138 self.setNextFile()
139
139
140 return
140 return
141
141
142 def readFirstHeader(self):
142 def readFirstHeader(self):
143 '''Read metadata and data'''
143 '''Read metadata and data'''
144
144
145 self.__readMetadata()
145 self.__readMetadata()
146 self.__readData()
146 self.__readData()
147 self.__setBlockList()
147 self.__setBlockList()
148
148
149 if 'type' in self.meta:
149 if 'type' in self.meta:
150 self.dataOut = eval(self.meta['type'])()
150 self.dataOut = eval(self.meta['type'])()
151
151
152 for attr in self.meta:
152 for attr in self.meta:
153 setattr(self.dataOut, attr, self.meta[attr])
153 setattr(self.dataOut, attr, self.meta[attr])
154
154
155 self.blockIndex = 0
155 self.blockIndex = 0
156
156
157 return
157 return
158
158
159 def __setBlockList(self):
159 def __setBlockList(self):
160 '''
160 '''
161 Selects the data within the times defined
161 Selects the data within the times defined
162
162
163 self.fp
163 self.fp
164 self.startTime
164 self.startTime
165 self.endTime
165 self.endTime
166 self.blockList
166 self.blockList
167 self.blocksPerFile
167 self.blocksPerFile
168
168
169 '''
169 '''
170
170
171 startTime = self.startTime
171 startTime = self.startTime
172 endTime = self.endTime
172 endTime = self.endTime
173 thisUtcTime = self.data['utctime'] + self.utcoffset
173 thisUtcTime = self.data['utctime'] + self.utcoffset
174 self.interval = numpy.min(thisUtcTime[1:] - thisUtcTime[:-1])
174 self.interval = numpy.min(thisUtcTime[1:] - thisUtcTime[:-1])
175 thisDatetime = datetime.datetime.utcfromtimestamp(thisUtcTime[0])
175 thisDatetime = datetime.datetime.utcfromtimestamp(thisUtcTime[0])
176
176
177 thisDate = thisDatetime.date()
177 thisDate = thisDatetime.date()
178 thisTime = thisDatetime.time()
178 thisTime = thisDatetime.time()
179
179
180 startUtcTime = (datetime.datetime.combine(thisDate, startTime) - datetime.datetime(1970, 1, 1)).total_seconds()
180 startUtcTime = (datetime.datetime.combine(thisDate, startTime) - datetime.datetime(1970, 1, 1)).total_seconds()
181 endUtcTime = (datetime.datetime.combine(thisDate, endTime) - datetime.datetime(1970, 1, 1)).total_seconds()
181 endUtcTime = (datetime.datetime.combine(thisDate, endTime) - datetime.datetime(1970, 1, 1)).total_seconds()
182
182
183 ind = numpy.where(numpy.logical_and(thisUtcTime >= startUtcTime, thisUtcTime < endUtcTime))[0]
183 ind = numpy.where(numpy.logical_and(thisUtcTime >= startUtcTime, thisUtcTime < endUtcTime))[0]
184
184
185 self.blockList = ind
185 self.blockList = ind
186 self.blocksPerFile = len(ind)
186 self.blocksPerFile = len(ind)
187 return
187 return
188
188
189 def __readMetadata(self):
189 def __readMetadata(self):
190 '''
190 '''
191 Reads Metadata
191 Reads Metadata
192 '''
192 '''
193
193
194 meta = {}
194 meta = {}
195
195
196 if self.description:
196 if self.description:
197 for key, value in self.description['Metadata'].items():
197 for key, value in self.description['Metadata'].items():
198 meta[key] = self.fp[value][()]
198 meta[key] = self.fp[value][()]
199 else:
199 else:
200 grp = self.fp['Metadata']
200 grp = self.fp['Metadata']
201 for name in grp:
201 for name in grp:
202 meta[name] = grp[name][()]
202 meta[name] = grp[name][()]
203
203
204 if self.extras:
204 if self.extras:
205 for key, value in self.extras.items():
205 for key, value in self.extras.items():
206 meta[key] = value
206 meta[key] = value
207 self.meta = meta
207 self.meta = meta
208
208
209 return
209 return
210
210
211 def __readData(self):
211 def __readData(self):
212
212
213 data = {}
213 data = {}
214
214
215 if self.description:
215 if self.description:
216 for key, value in self.description['Data'].items():
216 for key, value in self.description['Data'].items():
217 if isinstance(value, str):
217 if isinstance(value, str):
218 if isinstance(self.fp[value], h5py.Dataset):
218 if isinstance(self.fp[value], h5py.Dataset):
219 data[key] = self.fp[value][()]
219 data[key] = self.fp[value][()]
220 elif isinstance(self.fp[value], h5py.Group):
220 elif isinstance(self.fp[value], h5py.Group):
221 array = []
221 array = []
222 for ch in self.fp[value]:
222 for ch in self.fp[value]:
223 array.append(self.fp[value][ch][()])
223 array.append(self.fp[value][ch][()])
224 data[key] = numpy.array(array)
224 data[key] = numpy.array(array)
225 elif isinstance(value, list):
225 elif isinstance(value, list):
226 array = []
226 array = []
227 for ch in value:
227 for ch in value:
228 array.append(self.fp[ch][()])
228 array.append(self.fp[ch][()])
229 data[key] = numpy.array(array)
229 data[key] = numpy.array(array)
230 else:
230 else:
231 grp = self.fp['Data']
231 grp = self.fp['Data']
232 for name in grp:
232 for name in grp:
233 if isinstance(grp[name], h5py.Dataset):
233 if isinstance(grp[name], h5py.Dataset):
234 array = grp[name][()]
234 array = grp[name][()]
235 elif isinstance(grp[name], h5py.Group):
235 elif isinstance(grp[name], h5py.Group):
236 array = []
236 array = []
237 for ch in grp[name]:
237 for ch in grp[name]:
238 array.append(grp[name][ch][()])
238 array.append(grp[name][ch][()])
239 array = numpy.array(array)
239 array = numpy.array(array)
240 else:
240 else:
241 log.warning('Unknown type: {}'.format(name))
241 log.warning('Unknown type: {}'.format(name))
242
242
243 if name in self.description:
243 if name in self.description:
244 key = self.description[name]
244 key = self.description[name]
245 else:
245 else:
246 key = name
246 key = name
247 data[key] = array
247 data[key] = array
248
248
249 self.data = data
249 self.data = data
250 return
250 return
251
251
252 def getData(self):
252 def getData(self):
253
253
254 for attr in self.data:
254 for attr in self.data:
255 if self.data[attr].ndim == 1:
255 if self.data[attr].ndim == 1:
256 setattr(self.dataOut, attr, self.data[attr][self.blockIndex])
256 setattr(self.dataOut, attr, self.data[attr][self.blockIndex])
257 else:
257 else:
258 setattr(self.dataOut, attr, self.data[attr][:, self.blockIndex])
258 setattr(self.dataOut, attr, self.data[attr][:, self.blockIndex])
259
259
260 self.dataOut.flagNoData = False
260 self.dataOut.flagNoData = False
261 self.blockIndex += 1
261 self.blockIndex += 1
262
262
263 log.log("Block No. {}/{} -> {}".format(
263 log.log("Block No. {}/{} -> {}".format(
264 self.blockIndex,
264 self.blockIndex,
265 self.blocksPerFile,
265 self.blocksPerFile,
266 self.dataOut.datatime.ctime()), self.name)
266 self.dataOut.datatime.ctime()), self.name)
267
267
268 return
268 return
269
269
270 def run(self, **kwargs):
270 def run(self, **kwargs):
271
271
272 if not(self.isConfig):
272 if not(self.isConfig):
273 self.setup(**kwargs)
273 self.setup(**kwargs)
274 self.isConfig = True
274 self.isConfig = True
275
275
276 if self.blockIndex == self.blocksPerFile:
276 if self.blockIndex == self.blocksPerFile:
277 self.setNextFile()
277 self.setNextFile()
278
278
279 self.getData()
279 self.getData()
280
280
281 return
281 return
282
282
283 @MPDecorator
283 @MPDecorator
284 class HDFWriter(Operation):
284 class HDFWriter(Operation):
285 """Operation to write HDF5 files.
285 """Operation to write HDF5 files.
286
286
287 The HDF5 file contains by default two groups Data and Metadata where
287 The HDF5 file contains by default two groups Data and Metadata where
288 you can save any `dataOut` attribute specified by `dataList` and `metadataList`
288 you can save any `dataOut` attribute specified by `dataList` and `metadataList`
289 parameters, data attributes are normaly time dependent where the metadata
289 parameters, data attributes are normaly time dependent where the metadata
290 are not.
290 are not.
291 It is possible to customize the structure of the HDF5 file with the
291 It is possible to customize the structure of the HDF5 file with the
292 optional description parameter see the examples.
292 optional description parameter see the examples.
293
293
294 Parameters:
294 Parameters:
295 -----------
295 -----------
296 path : str
296 path : str
297 Path where files will be saved.
297 Path where files will be saved.
298 blocksPerFile : int
298 blocksPerFile : int
299 Number of blocks per file
299 Number of blocks per file
300 metadataList : list
300 metadataList : list
301 List of the dataOut attributes that will be saved as metadata
301 List of the dataOut attributes that will be saved as metadata
302 dataList : int
302 dataList : int
303 List of the dataOut attributes that will be saved as data
303 List of the dataOut attributes that will be saved as data
304 setType : bool
304 setType : bool
305 If True the name of the files corresponds to the timestamp of the data
305 If True the name of the files corresponds to the timestamp of the data
306 description : dict, optional
306 description : dict, optional
307 Dictionary with the desired description of the HDF5 file
307 Dictionary with the desired description of the HDF5 file
308
308
309 Examples
309 Examples
310 --------
310 --------
311
311
312 desc = {
312 desc = {
313 'data_output': {'winds': ['z', 'w', 'v']},
313 'data_output': {'winds': ['z', 'w', 'v']},
314 'utctime': 'timestamps',
314 'utctime': 'timestamps',
315 'heightList': 'heights'
315 'heightList': 'heights'
316 }
316 }
317 desc = {
317 desc = {
318 'data_output': ['z', 'w', 'v'],
318 'data_output': ['z', 'w', 'v'],
319 'utctime': 'timestamps',
319 'utctime': 'timestamps',
320 'heightList': 'heights'
320 'heightList': 'heights'
321 }
321 }
322 desc = {
322 desc = {
323 'Data': {
323 'Data': {
324 'data_output': 'winds',
324 'data_output': 'winds',
325 'utctime': 'timestamps'
325 'utctime': 'timestamps'
326 },
326 },
327 'Metadata': {
327 'Metadata': {
328 'heightList': 'heights'
328 'heightList': 'heights'
329 }
329 }
330 }
330 }
331
331
332 writer = proc_unit.addOperation(name='HDFWriter')
332 writer = proc_unit.addOperation(name='HDFWriter')
333 writer.addParameter(name='path', value='/path/to/file')
333 writer.addParameter(name='path', value='/path/to/file')
334 writer.addParameter(name='blocksPerFile', value='32')
334 writer.addParameter(name='blocksPerFile', value='32')
335 writer.addParameter(name='metadataList', value='heightList,timeZone')
335 writer.addParameter(name='metadataList', value='heightList,timeZone')
336 writer.addParameter(name='dataList',value='data_output,utctime')
336 writer.addParameter(name='dataList',value='data_output,utctime')
337 # writer.addParameter(name='description',value=json.dumps(desc))
337 # writer.addParameter(name='description',value=json.dumps(desc))
338
338
339 """
339 """
340
340
341 ext = ".hdf5"
341 ext = ".hdf5"
342 optchar = "D"
342 optchar = "D"
343 filename = None
343 filename = None
344 path = None
344 path = None
345 setFile = None
345 setFile = None
346 fp = None
346 fp = None
347 firsttime = True
347 firsttime = True
348 #Configurations
348 #Configurations
349 blocksPerFile = None
349 blocksPerFile = None
350 blockIndex = None
350 blockIndex = None
351 dataOut = None
351 dataOut = None
352 #Data Arrays
352 #Data Arrays
353 dataList = None
353 dataList = None
354 metadataList = None
354 metadataList = None
355 currentDay = None
355 currentDay = None
356 lastTime = None
356 lastTime = None
357 last_Azipos = None
357 last_Azipos = None
358 last_Elepos = None
358 last_Elepos = None
359 mode = None
359 mode = None
360 #-----------------------
360 #-----------------------
361 Typename = None
361 Typename = None
362
362
363
363
364
364
365 def __init__(self):
365 def __init__(self):
366
366
367 Operation.__init__(self)
367 Operation.__init__(self)
368 return
368 return
369
369
370
370
371 def set_kwargs(self, **kwargs):
371 def set_kwargs(self, **kwargs):
372
372
373 for key, value in kwargs.items():
373 for key, value in kwargs.items():
374 setattr(self, key, value)
374 setattr(self, key, value)
375
375
376 def set_kwargs_obj(self,obj, **kwargs):
376 def set_kwargs_obj(self,obj, **kwargs):
377
377
378 for key, value in kwargs.items():
378 for key, value in kwargs.items():
379 setattr(obj, key, value)
379 setattr(obj, key, value)
380
380
381 def generalFlag(self):
381 def generalFlag(self):
382 ####rint("GENERALFLAG")
382 ####rint("GENERALFLAG")
383 if self.mode== "weather":
383 if self.mode== "weather":
384 if self.last_Azipos == None:
384 if self.last_Azipos == None:
385 tmp = self.dataOut.azimuth
385 tmp = self.dataOut.azimuth
386 ####print("ang azimuth writer",tmp)
386 ####print("ang azimuth writer",tmp)
387 self.last_Azipos = tmp
387 self.last_Azipos = tmp
388 flag = False
388 flag = False
389 return flag
389 return flag
390 ####print("ang_azimuth writer",self.dataOut.azimuth)
390 ####print("ang_azimuth writer",self.dataOut.azimuth)
391 result = self.dataOut.azimuth - self.last_Azipos
391 result = self.dataOut.azimuth - self.last_Azipos
392 self.last_Azipos = self.dataOut.azimuth
392 self.last_Azipos = self.dataOut.azimuth
393 if result<0:
393 if result<0:
394 flag = True
394 flag = True
395 return flag
395 return flag
396
396
397 def generalFlag_vRF(self):
397 def generalFlag_vRF(self):
398 ####rint("GENERALFLAG")
398 ####rint("GENERALFLAG")
399
399
400 try:
400 try:
401 self.dataOut.flagBlock360Done
401 self.dataOut.flagBlock360Done
402 return self.dataOut.flagBlock360Done
402 return self.dataOut.flagBlock360Done
403 except:
403 except:
404 return 0
404 return 0
405
405
406
406
407 def setup(self, path=None, blocksPerFile=10, metadataList=None, dataList=None, setType=None, description=None,type_data=None,**kwargs):
407 def setup(self, path=None, blocksPerFile=10, metadataList=None, dataList=None, setType=None, description=None,type_data=None,**kwargs):
408 self.path = path
408 self.path = path
409 self.blocksPerFile = blocksPerFile
409 self.blocksPerFile = blocksPerFile
410 self.metadataList = metadataList
410 self.metadataList = metadataList
411 self.dataList = [s.strip() for s in dataList]
411 self.dataList = [s.strip() for s in dataList]
412 self.setType = setType
412 self.setType = setType
413 if self.mode == "weather":
413 if self.mode == "weather":
414 self.setType = "weather"
414 self.setType = "weather"
415 self.set_kwargs(**kwargs)
415 self.set_kwargs(**kwargs)
416 self.set_kwargs_obj(self.dataOut,**kwargs)
416 self.set_kwargs_obj(self.dataOut,**kwargs)
417
417
418
418
419 self.description = description
419 self.description = description
420 self.type_data=type_data
420 self.type_data=type_data
421
421
422 if self.metadataList is None:
422 if self.metadataList is None:
423 self.metadataList = self.dataOut.metadata_list
423 self.metadataList = self.dataOut.metadata_list
424
424
425 tableList = []
425 tableList = []
426 dsList = []
426 dsList = []
427
427
428 for i in range(len(self.dataList)):
428 for i in range(len(self.dataList)):
429 dsDict = {}
429 dsDict = {}
430 if hasattr(self.dataOut, self.dataList[i]):
430 if hasattr(self.dataOut, self.dataList[i]):
431 dataAux = getattr(self.dataOut, self.dataList[i])
431 dataAux = getattr(self.dataOut, self.dataList[i])
432 dsDict['variable'] = self.dataList[i]
432 dsDict['variable'] = self.dataList[i]
433 else:
433 else:
434 log.warning('Attribute {} not found in dataOut', self.name)
434 log.warning('Attribute {} not found in dataOut', self.name)
435 continue
435 continue
436
436
437 if dataAux is None:
437 if dataAux is None:
438 continue
438 continue
439 elif isinstance(dataAux, (int, float, numpy.integer, numpy.float)):
439 elif isinstance(dataAux, (int, float, numpy.integer, numpy.float)):
440 dsDict['nDim'] = 0
440 dsDict['nDim'] = 0
441 else:
441 else:
442 dsDict['nDim'] = len(dataAux.shape)
442 dsDict['nDim'] = len(dataAux.shape)
443 dsDict['shape'] = dataAux.shape
443 dsDict['shape'] = dataAux.shape
444 dsDict['dsNumber'] = dataAux.shape[0]
444 dsDict['dsNumber'] = dataAux.shape[0]
445 dsDict['dtype'] = dataAux.dtype
445 dsDict['dtype'] = dataAux.dtype
446 dsList.append(dsDict)
446 dsList.append(dsDict)
447
447
448 self.dsList = dsList
448 self.dsList = dsList
449 self.currentDay = self.dataOut.datatime.date()
449 self.currentDay = self.dataOut.datatime.date()
450
450
451 def timeFlag(self):
451 def timeFlag(self):
452 currentTime = self.dataOut.utctime
452 currentTime = self.dataOut.utctime
453 timeTuple = time.localtime(currentTime)
453 timeTuple = time.localtime(currentTime)
454 dataDay = timeTuple.tm_yday
454 dataDay = timeTuple.tm_yday
455
455
456 if self.lastTime is None:
456 if self.lastTime is None:
457 self.lastTime = currentTime
457 self.lastTime = currentTime
458 self.currentDay = dataDay
458 self.currentDay = dataDay
459 return False
459 return False
460
460
461 timeDiff = currentTime - self.lastTime
461 timeDiff = currentTime - self.lastTime
462
462
463 #Si el dia es diferente o si la diferencia entre un dato y otro supera la hora
463 #Si el dia es diferente o si la diferencia entre un dato y otro supera la hora
464 if dataDay != self.currentDay:
464 if dataDay != self.currentDay:
465 self.currentDay = dataDay
465 self.currentDay = dataDay
466 return True
466 return True
467 elif timeDiff > 3*60*60:
467 elif timeDiff > 3*60*60:
468 self.lastTime = currentTime
468 self.lastTime = currentTime
469 return True
469 return True
470 else:
470 else:
471 self.lastTime = currentTime
471 self.lastTime = currentTime
472 return False
472 return False
473
473
474 def run(self, dataOut, path, blocksPerFile=10, metadataList=None,
474 def run(self, dataOut, path, blocksPerFile=10, metadataList=None,
475 dataList=[], setType=None, description={},mode= None,type_data=None,Reset = False,**kwargs):
475 dataList=[], setType=None, description={},mode= None,type_data=None,Reset = False,**kwargs):
476
476
477 if Reset:
477 if Reset:
478 self.isConfig = False
478 self.isConfig = False
479 self.closeFile()
479 self.closeFile()
480 self.lastTime = None
480 self.lastTime = None
481 self.blockIndex = 0
481 self.blockIndex = 0
482
482
483 self.dataOut = dataOut
483 self.dataOut = dataOut
484 self.mode = mode
484 self.mode = mode
485 self.var = dataList[0]
486
485 if not(self.isConfig):
487 if not(self.isConfig):
486 self.setup(path=path, blocksPerFile=blocksPerFile,
488 self.setup(path=path, blocksPerFile=blocksPerFile,
487 metadataList=metadataList, dataList=dataList,
489 metadataList=metadataList, dataList=dataList,
488 setType=setType, description=description,type_data=type_data,**kwargs)
490 setType=setType, description=description,type_data=type_data,**kwargs)
489
491
490 self.isConfig = True
492 self.isConfig = True
491 self.setNextFile()
493 self.setNextFile()
492
494
493 self.putData()
495 self.putData()
494 return
496 return
495
497
496 def setNextFile(self):
498 def setNextFile(self):
497 ###print("HELLO WORLD--------------------------------")
499 ###print("HELLO WORLD--------------------------------")
498 ext = self.ext
500 ext = self.ext
499 path = self.path
501 path = self.path
500 setFile = self.setFile
502 setFile = self.setFile
501 type_data = self.type_data
503 type_data = self.type_data
502
504
503 timeTuple = time.localtime(self.dataOut.utctime)
505 timeTuple = time.localtime(self.dataOut.utctime)
504 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
506 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
505 fullpath = os.path.join(path, subfolder)
507 fullpath = os.path.join(path, subfolder)
506
508
507 if os.path.exists(fullpath):
509 if os.path.exists(fullpath):
508 filesList = os.listdir(fullpath)
510 filesList = os.listdir(fullpath)
509 filesList = [k for k in filesList if k.startswith(self.optchar)]
511 filesList = [k for k in filesList if k.startswith(self.optchar)]
510 if len( filesList ) > 0:
512 if len( filesList ) > 0:
511 filesList = sorted(filesList, key=str.lower)
513 filesList = sorted(filesList, key=str.lower)
512 filen = filesList[-1]
514 filen = filesList[-1]
513 # el filename debera tener el siguiente formato
515 # el filename debera tener el siguiente formato
514 # 0 1234 567 89A BCDE (hex)
516 # 0 1234 567 89A BCDE (hex)
515 # x YYYY DDD SSS .ext
517 # x YYYY DDD SSS .ext
516 if isNumber(filen[8:11]):
518 if isNumber(filen[8:11]):
517 setFile = int(filen[8:11]) #inicializo mi contador de seteo al seteo del ultimo file
519 setFile = int(filen[8:11]) #inicializo mi contador de seteo al seteo del ultimo file
518 else:
520 else:
519 setFile = -1
521 setFile = -1
520 else:
522 else:
521 setFile = -1 #inicializo mi contador de seteo
523 setFile = -1 #inicializo mi contador de seteo
522 else:
524 else:
523 os.makedirs(fullpath)
525 os.makedirs(fullpath)
524 setFile = -1 #inicializo mi contador de seteo
526 setFile = -1 #inicializo mi contador de seteo
525
527
526 ###print("**************************",self.setType)
528 ###print("**************************",self.setType)
527 if self.setType is None:
529 if self.setType is None:
528 setFile += 1
530 setFile += 1
529 file = '%s%4.4d%3.3d%03d%s' % (self.optchar,
531 file = '%s%4.4d%3.3d%03d%s' % (self.optchar,
530 timeTuple.tm_year,
532 timeTuple.tm_year,
531 timeTuple.tm_yday,
533 timeTuple.tm_yday,
532 setFile,
534 setFile,
533 ext )
535 ext )
534 elif self.setType == "weather":
536 elif self.setType == "weather":
535 print("HOLA AMIGOS")
536 wr_exp = self.dataOut.wr_exp
537 if wr_exp== "PPI":
538 wr_type = 'E'
539 ang_ = numpy.mean(self.dataOut.elevation)
540 else:
541 wr_type = 'A'
542 ang_ = numpy.mean(self.dataOut.azimuth)
543
537
544 wr_writer = '%s%s%2.1f%s'%('-',
538 if self.var.lower() == 'Zdb'.lower():
545 wr_type,
539 wr_type = 'Z'
540 elif self.var.lower() == 'Zdb_D'.lower():
541 wr_type = 'D'
542 elif self.var.lower() == 'PhiD_P'.lower():
543 wr_type = 'P'
544 elif self.var.lower() == 'RhoHV_R'.lower():
545 wr_type = 'R'
546 elif self.var.lower() == 'velRadial_V'.lower():
547 wr_type = 'V'
548 elif self.var.lower() == 'Sigmav_W'.lower():
549 wr_type = 'S'
550 elif self.var.lower() == 'dataPP_POWER'.lower():
551 wr_type = 'Pow'
552 elif self.var.lower() == 'dataPP_DOP'.lower():
553 wr_type = 'Dop'
554
555
556 #Z_SOPHy_El10.0_20200505_14:02:15.h5
557 #Z_SOPHy_Az40.0_20200505_14:02:15.h5
558 if self.dataOut.flagMode == 1: #'AZI' #PPI
559 ang_type = 'El'
560 ang_ = round(numpy.mean(self.dataOut.data_ele),1)
561 elif self.dataOut.flagMode == 0: #'ELE' #RHI
562 ang_type = 'Az'
563 ang_ = round(numpy.mean(self.dataOut.data_azi),1)
564
565 file = '%s%s%s%2.1f%s%2.2d%2.2d%2.2d%s%2.2d%2.2d%2.2d%s' % (wr_type,
566 '_SOPHy_',
567 ang_type,
546 ang_,
568 ang_,
547 '-')
569 '_',
548 ###print("wr_writer********************",wr_writer)
549 file = '%s%4.4d%2.2d%2.2d%s%2.2d%2.2d%2.2d%s%s%s' % (self.optchar,
550 timeTuple.tm_year,
570 timeTuple.tm_year,
551 timeTuple.tm_mon,
571 timeTuple.tm_mon,
552 timeTuple.tm_mday,
572 timeTuple.tm_mday,
553 '-',
573 '_',
554 timeTuple.tm_hour,
574 timeTuple.tm_hour,
555 timeTuple.tm_min,
575 timeTuple.tm_min,
556 timeTuple.tm_sec,
576 timeTuple.tm_sec,
557 wr_writer,
558 type_data,
559 ext )
577 ext )
560 ###print("FILENAME", file)
561
562
578
563 else:
579 else:
564 setFile = timeTuple.tm_hour*60+timeTuple.tm_min
580 setFile = timeTuple.tm_hour*60+timeTuple.tm_min
565 file = '%s%4.4d%3.3d%04d%s' % (self.optchar,
581 file = '%s%4.4d%3.3d%04d%s' % (self.optchar,
566 timeTuple.tm_year,
582 timeTuple.tm_year,
567 timeTuple.tm_yday,
583 timeTuple.tm_yday,
568 setFile,
584 setFile,
569 ext )
585 ext )
570
586
571 self.filename = os.path.join( path, subfolder, file )
587 self.filename = os.path.join( path, subfolder, file )
572
588
573 #Setting HDF5 File
589 #Setting HDF5 File
574
590 print("filename",self.filename)
575 self.fp = h5py.File(self.filename, 'w')
591 self.fp = h5py.File(self.filename, 'w')
576 #write metadata
592 #write metadata
577 self.writeMetadata(self.fp)
593 self.writeMetadata(self.fp)
578 #Write data
594 #Write data
579 self.writeData(self.fp)
595 self.writeData(self.fp)
580
596
581 def getLabel(self, name, x=None):
597 def getLabel(self, name, x=None):
582
598
583 if x is None:
599 if x is None:
584 if 'Data' in self.description:
600 if 'Data' in self.description:
585 data = self.description['Data']
601 data = self.description['Data']
586 if 'Metadata' in self.description:
602 if 'Metadata' in self.description:
587 data.update(self.description['Metadata'])
603 data.update(self.description['Metadata'])
588 else:
604 else:
589 data = self.description
605 data = self.description
590 if name in data:
606 if name in data:
591 if isinstance(data[name], str):
607 if isinstance(data[name], str):
592 return data[name]
608 return data[name]
593 elif isinstance(data[name], list):
609 elif isinstance(data[name], list):
594 return None
610 return None
595 elif isinstance(data[name], dict):
611 elif isinstance(data[name], dict):
596 for key, value in data[name].items():
612 for key, value in data[name].items():
597 return key
613 return key
598 return name
614 return name
599 else:
615 else:
600 if 'Metadata' in self.description:
616 if 'Metadata' in self.description:
601 meta = self.description['Metadata']
617 meta = self.description['Metadata']
602 else:
618 else:
603 meta = self.description
619 meta = self.description
604 if name in meta:
620 if name in meta:
605 if isinstance(meta[name], list):
621 if isinstance(meta[name], list):
606 return meta[name][x]
622 return meta[name][x]
607 elif isinstance(meta[name], dict):
623 elif isinstance(meta[name], dict):
608 for key, value in meta[name].items():
624 for key, value in meta[name].items():
609 return value[x]
625 return value[x]
610 if 'cspc' in name:
626 if 'cspc' in name:
611 return 'pair{:02d}'.format(x)
627 return 'pair{:02d}'.format(x)
612 else:
628 else:
613 return 'channel{:02d}'.format(x)
629 return 'channel{:02d}'.format(x)
614
630
615 def writeMetadata(self, fp):
631 def writeMetadata(self, fp):
616
632
617 if self.description:
633 if self.description:
618 if 'Metadata' in self.description:
634 if 'Metadata' in self.description:
619 grp = fp.create_group('Metadata')
635 grp = fp.create_group('Metadata')
620 else:
636 else:
621 grp = fp
637 grp = fp
622 else:
638 else:
623 grp = fp.create_group('Metadata')
639 grp = fp.create_group('Metadata')
624
640
625 for i in range(len(self.metadataList)):
641 for i in range(len(self.metadataList)):
626 if not hasattr(self.dataOut, self.metadataList[i]):
642 if not hasattr(self.dataOut, self.metadataList[i]):
627 log.warning('Metadata: `{}` not found'.format(self.metadataList[i]), self.name)
643 log.warning('Metadata: `{}` not found'.format(self.metadataList[i]), self.name)
628 continue
644 continue
629 value = getattr(self.dataOut, self.metadataList[i])
645 value = getattr(self.dataOut, self.metadataList[i])
630 if isinstance(value, bool):
646 if isinstance(value, bool):
631 if value is True:
647 if value is True:
632 value = 1
648 value = 1
633 else:
649 else:
634 value = 0
650 value = 0
635 grp.create_dataset(self.getLabel(self.metadataList[i]), data=value)
651 grp.create_dataset(self.getLabel(self.metadataList[i]), data=value)
636 return
652 return
637
653
638 def writeData(self, fp):
654 def writeData(self, fp):
639
655
640 if self.description:
656 if self.description:
641 if 'Data' in self.description:
657 if 'Data' in self.description:
642 grp = fp.create_group('Data')
658 grp = fp.create_group('Data')
643 else:
659 else:
644 grp = fp
660 grp = fp
645 else:
661 else:
646 grp = fp.create_group('Data')
662 grp = fp.create_group('Data')
647
663
648 dtsets = []
664 dtsets = []
649 data = []
665 data = []
650
666
651 for dsInfo in self.dsList:
667 for dsInfo in self.dsList:
652 if dsInfo['nDim'] == 0:
668 if dsInfo['nDim'] == 0:
653 ds = grp.create_dataset(
669 ds = grp.create_dataset(
654 self.getLabel(dsInfo['variable']),
670 self.getLabel(dsInfo['variable']),
655 (self.blocksPerFile, ),
671 (self.blocksPerFile, ),
656 chunks=True,
672 chunks=True,
657 dtype=numpy.float64)
673 dtype=numpy.float64)
658 dtsets.append(ds)
674 dtsets.append(ds)
659 data.append((dsInfo['variable'], -1))
675 data.append((dsInfo['variable'], -1))
660 else:
676 else:
661 label = self.getLabel(dsInfo['variable'])
677 label = self.getLabel(dsInfo['variable'])
662 if label is not None:
678 if label is not None:
663 sgrp = grp.create_group(label)
679 sgrp = grp.create_group(label)
664 else:
680 else:
665 sgrp = grp
681 sgrp = grp
666 for i in range(dsInfo['dsNumber']):
682 for i in range(dsInfo['dsNumber']):
667 ds = sgrp.create_dataset(
683 ds = sgrp.create_dataset(
668 self.getLabel(dsInfo['variable'], i),
684 self.getLabel(dsInfo['variable'], i),
669 (self.blocksPerFile, ) + dsInfo['shape'][1:],
685 (self.blocksPerFile, ) + dsInfo['shape'][1:],
670 chunks=True,
686 chunks=True,
671 dtype=dsInfo['dtype'])
687 dtype=dsInfo['dtype'])
672 dtsets.append(ds)
688 dtsets.append(ds)
673 data.append((dsInfo['variable'], i))
689 data.append((dsInfo['variable'], i))
674 fp.flush()
690 fp.flush()
675
691
676 log.log('Creating file: {}'.format(fp.filename), self.name)
692 log.log('Creating file: {}'.format(fp.filename), self.name)
677
693
678 self.ds = dtsets
694 self.ds = dtsets
679 self.data = data
695 self.data = data
680 self.firsttime = True
696 self.firsttime = True
681 self.blockIndex = 0
697 self.blockIndex = 0
682 return
698 return
683
699
684 def putData(self):
700 def putData(self):
701
685 if (self.blockIndex == self.blocksPerFile) or self.timeFlag():# or self.generalFlag_vRF():
702 if (self.blockIndex == self.blocksPerFile) or self.timeFlag():# or self.generalFlag_vRF():
686 self.closeFile()
703 self.closeFile()
687 self.setNextFile()
704 self.setNextFile()
688
705
689 for i, ds in enumerate(self.ds):
706 for i, ds in enumerate(self.ds):
690 attr, ch = self.data[i]
707 attr, ch = self.data[i]
691 if ch == -1:
708 if ch == -1:
692 ds[self.blockIndex] = getattr(self.dataOut, attr)
709 ds[self.blockIndex] = getattr(self.dataOut, attr)
693 else:
710 else:
694 ds[self.blockIndex] = getattr(self.dataOut, attr)[ch]
711 ds[self.blockIndex] = getattr(self.dataOut, attr)[ch]
695
712
696 self.fp.flush()
713 self.fp.flush()
697 self.blockIndex += 1
714 self.blockIndex += 1
698 log.log('Block No. {}/{}'.format(self.blockIndex, self.blocksPerFile), self.name)
715 log.log('Block No. {}/{}'.format(self.blockIndex, self.blocksPerFile), self.name)
699
716
700 return
717 return
701
718
702 def closeFile(self):
719 def closeFile(self):
703
720
704 if self.blockIndex != self.blocksPerFile:
721 if self.blockIndex != self.blocksPerFile:
705 for ds in self.ds:
722 for ds in self.ds:
706 ds.resize(self.blockIndex, axis=0)
723 ds.resize(self.blockIndex, axis=0)
707
724
708 if self.fp:
725 if self.fp:
709 self.fp.flush()
726 self.fp.flush()
710 self.fp.close()
727 self.fp.close()
711
728
712 def close(self):
729 def close(self):
713
730
714 self.closeFile()
731 self.closeFile()
@@ -1,226 +1,236
1 '''
1 '''
2 Base clases to create Processing units and operations, the MPDecorator
2 Base clases to create Processing units and operations, the MPDecorator
3 must be used in plotting and writing operations to allow to run as an
3 must be used in plotting and writing operations to allow to run as an
4 external process.
4 external process.
5 '''
5 '''
6
6
7 import os
7 import os
8 import inspect
8 import inspect
9 import zmq
9 import zmq
10 import time
10 import time
11 import pickle
11 import pickle
12 import traceback
12 import traceback
13 from threading import Thread
13 from threading import Thread
14 from multiprocessing import Process, Queue
14 from multiprocessing import Process, Queue
15 from schainpy.utils import log
15 from schainpy.utils import log
16
16
17 QUEUE_SIZE = int(os.environ.get('QUEUE_MAX_SIZE', '10'))
17 QUEUE_SIZE = int(os.environ.get('QUEUE_MAX_SIZE', '10'))
18
18
19 class ProcessingUnit(object):
19 class ProcessingUnit(object):
20 '''
20 '''
21 Base class to create Signal Chain Units
21 Base class to create Signal Chain Units
22 '''
22 '''
23
23
24 proc_type = 'processing'
24 proc_type = 'processing'
25
25
26 def __init__(self):
26 def __init__(self):
27
27
28 self.dataIn = None
28 self.dataIn = None
29 self.dataOut = None
29 self.dataOut = None
30 self.isConfig = False
30 self.isConfig = False
31 self.operations = []
31 self.operations = []
32 self.name = 'Test'
32 self.name = 'Test'
33 self.inputs = []
33 self.inputs = []
34
34
35 def setInput(self, unit):
35 def setInput(self, unit):
36
36
37 attr = 'dataIn'
37 attr = 'dataIn'
38 for i, u in enumerate(unit):
38 for i, u in enumerate(unit):
39 if i==0:
39 if i==0:
40 self.dataIn = u.dataOut
40 self.dataIn = u.dataOut
41 self.inputs.append('dataIn')
41 self.inputs.append('dataIn')
42 else:
42 else:
43 setattr(self, 'dataIn{}'.format(i), u.dataOut)
43 setattr(self, 'dataIn{}'.format(i), u.dataOut)
44 self.inputs.append('dataIn{}'.format(i))
44 self.inputs.append('dataIn{}'.format(i))
45
45
46 def getAllowedArgs(self):
46 def getAllowedArgs(self):
47 if hasattr(self, '__attrs__'):
47 if hasattr(self, '__attrs__'):
48 return self.__attrs__
48 return self.__attrs__
49 else:
49 else:
50 return inspect.getargspec(self.run).args
50 return inspect.getargspec(self.run).args
51
51
52 def addOperation(self, conf, operation):
52 def addOperation(self, conf, operation):
53 '''
53 '''
54 '''
54 '''
55
55
56 self.operations.append((operation, conf.type, conf.getKwargs()))
56 self.operations.append((operation, conf.type, conf.getKwargs()))
57
57
58 def getOperationObj(self, objId):
58 def getOperationObj(self, objId):
59
59
60 if objId not in list(self.operations.keys()):
60 if objId not in list(self.operations.keys()):
61 return None
61 return None
62
62
63 return self.operations[objId]
63 return self.operations[objId]
64
64
65 def call(self, **kwargs):
65 def call(self, **kwargs):
66 '''
66 '''
67 '''
67 '''
68
68
69 try:
69 try:
70 if self.dataIn is not None and self.dataIn.flagNoData and not self.dataIn.error:
70 if self.dataIn is not None and self.dataIn.flagNoData and not self.dataIn.error:
71 return self.dataIn.isReady()
71 return self.dataIn.isReady()
72 elif self.dataIn is None or not self.dataIn.error:
72 elif self.dataIn is None or not self.dataIn.error:
73 self.run(**kwargs)
73 self.run(**kwargs)
74 elif self.dataIn.error:
74 elif self.dataIn.error:
75 self.dataOut.error = self.dataIn.error
75 self.dataOut.error = self.dataIn.error
76 self.dataOut.flagNoData = True
76 self.dataOut.flagNoData = True
77 except:
77 except:
78 err = traceback.format_exc()
78 err = traceback.format_exc()
79 if 'SchainWarning' in err:
79 if 'SchainWarning' in err:
80 log.warning(err.split('SchainWarning:')[-1].split('\n')[0].strip(), self.name)
80 log.warning(err.split('SchainWarning:')[-1].split('\n')[0].strip(), self.name)
81 elif 'SchainError' in err:
81 elif 'SchainError' in err:
82 log.error(err.split('SchainError:')[-1].split('\n')[0].strip(), self.name)
82 log.error(err.split('SchainError:')[-1].split('\n')[0].strip(), self.name)
83 else:
83 else:
84 log.error(err, self.name)
84 log.error(err, self.name)
85 self.dataOut.error = True
85 self.dataOut.error = True
86 ##### correcion de la declaracion Out
86 ##### correcion de la declaracion Out
87 for op, optype, opkwargs in self.operations:
87 for op, optype, opkwargs in self.operations:
88 aux = self.dataOut.copy()
88 aux = self.dataOut.copy()
89 if optype == 'other' and not self.dataOut.flagNoData:
89 '''
90 print("op",op)
91 try:
92 print("runNextOp",self.dataOut.runNextOp)
93 except:
94 pass
95 '''
96 if not hasattr(self.dataOut, 'runNextOp'):
97 self.dataOut.runNextOp = False
98 if optype == 'other' and (not self.dataOut.flagNoData or self.dataOut.runNextOp):
99 #if optype == 'other' and not self.dataOut.flagNoData:
90 self.dataOut = op.run(self.dataOut, **opkwargs)
100 self.dataOut = op.run(self.dataOut, **opkwargs)
91 elif optype == 'external' and not self.dataOut.flagNoData:
101 elif optype == 'external' and not self.dataOut.flagNoData:
92 #op.queue.put(self.dataOut)
102 #op.queue.put(self.dataOut)
93 op.queue.put(aux)
103 op.queue.put(aux)
94 elif optype == 'external' and self.dataOut.error:
104 elif optype == 'external' and self.dataOut.error:
95 #op.queue.put(self.dataOut)
105 #op.queue.put(self.dataOut)
96 op.queue.put(aux)
106 op.queue.put(aux)
97
107
98 try:
108 try:
99 if self.dataOut.runNextUnit:
109 if self.dataOut.runNextUnit:
100 runNextUnit = self.dataOut.runNextUnit
110 runNextUnit = self.dataOut.runNextUnit
101
111
102 else:
112 else:
103 runNextUnit = self.dataOut.isReady()
113 runNextUnit = self.dataOut.isReady()
104 except:
114 except:
105 runNextUnit = self.dataOut.isReady()
115 runNextUnit = self.dataOut.isReady()
106
116
107 return 'Error' if self.dataOut.error else runNextUnit
117 return 'Error' if self.dataOut.error else runNextUnit
108
118
109 def setup(self):
119 def setup(self):
110
120
111 raise NotImplementedError
121 raise NotImplementedError
112
122
113 def run(self):
123 def run(self):
114
124
115 raise NotImplementedError
125 raise NotImplementedError
116
126
117 def close(self):
127 def close(self):
118
128
119 return
129 return
120
130
121
131
122 class Operation(object):
132 class Operation(object):
123
133
124 '''
134 '''
125 '''
135 '''
126
136
127 proc_type = 'operation'
137 proc_type = 'operation'
128
138
129 def __init__(self):
139 def __init__(self):
130
140
131 self.id = None
141 self.id = None
132 self.isConfig = False
142 self.isConfig = False
133
143
134 if not hasattr(self, 'name'):
144 if not hasattr(self, 'name'):
135 self.name = self.__class__.__name__
145 self.name = self.__class__.__name__
136
146
137 def getAllowedArgs(self):
147 def getAllowedArgs(self):
138 if hasattr(self, '__attrs__'):
148 if hasattr(self, '__attrs__'):
139 return self.__attrs__
149 return self.__attrs__
140 else:
150 else:
141 return inspect.getargspec(self.run).args
151 return inspect.getargspec(self.run).args
142
152
143 def setup(self):
153 def setup(self):
144
154
145 self.isConfig = True
155 self.isConfig = True
146
156
147 raise NotImplementedError
157 raise NotImplementedError
148
158
149 def run(self, dataIn, **kwargs):
159 def run(self, dataIn, **kwargs):
150 """
160 """
151 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los
161 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los
152 atributos del objeto dataIn.
162 atributos del objeto dataIn.
153
163
154 Input:
164 Input:
155
165
156 dataIn : objeto del tipo JROData
166 dataIn : objeto del tipo JROData
157
167
158 Return:
168 Return:
159
169
160 None
170 None
161
171
162 Affected:
172 Affected:
163 __buffer : buffer de recepcion de datos.
173 __buffer : buffer de recepcion de datos.
164
174
165 """
175 """
166 if not self.isConfig:
176 if not self.isConfig:
167 self.setup(**kwargs)
177 self.setup(**kwargs)
168
178
169 raise NotImplementedError
179 raise NotImplementedError
170
180
171 def close(self):
181 def close(self):
172
182
173 return
183 return
174
184
175
185
176 def MPDecorator(BaseClass):
186 def MPDecorator(BaseClass):
177 """
187 """
178 Multiprocessing class decorator
188 Multiprocessing class decorator
179
189
180 This function add multiprocessing features to a BaseClass.
190 This function add multiprocessing features to a BaseClass.
181 """
191 """
182
192
183 class MPClass(BaseClass, Process):
193 class MPClass(BaseClass, Process):
184
194
185 def __init__(self, *args, **kwargs):
195 def __init__(self, *args, **kwargs):
186 super(MPClass, self).__init__()
196 super(MPClass, self).__init__()
187 Process.__init__(self)
197 Process.__init__(self)
188
198
189 self.args = args
199 self.args = args
190 self.kwargs = kwargs
200 self.kwargs = kwargs
191 self.t = time.time()
201 self.t = time.time()
192 self.op_type = 'external'
202 self.op_type = 'external'
193 self.name = BaseClass.__name__
203 self.name = BaseClass.__name__
194 self.__doc__ = BaseClass.__doc__
204 self.__doc__ = BaseClass.__doc__
195
205
196 if 'plot' in self.name.lower() and not self.name.endswith('_'):
206 if 'plot' in self.name.lower() and not self.name.endswith('_'):
197 self.name = '{}{}'.format(self.CODE.upper(), 'Plot')
207 self.name = '{}{}'.format(self.CODE.upper(), 'Plot')
198
208
199 self.start_time = time.time()
209 self.start_time = time.time()
200 self.err_queue = args[3]
210 self.err_queue = args[3]
201 self.queue = Queue(maxsize=QUEUE_SIZE)
211 self.queue = Queue(maxsize=QUEUE_SIZE)
202 self.myrun = BaseClass.run
212 self.myrun = BaseClass.run
203
213
204 def run(self):
214 def run(self):
205
215
206 while True:
216 while True:
207
217
208 dataOut = self.queue.get()
218 dataOut = self.queue.get()
209
219
210 if not dataOut.error:
220 if not dataOut.error:
211 try:
221 try:
212 BaseClass.run(self, dataOut, **self.kwargs)
222 BaseClass.run(self, dataOut, **self.kwargs)
213 except:
223 except:
214 err = traceback.format_exc()
224 err = traceback.format_exc()
215 log.error(err, self.name)
225 log.error(err, self.name)
216 else:
226 else:
217 break
227 break
218
228
219 self.close()
229 self.close()
220
230
221 def close(self):
231 def close(self):
222
232
223 BaseClass.close(self)
233 BaseClass.close(self)
224 log.success('Done...(Time:{:4.2f} secs)'.format(time.time()-self.start_time), self.name)
234 log.success('Done...(Time:{:4.2f} secs)'.format(time.time()-self.start_time), self.name)
225
235
226 return MPClass
236 return MPClass
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,1860 +1,1861
1 import sys
1 import sys
2 import numpy,math
2 import numpy,math
3 from scipy import interpolate
3 from scipy import interpolate
4 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
4 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
5 from schainpy.model.data.jrodata import Voltage,hildebrand_sekhon
5 from schainpy.model.data.jrodata import Voltage,hildebrand_sekhon
6 from schainpy.utils import log
6 from schainpy.utils import log
7 from time import time
7 from time import time
8
8
9
9
10
10
11 class VoltageProc(ProcessingUnit):
11 class VoltageProc(ProcessingUnit):
12
12
13 def __init__(self):
13 def __init__(self):
14
14
15 ProcessingUnit.__init__(self)
15 ProcessingUnit.__init__(self)
16
16
17 self.dataOut = Voltage()
17 self.dataOut = Voltage()
18 self.flip = 1
18 self.flip = 1
19 self.setupReq = False
19 self.setupReq = False
20
20
21 def run(self):
21 def run(self):
22
22
23 if self.dataIn.type == 'AMISR':
23 if self.dataIn.type == 'AMISR':
24 self.__updateObjFromAmisrInput()
24 self.__updateObjFromAmisrInput()
25
25
26 if self.dataIn.type == 'Voltage':
26 if self.dataIn.type == 'Voltage':
27 self.dataOut.copy(self.dataIn)
27 self.dataOut.copy(self.dataIn)
28
28
29 def __updateObjFromAmisrInput(self):
29 def __updateObjFromAmisrInput(self):
30
30
31 self.dataOut.timeZone = self.dataIn.timeZone
31 self.dataOut.timeZone = self.dataIn.timeZone
32 self.dataOut.dstFlag = self.dataIn.dstFlag
32 self.dataOut.dstFlag = self.dataIn.dstFlag
33 self.dataOut.errorCount = self.dataIn.errorCount
33 self.dataOut.errorCount = self.dataIn.errorCount
34 self.dataOut.useLocalTime = self.dataIn.useLocalTime
34 self.dataOut.useLocalTime = self.dataIn.useLocalTime
35
35
36 self.dataOut.flagNoData = self.dataIn.flagNoData
36 self.dataOut.flagNoData = self.dataIn.flagNoData
37 self.dataOut.data = self.dataIn.data
37 self.dataOut.data = self.dataIn.data
38 self.dataOut.utctime = self.dataIn.utctime
38 self.dataOut.utctime = self.dataIn.utctime
39 self.dataOut.channelList = self.dataIn.channelList
39 self.dataOut.channelList = self.dataIn.channelList
40 #self.dataOut.timeInterval = self.dataIn.timeInterval
40 #self.dataOut.timeInterval = self.dataIn.timeInterval
41 self.dataOut.heightList = self.dataIn.heightList
41 self.dataOut.heightList = self.dataIn.heightList
42 self.dataOut.nProfiles = self.dataIn.nProfiles
42 self.dataOut.nProfiles = self.dataIn.nProfiles
43
43
44 self.dataOut.nCohInt = self.dataIn.nCohInt
44 self.dataOut.nCohInt = self.dataIn.nCohInt
45 self.dataOut.ippSeconds = self.dataIn.ippSeconds
45 self.dataOut.ippSeconds = self.dataIn.ippSeconds
46 self.dataOut.frequency = self.dataIn.frequency
46 self.dataOut.frequency = self.dataIn.frequency
47
47
48 self.dataOut.azimuth = self.dataIn.azimuth
48 self.dataOut.azimuth = self.dataIn.azimuth
49 self.dataOut.zenith = self.dataIn.zenith
49 self.dataOut.zenith = self.dataIn.zenith
50
50
51 self.dataOut.beam.codeList = self.dataIn.beam.codeList
51 self.dataOut.beam.codeList = self.dataIn.beam.codeList
52 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
52 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
53 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
53 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
54
54
55
55
56 class selectChannels(Operation):
56 class selectChannels(Operation):
57
57
58 def run(self, dataOut, channelList):
58 def run(self, dataOut, channelList):
59
59
60 channelIndexList = []
60 channelIndexList = []
61 self.dataOut = dataOut
61 self.dataOut = dataOut
62 for channel in channelList:
62 for channel in channelList:
63 if channel not in self.dataOut.channelList:
63 if channel not in self.dataOut.channelList:
64 raise ValueError("Channel %d is not in %s" %(channel, str(self.dataOut.channelList)))
64 raise ValueError("Channel %d is not in %s" %(channel, str(self.dataOut.channelList)))
65
65
66 index = self.dataOut.channelList.index(channel)
66 index = self.dataOut.channelList.index(channel)
67 channelIndexList.append(index)
67 channelIndexList.append(index)
68 self.selectChannelsByIndex(channelIndexList)
68 self.selectChannelsByIndex(channelIndexList)
69 return self.dataOut
69 return self.dataOut
70
70
71 def selectChannelsByIndex(self, channelIndexList):
71 def selectChannelsByIndex(self, channelIndexList):
72 """
72 """
73 Selecciona un bloque de datos en base a canales segun el channelIndexList
73 Selecciona un bloque de datos en base a canales segun el channelIndexList
74
74
75 Input:
75 Input:
76 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
76 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
77
77
78 Affected:
78 Affected:
79 self.dataOut.data
79 self.dataOut.data
80 self.dataOut.channelIndexList
80 self.dataOut.channelIndexList
81 self.dataOut.nChannels
81 self.dataOut.nChannels
82 self.dataOut.m_ProcessingHeader.totalSpectra
82 self.dataOut.m_ProcessingHeader.totalSpectra
83 self.dataOut.systemHeaderObj.numChannels
83 self.dataOut.systemHeaderObj.numChannels
84 self.dataOut.m_ProcessingHeader.blockSize
84 self.dataOut.m_ProcessingHeader.blockSize
85
85
86 Return:
86 Return:
87 None
87 None
88 """
88 """
89
89
90 for channelIndex in channelIndexList:
90 for channelIndex in channelIndexList:
91 if channelIndex not in self.dataOut.channelIndexList:
91 if channelIndex not in self.dataOut.channelIndexList:
92 raise ValueError("The value %d in channelIndexList is not valid" %channelIndex)
92 raise ValueError("The value %d in channelIndexList is not valid" %channelIndex)
93
93
94 if self.dataOut.type == 'Voltage':
94 if self.dataOut.type == 'Voltage':
95 if self.dataOut.flagDataAsBlock:
95 if self.dataOut.flagDataAsBlock:
96 """
96 """
97 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
97 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
98 """
98 """
99 data = self.dataOut.data[channelIndexList,:,:]
99 data = self.dataOut.data[channelIndexList,:,:]
100 else:
100 else:
101 data = self.dataOut.data[channelIndexList,:]
101 data = self.dataOut.data[channelIndexList,:]
102
102
103 self.dataOut.data = data
103 self.dataOut.data = data
104 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
104 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
105 self.dataOut.channelList = range(len(channelIndexList))
105 self.dataOut.channelList = range(len(channelIndexList))
106
106
107 elif self.dataOut.type == 'Spectra':
107 elif self.dataOut.type == 'Spectra':
108 data_spc = self.dataOut.data_spc[channelIndexList, :]
108 data_spc = self.dataOut.data_spc[channelIndexList, :]
109 data_dc = self.dataOut.data_dc[channelIndexList, :]
109 data_dc = self.dataOut.data_dc[channelIndexList, :]
110
110
111 self.dataOut.data_spc = data_spc
111 self.dataOut.data_spc = data_spc
112 self.dataOut.data_dc = data_dc
112 self.dataOut.data_dc = data_dc
113
113
114 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
114 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
115 self.dataOut.channelList = range(len(channelIndexList))
115 self.dataOut.channelList = range(len(channelIndexList))
116 self.__selectPairsByChannel(channelIndexList)
116 self.__selectPairsByChannel(channelIndexList)
117
117
118 return 1
118 return 1
119
119
120 def __selectPairsByChannel(self, channelList=None):
120 def __selectPairsByChannel(self, channelList=None):
121
121
122 if channelList == None:
122 if channelList == None:
123 return
123 return
124
124
125 pairsIndexListSelected = []
125 pairsIndexListSelected = []
126 for pairIndex in self.dataOut.pairsIndexList:
126 for pairIndex in self.dataOut.pairsIndexList:
127 # First pair
127 # First pair
128 if self.dataOut.pairsList[pairIndex][0] not in channelList:
128 if self.dataOut.pairsList[pairIndex][0] not in channelList:
129 continue
129 continue
130 # Second pair
130 # Second pair
131 if self.dataOut.pairsList[pairIndex][1] not in channelList:
131 if self.dataOut.pairsList[pairIndex][1] not in channelList:
132 continue
132 continue
133
133
134 pairsIndexListSelected.append(pairIndex)
134 pairsIndexListSelected.append(pairIndex)
135
135
136 if not pairsIndexListSelected:
136 if not pairsIndexListSelected:
137 self.dataOut.data_cspc = None
137 self.dataOut.data_cspc = None
138 self.dataOut.pairsList = []
138 self.dataOut.pairsList = []
139 return
139 return
140
140
141 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndexListSelected]
141 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndexListSelected]
142 self.dataOut.pairsList = [self.dataOut.pairsList[i]
142 self.dataOut.pairsList = [self.dataOut.pairsList[i]
143 for i in pairsIndexListSelected]
143 for i in pairsIndexListSelected]
144
144
145 return
145 return
146
146
147 class selectHeights(Operation):
147 class selectHeights(Operation):
148
148
149 def run(self, dataOut, minHei=None, maxHei=None, minIndex=None, maxIndex=None):
149 def run(self, dataOut, minHei=None, maxHei=None, minIndex=None, maxIndex=None):
150 """
150 """
151 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
151 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
152 minHei <= height <= maxHei
152 minHei <= height <= maxHei
153
153
154 Input:
154 Input:
155 minHei : valor minimo de altura a considerar
155 minHei : valor minimo de altura a considerar
156 maxHei : valor maximo de altura a considerar
156 maxHei : valor maximo de altura a considerar
157
157
158 Affected:
158 Affected:
159 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
159 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
160
160
161 Return:
161 Return:
162 1 si el metodo se ejecuto con exito caso contrario devuelve 0
162 1 si el metodo se ejecuto con exito caso contrario devuelve 0
163 """
163 """
164
164
165 self.dataOut = dataOut
165 self.dataOut = dataOut
166
166
167 if minHei and maxHei:
167 if minHei and maxHei:
168
168
169 if (minHei < self.dataOut.heightList[0]):
169 if (minHei < self.dataOut.heightList[0]):
170 minHei = self.dataOut.heightList[0]
170 minHei = self.dataOut.heightList[0]
171
171
172 if (maxHei > self.dataOut.heightList[-1]):
172 if (maxHei > self.dataOut.heightList[-1]):
173 maxHei = self.dataOut.heightList[-1]
173 maxHei = self.dataOut.heightList[-1]
174
174
175 minIndex = 0
175 minIndex = 0
176 maxIndex = 0
176 maxIndex = 0
177 heights = self.dataOut.heightList
177 heights = self.dataOut.heightList
178
178
179 inda = numpy.where(heights >= minHei)
179 inda = numpy.where(heights >= minHei)
180 indb = numpy.where(heights <= maxHei)
180 indb = numpy.where(heights <= maxHei)
181
181
182 try:
182 try:
183 minIndex = inda[0][0]
183 minIndex = inda[0][0]
184 except:
184 except:
185 minIndex = 0
185 minIndex = 0
186
186
187 try:
187 try:
188 maxIndex = indb[0][-1]
188 maxIndex = indb[0][-1]
189 except:
189 except:
190 maxIndex = len(heights)
190 maxIndex = len(heights)
191
191
192 self.selectHeightsByIndex(minIndex, maxIndex)
192 self.selectHeightsByIndex(minIndex, maxIndex)
193
193
194 return self.dataOut
194 return self.dataOut
195
195
196 def selectHeightsByIndex(self, minIndex, maxIndex):
196 def selectHeightsByIndex(self, minIndex, maxIndex):
197 """
197 """
198 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
198 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
199 minIndex <= index <= maxIndex
199 minIndex <= index <= maxIndex
200
200
201 Input:
201 Input:
202 minIndex : valor de indice minimo de altura a considerar
202 minIndex : valor de indice minimo de altura a considerar
203 maxIndex : valor de indice maximo de altura a considerar
203 maxIndex : valor de indice maximo de altura a considerar
204
204
205 Affected:
205 Affected:
206 self.dataOut.data
206 self.dataOut.data
207 self.dataOut.heightList
207 self.dataOut.heightList
208
208
209 Return:
209 Return:
210 1 si el metodo se ejecuto con exito caso contrario devuelve 0
210 1 si el metodo se ejecuto con exito caso contrario devuelve 0
211 """
211 """
212
212
213 if self.dataOut.type == 'Voltage':
213 if self.dataOut.type == 'Voltage':
214 if (minIndex < 0) or (minIndex > maxIndex):
214 if (minIndex < 0) or (minIndex > maxIndex):
215 raise ValueError("Height index range (%d,%d) is not valid" % (minIndex, maxIndex))
215 raise ValueError("Height index range (%d,%d) is not valid" % (minIndex, maxIndex))
216
216
217 if (maxIndex >= self.dataOut.nHeights):
217 if (maxIndex >= self.dataOut.nHeights):
218 maxIndex = self.dataOut.nHeights
218 maxIndex = self.dataOut.nHeights
219 #print("shapeeee",self.dataOut.data.shape)
219 #print("shapeeee",self.dataOut.data.shape)
220 #voltage
220 #voltage
221 if self.dataOut.flagDataAsBlock:
221 if self.dataOut.flagDataAsBlock:
222 """
222 """
223 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
223 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
224 """
224 """
225 data = self.dataOut.data[:,:, minIndex:maxIndex]
225 data = self.dataOut.data[:,:, minIndex:maxIndex]
226 else:
226 else:
227 data = self.dataOut.data[:, minIndex:maxIndex]
227 data = self.dataOut.data[:, minIndex:maxIndex]
228
228
229 # firstHeight = self.dataOut.heightList[minIndex]
229 # firstHeight = self.dataOut.heightList[minIndex]
230
230
231 self.dataOut.data = data
231 self.dataOut.data = data
232 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex]
232 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex]
233
233
234 if self.dataOut.nHeights <= 1:
234 if self.dataOut.nHeights <= 1:
235 raise ValueError("selectHeights: Too few heights. Current number of heights is %d" %(self.dataOut.nHeights))
235 raise ValueError("selectHeights: Too few heights. Current number of heights is %d" %(self.dataOut.nHeights))
236 elif self.dataOut.type == 'Spectra':
236 elif self.dataOut.type == 'Spectra':
237 if (minIndex < 0) or (minIndex > maxIndex):
237 if (minIndex < 0) or (minIndex > maxIndex):
238 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (
238 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (
239 minIndex, maxIndex))
239 minIndex, maxIndex))
240
240
241 if (maxIndex >= self.dataOut.nHeights):
241 if (maxIndex >= self.dataOut.nHeights):
242 maxIndex = self.dataOut.nHeights - 1
242 maxIndex = self.dataOut.nHeights - 1
243
243
244 # Spectra
244 # Spectra
245 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
245 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
246
246
247 data_cspc = None
247 data_cspc = None
248 if self.dataOut.data_cspc is not None:
248 if self.dataOut.data_cspc is not None:
249 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
249 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
250
250
251 data_dc = None
251 data_dc = None
252 if self.dataOut.data_dc is not None:
252 if self.dataOut.data_dc is not None:
253 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
253 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
254
254
255 self.dataOut.data_spc = data_spc
255 self.dataOut.data_spc = data_spc
256 self.dataOut.data_cspc = data_cspc
256 self.dataOut.data_cspc = data_cspc
257 self.dataOut.data_dc = data_dc
257 self.dataOut.data_dc = data_dc
258
258
259 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
259 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
260
260
261 return 1
261 return 1
262
262
263
263
264 class filterByHeights(Operation):
264 class filterByHeights(Operation):
265
265
266 def run(self, dataOut, window):
266 def run(self, dataOut, window):
267
267
268 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
268 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
269
269
270 if window == None:
270 if window == None:
271 window = (dataOut.radarControllerHeaderObj.txA/dataOut.radarControllerHeaderObj.nBaud) / deltaHeight
271 window = (dataOut.radarControllerHeaderObj.txA/dataOut.radarControllerHeaderObj.nBaud) / deltaHeight
272
272
273 newdelta = deltaHeight * window
273 newdelta = deltaHeight * window
274 r = dataOut.nHeights % window
274 r = dataOut.nHeights % window
275 newheights = (dataOut.nHeights-r)/window
275 newheights = (dataOut.nHeights-r)/window
276
276
277 if newheights <= 1:
277 if newheights <= 1:
278 raise ValueError("filterByHeights: Too few heights. Current number of heights is %d and window is %d" %(dataOut.nHeights, window))
278 raise ValueError("filterByHeights: Too few heights. Current number of heights is %d and window is %d" %(dataOut.nHeights, window))
279
279
280 if dataOut.flagDataAsBlock:
280 if dataOut.flagDataAsBlock:
281 """
281 """
282 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
282 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
283 """
283 """
284 buffer = dataOut.data[:, :, 0:int(dataOut.nHeights-r)]
284 buffer = dataOut.data[:, :, 0:int(dataOut.nHeights-r)]
285 buffer = buffer.reshape(dataOut.nChannels, dataOut.nProfiles, int(dataOut.nHeights/window), window)
285 buffer = buffer.reshape(dataOut.nChannels, dataOut.nProfiles, int(dataOut.nHeights/window), window)
286 buffer = numpy.sum(buffer,3)
286 buffer = numpy.sum(buffer,3)
287
287
288 else:
288 else:
289 buffer = dataOut.data[:,0:int(dataOut.nHeights-r)]
289 buffer = dataOut.data[:,0:int(dataOut.nHeights-r)]
290 buffer = buffer.reshape(dataOut.nChannels,int(dataOut.nHeights/window),int(window))
290 buffer = buffer.reshape(dataOut.nChannels,int(dataOut.nHeights/window),int(window))
291 buffer = numpy.sum(buffer,2)
291 buffer = numpy.sum(buffer,2)
292
292
293 dataOut.data = buffer
293 dataOut.data = buffer
294 dataOut.heightList = dataOut.heightList[0] + numpy.arange( newheights )*newdelta
294 dataOut.heightList = dataOut.heightList[0] + numpy.arange( newheights )*newdelta
295 dataOut.windowOfFilter = window
295 dataOut.windowOfFilter = window
296
296
297 return dataOut
297 return dataOut
298
298
299
299
300 class setH0(Operation):
300 class setH0(Operation):
301
301
302 def run(self, dataOut, h0, deltaHeight = None):
302 def run(self, dataOut, h0, deltaHeight = None):
303
303
304 if not deltaHeight:
304 if not deltaHeight:
305 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
305 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
306
306
307 nHeights = dataOut.nHeights
307 nHeights = dataOut.nHeights
308
308
309 newHeiRange = h0 + numpy.arange(nHeights)*deltaHeight
309 newHeiRange = h0 + numpy.arange(nHeights)*deltaHeight
310
310
311 dataOut.heightList = newHeiRange
311 dataOut.heightList = newHeiRange
312
312
313 return dataOut
313 return dataOut
314
314
315
315
316 class deFlip(Operation):
316 class deFlip(Operation):
317
317
318 def run(self, dataOut, channelList = []):
318 def run(self, dataOut, channelList = []):
319
319
320 data = dataOut.data.copy()
320 data = dataOut.data.copy()
321
321
322 if dataOut.flagDataAsBlock:
322 if dataOut.flagDataAsBlock:
323 flip = self.flip
323 flip = self.flip
324 profileList = list(range(dataOut.nProfiles))
324 profileList = list(range(dataOut.nProfiles))
325
325
326 if not channelList:
326 if not channelList:
327 for thisProfile in profileList:
327 for thisProfile in profileList:
328 data[:,thisProfile,:] = data[:,thisProfile,:]*flip
328 data[:,thisProfile,:] = data[:,thisProfile,:]*flip
329 flip *= -1.0
329 flip *= -1.0
330 else:
330 else:
331 for thisChannel in channelList:
331 for thisChannel in channelList:
332 if thisChannel not in dataOut.channelList:
332 if thisChannel not in dataOut.channelList:
333 continue
333 continue
334
334
335 for thisProfile in profileList:
335 for thisProfile in profileList:
336 data[thisChannel,thisProfile,:] = data[thisChannel,thisProfile,:]*flip
336 data[thisChannel,thisProfile,:] = data[thisChannel,thisProfile,:]*flip
337 flip *= -1.0
337 flip *= -1.0
338
338
339 self.flip = flip
339 self.flip = flip
340
340
341 else:
341 else:
342 if not channelList:
342 if not channelList:
343 data[:,:] = data[:,:]*self.flip
343 data[:,:] = data[:,:]*self.flip
344 else:
344 else:
345 for thisChannel in channelList:
345 for thisChannel in channelList:
346 if thisChannel not in dataOut.channelList:
346 if thisChannel not in dataOut.channelList:
347 continue
347 continue
348
348
349 data[thisChannel,:] = data[thisChannel,:]*self.flip
349 data[thisChannel,:] = data[thisChannel,:]*self.flip
350
350
351 self.flip *= -1.
351 self.flip *= -1.
352
352
353 dataOut.data = data
353 dataOut.data = data
354
354
355 return dataOut
355 return dataOut
356
356
357
357
358 class setAttribute(Operation):
358 class setAttribute(Operation):
359 '''
359 '''
360 Set an arbitrary attribute(s) to dataOut
360 Set an arbitrary attribute(s) to dataOut
361 '''
361 '''
362
362
363 def __init__(self):
363 def __init__(self):
364
364
365 Operation.__init__(self)
365 Operation.__init__(self)
366 self._ready = False
366 self._ready = False
367
367
368 def run(self, dataOut, **kwargs):
368 def run(self, dataOut, **kwargs):
369
369
370 for key, value in kwargs.items():
370 for key, value in kwargs.items():
371 setattr(dataOut, key, value)
371 setattr(dataOut, key, value)
372
372
373 return dataOut
373 return dataOut
374
374
375
375
376 @MPDecorator
376 @MPDecorator
377 class printAttribute(Operation):
377 class printAttribute(Operation):
378 '''
378 '''
379 Print an arbitrary attribute of dataOut
379 Print an arbitrary attribute of dataOut
380 '''
380 '''
381
381
382 def __init__(self):
382 def __init__(self):
383
383
384 Operation.__init__(self)
384 Operation.__init__(self)
385
385
386 def run(self, dataOut, attributes):
386 def run(self, dataOut, attributes):
387
387
388 if isinstance(attributes, str):
388 if isinstance(attributes, str):
389 attributes = [attributes]
389 attributes = [attributes]
390 for attr in attributes:
390 for attr in attributes:
391 if hasattr(dataOut, attr):
391 if hasattr(dataOut, attr):
392 log.log(getattr(dataOut, attr), attr)
392 log.log(getattr(dataOut, attr), attr)
393
393
394
394
395 class interpolateHeights(Operation):
395 class interpolateHeights(Operation):
396
396
397 def run(self, dataOut, topLim, botLim):
397 def run(self, dataOut, topLim, botLim):
398 #69 al 72 para julia
398 #69 al 72 para julia
399 #82-84 para meteoros
399 #82-84 para meteoros
400 if len(numpy.shape(dataOut.data))==2:
400 if len(numpy.shape(dataOut.data))==2:
401 sampInterp = (dataOut.data[:,botLim-1] + dataOut.data[:,topLim+1])/2
401 sampInterp = (dataOut.data[:,botLim-1] + dataOut.data[:,topLim+1])/2
402 sampInterp = numpy.transpose(numpy.tile(sampInterp,(topLim-botLim + 1,1)))
402 sampInterp = numpy.transpose(numpy.tile(sampInterp,(topLim-botLim + 1,1)))
403 #dataOut.data[:,botLim:limSup+1] = sampInterp
403 #dataOut.data[:,botLim:limSup+1] = sampInterp
404 dataOut.data[:,botLim:topLim+1] = sampInterp
404 dataOut.data[:,botLim:topLim+1] = sampInterp
405 else:
405 else:
406 nHeights = dataOut.data.shape[2]
406 nHeights = dataOut.data.shape[2]
407 x = numpy.hstack((numpy.arange(botLim),numpy.arange(topLim+1,nHeights)))
407 x = numpy.hstack((numpy.arange(botLim),numpy.arange(topLim+1,nHeights)))
408 y = dataOut.data[:,:,list(range(botLim))+list(range(topLim+1,nHeights))]
408 y = dataOut.data[:,:,list(range(botLim))+list(range(topLim+1,nHeights))]
409 f = interpolate.interp1d(x, y, axis = 2)
409 f = interpolate.interp1d(x, y, axis = 2)
410 xnew = numpy.arange(botLim,topLim+1)
410 xnew = numpy.arange(botLim,topLim+1)
411 ynew = f(xnew)
411 ynew = f(xnew)
412 dataOut.data[:,:,botLim:topLim+1] = ynew
412 dataOut.data[:,:,botLim:topLim+1] = ynew
413
413
414 return dataOut
414 return dataOut
415
415
416
416
417 class CohInt(Operation):
417 class CohInt(Operation):
418
418
419 isConfig = False
419 isConfig = False
420 __profIndex = 0
420 __profIndex = 0
421 __byTime = False
421 __byTime = False
422 __initime = None
422 __initime = None
423 __lastdatatime = None
423 __lastdatatime = None
424 __integrationtime = None
424 __integrationtime = None
425 __buffer = None
425 __buffer = None
426 __bufferStride = []
426 __bufferStride = []
427 __dataReady = False
427 __dataReady = False
428 __profIndexStride = 0
428 __profIndexStride = 0
429 __dataToPutStride = False
429 __dataToPutStride = False
430 n = None
430 n = None
431
431
432 def __init__(self, **kwargs):
432 def __init__(self, **kwargs):
433
433
434 Operation.__init__(self, **kwargs)
434 Operation.__init__(self, **kwargs)
435
435
436 def setup(self, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False):
436 def setup(self, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False):
437 """
437 """
438 Set the parameters of the integration class.
438 Set the parameters of the integration class.
439
439
440 Inputs:
440 Inputs:
441
441
442 n : Number of coherent integrations
442 n : Number of coherent integrations
443 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
443 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
444 overlapping :
444 overlapping :
445 """
445 """
446
446
447 self.__initime = None
447 self.__initime = None
448 self.__lastdatatime = 0
448 self.__lastdatatime = 0
449 self.__buffer = None
449 self.__buffer = None
450 self.__dataReady = False
450 self.__dataReady = False
451 self.byblock = byblock
451 self.byblock = byblock
452 self.stride = stride
452 self.stride = stride
453
453
454 if n == None and timeInterval == None:
454 if n == None and timeInterval == None:
455 raise ValueError("n or timeInterval should be specified ...")
455 raise ValueError("n or timeInterval should be specified ...")
456
456
457 if n != None:
457 if n != None:
458 self.n = n
458 self.n = n
459 self.__byTime = False
459 self.__byTime = False
460 else:
460 else:
461 self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line
461 self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line
462 self.n = 9999
462 self.n = 9999
463 self.__byTime = True
463 self.__byTime = True
464
464
465 if overlapping:
465 if overlapping:
466 self.__withOverlapping = True
466 self.__withOverlapping = True
467 self.__buffer = None
467 self.__buffer = None
468 else:
468 else:
469 self.__withOverlapping = False
469 self.__withOverlapping = False
470 self.__buffer = 0
470 self.__buffer = 0
471
471
472 self.__profIndex = 0
472 self.__profIndex = 0
473
473
474 def putData(self, data):
474 def putData(self, data):
475
475
476 """
476 """
477 Add a profile to the __buffer and increase in one the __profileIndex
477 Add a profile to the __buffer and increase in one the __profileIndex
478
478
479 """
479 """
480
480
481 if not self.__withOverlapping:
481 if not self.__withOverlapping:
482 self.__buffer += data.copy()
482 self.__buffer += data.copy()
483 self.__profIndex += 1
483 self.__profIndex += 1
484 return
484 return
485
485
486 #Overlapping data
486 #Overlapping data
487 nChannels, nHeis = data.shape
487 nChannels, nHeis = data.shape
488 data = numpy.reshape(data, (1, nChannels, nHeis))
488 data = numpy.reshape(data, (1, nChannels, nHeis))
489
489
490 #If the buffer is empty then it takes the data value
490 #If the buffer is empty then it takes the data value
491 if self.__buffer is None:
491 if self.__buffer is None:
492 self.__buffer = data
492 self.__buffer = data
493 self.__profIndex += 1
493 self.__profIndex += 1
494 return
494 return
495
495
496 #If the buffer length is lower than n then stakcing the data value
496 #If the buffer length is lower than n then stakcing the data value
497 if self.__profIndex < self.n:
497 if self.__profIndex < self.n:
498 self.__buffer = numpy.vstack((self.__buffer, data))
498 self.__buffer = numpy.vstack((self.__buffer, data))
499 self.__profIndex += 1
499 self.__profIndex += 1
500 return
500 return
501
501
502 #If the buffer length is equal to n then replacing the last buffer value with the data value
502 #If the buffer length is equal to n then replacing the last buffer value with the data value
503 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
503 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
504 self.__buffer[self.n-1] = data
504 self.__buffer[self.n-1] = data
505 self.__profIndex = self.n
505 self.__profIndex = self.n
506 return
506 return
507
507
508
508
509 def pushData(self):
509 def pushData(self):
510 """
510 """
511 Return the sum of the last profiles and the profiles used in the sum.
511 Return the sum of the last profiles and the profiles used in the sum.
512
512
513 Affected:
513 Affected:
514
514
515 self.__profileIndex
515 self.__profileIndex
516
516
517 """
517 """
518
518
519 if not self.__withOverlapping:
519 if not self.__withOverlapping:
520 data = self.__buffer
520 data = self.__buffer
521 n = self.__profIndex
521 n = self.__profIndex
522
522
523 self.__buffer = 0
523 self.__buffer = 0
524 self.__profIndex = 0
524 self.__profIndex = 0
525
525
526 return data, n
526 return data, n
527
527
528 #Integration with Overlapping
528 #Integration with Overlapping
529 data = numpy.sum(self.__buffer, axis=0)
529 data = numpy.sum(self.__buffer, axis=0)
530 # print data
530 # print data
531 # raise
531 # raise
532 n = self.__profIndex
532 n = self.__profIndex
533
533
534 return data, n
534 return data, n
535
535
536 def byProfiles(self, data):
536 def byProfiles(self, data):
537
537
538 self.__dataReady = False
538 self.__dataReady = False
539 avgdata = None
539 avgdata = None
540 # n = None
540 # n = None
541 # print data
541 # print data
542 # raise
542 # raise
543 self.putData(data)
543 self.putData(data)
544
544
545 if self.__profIndex == self.n:
545 if self.__profIndex == self.n:
546 avgdata, n = self.pushData()
546 avgdata, n = self.pushData()
547 self.__dataReady = True
547 self.__dataReady = True
548
548
549 return avgdata
549 return avgdata
550
550
551 def byTime(self, data, datatime):
551 def byTime(self, data, datatime):
552
552
553 self.__dataReady = False
553 self.__dataReady = False
554 avgdata = None
554 avgdata = None
555 n = None
555 n = None
556
556
557 self.putData(data)
557 self.putData(data)
558
558
559 if (datatime - self.__initime) >= self.__integrationtime:
559 if (datatime - self.__initime) >= self.__integrationtime:
560 avgdata, n = self.pushData()
560 avgdata, n = self.pushData()
561 self.n = n
561 self.n = n
562 self.__dataReady = True
562 self.__dataReady = True
563
563
564 return avgdata
564 return avgdata
565
565
566 def integrateByStride(self, data, datatime):
566 def integrateByStride(self, data, datatime):
567 # print data
567 # print data
568 if self.__profIndex == 0:
568 if self.__profIndex == 0:
569 self.__buffer = [[data.copy(), datatime]]
569 self.__buffer = [[data.copy(), datatime]]
570 else:
570 else:
571 self.__buffer.append([data.copy(),datatime])
571 self.__buffer.append([data.copy(),datatime])
572 self.__profIndex += 1
572 self.__profIndex += 1
573 self.__dataReady = False
573 self.__dataReady = False
574
574
575 if self.__profIndex == self.n * self.stride :
575 if self.__profIndex == self.n * self.stride :
576 self.__dataToPutStride = True
576 self.__dataToPutStride = True
577 self.__profIndexStride = 0
577 self.__profIndexStride = 0
578 self.__profIndex = 0
578 self.__profIndex = 0
579 self.__bufferStride = []
579 self.__bufferStride = []
580 for i in range(self.stride):
580 for i in range(self.stride):
581 current = self.__buffer[i::self.stride]
581 current = self.__buffer[i::self.stride]
582 data = numpy.sum([t[0] for t in current], axis=0)
582 data = numpy.sum([t[0] for t in current], axis=0)
583 avgdatatime = numpy.average([t[1] for t in current])
583 avgdatatime = numpy.average([t[1] for t in current])
584 # print data
584 # print data
585 self.__bufferStride.append((data, avgdatatime))
585 self.__bufferStride.append((data, avgdatatime))
586
586
587 if self.__dataToPutStride:
587 if self.__dataToPutStride:
588 self.__dataReady = True
588 self.__dataReady = True
589 self.__profIndexStride += 1
589 self.__profIndexStride += 1
590 if self.__profIndexStride == self.stride:
590 if self.__profIndexStride == self.stride:
591 self.__dataToPutStride = False
591 self.__dataToPutStride = False
592 # print self.__bufferStride[self.__profIndexStride - 1]
592 # print self.__bufferStride[self.__profIndexStride - 1]
593 # raise
593 # raise
594 return self.__bufferStride[self.__profIndexStride - 1]
594 return self.__bufferStride[self.__profIndexStride - 1]
595
595
596
596
597 return None, None
597 return None, None
598
598
599 def integrate(self, data, datatime=None):
599 def integrate(self, data, datatime=None):
600
600
601 if self.__initime == None:
601 if self.__initime == None:
602 self.__initime = datatime
602 self.__initime = datatime
603
603
604 if self.__byTime:
604 if self.__byTime:
605 avgdata = self.byTime(data, datatime)
605 avgdata = self.byTime(data, datatime)
606 else:
606 else:
607 avgdata = self.byProfiles(data)
607 avgdata = self.byProfiles(data)
608
608
609
609
610 self.__lastdatatime = datatime
610 self.__lastdatatime = datatime
611
611
612 if avgdata is None:
612 if avgdata is None:
613 return None, None
613 return None, None
614
614
615 avgdatatime = self.__initime
615 avgdatatime = self.__initime
616
616
617 deltatime = datatime - self.__lastdatatime
617 deltatime = datatime - self.__lastdatatime
618
618
619 if not self.__withOverlapping:
619 if not self.__withOverlapping:
620 self.__initime = datatime
620 self.__initime = datatime
621 else:
621 else:
622 self.__initime += deltatime
622 self.__initime += deltatime
623
623
624 return avgdata, avgdatatime
624 return avgdata, avgdatatime
625
625
626 def integrateByBlock(self, dataOut):
626 def integrateByBlock(self, dataOut):
627
627
628 times = int(dataOut.data.shape[1]/self.n)
628 times = int(dataOut.data.shape[1]/self.n)
629 avgdata = numpy.zeros((dataOut.nChannels, times, dataOut.nHeights), dtype=numpy.complex)
629 avgdata = numpy.zeros((dataOut.nChannels, times, dataOut.nHeights), dtype=numpy.complex)
630
630
631 id_min = 0
631 id_min = 0
632 id_max = self.n
632 id_max = self.n
633
633
634 for i in range(times):
634 for i in range(times):
635 junk = dataOut.data[:,id_min:id_max,:]
635 junk = dataOut.data[:,id_min:id_max,:]
636 avgdata[:,i,:] = junk.sum(axis=1)
636 avgdata[:,i,:] = junk.sum(axis=1)
637 id_min += self.n
637 id_min += self.n
638 id_max += self.n
638 id_max += self.n
639
639
640 timeInterval = dataOut.ippSeconds*self.n
640 timeInterval = dataOut.ippSeconds*self.n
641 avgdatatime = (times - 1) * timeInterval + dataOut.utctime
641 avgdatatime = (times - 1) * timeInterval + dataOut.utctime
642 self.__dataReady = True
642 self.__dataReady = True
643 return avgdata, avgdatatime
643 return avgdata, avgdatatime
644
644
645 def run(self, dataOut, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False, **kwargs):
645 def run(self, dataOut, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False, **kwargs):
646
646
647 if not self.isConfig:
647 if not self.isConfig:
648 self.setup(n=n, stride=stride, timeInterval=timeInterval, overlapping=overlapping, byblock=byblock, **kwargs)
648 self.setup(n=n, stride=stride, timeInterval=timeInterval, overlapping=overlapping, byblock=byblock, **kwargs)
649 self.isConfig = True
649 self.isConfig = True
650
650
651 if dataOut.flagDataAsBlock:
651 if dataOut.flagDataAsBlock:
652 """
652 """
653 Si la data es leida por bloques, dimension = [nChannels, nProfiles, nHeis]
653 Si la data es leida por bloques, dimension = [nChannels, nProfiles, nHeis]
654 """
654 """
655 avgdata, avgdatatime = self.integrateByBlock(dataOut)
655 avgdata, avgdatatime = self.integrateByBlock(dataOut)
656 dataOut.nProfiles /= self.n
656 dataOut.nProfiles /= self.n
657 else:
657 else:
658 if stride is None:
658 if stride is None:
659 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
659 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
660 else:
660 else:
661 avgdata, avgdatatime = self.integrateByStride(dataOut.data, dataOut.utctime)
661 avgdata, avgdatatime = self.integrateByStride(dataOut.data, dataOut.utctime)
662
662
663
663
664 # dataOut.timeInterval *= n
664 # dataOut.timeInterval *= n
665 dataOut.flagNoData = True
665 dataOut.flagNoData = True
666
666
667 if self.__dataReady:
667 if self.__dataReady:
668 dataOut.data = avgdata
668 dataOut.data = avgdata
669 if not dataOut.flagCohInt:
669 if not dataOut.flagCohInt:
670 dataOut.nCohInt *= self.n
670 dataOut.nCohInt *= self.n
671 dataOut.flagCohInt = True
671 dataOut.flagCohInt = True
672 dataOut.utctime = avgdatatime
672 ####################################dataOut.utctime = avgdatatime
673 # print avgdata, avgdatatime
673 # print avgdata, avgdatatime
674 # raise
674 # raise
675 # dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
675 # dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
676 dataOut.flagNoData = False
676 dataOut.flagNoData = False
677 return dataOut
677 return dataOut
678
678
679 class Decoder(Operation):
679 class Decoder(Operation):
680
680
681 isConfig = False
681 isConfig = False
682 __profIndex = 0
682 __profIndex = 0
683
683
684 code = None
684 code = None
685
685
686 nCode = None
686 nCode = None
687 nBaud = None
687 nBaud = None
688
688
689 def __init__(self, **kwargs):
689 def __init__(self, **kwargs):
690
690
691 Operation.__init__(self, **kwargs)
691 Operation.__init__(self, **kwargs)
692
692
693 self.times = None
693 self.times = None
694 self.osamp = None
694 self.osamp = None
695 # self.__setValues = False
695 # self.__setValues = False
696 self.isConfig = False
696 self.isConfig = False
697 self.setupReq = False
697 self.setupReq = False
698 def setup(self, code, osamp, dataOut):
698 def setup(self, code, osamp, dataOut):
699
699
700 self.__profIndex = 0
700 self.__profIndex = 0
701
701
702 self.code = code
702 self.code = code
703
703
704 self.nCode = len(code)
704 self.nCode = len(code)
705 self.nBaud = len(code[0])
705 self.nBaud = len(code[0])
706
706
707 if (osamp != None) and (osamp >1):
707 if (osamp != None) and (osamp >1):
708 self.osamp = osamp
708 self.osamp = osamp
709 self.code = numpy.repeat(code, repeats=self.osamp, axis=1)
709 self.code = numpy.repeat(code, repeats=self.osamp, axis=1)
710 self.nBaud = self.nBaud*self.osamp
710 self.nBaud = self.nBaud*self.osamp
711
711
712 self.__nChannels = dataOut.nChannels
712 self.__nChannels = dataOut.nChannels
713 self.__nProfiles = dataOut.nProfiles
713 self.__nProfiles = dataOut.nProfiles
714 self.__nHeis = dataOut.nHeights
714 self.__nHeis = dataOut.nHeights
715
715
716 if self.__nHeis < self.nBaud:
716 if self.__nHeis < self.nBaud:
717 raise ValueError('Number of heights (%d) should be greater than number of bauds (%d)' %(self.__nHeis, self.nBaud))
717 raise ValueError('Number of heights (%d) should be greater than number of bauds (%d)' %(self.__nHeis, self.nBaud))
718
718
719 #Frequency
719 #Frequency
720 __codeBuffer = numpy.zeros((self.nCode, self.__nHeis), dtype=numpy.complex)
720 __codeBuffer = numpy.zeros((self.nCode, self.__nHeis), dtype=numpy.complex)
721
721
722 __codeBuffer[:,0:self.nBaud] = self.code
722 __codeBuffer[:,0:self.nBaud] = self.code
723
723
724 self.fft_code = numpy.conj(numpy.fft.fft(__codeBuffer, axis=1))
724 self.fft_code = numpy.conj(numpy.fft.fft(__codeBuffer, axis=1))
725
725
726 if dataOut.flagDataAsBlock:
726 if dataOut.flagDataAsBlock:
727
727
728 self.ndatadec = self.__nHeis #- self.nBaud + 1
728 self.ndatadec = self.__nHeis #- self.nBaud + 1
729
729
730 self.datadecTime = numpy.zeros((self.__nChannels, self.__nProfiles, self.ndatadec), dtype=numpy.complex)
730 self.datadecTime = numpy.zeros((self.__nChannels, self.__nProfiles, self.ndatadec), dtype=numpy.complex)
731
731
732 else:
732 else:
733
733
734 #Time
734 #Time
735 self.ndatadec = self.__nHeis #- self.nBaud + 1
735 self.ndatadec = self.__nHeis #- self.nBaud + 1
736
736
737 self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex)
737 self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex)
738
738
739 def __convolutionInFreq(self, data):
739 def __convolutionInFreq(self, data):
740
740
741 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
741 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
742
742
743 fft_data = numpy.fft.fft(data, axis=1)
743 fft_data = numpy.fft.fft(data, axis=1)
744
744
745 conv = fft_data*fft_code
745 conv = fft_data*fft_code
746
746
747 data = numpy.fft.ifft(conv,axis=1)
747 data = numpy.fft.ifft(conv,axis=1)
748
748
749 return data
749 return data
750
750
751 def __convolutionInFreqOpt(self, data):
751 def __convolutionInFreqOpt(self, data):
752
752
753 raise NotImplementedError
753 raise NotImplementedError
754
754
755 def __convolutionInTime(self, data):
755 def __convolutionInTime(self, data):
756
756
757 code = self.code[self.__profIndex]
757 code = self.code[self.__profIndex]
758 for i in range(self.__nChannels):
758 for i in range(self.__nChannels):
759 self.datadecTime[i,:] = numpy.correlate(data[i,:], code, mode='full')[self.nBaud-1:]
759 self.datadecTime[i,:] = numpy.correlate(data[i,:], code, mode='full')[self.nBaud-1:]
760
760
761 return self.datadecTime
761 return self.datadecTime
762
762
763 def __convolutionByBlockInTime(self, data):
763 def __convolutionByBlockInTime(self, data):
764
764
765 repetitions = int(self.__nProfiles / self.nCode)
765 repetitions = int(self.__nProfiles / self.nCode)
766 junk = numpy.lib.stride_tricks.as_strided(self.code, (repetitions, self.code.size), (0, self.code.itemsize))
766 junk = numpy.lib.stride_tricks.as_strided(self.code, (repetitions, self.code.size), (0, self.code.itemsize))
767 junk = junk.flatten()
767 junk = junk.flatten()
768 code_block = numpy.reshape(junk, (self.nCode*repetitions, self.nBaud))
768 code_block = numpy.reshape(junk, (self.nCode*repetitions, self.nBaud))
769 profilesList = range(self.__nProfiles)
769 profilesList = range(self.__nProfiles)
770
770
771 for i in range(self.__nChannels):
771 for i in range(self.__nChannels):
772 for j in profilesList:
772 for j in profilesList:
773 self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:]
773 self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:]
774 return self.datadecTime
774 return self.datadecTime
775
775
776 def __convolutionByBlockInFreq(self, data):
776 def __convolutionByBlockInFreq(self, data):
777
777
778 raise NotImplementedError("Decoder by frequency fro Blocks not implemented")
778 raise NotImplementedError("Decoder by frequency fro Blocks not implemented")
779
779
780
780
781 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
781 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
782
782
783 fft_data = numpy.fft.fft(data, axis=2)
783 fft_data = numpy.fft.fft(data, axis=2)
784
784
785 conv = fft_data*fft_code
785 conv = fft_data*fft_code
786
786
787 data = numpy.fft.ifft(conv,axis=2)
787 data = numpy.fft.ifft(conv,axis=2)
788
788
789 return data
789 return data
790
790
791
791
792 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0, osamp=None, times=None):
792 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0, osamp=None, times=None):
793
793
794 if dataOut.flagDecodeData:
794 if dataOut.flagDecodeData:
795 print("This data is already decoded, recoding again ...")
795 print("This data is already decoded, recoding again ...")
796
796
797 if not self.isConfig:
797 if not self.isConfig:
798
798
799 if code is None:
799 if code is None:
800 if dataOut.code is None:
800 if dataOut.code is None:
801 raise ValueError("Code could not be read from %s instance. Enter a value in Code parameter" %dataOut.type)
801 raise ValueError("Code could not be read from %s instance. Enter a value in Code parameter" %dataOut.type)
802
802
803 code = dataOut.code
803 code = dataOut.code
804 else:
804 else:
805 code = numpy.array(code).reshape(nCode,nBaud)
805 code = numpy.array(code).reshape(nCode,nBaud)
806 self.setup(code, osamp, dataOut)
806 self.setup(code, osamp, dataOut)
807
807
808 self.isConfig = True
808 self.isConfig = True
809
809
810 if mode == 3:
810 if mode == 3:
811 sys.stderr.write("Decoder Warning: mode=%d is not valid, using mode=0\n" %mode)
811 sys.stderr.write("Decoder Warning: mode=%d is not valid, using mode=0\n" %mode)
812
812
813 if times != None:
813 if times != None:
814 sys.stderr.write("Decoder Warning: Argument 'times' in not used anymore\n")
814 sys.stderr.write("Decoder Warning: Argument 'times' in not used anymore\n")
815
815
816 if self.code is None:
816 if self.code is None:
817 print("Fail decoding: Code is not defined.")
817 print("Fail decoding: Code is not defined.")
818 return
818 return
819
819
820 self.__nProfiles = dataOut.nProfiles
820 self.__nProfiles = dataOut.nProfiles
821 datadec = None
821 datadec = None
822
822
823 if mode == 3:
823 if mode == 3:
824 mode = 0
824 mode = 0
825
825
826 if dataOut.flagDataAsBlock:
826 if dataOut.flagDataAsBlock:
827 """
827 """
828 Decoding when data have been read as block,
828 Decoding when data have been read as block,
829 """
829 """
830
830
831 if mode == 0:
831 if mode == 0:
832 datadec = self.__convolutionByBlockInTime(dataOut.data)
832 datadec = self.__convolutionByBlockInTime(dataOut.data)
833 if mode == 1:
833 if mode == 1:
834 datadec = self.__convolutionByBlockInFreq(dataOut.data)
834 datadec = self.__convolutionByBlockInFreq(dataOut.data)
835 else:
835 else:
836 """
836 """
837 Decoding when data have been read profile by profile
837 Decoding when data have been read profile by profile
838 """
838 """
839 if mode == 0:
839 if mode == 0:
840 datadec = self.__convolutionInTime(dataOut.data)
840 datadec = self.__convolutionInTime(dataOut.data)
841
841
842 if mode == 1:
842 if mode == 1:
843 datadec = self.__convolutionInFreq(dataOut.data)
843 datadec = self.__convolutionInFreq(dataOut.data)
844
844
845 if mode == 2:
845 if mode == 2:
846 datadec = self.__convolutionInFreqOpt(dataOut.data)
846 datadec = self.__convolutionInFreqOpt(dataOut.data)
847
847
848 if datadec is None:
848 if datadec is None:
849 raise ValueError("Codification mode selected is not valid: mode=%d. Try selecting 0 or 1" %mode)
849 raise ValueError("Codification mode selected is not valid: mode=%d. Try selecting 0 or 1" %mode)
850
850
851 dataOut.code = self.code
851 dataOut.code = self.code
852 dataOut.nCode = self.nCode
852 dataOut.nCode = self.nCode
853 dataOut.nBaud = self.nBaud
853 dataOut.nBaud = self.nBaud
854
854
855 dataOut.data = datadec
855 dataOut.data = datadec
856
856
857 dataOut.heightList = dataOut.heightList[0:datadec.shape[-1]]
857 dataOut.heightList = dataOut.heightList[0:datadec.shape[-1]]
858
858
859 dataOut.flagDecodeData = True #asumo q la data esta decodificada
859 dataOut.flagDecodeData = True #asumo q la data esta decodificada
860
860
861 if self.__profIndex == self.nCode-1:
861 if self.__profIndex == self.nCode-1:
862 self.__profIndex = 0
862 self.__profIndex = 0
863 return dataOut
863 return dataOut
864
864
865 self.__profIndex += 1
865 self.__profIndex += 1
866
866
867 return dataOut
867 return dataOut
868 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
868 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
869
869
870
870
871 class ProfileConcat(Operation):
871 class ProfileConcat(Operation):
872
872
873 isConfig = False
873 isConfig = False
874 buffer = None
874 buffer = None
875
875
876 def __init__(self, **kwargs):
876 def __init__(self, **kwargs):
877
877
878 Operation.__init__(self, **kwargs)
878 Operation.__init__(self, **kwargs)
879 self.profileIndex = 0
879 self.profileIndex = 0
880
880
881 def reset(self):
881 def reset(self):
882 self.buffer = numpy.zeros_like(self.buffer)
882 self.buffer = numpy.zeros_like(self.buffer)
883 self.start_index = 0
883 self.start_index = 0
884 self.times = 1
884 self.times = 1
885
885
886 def setup(self, data, m, n=1):
886 def setup(self, data, m, n=1):
887 self.buffer = numpy.zeros((data.shape[0],data.shape[1]*m),dtype=type(data[0,0]))
887 self.buffer = numpy.zeros((data.shape[0],data.shape[1]*m),dtype=type(data[0,0]))
888 self.nHeights = data.shape[1]#.nHeights
888 self.nHeights = data.shape[1]#.nHeights
889 self.start_index = 0
889 self.start_index = 0
890 self.times = 1
890 self.times = 1
891
891
892 def concat(self, data):
892 def concat(self, data):
893
893
894 self.buffer[:,self.start_index:self.nHeights*self.times] = data.copy()
894 self.buffer[:,self.start_index:self.nHeights*self.times] = data.copy()
895 self.start_index = self.start_index + self.nHeights
895 self.start_index = self.start_index + self.nHeights
896
896
897 def run(self, dataOut, m):
897 def run(self, dataOut, m):
898 dataOut.flagNoData = True
898 dataOut.flagNoData = True
899
899
900 if not self.isConfig:
900 if not self.isConfig:
901 self.setup(dataOut.data, m, 1)
901 self.setup(dataOut.data, m, 1)
902 self.isConfig = True
902 self.isConfig = True
903
903
904 if dataOut.flagDataAsBlock:
904 if dataOut.flagDataAsBlock:
905 raise ValueError("ProfileConcat can only be used when voltage have been read profile by profile, getBlock = False")
905 raise ValueError("ProfileConcat can only be used when voltage have been read profile by profile, getBlock = False")
906
906
907 else:
907 else:
908 self.concat(dataOut.data)
908 self.concat(dataOut.data)
909 self.times += 1
909 self.times += 1
910 if self.times > m:
910 if self.times > m:
911 dataOut.data = self.buffer
911 dataOut.data = self.buffer
912 self.reset()
912 self.reset()
913 dataOut.flagNoData = False
913 dataOut.flagNoData = False
914 # se deben actualizar mas propiedades del header y del objeto dataOut, por ejemplo, las alturas
914 # se deben actualizar mas propiedades del header y del objeto dataOut, por ejemplo, las alturas
915 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
915 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
916 xf = dataOut.heightList[0] + dataOut.nHeights * deltaHeight * m
916 xf = dataOut.heightList[0] + dataOut.nHeights * deltaHeight * m
917 dataOut.heightList = numpy.arange(dataOut.heightList[0], xf, deltaHeight)
917 dataOut.heightList = numpy.arange(dataOut.heightList[0], xf, deltaHeight)
918 dataOut.ippSeconds *= m
918 dataOut.ippSeconds *= m
919 return dataOut
919 return dataOut
920
920
921 class ProfileSelector(Operation):
921 class ProfileSelector(Operation):
922
922
923 profileIndex = None
923 profileIndex = None
924 # Tamanho total de los perfiles
924 # Tamanho total de los perfiles
925 nProfiles = None
925 nProfiles = None
926
926
927 def __init__(self, **kwargs):
927 def __init__(self, **kwargs):
928
928
929 Operation.__init__(self, **kwargs)
929 Operation.__init__(self, **kwargs)
930 self.profileIndex = 0
930 self.profileIndex = 0
931
931
932 def incProfileIndex(self):
932 def incProfileIndex(self):
933
933
934 self.profileIndex += 1
934 self.profileIndex += 1
935
935
936 if self.profileIndex >= self.nProfiles:
936 if self.profileIndex >= self.nProfiles:
937 self.profileIndex = 0
937 self.profileIndex = 0
938
938
939 def isThisProfileInRange(self, profileIndex, minIndex, maxIndex):
939 def isThisProfileInRange(self, profileIndex, minIndex, maxIndex):
940
940
941 if profileIndex < minIndex:
941 if profileIndex < minIndex:
942 return False
942 return False
943
943
944 if profileIndex > maxIndex:
944 if profileIndex > maxIndex:
945 return False
945 return False
946
946
947 return True
947 return True
948
948
949 def isThisProfileInList(self, profileIndex, profileList):
949 def isThisProfileInList(self, profileIndex, profileList):
950
950
951 if profileIndex not in profileList:
951 if profileIndex not in profileList:
952 return False
952 return False
953
953
954 return True
954 return True
955
955
956 def run(self, dataOut, profileList=None, profileRangeList=None, beam=None, byblock=False, rangeList = None, nProfiles=None):
956 def run(self, dataOut, profileList=None, profileRangeList=None, beam=None, byblock=False, rangeList = None, nProfiles=None):
957 #print("before",dataOut.data.shape)
957 #print("before",dataOut.data.shape)
958 """
958 """
959 ProfileSelector:
959 ProfileSelector:
960
960
961 Inputs:
961 Inputs:
962 profileList : Index of profiles selected. Example: profileList = (0,1,2,7,8)
962 profileList : Index of profiles selected. Example: profileList = (0,1,2,7,8)
963
963
964 profileRangeList : Minimum and maximum profile indexes. Example: profileRangeList = (4, 30)
964 profileRangeList : Minimum and maximum profile indexes. Example: profileRangeList = (4, 30)
965
965
966 rangeList : List of profile ranges. Example: rangeList = ((4, 30), (32, 64), (128, 256))
966 rangeList : List of profile ranges. Example: rangeList = ((4, 30), (32, 64), (128, 256))
967
967
968 """
968 """
969
969
970 if rangeList is not None:
970 if rangeList is not None:
971 if type(rangeList[0]) not in (tuple, list):
971 if type(rangeList[0]) not in (tuple, list):
972 rangeList = [rangeList]
972 rangeList = [rangeList]
973
973
974 dataOut.flagNoData = True
974 dataOut.flagNoData = True
975
975
976 if dataOut.flagDataAsBlock:
976 if dataOut.flagDataAsBlock:
977 """
977 """
978 data dimension = [nChannels, nProfiles, nHeis]
978 data dimension = [nChannels, nProfiles, nHeis]
979 """
979 """
980 if profileList != None:
980 if profileList != None:
981 dataOut.data = dataOut.data[:,profileList,:]
981 dataOut.data = dataOut.data[:,profileList,:]
982
982
983 if profileRangeList != None:
983 if profileRangeList != None:
984 minIndex = profileRangeList[0]
984 minIndex = profileRangeList[0]
985 maxIndex = profileRangeList[1]
985 maxIndex = profileRangeList[1]
986 profileList = list(range(minIndex, maxIndex+1))
986 profileList = list(range(minIndex, maxIndex+1))
987
987
988 dataOut.data = dataOut.data[:,minIndex:maxIndex+1,:]
988 dataOut.data = dataOut.data[:,minIndex:maxIndex+1,:]
989
989
990 if rangeList != None:
990 if rangeList != None:
991
991
992 profileList = []
992 profileList = []
993
993
994 for thisRange in rangeList:
994 for thisRange in rangeList:
995 minIndex = thisRange[0]
995 minIndex = thisRange[0]
996 maxIndex = thisRange[1]
996 maxIndex = thisRange[1]
997
997
998 profileList.extend(list(range(minIndex, maxIndex+1)))
998 profileList.extend(list(range(minIndex, maxIndex+1)))
999
999
1000 dataOut.data = dataOut.data[:,profileList,:]
1000 dataOut.data = dataOut.data[:,profileList,:]
1001
1001
1002 dataOut.nProfiles = len(profileList)
1002 dataOut.nProfiles = len(profileList)
1003 dataOut.profileIndex = dataOut.nProfiles - 1
1003 dataOut.profileIndex = dataOut.nProfiles - 1
1004 dataOut.flagNoData = False
1004 dataOut.flagNoData = False
1005 #print(dataOut.data.shape)
1005 #print(dataOut.data.shape)
1006 return dataOut
1006 return dataOut
1007
1007
1008 """
1008 """
1009 data dimension = [nChannels, nHeis]
1009 data dimension = [nChannels, nHeis]
1010 """
1010 """
1011
1011
1012 if profileList != None:
1012 if profileList != None:
1013
1013
1014 if self.isThisProfileInList(dataOut.profileIndex, profileList):
1014 if self.isThisProfileInList(dataOut.profileIndex, profileList):
1015
1015
1016 self.nProfiles = len(profileList)
1016 self.nProfiles = len(profileList)
1017 dataOut.nProfiles = self.nProfiles
1017 dataOut.nProfiles = self.nProfiles
1018 dataOut.profileIndex = self.profileIndex
1018 dataOut.profileIndex = self.profileIndex
1019 dataOut.flagNoData = False
1019 dataOut.flagNoData = False
1020
1020
1021 self.incProfileIndex()
1021 self.incProfileIndex()
1022 return dataOut
1022 return dataOut
1023
1023
1024 if profileRangeList != None:
1024 if profileRangeList != None:
1025
1025
1026 minIndex = profileRangeList[0]
1026 minIndex = profileRangeList[0]
1027 maxIndex = profileRangeList[1]
1027 maxIndex = profileRangeList[1]
1028
1028
1029 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1029 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1030
1030
1031 self.nProfiles = maxIndex - minIndex + 1
1031 self.nProfiles = maxIndex - minIndex + 1
1032 dataOut.nProfiles = self.nProfiles
1032 dataOut.nProfiles = self.nProfiles
1033 dataOut.profileIndex = self.profileIndex
1033 dataOut.profileIndex = self.profileIndex
1034 dataOut.flagNoData = False
1034 dataOut.flagNoData = False
1035
1035
1036 self.incProfileIndex()
1036 self.incProfileIndex()
1037 return dataOut
1037 return dataOut
1038
1038
1039 if rangeList != None:
1039 if rangeList != None:
1040
1040
1041 nProfiles = 0
1041 nProfiles = 0
1042
1042
1043 for thisRange in rangeList:
1043 for thisRange in rangeList:
1044 minIndex = thisRange[0]
1044 minIndex = thisRange[0]
1045 maxIndex = thisRange[1]
1045 maxIndex = thisRange[1]
1046
1046
1047 nProfiles += maxIndex - minIndex + 1
1047 nProfiles += maxIndex - minIndex + 1
1048
1048
1049 for thisRange in rangeList:
1049 for thisRange in rangeList:
1050
1050
1051 minIndex = thisRange[0]
1051 minIndex = thisRange[0]
1052 maxIndex = thisRange[1]
1052 maxIndex = thisRange[1]
1053
1053
1054 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1054 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1055
1055
1056 self.nProfiles = nProfiles
1056 self.nProfiles = nProfiles
1057 dataOut.nProfiles = self.nProfiles
1057 dataOut.nProfiles = self.nProfiles
1058 dataOut.profileIndex = self.profileIndex
1058 dataOut.profileIndex = self.profileIndex
1059 dataOut.flagNoData = False
1059 dataOut.flagNoData = False
1060
1060
1061 self.incProfileIndex()
1061 self.incProfileIndex()
1062
1062
1063 break
1063 break
1064
1064
1065 return dataOut
1065 return dataOut
1066
1066
1067
1067
1068 if beam != None: #beam is only for AMISR data
1068 if beam != None: #beam is only for AMISR data
1069 if self.isThisProfileInList(dataOut.profileIndex, dataOut.beamRangeDict[beam]):
1069 if self.isThisProfileInList(dataOut.profileIndex, dataOut.beamRangeDict[beam]):
1070 dataOut.flagNoData = False
1070 dataOut.flagNoData = False
1071 dataOut.profileIndex = self.profileIndex
1071 dataOut.profileIndex = self.profileIndex
1072
1072
1073 self.incProfileIndex()
1073 self.incProfileIndex()
1074
1074
1075 return dataOut
1075 return dataOut
1076
1076
1077 raise ValueError("ProfileSelector needs profileList, profileRangeList or rangeList parameter")
1077 raise ValueError("ProfileSelector needs profileList, profileRangeList or rangeList parameter")
1078
1078
1079
1079
1080 class Reshaper(Operation):
1080 class Reshaper(Operation):
1081
1081
1082 def __init__(self, **kwargs):
1082 def __init__(self, **kwargs):
1083
1083
1084 Operation.__init__(self, **kwargs)
1084 Operation.__init__(self, **kwargs)
1085
1085
1086 self.__buffer = None
1086 self.__buffer = None
1087 self.__nitems = 0
1087 self.__nitems = 0
1088
1088
1089 def __appendProfile(self, dataOut, nTxs):
1089 def __appendProfile(self, dataOut, nTxs):
1090
1090
1091 if self.__buffer is None:
1091 if self.__buffer is None:
1092 shape = (dataOut.nChannels, int(dataOut.nHeights/nTxs) )
1092 shape = (dataOut.nChannels, int(dataOut.nHeights/nTxs) )
1093 self.__buffer = numpy.empty(shape, dtype = dataOut.data.dtype)
1093 self.__buffer = numpy.empty(shape, dtype = dataOut.data.dtype)
1094
1094
1095 ini = dataOut.nHeights * self.__nitems
1095 ini = dataOut.nHeights * self.__nitems
1096 end = ini + dataOut.nHeights
1096 end = ini + dataOut.nHeights
1097
1097
1098 self.__buffer[:, ini:end] = dataOut.data
1098 self.__buffer[:, ini:end] = dataOut.data
1099
1099
1100 self.__nitems += 1
1100 self.__nitems += 1
1101
1101
1102 return int(self.__nitems*nTxs)
1102 return int(self.__nitems*nTxs)
1103
1103
1104 def __getBuffer(self):
1104 def __getBuffer(self):
1105
1105
1106 if self.__nitems == int(1./self.__nTxs):
1106 if self.__nitems == int(1./self.__nTxs):
1107
1107
1108 self.__nitems = 0
1108 self.__nitems = 0
1109
1109
1110 return self.__buffer.copy()
1110 return self.__buffer.copy()
1111
1111
1112 return None
1112 return None
1113
1113
1114 def __checkInputs(self, dataOut, shape, nTxs):
1114 def __checkInputs(self, dataOut, shape, nTxs):
1115
1115
1116 if shape is None and nTxs is None:
1116 if shape is None and nTxs is None:
1117 raise ValueError("Reshaper: shape of factor should be defined")
1117 raise ValueError("Reshaper: shape of factor should be defined")
1118
1118
1119 if nTxs:
1119 if nTxs:
1120 if nTxs < 0:
1120 if nTxs < 0:
1121 raise ValueError("nTxs should be greater than 0")
1121 raise ValueError("nTxs should be greater than 0")
1122
1122
1123 if nTxs < 1 and dataOut.nProfiles % (1./nTxs) != 0:
1123 if nTxs < 1 and dataOut.nProfiles % (1./nTxs) != 0:
1124 raise ValueError("nProfiles= %d is not divisibled by (1./nTxs) = %f" %(dataOut.nProfiles, (1./nTxs)))
1124 raise ValueError("nProfiles= %d is not divisibled by (1./nTxs) = %f" %(dataOut.nProfiles, (1./nTxs)))
1125
1125
1126 shape = [dataOut.nChannels, dataOut.nProfiles*nTxs, dataOut.nHeights/nTxs]
1126 shape = [dataOut.nChannels, dataOut.nProfiles*nTxs, dataOut.nHeights/nTxs]
1127
1127
1128 return shape, nTxs
1128 return shape, nTxs
1129
1129
1130 if len(shape) != 2 and len(shape) != 3:
1130 if len(shape) != 2 and len(shape) != 3:
1131 raise ValueError("shape dimension should be equal to 2 or 3. shape = (nProfiles, nHeis) or (nChannels, nProfiles, nHeis). Actually shape = (%d, %d, %d)" %(dataOut.nChannels, dataOut.nProfiles, dataOut.nHeights))
1131 raise ValueError("shape dimension should be equal to 2 or 3. shape = (nProfiles, nHeis) or (nChannels, nProfiles, nHeis). Actually shape = (%d, %d, %d)" %(dataOut.nChannels, dataOut.nProfiles, dataOut.nHeights))
1132
1132
1133 if len(shape) == 2:
1133 if len(shape) == 2:
1134 shape_tuple = [dataOut.nChannels]
1134 shape_tuple = [dataOut.nChannels]
1135 shape_tuple.extend(shape)
1135 shape_tuple.extend(shape)
1136 else:
1136 else:
1137 shape_tuple = list(shape)
1137 shape_tuple = list(shape)
1138
1138
1139 nTxs = 1.0*shape_tuple[1]/dataOut.nProfiles
1139 nTxs = 1.0*shape_tuple[1]/dataOut.nProfiles
1140
1140
1141 return shape_tuple, nTxs
1141 return shape_tuple, nTxs
1142
1142
1143 def run(self, dataOut, shape=None, nTxs=None):
1143 def run(self, dataOut, shape=None, nTxs=None):
1144
1144
1145 shape_tuple, self.__nTxs = self.__checkInputs(dataOut, shape, nTxs)
1145 shape_tuple, self.__nTxs = self.__checkInputs(dataOut, shape, nTxs)
1146
1146
1147 dataOut.flagNoData = True
1147 dataOut.flagNoData = True
1148 profileIndex = None
1148 profileIndex = None
1149
1149
1150 if dataOut.flagDataAsBlock:
1150 if dataOut.flagDataAsBlock:
1151
1151
1152 dataOut.data = numpy.reshape(dataOut.data, shape_tuple)
1152 dataOut.data = numpy.reshape(dataOut.data, shape_tuple)
1153 dataOut.flagNoData = False
1153 dataOut.flagNoData = False
1154
1154
1155 profileIndex = int(dataOut.nProfiles*self.__nTxs) - 1
1155 profileIndex = int(dataOut.nProfiles*self.__nTxs) - 1
1156
1156
1157 else:
1157 else:
1158
1158
1159 if self.__nTxs < 1:
1159 if self.__nTxs < 1:
1160
1160
1161 self.__appendProfile(dataOut, self.__nTxs)
1161 self.__appendProfile(dataOut, self.__nTxs)
1162 new_data = self.__getBuffer()
1162 new_data = self.__getBuffer()
1163
1163
1164 if new_data is not None:
1164 if new_data is not None:
1165 dataOut.data = new_data
1165 dataOut.data = new_data
1166 dataOut.flagNoData = False
1166 dataOut.flagNoData = False
1167
1167
1168 profileIndex = dataOut.profileIndex*nTxs
1168 profileIndex = dataOut.profileIndex*nTxs
1169
1169
1170 else:
1170 else:
1171 raise ValueError("nTxs should be greater than 0 and lower than 1, or use VoltageReader(..., getblock=True)")
1171 raise ValueError("nTxs should be greater than 0 and lower than 1, or use VoltageReader(..., getblock=True)")
1172
1172
1173 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1173 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1174
1174
1175 dataOut.heightList = numpy.arange(dataOut.nHeights/self.__nTxs) * deltaHeight + dataOut.heightList[0]
1175 dataOut.heightList = numpy.arange(dataOut.nHeights/self.__nTxs) * deltaHeight + dataOut.heightList[0]
1176
1176
1177 dataOut.nProfiles = int(dataOut.nProfiles*self.__nTxs)
1177 dataOut.nProfiles = int(dataOut.nProfiles*self.__nTxs)
1178
1178
1179 dataOut.profileIndex = profileIndex
1179 dataOut.profileIndex = profileIndex
1180
1180
1181 dataOut.ippSeconds /= self.__nTxs
1181 dataOut.ippSeconds /= self.__nTxs
1182
1182
1183 return dataOut
1183 return dataOut
1184
1184
1185 class SplitProfiles(Operation):
1185 class SplitProfiles(Operation):
1186
1186
1187 def __init__(self, **kwargs):
1187 def __init__(self, **kwargs):
1188
1188
1189 Operation.__init__(self, **kwargs)
1189 Operation.__init__(self, **kwargs)
1190
1190
1191 def run(self, dataOut, n):
1191 def run(self, dataOut, n):
1192
1192
1193 dataOut.flagNoData = True
1193 dataOut.flagNoData = True
1194 profileIndex = None
1194 profileIndex = None
1195
1195
1196 if dataOut.flagDataAsBlock:
1196 if dataOut.flagDataAsBlock:
1197
1197
1198 #nchannels, nprofiles, nsamples
1198 #nchannels, nprofiles, nsamples
1199 shape = dataOut.data.shape
1199 shape = dataOut.data.shape
1200
1200
1201 if shape[2] % n != 0:
1201 if shape[2] % n != 0:
1202 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[2]))
1202 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[2]))
1203
1203
1204 new_shape = shape[0], shape[1]*n, int(shape[2]/n)
1204 new_shape = shape[0], shape[1]*n, int(shape[2]/n)
1205
1205
1206 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1206 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1207 dataOut.flagNoData = False
1207 dataOut.flagNoData = False
1208
1208
1209 profileIndex = int(dataOut.nProfiles/n) - 1
1209 profileIndex = int(dataOut.nProfiles/n) - 1
1210
1210
1211 else:
1211 else:
1212
1212
1213 raise ValueError("Could not split the data when is read Profile by Profile. Use VoltageReader(..., getblock=True)")
1213 raise ValueError("Could not split the data when is read Profile by Profile. Use VoltageReader(..., getblock=True)")
1214
1214
1215 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1215 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1216
1216
1217 dataOut.heightList = numpy.arange(dataOut.nHeights/n) * deltaHeight + dataOut.heightList[0]
1217 dataOut.heightList = numpy.arange(dataOut.nHeights/n) * deltaHeight + dataOut.heightList[0]
1218
1218
1219 dataOut.nProfiles = int(dataOut.nProfiles*n)
1219 dataOut.nProfiles = int(dataOut.nProfiles*n)
1220
1220
1221 dataOut.profileIndex = profileIndex
1221 dataOut.profileIndex = profileIndex
1222
1222
1223 dataOut.ippSeconds /= n
1223 dataOut.ippSeconds /= n
1224
1224
1225 return dataOut
1225 return dataOut
1226
1226
1227 class CombineProfiles(Operation):
1227 class CombineProfiles(Operation):
1228 def __init__(self, **kwargs):
1228 def __init__(self, **kwargs):
1229
1229
1230 Operation.__init__(self, **kwargs)
1230 Operation.__init__(self, **kwargs)
1231
1231
1232 self.__remData = None
1232 self.__remData = None
1233 self.__profileIndex = 0
1233 self.__profileIndex = 0
1234
1234
1235 def run(self, dataOut, n):
1235 def run(self, dataOut, n):
1236
1236
1237 dataOut.flagNoData = True
1237 dataOut.flagNoData = True
1238 profileIndex = None
1238 profileIndex = None
1239
1239
1240 if dataOut.flagDataAsBlock:
1240 if dataOut.flagDataAsBlock:
1241
1241
1242 #nchannels, nprofiles, nsamples
1242 #nchannels, nprofiles, nsamples
1243 shape = dataOut.data.shape
1243 shape = dataOut.data.shape
1244 new_shape = shape[0], shape[1]/n, shape[2]*n
1244 new_shape = shape[0], shape[1]/n, shape[2]*n
1245
1245
1246 if shape[1] % n != 0:
1246 if shape[1] % n != 0:
1247 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[1]))
1247 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[1]))
1248
1248
1249 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1249 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1250 dataOut.flagNoData = False
1250 dataOut.flagNoData = False
1251
1251
1252 profileIndex = int(dataOut.nProfiles*n) - 1
1252 profileIndex = int(dataOut.nProfiles*n) - 1
1253
1253
1254 else:
1254 else:
1255
1255
1256 #nchannels, nsamples
1256 #nchannels, nsamples
1257 if self.__remData is None:
1257 if self.__remData is None:
1258 newData = dataOut.data
1258 newData = dataOut.data
1259 else:
1259 else:
1260 newData = numpy.concatenate((self.__remData, dataOut.data), axis=1)
1260 newData = numpy.concatenate((self.__remData, dataOut.data), axis=1)
1261
1261
1262 self.__profileIndex += 1
1262 self.__profileIndex += 1
1263
1263
1264 if self.__profileIndex < n:
1264 if self.__profileIndex < n:
1265 self.__remData = newData
1265 self.__remData = newData
1266 #continue
1266 #continue
1267 return
1267 return
1268
1268
1269 self.__profileIndex = 0
1269 self.__profileIndex = 0
1270 self.__remData = None
1270 self.__remData = None
1271
1271
1272 dataOut.data = newData
1272 dataOut.data = newData
1273 dataOut.flagNoData = False
1273 dataOut.flagNoData = False
1274
1274
1275 profileIndex = dataOut.profileIndex/n
1275 profileIndex = dataOut.profileIndex/n
1276
1276
1277
1277
1278 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1278 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1279
1279
1280 dataOut.heightList = numpy.arange(dataOut.nHeights*n) * deltaHeight + dataOut.heightList[0]
1280 dataOut.heightList = numpy.arange(dataOut.nHeights*n) * deltaHeight + dataOut.heightList[0]
1281
1281
1282 dataOut.nProfiles = int(dataOut.nProfiles/n)
1282 dataOut.nProfiles = int(dataOut.nProfiles/n)
1283
1283
1284 dataOut.profileIndex = profileIndex
1284 dataOut.profileIndex = profileIndex
1285
1285
1286 dataOut.ippSeconds *= n
1286 dataOut.ippSeconds *= n
1287
1287
1288 return dataOut
1288 return dataOut
1289
1289
1290 class PulsePair(Operation):
1290 class PulsePair(Operation):
1291 '''
1291 '''
1292 Function PulsePair(Signal Power, Velocity)
1292 Function PulsePair(Signal Power, Velocity)
1293 The real component of Lag[0] provides Intensity Information
1293 The real component of Lag[0] provides Intensity Information
1294 The imag component of Lag[1] Phase provides Velocity Information
1294 The imag component of Lag[1] Phase provides Velocity Information
1295
1295
1296 Configuration Parameters:
1296 Configuration Parameters:
1297 nPRF = Number of Several PRF
1297 nPRF = Number of Several PRF
1298 theta = Degree Azimuth angel Boundaries
1298 theta = Degree Azimuth angel Boundaries
1299
1299
1300 Input:
1300 Input:
1301 self.dataOut
1301 self.dataOut
1302 lag[N]
1302 lag[N]
1303 Affected:
1303 Affected:
1304 self.dataOut.spc
1304 self.dataOut.spc
1305 '''
1305 '''
1306 isConfig = False
1306 isConfig = False
1307 __profIndex = 0
1307 __profIndex = 0
1308 __initime = None
1308 __initime = None
1309 __lastdatatime = None
1309 __lastdatatime = None
1310 __buffer = None
1310 __buffer = None
1311 noise = None
1311 noise = None
1312 __dataReady = False
1312 __dataReady = False
1313 n = None
1313 n = None
1314 __nch = 0
1314 __nch = 0
1315 __nHeis = 0
1315 __nHeis = 0
1316 removeDC = False
1316 removeDC = False
1317 ipp = None
1317 ipp = None
1318 lambda_ = 0
1318 lambda_ = 0
1319
1319
1320 def __init__(self,**kwargs):
1320 def __init__(self,**kwargs):
1321 Operation.__init__(self,**kwargs)
1321 Operation.__init__(self,**kwargs)
1322
1322
1323 def setup(self, dataOut, n = None, removeDC=False):
1323 def setup(self, dataOut, n = None, removeDC=False):
1324 '''
1324 '''
1325 n= Numero de PRF's de entrada
1325 n= Numero de PRF's de entrada
1326 '''
1326 '''
1327 self.__initime = None
1327 self.__initime = None
1328 ####print("[INICIO]-setup del METODO PULSE PAIR")
1328 ####print("[INICIO]-setup del METODO PULSE PAIR")
1329 self.__lastdatatime = 0
1329 self.__lastdatatime = 0
1330 self.__dataReady = False
1330 self.__dataReady = False
1331 self.__buffer = 0
1331 self.__buffer = 0
1332 self.__profIndex = 0
1332 self.__profIndex = 0
1333 self.noise = None
1333 self.noise = None
1334 self.__nch = dataOut.nChannels
1334 self.__nch = dataOut.nChannels
1335 self.__nHeis = dataOut.nHeights
1335 self.__nHeis = dataOut.nHeights
1336 self.removeDC = removeDC
1336 self.removeDC = removeDC
1337 self.lambda_ = 3.0e8/(9345.0e6)
1337 self.lambda_ = 3.0e8/(9345.0e6)
1338 self.ippSec = dataOut.ippSeconds
1338 self.ippSec = dataOut.ippSeconds
1339 self.nCohInt = dataOut.nCohInt
1339 self.nCohInt = dataOut.nCohInt
1340 ####print("IPPseconds",dataOut.ippSeconds)
1340 ####print("IPPseconds",dataOut.ippSeconds)
1341 ####print("ELVALOR DE n es:", n)
1341 ####print("ELVALOR DE n es:", n)
1342 if n == None:
1342 if n == None:
1343 raise ValueError("n should be specified.")
1343 raise ValueError("n should be specified.")
1344
1344
1345 if n != None:
1345 if n != None:
1346 if n<2:
1346 if n<2:
1347 raise ValueError("n should be greater than 2")
1347 raise ValueError("n should be greater than 2")
1348
1348
1349 self.n = n
1349 self.n = n
1350 self.__nProf = n
1350 self.__nProf = n
1351
1351
1352 self.__buffer = numpy.zeros((dataOut.nChannels,
1352 self.__buffer = numpy.zeros((dataOut.nChannels,
1353 n,
1353 n,
1354 dataOut.nHeights),
1354 dataOut.nHeights),
1355 dtype='complex')
1355 dtype='complex')
1356
1356
1357 def putData(self,data):
1357 def putData(self,data):
1358 '''
1358 '''
1359 Add a profile to he __buffer and increase in one the __profiel Index
1359 Add a profile to he __buffer and increase in one the __profiel Index
1360 '''
1360 '''
1361 self.__buffer[:,self.__profIndex,:]= data
1361 self.__buffer[:,self.__profIndex,:]= data
1362 self.__profIndex += 1
1362 self.__profIndex += 1
1363 return
1363 return
1364
1364
1365 def pushData(self,dataOut):
1365 def pushData(self,dataOut):
1366 '''
1366 '''
1367 Return the PULSEPAIR and the profiles used in the operation
1367 Return the PULSEPAIR and the profiles used in the operation
1368 Affected : self.__profileIndex
1368 Affected : self.__profileIndex
1369 '''
1369 '''
1370 #----------------- Remove DC-----------------------------------
1370 #----------------- Remove DC-----------------------------------
1371 if self.removeDC==True:
1371 if self.removeDC==True:
1372 mean = numpy.mean(self.__buffer,1)
1372 mean = numpy.mean(self.__buffer,1)
1373 tmp = mean.reshape(self.__nch,1,self.__nHeis)
1373 tmp = mean.reshape(self.__nch,1,self.__nHeis)
1374 dc= numpy.tile(tmp,[1,self.__nProf,1])
1374 dc= numpy.tile(tmp,[1,self.__nProf,1])
1375 self.__buffer = self.__buffer - dc
1375 self.__buffer = self.__buffer - dc
1376 #------------------Calculo de Potencia ------------------------
1376 #------------------Calculo de Potencia ------------------------
1377 pair0 = self.__buffer*numpy.conj(self.__buffer)
1377 pair0 = self.__buffer*numpy.conj(self.__buffer)
1378 pair0 = pair0.real
1378 pair0 = pair0.real
1379 lag_0 = numpy.sum(pair0,1)
1379 lag_0 = numpy.sum(pair0,1)
1380 #-----------------Calculo de Cscp------------------------------ New
1380 #-----------------Calculo de Cscp------------------------------ New
1381 cspc_pair01 = self.__buffer[0]*self.__buffer[1]
1381 cspc_pair01 = self.__buffer[0]*self.__buffer[1]
1382 #------------------Calculo de Ruido x canal--------------------
1382 #------------------Calculo de Ruido x canal--------------------
1383 self.noise = numpy.zeros(self.__nch)
1383 self.noise = numpy.zeros(self.__nch)
1384 for i in range(self.__nch):
1384 for i in range(self.__nch):
1385 daux = numpy.sort(pair0[i,:,:],axis= None)
1385 daux = numpy.sort(pair0[i,:,:],axis= None)
1386 self.noise[i]=hildebrand_sekhon( daux ,self.nCohInt)
1386 self.noise[i]=hildebrand_sekhon( daux ,self.nCohInt)
1387
1387
1388 self.noise = self.noise.reshape(self.__nch,1)
1388 self.noise = self.noise.reshape(self.__nch,1)
1389 self.noise = numpy.tile(self.noise,[1,self.__nHeis])
1389 self.noise = numpy.tile(self.noise,[1,self.__nHeis])
1390 noise_buffer = self.noise.reshape(self.__nch,1,self.__nHeis)
1390 noise_buffer = self.noise.reshape(self.__nch,1,self.__nHeis)
1391 noise_buffer = numpy.tile(noise_buffer,[1,self.__nProf,1])
1391 noise_buffer = numpy.tile(noise_buffer,[1,self.__nProf,1])
1392 #------------------ Potencia recibida= P , Potencia senal = S , Ruido= N--
1392 #------------------ Potencia recibida= P , Potencia senal = S , Ruido= N--
1393 #------------------ P= S+N ,P=lag_0/N ---------------------------------
1393 #------------------ P= S+N ,P=lag_0/N ---------------------------------
1394 #-------------------- Power --------------------------------------------------
1394 #-------------------- Power --------------------------------------------------
1395 data_power = lag_0/(self.n*self.nCohInt)
1395 data_power = lag_0/(self.n*self.nCohInt)
1396 #--------------------CCF------------------------------------------------------
1396 #--------------------CCF------------------------------------------------------
1397 data_ccf =numpy.sum(cspc_pair01,axis=0)/(self.n*self.nCohInt)
1397 data_ccf =numpy.sum(cspc_pair01,axis=0)/(self.n*self.nCohInt)
1398 #------------------ Senal --------------------------------------------------
1398 #------------------ Senal --------------------------------------------------
1399 data_intensity = pair0 - noise_buffer
1399 data_intensity = pair0 - noise_buffer
1400 data_intensity = numpy.sum(data_intensity,axis=1)*(self.n*self.nCohInt)#*self.nCohInt)
1400 data_intensity = numpy.sum(data_intensity,axis=1)*(self.n*self.nCohInt)#*self.nCohInt)
1401 #data_intensity = (lag_0-self.noise*self.n)*(self.n*self.nCohInt)
1401 #data_intensity = (lag_0-self.noise*self.n)*(self.n*self.nCohInt)
1402 for i in range(self.__nch):
1402 for i in range(self.__nch):
1403 for j in range(self.__nHeis):
1403 for j in range(self.__nHeis):
1404 if data_intensity[i][j] < 0:
1404 if data_intensity[i][j] < 0:
1405 data_intensity[i][j] = numpy.min(numpy.absolute(data_intensity[i][j]))
1405 data_intensity[i][j] = numpy.min(numpy.absolute(data_intensity[i][j]))
1406
1406
1407 #----------------- Calculo de Frecuencia y Velocidad doppler--------
1407 #----------------- Calculo de Frecuencia y Velocidad doppler--------
1408 pair1 = self.__buffer[:,:-1,:]*numpy.conjugate(self.__buffer[:,1:,:])
1408 pair1 = self.__buffer[:,:-1,:]*numpy.conjugate(self.__buffer[:,1:,:])
1409 lag_1 = numpy.sum(pair1,1)
1409 lag_1 = numpy.sum(pair1,1)
1410 data_freq = (-1/(2.0*math.pi*self.ippSec*self.nCohInt))*numpy.angle(lag_1)
1410 data_freq = (-1/(2.0*math.pi*self.ippSec*self.nCohInt))*numpy.angle(lag_1)
1411 data_velocity = (self.lambda_/2.0)*data_freq
1411 data_velocity = (self.lambda_/2.0)*data_freq
1412
1412
1413 #---------------- Potencia promedio estimada de la Senal-----------
1413 #---------------- Potencia promedio estimada de la Senal-----------
1414 lag_0 = lag_0/self.n
1414 lag_0 = lag_0/self.n
1415 S = lag_0-self.noise
1415 S = lag_0-self.noise
1416
1416
1417 #---------------- Frecuencia Doppler promedio ---------------------
1417 #---------------- Frecuencia Doppler promedio ---------------------
1418 lag_1 = lag_1/(self.n-1)
1418 lag_1 = lag_1/(self.n-1)
1419 R1 = numpy.abs(lag_1)
1419 R1 = numpy.abs(lag_1)
1420
1420
1421 #---------------- Calculo del SNR----------------------------------
1421 #---------------- Calculo del SNR----------------------------------
1422 data_snrPP = S/self.noise
1422 data_snrPP = S/self.noise
1423 for i in range(self.__nch):
1423 for i in range(self.__nch):
1424 for j in range(self.__nHeis):
1424 for j in range(self.__nHeis):
1425 if data_snrPP[i][j] < 1.e-20:
1425 if data_snrPP[i][j] < 1.e-20:
1426 data_snrPP[i][j] = 1.e-20
1426 data_snrPP[i][j] = 1.e-20
1427
1427
1428 #----------------- Calculo del ancho espectral ----------------------
1428 #----------------- Calculo del ancho espectral ----------------------
1429 L = S/R1
1429 L = S/R1
1430 L = numpy.where(L<0,1,L)
1430 L = numpy.where(L<0,1,L)
1431 L = numpy.log(L)
1431 L = numpy.log(L)
1432 tmp = numpy.sqrt(numpy.absolute(L))
1432 tmp = numpy.sqrt(numpy.absolute(L))
1433 data_specwidth = (self.lambda_/(2*math.sqrt(2)*math.pi*self.ippSec*self.nCohInt))*tmp*numpy.sign(L)
1433 data_specwidth = (self.lambda_/(2*math.sqrt(2)*math.pi*self.ippSec*self.nCohInt))*tmp*numpy.sign(L)
1434 n = self.__profIndex
1434 n = self.__profIndex
1435
1435
1436 self.__buffer = numpy.zeros((self.__nch, self.__nProf,self.__nHeis), dtype='complex')
1436 self.__buffer = numpy.zeros((self.__nch, self.__nProf,self.__nHeis), dtype='complex')
1437 self.__profIndex = 0
1437 self.__profIndex = 0
1438 return data_power,data_intensity,data_velocity,data_snrPP,data_specwidth,data_ccf,n
1438 return data_power,data_intensity,data_velocity,data_snrPP,data_specwidth,data_ccf,n
1439
1439
1440
1440
1441 def pulsePairbyProfiles(self,dataOut):
1441 def pulsePairbyProfiles(self,dataOut):
1442
1442
1443 self.__dataReady = False
1443 self.__dataReady = False
1444 data_power = None
1444 data_power = None
1445 data_intensity = None
1445 data_intensity = None
1446 data_velocity = None
1446 data_velocity = None
1447 data_specwidth = None
1447 data_specwidth = None
1448 data_snrPP = None
1448 data_snrPP = None
1449 data_ccf = None
1449 data_ccf = None
1450 self.putData(data=dataOut.data)
1450 self.putData(data=dataOut.data)
1451 if self.__profIndex == self.n:
1451 if self.__profIndex == self.n:
1452 data_power,data_intensity, data_velocity,data_snrPP,data_specwidth,data_ccf, n = self.pushData(dataOut=dataOut)
1452 data_power,data_intensity, data_velocity,data_snrPP,data_specwidth,data_ccf, n = self.pushData(dataOut=dataOut)
1453 self.__dataReady = True
1453 self.__dataReady = True
1454
1454
1455 return data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf
1455 return data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf
1456
1456
1457
1457
1458 def pulsePairOp(self, dataOut, datatime= None):
1458 def pulsePairOp(self, dataOut, datatime= None):
1459
1459
1460 if self.__initime == None:
1460 if self.__initime == None:
1461 self.__initime = datatime
1461 self.__initime = datatime
1462 data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf = self.pulsePairbyProfiles(dataOut)
1462 data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf = self.pulsePairbyProfiles(dataOut)
1463 self.__lastdatatime = datatime
1463 self.__lastdatatime = datatime
1464
1464
1465 if data_power is None:
1465 if data_power is None:
1466 return None, None, None,None,None,None,None
1466 return None, None, None,None,None,None,None
1467
1467
1468 avgdatatime = self.__initime
1468 avgdatatime = self.__initime
1469 deltatime = datatime - self.__lastdatatime
1469 deltatime = datatime - self.__lastdatatime
1470 self.__initime = datatime
1470 self.__initime = datatime
1471
1471
1472 return data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf, avgdatatime
1472 return data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf, avgdatatime
1473
1473
1474 def run(self, dataOut,n = None,removeDC= False, overlapping= False,**kwargs):
1474 def run(self, dataOut,n = None,removeDC= False, overlapping= False,**kwargs):
1475 #print("hey")
1475 #print("hey")
1476 #print(dataOut.data.shape)
1476 #print(dataOut.data.shape)
1477 #exit(1)
1477 #exit(1)
1478 #print(self.__profIndex)
1478 #print(self.__profIndex)
1479 if not self.isConfig:
1479 if not self.isConfig:
1480 self.setup(dataOut = dataOut, n = n , removeDC=removeDC , **kwargs)
1480 self.setup(dataOut = dataOut, n = n , removeDC=removeDC , **kwargs)
1481 self.isConfig = True
1481 self.isConfig = True
1482 data_power, data_intensity, data_velocity,data_snrPP,data_specwidth,data_ccf, avgdatatime = self.pulsePairOp(dataOut, dataOut.utctime)
1482 data_power, data_intensity, data_velocity,data_snrPP,data_specwidth,data_ccf, avgdatatime = self.pulsePairOp(dataOut, dataOut.utctime)
1483 dataOut.flagNoData = True
1483 dataOut.flagNoData = True
1484
1484
1485 if self.__dataReady:
1485 if self.__dataReady:
1486 ###print("READY ----------------------------------")
1486 ###print("READY ----------------------------------")
1487 dataOut.nCohInt *= self.n
1487 dataOut.nCohInt *= self.n
1488 dataOut.dataPP_POW = data_intensity # S
1488 dataOut.dataPP_POW = data_intensity # S
1489 dataOut.dataPP_POWER = data_power # P valor que corresponde a POTENCIA MOMENTO
1489 dataOut.dataPP_POWER = data_power # P valor que corresponde a POTENCIA MOMENTO
1490 dataOut.dataPP_DOP = data_velocity
1490 dataOut.dataPP_DOP = data_velocity
1491 dataOut.dataPP_SNR = data_snrPP
1491 dataOut.dataPP_SNR = data_snrPP
1492 dataOut.dataPP_WIDTH = data_specwidth
1492 dataOut.dataPP_WIDTH = data_specwidth
1493 dataOut.dataPP_CCF = data_ccf
1493 dataOut.dataPP_CCF = data_ccf
1494 dataOut.PRFbyAngle = self.n #numero de PRF*cada angulo rotado que equivale a un tiempo.
1494 dataOut.PRFbyAngle = self.n #numero de PRF*cada angulo rotado que equivale a un tiempo.
1495 dataOut.nProfiles = int(dataOut.nProfiles/n)
1495 dataOut.nProfiles = int(dataOut.nProfiles/n)
1496 dataOut.utctime = avgdatatime
1496 dataOut.utctime = avgdatatime
1497 dataOut.flagNoData = False
1497 dataOut.flagNoData = False
1498 return dataOut
1498 return dataOut
1499
1499
1500 class PulsePair_vRF(Operation):
1500 class PulsePair_vRF(Operation):
1501 '''
1501 '''
1502 Function PulsePair(Signal Power, Velocity)
1502 Function PulsePair(Signal Power, Velocity)
1503 The real component of Lag[0] provides Intensity Information
1503 The real component of Lag[0] provides Intensity Information
1504 The imag component of Lag[1] Phase provides Velocity Information
1504 The imag component of Lag[1] Phase provides Velocity Information
1505
1505
1506 Configuration Parameters:
1506 Configuration Parameters:
1507 nPRF = Number of Several PRF
1507 nPRF = Number of Several PRF
1508 theta = Degree Azimuth angel Boundaries
1508 theta = Degree Azimuth angel Boundaries
1509
1509
1510 Input:
1510 Input:
1511 self.dataOut
1511 self.dataOut
1512 lag[N]
1512 lag[N]
1513 Affected:
1513 Affected:
1514 self.dataOut.spc
1514 self.dataOut.spc
1515 '''
1515 '''
1516 isConfig = False
1516 isConfig = False
1517 __profIndex = 0
1517 __profIndex = 0
1518 __initime = None
1518 __initime = None
1519 __lastdatatime = None
1519 __lastdatatime = None
1520 __buffer = None
1520 __buffer = None
1521 noise = None
1521 noise = None
1522 __dataReady = False
1522 __dataReady = False
1523 n = None
1523 n = None
1524 __nch = 0
1524 __nch = 0
1525 __nHeis = 0
1525 __nHeis = 0
1526 removeDC = False
1526 removeDC = False
1527 ipp = None
1527 ipp = None
1528 lambda_ = 0
1528 lambda_ = 0
1529
1529
1530 def __init__(self,**kwargs):
1530 def __init__(self,**kwargs):
1531 Operation.__init__(self,**kwargs)
1531 Operation.__init__(self,**kwargs)
1532
1532
1533 def setup(self, dataOut, n = None, removeDC=False):
1533 def setup(self, dataOut, n = None, removeDC=False):
1534 '''
1534 '''
1535 n= Numero de PRF's de entrada
1535 n= Numero de PRF's de entrada
1536 '''
1536 '''
1537 self.__initime = None
1537 self.__initime = None
1538 ####print("[INICIO]-setup del METODO PULSE PAIR")
1538 ####print("[INICIO]-setup del METODO PULSE PAIR")
1539 self.__lastdatatime = 0
1539 self.__lastdatatime = 0
1540 self.__dataReady = False
1540 self.__dataReady = False
1541 self.__buffer = 0
1541 self.__buffer = 0
1542 self.__profIndex = 0
1542 self.__profIndex = 0
1543 self.noise = None
1543 self.noise = None
1544 self.__nch = dataOut.nChannels
1544 self.__nch = dataOut.nChannels
1545 self.__nHeis = dataOut.nHeights
1545 self.__nHeis = dataOut.nHeights
1546 self.removeDC = removeDC
1546 self.removeDC = removeDC
1547 self.lambda_ = 3.0e8/(9345.0e6)
1547 self.lambda_ = 3.0e8/(9345.0e6)
1548 self.ippSec = dataOut.ippSeconds
1548 self.ippSec = dataOut.ippSeconds
1549 self.nCohInt = dataOut.nCohInt
1549 self.nCohInt = dataOut.nCohInt
1550 ####print("IPPseconds",dataOut.ippSeconds)
1550 ####print("IPPseconds",dataOut.ippSeconds)
1551 ####print("ELVALOR DE n es:", n)
1551 ####print("ELVALOR DE n es:", n)
1552 if n == None:
1552 if n == None:
1553 raise ValueError("n should be specified.")
1553 raise ValueError("n should be specified.")
1554
1554
1555 if n != None:
1555 if n != None:
1556 if n<2:
1556 if n<2:
1557 raise ValueError("n should be greater than 2")
1557 raise ValueError("n should be greater than 2")
1558
1558
1559 self.n = n
1559 self.n = n
1560 self.__nProf = n
1560 self.__nProf = n
1561
1561
1562 self.__buffer = numpy.zeros((dataOut.nChannels,
1562 self.__buffer = numpy.zeros((dataOut.nChannels,
1563 n,
1563 n,
1564 dataOut.nHeights),
1564 dataOut.nHeights),
1565 dtype='complex')
1565 dtype='complex')
1566
1566
1567 def putData(self,data):
1567 def putData(self,data):
1568 '''
1568 '''
1569 Add a profile to he __buffer and increase in one the __profiel Index
1569 Add a profile to he __buffer and increase in one the __profiel Index
1570 '''
1570 '''
1571 self.__buffer[:,self.__profIndex,:]= data
1571 self.__buffer[:,self.__profIndex,:]= data
1572 self.__profIndex += 1
1572 self.__profIndex += 1
1573 return
1573 return
1574
1574
1575 def putDataByBlock(self,data,n):
1575 def putDataByBlock(self,data,n):
1576 '''
1576 '''
1577 Add a profile to he __buffer and increase in one the __profiel Index
1577 Add a profile to he __buffer and increase in one the __profiel Index
1578 '''
1578 '''
1579 self.__buffer[:]= data
1579 self.__buffer[:]= data
1580 self.__profIndex = n
1580 self.__profIndex = n
1581 return
1581 return
1582
1582
1583 def pushData(self,dataOut):
1583 def pushData(self,dataOut):
1584 '''
1584 '''
1585 Return the PULSEPAIR and the profiles used in the operation
1585 Return the PULSEPAIR and the profiles used in the operation
1586 Affected : self.__profileIndex
1586 Affected : self.__profileIndex
1587 '''
1587 '''
1588 #----------------- Remove DC-----------------------------------
1588 #----------------- Remove DC-----------------------------------
1589 if self.removeDC==True:
1589 if self.removeDC==True:
1590 mean = numpy.mean(self.__buffer,1)
1590 mean = numpy.mean(self.__buffer,1)
1591 tmp = mean.reshape(self.__nch,1,self.__nHeis)
1591 tmp = mean.reshape(self.__nch,1,self.__nHeis)
1592 dc= numpy.tile(tmp,[1,self.__nProf,1])
1592 dc= numpy.tile(tmp,[1,self.__nProf,1])
1593 self.__buffer = self.__buffer - dc
1593 self.__buffer = self.__buffer - dc
1594 #------------------Calculo de Potencia ------------------------
1594 #------------------Calculo de Potencia ------------------------
1595 pair0 = self.__buffer*numpy.conj(self.__buffer)
1595 pair0 = self.__buffer*numpy.conj(self.__buffer)
1596 pair0 = pair0.real
1596 pair0 = pair0.real
1597 lag_0 = numpy.sum(pair0,1)
1597 lag_0 = numpy.sum(pair0,1)
1598 #-----------------Calculo de Cscp------------------------------ New
1598 #-----------------Calculo de Cscp------------------------------ New
1599 cspc_pair01 = self.__buffer[0]*self.__buffer[1]
1599 cspc_pair01 = self.__buffer[0]*self.__buffer[1]
1600 #------------------Calculo de Ruido x canal--------------------
1600 #------------------Calculo de Ruido x canal--------------------
1601 self.noise = numpy.zeros(self.__nch)
1601 self.noise = numpy.zeros(self.__nch)
1602 for i in range(self.__nch):
1602 for i in range(self.__nch):
1603 daux = numpy.sort(pair0[i,:,:],axis= None)
1603 daux = numpy.sort(pair0[i,:,:],axis= None)
1604 self.noise[i]=hildebrand_sekhon( daux ,self.nCohInt)
1604 self.noise[i]=hildebrand_sekhon( daux ,self.nCohInt)
1605
1605
1606 self.noise = self.noise.reshape(self.__nch,1)
1606 self.noise = self.noise.reshape(self.__nch,1)
1607 self.noise = numpy.tile(self.noise,[1,self.__nHeis])
1607 self.noise = numpy.tile(self.noise,[1,self.__nHeis])
1608 noise_buffer = self.noise.reshape(self.__nch,1,self.__nHeis)
1608 noise_buffer = self.noise.reshape(self.__nch,1,self.__nHeis)
1609 noise_buffer = numpy.tile(noise_buffer,[1,self.__nProf,1])
1609 noise_buffer = numpy.tile(noise_buffer,[1,self.__nProf,1])
1610 #------------------ Potencia recibida= P , Potencia senal = S , Ruido= N--
1610 #------------------ Potencia recibida= P , Potencia senal = S , Ruido= N--
1611 #------------------ P= S+N ,P=lag_0/N ---------------------------------
1611 #------------------ P= S+N ,P=lag_0/N ---------------------------------
1612 #-------------------- Power --------------------------------------------------
1612 #-------------------- Power --------------------------------------------------
1613 data_power = lag_0/(self.n*self.nCohInt)
1613 data_power = lag_0/(self.n*self.nCohInt)
1614 #--------------------CCF------------------------------------------------------
1614 #--------------------CCF------------------------------------------------------
1615 data_ccf =numpy.sum(cspc_pair01,axis=0)/(self.n*self.nCohInt)
1615 data_ccf =numpy.sum(cspc_pair01,axis=0)/(self.n*self.nCohInt)
1616 #------------------ Senal --------------------------------------------------
1616 #------------------ Senal --------------------------------------------------
1617 data_intensity = pair0 - noise_buffer
1617 data_intensity = pair0 - noise_buffer
1618 data_intensity = numpy.sum(data_intensity,axis=1)*(self.n*self.nCohInt)#*self.nCohInt)
1618 data_intensity = numpy.sum(data_intensity,axis=1)*(self.n*self.nCohInt)#*self.nCohInt)
1619 #data_intensity = (lag_0-self.noise*self.n)*(self.n*self.nCohInt)
1619 #data_intensity = (lag_0-self.noise*self.n)*(self.n*self.nCohInt)
1620 for i in range(self.__nch):
1620 for i in range(self.__nch):
1621 for j in range(self.__nHeis):
1621 for j in range(self.__nHeis):
1622 if data_intensity[i][j] < 0:
1622 if data_intensity[i][j] < 0:
1623 data_intensity[i][j] = numpy.min(numpy.absolute(data_intensity[i][j]))
1623 data_intensity[i][j] = numpy.min(numpy.absolute(data_intensity[i][j]))
1624
1624
1625 #----------------- Calculo de Frecuencia y Velocidad doppler--------
1625 #----------------- Calculo de Frecuencia y Velocidad doppler--------
1626 pair1 = self.__buffer[:,:-1,:]*numpy.conjugate(self.__buffer[:,1:,:])
1626 pair1 = self.__buffer[:,:-1,:]*numpy.conjugate(self.__buffer[:,1:,:])
1627 lag_1 = numpy.sum(pair1,1)
1627 lag_1 = numpy.sum(pair1,1)
1628 data_freq = (-1/(2.0*math.pi*self.ippSec*self.nCohInt))*numpy.angle(lag_1)
1628 data_freq = (-1/(2.0*math.pi*self.ippSec*self.nCohInt))*numpy.angle(lag_1)
1629 data_velocity = (self.lambda_/2.0)*data_freq
1629 data_velocity = (self.lambda_/2.0)*data_freq
1630
1630
1631 #---------------- Potencia promedio estimada de la Senal-----------
1631 #---------------- Potencia promedio estimada de la Senal-----------
1632 lag_0 = lag_0/self.n
1632 lag_0 = lag_0/self.n
1633 S = lag_0-self.noise
1633 S = lag_0-self.noise
1634
1634
1635 #---------------- Frecuencia Doppler promedio ---------------------
1635 #---------------- Frecuencia Doppler promedio ---------------------
1636 lag_1 = lag_1/(self.n-1)
1636 lag_1 = lag_1/(self.n-1)
1637 R1 = numpy.abs(lag_1)
1637 R1 = numpy.abs(lag_1)
1638
1638
1639 #---------------- Calculo del SNR----------------------------------
1639 #---------------- Calculo del SNR----------------------------------
1640 data_snrPP = S/self.noise
1640 data_snrPP = S/self.noise
1641 for i in range(self.__nch):
1641 for i in range(self.__nch):
1642 for j in range(self.__nHeis):
1642 for j in range(self.__nHeis):
1643 if data_snrPP[i][j] < 1.e-20:
1643 if data_snrPP[i][j] < 1.e-20:
1644 data_snrPP[i][j] = 1.e-20
1644 data_snrPP[i][j] = 1.e-20
1645
1645
1646 #----------------- Calculo del ancho espectral ----------------------
1646 #----------------- Calculo del ancho espectral ----------------------
1647 L = S/R1
1647 L = S/R1
1648 L = numpy.where(L<0,1,L)
1648 L = numpy.where(L<0,1,L)
1649 L = numpy.log(L)
1649 L = numpy.log(L)
1650 tmp = numpy.sqrt(numpy.absolute(L))
1650 tmp = numpy.sqrt(numpy.absolute(L))
1651 data_specwidth = (self.lambda_/(2*math.sqrt(2)*math.pi*self.ippSec*self.nCohInt))*tmp*numpy.sign(L)
1651 data_specwidth = (self.lambda_/(2*math.sqrt(2)*math.pi*self.ippSec*self.nCohInt))*tmp*numpy.sign(L)
1652 n = self.__profIndex
1652 n = self.__profIndex
1653
1653
1654 self.__buffer = numpy.zeros((self.__nch, self.__nProf,self.__nHeis), dtype='complex')
1654 self.__buffer = numpy.zeros((self.__nch, self.__nProf,self.__nHeis), dtype='complex')
1655 self.__profIndex = 0
1655 self.__profIndex = 0
1656 return data_power,data_intensity,data_velocity,data_snrPP,data_specwidth,data_ccf,n
1656 return data_power,data_intensity,data_velocity,data_snrPP,data_specwidth,data_ccf,n
1657
1657
1658
1658
1659 def pulsePairbyProfiles(self,dataOut,n):
1659 def pulsePairbyProfiles(self,dataOut,n):
1660
1660
1661 self.__dataReady = False
1661 self.__dataReady = False
1662 data_power = None
1662 data_power = None
1663 data_intensity = None
1663 data_intensity = None
1664 data_velocity = None
1664 data_velocity = None
1665 data_specwidth = None
1665 data_specwidth = None
1666 data_snrPP = None
1666 data_snrPP = None
1667 data_ccf = None
1667 data_ccf = None
1668
1668
1669 if dataOut.flagDataAsBlock:
1669 if dataOut.flagDataAsBlock:
1670 self.putDataByBlock(data=dataOut.data,n=n)
1670 self.putDataByBlock(data=dataOut.data,n=n)
1671 else:
1671 else:
1672 self.putData(data=dataOut.data)
1672 self.putData(data=dataOut.data)
1673 if self.__profIndex == self.n:
1673 if self.__profIndex == self.n:
1674 data_power,data_intensity, data_velocity,data_snrPP,data_specwidth,data_ccf, n = self.pushData(dataOut=dataOut)
1674 data_power,data_intensity, data_velocity,data_snrPP,data_specwidth,data_ccf, n = self.pushData(dataOut=dataOut)
1675 self.__dataReady = True
1675 self.__dataReady = True
1676
1676
1677 return data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf
1677 return data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf
1678
1678
1679
1679
1680 def pulsePairOp(self, dataOut, n, datatime= None):
1680 def pulsePairOp(self, dataOut, n, datatime= None):
1681
1681
1682 if self.__initime == None:
1682 if self.__initime == None:
1683 self.__initime = datatime
1683 self.__initime = datatime
1684 data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf = self.pulsePairbyProfiles(dataOut,n)
1684 data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf = self.pulsePairbyProfiles(dataOut,n)
1685 self.__lastdatatime = datatime
1685 self.__lastdatatime = datatime
1686
1686
1687 if data_power is None:
1687 if data_power is None:
1688 return None, None, None,None,None,None,None
1688 return None, None, None,None,None,None,None
1689
1689
1690 avgdatatime = self.__initime
1690 avgdatatime = self.__initime
1691 deltatime = datatime - self.__lastdatatime
1691 deltatime = datatime - self.__lastdatatime
1692 self.__initime = datatime
1692 self.__initime = datatime
1693
1693
1694 return data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf, avgdatatime
1694 return data_power, data_intensity, data_velocity, data_snrPP,data_specwidth,data_ccf, avgdatatime
1695
1695
1696 def run(self, dataOut,n = None,removeDC= False, overlapping= False,**kwargs):
1696 def run(self, dataOut,n = None,removeDC= False, overlapping= False,**kwargs):
1697
1697
1698 if dataOut.flagDataAsBlock:
1698 if dataOut.flagDataAsBlock:
1699 n = dataOut.nProfiles
1699 n = int(dataOut.nProfiles)
1700 #print("n",n)
1700
1701
1701 if not self.isConfig:
1702 if not self.isConfig:
1702 self.setup(dataOut = dataOut, n = n , removeDC=removeDC , **kwargs)
1703 self.setup(dataOut = dataOut, n = n , removeDC=removeDC , **kwargs)
1703 self.isConfig = True
1704 self.isConfig = True
1704
1705
1705
1706
1706 data_power, data_intensity, data_velocity,data_snrPP,data_specwidth,data_ccf, avgdatatime = self.pulsePairOp(dataOut, n, dataOut.utctime)
1707 data_power, data_intensity, data_velocity,data_snrPP,data_specwidth,data_ccf, avgdatatime = self.pulsePairOp(dataOut, n, dataOut.utctime)
1707
1708
1708
1709
1709 dataOut.flagNoData = True
1710 dataOut.flagNoData = True
1710
1711
1711 if self.__dataReady:
1712 if self.__dataReady:
1712 ###print("READY ----------------------------------")
1713 ###print("READY ----------------------------------")
1713 dataOut.nCohInt *= self.n
1714 dataOut.nCohInt *= self.n
1714 dataOut.dataPP_POW = data_intensity # S
1715 dataOut.dataPP_POW = data_intensity # S
1715 dataOut.dataPP_POWER = data_power # P valor que corresponde a POTENCIA MOMENTO
1716 dataOut.dataPP_POWER = data_power # P valor que corresponde a POTENCIA MOMENTO
1716 dataOut.dataPP_DOP = data_velocity
1717 dataOut.dataPP_DOP = data_velocity
1717 dataOut.dataPP_SNR = data_snrPP
1718 dataOut.dataPP_SNR = data_snrPP
1718 dataOut.dataPP_WIDTH = data_specwidth
1719 dataOut.dataPP_WIDTH = data_specwidth
1719 dataOut.dataPP_CCF = data_ccf
1720 dataOut.dataPP_CCF = data_ccf
1720 dataOut.PRFbyAngle = self.n #numero de PRF*cada angulo rotado que equivale a un tiempo.
1721 dataOut.PRFbyAngle = self.n #numero de PRF*cada angulo rotado que equivale a un tiempo.
1721 dataOut.nProfiles = int(dataOut.nProfiles/n)
1722 dataOut.nProfiles = int(dataOut.nProfiles/n)
1722 dataOut.utctime = avgdatatime
1723 dataOut.utctime = avgdatatime
1723 dataOut.flagNoData = False
1724 dataOut.flagNoData = False
1724 return dataOut
1725 return dataOut
1725
1726
1726 # import collections
1727 # import collections
1727 # from scipy.stats import mode
1728 # from scipy.stats import mode
1728 #
1729 #
1729 # class Synchronize(Operation):
1730 # class Synchronize(Operation):
1730 #
1731 #
1731 # isConfig = False
1732 # isConfig = False
1732 # __profIndex = 0
1733 # __profIndex = 0
1733 #
1734 #
1734 # def __init__(self, **kwargs):
1735 # def __init__(self, **kwargs):
1735 #
1736 #
1736 # Operation.__init__(self, **kwargs)
1737 # Operation.__init__(self, **kwargs)
1737 # # self.isConfig = False
1738 # # self.isConfig = False
1738 # self.__powBuffer = None
1739 # self.__powBuffer = None
1739 # self.__startIndex = 0
1740 # self.__startIndex = 0
1740 # self.__pulseFound = False
1741 # self.__pulseFound = False
1741 #
1742 #
1742 # def __findTxPulse(self, dataOut, channel=0, pulse_with = None):
1743 # def __findTxPulse(self, dataOut, channel=0, pulse_with = None):
1743 #
1744 #
1744 # #Read data
1745 # #Read data
1745 #
1746 #
1746 # powerdB = dataOut.getPower(channel = channel)
1747 # powerdB = dataOut.getPower(channel = channel)
1747 # noisedB = dataOut.getNoise(channel = channel)[0]
1748 # noisedB = dataOut.getNoise(channel = channel)[0]
1748 #
1749 #
1749 # self.__powBuffer.extend(powerdB.flatten())
1750 # self.__powBuffer.extend(powerdB.flatten())
1750 #
1751 #
1751 # dataArray = numpy.array(self.__powBuffer)
1752 # dataArray = numpy.array(self.__powBuffer)
1752 #
1753 #
1753 # filteredPower = numpy.correlate(dataArray, dataArray[0:self.__nSamples], "same")
1754 # filteredPower = numpy.correlate(dataArray, dataArray[0:self.__nSamples], "same")
1754 #
1755 #
1755 # maxValue = numpy.nanmax(filteredPower)
1756 # maxValue = numpy.nanmax(filteredPower)
1756 #
1757 #
1757 # if maxValue < noisedB + 10:
1758 # if maxValue < noisedB + 10:
1758 # #No se encuentra ningun pulso de transmision
1759 # #No se encuentra ningun pulso de transmision
1759 # return None
1760 # return None
1760 #
1761 #
1761 # maxValuesIndex = numpy.where(filteredPower > maxValue - 0.1*abs(maxValue))[0]
1762 # maxValuesIndex = numpy.where(filteredPower > maxValue - 0.1*abs(maxValue))[0]
1762 #
1763 #
1763 # if len(maxValuesIndex) < 2:
1764 # if len(maxValuesIndex) < 2:
1764 # #Solo se encontro un solo pulso de transmision de un baudio, esperando por el siguiente TX
1765 # #Solo se encontro un solo pulso de transmision de un baudio, esperando por el siguiente TX
1765 # return None
1766 # return None
1766 #
1767 #
1767 # phasedMaxValuesIndex = maxValuesIndex - self.__nSamples
1768 # phasedMaxValuesIndex = maxValuesIndex - self.__nSamples
1768 #
1769 #
1769 # #Seleccionar solo valores con un espaciamiento de nSamples
1770 # #Seleccionar solo valores con un espaciamiento de nSamples
1770 # pulseIndex = numpy.intersect1d(maxValuesIndex, phasedMaxValuesIndex)
1771 # pulseIndex = numpy.intersect1d(maxValuesIndex, phasedMaxValuesIndex)
1771 #
1772 #
1772 # if len(pulseIndex) < 2:
1773 # if len(pulseIndex) < 2:
1773 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1774 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1774 # return None
1775 # return None
1775 #
1776 #
1776 # spacing = pulseIndex[1:] - pulseIndex[:-1]
1777 # spacing = pulseIndex[1:] - pulseIndex[:-1]
1777 #
1778 #
1778 # #remover senales que se distancien menos de 10 unidades o muestras
1779 # #remover senales que se distancien menos de 10 unidades o muestras
1779 # #(No deberian existir IPP menor a 10 unidades)
1780 # #(No deberian existir IPP menor a 10 unidades)
1780 #
1781 #
1781 # realIndex = numpy.where(spacing > 10 )[0]
1782 # realIndex = numpy.where(spacing > 10 )[0]
1782 #
1783 #
1783 # if len(realIndex) < 2:
1784 # if len(realIndex) < 2:
1784 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1785 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1785 # return None
1786 # return None
1786 #
1787 #
1787 # #Eliminar pulsos anchos (deja solo la diferencia entre IPPs)
1788 # #Eliminar pulsos anchos (deja solo la diferencia entre IPPs)
1788 # realPulseIndex = pulseIndex[realIndex]
1789 # realPulseIndex = pulseIndex[realIndex]
1789 #
1790 #
1790 # period = mode(realPulseIndex[1:] - realPulseIndex[:-1])[0][0]
1791 # period = mode(realPulseIndex[1:] - realPulseIndex[:-1])[0][0]
1791 #
1792 #
1792 # print "IPP = %d samples" %period
1793 # print "IPP = %d samples" %period
1793 #
1794 #
1794 # self.__newNSamples = dataOut.nHeights #int(period)
1795 # self.__newNSamples = dataOut.nHeights #int(period)
1795 # self.__startIndex = int(realPulseIndex[0])
1796 # self.__startIndex = int(realPulseIndex[0])
1796 #
1797 #
1797 # return 1
1798 # return 1
1798 #
1799 #
1799 #
1800 #
1800 # def setup(self, nSamples, nChannels, buffer_size = 4):
1801 # def setup(self, nSamples, nChannels, buffer_size = 4):
1801 #
1802 #
1802 # self.__powBuffer = collections.deque(numpy.zeros( buffer_size*nSamples,dtype=numpy.float),
1803 # self.__powBuffer = collections.deque(numpy.zeros( buffer_size*nSamples,dtype=numpy.float),
1803 # maxlen = buffer_size*nSamples)
1804 # maxlen = buffer_size*nSamples)
1804 #
1805 #
1805 # bufferList = []
1806 # bufferList = []
1806 #
1807 #
1807 # for i in range(nChannels):
1808 # for i in range(nChannels):
1808 # bufferByChannel = collections.deque(numpy.zeros( buffer_size*nSamples, dtype=numpy.complex) + numpy.NAN,
1809 # bufferByChannel = collections.deque(numpy.zeros( buffer_size*nSamples, dtype=numpy.complex) + numpy.NAN,
1809 # maxlen = buffer_size*nSamples)
1810 # maxlen = buffer_size*nSamples)
1810 #
1811 #
1811 # bufferList.append(bufferByChannel)
1812 # bufferList.append(bufferByChannel)
1812 #
1813 #
1813 # self.__nSamples = nSamples
1814 # self.__nSamples = nSamples
1814 # self.__nChannels = nChannels
1815 # self.__nChannels = nChannels
1815 # self.__bufferList = bufferList
1816 # self.__bufferList = bufferList
1816 #
1817 #
1817 # def run(self, dataOut, channel = 0):
1818 # def run(self, dataOut, channel = 0):
1818 #
1819 #
1819 # if not self.isConfig:
1820 # if not self.isConfig:
1820 # nSamples = dataOut.nHeights
1821 # nSamples = dataOut.nHeights
1821 # nChannels = dataOut.nChannels
1822 # nChannels = dataOut.nChannels
1822 # self.setup(nSamples, nChannels)
1823 # self.setup(nSamples, nChannels)
1823 # self.isConfig = True
1824 # self.isConfig = True
1824 #
1825 #
1825 # #Append new data to internal buffer
1826 # #Append new data to internal buffer
1826 # for thisChannel in range(self.__nChannels):
1827 # for thisChannel in range(self.__nChannels):
1827 # bufferByChannel = self.__bufferList[thisChannel]
1828 # bufferByChannel = self.__bufferList[thisChannel]
1828 # bufferByChannel.extend(dataOut.data[thisChannel])
1829 # bufferByChannel.extend(dataOut.data[thisChannel])
1829 #
1830 #
1830 # if self.__pulseFound:
1831 # if self.__pulseFound:
1831 # self.__startIndex -= self.__nSamples
1832 # self.__startIndex -= self.__nSamples
1832 #
1833 #
1833 # #Finding Tx Pulse
1834 # #Finding Tx Pulse
1834 # if not self.__pulseFound:
1835 # if not self.__pulseFound:
1835 # indexFound = self.__findTxPulse(dataOut, channel)
1836 # indexFound = self.__findTxPulse(dataOut, channel)
1836 #
1837 #
1837 # if indexFound == None:
1838 # if indexFound == None:
1838 # dataOut.flagNoData = True
1839 # dataOut.flagNoData = True
1839 # return
1840 # return
1840 #
1841 #
1841 # self.__arrayBuffer = numpy.zeros((self.__nChannels, self.__newNSamples), dtype = numpy.complex)
1842 # self.__arrayBuffer = numpy.zeros((self.__nChannels, self.__newNSamples), dtype = numpy.complex)
1842 # self.__pulseFound = True
1843 # self.__pulseFound = True
1843 # self.__startIndex = indexFound
1844 # self.__startIndex = indexFound
1844 #
1845 #
1845 # #If pulse was found ...
1846 # #If pulse was found ...
1846 # for thisChannel in range(self.__nChannels):
1847 # for thisChannel in range(self.__nChannels):
1847 # bufferByChannel = self.__bufferList[thisChannel]
1848 # bufferByChannel = self.__bufferList[thisChannel]
1848 # #print self.__startIndex
1849 # #print self.__startIndex
1849 # x = numpy.array(bufferByChannel)
1850 # x = numpy.array(bufferByChannel)
1850 # self.__arrayBuffer[thisChannel] = x[self.__startIndex:self.__startIndex+self.__newNSamples]
1851 # self.__arrayBuffer[thisChannel] = x[self.__startIndex:self.__startIndex+self.__newNSamples]
1851 #
1852 #
1852 # deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1853 # deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1853 # dataOut.heightList = numpy.arange(self.__newNSamples)*deltaHeight
1854 # dataOut.heightList = numpy.arange(self.__newNSamples)*deltaHeight
1854 # # dataOut.ippSeconds = (self.__newNSamples / deltaHeight)/1e6
1855 # # dataOut.ippSeconds = (self.__newNSamples / deltaHeight)/1e6
1855 #
1856 #
1856 # dataOut.data = self.__arrayBuffer
1857 # dataOut.data = self.__arrayBuffer
1857 #
1858 #
1858 # self.__startIndex += self.__newNSamples
1859 # self.__startIndex += self.__newNSamples
1859 #
1860 #
1860 # return
1861 # return
General Comments 0
You need to be logged in to leave comments. Login now