##// END OF EJS Templates
-Added Radial Velocity graphic ...
Julio Valdez -
r511:4883db3dd5a0
parent child
Show More
@@ -1,576 +1,793
1 1 import os
2 2 import datetime
3 3 import numpy
4 4
5 5 from figure import Figure, isRealtime
6 6
7 7 class MomentsPlot(Figure):
8 8
9 9 isConfig = None
10 10 __nsubplots = None
11 11
12 12 WIDTHPROF = None
13 13 HEIGHTPROF = None
14 14 PREFIX = 'prm'
15 15
16 16 def __init__(self):
17 17
18 18 self.isConfig = False
19 19 self.__nsubplots = 1
20 20
21 21 self.WIDTH = 280
22 22 self.HEIGHT = 250
23 23 self.WIDTHPROF = 120
24 24 self.HEIGHTPROF = 0
25 25 self.counter_imagwr = 0
26 26
27 27 self.PLOT_CODE = 1
28 28 self.FTP_WEI = None
29 29 self.EXP_CODE = None
30 30 self.SUB_EXP_CODE = None
31 31 self.PLOT_POS = None
32 32
33 33 def getSubplots(self):
34 34
35 35 ncol = int(numpy.sqrt(self.nplots)+0.9)
36 36 nrow = int(self.nplots*1./ncol + 0.9)
37 37
38 38 return nrow, ncol
39 39
40 40 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
41 41
42 42 self.__showprofile = showprofile
43 43 self.nplots = nplots
44 44
45 45 ncolspan = 1
46 46 colspan = 1
47 47 if showprofile:
48 48 ncolspan = 3
49 49 colspan = 2
50 50 self.__nsubplots = 2
51 51
52 52 self.createFigure(id = id,
53 53 wintitle = wintitle,
54 54 widthplot = self.WIDTH + self.WIDTHPROF,
55 55 heightplot = self.HEIGHT + self.HEIGHTPROF,
56 56 show=show)
57 57
58 58 nrow, ncol = self.getSubplots()
59 59
60 60 counter = 0
61 61 for y in range(nrow):
62 62 for x in range(ncol):
63 63
64 64 if counter >= self.nplots:
65 65 break
66 66
67 67 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
68 68
69 69 if showprofile:
70 70 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
71 71
72 72 counter += 1
73 73
74 74 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
75 75 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
76 76 save=False, figpath='', figfile=None, show=True, ftp=False, wr_period=1,
77 77 server=None, folder=None, username=None, password=None,
78 78 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
79 79
80 80 """
81 81
82 82 Input:
83 83 dataOut :
84 84 id :
85 85 wintitle :
86 86 channelList :
87 87 showProfile :
88 88 xmin : None,
89 89 xmax : None,
90 90 ymin : None,
91 91 ymax : None,
92 92 zmin : None,
93 93 zmax : None
94 94 """
95 95
96 96 if dataOut.flagNoData:
97 97 return None
98 98
99 99 if realtime:
100 100 if not(isRealtime(utcdatatime = dataOut.utctime)):
101 101 print 'Skipping this plot function'
102 102 return
103 103
104 104 if channelList == None:
105 105 channelIndexList = dataOut.channelIndexList
106 106 else:
107 107 channelIndexList = []
108 108 for channel in channelList:
109 109 if channel not in dataOut.channelList:
110 110 raise ValueError, "Channel %d is not in dataOut.channelList"
111 111 channelIndexList.append(dataOut.channelList.index(channel))
112 112
113 113 factor = dataOut.normFactor
114 114 x = dataOut.abscissaRange
115 115 y = dataOut.heightRange
116 116
117 117 z = dataOut.data_pre[channelIndexList,:,:]/factor
118 118 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
119 119 avg = numpy.average(z, axis=1)
120 120 noise = dataOut.noise/factor
121 121
122 122 zdB = 10*numpy.log10(z)
123 123 avgdB = 10*numpy.log10(avg)
124 124 noisedB = 10*numpy.log10(noise)
125 125
126 126 #thisDatetime = dataOut.datatime
127 127 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[1])
128 128 title = wintitle + " Parameters"
129 129 xlabel = "Velocity (m/s)"
130 130 ylabel = "Range (Km)"
131 131
132 132 if not self.isConfig:
133 133
134 134 nplots = len(channelIndexList)
135 135
136 136 self.setup(id=id,
137 137 nplots=nplots,
138 138 wintitle=wintitle,
139 139 showprofile=showprofile,
140 140 show=show)
141 141
142 142 if xmin == None: xmin = numpy.nanmin(x)
143 143 if xmax == None: xmax = numpy.nanmax(x)
144 144 if ymin == None: ymin = numpy.nanmin(y)
145 145 if ymax == None: ymax = numpy.nanmax(y)
146 146 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
147 147 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
148 148
149 149 self.FTP_WEI = ftp_wei
150 150 self.EXP_CODE = exp_code
151 151 self.SUB_EXP_CODE = sub_exp_code
152 152 self.PLOT_POS = plot_pos
153 153
154 154 self.isConfig = True
155 155
156 156 self.setWinTitle(title)
157 157
158 158 for i in range(self.nplots):
159 159 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
160 160 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[i]+1, noisedB[i], str_datetime)
161 161 axes = self.axesList[i*self.__nsubplots]
162 162 axes.pcolor(x, y, zdB[i,:,:],
163 163 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
164 164 xlabel=xlabel, ylabel=ylabel, title=title,
165 165 ticksize=9, cblabel='')
166 166 #Mean Line
167 167 mean = dataOut.data_param[i, 1, :]
168 168 axes.addpline(mean, y, idline=0, color="black", linestyle="solid", lw=1)
169 169
170 170 if self.__showprofile:
171 171 axes = self.axesList[i*self.__nsubplots +1]
172 172 axes.pline(avgdB[i], y,
173 173 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
174 174 xlabel='dB', ylabel='', title='',
175 175 ytick_visible=False,
176 176 grid='x')
177 177
178 178 noiseline = numpy.repeat(noisedB[i], len(y))
179 179 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
180 180
181 181 self.draw()
182 182
183 183 if figfile == None:
184 184 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
185 185 figfile = self.getFilename(name = str_datetime)
186 186
187 187 if figpath != '':
188 188 self.counter_imagwr += 1
189 189 if (self.counter_imagwr>=wr_period):
190 190 # store png plot to local folder
191 191 self.saveFigure(figpath, figfile)
192 192 # store png plot to FTP server according to RT-Web format
193 193 name = self.getNameToFtp(thisDatetime, self.FTP_WEI, self.EXP_CODE, self.SUB_EXP_CODE, self.PLOT_CODE, self.PLOT_POS)
194 194 ftp_filename = os.path.join(figpath, name)
195 195 self.saveFigure(figpath, ftp_filename)
196 196 self.counter_imagwr = 0
197 197
198 198 class SkyMapPlot(Figure):
199 199
200 200 __isConfig = None
201 201 __nsubplots = None
202 202
203 203 WIDTHPROF = None
204 204 HEIGHTPROF = None
205 205 PREFIX = 'prm'
206 206
207 207 def __init__(self):
208 208
209 209 self.__isConfig = False
210 210 self.__nsubplots = 1
211 211
212 212 # self.WIDTH = 280
213 213 # self.HEIGHT = 250
214 214 self.WIDTH = 600
215 215 self.HEIGHT = 600
216 216 self.WIDTHPROF = 120
217 217 self.HEIGHTPROF = 0
218 218 self.counter_imagwr = 0
219 219
220 220 self.PLOT_CODE = 1
221 221 self.FTP_WEI = None
222 222 self.EXP_CODE = None
223 223 self.SUB_EXP_CODE = None
224 224 self.PLOT_POS = None
225 225
226 226 def getSubplots(self):
227 227
228 228 ncol = int(numpy.sqrt(self.nplots)+0.9)
229 229 nrow = int(self.nplots*1./ncol + 0.9)
230 230
231 231 return nrow, ncol
232 232
233 233 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
234 234
235 235 self.__showprofile = showprofile
236 236 self.nplots = nplots
237 237
238 238 ncolspan = 1
239 239 colspan = 1
240 240
241 241 self.createFigure(id = id,
242 242 wintitle = wintitle,
243 243 widthplot = self.WIDTH, #+ self.WIDTHPROF,
244 244 heightplot = self.HEIGHT,# + self.HEIGHTPROF,
245 245 show=show)
246 246
247 247 nrow, ncol = 1,1
248 248 counter = 0
249 249 x = 0
250 250 y = 0
251 251 self.addAxes(1, 1, 0, 0, 1, 1, True)
252 252
253 253 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
254 254 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
255 255 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
256 256 server=None, folder=None, username=None, password=None,
257 257 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
258 258
259 259 """
260 260
261 261 Input:
262 262 dataOut :
263 263 id :
264 264 wintitle :
265 265 channelList :
266 266 showProfile :
267 267 xmin : None,
268 268 xmax : None,
269 269 ymin : None,
270 270 ymax : None,
271 271 zmin : None,
272 272 zmax : None
273 273 """
274 274
275 275 arrayParameters = dataOut.data_param
276 276 error = arrayParameters[:,-1]
277 277 indValid = numpy.where(error == 0)[0]
278 278 finalMeteor = arrayParameters[indValid,:]
279 279 finalAzimuth = finalMeteor[:,4]
280 280 finalZenith = finalMeteor[:,5]
281 281
282 282 x = finalAzimuth*numpy.pi/180
283 283 y = finalZenith
284 284
285 285
286 286 #thisDatetime = dataOut.datatime
287 287 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[1])
288 288 title = wintitle + " Parameters"
289 289 xlabel = "Zonal Zenith Angle (deg) "
290 290 ylabel = "Meridional Zenith Angle (deg)"
291 291
292 292 if not self.__isConfig:
293 293
294 294 nplots = 1
295 295
296 296 self.setup(id=id,
297 297 nplots=nplots,
298 298 wintitle=wintitle,
299 299 showprofile=showprofile,
300 300 show=show)
301 301
302 302 self.FTP_WEI = ftp_wei
303 303 self.EXP_CODE = exp_code
304 304 self.SUB_EXP_CODE = sub_exp_code
305 305 self.PLOT_POS = plot_pos
306 306 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
307 307 self.firstdate = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
308 308 self.__isConfig = True
309 309
310 310 self.setWinTitle(title)
311 311
312 312 i = 0
313 313 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
314 314
315 315 axes = self.axesList[i*self.__nsubplots]
316 316 nevents = axes.x_buffer.shape[0] + x.shape[0]
317 317 title = "Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n" %(self.firstdate,str_datetime,nevents)
318 318 axes.polar(x, y,
319 319 title=title, xlabel=xlabel, ylabel=ylabel,
320 320 ticksize=9, cblabel='')
321 321
322 322 self.draw()
323 323
324 324 if save:
325 325
326 326 self.counter_imagwr += 1
327 327 if (self.counter_imagwr==wr_period):
328 328
329 329 if figfile == None:
330 330 figfile = self.getFilename(name = self.name)
331 331 self.saveFigure(figpath, figfile)
332 332
333 333 if ftp:
334 334 #provisionalmente envia archivos en el formato de la web en tiempo real
335 335 name = self.getNameToFtp(thisDatetime, self.FTP_WEI, self.EXP_CODE, self.SUB_EXP_CODE, self.PLOT_CODE, self.PLOT_POS)
336 336 path = '%s%03d' %(self.PREFIX, self.id)
337 337 ftp_file = os.path.join(path,'ftp','%s.png'%name)
338 338 self.saveFigure(figpath, ftp_file)
339 339 ftp_filename = os.path.join(figpath,ftp_file)
340 340
341 341
342 342 try:
343 343 self.sendByFTP(ftp_filename, server, folder, username, password)
344 344 except:
345 345 self.counter_imagwr = 0
346 346 raise ValueError, 'Error FTP'
347 347
348 348 self.counter_imagwr = 0
349 349
350 350
351 351 class WindProfilerPlot(Figure):
352 352
353 353 __isConfig = None
354 354 __nsubplots = None
355 355
356 356 WIDTHPROF = None
357 357 HEIGHTPROF = None
358 358 PREFIX = 'wind'
359 359
360 360 def __init__(self):
361 361
362 362 self.timerange = 2*60*60
363 363 self.__isConfig = False
364 364 self.__nsubplots = 1
365 365
366 366 self.WIDTH = 800
367 367 self.HEIGHT = 150
368 368 self.WIDTHPROF = 120
369 369 self.HEIGHTPROF = 0
370 370 self.counter_imagwr = 0
371 371
372 372 self.PLOT_CODE = 0
373 373 self.FTP_WEI = None
374 374 self.EXP_CODE = None
375 375 self.SUB_EXP_CODE = None
376 376 self.PLOT_POS = None
377 377 self.tmin = None
378 378 self.tmax = None
379 379
380 380 self.xmin = None
381 381 self.xmax = None
382 382
383 383 self.figfile = None
384 384
385 385 def getSubplots(self):
386 386
387 387 ncol = 1
388 388 nrow = self.nplots
389 389
390 390 return nrow, ncol
391 391
392 392 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
393 393
394 394 self.__showprofile = showprofile
395 395 self.nplots = nplots
396 396
397 397 ncolspan = 1
398 398 colspan = 1
399 399
400 400 self.createFigure(id = id,
401 401 wintitle = wintitle,
402 402 widthplot = self.WIDTH + self.WIDTHPROF,
403 403 heightplot = self.HEIGHT + self.HEIGHTPROF,
404 404 show=show)
405 405
406 406 nrow, ncol = self.getSubplots()
407 407
408 408 counter = 0
409 409 for y in range(nrow):
410 410 if counter >= self.nplots:
411 411 break
412 412
413 413 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
414 414 counter += 1
415 415
416 416 def run(self, dataOut, id, wintitle="", channelList=None,
417 417 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
418 418 zmax_ver = None, zmin_ver = None, SNRmin = None, SNRmax = None,
419 419 timerange=None, SNRthresh = None,
420 420 save=False, figpath='', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
421 421 server=None, folder=None, username=None, password=None,
422 422 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
423 423 """
424 424
425 425 Input:
426 426 dataOut :
427 427 id :
428 428 wintitle :
429 429 channelList :
430 430 showProfile :
431 431 xmin : None,
432 432 xmax : None,
433 433 ymin : None,
434 434 ymax : None,
435 435 zmin : None,
436 436 zmax : None
437 437 """
438 438
439 439 if channelList == None:
440 440 channelIndexList = dataOut.channelIndexList
441 441 else:
442 442 channelIndexList = []
443 443 for channel in channelList:
444 444 if channel not in dataOut.channelList:
445 445 raise ValueError, "Channel %d is not in dataOut.channelList"
446 446 channelIndexList.append(dataOut.channelList.index(channel))
447 447
448 448 if timerange != None:
449 449 self.timerange = timerange
450 450
451 451 tmin = None
452 452 tmax = None
453 453
454 454 x = dataOut.getTimeRange1()
455 455 # y = dataOut.heightRange
456 456 y = dataOut.heightRange
457 457
458 z = dataOut.winds
458 z = dataOut.winds.copy()
459 459 nplots = z.shape[0] #Number of wind dimensions estimated
460 460 nplotsw = nplots
461 461
462 462 #If there is a SNR function defined
463 463 if dataOut.SNR != None:
464 464 nplots += 1
465 465 SNR = dataOut.SNR
466 466 SNRavg = numpy.average(SNR, axis=0)
467 467
468 468 SNRdB = 10*numpy.log10(SNR)
469 469 SNRavgdB = 10*numpy.log10(SNRavg)
470 470
471 471 if SNRthresh == None: SNRthresh = -5.0
472 472 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
473 473
474 474 for i in range(nplotsw):
475 475 z[i,ind] = numpy.nan
476 476
477 477
478 478 showprofile = False
479 479 # thisDatetime = dataOut.datatime
480 480 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[1])
481 481 title = wintitle + "Wind"
482 482 xlabel = ""
483 483 ylabel = "Range (Km)"
484 484
485 485 if not self.__isConfig:
486 486
487 487 self.setup(id=id,
488 488 nplots=nplots,
489 489 wintitle=wintitle,
490 490 showprofile=showprofile,
491 491 show=show)
492 492
493 493 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
494 494
495 495 if ymin == None: ymin = numpy.nanmin(y)
496 496 if ymax == None: ymax = numpy.nanmax(y)
497 497
498 498 if zmax == None: zmax = numpy.nanmax(abs(z[range(2),:]))
499 499 #if numpy.isnan(zmax): zmax = 50
500 500 if zmin == None: zmin = -zmax
501 501
502 502 if nplotsw == 3:
503 503 if zmax_ver == None: zmax_ver = numpy.nanmax(abs(z[2,:]))
504 504 if zmin_ver == None: zmin_ver = -zmax_ver
505 505
506 506 if dataOut.SNR != None:
507 507 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
508 508 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
509 509
510 510 self.FTP_WEI = ftp_wei
511 511 self.EXP_CODE = exp_code
512 512 self.SUB_EXP_CODE = sub_exp_code
513 513 self.PLOT_POS = plot_pos
514 514
515 515 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
516 516 self.__isConfig = True
517 517
518 518
519 519 self.setWinTitle(title)
520 520
521 521 if ((self.xmax - x[1]) < (x[1]-x[0])):
522 522 x[1] = self.xmax
523 523
524 524 strWind = ['Zonal', 'Meridional', 'Vertical']
525 525 strCb = ['Velocity (m/s)','Velocity (m/s)','Velocity (cm/s)']
526 526 zmaxVector = [zmax, zmax, zmax_ver]
527 527 zminVector = [zmin, zmin, zmin_ver]
528 528 windFactor = [1,1,100]
529 529
530 530 for i in range(nplotsw):
531 531
532 532 title = "%s Wind: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
533 533 axes = self.axesList[i*self.__nsubplots]
534 534
535 535 z1 = z[i,:].reshape((1,-1))*windFactor[i]
536 536
537 537 axes.pcolorbuffer(x, y, z1,
538 538 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
539 539 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
540 540 ticksize=9, cblabel=strCb[i], cbsize="1%", colormap="RdBu_r" )
541 541
542 542 if dataOut.SNR != None:
543 543 i += 1
544 544 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
545 545 axes = self.axesList[i*self.__nsubplots]
546 546
547 547 SNRavgdB = SNRavgdB.reshape((1,-1))
548 548
549 549 axes.pcolorbuffer(x, y, SNRavgdB,
550 550 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
551 551 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
552 552 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
553 553
554 554 self.draw()
555 555
556 556 if self.figfile == None:
557 557 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
558 558 self.figfile = self.getFilename(name = str_datetime)
559 559
560 560 if figpath != '':
561 561
562 562 self.counter_imagwr += 1
563 563 if (self.counter_imagwr>=wr_period):
564 564 # store png plot to local folder
565 565 self.saveFigure(figpath, self.figfile)
566 566 # store png plot to FTP server according to RT-Web format
567 567 name = self.getNameToFtp(thisDatetime, self.FTP_WEI, self.EXP_CODE, self.SUB_EXP_CODE, self.PLOT_CODE, self.PLOT_POS)
568 568 ftp_filename = os.path.join(figpath, name)
569 569 self.saveFigure(figpath, ftp_filename)
570 570
571 571 self.counter_imagwr = 0
572 572
573 573 if x[1] >= self.axesList[0].xmax:
574 574 self.counter_imagwr = wr_period
575 575 self.__isConfig = False
576 576 self.figfile = None
577
578
579 class RadialVelocityPlot(Figure):
580
581 __isConfig = None
582 __nsubplots = None
583
584 WIDTHPROF = None
585 HEIGHTPROF = None
586 PREFIX = 'rti'
587
588 def __init__(self):
589
590 self.timerange = 2*60*60
591 self.__isConfig = False
592 self.__nsubplots = 1
593
594 self.WIDTH = 800
595 self.HEIGHT = 150
596 self.WIDTHPROF = 120
597 self.HEIGHTPROF = 0
598 self.counter_imagwr = 0
599
600 self.PLOT_CODE = 0
601 self.FTP_WEI = None
602 self.EXP_CODE = None
603 self.SUB_EXP_CODE = None
604 self.PLOT_POS = None
605 self.tmin = None
606 self.tmax = None
607
608 self.xmin = None
609 self.xmax = None
610
611 self.figfile = None
612
613 def getSubplots(self):
614
615 ncol = 1
616 nrow = self.nplots
617
618 return nrow, ncol
619
620 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
621
622 self.__showprofile = showprofile
623 self.nplots = nplots
624
625 ncolspan = 1
626 colspan = 1
627
628 self.createFigure(id = id,
629 wintitle = wintitle,
630 widthplot = self.WIDTH + self.WIDTHPROF,
631 heightplot = self.HEIGHT + self.HEIGHTPROF,
632 show=show)
633
634 nrow, ncol = self.getSubplots()
635
636 counter = 0
637 for y in range(nrow):
638 for x in range(ncol):
639
640 if counter >= self.nplots:
641 break
642
643 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
644
645 if showprofile:
646 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
647
648 counter += 1
649
650 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
651 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,timerange=None,
652 SNRmin = None, SNRmax = None, SNRthresh = None, paramIndex = None,
653 save=False, figpath='', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
654 server=None, folder=None, username=None, password=None,
655 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
656
657 """
658
659 Input:
660 dataOut :
661 id :
662 wintitle :
663 channelList :
664 showProfile :
665 xmin : None,
666 xmax : None,
667 ymin : None,
668 ymax : None,
669 zmin : None,
670 zmax : None
671 """
672
673 if channelList == None:
674 channelIndexList = dataOut.channelIndexList
675 else:
676 channelIndexList = []
677 for channel in channelList:
678 if channel not in dataOut.channelList:
679 raise ValueError, "Channel %d is not in dataOut.channelList"
680 channelIndexList.append(dataOut.channelList.index(channel))
681
682 if timerange != None:
683 self.timerange = timerange
684
685 #tmin = None
686 #tmax = None
687 if paramIndex == None:
688 paramIndex = 1
689 x = dataOut.getTimeRange1()
690 y = dataOut.heightRange
691 z = dataOut.data_param[channelIndexList,paramIndex,:].copy()
692
693 zRange = dataOut.abscissaRange
694 nplots = z.shape[0] #Number of wind dimensions estimated
695 nplotsw = nplots
696
697 if dataOut.SNR != None:
698 nplots += 1
699 SNR = dataOut.SNR
700 SNRavg = numpy.average(SNR, axis=0)
701
702 SNRdB = 10*numpy.log10(SNR)
703 SNRavgdB = 10*numpy.log10(SNRavg)
704
705 if SNRthresh == None: SNRthresh = -5.0
706 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
707
708 for i in range(nplotsw):
709 z[i,ind] = numpy.nan
710 # thisDatetime = dataOut.datatime
711 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[1])
712 title = wintitle + " Radial Velocity" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
713 xlabel = ""
714 ylabel = "Height (Km)"
715
716 if not self.__isConfig:
717
718 self.setup(id=id,
719 nplots=nplots,
720 wintitle=wintitle,
721 showprofile=showprofile,
722 show=show)
723
724 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
725
726 if ymin == None: ymin = numpy.nanmin(y)
727 if ymax == None: ymax = numpy.nanmax(y)
728 if zmin == None: zmin = numpy.nanmin(zRange)
729 if zmax == None: zmax = numpy.nanmax(zRange)
730 if dataOut.SNR != None:
731 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
732 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
733
734 self.FTP_WEI = ftp_wei
735 self.EXP_CODE = exp_code
736 self.SUB_EXP_CODE = sub_exp_code
737 self.PLOT_POS = plot_pos
738
739 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
740 self.__isConfig = True
741 self.figfile = figfile
742
743 self.setWinTitle(title)
744
745 if ((self.xmax - x[1]) < (x[1]-x[0])):
746 x[1] = self.xmax
747
748 for i in range(nplotsw):
749 title = "Channel %d: %s" %(dataOut.channelList[i]+1, thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
750 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
751 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
752 axes = self.axesList[i*self.__nsubplots]
753 z1 = z[i,:].reshape((1,-1))
754 axes.pcolorbuffer(x, y, z1,
755 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
756 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap="RdBu_r",
757 ticksize=9, cblabel='', cbsize="1%")
758
759 if dataOut.SNR != None:
760 i += 1
761 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
762 axes = self.axesList[i*self.__nsubplots]
763
764 SNRavgdB = SNRavgdB.reshape((1,-1))
765
766 axes.pcolorbuffer(x, y, SNRavgdB,
767 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
768 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
769 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
770
771 self.draw()
772
773 if self.figfile == None:
774 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
775 self.figfile = self.getFilename(name = str_datetime)
776
777 if figpath != '':
778
779 self.counter_imagwr += 1
780 if (self.counter_imagwr>=wr_period):
781 # store png plot to local folder
782 self.saveFigure(figpath, self.figfile)
783 # store png plot to FTP server according to RT-Web format
784 name = self.getNameToFtp(thisDatetime, self.FTP_WEI, self.EXP_CODE, self.SUB_EXP_CODE, self.PLOT_CODE, self.PLOT_POS)
785 ftp_filename = os.path.join(figpath, name)
786 self.saveFigure(figpath, ftp_filename)
787
788 self.counter_imagwr = 0
789
790 if x[1] >= self.axesList[0].xmax:
791 self.counter_imagwr = wr_period
792 self.__isConfig = False
793 self.figfile = None No newline at end of file
@@ -1,1539 +1,1539
1 1 import numpy
2 2 import math
3 3 from scipy import optimize
4 4 from scipy import interpolate
5 5 from scipy import signal
6 6 from scipy import stats
7 7 import re
8 8 import datetime
9 9 import copy
10 10
11 11
12 12 from jroproc_base import ProcessingUnit, Operation
13 13 from model.data.jrodata import Parameters
14 14
15 15
16 16 class ParametersProc(ProcessingUnit):
17 17
18 18 nSeconds = None
19 19
20 20 def __init__(self):
21 21 ProcessingUnit.__init__(self)
22 22
23 23 self.objectDict = {}
24 24 self.buffer = None
25 25 self.firstdatatime = None
26 26 self.profIndex = 0
27 27 self.dataOut = Parameters()
28 28
29 29 def __updateObjFromInput(self):
30 30
31 31 self.dataOut.inputUnit = self.dataIn.type
32 32
33 33 self.dataOut.timeZone = self.dataIn.timeZone
34 34 self.dataOut.dstFlag = self.dataIn.dstFlag
35 35 self.dataOut.errorCount = self.dataIn.errorCount
36 36 self.dataOut.useLocalTime = self.dataIn.useLocalTime
37 37
38 38 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
39 39 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
40 40 self.dataOut.channelList = self.dataIn.channelList
41 41 self.dataOut.heightList = self.dataIn.heightList
42 42 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
43 43 # self.dataOut.nHeights = self.dataIn.nHeights
44 44 # self.dataOut.nChannels = self.dataIn.nChannels
45 45 self.dataOut.nBaud = self.dataIn.nBaud
46 46 self.dataOut.nCode = self.dataIn.nCode
47 47 self.dataOut.code = self.dataIn.code
48 48 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
49 49 self.dataOut.flagTimeBlock = self.dataIn.flagTimeBlock
50 50 self.dataOut.utctime = self.firstdatatime
51 51 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
52 52 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
53 53 # self.dataOut.nCohInt = self.dataIn.nCohInt
54 54 # self.dataOut.nIncohInt = 1
55 55 self.dataOut.ippSeconds = self.dataIn.ippSeconds
56 56 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
57 57 self.dataOut.timeInterval = self.dataIn.timeInterval
58 58 self.dataOut.heightRange = self.dataIn.getHeiRange()
59 59 self.dataOut.frequency = self.dataIn.frequency
60 60
61 61 def run(self, nSeconds = None, nProfiles = None):
62 62
63 63 self.dataOut.flagNoData = True
64 64
65 65 if self.firstdatatime == None:
66 66 self.firstdatatime = self.dataIn.utctime
67 67
68 68 #---------------------- Voltage Data ---------------------------
69 69
70 70 if self.dataIn.type == "Voltage":
71 71 if nSeconds != None:
72 72 self.nSeconds = nSeconds
73 73 self.nProfiles= int(numpy.floor(nSeconds/(self.dataIn.ippSeconds*self.dataIn.nCohInt)))
74 74
75 75 if self.buffer == None:
76 76 self.buffer = numpy.zeros((self.dataIn.nChannels,
77 77 self.nProfiles,
78 78 self.dataIn.nHeights),
79 79 dtype='complex')
80 80
81 81 self.buffer[:,self.profIndex,:] = self.dataIn.data.copy()
82 82 self.profIndex += 1
83 83
84 84 if self.profIndex == self.nProfiles:
85 85
86 86 self.__updateObjFromInput()
87 87 self.dataOut.data_pre = self.buffer.copy()
88 88 self.dataOut.paramInterval = nSeconds
89 89 self.dataOut.flagNoData = False
90 90
91 91 self.buffer = None
92 92 self.firstdatatime = None
93 93 self.profIndex = 0
94 return
94 95
95 96 #---------------------- Spectra Data ---------------------------
96 97
97 98 if self.dataIn.type == "Spectra":
98 99 self.dataOut.data_pre = self.dataIn.data_spc.copy()
99 100 self.dataOut.abscissaRange = self.dataIn.getVelRange(1)
100 101 self.dataOut.noise = self.dataIn.getNoise()
101 102 self.dataOut.normFactor = self.dataIn.normFactor
102 103
103 self.__updateObjFromInput()
104 self.dataOut.flagNoData = False
105 self.firstdatatime = None
106
107 104 #---------------------- Correlation Data ---------------------------
108 105
109 106 if self.dataIn.type == "Correlation":
110 107 lagRRange = self.dataIn.lagR
111 108 indR = numpy.where(lagRRange == 0)[0][0]
112 109
113 110 self.dataOut.data_pre = self.dataIn.data_corr.copy()[:,:,indR,:]
114 111 self.dataOut.abscissaRange = self.dataIn.getLagTRange(1)
115 112 self.dataOut.noise = self.dataIn.noise
116 113 self.dataOut.normFactor = self.dataIn.normFactor
117 114 self.dataOut.SNR = self.dataIn.SNR
118 115 self.dataOut.pairsList = self.dataIn.pairsList
119 116
117
120 118 self.__updateObjFromInput()
121 119 self.dataOut.flagNoData = False
122 120 self.firstdatatime = None
121 self.dataOut.initUtcTime = self.dataIn.ltctime
122 self.dataOut.windsInterval = self.dataIn.timeInterval
123 123
124 124 #------------------- Get Moments ----------------------------------
125 125 def GetMoments(self, channelList = None):
126 126 '''
127 127 Function GetMoments()
128 128
129 129 Input:
130 130 channelList : simple channel list to select e.g. [2,3,7]
131 131 self.dataOut.data_pre
132 132 self.dataOut.abscissaRange
133 133 self.dataOut.noise
134 134
135 135 Affected:
136 136 self.dataOut.data_param
137 137 self.dataOut.SNR
138 138
139 139 '''
140 140 data = self.dataOut.data_pre
141 141 absc = self.dataOut.abscissaRange[:-1]
142 142 noise = self.dataOut.noise
143 143
144 144 data_param = numpy.zeros((data.shape[0], 4, data.shape[2]))
145 145
146 if channelList== None: channelList = self.dataOut.channelList
146 if channelList== None:
147 channelList = self.dataIn.channelList
148 self.dataOut.channelList = channelList
147 149
148 150 for ind in channelList:
149 151 data_param[ind,:,:] = self.__calculateMoments(data[ind,:,:], absc, noise[ind])
150 152
151 self.dataOut.data_param = data_param[:,1:]
153 self.dataOut.data_param = data_param[:,1:,:]
152 154 self.dataOut.SNR = data_param[:,0]
153 155 return
154 156
155 157 def __calculateMoments(self, oldspec, oldfreq, n0, nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
156 158
157 159 if (nicoh == None): nicoh = 1
158 160 if (graph == None): graph = 0
159 161 if (smooth == None): smooth = 0
160 162 elif (self.smooth < 3): smooth = 0
161 163
162 164 if (type1 == None): type1 = 0
163 165 if (fwindow == None): fwindow = numpy.zeros(oldfreq.size) + 1
164 166 if (snrth == None): snrth = -3
165 167 if (dc == None): dc = 0
166 168 if (aliasing == None): aliasing = 0
167 169 if (oldfd == None): oldfd = 0
168 170 if (wwauto == None): wwauto = 0
169 171
170 172 if (n0 < 1.e-20): n0 = 1.e-20
171 173
172 174 freq = oldfreq
173 175 vec_power = numpy.zeros(oldspec.shape[1])
174 176 vec_fd = numpy.zeros(oldspec.shape[1])
175 177 vec_w = numpy.zeros(oldspec.shape[1])
176 178 vec_snr = numpy.zeros(oldspec.shape[1])
177 179
178 180 for ind in range(oldspec.shape[1]):
179 181
180 182 spec = oldspec[:,ind]
181 183 aux = spec*fwindow
182 184 max_spec = aux.max()
183 185 m = list(aux).index(max_spec)
184 186
185 187 #Smooth
186 188 if (smooth == 0): spec2 = spec
187 189 else: spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
188 190
189 191 # Calculo de Momentos
190 192 bb = spec2[range(m,spec2.size)]
191 193 bb = (bb<n0).nonzero()
192 194 bb = bb[0]
193 195
194 196 ss = spec2[range(0,m + 1)]
195 197 ss = (ss<n0).nonzero()
196 198 ss = ss[0]
197 199
198 200 if (bb.size == 0):
199 201 bb0 = spec.size - 1 - m
200 202 else:
201 203 bb0 = bb[0] - 1
202 204 if (bb0 < 0):
203 205 bb0 = 0
204 206
205 207 if (ss.size == 0): ss1 = 1
206 208 else: ss1 = max(ss) + 1
207 209
208 210 if (ss1 > m): ss1 = m
209 211
210 212 valid = numpy.asarray(range(int(m + bb0 - ss1 + 1))) + ss1
211 213 power = ((spec2[valid] - n0)*fwindow[valid]).sum()
212 214 fd = ((spec2[valid]- n0)*freq[valid]*fwindow[valid]).sum()/power
213 215 w = math.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum()/power)
214 216 snr = (spec2.mean()-n0)/n0
215 217
216 218 if (snr < 1.e-20) :
217 219 snr = 1.e-20
218 220
219 221 vec_power[ind] = power
220 222 vec_fd[ind] = fd
221 223 vec_w[ind] = w
222 224 vec_snr[ind] = snr
223 225
224 226 moments = numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
225 227 return moments
226 228
227 229 #------------------- Get Lags ----------------------------------
228 230
229 231 def GetLags(self):
230 232 '''
231 233 Function GetMoments()
232 234
233 235 Input:
234 236 self.dataOut.data_pre
235 237 self.dataOut.abscissaRange
236 238 self.dataOut.noise
237 239 self.dataOut.normFactor
238 240 self.dataOut.SNR
239 241 self.dataOut.pairsList
240 242 self.dataOut.nChannels
241 243
242 244 Affected:
243 245 self.dataOut.data_param
244 246
245 247 '''
246 248 data = self.dataOut.data_pre
247 249 normFactor = self.dataOut.normFactor
248 250 nHeights = self.dataOut.nHeights
249 251 absc = self.dataOut.abscissaRange[:-1]
250 252 noise = self.dataOut.noise
251 253 SNR = self.dataOut.SNR
252 254 pairsList = self.dataOut.pairsList
253 255 nChannels = self.dataOut.nChannels
254 256 pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
255 257 self.dataOut.data_param = numpy.zeros((len(pairsCrossCorr)*2 + 1, nHeights))
256 258
257 259 dataNorm = numpy.abs(data)
258 260 for l in range(len(pairsList)):
259 261 dataNorm[l,:,:] = dataNorm[l,:,:]/normFactor[l,:]
260 262
261 263 self.dataOut.data_param[:-1,:] = self.__calculateTaus(dataNorm, pairsCrossCorr, pairsAutoCorr, absc)
262 264 self.dataOut.data_param[-1,:] = self.__calculateLag1Phase(data, pairsAutoCorr, absc)
263 265 return
264 266
265 267 def __getPairsAutoCorr(self, pairsList, nChannels):
266 268
267 269 pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
268 270
269 271 for l in range(len(pairsList)):
270 272 firstChannel = pairsList[l][0]
271 273 secondChannel = pairsList[l][1]
272 274
273 275 #Obteniendo pares de Autocorrelacion
274 276 if firstChannel == secondChannel:
275 277 pairsAutoCorr[firstChannel] = int(l)
276 278
277 279 pairsAutoCorr = pairsAutoCorr.astype(int)
278 280
279 281 pairsCrossCorr = range(len(pairsList))
280 282 pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
281 283
282 284 return pairsAutoCorr, pairsCrossCorr
283 285
284 286 def __calculateTaus(self, data, pairsCrossCorr, pairsAutoCorr, lagTRange):
285 287
286 288 Pt0 = data.shape[1]/2
287 289 #Funcion de Autocorrelacion
288 290 dataAutoCorr = stats.nanmean(data[pairsAutoCorr,:,:], axis = 0)
289 291
290 292 #Obtencion Indice de TauCross
291 293 indCross = data[pairsCrossCorr,:,:].argmax(axis = 1)
292 294 #Obtencion Indice de TauAuto
293 295 indAuto = numpy.zeros(indCross.shape,dtype = 'int')
294 296 CCValue = data[pairsCrossCorr,Pt0,:]
295 297 for i in range(pairsCrossCorr.size):
296 298 indAuto[i,:] = numpy.abs(dataAutoCorr - CCValue[i,:]).argmin(axis = 0)
297 299
298 300 #Obtencion de TauCross y TauAuto
299 301 tauCross = lagTRange[indCross]
300 302 tauAuto = lagTRange[indAuto]
301 303
302 304 Nan1, Nan2 = numpy.where(tauCross == lagTRange[0])
303 305
304 306 tauCross[Nan1,Nan2] = numpy.nan
305 307 tauAuto[Nan1,Nan2] = numpy.nan
306 308 tau = numpy.vstack((tauCross,tauAuto))
307 309
308 310 return tau
309 311
310 312 def __calculateLag1Phase(self, data, pairs, lagTRange):
311 313 data1 = stats.nanmean(data[pairs,:,:], axis = 0)
312 314 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
313 315
314 316 phase = numpy.angle(data1[lag1,:])
315 317
316 318 return phase
317 319 #------------------- Detect Meteors ------------------------------
318 320
319 321 def DetectMeteors(self, hei_ref = None, tauindex = 0,
320 322 predefinedPhaseShifts = None, centerReceiverIndex = 2,
321 323 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
322 324 noise_timeStep = 4, noise_multiple = 4,
323 325 multDet_timeLimit = 1, multDet_rangeLimit = 3,
324 326 phaseThresh = 20, SNRThresh = 8,
325 327 hmin = 70, hmax=110, azimuth = 0) :
326 328
327 329 '''
328 330 Function DetectMeteors()
329 331 Project developed with paper:
330 332 HOLDSWORTH ET AL. 2004
331 333
332 334 Input:
333 335 self.dataOut.data_pre
334 336
335 337 centerReceiverIndex: From the channels, which is the center receiver
336 338
337 339 hei_ref: Height reference for the Beacon signal extraction
338 340 tauindex:
339 341 predefinedPhaseShifts: Predefined phase offset for the voltge signals
340 342
341 343 cohDetection: Whether to user Coherent detection or not
342 344 cohDet_timeStep: Coherent Detection calculation time step
343 345 cohDet_thresh: Coherent Detection phase threshold to correct phases
344 346
345 347 noise_timeStep: Noise calculation time step
346 348 noise_multiple: Noise multiple to define signal threshold
347 349
348 350 multDet_timeLimit: Multiple Detection Removal time limit in seconds
349 351 multDet_rangeLimit: Multiple Detection Removal range limit in km
350 352
351 353 phaseThresh: Maximum phase difference between receiver to be consider a meteor
352 354 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
353 355
354 356 hmin: Minimum Height of the meteor to use it in the further wind estimations
355 357 hmax: Maximum Height of the meteor to use it in the further wind estimations
356 358 azimuth: Azimuth angle correction
357 359
358 360 Affected:
359 361 self.dataOut.data_param
360 362
361 363 Rejection Criteria (Errors):
362 364 0: No error; analysis OK
363 365 1: SNR < SNR threshold
364 366 2: angle of arrival (AOA) ambiguously determined
365 367 3: AOA estimate not feasible
366 368 4: Large difference in AOAs obtained from different antenna baselines
367 369 5: echo at start or end of time series
368 370 6: echo less than 5 examples long; too short for analysis
369 371 7: echo rise exceeds 0.3s
370 372 8: echo decay time less than twice rise time
371 373 9: large power level before echo
372 374 10: large power level after echo
373 375 11: poor fit to amplitude for estimation of decay time
374 376 12: poor fit to CCF phase variation for estimation of radial drift velocity
375 377 13: height unresolvable echo: not valid height within 70 to 110 km
376 378 14: height ambiguous echo: more then one possible height within 70 to 110 km
377 379 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
378 380 16: oscilatory echo, indicating event most likely not an underdense echo
379 381
380 382 17: phase difference in meteor Reestimation
381 383
382 384 Data Storage:
383 385 Meteors for Wind Estimation (8):
384 386 Day Hour | Range Height
385 387 Azimuth Zenith errorCosDir
386 388 VelRad errorVelRad
387 389 TypeError
388 390
389 391 '''
390 392 #Get Beacon signal
391 393 newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
392 394
393 395 if hei_ref != None:
394 396 newheis = numpy.where(self.dataOut.heightList>hei_ref)
395 397
396 398 heiRang = self.dataOut.getHeiRange()
397 399 #Pairs List
398 400 pairslist = []
399 401 nChannel = self.dataOut.nChannels
400 402 for i in range(nChannel):
401 403 if i != centerReceiverIndex:
402 404 pairslist.append((centerReceiverIndex,i))
403 405
404 406 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
405 407 # see if the user put in pre defined phase shifts
406 408 voltsPShift = self.dataOut.data_pre.copy()
407 409
408 410 if predefinedPhaseShifts != None:
409 411 hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
410 412 else:
411 413 #get hardware phase shifts using beacon signal
412 414 hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
413 415 hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
414 416
415 417 voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
416 418 for i in range(self.dataOut.data_pre.shape[0]):
417 419 voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
418 420 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
419 421
420 422 #Remove DC
421 423 voltsDC = numpy.mean(voltsPShift,1)
422 424 voltsDC = numpy.mean(voltsDC,1)
423 425 for i in range(voltsDC.shape[0]):
424 426 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
425 427
426 428 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
427 429 voltsPShift = voltsPShift[:,:,:newheis[0][0]]
428 430
429 431 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
430 432 #Coherent Detection
431 433 if cohDetection:
432 434 #use coherent detection to get the net power
433 435 cohDet_thresh = cohDet_thresh*numpy.pi/180
434 436 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, self.dataOut.timeInterval, pairslist, cohDet_thresh)
435 437
436 438 #Non-coherent detection!
437 439 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
438 440 #********** END OF COH/NON-COH POWER CALCULATION**********************
439 441
440 442 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
441 443 #Get noise
442 444 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, self.dataOut.timeInterval)
443 445 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
444 446 #Get signal threshold
445 447 signalThresh = noise_multiple*noise
446 448 #Meteor echoes detection
447 449 listMeteors = self.__findMeteors(powerNet, signalThresh)
448 450 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
449 451
450 452 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
451 453 #Parameters
452 454 heiRange = self.dataOut.getHeiRange()
453 455 rangeInterval = heiRange[1] - heiRange[0]
454 456 rangeLimit = multDet_rangeLimit/rangeInterval
455 457 timeLimit = multDet_timeLimit/self.dataOut.timeInterval
456 458 #Multiple detection removals
457 459 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
458 460 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
459 461
460 462 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
461 463 #Parameters
462 464 phaseThresh = phaseThresh*numpy.pi/180
463 465 thresh = [phaseThresh, noise_multiple, SNRThresh]
464 466 #Meteor reestimation (Errors N 1, 6, 12, 17)
465 467 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist, thresh, noise, self.dataOut.timeInterval, self.dataOut.frequency)
466 468 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
467 469 #Estimation of decay times (Errors N 7, 8, 11)
468 470 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, self.dataOut.timeInterval, self.dataOut.frequency)
469 471 #******************* END OF METEOR REESTIMATION *******************
470 472
471 473 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
472 474 #Calculating Radial Velocity (Error N 15)
473 475 radialStdThresh = 10
474 476 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist, self.dataOut.timeInterval)
475 477
476 478 if len(listMeteors4) > 0:
477 479 #Setting New Array
478 480 date = repr(self.dataOut.datatime)
479 481 arrayMeteors4, arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
480 482
481 483 #Calculate AOA (Error N 3, 4)
482 484 #JONES ET AL. 1998
483 485 AOAthresh = numpy.pi/8
484 486 error = arrayParameters[:,-1]
485 487 phases = -arrayMeteors4[:,9:13]
486 488 pairsList = []
487 489 pairsList.append((0,3))
488 490 pairsList.append((1,2))
489 491 arrayParameters[:,4:7], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, error, AOAthresh, azimuth)
490 492
491 493 #Calculate Heights (Error N 13 and 14)
492 494 error = arrayParameters[:,-1]
493 495 Ranges = arrayParameters[:,2]
494 496 zenith = arrayParameters[:,5]
495 497 arrayParameters[:,3], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
496 498 #********************* END OF PARAMETERS CALCULATION **************************
497 499
498 500 #***************************+ SAVE DATA IN HDF5 FORMAT **********************
499 501 self.dataOut.data_param = arrayParameters
500 502
501 503 return
502 504
503 505 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
504 506
505 507 minIndex = min(newheis[0])
506 508 maxIndex = max(newheis[0])
507 509
508 510 voltage = voltage0[:,:,minIndex:maxIndex+1]
509 511 nLength = voltage.shape[1]/n
510 512 nMin = 0
511 513 nMax = 0
512 514 phaseOffset = numpy.zeros((len(pairslist),n))
513 515
514 516 for i in range(n):
515 517 nMax += nLength
516 518 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
517 519 phaseCCF = numpy.mean(phaseCCF, axis = 2)
518 520 phaseOffset[:,i] = phaseCCF.transpose()
519 521 nMin = nMax
520 522 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
521 523
522 524 #Remove Outliers
523 525 factor = 2
524 526 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
525 527 dw = numpy.std(wt,axis = 1)
526 528 dw = dw.reshape((dw.size,1))
527 529 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
528 530 phaseOffset[ind] = numpy.nan
529 531 phaseOffset = stats.nanmean(phaseOffset, axis=1)
530 532
531 533 return phaseOffset
532 534
533 535 def __shiftPhase(self, data, phaseShift):
534 536 #this will shift the phase of a complex number
535 537 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
536 538 return dataShifted
537 539
538 540 def __estimatePhaseDifference(self, array, pairslist):
539 541 nChannel = array.shape[0]
540 542 nHeights = array.shape[2]
541 543 numPairs = len(pairslist)
542 544 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
543 545 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
544 546
545 547 #Correct phases
546 548 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
547 549 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
548 550
549 551 if indDer[0].shape[0] > 0:
550 552 for i in range(indDer[0].shape[0]):
551 553 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
552 554 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
553 555
554 556 # for j in range(numSides):
555 557 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
556 558 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
557 559 #
558 560 #Linear
559 561 phaseInt = numpy.zeros((numPairs,1))
560 562 angAllCCF = phaseCCF[:,[0,1,3,4],0]
561 563 for j in range(numPairs):
562 564 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
563 565 phaseInt[j] = fit[1]
564 566 #Phase Differences
565 567 phaseDiff = phaseInt - phaseCCF[:,2,:]
566 568 phaseArrival = phaseInt.reshape(phaseInt.size)
567 569
568 570 #Dealias
569 571 indAlias = numpy.where(phaseArrival > numpy.pi)
570 572 phaseArrival[indAlias] -= 2*numpy.pi
571 573 indAlias = numpy.where(phaseArrival < -numpy.pi)
572 574 phaseArrival[indAlias] += 2*numpy.pi
573 575
574 576 return phaseDiff, phaseArrival
575 577
576 578 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
577 579 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
578 580 #find the phase shifts of each channel over 1 second intervals
579 581 #only look at ranges below the beacon signal
580 582 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
581 583 numBlocks = int(volts.shape[1]/numProfPerBlock)
582 584 numHeights = volts.shape[2]
583 585 nChannel = volts.shape[0]
584 586 voltsCohDet = volts.copy()
585 587
586 588 pairsarray = numpy.array(pairslist)
587 589 indSides = pairsarray[:,1]
588 590 # indSides = numpy.array(range(nChannel))
589 591 # indSides = numpy.delete(indSides, indCenter)
590 592 #
591 593 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
592 594 listBlocks = numpy.array_split(volts, numBlocks, 1)
593 595
594 596 startInd = 0
595 597 endInd = 0
596 598
597 599 for i in range(numBlocks):
598 600 startInd = endInd
599 601 endInd = endInd + listBlocks[i].shape[1]
600 602
601 603 arrayBlock = listBlocks[i]
602 604 # arrayBlockCenter = listCenter[i]
603 605
604 606 #Estimate the Phase Difference
605 607 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
606 608 #Phase Difference RMS
607 609 arrayPhaseRMS = numpy.abs(phaseDiff)
608 610 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
609 611 indPhase = numpy.where(phaseRMSaux==4)
610 612 #Shifting
611 613 if indPhase[0].shape[0] > 0:
612 614 for j in range(indSides.size):
613 615 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
614 616 voltsCohDet[:,startInd:endInd,:] = arrayBlock
615 617
616 618 return voltsCohDet
617 619
618 620 def __calculateCCF(self, volts, pairslist ,laglist):
619 621
620 622 nHeights = volts.shape[2]
621 623 nPoints = volts.shape[1]
622 624 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
623 625
624 626 for i in range(len(pairslist)):
625 627 volts1 = volts[pairslist[i][0]]
626 628 volts2 = volts[pairslist[i][1]]
627 629
628 630 for t in range(len(laglist)):
629 631 idxT = laglist[t]
630 632 if idxT >= 0:
631 633 vStacked = numpy.vstack((volts2[idxT:,:],
632 634 numpy.zeros((idxT, nHeights),dtype='complex')))
633 635 else:
634 636 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
635 637 volts2[:(nPoints + idxT),:]))
636 638 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
637 639
638 640 vStacked = None
639 641 return voltsCCF
640 642
641 643 def __getNoise(self, power, timeSegment, timeInterval):
642 644 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
643 645 numBlocks = int(power.shape[0]/numProfPerBlock)
644 646 numHeights = power.shape[1]
645 647
646 648 listPower = numpy.array_split(power, numBlocks, 0)
647 649 noise = numpy.zeros((power.shape[0], power.shape[1]))
648 650 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
649 651
650 652 startInd = 0
651 653 endInd = 0
652 654
653 655 for i in range(numBlocks): #split por canal
654 656 startInd = endInd
655 657 endInd = endInd + listPower[i].shape[0]
656 658
657 659 arrayBlock = listPower[i]
658 660 noiseAux = numpy.mean(arrayBlock, 0)
659 661 # noiseAux = numpy.median(noiseAux)
660 662 # noiseAux = numpy.mean(arrayBlock)
661 663 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
662 664
663 665 noiseAux1 = numpy.mean(arrayBlock)
664 666 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
665 667
666 668 return noise, noise1
667 669
668 670 def __findMeteors(self, power, thresh):
669 671 nProf = power.shape[0]
670 672 nHeights = power.shape[1]
671 673 listMeteors = []
672 674
673 675 for i in range(nHeights):
674 676 powerAux = power[:,i]
675 677 threshAux = thresh[:,i]
676 678
677 679 indUPthresh = numpy.where(powerAux > threshAux)[0]
678 680 indDNthresh = numpy.where(powerAux <= threshAux)[0]
679 681
680 682 j = 0
681 683
682 684 while (j < indUPthresh.size - 2):
683 685 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
684 686 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
685 687 indDNthresh = indDNthresh[indDNAux]
686 688
687 689 if (indDNthresh.size > 0):
688 690 indEnd = indDNthresh[0] - 1
689 691 indInit = indUPthresh[j]
690 692
691 693 meteor = powerAux[indInit:indEnd + 1]
692 694 indPeak = meteor.argmax() + indInit
693 695 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
694 696
695 697 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
696 698 j = numpy.where(indUPthresh == indEnd)[0] + 1
697 699 else: j+=1
698 700 else: j+=1
699 701
700 702 return listMeteors
701 703
702 704 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
703 705
704 706 arrayMeteors = numpy.asarray(listMeteors)
705 707 listMeteors1 = []
706 708
707 709 while arrayMeteors.shape[0] > 0:
708 710 FLAs = arrayMeteors[:,4]
709 711 maxFLA = FLAs.argmax()
710 712 listMeteors1.append(arrayMeteors[maxFLA,:])
711 713
712 714 MeteorInitTime = arrayMeteors[maxFLA,1]
713 715 MeteorEndTime = arrayMeteors[maxFLA,3]
714 716 MeteorHeight = arrayMeteors[maxFLA,0]
715 717
716 718 #Check neighborhood
717 719 maxHeightIndex = MeteorHeight + rangeLimit
718 720 minHeightIndex = MeteorHeight - rangeLimit
719 721 minTimeIndex = MeteorInitTime - timeLimit
720 722 maxTimeIndex = MeteorEndTime + timeLimit
721 723
722 724 #Check Heights
723 725 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
724 726 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
725 727 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
726 728
727 729 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
728 730
729 731 return listMeteors1
730 732
731 733 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
732 734 numHeights = volts.shape[2]
733 735 nChannel = volts.shape[0]
734 736
735 737 thresholdPhase = thresh[0]
736 738 thresholdNoise = thresh[1]
737 739 thresholdDB = float(thresh[2])
738 740
739 741 thresholdDB1 = 10**(thresholdDB/10)
740 742 pairsarray = numpy.array(pairslist)
741 743 indSides = pairsarray[:,1]
742 744
743 745 pairslist1 = list(pairslist)
744 746 pairslist1.append((0,1))
745 747 pairslist1.append((3,4))
746 748
747 749 listMeteors1 = []
748 750 listPowerSeries = []
749 751 listVoltageSeries = []
750 752 #volts has the war data
751 753
752 754 if frequency == 30e6:
753 755 timeLag = 45*10**-3
754 756 else:
755 757 timeLag = 15*10**-3
756 758 lag = numpy.ceil(timeLag/timeInterval)
757 759
758 760 for i in range(len(listMeteors)):
759 761
760 762 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
761 763 meteorAux = numpy.zeros(16)
762 764
763 765 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
764 766 mHeight = listMeteors[i][0]
765 767 mStart = listMeteors[i][1]
766 768 mPeak = listMeteors[i][2]
767 769 mEnd = listMeteors[i][3]
768 770
769 771 #get the volt data between the start and end times of the meteor
770 772 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
771 773 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
772 774
773 775 #3.6. Phase Difference estimation
774 776 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
775 777
776 778 #3.7. Phase difference removal & meteor start, peak and end times reestimated
777 779 #meteorVolts0.- all Channels, all Profiles
778 780 meteorVolts0 = volts[:,:,mHeight]
779 781 meteorThresh = noise[:,mHeight]*thresholdNoise
780 782 meteorNoise = noise[:,mHeight]
781 783 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
782 784 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
783 785
784 786 #Times reestimation
785 787 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
786 788 if mStart1.size > 0:
787 789 mStart1 = mStart1[-1] + 1
788 790
789 791 else:
790 792 mStart1 = mPeak
791 793
792 794 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
793 795 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
794 796 if mEndDecayTime1.size == 0:
795 797 mEndDecayTime1 = powerNet0.size
796 798 else:
797 799 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
798 800 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
799 801
800 802 #meteorVolts1.- all Channels, from start to end
801 803 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
802 804 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
803 805 if meteorVolts2.shape[1] == 0:
804 806 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
805 807 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
806 808 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
807 809 ##################### END PARAMETERS REESTIMATION #########################
808 810
809 811 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
810 812 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
811 813 if meteorVolts2.shape[1] > 0:
812 814 #Phase Difference re-estimation
813 815 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
814 816 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
815 817 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
816 818 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
817 819 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
818 820
819 821 #Phase Difference RMS
820 822 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
821 823 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
822 824 #Data from Meteor
823 825 mPeak1 = powerNet1.argmax() + mStart1
824 826 mPeakPower1 = powerNet1.max()
825 827 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
826 828 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
827 829 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
828 830 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
829 831 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
830 832 #Vectorize
831 833 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
832 834 meteorAux[7:11] = phaseDiffint[0:4]
833 835
834 836 #Rejection Criterions
835 837 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
836 838 meteorAux[-1] = 17
837 839 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
838 840 meteorAux[-1] = 1
839 841
840 842
841 843 else:
842 844 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
843 845 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
844 846 PowerSeries = 0
845 847
846 848 listMeteors1.append(meteorAux)
847 849 listPowerSeries.append(PowerSeries)
848 850 listVoltageSeries.append(meteorVolts1)
849 851
850 852 return listMeteors1, listPowerSeries, listVoltageSeries
851 853
852 854 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
853 855
854 856 threshError = 10
855 857 #Depending if it is 30 or 50 MHz
856 858 if frequency == 30e6:
857 859 timeLag = 45*10**-3
858 860 else:
859 861 timeLag = 15*10**-3
860 862 lag = numpy.ceil(timeLag/timeInterval)
861 863
862 864 listMeteors1 = []
863 865
864 866 for i in range(len(listMeteors)):
865 867 meteorPower = listPower[i]
866 868 meteorAux = listMeteors[i]
867 869
868 870 if meteorAux[-1] == 0:
869 871
870 872 try:
871 873 indmax = meteorPower.argmax()
872 874 indlag = indmax + lag
873 875
874 876 y = meteorPower[indlag:]
875 877 x = numpy.arange(0, y.size)*timeLag
876 878
877 879 #first guess
878 880 a = y[0]
879 881 tau = timeLag
880 882 #exponential fit
881 883 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
882 884 y1 = self.__exponential_function(x, *popt)
883 885 #error estimation
884 886 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
885 887
886 888 decayTime = popt[1]
887 889 riseTime = indmax*timeInterval
888 890 meteorAux[11:13] = [decayTime, error]
889 891
890 892 #Table items 7, 8 and 11
891 893 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
892 894 meteorAux[-1] = 7
893 895 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
894 896 meteorAux[-1] = 8
895 897 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
896 898 meteorAux[-1] = 11
897 899
898 900
899 901 except:
900 902 meteorAux[-1] = 11
901 903
902 904
903 905 listMeteors1.append(meteorAux)
904 906
905 907 return listMeteors1
906 908
907 909 #Exponential Function
908 910
909 911 def __exponential_function(self, x, a, tau):
910 912 y = a*numpy.exp(-x/tau)
911 913 return y
912 914
913 915 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
914 916
915 917 pairslist1 = list(pairslist)
916 918 pairslist1.append((0,1))
917 919 pairslist1.append((3,4))
918 920 numPairs = len(pairslist1)
919 921 #Time Lag
920 922 timeLag = 45*10**-3
921 923 c = 3e8
922 924 lag = numpy.ceil(timeLag/timeInterval)
923 925 freq = 30e6
924 926
925 927 listMeteors1 = []
926 928
927 929 for i in range(len(listMeteors)):
928 930 meteor = listMeteors[i]
929 931 meteorAux = numpy.hstack((meteor[:-1], 0, 0, meteor[-1]))
930 932 if meteor[-1] == 0:
931 933 mStart = listMeteors[i][1]
932 934 mPeak = listMeteors[i][2]
933 935 mLag = mPeak - mStart + lag
934 936
935 937 #get the volt data between the start and end times of the meteor
936 938 meteorVolts = listVolts[i]
937 939 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
938 940
939 941 #Get CCF
940 942 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
941 943
942 944 #Method 2
943 945 slopes = numpy.zeros(numPairs)
944 946 time = numpy.array([-2,-1,1,2])*timeInterval
945 947 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
946 948
947 949 #Correct phases
948 950 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
949 951 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
950 952
951 953 if indDer[0].shape[0] > 0:
952 954 for i in range(indDer[0].shape[0]):
953 955 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
954 956 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
955 957
956 958 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
957 959 for j in range(numPairs):
958 960 fit = stats.linregress(time, angAllCCF[j,:])
959 961 slopes[j] = fit[0]
960 962
961 963 #Remove Outlier
962 964 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
963 965 # slopes = numpy.delete(slopes,indOut)
964 966 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
965 967 # slopes = numpy.delete(slopes,indOut)
966 968
967 969 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
968 970 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
969 971 meteorAux[-2] = radialError
970 972 meteorAux[-3] = radialVelocity
971 973
972 974 #Setting Error
973 975 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
974 976 if numpy.abs(radialVelocity) > 200:
975 977 meteorAux[-1] = 15
976 978 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
977 979 elif radialError > radialStdThresh:
978 980 meteorAux[-1] = 12
979 981
980 982 listMeteors1.append(meteorAux)
981 983 return listMeteors1
982 984
983 985 def __setNewArrays(self, listMeteors, date, heiRang):
984 986
985 987 #New arrays
986 988 arrayMeteors = numpy.array(listMeteors)
987 989 arrayParameters = numpy.zeros((len(listMeteors),10))
988 990
989 991 #Date inclusion
990 992 date = re.findall(r'\((.*?)\)', date)
991 993 date = date[0].split(',')
992 994 date = map(int, date)
993 995 date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
994 996 arrayDate = numpy.tile(date, (len(listMeteors), 1))
995 997
996 998 #Meteor array
997 999 arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
998 1000 arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
999 1001
1000 1002 #Parameters Array
1001 1003 arrayParameters[:,0:3] = arrayMeteors[:,0:3]
1002 1004 arrayParameters[:,-3:] = arrayMeteors[:,-3:]
1003 1005
1004 1006 return arrayMeteors, arrayParameters
1005 1007
1006 1008 def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
1007 1009
1008 1010 arrayAOA = numpy.zeros((phases.shape[0],3))
1009 1011 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
1010 1012
1011 1013 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
1012 1014 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
1013 1015 arrayAOA[:,2] = cosDirError
1014 1016
1015 1017 azimuthAngle = arrayAOA[:,0]
1016 1018 zenithAngle = arrayAOA[:,1]
1017 1019
1018 1020 #Setting Error
1019 1021 #Number 3: AOA not fesible
1020 1022 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
1021 1023 error[indInvalid] = 3
1022 1024 #Number 4: Large difference in AOAs obtained from different antenna baselines
1023 1025 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
1024 1026 error[indInvalid] = 4
1025 1027 return arrayAOA, error
1026 1028
1027 1029 def __getDirectionCosines(self, arrayPhase, pairsList):
1028 1030
1029 1031 #Initializing some variables
1030 1032 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
1031 1033 ang_aux = ang_aux.reshape(1,ang_aux.size)
1032 1034
1033 1035 cosdir = numpy.zeros((arrayPhase.shape[0],2))
1034 1036 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
1035 1037
1036 1038
1037 1039 for i in range(2):
1038 1040 #First Estimation
1039 1041 phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
1040 1042 #Dealias
1041 1043 indcsi = numpy.where(phi0_aux > numpy.pi)
1042 1044 phi0_aux[indcsi] -= 2*numpy.pi
1043 1045 indcsi = numpy.where(phi0_aux < -numpy.pi)
1044 1046 phi0_aux[indcsi] += 2*numpy.pi
1045 1047 #Direction Cosine 0
1046 1048 cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
1047 1049
1048 1050 #Most-Accurate Second Estimation
1049 1051 phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
1050 1052 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
1051 1053 #Direction Cosine 1
1052 1054 cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
1053 1055
1054 1056 #Searching the correct Direction Cosine
1055 1057 cosdir0_aux = cosdir0[:,i]
1056 1058 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
1057 1059 #Minimum Distance
1058 1060 cosDiff = (cosdir1 - cosdir0_aux)**2
1059 1061 indcos = cosDiff.argmin(axis = 1)
1060 1062 #Saving Value obtained
1061 1063 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
1062 1064
1063 1065 return cosdir0, cosdir
1064 1066
1065 1067 def __calculateAOA(self, cosdir, azimuth):
1066 1068 cosdirX = cosdir[:,0]
1067 1069 cosdirY = cosdir[:,1]
1068 1070
1069 1071 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
1070 1072 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
1071 1073 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
1072 1074
1073 1075 return angles
1074 1076
1075 1077 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
1076 1078
1077 1079 Ramb = 375 #Ramb = c/(2*PRF)
1078 1080 Re = 6371 #Earth Radius
1079 1081 heights = numpy.zeros(Ranges.shape)
1080 1082
1081 1083 R_aux = numpy.array([0,1,2])*Ramb
1082 1084 R_aux = R_aux.reshape(1,R_aux.size)
1083 1085
1084 1086 Ranges = Ranges.reshape(Ranges.size,1)
1085 1087
1086 1088 Ri = Ranges + R_aux
1087 1089 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
1088 1090
1089 1091 #Check if there is a height between 70 and 110 km
1090 1092 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
1091 1093 ind_h = numpy.where(h_bool == 1)[0]
1092 1094
1093 1095 hCorr = hi[ind_h, :]
1094 1096 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
1095 1097
1096 1098 hCorr = hi[ind_hCorr]
1097 1099 heights[ind_h] = hCorr
1098 1100
1099 1101 #Setting Error
1100 1102 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
1101 1103 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
1102 1104
1103 1105 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
1104 1106 error[indInvalid2] = 14
1105 1107 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
1106 1108 error[indInvalid1] = 13
1107 1109
1108 1110 return heights, error
1109 1111
1110 1112
1111 1113 class WindProfiler(Operation):
1112 1114
1113 1115 __isConfig = False
1114 1116
1115 1117 __initime = None
1116 1118 __lastdatatime = None
1117 1119 __integrationtime = None
1118 1120
1119 1121 __buffer = None
1120 1122
1121 1123 __dataReady = False
1122 1124
1123 1125 __firstdata = None
1124 1126
1125 1127 n = None
1126 1128
1127 1129 def __init__(self):
1128 1130 Operation.__init__(self)
1129 1131
1130 1132 def __calculateCosDir(self, elev, azim):
1131 1133 zen = (90 - elev)*numpy.pi/180
1132 1134 azim = azim*numpy.pi/180
1133 1135 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1134 1136 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1135 1137
1136 1138 signX = numpy.sign(numpy.cos(azim))
1137 1139 signY = numpy.sign(numpy.sin(azim))
1138 1140
1139 1141 cosDirX = numpy.copysign(cosDirX, signX)
1140 1142 cosDirY = numpy.copysign(cosDirY, signY)
1141 1143 return cosDirX, cosDirY
1142 1144
1143 1145 def __calculateAngles(self, theta_x, theta_y, azimuth):
1144 1146
1145 1147 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1146 1148 zenith_arr = numpy.arccos(dir_cosw)
1147 1149 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1148 1150
1149 1151 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1150 1152 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1151 1153
1152 1154 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1153 1155
1154 1156 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1155 1157
1156 1158 #
1157 1159 if horOnly:
1158 1160 A = numpy.c_[dir_cosu,dir_cosv]
1159 1161 else:
1160 1162 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
1161 1163 A = numpy.asmatrix(A)
1162 1164 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
1163 1165
1164 1166 return A1
1165 1167
1166 1168 def __correctValues(self, heiRang, phi, velRadial, SNR):
1167 1169 listPhi = phi.tolist()
1168 1170 maxid = listPhi.index(max(listPhi))
1169 1171 minid = listPhi.index(min(listPhi))
1170 1172
1171 1173 rango = range(len(phi))
1172 1174 # rango = numpy.delete(rango,maxid)
1173 1175
1174 1176 heiRang1 = heiRang*math.cos(phi[maxid])
1175 1177 heiRangAux = heiRang*math.cos(phi[minid])
1176 1178 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1177 1179 heiRang1 = numpy.delete(heiRang1,indOut)
1178 1180
1179 1181 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1180 1182 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1181 1183
1182 1184 for i in rango:
1183 1185 x = heiRang*math.cos(phi[i])
1184 1186 y1 = velRadial[i,:]
1185 1187 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1186 1188
1187 1189 x1 = heiRang1
1188 1190 y11 = f1(x1)
1189 1191
1190 1192 y2 = SNR[i,:]
1191 1193 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1192 1194 y21 = f2(x1)
1193 1195
1194 1196 velRadial1[i,:] = y11
1195 1197 SNR1[i,:] = y21
1196 1198
1197 1199 return heiRang1, velRadial1, SNR1
1198 1200
1199 1201 def __calculateVelUVW(self, A, velRadial):
1200 1202
1201 1203 #Operacion Matricial
1202 1204 # velUVW = numpy.zeros((velRadial.shape[1],3))
1203 1205 # for ind in range(velRadial.shape[1]):
1204 1206 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
1205 1207 # velUVW = velUVW.transpose()
1206 1208 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1207 1209 velUVW[:,:] = numpy.dot(A,velRadial)
1208 1210
1209 1211
1210 1212 return velUVW
1211 1213
1212 1214 def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1213 1215 """
1214 1216 Function that implements Doppler Beam Swinging (DBS) technique.
1215 1217
1216 1218 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1217 1219 Direction correction (if necessary), Ranges and SNR
1218 1220
1219 1221 Output: Winds estimation (Zonal, Meridional and Vertical)
1220 1222
1221 1223 Parameters affected: Winds, height range, SNR
1222 1224 """
1223 1225 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(dirCosx, disrCosy, azimuth)
1224 1226 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correct*velRadial0, SNR0)
1225 1227 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1226 1228
1227 1229 #Calculo de Componentes de la velocidad con DBS
1228 1230 winds = self.__calculateVelUVW(A,velRadial1)
1229 1231
1230 1232 return winds, heiRang1, SNR1
1231 1233
1232 1234 def __calculateDistance(self, posx, posy, pairsCrossCorr, pairsList, pairs, azimuth = None):
1233 1235
1234 1236 posx = numpy.asarray(posx)
1235 1237 posy = numpy.asarray(posy)
1236 1238
1237 1239 #Rotacion Inversa para alinear con el azimuth
1238 1240 if azimuth!= None:
1239 1241 azimuth = azimuth*math.pi/180
1240 1242 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
1241 1243 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
1242 1244 else:
1243 1245 posx1 = posx
1244 1246 posy1 = posy
1245 1247
1246 1248 #Calculo de Distancias
1247 1249 distx = numpy.zeros(pairsCrossCorr.size)
1248 1250 disty = numpy.zeros(pairsCrossCorr.size)
1249 1251 dist = numpy.zeros(pairsCrossCorr.size)
1250 1252 ang = numpy.zeros(pairsCrossCorr.size)
1251 1253
1252 1254 for i in range(pairsCrossCorr.size):
1253 1255 distx[i] = posx1[pairsList[pairsCrossCorr[i]][1]] - posx1[pairsList[pairsCrossCorr[i]][0]]
1254 1256 disty[i] = posy1[pairsList[pairsCrossCorr[i]][1]] - posy1[pairsList[pairsCrossCorr[i]][0]]
1255 1257 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1256 1258 ang[i] = numpy.arctan2(disty[i],distx[i])
1257 1259 #Calculo de Matrices
1258 1260 nPairs = len(pairs)
1259 1261 ang1 = numpy.zeros((nPairs, 2, 1))
1260 1262 dist1 = numpy.zeros((nPairs, 2, 1))
1261 1263
1262 1264 for j in range(nPairs):
1263 1265 dist1[j,0,0] = dist[pairs[j][0]]
1264 1266 dist1[j,1,0] = dist[pairs[j][1]]
1265 1267 ang1[j,0,0] = ang[pairs[j][0]]
1266 1268 ang1[j,1,0] = ang[pairs[j][1]]
1267 1269
1268 1270 return distx,disty, dist1,ang1
1269 1271
1270 1272 def __calculateVelVer(self, phase, lagTRange, _lambda):
1271 1273
1272 1274 Ts = lagTRange[1] - lagTRange[0]
1273 1275 velW = -_lambda*phase/(4*math.pi*Ts)
1274 1276
1275 1277 return velW
1276 1278
1277 1279 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1278 1280 nPairs = tau1.shape[0]
1279 1281 vel = numpy.zeros((nPairs,3,tau1.shape[2]))
1280 1282
1281 1283 angCos = numpy.cos(ang)
1282 1284 angSin = numpy.sin(ang)
1283 1285
1284 1286 vel0 = dist*tau1/(2*tau2**2)
1285 1287 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1286 1288 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1287 1289
1288 1290 ind = numpy.where(numpy.isinf(vel))
1289 1291 vel[ind] = numpy.nan
1290 1292
1291 1293 return vel
1292 1294
1293 1295 def __getPairsAutoCorr(self, pairsList, nChannels):
1294 1296
1295 1297 pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1296 1298
1297 1299 for l in range(len(pairsList)):
1298 1300 firstChannel = pairsList[l][0]
1299 1301 secondChannel = pairsList[l][1]
1300 1302
1301 1303 #Obteniendo pares de Autocorrelacion
1302 1304 if firstChannel == secondChannel:
1303 1305 pairsAutoCorr[firstChannel] = int(l)
1304 1306
1305 1307 pairsAutoCorr = pairsAutoCorr.astype(int)
1306 1308
1307 1309 pairsCrossCorr = range(len(pairsList))
1308 1310 pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1309 1311
1310 1312 return pairsAutoCorr, pairsCrossCorr
1311 1313
1312 1314 def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1313 1315 """
1314 1316 Function that implements Spaced Antenna (SA) technique.
1315 1317
1316 1318 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1317 1319 Direction correction (if necessary), Ranges and SNR
1318 1320
1319 1321 Output: Winds estimation (Zonal, Meridional and Vertical)
1320 1322
1321 1323 Parameters affected: Winds
1322 1324 """
1323 1325 #Cross Correlation pairs obtained
1324 1326 pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
1325 1327 pairsArray = numpy.array(pairsList)[pairsCrossCorr]
1326 1328 pairsSelArray = numpy.array(pairsSelected)
1327 1329 pairs = []
1328 1330
1329 1331 #Wind estimation pairs obtained
1330 1332 for i in range(pairsSelArray.shape[0]/2):
1331 1333 ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
1332 1334 ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
1333 1335 pairs.append((ind1,ind2))
1334 1336
1335 1337 indtau = tau.shape[0]/2
1336 1338 tau1 = tau[:indtau,:]
1337 1339 tau2 = tau[indtau:-1,:]
1338 1340 tau1 = tau1[pairs,:]
1339 1341 tau2 = tau2[pairs,:]
1340 1342 phase1 = tau[-1,:]
1341 1343
1342 1344 #---------------------------------------------------------------------
1343 1345 #Metodo Directo
1344 1346 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairsCrossCorr, pairsList, pairs,azimuth)
1345 1347 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
1346 1348 winds = stats.nanmean(winds, axis=0)
1347 1349 #---------------------------------------------------------------------
1348 1350 #Metodo General
1349 1351 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
1350 1352 # #Calculo Coeficientes de Funcion de Correlacion
1351 1353 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
1352 1354 # #Calculo de Velocidades
1353 1355 # winds = self.calculateVelUV(F,G,A,B,H)
1354 1356
1355 1357 #---------------------------------------------------------------------
1356 1358 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
1357 1359 winds = correctFactor*winds
1358 1360 return winds
1359 1361
1360 1362 def __checkTime(self, currentTime, paramInterval, windsInterval):
1361 1363
1362 1364 dataTime = currentTime + paramInterval
1363 1365 deltaTime = dataTime - self.__initime
1364 1366
1365 1367 if deltaTime >= windsInterval or deltaTime < 0:
1366 1368 self.__dataReady = True
1367 1369 return
1368 1370
1369 1371 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
1370 1372 '''
1371 1373 Function that implements winds estimation technique with detected meteors.
1372 1374
1373 1375 Input: Detected meteors, Minimum meteor quantity to wind estimation
1374 1376
1375 1377 Output: Winds estimation (Zonal and Meridional)
1376 1378
1377 1379 Parameters affected: Winds
1378 1380 '''
1379 1381 #Settings
1380 1382 nInt = (heightMax - heightMin)/2
1381 1383 winds = numpy.zeros((2,nInt))*numpy.nan
1382 1384
1383 1385 #Filter errors
1384 1386 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
1385 1387 finalMeteor = arrayMeteor[error,:]
1386 1388
1387 1389 #Meteor Histogram
1388 1390 finalHeights = finalMeteor[:,3]
1389 1391 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
1390 1392 nMeteorsPerI = hist[0]
1391 1393 heightPerI = hist[1]
1392 1394
1393 1395 #Sort of meteors
1394 1396 indSort = finalHeights.argsort()
1395 1397 finalMeteor2 = finalMeteor[indSort,:]
1396 1398
1397 1399 # Calculating winds
1398 1400 ind1 = 0
1399 1401 ind2 = 0
1400 1402
1401 1403 for i in range(nInt):
1402 1404 nMet = nMeteorsPerI[i]
1403 1405 ind1 = ind2
1404 1406 ind2 = ind1 + nMet
1405 1407
1406 1408 meteorAux = finalMeteor2[ind1:ind2,:]
1407 1409
1408 1410 if meteorAux.shape[0] >= meteorThresh:
1409 1411 vel = meteorAux[:, 7]
1410 1412 zen = meteorAux[:, 5]*numpy.pi/180
1411 1413 azim = meteorAux[:, 4]*numpy.pi/180
1412 1414
1413 1415 n = numpy.cos(zen)
1414 1416 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
1415 1417 # l = m*numpy.tan(azim)
1416 1418 l = numpy.sin(zen)*numpy.sin(azim)
1417 1419 m = numpy.sin(zen)*numpy.cos(azim)
1418 1420
1419 1421 A = numpy.vstack((l, m)).transpose()
1420 1422 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
1421 1423 windsAux = numpy.dot(A1, vel)
1422 1424
1423 1425 winds[0,i] = windsAux[0]
1424 1426 winds[1,i] = windsAux[1]
1425 1427
1426 1428 return winds, heightPerI[:-1]
1427 1429
1428 1430 def run(self, dataOut, technique, **kwargs):
1429 1431
1430 1432 param = dataOut.data_param
1431 1433 if dataOut.abscissaRange != None:
1432 1434 absc = dataOut.abscissaRange[:-1]
1433 1435 noise = dataOut.noise
1434 1436 heightRange = dataOut.getHeiRange()
1435 1437 SNR = dataOut.SNR
1436 1438
1437 1439 if technique == 'DBS':
1438 1440
1439 1441 if kwargs.has_key('dirCosx') and kwargs.has_key('dirCosy'):
1440 1442 theta_x = numpy.array(kwargs['dirCosx'])
1441 1443 theta_y = numpy.array(kwargs['dirCosy'])
1442 1444 else:
1443 1445 elev = numpy.array(kwargs['elevation'])
1444 1446 azim = numpy.array(kwargs['azimuth'])
1445 1447 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1446 1448 azimuth = kwargs['correctAzimuth']
1447 1449 if kwargs.has_key('horizontalOnly'):
1448 1450 horizontalOnly = kwargs['horizontalOnly']
1449 1451 else: horizontalOnly = False
1450 1452 if kwargs.has_key('correctFactor'):
1451 1453 correctFactor = kwargs['correctFactor']
1452 1454 else: correctFactor = 1
1453 1455 if kwargs.has_key('channelList'):
1454 1456 channelList = kwargs['channelList']
1455 1457 if len(channelList) == 2:
1456 1458 horizontalOnly = True
1457 1459 arrayChannel = numpy.array(channelList)
1458 1460 param = param[arrayChannel,:,:]
1459 1461 theta_x = theta_x[arrayChannel]
1460 1462 theta_y = theta_y[arrayChannel]
1461 1463
1462 1464 velRadial0 = param[:,1,:] #Radial velocity
1463 1465 dataOut.winds, dataOut.heightRange, dataOut.SNR = self.techniqueDBS(velRadial0, theta_x, theta_y, azimuth, correctFactor, horizontalOnly, heightRange, SNR) #DBS Function
1464 dataOut.initUtcTime = dataOut.ltctime
1465 dataOut.windsInterval = dataOut.timeInterval
1466 1466
1467 1467 elif technique == 'SA':
1468 1468
1469 1469 #Parameters
1470 1470 position_x = kwargs['positionX']
1471 1471 position_y = kwargs['positionY']
1472 1472 azimuth = kwargs['azimuth']
1473 1473
1474 1474 if kwargs.has_key('crosspairsList'):
1475 1475 pairs = kwargs['crosspairsList']
1476 1476 else:
1477 1477 pairs = None
1478 1478
1479 1479 if kwargs.has_key('correctFactor'):
1480 1480 correctFactor = kwargs['correctFactor']
1481 1481 else:
1482 1482 correctFactor = 1
1483 1483
1484 1484 tau = dataOut.data_param
1485 1485 _lambda = dataOut.C/dataOut.frequency
1486 1486 pairsList = dataOut.pairsList
1487 1487 nChannels = dataOut.nChannels
1488 1488
1489 1489 dataOut.winds = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
1490 1490 dataOut.initUtcTime = dataOut.ltctime
1491 1491 dataOut.windsInterval = dataOut.timeInterval
1492 1492
1493 1493 elif technique == 'Meteors':
1494 1494 dataOut.flagNoData = True
1495 1495 self.__dataReady = False
1496 1496
1497 1497 if kwargs.has_key('nHours'):
1498 1498 nHours = kwargs['nHours']
1499 1499 else:
1500 1500 nHours = 1
1501 1501
1502 1502 if kwargs.has_key('meteorsPerBin'):
1503 1503 meteorThresh = kwargs['meteorsPerBin']
1504 1504 else:
1505 1505 meteorThresh = 6
1506 1506
1507 1507 if kwargs.has_key('hmin'):
1508 1508 hmin = kwargs['hmin']
1509 1509 else: hmin = 70
1510 1510 if kwargs.has_key('hmax'):
1511 1511 hmax = kwargs['hmax']
1512 1512 else: hmax = 110
1513 1513
1514 1514 dataOut.windsInterval = nHours*3600
1515 1515
1516 1516 if self.__isConfig == False:
1517 1517 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
1518 1518 #Get Initial LTC time
1519 1519 self.__initime = (dataOut.datatime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
1520 1520 self.__isConfig = True
1521 1521
1522 1522 if self.__buffer == None:
1523 1523 self.__buffer = dataOut.data_param
1524 1524 self.__firstdata = copy.copy(dataOut)
1525 1525
1526 1526 else:
1527 1527 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
1528 1528
1529 1529 self.__checkTime(dataOut.ltctime, dataOut.paramInterval, dataOut.windsInterval) #Check if the buffer is ready
1530 1530
1531 1531 if self.__dataReady:
1532 1532 dataOut.initUtcTime = self.__initime
1533 1533 self.__initime = self.__initime + dataOut.windsInterval #to erase time offset
1534 1534
1535 1535 dataOut.winds, dataOut.heightRange = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
1536 1536 dataOut.flagNoData = False
1537 1537 self.__buffer = None
1538 1538
1539 1539 return No newline at end of file
@@ -1,144 +1,155
1 1 # DIAS 19 Y 20 FEB 2014
2 2 # Comprobacion de Resultados DBS con SA
3 3
4 4 import os, sys
5 5
6 6 path = os.path.split(os.getcwd())[0]
7 7 sys.path.append(path)
8 8
9 9 from controller import *
10 10
11 11 desc = "DBS Experiment Test"
12 12 filename = "DBStest.xml"
13 13
14 14 controllerObj = Project()
15 15
16 16 controllerObj.setup(id = '191', name='test01', description=desc)
17 17
18 18 #Experimentos
19 19
20 20 #2014050 19 Feb 2014
21 21 # path = '/home/soporte/Documents/MST_Data/DBS/d2014050'
22 22 # pathFigure = '/home/soporte/workspace/Graficos/DBS/d2014050p/'
23 23 # xmin = '15.5'
24 24 # xmax = '23.99999999'
25 25 # startTime = '17:25:00'
26 26 # filehdf5 = "DBS_2014050.hdf5"
27 27
28 28 #2014051 20 Feb 2014
29 29 path = '/home/soporte/Data/MST/DBS/d2014051'
30 30 pathFigure = '/home/soporte/workspace/Graficos/DBS/prueba1/'
31 xmin = '0.0'
32 xmax = '8.0'
31 xmin = '0'
32 xmax = '7.5'
33 33 startTime = '00:00:00'
34 34 filehdf5 = "DBS_2014051.hdf5"
35 35
36 36
37 37
38 38 #------------------------------------------------------------------------------------------------
39 39 readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader',
40 40 path=path,
41 41 startDate='2014/01/31',
42 42 endDate='2014/03/31',
43 43 startTime=startTime,
44 44 endTime='23:59:59',
45 45 online=0,
46 46 delay=5,
47 47 walk=0)
48 48
49 49 opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock')
50 50
51 51
52 52 #--------------------------------------------------------------------------------------------------
53 53
54 54 procUnitConfObj0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId())
55 55
56 56 opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other')
57 57
58 58 opObj11 = procUnitConfObj0.addOperation(name='CohInt', optype='other')
59 59 opObj11.addParameter(name='n', value='256', format='int')
60 60 # opObj11.addParameter(name='n', value='16', format='int')
61 61
62 62 opObj11 = procUnitConfObj0.addOperation(name='selectHeightsByIndex')
63 63 opObj11.addParameter(name='minIndex', value='10', format='float')
64 64 opObj11.addParameter(name='maxIndex', value='60', format='float')
65 65
66 66 #---------------------------------------------------------------------------------------------------
67 67
68 68 procUnitConfObj1 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObj0.getId())
69 69 procUnitConfObj1.addParameter(name='nFFTPoints', value='64', format='int')
70 70 procUnitConfObj1.addParameter(name='nProfiles', value='64', format='int')
71 71 # procUnitConfObj1.addParameter(name='ippFactor', value='2', format='int')
72 72 procUnitConfObj1.addParameter(name='pairsList', value='(0,0),(0,1),(2,1)', format='pairsList')
73 73
74 74 opObj11 = procUnitConfObj1.addOperation(name='IncohInt', optype='other')
75 75 opObj11.addParameter(name='n', value='5', format='int')
76 76
77 77 opObj14 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other')
78 78 opObj14.addParameter(name='id', value='1', format='int')
79 79 opObj14.addParameter(name='wintitle', value='Con interf', format='str')
80 80 opObj14.addParameter(name='save', value='1', format='bool')
81 81 opObj14.addParameter(name='figpath', value=pathFigure, format='str')
82 82 opObj14.addParameter(name='zmin', value='5', format='int')
83 83 opObj14.addParameter(name='zmax', value='90', format='int')
84 84
85 85 opObj12 = procUnitConfObj1.addOperation(name='removeInterference')
86 86 opObj13 = procUnitConfObj1.addOperation(name='removeDC')
87 87 opObj13.addParameter(name='mode', value='1', format='int')
88 88
89 89 opObj12 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other')
90 90 opObj12.addParameter(name='id', value='2', format='int')
91 91 opObj12.addParameter(name='wintitle', value='RTI Plot', format='str')
92 92 opObj12.addParameter(name='save', value='1', format='bool')
93 93 opObj12.addParameter(name='figpath', value = pathFigure, format='str')
94 94 opObj12.addParameter(name='xmin', value=xmin, format='float')
95 95 opObj12.addParameter(name='xmax', value=xmax, format='float')
96 96 opObj12.addParameter(name='zmin', value='5', format='int')
97 97 opObj12.addParameter(name='zmax', value='90', format='int')
98 98
99 99 #--------------------------------------------------------------------------------------------------
100 100
101 101 procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObj1.getId())
102 102 opObj20 = procUnitConfObj2.addOperation(name='GetMoments')
103 103
104 104 opObj21 = procUnitConfObj2.addOperation(name='MomentsPlot', optype='other')
105 105 opObj21.addParameter(name='id', value='3', format='int')
106 106 opObj21.addParameter(name='wintitle', value='Moments Plot', format='str')
107 107 opObj21.addParameter(name='save', value='1', format='bool')
108 108 opObj21.addParameter(name='figpath', value=pathFigure, format='str')
109 109 opObj21.addParameter(name='zmin', value='5', format='int')
110 110 opObj21.addParameter(name='zmax', value='90', format='int')
111 111
112 opObj21 = procUnitConfObj2.addOperation(name='RadialVelocityPlot', optype='other')
113 opObj21.addParameter(name='id', value='5', format='int')
114 opObj21.addParameter(name='wintitle', value='Radial Velocity Plot', format='str')
115 opObj21.addParameter(name='save', value='1', format='bool')
116 opObj21.addParameter(name='figpath', value=pathFigure, format='str')
117 opObj21.addParameter(name='SNRmin', value='-10', format='int')
118 opObj21.addParameter(name='SNRmax', value='60', format='int')
119 opObj21.addParameter(name='SNRthresh', value='0', format='float')
120 opObj21.addParameter(name='xmin', value=xmin, format='float')
121 opObj21.addParameter(name='xmax', value=xmax, format='float')
122
112 123 opObj22 = procUnitConfObj2.addOperation(name='WindProfiler', optype='other')
113 124 opObj22.addParameter(name='technique', value='DBS', format='str')
114 125 opObj22.addParameter(name='correctAzimuth', value='51.06', format='float')
115 126 opObj22.addParameter(name='correctFactor', value='-1', format='float')
116 127 opObj22.addParameter(name='dirCosx', value='0.041016, 0, -0.054688', format='floatlist')
117 128 opObj22.addParameter(name='dirCosy', value='-0.041016, 0.025391, -0.023438', format='floatlist')
118 129 # opObj22.addParameter(name='horizontalOnly', value='1', format='bool')
119 130 # opObj22.addParameter(name='channelList', value='1,2', format='intlist')
120 131
121 132 opObj23 = procUnitConfObj2.addOperation(name='WindProfilerPlot', optype='other')
122 133 opObj23.addParameter(name='id', value='4', format='int')
123 134 opObj23.addParameter(name='wintitle', value='Wind Profiler', format='str')
124 135 opObj23.addParameter(name='save', value='1', format='bool')
125 136 opObj23.addParameter(name='figpath', value = pathFigure, format='str')
126 137 opObj23.addParameter(name='zmin', value='-10', format='int')
127 138 opObj23.addParameter(name='zmax', value='10', format='int')
128 139 opObj23.addParameter(name='zmin_ver', value='-80', format='float')
129 140 opObj23.addParameter(name='zmax_ver', value='80', format='float')
130 141 opObj23.addParameter(name='SNRmin', value='-10', format='int')
131 142 opObj23.addParameter(name='SNRmax', value='60', format='int')
132 143 opObj23.addParameter(name='SNRthresh', value='0', format='float')
133 144 opObj23.addParameter(name='xmin', value=xmin, format='float')
134 145 opObj23.addParameter(name='xmax', value=xmax, format='float')
135 146
136 147 #--------------------------------------------------------------------------------------------------
137 148 print "Escribiendo el archivo XML"
138 149 controllerObj.writeXml(filename)
139 150 print "Leyendo el archivo XML"
140 151 controllerObj.readXml(filename)
141 152
142 153 controllerObj.createObjects()
143 154 controllerObj.connectObjects()
144 155 controllerObj.run() No newline at end of file
@@ -1,139 +1,139
1 1 # DIAS 19 Y 20 FEB 2014
2 2 # Comprobacion de Resultados DBS con SA
3 3
4 4 import os, sys
5 5
6 6 path = os.path.split(os.getcwd())[0]
7 7 sys.path.append(path)
8 8
9 9 from controller import *
10 10
11 11 desc = "SA Experiment Test"
12 12 filename = "SA2014050.xml"
13 13
14 14 controllerObj = Project()
15 15
16 16 controllerObj.setup(id = '191', name='test01', description=desc)
17 17
18 18
19 19 #Experimentos
20 20
21 21 #2014050 19 Feb 2014
22 # path = '/home/soporte/Documents/MST_Data/SA/d2014050'
23 # pathFigure = '/home/soporte/workspace/Graficos/SA/d2014050_prueba/'
24 # xmin = '15.5'
25 # xmax = '23.99999999'
26 # startTime = '15:30:00'
27 # filehdf5 = "SA_2014050.hdf5"
22 path = '/home/soporte/Data/MST/SA/d2014050'
23 pathFigure = '/home/soporte/workspace/Graficos/SA/new1/'
24 xmin = '15.5'
25 xmax = '24'
26 startTime = '15:30:00'
27 filehdf5 = "SA_2014050.hdf5"
28 28
29 29 #2014051 20 Feb 2014
30 path = '/home/soporte/Data/MST/SA/d2014051'
31 pathFigure = '/home/soporte/workspace/Graficos/SA/prueba1/'
32 xmin = '0.0'
33 xmax = '8.0'
34 startTime = '06:00:00'
35 filehdf5 = "SA_2014051.hdf5"
30 # path = '/home/soporte/Data/MST/SA/d2014051'
31 # pathFigure = '/home/soporte/workspace/Graficos/SA/new/'
32 # xmin = '0.0'
33 # xmax = '8.0'
34 # startTime = '00:00:00'
35 # filehdf5 = "SA_2014051.hdf5"
36 36
37 37 readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader',
38 38 path=path,
39 39 startDate='2014/01/01',
40 40 endDate='2014/03/31',
41 41 startTime=startTime,
42 42 endTime='23:59:59',
43 43 online=0,
44 44 delay=5,
45 45 walk=0)
46 46
47 47 opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock')
48 48
49 49
50 50 #--------------------------------------------------------------------------------------------------
51 51
52 52 procUnitConfObj0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId())
53 53
54 54 opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other')
55 55
56 56 opObj11 = procUnitConfObj0.addOperation(name='CohInt', optype='other')
57 57 opObj11.addParameter(name='n', value='600', format='int')
58 58 # opObj11.addParameter(name='n', value='10', format='int')
59 59
60 60 opObj11 = procUnitConfObj0.addOperation(name='selectHeightsByIndex')
61 61 opObj11.addParameter(name='minIndex', value='10', format='float')
62 62 opObj11.addParameter(name='maxIndex', value='60', format='float')
63 63 #---------------------------------------------------------------------------------------------------
64 64 procUnitConfObj1 = controllerObj.addProcUnit(datatype='CorrelationProc', inputId=procUnitConfObj0.getId())
65 65 # procUnitConfObj1.addParameter(name='pairsList', value='(0,0),(1,1),(2,2),(3,3),(1,0),(2,3)', format='pairsList')
66 procUnitConfObj1.addParameter(name='pairsList', value='(0,0),(1,1),(2,2),(3,3),(0,3),(0,2),(1,3),(1,2)', format='pairsList')
66 procUnitConfObj1.addParameter(name='pairsList', value='(0,0),(1,1),(2,2),(3,3),(0,3),(0,2),(1,3),(1,2),(0,1),(2,3)', format='pairsList')
67 67 procUnitConfObj1.addParameter(name='fullT', value='1', format='bool')
68 68 procUnitConfObj1.addParameter(name='removeDC', value='1', format='bool')
69 69 #procUnitConfObj1.addParameter(name='lagT', value='0,1,2,3', format='intlist')
70 70
71 71 opObj12 = procUnitConfObj1.addOperation(name='CorrelationPlot', optype='other')
72 72 opObj12.addParameter(name='id', value='1', format='int')
73 73 opObj12.addParameter(name='wintitle', value='CrossCorrelation Plot', format='str')
74 74 opObj12.addParameter(name='save', value='1', format='bool')
75 75 opObj12.addParameter(name='zmin', value='0', format='int')
76 76 opObj12.addParameter(name='zmax', value='1', format='int')
77 77 opObj12.addParameter(name='figpath', value = pathFigure, format='str')
78 78
79 79 opObj12 = procUnitConfObj1.addOperation(name='removeNoise')
80 80 opObj12.addParameter(name='mode', value='2', format='int')
81 81 opObj12 = procUnitConfObj1.addOperation(name='calculateNormFactor')
82 82
83 83 opObj12 = procUnitConfObj1.addOperation(name='CorrelationPlot', optype='other')
84 84 opObj12.addParameter(name='id', value='2', format='int')
85 85 opObj12.addParameter(name='wintitle', value='CrossCorrelation Plot', format='str')
86 86 opObj12.addParameter(name='save', value='1', format='bool')
87 87 opObj12.addParameter(name='zmin', value='0', format='int')
88 88 opObj12.addParameter(name='zmax', value='1', format='int')
89 89 opObj12.addParameter(name='figpath', value = pathFigure, format='str')
90 90
91 91 #---------------------------------------------------------------------------------------------------
92 92 procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObj1.getId())
93 93 opObj20 = procUnitConfObj2.addOperation(name='GetLags')
94 94
95 95 opObj21 = procUnitConfObj2.addOperation(name='WindProfiler', optype='other')
96 96 opObj21.addParameter(name='technique', value='SA', format='str')
97 97 # opObj21.addParameter(name='correctFactor', value='-1', format='float')
98 98 opObj21.addParameter(name='positionX', value='36,0,36,0', format='floatlist')
99 99 opObj21.addParameter(name='positionY', value='36,0,0,36', format='floatlist')
100 100 opObj21.addParameter(name='azimuth', value='51.06', format='float')
101 opObj21.addParameter(name='crosspairsList', value='(0,3),(0,2),(1,3),(1,2)', format='pairsList')#COrregir
101 opObj21.addParameter(name='crosspairsList', value='(0,3),(0,2),(1,3),(1,2),(0,1),(2,3)', format='pairsList')#COrregir
102 102 #
103 103 opObj22 = procUnitConfObj2.addOperation(name='WindProfilerPlot', optype='other')
104 104 opObj22.addParameter(name='id', value='4', format='int')
105 105 opObj22.addParameter(name='wintitle', value='Wind Profiler', format='str')
106 106 opObj22.addParameter(name='save', value='1', format='bool')
107 107 opObj22.addParameter(name='figpath', value = pathFigure, format='str')
108 108 opObj22.addParameter(name='zmin', value='-15', format='int')
109 109 opObj22.addParameter(name='zmax', value='15', format='int')
110 110 opObj22.addParameter(name='zmin_ver', value='-80', format='float')
111 111 opObj22.addParameter(name='zmax_ver', value='80', format='float')
112 112 opObj22.addParameter(name='SNRmin', value='-20', format='int')
113 113 opObj22.addParameter(name='SNRmax', value='40', format='int')
114 114 opObj22.addParameter(name='SNRthresh', value='-3.5', format='float')
115 115 opObj22.addParameter(name='xmin', value=xmin, format='float')
116 116 opObj22.addParameter(name='xmax', value=xmax, format='float')
117 117 # #-----------------------------------------------------------------------------------
118 118 #
119 119 # procUnitConfObj2 = controllerObj.addProcUnit(datatype='Spectra', inputId=procUnitConfObj0.getId())
120 120 # procUnitConfObj2.addParameter(name='nFFTPoints', value='128', format='int')
121 121 # procUnitConfObj2.addParameter(name='nProfiles', value='128', format='int')
122 122 # procUnitConfObj2.addParameter(name='pairsList', value='(0,0),(0,1),(2,1)', format='pairsList')
123 123 #
124 124 # opObj22 = procUnitConfObj2.addOperation(name='SpectraPlot', optype='other')
125 125 # opObj22.addParameter(name='id', value='5', format='int')
126 126 # opObj22.addParameter(name='wintitle', value='Spectra Plot', format='str')
127 127 # opObj22.addParameter(name='save', value='1', format='bool')
128 128 # opObj22.addParameter(name='figpath', value = pathFigure, format='str')
129 129
130 130 #-----------------------------------------------------------------------------------
131 131
132 132 print "Escribiendo el archivo XML"
133 133 controllerObj.writeXml(filename)
134 134 print "Leyendo el archivo XML"
135 135 controllerObj.readXml(filename)
136 136
137 137 controllerObj.createObjects()
138 138 controllerObj.connectObjects()
139 139 controllerObj.run() No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now