##// END OF EJS Templates
Update de WR-Project
avaldez -
r1282:f590e95f1fbc
parent child
Show More
@@ -548,7 +548,7 class Spectra(JROData):
548
548
549 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
549 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
550 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
550 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
551
551
552 if self.nmodes:
552 if self.nmodes:
553 return velrange/self.nmodes
553 return velrange/self.nmodes
554 else:
554 else:
@@ -1104,7 +1104,7 class PlotterData(object):
1104 MAXNUMY = 100
1104 MAXNUMY = 100
1105
1105
1106 def __init__(self, code, throttle_value, exp_code, buffering=True, snr=False):
1106 def __init__(self, code, throttle_value, exp_code, buffering=True, snr=False):
1107
1107
1108 self.key = code
1108 self.key = code
1109 self.throttle = throttle_value
1109 self.throttle = throttle_value
1110 self.exp_code = exp_code
1110 self.exp_code = exp_code
@@ -1139,7 +1139,7 class PlotterData(object):
1139 return len(self.__times)
1139 return len(self.__times)
1140
1140
1141 def __getitem__(self, key):
1141 def __getitem__(self, key):
1142
1142
1143 if key not in self.data:
1143 if key not in self.data:
1144 raise KeyError(log.error('Missing key: {}'.format(key)))
1144 raise KeyError(log.error('Missing key: {}'.format(key)))
1145 if 'spc' in key or not self.buffering:
1145 if 'spc' in key or not self.buffering:
@@ -1172,7 +1172,7 class PlotterData(object):
1172 elif 'spc_moments' == plot:
1172 elif 'spc_moments' == plot:
1173 plot = 'moments'
1173 plot = 'moments'
1174 self.data[plot] = {}
1174 self.data[plot] = {}
1175
1175
1176 if 'spc' in self.data or 'rti' in self.data or 'cspc' in self.data or 'moments' in self.data:
1176 if 'spc' in self.data or 'rti' in self.data or 'cspc' in self.data or 'moments' in self.data:
1177 self.data['noise'] = {}
1177 self.data['noise'] = {}
1178 self.data['rti'] = {}
1178 self.data['rti'] = {}
@@ -1180,7 +1180,7 class PlotterData(object):
1180 self.plottypes.append('noise')
1180 self.plottypes.append('noise')
1181 if 'rti' not in self.plottypes:
1181 if 'rti' not in self.plottypes:
1182 self.plottypes.append('rti')
1182 self.plottypes.append('rti')
1183
1183
1184 def shape(self, key):
1184 def shape(self, key):
1185 '''
1185 '''
1186 Get the shape of the one-element data for the given key
1186 Get the shape of the one-element data for the given key
@@ -1196,17 +1196,17 class PlotterData(object):
1196 '''
1196 '''
1197 Update data object with new dataOut
1197 Update data object with new dataOut
1198 '''
1198 '''
1199
1199
1200 if tm in self.__times:
1200 if tm in self.__times:
1201 return
1201 return
1202 self.profileIndex = dataOut.profileIndex
1202 self.profileIndex = dataOut.profileIndex
1203 self.tm = tm
1203 self.tm = tm
1204 self.type = dataOut.type
1204 self.type = dataOut.type
1205 self.parameters = getattr(dataOut, 'parameters', [])
1205 self.parameters = getattr(dataOut, 'parameters', [])
1206
1206
1207 if hasattr(dataOut, 'meta'):
1207 if hasattr(dataOut, 'meta'):
1208 self.meta.update(dataOut.meta)
1208 self.meta.update(dataOut.meta)
1209
1209
1210 self.pairs = dataOut.pairsList
1210 self.pairs = dataOut.pairsList
1211 self.interval = dataOut.getTimeInterval()
1211 self.interval = dataOut.getTimeInterval()
1212 self.localtime = dataOut.useLocalTime
1212 self.localtime = dataOut.useLocalTime
@@ -1217,7 +1217,7 class PlotterData(object):
1217 self.__heights.append(dataOut.heightList)
1217 self.__heights.append(dataOut.heightList)
1218 self.__all_heights.update(dataOut.heightList)
1218 self.__all_heights.update(dataOut.heightList)
1219 self.__times.append(tm)
1219 self.__times.append(tm)
1220
1220
1221 for plot in self.plottypes:
1221 for plot in self.plottypes:
1222 if plot in ('spc', 'spc_moments'):
1222 if plot in ('spc', 'spc_moments'):
1223 z = dataOut.data_spc/dataOut.normFactor
1223 z = dataOut.data_spc/dataOut.normFactor
@@ -1250,8 +1250,8 class PlotterData(object):
1250 if plot == 'scope':
1250 if plot == 'scope':
1251 buffer = dataOut.data
1251 buffer = dataOut.data
1252 self.flagDataAsBlock = dataOut.flagDataAsBlock
1252 self.flagDataAsBlock = dataOut.flagDataAsBlock
1253 self.nProfiles = dataOut.nProfiles
1253 self.nProfiles = dataOut.nProfiles
1254
1254
1255 if plot == 'spc':
1255 if plot == 'spc':
1256 self.data['spc'] = buffer
1256 self.data['spc'] = buffer
1257 elif plot == 'cspc':
1257 elif plot == 'cspc':
@@ -1326,7 +1326,7 class PlotterData(object):
1326 else:
1326 else:
1327 meta['xrange'] = []
1327 meta['xrange'] = []
1328
1328
1329 meta.update(self.meta)
1329 meta.update(self.meta)
1330 ret['metadata'] = meta
1330 ret['metadata'] = meta
1331 return json.dumps(ret)
1331 return json.dumps(ret)
1332
1332
@@ -42,7 +42,7 class SpectraPlot_(Figure):
42
42
43 self.__xfilter_ena = False
43 self.__xfilter_ena = False
44 self.__yfilter_ena = False
44 self.__yfilter_ena = False
45
45
46 self.indice=1
46 self.indice=1
47
47
48 def getSubplots(self):
48 def getSubplots(self):
@@ -225,11 +225,231 class SpectraPlot_(Figure):
225 ftp=ftp,
225 ftp=ftp,
226 wr_period=wr_period,
226 wr_period=wr_period,
227 thisDatetime=thisDatetime)
227 thisDatetime=thisDatetime)
228
228
229
229
230 return dataOut
230 return dataOut
231
231
232 @MPDecorator
232 @MPDecorator
233 class WpowerPlot_(Figure):
234
235 isConfig = None
236 __nsubplots = None
237
238 WIDTHPROF = None
239 HEIGHTPROF = None
240 PREFIX = 'wpo'
241
242 def __init__(self):
243 Figure.__init__(self)
244 self.isConfig = False
245 self.__nsubplots = 1
246 self.WIDTH = 250
247 self.HEIGHT = 250
248 self.WIDTHPROF = 120
249 self.HEIGHTPROF = 0
250 self.counter_imagwr = 0
251
252 self.PLOT_CODE = WPO_CODE
253
254 self.FTP_WEI = None
255 self.EXP_CODE = None
256 self.SUB_EXP_CODE = None
257 self.PLOT_POS = None
258
259 self.__xfilter_ena = False
260 self.__yfilter_ena = False
261
262 self.indice=1
263
264 def getSubplots(self):
265
266 ncol = int(numpy.sqrt(self.nplots)+0.9)
267 nrow = int(self.nplots*1./ncol + 0.9)
268
269 return nrow, ncol
270
271 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
272
273 self.__showprofile = showprofile
274 self.nplots = nplots
275
276 ncolspan = 1
277 colspan = 1
278 if showprofile:
279 ncolspan = 3
280 colspan = 2
281 self.__nsubplots = 2
282
283 self.createFigure(id = id,
284 wintitle = wintitle,
285 widthplot = self.WIDTH + self.WIDTHPROF,
286 heightplot = self.HEIGHT + self.HEIGHTPROF,
287 show=show)
288
289 nrow, ncol = self.getSubplots()
290
291 counter = 0
292 for y in range(nrow):
293 for x in range(ncol):
294
295 if counter >= self.nplots:
296 break
297
298 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
299
300 if showprofile:
301 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
302
303 counter += 1
304
305 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
306 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
307 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
308 server=None, folder=None, username=None, password=None,
309 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
310 xaxis="frequency", colormap='jet', normFactor=None):
311
312 """
313
314 Input:
315 dataOut :
316 id :
317 wintitle :
318 channelList :
319 showProfile :
320 xmin : None,
321 xmax : None,
322 ymin : None,
323 ymax : None,
324 zmin : None,
325 zmax : None
326 """
327 print("***************PLOTEO******************")
328 print("DATAOUT SHAPE : ",dataOut.data.shape)
329 if dataOut.flagNoData:
330 return dataOut
331
332 if realtime:
333 if not(isRealtime(utcdatatime = dataOut.utctime)):
334 print('Skipping this plot function')
335 return
336
337 if channelList == None:
338 channelIndexList = dataOut.channelIndexList
339 else:
340 channelIndexList = []
341 for channel in channelList:
342 if channel not in dataOut.channelList:
343 raise ValueError("Channel %d is not in dataOut.channelList" %channel)
344 channelIndexList.append(dataOut.channelList.index(channel))
345
346
347 print("channelIndexList",channelIndexList)
348 if normFactor is None:
349 factor = dataOut.normFactor
350 else:
351 factor = normFactor
352 if xaxis == "frequency":
353 x = dataOut.getFreqRange(1)/1000.
354 xlabel = "Frequency (kHz)"
355
356 elif xaxis == "time":
357 x = dataOut.getAcfRange(1)
358 xlabel = "Time (ms)"
359
360 else:
361 x = dataOut.getVelRange(1)
362 xlabel = "Velocity (m/s)"
363
364 ylabel = "Range (km)"
365
366 y = dataOut.getHeiRange()
367 print("factor",factor)
368
369 z = dataOut.data/factor # dividido /factor
370 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
371 zdB = 10*numpy.log10(z)
372
373 avg = numpy.average(z, axis=1)
374 avgdB = 10*numpy.log10(avg)
375
376 noise = dataOut.getNoise()/factor
377 noisedB = 10*numpy.log10(noise)
378
379 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
380 title = wintitle + "Weather Power"
381
382 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
383 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
384
385 if not self.isConfig:
386
387 nplots = len(channelIndexList)
388
389 self.setup(id=id,
390 nplots=nplots,
391 wintitle=wintitle,
392 showprofile=showprofile,
393 show=show)
394
395 if xmin == None: xmin = numpy.nanmin(x)
396 if xmax == None: xmax = numpy.nanmax(x)
397 if ymin == None: ymin = numpy.nanmin(y)
398 if ymax == None: ymax = numpy.nanmax(y)
399 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
400 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
401
402 self.FTP_WEI = ftp_wei
403 self.EXP_CODE = exp_code
404 self.SUB_EXP_CODE = sub_exp_code
405 self.PLOT_POS = plot_pos
406
407 self.isConfig = True
408
409 self.setWinTitle(title)
410
411 for i in range(self.nplots):
412 index = channelIndexList[i]
413 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
414 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[index], noisedB[index], str_datetime)
415 if len(dataOut.beam.codeList) != 0:
416 title = "Ch%d:%4.2fdB,%2.2f,%2.2f:%s" %(dataOut.channelList[index], noisedB[index], dataOut.beam.azimuthList[index], dataOut.beam.zenithList[index], str_datetime)
417
418 axes = self.axesList[i*self.__nsubplots]
419 axes.pcolor(x, y, zdB[index,:,:],
420 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
421 xlabel=xlabel, ylabel=ylabel, title=title, colormap=colormap,
422 ticksize=9, cblabel='')
423
424 if self.__showprofile:
425 axes = self.axesList[i*self.__nsubplots +1]
426 axes.pline(avgdB[index,:], y,
427 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
428 xlabel='dB', ylabel='', title='',
429 ytick_visible=False,
430 grid='x')
431
432 noiseline = numpy.repeat(noisedB[index], len(y))
433 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
434
435 self.draw()
436
437 if figfile == None:
438 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
439 name = str_datetime
440 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
441 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
442 figfile = self.getFilename(name)
443
444 self.save(figpath=figpath,
445 figfile=figfile,
446 save=save,
447 ftp=ftp,
448 wr_period=wr_period,
449 thisDatetime=thisDatetime)
450 return dataOut
451
452 @MPDecorator
233 class CrossSpectraPlot_(Figure):
453 class CrossSpectraPlot_(Figure):
234
454
235 isConfig = None
455 isConfig = None
@@ -256,7 +476,7 class CrossSpectraPlot_(Figure):
256 self.EXP_CODE = None
476 self.EXP_CODE = None
257 self.SUB_EXP_CODE = None
477 self.SUB_EXP_CODE = None
258 self.PLOT_POS = None
478 self.PLOT_POS = None
259
479
260 self.indice=0
480 self.indice=0
261
481
262 def getSubplots(self):
482 def getSubplots(self):
@@ -314,7 +534,7 class CrossSpectraPlot_(Figure):
314 zmax : None
534 zmax : None
315 """
535 """
316
536
317 if dataOut.flagNoData:
537 if dataOut.flagNoData:
318 return dataOut
538 return dataOut
319
539
320 if pairsList == None:
540 if pairsList == None:
@@ -331,7 +551,7 class CrossSpectraPlot_(Figure):
331
551
332 if len(pairsIndexList) > 4:
552 if len(pairsIndexList) > 4:
333 pairsIndexList = pairsIndexList[0:4]
553 pairsIndexList = pairsIndexList[0:4]
334
554
335 if normFactor is None:
555 if normFactor is None:
336 factor = dataOut.normFactor
556 factor = dataOut.normFactor
337 else:
557 else:
@@ -402,7 +622,7 class CrossSpectraPlot_(Figure):
402 self.isConfig = True
622 self.isConfig = True
403
623
404 self.setWinTitle(title)
624 self.setWinTitle(title)
405
625
406
626
407 for i in range(self.nplots):
627 for i in range(self.nplots):
408 pair = dataOut.pairsList[pairsIndexList[i]]
628 pair = dataOut.pairsList[pairsIndexList[i]]
@@ -563,7 +783,7 class RTIPlot_(Figure):
563 #colormap = kwargs.get('colormap', 'jet')
783 #colormap = kwargs.get('colormap', 'jet')
564 if HEIGHT is not None:
784 if HEIGHT is not None:
565 self.HEIGHT = HEIGHT
785 self.HEIGHT = HEIGHT
566
786
567 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
787 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
568 return
788 return
569
789
@@ -745,7 +965,7 class CoherenceMap_(Figure):
745 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
965 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
746
966
747
967
748 if dataOut.flagNoData:
968 if dataOut.flagNoData:
749 return dataOut
969 return dataOut
750
970
751 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
971 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
@@ -935,7 +1155,7 class PowerProfilePlot_(Figure):
935 ftp=False, wr_period=1, server=None,
1155 ftp=False, wr_period=1, server=None,
936 folder=None, username=None, password=None):
1156 folder=None, username=None, password=None):
937
1157
938 if dataOut.flagNoData:
1158 if dataOut.flagNoData:
939 return dataOut
1159 return dataOut
940
1160
941
1161
@@ -1009,7 +1229,7 class PowerProfilePlot_(Figure):
1009 ftp=ftp,
1229 ftp=ftp,
1010 wr_period=wr_period,
1230 wr_period=wr_period,
1011 thisDatetime=thisDatetime)
1231 thisDatetime=thisDatetime)
1012
1232
1013 return dataOut
1233 return dataOut
1014
1234
1015 @MPDecorator
1235 @MPDecorator
@@ -1066,7 +1286,7 class SpectraCutPlot_(Figure):
1066 folder=None, username=None, password=None,
1286 folder=None, username=None, password=None,
1067 xaxis="frequency"):
1287 xaxis="frequency"):
1068
1288
1069 if dataOut.flagNoData:
1289 if dataOut.flagNoData:
1070 return dataOut
1290 return dataOut
1071
1291
1072 if channelList == None:
1292 if channelList == None:
@@ -1248,7 +1468,7 class Noise_(Figure):
1248 server=None, folder=None, username=None, password=None,
1468 server=None, folder=None, username=None, password=None,
1249 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1469 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1250
1470
1251 if dataOut.flagNoData:
1471 if dataOut.flagNoData:
1252 return dataOut
1472 return dataOut
1253
1473
1254 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1474 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
@@ -1444,7 +1664,7 class BeaconPhase_(Figure):
1444 server=None, folder=None, username=None, password=None,
1664 server=None, folder=None, username=None, password=None,
1445 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1665 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1446
1666
1447 if dataOut.flagNoData:
1667 if dataOut.flagNoData:
1448 return dataOut
1668 return dataOut
1449
1669
1450 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1670 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
@@ -1586,4 +1806,4 class BeaconPhase_(Figure):
1586 thisDatetime=thisDatetime,
1806 thisDatetime=thisDatetime,
1587 update_figfile=update_figfile)
1807 update_figfile=update_figfile)
1588
1808
1589 return dataOut No newline at end of file
1809 return dataOut
@@ -13,62 +13,62 from .figure import Figure
13
13
14 @MPDecorator
14 @MPDecorator
15 class Scope_(Figure):
15 class Scope_(Figure):
16
16
17 isConfig = None
17 isConfig = None
18
18
19 def __init__(self):#, **kwargs): #YONG
19 def __init__(self):#, **kwargs): #YONG
20 Figure.__init__(self)#, **kwargs)
20 Figure.__init__(self)#, **kwargs)
21 self.isConfig = False
21 self.isConfig = False
22 self.WIDTH = 300
22 self.WIDTH = 300
23 self.HEIGHT = 200
23 self.HEIGHT = 200
24 self.counter_imagwr = 0
24 self.counter_imagwr = 0
25
25
26 def getSubplots(self):
26 def getSubplots(self):
27
27
28 nrow = self.nplots
28 nrow = self.nplots
29 ncol = 3
29 ncol = 3
30 return nrow, ncol
30 return nrow, ncol
31
31
32 def setup(self, id, nplots, wintitle, show):
32 def setup(self, id, nplots, wintitle, show):
33
33
34 self.nplots = nplots
34 self.nplots = nplots
35
35
36 self.createFigure(id=id,
36 self.createFigure(id=id,
37 wintitle=wintitle,
37 wintitle=wintitle,
38 show=show)
38 show=show)
39
39
40 nrow,ncol = self.getSubplots()
40 nrow,ncol = self.getSubplots()
41 colspan = 3
41 colspan = 3
42 rowspan = 1
42 rowspan = 1
43
43
44 for i in range(nplots):
44 for i in range(nplots):
45 self.addAxes(nrow, ncol, i, 0, colspan, rowspan)
45 self.addAxes(nrow, ncol, i, 0, colspan, rowspan)
46
46
47 def plot_iq(self, x, y, id, channelIndexList, thisDatetime, wintitle, show, xmin, xmax, ymin, ymax):
47 def plot_iq(self, x, y, id, channelIndexList, thisDatetime, wintitle, show, xmin, xmax, ymin, ymax):
48 yreal = y[channelIndexList,:].real
48 yreal = y[channelIndexList,:].real
49 yimag = y[channelIndexList,:].imag
49 yimag = y[channelIndexList,:].imag
50
50
51 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
51 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
52 xlabel = "Range (Km)"
52 xlabel = "Range (Km)"
53 ylabel = "Intensity - IQ"
53 ylabel = "Intensity - IQ"
54
54
55 if not self.isConfig:
55 if not self.isConfig:
56 nplots = len(channelIndexList)
56 nplots = len(channelIndexList)
57
57
58 self.setup(id=id,
58 self.setup(id=id,
59 nplots=nplots,
59 nplots=nplots,
60 wintitle='',
60 wintitle='',
61 show=show)
61 show=show)
62
62
63 if xmin == None: xmin = numpy.nanmin(x)
63 if xmin == None: xmin = numpy.nanmin(x)
64 if xmax == None: xmax = numpy.nanmax(x)
64 if xmax == None: xmax = numpy.nanmax(x)
65 if ymin == None: ymin = min(numpy.nanmin(yreal),numpy.nanmin(yimag))
65 if ymin == None: ymin = min(numpy.nanmin(yreal),numpy.nanmin(yimag))
66 if ymax == None: ymax = max(numpy.nanmax(yreal),numpy.nanmax(yimag))
66 if ymax == None: ymax = max(numpy.nanmax(yreal),numpy.nanmax(yimag))
67
67
68 self.isConfig = True
68 self.isConfig = True
69
69
70 self.setWinTitle(title)
70 self.setWinTitle(title)
71
71
72 for i in range(len(self.axesList)):
72 for i in range(len(self.axesList)):
73 title = "Channel %d" %(i)
73 title = "Channel %d" %(i)
74 axes = self.axesList[i]
74 axes = self.axesList[i]
@@ -78,32 +78,32 class Scope_(Figure):
78 xlabel=xlabel, ylabel=ylabel, title=title)
78 xlabel=xlabel, ylabel=ylabel, title=title)
79
79
80 axes.addpline(x, yimag[i,:], idline=1, color="red", linestyle="solid", lw=2)
80 axes.addpline(x, yimag[i,:], idline=1, color="red", linestyle="solid", lw=2)
81
81
82 def plot_power(self, x, y, id, channelIndexList, thisDatetime, wintitle, show, xmin, xmax, ymin, ymax):
82 def plot_power(self, x, y, id, channelIndexList, thisDatetime, wintitle, show, xmin, xmax, ymin, ymax):
83 y = y[channelIndexList,:] * numpy.conjugate(y[channelIndexList,:])
83 y = y[channelIndexList,:] * numpy.conjugate(y[channelIndexList,:])
84 yreal = y.real
84 yreal = y.real
85
85
86 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
86 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
87 xlabel = "Range (Km)"
87 xlabel = "Range (Km)"
88 ylabel = "Intensity"
88 ylabel = "Intensity"
89
89
90 if not self.isConfig:
90 if not self.isConfig:
91 nplots = len(channelIndexList)
91 nplots = len(channelIndexList)
92
92
93 self.setup(id=id,
93 self.setup(id=id,
94 nplots=nplots,
94 nplots=nplots,
95 wintitle='',
95 wintitle='',
96 show=show)
96 show=show)
97
97
98 if xmin == None: xmin = numpy.nanmin(x)
98 if xmin == None: xmin = numpy.nanmin(x)
99 if xmax == None: xmax = numpy.nanmax(x)
99 if xmax == None: xmax = numpy.nanmax(x)
100 if ymin == None: ymin = numpy.nanmin(yreal)
100 if ymin == None: ymin = numpy.nanmin(yreal)
101 if ymax == None: ymax = numpy.nanmax(yreal)
101 if ymax == None: ymax = numpy.nanmax(yreal)
102
102
103 self.isConfig = True
103 self.isConfig = True
104
104
105 self.setWinTitle(title)
105 self.setWinTitle(title)
106
106
107 for i in range(len(self.axesList)):
107 for i in range(len(self.axesList)):
108 title = "Channel %d" %(i)
108 title = "Channel %d" %(i)
109 axes = self.axesList[i]
109 axes = self.axesList[i]
@@ -112,14 +112,48 class Scope_(Figure):
112 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
112 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
113 xlabel=xlabel, ylabel=ylabel, title=title)
113 xlabel=xlabel, ylabel=ylabel, title=title)
114
114
115
115 def plot_weatherpower(self, x, y, id, channelIndexList, thisDatetime, wintitle, show, xmin, xmax, ymin, ymax):
116 y = y[channelIndexList,:]
117 yreal = y
118
119 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
120 xlabel = "Range (Km)"
121 ylabel = "Intensity"
122
123 if not self.isConfig:
124 nplots = len(channelIndexList)
125
126 self.setup(id=id,
127 nplots=nplots,
128 wintitle='',
129 show=show)
130
131 if xmin == None: xmin = numpy.nanmin(x)
132 if xmax == None: xmax = numpy.nanmax(x)
133 if ymin == None: ymin = numpy.nanmin(yreal)
134 if ymax == None: ymax = numpy.nanmax(yreal)
135
136 self.isConfig = True
137
138 self.setWinTitle(title)
139
140 for i in range(len(self.axesList)):
141 title = "Channel %d" %(i)
142 axes = self.axesList[i]
143 ychannel = yreal[i,:]
144 axes.pline(x, ychannel,
145 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
146 xlabel=xlabel, ylabel=ylabel, title=title)
147
148
149
116 def run(self, dataOut, id, wintitle="", channelList=None,
150 def run(self, dataOut, id, wintitle="", channelList=None,
117 xmin=None, xmax=None, ymin=None, ymax=None, save=False,
151 xmin=None, xmax=None, ymin=None, ymax=None, save=False,
118 figpath='./', figfile=None, show=True, wr_period=1,
152 figpath='./', figfile=None, show=True, wr_period=1,
119 ftp=False, server=None, folder=None, username=None, password=None, type='power', **kwargs):
153 ftp=False, server=None, folder=None, username=None, password=None, type='power', **kwargs):
120
154
121 """
155 """
122
156
123 Input:
157 Input:
124 dataOut :
158 dataOut :
125 id :
159 id :
@@ -130,9 +164,9 class Scope_(Figure):
130 ymin : None,
164 ymin : None,
131 ymax : None,
165 ymax : None,
132 """
166 """
133 if dataOut.flagNoData:
167 if dataOut.flagNoData:
134 return dataOut
168 return dataOut
135
169
136 if channelList == None:
170 if channelList == None:
137 channelIndexList = dataOut.channelIndexList
171 channelIndexList = dataOut.channelIndexList
138 else:
172 else:
@@ -141,20 +175,22 class Scope_(Figure):
141 if channel not in dataOut.channelList:
175 if channel not in dataOut.channelList:
142 raise ValueError("Channel %d is not in dataOut.channelList")
176 raise ValueError("Channel %d is not in dataOut.channelList")
143 channelIndexList.append(dataOut.channelList.index(channel))
177 channelIndexList.append(dataOut.channelList.index(channel))
144
178
145 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
179 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
146
180 ### print("***************** PLOTEO **************************")
181 ### print(dataOut.nProfiles)
182 ### print(dataOut.heightList.shape)
147 if dataOut.flagDataAsBlock:
183 if dataOut.flagDataAsBlock:
148
184
149 for i in range(dataOut.nProfiles):
185 for i in range(dataOut.nProfiles):
150
186
151 wintitle1 = wintitle + " [Profile = %d] " %i
187 wintitle1 = wintitle + " [Profile = %d] " %i
152
188
153 if type == "power":
189 if type == "power":
154 self.plot_power(dataOut.heightList,
190 self.plot_power(dataOut.heightList,
155 dataOut.data[:,i,:],
191 dataOut.data[:,i,:],
156 id,
192 id,
157 channelIndexList,
193 channelIndexList,
158 thisDatetime,
194 thisDatetime,
159 wintitle1,
195 wintitle1,
160 show,
196 show,
@@ -162,12 +198,38 class Scope_(Figure):
162 xmax,
198 xmax,
163 ymin,
199 ymin,
164 ymax)
200 ymax)
165
201
202 if type == "weatherpower":
203 self.plot_weatherpower(dataOut.heightList,
204 dataOut.data[:,i,:],
205 id,
206 channelIndexList,
207 thisDatetime,
208 wintitle1,
209 show,
210 xmin,
211 xmax,
212 ymin,
213 ymax)
214
215 if type == "weathervelocity":
216 self.plot_weatherpower(dataOut.heightList,
217 dataOut.data_velocity[:,i,:],
218 id,
219 channelIndexList,
220 thisDatetime,
221 wintitle1,
222 show,
223 xmin,
224 xmax,
225 ymin,
226 ymax)
227
166 if type == "iq":
228 if type == "iq":
167 self.plot_iq(dataOut.heightList,
229 self.plot_iq(dataOut.heightList,
168 dataOut.data[:,i,:],
230 dataOut.data[:,i,:],
169 id,
231 id,
170 channelIndexList,
232 channelIndexList,
171 thisDatetime,
233 thisDatetime,
172 wintitle1,
234 wintitle1,
173 show,
235 show,
@@ -175,27 +237,27 class Scope_(Figure):
175 xmax,
237 xmax,
176 ymin,
238 ymin,
177 ymax)
239 ymax)
178
240
179 self.draw()
241 self.draw()
180
242
181 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
243 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
182 figfile = self.getFilename(name = str_datetime) + "_" + str(i)
244 figfile = self.getFilename(name = str_datetime) + "_" + str(i)
183
245
184 self.save(figpath=figpath,
246 self.save(figpath=figpath,
185 figfile=figfile,
247 figfile=figfile,
186 save=save,
248 save=save,
187 ftp=ftp,
249 ftp=ftp,
188 wr_period=wr_period,
250 wr_period=wr_period,
189 thisDatetime=thisDatetime)
251 thisDatetime=thisDatetime)
190
252
191 else:
253 else:
192 wintitle += " [Profile = %d] " %dataOut.profileIndex
254 wintitle += " [Profile = %d] " %dataOut.profileIndex
193
255
194 if type == "power":
256 if type == "power":
195 self.plot_power(dataOut.heightList,
257 self.plot_power(dataOut.heightList,
196 dataOut.data,
258 dataOut.data,
197 id,
259 id,
198 channelIndexList,
260 channelIndexList,
199 thisDatetime,
261 thisDatetime,
200 wintitle,
262 wintitle,
201 show,
263 show,
@@ -203,12 +265,12 class Scope_(Figure):
203 xmax,
265 xmax,
204 ymin,
266 ymin,
205 ymax)
267 ymax)
206
268
207 if type == "iq":
269 if type == "iq":
208 self.plot_iq(dataOut.heightList,
270 self.plot_iq(dataOut.heightList,
209 dataOut.data,
271 dataOut.data,
210 id,
272 id,
211 channelIndexList,
273 channelIndexList,
212 thisDatetime,
274 thisDatetime,
213 wintitle,
275 wintitle,
214 show,
276 show,
@@ -216,12 +278,12 class Scope_(Figure):
216 xmax,
278 xmax,
217 ymin,
279 ymin,
218 ymax)
280 ymax)
219
281
220 self.draw()
282 self.draw()
221
283
222 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S") + "_" + str(dataOut.profileIndex)
284 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S") + "_" + str(dataOut.profileIndex)
223 figfile = self.getFilename(name = str_datetime)
285 figfile = self.getFilename(name = str_datetime)
224
286
225 self.save(figpath=figpath,
287 self.save(figpath=figpath,
226 figfile=figfile,
288 figfile=figfile,
227 save=save,
289 save=save,
@@ -229,4 +291,4 class Scope_(Figure):
229 wr_period=wr_period,
291 wr_period=wr_period,
230 thisDatetime=thisDatetime)
292 thisDatetime=thisDatetime)
231
293
232 return dataOut No newline at end of file
294 return dataOut
@@ -23,6 +23,8 MSKYMAP_CODE = 23
23 MPHASE_CODE = 24
23 MPHASE_CODE = 24
24
24
25 MOMENTS_CODE = 25
25 MOMENTS_CODE = 25
26 PARMS_CODE = 26
26 PARMS_CODE = 26
27 SPECFIT_CODE = 27
27 SPECFIT_CODE = 27
28 EWDRIFT_CODE = 28
28 EWDRIFT_CODE = 28
29
30 WPO_CODE = 29 #Weather Intensity - Power
@@ -183,7 +183,7 class ParamReader(JRODataReader,ProcessingUnit):
183 except IOError:
183 except IOError:
184 traceback.print_exc()
184 traceback.print_exc()
185 raise IOError("The file %s can't be opened" %(filename))
185 raise IOError("The file %s can't be opened" %(filename))
186
186
187 #In case has utctime attribute
187 #In case has utctime attribute
188 grp2 = grp1['utctime']
188 grp2 = grp1['utctime']
189 # thisUtcTime = grp2.value[0] - 5*3600 #To convert to local time
189 # thisUtcTime = grp2.value[0] - 5*3600 #To convert to local time
@@ -497,7 +497,7 class ParamWriter(Operation):
497 setType = None
497 setType = None
498
498
499 def __init__(self):
499 def __init__(self):
500
500
501 Operation.__init__(self)
501 Operation.__init__(self)
502 return
502 return
503
503
@@ -530,9 +530,9 class ParamWriter(Operation):
530 dsDict['variable'] = self.dataList[i]
530 dsDict['variable'] = self.dataList[i]
531 #--------------------- Conditionals ------------------------
531 #--------------------- Conditionals ------------------------
532 #There is no data
532 #There is no data
533
533
534 if dataAux is None:
534 if dataAux is None:
535
535
536 return 0
536 return 0
537
537
538 if isinstance(dataAux, (int, float, numpy.integer, numpy.float)):
538 if isinstance(dataAux, (int, float, numpy.integer, numpy.float)):
@@ -704,7 +704,7 class ParamWriter(Operation):
704 return False
704 return False
705
705
706 def setNextFile(self):
706 def setNextFile(self):
707
707
708 ext = self.ext
708 ext = self.ext
709 path = self.path
709 path = self.path
710 setFile = self.setFile
710 setFile = self.setFile
@@ -785,7 +785,7 class ParamWriter(Operation):
785 for j in range(dsInfo['dsNumber']):
785 for j in range(dsInfo['dsNumber']):
786 dsInfo = dsList[i]
786 dsInfo = dsList[i]
787 tableName = dsInfo['dsName']
787 tableName = dsInfo['dsName']
788
788
789
789
790 if dsInfo['nDim'] == 3:
790 if dsInfo['nDim'] == 3:
791 shape = dsInfo['shape'].astype(int)
791 shape = dsInfo['shape'].astype(int)
@@ -869,7 +869,8 class ParamWriter(Operation):
869 dsList = self.dsList
869 dsList = self.dsList
870 data = self.data
870 data = self.data
871 ind = 0
871 ind = 0
872
872 #print("dsList ",dsList)
873 #print("len ",len(dsList))
873 while ind < len(dsList):
874 while ind < len(dsList):
874 dsInfo = dsList[ind]
875 dsInfo = dsList[ind]
875 dataAux = getattr(self.dataOut, dsInfo['variable'])
876 dataAux = getattr(self.dataOut, dsInfo['variable'])
@@ -902,22 +903,41 class ParamWriter(Operation):
902 dsList = self.dsList
903 dsList = self.dsList
903
904
904 for i in range(len(self.ds)):
905 for i in range(len(self.ds)):
906 print("#############", i , "#######################")
905 dsInfo = dsList[i]
907 dsInfo = dsList[i]
906 nDim = dsInfo['nDim']
908 nDim = dsInfo['nDim']
907 mode = dsInfo['mode']
909 mode = dsInfo['mode']
908
910 print("dsInfo",dsInfo)
911 print("nDim",nDim)
912 print("mode",mode)
909 # First time
913 # First time
910 if self.firsttime:
914 if self.firsttime:
915 print("ENTRE FIRSTIME")
911 if type(self.data[i]) == numpy.ndarray:
916 if type(self.data[i]) == numpy.ndarray:
912
917
913 if nDim == 3:
918 if nDim == 3:
919 print("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
920 print("ndim","dentro del primer if 3")
914 self.data[i] = self.data[i].reshape((self.data[i].shape[0],self.data[i].shape[1],1))
921 self.data[i] = self.data[i].reshape((self.data[i].shape[0],self.data[i].shape[1],1))
922 print(self.data[i].shape)
923 print(type(self.data[i]))
915 self.ds[i].resize(self.data[i].shape)
924 self.ds[i].resize(self.data[i].shape)
925 print(self.ds[i].shape)
926 print(type(self.ds[i]))
916 if mode == 2:
927 if mode == 2:
917 self.ds[i].resize(self.data[i].shape)
928 self.ds[i].resize(self.data[i].shape)
918 self.ds[i][:] = self.data[i]
929 try:
919 else:
930 print("PTM ODIO ESTO")
931 print(self.ds[i][:].shape)
932 self.ds[i][:] = self.data[i]
933 print("*****___________********______******")
920
934
935 except:
936 print("q habra pasaado")
937 return
938 print("LLEGUE Y CUMPLI EL IF")
939 else:
940 print("ELSE -----------------------")
921 # From second time
941 # From second time
922 # Meteors!
942 # Meteors!
923 if mode == 2:
943 if mode == 2:
@@ -944,7 +964,8 class ParamWriter(Operation):
944
964
945 self.firsttime = False
965 self.firsttime = False
946 self.blockIndex += 1
966 self.blockIndex += 1
947
967 print("HOLA AMIGOS COMO ESTAN LLEGUE")
968 print("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
948 #Close to save changes
969 #Close to save changes
949 self.fp.flush()
970 self.fp.flush()
950 self.fp.close()
971 self.fp.close()
@@ -954,7 +975,7 class ParamWriter(Operation):
954
975
955 self.dataOut = dataOut
976 self.dataOut = dataOut
956 if not(self.isConfig):
977 if not(self.isConfig):
957 self.setup(dataOut, path=path, blocksPerFile=blocksPerFile,
978 self.setup(dataOut, path=path, blocksPerFile=blocksPerFile,
958 metadataList=metadataList, dataList=dataList, mode=mode,
979 metadataList=metadataList, dataList=dataList, mode=mode,
959 setType=setType)
980 setType=setType)
960
981
@@ -963,7 +984,7 class ParamWriter(Operation):
963
984
964 self.putData()
985 self.putData()
965 return
986 return
966
987
967
988
968 @MPDecorator
989 @MPDecorator
969 class ParameterReader(Reader, ProcessingUnit):
990 class ParameterReader(Reader, ProcessingUnit):
@@ -992,43 +1013,43 class ParameterReader(Reader, ProcessingUnit):
992
1013
993 self.set_kwargs(**kwargs)
1014 self.set_kwargs(**kwargs)
994 if not self.ext.startswith('.'):
1015 if not self.ext.startswith('.'):
995 self.ext = '.{}'.format(self.ext)
1016 self.ext = '.{}'.format(self.ext)
996
1017
997 if self.online:
1018 if self.online:
998 log.log("Searching files in online mode...", self.name)
1019 log.log("Searching files in online mode...", self.name)
999
1020
1000 for nTries in range(self.nTries):
1021 for nTries in range(self.nTries):
1001 fullpath = self.searchFilesOnLine(self.path, self.startDate,
1022 fullpath = self.searchFilesOnLine(self.path, self.startDate,
1002 self.endDate, self.expLabel, self.ext, self.walk,
1023 self.endDate, self.expLabel, self.ext, self.walk,
1003 self.filefmt, self.folderfmt)
1024 self.filefmt, self.folderfmt)
1004
1025
1005 try:
1026 try:
1006 fullpath = next(fullpath)
1027 fullpath = next(fullpath)
1007 except:
1028 except:
1008 fullpath = None
1029 fullpath = None
1009
1030
1010 if fullpath:
1031 if fullpath:
1011 break
1032 break
1012
1033
1013 log.warning(
1034 log.warning(
1014 'Waiting {} sec for a valid file in {}: try {} ...'.format(
1035 'Waiting {} sec for a valid file in {}: try {} ...'.format(
1015 self.delay, self.path, nTries + 1),
1036 self.delay, self.path, nTries + 1),
1016 self.name)
1037 self.name)
1017 time.sleep(self.delay)
1038 time.sleep(self.delay)
1018
1039
1019 if not(fullpath):
1040 if not(fullpath):
1020 raise schainpy.admin.SchainError(
1041 raise schainpy.admin.SchainError(
1021 'There isn\'t any valid file in {}'.format(self.path))
1042 'There isn\'t any valid file in {}'.format(self.path))
1022
1043
1023 pathname, filename = os.path.split(fullpath)
1044 pathname, filename = os.path.split(fullpath)
1024 self.year = int(filename[1:5])
1045 self.year = int(filename[1:5])
1025 self.doy = int(filename[5:8])
1046 self.doy = int(filename[5:8])
1026 self.set = int(filename[8:11]) - 1
1047 self.set = int(filename[8:11]) - 1
1027 else:
1048 else:
1028 log.log("Searching files in {}".format(self.path), self.name)
1049 log.log("Searching files in {}".format(self.path), self.name)
1029 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
1050 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
1030 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
1051 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
1031
1052
1032 self.setNextFile()
1053 self.setNextFile()
1033
1054
1034 return
1055 return
@@ -1036,11 +1057,11 class ParameterReader(Reader, ProcessingUnit):
1036 def readFirstHeader(self):
1057 def readFirstHeader(self):
1037 '''Read metadata and data'''
1058 '''Read metadata and data'''
1038
1059
1039 self.__readMetadata()
1060 self.__readMetadata()
1040 self.__readData()
1061 self.__readData()
1041 self.__setBlockList()
1062 self.__setBlockList()
1042 self.blockIndex = 0
1063 self.blockIndex = 0
1043
1064
1044 return
1065 return
1045
1066
1046 def __setBlockList(self):
1067 def __setBlockList(self):
@@ -1099,7 +1120,7 class ParameterReader(Reader, ProcessingUnit):
1099 else:
1120 else:
1100 data = gp[name].value
1121 data = gp[name].value
1101 listMetaname.append(name)
1122 listMetaname.append(name)
1102 listMetadata.append(data)
1123 listMetadata.append(data)
1103 elif self.metadata:
1124 elif self.metadata:
1104 metadata = json.loads(self.metadata)
1125 metadata = json.loads(self.metadata)
1105 listShapes = {}
1126 listShapes = {}
@@ -1115,7 +1136,7 class ParameterReader(Reader, ProcessingUnit):
1115
1136
1116 self.listShapes = listShapes
1137 self.listShapes = listShapes
1117 self.listMetaname = listMetaname
1138 self.listMetaname = listMetaname
1118 self.listMeta = listMetadata
1139 self.listMeta = listMetadata
1119
1140
1120 return
1141 return
1121
1142
@@ -1123,7 +1144,7 class ParameterReader(Reader, ProcessingUnit):
1123
1144
1124 listdataname = []
1145 listdataname = []
1125 listdata = []
1146 listdata = []
1126
1147
1127 if 'Data' in self.fp:
1148 if 'Data' in self.fp:
1128 grp = self.fp['Data']
1149 grp = self.fp['Data']
1129 for item in list(grp.items()):
1150 for item in list(grp.items()):
@@ -1137,7 +1158,7 class ParameterReader(Reader, ProcessingUnit):
1137 for i in range(dim):
1158 for i in range(dim):
1138 array.append(grp[name]['table{:02d}'.format(i)].value)
1159 array.append(grp[name]['table{:02d}'.format(i)].value)
1139 array = numpy.array(array)
1160 array = numpy.array(array)
1140
1161
1141 listdata.append(array)
1162 listdata.append(array)
1142 elif self.metadata:
1163 elif self.metadata:
1143 metadata = json.loads(self.metadata)
1164 metadata = json.loads(self.metadata)
@@ -1160,7 +1181,7 class ParameterReader(Reader, ProcessingUnit):
1160 self.listDataname = listdataname
1181 self.listDataname = listdataname
1161 self.listData = listdata
1182 self.listData = listdata
1162 return
1183 return
1163
1184
1164 def getData(self):
1185 def getData(self):
1165
1186
1166 for i in range(len(self.listMeta)):
1187 for i in range(len(self.listMeta)):
@@ -1230,7 +1251,7 class ParameterWriter(Operation):
1230 lastTime = None
1251 lastTime = None
1231
1252
1232 def __init__(self):
1253 def __init__(self):
1233
1254
1234 Operation.__init__(self)
1255 Operation.__init__(self)
1235 return
1256 return
1236
1257
@@ -1257,7 +1278,7 class ParameterWriter(Operation):
1257 dsDict['nDim'] = len(dataAux.shape)
1278 dsDict['nDim'] = len(dataAux.shape)
1258 dsDict['shape'] = dataAux.shape
1279 dsDict['shape'] = dataAux.shape
1259 dsDict['dsNumber'] = dataAux.shape[0]
1280 dsDict['dsNumber'] = dataAux.shape[0]
1260
1281
1261 dsList.append(dsDict)
1282 dsList.append(dsDict)
1262 tableList.append((self.dataList[i], dsDict['nDim']))
1283 tableList.append((self.dataList[i], dsDict['nDim']))
1263
1284
@@ -1274,7 +1295,7 class ParameterWriter(Operation):
1274 self.lastTime = currentTime
1295 self.lastTime = currentTime
1275 self.currentDay = dataDay
1296 self.currentDay = dataDay
1276 return False
1297 return False
1277
1298
1278 timeDiff = currentTime - self.lastTime
1299 timeDiff = currentTime - self.lastTime
1279
1300
1280 #Si el dia es diferente o si la diferencia entre un dato y otro supera la hora
1301 #Si el dia es diferente o si la diferencia entre un dato y otro supera la hora
@@ -1292,7 +1313,7 class ParameterWriter(Operation):
1292
1313
1293 self.dataOut = dataOut
1314 self.dataOut = dataOut
1294 if not(self.isConfig):
1315 if not(self.isConfig):
1295 self.setup(path=path, blocksPerFile=blocksPerFile,
1316 self.setup(path=path, blocksPerFile=blocksPerFile,
1296 metadataList=metadataList, dataList=dataList,
1317 metadataList=metadataList, dataList=dataList,
1297 setType=setType)
1318 setType=setType)
1298
1319
@@ -1301,9 +1322,9 class ParameterWriter(Operation):
1301
1322
1302 self.putData()
1323 self.putData()
1303 return
1324 return
1304
1325
1305 def setNextFile(self):
1326 def setNextFile(self):
1306
1327
1307 ext = self.ext
1328 ext = self.ext
1308 path = self.path
1329 path = self.path
1309 setFile = self.setFile
1330 setFile = self.setFile
@@ -1369,17 +1390,17 class ParameterWriter(Operation):
1369 return
1390 return
1370
1391
1371 def writeData(self, fp):
1392 def writeData(self, fp):
1372
1393
1373 grp = fp.create_group("Data")
1394 grp = fp.create_group("Data")
1374 dtsets = []
1395 dtsets = []
1375 data = []
1396 data = []
1376
1397
1377 for dsInfo in self.dsList:
1398 for dsInfo in self.dsList:
1378 if dsInfo['nDim'] == 0:
1399 if dsInfo['nDim'] == 0:
1379 ds = grp.create_dataset(
1400 ds = grp.create_dataset(
1380 dsInfo['variable'],
1401 dsInfo['variable'],
1381 (self.blocksPerFile, ),
1402 (self.blocksPerFile, ),
1382 chunks=True,
1403 chunks=True,
1383 dtype=numpy.float64)
1404 dtype=numpy.float64)
1384 dtsets.append(ds)
1405 dtsets.append(ds)
1385 data.append((dsInfo['variable'], -1))
1406 data.append((dsInfo['variable'], -1))
@@ -1387,7 +1408,7 class ParameterWriter(Operation):
1387 sgrp = grp.create_group(dsInfo['variable'])
1408 sgrp = grp.create_group(dsInfo['variable'])
1388 for i in range(dsInfo['dsNumber']):
1409 for i in range(dsInfo['dsNumber']):
1389 ds = sgrp.create_dataset(
1410 ds = sgrp.create_dataset(
1390 'table{:02d}'.format(i),
1411 'table{:02d}'.format(i),
1391 (self.blocksPerFile, ) + dsInfo['shape'][1:],
1412 (self.blocksPerFile, ) + dsInfo['shape'][1:],
1392 chunks=True)
1413 chunks=True)
1393 dtsets.append(ds)
1414 dtsets.append(ds)
@@ -1395,7 +1416,7 class ParameterWriter(Operation):
1395 fp.flush()
1416 fp.flush()
1396
1417
1397 log.log('Creating file: {}'.format(fp.filename), self.name)
1418 log.log('Creating file: {}'.format(fp.filename), self.name)
1398
1419
1399 self.ds = dtsets
1420 self.ds = dtsets
1400 self.data = data
1421 self.data = data
1401 self.firsttime = True
1422 self.firsttime = True
@@ -1409,10 +1430,12 class ParameterWriter(Operation):
1409 self.setNextFile()
1430 self.setNextFile()
1410
1431
1411 for i, ds in enumerate(self.ds):
1432 for i, ds in enumerate(self.ds):
1433 print(i,ds)
1412 attr, ch = self.data[i]
1434 attr, ch = self.data[i]
1413 if ch == -1:
1435 if ch == -1:
1414 ds[self.blockIndex] = getattr(self.dataOut, attr)
1436 ds[self.blockIndex] = getattr(self.dataOut, attr)
1415 else:
1437 else:
1438 print(ch, getattr(self.dataOut, attr).shape)
1416 ds[self.blockIndex] = getattr(self.dataOut, attr)[ch]
1439 ds[self.blockIndex] = getattr(self.dataOut, attr)[ch]
1417
1440
1418 self.fp.flush()
1441 self.fp.flush()
This diff has been collapsed as it changes many lines, (2157 lines changed) Show them Hide them
@@ -8,12 +8,12 import copy
8 import sys
8 import sys
9 import importlib
9 import importlib
10 import itertools
10 import itertools
11 from multiprocessing import Pool, TimeoutError
11 from multiprocessing import Pool, TimeoutError
12 from multiprocessing.pool import ThreadPool
12 from multiprocessing.pool import ThreadPool
13 import time
13 import time
14
14
15 from scipy.optimize import fmin_l_bfgs_b #optimize with bounds on state papameters
15 from scipy.optimize import fmin_l_bfgs_b #optimize with bounds on state papameters
16 from .jroproc_base import ProcessingUnit, Operation, MPDecorator
16 from .jroproc_base import ProcessingUnit, Operation, MPDecorator
17 from schainpy.model.data.jrodata import Parameters, hildebrand_sekhon
17 from schainpy.model.data.jrodata import Parameters, hildebrand_sekhon
18 from scipy import asarray as ar,exp
18 from scipy import asarray as ar,exp
19 from scipy.optimize import curve_fit
19 from scipy.optimize import curve_fit
@@ -48,13 +48,13 def _unpickle_method(func_name, obj, cls):
48
48
49 @MPDecorator
49 @MPDecorator
50 class ParametersProc(ProcessingUnit):
50 class ParametersProc(ProcessingUnit):
51
51
52 METHODS = {}
52 METHODS = {}
53 nSeconds = None
53 nSeconds = None
54
54
55 def __init__(self):
55 def __init__(self):
56 ProcessingUnit.__init__(self)
56 ProcessingUnit.__init__(self)
57
57
58 # self.objectDict = {}
58 # self.objectDict = {}
59 self.buffer = None
59 self.buffer = None
60 self.firstdatatime = None
60 self.firstdatatime = None
@@ -63,14 +63,14 class ParametersProc(ProcessingUnit):
63 self.setupReq = False #Agregar a todas las unidades de proc
63 self.setupReq = False #Agregar a todas las unidades de proc
64
64
65 def __updateObjFromInput(self):
65 def __updateObjFromInput(self):
66
66
67 self.dataOut.inputUnit = self.dataIn.type
67 self.dataOut.inputUnit = self.dataIn.type
68
68
69 self.dataOut.timeZone = self.dataIn.timeZone
69 self.dataOut.timeZone = self.dataIn.timeZone
70 self.dataOut.dstFlag = self.dataIn.dstFlag
70 self.dataOut.dstFlag = self.dataIn.dstFlag
71 self.dataOut.errorCount = self.dataIn.errorCount
71 self.dataOut.errorCount = self.dataIn.errorCount
72 self.dataOut.useLocalTime = self.dataIn.useLocalTime
72 self.dataOut.useLocalTime = self.dataIn.useLocalTime
73
73
74 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
74 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
75 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
75 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
76 self.dataOut.channelList = self.dataIn.channelList
76 self.dataOut.channelList = self.dataIn.channelList
@@ -92,27 +92,32 class ParametersProc(ProcessingUnit):
92 self.dataOut.ippSeconds = self.dataIn.ippSeconds
92 self.dataOut.ippSeconds = self.dataIn.ippSeconds
93 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
93 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
94 self.dataOut.timeInterval1 = self.dataIn.timeInterval
94 self.dataOut.timeInterval1 = self.dataIn.timeInterval
95 self.dataOut.heightList = self.dataIn.getHeiRange()
95 self.dataOut.heightList = self.dataIn.getHeiRange()
96 self.dataOut.frequency = self.dataIn.frequency
96 self.dataOut.frequency = self.dataIn.frequency
97 # self.dataOut.noise = self.dataIn.noise
97 # self.dataOut.noise = self.dataIn.noise
98
99 def run(self):
100
101
102
98
99 def run(self):
103 #---------------------- Voltage Data ---------------------------
100 #---------------------- Voltage Data ---------------------------
104
105 if self.dataIn.type == "Voltage":
101 if self.dataIn.type == "Voltage":
106
102 print(" *************INSIDE PARAMETER********")
107 self.__updateObjFromInput()
103 self.__updateObjFromInput()
108 self.dataOut.data_pre = self.dataIn.data.copy()
104 self.dataOut.data_pre = self.dataIn.data.copy()
109 self.dataOut.flagNoData = False
105 self.dataOut.flagNoData = False
110 self.dataOut.utctimeInit = self.dataIn.utctime
106 self.dataOut.utctimeInit = self.dataIn.utctime
111 self.dataOut.paramInterval = self.dataIn.nProfiles*self.dataIn.nCohInt*self.dataIn.ippSeconds
107 self.dataOut.paramInterval = self.dataIn.nProfiles*self.dataIn.nCohInt*self.dataIn.ippSeconds
108
109 if self.dataIn.identifierWR== True:
110 print("**********************************************")
111 self.dataOut.data_intensity = self.dataIn.data #valor para intensidad
112 self.dataOut.data_velocity = self.dataIn.data_velocity #valor para velocidad
113 self.dataOut.identifierWR = self.dataIn.identifierWR
114 self.dataOut.PRFbyAngle = self.dataIn.PRFbyAngle
115 print(self.dataOut.data_intensity.shape)
116 print(self.dataOut.utctimeInit)
117 print(self.dataOut.nCohInt )
118 print(self.dataOut.PRFbyAngle)
112 return
119 return
113
114 #---------------------- Spectra Data ---------------------------
120 #---------------------- Spectra Data ---------------------------
115
116 if self.dataIn.type == "Spectra":
121 if self.dataIn.type == "Spectra":
117
122
118 self.dataOut.data_pre = (self.dataIn.data_spc, self.dataIn.data_cspc)
123 self.dataOut.data_pre = (self.dataIn.data_spc, self.dataIn.data_cspc)
@@ -126,243 +131,256 class ParametersProc(ProcessingUnit):
126 self.dataOut.spc_noise = self.dataIn.getNoise()
131 self.dataOut.spc_noise = self.dataIn.getNoise()
127 self.dataOut.spc_range = (self.dataIn.getFreqRange(1) , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
132 self.dataOut.spc_range = (self.dataIn.getFreqRange(1) , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
128 # self.dataOut.normFactor = self.dataIn.normFactor
133 # self.dataOut.normFactor = self.dataIn.normFactor
129 self.dataOut.pairsList = self.dataIn.pairsList
134 self.dataOut.pairsList = self.dataIn.pairsList
130 self.dataOut.groupList = self.dataIn.pairsList
135 self.dataOut.groupList = self.dataIn.pairsList
131 self.dataOut.flagNoData = False
136 self.dataOut.flagNoData = False
132
137
138 if self.dataIn.flagWR== True:
139 print("##############################################")
140 self.dataOut.nIncohInt = self.dataIn.nIncohInt
141 self.dataOut.utctimeInit = self.dataIn.utctime
142 self.dataOut.data_intensity = self.dataIn.data #valor para intensidad
143 self.dataOut.data_velocity = self.dataIn.data_velocity #valor para velocidad
144 self.dataOut.flagWR = self.dataIn.flagWR
145 self.dataOut.PRFbyAngle = self.dataIn.PRFbyAngle
146 print(self.dataOut.data_intensity.shape)
147 print(self.dataOut.utctimeInit)
148 print(self.dataOut.nIncohInt )
149 print(self.dataOut.PRFbyAngle)
150
133 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
151 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
134 self.dataOut.ChanDist = self.dataIn.ChanDist
152 self.dataOut.ChanDist = self.dataIn.ChanDist
135 else: self.dataOut.ChanDist = None
153 else: self.dataOut.ChanDist = None
136
154
137 #if hasattr(self.dataIn, 'VelRange'): #Velocities range
155 #if hasattr(self.dataIn, 'VelRange'): #Velocities range
138 # self.dataOut.VelRange = self.dataIn.VelRange
156 # self.dataOut.VelRange = self.dataIn.VelRange
139 #else: self.dataOut.VelRange = None
157 #else: self.dataOut.VelRange = None
140
158
141 if hasattr(self.dataIn, 'RadarConst'): #Radar Constant
159 if hasattr(self.dataIn, 'RadarConst'): #Radar Constant
142 self.dataOut.RadarConst = self.dataIn.RadarConst
160 self.dataOut.RadarConst = self.dataIn.RadarConst
143
161
144 if hasattr(self.dataIn, 'NPW'): #NPW
162 if hasattr(self.dataIn, 'NPW'): #NPW
145 self.dataOut.NPW = self.dataIn.NPW
163 self.dataOut.NPW = self.dataIn.NPW
146
164
147 if hasattr(self.dataIn, 'COFA'): #COFA
165 if hasattr(self.dataIn, 'COFA'): #COFA
148 self.dataOut.COFA = self.dataIn.COFA
166 self.dataOut.COFA = self.dataIn.COFA
149
167
150
168
151
169
152 #---------------------- Correlation Data ---------------------------
170 #---------------------- Correlation Data ---------------------------
153
171
154 if self.dataIn.type == "Correlation":
172 if self.dataIn.type == "Correlation":
155 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
173 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
156
174
157 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
175 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
158 self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
176 self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
159 self.dataOut.groupList = (acf_pairs, ccf_pairs)
177 self.dataOut.groupList = (acf_pairs, ccf_pairs)
160
178
161 self.dataOut.abscissaList = self.dataIn.lagRange
179 self.dataOut.abscissaList = self.dataIn.lagRange
162 self.dataOut.noise = self.dataIn.noise
180 self.dataOut.noise = self.dataIn.noise
163 self.dataOut.data_SNR = self.dataIn.SNR
181 self.dataOut.data_SNR = self.dataIn.SNR
164 self.dataOut.flagNoData = False
182 self.dataOut.flagNoData = False
165 self.dataOut.nAvg = self.dataIn.nAvg
183 self.dataOut.nAvg = self.dataIn.nAvg
166
184
167 #---------------------- Parameters Data ---------------------------
185 #---------------------- Parameters Data ---------------------------
168
186
169 if self.dataIn.type == "Parameters":
187 if self.dataIn.type == "Parameters":
170 self.dataOut.copy(self.dataIn)
188 self.dataOut.copy(self.dataIn)
171 self.dataOut.flagNoData = False
189 self.dataOut.flagNoData = False
172
190
173 return True
191 return True
174
192
175 self.__updateObjFromInput()
193 self.__updateObjFromInput()
176 self.dataOut.utctimeInit = self.dataIn.utctime
194 self.dataOut.utctimeInit = self.dataIn.utctime
177 self.dataOut.paramInterval = self.dataIn.timeInterval
195 self.dataOut.paramInterval = self.dataIn.timeInterval
178
196
179 return
197 return
180
198
181
199
182 def target(tups):
200 def target(tups):
183
201
184 obj, args = tups
202 obj, args = tups
185
203
186 return obj.FitGau(args)
204 return obj.FitGau(args)
187
205
188
206
189 class SpectralFilters(Operation):
207 class SpectralFilters(Operation):
190
208
191 '''This class allows the Rainfall / Wind Selection for CLAIRE RADAR
209 '''This class allows the Rainfall / Wind Selection for CLAIRE RADAR
192
210
193 LimitR : It is the limit in m/s of Rainfall
211 LimitR : It is the limit in m/s of Rainfall
194 LimitW : It is the limit in m/s for Winds
212 LimitW : It is the limit in m/s for Winds
195
213
196 Input:
214 Input:
197
215
198 self.dataOut.data_pre : SPC and CSPC
216 self.dataOut.data_pre : SPC and CSPC
199 self.dataOut.spc_range : To select wind and rainfall velocities
217 self.dataOut.spc_range : To select wind and rainfall velocities
200
218
201 Affected:
219 Affected:
202
220
203 self.dataOut.data_pre : It is used for the new SPC and CSPC ranges of wind
221 self.dataOut.data_pre : It is used for the new SPC and CSPC ranges of wind
204 self.dataOut.spcparam_range : Used in SpcParamPlot
222 self.dataOut.spcparam_range : Used in SpcParamPlot
205 self.dataOut.SPCparam : Used in PrecipitationProc
223 self.dataOut.SPCparam : Used in PrecipitationProc
206
224
207
225
208 '''
226 '''
209
227
210 def __init__(self):
228 def __init__(self):
211 Operation.__init__(self)
229 Operation.__init__(self)
212 self.i=0
230 self.i=0
213
231
214 def run(self, dataOut, PositiveLimit=1.5, NegativeLimit=2.5):
232 def run(self, dataOut, PositiveLimit=1.5, NegativeLimit=2.5):
215
233
216
234
217 #Limite de vientos
235 #Limite de vientos
218 LimitR = PositiveLimit
236 LimitR = PositiveLimit
219 LimitN = NegativeLimit
237 LimitN = NegativeLimit
220
238
221 self.spc = dataOut.data_pre[0].copy()
239 self.spc = dataOut.data_pre[0].copy()
222 self.cspc = dataOut.data_pre[1].copy()
240 self.cspc = dataOut.data_pre[1].copy()
223
241
224 self.Num_Hei = self.spc.shape[2]
242 self.Num_Hei = self.spc.shape[2]
225 self.Num_Bin = self.spc.shape[1]
243 self.Num_Bin = self.spc.shape[1]
226 self.Num_Chn = self.spc.shape[0]
244 self.Num_Chn = self.spc.shape[0]
227
245
228 VelRange = dataOut.spc_range[2]
246 VelRange = dataOut.spc_range[2]
229 TimeRange = dataOut.spc_range[1]
247 TimeRange = dataOut.spc_range[1]
230 FrecRange = dataOut.spc_range[0]
248 FrecRange = dataOut.spc_range[0]
231
249
232 Vmax= 2*numpy.max(dataOut.spc_range[2])
250 Vmax= 2*numpy.max(dataOut.spc_range[2])
233 Tmax= 2*numpy.max(dataOut.spc_range[1])
251 Tmax= 2*numpy.max(dataOut.spc_range[1])
234 Fmax= 2*numpy.max(dataOut.spc_range[0])
252 Fmax= 2*numpy.max(dataOut.spc_range[0])
235
253
236 Breaker1R=VelRange[numpy.abs(VelRange-(-LimitN)).argmin()]
254 Breaker1R=VelRange[numpy.abs(VelRange-(-LimitN)).argmin()]
237 Breaker1R=numpy.where(VelRange == Breaker1R)
255 Breaker1R=numpy.where(VelRange == Breaker1R)
238
256
239 Delta = self.Num_Bin/2 - Breaker1R[0]
257 Delta = self.Num_Bin/2 - Breaker1R[0]
240
258
241
259
242 '''Reacomodando SPCrange'''
260 '''Reacomodando SPCrange'''
243
261
244 VelRange=numpy.roll(VelRange,-(int(self.Num_Bin/2)) ,axis=0)
262 VelRange=numpy.roll(VelRange,-(int(self.Num_Bin/2)) ,axis=0)
245
263
246 VelRange[-(int(self.Num_Bin/2)):]+= Vmax
264 VelRange[-(int(self.Num_Bin/2)):]+= Vmax
247
265
248 FrecRange=numpy.roll(FrecRange,-(int(self.Num_Bin/2)),axis=0)
266 FrecRange=numpy.roll(FrecRange,-(int(self.Num_Bin/2)),axis=0)
249
267
250 FrecRange[-(int(self.Num_Bin/2)):]+= Fmax
268 FrecRange[-(int(self.Num_Bin/2)):]+= Fmax
251
269
252 TimeRange=numpy.roll(TimeRange,-(int(self.Num_Bin/2)),axis=0)
270 TimeRange=numpy.roll(TimeRange,-(int(self.Num_Bin/2)),axis=0)
253
271
254 TimeRange[-(int(self.Num_Bin/2)):]+= Tmax
272 TimeRange[-(int(self.Num_Bin/2)):]+= Tmax
255
273
256 ''' ------------------ '''
274 ''' ------------------ '''
257
275
258 Breaker2R=VelRange[numpy.abs(VelRange-(LimitR)).argmin()]
276 Breaker2R=VelRange[numpy.abs(VelRange-(LimitR)).argmin()]
259 Breaker2R=numpy.where(VelRange == Breaker2R)
277 Breaker2R=numpy.where(VelRange == Breaker2R)
260
278
261
279
262 SPCroll = numpy.roll(self.spc,-(int(self.Num_Bin/2)) ,axis=1)
280 SPCroll = numpy.roll(self.spc,-(int(self.Num_Bin/2)) ,axis=1)
263
281
264 SPCcut = SPCroll.copy()
282 SPCcut = SPCroll.copy()
265 for i in range(self.Num_Chn):
283 for i in range(self.Num_Chn):
266
284
267 SPCcut[i,0:int(Breaker2R[0]),:] = dataOut.noise[i]
285 SPCcut[i,0:int(Breaker2R[0]),:] = dataOut.noise[i]
268 SPCcut[i,-int(Delta):,:] = dataOut.noise[i]
286 SPCcut[i,-int(Delta):,:] = dataOut.noise[i]
269
287
270 SPCcut[i]=SPCcut[i]- dataOut.noise[i]
288 SPCcut[i]=SPCcut[i]- dataOut.noise[i]
271 SPCcut[ numpy.where( SPCcut<0 ) ] = 1e-20
289 SPCcut[ numpy.where( SPCcut<0 ) ] = 1e-20
272
290
273 SPCroll[i]=SPCroll[i]-dataOut.noise[i]
291 SPCroll[i]=SPCroll[i]-dataOut.noise[i]
274 SPCroll[ numpy.where( SPCroll<0 ) ] = 1e-20
292 SPCroll[ numpy.where( SPCroll<0 ) ] = 1e-20
275
293
276 SPC_ch1 = SPCroll
294 SPC_ch1 = SPCroll
277
295
278 SPC_ch2 = SPCcut
296 SPC_ch2 = SPCcut
279
297
280 SPCparam = (SPC_ch1, SPC_ch2, self.spc)
298 SPCparam = (SPC_ch1, SPC_ch2, self.spc)
281 dataOut.SPCparam = numpy.asarray(SPCparam)
299 dataOut.SPCparam = numpy.asarray(SPCparam)
282
300
283
301
284 dataOut.spcparam_range=numpy.zeros([self.Num_Chn,self.Num_Bin+1])
302 dataOut.spcparam_range=numpy.zeros([self.Num_Chn,self.Num_Bin+1])
285
303
286 dataOut.spcparam_range[2]=VelRange
304 dataOut.spcparam_range[2]=VelRange
287 dataOut.spcparam_range[1]=TimeRange
305 dataOut.spcparam_range[1]=TimeRange
288 dataOut.spcparam_range[0]=FrecRange
306 dataOut.spcparam_range[0]=FrecRange
289 return dataOut
307 return dataOut
290
308
291 class GaussianFit(Operation):
309 class GaussianFit(Operation):
292
310
293 '''
311 '''
294 Function that fit of one and two generalized gaussians (gg) based
312 Function that fit of one and two generalized gaussians (gg) based
295 on the PSD shape across an "power band" identified from a cumsum of
313 on the PSD shape across an "power band" identified from a cumsum of
296 the measured spectrum - noise.
314 the measured spectrum - noise.
297
315
298 Input:
316 Input:
299 self.dataOut.data_pre : SelfSpectra
317 self.dataOut.data_pre : SelfSpectra
300
318
301 Output:
319 Output:
302 self.dataOut.SPCparam : SPC_ch1, SPC_ch2
320 self.dataOut.SPCparam : SPC_ch1, SPC_ch2
303
321
304 '''
322 '''
305 def __init__(self):
323 def __init__(self):
306 Operation.__init__(self)
324 Operation.__init__(self)
307 self.i=0
325 self.i=0
308
326
309
327
310 def run(self, dataOut, num_intg=7, pnoise=1., SNRlimit=-9): #num_intg: Incoherent integrations, pnoise: Noise, vel_arr: range of velocities, similar to the ftt points
328 def run(self, dataOut, num_intg=7, pnoise=1., SNRlimit=-9): #num_intg: Incoherent integrations, pnoise: Noise, vel_arr: range of velocities, similar to the ftt points
311 """This routine will find a couple of generalized Gaussians to a power spectrum
329 """This routine will find a couple of generalized Gaussians to a power spectrum
312 input: spc
330 input: spc
313 output:
331 output:
314 Amplitude0,shift0,width0,p0,Amplitude1,shift1,width1,p1,noise
332 Amplitude0,shift0,width0,p0,Amplitude1,shift1,width1,p1,noise
315 """
333 """
316
334
317 self.spc = dataOut.data_pre[0].copy()
335 self.spc = dataOut.data_pre[0].copy()
318 self.Num_Hei = self.spc.shape[2]
336 self.Num_Hei = self.spc.shape[2]
319 self.Num_Bin = self.spc.shape[1]
337 self.Num_Bin = self.spc.shape[1]
320 self.Num_Chn = self.spc.shape[0]
338 self.Num_Chn = self.spc.shape[0]
321 Vrange = dataOut.abscissaList
339 Vrange = dataOut.abscissaList
322
340
323 GauSPC = numpy.empty([self.Num_Chn,self.Num_Bin,self.Num_Hei])
341 GauSPC = numpy.empty([self.Num_Chn,self.Num_Bin,self.Num_Hei])
324 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
342 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
325 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
343 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
326 SPC_ch1[:] = numpy.NaN
344 SPC_ch1[:] = numpy.NaN
327 SPC_ch2[:] = numpy.NaN
345 SPC_ch2[:] = numpy.NaN
328
346
329
347
330 start_time = time.time()
348 start_time = time.time()
331
349
332 noise_ = dataOut.spc_noise[0].copy()
350 noise_ = dataOut.spc_noise[0].copy()
333
351
334
352
335 pool = Pool(processes=self.Num_Chn)
353 pool = Pool(processes=self.Num_Chn)
336 args = [(Vrange, Ch, pnoise, noise_, num_intg, SNRlimit) for Ch in range(self.Num_Chn)]
354 args = [(Vrange, Ch, pnoise, noise_, num_intg, SNRlimit) for Ch in range(self.Num_Chn)]
337 objs = [self for __ in range(self.Num_Chn)]
355 objs = [self for __ in range(self.Num_Chn)]
338 attrs = list(zip(objs, args))
356 attrs = list(zip(objs, args))
339 gauSPC = pool.map(target, attrs)
357 gauSPC = pool.map(target, attrs)
340 dataOut.SPCparam = numpy.asarray(SPCparam)
358 dataOut.SPCparam = numpy.asarray(SPCparam)
341
359
342 ''' Parameters:
360 ''' Parameters:
343 1. Amplitude
361 1. Amplitude
344 2. Shift
362 2. Shift
345 3. Width
363 3. Width
346 4. Power
364 4. Power
347 '''
365 '''
348
366
349 def FitGau(self, X):
367 def FitGau(self, X):
350
368
351 Vrange, ch, pnoise, noise_, num_intg, SNRlimit = X
369 Vrange, ch, pnoise, noise_, num_intg, SNRlimit = X
352
370
353 SPCparam = []
371 SPCparam = []
354 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
372 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
355 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
373 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
356 SPC_ch1[:] = 0#numpy.NaN
374 SPC_ch1[:] = 0#numpy.NaN
357 SPC_ch2[:] = 0#numpy.NaN
375 SPC_ch2[:] = 0#numpy.NaN
358
376
359
377
360
378
361 for ht in range(self.Num_Hei):
379 for ht in range(self.Num_Hei):
362
380
363
381
364 spc = numpy.asarray(self.spc)[ch,:,ht]
382 spc = numpy.asarray(self.spc)[ch,:,ht]
365
383
366 #############################################
384 #############################################
367 # normalizing spc and noise
385 # normalizing spc and noise
368 # This part differs from gg1
386 # This part differs from gg1
@@ -370,60 +388,60 class GaussianFit(Operation):
370 #spc = spc / spc_norm_max
388 #spc = spc / spc_norm_max
371 pnoise = pnoise #/ spc_norm_max
389 pnoise = pnoise #/ spc_norm_max
372 #############################################
390 #############################################
373
391
374 fatspectra=1.0
392 fatspectra=1.0
375
393
376 wnoise = noise_ #/ spc_norm_max
394 wnoise = noise_ #/ spc_norm_max
377 #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
395 #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
378 #if wnoise>1.1*pnoise: # to be tested later
396 #if wnoise>1.1*pnoise: # to be tested later
379 # wnoise=pnoise
397 # wnoise=pnoise
380 noisebl=wnoise*0.9;
398 noisebl=wnoise*0.9;
381 noisebh=wnoise*1.1
399 noisebh=wnoise*1.1
382 spc=spc-wnoise
400 spc=spc-wnoise
383
401
384 minx=numpy.argmin(spc)
402 minx=numpy.argmin(spc)
385 #spcs=spc.copy()
403 #spcs=spc.copy()
386 spcs=numpy.roll(spc,-minx)
404 spcs=numpy.roll(spc,-minx)
387 cum=numpy.cumsum(spcs)
405 cum=numpy.cumsum(spcs)
388 tot_noise=wnoise * self.Num_Bin #64;
406 tot_noise=wnoise * self.Num_Bin #64;
389
407
390 snr = sum(spcs)/tot_noise
408 snr = sum(spcs)/tot_noise
391 snrdB=10.*numpy.log10(snr)
409 snrdB=10.*numpy.log10(snr)
392
410
393 if snrdB < SNRlimit :
411 if snrdB < SNRlimit :
394 snr = numpy.NaN
412 snr = numpy.NaN
395 SPC_ch1[:,ht] = 0#numpy.NaN
413 SPC_ch1[:,ht] = 0#numpy.NaN
396 SPC_ch1[:,ht] = 0#numpy.NaN
414 SPC_ch1[:,ht] = 0#numpy.NaN
397 SPCparam = (SPC_ch1,SPC_ch2)
415 SPCparam = (SPC_ch1,SPC_ch2)
398 continue
416 continue
399
417
400
418
401 #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
419 #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
402 # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
420 # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
403
421
404 cummax=max(cum);
422 cummax=max(cum);
405 epsi=0.08*fatspectra # cumsum to narrow down the energy region
423 epsi=0.08*fatspectra # cumsum to narrow down the energy region
406 cumlo=cummax*epsi;
424 cumlo=cummax*epsi;
407 cumhi=cummax*(1-epsi)
425 cumhi=cummax*(1-epsi)
408 powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
426 powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
409
427
410
428
411 if len(powerindex) < 1:# case for powerindex 0
429 if len(powerindex) < 1:# case for powerindex 0
412 continue
430 continue
413 powerlo=powerindex[0]
431 powerlo=powerindex[0]
414 powerhi=powerindex[-1]
432 powerhi=powerindex[-1]
415 powerwidth=powerhi-powerlo
433 powerwidth=powerhi-powerlo
416
434
417 firstpeak=powerlo+powerwidth/10.# first gaussian energy location
435 firstpeak=powerlo+powerwidth/10.# first gaussian energy location
418 secondpeak=powerhi-powerwidth/10.#second gaussian energy location
436 secondpeak=powerhi-powerwidth/10.#second gaussian energy location
419 midpeak=(firstpeak+secondpeak)/2.
437 midpeak=(firstpeak+secondpeak)/2.
420 firstamp=spcs[int(firstpeak)]
438 firstamp=spcs[int(firstpeak)]
421 secondamp=spcs[int(secondpeak)]
439 secondamp=spcs[int(secondpeak)]
422 midamp=spcs[int(midpeak)]
440 midamp=spcs[int(midpeak)]
423
441
424 x=numpy.arange( self.Num_Bin )
442 x=numpy.arange( self.Num_Bin )
425 y_data=spc+wnoise
443 y_data=spc+wnoise
426
444
427 ''' single Gaussian '''
445 ''' single Gaussian '''
428 shift0=numpy.mod(midpeak+minx, self.Num_Bin )
446 shift0=numpy.mod(midpeak+minx, self.Num_Bin )
429 width0=powerwidth/4.#Initialization entire power of spectrum divided by 4
447 width0=powerwidth/4.#Initialization entire power of spectrum divided by 4
@@ -432,10 +450,10 class GaussianFit(Operation):
432 state0=[shift0,width0,amplitude0,power0,wnoise]
450 state0=[shift0,width0,amplitude0,power0,wnoise]
433 bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
451 bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
434 lsq1=fmin_l_bfgs_b(self.misfit1,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
452 lsq1=fmin_l_bfgs_b(self.misfit1,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
435
436 chiSq1=lsq1[1];
437
453
438
454 chiSq1=lsq1[1];
455
456
439 if fatspectra<1.0 and powerwidth<4:
457 if fatspectra<1.0 and powerwidth<4:
440 choice=0
458 choice=0
441 Amplitude0=lsq1[0][2]
459 Amplitude0=lsq1[0][2]
@@ -449,31 +467,31 class GaussianFit(Operation):
449 noise=lsq1[0][4]
467 noise=lsq1[0][4]
450 #return (numpy.array([shift0,width0,Amplitude0,p0]),
468 #return (numpy.array([shift0,width0,Amplitude0,p0]),
451 # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
469 # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
452
470
453 ''' two gaussians '''
471 ''' two gaussians '''
454 #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
472 #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
455 shift0=numpy.mod(firstpeak+minx, self.Num_Bin );
473 shift0=numpy.mod(firstpeak+minx, self.Num_Bin );
456 shift1=numpy.mod(secondpeak+minx, self.Num_Bin )
474 shift1=numpy.mod(secondpeak+minx, self.Num_Bin )
457 width0=powerwidth/6.;
475 width0=powerwidth/6.;
458 width1=width0
476 width1=width0
459 power0=2.;
477 power0=2.;
460 power1=power0
478 power1=power0
461 amplitude0=firstamp;
479 amplitude0=firstamp;
462 amplitude1=secondamp
480 amplitude1=secondamp
463 state0=[shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
481 state0=[shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
464 #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
482 #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
465 bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
483 bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
466 #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(0.1,0.5))
484 #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(0.1,0.5))
467
485
468 lsq2 = fmin_l_bfgs_b( self.misfit2 , state0 , args=(y_data,x,num_intg) , bounds=bnds , approx_grad=True )
486 lsq2 = fmin_l_bfgs_b( self.misfit2 , state0 , args=(y_data,x,num_intg) , bounds=bnds , approx_grad=True )
469
487
470
488
471 chiSq2=lsq2[1];
489 chiSq2=lsq2[1];
472
490
473
491
474
492
475 oneG=(chiSq1<5 and chiSq1/chiSq2<2.0) and (abs(lsq2[0][0]-lsq2[0][4])<(lsq2[0][1]+lsq2[0][5])/3. or abs(lsq2[0][0]-lsq2[0][4])<10)
493 oneG=(chiSq1<5 and chiSq1/chiSq2<2.0) and (abs(lsq2[0][0]-lsq2[0][4])<(lsq2[0][1]+lsq2[0][5])/3. or abs(lsq2[0][0]-lsq2[0][4])<10)
476
494
477 if snrdB>-12: # when SNR is strong pick the peak with least shift (LOS velocity) error
495 if snrdB>-12: # when SNR is strong pick the peak with least shift (LOS velocity) error
478 if oneG:
496 if oneG:
479 choice=0
497 choice=0
@@ -481,10 +499,10 class GaussianFit(Operation):
481 w1=lsq2[0][1]; w2=lsq2[0][5]
499 w1=lsq2[0][1]; w2=lsq2[0][5]
482 a1=lsq2[0][2]; a2=lsq2[0][6]
500 a1=lsq2[0][2]; a2=lsq2[0][6]
483 p1=lsq2[0][3]; p2=lsq2[0][7]
501 p1=lsq2[0][3]; p2=lsq2[0][7]
484 s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1;
502 s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1;
485 s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2;
503 s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2;
486 gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling
504 gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling
487
505
488 if gp1>gp2:
506 if gp1>gp2:
489 if a1>0.7*a2:
507 if a1>0.7*a2:
490 choice=1
508 choice=1
@@ -499,157 +517,157 class GaussianFit(Operation):
499 choice=numpy.argmax([a1,a2])+1
517 choice=numpy.argmax([a1,a2])+1
500 #else:
518 #else:
501 #choice=argmin([std2a,std2b])+1
519 #choice=argmin([std2a,std2b])+1
502
520
503 else: # with low SNR go to the most energetic peak
521 else: # with low SNR go to the most energetic peak
504 choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
522 choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
505
523
506
524
507 shift0=lsq2[0][0];
525 shift0=lsq2[0][0];
508 vel0=Vrange[0] + shift0*(Vrange[1]-Vrange[0])
526 vel0=Vrange[0] + shift0*(Vrange[1]-Vrange[0])
509 shift1=lsq2[0][4];
527 shift1=lsq2[0][4];
510 vel1=Vrange[0] + shift1*(Vrange[1]-Vrange[0])
528 vel1=Vrange[0] + shift1*(Vrange[1]-Vrange[0])
511
529
512 max_vel = 1.0
530 max_vel = 1.0
513
531
514 #first peak will be 0, second peak will be 1
532 #first peak will be 0, second peak will be 1
515 if vel0 > -1.0 and vel0 < max_vel : #first peak is in the correct range
533 if vel0 > -1.0 and vel0 < max_vel : #first peak is in the correct range
516 shift0=lsq2[0][0]
534 shift0=lsq2[0][0]
517 width0=lsq2[0][1]
535 width0=lsq2[0][1]
518 Amplitude0=lsq2[0][2]
536 Amplitude0=lsq2[0][2]
519 p0=lsq2[0][3]
537 p0=lsq2[0][3]
520
538
521 shift1=lsq2[0][4]
539 shift1=lsq2[0][4]
522 width1=lsq2[0][5]
540 width1=lsq2[0][5]
523 Amplitude1=lsq2[0][6]
541 Amplitude1=lsq2[0][6]
524 p1=lsq2[0][7]
542 p1=lsq2[0][7]
525 noise=lsq2[0][8]
543 noise=lsq2[0][8]
526 else:
544 else:
527 shift1=lsq2[0][0]
545 shift1=lsq2[0][0]
528 width1=lsq2[0][1]
546 width1=lsq2[0][1]
529 Amplitude1=lsq2[0][2]
547 Amplitude1=lsq2[0][2]
530 p1=lsq2[0][3]
548 p1=lsq2[0][3]
531
549
532 shift0=lsq2[0][4]
550 shift0=lsq2[0][4]
533 width0=lsq2[0][5]
551 width0=lsq2[0][5]
534 Amplitude0=lsq2[0][6]
552 Amplitude0=lsq2[0][6]
535 p0=lsq2[0][7]
553 p0=lsq2[0][7]
536 noise=lsq2[0][8]
554 noise=lsq2[0][8]
537
555
538 if Amplitude0<0.05: # in case the peak is noise
556 if Amplitude0<0.05: # in case the peak is noise
539 shift0,width0,Amplitude0,p0 = [0,0,0,0]#4*[numpy.NaN]
557 shift0,width0,Amplitude0,p0 = [0,0,0,0]#4*[numpy.NaN]
540 if Amplitude1<0.05:
558 if Amplitude1<0.05:
541 shift1,width1,Amplitude1,p1 = [0,0,0,0]#4*[numpy.NaN]
559 shift1,width1,Amplitude1,p1 = [0,0,0,0]#4*[numpy.NaN]
542
560
543
561
544 SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0
562 SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0
545 SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1
563 SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1
546 SPCparam = (SPC_ch1,SPC_ch2)
564 SPCparam = (SPC_ch1,SPC_ch2)
547
565
548
566
549 return GauSPC
567 return GauSPC
550
568
551 def y_model1(self,x,state):
569 def y_model1(self,x,state):
552 shift0,width0,amplitude0,power0,noise=state
570 shift0,width0,amplitude0,power0,noise=state
553 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
571 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
554
572
555 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
573 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
556
574
557 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
575 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
558 return model0+model0u+model0d+noise
576 return model0+model0u+model0d+noise
559
577
560 def y_model2(self,x,state): #Equation for two generalized Gaussians with Nyquist
578 def y_model2(self,x,state): #Equation for two generalized Gaussians with Nyquist
561 shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,noise=state
579 shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,noise=state
562 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
580 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
563
581
564 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
582 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
565
583
566 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
584 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
567 model1=amplitude1*numpy.exp(-0.5*abs((x-shift1)/width1)**power1)
585 model1=amplitude1*numpy.exp(-0.5*abs((x-shift1)/width1)**power1)
568
586
569 model1u=amplitude1*numpy.exp(-0.5*abs((x-shift1- self.Num_Bin )/width1)**power1)
587 model1u=amplitude1*numpy.exp(-0.5*abs((x-shift1- self.Num_Bin )/width1)**power1)
570
588
571 model1d=amplitude1*numpy.exp(-0.5*abs((x-shift1+ self.Num_Bin )/width1)**power1)
589 model1d=amplitude1*numpy.exp(-0.5*abs((x-shift1+ self.Num_Bin )/width1)**power1)
572 return model0+model0u+model0d+model1+model1u+model1d+noise
590 return model0+model0u+model0d+model1+model1u+model1d+noise
573
591
574 def misfit1(self,state,y_data,x,num_intg): # This function compares how close real data is with the model data, the close it is, the better it is.
592 def misfit1(self,state,y_data,x,num_intg): # This function compares how close real data is with the model data, the close it is, the better it is.
575
593
576 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model1(x,state)))**2)#/(64-5.) # /(64-5.) can be commented
594 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model1(x,state)))**2)#/(64-5.) # /(64-5.) can be commented
577
595
578 def misfit2(self,state,y_data,x,num_intg):
596 def misfit2(self,state,y_data,x,num_intg):
579 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model2(x,state)))**2)#/(64-9.)
597 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model2(x,state)))**2)#/(64-9.)
580
598
581
599
582
600
583 class PrecipitationProc(Operation):
601 class PrecipitationProc(Operation):
584
602
585 '''
603 '''
586 Operator that estimates Reflectivity factor (Z), and estimates rainfall Rate (R)
604 Operator that estimates Reflectivity factor (Z), and estimates rainfall Rate (R)
587
605
588 Input:
606 Input:
589 self.dataOut.data_pre : SelfSpectra
607 self.dataOut.data_pre : SelfSpectra
590
608
591 Output:
609 Output:
592
610
593 self.dataOut.data_output : Reflectivity factor, rainfall Rate
611 self.dataOut.data_output : Reflectivity factor, rainfall Rate
594
612
595
613
596 Parameters affected:
614 Parameters affected:
597 '''
615 '''
598
616
599 def __init__(self):
617 def __init__(self):
600 Operation.__init__(self)
618 Operation.__init__(self)
601 self.i=0
619 self.i=0
602
620
603
621
604 def gaus(self,xSamples,Amp,Mu,Sigma):
622 def gaus(self,xSamples,Amp,Mu,Sigma):
605 return ( Amp / ((2*numpy.pi)**0.5 * Sigma) ) * numpy.exp( -( xSamples - Mu )**2 / ( 2 * (Sigma**2) ))
623 return ( Amp / ((2*numpy.pi)**0.5 * Sigma) ) * numpy.exp( -( xSamples - Mu )**2 / ( 2 * (Sigma**2) ))
606
624
607
625
608
626
609 def Moments(self, ySamples, xSamples):
627 def Moments(self, ySamples, xSamples):
610 Pot = numpy.nansum( ySamples ) # Potencia, momento 0
628 Pot = numpy.nansum( ySamples ) # Potencia, momento 0
611 yNorm = ySamples / Pot
629 yNorm = ySamples / Pot
612
630
613 Vr = numpy.nansum( yNorm * xSamples ) # Velocidad radial, mu, corrimiento doppler, primer momento
631 Vr = numpy.nansum( yNorm * xSamples ) # Velocidad radial, mu, corrimiento doppler, primer momento
614 Sigma2 = abs(numpy.nansum( yNorm * ( xSamples - Vr )**2 )) # Segundo Momento
632 Sigma2 = abs(numpy.nansum( yNorm * ( xSamples - Vr )**2 )) # Segundo Momento
615 Desv = Sigma2**0.5 # Desv. Estandar, Ancho espectral
633 Desv = Sigma2**0.5 # Desv. Estandar, Ancho espectral
616
634
617 return numpy.array([Pot, Vr, Desv])
635 return numpy.array([Pot, Vr, Desv])
618
636
619 def run(self, dataOut, radar=None, Pt=5000, Gt=295.1209, Gr=70.7945, Lambda=0.6741, aL=2.5118,
637 def run(self, dataOut, radar=None, Pt=5000, Gt=295.1209, Gr=70.7945, Lambda=0.6741, aL=2.5118,
620 tauW=4e-06, ThetaT=0.1656317, ThetaR=0.36774087, Km = 0.93, Altitude=3350):
638 tauW=4e-06, ThetaT=0.1656317, ThetaR=0.36774087, Km = 0.93, Altitude=3350):
621
639
622
640
623 Velrange = dataOut.spcparam_range[2]
641 Velrange = dataOut.spcparam_range[2]
624 FrecRange = dataOut.spcparam_range[0]
642 FrecRange = dataOut.spcparam_range[0]
625
643
626 dV= Velrange[1]-Velrange[0]
644 dV= Velrange[1]-Velrange[0]
627 dF= FrecRange[1]-FrecRange[0]
645 dF= FrecRange[1]-FrecRange[0]
628
646
629 if radar == "MIRA35C" :
647 if radar == "MIRA35C" :
630
648
631 self.spc = dataOut.data_pre[0].copy()
649 self.spc = dataOut.data_pre[0].copy()
632 self.Num_Hei = self.spc.shape[2]
650 self.Num_Hei = self.spc.shape[2]
633 self.Num_Bin = self.spc.shape[1]
651 self.Num_Bin = self.spc.shape[1]
634 self.Num_Chn = self.spc.shape[0]
652 self.Num_Chn = self.spc.shape[0]
635 Ze = self.dBZeMODE2(dataOut)
653 Ze = self.dBZeMODE2(dataOut)
636
654
637 else:
655 else:
638
656
639 self.spc = dataOut.SPCparam[1].copy() #dataOut.data_pre[0].copy() #
657 self.spc = dataOut.SPCparam[1].copy() #dataOut.data_pre[0].copy() #
640
658
641 """NOTA SE DEBE REMOVER EL RANGO DEL PULSO TX"""
659 """NOTA SE DEBE REMOVER EL RANGO DEL PULSO TX"""
642
660
643 self.spc[:,:,0:7]= numpy.NaN
661 self.spc[:,:,0:7]= numpy.NaN
644
662
645 """##########################################"""
663 """##########################################"""
646
664
647 self.Num_Hei = self.spc.shape[2]
665 self.Num_Hei = self.spc.shape[2]
648 self.Num_Bin = self.spc.shape[1]
666 self.Num_Bin = self.spc.shape[1]
649 self.Num_Chn = self.spc.shape[0]
667 self.Num_Chn = self.spc.shape[0]
650
668
651 ''' Se obtiene la constante del RADAR '''
669 ''' Se obtiene la constante del RADAR '''
652
670
653 self.Pt = Pt
671 self.Pt = Pt
654 self.Gt = Gt
672 self.Gt = Gt
655 self.Gr = Gr
673 self.Gr = Gr
@@ -658,30 +676,30 class PrecipitationProc(Operation):
658 self.tauW = tauW
676 self.tauW = tauW
659 self.ThetaT = ThetaT
677 self.ThetaT = ThetaT
660 self.ThetaR = ThetaR
678 self.ThetaR = ThetaR
661
679
662 Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
680 Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
663 Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * tauW * numpy.pi * ThetaT * ThetaR)
681 Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * tauW * numpy.pi * ThetaT * ThetaR)
664 RadarConstant = 10e-26 * Numerator / Denominator #
682 RadarConstant = 10e-26 * Numerator / Denominator #
665
683
666 ''' ============================= '''
684 ''' ============================= '''
667
685
668 self.spc[0] = (self.spc[0]-dataOut.noise[0])
686 self.spc[0] = (self.spc[0]-dataOut.noise[0])
669 self.spc[1] = (self.spc[1]-dataOut.noise[1])
687 self.spc[1] = (self.spc[1]-dataOut.noise[1])
670 self.spc[2] = (self.spc[2]-dataOut.noise[2])
688 self.spc[2] = (self.spc[2]-dataOut.noise[2])
671
689
672 self.spc[ numpy.where(self.spc < 0)] = 0
690 self.spc[ numpy.where(self.spc < 0)] = 0
673
691
674 SPCmean = (numpy.mean(self.spc,0) - numpy.mean(dataOut.noise))
692 SPCmean = (numpy.mean(self.spc,0) - numpy.mean(dataOut.noise))
675 SPCmean[ numpy.where(SPCmean < 0)] = 0
693 SPCmean[ numpy.where(SPCmean < 0)] = 0
676
694
677 ETAn = numpy.zeros([self.Num_Bin,self.Num_Hei])
695 ETAn = numpy.zeros([self.Num_Bin,self.Num_Hei])
678 ETAv = numpy.zeros([self.Num_Bin,self.Num_Hei])
696 ETAv = numpy.zeros([self.Num_Bin,self.Num_Hei])
679 ETAd = numpy.zeros([self.Num_Bin,self.Num_Hei])
697 ETAd = numpy.zeros([self.Num_Bin,self.Num_Hei])
680
698
681 Pr = SPCmean[:,:]
699 Pr = SPCmean[:,:]
682
700
683 VelMeteoro = numpy.mean(SPCmean,axis=0)
701 VelMeteoro = numpy.mean(SPCmean,axis=0)
684
702
685 D_range = numpy.zeros([self.Num_Bin,self.Num_Hei])
703 D_range = numpy.zeros([self.Num_Bin,self.Num_Hei])
686 SIGMA = numpy.zeros([self.Num_Bin,self.Num_Hei])
704 SIGMA = numpy.zeros([self.Num_Bin,self.Num_Hei])
687 N_dist = numpy.zeros([self.Num_Bin,self.Num_Hei])
705 N_dist = numpy.zeros([self.Num_Bin,self.Num_Hei])
@@ -690,102 +708,102 class PrecipitationProc(Operation):
690 Z = numpy.zeros(self.Num_Hei)
708 Z = numpy.zeros(self.Num_Hei)
691 Ze = numpy.zeros(self.Num_Hei)
709 Ze = numpy.zeros(self.Num_Hei)
692 RR = numpy.zeros(self.Num_Hei)
710 RR = numpy.zeros(self.Num_Hei)
693
711
694 Range = dataOut.heightList*1000.
712 Range = dataOut.heightList*1000.
695
713
696 for R in range(self.Num_Hei):
714 for R in range(self.Num_Hei):
697
715
698 h = Range[R] + Altitude #Range from ground to radar pulse altitude
716 h = Range[R] + Altitude #Range from ground to radar pulse altitude
699 del_V[R] = 1 + 3.68 * 10**-5 * h + 1.71 * 10**-9 * h**2 #Density change correction for velocity
717 del_V[R] = 1 + 3.68 * 10**-5 * h + 1.71 * 10**-9 * h**2 #Density change correction for velocity
700
718
701 D_range[:,R] = numpy.log( (9.65 - (Velrange[0:self.Num_Bin] / del_V[R])) / 10.3 ) / -0.6 #Diameter range [m]x10**-3
719 D_range[:,R] = numpy.log( (9.65 - (Velrange[0:self.Num_Bin] / del_V[R])) / 10.3 ) / -0.6 #Diameter range [m]x10**-3
702
720
703 '''NOTA: ETA(n) dn = ETA(f) df
721 '''NOTA: ETA(n) dn = ETA(f) df
704
722
705 dn = 1 Diferencial de muestreo
723 dn = 1 Diferencial de muestreo
706 df = ETA(n) / ETA(f)
724 df = ETA(n) / ETA(f)
707
725
708 '''
726 '''
709
727
710 ETAn[:,R] = RadarConstant * Pr[:,R] * (Range[R] )**2 #Reflectivity (ETA)
728 ETAn[:,R] = RadarConstant * Pr[:,R] * (Range[R] )**2 #Reflectivity (ETA)
711
729
712 ETAv[:,R]=ETAn[:,R]/dV
730 ETAv[:,R]=ETAn[:,R]/dV
713
731
714 ETAd[:,R]=ETAv[:,R]*6.18*exp(-0.6*D_range[:,R])
732 ETAd[:,R]=ETAv[:,R]*6.18*exp(-0.6*D_range[:,R])
715
733
716 SIGMA[:,R] = Km * (D_range[:,R] * 1e-3 )**6 * numpy.pi**5 / Lambda**4 #Equivalent Section of drops (sigma)
734 SIGMA[:,R] = Km * (D_range[:,R] * 1e-3 )**6 * numpy.pi**5 / Lambda**4 #Equivalent Section of drops (sigma)
717
735
718 N_dist[:,R] = ETAn[:,R] / SIGMA[:,R]
736 N_dist[:,R] = ETAn[:,R] / SIGMA[:,R]
719
737
720 DMoments = self.Moments(Pr[:,R], Velrange[0:self.Num_Bin])
738 DMoments = self.Moments(Pr[:,R], Velrange[0:self.Num_Bin])
721
739
722 try:
740 try:
723 popt01,pcov = curve_fit(self.gaus, Velrange[0:self.Num_Bin] , Pr[:,R] , p0=DMoments)
741 popt01,pcov = curve_fit(self.gaus, Velrange[0:self.Num_Bin] , Pr[:,R] , p0=DMoments)
724 except:
742 except:
725 popt01=numpy.zeros(3)
743 popt01=numpy.zeros(3)
726 popt01[1]= DMoments[1]
744 popt01[1]= DMoments[1]
727
745
728 if popt01[1]<0 or popt01[1]>20:
746 if popt01[1]<0 or popt01[1]>20:
729 popt01[1]=numpy.NaN
747 popt01[1]=numpy.NaN
730
748
731
749
732 V_mean[R]=popt01[1]
750 V_mean[R]=popt01[1]
733
751
734 Z[R] = numpy.nansum( N_dist[:,R] * (D_range[:,R])**6 )#*10**-18
752 Z[R] = numpy.nansum( N_dist[:,R] * (D_range[:,R])**6 )#*10**-18
735
753
736 RR[R] = 0.0006*numpy.pi * numpy.nansum( D_range[:,R]**3 * N_dist[:,R] * Velrange[0:self.Num_Bin] ) #Rainfall rate
754 RR[R] = 0.0006*numpy.pi * numpy.nansum( D_range[:,R]**3 * N_dist[:,R] * Velrange[0:self.Num_Bin] ) #Rainfall rate
737
755
738 Ze[R] = (numpy.nansum( ETAn[:,R]) * Lambda**4) / ( 10**-18*numpy.pi**5 * Km)
756 Ze[R] = (numpy.nansum( ETAn[:,R]) * Lambda**4) / ( 10**-18*numpy.pi**5 * Km)
739
757
740
758
741
759
742 RR2 = (Z/200)**(1/1.6)
760 RR2 = (Z/200)**(1/1.6)
743 dBRR = 10*numpy.log10(RR)
761 dBRR = 10*numpy.log10(RR)
744 dBRR2 = 10*numpy.log10(RR2)
762 dBRR2 = 10*numpy.log10(RR2)
745
763
746 dBZe = 10*numpy.log10(Ze)
764 dBZe = 10*numpy.log10(Ze)
747 dBZ = 10*numpy.log10(Z)
765 dBZ = 10*numpy.log10(Z)
748
766
749 dataOut.data_output = RR[8]
767 dataOut.data_output = RR[8]
750 dataOut.data_param = numpy.ones([3,self.Num_Hei])
768 dataOut.data_param = numpy.ones([3,self.Num_Hei])
751 dataOut.channelList = [0,1,2]
769 dataOut.channelList = [0,1,2]
752
770
753 dataOut.data_param[0]=dBZ
771 dataOut.data_param[0]=dBZ
754 dataOut.data_param[1]=V_mean
772 dataOut.data_param[1]=V_mean
755 dataOut.data_param[2]=RR
773 dataOut.data_param[2]=RR
756
774
757 return dataOut
775 return dataOut
758
776
759 def dBZeMODE2(self, dataOut): # Processing for MIRA35C
777 def dBZeMODE2(self, dataOut): # Processing for MIRA35C
760
778
761 NPW = dataOut.NPW
779 NPW = dataOut.NPW
762 COFA = dataOut.COFA
780 COFA = dataOut.COFA
763
781
764 SNR = numpy.array([self.spc[0,:,:] / NPW[0]]) #, self.spc[1,:,:] / NPW[1]])
782 SNR = numpy.array([self.spc[0,:,:] / NPW[0]]) #, self.spc[1,:,:] / NPW[1]])
765 RadarConst = dataOut.RadarConst
783 RadarConst = dataOut.RadarConst
766 #frequency = 34.85*10**9
784 #frequency = 34.85*10**9
767
785
768 ETA = numpy.zeros(([self.Num_Chn ,self.Num_Hei]))
786 ETA = numpy.zeros(([self.Num_Chn ,self.Num_Hei]))
769 data_output = numpy.ones([self.Num_Chn , self.Num_Hei])*numpy.NaN
787 data_output = numpy.ones([self.Num_Chn , self.Num_Hei])*numpy.NaN
770
788
771 ETA = numpy.sum(SNR,1)
789 ETA = numpy.sum(SNR,1)
772
790
773 ETA = numpy.where(ETA is not 0. , ETA, numpy.NaN)
791 ETA = numpy.where(ETA is not 0. , ETA, numpy.NaN)
774
792
775 Ze = numpy.ones([self.Num_Chn, self.Num_Hei] )
793 Ze = numpy.ones([self.Num_Chn, self.Num_Hei] )
776
794
777 for r in range(self.Num_Hei):
795 for r in range(self.Num_Hei):
778
796
779 Ze[0,r] = ( ETA[0,r] ) * COFA[0,r][0] * RadarConst * ((r/5000.)**2)
797 Ze[0,r] = ( ETA[0,r] ) * COFA[0,r][0] * RadarConst * ((r/5000.)**2)
780 #Ze[1,r] = ( ETA[1,r] ) * COFA[1,r][0] * RadarConst * ((r/5000.)**2)
798 #Ze[1,r] = ( ETA[1,r] ) * COFA[1,r][0] * RadarConst * ((r/5000.)**2)
781
799
782 return Ze
800 return Ze
783
801
784 # def GetRadarConstant(self):
802 # def GetRadarConstant(self):
785 #
803 #
786 # """
804 # """
787 # Constants:
805 # Constants:
788 #
806 #
789 # Pt: Transmission Power dB 5kW 5000
807 # Pt: Transmission Power dB 5kW 5000
790 # Gt: Transmission Gain dB 24.7 dB 295.1209
808 # Gt: Transmission Gain dB 24.7 dB 295.1209
791 # Gr: Reception Gain dB 18.5 dB 70.7945
809 # Gr: Reception Gain dB 18.5 dB 70.7945
@@ -794,55 +812,55 class PrecipitationProc(Operation):
794 # tauW: Width of transmission pulse s 4us 4e-6
812 # tauW: Width of transmission pulse s 4us 4e-6
795 # ThetaT: Transmission antenna bean angle rad 0.1656317 rad 0.1656317
813 # ThetaT: Transmission antenna bean angle rad 0.1656317 rad 0.1656317
796 # ThetaR: Reception antenna beam angle rad 0.36774087 rad 0.36774087
814 # ThetaR: Reception antenna beam angle rad 0.36774087 rad 0.36774087
797 #
815 #
798 # """
816 # """
799 #
817 #
800 # Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
818 # Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
801 # Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * TauW * numpy.pi * ThetaT * TheraR)
819 # Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * TauW * numpy.pi * ThetaT * TheraR)
802 # RadarConstant = Numerator / Denominator
820 # RadarConstant = Numerator / Denominator
803 #
821 #
804 # return RadarConstant
822 # return RadarConstant
805
823
806
824
807
825
808 class FullSpectralAnalysis(Operation):
826 class FullSpectralAnalysis(Operation):
809
827
810 """
828 """
811 Function that implements Full Spectral Analysis technique.
829 Function that implements Full Spectral Analysis technique.
812
830
813 Input:
831 Input:
814 self.dataOut.data_pre : SelfSpectra and CrossSpectra data
832 self.dataOut.data_pre : SelfSpectra and CrossSpectra data
815 self.dataOut.groupList : Pairlist of channels
833 self.dataOut.groupList : Pairlist of channels
816 self.dataOut.ChanDist : Physical distance between receivers
834 self.dataOut.ChanDist : Physical distance between receivers
817
835
818
836
819 Output:
837 Output:
820
838
821 self.dataOut.data_output : Zonal wind, Meridional wind and Vertical wind
839 self.dataOut.data_output : Zonal wind, Meridional wind and Vertical wind
822
840
823
841
824 Parameters affected: Winds, height range, SNR
842 Parameters affected: Winds, height range, SNR
825
843
826 """
844 """
827 def run(self, dataOut, Xi01=None, Xi02=None, Xi12=None, Eta01=None, Eta02=None, Eta12=None, SNRlimit=7, minheight=None, maxheight=None):
845 def run(self, dataOut, Xi01=None, Xi02=None, Xi12=None, Eta01=None, Eta02=None, Eta12=None, SNRlimit=7, minheight=None, maxheight=None):
828
846
829 self.indice=int(numpy.random.rand()*1000)
847 self.indice=int(numpy.random.rand()*1000)
830
848
831 spc = dataOut.data_pre[0].copy()
849 spc = dataOut.data_pre[0].copy()
832 cspc = dataOut.data_pre[1]
850 cspc = dataOut.data_pre[1]
833
851
834 """Erick: NOTE THE RANGE OF THE PULSE TX MUST BE REMOVED"""
852 """Erick: NOTE THE RANGE OF THE PULSE TX MUST BE REMOVED"""
835
853
836 SNRspc = spc.copy()
854 SNRspc = spc.copy()
837 SNRspc[:,:,0:7]= numpy.NaN
855 SNRspc[:,:,0:7]= numpy.NaN
838
856
839 """##########################################"""
857 """##########################################"""
840
858
841
859
842 nChannel = spc.shape[0]
860 nChannel = spc.shape[0]
843 nProfiles = spc.shape[1]
861 nProfiles = spc.shape[1]
844 nHeights = spc.shape[2]
862 nHeights = spc.shape[2]
845
863
846 # first_height = 0.75 #km (ref: data header 20170822)
864 # first_height = 0.75 #km (ref: data header 20170822)
847 # resolution_height = 0.075 #km
865 # resolution_height = 0.075 #km
848 '''
866 '''
@@ -866,37 +884,37 class FullSpectralAnalysis(Operation):
866 ChanDist = dataOut.ChanDist
884 ChanDist = dataOut.ChanDist
867 else:
885 else:
868 ChanDist = numpy.array([[Xi01, Eta01],[Xi02,Eta02],[Xi12,Eta12]])
886 ChanDist = numpy.array([[Xi01, Eta01],[Xi02,Eta02],[Xi12,Eta12]])
869
887
870 FrecRange = dataOut.spc_range[0]
888 FrecRange = dataOut.spc_range[0]
871
889
872 data_SNR=numpy.zeros([nProfiles])
890 data_SNR=numpy.zeros([nProfiles])
873 noise = dataOut.noise
891 noise = dataOut.noise
874
892
875 dataOut.data_SNR = (numpy.mean(SNRspc,axis=1)- noise[0]) / noise[0]
893 dataOut.data_SNR = (numpy.mean(SNRspc,axis=1)- noise[0]) / noise[0]
876
894
877 dataOut.data_SNR[numpy.where( dataOut.data_SNR <0 )] = 1e-20
895 dataOut.data_SNR[numpy.where( dataOut.data_SNR <0 )] = 1e-20
878
896
879
897
880 data_output=numpy.ones([spc.shape[0],spc.shape[2]])*numpy.NaN
898 data_output=numpy.ones([spc.shape[0],spc.shape[2]])*numpy.NaN
881
899
882 velocityX=[]
900 velocityX=[]
883 velocityY=[]
901 velocityY=[]
884 velocityV=[]
902 velocityV=[]
885
903
886 dbSNR = 10*numpy.log10(dataOut.data_SNR)
904 dbSNR = 10*numpy.log10(dataOut.data_SNR)
887 dbSNR = numpy.average(dbSNR,0)
905 dbSNR = numpy.average(dbSNR,0)
888
906
889 '''***********************************************WIND ESTIMATION**************************************'''
907 '''***********************************************WIND ESTIMATION**************************************'''
890
908
891 for Height in range(nHeights):
909 for Height in range(nHeights):
892
910
893 if Height >= range_min and Height < range_max:
911 if Height >= range_min and Height < range_max:
894 # error_code unused, yet maybe useful for future analysis.
912 # error_code unused, yet maybe useful for future analysis.
895 [Vzon,Vmer,Vver, error_code] = self.WindEstimation(spc[:,:,Height], cspc[:,:,Height], pairsList, ChanDist, Height, noise, dataOut.spc_range, dbSNR[Height], SNRlimit)
913 [Vzon,Vmer,Vver, error_code] = self.WindEstimation(spc[:,:,Height], cspc[:,:,Height], pairsList, ChanDist, Height, noise, dataOut.spc_range, dbSNR[Height], SNRlimit)
896 else:
914 else:
897 Vzon,Vmer,Vver = 0., 0., numpy.NaN
915 Vzon,Vmer,Vver = 0., 0., numpy.NaN
898
916
899
917
900 if abs(Vzon) < 100. and abs(Vzon) > 0. and abs(Vmer) < 100. and abs(Vmer) > 0.:
918 if abs(Vzon) < 100. and abs(Vzon) > 0. and abs(Vmer) < 100. and abs(Vmer) > 0.:
901 velocityX=numpy.append(velocityX, Vzon)
919 velocityX=numpy.append(velocityX, Vzon)
902 velocityY=numpy.append(velocityY, -Vmer)
920 velocityY=numpy.append(velocityY, -Vmer)
@@ -904,33 +922,33 class FullSpectralAnalysis(Operation):
904 else:
922 else:
905 velocityX=numpy.append(velocityX, numpy.NaN)
923 velocityX=numpy.append(velocityX, numpy.NaN)
906 velocityY=numpy.append(velocityY, numpy.NaN)
924 velocityY=numpy.append(velocityY, numpy.NaN)
907
925
908 if dbSNR[Height] > SNRlimit:
926 if dbSNR[Height] > SNRlimit:
909 velocityV=numpy.append(velocityV, -Vver) # reason for this minus sign -> convention? (taken from Ericks version)
927 velocityV=numpy.append(velocityV, -Vver) # reason for this minus sign -> convention? (taken from Ericks version)
910 else:
928 else:
911 velocityV=numpy.append(velocityV, numpy.NaN)
929 velocityV=numpy.append(velocityV, numpy.NaN)
912
930
913
931
914 '''Change the numpy.array (velocityX) sign when trying to process BLTR data (Erick)'''
932 '''Change the numpy.array (velocityX) sign when trying to process BLTR data (Erick)'''
915 data_output[0] = numpy.array(velocityX)
933 data_output[0] = numpy.array(velocityX)
916 data_output[1] = numpy.array(velocityY)
934 data_output[1] = numpy.array(velocityY)
917 data_output[2] = velocityV
935 data_output[2] = velocityV
918
936
919
937
920 dataOut.data_output = data_output
938 dataOut.data_output = data_output
921
939
922 return dataOut
940 return dataOut
923
941
924
942
925 def moving_average(self,x, N=2):
943 def moving_average(self,x, N=2):
926 """ convolution for smoothenig data. note that last N-1 values are convolution with zeroes """
944 """ convolution for smoothenig data. note that last N-1 values are convolution with zeroes """
927 return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):]
945 return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):]
928
946
929 def gaus(self,xSamples,Amp,Mu,Sigma):
947 def gaus(self,xSamples,Amp,Mu,Sigma):
930 return ( Amp / ((2*numpy.pi)**0.5 * Sigma) ) * numpy.exp( -( xSamples - Mu )**2 / ( 2 * (Sigma**2) ))
948 return ( Amp / ((2*numpy.pi)**0.5 * Sigma) ) * numpy.exp( -( xSamples - Mu )**2 / ( 2 * (Sigma**2) ))
931
949
932 def Moments(self, ySamples, xSamples):
950 def Moments(self, ySamples, xSamples):
933 '''***
951 '''***
934 Variables corresponding to moments of distribution.
952 Variables corresponding to moments of distribution.
935 Also used as initial coefficients for curve_fit.
953 Also used as initial coefficients for curve_fit.
936 Vr was corrected. Only a velocity when x is velocity, of course.
954 Vr was corrected. Only a velocity when x is velocity, of course.
@@ -939,9 +957,9 class FullSpectralAnalysis(Operation):
939 yNorm = ySamples / Pot
957 yNorm = ySamples / Pot
940 x_range = (numpy.max(xSamples)-numpy.min(xSamples))
958 x_range = (numpy.max(xSamples)-numpy.min(xSamples))
941 Vr = numpy.nansum( yNorm * xSamples )*x_range/len(xSamples) # Velocidad radial, mu, corrimiento doppler, primer momento
959 Vr = numpy.nansum( yNorm * xSamples )*x_range/len(xSamples) # Velocidad radial, mu, corrimiento doppler, primer momento
942 Sigma2 = abs(numpy.nansum( yNorm * ( xSamples - Vr )**2 )) # Segundo Momento
960 Sigma2 = abs(numpy.nansum( yNorm * ( xSamples - Vr )**2 )) # Segundo Momento
943 Desv = Sigma2**0.5 # Desv. Estandar, Ancho espectral
961 Desv = Sigma2**0.5 # Desv. Estandar, Ancho espectral
944
962
945 return numpy.array([Pot, Vr, Desv])
963 return numpy.array([Pot, Vr, Desv])
946
964
947 def StopWindEstimation(self, error_code):
965 def StopWindEstimation(self, error_code):
@@ -954,7 +972,7 class FullSpectralAnalysis(Operation):
954 return Vzon, Vmer, Vver, error_code
972 return Vzon, Vmer, Vver, error_code
955
973
956 def AntiAliasing(self, interval, maxstep):
974 def AntiAliasing(self, interval, maxstep):
957 """
975 """
958 function to prevent errors from aliased values when computing phaseslope
976 function to prevent errors from aliased values when computing phaseslope
959 """
977 """
960 antialiased = numpy.zeros(len(interval))*0.0
978 antialiased = numpy.zeros(len(interval))*0.0
@@ -964,8 +982,8 class FullSpectralAnalysis(Operation):
964
982
965 for i in range(1,len(antialiased)):
983 for i in range(1,len(antialiased)):
966
984
967 step = interval[i] - interval[i-1]
985 step = interval[i] - interval[i-1]
968
986
969 if step > maxstep:
987 if step > maxstep:
970 copyinterval -= 2*numpy.pi
988 copyinterval -= 2*numpy.pi
971 antialiased[i] = copyinterval[i]
989 antialiased[i] = copyinterval[i]
@@ -973,7 +991,7 class FullSpectralAnalysis(Operation):
973 elif step < maxstep*(-1):
991 elif step < maxstep*(-1):
974 copyinterval += 2*numpy.pi
992 copyinterval += 2*numpy.pi
975 antialiased[i] = copyinterval[i]
993 antialiased[i] = copyinterval[i]
976
994
977 else:
995 else:
978 antialiased[i] = copyinterval[i].copy()
996 antialiased[i] = copyinterval[i].copy()
979
997
@@ -1003,27 +1021,27 class FullSpectralAnalysis(Operation):
1003 3 : SNR to low or velocity to high -> prec. e.g.
1021 3 : SNR to low or velocity to high -> prec. e.g.
1004 4 : at least one Gaussian of cspc exceeds widthlimit
1022 4 : at least one Gaussian of cspc exceeds widthlimit
1005 5 : zero out of three cspc Gaussian fits converged
1023 5 : zero out of three cspc Gaussian fits converged
1006 6 : phase slope fit could not be found
1024 6 : phase slope fit could not be found
1007 7 : arrays used to fit phase have different length
1025 7 : arrays used to fit phase have different length
1008 8 : frequency range is either too short (len <= 5) or very long (> 30% of cspc)
1026 8 : frequency range is either too short (len <= 5) or very long (> 30% of cspc)
1009
1027
1010 """
1028 """
1011
1029
1012 error_code = 0
1030 error_code = 0
1013
1031
1014
1032
1015 SPC_Samples = numpy.ones([spc.shape[0],spc.shape[1]]) # for normalized spc values for one height
1033 SPC_Samples = numpy.ones([spc.shape[0],spc.shape[1]]) # for normalized spc values for one height
1016 phase = numpy.ones([spc.shape[0],spc.shape[1]]) # phase between channels
1034 phase = numpy.ones([spc.shape[0],spc.shape[1]]) # phase between channels
1017 CSPC_Samples = numpy.ones([spc.shape[0],spc.shape[1]],dtype=numpy.complex_) # for normalized cspc values
1035 CSPC_Samples = numpy.ones([spc.shape[0],spc.shape[1]],dtype=numpy.complex_) # for normalized cspc values
1018 PhaseSlope = numpy.zeros(spc.shape[0]) # slope of the phases, channelwise
1036 PhaseSlope = numpy.zeros(spc.shape[0]) # slope of the phases, channelwise
1019 PhaseInter = numpy.ones(spc.shape[0]) # intercept to the slope of the phases, channelwise
1037 PhaseInter = numpy.ones(spc.shape[0]) # intercept to the slope of the phases, channelwise
1020 xFrec = AbbsisaRange[0][0:spc.shape[1]] # frequency range
1038 xFrec = AbbsisaRange[0][0:spc.shape[1]] # frequency range
1021 xVel = AbbsisaRange[2][0:spc.shape[1]] # velocity range
1039 xVel = AbbsisaRange[2][0:spc.shape[1]] # velocity range
1022 SPCav = numpy.average(spc, axis=0)-numpy.average(noise) # spc[0]-noise[0]
1040 SPCav = numpy.average(spc, axis=0)-numpy.average(noise) # spc[0]-noise[0]
1023
1041
1024 SPCmoments_vel = self.Moments(SPCav, xVel ) # SPCmoments_vel[1] corresponds to vertical velocity and is used to determine if signal corresponds to wind (if .. <3)
1042 SPCmoments_vel = self.Moments(SPCav, xVel ) # SPCmoments_vel[1] corresponds to vertical velocity and is used to determine if signal corresponds to wind (if .. <3)
1025 CSPCmoments = []
1043 CSPCmoments = []
1026
1044
1027
1045
1028 '''Getting Eij and Nij'''
1046 '''Getting Eij and Nij'''
1029
1047
@@ -1038,13 +1056,13 class FullSpectralAnalysis(Operation):
1038 spc_norm = spc.copy() # need copy() because untouched spc is needed for normalization of cspc below
1056 spc_norm = spc.copy() # need copy() because untouched spc is needed for normalization of cspc below
1039 spc_norm = numpy.where(numpy.isfinite(spc_norm), spc_norm, numpy.NAN)
1057 spc_norm = numpy.where(numpy.isfinite(spc_norm), spc_norm, numpy.NAN)
1040
1058
1041 for i in range(spc.shape[0]):
1059 for i in range(spc.shape[0]):
1042
1060
1043 spc_sub = spc_norm[i,:] - noise[i] # spc not smoothed here or in previous version.
1061 spc_sub = spc_norm[i,:] - noise[i] # spc not smoothed here or in previous version.
1044
1062
1045 Factor_Norm = 2*numpy.max(xFrec) / numpy.count_nonzero(~numpy.isnan(spc_sub)) # usually = Freq range / nfft
1063 Factor_Norm = 2*numpy.max(xFrec) / numpy.count_nonzero(~numpy.isnan(spc_sub)) # usually = Freq range / nfft
1046 normalized_spc = spc_sub / (numpy.nansum(numpy.abs(spc_sub)) * Factor_Norm)
1064 normalized_spc = spc_sub / (numpy.nansum(numpy.abs(spc_sub)) * Factor_Norm)
1047
1065
1048 xSamples = xFrec # the frequency range is taken
1066 xSamples = xFrec # the frequency range is taken
1049 SPC_Samples[i] = normalized_spc # Normalized SPC values are taken
1067 SPC_Samples[i] = normalized_spc # Normalized SPC values are taken
1050
1068
@@ -1055,49 +1073,49 class FullSpectralAnalysis(Operation):
1055 only for estimation of width. for normalization of cross spectra, you need initial,
1073 only for estimation of width. for normalization of cross spectra, you need initial,
1056 unnormalized self-spectra With noise.
1074 unnormalized self-spectra With noise.
1057
1075
1058 Technically, you don't even need to normalize the self-spectra, as you only need the
1076 Technically, you don't even need to normalize the self-spectra, as you only need the
1059 width of the peak. However, it was left this way. Note that the normalization has a flaw:
1077 width of the peak. However, it was left this way. Note that the normalization has a flaw:
1060 due to subtraction of the noise, some values are below zero. Raw "spc" values should be
1078 due to subtraction of the noise, some values are below zero. Raw "spc" values should be
1061 >= 0, as it is the modulus squared of the signals (complex * it's conjugate)
1079 >= 0, as it is the modulus squared of the signals (complex * it's conjugate)
1062 """
1080 """
1063
1081
1064 SPCMean = numpy.average(SPC_Samples, axis=0)
1082 SPCMean = numpy.average(SPC_Samples, axis=0)
1065
1083
1066 popt = [1e-10,0,1e-10]
1084 popt = [1e-10,0,1e-10]
1067 SPCMoments = self.Moments(SPCMean, xSamples)
1085 SPCMoments = self.Moments(SPCMean, xSamples)
1068
1086
1069 if dbSNR > SNRlimit and numpy.abs(SPCmoments_vel[1]) < 3:
1087 if dbSNR > SNRlimit and numpy.abs(SPCmoments_vel[1]) < 3:
1070 try:
1088 try:
1071 popt,pcov = curve_fit(self.gaus,xSamples,SPCMean,p0=SPCMoments)#, bounds=(-numpy.inf, [numpy.inf, numpy.inf, 10])). Setting bounds does not make the code faster but only keeps the fit from finding the minimum.
1089 popt,pcov = curve_fit(self.gaus,xSamples,SPCMean,p0=SPCMoments)#, bounds=(-numpy.inf, [numpy.inf, numpy.inf, 10])). Setting bounds does not make the code faster but only keeps the fit from finding the minimum.
1072 if popt[2] > widthlimit: # CONDITION
1090 if popt[2] > widthlimit: # CONDITION
1073 return self.StopWindEstimation(error_code = 1)
1091 return self.StopWindEstimation(error_code = 1)
1074
1092
1075 FitGauss = self.gaus(xSamples,*popt)
1093 FitGauss = self.gaus(xSamples,*popt)
1076
1094
1077 except :#RuntimeError:
1095 except :#RuntimeError:
1078 return self.StopWindEstimation(error_code = 2)
1096 return self.StopWindEstimation(error_code = 2)
1079
1097
1080 else:
1098 else:
1081 return self.StopWindEstimation(error_code = 3)
1099 return self.StopWindEstimation(error_code = 3)
1082
1100
1083
1101
1084
1102
1085 '''***************************** CSPC Normalization *************************
1103 '''***************************** CSPC Normalization *************************
1086 new section:
1104 new section:
1087 The Spc spectra are used to normalize the crossspectra. Peaks from precipitation
1105 The Spc spectra are used to normalize the crossspectra. Peaks from precipitation
1088 influence the norm which is not desired. First, a range is identified where the
1106 influence the norm which is not desired. First, a range is identified where the
1089 wind peak is estimated -> sum_wind is sum of those frequencies. Next, the area
1107 wind peak is estimated -> sum_wind is sum of those frequencies. Next, the area
1090 around it gets cut off and values replaced by mean determined by the boundary
1108 around it gets cut off and values replaced by mean determined by the boundary
1091 data -> sum_noise (spc is not normalized here, thats why the noise is important)
1109 data -> sum_noise (spc is not normalized here, thats why the noise is important)
1092
1110
1093 The sums are then added and multiplied by range/datapoints, because you need
1111 The sums are then added and multiplied by range/datapoints, because you need
1094 an integral and not a sum for normalization.
1112 an integral and not a sum for normalization.
1095
1113
1096 A norm is found according to Briggs 92.
1114 A norm is found according to Briggs 92.
1097 '''
1115 '''
1098
1116
1099 radarWavelength = 0.6741 # meters
1117 radarWavelength = 0.6741 # meters
1100 count_limit_freq = numpy.abs(popt[1]) + widthlimit # Hz, m/s can be also used if velocity is desired abscissa.
1118 count_limit_freq = numpy.abs(popt[1]) + widthlimit # Hz, m/s can be also used if velocity is desired abscissa.
1101 # count_limit_freq = numpy.max(xFrec)
1119 # count_limit_freq = numpy.max(xFrec)
1102
1120
1103 channel_integrals = numpy.zeros(3)
1121 channel_integrals = numpy.zeros(3)
@@ -1108,11 +1126,11 class FullSpectralAnalysis(Operation):
1108 sum over all frequencies in the range around zero Hz @ math.ceil(N_freq/2)
1126 sum over all frequencies in the range around zero Hz @ math.ceil(N_freq/2)
1109 '''
1127 '''
1110 N_freq = numpy.count_nonzero(~numpy.isnan(spc[i,:]))
1128 N_freq = numpy.count_nonzero(~numpy.isnan(spc[i,:]))
1111 count_limit_int = int(math.ceil( count_limit_freq / numpy.max(xFrec) * (N_freq / 2) )) # gives integer point
1129 count_limit_int = int(math.ceil( count_limit_freq / numpy.max(xFrec) * (N_freq / 2) )) # gives integer point
1112 sum_wind = numpy.nansum( spc[i, (math.ceil(N_freq/2) - count_limit_int) : (math.ceil(N_freq / 2) + count_limit_int)] ) #N_freq/2 is where frequency (velocity) is zero, i.e. middle of spectrum.
1130 sum_wind = numpy.nansum( spc[i, (math.ceil(N_freq/2) - count_limit_int) : (math.ceil(N_freq / 2) + count_limit_int)] ) #N_freq/2 is where frequency (velocity) is zero, i.e. middle of spectrum.
1113 sum_noise = (numpy.mean(spc[i, :4]) + numpy.mean(spc[i, -6:-2]))/2.0 * (N_freq - 2*count_limit_int)
1131 sum_noise = (numpy.mean(spc[i, :4]) + numpy.mean(spc[i, -6:-2]))/2.0 * (N_freq - 2*count_limit_int)
1114 channel_integrals[i] = (sum_noise + sum_wind) * (2*numpy.max(xFrec) / N_freq)
1132 channel_integrals[i] = (sum_noise + sum_wind) * (2*numpy.max(xFrec) / N_freq)
1115
1133
1116
1134
1117 cross_integrals_peak = numpy.zeros(3)
1135 cross_integrals_peak = numpy.zeros(3)
1118 # cross_integrals_totalrange = numpy.zeros(3)
1136 # cross_integrals_totalrange = numpy.zeros(3)
@@ -1125,45 +1143,45 class FullSpectralAnalysis(Operation):
1125 chan_index1 = pairsList[i][1]
1143 chan_index1 = pairsList[i][1]
1126
1144
1127 cross_integrals_peak[i] = channel_integrals[chan_index0]*channel_integrals[chan_index1]
1145 cross_integrals_peak[i] = channel_integrals[chan_index0]*channel_integrals[chan_index1]
1128 normalized_cspc = cspc_norm / numpy.sqrt(cross_integrals_peak[i])
1146 normalized_cspc = cspc_norm / numpy.sqrt(cross_integrals_peak[i])
1129 CSPC_Samples[i] = normalized_cspc
1147 CSPC_Samples[i] = normalized_cspc
1130
1148
1131 ''' Finding cross integrals without subtracting any peaks:'''
1149 ''' Finding cross integrals without subtracting any peaks:'''
1132 # FactorNorm0 = 2*numpy.max(xFrec) / numpy.count_nonzero(~numpy.isnan(spc[chan_index0,:]))
1150 # FactorNorm0 = 2*numpy.max(xFrec) / numpy.count_nonzero(~numpy.isnan(spc[chan_index0,:]))
1133 # FactorNorm1 = 2*numpy.max(xFrec) / numpy.count_nonzero(~numpy.isnan(spc[chan_index1,:]))
1151 # FactorNorm1 = 2*numpy.max(xFrec) / numpy.count_nonzero(~numpy.isnan(spc[chan_index1,:]))
1134 # cross_integrals_totalrange[i] = (numpy.nansum(spc[chan_index0,:])) * FactorNorm0 * (numpy.nansum(spc[chan_index1,:])) * FactorNorm1
1152 # cross_integrals_totalrange[i] = (numpy.nansum(spc[chan_index0,:])) * FactorNorm0 * (numpy.nansum(spc[chan_index1,:])) * FactorNorm1
1135 # normalized_cspc = cspc_norm / numpy.sqrt(cross_integrals_totalrange[i])
1153 # normalized_cspc = cspc_norm / numpy.sqrt(cross_integrals_totalrange[i])
1136 # CSPC_Samples[i] = normalized_cspc
1154 # CSPC_Samples[i] = normalized_cspc
1137
1155
1138
1156
1139 phase[i] = numpy.arctan2(CSPC_Samples[i].imag, CSPC_Samples[i].real)
1157 phase[i] = numpy.arctan2(CSPC_Samples[i].imag, CSPC_Samples[i].real)
1140
1158
1141
1159
1142 CSPCmoments = numpy.vstack([self.Moments(numpy.abs(CSPC_Samples[0]), xSamples),
1160 CSPCmoments = numpy.vstack([self.Moments(numpy.abs(CSPC_Samples[0]), xSamples),
1143 self.Moments(numpy.abs(CSPC_Samples[1]), xSamples),
1161 self.Moments(numpy.abs(CSPC_Samples[1]), xSamples),
1144 self.Moments(numpy.abs(CSPC_Samples[2]), xSamples)])
1162 self.Moments(numpy.abs(CSPC_Samples[2]), xSamples)])
1145
1163
1146
1164
1147 '''***Sorting out NaN entries***'''
1165 '''***Sorting out NaN entries***'''
1148 CSPCMask01 = numpy.abs(CSPC_Samples[0])
1166 CSPCMask01 = numpy.abs(CSPC_Samples[0])
1149 CSPCMask02 = numpy.abs(CSPC_Samples[1])
1167 CSPCMask02 = numpy.abs(CSPC_Samples[1])
1150 CSPCMask12 = numpy.abs(CSPC_Samples[2])
1168 CSPCMask12 = numpy.abs(CSPC_Samples[2])
1151
1169
1152 mask01 = ~numpy.isnan(CSPCMask01)
1170 mask01 = ~numpy.isnan(CSPCMask01)
1153 mask02 = ~numpy.isnan(CSPCMask02)
1171 mask02 = ~numpy.isnan(CSPCMask02)
1154 mask12 = ~numpy.isnan(CSPCMask12)
1172 mask12 = ~numpy.isnan(CSPCMask12)
1155
1173
1156 CSPCMask01 = CSPCMask01[mask01]
1174 CSPCMask01 = CSPCMask01[mask01]
1157 CSPCMask02 = CSPCMask02[mask02]
1175 CSPCMask02 = CSPCMask02[mask02]
1158 CSPCMask12 = CSPCMask12[mask12]
1176 CSPCMask12 = CSPCMask12[mask12]
1159
1177
1160
1178
1161 popt01, popt02, popt12 = [1e-10,1e-10,1e-10], [1e-10,1e-10,1e-10] ,[1e-10,1e-10,1e-10]
1179 popt01, popt02, popt12 = [1e-10,1e-10,1e-10], [1e-10,1e-10,1e-10] ,[1e-10,1e-10,1e-10]
1162 FitGauss01, FitGauss02, FitGauss12 = numpy.empty(len(xSamples))*0, numpy.empty(len(xSamples))*0, numpy.empty(len(xSamples))*0
1180 FitGauss01, FitGauss02, FitGauss12 = numpy.empty(len(xSamples))*0, numpy.empty(len(xSamples))*0, numpy.empty(len(xSamples))*0
1163
1181
1164 '''*******************************FIT GAUSS CSPC************************************'''
1182 '''*******************************FIT GAUSS CSPC************************************'''
1165
1183
1166 try:
1184 try:
1167 popt01,pcov = curve_fit(self.gaus,xSamples[mask01],numpy.abs(CSPCMask01),p0=CSPCmoments[0])
1185 popt01,pcov = curve_fit(self.gaus,xSamples[mask01],numpy.abs(CSPCMask01),p0=CSPCmoments[0])
1168 if popt01[2] > widthlimit: # CONDITION
1186 if popt01[2] > widthlimit: # CONDITION
1169 return self.StopWindEstimation(error_code = 4)
1187 return self.StopWindEstimation(error_code = 4)
@@ -1186,53 +1204,53 class FullSpectralAnalysis(Operation):
1186
1204
1187 '''************* Getting Fij ***************'''
1205 '''************* Getting Fij ***************'''
1188
1206
1189
1207
1190 #Punto en Eje X de la Gaussiana donde se encuentra el centro -- x-axis point of the gaussian where the center is located
1208 #Punto en Eje X de la Gaussiana donde se encuentra el centro -- x-axis point of the gaussian where the center is located
1191 # -> PointGauCenter
1209 # -> PointGauCenter
1192 GaussCenter = popt[1]
1210 GaussCenter = popt[1]
1193 ClosestCenter = xSamples[numpy.abs(xSamples-GaussCenter).argmin()]
1211 ClosestCenter = xSamples[numpy.abs(xSamples-GaussCenter).argmin()]
1194 PointGauCenter = numpy.where(xSamples==ClosestCenter)[0][0]
1212 PointGauCenter = numpy.where(xSamples==ClosestCenter)[0][0]
1195
1213
1196 #Punto e^-1 hubicado en la Gaussiana -- point where e^-1 is located in the gaussian
1214 #Punto e^-1 hubicado en la Gaussiana -- point where e^-1 is located in the gaussian
1197 PeMinus1 = numpy.max(FitGauss) * numpy.exp(-1)
1215 PeMinus1 = numpy.max(FitGauss) * numpy.exp(-1)
1198 FijClosest = FitGauss[numpy.abs(FitGauss-PeMinus1).argmin()] # El punto mas cercano a "Peminus1" dentro de "FitGauss"
1216 FijClosest = FitGauss[numpy.abs(FitGauss-PeMinus1).argmin()] # El punto mas cercano a "Peminus1" dentro de "FitGauss"
1199 PointFij = numpy.where(FitGauss==FijClosest)[0][0]
1217 PointFij = numpy.where(FitGauss==FijClosest)[0][0]
1200
1218
1201 Fij = numpy.abs(xSamples[PointFij] - xSamples[PointGauCenter])
1219 Fij = numpy.abs(xSamples[PointFij] - xSamples[PointGauCenter])
1202
1220
1203 '''********** Taking frequency ranges from mean SPCs **********'''
1221 '''********** Taking frequency ranges from mean SPCs **********'''
1204
1222
1205 #GaussCenter = popt[1] #Primer momento 01
1223 #GaussCenter = popt[1] #Primer momento 01
1206 GauWidth = popt[2] * 3/2 #Ancho de banda de Gau01 -- Bandwidth of Gau01 TODO why *3/2?
1224 GauWidth = popt[2] * 3/2 #Ancho de banda de Gau01 -- Bandwidth of Gau01 TODO why *3/2?
1207 Range = numpy.empty(2)
1225 Range = numpy.empty(2)
1208 Range[0] = GaussCenter - GauWidth
1226 Range[0] = GaussCenter - GauWidth
1209 Range[1] = GaussCenter + GauWidth
1227 Range[1] = GaussCenter + GauWidth
1210 #Punto en Eje X de la Gaussiana donde se encuentra ancho de banda (min:max) -- Point in x-axis where the bandwidth is located (min:max)
1228 #Punto en Eje X de la Gaussiana donde se encuentra ancho de banda (min:max) -- Point in x-axis where the bandwidth is located (min:max)
1211 ClosRangeMin = xSamples[numpy.abs(xSamples-Range[0]).argmin()]
1229 ClosRangeMin = xSamples[numpy.abs(xSamples-Range[0]).argmin()]
1212 ClosRangeMax = xSamples[numpy.abs(xSamples-Range[1]).argmin()]
1230 ClosRangeMax = xSamples[numpy.abs(xSamples-Range[1]).argmin()]
1213
1231
1214 PointRangeMin = numpy.where(xSamples==ClosRangeMin)[0][0]
1232 PointRangeMin = numpy.where(xSamples==ClosRangeMin)[0][0]
1215 PointRangeMax = numpy.where(xSamples==ClosRangeMax)[0][0]
1233 PointRangeMax = numpy.where(xSamples==ClosRangeMax)[0][0]
1216
1234
1217 Range = numpy.array([ PointRangeMin, PointRangeMax ])
1235 Range = numpy.array([ PointRangeMin, PointRangeMax ])
1218
1236
1219 FrecRange = xFrec[ Range[0] : Range[1] ]
1237 FrecRange = xFrec[ Range[0] : Range[1] ]
1220
1238
1221
1239
1222 '''************************** Getting Phase Slope ***************************'''
1240 '''************************** Getting Phase Slope ***************************'''
1223
1241
1224 for i in range(1,3): # Changed to only compute two
1242 for i in range(1,3): # Changed to only compute two
1225
1243
1226 if len(FrecRange) > 5 and len(FrecRange) < spc.shape[1] * 0.3:
1244 if len(FrecRange) > 5 and len(FrecRange) < spc.shape[1] * 0.3:
1227 # PhaseRange=self.moving_average(phase[i,Range[0]:Range[1]],N=1) #used before to smooth phase with N=3
1245 # PhaseRange=self.moving_average(phase[i,Range[0]:Range[1]],N=1) #used before to smooth phase with N=3
1228 PhaseRange = phase[i,Range[0]:Range[1]].copy()
1246 PhaseRange = phase[i,Range[0]:Range[1]].copy()
1229
1247
1230 mask = ~numpy.isnan(FrecRange) & ~numpy.isnan(PhaseRange)
1248 mask = ~numpy.isnan(FrecRange) & ~numpy.isnan(PhaseRange)
1231
1249
1232
1250
1233 if len(FrecRange) == len(PhaseRange):
1251 if len(FrecRange) == len(PhaseRange):
1234
1252
1235 try:
1253 try:
1236 slope, intercept, _, _, _ = stats.linregress(FrecRange[mask], self.AntiAliasing(PhaseRange[mask], 4.5))
1254 slope, intercept, _, _, _ = stats.linregress(FrecRange[mask], self.AntiAliasing(PhaseRange[mask], 4.5))
1237 PhaseSlope[i] = slope
1255 PhaseSlope[i] = slope
1238 PhaseInter[i] = intercept
1256 PhaseInter[i] = intercept
@@ -1242,49 +1260,49 class FullSpectralAnalysis(Operation):
1242
1260
1243 else:
1261 else:
1244 return self.StopWindEstimation(error_code = 7)
1262 return self.StopWindEstimation(error_code = 7)
1245
1263
1246 else:
1264 else:
1247 return self.StopWindEstimation(error_code = 8)
1265 return self.StopWindEstimation(error_code = 8)
1248
1266
1249
1267
1250
1268
1251 '''*** Constants A-H correspond to the convention as in Briggs and Vincent 1992 ***'''
1269 '''*** Constants A-H correspond to the convention as in Briggs and Vincent 1992 ***'''
1252
1270
1253 '''Getting constant C'''
1271 '''Getting constant C'''
1254 cC=(Fij*numpy.pi)**2
1272 cC=(Fij*numpy.pi)**2
1255
1273
1256 '''****** Getting constants F and G ******'''
1274 '''****** Getting constants F and G ******'''
1257 MijEijNij = numpy.array([[Xi02,Eta02], [Xi12,Eta12]])
1275 MijEijNij = numpy.array([[Xi02,Eta02], [Xi12,Eta12]])
1258 MijResult0 = (-PhaseSlope[1] * cC) / (2*numpy.pi)
1276 MijResult0 = (-PhaseSlope[1] * cC) / (2*numpy.pi)
1259 MijResult1 = (-PhaseSlope[2] * cC) / (2*numpy.pi)
1277 MijResult1 = (-PhaseSlope[2] * cC) / (2*numpy.pi)
1260 MijResults = numpy.array([MijResult0,MijResult1])
1278 MijResults = numpy.array([MijResult0,MijResult1])
1261 (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults)
1279 (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults)
1262
1280
1263 '''****** Getting constants A, B and H ******'''
1281 '''****** Getting constants A, B and H ******'''
1264 W01 = numpy.nanmax( FitGauss01 )
1282 W01 = numpy.nanmax( FitGauss01 )
1265 W02 = numpy.nanmax( FitGauss02 )
1283 W02 = numpy.nanmax( FitGauss02 )
1266 W12 = numpy.nanmax( FitGauss12 )
1284 W12 = numpy.nanmax( FitGauss12 )
1267
1285
1268 WijResult0 = ((cF * Xi01 + cG * Eta01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi / cC))
1286 WijResult0 = ((cF * Xi01 + cG * Eta01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi / cC))
1269 WijResult1 = ((cF * Xi02 + cG * Eta02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi / cC))
1287 WijResult1 = ((cF * Xi02 + cG * Eta02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi / cC))
1270 WijResult2 = ((cF * Xi12 + cG * Eta12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi / cC))
1288 WijResult2 = ((cF * Xi12 + cG * Eta12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi / cC))
1271
1289
1272 WijResults = numpy.array([WijResult0, WijResult1, WijResult2])
1290 WijResults = numpy.array([WijResult0, WijResult1, WijResult2])
1273
1291
1274 WijEijNij = numpy.array([ [Xi01**2, Eta01**2, 2*Xi01*Eta01] , [Xi02**2, Eta02**2, 2*Xi02*Eta02] , [Xi12**2, Eta12**2, 2*Xi12*Eta12] ])
1292 WijEijNij = numpy.array([ [Xi01**2, Eta01**2, 2*Xi01*Eta01] , [Xi02**2, Eta02**2, 2*Xi02*Eta02] , [Xi12**2, Eta12**2, 2*Xi12*Eta12] ])
1275 (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults)
1293 (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults)
1276
1294
1277 VxVy = numpy.array([[cA,cH],[cH,cB]])
1295 VxVy = numpy.array([[cA,cH],[cH,cB]])
1278 VxVyResults = numpy.array([-cF,-cG])
1296 VxVyResults = numpy.array([-cF,-cG])
1279 (Vx,Vy) = numpy.linalg.solve(VxVy, VxVyResults)
1297 (Vx,Vy) = numpy.linalg.solve(VxVy, VxVyResults)
1280
1298
1281 Vzon = Vy
1299 Vzon = Vy
1282 Vmer = Vx
1300 Vmer = Vx
1283
1301
1284 # Vmag=numpy.sqrt(Vzon**2+Vmer**2) # unused
1302 # Vmag=numpy.sqrt(Vzon**2+Vmer**2) # unused
1285 # Vang=numpy.arctan2(Vmer,Vzon) # unused
1303 # Vang=numpy.arctan2(Vmer,Vzon) # unused
1286
1304
1287
1305
1288 ''' using frequency as abscissa. Due to three channels, the offzenith angle is zero
1306 ''' using frequency as abscissa. Due to three channels, the offzenith angle is zero
1289 and Vrad equal to Vver. formula taken from Briggs 92, figure 4.
1307 and Vrad equal to Vver. formula taken from Briggs 92, figure 4.
1290 '''
1308 '''
@@ -1295,62 +1313,62 class FullSpectralAnalysis(Operation):
1295
1313
1296 error_code = 0
1314 error_code = 0
1297
1315
1298 return Vzon, Vmer, Vver, error_code
1316 return Vzon, Vmer, Vver, error_code
1299
1317
1300
1318
1301 class SpectralMoments(Operation):
1319 class SpectralMoments(Operation):
1302
1320
1303 '''
1321 '''
1304 Function SpectralMoments()
1322 Function SpectralMoments()
1305
1323
1306 Calculates moments (power, mean, standard deviation) and SNR of the signal
1324 Calculates moments (power, mean, standard deviation) and SNR of the signal
1307
1325
1308 Type of dataIn: Spectra
1326 Type of dataIn: Spectra
1309
1327
1310 Configuration Parameters:
1328 Configuration Parameters:
1311
1329
1312 dirCosx : Cosine director in X axis
1330 dirCosx : Cosine director in X axis
1313 dirCosy : Cosine director in Y axis
1331 dirCosy : Cosine director in Y axis
1314
1332
1315 elevation :
1333 elevation :
1316 azimuth :
1334 azimuth :
1317
1335
1318 Input:
1336 Input:
1319 channelList : simple channel list to select e.g. [2,3,7]
1337 channelList : simple channel list to select e.g. [2,3,7]
1320 self.dataOut.data_pre : Spectral data
1338 self.dataOut.data_pre : Spectral data
1321 self.dataOut.abscissaList : List of frequencies
1339 self.dataOut.abscissaList : List of frequencies
1322 self.dataOut.noise : Noise level per channel
1340 self.dataOut.noise : Noise level per channel
1323
1341
1324 Affected:
1342 Affected:
1325 self.dataOut.moments : Parameters per channel
1343 self.dataOut.moments : Parameters per channel
1326 self.dataOut.data_SNR : SNR per channel
1344 self.dataOut.data_SNR : SNR per channel
1327
1345
1328 '''
1346 '''
1329
1347
1330 def run(self, dataOut):
1348 def run(self, dataOut):
1331
1349
1332 #dataOut.data_pre = dataOut.data_pre[0]
1350 #dataOut.data_pre = dataOut.data_pre[0]
1333 data = dataOut.data_pre[0]
1351 data = dataOut.data_pre[0]
1334 absc = dataOut.abscissaList[:-1]
1352 absc = dataOut.abscissaList[:-1]
1335 noise = dataOut.noise
1353 noise = dataOut.noise
1336 nChannel = data.shape[0]
1354 nChannel = data.shape[0]
1337 data_param = numpy.zeros((nChannel, 4, data.shape[2]))
1355 data_param = numpy.zeros((nChannel, 4, data.shape[2]))
1338
1356
1339 for ind in range(nChannel):
1357 for ind in range(nChannel):
1340 data_param[ind,:,:] = self.__calculateMoments( data[ind,:,:] , absc , noise[ind] )
1358 data_param[ind,:,:] = self.__calculateMoments( data[ind,:,:] , absc , noise[ind] )
1341
1359
1342 dataOut.moments = data_param[:,1:,:]
1360 dataOut.moments = data_param[:,1:,:]
1343 dataOut.data_SNR = data_param[:,0]
1361 dataOut.data_SNR = data_param[:,0]
1344 dataOut.data_POW = data_param[:,1]
1362 dataOut.data_POW = data_param[:,1]
1345 dataOut.data_DOP = data_param[:,2]
1363 dataOut.data_DOP = data_param[:,2]
1346 dataOut.data_WIDTH = data_param[:,3]
1364 dataOut.data_WIDTH = data_param[:,3]
1347 return dataOut
1365 return dataOut
1348
1366
1349 def __calculateMoments(self, oldspec, oldfreq, n0,
1367 def __calculateMoments(self, oldspec, oldfreq, n0,
1350 nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
1368 nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
1351
1369
1352 if (nicoh is None): nicoh = 1
1370 if (nicoh is None): nicoh = 1
1353 if (graph is None): graph = 0
1371 if (graph is None): graph = 0
1354 if (smooth is None): smooth = 0
1372 if (smooth is None): smooth = 0
1355 elif (self.smooth < 3): smooth = 0
1373 elif (self.smooth < 3): smooth = 0
1356
1374
@@ -1361,98 +1379,98 class SpectralMoments(Operation):
1361 if (aliasing is None): aliasing = 0
1379 if (aliasing is None): aliasing = 0
1362 if (oldfd is None): oldfd = 0
1380 if (oldfd is None): oldfd = 0
1363 if (wwauto is None): wwauto = 0
1381 if (wwauto is None): wwauto = 0
1364
1382
1365 if (n0 < 1.e-20): n0 = 1.e-20
1383 if (n0 < 1.e-20): n0 = 1.e-20
1366
1384
1367 freq = oldfreq
1385 freq = oldfreq
1368 vec_power = numpy.zeros(oldspec.shape[1])
1386 vec_power = numpy.zeros(oldspec.shape[1])
1369 vec_fd = numpy.zeros(oldspec.shape[1])
1387 vec_fd = numpy.zeros(oldspec.shape[1])
1370 vec_w = numpy.zeros(oldspec.shape[1])
1388 vec_w = numpy.zeros(oldspec.shape[1])
1371 vec_snr = numpy.zeros(oldspec.shape[1])
1389 vec_snr = numpy.zeros(oldspec.shape[1])
1372
1390
1373 oldspec = numpy.ma.masked_invalid(oldspec)
1391 oldspec = numpy.ma.masked_invalid(oldspec)
1374
1392
1375 for ind in range(oldspec.shape[1]):
1393 for ind in range(oldspec.shape[1]):
1376
1394
1377 spec = oldspec[:,ind]
1395 spec = oldspec[:,ind]
1378 aux = spec*fwindow
1396 aux = spec*fwindow
1379 max_spec = aux.max()
1397 max_spec = aux.max()
1380 m = list(aux).index(max_spec)
1398 m = list(aux).index(max_spec)
1381
1399
1382 #Smooth
1400 #Smooth
1383 if (smooth == 0): spec2 = spec
1401 if (smooth == 0): spec2 = spec
1384 else: spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
1402 else: spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
1385
1403
1386 # Calculo de Momentos
1404 # Calculo de Momentos
1387 bb = spec2[list(range(m,spec2.size))]
1405 bb = spec2[list(range(m,spec2.size))]
1388 bb = (bb<n0).nonzero()
1406 bb = (bb<n0).nonzero()
1389 bb = bb[0]
1407 bb = bb[0]
1390
1408
1391 ss = spec2[list(range(0,m + 1))]
1409 ss = spec2[list(range(0,m + 1))]
1392 ss = (ss<n0).nonzero()
1410 ss = (ss<n0).nonzero()
1393 ss = ss[0]
1411 ss = ss[0]
1394
1412
1395 if (bb.size == 0):
1413 if (bb.size == 0):
1396 bb0 = spec.size - 1 - m
1414 bb0 = spec.size - 1 - m
1397 else:
1415 else:
1398 bb0 = bb[0] - 1
1416 bb0 = bb[0] - 1
1399 if (bb0 < 0):
1417 if (bb0 < 0):
1400 bb0 = 0
1418 bb0 = 0
1401
1419
1402 if (ss.size == 0): ss1 = 1
1420 if (ss.size == 0): ss1 = 1
1403 else: ss1 = max(ss) + 1
1421 else: ss1 = max(ss) + 1
1404
1422
1405 if (ss1 > m): ss1 = m
1423 if (ss1 > m): ss1 = m
1406
1424
1407 valid = numpy.asarray(list(range(int(m + bb0 - ss1 + 1)))) + ss1
1425 valid = numpy.asarray(list(range(int(m + bb0 - ss1 + 1)))) + ss1
1408 power = ((spec2[valid] - n0)*fwindow[valid]).sum()
1426 power = ((spec2[valid] - n0)*fwindow[valid]).sum()
1409 fd = ((spec2[valid]- n0)*freq[valid]*fwindow[valid]).sum()/power
1427 fd = ((spec2[valid]- n0)*freq[valid]*fwindow[valid]).sum()/power
1410 w = math.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum()/power)
1428 w = math.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum()/power)
1411 snr = (spec2.mean()-n0)/n0
1429 snr = (spec2.mean()-n0)/n0
1412
1430
1413 if (snr < 1.e-20) :
1431 if (snr < 1.e-20) :
1414 snr = 1.e-20
1432 snr = 1.e-20
1415
1433
1416 vec_power[ind] = power
1434 vec_power[ind] = power
1417 vec_fd[ind] = fd
1435 vec_fd[ind] = fd
1418 vec_w[ind] = w
1436 vec_w[ind] = w
1419 vec_snr[ind] = snr
1437 vec_snr[ind] = snr
1420
1438
1421 moments = numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
1439 moments = numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
1422 return moments
1440 return moments
1423
1441
1424 #------------------ Get SA Parameters --------------------------
1442 #------------------ Get SA Parameters --------------------------
1425
1443
1426 def GetSAParameters(self):
1444 def GetSAParameters(self):
1427 #SA en frecuencia
1445 #SA en frecuencia
1428 pairslist = self.dataOut.groupList
1446 pairslist = self.dataOut.groupList
1429 num_pairs = len(pairslist)
1447 num_pairs = len(pairslist)
1430
1448
1431 vel = self.dataOut.abscissaList
1449 vel = self.dataOut.abscissaList
1432 spectra = self.dataOut.data_pre
1450 spectra = self.dataOut.data_pre
1433 cspectra = self.dataIn.data_cspc
1451 cspectra = self.dataIn.data_cspc
1434 delta_v = vel[1] - vel[0]
1452 delta_v = vel[1] - vel[0]
1435
1453
1436 #Calculating the power spectrum
1454 #Calculating the power spectrum
1437 spc_pow = numpy.sum(spectra, 3)*delta_v
1455 spc_pow = numpy.sum(spectra, 3)*delta_v
1438 #Normalizing Spectra
1456 #Normalizing Spectra
1439 norm_spectra = spectra/spc_pow
1457 norm_spectra = spectra/spc_pow
1440 #Calculating the norm_spectra at peak
1458 #Calculating the norm_spectra at peak
1441 max_spectra = numpy.max(norm_spectra, 3)
1459 max_spectra = numpy.max(norm_spectra, 3)
1442
1460
1443 #Normalizing Cross Spectra
1461 #Normalizing Cross Spectra
1444 norm_cspectra = numpy.zeros(cspectra.shape)
1462 norm_cspectra = numpy.zeros(cspectra.shape)
1445
1463
1446 for i in range(num_chan):
1464 for i in range(num_chan):
1447 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
1465 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
1448
1466
1449 max_cspectra = numpy.max(norm_cspectra,2)
1467 max_cspectra = numpy.max(norm_cspectra,2)
1450 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
1468 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
1451
1469
1452 for i in range(num_pairs):
1470 for i in range(num_pairs):
1453 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
1471 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
1454 #------------------- Get Lags ----------------------------------
1472 #------------------- Get Lags ----------------------------------
1455
1473
1456 class SALags(Operation):
1474 class SALags(Operation):
1457 '''
1475 '''
1458 Function GetMoments()
1476 Function GetMoments()
@@ -1465,19 +1483,19 class SALags(Operation):
1465 self.dataOut.data_SNR
1483 self.dataOut.data_SNR
1466 self.dataOut.groupList
1484 self.dataOut.groupList
1467 self.dataOut.nChannels
1485 self.dataOut.nChannels
1468
1486
1469 Affected:
1487 Affected:
1470 self.dataOut.data_param
1488 self.dataOut.data_param
1471
1489
1472 '''
1490 '''
1473 def run(self, dataOut):
1491 def run(self, dataOut):
1474 data_acf = dataOut.data_pre[0]
1492 data_acf = dataOut.data_pre[0]
1475 data_ccf = dataOut.data_pre[1]
1493 data_ccf = dataOut.data_pre[1]
1476 normFactor_acf = dataOut.normFactor[0]
1494 normFactor_acf = dataOut.normFactor[0]
1477 normFactor_ccf = dataOut.normFactor[1]
1495 normFactor_ccf = dataOut.normFactor[1]
1478 pairs_acf = dataOut.groupList[0]
1496 pairs_acf = dataOut.groupList[0]
1479 pairs_ccf = dataOut.groupList[1]
1497 pairs_ccf = dataOut.groupList[1]
1480
1498
1481 nHeights = dataOut.nHeights
1499 nHeights = dataOut.nHeights
1482 absc = dataOut.abscissaList
1500 absc = dataOut.abscissaList
1483 noise = dataOut.noise
1501 noise = dataOut.noise
@@ -1488,97 +1506,97 class SALags(Operation):
1488
1506
1489 for l in range(len(pairs_acf)):
1507 for l in range(len(pairs_acf)):
1490 data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
1508 data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
1491
1509
1492 for l in range(len(pairs_ccf)):
1510 for l in range(len(pairs_ccf)):
1493 data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
1511 data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
1494
1512
1495 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
1513 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
1496 dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
1514 dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
1497 dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
1515 dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
1498 return
1516 return
1499
1517
1500 # def __getPairsAutoCorr(self, pairsList, nChannels):
1518 # def __getPairsAutoCorr(self, pairsList, nChannels):
1501 #
1519 #
1502 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1520 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1503 #
1521 #
1504 # for l in range(len(pairsList)):
1522 # for l in range(len(pairsList)):
1505 # firstChannel = pairsList[l][0]
1523 # firstChannel = pairsList[l][0]
1506 # secondChannel = pairsList[l][1]
1524 # secondChannel = pairsList[l][1]
1507 #
1525 #
1508 # #Obteniendo pares de Autocorrelacion
1526 # #Obteniendo pares de Autocorrelacion
1509 # if firstChannel == secondChannel:
1527 # if firstChannel == secondChannel:
1510 # pairsAutoCorr[firstChannel] = int(l)
1528 # pairsAutoCorr[firstChannel] = int(l)
1511 #
1529 #
1512 # pairsAutoCorr = pairsAutoCorr.astype(int)
1530 # pairsAutoCorr = pairsAutoCorr.astype(int)
1513 #
1531 #
1514 # pairsCrossCorr = range(len(pairsList))
1532 # pairsCrossCorr = range(len(pairsList))
1515 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1533 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1516 #
1534 #
1517 # return pairsAutoCorr, pairsCrossCorr
1535 # return pairsAutoCorr, pairsCrossCorr
1518
1536
1519 def __calculateTaus(self, data_acf, data_ccf, lagRange):
1537 def __calculateTaus(self, data_acf, data_ccf, lagRange):
1520
1538
1521 lag0 = data_acf.shape[1]/2
1539 lag0 = data_acf.shape[1]/2
1522 #Funcion de Autocorrelacion
1540 #Funcion de Autocorrelacion
1523 mean_acf = stats.nanmean(data_acf, axis = 0)
1541 mean_acf = stats.nanmean(data_acf, axis = 0)
1524
1542
1525 #Obtencion Indice de TauCross
1543 #Obtencion Indice de TauCross
1526 ind_ccf = data_ccf.argmax(axis = 1)
1544 ind_ccf = data_ccf.argmax(axis = 1)
1527 #Obtencion Indice de TauAuto
1545 #Obtencion Indice de TauAuto
1528 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
1546 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
1529 ccf_lag0 = data_ccf[:,lag0,:]
1547 ccf_lag0 = data_ccf[:,lag0,:]
1530
1548
1531 for i in range(ccf_lag0.shape[0]):
1549 for i in range(ccf_lag0.shape[0]):
1532 ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
1550 ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
1533
1551
1534 #Obtencion de TauCross y TauAuto
1552 #Obtencion de TauCross y TauAuto
1535 tau_ccf = lagRange[ind_ccf]
1553 tau_ccf = lagRange[ind_ccf]
1536 tau_acf = lagRange[ind_acf]
1554 tau_acf = lagRange[ind_acf]
1537
1555
1538 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
1556 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
1539
1557
1540 tau_ccf[Nan1,Nan2] = numpy.nan
1558 tau_ccf[Nan1,Nan2] = numpy.nan
1541 tau_acf[Nan1,Nan2] = numpy.nan
1559 tau_acf[Nan1,Nan2] = numpy.nan
1542 tau = numpy.vstack((tau_ccf,tau_acf))
1560 tau = numpy.vstack((tau_ccf,tau_acf))
1543
1561
1544 return tau
1562 return tau
1545
1563
1546 def __calculateLag1Phase(self, data, lagTRange):
1564 def __calculateLag1Phase(self, data, lagTRange):
1547 data1 = stats.nanmean(data, axis = 0)
1565 data1 = stats.nanmean(data, axis = 0)
1548 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
1566 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
1549
1567
1550 phase = numpy.angle(data1[lag1,:])
1568 phase = numpy.angle(data1[lag1,:])
1551
1569
1552 return phase
1570 return phase
1553
1571
1554 class SpectralFitting(Operation):
1572 class SpectralFitting(Operation):
1555 '''
1573 '''
1556 Function GetMoments()
1574 Function GetMoments()
1557
1575
1558 Input:
1576 Input:
1559 Output:
1577 Output:
1560 Variables modified:
1578 Variables modified:
1561 '''
1579 '''
1562
1580
1563 def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
1581 def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
1564
1582
1565
1583
1566 if path != None:
1584 if path != None:
1567 sys.path.append(path)
1585 sys.path.append(path)
1568 self.dataOut.library = importlib.import_module(file)
1586 self.dataOut.library = importlib.import_module(file)
1569
1587
1570 #To be inserted as a parameter
1588 #To be inserted as a parameter
1571 groupArray = numpy.array(groupList)
1589 groupArray = numpy.array(groupList)
1572 # groupArray = numpy.array([[0,1],[2,3]])
1590 # groupArray = numpy.array([[0,1],[2,3]])
1573 self.dataOut.groupList = groupArray
1591 self.dataOut.groupList = groupArray
1574
1592
1575 nGroups = groupArray.shape[0]
1593 nGroups = groupArray.shape[0]
1576 nChannels = self.dataIn.nChannels
1594 nChannels = self.dataIn.nChannels
1577 nHeights=self.dataIn.heightList.size
1595 nHeights=self.dataIn.heightList.size
1578
1596
1579 #Parameters Array
1597 #Parameters Array
1580 self.dataOut.data_param = None
1598 self.dataOut.data_param = None
1581
1599
1582 #Set constants
1600 #Set constants
1583 constants = self.dataOut.library.setConstants(self.dataIn)
1601 constants = self.dataOut.library.setConstants(self.dataIn)
1584 self.dataOut.constants = constants
1602 self.dataOut.constants = constants
@@ -1587,24 +1605,24 class SpectralFitting(Operation):
1587 ippSeconds = self.dataIn.ippSeconds
1605 ippSeconds = self.dataIn.ippSeconds
1588 K = self.dataIn.nIncohInt
1606 K = self.dataIn.nIncohInt
1589 pairsArray = numpy.array(self.dataIn.pairsList)
1607 pairsArray = numpy.array(self.dataIn.pairsList)
1590
1608
1591 #List of possible combinations
1609 #List of possible combinations
1592 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1610 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1593 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1611 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1594
1612
1595 if getSNR:
1613 if getSNR:
1596 listChannels = groupArray.reshape((groupArray.size))
1614 listChannels = groupArray.reshape((groupArray.size))
1597 listChannels.sort()
1615 listChannels.sort()
1598 noise = self.dataIn.getNoise()
1616 noise = self.dataIn.getNoise()
1599 self.dataOut.data_SNR = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1617 self.dataOut.data_SNR = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1600
1618
1601 for i in range(nGroups):
1619 for i in range(nGroups):
1602 coord = groupArray[i,:]
1620 coord = groupArray[i,:]
1603
1621
1604 #Input data array
1622 #Input data array
1605 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1623 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1606 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1624 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1607
1625
1608 #Cross Spectra data array for Covariance Matrixes
1626 #Cross Spectra data array for Covariance Matrixes
1609 ind = 0
1627 ind = 0
1610 for pairs in listComb:
1628 for pairs in listComb:
@@ -1613,9 +1631,9 class SpectralFitting(Operation):
1613 ind += 1
1631 ind += 1
1614 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1632 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1615 dataCross = dataCross**2/K
1633 dataCross = dataCross**2/K
1616
1634
1617 for h in range(nHeights):
1635 for h in range(nHeights):
1618
1636
1619 #Input
1637 #Input
1620 d = data[:,h]
1638 d = data[:,h]
1621
1639
@@ -1624,7 +1642,7 class SpectralFitting(Operation):
1624 ind = 0
1642 ind = 0
1625 for pairs in listComb:
1643 for pairs in listComb:
1626 #Coordinates in Covariance Matrix
1644 #Coordinates in Covariance Matrix
1627 x = pairs[0]
1645 x = pairs[0]
1628 y = pairs[1]
1646 y = pairs[1]
1629 #Channel Index
1647 #Channel Index
1630 S12 = dataCross[ind,:,h]
1648 S12 = dataCross[ind,:,h]
@@ -1638,15 +1656,15 class SpectralFitting(Operation):
1638 LT=L.T
1656 LT=L.T
1639
1657
1640 dp = numpy.dot(LT,d)
1658 dp = numpy.dot(LT,d)
1641
1659
1642 #Initial values
1660 #Initial values
1643 data_spc = self.dataIn.data_spc[coord,:,h]
1661 data_spc = self.dataIn.data_spc[coord,:,h]
1644
1662
1645 if (h>0)and(error1[3]<5):
1663 if (h>0)and(error1[3]<5):
1646 p0 = self.dataOut.data_param[i,:,h-1]
1664 p0 = self.dataOut.data_param[i,:,h-1]
1647 else:
1665 else:
1648 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1666 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1649
1667
1650 try:
1668 try:
1651 #Least Squares
1669 #Least Squares
1652 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
1670 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
@@ -1659,30 +1677,30 class SpectralFitting(Operation):
1659 minp = p0*numpy.nan
1677 minp = p0*numpy.nan
1660 error0 = numpy.nan
1678 error0 = numpy.nan
1661 error1 = p0*numpy.nan
1679 error1 = p0*numpy.nan
1662
1680
1663 #Save
1681 #Save
1664 if self.dataOut.data_param is None:
1682 if self.dataOut.data_param is None:
1665 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1683 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1666 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1684 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1667
1685
1668 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1686 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1669 self.dataOut.data_param[i,:,h] = minp
1687 self.dataOut.data_param[i,:,h] = minp
1670 return
1688 return
1671
1689
1672 def __residFunction(self, p, dp, LT, constants):
1690 def __residFunction(self, p, dp, LT, constants):
1673
1691
1674 fm = self.dataOut.library.modelFunction(p, constants)
1692 fm = self.dataOut.library.modelFunction(p, constants)
1675 fmp=numpy.dot(LT,fm)
1693 fmp=numpy.dot(LT,fm)
1676
1694
1677 return dp-fmp
1695 return dp-fmp
1678
1696
1679 def __getSNR(self, z, noise):
1697 def __getSNR(self, z, noise):
1680
1698
1681 avg = numpy.average(z, axis=1)
1699 avg = numpy.average(z, axis=1)
1682 SNR = (avg.T-noise)/noise
1700 SNR = (avg.T-noise)/noise
1683 SNR = SNR.T
1701 SNR = SNR.T
1684 return SNR
1702 return SNR
1685
1703
1686 def __chisq(p,chindex,hindex):
1704 def __chisq(p,chindex,hindex):
1687 #similar to Resid but calculates CHI**2
1705 #similar to Resid but calculates CHI**2
1688 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
1706 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
@@ -1690,53 +1708,53 class SpectralFitting(Operation):
1690 fmp=numpy.dot(LT,fm)
1708 fmp=numpy.dot(LT,fm)
1691 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1709 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1692 return chisq
1710 return chisq
1693
1711
1694 class WindProfiler(Operation):
1712 class WindProfiler(Operation):
1695
1713
1696 __isConfig = False
1714 __isConfig = False
1697
1715
1698 __initime = None
1716 __initime = None
1699 __lastdatatime = None
1717 __lastdatatime = None
1700 __integrationtime = None
1718 __integrationtime = None
1701
1719
1702 __buffer = None
1720 __buffer = None
1703
1721
1704 __dataReady = False
1722 __dataReady = False
1705
1723
1706 __firstdata = None
1724 __firstdata = None
1707
1725
1708 n = None
1726 n = None
1709
1727
1710 def __init__(self):
1728 def __init__(self):
1711 Operation.__init__(self)
1729 Operation.__init__(self)
1712
1730
1713 def __calculateCosDir(self, elev, azim):
1731 def __calculateCosDir(self, elev, azim):
1714 zen = (90 - elev)*numpy.pi/180
1732 zen = (90 - elev)*numpy.pi/180
1715 azim = azim*numpy.pi/180
1733 azim = azim*numpy.pi/180
1716 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1734 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1717 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1735 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1718
1736
1719 signX = numpy.sign(numpy.cos(azim))
1737 signX = numpy.sign(numpy.cos(azim))
1720 signY = numpy.sign(numpy.sin(azim))
1738 signY = numpy.sign(numpy.sin(azim))
1721
1739
1722 cosDirX = numpy.copysign(cosDirX, signX)
1740 cosDirX = numpy.copysign(cosDirX, signX)
1723 cosDirY = numpy.copysign(cosDirY, signY)
1741 cosDirY = numpy.copysign(cosDirY, signY)
1724 return cosDirX, cosDirY
1742 return cosDirX, cosDirY
1725
1743
1726 def __calculateAngles(self, theta_x, theta_y, azimuth):
1744 def __calculateAngles(self, theta_x, theta_y, azimuth):
1727
1745
1728 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1746 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1729 zenith_arr = numpy.arccos(dir_cosw)
1747 zenith_arr = numpy.arccos(dir_cosw)
1730 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1748 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1731
1749
1732 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1750 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1733 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1751 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1734
1752
1735 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1753 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1736
1754
1737 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1755 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1738
1756
1739 #
1757 #
1740 if horOnly:
1758 if horOnly:
1741 A = numpy.c_[dir_cosu,dir_cosv]
1759 A = numpy.c_[dir_cosu,dir_cosv]
1742 else:
1760 else:
@@ -1750,37 +1768,37 class WindProfiler(Operation):
1750 listPhi = phi.tolist()
1768 listPhi = phi.tolist()
1751 maxid = listPhi.index(max(listPhi))
1769 maxid = listPhi.index(max(listPhi))
1752 minid = listPhi.index(min(listPhi))
1770 minid = listPhi.index(min(listPhi))
1753
1771
1754 rango = list(range(len(phi)))
1772 rango = list(range(len(phi)))
1755 # rango = numpy.delete(rango,maxid)
1773 # rango = numpy.delete(rango,maxid)
1756
1774
1757 heiRang1 = heiRang*math.cos(phi[maxid])
1775 heiRang1 = heiRang*math.cos(phi[maxid])
1758 heiRangAux = heiRang*math.cos(phi[minid])
1776 heiRangAux = heiRang*math.cos(phi[minid])
1759 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1777 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1760 heiRang1 = numpy.delete(heiRang1,indOut)
1778 heiRang1 = numpy.delete(heiRang1,indOut)
1761
1779
1762 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1780 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1763 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1781 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1764
1782
1765 for i in rango:
1783 for i in rango:
1766 x = heiRang*math.cos(phi[i])
1784 x = heiRang*math.cos(phi[i])
1767 y1 = velRadial[i,:]
1785 y1 = velRadial[i,:]
1768 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1786 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1769
1787
1770 x1 = heiRang1
1788 x1 = heiRang1
1771 y11 = f1(x1)
1789 y11 = f1(x1)
1772
1790
1773 y2 = SNR[i,:]
1791 y2 = SNR[i,:]
1774 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1792 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1775 y21 = f2(x1)
1793 y21 = f2(x1)
1776
1794
1777 velRadial1[i,:] = y11
1795 velRadial1[i,:] = y11
1778 SNR1[i,:] = y21
1796 SNR1[i,:] = y21
1779
1797
1780 return heiRang1, velRadial1, SNR1
1798 return heiRang1, velRadial1, SNR1
1781
1799
1782 def __calculateVelUVW(self, A, velRadial):
1800 def __calculateVelUVW(self, A, velRadial):
1783
1801
1784 #Operacion Matricial
1802 #Operacion Matricial
1785 # velUVW = numpy.zeros((velRadial.shape[1],3))
1803 # velUVW = numpy.zeros((velRadial.shape[1],3))
1786 # for ind in range(velRadial.shape[1]):
1804 # for ind in range(velRadial.shape[1]):
@@ -1788,27 +1806,27 class WindProfiler(Operation):
1788 # velUVW = velUVW.transpose()
1806 # velUVW = velUVW.transpose()
1789 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1807 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1790 velUVW[:,:] = numpy.dot(A,velRadial)
1808 velUVW[:,:] = numpy.dot(A,velRadial)
1791
1809
1792
1810
1793 return velUVW
1811 return velUVW
1794
1812
1795 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1813 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1796
1814
1797 def techniqueDBS(self, kwargs):
1815 def techniqueDBS(self, kwargs):
1798 """
1816 """
1799 Function that implements Doppler Beam Swinging (DBS) technique.
1817 Function that implements Doppler Beam Swinging (DBS) technique.
1800
1818
1801 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1819 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1802 Direction correction (if necessary), Ranges and SNR
1820 Direction correction (if necessary), Ranges and SNR
1803
1821
1804 Output: Winds estimation (Zonal, Meridional and Vertical)
1822 Output: Winds estimation (Zonal, Meridional and Vertical)
1805
1823
1806 Parameters affected: Winds, height range, SNR
1824 Parameters affected: Winds, height range, SNR
1807 """
1825 """
1808 velRadial0 = kwargs['velRadial']
1826 velRadial0 = kwargs['velRadial']
1809 heiRang = kwargs['heightList']
1827 heiRang = kwargs['heightList']
1810 SNR0 = kwargs['SNR']
1828 SNR0 = kwargs['SNR']
1811
1829
1812 if 'dirCosx' in kwargs and 'dirCosy' in kwargs:
1830 if 'dirCosx' in kwargs and 'dirCosy' in kwargs:
1813 theta_x = numpy.array(kwargs['dirCosx'])
1831 theta_x = numpy.array(kwargs['dirCosx'])
1814 theta_y = numpy.array(kwargs['dirCosy'])
1832 theta_y = numpy.array(kwargs['dirCosy'])
@@ -1816,7 +1834,7 class WindProfiler(Operation):
1816 elev = numpy.array(kwargs['elevation'])
1834 elev = numpy.array(kwargs['elevation'])
1817 azim = numpy.array(kwargs['azimuth'])
1835 azim = numpy.array(kwargs['azimuth'])
1818 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1836 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1819 azimuth = kwargs['correctAzimuth']
1837 azimuth = kwargs['correctAzimuth']
1820 if 'horizontalOnly' in kwargs:
1838 if 'horizontalOnly' in kwargs:
1821 horizontalOnly = kwargs['horizontalOnly']
1839 horizontalOnly = kwargs['horizontalOnly']
1822 else: horizontalOnly = False
1840 else: horizontalOnly = False
@@ -1831,22 +1849,22 class WindProfiler(Operation):
1831 param = param[arrayChannel,:,:]
1849 param = param[arrayChannel,:,:]
1832 theta_x = theta_x[arrayChannel]
1850 theta_x = theta_x[arrayChannel]
1833 theta_y = theta_y[arrayChannel]
1851 theta_y = theta_y[arrayChannel]
1834
1852
1835 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
1853 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
1836 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
1854 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
1837 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1855 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1838
1856
1839 #Calculo de Componentes de la velocidad con DBS
1857 #Calculo de Componentes de la velocidad con DBS
1840 winds = self.__calculateVelUVW(A,velRadial1)
1858 winds = self.__calculateVelUVW(A,velRadial1)
1841
1859
1842 return winds, heiRang1, SNR1
1860 return winds, heiRang1, SNR1
1843
1861
1844 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
1862 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
1845
1863
1846 nPairs = len(pairs_ccf)
1864 nPairs = len(pairs_ccf)
1847 posx = numpy.asarray(posx)
1865 posx = numpy.asarray(posx)
1848 posy = numpy.asarray(posy)
1866 posy = numpy.asarray(posy)
1849
1867
1850 #Rotacion Inversa para alinear con el azimuth
1868 #Rotacion Inversa para alinear con el azimuth
1851 if azimuth!= None:
1869 if azimuth!= None:
1852 azimuth = azimuth*math.pi/180
1870 azimuth = azimuth*math.pi/180
@@ -1855,126 +1873,126 class WindProfiler(Operation):
1855 else:
1873 else:
1856 posx1 = posx
1874 posx1 = posx
1857 posy1 = posy
1875 posy1 = posy
1858
1876
1859 #Calculo de Distancias
1877 #Calculo de Distancias
1860 distx = numpy.zeros(nPairs)
1878 distx = numpy.zeros(nPairs)
1861 disty = numpy.zeros(nPairs)
1879 disty = numpy.zeros(nPairs)
1862 dist = numpy.zeros(nPairs)
1880 dist = numpy.zeros(nPairs)
1863 ang = numpy.zeros(nPairs)
1881 ang = numpy.zeros(nPairs)
1864
1882
1865 for i in range(nPairs):
1883 for i in range(nPairs):
1866 distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
1884 distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
1867 disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
1885 disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
1868 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1886 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1869 ang[i] = numpy.arctan2(disty[i],distx[i])
1887 ang[i] = numpy.arctan2(disty[i],distx[i])
1870
1888
1871 return distx, disty, dist, ang
1889 return distx, disty, dist, ang
1872 #Calculo de Matrices
1890 #Calculo de Matrices
1873 # nPairs = len(pairs)
1891 # nPairs = len(pairs)
1874 # ang1 = numpy.zeros((nPairs, 2, 1))
1892 # ang1 = numpy.zeros((nPairs, 2, 1))
1875 # dist1 = numpy.zeros((nPairs, 2, 1))
1893 # dist1 = numpy.zeros((nPairs, 2, 1))
1876 #
1894 #
1877 # for j in range(nPairs):
1895 # for j in range(nPairs):
1878 # dist1[j,0,0] = dist[pairs[j][0]]
1896 # dist1[j,0,0] = dist[pairs[j][0]]
1879 # dist1[j,1,0] = dist[pairs[j][1]]
1897 # dist1[j,1,0] = dist[pairs[j][1]]
1880 # ang1[j,0,0] = ang[pairs[j][0]]
1898 # ang1[j,0,0] = ang[pairs[j][0]]
1881 # ang1[j,1,0] = ang[pairs[j][1]]
1899 # ang1[j,1,0] = ang[pairs[j][1]]
1882 #
1900 #
1883 # return distx,disty, dist1,ang1
1901 # return distx,disty, dist1,ang1
1884
1902
1885
1903
1886 def __calculateVelVer(self, phase, lagTRange, _lambda):
1904 def __calculateVelVer(self, phase, lagTRange, _lambda):
1887
1905
1888 Ts = lagTRange[1] - lagTRange[0]
1906 Ts = lagTRange[1] - lagTRange[0]
1889 velW = -_lambda*phase/(4*math.pi*Ts)
1907 velW = -_lambda*phase/(4*math.pi*Ts)
1890
1908
1891 return velW
1909 return velW
1892
1910
1893 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1911 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1894 nPairs = tau1.shape[0]
1912 nPairs = tau1.shape[0]
1895 nHeights = tau1.shape[1]
1913 nHeights = tau1.shape[1]
1896 vel = numpy.zeros((nPairs,3,nHeights))
1914 vel = numpy.zeros((nPairs,3,nHeights))
1897 dist1 = numpy.reshape(dist, (dist.size,1))
1915 dist1 = numpy.reshape(dist, (dist.size,1))
1898
1916
1899 angCos = numpy.cos(ang)
1917 angCos = numpy.cos(ang)
1900 angSin = numpy.sin(ang)
1918 angSin = numpy.sin(ang)
1901
1919
1902 vel0 = dist1*tau1/(2*tau2**2)
1920 vel0 = dist1*tau1/(2*tau2**2)
1903 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1921 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1904 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1922 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1905
1923
1906 ind = numpy.where(numpy.isinf(vel))
1924 ind = numpy.where(numpy.isinf(vel))
1907 vel[ind] = numpy.nan
1925 vel[ind] = numpy.nan
1908
1926
1909 return vel
1927 return vel
1910
1928
1911 # def __getPairsAutoCorr(self, pairsList, nChannels):
1929 # def __getPairsAutoCorr(self, pairsList, nChannels):
1912 #
1930 #
1913 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1931 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1914 #
1932 #
1915 # for l in range(len(pairsList)):
1933 # for l in range(len(pairsList)):
1916 # firstChannel = pairsList[l][0]
1934 # firstChannel = pairsList[l][0]
1917 # secondChannel = pairsList[l][1]
1935 # secondChannel = pairsList[l][1]
1918 #
1936 #
1919 # #Obteniendo pares de Autocorrelacion
1937 # #Obteniendo pares de Autocorrelacion
1920 # if firstChannel == secondChannel:
1938 # if firstChannel == secondChannel:
1921 # pairsAutoCorr[firstChannel] = int(l)
1939 # pairsAutoCorr[firstChannel] = int(l)
1922 #
1940 #
1923 # pairsAutoCorr = pairsAutoCorr.astype(int)
1941 # pairsAutoCorr = pairsAutoCorr.astype(int)
1924 #
1942 #
1925 # pairsCrossCorr = range(len(pairsList))
1943 # pairsCrossCorr = range(len(pairsList))
1926 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1944 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1927 #
1945 #
1928 # return pairsAutoCorr, pairsCrossCorr
1946 # return pairsAutoCorr, pairsCrossCorr
1929
1947
1930 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1948 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1931 def techniqueSA(self, kwargs):
1949 def techniqueSA(self, kwargs):
1932
1950
1933 """
1951 """
1934 Function that implements Spaced Antenna (SA) technique.
1952 Function that implements Spaced Antenna (SA) technique.
1935
1953
1936 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1954 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1937 Direction correction (if necessary), Ranges and SNR
1955 Direction correction (if necessary), Ranges and SNR
1938
1956
1939 Output: Winds estimation (Zonal, Meridional and Vertical)
1957 Output: Winds estimation (Zonal, Meridional and Vertical)
1940
1958
1941 Parameters affected: Winds
1959 Parameters affected: Winds
1942 """
1960 """
1943 position_x = kwargs['positionX']
1961 position_x = kwargs['positionX']
1944 position_y = kwargs['positionY']
1962 position_y = kwargs['positionY']
1945 azimuth = kwargs['azimuth']
1963 azimuth = kwargs['azimuth']
1946
1964
1947 if 'correctFactor' in kwargs:
1965 if 'correctFactor' in kwargs:
1948 correctFactor = kwargs['correctFactor']
1966 correctFactor = kwargs['correctFactor']
1949 else:
1967 else:
1950 correctFactor = 1
1968 correctFactor = 1
1951
1969
1952 groupList = kwargs['groupList']
1970 groupList = kwargs['groupList']
1953 pairs_ccf = groupList[1]
1971 pairs_ccf = groupList[1]
1954 tau = kwargs['tau']
1972 tau = kwargs['tau']
1955 _lambda = kwargs['_lambda']
1973 _lambda = kwargs['_lambda']
1956
1974
1957 #Cross Correlation pairs obtained
1975 #Cross Correlation pairs obtained
1958 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
1976 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
1959 # pairsArray = numpy.array(pairsList)[pairsCrossCorr]
1977 # pairsArray = numpy.array(pairsList)[pairsCrossCorr]
1960 # pairsSelArray = numpy.array(pairsSelected)
1978 # pairsSelArray = numpy.array(pairsSelected)
1961 # pairs = []
1979 # pairs = []
1962 #
1980 #
1963 # #Wind estimation pairs obtained
1981 # #Wind estimation pairs obtained
1964 # for i in range(pairsSelArray.shape[0]/2):
1982 # for i in range(pairsSelArray.shape[0]/2):
1965 # ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
1983 # ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
1966 # ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
1984 # ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
1967 # pairs.append((ind1,ind2))
1985 # pairs.append((ind1,ind2))
1968
1986
1969 indtau = tau.shape[0]/2
1987 indtau = tau.shape[0]/2
1970 tau1 = tau[:indtau,:]
1988 tau1 = tau[:indtau,:]
1971 tau2 = tau[indtau:-1,:]
1989 tau2 = tau[indtau:-1,:]
1972 # tau1 = tau1[pairs,:]
1990 # tau1 = tau1[pairs,:]
1973 # tau2 = tau2[pairs,:]
1991 # tau2 = tau2[pairs,:]
1974 phase1 = tau[-1,:]
1992 phase1 = tau[-1,:]
1975
1993
1976 #---------------------------------------------------------------------
1994 #---------------------------------------------------------------------
1977 #Metodo Directo
1995 #Metodo Directo
1978 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
1996 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
1979 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
1997 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
1980 winds = stats.nanmean(winds, axis=0)
1998 winds = stats.nanmean(winds, axis=0)
@@ -1990,97 +2008,97 class WindProfiler(Operation):
1990 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
2008 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
1991 winds = correctFactor*winds
2009 winds = correctFactor*winds
1992 return winds
2010 return winds
1993
2011
1994 def __checkTime(self, currentTime, paramInterval, outputInterval):
2012 def __checkTime(self, currentTime, paramInterval, outputInterval):
1995
2013
1996 dataTime = currentTime + paramInterval
2014 dataTime = currentTime + paramInterval
1997 deltaTime = dataTime - self.__initime
2015 deltaTime = dataTime - self.__initime
1998
2016
1999 if deltaTime >= outputInterval or deltaTime < 0:
2017 if deltaTime >= outputInterval or deltaTime < 0:
2000 self.__dataReady = True
2018 self.__dataReady = True
2001 return
2019 return
2002
2020
2003 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
2021 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
2004 '''
2022 '''
2005 Function that implements winds estimation technique with detected meteors.
2023 Function that implements winds estimation technique with detected meteors.
2006
2024
2007 Input: Detected meteors, Minimum meteor quantity to wind estimation
2025 Input: Detected meteors, Minimum meteor quantity to wind estimation
2008
2026
2009 Output: Winds estimation (Zonal and Meridional)
2027 Output: Winds estimation (Zonal and Meridional)
2010
2028
2011 Parameters affected: Winds
2029 Parameters affected: Winds
2012 '''
2030 '''
2013 #Settings
2031 #Settings
2014 nInt = (heightMax - heightMin)/2
2032 nInt = (heightMax - heightMin)/2
2015 nInt = int(nInt)
2033 nInt = int(nInt)
2016 winds = numpy.zeros((2,nInt))*numpy.nan
2034 winds = numpy.zeros((2,nInt))*numpy.nan
2017
2035
2018 #Filter errors
2036 #Filter errors
2019 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
2037 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
2020 finalMeteor = arrayMeteor[error,:]
2038 finalMeteor = arrayMeteor[error,:]
2021
2039
2022 #Meteor Histogram
2040 #Meteor Histogram
2023 finalHeights = finalMeteor[:,2]
2041 finalHeights = finalMeteor[:,2]
2024 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
2042 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
2025 nMeteorsPerI = hist[0]
2043 nMeteorsPerI = hist[0]
2026 heightPerI = hist[1]
2044 heightPerI = hist[1]
2027
2045
2028 #Sort of meteors
2046 #Sort of meteors
2029 indSort = finalHeights.argsort()
2047 indSort = finalHeights.argsort()
2030 finalMeteor2 = finalMeteor[indSort,:]
2048 finalMeteor2 = finalMeteor[indSort,:]
2031
2049
2032 # Calculating winds
2050 # Calculating winds
2033 ind1 = 0
2051 ind1 = 0
2034 ind2 = 0
2052 ind2 = 0
2035
2053
2036 for i in range(nInt):
2054 for i in range(nInt):
2037 nMet = nMeteorsPerI[i]
2055 nMet = nMeteorsPerI[i]
2038 ind1 = ind2
2056 ind1 = ind2
2039 ind2 = ind1 + nMet
2057 ind2 = ind1 + nMet
2040
2058
2041 meteorAux = finalMeteor2[ind1:ind2,:]
2059 meteorAux = finalMeteor2[ind1:ind2,:]
2042
2060
2043 if meteorAux.shape[0] >= meteorThresh:
2061 if meteorAux.shape[0] >= meteorThresh:
2044 vel = meteorAux[:, 6]
2062 vel = meteorAux[:, 6]
2045 zen = meteorAux[:, 4]*numpy.pi/180
2063 zen = meteorAux[:, 4]*numpy.pi/180
2046 azim = meteorAux[:, 3]*numpy.pi/180
2064 azim = meteorAux[:, 3]*numpy.pi/180
2047
2065
2048 n = numpy.cos(zen)
2066 n = numpy.cos(zen)
2049 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
2067 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
2050 # l = m*numpy.tan(azim)
2068 # l = m*numpy.tan(azim)
2051 l = numpy.sin(zen)*numpy.sin(azim)
2069 l = numpy.sin(zen)*numpy.sin(azim)
2052 m = numpy.sin(zen)*numpy.cos(azim)
2070 m = numpy.sin(zen)*numpy.cos(azim)
2053
2071
2054 A = numpy.vstack((l, m)).transpose()
2072 A = numpy.vstack((l, m)).transpose()
2055 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
2073 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
2056 windsAux = numpy.dot(A1, vel)
2074 windsAux = numpy.dot(A1, vel)
2057
2075
2058 winds[0,i] = windsAux[0]
2076 winds[0,i] = windsAux[0]
2059 winds[1,i] = windsAux[1]
2077 winds[1,i] = windsAux[1]
2060
2078
2061 return winds, heightPerI[:-1]
2079 return winds, heightPerI[:-1]
2062
2080
2063 def techniqueNSM_SA(self, **kwargs):
2081 def techniqueNSM_SA(self, **kwargs):
2064 metArray = kwargs['metArray']
2082 metArray = kwargs['metArray']
2065 heightList = kwargs['heightList']
2083 heightList = kwargs['heightList']
2066 timeList = kwargs['timeList']
2084 timeList = kwargs['timeList']
2067
2085
2068 rx_location = kwargs['rx_location']
2086 rx_location = kwargs['rx_location']
2069 groupList = kwargs['groupList']
2087 groupList = kwargs['groupList']
2070 azimuth = kwargs['azimuth']
2088 azimuth = kwargs['azimuth']
2071 dfactor = kwargs['dfactor']
2089 dfactor = kwargs['dfactor']
2072 k = kwargs['k']
2090 k = kwargs['k']
2073
2091
2074 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
2092 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
2075 d = dist*dfactor
2093 d = dist*dfactor
2076 #Phase calculation
2094 #Phase calculation
2077 metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
2095 metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
2078
2096
2079 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
2097 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
2080
2098
2081 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2099 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2082 azimuth1 = azimuth1*numpy.pi/180
2100 azimuth1 = azimuth1*numpy.pi/180
2083
2101
2084 for i in range(heightList.size):
2102 for i in range(heightList.size):
2085 h = heightList[i]
2103 h = heightList[i]
2086 indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
2104 indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
@@ -2093,71 +2111,71 class WindProfiler(Operation):
2093 A = numpy.asmatrix(A)
2111 A = numpy.asmatrix(A)
2094 A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
2112 A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
2095 velHor = numpy.dot(A1,velAux)
2113 velHor = numpy.dot(A1,velAux)
2096
2114
2097 velEst[i,:] = numpy.squeeze(velHor)
2115 velEst[i,:] = numpy.squeeze(velHor)
2098 return velEst
2116 return velEst
2099
2117
2100 def __getPhaseSlope(self, metArray, heightList, timeList):
2118 def __getPhaseSlope(self, metArray, heightList, timeList):
2101 meteorList = []
2119 meteorList = []
2102 #utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
2120 #utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
2103 #Putting back together the meteor matrix
2121 #Putting back together the meteor matrix
2104 utctime = metArray[:,0]
2122 utctime = metArray[:,0]
2105 uniqueTime = numpy.unique(utctime)
2123 uniqueTime = numpy.unique(utctime)
2106
2124
2107 phaseDerThresh = 0.5
2125 phaseDerThresh = 0.5
2108 ippSeconds = timeList[1] - timeList[0]
2126 ippSeconds = timeList[1] - timeList[0]
2109 sec = numpy.where(timeList>1)[0][0]
2127 sec = numpy.where(timeList>1)[0][0]
2110 nPairs = metArray.shape[1] - 6
2128 nPairs = metArray.shape[1] - 6
2111 nHeights = len(heightList)
2129 nHeights = len(heightList)
2112
2130
2113 for t in uniqueTime:
2131 for t in uniqueTime:
2114 metArray1 = metArray[utctime==t,:]
2132 metArray1 = metArray[utctime==t,:]
2115 # phaseDerThresh = numpy.pi/4 #reducir Phase thresh
2133 # phaseDerThresh = numpy.pi/4 #reducir Phase thresh
2116 tmet = metArray1[:,1].astype(int)
2134 tmet = metArray1[:,1].astype(int)
2117 hmet = metArray1[:,2].astype(int)
2135 hmet = metArray1[:,2].astype(int)
2118
2136
2119 metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
2137 metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
2120 metPhase[:,:] = numpy.nan
2138 metPhase[:,:] = numpy.nan
2121 metPhase[:,hmet,tmet] = metArray1[:,6:].T
2139 metPhase[:,hmet,tmet] = metArray1[:,6:].T
2122
2140
2123 #Delete short trails
2141 #Delete short trails
2124 metBool = ~numpy.isnan(metPhase[0,:,:])
2142 metBool = ~numpy.isnan(metPhase[0,:,:])
2125 heightVect = numpy.sum(metBool, axis = 1)
2143 heightVect = numpy.sum(metBool, axis = 1)
2126 metBool[heightVect<sec,:] = False
2144 metBool[heightVect<sec,:] = False
2127 metPhase[:,heightVect<sec,:] = numpy.nan
2145 metPhase[:,heightVect<sec,:] = numpy.nan
2128
2146
2129 #Derivative
2147 #Derivative
2130 metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
2148 metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
2131 phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
2149 phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
2132 metPhase[phDerAux] = numpy.nan
2150 metPhase[phDerAux] = numpy.nan
2133
2151
2134 #--------------------------METEOR DETECTION -----------------------------------------
2152 #--------------------------METEOR DETECTION -----------------------------------------
2135 indMet = numpy.where(numpy.any(metBool,axis=1))[0]
2153 indMet = numpy.where(numpy.any(metBool,axis=1))[0]
2136
2154
2137 for p in numpy.arange(nPairs):
2155 for p in numpy.arange(nPairs):
2138 phase = metPhase[p,:,:]
2156 phase = metPhase[p,:,:]
2139 phDer = metDer[p,:,:]
2157 phDer = metDer[p,:,:]
2140
2158
2141 for h in indMet:
2159 for h in indMet:
2142 height = heightList[h]
2160 height = heightList[h]
2143 phase1 = phase[h,:] #82
2161 phase1 = phase[h,:] #82
2144 phDer1 = phDer[h,:]
2162 phDer1 = phDer[h,:]
2145
2163
2146 phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
2164 phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
2147
2165
2148 indValid = numpy.where(~numpy.isnan(phase1))[0]
2166 indValid = numpy.where(~numpy.isnan(phase1))[0]
2149 initMet = indValid[0]
2167 initMet = indValid[0]
2150 endMet = 0
2168 endMet = 0
2151
2169
2152 for i in range(len(indValid)-1):
2170 for i in range(len(indValid)-1):
2153
2171
2154 #Time difference
2172 #Time difference
2155 inow = indValid[i]
2173 inow = indValid[i]
2156 inext = indValid[i+1]
2174 inext = indValid[i+1]
2157 idiff = inext - inow
2175 idiff = inext - inow
2158 #Phase difference
2176 #Phase difference
2159 phDiff = numpy.abs(phase1[inext] - phase1[inow])
2177 phDiff = numpy.abs(phase1[inext] - phase1[inow])
2160
2178
2161 if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
2179 if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
2162 sizeTrail = inow - initMet + 1
2180 sizeTrail = inow - initMet + 1
2163 if sizeTrail>3*sec: #Too short meteors
2181 if sizeTrail>3*sec: #Too short meteors
@@ -2173,43 +2191,43 class WindProfiler(Operation):
2173 vel = slope#*height*1000/(k*d)
2191 vel = slope#*height*1000/(k*d)
2174 estAux = numpy.array([utctime,p,height, vel, rsq])
2192 estAux = numpy.array([utctime,p,height, vel, rsq])
2175 meteorList.append(estAux)
2193 meteorList.append(estAux)
2176 initMet = inext
2194 initMet = inext
2177 metArray2 = numpy.array(meteorList)
2195 metArray2 = numpy.array(meteorList)
2178
2196
2179 return metArray2
2197 return metArray2
2180
2198
2181 def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
2199 def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
2182
2200
2183 azimuth1 = numpy.zeros(len(pairslist))
2201 azimuth1 = numpy.zeros(len(pairslist))
2184 dist = numpy.zeros(len(pairslist))
2202 dist = numpy.zeros(len(pairslist))
2185
2203
2186 for i in range(len(rx_location)):
2204 for i in range(len(rx_location)):
2187 ch0 = pairslist[i][0]
2205 ch0 = pairslist[i][0]
2188 ch1 = pairslist[i][1]
2206 ch1 = pairslist[i][1]
2189
2207
2190 diffX = rx_location[ch0][0] - rx_location[ch1][0]
2208 diffX = rx_location[ch0][0] - rx_location[ch1][0]
2191 diffY = rx_location[ch0][1] - rx_location[ch1][1]
2209 diffY = rx_location[ch0][1] - rx_location[ch1][1]
2192 azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
2210 azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
2193 dist[i] = numpy.sqrt(diffX**2 + diffY**2)
2211 dist[i] = numpy.sqrt(diffX**2 + diffY**2)
2194
2212
2195 azimuth1 -= azimuth0
2213 azimuth1 -= azimuth0
2196 return azimuth1, dist
2214 return azimuth1, dist
2197
2215
2198 def techniqueNSM_DBS(self, **kwargs):
2216 def techniqueNSM_DBS(self, **kwargs):
2199 metArray = kwargs['metArray']
2217 metArray = kwargs['metArray']
2200 heightList = kwargs['heightList']
2218 heightList = kwargs['heightList']
2201 timeList = kwargs['timeList']
2219 timeList = kwargs['timeList']
2202 azimuth = kwargs['azimuth']
2220 azimuth = kwargs['azimuth']
2203 theta_x = numpy.array(kwargs['theta_x'])
2221 theta_x = numpy.array(kwargs['theta_x'])
2204 theta_y = numpy.array(kwargs['theta_y'])
2222 theta_y = numpy.array(kwargs['theta_y'])
2205
2223
2206 utctime = metArray[:,0]
2224 utctime = metArray[:,0]
2207 cmet = metArray[:,1].astype(int)
2225 cmet = metArray[:,1].astype(int)
2208 hmet = metArray[:,3].astype(int)
2226 hmet = metArray[:,3].astype(int)
2209 SNRmet = metArray[:,4]
2227 SNRmet = metArray[:,4]
2210 vmet = metArray[:,5]
2228 vmet = metArray[:,5]
2211 spcmet = metArray[:,6]
2229 spcmet = metArray[:,6]
2212
2230
2213 nChan = numpy.max(cmet) + 1
2231 nChan = numpy.max(cmet) + 1
2214 nHeights = len(heightList)
2232 nHeights = len(heightList)
2215
2233
@@ -2225,20 +2243,20 class WindProfiler(Operation):
2225
2243
2226 thisH = (h1met>=hmin) & (h1met<hmax) & (cmet!=2) & (SNRmet>8) & (vmet<50) & (spcmet<10)
2244 thisH = (h1met>=hmin) & (h1met<hmax) & (cmet!=2) & (SNRmet>8) & (vmet<50) & (spcmet<10)
2227 indthisH = numpy.where(thisH)
2245 indthisH = numpy.where(thisH)
2228
2246
2229 if numpy.size(indthisH) > 3:
2247 if numpy.size(indthisH) > 3:
2230
2248
2231 vel_aux = vmet[thisH]
2249 vel_aux = vmet[thisH]
2232 chan_aux = cmet[thisH]
2250 chan_aux = cmet[thisH]
2233 cosu_aux = dir_cosu[chan_aux]
2251 cosu_aux = dir_cosu[chan_aux]
2234 cosv_aux = dir_cosv[chan_aux]
2252 cosv_aux = dir_cosv[chan_aux]
2235 cosw_aux = dir_cosw[chan_aux]
2253 cosw_aux = dir_cosw[chan_aux]
2236
2254
2237 nch = numpy.size(numpy.unique(chan_aux))
2255 nch = numpy.size(numpy.unique(chan_aux))
2238 if nch > 1:
2256 if nch > 1:
2239 A = self.__calculateMatA(cosu_aux, cosv_aux, cosw_aux, True)
2257 A = self.__calculateMatA(cosu_aux, cosv_aux, cosw_aux, True)
2240 velEst[i,:] = numpy.dot(A,vel_aux)
2258 velEst[i,:] = numpy.dot(A,vel_aux)
2241
2259
2242 return velEst
2260 return velEst
2243
2261
2244 def run(self, dataOut, technique, nHours=1, hmin=70, hmax=110, **kwargs):
2262 def run(self, dataOut, technique, nHours=1, hmin=70, hmax=110, **kwargs):
@@ -2249,39 +2267,39 class WindProfiler(Operation):
2249 # noise = dataOut.noise
2267 # noise = dataOut.noise
2250 heightList = dataOut.heightList
2268 heightList = dataOut.heightList
2251 SNR = dataOut.data_SNR
2269 SNR = dataOut.data_SNR
2252
2270
2253 if technique == 'DBS':
2271 if technique == 'DBS':
2254
2272
2255 kwargs['velRadial'] = param[:,1,:] #Radial velocity
2273 kwargs['velRadial'] = param[:,1,:] #Radial velocity
2256 kwargs['heightList'] = heightList
2274 kwargs['heightList'] = heightList
2257 kwargs['SNR'] = SNR
2275 kwargs['SNR'] = SNR
2258
2276
2259 dataOut.data_output, dataOut.heightList, dataOut.data_SNR = self.techniqueDBS(kwargs) #DBS Function
2277 dataOut.data_output, dataOut.heightList, dataOut.data_SNR = self.techniqueDBS(kwargs) #DBS Function
2260 dataOut.utctimeInit = dataOut.utctime
2278 dataOut.utctimeInit = dataOut.utctime
2261 dataOut.outputInterval = dataOut.paramInterval
2279 dataOut.outputInterval = dataOut.paramInterval
2262
2280
2263 elif technique == 'SA':
2281 elif technique == 'SA':
2264
2282
2265 #Parameters
2283 #Parameters
2266 # position_x = kwargs['positionX']
2284 # position_x = kwargs['positionX']
2267 # position_y = kwargs['positionY']
2285 # position_y = kwargs['positionY']
2268 # azimuth = kwargs['azimuth']
2286 # azimuth = kwargs['azimuth']
2269 #
2287 #
2270 # if kwargs.has_key('crosspairsList'):
2288 # if kwargs.has_key('crosspairsList'):
2271 # pairs = kwargs['crosspairsList']
2289 # pairs = kwargs['crosspairsList']
2272 # else:
2290 # else:
2273 # pairs = None
2291 # pairs = None
2274 #
2292 #
2275 # if kwargs.has_key('correctFactor'):
2293 # if kwargs.has_key('correctFactor'):
2276 # correctFactor = kwargs['correctFactor']
2294 # correctFactor = kwargs['correctFactor']
2277 # else:
2295 # else:
2278 # correctFactor = 1
2296 # correctFactor = 1
2279
2297
2280 # tau = dataOut.data_param
2298 # tau = dataOut.data_param
2281 # _lambda = dataOut.C/dataOut.frequency
2299 # _lambda = dataOut.C/dataOut.frequency
2282 # pairsList = dataOut.groupList
2300 # pairsList = dataOut.groupList
2283 # nChannels = dataOut.nChannels
2301 # nChannels = dataOut.nChannels
2284
2302
2285 kwargs['groupList'] = dataOut.groupList
2303 kwargs['groupList'] = dataOut.groupList
2286 kwargs['tau'] = dataOut.data_param
2304 kwargs['tau'] = dataOut.data_param
2287 kwargs['_lambda'] = dataOut.C/dataOut.frequency
2305 kwargs['_lambda'] = dataOut.C/dataOut.frequency
@@ -2289,30 +2307,30 class WindProfiler(Operation):
2289 dataOut.data_output = self.techniqueSA(kwargs)
2307 dataOut.data_output = self.techniqueSA(kwargs)
2290 dataOut.utctimeInit = dataOut.utctime
2308 dataOut.utctimeInit = dataOut.utctime
2291 dataOut.outputInterval = dataOut.timeInterval
2309 dataOut.outputInterval = dataOut.timeInterval
2292
2310
2293 elif technique == 'Meteors':
2311 elif technique == 'Meteors':
2294 dataOut.flagNoData = True
2312 dataOut.flagNoData = True
2295 self.__dataReady = False
2313 self.__dataReady = False
2296
2314
2297 if 'nHours' in kwargs:
2315 if 'nHours' in kwargs:
2298 nHours = kwargs['nHours']
2316 nHours = kwargs['nHours']
2299 else:
2317 else:
2300 nHours = 1
2318 nHours = 1
2301
2319
2302 if 'meteorsPerBin' in kwargs:
2320 if 'meteorsPerBin' in kwargs:
2303 meteorThresh = kwargs['meteorsPerBin']
2321 meteorThresh = kwargs['meteorsPerBin']
2304 else:
2322 else:
2305 meteorThresh = 6
2323 meteorThresh = 6
2306
2324
2307 if 'hmin' in kwargs:
2325 if 'hmin' in kwargs:
2308 hmin = kwargs['hmin']
2326 hmin = kwargs['hmin']
2309 else: hmin = 70
2327 else: hmin = 70
2310 if 'hmax' in kwargs:
2328 if 'hmax' in kwargs:
2311 hmax = kwargs['hmax']
2329 hmax = kwargs['hmax']
2312 else: hmax = 110
2330 else: hmax = 110
2313
2331
2314 dataOut.outputInterval = nHours*3600
2332 dataOut.outputInterval = nHours*3600
2315
2333
2316 if self.__isConfig == False:
2334 if self.__isConfig == False:
2317 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2335 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2318 #Get Initial LTC time
2336 #Get Initial LTC time
@@ -2320,29 +2338,29 class WindProfiler(Operation):
2320 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2338 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2321
2339
2322 self.__isConfig = True
2340 self.__isConfig = True
2323
2341
2324 if self.__buffer is None:
2342 if self.__buffer is None:
2325 self.__buffer = dataOut.data_param
2343 self.__buffer = dataOut.data_param
2326 self.__firstdata = copy.copy(dataOut)
2344 self.__firstdata = copy.copy(dataOut)
2327
2345
2328 else:
2346 else:
2329 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2347 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2330
2348
2331 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2349 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2332
2350
2333 if self.__dataReady:
2351 if self.__dataReady:
2334 dataOut.utctimeInit = self.__initime
2352 dataOut.utctimeInit = self.__initime
2335
2353
2336 self.__initime += dataOut.outputInterval #to erase time offset
2354 self.__initime += dataOut.outputInterval #to erase time offset
2337
2355
2338 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
2356 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
2339 dataOut.flagNoData = False
2357 dataOut.flagNoData = False
2340 self.__buffer = None
2358 self.__buffer = None
2341
2359
2342 elif technique == 'Meteors1':
2360 elif technique == 'Meteors1':
2343 dataOut.flagNoData = True
2361 dataOut.flagNoData = True
2344 self.__dataReady = False
2362 self.__dataReady = False
2345
2363
2346 if 'nMins' in kwargs:
2364 if 'nMins' in kwargs:
2347 nMins = kwargs['nMins']
2365 nMins = kwargs['nMins']
2348 else: nMins = 20
2366 else: nMins = 20
@@ -2357,7 +2375,7 class WindProfiler(Operation):
2357 if 'mode' in kwargs:
2375 if 'mode' in kwargs:
2358 mode = kwargs['mode']
2376 mode = kwargs['mode']
2359 if 'theta_x' in kwargs:
2377 if 'theta_x' in kwargs:
2360 theta_x = kwargs['theta_x']
2378 theta_x = kwargs['theta_x']
2361 if 'theta_y' in kwargs:
2379 if 'theta_y' in kwargs:
2362 theta_y = kwargs['theta_y']
2380 theta_y = kwargs['theta_y']
2363 else: mode = 'SA'
2381 else: mode = 'SA'
@@ -2370,10 +2388,10 class WindProfiler(Operation):
2370 freq = 50e6
2388 freq = 50e6
2371 lamb = C/freq
2389 lamb = C/freq
2372 k = 2*numpy.pi/lamb
2390 k = 2*numpy.pi/lamb
2373
2391
2374 timeList = dataOut.abscissaList
2392 timeList = dataOut.abscissaList
2375 heightList = dataOut.heightList
2393 heightList = dataOut.heightList
2376
2394
2377 if self.__isConfig == False:
2395 if self.__isConfig == False:
2378 dataOut.outputInterval = nMins*60
2396 dataOut.outputInterval = nMins*60
2379 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2397 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
@@ -2384,20 +2402,20 class WindProfiler(Operation):
2384 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2402 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2385
2403
2386 self.__isConfig = True
2404 self.__isConfig = True
2387
2405
2388 if self.__buffer is None:
2406 if self.__buffer is None:
2389 self.__buffer = dataOut.data_param
2407 self.__buffer = dataOut.data_param
2390 self.__firstdata = copy.copy(dataOut)
2408 self.__firstdata = copy.copy(dataOut)
2391
2409
2392 else:
2410 else:
2393 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2411 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2394
2412
2395 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2413 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2396
2414
2397 if self.__dataReady:
2415 if self.__dataReady:
2398 dataOut.utctimeInit = self.__initime
2416 dataOut.utctimeInit = self.__initime
2399 self.__initime += dataOut.outputInterval #to erase time offset
2417 self.__initime += dataOut.outputInterval #to erase time offset
2400
2418
2401 metArray = self.__buffer
2419 metArray = self.__buffer
2402 if mode == 'SA':
2420 if mode == 'SA':
2403 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
2421 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
@@ -2408,71 +2426,71 class WindProfiler(Operation):
2408 self.__buffer = None
2426 self.__buffer = None
2409
2427
2410 return
2428 return
2411
2429
2412 class EWDriftsEstimation(Operation):
2430 class EWDriftsEstimation(Operation):
2413
2431
2414 def __init__(self):
2432 def __init__(self):
2415 Operation.__init__(self)
2433 Operation.__init__(self)
2416
2434
2417 def __correctValues(self, heiRang, phi, velRadial, SNR):
2435 def __correctValues(self, heiRang, phi, velRadial, SNR):
2418 listPhi = phi.tolist()
2436 listPhi = phi.tolist()
2419 maxid = listPhi.index(max(listPhi))
2437 maxid = listPhi.index(max(listPhi))
2420 minid = listPhi.index(min(listPhi))
2438 minid = listPhi.index(min(listPhi))
2421
2439
2422 rango = list(range(len(phi)))
2440 rango = list(range(len(phi)))
2423 # rango = numpy.delete(rango,maxid)
2441 # rango = numpy.delete(rango,maxid)
2424
2442
2425 heiRang1 = heiRang*math.cos(phi[maxid])
2443 heiRang1 = heiRang*math.cos(phi[maxid])
2426 heiRangAux = heiRang*math.cos(phi[minid])
2444 heiRangAux = heiRang*math.cos(phi[minid])
2427 indOut = (heiRang1 < heiRangAux[0]).nonzero()
2445 indOut = (heiRang1 < heiRangAux[0]).nonzero()
2428 heiRang1 = numpy.delete(heiRang1,indOut)
2446 heiRang1 = numpy.delete(heiRang1,indOut)
2429
2447
2430 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
2448 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
2431 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
2449 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
2432
2450
2433 for i in rango:
2451 for i in rango:
2434 x = heiRang*math.cos(phi[i])
2452 x = heiRang*math.cos(phi[i])
2435 y1 = velRadial[i,:]
2453 y1 = velRadial[i,:]
2436 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
2454 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
2437
2455
2438 x1 = heiRang1
2456 x1 = heiRang1
2439 y11 = f1(x1)
2457 y11 = f1(x1)
2440
2458
2441 y2 = SNR[i,:]
2459 y2 = SNR[i,:]
2442 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
2460 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
2443 y21 = f2(x1)
2461 y21 = f2(x1)
2444
2462
2445 velRadial1[i,:] = y11
2463 velRadial1[i,:] = y11
2446 SNR1[i,:] = y21
2464 SNR1[i,:] = y21
2447
2465
2448 return heiRang1, velRadial1, SNR1
2466 return heiRang1, velRadial1, SNR1
2449
2467
2450 def run(self, dataOut, zenith, zenithCorrection):
2468 def run(self, dataOut, zenith, zenithCorrection):
2451 heiRang = dataOut.heightList
2469 heiRang = dataOut.heightList
2452 velRadial = dataOut.data_param[:,3,:]
2470 velRadial = dataOut.data_param[:,3,:]
2453 SNR = dataOut.data_SNR
2471 SNR = dataOut.data_SNR
2454
2472
2455 zenith = numpy.array(zenith)
2473 zenith = numpy.array(zenith)
2456 zenith -= zenithCorrection
2474 zenith -= zenithCorrection
2457 zenith *= numpy.pi/180
2475 zenith *= numpy.pi/180
2458
2476
2459 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
2477 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
2460
2478
2461 alp = zenith[0]
2479 alp = zenith[0]
2462 bet = zenith[1]
2480 bet = zenith[1]
2463
2481
2464 w_w = velRadial1[0,:]
2482 w_w = velRadial1[0,:]
2465 w_e = velRadial1[1,:]
2483 w_e = velRadial1[1,:]
2466
2484
2467 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
2485 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
2468 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
2486 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
2469
2487
2470 winds = numpy.vstack((u,w))
2488 winds = numpy.vstack((u,w))
2471
2489
2472 dataOut.heightList = heiRang1
2490 dataOut.heightList = heiRang1
2473 dataOut.data_output = winds
2491 dataOut.data_output = winds
2474 dataOut.data_SNR = SNR1
2492 dataOut.data_SNR = SNR1
2475
2493
2476 dataOut.utctimeInit = dataOut.utctime
2494 dataOut.utctimeInit = dataOut.utctime
2477 dataOut.outputInterval = dataOut.timeInterval
2495 dataOut.outputInterval = dataOut.timeInterval
2478 return
2496 return
@@ -2485,11 +2503,11 class NonSpecularMeteorDetection(Operation):
2485 data_acf = dataOut.data_pre[0]
2503 data_acf = dataOut.data_pre[0]
2486 data_ccf = dataOut.data_pre[1]
2504 data_ccf = dataOut.data_pre[1]
2487 pairsList = dataOut.groupList[1]
2505 pairsList = dataOut.groupList[1]
2488
2506
2489 lamb = dataOut.C/dataOut.frequency
2507 lamb = dataOut.C/dataOut.frequency
2490 tSamp = dataOut.ippSeconds*dataOut.nCohInt
2508 tSamp = dataOut.ippSeconds*dataOut.nCohInt
2491 paramInterval = dataOut.paramInterval
2509 paramInterval = dataOut.paramInterval
2492
2510
2493 nChannels = data_acf.shape[0]
2511 nChannels = data_acf.shape[0]
2494 nLags = data_acf.shape[1]
2512 nLags = data_acf.shape[1]
2495 nProfiles = data_acf.shape[2]
2513 nProfiles = data_acf.shape[2]
@@ -2499,7 +2517,7 class NonSpecularMeteorDetection(Operation):
2499 heightList = dataOut.heightList
2517 heightList = dataOut.heightList
2500 ippSeconds = dataOut.ippSeconds*dataOut.nCohInt*dataOut.nAvg
2518 ippSeconds = dataOut.ippSeconds*dataOut.nCohInt*dataOut.nAvg
2501 utctime = dataOut.utctime
2519 utctime = dataOut.utctime
2502
2520
2503 dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
2521 dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
2504
2522
2505 #------------------------ SNR --------------------------------------
2523 #------------------------ SNR --------------------------------------
@@ -2511,7 +2529,7 class NonSpecularMeteorDetection(Operation):
2511 SNR[i] = (power[i]-noise[i])/noise[i]
2529 SNR[i] = (power[i]-noise[i])/noise[i]
2512 SNRm = numpy.nanmean(SNR, axis = 0)
2530 SNRm = numpy.nanmean(SNR, axis = 0)
2513 SNRdB = 10*numpy.log10(SNR)
2531 SNRdB = 10*numpy.log10(SNR)
2514
2532
2515 if mode == 'SA':
2533 if mode == 'SA':
2516 dataOut.groupList = dataOut.groupList[1]
2534 dataOut.groupList = dataOut.groupList[1]
2517 nPairs = data_ccf.shape[0]
2535 nPairs = data_ccf.shape[0]
@@ -2519,22 +2537,22 class NonSpecularMeteorDetection(Operation):
2519 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
2537 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
2520 # phase1 = numpy.copy(phase)
2538 # phase1 = numpy.copy(phase)
2521 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
2539 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
2522
2540
2523 for p in range(nPairs):
2541 for p in range(nPairs):
2524 ch0 = pairsList[p][0]
2542 ch0 = pairsList[p][0]
2525 ch1 = pairsList[p][1]
2543 ch1 = pairsList[p][1]
2526 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
2544 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
2527 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
2545 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
2528 # phase1[p,:,:] = numpy.angle(ccf) #median filter
2546 # phase1[p,:,:] = numpy.angle(ccf) #median filter
2529 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
2547 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
2530 # coh1[p,:,:] = numpy.abs(ccf) #median filter
2548 # coh1[p,:,:] = numpy.abs(ccf) #median filter
2531 coh = numpy.nanmax(coh1, axis = 0)
2549 coh = numpy.nanmax(coh1, axis = 0)
2532 # struc = numpy.ones((5,1))
2550 # struc = numpy.ones((5,1))
2533 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
2551 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
2534 #---------------------- Radial Velocity ----------------------------
2552 #---------------------- Radial Velocity ----------------------------
2535 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
2553 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
2536 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
2554 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
2537
2555
2538 if allData:
2556 if allData:
2539 boolMetFin = ~numpy.isnan(SNRm)
2557 boolMetFin = ~numpy.isnan(SNRm)
2540 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2558 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
@@ -2542,31 +2560,31 class NonSpecularMeteorDetection(Operation):
2542 #------------------------ Meteor mask ---------------------------------
2560 #------------------------ Meteor mask ---------------------------------
2543 # #SNR mask
2561 # #SNR mask
2544 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
2562 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
2545 #
2563 #
2546 # #Erase small objects
2564 # #Erase small objects
2547 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
2565 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
2548 #
2566 #
2549 # auxEEJ = numpy.sum(boolMet1,axis=0)
2567 # auxEEJ = numpy.sum(boolMet1,axis=0)
2550 # indOver = auxEEJ>nProfiles*0.8 #Use this later
2568 # indOver = auxEEJ>nProfiles*0.8 #Use this later
2551 # indEEJ = numpy.where(indOver)[0]
2569 # indEEJ = numpy.where(indOver)[0]
2552 # indNEEJ = numpy.where(~indOver)[0]
2570 # indNEEJ = numpy.where(~indOver)[0]
2553 #
2571 #
2554 # boolMetFin = boolMet1
2572 # boolMetFin = boolMet1
2555 #
2573 #
2556 # if indEEJ.size > 0:
2574 # if indEEJ.size > 0:
2557 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
2575 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
2558 #
2576 #
2559 # boolMet2 = coh > cohThresh
2577 # boolMet2 = coh > cohThresh
2560 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
2578 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
2561 #
2579 #
2562 # #Final Meteor mask
2580 # #Final Meteor mask
2563 # boolMetFin = boolMet1|boolMet2
2581 # boolMetFin = boolMet1|boolMet2
2564
2582
2565 #Coherence mask
2583 #Coherence mask
2566 boolMet1 = coh > 0.75
2584 boolMet1 = coh > 0.75
2567 struc = numpy.ones((30,1))
2585 struc = numpy.ones((30,1))
2568 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
2586 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
2569
2587
2570 #Derivative mask
2588 #Derivative mask
2571 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2589 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2572 boolMet2 = derPhase < 0.2
2590 boolMet2 = derPhase < 0.2
@@ -2583,7 +2601,7 class NonSpecularMeteorDetection(Operation):
2583
2601
2584 tmet = coordMet[0]
2602 tmet = coordMet[0]
2585 hmet = coordMet[1]
2603 hmet = coordMet[1]
2586
2604
2587 data_param = numpy.zeros((tmet.size, 6 + nPairs))
2605 data_param = numpy.zeros((tmet.size, 6 + nPairs))
2588 data_param[:,0] = utctime
2606 data_param[:,0] = utctime
2589 data_param[:,1] = tmet
2607 data_param[:,1] = tmet
@@ -2592,7 +2610,7 class NonSpecularMeteorDetection(Operation):
2592 data_param[:,4] = velRad[tmet,hmet]
2610 data_param[:,4] = velRad[tmet,hmet]
2593 data_param[:,5] = coh[tmet,hmet]
2611 data_param[:,5] = coh[tmet,hmet]
2594 data_param[:,6:] = phase[:,tmet,hmet].T
2612 data_param[:,6:] = phase[:,tmet,hmet].T
2595
2613
2596 elif mode == 'DBS':
2614 elif mode == 'DBS':
2597 dataOut.groupList = numpy.arange(nChannels)
2615 dataOut.groupList = numpy.arange(nChannels)
2598
2616
@@ -2600,7 +2618,7 class NonSpecularMeteorDetection(Operation):
2600 phase = numpy.angle(data_acf[:,1,:,:])
2618 phase = numpy.angle(data_acf[:,1,:,:])
2601 # phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
2619 # phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
2602 velRad = phase*lamb/(4*numpy.pi*tSamp)
2620 velRad = phase*lamb/(4*numpy.pi*tSamp)
2603
2621
2604 #Spectral width
2622 #Spectral width
2605 # acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
2623 # acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
2606 # acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
2624 # acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
@@ -2615,24 +2633,24 class NonSpecularMeteorDetection(Operation):
2615 #SNR
2633 #SNR
2616 boolMet1 = (SNRdB>SNRthresh) #SNR mask
2634 boolMet1 = (SNRdB>SNRthresh) #SNR mask
2617 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
2635 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
2618
2636
2619 #Radial velocity
2637 #Radial velocity
2620 boolMet2 = numpy.abs(velRad) < 20
2638 boolMet2 = numpy.abs(velRad) < 20
2621 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
2639 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
2622
2640
2623 #Spectral Width
2641 #Spectral Width
2624 boolMet3 = spcWidth < 30
2642 boolMet3 = spcWidth < 30
2625 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
2643 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
2626 # boolMetFin = self.__erase_small(boolMet1, 10,5)
2644 # boolMetFin = self.__erase_small(boolMet1, 10,5)
2627 boolMetFin = boolMet1&boolMet2&boolMet3
2645 boolMetFin = boolMet1&boolMet2&boolMet3
2628
2646
2629 #Creating data_param
2647 #Creating data_param
2630 coordMet = numpy.where(boolMetFin)
2648 coordMet = numpy.where(boolMetFin)
2631
2649
2632 cmet = coordMet[0]
2650 cmet = coordMet[0]
2633 tmet = coordMet[1]
2651 tmet = coordMet[1]
2634 hmet = coordMet[2]
2652 hmet = coordMet[2]
2635
2653
2636 data_param = numpy.zeros((tmet.size, 7))
2654 data_param = numpy.zeros((tmet.size, 7))
2637 data_param[:,0] = utctime
2655 data_param[:,0] = utctime
2638 data_param[:,1] = cmet
2656 data_param[:,1] = cmet
@@ -2641,7 +2659,7 class NonSpecularMeteorDetection(Operation):
2641 data_param[:,4] = SNR[cmet,tmet,hmet].T
2659 data_param[:,4] = SNR[cmet,tmet,hmet].T
2642 data_param[:,5] = velRad[cmet,tmet,hmet].T
2660 data_param[:,5] = velRad[cmet,tmet,hmet].T
2643 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
2661 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
2644
2662
2645 # self.dataOut.data_param = data_int
2663 # self.dataOut.data_param = data_int
2646 if len(data_param) == 0:
2664 if len(data_param) == 0:
2647 dataOut.flagNoData = True
2665 dataOut.flagNoData = True
@@ -2651,21 +2669,21 class NonSpecularMeteorDetection(Operation):
2651 def __erase_small(self, binArray, threshX, threshY):
2669 def __erase_small(self, binArray, threshX, threshY):
2652 labarray, numfeat = ndimage.measurements.label(binArray)
2670 labarray, numfeat = ndimage.measurements.label(binArray)
2653 binArray1 = numpy.copy(binArray)
2671 binArray1 = numpy.copy(binArray)
2654
2672
2655 for i in range(1,numfeat + 1):
2673 for i in range(1,numfeat + 1):
2656 auxBin = (labarray==i)
2674 auxBin = (labarray==i)
2657 auxSize = auxBin.sum()
2675 auxSize = auxBin.sum()
2658
2676
2659 x,y = numpy.where(auxBin)
2677 x,y = numpy.where(auxBin)
2660 widthX = x.max() - x.min()
2678 widthX = x.max() - x.min()
2661 widthY = y.max() - y.min()
2679 widthY = y.max() - y.min()
2662
2680
2663 #width X: 3 seg -> 12.5*3
2681 #width X: 3 seg -> 12.5*3
2664 #width Y:
2682 #width Y:
2665
2683
2666 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
2684 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
2667 binArray1[auxBin] = False
2685 binArray1[auxBin] = False
2668
2686
2669 return binArray1
2687 return binArray1
2670
2688
2671 #--------------- Specular Meteor ----------------
2689 #--------------- Specular Meteor ----------------
@@ -2675,36 +2693,36 class SMDetection(Operation):
2675 Function DetectMeteors()
2693 Function DetectMeteors()
2676 Project developed with paper:
2694 Project developed with paper:
2677 HOLDSWORTH ET AL. 2004
2695 HOLDSWORTH ET AL. 2004
2678
2696
2679 Input:
2697 Input:
2680 self.dataOut.data_pre
2698 self.dataOut.data_pre
2681
2699
2682 centerReceiverIndex: From the channels, which is the center receiver
2700 centerReceiverIndex: From the channels, which is the center receiver
2683
2701
2684 hei_ref: Height reference for the Beacon signal extraction
2702 hei_ref: Height reference for the Beacon signal extraction
2685 tauindex:
2703 tauindex:
2686 predefinedPhaseShifts: Predefined phase offset for the voltge signals
2704 predefinedPhaseShifts: Predefined phase offset for the voltge signals
2687
2705
2688 cohDetection: Whether to user Coherent detection or not
2706 cohDetection: Whether to user Coherent detection or not
2689 cohDet_timeStep: Coherent Detection calculation time step
2707 cohDet_timeStep: Coherent Detection calculation time step
2690 cohDet_thresh: Coherent Detection phase threshold to correct phases
2708 cohDet_thresh: Coherent Detection phase threshold to correct phases
2691
2709
2692 noise_timeStep: Noise calculation time step
2710 noise_timeStep: Noise calculation time step
2693 noise_multiple: Noise multiple to define signal threshold
2711 noise_multiple: Noise multiple to define signal threshold
2694
2712
2695 multDet_timeLimit: Multiple Detection Removal time limit in seconds
2713 multDet_timeLimit: Multiple Detection Removal time limit in seconds
2696 multDet_rangeLimit: Multiple Detection Removal range limit in km
2714 multDet_rangeLimit: Multiple Detection Removal range limit in km
2697
2715
2698 phaseThresh: Maximum phase difference between receiver to be consider a meteor
2716 phaseThresh: Maximum phase difference between receiver to be consider a meteor
2699 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
2717 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
2700
2718
2701 hmin: Minimum Height of the meteor to use it in the further wind estimations
2719 hmin: Minimum Height of the meteor to use it in the further wind estimations
2702 hmax: Maximum Height of the meteor to use it in the further wind estimations
2720 hmax: Maximum Height of the meteor to use it in the further wind estimations
2703 azimuth: Azimuth angle correction
2721 azimuth: Azimuth angle correction
2704
2722
2705 Affected:
2723 Affected:
2706 self.dataOut.data_param
2724 self.dataOut.data_param
2707
2725
2708 Rejection Criteria (Errors):
2726 Rejection Criteria (Errors):
2709 0: No error; analysis OK
2727 0: No error; analysis OK
2710 1: SNR < SNR threshold
2728 1: SNR < SNR threshold
@@ -2723,9 +2741,9 class SMDetection(Operation):
2723 14: height ambiguous echo: more then one possible height within 70 to 110 km
2741 14: height ambiguous echo: more then one possible height within 70 to 110 km
2724 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
2742 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
2725 16: oscilatory echo, indicating event most likely not an underdense echo
2743 16: oscilatory echo, indicating event most likely not an underdense echo
2726
2744
2727 17: phase difference in meteor Reestimation
2745 17: phase difference in meteor Reestimation
2728
2746
2729 Data Storage:
2747 Data Storage:
2730 Meteors for Wind Estimation (8):
2748 Meteors for Wind Estimation (8):
2731 Utc Time | Range Height
2749 Utc Time | Range Height
@@ -2733,19 +2751,19 class SMDetection(Operation):
2733 VelRad errorVelRad
2751 VelRad errorVelRad
2734 Phase0 Phase1 Phase2 Phase3
2752 Phase0 Phase1 Phase2 Phase3
2735 TypeError
2753 TypeError
2736
2754
2737 '''
2755 '''
2738
2756
2739 def run(self, dataOut, hei_ref = None, tauindex = 0,
2757 def run(self, dataOut, hei_ref = None, tauindex = 0,
2740 phaseOffsets = None,
2758 phaseOffsets = None,
2741 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
2759 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
2742 noise_timeStep = 4, noise_multiple = 4,
2760 noise_timeStep = 4, noise_multiple = 4,
2743 multDet_timeLimit = 1, multDet_rangeLimit = 3,
2761 multDet_timeLimit = 1, multDet_rangeLimit = 3,
2744 phaseThresh = 20, SNRThresh = 5,
2762 phaseThresh = 20, SNRThresh = 5,
2745 hmin = 50, hmax=150, azimuth = 0,
2763 hmin = 50, hmax=150, azimuth = 0,
2746 channelPositions = None) :
2764 channelPositions = None) :
2747
2765
2748
2766
2749 #Getting Pairslist
2767 #Getting Pairslist
2750 if channelPositions is None:
2768 if channelPositions is None:
2751 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2769 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
@@ -2755,53 +2773,53 class SMDetection(Operation):
2755 heiRang = dataOut.getHeiRange()
2773 heiRang = dataOut.getHeiRange()
2756 #Get Beacon signal - No Beacon signal anymore
2774 #Get Beacon signal - No Beacon signal anymore
2757 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
2775 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
2758 #
2776 #
2759 # if hei_ref != None:
2777 # if hei_ref != None:
2760 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
2778 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
2761 #
2779 #
2762
2780
2763
2781
2764 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
2782 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
2765 # see if the user put in pre defined phase shifts
2783 # see if the user put in pre defined phase shifts
2766 voltsPShift = dataOut.data_pre.copy()
2784 voltsPShift = dataOut.data_pre.copy()
2767
2785
2768 # if predefinedPhaseShifts != None:
2786 # if predefinedPhaseShifts != None:
2769 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
2787 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
2770 #
2788 #
2771 # # elif beaconPhaseShifts:
2789 # # elif beaconPhaseShifts:
2772 # # #get hardware phase shifts using beacon signal
2790 # # #get hardware phase shifts using beacon signal
2773 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
2791 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
2774 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
2792 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
2775 #
2793 #
2776 # else:
2794 # else:
2777 # hardwarePhaseShifts = numpy.zeros(5)
2795 # hardwarePhaseShifts = numpy.zeros(5)
2778 #
2796 #
2779 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
2797 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
2780 # for i in range(self.dataOut.data_pre.shape[0]):
2798 # for i in range(self.dataOut.data_pre.shape[0]):
2781 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
2799 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
2782
2800
2783 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
2801 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
2784
2802
2785 #Remove DC
2803 #Remove DC
2786 voltsDC = numpy.mean(voltsPShift,1)
2804 voltsDC = numpy.mean(voltsPShift,1)
2787 voltsDC = numpy.mean(voltsDC,1)
2805 voltsDC = numpy.mean(voltsDC,1)
2788 for i in range(voltsDC.shape[0]):
2806 for i in range(voltsDC.shape[0]):
2789 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
2807 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
2790
2808
2791 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
2809 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
2792 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
2810 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
2793
2811
2794 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
2812 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
2795 #Coherent Detection
2813 #Coherent Detection
2796 if cohDetection:
2814 if cohDetection:
2797 #use coherent detection to get the net power
2815 #use coherent detection to get the net power
2798 cohDet_thresh = cohDet_thresh*numpy.pi/180
2816 cohDet_thresh = cohDet_thresh*numpy.pi/180
2799 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
2817 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
2800
2818
2801 #Non-coherent detection!
2819 #Non-coherent detection!
2802 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
2820 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
2803 #********** END OF COH/NON-COH POWER CALCULATION**********************
2821 #********** END OF COH/NON-COH POWER CALCULATION**********************
2804
2822
2805 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
2823 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
2806 #Get noise
2824 #Get noise
2807 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
2825 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
@@ -2811,7 +2829,7 class SMDetection(Operation):
2811 #Meteor echoes detection
2829 #Meteor echoes detection
2812 listMeteors = self.__findMeteors(powerNet, signalThresh)
2830 listMeteors = self.__findMeteors(powerNet, signalThresh)
2813 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
2831 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
2814
2832
2815 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
2833 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
2816 #Parameters
2834 #Parameters
2817 heiRange = dataOut.getHeiRange()
2835 heiRange = dataOut.getHeiRange()
@@ -2821,7 +2839,7 class SMDetection(Operation):
2821 #Multiple detection removals
2839 #Multiple detection removals
2822 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
2840 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
2823 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
2841 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
2824
2842
2825 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
2843 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
2826 #Parameters
2844 #Parameters
2827 phaseThresh = phaseThresh*numpy.pi/180
2845 phaseThresh = phaseThresh*numpy.pi/180
@@ -2832,40 +2850,40 class SMDetection(Operation):
2832 #Estimation of decay times (Errors N 7, 8, 11)
2850 #Estimation of decay times (Errors N 7, 8, 11)
2833 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
2851 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
2834 #******************* END OF METEOR REESTIMATION *******************
2852 #******************* END OF METEOR REESTIMATION *******************
2835
2853
2836 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
2854 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
2837 #Calculating Radial Velocity (Error N 15)
2855 #Calculating Radial Velocity (Error N 15)
2838 radialStdThresh = 10
2856 radialStdThresh = 10
2839 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
2857 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
2840
2858
2841 if len(listMeteors4) > 0:
2859 if len(listMeteors4) > 0:
2842 #Setting New Array
2860 #Setting New Array
2843 date = dataOut.utctime
2861 date = dataOut.utctime
2844 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
2862 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
2845
2863
2846 #Correcting phase offset
2864 #Correcting phase offset
2847 if phaseOffsets != None:
2865 if phaseOffsets != None:
2848 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2866 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2849 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2867 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2850
2868
2851 #Second Pairslist
2869 #Second Pairslist
2852 pairsList = []
2870 pairsList = []
2853 pairx = (0,1)
2871 pairx = (0,1)
2854 pairy = (2,3)
2872 pairy = (2,3)
2855 pairsList.append(pairx)
2873 pairsList.append(pairx)
2856 pairsList.append(pairy)
2874 pairsList.append(pairy)
2857
2875
2858 jph = numpy.array([0,0,0,0])
2876 jph = numpy.array([0,0,0,0])
2859 h = (hmin,hmax)
2877 h = (hmin,hmax)
2860 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2878 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2861
2879
2862 # #Calculate AOA (Error N 3, 4)
2880 # #Calculate AOA (Error N 3, 4)
2863 # #JONES ET AL. 1998
2881 # #JONES ET AL. 1998
2864 # error = arrayParameters[:,-1]
2882 # error = arrayParameters[:,-1]
2865 # AOAthresh = numpy.pi/8
2883 # AOAthresh = numpy.pi/8
2866 # phases = -arrayParameters[:,9:13]
2884 # phases = -arrayParameters[:,9:13]
2867 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
2885 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
2868 #
2886 #
2869 # #Calculate Heights (Error N 13 and 14)
2887 # #Calculate Heights (Error N 13 and 14)
2870 # error = arrayParameters[:,-1]
2888 # error = arrayParameters[:,-1]
2871 # Ranges = arrayParameters[:,2]
2889 # Ranges = arrayParameters[:,2]
@@ -2873,73 +2891,73 class SMDetection(Operation):
2873 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
2891 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
2874 # error = arrayParameters[:,-1]
2892 # error = arrayParameters[:,-1]
2875 #********************* END OF PARAMETERS CALCULATION **************************
2893 #********************* END OF PARAMETERS CALCULATION **************************
2876
2894
2877 #***************************+ PASS DATA TO NEXT STEP **********************
2895 #***************************+ PASS DATA TO NEXT STEP **********************
2878 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
2896 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
2879 dataOut.data_param = arrayParameters
2897 dataOut.data_param = arrayParameters
2880
2898
2881 if arrayParameters is None:
2899 if arrayParameters is None:
2882 dataOut.flagNoData = True
2900 dataOut.flagNoData = True
2883 else:
2901 else:
2884 dataOut.flagNoData = True
2902 dataOut.flagNoData = True
2885
2903
2886 return
2904 return
2887
2905
2888 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
2906 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
2889
2907
2890 minIndex = min(newheis[0])
2908 minIndex = min(newheis[0])
2891 maxIndex = max(newheis[0])
2909 maxIndex = max(newheis[0])
2892
2910
2893 voltage = voltage0[:,:,minIndex:maxIndex+1]
2911 voltage = voltage0[:,:,minIndex:maxIndex+1]
2894 nLength = voltage.shape[1]/n
2912 nLength = voltage.shape[1]/n
2895 nMin = 0
2913 nMin = 0
2896 nMax = 0
2914 nMax = 0
2897 phaseOffset = numpy.zeros((len(pairslist),n))
2915 phaseOffset = numpy.zeros((len(pairslist),n))
2898
2916
2899 for i in range(n):
2917 for i in range(n):
2900 nMax += nLength
2918 nMax += nLength
2901 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
2919 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
2902 phaseCCF = numpy.mean(phaseCCF, axis = 2)
2920 phaseCCF = numpy.mean(phaseCCF, axis = 2)
2903 phaseOffset[:,i] = phaseCCF.transpose()
2921 phaseOffset[:,i] = phaseCCF.transpose()
2904 nMin = nMax
2922 nMin = nMax
2905 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
2923 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
2906
2924
2907 #Remove Outliers
2925 #Remove Outliers
2908 factor = 2
2926 factor = 2
2909 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
2927 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
2910 dw = numpy.std(wt,axis = 1)
2928 dw = numpy.std(wt,axis = 1)
2911 dw = dw.reshape((dw.size,1))
2929 dw = dw.reshape((dw.size,1))
2912 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
2930 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
2913 phaseOffset[ind] = numpy.nan
2931 phaseOffset[ind] = numpy.nan
2914 phaseOffset = stats.nanmean(phaseOffset, axis=1)
2932 phaseOffset = stats.nanmean(phaseOffset, axis=1)
2915
2933
2916 return phaseOffset
2934 return phaseOffset
2917
2935
2918 def __shiftPhase(self, data, phaseShift):
2936 def __shiftPhase(self, data, phaseShift):
2919 #this will shift the phase of a complex number
2937 #this will shift the phase of a complex number
2920 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
2938 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
2921 return dataShifted
2939 return dataShifted
2922
2940
2923 def __estimatePhaseDifference(self, array, pairslist):
2941 def __estimatePhaseDifference(self, array, pairslist):
2924 nChannel = array.shape[0]
2942 nChannel = array.shape[0]
2925 nHeights = array.shape[2]
2943 nHeights = array.shape[2]
2926 numPairs = len(pairslist)
2944 numPairs = len(pairslist)
2927 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
2945 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
2928 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
2946 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
2929
2947
2930 #Correct phases
2948 #Correct phases
2931 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
2949 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
2932 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2950 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2933
2951
2934 if indDer[0].shape[0] > 0:
2952 if indDer[0].shape[0] > 0:
2935 for i in range(indDer[0].shape[0]):
2953 for i in range(indDer[0].shape[0]):
2936 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
2954 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
2937 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
2955 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
2938
2956
2939 # for j in range(numSides):
2957 # for j in range(numSides):
2940 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
2958 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
2941 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
2959 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
2942 #
2960 #
2943 #Linear
2961 #Linear
2944 phaseInt = numpy.zeros((numPairs,1))
2962 phaseInt = numpy.zeros((numPairs,1))
2945 angAllCCF = phaseCCF[:,[0,1,3,4],0]
2963 angAllCCF = phaseCCF[:,[0,1,3,4],0]
@@ -2949,16 +2967,16 class SMDetection(Operation):
2949 #Phase Differences
2967 #Phase Differences
2950 phaseDiff = phaseInt - phaseCCF[:,2,:]
2968 phaseDiff = phaseInt - phaseCCF[:,2,:]
2951 phaseArrival = phaseInt.reshape(phaseInt.size)
2969 phaseArrival = phaseInt.reshape(phaseInt.size)
2952
2970
2953 #Dealias
2971 #Dealias
2954 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
2972 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
2955 # indAlias = numpy.where(phaseArrival > numpy.pi)
2973 # indAlias = numpy.where(phaseArrival > numpy.pi)
2956 # phaseArrival[indAlias] -= 2*numpy.pi
2974 # phaseArrival[indAlias] -= 2*numpy.pi
2957 # indAlias = numpy.where(phaseArrival < -numpy.pi)
2975 # indAlias = numpy.where(phaseArrival < -numpy.pi)
2958 # phaseArrival[indAlias] += 2*numpy.pi
2976 # phaseArrival[indAlias] += 2*numpy.pi
2959
2977
2960 return phaseDiff, phaseArrival
2978 return phaseDiff, phaseArrival
2961
2979
2962 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
2980 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
2963 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
2981 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
2964 #find the phase shifts of each channel over 1 second intervals
2982 #find the phase shifts of each channel over 1 second intervals
@@ -2968,25 +2986,25 class SMDetection(Operation):
2968 numHeights = volts.shape[2]
2986 numHeights = volts.shape[2]
2969 nChannel = volts.shape[0]
2987 nChannel = volts.shape[0]
2970 voltsCohDet = volts.copy()
2988 voltsCohDet = volts.copy()
2971
2989
2972 pairsarray = numpy.array(pairslist)
2990 pairsarray = numpy.array(pairslist)
2973 indSides = pairsarray[:,1]
2991 indSides = pairsarray[:,1]
2974 # indSides = numpy.array(range(nChannel))
2992 # indSides = numpy.array(range(nChannel))
2975 # indSides = numpy.delete(indSides, indCenter)
2993 # indSides = numpy.delete(indSides, indCenter)
2976 #
2994 #
2977 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
2995 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
2978 listBlocks = numpy.array_split(volts, numBlocks, 1)
2996 listBlocks = numpy.array_split(volts, numBlocks, 1)
2979
2997
2980 startInd = 0
2998 startInd = 0
2981 endInd = 0
2999 endInd = 0
2982
3000
2983 for i in range(numBlocks):
3001 for i in range(numBlocks):
2984 startInd = endInd
3002 startInd = endInd
2985 endInd = endInd + listBlocks[i].shape[1]
3003 endInd = endInd + listBlocks[i].shape[1]
2986
3004
2987 arrayBlock = listBlocks[i]
3005 arrayBlock = listBlocks[i]
2988 # arrayBlockCenter = listCenter[i]
3006 # arrayBlockCenter = listCenter[i]
2989
3007
2990 #Estimate the Phase Difference
3008 #Estimate the Phase Difference
2991 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
3009 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
2992 #Phase Difference RMS
3010 #Phase Difference RMS
@@ -2998,21 +3016,21 class SMDetection(Operation):
2998 for j in range(indSides.size):
3016 for j in range(indSides.size):
2999 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
3017 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
3000 voltsCohDet[:,startInd:endInd,:] = arrayBlock
3018 voltsCohDet[:,startInd:endInd,:] = arrayBlock
3001
3019
3002 return voltsCohDet
3020 return voltsCohDet
3003
3021
3004 def __calculateCCF(self, volts, pairslist ,laglist):
3022 def __calculateCCF(self, volts, pairslist ,laglist):
3005
3023
3006 nHeights = volts.shape[2]
3024 nHeights = volts.shape[2]
3007 nPoints = volts.shape[1]
3025 nPoints = volts.shape[1]
3008 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
3026 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
3009
3027
3010 for i in range(len(pairslist)):
3028 for i in range(len(pairslist)):
3011 volts1 = volts[pairslist[i][0]]
3029 volts1 = volts[pairslist[i][0]]
3012 volts2 = volts[pairslist[i][1]]
3030 volts2 = volts[pairslist[i][1]]
3013
3031
3014 for t in range(len(laglist)):
3032 for t in range(len(laglist)):
3015 idxT = laglist[t]
3033 idxT = laglist[t]
3016 if idxT >= 0:
3034 if idxT >= 0:
3017 vStacked = numpy.vstack((volts2[idxT:,:],
3035 vStacked = numpy.vstack((volts2[idxT:,:],
3018 numpy.zeros((idxT, nHeights),dtype='complex')))
3036 numpy.zeros((idxT, nHeights),dtype='complex')))
@@ -3020,10 +3038,10 class SMDetection(Operation):
3020 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
3038 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
3021 volts2[:(nPoints + idxT),:]))
3039 volts2[:(nPoints + idxT),:]))
3022 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
3040 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
3023
3041
3024 vStacked = None
3042 vStacked = None
3025 return voltsCCF
3043 return voltsCCF
3026
3044
3027 def __getNoise(self, power, timeSegment, timeInterval):
3045 def __getNoise(self, power, timeSegment, timeInterval):
3028 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
3046 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
3029 numBlocks = int(power.shape[0]/numProfPerBlock)
3047 numBlocks = int(power.shape[0]/numProfPerBlock)
@@ -3032,100 +3050,100 class SMDetection(Operation):
3032 listPower = numpy.array_split(power, numBlocks, 0)
3050 listPower = numpy.array_split(power, numBlocks, 0)
3033 noise = numpy.zeros((power.shape[0], power.shape[1]))
3051 noise = numpy.zeros((power.shape[0], power.shape[1]))
3034 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
3052 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
3035
3053
3036 startInd = 0
3054 startInd = 0
3037 endInd = 0
3055 endInd = 0
3038
3056
3039 for i in range(numBlocks): #split por canal
3057 for i in range(numBlocks): #split por canal
3040 startInd = endInd
3058 startInd = endInd
3041 endInd = endInd + listPower[i].shape[0]
3059 endInd = endInd + listPower[i].shape[0]
3042
3060
3043 arrayBlock = listPower[i]
3061 arrayBlock = listPower[i]
3044 noiseAux = numpy.mean(arrayBlock, 0)
3062 noiseAux = numpy.mean(arrayBlock, 0)
3045 # noiseAux = numpy.median(noiseAux)
3063 # noiseAux = numpy.median(noiseAux)
3046 # noiseAux = numpy.mean(arrayBlock)
3064 # noiseAux = numpy.mean(arrayBlock)
3047 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
3065 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
3048
3066
3049 noiseAux1 = numpy.mean(arrayBlock)
3067 noiseAux1 = numpy.mean(arrayBlock)
3050 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
3068 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
3051
3069
3052 return noise, noise1
3070 return noise, noise1
3053
3071
3054 def __findMeteors(self, power, thresh):
3072 def __findMeteors(self, power, thresh):
3055 nProf = power.shape[0]
3073 nProf = power.shape[0]
3056 nHeights = power.shape[1]
3074 nHeights = power.shape[1]
3057 listMeteors = []
3075 listMeteors = []
3058
3076
3059 for i in range(nHeights):
3077 for i in range(nHeights):
3060 powerAux = power[:,i]
3078 powerAux = power[:,i]
3061 threshAux = thresh[:,i]
3079 threshAux = thresh[:,i]
3062
3080
3063 indUPthresh = numpy.where(powerAux > threshAux)[0]
3081 indUPthresh = numpy.where(powerAux > threshAux)[0]
3064 indDNthresh = numpy.where(powerAux <= threshAux)[0]
3082 indDNthresh = numpy.where(powerAux <= threshAux)[0]
3065
3083
3066 j = 0
3084 j = 0
3067
3085
3068 while (j < indUPthresh.size - 2):
3086 while (j < indUPthresh.size - 2):
3069 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
3087 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
3070 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
3088 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
3071 indDNthresh = indDNthresh[indDNAux]
3089 indDNthresh = indDNthresh[indDNAux]
3072
3090
3073 if (indDNthresh.size > 0):
3091 if (indDNthresh.size > 0):
3074 indEnd = indDNthresh[0] - 1
3092 indEnd = indDNthresh[0] - 1
3075 indInit = indUPthresh[j]
3093 indInit = indUPthresh[j]
3076
3094
3077 meteor = powerAux[indInit:indEnd + 1]
3095 meteor = powerAux[indInit:indEnd + 1]
3078 indPeak = meteor.argmax() + indInit
3096 indPeak = meteor.argmax() + indInit
3079 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
3097 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
3080
3098
3081 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
3099 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
3082 j = numpy.where(indUPthresh == indEnd)[0] + 1
3100 j = numpy.where(indUPthresh == indEnd)[0] + 1
3083 else: j+=1
3101 else: j+=1
3084 else: j+=1
3102 else: j+=1
3085
3103
3086 return listMeteors
3104 return listMeteors
3087
3105
3088 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
3106 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
3089
3107
3090 arrayMeteors = numpy.asarray(listMeteors)
3108 arrayMeteors = numpy.asarray(listMeteors)
3091 listMeteors1 = []
3109 listMeteors1 = []
3092
3110
3093 while arrayMeteors.shape[0] > 0:
3111 while arrayMeteors.shape[0] > 0:
3094 FLAs = arrayMeteors[:,4]
3112 FLAs = arrayMeteors[:,4]
3095 maxFLA = FLAs.argmax()
3113 maxFLA = FLAs.argmax()
3096 listMeteors1.append(arrayMeteors[maxFLA,:])
3114 listMeteors1.append(arrayMeteors[maxFLA,:])
3097
3115
3098 MeteorInitTime = arrayMeteors[maxFLA,1]
3116 MeteorInitTime = arrayMeteors[maxFLA,1]
3099 MeteorEndTime = arrayMeteors[maxFLA,3]
3117 MeteorEndTime = arrayMeteors[maxFLA,3]
3100 MeteorHeight = arrayMeteors[maxFLA,0]
3118 MeteorHeight = arrayMeteors[maxFLA,0]
3101
3119
3102 #Check neighborhood
3120 #Check neighborhood
3103 maxHeightIndex = MeteorHeight + rangeLimit
3121 maxHeightIndex = MeteorHeight + rangeLimit
3104 minHeightIndex = MeteorHeight - rangeLimit
3122 minHeightIndex = MeteorHeight - rangeLimit
3105 minTimeIndex = MeteorInitTime - timeLimit
3123 minTimeIndex = MeteorInitTime - timeLimit
3106 maxTimeIndex = MeteorEndTime + timeLimit
3124 maxTimeIndex = MeteorEndTime + timeLimit
3107
3125
3108 #Check Heights
3126 #Check Heights
3109 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
3127 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
3110 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
3128 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
3111 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
3129 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
3112
3130
3113 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
3131 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
3114
3132
3115 return listMeteors1
3133 return listMeteors1
3116
3134
3117 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
3135 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
3118 numHeights = volts.shape[2]
3136 numHeights = volts.shape[2]
3119 nChannel = volts.shape[0]
3137 nChannel = volts.shape[0]
3120
3138
3121 thresholdPhase = thresh[0]
3139 thresholdPhase = thresh[0]
3122 thresholdNoise = thresh[1]
3140 thresholdNoise = thresh[1]
3123 thresholdDB = float(thresh[2])
3141 thresholdDB = float(thresh[2])
3124
3142
3125 thresholdDB1 = 10**(thresholdDB/10)
3143 thresholdDB1 = 10**(thresholdDB/10)
3126 pairsarray = numpy.array(pairslist)
3144 pairsarray = numpy.array(pairslist)
3127 indSides = pairsarray[:,1]
3145 indSides = pairsarray[:,1]
3128
3146
3129 pairslist1 = list(pairslist)
3147 pairslist1 = list(pairslist)
3130 pairslist1.append((0,1))
3148 pairslist1.append((0,1))
3131 pairslist1.append((3,4))
3149 pairslist1.append((3,4))
@@ -3134,31 +3152,31 class SMDetection(Operation):
3134 listPowerSeries = []
3152 listPowerSeries = []
3135 listVoltageSeries = []
3153 listVoltageSeries = []
3136 #volts has the war data
3154 #volts has the war data
3137
3155
3138 if frequency == 30e6:
3156 if frequency == 30e6:
3139 timeLag = 45*10**-3
3157 timeLag = 45*10**-3
3140 else:
3158 else:
3141 timeLag = 15*10**-3
3159 timeLag = 15*10**-3
3142 lag = numpy.ceil(timeLag/timeInterval)
3160 lag = numpy.ceil(timeLag/timeInterval)
3143
3161
3144 for i in range(len(listMeteors)):
3162 for i in range(len(listMeteors)):
3145
3163
3146 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
3164 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
3147 meteorAux = numpy.zeros(16)
3165 meteorAux = numpy.zeros(16)
3148
3166
3149 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
3167 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
3150 mHeight = listMeteors[i][0]
3168 mHeight = listMeteors[i][0]
3151 mStart = listMeteors[i][1]
3169 mStart = listMeteors[i][1]
3152 mPeak = listMeteors[i][2]
3170 mPeak = listMeteors[i][2]
3153 mEnd = listMeteors[i][3]
3171 mEnd = listMeteors[i][3]
3154
3172
3155 #get the volt data between the start and end times of the meteor
3173 #get the volt data between the start and end times of the meteor
3156 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
3174 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
3157 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3175 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3158
3176
3159 #3.6. Phase Difference estimation
3177 #3.6. Phase Difference estimation
3160 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
3178 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
3161
3179
3162 #3.7. Phase difference removal & meteor start, peak and end times reestimated
3180 #3.7. Phase difference removal & meteor start, peak and end times reestimated
3163 #meteorVolts0.- all Channels, all Profiles
3181 #meteorVolts0.- all Channels, all Profiles
3164 meteorVolts0 = volts[:,:,mHeight]
3182 meteorVolts0 = volts[:,:,mHeight]
@@ -3166,15 +3184,15 class SMDetection(Operation):
3166 meteorNoise = noise[:,mHeight]
3184 meteorNoise = noise[:,mHeight]
3167 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
3185 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
3168 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
3186 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
3169
3187
3170 #Times reestimation
3188 #Times reestimation
3171 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
3189 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
3172 if mStart1.size > 0:
3190 if mStart1.size > 0:
3173 mStart1 = mStart1[-1] + 1
3191 mStart1 = mStart1[-1] + 1
3174
3192
3175 else:
3193 else:
3176 mStart1 = mPeak
3194 mStart1 = mPeak
3177
3195
3178 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
3196 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
3179 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
3197 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
3180 if mEndDecayTime1.size == 0:
3198 if mEndDecayTime1.size == 0:
@@ -3182,7 +3200,7 class SMDetection(Operation):
3182 else:
3200 else:
3183 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
3201 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
3184 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
3202 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
3185
3203
3186 #meteorVolts1.- all Channels, from start to end
3204 #meteorVolts1.- all Channels, from start to end
3187 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
3205 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
3188 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
3206 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
@@ -3191,17 +3209,17 class SMDetection(Operation):
3191 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
3209 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
3192 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
3210 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
3193 ##################### END PARAMETERS REESTIMATION #########################
3211 ##################### END PARAMETERS REESTIMATION #########################
3194
3212
3195 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
3213 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
3196 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
3214 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
3197 if meteorVolts2.shape[1] > 0:
3215 if meteorVolts2.shape[1] > 0:
3198 #Phase Difference re-estimation
3216 #Phase Difference re-estimation
3199 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
3217 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
3200 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
3218 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
3201 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
3219 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
3202 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
3220 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
3203 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
3221 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
3204
3222
3205 #Phase Difference RMS
3223 #Phase Difference RMS
3206 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
3224 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
3207 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
3225 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
@@ -3216,27 +3234,27 class SMDetection(Operation):
3216 #Vectorize
3234 #Vectorize
3217 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
3235 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
3218 meteorAux[7:11] = phaseDiffint[0:4]
3236 meteorAux[7:11] = phaseDiffint[0:4]
3219
3237
3220 #Rejection Criterions
3238 #Rejection Criterions
3221 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
3239 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
3222 meteorAux[-1] = 17
3240 meteorAux[-1] = 17
3223 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
3241 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
3224 meteorAux[-1] = 1
3242 meteorAux[-1] = 1
3225
3243
3226
3244
3227 else:
3245 else:
3228 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
3246 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
3229 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
3247 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
3230 PowerSeries = 0
3248 PowerSeries = 0
3231
3249
3232 listMeteors1.append(meteorAux)
3250 listMeteors1.append(meteorAux)
3233 listPowerSeries.append(PowerSeries)
3251 listPowerSeries.append(PowerSeries)
3234 listVoltageSeries.append(meteorVolts1)
3252 listVoltageSeries.append(meteorVolts1)
3235
3253
3236 return listMeteors1, listPowerSeries, listVoltageSeries
3254 return listMeteors1, listPowerSeries, listVoltageSeries
3237
3255
3238 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
3256 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
3239
3257
3240 threshError = 10
3258 threshError = 10
3241 #Depending if it is 30 or 50 MHz
3259 #Depending if it is 30 or 50 MHz
3242 if frequency == 30e6:
3260 if frequency == 30e6:
@@ -3244,22 +3262,22 class SMDetection(Operation):
3244 else:
3262 else:
3245 timeLag = 15*10**-3
3263 timeLag = 15*10**-3
3246 lag = numpy.ceil(timeLag/timeInterval)
3264 lag = numpy.ceil(timeLag/timeInterval)
3247
3265
3248 listMeteors1 = []
3266 listMeteors1 = []
3249
3267
3250 for i in range(len(listMeteors)):
3268 for i in range(len(listMeteors)):
3251 meteorPower = listPower[i]
3269 meteorPower = listPower[i]
3252 meteorAux = listMeteors[i]
3270 meteorAux = listMeteors[i]
3253
3271
3254 if meteorAux[-1] == 0:
3272 if meteorAux[-1] == 0:
3255
3273
3256 try:
3274 try:
3257 indmax = meteorPower.argmax()
3275 indmax = meteorPower.argmax()
3258 indlag = indmax + lag
3276 indlag = indmax + lag
3259
3277
3260 y = meteorPower[indlag:]
3278 y = meteorPower[indlag:]
3261 x = numpy.arange(0, y.size)*timeLag
3279 x = numpy.arange(0, y.size)*timeLag
3262
3280
3263 #first guess
3281 #first guess
3264 a = y[0]
3282 a = y[0]
3265 tau = timeLag
3283 tau = timeLag
@@ -3268,26 +3286,26 class SMDetection(Operation):
3268 y1 = self.__exponential_function(x, *popt)
3286 y1 = self.__exponential_function(x, *popt)
3269 #error estimation
3287 #error estimation
3270 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
3288 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
3271
3289
3272 decayTime = popt[1]
3290 decayTime = popt[1]
3273 riseTime = indmax*timeInterval
3291 riseTime = indmax*timeInterval
3274 meteorAux[11:13] = [decayTime, error]
3292 meteorAux[11:13] = [decayTime, error]
3275
3293
3276 #Table items 7, 8 and 11
3294 #Table items 7, 8 and 11
3277 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
3295 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
3278 meteorAux[-1] = 7
3296 meteorAux[-1] = 7
3279 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
3297 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
3280 meteorAux[-1] = 8
3298 meteorAux[-1] = 8
3281 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
3299 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
3282 meteorAux[-1] = 11
3300 meteorAux[-1] = 11
3283
3301
3284
3302
3285 except:
3303 except:
3286 meteorAux[-1] = 11
3304 meteorAux[-1] = 11
3287
3305
3288
3306
3289 listMeteors1.append(meteorAux)
3307 listMeteors1.append(meteorAux)
3290
3308
3291 return listMeteors1
3309 return listMeteors1
3292
3310
3293 #Exponential Function
3311 #Exponential Function
@@ -3295,9 +3313,9 class SMDetection(Operation):
3295 def __exponential_function(self, x, a, tau):
3313 def __exponential_function(self, x, a, tau):
3296 y = a*numpy.exp(-x/tau)
3314 y = a*numpy.exp(-x/tau)
3297 return y
3315 return y
3298
3316
3299 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
3317 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
3300
3318
3301 pairslist1 = list(pairslist)
3319 pairslist1 = list(pairslist)
3302 pairslist1.append((0,1))
3320 pairslist1.append((0,1))
3303 pairslist1.append((3,4))
3321 pairslist1.append((3,4))
@@ -3307,33 +3325,33 class SMDetection(Operation):
3307 c = 3e8
3325 c = 3e8
3308 lag = numpy.ceil(timeLag/timeInterval)
3326 lag = numpy.ceil(timeLag/timeInterval)
3309 freq = 30e6
3327 freq = 30e6
3310
3328
3311 listMeteors1 = []
3329 listMeteors1 = []
3312
3330
3313 for i in range(len(listMeteors)):
3331 for i in range(len(listMeteors)):
3314 meteorAux = listMeteors[i]
3332 meteorAux = listMeteors[i]
3315 if meteorAux[-1] == 0:
3333 if meteorAux[-1] == 0:
3316 mStart = listMeteors[i][1]
3334 mStart = listMeteors[i][1]
3317 mPeak = listMeteors[i][2]
3335 mPeak = listMeteors[i][2]
3318 mLag = mPeak - mStart + lag
3336 mLag = mPeak - mStart + lag
3319
3337
3320 #get the volt data between the start and end times of the meteor
3338 #get the volt data between the start and end times of the meteor
3321 meteorVolts = listVolts[i]
3339 meteorVolts = listVolts[i]
3322 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3340 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3323
3341
3324 #Get CCF
3342 #Get CCF
3325 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
3343 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
3326
3344
3327 #Method 2
3345 #Method 2
3328 slopes = numpy.zeros(numPairs)
3346 slopes = numpy.zeros(numPairs)
3329 time = numpy.array([-2,-1,1,2])*timeInterval
3347 time = numpy.array([-2,-1,1,2])*timeInterval
3330 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
3348 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
3331
3349
3332 #Correct phases
3350 #Correct phases
3333 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
3351 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
3334 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
3352 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
3335
3353
3336 if indDer[0].shape[0] > 0:
3354 if indDer[0].shape[0] > 0:
3337 for i in range(indDer[0].shape[0]):
3355 for i in range(indDer[0].shape[0]):
3338 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
3356 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
3339 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
3357 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
@@ -3342,51 +3360,51 class SMDetection(Operation):
3342 for j in range(numPairs):
3360 for j in range(numPairs):
3343 fit = stats.linregress(time, angAllCCF[j,:])
3361 fit = stats.linregress(time, angAllCCF[j,:])
3344 slopes[j] = fit[0]
3362 slopes[j] = fit[0]
3345
3363
3346 #Remove Outlier
3364 #Remove Outlier
3347 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3365 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3348 # slopes = numpy.delete(slopes,indOut)
3366 # slopes = numpy.delete(slopes,indOut)
3349 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3367 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3350 # slopes = numpy.delete(slopes,indOut)
3368 # slopes = numpy.delete(slopes,indOut)
3351
3369
3352 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
3370 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
3353 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
3371 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
3354 meteorAux[-2] = radialError
3372 meteorAux[-2] = radialError
3355 meteorAux[-3] = radialVelocity
3373 meteorAux[-3] = radialVelocity
3356
3374
3357 #Setting Error
3375 #Setting Error
3358 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
3376 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
3359 if numpy.abs(radialVelocity) > 200:
3377 if numpy.abs(radialVelocity) > 200:
3360 meteorAux[-1] = 15
3378 meteorAux[-1] = 15
3361 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
3379 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
3362 elif radialError > radialStdThresh:
3380 elif radialError > radialStdThresh:
3363 meteorAux[-1] = 12
3381 meteorAux[-1] = 12
3364
3382
3365 listMeteors1.append(meteorAux)
3383 listMeteors1.append(meteorAux)
3366 return listMeteors1
3384 return listMeteors1
3367
3385
3368 def __setNewArrays(self, listMeteors, date, heiRang):
3386 def __setNewArrays(self, listMeteors, date, heiRang):
3369
3387
3370 #New arrays
3388 #New arrays
3371 arrayMeteors = numpy.array(listMeteors)
3389 arrayMeteors = numpy.array(listMeteors)
3372 arrayParameters = numpy.zeros((len(listMeteors), 13))
3390 arrayParameters = numpy.zeros((len(listMeteors), 13))
3373
3391
3374 #Date inclusion
3392 #Date inclusion
3375 # date = re.findall(r'\((.*?)\)', date)
3393 # date = re.findall(r'\((.*?)\)', date)
3376 # date = date[0].split(',')
3394 # date = date[0].split(',')
3377 # date = map(int, date)
3395 # date = map(int, date)
3378 #
3396 #
3379 # if len(date)<6:
3397 # if len(date)<6:
3380 # date.append(0)
3398 # date.append(0)
3381 #
3399 #
3382 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
3400 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
3383 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
3401 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
3384 arrayDate = numpy.tile(date, (len(listMeteors)))
3402 arrayDate = numpy.tile(date, (len(listMeteors)))
3385
3403
3386 #Meteor array
3404 #Meteor array
3387 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
3405 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
3388 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
3406 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
3389
3407
3390 #Parameters Array
3408 #Parameters Array
3391 arrayParameters[:,0] = arrayDate #Date
3409 arrayParameters[:,0] = arrayDate #Date
3392 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
3410 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
@@ -3394,13 +3412,13 class SMDetection(Operation):
3394 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
3412 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
3395 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
3413 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
3396
3414
3397
3415
3398 return arrayParameters
3416 return arrayParameters
3399
3417
3400 class CorrectSMPhases(Operation):
3418 class CorrectSMPhases(Operation):
3401
3419
3402 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
3420 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
3403
3421
3404 arrayParameters = dataOut.data_param
3422 arrayParameters = dataOut.data_param
3405 pairsList = []
3423 pairsList = []
3406 pairx = (0,1)
3424 pairx = (0,1)
@@ -3408,49 +3426,49 class CorrectSMPhases(Operation):
3408 pairsList.append(pairx)
3426 pairsList.append(pairx)
3409 pairsList.append(pairy)
3427 pairsList.append(pairy)
3410 jph = numpy.zeros(4)
3428 jph = numpy.zeros(4)
3411
3429
3412 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
3430 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
3413 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
3431 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
3414 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
3432 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
3415
3433
3416 meteorOps = SMOperations()
3434 meteorOps = SMOperations()
3417 if channelPositions is None:
3435 if channelPositions is None:
3418 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3436 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3419 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3437 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3420
3438
3421 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3439 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3422 h = (hmin,hmax)
3440 h = (hmin,hmax)
3423
3441
3424 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
3442 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
3425
3443
3426 dataOut.data_param = arrayParameters
3444 dataOut.data_param = arrayParameters
3427 return
3445 return
3428
3446
3429 class SMPhaseCalibration(Operation):
3447 class SMPhaseCalibration(Operation):
3430
3448
3431 __buffer = None
3449 __buffer = None
3432
3450
3433 __initime = None
3451 __initime = None
3434
3452
3435 __dataReady = False
3453 __dataReady = False
3436
3454
3437 __isConfig = False
3455 __isConfig = False
3438
3456
3439 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
3457 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
3440
3458
3441 dataTime = currentTime + paramInterval
3459 dataTime = currentTime + paramInterval
3442 deltaTime = dataTime - initTime
3460 deltaTime = dataTime - initTime
3443
3461
3444 if deltaTime >= outputInterval or deltaTime < 0:
3462 if deltaTime >= outputInterval or deltaTime < 0:
3445 return True
3463 return True
3446
3464
3447 return False
3465 return False
3448
3466
3449 def __getGammas(self, pairs, d, phases):
3467 def __getGammas(self, pairs, d, phases):
3450 gammas = numpy.zeros(2)
3468 gammas = numpy.zeros(2)
3451
3469
3452 for i in range(len(pairs)):
3470 for i in range(len(pairs)):
3453
3471
3454 pairi = pairs[i]
3472 pairi = pairs[i]
3455
3473
3456 phip3 = phases[:,pairi[0]]
3474 phip3 = phases[:,pairi[0]]
@@ -3464,7 +3482,7 class SMPhaseCalibration(Operation):
3464 jgamma = numpy.angle(numpy.exp(1j*jgamma))
3482 jgamma = numpy.angle(numpy.exp(1j*jgamma))
3465 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
3483 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
3466 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
3484 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
3467
3485
3468 #Revised distribution
3486 #Revised distribution
3469 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
3487 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
3470
3488
@@ -3473,39 +3491,39 class SMPhaseCalibration(Operation):
3473 rmin = -0.5*numpy.pi
3491 rmin = -0.5*numpy.pi
3474 rmax = 0.5*numpy.pi
3492 rmax = 0.5*numpy.pi
3475 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
3493 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
3476
3494
3477 meteorsY = phaseHisto[0]
3495 meteorsY = phaseHisto[0]
3478 phasesX = phaseHisto[1][:-1]
3496 phasesX = phaseHisto[1][:-1]
3479 width = phasesX[1] - phasesX[0]
3497 width = phasesX[1] - phasesX[0]
3480 phasesX += width/2
3498 phasesX += width/2
3481
3499
3482 #Gaussian aproximation
3500 #Gaussian aproximation
3483 bpeak = meteorsY.argmax()
3501 bpeak = meteorsY.argmax()
3484 peak = meteorsY.max()
3502 peak = meteorsY.max()
3485 jmin = bpeak - 5
3503 jmin = bpeak - 5
3486 jmax = bpeak + 5 + 1
3504 jmax = bpeak + 5 + 1
3487
3505
3488 if jmin<0:
3506 if jmin<0:
3489 jmin = 0
3507 jmin = 0
3490 jmax = 6
3508 jmax = 6
3491 elif jmax > meteorsY.size:
3509 elif jmax > meteorsY.size:
3492 jmin = meteorsY.size - 6
3510 jmin = meteorsY.size - 6
3493 jmax = meteorsY.size
3511 jmax = meteorsY.size
3494
3512
3495 x0 = numpy.array([peak,bpeak,50])
3513 x0 = numpy.array([peak,bpeak,50])
3496 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
3514 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
3497
3515
3498 #Gammas
3516 #Gammas
3499 gammas[i] = coeff[0][1]
3517 gammas[i] = coeff[0][1]
3500
3518
3501 return gammas
3519 return gammas
3502
3520
3503 def __residualFunction(self, coeffs, y, t):
3521 def __residualFunction(self, coeffs, y, t):
3504
3522
3505 return y - self.__gauss_function(t, coeffs)
3523 return y - self.__gauss_function(t, coeffs)
3506
3524
3507 def __gauss_function(self, t, coeffs):
3525 def __gauss_function(self, t, coeffs):
3508
3526
3509 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
3527 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
3510
3528
3511 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
3529 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
@@ -3526,16 +3544,16 class SMPhaseCalibration(Operation):
3526 max_xangle = range_angle[iz]/2 + center_xangle
3544 max_xangle = range_angle[iz]/2 + center_xangle
3527 min_yangle = -range_angle[iz]/2 + center_yangle
3545 min_yangle = -range_angle[iz]/2 + center_yangle
3528 max_yangle = range_angle[iz]/2 + center_yangle
3546 max_yangle = range_angle[iz]/2 + center_yangle
3529
3547
3530 inc_x = (max_xangle-min_xangle)/nstepsx
3548 inc_x = (max_xangle-min_xangle)/nstepsx
3531 inc_y = (max_yangle-min_yangle)/nstepsy
3549 inc_y = (max_yangle-min_yangle)/nstepsy
3532
3550
3533 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
3551 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
3534 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
3552 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
3535 penalty = numpy.zeros((nstepsx,nstepsy))
3553 penalty = numpy.zeros((nstepsx,nstepsy))
3536 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
3554 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
3537 jph = numpy.zeros(nchan)
3555 jph = numpy.zeros(nchan)
3538
3556
3539 # Iterations looking for the offset
3557 # Iterations looking for the offset
3540 for iy in range(int(nstepsy)):
3558 for iy in range(int(nstepsy)):
3541 for ix in range(int(nstepsx)):
3559 for ix in range(int(nstepsx)):
@@ -3543,46 +3561,46 class SMPhaseCalibration(Operation):
3543 d2 = d[pairsList[1][1]]
3561 d2 = d[pairsList[1][1]]
3544 d5 = d[pairsList[0][0]]
3562 d5 = d[pairsList[0][0]]
3545 d4 = d[pairsList[0][1]]
3563 d4 = d[pairsList[0][1]]
3546
3564
3547 alp2 = alpha_y[iy] #gamma 1
3565 alp2 = alpha_y[iy] #gamma 1
3548 alp4 = alpha_x[ix] #gamma 0
3566 alp4 = alpha_x[ix] #gamma 0
3549
3567
3550 alp3 = -alp2*d3/d2 - gammas[1]
3568 alp3 = -alp2*d3/d2 - gammas[1]
3551 alp5 = -alp4*d5/d4 - gammas[0]
3569 alp5 = -alp4*d5/d4 - gammas[0]
3552 # jph[pairy[1]] = alpha_y[iy]
3570 # jph[pairy[1]] = alpha_y[iy]
3553 # jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
3571 # jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
3554
3572
3555 # jph[pairx[1]] = alpha_x[ix]
3573 # jph[pairx[1]] = alpha_x[ix]
3556 # jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
3574 # jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
3557 jph[pairsList[0][1]] = alp4
3575 jph[pairsList[0][1]] = alp4
3558 jph[pairsList[0][0]] = alp5
3576 jph[pairsList[0][0]] = alp5
3559 jph[pairsList[1][0]] = alp3
3577 jph[pairsList[1][0]] = alp3
3560 jph[pairsList[1][1]] = alp2
3578 jph[pairsList[1][1]] = alp2
3561 jph_array[:,ix,iy] = jph
3579 jph_array[:,ix,iy] = jph
3562 # d = [2.0,2.5,2.5,2.0]
3580 # d = [2.0,2.5,2.5,2.0]
3563 #falta chequear si va a leer bien los meteoros
3581 #falta chequear si va a leer bien los meteoros
3564 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
3582 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
3565 error = meteorsArray1[:,-1]
3583 error = meteorsArray1[:,-1]
3566 ind1 = numpy.where(error==0)[0]
3584 ind1 = numpy.where(error==0)[0]
3567 penalty[ix,iy] = ind1.size
3585 penalty[ix,iy] = ind1.size
3568
3586
3569 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
3587 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
3570 phOffset = jph_array[:,i,j]
3588 phOffset = jph_array[:,i,j]
3571
3589
3572 center_xangle = phOffset[pairx[1]]
3590 center_xangle = phOffset[pairx[1]]
3573 center_yangle = phOffset[pairy[1]]
3591 center_yangle = phOffset[pairy[1]]
3574
3592
3575 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
3593 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
3576 phOffset = phOffset*180/numpy.pi
3594 phOffset = phOffset*180/numpy.pi
3577 return phOffset
3595 return phOffset
3578
3596
3579
3597
3580 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
3598 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
3581
3599
3582 dataOut.flagNoData = True
3600 dataOut.flagNoData = True
3583 self.__dataReady = False
3601 self.__dataReady = False
3584 dataOut.outputInterval = nHours*3600
3602 dataOut.outputInterval = nHours*3600
3585
3603
3586 if self.__isConfig == False:
3604 if self.__isConfig == False:
3587 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
3605 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
3588 #Get Initial LTC time
3606 #Get Initial LTC time
@@ -3590,19 +3608,19 class SMPhaseCalibration(Operation):
3590 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
3608 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
3591
3609
3592 self.__isConfig = True
3610 self.__isConfig = True
3593
3611
3594 if self.__buffer is None:
3612 if self.__buffer is None:
3595 self.__buffer = dataOut.data_param.copy()
3613 self.__buffer = dataOut.data_param.copy()
3596
3614
3597 else:
3615 else:
3598 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
3616 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
3599
3617
3600 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
3618 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
3601
3619
3602 if self.__dataReady:
3620 if self.__dataReady:
3603 dataOut.utctimeInit = self.__initime
3621 dataOut.utctimeInit = self.__initime
3604 self.__initime += dataOut.outputInterval #to erase time offset
3622 self.__initime += dataOut.outputInterval #to erase time offset
3605
3623
3606 freq = dataOut.frequency
3624 freq = dataOut.frequency
3607 c = dataOut.C #m/s
3625 c = dataOut.C #m/s
3608 lamb = c/freq
3626 lamb = c/freq
@@ -3624,13 +3642,13 class SMPhaseCalibration(Operation):
3624 pairs.append((1,0))
3642 pairs.append((1,0))
3625 else:
3643 else:
3626 pairs.append((0,1))
3644 pairs.append((0,1))
3627
3645
3628 if distances[3] > distances[2]:
3646 if distances[3] > distances[2]:
3629 pairs.append((3,2))
3647 pairs.append((3,2))
3630 else:
3648 else:
3631 pairs.append((2,3))
3649 pairs.append((2,3))
3632 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
3650 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
3633
3651
3634 meteorsArray = self.__buffer
3652 meteorsArray = self.__buffer
3635 error = meteorsArray[:,-1]
3653 error = meteorsArray[:,-1]
3636 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
3654 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
@@ -3638,7 +3656,7 class SMPhaseCalibration(Operation):
3638 meteorsArray = meteorsArray[ind1,:]
3656 meteorsArray = meteorsArray[ind1,:]
3639 meteorsArray[:,-1] = 0
3657 meteorsArray[:,-1] = 0
3640 phases = meteorsArray[:,8:12]
3658 phases = meteorsArray[:,8:12]
3641
3659
3642 #Calculate Gammas
3660 #Calculate Gammas
3643 gammas = self.__getGammas(pairs, distances, phases)
3661 gammas = self.__getGammas(pairs, distances, phases)
3644 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
3662 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
@@ -3648,22 +3666,22 class SMPhaseCalibration(Operation):
3648 dataOut.data_output = -phasesOff
3666 dataOut.data_output = -phasesOff
3649 dataOut.flagNoData = False
3667 dataOut.flagNoData = False
3650 self.__buffer = None
3668 self.__buffer = None
3651
3669
3652
3670
3653 return
3671 return
3654
3672
3655 class SMOperations():
3673 class SMOperations():
3656
3674
3657 def __init__(self):
3675 def __init__(self):
3658
3676
3659 return
3677 return
3660
3678
3661 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
3679 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
3662
3680
3663 arrayParameters = arrayParameters0.copy()
3681 arrayParameters = arrayParameters0.copy()
3664 hmin = h[0]
3682 hmin = h[0]
3665 hmax = h[1]
3683 hmax = h[1]
3666
3684
3667 #Calculate AOA (Error N 3, 4)
3685 #Calculate AOA (Error N 3, 4)
3668 #JONES ET AL. 1998
3686 #JONES ET AL. 1998
3669 AOAthresh = numpy.pi/8
3687 AOAthresh = numpy.pi/8
@@ -3671,72 +3689,72 class SMOperations():
3671 phases = -arrayParameters[:,8:12] + jph
3689 phases = -arrayParameters[:,8:12] + jph
3672 # phases = numpy.unwrap(phases)
3690 # phases = numpy.unwrap(phases)
3673 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
3691 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
3674
3692
3675 #Calculate Heights (Error N 13 and 14)
3693 #Calculate Heights (Error N 13 and 14)
3676 error = arrayParameters[:,-1]
3694 error = arrayParameters[:,-1]
3677 Ranges = arrayParameters[:,1]
3695 Ranges = arrayParameters[:,1]
3678 zenith = arrayParameters[:,4]
3696 zenith = arrayParameters[:,4]
3679 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
3697 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
3680
3698
3681 #----------------------- Get Final data ------------------------------------
3699 #----------------------- Get Final data ------------------------------------
3682 # error = arrayParameters[:,-1]
3700 # error = arrayParameters[:,-1]
3683 # ind1 = numpy.where(error==0)[0]
3701 # ind1 = numpy.where(error==0)[0]
3684 # arrayParameters = arrayParameters[ind1,:]
3702 # arrayParameters = arrayParameters[ind1,:]
3685
3703
3686 return arrayParameters
3704 return arrayParameters
3687
3705
3688 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
3706 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
3689
3707
3690 arrayAOA = numpy.zeros((phases.shape[0],3))
3708 arrayAOA = numpy.zeros((phases.shape[0],3))
3691 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
3709 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
3692
3710
3693 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3711 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3694 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3712 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3695 arrayAOA[:,2] = cosDirError
3713 arrayAOA[:,2] = cosDirError
3696
3714
3697 azimuthAngle = arrayAOA[:,0]
3715 azimuthAngle = arrayAOA[:,0]
3698 zenithAngle = arrayAOA[:,1]
3716 zenithAngle = arrayAOA[:,1]
3699
3717
3700 #Setting Error
3718 #Setting Error
3701 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
3719 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
3702 error[indError] = 0
3720 error[indError] = 0
3703 #Number 3: AOA not fesible
3721 #Number 3: AOA not fesible
3704 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3722 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3705 error[indInvalid] = 3
3723 error[indInvalid] = 3
3706 #Number 4: Large difference in AOAs obtained from different antenna baselines
3724 #Number 4: Large difference in AOAs obtained from different antenna baselines
3707 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3725 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3708 error[indInvalid] = 4
3726 error[indInvalid] = 4
3709 return arrayAOA, error
3727 return arrayAOA, error
3710
3728
3711 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
3729 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
3712
3730
3713 #Initializing some variables
3731 #Initializing some variables
3714 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3732 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3715 ang_aux = ang_aux.reshape(1,ang_aux.size)
3733 ang_aux = ang_aux.reshape(1,ang_aux.size)
3716
3734
3717 cosdir = numpy.zeros((arrayPhase.shape[0],2))
3735 cosdir = numpy.zeros((arrayPhase.shape[0],2))
3718 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3736 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3719
3737
3720
3738
3721 for i in range(2):
3739 for i in range(2):
3722 ph0 = arrayPhase[:,pairsList[i][0]]
3740 ph0 = arrayPhase[:,pairsList[i][0]]
3723 ph1 = arrayPhase[:,pairsList[i][1]]
3741 ph1 = arrayPhase[:,pairsList[i][1]]
3724 d0 = distances[pairsList[i][0]]
3742 d0 = distances[pairsList[i][0]]
3725 d1 = distances[pairsList[i][1]]
3743 d1 = distances[pairsList[i][1]]
3726
3744
3727 ph0_aux = ph0 + ph1
3745 ph0_aux = ph0 + ph1
3728 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
3746 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
3729 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
3747 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
3730 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
3748 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
3731 #First Estimation
3749 #First Estimation
3732 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
3750 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
3733
3751
3734 #Most-Accurate Second Estimation
3752 #Most-Accurate Second Estimation
3735 phi1_aux = ph0 - ph1
3753 phi1_aux = ph0 - ph1
3736 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3754 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3737 #Direction Cosine 1
3755 #Direction Cosine 1
3738 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
3756 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
3739
3757
3740 #Searching the correct Direction Cosine
3758 #Searching the correct Direction Cosine
3741 cosdir0_aux = cosdir0[:,i]
3759 cosdir0_aux = cosdir0[:,i]
3742 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3760 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
@@ -3745,59 +3763,59 class SMOperations():
3745 indcos = cosDiff.argmin(axis = 1)
3763 indcos = cosDiff.argmin(axis = 1)
3746 #Saving Value obtained
3764 #Saving Value obtained
3747 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3765 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3748
3766
3749 return cosdir0, cosdir
3767 return cosdir0, cosdir
3750
3768
3751 def __calculateAOA(self, cosdir, azimuth):
3769 def __calculateAOA(self, cosdir, azimuth):
3752 cosdirX = cosdir[:,0]
3770 cosdirX = cosdir[:,0]
3753 cosdirY = cosdir[:,1]
3771 cosdirY = cosdir[:,1]
3754
3772
3755 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3773 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3756 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
3774 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
3757 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3775 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3758
3776
3759 return angles
3777 return angles
3760
3778
3761 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3779 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3762
3780
3763 Ramb = 375 #Ramb = c/(2*PRF)
3781 Ramb = 375 #Ramb = c/(2*PRF)
3764 Re = 6371 #Earth Radius
3782 Re = 6371 #Earth Radius
3765 heights = numpy.zeros(Ranges.shape)
3783 heights = numpy.zeros(Ranges.shape)
3766
3784
3767 R_aux = numpy.array([0,1,2])*Ramb
3785 R_aux = numpy.array([0,1,2])*Ramb
3768 R_aux = R_aux.reshape(1,R_aux.size)
3786 R_aux = R_aux.reshape(1,R_aux.size)
3769
3787
3770 Ranges = Ranges.reshape(Ranges.size,1)
3788 Ranges = Ranges.reshape(Ranges.size,1)
3771
3789
3772 Ri = Ranges + R_aux
3790 Ri = Ranges + R_aux
3773 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3791 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3774
3792
3775 #Check if there is a height between 70 and 110 km
3793 #Check if there is a height between 70 and 110 km
3776 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3794 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3777 ind_h = numpy.where(h_bool == 1)[0]
3795 ind_h = numpy.where(h_bool == 1)[0]
3778
3796
3779 hCorr = hi[ind_h, :]
3797 hCorr = hi[ind_h, :]
3780 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3798 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3781
3799
3782 hCorr = hi[ind_hCorr][:len(ind_h)]
3800 hCorr = hi[ind_hCorr][:len(ind_h)]
3783 heights[ind_h] = hCorr
3801 heights[ind_h] = hCorr
3784
3802
3785 #Setting Error
3803 #Setting Error
3786 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3804 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3787 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3805 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3788 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
3806 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
3789 error[indError] = 0
3807 error[indError] = 0
3790 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3808 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3791 error[indInvalid2] = 14
3809 error[indInvalid2] = 14
3792 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3810 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3793 error[indInvalid1] = 13
3811 error[indInvalid1] = 13
3794
3812
3795 return heights, error
3813 return heights, error
3796
3814
3797 def getPhasePairs(self, channelPositions):
3815 def getPhasePairs(self, channelPositions):
3798 chanPos = numpy.array(channelPositions)
3816 chanPos = numpy.array(channelPositions)
3799 listOper = list(itertools.combinations(list(range(5)),2))
3817 listOper = list(itertools.combinations(list(range(5)),2))
3800
3818
3801 distances = numpy.zeros(4)
3819 distances = numpy.zeros(4)
3802 axisX = []
3820 axisX = []
3803 axisY = []
3821 axisY = []
@@ -3805,15 +3823,15 class SMOperations():
3805 distY = numpy.zeros(3)
3823 distY = numpy.zeros(3)
3806 ix = 0
3824 ix = 0
3807 iy = 0
3825 iy = 0
3808
3826
3809 pairX = numpy.zeros((2,2))
3827 pairX = numpy.zeros((2,2))
3810 pairY = numpy.zeros((2,2))
3828 pairY = numpy.zeros((2,2))
3811
3829
3812 for i in range(len(listOper)):
3830 for i in range(len(listOper)):
3813 pairi = listOper[i]
3831 pairi = listOper[i]
3814
3832
3815 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
3833 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
3816
3834
3817 if posDif[0] == 0:
3835 if posDif[0] == 0:
3818 axisY.append(pairi)
3836 axisY.append(pairi)
3819 distY[iy] = posDif[1]
3837 distY[iy] = posDif[1]
@@ -3822,7 +3840,7 class SMOperations():
3822 axisX.append(pairi)
3840 axisX.append(pairi)
3823 distX[ix] = posDif[0]
3841 distX[ix] = posDif[0]
3824 ix += 1
3842 ix += 1
3825
3843
3826 for i in range(2):
3844 for i in range(2):
3827 if i==0:
3845 if i==0:
3828 dist0 = distX
3846 dist0 = distX
@@ -3830,7 +3848,7 class SMOperations():
3830 else:
3848 else:
3831 dist0 = distY
3849 dist0 = distY
3832 axis0 = axisY
3850 axis0 = axisY
3833
3851
3834 side = numpy.argsort(dist0)[:-1]
3852 side = numpy.argsort(dist0)[:-1]
3835 axis0 = numpy.array(axis0)[side,:]
3853 axis0 = numpy.array(axis0)[side,:]
3836 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
3854 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
@@ -3838,7 +3856,7 class SMOperations():
3838 side = axis1[axis1 != chanC]
3856 side = axis1[axis1 != chanC]
3839 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
3857 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
3840 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
3858 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
3841 if diff1<0:
3859 if diff1<0:
3842 chan2 = side[0]
3860 chan2 = side[0]
3843 d2 = numpy.abs(diff1)
3861 d2 = numpy.abs(diff1)
3844 chan1 = side[1]
3862 chan1 = side[1]
@@ -3848,7 +3866,7 class SMOperations():
3848 d2 = numpy.abs(diff2)
3866 d2 = numpy.abs(diff2)
3849 chan1 = side[0]
3867 chan1 = side[0]
3850 d1 = numpy.abs(diff1)
3868 d1 = numpy.abs(diff1)
3851
3869
3852 if i==0:
3870 if i==0:
3853 chanCX = chanC
3871 chanCX = chanC
3854 chan1X = chan1
3872 chan1X = chan1
@@ -3860,10 +3878,10 class SMOperations():
3860 chan2Y = chan2
3878 chan2Y = chan2
3861 distances[2:4] = numpy.array([d1,d2])
3879 distances[2:4] = numpy.array([d1,d2])
3862 # axisXsides = numpy.reshape(axisX[ix,:],4)
3880 # axisXsides = numpy.reshape(axisX[ix,:],4)
3863 #
3881 #
3864 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
3882 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
3865 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
3883 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
3866 #
3884 #
3867 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
3885 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
3868 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
3886 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
3869 # channel25X = int(pairX[0,ind25X])
3887 # channel25X = int(pairX[0,ind25X])
@@ -3872,59 +3890,59 class SMOperations():
3872 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
3890 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
3873 # channel25Y = int(pairY[0,ind25Y])
3891 # channel25Y = int(pairY[0,ind25Y])
3874 # channel20Y = int(pairY[1,ind20Y])
3892 # channel20Y = int(pairY[1,ind20Y])
3875
3893
3876 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
3894 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
3877 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
3895 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
3878
3896
3879 return pairslist, distances
3897 return pairslist, distances
3880 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
3898 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
3881 #
3899 #
3882 # arrayAOA = numpy.zeros((phases.shape[0],3))
3900 # arrayAOA = numpy.zeros((phases.shape[0],3))
3883 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
3901 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
3884 #
3902 #
3885 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3903 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3886 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3904 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3887 # arrayAOA[:,2] = cosDirError
3905 # arrayAOA[:,2] = cosDirError
3888 #
3906 #
3889 # azimuthAngle = arrayAOA[:,0]
3907 # azimuthAngle = arrayAOA[:,0]
3890 # zenithAngle = arrayAOA[:,1]
3908 # zenithAngle = arrayAOA[:,1]
3891 #
3909 #
3892 # #Setting Error
3910 # #Setting Error
3893 # #Number 3: AOA not fesible
3911 # #Number 3: AOA not fesible
3894 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3912 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3895 # error[indInvalid] = 3
3913 # error[indInvalid] = 3
3896 # #Number 4: Large difference in AOAs obtained from different antenna baselines
3914 # #Number 4: Large difference in AOAs obtained from different antenna baselines
3897 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3915 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3898 # error[indInvalid] = 4
3916 # error[indInvalid] = 4
3899 # return arrayAOA, error
3917 # return arrayAOA, error
3900 #
3918 #
3901 # def __getDirectionCosines(self, arrayPhase, pairsList):
3919 # def __getDirectionCosines(self, arrayPhase, pairsList):
3902 #
3920 #
3903 # #Initializing some variables
3921 # #Initializing some variables
3904 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3922 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3905 # ang_aux = ang_aux.reshape(1,ang_aux.size)
3923 # ang_aux = ang_aux.reshape(1,ang_aux.size)
3906 #
3924 #
3907 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
3925 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
3908 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3926 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3909 #
3927 #
3910 #
3928 #
3911 # for i in range(2):
3929 # for i in range(2):
3912 # #First Estimation
3930 # #First Estimation
3913 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
3931 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
3914 # #Dealias
3932 # #Dealias
3915 # indcsi = numpy.where(phi0_aux > numpy.pi)
3933 # indcsi = numpy.where(phi0_aux > numpy.pi)
3916 # phi0_aux[indcsi] -= 2*numpy.pi
3934 # phi0_aux[indcsi] -= 2*numpy.pi
3917 # indcsi = numpy.where(phi0_aux < -numpy.pi)
3935 # indcsi = numpy.where(phi0_aux < -numpy.pi)
3918 # phi0_aux[indcsi] += 2*numpy.pi
3936 # phi0_aux[indcsi] += 2*numpy.pi
3919 # #Direction Cosine 0
3937 # #Direction Cosine 0
3920 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
3938 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
3921 #
3939 #
3922 # #Most-Accurate Second Estimation
3940 # #Most-Accurate Second Estimation
3923 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
3941 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
3924 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3942 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3925 # #Direction Cosine 1
3943 # #Direction Cosine 1
3926 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
3944 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
3927 #
3945 #
3928 # #Searching the correct Direction Cosine
3946 # #Searching the correct Direction Cosine
3929 # cosdir0_aux = cosdir0[:,i]
3947 # cosdir0_aux = cosdir0[:,i]
3930 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3948 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
@@ -3933,51 +3951,50 class SMOperations():
3933 # indcos = cosDiff.argmin(axis = 1)
3951 # indcos = cosDiff.argmin(axis = 1)
3934 # #Saving Value obtained
3952 # #Saving Value obtained
3935 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3953 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3936 #
3954 #
3937 # return cosdir0, cosdir
3955 # return cosdir0, cosdir
3938 #
3956 #
3939 # def __calculateAOA(self, cosdir, azimuth):
3957 # def __calculateAOA(self, cosdir, azimuth):
3940 # cosdirX = cosdir[:,0]
3958 # cosdirX = cosdir[:,0]
3941 # cosdirY = cosdir[:,1]
3959 # cosdirY = cosdir[:,1]
3942 #
3960 #
3943 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3961 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3944 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
3962 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
3945 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3963 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3946 #
3964 #
3947 # return angles
3965 # return angles
3948 #
3966 #
3949 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3967 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3950 #
3968 #
3951 # Ramb = 375 #Ramb = c/(2*PRF)
3969 # Ramb = 375 #Ramb = c/(2*PRF)
3952 # Re = 6371 #Earth Radius
3970 # Re = 6371 #Earth Radius
3953 # heights = numpy.zeros(Ranges.shape)
3971 # heights = numpy.zeros(Ranges.shape)
3954 #
3972 #
3955 # R_aux = numpy.array([0,1,2])*Ramb
3973 # R_aux = numpy.array([0,1,2])*Ramb
3956 # R_aux = R_aux.reshape(1,R_aux.size)
3974 # R_aux = R_aux.reshape(1,R_aux.size)
3957 #
3975 #
3958 # Ranges = Ranges.reshape(Ranges.size,1)
3976 # Ranges = Ranges.reshape(Ranges.size,1)
3959 #
3977 #
3960 # Ri = Ranges + R_aux
3978 # Ri = Ranges + R_aux
3961 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3979 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3962 #
3980 #
3963 # #Check if there is a height between 70 and 110 km
3981 # #Check if there is a height between 70 and 110 km
3964 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3982 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3965 # ind_h = numpy.where(h_bool == 1)[0]
3983 # ind_h = numpy.where(h_bool == 1)[0]
3966 #
3984 #
3967 # hCorr = hi[ind_h, :]
3985 # hCorr = hi[ind_h, :]
3968 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3986 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3969 #
3987 #
3970 # hCorr = hi[ind_hCorr]
3988 # hCorr = hi[ind_hCorr]
3971 # heights[ind_h] = hCorr
3989 # heights[ind_h] = hCorr
3972 #
3990 #
3973 # #Setting Error
3991 # #Setting Error
3974 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3992 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3975 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3993 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3976 #
3994 #
3977 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3995 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3978 # error[indInvalid2] = 14
3996 # error[indInvalid2] = 14
3979 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3997 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3980 # error[indInvalid1] = 13
3998 # error[indInvalid1] = 13
3981 #
3999 #
3982 # return heights, error
4000 # return heights, error
3983 No newline at end of file
@@ -94,6 +94,12 class SpectraProc(ProcessingUnit):
94 blocksize += dc.size
94 blocksize += dc.size
95 blocksize += spc.size
95 blocksize += spc.size
96
96
97 #print("spc :",spc.shape)
98 data_wr = None
99 if self.dataOut.flagWR:
100 data_wr = fft_volt
101 blocksize = fft_volt.size
102
97 cspc = None
103 cspc = None
98 pairIndex = 0
104 pairIndex = 0
99 if self.dataOut.pairsList != None:
105 if self.dataOut.pairsList != None:
@@ -113,16 +119,20 class SpectraProc(ProcessingUnit):
113 pairIndex += 1
119 pairIndex += 1
114 blocksize += cspc.size
120 blocksize += cspc.size
115
121
116 self.dataOut.data_spc = spc
122 self.dataOut.data_spc = spc
117 self.dataOut.data_cspc = cspc
123 self.dataOut.data_cspc = cspc
118 self.dataOut.data_dc = dc
124 self.dataOut.data_wr = data_wr
119 self.dataOut.blockSize = blocksize
125 self.dataOut.data_dc = dc
126 self.dataOut.blockSize = blocksize
120 self.dataOut.flagShiftFFT = False
127 self.dataOut.flagShiftFFT = False
121
128
122 def run(self, nProfiles=None, nFFTPoints=None, pairsList=[], ippFactor=None, shift_fft=False):
129 def run(self, nProfiles=None, nFFTPoints=None, pairsList=[], ippFactor=None, shift_fft=False,flagWR= 0):
130
131 self.dataOut.flagWR = flagWR
123
132
124 if self.dataIn.type == "Spectra":
133 if self.dataIn.type == "Spectra":
125 self.dataOut.copy(self.dataIn)
134 self.dataOut.copy(self.dataIn)
135
126 if shift_fft:
136 if shift_fft:
127 #desplaza a la derecha en el eje 2 determinadas posiciones
137 #desplaza a la derecha en el eje 2 determinadas posiciones
128 shift = int(self.dataOut.nFFTPoints/2)
138 shift = int(self.dataOut.nFFTPoints/2)
@@ -135,7 +145,7 class SpectraProc(ProcessingUnit):
135 return True
145 return True
136
146
137 if self.dataIn.type == "Voltage":
147 if self.dataIn.type == "Voltage":
138
148 #print("VOLTAGE INPUT SPECTRA")
139 self.dataOut.flagNoData = True
149 self.dataOut.flagNoData = True
140
150
141 if nFFTPoints == None:
151 if nFFTPoints == None:
@@ -157,6 +167,7 class SpectraProc(ProcessingUnit):
157 nProfiles,
167 nProfiles,
158 self.dataIn.nHeights),
168 self.dataIn.nHeights),
159 dtype='complex')
169 dtype='complex')
170 #print("buffer :",self.buffer.shape)
160
171
161 if self.dataIn.flagDataAsBlock:
172 if self.dataIn.flagDataAsBlock:
162 nVoltProfiles = self.dataIn.data.shape[1]
173 nVoltProfiles = self.dataIn.data.shape[1]
@@ -182,6 +193,7 class SpectraProc(ProcessingUnit):
182 self.dataOut.flagNoData = True
193 self.dataOut.flagNoData = True
183 return 0
194 return 0
184 else:
195 else:
196 #print("Spectra ",self.profIndex)
185 self.buffer[:, self.profIndex, :] = self.dataIn.data.copy()
197 self.buffer[:, self.profIndex, :] = self.dataIn.data.copy()
186 self.profIndex += 1
198 self.profIndex += 1
187
199
@@ -191,6 +203,7 class SpectraProc(ProcessingUnit):
191 if self.profIndex == nProfiles:
203 if self.profIndex == nProfiles:
192 self.__updateSpecFromVoltage()
204 self.__updateSpecFromVoltage()
193 self.__getFft()
205 self.__getFft()
206 #print(" DATAOUT SHAPE SPEC",self.dataOut.data_spc.shape)
194
207
195 self.dataOut.flagNoData = False
208 self.dataOut.flagNoData = False
196 self.firstdatatime = None
209 self.firstdatatime = None
@@ -291,16 +304,16 class SpectraProc(ProcessingUnit):
291 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
304 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
292 self.dataOut.channelList = range(len(channelIndexList))
305 self.dataOut.channelList = range(len(channelIndexList))
293 self.__selectPairsByChannel(channelIndexList)
306 self.__selectPairsByChannel(channelIndexList)
294
307
295 return 1
308 return 1
296
309
297
310
298 def selectFFTs(self, minFFT, maxFFT ):
311 def selectFFTs(self, minFFT, maxFFT ):
299 """
312 """
300 Selecciona un bloque de datos en base a un grupo de valores de puntos FFTs segun el rango
313 Selecciona un bloque de datos en base a un grupo de valores de puntos FFTs segun el rango
301 minFFT<= FFT <= maxFFT
314 minFFT<= FFT <= maxFFT
302 """
315 """
303
316
304 if (minFFT > maxFFT):
317 if (minFFT > maxFFT):
305 raise ValueError("Error selecting heights: Height range (%d,%d) is not valid" % (minFFT, maxFFT))
318 raise ValueError("Error selecting heights: Height range (%d,%d) is not valid" % (minFFT, maxFFT))
306
319
@@ -330,20 +343,20 class SpectraProc(ProcessingUnit):
330 self.selectFFTsByIndex(minIndex, maxIndex)
343 self.selectFFTsByIndex(minIndex, maxIndex)
331
344
332 return 1
345 return 1
333
346
334
347
335 def setH0(self, h0, deltaHeight = None):
348 def setH0(self, h0, deltaHeight = None):
336
349
337 if not deltaHeight:
350 if not deltaHeight:
338 deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
351 deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
339
352
340 nHeights = self.dataOut.nHeights
353 nHeights = self.dataOut.nHeights
341
354
342 newHeiRange = h0 + numpy.arange(nHeights)*deltaHeight
355 newHeiRange = h0 + numpy.arange(nHeights)*deltaHeight
343
356
344 self.dataOut.heightList = newHeiRange
357 self.dataOut.heightList = newHeiRange
345
358
346
359
347 def selectHeights(self, minHei, maxHei):
360 def selectHeights(self, minHei, maxHei):
348 """
361 """
349 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
362 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
@@ -360,7 +373,7 class SpectraProc(ProcessingUnit):
360 1 si el metodo se ejecuto con exito caso contrario devuelve 0
373 1 si el metodo se ejecuto con exito caso contrario devuelve 0
361 """
374 """
362
375
363
376
364 if (minHei > maxHei):
377 if (minHei > maxHei):
365 raise ValueError("Error selecting heights: Height range (%d,%d) is not valid" % (minHei, maxHei))
378 raise ValueError("Error selecting heights: Height range (%d,%d) is not valid" % (minHei, maxHei))
366
379
@@ -388,7 +401,7 class SpectraProc(ProcessingUnit):
388 maxIndex = len(heights)
401 maxIndex = len(heights)
389
402
390 self.selectHeightsByIndex(minIndex, maxIndex)
403 self.selectHeightsByIndex(minIndex, maxIndex)
391
404
392
405
393 return 1
406 return 1
394
407
@@ -436,7 +449,7 class SpectraProc(ProcessingUnit):
436
449
437 def selectFFTsByIndex(self, minIndex, maxIndex):
450 def selectFFTsByIndex(self, minIndex, maxIndex):
438 """
451 """
439
452
440 """
453 """
441
454
442 if (minIndex < 0) or (minIndex > maxIndex):
455 if (minIndex < 0) or (minIndex > maxIndex):
@@ -459,7 +472,7 class SpectraProc(ProcessingUnit):
459 self.dataOut.data_spc = data_spc
472 self.dataOut.data_spc = data_spc
460 self.dataOut.data_cspc = data_cspc
473 self.dataOut.data_cspc = data_cspc
461 self.dataOut.data_dc = data_dc
474 self.dataOut.data_dc = data_dc
462
475
463 self.dataOut.ippSeconds = self.dataOut.ippSeconds*(self.dataOut.nFFTPoints / numpy.shape(data_cspc)[1])
476 self.dataOut.ippSeconds = self.dataOut.ippSeconds*(self.dataOut.nFFTPoints / numpy.shape(data_cspc)[1])
464 self.dataOut.nFFTPoints = numpy.shape(data_cspc)[1]
477 self.dataOut.nFFTPoints = numpy.shape(data_cspc)[1]
465 self.dataOut.profilesPerBlock = numpy.shape(data_cspc)[1]
478 self.dataOut.profilesPerBlock = numpy.shape(data_cspc)[1]
@@ -552,7 +565,7 class SpectraProc(ProcessingUnit):
552 xx_inv = numpy.linalg.inv(xx)
565 xx_inv = numpy.linalg.inv(xx)
553 xx_aux = xx_inv[0, :]
566 xx_aux = xx_inv[0, :]
554
567
555 for ich in range(num_chan):
568 for ich in range(num_chan):
556 yy = jspectra[ich, ind_vel, :]
569 yy = jspectra[ich, ind_vel, :]
557 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
570 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
558
571
@@ -574,12 +587,12 class SpectraProc(ProcessingUnit):
574 return 1
587 return 1
575
588
576 def removeInterference2(self):
589 def removeInterference2(self):
577
590
578 cspc = self.dataOut.data_cspc
591 cspc = self.dataOut.data_cspc
579 spc = self.dataOut.data_spc
592 spc = self.dataOut.data_spc
580 Heights = numpy.arange(cspc.shape[2])
593 Heights = numpy.arange(cspc.shape[2])
581 realCspc = numpy.abs(cspc)
594 realCspc = numpy.abs(cspc)
582
595
583 for i in range(cspc.shape[0]):
596 for i in range(cspc.shape[0]):
584 LinePower= numpy.sum(realCspc[i], axis=0)
597 LinePower= numpy.sum(realCspc[i], axis=0)
585 Threshold = numpy.amax(LinePower)-numpy.sort(LinePower)[len(Heights)-int(len(Heights)*0.1)]
598 Threshold = numpy.amax(LinePower)-numpy.sort(LinePower)[len(Heights)-int(len(Heights)*0.1)]
@@ -587,17 +600,17 class SpectraProc(ProcessingUnit):
587 InterferenceSum = numpy.sum( realCspc[i,:,SelectedHeights], axis=0 )
600 InterferenceSum = numpy.sum( realCspc[i,:,SelectedHeights], axis=0 )
588 InterferenceThresholdMin = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.98)]
601 InterferenceThresholdMin = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.98)]
589 InterferenceThresholdMax = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.99)]
602 InterferenceThresholdMax = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.99)]
590
603
591
604
592 InterferenceRange = numpy.where( ([InterferenceSum > InterferenceThresholdMin]))# , InterferenceSum < InterferenceThresholdMax]) )
605 InterferenceRange = numpy.where( ([InterferenceSum > InterferenceThresholdMin]))# , InterferenceSum < InterferenceThresholdMax]) )
593 #InterferenceRange = numpy.where( ([InterferenceRange < InterferenceThresholdMax]))
606 #InterferenceRange = numpy.where( ([InterferenceRange < InterferenceThresholdMax]))
594 if len(InterferenceRange)<int(cspc.shape[1]*0.3):
607 if len(InterferenceRange)<int(cspc.shape[1]*0.3):
595 cspc[i,InterferenceRange,:] = numpy.NaN
608 cspc[i,InterferenceRange,:] = numpy.NaN
596
609
597
610
598
611
599 self.dataOut.data_cspc = cspc
612 self.dataOut.data_cspc = cspc
600
613
601 def removeInterference(self, interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None):
614 def removeInterference(self, interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None):
602
615
603 jspectra = self.dataOut.data_spc
616 jspectra = self.dataOut.data_spc
@@ -931,7 +944,7 class IncohInt(Operation):
931 if n is not None:
944 if n is not None:
932 self.n = int(n)
945 self.n = int(n)
933 else:
946 else:
934
947
935 self.__integrationtime = int(timeInterval)
948 self.__integrationtime = int(timeInterval)
936 self.n = None
949 self.n = None
937 self.__byTime = True
950 self.__byTime = True
@@ -941,6 +954,9 class IncohInt(Operation):
941 Add a profile to the __buffer_spc and increase in one the __profileIndex
954 Add a profile to the __buffer_spc and increase in one the __profileIndex
942
955
943 """
956 """
957 print("profIndex: ",self.__profIndex)
958 print("data_spc.shape: ",data_spc.shape)
959 print("data_spc.shape: ",data_spc[0,0,:])
944
960
945 self.__buffer_spc += data_spc
961 self.__buffer_spc += data_spc
946
962
@@ -1032,7 +1048,7 class IncohInt(Operation):
1032 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
1048 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
1033 if n == 1:
1049 if n == 1:
1034 return
1050 return
1035
1051
1036 dataOut.flagNoData = True
1052 dataOut.flagNoData = True
1037
1053
1038 if not self.isConfig:
1054 if not self.isConfig:
@@ -1048,9 +1064,197 class IncohInt(Operation):
1048
1064
1049 dataOut.data_spc = avgdata_spc
1065 dataOut.data_spc = avgdata_spc
1050 dataOut.data_cspc = avgdata_cspc
1066 dataOut.data_cspc = avgdata_cspc
1051 dataOut.data_dc = avgdata_dc
1067 dataOut.data_dc = avgdata_dc
1052 dataOut.nIncohInt *= self.n
1068 dataOut.nIncohInt *= self.n
1053 dataOut.utctime = avgdatatime
1069 dataOut.utctime = avgdatatime
1054 dataOut.flagNoData = False
1070 dataOut.flagNoData = False
1055
1071
1056 return dataOut No newline at end of file
1072 return dataOut
1073
1074
1075 class PulsePair(Operation):
1076 isConfig = False
1077 __profIndex = 0
1078 __profIndex2 = 0
1079 __initime = None
1080 __lastdatatime = None
1081 __buffer = None
1082 __buffer2 = []
1083 __buffer3 = None
1084 __dataReady = False
1085 n = None
1086
1087 __nch =0
1088 __nProf =0
1089 __nHeis =0
1090
1091 def __init__(self,**kwargs):
1092 Operation.__init__(self,**kwargs)
1093
1094 def setup(self,dataOut,n =None, m = None):
1095
1096 self.__initime = None
1097 self.__lastdatatime = 0
1098 self.__buffer = 0
1099 self.__bufferV = 0
1100 #self.__buffer2 = []
1101 self.__buffer3 = 0
1102 self.__dataReady = False
1103 self.__profIndex = 0
1104 self.__profIndex2 = 0
1105 self.count = 0
1106
1107
1108 self.__nch = dataOut.nChannels
1109 self.__nHeis = dataOut.nHeights
1110 self.__nProf = dataOut.nProfiles
1111 self.__nFFT = dataOut.nFFTPoints
1112 #print("Valores de Ch,Samples,Perfiles,nFFT",self.__nch,self.__nHeis,self.__nProf, self.__nFFT)
1113 #print("EL VALOR DE n es:",n)
1114 if n == None:
1115 raise ValueError("n Should be specified.")
1116
1117 if n != None:
1118 if n<2:
1119 raise ValueError("n Should be greather than 2 ")
1120 self.n = n
1121 if m == None:
1122 m = n
1123 if m != None:
1124 if m<2:
1125 raise ValueError("n Should be greather than 2 ")
1126
1127 self.m = m
1128 self.__buffer2 = numpy.zeros((self.__nch,self.m,self.__nHeis))
1129 self.__bufferV2 = numpy.zeros((self.__nch,self.m,self.__nHeis))
1130
1131
1132
1133 def putData(self,data):
1134 #print("###################################################")
1135 '''
1136 data_tmp = numpy.zeros(self.__nch,self.n,self.__nHeis, dtype= complex)
1137 if self.count < self.__nProf:
1138
1139 for i in range(self.n):
1140 data_tmp[:,i,:] = data[:,i+self.count,:]
1141
1142 self.__buffer = data_tmp*numpy.conjugate(data_tmp)
1143
1144
1145 #####self.__buffer = data*numpy.conjugate(data)
1146 #####self.__bufferV = data[:,(self.__nProf-1):,:]*numpy.conjugate(data[:,1:,:])
1147
1148 #self.__buffer2.append(numpy.conjugate(data))
1149
1150 #####self.__profIndex = data.shape[1]
1151 self.count = self.count + self.n -1
1152 self.__profIndex = self.n
1153 '''
1154 self.__buffer = data*numpy.conjugate(data)
1155 self.__bufferV = data[:,(self.__nProf-1):,:]*numpy.conjugate(data[:,1:,:])
1156 self.__profIndex = self.n
1157 return
1158
1159 def pushData(self):
1160
1161 data_I = numpy.zeros((self.__nch,self.__nHeis))
1162 data_IV = numpy.zeros((self.__nch,self.__nHeis))
1163
1164 for i in range(self.__nch):
1165 data_I[i,:] = numpy.sum(numpy.sum(self.__buffer[i],axis=0),axis=0)/self.n
1166 data_IV[i,:] = numpy.sum(numpy.sum(self.__bufferV[i],axis=0),axis=0)/(self.n-1)
1167
1168 n = self.__profIndex
1169 ####data_intensity = numpy.sum(numpy.sum(self.__buffer,axis=0),axis=0)/self.n
1170 #print("data_intensity push data",data_intensity.shape)
1171 #data_velocity = self.__buffer3/(self.n-1)
1172 ####n = self.__profIndex
1173
1174 self.__buffer = 0
1175 self.__buffer3 = 0
1176 self.__profIndex = 0
1177
1178 #return data_intensity,data_velocity,n
1179 return data_I,data_IV,n
1180
1181 def pulsePairbyProfiles(self,data):
1182 self.__dataReady = False
1183 data_intensity = None
1184 data_velocity = None
1185
1186 self.putData(data)
1187
1188 if self.__profIndex == self.n:
1189 #data_intensity,data_velocity,n = self.pushData()
1190 data_intensity,data_velocity,n = self.pushData()
1191 #print(data_intensity.shape)
1192 #print("self.__profIndex2", self.__profIndex2)
1193 if self.__profIndex2 == 0:
1194 #print("PRIMERA VEZ")
1195 #print("self.__buffer2",self.__buffer2)
1196 for i in range(self.__nch):
1197 self.__buffer2[i][self.__profIndex2] = data_intensity[i]
1198 self.__bufferV2[i][self.__profIndex2] = data_velocity[i]
1199 self.__profIndex2 += 1
1200 return None,None
1201
1202 if self.__profIndex2 > 0:
1203 for i in range(self.__nch):
1204 self.__buffer2[i][self.__profIndex2] = data_intensity[i]
1205 self.__bufferV2[i][self.__profIndex2] = data_velocity[i]
1206 #print("Dentro del bucle",self.__buffer2)
1207 self.__profIndex2 += 1
1208 if self.__profIndex2 == self.m :
1209 data_i = self.__buffer2
1210 data_v = self.__bufferV2
1211 #print(data_i.shape)
1212 self.__dataReady = True
1213 self.__profIndex2 = 0
1214 self.__buffer2 = numpy.zeros((self.__nch,self.m,self.__nHeis))
1215 self.__bufferV2 = numpy.zeros((self.__nch,self.m,self.__nHeis))
1216 return data_i,data_v
1217 return None,None
1218
1219 def pulsePairOp(self,data,datatime=None):
1220 if self.__initime == None:
1221 self.__initime = datatime
1222
1223 data_intensity,data_velocity = self.pulsePairbyProfiles(data)
1224 self.__lastdatatime = datatime
1225
1226 if data_intensity is None:
1227 return None,None,None
1228
1229 avgdatatime = self.__initime
1230 self.__initime = datatime
1231
1232 return data_intensity,data_velocity,avgdatatime
1233
1234 def run(self,dataOut,n =None,m=None):
1235
1236 if not self.isConfig:
1237 self.setup(dataOut = dataOut, n = n, m = m)
1238 self.isConfig = True
1239
1240 data_intensity,data_velocity,avgdatatime = self.pulsePairOp(dataOut.data_wr,dataOut.utctime)
1241 dataOut.flagNoData = True
1242
1243 if self.__dataReady:
1244 #print(" DATA " , data_intensity.shape)
1245 #dataOut.data = numpy.array([data_intensity])#aqui amigo revisa
1246 #tmp = numpy.zeros([1,data_intensity.shape[0],data_intensity.shape[1]])
1247 #tmp[0] = data_intensity
1248 dataOut.data = data_intensity
1249 dataOut.data_velocity = data_velocity
1250 #dataOut.data = tmp
1251 #print(" DATA " , dataOut.data.shape)
1252 dataOut.nIncohInt *= self.n
1253 dataOut.nProfiles = self.m
1254 dataOut.nFFTPoints = self.m
1255 #dataOut.data_intensity = data_intensity
1256 dataOut.PRFbyAngle = self.n
1257 dataOut.utctime = avgdatatime
1258 dataOut.flagNoData = False
1259 #####print("TIEMPO: ",dataOut.utctime)
1260 return dataOut
@@ -8,8 +8,8 from time import time
8
8
9
9
10 @MPDecorator
10 @MPDecorator
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)
@@ -115,7 +115,7 class VoltageProc(ProcessingUnit):
115 self.dataOut.data = data
115 self.dataOut.data = data
116 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
116 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
117 self.dataOut.channelList = range(len(channelIndexList))
117 self.dataOut.channelList = range(len(channelIndexList))
118
118
119 return 1
119 return 1
120
120
121 def selectHeights(self, minHei=None, maxHei=None):
121 def selectHeights(self, minHei=None, maxHei=None):
@@ -229,7 +229,7 class VoltageProc(ProcessingUnit):
229 """
229 """
230 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
230 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
231 """
231 """
232 buffer = self.dataOut.data[:, :, 0:int(self.dataOut.nHeights-r)]
232 buffer = self.dataOut.data[:, :, 0:int(self.dataOut.nHeights-r)]
233 buffer = buffer.reshape(self.dataOut.nChannels, self.dataOut.nProfiles, int(self.dataOut.nHeights/window), window)
233 buffer = buffer.reshape(self.dataOut.nChannels, self.dataOut.nProfiles, int(self.dataOut.nHeights/window), window)
234 buffer = numpy.sum(buffer,3)
234 buffer = numpy.sum(buffer,3)
235
235
@@ -384,14 +384,16 class CohInt(Operation):
384 """
384 """
385
385
386 if not self.__withOverlapping:
386 if not self.__withOverlapping:
387 print("inside over")
387 self.__buffer += data.copy()
388 self.__buffer += data.copy()
388 self.__profIndex += 1
389 self.__profIndex += 1
389 return
390 return
390
391
391 #Overlapping data
392 #Overlapping data
392 nChannels, nHeis = data.shape
393 nChannels, nHeis = data.shape
394 print("show me the light",data.shape)
393 data = numpy.reshape(data, (1, nChannels, nHeis))
395 data = numpy.reshape(data, (1, nChannels, nHeis))
394
396 print(data.shape)
395 #If the buffer is empty then it takes the data value
397 #If the buffer is empty then it takes the data value
396 if self.__buffer is None:
398 if self.__buffer is None:
397 self.__buffer = data
399 self.__buffer = data
@@ -422,6 +424,7 class CohInt(Operation):
422 """
424 """
423
425
424 if not self.__withOverlapping:
426 if not self.__withOverlapping:
427 #print("ahora que fue")
425 data = self.__buffer
428 data = self.__buffer
426 n = self.__profIndex
429 n = self.__profIndex
427
430
@@ -430,6 +433,7 class CohInt(Operation):
430
433
431 return data, n
434 return data, n
432
435
436 #print("cual funciona")
433 #Integration with Overlapping
437 #Integration with Overlapping
434 data = numpy.sum(self.__buffer, axis=0)
438 data = numpy.sum(self.__buffer, axis=0)
435 # print data
439 # print data
@@ -445,6 +449,7 class CohInt(Operation):
445 # n = None
449 # n = None
446 # print data
450 # print data
447 # raise
451 # raise
452 #print("beforeputdata")
448 self.putData(data)
453 self.putData(data)
449
454
450 if self.__profIndex == self.n:
455 if self.__profIndex == self.n:
@@ -497,8 +502,8 class CohInt(Operation):
497 # print self.__bufferStride[self.__profIndexStride - 1]
502 # print self.__bufferStride[self.__profIndexStride - 1]
498 # raise
503 # raise
499 return self.__bufferStride[self.__profIndexStride - 1]
504 return self.__bufferStride[self.__profIndexStride - 1]
500
505
501
506
502 return None, None
507 return None, None
503
508
504 def integrate(self, data, datatime=None):
509 def integrate(self, data, datatime=None):
@@ -520,7 +525,7 class CohInt(Operation):
520 avgdatatime = self.__initime
525 avgdatatime = self.__initime
521
526
522 deltatime = datatime - self.__lastdatatime
527 deltatime = datatime - self.__lastdatatime
523
528
524 if not self.__withOverlapping:
529 if not self.__withOverlapping:
525 self.__initime = datatime
530 self.__initime = datatime
526 else:
531 else:
@@ -546,7 +551,7 class CohInt(Operation):
546 avgdatatime = (times - 1) * timeInterval + dataOut.utctime
551 avgdatatime = (times - 1) * timeInterval + dataOut.utctime
547 self.__dataReady = True
552 self.__dataReady = True
548 return avgdata, avgdatatime
553 return avgdata, avgdatatime
549
554
550 def run(self, dataOut, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False, **kwargs):
555 def run(self, dataOut, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False, **kwargs):
551
556
552 if not self.isConfig:
557 if not self.isConfig:
@@ -560,12 +565,12 class CohInt(Operation):
560 avgdata, avgdatatime = self.integrateByBlock(dataOut)
565 avgdata, avgdatatime = self.integrateByBlock(dataOut)
561 dataOut.nProfiles /= self.n
566 dataOut.nProfiles /= self.n
562 else:
567 else:
563 if stride is None:
568 if stride is None:
564 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
569 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
565 else:
570 else:
566 avgdata, avgdatatime = self.integrateByStride(dataOut.data, dataOut.utctime)
571 avgdata, avgdatatime = self.integrateByStride(dataOut.data, dataOut.utctime)
567
572
568
573
569 # dataOut.timeInterval *= n
574 # dataOut.timeInterval *= n
570 dataOut.flagNoData = True
575 dataOut.flagNoData = True
571
576
@@ -670,11 +675,11 class Decoder(Operation):
670 junk = junk.flatten()
675 junk = junk.flatten()
671 code_block = numpy.reshape(junk, (self.nCode*repetitions, self.nBaud))
676 code_block = numpy.reshape(junk, (self.nCode*repetitions, self.nBaud))
672 profilesList = range(self.__nProfiles)
677 profilesList = range(self.__nProfiles)
673
678
674 for i in range(self.__nChannels):
679 for i in range(self.__nChannels):
675 for j in profilesList:
680 for j in profilesList:
676 self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:]
681 self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:]
677 return self.datadecTime
682 return self.datadecTime
678
683
679 def __convolutionByBlockInFreq(self, data):
684 def __convolutionByBlockInFreq(self, data):
680
685
@@ -691,7 +696,7 class Decoder(Operation):
691
696
692 return data
697 return data
693
698
694
699
695 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0, osamp=None, times=None):
700 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0, osamp=None, times=None):
696
701
697 if dataOut.flagDecodeData:
702 if dataOut.flagDecodeData:
@@ -722,7 +727,7 class Decoder(Operation):
722
727
723 self.__nProfiles = dataOut.nProfiles
728 self.__nProfiles = dataOut.nProfiles
724 datadec = None
729 datadec = None
725
730
726 if mode == 3:
731 if mode == 3:
727 mode = 0
732 mode = 0
728
733
@@ -1105,9 +1110,9 class SplitProfiles(Operation):
1105
1110
1106 if shape[2] % n != 0:
1111 if shape[2] % n != 0:
1107 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[2]))
1112 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[2]))
1108
1113
1109 new_shape = shape[0], shape[1]*n, int(shape[2]/n)
1114 new_shape = shape[0], shape[1]*n, int(shape[2]/n)
1110
1115
1111 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1116 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1112 dataOut.flagNoData = False
1117 dataOut.flagNoData = False
1113
1118
@@ -1191,6 +1196,296 class CombineProfiles(Operation):
1191 dataOut.ippSeconds *= n
1196 dataOut.ippSeconds *= n
1192
1197
1193 return dataOut
1198 return dataOut
1199
1200
1201
1202 class CreateBlockVoltage(Operation):
1203
1204 isConfig = False
1205 __Index = 0
1206 bufferShape = None
1207 buffer = None
1208 firstdatatime = None
1209
1210 def __init__(self,**kwargs):
1211 Operation.__init__(self,**kwargs)
1212 self.isConfig = False
1213 self.__Index = 0
1214 self.firstdatatime = None
1215
1216 def setup(self,dataOut, m = None ):
1217 '''
1218 m= Numero perfiles
1219 '''
1220 #print("CONFIGURANDO CBV")
1221 self.__nChannels = dataOut.nChannels
1222 self.__nHeis = dataOut.nHeights
1223 shape = dataOut.data.shape #nchannels, nprofiles, nsamples
1224 #print("input nChannels",self.__nChannels)
1225 #print("input nHeis",self.__nHeis)
1226 #print("SETUP CREATE BLOCK VOLTAGE")
1227 #print("input Shape",shape)
1228 #print("dataOut.nProfiles",dataOut.nProfiles)
1229 numberSamples = self.__nHeis
1230 numberProfile = int(m)
1231 dataOut.nProfiles = numberProfile
1232 #print("new numberProfile",numberProfile)
1233 #print("new numberSamples",numberSamples)
1234
1235 self.bufferShape = shape[0], numberProfile, numberSamples # nchannels,nprofiles,nsamples
1236 self.buffer = numpy.zeros((self.bufferShape))
1237 self.bufferVel = numpy.zeros((self.bufferShape))
1238
1239 def run(self, dataOut, m=None):
1240 #print("RUN")
1241 dataOut.flagNoData = True
1242 dataOut.flagDataAsBlock = False
1243 #print("BLOCK INDEX ",self.__Index)
1244
1245 if not self.isConfig:
1246 self.setup(dataOut, m= m)
1247 self.isConfig = True
1248 if self.__Index < m:
1249 #print("PROFINDEX BLOCK CBV",self.__Index)
1250 self.buffer[:,self.__Index,:] = dataOut.data
1251 self.bufferVel[:,self.__Index,:] = dataOut.data_velocity
1252 self.__Index += 1
1253 dataOut.flagNoData = True
1254
1255 if self.firstdatatime == None:
1256 self.firstdatatime = dataOut.utctime
1257
1258 if self.__Index == m:
1259 #print("**********************************************")
1260 #print("self.buffer.shape ",self.buffer.shape)
1261 #print("##############",self.firstdatatime)
1262 ##print("*********************************************")
1263 ##print("*********************************************")
1264 ##print("******* nProfiles *******", dataOut.nProfiles)
1265 ##print("*********************************************")
1266 ##print("*********************************************")
1267 dataOut.data = self.buffer
1268 dataOut.data_velocity = self.bufferVel
1269 dataOut.utctime = self.firstdatatime
1270 dataOut.nProfiles = m
1271 self.firstdatatime = None
1272 dataOut.flagNoData = False
1273 dataOut.flagDataAsBlock = True
1274 self.__Index = 0
1275 dataOut.identifierWR = True
1276 return dataOut
1277
1278 class PulsePairVoltage(Operation):
1279 '''
1280 Function PulsePair(Signal Power, Velocity)
1281 The real component of Lag[0] provides Intensity Information
1282 The imag component of Lag[1] Phase provides Velocity Information
1283
1284 Configuration Parameters:
1285 nPRF = Number of Several PRF
1286 theta = Degree Azimuth angel Boundaries
1287
1288 Input:
1289 self.dataOut
1290 lag[N]
1291 Affected:
1292 self.dataOut.spc
1293 '''
1294 isConfig = False
1295 __profIndex = 0
1296 __initime = None
1297 __lastdatatime = None
1298 __buffer = None
1299 __buffer2 = []
1300 __buffer3 = None
1301 __dataReady = False
1302 n = None
1303 __nch = 0
1304 __nHeis = 0
1305
1306 def __init__(self,**kwargs):
1307 Operation.__init__(self,**kwargs)
1308
1309 def setup(self, dataOut, n = None ):
1310 '''
1311 n= Numero de PRF's de entrada
1312 '''
1313 self.__initime = None
1314 self.__lastdatatime = 0
1315 self.__dataReady = False
1316 self.__buffer = 0
1317 self.__buffer2 = []
1318 self.__buffer3 = 0
1319 self.__profIndex = 0
1320
1321 self.__nch = dataOut.nChannels
1322 self.__nHeis = dataOut.nHeights
1323
1324 print("ELVALOR DE n es:", n)
1325 if n == None:
1326 raise ValueError("n should be specified.")
1327
1328 if n != None:
1329 if n<2:
1330 raise ValueError("n should be greater than 2")
1331
1332 self.n = n
1333 self.__nProf = n
1334 '''
1335 if overlapping:
1336 self.__withOverlapping = True
1337 self.__buffer = None
1338
1339 else:
1340 #print ("estoy sin __withO")
1341 self.__withOverlapping = False
1342 self.__buffer = 0
1343 self.__buffer2 = []
1344 self.__buffer3 = 0
1345 '''
1346
1347 def putData(self,data):
1348 '''
1349 Add a profile to he __buffer and increase in one the __profiel Index
1350 '''
1351 #print("self.__profIndex :",self.__profIndex)
1352 self.__buffer += data*numpy.conjugate(data)
1353 self.__buffer2.append(numpy.conjugate(data))
1354 if self.__profIndex > 0:
1355 self.__buffer3 += self.__buffer2[self.__profIndex-1]*data
1356 self.__profIndex += 1
1357 return
1358 '''
1359 if not self.__withOverlapping:
1360 #print("Putdata inside over")
1361 self.__buffer += data* numpy.conjugate(data)
1362 self.__buffer2.append(numpy.conjugate(data))
1363
1364 if self.__profIndex >0:
1365 self.__buffer3 += self.__buffer2[self.__profIndex-1]*data
1366 self.__profIndex += 1
1367 return
1368
1369 if self.__buffer is None:
1370 #print("aqui bro")
1371 self.__buffer = data* numpy.conjugate(data)
1372 self.__buffer2.append(numpy.conjugate(data))
1373 self.__profIndex += 1
1374
1375 return
1376
1377 if self.__profIndex < self.n:
1378 self.__buffer = numpy.vstack(self.__buffer,data* numpy.conjugate(data))
1379 self.__buffer2.append(numpy.conjugate(data))
1380
1381 if self.__profIndex == 1:
1382 self.__buffer3 = self.__buffer2[self.__profIndex -1] * data
1383 else:
1384 self.__buffer3 = numpy.vstack(self.__buffer3, self.__buffer2[self.profIndex-1]*data)
1385
1386 self.__profIndex += 1
1387 return
1388 '''
1389
1390 def pushData(self):
1391 '''
1392 Return the PULSEPAIR and the profiles used in the operation
1393 Affected : self.__profileIndex
1394 '''
1395 #print("************************************************")
1396 #print("push data int vel n")
1397 data_intensity = self.__buffer/self.n
1398 data_velocity = self.__buffer3/(self.n-1)
1399 n = self.__profIndex
1400
1401 self.__buffer = 0
1402 self.__buffer2 = []
1403 self.__buffer3 = 0
1404 self.__profIndex = 0
1405
1406 return data_intensity, data_velocity,n
1407 '''
1408 if not self.__withOverlapping:
1409 #print("ahora que fue")
1410 data_intensity = self.__buffer/self.n
1411 data_velocity = self.__buffer3/(self.n-1)
1412 n = self.__profIndex
1413
1414 self.__buffer = 0
1415 self.__buffer2 = []
1416 self.__buffer3 = 0
1417 self.__profIndex = 0
1418 return data_intensity, data_velocity,n
1419
1420 data_intensity = numpy.sum(self.__buffer,axis = 0)
1421 data_velocity = numpy.sum(self.__buffer3,axis = 0)
1422 n = self.__profIndex
1423 #self.__buffer = 0
1424 #self.__buffer2 = []
1425 #self.__buffer3 = 0
1426 #self.__profIndex = 0
1427 return data_intensity, data_velocity,n
1428 '''
1429
1430 def pulsePairbyProfiles(self,data):
1431
1432 self.__dataReady = False
1433 data_intensity = None
1434 data_velocity = None
1435 #print("beforeputada")
1436 self.putData(data)
1437 #print("ProfileIndex:",self.__profIndex)
1438 if self.__profIndex == self.n:
1439 data_intensity, data_velocity, n = self.pushData()
1440 self.__dataReady = True
1441 #print("-----------------------------------------------")
1442 #print("data_intensity",data_intensity.shape,"data_velocity",data_velocity.shape)
1443 return data_intensity, data_velocity
1444
1445 def pulsePairOp(self, data, datatime= None):
1446
1447 if self.__initime == None:
1448 self.__initime = datatime
1449
1450 data_intensity, data_velocity = self.pulsePairbyProfiles(data)
1451 self.__lastdatatime = datatime
1452
1453 if data_intensity is None:
1454 return None, None, None
1455
1456 avgdatatime = self.__initime
1457 deltatime = datatime - self.__lastdatatime
1458 self.__initime = datatime
1459 '''
1460 if not self.__withOverlapping:
1461 self.__initime = datatime
1462 else:
1463 self.__initime += deltatime
1464 '''
1465 return data_intensity, data_velocity, avgdatatime
1466
1467 def run(self, dataOut,n = None, overlapping= False,**kwargs):
1468
1469 if not self.isConfig:
1470 self.setup(dataOut = dataOut, n = n , **kwargs)
1471 self.isConfig = True
1472 #print("*******************")
1473 #print("print Shape input data:",dataOut.data.shape)
1474 data_intensity, data_velocity, avgdatatime = self.pulsePairOp(dataOut.data, dataOut.utctime)
1475 dataOut.flagNoData = True
1476
1477 if self.__dataReady:
1478 #print("#------------------------------------------------------")
1479 #print("data_ready",data_intensity.shape)
1480 dataOut.data = data_intensity #valor para plotear RTI
1481 dataOut.nCohInt *= self.n
1482 dataOut.data_intensity = data_intensity #valor para intensidad
1483 dataOut.data_velocity = data_velocity #valor para velocidad
1484 dataOut.PRFbyAngle = self.n #numero de PRF*cada angulo rotado que equivale a un tiempo.
1485 dataOut.utctime = avgdatatime
1486 dataOut.flagNoData = False
1487 return dataOut
1488
1194 # import collections
1489 # import collections
1195 # from scipy.stats import mode
1490 # from scipy.stats import mode
1196 #
1491 #
@@ -25,9 +25,10 controllerObj.setup(id = '191', name='Test_USRP', description=desc)
25 #path = '/media/data/data/vientos/57.2063km/echoes/NCO_Woodman'
25 #path = '/media/data/data/vientos/57.2063km/echoes/NCO_Woodman'
26
26
27
27
28 path = '/home/soporte/data_hdf5' #### with clock 35.16 db noise
28 #path = '/home/soporte/data_hdf5' #### with clock 35.16 db noise
29
29 path = '/home/alex/WEATHER_DATA/DATA'
30 figpath = '/home/soporte/data_hdf5_imag'
30 figpath = '/home/alex/WEATHER_DATA/DATA/pic'
31 #figpath = '/home/soporte/data_hdf5_imag'
31 #remotefolder = "/home/wmaster/graficos"
32 #remotefolder = "/home/wmaster/graficos"
32 #######################################################################
33 #######################################################################
33 ################# RANGO DE PLOTEO######################################
34 ################# RANGO DE PLOTEO######################################
@@ -95,14 +96,33 procUnitConfObjA = controllerObj.addProcUnit(datatype='VoltageProc', inputId=rea
95 #opObj11.addParameter(name='nBaud', value='28', format='int')
96 #opObj11.addParameter(name='nBaud', value='28', format='int')
96
97
97 #opObj11 = procUnitConfObjA.addOperation(name='CohInt', optype='other')
98 #opObj11 = procUnitConfObjA.addOperation(name='CohInt', optype='other')
98 #opObj11.addParameter(name='n', value='100', format='int')
99 #opObj11.addParameter(name='n', value='10', format='int')
100
101
102 opObj11 = procUnitConfObjA.addOperation(name='PulsePair', optype='other')
103 opObj11.addParameter(name='n', value='10', format='int')
104
105 opObj11 = procUnitConfObjA.addOperation(name='CreateBlockVoltage', optype='other')
106 opObj11.addParameter(name='m', value='16', format='int')
107
108 procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObjA.getId())
99
109
110 #Not used because the RGB data is obtained directly from the HF Reader.
111 #opObj21 = procUnitConfObj2.addOperation(name='GetRGBData')
112
113 opObj21 = procUnitConfObj2.addOperation(name='ParamWriter', optype='external')
114 opObj21.addParameter(name='path', value=figpath+'/NEWData')
115 opObj21.addParameter(name='blocksPerFile', value='1', format='int')
116 opObj21.addParameter(name='metadataList',value='heightList',format='list')
117 opObj21.addParameter(name='dataList',value='data_intensity',format='list')
118
119 '''
100 #######################################################################
120 #######################################################################
101 ########## OPERACIONES DOMINIO DE LA FRECUENCIA########################
121 ########## OPERACIONES DOMINIO DE LA FRECUENCIA########################
102 #######################################################################
122 #######################################################################
103 procUnitConfObjSousySpectra = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjA.getId())
123 procUnitConfObjSousySpectra = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjA.getId())
104 procUnitConfObjSousySpectra.addParameter(name='nFFTPoints', value='100', format='int')
124 procUnitConfObjSousySpectra.addParameter(name='nFFTPoints', value='16', format='int')
105 procUnitConfObjSousySpectra.addParameter(name='nProfiles', value='100', format='int')
125 procUnitConfObjSousySpectra.addParameter(name='nProfiles', value='16', format='int')
106 #procUnitConfObjSousySpectra.addParameter(name='pairsList', value='(0,0),(1,1),(0,1)', format='pairsList')
126 #procUnitConfObjSousySpectra.addParameter(name='pairsList', value='(0,0),(1,1),(0,1)', format='pairsList')
107
127
108 #opObj13 = procUnitConfObjSousySpectra.addOperation(name='removeDC')
128 #opObj13 = procUnitConfObjSousySpectra.addOperation(name='removeDC')
@@ -174,10 +194,10 opObj11.addParameter(name='save_period', value=10, format='int')
174 #opObj11 = procUnitConfObjSousySpectra.addOperation(name='SpectraWriter', optype='other')
194 #opObj11 = procUnitConfObjSousySpectra.addOperation(name='SpectraWriter', optype='other')
175 #opObj11.addParameter(name='path', value=wr_path)
195 #opObj11.addParameter(name='path', value=wr_path)
176 #opObj11.addParameter(name='blocksPerFile', value='50', format='int')
196 #opObj11.addParameter(name='blocksPerFile', value='50', format='int')
197 '''
177 print ("Escribiendo el archivo XML")
198 print ("Escribiendo el archivo XML")
178 print ("Leyendo el archivo XML")
199 print ("Leyendo el archivo XML")
179
200
180
201
181
202
182 controllerObj.start()
203 controllerObj.start()
183
General Comments 0
You need to be logged in to leave comments. Login now