##// END OF EJS Templates
07/09/2017
ebocanegra -
r1027:f11c2da27e74
parent child
Show More
@@ -1,1541 +1,1584
1 1 '''
2 2 Created on Jul 9, 2014
3 3
4 4 @author: roj-idl71
5 5 '''
6 6 import os
7 7 import datetime
8 8 import numpy
9 9
10 import matplotlib.pyplot as plt
11
10 12 from figure import Figure, isRealtime, isTimeInHourRange
11 13 from plotting_codes import *
14 from matplotlib.pyplot import savefig
12 15
13 16 class SpectraPlot(Figure):
14 17
15 18 isConfig = None
16 19 __nsubplots = None
17 20
18 21 WIDTHPROF = None
19 22 HEIGHTPROF = None
20 23 PREFIX = 'spc'
21 24
22 25 def __init__(self, **kwargs):
23 26 Figure.__init__(self, **kwargs)
24 27 self.isConfig = False
25 28 self.__nsubplots = 1
26 29
27 30 self.WIDTH = 250
28 31 self.HEIGHT = 250
29 32 self.WIDTHPROF = 120
30 33 self.HEIGHTPROF = 0
31 34 self.counter_imagwr = 0
32 35
33 36 self.PLOT_CODE = SPEC_CODE
34 37
35 38 self.FTP_WEI = None
36 39 self.EXP_CODE = None
37 40 self.SUB_EXP_CODE = None
38 41 self.PLOT_POS = None
39 42
40 43 self.__xfilter_ena = False
41 44 self.__yfilter_ena = False
45
46 self.indice=1
42 47
43 48 def getSubplots(self):
44 49
45 50 ncol = int(numpy.sqrt(self.nplots)+0.9)
46 51 nrow = int(self.nplots*1./ncol + 0.9)
47 52
48 53 return nrow, ncol
49 54
50 55 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
51 56
52 57 self.__showprofile = showprofile
53 58 self.nplots = nplots
54 59
55 60 ncolspan = 1
56 61 colspan = 1
57 62 if showprofile:
58 63 ncolspan = 3
59 64 colspan = 2
60 65 self.__nsubplots = 2
61 66
62 67 self.createFigure(id = id,
63 68 wintitle = wintitle,
64 69 widthplot = self.WIDTH + self.WIDTHPROF,
65 70 heightplot = self.HEIGHT + self.HEIGHTPROF,
66 71 show=show)
67 72
68 73 nrow, ncol = self.getSubplots()
69 74
70 75 counter = 0
71 76 for y in range(nrow):
72 77 for x in range(ncol):
73 78
74 79 if counter >= self.nplots:
75 80 break
76 81
77 82 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
78 83
79 84 if showprofile:
80 85 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
81 86
82 87 counter += 1
83 88
84 89 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
85 90 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
86 91 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
87 92 server=None, folder=None, username=None, password=None,
88 93 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
89 94 xaxis="frequency", colormap='jet', normFactor=None):
90 95
91 96 """
92 97
93 98 Input:
94 99 dataOut :
95 100 id :
96 101 wintitle :
97 102 channelList :
98 103 showProfile :
99 104 xmin : None,
100 105 xmax : None,
101 106 ymin : None,
102 107 ymax : None,
103 108 zmin : None,
104 109 zmax : None
105 110 """
106 111 if realtime:
107 112 if not(isRealtime(utcdatatime = dataOut.utctime)):
108 113 print 'Skipping this plot function'
109 114 return
110 115
111 116 if channelList == None:
112 117 channelIndexList = dataOut.channelIndexList
113 118 else:
114 119 channelIndexList = []
115 120 for channel in channelList:
116 121 if channel not in dataOut.channelList:
117 122 raise ValueError, "Channel %d is not in dataOut.channelList" %channel
118 123 channelIndexList.append(dataOut.channelList.index(channel))
119 124
120 125 if normFactor is None:
121 126 factor = dataOut.normFactor
122 127 else:
123 128 factor = normFactor
124 129 if xaxis == "frequency":
125 130 x = dataOut.getFreqRange(1)/1000.
126 131 xlabel = "Frequency (kHz)"
127 132
128 133 elif xaxis == "time":
129 134 x = dataOut.getAcfRange(1)
130 135 xlabel = "Time (ms)"
131 136
132 137 else:
133 138 x = dataOut.getVelRange(1)
134 139 xlabel = "Velocity (m/s)"
135 140
136 141 ylabel = "Range (Km)"
137 142
138 143 y = dataOut.getHeiRange()
139 144
140 145 z = dataOut.data_spc/factor
141 146 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
142 147 zdB = 10*numpy.log10(z)
143 148
144 149 avg = numpy.average(z, axis=1)
145 150 avgdB = 10*numpy.log10(avg)
146 151
147 152 noise = dataOut.getNoise()/factor
148 153 noisedB = 10*numpy.log10(noise)
149 154
150 155 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
151 156 title = wintitle + " Spectra"
157
158
159
160 print 'len de X',len(x), numpy.shape(x), 'len de spc line',len(dataOut.data_spc[1,:,15]), numpy.shape(dataOut.data_spc)
161 print 'Altura:', y[0], y[1], y[13], y[14], y[10]
162 #a=z[1,:,15]
163
164 # fig = plt.figure(10+self.indice)
165 # plt.plot( x[0:128], zdB[0,:,10] )
166 # plt.axis([-12, 12, 15, 50])
167 # plt.title(" %s" %( '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))) )
168 # plt.ylabel('Intensidad [dB]')
169 # plt.xlabel('Velocidad [m/s]')
170 # fig.savefig('/home/erick/Documents/Pics/to{}.png'.format(self.indice))
171 #
172 # plt.show()
173 #
174 # self.indice=self.indice+1
175
176
177
152 178 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
153 179 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
154 180
155 181 if not self.isConfig:
156 182
157 183 nplots = len(channelIndexList)
158 184
159 185 self.setup(id=id,
160 186 nplots=nplots,
161 187 wintitle=wintitle,
162 188 showprofile=showprofile,
163 189 show=show)
164 190
165 191 if xmin == None: xmin = numpy.nanmin(x)
166 192 if xmax == None: xmax = numpy.nanmax(x)
167 193 if ymin == None: ymin = numpy.nanmin(y)
168 194 if ymax == None: ymax = numpy.nanmax(y)
169 195 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
170 196 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
171 197
172 198 self.FTP_WEI = ftp_wei
173 199 self.EXP_CODE = exp_code
174 200 self.SUB_EXP_CODE = sub_exp_code
175 201 self.PLOT_POS = plot_pos
176 202
177 203 self.isConfig = True
178 204
179 205 self.setWinTitle(title)
180 206
181 207 for i in range(self.nplots):
182 208 index = channelIndexList[i]
183 209 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
184 210 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[index], noisedB[index], str_datetime)
185 211 if len(dataOut.beam.codeList) != 0:
186 212 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)
187 213
188 214 axes = self.axesList[i*self.__nsubplots]
189 215 axes.pcolor(x, y, zdB[index,:,:],
190 216 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
191 217 xlabel=xlabel, ylabel=ylabel, title=title, colormap=colormap,
192 218 ticksize=9, cblabel='')
193 219
194 220 if self.__showprofile:
195 221 axes = self.axesList[i*self.__nsubplots +1]
196 222 axes.pline(avgdB[index,:], y,
197 223 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
198 224 xlabel='dB', ylabel='', title='',
199 225 ytick_visible=False,
200 226 grid='x')
201 227
202 228 noiseline = numpy.repeat(noisedB[index], len(y))
203 229 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
204 230
205 231 self.draw()
206 232
207 233 if figfile == None:
208 234 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
209 235 name = str_datetime
210 236 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
211 237 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
212 238 figfile = self.getFilename(name)
213 239
214 240 self.save(figpath=figpath,
215 241 figfile=figfile,
216 242 save=save,
217 243 ftp=ftp,
218 244 wr_period=wr_period,
219 245 thisDatetime=thisDatetime)
246
220 247
221 248 class CrossSpectraPlot(Figure):
222 249
223 250 isConfig = None
224 251 __nsubplots = None
225 252
226 253 WIDTH = None
227 254 HEIGHT = None
228 255 WIDTHPROF = None
229 256 HEIGHTPROF = None
230 257 PREFIX = 'cspc'
231 258
232 259 def __init__(self, **kwargs):
233 260 Figure.__init__(self, **kwargs)
234 261 self.isConfig = False
235 262 self.__nsubplots = 4
236 263 self.counter_imagwr = 0
237 264 self.WIDTH = 250
238 265 self.HEIGHT = 250
239 266 self.WIDTHPROF = 0
240 267 self.HEIGHTPROF = 0
241 268
242 269 self.PLOT_CODE = CROSS_CODE
243 270 self.FTP_WEI = None
244 271 self.EXP_CODE = None
245 272 self.SUB_EXP_CODE = None
246 273 self.PLOT_POS = None
274
275 self.indice=0
247 276
248 277 def getSubplots(self):
249 278
250 279 ncol = 4
251 280 nrow = self.nplots
252 281
253 282 return nrow, ncol
254 283
255 284 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
256 285
257 286 self.__showprofile = showprofile
258 287 self.nplots = nplots
259 288
260 289 ncolspan = 1
261 290 colspan = 1
262 291
263 292 self.createFigure(id = id,
264 293 wintitle = wintitle,
265 294 widthplot = self.WIDTH + self.WIDTHPROF,
266 295 heightplot = self.HEIGHT + self.HEIGHTPROF,
267 296 show=True)
268 297
269 298 nrow, ncol = self.getSubplots()
270 299
271 300 counter = 0
272 301 for y in range(nrow):
273 302 for x in range(ncol):
274 303 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
275 304
276 305 counter += 1
277 306
278 307 def run(self, dataOut, id, wintitle="", pairsList=None,
279 308 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
280 309 coh_min=None, coh_max=None, phase_min=None, phase_max=None,
281 310 save=False, figpath='./', figfile=None, ftp=False, wr_period=1,
282 311 power_cmap='jet', coherence_cmap='jet', phase_cmap='RdBu_r', show=True,
283 312 server=None, folder=None, username=None, password=None,
284 313 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, normFactor=None,
285 314 xaxis='frequency'):
286 315
287 316 """
288 317
289 318 Input:
290 319 dataOut :
291 320 id :
292 321 wintitle :
293 322 channelList :
294 323 showProfile :
295 324 xmin : None,
296 325 xmax : None,
297 326 ymin : None,
298 327 ymax : None,
299 328 zmin : None,
300 329 zmax : None
301 330 """
302 331
303 332 if pairsList == None:
304 333 pairsIndexList = dataOut.pairsIndexList
305 334 else:
306 335 pairsIndexList = []
307 336 for pair in pairsList:
308 337 if pair not in dataOut.pairsList:
309 338 raise ValueError, "Pair %s is not in dataOut.pairsList" %str(pair)
310 339 pairsIndexList.append(dataOut.pairsList.index(pair))
311 340
312 341 if not pairsIndexList:
313 342 return
314 343
315 344 if len(pairsIndexList) > 4:
316 345 pairsIndexList = pairsIndexList[0:4]
317 346
318 347 if normFactor is None:
319 348 factor = dataOut.normFactor
320 349 else:
321 350 factor = normFactor
322 351 x = dataOut.getVelRange(1)
323 352 y = dataOut.getHeiRange()
324 353 z = dataOut.data_spc[:,:,:]/factor
325 354 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
326 355
327 356 noise = dataOut.noise/factor
328 357
329 358 zdB = 10*numpy.log10(z)
330 359 noisedB = 10*numpy.log10(noise)
331 360
332 361 if coh_min == None:
333 362 coh_min = 0.0
334 363 if coh_max == None:
335 364 coh_max = 1.0
336 365
337 366 if phase_min == None:
338 367 phase_min = -180
339 368 if phase_max == None:
340 369 phase_max = 180
341 370
342 371 #thisDatetime = dataOut.datatime
343 372 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
344 373 title = wintitle + " Cross-Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
345 374 # xlabel = "Velocity (m/s)"
346 375 ylabel = "Range (Km)"
347 376
348 377 if xaxis == "frequency":
349 378 x = dataOut.getFreqRange(1)/1000.
350 379 xlabel = "Frequency (kHz)"
351 380
352 381 elif xaxis == "time":
353 382 x = dataOut.getAcfRange(1)
354 383 xlabel = "Time (ms)"
355 384
356 385 else:
357 386 x = dataOut.getVelRange(1)
358 387 xlabel = "Velocity (m/s)"
359 388
360 389 if not self.isConfig:
361 390
362 391 nplots = len(pairsIndexList)
363 392
364 393 self.setup(id=id,
365 394 nplots=nplots,
366 395 wintitle=wintitle,
367 396 showprofile=False,
368 397 show=show)
369 398
370 399 avg = numpy.abs(numpy.average(z, axis=1))
371 400 avgdB = 10*numpy.log10(avg)
372 401
373 402 if xmin == None: xmin = numpy.nanmin(x)
374 403 if xmax == None: xmax = numpy.nanmax(x)
375 404 if ymin == None: ymin = numpy.nanmin(y)
376 405 if ymax == None: ymax = numpy.nanmax(y)
377 406 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
378 407 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
379 408
380 409 self.FTP_WEI = ftp_wei
381 410 self.EXP_CODE = exp_code
382 411 self.SUB_EXP_CODE = sub_exp_code
383 412 self.PLOT_POS = plot_pos
384 413
385 414 self.isConfig = True
386 415
387 416 self.setWinTitle(title)
417
388 418
389 419 for i in range(self.nplots):
390 420 pair = dataOut.pairsList[pairsIndexList[i]]
391 421
392 422 chan_index0 = dataOut.channelList.index(pair[0])
393 423 chan_index1 = dataOut.channelList.index(pair[1])
394 424
395 425 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
396 426 title = "Ch%d: %4.2fdB: %s" %(pair[0], noisedB[chan_index0], str_datetime)
397 427 zdB = 10.*numpy.log10(dataOut.data_spc[chan_index0,:,:]/factor)
398 428 axes0 = self.axesList[i*self.__nsubplots]
399 429 axes0.pcolor(x, y, zdB,
400 430 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
401 431 xlabel=xlabel, ylabel=ylabel, title=title,
402 432 ticksize=9, colormap=power_cmap, cblabel='')
403 433
404 434 title = "Ch%d: %4.2fdB: %s" %(pair[1], noisedB[chan_index1], str_datetime)
405 435 zdB = 10.*numpy.log10(dataOut.data_spc[chan_index1,:,:]/factor)
406 436 axes0 = self.axesList[i*self.__nsubplots+1]
407 437 axes0.pcolor(x, y, zdB,
408 438 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
409 439 xlabel=xlabel, ylabel=ylabel, title=title,
410 440 ticksize=9, colormap=power_cmap, cblabel='')
411 441
412 442 coherenceComplex = dataOut.data_cspc[pairsIndexList[i],:,:]/numpy.sqrt(dataOut.data_spc[chan_index0,:,:]*dataOut.data_spc[chan_index1,:,:])
413 443 coherence = numpy.abs(coherenceComplex)
414 444 # phase = numpy.arctan(-1*coherenceComplex.imag/coherenceComplex.real)*180/numpy.pi
415 445 phase = numpy.arctan2(coherenceComplex.imag, coherenceComplex.real)*180/numpy.pi
446
447
448 # print 'FASE', numpy.shape(phase), y[10]
449 # fig = plt.figure(10+self.indice)
450 # plt.plot( x[0:128],phase[:,10] )
451 # #plt.axis([-12, 12, 15, 50])
452 # plt.title("%s" %( '%s %s, Channel %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S") , i)))
453 # plt.ylabel('Desfase [grados]')
454 # plt.xlabel('Velocidad [m/s]')
455 # fig.savefig('/home/erick/Documents/Pics/to{}.png'.format(self.indice))
456 #
457 # plt.show()
458 # self.indice=self.indice+1
416 459
417 460 title = "Coherence Ch%d * Ch%d" %(pair[0], pair[1])
418 461 axes0 = self.axesList[i*self.__nsubplots+2]
419 462 axes0.pcolor(x, y, coherence,
420 463 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=coh_min, zmax=coh_max,
421 464 xlabel=xlabel, ylabel=ylabel, title=title,
422 465 ticksize=9, colormap=coherence_cmap, cblabel='')
423 466
424 467 title = "Phase Ch%d * Ch%d" %(pair[0], pair[1])
425 468 axes0 = self.axesList[i*self.__nsubplots+3]
426 469 axes0.pcolor(x, y, phase,
427 470 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=phase_min, zmax=phase_max,
428 471 xlabel=xlabel, ylabel=ylabel, title=title,
429 472 ticksize=9, colormap=phase_cmap, cblabel='')
430 473
431 474
432 475
433 476 self.draw()
434 477
435 478 self.save(figpath=figpath,
436 479 figfile=figfile,
437 480 save=save,
438 481 ftp=ftp,
439 482 wr_period=wr_period,
440 483 thisDatetime=thisDatetime)
441 484
442 485
443 486 class RTIPlot(Figure):
444 487
445 488 __isConfig = None
446 489 __nsubplots = None
447 490
448 491 WIDTHPROF = None
449 492 HEIGHTPROF = None
450 493 PREFIX = 'rti'
451 494
452 495 def __init__(self, **kwargs):
453 496
454 497 Figure.__init__(self, **kwargs)
455 498 self.timerange = None
456 499 self.isConfig = False
457 500 self.__nsubplots = 1
458 501
459 502 self.WIDTH = 800
460 503 self.HEIGHT = 180
461 504 self.WIDTHPROF = 120
462 505 self.HEIGHTPROF = 0
463 506 self.counter_imagwr = 0
464 507
465 508 self.PLOT_CODE = RTI_CODE
466 509
467 510 self.FTP_WEI = None
468 511 self.EXP_CODE = None
469 512 self.SUB_EXP_CODE = None
470 513 self.PLOT_POS = None
471 514 self.tmin = None
472 515 self.tmax = None
473 516
474 517 self.xmin = None
475 518 self.xmax = None
476 519
477 520 self.figfile = None
478 521
479 522 def getSubplots(self):
480 523
481 524 ncol = 1
482 525 nrow = self.nplots
483 526
484 527 return nrow, ncol
485 528
486 529 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
487 530
488 531 self.__showprofile = showprofile
489 532 self.nplots = nplots
490 533
491 534 ncolspan = 1
492 535 colspan = 1
493 536 if showprofile:
494 537 ncolspan = 7
495 538 colspan = 6
496 539 self.__nsubplots = 2
497 540
498 541 self.createFigure(id = id,
499 542 wintitle = wintitle,
500 543 widthplot = self.WIDTH + self.WIDTHPROF,
501 544 heightplot = self.HEIGHT + self.HEIGHTPROF,
502 545 show=show)
503 546
504 547 nrow, ncol = self.getSubplots()
505 548
506 549 counter = 0
507 550 for y in range(nrow):
508 551 for x in range(ncol):
509 552
510 553 if counter >= self.nplots:
511 554 break
512 555
513 556 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
514 557
515 558 if showprofile:
516 559 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
517 560
518 561 counter += 1
519 562
520 563 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='True',
521 564 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
522 565 timerange=None, colormap='jet',
523 566 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
524 567 server=None, folder=None, username=None, password=None,
525 568 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, normFactor=None, HEIGHT=None):
526 569
527 570 """
528 571
529 572 Input:
530 573 dataOut :
531 574 id :
532 575 wintitle :
533 576 channelList :
534 577 showProfile :
535 578 xmin : None,
536 579 xmax : None,
537 580 ymin : None,
538 581 ymax : None,
539 582 zmin : None,
540 583 zmax : None
541 584 """
542 585
543 586 #colormap = kwargs.get('colormap', 'jet')
544 587 if HEIGHT is not None:
545 588 self.HEIGHT = HEIGHT
546 589
547 590 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
548 591 return
549 592
550 593 if channelList == None:
551 594 channelIndexList = dataOut.channelIndexList
552 595 else:
553 596 channelIndexList = []
554 597 for channel in channelList:
555 598 if channel not in dataOut.channelList:
556 599 raise ValueError, "Channel %d is not in dataOut.channelList"
557 600 channelIndexList.append(dataOut.channelList.index(channel))
558 601
559 602 if normFactor is None:
560 603 factor = dataOut.normFactor
561 604 else:
562 605 factor = normFactor
563 606
564 607 # factor = dataOut.normFactor
565 608 x = dataOut.getTimeRange()
566 609 y = dataOut.getHeiRange()
567 610
568 611 z = dataOut.data_spc/factor
569 612 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
570 613 avg = numpy.average(z, axis=1)
571 614 avgdB = 10.*numpy.log10(avg)
572 615 # avgdB = dataOut.getPower()
573 616
574 617
575 618 thisDatetime = dataOut.datatime
576 619 # thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
577 620 title = wintitle + " RTI" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
578 621 xlabel = ""
579 622 ylabel = "Range (Km)"
580 623
581 624 update_figfile = False
582 625
583 626 if dataOut.ltctime >= self.xmax:
584 627 self.counter_imagwr = wr_period
585 628 self.isConfig = False
586 629 update_figfile = True
587 630
588 631 if not self.isConfig:
589 632
590 633 nplots = len(channelIndexList)
591 634
592 635 self.setup(id=id,
593 636 nplots=nplots,
594 637 wintitle=wintitle,
595 638 showprofile=showprofile,
596 639 show=show)
597 640
598 641 if timerange != None:
599 642 self.timerange = timerange
600 643
601 644 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
602 645
603 646 noise = dataOut.noise/factor
604 647 noisedB = 10*numpy.log10(noise)
605 648
606 649 if ymin == None: ymin = numpy.nanmin(y)
607 650 if ymax == None: ymax = numpy.nanmax(y)
608 651 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
609 652 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
610 653
611 654 self.FTP_WEI = ftp_wei
612 655 self.EXP_CODE = exp_code
613 656 self.SUB_EXP_CODE = sub_exp_code
614 657 self.PLOT_POS = plot_pos
615 658
616 659 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
617 660 self.isConfig = True
618 661 self.figfile = figfile
619 662 update_figfile = True
620 663
621 664 self.setWinTitle(title)
622 665
623 666 for i in range(self.nplots):
624 667 index = channelIndexList[i]
625 668 title = "Channel %d: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
626 669 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
627 670 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
628 671 axes = self.axesList[i*self.__nsubplots]
629 672 zdB = avgdB[index].reshape((1,-1))
630 673 axes.pcolorbuffer(x, y, zdB,
631 674 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
632 675 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
633 676 ticksize=9, cblabel='', cbsize="1%", colormap=colormap)
634 677
635 678 if self.__showprofile:
636 679 axes = self.axesList[i*self.__nsubplots +1]
637 680 axes.pline(avgdB[index], y,
638 681 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
639 682 xlabel='dB', ylabel='', title='',
640 683 ytick_visible=False,
641 684 grid='x')
642 685
643 686 self.draw()
644 687
645 688 self.save(figpath=figpath,
646 689 figfile=figfile,
647 690 save=save,
648 691 ftp=ftp,
649 692 wr_period=wr_period,
650 693 thisDatetime=thisDatetime,
651 694 update_figfile=update_figfile)
652 695
653 696 class CoherenceMap(Figure):
654 697 isConfig = None
655 698 __nsubplots = None
656 699
657 700 WIDTHPROF = None
658 701 HEIGHTPROF = None
659 702 PREFIX = 'cmap'
660 703
661 704 def __init__(self, **kwargs):
662 705 Figure.__init__(self, **kwargs)
663 706 self.timerange = 2*60*60
664 707 self.isConfig = False
665 708 self.__nsubplots = 1
666 709
667 710 self.WIDTH = 800
668 711 self.HEIGHT = 180
669 712 self.WIDTHPROF = 120
670 713 self.HEIGHTPROF = 0
671 714 self.counter_imagwr = 0
672 715
673 716 self.PLOT_CODE = COH_CODE
674 717
675 718 self.FTP_WEI = None
676 719 self.EXP_CODE = None
677 720 self.SUB_EXP_CODE = None
678 721 self.PLOT_POS = None
679 722 self.counter_imagwr = 0
680 723
681 724 self.xmin = None
682 725 self.xmax = None
683 726
684 727 def getSubplots(self):
685 728 ncol = 1
686 729 nrow = self.nplots*2
687 730
688 731 return nrow, ncol
689 732
690 733 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
691 734 self.__showprofile = showprofile
692 735 self.nplots = nplots
693 736
694 737 ncolspan = 1
695 738 colspan = 1
696 739 if showprofile:
697 740 ncolspan = 7
698 741 colspan = 6
699 742 self.__nsubplots = 2
700 743
701 744 self.createFigure(id = id,
702 745 wintitle = wintitle,
703 746 widthplot = self.WIDTH + self.WIDTHPROF,
704 747 heightplot = self.HEIGHT + self.HEIGHTPROF,
705 748 show=True)
706 749
707 750 nrow, ncol = self.getSubplots()
708 751
709 752 for y in range(nrow):
710 753 for x in range(ncol):
711 754
712 755 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
713 756
714 757 if showprofile:
715 758 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
716 759
717 760 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
718 761 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
719 762 timerange=None, phase_min=None, phase_max=None,
720 763 save=False, figpath='./', figfile=None, ftp=False, wr_period=1,
721 764 coherence_cmap='jet', phase_cmap='RdBu_r', show=True,
722 765 server=None, folder=None, username=None, password=None,
723 766 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
724 767
725 768 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
726 769 return
727 770
728 771 if pairsList == None:
729 772 pairsIndexList = dataOut.pairsIndexList
730 773 else:
731 774 pairsIndexList = []
732 775 for pair in pairsList:
733 776 if pair not in dataOut.pairsList:
734 777 raise ValueError, "Pair %s is not in dataOut.pairsList" %(pair)
735 778 pairsIndexList.append(dataOut.pairsList.index(pair))
736 779
737 780 if pairsIndexList == []:
738 781 return
739 782
740 783 if len(pairsIndexList) > 4:
741 784 pairsIndexList = pairsIndexList[0:4]
742 785
743 786 if phase_min == None:
744 787 phase_min = -180
745 788 if phase_max == None:
746 789 phase_max = 180
747 790
748 791 x = dataOut.getTimeRange()
749 792 y = dataOut.getHeiRange()
750 793
751 794 thisDatetime = dataOut.datatime
752 795
753 796 title = wintitle + " CoherenceMap" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
754 797 xlabel = ""
755 798 ylabel = "Range (Km)"
756 799 update_figfile = False
757 800
758 801 if not self.isConfig:
759 802 nplots = len(pairsIndexList)
760 803 self.setup(id=id,
761 804 nplots=nplots,
762 805 wintitle=wintitle,
763 806 showprofile=showprofile,
764 807 show=show)
765 808
766 809 if timerange != None:
767 810 self.timerange = timerange
768 811
769 812 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
770 813
771 814 if ymin == None: ymin = numpy.nanmin(y)
772 815 if ymax == None: ymax = numpy.nanmax(y)
773 816 if zmin == None: zmin = 0.
774 817 if zmax == None: zmax = 1.
775 818
776 819 self.FTP_WEI = ftp_wei
777 820 self.EXP_CODE = exp_code
778 821 self.SUB_EXP_CODE = sub_exp_code
779 822 self.PLOT_POS = plot_pos
780 823
781 824 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
782 825
783 826 self.isConfig = True
784 827 update_figfile = True
785 828
786 829 self.setWinTitle(title)
787 830
788 831 for i in range(self.nplots):
789 832
790 833 pair = dataOut.pairsList[pairsIndexList[i]]
791 834
792 835 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i],:,:],axis=0)
793 836 powa = numpy.average(dataOut.data_spc[pair[0],:,:],axis=0)
794 837 powb = numpy.average(dataOut.data_spc[pair[1],:,:],axis=0)
795 838
796 839
797 840 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
798 841 coherence = numpy.abs(avgcoherenceComplex)
799 842
800 843 z = coherence.reshape((1,-1))
801 844
802 845 counter = 0
803 846
804 847 title = "Coherence Ch%d * Ch%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
805 848 axes = self.axesList[i*self.__nsubplots*2]
806 849 axes.pcolorbuffer(x, y, z,
807 850 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
808 851 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
809 852 ticksize=9, cblabel='', colormap=coherence_cmap, cbsize="1%")
810 853
811 854 if self.__showprofile:
812 855 counter += 1
813 856 axes = self.axesList[i*self.__nsubplots*2 + counter]
814 857 axes.pline(coherence, y,
815 858 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
816 859 xlabel='', ylabel='', title='', ticksize=7,
817 860 ytick_visible=False, nxticks=5,
818 861 grid='x')
819 862
820 863 counter += 1
821 864
822 865 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
823 866
824 867 z = phase.reshape((1,-1))
825 868
826 869 title = "Phase Ch%d * Ch%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
827 870 axes = self.axesList[i*self.__nsubplots*2 + counter]
828 871 axes.pcolorbuffer(x, y, z,
829 872 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=phase_min, zmax=phase_max,
830 873 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
831 874 ticksize=9, cblabel='', colormap=phase_cmap, cbsize="1%")
832 875
833 876 if self.__showprofile:
834 877 counter += 1
835 878 axes = self.axesList[i*self.__nsubplots*2 + counter]
836 879 axes.pline(phase, y,
837 880 xmin=phase_min, xmax=phase_max, ymin=ymin, ymax=ymax,
838 881 xlabel='', ylabel='', title='', ticksize=7,
839 882 ytick_visible=False, nxticks=4,
840 883 grid='x')
841 884
842 885 self.draw()
843 886
844 887 if dataOut.ltctime >= self.xmax:
845 888 self.counter_imagwr = wr_period
846 889 self.isConfig = False
847 890 update_figfile = True
848 891
849 892 self.save(figpath=figpath,
850 893 figfile=figfile,
851 894 save=save,
852 895 ftp=ftp,
853 896 wr_period=wr_period,
854 897 thisDatetime=thisDatetime,
855 898 update_figfile=update_figfile)
856 899
857 900 class PowerProfilePlot(Figure):
858 901
859 902 isConfig = None
860 903 __nsubplots = None
861 904
862 905 WIDTHPROF = None
863 906 HEIGHTPROF = None
864 907 PREFIX = 'spcprofile'
865 908
866 909 def __init__(self, **kwargs):
867 910 Figure.__init__(self, **kwargs)
868 911 self.isConfig = False
869 912 self.__nsubplots = 1
870 913
871 914 self.PLOT_CODE = POWER_CODE
872 915
873 916 self.WIDTH = 300
874 917 self.HEIGHT = 500
875 918 self.counter_imagwr = 0
876 919
877 920 def getSubplots(self):
878 921 ncol = 1
879 922 nrow = 1
880 923
881 924 return nrow, ncol
882 925
883 926 def setup(self, id, nplots, wintitle, show):
884 927
885 928 self.nplots = nplots
886 929
887 930 ncolspan = 1
888 931 colspan = 1
889 932
890 933 self.createFigure(id = id,
891 934 wintitle = wintitle,
892 935 widthplot = self.WIDTH,
893 936 heightplot = self.HEIGHT,
894 937 show=show)
895 938
896 939 nrow, ncol = self.getSubplots()
897 940
898 941 counter = 0
899 942 for y in range(nrow):
900 943 for x in range(ncol):
901 944 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
902 945
903 946 def run(self, dataOut, id, wintitle="", channelList=None,
904 947 xmin=None, xmax=None, ymin=None, ymax=None,
905 948 save=False, figpath='./', figfile=None, show=True,
906 949 ftp=False, wr_period=1, server=None,
907 950 folder=None, username=None, password=None):
908 951
909 952
910 953 if channelList == None:
911 954 channelIndexList = dataOut.channelIndexList
912 955 channelList = dataOut.channelList
913 956 else:
914 957 channelIndexList = []
915 958 for channel in channelList:
916 959 if channel not in dataOut.channelList:
917 960 raise ValueError, "Channel %d is not in dataOut.channelList"
918 961 channelIndexList.append(dataOut.channelList.index(channel))
919 962
920 963 factor = dataOut.normFactor
921 964
922 965 y = dataOut.getHeiRange()
923 966
924 967 #for voltage
925 968 if dataOut.type == 'Voltage':
926 969 x = dataOut.data[channelIndexList,:] * numpy.conjugate(dataOut.data[channelIndexList,:])
927 970 x = x.real
928 971 x = numpy.where(numpy.isfinite(x), x, numpy.NAN)
929 972
930 973 #for spectra
931 974 if dataOut.type == 'Spectra':
932 975 x = dataOut.data_spc[channelIndexList,:,:]/factor
933 976 x = numpy.where(numpy.isfinite(x), x, numpy.NAN)
934 977 x = numpy.average(x, axis=1)
935 978
936 979
937 980 xdB = 10*numpy.log10(x)
938 981
939 982 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
940 983 title = wintitle + " Power Profile %s" %(thisDatetime.strftime("%d-%b-%Y"))
941 984 xlabel = "dB"
942 985 ylabel = "Range (Km)"
943 986
944 987 if not self.isConfig:
945 988
946 989 nplots = 1
947 990
948 991 self.setup(id=id,
949 992 nplots=nplots,
950 993 wintitle=wintitle,
951 994 show=show)
952 995
953 996 if ymin == None: ymin = numpy.nanmin(y)
954 997 if ymax == None: ymax = numpy.nanmax(y)
955 998 if xmin == None: xmin = numpy.nanmin(xdB)*0.9
956 999 if xmax == None: xmax = numpy.nanmax(xdB)*1.1
957 1000
958 1001 self.isConfig = True
959 1002
960 1003 self.setWinTitle(title)
961 1004
962 1005 title = "Power Profile: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
963 1006 axes = self.axesList[0]
964 1007
965 1008 legendlabels = ["channel %d"%x for x in channelList]
966 1009 axes.pmultiline(xdB, y,
967 1010 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
968 1011 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels,
969 1012 ytick_visible=True, nxticks=5,
970 1013 grid='x')
971 1014
972 1015 self.draw()
973 1016
974 1017 self.save(figpath=figpath,
975 1018 figfile=figfile,
976 1019 save=save,
977 1020 ftp=ftp,
978 1021 wr_period=wr_period,
979 1022 thisDatetime=thisDatetime)
980 1023
981 1024 class SpectraCutPlot(Figure):
982 1025
983 1026 isConfig = None
984 1027 __nsubplots = None
985 1028
986 1029 WIDTHPROF = None
987 1030 HEIGHTPROF = None
988 1031 PREFIX = 'spc_cut'
989 1032
990 1033 def __init__(self, **kwargs):
991 1034 Figure.__init__(self, **kwargs)
992 1035 self.isConfig = False
993 1036 self.__nsubplots = 1
994 1037
995 1038 self.PLOT_CODE = POWER_CODE
996 1039
997 1040 self.WIDTH = 700
998 1041 self.HEIGHT = 500
999 1042 self.counter_imagwr = 0
1000 1043
1001 1044 def getSubplots(self):
1002 1045 ncol = 1
1003 1046 nrow = 1
1004 1047
1005 1048 return nrow, ncol
1006 1049
1007 1050 def setup(self, id, nplots, wintitle, show):
1008 1051
1009 1052 self.nplots = nplots
1010 1053
1011 1054 ncolspan = 1
1012 1055 colspan = 1
1013 1056
1014 1057 self.createFigure(id = id,
1015 1058 wintitle = wintitle,
1016 1059 widthplot = self.WIDTH,
1017 1060 heightplot = self.HEIGHT,
1018 1061 show=show)
1019 1062
1020 1063 nrow, ncol = self.getSubplots()
1021 1064
1022 1065 counter = 0
1023 1066 for y in range(nrow):
1024 1067 for x in range(ncol):
1025 1068 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1026 1069
1027 1070 def run(self, dataOut, id, wintitle="", channelList=None,
1028 1071 xmin=None, xmax=None, ymin=None, ymax=None,
1029 1072 save=False, figpath='./', figfile=None, show=True,
1030 1073 ftp=False, wr_period=1, server=None,
1031 1074 folder=None, username=None, password=None,
1032 1075 xaxis="frequency"):
1033 1076
1034 1077
1035 1078 if channelList == None:
1036 1079 channelIndexList = dataOut.channelIndexList
1037 1080 channelList = dataOut.channelList
1038 1081 else:
1039 1082 channelIndexList = []
1040 1083 for channel in channelList:
1041 1084 if channel not in dataOut.channelList:
1042 1085 raise ValueError, "Channel %d is not in dataOut.channelList"
1043 1086 channelIndexList.append(dataOut.channelList.index(channel))
1044 1087
1045 1088 factor = dataOut.normFactor
1046 1089
1047 1090 y = dataOut.getHeiRange()
1048 1091
1049 1092 z = dataOut.data_spc/factor
1050 1093 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1051 1094
1052 1095 hei_index = numpy.arange(25)*3 + 20
1053 1096
1054 1097 if xaxis == "frequency":
1055 1098 x = dataOut.getFreqRange()/1000.
1056 1099 zdB = 10*numpy.log10(z[0,:,hei_index])
1057 1100 xlabel = "Frequency (kHz)"
1058 1101 ylabel = "Power (dB)"
1059 1102
1060 1103 elif xaxis == "time":
1061 1104 x = dataOut.getAcfRange()
1062 1105 zdB = z[0,:,hei_index]
1063 1106 xlabel = "Time (ms)"
1064 1107 ylabel = "ACF"
1065 1108
1066 1109 else:
1067 1110 x = dataOut.getVelRange()
1068 1111 zdB = 10*numpy.log10(z[0,:,hei_index])
1069 1112 xlabel = "Velocity (m/s)"
1070 1113 ylabel = "Power (dB)"
1071 1114
1072 1115 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1073 1116 title = wintitle + " Range Cuts %s" %(thisDatetime.strftime("%d-%b-%Y"))
1074 1117
1075 1118 if not self.isConfig:
1076 1119
1077 1120 nplots = 1
1078 1121
1079 1122 self.setup(id=id,
1080 1123 nplots=nplots,
1081 1124 wintitle=wintitle,
1082 1125 show=show)
1083 1126
1084 1127 if xmin == None: xmin = numpy.nanmin(x)*0.9
1085 1128 if xmax == None: xmax = numpy.nanmax(x)*1.1
1086 1129 if ymin == None: ymin = numpy.nanmin(zdB)
1087 1130 if ymax == None: ymax = numpy.nanmax(zdB)
1088 1131
1089 1132 self.isConfig = True
1090 1133
1091 1134 self.setWinTitle(title)
1092 1135
1093 1136 title = "Spectra Cuts: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
1094 1137 axes = self.axesList[0]
1095 1138
1096 1139 legendlabels = ["Range = %dKm" %y[i] for i in hei_index]
1097 1140
1098 1141 axes.pmultilineyaxis( x, zdB,
1099 1142 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1100 1143 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels,
1101 1144 ytick_visible=True, nxticks=5,
1102 1145 grid='x')
1103 1146
1104 1147 self.draw()
1105 1148
1106 1149 self.save(figpath=figpath,
1107 1150 figfile=figfile,
1108 1151 save=save,
1109 1152 ftp=ftp,
1110 1153 wr_period=wr_period,
1111 1154 thisDatetime=thisDatetime)
1112 1155
1113 1156 class Noise(Figure):
1114 1157
1115 1158 isConfig = None
1116 1159 __nsubplots = None
1117 1160
1118 1161 PREFIX = 'noise'
1119 1162
1120 1163
1121 1164 def __init__(self, **kwargs):
1122 1165 Figure.__init__(self, **kwargs)
1123 1166 self.timerange = 24*60*60
1124 1167 self.isConfig = False
1125 1168 self.__nsubplots = 1
1126 1169 self.counter_imagwr = 0
1127 1170 self.WIDTH = 800
1128 1171 self.HEIGHT = 400
1129 1172 self.WIDTHPROF = 120
1130 1173 self.HEIGHTPROF = 0
1131 1174 self.xdata = None
1132 1175 self.ydata = None
1133 1176
1134 1177 self.PLOT_CODE = NOISE_CODE
1135 1178
1136 1179 self.FTP_WEI = None
1137 1180 self.EXP_CODE = None
1138 1181 self.SUB_EXP_CODE = None
1139 1182 self.PLOT_POS = None
1140 1183 self.figfile = None
1141 1184
1142 1185 self.xmin = None
1143 1186 self.xmax = None
1144 1187
1145 1188 def getSubplots(self):
1146 1189
1147 1190 ncol = 1
1148 1191 nrow = 1
1149 1192
1150 1193 return nrow, ncol
1151 1194
1152 1195 def openfile(self, filename):
1153 1196 dirname = os.path.dirname(filename)
1154 1197
1155 1198 if not os.path.exists(dirname):
1156 1199 os.mkdir(dirname)
1157 1200
1158 1201 f = open(filename,'w+')
1159 1202 f.write('\n\n')
1160 1203 f.write('JICAMARCA RADIO OBSERVATORY - Noise \n')
1161 1204 f.write('DD MM YYYY HH MM SS Channel0 Channel1 Channel2 Channel3\n\n' )
1162 1205 f.close()
1163 1206
1164 1207 def save_data(self, filename_phase, data, data_datetime):
1165 1208
1166 1209 f=open(filename_phase,'a')
1167 1210
1168 1211 timetuple_data = data_datetime.timetuple()
1169 1212 day = str(timetuple_data.tm_mday)
1170 1213 month = str(timetuple_data.tm_mon)
1171 1214 year = str(timetuple_data.tm_year)
1172 1215 hour = str(timetuple_data.tm_hour)
1173 1216 minute = str(timetuple_data.tm_min)
1174 1217 second = str(timetuple_data.tm_sec)
1175 1218
1176 1219 data_msg = ''
1177 1220 for i in range(len(data)):
1178 1221 data_msg += str(data[i]) + ' '
1179 1222
1180 1223 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' ' + data_msg + '\n')
1181 1224 f.close()
1182 1225
1183 1226
1184 1227 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1185 1228
1186 1229 self.__showprofile = showprofile
1187 1230 self.nplots = nplots
1188 1231
1189 1232 ncolspan = 7
1190 1233 colspan = 6
1191 1234 self.__nsubplots = 2
1192 1235
1193 1236 self.createFigure(id = id,
1194 1237 wintitle = wintitle,
1195 1238 widthplot = self.WIDTH+self.WIDTHPROF,
1196 1239 heightplot = self.HEIGHT+self.HEIGHTPROF,
1197 1240 show=show)
1198 1241
1199 1242 nrow, ncol = self.getSubplots()
1200 1243
1201 1244 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1202 1245
1203 1246
1204 1247 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='True',
1205 1248 xmin=None, xmax=None, ymin=None, ymax=None,
1206 1249 timerange=None,
1207 1250 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1208 1251 server=None, folder=None, username=None, password=None,
1209 1252 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1210 1253
1211 1254 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1212 1255 return
1213 1256
1214 1257 if channelList == None:
1215 1258 channelIndexList = dataOut.channelIndexList
1216 1259 channelList = dataOut.channelList
1217 1260 else:
1218 1261 channelIndexList = []
1219 1262 for channel in channelList:
1220 1263 if channel not in dataOut.channelList:
1221 1264 raise ValueError, "Channel %d is not in dataOut.channelList"
1222 1265 channelIndexList.append(dataOut.channelList.index(channel))
1223 1266
1224 1267 x = dataOut.getTimeRange()
1225 1268 #y = dataOut.getHeiRange()
1226 1269 factor = dataOut.normFactor
1227 1270 noise = dataOut.noise[channelIndexList]/factor
1228 1271 noisedB = 10*numpy.log10(noise)
1229 1272
1230 1273 thisDatetime = dataOut.datatime
1231 1274
1232 1275 title = wintitle + " Noise" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1233 1276 xlabel = ""
1234 1277 ylabel = "Intensity (dB)"
1235 1278 update_figfile = False
1236 1279
1237 1280 if not self.isConfig:
1238 1281
1239 1282 nplots = 1
1240 1283
1241 1284 self.setup(id=id,
1242 1285 nplots=nplots,
1243 1286 wintitle=wintitle,
1244 1287 showprofile=showprofile,
1245 1288 show=show)
1246 1289
1247 1290 if timerange != None:
1248 1291 self.timerange = timerange
1249 1292
1250 1293 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1251 1294
1252 1295 if ymin == None: ymin = numpy.floor(numpy.nanmin(noisedB)) - 10.0
1253 1296 if ymax == None: ymax = numpy.nanmax(noisedB) + 10.0
1254 1297
1255 1298 self.FTP_WEI = ftp_wei
1256 1299 self.EXP_CODE = exp_code
1257 1300 self.SUB_EXP_CODE = sub_exp_code
1258 1301 self.PLOT_POS = plot_pos
1259 1302
1260 1303
1261 1304 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1262 1305 self.isConfig = True
1263 1306 self.figfile = figfile
1264 1307 self.xdata = numpy.array([])
1265 1308 self.ydata = numpy.array([])
1266 1309
1267 1310 update_figfile = True
1268 1311
1269 1312 #open file beacon phase
1270 1313 path = '%s%03d' %(self.PREFIX, self.id)
1271 1314 noise_file = os.path.join(path,'%s.txt'%self.name)
1272 1315 self.filename_noise = os.path.join(figpath,noise_file)
1273 1316
1274 1317 self.setWinTitle(title)
1275 1318
1276 1319 title = "Noise %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1277 1320
1278 1321 legendlabels = ["channel %d"%(idchannel) for idchannel in channelList]
1279 1322 axes = self.axesList[0]
1280 1323
1281 1324 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1282 1325
1283 1326 if len(self.ydata)==0:
1284 1327 self.ydata = noisedB.reshape(-1,1)
1285 1328 else:
1286 1329 self.ydata = numpy.hstack((self.ydata, noisedB.reshape(-1,1)))
1287 1330
1288 1331
1289 1332 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1290 1333 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1291 1334 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1292 1335 XAxisAsTime=True, grid='both'
1293 1336 )
1294 1337
1295 1338 self.draw()
1296 1339
1297 1340 if dataOut.ltctime >= self.xmax:
1298 1341 self.counter_imagwr = wr_period
1299 1342 self.isConfig = False
1300 1343 update_figfile = True
1301 1344
1302 1345 self.save(figpath=figpath,
1303 1346 figfile=figfile,
1304 1347 save=save,
1305 1348 ftp=ftp,
1306 1349 wr_period=wr_period,
1307 1350 thisDatetime=thisDatetime,
1308 1351 update_figfile=update_figfile)
1309 1352
1310 1353 #store data beacon phase
1311 1354 if save:
1312 1355 self.save_data(self.filename_noise, noisedB, thisDatetime)
1313 1356
1314 1357 class BeaconPhase(Figure):
1315 1358
1316 1359 __isConfig = None
1317 1360 __nsubplots = None
1318 1361
1319 1362 PREFIX = 'beacon_phase'
1320 1363
1321 1364 def __init__(self, **kwargs):
1322 1365 Figure.__init__(self, **kwargs)
1323 1366 self.timerange = 24*60*60
1324 1367 self.isConfig = False
1325 1368 self.__nsubplots = 1
1326 1369 self.counter_imagwr = 0
1327 1370 self.WIDTH = 800
1328 1371 self.HEIGHT = 400
1329 1372 self.WIDTHPROF = 120
1330 1373 self.HEIGHTPROF = 0
1331 1374 self.xdata = None
1332 1375 self.ydata = None
1333 1376
1334 1377 self.PLOT_CODE = BEACON_CODE
1335 1378
1336 1379 self.FTP_WEI = None
1337 1380 self.EXP_CODE = None
1338 1381 self.SUB_EXP_CODE = None
1339 1382 self.PLOT_POS = None
1340 1383
1341 1384 self.filename_phase = None
1342 1385
1343 1386 self.figfile = None
1344 1387
1345 1388 self.xmin = None
1346 1389 self.xmax = None
1347 1390
1348 1391 def getSubplots(self):
1349 1392
1350 1393 ncol = 1
1351 1394 nrow = 1
1352 1395
1353 1396 return nrow, ncol
1354 1397
1355 1398 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1356 1399
1357 1400 self.__showprofile = showprofile
1358 1401 self.nplots = nplots
1359 1402
1360 1403 ncolspan = 7
1361 1404 colspan = 6
1362 1405 self.__nsubplots = 2
1363 1406
1364 1407 self.createFigure(id = id,
1365 1408 wintitle = wintitle,
1366 1409 widthplot = self.WIDTH+self.WIDTHPROF,
1367 1410 heightplot = self.HEIGHT+self.HEIGHTPROF,
1368 1411 show=show)
1369 1412
1370 1413 nrow, ncol = self.getSubplots()
1371 1414
1372 1415 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1373 1416
1374 1417 def save_phase(self, filename_phase):
1375 1418 f = open(filename_phase,'w+')
1376 1419 f.write('\n\n')
1377 1420 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
1378 1421 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
1379 1422 f.close()
1380 1423
1381 1424 def save_data(self, filename_phase, data, data_datetime):
1382 1425 f=open(filename_phase,'a')
1383 1426 timetuple_data = data_datetime.timetuple()
1384 1427 day = str(timetuple_data.tm_mday)
1385 1428 month = str(timetuple_data.tm_mon)
1386 1429 year = str(timetuple_data.tm_year)
1387 1430 hour = str(timetuple_data.tm_hour)
1388 1431 minute = str(timetuple_data.tm_min)
1389 1432 second = str(timetuple_data.tm_sec)
1390 1433 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
1391 1434 f.close()
1392 1435
1393 1436
1394 1437 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1395 1438 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
1396 1439 timerange=None,
1397 1440 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1398 1441 server=None, folder=None, username=None, password=None,
1399 1442 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1400 1443
1401 1444 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1402 1445 return
1403 1446
1404 1447 if pairsList == None:
1405 1448 pairsIndexList = dataOut.pairsIndexList[:10]
1406 1449 else:
1407 1450 pairsIndexList = []
1408 1451 for pair in pairsList:
1409 1452 if pair not in dataOut.pairsList:
1410 1453 raise ValueError, "Pair %s is not in dataOut.pairsList" %(pair)
1411 1454 pairsIndexList.append(dataOut.pairsList.index(pair))
1412 1455
1413 1456 if pairsIndexList == []:
1414 1457 return
1415 1458
1416 1459 # if len(pairsIndexList) > 4:
1417 1460 # pairsIndexList = pairsIndexList[0:4]
1418 1461
1419 1462 hmin_index = None
1420 1463 hmax_index = None
1421 1464
1422 1465 if hmin != None and hmax != None:
1423 1466 indexes = numpy.arange(dataOut.nHeights)
1424 1467 hmin_list = indexes[dataOut.heightList >= hmin]
1425 1468 hmax_list = indexes[dataOut.heightList <= hmax]
1426 1469
1427 1470 if hmin_list.any():
1428 1471 hmin_index = hmin_list[0]
1429 1472
1430 1473 if hmax_list.any():
1431 1474 hmax_index = hmax_list[-1]+1
1432 1475
1433 1476 x = dataOut.getTimeRange()
1434 1477 #y = dataOut.getHeiRange()
1435 1478
1436 1479
1437 1480 thisDatetime = dataOut.datatime
1438 1481
1439 1482 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1440 1483 xlabel = "Local Time"
1441 1484 ylabel = "Phase (degrees)"
1442 1485
1443 1486 update_figfile = False
1444 1487
1445 1488 nplots = len(pairsIndexList)
1446 1489 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1447 1490 phase_beacon = numpy.zeros(len(pairsIndexList))
1448 1491 for i in range(nplots):
1449 1492 pair = dataOut.pairsList[pairsIndexList[i]]
1450 1493 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
1451 1494 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
1452 1495 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
1453 1496 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
1454 1497 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
1455 1498
1456 1499 #print "Phase %d%d" %(pair[0], pair[1])
1457 1500 #print phase[dataOut.beacon_heiIndexList]
1458 1501
1459 1502 if dataOut.beacon_heiIndexList:
1460 1503 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
1461 1504 else:
1462 1505 phase_beacon[i] = numpy.average(phase)
1463 1506
1464 1507 if not self.isConfig:
1465 1508
1466 1509 nplots = len(pairsIndexList)
1467 1510
1468 1511 self.setup(id=id,
1469 1512 nplots=nplots,
1470 1513 wintitle=wintitle,
1471 1514 showprofile=showprofile,
1472 1515 show=show)
1473 1516
1474 1517 if timerange != None:
1475 1518 self.timerange = timerange
1476 1519
1477 1520 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1478 1521
1479 1522 if ymin == None: ymin = 0
1480 1523 if ymax == None: ymax = 360
1481 1524
1482 1525 self.FTP_WEI = ftp_wei
1483 1526 self.EXP_CODE = exp_code
1484 1527 self.SUB_EXP_CODE = sub_exp_code
1485 1528 self.PLOT_POS = plot_pos
1486 1529
1487 1530 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1488 1531 self.isConfig = True
1489 1532 self.figfile = figfile
1490 1533 self.xdata = numpy.array([])
1491 1534 self.ydata = numpy.array([])
1492 1535
1493 1536 update_figfile = True
1494 1537
1495 1538 #open file beacon phase
1496 1539 path = '%s%03d' %(self.PREFIX, self.id)
1497 1540 beacon_file = os.path.join(path,'%s.txt'%self.name)
1498 1541 self.filename_phase = os.path.join(figpath,beacon_file)
1499 1542 #self.save_phase(self.filename_phase)
1500 1543
1501 1544
1502 1545 #store data beacon phase
1503 1546 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1504 1547
1505 1548 self.setWinTitle(title)
1506 1549
1507 1550
1508 1551 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1509 1552
1510 1553 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
1511 1554
1512 1555 axes = self.axesList[0]
1513 1556
1514 1557 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1515 1558
1516 1559 if len(self.ydata)==0:
1517 1560 self.ydata = phase_beacon.reshape(-1,1)
1518 1561 else:
1519 1562 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1520 1563
1521 1564
1522 1565 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1523 1566 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1524 1567 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1525 1568 XAxisAsTime=True, grid='both'
1526 1569 )
1527 1570
1528 1571 self.draw()
1529 1572
1530 1573 if dataOut.ltctime >= self.xmax:
1531 1574 self.counter_imagwr = wr_period
1532 1575 self.isConfig = False
1533 1576 update_figfile = True
1534 1577
1535 1578 self.save(figpath=figpath,
1536 1579 figfile=figfile,
1537 1580 save=save,
1538 1581 ftp=ftp,
1539 1582 wr_period=wr_period,
1540 1583 thisDatetime=thisDatetime,
1541 1584 update_figfile=update_figfile)
1 NO CONTENT: modified file, binary diff hidden
@@ -1,1193 +1,1194
1 1 import os, sys
2 2 import glob
3 3 import fnmatch
4 4 import datetime
5 5 import time
6 6 import re
7 7 import h5py
8 8 import numpy
9 9 import matplotlib.pyplot as plt
10 10
11 11 import pylab as plb
12 12 from scipy.optimize import curve_fit
13 13 from scipy import asarray as ar,exp
14 14 from scipy import stats
15 15
16 16 from duplicity.path import Path
17 17 from numpy.ma.core import getdata
18 18
19 19 SPEED_OF_LIGHT = 299792458
20 20 SPEED_OF_LIGHT = 3e8
21 21
22 22 try:
23 23 from gevent import sleep
24 24 except:
25 25 from time import sleep
26 26
27 27 from schainpy.model.data.jrodata import Spectra
28 28 #from schainpy.model.data.BLTRheaderIO import FileHeader, RecordHeader
29 29 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation
30 30 #from schainpy.model.io.jroIO_bltr import BLTRReader
31 31 from numpy import imag, shape, NaN
32 32
33 33 from jroIO_base import JRODataReader
34 34
35 35
36 36 class Header(object):
37 37
38 38 def __init__(self):
39 39 raise NotImplementedError
40 40
41 41
42 42 def read(self):
43 43
44 44 raise NotImplementedError
45 45
46 46 def write(self):
47 47
48 48 raise NotImplementedError
49 49
50 50 def printInfo(self):
51 51
52 52 message = "#"*50 + "\n"
53 53 message += self.__class__.__name__.upper() + "\n"
54 54 message += "#"*50 + "\n"
55 55
56 56 keyList = self.__dict__.keys()
57 57 keyList.sort()
58 58
59 59 for key in keyList:
60 60 message += "%s = %s" %(key, self.__dict__[key]) + "\n"
61 61
62 62 if "size" not in keyList:
63 63 attr = getattr(self, "size")
64 64
65 65 if attr:
66 66 message += "%s = %s" %("size", attr) + "\n"
67 67
68 68 #print message
69 69
70 70
71 71
72 72
73 73
74 74 FILE_STRUCTURE = numpy.dtype([ #HEADER 48bytes
75 75 ('FileMgcNumber','<u4'), #0x23020100
76 76 ('nFDTdataRecors','<u4'), #No Of FDT data records in this file (0 or more)
77 77 ('OffsetStartHeader','<u4'),
78 78 ('RadarUnitId','<u4'),
79 79 ('SiteName',numpy.str_,32), #Null terminated
80 80 ])
81 81
82 82 class FileHeaderBLTR(Header):
83 83
84 84 def __init__(self):
85 85
86 86 self.FileMgcNumber= 0 #0x23020100
87 87 self.nFDTdataRecors=0 #No Of FDT data records in this file (0 or more)
88 88 self.RadarUnitId= 0
89 89 self.OffsetStartHeader=0
90 90 self.SiteName= ""
91 91 self.size = 48
92 92
93 93 def FHread(self, fp):
94 94 #try:
95 95 startFp = open(fp,"rb")
96 96
97 97 header = numpy.fromfile(startFp, FILE_STRUCTURE,1)
98 98
99 99 print ' '
100 100 print 'puntero file header', startFp.tell()
101 101 print ' '
102 102
103 103
104 104 ''' numpy.fromfile(file, dtype, count, sep='')
105 105 file : file or str
106 106 Open file object or filename.
107 107
108 108 dtype : data-type
109 109 Data type of the returned array. For binary files, it is used to determine
110 110 the size and byte-order of the items in the file.
111 111
112 112 count : int
113 113 Number of items to read. -1 means all items (i.e., the complete file).
114 114
115 115 sep : str
116 116 Separator between items if file is a text file. Empty ("") separator means
117 117 the file should be treated as binary. Spaces (" ") in the separator match zero
118 118 or more whitespace characters. A separator consisting only of spaces must match
119 119 at least one whitespace.
120 120
121 121 '''
122 122
123 123
124 124
125 125 self.FileMgcNumber= hex(header['FileMgcNumber'][0])
126 126 self.nFDTdataRecors=int(header['nFDTdataRecors'][0]) #No Of FDT data records in this file (0 or more)
127 127 self.RadarUnitId= int(header['RadarUnitId'][0])
128 128 self.OffsetStartHeader= int(header['OffsetStartHeader'][0])
129 129 self.SiteName= str(header['SiteName'][0])
130 130
131 131 #print 'Numero de bloques', self.nFDTdataRecors
132 132
133 133
134 134 if self.size <48:
135 135 return 0
136 136
137 137 return 1
138 138
139 139
140 140 def write(self, fp):
141 141
142 142 headerTuple = (self.FileMgcNumber,
143 143 self.nFDTdataRecors,
144 144 self.RadarUnitId,
145 145 self.SiteName,
146 146 self.size)
147 147
148 148
149 149 header = numpy.array(headerTuple, FILE_STRUCTURE)
150 150 # numpy.array(object, dtype=None, copy=True, order=None, subok=False, ndmin=0)
151 151 header.tofile(fp)
152 152 ''' ndarray.tofile(fid, sep, format) Write array to a file as text or binary (default).
153 153
154 154 fid : file or str
155 155 An open file object, or a string containing a filename.
156 156
157 157 sep : str
158 158 Separator between array items for text output. If "" (empty), a binary file is written,
159 159 equivalent to file.write(a.tobytes()).
160 160
161 161 format : str
162 162 Format string for text file output. Each entry in the array is formatted to text by
163 163 first converting it to the closest Python type, and then using "format" % item.
164 164
165 165 '''
166 166
167 167 return 1
168 168
169 169
170 170
171 171
172 172
173 173 RECORD_STRUCTURE = numpy.dtype([ #RECORD HEADER 180+20N bytes
174 174 ('RecMgcNumber','<u4'), #0x23030001
175 175 ('RecCounter','<u4'), #Record counter(0,1, ...)
176 176 ('Off2StartNxtRec','<u4'), #Offset to start of next record form start of this record
177 177 ('Off2StartData','<u4'), #Offset to start of data from start of this record
178 178 ('nUtime','<i4'), #Epoch time stamp of start of acquisition (seconds)
179 179 ('nMilisec','<u4'), #Millisecond component of time stamp (0,...,999)
180 180 ('ExpTagName',numpy.str_,32), #Experiment tag name (null terminated)
181 181 ('ExpComment',numpy.str_,32), #Experiment comment (null terminated)
182 182 ('SiteLatDegrees','<f4'), #Site latitude (from GPS) in degrees (positive implies North)
183 183 ('SiteLongDegrees','<f4'), #Site longitude (from GPS) in degrees (positive implies East)
184 184 ('RTCgpsStatus','<u4'), #RTC GPS engine status (0=SEEK, 1=LOCK, 2=NOT FITTED, 3=UNAVAILABLE)
185 185 ('TransmitFrec','<u4'), #Transmit frequency (Hz)
186 186 ('ReceiveFrec','<u4'), #Receive frequency
187 187 ('FirstOsciFrec','<u4'), #First local oscillator frequency (Hz)
188 188 ('Polarisation','<u4'), #(0="O", 1="E", 2="linear 1", 3="linear2")
189 189 ('ReceiverFiltSett','<u4'), #Receiver filter settings (0,1,2,3)
190 190 ('nModesInUse','<u4'), #Number of modes in use (1 or 2)
191 191 ('DualModeIndex','<u4'), #Dual Mode index number for these data (0 or 1)
192 192 ('DualModeRange','<u4'), #Dual Mode range correction for these data (m)
193 193 ('nDigChannels','<u4'), #Number of digital channels acquired (2*N)
194 194 ('SampResolution','<u4'), #Sampling resolution (meters)
195 195 ('nHeights','<u4'), #Number of range gates sampled
196 196 ('StartRangeSamp','<u4'), #Start range of sampling (meters)
197 197 ('PRFhz','<u4'), #PRF (Hz)
198 198 ('nCohInt','<u4'), #Integrations
199 199 ('nProfiles','<u4'), #Number of data points transformed
200 200 ('nChannels','<u4'), #Number of receive beams stored in file (1 or N)
201 201 ('nIncohInt','<u4'), #Number of spectral averages
202 202 ('FFTwindowingInd','<u4'), #FFT windowing index (0 = no window)
203 203 ('BeamAngleAzim','<f4'), #Beam steer angle (azimuth) in degrees (clockwise from true North)
204 204 ('BeamAngleZen','<f4'), #Beam steer angle (zenith) in degrees (0=> vertical)
205 205 ('AntennaCoord0','<f4'), #Antenna coordinates (Range(meters), Bearing(degrees)) - N pairs
206 206 ('AntennaAngl0','<f4'), #Antenna coordinates (Range(meters), Bearing(degrees)) - N pairs
207 207 ('AntennaCoord1','<f4'), #Antenna coordinates (Range(meters), Bearing(degrees)) - N pairs
208 208 ('AntennaAngl1','<f4'), #Antenna coordinates (Range(meters), Bearing(degrees)) - N pairs
209 209 ('AntennaCoord2','<f4'), #Antenna coordinates (Range(meters), Bearing(degrees)) - N pairs
210 210 ('AntennaAngl2','<f4'), #Antenna coordinates (Range(meters), Bearing(degrees)) - N pairs
211 211 ('RecPhaseCalibr0','<f4'), #Receiver phase calibration (degrees) - N values
212 212 ('RecPhaseCalibr1','<f4'), #Receiver phase calibration (degrees) - N values
213 213 ('RecPhaseCalibr2','<f4'), #Receiver phase calibration (degrees) - N values
214 214 ('RecAmpCalibr0','<f4'), #Receiver amplitude calibration (ratio relative to receiver one) - N values
215 215 ('RecAmpCalibr1','<f4'), #Receiver amplitude calibration (ratio relative to receiver one) - N values
216 216 ('RecAmpCalibr2','<f4'), #Receiver amplitude calibration (ratio relative to receiver one) - N values
217 217 ('ReceiverGaindB0','<i4'), #Receiver gains in dB - N values
218 218 ('ReceiverGaindB1','<i4'), #Receiver gains in dB - N values
219 219 ('ReceiverGaindB2','<i4'), #Receiver gains in dB - N values
220 220 ])
221 221
222 222
223 223 class RecordHeaderBLTR(Header):
224 224
225 225 def __init__(self, RecMgcNumber=None, RecCounter= 0, Off2StartNxtRec= 811248,
226 226 nUtime= 0, nMilisec= 0, ExpTagName= None,
227 227 ExpComment=None, SiteLatDegrees=0, SiteLongDegrees= 0,
228 228 RTCgpsStatus= 0, TransmitFrec= 0, ReceiveFrec= 0,
229 229 FirstOsciFrec= 0, Polarisation= 0, ReceiverFiltSett= 0,
230 230 nModesInUse= 0, DualModeIndex= 0, DualModeRange= 0,
231 231 nDigChannels= 0, SampResolution= 0, nHeights= 0,
232 232 StartRangeSamp= 0, PRFhz= 0, nCohInt= 0,
233 233 nProfiles= 0, nChannels= 0, nIncohInt= 0,
234 234 FFTwindowingInd= 0, BeamAngleAzim= 0, BeamAngleZen= 0,
235 235 AntennaCoord0= 0, AntennaCoord1= 0, AntennaCoord2= 0,
236 236 RecPhaseCalibr0= 0, RecPhaseCalibr1= 0, RecPhaseCalibr2= 0,
237 237 RecAmpCalibr0= 0, RecAmpCalibr1= 0, RecAmpCalibr2= 0,
238 238 AntennaAngl0=0, AntennaAngl1=0, AntennaAngl2=0,
239 239 ReceiverGaindB0= 0, ReceiverGaindB1= 0, ReceiverGaindB2= 0, Off2StartData=0, OffsetStartHeader=0):
240 240
241 241 self.RecMgcNumber = RecMgcNumber #0x23030001
242 242 self.RecCounter = RecCounter
243 243 self.Off2StartNxtRec = Off2StartNxtRec
244 244 self.Off2StartData = Off2StartData
245 245 self.nUtime = nUtime
246 246 self.nMilisec = nMilisec
247 247 self.ExpTagName = ExpTagName
248 248 self.ExpComment = ExpComment
249 249 self.SiteLatDegrees = SiteLatDegrees
250 250 self.SiteLongDegrees = SiteLongDegrees
251 251 self.RTCgpsStatus = RTCgpsStatus
252 252 self.TransmitFrec = TransmitFrec
253 253 self.ReceiveFrec = ReceiveFrec
254 254 self.FirstOsciFrec = FirstOsciFrec
255 255 self.Polarisation = Polarisation
256 256 self.ReceiverFiltSett = ReceiverFiltSett
257 257 self.nModesInUse = nModesInUse
258 258 self.DualModeIndex = DualModeIndex
259 259 self.DualModeRange = DualModeRange
260 260 self.nDigChannels = nDigChannels
261 261 self.SampResolution = SampResolution
262 262 self.nHeights = nHeights
263 263 self.StartRangeSamp = StartRangeSamp
264 264 self.PRFhz = PRFhz
265 265 self.nCohInt = nCohInt
266 266 self.nProfiles = nProfiles
267 267 self.nChannels = nChannels
268 268 self.nIncohInt = nIncohInt
269 269 self.FFTwindowingInd = FFTwindowingInd
270 270 self.BeamAngleAzim = BeamAngleAzim
271 271 self.BeamAngleZen = BeamAngleZen
272 272 self.AntennaCoord0 = AntennaCoord0
273 273 self.AntennaAngl0 = AntennaAngl0
274 274 self.AntennaAngl1 = AntennaAngl1
275 275 self.AntennaAngl2 = AntennaAngl2
276 276 self.AntennaCoord1 = AntennaCoord1
277 277 self.AntennaCoord2 = AntennaCoord2
278 278 self.RecPhaseCalibr0 = RecPhaseCalibr0
279 279 self.RecPhaseCalibr1 = RecPhaseCalibr1
280 280 self.RecPhaseCalibr2 = RecPhaseCalibr2
281 281 self.RecAmpCalibr0 = RecAmpCalibr0
282 282 self.RecAmpCalibr1 = RecAmpCalibr1
283 283 self.RecAmpCalibr2 = RecAmpCalibr2
284 284 self.ReceiverGaindB0 = ReceiverGaindB0
285 285 self.ReceiverGaindB1 = ReceiverGaindB1
286 286 self.ReceiverGaindB2 = ReceiverGaindB2
287 287 self.OffsetStartHeader = 48
288 288
289 289
290 290
291 291 def RHread(self, fp):
292 292 #print fp
293 293 #startFp = open('/home/erick/Documents/Data/huancayo.20161019.22.fdt',"rb") #The method tell() returns the current position of the file read/write pointer within the file.
294 294 startFp = open(fp,"rb") #The method tell() returns the current position of the file read/write pointer within the file.
295 295 #RecCounter=0
296 296 #Off2StartNxtRec=811248
297 297 OffRHeader= self.OffsetStartHeader + self.RecCounter*self.Off2StartNxtRec
298 298 print ' '
299 299 print 'puntero Record Header', startFp.tell()
300 300 print ' '
301 301
302 302
303 303 startFp.seek(OffRHeader, os.SEEK_SET)
304 304
305 305 print ' '
306 306 print 'puntero Record Header con seek', startFp.tell()
307 307 print ' '
308 308
309 309 #print 'Posicion del bloque: ',OffRHeader
310 310
311 311 header = numpy.fromfile(startFp,RECORD_STRUCTURE,1)
312 312
313 313 print ' '
314 314 print 'puntero Record Header con seek', startFp.tell()
315 315 print ' '
316 316
317 317 print ' '
318 318 #
319 319 #print 'puntero Record Header despues de seek', header.tell()
320 320 print ' '
321 321
322 322 self.RecMgcNumber = hex(header['RecMgcNumber'][0]) #0x23030001
323 323 self.RecCounter = int(header['RecCounter'][0])
324 324 self.Off2StartNxtRec = int(header['Off2StartNxtRec'][0])
325 325 self.Off2StartData = int(header['Off2StartData'][0])
326 326 self.nUtime = header['nUtime'][0]
327 327 self.nMilisec = header['nMilisec'][0]
328 328 self.ExpTagName = str(header['ExpTagName'][0])
329 329 self.ExpComment = str(header['ExpComment'][0])
330 330 self.SiteLatDegrees = header['SiteLatDegrees'][0]
331 331 self.SiteLongDegrees = header['SiteLongDegrees'][0]
332 332 self.RTCgpsStatus = header['RTCgpsStatus'][0]
333 333 self.TransmitFrec = header['TransmitFrec'][0]
334 334 self.ReceiveFrec = header['ReceiveFrec'][0]
335 335 self.FirstOsciFrec = header['FirstOsciFrec'][0]
336 336 self.Polarisation = header['Polarisation'][0]
337 337 self.ReceiverFiltSett = header['ReceiverFiltSett'][0]
338 338 self.nModesInUse = header['nModesInUse'][0]
339 339 self.DualModeIndex = header['DualModeIndex'][0]
340 340 self.DualModeRange = header['DualModeRange'][0]
341 341 self.nDigChannels = header['nDigChannels'][0]
342 342 self.SampResolution = header['SampResolution'][0]
343 343 self.nHeights = header['nHeights'][0]
344 344 self.StartRangeSamp = header['StartRangeSamp'][0]
345 345 self.PRFhz = header['PRFhz'][0]
346 346 self.nCohInt = header['nCohInt'][0]
347 347 self.nProfiles = header['nProfiles'][0]
348 348 self.nChannels = header['nChannels'][0]
349 349 self.nIncohInt = header['nIncohInt'][0]
350 350 self.FFTwindowingInd = header['FFTwindowingInd'][0]
351 351 self.BeamAngleAzim = header['BeamAngleAzim'][0]
352 352 self.BeamAngleZen = header['BeamAngleZen'][0]
353 353 self.AntennaCoord0 = header['AntennaCoord0'][0]
354 354 self.AntennaAngl0 = header['AntennaAngl0'][0]
355 355 self.AntennaCoord1 = header['AntennaCoord1'][0]
356 356 self.AntennaAngl1 = header['AntennaAngl1'][0]
357 357 self.AntennaCoord2 = header['AntennaCoord2'][0]
358 358 self.AntennaAngl2 = header['AntennaAngl2'][0]
359 359 self.RecPhaseCalibr0 = header['RecPhaseCalibr0'][0]
360 360 self.RecPhaseCalibr1 = header['RecPhaseCalibr1'][0]
361 361 self.RecPhaseCalibr2 = header['RecPhaseCalibr2'][0]
362 362 self.RecAmpCalibr0 = header['RecAmpCalibr0'][0]
363 363 self.RecAmpCalibr1 = header['RecAmpCalibr1'][0]
364 364 self.RecAmpCalibr2 = header['RecAmpCalibr2'][0]
365 365 self.ReceiverGaindB0 = header['ReceiverGaindB0'][0]
366 366 self.ReceiverGaindB1 = header['ReceiverGaindB1'][0]
367 367 self.ReceiverGaindB2 = header['ReceiverGaindB2'][0]
368 368
369 369 self.ipp= 0.5*(SPEED_OF_LIGHT/self.PRFhz)
370 370
371 371 self.RHsize = 180+20*self.nChannels
372 372 self.Datasize= self.nProfiles*self.nChannels*self.nHeights*2*4
373 373 #print 'Datasize',self.Datasize
374 374 endFp = self.OffsetStartHeader + self.RecCounter*self.Off2StartNxtRec
375 375
376 376 print '=============================================='
377 377 print 'RecMgcNumber ',self.RecMgcNumber
378 378 print 'RecCounter ',self.RecCounter
379 379 print 'Off2StartNxtRec ',self.Off2StartNxtRec
380 380 print 'Off2StartData ',self.Off2StartData
381 381 print 'Range Resolution ',self.SampResolution
382 382 print 'First Height ',self.StartRangeSamp
383 383 print 'PRF (Hz) ',self.PRFhz
384 384 print 'Heights (K) ',self.nHeights
385 385 print 'Channels (N) ',self.nChannels
386 386 print 'Profiles (J) ',self.nProfiles
387 387 print 'iCoh ',self.nCohInt
388 388 print 'iInCoh ',self.nIncohInt
389 389 print 'BeamAngleAzim ',self.BeamAngleAzim
390 390 print 'BeamAngleZen ',self.BeamAngleZen
391 391
392 392 #print 'ModoEnUso ',self.DualModeIndex
393 393 #print 'UtcTime ',self.nUtime
394 394 #print 'MiliSec ',self.nMilisec
395 395 #print 'Exp TagName ',self.ExpTagName
396 396 #print 'Exp Comment ',self.ExpComment
397 397 #print 'FFT Window Index ',self.FFTwindowingInd
398 398 #print 'N Dig. Channels ',self.nDigChannels
399 399 print 'Size de bloque ',self.RHsize
400 400 print 'DataSize ',self.Datasize
401 401 print 'BeamAngleAzim ',self.BeamAngleAzim
402 402 #print 'AntennaCoord0 ',self.AntennaCoord0
403 403 #print 'AntennaAngl0 ',self.AntennaAngl0
404 404 #print 'AntennaCoord1 ',self.AntennaCoord1
405 405 #print 'AntennaAngl1 ',self.AntennaAngl1
406 406 #print 'AntennaCoord2 ',self.AntennaCoord2
407 407 #print 'AntennaAngl2 ',self.AntennaAngl2
408 408 print 'RecPhaseCalibr0 ',self.RecPhaseCalibr0
409 409 print 'RecPhaseCalibr1 ',self.RecPhaseCalibr1
410 410 print 'RecPhaseCalibr2 ',self.RecPhaseCalibr2
411 411 print 'RecAmpCalibr0 ',self.RecAmpCalibr0
412 412 print 'RecAmpCalibr1 ',self.RecAmpCalibr1
413 413 print 'RecAmpCalibr2 ',self.RecAmpCalibr2
414 414 print 'ReceiverGaindB0 ',self.ReceiverGaindB0
415 415 print 'ReceiverGaindB1 ',self.ReceiverGaindB1
416 416 print 'ReceiverGaindB2 ',self.ReceiverGaindB2
417 417 print '=============================================='
418 418
419 419 if OffRHeader > endFp:
420 420 sys.stderr.write("Warning %s: Size value read from System Header is lower than it has to be\n" %fp)
421 421 return 0
422 422
423 423 if OffRHeader < endFp:
424 424 sys.stderr.write("Warning %s: Size value read from System Header size is greater than it has to be\n" %fp)
425 425 return 0
426 426
427 427 return 1
428 428
429 429
430 430 class BLTRReader (ProcessingUnit, FileHeaderBLTR, RecordHeaderBLTR, JRODataReader):
431 431
432 432 path = None
433 433 startDate = None
434 434 endDate = None
435 435 startTime = None
436 436 endTime = None
437 437 walk = None
438 438 isConfig = False
439 439
440 440
441 441 fileList= None
442 442
443 443 #metadata
444 444 TimeZone= None
445 445 Interval= None
446 446 heightList= None
447 447
448 448 #data
449 449 data= None
450 450 utctime= None
451 451
452 452
453 453
454 454 def __init__(self, **kwargs):
455 455
456 456 #Eliminar de la base la herencia
457 457 ProcessingUnit.__init__(self, **kwargs)
458 458
459 459 # self.isConfig = False
460 460
461 461 #self.pts2read_SelfSpectra = 0
462 462 #self.pts2read_CrossSpectra = 0
463 463 #self.pts2read_DCchannels = 0
464 464 #self.datablock = None
465 465 self.utc = None
466 466 self.ext = ".fdt"
467 467 self.optchar = "P"
468 468 self.fpFile=None
469 469 self.fp = None
470 470 self.BlockCounter=0
471 471 self.dtype = None
472 472 self.fileSizeByHeader = None
473 473 self.filenameList = []
474 474 self.fileSelector = 0
475 475 self.Off2StartNxtRec=0
476 476 self.RecCounter=0
477 477 self.flagNoMoreFiles = 0
478 478 self.data_spc=None
479 479 self.data_cspc=None
480 480 self.data_output=None
481 481 self.path = None
482 482 self.OffsetStartHeader=0
483 483 self.Off2StartData=0
484 484 self.ipp = 0
485 485 self.nFDTdataRecors=0
486 486 self.blocksize = 0
487 487 self.dataOut = Spectra()
488 488 self.profileIndex = 1 #Always
489 489 self.dataOut.flagNoData=False
490 490 self.dataOut.nRdPairs = 0
491 491 self.dataOut.pairsList = []
492 492 self.dataOut.data_spc=None
493 493 self.dataOut.noise=[]
494 494 self.dataOut.velocityX=[]
495 495 self.dataOut.velocityY=[]
496 496 self.dataOut.velocityV=[]
497 497
498 498
499 499
500 500 def Files2Read(self, fp):
501 501 '''
502 502 Function that indicates the number of .fdt files that exist in the folder to be read.
503 503 It also creates an organized list with the names of the files to read.
504 504 '''
505 505 #self.__checkPath()
506 506
507 507 ListaData=os.listdir(fp) #Gets the list of files within the fp address
508 508 ListaData=sorted(ListaData) #Sort the list of files from least to largest by names
509 509 nFiles=0 #File Counter
510 510 FileList=[] #A list is created that will contain the .fdt files
511 511 for IndexFile in ListaData :
512 512 if '.fdt' in IndexFile:
513 513 FileList.append(IndexFile)
514 514 nFiles+=1
515 515
516 516 #print 'Files2Read'
517 517 #print 'Existen '+str(nFiles)+' archivos .fdt'
518 518
519 519 self.filenameList=FileList #List of files from least to largest by names
520 520
521 521
522 522 def run(self, **kwargs):
523 523 '''
524 524 This method will be the one that will initiate the data entry, will be called constantly.
525 525 You should first verify that your Setup () is set up and then continue to acquire
526 526 the data to be processed with getData ().
527 527 '''
528 528 if not self.isConfig:
529 529 self.setup(**kwargs)
530 530 self.isConfig = True
531 531
532 532 self.getData()
533 533 #print 'running'
534 534
535 535
536 536 def setup(self, path=None,
537 537 startDate=None,
538 538 endDate=None,
539 539 startTime=None,
540 540 endTime=None,
541 541 walk=True,
542 542 timezone='utc',
543 543 code = None,
544 544 online=False,
545 545 ReadMode=None,
546 546 **kwargs):
547 547
548 548 self.isConfig = True
549 549
550 550 self.path=path
551 551 self.startDate=startDate
552 552 self.endDate=endDate
553 553 self.startTime=startTime
554 554 self.endTime=endTime
555 555 self.walk=walk
556 556 self.ReadMode=int(ReadMode)
557 557
558 558 pass
559 559
560 560
561 561 def getData(self):
562 562 '''
563 563 Before starting this function, you should check that there is still an unread file,
564 564 If there are still blocks to read or if the data block is empty.
565 565
566 566 You should call the file "read".
567 567
568 568 '''
569 569
570 570 if self.flagNoMoreFiles:
571 571 self.dataOut.flagNoData = True
572 572 print 'NoData se vuelve true'
573 573 return 0
574 574
575 575 self.fp=self.path
576 576 self.Files2Read(self.fp)
577 577 self.readFile(self.fp)
578 578 self.dataOut.data_spc = self.data_spc
579 579 self.dataOut.data_cspc =self.data_cspc
580 580 self.dataOut.data_output=self.data_output
581 581
582 582 print 'self.dataOut.data_output', shape(self.dataOut.data_output)
583 583
584 584 #self.removeDC()
585 585 return self.dataOut.data_spc
586 586
587 587
588 588 def readFile(self,fp):
589 589 '''
590 590 You must indicate if you are reading in Online or Offline mode and load the
591 591 The parameters for this file reading mode.
592 592
593 593 Then you must do 2 actions:
594 594
595 595 1. Get the BLTR FileHeader.
596 596 2. Start reading the first block.
597 597 '''
598 598
599 599 #The address of the folder is generated the name of the .fdt file that will be read
600 600 print "File: ",self.fileSelector+1
601 601
602 602 if self.fileSelector < len(self.filenameList):
603 603
604 604 self.fpFile=str(fp)+'/'+str(self.filenameList[self.fileSelector])
605 605 #print self.fpFile
606 606 fheader = FileHeaderBLTR()
607 607 fheader.FHread(self.fpFile) #Bltr FileHeader Reading
608 608 self.nFDTdataRecors=fheader.nFDTdataRecors
609 609
610 610 self.readBlock() #Block reading
611 611 else:
612 612 print 'readFile FlagNoData becomes true'
613 613 self.flagNoMoreFiles=True
614 614 self.dataOut.flagNoData = True
615 615 return 0
616 616
617 617 def getVelRange(self, extrapoints=0):
618 618 Lambda= SPEED_OF_LIGHT/50000000
619 619 PRF = self.dataOut.PRF#1./(self.dataOut.ippSeconds * self.dataOut.nCohInt)
620 620 Vmax=-Lambda/(4.*(1./PRF)*self.dataOut.nCohInt*2.)
621 621 deltafreq = PRF / (self.nProfiles)
622 622 deltavel = (Vmax*2) / (self.nProfiles)
623 623 freqrange = deltafreq*(numpy.arange(self.nProfiles)-self.nProfiles/2.) - deltafreq/2
624 624 velrange = deltavel*(numpy.arange(self.nProfiles)-self.nProfiles/2.)
625 625 return velrange
626 626
627 627 def readBlock(self):
628 628 '''
629 629 It should be checked if the block has data, if it is not passed to the next file.
630 630
631 631 Then the following is done:
632 632
633 633 1. Read the RecordHeader
634 634 2. Fill the buffer with the current block number.
635 635
636 636 '''
637 637
638 638 if self.BlockCounter < self.nFDTdataRecors-2:
639 639 print self.nFDTdataRecors, 'CONDICION!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
640 640 if self.ReadMode==1:
641 641 rheader = RecordHeaderBLTR(RecCounter=self.BlockCounter+1)
642 642 elif self.ReadMode==0:
643 643 rheader = RecordHeaderBLTR(RecCounter=self.BlockCounter)
644 644
645 645 rheader.RHread(self.fpFile) #Bltr FileHeader Reading
646 646
647 647 self.OffsetStartHeader=rheader.OffsetStartHeader
648 648 self.RecCounter=rheader.RecCounter
649 649 self.Off2StartNxtRec=rheader.Off2StartNxtRec
650 650 self.Off2StartData=rheader.Off2StartData
651 651 self.nProfiles=rheader.nProfiles
652 652 self.nChannels=rheader.nChannels
653 653 self.nHeights=rheader.nHeights
654 654 self.frequency=rheader.TransmitFrec
655 655 self.DualModeIndex=rheader.DualModeIndex
656 656
657 657 self.pairsList =[(0,1),(0,2),(1,2)]
658 658 self.dataOut.pairsList = self.pairsList
659 659
660 660 self.nRdPairs=len(self.dataOut.pairsList)
661 661 self.dataOut.nRdPairs = self.nRdPairs
662 662
663 663 self.__firstHeigth=rheader.StartRangeSamp
664 664 self.__deltaHeigth=rheader.SampResolution
665 665 self.dataOut.heightList= self.__firstHeigth + numpy.array(range(self.nHeights))*self.__deltaHeigth
666 666 self.dataOut.channelList = range(self.nChannels)
667 667 self.dataOut.nProfiles=rheader.nProfiles
668 668 self.dataOut.nIncohInt=rheader.nIncohInt
669 669 self.dataOut.nCohInt=rheader.nCohInt
670 670 self.dataOut.ippSeconds= 1/float(rheader.PRFhz)
671 671 self.dataOut.PRF=rheader.PRFhz
672 672 self.dataOut.nFFTPoints=rheader.nProfiles
673 673 self.dataOut.utctime=rheader.nUtime
674 674 self.dataOut.timeZone=0
675 675 self.dataOut.normFactor= self.dataOut.nProfiles*self.dataOut.nIncohInt*self.dataOut.nCohInt
676 676 self.dataOut.outputInterval= self.dataOut.ippSeconds * self.dataOut.nCohInt * self.dataOut.nIncohInt * self.nProfiles
677 677
678 678 self.data_output=numpy.ones([3,rheader.nHeights])*numpy.NaN
679 679 print 'self.data_output', shape(self.data_output)
680 680 self.dataOut.velocityX=[]
681 681 self.dataOut.velocityY=[]
682 682 self.dataOut.velocityV=[]
683 683
684 684 '''Block Reading, the Block Data is received and Reshape is used to give it
685 685 shape.
686 686 '''
687 687
688 688 #Procedure to take the pointer to where the date block starts
689 689 startDATA = open(self.fpFile,"rb")
690 690 OffDATA= self.OffsetStartHeader + self.RecCounter*self.Off2StartNxtRec+self.Off2StartData
691 691 startDATA.seek(OffDATA, os.SEEK_SET)
692 692
693 693 def moving_average(x, N=2):
694 694 return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):]
695 695
696 696 def gaus(xSamples,a,x0,sigma):
697 697 return a*exp(-(xSamples-x0)**2/(2*sigma**2))
698 698
699 699 def Find(x,value):
700 700 for index in range(len(x)):
701 701 if x[index]==value:
702 702 return index
703 703
704 704 def pol2cart(rho, phi):
705 705 x = rho * numpy.cos(phi)
706 706 y = rho * numpy.sin(phi)
707 707 return(x, y)
708 708
709 709
710 710
711 711
712 712 if self.DualModeIndex==self.ReadMode:
713 713
714 714 self.data_fft = numpy.fromfile( startDATA, [('complex','<c8')],self.nProfiles*self.nChannels*self.nHeights )
715 715
716 716 self.data_fft=self.data_fft.astype(numpy.dtype('complex'))
717 717
718 718 self.data_block=numpy.reshape(self.data_fft,(self.nHeights, self.nChannels, self.nProfiles ))
719 719
720 720 self.data_block = numpy.transpose(self.data_block, (1,2,0))
721 721
722 722 copy = self.data_block.copy()
723 723 spc = copy * numpy.conjugate(copy)
724 724
725 725 self.data_spc = numpy.absolute(spc) # valor absoluto o magnitud
726 726
727 727 factor = self.dataOut.normFactor
728 728
729 729
730 730 z = self.data_spc.copy()#/factor
731 731 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
732 732 #zdB = 10*numpy.log10(z)
733 733 print ' '
734 734 print 'Z: '
735 735 print shape(z)
736 736 print ' '
737 737 print ' '
738 738
739 739 self.dataOut.data_spc=self.data_spc
740 740
741 741 self.noise = self.dataOut.getNoise(ymin_index=80, ymax_index=132)#/factor
742 742 #noisedB = 10*numpy.log10(self.noise)
743 743
744 744
745 745 ySamples=numpy.ones([3,self.nProfiles])
746 746 phase=numpy.ones([3,self.nProfiles])
747 747 CSPCSamples=numpy.ones([3,self.nProfiles],dtype=numpy.complex_)
748 748 coherence=numpy.ones([3,self.nProfiles])
749 749 PhaseSlope=numpy.ones(3)
750 750 PhaseInter=numpy.ones(3)
751 751
752 752 '''****** Getting CrossSpectra ******'''
753 753 cspc=self.data_block.copy()
754 754 self.data_cspc=self.data_block.copy()
755 755
756 756 xFrec=self.getVelRange(1)
757 757 VelRange=self.getVelRange(1)
758 758 self.dataOut.VelRange=VelRange
759 759 #print ' '
760 760 #print ' '
761 761 #print 'xFrec',xFrec
762 762 #print ' '
763 763 #print ' '
764 764 #Height=35
765
765 766 for i in range(self.nRdPairs):
766 767
767 768 chan_index0 = self.dataOut.pairsList[i][0]
768 769 chan_index1 = self.dataOut.pairsList[i][1]
769 770
770 771 self.data_cspc[i,:,:]=cspc[chan_index0,:,:] * numpy.conjugate(cspc[chan_index1,:,:])
771 772
772 773
773 774 '''Getting Eij and Nij'''
774 775 (AntennaX0,AntennaY0)=pol2cart(rheader.AntennaCoord0, rheader.AntennaAngl0*numpy.pi/180)
775 776 (AntennaX1,AntennaY1)=pol2cart(rheader.AntennaCoord1, rheader.AntennaAngl1*numpy.pi/180)
776 777 (AntennaX2,AntennaY2)=pol2cart(rheader.AntennaCoord2, rheader.AntennaAngl2*numpy.pi/180)
777 778
778 779 E01=AntennaX0-AntennaX1
779 780 N01=AntennaY0-AntennaY1
780 781
781 782 E02=AntennaX0-AntennaX2
782 783 N02=AntennaY0-AntennaY2
783 784
784 785 E12=AntennaX1-AntennaX2
785 786 N12=AntennaY1-AntennaY2
786 787
787 788 self.ChanDist= numpy.array([[E01, N01],[E02,N02],[E12,N12]])
788 789
789 790 self.dataOut.ChanDist = self.ChanDist
790 791
791 792
792 793 # for Height in range(self.nHeights):
793 794 #
794 795 # for i in range(self.nRdPairs):
795 796 #
796 797 # '''****** Line of Data SPC ******'''
797 798 # zline=z[i,:,Height]
798 799 #
799 800 # '''****** DC is removed ******'''
800 801 # DC=Find(zline,numpy.amax(zline))
801 802 # zline[DC]=(zline[DC-1]+zline[DC+1])/2
802 803 #
803 804 #
804 805 # '''****** SPC is normalized ******'''
805 806 # FactNorm= zline.copy() / numpy.sum(zline.copy())
806 807 # FactNorm= FactNorm/numpy.sum(FactNorm)
807 808 #
808 809 # SmoothSPC=moving_average(FactNorm,N=3)
809 810 #
810 811 # xSamples = ar(range(len(SmoothSPC)))
811 812 # ySamples[i] = SmoothSPC-self.noise[i]
812 813 #
813 814 # for i in range(self.nRdPairs):
814 815 #
815 816 # '''****** Line of Data CSPC ******'''
816 817 # cspcLine=self.data_cspc[i,:,Height].copy()
817 818 #
818 819 #
819 820 #
820 821 # '''****** CSPC is normalized ******'''
821 822 # chan_index0 = self.dataOut.pairsList[i][0]
822 823 # chan_index1 = self.dataOut.pairsList[i][1]
823 824 # CSPCFactor= numpy.sum(ySamples[chan_index0]) * numpy.sum(ySamples[chan_index1])
824 825 #
825 826 #
826 827 # CSPCNorm= cspcLine.copy() / numpy.sqrt(CSPCFactor)
827 828 #
828 829 #
829 830 # CSPCSamples[i] = CSPCNorm-self.noise[i]
830 831 # coherence[i] = numpy.abs(CSPCSamples[i]) / numpy.sqrt(CSPCFactor)
831 832 #
832 833 # '''****** DC is removed ******'''
833 834 # DC=Find(coherence[i],numpy.amax(coherence[i]))
834 835 # coherence[i][DC]=(coherence[i][DC-1]+coherence[i][DC+1])/2
835 836 # coherence[i]= moving_average(coherence[i],N=2)
836 837 #
837 838 # phase[i] = moving_average( numpy.arctan2(CSPCSamples[i].imag, CSPCSamples[i].real),N=1)#*180/numpy.pi
838 839 #
839 840 #
840 841 # '''****** Getting fij width ******'''
841 842 #
842 843 # yMean=[]
843 844 # yMean2=[]
844 845 #
845 846 # for j in range(len(ySamples[1])):
846 847 # yMean=numpy.append(yMean,numpy.average([ySamples[0,j],ySamples[1,j],ySamples[2,j]]))
847 848 #
848 849 # '''******* Getting fitting Gaussian ******'''
849 850 # meanGauss=sum(xSamples*yMean) / len(xSamples)
850 851 # sigma=sum(yMean*(xSamples-meanGauss)**2) / len(xSamples)
851 852 # #print 'Height',Height,'SNR', meanGauss/sigma**2
852 853 #
853 854 # if (abs(meanGauss/sigma**2) > 0.0001) :
854 855 #
855 856 # try:
856 857 # popt,pcov = curve_fit(gaus,xSamples,yMean,p0=[1,meanGauss,sigma])
857 858 #
858 859 # if numpy.amax(popt)>numpy.amax(yMean)*0.3:
859 860 # FitGauss=gaus(xSamples,*popt)
860 861 #
861 862 # else:
862 863 # FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
863 864 # print 'Verificador: Dentro', Height
864 865 # except RuntimeError:
865 866 #
866 867 # try:
867 868 # for j in range(len(ySamples[1])):
868 869 # yMean2=numpy.append(yMean2,numpy.average([ySamples[1,j],ySamples[2,j]]))
869 870 # popt,pcov = curve_fit(gaus,xSamples,yMean2,p0=[1,meanGauss,sigma])
870 871 # FitGauss=gaus(xSamples,*popt)
871 872 # print 'Verificador: Exepcion1', Height
872 873 # except RuntimeError:
873 874 #
874 875 # try:
875 876 # popt,pcov = curve_fit(gaus,xSamples,ySamples[1],p0=[1,meanGauss,sigma])
876 877 # FitGauss=gaus(xSamples,*popt)
877 878 # print 'Verificador: Exepcion2', Height
878 879 # except RuntimeError:
879 880 # FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
880 881 # print 'Verificador: Exepcion3', Height
881 882 # else:
882 883 # FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
883 884 # #print 'Verificador: Fuera', Height
884 885 #
885 886 #
886 887 #
887 888 # Maximun=numpy.amax(yMean)
888 889 # eMinus1=Maximun*numpy.exp(-1)
889 890 #
890 891 # HWpos=Find(FitGauss,min(FitGauss, key=lambda value:abs(value-eMinus1)))
891 892 # HalfWidth= xFrec[HWpos]
892 893 # GCpos=Find(FitGauss, numpy.amax(FitGauss))
893 894 # Vpos=Find(FactNorm, numpy.amax(FactNorm))
894 895 # #Vpos=numpy.sum(FactNorm)/len(FactNorm)
895 896 # #Vpos=Find(FactNorm, min(FactNorm, key=lambda value:abs(value- numpy.mean(FactNorm) )))
896 897 # #print 'GCpos',GCpos, numpy.amax(FitGauss), 'HWpos',HWpos
897 898 # '''****** Getting Fij ******'''
898 899 #
899 900 # GaussCenter=xFrec[GCpos]
900 901 # if (GaussCenter<0 and HalfWidth>0) or (GaussCenter>0 and HalfWidth<0):
901 902 # Fij=abs(GaussCenter)+abs(HalfWidth)+0.0000001
902 903 # else:
903 904 # Fij=abs(GaussCenter-HalfWidth)+0.0000001
904 905 #
905 906 # '''****** Getting Frecuency range of significant data ******'''
906 907 #
907 908 # Rangpos=Find(FitGauss,min(FitGauss, key=lambda value:abs(value-Maximun*0.10)))
908 909 #
909 910 # if Rangpos<GCpos:
910 911 # Range=numpy.array([Rangpos,2*GCpos-Rangpos])
911 912 # else:
912 913 # Range=numpy.array([2*GCpos-Rangpos,Rangpos])
913 914 #
914 915 # FrecRange=xFrec[Range[0]:Range[1]]
915 916 #
916 917 # #print 'FrecRange', FrecRange
917 918 # '''****** Getting SCPC Slope ******'''
918 919 #
919 920 # for i in range(self.nRdPairs):
920 921 #
921 922 # if len(FrecRange)>5 and len(FrecRange)<self.nProfiles*0.5:
922 923 # PhaseRange=moving_average(phase[i,Range[0]:Range[1]],N=3)
923 924 #
924 925 # slope, intercept, r_value, p_value, std_err = stats.linregress(FrecRange,PhaseRange)
925 926 # PhaseSlope[i]=slope
926 927 # PhaseInter[i]=intercept
927 928 # else:
928 929 # PhaseSlope[i]=0
929 930 # PhaseInter[i]=0
930 931 #
931 932 # # plt.figure(i+15)
932 933 # # plt.title('FASE ( CH%s*CH%s )' %(self.dataOut.pairsList[i][0],self.dataOut.pairsList[i][1]))
933 934 # # plt.xlabel('Frecuencia (KHz)')
934 935 # # plt.ylabel('Magnitud')
935 936 # # #plt.subplot(311+i)
936 937 # # plt.plot(FrecRange,PhaseRange,'b')
937 938 # # plt.plot(FrecRange,FrecRange*PhaseSlope[i]+PhaseInter[i],'r')
938 939 #
939 940 # #plt.axis([-0.6, 0.2, -3.2, 3.2])
940 941 #
941 942 #
942 943 # '''Getting constant C'''
943 944 # cC=(Fij*numpy.pi)**2
944 945 #
945 946 # # '''Getting Eij and Nij'''
946 947 # # (AntennaX0,AntennaY0)=pol2cart(rheader.AntennaCoord0, rheader.AntennaAngl0*numpy.pi/180)
947 948 # # (AntennaX1,AntennaY1)=pol2cart(rheader.AntennaCoord1, rheader.AntennaAngl1*numpy.pi/180)
948 949 # # (AntennaX2,AntennaY2)=pol2cart(rheader.AntennaCoord2, rheader.AntennaAngl2*numpy.pi/180)
949 950 # #
950 951 # # E01=AntennaX0-AntennaX1
951 952 # # N01=AntennaY0-AntennaY1
952 953 # #
953 954 # # E02=AntennaX0-AntennaX2
954 955 # # N02=AntennaY0-AntennaY2
955 956 # #
956 957 # # E12=AntennaX1-AntennaX2
957 958 # # N12=AntennaY1-AntennaY2
958 959 #
959 960 # '''****** Getting constants F and G ******'''
960 961 # MijEijNij=numpy.array([[E02,N02], [E12,N12]])
961 962 # MijResult0=(-PhaseSlope[1]*cC) / (2*numpy.pi)
962 963 # MijResult1=(-PhaseSlope[2]*cC) / (2*numpy.pi)
963 964 # MijResults=numpy.array([MijResult0,MijResult1])
964 965 # (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults)
965 966 #
966 967 # '''****** Getting constants A, B and H ******'''
967 968 # W01=numpy.amax(coherence[0])
968 969 # W02=numpy.amax(coherence[1])
969 970 # W12=numpy.amax(coherence[2])
970 971 #
971 972 # WijResult0=((cF*E01+cG*N01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi/cC))
972 973 # WijResult1=((cF*E02+cG*N02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi/cC))
973 974 # WijResult2=((cF*E12+cG*N12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi/cC))
974 975 #
975 976 # WijResults=numpy.array([WijResult0, WijResult1, WijResult2])
976 977 #
977 978 # WijEijNij=numpy.array([ [E01**2, N01**2, 2*E01*N01] , [E02**2, N02**2, 2*E02*N02] , [E12**2, N12**2, 2*E12*N12] ])
978 979 # (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults)
979 980 #
980 981 # VxVy=numpy.array([[cA,cH],[cH,cB]])
981 982 #
982 983 # VxVyResults=numpy.array([-cF,-cG])
983 984 # (Vx,Vy) = numpy.linalg.solve(VxVy, VxVyResults)
984 985 # Vzon = Vy
985 986 # Vmer = Vx
986 987 # Vmag=numpy.sqrt(Vzon**2+Vmer**2)
987 988 # Vang=numpy.arctan2(Vmer,Vzon)
988 989 #
989 990 # if abs(Vy)<100 and abs(Vy)> 0.:
990 991 # self.dataOut.velocityX=numpy.append(self.dataOut.velocityX, Vzon) #Vmag
991 992 # #print 'Vmag',Vmag
992 993 # else:
993 994 # self.dataOut.velocityX=numpy.append(self.dataOut.velocityX, NaN)
994 995 #
995 996 # if abs(Vx)<100 and abs(Vx) > 0.:
996 997 # self.dataOut.velocityY=numpy.append(self.dataOut.velocityY, Vmer) #Vang
997 998 # #print 'Vang',Vang
998 999 # else:
999 1000 # self.dataOut.velocityY=numpy.append(self.dataOut.velocityY, NaN)
1000 1001 #
1001 1002 # if abs(GaussCenter)<2:
1002 1003 # self.dataOut.velocityV=numpy.append(self.dataOut.velocityV, xFrec[Vpos])
1003 1004 #
1004 1005 # else:
1005 1006 # self.dataOut.velocityV=numpy.append(self.dataOut.velocityV, NaN)
1006 1007 #
1007 1008 #
1008 1009 # # print '********************************************'
1009 1010 # # print 'HalfWidth ', HalfWidth
1010 1011 # # print 'Maximun ', Maximun
1011 1012 # # print 'eMinus1 ', eMinus1
1012 1013 # # print 'Rangpos ', Rangpos
1013 1014 # # print 'GaussCenter ',GaussCenter
1014 1015 # # print 'E01 ',E01
1015 1016 # # print 'N01 ',N01
1016 1017 # # print 'E02 ',E02
1017 1018 # # print 'N02 ',N02
1018 1019 # # print 'E12 ',E12
1019 1020 # # print 'N12 ',N12
1020 1021 # #print 'self.dataOut.velocityX ', self.dataOut.velocityX
1021 1022 # # print 'Fij ', Fij
1022 1023 # # print 'cC ', cC
1023 1024 # # print 'cF ', cF
1024 1025 # # print 'cG ', cG
1025 1026 # # print 'cA ', cA
1026 1027 # # print 'cB ', cB
1027 1028 # # print 'cH ', cH
1028 1029 # # print 'Vx ', Vx
1029 1030 # # print 'Vy ', Vy
1030 1031 # # print 'Vmag ', Vmag
1031 1032 # # print 'Vang ', Vang*180/numpy.pi
1032 1033 # # print 'PhaseSlope ',PhaseSlope[0]
1033 1034 # # print 'PhaseSlope ',PhaseSlope[1]
1034 1035 # # print 'PhaseSlope ',PhaseSlope[2]
1035 1036 # # print '********************************************'
1036 1037 # #print 'data_output',shape(self.dataOut.velocityX), shape(self.dataOut.velocityY)
1037 1038 #
1038 1039 # #print 'self.dataOut.velocityX', len(self.dataOut.velocityX)
1039 1040 # #print 'self.dataOut.velocityY', len(self.dataOut.velocityY)
1040 1041 # #print 'self.dataOut.velocityV', self.dataOut.velocityV
1041 1042 #
1042 1043 # self.data_output[0]=numpy.array(self.dataOut.velocityX)
1043 1044 # self.data_output[1]=numpy.array(self.dataOut.velocityY)
1044 1045 # self.data_output[2]=numpy.array(self.dataOut.velocityV)
1045 1046 #
1046 1047 # prin= self.data_output[0][~numpy.isnan(self.data_output[0])]
1047 1048 # print ' '
1048 1049 # print 'VmagAverage',numpy.mean(prin)
1049 1050 # print ' '
1050 1051 # # plt.figure(5)
1051 1052 # # plt.subplot(211)
1052 1053 # # plt.plot(self.dataOut.velocityX,'yo:')
1053 1054 # # plt.subplot(212)
1054 1055 # # plt.plot(self.dataOut.velocityY,'yo:')
1055 1056 #
1056 1057 # # plt.figure(1)
1057 1058 # # # plt.subplot(121)
1058 1059 # # # plt.plot(xFrec,ySamples[0],'k',label='Ch0')
1059 1060 # # # plt.plot(xFrec,ySamples[1],'g',label='Ch1')
1060 1061 # # # plt.plot(xFrec,ySamples[2],'r',label='Ch2')
1061 1062 # # # plt.plot(xFrec,FitGauss,'yo:',label='fit')
1062 1063 # # # plt.legend()
1063 1064 # # plt.title('DATOS A ALTURA DE 2850 METROS')
1064 1065 # #
1065 1066 # # plt.xlabel('Frecuencia (KHz)')
1066 1067 # # plt.ylabel('Magnitud')
1067 1068 # # # plt.subplot(122)
1068 1069 # # # plt.title('Fit for Time Constant')
1069 1070 # # #plt.plot(xFrec,zline)
1070 1071 # # #plt.plot(xFrec,SmoothSPC,'g')
1071 1072 # # plt.plot(xFrec,FactNorm)
1072 1073 # # plt.axis([-4, 4, 0, 0.15])
1073 1074 # # # plt.xlabel('SelfSpectra KHz')
1074 1075 # #
1075 1076 # # plt.figure(10)
1076 1077 # # # plt.subplot(121)
1077 1078 # # plt.plot(xFrec,ySamples[0],'b',label='Ch0')
1078 1079 # # plt.plot(xFrec,ySamples[1],'y',label='Ch1')
1079 1080 # # plt.plot(xFrec,ySamples[2],'r',label='Ch2')
1080 1081 # # # plt.plot(xFrec,FitGauss,'yo:',label='fit')
1081 1082 # # plt.legend()
1082 1083 # # plt.title('SELFSPECTRA EN CANALES')
1083 1084 # #
1084 1085 # # plt.xlabel('Frecuencia (KHz)')
1085 1086 # # plt.ylabel('Magnitud')
1086 1087 # # # plt.subplot(122)
1087 1088 # # # plt.title('Fit for Time Constant')
1088 1089 # # #plt.plot(xFrec,zline)
1089 1090 # # #plt.plot(xFrec,SmoothSPC,'g')
1090 1091 # # # plt.plot(xFrec,FactNorm)
1091 1092 # # # plt.axis([-4, 4, 0, 0.15])
1092 1093 # # # plt.xlabel('SelfSpectra KHz')
1093 1094 # #
1094 1095 # # plt.figure(9)
1095 1096 # #
1096 1097 # #
1097 1098 # # plt.title('DATOS SUAVIZADOS')
1098 1099 # # plt.xlabel('Frecuencia (KHz)')
1099 1100 # # plt.ylabel('Magnitud')
1100 1101 # # plt.plot(xFrec,SmoothSPC,'g')
1101 1102 # #
1102 1103 # # #plt.plot(xFrec,FactNorm)
1103 1104 # # plt.axis([-4, 4, 0, 0.15])
1104 1105 # # # plt.xlabel('SelfSpectra KHz')
1105 1106 # # #
1106 1107 # # plt.figure(2)
1107 1108 # # # #plt.subplot(121)
1108 1109 # # plt.plot(xFrec,yMean,'r',label='Mean SelfSpectra')
1109 1110 # # plt.plot(xFrec,FitGauss,'yo:',label='Ajuste Gaussiano')
1110 1111 # # # plt.plot(xFrec[Rangpos],FitGauss[Find(FitGauss,min(FitGauss, key=lambda value:abs(value-Maximun*0.1)))],'bo')
1111 1112 # # # #plt.plot(xFrec,phase)
1112 1113 # # # plt.xlabel('Suavizado, promediado KHz')
1113 1114 # # plt.title('SELFSPECTRA PROMEDIADO')
1114 1115 # # # #plt.subplot(122)
1115 1116 # # # #plt.plot(xSamples,zline)
1116 1117 # # plt.xlabel('Frecuencia (KHz)')
1117 1118 # # plt.ylabel('Magnitud')
1118 1119 # # plt.legend()
1119 1120 # # #
1120 1121 # # # plt.figure(3)
1121 1122 # # # plt.subplot(311)
1122 1123 # # # #plt.plot(xFrec,phase[0])
1123 1124 # # # plt.plot(xFrec,phase[0],'g')
1124 1125 # # # plt.subplot(312)
1125 1126 # # # plt.plot(xFrec,phase[1],'g')
1126 1127 # # # plt.subplot(313)
1127 1128 # # # plt.plot(xFrec,phase[2],'g')
1128 1129 # # # #plt.plot(xFrec,phase[2])
1129 1130 # # #
1130 1131 # # # plt.figure(4)
1131 1132 # # #
1132 1133 # # # plt.plot(xSamples,coherence[0],'b')
1133 1134 # # # plt.plot(xSamples,coherence[1],'r')
1134 1135 # # # plt.plot(xSamples,coherence[2],'g')
1135 1136 # # plt.show()
1136 1137 # # #
1137 1138 # # # plt.clf()
1138 1139 # # # plt.cla()
1139 1140 # # # plt.close()
1140 1141 #
1141 1142 # print ' '
1142 1143
1143 1144
1144 1145
1145 1146 self.BlockCounter+=2
1146 1147
1147 1148 else:
1148 1149 self.fileSelector+=1
1149 1150 self.BlockCounter=0
1150 1151 print "Next File"
1151 1152
1152 1153
1153 1154
1154 1155 class BLTRWriter(ProcessingUnit):
1155 1156 '''
1156 1157 classdocs
1157 1158 '''
1158 1159
1159 1160 def __init__(self):
1160 1161 '''
1161 1162 Constructor
1162 1163 '''
1163 1164 self.dataOut = None
1164 1165
1165 1166 self.isConfig = False
1166 1167
1167 1168 def setup(self, dataIn, path, blocksPerFile, set=0, ext=None):
1168 1169 '''
1169 1170 In this method we should set all initial parameters.
1170 1171
1171 1172 Input:
1172 1173 dataIn : Input data will also be outputa data
1173 1174
1174 1175 '''
1175 1176 self.dataOut = dataIn
1176 1177
1177 1178 self.isConfig = True
1178 1179
1179 1180 return
1180 1181
1181 1182 def run(self, dataIn, **kwargs):
1182 1183 '''
1183 1184 This method will be called many times so here you should put all your code
1184 1185
1185 1186 Inputs:
1186 1187
1187 1188 dataIn : object with the data
1188 1189
1189 1190 '''
1190 1191
1191 1192 if not self.isConfig:
1192 1193 self.setup(dataIn, **kwargs)
1193 1194
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
@@ -1,3994 +1,4001
1 1 import numpy
2 2 import math
3 3 from scipy import optimize, interpolate, signal, stats, ndimage
4 4 import scipy
5 5 import re
6 6 import datetime
7 7 import copy
8 8 import sys
9 9 import importlib
10 10 import itertools
11 11 from multiprocessing import Pool, TimeoutError
12 12 from multiprocessing.pool import ThreadPool
13 13 import copy_reg
14 14 import cPickle
15 15 import types
16 16 from functools import partial
17 17 import time
18 18 #from sklearn.cluster import KMeans
19 19
20 20 import matplotlib.pyplot as plt
21 21
22 22 from scipy.optimize import fmin_l_bfgs_b #optimize with bounds on state papameters
23 23 from jroproc_base import ProcessingUnit, Operation
24 24 from schainpy.model.data.jrodata import Parameters, hildebrand_sekhon
25 25 from scipy import asarray as ar,exp
26 26 from scipy.optimize import curve_fit
27 27
28 28 import warnings
29 29 from numpy import NaN
30 30 from scipy.optimize.optimize import OptimizeWarning
31 31 warnings.filterwarnings('ignore')
32 32
33 33
34 34 SPEED_OF_LIGHT = 299792458
35 35
36 36
37 37 '''solving pickling issue'''
38 38
39 39 def _pickle_method(method):
40 40 func_name = method.im_func.__name__
41 41 obj = method.im_self
42 42 cls = method.im_class
43 43 return _unpickle_method, (func_name, obj, cls)
44 44
45 45 def _unpickle_method(func_name, obj, cls):
46 46 for cls in cls.mro():
47 47 try:
48 48 func = cls.__dict__[func_name]
49 49 except KeyError:
50 50 pass
51 51 else:
52 52 break
53 53 return func.__get__(obj, cls)
54 54
55 55
56 56
57 57
58 58
59 59
60 60
61 61
62 62 class ParametersProc(ProcessingUnit):
63 63
64 64 nSeconds = None
65 65
66 66 def __init__(self):
67 67 ProcessingUnit.__init__(self)
68 68
69 69 # self.objectDict = {}
70 70 self.buffer = None
71 71 self.firstdatatime = None
72 72 self.profIndex = 0
73 73 self.dataOut = Parameters()
74 74
75 75 def __updateObjFromInput(self):
76 76
77 77 self.dataOut.inputUnit = self.dataIn.type
78 78
79 79 self.dataOut.timeZone = self.dataIn.timeZone
80 80 self.dataOut.dstFlag = self.dataIn.dstFlag
81 81 self.dataOut.errorCount = self.dataIn.errorCount
82 82 self.dataOut.useLocalTime = self.dataIn.useLocalTime
83 83
84 84 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
85 85 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
86 86 self.dataOut.channelList = self.dataIn.channelList
87 87 self.dataOut.heightList = self.dataIn.heightList
88 88 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
89 89 # self.dataOut.nHeights = self.dataIn.nHeights
90 90 # self.dataOut.nChannels = self.dataIn.nChannels
91 91 self.dataOut.nBaud = self.dataIn.nBaud
92 92 self.dataOut.nCode = self.dataIn.nCode
93 93 self.dataOut.code = self.dataIn.code
94 94 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
95 95 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
96 96 # self.dataOut.utctime = self.firstdatatime
97 97 self.dataOut.utctime = self.dataIn.utctime
98 98 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
99 99 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
100 100 self.dataOut.nCohInt = self.dataIn.nCohInt
101 101 # self.dataOut.nIncohInt = 1
102 102 self.dataOut.ippSeconds = self.dataIn.ippSeconds
103 103 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
104 104 self.dataOut.timeInterval1 = self.dataIn.timeInterval
105 105 self.dataOut.heightList = self.dataIn.getHeiRange()
106 106 self.dataOut.frequency = self.dataIn.frequency
107 107 self.dataOut.noise = self.dataIn.noise
108 108
109 109
110 110
111 111 def run(self):
112 112
113 113 #---------------------- Voltage Data ---------------------------
114 114
115 115 if self.dataIn.type == "Voltage":
116 116
117 117 self.__updateObjFromInput()
118 118 self.dataOut.data_pre = self.dataIn.data.copy()
119 119 self.dataOut.flagNoData = False
120 120 self.dataOut.utctimeInit = self.dataIn.utctime
121 121 self.dataOut.paramInterval = self.dataIn.nProfiles*self.dataIn.nCohInt*self.dataIn.ippSeconds
122 122 return
123 123
124 124 #---------------------- Spectra Data ---------------------------
125 125
126 126 if self.dataIn.type == "Spectra":
127 127
128 128 self.dataOut.data_pre = (self.dataIn.data_spc,self.dataIn.data_cspc)
129 129 print 'self.dataIn.data_spc', self.dataIn.data_spc.shape
130 130 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
131 131 self.dataOut.spc_noise = self.dataIn.getNoise()
132 132 self.dataOut.spc_range = (self.dataIn.getFreqRange(1)/1000. , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1) )
133 133
134 134 self.dataOut.normFactor = self.dataIn.normFactor
135 135 #self.dataOut.outputInterval = self.dataIn.outputInterval
136 136 self.dataOut.groupList = self.dataIn.pairsList
137 137 self.dataOut.flagNoData = False
138 138 #print 'datain chandist ',self.dataIn.ChanDist
139 139 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
140 140 self.dataOut.ChanDist = self.dataIn.ChanDist
141 141 else: self.dataOut.ChanDist = None
142 142
143 143 print 'datain chandist ',self.dataOut.ChanDist
144 144
145 145 if hasattr(self.dataIn, 'VelRange'): #Velocities range
146 146 self.dataOut.VelRange = self.dataIn.VelRange
147 147 else: self.dataOut.VelRange = None
148 148
149 149 if hasattr(self.dataIn, 'RadarConst'): #Radar Constant
150 150 self.dataOut.RadarConst = self.dataIn.RadarConst
151 151
152 152 if hasattr(self.dataIn, 'NPW'): #NPW
153 153 self.dataOut.NPW = self.dataIn.NPW
154 154
155 155 if hasattr(self.dataIn, 'COFA'): #COFA
156 156 self.dataOut.COFA = self.dataIn.COFA
157 157
158 158
159 159
160 160 #---------------------- Correlation Data ---------------------------
161 161
162 162 if self.dataIn.type == "Correlation":
163 163 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
164 164
165 165 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
166 166 self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
167 167 self.dataOut.groupList = (acf_pairs, ccf_pairs)
168 168
169 169 self.dataOut.abscissaList = self.dataIn.lagRange
170 170 self.dataOut.noise = self.dataIn.noise
171 171 self.dataOut.data_SNR = self.dataIn.SNR
172 172 self.dataOut.flagNoData = False
173 173 self.dataOut.nAvg = self.dataIn.nAvg
174 174
175 175 #---------------------- Parameters Data ---------------------------
176 176
177 177 if self.dataIn.type == "Parameters":
178 178 self.dataOut.copy(self.dataIn)
179 179 self.dataOut.flagNoData = False
180 180
181 181 return True
182 182
183 183 self.__updateObjFromInput()
184 184 self.dataOut.utctimeInit = self.dataIn.utctime
185 185 self.dataOut.paramInterval = self.dataIn.timeInterval
186 186
187 187 return
188 188
189 189
190 190 def target(tups):
191 191
192 192 obj, args = tups
193 193 #print 'TARGETTT', obj, args
194 194 return obj.FitGau(args)
195 195
196 196 class GaussianFit(Operation):
197 197
198 198 '''
199 199 Function that fit of one and two generalized gaussians (gg) based
200 200 on the PSD shape across an "power band" identified from a cumsum of
201 201 the measured spectrum - noise.
202 202
203 203 Input:
204 204 self.dataOut.data_pre : SelfSpectra
205 205
206 206 Output:
207 207 self.dataOut.GauSPC : SPC_ch1, SPC_ch2
208 208
209 209 '''
210 210 def __init__(self, **kwargs):
211 211 Operation.__init__(self, **kwargs)
212 212 self.i=0
213 213
214 214
215 215 def run(self, dataOut, num_intg=7, pnoise=1., vel_arr=None, SNRlimit=-9): #num_intg: Incoherent integrations, pnoise: Noise, vel_arr: range of velocities, similar to the ftt points
216 216 """This routine will find a couple of generalized Gaussians to a power spectrum
217 217 input: spc
218 218 output:
219 219 Amplitude0,shift0,width0,p0,Amplitude1,shift1,width1,p1,noise
220 220 """
221 221
222 222 self.spc = dataOut.data_pre[0].copy()
223 223
224 224
225 225 print 'SelfSpectra Shape', numpy.asarray(self.spc).shape
226 226
227 227
228 228 #plt.figure(50)
229 229 #plt.subplot(121)
230 230 #plt.plot(self.spc,'k',label='spc(66)')
231 231 #plt.plot(xFrec,ySamples[1],'g',label='Ch1')
232 232 #plt.plot(xFrec,ySamples[2],'r',label='Ch2')
233 233 #plt.plot(xFrec,FitGauss,'yo:',label='fit')
234 234 #plt.legend()
235 235 #plt.title('DATOS A ALTURA DE 7500 METROS')
236 236 #plt.show()
237 237
238 238 self.Num_Hei = self.spc.shape[2]
239 239 #self.Num_Bin = len(self.spc)
240 240 self.Num_Bin = self.spc.shape[1]
241 241 self.Num_Chn = self.spc.shape[0]
242 242
243 243 Vrange = dataOut.abscissaList
244 244
245 245 #print 'self.spc2', numpy.asarray(self.spc).shape
246 246
247 247 GauSPC = numpy.empty([2,self.Num_Bin,self.Num_Hei])
248 248 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
249 249 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
250 250 SPC_ch1[:] = numpy.NaN
251 251 SPC_ch2[:] = numpy.NaN
252 252
253 253
254 254 start_time = time.time()
255 255
256 256 noise_ = dataOut.spc_noise[0].copy()
257 257
258 258
259 259
260 260 pool = Pool(processes=self.Num_Chn)
261 261 args = [(Vrange, Ch, pnoise, noise_, num_intg, SNRlimit) for Ch in range(self.Num_Chn)]
262 262 objs = [self for __ in range(self.Num_Chn)]
263 263 attrs = zip(objs, args)
264 264 gauSPC = pool.map(target, attrs)
265 265 dataOut.GauSPC = numpy.asarray(gauSPC)
266 266 # ret = []
267 267 # for n in range(self.Num_Chn):
268 268 # self.FitGau(args[n])
269 269 # dataOut.GauSPC = ret
270 270
271 271
272 272
273 273 # for ch in range(self.Num_Chn):
274 274 #
275 275 # for ht in range(self.Num_Hei):
276 276 # #print (numpy.asarray(self.spc).shape)
277 277 # spc = numpy.asarray(self.spc)[ch,:,ht]
278 278 #
279 279 # #############################################
280 280 # # normalizing spc and noise
281 281 # # This part differs from gg1
282 282 # spc_norm_max = max(spc)
283 283 # spc = spc / spc_norm_max
284 284 # pnoise = pnoise / spc_norm_max
285 285 # #############################################
286 286 #
287 287 # if abs(vel_arr[0])<15.0: # this switch is for spectra collected with different length IPP's
288 288 # fatspectra=1.0
289 289 # else:
290 290 # fatspectra=0.5
291 291 #
292 292 # wnoise = noise_ / spc_norm_max
293 293 # #print 'wnoise', noise_, dataOut.spc_noise[0], wnoise
294 294 # #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
295 295 # #if wnoise>1.1*pnoise: # to be tested later
296 296 # # wnoise=pnoise
297 297 # noisebl=wnoise*0.9; noisebh=wnoise*1.1
298 298 # spc=spc-wnoise
299 299 #
300 300 # minx=numpy.argmin(spc)
301 301 # spcs=numpy.roll(spc,-minx)
302 302 # cum=numpy.cumsum(spcs)
303 303 # tot_noise=wnoise * self.Num_Bin #64;
304 304 # #tot_signal=sum(cum[-5:])/5.; ''' How does this line work? '''
305 305 # #snr=tot_signal/tot_noise
306 306 # #snr=cum[-1]/tot_noise
307 307 #
308 308 # #print 'spc' , spcs[5:8] , 'tot_noise', tot_noise
309 309 #
310 310 # snr = sum(spcs)/tot_noise
311 311 # snrdB=10.*numpy.log10(snr)
312 312 #
313 313 # #if snrdB < -9 :
314 314 # # snrdB = numpy.NaN
315 315 # # continue
316 316 #
317 317 # #print 'snr',snrdB # , sum(spcs) , tot_noise
318 318 #
319 319 #
320 320 # #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
321 321 # # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
322 322 #
323 323 # cummax=max(cum); epsi=0.08*fatspectra # cumsum to narrow down the energy region
324 324 # cumlo=cummax*epsi;
325 325 # cumhi=cummax*(1-epsi)
326 326 # powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
327 327 #
328 328 # #if len(powerindex)==1:
329 329 # ##return [numpy.mod(powerindex[0]+minx,64),None,None,None,],[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
330 330 # #return [numpy.mod(powerindex[0]+minx, self.Num_Bin ),None,None,None,],[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
331 331 # #elif len(powerindex)<4*fatspectra:
332 332 # #return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
333 333 #
334 334 # if len(powerindex) < 1:# case for powerindex 0
335 335 # continue
336 336 # powerlo=powerindex[0]
337 337 # powerhi=powerindex[-1]
338 338 # powerwidth=powerhi-powerlo
339 339 #
340 340 # firstpeak=powerlo+powerwidth/10.# first gaussian energy location
341 341 # secondpeak=powerhi-powerwidth/10.#second gaussian energy location
342 342 # midpeak=(firstpeak+secondpeak)/2.
343 343 # firstamp=spcs[int(firstpeak)]
344 344 # secondamp=spcs[int(secondpeak)]
345 345 # midamp=spcs[int(midpeak)]
346 346 # #x=numpy.spc.shape[1]
347 347 #
348 348 # #x=numpy.arange(64)
349 349 # x=numpy.arange( self.Num_Bin )
350 350 # y_data=spc+wnoise
351 351 #
352 352 # # single gaussian
353 353 # #shift0=numpy.mod(midpeak+minx,64)
354 354 # shift0=numpy.mod(midpeak+minx, self.Num_Bin )
355 355 # width0=powerwidth/4.#Initialization entire power of spectrum divided by 4
356 356 # power0=2.
357 357 # amplitude0=midamp
358 358 # state0=[shift0,width0,amplitude0,power0,wnoise]
359 359 # #bnds=((0,63),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
360 360 # bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
361 361 # #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(0.1,0.5))
362 362 # # bnds = range of fft, power width, amplitude, power, noise
363 363 # lsq1=fmin_l_bfgs_b(self.misfit1,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
364 364 #
365 365 # chiSq1=lsq1[1];
366 366 # jack1= self.y_jacobian1(x,lsq1[0])
367 367 #
368 368 #
369 369 # try:
370 370 # sigmas1=numpy.sqrt(chiSq1*numpy.diag(numpy.linalg.inv(numpy.dot(jack1.T,jack1))))
371 371 # except:
372 372 # std1=32.; sigmas1=numpy.ones(5)
373 373 # else:
374 374 # std1=sigmas1[0]
375 375 #
376 376 #
377 377 # if fatspectra<1.0 and powerwidth<4:
378 378 # choice=0
379 379 # Amplitude0=lsq1[0][2]
380 380 # shift0=lsq1[0][0]
381 381 # width0=lsq1[0][1]
382 382 # p0=lsq1[0][3]
383 383 # Amplitude1=0.
384 384 # shift1=0.
385 385 # width1=0.
386 386 # p1=0.
387 387 # noise=lsq1[0][4]
388 388 # #return (numpy.array([shift0,width0,Amplitude0,p0]),
389 389 # # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
390 390 #
391 391 # # two gaussians
392 392 # #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
393 393 # shift0=numpy.mod(firstpeak+minx, self.Num_Bin );
394 394 # shift1=numpy.mod(secondpeak+minx, self.Num_Bin )
395 395 # width0=powerwidth/6.;
396 396 # width1=width0
397 397 # power0=2.;
398 398 # power1=power0
399 399 # amplitude0=firstamp;
400 400 # amplitude1=secondamp
401 401 # state0=[shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
402 402 # #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
403 403 # 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))
404 404 # #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))
405 405 #
406 406 # lsq2=fmin_l_bfgs_b(self.misfit2,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
407 407 #
408 408 #
409 409 # chiSq2=lsq2[1]; jack2=self.y_jacobian2(x,lsq2[0])
410 410 #
411 411 #
412 412 # try:
413 413 # sigmas2=numpy.sqrt(chiSq2*numpy.diag(numpy.linalg.inv(numpy.dot(jack2.T,jack2))))
414 414 # except:
415 415 # std2a=32.; std2b=32.; sigmas2=numpy.ones(9)
416 416 # else:
417 417 # std2a=sigmas2[0]; std2b=sigmas2[4]
418 418 #
419 419 #
420 420 #
421 421 # 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)
422 422 #
423 423 # if snrdB>-9: # when SNR is strong pick the peak with least shift (LOS velocity) error
424 424 # if oneG:
425 425 # choice=0
426 426 # else:
427 427 # w1=lsq2[0][1]; w2=lsq2[0][5]
428 428 # a1=lsq2[0][2]; a2=lsq2[0][6]
429 429 # p1=lsq2[0][3]; p2=lsq2[0][7]
430 430 # s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1; s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2;
431 431 # gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling
432 432 #
433 433 # if gp1>gp2:
434 434 # if a1>0.7*a2:
435 435 # choice=1
436 436 # else:
437 437 # choice=2
438 438 # elif gp2>gp1:
439 439 # if a2>0.7*a1:
440 440 # choice=2
441 441 # else:
442 442 # choice=1
443 443 # else:
444 444 # choice=numpy.argmax([a1,a2])+1
445 445 # #else:
446 446 # #choice=argmin([std2a,std2b])+1
447 447 #
448 448 # else: # with low SNR go to the most energetic peak
449 449 # choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
450 450 #
451 451 # #print 'choice',choice
452 452 #
453 453 # if choice==0: # pick the single gaussian fit
454 454 # Amplitude0=lsq1[0][2]
455 455 # shift0=lsq1[0][0]
456 456 # width0=lsq1[0][1]
457 457 # p0=lsq1[0][3]
458 458 # Amplitude1=0.
459 459 # shift1=0.
460 460 # width1=0.
461 461 # p1=0.
462 462 # noise=lsq1[0][4]
463 463 # elif choice==1: # take the first one of the 2 gaussians fitted
464 464 # Amplitude0 = lsq2[0][2]
465 465 # shift0 = lsq2[0][0]
466 466 # width0 = lsq2[0][1]
467 467 # p0 = lsq2[0][3]
468 468 # Amplitude1 = lsq2[0][6] # This is 0 in gg1
469 469 # shift1 = lsq2[0][4] # This is 0 in gg1
470 470 # width1 = lsq2[0][5] # This is 0 in gg1
471 471 # p1 = lsq2[0][7] # This is 0 in gg1
472 472 # noise = lsq2[0][8]
473 473 # else: # the second one
474 474 # Amplitude0 = lsq2[0][6]
475 475 # shift0 = lsq2[0][4]
476 476 # width0 = lsq2[0][5]
477 477 # p0 = lsq2[0][7]
478 478 # Amplitude1 = lsq2[0][2] # This is 0 in gg1
479 479 # shift1 = lsq2[0][0] # This is 0 in gg1
480 480 # width1 = lsq2[0][1] # This is 0 in gg1
481 481 # p1 = lsq2[0][3] # This is 0 in gg1
482 482 # noise = lsq2[0][8]
483 483 #
484 484 # #print len(noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0)
485 485 # SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0
486 486 # SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1
487 487 # #print 'SPC_ch1.shape',SPC_ch1.shape
488 488 # #print 'SPC_ch2.shape',SPC_ch2.shape
489 489 # #dataOut.data_param = SPC_ch1
490 490 # GauSPC[0] = SPC_ch1
491 491 # GauSPC[1] = SPC_ch2
492 492
493 493 # #plt.gcf().clear()
494 494 # plt.figure(50+self.i)
495 495 # self.i=self.i+1
496 496 # #plt.subplot(121)
497 497 # plt.plot(self.spc,'k')#,label='spc(66)')
498 498 # plt.plot(SPC_ch1[ch,ht],'b')#,label='gg1')
499 499 # #plt.plot(SPC_ch2,'r')#,label='gg2')
500 500 # #plt.plot(xFrec,ySamples[1],'g',label='Ch1')
501 501 # #plt.plot(xFrec,ySamples[2],'r',label='Ch2')
502 502 # #plt.plot(xFrec,FitGauss,'yo:',label='fit')
503 503 # plt.legend()
504 504 # plt.title('DATOS A ALTURA DE 7500 METROS')
505 505 # plt.show()
506 506 # print 'shift0', shift0
507 507 # print 'Amplitude0', Amplitude0
508 508 # print 'width0', width0
509 509 # print 'p0', p0
510 510 # print '========================'
511 511 # print 'shift1', shift1
512 512 # print 'Amplitude1', Amplitude1
513 513 # print 'width1', width1
514 514 # print 'p1', p1
515 515 # print 'noise', noise
516 516 # print 's_noise', wnoise
517 517
518 518 print '========================================================'
519 519 print 'total_time: ', time.time()-start_time
520 520
521 521 # re-normalizing spc and noise
522 522 # This part differs from gg1
523 523
524 524
525 525
526 526 ''' Parameters:
527 527 1. Amplitude
528 528 2. Shift
529 529 3. Width
530 530 4. Power
531 531 '''
532 532
533 533
534 534 ###############################################################################
535 535 def FitGau(self, X):
536 536
537 537 Vrange, ch, pnoise, noise_, num_intg, SNRlimit = X
538 538 #print 'VARSSSS', ch, pnoise, noise, num_intg
539 539
540 540 #print 'HEIGHTS', self.Num_Hei
541 541
542 542 GauSPC = []
543 543 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
544 544 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
545 545 SPC_ch1[:] = 0#numpy.NaN
546 546 SPC_ch2[:] = 0#numpy.NaN
547 547
548 548
549 549
550 550 for ht in range(self.Num_Hei):
551 551 #print (numpy.asarray(self.spc).shape)
552 552
553 553 #print 'TTTTT', ch , ht
554 554 #print self.spc.shape
555 555
556 556
557 557 spc = numpy.asarray(self.spc)[ch,:,ht]
558 558
559 559 #############################################
560 560 # normalizing spc and noise
561 561 # This part differs from gg1
562 562 spc_norm_max = max(spc)
563 563 spc = spc / spc_norm_max
564 564 pnoise = pnoise / spc_norm_max
565 565 #############################################
566 566
567 567 fatspectra=1.0
568 568
569 569 wnoise = noise_ / spc_norm_max
570 570 #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
571 571 #if wnoise>1.1*pnoise: # to be tested later
572 572 # wnoise=pnoise
573 573 noisebl=wnoise*0.9; noisebh=wnoise*1.1
574 574 spc=spc-wnoise
575 575 # print 'wnoise', noise_[0], spc_norm_max, wnoise
576 576 minx=numpy.argmin(spc)
577 577 spcs=numpy.roll(spc,-minx)
578 578 cum=numpy.cumsum(spcs)
579 579 tot_noise=wnoise * self.Num_Bin #64;
580 580 #print 'spc' , spcs[5:8] , 'tot_noise', tot_noise
581 581 #tot_signal=sum(cum[-5:])/5.; ''' How does this line work? '''
582 582 #snr=tot_signal/tot_noise
583 583 #snr=cum[-1]/tot_noise
584 584 snr = sum(spcs)/tot_noise
585 585 snrdB=10.*numpy.log10(snr)
586 586
587 587 if snrdB < SNRlimit :
588 588 snr = numpy.NaN
589 589 SPC_ch1[:,ht] = 0#numpy.NaN
590 590 SPC_ch1[:,ht] = 0#numpy.NaN
591 591 GauSPC = (SPC_ch1,SPC_ch2)
592 592 continue
593 593 #print 'snr',snrdB #, sum(spcs) , tot_noise
594 594
595 595
596 596
597 597 #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
598 598 # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
599 599
600 600 cummax=max(cum); epsi=0.08*fatspectra # cumsum to narrow down the energy region
601 601 cumlo=cummax*epsi;
602 602 cumhi=cummax*(1-epsi)
603 603 powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
604 604
605 605
606 606 if len(powerindex) < 1:# case for powerindex 0
607 607 continue
608 608 powerlo=powerindex[0]
609 609 powerhi=powerindex[-1]
610 610 powerwidth=powerhi-powerlo
611 611
612 612 firstpeak=powerlo+powerwidth/10.# first gaussian energy location
613 613 secondpeak=powerhi-powerwidth/10.#second gaussian energy location
614 614 midpeak=(firstpeak+secondpeak)/2.
615 615 firstamp=spcs[int(firstpeak)]
616 616 secondamp=spcs[int(secondpeak)]
617 617 midamp=spcs[int(midpeak)]
618 618
619 619 x=numpy.arange( self.Num_Bin )
620 620 y_data=spc+wnoise
621 621
622 622 # single gaussian
623 623 shift0=numpy.mod(midpeak+minx, self.Num_Bin )
624 624 width0=powerwidth/4.#Initialization entire power of spectrum divided by 4
625 625 power0=2.
626 626 amplitude0=midamp
627 627 state0=[shift0,width0,amplitude0,power0,wnoise]
628 628 bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
629 629 lsq1=fmin_l_bfgs_b(self.misfit1,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
630 630
631 631 chiSq1=lsq1[1];
632 632 jack1= self.y_jacobian1(x,lsq1[0])
633 633
634 634
635 635 try:
636 636 sigmas1=numpy.sqrt(chiSq1*numpy.diag(numpy.linalg.inv(numpy.dot(jack1.T,jack1))))
637 637 except:
638 638 std1=32.; sigmas1=numpy.ones(5)
639 639 else:
640 640 std1=sigmas1[0]
641 641
642 642
643 643 if fatspectra<1.0 and powerwidth<4:
644 644 choice=0
645 645 Amplitude0=lsq1[0][2]
646 646 shift0=lsq1[0][0]
647 647 width0=lsq1[0][1]
648 648 p0=lsq1[0][3]
649 649 Amplitude1=0.
650 650 shift1=0.
651 651 width1=0.
652 652 p1=0.
653 653 noise=lsq1[0][4]
654 654 #return (numpy.array([shift0,width0,Amplitude0,p0]),
655 655 # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
656 656
657 657 # two gaussians
658 658 #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
659 659 shift0=numpy.mod(firstpeak+minx, self.Num_Bin );
660 660 shift1=numpy.mod(secondpeak+minx, self.Num_Bin )
661 661 width0=powerwidth/6.;
662 662 width1=width0
663 663 power0=2.;
664 664 power1=power0
665 665 amplitude0=firstamp;
666 666 amplitude1=secondamp
667 667 state0=[shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
668 668 #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
669 669 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))
670 670 #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))
671 671
672 672 lsq2=fmin_l_bfgs_b(self.misfit2,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
673 673
674 674
675 675 chiSq2=lsq2[1]; jack2=self.y_jacobian2(x,lsq2[0])
676 676
677 677
678 678 try:
679 679 sigmas2=numpy.sqrt(chiSq2*numpy.diag(numpy.linalg.inv(numpy.dot(jack2.T,jack2))))
680 680 except:
681 681 std2a=32.; std2b=32.; sigmas2=numpy.ones(9)
682 682 else:
683 683 std2a=sigmas2[0]; std2b=sigmas2[4]
684 684
685 685
686 686
687 687 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)
688 688
689 689 if snrdB>-6: # when SNR is strong pick the peak with least shift (LOS velocity) error
690 690 if oneG:
691 691 choice=0
692 692 else:
693 693 w1=lsq2[0][1]; w2=lsq2[0][5]
694 694 a1=lsq2[0][2]; a2=lsq2[0][6]
695 695 p1=lsq2[0][3]; p2=lsq2[0][7]
696 696 s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1;
697 697 s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2;
698 698 gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling
699 699
700 700 if gp1>gp2:
701 701 if a1>0.7*a2:
702 702 choice=1
703 703 else:
704 704 choice=2
705 705 elif gp2>gp1:
706 706 if a2>0.7*a1:
707 707 choice=2
708 708 else:
709 709 choice=1
710 710 else:
711 711 choice=numpy.argmax([a1,a2])+1
712 712 #else:
713 713 #choice=argmin([std2a,std2b])+1
714 714
715 715 else: # with low SNR go to the most energetic peak
716 716 choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
717 717
718 718
719 719 shift0=lsq2[0][0]; vel0=Vrange[0] + shift0*(Vrange[1]-Vrange[0])
720 720 shift1=lsq2[0][4]; vel1=Vrange[0] + shift1*(Vrange[1]-Vrange[0])
721 721
722 722 max_vel = 20
723 723
724 724 #first peak will be 0, second peak will be 1
725 725 if vel0 > 0 and vel0 < max_vel : #first peak is in the correct range
726 726 shift0=lsq2[0][0]
727 727 width0=lsq2[0][1]
728 728 Amplitude0=lsq2[0][2]
729 729 p0=lsq2[0][3]
730 730
731 731 shift1=lsq2[0][4]
732 732 width1=lsq2[0][5]
733 733 Amplitude1=lsq2[0][6]
734 734 p1=lsq2[0][7]
735 735 noise=lsq2[0][8]
736 736 else:
737 737 shift1=lsq2[0][0]
738 738 width1=lsq2[0][1]
739 739 Amplitude1=lsq2[0][2]
740 740 p1=lsq2[0][3]
741 741
742 742 shift0=lsq2[0][4]
743 743 width0=lsq2[0][5]
744 744 Amplitude0=lsq2[0][6]
745 745 p0=lsq2[0][7]
746 746 noise=lsq2[0][8]
747 747
748 748 if Amplitude0<0.1: # in case the peak is noise
749 749 shift0,width0,Amplitude0,p0 = 4*[numpy.NaN]
750 750 if Amplitude1<0.1:
751 751 shift1,width1,Amplitude1,p1 = 4*[numpy.NaN]
752 752
753 753
754 754 # if choice==0: # pick the single gaussian fit
755 755 # Amplitude0=lsq1[0][2]
756 756 # shift0=lsq1[0][0]
757 757 # width0=lsq1[0][1]
758 758 # p0=lsq1[0][3]
759 759 # Amplitude1=0.
760 760 # shift1=0.
761 761 # width1=0.
762 762 # p1=0.
763 763 # noise=lsq1[0][4]
764 764 # elif choice==1: # take the first one of the 2 gaussians fitted
765 765 # Amplitude0 = lsq2[0][2]
766 766 # shift0 = lsq2[0][0]
767 767 # width0 = lsq2[0][1]
768 768 # p0 = lsq2[0][3]
769 769 # Amplitude1 = lsq2[0][6] # This is 0 in gg1
770 770 # shift1 = lsq2[0][4] # This is 0 in gg1
771 771 # width1 = lsq2[0][5] # This is 0 in gg1
772 772 # p1 = lsq2[0][7] # This is 0 in gg1
773 773 # noise = lsq2[0][8]
774 774 # else: # the second one
775 775 # Amplitude0 = lsq2[0][6]
776 776 # shift0 = lsq2[0][4]
777 777 # width0 = lsq2[0][5]
778 778 # p0 = lsq2[0][7]
779 779 # Amplitude1 = lsq2[0][2] # This is 0 in gg1
780 780 # shift1 = lsq2[0][0] # This is 0 in gg1
781 781 # width1 = lsq2[0][1] # This is 0 in gg1
782 782 # p1 = lsq2[0][3] # This is 0 in gg1
783 783 # noise = lsq2[0][8]
784 784
785 785 #print len(noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0)
786 786 SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0
787 787 SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1
788 788 #print 'SPC_ch1.shape',SPC_ch1.shape
789 789 #print 'SPC_ch2.shape',SPC_ch2.shape
790 790 #dataOut.data_param = SPC_ch1
791 791 GauSPC = (SPC_ch1,SPC_ch2)
792 792 #GauSPC[1] = SPC_ch2
793 793
794 794 # print 'shift0', shift0
795 795 # print 'Amplitude0', Amplitude0
796 796 # print 'width0', width0
797 797 # print 'p0', p0
798 798 # print '========================'
799 799 # print 'shift1', shift1
800 800 # print 'Amplitude1', Amplitude1
801 801 # print 'width1', width1
802 802 # print 'p1', p1
803 803 # print 'noise', noise
804 804 # print 's_noise', wnoise
805 805
806 806 return GauSPC
807 807
808 808
809 809 def y_jacobian1(self,x,state): # This function is for further analysis of generalized Gaussians, it is not too importan for the signal discrimination.
810 810 y_model=self.y_model1(x,state)
811 811 s0,w0,a0,p0,n=state
812 812 e0=((x-s0)/w0)**2;
813 813
814 814 e0u=((x-s0-self.Num_Bin)/w0)**2;
815 815
816 816 e0d=((x-s0+self.Num_Bin)/w0)**2
817 817 m0=numpy.exp(-0.5*e0**(p0/2.));
818 818 m0u=numpy.exp(-0.5*e0u**(p0/2.));
819 819 m0d=numpy.exp(-0.5*e0d**(p0/2.))
820 820 JA=m0+m0u+m0d
821 821 JP=(-1/4.)*a0*m0*e0**(p0/2.)*numpy.log(e0)+(-1/4.)*a0*m0u*e0u**(p0/2.)*numpy.log(e0u)+(-1/4.)*a0*m0d*e0d**(p0/2.)*numpy.log(e0d)
822 822
823 823 JS=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)
824 824
825 825 JW=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)**2+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)**2+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)**2
826 826 jack1=numpy.sqrt(7)*numpy.array([JS/y_model,JW/y_model,JA/y_model,JP/y_model,1./y_model])
827 827 return jack1.T
828 828
829 829 def y_jacobian2(self,x,state):
830 830 y_model=self.y_model2(x,state)
831 831 s0,w0,a0,p0,s1,w1,a1,p1,n=state
832 832 e0=((x-s0)/w0)**2;
833 833
834 834 e0u=((x-s0- self.Num_Bin )/w0)**2;
835 835
836 836 e0d=((x-s0+ self.Num_Bin )/w0)**2
837 837 e1=((x-s1)/w1)**2;
838 838
839 839 e1u=((x-s1- self.Num_Bin )/w1)**2;
840 840
841 841 e1d=((x-s1+ self.Num_Bin )/w1)**2
842 842 m0=numpy.exp(-0.5*e0**(p0/2.));
843 843 m0u=numpy.exp(-0.5*e0u**(p0/2.));
844 844 m0d=numpy.exp(-0.5*e0d**(p0/2.))
845 845 m1=numpy.exp(-0.5*e1**(p1/2.));
846 846 m1u=numpy.exp(-0.5*e1u**(p1/2.));
847 847 m1d=numpy.exp(-0.5*e1d**(p1/2.))
848 848 JA=m0+m0u+m0d
849 849 JA1=m1+m1u+m1d
850 850 JP=(-1/4.)*a0*m0*e0**(p0/2.)*numpy.log(e0)+(-1/4.)*a0*m0u*e0u**(p0/2.)*numpy.log(e0u)+(-1/4.)*a0*m0d*e0d**(p0/2.)*numpy.log(e0d)
851 851 JP1=(-1/4.)*a1*m1*e1**(p1/2.)*numpy.log(e1)+(-1/4.)*a1*m1u*e1u**(p1/2.)*numpy.log(e1u)+(-1/4.)*a1*m1d*e1d**(p1/2.)*numpy.log(e1d)
852 852
853 853 JS=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)
854 854
855 855 JS1=(p1/w1/2.)*a1*m1*e1**(p1/2.-1)*((x-s1)/w1)+(p1/w1/2.)*a1*m1u*e1u**(p1/2.-1)*((x-s1- self.Num_Bin )/w1)+(p1/w1/2.)*a1*m1d*e1d**(p1/2.-1)*((x-s1+ self.Num_Bin )/w1)
856 856
857 857 JW=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)**2+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)**2+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)**2
858 858
859 859 JW1=(p1/w1/2.)*a1*m1*e1**(p1/2.-1)*((x-s1)/w1)**2+(p1/w1/2.)*a1*m1u*e1u**(p1/2.-1)*((x-s1- self.Num_Bin )/w1)**2+(p1/w1/2.)*a1*m1d*e1d**(p1/2.-1)*((x-s1+ self.Num_Bin )/w1)**2
860 860 jack2=numpy.sqrt(7)*numpy.array([JS/y_model,JW/y_model,JA/y_model,JP/y_model,JS1/y_model,JW1/y_model,JA1/y_model,JP1/y_model,1./y_model])
861 861 return jack2.T
862 862
863 863 def y_model1(self,x,state):
864 864 shift0,width0,amplitude0,power0,noise=state
865 865 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
866 866
867 867 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
868 868
869 869 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
870 870 return model0+model0u+model0d+noise
871 871
872 872 def y_model2(self,x,state): #Equation for two generalized Gaussians with Nyquist
873 873 shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,noise=state
874 874 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
875 875
876 876 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
877 877
878 878 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
879 879 model1=amplitude1*numpy.exp(-0.5*abs((x-shift1)/width1)**power1)
880 880
881 881 model1u=amplitude1*numpy.exp(-0.5*abs((x-shift1- self.Num_Bin )/width1)**power1)
882 882
883 883 model1d=amplitude1*numpy.exp(-0.5*abs((x-shift1+ self.Num_Bin )/width1)**power1)
884 884 return model0+model0u+model0d+model1+model1u+model1d+noise
885 885
886 886 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.
887 887
888 888 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model1(x,state)))**2)#/(64-5.) # /(64-5.) can be commented
889 889
890 890 def misfit2(self,state,y_data,x,num_intg):
891 891 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model2(x,state)))**2)#/(64-9.)
892 892
893 893
894 894 class PrecipitationProc(Operation):
895 895
896 896 '''
897 897 Operator that estimates Reflectivity factor (Z), and estimates rainfall Rate (R)
898 898
899 899 Input:
900 900 self.dataOut.data_pre : SelfSpectra
901 901
902 902 Output:
903 903
904 904 self.dataOut.data_output : Reflectivity factor, rainfall Rate
905 905
906 906
907 907 Parameters affected:
908 908 '''
909 909
910 910
911 911 def run(self, dataOut, radar=None, Pt=None, Gt=None, Gr=None, Lambda=None, aL=None,
912 912 tauW=None, ThetaT=None, ThetaR=None, Km = 0.93, Altitude=None):
913 913
914 914 self.spc = dataOut.data_pre[0].copy()
915 915 self.Num_Hei = self.spc.shape[2]
916 916 self.Num_Bin = self.spc.shape[1]
917 917 self.Num_Chn = self.spc.shape[0]
918 918
919 919 Velrange = dataOut.abscissaList
920 920
921 921 if radar == "MIRA35C" :
922 922
923 923 Ze = self.dBZeMODE2(dataOut)
924 924
925 925 else:
926 926
927 927 self.Pt = Pt
928 928 self.Gt = Gt
929 929 self.Gr = Gr
930 930 self.Lambda = Lambda
931 931 self.aL = aL
932 932 self.tauW = tauW
933 933 self.ThetaT = ThetaT
934 934 self.ThetaR = ThetaR
935 935
936 936 RadarConstant = GetRadarConstant()
937 937 SPCmean = numpy.mean(self.spc,0)
938 938 ETA = numpy.zeros(self.Num_Hei)
939 939 Pr = numpy.sum(SPCmean,0)
940 940
941 941 #for R in range(self.Num_Hei):
942 942 # ETA[R] = RadarConstant * Pr[R] * R**2 #Reflectivity (ETA)
943 943
944 944 D_range = numpy.zeros(self.Num_Hei)
945 945 EqSec = numpy.zeros(self.Num_Hei)
946 946 del_V = numpy.zeros(self.Num_Hei)
947 947
948 948 for R in range(self.Num_Hei):
949 949 ETA[R] = RadarConstant * Pr[R] * R**2 #Reflectivity (ETA)
950 950
951 951 h = R + Altitude #Range from ground to radar pulse altitude
952 952 del_V[R] = 1 + 3.68 * 10**-5 * h + 1.71 * 10**-9 * h**2 #Density change correction for velocity
953 953
954 954 D_range[R] = numpy.log( (9.65 - (Velrange[R]/del_V[R])) / 10.3 ) / -0.6 #Range of Diameter of drops related to velocity
955 955 SIGMA[R] = numpy.pi**5 / Lambda**4 * Km * D_range[R]**6 #Equivalent Section of drops (sigma)
956 956
957 957 N_dist[R] = ETA[R] / SIGMA[R]
958 958
959 959 Ze = (ETA * Lambda**4) / (numpy.pi * Km)
960 960 Z = numpy.sum( N_dist * D_range**6 )
961 961 RR = 6*10**-4*numpy.pi * numpy.sum( D_range**3 * N_dist * Velrange ) #Rainfall rate
962 962
963 963
964 964 RR = (Ze/200)**(1/1.6)
965 965 dBRR = 10*numpy.log10(RR)
966 966
967 967 dBZe = 10*numpy.log10(Ze)
968 968 dataOut.data_output = Ze
969 969 dataOut.data_param = numpy.ones([2,self.Num_Hei])
970 970 dataOut.channelList = [0,1]
971 971 print 'channelList', dataOut.channelList
972 972 dataOut.data_param[0]=dBZe
973 973 dataOut.data_param[1]=dBRR
974 974 print 'RR SHAPE', dBRR.shape
975 975 print 'Ze SHAPE', dBZe.shape
976 976 print 'dataOut.data_param SHAPE', dataOut.data_param.shape
977 977
978 978
979 979 def dBZeMODE2(self, dataOut): # Processing for MIRA35C
980 980
981 981 NPW = dataOut.NPW
982 982 COFA = dataOut.COFA
983 983
984 984 SNR = numpy.array([self.spc[0,:,:] / NPW[0]]) #, self.spc[1,:,:] / NPW[1]])
985 985 RadarConst = dataOut.RadarConst
986 986 #frequency = 34.85*10**9
987 987
988 988 ETA = numpy.zeros(([self.Num_Chn ,self.Num_Hei]))
989 989 data_output = numpy.ones([self.Num_Chn , self.Num_Hei])*numpy.NaN
990 990
991 991 ETA = numpy.sum(SNR,1)
992 992 print 'ETA' , ETA
993 993 ETA = numpy.where(ETA is not 0. , ETA, numpy.NaN)
994 994
995 995 Ze = numpy.ones([self.Num_Chn, self.Num_Hei] )
996 996
997 997 for r in range(self.Num_Hei):
998 998
999 999 Ze[0,r] = ( ETA[0,r] ) * COFA[0,r][0] * RadarConst * ((r/5000.)**2)
1000 1000 #Ze[1,r] = ( ETA[1,r] ) * COFA[1,r][0] * RadarConst * ((r/5000.)**2)
1001 1001
1002 1002 return Ze
1003 1003
1004 1004 def GetRadarConstant(self):
1005 1005
1006 1006 """
1007 1007 Constants:
1008 1008
1009 Pt: Transmission Power dB
1010 Gt: Transmission Gain dB
1011 Gr: Reception Gain dB
1012 Lambda: Wavelenght m
1013 aL: Attenuation loses dB
1014 tauW: Width of transmission pulse s
1015 ThetaT: Transmission antenna bean angle rad
1016 ThetaR: Reception antenna beam angle rad
1009 Pt: Transmission Power dB 5kW
1010 Gt: Transmission Gain dB 24.7 dB
1011 Gr: Reception Gain dB 18.5 dB
1012 Lambda: Wavelenght m 0.6741 m
1013 aL: Attenuation loses dB
1014 tauW: Width of transmission pulse s
1015 ThetaT: Transmission antenna bean angle rad 0.1656317 rad
1016 ThetaR: Reception antenna beam angle rad 0.36774087 rad
1017 1017
1018 1018 """
1019 1019 Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
1020 1020 Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * TauW * numpy.pi * ThetaT * TheraR)
1021 1021 RadarConstant = Numerator / Denominator
1022 1022
1023 1023 return RadarConstant
1024 1024
1025 1025
1026 1026
1027 1027 class FullSpectralAnalysis(Operation):
1028 1028
1029 1029 """
1030 1030 Function that implements Full Spectral Analisys technique.
1031 1031
1032 1032 Input:
1033 1033 self.dataOut.data_pre : SelfSpectra and CrossSPectra data
1034 1034 self.dataOut.groupList : Pairlist of channels
1035 1035 self.dataOut.ChanDist : Physical distance between receivers
1036 1036
1037 1037
1038 1038 Output:
1039 1039
1040 1040 self.dataOut.data_output : Zonal wind, Meridional wind and Vertical wind
1041 1041
1042 1042
1043 1043 Parameters affected: Winds, height range, SNR
1044 1044
1045 1045 """
1046 1046 def run(self, dataOut, E01=None, E02=None, E12=None, N01=None, N02=None, N12=None, SNRlimit=7):
1047 1047
1048 1048 spc = dataOut.data_pre[0].copy()
1049 1049 cspc = dataOut.data_pre[1].copy()
1050 1050
1051 1051 nChannel = spc.shape[0]
1052 1052 nProfiles = spc.shape[1]
1053 1053 nHeights = spc.shape[2]
1054 1054
1055 1055 pairsList = dataOut.groupList
1056 1056 if dataOut.ChanDist is not None :
1057 1057 ChanDist = dataOut.ChanDist
1058 1058 else:
1059 1059 ChanDist = numpy.array([[E01, N01],[E02,N02],[E12,N12]])
1060 1060
1061 1061 #print 'ChanDist', ChanDist
1062 1062
1063 1063 if dataOut.VelRange is not None:
1064 1064 VelRange= dataOut.VelRange
1065 1065 else:
1066 1066 VelRange= dataOut.abscissaList
1067 1067
1068 1068 ySamples=numpy.ones([nChannel,nProfiles])
1069 1069 phase=numpy.ones([nChannel,nProfiles])
1070 1070 CSPCSamples=numpy.ones([nChannel,nProfiles],dtype=numpy.complex_)
1071 1071 coherence=numpy.ones([nChannel,nProfiles])
1072 1072 PhaseSlope=numpy.ones(nChannel)
1073 1073 PhaseInter=numpy.ones(nChannel)
1074 1074 dataSNR = dataOut.data_SNR
1075 1075
1076 1076
1077 1077
1078 1078 data = dataOut.data_pre
1079 1079 noise = dataOut.noise
1080 print 'noise',noise
1080 #print 'noise',noise
1081 1081 #SNRdB = 10*numpy.log10(dataOut.data_SNR)
1082 1082
1083 1083 FirstMoment = numpy.average(dataOut.data_param[:,1,:],0)
1084 1084 #SNRdBMean = []
1085 1085
1086 1086
1087 1087 #for j in range(nHeights):
1088 1088 # FirstMoment = numpy.append(FirstMoment,numpy.mean([dataOut.data_param[0,1,j],dataOut.data_param[1,1,j],dataOut.data_param[2,1,j]]))
1089 1089 # SNRdBMean = numpy.append(SNRdBMean,numpy.mean([SNRdB[0,j],SNRdB[1,j],SNRdB[2,j]]))
1090 1090
1091 1091 data_output=numpy.ones([3,spc.shape[2]])*numpy.NaN
1092 1092
1093 1093 velocityX=[]
1094 1094 velocityY=[]
1095 1095 velocityV=[]
1096 PhaseLine=[]
1096 1097
1097 1098 dbSNR = 10*numpy.log10(dataSNR)
1098 1099 dbSNR = numpy.average(dbSNR,0)
1099 1100 for Height in range(nHeights):
1100 1101
1101 [Vzon,Vmer,Vver, GaussCenter]= self.WindEstimation(spc, cspc, pairsList, ChanDist, Height, noise, VelRange, dbSNR[Height], SNRlimit)
1102 [Vzon,Vmer,Vver, GaussCenter, PhaseSlope]= self.WindEstimation(spc, cspc, pairsList, ChanDist, Height, noise, VelRange, dbSNR[Height], SNRlimit)
1103
1104 PhaseLine = numpy.append(PhaseLine, PhaseSlope)
1102 1105
1103 1106 if abs(Vzon)<100. and abs(Vzon)> 0.:
1104 1107 velocityX=numpy.append(velocityX, Vzon)#Vmag
1105 1108
1106 1109 else:
1107 print 'Vzon',Vzon
1110 #print 'Vzon',Vzon
1108 1111 velocityX=numpy.append(velocityX, numpy.NaN)
1109 1112
1110 1113 if abs(Vmer)<100. and abs(Vmer) > 0.:
1111 1114 velocityY=numpy.append(velocityY, Vmer)#Vang
1112 1115
1113 1116 else:
1114 print 'Vmer',Vmer
1117 #print 'Vmer',Vmer
1115 1118 velocityY=numpy.append(velocityY, numpy.NaN)
1116 1119
1117 1120 if dbSNR[Height] > SNRlimit:
1118 1121 velocityV=numpy.append(velocityV, FirstMoment[Height])
1119 1122 else:
1120 1123 velocityV=numpy.append(velocityV, numpy.NaN)
1121 1124 #FirstMoment[Height]= numpy.NaN
1122 1125 # if SNRdBMean[Height] <12:
1123 1126 # FirstMoment[Height] = numpy.NaN
1124 1127 # velocityX[Height] = numpy.NaN
1125 1128 # velocityY[Height] = numpy.NaN
1126
1129
1130
1127 1131
1128 1132 data_output[0]=numpy.array(velocityX)
1129 1133 data_output[1]=numpy.array(velocityY)
1130 1134 data_output[2]=-velocityV#FirstMoment
1131 1135
1132 1136 print ' '
1133 1137 #print 'FirstMoment'
1134 1138 #print FirstMoment
1135 1139 print 'velocityX',data_output[0]
1136 1140 print ' '
1137 1141 print 'velocityY',data_output[1]
1142 print 'PhaseLine',PhaseLine
1138 1143 #print numpy.array(velocityY)
1139 1144 print ' '
1140 1145 #print 'SNR'
1141 1146 #print 10*numpy.log10(dataOut.data_SNR)
1142 1147 #print numpy.shape(10*numpy.log10(dataOut.data_SNR))
1143 1148 print ' '
1144 1149
1145 1150
1146 1151 dataOut.data_output=data_output
1152
1147 1153 return
1148 1154
1149 1155
1150 1156 def moving_average(self,x, N=2):
1151 1157 return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):]
1152 1158
1153 1159 def gaus(self,xSamples,a,x0,sigma):
1154 1160 return a*numpy.exp(-(xSamples-x0)**2/(2*sigma**2))
1155 1161
1156 1162 def Find(self,x,value):
1157 1163 for index in range(len(x)):
1158 1164 if x[index]==value:
1159 1165 return index
1160 1166
1161 1167 def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, VelRange, dbSNR, SNRlimit):
1162 1168
1163 1169 ySamples=numpy.ones([spc.shape[0],spc.shape[1]])
1164 1170 phase=numpy.ones([spc.shape[0],spc.shape[1]])
1165 1171 CSPCSamples=numpy.ones([spc.shape[0],spc.shape[1]],dtype=numpy.complex_)
1166 1172 coherence=numpy.ones([spc.shape[0],spc.shape[1]])
1167 PhaseSlope=numpy.ones(spc.shape[0])
1173 PhaseSlope=numpy.zeros(spc.shape[0])
1168 1174 PhaseInter=numpy.ones(spc.shape[0])
1169 1175 xFrec=VelRange
1170 1176
1171 1177 '''Getting Eij and Nij'''
1172 1178
1173 1179 E01=ChanDist[0][0]
1174 1180 N01=ChanDist[0][1]
1175 1181
1176 1182 E02=ChanDist[1][0]
1177 1183 N02=ChanDist[1][1]
1178 1184
1179 1185 E12=ChanDist[2][0]
1180 1186 N12=ChanDist[2][1]
1181 1187
1182 1188 z = spc.copy()
1183 1189 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1184 1190
1185 1191 for i in range(spc.shape[0]):
1186 1192
1187 1193 '''****** Line of Data SPC ******'''
1188 1194 zline=z[i,:,Height]
1189 1195
1190 1196 '''****** SPC is normalized ******'''
1191 1197 FactNorm= (zline.copy()-noise[i]) / numpy.sum(zline.copy())
1192 1198 FactNorm= FactNorm/numpy.sum(FactNorm)
1193 1199
1194 1200 SmoothSPC=self.moving_average(FactNorm,N=3)
1195 1201
1196 1202 xSamples = ar(range(len(SmoothSPC)))
1197 1203 ySamples[i] = SmoothSPC
1198 1204
1199 1205 #dbSNR=10*numpy.log10(dataSNR)
1200 1206 print ' '
1201 1207 print ' '
1202 1208 print ' '
1203 1209
1204 1210 #print 'dataSNR', dbSNR.shape, dbSNR[0,40:120]
1205 print 'SmoothSPC', SmoothSPC.shape, SmoothSPC[0:20]
1206 print 'noise',noise
1207 print 'zline',zline.shape, zline[0:20]
1208 print 'FactNorm',FactNorm.shape, FactNorm[0:20]
1209 print 'FactNorm suma', numpy.sum(FactNorm)
1211 #print 'SmoothSPC', SmoothSPC.shape, SmoothSPC[0:20]
1212 #print 'noise',noise
1213 #print 'zline',zline.shape, zline[0:20]
1214 #print 'FactNorm',FactNorm.shape, FactNorm[0:20]
1215 #print 'FactNorm suma', numpy.sum(FactNorm)
1210 1216
1211 1217 for i in range(spc.shape[0]):
1212 1218
1213 1219 '''****** Line of Data CSPC ******'''
1214 1220 cspcLine=cspc[i,:,Height].copy()
1215 1221
1216 1222 '''****** CSPC is normalized ******'''
1217 1223 chan_index0 = pairsList[i][0]
1218 1224 chan_index1 = pairsList[i][1]
1219 1225 CSPCFactor= abs(numpy.sum(ySamples[chan_index0]) * numpy.sum(ySamples[chan_index1])) #
1220 1226
1221 1227 CSPCNorm = (cspcLine.copy() -noise[i]) / numpy.sqrt(CSPCFactor)
1222 1228
1223 1229 CSPCSamples[i] = CSPCNorm
1224 1230 coherence[i] = numpy.abs(CSPCSamples[i]) / numpy.sqrt(CSPCFactor)
1225 1231
1226 1232 coherence[i]= self.moving_average(coherence[i],N=2)
1227 1233
1228 1234 phase[i] = self.moving_average( numpy.arctan2(CSPCSamples[i].imag, CSPCSamples[i].real),N=1)#*180/numpy.pi
1229 1235
1230 print 'cspcLine', cspcLine.shape, cspcLine[0:20]
1231 print 'CSPCFactor', CSPCFactor#, CSPCFactor[0:20]
1232 print numpy.sum(ySamples[chan_index0]), numpy.sum(ySamples[chan_index1]), -noise[i]
1233 print 'CSPCNorm', CSPCNorm.shape, CSPCNorm[0:20]
1234 print 'CSPCNorm suma', numpy.sum(CSPCNorm)
1235 print 'CSPCSamples', CSPCSamples.shape, CSPCSamples[0,0:20]
1236 #print 'cspcLine', cspcLine.shape, cspcLine[0:20]
1237 #print 'CSPCFactor', CSPCFactor#, CSPCFactor[0:20]
1238 #print numpy.sum(ySamples[chan_index0]), numpy.sum(ySamples[chan_index1]), -noise[i]
1239 #print 'CSPCNorm', CSPCNorm.shape, CSPCNorm[0:20]
1240 #print 'CSPCNorm suma', numpy.sum(CSPCNorm)
1241 #print 'CSPCSamples', CSPCSamples.shape, CSPCSamples[0,0:20]
1236 1242
1237 1243 '''****** Getting fij width ******'''
1238 1244
1239 1245 yMean=[]
1240 1246 yMean2=[]
1241 1247
1242 1248 for j in range(len(ySamples[1])):
1243 1249 yMean=numpy.append(yMean,numpy.mean([ySamples[0,j],ySamples[1,j],ySamples[2,j]]))
1244 1250
1245 1251 '''******* Getting fitting Gaussian ******'''
1246 1252 meanGauss=sum(xSamples*yMean) / len(xSamples)
1247 1253 sigma=sum(yMean*(xSamples-meanGauss)**2) / len(xSamples)
1248 1254
1249 print '****************************'
1250 print 'len(xSamples): ',len(xSamples)
1251 print 'yMean: ', yMean.shape, yMean[0:20]
1252 print 'ySamples', ySamples.shape, ySamples[0,0:20]
1253 print 'xSamples: ',xSamples.shape, xSamples[0:20]
1255 #print '****************************'
1256 #print 'len(xSamples): ',len(xSamples)
1257 #print 'yMean: ', yMean.shape, yMean[0:20]
1258 #print 'ySamples', ySamples.shape, ySamples[0,0:20]
1259 #print 'xSamples: ',xSamples.shape, xSamples[0:20]
1254 1260
1255 print 'meanGauss',meanGauss
1256 print 'sigma',sigma
1261 #print 'meanGauss',meanGauss
1262 #print 'sigma',sigma
1257 1263
1258 1264 #if (abs(meanGauss/sigma**2) > 0.0001) : #0.000000001):
1259 if dbSNR > SNRlimit :
1265 if dbSNR > SNRlimit and abs(meanGauss/sigma**2) > 0.0001:
1260 1266 try:
1261 1267 popt,pcov = curve_fit(self.gaus,xSamples,yMean,p0=[1,meanGauss,sigma])
1262 1268
1263 1269 if numpy.amax(popt)>numpy.amax(yMean)*0.3:
1264 1270 FitGauss=self.gaus(xSamples,*popt)
1265 1271
1266 1272 else:
1267 1273 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1268 1274 print 'Verificador: Dentro', Height
1269 1275 except :#RuntimeError:
1270 1276 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1271 1277
1272 1278
1273 1279 else:
1274 1280 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1275 1281
1276 1282 Maximun=numpy.amax(yMean)
1277 1283 eMinus1=Maximun*numpy.exp(-1)#*0.8
1278 1284
1279 1285 HWpos=self.Find(FitGauss,min(FitGauss, key=lambda value:abs(value-eMinus1)))
1280 1286 HalfWidth= xFrec[HWpos]
1281 1287 GCpos=self.Find(FitGauss, numpy.amax(FitGauss))
1282 1288 Vpos=self.Find(FactNorm, numpy.amax(FactNorm))
1283 1289
1284 1290 #Vpos=FirstMoment[]
1285 1291
1286 1292 '''****** Getting Fij ******'''
1287 1293
1288 1294 GaussCenter=xFrec[GCpos]
1289 1295 if (GaussCenter<0 and HalfWidth>0) or (GaussCenter>0 and HalfWidth<0):
1290 1296 Fij=abs(GaussCenter)+abs(HalfWidth)+0.0000001
1291 1297 else:
1292 1298 Fij=abs(GaussCenter-HalfWidth)+0.0000001
1293 1299
1294 1300 '''****** Getting Frecuency range of significant data ******'''
1295 1301
1296 1302 Rangpos=self.Find(FitGauss,min(FitGauss, key=lambda value:abs(value-Maximun*0.10)))
1297 1303
1298 1304 if Rangpos<GCpos:
1299 1305 Range=numpy.array([Rangpos,2*GCpos-Rangpos])
1300 1306 elif Rangpos< ( len(xFrec)- len(xFrec)*0.1):
1301 1307 Range=numpy.array([2*GCpos-Rangpos,Rangpos])
1302 1308 else:
1303 1309 Range = numpy.array([0,0])
1304 1310
1305 print ' '
1306 print 'GCpos',GCpos, ( len(xFrec)- len(xFrec)*0.1)
1307 print 'Rangpos',Rangpos
1311 #print ' '
1312 #print 'GCpos',GCpos, ( len(xFrec)- len(xFrec)*0.1)
1313 #print 'Rangpos',Rangpos
1308 1314 print 'RANGE: ', Range
1309 1315 FrecRange=xFrec[Range[0]:Range[1]]
1310 1316
1311 1317 '''****** Getting SCPC Slope ******'''
1312 1318
1313 1319 for i in range(spc.shape[0]):
1314 1320
1315 1321 if len(FrecRange)>5 and len(FrecRange)<spc.shape[1]*0.5:
1316 1322 PhaseRange=self.moving_average(phase[i,Range[0]:Range[1]],N=3)
1317 1323
1318 1324 print 'FrecRange', len(FrecRange) , FrecRange
1319 1325 print 'PhaseRange', len(PhaseRange), PhaseRange
1320 1326 print ' '
1321 1327 if len(FrecRange) == len(PhaseRange):
1322 1328 slope, intercept, r_value, p_value, std_err = stats.linregress(FrecRange,PhaseRange)
1323 1329 PhaseSlope[i]=slope
1324 1330 PhaseInter[i]=intercept
1325 1331 else:
1326 1332 PhaseSlope[i]=0
1327 1333 PhaseInter[i]=0
1328 1334 else:
1329 1335 PhaseSlope[i]=0
1330 1336 PhaseInter[i]=0
1331 1337
1332 1338 '''Getting constant C'''
1333 1339 cC=(Fij*numpy.pi)**2
1334 1340
1335 1341 '''****** Getting constants F and G ******'''
1336 1342 MijEijNij=numpy.array([[E02,N02], [E12,N12]])
1337 1343 MijResult0=(-PhaseSlope[1]*cC) / (2*numpy.pi)
1338 1344 MijResult1=(-PhaseSlope[2]*cC) / (2*numpy.pi)
1339 1345 MijResults=numpy.array([MijResult0,MijResult1])
1340 1346 (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults)
1341 1347
1342 1348 '''****** Getting constants A, B and H ******'''
1343 1349 W01=numpy.amax(coherence[0])
1344 1350 W02=numpy.amax(coherence[1])
1345 1351 W12=numpy.amax(coherence[2])
1346 1352
1347 1353 WijResult0=((cF*E01+cG*N01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi/cC))
1348 1354 WijResult1=((cF*E02+cG*N02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi/cC))
1349 1355 WijResult2=((cF*E12+cG*N12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi/cC))
1350 1356
1351 1357 WijResults=numpy.array([WijResult0, WijResult1, WijResult2])
1352 1358
1353 1359 WijEijNij=numpy.array([ [E01**2, N01**2, 2*E01*N01] , [E02**2, N02**2, 2*E02*N02] , [E12**2, N12**2, 2*E12*N12] ])
1354 1360 (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults)
1355 1361
1356 1362 VxVy=numpy.array([[cA,cH],[cH,cB]])
1357 1363
1358 1364 VxVyResults=numpy.array([-cF,-cG])
1359 1365 (Vx,Vy) = numpy.linalg.solve(VxVy, VxVyResults)
1360 1366
1361 1367 Vzon = Vy
1362 1368 Vmer = Vx
1363 1369 Vmag=numpy.sqrt(Vzon**2+Vmer**2)
1364 1370 Vang=numpy.arctan2(Vmer,Vzon)
1365 1371 Vver=xFrec[Vpos]
1372 print 'Height',Height
1366 1373 print 'vzon y vmer', Vzon, Vmer
1367 return Vzon, Vmer, Vver, GaussCenter
1374 return Vzon, Vmer, Vver, GaussCenter, PhaseSlope
1368 1375
1369 1376 class SpectralMoments(Operation):
1370 1377
1371 1378 '''
1372 1379 Function SpectralMoments()
1373 1380
1374 1381 Calculates moments (power, mean, standard deviation) and SNR of the signal
1375 1382
1376 1383 Type of dataIn: Spectra
1377 1384
1378 1385 Configuration Parameters:
1379 1386
1380 1387 dirCosx : Cosine director in X axis
1381 1388 dirCosy : Cosine director in Y axis
1382 1389
1383 1390 elevation :
1384 1391 azimuth :
1385 1392
1386 1393 Input:
1387 1394 channelList : simple channel list to select e.g. [2,3,7]
1388 1395 self.dataOut.data_pre : Spectral data
1389 1396 self.dataOut.abscissaList : List of frequencies
1390 1397 self.dataOut.noise : Noise level per channel
1391 1398
1392 1399 Affected:
1393 1400 self.dataOut.data_param : Parameters per channel
1394 1401 self.dataOut.data_SNR : SNR per channel
1395 1402
1396 1403 '''
1397 1404
1398 1405 def run(self, dataOut):
1399 1406
1400 1407 #dataOut.data_pre = dataOut.data_pre[0]
1401 1408 data = dataOut.data_pre[0]
1402 1409 absc = dataOut.abscissaList[:-1]
1403 1410 noise = dataOut.noise
1404 1411 nChannel = data.shape[0]
1405 1412 data_param = numpy.zeros((nChannel, 4, data.shape[2]))
1406 1413
1407 1414 for ind in range(nChannel):
1408 1415 data_param[ind,:,:] = self.__calculateMoments( data[ind,:,:] , absc , noise[ind] )
1409 1416
1410 1417 dataOut.data_param = data_param[:,1:,:]
1411 1418 dataOut.data_SNR = data_param[:,0]
1412 1419 return
1413 1420
1414 1421 def __calculateMoments(self, oldspec, oldfreq, n0,
1415 1422 nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
1416 1423
1417 1424 if (nicoh == None): nicoh = 1
1418 1425 if (graph == None): graph = 0
1419 1426 if (smooth == None): smooth = 0
1420 1427 elif (self.smooth < 3): smooth = 0
1421 1428
1422 1429 if (type1 == None): type1 = 0
1423 1430 if (fwindow == None): fwindow = numpy.zeros(oldfreq.size) + 1
1424 1431 if (snrth == None): snrth = -3
1425 1432 if (dc == None): dc = 0
1426 1433 if (aliasing == None): aliasing = 0
1427 1434 if (oldfd == None): oldfd = 0
1428 1435 if (wwauto == None): wwauto = 0
1429 1436
1430 1437 if (n0 < 1.e-20): n0 = 1.e-20
1431 1438
1432 1439 freq = oldfreq
1433 1440 vec_power = numpy.zeros(oldspec.shape[1])
1434 1441 vec_fd = numpy.zeros(oldspec.shape[1])
1435 1442 vec_w = numpy.zeros(oldspec.shape[1])
1436 1443 vec_snr = numpy.zeros(oldspec.shape[1])
1437 1444
1438 1445 for ind in range(oldspec.shape[1]):
1439 1446
1440 1447 spec = oldspec[:,ind]
1441 1448 aux = spec*fwindow
1442 1449 max_spec = aux.max()
1443 1450 m = list(aux).index(max_spec)
1444 1451
1445 1452 #Smooth
1446 1453 if (smooth == 0): spec2 = spec
1447 1454 else: spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
1448 1455
1449 1456 # Calculo de Momentos
1450 1457 bb = spec2[range(m,spec2.size)]
1451 1458 bb = (bb<n0).nonzero()
1452 1459 bb = bb[0]
1453 1460
1454 1461 ss = spec2[range(0,m + 1)]
1455 1462 ss = (ss<n0).nonzero()
1456 1463 ss = ss[0]
1457 1464
1458 1465 if (bb.size == 0):
1459 1466 bb0 = spec.size - 1 - m
1460 1467 else:
1461 1468 bb0 = bb[0] - 1
1462 1469 if (bb0 < 0):
1463 1470 bb0 = 0
1464 1471
1465 1472 if (ss.size == 0): ss1 = 1
1466 1473 else: ss1 = max(ss) + 1
1467 1474
1468 1475 if (ss1 > m): ss1 = m
1469 1476
1470 1477 valid = numpy.asarray(range(int(m + bb0 - ss1 + 1))) + ss1
1471 1478 power = ((spec2[valid] - n0)*fwindow[valid]).sum()
1472 1479 fd = ((spec2[valid]- n0)*freq[valid]*fwindow[valid]).sum()/power
1473 1480 w = math.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum()/power)
1474 1481 snr = (spec2.mean()-n0)/n0
1475 1482
1476 1483 if (snr < 1.e-20) :
1477 1484 snr = 1.e-20
1478 1485
1479 1486 vec_power[ind] = power
1480 1487 vec_fd[ind] = fd
1481 1488 vec_w[ind] = w
1482 1489 vec_snr[ind] = snr
1483 1490
1484 1491 moments = numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
1485 1492 return moments
1486 1493
1487 1494 #------------------ Get SA Parameters --------------------------
1488 1495
1489 1496 def GetSAParameters(self):
1490 1497 #SA en frecuencia
1491 1498 pairslist = self.dataOut.groupList
1492 1499 num_pairs = len(pairslist)
1493 1500
1494 1501 vel = self.dataOut.abscissaList
1495 1502 spectra = self.dataOut.data_pre
1496 1503 cspectra = self.dataIn.data_cspc
1497 1504 delta_v = vel[1] - vel[0]
1498 1505
1499 1506 #Calculating the power spectrum
1500 1507 spc_pow = numpy.sum(spectra, 3)*delta_v
1501 1508 #Normalizing Spectra
1502 1509 norm_spectra = spectra/spc_pow
1503 1510 #Calculating the norm_spectra at peak
1504 1511 max_spectra = numpy.max(norm_spectra, 3)
1505 1512
1506 1513 #Normalizing Cross Spectra
1507 1514 norm_cspectra = numpy.zeros(cspectra.shape)
1508 1515
1509 1516 for i in range(num_chan):
1510 1517 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
1511 1518
1512 1519 max_cspectra = numpy.max(norm_cspectra,2)
1513 1520 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
1514 1521
1515 1522 for i in range(num_pairs):
1516 1523 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
1517 1524 #------------------- Get Lags ----------------------------------
1518 1525
1519 1526 class SALags(Operation):
1520 1527 '''
1521 1528 Function GetMoments()
1522 1529
1523 1530 Input:
1524 1531 self.dataOut.data_pre
1525 1532 self.dataOut.abscissaList
1526 1533 self.dataOut.noise
1527 1534 self.dataOut.normFactor
1528 1535 self.dataOut.data_SNR
1529 1536 self.dataOut.groupList
1530 1537 self.dataOut.nChannels
1531 1538
1532 1539 Affected:
1533 1540 self.dataOut.data_param
1534 1541
1535 1542 '''
1536 1543 def run(self, dataOut):
1537 1544 data_acf = dataOut.data_pre[0]
1538 1545 data_ccf = dataOut.data_pre[1]
1539 1546 normFactor_acf = dataOut.normFactor[0]
1540 1547 normFactor_ccf = dataOut.normFactor[1]
1541 1548 pairs_acf = dataOut.groupList[0]
1542 1549 pairs_ccf = dataOut.groupList[1]
1543 1550
1544 1551 nHeights = dataOut.nHeights
1545 1552 absc = dataOut.abscissaList
1546 1553 noise = dataOut.noise
1547 1554 SNR = dataOut.data_SNR
1548 1555 nChannels = dataOut.nChannels
1549 1556 # pairsList = dataOut.groupList
1550 1557 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
1551 1558
1552 1559 for l in range(len(pairs_acf)):
1553 1560 data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
1554 1561
1555 1562 for l in range(len(pairs_ccf)):
1556 1563 data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
1557 1564
1558 1565 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
1559 1566 dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
1560 1567 dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
1561 1568 return
1562 1569
1563 1570 # def __getPairsAutoCorr(self, pairsList, nChannels):
1564 1571 #
1565 1572 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1566 1573 #
1567 1574 # for l in range(len(pairsList)):
1568 1575 # firstChannel = pairsList[l][0]
1569 1576 # secondChannel = pairsList[l][1]
1570 1577 #
1571 1578 # #Obteniendo pares de Autocorrelacion
1572 1579 # if firstChannel == secondChannel:
1573 1580 # pairsAutoCorr[firstChannel] = int(l)
1574 1581 #
1575 1582 # pairsAutoCorr = pairsAutoCorr.astype(int)
1576 1583 #
1577 1584 # pairsCrossCorr = range(len(pairsList))
1578 1585 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1579 1586 #
1580 1587 # return pairsAutoCorr, pairsCrossCorr
1581 1588
1582 1589 def __calculateTaus(self, data_acf, data_ccf, lagRange):
1583 1590
1584 1591 lag0 = data_acf.shape[1]/2
1585 1592 #Funcion de Autocorrelacion
1586 1593 mean_acf = stats.nanmean(data_acf, axis = 0)
1587 1594
1588 1595 #Obtencion Indice de TauCross
1589 1596 ind_ccf = data_ccf.argmax(axis = 1)
1590 1597 #Obtencion Indice de TauAuto
1591 1598 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
1592 1599 ccf_lag0 = data_ccf[:,lag0,:]
1593 1600
1594 1601 for i in range(ccf_lag0.shape[0]):
1595 1602 ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
1596 1603
1597 1604 #Obtencion de TauCross y TauAuto
1598 1605 tau_ccf = lagRange[ind_ccf]
1599 1606 tau_acf = lagRange[ind_acf]
1600 1607
1601 1608 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
1602 1609
1603 1610 tau_ccf[Nan1,Nan2] = numpy.nan
1604 1611 tau_acf[Nan1,Nan2] = numpy.nan
1605 1612 tau = numpy.vstack((tau_ccf,tau_acf))
1606 1613
1607 1614 return tau
1608 1615
1609 1616 def __calculateLag1Phase(self, data, lagTRange):
1610 1617 data1 = stats.nanmean(data, axis = 0)
1611 1618 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
1612 1619
1613 1620 phase = numpy.angle(data1[lag1,:])
1614 1621
1615 1622 return phase
1616 1623
1617 1624 class SpectralFitting(Operation):
1618 1625 '''
1619 1626 Function GetMoments()
1620 1627
1621 1628 Input:
1622 1629 Output:
1623 1630 Variables modified:
1624 1631 '''
1625 1632
1626 1633 def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
1627 1634
1628 1635
1629 1636 if path != None:
1630 1637 sys.path.append(path)
1631 1638 self.dataOut.library = importlib.import_module(file)
1632 1639
1633 1640 #To be inserted as a parameter
1634 1641 groupArray = numpy.array(groupList)
1635 1642 # groupArray = numpy.array([[0,1],[2,3]])
1636 1643 self.dataOut.groupList = groupArray
1637 1644
1638 1645 nGroups = groupArray.shape[0]
1639 1646 nChannels = self.dataIn.nChannels
1640 1647 nHeights=self.dataIn.heightList.size
1641 1648
1642 1649 #Parameters Array
1643 1650 self.dataOut.data_param = None
1644 1651
1645 1652 #Set constants
1646 1653 constants = self.dataOut.library.setConstants(self.dataIn)
1647 1654 self.dataOut.constants = constants
1648 1655 M = self.dataIn.normFactor
1649 1656 N = self.dataIn.nFFTPoints
1650 1657 ippSeconds = self.dataIn.ippSeconds
1651 1658 K = self.dataIn.nIncohInt
1652 1659 pairsArray = numpy.array(self.dataIn.pairsList)
1653 1660
1654 1661 #List of possible combinations
1655 1662 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1656 1663 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1657 1664
1658 1665 if getSNR:
1659 1666 listChannels = groupArray.reshape((groupArray.size))
1660 1667 listChannels.sort()
1661 1668 noise = self.dataIn.getNoise()
1662 1669 self.dataOut.data_SNR = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1663 1670
1664 1671 for i in range(nGroups):
1665 1672 coord = groupArray[i,:]
1666 1673
1667 1674 #Input data array
1668 1675 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1669 1676 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1670 1677
1671 1678 #Cross Spectra data array for Covariance Matrixes
1672 1679 ind = 0
1673 1680 for pairs in listComb:
1674 1681 pairsSel = numpy.array([coord[x],coord[y]])
1675 1682 indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
1676 1683 ind += 1
1677 1684 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1678 1685 dataCross = dataCross**2/K
1679 1686
1680 1687 for h in range(nHeights):
1681 1688 # print self.dataOut.heightList[h]
1682 1689
1683 1690 #Input
1684 1691 d = data[:,h]
1685 1692
1686 1693 #Covariance Matrix
1687 1694 D = numpy.diag(d**2/K)
1688 1695 ind = 0
1689 1696 for pairs in listComb:
1690 1697 #Coordinates in Covariance Matrix
1691 1698 x = pairs[0]
1692 1699 y = pairs[1]
1693 1700 #Channel Index
1694 1701 S12 = dataCross[ind,:,h]
1695 1702 D12 = numpy.diag(S12)
1696 1703 #Completing Covariance Matrix with Cross Spectras
1697 1704 D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
1698 1705 D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
1699 1706 ind += 1
1700 1707 Dinv=numpy.linalg.inv(D)
1701 1708 L=numpy.linalg.cholesky(Dinv)
1702 1709 LT=L.T
1703 1710
1704 1711 dp = numpy.dot(LT,d)
1705 1712
1706 1713 #Initial values
1707 1714 data_spc = self.dataIn.data_spc[coord,:,h]
1708 1715
1709 1716 if (h>0)and(error1[3]<5):
1710 1717 p0 = self.dataOut.data_param[i,:,h-1]
1711 1718 else:
1712 1719 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1713 1720
1714 1721 try:
1715 1722 #Least Squares
1716 1723 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
1717 1724 # minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
1718 1725 #Chi square error
1719 1726 error0 = numpy.sum(infodict['fvec']**2)/(2*N)
1720 1727 #Error with Jacobian
1721 1728 error1 = self.dataOut.library.errorFunction(minp,constants,LT)
1722 1729 except:
1723 1730 minp = p0*numpy.nan
1724 1731 error0 = numpy.nan
1725 1732 error1 = p0*numpy.nan
1726 1733
1727 1734 #Save
1728 1735 if self.dataOut.data_param == None:
1729 1736 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1730 1737 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1731 1738
1732 1739 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1733 1740 self.dataOut.data_param[i,:,h] = minp
1734 1741 return
1735 1742
1736 1743 def __residFunction(self, p, dp, LT, constants):
1737 1744
1738 1745 fm = self.dataOut.library.modelFunction(p, constants)
1739 1746 fmp=numpy.dot(LT,fm)
1740 1747
1741 1748 return dp-fmp
1742 1749
1743 1750 def __getSNR(self, z, noise):
1744 1751
1745 1752 avg = numpy.average(z, axis=1)
1746 1753 SNR = (avg.T-noise)/noise
1747 1754 SNR = SNR.T
1748 1755 return SNR
1749 1756
1750 1757 def __chisq(p,chindex,hindex):
1751 1758 #similar to Resid but calculates CHI**2
1752 1759 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
1753 1760 dp=numpy.dot(LT,d)
1754 1761 fmp=numpy.dot(LT,fm)
1755 1762 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1756 1763 return chisq
1757 1764
1758 1765 class WindProfiler(Operation):
1759 1766
1760 1767 __isConfig = False
1761 1768
1762 1769 __initime = None
1763 1770 __lastdatatime = None
1764 1771 __integrationtime = None
1765 1772
1766 1773 __buffer = None
1767 1774
1768 1775 __dataReady = False
1769 1776
1770 1777 __firstdata = None
1771 1778
1772 1779 n = None
1773 1780
1774 1781 def __init__(self):
1775 1782 Operation.__init__(self)
1776 1783
1777 1784 def __calculateCosDir(self, elev, azim):
1778 1785 zen = (90 - elev)*numpy.pi/180
1779 1786 azim = azim*numpy.pi/180
1780 1787 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1781 1788 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1782 1789
1783 1790 signX = numpy.sign(numpy.cos(azim))
1784 1791 signY = numpy.sign(numpy.sin(azim))
1785 1792
1786 1793 cosDirX = numpy.copysign(cosDirX, signX)
1787 1794 cosDirY = numpy.copysign(cosDirY, signY)
1788 1795 return cosDirX, cosDirY
1789 1796
1790 1797 def __calculateAngles(self, theta_x, theta_y, azimuth):
1791 1798
1792 1799 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1793 1800 zenith_arr = numpy.arccos(dir_cosw)
1794 1801 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1795 1802
1796 1803 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1797 1804 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1798 1805
1799 1806 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1800 1807
1801 1808 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1802 1809
1803 1810 #
1804 1811 if horOnly:
1805 1812 A = numpy.c_[dir_cosu,dir_cosv]
1806 1813 else:
1807 1814 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
1808 1815 A = numpy.asmatrix(A)
1809 1816 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
1810 1817
1811 1818 return A1
1812 1819
1813 1820 def __correctValues(self, heiRang, phi, velRadial, SNR):
1814 1821 listPhi = phi.tolist()
1815 1822 maxid = listPhi.index(max(listPhi))
1816 1823 minid = listPhi.index(min(listPhi))
1817 1824
1818 1825 rango = range(len(phi))
1819 1826 # rango = numpy.delete(rango,maxid)
1820 1827
1821 1828 heiRang1 = heiRang*math.cos(phi[maxid])
1822 1829 heiRangAux = heiRang*math.cos(phi[minid])
1823 1830 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1824 1831 heiRang1 = numpy.delete(heiRang1,indOut)
1825 1832
1826 1833 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1827 1834 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1828 1835
1829 1836 for i in rango:
1830 1837 x = heiRang*math.cos(phi[i])
1831 1838 y1 = velRadial[i,:]
1832 1839 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1833 1840
1834 1841 x1 = heiRang1
1835 1842 y11 = f1(x1)
1836 1843
1837 1844 y2 = SNR[i,:]
1838 1845 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1839 1846 y21 = f2(x1)
1840 1847
1841 1848 velRadial1[i,:] = y11
1842 1849 SNR1[i,:] = y21
1843 1850
1844 1851 return heiRang1, velRadial1, SNR1
1845 1852
1846 1853 def __calculateVelUVW(self, A, velRadial):
1847 1854
1848 1855 #Operacion Matricial
1849 1856 # velUVW = numpy.zeros((velRadial.shape[1],3))
1850 1857 # for ind in range(velRadial.shape[1]):
1851 1858 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
1852 1859 # velUVW = velUVW.transpose()
1853 1860 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1854 1861 velUVW[:,:] = numpy.dot(A,velRadial)
1855 1862
1856 1863
1857 1864 return velUVW
1858 1865
1859 1866 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1860 1867
1861 1868 def techniqueDBS(self, kwargs):
1862 1869 """
1863 1870 Function that implements Doppler Beam Swinging (DBS) technique.
1864 1871
1865 1872 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1866 1873 Direction correction (if necessary), Ranges and SNR
1867 1874
1868 1875 Output: Winds estimation (Zonal, Meridional and Vertical)
1869 1876
1870 1877 Parameters affected: Winds, height range, SNR
1871 1878 """
1872 1879 velRadial0 = kwargs['velRadial']
1873 1880 heiRang = kwargs['heightList']
1874 1881 SNR0 = kwargs['SNR']
1875 1882
1876 1883 if kwargs.has_key('dirCosx') and kwargs.has_key('dirCosy'):
1877 1884 theta_x = numpy.array(kwargs['dirCosx'])
1878 1885 theta_y = numpy.array(kwargs['dirCosy'])
1879 1886 else:
1880 1887 elev = numpy.array(kwargs['elevation'])
1881 1888 azim = numpy.array(kwargs['azimuth'])
1882 1889 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1883 1890 azimuth = kwargs['correctAzimuth']
1884 1891 if kwargs.has_key('horizontalOnly'):
1885 1892 horizontalOnly = kwargs['horizontalOnly']
1886 1893 else: horizontalOnly = False
1887 1894 if kwargs.has_key('correctFactor'):
1888 1895 correctFactor = kwargs['correctFactor']
1889 1896 else: correctFactor = 1
1890 1897 if kwargs.has_key('channelList'):
1891 1898 channelList = kwargs['channelList']
1892 1899 if len(channelList) == 2:
1893 1900 horizontalOnly = True
1894 1901 arrayChannel = numpy.array(channelList)
1895 1902 param = param[arrayChannel,:,:]
1896 1903 theta_x = theta_x[arrayChannel]
1897 1904 theta_y = theta_y[arrayChannel]
1898 1905
1899 1906 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
1900 1907 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
1901 1908 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1902 1909
1903 1910 #Calculo de Componentes de la velocidad con DBS
1904 1911 winds = self.__calculateVelUVW(A,velRadial1)
1905 1912
1906 1913 return winds, heiRang1, SNR1
1907 1914
1908 1915 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
1909 1916
1910 1917 nPairs = len(pairs_ccf)
1911 1918 posx = numpy.asarray(posx)
1912 1919 posy = numpy.asarray(posy)
1913 1920
1914 1921 #Rotacion Inversa para alinear con el azimuth
1915 1922 if azimuth!= None:
1916 1923 azimuth = azimuth*math.pi/180
1917 1924 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
1918 1925 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
1919 1926 else:
1920 1927 posx1 = posx
1921 1928 posy1 = posy
1922 1929
1923 1930 #Calculo de Distancias
1924 1931 distx = numpy.zeros(nPairs)
1925 1932 disty = numpy.zeros(nPairs)
1926 1933 dist = numpy.zeros(nPairs)
1927 1934 ang = numpy.zeros(nPairs)
1928 1935
1929 1936 for i in range(nPairs):
1930 1937 distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
1931 1938 disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
1932 1939 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1933 1940 ang[i] = numpy.arctan2(disty[i],distx[i])
1934 1941
1935 1942 return distx, disty, dist, ang
1936 1943 #Calculo de Matrices
1937 1944 # nPairs = len(pairs)
1938 1945 # ang1 = numpy.zeros((nPairs, 2, 1))
1939 1946 # dist1 = numpy.zeros((nPairs, 2, 1))
1940 1947 #
1941 1948 # for j in range(nPairs):
1942 1949 # dist1[j,0,0] = dist[pairs[j][0]]
1943 1950 # dist1[j,1,0] = dist[pairs[j][1]]
1944 1951 # ang1[j,0,0] = ang[pairs[j][0]]
1945 1952 # ang1[j,1,0] = ang[pairs[j][1]]
1946 1953 #
1947 1954 # return distx,disty, dist1,ang1
1948 1955
1949 1956
1950 1957 def __calculateVelVer(self, phase, lagTRange, _lambda):
1951 1958
1952 1959 Ts = lagTRange[1] - lagTRange[0]
1953 1960 velW = -_lambda*phase/(4*math.pi*Ts)
1954 1961
1955 1962 return velW
1956 1963
1957 1964 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1958 1965 nPairs = tau1.shape[0]
1959 1966 nHeights = tau1.shape[1]
1960 1967 vel = numpy.zeros((nPairs,3,nHeights))
1961 1968 dist1 = numpy.reshape(dist, (dist.size,1))
1962 1969
1963 1970 angCos = numpy.cos(ang)
1964 1971 angSin = numpy.sin(ang)
1965 1972
1966 1973 vel0 = dist1*tau1/(2*tau2**2)
1967 1974 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1968 1975 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1969 1976
1970 1977 ind = numpy.where(numpy.isinf(vel))
1971 1978 vel[ind] = numpy.nan
1972 1979
1973 1980 return vel
1974 1981
1975 1982 # def __getPairsAutoCorr(self, pairsList, nChannels):
1976 1983 #
1977 1984 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1978 1985 #
1979 1986 # for l in range(len(pairsList)):
1980 1987 # firstChannel = pairsList[l][0]
1981 1988 # secondChannel = pairsList[l][1]
1982 1989 #
1983 1990 # #Obteniendo pares de Autocorrelacion
1984 1991 # if firstChannel == secondChannel:
1985 1992 # pairsAutoCorr[firstChannel] = int(l)
1986 1993 #
1987 1994 # pairsAutoCorr = pairsAutoCorr.astype(int)
1988 1995 #
1989 1996 # pairsCrossCorr = range(len(pairsList))
1990 1997 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1991 1998 #
1992 1999 # return pairsAutoCorr, pairsCrossCorr
1993 2000
1994 2001 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1995 2002 def techniqueSA(self, kwargs):
1996 2003
1997 2004 """
1998 2005 Function that implements Spaced Antenna (SA) technique.
1999 2006
2000 2007 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
2001 2008 Direction correction (if necessary), Ranges and SNR
2002 2009
2003 2010 Output: Winds estimation (Zonal, Meridional and Vertical)
2004 2011
2005 2012 Parameters affected: Winds
2006 2013 """
2007 2014 position_x = kwargs['positionX']
2008 2015 position_y = kwargs['positionY']
2009 2016 azimuth = kwargs['azimuth']
2010 2017
2011 2018 if kwargs.has_key('correctFactor'):
2012 2019 correctFactor = kwargs['correctFactor']
2013 2020 else:
2014 2021 correctFactor = 1
2015 2022
2016 2023 groupList = kwargs['groupList']
2017 2024 pairs_ccf = groupList[1]
2018 2025 tau = kwargs['tau']
2019 2026 _lambda = kwargs['_lambda']
2020 2027
2021 2028 #Cross Correlation pairs obtained
2022 2029 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
2023 2030 # pairsArray = numpy.array(pairsList)[pairsCrossCorr]
2024 2031 # pairsSelArray = numpy.array(pairsSelected)
2025 2032 # pairs = []
2026 2033 #
2027 2034 # #Wind estimation pairs obtained
2028 2035 # for i in range(pairsSelArray.shape[0]/2):
2029 2036 # ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
2030 2037 # ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
2031 2038 # pairs.append((ind1,ind2))
2032 2039
2033 2040 indtau = tau.shape[0]/2
2034 2041 tau1 = tau[:indtau,:]
2035 2042 tau2 = tau[indtau:-1,:]
2036 2043 # tau1 = tau1[pairs,:]
2037 2044 # tau2 = tau2[pairs,:]
2038 2045 phase1 = tau[-1,:]
2039 2046
2040 2047 #---------------------------------------------------------------------
2041 2048 #Metodo Directo
2042 2049 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
2043 2050 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
2044 2051 winds = stats.nanmean(winds, axis=0)
2045 2052 #---------------------------------------------------------------------
2046 2053 #Metodo General
2047 2054 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
2048 2055 # #Calculo Coeficientes de Funcion de Correlacion
2049 2056 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
2050 2057 # #Calculo de Velocidades
2051 2058 # winds = self.calculateVelUV(F,G,A,B,H)
2052 2059
2053 2060 #---------------------------------------------------------------------
2054 2061 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
2055 2062 winds = correctFactor*winds
2056 2063 return winds
2057 2064
2058 2065 def __checkTime(self, currentTime, paramInterval, outputInterval):
2059 2066
2060 2067 dataTime = currentTime + paramInterval
2061 2068 deltaTime = dataTime - self.__initime
2062 2069
2063 2070 if deltaTime >= outputInterval or deltaTime < 0:
2064 2071 self.__dataReady = True
2065 2072 return
2066 2073
2067 2074 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
2068 2075 '''
2069 2076 Function that implements winds estimation technique with detected meteors.
2070 2077
2071 2078 Input: Detected meteors, Minimum meteor quantity to wind estimation
2072 2079
2073 2080 Output: Winds estimation (Zonal and Meridional)
2074 2081
2075 2082 Parameters affected: Winds
2076 2083 '''
2077 2084 # print arrayMeteor.shape
2078 2085 #Settings
2079 2086 nInt = (heightMax - heightMin)/2
2080 2087 # print nInt
2081 2088 nInt = int(nInt)
2082 2089 # print nInt
2083 2090 winds = numpy.zeros((2,nInt))*numpy.nan
2084 2091
2085 2092 #Filter errors
2086 2093 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
2087 2094 finalMeteor = arrayMeteor[error,:]
2088 2095
2089 2096 #Meteor Histogram
2090 2097 finalHeights = finalMeteor[:,2]
2091 2098 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
2092 2099 nMeteorsPerI = hist[0]
2093 2100 heightPerI = hist[1]
2094 2101
2095 2102 #Sort of meteors
2096 2103 indSort = finalHeights.argsort()
2097 2104 finalMeteor2 = finalMeteor[indSort,:]
2098 2105
2099 2106 # Calculating winds
2100 2107 ind1 = 0
2101 2108 ind2 = 0
2102 2109
2103 2110 for i in range(nInt):
2104 2111 nMet = nMeteorsPerI[i]
2105 2112 ind1 = ind2
2106 2113 ind2 = ind1 + nMet
2107 2114
2108 2115 meteorAux = finalMeteor2[ind1:ind2,:]
2109 2116
2110 2117 if meteorAux.shape[0] >= meteorThresh:
2111 2118 vel = meteorAux[:, 6]
2112 2119 zen = meteorAux[:, 4]*numpy.pi/180
2113 2120 azim = meteorAux[:, 3]*numpy.pi/180
2114 2121
2115 2122 n = numpy.cos(zen)
2116 2123 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
2117 2124 # l = m*numpy.tan(azim)
2118 2125 l = numpy.sin(zen)*numpy.sin(azim)
2119 2126 m = numpy.sin(zen)*numpy.cos(azim)
2120 2127
2121 2128 A = numpy.vstack((l, m)).transpose()
2122 2129 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
2123 2130 windsAux = numpy.dot(A1, vel)
2124 2131
2125 2132 winds[0,i] = windsAux[0]
2126 2133 winds[1,i] = windsAux[1]
2127 2134
2128 2135 return winds, heightPerI[:-1]
2129 2136
2130 2137 def techniqueNSM_SA(self, **kwargs):
2131 2138 metArray = kwargs['metArray']
2132 2139 heightList = kwargs['heightList']
2133 2140 timeList = kwargs['timeList']
2134 2141
2135 2142 rx_location = kwargs['rx_location']
2136 2143 groupList = kwargs['groupList']
2137 2144 azimuth = kwargs['azimuth']
2138 2145 dfactor = kwargs['dfactor']
2139 2146 k = kwargs['k']
2140 2147
2141 2148 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
2142 2149 d = dist*dfactor
2143 2150 #Phase calculation
2144 2151 metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
2145 2152
2146 2153 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
2147 2154
2148 2155 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2149 2156 azimuth1 = azimuth1*numpy.pi/180
2150 2157
2151 2158 for i in range(heightList.size):
2152 2159 h = heightList[i]
2153 2160 indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
2154 2161 metHeight = metArray1[indH,:]
2155 2162 if metHeight.shape[0] >= 2:
2156 2163 velAux = numpy.asmatrix(metHeight[:,-2]).T #Radial Velocities
2157 2164 iazim = metHeight[:,1].astype(int)
2158 2165 azimAux = numpy.asmatrix(azimuth1[iazim]).T #Azimuths
2159 2166 A = numpy.hstack((numpy.cos(azimAux),numpy.sin(azimAux)))
2160 2167 A = numpy.asmatrix(A)
2161 2168 A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
2162 2169 velHor = numpy.dot(A1,velAux)
2163 2170
2164 2171 velEst[i,:] = numpy.squeeze(velHor)
2165 2172 return velEst
2166 2173
2167 2174 def __getPhaseSlope(self, metArray, heightList, timeList):
2168 2175 meteorList = []
2169 2176 #utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
2170 2177 #Putting back together the meteor matrix
2171 2178 utctime = metArray[:,0]
2172 2179 uniqueTime = numpy.unique(utctime)
2173 2180
2174 2181 phaseDerThresh = 0.5
2175 2182 ippSeconds = timeList[1] - timeList[0]
2176 2183 sec = numpy.where(timeList>1)[0][0]
2177 2184 nPairs = metArray.shape[1] - 6
2178 2185 nHeights = len(heightList)
2179 2186
2180 2187 for t in uniqueTime:
2181 2188 metArray1 = metArray[utctime==t,:]
2182 2189 # phaseDerThresh = numpy.pi/4 #reducir Phase thresh
2183 2190 tmet = metArray1[:,1].astype(int)
2184 2191 hmet = metArray1[:,2].astype(int)
2185 2192
2186 2193 metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
2187 2194 metPhase[:,:] = numpy.nan
2188 2195 metPhase[:,hmet,tmet] = metArray1[:,6:].T
2189 2196
2190 2197 #Delete short trails
2191 2198 metBool = ~numpy.isnan(metPhase[0,:,:])
2192 2199 heightVect = numpy.sum(metBool, axis = 1)
2193 2200 metBool[heightVect<sec,:] = False
2194 2201 metPhase[:,heightVect<sec,:] = numpy.nan
2195 2202
2196 2203 #Derivative
2197 2204 metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
2198 2205 phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
2199 2206 metPhase[phDerAux] = numpy.nan
2200 2207
2201 2208 #--------------------------METEOR DETECTION -----------------------------------------
2202 2209 indMet = numpy.where(numpy.any(metBool,axis=1))[0]
2203 2210
2204 2211 for p in numpy.arange(nPairs):
2205 2212 phase = metPhase[p,:,:]
2206 2213 phDer = metDer[p,:,:]
2207 2214
2208 2215 for h in indMet:
2209 2216 height = heightList[h]
2210 2217 phase1 = phase[h,:] #82
2211 2218 phDer1 = phDer[h,:]
2212 2219
2213 2220 phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
2214 2221
2215 2222 indValid = numpy.where(~numpy.isnan(phase1))[0]
2216 2223 initMet = indValid[0]
2217 2224 endMet = 0
2218 2225
2219 2226 for i in range(len(indValid)-1):
2220 2227
2221 2228 #Time difference
2222 2229 inow = indValid[i]
2223 2230 inext = indValid[i+1]
2224 2231 idiff = inext - inow
2225 2232 #Phase difference
2226 2233 phDiff = numpy.abs(phase1[inext] - phase1[inow])
2227 2234
2228 2235 if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
2229 2236 sizeTrail = inow - initMet + 1
2230 2237 if sizeTrail>3*sec: #Too short meteors
2231 2238 x = numpy.arange(initMet,inow+1)*ippSeconds
2232 2239 y = phase1[initMet:inow+1]
2233 2240 ynnan = ~numpy.isnan(y)
2234 2241 x = x[ynnan]
2235 2242 y = y[ynnan]
2236 2243 slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
2237 2244 ylin = x*slope + intercept
2238 2245 rsq = r_value**2
2239 2246 if rsq > 0.5:
2240 2247 vel = slope#*height*1000/(k*d)
2241 2248 estAux = numpy.array([utctime,p,height, vel, rsq])
2242 2249 meteorList.append(estAux)
2243 2250 initMet = inext
2244 2251 metArray2 = numpy.array(meteorList)
2245 2252
2246 2253 return metArray2
2247 2254
2248 2255 def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
2249 2256
2250 2257 azimuth1 = numpy.zeros(len(pairslist))
2251 2258 dist = numpy.zeros(len(pairslist))
2252 2259
2253 2260 for i in range(len(rx_location)):
2254 2261 ch0 = pairslist[i][0]
2255 2262 ch1 = pairslist[i][1]
2256 2263
2257 2264 diffX = rx_location[ch0][0] - rx_location[ch1][0]
2258 2265 diffY = rx_location[ch0][1] - rx_location[ch1][1]
2259 2266 azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
2260 2267 dist[i] = numpy.sqrt(diffX**2 + diffY**2)
2261 2268
2262 2269 azimuth1 -= azimuth0
2263 2270 return azimuth1, dist
2264 2271
2265 2272 def techniqueNSM_DBS(self, **kwargs):
2266 2273 metArray = kwargs['metArray']
2267 2274 heightList = kwargs['heightList']
2268 2275 timeList = kwargs['timeList']
2269 2276 zenithList = kwargs['zenithList']
2270 2277 nChan = numpy.max(cmet) + 1
2271 2278 nHeights = len(heightList)
2272 2279
2273 2280 utctime = metArray[:,0]
2274 2281 cmet = metArray[:,1]
2275 2282 hmet = metArray1[:,3].astype(int)
2276 2283 h1met = heightList[hmet]*zenithList[cmet]
2277 2284 vmet = metArray1[:,5]
2278 2285
2279 2286 for i in range(nHeights - 1):
2280 2287 hmin = heightList[i]
2281 2288 hmax = heightList[i + 1]
2282 2289
2283 2290 vthisH = vmet[(h1met>=hmin) & (h1met<hmax)]
2284 2291
2285 2292
2286 2293
2287 2294 return data_output
2288 2295
2289 2296 def run(self, dataOut, technique, **kwargs):
2290 2297
2291 2298 param = dataOut.data_param
2292 2299 if dataOut.abscissaList != None:
2293 2300 absc = dataOut.abscissaList[:-1]
2294 2301 noise = dataOut.noise
2295 2302 heightList = dataOut.heightList
2296 2303 SNR = dataOut.data_SNR
2297 2304
2298 2305 if technique == 'DBS':
2299 2306
2300 2307 kwargs['velRadial'] = param[:,1,:] #Radial velocity
2301 2308 kwargs['heightList'] = heightList
2302 2309 kwargs['SNR'] = SNR
2303 2310
2304 2311 dataOut.data_output, dataOut.heightList, dataOut.data_SNR = self.techniqueDBS(kwargs) #DBS Function
2305 2312 dataOut.utctimeInit = dataOut.utctime
2306 2313 dataOut.outputInterval = dataOut.paramInterval
2307 2314
2308 2315 elif technique == 'SA':
2309 2316
2310 2317 #Parameters
2311 2318 # position_x = kwargs['positionX']
2312 2319 # position_y = kwargs['positionY']
2313 2320 # azimuth = kwargs['azimuth']
2314 2321 #
2315 2322 # if kwargs.has_key('crosspairsList'):
2316 2323 # pairs = kwargs['crosspairsList']
2317 2324 # else:
2318 2325 # pairs = None
2319 2326 #
2320 2327 # if kwargs.has_key('correctFactor'):
2321 2328 # correctFactor = kwargs['correctFactor']
2322 2329 # else:
2323 2330 # correctFactor = 1
2324 2331
2325 2332 # tau = dataOut.data_param
2326 2333 # _lambda = dataOut.C/dataOut.frequency
2327 2334 # pairsList = dataOut.groupList
2328 2335 # nChannels = dataOut.nChannels
2329 2336
2330 2337 kwargs['groupList'] = dataOut.groupList
2331 2338 kwargs['tau'] = dataOut.data_param
2332 2339 kwargs['_lambda'] = dataOut.C/dataOut.frequency
2333 2340 # dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
2334 2341 dataOut.data_output = self.techniqueSA(kwargs)
2335 2342 dataOut.utctimeInit = dataOut.utctime
2336 2343 dataOut.outputInterval = dataOut.timeInterval
2337 2344
2338 2345 elif technique == 'Meteors':
2339 2346 dataOut.flagNoData = True
2340 2347 self.__dataReady = False
2341 2348
2342 2349 if kwargs.has_key('nHours'):
2343 2350 nHours = kwargs['nHours']
2344 2351 else:
2345 2352 nHours = 1
2346 2353
2347 2354 if kwargs.has_key('meteorsPerBin'):
2348 2355 meteorThresh = kwargs['meteorsPerBin']
2349 2356 else:
2350 2357 meteorThresh = 6
2351 2358
2352 2359 if kwargs.has_key('hmin'):
2353 2360 hmin = kwargs['hmin']
2354 2361 else: hmin = 70
2355 2362 if kwargs.has_key('hmax'):
2356 2363 hmax = kwargs['hmax']
2357 2364 else: hmax = 110
2358 2365
2359 2366 dataOut.outputInterval = nHours*3600
2360 2367
2361 2368 if self.__isConfig == False:
2362 2369 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2363 2370 #Get Initial LTC time
2364 2371 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2365 2372 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2366 2373
2367 2374 self.__isConfig = True
2368 2375
2369 2376 if self.__buffer == None:
2370 2377 self.__buffer = dataOut.data_param
2371 2378 self.__firstdata = copy.copy(dataOut)
2372 2379
2373 2380 else:
2374 2381 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2375 2382
2376 2383 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2377 2384
2378 2385 if self.__dataReady:
2379 2386 dataOut.utctimeInit = self.__initime
2380 2387
2381 2388 self.__initime += dataOut.outputInterval #to erase time offset
2382 2389
2383 2390 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
2384 2391 dataOut.flagNoData = False
2385 2392 self.__buffer = None
2386 2393
2387 2394 elif technique == 'Meteors1':
2388 2395 dataOut.flagNoData = True
2389 2396 self.__dataReady = False
2390 2397
2391 2398 if kwargs.has_key('nMins'):
2392 2399 nMins = kwargs['nMins']
2393 2400 else: nMins = 20
2394 2401 if kwargs.has_key('rx_location'):
2395 2402 rx_location = kwargs['rx_location']
2396 2403 else: rx_location = [(0,1),(1,1),(1,0)]
2397 2404 if kwargs.has_key('azimuth'):
2398 2405 azimuth = kwargs['azimuth']
2399 2406 else: azimuth = 51
2400 2407 if kwargs.has_key('dfactor'):
2401 2408 dfactor = kwargs['dfactor']
2402 2409 if kwargs.has_key('mode'):
2403 2410 mode = kwargs['mode']
2404 2411 else: mode = 'SA'
2405 2412
2406 2413 #Borrar luego esto
2407 2414 if dataOut.groupList == None:
2408 2415 dataOut.groupList = [(0,1),(0,2),(1,2)]
2409 2416 groupList = dataOut.groupList
2410 2417 C = 3e8
2411 2418 freq = 50e6
2412 2419 lamb = C/freq
2413 2420 k = 2*numpy.pi/lamb
2414 2421
2415 2422 timeList = dataOut.abscissaList
2416 2423 heightList = dataOut.heightList
2417 2424
2418 2425 if self.__isConfig == False:
2419 2426 dataOut.outputInterval = nMins*60
2420 2427 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2421 2428 #Get Initial LTC time
2422 2429 initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2423 2430 minuteAux = initime.minute
2424 2431 minuteNew = int(numpy.floor(minuteAux/nMins)*nMins)
2425 2432 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2426 2433
2427 2434 self.__isConfig = True
2428 2435
2429 2436 if self.__buffer == None:
2430 2437 self.__buffer = dataOut.data_param
2431 2438 self.__firstdata = copy.copy(dataOut)
2432 2439
2433 2440 else:
2434 2441 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2435 2442
2436 2443 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2437 2444
2438 2445 if self.__dataReady:
2439 2446 dataOut.utctimeInit = self.__initime
2440 2447 self.__initime += dataOut.outputInterval #to erase time offset
2441 2448
2442 2449 metArray = self.__buffer
2443 2450 if mode == 'SA':
2444 2451 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
2445 2452 elif mode == 'DBS':
2446 2453 dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList)
2447 2454 dataOut.data_output = dataOut.data_output.T
2448 2455 dataOut.flagNoData = False
2449 2456 self.__buffer = None
2450 2457
2451 2458 return
2452 2459
2453 2460 class EWDriftsEstimation(Operation):
2454 2461
2455 2462 def __init__(self):
2456 2463 Operation.__init__(self)
2457 2464
2458 2465 def __correctValues(self, heiRang, phi, velRadial, SNR):
2459 2466 listPhi = phi.tolist()
2460 2467 maxid = listPhi.index(max(listPhi))
2461 2468 minid = listPhi.index(min(listPhi))
2462 2469
2463 2470 rango = range(len(phi))
2464 2471 # rango = numpy.delete(rango,maxid)
2465 2472
2466 2473 heiRang1 = heiRang*math.cos(phi[maxid])
2467 2474 heiRangAux = heiRang*math.cos(phi[minid])
2468 2475 indOut = (heiRang1 < heiRangAux[0]).nonzero()
2469 2476 heiRang1 = numpy.delete(heiRang1,indOut)
2470 2477
2471 2478 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
2472 2479 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
2473 2480
2474 2481 for i in rango:
2475 2482 x = heiRang*math.cos(phi[i])
2476 2483 y1 = velRadial[i,:]
2477 2484 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
2478 2485
2479 2486 x1 = heiRang1
2480 2487 y11 = f1(x1)
2481 2488
2482 2489 y2 = SNR[i,:]
2483 2490 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
2484 2491 y21 = f2(x1)
2485 2492
2486 2493 velRadial1[i,:] = y11
2487 2494 SNR1[i,:] = y21
2488 2495
2489 2496 return heiRang1, velRadial1, SNR1
2490 2497
2491 2498 def run(self, dataOut, zenith, zenithCorrection):
2492 2499 heiRang = dataOut.heightList
2493 2500 velRadial = dataOut.data_param[:,3,:]
2494 2501 SNR = dataOut.data_SNR
2495 2502
2496 2503 zenith = numpy.array(zenith)
2497 2504 zenith -= zenithCorrection
2498 2505 zenith *= numpy.pi/180
2499 2506
2500 2507 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
2501 2508
2502 2509 alp = zenith[0]
2503 2510 bet = zenith[1]
2504 2511
2505 2512 w_w = velRadial1[0,:]
2506 2513 w_e = velRadial1[1,:]
2507 2514
2508 2515 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
2509 2516 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
2510 2517
2511 2518 winds = numpy.vstack((u,w))
2512 2519
2513 2520 dataOut.heightList = heiRang1
2514 2521 dataOut.data_output = winds
2515 2522 dataOut.data_SNR = SNR1
2516 2523
2517 2524 dataOut.utctimeInit = dataOut.utctime
2518 2525 dataOut.outputInterval = dataOut.timeInterval
2519 2526 return
2520 2527
2521 2528 #--------------- Non Specular Meteor ----------------
2522 2529
2523 2530 class NonSpecularMeteorDetection(Operation):
2524 2531
2525 2532 def run(self, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False):
2526 2533 data_acf = self.dataOut.data_pre[0]
2527 2534 data_ccf = self.dataOut.data_pre[1]
2528 2535
2529 2536 lamb = self.dataOut.C/self.dataOut.frequency
2530 2537 tSamp = self.dataOut.ippSeconds*self.dataOut.nCohInt
2531 2538 paramInterval = self.dataOut.paramInterval
2532 2539
2533 2540 nChannels = data_acf.shape[0]
2534 2541 nLags = data_acf.shape[1]
2535 2542 nProfiles = data_acf.shape[2]
2536 2543 nHeights = self.dataOut.nHeights
2537 2544 nCohInt = self.dataOut.nCohInt
2538 2545 sec = numpy.round(nProfiles/self.dataOut.paramInterval)
2539 2546 heightList = self.dataOut.heightList
2540 2547 ippSeconds = self.dataOut.ippSeconds*self.dataOut.nCohInt*self.dataOut.nAvg
2541 2548 utctime = self.dataOut.utctime
2542 2549
2543 2550 self.dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
2544 2551
2545 2552 #------------------------ SNR --------------------------------------
2546 2553 power = data_acf[:,0,:,:].real
2547 2554 noise = numpy.zeros(nChannels)
2548 2555 SNR = numpy.zeros(power.shape)
2549 2556 for i in range(nChannels):
2550 2557 noise[i] = hildebrand_sekhon(power[i,:], nCohInt)
2551 2558 SNR[i] = (power[i]-noise[i])/noise[i]
2552 2559 SNRm = numpy.nanmean(SNR, axis = 0)
2553 2560 SNRdB = 10*numpy.log10(SNR)
2554 2561
2555 2562 if mode == 'SA':
2556 2563 nPairs = data_ccf.shape[0]
2557 2564 #---------------------- Coherence and Phase --------------------------
2558 2565 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
2559 2566 # phase1 = numpy.copy(phase)
2560 2567 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
2561 2568
2562 2569 for p in range(nPairs):
2563 2570 ch0 = self.dataOut.groupList[p][0]
2564 2571 ch1 = self.dataOut.groupList[p][1]
2565 2572 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
2566 2573 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
2567 2574 # phase1[p,:,:] = numpy.angle(ccf) #median filter
2568 2575 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
2569 2576 # coh1[p,:,:] = numpy.abs(ccf) #median filter
2570 2577 coh = numpy.nanmax(coh1, axis = 0)
2571 2578 # struc = numpy.ones((5,1))
2572 2579 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
2573 2580 #---------------------- Radial Velocity ----------------------------
2574 2581 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
2575 2582 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
2576 2583
2577 2584 if allData:
2578 2585 boolMetFin = ~numpy.isnan(SNRm)
2579 2586 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2580 2587 else:
2581 2588 #------------------------ Meteor mask ---------------------------------
2582 2589 # #SNR mask
2583 2590 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
2584 2591 #
2585 2592 # #Erase small objects
2586 2593 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
2587 2594 #
2588 2595 # auxEEJ = numpy.sum(boolMet1,axis=0)
2589 2596 # indOver = auxEEJ>nProfiles*0.8 #Use this later
2590 2597 # indEEJ = numpy.where(indOver)[0]
2591 2598 # indNEEJ = numpy.where(~indOver)[0]
2592 2599 #
2593 2600 # boolMetFin = boolMet1
2594 2601 #
2595 2602 # if indEEJ.size > 0:
2596 2603 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
2597 2604 #
2598 2605 # boolMet2 = coh > cohThresh
2599 2606 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
2600 2607 #
2601 2608 # #Final Meteor mask
2602 2609 # boolMetFin = boolMet1|boolMet2
2603 2610
2604 2611 #Coherence mask
2605 2612 boolMet1 = coh > 0.75
2606 2613 struc = numpy.ones((30,1))
2607 2614 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
2608 2615
2609 2616 #Derivative mask
2610 2617 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2611 2618 boolMet2 = derPhase < 0.2
2612 2619 # boolMet2 = ndimage.morphology.binary_opening(boolMet2)
2613 2620 # boolMet2 = ndimage.morphology.binary_closing(boolMet2, structure = numpy.ones((10,1)))
2614 2621 boolMet2 = ndimage.median_filter(boolMet2,size=5)
2615 2622 boolMet2 = numpy.vstack((boolMet2,numpy.full((1,nHeights), True, dtype=bool)))
2616 2623 # #Final mask
2617 2624 # boolMetFin = boolMet2
2618 2625 boolMetFin = boolMet1&boolMet2
2619 2626 # boolMetFin = ndimage.morphology.binary_dilation(boolMetFin)
2620 2627 #Creating data_param
2621 2628 coordMet = numpy.where(boolMetFin)
2622 2629
2623 2630 tmet = coordMet[0]
2624 2631 hmet = coordMet[1]
2625 2632
2626 2633 data_param = numpy.zeros((tmet.size, 6 + nPairs))
2627 2634 data_param[:,0] = utctime
2628 2635 data_param[:,1] = tmet
2629 2636 data_param[:,2] = hmet
2630 2637 data_param[:,3] = SNRm[tmet,hmet]
2631 2638 data_param[:,4] = velRad[tmet,hmet]
2632 2639 data_param[:,5] = coh[tmet,hmet]
2633 2640 data_param[:,6:] = phase[:,tmet,hmet].T
2634 2641
2635 2642 elif mode == 'DBS':
2636 2643 self.dataOut.groupList = numpy.arange(nChannels)
2637 2644
2638 2645 #Radial Velocities
2639 2646 # phase = numpy.angle(data_acf[:,1,:,:])
2640 2647 phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
2641 2648 velRad = phase*lamb/(4*numpy.pi*tSamp)
2642 2649
2643 2650 #Spectral width
2644 2651 acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
2645 2652 acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
2646 2653
2647 2654 spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2))
2648 2655 # velRad = ndimage.median_filter(velRad, size = (1,5,1))
2649 2656 if allData:
2650 2657 boolMetFin = ~numpy.isnan(SNRdB)
2651 2658 else:
2652 2659 #SNR
2653 2660 boolMet1 = (SNRdB>SNRthresh) #SNR mask
2654 2661 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
2655 2662
2656 2663 #Radial velocity
2657 2664 boolMet2 = numpy.abs(velRad) < 30
2658 2665 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
2659 2666
2660 2667 #Spectral Width
2661 2668 boolMet3 = spcWidth < 30
2662 2669 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
2663 2670 # boolMetFin = self.__erase_small(boolMet1, 10,5)
2664 2671 boolMetFin = boolMet1&boolMet2&boolMet3
2665 2672
2666 2673 #Creating data_param
2667 2674 coordMet = numpy.where(boolMetFin)
2668 2675
2669 2676 cmet = coordMet[0]
2670 2677 tmet = coordMet[1]
2671 2678 hmet = coordMet[2]
2672 2679
2673 2680 data_param = numpy.zeros((tmet.size, 7))
2674 2681 data_param[:,0] = utctime
2675 2682 data_param[:,1] = cmet
2676 2683 data_param[:,2] = tmet
2677 2684 data_param[:,3] = hmet
2678 2685 data_param[:,4] = SNR[cmet,tmet,hmet].T
2679 2686 data_param[:,5] = velRad[cmet,tmet,hmet].T
2680 2687 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
2681 2688
2682 2689 # self.dataOut.data_param = data_int
2683 2690 if len(data_param) == 0:
2684 2691 self.dataOut.flagNoData = True
2685 2692 else:
2686 2693 self.dataOut.data_param = data_param
2687 2694
2688 2695 def __erase_small(self, binArray, threshX, threshY):
2689 2696 labarray, numfeat = ndimage.measurements.label(binArray)
2690 2697 binArray1 = numpy.copy(binArray)
2691 2698
2692 2699 for i in range(1,numfeat + 1):
2693 2700 auxBin = (labarray==i)
2694 2701 auxSize = auxBin.sum()
2695 2702
2696 2703 x,y = numpy.where(auxBin)
2697 2704 widthX = x.max() - x.min()
2698 2705 widthY = y.max() - y.min()
2699 2706
2700 2707 #width X: 3 seg -> 12.5*3
2701 2708 #width Y:
2702 2709
2703 2710 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
2704 2711 binArray1[auxBin] = False
2705 2712
2706 2713 return binArray1
2707 2714
2708 2715 #--------------- Specular Meteor ----------------
2709 2716
2710 2717 class SMDetection(Operation):
2711 2718 '''
2712 2719 Function DetectMeteors()
2713 2720 Project developed with paper:
2714 2721 HOLDSWORTH ET AL. 2004
2715 2722
2716 2723 Input:
2717 2724 self.dataOut.data_pre
2718 2725
2719 2726 centerReceiverIndex: From the channels, which is the center receiver
2720 2727
2721 2728 hei_ref: Height reference for the Beacon signal extraction
2722 2729 tauindex:
2723 2730 predefinedPhaseShifts: Predefined phase offset for the voltge signals
2724 2731
2725 2732 cohDetection: Whether to user Coherent detection or not
2726 2733 cohDet_timeStep: Coherent Detection calculation time step
2727 2734 cohDet_thresh: Coherent Detection phase threshold to correct phases
2728 2735
2729 2736 noise_timeStep: Noise calculation time step
2730 2737 noise_multiple: Noise multiple to define signal threshold
2731 2738
2732 2739 multDet_timeLimit: Multiple Detection Removal time limit in seconds
2733 2740 multDet_rangeLimit: Multiple Detection Removal range limit in km
2734 2741
2735 2742 phaseThresh: Maximum phase difference between receiver to be consider a meteor
2736 2743 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
2737 2744
2738 2745 hmin: Minimum Height of the meteor to use it in the further wind estimations
2739 2746 hmax: Maximum Height of the meteor to use it in the further wind estimations
2740 2747 azimuth: Azimuth angle correction
2741 2748
2742 2749 Affected:
2743 2750 self.dataOut.data_param
2744 2751
2745 2752 Rejection Criteria (Errors):
2746 2753 0: No error; analysis OK
2747 2754 1: SNR < SNR threshold
2748 2755 2: angle of arrival (AOA) ambiguously determined
2749 2756 3: AOA estimate not feasible
2750 2757 4: Large difference in AOAs obtained from different antenna baselines
2751 2758 5: echo at start or end of time series
2752 2759 6: echo less than 5 examples long; too short for analysis
2753 2760 7: echo rise exceeds 0.3s
2754 2761 8: echo decay time less than twice rise time
2755 2762 9: large power level before echo
2756 2763 10: large power level after echo
2757 2764 11: poor fit to amplitude for estimation of decay time
2758 2765 12: poor fit to CCF phase variation for estimation of radial drift velocity
2759 2766 13: height unresolvable echo: not valid height within 70 to 110 km
2760 2767 14: height ambiguous echo: more then one possible height within 70 to 110 km
2761 2768 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
2762 2769 16: oscilatory echo, indicating event most likely not an underdense echo
2763 2770
2764 2771 17: phase difference in meteor Reestimation
2765 2772
2766 2773 Data Storage:
2767 2774 Meteors for Wind Estimation (8):
2768 2775 Utc Time | Range Height
2769 2776 Azimuth Zenith errorCosDir
2770 2777 VelRad errorVelRad
2771 2778 Phase0 Phase1 Phase2 Phase3
2772 2779 TypeError
2773 2780
2774 2781 '''
2775 2782
2776 2783 def run(self, dataOut, hei_ref = None, tauindex = 0,
2777 2784 phaseOffsets = None,
2778 2785 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
2779 2786 noise_timeStep = 4, noise_multiple = 4,
2780 2787 multDet_timeLimit = 1, multDet_rangeLimit = 3,
2781 2788 phaseThresh = 20, SNRThresh = 5,
2782 2789 hmin = 50, hmax=150, azimuth = 0,
2783 2790 channelPositions = None) :
2784 2791
2785 2792
2786 2793 #Getting Pairslist
2787 2794 if channelPositions == None:
2788 2795 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2789 2796 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2790 2797 meteorOps = SMOperations()
2791 2798 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2792 2799 heiRang = dataOut.getHeiRange()
2793 2800 #Get Beacon signal - No Beacon signal anymore
2794 2801 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
2795 2802 #
2796 2803 # if hei_ref != None:
2797 2804 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
2798 2805 #
2799 2806
2800 2807
2801 2808 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
2802 2809 # see if the user put in pre defined phase shifts
2803 2810 voltsPShift = dataOut.data_pre.copy()
2804 2811
2805 2812 # if predefinedPhaseShifts != None:
2806 2813 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
2807 2814 #
2808 2815 # # elif beaconPhaseShifts:
2809 2816 # # #get hardware phase shifts using beacon signal
2810 2817 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
2811 2818 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
2812 2819 #
2813 2820 # else:
2814 2821 # hardwarePhaseShifts = numpy.zeros(5)
2815 2822 #
2816 2823 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
2817 2824 # for i in range(self.dataOut.data_pre.shape[0]):
2818 2825 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
2819 2826
2820 2827 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
2821 2828
2822 2829 #Remove DC
2823 2830 voltsDC = numpy.mean(voltsPShift,1)
2824 2831 voltsDC = numpy.mean(voltsDC,1)
2825 2832 for i in range(voltsDC.shape[0]):
2826 2833 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
2827 2834
2828 2835 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
2829 2836 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
2830 2837
2831 2838 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
2832 2839 #Coherent Detection
2833 2840 if cohDetection:
2834 2841 #use coherent detection to get the net power
2835 2842 cohDet_thresh = cohDet_thresh*numpy.pi/180
2836 2843 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
2837 2844
2838 2845 #Non-coherent detection!
2839 2846 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
2840 2847 #********** END OF COH/NON-COH POWER CALCULATION**********************
2841 2848
2842 2849 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
2843 2850 #Get noise
2844 2851 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
2845 2852 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
2846 2853 #Get signal threshold
2847 2854 signalThresh = noise_multiple*noise
2848 2855 #Meteor echoes detection
2849 2856 listMeteors = self.__findMeteors(powerNet, signalThresh)
2850 2857 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
2851 2858
2852 2859 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
2853 2860 #Parameters
2854 2861 heiRange = dataOut.getHeiRange()
2855 2862 rangeInterval = heiRange[1] - heiRange[0]
2856 2863 rangeLimit = multDet_rangeLimit/rangeInterval
2857 2864 timeLimit = multDet_timeLimit/dataOut.timeInterval
2858 2865 #Multiple detection removals
2859 2866 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
2860 2867 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
2861 2868
2862 2869 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
2863 2870 #Parameters
2864 2871 phaseThresh = phaseThresh*numpy.pi/180
2865 2872 thresh = [phaseThresh, noise_multiple, SNRThresh]
2866 2873 #Meteor reestimation (Errors N 1, 6, 12, 17)
2867 2874 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist0, thresh, noise, dataOut.timeInterval, dataOut.frequency)
2868 2875 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
2869 2876 #Estimation of decay times (Errors N 7, 8, 11)
2870 2877 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
2871 2878 #******************* END OF METEOR REESTIMATION *******************
2872 2879
2873 2880 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
2874 2881 #Calculating Radial Velocity (Error N 15)
2875 2882 radialStdThresh = 10
2876 2883 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
2877 2884
2878 2885 if len(listMeteors4) > 0:
2879 2886 #Setting New Array
2880 2887 date = dataOut.utctime
2881 2888 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
2882 2889
2883 2890 #Correcting phase offset
2884 2891 if phaseOffsets != None:
2885 2892 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2886 2893 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2887 2894
2888 2895 #Second Pairslist
2889 2896 pairsList = []
2890 2897 pairx = (0,1)
2891 2898 pairy = (2,3)
2892 2899 pairsList.append(pairx)
2893 2900 pairsList.append(pairy)
2894 2901
2895 2902 jph = numpy.array([0,0,0,0])
2896 2903 h = (hmin,hmax)
2897 2904 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2898 2905
2899 2906 # #Calculate AOA (Error N 3, 4)
2900 2907 # #JONES ET AL. 1998
2901 2908 # error = arrayParameters[:,-1]
2902 2909 # AOAthresh = numpy.pi/8
2903 2910 # phases = -arrayParameters[:,9:13]
2904 2911 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
2905 2912 #
2906 2913 # #Calculate Heights (Error N 13 and 14)
2907 2914 # error = arrayParameters[:,-1]
2908 2915 # Ranges = arrayParameters[:,2]
2909 2916 # zenith = arrayParameters[:,5]
2910 2917 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
2911 2918 # error = arrayParameters[:,-1]
2912 2919 #********************* END OF PARAMETERS CALCULATION **************************
2913 2920
2914 2921 #***************************+ PASS DATA TO NEXT STEP **********************
2915 2922 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
2916 2923 dataOut.data_param = arrayParameters
2917 2924
2918 2925 if arrayParameters == None:
2919 2926 dataOut.flagNoData = True
2920 2927 else:
2921 2928 dataOut.flagNoData = True
2922 2929
2923 2930 return
2924 2931
2925 2932 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
2926 2933
2927 2934 minIndex = min(newheis[0])
2928 2935 maxIndex = max(newheis[0])
2929 2936
2930 2937 voltage = voltage0[:,:,minIndex:maxIndex+1]
2931 2938 nLength = voltage.shape[1]/n
2932 2939 nMin = 0
2933 2940 nMax = 0
2934 2941 phaseOffset = numpy.zeros((len(pairslist),n))
2935 2942
2936 2943 for i in range(n):
2937 2944 nMax += nLength
2938 2945 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
2939 2946 phaseCCF = numpy.mean(phaseCCF, axis = 2)
2940 2947 phaseOffset[:,i] = phaseCCF.transpose()
2941 2948 nMin = nMax
2942 2949 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
2943 2950
2944 2951 #Remove Outliers
2945 2952 factor = 2
2946 2953 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
2947 2954 dw = numpy.std(wt,axis = 1)
2948 2955 dw = dw.reshape((dw.size,1))
2949 2956 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
2950 2957 phaseOffset[ind] = numpy.nan
2951 2958 phaseOffset = stats.nanmean(phaseOffset, axis=1)
2952 2959
2953 2960 return phaseOffset
2954 2961
2955 2962 def __shiftPhase(self, data, phaseShift):
2956 2963 #this will shift the phase of a complex number
2957 2964 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
2958 2965 return dataShifted
2959 2966
2960 2967 def __estimatePhaseDifference(self, array, pairslist):
2961 2968 nChannel = array.shape[0]
2962 2969 nHeights = array.shape[2]
2963 2970 numPairs = len(pairslist)
2964 2971 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
2965 2972 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
2966 2973
2967 2974 #Correct phases
2968 2975 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
2969 2976 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2970 2977
2971 2978 if indDer[0].shape[0] > 0:
2972 2979 for i in range(indDer[0].shape[0]):
2973 2980 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
2974 2981 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
2975 2982
2976 2983 # for j in range(numSides):
2977 2984 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
2978 2985 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
2979 2986 #
2980 2987 #Linear
2981 2988 phaseInt = numpy.zeros((numPairs,1))
2982 2989 angAllCCF = phaseCCF[:,[0,1,3,4],0]
2983 2990 for j in range(numPairs):
2984 2991 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
2985 2992 phaseInt[j] = fit[1]
2986 2993 #Phase Differences
2987 2994 phaseDiff = phaseInt - phaseCCF[:,2,:]
2988 2995 phaseArrival = phaseInt.reshape(phaseInt.size)
2989 2996
2990 2997 #Dealias
2991 2998 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
2992 2999 # indAlias = numpy.where(phaseArrival > numpy.pi)
2993 3000 # phaseArrival[indAlias] -= 2*numpy.pi
2994 3001 # indAlias = numpy.where(phaseArrival < -numpy.pi)
2995 3002 # phaseArrival[indAlias] += 2*numpy.pi
2996 3003
2997 3004 return phaseDiff, phaseArrival
2998 3005
2999 3006 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
3000 3007 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
3001 3008 #find the phase shifts of each channel over 1 second intervals
3002 3009 #only look at ranges below the beacon signal
3003 3010 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
3004 3011 numBlocks = int(volts.shape[1]/numProfPerBlock)
3005 3012 numHeights = volts.shape[2]
3006 3013 nChannel = volts.shape[0]
3007 3014 voltsCohDet = volts.copy()
3008 3015
3009 3016 pairsarray = numpy.array(pairslist)
3010 3017 indSides = pairsarray[:,1]
3011 3018 # indSides = numpy.array(range(nChannel))
3012 3019 # indSides = numpy.delete(indSides, indCenter)
3013 3020 #
3014 3021 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
3015 3022 listBlocks = numpy.array_split(volts, numBlocks, 1)
3016 3023
3017 3024 startInd = 0
3018 3025 endInd = 0
3019 3026
3020 3027 for i in range(numBlocks):
3021 3028 startInd = endInd
3022 3029 endInd = endInd + listBlocks[i].shape[1]
3023 3030
3024 3031 arrayBlock = listBlocks[i]
3025 3032 # arrayBlockCenter = listCenter[i]
3026 3033
3027 3034 #Estimate the Phase Difference
3028 3035 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
3029 3036 #Phase Difference RMS
3030 3037 arrayPhaseRMS = numpy.abs(phaseDiff)
3031 3038 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
3032 3039 indPhase = numpy.where(phaseRMSaux==4)
3033 3040 #Shifting
3034 3041 if indPhase[0].shape[0] > 0:
3035 3042 for j in range(indSides.size):
3036 3043 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
3037 3044 voltsCohDet[:,startInd:endInd,:] = arrayBlock
3038 3045
3039 3046 return voltsCohDet
3040 3047
3041 3048 def __calculateCCF(self, volts, pairslist ,laglist):
3042 3049
3043 3050 nHeights = volts.shape[2]
3044 3051 nPoints = volts.shape[1]
3045 3052 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
3046 3053
3047 3054 for i in range(len(pairslist)):
3048 3055 volts1 = volts[pairslist[i][0]]
3049 3056 volts2 = volts[pairslist[i][1]]
3050 3057
3051 3058 for t in range(len(laglist)):
3052 3059 idxT = laglist[t]
3053 3060 if idxT >= 0:
3054 3061 vStacked = numpy.vstack((volts2[idxT:,:],
3055 3062 numpy.zeros((idxT, nHeights),dtype='complex')))
3056 3063 else:
3057 3064 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
3058 3065 volts2[:(nPoints + idxT),:]))
3059 3066 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
3060 3067
3061 3068 vStacked = None
3062 3069 return voltsCCF
3063 3070
3064 3071 def __getNoise(self, power, timeSegment, timeInterval):
3065 3072 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
3066 3073 numBlocks = int(power.shape[0]/numProfPerBlock)
3067 3074 numHeights = power.shape[1]
3068 3075
3069 3076 listPower = numpy.array_split(power, numBlocks, 0)
3070 3077 noise = numpy.zeros((power.shape[0], power.shape[1]))
3071 3078 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
3072 3079
3073 3080 startInd = 0
3074 3081 endInd = 0
3075 3082
3076 3083 for i in range(numBlocks): #split por canal
3077 3084 startInd = endInd
3078 3085 endInd = endInd + listPower[i].shape[0]
3079 3086
3080 3087 arrayBlock = listPower[i]
3081 3088 noiseAux = numpy.mean(arrayBlock, 0)
3082 3089 # noiseAux = numpy.median(noiseAux)
3083 3090 # noiseAux = numpy.mean(arrayBlock)
3084 3091 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
3085 3092
3086 3093 noiseAux1 = numpy.mean(arrayBlock)
3087 3094 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
3088 3095
3089 3096 return noise, noise1
3090 3097
3091 3098 def __findMeteors(self, power, thresh):
3092 3099 nProf = power.shape[0]
3093 3100 nHeights = power.shape[1]
3094 3101 listMeteors = []
3095 3102
3096 3103 for i in range(nHeights):
3097 3104 powerAux = power[:,i]
3098 3105 threshAux = thresh[:,i]
3099 3106
3100 3107 indUPthresh = numpy.where(powerAux > threshAux)[0]
3101 3108 indDNthresh = numpy.where(powerAux <= threshAux)[0]
3102 3109
3103 3110 j = 0
3104 3111
3105 3112 while (j < indUPthresh.size - 2):
3106 3113 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
3107 3114 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
3108 3115 indDNthresh = indDNthresh[indDNAux]
3109 3116
3110 3117 if (indDNthresh.size > 0):
3111 3118 indEnd = indDNthresh[0] - 1
3112 3119 indInit = indUPthresh[j]
3113 3120
3114 3121 meteor = powerAux[indInit:indEnd + 1]
3115 3122 indPeak = meteor.argmax() + indInit
3116 3123 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
3117 3124
3118 3125 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
3119 3126 j = numpy.where(indUPthresh == indEnd)[0] + 1
3120 3127 else: j+=1
3121 3128 else: j+=1
3122 3129
3123 3130 return listMeteors
3124 3131
3125 3132 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
3126 3133
3127 3134 arrayMeteors = numpy.asarray(listMeteors)
3128 3135 listMeteors1 = []
3129 3136
3130 3137 while arrayMeteors.shape[0] > 0:
3131 3138 FLAs = arrayMeteors[:,4]
3132 3139 maxFLA = FLAs.argmax()
3133 3140 listMeteors1.append(arrayMeteors[maxFLA,:])
3134 3141
3135 3142 MeteorInitTime = arrayMeteors[maxFLA,1]
3136 3143 MeteorEndTime = arrayMeteors[maxFLA,3]
3137 3144 MeteorHeight = arrayMeteors[maxFLA,0]
3138 3145
3139 3146 #Check neighborhood
3140 3147 maxHeightIndex = MeteorHeight + rangeLimit
3141 3148 minHeightIndex = MeteorHeight - rangeLimit
3142 3149 minTimeIndex = MeteorInitTime - timeLimit
3143 3150 maxTimeIndex = MeteorEndTime + timeLimit
3144 3151
3145 3152 #Check Heights
3146 3153 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
3147 3154 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
3148 3155 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
3149 3156
3150 3157 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
3151 3158
3152 3159 return listMeteors1
3153 3160
3154 3161 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
3155 3162 numHeights = volts.shape[2]
3156 3163 nChannel = volts.shape[0]
3157 3164
3158 3165 thresholdPhase = thresh[0]
3159 3166 thresholdNoise = thresh[1]
3160 3167 thresholdDB = float(thresh[2])
3161 3168
3162 3169 thresholdDB1 = 10**(thresholdDB/10)
3163 3170 pairsarray = numpy.array(pairslist)
3164 3171 indSides = pairsarray[:,1]
3165 3172
3166 3173 pairslist1 = list(pairslist)
3167 3174 pairslist1.append((0,1))
3168 3175 pairslist1.append((3,4))
3169 3176
3170 3177 listMeteors1 = []
3171 3178 listPowerSeries = []
3172 3179 listVoltageSeries = []
3173 3180 #volts has the war data
3174 3181
3175 3182 if frequency == 30e6:
3176 3183 timeLag = 45*10**-3
3177 3184 else:
3178 3185 timeLag = 15*10**-3
3179 3186 lag = numpy.ceil(timeLag/timeInterval)
3180 3187
3181 3188 for i in range(len(listMeteors)):
3182 3189
3183 3190 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
3184 3191 meteorAux = numpy.zeros(16)
3185 3192
3186 3193 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
3187 3194 mHeight = listMeteors[i][0]
3188 3195 mStart = listMeteors[i][1]
3189 3196 mPeak = listMeteors[i][2]
3190 3197 mEnd = listMeteors[i][3]
3191 3198
3192 3199 #get the volt data between the start and end times of the meteor
3193 3200 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
3194 3201 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3195 3202
3196 3203 #3.6. Phase Difference estimation
3197 3204 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
3198 3205
3199 3206 #3.7. Phase difference removal & meteor start, peak and end times reestimated
3200 3207 #meteorVolts0.- all Channels, all Profiles
3201 3208 meteorVolts0 = volts[:,:,mHeight]
3202 3209 meteorThresh = noise[:,mHeight]*thresholdNoise
3203 3210 meteorNoise = noise[:,mHeight]
3204 3211 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
3205 3212 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
3206 3213
3207 3214 #Times reestimation
3208 3215 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
3209 3216 if mStart1.size > 0:
3210 3217 mStart1 = mStart1[-1] + 1
3211 3218
3212 3219 else:
3213 3220 mStart1 = mPeak
3214 3221
3215 3222 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
3216 3223 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
3217 3224 if mEndDecayTime1.size == 0:
3218 3225 mEndDecayTime1 = powerNet0.size
3219 3226 else:
3220 3227 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
3221 3228 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
3222 3229
3223 3230 #meteorVolts1.- all Channels, from start to end
3224 3231 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
3225 3232 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
3226 3233 if meteorVolts2.shape[1] == 0:
3227 3234 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
3228 3235 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
3229 3236 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
3230 3237 ##################### END PARAMETERS REESTIMATION #########################
3231 3238
3232 3239 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
3233 3240 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
3234 3241 if meteorVolts2.shape[1] > 0:
3235 3242 #Phase Difference re-estimation
3236 3243 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
3237 3244 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
3238 3245 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
3239 3246 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
3240 3247 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
3241 3248
3242 3249 #Phase Difference RMS
3243 3250 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
3244 3251 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
3245 3252 #Data from Meteor
3246 3253 mPeak1 = powerNet1.argmax() + mStart1
3247 3254 mPeakPower1 = powerNet1.max()
3248 3255 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
3249 3256 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
3250 3257 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
3251 3258 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
3252 3259 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
3253 3260 #Vectorize
3254 3261 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
3255 3262 meteorAux[7:11] = phaseDiffint[0:4]
3256 3263
3257 3264 #Rejection Criterions
3258 3265 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
3259 3266 meteorAux[-1] = 17
3260 3267 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
3261 3268 meteorAux[-1] = 1
3262 3269
3263 3270
3264 3271 else:
3265 3272 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
3266 3273 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
3267 3274 PowerSeries = 0
3268 3275
3269 3276 listMeteors1.append(meteorAux)
3270 3277 listPowerSeries.append(PowerSeries)
3271 3278 listVoltageSeries.append(meteorVolts1)
3272 3279
3273 3280 return listMeteors1, listPowerSeries, listVoltageSeries
3274 3281
3275 3282 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
3276 3283
3277 3284 threshError = 10
3278 3285 #Depending if it is 30 or 50 MHz
3279 3286 if frequency == 30e6:
3280 3287 timeLag = 45*10**-3
3281 3288 else:
3282 3289 timeLag = 15*10**-3
3283 3290 lag = numpy.ceil(timeLag/timeInterval)
3284 3291
3285 3292 listMeteors1 = []
3286 3293
3287 3294 for i in range(len(listMeteors)):
3288 3295 meteorPower = listPower[i]
3289 3296 meteorAux = listMeteors[i]
3290 3297
3291 3298 if meteorAux[-1] == 0:
3292 3299
3293 3300 try:
3294 3301 indmax = meteorPower.argmax()
3295 3302 indlag = indmax + lag
3296 3303
3297 3304 y = meteorPower[indlag:]
3298 3305 x = numpy.arange(0, y.size)*timeLag
3299 3306
3300 3307 #first guess
3301 3308 a = y[0]
3302 3309 tau = timeLag
3303 3310 #exponential fit
3304 3311 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
3305 3312 y1 = self.__exponential_function(x, *popt)
3306 3313 #error estimation
3307 3314 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
3308 3315
3309 3316 decayTime = popt[1]
3310 3317 riseTime = indmax*timeInterval
3311 3318 meteorAux[11:13] = [decayTime, error]
3312 3319
3313 3320 #Table items 7, 8 and 11
3314 3321 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
3315 3322 meteorAux[-1] = 7
3316 3323 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
3317 3324 meteorAux[-1] = 8
3318 3325 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
3319 3326 meteorAux[-1] = 11
3320 3327
3321 3328
3322 3329 except:
3323 3330 meteorAux[-1] = 11
3324 3331
3325 3332
3326 3333 listMeteors1.append(meteorAux)
3327 3334
3328 3335 return listMeteors1
3329 3336
3330 3337 #Exponential Function
3331 3338
3332 3339 def __exponential_function(self, x, a, tau):
3333 3340 y = a*numpy.exp(-x/tau)
3334 3341 return y
3335 3342
3336 3343 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
3337 3344
3338 3345 pairslist1 = list(pairslist)
3339 3346 pairslist1.append((0,1))
3340 3347 pairslist1.append((3,4))
3341 3348 numPairs = len(pairslist1)
3342 3349 #Time Lag
3343 3350 timeLag = 45*10**-3
3344 3351 c = 3e8
3345 3352 lag = numpy.ceil(timeLag/timeInterval)
3346 3353 freq = 30e6
3347 3354
3348 3355 listMeteors1 = []
3349 3356
3350 3357 for i in range(len(listMeteors)):
3351 3358 meteorAux = listMeteors[i]
3352 3359 if meteorAux[-1] == 0:
3353 3360 mStart = listMeteors[i][1]
3354 3361 mPeak = listMeteors[i][2]
3355 3362 mLag = mPeak - mStart + lag
3356 3363
3357 3364 #get the volt data between the start and end times of the meteor
3358 3365 meteorVolts = listVolts[i]
3359 3366 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3360 3367
3361 3368 #Get CCF
3362 3369 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
3363 3370
3364 3371 #Method 2
3365 3372 slopes = numpy.zeros(numPairs)
3366 3373 time = numpy.array([-2,-1,1,2])*timeInterval
3367 3374 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
3368 3375
3369 3376 #Correct phases
3370 3377 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
3371 3378 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
3372 3379
3373 3380 if indDer[0].shape[0] > 0:
3374 3381 for i in range(indDer[0].shape[0]):
3375 3382 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
3376 3383 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
3377 3384
3378 3385 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
3379 3386 for j in range(numPairs):
3380 3387 fit = stats.linregress(time, angAllCCF[j,:])
3381 3388 slopes[j] = fit[0]
3382 3389
3383 3390 #Remove Outlier
3384 3391 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3385 3392 # slopes = numpy.delete(slopes,indOut)
3386 3393 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3387 3394 # slopes = numpy.delete(slopes,indOut)
3388 3395
3389 3396 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
3390 3397 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
3391 3398 meteorAux[-2] = radialError
3392 3399 meteorAux[-3] = radialVelocity
3393 3400
3394 3401 #Setting Error
3395 3402 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
3396 3403 if numpy.abs(radialVelocity) > 200:
3397 3404 meteorAux[-1] = 15
3398 3405 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
3399 3406 elif radialError > radialStdThresh:
3400 3407 meteorAux[-1] = 12
3401 3408
3402 3409 listMeteors1.append(meteorAux)
3403 3410 return listMeteors1
3404 3411
3405 3412 def __setNewArrays(self, listMeteors, date, heiRang):
3406 3413
3407 3414 #New arrays
3408 3415 arrayMeteors = numpy.array(listMeteors)
3409 3416 arrayParameters = numpy.zeros((len(listMeteors), 13))
3410 3417
3411 3418 #Date inclusion
3412 3419 # date = re.findall(r'\((.*?)\)', date)
3413 3420 # date = date[0].split(',')
3414 3421 # date = map(int, date)
3415 3422 #
3416 3423 # if len(date)<6:
3417 3424 # date.append(0)
3418 3425 #
3419 3426 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
3420 3427 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
3421 3428 arrayDate = numpy.tile(date, (len(listMeteors)))
3422 3429
3423 3430 #Meteor array
3424 3431 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
3425 3432 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
3426 3433
3427 3434 #Parameters Array
3428 3435 arrayParameters[:,0] = arrayDate #Date
3429 3436 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
3430 3437 arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
3431 3438 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
3432 3439 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
3433 3440
3434 3441
3435 3442 return arrayParameters
3436 3443
3437 3444 class CorrectSMPhases(Operation):
3438 3445
3439 3446 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
3440 3447
3441 3448 arrayParameters = dataOut.data_param
3442 3449 pairsList = []
3443 3450 pairx = (0,1)
3444 3451 pairy = (2,3)
3445 3452 pairsList.append(pairx)
3446 3453 pairsList.append(pairy)
3447 3454 jph = numpy.zeros(4)
3448 3455
3449 3456 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
3450 3457 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
3451 3458 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
3452 3459
3453 3460 meteorOps = SMOperations()
3454 3461 if channelPositions == None:
3455 3462 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3456 3463 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3457 3464
3458 3465 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3459 3466 h = (hmin,hmax)
3460 3467
3461 3468 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
3462 3469
3463 3470 dataOut.data_param = arrayParameters
3464 3471 return
3465 3472
3466 3473 class SMPhaseCalibration(Operation):
3467 3474
3468 3475 __buffer = None
3469 3476
3470 3477 __initime = None
3471 3478
3472 3479 __dataReady = False
3473 3480
3474 3481 __isConfig = False
3475 3482
3476 3483 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
3477 3484
3478 3485 dataTime = currentTime + paramInterval
3479 3486 deltaTime = dataTime - initTime
3480 3487
3481 3488 if deltaTime >= outputInterval or deltaTime < 0:
3482 3489 return True
3483 3490
3484 3491 return False
3485 3492
3486 3493 def __getGammas(self, pairs, d, phases):
3487 3494 gammas = numpy.zeros(2)
3488 3495
3489 3496 for i in range(len(pairs)):
3490 3497
3491 3498 pairi = pairs[i]
3492 3499
3493 3500 phip3 = phases[:,pairi[1]]
3494 3501 d3 = d[pairi[1]]
3495 3502 phip2 = phases[:,pairi[0]]
3496 3503 d2 = d[pairi[0]]
3497 3504 #Calculating gamma
3498 3505 # jdcos = alp1/(k*d1)
3499 3506 # jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0)))
3500 3507 jgamma = -phip2*d3/d2 - phip3
3501 3508 jgamma = numpy.angle(numpy.exp(1j*jgamma))
3502 3509 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
3503 3510 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
3504 3511
3505 3512 #Revised distribution
3506 3513 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
3507 3514
3508 3515 #Histogram
3509 3516 nBins = 64.0
3510 3517 rmin = -0.5*numpy.pi
3511 3518 rmax = 0.5*numpy.pi
3512 3519 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
3513 3520
3514 3521 meteorsY = phaseHisto[0]
3515 3522 phasesX = phaseHisto[1][:-1]
3516 3523 width = phasesX[1] - phasesX[0]
3517 3524 phasesX += width/2
3518 3525
3519 3526 #Gaussian aproximation
3520 3527 bpeak = meteorsY.argmax()
3521 3528 peak = meteorsY.max()
3522 3529 jmin = bpeak - 5
3523 3530 jmax = bpeak + 5 + 1
3524 3531
3525 3532 if jmin<0:
3526 3533 jmin = 0
3527 3534 jmax = 6
3528 3535 elif jmax > meteorsY.size:
3529 3536 jmin = meteorsY.size - 6
3530 3537 jmax = meteorsY.size
3531 3538
3532 3539 x0 = numpy.array([peak,bpeak,50])
3533 3540 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
3534 3541
3535 3542 #Gammas
3536 3543 gammas[i] = coeff[0][1]
3537 3544
3538 3545 return gammas
3539 3546
3540 3547 def __residualFunction(self, coeffs, y, t):
3541 3548
3542 3549 return y - self.__gauss_function(t, coeffs)
3543 3550
3544 3551 def __gauss_function(self, t, coeffs):
3545 3552
3546 3553 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
3547 3554
3548 3555 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
3549 3556 meteorOps = SMOperations()
3550 3557 nchan = 4
3551 3558 pairx = pairsList[0]
3552 3559 pairy = pairsList[1]
3553 3560 center_xangle = 0
3554 3561 center_yangle = 0
3555 3562 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
3556 3563 ntimes = len(range_angle)
3557 3564
3558 3565 nstepsx = 20.0
3559 3566 nstepsy = 20.0
3560 3567
3561 3568 for iz in range(ntimes):
3562 3569 min_xangle = -range_angle[iz]/2 + center_xangle
3563 3570 max_xangle = range_angle[iz]/2 + center_xangle
3564 3571 min_yangle = -range_angle[iz]/2 + center_yangle
3565 3572 max_yangle = range_angle[iz]/2 + center_yangle
3566 3573
3567 3574 inc_x = (max_xangle-min_xangle)/nstepsx
3568 3575 inc_y = (max_yangle-min_yangle)/nstepsy
3569 3576
3570 3577 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
3571 3578 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
3572 3579 penalty = numpy.zeros((nstepsx,nstepsy))
3573 3580 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
3574 3581 jph = numpy.zeros(nchan)
3575 3582
3576 3583 # Iterations looking for the offset
3577 3584 for iy in range(int(nstepsy)):
3578 3585 for ix in range(int(nstepsx)):
3579 3586 jph[pairy[1]] = alpha_y[iy]
3580 3587 jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
3581 3588
3582 3589 jph[pairx[1]] = alpha_x[ix]
3583 3590 jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
3584 3591
3585 3592 jph_array[:,ix,iy] = jph
3586 3593
3587 3594 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
3588 3595 error = meteorsArray1[:,-1]
3589 3596 ind1 = numpy.where(error==0)[0]
3590 3597 penalty[ix,iy] = ind1.size
3591 3598
3592 3599 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
3593 3600 phOffset = jph_array[:,i,j]
3594 3601
3595 3602 center_xangle = phOffset[pairx[1]]
3596 3603 center_yangle = phOffset[pairy[1]]
3597 3604
3598 3605 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
3599 3606 phOffset = phOffset*180/numpy.pi
3600 3607 return phOffset
3601 3608
3602 3609
3603 3610 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
3604 3611
3605 3612 dataOut.flagNoData = True
3606 3613 self.__dataReady = False
3607 3614 dataOut.outputInterval = nHours*3600
3608 3615
3609 3616 if self.__isConfig == False:
3610 3617 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
3611 3618 #Get Initial LTC time
3612 3619 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
3613 3620 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
3614 3621
3615 3622 self.__isConfig = True
3616 3623
3617 3624 if self.__buffer == None:
3618 3625 self.__buffer = dataOut.data_param.copy()
3619 3626
3620 3627 else:
3621 3628 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
3622 3629
3623 3630 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
3624 3631
3625 3632 if self.__dataReady:
3626 3633 dataOut.utctimeInit = self.__initime
3627 3634 self.__initime += dataOut.outputInterval #to erase time offset
3628 3635
3629 3636 freq = dataOut.frequency
3630 3637 c = dataOut.C #m/s
3631 3638 lamb = c/freq
3632 3639 k = 2*numpy.pi/lamb
3633 3640 azimuth = 0
3634 3641 h = (hmin, hmax)
3635 3642 pairs = ((0,1),(2,3))
3636 3643
3637 3644 if channelPositions == None:
3638 3645 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3639 3646 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3640 3647 meteorOps = SMOperations()
3641 3648 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3642 3649
3643 3650 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
3644 3651
3645 3652 meteorsArray = self.__buffer
3646 3653 error = meteorsArray[:,-1]
3647 3654 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
3648 3655 ind1 = numpy.where(boolError)[0]
3649 3656 meteorsArray = meteorsArray[ind1,:]
3650 3657 meteorsArray[:,-1] = 0
3651 3658 phases = meteorsArray[:,8:12]
3652 3659
3653 3660 #Calculate Gammas
3654 3661 gammas = self.__getGammas(pairs, distances, phases)
3655 3662 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
3656 3663 #Calculate Phases
3657 3664 phasesOff = self.__getPhases(azimuth, h, pairs, distances, gammas, meteorsArray)
3658 3665 phasesOff = phasesOff.reshape((1,phasesOff.size))
3659 3666 dataOut.data_output = -phasesOff
3660 3667 dataOut.flagNoData = False
3661 3668 self.__buffer = None
3662 3669
3663 3670
3664 3671 return
3665 3672
3666 3673 class SMOperations():
3667 3674
3668 3675 def __init__(self):
3669 3676
3670 3677 return
3671 3678
3672 3679 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
3673 3680
3674 3681 arrayParameters = arrayParameters0.copy()
3675 3682 hmin = h[0]
3676 3683 hmax = h[1]
3677 3684
3678 3685 #Calculate AOA (Error N 3, 4)
3679 3686 #JONES ET AL. 1998
3680 3687 AOAthresh = numpy.pi/8
3681 3688 error = arrayParameters[:,-1]
3682 3689 phases = -arrayParameters[:,8:12] + jph
3683 3690 # phases = numpy.unwrap(phases)
3684 3691 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
3685 3692
3686 3693 #Calculate Heights (Error N 13 and 14)
3687 3694 error = arrayParameters[:,-1]
3688 3695 Ranges = arrayParameters[:,1]
3689 3696 zenith = arrayParameters[:,4]
3690 3697 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
3691 3698
3692 3699 #----------------------- Get Final data ------------------------------------
3693 3700 # error = arrayParameters[:,-1]
3694 3701 # ind1 = numpy.where(error==0)[0]
3695 3702 # arrayParameters = arrayParameters[ind1,:]
3696 3703
3697 3704 return arrayParameters
3698 3705
3699 3706 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
3700 3707
3701 3708 arrayAOA = numpy.zeros((phases.shape[0],3))
3702 3709 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
3703 3710
3704 3711 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3705 3712 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3706 3713 arrayAOA[:,2] = cosDirError
3707 3714
3708 3715 azimuthAngle = arrayAOA[:,0]
3709 3716 zenithAngle = arrayAOA[:,1]
3710 3717
3711 3718 #Setting Error
3712 3719 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
3713 3720 error[indError] = 0
3714 3721 #Number 3: AOA not fesible
3715 3722 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3716 3723 error[indInvalid] = 3
3717 3724 #Number 4: Large difference in AOAs obtained from different antenna baselines
3718 3725 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3719 3726 error[indInvalid] = 4
3720 3727 return arrayAOA, error
3721 3728
3722 3729 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
3723 3730
3724 3731 #Initializing some variables
3725 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
3726 3733 ang_aux = ang_aux.reshape(1,ang_aux.size)
3727 3734
3728 3735 cosdir = numpy.zeros((arrayPhase.shape[0],2))
3729 3736 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3730 3737
3731 3738
3732 3739 for i in range(2):
3733 3740 ph0 = arrayPhase[:,pairsList[i][0]]
3734 3741 ph1 = arrayPhase[:,pairsList[i][1]]
3735 3742 d0 = distances[pairsList[i][0]]
3736 3743 d1 = distances[pairsList[i][1]]
3737 3744
3738 3745 ph0_aux = ph0 + ph1
3739 3746 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
3740 3747 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
3741 3748 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
3742 3749 #First Estimation
3743 3750 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
3744 3751
3745 3752 #Most-Accurate Second Estimation
3746 3753 phi1_aux = ph0 - ph1
3747 3754 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3748 3755 #Direction Cosine 1
3749 3756 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
3750 3757
3751 3758 #Searching the correct Direction Cosine
3752 3759 cosdir0_aux = cosdir0[:,i]
3753 3760 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3754 3761 #Minimum Distance
3755 3762 cosDiff = (cosdir1 - cosdir0_aux)**2
3756 3763 indcos = cosDiff.argmin(axis = 1)
3757 3764 #Saving Value obtained
3758 3765 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3759 3766
3760 3767 return cosdir0, cosdir
3761 3768
3762 3769 def __calculateAOA(self, cosdir, azimuth):
3763 3770 cosdirX = cosdir[:,0]
3764 3771 cosdirY = cosdir[:,1]
3765 3772
3766 3773 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3767 3774 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
3768 3775 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3769 3776
3770 3777 return angles
3771 3778
3772 3779 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3773 3780
3774 3781 Ramb = 375 #Ramb = c/(2*PRF)
3775 3782 Re = 6371 #Earth Radius
3776 3783 heights = numpy.zeros(Ranges.shape)
3777 3784
3778 3785 R_aux = numpy.array([0,1,2])*Ramb
3779 3786 R_aux = R_aux.reshape(1,R_aux.size)
3780 3787
3781 3788 Ranges = Ranges.reshape(Ranges.size,1)
3782 3789
3783 3790 Ri = Ranges + R_aux
3784 3791 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3785 3792
3786 3793 #Check if there is a height between 70 and 110 km
3787 3794 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3788 3795 ind_h = numpy.where(h_bool == 1)[0]
3789 3796
3790 3797 hCorr = hi[ind_h, :]
3791 3798 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3792 3799
3793 3800 hCorr = hi[ind_hCorr]
3794 3801 heights[ind_h] = hCorr
3795 3802
3796 3803 #Setting Error
3797 3804 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3798 3805 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3799 3806 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
3800 3807 error[indError] = 0
3801 3808 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3802 3809 error[indInvalid2] = 14
3803 3810 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3804 3811 error[indInvalid1] = 13
3805 3812
3806 3813 return heights, error
3807 3814
3808 3815 def getPhasePairs(self, channelPositions):
3809 3816 chanPos = numpy.array(channelPositions)
3810 3817 listOper = list(itertools.combinations(range(5),2))
3811 3818
3812 3819 distances = numpy.zeros(4)
3813 3820 axisX = []
3814 3821 axisY = []
3815 3822 distX = numpy.zeros(3)
3816 3823 distY = numpy.zeros(3)
3817 3824 ix = 0
3818 3825 iy = 0
3819 3826
3820 3827 pairX = numpy.zeros((2,2))
3821 3828 pairY = numpy.zeros((2,2))
3822 3829
3823 3830 for i in range(len(listOper)):
3824 3831 pairi = listOper[i]
3825 3832
3826 3833 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
3827 3834
3828 3835 if posDif[0] == 0:
3829 3836 axisY.append(pairi)
3830 3837 distY[iy] = posDif[1]
3831 3838 iy += 1
3832 3839 elif posDif[1] == 0:
3833 3840 axisX.append(pairi)
3834 3841 distX[ix] = posDif[0]
3835 3842 ix += 1
3836 3843
3837 3844 for i in range(2):
3838 3845 if i==0:
3839 3846 dist0 = distX
3840 3847 axis0 = axisX
3841 3848 else:
3842 3849 dist0 = distY
3843 3850 axis0 = axisY
3844 3851
3845 3852 side = numpy.argsort(dist0)[:-1]
3846 3853 axis0 = numpy.array(axis0)[side,:]
3847 3854 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
3848 3855 axis1 = numpy.unique(numpy.reshape(axis0,4))
3849 3856 side = axis1[axis1 != chanC]
3850 3857 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
3851 3858 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
3852 3859 if diff1<0:
3853 3860 chan2 = side[0]
3854 3861 d2 = numpy.abs(diff1)
3855 3862 chan1 = side[1]
3856 3863 d1 = numpy.abs(diff2)
3857 3864 else:
3858 3865 chan2 = side[1]
3859 3866 d2 = numpy.abs(diff2)
3860 3867 chan1 = side[0]
3861 3868 d1 = numpy.abs(diff1)
3862 3869
3863 3870 if i==0:
3864 3871 chanCX = chanC
3865 3872 chan1X = chan1
3866 3873 chan2X = chan2
3867 3874 distances[0:2] = numpy.array([d1,d2])
3868 3875 else:
3869 3876 chanCY = chanC
3870 3877 chan1Y = chan1
3871 3878 chan2Y = chan2
3872 3879 distances[2:4] = numpy.array([d1,d2])
3873 3880 # axisXsides = numpy.reshape(axisX[ix,:],4)
3874 3881 #
3875 3882 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
3876 3883 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
3877 3884 #
3878 3885 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
3879 3886 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
3880 3887 # channel25X = int(pairX[0,ind25X])
3881 3888 # channel20X = int(pairX[1,ind20X])
3882 3889 # ind25Y = numpy.where(pairY[0,:] != channelCentY)[0][0]
3883 3890 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
3884 3891 # channel25Y = int(pairY[0,ind25Y])
3885 3892 # channel20Y = int(pairY[1,ind20Y])
3886 3893
3887 3894 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
3888 3895 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
3889 3896
3890 3897 return pairslist, distances
3891 3898 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
3892 3899 #
3893 3900 # arrayAOA = numpy.zeros((phases.shape[0],3))
3894 3901 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
3895 3902 #
3896 3903 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3897 3904 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3898 3905 # arrayAOA[:,2] = cosDirError
3899 3906 #
3900 3907 # azimuthAngle = arrayAOA[:,0]
3901 3908 # zenithAngle = arrayAOA[:,1]
3902 3909 #
3903 3910 # #Setting Error
3904 3911 # #Number 3: AOA not fesible
3905 3912 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3906 3913 # error[indInvalid] = 3
3907 3914 # #Number 4: Large difference in AOAs obtained from different antenna baselines
3908 3915 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3909 3916 # error[indInvalid] = 4
3910 3917 # return arrayAOA, error
3911 3918 #
3912 3919 # def __getDirectionCosines(self, arrayPhase, pairsList):
3913 3920 #
3914 3921 # #Initializing some variables
3915 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
3916 3923 # ang_aux = ang_aux.reshape(1,ang_aux.size)
3917 3924 #
3918 3925 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
3919 3926 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3920 3927 #
3921 3928 #
3922 3929 # for i in range(2):
3923 3930 # #First Estimation
3924 3931 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
3925 3932 # #Dealias
3926 3933 # indcsi = numpy.where(phi0_aux > numpy.pi)
3927 3934 # phi0_aux[indcsi] -= 2*numpy.pi
3928 3935 # indcsi = numpy.where(phi0_aux < -numpy.pi)
3929 3936 # phi0_aux[indcsi] += 2*numpy.pi
3930 3937 # #Direction Cosine 0
3931 3938 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
3932 3939 #
3933 3940 # #Most-Accurate Second Estimation
3934 3941 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
3935 3942 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3936 3943 # #Direction Cosine 1
3937 3944 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
3938 3945 #
3939 3946 # #Searching the correct Direction Cosine
3940 3947 # cosdir0_aux = cosdir0[:,i]
3941 3948 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3942 3949 # #Minimum Distance
3943 3950 # cosDiff = (cosdir1 - cosdir0_aux)**2
3944 3951 # indcos = cosDiff.argmin(axis = 1)
3945 3952 # #Saving Value obtained
3946 3953 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3947 3954 #
3948 3955 # return cosdir0, cosdir
3949 3956 #
3950 3957 # def __calculateAOA(self, cosdir, azimuth):
3951 3958 # cosdirX = cosdir[:,0]
3952 3959 # cosdirY = cosdir[:,1]
3953 3960 #
3954 3961 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3955 3962 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
3956 3963 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3957 3964 #
3958 3965 # return angles
3959 3966 #
3960 3967 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3961 3968 #
3962 3969 # Ramb = 375 #Ramb = c/(2*PRF)
3963 3970 # Re = 6371 #Earth Radius
3964 3971 # heights = numpy.zeros(Ranges.shape)
3965 3972 #
3966 3973 # R_aux = numpy.array([0,1,2])*Ramb
3967 3974 # R_aux = R_aux.reshape(1,R_aux.size)
3968 3975 #
3969 3976 # Ranges = Ranges.reshape(Ranges.size,1)
3970 3977 #
3971 3978 # Ri = Ranges + R_aux
3972 3979 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3973 3980 #
3974 3981 # #Check if there is a height between 70 and 110 km
3975 3982 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3976 3983 # ind_h = numpy.where(h_bool == 1)[0]
3977 3984 #
3978 3985 # hCorr = hi[ind_h, :]
3979 3986 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3980 3987 #
3981 3988 # hCorr = hi[ind_hCorr]
3982 3989 # heights[ind_h] = hCorr
3983 3990 #
3984 3991 # #Setting Error
3985 3992 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3986 3993 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3987 3994 #
3988 3995 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3989 3996 # error[indInvalid2] = 14
3990 3997 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3991 3998 # error[indInvalid1] = 13
3992 3999 #
3993 4000 # return heights, error
3994 4001 No newline at end of file
1 NO CONTENT: modified file, binary diff hidden
@@ -1,1 +1,1
1 <Project description="read bltr data sswma file" id="191" name="test1"><ReadUnit datatype="testBLTRReader" id="1911" inputId="0" name="testBLTRReader"><Operation id="19111" name="run" priority="1" type="self"><Parameter format="str" id="191111" name="datatype" value="testBLTRReader" /><Parameter format="str" id="191112" name="path" value="/media/erick/6F60F7113095A154/BLTR" /><Parameter format="date" id="191113" name="startDate" value="2017/01/17" /><Parameter format="date" id="191114" name="endDate" value="2018/01/01" /><Parameter format="time" id="191115" name="startTime" value="00:00:00" /><Parameter format="time" id="191116" name="endTime" value="23:59:59" /><Parameter format="str" id="191118" name="ext" value="sswma" /></Operation></ReadUnit><ProcUnit datatype="BLTRProcess" id="1912" inputId="1911" name="BLTRProcess"><Operation id="19121" name="run" priority="1" type="self" /><Operation id="19122" name="SnrFilter" priority="2" type="self"><Parameter format="float" id="191221" name="snr_val" value="-20" /><Parameter format="int" id="191222" name="modetofilter" value="2" /></Operation><Operation id="19123" name="OutliersFilter" priority="3" type="self"><Parameter format="str" id="191231" name="svalue" value="meridional" /><Parameter format="str" id="191232" name="svalue2" value="inTime" /><Parameter format="float" id="191233" name="method" value="0" /><Parameter format="float" id="191234" name="factor" value="2" /><Parameter format="float" id="191235" name="filter" value="0" /><Parameter format="float" id="191236" name="npoints" value="9" /><Parameter format="int" id="191237" name="modetofilter" value="2" /></Operation><Operation id="19124" name="OutliersFilter" priority="4" type="self"><Parameter format="str" id="191241" name="svalue" value="zonal" /><Parameter format="str" id="191242" name="svalue2" value="inTime" /><Parameter format="float" id="191243" name="method" value="0" /><Parameter format="float" id="191244" name="factor" value="2" /><Parameter format="float" id="191245" name="filter" value="0" /><Parameter format="float" id="191246" name="npoints" value="9" /><Parameter format="int" id="191247" name="modetofilter" value="2" /></Operation><Operation id="19125" name="OutliersFilter" priority="5" type="self"><Parameter format="str" id="191251" name="svalue" value="vertical" /><Parameter format="str" id="191252" name="svalue2" value="inHeight" /><Parameter format="float" id="191253" name="method" value="0" /><Parameter format="float" id="191254" name="factor" value="2" /><Parameter format="float" id="191255" name="filter" value="0" /><Parameter format="float" id="191256" name="npoints" value="9" /><Parameter format="int" id="191257" name="modetofilter" value="2" /></Operation><Operation id="19126" name="prePlot" priority="6" type="self"><Parameter format="int" id="191261" name="modeselect" value="1" /></Operation><Operation id="19127" name="WindProfilerPlot" priority="7" type="other"><Parameter format="int" id="191271" name="id" value="1" /><Parameter format="str" id="191272" name="wintitle" value="" /><Parameter format="intlist" id="191273" name="channelList" value="0" /><Parameter format="int" id="191274" name="SNRmin" value="-10" /><Parameter format="int" id="191275" name="SNRmax" value="50" /><Parameter format="float" id="191276" name="SNRthresh" value="0" /><Parameter format="float" id="191277" name="xmin" value="0" /><Parameter format="float" id="191278" name="xmax" value="24" /><Parameter format="float" id="191279" name="ymax" value="3" /><Parameter format="float" id="191280" name="zmin" value="-20" /><Parameter format="float" id="191281" name="zmax" value="20" /><Parameter format="float" id="191282" name="zmin_ver" value="-200" /><Parameter format="float" id="191283" name="zmax_ver" value="200" /></Operation><Operation id="19128" name="prePlot" priority="8" type="self"><Parameter format="int" id="191281" name="modeselect" value="2" /></Operation><Operation id="19129" name="WindProfilerPlot" priority="9" type="other"><Parameter format="int" id="191291" name="id" value="2" /><Parameter format="str" id="191292" name="wintitle" value="" /><Parameter format="bool" id="191293" name="save" value="1" /><Parameter format="str" id="191294" name="figpath" value="/media/erick/6F60F7113095A154/BLTR/" /><Parameter format="int" id="191295" name="SNRmin" value="-20" /><Parameter format="int" id="191296" name="SNRmax" value="40" /><Parameter format="float" id="191297" name="SNRthresh" value="0" /><Parameter format="float" id="191298" name="xmin" value="0" /><Parameter format="float" id="191299" name="xmax" value="24" /><Parameter format="float" id="191300" name="ymin" value="0" /><Parameter format="float" id="191301" name="ymax" value="10" /><Parameter format="float" id="191302" name="zmin" value="-4" /><Parameter format="float" id="191303" name="zmax" value="4" /><Parameter format="float" id="191304" name="zmin_ver" value="-200" /><Parameter format="float" id="191305" name="zmax_ver" value="200" /></Operation></ProcUnit></Project> No newline at end of file
1 <Project description="Segundo Test" id="191" name="test01"><ReadUnit datatype="VoltageReader" id="1911" inputId="0" name="VoltageReader"><Operation id="19111" name="run" priority="1" type="self"><Parameter format="str" id="191111" name="datatype" value="VoltageReader" /><Parameter format="str" id="191112" name="path" value="/home/erick/Documents/Data/Claire_Data/raw" /><Parameter format="date" id="191113" name="startDate" value="2017/07/26" /><Parameter format="date" id="191114" name="endDate" value="2017/07/26" /><Parameter format="time" id="191115" name="startTime" value="10:02:00" /><Parameter format="time" id="191116" name="endTime" value="10:11:00" /><Parameter format="int" id="191118" name="online" value="0" /><Parameter format="int" id="191119" name="walk" value="1" /></Operation><Operation id="19112" name="printNumberOfBlock" priority="2" type="self" /></ReadUnit><ProcUnit datatype="SpectraProc" id="1913" inputId="1912" name="SpectraProc"><Operation id="19131" name="run" priority="1" type="self"><Parameter format="int" id="191311" name="nFFTPoints" value="128" /><Parameter format="pairslist" id="191312" name="pairsList" value="(0,1),(0,2),(1,2)" /></Operation><Operation id="19132" name="removeDC" priority="2" type="self" /><Operation id="19133" name="IncohInt" priority="3" type="external"><Parameter format="float" id="191331" name="n" value="30" /></Operation><Operation id="19134" name="CrossSpectraPlot" priority="4" type="other"><Parameter format="str" id="191341" name="phase_cmap" value="bwr" /><Parameter format="int" id="191342" name="id" value="2005" /><Parameter format="str" id="191343" name="wintitle" value="CrossSpectraPlot_ShortPulse" /><Parameter format="str" id="191344" name="xaxis" value="Velocity" /><Parameter format="float" id="191345" name="ymin" value="1" /><Parameter format="int" id="191346" name="ymax" value="7" /><Parameter format="int" id="191347" name="zmin" value="15" /><Parameter format="int" id="191348" name="zmax" value="60" /><Parameter format="int" id="191349" name="save" value="2" /><Parameter format="str" id="191350" name="figpath" value="/media/erick/6F60F7113095A154/CLAIRE/CLAIRE_WINDS_2MHZ/Images" /></Operation></ProcUnit><ProcUnit datatype="VoltageProc" id="1912" inputId="1911" name="VoltageProc"><Operation id="19121" name="run" priority="1" type="self" /><Operation id="19122" name="setRadarFrequency" priority="2" type="self"><Parameter format="float" id="191221" name="frequency" value="445.09e6" /></Operation><Operation id="19123" name="selectHeights" priority="3" type="self"><Parameter format="float" id="191231" name="minHei" value="0" /><Parameter format="float" id="191232" name="maxHei" value="64" /></Operation></ProcUnit><ProcUnit datatype="Parameters" id="1914" inputId="1913" name="ParametersProc"><Operation id="19141" name="run" priority="1" type="self" /><Operation id="19142" name="GaussianFit" priority="2" type="other" /></ProcUnit></Project> No newline at end of file
@@ -1,171 +1,171
1 1 '''
2 2 Created on Nov 09, 2016
3 3
4 4 @author: roj- LouVD
5 5 '''
6 6 import os, sys
7 7
8 8
9 9 path = os.path.split(os.getcwd())[0]
10 10 path = os.path.split(path)[0]
11 11
12 12 sys.path.insert(0, path)
13 13
14 14 from schainpy.controller import Project
15 15
16 16 filename = 'test1.xml'
17 17 # path = '/home/jespinoza/workspace/data/bltr/'
18 18 path = '/media/erick/6F60F7113095A154/BLTR/'
19 19 desc = "read bltr data sswma file"
20 20 figpath = '/media/erick/6F60F7113095A154/BLTR/'
21 21 pathhdf5 = '/tmp/'
22 22
23 23 controllerObj = Project()
24 24
25 25 controllerObj.setup(id = '191', name='test1', description=desc)
26 26 readUnitConfObj = controllerObj.addReadUnit(datatype='testBLTRReader',
27 27 path=path,
28 28 startDate='2017/01/17',
29 29 endDate='2018/01/01',
30 30 startTime='00:00:00',
31 31 endTime='23:59:59',
32 32 ext='sswma')
33 33
34 34 procUnitConfObj1 = controllerObj.addProcUnit(datatype='BLTRProcess',
35 35 inputId=readUnitConfObj.getId())
36 36
37 37 '''-------------------------------------------Processing--------------------------------------------'''
38 38
39 39 '''MODE 1: LOW ATMOSPHERE: 0- 3 km'''
40 40 # opObj10 = procUnitConfObj1.addOperation(name='SnrFilter')
41 41 # opObj10.addParameter(name='snr_val', value='-10', format='float')
42 42 # opObj10.addParameter(name='modetofilter', value='1', format='int')
43 43 #
44 44 # opObj10 = procUnitConfObj1.addOperation(name='OutliersFilter')
45 45 # opObj10.addParameter(name='svalue', value='meridional', format='str')
46 46 # opObj10.addParameter(name='svalue2', value='inTime', format='str')
47 47 # opObj10.addParameter(name='method', value='0', format='float')
48 48 # opObj10.addParameter(name='factor', value='1', format='float')
49 49 # opObj10.addParameter(name='filter', value='0', format='float')
50 50 # opObj10.addParameter(name='npoints', value='5', format='float')
51 51 # opObj10.addParameter(name='modetofilter', value='1', format='int')
52 52 # #
53 53 # opObj10 = procUnitConfObj1.addOperation(name='OutliersFilter')
54 54 # opObj10.addParameter(name='svalue', value='zonal', format='str')
55 55 # opObj10.addParameter(name='svalue2', value='inTime', format='str')
56 56 # opObj10.addParameter(name='method', value='0', format='float')
57 57 # opObj10.addParameter(name='factor', value='1', format='float')
58 58 # opObj10.addParameter(name='filter', value='0', format='float')
59 59 # opObj10.addParameter(name='npoints', value='5', format='float')
60 60 # opObj10.addParameter(name='modetofilter', value='1', format='int')
61 61 # #
62 62 # opObj10 = procUnitConfObj1.addOperation(name='OutliersFilter')
63 63 # opObj10.addParameter(name='svalue', value='vertical', format='str')
64 64 # opObj10.addParameter(name='svalue2', value='inHeight', format='str')
65 65 # opObj10.addParameter(name='method', value='0', format='float')
66 66 # opObj10.addParameter(name='factor', value='2', format='float')
67 67 # opObj10.addParameter(name='filter', value='0', format='float')
68 68 # opObj10.addParameter(name='npoints', value='9', format='float')
69 69 # opObj10.addParameter(name='modetofilter', value='1', format='int')
70 70 #
71 71
72 72 ''' MODE 2: 0 - 10 km '''
73 73
74 74 opObj10 = procUnitConfObj1.addOperation(name='SnrFilter')
75 75 opObj10.addParameter(name='snr_val', value='-20', format='float')
76 76 opObj10.addParameter(name='modetofilter', value='2', format='int')
77 77
78 78 opObj10 = procUnitConfObj1.addOperation(name='OutliersFilter')
79 79 opObj10.addParameter(name='svalue', value='meridional', format='str')
80 80 opObj10.addParameter(name='svalue2', value='inTime', format='str')
81 81 opObj10.addParameter(name='method', value='0', format='float')
82 82 opObj10.addParameter(name='factor', value='2', format='float')
83 83 opObj10.addParameter(name='filter', value='0', format='float')
84 84 opObj10.addParameter(name='npoints', value='9', format='float')
85 85 opObj10.addParameter(name='modetofilter', value='2', format='int')
86 86 # #
87 87 opObj10 = procUnitConfObj1.addOperation(name='OutliersFilter')
88 88 opObj10.addParameter(name='svalue', value='zonal', format='str')
89 89 opObj10.addParameter(name='svalue2', value='inTime', format='str')
90 90 opObj10.addParameter(name='method', value='0', format='float')
91 91 opObj10.addParameter(name='factor', value='2', format='float')
92 92 opObj10.addParameter(name='filter', value='0', format='float')
93 93 opObj10.addParameter(name='npoints', value='9', format='float')
94 94 opObj10.addParameter(name='modetofilter', value='2', format='int')
95 95 # #
96 96 opObj10 = procUnitConfObj1.addOperation(name='OutliersFilter')
97 97 opObj10.addParameter(name='svalue', value='vertical', format='str')
98 98 opObj10.addParameter(name='svalue2', value='inHeight', format='str')
99 99 opObj10.addParameter(name='method', value='0', format='float')
100 100 opObj10.addParameter(name='factor', value='2', format='float')
101 101 opObj10.addParameter(name='filter', value='0', format='float')
102 102 opObj10.addParameter(name='npoints', value='9', format='float')
103 103 opObj10.addParameter(name='modetofilter', value='2', format='int')
104 104
105 105 # '''-----------------------------------------Writing-------------------------------------------'''
106 106 #
107 107 # # opObj10 = procUnitConfObj1.addOperation(name='testBLTRWriter',optype='other')
108 108 # # opObj10.addParameter(name='path', value = pathhdf5)
109 109 # # opObj10.addParameter(name='modetowrite', value = '2',format='int')
110 110 # #
111 111 # # opObj10 = procUnitConfObj1.addOperation(name='testBLTRWriter',optype='other')
112 112 # # opObj10.addParameter(name='path', value = pathhdf5)
113 113 # # opObj10.addParameter(name='modetowrite', value = '1',format='int')
114 114 #
115 115 # '''----------------------------------------Plotting--------------------------------------------'''
116 116 #
117 117 opObj10 = procUnitConfObj1.addOperation(name='prePlot')
118 118 opObj10.addParameter(name='modeselect',value='1',format='int')
119 119 # #
120 120 opObj10 = procUnitConfObj1.addOperation(name='WindProfilerPlot', optype='other')
121 121 opObj10.addParameter(name='id', value='1', format='int')
122 122 opObj10.addParameter(name='wintitle', value='', format='str')
123 123 opObj10.addParameter(name='channelList', value='0', format='intlist')
124 124 #opObj10.addParameter(name='save', value='1', format='bool')
125 125 #opObj10.addParameter(name='figpath', value=figpath, format='str')
126 126 opObj10.addParameter(name='SNRmin', value='-10', format='int')
127 127 opObj10.addParameter(name='SNRmax', value='50', format='int')
128 128 opObj10.addParameter(name='SNRthresh', value='0', format='float')
129 129 opObj10.addParameter(name='xmin', value='0', format='float')
130 130 opObj10.addParameter(name='xmax', value='24', format='float')
131 131 opObj10.addParameter(name='ymax', value='3', format='float')
132 132 opObj10.addParameter(name='zmin', value='-20', format='float')
133 133 opObj10.addParameter(name='zmax', value='20', format='float')
134 134 opObj10.addParameter(name='zmin_ver', value='-200', format='float')
135 135 opObj10.addParameter(name='zmax_ver', value='200', format='float')
136 136 #opObj10.addParameter(name='showprofile', value='1', format='bool')
137 137 #opObj10.addParameter(name='show', value='1', format='bool')
138 138
139 139 opObj10 = procUnitConfObj1.addOperation(name='prePlot')
140 140 opObj10.addParameter(name='modeselect',value='2',format='int')
141 141 #
142 142 opObj10 = procUnitConfObj1.addOperation(name='WindProfilerPlot', optype='other')
143 143 opObj10.addParameter(name='id', value='2', format='int')
144 144 opObj10.addParameter(name='wintitle', value='', format='str')
145 145 #opObj10.addParameter(name='channelList', value='0', format='intlist')
146 146 opObj10.addParameter(name='save', value='1', format='bool')
147 147 opObj10.addParameter(name='figpath', value=figpath, format='str')
148 148 opObj10.addParameter(name='SNRmin', value='-20', format='int')
149 149 opObj10.addParameter(name='SNRmax', value='40', format='int')
150 150 opObj10.addParameter(name='SNRthresh', value='0', format='float')
151 151 opObj10.addParameter(name='xmin', value='0', format='float')
152 152 opObj10.addParameter(name='xmax', value='24', format='float')
153 153 opObj10.addParameter(name='ymin', value='0', format='float')
154 opObj10.addParameter(name='ymax', value='10', format='float')
154 opObj10.addParameter(name='ymax', value='7', format='float')
155 155 opObj10.addParameter(name='zmin', value='-4', format='float')
156 156 opObj10.addParameter(name='zmax', value='4', format='float')
157 157 opObj10.addParameter(name='zmin_ver', value='-200', format='float')
158 158 opObj10.addParameter(name='zmax_ver', value='200', format='float')
159 159 #opObj10.addParameter(name='showprofile', value='1', format='bool')
160 160 #opObj10.addParameter(name='show', value='1', format='bool')
161 161
162 162 # # print "Escribiendo el archivo XML"
163 163 # controllerObj.writeXml(filename)
164 164 # # print "Leyendo el archivo XML"
165 165 # controllerObj.readXml(filename)
166 166
167 167 # controllerObj.createObjects()
168 168 # controllerObj.connectObjects()
169 169 # controllerObj.run()
170 170 controllerObj.start()
171 171
@@ -1,150 +1,151
1 1 #!/usr/bin/env python
2 2 import os, sys
3 3
4 4 # path = os.path.dirname(os.getcwd())
5 5 # path = os.path.join(path, 'source')
6 6 # sys.path.insert(0, '../')
7 7
8 8 from schainpy.controller import Project
9 9
10 10 xmin = '15.5'
11 11 xmax = '24'
12 12
13 13
14 14 desc = "ProcBLTR Test"
15 15 filename = "ProcBLTR.xml"
16 16 figpath = '/media/erick/6F60F7113095A154/BLTR'
17 17
18 18 controllerObj = Project()
19 19
20 20
21 21 controllerObj.setup(id='191', name='test01', description=desc)
22 22
23 23 readUnitConfObj = controllerObj.addReadUnit(datatype='BLTRReader',
24 24 path='/media/erick/6F60F7113095A154/BLTR/',
25 25
26 26 endDate='2017/10/19',
27 27 startTime='13:00:00',
28 28 startDate='2016/11/8',
29 29 endTime='23:59:59',
30 30
31 31
32 32 online=0,
33 33 walk=0,
34 34 ReadMode='1')
35 35 # expLabel='')
36 36
37 37 # opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock')
38 38
39 39 procUnitConfObj1 = controllerObj.addProcUnit(datatype='Spectra', inputId=readUnitConfObj.getId())
40 40
41 41
42 42
43 43 opObj11 = procUnitConfObj1.addOperation(name='IncohInt', optype='other')
44 44 opObj11.addParameter(name='n', value='3', format='float')
45 45
46 46 opObj10 = procUnitConfObj1.addOperation(name='removeDC')
47 47
48 48 # opObj10 = procUnitConfObj1.addOperation(name='calcMag')
49 49
50 50 # opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other')
51 51 # opObj11.addParameter(name='id', value='21', format='int')
52 52 # opObj11.addParameter(name='wintitle', value='SpectraCutPlot', format='str')
53 53 # opObj11.addParameter(name='xaxis', value='frequency', format='str')
54 54 # opObj11.addParameter(name='colormap', value='winter', format='str')
55 55 # opObj11.addParameter(name='xmin', value='-0.005', format='float')
56 56 # opObj11.addParameter(name='xmax', value='0.005', format='float')
57 57 # #opObj10 = procUnitConfObj1.addOperation(name='selectChannels')
58 58 # #opObj10.addParameter(name='channelList', value='0,1', format='intlist')
59 59 # opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other')
60 60 # opObj11.addParameter(name='id', value='21', format='int')
61 61 # opObj11.addParameter(name='wintitle', value='SpectraPlot', format='str')
62 62 # #opObj11.addParameter(name='xaxis', value='Velocity', format='str')
63 63
64 64 # opObj11.addParameter(name='xaxis', value='velocity', format='str')
65 65 # opObj11.addParameter(name='xmin', value='-0.005', format='float')
66 66 # opObj11.addParameter(name='xmax', value='0.005', format='float')
67 67
68 68 # opObj11.addParameter(name='ymin', value='225', format='float')
69 69 # opObj11.addParameter(name='ymax', value='3000', format='float')
70 70 # opObj11.addParameter(name='zmin', value='-100', format='int')
71 71 # opObj11.addParameter(name='zmax', value='-65', format='int')
72 72
73 73 # opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other')
74 74 # opObj11.addParameter(name='id', value='10', format='int')
75 75 # opObj11.addParameter(name='wintitle', value='RTI', format='str')
76 76 # opObj11.addParameter(name='ymin', value='0', format='float')
77 77 # opObj11.addParameter(name='ymax', value='4000', format='float')
78 78 # #opObj11.addParameter(name='zmin', value='-100', format='int')
79 79 # #opObj11.addParameter(name='zmax', value='-70', format='int')
80 80 # opObj11.addParameter(name='zmin', value='-90', format='int')
81 81 # opObj11.addParameter(name='zmax', value='-40', format='int')
82 82 # opObj11.addParameter(name='showprofile', value='1', format='int')
83 83 # opObj11.addParameter(name='timerange', value=str(2*60*60), format='int')
84 84
85 85 opObj11 = procUnitConfObj1.addOperation(name='CrossSpectraPlot', optype='other')
86 86 procUnitConfObj1.addParameter(name='pairsList', value='(0,1),(0,2),(1,2)', format='pairsList')
87 87 opObj11.addParameter(name='id', value='2005', format='int')
88 88 opObj11.addParameter(name='wintitle', value='CrossSpectraPlot_ShortPulse', format='str')
89 89 # opObj11.addParameter(name='exp_code', value='13', format='int')
90 90 opObj11.addParameter(name='xaxis', value='Velocity', format='str')
91 91 #opObj11.addParameter(name='xmin', value='-10', format='float')
92 92 #opObj11.addParameter(name='xmax', value='10', format='float')
93 93 #opObj11.addParameter(name='ymin', value='225', format='float')
94 94 #opObj11.addParameter(name='ymax', value='3000', format='float')
95 95 #opObj11.addParameter(name='phase_min', value='-4', format='int')
96 96 #opObj11.addParameter(name='phase_max', value='4', format='int')
97 97
98 98 # procUnitConfObj2 = controllerObj.addProcUnit(datatype='CorrelationProc', inputId=procUnitConfObj1.getId())
99 99 # procUnitConfObj2.addParameter(name='pairsList', value='(0,1),(0,2),(1,2)', format='pairsList')
100 100
101 101 procUnitConfObj2 = controllerObj.addProcUnit(datatype='Parameters', inputId=procUnitConfObj1.getId())
102 102 opObj11 = procUnitConfObj2.addOperation(name='SpectralMoments', optype='other')
103 103 opObj22 = procUnitConfObj2.addOperation(name='FullSpectralAnalysis', optype='other')
104 opObj22.addParameter(name='SNRlimit', value='-4', format='float')
104 105 #
105 106 opObj22 = procUnitConfObj2.addOperation(name='WindProfilerPlot', optype='other')
106 107 opObj22.addParameter(name='id', value='4', format='int')
107 108 opObj22.addParameter(name='wintitle', value='Wind Profiler', format='str')
108 109 opObj22.addParameter(name='save', value='1', format='bool')
109 110 # opObj22.addParameter(name='figpath', value = '/home/erick/Pictures', format='str')
110 111
111 112 opObj22.addParameter(name='zmin', value='-20', format='int')
112 113 opObj22.addParameter(name='zmax', value='20', format='int')
113 114 opObj22.addParameter(name='zmin_ver', value='-250', format='float')
114 115 opObj22.addParameter(name='zmax_ver', value='250', format='float')
115 116 opObj22.addParameter(name='SNRmin', value='-5', format='int')
116 117 opObj22.addParameter(name='SNRmax', value='30', format='int')
117 118 # opObj22.addParameter(name='SNRthresh', value='-3.5', format='float')
118 opObj22.addParameter(name='xmin', value=0, format='float')
119 opObj22.addParameter(name='xmax', value=24, format='float')
119 opObj22.addParameter(name='xmin', value='0', format='float')
120 opObj22.addParameter(name='xmax', value='24', format='float')
120 121 opObj22.addParameter(name='ymin', value='225', format='float')
121 122 #opObj22.addParameter(name='ymax', value='2000', format='float')
122 123 opObj22.addParameter(name='save', value='1', format='int')
123 124 opObj22.addParameter(name='figpath', value=figpath, format='str')
124 125
125 126
126 127 # opObj11.addParameter(name='pairlist', value='(1,0),(0,2),(1,2)', format='pairsList')
127 128 #opObj10 = procUnitConfObj1.addOperation(name='selectHeights')
128 129 #opObj10.addParameter(name='minHei', value='225', format='float')
129 130 #opObj10.addParameter(name='maxHei', value='1000', format='float')
130 131
131 132 # opObj11 = procUnitConfObj1.addOperation(name='CoherenceMap', optype='other')
132 133 # opObj11.addParameter(name='id', value='102', format='int')
133 134 # opObj11.addParameter(name='wintitle', value='Coherence', format='str')
134 135 # opObj11.addParameter(name='ymin', value='225', format='float')
135 136 # opObj11.addParameter(name='ymax', value='4000', format='float')
136 137
137 138 # opObj11.addParameter(name='phase_cmap', value='jet', format='str')
138 139 # opObj11.addParameter(name='xmin', value='8.5', format='float')
139 140 # opObj11.addParameter(name='xmax', value='9.5', format='float')
140 141 # opObj11.addParameter(name='figpath', value=figpath, format='str')
141 142 # opObj11.addParameter(name='save', value=1, format='bool')
142 143 # opObj11.addParameter(name='pairsList', value='(1,0),(3,2)', format='pairsList')
143 144
144 145 # opObj12 = procUnitConfObj1.addOperation(name='PublishData', optype='other')
145 146 # opObj12.addParameter(name='zeromq', value=1, format='int')
146 147 # opObj12.addParameter(name='verbose', value=0, format='bool')
147 148 # opObj12.addParameter(name='server', value='erick2', format='str')
148 149 controllerObj.start()
149 150
150 151
General Comments 0
You need to be logged in to leave comments. Login now