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