##// END OF EJS Templates
reworked
José Chávez -
r954:94be3372cea7
parent child
Show More
@@ -1,12 +1,22
1 1 #from schainpy.model.data.jrodata import *
2 2 # from schainpy.model.io.jrodataIO import *
3 3 # from schainpy.model.proc.jroprocessing import *
4 4 # from schainpy.model.graphics.jroplot import *
5 5 # from schainpy.model.utils.jroutils import *
6 6 # from schainpy.serializer import *
7 7
8 8 from data import *
9 9 from io import *
10 10 from proc import *
11 11 from graphics import *
12 12 from utils import *
13
14 global_type_string = 'string'
15 global_type_integer = 'int'
16 global_type_floatList = 'floatList'
17 global_type_pairsList = 'pairsList'
18 global_type_boolean = 'bolean'
19 global_type_float = 'float'
20 global_type_colormap = 'colormap'
21 global_type_list = 'list'
22 global_type_float = 'float'
@@ -1,657 +1,657
1 1 import os
2 2 import numpy
3 3 import time, datetime
4 4 import mpldriver
5 5
6 6 from schainpy.model.proc.jroproc_base import Operation
7 7
8 8 def isTimeInHourRange(datatime, xmin, xmax):
9 9
10 10 if xmin == None or xmax == None:
11 11 return 1
12 12 hour = datatime.hour + datatime.minute/60.0
13 13
14 14 if xmin < (xmax % 24):
15 15
16 16 if hour >= xmin and hour <= xmax:
17 17 return 1
18 18 else:
19 19 return 0
20 20
21 21 else:
22 22
23 23 if hour >= xmin or hour <= (xmax % 24):
24 24 return 1
25 25 else:
26 26 return 0
27 27
28 28 return 0
29 29
30 30 def isRealtime(utcdatatime):
31 31
32 32 utcnow = time.mktime(time.localtime())
33 33 delta = abs(utcnow - utcdatatime) # abs
34 34 if delta >= 30.:
35 35 return False
36 36 return True
37 37
38 38 class Figure(Operation):
39 39
40 40 __driver = mpldriver
41 41 fig = None
42 42
43 43 id = None
44 44 wintitle = None
45 45 width = None
46 46 height = None
47 47 nplots = None
48 48 timerange = None
49 49
50 50 axesObjList = []
51 51
52 52 WIDTH = 300
53 53 HEIGHT = 200
54 54 PREFIX = 'fig'
55 55
56 56 xmin = None
57 57 xmax = None
58 58
59 59 counter_imagwr = 0
60 60
61 61 figfile = None
62 62
63 63 created = False
64
64 parameters = {}
65 65 def __init__(self, **kwargs):
66 66
67 67 Operation.__init__(self, **kwargs)
68 68
69 69 def __del__(self):
70 70
71 71 self.__driver.closeFigure()
72 72
73 73 def getFilename(self, name, ext='.png'):
74 74
75 75 path = '%s%03d' %(self.PREFIX, self.id)
76 76 filename = '%s_%s%s' %(self.PREFIX, name, ext)
77 77 return os.path.join(path, filename)
78 78
79 79 def getAxesObjList(self):
80 80
81 81 return self.axesObjList
82 82
83 83 def getSubplots(self):
84 84
85 85 raise NotImplementedError
86 86
87 87 def getScreenDim(self, widthplot, heightplot):
88 88
89 89 nrow, ncol = self.getSubplots()
90 90
91 91 widthscreen = widthplot*ncol
92 92 heightscreen = heightplot*nrow
93 93
94 94 return widthscreen, heightscreen
95 95
96 96 def getTimeLim(self, x, xmin=None, xmax=None, timerange=None):
97 97
98 98 # if self.xmin != None and self.xmax != None:
99 99 # if timerange == None:
100 100 # timerange = self.xmax - self.xmin
101 101 # xmin = self.xmin + timerange
102 102 # xmax = self.xmax + timerange
103 103 #
104 104 # return xmin, xmax
105 105
106 106 if timerange == None and (xmin==None or xmax==None):
107 107 timerange = 14400 #seconds
108 108
109 109 if timerange != None:
110 110 txmin = x[0] #- x[0] % min(timerange/10, 10*60)
111 111 else:
112 112 txmin = x[0] #- x[0] % 10*60
113 113
114 114 thisdatetime = datetime.datetime.utcfromtimestamp(txmin)
115 115 thisdate = datetime.datetime.combine(thisdatetime.date(), datetime.time(0,0,0))
116 116
117 117 if timerange != None:
118 118 xmin = (thisdatetime - thisdate).seconds/(60*60.)
119 119 xmax = xmin + timerange/(60*60.)
120 120
121 121 d1970 = datetime.datetime(1970,1,1)
122 122
123 123 mindt = thisdate + datetime.timedelta(hours=xmin) #- datetime.timedelta(seconds=time.timezone)
124 124 xmin_sec = (mindt - d1970).total_seconds() #time.mktime(mindt.timetuple()) - time.timezone
125 125
126 126 maxdt = thisdate + datetime.timedelta(hours=xmax) #- datetime.timedelta(seconds=time.timezone)
127 127 xmax_sec = (maxdt - d1970).total_seconds() #time.mktime(maxdt.timetuple()) - time.timezone
128 128
129 129 return xmin_sec, xmax_sec
130 130
131 131 def init(self, id, nplots, wintitle):
132 132
133 133 raise NotImplementedError, "This method has been replaced by createFigure"
134 134
135 135 def createFigure(self, id, wintitle, widthplot=None, heightplot=None, show=True):
136 136
137 137 """
138 138 Crea la figura de acuerdo al driver y parametros seleccionados seleccionados.
139 139 Las dimensiones de la pantalla es calculada a partir de los atributos self.WIDTH
140 140 y self.HEIGHT y el numero de subplots (nrow, ncol)
141 141
142 142 Input:
143 143 id : Los parametros necesarios son
144 144 wintitle :
145 145
146 146 """
147 147
148 148 if widthplot == None:
149 149 widthplot = self.WIDTH
150 150
151 151 if heightplot == None:
152 152 heightplot = self.HEIGHT
153 153
154 154 self.id = id
155 155
156 156 self.wintitle = wintitle
157 157
158 158 self.widthscreen, self.heightscreen = self.getScreenDim(widthplot, heightplot)
159 159
160 160 # if self.created:
161 161 # self.__driver.closeFigure(self.fig)
162 162
163 163 if not self.created:
164 164 self.fig = self.__driver.createFigure(id=self.id,
165 165 wintitle=self.wintitle,
166 166 width=self.widthscreen,
167 167 height=self.heightscreen,
168 168 show=show)
169 169 else:
170 170 self.__driver.clearFigure(self.fig)
171 171
172 172 self.axesObjList = []
173 173 self.counter_imagwr = 0
174 174
175 175 self.created = True
176 176
177 177 def setDriver(self, driver=mpldriver):
178 178
179 179 self.__driver = driver
180 180
181 181 def setTitle(self, title):
182 182
183 183 self.__driver.setTitle(self.fig, title)
184 184
185 185 def setWinTitle(self, title):
186 186
187 187 self.__driver.setWinTitle(self.fig, title=title)
188 188
189 189 def setTextFromAxes(self, text):
190 190
191 191 raise NotImplementedError, "This method has been replaced with Axes.setText"
192 192
193 193 def makeAxes(self, nrow, ncol, xpos, ypos, colspan, rowspan):
194 194
195 195 raise NotImplementedError, "This method has been replaced with Axes.addAxes"
196 196
197 197 def addAxes(self, *args):
198 198 """
199 199
200 200 Input:
201 201 *args : Los parametros necesarios son
202 202 nrow, ncol, xpos, ypos, colspan, rowspan
203 203 """
204 204
205 205 axesObj = Axes(self.fig, *args)
206 206 self.axesObjList.append(axesObj)
207 207
208 208 def saveFigure(self, figpath, figfile, *args):
209 209
210 210 filename = os.path.join(figpath, figfile)
211 211
212 212 fullpath = os.path.split(filename)[0]
213 213
214 214 if not os.path.exists(fullpath):
215 215 subpath = os.path.split(fullpath)[0]
216 216
217 217 if not os.path.exists(subpath):
218 218 os.mkdir(subpath)
219 219
220 220 os.mkdir(fullpath)
221 221
222 222 self.__driver.saveFigure(self.fig, filename, *args)
223 223
224 224 def save(self, figpath, figfile=None, save=True, ftp=False, wr_period=1, thisDatetime=None, update_figfile=True):
225 225
226 226 self.counter_imagwr += 1
227 227 if self.counter_imagwr < wr_period:
228 228 return
229 229
230 230 self.counter_imagwr = 0
231 231
232 232 if save:
233 233
234 234 if not figfile:
235 235
236 236 if not thisDatetime:
237 237 raise ValueError, "Saving figure: figfile or thisDatetime should be defined"
238 238 return
239 239
240 240 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
241 241 figfile = self.getFilename(name = str_datetime)
242 242
243 243 if self.figfile == None:
244 244 self.figfile = figfile
245 245
246 246 if update_figfile:
247 247 self.figfile = figfile
248 248
249 249 # store png plot to local folder
250 250 self.saveFigure(figpath, self.figfile)
251 251
252 252
253 253 if not ftp:
254 254 return
255 255
256 256 if not thisDatetime:
257 257 return
258 258
259 259 # store png plot to FTP server according to RT-Web format
260 260 ftp_filename = self.getNameToFtp(thisDatetime, self.FTP_WEI, self.EXP_CODE, self.SUB_EXP_CODE, self.PLOT_CODE, self.PLOT_POS)
261 261 # ftp_filename = os.path.join(figpath, name)
262 262 self.saveFigure(figpath, ftp_filename)
263 263
264 264 def getNameToFtp(self, thisDatetime, FTP_WEI, EXP_CODE, SUB_EXP_CODE, PLOT_CODE, PLOT_POS):
265 265 YEAR_STR = '%4.4d'%thisDatetime.timetuple().tm_year
266 266 DOY_STR = '%3.3d'%thisDatetime.timetuple().tm_yday
267 267 FTP_WEI = '%2.2d'%FTP_WEI
268 268 EXP_CODE = '%3.3d'%EXP_CODE
269 269 SUB_EXP_CODE = '%2.2d'%SUB_EXP_CODE
270 270 PLOT_CODE = '%2.2d'%PLOT_CODE
271 271 PLOT_POS = '%2.2d'%PLOT_POS
272 272 name = YEAR_STR + DOY_STR + FTP_WEI + EXP_CODE + SUB_EXP_CODE + PLOT_CODE + PLOT_POS
273 273 return name
274 274
275 275 def draw(self):
276 276
277 277 self.__driver.draw(self.fig)
278 278
279 279 def run(self):
280 280
281 281 raise NotImplementedError
282 282
283 283 def close(self, show=False):
284 284
285 285 self.__driver.closeFigure(show=show, fig=self.fig)
286 286
287 287 axesList = property(getAxesObjList)
288 288
289 289
290 290 class Axes:
291 291
292 292 __driver = mpldriver
293 293 fig = None
294 294 ax = None
295 295 plot = None
296 296 __missing = 1E30
297 297 __firsttime = None
298 298
299 299 __showprofile = False
300 300
301 301 xmin = None
302 302 xmax = None
303 303 ymin = None
304 304 ymax = None
305 305 zmin = None
306 306 zmax = None
307 307
308 308 x_buffer = None
309 309 z_buffer = None
310 310
311 311 decimationx = None
312 312 decimationy = None
313 313
314 314 __MAXNUMX = 200
315 315 __MAXNUMY = 400
316 316
317 317 __MAXNUMTIME = 500
318 318
319 319 def __init__(self, *args):
320 320
321 321 """
322 322
323 323 Input:
324 324 *args : Los parametros necesarios son
325 325 fig, nrow, ncol, xpos, ypos, colspan, rowspan
326 326 """
327 327
328 328 ax = self.__driver.createAxes(*args)
329 329 self.fig = args[0]
330 330 self.ax = ax
331 331 self.plot = None
332 332
333 333 self.__firsttime = True
334 334 self.idlineList = []
335 335
336 336 self.x_buffer = numpy.array([])
337 337 self.z_buffer = numpy.array([])
338 338
339 339 def setText(self, text):
340 340
341 341 self.__driver.setAxesText(self.ax, text)
342 342
343 343 def setXAxisAsTime(self):
344 344 pass
345 345
346 346 def pline(self, x, y,
347 347 xmin=None, xmax=None,
348 348 ymin=None, ymax=None,
349 349 xlabel='', ylabel='',
350 350 title='',
351 351 **kwargs):
352 352
353 353 """
354 354
355 355 Input:
356 356 x :
357 357 y :
358 358 xmin :
359 359 xmax :
360 360 ymin :
361 361 ymax :
362 362 xlabel :
363 363 ylabel :
364 364 title :
365 365 **kwargs : Los parametros aceptados son
366 366
367 367 ticksize
368 368 ytick_visible
369 369 """
370 370
371 371 if self.__firsttime:
372 372
373 373 if xmin == None: xmin = numpy.nanmin(x)
374 374 if xmax == None: xmax = numpy.nanmax(x)
375 375 if ymin == None: ymin = numpy.nanmin(y)
376 376 if ymax == None: ymax = numpy.nanmax(y)
377 377
378 378 self.plot = self.__driver.createPline(self.ax, x, y,
379 379 xmin, xmax,
380 380 ymin, ymax,
381 381 xlabel=xlabel,
382 382 ylabel=ylabel,
383 383 title=title,
384 384 **kwargs)
385 385
386 386 self.idlineList.append(0)
387 387 self.__firsttime = False
388 388 return
389 389
390 390 self.__driver.pline(self.plot, x, y, xlabel=xlabel,
391 391 ylabel=ylabel,
392 392 title=title)
393 393
394 394 # self.__driver.pause()
395 395
396 396 def addpline(self, x, y, idline, **kwargs):
397 397 lines = self.ax.lines
398 398
399 399 if idline in self.idlineList:
400 400 self.__driver.set_linedata(self.ax, x, y, idline)
401 401
402 402 if idline not in(self.idlineList):
403 403 self.__driver.addpline(self.ax, x, y, **kwargs)
404 404 self.idlineList.append(idline)
405 405
406 406 return
407 407
408 408 def pmultiline(self, x, y,
409 409 xmin=None, xmax=None,
410 410 ymin=None, ymax=None,
411 411 xlabel='', ylabel='',
412 412 title='',
413 413 **kwargs):
414 414
415 415 if self.__firsttime:
416 416
417 417 if xmin == None: xmin = numpy.nanmin(x)
418 418 if xmax == None: xmax = numpy.nanmax(x)
419 419 if ymin == None: ymin = numpy.nanmin(y)
420 420 if ymax == None: ymax = numpy.nanmax(y)
421 421
422 422 self.plot = self.__driver.createPmultiline(self.ax, x, y,
423 423 xmin, xmax,
424 424 ymin, ymax,
425 425 xlabel=xlabel,
426 426 ylabel=ylabel,
427 427 title=title,
428 428 **kwargs)
429 429 self.__firsttime = False
430 430 return
431 431
432 432 self.__driver.pmultiline(self.plot, x, y, xlabel=xlabel,
433 433 ylabel=ylabel,
434 434 title=title)
435 435
436 436 # self.__driver.pause()
437 437
438 438 def pmultilineyaxis(self, x, y,
439 439 xmin=None, xmax=None,
440 440 ymin=None, ymax=None,
441 441 xlabel='', ylabel='',
442 442 title='',
443 443 **kwargs):
444 444
445 445 if self.__firsttime:
446 446
447 447 if xmin == None: xmin = numpy.nanmin(x)
448 448 if xmax == None: xmax = numpy.nanmax(x)
449 449 if ymin == None: ymin = numpy.nanmin(y)
450 450 if ymax == None: ymax = numpy.nanmax(y)
451 451
452 452 self.plot = self.__driver.createPmultilineYAxis(self.ax, x, y,
453 453 xmin, xmax,
454 454 ymin, ymax,
455 455 xlabel=xlabel,
456 456 ylabel=ylabel,
457 457 title=title,
458 458 **kwargs)
459 459 if self.xmin == None: self.xmin = xmin
460 460 if self.xmax == None: self.xmax = xmax
461 461 if self.ymin == None: self.ymin = ymin
462 462 if self.ymax == None: self.ymax = ymax
463 463
464 464 self.__firsttime = False
465 465 return
466 466
467 467 self.__driver.pmultilineyaxis(self.plot, x, y, xlabel=xlabel,
468 468 ylabel=ylabel,
469 469 title=title)
470 470
471 471 # self.__driver.pause()
472 472
473 473 def pcolor(self, x, y, z,
474 474 xmin=None, xmax=None,
475 475 ymin=None, ymax=None,
476 476 zmin=None, zmax=None,
477 477 xlabel='', ylabel='',
478 478 title='', colormap='jet',
479 479 **kwargs):
480 480
481 481 """
482 482 Input:
483 483 x :
484 484 y :
485 485 x :
486 486 xmin :
487 487 xmax :
488 488 ymin :
489 489 ymax :
490 490 zmin :
491 491 zmax :
492 492 xlabel :
493 493 ylabel :
494 494 title :
495 495 **kwargs : Los parametros aceptados son
496 496 ticksize=9,
497 497 cblabel=''
498 498 """
499 499
500 500 #Decimating data
501 501 xlen = len(x)
502 502 ylen = len(y)
503 503
504 504 decimationx = int(xlen/self.__MAXNUMX) + 1
505 505 decimationy = int(ylen/self.__MAXNUMY) + 1
506 506
507 507
508 508 x_buffer = x#[::decimationx]
509 509 y_buffer = y#[::decimationy]
510 510 z_buffer = z#[::decimationx, ::decimationy]
511 511 #===================================================
512 512
513 513 if self.__firsttime:
514 514
515 515 if xmin == None: xmin = numpy.nanmin(x)
516 516 if xmax == None: xmax = numpy.nanmax(x)
517 517 if ymin == None: ymin = numpy.nanmin(y)
518 518 if ymax == None: ymax = numpy.nanmax(y)
519 519 if zmin == None: zmin = numpy.nanmin(z)
520 520 if zmax == None: zmax = numpy.nanmax(z)
521 521
522 522
523 523 self.plot = self.__driver.createPcolor(self.ax, x_buffer,
524 524 y_buffer,
525 525 z_buffer,
526 526 xmin, xmax,
527 527 ymin, ymax,
528 528 zmin, zmax,
529 529 xlabel=xlabel,
530 530 ylabel=ylabel,
531 531 title=title,
532 532 colormap=colormap,
533 533 **kwargs)
534 534
535 535 if self.xmin == None: self.xmin = xmin
536 536 if self.xmax == None: self.xmax = xmax
537 537 if self.ymin == None: self.ymin = ymin
538 538 if self.ymax == None: self.ymax = ymax
539 539 if self.zmin == None: self.zmin = zmin
540 540 if self.zmax == None: self.zmax = zmax
541 541
542 542 self.__firsttime = False
543 543 return
544 544
545 545 self.__driver.pcolor(self.plot,
546 546 z_buffer,
547 547 xlabel=xlabel,
548 548 ylabel=ylabel,
549 549 title=title)
550 550
551 551 # self.__driver.pause()
552 552
553 553 def pcolorbuffer(self, x, y, z,
554 554 xmin=None, xmax=None,
555 555 ymin=None, ymax=None,
556 556 zmin=None, zmax=None,
557 557 xlabel='', ylabel='',
558 558 title='', rti = True, colormap='jet',
559 559 maxNumX = None, maxNumY = None,
560 560 **kwargs):
561 561
562 562 if maxNumX == None:
563 563 maxNumX = self.__MAXNUMTIME
564 564
565 565 if maxNumY == None:
566 566 maxNumY = self.__MAXNUMY
567 567
568 568 if self.__firsttime:
569 569 self.z_buffer = z
570 570 self.x_buffer = numpy.hstack((self.x_buffer, x))
571 571
572 572 if xmin == None: xmin = numpy.nanmin(x)
573 573 if xmax == None: xmax = numpy.nanmax(x)
574 574 if ymin == None: ymin = numpy.nanmin(y)
575 575 if ymax == None: ymax = numpy.nanmax(y)
576 576 if zmin == None: zmin = numpy.nanmin(z)
577 577 if zmax == None: zmax = numpy.nanmax(z)
578 578
579 579 self.plot = self.__driver.createPcolor(self.ax, self.x_buffer, y, z,
580 580 xmin, xmax,
581 581 ymin, ymax,
582 582 zmin, zmax,
583 583 xlabel=xlabel,
584 584 ylabel=ylabel,
585 585 title=title,
586 586 colormap=colormap,
587 587 **kwargs)
588 588
589 589 if self.xmin == None: self.xmin = xmin
590 590 if self.xmax == None: self.xmax = xmax
591 591 if self.ymin == None: self.ymin = ymin
592 592 if self.ymax == None: self.ymax = ymax
593 593 if self.zmin == None: self.zmin = zmin
594 594 if self.zmax == None: self.zmax = zmax
595 595
596 596 self.__firsttime = False
597 597 return
598 598
599 599 self.x_buffer = numpy.hstack((self.x_buffer[:-1], x[0], x[-1]))
600 600 self.z_buffer = numpy.hstack((self.z_buffer, z))
601 601 z_buffer = self.z_buffer.reshape(-1,len(y))
602 602
603 603 #Decimating data
604 604 xlen = len(self.x_buffer)
605 605 ylen = len(y)
606 606
607 607 decimationx = int(xlen/maxNumX) + 1
608 608 decimationy = int(ylen/maxNumY) + 1
609 609
610 610 x_buffer = self.x_buffer#[::decimationx]
611 611 y_buffer = y#[::decimationy]
612 612 z_buffer = z_buffer#[::decimationx, ::decimationy]
613 613 #===================================================
614 614
615 615 x_buffer, y_buffer, z_buffer = self.__fillGaps(x_buffer, y_buffer, z_buffer)
616 616
617 617 self.__driver.addpcolorbuffer(self.ax, x_buffer, y_buffer, z_buffer, self.zmin, self.zmax,
618 618 xlabel=xlabel,
619 619 ylabel=ylabel,
620 620 title=title,
621 621 colormap=colormap)
622 622
623 623 # self.__driver.pause()
624 624
625 625 def polar(self, x, y,
626 626 title='', xlabel='',ylabel='',**kwargs):
627 627
628 628 if self.__firsttime:
629 629 self.plot = self.__driver.createPolar(self.ax, x, y, title = title, xlabel = xlabel, ylabel = ylabel)
630 630 self.__firsttime = False
631 631 self.x_buffer = x
632 632 self.y_buffer = y
633 633 return
634 634
635 635 self.x_buffer = numpy.hstack((self.x_buffer,x))
636 636 self.y_buffer = numpy.hstack((self.y_buffer,y))
637 637 self.__driver.polar(self.plot, self.x_buffer, self.y_buffer, xlabel=xlabel,
638 638 ylabel=ylabel,
639 639 title=title)
640 640
641 641 # self.__driver.pause()
642 642
643 643 def __fillGaps(self, x_buffer, y_buffer, z_buffer):
644 644
645 645 if x_buffer.shape[0] < 2:
646 646 return x_buffer, y_buffer, z_buffer
647 647
648 648 deltas = x_buffer[1:] - x_buffer[0:-1]
649 649 x_median = numpy.median(deltas)
650 650
651 651 index = numpy.where(deltas > 5*x_median)
652 652
653 653 if len(index[0]) != 0:
654 654 z_buffer[index[0],::] = self.__missing
655 655 z_buffer = numpy.ma.masked_inside(z_buffer,0.99*self.__missing,1.01*self.__missing)
656 656
657 657 return x_buffer, y_buffer, z_buffer
@@ -1,188 +1,215
1 1 import os
2 2 import datetime
3 3 import numpy
4 4 import copy
5
5 from schainpy.model import *
6 6 from figure import Figure, isRealtime
7 7
8 8 class CorrelationPlot(Figure):
9 parameters = {
10 'id': global_type_string,
11 'wintitle': global_type_string,
12 'channelList': global_type_list,
13 'showprofile': global_type_string,
14 'xmin': global_type_float,
15 'xmax': global_type_float,
16 'ymin': global_type_float,
17 'ymax': global_type_float,
18 'zmin': global_type_float,
19 'zmax': global_type_float,
20 'save': global_type_boolean,
21 'figpath': global_type_string,
22 'figfile': global_type_string,
23 'show': global_type_boolean,
24 'ftp': global_type_boolean,
25 'wr_period': global_type_integer,
26 'server': global_type_string,
27 'folder': global_type_string,
28 'username': global_type_string,
29 'password': global_type_string,
30 'ftp_wei': global_type_integer,
31 'exp_code': global_type_integer,
32 'sub_exp_code': global_type_integer,
33 'plot_pos': global_type_integer,
34 'realtime': global_type_boolean,
35 }
9 36
10 37 isConfig = None
11 38 __nsubplots = None
12 39
13 40 WIDTHPROF = None
14 41 HEIGHTPROF = None
15 42 PREFIX = 'corr'
16 43
17 44 def __init__(self, **kwargs):
18 45 Figure.__init__(self, **kwargs)
19 46 self.isConfig = False
20 47 self.__nsubplots = 1
21 48
22 49 self.WIDTH = 280
23 50 self.HEIGHT = 250
24 51 self.WIDTHPROF = 120
25 52 self.HEIGHTPROF = 0
26 53 self.counter_imagwr = 0
27 54
28 55 self.PLOT_CODE = 1
29 56 self.FTP_WEI = None
30 57 self.EXP_CODE = None
31 58 self.SUB_EXP_CODE = None
32 59 self.PLOT_POS = None
33 60
34 61 def getSubplots(self):
35 62
36 63 ncol = int(numpy.sqrt(self.nplots)+0.9)
37 64 nrow = int(self.nplots*1./ncol + 0.9)
38 65
39 66 return nrow, ncol
40 67
41 68 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
42 69
43 70 showprofile = False
44 71 self.__showprofile = showprofile
45 72 self.nplots = nplots
46 73
47 74 ncolspan = 1
48 75 colspan = 1
49 76 if showprofile:
50 77 ncolspan = 3
51 78 colspan = 2
52 79 self.__nsubplots = 2
53 80
54 81 self.createFigure(id = id,
55 82 wintitle = wintitle,
56 83 widthplot = self.WIDTH + self.WIDTHPROF,
57 84 heightplot = self.HEIGHT + self.HEIGHTPROF,
58 85 show=show)
59 86
60 87 nrow, ncol = self.getSubplots()
61 88
62 89 counter = 0
63 90 for y in range(nrow):
64 91 for x in range(ncol):
65 92
66 93 if counter >= self.nplots:
67 94 break
68 95
69 96 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
70 97
71 98 if showprofile:
72 99 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
73 100
74 101 counter += 1
75 102
76 103 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
77 104 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
78 105 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
79 106 server=None, folder=None, username=None, password=None,
80 107 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
81 108
82 109 """
83 110
84 111 Input:
85 112 dataOut :
86 113 id :
87 114 wintitle :
88 115 channelList :
89 116 showProfile :
90 117 xmin : None,
91 118 xmax : None,
92 119 ymin : None,
93 120 ymax : None,
94 121 zmin : None,
95 122 zmax : None
96 123 """
97 124
98 125 if dataOut.flagNoData:
99 126 return None
100 127
101 128 if realtime:
102 129 if not(isRealtime(utcdatatime = dataOut.utctime)):
103 130 print 'Skipping this plot function'
104 131 return
105 132
106 133 if channelList == None:
107 134 channelIndexList = dataOut.channelIndexList
108 135 else:
109 136 channelIndexList = []
110 137 for channel in channelList:
111 138 if channel not in dataOut.channelList:
112 139 raise ValueError, "Channel %d is not in dataOut.channelList"
113 140 channelIndexList.append(dataOut.channelList.index(channel))
114 141
115 142 factor = dataOut.normFactor
116 143 lenfactor = factor.shape[1]
117 144 x = dataOut.getLagTRange(1)
118 145 y = dataOut.getHeiRange()
119 146
120 147 z = copy.copy(dataOut.data_corr[:,:,0,:])
121 148 for i in range(dataOut.data_corr.shape[0]):
122 149 z[i,:,:] = z[i,:,:]/factor[i,:]
123 150 zdB = numpy.abs(z)
124 151
125 152 avg = numpy.average(z, axis=1)
126 153 # avg = numpy.nanmean(z, axis=1)
127 154 # noise = dataOut.noise/factor
128 155
129 156 #thisDatetime = dataOut.datatime
130 157 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
131 158 title = wintitle + " Correlation"
132 159 xlabel = "Lag T (s)"
133 160 ylabel = "Range (Km)"
134 161
135 162 if not self.isConfig:
136 163
137 164 nplots = dataOut.data_corr.shape[0]
138 165
139 166 self.setup(id=id,
140 167 nplots=nplots,
141 168 wintitle=wintitle,
142 169 showprofile=showprofile,
143 170 show=show)
144 171
145 172 if xmin == None: xmin = numpy.nanmin(x)
146 173 if xmax == None: xmax = numpy.nanmax(x)
147 174 if ymin == None: ymin = numpy.nanmin(y)
148 175 if ymax == None: ymax = numpy.nanmax(y)
149 176 if zmin == None: zmin = 0
150 177 if zmax == None: zmax = 1
151 178
152 179 self.FTP_WEI = ftp_wei
153 180 self.EXP_CODE = exp_code
154 181 self.SUB_EXP_CODE = sub_exp_code
155 182 self.PLOT_POS = plot_pos
156 183
157 184 self.isConfig = True
158 185
159 186 self.setWinTitle(title)
160 187
161 188 for i in range(self.nplots):
162 189 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
163 190 title = "Channel %d and %d: : %s" %(dataOut.pairsList[i][0],dataOut.pairsList[i][1] , str_datetime)
164 191 axes = self.axesList[i*self.__nsubplots]
165 192 axes.pcolor(x, y, zdB[i,:,:],
166 193 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
167 194 xlabel=xlabel, ylabel=ylabel, title=title,
168 195 ticksize=9, cblabel='')
169 196
170 197 # if self.__showprofile:
171 198 # axes = self.axesList[i*self.__nsubplots +1]
172 199 # axes.pline(avgdB[i], y,
173 200 # xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
174 201 # xlabel='dB', ylabel='', title='',
175 202 # ytick_visible=False,
176 203 # grid='x')
177 204 #
178 205 # noiseline = numpy.repeat(noisedB[i], len(y))
179 206 # axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
180 207
181 208 self.draw()
182 209
183 210 self.save(figpath=figpath,
184 211 figfile=figfile,
185 212 save=save,
186 213 ftp=ftp,
187 214 wr_period=wr_period,
188 215 thisDatetime=thisDatetime)
@@ -1,1945 +1,2077
1 1 import os
2 2 import datetime
3 3 import numpy
4 4 import inspect
5 5 from figure import Figure, isRealtime, isTimeInHourRange
6 6 from plotting_codes import *
7 7
8 8
9 9 class MomentsPlot(Figure):
10 10
11 11 isConfig = None
12 12 __nsubplots = None
13 13
14 14 WIDTHPROF = None
15 15 HEIGHTPROF = None
16 16 PREFIX = 'prm'
17 17
18 parameters = {
19 'id': global_type_string,
20 'wintitle': global_type_string,
21 'channelList': global_type_list,
22 'showprofile': global_type_boolean,
23 'xmin': global_type_float,
24 'xmax': global_type_float,
25 'ymin': global_type_float,
26 'ymax': global_type_float,
27 'zmin': global_type_float,
28 'zmax': global_type_float,
29 'save': global_type_boolean,
30 'figpath': global_type_string,
31 'figfile': global_type_string,
32 'show': global_type_boolean,
33 'ftp': global_type_boolean,
34 'wr_period': global_type_integer,
35 'server': global_type_string,
36 'folder': global_type_string,
37 'username': global_type_string,
38 'password': global_type_string,
39 'ftp_wei': global_type_string,
40 'exp_code': global_type_integer,
41 'sub_exp_code': global_type_integer,
42 'plot_pos': global_type_integer,
43 'realtime': global_type_boolean,
44 }
45
18 46 def __init__(self, **kwargs):
19 47 Figure.__init__(self, **kwargs)
20 48 self.isConfig = False
21 49 self.__nsubplots = 1
22 50
23 51 self.WIDTH = 280
24 52 self.HEIGHT = 250
25 53 self.WIDTHPROF = 120
26 54 self.HEIGHTPROF = 0
27 55 self.counter_imagwr = 0
28 56
29 57 self.PLOT_CODE = MOMENTS_CODE
30 58
31 59 self.FTP_WEI = None
32 60 self.EXP_CODE = None
33 61 self.SUB_EXP_CODE = None
34 62 self.PLOT_POS = None
35 63
36 64 def getSubplots(self):
37 65
38 66 ncol = int(numpy.sqrt(self.nplots)+0.9)
39 67 nrow = int(self.nplots*1./ncol + 0.9)
40 68
41 69 return nrow, ncol
42 70
43 71 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
44 72
45 73 self.__showprofile = showprofile
46 74 self.nplots = nplots
47 75
48 76 ncolspan = 1
49 77 colspan = 1
50 78 if showprofile:
51 79 ncolspan = 3
52 80 colspan = 2
53 81 self.__nsubplots = 2
54 82
55 83 self.createFigure(id = id,
56 84 wintitle = wintitle,
57 85 widthplot = self.WIDTH + self.WIDTHPROF,
58 86 heightplot = self.HEIGHT + self.HEIGHTPROF,
59 87 show=show)
60 88
61 89 nrow, ncol = self.getSubplots()
62 90
63 91 counter = 0
64 92 for y in range(nrow):
65 93 for x in range(ncol):
66 94
67 95 if counter >= self.nplots:
68 96 break
69 97
70 98 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
71 99
72 100 if showprofile:
73 101 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
74 102
75 103 counter += 1
76 104
77 105 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
78 106 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
79 107 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
80 108 server=None, folder=None, username=None, password=None,
81 109 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
82 110
83 111 """
84 112
85 113 Input:
86 114 dataOut :
87 115 id :
88 116 wintitle :
89 117 channelList :
90 118 showProfile :
91 119 xmin : None,
92 120 xmax : None,
93 121 ymin : None,
94 122 ymax : None,
95 123 zmin : None,
96 124 zmax : None
97 125 """
98 126
99 127 if dataOut.flagNoData:
100 128 return None
101 129
102 130 if realtime:
103 131 if not(isRealtime(utcdatatime = dataOut.utctime)):
104 132 print 'Skipping this plot function'
105 133 return
106 134
107 135 if channelList == None:
108 136 channelIndexList = dataOut.channelIndexList
109 137 else:
110 138 channelIndexList = []
111 139 for channel in channelList:
112 140 if channel not in dataOut.channelList:
113 141 raise ValueError, "Channel %d is not in dataOut.channelList"
114 142 channelIndexList.append(dataOut.channelList.index(channel))
115 143
116 144 factor = dataOut.normFactor
117 145 x = dataOut.abscissaList
118 146 y = dataOut.heightList
119 147
120 148 z = dataOut.data_pre[channelIndexList,:,:]/factor
121 149 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
122 150 avg = numpy.average(z, axis=1)
123 151 noise = dataOut.noise/factor
124 152
125 153 zdB = 10*numpy.log10(z)
126 154 avgdB = 10*numpy.log10(avg)
127 155 noisedB = 10*numpy.log10(noise)
128 156
129 157 #thisDatetime = dataOut.datatime
130 158 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
131 159 title = wintitle + " Parameters"
132 160 xlabel = "Velocity (m/s)"
133 161 ylabel = "Range (Km)"
134 162
135 163 update_figfile = False
136 164
137 165 if not self.isConfig:
138 166
139 167 nplots = len(channelIndexList)
140 168
141 169 self.setup(id=id,
142 170 nplots=nplots,
143 171 wintitle=wintitle,
144 172 showprofile=showprofile,
145 173 show=show)
146 174
147 175 if xmin == None: xmin = numpy.nanmin(x)
148 176 if xmax == None: xmax = numpy.nanmax(x)
149 177 if ymin == None: ymin = numpy.nanmin(y)
150 178 if ymax == None: ymax = numpy.nanmax(y)
151 179 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
152 180 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
153 181
154 182 self.FTP_WEI = ftp_wei
155 183 self.EXP_CODE = exp_code
156 184 self.SUB_EXP_CODE = sub_exp_code
157 185 self.PLOT_POS = plot_pos
158 186
159 187 self.isConfig = True
160 188 update_figfile = True
161 189
162 190 self.setWinTitle(title)
163 191
164 192 for i in range(self.nplots):
165 193 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
166 194 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[i], noisedB[i], str_datetime)
167 195 axes = self.axesList[i*self.__nsubplots]
168 196 axes.pcolor(x, y, zdB[i,:,:],
169 197 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
170 198 xlabel=xlabel, ylabel=ylabel, title=title,
171 199 ticksize=9, cblabel='')
172 200 #Mean Line
173 201 mean = dataOut.data_param[i, 1, :]
174 202 axes.addpline(mean, y, idline=0, color="black", linestyle="solid", lw=1)
175 203
176 204 if self.__showprofile:
177 205 axes = self.axesList[i*self.__nsubplots +1]
178 206 axes.pline(avgdB[i], y,
179 207 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
180 208 xlabel='dB', ylabel='', title='',
181 209 ytick_visible=False,
182 210 grid='x')
183 211
184 212 noiseline = numpy.repeat(noisedB[i], len(y))
185 213 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
186 214
187 215 self.draw()
188 216
189 217 self.save(figpath=figpath,
190 218 figfile=figfile,
191 219 save=save,
192 220 ftp=ftp,
193 221 wr_period=wr_period,
194 222 thisDatetime=thisDatetime)
195 223
196 224
197 225
198 226 class SkyMapPlot(Figure):
199 227
200 228 __isConfig = None
201 229 __nsubplots = None
202 230
203 231 WIDTHPROF = None
204 232 HEIGHTPROF = None
205 233 PREFIX = 'mmap'
206 234
207 235 def __init__(self, **kwargs):
208 236 Figure.__init__(self, **kwargs)
209 237 self.isConfig = False
210 238 self.__nsubplots = 1
211 239
212 240 # self.WIDTH = 280
213 241 # self.HEIGHT = 250
214 242 self.WIDTH = 600
215 243 self.HEIGHT = 600
216 244 self.WIDTHPROF = 120
217 245 self.HEIGHTPROF = 0
218 246 self.counter_imagwr = 0
219 247
220 248 self.PLOT_CODE = MSKYMAP_CODE
221 249
222 250 self.FTP_WEI = None
223 251 self.EXP_CODE = None
224 252 self.SUB_EXP_CODE = None
225 253 self.PLOT_POS = None
226 254
227 255 def getSubplots(self):
228 256
229 257 ncol = int(numpy.sqrt(self.nplots)+0.9)
230 258 nrow = int(self.nplots*1./ncol + 0.9)
231 259
232 260 return nrow, ncol
233 261
234 262 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
235 263
236 264 self.__showprofile = showprofile
237 265 self.nplots = nplots
238 266
239 267 ncolspan = 1
240 268 colspan = 1
241 269
242 270 self.createFigure(id = id,
243 271 wintitle = wintitle,
244 272 widthplot = self.WIDTH, #+ self.WIDTHPROF,
245 273 heightplot = self.HEIGHT,# + self.HEIGHTPROF,
246 274 show=show)
247 275
248 276 nrow, ncol = 1,1
249 277 counter = 0
250 278 x = 0
251 279 y = 0
252 280 self.addAxes(1, 1, 0, 0, 1, 1, True)
253 281
254 282 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
255 283 tmin=0, tmax=24, timerange=None,
256 284 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
257 285 server=None, folder=None, username=None, password=None,
258 286 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False):
259 287
260 288 """
261 289
262 290 Input:
263 291 dataOut :
264 292 id :
265 293 wintitle :
266 294 channelList :
267 295 showProfile :
268 296 xmin : None,
269 297 xmax : None,
270 298 ymin : None,
271 299 ymax : None,
272 300 zmin : None,
273 301 zmax : None
274 302 """
275 303
276 304 arrayParameters = dataOut.data_param
277 305 error = arrayParameters[:,-1]
278 306 indValid = numpy.where(error == 0)[0]
279 307 finalMeteor = arrayParameters[indValid,:]
280 308 finalAzimuth = finalMeteor[:,3]
281 309 finalZenith = finalMeteor[:,4]
282 310
283 311 x = finalAzimuth*numpy.pi/180
284 312 y = finalZenith
285 313 x1 = [dataOut.ltctime, dataOut.ltctime]
286 314
287 315 #thisDatetime = dataOut.datatime
288 316 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
289 317 title = wintitle + " Parameters"
290 318 xlabel = "Zonal Zenith Angle (deg) "
291 319 ylabel = "Meridional Zenith Angle (deg)"
292 320 update_figfile = False
293 321
294 322 if not self.isConfig:
295 323
296 324 nplots = 1
297 325
298 326 self.setup(id=id,
299 327 nplots=nplots,
300 328 wintitle=wintitle,
301 329 showprofile=showprofile,
302 330 show=show)
303 331
304 332 if self.xmin is None and self.xmax is None:
305 333 self.xmin, self.xmax = self.getTimeLim(x1, tmin, tmax, timerange)
306 334
307 335 if timerange != None:
308 336 self.timerange = timerange
309 337 else:
310 338 self.timerange = self.xmax - self.xmin
311 339
312 340 self.FTP_WEI = ftp_wei
313 341 self.EXP_CODE = exp_code
314 342 self.SUB_EXP_CODE = sub_exp_code
315 343 self.PLOT_POS = plot_pos
316 344 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
317 345 self.firstdate = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
318 346 self.isConfig = True
319 347 update_figfile = True
320 348
321 349 self.setWinTitle(title)
322 350
323 351 i = 0
324 352 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
325 353
326 354 axes = self.axesList[i*self.__nsubplots]
327 355 nevents = axes.x_buffer.shape[0] + x.shape[0]
328 356 title = "Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n" %(self.firstdate,str_datetime,nevents)
329 357 axes.polar(x, y,
330 358 title=title, xlabel=xlabel, ylabel=ylabel,
331 359 ticksize=9, cblabel='')
332 360
333 361 self.draw()
334 362
335 363 self.save(figpath=figpath,
336 364 figfile=figfile,
337 365 save=save,
338 366 ftp=ftp,
339 367 wr_period=wr_period,
340 368 thisDatetime=thisDatetime,
341 369 update_figfile=update_figfile)
342 370
343 371 if dataOut.ltctime >= self.xmax:
344 372 self.isConfigmagwr = wr_period
345 373 self.isConfig = False
346 374 update_figfile = True
347 375 axes.__firsttime = True
348 376 self.xmin += self.timerange
349 377 self.xmax += self.timerange
350 378
351 379
352 380
353 381
354 382 class WindProfilerPlot(Figure):
355 383
356 384 __isConfig = None
357 385 __nsubplots = None
358 386
359 387 WIDTHPROF = None
360 388 HEIGHTPROF = None
361 389 PREFIX = 'wind'
362 390
363 391 def __init__(self, **kwargs):
364 392 Figure.__init__(self, **kwargs)
365 393 self.timerange = None
366 394 self.isConfig = False
367 395 self.__nsubplots = 1
368 396
369 397 self.WIDTH = 800
370 398 self.HEIGHT = 300
371 399 self.WIDTHPROF = 120
372 400 self.HEIGHTPROF = 0
373 401 self.counter_imagwr = 0
374 402
375 403 self.PLOT_CODE = WIND_CODE
376 404
377 405 self.FTP_WEI = None
378 406 self.EXP_CODE = None
379 407 self.SUB_EXP_CODE = None
380 408 self.PLOT_POS = None
381 409 self.tmin = None
382 410 self.tmax = None
383 411
384 412 self.xmin = None
385 413 self.xmax = None
386 414
387 415 self.figfile = None
388 416
389 417 def getSubplots(self):
390 418
391 419 ncol = 1
392 420 nrow = self.nplots
393 421
394 422 return nrow, ncol
395 423
396 424 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
397 425
398 426 self.__showprofile = showprofile
399 427 self.nplots = nplots
400 428
401 429 ncolspan = 1
402 430 colspan = 1
403 431
404 432 self.createFigure(id = id,
405 433 wintitle = wintitle,
406 434 widthplot = self.WIDTH + self.WIDTHPROF,
407 435 heightplot = self.HEIGHT + self.HEIGHTPROF,
408 436 show=show)
409 437
410 438 nrow, ncol = self.getSubplots()
411 439
412 440 counter = 0
413 441 for y in range(nrow):
414 442 if counter >= self.nplots:
415 443 break
416 444
417 445 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
418 446 counter += 1
419 447
420 448 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='False',
421 449 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
422 450 zmax_ver = None, zmin_ver = None, SNRmin = None, SNRmax = None,
423 451 timerange=None, SNRthresh = None,
424 452 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
425 453 server=None, folder=None, username=None, password=None,
426 454 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
427 455 """
428 456
429 457 Input:
430 458 dataOut :
431 459 id :
432 460 wintitle :
433 461 channelList :
434 462 showProfile :
435 463 xmin : None,
436 464 xmax : None,
437 465 ymin : None,
438 466 ymax : None,
439 467 zmin : None,
440 468 zmax : None
441 469 """
442 470
443 471 # if timerange is not None:
444 472 # self.timerange = timerange
445 473 #
446 474 # tmin = None
447 475 # tmax = None
448 476
449 477
450 478 x = dataOut.getTimeRange1(dataOut.outputInterval)
451 479 y = dataOut.heightList
452 480 z = dataOut.data_output.copy()
453 481 nplots = z.shape[0] #Number of wind dimensions estimated
454 482 nplotsw = nplots
455 483
456 484
457 485 #If there is a SNR function defined
458 486 if dataOut.data_SNR is not None:
459 487 nplots += 1
460 488 SNR = dataOut.data_SNR
461 489 SNRavg = numpy.average(SNR, axis=0)
462 490
463 491 SNRdB = 10*numpy.log10(SNR)
464 492 SNRavgdB = 10*numpy.log10(SNRavg)
465 493
466 494 if SNRthresh == None: SNRthresh = -5.0
467 495 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
468 496
469 497 for i in range(nplotsw):
470 498 z[i,ind] = numpy.nan
471 499
472 500 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
473 501 #thisDatetime = datetime.datetime.now()
474 502 title = wintitle + "Wind"
475 503 xlabel = ""
476 504 ylabel = "Height (km)"
477 505 update_figfile = False
478 506
479 507 if not self.isConfig:
480 508
481 509 self.setup(id=id,
482 510 nplots=nplots,
483 511 wintitle=wintitle,
484 512 showprofile=showprofile,
485 513 show=show)
486 514
487 515 if timerange is not None:
488 516 self.timerange = timerange
489 517
490 518 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
491 519
492 520 if ymin == None: ymin = numpy.nanmin(y)
493 521 if ymax == None: ymax = numpy.nanmax(y)
494 522
495 523 if zmax == None: zmax = numpy.nanmax(abs(z[range(2),:]))
496 524 #if numpy.isnan(zmax): zmax = 50
497 525 if zmin == None: zmin = -zmax
498 526
499 527 if nplotsw == 3:
500 528 if zmax_ver == None: zmax_ver = numpy.nanmax(abs(z[2,:]))
501 529 if zmin_ver == None: zmin_ver = -zmax_ver
502 530
503 531 if dataOut.data_SNR is not None:
504 532 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
505 533 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
506 534
507 535
508 536 self.FTP_WEI = ftp_wei
509 537 self.EXP_CODE = exp_code
510 538 self.SUB_EXP_CODE = sub_exp_code
511 539 self.PLOT_POS = plot_pos
512 540
513 541 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
514 542 self.isConfig = True
515 543 self.figfile = figfile
516 544 update_figfile = True
517 545
518 546 self.setWinTitle(title)
519 547
520 548 if ((self.xmax - x[1]) < (x[1]-x[0])):
521 549 x[1] = self.xmax
522 550
523 551 strWind = ['Zonal', 'Meridional', 'Vertical']
524 552 strCb = ['Velocity (m/s)','Velocity (m/s)','Velocity (cm/s)']
525 553 zmaxVector = [zmax, zmax, zmax_ver]
526 554 zminVector = [zmin, zmin, zmin_ver]
527 555 windFactor = [1,1,100]
528 556
529 557 for i in range(nplotsw):
530 558
531 559 title = "%s Wind: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
532 560 axes = self.axesList[i*self.__nsubplots]
533 561
534 562 z1 = z[i,:].reshape((1,-1))*windFactor[i]
535 563 #z1=numpy.ma.masked_where(z1==0.,z1)
536 564
537 565 axes.pcolorbuffer(x, y, z1,
538 566 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
539 567 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
540 568 ticksize=9, cblabel=strCb[i], cbsize="1%", colormap="seismic" )
541 569
542 570 if dataOut.data_SNR is not None:
543 571 i += 1
544 572 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
545 573 axes = self.axesList[i*self.__nsubplots]
546 574 SNRavgdB = SNRavgdB.reshape((1,-1))
547 575 axes.pcolorbuffer(x, y, SNRavgdB,
548 576 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
549 577 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
550 578 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
551 579
552 580 self.draw()
553 581
554 582 self.save(figpath=figpath,
555 583 figfile=figfile,
556 584 save=save,
557 585 ftp=ftp,
558 586 wr_period=wr_period,
559 587 thisDatetime=thisDatetime,
560 588 update_figfile=update_figfile)
561 589
562 590 if dataOut.ltctime + dataOut.outputInterval >= self.xmax:
563 591 self.counter_imagwr = wr_period
564 592 self.isConfig = False
565 593 update_figfile = True
566 594
567 595
568 596 class ParametersPlot(Figure):
569 597
570 598 __isConfig = None
571 599 __nsubplots = None
572 600
573 601 WIDTHPROF = None
574 602 HEIGHTPROF = None
575 603 PREFIX = 'param'
576 604
577 605 nplots = None
578 606 nchan = None
579 607
580 608 def __init__(self, **kwargs):
581 609 Figure.__init__(self, **kwargs)
582 610 self.timerange = None
583 611 self.isConfig = False
584 612 self.__nsubplots = 1
585 613
586 614 self.WIDTH = 800
587 615 self.HEIGHT = 180
588 616 self.WIDTHPROF = 120
589 617 self.HEIGHTPROF = 0
590 618 self.counter_imagwr = 0
591 619
592 620 self.PLOT_CODE = RTI_CODE
593 621
594 622 self.FTP_WEI = None
595 623 self.EXP_CODE = None
596 624 self.SUB_EXP_CODE = None
597 625 self.PLOT_POS = None
598 626 self.tmin = None
599 627 self.tmax = None
600 628
601 629 self.xmin = None
602 630 self.xmax = None
603 631
604 632 self.figfile = None
605 633
606 634 def getSubplots(self):
607 635
608 636 ncol = 1
609 637 nrow = self.nplots
610 638
611 639 return nrow, ncol
612 640
613 641 def setup(self, id, nplots, wintitle, show=True):
614 642
615 643 self.nplots = nplots
616 644
617 645 ncolspan = 1
618 646 colspan = 1
619 647
620 648 self.createFigure(id = id,
621 649 wintitle = wintitle,
622 650 widthplot = self.WIDTH + self.WIDTHPROF,
623 651 heightplot = self.HEIGHT + self.HEIGHTPROF,
624 652 show=show)
625 653
626 654 nrow, ncol = self.getSubplots()
627 655
628 656 counter = 0
629 657 for y in range(nrow):
630 658 for x in range(ncol):
631 659
632 660 if counter >= self.nplots:
633 661 break
634 662
635 663 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
636 664
637 665 counter += 1
638 666
639 667 def run(self, dataOut, id, wintitle="", channelList=None, paramIndex = 0, colormap=True,
640 668 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None, timerange=None,
641 669 showSNR=False, SNRthresh = -numpy.inf, SNRmin=None, SNRmax=None,
642 670 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
643 671 server=None, folder=None, username=None, password=None,
644 672 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
645 673 """
646 674
647 675 Input:
648 676 dataOut :
649 677 id :
650 678 wintitle :
651 679 channelList :
652 680 showProfile :
653 681 xmin : None,
654 682 xmax : None,
655 683 ymin : None,
656 684 ymax : None,
657 685 zmin : None,
658 686 zmax : None
659 687 """
660 688
661 689 if colormap:
662 690 colormap="jet"
663 691 else:
664 692 colormap="RdBu_r"
665 693
666 694 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
667 695 return
668 696
669 697 if channelList == None:
670 698 channelIndexList = range(dataOut.data_param.shape[0])
671 699 else:
672 700 channelIndexList = []
673 701 for channel in channelList:
674 702 if channel not in dataOut.channelList:
675 703 raise ValueError, "Channel %d is not in dataOut.channelList"
676 704 channelIndexList.append(dataOut.channelList.index(channel))
677 705
678 706 x = dataOut.getTimeRange1(dataOut.paramInterval)
679 707 y = dataOut.getHeiRange()
680 708
681 709 if dataOut.data_param.ndim == 3:
682 710 z = dataOut.data_param[channelIndexList,paramIndex,:]
683 711 else:
684 712 z = dataOut.data_param[channelIndexList,:]
685 713
686 714 if showSNR:
687 715 #SNR data
688 716 SNRarray = dataOut.data_SNR[channelIndexList,:]
689 717 SNRdB = 10*numpy.log10(SNRarray)
690 718 ind = numpy.where(SNRdB < SNRthresh)
691 719 z[ind] = numpy.nan
692 720
693 721 thisDatetime = dataOut.datatime
694 722 # thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
695 723 title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
696 724 xlabel = ""
697 725 ylabel = "Range (Km)"
698 726
699 727 update_figfile = False
700 728
701 729 if not self.isConfig:
702 730
703 731 nchan = len(channelIndexList)
704 732 self.nchan = nchan
705 733 self.plotFact = 1
706 734 nplots = nchan
707 735
708 736 if showSNR:
709 737 nplots = nchan*2
710 738 self.plotFact = 2
711 739 if SNRmin == None: SNRmin = numpy.nanmin(SNRdB)
712 740 if SNRmax == None: SNRmax = numpy.nanmax(SNRdB)
713 741
714 742 self.setup(id=id,
715 743 nplots=nplots,
716 744 wintitle=wintitle,
717 745 show=show)
718 746
719 747 if timerange != None:
720 748 self.timerange = timerange
721 749
722 750 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
723 751
724 752 if ymin == None: ymin = numpy.nanmin(y)
725 753 if ymax == None: ymax = numpy.nanmax(y)
726 754 if zmin == None: zmin = numpy.nanmin(z)
727 755 if zmax == None: zmax = numpy.nanmax(z)
728 756
729 757 self.FTP_WEI = ftp_wei
730 758 self.EXP_CODE = exp_code
731 759 self.SUB_EXP_CODE = sub_exp_code
732 760 self.PLOT_POS = plot_pos
733 761
734 762 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
735 763 self.isConfig = True
736 764 self.figfile = figfile
737 765 update_figfile = True
738 766
739 767 self.setWinTitle(title)
740 768
741 769 for i in range(self.nchan):
742 770 index = channelIndexList[i]
743 771 title = "Channel %d: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
744 772 axes = self.axesList[i*self.plotFact]
745 773 z1 = z[i,:].reshape((1,-1))
746 774 axes.pcolorbuffer(x, y, z1,
747 775 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
748 776 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
749 777 ticksize=9, cblabel='', cbsize="1%",colormap=colormap)
750 778
751 779 if showSNR:
752 780 title = "Channel %d SNR: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
753 781 axes = self.axesList[i*self.plotFact + 1]
754 782 SNRdB1 = SNRdB[i,:].reshape((1,-1))
755 783 axes.pcolorbuffer(x, y, SNRdB1,
756 784 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
757 785 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
758 786 ticksize=9, cblabel='', cbsize="1%",colormap='jet')
759 787
760 788
761 789 self.draw()
762 790
763 791 if dataOut.ltctime >= self.xmax:
764 792 self.counter_imagwr = wr_period
765 793 self.isConfig = False
766 794 update_figfile = True
767 795
768 796 self.save(figpath=figpath,
769 797 figfile=figfile,
770 798 save=save,
771 799 ftp=ftp,
772 800 wr_period=wr_period,
773 801 thisDatetime=thisDatetime,
774 802 update_figfile=update_figfile)
775 803
776 804
777 805
778 806 class Parameters1Plot(Figure):
779 807
780 808 __isConfig = None
781 809 __nsubplots = None
782 810
783 811 WIDTHPROF = None
784 812 HEIGHTPROF = None
785 813 PREFIX = 'prm'
786 814
787 815 def __init__(self, **kwargs):
788 816 Figure.__init__(self, **kwargs)
789 817 self.timerange = 2*60*60
790 818 self.isConfig = False
791 819 self.__nsubplots = 1
792 820
793 821 self.WIDTH = 800
794 822 self.HEIGHT = 180
795 823 self.WIDTHPROF = 120
796 824 self.HEIGHTPROF = 0
797 825 self.counter_imagwr = 0
798 826
799 827 self.PLOT_CODE = PARMS_CODE
800 828
801 829 self.FTP_WEI = None
802 830 self.EXP_CODE = None
803 831 self.SUB_EXP_CODE = None
804 832 self.PLOT_POS = None
805 833 self.tmin = None
806 834 self.tmax = None
807 835
808 836 self.xmin = None
809 837 self.xmax = None
810 838
811 839 self.figfile = None
812 840
813 841 def getSubplots(self):
814 842
815 843 ncol = 1
816 844 nrow = self.nplots
817 845
818 846 return nrow, ncol
819 847
820 848 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
821 849
822 850 self.__showprofile = showprofile
823 851 self.nplots = nplots
824 852
825 853 ncolspan = 1
826 854 colspan = 1
827 855
828 856 self.createFigure(id = id,
829 857 wintitle = wintitle,
830 858 widthplot = self.WIDTH + self.WIDTHPROF,
831 859 heightplot = self.HEIGHT + self.HEIGHTPROF,
832 860 show=show)
833 861
834 862 nrow, ncol = self.getSubplots()
835 863
836 864 counter = 0
837 865 for y in range(nrow):
838 866 for x in range(ncol):
839 867
840 868 if counter >= self.nplots:
841 869 break
842 870
843 871 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
844 872
845 873 if showprofile:
846 874 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
847 875
848 876 counter += 1
849 877
850 878 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
851 879 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,timerange=None,
852 880 parameterIndex = None, onlyPositive = False,
853 881 SNRthresh = -numpy.inf, SNR = True, SNRmin = None, SNRmax = None, onlySNR = False,
854 882 DOP = True,
855 883 zlabel = "", parameterName = "", parameterObject = "data_param",
856 884 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
857 885 server=None, folder=None, username=None, password=None,
858 886 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
859 887 #print inspect.getargspec(self.run).args
860 888 """
861 889
862 890 Input:
863 891 dataOut :
864 892 id :
865 893 wintitle :
866 894 channelList :
867 895 showProfile :
868 896 xmin : None,
869 897 xmax : None,
870 898 ymin : None,
871 899 ymax : None,
872 900 zmin : None,
873 901 zmax : None
874 902 """
875 903
876 904 data_param = getattr(dataOut, parameterObject)
877 905
878 906 if channelList == None:
879 907 channelIndexList = numpy.arange(data_param.shape[0])
880 908 else:
881 909 channelIndexList = numpy.array(channelList)
882 910
883 911 nchan = len(channelIndexList) #Number of channels being plotted
884 912
885 913 if nchan < 1:
886 914 return
887 915
888 916 nGraphsByChannel = 0
889 917
890 918 if SNR:
891 919 nGraphsByChannel += 1
892 920 if DOP:
893 921 nGraphsByChannel += 1
894 922
895 923 if nGraphsByChannel < 1:
896 924 return
897 925
898 926 nplots = nGraphsByChannel*nchan
899 927
900 928 if timerange is not None:
901 929 self.timerange = timerange
902 930
903 931 #tmin = None
904 932 #tmax = None
905 933 if parameterIndex == None:
906 934 parameterIndex = 1
907 935
908 936 x = dataOut.getTimeRange1(dataOut.paramInterval)
909 937 y = dataOut.heightList
910 938 z = data_param[channelIndexList,parameterIndex,:].copy()
911 939
912 940 zRange = dataOut.abscissaList
913 941 # nChannels = z.shape[0] #Number of wind dimensions estimated
914 942 # thisDatetime = dataOut.datatime
915 943
916 944 if dataOut.data_SNR is not None:
917 945 SNRarray = dataOut.data_SNR[channelIndexList,:]
918 946 SNRdB = 10*numpy.log10(SNRarray)
919 947 # SNRavgdB = 10*numpy.log10(SNRavg)
920 948 ind = numpy.where(SNRdB < 10**(SNRthresh/10))
921 949 z[ind] = numpy.nan
922 950
923 951 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
924 952 title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
925 953 xlabel = ""
926 954 ylabel = "Range (Km)"
927 955
928 956 if (SNR and not onlySNR): nplots = 2*nplots
929 957
930 958 if onlyPositive:
931 959 colormap = "jet"
932 960 zmin = 0
933 961 else: colormap = "RdBu_r"
934 962
935 963 if not self.isConfig:
936 964
937 965 self.setup(id=id,
938 966 nplots=nplots,
939 967 wintitle=wintitle,
940 968 showprofile=showprofile,
941 969 show=show)
942 970
943 971 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
944 972
945 973 if ymin == None: ymin = numpy.nanmin(y)
946 974 if ymax == None: ymax = numpy.nanmax(y)
947 975 if zmin == None: zmin = numpy.nanmin(zRange)
948 976 if zmax == None: zmax = numpy.nanmax(zRange)
949 977
950 978 if SNR:
951 979 if SNRmin == None: SNRmin = numpy.nanmin(SNRdB)
952 980 if SNRmax == None: SNRmax = numpy.nanmax(SNRdB)
953 981
954 982 self.FTP_WEI = ftp_wei
955 983 self.EXP_CODE = exp_code
956 984 self.SUB_EXP_CODE = sub_exp_code
957 985 self.PLOT_POS = plot_pos
958 986
959 987 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
960 988 self.isConfig = True
961 989 self.figfile = figfile
962 990
963 991 self.setWinTitle(title)
964 992
965 993 if ((self.xmax - x[1]) < (x[1]-x[0])):
966 994 x[1] = self.xmax
967 995
968 996 for i in range(nchan):
969 997
970 998 if (SNR and not onlySNR): j = 2*i
971 999 else: j = i
972 1000
973 1001 j = nGraphsByChannel*i
974 1002
975 1003 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
976 1004 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
977 1005
978 1006 if not onlySNR:
979 1007 axes = self.axesList[j*self.__nsubplots]
980 1008 z1 = z[i,:].reshape((1,-1))
981 1009 axes.pcolorbuffer(x, y, z1,
982 1010 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
983 1011 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
984 1012 ticksize=9, cblabel=zlabel, cbsize="1%")
985 1013
986 1014 if DOP:
987 1015 title = "%s Channel %d: %s" %(parameterName, channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
988 1016
989 1017 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
990 1018 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
991 1019 axes = self.axesList[j]
992 1020 z1 = z[i,:].reshape((1,-1))
993 1021 axes.pcolorbuffer(x, y, z1,
994 1022 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
995 1023 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
996 1024 ticksize=9, cblabel=zlabel, cbsize="1%")
997 1025
998 1026 if SNR:
999 1027 title = "Channel %d Signal Noise Ratio (SNR): %s" %(channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1000 1028 axes = self.axesList[(j)*self.__nsubplots]
1001 1029 if not onlySNR:
1002 1030 axes = self.axesList[(j + 1)*self.__nsubplots]
1003 1031
1004 1032 axes = self.axesList[(j + nGraphsByChannel-1)]
1005 1033
1006 1034 z1 = SNRdB[i,:].reshape((1,-1))
1007 1035 axes.pcolorbuffer(x, y, z1,
1008 1036 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1009 1037 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap="jet",
1010 1038 ticksize=9, cblabel=zlabel, cbsize="1%")
1011 1039
1012 1040
1013 1041
1014 1042 self.draw()
1015 1043
1016 1044 if x[1] >= self.axesList[0].xmax:
1017 1045 self.counter_imagwr = wr_period
1018 1046 self.isConfig = False
1019 1047 self.figfile = None
1020 1048
1021 1049 self.save(figpath=figpath,
1022 1050 figfile=figfile,
1023 1051 save=save,
1024 1052 ftp=ftp,
1025 1053 wr_period=wr_period,
1026 1054 thisDatetime=thisDatetime,
1027 1055 update_figfile=False)
1028 1056
1029 1057 class SpectralFittingPlot(Figure):
1030 1058
1031 1059 __isConfig = None
1032 1060 __nsubplots = None
1033 1061
1034 1062 WIDTHPROF = None
1035 1063 HEIGHTPROF = None
1036 1064 PREFIX = 'prm'
1037 1065
1038 1066
1039 1067 N = None
1040 1068 ippSeconds = None
1041 1069
1042 1070 def __init__(self, **kwargs):
1043 1071 Figure.__init__(self, **kwargs)
1044 1072 self.isConfig = False
1045 1073 self.__nsubplots = 1
1046 1074
1047 1075 self.PLOT_CODE = SPECFIT_CODE
1048 1076
1049 1077 self.WIDTH = 450
1050 1078 self.HEIGHT = 250
1051 1079 self.WIDTHPROF = 0
1052 1080 self.HEIGHTPROF = 0
1053 1081
1054 1082 def getSubplots(self):
1055 1083
1056 1084 ncol = int(numpy.sqrt(self.nplots)+0.9)
1057 1085 nrow = int(self.nplots*1./ncol + 0.9)
1058 1086
1059 1087 return nrow, ncol
1060 1088
1061 1089 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
1062 1090
1063 1091 showprofile = False
1064 1092 self.__showprofile = showprofile
1065 1093 self.nplots = nplots
1066 1094
1067 1095 ncolspan = 5
1068 1096 colspan = 4
1069 1097 if showprofile:
1070 1098 ncolspan = 5
1071 1099 colspan = 4
1072 1100 self.__nsubplots = 2
1073 1101
1074 1102 self.createFigure(id = id,
1075 1103 wintitle = wintitle,
1076 1104 widthplot = self.WIDTH + self.WIDTHPROF,
1077 1105 heightplot = self.HEIGHT + self.HEIGHTPROF,
1078 1106 show=show)
1079 1107
1080 1108 nrow, ncol = self.getSubplots()
1081 1109
1082 1110 counter = 0
1083 1111 for y in range(nrow):
1084 1112 for x in range(ncol):
1085 1113
1086 1114 if counter >= self.nplots:
1087 1115 break
1088 1116
1089 1117 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1090 1118
1091 1119 if showprofile:
1092 1120 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
1093 1121
1094 1122 counter += 1
1095 1123
1096 1124 def run(self, dataOut, id, cutHeight=None, fit=False, wintitle="", channelList=None, showprofile=True,
1097 1125 xmin=None, xmax=None, ymin=None, ymax=None,
1098 1126 save=False, figpath='./', figfile=None, show=True):
1099 1127
1100 1128 """
1101 1129
1102 1130 Input:
1103 1131 dataOut :
1104 1132 id :
1105 1133 wintitle :
1106 1134 channelList :
1107 1135 showProfile :
1108 1136 xmin : None,
1109 1137 xmax : None,
1110 1138 zmin : None,
1111 1139 zmax : None
1112 1140 """
1113 1141
1114 1142 if cutHeight==None:
1115 1143 h=270
1116 1144 heightindex = numpy.abs(cutHeight - dataOut.heightList).argmin()
1117 1145 cutHeight = dataOut.heightList[heightindex]
1118 1146
1119 1147 factor = dataOut.normFactor
1120 1148 x = dataOut.abscissaList[:-1]
1121 1149 #y = dataOut.getHeiRange()
1122 1150
1123 1151 z = dataOut.data_pre[:,:,heightindex]/factor
1124 1152 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1125 1153 avg = numpy.average(z, axis=1)
1126 1154 listChannels = z.shape[0]
1127 1155
1128 1156 #Reconstruct Function
1129 1157 if fit==True:
1130 1158 groupArray = dataOut.groupList
1131 1159 listChannels = groupArray.reshape((groupArray.size))
1132 1160 listChannels.sort()
1133 1161 spcFitLine = numpy.zeros(z.shape)
1134 1162 constants = dataOut.constants
1135 1163
1136 1164 nGroups = groupArray.shape[0]
1137 1165 nChannels = groupArray.shape[1]
1138 1166 nProfiles = z.shape[1]
1139 1167
1140 1168 for f in range(nGroups):
1141 1169 groupChann = groupArray[f,:]
1142 1170 p = dataOut.data_param[f,:,heightindex]
1143 1171 # p = numpy.array([ 89.343967,0.14036615,0.17086219,18.89835291,1.58388365,1.55099167])
1144 1172 fitLineAux = dataOut.library.modelFunction(p, constants)*nProfiles
1145 1173 fitLineAux = fitLineAux.reshape((nChannels,nProfiles))
1146 1174 spcFitLine[groupChann,:] = fitLineAux
1147 1175 # spcFitLine = spcFitLine/factor
1148 1176
1149 1177 z = z[listChannels,:]
1150 1178 spcFitLine = spcFitLine[listChannels,:]
1151 1179 spcFitLinedB = 10*numpy.log10(spcFitLine)
1152 1180
1153 1181 zdB = 10*numpy.log10(z)
1154 1182 #thisDatetime = dataOut.datatime
1155 1183 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1156 1184 title = wintitle + " Doppler Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
1157 1185 xlabel = "Velocity (m/s)"
1158 1186 ylabel = "Spectrum"
1159 1187
1160 1188 if not self.isConfig:
1161 1189
1162 1190 nplots = listChannels.size
1163 1191
1164 1192 self.setup(id=id,
1165 1193 nplots=nplots,
1166 1194 wintitle=wintitle,
1167 1195 showprofile=showprofile,
1168 1196 show=show)
1169 1197
1170 1198 if xmin == None: xmin = numpy.nanmin(x)
1171 1199 if xmax == None: xmax = numpy.nanmax(x)
1172 1200 if ymin == None: ymin = numpy.nanmin(zdB)
1173 1201 if ymax == None: ymax = numpy.nanmax(zdB)+2
1174 1202
1175 1203 self.isConfig = True
1176 1204
1177 1205 self.setWinTitle(title)
1178 1206 for i in range(self.nplots):
1179 1207 # title = "Channel %d: %4.2fdB" %(dataOut.channelList[i]+1, noisedB[i])
1180 1208 title = "Height %4.1f km\nChannel %d:" %(cutHeight, listChannels[i])
1181 1209 axes = self.axesList[i*self.__nsubplots]
1182 1210 if fit == False:
1183 1211 axes.pline(x, zdB[i,:],
1184 1212 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1185 1213 xlabel=xlabel, ylabel=ylabel, title=title
1186 1214 )
1187 1215 if fit == True:
1188 1216 fitline=spcFitLinedB[i,:]
1189 1217 y=numpy.vstack([zdB[i,:],fitline] )
1190 1218 legendlabels=['Data','Fitting']
1191 1219 axes.pmultilineyaxis(x, y,
1192 1220 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1193 1221 xlabel=xlabel, ylabel=ylabel, title=title,
1194 1222 legendlabels=legendlabels, marker=None,
1195 1223 linestyle='solid', grid='both')
1196 1224
1197 1225 self.draw()
1198 1226
1199 1227 self.save(figpath=figpath,
1200 1228 figfile=figfile,
1201 1229 save=save,
1202 1230 ftp=ftp,
1203 1231 wr_period=wr_period,
1204 1232 thisDatetime=thisDatetime)
1205 1233
1206 1234
1207 1235 class EWDriftsPlot(Figure):
1208 1236
1209 1237 __isConfig = None
1210 1238 __nsubplots = None
1211 1239
1212 1240 WIDTHPROF = None
1213 1241 HEIGHTPROF = None
1214 1242 PREFIX = 'drift'
1215 1243
1244 parameters = {
1245 'id': global_type_string,
1246 'wintitle': global_type_string,
1247 'channelList': global_type_string,
1248 'xmin': global_type_float,
1249 'xmax': global_type_float,
1250 'ymin': global_type_float,
1251 'ymax': global_type_float,
1252 'zmin': global_type_float,
1253 'zmax': global_type_float,
1254 'zmaxVertfloat': global_type_float,
1255 'zminVertfloat': global_type_float,
1256 'zmaxZonafloat': global_type_float,
1257 'zminZonafloat': global_type_float,
1258 'timerange': global_type_float,
1259 'SNRthresh': global_type_float,
1260 'SNRmin': global_type_float,
1261 'SNRmax': global_type_float,
1262 'SNR_1': global_type_boolean,
1263 'save': global_type_boolean,
1264 'figpath': global_type_string,
1265 'lastone': global_type_float,
1266 'figfile': global_type_string,
1267 'ftp': global_type_string,
1268 'wr_period': global_type_integer,
1269 'show': global_type_string,
1270 'server': global_type_string,
1271 'folder': global_type_string,
1272 'username': global_type_string,
1273 'password': global_type_string,
1274 'ftp_wei': global_type_integer,
1275 'exp_code': global_type_integer,
1276 'sub_exp_code': global_type_integer,
1277 'plot_pos': global_type_integer,
1278 }
1279
1216 1280 def __init__(self, **kwargs):
1217 1281 Figure.__init__(self, **kwargs)
1218 1282 self.timerange = 2*60*60
1219 1283 self.isConfig = False
1220 1284 self.__nsubplots = 1
1221 1285
1222 1286 self.WIDTH = 800
1223 1287 self.HEIGHT = 150
1224 1288 self.WIDTHPROF = 120
1225 1289 self.HEIGHTPROF = 0
1226 1290 self.counter_imagwr = 0
1227 1291
1228 1292 self.PLOT_CODE = EWDRIFT_CODE
1229 1293
1230 1294 self.FTP_WEI = None
1231 1295 self.EXP_CODE = None
1232 1296 self.SUB_EXP_CODE = None
1233 1297 self.PLOT_POS = None
1234 1298 self.tmin = None
1235 1299 self.tmax = None
1236 1300
1237 1301 self.xmin = None
1238 1302 self.xmax = None
1239 1303
1240 1304 self.figfile = None
1241 1305
1242 1306 def getSubplots(self):
1243 1307
1244 1308 ncol = 1
1245 1309 nrow = self.nplots
1246 1310
1247 1311 return nrow, ncol
1248 1312
1249 1313 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1250 1314
1251 1315 self.__showprofile = showprofile
1252 1316 self.nplots = nplots
1253 1317
1254 1318 ncolspan = 1
1255 1319 colspan = 1
1256 1320
1257 1321 self.createFigure(id = id,
1258 1322 wintitle = wintitle,
1259 1323 widthplot = self.WIDTH + self.WIDTHPROF,
1260 1324 heightplot = self.HEIGHT + self.HEIGHTPROF,
1261 1325 show=show)
1262 1326
1263 1327 nrow, ncol = self.getSubplots()
1264 1328
1265 1329 counter = 0
1266 1330 for y in range(nrow):
1267 1331 if counter >= self.nplots:
1268 1332 break
1269 1333
1270 1334 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
1271 1335 counter += 1
1272 1336
1273 1337 def run(self, dataOut, id, wintitle="", channelList=None,
1274 1338 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
1275 1339 zmaxVertical = None, zminVertical = None, zmaxZonal = None, zminZonal = None,
1276 1340 timerange=None, SNRthresh = -numpy.inf, SNRmin = None, SNRmax = None, SNR_1 = False,
1277 1341 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
1278 1342 server=None, folder=None, username=None, password=None,
1279 1343 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1280 1344 """
1281 1345
1282 1346 Input:
1283 1347 dataOut :
1284 1348 id :
1285 1349 wintitle :
1286 1350 channelList :
1287 1351 showProfile :
1288 1352 xmin : None,
1289 1353 xmax : None,
1290 1354 ymin : None,
1291 1355 ymax : None,
1292 1356 zmin : None,
1293 1357 zmax : None
1294 1358 """
1295 1359
1296 1360 if timerange is not None:
1297 1361 self.timerange = timerange
1298 1362
1299 1363 tmin = None
1300 1364 tmax = None
1301 1365
1302 1366 x = dataOut.getTimeRange1(dataOut.outputInterval)
1303 1367 # y = dataOut.heightList
1304 1368 y = dataOut.heightList
1305 1369
1306 1370 z = dataOut.data_output
1307 1371 nplots = z.shape[0] #Number of wind dimensions estimated
1308 1372 nplotsw = nplots
1309 1373
1310 1374 #If there is a SNR function defined
1311 1375 if dataOut.data_SNR is not None:
1312 1376 nplots += 1
1313 1377 SNR = dataOut.data_SNR
1314 1378
1315 1379 if SNR_1:
1316 1380 SNR += 1
1317 1381
1318 1382 SNRavg = numpy.average(SNR, axis=0)
1319 1383
1320 1384 SNRdB = 10*numpy.log10(SNR)
1321 1385 SNRavgdB = 10*numpy.log10(SNRavg)
1322 1386
1323 1387 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
1324 1388
1325 1389 for i in range(nplotsw):
1326 1390 z[i,ind] = numpy.nan
1327 1391
1328 1392
1329 1393 showprofile = False
1330 1394 # thisDatetime = dataOut.datatime
1331 1395 thisDatetime = datetime.datetime.utcfromtimestamp(x[1])
1332 1396 title = wintitle + " EW Drifts"
1333 1397 xlabel = ""
1334 1398 ylabel = "Height (Km)"
1335 1399
1336 1400 if not self.isConfig:
1337 1401
1338 1402 self.setup(id=id,
1339 1403 nplots=nplots,
1340 1404 wintitle=wintitle,
1341 1405 showprofile=showprofile,
1342 1406 show=show)
1343 1407
1344 1408 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1345 1409
1346 1410 if ymin == None: ymin = numpy.nanmin(y)
1347 1411 if ymax == None: ymax = numpy.nanmax(y)
1348 1412
1349 1413 if zmaxZonal == None: zmaxZonal = numpy.nanmax(abs(z[0,:]))
1350 1414 if zminZonal == None: zminZonal = -zmaxZonal
1351 1415 if zmaxVertical == None: zmaxVertical = numpy.nanmax(abs(z[1,:]))
1352 1416 if zminVertical == None: zminVertical = -zmaxVertical
1353 1417
1354 1418 if dataOut.data_SNR is not None:
1355 1419 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
1356 1420 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
1357 1421
1358 1422 self.FTP_WEI = ftp_wei
1359 1423 self.EXP_CODE = exp_code
1360 1424 self.SUB_EXP_CODE = sub_exp_code
1361 1425 self.PLOT_POS = plot_pos
1362 1426
1363 1427 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1364 1428 self.isConfig = True
1365 1429
1366 1430
1367 1431 self.setWinTitle(title)
1368 1432
1369 1433 if ((self.xmax - x[1]) < (x[1]-x[0])):
1370 1434 x[1] = self.xmax
1371 1435
1372 1436 strWind = ['Zonal','Vertical']
1373 1437 strCb = 'Velocity (m/s)'
1374 1438 zmaxVector = [zmaxZonal, zmaxVertical]
1375 1439 zminVector = [zminZonal, zminVertical]
1376 1440
1377 1441 for i in range(nplotsw):
1378 1442
1379 1443 title = "%s Drifts: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1380 1444 axes = self.axesList[i*self.__nsubplots]
1381 1445
1382 1446 z1 = z[i,:].reshape((1,-1))
1383 1447
1384 1448 axes.pcolorbuffer(x, y, z1,
1385 1449 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
1386 1450 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1387 1451 ticksize=9, cblabel=strCb, cbsize="1%", colormap="RdBu_r")
1388 1452
1389 1453 if dataOut.data_SNR is not None:
1390 1454 i += 1
1391 1455 if SNR_1:
1392 1456 title = "Signal Noise Ratio + 1 (SNR+1): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1393 1457 else:
1394 1458 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1395 1459 axes = self.axesList[i*self.__nsubplots]
1396 1460 SNRavgdB = SNRavgdB.reshape((1,-1))
1397 1461
1398 1462 axes.pcolorbuffer(x, y, SNRavgdB,
1399 1463 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1400 1464 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1401 1465 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
1402 1466
1403 1467 self.draw()
1404 1468
1405 1469 if x[1] >= self.axesList[0].xmax:
1406 1470 self.counter_imagwr = wr_period
1407 1471 self.isConfig = False
1408 1472 self.figfile = None
1409 1473
1410 1474
1411 1475
1412 1476
1413 1477 class PhasePlot(Figure):
1414 1478
1415 1479 __isConfig = None
1416 1480 __nsubplots = None
1417 1481
1418 1482 PREFIX = 'mphase'
1419 1483
1420 1484 def __init__(self, **kwargs):
1421 1485 Figure.__init__(self, **kwargs)
1422 1486 self.timerange = 24*60*60
1423 1487 self.isConfig = False
1424 1488 self.__nsubplots = 1
1425 1489 self.counter_imagwr = 0
1426 1490 self.WIDTH = 600
1427 1491 self.HEIGHT = 300
1428 1492 self.WIDTHPROF = 120
1429 1493 self.HEIGHTPROF = 0
1430 1494 self.xdata = None
1431 1495 self.ydata = None
1432 1496
1433 1497 self.PLOT_CODE = MPHASE_CODE
1434 1498
1435 1499 self.FTP_WEI = None
1436 1500 self.EXP_CODE = None
1437 1501 self.SUB_EXP_CODE = None
1438 1502 self.PLOT_POS = None
1439 1503
1440 1504
1441 1505 self.filename_phase = None
1442 1506
1443 1507 self.figfile = None
1444 1508
1445 1509 def getSubplots(self):
1446 1510
1447 1511 ncol = 1
1448 1512 nrow = 1
1449 1513
1450 1514 return nrow, ncol
1451 1515
1452 1516 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1453 1517
1454 1518 self.__showprofile = showprofile
1455 1519 self.nplots = nplots
1456 1520
1457 1521 ncolspan = 7
1458 1522 colspan = 6
1459 1523 self.__nsubplots = 2
1460 1524
1461 1525 self.createFigure(id = id,
1462 1526 wintitle = wintitle,
1463 1527 widthplot = self.WIDTH+self.WIDTHPROF,
1464 1528 heightplot = self.HEIGHT+self.HEIGHTPROF,
1465 1529 show=show)
1466 1530
1467 1531 nrow, ncol = self.getSubplots()
1468 1532
1469 1533 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1470 1534
1471 1535
1472 1536 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1473 1537 xmin=None, xmax=None, ymin=None, ymax=None,
1474 1538 timerange=None,
1475 1539 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1476 1540 server=None, folder=None, username=None, password=None,
1477 1541 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1478 1542
1479 1543
1480 1544 tmin = None
1481 1545 tmax = None
1482 1546 x = dataOut.getTimeRange1(dataOut.outputInterval)
1483 1547 y = dataOut.getHeiRange()
1484 1548
1485 1549
1486 1550 #thisDatetime = dataOut.datatime
1487 1551 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
1488 1552 title = wintitle + " Phase of Beacon Signal" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1489 1553 xlabel = "Local Time"
1490 1554 ylabel = "Phase"
1491 1555
1492 1556
1493 1557 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1494 1558 phase_beacon = dataOut.data_output
1495 1559 update_figfile = False
1496 1560
1497 1561 if not self.isConfig:
1498 1562
1499 1563 self.nplots = phase_beacon.size
1500 1564
1501 1565 self.setup(id=id,
1502 1566 nplots=self.nplots,
1503 1567 wintitle=wintitle,
1504 1568 showprofile=showprofile,
1505 1569 show=show)
1506 1570
1507 1571 if timerange is not None:
1508 1572 self.timerange = timerange
1509 1573
1510 1574 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1511 1575
1512 1576 if ymin == None: ymin = numpy.nanmin(phase_beacon) - 10.0
1513 1577 if ymax == None: ymax = numpy.nanmax(phase_beacon) + 10.0
1514 1578
1515 1579 self.FTP_WEI = ftp_wei
1516 1580 self.EXP_CODE = exp_code
1517 1581 self.SUB_EXP_CODE = sub_exp_code
1518 1582 self.PLOT_POS = plot_pos
1519 1583
1520 1584 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1521 1585 self.isConfig = True
1522 1586 self.figfile = figfile
1523 1587 self.xdata = numpy.array([])
1524 1588 self.ydata = numpy.array([])
1525 1589
1526 1590 #open file beacon phase
1527 1591 path = '%s%03d' %(self.PREFIX, self.id)
1528 1592 beacon_file = os.path.join(path,'%s.txt'%self.name)
1529 1593 self.filename_phase = os.path.join(figpath,beacon_file)
1530 1594 update_figfile = True
1531 1595
1532 1596
1533 1597 #store data beacon phase
1534 1598 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1535 1599
1536 1600 self.setWinTitle(title)
1537 1601
1538 1602
1539 1603 title = "Phase Offset %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1540 1604
1541 1605 legendlabels = ["phase %d"%(chan) for chan in numpy.arange(self.nplots)]
1542 1606
1543 1607 axes = self.axesList[0]
1544 1608
1545 1609 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1546 1610
1547 1611 if len(self.ydata)==0:
1548 1612 self.ydata = phase_beacon.reshape(-1,1)
1549 1613 else:
1550 1614 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1551 1615
1552 1616
1553 1617 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1554 1618 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1555 1619 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1556 1620 XAxisAsTime=True, grid='both'
1557 1621 )
1558 1622
1559 1623 self.draw()
1560 1624
1561 1625 self.save(figpath=figpath,
1562 1626 figfile=figfile,
1563 1627 save=save,
1564 1628 ftp=ftp,
1565 1629 wr_period=wr_period,
1566 1630 thisDatetime=thisDatetime,
1567 1631 update_figfile=update_figfile)
1568 1632
1569 1633 if dataOut.ltctime + dataOut.outputInterval >= self.xmax:
1570 1634 self.counter_imagwr = wr_period
1571 1635 self.isConfig = False
1572 1636 update_figfile = True
1573 1637
1574 1638
1575 1639
1576 1640 class NSMeteorDetection1Plot(Figure):
1577 1641
1578 1642 isConfig = None
1579 1643 __nsubplots = None
1580 1644
1581 1645 WIDTHPROF = None
1582 1646 HEIGHTPROF = None
1583 1647 PREFIX = 'nsm'
1584 1648
1585 1649 zminList = None
1586 1650 zmaxList = None
1587 1651 cmapList = None
1588 1652 titleList = None
1589 1653 nPairs = None
1590 1654 nChannels = None
1591 1655 nParam = None
1592 1656
1657 parameters = {
1658 'id': global_type_string,
1659 'wintitle': global_type_string,
1660 'channelList': global_type_list,
1661 'showprofile': global_type_boolean,
1662 'xmin': global_type_float,
1663 'xmax': global_type_float,
1664 'ymin': global_type_float,
1665 'ymax': global_type_float,
1666 'SNRmin': global_type_float,
1667 'SNRmax': global_type_float,
1668 'vmin': global_type_float,
1669 'vmax': global_type_float,
1670 'wmin': global_type_float,
1671 'wmax': global_type_float,
1672 'mode': global_type_string,
1673 'save': global_type_boolean,
1674 'figpath': global_type_string,
1675 'figfile': global_type_string,
1676 'show': global_type_boolean,
1677 'ftp': global_type_string,
1678 'wr_period': global_type_integer,
1679 'server': global_type_string,
1680 'folder': global_type_string,
1681 'username': global_type_string,
1682 'password': global_type_string,
1683 'ftp_wei': global_type_integer,
1684 'exp_code': global_type_integer,
1685 'sub_exp_code': global_type_integer,
1686 'plot_pos': global_type_integer,
1687 'realtime': global_type_boolean,
1688 'xaxis': global_type_string,
1689 }
1690
1593 1691 def __init__(self, **kwargs):
1594 1692 Figure.__init__(self, **kwargs)
1595 1693 self.isConfig = False
1596 1694 self.__nsubplots = 1
1597 1695
1598 1696 self.WIDTH = 750
1599 1697 self.HEIGHT = 250
1600 1698 self.WIDTHPROF = 120
1601 1699 self.HEIGHTPROF = 0
1602 1700 self.counter_imagwr = 0
1603 1701
1604 1702 self.PLOT_CODE = SPEC_CODE
1605 1703
1606 1704 self.FTP_WEI = None
1607 1705 self.EXP_CODE = None
1608 1706 self.SUB_EXP_CODE = None
1609 1707 self.PLOT_POS = None
1610 1708
1611 1709 self.__xfilter_ena = False
1612 1710 self.__yfilter_ena = False
1613 1711
1614 1712 def getSubplots(self):
1615 1713
1616 1714 ncol = 3
1617 1715 nrow = int(numpy.ceil(self.nplots/3.0))
1618 1716
1619 1717 return nrow, ncol
1620 1718
1621 1719 def setup(self, id, nplots, wintitle, show=True):
1622 1720
1623 1721 self.nplots = nplots
1624 1722
1625 1723 ncolspan = 1
1626 1724 colspan = 1
1627 1725
1628 1726 self.createFigure(id = id,
1629 1727 wintitle = wintitle,
1630 1728 widthplot = self.WIDTH + self.WIDTHPROF,
1631 1729 heightplot = self.HEIGHT + self.HEIGHTPROF,
1632 1730 show=show)
1633 1731
1634 1732 nrow, ncol = self.getSubplots()
1635 1733
1636 1734 counter = 0
1637 1735 for y in range(nrow):
1638 1736 for x in range(ncol):
1639 1737
1640 1738 if counter >= self.nplots:
1641 1739 break
1642 1740
1643 1741 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1644 1742
1645 1743 counter += 1
1646 1744
1647 1745 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
1648 1746 xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None,
1649 1747 vmin=None, vmax=None, wmin=None, wmax=None, mode = 'SA',
1650 1748 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1651 1749 server=None, folder=None, username=None, password=None,
1652 1750 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
1653 1751 xaxis="frequency"):
1654 1752
1655 1753 """
1656 1754
1657 1755 Input:
1658 1756 dataOut :
1659 1757 id :
1660 1758 wintitle :
1661 1759 channelList :
1662 1760 showProfile :
1663 1761 xmin : None,
1664 1762 xmax : None,
1665 1763 ymin : None,
1666 1764 ymax : None,
1667 1765 zmin : None,
1668 1766 zmax : None
1669 1767 """
1670 1768 #SEPARAR EN DOS PLOTS
1671 1769 nParam = dataOut.data_param.shape[1] - 3
1672 1770
1673 1771 utctime = dataOut.data_param[0,0]
1674 1772 tmet = dataOut.data_param[:,1].astype(int)
1675 1773 hmet = dataOut.data_param[:,2].astype(int)
1676 1774
1677 1775 x = dataOut.abscissaList
1678 1776 y = dataOut.heightList
1679 1777
1680 1778 z = numpy.zeros((nParam, y.size, x.size - 1))
1681 1779 z[:,:] = numpy.nan
1682 1780 z[:,hmet,tmet] = dataOut.data_param[:,3:].T
1683 1781 z[0,:,:] = 10*numpy.log10(z[0,:,:])
1684 1782
1685 1783 xlabel = "Time (s)"
1686 1784 ylabel = "Range (km)"
1687 1785
1688 1786 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
1689 1787
1690 1788 if not self.isConfig:
1691 1789
1692 1790 nplots = nParam
1693 1791
1694 1792 self.setup(id=id,
1695 1793 nplots=nplots,
1696 1794 wintitle=wintitle,
1697 1795 show=show)
1698 1796
1699 1797 if xmin is None: xmin = numpy.nanmin(x)
1700 1798 if xmax is None: xmax = numpy.nanmax(x)
1701 1799 if ymin is None: ymin = numpy.nanmin(y)
1702 1800 if ymax is None: ymax = numpy.nanmax(y)
1703 1801 if SNRmin is None: SNRmin = numpy.nanmin(z[0,:])
1704 1802 if SNRmax is None: SNRmax = numpy.nanmax(z[0,:])
1705 1803 if vmax is None: vmax = numpy.nanmax(numpy.abs(z[1,:]))
1706 1804 if vmin is None: vmin = -vmax
1707 1805 if wmin is None: wmin = 0
1708 1806 if wmax is None: wmax = 50
1709 1807
1710 1808 pairsList = dataOut.groupList
1711 1809 self.nPairs = len(dataOut.groupList)
1712 1810
1713 1811 zminList = [SNRmin, vmin, cmin] + [pmin]*self.nPairs
1714 1812 zmaxList = [SNRmax, vmax, cmax] + [pmax]*self.nPairs
1715 1813 titleList = ["SNR","Radial Velocity","Coherence"]
1716 1814 cmapList = ["jet","RdBu_r","jet"]
1717 1815
1718 1816 for i in range(self.nPairs):
1719 1817 strAux1 = "Phase Difference "+ str(pairsList[i][0]) + str(pairsList[i][1])
1720 1818 titleList = titleList + [strAux1]
1721 1819 cmapList = cmapList + ["RdBu_r"]
1722 1820
1723 1821 self.zminList = zminList
1724 1822 self.zmaxList = zmaxList
1725 1823 self.cmapList = cmapList
1726 1824 self.titleList = titleList
1727 1825
1728 1826 self.FTP_WEI = ftp_wei
1729 1827 self.EXP_CODE = exp_code
1730 1828 self.SUB_EXP_CODE = sub_exp_code
1731 1829 self.PLOT_POS = plot_pos
1732 1830
1733 1831 self.isConfig = True
1734 1832
1735 1833 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
1736 1834
1737 1835 for i in range(nParam):
1738 1836 title = self.titleList[i] + ": " +str_datetime
1739 1837 axes = self.axesList[i]
1740 1838 axes.pcolor(x, y, z[i,:].T,
1741 1839 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=self.zminList[i], zmax=self.zmaxList[i],
1742 1840 xlabel=xlabel, ylabel=ylabel, title=title, colormap=self.cmapList[i],ticksize=9, cblabel='')
1743 1841 self.draw()
1744 1842
1745 1843 if figfile == None:
1746 1844 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
1747 1845 name = str_datetime
1748 1846 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1749 1847 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
1750 1848 figfile = self.getFilename(name)
1751 1849
1752 1850 self.save(figpath=figpath,
1753 1851 figfile=figfile,
1754 1852 save=save,
1755 1853 ftp=ftp,
1756 1854 wr_period=wr_period,
1757 1855 thisDatetime=thisDatetime)
1758 1856
1759 1857
1760 1858 class NSMeteorDetection2Plot(Figure):
1761 1859
1762 1860 isConfig = None
1763 1861 __nsubplots = None
1764 1862
1765 1863 WIDTHPROF = None
1766 1864 HEIGHTPROF = None
1767 1865 PREFIX = 'nsm'
1768 1866
1769 1867 zminList = None
1770 1868 zmaxList = None
1771 1869 cmapList = None
1772 1870 titleList = None
1773 1871 nPairs = None
1774 1872 nChannels = None
1775 1873 nParam = None
1776 1874
1875 parameters = {
1876 'id': global_type_string,
1877 'wintitle': global_type_string,
1878 'channelList': global_type_list,
1879 'showprofile': global_type_boolean,
1880 'xmin': global_type_float,
1881 'xmax': global_type_float,
1882 'ymin': global_type_float,
1883 'ymax': global_type_float,
1884 'SNRmin': global_type_float,
1885 'SNRmax': global_type_float,
1886 'vmin': global_type_float,
1887 'vmax': global_type_float,
1888 'wmin': global_type_float,
1889 'wmax': global_type_float,
1890 'mode': global_type_string,
1891 'save': global_type_boolean,
1892 'figpath': global_type_string,
1893 'figfile': global_type_string,
1894 'show': global_type_string,
1895 'ftp': global_type_boolean,
1896 'wr_period': global_type_integer,
1897 'server': global_type_string,
1898 'folder': global_type_string,
1899 'username': global_type_string,
1900 'password': global_type_string,
1901 'ftp_wei': global_type_integer,
1902 'exp_code': global_type_integer,
1903 'sub_exp_code': global_type_integer,
1904 'plot_pos': global_type_integer,
1905 'realtime': global_type_boolean,
1906 'xaxis': global_type_string,
1907 }
1908
1777 1909 def __init__(self, **kwargs):
1778 1910 Figure.__init__(self, **kwargs)
1779 1911 self.isConfig = False
1780 1912 self.__nsubplots = 1
1781 1913
1782 1914 self.WIDTH = 750
1783 1915 self.HEIGHT = 250
1784 1916 self.WIDTHPROF = 120
1785 1917 self.HEIGHTPROF = 0
1786 1918 self.counter_imagwr = 0
1787 1919
1788 1920 self.PLOT_CODE = SPEC_CODE
1789 1921
1790 1922 self.FTP_WEI = None
1791 1923 self.EXP_CODE = None
1792 1924 self.SUB_EXP_CODE = None
1793 1925 self.PLOT_POS = None
1794 1926
1795 1927 self.__xfilter_ena = False
1796 1928 self.__yfilter_ena = False
1797 1929
1798 1930 def getSubplots(self):
1799 1931
1800 1932 ncol = 3
1801 1933 nrow = int(numpy.ceil(self.nplots/3.0))
1802 1934
1803 1935 return nrow, ncol
1804 1936
1805 1937 def setup(self, id, nplots, wintitle, show=True):
1806 1938
1807 1939 self.nplots = nplots
1808 1940
1809 1941 ncolspan = 1
1810 1942 colspan = 1
1811 1943
1812 1944 self.createFigure(id = id,
1813 1945 wintitle = wintitle,
1814 1946 widthplot = self.WIDTH + self.WIDTHPROF,
1815 1947 heightplot = self.HEIGHT + self.HEIGHTPROF,
1816 1948 show=show)
1817 1949
1818 1950 nrow, ncol = self.getSubplots()
1819 1951
1820 1952 counter = 0
1821 1953 for y in range(nrow):
1822 1954 for x in range(ncol):
1823 1955
1824 1956 if counter >= self.nplots:
1825 1957 break
1826 1958
1827 1959 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1828 1960
1829 1961 counter += 1
1830 1962
1831 1963 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
1832 1964 xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None,
1833 1965 vmin=None, vmax=None, wmin=None, wmax=None, mode = 'SA',
1834 1966 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1835 1967 server=None, folder=None, username=None, password=None,
1836 1968 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
1837 1969 xaxis="frequency"):
1838 1970
1839 1971 """
1840 1972
1841 1973 Input:
1842 1974 dataOut :
1843 1975 id :
1844 1976 wintitle :
1845 1977 channelList :
1846 1978 showProfile :
1847 1979 xmin : None,
1848 1980 xmax : None,
1849 1981 ymin : None,
1850 1982 ymax : None,
1851 1983 zmin : None,
1852 1984 zmax : None
1853 1985 """
1854 1986 #Rebuild matrix
1855 1987 utctime = dataOut.data_param[0,0]
1856 1988 cmet = dataOut.data_param[:,1].astype(int)
1857 1989 tmet = dataOut.data_param[:,2].astype(int)
1858 1990 hmet = dataOut.data_param[:,3].astype(int)
1859 1991
1860 1992 nParam = 3
1861 1993 nChan = len(dataOut.groupList)
1862 1994 x = dataOut.abscissaList
1863 1995 y = dataOut.heightList
1864 1996
1865 1997 z = numpy.full((nChan, nParam, y.size, x.size - 1),numpy.nan)
1866 1998 z[cmet,:,hmet,tmet] = dataOut.data_param[:,4:]
1867 1999 z[:,0,:,:] = 10*numpy.log10(z[:,0,:,:]) #logarithmic scale
1868 2000 z = numpy.reshape(z, (nChan*nParam, y.size, x.size-1))
1869 2001
1870 2002 xlabel = "Time (s)"
1871 2003 ylabel = "Range (km)"
1872 2004
1873 2005 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
1874 2006
1875 2007 if not self.isConfig:
1876 2008
1877 2009 nplots = nParam*nChan
1878 2010
1879 2011 self.setup(id=id,
1880 2012 nplots=nplots,
1881 2013 wintitle=wintitle,
1882 2014 show=show)
1883 2015
1884 2016 if xmin is None: xmin = numpy.nanmin(x)
1885 2017 if xmax is None: xmax = numpy.nanmax(x)
1886 2018 if ymin is None: ymin = numpy.nanmin(y)
1887 2019 if ymax is None: ymax = numpy.nanmax(y)
1888 2020 if SNRmin is None: SNRmin = numpy.nanmin(z[0,:])
1889 2021 if SNRmax is None: SNRmax = numpy.nanmax(z[0,:])
1890 2022 if vmax is None: vmax = numpy.nanmax(numpy.abs(z[1,:]))
1891 2023 if vmin is None: vmin = -vmax
1892 2024 if wmin is None: wmin = 0
1893 2025 if wmax is None: wmax = 50
1894 2026
1895 2027 self.nChannels = nChan
1896 2028
1897 2029 zminList = []
1898 2030 zmaxList = []
1899 2031 titleList = []
1900 2032 cmapList = []
1901 2033 for i in range(self.nChannels):
1902 2034 strAux1 = "SNR Channel "+ str(i)
1903 2035 strAux2 = "Radial Velocity Channel "+ str(i)
1904 2036 strAux3 = "Spectral Width Channel "+ str(i)
1905 2037
1906 2038 titleList = titleList + [strAux1,strAux2,strAux3]
1907 2039 cmapList = cmapList + ["jet","RdBu_r","jet"]
1908 2040 zminList = zminList + [SNRmin,vmin,wmin]
1909 2041 zmaxList = zmaxList + [SNRmax,vmax,wmax]
1910 2042
1911 2043 self.zminList = zminList
1912 2044 self.zmaxList = zmaxList
1913 2045 self.cmapList = cmapList
1914 2046 self.titleList = titleList
1915 2047
1916 2048 self.FTP_WEI = ftp_wei
1917 2049 self.EXP_CODE = exp_code
1918 2050 self.SUB_EXP_CODE = sub_exp_code
1919 2051 self.PLOT_POS = plot_pos
1920 2052
1921 2053 self.isConfig = True
1922 2054
1923 2055 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
1924 2056
1925 2057 for i in range(self.nplots):
1926 2058 title = self.titleList[i] + ": " +str_datetime
1927 2059 axes = self.axesList[i]
1928 2060 axes.pcolor(x, y, z[i,:].T,
1929 2061 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=self.zminList[i], zmax=self.zmaxList[i],
1930 2062 xlabel=xlabel, ylabel=ylabel, title=title, colormap=self.cmapList[i],ticksize=9, cblabel='')
1931 2063 self.draw()
1932 2064
1933 2065 if figfile == None:
1934 2066 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
1935 2067 name = str_datetime
1936 2068 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1937 2069 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
1938 2070 figfile = self.getFilename(name)
1939 2071
1940 2072 self.save(figpath=figpath,
1941 2073 figfile=figfile,
1942 2074 save=save,
1943 2075 ftp=ftp,
1944 2076 wr_period=wr_period,
1945 2077 thisDatetime=thisDatetime)
@@ -1,1595 +1,1655
1 1 '''
2 2 Created on Jul 9, 2014
3 3
4 4 @author: roj-idl71
5 5 '''
6 6 import os
7 7 import datetime
8 8 import numpy
9 9
10 10 from figure import Figure, isRealtime, isTimeInHourRange
11 11 from plotting_codes import *
12 12
13 13
14 14 class SpectraPlot(Figure):
15 15
16 16 isConfig = None
17 17 __nsubplots = None
18 18
19 19 WIDTHPROF = None
20 20 HEIGHTPROF = None
21 21 PREFIX = 'spc'
22 22
23 23 def __init__(self, **kwargs):
24 24 Figure.__init__(self, **kwargs)
25 25 self.isConfig = False
26 26 self.__nsubplots = 1
27 27
28 28 self.WIDTH = 250
29 29 self.HEIGHT = 250
30 30 self.WIDTHPROF = 120
31 31 self.HEIGHTPROF = 0
32 32 self.counter_imagwr = 0
33 33
34 34 self.PLOT_CODE = SPEC_CODE
35 35
36 36 self.FTP_WEI = None
37 37 self.EXP_CODE = None
38 38 self.SUB_EXP_CODE = None
39 39 self.PLOT_POS = None
40 40
41 41 self.__xfilter_ena = False
42 42 self.__yfilter_ena = False
43 43
44 44 def getSubplots(self):
45 45
46 46 ncol = int(numpy.sqrt(self.nplots)+0.9)
47 47 nrow = int(self.nplots*1./ncol + 0.9)
48 48
49 49 return nrow, ncol
50 50
51 51 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
52 52
53 53 self.__showprofile = showprofile
54 54 self.nplots = nplots
55 55
56 56 ncolspan = 1
57 57 colspan = 1
58 58 if showprofile:
59 59 ncolspan = 3
60 60 colspan = 2
61 61 self.__nsubplots = 2
62 62
63 63 self.createFigure(id = id,
64 64 wintitle = wintitle,
65 65 widthplot = self.WIDTH + self.WIDTHPROF,
66 66 heightplot = self.HEIGHT + self.HEIGHTPROF,
67 67 show=show)
68 68
69 69 nrow, ncol = self.getSubplots()
70 70
71 71 counter = 0
72 72 for y in range(nrow):
73 73 for x in range(ncol):
74 74
75 75 if counter >= self.nplots:
76 76 break
77 77
78 78 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
79 79
80 80 if showprofile:
81 81 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
82 82
83 83 counter += 1
84 84
85 85 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
86 86 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
87 87 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
88 88 server=None, folder=None, username=None, password=None,
89 89 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
90 90 xaxis="velocity", **kwargs):
91 91
92 92 """
93 93
94 94 Input:
95 95 dataOut :
96 96 id :
97 97 wintitle :
98 98 channelList :
99 99 showProfile :
100 100 xmin : None,
101 101 xmax : None,
102 102 ymin : None,
103 103 ymax : None,
104 104 zmin : None,
105 105 zmax : None
106 106 """
107 107
108 108 colormap = kwargs.get('colormap','jet')
109 109
110 110 if realtime:
111 111 if not(isRealtime(utcdatatime = dataOut.utctime)):
112 112 print 'Skipping this plot function'
113 113 return
114 114
115 115 if channelList == None:
116 116 channelIndexList = dataOut.channelIndexList
117 117 else:
118 118 channelIndexList = []
119 119 for channel in channelList:
120 120 if channel not in dataOut.channelList:
121 121 raise ValueError, "Channel %d is not in dataOut.channelList" %channel
122 122 channelIndexList.append(dataOut.channelList.index(channel))
123 123
124 124 factor = dataOut.normFactor
125 125
126 126 if xaxis == "frequency":
127 127 x = dataOut.getFreqRange(1)/1000.
128 128 xlabel = "Frequency (kHz)"
129 129
130 130 elif xaxis == "time":
131 131 x = dataOut.getAcfRange(1)
132 132 xlabel = "Time (ms)"
133 133
134 134 else:
135 135 x = dataOut.getVelRange(1)
136 136 xlabel = "Velocity (m/s)"
137 137
138 138 ylabel = "Range (Km)"
139 139
140 140 y = dataOut.getHeiRange()
141 141
142 142 z = dataOut.data_spc/factor
143 143 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
144 144 zdB = 10*numpy.log10(z)
145 145
146 146 avg = numpy.average(z, axis=1)
147 147 avgdB = 10*numpy.log10(avg)
148 148
149 149 noise = dataOut.getNoise()/factor
150 150 noisedB = 10*numpy.log10(noise)
151 151
152 152 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
153 153 title = wintitle + " Spectra"
154 154 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
155 155 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
156 156
157 157 if not self.isConfig:
158 158
159 159 nplots = len(channelIndexList)
160 160
161 161 self.setup(id=id,
162 162 nplots=nplots,
163 163 wintitle=wintitle,
164 164 showprofile=showprofile,
165 165 show=show)
166 166
167 167 if xmin == None: xmin = numpy.nanmin(x)
168 168 if xmax == None: xmax = numpy.nanmax(x)
169 169 if ymin == None: ymin = numpy.nanmin(y)
170 170 if ymax == None: ymax = numpy.nanmax(y)
171 171 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
172 172 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
173 173
174 174 self.FTP_WEI = ftp_wei
175 175 self.EXP_CODE = exp_code
176 176 self.SUB_EXP_CODE = sub_exp_code
177 177 self.PLOT_POS = plot_pos
178 178
179 179 self.isConfig = True
180 180
181 181 self.setWinTitle(title)
182 182
183 183 for i in range(self.nplots):
184 184 index = channelIndexList[i]
185 185 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
186 186 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[index], noisedB[index], str_datetime)
187 187 if len(dataOut.beam.codeList) != 0:
188 188 title = "Ch%d:%4.2fdB,%2.2f,%2.2f:%s" %(dataOut.channelList[index], noisedB[index], dataOut.beam.azimuthList[index], dataOut.beam.zenithList[index], str_datetime)
189 189
190 190 axes = self.axesList[i*self.__nsubplots]
191 191 axes.pcolor(x, y, zdB[index,:,:],
192 192 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
193 193 xlabel=xlabel, ylabel=ylabel, title=title, colormap=colormap,
194 194 ticksize=9, cblabel='')
195 195
196 196 if self.__showprofile:
197 197 axes = self.axesList[i*self.__nsubplots +1]
198 198 axes.pline(avgdB[index,:], y,
199 199 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
200 200 xlabel='dB', ylabel='', title='',
201 201 ytick_visible=False,
202 202 grid='x')
203 203
204 204 noiseline = numpy.repeat(noisedB[index], len(y))
205 205 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
206 206
207 207 self.draw()
208 208
209 209 if figfile == None:
210 210 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
211 211 name = str_datetime
212 212 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
213 213 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
214 214 figfile = self.getFilename(name)
215 215
216 216 self.save(figpath=figpath,
217 217 figfile=figfile,
218 218 save=save,
219 219 ftp=ftp,
220 220 wr_period=wr_period,
221 221 thisDatetime=thisDatetime)
222 222
223 223 class CrossSpectraPlot(Figure):
224 224
225 225 isConfig = None
226 226 __nsubplots = None
227 227
228 228 WIDTH = None
229 229 HEIGHT = None
230 230 WIDTHPROF = None
231 231 HEIGHTPROF = None
232 232 PREFIX = 'cspc'
233 233
234 parameters = {
235 'id': global_type_string,
236 'wintitle': global_type_string,
237 'pairsList': global_type_pairsList,
238 'xmin': global_type_float,
239 'xmax': global_type_float,
240 'ymin': global_type_float,
241 'ymax': global_type_float,
242 'zmin': global_type_float,
243 'zmax': global_type_float,
244 'coh_min': global_type_float,
245 'coh_max': global_type_float,
246 'phase_min': global_type_float,
247 'phase_max': global_type_float,
248 'save': global_type_boolean,
249 'figpath': global_type_string,
250 'figfile': global_type_string,
251 'ftp': global_type_boolean,
252 'wr_period': global_type_integer,
253 'power_cmap': global_type_colormap,
254 'coherence_cmap': global_type_colormap,
255 'phase_cmap': global_type_colormap,
256 'show': global_type_boolean,
257 'server': global_type_string,
258 'folder': global_type_string,
259 'username': global_type_string,
260 'password': global_type_string,
261 'ftp_wei': global_type_integer,
262 'exp_code': global_type_integer,
263 'sub_exp_code': global_type_integer,
264 'plot_pos': global_type_integer,
265 'xaxis': global_type_string,
266 }
267
234 268 def __init__(self, **kwargs):
235 269 Figure.__init__(self, **kwargs)
236 270 self.isConfig = False
237 271 self.__nsubplots = 4
238 272 self.counter_imagwr = 0
239 273 self.WIDTH = 250
240 274 self.HEIGHT = 250
241 275 self.WIDTHPROF = 0
242 276 self.HEIGHTPROF = 0
243 277
244 278 self.PLOT_CODE = CROSS_CODE
245 279 self.FTP_WEI = None
246 280 self.EXP_CODE = None
247 281 self.SUB_EXP_CODE = None
248 282 self.PLOT_POS = None
249 283
250 284 def getSubplots(self):
251 285
252 286 ncol = 4
253 287 nrow = self.nplots
254 288
255 289 return nrow, ncol
256 290
257 291 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
258 292
259 293 self.__showprofile = showprofile
260 294 self.nplots = nplots
261 295
262 296 ncolspan = 1
263 297 colspan = 1
264 298
265 299 self.createFigure(id = id,
266 300 wintitle = wintitle,
267 301 widthplot = self.WIDTH + self.WIDTHPROF,
268 302 heightplot = self.HEIGHT + self.HEIGHTPROF,
269 303 show=True)
270 304
271 305 nrow, ncol = self.getSubplots()
272 306
273 307 counter = 0
274 308 for y in range(nrow):
275 309 for x in range(ncol):
276 310 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
277 311
278 312 counter += 1
279 313
280 314 def run(self, dataOut, id, wintitle="", pairsList=None,
281 315 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
282 316 coh_min=None, coh_max=None, phase_min=None, phase_max=None,
283 317 save=False, figpath='./', figfile=None, ftp=False, wr_period=1,
284 318 power_cmap='jet', coherence_cmap='jet', phase_cmap='RdBu_r', show=True,
285 319 server=None, folder=None, username=None, password=None,
286 320 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0,
287 321 xaxis='frequency'):
288 322
289 323 """
290 324
291 325 Input:
292 326 dataOut :
293 327 id :
294 328 wintitle :
295 329 channelList :
296 330 showProfile :
297 331 xmin : None,
298 332 xmax : None,
299 333 ymin : None,
300 334 ymax : None,
301 335 zmin : None,
302 336 zmax : None
303 337 """
304 338
305 339 if pairsList == None:
306 340 pairsIndexList = dataOut.pairsIndexList
307 341 else:
308 342 pairsIndexList = []
309 343 for pair in pairsList:
310 344 if pair not in dataOut.pairsList:
311 345 raise ValueError, "Pair %s is not in dataOut.pairsList" %str(pair)
312 346 pairsIndexList.append(dataOut.pairsList.index(pair))
313 347
314 348 if not pairsIndexList:
315 349 return
316 350
317 351 if len(pairsIndexList) > 4:
318 352 pairsIndexList = pairsIndexList[0:4]
319 353
320 354 factor = dataOut.normFactor
321 355 x = dataOut.getVelRange(1)
322 356 y = dataOut.getHeiRange()
323 357 z = dataOut.data_spc[:,:,:]/factor
324 358 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
325 359
326 360 noise = dataOut.noise/factor
327 361
328 362 zdB = 10*numpy.log10(z)
329 363 noisedB = 10*numpy.log10(noise)
330 364
331 365 if coh_min == None:
332 366 coh_min = 0.0
333 367 if coh_max == None:
334 368 coh_max = 1.0
335 369
336 370 if phase_min == None:
337 371 phase_min = -180
338 372 if phase_max == None:
339 373 phase_max = 180
340 374
341 375 #thisDatetime = dataOut.datatime
342 376 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
343 377 title = wintitle + " Cross-Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
344 378 # xlabel = "Velocity (m/s)"
345 379 ylabel = "Range (Km)"
346 380
347 381 if xaxis == "frequency":
348 382 x = dataOut.getFreqRange(1)/1000.
349 383 xlabel = "Frequency (kHz)"
350 384
351 385 elif xaxis == "time":
352 386 x = dataOut.getAcfRange(1)
353 387 xlabel = "Time (ms)"
354 388
355 389 else:
356 390 x = dataOut.getVelRange(1)
357 391 xlabel = "Velocity (m/s)"
358 392
359 393 if not self.isConfig:
360 394
361 395 nplots = len(pairsIndexList)
362 396
363 397 self.setup(id=id,
364 398 nplots=nplots,
365 399 wintitle=wintitle,
366 400 showprofile=False,
367 401 show=show)
368 402
369 403 avg = numpy.abs(numpy.average(z, axis=1))
370 404 avgdB = 10*numpy.log10(avg)
371 405
372 406 if xmin == None: xmin = numpy.nanmin(x)
373 407 if xmax == None: xmax = numpy.nanmax(x)
374 408 if ymin == None: ymin = numpy.nanmin(y)
375 409 if ymax == None: ymax = numpy.nanmax(y)
376 410 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
377 411 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
378 412
379 413 self.FTP_WEI = ftp_wei
380 414 self.EXP_CODE = exp_code
381 415 self.SUB_EXP_CODE = sub_exp_code
382 416 self.PLOT_POS = plot_pos
383 417
384 418 self.isConfig = True
385 419
386 420 self.setWinTitle(title)
387 421
388 422 for i in range(self.nplots):
389 423 pair = dataOut.pairsList[pairsIndexList[i]]
390 424
391 425 chan_index0 = dataOut.channelList.index(pair[0])
392 426 chan_index1 = dataOut.channelList.index(pair[1])
393 427
394 428 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
395 429 title = "Ch%d: %4.2fdB: %s" %(pair[0], noisedB[chan_index0], str_datetime)
396 430 zdB = 10.*numpy.log10(dataOut.data_spc[chan_index0,:,:]/factor)
397 431 axes0 = self.axesList[i*self.__nsubplots]
398 432 axes0.pcolor(x, y, zdB,
399 433 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
400 434 xlabel=xlabel, ylabel=ylabel, title=title,
401 435 ticksize=9, colormap=power_cmap, cblabel='')
402 436
403 437 title = "Ch%d: %4.2fdB: %s" %(pair[1], noisedB[chan_index1], str_datetime)
404 438 zdB = 10.*numpy.log10(dataOut.data_spc[chan_index1,:,:]/factor)
405 439 axes0 = self.axesList[i*self.__nsubplots+1]
406 440 axes0.pcolor(x, y, zdB,
407 441 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
408 442 xlabel=xlabel, ylabel=ylabel, title=title,
409 443 ticksize=9, colormap=power_cmap, cblabel='')
410 444
411 445 coherenceComplex = dataOut.data_cspc[pairsIndexList[i],:,:]/numpy.sqrt(dataOut.data_spc[chan_index0,:,:]*dataOut.data_spc[chan_index1,:,:])
412 446 coherence = numpy.abs(coherenceComplex)
413 447 # phase = numpy.arctan(-1*coherenceComplex.imag/coherenceComplex.real)*180/numpy.pi
414 448 phase = numpy.arctan2(coherenceComplex.imag, coherenceComplex.real)*180/numpy.pi
415 449
416 450 title = "Coherence Ch%d * Ch%d" %(pair[0], pair[1])
417 451 axes0 = self.axesList[i*self.__nsubplots+2]
418 452 axes0.pcolor(x, y, coherence,
419 453 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=coh_min, zmax=coh_max,
420 454 xlabel=xlabel, ylabel=ylabel, title=title,
421 455 ticksize=9, colormap=coherence_cmap, cblabel='')
422 456
423 457 title = "Phase Ch%d * Ch%d" %(pair[0], pair[1])
424 458 axes0 = self.axesList[i*self.__nsubplots+3]
425 459 axes0.pcolor(x, y, phase,
426 460 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=phase_min, zmax=phase_max,
427 461 xlabel=xlabel, ylabel=ylabel, title=title,
428 462 ticksize=9, colormap=phase_cmap, cblabel='')
429 463
430 464
431 465
432 466 self.draw()
433 467
434 468 self.save(figpath=figpath,
435 469 figfile=figfile,
436 470 save=save,
437 471 ftp=ftp,
438 472 wr_period=wr_period,
439 473 thisDatetime=thisDatetime)
440 474
441 475
442 476 class RTIPlot(Figure):
443 477
444 478 __isConfig = None
445 479 __nsubplots = None
446 480
447 481 WIDTHPROF = None
448 482 HEIGHTPROF = None
449 483 PREFIX = 'rti'
450 484
451 485 def __init__(self, **kwargs):
452 486
453 487 Figure.__init__(self, **kwargs)
454 488 self.timerange = None
455 489 self.isConfig = False
456 490 self.__nsubplots = 1
457 491
458 492 self.WIDTH = 800
459 493 self.HEIGHT = 180
460 494 self.WIDTHPROF = 120
461 495 self.HEIGHTPROF = 0
462 496 self.counter_imagwr = 0
463 497
464 498 self.PLOT_CODE = RTI_CODE
465 499
466 500 self.FTP_WEI = None
467 501 self.EXP_CODE = None
468 502 self.SUB_EXP_CODE = None
469 503 self.PLOT_POS = None
470 504 self.tmin = None
471 505 self.tmax = None
472 506
473 507 self.xmin = None
474 508 self.xmax = None
475 509
476 510 self.figfile = None
477 511
478 512 def getSubplots(self):
479 513
480 514 ncol = 1
481 515 nrow = self.nplots
482 516
483 517 return nrow, ncol
484 518
485 519 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
486 520
487 521 self.__showprofile = showprofile
488 522 self.nplots = nplots
489 523
490 524 ncolspan = 1
491 525 colspan = 1
492 526 if showprofile:
493 527 ncolspan = 7
494 528 colspan = 6
495 529 self.__nsubplots = 2
496 530
497 531 self.createFigure(id = id,
498 532 wintitle = wintitle,
499 533 widthplot = self.WIDTH + self.WIDTHPROF,
500 534 heightplot = self.HEIGHT + self.HEIGHTPROF,
501 535 show=show)
502 536
503 537 nrow, ncol = self.getSubplots()
504 538
505 539 counter = 0
506 540 for y in range(nrow):
507 541 for x in range(ncol):
508 542
509 543 if counter >= self.nplots:
510 544 break
511 545
512 546 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
513 547
514 548 if showprofile:
515 549 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
516 550
517 551 counter += 1
518 552
519 553 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='True',
520 554 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
521 555 timerange=None,
522 556 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
523 557 server=None, folder=None, username=None, password=None,
524 558 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, **kwargs):
525 559
526 560 """
527 561
528 562 Input:
529 563 dataOut :
530 564 id :
531 565 wintitle :
532 566 channelList :
533 567 showProfile :
534 568 xmin : None,
535 569 xmax : None,
536 570 ymin : None,
537 571 ymax : None,
538 572 zmin : None,
539 573 zmax : None
540 574 """
541 575
542 576 colormap = kwargs.get('colormap', 'jet')
543 577 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
544 578 return
545 579
546 580 if channelList == None:
547 581 channelIndexList = dataOut.channelIndexList
548 582 else:
549 583 channelIndexList = []
550 584 for channel in channelList:
551 585 if channel not in dataOut.channelList:
552 586 raise ValueError, "Channel %d is not in dataOut.channelList"
553 587 channelIndexList.append(dataOut.channelList.index(channel))
554 588
555 589 if hasattr(dataOut, 'normFactor'):
556 590 factor = dataOut.normFactor
557 591 else:
558 592 factor = 1
559 593
560 594 # factor = dataOut.normFactor
561 595 x = dataOut.getTimeRange()
562 596 y = dataOut.getHeiRange()
563 597
564 598 # z = dataOut.data_spc/factor
565 599 # z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
566 600 # avg = numpy.average(z, axis=1)
567 601 # avgdB = 10.*numpy.log10(avg)
568 602 avgdB = dataOut.getPower()
569 603
570 604 thisDatetime = dataOut.datatime
571 605 # thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
572 606 title = wintitle + " RTI" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
573 607 xlabel = ""
574 608 ylabel = "Range (Km)"
575 609
576 610 update_figfile = False
577 611
578 612 if dataOut.ltctime >= self.xmax:
579 613 self.counter_imagwr = wr_period
580 614 self.isConfig = False
581 615 update_figfile = True
582 616
583 617 if not self.isConfig:
584 618
585 619 nplots = len(channelIndexList)
586 620
587 621 self.setup(id=id,
588 622 nplots=nplots,
589 623 wintitle=wintitle,
590 624 showprofile=showprofile,
591 625 show=show)
592 626
593 627 if timerange != None:
594 628 self.timerange = timerange
595 629
596 630 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
597 631
598 632 noise = dataOut.noise/factor
599 633 noisedB = 10*numpy.log10(noise)
600 634
601 635 if ymin == None: ymin = numpy.nanmin(y)
602 636 if ymax == None: ymax = numpy.nanmax(y)
603 637 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
604 638 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
605 639
606 640 self.FTP_WEI = ftp_wei
607 641 self.EXP_CODE = exp_code
608 642 self.SUB_EXP_CODE = sub_exp_code
609 643 self.PLOT_POS = plot_pos
610 644
611 645 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
612 646 self.isConfig = True
613 647 self.figfile = figfile
614 648 update_figfile = True
615 649
616 650 self.setWinTitle(title)
617 651
618 652 for i in range(self.nplots):
619 653 index = channelIndexList[i]
620 654 title = "Channel %d: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
621 655 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
622 656 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
623 657 axes = self.axesList[i*self.__nsubplots]
624 658 zdB = avgdB[index].reshape((1,-1))
625 659 axes.pcolorbuffer(x, y, zdB,
626 660 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
627 661 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
628 662 ticksize=9, cblabel='', cbsize="1%", colormap=colormap)
629 663
630 664 if self.__showprofile:
631 665 axes = self.axesList[i*self.__nsubplots +1]
632 666 axes.pline(avgdB[index], y,
633 667 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
634 668 xlabel='dB', ylabel='', title='',
635 669 ytick_visible=False,
636 670 grid='x')
637 671
638 672 self.draw()
639 673
640 674 self.save(figpath=figpath,
641 675 figfile=figfile,
642 676 save=save,
643 677 ftp=ftp,
644 678 wr_period=wr_period,
645 679 thisDatetime=thisDatetime,
646 680 update_figfile=update_figfile)
647 681
648 682 class CoherenceMap(Figure):
649 683 isConfig = None
650 684 __nsubplots = None
651 685
652 686 WIDTHPROF = None
653 687 HEIGHTPROF = None
654 688 PREFIX = 'cmap'
655 689
656 690 parameters = {
657 691 'id': 'string',
658 692 'wintitle': 'string',
659 693 'pairsList': 'pairsLists',
660 694 'showprofile': 'boolean',
661 695 'xmin': 'float',
662 696 'xmax': 'float',
663 697 'ymin': 'float',
664 698 'ymax': 'float',
665 699 'zmin': 'float',
666 700 'zmax': 'float',
667 701 'timerange': 'float',
668 702 'phase_min': 'float',
669 703 'phase_max': 'float',
670 704 'save': 'boolean',
671 705 'figpath': 'string',
672 706 'figfile': 'string',
673 707 'ftp': 'boolean',
674 708 'wr_period': 'int',
675 709 'coherence_cmap': 'colormap',
676 710 'phase_cmap': 'colormap',
677 711 'show': 'boolean',
678 712 'server': 'string',
679 713 'folder': 'string',
680 714 'username': 'string',
681 715 'password': 'string',
682 716 'ftp_wei': 'int',
683 717 'exp_code': 'int',
684 718 'sub_exp_code': 'int',
685 719 'plot_pos': 'int',
686 720 }
687 721
688 722 def __init__(self, **kwargs):
689 723 Figure.__init__(self, **kwargs)
690 724 self.timerange = 2*60*60
691 725 self.isConfig = False
692 726 self.__nsubplots = 1
693 727
694 728 self.WIDTH = 800
695 729 self.HEIGHT = 180
696 730 self.WIDTHPROF = 120
697 731 self.HEIGHTPROF = 0
698 732 self.counter_imagwr = 0
699 733
700 734 self.PLOT_CODE = COH_CODE
701 735
702 736 self.FTP_WEI = None
703 737 self.EXP_CODE = None
704 738 self.SUB_EXP_CODE = None
705 739 self.PLOT_POS = None
706 740 self.counter_imagwr = 0
707 741
708 742 self.xmin = None
709 743 self.xmax = None
710 744
711 745 def getSubplots(self):
712 746 ncol = 1
713 747 nrow = self.nplots*2
714 748
715 749 return nrow, ncol
716 750
717 751 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
718 752 self.__showprofile = showprofile
719 753 self.nplots = nplots
720 754
721 755 ncolspan = 1
722 756 colspan = 1
723 757 if showprofile:
724 758 ncolspan = 7
725 759 colspan = 6
726 760 self.__nsubplots = 2
727 761
728 762 self.createFigure(id = id,
729 763 wintitle = wintitle,
730 764 widthplot = self.WIDTH + self.WIDTHPROF,
731 765 heightplot = self.HEIGHT + self.HEIGHTPROF,
732 766 show=True)
733 767
734 768 nrow, ncol = self.getSubplots()
735 769
736 770 for y in range(nrow):
737 771 for x in range(ncol):
738 772
739 773 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
740 774
741 775 if showprofile:
742 776 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
743 777
744 778 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
745 779 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
746 780 timerange=None, phase_min=None, phase_max=None,
747 781 save=False, figpath='./', figfile=None, ftp=False, wr_period=1,
748 782 coherence_cmap='jet', phase_cmap='RdBu_r', show=True,
749 783 server=None, folder=None, username=None, password=None,
750 784 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
751 785
752 786 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
753 787 return
754 788
755 789 if pairsList == None:
756 790 pairsIndexList = dataOut.pairsIndexList
757 791 else:
758 792 pairsIndexList = []
759 793 for pair in pairsList:
760 794 if pair not in dataOut.pairsList:
761 795 raise ValueError, "Pair %s is not in dataOut.pairsList" %(pair)
762 796 pairsIndexList.append(dataOut.pairsList.index(pair))
763 797
764 798 if pairsIndexList == []:
765 799 return
766 800
767 801 if len(pairsIndexList) > 4:
768 802 pairsIndexList = pairsIndexList[0:4]
769 803
770 804 if phase_min == None:
771 805 phase_min = -180
772 806 if phase_max == None:
773 807 phase_max = 180
774 808
775 809 x = dataOut.getTimeRange()
776 810 y = dataOut.getHeiRange()
777 811
778 812 thisDatetime = dataOut.datatime
779 813
780 814 title = wintitle + " CoherenceMap" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
781 815 xlabel = ""
782 816 ylabel = "Range (Km)"
783 817 update_figfile = False
784 818
785 819 if not self.isConfig:
786 820 nplots = len(pairsIndexList)
787 821 self.setup(id=id,
788 822 nplots=nplots,
789 823 wintitle=wintitle,
790 824 showprofile=showprofile,
791 825 show=show)
792 826
793 827 if timerange != None:
794 828 self.timerange = timerange
795 829
796 830 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
797 831
798 832 if ymin == None: ymin = numpy.nanmin(y)
799 833 if ymax == None: ymax = numpy.nanmax(y)
800 834 if zmin == None: zmin = 0.
801 835 if zmax == None: zmax = 1.
802 836
803 837 self.FTP_WEI = ftp_wei
804 838 self.EXP_CODE = exp_code
805 839 self.SUB_EXP_CODE = sub_exp_code
806 840 self.PLOT_POS = plot_pos
807 841
808 842 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
809 843
810 844 self.isConfig = True
811 845 update_figfile = True
812 846
813 847 self.setWinTitle(title)
814 848
815 849 for i in range(self.nplots):
816 850
817 851 pair = dataOut.pairsList[pairsIndexList[i]]
818 852
819 853 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i],:,:],axis=0)
820 854 powa = numpy.average(dataOut.data_spc[pair[0],:,:],axis=0)
821 855 powb = numpy.average(dataOut.data_spc[pair[1],:,:],axis=0)
822 856
823 857
824 858 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
825 859 coherence = numpy.abs(avgcoherenceComplex)
826 860
827 861 z = coherence.reshape((1,-1))
828 862
829 863 counter = 0
830 864
831 865 title = "Coherence Ch%d * Ch%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
832 866 axes = self.axesList[i*self.__nsubplots*2]
833 867 axes.pcolorbuffer(x, y, z,
834 868 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
835 869 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
836 870 ticksize=9, cblabel='', colormap=coherence_cmap, cbsize="1%")
837 871
838 872 if self.__showprofile:
839 873 counter += 1
840 874 axes = self.axesList[i*self.__nsubplots*2 + counter]
841 875 axes.pline(coherence, y,
842 876 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
843 877 xlabel='', ylabel='', title='', ticksize=7,
844 878 ytick_visible=False, nxticks=5,
845 879 grid='x')
846 880
847 881 counter += 1
848 882
849 883 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
850 884
851 885 z = phase.reshape((1,-1))
852 886
853 887 title = "Phase Ch%d * Ch%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
854 888 axes = self.axesList[i*self.__nsubplots*2 + counter]
855 889 axes.pcolorbuffer(x, y, z,
856 890 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=phase_min, zmax=phase_max,
857 891 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
858 892 ticksize=9, cblabel='', colormap=phase_cmap, cbsize="1%")
859 893
860 894 if self.__showprofile:
861 895 counter += 1
862 896 axes = self.axesList[i*self.__nsubplots*2 + counter]
863 897 axes.pline(phase, y,
864 898 xmin=phase_min, xmax=phase_max, ymin=ymin, ymax=ymax,
865 899 xlabel='', ylabel='', title='', ticksize=7,
866 900 ytick_visible=False, nxticks=4,
867 901 grid='x')
868 902
869 903 self.draw()
870 904
871 905 if dataOut.ltctime >= self.xmax:
872 906 self.counter_imagwr = wr_period
873 907 self.isConfig = False
874 908 update_figfile = True
875 909
876 910 self.save(figpath=figpath,
877 911 figfile=figfile,
878 912 save=save,
879 913 ftp=ftp,
880 914 wr_period=wr_period,
881 915 thisDatetime=thisDatetime,
882 916 update_figfile=update_figfile)
883 917
884 918 class PowerProfilePlot(Figure):
885 919
886 920 isConfig = None
887 921 __nsubplots = None
888 922
889 923 WIDTHPROF = None
890 924 HEIGHTPROF = None
891 925 PREFIX = 'spcprofile'
892 926
893 927 def __init__(self, **kwargs):
894 928 Figure.__init__(self, **kwargs)
895 929 self.isConfig = False
896 930 self.__nsubplots = 1
897 931
898 932 self.PLOT_CODE = POWER_CODE
899 933
900 934 self.WIDTH = 300
901 935 self.HEIGHT = 500
902 936 self.counter_imagwr = 0
903 937
904 938 def getSubplots(self):
905 939 ncol = 1
906 940 nrow = 1
907 941
908 942 return nrow, ncol
909 943
910 944 def setup(self, id, nplots, wintitle, show):
911 945
912 946 self.nplots = nplots
913 947
914 948 ncolspan = 1
915 949 colspan = 1
916 950
917 951 self.createFigure(id = id,
918 952 wintitle = wintitle,
919 953 widthplot = self.WIDTH,
920 954 heightplot = self.HEIGHT,
921 955 show=show)
922 956
923 957 nrow, ncol = self.getSubplots()
924 958
925 959 counter = 0
926 960 for y in range(nrow):
927 961 for x in range(ncol):
928 962 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
929 963
930 964 def run(self, dataOut, id, wintitle="", channelList=None,
931 965 xmin=None, xmax=None, ymin=None, ymax=None,
932 966 save=False, figpath='./', figfile=None, show=True,
933 967 ftp=False, wr_period=1, server=None,
934 968 folder=None, username=None, password=None):
935 969
936 970
937 971 if channelList == None:
938 972 channelIndexList = dataOut.channelIndexList
939 973 channelList = dataOut.channelList
940 974 else:
941 975 channelIndexList = []
942 976 for channel in channelList:
943 977 if channel not in dataOut.channelList:
944 978 raise ValueError, "Channel %d is not in dataOut.channelList"
945 979 channelIndexList.append(dataOut.channelList.index(channel))
946 980
947 981 factor = dataOut.normFactor
948 982
949 983 y = dataOut.getHeiRange()
950 984
951 985 #for voltage
952 986 if dataOut.type == 'Voltage':
953 987 x = dataOut.data[channelIndexList,:] * numpy.conjugate(dataOut.data[channelIndexList,:])
954 988 x = x.real
955 989 x = numpy.where(numpy.isfinite(x), x, numpy.NAN)
956 990
957 991 #for spectra
958 992 if dataOut.type == 'Spectra':
959 993 x = dataOut.data_spc[channelIndexList,:,:]/factor
960 994 x = numpy.where(numpy.isfinite(x), x, numpy.NAN)
961 995 x = numpy.average(x, axis=1)
962 996
963 997
964 998 xdB = 10*numpy.log10(x)
965 999
966 1000 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
967 1001 title = wintitle + " Power Profile %s" %(thisDatetime.strftime("%d-%b-%Y"))
968 1002 xlabel = "dB"
969 1003 ylabel = "Range (Km)"
970 1004
971 1005 if not self.isConfig:
972 1006
973 1007 nplots = 1
974 1008
975 1009 self.setup(id=id,
976 1010 nplots=nplots,
977 1011 wintitle=wintitle,
978 1012 show=show)
979 1013
980 1014 if ymin == None: ymin = numpy.nanmin(y)
981 1015 if ymax == None: ymax = numpy.nanmax(y)
982 1016 if xmin == None: xmin = numpy.nanmin(xdB)*0.9
983 1017 if xmax == None: xmax = numpy.nanmax(xdB)*1.1
984 1018
985 1019 self.isConfig = True
986 1020
987 1021 self.setWinTitle(title)
988 1022
989 1023 title = "Power Profile: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
990 1024 axes = self.axesList[0]
991 1025
992 1026 legendlabels = ["channel %d"%x for x in channelList]
993 1027 axes.pmultiline(xdB, y,
994 1028 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
995 1029 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels,
996 1030 ytick_visible=True, nxticks=5,
997 1031 grid='x')
998 1032
999 1033 self.draw()
1000 1034
1001 1035 self.save(figpath=figpath,
1002 1036 figfile=figfile,
1003 1037 save=save,
1004 1038 ftp=ftp,
1005 1039 wr_period=wr_period,
1006 1040 thisDatetime=thisDatetime)
1007 1041
1008 1042 class SpectraCutPlot(Figure):
1009 1043
1010 1044 isConfig = None
1011 1045 __nsubplots = None
1012 1046
1013 1047 WIDTHPROF = None
1014 1048 HEIGHTPROF = None
1015 1049 PREFIX = 'spc_cut'
1016 1050
1017 1051 def __init__(self, **kwargs):
1018 1052 Figure.__init__(self, **kwargs)
1019 1053 self.isConfig = False
1020 1054 self.__nsubplots = 1
1021 1055
1022 1056 self.PLOT_CODE = POWER_CODE
1023 1057
1024 1058 self.WIDTH = 700
1025 1059 self.HEIGHT = 500
1026 1060 self.counter_imagwr = 0
1027 1061
1028 1062 def getSubplots(self):
1029 1063 ncol = 1
1030 1064 nrow = 1
1031 1065
1032 1066 return nrow, ncol
1033 1067
1034 1068 def setup(self, id, nplots, wintitle, show):
1035 1069
1036 1070 self.nplots = nplots
1037 1071
1038 1072 ncolspan = 1
1039 1073 colspan = 1
1040 1074
1041 1075 self.createFigure(id = id,
1042 1076 wintitle = wintitle,
1043 1077 widthplot = self.WIDTH,
1044 1078 heightplot = self.HEIGHT,
1045 1079 show=show)
1046 1080
1047 1081 nrow, ncol = self.getSubplots()
1048 1082
1049 1083 counter = 0
1050 1084 for y in range(nrow):
1051 1085 for x in range(ncol):
1052 1086 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1053 1087
1054 1088 def run(self, dataOut, id, wintitle="", channelList=None,
1055 1089 xmin=None, xmax=None, ymin=None, ymax=None,
1056 1090 save=False, figpath='./', figfile=None, show=True,
1057 1091 ftp=False, wr_period=1, server=None,
1058 1092 folder=None, username=None, password=None,
1059 1093 xaxis="frequency"):
1060 1094
1061 1095
1062 1096 if channelList == None:
1063 1097 channelIndexList = dataOut.channelIndexList
1064 1098 channelList = dataOut.channelList
1065 1099 else:
1066 1100 channelIndexList = []
1067 1101 for channel in channelList:
1068 1102 if channel not in dataOut.channelList:
1069 1103 raise ValueError, "Channel %d is not in dataOut.channelList"
1070 1104 channelIndexList.append(dataOut.channelList.index(channel))
1071 1105
1072 1106 factor = dataOut.normFactor
1073 1107
1074 1108 y = dataOut.getHeiRange()
1075 1109
1076 1110 z = dataOut.data_spc/factor
1077 1111 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1078 1112
1079 1113 hei_index = numpy.arange(25)*3 + 20
1080 1114
1081 1115 if xaxis == "frequency":
1082 1116 x = dataOut.getFreqRange()/1000.
1083 1117 zdB = 10*numpy.log10(z[0,:,hei_index])
1084 1118 xlabel = "Frequency (kHz)"
1085 1119 ylabel = "Power (dB)"
1086 1120
1087 1121 elif xaxis == "time":
1088 1122 x = dataOut.getAcfRange()
1089 1123 zdB = z[0,:,hei_index]
1090 1124 xlabel = "Time (ms)"
1091 1125 ylabel = "ACF"
1092 1126
1093 1127 else:
1094 1128 x = dataOut.getVelRange()
1095 1129 zdB = 10*numpy.log10(z[0,:,hei_index])
1096 1130 xlabel = "Velocity (m/s)"
1097 1131 ylabel = "Power (dB)"
1098 1132
1099 1133 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1100 1134 title = wintitle + " Range Cuts %s" %(thisDatetime.strftime("%d-%b-%Y"))
1101 1135
1102 1136 if not self.isConfig:
1103 1137
1104 1138 nplots = 1
1105 1139
1106 1140 self.setup(id=id,
1107 1141 nplots=nplots,
1108 1142 wintitle=wintitle,
1109 1143 show=show)
1110 1144
1111 1145 if xmin == None: xmin = numpy.nanmin(x)*0.9
1112 1146 if xmax == None: xmax = numpy.nanmax(x)*1.1
1113 1147 if ymin == None: ymin = numpy.nanmin(zdB)
1114 1148 if ymax == None: ymax = numpy.nanmax(zdB)
1115 1149
1116 1150 self.isConfig = True
1117 1151
1118 1152 self.setWinTitle(title)
1119 1153
1120 1154 title = "Spectra Cuts: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
1121 1155 axes = self.axesList[0]
1122 1156
1123 1157 legendlabels = ["Range = %dKm" %y[i] for i in hei_index]
1124 1158
1125 1159 axes.pmultilineyaxis( x, zdB,
1126 1160 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1127 1161 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels,
1128 1162 ytick_visible=True, nxticks=5,
1129 1163 grid='x')
1130 1164
1131 1165 self.draw()
1132 1166
1133 1167 self.save(figpath=figpath,
1134 1168 figfile=figfile,
1135 1169 save=save,
1136 1170 ftp=ftp,
1137 1171 wr_period=wr_period,
1138 1172 thisDatetime=thisDatetime)
1139 1173
1140 1174 class Noise(Figure):
1141 1175
1142 1176 isConfig = None
1143 1177 __nsubplots = None
1144 1178
1145 1179 PREFIX = 'noise'
1180
1181 parameters = {
1182 'id': global_type_string,
1183 'wintitle': global_type_string,
1184 'channelList': global_type_list,
1185 'showprofile': global_type_boolean,
1186 'xmin': global_type_float,
1187 'xmax': global_type_float,
1188 'ymin': global_type_float,
1189 'ymax': global_type_float,
1190 'timerange': global_type_float,
1191 'save': global_type_boolean,
1192 'figpath': global_type_string,
1193 'figfile': global_type_string,
1194 'show': global_type_boolean,
1195 'ftp': global_type_boolean,
1196 'wr_period': global_type_integer,
1197 'server': global_type_string,
1198 'folder': global_type_string,
1199 'username': global_type_string,
1200 'password': global_type_string,
1201 'ftp_wei': global_type_integer,
1202 'exp_code': global_type_integer,
1203 'sub_exp_code': global_type_integer,
1204 'plot_pos': global_type_integer,
1205 }
1146 1206
1147 1207 def __init__(self, **kwargs):
1148 1208 Figure.__init__(self, **kwargs)
1149 1209 self.timerange = 24*60*60
1150 1210 self.isConfig = False
1151 1211 self.__nsubplots = 1
1152 1212 self.counter_imagwr = 0
1153 1213 self.WIDTH = 800
1154 1214 self.HEIGHT = 400
1155 1215 self.WIDTHPROF = 120
1156 1216 self.HEIGHTPROF = 0
1157 1217 self.xdata = None
1158 1218 self.ydata = None
1159 1219
1160 1220 self.PLOT_CODE = NOISE_CODE
1161 1221
1162 1222 self.FTP_WEI = None
1163 1223 self.EXP_CODE = None
1164 1224 self.SUB_EXP_CODE = None
1165 1225 self.PLOT_POS = None
1166 1226 self.figfile = None
1167 1227
1168 1228 self.xmin = None
1169 1229 self.xmax = None
1170 1230
1171 1231 def getSubplots(self):
1172 1232
1173 1233 ncol = 1
1174 1234 nrow = 1
1175 1235
1176 1236 return nrow, ncol
1177 1237
1178 1238 def openfile(self, filename):
1179 1239 dirname = os.path.dirname(filename)
1180 1240
1181 1241 if not os.path.exists(dirname):
1182 1242 os.mkdir(dirname)
1183 1243
1184 1244 f = open(filename,'w+')
1185 1245 f.write('\n\n')
1186 1246 f.write('JICAMARCA RADIO OBSERVATORY - Noise \n')
1187 1247 f.write('DD MM YYYY HH MM SS Channel0 Channel1 Channel2 Channel3\n\n' )
1188 1248 f.close()
1189 1249
1190 1250 def save_data(self, filename_phase, data, data_datetime):
1191 1251
1192 1252 f=open(filename_phase,'a')
1193 1253
1194 1254 timetuple_data = data_datetime.timetuple()
1195 1255 day = str(timetuple_data.tm_mday)
1196 1256 month = str(timetuple_data.tm_mon)
1197 1257 year = str(timetuple_data.tm_year)
1198 1258 hour = str(timetuple_data.tm_hour)
1199 1259 minute = str(timetuple_data.tm_min)
1200 1260 second = str(timetuple_data.tm_sec)
1201 1261
1202 1262 data_msg = ''
1203 1263 for i in range(len(data)):
1204 1264 data_msg += str(data[i]) + ' '
1205 1265
1206 1266 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' ' + data_msg + '\n')
1207 1267 f.close()
1208 1268
1209 1269
1210 1270 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1211 1271
1212 1272 self.__showprofile = showprofile
1213 1273 self.nplots = nplots
1214 1274
1215 1275 ncolspan = 7
1216 1276 colspan = 6
1217 1277 self.__nsubplots = 2
1218 1278
1219 1279 self.createFigure(id = id,
1220 1280 wintitle = wintitle,
1221 1281 widthplot = self.WIDTH+self.WIDTHPROF,
1222 1282 heightplot = self.HEIGHT+self.HEIGHTPROF,
1223 1283 show=show)
1224 1284
1225 1285 nrow, ncol = self.getSubplots()
1226 1286
1227 1287 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1228 1288
1229 1289
1230 1290 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='True',
1231 1291 xmin=None, xmax=None, ymin=None, ymax=None,
1232 1292 timerange=None,
1233 1293 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1234 1294 server=None, folder=None, username=None, password=None,
1235 1295 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1236 1296
1237 1297 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1238 1298 return
1239 1299
1240 1300 if channelList == None:
1241 1301 channelIndexList = dataOut.channelIndexList
1242 1302 channelList = dataOut.channelList
1243 1303 else:
1244 1304 channelIndexList = []
1245 1305 for channel in channelList:
1246 1306 if channel not in dataOut.channelList:
1247 1307 raise ValueError, "Channel %d is not in dataOut.channelList"
1248 1308 channelIndexList.append(dataOut.channelList.index(channel))
1249 1309
1250 1310 x = dataOut.getTimeRange()
1251 1311 #y = dataOut.getHeiRange()
1252 1312 factor = dataOut.normFactor
1253 1313 noise = dataOut.noise[channelIndexList]/factor
1254 1314 noisedB = 10*numpy.log10(noise)
1255 1315
1256 1316 thisDatetime = dataOut.datatime
1257 1317
1258 1318 title = wintitle + " Noise" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1259 1319 xlabel = ""
1260 1320 ylabel = "Intensity (dB)"
1261 1321 update_figfile = False
1262 1322
1263 1323 if not self.isConfig:
1264 1324
1265 1325 nplots = 1
1266 1326
1267 1327 self.setup(id=id,
1268 1328 nplots=nplots,
1269 1329 wintitle=wintitle,
1270 1330 showprofile=showprofile,
1271 1331 show=show)
1272 1332
1273 1333 if timerange != None:
1274 1334 self.timerange = timerange
1275 1335
1276 1336 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1277 1337
1278 1338 if ymin == None: ymin = numpy.floor(numpy.nanmin(noisedB)) - 10.0
1279 1339 if ymax == None: ymax = numpy.nanmax(noisedB) + 10.0
1280 1340
1281 1341 self.FTP_WEI = ftp_wei
1282 1342 self.EXP_CODE = exp_code
1283 1343 self.SUB_EXP_CODE = sub_exp_code
1284 1344 self.PLOT_POS = plot_pos
1285 1345
1286 1346
1287 1347 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1288 1348 self.isConfig = True
1289 1349 self.figfile = figfile
1290 1350 self.xdata = numpy.array([])
1291 1351 self.ydata = numpy.array([])
1292 1352
1293 1353 update_figfile = True
1294 1354
1295 1355 #open file beacon phase
1296 1356 path = '%s%03d' %(self.PREFIX, self.id)
1297 1357 noise_file = os.path.join(path,'%s.txt'%self.name)
1298 1358 self.filename_noise = os.path.join(figpath,noise_file)
1299 1359
1300 1360 self.setWinTitle(title)
1301 1361
1302 1362 title = "Noise %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1303 1363
1304 1364 legendlabels = ["channel %d"%(idchannel) for idchannel in channelList]
1305 1365 axes = self.axesList[0]
1306 1366
1307 1367 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1308 1368
1309 1369 if len(self.ydata)==0:
1310 1370 self.ydata = noisedB.reshape(-1,1)
1311 1371 else:
1312 1372 self.ydata = numpy.hstack((self.ydata, noisedB.reshape(-1,1)))
1313 1373
1314 1374
1315 1375 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1316 1376 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1317 1377 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1318 1378 XAxisAsTime=True, grid='both'
1319 1379 )
1320 1380
1321 1381 self.draw()
1322 1382
1323 1383 if dataOut.ltctime >= self.xmax:
1324 1384 self.counter_imagwr = wr_period
1325 1385 self.isConfig = False
1326 1386 update_figfile = True
1327 1387
1328 1388 self.save(figpath=figpath,
1329 1389 figfile=figfile,
1330 1390 save=save,
1331 1391 ftp=ftp,
1332 1392 wr_period=wr_period,
1333 1393 thisDatetime=thisDatetime,
1334 1394 update_figfile=update_figfile)
1335 1395
1336 1396 #store data beacon phase
1337 1397 if save:
1338 1398 self.save_data(self.filename_noise, noisedB, thisDatetime)
1339 1399
1340 1400 class BeaconPhase(Figure):
1341 1401
1342 1402 __isConfig = None
1343 1403 __nsubplots = None
1344 1404
1345 1405 PREFIX = 'beacon_phase'
1346 1406
1347 1407 parameters = {
1348 'id': 'string',
1349 'wintitle': 'string',
1350 'pairsList': 'pairsList',
1351 'showprofile': 'boolean',
1352 'xmin': 'float',
1353 'xmax': 'float',
1354 'ymin': 'float',
1355 'ymax': 'float',
1356 'hmin': 'float',
1357 'hmax': 'float',
1358 'timerange': 'float',
1359 'save': 'boolean',
1360 'figpath': 'string',
1361 'figfile': 'string',
1362 'show': 'boolean',
1363 'ftp': 'string',
1364 'wr_period': 'int',
1365 'server': 'string',
1366 'folder': 'string',
1367 'username': 'string',
1368 'password': 'string',
1369 'ftp_wei': 'int',
1370 'exp_code': 'int',
1371 'sub_exp_code': 'int',
1372 'plot_pos': 'int',
1408 'id': global_type_string,
1409 'wintitle': global_type_string,
1410 'pairsList': global_type_pairsList,
1411 'showprofile': global_type_boolean,
1412 'xmin': global_type_float,
1413 'xmax': global_type_float,
1414 'ymin': global_type_float,
1415 'ymax': global_type_float,
1416 'hmin': global_type_float,
1417 'hmax': global_type_float,
1418 'timerange': global_type_float,
1419 'save': global_type_boolean,
1420 'figpath': global_type_string,
1421 'figfile': global_type_string,
1422 'show': global_type_boolean,
1423 'ftp': global_type_boolean,
1424 'wr_period': global_type_integer,
1425 'server': global_type_string,
1426 'folder': global_type_string,
1427 'username': global_type_string,
1428 'password': global_type_string,
1429 'ftp_wei': global_type_integer,
1430 'exp_code': global_type_integer,
1431 'sub_exp_code': global_type_integer,
1432 'plot_pos': global_type_integer,
1373 1433 }
1374 1434
1375 1435 def __init__(self, **kwargs):
1376 1436 Figure.__init__(self, **kwargs)
1377 1437 self.timerange = 24*60*60
1378 1438 self.isConfig = False
1379 1439 self.__nsubplots = 1
1380 1440 self.counter_imagwr = 0
1381 1441 self.WIDTH = 800
1382 1442 self.HEIGHT = 400
1383 1443 self.WIDTHPROF = 120
1384 1444 self.HEIGHTPROF = 0
1385 1445 self.xdata = None
1386 1446 self.ydata = None
1387 1447
1388 1448 self.PLOT_CODE = BEACON_CODE
1389 1449
1390 1450 self.FTP_WEI = None
1391 1451 self.EXP_CODE = None
1392 1452 self.SUB_EXP_CODE = None
1393 1453 self.PLOT_POS = None
1394 1454
1395 1455 self.filename_phase = None
1396 1456
1397 1457 self.figfile = None
1398 1458
1399 1459 self.xmin = None
1400 1460 self.xmax = None
1401 1461
1402 1462 def getSubplots(self):
1403 1463
1404 1464 ncol = 1
1405 1465 nrow = 1
1406 1466
1407 1467 return nrow, ncol
1408 1468
1409 1469 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1410 1470
1411 1471 self.__showprofile = showprofile
1412 1472 self.nplots = nplots
1413 1473
1414 1474 ncolspan = 7
1415 1475 colspan = 6
1416 1476 self.__nsubplots = 2
1417 1477
1418 1478 self.createFigure(id = id,
1419 1479 wintitle = wintitle,
1420 1480 widthplot = self.WIDTH+self.WIDTHPROF,
1421 1481 heightplot = self.HEIGHT+self.HEIGHTPROF,
1422 1482 show=show)
1423 1483
1424 1484 nrow, ncol = self.getSubplots()
1425 1485
1426 1486 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1427 1487
1428 1488 def save_phase(self, filename_phase):
1429 1489 f = open(filename_phase,'w+')
1430 1490 f.write('\n\n')
1431 1491 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
1432 1492 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
1433 1493 f.close()
1434 1494
1435 1495 def save_data(self, filename_phase, data, data_datetime):
1436 1496 f=open(filename_phase,'a')
1437 1497 timetuple_data = data_datetime.timetuple()
1438 1498 day = str(timetuple_data.tm_mday)
1439 1499 month = str(timetuple_data.tm_mon)
1440 1500 year = str(timetuple_data.tm_year)
1441 1501 hour = str(timetuple_data.tm_hour)
1442 1502 minute = str(timetuple_data.tm_min)
1443 1503 second = str(timetuple_data.tm_sec)
1444 1504 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
1445 1505 f.close()
1446 1506
1447 1507
1448 1508 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1449 1509 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
1450 1510 timerange=None,
1451 1511 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1452 1512 server=None, folder=None, username=None, password=None,
1453 1513 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1454 1514
1455 1515 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1456 1516 return
1457 1517
1458 1518 if pairsList == None:
1459 1519 pairsIndexList = dataOut.pairsIndexList[:10]
1460 1520 else:
1461 1521 pairsIndexList = []
1462 1522 for pair in pairsList:
1463 1523 if pair not in dataOut.pairsList:
1464 1524 raise ValueError, "Pair %s is not in dataOut.pairsList" %(pair)
1465 1525 pairsIndexList.append(dataOut.pairsList.index(pair))
1466 1526
1467 1527 if pairsIndexList == []:
1468 1528 return
1469 1529
1470 1530 # if len(pairsIndexList) > 4:
1471 1531 # pairsIndexList = pairsIndexList[0:4]
1472 1532
1473 1533 hmin_index = None
1474 1534 hmax_index = None
1475 1535
1476 1536 if hmin != None and hmax != None:
1477 1537 indexes = numpy.arange(dataOut.nHeights)
1478 1538 hmin_list = indexes[dataOut.heightList >= hmin]
1479 1539 hmax_list = indexes[dataOut.heightList <= hmax]
1480 1540
1481 1541 if hmin_list.any():
1482 1542 hmin_index = hmin_list[0]
1483 1543
1484 1544 if hmax_list.any():
1485 1545 hmax_index = hmax_list[-1]+1
1486 1546
1487 1547 x = dataOut.getTimeRange()
1488 1548 #y = dataOut.getHeiRange()
1489 1549
1490 1550
1491 1551 thisDatetime = dataOut.datatime
1492 1552
1493 1553 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1494 1554 xlabel = "Local Time"
1495 1555 ylabel = "Phase (degrees)"
1496 1556
1497 1557 update_figfile = False
1498 1558
1499 1559 nplots = len(pairsIndexList)
1500 1560 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1501 1561 phase_beacon = numpy.zeros(len(pairsIndexList))
1502 1562 for i in range(nplots):
1503 1563 pair = dataOut.pairsList[pairsIndexList[i]]
1504 1564 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
1505 1565 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
1506 1566 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
1507 1567 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
1508 1568 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
1509 1569
1510 1570 #print "Phase %d%d" %(pair[0], pair[1])
1511 1571 #print phase[dataOut.beacon_heiIndexList]
1512 1572
1513 1573 if dataOut.beacon_heiIndexList:
1514 1574 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
1515 1575 else:
1516 1576 phase_beacon[i] = numpy.average(phase)
1517 1577
1518 1578 if not self.isConfig:
1519 1579
1520 1580 nplots = len(pairsIndexList)
1521 1581
1522 1582 self.setup(id=id,
1523 1583 nplots=nplots,
1524 1584 wintitle=wintitle,
1525 1585 showprofile=showprofile,
1526 1586 show=show)
1527 1587
1528 1588 if timerange != None:
1529 1589 self.timerange = timerange
1530 1590
1531 1591 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1532 1592
1533 1593 if ymin == None: ymin = 0
1534 1594 if ymax == None: ymax = 360
1535 1595
1536 1596 self.FTP_WEI = ftp_wei
1537 1597 self.EXP_CODE = exp_code
1538 1598 self.SUB_EXP_CODE = sub_exp_code
1539 1599 self.PLOT_POS = plot_pos
1540 1600
1541 1601 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1542 1602 self.isConfig = True
1543 1603 self.figfile = figfile
1544 1604 self.xdata = numpy.array([])
1545 1605 self.ydata = numpy.array([])
1546 1606
1547 1607 update_figfile = True
1548 1608
1549 1609 #open file beacon phase
1550 1610 path = '%s%03d' %(self.PREFIX, self.id)
1551 1611 beacon_file = os.path.join(path,'%s.txt'%self.name)
1552 1612 self.filename_phase = os.path.join(figpath,beacon_file)
1553 1613 #self.save_phase(self.filename_phase)
1554 1614
1555 1615
1556 1616 #store data beacon phase
1557 1617 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1558 1618
1559 1619 self.setWinTitle(title)
1560 1620
1561 1621
1562 1622 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1563 1623
1564 1624 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
1565 1625
1566 1626 axes = self.axesList[0]
1567 1627
1568 1628 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1569 1629
1570 1630 if len(self.ydata)==0:
1571 1631 self.ydata = phase_beacon.reshape(-1,1)
1572 1632 else:
1573 1633 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1574 1634
1575 1635
1576 1636 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1577 1637 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1578 1638 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1579 1639 XAxisAsTime=True, grid='both'
1580 1640 )
1581 1641
1582 1642 self.draw()
1583 1643
1584 1644 if dataOut.ltctime >= self.xmax:
1585 1645 self.counter_imagwr = wr_period
1586 1646 self.isConfig = False
1587 1647 update_figfile = True
1588 1648
1589 1649 self.save(figpath=figpath,
1590 1650 figfile=figfile,
1591 1651 save=save,
1592 1652 ftp=ftp,
1593 1653 wr_period=wr_period,
1594 1654 thisDatetime=thisDatetime,
1595 1655 update_figfile=update_figfile)
@@ -1,849 +1,853
1 1 '''
2 2 Created on Jul 3, 2014
3 3
4 4 @author: roj-idl71
5 5 '''
6 6
7 7 import os, sys
8 8 import time, datetime
9 9 import numpy
10 10 import fnmatch
11 11 import glob
12 12 from time import sleep
13 13
14 14 try:
15 15 import pyfits
16 16 except ImportError, e:
17 17 print "Fits data cannot be used. Install pyfits module"
18 18
19 19 from xml.etree.ElementTree import ElementTree
20 20
21 21 from jroIO_base import isRadarFolder, isNumber
22 22 from schainpy.model.data.jrodata import Fits
23 23 from schainpy.model.proc.jroproc_base import Operation, ProcessingUnit
24 24
25 25 class PyFits(object):
26 26 name=None
27 27 format=None
28 28 array =None
29 29 data =None
30 30 thdulist=None
31 31 prihdr=None
32 32 hdu=None
33 33
34 34 def __init__(self):
35 35
36 36 pass
37 37
38 38 def setColF(self,name,format,array):
39 39 self.name=name
40 40 self.format=format
41 41 self.array=array
42 42 a1=numpy.array([self.array],dtype=numpy.float32)
43 43 self.col1 = pyfits.Column(name=self.name, format=self.format, array=a1)
44 44 return self.col1
45 45
46 46 # def setColP(self,name,format,data):
47 47 # self.name=name
48 48 # self.format=format
49 49 # self.data=data
50 50 # a2=numpy.array([self.data],dtype=numpy.float32)
51 51 # self.col2 = pyfits.Column(name=self.name, format=self.format, array=a2)
52 52 # return self.col2
53 53
54 54
55 55 def writeData(self,name,format,data):
56 56 self.name=name
57 57 self.format=format
58 58 self.data=data
59 59 a2=numpy.array([self.data],dtype=numpy.float32)
60 60 self.col2 = pyfits.Column(name=self.name, format=self.format, array=a2)
61 61 return self.col2
62 62
63 63 def cFImage(self,idblock,year,month,day,hour,minute,second):
64 64 self.hdu= pyfits.PrimaryHDU(idblock)
65 65 self.hdu.header.set("Year",year)
66 66 self.hdu.header.set("Month",month)
67 67 self.hdu.header.set("Day",day)
68 68 self.hdu.header.set("Hour",hour)
69 69 self.hdu.header.set("Minute",minute)
70 70 self.hdu.header.set("Second",second)
71 71 return self.hdu
72 72
73 73
74 74 def Ctable(self,colList):
75 75 self.cols=pyfits.ColDefs(colList)
76 76 self.tbhdu = pyfits.new_table(self.cols)
77 77 return self.tbhdu
78 78
79 79
80 80 def CFile(self,hdu,tbhdu):
81 81 self.thdulist=pyfits.HDUList([hdu,tbhdu])
82 82
83 83 def wFile(self,filename):
84 84 if os.path.isfile(filename):
85 85 os.remove(filename)
86 86 self.thdulist.writeto(filename)
87 87
88 88
89 89 class ParameterConf:
90 90 ELEMENTNAME = 'Parameter'
91 91 def __init__(self):
92 92 self.name = ''
93 93 self.value = ''
94 94
95 95 def readXml(self, parmElement):
96 96 self.name = parmElement.get('name')
97 97 self.value = parmElement.get('value')
98 98
99 99 def getElementName(self):
100 100 return self.ELEMENTNAME
101 101
102 102 class Metadata(object):
103 103
104 104 def __init__(self, filename):
105 105 self.parmConfObjList = []
106 106 self.readXml(filename)
107 107
108 108 def readXml(self, filename):
109 109 self.projectElement = None
110 110 self.procUnitConfObjDict = {}
111 111 self.projectElement = ElementTree().parse(filename)
112 112 self.project = self.projectElement.tag
113 113
114 114 parmElementList = self.projectElement.getiterator(ParameterConf().getElementName())
115 115
116 116 for parmElement in parmElementList:
117 117 parmConfObj = ParameterConf()
118 118 parmConfObj.readXml(parmElement)
119 119 self.parmConfObjList.append(parmConfObj)
120 120
121 121 class FitsWriter(Operation):
122
122 parameters = {
123 'path': global_type_string,
124 'dataBlocksPerFile': global_type_integer,
125 'metadatafile': global_type_string,
126 }
123 127 def __init__(self, **kwargs):
124 128 Operation.__init__(self, **kwargs)
125 129 self.isConfig = False
126 130 self.dataBlocksPerFile = None
127 131 self.blockIndex = 0
128 132 self.flagIsNewFile = 1
129 133 self.fitsObj = None
130 134 self.optchar = 'P'
131 135 self.ext = '.fits'
132 136 self.setFile = 0
133 137
134 138 def setFitsHeader(self, dataOut, metadatafile=None):
135 139
136 140 header_data = pyfits.PrimaryHDU()
137 141
138 142 header_data.header['EXPNAME'] = "RADAR DATA"
139 143 header_data.header['DATATYPE'] = "SPECTRA"
140 144 header_data.header['COMMENT'] = ""
141 145
142 146 if metadatafile:
143 147
144 148 metadata4fits = Metadata(metadatafile)
145 149
146 150 for parameter in metadata4fits.parmConfObjList:
147 151 parm_name = parameter.name
148 152 parm_value = parameter.value
149 153
150 154 header_data.header[parm_name] = parm_value
151 155
152 156 header_data.header['DATETIME'] = time.strftime("%b %d %Y %H:%M:%S", dataOut.datatime.timetuple())
153 157 header_data.header['CHANNELLIST'] = str(dataOut.channelList)
154 158 header_data.header['NCHANNELS'] = dataOut.nChannels
155 159 #header_data.header['HEIGHTS'] = dataOut.heightList
156 160 header_data.header['NHEIGHTS'] = dataOut.nHeights
157 161
158 162 header_data.header['IPPSECONDS'] = dataOut.ippSeconds
159 163 header_data.header['NCOHINT'] = dataOut.nCohInt
160 164 header_data.header['NINCOHINT'] = dataOut.nIncohInt
161 165 header_data.header['TIMEZONE'] = dataOut.timeZone
162 166 header_data.header['NBLOCK'] = self.blockIndex
163 167
164 168 header_data.writeto(self.filename)
165 169
166 170 self.addExtension(dataOut.heightList,'HEIGHTLIST')
167 171
168 172
169 173 def setup(self, dataOut, path, dataBlocksPerFile=100, metadatafile=None):
170 174
171 175 self.path = path
172 176 self.dataOut = dataOut
173 177 self.metadatafile = metadatafile
174 178 self.dataBlocksPerFile = dataBlocksPerFile
175 179
176 180 def open(self):
177 181 self.fitsObj = pyfits.open(self.filename, mode='update')
178 182
179 183
180 184 def addExtension(self, data, tagname):
181 185 self.open()
182 186 extension = pyfits.ImageHDU(data=data, name=tagname)
183 187 #extension.header['TAG'] = tagname
184 188 self.fitsObj.append(extension)
185 189 self.write()
186 190
187 191 def addData(self, data):
188 192 self.open()
189 193 extension = pyfits.ImageHDU(data=data, name=self.fitsObj[0].header['DATATYPE'])
190 194 extension.header['UTCTIME'] = self.dataOut.utctime
191 195 self.fitsObj.append(extension)
192 196 self.blockIndex += 1
193 197 self.fitsObj[0].header['NBLOCK'] = self.blockIndex
194 198
195 199 self.write()
196 200
197 201 def write(self):
198 202
199 203 self.fitsObj.flush(verbose=True)
200 204 self.fitsObj.close()
201 205
202 206
203 207 def setNextFile(self):
204 208
205 209 ext = self.ext
206 210 path = self.path
207 211
208 212 timeTuple = time.localtime( self.dataOut.utctime)
209 213 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
210 214
211 215 fullpath = os.path.join( path, subfolder )
212 216 if not( os.path.exists(fullpath) ):
213 217 os.mkdir(fullpath)
214 218 self.setFile = -1 #inicializo mi contador de seteo
215 219 else:
216 220 filesList = os.listdir( fullpath )
217 221 if len( filesList ) > 0:
218 222 filesList = sorted( filesList, key=str.lower )
219 223 filen = filesList[-1]
220 224
221 225 if isNumber( filen[8:11] ):
222 226 self.setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
223 227 else:
224 228 self.setFile = -1
225 229 else:
226 230 self.setFile = -1 #inicializo mi contador de seteo
227 231
228 232 setFile = self.setFile
229 233 setFile += 1
230 234
231 235 thisFile = '%s%4.4d%3.3d%3.3d%s' % (self.optchar,
232 236 timeTuple.tm_year,
233 237 timeTuple.tm_yday,
234 238 setFile,
235 239 ext )
236 240
237 241 filename = os.path.join( path, subfolder, thisFile )
238 242
239 243 self.blockIndex = 0
240 244 self.filename = filename
241 245 self.setFile = setFile
242 246 self.flagIsNewFile = 1
243 247
244 248 print 'Writing the file: %s'%self.filename
245 249
246 250 self.setFitsHeader(self.dataOut, self.metadatafile)
247 251
248 252 return 1
249 253
250 254 def writeBlock(self):
251 255 self.addData(self.dataOut.data_spc)
252 256 self.flagIsNewFile = 0
253 257
254 258
255 259 def __setNewBlock(self):
256 260
257 261 if self.flagIsNewFile:
258 262 return 1
259 263
260 264 if self.blockIndex < self.dataBlocksPerFile:
261 265 return 1
262 266
263 267 if not( self.setNextFile() ):
264 268 return 0
265 269
266 270 return 1
267 271
268 272 def writeNextBlock(self):
269 273 if not( self.__setNewBlock() ):
270 274 return 0
271 275 self.writeBlock()
272 276 return 1
273 277
274 278 def putData(self):
275 279 if self.flagIsNewFile:
276 280 self.setNextFile()
277 281 self.writeNextBlock()
278 282
279 def run(self, dataOut, **kwargs):
283 def run(self, dataOut, path, dataBlocksPerFile=100, metadatafile=None, **kwargs):
280 284 if not(self.isConfig):
281 self.setup(dataOut, **kwargs)
285 self.setup(dataOut, path, dataBlocksPerFile=dataBlocksPerFile, metadatafile=metadatafile, **kwargs)
282 286 self.isConfig = True
283 287 self.putData()
284 288
285 289
286 290 class FitsReader(ProcessingUnit):
287 291
288 292 # __TIMEZONE = time.timezone
289 293
290 294 expName = None
291 295 datetimestr = None
292 296 utc = None
293 297 nChannels = None
294 298 nSamples = None
295 299 dataBlocksPerFile = None
296 300 comments = None
297 301 lastUTTime = None
298 302 header_dict = None
299 303 data = None
300 304 data_header_dict = None
301 305
302 306 def __init__(self, **kwargs):
303 307 ProcessingUnit.__init__(self, **kwargs)
304 308 self.isConfig = False
305 309 self.ext = '.fits'
306 310 self.setFile = 0
307 311 self.flagNoMoreFiles = 0
308 312 self.flagIsNewFile = 1
309 313 self.flagDiscontinuousBlock = None
310 314 self.fileIndex = None
311 315 self.filename = None
312 316 self.fileSize = None
313 317 self.fitsObj = None
314 318 self.timeZone = None
315 319 self.nReadBlocks = 0
316 320 self.nTotalBlocks = 0
317 321 self.dataOut = self.createObjByDefault()
318 322 self.maxTimeStep = 10# deberia ser definido por el usuario usando el metodo setup()
319 323 self.blockIndex = 1
320 324
321 325 def createObjByDefault(self):
322 326
323 327 dataObj = Fits()
324 328
325 329 return dataObj
326 330
327 331 def isFileinThisTime(self, filename, startTime, endTime, useLocalTime=False):
328 332 try:
329 333 fitsObj = pyfits.open(filename,'readonly')
330 334 except:
331 335 print "File %s can't be opened" %(filename)
332 336 return None
333 337
334 338 header = fitsObj[0].header
335 339 struct_time = time.strptime(header['DATETIME'], "%b %d %Y %H:%M:%S")
336 340 utc = time.mktime(struct_time) - time.timezone #TIMEZONE debe ser un parametro del header FITS
337 341
338 342 ltc = utc
339 343 if useLocalTime:
340 344 ltc -= time.timezone
341 345 thisDatetime = datetime.datetime.utcfromtimestamp(ltc)
342 346 thisTime = thisDatetime.time()
343 347
344 348 if not ((startTime <= thisTime) and (endTime > thisTime)):
345 349 return None
346 350
347 351 return thisDatetime
348 352
349 353 def __setNextFileOnline(self):
350 354 raise NotImplementedError
351 355
352 356 def __setNextFileOffline(self):
353 357 idFile = self.fileIndex
354 358
355 359 while (True):
356 360 idFile += 1
357 361 if not(idFile < len(self.filenameList)):
358 362 self.flagNoMoreFiles = 1
359 363 print "No more Files"
360 364 return 0
361 365
362 366 filename = self.filenameList[idFile]
363 367
364 368 # if not(self.__verifyFile(filename)):
365 369 # continue
366 370
367 371 fileSize = os.path.getsize(filename)
368 372 fitsObj = pyfits.open(filename,'readonly')
369 373 break
370 374
371 375 self.flagIsNewFile = 1
372 376 self.fileIndex = idFile
373 377 self.filename = filename
374 378 self.fileSize = fileSize
375 379 self.fitsObj = fitsObj
376 380 self.blockIndex = 0
377 381 print "Setting the file: %s"%self.filename
378 382
379 383 return 1
380 384
381 385 def __setValuesFromHeader(self):
382 386
383 387 self.dataOut.header = self.header_dict
384 388 self.dataOut.expName = self.expName
385 389
386 390 self.dataOut.timeZone = self.timeZone
387 391 self.dataOut.dataBlocksPerFile = self.dataBlocksPerFile
388 392 self.dataOut.comments = self.comments
389 393 # self.dataOut.timeInterval = self.timeInterval
390 394 self.dataOut.channelList = self.channelList
391 395 self.dataOut.heightList = self.heightList
392 396
393 397 self.dataOut.nCohInt = self.nCohInt
394 398 self.dataOut.nIncohInt = self.nIncohInt
395 399
396 400 self.dataOut.ippSeconds = self.ippSeconds
397 401
398 402 def readHeader(self):
399 403 headerObj = self.fitsObj[0]
400 404
401 405 self.header_dict = headerObj.header
402 406 if 'EXPNAME' in headerObj.header.keys():
403 407 self.expName = headerObj.header['EXPNAME']
404 408
405 409 if 'DATATYPE' in headerObj.header.keys():
406 410 self.dataType = headerObj.header['DATATYPE']
407 411
408 412 self.datetimestr = headerObj.header['DATETIME']
409 413 channelList = headerObj.header['CHANNELLIST']
410 414 channelList = channelList.split('[')
411 415 channelList = channelList[1].split(']')
412 416 channelList = channelList[0].split(',')
413 417 channelList = [int(ch) for ch in channelList]
414 418 self.channelList = channelList
415 419 self.nChannels = headerObj.header['NCHANNELS']
416 420 self.nHeights = headerObj.header['NHEIGHTS']
417 421 self.ippSeconds = headerObj.header['IPPSECONDS']
418 422 self.nCohInt = headerObj.header['NCOHINT']
419 423 self.nIncohInt = headerObj.header['NINCOHINT']
420 424 self.dataBlocksPerFile = headerObj.header['NBLOCK']
421 425 self.timeZone = headerObj.header['TIMEZONE']
422 426
423 427 # self.timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
424 428
425 429 if 'COMMENT' in headerObj.header.keys():
426 430 self.comments = headerObj.header['COMMENT']
427 431
428 432 self.readHeightList()
429 433
430 434 def readHeightList(self):
431 435 self.blockIndex = self.blockIndex + 1
432 436 obj = self.fitsObj[self.blockIndex]
433 437 self.heightList = obj.data
434 438 self.blockIndex = self.blockIndex + 1
435 439
436 440 def readExtension(self):
437 441 obj = self.fitsObj[self.blockIndex]
438 442 self.heightList = obj.data
439 443 self.blockIndex = self.blockIndex + 1
440 444
441 445 def setNextFile(self):
442 446
443 447 if self.online:
444 448 newFile = self.__setNextFileOnline()
445 449 else:
446 450 newFile = self.__setNextFileOffline()
447 451
448 452 if not(newFile):
449 453 return 0
450 454
451 455 self.readHeader()
452 456 self.__setValuesFromHeader()
453 457 self.nReadBlocks = 0
454 458 # self.blockIndex = 1
455 459 return 1
456 460
457 461 def __searchFilesOffLine(self,
458 462 path,
459 463 startDate,
460 464 endDate,
461 465 startTime=datetime.time(0,0,0),
462 466 endTime=datetime.time(23,59,59),
463 467 set=None,
464 468 expLabel='',
465 469 ext='.fits',
466 470 walk=True):
467 471
468 472 pathList = []
469 473
470 474 if not walk:
471 475 pathList.append(path)
472 476
473 477 else:
474 478 dirList = []
475 479 for thisPath in os.listdir(path):
476 480 if not os.path.isdir(os.path.join(path,thisPath)):
477 481 continue
478 482 if not isRadarFolder(thisPath):
479 483 continue
480 484
481 485 dirList.append(thisPath)
482 486
483 487 if not(dirList):
484 488 return None, None
485 489
486 490 thisDate = startDate
487 491
488 492 while(thisDate <= endDate):
489 493 year = thisDate.timetuple().tm_year
490 494 doy = thisDate.timetuple().tm_yday
491 495
492 496 matchlist = fnmatch.filter(dirList, '?' + '%4.4d%3.3d' % (year,doy) + '*')
493 497 if len(matchlist) == 0:
494 498 thisDate += datetime.timedelta(1)
495 499 continue
496 500 for match in matchlist:
497 501 pathList.append(os.path.join(path,match,expLabel))
498 502
499 503 thisDate += datetime.timedelta(1)
500 504
501 505 if pathList == []:
502 506 print "Any folder was found for the date range: %s-%s" %(startDate, endDate)
503 507 return None, None
504 508
505 509 print "%d folder(s) was(were) found for the date range: %s - %s" %(len(pathList), startDate, endDate)
506 510
507 511 filenameList = []
508 512 datetimeList = []
509 513
510 514 for i in range(len(pathList)):
511 515
512 516 thisPath = pathList[i]
513 517
514 518 fileList = glob.glob1(thisPath, "*%s" %ext)
515 519 fileList.sort()
516 520
517 521 for thisFile in fileList:
518 522
519 523 filename = os.path.join(thisPath,thisFile)
520 524 thisDatetime = self.isFileinThisTime(filename, startTime, endTime)
521 525
522 526 if not(thisDatetime):
523 527 continue
524 528
525 529 filenameList.append(filename)
526 530 datetimeList.append(thisDatetime)
527 531
528 532 if not(filenameList):
529 533 print "Any file was found for the time range %s - %s" %(startTime, endTime)
530 534 return None, None
531 535
532 536 print "%d file(s) was(were) found for the time range: %s - %s" %(len(filenameList), startTime, endTime)
533 537 print
534 538
535 539 for i in range(len(filenameList)):
536 540 print "%s -> [%s]" %(filenameList[i], datetimeList[i].ctime())
537 541
538 542 self.filenameList = filenameList
539 543 self.datetimeList = datetimeList
540 544
541 545 return pathList, filenameList
542 546
543 547 def setup(self, path=None,
544 548 startDate=None,
545 549 endDate=None,
546 550 startTime=datetime.time(0,0,0),
547 551 endTime=datetime.time(23,59,59),
548 552 set=0,
549 553 expLabel = "",
550 554 ext = None,
551 555 online = False,
552 556 delay = 60,
553 557 walk = True):
554 558
555 559 if path == None:
556 560 raise ValueError, "The path is not valid"
557 561
558 562 if ext == None:
559 563 ext = self.ext
560 564
561 565 if not(online):
562 566 print "Searching files in offline mode ..."
563 567 pathList, filenameList = self.__searchFilesOffLine(path, startDate=startDate, endDate=endDate,
564 568 startTime=startTime, endTime=endTime,
565 569 set=set, expLabel=expLabel, ext=ext,
566 570 walk=walk)
567 571
568 572 if not(pathList):
569 573 print "No *%s files into the folder %s \nfor the range: %s - %s"%(ext, path,
570 574 datetime.datetime.combine(startDate,startTime).ctime(),
571 575 datetime.datetime.combine(endDate,endTime).ctime())
572 576
573 577 sys.exit(-1)
574 578
575 579 self.fileIndex = -1
576 580 self.pathList = pathList
577 581 self.filenameList = filenameList
578 582
579 583 self.online = online
580 584 self.delay = delay
581 585 ext = ext.lower()
582 586 self.ext = ext
583 587
584 588 if not(self.setNextFile()):
585 589 if (startDate!=None) and (endDate!=None):
586 590 print "No files in range: %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime())
587 591 elif startDate != None:
588 592 print "No files in range: %s" %(datetime.datetime.combine(startDate,startTime).ctime())
589 593 else:
590 594 print "No files"
591 595
592 596 sys.exit(-1)
593 597
594 598
595 599
596 600 def readBlock(self):
597 601 dataObj = self.fitsObj[self.blockIndex]
598 602
599 603 self.data = dataObj.data
600 604 self.data_header_dict = dataObj.header
601 605 self.utc = self.data_header_dict['UTCTIME']
602 606
603 607 self.flagIsNewFile = 0
604 608 self.blockIndex += 1
605 609 self.nTotalBlocks += 1
606 610 self.nReadBlocks += 1
607 611
608 612 return 1
609 613
610 614 def __jumpToLastBlock(self):
611 615 raise NotImplementedError
612 616
613 617 def __waitNewBlock(self):
614 618 """
615 619 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
616 620
617 621 Si el modo de lectura es OffLine siempre retorn 0
618 622 """
619 623 if not self.online:
620 624 return 0
621 625
622 626 if (self.nReadBlocks >= self.dataBlocksPerFile):
623 627 return 0
624 628
625 629 currentPointer = self.fp.tell()
626 630
627 631 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
628 632
629 633 for nTries in range( self.nTries ):
630 634
631 635 self.fp.close()
632 636 self.fp = open( self.filename, 'rb' )
633 637 self.fp.seek( currentPointer )
634 638
635 639 self.fileSize = os.path.getsize( self.filename )
636 640 currentSize = self.fileSize - currentPointer
637 641
638 642 if ( currentSize >= neededSize ):
639 643 self.__rdBasicHeader()
640 644 return 1
641 645
642 646 print "\tWaiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries+1)
643 647 sleep( self.delay )
644 648
645 649
646 650 return 0
647 651
648 652 def __setNewBlock(self):
649 653
650 654 if self.online:
651 655 self.__jumpToLastBlock()
652 656
653 657 if self.flagIsNewFile:
654 658 return 1
655 659
656 660 self.lastUTTime = self.utc
657 661
658 662 if self.online:
659 663 if self.__waitNewBlock():
660 664 return 1
661 665
662 666 if self.nReadBlocks < self.dataBlocksPerFile:
663 667 return 1
664 668
665 669 if not(self.setNextFile()):
666 670 return 0
667 671
668 672 deltaTime = self.utc - self.lastUTTime
669 673
670 674 self.flagDiscontinuousBlock = 0
671 675
672 676 if deltaTime > self.maxTimeStep:
673 677 self.flagDiscontinuousBlock = 1
674 678
675 679 return 1
676 680
677 681
678 682 def readNextBlock(self):
679 683 if not(self.__setNewBlock()):
680 684 return 0
681 685
682 686 if not(self.readBlock()):
683 687 return 0
684 688
685 689 return 1
686 690
687 691 def printInfo(self):
688 692
689 693 pass
690 694
691 695 def getData(self):
692 696
693 697 if self.flagNoMoreFiles:
694 698 self.dataOut.flagNoData = True
695 699 print 'Process finished'
696 700 return 0
697 701
698 702 self.flagDiscontinuousBlock = 0
699 703 self.flagIsNewBlock = 0
700 704
701 705 if not(self.readNextBlock()):
702 706 return 0
703 707
704 708 if self.data is None:
705 709 self.dataOut.flagNoData = True
706 710 return 0
707 711
708 712 self.dataOut.data = self.data
709 713 self.dataOut.data_header = self.data_header_dict
710 714 self.dataOut.utctime = self.utc
711 715
712 716 # self.dataOut.header = self.header_dict
713 717 # self.dataOut.expName = self.expName
714 718 # self.dataOut.nChannels = self.nChannels
715 719 # self.dataOut.timeZone = self.timeZone
716 720 # self.dataOut.dataBlocksPerFile = self.dataBlocksPerFile
717 721 # self.dataOut.comments = self.comments
718 722 # # self.dataOut.timeInterval = self.timeInterval
719 723 # self.dataOut.channelList = self.channelList
720 724 # self.dataOut.heightList = self.heightList
721 725 self.dataOut.flagNoData = False
722 726
723 727 return self.dataOut.data
724 728
725 729 def run(self, **kwargs):
726 730
727 731 if not(self.isConfig):
728 732 self.setup(**kwargs)
729 733 self.isConfig = True
730 734
731 735 self.getData()
732 736
733 737 class SpectraHeisWriter(Operation):
734 738 # set = None
735 739 setFile = None
736 740 idblock = None
737 741 doypath = None
738 742 subfolder = None
739 743
740 744 def __init__(self, **kwargs):
741 745 Operation.__init__(self, **kwargs)
742 746 self.wrObj = PyFits()
743 747 # self.dataOut = dataOut
744 748 self.nTotalBlocks=0
745 749 # self.set = None
746 750 self.setFile = None
747 751 self.idblock = 0
748 752 self.wrpath = None
749 753 self.doypath = None
750 754 self.subfolder = None
751 755 self.isConfig = False
752 756
753 757 def isNumber(str):
754 758 """
755 759 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
756 760
757 761 Excepciones:
758 762 Si un determinado string no puede ser convertido a numero
759 763 Input:
760 764 str, string al cual se le analiza para determinar si convertible a un numero o no
761 765
762 766 Return:
763 767 True : si el string es uno numerico
764 768 False : no es un string numerico
765 769 """
766 770 try:
767 771 float( str )
768 772 return True
769 773 except:
770 774 return False
771 775
772 776 def setup(self, dataOut, wrpath):
773 777
774 778 if not(os.path.exists(wrpath)):
775 779 os.mkdir(wrpath)
776 780
777 781 self.wrpath = wrpath
778 782 # self.setFile = 0
779 783 self.dataOut = dataOut
780 784
781 785 def putData(self):
782 786 name= time.localtime( self.dataOut.utctime)
783 787 ext=".fits"
784 788
785 789 if self.doypath == None:
786 790 self.subfolder = 'F%4.4d%3.3d_%d' % (name.tm_year,name.tm_yday,time.mktime(datetime.datetime.now().timetuple()))
787 791 self.doypath = os.path.join( self.wrpath, self.subfolder )
788 792 os.mkdir(self.doypath)
789 793
790 794 if self.setFile == None:
791 795 # self.set = self.dataOut.set
792 796 self.setFile = 0
793 797 # if self.set != self.dataOut.set:
794 798 ## self.set = self.dataOut.set
795 799 # self.setFile = 0
796 800
797 801 #make the filename
798 802 thisFile = 'D%4.4d%3.3d_%3.3d%s' % (name.tm_year,name.tm_yday,self.setFile,ext)
799 803
800 804 filename = os.path.join(self.wrpath,self.subfolder, thisFile)
801 805
802 806 idblock = numpy.array([self.idblock],dtype="int64")
803 807 header=self.wrObj.cFImage(idblock=idblock,
804 808 year=time.gmtime(self.dataOut.utctime).tm_year,
805 809 month=time.gmtime(self.dataOut.utctime).tm_mon,
806 810 day=time.gmtime(self.dataOut.utctime).tm_mday,
807 811 hour=time.gmtime(self.dataOut.utctime).tm_hour,
808 812 minute=time.gmtime(self.dataOut.utctime).tm_min,
809 813 second=time.gmtime(self.dataOut.utctime).tm_sec)
810 814
811 815 c=3E8
812 816 deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
813 817 freq=numpy.arange(-1*self.dataOut.nHeights/2.,self.dataOut.nHeights/2.)*(c/(2*deltaHeight*1000))
814 818
815 819 colList = []
816 820
817 821 colFreq=self.wrObj.setColF(name="freq", format=str(self.dataOut.nFFTPoints)+'E', array=freq)
818 822
819 823 colList.append(colFreq)
820 824
821 825 nchannel=self.dataOut.nChannels
822 826
823 827 for i in range(nchannel):
824 828 col = self.wrObj.writeData(name="PCh"+str(i+1),
825 829 format=str(self.dataOut.nFFTPoints)+'E',
826 830 data=10*numpy.log10(self.dataOut.data_spc[i,:]))
827 831
828 832 colList.append(col)
829 833
830 834 data=self.wrObj.Ctable(colList=colList)
831 835
832 836 self.wrObj.CFile(header,data)
833 837
834 838 self.wrObj.wFile(filename)
835 839
836 840 #update the setFile
837 841 self.setFile += 1
838 842 self.idblock += 1
839 843
840 844 return 1
841 845
842 846 def run(self, dataOut, **kwargs):
843 847
844 848 if not(self.isConfig):
845 849
846 850 self.setup(dataOut, **kwargs)
847 851 self.isConfig = True
848 852
849 853 self.putData()
@@ -1,144 +1,144
1 1 '''
2 2 @author: Daniel Suarez
3 3 '''
4 4 import numpy
5 5 from jroproc_base import ProcessingUnit, Operation
6 6 from schainpy.model.data.jroamisr import AMISR
7 7
8 8 class AMISRProc(ProcessingUnit):
9 9 def __init__(self):
10 10 ProcessingUnit.__init__(self)
11 11 self.objectDict = {}
12 12 self.dataOut = AMISR()
13 13
14 14 def run(self):
15 15 if self.dataIn.type == 'AMISR':
16 16 self.dataOut.copy(self.dataIn)
17 17
18 18
19 19 class PrintInfo(Operation):
20 20 def __init__(self):
21 21 self.__isPrinted = False
22 22
23 23 def run(self, dataOut):
24 24
25 25 if not self.__isPrinted:
26 26 print 'Number of Records by File: %d'%dataOut.nRecords
27 27 print 'Number of Pulses: %d'%dataOut.nProfiles
28 28 print 'Number of Pulses by Frame: %d'%dataOut.npulseByFrame
29 29 print 'Number of Samples by Pulse: %d'%len(dataOut.heightList)
30 30 print 'Ipp Seconds: %f'%dataOut.ippSeconds
31 31 print 'Number of Beams: %d'%dataOut.nBeams
32 32 print 'BeamCodes:'
33 33 beamStrList = ['Beam %d -> Code=%d, azimuth=%2.2f, zenith=%2.2f, gain=%2.2f'%(k,v[0],v[1],v[2],v[3]) for k,v in dataOut.beamCodeDict.items()]
34 34 for b in beamStrList:
35 35 print b
36 36 self.__isPrinted = True
37 37
38 38 return
39 39
40 40
41 41 class BeamSelector(Operation):
42 42 profileIndex = None
43 43 nProfiles = None
44 44 parameters = {
45 'beam': 'string',
45 'beam': global_type_string,
46 46 }
47 47
48 48 def __init__(self):
49 49
50 50 self.profileIndex = 0
51 51 self.__isConfig = False
52 52
53 53 def incIndex(self):
54 54 self.profileIndex += 1
55 55
56 56 if self.profileIndex >= self.nProfiles:
57 57 self.profileIndex = 0
58 58
59 59 def isProfileInRange(self, minIndex, maxIndex):
60 60
61 61 if self.profileIndex < minIndex:
62 62 return False
63 63
64 64 if self.profileIndex > maxIndex:
65 65 return False
66 66
67 67 return True
68 68
69 69 def isProfileInList(self, profileList):
70 70
71 71 if self.profileIndex not in profileList:
72 72 return False
73 73
74 74 return True
75 75
76 76 def run(self, dataOut, beam=None):
77 77
78 78 dataOut.flagNoData = True
79 79
80 80 if not(self.__isConfig):
81 81
82 82 self.nProfiles = dataOut.nProfiles
83 83 self.profileIndex = dataOut.profileIndex
84 84 self.__isConfig = True
85 85
86 86 if beam != None:
87 87 if self.isProfileInList(dataOut.beamRangeDict[beam]):
88 88 beamInfo = dataOut.beamCodeDict[beam]
89 89 dataOut.azimuth = beamInfo[1]
90 90 dataOut.zenith = beamInfo[2]
91 91 dataOut.gain = beamInfo[3]
92 92 dataOut.flagNoData = False
93 93
94 94 self.incIndex()
95 95 return 1
96 96
97 97 else:
98 98 raise ValueError, "BeamSelector needs beam value"
99 99
100 100 return 0
101 101
102 102 class ProfileToChannels(Operation):
103 103
104 104 def __init__(self):
105 105 self.__isConfig = False
106 106 self.__counter_chan = 0
107 107 self.buffer = None
108 108
109 109 def isProfileInList(self, profileList):
110 110
111 111 if self.profileIndex not in profileList:
112 112 return False
113 113
114 114 return True
115 115
116 116 def run(self, dataOut):
117 117
118 118 dataOut.flagNoData = True
119 119
120 120 if not(self.__isConfig):
121 121 nchannels = len(dataOut.beamRangeDict.keys())
122 122 nsamples = dataOut.nHeights
123 123 self.buffer = numpy.zeros((nchannels, nsamples), dtype = 'complex128')
124 124 dataOut.beam.codeList = [dataOut.beamCodeDict[x][0] for x in range(nchannels)]
125 125 dataOut.beam.azimuthList = [dataOut.beamCodeDict[x][1] for x in range(nchannels)]
126 126 dataOut.beam.zenithList = [dataOut.beamCodeDict[x][2] for x in range(nchannels)]
127 127 self.__isConfig = True
128 128
129 129 for i in range(self.buffer.shape[0]):
130 130 if dataOut.profileIndex in dataOut.beamRangeDict[i]:
131 131 self.buffer[i,:] = dataOut.data
132 132 break
133 133
134 134
135 135 self.__counter_chan += 1
136 136
137 137 if self.__counter_chan >= self.buffer.shape[0]:
138 138 self.__counter_chan = 0
139 139 dataOut.data = self.buffer.copy()
140 140 dataOut.channelList = range(self.buffer.shape[0])
141 141 self.__isConfig = False
142 142 dataOut.flagNoData = False
143 143 pass
144 144 No newline at end of file
@@ -1,345 +1,350
1 1 import numpy
2 2
3 3 from jroproc_base import ProcessingUnit, Operation
4 4 from schainpy.model.data.jrodata import SpectraHeis
5 5
6 6 class SpectraHeisProc(ProcessingUnit):
7 7
8 8 def __init__(self, **kwargs):
9 9
10 10 ProcessingUnit.__init__(self, **kwargs)
11 11
12 12 # self.buffer = None
13 13 # self.firstdatatime = None
14 14 # self.profIndex = 0
15 15 self.dataOut = SpectraHeis()
16 16
17 17 def __updateObjFromVoltage(self):
18 18
19 19 self.dataOut.timeZone = self.dataIn.timeZone
20 20 self.dataOut.dstFlag = self.dataIn.dstFlag
21 21 self.dataOut.errorCount = self.dataIn.errorCount
22 22 self.dataOut.useLocalTime = self.dataIn.useLocalTime
23 23
24 24 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()#
25 25 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()#
26 26 self.dataOut.channelList = self.dataIn.channelList
27 27 self.dataOut.heightList = self.dataIn.heightList
28 28 # self.dataOut.dtype = self.dataIn.dtype
29 29 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
30 30 # self.dataOut.nHeights = self.dataIn.nHeights
31 31 # self.dataOut.nChannels = self.dataIn.nChannels
32 32 self.dataOut.nBaud = self.dataIn.nBaud
33 33 self.dataOut.nCode = self.dataIn.nCode
34 34 self.dataOut.code = self.dataIn.code
35 35 # self.dataOut.nProfiles = 1
36 36 self.dataOut.ippFactor = 1
37 37 self.dataOut.noise_estimation = None
38 38 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
39 39 self.dataOut.nFFTPoints = self.dataIn.nHeights
40 40 # self.dataOut.channelIndexList = self.dataIn.channelIndexList
41 41 # self.dataOut.flagNoData = self.dataIn.flagNoData
42 42 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
43 43 self.dataOut.utctime = self.dataIn.utctime
44 44 # self.dataOut.utctime = self.firstdatatime
45 45 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
46 46 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
47 47 # self.dataOut.flagShiftFFT = self.dataIn.flagShiftFFT
48 48 self.dataOut.nCohInt = self.dataIn.nCohInt
49 49 self.dataOut.nIncohInt = 1
50 50 # self.dataOut.ippSeconds= self.dataIn.ippSeconds
51 51 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
52 52
53 53 # self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nIncohInt
54 54 # self.dataOut.set=self.dataIn.set
55 55 # self.dataOut.deltaHeight=self.dataIn.deltaHeight
56 56
57 57
58 58 def __updateObjFromFits(self):
59 59
60 60 self.dataOut.utctime = self.dataIn.utctime
61 61 # self.dataOut.channelIndexList = self.dataIn.channelIndexList
62 62
63 63 self.dataOut.channelList = self.dataIn.channelList
64 64 self.dataOut.heightList = self.dataIn.heightList
65 65 self.dataOut.data_spc = self.dataIn.data
66 66 self.dataOut.ippSeconds = self.dataIn.ippSeconds
67 67 self.dataOut.nCohInt = self.dataIn.nCohInt
68 68 self.dataOut.nIncohInt = self.dataIn.nIncohInt
69 69 # self.dataOut.timeInterval = self.dataIn.timeInterval
70 70 self.dataOut.timeZone = self.dataIn.timeZone
71 71 self.dataOut.useLocalTime = True
72 72 # self.dataOut.
73 73 # self.dataOut.
74 74
75 75 def __getFft(self):
76 76
77 77 fft_volt = numpy.fft.fft(self.dataIn.data, axis=1)
78 78 fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,))
79 79 spc = numpy.abs(fft_volt * numpy.conjugate(fft_volt))/(self.dataOut.nFFTPoints)
80 80 self.dataOut.data_spc = spc
81 81
82 82 def run(self):
83 83
84 84 self.dataOut.flagNoData = True
85 85
86 86 if self.dataIn.type == "Fits":
87 87 self.__updateObjFromFits()
88 88 self.dataOut.flagNoData = False
89 89 return
90 90
91 91 if self.dataIn.type == "SpectraHeis":
92 92 self.dataOut.copy(self.dataIn)
93 93 return
94 94
95 95 if self.dataIn.type == "Voltage":
96 96 self.__updateObjFromVoltage()
97 97 self.__getFft()
98 98 self.dataOut.flagNoData = False
99 99
100 100 return
101 101
102 102 raise ValueError, "The type object %s is not valid"%(self.dataIn.type)
103 103
104 104
105 105 def selectChannels(self, channelList):
106 106
107 107 channelIndexList = []
108 108
109 109 for channel in channelList:
110 110 index = self.dataOut.channelList.index(channel)
111 111 channelIndexList.append(index)
112 112
113 113 self.selectChannelsByIndex(channelIndexList)
114 114
115 115 def selectChannelsByIndex(self, channelIndexList):
116 116 """
117 117 Selecciona un bloque de datos en base a canales segun el channelIndexList
118 118
119 119 Input:
120 120 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
121 121
122 122 Affected:
123 123 self.dataOut.data
124 124 self.dataOut.channelIndexList
125 125 self.dataOut.nChannels
126 126 self.dataOut.m_ProcessingHeader.totalSpectra
127 127 self.dataOut.systemHeaderObj.numChannels
128 128 self.dataOut.m_ProcessingHeader.blockSize
129 129
130 130 Return:
131 131 None
132 132 """
133 133
134 134 for channelIndex in channelIndexList:
135 135 if channelIndex not in self.dataOut.channelIndexList:
136 136 print channelIndexList
137 137 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
138 138
139 139 # nChannels = len(channelIndexList)
140 140
141 141 data_spc = self.dataOut.data_spc[channelIndexList,:]
142 142
143 143 self.dataOut.data_spc = data_spc
144 144 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
145 145
146 146 return 1
147 147
148 148 class IncohInt4SpectraHeis(Operation):
149 149
150 150 isConfig = False
151 151
152 152 __profIndex = 0
153 153 __withOverapping = False
154 154
155 155 __byTime = False
156 156 __initime = None
157 157 __lastdatatime = None
158 158 __integrationtime = None
159 159
160 160 __buffer = None
161 161
162 162 __dataReady = False
163 163
164 164 n = None
165 parameters = {
166 'n': global_type_float,
167 'timeInterval': global_type_integer,
168 'overlapping': global_type_boolean,
169 }
165 170
166 171
167 172 def __init__(self, **kwargs):
168 173
169 174 Operation.__init__(self, **kwargs)
170 175 # self.isConfig = False
171 176
172 177 def setup(self, n=None, timeInterval=None, overlapping=False):
173 178 """
174 179 Set the parameters of the integration class.
175 180
176 181 Inputs:
177 182
178 183 n : Number of coherent integrations
179 184 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
180 185 overlapping :
181 186
182 187 """
183 188
184 189 self.__initime = None
185 190 self.__lastdatatime = 0
186 191 self.__buffer = None
187 192 self.__dataReady = False
188 193
189 194
190 195 if n == None and timeInterval == None:
191 196 raise ValueError, "n or timeInterval should be specified ..."
192 197
193 198 if n != None:
194 199 self.n = n
195 200 self.__byTime = False
196 201 else:
197 202 self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line
198 203 self.n = 9999
199 204 self.__byTime = True
200 205
201 206 if overlapping:
202 207 self.__withOverapping = True
203 208 self.__buffer = None
204 209 else:
205 210 self.__withOverapping = False
206 211 self.__buffer = 0
207 212
208 213 self.__profIndex = 0
209 214
210 215 def putData(self, data):
211 216
212 217 """
213 218 Add a profile to the __buffer and increase in one the __profileIndex
214 219
215 220 """
216 221
217 222 if not self.__withOverapping:
218 223 self.__buffer += data.copy()
219 224 self.__profIndex += 1
220 225 return
221 226
222 227 #Overlapping data
223 228 nChannels, nHeis = data.shape
224 229 data = numpy.reshape(data, (1, nChannels, nHeis))
225 230
226 231 #If the buffer is empty then it takes the data value
227 232 if self.__buffer is None:
228 233 self.__buffer = data
229 234 self.__profIndex += 1
230 235 return
231 236
232 237 #If the buffer length is lower than n then stakcing the data value
233 238 if self.__profIndex < self.n:
234 239 self.__buffer = numpy.vstack((self.__buffer, data))
235 240 self.__profIndex += 1
236 241 return
237 242
238 243 #If the buffer length is equal to n then replacing the last buffer value with the data value
239 244 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
240 245 self.__buffer[self.n-1] = data
241 246 self.__profIndex = self.n
242 247 return
243 248
244 249
245 250 def pushData(self):
246 251 """
247 252 Return the sum of the last profiles and the profiles used in the sum.
248 253
249 254 Affected:
250 255
251 256 self.__profileIndex
252 257
253 258 """
254 259
255 260 if not self.__withOverapping:
256 261 data = self.__buffer
257 262 n = self.__profIndex
258 263
259 264 self.__buffer = 0
260 265 self.__profIndex = 0
261 266
262 267 return data, n
263 268
264 269 #Integration with Overlapping
265 270 data = numpy.sum(self.__buffer, axis=0)
266 271 n = self.__profIndex
267 272
268 273 return data, n
269 274
270 275 def byProfiles(self, data):
271 276
272 277 self.__dataReady = False
273 278 avgdata = None
274 279 # n = None
275 280
276 281 self.putData(data)
277 282
278 283 if self.__profIndex == self.n:
279 284
280 285 avgdata, n = self.pushData()
281 286 self.__dataReady = True
282 287
283 288 return avgdata
284 289
285 290 def byTime(self, data, datatime):
286 291
287 292 self.__dataReady = False
288 293 avgdata = None
289 294 n = None
290 295
291 296 self.putData(data)
292 297
293 298 if (datatime - self.__initime) >= self.__integrationtime:
294 299 avgdata, n = self.pushData()
295 300 self.n = n
296 301 self.__dataReady = True
297 302
298 303 return avgdata
299 304
300 305 def integrate(self, data, datatime=None):
301 306
302 307 if self.__initime == None:
303 308 self.__initime = datatime
304 309
305 310 if self.__byTime:
306 311 avgdata = self.byTime(data, datatime)
307 312 else:
308 313 avgdata = self.byProfiles(data)
309 314
310 315
311 316 self.__lastdatatime = datatime
312 317
313 318 if avgdata is None:
314 319 return None, None
315 320
316 321 avgdatatime = self.__initime
317 322
318 323 deltatime = datatime -self.__lastdatatime
319 324
320 325 if not self.__withOverapping:
321 326 self.__initime = datatime
322 327 else:
323 328 self.__initime += deltatime
324 329
325 330 return avgdata, avgdatatime
326 331
327 def run(self, dataOut, **kwargs):
332 def run(self, dataOut, n=None, timeInterval=None, overlapping=False, **kwargs):
328 333
329 334 if not self.isConfig:
330 self.setup(**kwargs)
335 self.setup(n=n, timeInterval=timeInterval, overlapping=overlapping)
331 336 self.isConfig = True
332 337
333 338 avgdata, avgdatatime = self.integrate(dataOut.data_spc, dataOut.utctime)
334 339
335 340 # dataOut.timeInterval *= n
336 341 dataOut.flagNoData = True
337 342
338 343 if self.__dataReady:
339 344 dataOut.data_spc = avgdata
340 345 dataOut.nIncohInt *= self.n
341 346 # dataOut.nCohInt *= self.n
342 347 dataOut.utctime = avgdatatime
343 348 # dataOut.timeInterval = dataOut.ippSeconds * dataOut.nIncohInt
344 349 # dataOut.timeInterval = self.__timeInterval*self.n
345 350 dataOut.flagNoData = False
@@ -1,2749 +1,2764
1 1 import numpy
2 2 import math
3 3 from scipy import optimize, interpolate, signal, stats, ndimage
4 4 import re
5 5 import datetime
6 6 import copy
7 7 import sys
8 8 import importlib
9 9 import itertools
10 10
11 11 from jroproc_base import ProcessingUnit, Operation
12 12 from schainpy.model.data.jrodata import Parameters, hildebrand_sekhon
13 13
14 14
15 15 class ParametersProc(ProcessingUnit):
16 16
17 17 nSeconds = None
18 18
19 19 def __init__(self):
20 20 ProcessingUnit.__init__(self)
21 21
22 22 # self.objectDict = {}
23 23 self.buffer = None
24 24 self.firstdatatime = None
25 25 self.profIndex = 0
26 26 self.dataOut = Parameters()
27 27
28 28 def __updateObjFromInput(self):
29 29
30 30 self.dataOut.inputUnit = self.dataIn.type
31 31
32 32 self.dataOut.timeZone = self.dataIn.timeZone
33 33 self.dataOut.dstFlag = self.dataIn.dstFlag
34 34 self.dataOut.errorCount = self.dataIn.errorCount
35 35 self.dataOut.useLocalTime = self.dataIn.useLocalTime
36 36
37 37 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
38 38 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
39 39 self.dataOut.channelList = self.dataIn.channelList
40 40 self.dataOut.heightList = self.dataIn.heightList
41 41 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
42 42 # self.dataOut.nHeights = self.dataIn.nHeights
43 43 # self.dataOut.nChannels = self.dataIn.nChannels
44 44 self.dataOut.nBaud = self.dataIn.nBaud
45 45 self.dataOut.nCode = self.dataIn.nCode
46 46 self.dataOut.code = self.dataIn.code
47 47 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
48 48 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
49 49 # self.dataOut.utctime = self.firstdatatime
50 50 self.dataOut.utctime = self.dataIn.utctime
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.timeInterval1 = self.dataIn.timeInterval
58 58 self.dataOut.heightList = self.dataIn.getHeiRange()
59 59 self.dataOut.frequency = self.dataIn.frequency
60 60 #self.dataOut.noise = self.dataIn.noise
61 61
62 62 def run(self):
63 63
64 64 #---------------------- Voltage Data ---------------------------
65 65
66 66 if self.dataIn.type == "Voltage":
67 67
68 68 self.__updateObjFromInput()
69 69 self.dataOut.data_pre = self.dataIn.data.copy()
70 70 self.dataOut.flagNoData = False
71 71 self.dataOut.utctimeInit = self.dataIn.utctime
72 72 self.dataOut.paramInterval = self.dataIn.nProfiles*self.dataIn.nCohInt*self.dataIn.ippSeconds
73 73 return
74 74
75 75 #---------------------- Spectra Data ---------------------------
76 76
77 77 if self.dataIn.type == "Spectra":
78 78
79 79 self.dataOut.data_pre = (self.dataIn.data_spc, self.dataIn.data_cspc)
80 80 self.dataOut.data_spc = self.dataIn.data_spc
81 81 self.dataOut.data_cspc = self.dataIn.data_cspc
82 82 self.dataOut.nProfiles = self.dataIn.nProfiles
83 83 self.dataOut.nIncohInt = self.dataIn.nIncohInt
84 84 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
85 85 self.dataOut.ippFactor = self.dataIn.ippFactor
86 86 #self.dataOut.normFactor = self.dataIn.getNormFactor()
87 87 self.dataOut.pairsList = self.dataIn.pairsList
88 88 self.dataOut.groupList = self.dataIn.pairsList
89 89 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
90 90 self.dataOut.flagNoData = False
91 91
92 92 #---------------------- Correlation Data ---------------------------
93 93
94 94 if self.dataIn.type == "Correlation":
95 95 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
96 96
97 97 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
98 98 self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
99 99 self.dataOut.groupList = (acf_pairs, ccf_pairs)
100 100
101 101 self.dataOut.abscissaList = self.dataIn.lagRange
102 102 self.dataOut.noise = self.dataIn.noise
103 103 self.dataOut.data_SNR = self.dataIn.SNR
104 104 self.dataOut.flagNoData = False
105 105 self.dataOut.nAvg = self.dataIn.nAvg
106 106
107 107 #---------------------- Parameters Data ---------------------------
108 108
109 109 if self.dataIn.type == "Parameters":
110 110 self.dataOut.copy(self.dataIn)
111 111 self.dataOut.utctimeInit = self.dataIn.utctime
112 112 self.dataOut.flagNoData = False
113 113
114 114 return True
115 115
116 116 self.__updateObjFromInput()
117 117 self.dataOut.utctimeInit = self.dataIn.utctime
118 118 self.dataOut.paramInterval = self.dataIn.timeInterval
119 119
120 120 return
121 121
122 122 class SpectralMoments(Operation):
123 123
124 124 '''
125 125 Function SpectralMoments()
126 126
127 127 Calculates moments (power, mean, standard deviation) and SNR of the signal
128 128
129 129 Type of dataIn: Spectra
130 130
131 131 Configuration Parameters:
132 132
133 133 dirCosx : Cosine director in X axis
134 134 dirCosy : Cosine director in Y axis
135 135
136 136 elevation :
137 137 azimuth :
138 138
139 139 Input:
140 140 channelList : simple channel list to select e.g. [2,3,7]
141 141 self.dataOut.data_pre : Spectral data
142 142 self.dataOut.abscissaList : List of frequencies
143 143 self.dataOut.noise : Noise level per channel
144 144
145 145 Affected:
146 146 self.dataOut.data_param : Parameters per channel
147 147 self.dataOut.data_SNR : SNR per channel
148 148
149 149 '''
150 150
151 151 def run(self, dataOut):
152 152
153 153 #dataOut.data_pre = dataOut.data_pre[0]
154 154 data = dataOut.data_pre[0]
155 155 absc = dataOut.abscissaList[:-1]
156 156 noise = dataOut.noise
157 157 nChannel = data.shape[0]
158 158 data_param = numpy.zeros((nChannel, 4, data.shape[2]))
159 159
160 160 for ind in range(nChannel):
161 161 data_param[ind,:,:] = self.__calculateMoments(data[ind,:,:], absc, noise[ind])
162 162
163 163 dataOut.data_param = data_param[:,1:,:]
164 164 dataOut.data_SNR = data_param[:,0]
165 165 dataOut.data_DOP = data_param[:,1]
166 166 dataOut.data_MEAN = data_param[:,2]
167 167 dataOut.data_STD = data_param[:,3]
168 168 return
169 169
170 170 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):
171 171
172 172 if (nicoh is None): nicoh = 1
173 173 if (graph is None): graph = 0
174 174 if (smooth is None): smooth = 0
175 175 elif (self.smooth < 3): smooth = 0
176 176
177 177 if (type1 is None): type1 = 0
178 178 if (fwindow is None): fwindow = numpy.zeros(oldfreq.size) + 1
179 179 if (snrth is None): snrth = -3
180 180 if (dc is None): dc = 0
181 181 if (aliasing is None): aliasing = 0
182 182 if (oldfd is None): oldfd = 0
183 183 if (wwauto is None): wwauto = 0
184 184
185 185 if (n0 < 1.e-20): n0 = 1.e-20
186 186
187 187 freq = oldfreq
188 188 vec_power = numpy.zeros(oldspec.shape[1])
189 189 vec_fd = numpy.zeros(oldspec.shape[1])
190 190 vec_w = numpy.zeros(oldspec.shape[1])
191 191 vec_snr = numpy.zeros(oldspec.shape[1])
192 192
193 193 for ind in range(oldspec.shape[1]):
194 194
195 195 spec = oldspec[:,ind]
196 196 aux = spec*fwindow
197 197 max_spec = aux.max()
198 198 m = list(aux).index(max_spec)
199 199
200 200 #Smooth
201 201 if (smooth == 0): spec2 = spec
202 202 else: spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
203 203
204 204 # Calculo de Momentos
205 205 bb = spec2[range(m,spec2.size)]
206 206 bb = (bb<n0).nonzero()
207 207 bb = bb[0]
208 208
209 209 ss = spec2[range(0,m + 1)]
210 210 ss = (ss<n0).nonzero()
211 211 ss = ss[0]
212 212
213 213 if (bb.size == 0):
214 214 bb0 = spec.size - 1 - m
215 215 else:
216 216 bb0 = bb[0] - 1
217 217 if (bb0 < 0):
218 218 bb0 = 0
219 219
220 220 if (ss.size == 0): ss1 = 1
221 221 else: ss1 = max(ss) + 1
222 222
223 223 if (ss1 > m): ss1 = m
224 224
225 225 valid = numpy.asarray(range(int(m + bb0 - ss1 + 1))) + ss1
226 226 power = ((spec2[valid] - n0)*fwindow[valid]).sum()
227 227 fd = ((spec2[valid]- n0)*freq[valid]*fwindow[valid]).sum()/power
228 228 w = math.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum()/power)
229 229 snr = (spec2.mean()-n0)/n0
230 230
231 231 if (snr < 1.e-20) :
232 232 snr = 1.e-20
233 233
234 234 vec_power[ind] = power
235 235 vec_fd[ind] = fd
236 236 vec_w[ind] = w
237 237 vec_snr[ind] = snr
238 238
239 239 moments = numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
240 240 return moments
241 241
242 242 #------------------ Get SA Parameters --------------------------
243 243
244 244 def GetSAParameters(self):
245 245 #SA en frecuencia
246 246 pairslist = self.dataOut.groupList
247 247 num_pairs = len(pairslist)
248 248
249 249 vel = self.dataOut.abscissaList
250 250 spectra = self.dataOut.data_pre[0]
251 251 cspectra = self.dataOut.data_pre[1]
252 252 delta_v = vel[1] - vel[0]
253 253
254 254 #Calculating the power spectrum
255 255 spc_pow = numpy.sum(spectra, 3)*delta_v
256 256 #Normalizing Spectra
257 257 norm_spectra = spectra/spc_pow
258 258 #Calculating the norm_spectra at peak
259 259 max_spectra = numpy.max(norm_spectra, 3)
260 260
261 261 #Normalizing Cross Spectra
262 262 norm_cspectra = numpy.zeros(cspectra.shape)
263 263
264 264 for i in range(num_chan):
265 265 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
266 266
267 267 max_cspectra = numpy.max(norm_cspectra,2)
268 268 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
269 269
270 270 for i in range(num_pairs):
271 271 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
272 272 #------------------- Get Lags ----------------------------------
273 273
274 274 class SALags(Operation):
275 275 '''
276 276 Function GetMoments()
277 277
278 278 Input:
279 279 self.dataOut.data_pre
280 280 self.dataOut.abscissaList
281 281 self.dataOut.noise
282 282 self.dataOut.normFactor
283 283 self.dataOut.data_SNR
284 284 self.dataOut.groupList
285 285 self.dataOut.nChannels
286 286
287 287 Affected:
288 288 self.dataOut.data_param
289 289
290 290 '''
291 291 def run(self, dataOut):
292 292 data_acf = dataOut.data_pre[0]
293 293 data_ccf = dataOut.data_pre[1]
294 294 normFactor_acf = dataOut.normFactor[0]
295 295 normFactor_ccf = dataOut.normFactor[1]
296 296 pairs_acf = dataOut.groupList[0]
297 297 pairs_ccf = dataOut.groupList[1]
298 298
299 299 nHeights = dataOut.nHeights
300 300 absc = dataOut.abscissaList
301 301 noise = dataOut.noise
302 302 SNR = dataOut.data_SNR
303 303 nChannels = dataOut.nChannels
304 304 # pairsList = dataOut.groupList
305 305 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
306 306
307 307 for l in range(len(pairs_acf)):
308 308 data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
309 309
310 310 for l in range(len(pairs_ccf)):
311 311 data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
312 312
313 313 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
314 314 dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
315 315 dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
316 316 return
317 317
318 318 # def __getPairsAutoCorr(self, pairsList, nChannels):
319 319 #
320 320 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
321 321 #
322 322 # for l in range(len(pairsList)):
323 323 # firstChannel = pairsList[l][0]
324 324 # secondChannel = pairsList[l][1]
325 325 #
326 326 # #Obteniendo pares de Autocorrelacion
327 327 # if firstChannel == secondChannel:
328 328 # pairsAutoCorr[firstChannel] = int(l)
329 329 #
330 330 # pairsAutoCorr = pairsAutoCorr.astype(int)
331 331 #
332 332 # pairsCrossCorr = range(len(pairsList))
333 333 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
334 334 #
335 335 # return pairsAutoCorr, pairsCrossCorr
336 336
337 337 def __calculateTaus(self, data_acf, data_ccf, lagRange):
338 338
339 339 lag0 = data_acf.shape[1]/2
340 340 #Funcion de Autocorrelacion
341 341 mean_acf = stats.nanmean(data_acf, axis = 0)
342 342
343 343 #Obtencion Indice de TauCross
344 344 ind_ccf = data_ccf.argmax(axis = 1)
345 345 #Obtencion Indice de TauAuto
346 346 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
347 347 ccf_lag0 = data_ccf[:,lag0,:]
348 348
349 349 for i in range(ccf_lag0.shape[0]):
350 350 ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
351 351
352 352 #Obtencion de TauCross y TauAuto
353 353 tau_ccf = lagRange[ind_ccf]
354 354 tau_acf = lagRange[ind_acf]
355 355
356 356 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
357 357
358 358 tau_ccf[Nan1,Nan2] = numpy.nan
359 359 tau_acf[Nan1,Nan2] = numpy.nan
360 360 tau = numpy.vstack((tau_ccf,tau_acf))
361 361
362 362 return tau
363 363
364 364 def __calculateLag1Phase(self, data, lagTRange):
365 365 data1 = stats.nanmean(data, axis = 0)
366 366 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
367 367
368 368 phase = numpy.angle(data1[lag1,:])
369 369
370 370 return phase
371 371
372 372 class SpectralFitting(Operation):
373 373 '''
374 374 Function GetMoments()
375 375
376 376 Input:
377 377 Output:
378 378 Variables modified:
379 379 '''
380 380
381 381 def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
382 382
383 383
384 384 if path != None:
385 385 sys.path.append(path)
386 386 self.dataOut.library = importlib.import_module(file)
387 387
388 388 #To be inserted as a parameter
389 389 groupArray = numpy.array(groupList)
390 390 # groupArray = numpy.array([[0,1],[2,3]])
391 391 self.dataOut.groupList = groupArray
392 392
393 393 nGroups = groupArray.shape[0]
394 394 nChannels = self.dataIn.nChannels
395 395 nHeights=self.dataIn.heightList.size
396 396
397 397 #Parameters Array
398 398 self.dataOut.data_param = None
399 399
400 400 #Set constants
401 401 constants = self.dataOut.library.setConstants(self.dataIn)
402 402 self.dataOut.constants = constants
403 403 M = self.dataIn.normFactor
404 404 N = self.dataIn.nFFTPoints
405 405 ippSeconds = self.dataIn.ippSeconds
406 406 K = self.dataIn.nIncohInt
407 407 pairsArray = numpy.array(self.dataIn.pairsList)
408 408
409 409 #List of possible combinations
410 410 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
411 411 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
412 412
413 413 if getSNR:
414 414 listChannels = groupArray.reshape((groupArray.size))
415 415 listChannels.sort()
416 416 noise = self.dataIn.getNoise()
417 417 self.dataOut.data_SNR = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
418 418
419 419 for i in range(nGroups):
420 420 coord = groupArray[i,:]
421 421
422 422 #Input data array
423 423 data = self.dataIn.data_spc[coord,:,:]/(M*N)
424 424 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
425 425
426 426 #Cross Spectra data array for Covariance Matrixes
427 427 ind = 0
428 428 for pairs in listComb:
429 429 pairsSel = numpy.array([coord[x],coord[y]])
430 430 indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
431 431 ind += 1
432 432 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
433 433 dataCross = dataCross**2/K
434 434
435 435 for h in range(nHeights):
436 436 # print self.dataOut.heightList[h]
437 437
438 438 #Input
439 439 d = data[:,h]
440 440
441 441 #Covariance Matrix
442 442 D = numpy.diag(d**2/K)
443 443 ind = 0
444 444 for pairs in listComb:
445 445 #Coordinates in Covariance Matrix
446 446 x = pairs[0]
447 447 y = pairs[1]
448 448 #Channel Index
449 449 S12 = dataCross[ind,:,h]
450 450 D12 = numpy.diag(S12)
451 451 #Completing Covariance Matrix with Cross Spectras
452 452 D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
453 453 D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
454 454 ind += 1
455 455 Dinv=numpy.linalg.inv(D)
456 456 L=numpy.linalg.cholesky(Dinv)
457 457 LT=L.T
458 458
459 459 dp = numpy.dot(LT,d)
460 460
461 461 #Initial values
462 462 data_spc = self.dataIn.data_spc[coord,:,h]
463 463
464 464 if (h>0)and(error1[3]<5):
465 465 p0 = self.dataOut.data_param[i,:,h-1]
466 466 else:
467 467 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
468 468
469 469 try:
470 470 #Least Squares
471 471 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
472 472 # minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
473 473 #Chi square error
474 474 error0 = numpy.sum(infodict['fvec']**2)/(2*N)
475 475 #Error with Jacobian
476 476 error1 = self.dataOut.library.errorFunction(minp,constants,LT)
477 477 except:
478 478 minp = p0*numpy.nan
479 479 error0 = numpy.nan
480 480 error1 = p0*numpy.nan
481 481
482 482 #Save
483 483 if self.dataOut.data_param is None:
484 484 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
485 485 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
486 486
487 487 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
488 488 self.dataOut.data_param[i,:,h] = minp
489 489 return
490 490
491 491 def __residFunction(self, p, dp, LT, constants):
492 492
493 493 fm = self.dataOut.library.modelFunction(p, constants)
494 494 fmp=numpy.dot(LT,fm)
495 495
496 496 return dp-fmp
497 497
498 498 def __getSNR(self, z, noise):
499 499
500 500 avg = numpy.average(z, axis=1)
501 501 SNR = (avg.T-noise)/noise
502 502 SNR = SNR.T
503 503 return SNR
504 504
505 505 def __chisq(p,chindex,hindex):
506 506 #similar to Resid but calculates CHI**2
507 507 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
508 508 dp=numpy.dot(LT,d)
509 509 fmp=numpy.dot(LT,fm)
510 510 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
511 511 return chisq
512 512
513 513 class WindProfiler(Operation):
514 514
515 515 __isConfig = False
516 516
517 517 __initime = None
518 518 __lastdatatime = None
519 519 __integrationtime = None
520 520
521 521 __buffer = None
522 522
523 523 __dataReady = False
524 524
525 525 __firstdata = None
526 526
527 527 n = None
528 528
529 529 def __calculateCosDir(self, elev, azim):
530 530 zen = (90 - elev)*numpy.pi/180
531 531 azim = azim*numpy.pi/180
532 532 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
533 533 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
534 534
535 535 signX = numpy.sign(numpy.cos(azim))
536 536 signY = numpy.sign(numpy.sin(azim))
537 537
538 538 cosDirX = numpy.copysign(cosDirX, signX)
539 539 cosDirY = numpy.copysign(cosDirY, signY)
540 540 return cosDirX, cosDirY
541 541
542 542 def __calculateAngles(self, theta_x, theta_y, azimuth):
543 543
544 544 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
545 545 zenith_arr = numpy.arccos(dir_cosw)
546 546 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
547 547
548 548 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
549 549 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
550 550
551 551 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
552 552
553 553 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
554 554
555 555 #
556 556 if horOnly:
557 557 A = numpy.c_[dir_cosu,dir_cosv]
558 558 else:
559 559 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
560 560 A = numpy.asmatrix(A)
561 561 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
562 562
563 563 return A1
564 564
565 565 def __correctValues(self, heiRang, phi, velRadial, SNR):
566 566 listPhi = phi.tolist()
567 567 maxid = listPhi.index(max(listPhi))
568 568 minid = listPhi.index(min(listPhi))
569 569
570 570 rango = range(len(phi))
571 571 # rango = numpy.delete(rango,maxid)
572 572
573 573 heiRang1 = heiRang*math.cos(phi[maxid])
574 574 heiRangAux = heiRang*math.cos(phi[minid])
575 575 indOut = (heiRang1 < heiRangAux[0]).nonzero()
576 576 heiRang1 = numpy.delete(heiRang1,indOut)
577 577
578 578 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
579 579 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
580 580
581 581 for i in rango:
582 582 x = heiRang*math.cos(phi[i])
583 583 y1 = velRadial[i,:]
584 584 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
585 585
586 586 x1 = heiRang1
587 587 y11 = f1(x1)
588 588
589 589 y2 = SNR[i,:]
590 590 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
591 591 y21 = f2(x1)
592 592
593 593 velRadial1[i,:] = y11
594 594 SNR1[i,:] = y21
595 595
596 596 return heiRang1, velRadial1, SNR1
597 597
598 598 def __calculateVelUVW(self, A, velRadial):
599 599
600 600 #Operacion Matricial
601 601 # velUVW = numpy.zeros((velRadial.shape[1],3))
602 602 # for ind in range(velRadial.shape[1]):
603 603 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
604 604 # velUVW = velUVW.transpose()
605 605 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
606 606 velUVW[:,:] = numpy.dot(A,velRadial)
607 607
608 608
609 609 return velUVW
610 610
611 611 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
612 612
613 613 def techniqueDBS(self, kwargs):
614 614 """
615 615 Function that implements Doppler Beam Swinging (DBS) technique.
616 616
617 617 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
618 618 Direction correction (if necessary), Ranges and SNR
619 619
620 620 Output: Winds estimation (Zonal, Meridional and Vertical)
621 621
622 622 Parameters affected: Winds, height range, SNR
623 623 """
624 624 velRadial0 = kwargs['velRadial']
625 625 heiRang = kwargs['heightList']
626 626 SNR0 = kwargs['SNR']
627 627
628 628 if kwargs.has_key('dirCosx') and kwargs.has_key('dirCosy'):
629 629 theta_x = numpy.array(kwargs['dirCosx'])
630 630 theta_y = numpy.array(kwargs['dirCosy'])
631 631 else:
632 632 elev = numpy.array(kwargs['elevation'])
633 633 azim = numpy.array(kwargs['azimuth'])
634 634 theta_x, theta_y = self.__calculateCosDir(elev, azim)
635 635 azimuth = kwargs['correctAzimuth']
636 636 if kwargs.has_key('horizontalOnly'):
637 637 horizontalOnly = kwargs['horizontalOnly']
638 638 else: horizontalOnly = False
639 639 if kwargs.has_key('correctFactor'):
640 640 correctFactor = kwargs['correctFactor']
641 641 else: correctFactor = 1
642 642 if kwargs.has_key('channelList'):
643 643 channelList = kwargs['channelList']
644 644 if len(channelList) == 2:
645 645 horizontalOnly = True
646 646 arrayChannel = numpy.array(channelList)
647 647 param = param[arrayChannel,:,:]
648 648 theta_x = theta_x[arrayChannel]
649 649 theta_y = theta_y[arrayChannel]
650 650
651 651 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
652 652 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
653 653 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
654 654
655 655 #Calculo de Componentes de la velocidad con DBS
656 656 winds = self.__calculateVelUVW(A,velRadial1)
657 657
658 658 return winds, heiRang1, SNR1
659 659
660 660 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
661 661
662 662 nPairs = len(pairs_ccf)
663 663 posx = numpy.asarray(posx)
664 664 posy = numpy.asarray(posy)
665 665
666 666 #Rotacion Inversa para alinear con el azimuth
667 667 if azimuth!= None:
668 668 azimuth = azimuth*math.pi/180
669 669 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
670 670 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
671 671 else:
672 672 posx1 = posx
673 673 posy1 = posy
674 674
675 675 #Calculo de Distancias
676 676 distx = numpy.zeros(nPairs)
677 677 disty = numpy.zeros(nPairs)
678 678 dist = numpy.zeros(nPairs)
679 679 ang = numpy.zeros(nPairs)
680 680
681 681 for i in range(nPairs):
682 682 distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
683 683 disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
684 684 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
685 685 ang[i] = numpy.arctan2(disty[i],distx[i])
686 686
687 687 return distx, disty, dist, ang
688 688 #Calculo de Matrices
689 689 # nPairs = len(pairs)
690 690 # ang1 = numpy.zeros((nPairs, 2, 1))
691 691 # dist1 = numpy.zeros((nPairs, 2, 1))
692 692 #
693 693 # for j in range(nPairs):
694 694 # dist1[j,0,0] = dist[pairs[j][0]]
695 695 # dist1[j,1,0] = dist[pairs[j][1]]
696 696 # ang1[j,0,0] = ang[pairs[j][0]]
697 697 # ang1[j,1,0] = ang[pairs[j][1]]
698 698 #
699 699 # return distx,disty, dist1,ang1
700 700
701 701
702 702 def __calculateVelVer(self, phase, lagTRange, _lambda):
703 703
704 704 Ts = lagTRange[1] - lagTRange[0]
705 705 velW = -_lambda*phase/(4*math.pi*Ts)
706 706
707 707 return velW
708 708
709 709 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
710 710 nPairs = tau1.shape[0]
711 711 nHeights = tau1.shape[1]
712 712 vel = numpy.zeros((nPairs,3,nHeights))
713 713 dist1 = numpy.reshape(dist, (dist.size,1))
714 714
715 715 angCos = numpy.cos(ang)
716 716 angSin = numpy.sin(ang)
717 717
718 718 vel0 = dist1*tau1/(2*tau2**2)
719 719 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
720 720 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
721 721
722 722 ind = numpy.where(numpy.isinf(vel))
723 723 vel[ind] = numpy.nan
724 724
725 725 return vel
726 726
727 727 # def __getPairsAutoCorr(self, pairsList, nChannels):
728 728 #
729 729 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
730 730 #
731 731 # for l in range(len(pairsList)):
732 732 # firstChannel = pairsList[l][0]
733 733 # secondChannel = pairsList[l][1]
734 734 #
735 735 # #Obteniendo pares de Autocorrelacion
736 736 # if firstChannel == secondChannel:
737 737 # pairsAutoCorr[firstChannel] = int(l)
738 738 #
739 739 # pairsAutoCorr = pairsAutoCorr.astype(int)
740 740 #
741 741 # pairsCrossCorr = range(len(pairsList))
742 742 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
743 743 #
744 744 # return pairsAutoCorr, pairsCrossCorr
745 745
746 746 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
747 747 def techniqueSA(self, kwargs):
748 748
749 749 """
750 750 Function that implements Spaced Antenna (SA) technique.
751 751
752 752 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
753 753 Direction correction (if necessary), Ranges and SNR
754 754
755 755 Output: Winds estimation (Zonal, Meridional and Vertical)
756 756
757 757 Parameters affected: Winds
758 758 """
759 759 position_x = kwargs['positionX']
760 760 position_y = kwargs['positionY']
761 761 azimuth = kwargs['azimuth']
762 762
763 763 if kwargs.has_key('correctFactor'):
764 764 correctFactor = kwargs['correctFactor']
765 765 else:
766 766 correctFactor = 1
767 767
768 768 groupList = kwargs['groupList']
769 769 pairs_ccf = groupList[1]
770 770 tau = kwargs['tau']
771 771 _lambda = kwargs['_lambda']
772 772
773 773 #Cross Correlation pairs obtained
774 774 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
775 775 # pairsArray = numpy.array(pairsList)[pairsCrossCorr]
776 776 # pairsSelArray = numpy.array(pairsSelected)
777 777 # pairs = []
778 778 #
779 779 # #Wind estimation pairs obtained
780 780 # for i in range(pairsSelArray.shape[0]/2):
781 781 # ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
782 782 # ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
783 783 # pairs.append((ind1,ind2))
784 784
785 785 indtau = tau.shape[0]/2
786 786 tau1 = tau[:indtau,:]
787 787 tau2 = tau[indtau:-1,:]
788 788 # tau1 = tau1[pairs,:]
789 789 # tau2 = tau2[pairs,:]
790 790 phase1 = tau[-1,:]
791 791
792 792 #---------------------------------------------------------------------
793 793 #Metodo Directo
794 794 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
795 795 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
796 796 winds = stats.nanmean(winds, axis=0)
797 797 #---------------------------------------------------------------------
798 798 #Metodo General
799 799 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
800 800 # #Calculo Coeficientes de Funcion de Correlacion
801 801 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
802 802 # #Calculo de Velocidades
803 803 # winds = self.calculateVelUV(F,G,A,B,H)
804 804
805 805 #---------------------------------------------------------------------
806 806 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
807 807 winds = correctFactor*winds
808 808 return winds
809 809
810 810 def __checkTime(self, currentTime, paramInterval, outputInterval):
811 811
812 812 dataTime = currentTime + paramInterval
813 813 deltaTime = dataTime - self.__initime
814 814
815 815 if deltaTime >= outputInterval or deltaTime < 0:
816 816 self.__dataReady = True
817 817 return
818 818
819 819 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax, binkm=2):
820 820 '''
821 821 Function that implements winds estimation technique with detected meteors.
822 822
823 823 Input: Detected meteors, Minimum meteor quantity to wind estimation
824 824
825 825 Output: Winds estimation (Zonal and Meridional)
826 826
827 827 Parameters affected: Winds
828 828 '''
829 829 # print arrayMeteor.shape
830 830 #Settings
831 831 nInt = (heightMax - heightMin)/binkm
832 832 # print nInt
833 833 nInt = int(nInt)
834 834 # print nInt
835 835 winds = numpy.zeros((2,nInt))*numpy.nan
836 836
837 837 #Filter errors
838 838 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
839 839 finalMeteor = arrayMeteor[error,:]
840 840
841 841 #Meteor Histogram
842 842 finalHeights = finalMeteor[:,2]
843 843 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
844 844 nMeteorsPerI = hist[0]
845 845 heightPerI = hist[1]
846 846
847 847 #Sort of meteors
848 848 indSort = finalHeights.argsort()
849 849 finalMeteor2 = finalMeteor[indSort,:]
850 850
851 851 # Calculating winds
852 852 ind1 = 0
853 853 ind2 = 0
854 854
855 855 for i in range(nInt):
856 856 nMet = nMeteorsPerI[i]
857 857 ind1 = ind2
858 858 ind2 = ind1 + nMet
859 859
860 860 meteorAux = finalMeteor2[ind1:ind2,:]
861 861
862 862 if meteorAux.shape[0] >= meteorThresh:
863 863 vel = meteorAux[:, 6]
864 864 zen = meteorAux[:, 4]*numpy.pi/180
865 865 azim = meteorAux[:, 3]*numpy.pi/180
866 866
867 867 n = numpy.cos(zen)
868 868 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
869 869 # l = m*numpy.tan(azim)
870 870 l = numpy.sin(zen)*numpy.sin(azim)
871 871 m = numpy.sin(zen)*numpy.cos(azim)
872 872
873 873 A = numpy.vstack((l, m)).transpose()
874 874 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
875 875 windsAux = numpy.dot(A1, vel)
876 876
877 877 winds[0,i] = windsAux[0]
878 878 winds[1,i] = windsAux[1]
879 879
880 880 return winds, heightPerI[:-1]
881 881
882 882 def techniqueNSM_SA(self, **kwargs):
883 883 metArray = kwargs['metArray']
884 884 heightList = kwargs['heightList']
885 885 timeList = kwargs['timeList']
886 886
887 887 rx_location = kwargs['rx_location']
888 888 groupList = kwargs['groupList']
889 889 azimuth = kwargs['azimuth']
890 890 dfactor = kwargs['dfactor']
891 891 k = kwargs['k']
892 892
893 893 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
894 894 d = dist*dfactor
895 895 #Phase calculation
896 896 metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
897 897
898 898 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
899 899
900 900 velEst = numpy.zeros((heightList.size,2))*numpy.nan
901 901 azimuth1 = azimuth1*numpy.pi/180
902 902
903 903 for i in range(heightList.size):
904 904 h = heightList[i]
905 905 indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
906 906 metHeight = metArray1[indH,:]
907 907 if metHeight.shape[0] >= 2:
908 908 velAux = numpy.asmatrix(metHeight[:,-2]).T #Radial Velocities
909 909 iazim = metHeight[:,1].astype(int)
910 910 azimAux = numpy.asmatrix(azimuth1[iazim]).T #Azimuths
911 911 A = numpy.hstack((numpy.cos(azimAux),numpy.sin(azimAux)))
912 912 A = numpy.asmatrix(A)
913 913 A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
914 914 velHor = numpy.dot(A1,velAux)
915 915
916 916 velEst[i,:] = numpy.squeeze(velHor)
917 917 return velEst
918 918
919 919 def __getPhaseSlope(self, metArray, heightList, timeList):
920 920 meteorList = []
921 921 #utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
922 922 #Putting back together the meteor matrix
923 923 utctime = metArray[:,0]
924 924 uniqueTime = numpy.unique(utctime)
925 925
926 926 phaseDerThresh = 0.5
927 927 ippSeconds = timeList[1] - timeList[0]
928 928 sec = numpy.where(timeList>1)[0][0]
929 929 nPairs = metArray.shape[1] - 6
930 930 nHeights = len(heightList)
931 931
932 932 for t in uniqueTime:
933 933 metArray1 = metArray[utctime==t,:]
934 934 # phaseDerThresh = numpy.pi/4 #reducir Phase thresh
935 935 tmet = metArray1[:,1].astype(int)
936 936 hmet = metArray1[:,2].astype(int)
937 937
938 938 metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
939 939 metPhase[:,:] = numpy.nan
940 940 metPhase[:,hmet,tmet] = metArray1[:,6:].T
941 941
942 942 #Delete short trails
943 943 metBool = ~numpy.isnan(metPhase[0,:,:])
944 944 heightVect = numpy.sum(metBool, axis = 1)
945 945 metBool[heightVect<sec,:] = False
946 946 metPhase[:,heightVect<sec,:] = numpy.nan
947 947
948 948 #Derivative
949 949 metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
950 950 phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
951 951 metPhase[phDerAux] = numpy.nan
952 952
953 953 #--------------------------METEOR DETECTION -----------------------------------------
954 954 indMet = numpy.where(numpy.any(metBool,axis=1))[0]
955 955
956 956 for p in numpy.arange(nPairs):
957 957 phase = metPhase[p,:,:]
958 958 phDer = metDer[p,:,:]
959 959
960 960 for h in indMet:
961 961 height = heightList[h]
962 962 phase1 = phase[h,:] #82
963 963 phDer1 = phDer[h,:]
964 964
965 965 phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
966 966
967 967 indValid = numpy.where(~numpy.isnan(phase1))[0]
968 968 initMet = indValid[0]
969 969 endMet = 0
970 970
971 971 for i in range(len(indValid)-1):
972 972
973 973 #Time difference
974 974 inow = indValid[i]
975 975 inext = indValid[i+1]
976 976 idiff = inext - inow
977 977 #Phase difference
978 978 phDiff = numpy.abs(phase1[inext] - phase1[inow])
979 979
980 980 if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
981 981 sizeTrail = inow - initMet + 1
982 982 if sizeTrail>3*sec: #Too short meteors
983 983 x = numpy.arange(initMet,inow+1)*ippSeconds
984 984 y = phase1[initMet:inow+1]
985 985 ynnan = ~numpy.isnan(y)
986 986 x = x[ynnan]
987 987 y = y[ynnan]
988 988 slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
989 989 ylin = x*slope + intercept
990 990 rsq = r_value**2
991 991 if rsq > 0.5:
992 992 vel = slope#*height*1000/(k*d)
993 993 estAux = numpy.array([utctime,p,height, vel, rsq])
994 994 meteorList.append(estAux)
995 995 initMet = inext
996 996 metArray2 = numpy.array(meteorList)
997 997
998 998 return metArray2
999 999
1000 1000 def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
1001 1001
1002 1002 azimuth1 = numpy.zeros(len(pairslist))
1003 1003 dist = numpy.zeros(len(pairslist))
1004 1004
1005 1005 for i in range(len(rx_location)):
1006 1006 ch0 = pairslist[i][0]
1007 1007 ch1 = pairslist[i][1]
1008 1008
1009 1009 diffX = rx_location[ch0][0] - rx_location[ch1][0]
1010 1010 diffY = rx_location[ch0][1] - rx_location[ch1][1]
1011 1011 azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
1012 1012 dist[i] = numpy.sqrt(diffX**2 + diffY**2)
1013 1013
1014 1014 azimuth1 -= azimuth0
1015 1015 return azimuth1, dist
1016 1016
1017 1017 def techniqueNSM_DBS(self, **kwargs):
1018 1018 metArray = kwargs['metArray']
1019 1019 heightList = kwargs['heightList']
1020 1020 timeList = kwargs['timeList']
1021 1021 zenithList = kwargs['zenithList']
1022 1022 nChan = numpy.max(cmet) + 1
1023 1023 nHeights = len(heightList)
1024 1024
1025 1025 utctime = metArray[:,0]
1026 1026 cmet = metArray[:,1]
1027 1027 hmet = metArray1[:,3].astype(int)
1028 1028 h1met = heightList[hmet]*zenithList[cmet]
1029 1029 vmet = metArray1[:,5]
1030 1030
1031 1031 for i in range(nHeights - 1):
1032 1032 hmin = heightList[i]
1033 1033 hmax = heightList[i + 1]
1034 1034
1035 1035 vthisH = vmet[(h1met>=hmin) & (h1met<hmax)]
1036 1036
1037 1037
1038 1038
1039 1039 return data_output
1040 1040
1041 1041 def run(self, dataOut, technique, **kwargs):
1042 1042
1043 1043 param = dataOut.data_param
1044 1044 if dataOut.abscissaList != None:
1045 1045 absc = dataOut.abscissaList[:-1]
1046 1046 #noise = dataOut.noise
1047 1047 heightList = dataOut.heightList
1048 1048 SNR = dataOut.data_SNR
1049 1049
1050 1050 if technique == 'DBS':
1051 1051
1052 1052 kwargs['velRadial'] = param[:,1,:] #Radial velocity
1053 1053 kwargs['heightList'] = heightList
1054 1054 kwargs['SNR'] = SNR
1055 1055
1056 1056 dataOut.data_output, dataOut.heightList, dataOut.data_SNR = self.techniqueDBS(kwargs) #DBS Function
1057 1057 dataOut.utctimeInit = dataOut.utctime
1058 1058 dataOut.outputInterval = dataOut.paramInterval
1059 1059
1060 1060 elif technique == 'SA':
1061 1061
1062 1062 #Parameters
1063 1063 # position_x = kwargs['positionX']
1064 1064 # position_y = kwargs['positionY']
1065 1065 # azimuth = kwargs['azimuth']
1066 1066 #
1067 1067 # if kwargs.has_key('crosspairsList'):
1068 1068 # pairs = kwargs['crosspairsList']
1069 1069 # else:
1070 1070 # pairs = None
1071 1071 #
1072 1072 # if kwargs.has_key('correctFactor'):
1073 1073 # correctFactor = kwargs['correctFactor']
1074 1074 # else:
1075 1075 # correctFactor = 1
1076 1076
1077 1077 # tau = dataOut.data_param
1078 1078 # _lambda = dataOut.C/dataOut.frequency
1079 1079 # pairsList = dataOut.groupList
1080 1080 # nChannels = dataOut.nChannels
1081 1081
1082 1082 kwargs['groupList'] = dataOut.groupList
1083 1083 kwargs['tau'] = dataOut.data_param
1084 1084 kwargs['_lambda'] = dataOut.C/dataOut.frequency
1085 1085 # dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
1086 1086 dataOut.data_output = self.techniqueSA(kwargs)
1087 1087 dataOut.utctimeInit = dataOut.utctime
1088 1088 dataOut.outputInterval = dataOut.timeInterval
1089 1089
1090 1090 elif technique == 'Meteors':
1091 1091 dataOut.flagNoData = True
1092 1092 self.__dataReady = False
1093 1093
1094 1094 if kwargs.has_key('nHours'):
1095 1095 nHours = kwargs['nHours']
1096 1096 else:
1097 1097 nHours = 1
1098 1098
1099 1099 if kwargs.has_key('meteorsPerBin'):
1100 1100 meteorThresh = kwargs['meteorsPerBin']
1101 1101 else:
1102 1102 meteorThresh = 6
1103 1103
1104 1104 if kwargs.has_key('hmin'):
1105 1105 hmin = kwargs['hmin']
1106 1106 else: hmin = 70
1107 1107 if kwargs.has_key('hmax'):
1108 1108 hmax = kwargs['hmax']
1109 1109 else: hmax = 110
1110 1110
1111 1111 if kwargs.has_key('BinKm'):
1112 1112 binkm = kwargs['BinKm']
1113 1113 else:
1114 1114 binkm = 2
1115 1115
1116 1116 dataOut.outputInterval = nHours*3600
1117 1117
1118 1118 if self.__isConfig == False:
1119 1119 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
1120 1120 #Get Initial LTC time
1121 1121 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
1122 1122 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
1123 1123
1124 1124 self.__isConfig = True
1125 1125
1126 1126 if self.__buffer is None:
1127 1127 self.__buffer = dataOut.data_param
1128 1128 self.__firstdata = copy.copy(dataOut)
1129 1129
1130 1130 else:
1131 1131 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
1132 1132
1133 1133 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
1134 1134
1135 1135 if self.__dataReady:
1136 1136 dataOut.utctimeInit = self.__initime
1137 1137
1138 1138 self.__initime += dataOut.outputInterval #to erase time offset
1139 1139
1140 1140 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax, binkm)
1141 1141 dataOut.flagNoData = False
1142 1142 self.__buffer = None
1143 1143
1144 1144 elif technique == 'Meteors1':
1145 1145 dataOut.flagNoData = True
1146 1146 self.__dataReady = False
1147 1147
1148 1148 if kwargs.has_key('nMins'):
1149 1149 nMins = kwargs['nMins']
1150 1150 else: nMins = 20
1151 1151 if kwargs.has_key('rx_location'):
1152 1152 rx_location = kwargs['rx_location']
1153 1153 else: rx_location = [(0,1),(1,1),(1,0)]
1154 1154 if kwargs.has_key('azimuth'):
1155 1155 azimuth = kwargs['azimuth']
1156 1156 else: azimuth = 51
1157 1157 if kwargs.has_key('dfactor'):
1158 1158 dfactor = kwargs['dfactor']
1159 1159 if kwargs.has_key('mode'):
1160 1160 mode = kwargs['mode']
1161 1161 else: mode = 'SA'
1162 1162
1163 1163 #Borrar luego esto
1164 1164 if dataOut.groupList is None:
1165 1165 dataOut.groupList = [(0,1),(0,2),(1,2)]
1166 1166 groupList = dataOut.groupList
1167 1167 C = 3e8
1168 1168 freq = 50e6
1169 1169 lamb = C/freq
1170 1170 k = 2*numpy.pi/lamb
1171 1171
1172 1172 timeList = dataOut.abscissaList
1173 1173 heightList = dataOut.heightList
1174 1174
1175 1175 if self.__isConfig == False:
1176 1176 dataOut.outputInterval = nMins*60
1177 1177 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
1178 1178 #Get Initial LTC time
1179 1179 initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
1180 1180 minuteAux = initime.minute
1181 1181 minuteNew = int(numpy.floor(minuteAux/nMins)*nMins)
1182 1182 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
1183 1183
1184 1184 self.__isConfig = True
1185 1185
1186 1186 if self.__buffer is None:
1187 1187 self.__buffer = dataOut.data_param
1188 1188 self.__firstdata = copy.copy(dataOut)
1189 1189
1190 1190 else:
1191 1191 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
1192 1192
1193 1193 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
1194 1194
1195 1195 if self.__dataReady:
1196 1196 dataOut.utctimeInit = self.__initime
1197 1197 self.__initime += dataOut.outputInterval #to erase time offset
1198 1198
1199 1199 metArray = self.__buffer
1200 1200 if mode == 'SA':
1201 1201 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
1202 1202 elif mode == 'DBS':
1203 1203 dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList)
1204 1204 dataOut.data_output = dataOut.data_output.T
1205 1205 dataOut.flagNoData = False
1206 1206 self.__buffer = None
1207 1207
1208 1208 return
1209 1209
1210 1210 class EWDriftsEstimation(Operation):
1211 1211
1212 1212
1213 1213 def __correctValues(self, heiRang, phi, velRadial, SNR):
1214 1214 listPhi = phi.tolist()
1215 1215 maxid = listPhi.index(max(listPhi))
1216 1216 minid = listPhi.index(min(listPhi))
1217 1217
1218 1218 rango = range(len(phi))
1219 1219 # rango = numpy.delete(rango,maxid)
1220 1220
1221 1221 heiRang1 = heiRang*math.cos(phi[maxid])
1222 1222 heiRangAux = heiRang*math.cos(phi[minid])
1223 1223 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1224 1224 heiRang1 = numpy.delete(heiRang1,indOut)
1225 1225
1226 1226 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1227 1227 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1228 1228
1229 1229 for i in rango:
1230 1230 x = heiRang*math.cos(phi[i])
1231 1231 y1 = velRadial[i,:]
1232 1232 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1233 1233
1234 1234 x1 = heiRang1
1235 1235 y11 = f1(x1)
1236 1236
1237 1237 y2 = SNR[i,:]
1238 1238 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1239 1239 y21 = f2(x1)
1240 1240
1241 1241 velRadial1[i,:] = y11
1242 1242 SNR1[i,:] = y21
1243 1243
1244 1244 return heiRang1, velRadial1, SNR1
1245 1245
1246 1246 def run(self, dataOut, zenith, zenithCorrection):
1247 1247 heiRang = dataOut.heightList
1248 1248 velRadial = dataOut.data_param[:,3,:]
1249 1249 SNR = dataOut.data_SNR
1250 1250
1251 1251 zenith = numpy.array(zenith)
1252 1252 zenith -= zenithCorrection
1253 1253 zenith *= numpy.pi/180
1254 1254
1255 1255 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
1256 1256
1257 1257 alp = zenith[0]
1258 1258 bet = zenith[1]
1259 1259
1260 1260 w_w = velRadial1[0,:]
1261 1261 w_e = velRadial1[1,:]
1262 1262
1263 1263 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
1264 1264 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
1265 1265
1266 1266 winds = numpy.vstack((u,w))
1267 1267
1268 1268 dataOut.heightList = heiRang1
1269 1269 dataOut.data_output = winds
1270 1270 dataOut.data_SNR = SNR1
1271 1271
1272 1272 dataOut.utctimeInit = dataOut.utctime
1273 1273 dataOut.outputInterval = dataOut.timeInterval
1274 1274 return
1275 1275
1276 1276 #--------------- Non Specular Meteor ----------------
1277 1277
1278 1278 class NonSpecularMeteorDetection(Operation):
1279 1279
1280 parameters = {
1281 'mode': global_type_string,
1282 'SNRthresh': global_type_float,
1283 'phaseDerThresh': global_type_float,
1284 'cohThresh': global_type_float,
1285 'allData': global_type_boolean,
1286 }
1287
1280 1288 def run(self, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False):
1281 1289 data_acf = self.dataOut.data_pre[0]
1282 1290 data_ccf = self.dataOut.data_pre[1]
1283 1291
1284 1292 lamb = self.dataOut.C/self.dataOut.frequency
1285 1293 tSamp = self.dataOut.ippSeconds*self.dataOut.nCohInt
1286 1294 paramInterval = self.dataOut.paramInterval
1287 1295
1288 1296 nChannels = data_acf.shape[0]
1289 1297 nLags = data_acf.shape[1]
1290 1298 nProfiles = data_acf.shape[2]
1291 1299 nHeights = self.dataOut.nHeights
1292 1300 nCohInt = self.dataOut.nCohInt
1293 1301 sec = numpy.round(nProfiles/self.dataOut.paramInterval)
1294 1302 heightList = self.dataOut.heightList
1295 1303 ippSeconds = self.dataOut.ippSeconds*self.dataOut.nCohInt*self.dataOut.nAvg
1296 1304 utctime = self.dataOut.utctime
1297 1305
1298 1306 self.dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
1299 1307
1300 1308 #------------------------ SNR --------------------------------------
1301 1309 power = data_acf[:,0,:,:].real
1302 1310 noise = numpy.zeros(nChannels)
1303 1311 SNR = numpy.zeros(power.shape)
1304 1312 for i in range(nChannels):
1305 1313 noise[i] = hildebrand_sekhon(power[i,:], nCohInt)
1306 1314 SNR[i] = (power[i]-noise[i])/noise[i]
1307 1315 SNRm = numpy.nanmean(SNR, axis = 0)
1308 1316 SNRdB = 10*numpy.log10(SNR)
1309 1317
1310 1318 if mode == 'SA':
1311 1319 nPairs = data_ccf.shape[0]
1312 1320 #---------------------- Coherence and Phase --------------------------
1313 1321 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
1314 1322 # phase1 = numpy.copy(phase)
1315 1323 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
1316 1324
1317 1325 for p in range(nPairs):
1318 1326 ch0 = self.dataOut.groupList[p][0]
1319 1327 ch1 = self.dataOut.groupList[p][1]
1320 1328 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
1321 1329 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
1322 1330 # phase1[p,:,:] = numpy.angle(ccf) #median filter
1323 1331 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
1324 1332 # coh1[p,:,:] = numpy.abs(ccf) #median filter
1325 1333 coh = numpy.nanmax(coh1, axis = 0)
1326 1334 # struc = numpy.ones((5,1))
1327 1335 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
1328 1336 #---------------------- Radial Velocity ----------------------------
1329 1337 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
1330 1338 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
1331 1339
1332 1340 if allData:
1333 1341 boolMetFin = ~numpy.isnan(SNRm)
1334 1342 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
1335 1343 else:
1336 1344 #------------------------ Meteor mask ---------------------------------
1337 1345 # #SNR mask
1338 1346 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
1339 1347 #
1340 1348 # #Erase small objects
1341 1349 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
1342 1350 #
1343 1351 # auxEEJ = numpy.sum(boolMet1,axis=0)
1344 1352 # indOver = auxEEJ>nProfiles*0.8 #Use this later
1345 1353 # indEEJ = numpy.where(indOver)[0]
1346 1354 # indNEEJ = numpy.where(~indOver)[0]
1347 1355 #
1348 1356 # boolMetFin = boolMet1
1349 1357 #
1350 1358 # if indEEJ.size > 0:
1351 1359 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
1352 1360 #
1353 1361 # boolMet2 = coh > cohThresh
1354 1362 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
1355 1363 #
1356 1364 # #Final Meteor mask
1357 1365 # boolMetFin = boolMet1|boolMet2
1358 1366
1359 1367 #Coherence mask
1360 1368 boolMet1 = coh > 0.75
1361 1369 struc = numpy.ones((30,1))
1362 1370 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
1363 1371
1364 1372 #Derivative mask
1365 1373 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
1366 1374 boolMet2 = derPhase < 0.2
1367 1375 # boolMet2 = ndimage.morphology.binary_opening(boolMet2)
1368 1376 # boolMet2 = ndimage.morphology.binary_closing(boolMet2, structure = numpy.ones((10,1)))
1369 1377 boolMet2 = ndimage.median_filter(boolMet2,size=5)
1370 1378 boolMet2 = numpy.vstack((boolMet2,numpy.full((1,nHeights), True, dtype=bool)))
1371 1379 # #Final mask
1372 1380 # boolMetFin = boolMet2
1373 1381 boolMetFin = boolMet1&boolMet2
1374 1382 # boolMetFin = ndimage.morphology.binary_dilation(boolMetFin)
1375 1383 #Creating data_param
1376 1384 coordMet = numpy.where(boolMetFin)
1377 1385
1378 1386 tmet = coordMet[0]
1379 1387 hmet = coordMet[1]
1380 1388
1381 1389 data_param = numpy.zeros((tmet.size, 6 + nPairs))
1382 1390 data_param[:,0] = utctime
1383 1391 data_param[:,1] = tmet
1384 1392 data_param[:,2] = hmet
1385 1393 data_param[:,3] = SNRm[tmet,hmet]
1386 1394 data_param[:,4] = velRad[tmet,hmet]
1387 1395 data_param[:,5] = coh[tmet,hmet]
1388 1396 data_param[:,6:] = phase[:,tmet,hmet].T
1389 1397
1390 1398 elif mode == 'DBS':
1391 1399 self.dataOut.groupList = numpy.arange(nChannels)
1392 1400
1393 1401 #Radial Velocities
1394 1402 # phase = numpy.angle(data_acf[:,1,:,:])
1395 1403 phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
1396 1404 velRad = phase*lamb/(4*numpy.pi*tSamp)
1397 1405
1398 1406 #Spectral width
1399 1407 acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
1400 1408 acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
1401 1409
1402 1410 spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2))
1403 1411 # velRad = ndimage.median_filter(velRad, size = (1,5,1))
1404 1412 if allData:
1405 1413 boolMetFin = ~numpy.isnan(SNRdB)
1406 1414 else:
1407 1415 #SNR
1408 1416 boolMet1 = (SNRdB>SNRthresh) #SNR mask
1409 1417 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
1410 1418
1411 1419 #Radial velocity
1412 1420 boolMet2 = numpy.abs(velRad) < 30
1413 1421 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
1414 1422
1415 1423 #Spectral Width
1416 1424 boolMet3 = spcWidth < 30
1417 1425 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
1418 1426 # boolMetFin = self.__erase_small(boolMet1, 10,5)
1419 1427 boolMetFin = boolMet1&boolMet2&boolMet3
1420 1428
1421 1429 #Creating data_param
1422 1430 coordMet = numpy.where(boolMetFin)
1423 1431
1424 1432 cmet = coordMet[0]
1425 1433 tmet = coordMet[1]
1426 1434 hmet = coordMet[2]
1427 1435
1428 1436 data_param = numpy.zeros((tmet.size, 7))
1429 1437 data_param[:,0] = utctime
1430 1438 data_param[:,1] = cmet
1431 1439 data_param[:,2] = tmet
1432 1440 data_param[:,3] = hmet
1433 1441 data_param[:,4] = SNR[cmet,tmet,hmet].T
1434 1442 data_param[:,5] = velRad[cmet,tmet,hmet].T
1435 1443 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
1436 1444
1437 1445 # self.dataOut.data_param = data_int
1438 1446 if len(data_param) == 0:
1439 1447 self.dataOut.flagNoData = True
1440 1448 else:
1441 1449 self.dataOut.data_param = data_param
1442 1450
1443 1451 def __erase_small(self, binArray, threshX, threshY):
1444 1452 labarray, numfeat = ndimage.measurements.label(binArray)
1445 1453 binArray1 = numpy.copy(binArray)
1446 1454
1447 1455 for i in range(1,numfeat + 1):
1448 1456 auxBin = (labarray==i)
1449 1457 auxSize = auxBin.sum()
1450 1458
1451 1459 x,y = numpy.where(auxBin)
1452 1460 widthX = x.max() - x.min()
1453 1461 widthY = y.max() - y.min()
1454 1462
1455 1463 #width X: 3 seg -> 12.5*3
1456 1464 #width Y:
1457 1465
1458 1466 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
1459 1467 binArray1[auxBin] = False
1460 1468
1461 1469 return binArray1
1462 1470
1463 1471 #--------------- Specular Meteor ----------------
1464 1472
1465 1473 class SMDetection(Operation):
1466 1474 '''
1467 1475 Function DetectMeteors()
1468 1476 Project developed with paper:
1469 1477 HOLDSWORTH ET AL. 2004
1470 1478
1471 1479 Input:
1472 1480 self.dataOut.data_pre
1473 1481
1474 1482 centerReceiverIndex: From the channels, which is the center receiver
1475 1483
1476 1484 hei_ref: Height reference for the Beacon signal extraction
1477 1485 tauindex:
1478 1486 predefinedPhaseShifts: Predefined phase offset for the voltge signals
1479 1487
1480 1488 cohDetection: Whether to user Coherent detection or not
1481 1489 cohDet_timeStep: Coherent Detection calculation time step
1482 1490 cohDet_thresh: Coherent Detection phase threshold to correct phases
1483 1491
1484 1492 noise_timeStep: Noise calculation time step
1485 1493 noise_multiple: Noise multiple to define signal threshold
1486 1494
1487 1495 multDet_timeLimit: Multiple Detection Removal time limit in seconds
1488 1496 multDet_rangeLimit: Multiple Detection Removal range limit in km
1489 1497
1490 1498 phaseThresh: Maximum phase difference between receiver to be consider a meteor
1491 1499 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
1492 1500
1493 1501 hmin: Minimum Height of the meteor to use it in the further wind estimations
1494 1502 hmax: Maximum Height of the meteor to use it in the further wind estimations
1495 1503 azimuth: Azimuth angle correction
1496 1504
1497 1505 Affected:
1498 1506 self.dataOut.data_param
1499 1507
1500 1508 Rejection Criteria (Errors):
1501 1509 0: No error; analysis OK
1502 1510 1: SNR < SNR threshold
1503 1511 2: angle of arrival (AOA) ambiguously determined
1504 1512 3: AOA estimate not feasible
1505 1513 4: Large difference in AOAs obtained from different antenna baselines
1506 1514 5: echo at start or end of time series
1507 1515 6: echo less than 5 examples long; too short for analysis
1508 1516 7: echo rise exceeds 0.3s
1509 1517 8: echo decay time less than twice rise time
1510 1518 9: large power level before echo
1511 1519 10: large power level after echo
1512 1520 11: poor fit to amplitude for estimation of decay time
1513 1521 12: poor fit to CCF phase variation for estimation of radial drift velocity
1514 1522 13: height unresolvable echo: not valid height within 70 to 110 km
1515 1523 14: height ambiguous echo: more then one possible height within 70 to 110 km
1516 1524 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
1517 1525 16: oscilatory echo, indicating event most likely not an underdense echo
1518 1526
1519 1527 17: phase difference in meteor Reestimation
1520 1528
1521 1529 Data Storage:
1522 1530 Meteors for Wind Estimation (8):
1523 1531 Utc Time | Range Height
1524 1532 Azimuth Zenith errorCosDir
1525 1533 VelRad errorVelRad
1526 1534 Phase0 Phase1 Phase2 Phase3
1527 1535 TypeError
1528 1536
1529 1537 '''
1530 1538
1531 1539 def run(self, dataOut, hei_ref = None, tauindex = 0,
1532 1540 phaseOffsets = None,
1533 1541 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
1534 1542 noise_timeStep = 4, noise_multiple = 4,
1535 1543 multDet_timeLimit = 1, multDet_rangeLimit = 3,
1536 1544 phaseThresh = 20, SNRThresh = 5,
1537 1545 hmin = 50, hmax=150, azimuth = 0,
1538 1546 channelPositions = None) :
1539 1547
1540 1548
1541 1549 #Getting Pairslist
1542 1550 if channelPositions is None:
1543 1551 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
1544 1552 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
1545 1553 meteorOps = SMOperations()
1546 1554 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
1547 1555 heiRang = dataOut.getHeiRange()
1548 1556 #Get Beacon signal - No Beacon signal anymore
1549 1557 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
1550 1558 #
1551 1559 # if hei_ref != None:
1552 1560 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
1553 1561 #
1554 1562
1555 1563
1556 1564 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
1557 1565 # see if the user put in pre defined phase shifts
1558 1566 voltsPShift = dataOut.data_pre.copy()
1559 1567
1560 1568 # if predefinedPhaseShifts != None:
1561 1569 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
1562 1570 #
1563 1571 # # elif beaconPhaseShifts:
1564 1572 # # #get hardware phase shifts using beacon signal
1565 1573 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
1566 1574 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
1567 1575 #
1568 1576 # else:
1569 1577 # hardwarePhaseShifts = numpy.zeros(5)
1570 1578 #
1571 1579 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
1572 1580 # for i in range(self.dataOut.data_pre.shape[0]):
1573 1581 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
1574 1582
1575 1583 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
1576 1584
1577 1585 #Remove DC
1578 1586 voltsDC = numpy.mean(voltsPShift,1)
1579 1587 voltsDC = numpy.mean(voltsDC,1)
1580 1588 for i in range(voltsDC.shape[0]):
1581 1589 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
1582 1590
1583 1591 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
1584 1592 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
1585 1593
1586 1594 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
1587 1595 #Coherent Detection
1588 1596 if cohDetection:
1589 1597 #use coherent detection to get the net power
1590 1598 cohDet_thresh = cohDet_thresh*numpy.pi/180
1591 1599 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
1592 1600
1593 1601 #Non-coherent detection!
1594 1602 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
1595 1603 #********** END OF COH/NON-COH POWER CALCULATION**********************
1596 1604
1597 1605 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
1598 1606 #Get noise
1599 1607 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
1600 1608 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
1601 1609 #Get signal threshold
1602 1610 signalThresh = noise_multiple*noise
1603 1611 #Meteor echoes detection
1604 1612 listMeteors = self.__findMeteors(powerNet, signalThresh)
1605 1613 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
1606 1614
1607 1615 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
1608 1616 #Parameters
1609 1617 heiRange = dataOut.getHeiRange()
1610 1618 rangeInterval = heiRange[1] - heiRange[0]
1611 1619 rangeLimit = multDet_rangeLimit/rangeInterval
1612 1620 timeLimit = multDet_timeLimit/dataOut.timeInterval
1613 1621 #Multiple detection removals
1614 1622 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
1615 1623 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
1616 1624
1617 1625 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
1618 1626 #Parameters
1619 1627 phaseThresh = phaseThresh*numpy.pi/180
1620 1628 thresh = [phaseThresh, noise_multiple, SNRThresh]
1621 1629 #Meteor reestimation (Errors N 1, 6, 12, 17)
1622 1630 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist0, thresh, noise, dataOut.timeInterval, dataOut.frequency)
1623 1631 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
1624 1632 #Estimation of decay times (Errors N 7, 8, 11)
1625 1633 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
1626 1634 #******************* END OF METEOR REESTIMATION *******************
1627 1635
1628 1636 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
1629 1637 #Calculating Radial Velocity (Error N 15)
1630 1638 radialStdThresh = 10
1631 1639 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
1632 1640
1633 1641 if len(listMeteors4) > 0:
1634 1642 #Setting New Array
1635 1643 date = dataOut.utctime
1636 1644 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
1637 1645
1638 1646 #Correcting phase offset
1639 1647 if phaseOffsets != None:
1640 1648 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
1641 1649 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
1642 1650
1643 1651 #Second Pairslist
1644 1652 pairsList = []
1645 1653 pairx = (0,1)
1646 1654 pairy = (2,3)
1647 1655 pairsList.append(pairx)
1648 1656 pairsList.append(pairy)
1649 1657
1650 1658 jph = numpy.array([0,0,0,0])
1651 1659 h = (hmin,hmax)
1652 1660 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
1653 1661
1654 1662 # #Calculate AOA (Error N 3, 4)
1655 1663 # #JONES ET AL. 1998
1656 1664 # error = arrayParameters[:,-1]
1657 1665 # AOAthresh = numpy.pi/8
1658 1666 # phases = -arrayParameters[:,9:13]
1659 1667 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
1660 1668 #
1661 1669 # #Calculate Heights (Error N 13 and 14)
1662 1670 # error = arrayParameters[:,-1]
1663 1671 # Ranges = arrayParameters[:,2]
1664 1672 # zenith = arrayParameters[:,5]
1665 1673 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
1666 1674 # error = arrayParameters[:,-1]
1667 1675 #********************* END OF PARAMETERS CALCULATION **************************
1668 1676
1669 1677 #***************************+ PASS DATA TO NEXT STEP **********************
1670 1678 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
1671 1679 dataOut.data_param = arrayParameters
1672 1680
1673 1681 if arrayParameters is None:
1674 1682 dataOut.flagNoData = True
1675 1683 else:
1676 1684 dataOut.flagNoData = True
1677 1685
1678 1686 return
1679 1687
1680 1688 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
1681 1689
1682 1690 minIndex = min(newheis[0])
1683 1691 maxIndex = max(newheis[0])
1684 1692
1685 1693 voltage = voltage0[:,:,minIndex:maxIndex+1]
1686 1694 nLength = voltage.shape[1]/n
1687 1695 nMin = 0
1688 1696 nMax = 0
1689 1697 phaseOffset = numpy.zeros((len(pairslist),n))
1690 1698
1691 1699 for i in range(n):
1692 1700 nMax += nLength
1693 1701 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
1694 1702 phaseCCF = numpy.mean(phaseCCF, axis = 2)
1695 1703 phaseOffset[:,i] = phaseCCF.transpose()
1696 1704 nMin = nMax
1697 1705 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
1698 1706
1699 1707 #Remove Outliers
1700 1708 factor = 2
1701 1709 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
1702 1710 dw = numpy.std(wt,axis = 1)
1703 1711 dw = dw.reshape((dw.size,1))
1704 1712 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
1705 1713 phaseOffset[ind] = numpy.nan
1706 1714 phaseOffset = stats.nanmean(phaseOffset, axis=1)
1707 1715
1708 1716 return phaseOffset
1709 1717
1710 1718 def __shiftPhase(self, data, phaseShift):
1711 1719 #this will shift the phase of a complex number
1712 1720 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
1713 1721 return dataShifted
1714 1722
1715 1723 def __estimatePhaseDifference(self, array, pairslist):
1716 1724 nChannel = array.shape[0]
1717 1725 nHeights = array.shape[2]
1718 1726 numPairs = len(pairslist)
1719 1727 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
1720 1728 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
1721 1729
1722 1730 #Correct phases
1723 1731 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
1724 1732 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
1725 1733
1726 1734 if indDer[0].shape[0] > 0:
1727 1735 for i in range(indDer[0].shape[0]):
1728 1736 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
1729 1737 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
1730 1738
1731 1739 # for j in range(numSides):
1732 1740 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
1733 1741 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
1734 1742 #
1735 1743 #Linear
1736 1744 phaseInt = numpy.zeros((numPairs,1))
1737 1745 angAllCCF = phaseCCF[:,[0,1,3,4],0]
1738 1746 for j in range(numPairs):
1739 1747 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
1740 1748 phaseInt[j] = fit[1]
1741 1749 #Phase Differences
1742 1750 phaseDiff = phaseInt - phaseCCF[:,2,:]
1743 1751 phaseArrival = phaseInt.reshape(phaseInt.size)
1744 1752
1745 1753 #Dealias
1746 1754 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
1747 1755 # indAlias = numpy.where(phaseArrival > numpy.pi)
1748 1756 # phaseArrival[indAlias] -= 2*numpy.pi
1749 1757 # indAlias = numpy.where(phaseArrival < -numpy.pi)
1750 1758 # phaseArrival[indAlias] += 2*numpy.pi
1751 1759
1752 1760 return phaseDiff, phaseArrival
1753 1761
1754 1762 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
1755 1763 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
1756 1764 #find the phase shifts of each channel over 1 second intervals
1757 1765 #only look at ranges below the beacon signal
1758 1766 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
1759 1767 numBlocks = int(volts.shape[1]/numProfPerBlock)
1760 1768 numHeights = volts.shape[2]
1761 1769 nChannel = volts.shape[0]
1762 1770 voltsCohDet = volts.copy()
1763 1771
1764 1772 pairsarray = numpy.array(pairslist)
1765 1773 indSides = pairsarray[:,1]
1766 1774 # indSides = numpy.array(range(nChannel))
1767 1775 # indSides = numpy.delete(indSides, indCenter)
1768 1776 #
1769 1777 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
1770 1778 listBlocks = numpy.array_split(volts, numBlocks, 1)
1771 1779
1772 1780 startInd = 0
1773 1781 endInd = 0
1774 1782
1775 1783 for i in range(numBlocks):
1776 1784 startInd = endInd
1777 1785 endInd = endInd + listBlocks[i].shape[1]
1778 1786
1779 1787 arrayBlock = listBlocks[i]
1780 1788 # arrayBlockCenter = listCenter[i]
1781 1789
1782 1790 #Estimate the Phase Difference
1783 1791 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
1784 1792 #Phase Difference RMS
1785 1793 arrayPhaseRMS = numpy.abs(phaseDiff)
1786 1794 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
1787 1795 indPhase = numpy.where(phaseRMSaux==4)
1788 1796 #Shifting
1789 1797 if indPhase[0].shape[0] > 0:
1790 1798 for j in range(indSides.size):
1791 1799 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
1792 1800 voltsCohDet[:,startInd:endInd,:] = arrayBlock
1793 1801
1794 1802 return voltsCohDet
1795 1803
1796 1804 def __calculateCCF(self, volts, pairslist ,laglist):
1797 1805
1798 1806 nHeights = volts.shape[2]
1799 1807 nPoints = volts.shape[1]
1800 1808 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
1801 1809
1802 1810 for i in range(len(pairslist)):
1803 1811 volts1 = volts[pairslist[i][0]]
1804 1812 volts2 = volts[pairslist[i][1]]
1805 1813
1806 1814 for t in range(len(laglist)):
1807 1815 idxT = laglist[t]
1808 1816 if idxT >= 0:
1809 1817 vStacked = numpy.vstack((volts2[idxT:,:],
1810 1818 numpy.zeros((idxT, nHeights),dtype='complex')))
1811 1819 else:
1812 1820 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
1813 1821 volts2[:(nPoints + idxT),:]))
1814 1822 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
1815 1823
1816 1824 vStacked = None
1817 1825 return voltsCCF
1818 1826
1819 1827 def __getNoise(self, power, timeSegment, timeInterval):
1820 1828 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
1821 1829 numBlocks = int(power.shape[0]/numProfPerBlock)
1822 1830 numHeights = power.shape[1]
1823 1831
1824 1832 listPower = numpy.array_split(power, numBlocks, 0)
1825 1833 noise = numpy.zeros((power.shape[0], power.shape[1]))
1826 1834 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
1827 1835
1828 1836 startInd = 0
1829 1837 endInd = 0
1830 1838
1831 1839 for i in range(numBlocks): #split por canal
1832 1840 startInd = endInd
1833 1841 endInd = endInd + listPower[i].shape[0]
1834 1842
1835 1843 arrayBlock = listPower[i]
1836 1844 noiseAux = numpy.mean(arrayBlock, 0)
1837 1845 # noiseAux = numpy.median(noiseAux)
1838 1846 # noiseAux = numpy.mean(arrayBlock)
1839 1847 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
1840 1848
1841 1849 noiseAux1 = numpy.mean(arrayBlock)
1842 1850 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
1843 1851
1844 1852 return noise, noise1
1845 1853
1846 1854 def __findMeteors(self, power, thresh):
1847 1855 nProf = power.shape[0]
1848 1856 nHeights = power.shape[1]
1849 1857 listMeteors = []
1850 1858
1851 1859 for i in range(nHeights):
1852 1860 powerAux = power[:,i]
1853 1861 threshAux = thresh[:,i]
1854 1862
1855 1863 indUPthresh = numpy.where(powerAux > threshAux)[0]
1856 1864 indDNthresh = numpy.where(powerAux <= threshAux)[0]
1857 1865
1858 1866 j = 0
1859 1867
1860 1868 while (j < indUPthresh.size - 2):
1861 1869 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
1862 1870 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
1863 1871 indDNthresh = indDNthresh[indDNAux]
1864 1872
1865 1873 if (indDNthresh.size > 0):
1866 1874 indEnd = indDNthresh[0] - 1
1867 1875 indInit = indUPthresh[j] if isinstance(indUPthresh[j], (int, float)) else indUPthresh[j][0] ##CHECK!!!!
1868 1876
1869 1877 meteor = powerAux[indInit:indEnd + 1]
1870 1878 indPeak = meteor.argmax() + indInit
1871 1879 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
1872 1880
1873 1881 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
1874 1882 j = numpy.where(indUPthresh == indEnd)[0] + 1
1875 1883 else: j+=1
1876 1884 else: j+=1
1877 1885
1878 1886 return listMeteors
1879 1887
1880 1888 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
1881 1889
1882 1890 arrayMeteors = numpy.asarray(listMeteors)
1883 1891 listMeteors1 = []
1884 1892
1885 1893 while arrayMeteors.shape[0] > 0:
1886 1894 FLAs = arrayMeteors[:,4]
1887 1895 maxFLA = FLAs.argmax()
1888 1896 listMeteors1.append(arrayMeteors[maxFLA,:])
1889 1897
1890 1898 MeteorInitTime = arrayMeteors[maxFLA,1]
1891 1899 MeteorEndTime = arrayMeteors[maxFLA,3]
1892 1900 MeteorHeight = arrayMeteors[maxFLA,0]
1893 1901
1894 1902 #Check neighborhood
1895 1903 maxHeightIndex = MeteorHeight + rangeLimit
1896 1904 minHeightIndex = MeteorHeight - rangeLimit
1897 1905 minTimeIndex = MeteorInitTime - timeLimit
1898 1906 maxTimeIndex = MeteorEndTime + timeLimit
1899 1907
1900 1908 #Check Heights
1901 1909 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
1902 1910 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
1903 1911 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
1904 1912
1905 1913 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
1906 1914
1907 1915 return listMeteors1
1908 1916
1909 1917 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
1910 1918 numHeights = volts.shape[2]
1911 1919 nChannel = volts.shape[0]
1912 1920
1913 1921 thresholdPhase = thresh[0]
1914 1922 thresholdNoise = thresh[1]
1915 1923 thresholdDB = float(thresh[2])
1916 1924
1917 1925 thresholdDB1 = 10**(thresholdDB/10)
1918 1926 pairsarray = numpy.array(pairslist)
1919 1927 indSides = pairsarray[:,1]
1920 1928
1921 1929 pairslist1 = list(pairslist)
1922 1930 pairslist1.append((0,4))
1923 1931 pairslist1.append((1,3))
1924 1932
1925 1933 listMeteors1 = []
1926 1934 listPowerSeries = []
1927 1935 listVoltageSeries = []
1928 1936 #volts has the war data
1929 1937
1930 1938 if frequency == 30.175e6:
1931 1939 timeLag = 45*10**-3
1932 1940 else:
1933 1941 timeLag = 15*10**-3
1934 1942 lag = int(numpy.ceil(timeLag/timeInterval))
1935 1943
1936 1944 for i in range(len(listMeteors)):
1937 1945
1938 1946 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
1939 1947 meteorAux = numpy.zeros(16)
1940 1948
1941 1949 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
1942 1950 mHeight = int(listMeteors[i][0])
1943 1951 mStart = int(listMeteors[i][1])
1944 1952 mPeak = int(listMeteors[i][2])
1945 1953 mEnd = int(listMeteors[i][3])
1946 1954
1947 1955 #get the volt data between the start and end times of the meteor
1948 1956 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
1949 1957 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
1950 1958
1951 1959 #3.6. Phase Difference estimation
1952 1960 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
1953 1961
1954 1962 #3.7. Phase difference removal & meteor start, peak and end times reestimated
1955 1963 #meteorVolts0.- all Channels, all Profiles
1956 1964 meteorVolts0 = volts[:,:,mHeight]
1957 1965 meteorThresh = noise[:,mHeight]*thresholdNoise
1958 1966 meteorNoise = noise[:,mHeight]
1959 1967 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
1960 1968 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
1961 1969
1962 1970 #Times reestimation
1963 1971 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
1964 1972 if mStart1.size > 0:
1965 1973 mStart1 = mStart1[-1] + 1
1966 1974
1967 1975 else:
1968 1976 mStart1 = mPeak
1969 1977
1970 1978 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
1971 1979 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
1972 1980 if mEndDecayTime1.size == 0:
1973 1981 mEndDecayTime1 = powerNet0.size
1974 1982 else:
1975 1983 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
1976 1984 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
1977 1985
1978 1986 #meteorVolts1.- all Channels, from start to end
1979 1987 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
1980 1988 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
1981 1989 if meteorVolts2.shape[1] == 0:
1982 1990 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
1983 1991 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
1984 1992 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
1985 1993 ##################### END PARAMETERS REESTIMATION #########################
1986 1994
1987 1995 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
1988 1996 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
1989 1997 if meteorVolts2.shape[1] > 0:
1990 1998 #Phase Difference re-estimation
1991 1999 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
1992 2000 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
1993 2001 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
1994 2002 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
1995 2003 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
1996 2004
1997 2005 #Phase Difference RMS
1998 2006 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
1999 2007 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
2000 2008 #Data from Meteor
2001 2009 mPeak1 = powerNet1.argmax() + mStart1
2002 2010 mPeakPower1 = powerNet1.max()
2003 2011 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
2004 2012 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
2005 2013 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
2006 2014 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
2007 2015 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
2008 2016 #Vectorize
2009 2017 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
2010 2018 meteorAux[7:11] = phaseDiffint[0:4]
2011 2019
2012 2020 #Rejection Criterions
2013 2021 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
2014 2022 meteorAux[-1] = 17
2015 2023 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
2016 2024 meteorAux[-1] = 1
2017 2025
2018 2026
2019 2027 else:
2020 2028 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
2021 2029 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
2022 2030 PowerSeries = 0
2023 2031
2024 2032 listMeteors1.append(meteorAux)
2025 2033 listPowerSeries.append(PowerSeries)
2026 2034 listVoltageSeries.append(meteorVolts1)
2027 2035
2028 2036 return listMeteors1, listPowerSeries, listVoltageSeries
2029 2037
2030 2038 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
2031 2039
2032 2040 threshError = 10
2033 2041 #Depending if it is 30 or 50 MHz
2034 2042 if frequency == 30.175e6:
2035 2043 timeLag = 45*10**-3
2036 2044 else:
2037 2045 timeLag = 15*10**-3
2038 2046 lag = int(numpy.ceil(timeLag/timeInterval))
2039 2047
2040 2048 listMeteors1 = []
2041 2049
2042 2050 for i in range(len(listMeteors)):
2043 2051 meteorPower = listPower[i]
2044 2052 meteorAux = listMeteors[i]
2045 2053
2046 2054 if meteorAux[-1] == 0:
2047 2055
2048 2056 try:
2049 2057 indmax = meteorPower.argmax()
2050 2058 indlag = indmax + lag
2051 2059
2052 2060 y = meteorPower[indlag:]
2053 2061 x = numpy.arange(0, y.size)*timeLag
2054 2062
2055 2063 #first guess
2056 2064 a = y[0]
2057 2065 tau = timeLag
2058 2066 #exponential fit
2059 2067 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
2060 2068 y1 = self.__exponential_function(x, *popt)
2061 2069 #error estimation
2062 2070 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
2063 2071
2064 2072 decayTime = popt[1]
2065 2073 riseTime = indmax*timeInterval
2066 2074 meteorAux[11:13] = [decayTime, error]
2067 2075
2068 2076 #Table items 7, 8 and 11
2069 2077 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
2070 2078 meteorAux[-1] = 7
2071 2079 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
2072 2080 meteorAux[-1] = 8
2073 2081 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
2074 2082 meteorAux[-1] = 11
2075 2083
2076 2084
2077 2085 except:
2078 2086 meteorAux[-1] = 11
2079 2087
2080 2088
2081 2089 listMeteors1.append(meteorAux)
2082 2090
2083 2091 return listMeteors1
2084 2092
2085 2093 #Exponential Function
2086 2094
2087 2095 def __exponential_function(self, x, a, tau):
2088 2096 y = a*numpy.exp(-x/tau)
2089 2097 return y
2090 2098
2091 2099 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
2092 2100
2093 2101 pairslist1 = list(pairslist)
2094 2102 pairslist1.append((0,4))
2095 2103 pairslist1.append((1,3))
2096 2104 numPairs = len(pairslist1)
2097 2105 #Time Lag
2098 2106 timeLag = 45*10**-3
2099 2107 c = 3e8
2100 2108 lag = numpy.ceil(timeLag/timeInterval)
2101 2109 freq = 30.175e6
2102 2110
2103 2111 listMeteors1 = []
2104 2112
2105 2113 for i in range(len(listMeteors)):
2106 2114 meteorAux = listMeteors[i]
2107 2115 if meteorAux[-1] == 0:
2108 2116 mStart = listMeteors[i][1]
2109 2117 mPeak = listMeteors[i][2]
2110 2118 mLag = mPeak - mStart + lag
2111 2119
2112 2120 #get the volt data between the start and end times of the meteor
2113 2121 meteorVolts = listVolts[i]
2114 2122 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
2115 2123
2116 2124 #Get CCF
2117 2125 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
2118 2126
2119 2127 #Method 2
2120 2128 slopes = numpy.zeros(numPairs)
2121 2129 time = numpy.array([-2,-1,1,2])*timeInterval
2122 2130 angAllCCF = numpy.angle(allCCFs[:,[0,4,2,3],0])
2123 2131
2124 2132 #Correct phases
2125 2133 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
2126 2134 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2127 2135
2128 2136 if indDer[0].shape[0] > 0:
2129 2137 for i in range(indDer[0].shape[0]):
2130 2138 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
2131 2139 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
2132 2140
2133 2141 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
2134 2142 for j in range(numPairs):
2135 2143 fit = stats.linregress(time, angAllCCF[j,:])
2136 2144 slopes[j] = fit[0]
2137 2145
2138 2146 #Remove Outlier
2139 2147 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
2140 2148 # slopes = numpy.delete(slopes,indOut)
2141 2149 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
2142 2150 # slopes = numpy.delete(slopes,indOut)
2143 2151
2144 2152 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
2145 2153 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
2146 2154 meteorAux[-2] = radialError
2147 2155 meteorAux[-3] = radialVelocity
2148 2156
2149 2157 #Setting Error
2150 2158 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
2151 2159 if numpy.abs(radialVelocity) > 200:
2152 2160 meteorAux[-1] = 15
2153 2161 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
2154 2162 elif radialError > radialStdThresh:
2155 2163 meteorAux[-1] = 12
2156 2164
2157 2165 listMeteors1.append(meteorAux)
2158 2166 return listMeteors1
2159 2167
2160 2168 def __setNewArrays(self, listMeteors, date, heiRang):
2161 2169
2162 2170 #New arrays
2163 2171 arrayMeteors = numpy.array(listMeteors)
2164 2172 arrayParameters = numpy.zeros((len(listMeteors), 13))
2165 2173
2166 2174 #Date inclusion
2167 2175 # date = re.findall(r'\((.*?)\)', date)
2168 2176 # date = date[0].split(',')
2169 2177 # date = map(int, date)
2170 2178 #
2171 2179 # if len(date)<6:
2172 2180 # date.append(0)
2173 2181 #
2174 2182 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
2175 2183 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
2176 2184 arrayDate = numpy.tile(date, (len(listMeteors)))
2177 2185
2178 2186 #Meteor array
2179 2187 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
2180 2188 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
2181 2189
2182 2190 #Parameters Array
2183 2191 arrayParameters[:,0] = arrayDate #Date
2184 2192 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
2185 2193 arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
2186 2194 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
2187 2195 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
2188 2196
2189 2197
2190 2198 return arrayParameters
2191 2199
2192 2200 class CorrectSMPhases(Operation):
2201 parameters = {
2202 'phaseOffsets': global_type_pairsList,
2203 'hmin': global_type_float,
2204 'hmax': global_type_float,
2205 'azimuth': global_type_float,
2206 'channelPositions': global_type_pairsList,
2207 }
2193 2208
2194 2209 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
2195 2210
2196 2211 arrayParameters = dataOut.data_param
2197 2212 pairsList = []
2198 2213 pairx = (0,1)
2199 2214 pairy = (2,3)
2200 2215 pairsList.append(pairx)
2201 2216 pairsList.append(pairy)
2202 2217 jph = numpy.zeros(4)
2203 2218
2204 2219 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2205 2220 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2206 2221 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
2207 2222
2208 2223 meteorOps = SMOperations()
2209 2224 if channelPositions is None:
2210 2225 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2211 2226 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2212 2227
2213 2228 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2214 2229 h = (hmin,hmax)
2215 2230
2216 2231 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2217 2232
2218 2233 dataOut.data_param = arrayParameters
2219 2234 return
2220 2235
2221 2236 class SMPhaseCalibration(Operation):
2222 2237
2223 2238 __buffer = None
2224 2239
2225 2240 __initime = None
2226 2241
2227 2242 __dataReady = False
2228 2243
2229 2244 __isConfig = False
2230 2245
2231 2246 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
2232 2247
2233 2248 dataTime = currentTime + paramInterval
2234 2249 deltaTime = dataTime - initTime
2235 2250
2236 2251 if deltaTime >= outputInterval or deltaTime < 0:
2237 2252 return True
2238 2253
2239 2254 return False
2240 2255
2241 2256 def __getGammas(self, pairs, d, phases):
2242 2257 gammas = numpy.zeros(2)
2243 2258
2244 2259 for i in range(len(pairs)):
2245 2260
2246 2261 pairi = pairs[i]
2247 2262
2248 2263 phip3 = phases[:,pairi[1]]
2249 2264 d3 = d[pairi[1]]
2250 2265 phip2 = phases[:,pairi[0]]
2251 2266 d2 = d[pairi[0]]
2252 2267 #Calculating gamma
2253 2268 # jdcos = alp1/(k*d1)
2254 2269 # jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0)))
2255 2270 jgamma = -phip2*d3/d2 - phip3
2256 2271 jgamma = numpy.angle(numpy.exp(1j*jgamma))
2257 2272 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
2258 2273 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
2259 2274
2260 2275 #Revised distribution
2261 2276 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
2262 2277
2263 2278 #Histogram
2264 2279 nBins = 64.0
2265 2280 rmin = -0.5*numpy.pi
2266 2281 rmax = 0.5*numpy.pi
2267 2282 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
2268 2283
2269 2284 meteorsY = phaseHisto[0]
2270 2285 phasesX = phaseHisto[1][:-1]
2271 2286 width = phasesX[1] - phasesX[0]
2272 2287 phasesX += width/2
2273 2288
2274 2289 #Gaussian aproximation
2275 2290 bpeak = meteorsY.argmax()
2276 2291 peak = meteorsY.max()
2277 2292 jmin = bpeak - 5
2278 2293 jmax = bpeak + 5 + 1
2279 2294
2280 2295 if jmin<0:
2281 2296 jmin = 0
2282 2297 jmax = 6
2283 2298 elif jmax > meteorsY.size:
2284 2299 jmin = meteorsY.size - 6
2285 2300 jmax = meteorsY.size
2286 2301
2287 2302 x0 = numpy.array([peak,bpeak,50])
2288 2303 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
2289 2304
2290 2305 #Gammas
2291 2306 gammas[i] = coeff[0][1]
2292 2307
2293 2308 return gammas
2294 2309
2295 2310 def __residualFunction(self, coeffs, y, t):
2296 2311
2297 2312 return y - self.__gauss_function(t, coeffs)
2298 2313
2299 2314 def __gauss_function(self, t, coeffs):
2300 2315
2301 2316 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
2302 2317
2303 2318 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
2304 2319 meteorOps = SMOperations()
2305 2320 nchan = 4
2306 2321 pairx = pairsList[0]
2307 2322 pairy = pairsList[1]
2308 2323 center_xangle = 0
2309 2324 center_yangle = 0
2310 2325 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
2311 2326 ntimes = len(range_angle)
2312 2327
2313 2328 nstepsx = 20.0
2314 2329 nstepsy = 20.0
2315 2330
2316 2331 for iz in range(ntimes):
2317 2332 min_xangle = -range_angle[iz]/2 + center_xangle
2318 2333 max_xangle = range_angle[iz]/2 + center_xangle
2319 2334 min_yangle = -range_angle[iz]/2 + center_yangle
2320 2335 max_yangle = range_angle[iz]/2 + center_yangle
2321 2336
2322 2337 inc_x = (max_xangle-min_xangle)/nstepsx
2323 2338 inc_y = (max_yangle-min_yangle)/nstepsy
2324 2339
2325 2340 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
2326 2341 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
2327 2342 penalty = numpy.zeros((nstepsx,nstepsy))
2328 2343 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
2329 2344 jph = numpy.zeros(nchan)
2330 2345
2331 2346 # Iterations looking for the offset
2332 2347 for iy in range(int(nstepsy)):
2333 2348 for ix in range(int(nstepsx)):
2334 2349 jph[pairy[1]] = alpha_y[iy]
2335 2350 jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
2336 2351
2337 2352 jph[pairx[1]] = alpha_x[ix]
2338 2353 jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
2339 2354
2340 2355 jph_array[:,ix,iy] = jph
2341 2356
2342 2357 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
2343 2358 error = meteorsArray1[:,-1]
2344 2359 ind1 = numpy.where(error==0)[0]
2345 2360 penalty[ix,iy] = ind1.size
2346 2361
2347 2362 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
2348 2363 phOffset = jph_array[:,i,j]
2349 2364
2350 2365 center_xangle = phOffset[pairx[1]]
2351 2366 center_yangle = phOffset[pairy[1]]
2352 2367
2353 2368 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
2354 2369 phOffset = phOffset*180/numpy.pi
2355 2370 return phOffset
2356 2371
2357 2372
2358 2373 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
2359 2374
2360 2375 dataOut.flagNoData = True
2361 2376 self.__dataReady = False
2362 2377 dataOut.outputInterval = nHours*3600
2363 2378
2364 2379 if self.__isConfig == False:
2365 2380 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2366 2381 #Get Initial LTC time
2367 2382 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2368 2383 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2369 2384
2370 2385 self.__isConfig = True
2371 2386
2372 2387 if self.__buffer is None:
2373 2388 self.__buffer = dataOut.data_param.copy()
2374 2389
2375 2390 else:
2376 2391 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2377 2392
2378 2393 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2379 2394
2380 2395 if self.__dataReady:
2381 2396 dataOut.utctimeInit = self.__initime
2382 2397 self.__initime += dataOut.outputInterval #to erase time offset
2383 2398
2384 2399 freq = dataOut.frequency
2385 2400 c = dataOut.C #m/s
2386 2401 lamb = c/freq
2387 2402 k = 2*numpy.pi/lamb
2388 2403 azimuth = 0
2389 2404 h = (hmin, hmax)
2390 2405 pairs = ((0,1),(2,3))
2391 2406
2392 2407 if channelPositions is None:
2393 2408 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2394 2409 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2395 2410 meteorOps = SMOperations()
2396 2411 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2397 2412
2398 2413 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
2399 2414
2400 2415 meteorsArray = self.__buffer
2401 2416 error = meteorsArray[:,-1]
2402 2417 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
2403 2418 ind1 = numpy.where(boolError)[0]
2404 2419 meteorsArray = meteorsArray[ind1,:]
2405 2420 meteorsArray[:,-1] = 0
2406 2421 phases = meteorsArray[:,8:12]
2407 2422
2408 2423 #Calculate Gammas
2409 2424 gammas = self.__getGammas(pairs, distances, phases)
2410 2425 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
2411 2426 #Calculate Phases
2412 2427 phasesOff = self.__getPhases(azimuth, h, pairs, distances, gammas, meteorsArray)
2413 2428 phasesOff = phasesOff.reshape((1,phasesOff.size))
2414 2429 dataOut.data_output = -phasesOff
2415 2430 dataOut.flagNoData = False
2416 2431 dataOut.channelList = pairslist0
2417 2432 self.__buffer = None
2418 2433
2419 2434
2420 2435 return
2421 2436
2422 2437 class SMOperations():
2423 2438
2424 2439 def __init__(self):
2425 2440
2426 2441 return
2427 2442
2428 2443 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
2429 2444
2430 2445 arrayParameters = arrayParameters0.copy()
2431 2446 hmin = h[0]
2432 2447 hmax = h[1]
2433 2448
2434 2449 #Calculate AOA (Error N 3, 4)
2435 2450 #JONES ET AL. 1998
2436 2451 AOAthresh = numpy.pi/8
2437 2452 error = arrayParameters[:,-1]
2438 2453 phases = -arrayParameters[:,8:12] + jph
2439 2454 # phases = numpy.unwrap(phases)
2440 2455 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
2441 2456
2442 2457 #Calculate Heights (Error N 13 and 14)
2443 2458 error = arrayParameters[:,-1]
2444 2459 Ranges = arrayParameters[:,1]
2445 2460 zenith = arrayParameters[:,4]
2446 2461 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
2447 2462
2448 2463 #----------------------- Get Final data ------------------------------------
2449 2464 # error = arrayParameters[:,-1]
2450 2465 # ind1 = numpy.where(error==0)[0]
2451 2466 # arrayParameters = arrayParameters[ind1,:]
2452 2467
2453 2468 return arrayParameters
2454 2469
2455 2470 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
2456 2471
2457 2472 arrayAOA = numpy.zeros((phases.shape[0],3))
2458 2473 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
2459 2474
2460 2475 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
2461 2476 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
2462 2477 arrayAOA[:,2] = cosDirError
2463 2478
2464 2479 azimuthAngle = arrayAOA[:,0]
2465 2480 zenithAngle = arrayAOA[:,1]
2466 2481
2467 2482 #Setting Error
2468 2483 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
2469 2484 error[indError] = 0
2470 2485 #Number 3: AOA not fesible
2471 2486 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
2472 2487 error[indInvalid] = 3
2473 2488 #Number 4: Large difference in AOAs obtained from different antenna baselines
2474 2489 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
2475 2490 error[indInvalid] = 4
2476 2491 return arrayAOA, error
2477 2492
2478 2493 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
2479 2494
2480 2495 #Initializing some variables
2481 2496 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
2482 2497 ang_aux = ang_aux.reshape(1,ang_aux.size)
2483 2498
2484 2499 cosdir = numpy.zeros((arrayPhase.shape[0],2))
2485 2500 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
2486 2501
2487 2502
2488 2503 for i in range(2):
2489 2504 ph0 = arrayPhase[:,pairsList[i][0]]
2490 2505 ph1 = arrayPhase[:,pairsList[i][1]]
2491 2506 d0 = distances[pairsList[i][0]]
2492 2507 d1 = distances[pairsList[i][1]]
2493 2508
2494 2509 ph0_aux = ph0 + ph1
2495 2510 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
2496 2511 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
2497 2512 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
2498 2513 #First Estimation
2499 2514 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
2500 2515
2501 2516 #Most-Accurate Second Estimation
2502 2517 phi1_aux = ph0 - ph1
2503 2518 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
2504 2519 #Direction Cosine 1
2505 2520 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
2506 2521
2507 2522 #Searching the correct Direction Cosine
2508 2523 cosdir0_aux = cosdir0[:,i]
2509 2524 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
2510 2525 #Minimum Distance
2511 2526 cosDiff = (cosdir1 - cosdir0_aux)**2
2512 2527 indcos = cosDiff.argmin(axis = 1)
2513 2528 #Saving Value obtained
2514 2529 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
2515 2530
2516 2531 return cosdir0, cosdir
2517 2532
2518 2533 def __calculateAOA(self, cosdir, azimuth):
2519 2534 cosdirX = cosdir[:,0]
2520 2535 cosdirY = cosdir[:,1]
2521 2536
2522 2537 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
2523 2538 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
2524 2539 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
2525 2540
2526 2541 return angles
2527 2542
2528 2543 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
2529 2544
2530 2545 Ramb = 375 #Ramb = c/(2*PRF)
2531 2546 Re = 6371 #Earth Radius
2532 2547 heights = numpy.zeros(Ranges.shape)
2533 2548
2534 2549 R_aux = numpy.array([0,1,2])*Ramb
2535 2550 R_aux = R_aux.reshape(1,R_aux.size)
2536 2551
2537 2552 Ranges = Ranges.reshape(Ranges.size,1)
2538 2553
2539 2554 Ri = Ranges + R_aux
2540 2555 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
2541 2556
2542 2557 #Check if there is a height between 70 and 110 km
2543 2558 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
2544 2559 ind_h = numpy.where(h_bool == 1)[0]
2545 2560
2546 2561 hCorr = hi[ind_h, :]
2547 2562 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
2548 2563
2549 2564 hCorr = hi[ind_hCorr]
2550 2565 heights[ind_h] = hCorr
2551 2566
2552 2567 #Setting Error
2553 2568 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
2554 2569 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
2555 2570 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
2556 2571 error[indError] = 0
2557 2572 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
2558 2573 error[indInvalid2] = 14
2559 2574 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
2560 2575 error[indInvalid1] = 13
2561 2576
2562 2577 return heights, error
2563 2578
2564 2579 def getPhasePairs(self, channelPositions):
2565 2580 chanPos = numpy.array(channelPositions)
2566 2581 listOper = list(itertools.combinations(range(5),2))
2567 2582
2568 2583 distances = numpy.zeros(4)
2569 2584 axisX = []
2570 2585 axisY = []
2571 2586 distX = numpy.zeros(3)
2572 2587 distY = numpy.zeros(3)
2573 2588 ix = 0
2574 2589 iy = 0
2575 2590
2576 2591 pairX = numpy.zeros((2,2))
2577 2592 pairY = numpy.zeros((2,2))
2578 2593
2579 2594 for i in range(len(listOper)):
2580 2595 pairi = listOper[i]
2581 2596
2582 2597 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
2583 2598
2584 2599 if posDif[0] == 0:
2585 2600 axisY.append(pairi)
2586 2601 distY[iy] = posDif[1]
2587 2602 iy += 1
2588 2603 elif posDif[1] == 0:
2589 2604 axisX.append(pairi)
2590 2605 distX[ix] = posDif[0]
2591 2606 ix += 1
2592 2607
2593 2608 for i in range(2):
2594 2609 if i==0:
2595 2610 dist0 = distX
2596 2611 axis0 = axisX
2597 2612 else:
2598 2613 dist0 = distY
2599 2614 axis0 = axisY
2600 2615
2601 2616 side = numpy.argsort(dist0)[:-1]
2602 2617 axis0 = numpy.array(axis0)[side,:]
2603 2618 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
2604 2619 axis1 = numpy.unique(numpy.reshape(axis0,4))
2605 2620 side = axis1[axis1 != chanC]
2606 2621 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
2607 2622 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
2608 2623 if diff1<0:
2609 2624 chan2 = side[0]
2610 2625 d2 = numpy.abs(diff1)
2611 2626 chan1 = side[1]
2612 2627 d1 = numpy.abs(diff2)
2613 2628 else:
2614 2629 chan2 = side[1]
2615 2630 d2 = numpy.abs(diff2)
2616 2631 chan1 = side[0]
2617 2632 d1 = numpy.abs(diff1)
2618 2633
2619 2634 if i==0:
2620 2635 chanCX = chanC
2621 2636 chan1X = chan1
2622 2637 chan2X = chan2
2623 2638 distances[0:2] = numpy.array([d1,d2])
2624 2639 else:
2625 2640 chanCY = chanC
2626 2641 chan1Y = chan1
2627 2642 chan2Y = chan2
2628 2643 distances[2:4] = numpy.array([d1,d2])
2629 2644 # axisXsides = numpy.reshape(axisX[ix,:],4)
2630 2645 #
2631 2646 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
2632 2647 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
2633 2648 #
2634 2649 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
2635 2650 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
2636 2651 # channel25X = int(pairX[0,ind25X])
2637 2652 # channel20X = int(pairX[1,ind20X])
2638 2653 # ind25Y = numpy.where(pairY[0,:] != channelCentY)[0][0]
2639 2654 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
2640 2655 # channel25Y = int(pairY[0,ind25Y])
2641 2656 # channel20Y = int(pairY[1,ind20Y])
2642 2657
2643 2658 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
2644 2659 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
2645 2660
2646 2661 return pairslist, distances
2647 2662 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
2648 2663 #
2649 2664 # arrayAOA = numpy.zeros((phases.shape[0],3))
2650 2665 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
2651 2666 #
2652 2667 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
2653 2668 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
2654 2669 # arrayAOA[:,2] = cosDirError
2655 2670 #
2656 2671 # azimuthAngle = arrayAOA[:,0]
2657 2672 # zenithAngle = arrayAOA[:,1]
2658 2673 #
2659 2674 # #Setting Error
2660 2675 # #Number 3: AOA not fesible
2661 2676 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
2662 2677 # error[indInvalid] = 3
2663 2678 # #Number 4: Large difference in AOAs obtained from different antenna baselines
2664 2679 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
2665 2680 # error[indInvalid] = 4
2666 2681 # return arrayAOA, error
2667 2682 #
2668 2683 # def __getDirectionCosines(self, arrayPhase, pairsList):
2669 2684 #
2670 2685 # #Initializing some variables
2671 2686 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
2672 2687 # ang_aux = ang_aux.reshape(1,ang_aux.size)
2673 2688 #
2674 2689 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
2675 2690 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
2676 2691 #
2677 2692 #
2678 2693 # for i in range(2):
2679 2694 # #First Estimation
2680 2695 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
2681 2696 # #Dealias
2682 2697 # indcsi = numpy.where(phi0_aux > numpy.pi)
2683 2698 # phi0_aux[indcsi] -= 2*numpy.pi
2684 2699 # indcsi = numpy.where(phi0_aux < -numpy.pi)
2685 2700 # phi0_aux[indcsi] += 2*numpy.pi
2686 2701 # #Direction Cosine 0
2687 2702 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
2688 2703 #
2689 2704 # #Most-Accurate Second Estimation
2690 2705 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
2691 2706 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
2692 2707 # #Direction Cosine 1
2693 2708 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
2694 2709 #
2695 2710 # #Searching the correct Direction Cosine
2696 2711 # cosdir0_aux = cosdir0[:,i]
2697 2712 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
2698 2713 # #Minimum Distance
2699 2714 # cosDiff = (cosdir1 - cosdir0_aux)**2
2700 2715 # indcos = cosDiff.argmin(axis = 1)
2701 2716 # #Saving Value obtained
2702 2717 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
2703 2718 #
2704 2719 # return cosdir0, cosdir
2705 2720 #
2706 2721 # def __calculateAOA(self, cosdir, azimuth):
2707 2722 # cosdirX = cosdir[:,0]
2708 2723 # cosdirY = cosdir[:,1]
2709 2724 #
2710 2725 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
2711 2726 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
2712 2727 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
2713 2728 #
2714 2729 # return angles
2715 2730 #
2716 2731 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
2717 2732 #
2718 2733 # Ramb = 375 #Ramb = c/(2*PRF)
2719 2734 # Re = 6371 #Earth Radius
2720 2735 # heights = numpy.zeros(Ranges.shape)
2721 2736 #
2722 2737 # R_aux = numpy.array([0,1,2])*Ramb
2723 2738 # R_aux = R_aux.reshape(1,R_aux.size)
2724 2739 #
2725 2740 # Ranges = Ranges.reshape(Ranges.size,1)
2726 2741 #
2727 2742 # Ri = Ranges + R_aux
2728 2743 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
2729 2744 #
2730 2745 # #Check if there is a height between 70 and 110 km
2731 2746 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
2732 2747 # ind_h = numpy.where(h_bool == 1)[0]
2733 2748 #
2734 2749 # hCorr = hi[ind_h, :]
2735 2750 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
2736 2751 #
2737 2752 # hCorr = hi[ind_hCorr]
2738 2753 # heights[ind_h] = hCorr
2739 2754 #
2740 2755 # #Setting Error
2741 2756 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
2742 2757 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
2743 2758 #
2744 2759 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
2745 2760 # error[indInvalid2] = 14
2746 2761 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
2747 2762 # error[indInvalid1] = 13
2748 2763 #
2749 2764 # return heights, error
@@ -1,904 +1,910
1 1 import numpy
2 2
3 3 from jroproc_base import ProcessingUnit, Operation
4 4 from schainpy.model.data.jrodata import Spectra
5 5 from schainpy.model.data.jrodata import hildebrand_sekhon
6 6
7 7 class SpectraProc(ProcessingUnit):
8 8
9 9 def __init__(self, **kwargs):
10 10
11 11 ProcessingUnit.__init__(self, **kwargs)
12 12
13 13 self.buffer = None
14 14 self.firstdatatime = None
15 15 self.profIndex = 0
16 16 self.dataOut = Spectra()
17 17 self.id_min = None
18 18 self.id_max = None
19 19
20 20 def __updateSpecFromVoltage(self):
21 21
22 22 self.dataOut.timeZone = self.dataIn.timeZone
23 23 self.dataOut.dstFlag = self.dataIn.dstFlag
24 24 self.dataOut.errorCount = self.dataIn.errorCount
25 25 self.dataOut.useLocalTime = self.dataIn.useLocalTime
26 26
27 27 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
28 28 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
29 29 self.dataOut.channelList = self.dataIn.channelList
30 30 self.dataOut.heightList = self.dataIn.heightList
31 31 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
32 32
33 33 self.dataOut.nBaud = self.dataIn.nBaud
34 34 self.dataOut.nCode = self.dataIn.nCode
35 35 self.dataOut.code = self.dataIn.code
36 36 self.dataOut.nProfiles = self.dataOut.nFFTPoints
37 37
38 38 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
39 39 self.dataOut.utctime = self.firstdatatime
40 40 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
41 41 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
42 42 self.dataOut.flagShiftFFT = False
43 43
44 44 self.dataOut.nCohInt = self.dataIn.nCohInt
45 45 self.dataOut.nIncohInt = 1
46 46
47 47 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
48 48
49 49 self.dataOut.frequency = self.dataIn.frequency
50 50 self.dataOut.realtime = self.dataIn.realtime
51 51
52 52 self.dataOut.azimuth = self.dataIn.azimuth
53 53 self.dataOut.zenith = self.dataIn.zenith
54 54
55 55 self.dataOut.beam.codeList = self.dataIn.beam.codeList
56 56 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
57 57 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
58 58
59 59 def __getFft(self):
60 60 """
61 61 Convierte valores de Voltaje a Spectra
62 62
63 63 Affected:
64 64 self.dataOut.data_spc
65 65 self.dataOut.data_cspc
66 66 self.dataOut.data_dc
67 67 self.dataOut.heightList
68 68 self.profIndex
69 69 self.buffer
70 70 self.dataOut.flagNoData
71 71 """
72 72 fft_volt = numpy.fft.fft(self.buffer,n=self.dataOut.nFFTPoints,axis=1)
73 73 fft_volt = fft_volt.astype(numpy.dtype('complex'))
74 74 dc = fft_volt[:,0,:]
75 75
76 76 #calculo de self-spectra
77 77 fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,))
78 78 spc = fft_volt * numpy.conjugate(fft_volt)
79 79 spc = spc.real
80 80
81 81 blocksize = 0
82 82 blocksize += dc.size
83 83 blocksize += spc.size
84 84
85 85 cspc = None
86 86 pairIndex = 0
87 87 if self.dataOut.pairsList != None:
88 88 #calculo de cross-spectra
89 89 cspc = numpy.zeros((self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
90 90 for pair in self.dataOut.pairsList:
91 91 if pair[0] not in self.dataOut.channelList:
92 92 raise ValueError, "Error getting CrossSpectra: pair 0 of %s is not in channelList = %s" %(str(pair), str(self.dataOut.channelList))
93 93 if pair[1] not in self.dataOut.channelList:
94 94 raise ValueError, "Error getting CrossSpectra: pair 1 of %s is not in channelList = %s" %(str(pair), str(self.dataOut.channelList))
95 95
96 96 cspc[pairIndex,:,:] = fft_volt[pair[0],:,:] * numpy.conjugate(fft_volt[pair[1],:,:])
97 97 pairIndex += 1
98 98 blocksize += cspc.size
99 99
100 100 self.dataOut.data_spc = spc
101 101 self.dataOut.data_cspc = cspc
102 102 self.dataOut.data_dc = dc
103 103 self.dataOut.blockSize = blocksize
104 104 self.dataOut.flagShiftFFT = True
105 105
106 106 def run(self, nProfiles=None, nFFTPoints=None, pairsList=[], ippFactor=None):
107 107
108 108 self.dataOut.flagNoData = True
109 109
110 110 if self.dataIn.type == "Spectra":
111 111 self.dataOut.copy(self.dataIn)
112 112 # self.__selectPairs(pairsList)
113 113 return True
114 114
115 115 if self.dataIn.type == "Voltage":
116 116
117 117 if nFFTPoints == None:
118 118 raise ValueError, "This SpectraProc.run() need nFFTPoints input variable"
119 119
120 120 if nProfiles == None:
121 121 nProfiles = nFFTPoints
122 122
123 123 if ippFactor == None:
124 124 ippFactor = 1
125 125
126 126 self.dataOut.ippFactor = ippFactor
127 127
128 128 self.dataOut.nFFTPoints = nFFTPoints
129 129 self.dataOut.pairsList = pairsList
130 130
131 131 if self.buffer is None:
132 132 self.buffer = numpy.zeros( (self.dataIn.nChannels,
133 133 nProfiles,
134 134 self.dataIn.nHeights),
135 135 dtype='complex')
136 136
137 137 if self.dataIn.flagDataAsBlock:
138 138 #data dimension: [nChannels, nProfiles, nSamples]
139 139 nVoltProfiles = self.dataIn.data.shape[1]
140 140 # nVoltProfiles = self.dataIn.nProfiles
141 141
142 142 if nVoltProfiles == nProfiles:
143 143 self.buffer = self.dataIn.data.copy()
144 144 self.profIndex = nVoltProfiles
145 145
146 146 elif nVoltProfiles < nProfiles:
147 147
148 148 if self.profIndex == 0:
149 149 self.id_min = 0
150 150 self.id_max = nVoltProfiles
151 151
152 152 self.buffer[:,self.id_min:self.id_max,:] = self.dataIn.data
153 153 self.profIndex += nVoltProfiles
154 154 self.id_min += nVoltProfiles
155 155 self.id_max += nVoltProfiles
156 156 else:
157 157 raise ValueError, "The type object %s has %d profiles, it should just has %d profiles"%(self.dataIn.type,self.dataIn.data.shape[1],nProfiles)
158 158 self.dataOut.flagNoData = True
159 159 return 0
160 160 else:
161 161 self.buffer[:,self.profIndex,:] = self.dataIn.data.copy()
162 162 self.profIndex += 1
163 163
164 164 if self.firstdatatime == None:
165 165 self.firstdatatime = self.dataIn.utctime
166 166
167 167 if self.profIndex == nProfiles:
168 168 self.__updateSpecFromVoltage()
169 169 self.__getFft()
170 170
171 171 self.dataOut.flagNoData = False
172 172 self.firstdatatime = None
173 173 self.profIndex = 0
174 174
175 175 return True
176 176
177 177 raise ValueError, "The type of input object '%s' is not valid"%(self.dataIn.type)
178 178
179 179 def __selectPairs(self, pairsList):
180 180
181 181 if channelList == None:
182 182 return
183 183
184 184 pairsIndexListSelected = []
185 185
186 186 for thisPair in pairsList:
187 187
188 188 if thisPair not in self.dataOut.pairsList:
189 189 continue
190 190
191 191 pairIndex = self.dataOut.pairsList.index(thisPair)
192 192
193 193 pairsIndexListSelected.append(pairIndex)
194 194
195 195 if not pairsIndexListSelected:
196 196 self.dataOut.data_cspc = None
197 197 self.dataOut.pairsList = []
198 198 return
199 199
200 200 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndexListSelected]
201 201 self.dataOut.pairsList = [self.dataOut.pairsList[i] for i in pairsIndexListSelected]
202 202
203 203 return
204 204
205 205 def __selectPairsByChannel(self, channelList=None):
206 206
207 207 if channelList == None:
208 208 return
209 209
210 210 pairsIndexListSelected = []
211 211 for pairIndex in self.dataOut.pairsIndexList:
212 212 #First pair
213 213 if self.dataOut.pairsList[pairIndex][0] not in channelList:
214 214 continue
215 215 #Second pair
216 216 if self.dataOut.pairsList[pairIndex][1] not in channelList:
217 217 continue
218 218
219 219 pairsIndexListSelected.append(pairIndex)
220 220
221 221 if not pairsIndexListSelected:
222 222 self.dataOut.data_cspc = None
223 223 self.dataOut.pairsList = []
224 224 return
225 225
226 226 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndexListSelected]
227 227 self.dataOut.pairsList = [self.dataOut.pairsList[i] for i in pairsIndexListSelected]
228 228
229 229 return
230 230
231 231 def selectChannels(self, channelList):
232 232
233 233 channelIndexList = []
234 234
235 235 for channel in channelList:
236 236 if channel not in self.dataOut.channelList:
237 237 raise ValueError, "Error selecting channels, Channel %d is not valid.\nAvailable channels = %s" %(channel, str(self.dataOut.channelList))
238 238
239 239 index = self.dataOut.channelList.index(channel)
240 240 channelIndexList.append(index)
241 241
242 242 self.selectChannelsByIndex(channelIndexList)
243 243
244 244 def selectChannelsByIndex(self, channelIndexList):
245 245 """
246 246 Selecciona un bloque de datos en base a canales segun el channelIndexList
247 247
248 248 Input:
249 249 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
250 250
251 251 Affected:
252 252 self.dataOut.data_spc
253 253 self.dataOut.channelIndexList
254 254 self.dataOut.nChannels
255 255
256 256 Return:
257 257 None
258 258 """
259 259
260 260 for channelIndex in channelIndexList:
261 261 if channelIndex not in self.dataOut.channelIndexList:
262 262 raise ValueError, "Error selecting channels: The value %d in channelIndexList is not valid.\nAvailable channel indexes = " %(channelIndex, self.dataOut.channelIndexList)
263 263
264 264 # nChannels = len(channelIndexList)
265 265
266 266 data_spc = self.dataOut.data_spc[channelIndexList,:]
267 267 data_dc = self.dataOut.data_dc[channelIndexList,:]
268 268
269 269 self.dataOut.data_spc = data_spc
270 270 self.dataOut.data_dc = data_dc
271 271
272 272 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
273 273 # self.dataOut.nChannels = nChannels
274 274
275 275 self.__selectPairsByChannel(self.dataOut.channelList)
276 276
277 277 return 1
278 278
279 279 def selectHeights(self, minHei, maxHei):
280 280 """
281 281 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
282 282 minHei <= height <= maxHei
283 283
284 284 Input:
285 285 minHei : valor minimo de altura a considerar
286 286 maxHei : valor maximo de altura a considerar
287 287
288 288 Affected:
289 289 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
290 290
291 291 Return:
292 292 1 si el metodo se ejecuto con exito caso contrario devuelve 0
293 293 """
294 294
295 295 if (minHei > maxHei):
296 296 raise ValueError, "Error selecting heights: Height range (%d,%d) is not valid" % (minHei, maxHei)
297 297
298 298 if (minHei < self.dataOut.heightList[0]):
299 299 minHei = self.dataOut.heightList[0]
300 300
301 301 if (maxHei > self.dataOut.heightList[-1]):
302 302 maxHei = self.dataOut.heightList[-1]
303 303
304 304 minIndex = 0
305 305 maxIndex = 0
306 306 heights = self.dataOut.heightList
307 307
308 308 inda = numpy.where(heights >= minHei)
309 309 indb = numpy.where(heights <= maxHei)
310 310
311 311 try:
312 312 minIndex = inda[0][0]
313 313 except:
314 314 minIndex = 0
315 315
316 316 try:
317 317 maxIndex = indb[0][-1]
318 318 except:
319 319 maxIndex = len(heights)
320 320
321 321 self.selectHeightsByIndex(minIndex, maxIndex)
322 322
323 323 return 1
324 324
325 325 def getBeaconSignal(self, tauindex = 0, channelindex = 0, hei_ref=None):
326 326 newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
327 327
328 328 if hei_ref != None:
329 329 newheis = numpy.where(self.dataOut.heightList>hei_ref)
330 330
331 331 minIndex = min(newheis[0])
332 332 maxIndex = max(newheis[0])
333 333 data_spc = self.dataOut.data_spc[:,:,minIndex:maxIndex+1]
334 334 heightList = self.dataOut.heightList[minIndex:maxIndex+1]
335 335
336 336 # determina indices
337 337 nheis = int(self.dataOut.radarControllerHeaderObj.txB/(self.dataOut.heightList[1]-self.dataOut.heightList[0]))
338 338 avg_dB = 10*numpy.log10(numpy.sum(data_spc[channelindex,:,:],axis=0))
339 339 beacon_dB = numpy.sort(avg_dB)[-nheis:]
340 340 beacon_heiIndexList = []
341 341 for val in avg_dB.tolist():
342 342 if val >= beacon_dB[0]:
343 343 beacon_heiIndexList.append(avg_dB.tolist().index(val))
344 344
345 345 #data_spc = data_spc[:,:,beacon_heiIndexList]
346 346 data_cspc = None
347 347 if self.dataOut.data_cspc is not None:
348 348 data_cspc = self.dataOut.data_cspc[:,:,minIndex:maxIndex+1]
349 349 #data_cspc = data_cspc[:,:,beacon_heiIndexList]
350 350
351 351 data_dc = None
352 352 if self.dataOut.data_dc is not None:
353 353 data_dc = self.dataOut.data_dc[:,minIndex:maxIndex+1]
354 354 #data_dc = data_dc[:,beacon_heiIndexList]
355 355
356 356 self.dataOut.data_spc = data_spc
357 357 self.dataOut.data_cspc = data_cspc
358 358 self.dataOut.data_dc = data_dc
359 359 self.dataOut.heightList = heightList
360 360 self.dataOut.beacon_heiIndexList = beacon_heiIndexList
361 361
362 362 return 1
363 363
364 364
365 365 def selectHeightsByIndex(self, minIndex, maxIndex):
366 366 """
367 367 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
368 368 minIndex <= index <= maxIndex
369 369
370 370 Input:
371 371 minIndex : valor de indice minimo de altura a considerar
372 372 maxIndex : valor de indice maximo de altura a considerar
373 373
374 374 Affected:
375 375 self.dataOut.data_spc
376 376 self.dataOut.data_cspc
377 377 self.dataOut.data_dc
378 378 self.dataOut.heightList
379 379
380 380 Return:
381 381 1 si el metodo se ejecuto con exito caso contrario devuelve 0
382 382 """
383 383
384 384 if (minIndex < 0) or (minIndex > maxIndex):
385 385 raise ValueError, "Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex)
386 386
387 387 if (maxIndex >= self.dataOut.nHeights):
388 388 maxIndex = self.dataOut.nHeights-1
389 389
390 390 #Spectra
391 391 data_spc = self.dataOut.data_spc[:,:,minIndex:maxIndex+1]
392 392
393 393 data_cspc = None
394 394 if self.dataOut.data_cspc is not None:
395 395 data_cspc = self.dataOut.data_cspc[:,:,minIndex:maxIndex+1]
396 396
397 397 data_dc = None
398 398 if self.dataOut.data_dc is not None:
399 399 data_dc = self.dataOut.data_dc[:,minIndex:maxIndex+1]
400 400
401 401 self.dataOut.data_spc = data_spc
402 402 self.dataOut.data_cspc = data_cspc
403 403 self.dataOut.data_dc = data_dc
404 404
405 405 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex+1]
406 406
407 407 return 1
408 408
409 409 def removeDC(self, mode = 2):
410 410 jspectra = self.dataOut.data_spc
411 411 jcspectra = self.dataOut.data_cspc
412 412
413 413
414 414 num_chan = jspectra.shape[0]
415 415 num_hei = jspectra.shape[2]
416 416
417 417 if jcspectra is not None:
418 418 jcspectraExist = True
419 419 num_pairs = jcspectra.shape[0]
420 420 else: jcspectraExist = False
421 421
422 422 freq_dc = jspectra.shape[1]/2
423 423 ind_vel = numpy.array([-2,-1,1,2]) + freq_dc
424 424
425 425 if ind_vel[0]<0:
426 426 ind_vel[range(0,1)] = ind_vel[range(0,1)] + self.num_prof
427 427
428 428 if mode == 1:
429 429 jspectra[:,freq_dc,:] = (jspectra[:,ind_vel[1],:] + jspectra[:,ind_vel[2],:])/2 #CORRECCION
430 430
431 431 if jcspectraExist:
432 432 jcspectra[:,freq_dc,:] = (jcspectra[:,ind_vel[1],:] + jcspectra[:,ind_vel[2],:])/2
433 433
434 434 if mode == 2:
435 435
436 436 vel = numpy.array([-2,-1,1,2])
437 437 xx = numpy.zeros([4,4])
438 438
439 439 for fil in range(4):
440 440 xx[fil,:] = vel[fil]**numpy.asarray(range(4))
441 441
442 442 xx_inv = numpy.linalg.inv(xx)
443 443 xx_aux = xx_inv[0,:]
444 444
445 445 for ich in range(num_chan):
446 446 yy = jspectra[ich,ind_vel,:]
447 447 jspectra[ich,freq_dc,:] = numpy.dot(xx_aux,yy)
448 448
449 449 junkid = jspectra[ich,freq_dc,:]<=0
450 450 cjunkid = sum(junkid)
451 451
452 452 if cjunkid.any():
453 453 jspectra[ich,freq_dc,junkid.nonzero()] = (jspectra[ich,ind_vel[1],junkid] + jspectra[ich,ind_vel[2],junkid])/2
454 454
455 455 if jcspectraExist:
456 456 for ip in range(num_pairs):
457 457 yy = jcspectra[ip,ind_vel,:]
458 458 jcspectra[ip,freq_dc,:] = numpy.dot(xx_aux,yy)
459 459
460 460
461 461 self.dataOut.data_spc = jspectra
462 462 self.dataOut.data_cspc = jcspectra
463 463
464 464 return 1
465 465
466 466 def removeInterference(self, interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None):
467 467
468 468 jspectra = self.dataOut.data_spc
469 469 jcspectra = self.dataOut.data_cspc
470 470 jnoise = self.dataOut.getNoise()
471 471 num_incoh = self.dataOut.nIncohInt
472 472
473 473 num_channel = jspectra.shape[0]
474 474 num_prof = jspectra.shape[1]
475 475 num_hei = jspectra.shape[2]
476 476
477 477 #hei_interf
478 478 if hei_interf is None:
479 479 count_hei = num_hei/2 #Como es entero no importa
480 480 hei_interf = numpy.asmatrix(range(count_hei)) + num_hei - count_hei
481 481 hei_interf = numpy.asarray(hei_interf)[0]
482 482 #nhei_interf
483 483 if (nhei_interf == None):
484 484 nhei_interf = 5
485 485 if (nhei_interf < 1):
486 486 nhei_interf = 1
487 487 if (nhei_interf > count_hei):
488 488 nhei_interf = count_hei
489 489 if (offhei_interf == None):
490 490 offhei_interf = 0
491 491
492 492 ind_hei = range(num_hei)
493 493 # mask_prof = numpy.asarray(range(num_prof - 2)) + 1
494 494 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1
495 495 mask_prof = numpy.asarray(range(num_prof))
496 496 num_mask_prof = mask_prof.size
497 497 comp_mask_prof = [0, num_prof/2]
498 498
499 499
500 500 #noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal
501 501 if (jnoise.size < num_channel or numpy.isnan(jnoise).any()):
502 502 jnoise = numpy.nan
503 503 noise_exist = jnoise[0] < numpy.Inf
504 504
505 505 #Subrutina de Remocion de la Interferencia
506 506 for ich in range(num_channel):
507 507 #Se ordena los espectros segun su potencia (menor a mayor)
508 508 power = jspectra[ich,mask_prof,:]
509 509 power = power[:,hei_interf]
510 510 power = power.sum(axis = 0)
511 511 psort = power.ravel().argsort()
512 512
513 513 #Se estima la interferencia promedio en los Espectros de Potencia empleando
514 514 junkspc_interf = jspectra[ich,:,hei_interf[psort[range(offhei_interf, nhei_interf + offhei_interf)]]]
515 515
516 516 if noise_exist:
517 517 # tmp_noise = jnoise[ich] / num_prof
518 518 tmp_noise = jnoise[ich]
519 519 junkspc_interf = junkspc_interf - tmp_noise
520 520 #junkspc_interf[:,comp_mask_prof] = 0
521 521
522 522 jspc_interf = junkspc_interf.sum(axis = 0) / nhei_interf
523 523 jspc_interf = jspc_interf.transpose()
524 524 #Calculando el espectro de interferencia promedio
525 525 noiseid = numpy.where(jspc_interf <= tmp_noise/ numpy.sqrt(num_incoh))
526 526 noiseid = noiseid[0]
527 527 cnoiseid = noiseid.size
528 528 interfid = numpy.where(jspc_interf > tmp_noise/ numpy.sqrt(num_incoh))
529 529 interfid = interfid[0]
530 530 cinterfid = interfid.size
531 531
532 532 if (cnoiseid > 0): jspc_interf[noiseid] = 0
533 533
534 534 #Expandiendo los perfiles a limpiar
535 535 if (cinterfid > 0):
536 536 new_interfid = (numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof)%num_prof
537 537 new_interfid = numpy.asarray(new_interfid)
538 538 new_interfid = {x for x in new_interfid}
539 539 new_interfid = numpy.array(list(new_interfid))
540 540 new_cinterfid = new_interfid.size
541 541 else: new_cinterfid = 0
542 542
543 543 for ip in range(new_cinterfid):
544 544 ind = junkspc_interf[:,new_interfid[ip]].ravel().argsort()
545 545 jspc_interf[new_interfid[ip]] = junkspc_interf[ind[nhei_interf/2],new_interfid[ip]]
546 546
547 547
548 548 jspectra[ich,:,ind_hei] = jspectra[ich,:,ind_hei] - jspc_interf #Corregir indices
549 549
550 550 #Removiendo la interferencia del punto de mayor interferencia
551 551 ListAux = jspc_interf[mask_prof].tolist()
552 552 maxid = ListAux.index(max(ListAux))
553 553
554 554
555 555 if cinterfid > 0:
556 556 for ip in range(cinterfid*(interf == 2) - 1):
557 557 ind = (jspectra[ich,interfid[ip],:] < tmp_noise*(1 + 1/numpy.sqrt(num_incoh))).nonzero()
558 558 cind = len(ind)
559 559
560 560 if (cind > 0):
561 561 jspectra[ich,interfid[ip],ind] = tmp_noise*(1 + (numpy.random.uniform(cind) - 0.5)/numpy.sqrt(num_incoh))
562 562
563 563 ind = numpy.array([-2,-1,1,2])
564 564 xx = numpy.zeros([4,4])
565 565
566 566 for id1 in range(4):
567 567 xx[:,id1] = ind[id1]**numpy.asarray(range(4))
568 568
569 569 xx_inv = numpy.linalg.inv(xx)
570 570 xx = xx_inv[:,0]
571 571 ind = (ind + maxid + num_mask_prof)%num_mask_prof
572 572 yy = jspectra[ich,mask_prof[ind],:]
573 573 jspectra[ich,mask_prof[maxid],:] = numpy.dot(yy.transpose(),xx)
574 574
575 575
576 576 indAux = (jspectra[ich,:,:] < tmp_noise*(1-1/numpy.sqrt(num_incoh))).nonzero()
577 577 jspectra[ich,indAux[0],indAux[1]] = tmp_noise * (1 - 1/numpy.sqrt(num_incoh))
578 578
579 579 #Remocion de Interferencia en el Cross Spectra
580 580 if jcspectra is None: return jspectra, jcspectra
581 581 num_pairs = jcspectra.size/(num_prof*num_hei)
582 582 jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei)
583 583
584 584 for ip in range(num_pairs):
585 585
586 586 #-------------------------------------------
587 587
588 588 cspower = numpy.abs(jcspectra[ip,mask_prof,:])
589 589 cspower = cspower[:,hei_interf]
590 590 cspower = cspower.sum(axis = 0)
591 591
592 592 cspsort = cspower.ravel().argsort()
593 593 junkcspc_interf = jcspectra[ip,:,hei_interf[cspsort[range(offhei_interf, nhei_interf + offhei_interf)]]]
594 594 junkcspc_interf = junkcspc_interf.transpose()
595 595 jcspc_interf = junkcspc_interf.sum(axis = 1)/nhei_interf
596 596
597 597 ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort()
598 598
599 599 median_real = numpy.median(numpy.real(junkcspc_interf[mask_prof[ind[range(3*num_prof/4)]],:]))
600 600 median_imag = numpy.median(numpy.imag(junkcspc_interf[mask_prof[ind[range(3*num_prof/4)]],:]))
601 601 junkcspc_interf[comp_mask_prof,:] = numpy.complex(median_real, median_imag)
602 602
603 603 for iprof in range(num_prof):
604 604 ind = numpy.abs(junkcspc_interf[iprof,:]).ravel().argsort()
605 605 jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf/2]]
606 606
607 607 #Removiendo la Interferencia
608 608 jcspectra[ip,:,ind_hei] = jcspectra[ip,:,ind_hei] - jcspc_interf
609 609
610 610 ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist()
611 611 maxid = ListAux.index(max(ListAux))
612 612
613 613 ind = numpy.array([-2,-1,1,2])
614 614 xx = numpy.zeros([4,4])
615 615
616 616 for id1 in range(4):
617 617 xx[:,id1] = ind[id1]**numpy.asarray(range(4))
618 618
619 619 xx_inv = numpy.linalg.inv(xx)
620 620 xx = xx_inv[:,0]
621 621
622 622 ind = (ind + maxid + num_mask_prof)%num_mask_prof
623 623 yy = jcspectra[ip,mask_prof[ind],:]
624 624 jcspectra[ip,mask_prof[maxid],:] = numpy.dot(yy.transpose(),xx)
625 625
626 626 #Guardar Resultados
627 627 self.dataOut.data_spc = jspectra
628 628 self.dataOut.data_cspc = jcspectra
629 629
630 630 return 1
631 631
632 632 def setRadarFrequency(self, frequency=None):
633 633
634 634 if frequency != None:
635 635 self.dataOut.frequency = frequency
636 636
637 637 return 1
638 638
639 639 def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None):
640 640 #validacion de rango
641 641 if minHei == None:
642 642 minHei = self.dataOut.heightList[0]
643 643
644 644 if maxHei == None:
645 645 maxHei = self.dataOut.heightList[-1]
646 646
647 647 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
648 648 print 'minHei: %.2f is out of the heights range'%(minHei)
649 649 print 'minHei is setting to %.2f'%(self.dataOut.heightList[0])
650 650 minHei = self.dataOut.heightList[0]
651 651
652 652 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
653 653 print 'maxHei: %.2f is out of the heights range'%(maxHei)
654 654 print 'maxHei is setting to %.2f'%(self.dataOut.heightList[-1])
655 655 maxHei = self.dataOut.heightList[-1]
656 656
657 657 # validacion de velocidades
658 658 velrange = self.dataOut.getVelRange(1)
659 659
660 660 if minVel == None:
661 661 minVel = velrange[0]
662 662
663 663 if maxVel == None:
664 664 maxVel = velrange[-1]
665 665
666 666 if (minVel < velrange[0]) or (minVel > maxVel):
667 667 print 'minVel: %.2f is out of the velocity range'%(minVel)
668 668 print 'minVel is setting to %.2f'%(velrange[0])
669 669 minVel = velrange[0]
670 670
671 671 if (maxVel > velrange[-1]) or (maxVel < minVel):
672 672 print 'maxVel: %.2f is out of the velocity range'%(maxVel)
673 673 print 'maxVel is setting to %.2f'%(velrange[-1])
674 674 maxVel = velrange[-1]
675 675
676 676 # seleccion de indices para rango
677 677 minIndex = 0
678 678 maxIndex = 0
679 679 heights = self.dataOut.heightList
680 680
681 681 inda = numpy.where(heights >= minHei)
682 682 indb = numpy.where(heights <= maxHei)
683 683
684 684 try:
685 685 minIndex = inda[0][0]
686 686 except:
687 687 minIndex = 0
688 688
689 689 try:
690 690 maxIndex = indb[0][-1]
691 691 except:
692 692 maxIndex = len(heights)
693 693
694 694 if (minIndex < 0) or (minIndex > maxIndex):
695 695 raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
696 696
697 697 if (maxIndex >= self.dataOut.nHeights):
698 698 maxIndex = self.dataOut.nHeights-1
699 699
700 700 # seleccion de indices para velocidades
701 701 indminvel = numpy.where(velrange >= minVel)
702 702 indmaxvel = numpy.where(velrange <= maxVel)
703 703 try:
704 704 minIndexVel = indminvel[0][0]
705 705 except:
706 706 minIndexVel = 0
707 707
708 708 try:
709 709 maxIndexVel = indmaxvel[0][-1]
710 710 except:
711 711 maxIndexVel = len(velrange)
712 712
713 713 #seleccion del espectro
714 714 data_spc = self.dataOut.data_spc[:,minIndexVel:maxIndexVel+1,minIndex:maxIndex+1]
715 715 #estimacion de ruido
716 716 noise = numpy.zeros(self.dataOut.nChannels)
717 717
718 718 for channel in range(self.dataOut.nChannels):
719 719 daux = data_spc[channel,:,:]
720 720 noise[channel] = hildebrand_sekhon(daux, self.dataOut.nIncohInt)
721 721
722 722 self.dataOut.noise_estimation = noise.copy()
723 723
724 724 return 1
725 725
726 726 class IncohInt(Operation):
727 727
728 728
729 729 __profIndex = 0
730 730 __withOverapping = False
731 731
732 732 __byTime = False
733 733 __initime = None
734 734 __lastdatatime = None
735 735 __integrationtime = None
736 736
737 737 __buffer_spc = None
738 738 __buffer_cspc = None
739 739 __buffer_dc = None
740 740
741 741 __dataReady = False
742 742
743 743 __timeInterval = None
744 744
745 parameters = {
746 'n': global_type_float,
747 'timeInterval': global_type_integer,
748 'overlapping': global_type_boolean,
749 }
750
745 751 n = None
746 752
747 753
748 754
749 755 def __init__(self, **kwargs):
750 756
751 757 Operation.__init__(self, **kwargs)
752 758 # self.isConfig = False
753 759
754 760 def setup(self, n=None, timeInterval=None, overlapping=False):
755 761 """
756 762 Set the parameters of the integration class.
757 763
758 764 Inputs:
759 765
760 766 n : Number of coherent integrations
761 767 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
762 768 overlapping :
763 769
764 770 """
765 771
766 772 self.__initime = None
767 773 self.__lastdatatime = 0
768 774
769 775 self.__buffer_spc = 0
770 776 self.__buffer_cspc = 0
771 777 self.__buffer_dc = 0
772 778
773 779 self.__profIndex = 0
774 780 self.__dataReady = False
775 781 self.__byTime = False
776 782
777 783 if n is None and timeInterval is None:
778 784 raise ValueError, "n or timeInterval should be specified ..."
779 785
780 786 if n is not None:
781 787 self.n = int(n)
782 788 else:
783 789 self.__integrationtime = int(timeInterval) #if (type(timeInterval)!=integer) -> change this line
784 790 self.n = None
785 791 self.__byTime = True
786 792
787 793 def putData(self, data_spc, data_cspc, data_dc):
788 794
789 795 """
790 796 Add a profile to the __buffer_spc and increase in one the __profileIndex
791 797
792 798 """
793 799
794 800 self.__buffer_spc += data_spc
795 801
796 802 if data_cspc is None:
797 803 self.__buffer_cspc = None
798 804 else:
799 805 self.__buffer_cspc += data_cspc
800 806
801 807 if data_dc is None:
802 808 self.__buffer_dc = None
803 809 else:
804 810 self.__buffer_dc += data_dc
805 811
806 812 self.__profIndex += 1
807 813
808 814 return
809 815
810 816 def pushData(self):
811 817 """
812 818 Return the sum of the last profiles and the profiles used in the sum.
813 819
814 820 Affected:
815 821
816 822 self.__profileIndex
817 823
818 824 """
819 825
820 826 data_spc = self.__buffer_spc
821 827 data_cspc = self.__buffer_cspc
822 828 data_dc = self.__buffer_dc
823 829 n = self.__profIndex
824 830
825 831 self.__buffer_spc = 0
826 832 self.__buffer_cspc = 0
827 833 self.__buffer_dc = 0
828 834 self.__profIndex = 0
829 835
830 836 return data_spc, data_cspc, data_dc, n
831 837
832 838 def byProfiles(self, *args):
833 839
834 840 self.__dataReady = False
835 841 avgdata_spc = None
836 842 avgdata_cspc = None
837 843 avgdata_dc = None
838 844
839 845 self.putData(*args)
840 846
841 847 if self.__profIndex == self.n:
842 848
843 849 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
844 850 self.n = n
845 851 self.__dataReady = True
846 852
847 853 return avgdata_spc, avgdata_cspc, avgdata_dc
848 854
849 855 def byTime(self, datatime, *args):
850 856
851 857 self.__dataReady = False
852 858 avgdata_spc = None
853 859 avgdata_cspc = None
854 860 avgdata_dc = None
855 861
856 862 self.putData(*args)
857 863
858 864 if (datatime - self.__initime) >= self.__integrationtime:
859 865 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
860 866 self.n = n
861 867 self.__dataReady = True
862 868
863 869 return avgdata_spc, avgdata_cspc, avgdata_dc
864 870
865 871 def integrate(self, datatime, *args):
866 872
867 873 if self.__profIndex == 0:
868 874 self.__initime = datatime
869 875
870 876 if self.__byTime:
871 877 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(datatime, *args)
872 878 else:
873 879 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
874 880
875 881 if not self.__dataReady:
876 882 return None, None, None, None
877 883
878 884 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
879 885
880 886 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
881 887
882 888 if n==1:
883 889 return
884 890
885 891 dataOut.flagNoData = True
886 892
887 893 if not self.isConfig:
888 894 self.setup(n, timeInterval, overlapping)
889 895 self.isConfig = True
890 896
891 897 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
892 898 dataOut.data_spc,
893 899 dataOut.data_cspc,
894 900 dataOut.data_dc)
895 901
896 902 if self.__dataReady:
897 903
898 904 dataOut.data_spc = avgdata_spc
899 905 dataOut.data_cspc = avgdata_cspc
900 906 dataOut.data_dc = avgdata_dc
901 907
902 908 dataOut.nIncohInt *= self.n
903 909 dataOut.utctime = avgdatatime
904 910 dataOut.flagNoData = False
@@ -1,1290 +1,1322
1 1 import sys
2 2 import numpy
3 3 from scipy import interpolate
4 4
5 5 from jroproc_base import ProcessingUnit, Operation
6 6 from schainpy.model.data.jrodata import Voltage
7 7
8 8 class VoltageProc(ProcessingUnit):
9 9
10 10
11 11 def __init__(self, **kwargs):
12 12
13 13 ProcessingUnit.__init__(self, **kwargs)
14 14
15 15 # self.objectDict = {}
16 16 self.dataOut = Voltage()
17 17 self.flip = 1
18 18
19 19 def run(self):
20 20 if self.dataIn.type == 'AMISR':
21 21 self.__updateObjFromAmisrInput()
22 22
23 23 if self.dataIn.type == 'Voltage':
24 24 self.dataOut.copy(self.dataIn)
25 25
26 26 # self.dataOut.copy(self.dataIn)
27 27
28 28 def __updateObjFromAmisrInput(self):
29 29
30 30 self.dataOut.timeZone = self.dataIn.timeZone
31 31 self.dataOut.dstFlag = self.dataIn.dstFlag
32 32 self.dataOut.errorCount = self.dataIn.errorCount
33 33 self.dataOut.useLocalTime = self.dataIn.useLocalTime
34 34
35 35 self.dataOut.flagNoData = self.dataIn.flagNoData
36 36 self.dataOut.data = self.dataIn.data
37 37 self.dataOut.utctime = self.dataIn.utctime
38 38 self.dataOut.channelList = self.dataIn.channelList
39 39 # self.dataOut.timeInterval = self.dataIn.timeInterval
40 40 self.dataOut.heightList = self.dataIn.heightList
41 41 self.dataOut.nProfiles = self.dataIn.nProfiles
42 42
43 43 self.dataOut.nCohInt = self.dataIn.nCohInt
44 44 self.dataOut.ippSeconds = self.dataIn.ippSeconds
45 45 self.dataOut.frequency = self.dataIn.frequency
46 46
47 47 self.dataOut.azimuth = self.dataIn.azimuth
48 48 self.dataOut.zenith = self.dataIn.zenith
49 49
50 50 self.dataOut.beam.codeList = self.dataIn.beam.codeList
51 51 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
52 52 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
53 53 #
54 54 # pass#
55 55 #
56 56 # def init(self):
57 57 #
58 58 #
59 59 # if self.dataIn.type == 'AMISR':
60 60 # self.__updateObjFromAmisrInput()
61 61 #
62 62 # if self.dataIn.type == 'Voltage':
63 63 # self.dataOut.copy(self.dataIn)
64 64 # # No necesita copiar en cada init() los atributos de dataIn
65 65 # # la copia deberia hacerse por cada nuevo bloque de datos
66 66
67 67 def selectChannels(self, channelList):
68 68
69 69 channelIndexList = []
70 70
71 71 for channel in channelList:
72 72 if channel not in self.dataOut.channelList:
73 73 raise ValueError, "Channel %d is not in %s" %(channel, str(self.dataOut.channelList))
74 74
75 75 index = self.dataOut.channelList.index(channel)
76 76 channelIndexList.append(index)
77 77
78 78 self.selectChannelsByIndex(channelIndexList)
79 79
80 80 def selectChannelsByIndex(self, channelIndexList):
81 81 """
82 82 Selecciona un bloque de datos en base a canales segun el channelIndexList
83 83
84 84 Input:
85 85 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
86 86
87 87 Affected:
88 88 self.dataOut.data
89 89 self.dataOut.channelIndexList
90 90 self.dataOut.nChannels
91 91 self.dataOut.m_ProcessingHeader.totalSpectra
92 92 self.dataOut.systemHeaderObj.numChannels
93 93 self.dataOut.m_ProcessingHeader.blockSize
94 94
95 95 Return:
96 96 None
97 97 """
98 98
99 99 for channelIndex in channelIndexList:
100 100 if channelIndex not in self.dataOut.channelIndexList:
101 101 print channelIndexList
102 102 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
103 103
104 104 if self.dataOut.flagDataAsBlock:
105 105 """
106 106 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
107 107 """
108 108 data = self.dataOut.data[channelIndexList,:,:]
109 109 else:
110 110 data = self.dataOut.data[channelIndexList,:]
111 111
112 112 self.dataOut.data = data
113 113 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
114 114 # self.dataOut.nChannels = nChannels
115 115
116 116 return 1
117 117
118 118 def selectHeights(self, minHei=None, maxHei=None):
119 119 """
120 120 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
121 121 minHei <= height <= maxHei
122 122
123 123 Input:
124 124 minHei : valor minimo de altura a considerar
125 125 maxHei : valor maximo de altura a considerar
126 126
127 127 Affected:
128 128 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
129 129
130 130 Return:
131 131 1 si el metodo se ejecuto con exito caso contrario devuelve 0
132 132 """
133 133
134 134 if minHei == None:
135 135 minHei = self.dataOut.heightList[0]
136 136
137 137 if maxHei == None:
138 138 maxHei = self.dataOut.heightList[-1]
139 139
140 140 if (minHei < self.dataOut.heightList[0]):
141 141 minHei = self.dataOut.heightList[0]
142 142
143 143 if (maxHei > self.dataOut.heightList[-1]):
144 144 maxHei = self.dataOut.heightList[-1]
145 145
146 146 minIndex = 0
147 147 maxIndex = 0
148 148 heights = self.dataOut.heightList
149 149
150 150 inda = numpy.where(heights >= minHei)
151 151 indb = numpy.where(heights <= maxHei)
152 152
153 153 try:
154 154 minIndex = inda[0][0]
155 155 except:
156 156 minIndex = 0
157 157
158 158 try:
159 159 maxIndex = indb[0][-1]
160 160 except:
161 161 maxIndex = len(heights)
162 162
163 163 self.selectHeightsByIndex(minIndex, maxIndex)
164 164
165 165 return 1
166 166
167 167
168 168 def selectHeightsByIndex(self, minIndex, maxIndex):
169 169 """
170 170 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
171 171 minIndex <= index <= maxIndex
172 172
173 173 Input:
174 174 minIndex : valor de indice minimo de altura a considerar
175 175 maxIndex : valor de indice maximo de altura a considerar
176 176
177 177 Affected:
178 178 self.dataOut.data
179 179 self.dataOut.heightList
180 180
181 181 Return:
182 182 1 si el metodo se ejecuto con exito caso contrario devuelve 0
183 183 """
184 184
185 185 if (minIndex < 0) or (minIndex > maxIndex):
186 186 raise ValueError, "Height index range (%d,%d) is not valid" % (minIndex, maxIndex)
187 187
188 188 if (maxIndex >= self.dataOut.nHeights):
189 189 maxIndex = self.dataOut.nHeights
190 190
191 191 #voltage
192 192 if self.dataOut.flagDataAsBlock:
193 193 """
194 194 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
195 195 """
196 196 data = self.dataOut.data[:,:, minIndex:maxIndex]
197 197 else:
198 198 data = self.dataOut.data[:, minIndex:maxIndex]
199 199
200 200 # firstHeight = self.dataOut.heightList[minIndex]
201 201
202 202 self.dataOut.data = data
203 203 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex]
204 204
205 205 if self.dataOut.nHeights <= 1:
206 206 raise ValueError, "selectHeights: Too few heights. Current number of heights is %d" %(self.dataOut.nHeights)
207 207
208 208 return 1
209 209
210 210
211 211 def filterByHeights(self, window):
212 212
213 213 deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
214 214
215 215 if window == None:
216 216 window = (self.dataOut.radarControllerHeaderObj.txA/self.dataOut.radarControllerHeaderObj.nBaud) / deltaHeight
217 217
218 218 newdelta = deltaHeight * window
219 219 r = self.dataOut.nHeights % window
220 220 newheights = (self.dataOut.nHeights-r)/window
221 221
222 222 if newheights <= 1:
223 223 raise ValueError, "filterByHeights: Too few heights. Current number of heights is %d and window is %d" %(self.dataOut.nHeights, window)
224 224
225 225 if self.dataOut.flagDataAsBlock:
226 226 """
227 227 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
228 228 """
229 229 buffer = self.dataOut.data[:, :, 0:self.dataOut.nHeights-r]
230 230 buffer = buffer.reshape(self.dataOut.nChannels,self.dataOut.nProfiles,self.dataOut.nHeights/window,window)
231 231 buffer = numpy.sum(buffer,3)
232 232
233 233 else:
234 234 buffer = self.dataOut.data[:,0:self.dataOut.nHeights-r]
235 235 buffer = buffer.reshape(self.dataOut.nChannels,self.dataOut.nHeights/window,window)
236 236 buffer = numpy.sum(buffer,2)
237 237
238 238 self.dataOut.data = buffer
239 239 self.dataOut.heightList = self.dataOut.heightList[0] + numpy.arange( newheights )*newdelta
240 240 self.dataOut.windowOfFilter = window
241 241
242 242 def setH0(self, h0, deltaHeight = None):
243 243
244 244 if not deltaHeight:
245 245 deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
246 246
247 247 nHeights = self.dataOut.nHeights
248 248
249 249 newHeiRange = h0 + numpy.arange(nHeights)*deltaHeight
250 250
251 251 self.dataOut.heightList = newHeiRange
252 252
253 253 def deFlip(self, channelList = []):
254 254
255 255 data = self.dataOut.data.copy()
256 256
257 257 if self.dataOut.flagDataAsBlock:
258 258 flip = self.flip
259 259 profileList = range(self.dataOut.nProfiles)
260 260
261 261 if not channelList:
262 262 for thisProfile in profileList:
263 263 data[:,thisProfile,:] = data[:,thisProfile,:]*flip
264 264 flip *= -1.0
265 265 else:
266 266 for thisChannel in channelList:
267 267 if thisChannel not in self.dataOut.channelList:
268 268 continue
269 269
270 270 for thisProfile in profileList:
271 271 data[thisChannel,thisProfile,:] = data[thisChannel,thisProfile,:]*flip
272 272 flip *= -1.0
273 273
274 274 self.flip = flip
275 275
276 276 else:
277 277 if not channelList:
278 278 data[:,:] = data[:,:]*self.flip
279 279 else:
280 280 for thisChannel in channelList:
281 281 if thisChannel not in self.dataOut.channelList:
282 282 continue
283 283
284 284 data[thisChannel,:] = data[thisChannel,:]*self.flip
285 285
286 286 self.flip *= -1.
287 287
288 288 self.dataOut.data = data
289 289
290 290 def setRadarFrequency(self, frequency=None):
291 291
292 292 if frequency != None:
293 293 self.dataOut.frequency = frequency
294 294
295 295 return 1
296 296
297 297 def interpolateHeights(self, topLim, botLim):
298 298 #69 al 72 para julia
299 299 #82-84 para meteoros
300 300 if len(numpy.shape(self.dataOut.data))==2:
301 301 sampInterp = (self.dataOut.data[:,botLim-1] + self.dataOut.data[:,topLim+1])/2
302 302 sampInterp = numpy.transpose(numpy.tile(sampInterp,(topLim-botLim + 1,1)))
303 303 #self.dataOut.data[:,botLim:limSup+1] = sampInterp
304 304 self.dataOut.data[:,botLim:topLim+1] = sampInterp
305 305 else:
306 306 nHeights = self.dataOut.data.shape[2]
307 307 x = numpy.hstack((numpy.arange(botLim),numpy.arange(topLim+1,nHeights)))
308 308 y = self.dataOut.data[:,:,range(botLim)+range(topLim+1,nHeights)]
309 309 f = interpolate.interp1d(x, y, axis = 2)
310 310 xnew = numpy.arange(botLim,topLim+1)
311 311 ynew = f(xnew)
312 312
313 313 self.dataOut.data[:,:,botLim:topLim+1] = ynew
314 314
315 315 # import collections
316 316
317 317 class CohInt(Operation):
318 318
319 319 isConfig = False
320 320
321 321 __profIndex = 0
322 322 __withOverapping = False
323 323
324 324 __byTime = False
325 325 __initime = None
326 326 __lastdatatime = None
327 327 __integrationtime = None
328 328
329 329 __buffer = None
330 330
331 331 __dataReady = False
332 332
333 333 n = None
334 334
335 335 parameters = {
336 'n': 'int',
337 'timeInterval':'float',
338 'overlapping': 'boolean',
339 'byblock': 'boolean'
336 'id': global_type_string,
337 'wintitle': global_type_string,
338 'pairsList': global_type_pairsList,
339 'showprofile': global_type_boolean,
340 'xmin': global_type_float,
341 'xmax': global_type_float,
342 'ymin': global_type_float,
343 'ymax': global_type_float,
344 'zmin': global_type_float,
345 'zmax': global_type_float,
346 'timerange': global_type_float,
347 'phase_min': global_type_float,
348 'phase_max': global_type_float,
349 'save': global_type_boolean,
350 'figpath': global_type_string,
351 'figfile': global_type_string,
352 'ftp': global_type_boolean,
353 'wr_period': global_type_integer,
354 'coherence_cmap': global_type_colormap,
355 'phase_cmap': global_type_colormap,
356 'show': global_type_boolean,
357 'server': global_type_string,
358 'folder': global_type_string,
359 'username': global_type_string,
360 'password': global_type_string,
361 'ftp_wei': global_type_integer,
362 'exp_code': global_type_integer,
363 'sub_exp_code': global_type_integer,
364 'plot_pos': global_type_integer,
340 365 }
341 366
342 367 def __init__(self, **kwargs):
343 368
344 369 Operation.__init__(self, **kwargs)
345 370
346 371 # self.isConfig = False
347 372
348 373 def setup(self, n=None, timeInterval=None, overlapping=False, byblock=False):
349 374 """
350 375 Set the parameters of the integration class.
351 376
352 377 Inputs:
353 378
354 379 n : Number of coherent integrations
355 380 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
356 381 overlapping :
357 382 """
358 383
359 384 self.__initime = None
360 385 self.__lastdatatime = 0
361 386 self.__buffer = None
362 387 self.__dataReady = False
363 388 self.byblock = byblock
364 389
365 390 if n == None and timeInterval == None:
366 391 raise ValueError, "n or timeInterval should be specified ..."
367 392
368 393 if n != None:
369 394 self.n = n
370 395 self.__byTime = False
371 396 else:
372 397 self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line
373 398 self.n = 9999
374 399 self.__byTime = True
375 400
376 401 if overlapping:
377 402 self.__withOverapping = True
378 403 self.__buffer = None
379 404 else:
380 405 self.__withOverapping = False
381 406 self.__buffer = 0
382 407
383 408 self.__profIndex = 0
384 409
385 410 def putData(self, data):
386 411
387 412 """
388 413 Add a profile to the __buffer and increase in one the __profileIndex
389 414
390 415 """
391 416
392 417 if not self.__withOverapping:
393 418 self.__buffer += data.copy()
394 419 self.__profIndex += 1
395 420 return
396 421
397 422 #Overlapping data
398 423 nChannels, nHeis = data.shape
399 424 data = numpy.reshape(data, (1, nChannels, nHeis))
400 425
401 426 #If the buffer is empty then it takes the data value
402 427 if self.__buffer is None:
403 428 self.__buffer = data
404 429 self.__profIndex += 1
405 430 return
406 431
407 432 #If the buffer length is lower than n then stakcing the data value
408 433 if self.__profIndex < self.n:
409 434 self.__buffer = numpy.vstack((self.__buffer, data))
410 435 self.__profIndex += 1
411 436 return
412 437
413 438 #If the buffer length is equal to n then replacing the last buffer value with the data value
414 439 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
415 440 self.__buffer[self.n-1] = data
416 441 self.__profIndex = self.n
417 442 return
418 443
419 444
420 445 def pushData(self):
421 446 """
422 447 Return the sum of the last profiles and the profiles used in the sum.
423 448
424 449 Affected:
425 450
426 451 self.__profileIndex
427 452
428 453 """
429 454
430 455 if not self.__withOverapping:
431 456 data = self.__buffer
432 457 n = self.__profIndex
433 458
434 459 self.__buffer = 0
435 460 self.__profIndex = 0
436 461
437 462 return data, n
438 463
439 464 #Integration with Overlapping
440 465 data = numpy.sum(self.__buffer, axis=0)
441 466 n = self.__profIndex
442 467
443 468 return data, n
444 469
445 470 def byProfiles(self, data):
446 471
447 472 self.__dataReady = False
448 473 avgdata = None
449 474 # n = None
450 475
451 476 self.putData(data)
452 477
453 478 if self.__profIndex == self.n:
454 479
455 480 avgdata, n = self.pushData()
456 481 self.__dataReady = True
457 482
458 483 return avgdata
459 484
460 485 def byTime(self, data, datatime):
461 486
462 487 self.__dataReady = False
463 488 avgdata = None
464 489 n = None
465 490
466 491 self.putData(data)
467 492
468 493 if (datatime - self.__initime) >= self.__integrationtime:
469 494 avgdata, n = self.pushData()
470 495 self.n = n
471 496 self.__dataReady = True
472 497
473 498 return avgdata
474 499
475 500 def integrate(self, data, datatime=None):
476 501
477 502 if self.__initime == None:
478 503 self.__initime = datatime
479 504
480 505 if self.__byTime:
481 506 avgdata = self.byTime(data, datatime)
482 507 else:
483 508 avgdata = self.byProfiles(data)
484 509
485 510
486 511 self.__lastdatatime = datatime
487 512
488 513 if avgdata is None:
489 514 return None, None
490 515
491 516 avgdatatime = self.__initime
492 517
493 518 deltatime = datatime -self.__lastdatatime
494 519
495 520 if not self.__withOverapping:
496 521 self.__initime = datatime
497 522 else:
498 523 self.__initime += deltatime
499 524
500 525 return avgdata, avgdatatime
501 526
502 527 def integrateByBlock(self, dataOut):
503 528
504 529 times = int(dataOut.data.shape[1]/self.n)
505 530 avgdata = numpy.zeros((dataOut.nChannels, times, dataOut.nHeights), dtype=numpy.complex)
506 531
507 532 id_min = 0
508 533 id_max = self.n
509 534
510 535 for i in range(times):
511 536 junk = dataOut.data[:,id_min:id_max,:]
512 537 avgdata[:,i,:] = junk.sum(axis=1)
513 538 id_min += self.n
514 539 id_max += self.n
515 540
516 541 timeInterval = dataOut.ippSeconds*self.n
517 542 avgdatatime = (times - 1) * timeInterval + dataOut.utctime
518 543 self.__dataReady = True
519 544 return avgdata, avgdatatime
520 545
521 546 def run(self, dataOut, n=None, timeInterval=None, overlapping=False, byblock=False):
522 547
523 548 if not self.isConfig:
524 549 self.setup(n=n, timeInterval=timeInterval, overlapping=overlapping, byblock=byblock)
525 550 self.isConfig = True
526 551
527 552 if dataOut.flagDataAsBlock:
528 553 """
529 554 Si la data es leida por bloques, dimension = [nChannels, nProfiles, nHeis]
530 555 """
531 556 avgdata, avgdatatime = self.integrateByBlock(dataOut)
532 557 dataOut.nProfiles /= self.n
533 558 else:
534 559 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
535 560
536 561 # dataOut.timeInterval *= n
537 562 dataOut.flagNoData = True
538 563
539 564 if self.__dataReady:
540 565 dataOut.data = avgdata
541 566 dataOut.nCohInt *= self.n
542 567 dataOut.utctime = avgdatatime
543 568 # dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
544 569 dataOut.flagNoData = False
545 570
546 571 class Decoder(Operation):
547 572
548 573 isConfig = False
549 574 __profIndex = 0
550 575
551 576 code = None
552 577
553 578 nCode = None
554 579 nBaud = None
555
580
581 parameters = {
582 'code': global_type_list,
583 'nCode': global_type_integer,
584 'nBaud': global_type_integer,
585 'mode': global_type_integer,
586 'osamp': global_type_float,
587 }
556 588
557 589 def __init__(self, **kwargs):
558 590
559 591 Operation.__init__(self, **kwargs)
560 592
561 593 self.times = None
562 594 self.osamp = None
563 595 # self.__setValues = False
564 596 self.isConfig = False
565 597
566 598 def setup(self, code, osamp, dataOut):
567 599
568 600 self.__profIndex = 0
569 601
570 602 self.code = code
571 603
572 604 self.nCode = len(code)
573 605 self.nBaud = len(code[0])
574 606
575 607 if (osamp != None) and (osamp >1):
576 608 self.osamp = osamp
577 609 self.code = numpy.repeat(code, repeats=self.osamp, axis=1)
578 610 self.nBaud = self.nBaud*self.osamp
579 611
580 612 self.__nChannels = dataOut.nChannels
581 613 self.__nProfiles = dataOut.nProfiles
582 614 self.__nHeis = dataOut.nHeights
583 615
584 616 if self.__nHeis < self.nBaud:
585 617 raise ValueError, 'Number of heights (%d) should be greater than number of bauds (%d)' %(self.__nHeis, self.nBaud)
586 618
587 619 #Frequency
588 620 __codeBuffer = numpy.zeros((self.nCode, self.__nHeis), dtype=numpy.complex)
589 621
590 622 __codeBuffer[:,0:self.nBaud] = self.code
591 623
592 624 self.fft_code = numpy.conj(numpy.fft.fft(__codeBuffer, axis=1))
593 625
594 626 if dataOut.flagDataAsBlock:
595 627
596 628 self.ndatadec = self.__nHeis #- self.nBaud + 1
597 629
598 630 self.datadecTime = numpy.zeros((self.__nChannels, self.__nProfiles, self.ndatadec), dtype=numpy.complex)
599 631
600 632 else:
601 633
602 634 #Time
603 635 self.ndatadec = self.__nHeis #- self.nBaud + 1
604 636
605 637 self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex)
606 638
607 639 def __convolutionInFreq(self, data):
608 640
609 641 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
610 642
611 643 fft_data = numpy.fft.fft(data, axis=1)
612 644
613 645 conv = fft_data*fft_code
614 646
615 647 data = numpy.fft.ifft(conv,axis=1)
616 648
617 649 return data
618 650
619 651 def __convolutionInFreqOpt(self, data):
620 652
621 653 raise NotImplementedError
622 654
623 655 def __convolutionInTime(self, data):
624 656
625 657 code = self.code[self.__profIndex]
626 658
627 659 for i in range(self.__nChannels):
628 660 self.datadecTime[i,:] = numpy.correlate(data[i,:], code, mode='full')[self.nBaud-1:]
629 661
630 662 return self.datadecTime
631 663
632 664 def __convolutionByBlockInTime(self, data):
633 665
634 666 repetitions = self.__nProfiles / self.nCode
635 667
636 668 junk = numpy.lib.stride_tricks.as_strided(self.code, (repetitions, self.code.size), (0, self.code.itemsize))
637 669 junk = junk.flatten()
638 670 code_block = numpy.reshape(junk, (self.nCode*repetitions, self.nBaud))
639 671
640 672 for i in range(self.__nChannels):
641 673 for j in range(self.__nProfiles):
642 674 self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:]
643 675
644 676 return self.datadecTime
645 677
646 678 def __convolutionByBlockInFreq(self, data):
647 679
648 680 raise NotImplementedError, "Decoder by frequency fro Blocks not implemented"
649 681
650 682
651 683 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
652 684
653 685 fft_data = numpy.fft.fft(data, axis=2)
654 686
655 687 conv = fft_data*fft_code
656 688
657 689 data = numpy.fft.ifft(conv,axis=2)
658 690
659 691 return data
660 692
661 693 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0, osamp=None, times=None):
662 694
663 695 if dataOut.flagDecodeData:
664 696 print "This data is already decoded, recoding again ..."
665 697
666 698 if not self.isConfig:
667 699
668 700 if code is None:
669 701 if dataOut.code is None:
670 702 raise ValueError, "Code could not be read from %s instance. Enter a value in Code parameter" %dataOut.type
671 703
672 704 code = dataOut.code
673 705 else:
674 706 code = numpy.array(code).reshape(nCode,nBaud)
675 707
676 708 self.setup(code, osamp, dataOut)
677 709
678 710 self.isConfig = True
679 711
680 712 if mode == 3:
681 713 sys.stderr.write("Decoder Warning: mode=%d is not valid, using mode=0\n" %mode)
682 714
683 715 if times != None:
684 716 sys.stderr.write("Decoder Warning: Argument 'times' in not used anymore\n")
685 717
686 718 if self.code is None:
687 719 print "Fail decoding: Code is not defined."
688 720 return
689 721
690 722 datadec = None
691 723 if mode == 3:
692 724 mode = 0
693 725
694 726 if dataOut.flagDataAsBlock:
695 727 """
696 728 Decoding when data have been read as block,
697 729 """
698 730
699 731 if mode == 0:
700 732 datadec = self.__convolutionByBlockInTime(dataOut.data)
701 733 if mode == 1:
702 734 datadec = self.__convolutionByBlockInFreq(dataOut.data)
703 735 else:
704 736 """
705 737 Decoding when data have been read profile by profile
706 738 """
707 739 if mode == 0:
708 740 datadec = self.__convolutionInTime(dataOut.data)
709 741
710 742 if mode == 1:
711 743 datadec = self.__convolutionInFreq(dataOut.data)
712 744
713 745 if mode == 2:
714 746 datadec = self.__convolutionInFreqOpt(dataOut.data)
715 747
716 748 if datadec is None:
717 749 raise ValueError, "Codification mode selected is not valid: mode=%d. Try selecting 0 or 1" %mode
718 750
719 751 dataOut.code = self.code
720 752 dataOut.nCode = self.nCode
721 753 dataOut.nBaud = self.nBaud
722 754
723 755 dataOut.data = datadec
724 756
725 757 dataOut.heightList = dataOut.heightList[0:datadec.shape[-1]]
726 758
727 759 dataOut.flagDecodeData = True #asumo q la data esta decodificada
728 760
729 761 if self.__profIndex == self.nCode-1:
730 762 self.__profIndex = 0
731 763 return 1
732 764
733 765 self.__profIndex += 1
734 766
735 767 return 1
736 768 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
737 769
738 770
739 771 class ProfileConcat(Operation):
740 772
741 773 isConfig = False
742 774 buffer = None
743 775
744 776 def __init__(self, **kwargs):
745 777
746 778 Operation.__init__(self, **kwargs)
747 779 self.profileIndex = 0
748 780
749 781 def reset(self):
750 782 self.buffer = numpy.zeros_like(self.buffer)
751 783 self.start_index = 0
752 784 self.times = 1
753 785
754 786 def setup(self, data, m, n=1):
755 787 self.buffer = numpy.zeros((data.shape[0],data.shape[1]*m),dtype=type(data[0,0]))
756 788 self.nHeights = data.shape[1]#.nHeights
757 789 self.start_index = 0
758 790 self.times = 1
759 791
760 792 def concat(self, data):
761 793
762 794 self.buffer[:,self.start_index:self.nHeights*self.times] = data.copy()
763 795 self.start_index = self.start_index + self.nHeights
764 796
765 797 def run(self, dataOut, m):
766 798
767 799 dataOut.flagNoData = True
768 800
769 801 if not self.isConfig:
770 802 self.setup(dataOut.data, m, 1)
771 803 self.isConfig = True
772 804
773 805 if dataOut.flagDataAsBlock:
774 806 raise ValueError, "ProfileConcat can only be used when voltage have been read profile by profile, getBlock = False"
775 807
776 808 else:
777 809 self.concat(dataOut.data)
778 810 self.times += 1
779 811 if self.times > m:
780 812 dataOut.data = self.buffer
781 813 self.reset()
782 814 dataOut.flagNoData = False
783 815 # se deben actualizar mas propiedades del header y del objeto dataOut, por ejemplo, las alturas
784 816 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
785 817 xf = dataOut.heightList[0] + dataOut.nHeights * deltaHeight * m
786 818 dataOut.heightList = numpy.arange(dataOut.heightList[0], xf, deltaHeight)
787 819 dataOut.ippSeconds *= m
788 820
789 821 class ProfileSelector(Operation):
790 822
791 823 profileIndex = None
792 824 # Tamanho total de los perfiles
793 825 nProfiles = None
794 826
795 827 def __init__(self, **kwargs):
796 828
797 829 Operation.__init__(self, **kwargs)
798 830 self.profileIndex = 0
799 831
800 832 def incProfileIndex(self):
801 833
802 834 self.profileIndex += 1
803 835
804 836 if self.profileIndex >= self.nProfiles:
805 837 self.profileIndex = 0
806 838
807 839 def isThisProfileInRange(self, profileIndex, minIndex, maxIndex):
808 840
809 841 if profileIndex < minIndex:
810 842 return False
811 843
812 844 if profileIndex > maxIndex:
813 845 return False
814 846
815 847 return True
816 848
817 849 def isThisProfileInList(self, profileIndex, profileList):
818 850
819 851 if profileIndex not in profileList:
820 852 return False
821 853
822 854 return True
823 855
824 856 def run(self, dataOut, profileList=None, profileRangeList=None, beam=None, byblock=False, rangeList = None, nProfiles=None):
825 857
826 858 """
827 859 ProfileSelector:
828 860
829 861 Inputs:
830 862 profileList : Index of profiles selected. Example: profileList = (0,1,2,7,8)
831 863
832 864 profileRangeList : Minimum and maximum profile indexes. Example: profileRangeList = (4, 30)
833 865
834 866 rangeList : List of profile ranges. Example: rangeList = ((4, 30), (32, 64), (128, 256))
835 867
836 868 """
837 869
838 870 if rangeList is not None:
839 871 if type(rangeList[0]) not in (tuple, list):
840 872 rangeList = [rangeList]
841 873
842 874 dataOut.flagNoData = True
843 875
844 876 if dataOut.flagDataAsBlock:
845 877 """
846 878 data dimension = [nChannels, nProfiles, nHeis]
847 879 """
848 880 if profileList != None:
849 881 dataOut.data = dataOut.data[:,profileList,:]
850 882
851 883 if profileRangeList != None:
852 884 minIndex = profileRangeList[0]
853 885 maxIndex = profileRangeList[1]
854 886 profileList = range(minIndex, maxIndex+1)
855 887
856 888 dataOut.data = dataOut.data[:,minIndex:maxIndex+1,:]
857 889
858 890 if rangeList != None:
859 891
860 892 profileList = []
861 893
862 894 for thisRange in rangeList:
863 895 minIndex = thisRange[0]
864 896 maxIndex = thisRange[1]
865 897
866 898 profileList.extend(range(minIndex, maxIndex+1))
867 899
868 900 dataOut.data = dataOut.data[:,profileList,:]
869 901
870 902 dataOut.nProfiles = len(profileList)
871 903 dataOut.profileIndex = dataOut.nProfiles - 1
872 904 dataOut.flagNoData = False
873 905
874 906 return True
875 907
876 908 """
877 909 data dimension = [nChannels, nHeis]
878 910 """
879 911
880 912 if profileList != None:
881 913
882 914 if self.isThisProfileInList(dataOut.profileIndex, profileList):
883 915
884 916 self.nProfiles = len(profileList)
885 917 dataOut.nProfiles = self.nProfiles
886 918 dataOut.profileIndex = self.profileIndex
887 919 dataOut.flagNoData = False
888 920
889 921 self.incProfileIndex()
890 922 return True
891 923
892 924 if profileRangeList != None:
893 925
894 926 minIndex = profileRangeList[0]
895 927 maxIndex = profileRangeList[1]
896 928
897 929 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
898 930
899 931 self.nProfiles = maxIndex - minIndex + 1
900 932 dataOut.nProfiles = self.nProfiles
901 933 dataOut.profileIndex = self.profileIndex
902 934 dataOut.flagNoData = False
903 935
904 936 self.incProfileIndex()
905 937 return True
906 938
907 939 if rangeList != None:
908 940
909 941 nProfiles = 0
910 942
911 943 for thisRange in rangeList:
912 944 minIndex = thisRange[0]
913 945 maxIndex = thisRange[1]
914 946
915 947 nProfiles += maxIndex - minIndex + 1
916 948
917 949 for thisRange in rangeList:
918 950
919 951 minIndex = thisRange[0]
920 952 maxIndex = thisRange[1]
921 953
922 954 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
923 955
924 956 self.nProfiles = nProfiles
925 957 dataOut.nProfiles = self.nProfiles
926 958 dataOut.profileIndex = self.profileIndex
927 959 dataOut.flagNoData = False
928 960
929 961 self.incProfileIndex()
930 962
931 963 break
932 964
933 965 return True
934 966
935 967
936 968 if beam != None: #beam is only for AMISR data
937 969 if self.isThisProfileInList(dataOut.profileIndex, dataOut.beamRangeDict[beam]):
938 970 dataOut.flagNoData = False
939 971 dataOut.profileIndex = self.profileIndex
940 972
941 973 self.incProfileIndex()
942 974
943 975 return True
944 976
945 977 raise ValueError, "ProfileSelector needs profileList, profileRangeList or rangeList parameter"
946 978
947 979 return False
948 980
949 981 class Reshaper(Operation):
950 982
951 983 def __init__(self, **kwargs):
952 984
953 985 Operation.__init__(self, **kwargs)
954 986
955 987 self.__buffer = None
956 988 self.__nitems = 0
957 989
958 990 def __appendProfile(self, dataOut, nTxs):
959 991
960 992 if self.__buffer is None:
961 993 shape = (dataOut.nChannels, int(dataOut.nHeights/nTxs) )
962 994 self.__buffer = numpy.empty(shape, dtype = dataOut.data.dtype)
963 995
964 996 ini = dataOut.nHeights * self.__nitems
965 997 end = ini + dataOut.nHeights
966 998
967 999 self.__buffer[:, ini:end] = dataOut.data
968 1000
969 1001 self.__nitems += 1
970 1002
971 1003 return int(self.__nitems*nTxs)
972 1004
973 1005 def __getBuffer(self):
974 1006
975 1007 if self.__nitems == int(1./self.__nTxs):
976 1008
977 1009 self.__nitems = 0
978 1010
979 1011 return self.__buffer.copy()
980 1012
981 1013 return None
982 1014
983 1015 def __checkInputs(self, dataOut, shape, nTxs):
984 1016
985 1017 if shape is None and nTxs is None:
986 1018 raise ValueError, "Reshaper: shape of factor should be defined"
987 1019
988 1020 if nTxs:
989 1021 if nTxs < 0:
990 1022 raise ValueError, "nTxs should be greater than 0"
991 1023
992 1024 if nTxs < 1 and dataOut.nProfiles % (1./nTxs) != 0:
993 1025 raise ValueError, "nProfiles= %d is not divisibled by (1./nTxs) = %f" %(dataOut.nProfiles, (1./nTxs))
994 1026
995 1027 shape = [dataOut.nChannels, dataOut.nProfiles*nTxs, dataOut.nHeights/nTxs]
996 1028
997 1029 return shape, nTxs
998 1030
999 1031 if len(shape) != 2 and len(shape) != 3:
1000 1032 raise ValueError, "shape dimension should be equal to 2 or 3. shape = (nProfiles, nHeis) or (nChannels, nProfiles, nHeis). Actually shape = (%d, %d, %d)" %(dataOut.nChannels, dataOut.nProfiles, dataOut.nHeights)
1001 1033
1002 1034 if len(shape) == 2:
1003 1035 shape_tuple = [dataOut.nChannels]
1004 1036 shape_tuple.extend(shape)
1005 1037 else:
1006 1038 shape_tuple = list(shape)
1007 1039
1008 1040 nTxs = 1.0*shape_tuple[1]/dataOut.nProfiles
1009 1041
1010 1042 return shape_tuple, nTxs
1011 1043
1012 1044 def run(self, dataOut, shape=None, nTxs=None):
1013 1045
1014 1046 shape_tuple, self.__nTxs = self.__checkInputs(dataOut, shape, nTxs)
1015 1047
1016 1048 dataOut.flagNoData = True
1017 1049 profileIndex = None
1018 1050
1019 1051 if dataOut.flagDataAsBlock:
1020 1052
1021 1053 dataOut.data = numpy.reshape(dataOut.data, shape_tuple)
1022 1054 dataOut.flagNoData = False
1023 1055
1024 1056 profileIndex = int(dataOut.nProfiles*self.__nTxs) - 1
1025 1057
1026 1058 else:
1027 1059
1028 1060 if self.__nTxs < 1:
1029 1061
1030 1062 self.__appendProfile(dataOut, self.__nTxs)
1031 1063 new_data = self.__getBuffer()
1032 1064
1033 1065 if new_data is not None:
1034 1066 dataOut.data = new_data
1035 1067 dataOut.flagNoData = False
1036 1068
1037 1069 profileIndex = dataOut.profileIndex*nTxs
1038 1070
1039 1071 else:
1040 1072 raise ValueError, "nTxs should be greater than 0 and lower than 1, or use VoltageReader(..., getblock=True)"
1041 1073
1042 1074 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1043 1075
1044 1076 dataOut.heightList = numpy.arange(dataOut.nHeights/self.__nTxs) * deltaHeight + dataOut.heightList[0]
1045 1077
1046 1078 dataOut.nProfiles = int(dataOut.nProfiles*self.__nTxs)
1047 1079
1048 1080 dataOut.profileIndex = profileIndex
1049 1081
1050 1082 dataOut.ippSeconds /= self.__nTxs
1051 1083
1052 1084 class SplitProfiles(Operation):
1053 1085
1054 1086 def __init__(self, **kwargs):
1055 1087
1056 1088 Operation.__init__(self, **kwargs)
1057 1089
1058 1090 def run(self, dataOut, n):
1059 1091
1060 1092 dataOut.flagNoData = True
1061 1093 profileIndex = None
1062 1094
1063 1095 if dataOut.flagDataAsBlock:
1064 1096
1065 1097 #nchannels, nprofiles, nsamples
1066 1098 shape = dataOut.data.shape
1067 1099
1068 1100 if shape[2] % n != 0:
1069 1101 raise ValueError, "Could not split the data, n=%d has to be multiple of %d" %(n, shape[2])
1070 1102
1071 1103 new_shape = shape[0], shape[1]*n, shape[2]/n
1072 1104
1073 1105 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1074 1106 dataOut.flagNoData = False
1075 1107
1076 1108 profileIndex = int(dataOut.nProfiles/n) - 1
1077 1109
1078 1110 else:
1079 1111
1080 1112 raise ValueError, "Could not split the data when is read Profile by Profile. Use VoltageReader(..., getblock=True)"
1081 1113
1082 1114 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1083 1115
1084 1116 dataOut.heightList = numpy.arange(dataOut.nHeights/n) * deltaHeight + dataOut.heightList[0]
1085 1117
1086 1118 dataOut.nProfiles = int(dataOut.nProfiles*n)
1087 1119
1088 1120 dataOut.profileIndex = profileIndex
1089 1121
1090 1122 dataOut.ippSeconds /= n
1091 1123
1092 1124 class CombineProfiles(Operation):
1093 1125 parameters = {
1094 'n': 'int',
1126 'n': global_type_integer,
1095 1127 }
1096 1128 def __init__(self, **kwargs):
1097 1129
1098 1130 Operation.__init__(self, **kwargs)
1099 1131
1100 1132 self.__remData = None
1101 1133 self.__profileIndex = 0
1102 1134
1103 1135 def run(self, dataOut, n):
1104 1136
1105 1137 dataOut.flagNoData = True
1106 1138 profileIndex = None
1107 1139
1108 1140 if dataOut.flagDataAsBlock:
1109 1141
1110 1142 #nchannels, nprofiles, nsamples
1111 1143 shape = dataOut.data.shape
1112 1144 new_shape = shape[0], shape[1]/n, shape[2]*n
1113 1145
1114 1146 if shape[1] % n != 0:
1115 1147 raise ValueError, "Could not split the data, n=%d has to be multiple of %d" %(n, shape[1])
1116 1148
1117 1149 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1118 1150 dataOut.flagNoData = False
1119 1151
1120 1152 profileIndex = int(dataOut.nProfiles*n) - 1
1121 1153
1122 1154 else:
1123 1155
1124 1156 #nchannels, nsamples
1125 1157 if self.__remData is None:
1126 1158 newData = dataOut.data
1127 1159 else:
1128 1160 newData = numpy.concatenate((self.__remData, dataOut.data), axis=1)
1129 1161
1130 1162 self.__profileIndex += 1
1131 1163
1132 1164 if self.__profileIndex < n:
1133 1165 self.__remData = newData
1134 1166 #continue
1135 1167 return
1136 1168
1137 1169 self.__profileIndex = 0
1138 1170 self.__remData = None
1139 1171
1140 1172 dataOut.data = newData
1141 1173 dataOut.flagNoData = False
1142 1174
1143 1175 profileIndex = dataOut.profileIndex/n
1144 1176
1145 1177
1146 1178 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1147 1179
1148 1180 dataOut.heightList = numpy.arange(dataOut.nHeights*n) * deltaHeight + dataOut.heightList[0]
1149 1181
1150 1182 dataOut.nProfiles = int(dataOut.nProfiles/n)
1151 1183
1152 1184 dataOut.profileIndex = profileIndex
1153 1185
1154 1186 dataOut.ippSeconds *= n
1155 1187
1156 1188 # import collections
1157 1189 # from scipy.stats import mode
1158 1190 #
1159 1191 # class Synchronize(Operation):
1160 1192 #
1161 1193 # isConfig = False
1162 1194 # __profIndex = 0
1163 1195 #
1164 1196 # def __init__(self, **kwargs):
1165 1197 #
1166 1198 # Operation.__init__(self, **kwargs)
1167 1199 # # self.isConfig = False
1168 1200 # self.__powBuffer = None
1169 1201 # self.__startIndex = 0
1170 1202 # self.__pulseFound = False
1171 1203 #
1172 1204 # def __findTxPulse(self, dataOut, channel=0, pulse_with = None):
1173 1205 #
1174 1206 # #Read data
1175 1207 #
1176 1208 # powerdB = dataOut.getPower(channel = channel)
1177 1209 # noisedB = dataOut.getNoise(channel = channel)[0]
1178 1210 #
1179 1211 # self.__powBuffer.extend(powerdB.flatten())
1180 1212 #
1181 1213 # dataArray = numpy.array(self.__powBuffer)
1182 1214 #
1183 1215 # filteredPower = numpy.correlate(dataArray, dataArray[0:self.__nSamples], "same")
1184 1216 #
1185 1217 # maxValue = numpy.nanmax(filteredPower)
1186 1218 #
1187 1219 # if maxValue < noisedB + 10:
1188 1220 # #No se encuentra ningun pulso de transmision
1189 1221 # return None
1190 1222 #
1191 1223 # maxValuesIndex = numpy.where(filteredPower > maxValue - 0.1*abs(maxValue))[0]
1192 1224 #
1193 1225 # if len(maxValuesIndex) < 2:
1194 1226 # #Solo se encontro un solo pulso de transmision de un baudio, esperando por el siguiente TX
1195 1227 # return None
1196 1228 #
1197 1229 # phasedMaxValuesIndex = maxValuesIndex - self.__nSamples
1198 1230 #
1199 1231 # #Seleccionar solo valores con un espaciamiento de nSamples
1200 1232 # pulseIndex = numpy.intersect1d(maxValuesIndex, phasedMaxValuesIndex)
1201 1233 #
1202 1234 # if len(pulseIndex) < 2:
1203 1235 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1204 1236 # return None
1205 1237 #
1206 1238 # spacing = pulseIndex[1:] - pulseIndex[:-1]
1207 1239 #
1208 1240 # #remover senales que se distancien menos de 10 unidades o muestras
1209 1241 # #(No deberian existir IPP menor a 10 unidades)
1210 1242 #
1211 1243 # realIndex = numpy.where(spacing > 10 )[0]
1212 1244 #
1213 1245 # if len(realIndex) < 2:
1214 1246 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1215 1247 # return None
1216 1248 #
1217 1249 # #Eliminar pulsos anchos (deja solo la diferencia entre IPPs)
1218 1250 # realPulseIndex = pulseIndex[realIndex]
1219 1251 #
1220 1252 # period = mode(realPulseIndex[1:] - realPulseIndex[:-1])[0][0]
1221 1253 #
1222 1254 # print "IPP = %d samples" %period
1223 1255 #
1224 1256 # self.__newNSamples = dataOut.nHeights #int(period)
1225 1257 # self.__startIndex = int(realPulseIndex[0])
1226 1258 #
1227 1259 # return 1
1228 1260 #
1229 1261 #
1230 1262 # def setup(self, nSamples, nChannels, buffer_size = 4):
1231 1263 #
1232 1264 # self.__powBuffer = collections.deque(numpy.zeros( buffer_size*nSamples,dtype=numpy.float),
1233 1265 # maxlen = buffer_size*nSamples)
1234 1266 #
1235 1267 # bufferList = []
1236 1268 #
1237 1269 # for i in range(nChannels):
1238 1270 # bufferByChannel = collections.deque(numpy.zeros( buffer_size*nSamples, dtype=numpy.complex) + numpy.NAN,
1239 1271 # maxlen = buffer_size*nSamples)
1240 1272 #
1241 1273 # bufferList.append(bufferByChannel)
1242 1274 #
1243 1275 # self.__nSamples = nSamples
1244 1276 # self.__nChannels = nChannels
1245 1277 # self.__bufferList = bufferList
1246 1278 #
1247 1279 # def run(self, dataOut, channel = 0):
1248 1280 #
1249 1281 # if not self.isConfig:
1250 1282 # nSamples = dataOut.nHeights
1251 1283 # nChannels = dataOut.nChannels
1252 1284 # self.setup(nSamples, nChannels)
1253 1285 # self.isConfig = True
1254 1286 #
1255 1287 # #Append new data to internal buffer
1256 1288 # for thisChannel in range(self.__nChannels):
1257 1289 # bufferByChannel = self.__bufferList[thisChannel]
1258 1290 # bufferByChannel.extend(dataOut.data[thisChannel])
1259 1291 #
1260 1292 # if self.__pulseFound:
1261 1293 # self.__startIndex -= self.__nSamples
1262 1294 #
1263 1295 # #Finding Tx Pulse
1264 1296 # if not self.__pulseFound:
1265 1297 # indexFound = self.__findTxPulse(dataOut, channel)
1266 1298 #
1267 1299 # if indexFound == None:
1268 1300 # dataOut.flagNoData = True
1269 1301 # return
1270 1302 #
1271 1303 # self.__arrayBuffer = numpy.zeros((self.__nChannels, self.__newNSamples), dtype = numpy.complex)
1272 1304 # self.__pulseFound = True
1273 1305 # self.__startIndex = indexFound
1274 1306 #
1275 1307 # #If pulse was found ...
1276 1308 # for thisChannel in range(self.__nChannels):
1277 1309 # bufferByChannel = self.__bufferList[thisChannel]
1278 1310 # #print self.__startIndex
1279 1311 # x = numpy.array(bufferByChannel)
1280 1312 # self.__arrayBuffer[thisChannel] = x[self.__startIndex:self.__startIndex+self.__newNSamples]
1281 1313 #
1282 1314 # deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1283 1315 # dataOut.heightList = numpy.arange(self.__newNSamples)*deltaHeight
1284 1316 # # dataOut.ippSeconds = (self.__newNSamples / deltaHeight)/1e6
1285 1317 #
1286 1318 # dataOut.data = self.__arrayBuffer
1287 1319 #
1288 1320 # self.__startIndex += self.__newNSamples
1289 1321 #
1290 1322 # return
@@ -1,94 +1,94
1 1 import argparse
2 2
3 3 from schainpy.controller import Project, multiSchain
4 4
5 5 desc = "HF_EXAMPLE"
6 6
7 7 def fiber(cursor, skip, q, dt):
8 8
9 9 controllerObj = Project()
10 10
11 11 controllerObj.setup(id='191', name='test01', description=desc)
12 12
13 13 readUnitConfObj = controllerObj.addReadUnit(datatype='SpectraReader',
14 path='/home/nanosat/data/julia',
15 startDate=dt,
16 endDate=dt,
17 startTime="00:00:00",
18 endTime="23:59:59",
19 online=0,
20 #set=1426485881,
21 delay=10,
22 walk=1,
23 queue=q,
24 cursor=cursor,
25 skip=skip,
26 #timezone=-5*3600
27 )
14 path='/home/nanosat/data/julia',
15 startDate=dt,
16 endDate=dt,
17 startTime="00:00:00",
18 endTime="23:59:59",
19 online=0,
20 #set=1426485881,
21 delay=10,
22 walk=1,
23 queue=q,
24 cursor=cursor,
25 skip=skip,
26 #timezone=-5*3600
27 )
28 28
29 29 # #opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock')
30 30 #
31 31 procUnitConfObj2 = controllerObj.addProcUnit(datatype='Spectra', inputId=readUnitConfObj.getId())
32 32 # procUnitConfObj2.addParameter(name='nipp', value='5', format='int')
33 33
34 34 # procUnitConfObj3 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=readUnitConfObj.getId())
35 35 # opObj11 = procUnitConfObj3.addOperation(name='SpectralMoments', optype='other')
36 36
37 37 #
38 38 opObj11 = procUnitConfObj2.addOperation(name='RTIPlot', optype='other')
39 39 opObj11.addParameter(name='id', value='1000', format='int')
40 40 opObj11.addParameter(name='wintitle', value='HF_Jicamarca_Spc', format='str')
41 41 opObj11.addParameter(name='xmin', value='0', format='int')
42 42 opObj11.addParameter(name='xmax', value='24', format='int')
43 43
44 44 # opObj11 = procUnitConfObj3.addOperation(name='Parameters1Plot', optype='other')
45 45 # opObj11.addParameter(name='channelList', value='0', format='intList')
46 46 #
47 47 # opObj11.addParameter(name='id', value='2000', format='int')
48 48 # # opObj11.addParameter(name='colormap', value='0', format='bool')
49 49 # opObj11.addParameter(name='onlySNR', value='1', format='bool')
50 50 # opObj11.addParameter(name='DOP', value='0', format='bool')
51 51 # opObj11.addParameter(name='showSNR', value='1', format='bool')
52 52 # opObj11.addParameter(name='SNRthresh', value='0', format='int')
53 53 # opObj11.addParameter(name='SNRmin', value='-10', format='int')
54 54 # opObj11.addParameter(name='SNRmax', value='30', format='int')
55 55
56 56 # opObj11.addParameter(name='showSNR', value='1', format='int')
57 57 # # opObj11.addParameter(name='channelList', value='0', format='intlist')
58 58 # # opObj11.addParameter(name='xmin', value='0', format='float')
59 59 # opObj11.addParameter(name='xmin', value='0', format='float')
60 60 # opObj11.addParameter(name='xmax', value='24', format='float')
61 61
62 62 # opObj11.addParameter(name='zmin', value='-110', format='float')
63 63 # opObj11.addParameter(name='zmax', value='-70', format='float')
64 64 # opObj11.addParameter(name='save', value='0', format='int')
65 65 # # opObj11.addParameter(name='figpath', value='/tmp/', format='str')
66 66 #
67 67 # opObj12 = procUnitConfObj2.addOperation(name='PublishData', optype='other')
68 68 # opObj12.addParameter(name='zeromq', value=1, format='int')
69 69 # opObj12.addParameter(name='server', value='tcp://10.10.10.82:7000', format='str')
70 70
71 71
72 72 # opObj13 = procUnitConfObj3.addOperation(name='PublishData', optype='other')
73 73 # opObj13.addParameter(name='zeromq', value=1, format='int')
74 74 # opObj13.addParameter(name='server', value="juanca", format='str')
75 75
76 76 # opObj12.addParameter(name='delay', value=1, format='int')
77 77
78 78
79 79 # print "Escribiendo el archivo XML"
80 80 # controllerObj.writeXml(filename)
81 81 # print "Leyendo el archivo XML"
82 82 # controllerObj.readXml(filename)
83 83
84 84
85 85 # timeit.timeit('controllerObj.run()', number=2)
86 86
87 87 controllerObj.start()
88 88
89 89
90 90 if __name__ == '__main__':
91 91 parser = argparse.ArgumentParser(description='Set number of parallel processes')
92 92 parser.add_argument('--nProcess', default=1, type=int)
93 93 args = parser.parse_args()
94 94 multiSchain(fiber, nProcess=args.nProcess, startDate='2016/08/19', endDate='2016/08/19')
This diff has been collapsed as it changes many lines, (1668 lines changed) Show them Hide them
@@ -1,1160 +1,1172
1 You should install "digital_rf_hdf5" module if you want to read USRP data
2 BeaconPhase
3 parameters = {
4 'id': 'string',
5 'wintitle': 'string',
6 'pairsList': 'pairsList',
7 'showprofile': 'boolean',
8 'xmin': 'float',
9 'xmax': 'float',
10 'ymin': 'float',
11 'ymax': 'float',
12 'hmin': 'float',
13 'hmax': 'float',
14 'timerange': 'float',
15 'save': 'boolean',
16 'figpath': 'string',
17 'figfile': 'string',
18 'show': 'boolean',
19 'ftp': 'boolean',
20 'wr_period': 'int',
21 'server': 'string',
22 'folder': 'string',
23 'username': 'string',
24 'password': 'string',
25 'ftp_wei': 'int',
26 'exp_code': 'int',
27 'sub_exp_code': 'int',
28 'plot_pos': 'int',
29 }
30
31
32 BeamSelector
33 parameters = {
34 'beam': 'string',
35 }
36
37
38 CohInt
39 parameters = {
40 'n': 'int',
41 'timeInterval': 'float',
42 'overlapping': 'boolean',
43 'byblock': 'boolean'
1
2 global_type_string = 'string'
3 global_type_integer = 'int'
4 global_type_floatList = 'floatList'
5 global_type_pairsList = 'pairsList'
6 global_type_boolean = 'bolean'
7 global_type_float = 'float'
8 global_type_colormap = 'colormap'
9 global_type_list = 'list'
10
11 #BeaconPhase
12 parameters = {
13 'id': global_type_string,
14 'wintitle': global_type_string,
15 'pairsList': global_type_pairsList,
16 'showprofile': global_type_boolean,
17 'xmin': global_type_float,
18 'xmax': global_type_float,
19 'ymin': global_type_float,
20 'ymax': global_type_float,
21 'hmin': global_type_float,
22 'hmax': global_type_float,
23 'timerange': global_type_float,
24 'save': global_type_boolean,
25 'figpath': global_type_string,
26 'figfile': global_type_string,
27 'show': global_type_boolean,
28 'ftp': global_type_boolean,
29 'wr_period': global_type_integer,
30 'server': global_type_string,
31 'folder': global_type_string,
32 'username': global_type_string,
33 'password': global_type_string,
34 'ftp_wei': global_type_integer,
35 'exp_code': global_type_integer,
36 'sub_exp_code': global_type_integer,
37 'plot_pos': global_type_integer,
38 }
39
40
41 #BeamSelector
42 parameters = {
43 'beam': global_type_string,
44 }
45
46
47 #CohInt
48 parameters = {
49 'n': global_type_integer,
50 'timeInterval': global_type_float,
51 'overlapping': global_type_boolean,
52 'byblock': global_type_boolean
53 }
54
55
56 #CoherenceMap
57 parameters = {
58 'id': global_type_string,
59 'wintitle': global_type_string,
60 'pairsList': global_type_pairsList,
61 'showprofile': global_type_boolean,
62 'xmin': global_type_float,
63 'xmax': global_type_float,
64 'ymin': global_type_float,
65 'ymax': global_type_float,
66 'zmin': global_type_float,
67 'zmax': global_type_float,
68 'timerange': global_type_float,
69 'phase_min': global_type_float,
70 'phase_max': global_type_float,
71 'save': global_type_boolean,
72 'figpath': global_type_string,
73 'figfile': global_type_string,
74 'ftp': global_type_boolean,
75 'wr_period': global_type_integer,
76 'coherence_cmap': global_type_colormap,
77 'phase_cmap': global_type_colormap,
78 'show': global_type_boolean,
79 'server': global_type_string,
80 'folder': global_type_string,
81 'username': global_type_string,
82 'password': global_type_string,
83 'ftp_wei': global_type_integer,
84 'exp_code': global_type_integer,
85 'sub_exp_code': global_type_integer,
86 'plot_pos': global_type_integer,
87 }
88
89
90 #CombineProfiles
91 parameters = {
92 'n': global_type_integer,
44 93 }
45 94
46 95
47 CoherenceMap
96 #CorrectSMPhases
48 97 parameters = {
49 'id': 'string',
50 'wintitle': 'string',
51 'pairsList': 'pairsLists',
52 'showprofile': 'boolean',
53 'xmin': 'float',
54 'xmax': 'float',
55 'ymin': 'float',
56 'ymax': 'float',
57 'zmin': 'float',
58 'zmax': 'float',
59 'timerange': 'float',
60 'phase_min': 'float',
61 'phase_max': 'float',
62 'save': 'boolean',
63 'figpath': 'string',
64 'figfile': 'string',
65 'ftp': 'boolean',
66 'wr_period': 'int',
67 'coherence_cmap': 'colormap',
68 'phase_cmap': 'colormap',
69 'show': 'boolean',
70 'server': 'string',
71 'folder': 'string',
72 'username': 'string',
73 'password': 'string',
74 'ftp_wei': 'int',
75 'exp_code': 'int',
76 'sub_exp_code': 'int',
77 'plot_pos': 'int',
78 }
79
80
81 CombineProfiles
82 parameters = {
83 'n': 'int',
84 }
85
86
87 CorrectSMPhases
88 parameters = {
89 'phaseOffsets': 'pairsLists',
90 'hmin': 'float',
91 'hmax': 'float',
92 'azimuth': 'string',
93 'channelPositions': 'string',
94 }
95
96
97 CorrelationPlot
98 parameters = {
99 'id': 'string',
100 'wintitle': 'string',
101 'channelList': 'string',
102 'showprofile': 'string',
103 'xmin': 'float',
104 'xmax': 'float',
105 'ymin': 'float',
106 'ymax': 'float',
107 'zmin': 'float',
108 'zmax': 'float',
109 'save': 'boolean',
110 'figpath': 'string',
111 'figfile': 'string',
112 'show': 'boolean',
113 'ftp': 'boolean',
114 'wr_period': 'int',
115 'server': 'string',
116 'folder': 'string',
117 'username': 'string',
118 'password': 'string',
119 'ftp_wei': 'string',
120 'exp_code': 'int',
121 'sub_exp_code': 'int',
122 'plot_pos': 'int',
123 'realtime': 'string',
124 }
125
126
127 CrossSpectraPlot
128 parameters = {
129 'id': 'string',
130 'wintitle': 'string',
131 'pairsList': 'pairsLists',
132 'xmin': 'float',
133 'xmax': 'float',
134 'ymin': 'float',
135 'ymax': 'float',
136 'zmin': 'float',
137 'zmax': 'float',
138 'coh_min': 'string',
139 'coh_max': 'string',
140 'phase_min': 'string',
141 'phase_max': 'string',
142 'save': 'boolean',
143 'figpath': 'string',
144 'figfile': 'string',
145 'ftp': 'boolean',
146 'wr_period': 'int',
147 'power_cmap': 'string',
148 'coherence_cmap': 'string',
149 'phase_cmap': 'string',
150 'show': 'string',
151 'server': 'string',
152 'folder': 'string',
153 'username': 'string',
154 'password': 'string',
155 'ftp_wei': 'string',
156 'exp_code': 'int',
157 'sub_exp_code': 'int',
158 'plot_pos': 'int',
159 'xaxis': 'string',
160 }
161
162
163 Decoder
164 parameters = {
165 'code': 'string',
166 'nCode': 'string',
167 'nBaud': 'string',
168 'mode': 'string',
169 'osamp': 'string',
170 'times': 'string',
171 }
172
173
174 EWDriftsEstimation
175 parameters = {
176 'zenith': 'string',
177 'zenithCorrection': 'string',
178 }
179
180
181 EWDriftsPlot
182 parameters = {
183 'id': 'string',
184 'wintitle': 'string',
185 'channelList': 'string',
186 'xmin': 'float',
187 'xmax': 'float',
188 'ymin': 'float',
189 'ymax': 'float',
190 'zmin': 'float',
191 'zmax': 'float',
192 'zmaxVertfloat 'string',
193 'zminVertfloat 'string',
194 'zmaxZonafloattring',
195 'zminZonafloattring',
196 'timerange': 'string',
197 'SNRthresh': 'string',
198 'SNRmin': 'string',
199 'SNRmax': 'string',
200 'SNR_1': 'string',
201 'save': 'boolean',
202 'figpath': 'string',
203 'lastone': 'string',
204 'figfile': 'string',
205 'ftp': 'string',
206 'wr_period': 'int',
207 'show': 'string',
208 'server': 'string',
209 'folder': 'string',
210 'username': 'string',
211 'password': 'string',
212 'ftp_wei': 'string',
213 'exp_code': 'int',
214 'sub_exp_code': 'int',
215 'plot_pos': 'int',
98 'phaseOffsets': global_type_pairsList,
99 'hmin': global_type_float,
100 'hmax': global_type_float,
101 'azimuth': global_type_float,
102 'channelPositions': global_type_pairsList,
103 }
104
105
106 #CorrelationPlot
107 parameters = {
108 'id': global_type_string,
109 'wintitle': global_type_string,
110 'channelList': global_type_list,
111 'showprofile': global_type_boolean,
112 'xmin': global_type_float,
113 'xmax': global_type_float,
114 'ymin': global_type_float,
115 'ymax': global_type_float,
116 'zmin': global_type_float,
117 'zmax': global_type_float,
118 'save': global_type_boolean,
119 'figpath': global_type_string,
120 'figfile': global_type_string,
121 'show': global_type_boolean,
122 'ftp': global_type_boolean,
123 'wr_period': global_type_integer,
124 'server': global_type_string,
125 'folder': global_type_string,
126 'username': global_type_string,
127 'password': global_type_string,
128 'ftp_wei': global_type_integer,
129 'exp_code': global_type_integer,
130 'sub_exp_code': global_type_integer,
131 'plot_pos': global_type_integer,
132 'realtime': global_type_boolean,
133 }
134
135
136 #CrossSpectraPlot
137 parameters = {
138 'id': global_type_string,
139 'wintitle': global_type_string,
140 'pairsList': global_type_pairsList,
141 'xmin': global_type_float,
142 'xmax': global_type_float,
143 'ymin': global_type_float,
144 'ymax': global_type_float,
145 'zmin': global_type_float,
146 'zmax': global_type_float,
147 'coh_min': global_type_float,
148 'coh_max': global_type_float,
149 'phase_min': global_type_float,
150 'phase_max': global_type_float,
151 'save': global_type_boolean,
152 'figpath': global_type_string,
153 'figfile': global_type_string,
154 'ftp': global_type_boolean,
155 'wr_period': global_type_integer,
156 'power_cmap': global_type_colormap,
157 'coherence_cmap': global_type_colormap,
158 'phase_cmap': global_type_colormap,
159 'show': global_type_boolean,
160 'server': global_type_string,
161 'folder': global_type_string,
162 'username': global_type_string,
163 'password': global_type_string,
164 'ftp_wei': global_type_integer,
165 'exp_code': global_type_integer,
166 'sub_exp_code': global_type_integer,
167 'plot_pos': global_type_integer,
168 'xaxis': global_type_string,
169 }
170
171
172 #Decoder
173 parameters = {
174 'code': global_type_list,
175 'nCode': global_type_integer,
176 'nBaud': global_type_integer,
177 'mode': global_type_integer,
178 'osamp': global_type_float,
179 }
180
181
182 #EWDriftsEstimation
183 parameters = {
184 'zenith': global_type_list,
185 'zenithCorrection': global_type_float,
186 }
187
188
189 #EWDriftsPlot
190 parameters = {
191 'id': global_type_string,
192 'wintitle': global_type_string,
193 'channelList': global_type_list,
194 'xmin': global_type_float,
195 'xmax': global_type_float,
196 'ymin': global_type_float,
197 'ymax': global_type_float,
198 'zmin': global_type_float,
199 'zmax': global_type_float,
200 'zmaxVertfloat': global_type_float,
201 'zminVertfloat': global_type_float,
202 'zmaxZonafloat': global_type_float,
203 'zminZonafloat': global_type_float,
204 'timerange': global_type_float,
205 'SNRthresh': global_type_float,
206 'SNRmin': global_type_float,
207 'SNRmax': global_type_float,
208 'SNR_1': global_type_boolean,
209 'save': global_type_boolean,
210 'figpath': global_type_string,
211 'lastone': global_type_float,
212 'figfile': global_type_string,
213 'ftp': global_type_string,
214 'wr_period': global_type_integer,
215 'show': global_type_string,
216 'server': global_type_string,
217 'folder': global_type_string,
218 'username': global_type_string,
219 'password': global_type_string,
220 'ftp_wei': global_type_integer,
221 'exp_code': global_type_integer,
222 'sub_exp_code': global_type_integer,
223 'plot_pos': global_type_integer,
216 224 }
217 225
218 226
219 227 Figure
228 # parameters = {
229 # : global_type_string,
230 # }
231
232
233 #FitsWriter
220 234 parameters = {
221 : 'string',
222 }
223
224
225 FitsWriter
226 parameters = {
227 : 'string',
228 }
229
230
231 IncohInt
232 parameters = {
233 'n': 'string',
234 'timeInterval': 'string',
235 'overlapping': 'string',
236 }
237
238
239 IncohInt4SpectraHeis
240 parameters = {
241 : 'string',
242 }
243
244
245 MomentsPlot
246 parameters = {
247 'id': 'string',
248 'wintitle': 'string',
249 'channelList': 'string',
250 'showprofile': 'string',
251 'xmin': 'float',
252 'xmax': 'float',
253 'ymin': 'float',
254 'ymax': 'float',
255 'zmin': 'float',
256 'zmax': 'float',
257 'save': 'boolean',
258 'figpath': 'string',
259 'figfile': 'string',
260 'show': 'string',
261 'ftp': 'string',
262 'wr_period': 'int',
263 'server': 'string',
264 'folder': 'string',
265 'username': 'string',
266 'password': 'string',
267 'ftp_wei': 'string',
268 'exp_code': 'int',
269 'sub_exp_code': 'int',
270 'plot_pos': 'int',
271 'realtime': 'string',
272 }
273
274
275 NSMeteorDetection1Plot
276 parameters = {
277 'id': 'string',
278 'wintitle': 'string',
279 'channelList': 'string',
280 'showprofile': 'string',
281 'xmin': 'float',
282 'xmax': 'float',
283 'ymin': 'float',
284 'ymax': 'float',
285 'SNRmin': 'string',
286 'SNRmax': 'string',
287 'vmin': 'string',
288 'vmax': 'string',
289 'wmin': 'string',
290 'wmax': 'string',
291 'mode': 'string',
292 'save': 'boolean',
293 'figpath': 'string',
294 'figfile': 'string',
295 'show': 'string',
296 'ftp': 'string',
297 'wr_period': 'int',
298 'server': 'string',
299 'folder': 'string',
300 'username': 'string',
301 'password': 'string',
302 'ftp_wei': 'string',
303 'exp_code': 'int',
304 'sub_exp_code': 'int',
305 'plot_pos': 'int',
306 'realtime': 'string',
307 'xaxis': 'string',
308 }
309
310
311 NSMeteorDetection2Plot
312 parameters = {
313 'id': 'string',
314 'wintitle': 'string',
315 'channelList': 'string',
316 'showprofile': 'string',
317 'xmin': 'float',
318 'xmax': 'float',
319 'ymin': 'float',
320 'ymax': 'float',
321 'SNRmin': 'string',
322 'SNRmax': 'string',
323 'vmin': 'string',
324 'vmax': 'string',
325 'wmin': 'string',
326 'wmax': 'string',
327 'mode': 'string',
328 'save': 'boolean',
329 'figpath': 'string',
330 'figfile': 'string',
331 'show': 'string',
332 'ftp': 'string',
333 'wr_period': 'int',
334 'server': 'string',
335 'folder': 'string',
336 'username': 'string',
337 'password': 'string',
338 'ftp_wei': 'string',
339 'exp_code': 'int',
340 'sub_exp_code': 'int',
341 'plot_pos': 'int',
342 'realtime': 'string',
343 'xaxis': 'string',
344 }
345
346
347 Noise
348 parameters = {
349 'id': 'string',
350 'wintitle': 'string',
351 'channelList': 'string',
352 'showprofile': 'string',
353 'xmin': 'float',
354 'xmax': 'float',
355 'ymin': 'float',
356 'ymax': 'float',
357 'timerange': 'string',
358 'save': 'boolean',
359 'figpath': 'string',
360 'figfile': 'string',
361 'show': 'string',
362 'ftp': 'string',
363 'wr_period': 'int',
364 'server': 'string',
365 'folder': 'string',
366 'username': 'string',
367 'password': 'string',
368 'ftp_wei': 'string',
369 'exp_code': 'int',
370 'sub_exp_code': 'int',
371 'plot_pos': 'int',
372 }
373
374
375 NonSpecularMeteorDetection
376 parameters = {
377 'mode': 'string',
378 'SNRthresh': 'string',
379 'phaseDerThresh': 'string',
380 'cohThresh': 'string',
381 'allData': 'string',
235 'path': global_type_string,
236 'dataBlocksPerFile': global_type_integer,
237 'metadatafile': global_type_string,
238 }
239
240
241 #IncohInt
242 parameters = {
243 'n': global_type_float,
244 'timeInterval': global_type_integer,
245 'overlapping': global_type_boolean,
246 }
247
248
249 #IncohInt4SpectraHeis
250 parameters = {
251 'n': global_type_float,
252 'timeInterval': global_type_integer,
253 'overlapping': global_type_boolean,
254 }
255
256
257 #MomentsPlot
258 parameters = {
259 'id': global_type_string,
260 'wintitle': global_type_string,
261 'channelList': global_type_list,
262 'showprofile': global_type_boolean,
263 'xmin': global_type_float,
264 'xmax': global_type_float,
265 'ymin': global_type_float,
266 'ymax': global_type_float,
267 'zmin': global_type_float,
268 'zmax': global_type_float,
269 'save': global_type_boolean,
270 'figpath': global_type_string,
271 'figfile': global_type_string,
272 'show': global_type_boolean,
273 'ftp': global_type_boolean,
274 'wr_period': global_type_integer,
275 'server': global_type_string,
276 'folder': global_type_string,
277 'username': global_type_string,
278 'password': global_type_string,
279 'ftp_wei': global_type_string,
280 'exp_code': global_type_integer,
281 'sub_exp_code': global_type_integer,
282 'plot_pos': global_type_integer,
283 'realtime': global_type_boolean,
284 }
285
286
287 #NSMeteorDetection1Plot
288 parameters = {
289 'id': global_type_string,
290 'wintitle': global_type_string,
291 'channelList': global_type_list,
292 'showprofile': global_type_boolean,
293 'xmin': global_type_float,
294 'xmax': global_type_float,
295 'ymin': global_type_float,
296 'ymax': global_type_float,
297 'SNRmin': global_type_float,
298 'SNRmax': global_type_float,
299 'vmin': global_type_float,
300 'vmax': global_type_float,
301 'wmin': global_type_float,
302 'wmax': global_type_float,
303 'mode': global_type_string,
304 'save': global_type_boolean,
305 'figpath': global_type_string,
306 'figfile': global_type_string,
307 'show': global_type_boolean,
308 'ftp': global_type_string,
309 'wr_period': global_type_integer,
310 'server': global_type_string,
311 'folder': global_type_string,
312 'username': global_type_string,
313 'password': global_type_string,
314 'ftp_wei': global_type_integer,
315 'exp_code': global_type_integer,
316 'sub_exp_code': global_type_integer,
317 'plot_pos': global_type_integer,
318 'realtime': global_type_boolean,
319 'xaxis': global_type_string,
320 }
321
322
323 #NSMeteorDetection2Plot
324 parameters = {
325 'id': global_type_string,
326 'wintitle': global_type_string,
327 'channelList': global_type_list,
328 'showprofile': global_type_boolean,
329 'xmin': global_type_float,
330 'xmax': global_type_float,
331 'ymin': global_type_float,
332 'ymax': global_type_float,
333 'SNRmin': global_type_float,
334 'SNRmax': global_type_float,
335 'vmin': global_type_float,
336 'vmax': global_type_float,
337 'wmin': global_type_float,
338 'wmax': global_type_float,
339 'mode': global_type_string,
340 'save': global_type_boolean,
341 'figpath': global_type_string,
342 'figfile': global_type_string,
343 'show': global_type_string,
344 'ftp': global_type_boolean,
345 'wr_period': global_type_integer,
346 'server': global_type_string,
347 'folder': global_type_string,
348 'username': global_type_string,
349 'password': global_type_string,
350 'ftp_wei': global_type_integer,
351 'exp_code': global_type_integer,
352 'sub_exp_code': global_type_integer,
353 'plot_pos': global_type_integer,
354 'realtime': global_type_boolean,
355 'xaxis': global_type_string,
356 }
357
358
359 #Noise
360 parameters = {
361 'id': global_type_string,
362 'wintitle': global_type_string,
363 'channelList': global_type_list,
364 'showprofile': global_type_boolean,
365 'xmin': global_type_float,
366 'xmax': global_type_float,
367 'ymin': global_type_float,
368 'ymax': global_type_float,
369 'timerange': global_type_float,
370 'save': global_type_boolean,
371 'figpath': global_type_string,
372 'figfile': global_type_string,
373 'show': global_type_boolean,
374 'ftp': global_type_boolean,
375 'wr_period': global_type_integer,
376 'server': global_type_string,
377 'folder': global_type_string,
378 'username': global_type_string,
379 'password': global_type_string,
380 'ftp_wei': global_type_integer,
381 'exp_code': global_type_integer,
382 'sub_exp_code': global_type_integer,
383 'plot_pos': global_type_integer,
384 }
385
386
387 #NonSpecularMeteorDetection
388 parameters = {
389 'mode': global_type_string,
390 'SNRthresh': global_type_float,
391 'phaseDerThresh': global_type_float,
392 'cohThresh': global_type_float,
393 'allData': global_type_boolean,
382 394 }
383 395
384 396
385 397 Operation
386 398 parameters = {
387 'dataIn': 'string',
399 'dataIn': global_type_string,
388 400 }
389 401
390 402
391 403 ParamWriter
392 404 parameters = {
393 : 'string',
405 : global_type_string,
394 406 }
395 407
396 408
397 409 Parameters1Plot
398 410 parameters = {
399 'id': 'string',
400 'wintitle': 'string',
401 'channelList': 'string',
402 'showprofile': 'string',
403 'xmin': 'float',
404 'xmax': 'float',
405 'ymin': 'float',
406 'ymax': 'float',
407 'zmin': 'float',
408 'zmax': 'float',
409 'timerange': 'string',
410 'parameterIndex': 'string',
411 'onlyPositive': 'string',
412 'SNRthresh': 'string',
413 'SNR': 'string',
414 'SNRmin': 'string',
415 'SNRmax': 'string',
416 'onlySNR': 'string',
417 'DOP': 'string',
418 'zlabel': 'string',
419 'parameterName': 'string',
420 'parameterObject': 'string',
421 'save': 'boolean',
422 'figpath': 'string',
423 'lastone': 'string',
424 'figfile': 'string',
425 'ftp': 'string',
426 'wr_period': 'int',
427 'show': 'string',
428 'server': 'string',
429 'folder': 'string',
430 'username': 'string',
431 'password': 'string',
432 'ftp_wei': 'string',
433 'exp_code': 'int',
434 'sub_exp_code': 'int',
435 'plot_pos': 'int',
411 'id': global_type_string,
412 'wintitle': global_type_string,
413 'channelList': global_type_list,
414 'showprofile': global_type_boolean,
415 'xmin': global_type_float,
416 'xmax': global_type_float,
417 'ymin': global_type_float,
418 'ymax': global_type_float,
419 'zmin': global_type_float,
420 'zmax': global_type_float,
421 'timerange': global_type_float,
422 'parameterIndex': global_type_string,
423 'onlyPositive': global_type_string,
424 'SNRthresh': global_type_string,
425 'SNR': global_type_string,
426 'SNRmin': global_type_float,
427 'SNRmax': global_type_float,
428 'onlySNR': global_type_string,
429 'DOP': global_type_string,
430 'zlabel': global_type_string,
431 'parameterName': global_type_string,
432 'parameterObject': global_type_string,
433 'save': global_type_boolean,
434 'figpath': global_type_string,
435 'lastone': global_type_string,
436 'figfile': global_type_string,
437 'ftp': global_type_string,
438 'wr_period': global_type_integer,
439 'show': global_type_string,
440 'server': global_type_string,
441 'folder': global_type_string,
442 'username': global_type_string,
443 'password': global_type_string,
444 'ftp_wei': global_type_integer,
445 'exp_code': global_type_integer,
446 'sub_exp_code': global_type_integer,
447 'plot_pos': global_type_integer,
436 448 }
437 449
438 450
439 451 ParametersPlot
440 452 parameters = {
441 'id': 'string',
442 'wintitle': 'string',
443 'channelList': 'string',
444 'paramIndex': 'string',
445 'colormap': 'string',
446 'xmin': 'float',
447 'xmax': 'float',
448 'ymin': 'float',
449 'ymax': 'float',
450 'zmin': 'float',
451 'zmax': 'float',
452 'timerange': 'string',
453 'showSNR': 'string',
454 'SNRthresh': 'string',
455 'SNRmin': 'string',
456 'SNRmax': 'string',
457 'save': 'boolean',
458 'figpath': 'string',
459 'lastone': 'string',
460 'figfile': 'string',
461 'ftp': 'string',
462 'wr_period': 'int',
463 'show': 'string',
464 'server': 'string',
465 'folder': 'string',
466 'username': 'string',
467 'password': 'string',
468 'ftp_wei': 'string',
469 'exp_code': 'int',
470 'sub_exp_code': 'int',
471 'plot_pos': 'int',
453 'id': global_type_string,
454 'wintitle': global_type_string,
455 'channelList': global_type_list,
456 'paramIndex': global_type_string,
457 'colormap': global_type_string,
458 'xmin': global_type_float,
459 'xmax': global_type_float,
460 'ymin': global_type_float,
461 'ymax': global_type_float,
462 'zmin': global_type_float,
463 'zmax': global_type_float,
464 'timerange': global_type_float,
465 'showSNR': global_type_string,
466 'SNRthresh': global_type_string,
467 'SNRmin': global_type_float,
468 'SNRmax': global_type_float,
469 'save': global_type_boolean,
470 'figpath': global_type_string,
471 'lastone': global_type_string,
472 'figfile': global_type_string,
473 'ftp': global_type_string,
474 'wr_period': global_type_integer,
475 'show': global_type_string,
476 'server': global_type_string,
477 'folder': global_type_string,
478 'username': global_type_string,
479 'password': global_type_string,
480 'ftp_wei': global_type_integer,
481 'exp_code': global_type_integer,
482 'sub_exp_code': global_type_integer,
483 'plot_pos': global_type_integer,
472 484 }
473 485
474 486
475 487 PhasePlot
476 488 parameters = {
477 'id': 'string',
478 'wintitle': 'string',
489 'id': global_type_string,
490 'wintitle': global_type_string,
479 491 'pairsList': 'pairsLists',
480 'showprofile': 'string',
481 'xmin': 'float',
482 'xmax': 'float',
483 'ymin': 'float',
484 'ymax': 'float',
485 'timerange': 'string',
486 'save': 'boolean',
487 'figpath': 'string',
488 'figfile': 'string',
489 'show': 'string',
490 'ftp': 'string',
491 'wr_period': 'int',
492 'server': 'string',
493 'folder': 'string',
494 'username': 'string',
495 'password': 'string',
496 'ftp_wei': 'string',
497 'exp_code': 'int',
498 'sub_exp_code': 'int',
499 'plot_pos': 'int',
492 'showprofile': global_type_boolean,
493 'xmin': global_type_float,
494 'xmax': global_type_float,
495 'ymin': global_type_float,
496 'ymax': global_type_float,
497 'timerange': global_type_float,
498 'save': global_type_boolean,
499 'figpath': global_type_string,
500 'figfile': global_type_string,
501 'show': global_type_string,
502 'ftp': global_type_string,
503 'wr_period': global_type_integer,
504 'server': global_type_string,
505 'folder': global_type_string,
506 'username': global_type_string,
507 'password': global_type_string,
508 'ftp_wei': global_type_integer,
509 'exp_code': global_type_integer,
510 'sub_exp_code': global_type_integer,
511 'plot_pos': global_type_integer,
500 512 }
501 513
502 514
503 515 PlotCOHData
504 516 parameters = {
505 : 'string',
517 : global_type_string,
506 518 }
507 519
508 520
509 521 PlotCrossSpectraData
510 522 parameters = {
511 : 'string',
523 : global_type_string,
512 524 }
513 525
514 526
515 527 PlotDOPData
516 528 parameters = {
517 : 'string',
529 : global_type_string,
518 530 }
519 531
520 532
521 533 PlotData
522 534 parameters = {
523 : 'string',
535 : global_type_string,
524 536 }
525 537
526 538
527 539 PlotNoiseData
528 540 parameters = {
529 : 'string',
541 : global_type_string,
530 542 }
531 543
532 544
533 545 PlotPHASEData
534 546 parameters = {
535 : 'string',
547 : global_type_string,
536 548 }
537 549
538 550
539 551 PlotRTIData
540 552 parameters = {
541 : 'string',
553 : global_type_string,
542 554 }
543 555
544 556
545 557 PlotSNRData
546 558 parameters = {
547 : 'string',
559 : global_type_string,
548 560 }
549 561
550 562
551 563 PlotSpectraData
552 564 parameters = {
553 : 'string',
565 : global_type_string,
554 566 }
555 567
556 568
557 569 PlotSpectraMeanData
558 570 parameters = {
559 : 'string',
571 : global_type_string,
560 572 }
561 573
562 574
563 575 PlotWindProfilerData
564 576 parameters = {
565 : 'string',
577 : global_type_string,
566 578 }
567 579
568 580
569 581 PowerProfilePlot
570 582 parameters = {
571 'id': 'string',
572 'wintitle': 'string',
573 'channelList': 'string',
574 'xmin': 'float',
575 'xmax': 'float',
576 'ymin': 'float',
577 'ymax': 'float',
578 'save': 'boolean',
579 'figpath': 'string',
580 'figfile': 'string',
581 'show': 'string',
582 'ftp': 'string',
583 'wr_period': 'int',
584 'server': 'string',
585 'folder': 'string',
586 'username': 'string',
587 'password': 'string',
583 'id': global_type_string,
584 'wintitle': global_type_string,
585 'channelList': global_type_list,
586 'xmin': global_type_float,
587 'xmax': global_type_float,
588 'ymin': global_type_float,
589 'ymax': global_type_float,
590 'save': global_type_boolean,
591 'figpath': global_type_string,
592 'figfile': global_type_string,
593 'show': global_type_string,
594 'ftp': global_type_string,
595 'wr_period': global_type_integer,
596 'server': global_type_string,
597 'folder': global_type_string,
598 'username': global_type_string,
599 'password': global_type_string,
588 600 }
589 601
590 602
591 603 PrintInfo
592 604 parameters = {
593 : 'string',
605 : global_type_string,
594 606 }
595 607
596 608
597 609 ProfileConcat
598 610 parameters = {
599 'm': 'string',
611 'm': global_type_string,
600 612 }
601 613
602 614
603 615 ProfileSelector
604 616 parameters = {
605 'profileList': 'string',
606 'profileRangeList': 'string',
607 'beam': 'string',
608 'byblock': 'string',
609 'rangeList': 'string',
610 'nProfiles': 'string',
617 'profileList': global_type_string,
618 'profileRangeList': global_type_string,
619 'beam': global_type_string,
620 'byblock': global_type_string,
621 'rangeList': global_type_string,
622 'nProfiles': global_type_string,
611 623 }
612 624
613 625
614 626 ProfileToChannels
615 627 parameters = {
616 : 'string',
628 : global_type_string,
617 629 }
618 630
619 631
620 632 PublishData
621 633 parameters = {
622 : 'string',
634 : global_type_string,
623 635 }
624 636
625 637
626 638 RTIPlot
627 639 parameters = {
628 'id': 'string',
629 'wintitle': 'string',
630 'channelList': 'string',
631 'showprofile': 'string',
632 'xmin': 'float',
633 'xmax': 'float',
634 'ymin': 'float',
635 'ymax': 'float',
636 'zmin': 'float',
637 'zmax': 'float',
638 'timerange': 'string',
639 'save': 'boolean',
640 'figpath': 'string',
641 'lastone': 'string',
642 'figfile': 'string',
643 'ftp': 'string',
644 'wr_period': 'int',
645 'show': 'string',
646 'server': 'string',
647 'folder': 'string',
648 'username': 'string',
649 'password': 'string',
650 'ftp_wei': 'string',
651 'exp_code': 'int',
652 'sub_exp_code': 'int',
653 'plot_pos': 'int',
640 'id': global_type_string,
641 'wintitle': global_type_string,
642 'channelList': global_type_list,
643 'showprofile': global_type_boolean,
644 'xmin': global_type_float,
645 'xmax': global_type_float,
646 'ymin': global_type_float,
647 'ymax': global_type_float,
648 'zmin': global_type_float,
649 'zmax': global_type_float,
650 'timerange': global_type_float,
651 'save': global_type_boolean,
652 'figpath': global_type_string,
653 'lastone': global_type_string,
654 'figfile': global_type_string,
655 'ftp': global_type_string,
656 'wr_period': global_type_integer,
657 'show': global_type_string,
658 'server': global_type_string,
659 'folder': global_type_string,
660 'username': global_type_string,
661 'password': global_type_string,
662 'ftp_wei': global_type_integer,
663 'exp_code': global_type_integer,
664 'sub_exp_code': global_type_integer,
665 'plot_pos': global_type_integer,
654 666 }
655 667
656 668
657 669 RTIfromSpectraHeis
658 670 parameters = {
659 'id': 'string',
660 'wintitle': 'string',
661 'channelList': 'string',
662 'showprofile': 'string',
663 'xmin': 'float',
664 'xmax': 'float',
665 'ymin': 'float',
666 'ymax': 'float',
667 'timerange': 'string',
668 'save': 'boolean',
669 'figpath': 'string',
670 'figfile': 'string',
671 'ftp': 'string',
672 'wr_period': 'int',
673 'show': 'string',
674 'server': 'string',
675 'folder': 'string',
676 'username': 'string',
677 'password': 'string',
678 'ftp_wei': 'string',
679 'exp_code': 'int',
680 'sub_exp_code': 'int',
681 'plot_pos': 'int',
671 'id': global_type_string,
672 'wintitle': global_type_string,
673 'channelList': global_type_list,
674 'showprofile': global_type_boolean,
675 'xmin': global_type_float,
676 'xmax': global_type_float,
677 'ymin': global_type_float,
678 'ymax': global_type_float,
679 'timerange': global_type_float,
680 'save': global_type_boolean,
681 'figpath': global_type_string,
682 'figfile': global_type_string,
683 'ftp': global_type_string,
684 'wr_period': global_type_integer,
685 'show': global_type_string,
686 'server': global_type_string,
687 'folder': global_type_string,
688 'username': global_type_string,
689 'password': global_type_string,
690 'ftp_wei': global_type_integer,
691 'exp_code': global_type_integer,
692 'sub_exp_code': global_type_integer,
693 'plot_pos': global_type_integer,
682 694 }
683 695
684 696
685 697 Reshaper
686 698 parameters = {
687 'shape': 'string',
688 'nTxs': 'string',
699 'shape': global_type_string,
700 'nTxs': global_type_string,
689 701 }
690 702
691 703
692 704 SALags
693 705 parameters = {
694 : 'string',
706 : global_type_string,
695 707 }
696 708
697 709
698 710 SMDetection
699 711 parameters = {
700 'hei_ref': 'string',
701 'tauindex': 'string',
702 'phaseOffsets': 'string',
703 'cohDetection': 'string',
704 'cohDet_timeStep': 'string',
705 'cohDet_thresh': 'string',
706 'noise_timeStep': 'string',
707 'noise_multiple': 'string',
708 'multDet_timeLimit': 'string',
709 'multDet_rangeLimit': 'string',
710 'phaseThresh': 'string',
711 'SNRThresh': 'string',
712 'hmin': 'string',
713 'hmax': 'string',
714 'azimuth': 'string',
715 'channelPositions': 'string',
712 'hei_ref': global_type_string,
713 'tauindex': global_type_string,
714 'phaseOffsets': global_type_string,
715 'cohDetection': global_type_string,
716 'cohDet_timeStep': global_type_string,
717 'cohDet_thresh': global_type_string,
718 'noise_timeStep': global_type_string,
719 'noise_multiple': global_type_string,
720 'multDet_timeLimit': global_type_string,
721 'multDet_rangeLimit': global_type_string,
722 'phaseThresh': global_type_string,
723 'SNRThresh': global_type_string,
724 'hmin': global_type_string,
725 'hmax': global_type_string,
726 'azimuth': global_type_string,
727 'channelPositions': global_type_string,
716 728 }
717 729
718 730
719 731 SMPhaseCalibration
720 732 parameters = {
721 'hmin': 'string',
722 'hmax': 'string',
723 'channelPositions': 'string',
724 'nHours': 'string',
733 'hmin': global_type_string,
734 'hmax': global_type_string,
735 'channelPositions': global_type_string,
736 'nHours': global_type_string,
725 737 }
726 738
727 739
728 740 Scope
729 741 parameters = {
730 'id': 'string',
731 'wintitle': 'string',
732 'channelList': 'string',
733 'xmin': 'float',
734 'xmax': 'float',
735 'ymin': 'float',
736 'ymax': 'float',
737 'save': 'boolean',
738 'figpath': 'string',
739 'figfile': 'string',
740 'show': 'string',
741 'wr_period': 'int',
742 'ftp': 'string',
743 'server': 'string',
744 'folder': 'string',
745 'username': 'string',
746 'password': 'string',
747 'type': 'string',
742 'id': global_type_string,
743 'wintitle': global_type_string,
744 'channelList': global_type_list,
745 'xmin': global_type_float,
746 'xmax': global_type_float,
747 'ymin': global_type_float,
748 'ymax': global_type_float,
749 'save': global_type_boolean,
750 'figpath': global_type_string,
751 'figfile': global_type_string,
752 'show': global_type_string,
753 'wr_period': global_type_integer,
754 'ftp': global_type_string,
755 'server': global_type_string,
756 'folder': global_type_string,
757 'username': global_type_string,
758 'password': global_type_string,
759 'type': global_type_string,
748 760 }
749 761
750 762
751 763 SendByFTP
752 764 parameters = {
753 'ext': 'string',
754 'localfolder': 'string',
755 'remotefolder': 'string',
756 'server': 'string',
757 'username': 'string',
758 'password': 'string',
759 'period': 'string',
765 'ext': global_type_string,
766 'localfolder': global_type_string,
767 'remotefolder': global_type_string,
768 'server': global_type_string,
769 'username': global_type_string,
770 'password': global_type_string,
771 'period': global_type_string,
760 772 }
761 773
762 774
763 775 SkyMapPlot
764 776 parameters = {
765 'id': 'string',
766 'wintitle': 'string',
767 'channelList': 'string',
768 'showprofile': 'string',
769 'tmin': 'string',
770 'tmax': 'string',
771 'timerange': 'string',
772 'save': 'boolean',
773 'figpath': 'string',
774 'figfile': 'string',
775 'show': 'string',
776 'ftp': 'string',
777 'wr_period': 'int',
778 'server': 'string',
779 'folder': 'string',
780 'username': 'string',
781 'password': 'string',
782 'ftp_wei': 'string',
783 'exp_code': 'int',
784 'sub_exp_code': 'int',
785 'plot_pos': 'int',
786 'realtime': 'string',
777 'id': global_type_string,
778 'wintitle': global_type_string,
779 'channelList': global_type_list,
780 'showprofile': global_type_boolean,
781 'tmin': global_type_string,
782 'tmax': global_type_string,
783 'timerange': global_type_float,
784 'save': global_type_boolean,
785 'figpath': global_type_string,
786 'figfile': global_type_string,
787 'show': global_type_string,
788 'ftp': global_type_string,
789 'wr_period': global_type_integer,
790 'server': global_type_string,
791 'folder': global_type_string,
792 'username': global_type_string,
793 'password': global_type_string,
794 'ftp_wei': global_type_integer,
795 'exp_code': global_type_integer,
796 'sub_exp_code': global_type_integer,
797 'plot_pos': global_type_integer,
798 'realtime': global_type_boolean,
787 799 }
788 800
789 801
790 802 SpectraCutPlot
791 803 parameters = {
792 'id': 'string',
793 'wintitle': 'string',
794 'channelList': 'string',
795 'xmin': 'float',
796 'xmax': 'float',
797 'ymin': 'float',
798 'ymax': 'float',
799 'save': 'boolean',
800 'figpath': 'string',
801 'figfile': 'string',
802 'show': 'string',
803 'ftp': 'string',
804 'wr_period': 'int',
805 'server': 'string',
806 'folder': 'string',
807 'username': 'string',
808 'password': 'string',
809 'xaxis': 'string',
804 'id': global_type_string,
805 'wintitle': global_type_string,
806 'channelList': global_type_list,
807 'xmin': global_type_float,
808 'xmax': global_type_float,
809 'ymin': global_type_float,
810 'ymax': global_type_float,
811 'save': global_type_boolean,
812 'figpath': global_type_string,
813 'figfile': global_type_string,
814 'show': global_type_string,
815 'ftp': global_type_string,
816 'wr_period': global_type_integer,
817 'server': global_type_string,
818 'folder': global_type_string,
819 'username': global_type_string,
820 'password': global_type_string,
821 'xaxis': global_type_string,
810 822 }
811 823
812 824
813 825 SpectraHeisScope
814 826 parameters = {
815 'id': 'string',
816 'wintitle': 'string',
817 'channelList': 'string',
818 'xmin': 'float',
819 'xmax': 'float',
820 'ymin': 'float',
821 'ymax': 'float',
822 'save': 'boolean',
823 'figpath': 'string',
824 'figfile': 'string',
825 'ftp': 'string',
826 'wr_period': 'int',
827 'show': 'string',
828 'server': 'string',
829 'folder': 'string',
830 'username': 'string',
831 'password': 'string',
832 'ftp_wei': 'string',
833 'exp_code': 'int',
834 'sub_exp_code': 'int',
835 'plot_pos': 'int',
827 'id': global_type_string,
828 'wintitle': global_type_string,
829 'channelList': global_type_list,
830 'xmin': global_type_float,
831 'xmax': global_type_float,
832 'ymin': global_type_float,
833 'ymax': global_type_float,
834 'save': global_type_boolean,
835 'figpath': global_type_string,
836 'figfile': global_type_string,
837 'ftp': global_type_string,
838 'wr_period': global_type_integer,
839 'show': global_type_string,
840 'server': global_type_string,
841 'folder': global_type_string,
842 'username': global_type_string,
843 'password': global_type_string,
844 'ftp_wei': global_type_integer,
845 'exp_code': global_type_integer,
846 'sub_exp_code': global_type_integer,
847 'plot_pos': global_type_integer,
836 848 }
837 849
838 850
839 851 SpectraHeisWriter
840 852 parameters = {
841 : 'string',
853 : global_type_string,
842 854 }
843 855
844 856
845 857 SpectraPlot
846 858 parameters = {
847 'id': 'string',
848 'wintitle': 'string',
849 'channelList': 'string',
850 'showprofile': 'string',
851 'xmin': 'float',
852 'xmax': 'float',
853 'ymin': 'float',
854 'ymax': 'float',
855 'zmin': 'float',
856 'zmax': 'float',
857 'save': 'boolean',
858 'figpath': 'string',
859 'figfile': 'string',
860 'show': 'string',
861 'ftp': 'string',
862 'wr_period': 'int',
863 'server': 'string',
864 'folder': 'string',
865 'username': 'string',
866 'password': 'string',
867 'ftp_wei': 'string',
868 'exp_code': 'int',
869 'sub_exp_code': 'int',
870 'plot_pos': 'int',
871 'realtime': 'string',
872 'xaxis': 'string',
859 'id': global_type_string,
860 'wintitle': global_type_string,
861 'channelList': global_type_list,
862 'showprofile': global_type_boolean,
863 'xmin': global_type_float,
864 'xmax': global_type_float,
865 'ymin': global_type_float,
866 'ymax': global_type_float,
867 'zmin': global_type_float,
868 'zmax': global_type_float,
869 'save': global_type_boolean,
870 'figpath': global_type_string,
871 'figfile': global_type_string,
872 'show': global_type_string,
873 'ftp': global_type_string,
874 'wr_period': global_type_integer,
875 'server': global_type_string,
876 'folder': global_type_string,
877 'username': global_type_string,
878 'password': global_type_string,
879 'ftp_wei': global_type_integer,
880 'exp_code': global_type_integer,
881 'sub_exp_code': global_type_integer,
882 'plot_pos': global_type_integer,
883 'realtime': global_type_boolean,
884 'xaxis': global_type_string,
873 885 }
874 886
875 887
876 888 SpectraWriter
877 889 parameters = {
878 'path': 'string',
879 'blocksPerFile': 'string',
880 'profilesPerBlock': 'string',
881 'set': 'string',
882 'ext': 'string',
883 'datatype': 'string',
890 'path': global_type_string,
891 'blocksPerFile': global_type_string,
892 'profilesPerBlock': global_type_string,
893 'set': global_type_string,
894 'ext': global_type_string,
895 'datatype': global_type_string,
884 896 }
885 897
886 898
887 899 SpectralFitting
888 900 parameters = {
889 'getSNR': 'string',
890 'path': 'string',
891 'file': 'string',
892 'groupList': 'string',
901 'getSNR': global_type_string,
902 'path': global_type_string,
903 'file': global_type_string,
904 'groupList': global_type_string,
893 905 }
894 906
895 907
896 908 SpectralFittingPlot
897 909 parameters = {
898 'id': 'string',
899 'cutHeight': 'string',
900 'fit': 'string',
901 'wintitle': 'string',
902 'channelList': 'string',
903 'showprofile': 'string',
904 'xmin': 'float',
905 'xmax': 'float',
906 'ymin': 'float',
907 'ymax': 'float',
908 'save': 'boolean',
909 'figpath': 'string',
910 'figfile': 'string',
911 'show': 'string',
910 'id': global_type_string,
911 'cutHeight': global_type_string,
912 'fit': global_type_string,
913 'wintitle': global_type_string,
914 'channelList': global_type_list,
915 'showprofile': global_type_boolean,
916 'xmin': global_type_float,
917 'xmax': global_type_float,
918 'ymin': global_type_float,
919 'ymax': global_type_float,
920 'save': global_type_boolean,
921 'figpath': global_type_string,
922 'figfile': global_type_string,
923 'show': global_type_string,
912 924 }
913 925
914 926
915 927 SpectralMoments
916 928 parameters = {
917 : 'string',
929 : global_type_string,
918 930 }
919 931
920 932
921 933 SplitProfiles
922 934 parameters = {
923 'n': 'string',
935 'n': global_type_string,
924 936 }
925 937
926 938
927 939 USRPWriter
928 940 parameters = {
929 'dataIn': 'string',
941 'dataIn': global_type_string,
930 942 }
931 943
932 944
933 945 VoltageWriter
934 946 parameters = {
935 'path': 'string',
936 'blocksPerFile': 'string',
937 'profilesPerBlock': 'string',
938 'set': 'string',
939 'ext': 'string',
940 'datatype': 'string',
947 'path': global_type_string,
948 'blocksPerFile': global_type_string,
949 'profilesPerBlock': global_type_string,
950 'set': global_type_string,
951 'ext': global_type_string,
952 'datatype': global_type_string,
941 953 }
942 954
943 955
944 956 WindProfiler
945 957 parameters = {
946 'technique': 'string',
958 'technique': global_type_string,
947 959 }
948 960
949 961
950 962 WindProfilerPlot
951 963 parameters = {
952 'id': 'string',
953 'wintitle': 'string',
954 'channelList': 'string',
955 'showprofile': 'string',
956 'xmin': 'float',
957 'xmax': 'float',
958 'ymin': 'float',
959 'ymax': 'float',
960 'zmin': 'float',
961 'zmax': 'float',
962 'zmax_ver': 'string',
963 'zmin_ver': 'string',
964 'SNRmin': 'string',
965 'SNRmax': 'string',
966 'timerange': 'string',
967 'SNRthresh': 'string',
968 'save': 'boolean',
969 'figpath': 'string',
970 'lastone': 'string',
971 'figfile': 'string',
972 'ftp': 'string',
973 'wr_period': 'int',
974 'show': 'string',
975 'server': 'string',
976 'folder': 'string',
977 'username': 'string',
978 'password': 'string',
979 'ftp_wei': 'string',
980 'exp_code': 'int',
981 'sub_exp_code': 'int',
982 'plot_pos': 'int',
964 'id': global_type_string,
965 'wintitle': global_type_string,
966 'channelList': global_type_list,
967 'showprofile': global_type_boolean,
968 'xmin': global_type_float,
969 'xmax': global_type_float,
970 'ymin': global_type_float,
971 'ymax': global_type_float,
972 'zmin': global_type_float,
973 'zmax': global_type_float,
974 'zmax_ver': global_type_string,
975 'zmin_ver': global_type_string,
976 'SNRmin': global_type_float,
977 'SNRmax': global_type_float,
978 'timerange': global_type_float,
979 'SNRthresh': global_type_string,
980 'save': global_type_boolean,
981 'figpath': global_type_string,
982 'lastone': global_type_string,
983 'figfile': global_type_string,
984 'ftp': global_type_string,
985 'wr_period': global_type_integer,
986 'show': global_type_string,
987 'server': global_type_string,
988 'folder': global_type_string,
989 'username': global_type_string,
990 'password': global_type_string,
991 'ftp_wei': global_type_integer,
992 'exp_code': global_type_integer,
993 'sub_exp_code': global_type_integer,
994 'plot_pos': global_type_integer,
983 995 }
984 996
985 997
986 998 Writer
987 999 parameters = {
988 'dataIn': 'string',
1000 'dataIn': global_type_string,
989 1001 }
990 1002
991 1003
992 1004 AMISRProc
993 1005 parameters = {
994 : 'string',
1006 : global_type_string,
995 1007 }
996 1008
997 1009
998 1010 AMISRReader
999 1011 parameters = {
1000 : 'string',
1012 : global_type_string,
1001 1013 }
1002 1014
1003 1015
1004 1016 CorrelationProc
1005 1017 parameters = {
1006 'lags': 'string',
1007 'mode': 'string',
1018 'lags': global_type_string,
1019 'mode': global_type_string,
1008 1020 'pairsList': 'pairsLists',
1009 'fullBuffer': 'string',
1010 'nAvg': 'string',
1011 'removeDC': 'string',
1012 'splitCF': 'string',
1021 'fullBuffer': global_type_string,
1022 'nAvg': global_type_string,
1023 'removeDC': global_type_string,
1024 'splitCF': global_type_string,
1013 1025 }
1014 1026
1015 1027
1016 1028 FitsReader
1017 1029 parameters = {
1018 : 'string',
1030 : global_type_string,
1019 1031 }
1020 1032
1021 1033
1022 1034 HFReader
1023 1035 parameters = {
1024 : 'string',
1036 : global_type_string,
1025 1037 }
1026 1038
1027 1039
1028 1040 ParamReader
1029 1041 parameters = {
1030 : 'string',
1042 : global_type_string,
1031 1043 }
1032 1044
1033 1045
1034 1046 ParametersProc
1035 1047 parameters = {
1036 : 'string',
1048 : global_type_string,
1037 1049 }
1038 1050
1039 1051
1040 1052 ProcessingUnit
1041 1053 parameters = {
1042 : 'string',
1054 : global_type_string,
1043 1055 }
1044 1056
1045 1057
1046 1058 ReceiverData
1047 1059 parameters = {
1048 : 'string',
1060 : global_type_string,
1049 1061 }
1050 1062
1051 1063
1052 1064 SendToServer
1053 1065 parameters = {
1054 : 'string',
1066 : global_type_string,
1055 1067 }
1056 1068
1057 1069
1058 1070 SpectraAFCProc
1059 1071 parameters = {
1060 'nProfiles': 'string',
1061 'nFFTPoints': 'string',
1072 'nProfiles': global_type_string,
1073 'nFFTPoints': global_type_string,
1062 1074 'pairsList': 'pairsLists',
1063 'code': 'string',
1064 'nCode': 'string',
1065 'nBaud': 'string',
1075 'code': global_type_string,
1076 'nCode': global_type_string,
1077 'nBaud': global_type_string,
1066 1078 }
1067 1079
1068 1080
1069 1081 SpectraHeisProc
1070 1082 parameters = {
1071 : 'string',
1083 : global_type_string,
1072 1084 }
1073 1085
1074 1086
1075 1087 SpectraLagsProc
1076 1088 parameters = {
1077 'nProfiles': 'string',
1078 'nFFTPoints': 'string',
1089 'nProfiles': global_type_string,
1090 'nFFTPoints': global_type_string,
1079 1091 'pairsList': 'pairsLists',
1080 'code': 'string',
1081 'nCode': 'string',
1082 'nBaud': 'string',
1083 'codeFromHeader': 'string',
1084 'pulseIndex': 'string',
1092 'code': global_type_string,
1093 'nCode': global_type_string,
1094 'nBaud': global_type_string,
1095 'codeFromHeader': global_type_string,
1096 'pulseIndex': global_type_string,
1085 1097 }
1086 1098
1087 1099
1088 1100 SpectraProc
1089 1101 parameters = {
1090 'nProfiles': 'string',
1091 'nFFTPoints': 'string',
1102 'nProfiles': global_type_string,
1103 'nFFTPoints': global_type_string,
1092 1104 'pairsList': 'pairsLists',
1093 'ippFactor': 'string',
1105 'ippFactor': global_type_string,
1094 1106 }
1095 1107
1096 1108
1097 1109 SpectraReader
1098 1110 parameters = {
1099 'path': 'string',
1100 'startDate': 'string',
1101 'endDate': 'string',
1102 'startTime': 'string',
1103 'endTime': 'string',
1104 'set': 'string',
1105 'expLabel': 'string',
1106 'ext': 'string',
1107 'online': 'string',
1108 'delay': 'string',
1109 'walk': 'string',
1110 'getblock': 'string',
1111 'nTxs': 'string',
1112 'realtime': 'string',
1113 'blocksize': 'string',
1114 'blocktime': 'string',
1115 'queue': 'string',
1116 'skip': 'string',
1117 'cursor': 'string',
1118 'warnings': 'string',
1119 'verbose': 'string',
1111 'path': global_type_string,
1112 'startDate': global_type_string,
1113 'endDate': global_type_string,
1114 'startTime': global_type_string,
1115 'endTime': global_type_string,
1116 'set': global_type_string,
1117 'expLabel': global_type_string,
1118 'ext': global_type_string,
1119 'online': global_type_string,
1120 'delay': global_type_string,
1121 'walk': global_type_string,
1122 'getblock': global_type_string,
1123 'nTxs': global_type_string,
1124 'realtime': global_type_boolean,
1125 'blocksize': global_type_string,
1126 'blocktime': global_type_string,
1127 'queue': global_type_string,
1128 'skip': global_type_string,
1129 'cursor': global_type_string,
1130 'warnings': global_type_string,
1131 'verbose': global_type_string,
1120 1132 }
1121 1133
1122 1134
1123 1135 USRPReader
1124 1136 parameters = {
1125 : 'string',
1137 : global_type_string,
1126 1138 }
1127 1139
1128 1140
1129 1141 VoltageProc
1130 1142 parameters = {
1131 : 'string',
1143 : global_type_string,
1132 1144 }
1133 1145
1134 1146
1135 1147 VoltageReader
1136 1148 parameters = {
1137 'path': 'string',
1138 'startDate': 'string',
1139 'endDate': 'string',
1140 'startTime': 'string',
1141 'endTime': 'string',
1142 'set': 'string',
1143 'expLabel': 'string',
1144 'ext': 'string',
1145 'online': 'string',
1146 'delay': 'string',
1147 'walk': 'string',
1148 'getblock': 'string',
1149 'nTxs': 'string',
1150 'realtime': 'string',
1151 'blocksize': 'string',
1152 'blocktime': 'string',
1153 'queue': 'string',
1154 'skip': 'string',
1155 'cursor': 'string',
1156 'warnings': 'string',
1157 'verbose': 'string',
1149 'path': global_type_string,
1150 'startDate': global_type_string,
1151 'endDate': global_type_string,
1152 'startTime': global_type_string,
1153 'endTime': global_type_string,
1154 'set': global_type_string,
1155 'expLabel': global_type_string,
1156 'ext': global_type_string,
1157 'online': global_type_string,
1158 'delay': global_type_string,
1159 'walk': global_type_string,
1160 'getblock': global_type_string,
1161 'nTxs': global_type_string,
1162 'realtime': global_type_boolean,
1163 'blocksize': global_type_string,
1164 'blocktime': global_type_string,
1165 'queue': global_type_string,
1166 'skip': global_type_string,
1167 'cursor': global_type_string,
1168 'warnings': global_type_string,
1169 'verbose': global_type_string,
1158 1170 }
1159 1171
1160 1172
General Comments 0
You need to be logged in to leave comments. Login now