##// END OF EJS Templates
merge con cli
José Chávez -
r1035:b65644e03ac2 merge
parent child
Show More
@@ -0,0 +1,94
1 import argparse
2
3 from schainpy.controller import Project, multiSchain
4
5 desc = "HF_EXAMPLE"
6
7 def fiber(cursor, skip, q, dt):
8
9 controllerObj = Project()
10
11 controllerObj.setup(id='191', name='test01', description=desc)
12
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 )
28
29 # #opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock')
30 #
31 procUnitConfObj2 = controllerObj.addProcUnit(datatype='Spectra', inputId=readUnitConfObj.getId())
32 # procUnitConfObj2.addParameter(name='nipp', value='5', format='int')
33
34 # procUnitConfObj3 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=readUnitConfObj.getId())
35 # opObj11 = procUnitConfObj3.addOperation(name='SpectralMoments', optype='other')
36
37 #
38 opObj11 = procUnitConfObj2.addOperation(name='RTIPlot', optype='other')
39 opObj11.addParameter(name='id', value='1000', format='int')
40 opObj11.addParameter(name='wintitle', value='HF_Jicamarca_Spc', format='str')
41 opObj11.addParameter(name='xmin', value='0', format='int')
42 opObj11.addParameter(name='xmax', value='24', format='int')
43
44 # opObj11 = procUnitConfObj3.addOperation(name='Parameters1Plot', optype='other')
45 # opObj11.addParameter(name='channelList', value='0', format='intList')
46 #
47 # opObj11.addParameter(name='id', value='2000', format='int')
48 # # opObj11.addParameter(name='colormap', value='0', format='bool')
49 # opObj11.addParameter(name='onlySNR', value='1', format='bool')
50 # opObj11.addParameter(name='DOP', value='0', format='bool')
51 # opObj11.addParameter(name='showSNR', value='1', format='bool')
52 # opObj11.addParameter(name='SNRthresh', value='0', format='int')
53 # opObj11.addParameter(name='SNRmin', value='-10', format='int')
54 # opObj11.addParameter(name='SNRmax', value='30', format='int')
55
56 # opObj11.addParameter(name='showSNR', value='1', format='int')
57 # # opObj11.addParameter(name='channelList', value='0', format='intlist')
58 # # opObj11.addParameter(name='xmin', value='0', format='float')
59 # opObj11.addParameter(name='xmin', value='0', format='float')
60 # opObj11.addParameter(name='xmax', value='24', format='float')
61
62 # opObj11.addParameter(name='zmin', value='-110', format='float')
63 # opObj11.addParameter(name='zmax', value='-70', format='float')
64 # opObj11.addParameter(name='save', value='0', format='int')
65 # # opObj11.addParameter(name='figpath', value='/tmp/', format='str')
66 #
67 # opObj12 = procUnitConfObj2.addOperation(name='PublishData', optype='other')
68 # opObj12.addParameter(name='zeromq', value=1, format='int')
69 # opObj12.addParameter(name='server', value='tcp://10.10.10.82:7000', format='str')
70
71
72 # opObj13 = procUnitConfObj3.addOperation(name='PublishData', optype='other')
73 # opObj13.addParameter(name='zeromq', value=1, format='int')
74 # opObj13.addParameter(name='server', value="juanca", format='str')
75
76 # opObj12.addParameter(name='delay', value=1, format='int')
77
78
79 # print "Escribiendo el archivo XML"
80 # controllerObj.writeXml(filename)
81 # print "Leyendo el archivo XML"
82 # controllerObj.readXml(filename)
83
84
85 # timeit.timeit('controllerObj.run()', number=2)
86
87 controllerObj.start()
88
89
90 if __name__ == '__main__':
91 parser = argparse.ArgumentParser(description='Set number of parallel processes')
92 parser.add_argument('--nProcess', default=1, type=int)
93 args = parser.parse_args()
94 multiSchain(fiber, nProcess=args.nProcess, startDate='2016/08/19', endDate='2016/08/19')
@@ -0,0 +1,6
1 [Desktop Entry]
2 Encoding=UTF-8
3 Name=Link to
4 Type=Link
5 URL=file:///home/nanosat/schain/schainpy/utils/parameters.txt
6 Icon=text-plain
This diff has been collapsed as it changes many lines, (1177 lines changed) Show them Hide them
@@ -0,0 +1,1177
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 global_type_integer_or_list = 'integer_or_list'
11
12 #BeaconPhase
13 parameters = {
14 'id': global_type_string,
15 'wintitle': global_type_string,
16 'pairsList': global_type_pairsList,
17 'showprofile': global_type_boolean,
18 'xmin': global_type_float,
19 'xmax': global_type_float,
20 'ymin': global_type_float,
21 'ymax': global_type_float,
22 'hmin': global_type_float,
23 'hmax': global_type_float,
24 'timerange': global_type_float,
25 'save': global_type_boolean,
26 'figpath': global_type_string,
27 'figfile': global_type_string,
28 'show': global_type_boolean,
29 'ftp': global_type_boolean,
30 'wr_period': global_type_integer,
31 'server': global_type_string,
32 'folder': global_type_string,
33 'username': global_type_string,
34 'password': global_type_string,
35 'ftp_wei': global_type_integer,
36 'exp_code': global_type_integer,
37 'sub_exp_code': global_type_integer,
38 'plot_pos': global_type_integer,
39 }
40
41
42 #BeamSelector
43 parameters = {
44 'beam': global_type_string,
45 }
46
47
48 #CohInt
49 parameters = {
50 'n': global_type_integer,
51 'timeInterval': global_type_float,
52 'overlapping': global_type_boolean,
53 'byblock': global_type_boolean
54 }
55
56
57 #CoherenceMap
58 parameters = {
59 'id': global_type_string,
60 'wintitle': global_type_string,
61 'pairsList': global_type_pairsList,
62 'showprofile': global_type_boolean,
63 'xmin': global_type_float,
64 'xmax': global_type_float,
65 'ymin': global_type_float,
66 'ymax': global_type_float,
67 'zmin': global_type_float,
68 'zmax': global_type_float,
69 'timerange': global_type_float,
70 'phase_min': global_type_float,
71 'phase_max': global_type_float,
72 'save': global_type_boolean,
73 'figpath': global_type_string,
74 'figfile': global_type_string,
75 'ftp': global_type_boolean,
76 'wr_period': global_type_integer,
77 'coherence_cmap': global_type_colormap,
78 'phase_cmap': global_type_colormap,
79 'show': global_type_boolean,
80 'server': global_type_string,
81 'folder': global_type_string,
82 'username': global_type_string,
83 'password': global_type_string,
84 'ftp_wei': global_type_integer,
85 'exp_code': global_type_integer,
86 'sub_exp_code': global_type_integer,
87 'plot_pos': global_type_integer,
88 }
89
90
91 #CombineProfiles
92 parameters = {
93 'n': global_type_integer,
94 }
95
96
97 #CorrectSMPhases
98 parameters = {
99 'phaseOffsets': global_type_pairsList,
100 'hmin': global_type_float,
101 'hmax': global_type_float,
102 'azimuth': global_type_float,
103 'channelPositions': global_type_pairsList,
104 }
105
106
107 #CorrelationPlot
108 parameters = {
109 'id': global_type_string,
110 'wintitle': global_type_string,
111 'channelList': global_type_list,
112 'showprofile': global_type_boolean,
113 'xmin': global_type_float,
114 'xmax': global_type_float,
115 'ymin': global_type_float,
116 'ymax': global_type_float,
117 'zmin': global_type_float,
118 'zmax': global_type_float,
119 'save': global_type_boolean,
120 'figpath': global_type_string,
121 'figfile': global_type_string,
122 'show': global_type_boolean,
123 'ftp': global_type_boolean,
124 'wr_period': global_type_integer,
125 'server': global_type_string,
126 'folder': global_type_string,
127 'username': global_type_string,
128 'password': global_type_string,
129 'ftp_wei': global_type_integer,
130 'exp_code': global_type_integer,
131 'sub_exp_code': global_type_integer,
132 'plot_pos': global_type_integer,
133 'realtime': global_type_boolean,
134 }
135
136
137 #CrossSpectraPlot
138 parameters = {
139 'id': global_type_string,
140 'wintitle': global_type_string,
141 'pairsList': global_type_pairsList,
142 'xmin': global_type_float,
143 'xmax': global_type_float,
144 'ymin': global_type_float,
145 'ymax': global_type_float,
146 'zmin': global_type_float,
147 'zmax': global_type_float,
148 'coh_min': global_type_float,
149 'coh_max': global_type_float,
150 'phase_min': global_type_float,
151 'phase_max': global_type_float,
152 'save': global_type_boolean,
153 'figpath': global_type_string,
154 'figfile': global_type_string,
155 'ftp': global_type_boolean,
156 'wr_period': global_type_integer,
157 'power_cmap': global_type_colormap,
158 'coherence_cmap': global_type_colormap,
159 'phase_cmap': global_type_colormap,
160 'show': global_type_boolean,
161 'server': global_type_string,
162 'folder': global_type_string,
163 'username': global_type_string,
164 'password': global_type_string,
165 'ftp_wei': global_type_integer,
166 'exp_code': global_type_integer,
167 'sub_exp_code': global_type_integer,
168 'plot_pos': global_type_integer,
169 'xaxis': global_type_string,
170 }
171
172
173 #Decoder
174 parameters = {
175 'code': global_type_list,
176 'nCode': global_type_integer,
177 'nBaud': global_type_integer,
178 'mode': global_type_integer,
179 'osamp': global_type_float,
180 }
181
182
183 #EWDriftsEstimation
184 parameters = {
185 'zenith': global_type_list,
186 'zenithCorrection': global_type_float,
187 }
188
189
190 #EWDriftsPlot
191 parameters = {
192 'id': global_type_string,
193 'wintitle': global_type_string,
194 'channelList': global_type_list,
195 'xmin': global_type_float,
196 'xmax': global_type_float,
197 'ymin': global_type_float,
198 'ymax': global_type_float,
199 'zmin': global_type_float,
200 'zmax': global_type_float,
201 'zmaxVertfloat': global_type_float,
202 'zminVertfloat': global_type_float,
203 'zmaxZonafloat': global_type_float,
204 'zminZonafloat': global_type_float,
205 'timerange': global_type_float,
206 'SNRthresh': global_type_float,
207 'SNRmin': global_type_float,
208 'SNRmax': global_type_float,
209 'SNR_1': global_type_boolean,
210 'save': global_type_boolean,
211 'figpath': global_type_string,
212 'lastone': global_type_float,
213 'figfile': global_type_string,
214 'ftp': global_type_string,
215 'wr_period': global_type_integer,
216 'show': global_type_string,
217 'server': global_type_string,
218 'folder': global_type_string,
219 'username': global_type_string,
220 'password': global_type_string,
221 'ftp_wei': global_type_integer,
222 'exp_code': global_type_integer,
223 'sub_exp_code': global_type_integer,
224 'plot_pos': global_type_integer,
225 }
226
227
228 Figure
229 # parameters = {
230 # : global_type_string,
231 # }
232
233
234 #FitsWriter
235 parameters = {
236 'path': global_type_string,
237 'dataBlocksPerFile': global_type_integer,
238 'metadatafile': global_type_string,
239 }
240
241
242 #IncohInt
243 parameters = {
244 'n': global_type_float,
245 'timeInterval': global_type_integer,
246 'overlapping': global_type_boolean,
247 }
248
249
250 #IncohInt4SpectraHeis
251 parameters = {
252 'n': global_type_float,
253 'timeInterval': global_type_integer,
254 'overlapping': global_type_boolean,
255 }
256
257
258 #MomentsPlot
259 parameters = {
260 'id': global_type_string,
261 'wintitle': global_type_string,
262 'channelList': global_type_list,
263 'showprofile': global_type_boolean,
264 'xmin': global_type_float,
265 'xmax': global_type_float,
266 'ymin': global_type_float,
267 'ymax': global_type_float,
268 'zmin': global_type_float,
269 'zmax': global_type_float,
270 'save': global_type_boolean,
271 'figpath': global_type_string,
272 'figfile': global_type_string,
273 'show': global_type_boolean,
274 'ftp': global_type_boolean,
275 'wr_period': global_type_integer,
276 'server': global_type_string,
277 'folder': global_type_string,
278 'username': global_type_string,
279 'password': global_type_string,
280 'ftp_wei': global_type_string,
281 'exp_code': global_type_integer,
282 'sub_exp_code': global_type_integer,
283 'plot_pos': global_type_integer,
284 'realtime': global_type_boolean,
285 }
286
287
288 #NSMeteorDetection1Plot
289 parameters = {
290 'id': global_type_string,
291 'wintitle': global_type_string,
292 'channelList': global_type_list,
293 'showprofile': global_type_boolean,
294 'xmin': global_type_float,
295 'xmax': global_type_float,
296 'ymin': global_type_float,
297 'ymax': global_type_float,
298 'SNRmin': global_type_float,
299 'SNRmax': global_type_float,
300 'vmin': global_type_float,
301 'vmax': global_type_float,
302 'wmin': global_type_float,
303 'wmax': global_type_float,
304 'mode': global_type_string,
305 'save': global_type_boolean,
306 'figpath': global_type_string,
307 'figfile': global_type_string,
308 'show': global_type_boolean,
309 'ftp': global_type_string,
310 'wr_period': global_type_integer,
311 'server': global_type_string,
312 'folder': global_type_string,
313 'username': global_type_string,
314 'password': global_type_string,
315 'ftp_wei': global_type_integer,
316 'exp_code': global_type_integer,
317 'sub_exp_code': global_type_integer,
318 'plot_pos': global_type_integer,
319 'realtime': global_type_boolean,
320 'xaxis': global_type_string,
321 }
322
323
324 #NSMeteorDetection2Plot
325 parameters = {
326 'id': global_type_string,
327 'wintitle': global_type_string,
328 'channelList': global_type_list,
329 'showprofile': global_type_boolean,
330 'xmin': global_type_float,
331 'xmax': global_type_float,
332 'ymin': global_type_float,
333 'ymax': global_type_float,
334 'SNRmin': global_type_float,
335 'SNRmax': global_type_float,
336 'vmin': global_type_float,
337 'vmax': global_type_float,
338 'wmin': global_type_float,
339 'wmax': global_type_float,
340 'mode': global_type_string,
341 'save': global_type_boolean,
342 'figpath': global_type_string,
343 'figfile': global_type_string,
344 'show': global_type_string,
345 'ftp': global_type_boolean,
346 'wr_period': global_type_integer,
347 'server': global_type_string,
348 'folder': global_type_string,
349 'username': global_type_string,
350 'password': global_type_string,
351 'ftp_wei': global_type_integer,
352 'exp_code': global_type_integer,
353 'sub_exp_code': global_type_integer,
354 'plot_pos': global_type_integer,
355 'realtime': global_type_boolean,
356 'xaxis': global_type_string,
357 }
358
359
360 #Noise
361 parameters = {
362 'id': global_type_string,
363 'wintitle': global_type_string,
364 'channelList': global_type_list,
365 'showprofile': global_type_boolean,
366 'xmin': global_type_float,
367 'xmax': global_type_float,
368 'ymin': global_type_float,
369 'ymax': global_type_float,
370 'timerange': global_type_float,
371 'save': global_type_boolean,
372 'figpath': global_type_string,
373 'figfile': global_type_string,
374 'show': global_type_boolean,
375 'ftp': global_type_boolean,
376 'wr_period': global_type_integer,
377 'server': global_type_string,
378 'folder': global_type_string,
379 'username': global_type_string,
380 'password': global_type_string,
381 'ftp_wei': global_type_integer,
382 'exp_code': global_type_integer,
383 'sub_exp_code': global_type_integer,
384 'plot_pos': global_type_integer,
385 }
386
387
388 #NonSpecularMeteorDetection
389 parameters = {
390 'mode': global_type_string,
391 'SNRthresh': global_type_float,
392 'phaseDerThresh': global_type_float,
393 'cohThresh': global_type_float,
394 'allData': global_type_boolean,
395 }
396
397
398 Operation
399 parameters = {
400 'dataIn': global_type_string,
401 }
402
403
404 #ParamWriter
405 parameters = {
406 'path': global_type_string,
407 'blocksPerFile':global_type_integer,
408 'metadataList': global_type_list,
409 'dataList': global_type_list,
410 'mode': global_type_integer,
411 }
412
413
414 #Parameters1Plot
415 parameters = {
416 'id': global_type_string,
417 'wintitle': global_type_string,
418 'channelList': global_type_list,
419 'showprofile': global_type_boolean,
420 'xmin': global_type_float,
421 'xmax': global_type_float,
422 'ymin': global_type_float,
423 'ymax': global_type_float,
424 'zmin': global_type_float,
425 'zmax': global_type_float,
426 'timerange': global_type_float,
427 'parameterIndex': global_type_float,
428 'onlyPositive': global_type_boolean,
429 'SNRthresh': global_type_float,
430 'SNR': global_type_boolean,
431 'SNRmin': global_type_float,
432 'SNRmax': global_type_float,
433 'onlySNR': global_type_boolean,
434 'DOP': global_type_boolean,
435 'zlabel': global_type_string,
436 'parameterName': global_type_string,
437 'parameterObject': global_type_string,
438 'save': global_type_boolean,
439 'figpath': global_type_string,
440 'lastone': global_type_integer,
441 'figfile': global_type_string,
442 'ftp': global_type_boolean,
443 'wr_period': global_type_integer,
444 'show': global_type_string,
445 'server': global_type_string,
446 'folder': global_type_string,
447 'username': global_type_string,
448 'password': global_type_string,
449 'ftp_wei': global_type_integer,
450 'exp_code': global_type_integer,
451 'sub_exp_code': global_type_integer,
452 'plot_pos': global_type_integer,
453 }
454
455
456 #ParametersPlot
457 parameters = {
458 'id': global_type_string,
459 'wintitle': global_type_string,
460 'channelList': global_type_list,
461 'paramIndex': global_type_integer,
462 'colormap': global_type_colormap,
463 'xmin': global_type_float,
464 'xmax': global_type_float,
465 'ymin': global_type_float,
466 'ymax': global_type_float,
467 'zmin': global_type_float,
468 'zmax': global_type_float,
469 'timerange': global_type_float,
470 'showSNR': global_type_boolean,
471 'SNRthresh': global_type_float,
472 'SNRmin': global_type_float,
473 'SNRmax': global_type_float,
474 'save': global_type_boolean,
475 'figpath': global_type_string,
476 'lastone': global_type_integer,
477 'figfile': global_type_string,
478 'ftp': global_type_boolean,
479 'wr_period': global_type_integer,
480 'show': global_type_boolean,
481 'server': global_type_string,
482 'folder': global_type_string,
483 'username': global_type_string,
484 'password': global_type_string,
485 'ftp_wei': global_type_integer,
486 'exp_code': global_type_integer,
487 'sub_exp_code': global_type_integer,
488 'plot_pos': global_type_integer,
489 }
490
491
492 #PhasePlot
493 parameters = {
494 'id': global_type_string,
495 'wintitle': global_type_string,
496 'pairsList': global_type_pairsList,
497 'showprofile': global_type_boolean,
498 'xmin': global_type_float,
499 'xmax': global_type_float,
500 'ymin': global_type_float,
501 'ymax': global_type_float,
502 'timerange': global_type_float,
503 'save': global_type_boolean,
504 'figpath': global_type_string,
505 'figfile': global_type_string,
506 'show': global_type_boolean,
507 'ftp': global_type_boolean,
508 'wr_period': global_type_integer,
509 'server': global_type_string,
510 'folder': global_type_string,
511 'username': global_type_string,
512 'password': global_type_string,
513 'ftp_wei': global_type_integer,
514 'exp_code': global_type_integer,
515 'sub_exp_code': global_type_integer,
516 'plot_pos': global_type_integer,
517 }
518
519
520 PlotCOHData
521 parameters = {
522 : global_type_string,
523 }
524
525
526 PlotCrossSpectraData
527 parameters = {
528 : global_type_string,
529 }
530
531
532 PlotDOPData
533 parameters = {
534 : global_type_string,
535 }
536
537
538 PlotData
539 parameters = {
540 : global_type_string,
541 }
542
543
544 PlotNoiseData
545 parameters = {
546 : global_type_string,
547 }
548
549
550 PlotPHASEData
551 parameters = {
552 : global_type_string,
553 }
554
555
556 PlotRTIData
557 parameters = {
558 : global_type_string,
559 }
560
561
562 PlotSNRData
563 parameters = {
564 : global_type_string,
565 }
566
567
568 PlotSpectraData
569 parameters = {
570 : global_type_string,
571 }
572
573
574 PlotSpectraMeanData
575 parameters = {
576 : global_type_string,
577 }
578
579
580 PlotWindProfilerData
581 parameters = {
582 : global_type_string,
583 }
584
585
586 PowerProfilePlot
587 parameters = {
588 'id': global_type_string,
589 'wintitle': global_type_string,
590 'channelList': global_type_list,
591 'xmin': global_type_float,
592 'xmax': global_type_float,
593 'ymin': global_type_float,
594 'ymax': global_type_float,
595 'save': global_type_boolean,
596 'figpath': global_type_string,
597 'figfile': global_type_string,
598 'show': global_type_boolean,
599 'ftp': global_type_boolean,
600 'wr_period': global_type_integer,
601 'server': global_type_string,
602 'folder': global_type_string,
603 'username': global_type_string,
604 'password': global_type_string,
605 }
606
607
608 PrintInfo
609 parameters = {
610 : global_type_string,
611 }
612
613
614 ProfileConcat
615 parameters = {
616 'm': global_type_string,
617 }
618
619
620 ProfileSelector
621 parameters = {
622 'profileList': global_type_string,
623 'profileRangeList': global_type_string,
624 'beam': global_type_string,
625 'byblock': global_type_string,
626 'rangeList': global_type_string,
627 'nProfiles': global_type_string,
628 }
629
630
631 ProfileToChannels
632 parameters = {
633 : global_type_string,
634 }
635
636
637 PublishData
638 parameters = {
639 : global_type_string,
640 }
641
642
643 RTIPlot
644 parameters = {
645 'id': global_type_string,
646 'wintitle': global_type_string,
647 'channelList': global_type_list,
648 'showprofile': global_type_boolean,
649 'xmin': global_type_float,
650 'xmax': global_type_float,
651 'ymin': global_type_float,
652 'ymax': global_type_float,
653 'zmin': global_type_float,
654 'zmax': global_type_float,
655 'timerange': global_type_float,
656 'save': global_type_boolean,
657 'figpath': global_type_string,
658 'lastone': global_type_string,
659 'figfile': global_type_string,
660 'ftp': global_type_boolean,
661 'wr_period': global_type_integer,
662 'show': global_type_boolean,
663 'server': global_type_string,
664 'folder': global_type_string,
665 'username': global_type_string,
666 'password': global_type_string,
667 'ftp_wei': global_type_integer,
668 'exp_code': global_type_integer,
669 'sub_exp_code': global_type_integer,
670 'plot_pos': global_type_integer,
671 }
672
673
674 RTIfromSpectraHeis
675 parameters = {
676 'id': global_type_string,
677 'wintitle': global_type_string,
678 'channelList': global_type_list,
679 'showprofile': global_type_boolean,
680 'xmin': global_type_float,
681 'xmax': global_type_float,
682 'ymin': global_type_float,
683 'ymax': global_type_float,
684 'timerange': global_type_float,
685 'save': global_type_boolean,
686 'figpath': global_type_string,
687 'figfile': global_type_string,
688 'ftp': global_type_boolean,
689 'wr_period': global_type_integer,
690 'show': global_type_boolean,
691 'server': global_type_string,
692 'folder': global_type_string,
693 'username': global_type_string,
694 'password': global_type_string,
695 'ftp_wei': global_type_integer,
696 'exp_code': global_type_integer,
697 'sub_exp_code': global_type_integer,
698 'plot_pos': global_type_integer,
699 }
700
701
702 Reshaper
703 parameters = {
704 'shape': global_type_string,
705 'nTxs': global_type_string,
706 }
707
708
709 SALags
710 parameters = {
711 : global_type_string,
712 }
713
714
715 SMDetection
716 parameters = {
717 'hei_ref': global_type_string,
718 'tauindex': global_type_string,
719 'phaseOffsets': global_type_string,
720 'cohDetection': global_type_string,
721 'cohDet_timeStep': global_type_string,
722 'cohDet_thresh': global_type_string,
723 'noise_timeStep': global_type_string,
724 'noise_multiple': global_type_string,
725 'multDet_timeLimit': global_type_string,
726 'multDet_rangeLimit': global_type_string,
727 'phaseThresh': global_type_string,
728 'SNRThresh': global_type_string,
729 'hmin': global_type_string,
730 'hmax': global_type_string,
731 'azimuth': global_type_string,
732 'channelPositions': global_type_string,
733 }
734
735
736 SMPhaseCalibration
737 parameters = {
738 'hmin': global_type_string,
739 'hmax': global_type_string,
740 'channelPositions': global_type_string,
741 'nHours': global_type_string,
742 }
743
744
745 Scope
746 parameters = {
747 'id': global_type_string,
748 'wintitle': global_type_string,
749 'channelList': global_type_list,
750 'xmin': global_type_float,
751 'xmax': global_type_float,
752 'ymin': global_type_float,
753 'ymax': global_type_float,
754 'save': global_type_boolean,
755 'figpath': global_type_string,
756 'figfile': global_type_string,
757 'show': global_type_boolean,
758 'wr_period': global_type_integer,
759 'ftp': global_type_boolean,
760 'server': global_type_string,
761 'folder': global_type_string,
762 'username': global_type_string,
763 'password': global_type_string,
764 'type': global_type_string,
765 }
766
767
768 SendByFTP
769 parameters = {
770 'ext': global_type_string,
771 'localfolder': global_type_string,
772 'remotefolder': global_type_string,
773 'server': global_type_string,
774 'username': global_type_string,
775 'password': global_type_string,
776 'period': global_type_string,
777 }
778
779
780 SkyMapPlot
781 parameters = {
782 'id': global_type_string,
783 'wintitle': global_type_string,
784 'channelList': global_type_list,
785 'showprofile': global_type_boolean,
786 'tmin': global_type_string,
787 'tmax': global_type_string,
788 'timerange': global_type_float,
789 'save': global_type_boolean,
790 'figpath': global_type_string,
791 'figfile': global_type_string,
792 'show': global_type_boolean,
793 'ftp': global_type_boolean,
794 'wr_period': global_type_integer,
795 'server': global_type_string,
796 'folder': global_type_string,
797 'username': global_type_string,
798 'password': global_type_string,
799 'ftp_wei': global_type_integer,
800 'exp_code': global_type_integer,
801 'sub_exp_code': global_type_integer,
802 'plot_pos': global_type_integer,
803 'realtime': global_type_boolean,
804 }
805
806
807 SpectraCutPlot
808 parameters = {
809 'id': global_type_string,
810 'wintitle': global_type_string,
811 'channelList': global_type_list,
812 'xmin': global_type_float,
813 'xmax': global_type_float,
814 'ymin': global_type_float,
815 'ymax': global_type_float,
816 'save': global_type_boolean,
817 'figpath': global_type_string,
818 'figfile': global_type_string,
819 'show': global_type_boolean,
820 'ftp': global_type_boolean,
821 'wr_period': global_type_integer,
822 'server': global_type_string,
823 'folder': global_type_string,
824 'username': global_type_string,
825 'password': global_type_string,
826 'xaxis': global_type_string,
827 }
828
829
830 SpectraHeisScope
831 parameters = {
832 'id': global_type_string,
833 'wintitle': global_type_string,
834 'channelList': global_type_list,
835 'xmin': global_type_float,
836 'xmax': global_type_float,
837 'ymin': global_type_float,
838 'ymax': global_type_float,
839 'save': global_type_boolean,
840 'figpath': global_type_string,
841 'figfile': global_type_string,
842 'ftp': global_type_boolean,
843 'wr_period': global_type_integer,
844 'show': global_type_boolean,
845 'server': global_type_string,
846 'folder': global_type_string,
847 'username': global_type_string,
848 'password': global_type_string,
849 'ftp_wei': global_type_integer,
850 'exp_code': global_type_integer,
851 'sub_exp_code': global_type_integer,
852 'plot_pos': global_type_integer,
853 }
854
855
856 SpectraHeisWriter
857 parameters = {
858 : global_type_string,
859 }
860
861
862 SpectraPlot
863 parameters = {
864 'id': global_type_string,
865 'wintitle': global_type_string,
866 'channelList': global_type_list,
867 'showprofile': global_type_boolean,
868 'xmin': global_type_float,
869 'xmax': global_type_float,
870 'ymin': global_type_float,
871 'ymax': global_type_float,
872 'zmin': global_type_float,
873 'zmax': global_type_float,
874 'save': global_type_boolean,
875 'figpath': global_type_string,
876 'figfile': global_type_string,
877 'show': global_type_boolean,
878 'ftp': global_type_boolean,
879 'wr_period': global_type_integer,
880 'server': global_type_string,
881 'folder': global_type_string,
882 'username': global_type_string,
883 'password': global_type_string,
884 'ftp_wei': global_type_integer,
885 'exp_code': global_type_integer,
886 'sub_exp_code': global_type_integer,
887 'plot_pos': global_type_integer,
888 'realtime': global_type_boolean,
889 'xaxis': global_type_string,
890 }
891
892
893 SpectraWriter
894 parameters = {
895 'path': global_type_string,
896 'blocksPerFile': global_type_string,
897 'profilesPerBlock': global_type_string,
898 'set': global_type_string,
899 'ext': global_type_string,
900 'datatype': global_type_string,
901 }
902
903
904 SpectralFitting
905 parameters = {
906 'getSNR': global_type_string,
907 'path': global_type_string,
908 'file': global_type_string,
909 'groupList': global_type_string,
910 }
911
912
913 SpectralFittingPlot
914 parameters = {
915 'id': global_type_string,
916 'cutHeight': global_type_string,
917 'fit': global_type_string,
918 'wintitle': global_type_string,
919 'channelList': global_type_list,
920 'showprofile': global_type_boolean,
921 'xmin': global_type_float,
922 'xmax': global_type_float,
923 'ymin': global_type_float,
924 'ymax': global_type_float,
925 'save': global_type_boolean,
926 'figpath': global_type_string,
927 'figfile': global_type_string,
928 'show': global_type_boolean,
929 }
930
931
932 SpectralMoments
933 parameters = {
934 : global_type_string,
935 }
936
937
938 SplitProfiles
939 parameters = {
940 'n': global_type_string,
941 }
942
943
944 USRPWriter
945 parameters = {
946 'dataIn': global_type_string,
947 }
948
949
950 VoltageWriter
951 parameters = {
952 'path': global_type_string,
953 'blocksPerFile': global_type_string,
954 'profilesPerBlock': global_type_string,
955 'set': global_type_string,
956 'ext': global_type_string,
957 'datatype': global_type_string,
958 }
959
960
961 WindProfiler
962 parameters = {
963 'technique': global_type_string,
964 }
965
966
967 WindProfilerPlot
968 parameters = {
969 'id': global_type_string,
970 'wintitle': global_type_string,
971 'channelList': global_type_list,
972 'showprofile': global_type_boolean,
973 'xmin': global_type_float,
974 'xmax': global_type_float,
975 'ymin': global_type_float,
976 'ymax': global_type_float,
977 'zmin': global_type_float,
978 'zmax': global_type_float,
979 'zmax_ver': global_type_string,
980 'zmin_ver': global_type_string,
981 'SNRmin': global_type_float,
982 'SNRmax': global_type_float,
983 'timerange': global_type_float,
984 'SNRthresh': global_type_string,
985 'save': global_type_boolean,
986 'figpath': global_type_string,
987 'lastone': global_type_string,
988 'figfile': global_type_string,
989 'ftp': global_type_boolean,
990 'wr_period': global_type_integer,
991 'show': global_type_boolean,
992 'server': global_type_string,
993 'folder': global_type_string,
994 'username': global_type_string,
995 'password': global_type_string,
996 'ftp_wei': global_type_integer,
997 'exp_code': global_type_integer,
998 'sub_exp_code': global_type_integer,
999 'plot_pos': global_type_integer,
1000 }
1001
1002
1003 Writer
1004 parameters = {
1005 'dataIn': global_type_string,
1006 }
1007
1008
1009 AMISRProc
1010 parameters = {
1011 : global_type_string,
1012 }
1013
1014
1015 AMISRReader
1016 parameters = {
1017 : global_type_string,
1018 }
1019
1020
1021 CorrelationProc
1022 parameters = {
1023 'lags': global_type_string,
1024 'mode': global_type_string,
1025 'pairsList': 'pairsLists',
1026 'fullBuffer': global_type_string,
1027 'nAvg': global_type_string,
1028 'removeDC': global_type_string,
1029 'splitCF': global_type_string,
1030 }
1031
1032
1033 FitsReader
1034 parameters = {
1035 : global_type_string,
1036 }
1037
1038
1039 HFReader
1040 parameters = {
1041 : global_type_string,
1042 }
1043
1044
1045 ParamReader
1046 parameters = {
1047 : global_type_string,
1048 }
1049
1050
1051 ParametersProc
1052 parameters = {
1053 : global_type_string,
1054 }
1055
1056
1057 ProcessingUnit
1058 parameters = {
1059 : global_type_string,
1060 }
1061
1062
1063 ReceiverData
1064 parameters = {
1065 : global_type_string,
1066 }
1067
1068
1069 SendToServer
1070 parameters = {
1071 : global_type_string,
1072 }
1073
1074
1075 SpectraAFCProc
1076 parameters = {
1077 'nProfiles': global_type_string,
1078 'nFFTPoints': global_type_string,
1079 'pairsList': 'pairsLists',
1080 'code': global_type_string,
1081 'nCode': global_type_string,
1082 'nBaud': global_type_string,
1083 }
1084
1085
1086 SpectraHeisProc
1087 parameters = {
1088 : global_type_string,
1089 }
1090
1091
1092 SpectraLagsProc
1093 parameters = {
1094 'nProfiles': global_type_string,
1095 'nFFTPoints': global_type_string,
1096 'pairsList': 'pairsLists',
1097 'code': global_type_string,
1098 'nCode': global_type_string,
1099 'nBaud': global_type_string,
1100 'codeFromHeader': global_type_string,
1101 'pulseIndex': global_type_string,
1102 }
1103
1104
1105 SpectraProc
1106 parameters = {
1107 'nProfiles': global_type_string,
1108 'nFFTPoints': global_type_string,
1109 'pairsList': 'pairsLists',
1110 'ippFactor': global_type_string,
1111 }
1112
1113
1114 SpectraReader
1115 parameters = {
1116 'path': global_type_string,
1117 'startDate': global_type_string,
1118 'endDate': global_type_string,
1119 'startTime': global_type_string,
1120 'endTime': global_type_string,
1121 'set': global_type_string,
1122 'expLabel': global_type_string,
1123 'ext': global_type_string,
1124 'online': global_type_string,
1125 'delay': global_type_string,
1126 'walk': global_type_string,
1127 'getblock': global_type_string,
1128 'nTxs': global_type_string,
1129 'realtime': global_type_boolean,
1130 'blocksize': global_type_string,
1131 'blocktime': global_type_string,
1132 'queue': global_type_string,
1133 'skip': global_type_string,
1134 'cursor': global_type_string,
1135 'warnings': global_type_string,
1136 'verbose': global_type_string,
1137 }
1138
1139
1140 USRPReader
1141 parameters = {
1142 : global_type_string,
1143 }
1144
1145
1146 VoltageProc
1147 parameters = {
1148 : global_type_string,
1149 }
1150
1151
1152 VoltageReader
1153 parameters = {
1154 'path': global_type_string,
1155 'startDate': global_type_string,
1156 'endDate': global_type_string,
1157 'startTime': global_type_string,
1158 'endTime': global_type_string,
1159 'set': global_type_string,
1160 'expLabel': global_type_string,
1161 'ext': global_type_string,
1162 'online': global_type_string,
1163 'delay': global_type_string,
1164 'walk': global_type_string,
1165 'getblock': global_type_string,
1166 'nTxs': global_type_string,
1167 'realtime': global_type_boolean,
1168 'blocksize': global_type_string,
1169 'blocktime': global_type_string,
1170 'queue': global_type_string,
1171 'skip': global_type_string,
1172 'cursor': global_type_string,
1173 'warnings': global_type_string,
1174 'verbose': global_type_string,
1175 }
1176
1177
@@ -0,0 +1,81
1 import schainpy
2 from schainpy.model import Operation, ProcessingUnit
3 from importlib import import_module
4 from pydoc import locate
5
6 def clean_modules(module):
7 noEndsUnder = [x for x in module if not x.endswith('__')]
8 noStartUnder = [x for x in noEndsUnder if not x.startswith('__')]
9 noFullUpper = [x for x in noStartUnder if not x.isupper()]
10 return noFullUpper
11
12 def check_module(possible, instance):
13 def check(x):
14 try:
15 instancia = locate('schainpy.model.{}'.format(x))
16 return isinstance(instancia(), instance)
17 except Exception as e:
18 return False
19 clean = clean_modules(possible)
20 return [x for x in clean if check(x)]
21
22
23 def getProcs():
24 module = dir(import_module('schainpy.model'))
25 procs = check_module(module, ProcessingUnit)
26 try:
27 procs.remove('ProcessingUnit')
28 except Exception as e:
29 pass
30 return procs
31
32 def getOperations():
33 module = dir(import_module('schainpy.model'))
34 noProcs = [x for x in module if not x.endswith('Proc')]
35 operations = check_module(noProcs, Operation)
36 try:
37 operations.remove('Operation')
38 except Exception as e:
39 pass
40 return operations
41
42 def getArgs(op):
43 module = locate('schainpy.model.{}'.format(op))
44 args = module().getAllowedArgs()
45 try:
46 args.remove('self')
47 except Exception as e:
48 pass
49 try:
50 args.remove('dataOut')
51 except Exception as e:
52 pass
53 return args
54
55 def getAll():
56 allModules = dir(import_module('schainpy.model'))
57 modules = check_module(allModules, Operation)
58 modules.extend(check_module(allModules, ProcessingUnit))
59 return modules
60
61 def formatArgs(op):
62 args = getArgs(op)
63
64 argsAsKey = ["\t'{}'".format(x) for x in args]
65 argsFormatted = ": 'string',\n".join(argsAsKey)
66
67 print op
68 print "parameters = { \n" + argsFormatted + ": 'string',\n }"
69 print '\n'
70
71
72 if __name__ == "__main__":
73 getAll()
74 [formatArgs(x) for x in getAll()]
75
76 '''
77 parameters = {
78 'id': ,
79 'wintitle': ,
80 }
81 ''' No newline at end of file
@@ -0,0 +1,1
1 You should install "digital_rf_hdf5" module if you want to read USRP data
@@ -1,188 +1,167
1 1 import click
2 2 import schainpy
3 3 import subprocess
4 4 import os
5 5 import sys
6 6 import glob
7 7 save_stdout = sys.stdout
8 8 sys.stdout = open('trash', 'w')
9 9 from multiprocessing import cpu_count
10 10 from schaincli import templates
11 11 from schainpy import controller_api
12 12 from schainpy.model import Operation, ProcessingUnit
13 13 from schainpy.utils import log
14 14 from importlib import import_module
15 15 from pydoc import locate
16 16 from fuzzywuzzy import process
17 from schainpy.utils import paramsFinder
17 18 sys.stdout = save_stdout
18 19
19 20
20 21 def print_version(ctx, param, value):
21 22 if not value or ctx.resilient_parsing:
22 23 return
23 24 click.echo(schainpy.__version__)
24 25 ctx.exit()
25 26
26 27
27 28 cliLogger = log.makelogger('schain cli')
28 29 PREFIX = 'experiment'
29 30
30 31
31 32 @click.command()
32 33 @click.option('--version', '-v', is_flag=True, callback=print_version, help='SChain version', type=str)
33 34 @click.option('--xml', '-x', default=None, help='run an XML file', type=click.Path(exists=True, resolve_path=True))
34 35 @click.argument('command', default='run', required=True)
35 36 @click.argument('nextcommand', default=None, required=False, type=str)
36 37 def main(command, nextcommand, version, xml):
37 38 """COMMAND LINE INTERFACE FOR SIGNAL CHAIN - JICAMARCA RADIO OBSERVATORY \n
38 39 Available commands.\n
39 40 --xml: runs a schain XML generated file\n
40 41 run: runs any python script starting 'experiment_'\n
41 42 generate: generates a template schain script\n
42 43 search: return avilable operations, procs or arguments of the give operation/proc\n"""
43 44 if xml is not None:
44 45 runFromXML(xml)
45 46 elif command == 'generate':
46 47 generate()
47 48 elif command == 'test':
48 49 test()
49 50 elif command == 'run':
50 51 runschain(nextcommand)
51 52 elif command == 'search':
52 53 search(nextcommand)
53 54 else:
54 55 log.error('Command {} is not defined'.format(command))
55 56
56 57 def check_module(possible, instance):
57 58 def check(x):
58 59 try:
59 60 instancia = locate('schainpy.model.{}'.format(x))
60 61 return isinstance(instancia(), instance)
61 62 except Exception as e:
62 63 return False
63 64 clean = clean_modules(possible)
64 65 return [x for x in clean if check(x)]
65 66
66 67
67 68 def clean_modules(module):
68 69 noEndsUnder = [x for x in module if not x.endswith('__')]
69 70 noStartUnder = [x for x in noEndsUnder if not x.startswith('__')]
70 71 noFullUpper = [x for x in noStartUnder if not x.isupper()]
71 72 return noFullUpper
72 73
73 74
74 75 def search(nextcommand):
75 76 if nextcommand is None:
76 77 log.error('There is no Operation/ProcessingUnit to search')
77 78 elif nextcommand == 'procs':
78 module = dir(import_module('schainpy.model'))
79 procs = check_module(module, ProcessingUnit)
80 try:
81 procs.remove('ProcessingUnit')
82 except Exception as e:
83 pass
79 procs = paramsFinder.getProcs()
84 80 log.success('Current ProcessingUnits are:\n\033[1m{}\033[0m'.format('\n'.join(procs)))
85 81
86 82 elif nextcommand == 'operations':
87 module = dir(import_module('schainpy.model'))
88 noProcs = [x for x in module if not x.endswith('Proc')]
89 operations = check_module(noProcs, Operation)
90 try:
91 operations.remove('Operation')
92 except Exception as e:
93 pass
83 operations = paramsFinder.getOperations()
94 84 log.success('Current Operations are:\n\033[1m{}\033[0m'.format('\n'.join(operations)))
95 85 else:
96 86 try:
97 module = locate('schainpy.model.{}'.format(nextcommand))
98 args = module().getAllowedArgs()
87 args = paramsFinder.getArgs(nextcommand)
99 88 log.warning('Use this feature with caution. It may not return all the allowed arguments')
100 try:
101 args.remove('self')
102 except Exception as e:
103 pass
104 try:
105 args.remove('dataOut')
106 except Exception as e:
107 pass
108 89 if len(args) == 0:
109 90 log.success('{} has no arguments'.format(nextcommand))
110 91 else:
111 92 log.success('Showing arguments of {} are:\n\033[1m{}\033[0m'.format(nextcommand, '\n'.join(args)))
112 93 except Exception as e:
113 94 log.error('Module {} does not exists'.format(nextcommand))
114 allModules = dir(import_module('schainpy.model'))
115 module = check_module(allModules, Operation)
116 module.extend(check_module(allModules, ProcessingUnit))
117 similar = process.extractOne(nextcommand, module)[0]
118 log.success('Searching {} instead'.format(similar))
95 allModules = paramsFinder.getAll()
96 similar = process.extractOne(nextcommand, allModules)[0]
97 log.success('Showing {} instead'.format(similar))
119 98 search(similar)
120 99
121 100
122 101 def runschain(nextcommand):
123 102 if nextcommand is None:
124 103 currentfiles = glob.glob('./{}_*.py'.format(PREFIX))
125 104 numberfiles = len(currentfiles)
126 105 if numberfiles > 1:
127 106 log.error('There is more than one file to run')
128 107 elif numberfiles == 1:
129 108 subprocess.call(['python ' + currentfiles[0]], shell=True)
130 109 else:
131 110 log.error('There is no file to run')
132 111 else:
133 112 try:
134 113 subprocess.call(['python ' + nextcommand], shell=True)
135 114 except Exception as e:
136 115 log.error("I cannot run the file. Does it exists?")
137 116
138 117
139 118 def basicInputs():
140 119 inputs = {}
141 120 inputs['desc'] = click.prompt('Enter a description', default="A schain project", type=str)
142 121 inputs['name'] = click.prompt('Name of the project', default="project", type=str)
143 122 inputs['path'] = click.prompt('Data path', default=os.getcwd(), type=click.Path(exists=True, resolve_path=True))
144 123 inputs['startDate'] = click.prompt('Start date', default='1970/01/01', type=str)
145 124 inputs['endDate'] = click.prompt('End date', default='2017/12/31', type=str)
146 125 inputs['startHour'] = click.prompt('Start hour', default='00:00:00', type=str)
147 126 inputs['endHour'] = click.prompt('End hour', default='23:59:59', type=str)
148 127 inputs['figpath'] = inputs['path'] + '/figs'
149 128 return inputs
150 129
151 130
152 131 def generate():
153 132 inputs = basicInputs()
154 133 inputs['multiprocess'] = click.confirm('Is this a multiprocess script?')
155 134 if inputs['multiprocess']:
156 135 inputs['nProcess'] = click.prompt('How many process?', default=cpu_count(), type=int)
157 136 current = templates.multiprocess.format(**inputs)
158 137 else:
159 138 current = templates.basic.format(**inputs)
160 139 scriptname = '{}_{}.py'.format(PREFIX, inputs['name'])
161 140 script = open(scriptname, 'w')
162 141 try:
163 142 script.write(current)
164 143 log.success('Script {} generated'.format(scriptname))
165 144 except Exception as e:
166 145 log.error('I cannot create the file. Do you have writing permissions?')
167 146
168 147
169 148 def test():
170 149 log.warning('testing')
171 150
172 151
173 152 def runFromXML(filename):
174 153 controller = controller_api.ControllerThread()
175 154 if not controller.readXml(filename):
176 155 return
177 156
178 157 plotterObj = controller.useExternalPlotter()
179 158
180 159 controller.start()
181 160 plotterObj.start()
182 161
183 162 cliLogger("Finishing all processes")
184 163
185 164 controller.join(5)
186 165
187 166 cliLogger("End of script")
188 167 return
@@ -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,2177
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
608 parameters = {
609 'id': global_type_string,
610 'wintitle': global_type_string,
611 'channelList': global_type_list,
612 'paramIndex': global_type_integer,
613 'colormap': global_type_colormap,
614 'xmin': global_type_float,
615 'xmax': global_type_float,
616 'ymin': global_type_float,
617 'ymax': global_type_float,
618 'zmin': global_type_float,
619 'zmax': global_type_float,
620 'timerange': global_type_float,
621 'showSNR': global_type_boolean,
622 'SNRthresh': global_type_float,
623 'SNRmin': global_type_float,
624 'SNRmax': global_type_float,
625 'save': global_type_boolean,
626 'figpath': global_type_string,
627 'lastone': global_type_integer,
628 'figfile': global_type_string,
629 'ftp': global_type_boolean,
630 'wr_period': global_type_integer,
631 'show': global_type_boolean,
632 'server': global_type_string,
633 'folder': global_type_string,
634 'username': global_type_string,
635 'password': global_type_string,
636 'ftp_wei': global_type_integer,
637 'exp_code': global_type_integer,
638 'sub_exp_code': global_type_integer,
639 'plot_pos': global_type_integer,
640 }
641
580 642 def __init__(self, **kwargs):
581 643 Figure.__init__(self, **kwargs)
582 644 self.timerange = None
583 645 self.isConfig = False
584 646 self.__nsubplots = 1
585 647
586 648 self.WIDTH = 800
587 649 self.HEIGHT = 180
588 650 self.WIDTHPROF = 120
589 651 self.HEIGHTPROF = 0
590 652 self.counter_imagwr = 0
591 653
592 654 self.PLOT_CODE = RTI_CODE
593 655
594 656 self.FTP_WEI = None
595 657 self.EXP_CODE = None
596 658 self.SUB_EXP_CODE = None
597 659 self.PLOT_POS = None
598 660 self.tmin = None
599 661 self.tmax = None
600 662
601 663 self.xmin = None
602 664 self.xmax = None
603 665
604 666 self.figfile = None
605 667
606 668 def getSubplots(self):
607 669
608 670 ncol = 1
609 671 nrow = self.nplots
610 672
611 673 return nrow, ncol
612 674
613 675 def setup(self, id, nplots, wintitle, show=True):
614 676
615 677 self.nplots = nplots
616 678
617 679 ncolspan = 1
618 680 colspan = 1
619 681
620 682 self.createFigure(id = id,
621 683 wintitle = wintitle,
622 684 widthplot = self.WIDTH + self.WIDTHPROF,
623 685 heightplot = self.HEIGHT + self.HEIGHTPROF,
624 686 show=show)
625 687
626 688 nrow, ncol = self.getSubplots()
627 689
628 690 counter = 0
629 691 for y in range(nrow):
630 692 for x in range(ncol):
631 693
632 694 if counter >= self.nplots:
633 695 break
634 696
635 697 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
636 698
637 699 counter += 1
638 700
639 701 def run(self, dataOut, id, wintitle="", channelList=None, paramIndex = 0, colormap=True,
640 702 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None, timerange=None,
641 703 showSNR=False, SNRthresh = -numpy.inf, SNRmin=None, SNRmax=None,
642 704 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
643 705 server=None, folder=None, username=None, password=None,
644 706 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
645 707 """
646 708
647 709 Input:
648 710 dataOut :
649 711 id :
650 712 wintitle :
651 713 channelList :
652 714 showProfile :
653 715 xmin : None,
654 716 xmax : None,
655 717 ymin : None,
656 718 ymax : None,
657 719 zmin : None,
658 720 zmax : None
659 721 """
660 722
661 723 if colormap:
662 724 colormap="jet"
663 725 else:
664 726 colormap="RdBu_r"
665 727
666 728 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
667 729 return
668 730
669 731 if channelList == None:
670 732 channelIndexList = range(dataOut.data_param.shape[0])
671 733 else:
672 734 channelIndexList = []
673 735 for channel in channelList:
674 736 if channel not in dataOut.channelList:
675 737 raise ValueError, "Channel %d is not in dataOut.channelList"
676 738 channelIndexList.append(dataOut.channelList.index(channel))
677 739
678 740 x = dataOut.getTimeRange1(dataOut.paramInterval)
679 741 y = dataOut.getHeiRange()
680 742
681 743 if dataOut.data_param.ndim == 3:
682 744 z = dataOut.data_param[channelIndexList,paramIndex,:]
683 745 else:
684 746 z = dataOut.data_param[channelIndexList,:]
685 747
686 748 if showSNR:
687 749 #SNR data
688 750 SNRarray = dataOut.data_SNR[channelIndexList,:]
689 751 SNRdB = 10*numpy.log10(SNRarray)
690 752 ind = numpy.where(SNRdB < SNRthresh)
691 753 z[ind] = numpy.nan
692 754
693 755 thisDatetime = dataOut.datatime
694 756 # thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
695 757 title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
696 758 xlabel = ""
697 759 ylabel = "Range (Km)"
698 760
699 761 update_figfile = False
700 762
701 763 if not self.isConfig:
702 764
703 765 nchan = len(channelIndexList)
704 766 self.nchan = nchan
705 767 self.plotFact = 1
706 768 nplots = nchan
707 769
708 770 if showSNR:
709 771 nplots = nchan*2
710 772 self.plotFact = 2
711 773 if SNRmin == None: SNRmin = numpy.nanmin(SNRdB)
712 774 if SNRmax == None: SNRmax = numpy.nanmax(SNRdB)
713 775
714 776 self.setup(id=id,
715 777 nplots=nplots,
716 778 wintitle=wintitle,
717 779 show=show)
718 780
719 781 if timerange != None:
720 782 self.timerange = timerange
721 783
722 784 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
723 785
724 786 if ymin == None: ymin = numpy.nanmin(y)
725 787 if ymax == None: ymax = numpy.nanmax(y)
726 788 if zmin == None: zmin = numpy.nanmin(z)
727 789 if zmax == None: zmax = numpy.nanmax(z)
728 790
729 791 self.FTP_WEI = ftp_wei
730 792 self.EXP_CODE = exp_code
731 793 self.SUB_EXP_CODE = sub_exp_code
732 794 self.PLOT_POS = plot_pos
733 795
734 796 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
735 797 self.isConfig = True
736 798 self.figfile = figfile
737 799 update_figfile = True
738 800
739 801 self.setWinTitle(title)
740 802
741 803 for i in range(self.nchan):
742 804 index = channelIndexList[i]
743 805 title = "Channel %d: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
744 806 axes = self.axesList[i*self.plotFact]
745 807 z1 = z[i,:].reshape((1,-1))
746 808 axes.pcolorbuffer(x, y, z1,
747 809 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
748 810 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
749 811 ticksize=9, cblabel='', cbsize="1%",colormap=colormap)
750 812
751 813 if showSNR:
752 814 title = "Channel %d SNR: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
753 815 axes = self.axesList[i*self.plotFact + 1]
754 816 SNRdB1 = SNRdB[i,:].reshape((1,-1))
755 817 axes.pcolorbuffer(x, y, SNRdB1,
756 818 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
757 819 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
758 820 ticksize=9, cblabel='', cbsize="1%",colormap='jet')
759 821
760 822
761 823 self.draw()
762 824
763 825 if dataOut.ltctime >= self.xmax:
764 826 self.counter_imagwr = wr_period
765 827 self.isConfig = False
766 828 update_figfile = True
767 829
768 830 self.save(figpath=figpath,
769 831 figfile=figfile,
770 832 save=save,
771 833 ftp=ftp,
772 834 wr_period=wr_period,
773 835 thisDatetime=thisDatetime,
774 836 update_figfile=update_figfile)
775 837
776 838
777 839
778 840 class Parameters1Plot(Figure):
779 841
780 842 __isConfig = None
781 843 __nsubplots = None
782 844
783 845 WIDTHPROF = None
784 846 HEIGHTPROF = None
785 847 PREFIX = 'prm'
786 848
849 parameters = {
850 'id': global_type_string,
851 'wintitle': global_type_string,
852 'channelList': global_type_list,
853 'showprofile': global_type_boolean,
854 'xmin': global_type_float,
855 'xmax': global_type_float,
856 'ymin': global_type_float,
857 'ymax': global_type_float,
858 'zmin': global_type_float,
859 'zmax': global_type_float,
860 'timerange': global_type_float,
861 'parameterIndex': global_type_float,
862 'onlyPositive': global_type_boolean,
863 'SNRthresh': global_type_float,
864 'SNR': global_type_boolean,
865 'SNRmin': global_type_float,
866 'SNRmax': global_type_float,
867 'onlySNR': global_type_boolean,
868 'DOP': global_type_boolean,
869 'zlabel': global_type_string,
870 'parameterName': global_type_string,
871 'parameterObject': global_type_string,
872 'save': global_type_boolean,
873 'figpath': global_type_string,
874 'lastone': global_type_integer,
875 'figfile': global_type_string,
876 'ftp': global_type_boolean,
877 'wr_period': global_type_integer,
878 'show': global_type_string,
879 'server': global_type_string,
880 'folder': global_type_string,
881 'username': global_type_string,
882 'password': global_type_string,
883 'ftp_wei': global_type_integer,
884 'exp_code': global_type_integer,
885 'sub_exp_code': global_type_integer,
886 'plot_pos': global_type_integer,
887 }
888
787 889 def __init__(self, **kwargs):
788 890 Figure.__init__(self, **kwargs)
789 891 self.timerange = 2*60*60
790 892 self.isConfig = False
791 893 self.__nsubplots = 1
792 894
793 895 self.WIDTH = 800
794 896 self.HEIGHT = 180
795 897 self.WIDTHPROF = 120
796 898 self.HEIGHTPROF = 0
797 899 self.counter_imagwr = 0
798 900
799 901 self.PLOT_CODE = PARMS_CODE
800 902
801 903 self.FTP_WEI = None
802 904 self.EXP_CODE = None
803 905 self.SUB_EXP_CODE = None
804 906 self.PLOT_POS = None
805 907 self.tmin = None
806 908 self.tmax = None
807 909
808 910 self.xmin = None
809 911 self.xmax = None
810 912
811 913 self.figfile = None
812 914
813 915 def getSubplots(self):
814 916
815 917 ncol = 1
816 918 nrow = self.nplots
817 919
818 920 return nrow, ncol
819 921
820 922 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
821 923
822 924 self.__showprofile = showprofile
823 925 self.nplots = nplots
824 926
825 927 ncolspan = 1
826 928 colspan = 1
827 929
828 930 self.createFigure(id = id,
829 931 wintitle = wintitle,
830 932 widthplot = self.WIDTH + self.WIDTHPROF,
831 933 heightplot = self.HEIGHT + self.HEIGHTPROF,
832 934 show=show)
833 935
834 936 nrow, ncol = self.getSubplots()
835 937
836 938 counter = 0
837 939 for y in range(nrow):
838 940 for x in range(ncol):
839 941
840 942 if counter >= self.nplots:
841 943 break
842 944
843 945 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
844 946
845 947 if showprofile:
846 948 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
847 949
848 950 counter += 1
849 951
850 952 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False,
851 953 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,timerange=None,
852 954 parameterIndex = None, onlyPositive = False,
853 955 SNRthresh = -numpy.inf, SNR = True, SNRmin = None, SNRmax = None, onlySNR = False,
854 956 DOP = True,
855 957 zlabel = "", parameterName = "", parameterObject = "data_param",
856 958 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
857 959 server=None, folder=None, username=None, password=None,
858 960 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
859 961 #print inspect.getargspec(self.run).args
860 962 """
861 963
862 964 Input:
863 965 dataOut :
864 966 id :
865 967 wintitle :
866 968 channelList :
867 969 showProfile :
868 970 xmin : None,
869 971 xmax : None,
870 972 ymin : None,
871 973 ymax : None,
872 974 zmin : None,
873 975 zmax : None
874 976 """
875 977
876 978 data_param = getattr(dataOut, parameterObject)
877 979
878 980 if channelList == None:
879 981 channelIndexList = numpy.arange(data_param.shape[0])
880 982 else:
881 983 channelIndexList = numpy.array(channelList)
882 984
883 985 nchan = len(channelIndexList) #Number of channels being plotted
884 986
885 987 if nchan < 1:
886 988 return
887 989
888 990 nGraphsByChannel = 0
889 991
890 992 if SNR:
891 993 nGraphsByChannel += 1
892 994 if DOP:
893 995 nGraphsByChannel += 1
894 996
895 997 if nGraphsByChannel < 1:
896 998 return
897 999
898 1000 nplots = nGraphsByChannel*nchan
899 1001
900 1002 if timerange is not None:
901 1003 self.timerange = timerange
902 1004
903 1005 #tmin = None
904 1006 #tmax = None
905 1007 if parameterIndex == None:
906 1008 parameterIndex = 1
907 1009
908 1010 x = dataOut.getTimeRange1(dataOut.paramInterval)
909 1011 y = dataOut.heightList
910 1012 z = data_param[channelIndexList,parameterIndex,:].copy()
911 1013
912 1014 zRange = dataOut.abscissaList
913 1015 # nChannels = z.shape[0] #Number of wind dimensions estimated
914 1016 # thisDatetime = dataOut.datatime
915 1017
916 1018 if dataOut.data_SNR is not None:
917 1019 SNRarray = dataOut.data_SNR[channelIndexList,:]
918 1020 SNRdB = 10*numpy.log10(SNRarray)
919 1021 # SNRavgdB = 10*numpy.log10(SNRavg)
920 1022 ind = numpy.where(SNRdB < 10**(SNRthresh/10))
921 1023 z[ind] = numpy.nan
922 1024
923 1025 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
924 1026 title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
925 1027 xlabel = ""
926 1028 ylabel = "Range (Km)"
927 1029
928 1030 if (SNR and not onlySNR): nplots = 2*nplots
929 1031
930 1032 if onlyPositive:
931 1033 colormap = "jet"
932 1034 zmin = 0
933 1035 else: colormap = "RdBu_r"
934 1036
935 1037 if not self.isConfig:
936 1038
937 1039 self.setup(id=id,
938 1040 nplots=nplots,
939 1041 wintitle=wintitle,
940 1042 showprofile=showprofile,
941 1043 show=show)
942 1044
943 1045 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
944 1046
945 1047 if ymin == None: ymin = numpy.nanmin(y)
946 1048 if ymax == None: ymax = numpy.nanmax(y)
947 1049 if zmin == None: zmin = numpy.nanmin(zRange)
948 1050 if zmax == None: zmax = numpy.nanmax(zRange)
949 1051
950 1052 if SNR:
951 1053 if SNRmin == None: SNRmin = numpy.nanmin(SNRdB)
952 1054 if SNRmax == None: SNRmax = numpy.nanmax(SNRdB)
953 1055
954 1056 self.FTP_WEI = ftp_wei
955 1057 self.EXP_CODE = exp_code
956 1058 self.SUB_EXP_CODE = sub_exp_code
957 1059 self.PLOT_POS = plot_pos
958 1060
959 1061 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
960 1062 self.isConfig = True
961 1063 self.figfile = figfile
962 1064
963 1065 self.setWinTitle(title)
964 1066
965 1067 if ((self.xmax - x[1]) < (x[1]-x[0])):
966 1068 x[1] = self.xmax
967 1069
968 1070 for i in range(nchan):
969 1071
970 1072 if (SNR and not onlySNR): j = 2*i
971 1073 else: j = i
972 1074
973 1075 j = nGraphsByChannel*i
974 1076
975 1077 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
976 1078 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
977 1079
978 1080 if not onlySNR:
979 1081 axes = self.axesList[j*self.__nsubplots]
980 1082 z1 = z[i,:].reshape((1,-1))
981 1083 axes.pcolorbuffer(x, y, z1,
982 1084 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
983 1085 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
984 1086 ticksize=9, cblabel=zlabel, cbsize="1%")
985 1087
986 1088 if DOP:
987 1089 title = "%s Channel %d: %s" %(parameterName, channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
988 1090
989 1091 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
990 1092 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
991 1093 axes = self.axesList[j]
992 1094 z1 = z[i,:].reshape((1,-1))
993 1095 axes.pcolorbuffer(x, y, z1,
994 1096 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
995 1097 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap,
996 1098 ticksize=9, cblabel=zlabel, cbsize="1%")
997 1099
998 1100 if SNR:
999 1101 title = "Channel %d Signal Noise Ratio (SNR): %s" %(channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1000 1102 axes = self.axesList[(j)*self.__nsubplots]
1001 1103 if not onlySNR:
1002 1104 axes = self.axesList[(j + 1)*self.__nsubplots]
1003 1105
1004 1106 axes = self.axesList[(j + nGraphsByChannel-1)]
1005 1107
1006 1108 z1 = SNRdB[i,:].reshape((1,-1))
1007 1109 axes.pcolorbuffer(x, y, z1,
1008 1110 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1009 1111 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap="jet",
1010 1112 ticksize=9, cblabel=zlabel, cbsize="1%")
1011 1113
1012 1114
1013 1115
1014 1116 self.draw()
1015 1117
1016 1118 if x[1] >= self.axesList[0].xmax:
1017 1119 self.counter_imagwr = wr_period
1018 1120 self.isConfig = False
1019 1121 self.figfile = None
1020 1122
1021 1123 self.save(figpath=figpath,
1022 1124 figfile=figfile,
1023 1125 save=save,
1024 1126 ftp=ftp,
1025 1127 wr_period=wr_period,
1026 1128 thisDatetime=thisDatetime,
1027 1129 update_figfile=False)
1028 1130
1029 1131 class SpectralFittingPlot(Figure):
1030 1132
1031 1133 __isConfig = None
1032 1134 __nsubplots = None
1033 1135
1034 1136 WIDTHPROF = None
1035 1137 HEIGHTPROF = None
1036 1138 PREFIX = 'prm'
1037 1139
1038 1140
1039 1141 N = None
1040 1142 ippSeconds = None
1041 1143
1042 1144 def __init__(self, **kwargs):
1043 1145 Figure.__init__(self, **kwargs)
1044 1146 self.isConfig = False
1045 1147 self.__nsubplots = 1
1046 1148
1047 1149 self.PLOT_CODE = SPECFIT_CODE
1048 1150
1049 1151 self.WIDTH = 450
1050 1152 self.HEIGHT = 250
1051 1153 self.WIDTHPROF = 0
1052 1154 self.HEIGHTPROF = 0
1053 1155
1054 1156 def getSubplots(self):
1055 1157
1056 1158 ncol = int(numpy.sqrt(self.nplots)+0.9)
1057 1159 nrow = int(self.nplots*1./ncol + 0.9)
1058 1160
1059 1161 return nrow, ncol
1060 1162
1061 1163 def setup(self, id, nplots, wintitle, showprofile=False, show=True):
1062 1164
1063 1165 showprofile = False
1064 1166 self.__showprofile = showprofile
1065 1167 self.nplots = nplots
1066 1168
1067 1169 ncolspan = 5
1068 1170 colspan = 4
1069 1171 if showprofile:
1070 1172 ncolspan = 5
1071 1173 colspan = 4
1072 1174 self.__nsubplots = 2
1073 1175
1074 1176 self.createFigure(id = id,
1075 1177 wintitle = wintitle,
1076 1178 widthplot = self.WIDTH + self.WIDTHPROF,
1077 1179 heightplot = self.HEIGHT + self.HEIGHTPROF,
1078 1180 show=show)
1079 1181
1080 1182 nrow, ncol = self.getSubplots()
1081 1183
1082 1184 counter = 0
1083 1185 for y in range(nrow):
1084 1186 for x in range(ncol):
1085 1187
1086 1188 if counter >= self.nplots:
1087 1189 break
1088 1190
1089 1191 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1090 1192
1091 1193 if showprofile:
1092 1194 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
1093 1195
1094 1196 counter += 1
1095 1197
1096 1198 def run(self, dataOut, id, cutHeight=None, fit=False, wintitle="", channelList=None, showprofile=True,
1097 1199 xmin=None, xmax=None, ymin=None, ymax=None,
1098 1200 save=False, figpath='./', figfile=None, show=True):
1099 1201
1100 1202 """
1101 1203
1102 1204 Input:
1103 1205 dataOut :
1104 1206 id :
1105 1207 wintitle :
1106 1208 channelList :
1107 1209 showProfile :
1108 1210 xmin : None,
1109 1211 xmax : None,
1110 1212 zmin : None,
1111 1213 zmax : None
1112 1214 """
1113 1215
1114 1216 if cutHeight==None:
1115 1217 h=270
1116 1218 heightindex = numpy.abs(cutHeight - dataOut.heightList).argmin()
1117 1219 cutHeight = dataOut.heightList[heightindex]
1118 1220
1119 1221 factor = dataOut.normFactor
1120 1222 x = dataOut.abscissaList[:-1]
1121 1223 #y = dataOut.getHeiRange()
1122 1224
1123 1225 z = dataOut.data_pre[:,:,heightindex]/factor
1124 1226 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1125 1227 avg = numpy.average(z, axis=1)
1126 1228 listChannels = z.shape[0]
1127 1229
1128 1230 #Reconstruct Function
1129 1231 if fit==True:
1130 1232 groupArray = dataOut.groupList
1131 1233 listChannels = groupArray.reshape((groupArray.size))
1132 1234 listChannels.sort()
1133 1235 spcFitLine = numpy.zeros(z.shape)
1134 1236 constants = dataOut.constants
1135 1237
1136 1238 nGroups = groupArray.shape[0]
1137 1239 nChannels = groupArray.shape[1]
1138 1240 nProfiles = z.shape[1]
1139 1241
1140 1242 for f in range(nGroups):
1141 1243 groupChann = groupArray[f,:]
1142 1244 p = dataOut.data_param[f,:,heightindex]
1143 1245 # p = numpy.array([ 89.343967,0.14036615,0.17086219,18.89835291,1.58388365,1.55099167])
1144 1246 fitLineAux = dataOut.library.modelFunction(p, constants)*nProfiles
1145 1247 fitLineAux = fitLineAux.reshape((nChannels,nProfiles))
1146 1248 spcFitLine[groupChann,:] = fitLineAux
1147 1249 # spcFitLine = spcFitLine/factor
1148 1250
1149 1251 z = z[listChannels,:]
1150 1252 spcFitLine = spcFitLine[listChannels,:]
1151 1253 spcFitLinedB = 10*numpy.log10(spcFitLine)
1152 1254
1153 1255 zdB = 10*numpy.log10(z)
1154 1256 #thisDatetime = dataOut.datatime
1155 1257 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1156 1258 title = wintitle + " Doppler Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
1157 1259 xlabel = "Velocity (m/s)"
1158 1260 ylabel = "Spectrum"
1159 1261
1160 1262 if not self.isConfig:
1161 1263
1162 1264 nplots = listChannels.size
1163 1265
1164 1266 self.setup(id=id,
1165 1267 nplots=nplots,
1166 1268 wintitle=wintitle,
1167 1269 showprofile=showprofile,
1168 1270 show=show)
1169 1271
1170 1272 if xmin == None: xmin = numpy.nanmin(x)
1171 1273 if xmax == None: xmax = numpy.nanmax(x)
1172 1274 if ymin == None: ymin = numpy.nanmin(zdB)
1173 1275 if ymax == None: ymax = numpy.nanmax(zdB)+2
1174 1276
1175 1277 self.isConfig = True
1176 1278
1177 1279 self.setWinTitle(title)
1178 1280 for i in range(self.nplots):
1179 1281 # title = "Channel %d: %4.2fdB" %(dataOut.channelList[i]+1, noisedB[i])
1180 1282 title = "Height %4.1f km\nChannel %d:" %(cutHeight, listChannels[i])
1181 1283 axes = self.axesList[i*self.__nsubplots]
1182 1284 if fit == False:
1183 1285 axes.pline(x, zdB[i,:],
1184 1286 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1185 1287 xlabel=xlabel, ylabel=ylabel, title=title
1186 1288 )
1187 1289 if fit == True:
1188 1290 fitline=spcFitLinedB[i,:]
1189 1291 y=numpy.vstack([zdB[i,:],fitline] )
1190 1292 legendlabels=['Data','Fitting']
1191 1293 axes.pmultilineyaxis(x, y,
1192 1294 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1193 1295 xlabel=xlabel, ylabel=ylabel, title=title,
1194 1296 legendlabels=legendlabels, marker=None,
1195 1297 linestyle='solid', grid='both')
1196 1298
1197 1299 self.draw()
1198 1300
1199 1301 self.save(figpath=figpath,
1200 1302 figfile=figfile,
1201 1303 save=save,
1202 1304 ftp=ftp,
1203 1305 wr_period=wr_period,
1204 1306 thisDatetime=thisDatetime)
1205 1307
1206 1308
1207 1309 class EWDriftsPlot(Figure):
1208 1310
1209 1311 __isConfig = None
1210 1312 __nsubplots = None
1211 1313
1212 1314 WIDTHPROF = None
1213 1315 HEIGHTPROF = None
1214 1316 PREFIX = 'drift'
1215 1317
1318 parameters = {
1319 'id': global_type_string,
1320 'wintitle': global_type_string,
1321 'channelList': global_type_string,
1322 'xmin': global_type_float,
1323 'xmax': global_type_float,
1324 'ymin': global_type_float,
1325 'ymax': global_type_float,
1326 'zmin': global_type_float,
1327 'zmax': global_type_float,
1328 'zmaxVertfloat': global_type_float,
1329 'zminVertfloat': global_type_float,
1330 'zmaxZonafloat': global_type_float,
1331 'zminZonafloat': global_type_float,
1332 'timerange': global_type_float,
1333 'SNRthresh': global_type_float,
1334 'SNRmin': global_type_float,
1335 'SNRmax': global_type_float,
1336 'SNR_1': global_type_boolean,
1337 'save': global_type_boolean,
1338 'figpath': global_type_string,
1339 'lastone': global_type_float,
1340 'figfile': global_type_string,
1341 'ftp': global_type_string,
1342 'wr_period': global_type_integer,
1343 'show': global_type_string,
1344 'server': global_type_string,
1345 'folder': global_type_string,
1346 'username': global_type_string,
1347 'password': global_type_string,
1348 'ftp_wei': global_type_integer,
1349 'exp_code': global_type_integer,
1350 'sub_exp_code': global_type_integer,
1351 'plot_pos': global_type_integer,
1352 }
1353
1216 1354 def __init__(self, **kwargs):
1217 1355 Figure.__init__(self, **kwargs)
1218 1356 self.timerange = 2*60*60
1219 1357 self.isConfig = False
1220 1358 self.__nsubplots = 1
1221 1359
1222 1360 self.WIDTH = 800
1223 1361 self.HEIGHT = 150
1224 1362 self.WIDTHPROF = 120
1225 1363 self.HEIGHTPROF = 0
1226 1364 self.counter_imagwr = 0
1227 1365
1228 1366 self.PLOT_CODE = EWDRIFT_CODE
1229 1367
1230 1368 self.FTP_WEI = None
1231 1369 self.EXP_CODE = None
1232 1370 self.SUB_EXP_CODE = None
1233 1371 self.PLOT_POS = None
1234 1372 self.tmin = None
1235 1373 self.tmax = None
1236 1374
1237 1375 self.xmin = None
1238 1376 self.xmax = None
1239 1377
1240 1378 self.figfile = None
1241 1379
1242 1380 def getSubplots(self):
1243 1381
1244 1382 ncol = 1
1245 1383 nrow = self.nplots
1246 1384
1247 1385 return nrow, ncol
1248 1386
1249 1387 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1250 1388
1251 1389 self.__showprofile = showprofile
1252 1390 self.nplots = nplots
1253 1391
1254 1392 ncolspan = 1
1255 1393 colspan = 1
1256 1394
1257 1395 self.createFigure(id = id,
1258 1396 wintitle = wintitle,
1259 1397 widthplot = self.WIDTH + self.WIDTHPROF,
1260 1398 heightplot = self.HEIGHT + self.HEIGHTPROF,
1261 1399 show=show)
1262 1400
1263 1401 nrow, ncol = self.getSubplots()
1264 1402
1265 1403 counter = 0
1266 1404 for y in range(nrow):
1267 1405 if counter >= self.nplots:
1268 1406 break
1269 1407
1270 1408 self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1)
1271 1409 counter += 1
1272 1410
1273 1411 def run(self, dataOut, id, wintitle="", channelList=None,
1274 1412 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
1275 1413 zmaxVertical = None, zminVertical = None, zmaxZonal = None, zminZonal = None,
1276 1414 timerange=None, SNRthresh = -numpy.inf, SNRmin = None, SNRmax = None, SNR_1 = False,
1277 1415 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
1278 1416 server=None, folder=None, username=None, password=None,
1279 1417 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1280 1418 """
1281 1419
1282 1420 Input:
1283 1421 dataOut :
1284 1422 id :
1285 1423 wintitle :
1286 1424 channelList :
1287 1425 showProfile :
1288 1426 xmin : None,
1289 1427 xmax : None,
1290 1428 ymin : None,
1291 1429 ymax : None,
1292 1430 zmin : None,
1293 1431 zmax : None
1294 1432 """
1295 1433
1296 1434 if timerange is not None:
1297 1435 self.timerange = timerange
1298 1436
1299 1437 tmin = None
1300 1438 tmax = None
1301 1439
1302 1440 x = dataOut.getTimeRange1(dataOut.outputInterval)
1303 1441 # y = dataOut.heightList
1304 1442 y = dataOut.heightList
1305 1443
1306 1444 z = dataOut.data_output
1307 1445 nplots = z.shape[0] #Number of wind dimensions estimated
1308 1446 nplotsw = nplots
1309 1447
1310 1448 #If there is a SNR function defined
1311 1449 if dataOut.data_SNR is not None:
1312 1450 nplots += 1
1313 1451 SNR = dataOut.data_SNR
1314 1452
1315 1453 if SNR_1:
1316 1454 SNR += 1
1317 1455
1318 1456 SNRavg = numpy.average(SNR, axis=0)
1319 1457
1320 1458 SNRdB = 10*numpy.log10(SNR)
1321 1459 SNRavgdB = 10*numpy.log10(SNRavg)
1322 1460
1323 1461 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0]
1324 1462
1325 1463 for i in range(nplotsw):
1326 1464 z[i,ind] = numpy.nan
1327 1465
1328 1466
1329 1467 showprofile = False
1330 1468 # thisDatetime = dataOut.datatime
1331 1469 thisDatetime = datetime.datetime.utcfromtimestamp(x[1])
1332 1470 title = wintitle + " EW Drifts"
1333 1471 xlabel = ""
1334 1472 ylabel = "Height (Km)"
1335 1473
1336 1474 if not self.isConfig:
1337 1475
1338 1476 self.setup(id=id,
1339 1477 nplots=nplots,
1340 1478 wintitle=wintitle,
1341 1479 showprofile=showprofile,
1342 1480 show=show)
1343 1481
1344 1482 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1345 1483
1346 1484 if ymin == None: ymin = numpy.nanmin(y)
1347 1485 if ymax == None: ymax = numpy.nanmax(y)
1348 1486
1349 1487 if zmaxZonal == None: zmaxZonal = numpy.nanmax(abs(z[0,:]))
1350 1488 if zminZonal == None: zminZonal = -zmaxZonal
1351 1489 if zmaxVertical == None: zmaxVertical = numpy.nanmax(abs(z[1,:]))
1352 1490 if zminVertical == None: zminVertical = -zmaxVertical
1353 1491
1354 1492 if dataOut.data_SNR is not None:
1355 1493 if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB)
1356 1494 if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB)
1357 1495
1358 1496 self.FTP_WEI = ftp_wei
1359 1497 self.EXP_CODE = exp_code
1360 1498 self.SUB_EXP_CODE = sub_exp_code
1361 1499 self.PLOT_POS = plot_pos
1362 1500
1363 1501 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1364 1502 self.isConfig = True
1365 1503
1366 1504
1367 1505 self.setWinTitle(title)
1368 1506
1369 1507 if ((self.xmax - x[1]) < (x[1]-x[0])):
1370 1508 x[1] = self.xmax
1371 1509
1372 1510 strWind = ['Zonal','Vertical']
1373 1511 strCb = 'Velocity (m/s)'
1374 1512 zmaxVector = [zmaxZonal, zmaxVertical]
1375 1513 zminVector = [zminZonal, zminVertical]
1376 1514
1377 1515 for i in range(nplotsw):
1378 1516
1379 1517 title = "%s Drifts: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1380 1518 axes = self.axesList[i*self.__nsubplots]
1381 1519
1382 1520 z1 = z[i,:].reshape((1,-1))
1383 1521
1384 1522 axes.pcolorbuffer(x, y, z1,
1385 1523 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i],
1386 1524 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1387 1525 ticksize=9, cblabel=strCb, cbsize="1%", colormap="RdBu_r")
1388 1526
1389 1527 if dataOut.data_SNR is not None:
1390 1528 i += 1
1391 1529 if SNR_1:
1392 1530 title = "Signal Noise Ratio + 1 (SNR+1): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1393 1531 else:
1394 1532 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1395 1533 axes = self.axesList[i*self.__nsubplots]
1396 1534 SNRavgdB = SNRavgdB.reshape((1,-1))
1397 1535
1398 1536 axes.pcolorbuffer(x, y, SNRavgdB,
1399 1537 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax,
1400 1538 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
1401 1539 ticksize=9, cblabel='', cbsize="1%", colormap="jet")
1402 1540
1403 1541 self.draw()
1404 1542
1405 1543 if x[1] >= self.axesList[0].xmax:
1406 1544 self.counter_imagwr = wr_period
1407 1545 self.isConfig = False
1408 1546 self.figfile = None
1409 1547
1410 1548
1411 1549
1412 1550
1413 1551 class PhasePlot(Figure):
1414 1552
1415 1553 __isConfig = None
1416 1554 __nsubplots = None
1417 1555
1418 1556 PREFIX = 'mphase'
1419 1557
1558 parameters = {
1559 'id': global_type_string,
1560 'wintitle': global_type_string,
1561 'pairsList': global_type_pairsList,
1562 'showprofile': global_type_boolean,
1563 'xmin': global_type_float,
1564 'xmax': global_type_float,
1565 'ymin': global_type_float,
1566 'ymax': global_type_float,
1567 'timerange': global_type_float,
1568 'save': global_type_boolean,
1569 'figpath': global_type_string,
1570 'figfile': global_type_string,
1571 'show': global_type_boolean,
1572 'ftp': global_type_boolean,
1573 'wr_period': global_type_integer,
1574 'server': global_type_string,
1575 'folder': global_type_string,
1576 'username': global_type_string,
1577 'password': global_type_string,
1578 'ftp_wei': global_type_integer,
1579 'exp_code': global_type_integer,
1580 'sub_exp_code': global_type_integer,
1581 'plot_pos': global_type_integer,
1582 }
1583
1420 1584 def __init__(self, **kwargs):
1421 1585 Figure.__init__(self, **kwargs)
1422 1586 self.timerange = 24*60*60
1423 1587 self.isConfig = False
1424 1588 self.__nsubplots = 1
1425 1589 self.counter_imagwr = 0
1426 1590 self.WIDTH = 600
1427 1591 self.HEIGHT = 300
1428 1592 self.WIDTHPROF = 120
1429 1593 self.HEIGHTPROF = 0
1430 1594 self.xdata = None
1431 1595 self.ydata = None
1432 1596
1433 1597 self.PLOT_CODE = MPHASE_CODE
1434 1598
1435 1599 self.FTP_WEI = None
1436 1600 self.EXP_CODE = None
1437 1601 self.SUB_EXP_CODE = None
1438 1602 self.PLOT_POS = None
1439 1603
1440 1604
1441 1605 self.filename_phase = None
1442 1606
1443 1607 self.figfile = None
1444 1608
1445 1609 def getSubplots(self):
1446 1610
1447 1611 ncol = 1
1448 1612 nrow = 1
1449 1613
1450 1614 return nrow, ncol
1451 1615
1452 1616 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1453 1617
1454 1618 self.__showprofile = showprofile
1455 1619 self.nplots = nplots
1456 1620
1457 1621 ncolspan = 7
1458 1622 colspan = 6
1459 1623 self.__nsubplots = 2
1460 1624
1461 1625 self.createFigure(id = id,
1462 1626 wintitle = wintitle,
1463 1627 widthplot = self.WIDTH+self.WIDTHPROF,
1464 1628 heightplot = self.HEIGHT+self.HEIGHTPROF,
1465 1629 show=show)
1466 1630
1467 1631 nrow, ncol = self.getSubplots()
1468 1632
1469 1633 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1470 1634
1471 1635
1472 1636 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1473 1637 xmin=None, xmax=None, ymin=None, ymax=None,
1474 1638 timerange=None,
1475 1639 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1476 1640 server=None, folder=None, username=None, password=None,
1477 1641 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1478 1642
1479 1643
1480 1644 tmin = None
1481 1645 tmax = None
1482 1646 x = dataOut.getTimeRange1(dataOut.outputInterval)
1483 1647 y = dataOut.getHeiRange()
1484 1648
1485 1649
1486 1650 #thisDatetime = dataOut.datatime
1487 1651 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
1488 1652 title = wintitle + " Phase of Beacon Signal" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1489 1653 xlabel = "Local Time"
1490 1654 ylabel = "Phase"
1491 1655
1492 1656
1493 1657 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1494 1658 phase_beacon = dataOut.data_output
1495 1659 update_figfile = False
1496 1660
1497 1661 if not self.isConfig:
1498 1662
1499 1663 self.nplots = phase_beacon.size
1500 1664
1501 1665 self.setup(id=id,
1502 1666 nplots=self.nplots,
1503 1667 wintitle=wintitle,
1504 1668 showprofile=showprofile,
1505 1669 show=show)
1506 1670
1507 1671 if timerange is not None:
1508 1672 self.timerange = timerange
1509 1673
1510 1674 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1511 1675
1512 1676 if ymin == None: ymin = numpy.nanmin(phase_beacon) - 10.0
1513 1677 if ymax == None: ymax = numpy.nanmax(phase_beacon) + 10.0
1514 1678
1515 1679 self.FTP_WEI = ftp_wei
1516 1680 self.EXP_CODE = exp_code
1517 1681 self.SUB_EXP_CODE = sub_exp_code
1518 1682 self.PLOT_POS = plot_pos
1519 1683
1520 1684 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1521 1685 self.isConfig = True
1522 1686 self.figfile = figfile
1523 1687 self.xdata = numpy.array([])
1524 1688 self.ydata = numpy.array([])
1525 1689
1526 1690 #open file beacon phase
1527 1691 path = '%s%03d' %(self.PREFIX, self.id)
1528 1692 beacon_file = os.path.join(path,'%s.txt'%self.name)
1529 1693 self.filename_phase = os.path.join(figpath,beacon_file)
1530 1694 update_figfile = True
1531 1695
1532 1696
1533 1697 #store data beacon phase
1534 1698 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1535 1699
1536 1700 self.setWinTitle(title)
1537 1701
1538 1702
1539 1703 title = "Phase Offset %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1540 1704
1541 1705 legendlabels = ["phase %d"%(chan) for chan in numpy.arange(self.nplots)]
1542 1706
1543 1707 axes = self.axesList[0]
1544 1708
1545 1709 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1546 1710
1547 1711 if len(self.ydata)==0:
1548 1712 self.ydata = phase_beacon.reshape(-1,1)
1549 1713 else:
1550 1714 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1551 1715
1552 1716
1553 1717 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1554 1718 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1555 1719 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1556 1720 XAxisAsTime=True, grid='both'
1557 1721 )
1558 1722
1559 1723 self.draw()
1560 1724
1561 1725 self.save(figpath=figpath,
1562 1726 figfile=figfile,
1563 1727 save=save,
1564 1728 ftp=ftp,
1565 1729 wr_period=wr_period,
1566 1730 thisDatetime=thisDatetime,
1567 1731 update_figfile=update_figfile)
1568 1732
1569 1733 if dataOut.ltctime + dataOut.outputInterval >= self.xmax:
1570 1734 self.counter_imagwr = wr_period
1571 1735 self.isConfig = False
1572 1736 update_figfile = True
1573 1737
1574 1738
1575 1739
1576 1740 class NSMeteorDetection1Plot(Figure):
1577 1741
1578 1742 isConfig = None
1579 1743 __nsubplots = None
1580 1744
1581 1745 WIDTHPROF = None
1582 1746 HEIGHTPROF = None
1583 1747 PREFIX = 'nsm'
1584 1748
1585 1749 zminList = None
1586 1750 zmaxList = None
1587 1751 cmapList = None
1588 1752 titleList = None
1589 1753 nPairs = None
1590 1754 nChannels = None
1591 1755 nParam = None
1592 1756
1757 parameters = {
1758 'id': global_type_string,
1759 'wintitle': global_type_string,
1760 'channelList': global_type_list,
1761 'showprofile': global_type_boolean,
1762 'xmin': global_type_float,
1763 'xmax': global_type_float,
1764 'ymin': global_type_float,
1765 'ymax': global_type_float,
1766 'SNRmin': global_type_float,
1767 'SNRmax': global_type_float,
1768 'vmin': global_type_float,
1769 'vmax': global_type_float,
1770 'wmin': global_type_float,
1771 'wmax': global_type_float,
1772 'mode': global_type_string,
1773 'save': global_type_boolean,
1774 'figpath': global_type_string,
1775 'figfile': global_type_string,
1776 'show': global_type_boolean,
1777 'ftp': global_type_string,
1778 'wr_period': global_type_integer,
1779 'server': global_type_string,
1780 'folder': global_type_string,
1781 'username': global_type_string,
1782 'password': global_type_string,
1783 'ftp_wei': global_type_integer,
1784 'exp_code': global_type_integer,
1785 'sub_exp_code': global_type_integer,
1786 'plot_pos': global_type_integer,
1787 'realtime': global_type_boolean,
1788 'xaxis': global_type_string,
1789 }
1790
1593 1791 def __init__(self, **kwargs):
1594 1792 Figure.__init__(self, **kwargs)
1595 1793 self.isConfig = False
1596 1794 self.__nsubplots = 1
1597 1795
1598 1796 self.WIDTH = 750
1599 1797 self.HEIGHT = 250
1600 1798 self.WIDTHPROF = 120
1601 1799 self.HEIGHTPROF = 0
1602 1800 self.counter_imagwr = 0
1603 1801
1604 1802 self.PLOT_CODE = SPEC_CODE
1605 1803
1606 1804 self.FTP_WEI = None
1607 1805 self.EXP_CODE = None
1608 1806 self.SUB_EXP_CODE = None
1609 1807 self.PLOT_POS = None
1610 1808
1611 1809 self.__xfilter_ena = False
1612 1810 self.__yfilter_ena = False
1613 1811
1614 1812 def getSubplots(self):
1615 1813
1616 1814 ncol = 3
1617 1815 nrow = int(numpy.ceil(self.nplots/3.0))
1618 1816
1619 1817 return nrow, ncol
1620 1818
1621 1819 def setup(self, id, nplots, wintitle, show=True):
1622 1820
1623 1821 self.nplots = nplots
1624 1822
1625 1823 ncolspan = 1
1626 1824 colspan = 1
1627 1825
1628 1826 self.createFigure(id = id,
1629 1827 wintitle = wintitle,
1630 1828 widthplot = self.WIDTH + self.WIDTHPROF,
1631 1829 heightplot = self.HEIGHT + self.HEIGHTPROF,
1632 1830 show=show)
1633 1831
1634 1832 nrow, ncol = self.getSubplots()
1635 1833
1636 1834 counter = 0
1637 1835 for y in range(nrow):
1638 1836 for x in range(ncol):
1639 1837
1640 1838 if counter >= self.nplots:
1641 1839 break
1642 1840
1643 1841 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1644 1842
1645 1843 counter += 1
1646 1844
1647 1845 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
1648 1846 xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None,
1649 1847 vmin=None, vmax=None, wmin=None, wmax=None, mode = 'SA',
1650 1848 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1651 1849 server=None, folder=None, username=None, password=None,
1652 1850 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
1653 1851 xaxis="frequency"):
1654 1852
1655 1853 """
1656 1854
1657 1855 Input:
1658 1856 dataOut :
1659 1857 id :
1660 1858 wintitle :
1661 1859 channelList :
1662 1860 showProfile :
1663 1861 xmin : None,
1664 1862 xmax : None,
1665 1863 ymin : None,
1666 1864 ymax : None,
1667 1865 zmin : None,
1668 1866 zmax : None
1669 1867 """
1670 1868 #SEPARAR EN DOS PLOTS
1671 1869 nParam = dataOut.data_param.shape[1] - 3
1672 1870
1673 1871 utctime = dataOut.data_param[0,0]
1674 1872 tmet = dataOut.data_param[:,1].astype(int)
1675 1873 hmet = dataOut.data_param[:,2].astype(int)
1676 1874
1677 1875 x = dataOut.abscissaList
1678 1876 y = dataOut.heightList
1679 1877
1680 1878 z = numpy.zeros((nParam, y.size, x.size - 1))
1681 1879 z[:,:] = numpy.nan
1682 1880 z[:,hmet,tmet] = dataOut.data_param[:,3:].T
1683 1881 z[0,:,:] = 10*numpy.log10(z[0,:,:])
1684 1882
1685 1883 xlabel = "Time (s)"
1686 1884 ylabel = "Range (km)"
1687 1885
1688 1886 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
1689 1887
1690 1888 if not self.isConfig:
1691 1889
1692 1890 nplots = nParam
1693 1891
1694 1892 self.setup(id=id,
1695 1893 nplots=nplots,
1696 1894 wintitle=wintitle,
1697 1895 show=show)
1698 1896
1699 1897 if xmin is None: xmin = numpy.nanmin(x)
1700 1898 if xmax is None: xmax = numpy.nanmax(x)
1701 1899 if ymin is None: ymin = numpy.nanmin(y)
1702 1900 if ymax is None: ymax = numpy.nanmax(y)
1703 1901 if SNRmin is None: SNRmin = numpy.nanmin(z[0,:])
1704 1902 if SNRmax is None: SNRmax = numpy.nanmax(z[0,:])
1705 1903 if vmax is None: vmax = numpy.nanmax(numpy.abs(z[1,:]))
1706 1904 if vmin is None: vmin = -vmax
1707 1905 if wmin is None: wmin = 0
1708 1906 if wmax is None: wmax = 50
1709 1907
1710 1908 pairsList = dataOut.groupList
1711 1909 self.nPairs = len(dataOut.groupList)
1712 1910
1713 1911 zminList = [SNRmin, vmin, cmin] + [pmin]*self.nPairs
1714 1912 zmaxList = [SNRmax, vmax, cmax] + [pmax]*self.nPairs
1715 1913 titleList = ["SNR","Radial Velocity","Coherence"]
1716 1914 cmapList = ["jet","RdBu_r","jet"]
1717 1915
1718 1916 for i in range(self.nPairs):
1719 1917 strAux1 = "Phase Difference "+ str(pairsList[i][0]) + str(pairsList[i][1])
1720 1918 titleList = titleList + [strAux1]
1721 1919 cmapList = cmapList + ["RdBu_r"]
1722 1920
1723 1921 self.zminList = zminList
1724 1922 self.zmaxList = zmaxList
1725 1923 self.cmapList = cmapList
1726 1924 self.titleList = titleList
1727 1925
1728 1926 self.FTP_WEI = ftp_wei
1729 1927 self.EXP_CODE = exp_code
1730 1928 self.SUB_EXP_CODE = sub_exp_code
1731 1929 self.PLOT_POS = plot_pos
1732 1930
1733 1931 self.isConfig = True
1734 1932
1735 1933 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
1736 1934
1737 1935 for i in range(nParam):
1738 1936 title = self.titleList[i] + ": " +str_datetime
1739 1937 axes = self.axesList[i]
1740 1938 axes.pcolor(x, y, z[i,:].T,
1741 1939 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=self.zminList[i], zmax=self.zmaxList[i],
1742 1940 xlabel=xlabel, ylabel=ylabel, title=title, colormap=self.cmapList[i],ticksize=9, cblabel='')
1743 1941 self.draw()
1744 1942
1745 1943 if figfile == None:
1746 1944 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
1747 1945 name = str_datetime
1748 1946 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1749 1947 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
1750 1948 figfile = self.getFilename(name)
1751 1949
1752 1950 self.save(figpath=figpath,
1753 1951 figfile=figfile,
1754 1952 save=save,
1755 1953 ftp=ftp,
1756 1954 wr_period=wr_period,
1757 1955 thisDatetime=thisDatetime)
1758 1956
1759 1957
1760 1958 class NSMeteorDetection2Plot(Figure):
1761 1959
1762 1960 isConfig = None
1763 1961 __nsubplots = None
1764 1962
1765 1963 WIDTHPROF = None
1766 1964 HEIGHTPROF = None
1767 1965 PREFIX = 'nsm'
1768 1966
1769 1967 zminList = None
1770 1968 zmaxList = None
1771 1969 cmapList = None
1772 1970 titleList = None
1773 1971 nPairs = None
1774 1972 nChannels = None
1775 1973 nParam = None
1776 1974
1975 parameters = {
1976 'id': global_type_string,
1977 'wintitle': global_type_string,
1978 'channelList': global_type_list,
1979 'showprofile': global_type_boolean,
1980 'xmin': global_type_float,
1981 'xmax': global_type_float,
1982 'ymin': global_type_float,
1983 'ymax': global_type_float,
1984 'SNRmin': global_type_float,
1985 'SNRmax': global_type_float,
1986 'vmin': global_type_float,
1987 'vmax': global_type_float,
1988 'wmin': global_type_float,
1989 'wmax': global_type_float,
1990 'mode': global_type_string,
1991 'save': global_type_boolean,
1992 'figpath': global_type_string,
1993 'figfile': global_type_string,
1994 'show': global_type_string,
1995 'ftp': global_type_boolean,
1996 'wr_period': global_type_integer,
1997 'server': global_type_string,
1998 'folder': global_type_string,
1999 'username': global_type_string,
2000 'password': global_type_string,
2001 'ftp_wei': global_type_integer,
2002 'exp_code': global_type_integer,
2003 'sub_exp_code': global_type_integer,
2004 'plot_pos': global_type_integer,
2005 'realtime': global_type_boolean,
2006 'xaxis': global_type_string,
2007 }
2008
1777 2009 def __init__(self, **kwargs):
1778 2010 Figure.__init__(self, **kwargs)
1779 2011 self.isConfig = False
1780 2012 self.__nsubplots = 1
1781 2013
1782 2014 self.WIDTH = 750
1783 2015 self.HEIGHT = 250
1784 2016 self.WIDTHPROF = 120
1785 2017 self.HEIGHTPROF = 0
1786 2018 self.counter_imagwr = 0
1787 2019
1788 2020 self.PLOT_CODE = SPEC_CODE
1789 2021
1790 2022 self.FTP_WEI = None
1791 2023 self.EXP_CODE = None
1792 2024 self.SUB_EXP_CODE = None
1793 2025 self.PLOT_POS = None
1794 2026
1795 2027 self.__xfilter_ena = False
1796 2028 self.__yfilter_ena = False
1797 2029
1798 2030 def getSubplots(self):
1799 2031
1800 2032 ncol = 3
1801 2033 nrow = int(numpy.ceil(self.nplots/3.0))
1802 2034
1803 2035 return nrow, ncol
1804 2036
1805 2037 def setup(self, id, nplots, wintitle, show=True):
1806 2038
1807 2039 self.nplots = nplots
1808 2040
1809 2041 ncolspan = 1
1810 2042 colspan = 1
1811 2043
1812 2044 self.createFigure(id = id,
1813 2045 wintitle = wintitle,
1814 2046 widthplot = self.WIDTH + self.WIDTHPROF,
1815 2047 heightplot = self.HEIGHT + self.HEIGHTPROF,
1816 2048 show=show)
1817 2049
1818 2050 nrow, ncol = self.getSubplots()
1819 2051
1820 2052 counter = 0
1821 2053 for y in range(nrow):
1822 2054 for x in range(ncol):
1823 2055
1824 2056 if counter >= self.nplots:
1825 2057 break
1826 2058
1827 2059 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1828 2060
1829 2061 counter += 1
1830 2062
1831 2063 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
1832 2064 xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None,
1833 2065 vmin=None, vmax=None, wmin=None, wmax=None, mode = 'SA',
1834 2066 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1835 2067 server=None, folder=None, username=None, password=None,
1836 2068 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
1837 2069 xaxis="frequency"):
1838 2070
1839 2071 """
1840 2072
1841 2073 Input:
1842 2074 dataOut :
1843 2075 id :
1844 2076 wintitle :
1845 2077 channelList :
1846 2078 showProfile :
1847 2079 xmin : None,
1848 2080 xmax : None,
1849 2081 ymin : None,
1850 2082 ymax : None,
1851 2083 zmin : None,
1852 2084 zmax : None
1853 2085 """
1854 2086 #Rebuild matrix
1855 2087 utctime = dataOut.data_param[0,0]
1856 2088 cmet = dataOut.data_param[:,1].astype(int)
1857 2089 tmet = dataOut.data_param[:,2].astype(int)
1858 2090 hmet = dataOut.data_param[:,3].astype(int)
1859 2091
1860 2092 nParam = 3
1861 2093 nChan = len(dataOut.groupList)
1862 2094 x = dataOut.abscissaList
1863 2095 y = dataOut.heightList
1864 2096
1865 2097 z = numpy.full((nChan, nParam, y.size, x.size - 1),numpy.nan)
1866 2098 z[cmet,:,hmet,tmet] = dataOut.data_param[:,4:]
1867 2099 z[:,0,:,:] = 10*numpy.log10(z[:,0,:,:]) #logarithmic scale
1868 2100 z = numpy.reshape(z, (nChan*nParam, y.size, x.size-1))
1869 2101
1870 2102 xlabel = "Time (s)"
1871 2103 ylabel = "Range (km)"
1872 2104
1873 2105 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime)
1874 2106
1875 2107 if not self.isConfig:
1876 2108
1877 2109 nplots = nParam*nChan
1878 2110
1879 2111 self.setup(id=id,
1880 2112 nplots=nplots,
1881 2113 wintitle=wintitle,
1882 2114 show=show)
1883 2115
1884 2116 if xmin is None: xmin = numpy.nanmin(x)
1885 2117 if xmax is None: xmax = numpy.nanmax(x)
1886 2118 if ymin is None: ymin = numpy.nanmin(y)
1887 2119 if ymax is None: ymax = numpy.nanmax(y)
1888 2120 if SNRmin is None: SNRmin = numpy.nanmin(z[0,:])
1889 2121 if SNRmax is None: SNRmax = numpy.nanmax(z[0,:])
1890 2122 if vmax is None: vmax = numpy.nanmax(numpy.abs(z[1,:]))
1891 2123 if vmin is None: vmin = -vmax
1892 2124 if wmin is None: wmin = 0
1893 2125 if wmax is None: wmax = 50
1894 2126
1895 2127 self.nChannels = nChan
1896 2128
1897 2129 zminList = []
1898 2130 zmaxList = []
1899 2131 titleList = []
1900 2132 cmapList = []
1901 2133 for i in range(self.nChannels):
1902 2134 strAux1 = "SNR Channel "+ str(i)
1903 2135 strAux2 = "Radial Velocity Channel "+ str(i)
1904 2136 strAux3 = "Spectral Width Channel "+ str(i)
1905 2137
1906 2138 titleList = titleList + [strAux1,strAux2,strAux3]
1907 2139 cmapList = cmapList + ["jet","RdBu_r","jet"]
1908 2140 zminList = zminList + [SNRmin,vmin,wmin]
1909 2141 zmaxList = zmaxList + [SNRmax,vmax,wmax]
1910 2142
1911 2143 self.zminList = zminList
1912 2144 self.zmaxList = zmaxList
1913 2145 self.cmapList = cmapList
1914 2146 self.titleList = titleList
1915 2147
1916 2148 self.FTP_WEI = ftp_wei
1917 2149 self.EXP_CODE = exp_code
1918 2150 self.SUB_EXP_CODE = sub_exp_code
1919 2151 self.PLOT_POS = plot_pos
1920 2152
1921 2153 self.isConfig = True
1922 2154
1923 2155 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
1924 2156
1925 2157 for i in range(self.nplots):
1926 2158 title = self.titleList[i] + ": " +str_datetime
1927 2159 axes = self.axesList[i]
1928 2160 axes.pcolor(x, y, z[i,:].T,
1929 2161 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=self.zminList[i], zmax=self.zmaxList[i],
1930 2162 xlabel=xlabel, ylabel=ylabel, title=title, colormap=self.cmapList[i],ticksize=9, cblabel='')
1931 2163 self.draw()
1932 2164
1933 2165 if figfile == None:
1934 2166 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
1935 2167 name = str_datetime
1936 2168 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
1937 2169 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
1938 2170 figfile = self.getFilename(name)
1939 2171
1940 2172 self.save(figpath=figpath,
1941 2173 figfile=figfile,
1942 2174 save=save,
1943 2175 ftp=ftp,
1944 2176 wr_period=wr_period,
1945 2177 thisDatetime=thisDatetime)
@@ -1,1534 +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 class SpectraPlot(Figure):
14 15
15 16 isConfig = None
16 17 __nsubplots = None
17 18
18 19 WIDTHPROF = None
19 20 HEIGHTPROF = None
20 21 PREFIX = 'spc'
21 22
22 23 def __init__(self, **kwargs):
23 24 Figure.__init__(self, **kwargs)
24 25 self.isConfig = False
25 26 self.__nsubplots = 1
26 27
27 28 self.WIDTH = 250
28 29 self.HEIGHT = 250
29 30 self.WIDTHPROF = 120
30 31 self.HEIGHTPROF = 0
31 32 self.counter_imagwr = 0
32 33
33 34 self.PLOT_CODE = SPEC_CODE
34 35
35 36 self.FTP_WEI = None
36 37 self.EXP_CODE = None
37 38 self.SUB_EXP_CODE = None
38 39 self.PLOT_POS = None
39 40
40 41 self.__xfilter_ena = False
41 42 self.__yfilter_ena = False
42 43
43 44 def getSubplots(self):
44 45
45 46 ncol = int(numpy.sqrt(self.nplots)+0.9)
46 47 nrow = int(self.nplots*1./ncol + 0.9)
47 48
48 49 return nrow, ncol
49 50
50 51 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
51 52
52 53 self.__showprofile = showprofile
53 54 self.nplots = nplots
54 55
55 56 ncolspan = 1
56 57 colspan = 1
57 58 if showprofile:
58 59 ncolspan = 3
59 60 colspan = 2
60 61 self.__nsubplots = 2
61 62
62 63 self.createFigure(id = id,
63 64 wintitle = wintitle,
64 65 widthplot = self.WIDTH + self.WIDTHPROF,
65 66 heightplot = self.HEIGHT + self.HEIGHTPROF,
66 67 show=show)
67 68
68 69 nrow, ncol = self.getSubplots()
69 70
70 71 counter = 0
71 72 for y in range(nrow):
72 73 for x in range(ncol):
73 74
74 75 if counter >= self.nplots:
75 76 break
76 77
77 78 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
78 79
79 80 if showprofile:
80 81 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
81 82
82 83 counter += 1
83 84
84 85 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
85 86 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
86 87 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
87 88 server=None, folder=None, username=None, password=None,
88 89 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False,
89 90 xaxis="velocity", **kwargs):
90 91
91 92 """
92 93
93 94 Input:
94 95 dataOut :
95 96 id :
96 97 wintitle :
97 98 channelList :
98 99 showProfile :
99 100 xmin : None,
100 101 xmax : None,
101 102 ymin : None,
102 103 ymax : None,
103 104 zmin : None,
104 105 zmax : None
105 106 """
106 107
107 108 colormap = kwargs.get('colormap','jet')
108 109
109 110 if realtime:
110 111 if not(isRealtime(utcdatatime = dataOut.utctime)):
111 112 print 'Skipping this plot function'
112 113 return
113 114
114 115 if channelList == None:
115 116 channelIndexList = dataOut.channelIndexList
116 117 else:
117 118 channelIndexList = []
118 119 for channel in channelList:
119 120 if channel not in dataOut.channelList:
120 121 raise ValueError, "Channel %d is not in dataOut.channelList" %channel
121 122 channelIndexList.append(dataOut.channelList.index(channel))
122 123
123 124 factor = dataOut.normFactor
124 125
125 126 if xaxis == "frequency":
126 127 x = dataOut.getFreqRange(1)/1000.
127 128 xlabel = "Frequency (kHz)"
128 129
129 130 elif xaxis == "time":
130 131 x = dataOut.getAcfRange(1)
131 132 xlabel = "Time (ms)"
132 133
133 134 else:
134 135 x = dataOut.getVelRange(1)
135 136 xlabel = "Velocity (m/s)"
136 137
137 138 ylabel = "Range (Km)"
138 139
139 140 y = dataOut.getHeiRange()
140 141
141 142 z = dataOut.data_spc/factor
142 143 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
143 144 zdB = 10*numpy.log10(z)
144 145
145 146 avg = numpy.average(z, axis=1)
146 147 avgdB = 10*numpy.log10(avg)
147 148
148 149 noise = dataOut.getNoise()/factor
149 150 noisedB = 10*numpy.log10(noise)
150 151
151 152 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
152 153 title = wintitle + " Spectra"
153 154 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
154 155 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
155 156
156 157 if not self.isConfig:
157 158
158 159 nplots = len(channelIndexList)
159 160
160 161 self.setup(id=id,
161 162 nplots=nplots,
162 163 wintitle=wintitle,
163 164 showprofile=showprofile,
164 165 show=show)
165 166
166 167 if xmin == None: xmin = numpy.nanmin(x)
167 168 if xmax == None: xmax = numpy.nanmax(x)
168 169 if ymin == None: ymin = numpy.nanmin(y)
169 170 if ymax == None: ymax = numpy.nanmax(y)
170 171 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
171 172 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
172 173
173 174 self.FTP_WEI = ftp_wei
174 175 self.EXP_CODE = exp_code
175 176 self.SUB_EXP_CODE = sub_exp_code
176 177 self.PLOT_POS = plot_pos
177 178
178 179 self.isConfig = True
179 180
180 181 self.setWinTitle(title)
181 182
182 183 for i in range(self.nplots):
183 184 index = channelIndexList[i]
184 185 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
185 186 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[index], noisedB[index], str_datetime)
186 187 if len(dataOut.beam.codeList) != 0:
187 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)
188 189
189 190 axes = self.axesList[i*self.__nsubplots]
190 191 axes.pcolor(x, y, zdB[index,:,:],
191 192 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
192 193 xlabel=xlabel, ylabel=ylabel, title=title, colormap=colormap,
193 194 ticksize=9, cblabel='')
194 195
195 196 if self.__showprofile:
196 197 axes = self.axesList[i*self.__nsubplots +1]
197 198 axes.pline(avgdB[index,:], y,
198 199 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
199 200 xlabel='dB', ylabel='', title='',
200 201 ytick_visible=False,
201 202 grid='x')
202 203
203 204 noiseline = numpy.repeat(noisedB[index], len(y))
204 205 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
205 206
206 207 self.draw()
207 208
208 209 if figfile == None:
209 210 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
210 211 name = str_datetime
211 212 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
212 213 name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith)
213 214 figfile = self.getFilename(name)
214 215
215 216 self.save(figpath=figpath,
216 217 figfile=figfile,
217 218 save=save,
218 219 ftp=ftp,
219 220 wr_period=wr_period,
220 221 thisDatetime=thisDatetime)
221 222
222 223 class CrossSpectraPlot(Figure):
223 224
224 225 isConfig = None
225 226 __nsubplots = None
226 227
227 228 WIDTH = None
228 229 HEIGHT = None
229 230 WIDTHPROF = None
230 231 HEIGHTPROF = None
231 232 PREFIX = 'cspc'
232 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
233 268 def __init__(self, **kwargs):
234 269 Figure.__init__(self, **kwargs)
235 270 self.isConfig = False
236 271 self.__nsubplots = 4
237 272 self.counter_imagwr = 0
238 273 self.WIDTH = 250
239 274 self.HEIGHT = 250
240 275 self.WIDTHPROF = 0
241 276 self.HEIGHTPROF = 0
242 277
243 278 self.PLOT_CODE = CROSS_CODE
244 279 self.FTP_WEI = None
245 280 self.EXP_CODE = None
246 281 self.SUB_EXP_CODE = None
247 282 self.PLOT_POS = None
248 283
249 284 def getSubplots(self):
250 285
251 286 ncol = 4
252 287 nrow = self.nplots
253 288
254 289 return nrow, ncol
255 290
256 291 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
257 292
258 293 self.__showprofile = showprofile
259 294 self.nplots = nplots
260 295
261 296 ncolspan = 1
262 297 colspan = 1
263 298
264 299 self.createFigure(id = id,
265 300 wintitle = wintitle,
266 301 widthplot = self.WIDTH + self.WIDTHPROF,
267 302 heightplot = self.HEIGHT + self.HEIGHTPROF,
268 303 show=True)
269 304
270 305 nrow, ncol = self.getSubplots()
271 306
272 307 counter = 0
273 308 for y in range(nrow):
274 309 for x in range(ncol):
275 310 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
276 311
277 312 counter += 1
278 313
279 314 def run(self, dataOut, id, wintitle="", pairsList=None,
280 315 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
281 316 coh_min=None, coh_max=None, phase_min=None, phase_max=None,
282 317 save=False, figpath='./', figfile=None, ftp=False, wr_period=1,
283 318 power_cmap='jet', coherence_cmap='jet', phase_cmap='RdBu_r', show=True,
284 319 server=None, folder=None, username=None, password=None,
285 320 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0,
286 321 xaxis='frequency'):
287 322
288 323 """
289 324
290 325 Input:
291 326 dataOut :
292 327 id :
293 328 wintitle :
294 329 channelList :
295 330 showProfile :
296 331 xmin : None,
297 332 xmax : None,
298 333 ymin : None,
299 334 ymax : None,
300 335 zmin : None,
301 336 zmax : None
302 337 """
303 338
304 339 if pairsList == None:
305 340 pairsIndexList = dataOut.pairsIndexList
306 341 else:
307 342 pairsIndexList = []
308 343 for pair in pairsList:
309 344 if pair not in dataOut.pairsList:
310 345 raise ValueError, "Pair %s is not in dataOut.pairsList" %str(pair)
311 346 pairsIndexList.append(dataOut.pairsList.index(pair))
312 347
313 348 if not pairsIndexList:
314 349 return
315 350
316 351 if len(pairsIndexList) > 4:
317 352 pairsIndexList = pairsIndexList[0:4]
318 353
319 354 factor = dataOut.normFactor
320 355 x = dataOut.getVelRange(1)
321 356 y = dataOut.getHeiRange()
322 357 z = dataOut.data_spc[:,:,:]/factor
323 358 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
324 359
325 360 noise = dataOut.noise/factor
326 361
327 362 zdB = 10*numpy.log10(z)
328 363 noisedB = 10*numpy.log10(noise)
329 364
330 365 if coh_min == None:
331 366 coh_min = 0.0
332 367 if coh_max == None:
333 368 coh_max = 1.0
334 369
335 370 if phase_min == None:
336 371 phase_min = -180
337 372 if phase_max == None:
338 373 phase_max = 180
339 374
340 375 #thisDatetime = dataOut.datatime
341 376 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
342 377 title = wintitle + " Cross-Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
343 378 # xlabel = "Velocity (m/s)"
344 379 ylabel = "Range (Km)"
345 380
346 381 if xaxis == "frequency":
347 382 x = dataOut.getFreqRange(1)/1000.
348 383 xlabel = "Frequency (kHz)"
349 384
350 385 elif xaxis == "time":
351 386 x = dataOut.getAcfRange(1)
352 387 xlabel = "Time (ms)"
353 388
354 389 else:
355 390 x = dataOut.getVelRange(1)
356 391 xlabel = "Velocity (m/s)"
357 392
358 393 if not self.isConfig:
359 394
360 395 nplots = len(pairsIndexList)
361 396
362 397 self.setup(id=id,
363 398 nplots=nplots,
364 399 wintitle=wintitle,
365 400 showprofile=False,
366 401 show=show)
367 402
368 403 avg = numpy.abs(numpy.average(z, axis=1))
369 404 avgdB = 10*numpy.log10(avg)
370 405
371 406 if xmin == None: xmin = numpy.nanmin(x)
372 407 if xmax == None: xmax = numpy.nanmax(x)
373 408 if ymin == None: ymin = numpy.nanmin(y)
374 409 if ymax == None: ymax = numpy.nanmax(y)
375 410 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
376 411 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
377 412
378 413 self.FTP_WEI = ftp_wei
379 414 self.EXP_CODE = exp_code
380 415 self.SUB_EXP_CODE = sub_exp_code
381 416 self.PLOT_POS = plot_pos
382 417
383 418 self.isConfig = True
384 419
385 420 self.setWinTitle(title)
386 421
387 422 for i in range(self.nplots):
388 423 pair = dataOut.pairsList[pairsIndexList[i]]
389 424
390 425 chan_index0 = dataOut.channelList.index(pair[0])
391 426 chan_index1 = dataOut.channelList.index(pair[1])
392 427
393 428 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
394 429 title = "Ch%d: %4.2fdB: %s" %(pair[0], noisedB[chan_index0], str_datetime)
395 430 zdB = 10.*numpy.log10(dataOut.data_spc[chan_index0,:,:]/factor)
396 431 axes0 = self.axesList[i*self.__nsubplots]
397 432 axes0.pcolor(x, y, zdB,
398 433 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
399 434 xlabel=xlabel, ylabel=ylabel, title=title,
400 435 ticksize=9, colormap=power_cmap, cblabel='')
401 436
402 437 title = "Ch%d: %4.2fdB: %s" %(pair[1], noisedB[chan_index1], str_datetime)
403 438 zdB = 10.*numpy.log10(dataOut.data_spc[chan_index1,:,:]/factor)
404 439 axes0 = self.axesList[i*self.__nsubplots+1]
405 440 axes0.pcolor(x, y, zdB,
406 441 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
407 442 xlabel=xlabel, ylabel=ylabel, title=title,
408 443 ticksize=9, colormap=power_cmap, cblabel='')
409 444
410 445 coherenceComplex = dataOut.data_cspc[pairsIndexList[i],:,:]/numpy.sqrt(dataOut.data_spc[chan_index0,:,:]*dataOut.data_spc[chan_index1,:,:])
411 446 coherence = numpy.abs(coherenceComplex)
412 447 # phase = numpy.arctan(-1*coherenceComplex.imag/coherenceComplex.real)*180/numpy.pi
413 448 phase = numpy.arctan2(coherenceComplex.imag, coherenceComplex.real)*180/numpy.pi
414 449
415 450 title = "Coherence Ch%d * Ch%d" %(pair[0], pair[1])
416 451 axes0 = self.axesList[i*self.__nsubplots+2]
417 452 axes0.pcolor(x, y, coherence,
418 453 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=coh_min, zmax=coh_max,
419 454 xlabel=xlabel, ylabel=ylabel, title=title,
420 455 ticksize=9, colormap=coherence_cmap, cblabel='')
421 456
422 457 title = "Phase Ch%d * Ch%d" %(pair[0], pair[1])
423 458 axes0 = self.axesList[i*self.__nsubplots+3]
424 459 axes0.pcolor(x, y, phase,
425 460 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=phase_min, zmax=phase_max,
426 461 xlabel=xlabel, ylabel=ylabel, title=title,
427 462 ticksize=9, colormap=phase_cmap, cblabel='')
428 463
429 464
430 465
431 466 self.draw()
432 467
433 468 self.save(figpath=figpath,
434 469 figfile=figfile,
435 470 save=save,
436 471 ftp=ftp,
437 472 wr_period=wr_period,
438 473 thisDatetime=thisDatetime)
439 474
440 475
441 476 class RTIPlot(Figure):
442 477
443 478 __isConfig = None
444 479 __nsubplots = None
445 480
446 481 WIDTHPROF = None
447 482 HEIGHTPROF = None
448 483 PREFIX = 'rti'
449 484
450 485 def __init__(self, **kwargs):
451 486
452 487 Figure.__init__(self, **kwargs)
453 488 self.timerange = None
454 489 self.isConfig = False
455 490 self.__nsubplots = 1
456 491
457 492 self.WIDTH = 800
458 493 self.HEIGHT = 180
459 494 self.WIDTHPROF = 120
460 495 self.HEIGHTPROF = 0
461 496 self.counter_imagwr = 0
462 497
463 498 self.PLOT_CODE = RTI_CODE
464 499
465 500 self.FTP_WEI = None
466 501 self.EXP_CODE = None
467 502 self.SUB_EXP_CODE = None
468 503 self.PLOT_POS = None
469 504 self.tmin = None
470 505 self.tmax = None
471 506
472 507 self.xmin = None
473 508 self.xmax = None
474 509
475 510 self.figfile = None
476 511
477 512 def getSubplots(self):
478 513
479 514 ncol = 1
480 515 nrow = self.nplots
481 516
482 517 return nrow, ncol
483 518
484 519 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
485 520
486 521 self.__showprofile = showprofile
487 522 self.nplots = nplots
488 523
489 524 ncolspan = 1
490 525 colspan = 1
491 526 if showprofile:
492 527 ncolspan = 7
493 528 colspan = 6
494 529 self.__nsubplots = 2
495 530
496 531 self.createFigure(id = id,
497 532 wintitle = wintitle,
498 533 widthplot = self.WIDTH + self.WIDTHPROF,
499 534 heightplot = self.HEIGHT + self.HEIGHTPROF,
500 535 show=show)
501 536
502 537 nrow, ncol = self.getSubplots()
503 538
504 539 counter = 0
505 540 for y in range(nrow):
506 541 for x in range(ncol):
507 542
508 543 if counter >= self.nplots:
509 544 break
510 545
511 546 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
512 547
513 548 if showprofile:
514 549 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
515 550
516 551 counter += 1
517 552
518 553 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='True',
519 554 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
520 555 timerange=None,
521 556 save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True,
522 557 server=None, folder=None, username=None, password=None,
523 558 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, **kwargs):
524 559
525 560 """
526 561
527 562 Input:
528 563 dataOut :
529 564 id :
530 565 wintitle :
531 566 channelList :
532 567 showProfile :
533 568 xmin : None,
534 569 xmax : None,
535 570 ymin : None,
536 571 ymax : None,
537 572 zmin : None,
538 573 zmax : None
539 574 """
540 575
541 576 colormap = kwargs.get('colormap', 'jet')
542 577 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
543 578 return
544 579
545 580 if channelList == None:
546 581 channelIndexList = dataOut.channelIndexList
547 582 else:
548 583 channelIndexList = []
549 584 for channel in channelList:
550 585 if channel not in dataOut.channelList:
551 586 raise ValueError, "Channel %d is not in dataOut.channelList"
552 587 channelIndexList.append(dataOut.channelList.index(channel))
553 588
554 589 if hasattr(dataOut, 'normFactor'):
555 590 factor = dataOut.normFactor
556 591 else:
557 592 factor = 1
558 593
559 594 # factor = dataOut.normFactor
560 595 x = dataOut.getTimeRange()
561 596 y = dataOut.getHeiRange()
562 597
563 598 # z = dataOut.data_spc/factor
564 599 # z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
565 600 # avg = numpy.average(z, axis=1)
566 601 # avgdB = 10.*numpy.log10(avg)
567 602 avgdB = dataOut.getPower()
568 603
569 604 thisDatetime = dataOut.datatime
570 605 # thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
571 606 title = wintitle + " RTI" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
572 607 xlabel = ""
573 608 ylabel = "Range (Km)"
574 609
575 610 update_figfile = False
576 611
577 612 if dataOut.ltctime >= self.xmax:
578 613 self.counter_imagwr = wr_period
579 614 self.isConfig = False
580 615 update_figfile = True
581 616
582 617 if not self.isConfig:
583 618
584 619 nplots = len(channelIndexList)
585 620
586 621 self.setup(id=id,
587 622 nplots=nplots,
588 623 wintitle=wintitle,
589 624 showprofile=showprofile,
590 625 show=show)
591 626
592 627 if timerange != None:
593 628 self.timerange = timerange
594 629
595 630 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
596 631
597 632 noise = dataOut.noise/factor
598 633 noisedB = 10*numpy.log10(noise)
599 634
600 635 if ymin == None: ymin = numpy.nanmin(y)
601 636 if ymax == None: ymax = numpy.nanmax(y)
602 637 if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3
603 638 if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3
604 639
605 640 self.FTP_WEI = ftp_wei
606 641 self.EXP_CODE = exp_code
607 642 self.SUB_EXP_CODE = sub_exp_code
608 643 self.PLOT_POS = plot_pos
609 644
610 645 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
611 646 self.isConfig = True
612 647 self.figfile = figfile
613 648 update_figfile = True
614 649
615 650 self.setWinTitle(title)
616 651
617 652 for i in range(self.nplots):
618 653 index = channelIndexList[i]
619 654 title = "Channel %d: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
620 655 if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)):
621 656 title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith)
622 657 axes = self.axesList[i*self.__nsubplots]
623 658 zdB = avgdB[index].reshape((1,-1))
624 659 axes.pcolorbuffer(x, y, zdB,
625 660 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
626 661 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
627 662 ticksize=9, cblabel='', cbsize="1%", colormap=colormap)
628 663
629 664 if self.__showprofile:
630 665 axes = self.axesList[i*self.__nsubplots +1]
631 666 axes.pline(avgdB[index], y,
632 667 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
633 668 xlabel='dB', ylabel='', title='',
634 669 ytick_visible=False,
635 670 grid='x')
636 671
637 672 self.draw()
638 673
639 674 self.save(figpath=figpath,
640 675 figfile=figfile,
641 676 save=save,
642 677 ftp=ftp,
643 678 wr_period=wr_period,
644 679 thisDatetime=thisDatetime,
645 680 update_figfile=update_figfile)
646 681
647 682 class CoherenceMap(Figure):
648 683 isConfig = None
649 684 __nsubplots = None
650 685
651 686 WIDTHPROF = None
652 687 HEIGHTPROF = None
653 688 PREFIX = 'cmap'
654 689
690 parameters = {
691 'id': 'string',
692 'wintitle': 'string',
693 'pairsList': 'pairsLists',
694 'showprofile': 'boolean',
695 'xmin': 'float',
696 'xmax': 'float',
697 'ymin': 'float',
698 'ymax': 'float',
699 'zmin': 'float',
700 'zmax': 'float',
701 'timerange': 'float',
702 'phase_min': 'float',
703 'phase_max': 'float',
704 'save': 'boolean',
705 'figpath': 'string',
706 'figfile': 'string',
707 'ftp': 'boolean',
708 'wr_period': 'int',
709 'coherence_cmap': 'colormap',
710 'phase_cmap': 'colormap',
711 'show': 'boolean',
712 'server': 'string',
713 'folder': 'string',
714 'username': 'string',
715 'password': 'string',
716 'ftp_wei': 'int',
717 'exp_code': 'int',
718 'sub_exp_code': 'int',
719 'plot_pos': 'int',
720 }
721
655 722 def __init__(self, **kwargs):
656 723 Figure.__init__(self, **kwargs)
657 724 self.timerange = 2*60*60
658 725 self.isConfig = False
659 726 self.__nsubplots = 1
660 727
661 728 self.WIDTH = 800
662 729 self.HEIGHT = 180
663 730 self.WIDTHPROF = 120
664 731 self.HEIGHTPROF = 0
665 732 self.counter_imagwr = 0
666 733
667 734 self.PLOT_CODE = COH_CODE
668 735
669 736 self.FTP_WEI = None
670 737 self.EXP_CODE = None
671 738 self.SUB_EXP_CODE = None
672 739 self.PLOT_POS = None
673 740 self.counter_imagwr = 0
674 741
675 742 self.xmin = None
676 743 self.xmax = None
677 744
678 745 def getSubplots(self):
679 746 ncol = 1
680 747 nrow = self.nplots*2
681 748
682 749 return nrow, ncol
683 750
684 751 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
685 752 self.__showprofile = showprofile
686 753 self.nplots = nplots
687 754
688 755 ncolspan = 1
689 756 colspan = 1
690 757 if showprofile:
691 758 ncolspan = 7
692 759 colspan = 6
693 760 self.__nsubplots = 2
694 761
695 762 self.createFigure(id = id,
696 763 wintitle = wintitle,
697 764 widthplot = self.WIDTH + self.WIDTHPROF,
698 765 heightplot = self.HEIGHT + self.HEIGHTPROF,
699 766 show=True)
700 767
701 768 nrow, ncol = self.getSubplots()
702 769
703 770 for y in range(nrow):
704 771 for x in range(ncol):
705 772
706 773 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
707 774
708 775 if showprofile:
709 776 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
710 777
711 778 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
712 779 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
713 780 timerange=None, phase_min=None, phase_max=None,
714 781 save=False, figpath='./', figfile=None, ftp=False, wr_period=1,
715 782 coherence_cmap='jet', phase_cmap='RdBu_r', show=True,
716 783 server=None, folder=None, username=None, password=None,
717 784 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
718 785
719 786 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
720 787 return
721 788
722 789 if pairsList == None:
723 790 pairsIndexList = dataOut.pairsIndexList
724 791 else:
725 792 pairsIndexList = []
726 793 for pair in pairsList:
727 794 if pair not in dataOut.pairsList:
728 795 raise ValueError, "Pair %s is not in dataOut.pairsList" %(pair)
729 796 pairsIndexList.append(dataOut.pairsList.index(pair))
730 797
731 798 if pairsIndexList == []:
732 799 return
733 800
734 801 if len(pairsIndexList) > 4:
735 802 pairsIndexList = pairsIndexList[0:4]
736 803
737 804 if phase_min == None:
738 805 phase_min = -180
739 806 if phase_max == None:
740 807 phase_max = 180
741 808
742 809 x = dataOut.getTimeRange()
743 810 y = dataOut.getHeiRange()
744 811
745 812 thisDatetime = dataOut.datatime
746 813
747 814 title = wintitle + " CoherenceMap" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
748 815 xlabel = ""
749 816 ylabel = "Range (Km)"
750 817 update_figfile = False
751 818
752 819 if not self.isConfig:
753 820 nplots = len(pairsIndexList)
754 821 self.setup(id=id,
755 822 nplots=nplots,
756 823 wintitle=wintitle,
757 824 showprofile=showprofile,
758 825 show=show)
759 826
760 827 if timerange != None:
761 828 self.timerange = timerange
762 829
763 830 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
764 831
765 832 if ymin == None: ymin = numpy.nanmin(y)
766 833 if ymax == None: ymax = numpy.nanmax(y)
767 834 if zmin == None: zmin = 0.
768 835 if zmax == None: zmax = 1.
769 836
770 837 self.FTP_WEI = ftp_wei
771 838 self.EXP_CODE = exp_code
772 839 self.SUB_EXP_CODE = sub_exp_code
773 840 self.PLOT_POS = plot_pos
774 841
775 842 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
776 843
777 844 self.isConfig = True
778 845 update_figfile = True
779 846
780 847 self.setWinTitle(title)
781 848
782 849 for i in range(self.nplots):
783 850
784 851 pair = dataOut.pairsList[pairsIndexList[i]]
785 852
786 853 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i],:,:],axis=0)
787 854 powa = numpy.average(dataOut.data_spc[pair[0],:,:],axis=0)
788 855 powb = numpy.average(dataOut.data_spc[pair[1],:,:],axis=0)
789 856
790 857
791 858 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
792 859 coherence = numpy.abs(avgcoherenceComplex)
793 860
794 861 z = coherence.reshape((1,-1))
795 862
796 863 counter = 0
797 864
798 865 title = "Coherence Ch%d * Ch%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
799 866 axes = self.axesList[i*self.__nsubplots*2]
800 867 axes.pcolorbuffer(x, y, z,
801 868 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
802 869 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
803 870 ticksize=9, cblabel='', colormap=coherence_cmap, cbsize="1%")
804 871
805 872 if self.__showprofile:
806 873 counter += 1
807 874 axes = self.axesList[i*self.__nsubplots*2 + counter]
808 875 axes.pline(coherence, y,
809 876 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
810 877 xlabel='', ylabel='', title='', ticksize=7,
811 878 ytick_visible=False, nxticks=5,
812 879 grid='x')
813 880
814 881 counter += 1
815 882
816 883 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
817 884
818 885 z = phase.reshape((1,-1))
819 886
820 887 title = "Phase Ch%d * Ch%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
821 888 axes = self.axesList[i*self.__nsubplots*2 + counter]
822 889 axes.pcolorbuffer(x, y, z,
823 890 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=phase_min, zmax=phase_max,
824 891 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
825 892 ticksize=9, cblabel='', colormap=phase_cmap, cbsize="1%")
826 893
827 894 if self.__showprofile:
828 895 counter += 1
829 896 axes = self.axesList[i*self.__nsubplots*2 + counter]
830 897 axes.pline(phase, y,
831 898 xmin=phase_min, xmax=phase_max, ymin=ymin, ymax=ymax,
832 899 xlabel='', ylabel='', title='', ticksize=7,
833 900 ytick_visible=False, nxticks=4,
834 901 grid='x')
835 902
836 903 self.draw()
837 904
838 905 if dataOut.ltctime >= self.xmax:
839 906 self.counter_imagwr = wr_period
840 907 self.isConfig = False
841 908 update_figfile = True
842 909
843 910 self.save(figpath=figpath,
844 911 figfile=figfile,
845 912 save=save,
846 913 ftp=ftp,
847 914 wr_period=wr_period,
848 915 thisDatetime=thisDatetime,
849 916 update_figfile=update_figfile)
850 917
851 918 class PowerProfilePlot(Figure):
852 919
853 920 isConfig = None
854 921 __nsubplots = None
855 922
856 923 WIDTHPROF = None
857 924 HEIGHTPROF = None
858 925 PREFIX = 'spcprofile'
859 926
860 927 def __init__(self, **kwargs):
861 928 Figure.__init__(self, **kwargs)
862 929 self.isConfig = False
863 930 self.__nsubplots = 1
864 931
865 932 self.PLOT_CODE = POWER_CODE
866 933
867 934 self.WIDTH = 300
868 935 self.HEIGHT = 500
869 936 self.counter_imagwr = 0
870 937
871 938 def getSubplots(self):
872 939 ncol = 1
873 940 nrow = 1
874 941
875 942 return nrow, ncol
876 943
877 944 def setup(self, id, nplots, wintitle, show):
878 945
879 946 self.nplots = nplots
880 947
881 948 ncolspan = 1
882 949 colspan = 1
883 950
884 951 self.createFigure(id = id,
885 952 wintitle = wintitle,
886 953 widthplot = self.WIDTH,
887 954 heightplot = self.HEIGHT,
888 955 show=show)
889 956
890 957 nrow, ncol = self.getSubplots()
891 958
892 959 counter = 0
893 960 for y in range(nrow):
894 961 for x in range(ncol):
895 962 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
896 963
897 964 def run(self, dataOut, id, wintitle="", channelList=None,
898 965 xmin=None, xmax=None, ymin=None, ymax=None,
899 966 save=False, figpath='./', figfile=None, show=True,
900 967 ftp=False, wr_period=1, server=None,
901 968 folder=None, username=None, password=None):
902 969
903 970
904 971 if channelList == None:
905 972 channelIndexList = dataOut.channelIndexList
906 973 channelList = dataOut.channelList
907 974 else:
908 975 channelIndexList = []
909 976 for channel in channelList:
910 977 if channel not in dataOut.channelList:
911 978 raise ValueError, "Channel %d is not in dataOut.channelList"
912 979 channelIndexList.append(dataOut.channelList.index(channel))
913 980
914 981 factor = dataOut.normFactor
915 982
916 983 y = dataOut.getHeiRange()
917 984
918 985 #for voltage
919 986 if dataOut.type == 'Voltage':
920 987 x = dataOut.data[channelIndexList,:] * numpy.conjugate(dataOut.data[channelIndexList,:])
921 988 x = x.real
922 989 x = numpy.where(numpy.isfinite(x), x, numpy.NAN)
923 990
924 991 #for spectra
925 992 if dataOut.type == 'Spectra':
926 993 x = dataOut.data_spc[channelIndexList,:,:]/factor
927 994 x = numpy.where(numpy.isfinite(x), x, numpy.NAN)
928 995 x = numpy.average(x, axis=1)
929 996
930 997
931 998 xdB = 10*numpy.log10(x)
932 999
933 1000 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
934 1001 title = wintitle + " Power Profile %s" %(thisDatetime.strftime("%d-%b-%Y"))
935 1002 xlabel = "dB"
936 1003 ylabel = "Range (Km)"
937 1004
938 1005 if not self.isConfig:
939 1006
940 1007 nplots = 1
941 1008
942 1009 self.setup(id=id,
943 1010 nplots=nplots,
944 1011 wintitle=wintitle,
945 1012 show=show)
946 1013
947 1014 if ymin == None: ymin = numpy.nanmin(y)
948 1015 if ymax == None: ymax = numpy.nanmax(y)
949 1016 if xmin == None: xmin = numpy.nanmin(xdB)*0.9
950 1017 if xmax == None: xmax = numpy.nanmax(xdB)*1.1
951 1018
952 1019 self.isConfig = True
953 1020
954 1021 self.setWinTitle(title)
955 1022
956 1023 title = "Power Profile: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
957 1024 axes = self.axesList[0]
958 1025
959 1026 legendlabels = ["channel %d"%x for x in channelList]
960 1027 axes.pmultiline(xdB, y,
961 1028 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
962 1029 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels,
963 1030 ytick_visible=True, nxticks=5,
964 1031 grid='x')
965 1032
966 1033 self.draw()
967 1034
968 1035 self.save(figpath=figpath,
969 1036 figfile=figfile,
970 1037 save=save,
971 1038 ftp=ftp,
972 1039 wr_period=wr_period,
973 1040 thisDatetime=thisDatetime)
974 1041
975 1042 class SpectraCutPlot(Figure):
976 1043
977 1044 isConfig = None
978 1045 __nsubplots = None
979 1046
980 1047 WIDTHPROF = None
981 1048 HEIGHTPROF = None
982 1049 PREFIX = 'spc_cut'
983 1050
984 1051 def __init__(self, **kwargs):
985 1052 Figure.__init__(self, **kwargs)
986 1053 self.isConfig = False
987 1054 self.__nsubplots = 1
988 1055
989 1056 self.PLOT_CODE = POWER_CODE
990 1057
991 1058 self.WIDTH = 700
992 1059 self.HEIGHT = 500
993 1060 self.counter_imagwr = 0
994 1061
995 1062 def getSubplots(self):
996 1063 ncol = 1
997 1064 nrow = 1
998 1065
999 1066 return nrow, ncol
1000 1067
1001 1068 def setup(self, id, nplots, wintitle, show):
1002 1069
1003 1070 self.nplots = nplots
1004 1071
1005 1072 ncolspan = 1
1006 1073 colspan = 1
1007 1074
1008 1075 self.createFigure(id = id,
1009 1076 wintitle = wintitle,
1010 1077 widthplot = self.WIDTH,
1011 1078 heightplot = self.HEIGHT,
1012 1079 show=show)
1013 1080
1014 1081 nrow, ncol = self.getSubplots()
1015 1082
1016 1083 counter = 0
1017 1084 for y in range(nrow):
1018 1085 for x in range(ncol):
1019 1086 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1020 1087
1021 1088 def run(self, dataOut, id, wintitle="", channelList=None,
1022 1089 xmin=None, xmax=None, ymin=None, ymax=None,
1023 1090 save=False, figpath='./', figfile=None, show=True,
1024 1091 ftp=False, wr_period=1, server=None,
1025 1092 folder=None, username=None, password=None,
1026 1093 xaxis="frequency"):
1027 1094
1028 1095
1029 1096 if channelList == None:
1030 1097 channelIndexList = dataOut.channelIndexList
1031 1098 channelList = dataOut.channelList
1032 1099 else:
1033 1100 channelIndexList = []
1034 1101 for channel in channelList:
1035 1102 if channel not in dataOut.channelList:
1036 1103 raise ValueError, "Channel %d is not in dataOut.channelList"
1037 1104 channelIndexList.append(dataOut.channelList.index(channel))
1038 1105
1039 1106 factor = dataOut.normFactor
1040 1107
1041 1108 y = dataOut.getHeiRange()
1042 1109
1043 1110 z = dataOut.data_spc/factor
1044 1111 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1045 1112
1046 1113 hei_index = numpy.arange(25)*3 + 20
1047 1114
1048 1115 if xaxis == "frequency":
1049 1116 x = dataOut.getFreqRange()/1000.
1050 1117 zdB = 10*numpy.log10(z[0,:,hei_index])
1051 1118 xlabel = "Frequency (kHz)"
1052 1119 ylabel = "Power (dB)"
1053 1120
1054 1121 elif xaxis == "time":
1055 1122 x = dataOut.getAcfRange()
1056 1123 zdB = z[0,:,hei_index]
1057 1124 xlabel = "Time (ms)"
1058 1125 ylabel = "ACF"
1059 1126
1060 1127 else:
1061 1128 x = dataOut.getVelRange()
1062 1129 zdB = 10*numpy.log10(z[0,:,hei_index])
1063 1130 xlabel = "Velocity (m/s)"
1064 1131 ylabel = "Power (dB)"
1065 1132
1066 1133 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0])
1067 1134 title = wintitle + " Range Cuts %s" %(thisDatetime.strftime("%d-%b-%Y"))
1068 1135
1069 1136 if not self.isConfig:
1070 1137
1071 1138 nplots = 1
1072 1139
1073 1140 self.setup(id=id,
1074 1141 nplots=nplots,
1075 1142 wintitle=wintitle,
1076 1143 show=show)
1077 1144
1078 1145 if xmin == None: xmin = numpy.nanmin(x)*0.9
1079 1146 if xmax == None: xmax = numpy.nanmax(x)*1.1
1080 1147 if ymin == None: ymin = numpy.nanmin(zdB)
1081 1148 if ymax == None: ymax = numpy.nanmax(zdB)
1082 1149
1083 1150 self.isConfig = True
1084 1151
1085 1152 self.setWinTitle(title)
1086 1153
1087 1154 title = "Spectra Cuts: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
1088 1155 axes = self.axesList[0]
1089 1156
1090 1157 legendlabels = ["Range = %dKm" %y[i] for i in hei_index]
1091 1158
1092 1159 axes.pmultilineyaxis( x, zdB,
1093 1160 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1094 1161 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels,
1095 1162 ytick_visible=True, nxticks=5,
1096 1163 grid='x')
1097 1164
1098 1165 self.draw()
1099 1166
1100 1167 self.save(figpath=figpath,
1101 1168 figfile=figfile,
1102 1169 save=save,
1103 1170 ftp=ftp,
1104 1171 wr_period=wr_period,
1105 1172 thisDatetime=thisDatetime)
1106 1173
1107 1174 class Noise(Figure):
1108 1175
1109 1176 isConfig = None
1110 1177 __nsubplots = None
1111 1178
1112 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 }
1113 1206
1114 1207 def __init__(self, **kwargs):
1115 1208 Figure.__init__(self, **kwargs)
1116 1209 self.timerange = 24*60*60
1117 1210 self.isConfig = False
1118 1211 self.__nsubplots = 1
1119 1212 self.counter_imagwr = 0
1120 1213 self.WIDTH = 800
1121 1214 self.HEIGHT = 400
1122 1215 self.WIDTHPROF = 120
1123 1216 self.HEIGHTPROF = 0
1124 1217 self.xdata = None
1125 1218 self.ydata = None
1126 1219
1127 1220 self.PLOT_CODE = NOISE_CODE
1128 1221
1129 1222 self.FTP_WEI = None
1130 1223 self.EXP_CODE = None
1131 1224 self.SUB_EXP_CODE = None
1132 1225 self.PLOT_POS = None
1133 1226 self.figfile = None
1134 1227
1135 1228 self.xmin = None
1136 1229 self.xmax = None
1137 1230
1138 1231 def getSubplots(self):
1139 1232
1140 1233 ncol = 1
1141 1234 nrow = 1
1142 1235
1143 1236 return nrow, ncol
1144 1237
1145 1238 def openfile(self, filename):
1146 1239 dirname = os.path.dirname(filename)
1147 1240
1148 1241 if not os.path.exists(dirname):
1149 1242 os.mkdir(dirname)
1150 1243
1151 1244 f = open(filename,'w+')
1152 1245 f.write('\n\n')
1153 1246 f.write('JICAMARCA RADIO OBSERVATORY - Noise \n')
1154 1247 f.write('DD MM YYYY HH MM SS Channel0 Channel1 Channel2 Channel3\n\n' )
1155 1248 f.close()
1156 1249
1157 1250 def save_data(self, filename_phase, data, data_datetime):
1158 1251
1159 1252 f=open(filename_phase,'a')
1160 1253
1161 1254 timetuple_data = data_datetime.timetuple()
1162 1255 day = str(timetuple_data.tm_mday)
1163 1256 month = str(timetuple_data.tm_mon)
1164 1257 year = str(timetuple_data.tm_year)
1165 1258 hour = str(timetuple_data.tm_hour)
1166 1259 minute = str(timetuple_data.tm_min)
1167 1260 second = str(timetuple_data.tm_sec)
1168 1261
1169 1262 data_msg = ''
1170 1263 for i in range(len(data)):
1171 1264 data_msg += str(data[i]) + ' '
1172 1265
1173 1266 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' ' + data_msg + '\n')
1174 1267 f.close()
1175 1268
1176 1269
1177 1270 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1178 1271
1179 1272 self.__showprofile = showprofile
1180 1273 self.nplots = nplots
1181 1274
1182 1275 ncolspan = 7
1183 1276 colspan = 6
1184 1277 self.__nsubplots = 2
1185 1278
1186 1279 self.createFigure(id = id,
1187 1280 wintitle = wintitle,
1188 1281 widthplot = self.WIDTH+self.WIDTHPROF,
1189 1282 heightplot = self.HEIGHT+self.HEIGHTPROF,
1190 1283 show=show)
1191 1284
1192 1285 nrow, ncol = self.getSubplots()
1193 1286
1194 1287 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1195 1288
1196 1289
1197 1290 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='True',
1198 1291 xmin=None, xmax=None, ymin=None, ymax=None,
1199 1292 timerange=None,
1200 1293 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1201 1294 server=None, folder=None, username=None, password=None,
1202 1295 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1203 1296
1204 1297 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1205 1298 return
1206 1299
1207 1300 if channelList == None:
1208 1301 channelIndexList = dataOut.channelIndexList
1209 1302 channelList = dataOut.channelList
1210 1303 else:
1211 1304 channelIndexList = []
1212 1305 for channel in channelList:
1213 1306 if channel not in dataOut.channelList:
1214 1307 raise ValueError, "Channel %d is not in dataOut.channelList"
1215 1308 channelIndexList.append(dataOut.channelList.index(channel))
1216 1309
1217 1310 x = dataOut.getTimeRange()
1218 1311 #y = dataOut.getHeiRange()
1219 1312 factor = dataOut.normFactor
1220 1313 noise = dataOut.noise[channelIndexList]/factor
1221 1314 noisedB = 10*numpy.log10(noise)
1222 1315
1223 1316 thisDatetime = dataOut.datatime
1224 1317
1225 1318 title = wintitle + " Noise" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1226 1319 xlabel = ""
1227 1320 ylabel = "Intensity (dB)"
1228 1321 update_figfile = False
1229 1322
1230 1323 if not self.isConfig:
1231 1324
1232 1325 nplots = 1
1233 1326
1234 1327 self.setup(id=id,
1235 1328 nplots=nplots,
1236 1329 wintitle=wintitle,
1237 1330 showprofile=showprofile,
1238 1331 show=show)
1239 1332
1240 1333 if timerange != None:
1241 1334 self.timerange = timerange
1242 1335
1243 1336 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1244 1337
1245 1338 if ymin == None: ymin = numpy.floor(numpy.nanmin(noisedB)) - 10.0
1246 1339 if ymax == None: ymax = numpy.nanmax(noisedB) + 10.0
1247 1340
1248 1341 self.FTP_WEI = ftp_wei
1249 1342 self.EXP_CODE = exp_code
1250 1343 self.SUB_EXP_CODE = sub_exp_code
1251 1344 self.PLOT_POS = plot_pos
1252 1345
1253 1346
1254 1347 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1255 1348 self.isConfig = True
1256 1349 self.figfile = figfile
1257 1350 self.xdata = numpy.array([])
1258 1351 self.ydata = numpy.array([])
1259 1352
1260 1353 update_figfile = True
1261 1354
1262 1355 #open file beacon phase
1263 1356 path = '%s%03d' %(self.PREFIX, self.id)
1264 1357 noise_file = os.path.join(path,'%s.txt'%self.name)
1265 1358 self.filename_noise = os.path.join(figpath,noise_file)
1266 1359
1267 1360 self.setWinTitle(title)
1268 1361
1269 1362 title = "Noise %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1270 1363
1271 1364 legendlabels = ["channel %d"%(idchannel) for idchannel in channelList]
1272 1365 axes = self.axesList[0]
1273 1366
1274 1367 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1275 1368
1276 1369 if len(self.ydata)==0:
1277 1370 self.ydata = noisedB.reshape(-1,1)
1278 1371 else:
1279 1372 self.ydata = numpy.hstack((self.ydata, noisedB.reshape(-1,1)))
1280 1373
1281 1374
1282 1375 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1283 1376 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1284 1377 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1285 1378 XAxisAsTime=True, grid='both'
1286 1379 )
1287 1380
1288 1381 self.draw()
1289 1382
1290 1383 if dataOut.ltctime >= self.xmax:
1291 1384 self.counter_imagwr = wr_period
1292 1385 self.isConfig = False
1293 1386 update_figfile = True
1294 1387
1295 1388 self.save(figpath=figpath,
1296 1389 figfile=figfile,
1297 1390 save=save,
1298 1391 ftp=ftp,
1299 1392 wr_period=wr_period,
1300 1393 thisDatetime=thisDatetime,
1301 1394 update_figfile=update_figfile)
1302 1395
1303 1396 #store data beacon phase
1304 1397 if save:
1305 1398 self.save_data(self.filename_noise, noisedB, thisDatetime)
1306 1399
1307 1400 class BeaconPhase(Figure):
1308 1401
1309 1402 __isConfig = None
1310 1403 __nsubplots = None
1311 1404
1312 1405 PREFIX = 'beacon_phase'
1406
1407 parameters = {
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,
1433 }
1313 1434
1314 1435 def __init__(self, **kwargs):
1315 1436 Figure.__init__(self, **kwargs)
1316 1437 self.timerange = 24*60*60
1317 1438 self.isConfig = False
1318 1439 self.__nsubplots = 1
1319 1440 self.counter_imagwr = 0
1320 1441 self.WIDTH = 800
1321 1442 self.HEIGHT = 400
1322 1443 self.WIDTHPROF = 120
1323 1444 self.HEIGHTPROF = 0
1324 1445 self.xdata = None
1325 1446 self.ydata = None
1326 1447
1327 1448 self.PLOT_CODE = BEACON_CODE
1328 1449
1329 1450 self.FTP_WEI = None
1330 1451 self.EXP_CODE = None
1331 1452 self.SUB_EXP_CODE = None
1332 1453 self.PLOT_POS = None
1333 1454
1334 1455 self.filename_phase = None
1335 1456
1336 1457 self.figfile = None
1337 1458
1338 1459 self.xmin = None
1339 1460 self.xmax = None
1340 1461
1341 1462 def getSubplots(self):
1342 1463
1343 1464 ncol = 1
1344 1465 nrow = 1
1345 1466
1346 1467 return nrow, ncol
1347 1468
1348 1469 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1349 1470
1350 1471 self.__showprofile = showprofile
1351 1472 self.nplots = nplots
1352 1473
1353 1474 ncolspan = 7
1354 1475 colspan = 6
1355 1476 self.__nsubplots = 2
1356 1477
1357 1478 self.createFigure(id = id,
1358 1479 wintitle = wintitle,
1359 1480 widthplot = self.WIDTH+self.WIDTHPROF,
1360 1481 heightplot = self.HEIGHT+self.HEIGHTPROF,
1361 1482 show=show)
1362 1483
1363 1484 nrow, ncol = self.getSubplots()
1364 1485
1365 1486 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1366 1487
1367 1488 def save_phase(self, filename_phase):
1368 1489 f = open(filename_phase,'w+')
1369 1490 f.write('\n\n')
1370 1491 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
1371 1492 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
1372 1493 f.close()
1373 1494
1374 1495 def save_data(self, filename_phase, data, data_datetime):
1375 1496 f=open(filename_phase,'a')
1376 1497 timetuple_data = data_datetime.timetuple()
1377 1498 day = str(timetuple_data.tm_mday)
1378 1499 month = str(timetuple_data.tm_mon)
1379 1500 year = str(timetuple_data.tm_year)
1380 1501 hour = str(timetuple_data.tm_hour)
1381 1502 minute = str(timetuple_data.tm_min)
1382 1503 second = str(timetuple_data.tm_sec)
1383 1504 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
1384 1505 f.close()
1385 1506
1386 1507
1387 1508 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1388 1509 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
1389 1510 timerange=None,
1390 1511 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1391 1512 server=None, folder=None, username=None, password=None,
1392 1513 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1393 1514
1394 1515 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1395 1516 return
1396 1517
1397 1518 if pairsList == None:
1398 1519 pairsIndexList = dataOut.pairsIndexList[:10]
1399 1520 else:
1400 1521 pairsIndexList = []
1401 1522 for pair in pairsList:
1402 1523 if pair not in dataOut.pairsList:
1403 1524 raise ValueError, "Pair %s is not in dataOut.pairsList" %(pair)
1404 1525 pairsIndexList.append(dataOut.pairsList.index(pair))
1405 1526
1406 1527 if pairsIndexList == []:
1407 1528 return
1408 1529
1409 1530 # if len(pairsIndexList) > 4:
1410 1531 # pairsIndexList = pairsIndexList[0:4]
1411 1532
1412 1533 hmin_index = None
1413 1534 hmax_index = None
1414 1535
1415 1536 if hmin != None and hmax != None:
1416 1537 indexes = numpy.arange(dataOut.nHeights)
1417 1538 hmin_list = indexes[dataOut.heightList >= hmin]
1418 1539 hmax_list = indexes[dataOut.heightList <= hmax]
1419 1540
1420 1541 if hmin_list.any():
1421 1542 hmin_index = hmin_list[0]
1422 1543
1423 1544 if hmax_list.any():
1424 1545 hmax_index = hmax_list[-1]+1
1425 1546
1426 1547 x = dataOut.getTimeRange()
1427 1548 #y = dataOut.getHeiRange()
1428 1549
1429 1550
1430 1551 thisDatetime = dataOut.datatime
1431 1552
1432 1553 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1433 1554 xlabel = "Local Time"
1434 1555 ylabel = "Phase (degrees)"
1435 1556
1436 1557 update_figfile = False
1437 1558
1438 1559 nplots = len(pairsIndexList)
1439 1560 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1440 1561 phase_beacon = numpy.zeros(len(pairsIndexList))
1441 1562 for i in range(nplots):
1442 1563 pair = dataOut.pairsList[pairsIndexList[i]]
1443 1564 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
1444 1565 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
1445 1566 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
1446 1567 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
1447 1568 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
1448 1569
1449 1570 #print "Phase %d%d" %(pair[0], pair[1])
1450 1571 #print phase[dataOut.beacon_heiIndexList]
1451 1572
1452 1573 if dataOut.beacon_heiIndexList:
1453 1574 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
1454 1575 else:
1455 1576 phase_beacon[i] = numpy.average(phase)
1456 1577
1457 1578 if not self.isConfig:
1458 1579
1459 1580 nplots = len(pairsIndexList)
1460 1581
1461 1582 self.setup(id=id,
1462 1583 nplots=nplots,
1463 1584 wintitle=wintitle,
1464 1585 showprofile=showprofile,
1465 1586 show=show)
1466 1587
1467 1588 if timerange != None:
1468 1589 self.timerange = timerange
1469 1590
1470 1591 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1471 1592
1472 1593 if ymin == None: ymin = 0
1473 1594 if ymax == None: ymax = 360
1474 1595
1475 1596 self.FTP_WEI = ftp_wei
1476 1597 self.EXP_CODE = exp_code
1477 1598 self.SUB_EXP_CODE = sub_exp_code
1478 1599 self.PLOT_POS = plot_pos
1479 1600
1480 1601 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1481 1602 self.isConfig = True
1482 1603 self.figfile = figfile
1483 1604 self.xdata = numpy.array([])
1484 1605 self.ydata = numpy.array([])
1485 1606
1486 1607 update_figfile = True
1487 1608
1488 1609 #open file beacon phase
1489 1610 path = '%s%03d' %(self.PREFIX, self.id)
1490 1611 beacon_file = os.path.join(path,'%s.txt'%self.name)
1491 1612 self.filename_phase = os.path.join(figpath,beacon_file)
1492 1613 #self.save_phase(self.filename_phase)
1493 1614
1494 1615
1495 1616 #store data beacon phase
1496 1617 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1497 1618
1498 1619 self.setWinTitle(title)
1499 1620
1500 1621
1501 1622 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1502 1623
1503 1624 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
1504 1625
1505 1626 axes = self.axesList[0]
1506 1627
1507 1628 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1508 1629
1509 1630 if len(self.ydata)==0:
1510 1631 self.ydata = phase_beacon.reshape(-1,1)
1511 1632 else:
1512 1633 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1513 1634
1514 1635
1515 1636 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1516 1637 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1517 1638 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1518 1639 XAxisAsTime=True, grid='both'
1519 1640 )
1520 1641
1521 1642 self.draw()
1522 1643
1523 1644 if dataOut.ltctime >= self.xmax:
1524 1645 self.counter_imagwr = wr_period
1525 1646 self.isConfig = False
1526 1647 update_figfile = True
1527 1648
1528 1649 self.save(figpath=figpath,
1529 1650 figfile=figfile,
1530 1651 save=save,
1531 1652 ftp=ftp,
1532 1653 wr_period=wr_period,
1533 1654 thisDatetime=thisDatetime,
1534 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,1105 +1,1103
1 1 import numpy
2 2 import time
3 3 import os
4 4 import h5py
5 5 import re
6 6 import datetime
7 7
8 8 from schainpy.model.data.jrodata import *
9 9 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation
10 10 # from jroIO_base import *
11 11 from schainpy.model.io.jroIO_base import *
12 12 import schainpy
13 13
14 14
15 15 class ParamReader(ProcessingUnit):
16 16 '''
17 17 Reads HDF5 format files
18 18
19 19 path
20 20
21 21 startDate
22 22
23 23 endDate
24 24
25 25 startTime
26 26
27 27 endTime
28 28 '''
29 29
30 30 ext = ".hdf5"
31 31
32 32 optchar = "D"
33 33
34 34 timezone = None
35 35
36 36 startTime = None
37 37
38 38 endTime = None
39 39
40 40 fileIndex = None
41 41
42 42 utcList = None #To select data in the utctime list
43 43
44 44 blockList = None #List to blocks to be read from the file
45 45
46 46 blocksPerFile = None #Number of blocks to be read
47 47
48 48 blockIndex = None
49 49
50 50 path = None
51 51
52 52 #List of Files
53 53
54 54 filenameList = None
55 55
56 56 datetimeList = None
57 57
58 58 #Hdf5 File
59 59
60 60 listMetaname = None
61 61
62 62 listMeta = None
63 63
64 64 listDataname = None
65 65
66 66 listData = None
67 67
68 68 listShapes = None
69 69
70 70 fp = None
71 71
72 72 #dataOut reconstruction
73 73
74 74 dataOut = None
75 75
76 76
77 77 def __init__(self, **kwargs):
78 78 ProcessingUnit.__init__(self, **kwargs)
79 79 self.dataOut = Parameters()
80 80 return
81 81
82 82 def setup(self, **kwargs):
83 83
84 84 path = kwargs['path']
85 85 startDate = kwargs['startDate']
86 86 endDate = kwargs['endDate']
87 87 startTime = kwargs['startTime']
88 88 endTime = kwargs['endTime']
89 89 walk = kwargs['walk']
90 90 if kwargs.has_key('ext'):
91 91 ext = kwargs['ext']
92 92 else:
93 93 ext = '.hdf5'
94 94 if kwargs.has_key('timezone'):
95 95 self.timezone = kwargs['timezone']
96 96 else:
97 97 self.timezone = 'lt'
98 98
99 99 print "[Reading] Searching files in offline mode ..."
100 100 pathList, filenameList = self.__searchFilesOffLine(path, startDate=startDate, endDate=endDate,
101 101 startTime=startTime, endTime=endTime,
102 102 ext=ext, walk=walk)
103 103
104 104 if not(filenameList):
105 105 print "There is no files into the folder: %s"%(path)
106 106 sys.exit(-1)
107 107
108 108 self.fileIndex = -1
109 109 self.startTime = startTime
110 110 self.endTime = endTime
111 111
112 112 self.__readMetadata()
113 113
114 114 self.__setNextFileOffline()
115 115
116 116 return
117 117
118 118 def __searchFilesOffLine(self,
119 119 path,
120 120 startDate=None,
121 121 endDate=None,
122 122 startTime=datetime.time(0,0,0),
123 123 endTime=datetime.time(23,59,59),
124 124 ext='.hdf5',
125 125 walk=True):
126 126
127 127 expLabel = ''
128 128 self.filenameList = []
129 129 self.datetimeList = []
130 130
131 131 pathList = []
132 132
133 133 JRODataObj = JRODataReader()
134 134 dateList, pathList = JRODataObj.findDatafiles(path, startDate, endDate, expLabel, ext, walk, include_path=True)
135 135
136 136 if dateList == []:
137 137 print "[Reading] No *%s files in %s from %s to %s)"%(ext, path,
138 138 datetime.datetime.combine(startDate,startTime).ctime(),
139 139 datetime.datetime.combine(endDate,endTime).ctime())
140 140
141 141 return None, None
142 142
143 143 if len(dateList) > 1:
144 144 print "[Reading] %d days were found in date range: %s - %s" %(len(dateList), startDate, endDate)
145 145 else:
146 146 print "[Reading] data was found for the date %s" %(dateList[0])
147 147
148 148 filenameList = []
149 149 datetimeList = []
150 150
151 151 #----------------------------------------------------------------------------------
152 152
153 153 for thisPath in pathList:
154 154 # thisPath = pathList[pathDict[file]]
155 155
156 156 fileList = glob.glob1(thisPath, "*%s" %ext)
157 157 fileList.sort()
158 158
159 159 for file in fileList:
160 160
161 161 filename = os.path.join(thisPath,file)
162 162
163 163 if not isFileInDateRange(filename, startDate, endDate):
164 164 continue
165 165
166 166 thisDatetime = self.__isFileInTimeRange(filename, startDate, endDate, startTime, endTime)
167 167
168 168 if not(thisDatetime):
169 169 continue
170 170
171 171 filenameList.append(filename)
172 172 datetimeList.append(thisDatetime)
173 173
174 174 if not(filenameList):
175 175 print "[Reading] Any file was found int time range %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime())
176 176 return None, None
177 177
178 178 print "[Reading] %d file(s) was(were) found in time range: %s - %s" %(len(filenameList), startTime, endTime)
179 179 print
180 180
181 181 for i in range(len(filenameList)):
182 182 print "[Reading] %s -> [%s]" %(filenameList[i], datetimeList[i].ctime())
183 183
184 184 self.filenameList = filenameList
185 185 self.datetimeList = datetimeList
186 186
187 187 return pathList, filenameList
188 188
189 189 def __isFileInTimeRange(self,filename, startDate, endDate, startTime, endTime):
190 190
191 191 """
192 192 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
193 193
194 194 Inputs:
195 195 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
196 196
197 197 startDate : fecha inicial del rango seleccionado en formato datetime.date
198 198
199 199 endDate : fecha final del rango seleccionado en formato datetime.date
200 200
201 201 startTime : tiempo inicial del rango seleccionado en formato datetime.time
202 202
203 203 endTime : tiempo final del rango seleccionado en formato datetime.time
204 204
205 205 Return:
206 206 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
207 207 fecha especificado, de lo contrario retorna False.
208 208
209 209 Excepciones:
210 210 Si el archivo no existe o no puede ser abierto
211 211 Si la cabecera no puede ser leida.
212 212
213 213 """
214 214
215 215 try:
216 216 fp = h5py.File(filename,'r')
217 217 grp1 = fp['Data']
218 218
219 219 except IOError:
220 220 traceback.print_exc()
221 221 raise IOError, "The file %s can't be opened" %(filename)
222 222 #chino rata
223 223 #In case has utctime attribute
224 224 grp2 = grp1['utctime']
225 225 # thisUtcTime = grp2.value[0] - 5*3600 #To convert to local time
226 226 thisUtcTime = grp2.value[0]
227 227
228 228 fp.close()
229 229
230 230 if self.timezone == 'lt':
231 231 thisUtcTime -= 5*3600
232 232
233 233 thisDatetime = datetime.datetime.fromtimestamp(thisUtcTime[0] + 5*3600)
234 234 # thisDatetime = datetime.datetime.fromtimestamp(thisUtcTime[0])
235 235 thisDate = thisDatetime.date()
236 236 thisTime = thisDatetime.time()
237 237
238 238 startUtcTime = (datetime.datetime.combine(thisDate,startTime)- datetime.datetime(1970, 1, 1)).total_seconds()
239 239 endUtcTime = (datetime.datetime.combine(thisDate,endTime)- datetime.datetime(1970, 1, 1)).total_seconds()
240 240
241 241 #General case
242 242 # o>>>>>>>>>>>>>><<<<<<<<<<<<<<o
243 243 #-----------o----------------------------o-----------
244 244 # startTime endTime
245 245
246 246 if endTime >= startTime:
247 247 thisUtcLog = numpy.logical_and(thisUtcTime > startUtcTime, thisUtcTime < endUtcTime)
248 248 if numpy.any(thisUtcLog): #If there is one block between the hours mentioned
249 249 return thisDatetime
250 250 return None
251 251
252 252 #If endTime < startTime then endTime belongs to the next day
253 253 #<<<<<<<<<<<o o>>>>>>>>>>>
254 254 #-----------o----------------------------o-----------
255 255 # endTime startTime
256 256
257 257 if (thisDate == startDate) and numpy.all(thisUtcTime < startUtcTime):
258 258 return None
259 259
260 260 if (thisDate == endDate) and numpy.all(thisUtcTime > endUtcTime):
261 261 return None
262 262
263 263 if numpy.all(thisUtcTime < startUtcTime) and numpy.all(thisUtcTime > endUtcTime):
264 264 return None
265 265
266 266 return thisDatetime
267 267
268 268 def __setNextFileOffline(self):
269 269
270 270 self.fileIndex += 1
271 271 idFile = self.fileIndex
272 272
273 273 if not(idFile < len(self.filenameList)):
274 274 print "No more Files"
275 275 return 0
276 276
277 277 filename = self.filenameList[idFile]
278 278
279 279 filePointer = h5py.File(filename,'r')
280 280
281 281 self.filename = filename
282 282
283 283 self.fp = filePointer
284 284
285 285 print "Setting the file: %s"%self.filename
286 286
287 287 # self.__readMetadata()
288 288 self.__setBlockList()
289 289 self.__readData()
290 290 # self.nRecords = self.fp['Data'].attrs['blocksPerFile']
291 291 # self.nRecords = self.fp['Data'].attrs['nRecords']
292 292 self.blockIndex = 0
293 293 return 1
294 294
295 295 def __setBlockList(self):
296 296 '''
297 297 Selects the data within the times defined
298 298
299 299 self.fp
300 300 self.startTime
301 301 self.endTime
302 302
303 303 self.blockList
304 304 self.blocksPerFile
305 305
306 306 '''
307 307 fp = self.fp
308 308 startTime = self.startTime
309 309 endTime = self.endTime
310 310
311 311 grp = fp['Data']
312 312 thisUtcTime = grp['utctime'].value.astype(numpy.float)[0]
313 313
314 314 #ERROOOOR
315 315 if self.timezone == 'lt':
316 316 thisUtcTime -= 5*3600
317 317
318 318 thisDatetime = datetime.datetime.fromtimestamp(thisUtcTime[0] + 5*3600)
319 319
320 320 thisDate = thisDatetime.date()
321 321 thisTime = thisDatetime.time()
322 322
323 323 startUtcTime = (datetime.datetime.combine(thisDate,startTime) - datetime.datetime(1970, 1, 1)).total_seconds()
324 324 endUtcTime = (datetime.datetime.combine(thisDate,endTime) - datetime.datetime(1970, 1, 1)).total_seconds()
325 325
326 326 ind = numpy.where(numpy.logical_and(thisUtcTime >= startUtcTime, thisUtcTime < endUtcTime))[0]
327 327
328 328 self.blockList = ind
329 329 self.blocksPerFile = len(ind)
330 330
331 331 return
332 332
333 333 def __readMetadata(self):
334 334 '''
335 335 Reads Metadata
336 336
337 337 self.pathMeta
338 338
339 339 self.listShapes
340 340 self.listMetaname
341 341 self.listMeta
342 342
343 343 '''
344 344
345 345 # grp = self.fp['Data']
346 346 # pathMeta = os.path.join(self.path, grp.attrs['metadata'])
347 347 #
348 348 # if pathMeta == self.pathMeta:
349 349 # return
350 350 # else:
351 351 # self.pathMeta = pathMeta
352 352 #
353 353 # filePointer = h5py.File(self.pathMeta,'r')
354 354 # groupPointer = filePointer['Metadata']
355 355
356 356 filename = self.filenameList[0]
357 357
358 358 fp = h5py.File(filename,'r')
359 359
360 360 gp = fp['Metadata']
361 361
362 362 listMetaname = []
363 363 listMetadata = []
364 364 for item in gp.items():
365 365 name = item[0]
366 366
367 367 if name=='array dimensions':
368 368 table = gp[name][:]
369 369 listShapes = {}
370 370 for shapes in table:
371 371 listShapes[shapes[0]] = numpy.array([shapes[1],shapes[2],shapes[3],shapes[4],shapes[5]])
372 372 else:
373 373 data = gp[name].value
374 374 listMetaname.append(name)
375 375 listMetadata.append(data)
376 376
377 377 # if name=='type':
378 378 # self.__initDataOut(data)
379 379
380 380 self.listShapes = listShapes
381 381 self.listMetaname = listMetaname
382 382 self.listMeta = listMetadata
383 383
384 384 fp.close()
385 385 return
386 386
387 387 def __readData(self):
388 388 grp = self.fp['Data']
389 389 listdataname = []
390 390 listdata = []
391 391
392 392 for item in grp.items():
393 393 name = item[0]
394 394 listdataname.append(name)
395 395
396 396 array = self.__setDataArray(grp[name],self.listShapes[name])
397 397 listdata.append(array)
398 398
399 399 self.listDataname = listdataname
400 400 self.listData = listdata
401 401 return
402 402
403 403 def __setDataArray(self, dataset, shapes):
404 404
405 405 nDims = shapes[0]
406 406
407 407 nDim2 = shapes[1] #Dimension 0
408 408
409 409 nDim1 = shapes[2] #Dimension 1, number of Points or Parameters
410 410
411 411 nDim0 = shapes[3] #Dimension 2, number of samples or ranges
412 412
413 413 mode = shapes[4] #Mode of storing
414 414
415 415 blockList = self.blockList
416 416
417 417 blocksPerFile = self.blocksPerFile
418 418
419 419 #Depending on what mode the data was stored
420 420 if mode == 0: #Divided in channels
421 421 arrayData = dataset.value.astype(numpy.float)[0][blockList]
422 422 if mode == 1: #Divided in parameter
423 423 strds = 'table'
424 424 nDatas = nDim1
425 425 newShapes = (blocksPerFile,nDim2,nDim0)
426 426 elif mode==2: #Concatenated in a table
427 427 strds = 'table0'
428 428 arrayData = dataset[strds].value
429 429 #Selecting part of the dataset
430 430 utctime = arrayData[:,0]
431 431 u, indices = numpy.unique(utctime, return_index=True)
432 432
433 433 if blockList.size != indices.size:
434 434 indMin = indices[blockList[0]]
435 435 if blockList[1] + 1 >= indices.size:
436 436 arrayData = arrayData[indMin:,:]
437 437 else:
438 438 indMax = indices[blockList[1] + 1]
439 439 arrayData = arrayData[indMin:indMax,:]
440 440 return arrayData
441 441
442 442 # One dimension
443 443 if nDims == 0:
444 444 arrayData = dataset.value.astype(numpy.float)[0][blockList]
445 445
446 446 # Two dimensions
447 447 elif nDims == 2:
448 448 arrayData = numpy.zeros((blocksPerFile,nDim1,nDim0))
449 449 newShapes = (blocksPerFile,nDim0)
450 450 nDatas = nDim1
451 451
452 452 for i in range(nDatas):
453 453 data = dataset[strds + str(i)].value
454 454 arrayData[:,i,:] = data[blockList,:]
455 455
456 456 # Three dimensions
457 457 else:
458 458 arrayData = numpy.zeros((blocksPerFile,nDim2,nDim1,nDim0))
459 459 for i in range(nDatas):
460 460
461 461 data = dataset[strds + str(i)].value
462 462
463 463 for b in range(blockList.size):
464 464 arrayData[b,:,i,:] = data[:,:,blockList[b]]
465 465
466 466 return arrayData
467 467
468 468 def __setDataOut(self):
469 469 listMeta = self.listMeta
470 470 listMetaname = self.listMetaname
471 471 listDataname = self.listDataname
472 472 listData = self.listData
473 473 listShapes = self.listShapes
474 474
475 475 blockIndex = self.blockIndex
476 476 # blockList = self.blockList
477 477
478 478 for i in range(len(listMeta)):
479 479 setattr(self.dataOut,listMetaname[i],listMeta[i])
480 480
481 481 for j in range(len(listData)):
482 482 nShapes = listShapes[listDataname[j]][0]
483 483 mode = listShapes[listDataname[j]][4]
484 484 if nShapes == 1:
485 485 setattr(self.dataOut,listDataname[j],listData[j][blockIndex])
486 486 elif nShapes > 1:
487 487 setattr(self.dataOut,listDataname[j],listData[j][blockIndex,:])
488 488 elif mode==0:
489 489 setattr(self.dataOut,listDataname[j],listData[j][blockIndex])
490 490 #Mode Meteors
491 491 elif mode ==2:
492 492 selectedData = self.__selectDataMode2(listData[j], blockIndex)
493 493 setattr(self.dataOut, listDataname[j], selectedData)
494 494 return
495 495
496 496 def __selectDataMode2(self, data, blockIndex):
497 497 utctime = data[:,0]
498 498 aux, indices = numpy.unique(utctime, return_inverse=True)
499 499 selInd = numpy.where(indices == blockIndex)[0]
500 500 selData = data[selInd,:]
501 501
502 502 return selData
503 503
504 504 def getData(self):
505 505
506 506 # if self.flagNoMoreFiles:
507 507 # self.dataOut.flagNoData = True
508 508 # print 'Process finished'
509 509 # return 0
510 510 #
511 511 if self.blockIndex==self.blocksPerFile:
512 512 if not( self.__setNextFileOffline() ):
513 513 self.dataOut.flagNoData = True
514 514 return 0
515 515
516 516 # if self.datablock == None: # setear esta condicion cuando no hayan datos por leers
517 517 # self.dataOut.flagNoData = True
518 518 # return 0
519 519 # self.__readData()
520 520 self.__setDataOut()
521 521 self.dataOut.flagNoData = False
522 522
523 523 self.blockIndex += 1
524 524
525 525 return
526 526
527 527 def run(self, **kwargs):
528 528
529 529 if not(self.isConfig):
530 530 self.setup(**kwargs)
531 531 # self.setObjProperties()
532 532 self.isConfig = True
533 533
534 534 self.getData()
535 535
536 536 return
537 537
538 538 class ParamWriter(Operation):
539 539 '''
540 540 HDF5 Writer, stores parameters data in HDF5 format files
541 541
542 542 path: path where the files will be stored
543 543
544 544 blocksPerFile: number of blocks that will be saved in per HDF5 format file
545 545
546 546 mode: selects the data stacking mode: '0' channels, '1' parameters, '3' table (for meteors)
547 547
548 548 metadataList: list of attributes that will be stored as metadata
549 549
550 550 dataList: list of attributes that will be stores as data
551 551
552 552 '''
553 553
554 554
555 555 ext = ".hdf5"
556 556
557 557 optchar = "D"
558 558
559 559 metaoptchar = "M"
560 560
561 561 metaFile = None
562 562
563 563 filename = None
564 564
565 565 path = None
566 566
567 567 setFile = None
568 568
569 569 fp = None
570 570
571 571 grp = None
572 572
573 573 ds = None
574 574
575 575 firsttime = True
576 576
577 577 #Configurations
578 578
579 579 blocksPerFile = None
580 580
581 581 blockIndex = None
582 582
583 583 dataOut = None
584 584
585 585 #Data Arrays
586 586
587 587 dataList = None
588 588
589 589 metadataList = None
590 590
591 591 # arrayDim = None
592 592
593 593 dsList = None #List of dictionaries with dataset properties
594 594
595 595 tableDim = None
596 596
597 597 # dtype = [('arrayName', 'S20'),('nChannels', 'i'), ('nPoints', 'i'), ('nSamples', 'i'),('mode', 'b')]
598 598
599 599 dtype = [('arrayName', 'S20'),('nDimensions', 'i'), ('dim2', 'i'), ('dim1', 'i'),('dim0', 'i'),('mode', 'b')]
600 600
601 601 currentDay = None
602 602
603 603 lastTime = None
604 604
605 parameters = {
606 'path': global_type_string,
607 'blocksPerFile':global_type_integer,
608 'metadataList': global_type_list,
609 'dataList': global_type_list,
610 'mode': global_type_integer,
611 }
612
605 613 def __init__(self, **kwargs):
606 614 Operation.__init__(self, **kwargs)
607 615 self.isConfig = False
608 616 return
609 617
610 def setup(self, dataOut, **kwargs):
611
612 self.path = kwargs['path']
613 self.setType = kwargs.get('setType', None)
614
615 if kwargs.has_key('blocksPerFile'):
616 self.blocksPerFile = kwargs['blocksPerFile']
617 else:
618 self.blocksPerFile = 10
619
620 self.metadataList = kwargs['metadataList']
621 self.dataList = kwargs['dataList']
618 def setup(self, dataOut, path=None, blocksPerFile=10, metadataList=None, dataList=None, mode=None, **kwargs):
619 self.path = path
620 self.blocksPerFile = blocksPerFile
621 self.metadataList = metadataList
622 self.dataList = dataList
622 623 self.dataOut = dataOut
623
624 if kwargs.has_key('mode'):
625 mode = kwargs['mode']
626
627 if type(mode) == int:
628 mode = numpy.zeros(len(self.dataList)) + mode
629 else:
630 mode = numpy.ones(len(self.dataList))
631
632 624 self.mode = mode
625
626 if self.mode is not None:
627 self.mode = numpy.zeros(len(self.dataList)) + mode
628 else:
629 self.mode = numpy.ones(len(self.dataList))
633 630
634 631 arrayDim = numpy.zeros((len(self.dataList),5))
635 632
636 633 #Table dimensions
637 634 dtype0 = self.dtype
638 635 tableList = []
639 636
640 637 #Dictionary and list of tables
641 638 dsList = []
642 639
643 640 for i in range(len(self.dataList)):
644 641 dsDict = {}
645 642 dataAux = getattr(self.dataOut, self.dataList[i])
646 643 dsDict['variable'] = self.dataList[i]
647 644 #--------------------- Conditionals ------------------------
648 645 #There is no data
649 646 if dataAux is None:
650 647 return 0
651 648
652 649 #Not array, just a number
653 650 #Mode 0
654 651 if type(dataAux)==float or type(dataAux)==int:
655 652 dsDict['mode'] = 0
656 653 dsDict['nDim'] = 0
657 654 arrayDim[i,0] = 0
658 655 dsList.append(dsDict)
659 656
660 657 #Mode 2: meteors
661 658 elif mode[i] == 2:
662 659 # dsDict['nDim'] = 0
663 660 dsDict['dsName'] = 'table0'
664 661 dsDict['mode'] = 2 # Mode meteors
665 662 dsDict['shape'] = dataAux.shape[-1]
666 663 dsDict['nDim'] = 0
667 664 dsDict['dsNumber'] = 1
668 665
669 666 arrayDim[i,3] = dataAux.shape[-1]
670 667 arrayDim[i,4] = mode[i] #Mode the data was stored
671 668
672 669 dsList.append(dsDict)
673 670
674 671 #Mode 1
675 672 else:
676 673 arrayDim0 = dataAux.shape #Data dimensions
677 674 arrayDim[i,0] = len(arrayDim0) #Number of array dimensions
678 675 arrayDim[i,4] = mode[i] #Mode the data was stored
679 676
680 677 strtable = 'table'
681 678 dsDict['mode'] = 1 # Mode parameters
682 679
683 680 # Three-dimension arrays
684 681 if len(arrayDim0) == 3:
685 682 arrayDim[i,1:-1] = numpy.array(arrayDim0)
686 683 nTables = int(arrayDim[i,2])
687 684 dsDict['dsNumber'] = nTables
688 685 dsDict['shape'] = arrayDim[i,2:4]
689 686 dsDict['nDim'] = 3
690 687
691 688 for j in range(nTables):
692 689 dsDict = dsDict.copy()
693 690 dsDict['dsName'] = strtable + str(j)
694 691 dsList.append(dsDict)
695 692
696 693 # Two-dimension arrays
697 694 elif len(arrayDim0) == 2:
698 695 arrayDim[i,2:-1] = numpy.array(arrayDim0)
699 696 nTables = int(arrayDim[i,2])
700 697 dsDict['dsNumber'] = nTables
701 698 dsDict['shape'] = arrayDim[i,3]
702 699 dsDict['nDim'] = 2
703 700
704 701 for j in range(nTables):
705 702 dsDict = dsDict.copy()
706 703 dsDict['dsName'] = strtable + str(j)
707 704 dsList.append(dsDict)
708 705
709 706 # One-dimension arrays
710 707 elif len(arrayDim0) == 1:
711 708 arrayDim[i,3] = arrayDim0[0]
712 709 dsDict['shape'] = arrayDim0[0]
713 710 dsDict['dsNumber'] = 1
714 711 dsDict['dsName'] = strtable + str(0)
715 712 dsDict['nDim'] = 1
716 713 dsList.append(dsDict)
717 714
718 715 table = numpy.array((self.dataList[i],) + tuple(arrayDim[i,:]),dtype = dtype0)
719 716 tableList.append(table)
720 717
721 718 # self.arrayDim = arrayDim
722 719 self.dsList = dsList
723 720 self.tableDim = numpy.array(tableList, dtype = dtype0)
724 721 self.blockIndex = 0
725 722
726 723 timeTuple = time.localtime(dataOut.utctime)
727 724 self.currentDay = timeTuple.tm_yday
728 725 return 1
729 726
730 727 def putMetadata(self):
731 728
732 729 fp = self.createMetadataFile()
733 730 self.writeMetadata(fp)
734 731 fp.close()
735 732 return
736 733
737 734 def createMetadataFile(self):
738 735 ext = self.ext
739 736 path = self.path
740 737 setFile = self.setFile
741 738
742 739 timeTuple = time.localtime(self.dataOut.utctime)
743 740
744 741 subfolder = ''
745 742 fullpath = os.path.join( path, subfolder )
746 743
747 744 if not( os.path.exists(fullpath) ):
748 745 os.mkdir(fullpath)
749 746 setFile = -1 #inicializo mi contador de seteo
750 747
751 748 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
752 749 fullpath = os.path.join( path, subfolder )
753 750
754 751 if not( os.path.exists(fullpath) ):
755 752 os.mkdir(fullpath)
756 753 setFile = -1 #inicializo mi contador de seteo
757 754
758 755 else:
759 756 filesList = os.listdir( fullpath )
760 757 filesList = sorted( filesList, key=str.lower )
761 758 if len( filesList ) > 0:
762 759 filesList = [k for k in filesList if 'M' in k]
763 760 filen = filesList[-1]
764 761 # el filename debera tener el siguiente formato
765 762 # 0 1234 567 89A BCDE (hex)
766 763 # x YYYY DDD SSS .ext
767 764 if isNumber( filen[8:11] ):
768 765 setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
769 766 else:
770 767 setFile = -1
771 768 else:
772 769 setFile = -1 #inicializo mi contador de seteo
773 770
774 771 if self.setType is None:
775 772 setFile += 1
776 773 file = '%s%4.4d%3.3d%03d%s' % (self.metaoptchar,
777 774 timeTuple.tm_year,
778 775 timeTuple.tm_yday,
779 776 setFile,
780 777 ext )
781 778 else:
782 779 setFile = timeTuple.tm_hour*60+timeTuple.tm_min
783 780 file = '%s%4.4d%3.3d%04d%s' % (self.metaoptchar,
784 781 timeTuple.tm_year,
785 782 timeTuple.tm_yday,
786 783 setFile,
787 784 ext )
788 785
789 786 filename = os.path.join( path, subfolder, file )
790 787 self.metaFile = file
791 788 #Setting HDF5 File
792 789 fp = h5py.File(filename,'w')
793 790
794 791 return fp
795 792
796 793 def writeMetadata(self, fp):
797 794
798 795 grp = fp.create_group("Metadata")
799 796 grp.create_dataset('array dimensions', data = self.tableDim, dtype = self.dtype)
800 797
801 798 for i in range(len(self.metadataList)):
802 799 grp.create_dataset(self.metadataList[i], data=getattr(self.dataOut, self.metadataList[i]))
803 800 return
804 801
805 802 def timeFlag(self):
806 803 currentTime = self.dataOut.utctime
807 804
808 805 if self.lastTime is None:
809 806 self.lastTime = currentTime
810 807
811 808 #Day
812 809 timeTuple = time.localtime(currentTime)
813 810 dataDay = timeTuple.tm_yday
814 811
815 812 #Time
816 813 timeDiff = currentTime - self.lastTime
817 814
818 815 #Si el dia es diferente o si la diferencia entre un dato y otro supera la hora
819 816 if dataDay != self.currentDay:
820 817 self.currentDay = dataDay
821 818 return True
822 819 elif timeDiff > 3*60*60:
823 820 self.lastTime = currentTime
824 821 return True
825 822 else:
826 823 self.lastTime = currentTime
827 824 return False
828 825
829 826 def setNextFile(self):
830 827
831 828 ext = self.ext
832 829 path = self.path
833 830 setFile = self.setFile
834 831 mode = self.mode
835 832
836 833 timeTuple = time.localtime(self.dataOut.utctime)
837 834 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
838 835
839 836 fullpath = os.path.join( path, subfolder )
840 837
841 838 if os.path.exists(fullpath):
842 839 filesList = os.listdir( fullpath )
843 840 filesList = [k for k in filesList if 'D' in k]
844 841 if len( filesList ) > 0:
845 842 filesList = sorted( filesList, key=str.lower )
846 843 filen = filesList[-1]
847 844 # el filename debera tener el siguiente formato
848 845 # 0 1234 567 89A BCDE (hex)
849 846 # x YYYY DDD SSS .ext
850 847 if isNumber( filen[8:11] ):
851 848 setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
852 849 else:
853 850 setFile = -1
854 851 else:
855 852 setFile = -1 #inicializo mi contador de seteo
856 853 else:
857 854 os.makedirs(fullpath)
858 855 setFile = -1 #inicializo mi contador de seteo
859 856
860 857 if self.setType is None:
861 858 setFile += 1
862 859 file = '%s%4.4d%3.3d%03d%s' % (self.metaoptchar,
863 860 timeTuple.tm_year,
864 861 timeTuple.tm_yday,
865 862 setFile,
866 863 ext )
867 864 else:
868 865 setFile = timeTuple.tm_hour*60+timeTuple.tm_min
869 866 file = '%s%4.4d%3.3d%04d%s' % (self.metaoptchar,
870 867 timeTuple.tm_year,
871 868 timeTuple.tm_yday,
872 869 setFile,
873 870 ext )
874 871
875 872 filename = os.path.join( path, subfolder, file )
876 873
877 874 #Setting HDF5 File
878 875 fp = h5py.File(filename,'w')
879 876 #write metadata
880 877 self.writeMetadata(fp)
881 878 #Write data
882 879 grp = fp.create_group("Data")
883 880 # grp.attrs['metadata'] = self.metaFile
884 881
885 882 # grp.attrs['blocksPerFile'] = 0
886 883 ds = []
887 884 data = []
888 885 dsList = self.dsList
889 886 i = 0
890 887 while i < len(dsList):
891 888 dsInfo = dsList[i]
892 889 #One-dimension data
893 890 if dsInfo['mode'] == 0:
894 891 # ds0 = grp.create_dataset(self.dataList[i], (1,1), maxshape=(1,self.blocksPerFile) , chunks = True, dtype='S20')
895 892 ds0 = grp.create_dataset(dsInfo['variable'], (1,1), maxshape=(1,self.blocksPerFile) , chunks = True, dtype=numpy.float64)
896 893 ds.append(ds0)
897 894 data.append([])
898 895 i += 1
899 896 continue
900 897 # nDimsForDs.append(nDims[i])
901 898
902 899 elif dsInfo['mode'] == 2:
903 900 grp0 = grp.create_group(dsInfo['variable'])
904 901 ds0 = grp0.create_dataset(dsInfo['dsName'], (1,dsInfo['shape']), data = numpy.zeros((1,dsInfo['shape'])) , maxshape=(None,dsInfo['shape']), chunks=True)
905 902 ds.append(ds0)
906 903 data.append([])
907 904 i += 1
908 905 continue
909 906
910 907 elif dsInfo['mode'] == 1:
911 908 grp0 = grp.create_group(dsInfo['variable'])
912 909
913 910 for j in range(dsInfo['dsNumber']):
914 911 dsInfo = dsList[i]
915 912 tableName = dsInfo['dsName']
916 913 shape = int(dsInfo['shape'])
917 914
918 915 if dsInfo['nDim'] == 3:
919 916 ds0 = grp0.create_dataset(tableName, (shape[0],shape[1],1) , data = numpy.zeros((shape[0],shape[1],1)), maxshape = (None,shape[1],None), chunks=True)
920 917 else:
921 918 ds0 = grp0.create_dataset(tableName, (1,shape), data = numpy.zeros((1,shape)) , maxshape=(None,shape), chunks=True)
922 919
923 920 ds.append(ds0)
924 921 data.append([])
925 922 i += 1
926 923 # nDimsForDs.append(nDims[i])
927 924
928 925 fp.flush()
929 926 fp.close()
930 927
931 928 # self.nDatas = nDatas
932 929 # self.nDims = nDims
933 930 # self.nDimsForDs = nDimsForDs
934 931 #Saving variables
935 932 print 'Writing the file: %s'%filename
936 933 self.filename = filename
937 934 # self.fp = fp
938 935 # self.grp = grp
939 936 # self.grp.attrs.modify('nRecords', 1)
940 937 self.ds = ds
941 938 self.data = data
942 939 # self.setFile = setFile
943 940 self.firsttime = True
944 941 self.blockIndex = 0
945 942 return
946 943
947 944 def putData(self):
948 945
949 946 if self.blockIndex == self.blocksPerFile or self.timeFlag():
950 947 self.setNextFile()
951 948
952 949 # if not self.firsttime:
953 950 self.readBlock()
954 951 self.setBlock() #Prepare data to be written
955 952 self.writeBlock() #Write data
956 953
957 954 return
958 955
959 956 def readBlock(self):
960 957
961 958 '''
962 959 data Array configured
963 960
964 961
965 962 self.data
966 963 '''
967 964 dsList = self.dsList
968 965 ds = self.ds
969 966 #Setting HDF5 File
970 967 fp = h5py.File(self.filename,'r+')
971 968 grp = fp["Data"]
972 969 ind = 0
973 970
974 971 # grp.attrs['blocksPerFile'] = 0
975 972 while ind < len(dsList):
976 973 dsInfo = dsList[ind]
977 974
978 975 if dsInfo['mode'] == 0:
979 976 ds0 = grp[dsInfo['variable']]
980 977 ds[ind] = ds0
981 978 ind += 1
982 979 else:
983 980
984 981 grp0 = grp[dsInfo['variable']]
985 982
986 983 for j in range(dsInfo['dsNumber']):
987 984 dsInfo = dsList[ind]
988 985 ds0 = grp0[dsInfo['dsName']]
989 986 ds[ind] = ds0
990 987 ind += 1
991 988
992 989 self.fp = fp
993 990 self.grp = grp
994 991 self.ds = ds
995 992
996 993 return
997 994
998 995 def setBlock(self):
999 996 '''
1000 997 data Array configured
1001 998
1002 999
1003 1000 self.data
1004 1001 '''
1005 1002 #Creating Arrays
1006 1003 dsList = self.dsList
1007 1004 data = self.data
1008 1005 ind = 0
1009 1006
1010 1007 while ind < len(dsList):
1011 1008 dsInfo = dsList[ind]
1012 1009 dataAux = getattr(self.dataOut, dsInfo['variable'])
1013 1010
1014 1011 mode = dsInfo['mode']
1015 1012 nDim = dsInfo['nDim']
1016 1013
1017 1014 if mode == 0 or mode == 2 or nDim == 1:
1018 1015 data[ind] = dataAux
1019 1016 ind += 1
1020 1017 # elif nDim == 1:
1021 1018 # data[ind] = numpy.reshape(dataAux,(numpy.size(dataAux),1))
1022 1019 # ind += 1
1023 1020 elif nDim == 2:
1024 1021 for j in range(dsInfo['dsNumber']):
1025 1022 data[ind] = dataAux[j,:]
1026 1023 ind += 1
1027 1024 elif nDim == 3:
1028 1025 for j in range(dsInfo['dsNumber']):
1029 1026 data[ind] = dataAux[:,j,:]
1030 1027 ind += 1
1031 1028
1032 1029 self.data = data
1033 1030 return
1034 1031
1035 1032 def writeBlock(self):
1036 1033 '''
1037 1034 Saves the block in the HDF5 file
1038 1035 '''
1039 1036 dsList = self.dsList
1040 1037
1041 1038 for i in range(len(self.ds)):
1042 1039 dsInfo = dsList[i]
1043 1040 nDim = dsInfo['nDim']
1044 1041 mode = dsInfo['mode']
1045 1042
1046 1043 # First time
1047 1044 if self.firsttime:
1048 1045 # self.ds[i].resize(self.data[i].shape)
1049 1046 # self.ds[i][self.blockIndex,:] = self.data[i]
1050 1047 if type(self.data[i]) == numpy.ndarray:
1051 1048
1052 1049 if nDim == 3:
1053 1050 self.data[i] = self.data[i].reshape((self.data[i].shape[0],self.data[i].shape[1],1))
1054 1051 self.ds[i].resize(self.data[i].shape)
1055 1052 if mode == 2:
1056 1053 self.ds[i].resize(self.data[i].shape)
1057 1054 self.ds[i][:] = self.data[i]
1058 1055 else:
1059 1056
1060 1057 # From second time
1061 1058 # Meteors!
1062 1059 if mode == 2:
1063 1060 dataShape = self.data[i].shape
1064 1061 dsShape = self.ds[i].shape
1065 1062 self.ds[i].resize((self.ds[i].shape[0] + dataShape[0],self.ds[i].shape[1]))
1066 1063 self.ds[i][dsShape[0]:,:] = self.data[i]
1067 1064 # No dimension
1068 1065 elif mode == 0:
1069 1066 self.ds[i].resize((self.ds[i].shape[0], self.ds[i].shape[1] + 1))
1070 1067 self.ds[i][0,-1] = self.data[i]
1071 1068 # One dimension
1072 1069 elif nDim == 1:
1073 1070 self.ds[i].resize((self.ds[i].shape[0] + 1, self.ds[i].shape[1]))
1074 1071 self.ds[i][-1,:] = self.data[i]
1075 1072 # Two dimension
1076 1073 elif nDim == 2:
1077 1074 self.ds[i].resize((self.ds[i].shape[0] + 1,self.ds[i].shape[1]))
1078 1075 self.ds[i][self.blockIndex,:] = self.data[i]
1079 1076 # Three dimensions
1080 1077 elif nDim == 3:
1081 1078 self.ds[i].resize((self.ds[i].shape[0],self.ds[i].shape[1],self.ds[i].shape[2]+1))
1082 1079 self.ds[i][:,:,-1] = self.data[i]
1083 1080
1084 1081 self.firsttime = False
1085 1082 self.blockIndex += 1
1086 1083
1087 1084 #Close to save changes
1088 1085 self.fp.flush()
1089 1086 self.fp.close()
1090 1087 return
1091 1088
1092 def run(self, dataOut, **kwargs):
1089 def run(self, dataOut, path=None, blocksPerFile=10, metadataList=None, dataList=None, mode=None, **kwargs):
1093 1090
1094 1091 if not(self.isConfig):
1095 flagdata = self.setup(dataOut, **kwargs)
1092 flagdata = self.setup(dataOut, path=path, blocksPerFile=blocksPerFile,
1093 metadataList=metadataList, dataList=dataList, mode=mode, **kwargs)
1096 1094
1097 1095 if not(flagdata):
1098 1096 return
1099 1097
1100 1098 self.isConfig = True
1101 1099 # self.putMetadata()
1102 1100 self.setNextFile()
1103 1101
1104 1102 self.putData()
1105 1103 return
@@ -1,141 +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 parameters = {
45 'beam': global_type_string,
46 }
44 47
45 48 def __init__(self):
46 49
47 50 self.profileIndex = 0
48 51 self.__isConfig = False
49 52
50 53 def incIndex(self):
51 54 self.profileIndex += 1
52 55
53 56 if self.profileIndex >= self.nProfiles:
54 57 self.profileIndex = 0
55 58
56 59 def isProfileInRange(self, minIndex, maxIndex):
57 60
58 61 if self.profileIndex < minIndex:
59 62 return False
60 63
61 64 if self.profileIndex > maxIndex:
62 65 return False
63 66
64 67 return True
65 68
66 69 def isProfileInList(self, profileList):
67 70
68 71 if self.profileIndex not in profileList:
69 72 return False
70 73
71 74 return True
72 75
73 76 def run(self, dataOut, beam=None):
74 77
75 78 dataOut.flagNoData = True
76 79
77 80 if not(self.__isConfig):
78 81
79 82 self.nProfiles = dataOut.nProfiles
80 83 self.profileIndex = dataOut.profileIndex
81 84 self.__isConfig = True
82 85
83 86 if beam != None:
84 87 if self.isProfileInList(dataOut.beamRangeDict[beam]):
85 88 beamInfo = dataOut.beamCodeDict[beam]
86 89 dataOut.azimuth = beamInfo[1]
87 90 dataOut.zenith = beamInfo[2]
88 91 dataOut.gain = beamInfo[3]
89 92 dataOut.flagNoData = False
90 93
91 94 self.incIndex()
92 95 return 1
93 96
94 97 else:
95 98 raise ValueError, "BeamSelector needs beam value"
96 99
97 100 return 0
98 101
99 102 class ProfileToChannels(Operation):
100 103
101 104 def __init__(self):
102 105 self.__isConfig = False
103 106 self.__counter_chan = 0
104 107 self.buffer = None
105 108
106 109 def isProfileInList(self, profileList):
107 110
108 111 if self.profileIndex not in profileList:
109 112 return False
110 113
111 114 return True
112 115
113 116 def run(self, dataOut):
114 117
115 118 dataOut.flagNoData = True
116 119
117 120 if not(self.__isConfig):
118 121 nchannels = len(dataOut.beamRangeDict.keys())
119 122 nsamples = dataOut.nHeights
120 123 self.buffer = numpy.zeros((nchannels, nsamples), dtype = 'complex128')
121 124 dataOut.beam.codeList = [dataOut.beamCodeDict[x][0] for x in range(nchannels)]
122 125 dataOut.beam.azimuthList = [dataOut.beamCodeDict[x][1] for x in range(nchannels)]
123 126 dataOut.beam.zenithList = [dataOut.beamCodeDict[x][2] for x in range(nchannels)]
124 127 self.__isConfig = True
125 128
126 129 for i in range(self.buffer.shape[0]):
127 130 if dataOut.profileIndex in dataOut.beamRangeDict[i]:
128 131 self.buffer[i,:] = dataOut.data
129 132 break
130 133
131 134
132 135 self.__counter_chan += 1
133 136
134 137 if self.__counter_chan >= self.buffer.shape[0]:
135 138 self.__counter_chan = 0
136 139 dataOut.data = self.buffer.copy()
137 140 dataOut.channelList = range(self.buffer.shape[0])
138 141 self.__isConfig = False
139 142 dataOut.flagNoData = False
140 143 pass
141 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,2805 +1,2812
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 azimuth = kwargs['azimuth']
1022 1022 theta_x = numpy.array(kwargs['theta_x'])
1023 1023 theta_y = numpy.array(kwargs['theta_y'])
1024 1024
1025 1025 utctime = metArray[:,0]
1026 1026 cmet = metArray[:,1].astype(int)
1027 1027 hmet = metArray[:,3].astype(int)
1028 1028 SNRmet = metArray[:,4]
1029 1029 vmet = metArray[:,5]
1030 1030 spcmet = metArray[:,6]
1031 1031
1032 1032 nChan = numpy.max(cmet) + 1
1033 1033 nHeights = len(heightList)
1034 1034
1035 1035 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
1036 1036 hmet = heightList[hmet]
1037 1037 h1met = hmet*numpy.cos(zenith_arr[cmet]) #Corrected heights
1038 1038
1039 1039 velEst = numpy.zeros((heightList.size,2))*numpy.nan
1040 1040
1041 1041 for i in range(nHeights - 1):
1042 1042 hmin = heightList[i]
1043 1043 hmax = heightList[i + 1]
1044 1044
1045 1045 thisH = (h1met>=hmin) & (h1met<hmax) & (cmet!=2) & (SNRmet>8) & (vmet<50) & (spcmet<10)
1046 1046 indthisH = numpy.where(thisH)
1047 1047
1048 1048 if numpy.size(indthisH) > 3:
1049 1049
1050 1050 vel_aux = vmet[thisH]
1051 1051 chan_aux = cmet[thisH]
1052 1052 cosu_aux = dir_cosu[chan_aux]
1053 1053 cosv_aux = dir_cosv[chan_aux]
1054 1054 cosw_aux = dir_cosw[chan_aux]
1055 1055
1056 1056 nch = numpy.size(numpy.unique(chan_aux))
1057 1057 if nch > 1:
1058 1058 A = self.__calculateMatA(cosu_aux, cosv_aux, cosw_aux, True)
1059 1059 velEst[i,:] = numpy.dot(A,vel_aux)
1060 1060
1061 1061 return velEst
1062 1062
1063 1063 def run(self, dataOut, technique, nHours=1, hmin=70, hmax=110, **kwargs):
1064 1064
1065 1065 param = dataOut.data_param
1066 1066 if dataOut.abscissaList != None:
1067 1067 absc = dataOut.abscissaList[:-1]
1068 1068 # noise = dataOut.noise
1069 1069 heightList = dataOut.heightList
1070 1070 SNR = dataOut.data_SNR
1071 1071
1072 1072 if technique == 'DBS':
1073 1073
1074 1074 kwargs['velRadial'] = param[:,1,:] #Radial velocity
1075 1075 kwargs['heightList'] = heightList
1076 1076 kwargs['SNR'] = SNR
1077 1077
1078 1078 dataOut.data_output, dataOut.heightList, dataOut.data_SNR = self.techniqueDBS(kwargs) #DBS Function
1079 1079 dataOut.utctimeInit = dataOut.utctime
1080 1080 dataOut.outputInterval = dataOut.paramInterval
1081 1081
1082 1082 elif technique == 'SA':
1083 1083
1084 1084 #Parameters
1085 1085 # position_x = kwargs['positionX']
1086 1086 # position_y = kwargs['positionY']
1087 1087 # azimuth = kwargs['azimuth']
1088 1088 #
1089 1089 # if kwargs.has_key('crosspairsList'):
1090 1090 # pairs = kwargs['crosspairsList']
1091 1091 # else:
1092 1092 # pairs = None
1093 1093 #
1094 1094 # if kwargs.has_key('correctFactor'):
1095 1095 # correctFactor = kwargs['correctFactor']
1096 1096 # else:
1097 1097 # correctFactor = 1
1098 1098
1099 1099 # tau = dataOut.data_param
1100 1100 # _lambda = dataOut.C/dataOut.frequency
1101 1101 # pairsList = dataOut.groupList
1102 1102 # nChannels = dataOut.nChannels
1103 1103
1104 1104 kwargs['groupList'] = dataOut.groupList
1105 1105 kwargs['tau'] = dataOut.data_param
1106 1106 kwargs['_lambda'] = dataOut.C/dataOut.frequency
1107 1107 # dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
1108 1108 dataOut.data_output = self.techniqueSA(kwargs)
1109 1109 dataOut.utctimeInit = dataOut.utctime
1110 1110 dataOut.outputInterval = dataOut.timeInterval
1111 1111
1112 1112 elif technique == 'Meteors':
1113 1113 dataOut.flagNoData = True
1114 1114 self.__dataReady = False
1115 1115
1116 1116 if kwargs.has_key('nHours'):
1117 1117 nHours = kwargs['nHours']
1118 1118 else:
1119 1119 nHours = 1
1120 1120
1121 1121 if kwargs.has_key('meteorsPerBin'):
1122 1122 meteorThresh = kwargs['meteorsPerBin']
1123 1123 else:
1124 1124 meteorThresh = 6
1125 1125
1126 1126 if kwargs.has_key('hmin'):
1127 1127 hmin = kwargs['hmin']
1128 1128 else: hmin = 70
1129 1129 if kwargs.has_key('hmax'):
1130 1130 hmax = kwargs['hmax']
1131 1131 else: hmax = 110
1132 1132
1133 1133 if kwargs.has_key('BinKm'):
1134 1134 binkm = kwargs['BinKm']
1135 1135 else:
1136 1136 binkm = 2
1137 1137
1138 1138 dataOut.outputInterval = nHours*3600
1139 1139
1140 1140 if self.__isConfig == False:
1141 1141 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
1142 1142 #Get Initial LTC time
1143 1143 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
1144 1144 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
1145 1145
1146 1146 self.__isConfig = True
1147 1147
1148 1148 if self.__buffer is None:
1149 1149 self.__buffer = dataOut.data_param
1150 1150 self.__firstdata = copy.copy(dataOut)
1151 1151
1152 1152 else:
1153 1153 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
1154 1154
1155 1155 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
1156 1156
1157 1157 if self.__dataReady:
1158 1158 dataOut.utctimeInit = self.__initime
1159 1159
1160 1160 self.__initime += dataOut.outputInterval #to erase time offset
1161 1161
1162 1162 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax, binkm)
1163 1163 dataOut.flagNoData = False
1164 1164 self.__buffer = None
1165 1165
1166 1166 elif technique == 'Meteors1':
1167 1167 dataOut.flagNoData = True
1168 1168 self.__dataReady = False
1169 1169
1170 1170 if kwargs.has_key('nMins'):
1171 1171 nMins = kwargs['nMins']
1172 1172 else: nMins = 20
1173 1173 if kwargs.has_key('rx_location'):
1174 1174 rx_location = kwargs['rx_location']
1175 1175 else: rx_location = [(0,1),(1,1),(1,0)]
1176 1176 if kwargs.has_key('azimuth'):
1177 1177 azimuth = kwargs['azimuth']
1178 1178 else: azimuth = 51.06
1179 1179 if kwargs.has_key('dfactor'):
1180 1180 dfactor = kwargs['dfactor']
1181 1181 if kwargs.has_key('mode'):
1182 1182 mode = kwargs['mode']
1183 1183 if kwargs.has_key('theta_x'):
1184 1184 theta_x = kwargs['theta_x']
1185 1185 if kwargs.has_key('theta_y'):
1186 1186 theta_y = kwargs['theta_y']
1187 1187 else: mode = 'SA'
1188 1188
1189 1189 #Borrar luego esto
1190 1190 if dataOut.groupList is None:
1191 1191 dataOut.groupList = [(0,1),(0,2),(1,2)]
1192 1192 groupList = dataOut.groupList
1193 1193 C = 3e8
1194 1194 freq = 50e6
1195 1195 lamb = C/freq
1196 1196 k = 2*numpy.pi/lamb
1197 1197
1198 1198 timeList = dataOut.abscissaList
1199 1199 heightList = dataOut.heightList
1200 1200
1201 1201 if self.__isConfig == False:
1202 1202 dataOut.outputInterval = nMins*60
1203 1203 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
1204 1204 #Get Initial LTC time
1205 1205 initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
1206 1206 minuteAux = initime.minute
1207 1207 minuteNew = int(numpy.floor(minuteAux/nMins)*nMins)
1208 1208 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
1209 1209
1210 1210 self.__isConfig = True
1211 1211
1212 1212 if self.__buffer is None:
1213 1213 self.__buffer = dataOut.data_param
1214 1214 self.__firstdata = copy.copy(dataOut)
1215 1215
1216 1216 else:
1217 1217 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
1218 1218
1219 1219 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
1220 1220
1221 1221 if self.__dataReady:
1222 1222 dataOut.utctimeInit = self.__initime
1223 1223 self.__initime += dataOut.outputInterval #to erase time offset
1224 1224
1225 1225 metArray = self.__buffer
1226 1226 if mode == 'SA':
1227 1227 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
1228 1228 elif mode == 'DBS':
1229 1229 dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList, azimuth=azimuth, theta_x=theta_x, theta_y=theta_y)
1230 1230 dataOut.data_output = dataOut.data_output.T
1231 1231 dataOut.flagNoData = False
1232 1232 self.__buffer = None
1233 1233
1234 1234 return
1235 1235
1236 1236 class EWDriftsEstimation(Operation):
1237 1237
1238 1238
1239 1239 def __correctValues(self, heiRang, phi, velRadial, SNR):
1240 1240 listPhi = phi.tolist()
1241 1241 maxid = listPhi.index(max(listPhi))
1242 1242 minid = listPhi.index(min(listPhi))
1243 1243
1244 1244 rango = range(len(phi))
1245 1245 # rango = numpy.delete(rango,maxid)
1246 1246
1247 1247 heiRang1 = heiRang*math.cos(phi[maxid])
1248 1248 heiRangAux = heiRang*math.cos(phi[minid])
1249 1249 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1250 1250 heiRang1 = numpy.delete(heiRang1,indOut)
1251 1251
1252 1252 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1253 1253 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1254 1254
1255 1255 for i in rango:
1256 1256 x = heiRang*math.cos(phi[i])
1257 1257 y1 = velRadial[i,:]
1258 1258 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1259 1259
1260 1260 x1 = heiRang1
1261 1261 y11 = f1(x1)
1262 1262
1263 1263 y2 = SNR[i,:]
1264 1264 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1265 1265 y21 = f2(x1)
1266 1266
1267 1267 velRadial1[i,:] = y11
1268 1268 SNR1[i,:] = y21
1269 1269
1270 1270 return heiRang1, velRadial1, SNR1
1271 1271
1272 1272 def run(self, dataOut, zenith, zenithCorrection):
1273 1273 heiRang = dataOut.heightList
1274 1274 velRadial = dataOut.data_param[:,3,:]
1275 1275 SNR = dataOut.data_SNR
1276 1276
1277 1277 zenith = numpy.array(zenith)
1278 1278 zenith -= zenithCorrection
1279 1279 zenith *= numpy.pi/180
1280 1280
1281 1281 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
1282 1282
1283 1283 alp = zenith[0]
1284 1284 bet = zenith[1]
1285 1285
1286 1286 w_w = velRadial1[0,:]
1287 1287 w_e = velRadial1[1,:]
1288 1288
1289 1289 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
1290 1290 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
1291 1291
1292 1292 winds = numpy.vstack((u,w))
1293 1293
1294 1294 dataOut.heightList = heiRang1
1295 1295 dataOut.data_output = winds
1296 1296 dataOut.data_SNR = SNR1
1297 1297
1298 1298 dataOut.utctimeInit = dataOut.utctime
1299 1299 dataOut.outputInterval = dataOut.timeInterval
1300 1300 return
1301 1301
1302 1302 #--------------- Non Specular Meteor ----------------
1303 1303
1304 1304 class NonSpecularMeteorDetection(Operation):
1305 1305
1306 1306 def run(self, dataOut, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False):
1307 1307 data_acf = dataOut.data_pre[0]
1308 1308 data_ccf = dataOut.data_pre[1]
1309 1309 pairsList = dataOut.groupList[1]
1310 1310
1311 1311 lamb = dataOut.C/dataOut.frequency
1312 1312 tSamp = dataOut.ippSeconds*dataOut.nCohInt
1313 1313 paramInterval = dataOut.paramInterval
1314 1314
1315 1315 nChannels = data_acf.shape[0]
1316 1316 nLags = data_acf.shape[1]
1317 1317 nProfiles = data_acf.shape[2]
1318 1318 nHeights = dataOut.nHeights
1319 1319 nCohInt = dataOut.nCohInt
1320 1320 sec = numpy.round(nProfiles/dataOut.paramInterval)
1321 1321 heightList = dataOut.heightList
1322 1322 ippSeconds = dataOut.ippSeconds*dataOut.nCohInt*dataOut.nAvg
1323 1323 utctime = dataOut.utctime
1324 1324
1325 1325 dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
1326 1326
1327 1327 #------------------------ SNR --------------------------------------
1328 1328 power = data_acf[:,0,:,:].real
1329 1329 noise = numpy.zeros(nChannels)
1330 1330 SNR = numpy.zeros(power.shape)
1331 1331 for i in range(nChannels):
1332 1332 noise[i] = hildebrand_sekhon(power[i,:], nCohInt)
1333 1333 SNR[i] = (power[i]-noise[i])/noise[i]
1334 1334 SNRm = numpy.nanmean(SNR, axis = 0)
1335 1335 SNRdB = 10*numpy.log10(SNR)
1336 1336
1337 1337 if mode == 'SA':
1338 1338 dataOut.groupList = dataOut.groupList[1]
1339 1339 nPairs = data_ccf.shape[0]
1340 1340 #---------------------- Coherence and Phase --------------------------
1341 1341 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
1342 1342 # phase1 = numpy.copy(phase)
1343 1343 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
1344 1344
1345 1345 for p in range(nPairs):
1346 1346 ch0 = pairsList[p][0]
1347 1347 ch1 = pairsList[p][1]
1348 1348 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
1349 1349 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
1350 1350 # phase1[p,:,:] = numpy.angle(ccf) #median filter
1351 1351 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
1352 1352 # coh1[p,:,:] = numpy.abs(ccf) #median filter
1353 1353 coh = numpy.nanmax(coh1, axis = 0)
1354 1354 # struc = numpy.ones((5,1))
1355 1355 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
1356 1356 #---------------------- Radial Velocity ----------------------------
1357 1357 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
1358 1358 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
1359 1359
1360 1360 if allData:
1361 1361 boolMetFin = ~numpy.isnan(SNRm)
1362 1362 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
1363 1363 else:
1364 1364 #------------------------ Meteor mask ---------------------------------
1365 1365 # #SNR mask
1366 1366 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
1367 1367 #
1368 1368 # #Erase small objects
1369 1369 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
1370 1370 #
1371 1371 # auxEEJ = numpy.sum(boolMet1,axis=0)
1372 1372 # indOver = auxEEJ>nProfiles*0.8 #Use this later
1373 1373 # indEEJ = numpy.where(indOver)[0]
1374 1374 # indNEEJ = numpy.where(~indOver)[0]
1375 1375 #
1376 1376 # boolMetFin = boolMet1
1377 1377 #
1378 1378 # if indEEJ.size > 0:
1379 1379 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
1380 1380 #
1381 1381 # boolMet2 = coh > cohThresh
1382 1382 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
1383 1383 #
1384 1384 # #Final Meteor mask
1385 1385 # boolMetFin = boolMet1|boolMet2
1386 1386
1387 1387 #Coherence mask
1388 1388 boolMet1 = coh > 0.75
1389 1389 struc = numpy.ones((30,1))
1390 1390 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
1391 1391
1392 1392 #Derivative mask
1393 1393 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
1394 1394 boolMet2 = derPhase < 0.2
1395 1395 # boolMet2 = ndimage.morphology.binary_opening(boolMet2)
1396 1396 # boolMet2 = ndimage.morphology.binary_closing(boolMet2, structure = numpy.ones((10,1)))
1397 1397 boolMet2 = ndimage.median_filter(boolMet2,size=5)
1398 1398 boolMet2 = numpy.vstack((boolMet2,numpy.full((1,nHeights), True, dtype=bool)))
1399 1399 # #Final mask
1400 1400 # boolMetFin = boolMet2
1401 1401 boolMetFin = boolMet1&boolMet2
1402 1402 # boolMetFin = ndimage.morphology.binary_dilation(boolMetFin)
1403 1403 #Creating data_param
1404 1404 coordMet = numpy.where(boolMetFin)
1405 1405
1406 1406 tmet = coordMet[0]
1407 1407 hmet = coordMet[1]
1408 1408
1409 1409 data_param = numpy.zeros((tmet.size, 6 + nPairs))
1410 1410 data_param[:,0] = utctime
1411 1411 data_param[:,1] = tmet
1412 1412 data_param[:,2] = hmet
1413 1413 data_param[:,3] = SNRm[tmet,hmet]
1414 1414 data_param[:,4] = velRad[tmet,hmet]
1415 1415 data_param[:,5] = coh[tmet,hmet]
1416 1416 data_param[:,6:] = phase[:,tmet,hmet].T
1417 1417
1418 1418 elif mode == 'DBS':
1419 1419 dataOut.groupList = numpy.arange(nChannels)
1420 1420
1421 1421 #Radial Velocities
1422 1422 phase = numpy.angle(data_acf[:,1,:,:])
1423 1423 # phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
1424 1424 velRad = phase*lamb/(4*numpy.pi*tSamp)
1425 1425
1426 1426 #Spectral width
1427 1427 # acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
1428 1428 # acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
1429 1429 acf1 = data_acf[:,1,:,:]
1430 1430 acf2 = data_acf[:,2,:,:]
1431 1431
1432 1432 spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2))
1433 1433 # velRad = ndimage.median_filter(velRad, size = (1,5,1))
1434 1434 if allData:
1435 1435 boolMetFin = ~numpy.isnan(SNRdB)
1436 1436 else:
1437 1437 #SNR
1438 1438 boolMet1 = (SNRdB>SNRthresh) #SNR mask
1439 1439 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
1440 1440
1441 1441 #Radial velocity
1442 1442 boolMet2 = numpy.abs(velRad) < 20
1443 1443 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
1444 1444
1445 1445 #Spectral Width
1446 1446 boolMet3 = spcWidth < 30
1447 1447 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
1448 1448 # boolMetFin = self.__erase_small(boolMet1, 10,5)
1449 1449 boolMetFin = boolMet1&boolMet2&boolMet3
1450 1450
1451 1451 #Creating data_param
1452 1452 coordMet = numpy.where(boolMetFin)
1453 1453
1454 1454 cmet = coordMet[0]
1455 1455 tmet = coordMet[1]
1456 1456 hmet = coordMet[2]
1457 1457
1458 1458 data_param = numpy.zeros((tmet.size, 7))
1459 1459 data_param[:,0] = utctime
1460 1460 data_param[:,1] = cmet
1461 1461 data_param[:,2] = tmet
1462 1462 data_param[:,3] = hmet
1463 1463 data_param[:,4] = SNR[cmet,tmet,hmet].T
1464 1464 data_param[:,5] = velRad[cmet,tmet,hmet].T
1465 1465 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
1466 1466
1467 1467 # self.dataOut.data_param = data_int
1468 1468 if len(data_param) == 0:
1469 1469 dataOut.flagNoData = True
1470 1470 else:
1471 1471 dataOut.data_param = data_param
1472 1472
1473 1473 def __erase_small(self, binArray, threshX, threshY):
1474 1474 labarray, numfeat = ndimage.measurements.label(binArray)
1475 1475 binArray1 = numpy.copy(binArray)
1476 1476
1477 1477 for i in range(1,numfeat + 1):
1478 1478 auxBin = (labarray==i)
1479 1479 auxSize = auxBin.sum()
1480 1480
1481 1481 x,y = numpy.where(auxBin)
1482 1482 widthX = x.max() - x.min()
1483 1483 widthY = y.max() - y.min()
1484 1484
1485 1485 #width X: 3 seg -> 12.5*3
1486 1486 #width Y:
1487 1487
1488 1488 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
1489 1489 binArray1[auxBin] = False
1490 1490
1491 1491 return binArray1
1492 1492
1493 1493 #--------------- Specular Meteor ----------------
1494 1494
1495 1495 class SMDetection(Operation):
1496 1496 '''
1497 1497 Function DetectMeteors()
1498 1498 Project developed with paper:
1499 1499 HOLDSWORTH ET AL. 2004
1500 1500
1501 1501 Input:
1502 1502 self.dataOut.data_pre
1503 1503
1504 1504 centerReceiverIndex: From the channels, which is the center receiver
1505 1505
1506 1506 hei_ref: Height reference for the Beacon signal extraction
1507 1507 tauindex:
1508 1508 predefinedPhaseShifts: Predefined phase offset for the voltge signals
1509 1509
1510 1510 cohDetection: Whether to user Coherent detection or not
1511 1511 cohDet_timeStep: Coherent Detection calculation time step
1512 1512 cohDet_thresh: Coherent Detection phase threshold to correct phases
1513 1513
1514 1514 noise_timeStep: Noise calculation time step
1515 1515 noise_multiple: Noise multiple to define signal threshold
1516 1516
1517 1517 multDet_timeLimit: Multiple Detection Removal time limit in seconds
1518 1518 multDet_rangeLimit: Multiple Detection Removal range limit in km
1519 1519
1520 1520 phaseThresh: Maximum phase difference between receiver to be consider a meteor
1521 1521 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
1522 1522
1523 1523 hmin: Minimum Height of the meteor to use it in the further wind estimations
1524 1524 hmax: Maximum Height of the meteor to use it in the further wind estimations
1525 1525 azimuth: Azimuth angle correction
1526 1526
1527 1527 Affected:
1528 1528 self.dataOut.data_param
1529 1529
1530 1530 Rejection Criteria (Errors):
1531 1531 0: No error; analysis OK
1532 1532 1: SNR < SNR threshold
1533 1533 2: angle of arrival (AOA) ambiguously determined
1534 1534 3: AOA estimate not feasible
1535 1535 4: Large difference in AOAs obtained from different antenna baselines
1536 1536 5: echo at start or end of time series
1537 1537 6: echo less than 5 examples long; too short for analysis
1538 1538 7: echo rise exceeds 0.3s
1539 1539 8: echo decay time less than twice rise time
1540 1540 9: large power level before echo
1541 1541 10: large power level after echo
1542 1542 11: poor fit to amplitude for estimation of decay time
1543 1543 12: poor fit to CCF phase variation for estimation of radial drift velocity
1544 1544 13: height unresolvable echo: not valid height within 70 to 110 km
1545 1545 14: height ambiguous echo: more then one possible height within 70 to 110 km
1546 1546 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
1547 1547 16: oscilatory echo, indicating event most likely not an underdense echo
1548 1548
1549 1549 17: phase difference in meteor Reestimation
1550 1550
1551 1551 Data Storage:
1552 1552 Meteors for Wind Estimation (8):
1553 1553 Utc Time | Range Height
1554 1554 Azimuth Zenith errorCosDir
1555 1555 VelRad errorVelRad
1556 1556 Phase0 Phase1 Phase2 Phase3
1557 1557 TypeError
1558 1558
1559 1559 '''
1560 1560
1561 1561 def run(self, dataOut, hei_ref = None, tauindex = 0,
1562 1562 phaseOffsets = None,
1563 1563 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
1564 1564 noise_timeStep = 4, noise_multiple = 4,
1565 1565 multDet_timeLimit = 1, multDet_rangeLimit = 3,
1566 1566 phaseThresh = 20, SNRThresh = 5,
1567 1567 hmin = 50, hmax=150, azimuth = 0,
1568 1568 channelPositions = None) :
1569 1569
1570 1570
1571 1571 #Getting Pairslist
1572 1572 if channelPositions is None:
1573 1573 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
1574 1574 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
1575 1575 meteorOps = SMOperations()
1576 1576 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
1577 1577 heiRang = dataOut.getHeiRange()
1578 1578 #Get Beacon signal - No Beacon signal anymore
1579 1579 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
1580 1580 #
1581 1581 # if hei_ref != None:
1582 1582 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
1583 1583 #
1584 1584
1585 1585
1586 1586 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
1587 1587 # see if the user put in pre defined phase shifts
1588 1588 voltsPShift = dataOut.data_pre.copy()
1589 1589
1590 1590 # if predefinedPhaseShifts != None:
1591 1591 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
1592 1592 #
1593 1593 # # elif beaconPhaseShifts:
1594 1594 # # #get hardware phase shifts using beacon signal
1595 1595 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
1596 1596 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
1597 1597 #
1598 1598 # else:
1599 1599 # hardwarePhaseShifts = numpy.zeros(5)
1600 1600 #
1601 1601 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
1602 1602 # for i in range(self.dataOut.data_pre.shape[0]):
1603 1603 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
1604 1604
1605 1605 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
1606 1606
1607 1607 #Remove DC
1608 1608 voltsDC = numpy.mean(voltsPShift,1)
1609 1609 voltsDC = numpy.mean(voltsDC,1)
1610 1610 for i in range(voltsDC.shape[0]):
1611 1611 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
1612 1612
1613 1613 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
1614 1614 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
1615 1615
1616 1616 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
1617 1617 #Coherent Detection
1618 1618 if cohDetection:
1619 1619 #use coherent detection to get the net power
1620 1620 cohDet_thresh = cohDet_thresh*numpy.pi/180
1621 1621 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
1622 1622
1623 1623 #Non-coherent detection!
1624 1624 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
1625 1625 #********** END OF COH/NON-COH POWER CALCULATION**********************
1626 1626
1627 1627 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
1628 1628 #Get noise
1629 1629 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
1630 1630 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
1631 1631 #Get signal threshold
1632 1632 signalThresh = noise_multiple*noise
1633 1633 #Meteor echoes detection
1634 1634 listMeteors = self.__findMeteors(powerNet, signalThresh)
1635 1635 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
1636 1636
1637 1637 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
1638 1638 #Parameters
1639 1639 heiRange = dataOut.getHeiRange()
1640 1640 rangeInterval = heiRange[1] - heiRange[0]
1641 1641 rangeLimit = multDet_rangeLimit/rangeInterval
1642 1642 timeLimit = multDet_timeLimit/dataOut.timeInterval
1643 1643 #Multiple detection removals
1644 1644 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
1645 1645 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
1646 1646
1647 1647 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
1648 1648 #Parameters
1649 1649 phaseThresh = phaseThresh*numpy.pi/180
1650 1650 thresh = [phaseThresh, noise_multiple, SNRThresh]
1651 1651 #Meteor reestimation (Errors N 1, 6, 12, 17)
1652 1652 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist0, thresh, noise, dataOut.timeInterval, dataOut.frequency)
1653 1653 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
1654 1654 #Estimation of decay times (Errors N 7, 8, 11)
1655 1655 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
1656 1656 #******************* END OF METEOR REESTIMATION *******************
1657 1657
1658 1658 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
1659 1659 #Calculating Radial Velocity (Error N 15)
1660 1660 radialStdThresh = 10
1661 1661 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
1662 1662
1663 1663 if len(listMeteors4) > 0:
1664 1664 #Setting New Array
1665 1665 date = dataOut.utctime
1666 1666 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
1667 1667
1668 1668 #Correcting phase offset
1669 1669 if phaseOffsets != None:
1670 1670 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
1671 1671 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
1672 1672
1673 1673 #Second Pairslist
1674 1674 pairsList = []
1675 1675 pairx = (0,1)
1676 1676 pairy = (2,3)
1677 1677 pairsList.append(pairx)
1678 1678 pairsList.append(pairy)
1679 1679
1680 1680 jph = numpy.array([0,0,0,0])
1681 1681 h = (hmin,hmax)
1682 1682 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
1683 1683
1684 1684 # #Calculate AOA (Error N 3, 4)
1685 1685 # #JONES ET AL. 1998
1686 1686 # error = arrayParameters[:,-1]
1687 1687 # AOAthresh = numpy.pi/8
1688 1688 # phases = -arrayParameters[:,9:13]
1689 1689 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
1690 1690 #
1691 1691 # #Calculate Heights (Error N 13 and 14)
1692 1692 # error = arrayParameters[:,-1]
1693 1693 # Ranges = arrayParameters[:,2]
1694 1694 # zenith = arrayParameters[:,5]
1695 1695 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
1696 1696 # error = arrayParameters[:,-1]
1697 1697 #********************* END OF PARAMETERS CALCULATION **************************
1698 1698
1699 1699 #***************************+ PASS DATA TO NEXT STEP **********************
1700 1700 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
1701 1701 dataOut.data_param = arrayParameters
1702 1702
1703 1703 if arrayParameters is None:
1704 1704 dataOut.flagNoData = True
1705 1705 else:
1706 1706 dataOut.flagNoData = True
1707 1707
1708 1708 return
1709 1709
1710 1710 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
1711 1711
1712 1712 minIndex = min(newheis[0])
1713 1713 maxIndex = max(newheis[0])
1714 1714
1715 1715 voltage = voltage0[:,:,minIndex:maxIndex+1]
1716 1716 nLength = voltage.shape[1]/n
1717 1717 nMin = 0
1718 1718 nMax = 0
1719 1719 phaseOffset = numpy.zeros((len(pairslist),n))
1720 1720
1721 1721 for i in range(n):
1722 1722 nMax += nLength
1723 1723 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
1724 1724 phaseCCF = numpy.mean(phaseCCF, axis = 2)
1725 1725 phaseOffset[:,i] = phaseCCF.transpose()
1726 1726 nMin = nMax
1727 1727 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
1728 1728
1729 1729 #Remove Outliers
1730 1730 factor = 2
1731 1731 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
1732 1732 dw = numpy.std(wt,axis = 1)
1733 1733 dw = dw.reshape((dw.size,1))
1734 1734 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
1735 1735 phaseOffset[ind] = numpy.nan
1736 1736 phaseOffset = stats.nanmean(phaseOffset, axis=1)
1737 1737
1738 1738 return phaseOffset
1739 1739
1740 1740 def __shiftPhase(self, data, phaseShift):
1741 1741 #this will shift the phase of a complex number
1742 1742 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
1743 1743 return dataShifted
1744 1744
1745 1745 def __estimatePhaseDifference(self, array, pairslist):
1746 1746 nChannel = array.shape[0]
1747 1747 nHeights = array.shape[2]
1748 1748 numPairs = len(pairslist)
1749 1749 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
1750 1750 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
1751 1751
1752 1752 #Correct phases
1753 1753 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
1754 1754 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
1755 1755
1756 1756 if indDer[0].shape[0] > 0:
1757 1757 for i in range(indDer[0].shape[0]):
1758 1758 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
1759 1759 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
1760 1760
1761 1761 # for j in range(numSides):
1762 1762 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
1763 1763 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
1764 1764 #
1765 1765 #Linear
1766 1766 phaseInt = numpy.zeros((numPairs,1))
1767 1767 angAllCCF = phaseCCF[:,[0,1,3,4],0]
1768 1768 for j in range(numPairs):
1769 1769 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
1770 1770 phaseInt[j] = fit[1]
1771 1771 #Phase Differences
1772 1772 phaseDiff = phaseInt - phaseCCF[:,2,:]
1773 1773 phaseArrival = phaseInt.reshape(phaseInt.size)
1774 1774
1775 1775 #Dealias
1776 1776 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
1777 1777 # indAlias = numpy.where(phaseArrival > numpy.pi)
1778 1778 # phaseArrival[indAlias] -= 2*numpy.pi
1779 1779 # indAlias = numpy.where(phaseArrival < -numpy.pi)
1780 1780 # phaseArrival[indAlias] += 2*numpy.pi
1781 1781
1782 1782 return phaseDiff, phaseArrival
1783 1783
1784 1784 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
1785 1785 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
1786 1786 #find the phase shifts of each channel over 1 second intervals
1787 1787 #only look at ranges below the beacon signal
1788 1788 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
1789 1789 numBlocks = int(volts.shape[1]/numProfPerBlock)
1790 1790 numHeights = volts.shape[2]
1791 1791 nChannel = volts.shape[0]
1792 1792 voltsCohDet = volts.copy()
1793 1793
1794 1794 pairsarray = numpy.array(pairslist)
1795 1795 indSides = pairsarray[:,1]
1796 1796 # indSides = numpy.array(range(nChannel))
1797 1797 # indSides = numpy.delete(indSides, indCenter)
1798 1798 #
1799 1799 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
1800 1800 listBlocks = numpy.array_split(volts, numBlocks, 1)
1801 1801
1802 1802 startInd = 0
1803 1803 endInd = 0
1804 1804
1805 1805 for i in range(numBlocks):
1806 1806 startInd = endInd
1807 1807 endInd = endInd + listBlocks[i].shape[1]
1808 1808
1809 1809 arrayBlock = listBlocks[i]
1810 1810 # arrayBlockCenter = listCenter[i]
1811 1811
1812 1812 #Estimate the Phase Difference
1813 1813 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
1814 1814 #Phase Difference RMS
1815 1815 arrayPhaseRMS = numpy.abs(phaseDiff)
1816 1816 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
1817 1817 indPhase = numpy.where(phaseRMSaux==4)
1818 1818 #Shifting
1819 1819 if indPhase[0].shape[0] > 0:
1820 1820 for j in range(indSides.size):
1821 1821 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
1822 1822 voltsCohDet[:,startInd:endInd,:] = arrayBlock
1823 1823
1824 1824 return voltsCohDet
1825 1825
1826 1826 def __calculateCCF(self, volts, pairslist ,laglist):
1827 1827
1828 1828 nHeights = volts.shape[2]
1829 1829 nPoints = volts.shape[1]
1830 1830 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
1831 1831
1832 1832 for i in range(len(pairslist)):
1833 1833 volts1 = volts[pairslist[i][0]]
1834 1834 volts2 = volts[pairslist[i][1]]
1835 1835
1836 1836 for t in range(len(laglist)):
1837 1837 idxT = laglist[t]
1838 1838 if idxT >= 0:
1839 1839 vStacked = numpy.vstack((volts2[idxT:,:],
1840 1840 numpy.zeros((idxT, nHeights),dtype='complex')))
1841 1841 else:
1842 1842 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
1843 1843 volts2[:(nPoints + idxT),:]))
1844 1844 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
1845 1845
1846 1846 vStacked = None
1847 1847 return voltsCCF
1848 1848
1849 1849 def __getNoise(self, power, timeSegment, timeInterval):
1850 1850 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
1851 1851 numBlocks = int(power.shape[0]/numProfPerBlock)
1852 1852 numHeights = power.shape[1]
1853 1853
1854 1854 listPower = numpy.array_split(power, numBlocks, 0)
1855 1855 noise = numpy.zeros((power.shape[0], power.shape[1]))
1856 1856 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
1857 1857
1858 1858 startInd = 0
1859 1859 endInd = 0
1860 1860
1861 1861 for i in range(numBlocks): #split por canal
1862 1862 startInd = endInd
1863 1863 endInd = endInd + listPower[i].shape[0]
1864 1864
1865 1865 arrayBlock = listPower[i]
1866 1866 noiseAux = numpy.mean(arrayBlock, 0)
1867 1867 # noiseAux = numpy.median(noiseAux)
1868 1868 # noiseAux = numpy.mean(arrayBlock)
1869 1869 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
1870 1870
1871 1871 noiseAux1 = numpy.mean(arrayBlock)
1872 1872 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
1873 1873
1874 1874 return noise, noise1
1875 1875
1876 1876 def __findMeteors(self, power, thresh):
1877 1877 nProf = power.shape[0]
1878 1878 nHeights = power.shape[1]
1879 1879 listMeteors = []
1880 1880
1881 1881 for i in range(nHeights):
1882 1882 powerAux = power[:,i]
1883 1883 threshAux = thresh[:,i]
1884 1884
1885 1885 indUPthresh = numpy.where(powerAux > threshAux)[0]
1886 1886 indDNthresh = numpy.where(powerAux <= threshAux)[0]
1887 1887
1888 1888 j = 0
1889 1889
1890 1890 while (j < indUPthresh.size - 2):
1891 1891 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
1892 1892 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
1893 1893 indDNthresh = indDNthresh[indDNAux]
1894 1894
1895 1895 if (indDNthresh.size > 0):
1896 1896 indEnd = indDNthresh[0] - 1
1897 1897 indInit = indUPthresh[j] if isinstance(indUPthresh[j], (int, float)) else indUPthresh[j][0] ##CHECK!!!!
1898 1898
1899 1899 meteor = powerAux[indInit:indEnd + 1]
1900 1900 indPeak = meteor.argmax() + indInit
1901 1901 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
1902 1902
1903 1903 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
1904 1904 j = numpy.where(indUPthresh == indEnd)[0] + 1
1905 1905 else: j+=1
1906 1906 else: j+=1
1907 1907
1908 1908 return listMeteors
1909 1909
1910 1910 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
1911 1911
1912 1912 arrayMeteors = numpy.asarray(listMeteors)
1913 1913 listMeteors1 = []
1914 1914
1915 1915 while arrayMeteors.shape[0] > 0:
1916 1916 FLAs = arrayMeteors[:,4]
1917 1917 maxFLA = FLAs.argmax()
1918 1918 listMeteors1.append(arrayMeteors[maxFLA,:])
1919 1919
1920 1920 MeteorInitTime = arrayMeteors[maxFLA,1]
1921 1921 MeteorEndTime = arrayMeteors[maxFLA,3]
1922 1922 MeteorHeight = arrayMeteors[maxFLA,0]
1923 1923
1924 1924 #Check neighborhood
1925 1925 maxHeightIndex = MeteorHeight + rangeLimit
1926 1926 minHeightIndex = MeteorHeight - rangeLimit
1927 1927 minTimeIndex = MeteorInitTime - timeLimit
1928 1928 maxTimeIndex = MeteorEndTime + timeLimit
1929 1929
1930 1930 #Check Heights
1931 1931 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
1932 1932 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
1933 1933 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
1934 1934
1935 1935 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
1936 1936
1937 1937 return listMeteors1
1938 1938
1939 1939 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
1940 1940 numHeights = volts.shape[2]
1941 1941 nChannel = volts.shape[0]
1942 1942
1943 1943 thresholdPhase = thresh[0]
1944 1944 thresholdNoise = thresh[1]
1945 1945 thresholdDB = float(thresh[2])
1946 1946
1947 1947 thresholdDB1 = 10**(thresholdDB/10)
1948 1948 pairsarray = numpy.array(pairslist)
1949 1949 indSides = pairsarray[:,1]
1950 1950
1951 1951 pairslist1 = list(pairslist)
1952 1952 pairslist1.append((0,4))
1953 1953 pairslist1.append((1,3))
1954 1954
1955 1955 listMeteors1 = []
1956 1956 listPowerSeries = []
1957 1957 listVoltageSeries = []
1958 1958 #volts has the war data
1959 1959
1960 1960 if frequency == 30.175e6:
1961 1961 timeLag = 45*10**-3
1962 1962 else:
1963 1963 timeLag = 15*10**-3
1964 1964 lag = int(numpy.ceil(timeLag/timeInterval))
1965 1965
1966 1966 for i in range(len(listMeteors)):
1967 1967
1968 1968 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
1969 1969 meteorAux = numpy.zeros(16)
1970 1970
1971 1971 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
1972 1972 mHeight = int(listMeteors[i][0])
1973 1973 mStart = int(listMeteors[i][1])
1974 1974 mPeak = int(listMeteors[i][2])
1975 1975 mEnd = int(listMeteors[i][3])
1976 1976
1977 1977 #get the volt data between the start and end times of the meteor
1978 1978 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
1979 1979 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
1980 1980
1981 1981 #3.6. Phase Difference estimation
1982 1982 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
1983 1983
1984 1984 #3.7. Phase difference removal & meteor start, peak and end times reestimated
1985 1985 #meteorVolts0.- all Channels, all Profiles
1986 1986 meteorVolts0 = volts[:,:,mHeight]
1987 1987 meteorThresh = noise[:,mHeight]*thresholdNoise
1988 1988 meteorNoise = noise[:,mHeight]
1989 1989 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
1990 1990 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
1991 1991
1992 1992 #Times reestimation
1993 1993 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
1994 1994 if mStart1.size > 0:
1995 1995 mStart1 = mStart1[-1] + 1
1996 1996
1997 1997 else:
1998 1998 mStart1 = mPeak
1999 1999
2000 2000 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
2001 2001 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
2002 2002 if mEndDecayTime1.size == 0:
2003 2003 mEndDecayTime1 = powerNet0.size
2004 2004 else:
2005 2005 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
2006 2006 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
2007 2007
2008 2008 #meteorVolts1.- all Channels, from start to end
2009 2009 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
2010 2010 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
2011 2011 if meteorVolts2.shape[1] == 0:
2012 2012 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
2013 2013 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
2014 2014 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
2015 2015 ##################### END PARAMETERS REESTIMATION #########################
2016 2016
2017 2017 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
2018 2018 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
2019 2019 if meteorVolts2.shape[1] > 0:
2020 2020 #Phase Difference re-estimation
2021 2021 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
2022 2022 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
2023 2023 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
2024 2024 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
2025 2025 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
2026 2026
2027 2027 #Phase Difference RMS
2028 2028 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
2029 2029 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
2030 2030 #Data from Meteor
2031 2031 mPeak1 = powerNet1.argmax() + mStart1
2032 2032 mPeakPower1 = powerNet1.max()
2033 2033 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
2034 2034 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
2035 2035 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
2036 2036 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
2037 2037 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
2038 2038 #Vectorize
2039 2039 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
2040 2040 meteorAux[7:11] = phaseDiffint[0:4]
2041 2041
2042 2042 #Rejection Criterions
2043 2043 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
2044 2044 meteorAux[-1] = 17
2045 2045 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
2046 2046 meteorAux[-1] = 1
2047 2047
2048 2048
2049 2049 else:
2050 2050 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
2051 2051 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
2052 2052 PowerSeries = 0
2053 2053
2054 2054 listMeteors1.append(meteorAux)
2055 2055 listPowerSeries.append(PowerSeries)
2056 2056 listVoltageSeries.append(meteorVolts1)
2057 2057
2058 2058 return listMeteors1, listPowerSeries, listVoltageSeries
2059 2059
2060 2060 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
2061 2061
2062 2062 threshError = 10
2063 2063 #Depending if it is 30 or 50 MHz
2064 2064 if frequency == 30.175e6:
2065 2065 timeLag = 45*10**-3
2066 2066 else:
2067 2067 timeLag = 15*10**-3
2068 2068 lag = int(numpy.ceil(timeLag/timeInterval))
2069 2069
2070 2070 listMeteors1 = []
2071 2071
2072 2072 for i in range(len(listMeteors)):
2073 2073 meteorPower = listPower[i]
2074 2074 meteorAux = listMeteors[i]
2075 2075
2076 2076 if meteorAux[-1] == 0:
2077 2077
2078 2078 try:
2079 2079 indmax = meteorPower.argmax()
2080 2080 indlag = indmax + lag
2081 2081
2082 2082 y = meteorPower[indlag:]
2083 2083 x = numpy.arange(0, y.size)*timeLag
2084 2084
2085 2085 #first guess
2086 2086 a = y[0]
2087 2087 tau = timeLag
2088 2088 #exponential fit
2089 2089 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
2090 2090 y1 = self.__exponential_function(x, *popt)
2091 2091 #error estimation
2092 2092 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
2093 2093
2094 2094 decayTime = popt[1]
2095 2095 riseTime = indmax*timeInterval
2096 2096 meteorAux[11:13] = [decayTime, error]
2097 2097
2098 2098 #Table items 7, 8 and 11
2099 2099 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
2100 2100 meteorAux[-1] = 7
2101 2101 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
2102 2102 meteorAux[-1] = 8
2103 2103 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
2104 2104 meteorAux[-1] = 11
2105 2105
2106 2106
2107 2107 except:
2108 2108 meteorAux[-1] = 11
2109 2109
2110 2110
2111 2111 listMeteors1.append(meteorAux)
2112 2112
2113 2113 return listMeteors1
2114 2114
2115 2115 #Exponential Function
2116 2116
2117 2117 def __exponential_function(self, x, a, tau):
2118 2118 y = a*numpy.exp(-x/tau)
2119 2119 return y
2120 2120
2121 2121 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
2122 2122
2123 2123 pairslist1 = list(pairslist)
2124 2124 pairslist1.append((0,4))
2125 2125 pairslist1.append((1,3))
2126 2126 numPairs = len(pairslist1)
2127 2127 #Time Lag
2128 2128 timeLag = 45*10**-3
2129 2129 c = 3e8
2130 2130 lag = numpy.ceil(timeLag/timeInterval)
2131 2131 freq = 30.175e6
2132 2132
2133 2133 listMeteors1 = []
2134 2134
2135 2135 for i in range(len(listMeteors)):
2136 2136 meteorAux = listMeteors[i]
2137 2137 if meteorAux[-1] == 0:
2138 2138 mStart = listMeteors[i][1]
2139 2139 mPeak = listMeteors[i][2]
2140 2140 mLag = mPeak - mStart + lag
2141 2141
2142 2142 #get the volt data between the start and end times of the meteor
2143 2143 meteorVolts = listVolts[i]
2144 2144 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
2145 2145
2146 2146 #Get CCF
2147 2147 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
2148 2148
2149 2149 #Method 2
2150 2150 slopes = numpy.zeros(numPairs)
2151 2151 time = numpy.array([-2,-1,1,2])*timeInterval
2152 2152 angAllCCF = numpy.angle(allCCFs[:,[0,4,2,3],0])
2153 2153
2154 2154 #Correct phases
2155 2155 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
2156 2156 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2157 2157
2158 2158 if indDer[0].shape[0] > 0:
2159 2159 for i in range(indDer[0].shape[0]):
2160 2160 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
2161 2161 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
2162 2162
2163 2163 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
2164 2164 for j in range(numPairs):
2165 2165 fit = stats.linregress(time, angAllCCF[j,:])
2166 2166 slopes[j] = fit[0]
2167 2167
2168 2168 #Remove Outlier
2169 2169 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
2170 2170 # slopes = numpy.delete(slopes,indOut)
2171 2171 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
2172 2172 # slopes = numpy.delete(slopes,indOut)
2173 2173
2174 2174 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
2175 2175 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
2176 2176 meteorAux[-2] = radialError
2177 2177 meteorAux[-3] = radialVelocity
2178 2178
2179 2179 #Setting Error
2180 2180 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
2181 2181 if numpy.abs(radialVelocity) > 200:
2182 2182 meteorAux[-1] = 15
2183 2183 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
2184 2184 elif radialError > radialStdThresh:
2185 2185 meteorAux[-1] = 12
2186 2186
2187 2187 listMeteors1.append(meteorAux)
2188 2188 return listMeteors1
2189 2189
2190 2190 def __setNewArrays(self, listMeteors, date, heiRang):
2191 2191
2192 2192 #New arrays
2193 2193 arrayMeteors = numpy.array(listMeteors)
2194 2194 arrayParameters = numpy.zeros((len(listMeteors), 13))
2195 2195
2196 2196 #Date inclusion
2197 2197 # date = re.findall(r'\((.*?)\)', date)
2198 2198 # date = date[0].split(',')
2199 2199 # date = map(int, date)
2200 2200 #
2201 2201 # if len(date)<6:
2202 2202 # date.append(0)
2203 2203 #
2204 2204 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
2205 2205 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
2206 2206 arrayDate = numpy.tile(date, (len(listMeteors)))
2207 2207
2208 2208 #Meteor array
2209 2209 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
2210 2210 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
2211 2211
2212 2212 #Parameters Array
2213 2213 arrayParameters[:,0] = arrayDate #Date
2214 2214 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
2215 2215 arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
2216 2216 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
2217 2217 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
2218 2218
2219 2219
2220 2220 return arrayParameters
2221 2221
2222 2222 class CorrectSMPhases(Operation):
2223 parameters = {
2224 'phaseOffsets': global_type_pairsList,
2225 'hmin': global_type_float,
2226 'hmax': global_type_float,
2227 'azimuth': global_type_float,
2228 'channelPositions': global_type_pairsList,
2229 }
2223 2230
2224 2231 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
2225 2232
2226 2233 arrayParameters = dataOut.data_param
2227 2234 pairsList = []
2228 2235 pairx = (0,1)
2229 2236 pairy = (2,3)
2230 2237 pairsList.append(pairx)
2231 2238 pairsList.append(pairy)
2232 2239 jph = numpy.zeros(4)
2233 2240
2234 2241 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2235 2242 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2236 2243 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
2237 2244
2238 2245 meteorOps = SMOperations()
2239 2246 if channelPositions is None:
2240 2247 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2241 2248 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2242 2249
2243 2250 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2244 2251 h = (hmin,hmax)
2245 2252
2246 2253 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2247 2254
2248 2255 dataOut.data_param = arrayParameters
2249 2256 return
2250 2257
2251 2258 class SMPhaseCalibration(Operation):
2252 2259
2253 2260 __buffer = None
2254 2261
2255 2262 __initime = None
2256 2263
2257 2264 __dataReady = False
2258 2265
2259 2266 __isConfig = False
2260 2267
2261 2268 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
2262 2269
2263 2270 dataTime = currentTime + paramInterval
2264 2271 deltaTime = dataTime - initTime
2265 2272
2266 2273 if deltaTime >= outputInterval or deltaTime < 0:
2267 2274 return True
2268 2275
2269 2276 return False
2270 2277
2271 2278 def __getGammas(self, pairs, d, phases):
2272 2279 gammas = numpy.zeros(2)
2273 2280
2274 2281 for i in range(len(pairs)):
2275 2282
2276 2283 pairi = pairs[i]
2277 2284
2278 2285 phip3 = phases[:,pairi[0]]
2279 2286 d3 = d[pairi[0]]
2280 2287 phip2 = phases[:,pairi[1]]
2281 2288 d2 = d[pairi[1]]
2282 2289 #Calculating gamma
2283 2290 # jdcos = alp1/(k*d1)
2284 2291 # jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0)))
2285 2292 jgamma = -phip2*d3/d2 - phip3
2286 2293 jgamma = numpy.angle(numpy.exp(1j*jgamma))
2287 2294 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
2288 2295 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
2289 2296
2290 2297 #Revised distribution
2291 2298 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
2292 2299
2293 2300 #Histogram
2294 2301 nBins = 64
2295 2302 rmin = -0.5*numpy.pi
2296 2303 rmax = 0.5*numpy.pi
2297 2304 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
2298 2305
2299 2306 meteorsY = phaseHisto[0]
2300 2307 phasesX = phaseHisto[1][:-1]
2301 2308 width = phasesX[1] - phasesX[0]
2302 2309 phasesX += width/2
2303 2310
2304 2311 #Gaussian aproximation
2305 2312 bpeak = meteorsY.argmax()
2306 2313 peak = meteorsY.max()
2307 2314 jmin = bpeak - 5
2308 2315 jmax = bpeak + 5 + 1
2309 2316
2310 2317 if jmin<0:
2311 2318 jmin = 0
2312 2319 jmax = 6
2313 2320 elif jmax > meteorsY.size:
2314 2321 jmin = meteorsY.size - 6
2315 2322 jmax = meteorsY.size
2316 2323
2317 2324 x0 = numpy.array([peak,bpeak,50])
2318 2325 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
2319 2326
2320 2327 #Gammas
2321 2328 gammas[i] = coeff[0][1]
2322 2329
2323 2330 return gammas
2324 2331
2325 2332 def __residualFunction(self, coeffs, y, t):
2326 2333
2327 2334 return y - self.__gauss_function(t, coeffs)
2328 2335
2329 2336 def __gauss_function(self, t, coeffs):
2330 2337
2331 2338 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
2332 2339
2333 2340 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
2334 2341 meteorOps = SMOperations()
2335 2342 nchan = 4
2336 2343 pairx = pairsList[0] #x es 0
2337 2344 pairy = pairsList[1] #y es 1
2338 2345 center_xangle = 0
2339 2346 center_yangle = 0
2340 2347 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
2341 2348 ntimes = len(range_angle)
2342 2349
2343 2350 nstepsx = 20
2344 2351 nstepsy = 20
2345 2352
2346 2353 for iz in range(ntimes):
2347 2354 min_xangle = -range_angle[iz]/2 + center_xangle
2348 2355 max_xangle = range_angle[iz]/2 + center_xangle
2349 2356 min_yangle = -range_angle[iz]/2 + center_yangle
2350 2357 max_yangle = range_angle[iz]/2 + center_yangle
2351 2358
2352 2359 inc_x = (max_xangle-min_xangle)/nstepsx
2353 2360 inc_y = (max_yangle-min_yangle)/nstepsy
2354 2361
2355 2362 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
2356 2363 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
2357 2364 penalty = numpy.zeros((nstepsx,nstepsy))
2358 2365 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
2359 2366 jph = numpy.zeros(nchan)
2360 2367
2361 2368 # Iterations looking for the offset
2362 2369 for iy in range(int(nstepsy)):
2363 2370 for ix in range(int(nstepsx)):
2364 2371 d3 = d[pairsList[1][0]]
2365 2372 d2 = d[pairsList[1][1]]
2366 2373 d5 = d[pairsList[0][0]]
2367 2374 d4 = d[pairsList[0][1]]
2368 2375
2369 2376 alp2 = alpha_y[iy] #gamma 1
2370 2377 alp4 = alpha_x[ix] #gamma 0
2371 2378
2372 2379 alp3 = -alp2*d3/d2 - gammas[1]
2373 2380 alp5 = -alp4*d5/d4 - gammas[0]
2374 2381 # jph[pairy[1]] = alpha_y[iy]
2375 2382 # jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
2376 2383
2377 2384 # jph[pairx[1]] = alpha_x[ix]
2378 2385 # jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
2379 2386 jph[pairsList[0][1]] = alp4
2380 2387 jph[pairsList[0][0]] = alp5
2381 2388 jph[pairsList[1][0]] = alp3
2382 2389 jph[pairsList[1][1]] = alp2
2383 2390 jph_array[:,ix,iy] = jph
2384 2391 # d = [2.0,2.5,2.5,2.0]
2385 2392 #falta chequear si va a leer bien los meteoros
2386 2393 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
2387 2394 error = meteorsArray1[:,-1]
2388 2395 ind1 = numpy.where(error==0)[0]
2389 2396 penalty[ix,iy] = ind1.size
2390 2397
2391 2398 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
2392 2399 phOffset = jph_array[:,i,j]
2393 2400
2394 2401 center_xangle = phOffset[pairx[1]]
2395 2402 center_yangle = phOffset[pairy[1]]
2396 2403
2397 2404 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
2398 2405 phOffset = phOffset*180/numpy.pi
2399 2406 return phOffset
2400 2407
2401 2408
2402 2409 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
2403 2410
2404 2411 dataOut.flagNoData = True
2405 2412 self.__dataReady = False
2406 2413 dataOut.outputInterval = nHours*3600
2407 2414
2408 2415 if self.__isConfig == False:
2409 2416 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2410 2417 #Get Initial LTC time
2411 2418 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2412 2419 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2413 2420
2414 2421 self.__isConfig = True
2415 2422
2416 2423 if self.__buffer is None:
2417 2424 self.__buffer = dataOut.data_param.copy()
2418 2425
2419 2426 else:
2420 2427 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2421 2428
2422 2429 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2423 2430
2424 2431 if self.__dataReady:
2425 2432 dataOut.utctimeInit = self.__initime
2426 2433 self.__initime += dataOut.outputInterval #to erase time offset
2427 2434
2428 2435 freq = dataOut.frequency
2429 2436 c = dataOut.C #m/s
2430 2437 lamb = c/freq
2431 2438 k = 2*numpy.pi/lamb
2432 2439 azimuth = 0
2433 2440 h = (hmin, hmax)
2434 2441 # pairs = ((0,1),(2,3)) #Estrella
2435 2442 # pairs = ((1,0),(2,3)) #T
2436 2443
2437 2444 if channelPositions is None:
2438 2445 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2439 2446 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2440 2447 meteorOps = SMOperations()
2441 2448 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2442 2449
2443 2450 #Checking correct order of pairs
2444 2451 pairs = []
2445 2452 if distances[1] > distances[0]:
2446 2453 pairs.append((1,0))
2447 2454 else:
2448 2455 pairs.append((0,1))
2449 2456
2450 2457 if distances[3] > distances[2]:
2451 2458 pairs.append((3,2))
2452 2459 else:
2453 2460 pairs.append((2,3))
2454 2461 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
2455 2462
2456 2463 meteorsArray = self.__buffer
2457 2464 error = meteorsArray[:,-1]
2458 2465 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
2459 2466 ind1 = numpy.where(boolError)[0]
2460 2467 meteorsArray = meteorsArray[ind1,:]
2461 2468 meteorsArray[:,-1] = 0
2462 2469 phases = meteorsArray[:,8:12]
2463 2470
2464 2471 #Calculate Gammas
2465 2472 gammas = self.__getGammas(pairs, distances, phases)
2466 2473 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
2467 2474 #Calculate Phases
2468 2475 phasesOff = self.__getPhases(azimuth, h, pairs, distances, gammas, meteorsArray)
2469 2476 phasesOff = phasesOff.reshape((1,phasesOff.size))
2470 2477 dataOut.data_output = -phasesOff
2471 2478 dataOut.flagNoData = False
2472 2479 dataOut.channelList = pairslist0
2473 2480 self.__buffer = None
2474 2481
2475 2482
2476 2483 return
2477 2484
2478 2485 class SMOperations():
2479 2486
2480 2487 def __init__(self):
2481 2488
2482 2489 return
2483 2490
2484 2491 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
2485 2492
2486 2493 arrayParameters = arrayParameters0.copy()
2487 2494 hmin = h[0]
2488 2495 hmax = h[1]
2489 2496
2490 2497 #Calculate AOA (Error N 3, 4)
2491 2498 #JONES ET AL. 1998
2492 2499 AOAthresh = numpy.pi/8
2493 2500 error = arrayParameters[:,-1]
2494 2501 phases = -arrayParameters[:,8:12] + jph
2495 2502 # phases = numpy.unwrap(phases)
2496 2503 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
2497 2504
2498 2505 #Calculate Heights (Error N 13 and 14)
2499 2506 error = arrayParameters[:,-1]
2500 2507 Ranges = arrayParameters[:,1]
2501 2508 zenith = arrayParameters[:,4]
2502 2509 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
2503 2510
2504 2511 #----------------------- Get Final data ------------------------------------
2505 2512 # error = arrayParameters[:,-1]
2506 2513 # ind1 = numpy.where(error==0)[0]
2507 2514 # arrayParameters = arrayParameters[ind1,:]
2508 2515
2509 2516 return arrayParameters
2510 2517
2511 2518 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
2512 2519
2513 2520 arrayAOA = numpy.zeros((phases.shape[0],3))
2514 2521 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
2515 2522
2516 2523 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
2517 2524 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
2518 2525 arrayAOA[:,2] = cosDirError
2519 2526
2520 2527 azimuthAngle = arrayAOA[:,0]
2521 2528 zenithAngle = arrayAOA[:,1]
2522 2529
2523 2530 #Setting Error
2524 2531 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
2525 2532 error[indError] = 0
2526 2533 #Number 3: AOA not fesible
2527 2534 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
2528 2535 error[indInvalid] = 3
2529 2536 #Number 4: Large difference in AOAs obtained from different antenna baselines
2530 2537 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
2531 2538 error[indInvalid] = 4
2532 2539 return arrayAOA, error
2533 2540
2534 2541 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
2535 2542
2536 2543 #Initializing some variables
2537 2544 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
2538 2545 ang_aux = ang_aux.reshape(1,ang_aux.size)
2539 2546
2540 2547 cosdir = numpy.zeros((arrayPhase.shape[0],2))
2541 2548 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
2542 2549
2543 2550
2544 2551 for i in range(2):
2545 2552 ph0 = arrayPhase[:,pairsList[i][0]]
2546 2553 ph1 = arrayPhase[:,pairsList[i][1]]
2547 2554 d0 = distances[pairsList[i][0]]
2548 2555 d1 = distances[pairsList[i][1]]
2549 2556
2550 2557 ph0_aux = ph0 + ph1
2551 2558 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
2552 2559 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
2553 2560 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
2554 2561 #First Estimation
2555 2562 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
2556 2563
2557 2564 #Most-Accurate Second Estimation
2558 2565 phi1_aux = ph0 - ph1
2559 2566 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
2560 2567 #Direction Cosine 1
2561 2568 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
2562 2569
2563 2570 #Searching the correct Direction Cosine
2564 2571 cosdir0_aux = cosdir0[:,i]
2565 2572 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
2566 2573 #Minimum Distance
2567 2574 cosDiff = (cosdir1 - cosdir0_aux)**2
2568 2575 indcos = cosDiff.argmin(axis = 1)
2569 2576 #Saving Value obtained
2570 2577 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
2571 2578
2572 2579 return cosdir0, cosdir
2573 2580
2574 2581 def __calculateAOA(self, cosdir, azimuth):
2575 2582 cosdirX = cosdir[:,0]
2576 2583 cosdirY = cosdir[:,1]
2577 2584
2578 2585 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
2579 2586 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
2580 2587 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
2581 2588
2582 2589 return angles
2583 2590
2584 2591 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
2585 2592
2586 2593 Ramb = 375 #Ramb = c/(2*PRF)
2587 2594 Re = 6371 #Earth Radius
2588 2595 heights = numpy.zeros(Ranges.shape)
2589 2596
2590 2597 R_aux = numpy.array([0,1,2])*Ramb
2591 2598 R_aux = R_aux.reshape(1,R_aux.size)
2592 2599
2593 2600 Ranges = Ranges.reshape(Ranges.size,1)
2594 2601
2595 2602 Ri = Ranges + R_aux
2596 2603 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
2597 2604
2598 2605 #Check if there is a height between 70 and 110 km
2599 2606 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
2600 2607 ind_h = numpy.where(h_bool == 1)[0]
2601 2608
2602 2609 hCorr = hi[ind_h, :]
2603 2610 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
2604 2611
2605 2612 hCorr = hi[ind_hCorr][:len(ind_h)]
2606 2613 heights[ind_h] = hCorr
2607 2614
2608 2615 #Setting Error
2609 2616 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
2610 2617 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
2611 2618 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
2612 2619 error[indError] = 0
2613 2620 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
2614 2621 error[indInvalid2] = 14
2615 2622 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
2616 2623 error[indInvalid1] = 13
2617 2624
2618 2625 return heights, error
2619 2626
2620 2627 def getPhasePairs(self, channelPositions):
2621 2628 chanPos = numpy.array(channelPositions)
2622 2629 listOper = list(itertools.combinations(range(5),2))
2623 2630
2624 2631 distances = numpy.zeros(4)
2625 2632 axisX = []
2626 2633 axisY = []
2627 2634 distX = numpy.zeros(3)
2628 2635 distY = numpy.zeros(3)
2629 2636 ix = 0
2630 2637 iy = 0
2631 2638
2632 2639 pairX = numpy.zeros((2,2))
2633 2640 pairY = numpy.zeros((2,2))
2634 2641
2635 2642 for i in range(len(listOper)):
2636 2643 pairi = listOper[i]
2637 2644
2638 2645 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
2639 2646
2640 2647 if posDif[0] == 0:
2641 2648 axisY.append(pairi)
2642 2649 distY[iy] = posDif[1]
2643 2650 iy += 1
2644 2651 elif posDif[1] == 0:
2645 2652 axisX.append(pairi)
2646 2653 distX[ix] = posDif[0]
2647 2654 ix += 1
2648 2655
2649 2656 for i in range(2):
2650 2657 if i==0:
2651 2658 dist0 = distX
2652 2659 axis0 = axisX
2653 2660 else:
2654 2661 dist0 = distY
2655 2662 axis0 = axisY
2656 2663
2657 2664 side = numpy.argsort(dist0)[:-1]
2658 2665 axis0 = numpy.array(axis0)[side,:]
2659 2666 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
2660 2667 axis1 = numpy.unique(numpy.reshape(axis0,4))
2661 2668 side = axis1[axis1 != chanC]
2662 2669 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
2663 2670 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
2664 2671 if diff1<0:
2665 2672 chan2 = side[0]
2666 2673 d2 = numpy.abs(diff1)
2667 2674 chan1 = side[1]
2668 2675 d1 = numpy.abs(diff2)
2669 2676 else:
2670 2677 chan2 = side[1]
2671 2678 d2 = numpy.abs(diff2)
2672 2679 chan1 = side[0]
2673 2680 d1 = numpy.abs(diff1)
2674 2681
2675 2682 if i==0:
2676 2683 chanCX = chanC
2677 2684 chan1X = chan1
2678 2685 chan2X = chan2
2679 2686 distances[0:2] = numpy.array([d1,d2])
2680 2687 else:
2681 2688 chanCY = chanC
2682 2689 chan1Y = chan1
2683 2690 chan2Y = chan2
2684 2691 distances[2:4] = numpy.array([d1,d2])
2685 2692 # axisXsides = numpy.reshape(axisX[ix,:],4)
2686 2693 #
2687 2694 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
2688 2695 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
2689 2696 #
2690 2697 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
2691 2698 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
2692 2699 # channel25X = int(pairX[0,ind25X])
2693 2700 # channel20X = int(pairX[1,ind20X])
2694 2701 # ind25Y = numpy.where(pairY[0,:] != channelCentY)[0][0]
2695 2702 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
2696 2703 # channel25Y = int(pairY[0,ind25Y])
2697 2704 # channel20Y = int(pairY[1,ind20Y])
2698 2705
2699 2706 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
2700 2707 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
2701 2708
2702 2709 return pairslist, distances
2703 2710 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
2704 2711 #
2705 2712 # arrayAOA = numpy.zeros((phases.shape[0],3))
2706 2713 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
2707 2714 #
2708 2715 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
2709 2716 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
2710 2717 # arrayAOA[:,2] = cosDirError
2711 2718 #
2712 2719 # azimuthAngle = arrayAOA[:,0]
2713 2720 # zenithAngle = arrayAOA[:,1]
2714 2721 #
2715 2722 # #Setting Error
2716 2723 # #Number 3: AOA not fesible
2717 2724 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
2718 2725 # error[indInvalid] = 3
2719 2726 # #Number 4: Large difference in AOAs obtained from different antenna baselines
2720 2727 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
2721 2728 # error[indInvalid] = 4
2722 2729 # return arrayAOA, error
2723 2730 #
2724 2731 # def __getDirectionCosines(self, arrayPhase, pairsList):
2725 2732 #
2726 2733 # #Initializing some variables
2727 2734 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
2728 2735 # ang_aux = ang_aux.reshape(1,ang_aux.size)
2729 2736 #
2730 2737 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
2731 2738 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
2732 2739 #
2733 2740 #
2734 2741 # for i in range(2):
2735 2742 # #First Estimation
2736 2743 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
2737 2744 # #Dealias
2738 2745 # indcsi = numpy.where(phi0_aux > numpy.pi)
2739 2746 # phi0_aux[indcsi] -= 2*numpy.pi
2740 2747 # indcsi = numpy.where(phi0_aux < -numpy.pi)
2741 2748 # phi0_aux[indcsi] += 2*numpy.pi
2742 2749 # #Direction Cosine 0
2743 2750 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
2744 2751 #
2745 2752 # #Most-Accurate Second Estimation
2746 2753 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
2747 2754 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
2748 2755 # #Direction Cosine 1
2749 2756 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
2750 2757 #
2751 2758 # #Searching the correct Direction Cosine
2752 2759 # cosdir0_aux = cosdir0[:,i]
2753 2760 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
2754 2761 # #Minimum Distance
2755 2762 # cosDiff = (cosdir1 - cosdir0_aux)**2
2756 2763 # indcos = cosDiff.argmin(axis = 1)
2757 2764 # #Saving Value obtained
2758 2765 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
2759 2766 #
2760 2767 # return cosdir0, cosdir
2761 2768 #
2762 2769 # def __calculateAOA(self, cosdir, azimuth):
2763 2770 # cosdirX = cosdir[:,0]
2764 2771 # cosdirY = cosdir[:,1]
2765 2772 #
2766 2773 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
2767 2774 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
2768 2775 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
2769 2776 #
2770 2777 # return angles
2771 2778 #
2772 2779 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
2773 2780 #
2774 2781 # Ramb = 375 #Ramb = c/(2*PRF)
2775 2782 # Re = 6371 #Earth Radius
2776 2783 # heights = numpy.zeros(Ranges.shape)
2777 2784 #
2778 2785 # R_aux = numpy.array([0,1,2])*Ramb
2779 2786 # R_aux = R_aux.reshape(1,R_aux.size)
2780 2787 #
2781 2788 # Ranges = Ranges.reshape(Ranges.size,1)
2782 2789 #
2783 2790 # Ri = Ranges + R_aux
2784 2791 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
2785 2792 #
2786 2793 # #Check if there is a height between 70 and 110 km
2787 2794 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
2788 2795 # ind_h = numpy.where(h_bool == 1)[0]
2789 2796 #
2790 2797 # hCorr = hi[ind_h, :]
2791 2798 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
2792 2799 #
2793 2800 # hCorr = hi[ind_hCorr]
2794 2801 # heights[ind_h] = hCorr
2795 2802 #
2796 2803 # #Setting Error
2797 2804 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
2798 2805 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
2799 2806 #
2800 2807 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
2801 2808 # error[indInvalid2] = 14
2802 2809 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
2803 2810 # error[indInvalid1] = 13
2804 2811 #
2805 2812 # 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,1310 +1,1349
1 1 import sys
2 2 import numpy
3 3 from profilehooks import profile
4 4 from scipy import interpolate
5 5 from schainpy import cSchain
6 6 from jroproc_base import ProcessingUnit, Operation
7 7 from schainpy.model.data.jrodata import Voltage
8 8 from time import time
9 9
10 10 class VoltageProc(ProcessingUnit):
11 11
12 12
13 13 def __init__(self, **kwargs):
14 14
15 15 ProcessingUnit.__init__(self, **kwargs)
16 16
17 17 # self.objectDict = {}
18 18 self.dataOut = Voltage()
19 19 self.flip = 1
20 20
21 21 def run(self):
22 22 if self.dataIn.type == 'AMISR':
23 23 self.__updateObjFromAmisrInput()
24 24
25 25 if self.dataIn.type == 'Voltage':
26 26 self.dataOut.copy(self.dataIn)
27 27
28 28 # self.dataOut.copy(self.dataIn)
29 29
30 30 def __updateObjFromAmisrInput(self):
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.flagNoData = self.dataIn.flagNoData
38 38 self.dataOut.data = self.dataIn.data
39 39 self.dataOut.utctime = self.dataIn.utctime
40 40 self.dataOut.channelList = self.dataIn.channelList
41 41 # self.dataOut.timeInterval = self.dataIn.timeInterval
42 42 self.dataOut.heightList = self.dataIn.heightList
43 43 self.dataOut.nProfiles = self.dataIn.nProfiles
44 44
45 45 self.dataOut.nCohInt = self.dataIn.nCohInt
46 46 self.dataOut.ippSeconds = self.dataIn.ippSeconds
47 47 self.dataOut.frequency = self.dataIn.frequency
48 48
49 49 self.dataOut.azimuth = self.dataIn.azimuth
50 50 self.dataOut.zenith = self.dataIn.zenith
51 51
52 52 self.dataOut.beam.codeList = self.dataIn.beam.codeList
53 53 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
54 54 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
55 55 #
56 56 # pass#
57 57 #
58 58 # def init(self):
59 59 #
60 60 #
61 61 # if self.dataIn.type == 'AMISR':
62 62 # self.__updateObjFromAmisrInput()
63 63 #
64 64 # if self.dataIn.type == 'Voltage':
65 65 # self.dataOut.copy(self.dataIn)
66 66 # # No necesita copiar en cada init() los atributos de dataIn
67 67 # # la copia deberia hacerse por cada nuevo bloque de datos
68 68
69 69 def selectChannels(self, channelList):
70 70
71 71 channelIndexList = []
72 72
73 73 for channel in channelList:
74 74 if channel not in self.dataOut.channelList:
75 75 raise ValueError, "Channel %d is not in %s" %(channel, str(self.dataOut.channelList))
76 76
77 77 index = self.dataOut.channelList.index(channel)
78 78 channelIndexList.append(index)
79 79
80 80 self.selectChannelsByIndex(channelIndexList)
81 81
82 82 def selectChannelsByIndex(self, channelIndexList):
83 83 """
84 84 Selecciona un bloque de datos en base a canales segun el channelIndexList
85 85
86 86 Input:
87 87 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
88 88
89 89 Affected:
90 90 self.dataOut.data
91 91 self.dataOut.channelIndexList
92 92 self.dataOut.nChannels
93 93 self.dataOut.m_ProcessingHeader.totalSpectra
94 94 self.dataOut.systemHeaderObj.numChannels
95 95 self.dataOut.m_ProcessingHeader.blockSize
96 96
97 97 Return:
98 98 None
99 99 """
100 100
101 101 for channelIndex in channelIndexList:
102 102 if channelIndex not in self.dataOut.channelIndexList:
103 103 print channelIndexList
104 104 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
105 105
106 106 if self.dataOut.flagDataAsBlock:
107 107 """
108 108 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
109 109 """
110 110 data = self.dataOut.data[channelIndexList,:,:]
111 111 else:
112 112 data = self.dataOut.data[channelIndexList,:]
113 113
114 114 self.dataOut.data = data
115 115 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
116 116 # self.dataOut.nChannels = nChannels
117 117
118 118 return 1
119 119
120 120 def selectHeights(self, minHei=None, maxHei=None):
121 121 """
122 122 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
123 123 minHei <= height <= maxHei
124 124
125 125 Input:
126 126 minHei : valor minimo de altura a considerar
127 127 maxHei : valor maximo de altura a considerar
128 128
129 129 Affected:
130 130 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
131 131
132 132 Return:
133 133 1 si el metodo se ejecuto con exito caso contrario devuelve 0
134 134 """
135 135
136 136 if minHei == None:
137 137 minHei = self.dataOut.heightList[0]
138 138
139 139 if maxHei == None:
140 140 maxHei = self.dataOut.heightList[-1]
141 141
142 142 if (minHei < self.dataOut.heightList[0]):
143 143 minHei = self.dataOut.heightList[0]
144 144
145 145 if (maxHei > self.dataOut.heightList[-1]):
146 146 maxHei = self.dataOut.heightList[-1]
147 147
148 148 minIndex = 0
149 149 maxIndex = 0
150 150 heights = self.dataOut.heightList
151 151
152 152 inda = numpy.where(heights >= minHei)
153 153 indb = numpy.where(heights <= maxHei)
154 154
155 155 try:
156 156 minIndex = inda[0][0]
157 157 except:
158 158 minIndex = 0
159 159
160 160 try:
161 161 maxIndex = indb[0][-1]
162 162 except:
163 163 maxIndex = len(heights)
164 164
165 165 self.selectHeightsByIndex(minIndex, maxIndex)
166 166
167 167 return 1
168 168
169 169
170 170 def selectHeightsByIndex(self, minIndex, maxIndex):
171 171 """
172 172 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
173 173 minIndex <= index <= maxIndex
174 174
175 175 Input:
176 176 minIndex : valor de indice minimo de altura a considerar
177 177 maxIndex : valor de indice maximo de altura a considerar
178 178
179 179 Affected:
180 180 self.dataOut.data
181 181 self.dataOut.heightList
182 182
183 183 Return:
184 184 1 si el metodo se ejecuto con exito caso contrario devuelve 0
185 185 """
186 186
187 187 if (minIndex < 0) or (minIndex > maxIndex):
188 188 raise ValueError, "Height index range (%d,%d) is not valid" % (minIndex, maxIndex)
189 189
190 190 if (maxIndex >= self.dataOut.nHeights):
191 191 maxIndex = self.dataOut.nHeights
192 192
193 193 #voltage
194 194 if self.dataOut.flagDataAsBlock:
195 195 """
196 196 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
197 197 """
198 198 data = self.dataOut.data[:,:, minIndex:maxIndex]
199 199 else:
200 200 data = self.dataOut.data[:, minIndex:maxIndex]
201 201
202 202 # firstHeight = self.dataOut.heightList[minIndex]
203 203
204 204 self.dataOut.data = data
205 205 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex]
206 206
207 207 if self.dataOut.nHeights <= 1:
208 208 raise ValueError, "selectHeights: Too few heights. Current number of heights is %d" %(self.dataOut.nHeights)
209 209
210 210 return 1
211 211
212 212
213 213 def filterByHeights(self, window):
214 214
215 215 deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
216 216
217 217 if window == None:
218 218 window = (self.dataOut.radarControllerHeaderObj.txA/self.dataOut.radarControllerHeaderObj.nBaud) / deltaHeight
219 219
220 220 newdelta = deltaHeight * window
221 221 r = self.dataOut.nHeights % window
222 222 newheights = (self.dataOut.nHeights-r)/window
223 223
224 224 if newheights <= 1:
225 225 raise ValueError, "filterByHeights: Too few heights. Current number of heights is %d and window is %d" %(self.dataOut.nHeights, window)
226 226
227 227 if self.dataOut.flagDataAsBlock:
228 228 """
229 229 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
230 230 """
231 231 buffer = self.dataOut.data[:, :, 0:self.dataOut.nHeights-r]
232 232 buffer = buffer.reshape(self.dataOut.nChannels,self.dataOut.nProfiles,self.dataOut.nHeights/window,window)
233 233 buffer = numpy.sum(buffer,3)
234 234
235 235 else:
236 236 buffer = self.dataOut.data[:,0:self.dataOut.nHeights-r]
237 237 buffer = buffer.reshape(self.dataOut.nChannels,self.dataOut.nHeights/window,window)
238 238 buffer = numpy.sum(buffer,2)
239 239
240 240 self.dataOut.data = buffer
241 241 self.dataOut.heightList = self.dataOut.heightList[0] + numpy.arange( newheights )*newdelta
242 242 self.dataOut.windowOfFilter = window
243 243
244 244 def setH0(self, h0, deltaHeight = None):
245 245
246 246 if not deltaHeight:
247 247 deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
248 248
249 249 nHeights = self.dataOut.nHeights
250 250
251 251 newHeiRange = h0 + numpy.arange(nHeights)*deltaHeight
252 252
253 253 self.dataOut.heightList = newHeiRange
254 254
255 255 def deFlip(self, channelList = []):
256 256
257 257 data = self.dataOut.data.copy()
258 258
259 259 if self.dataOut.flagDataAsBlock:
260 260 flip = self.flip
261 261 profileList = range(self.dataOut.nProfiles)
262 262
263 263 if not channelList:
264 264 for thisProfile in profileList:
265 265 data[:,thisProfile,:] = data[:,thisProfile,:]*flip
266 266 flip *= -1.0
267 267 else:
268 268 for thisChannel in channelList:
269 269 if thisChannel not in self.dataOut.channelList:
270 270 continue
271 271
272 272 for thisProfile in profileList:
273 273 data[thisChannel,thisProfile,:] = data[thisChannel,thisProfile,:]*flip
274 274 flip *= -1.0
275 275
276 276 self.flip = flip
277 277
278 278 else:
279 279 if not channelList:
280 280 data[:,:] = data[:,:]*self.flip
281 281 else:
282 282 for thisChannel in channelList:
283 283 if thisChannel not in self.dataOut.channelList:
284 284 continue
285 285
286 286 data[thisChannel,:] = data[thisChannel,:]*self.flip
287 287
288 288 self.flip *= -1.
289 289
290 290 self.dataOut.data = data
291 291
292 292 def setRadarFrequency(self, frequency=None):
293 293
294 294 if frequency != None:
295 295 self.dataOut.frequency = frequency
296 296
297 297 return 1
298 298
299 299 def interpolateHeights(self, topLim, botLim):
300 300 #69 al 72 para julia
301 301 #82-84 para meteoros
302 302 if len(numpy.shape(self.dataOut.data))==2:
303 303 sampInterp = (self.dataOut.data[:,botLim-1] + self.dataOut.data[:,topLim+1])/2
304 304 sampInterp = numpy.transpose(numpy.tile(sampInterp,(topLim-botLim + 1,1)))
305 305 #self.dataOut.data[:,botLim:limSup+1] = sampInterp
306 306 self.dataOut.data[:,botLim:topLim+1] = sampInterp
307 307 else:
308 308 nHeights = self.dataOut.data.shape[2]
309 309 x = numpy.hstack((numpy.arange(botLim),numpy.arange(topLim+1,nHeights)))
310 310 y = self.dataOut.data[:,:,range(botLim)+range(topLim+1,nHeights)]
311 311 f = interpolate.interp1d(x, y, axis = 2)
312 312 xnew = numpy.arange(botLim,topLim+1)
313 313 ynew = f(xnew)
314 314
315 315 self.dataOut.data[:,:,botLim:topLim+1] = ynew
316 316
317 317 # import collections
318 318
319 319 class CohInt(Operation):
320 320
321 321 isConfig = False
322 322
323 323 __profIndex = 0
324 324 __withOverapping = False
325 325
326 326 __byTime = False
327 327 __initime = None
328 328 __lastdatatime = None
329 329 __integrationtime = None
330 330
331 331 __buffer = None
332 332
333 333 __dataReady = False
334 334
335 335 n = None
336 336
337 parameters = {
338 'id': global_type_string,
339 'wintitle': global_type_string,
340 'pairsList': global_type_pairsList,
341 'showprofile': global_type_boolean,
342 'xmin': global_type_float,
343 'xmax': global_type_float,
344 'ymin': global_type_float,
345 'ymax': global_type_float,
346 'zmin': global_type_float,
347 'zmax': global_type_float,
348 'timerange': global_type_float,
349 'phase_min': global_type_float,
350 'phase_max': global_type_float,
351 'save': global_type_boolean,
352 'figpath': global_type_string,
353 'figfile': global_type_string,
354 'ftp': global_type_boolean,
355 'wr_period': global_type_integer,
356 'coherence_cmap': global_type_colormap,
357 'phase_cmap': global_type_colormap,
358 'show': global_type_boolean,
359 'server': global_type_string,
360 'folder': global_type_string,
361 'username': global_type_string,
362 'password': global_type_string,
363 'ftp_wei': global_type_integer,
364 'exp_code': global_type_integer,
365 'sub_exp_code': global_type_integer,
366 'plot_pos': global_type_integer,
367 }
337 368
338 369 def __init__(self, **kwargs):
339 370
340 371 Operation.__init__(self, **kwargs)
341 372
342 373 # self.isConfig = False
343 374
344 375 def setup(self, n=None, timeInterval=None, overlapping=False, byblock=False):
345 376 """
346 377 Set the parameters of the integration class.
347 378
348 379 Inputs:
349 380
350 n : Number of coherent integrations
351 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
352 overlapping :
353
381 n : Number of coherent integrations
382 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
383 overlapping :
354 384 """
355 385
356 386 self.__initime = None
357 387 self.__lastdatatime = 0
358 388 self.__buffer = None
359 389 self.__dataReady = False
360 390 self.byblock = byblock
361 391
362 392 if n == None and timeInterval == None:
363 393 raise ValueError, "n or timeInterval should be specified ..."
364 394
365 395 if n != None:
366 396 self.n = n
367 397 self.__byTime = False
368 398 else:
369 399 self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line
370 400 self.n = 9999
371 401 self.__byTime = True
372 402
373 403 if overlapping:
374 404 self.__withOverapping = True
375 405 self.__buffer = None
376 406 else:
377 407 self.__withOverapping = False
378 408 self.__buffer = 0
379 409
380 410 self.__profIndex = 0
381 411
382 412 def putData(self, data):
383 413
384 414 """
385 415 Add a profile to the __buffer and increase in one the __profileIndex
386 416
387 417 """
388 418
389 419 if not self.__withOverapping:
390 420 self.__buffer += data.copy()
391 421 self.__profIndex += 1
392 422 return
393 423
394 424 #Overlapping data
395 425 nChannels, nHeis = data.shape
396 426 data = numpy.reshape(data, (1, nChannels, nHeis))
397 427
398 428 #If the buffer is empty then it takes the data value
399 429 if self.__buffer is None:
400 430 self.__buffer = data
401 431 self.__profIndex += 1
402 432 return
403 433
404 434 #If the buffer length is lower than n then stakcing the data value
405 435 if self.__profIndex < self.n:
406 436 self.__buffer = numpy.vstack((self.__buffer, data))
407 437 self.__profIndex += 1
408 438 return
409 439
410 440 #If the buffer length is equal to n then replacing the last buffer value with the data value
411 441 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
412 442 self.__buffer[self.n-1] = data
413 443 self.__profIndex = self.n
414 444 return
415 445
416 446
417 447 def pushData(self):
418 448 """
419 449 Return the sum of the last profiles and the profiles used in the sum.
420 450
421 451 Affected:
422 452
423 453 self.__profileIndex
424 454
425 455 """
426 456
427 457 if not self.__withOverapping:
428 458 data = self.__buffer
429 459 n = self.__profIndex
430 460
431 461 self.__buffer = 0
432 462 self.__profIndex = 0
433 463
434 464 return data, n
435 465
436 466 #Integration with Overlapping
437 467 data = numpy.sum(self.__buffer, axis=0)
438 468 n = self.__profIndex
439 469
440 470 return data, n
441 471
442 472 def byProfiles(self, data):
443 473
444 474 self.__dataReady = False
445 475 avgdata = None
446 476 # n = None
447 477
448 478 self.putData(data)
449 479
450 480 if self.__profIndex == self.n:
451 481
452 482 avgdata, n = self.pushData()
453 483 self.__dataReady = True
454 484
455 485 return avgdata
456 486
457 487 def byTime(self, data, datatime):
458 488
459 489 self.__dataReady = False
460 490 avgdata = None
461 491 n = None
462 492
463 493 self.putData(data)
464 494
465 495 if (datatime - self.__initime) >= self.__integrationtime:
466 496 avgdata, n = self.pushData()
467 497 self.n = n
468 498 self.__dataReady = True
469 499
470 500 return avgdata
471 501
472 502 def integrate(self, data, datatime=None):
473 503
474 504 if self.__initime == None:
475 505 self.__initime = datatime
476 506
477 507 if self.__byTime:
478 508 avgdata = self.byTime(data, datatime)
479 509 else:
480 510 avgdata = self.byProfiles(data)
481 511
482 512
483 513 self.__lastdatatime = datatime
484 514
485 515 if avgdata is None:
486 516 return None, None
487 517
488 518 avgdatatime = self.__initime
489 519
490 520 deltatime = datatime -self.__lastdatatime
491 521
492 522 if not self.__withOverapping:
493 523 self.__initime = datatime
494 524 else:
495 525 self.__initime += deltatime
496 526
497 527 return avgdata, avgdatatime
498 528
499 529 def integrateByBlock(self, dataOut):
500 530
501 531 times = int(dataOut.data.shape[1]/self.n)
502 532 avgdata = numpy.zeros((dataOut.nChannels, times, dataOut.nHeights), dtype=numpy.complex)
503 533
504 534 id_min = 0
505 535 id_max = self.n
506 536
507 537 for i in range(times):
508 538 junk = dataOut.data[:,id_min:id_max,:]
509 539 avgdata[:,i,:] = junk.sum(axis=1)
510 540 id_min += self.n
511 541 id_max += self.n
512 542
513 543 timeInterval = dataOut.ippSeconds*self.n
514 544 avgdatatime = (times - 1) * timeInterval + dataOut.utctime
515 545 self.__dataReady = True
516 546 return avgdata, avgdatatime
517 547
518 548
519 549 def run(self, dataOut, n=None, timeInterval=None, overlapping=False, byblock=False, **kwargs):
520 550 if not self.isConfig:
521 551 self.setup(n=n, timeInterval=timeInterval, overlapping=overlapping, byblock=byblock, **kwargs)
522 552 self.isConfig = True
523 553
524 554 if dataOut.flagDataAsBlock:
525 555 """
526 556 Si la data es leida por bloques, dimension = [nChannels, nProfiles, nHeis]
527 557 """
528 558 avgdata, avgdatatime = self.integrateByBlock(dataOut)
529 559 dataOut.nProfiles /= self.n
530 560 else:
531 561 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
532 562
533 563 # dataOut.timeInterval *= n
534 564 dataOut.flagNoData = True
535 565
536 566 if self.__dataReady:
537 567 dataOut.data = avgdata
538 568 dataOut.nCohInt *= self.n
539 569 dataOut.utctime = avgdatatime
540 570 # dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
541 571 dataOut.flagNoData = False
542 572
543 573 class Decoder(Operation):
544 574
545 575 isConfig = False
546 576 __profIndex = 0
547 577
548 578 code = None
549 579
550 580 nCode = None
551 581 nBaud = None
552
582
583 parameters = {
584 'code': global_type_list,
585 'nCode': global_type_integer,
586 'nBaud': global_type_integer,
587 'mode': global_type_integer,
588 'osamp': global_type_float,
589 }
553 590
554 591 def __init__(self, **kwargs):
555 592
556 593 Operation.__init__(self, **kwargs)
557 594
558 595 self.times = None
559 596 self.osamp = None
560 597 # self.__setValues = False
561 598 self.isConfig = False
562 599
563 600 def setup(self, code, osamp, dataOut):
564 601
565 602 self.__profIndex = 0
566 603
567 604 self.code = code
568 605
569 606 self.nCode = len(code)
570 607 self.nBaud = len(code[0])
571 608
572 609 if (osamp != None) and (osamp >1):
573 610 self.osamp = osamp
574 611 self.code = numpy.repeat(code, repeats=self.osamp, axis=1)
575 612 self.nBaud = self.nBaud*self.osamp
576 613
577 614 self.__nChannels = dataOut.nChannels
578 615 self.__nProfiles = dataOut.nProfiles
579 616 self.__nHeis = dataOut.nHeights
580 617
581 618 if self.__nHeis < self.nBaud:
582 619 raise ValueError, 'Number of heights (%d) should be greater than number of bauds (%d)' %(self.__nHeis, self.nBaud)
583 620
584 621 #Frequency
585 622 __codeBuffer = numpy.zeros((self.nCode, self.__nHeis), dtype=numpy.complex)
586 623
587 624 __codeBuffer[:,0:self.nBaud] = self.code
588 625
589 626 self.fft_code = numpy.conj(numpy.fft.fft(__codeBuffer, axis=1))
590 627
591 628 if dataOut.flagDataAsBlock:
592 629
593 630 self.ndatadec = self.__nHeis #- self.nBaud + 1
594 631
595 632 self.datadecTime = numpy.zeros((self.__nChannels, self.__nProfiles, self.ndatadec), dtype=numpy.complex)
596 633
597 634 else:
598 635
599 636 #Time
600 637 self.ndatadec = self.__nHeis #- self.nBaud + 1
601 638
602 639 self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex)
603 640
604 641 def __convolutionInFreq(self, data):
605 642
606 643 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
607 644
608 645 fft_data = numpy.fft.fft(data, axis=1)
609 646
610 647 conv = fft_data*fft_code
611 648
612 649 data = numpy.fft.ifft(conv,axis=1)
613 650
614 651 return data
615 652
616 653 def __convolutionInFreqOpt(self, data):
617 654
618 655 raise NotImplementedError
619 656
620 657 def __convolutionInTime(self, data):
621 658
622 659 code = self.code[self.__profIndex]
623 660
624 661 for i in range(self.__nChannels):
625 662 self.datadecTime[i,:] = numpy.correlate(data[i,:], code, mode='full')[self.nBaud-1:]
626 663
627 664 return self.datadecTime
628 665
629 666 #@profile
630 667 def oldCorrelate(self, i, data, code_block):
631 668 profilesList = xrange(self.__nProfiles)
632 669 for j in profilesList:
633 670 self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:]
634 671
635 672 #@profile
636 673 def __convolutionByBlockInTime(self, data):
637 674
638 675 repetitions = self.__nProfiles / self.nCode
639 676
640 677 junk = numpy.lib.stride_tricks.as_strided(self.code, (repetitions, self.code.size), (0, self.code.itemsize))
641 678 junk = junk.flatten()
642 679 code_block = numpy.reshape(junk, (self.nCode*repetitions, self.nBaud))
643 680 profilesList = xrange(self.__nProfiles)
644 681
645 682 # def toVectorize(a,b):
646 683 # return numpy.correlate(a,b, mode='full')
647 684 # vectorized = numpy.vectorize(toVectorize, signature='(n),(m)->(k)')
648 685 for i in range(self.__nChannels):
649 686 # self.datadecTime[i,:,:] = numpy.array([numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:] for j in profilesList ])
650 687 # def func(i, j):
651 688 # self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:]
652 689 # map(lambda j: func(i, j), range(self.__nProfiles))
653 690 #print data[i,:,:].shape
654 691 # self.datadecTime[i,:,:] = vectorized(data[i,:,:], code_block[:,:])[:,self.nBaud-1:]
655 692 for j in profilesList:
656 693 self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:]
657 694 # print data[i,:,:]
658 695 # print cSchain.correlateByBlock(data[i,:,:], code_block, 2)
659 696 # self.datadecTime[i,:,:] = cSchain.correlateByBlock(data[i,:,:], code_block, 2)
660 697 # print self.datadecTime[i,:,:]
661 698 #print self.datadecTime[i,:,:].shape
662 699 return self.datadecTime
663 700
664 701
665 702 def __convolutionByBlockInFreq(self, data):
666 703
667 704 raise NotImplementedError, "Decoder by frequency fro Blocks not implemented"
668 705
669 706
670 707 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
671 708
672 709 fft_data = numpy.fft.fft(data, axis=2)
673 710
674 711 conv = fft_data*fft_code
675 712
676 713 data = numpy.fft.ifft(conv,axis=2)
677 714
678 715 return data
679 716
680 717
681 718 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0, osamp=None, times=None):
682 719
683 720 if dataOut.flagDecodeData:
684 721 print "This data is already decoded, recoding again ..."
685 722
686 723 if not self.isConfig:
687 724
688 725 if code is None:
689 726 if dataOut.code is None:
690 727 raise ValueError, "Code could not be read from %s instance. Enter a value in Code parameter" %dataOut.type
691 728
692 729 code = dataOut.code
693 730 else:
694 731 code = numpy.array(code).reshape(nCode,nBaud)
695 732
696 733 self.setup(code, osamp, dataOut)
697 734
698 735 self.isConfig = True
699 736
700 737 if mode == 3:
701 738 sys.stderr.write("Decoder Warning: mode=%d is not valid, using mode=0\n" %mode)
702 739
703 740 if times != None:
704 741 sys.stderr.write("Decoder Warning: Argument 'times' in not used anymore\n")
705 742
706 743 if self.code is None:
707 744 print "Fail decoding: Code is not defined."
708 745 return
709 746
710 747 self.__nProfiles = dataOut.nProfiles
711 748 datadec = None
712 749
713 750 if mode == 3:
714 751 mode = 0
715 752
716 753 if dataOut.flagDataAsBlock:
717 754 """
718 755 Decoding when data have been read as block,
719 756 """
720 757
721 758 if mode == 0:
722 759 datadec = self.__convolutionByBlockInTime(dataOut.data)
723 760 if mode == 1:
724 761 datadec = self.__convolutionByBlockInFreq(dataOut.data)
725 762 else:
726 763 """
727 764 Decoding when data have been read profile by profile
728 765 """
729 766 if mode == 0:
730 767 datadec = self.__convolutionInTime(dataOut.data)
731 768
732 769 if mode == 1:
733 770 datadec = self.__convolutionInFreq(dataOut.data)
734 771
735 772 if mode == 2:
736 773 datadec = self.__convolutionInFreqOpt(dataOut.data)
737 774
738 775 if datadec is None:
739 776 raise ValueError, "Codification mode selected is not valid: mode=%d. Try selecting 0 or 1" %mode
740 777
741 778 dataOut.code = self.code
742 779 dataOut.nCode = self.nCode
743 780 dataOut.nBaud = self.nBaud
744 781
745 782 dataOut.data = datadec
746 783
747 784 dataOut.heightList = dataOut.heightList[0:datadec.shape[-1]]
748 785
749 786 dataOut.flagDecodeData = True #asumo q la data esta decodificada
750 787
751 788 if self.__profIndex == self.nCode-1:
752 789 self.__profIndex = 0
753 790 return 1
754 791
755 792 self.__profIndex += 1
756 793
757 794 return 1
758 795 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
759 796
760 797
761 798 class ProfileConcat(Operation):
762 799
763 800 isConfig = False
764 801 buffer = None
765 802
766 803 def __init__(self, **kwargs):
767 804
768 805 Operation.__init__(self, **kwargs)
769 806 self.profileIndex = 0
770 807
771 808 def reset(self):
772 809 self.buffer = numpy.zeros_like(self.buffer)
773 810 self.start_index = 0
774 811 self.times = 1
775 812
776 813 def setup(self, data, m, n=1):
777 814 self.buffer = numpy.zeros((data.shape[0],data.shape[1]*m),dtype=type(data[0,0]))
778 815 self.nHeights = data.shape[1]#.nHeights
779 816 self.start_index = 0
780 817 self.times = 1
781 818
782 819 def concat(self, data):
783 820
784 821 self.buffer[:,self.start_index:self.nHeights*self.times] = data.copy()
785 822 self.start_index = self.start_index + self.nHeights
786 823
787 824 def run(self, dataOut, m):
788 825
789 826 dataOut.flagNoData = True
790 827
791 828 if not self.isConfig:
792 829 self.setup(dataOut.data, m, 1)
793 830 self.isConfig = True
794 831
795 832 if dataOut.flagDataAsBlock:
796 833 raise ValueError, "ProfileConcat can only be used when voltage have been read profile by profile, getBlock = False"
797 834
798 835 else:
799 836 self.concat(dataOut.data)
800 837 self.times += 1
801 838 if self.times > m:
802 839 dataOut.data = self.buffer
803 840 self.reset()
804 841 dataOut.flagNoData = False
805 842 # se deben actualizar mas propiedades del header y del objeto dataOut, por ejemplo, las alturas
806 843 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
807 844 xf = dataOut.heightList[0] + dataOut.nHeights * deltaHeight * m
808 845 dataOut.heightList = numpy.arange(dataOut.heightList[0], xf, deltaHeight)
809 846 dataOut.ippSeconds *= m
810 847
811 848 class ProfileSelector(Operation):
812 849
813 850 profileIndex = None
814 851 # Tamanho total de los perfiles
815 852 nProfiles = None
816 853
817 854 def __init__(self, **kwargs):
818 855
819 856 Operation.__init__(self, **kwargs)
820 857 self.profileIndex = 0
821 858
822 859 def incProfileIndex(self):
823 860
824 861 self.profileIndex += 1
825 862
826 863 if self.profileIndex >= self.nProfiles:
827 864 self.profileIndex = 0
828 865
829 866 def isThisProfileInRange(self, profileIndex, minIndex, maxIndex):
830 867
831 868 if profileIndex < minIndex:
832 869 return False
833 870
834 871 if profileIndex > maxIndex:
835 872 return False
836 873
837 874 return True
838 875
839 876 def isThisProfileInList(self, profileIndex, profileList):
840 877
841 878 if profileIndex not in profileList:
842 879 return False
843 880
844 881 return True
845 882
846 883 def run(self, dataOut, profileList=None, profileRangeList=None, beam=None, byblock=False, rangeList = None, nProfiles=None):
847 884
848 885 """
849 886 ProfileSelector:
850 887
851 888 Inputs:
852 889 profileList : Index of profiles selected. Example: profileList = (0,1,2,7,8)
853 890
854 891 profileRangeList : Minimum and maximum profile indexes. Example: profileRangeList = (4, 30)
855 892
856 893 rangeList : List of profile ranges. Example: rangeList = ((4, 30), (32, 64), (128, 256))
857 894
858 895 """
859 896
860 897 if rangeList is not None:
861 898 if type(rangeList[0]) not in (tuple, list):
862 899 rangeList = [rangeList]
863 900
864 901 dataOut.flagNoData = True
865 902
866 903 if dataOut.flagDataAsBlock:
867 904 """
868 905 data dimension = [nChannels, nProfiles, nHeis]
869 906 """
870 907 if profileList != None:
871 908 dataOut.data = dataOut.data[:,profileList,:]
872 909
873 910 if profileRangeList != None:
874 911 minIndex = profileRangeList[0]
875 912 maxIndex = profileRangeList[1]
876 913 profileList = range(minIndex, maxIndex+1)
877 914
878 915 dataOut.data = dataOut.data[:,minIndex:maxIndex+1,:]
879 916
880 917 if rangeList != None:
881 918
882 919 profileList = []
883 920
884 921 for thisRange in rangeList:
885 922 minIndex = thisRange[0]
886 923 maxIndex = thisRange[1]
887 924
888 925 profileList.extend(range(minIndex, maxIndex+1))
889 926
890 927 dataOut.data = dataOut.data[:,profileList,:]
891 928
892 929 dataOut.nProfiles = len(profileList)
893 930 dataOut.profileIndex = dataOut.nProfiles - 1
894 931 dataOut.flagNoData = False
895 932
896 933 return True
897 934
898 935 """
899 936 data dimension = [nChannels, nHeis]
900 937 """
901 938
902 939 if profileList != None:
903 940
904 941 if self.isThisProfileInList(dataOut.profileIndex, profileList):
905 942
906 943 self.nProfiles = len(profileList)
907 944 dataOut.nProfiles = self.nProfiles
908 945 dataOut.profileIndex = self.profileIndex
909 946 dataOut.flagNoData = False
910 947
911 948 self.incProfileIndex()
912 949 return True
913 950
914 951 if profileRangeList != None:
915 952
916 953 minIndex = profileRangeList[0]
917 954 maxIndex = profileRangeList[1]
918 955
919 956 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
920 957
921 958 self.nProfiles = maxIndex - minIndex + 1
922 959 dataOut.nProfiles = self.nProfiles
923 960 dataOut.profileIndex = self.profileIndex
924 961 dataOut.flagNoData = False
925 962
926 963 self.incProfileIndex()
927 964 return True
928 965
929 966 if rangeList != None:
930 967
931 968 nProfiles = 0
932 969
933 970 for thisRange in rangeList:
934 971 minIndex = thisRange[0]
935 972 maxIndex = thisRange[1]
936 973
937 974 nProfiles += maxIndex - minIndex + 1
938 975
939 976 for thisRange in rangeList:
940 977
941 978 minIndex = thisRange[0]
942 979 maxIndex = thisRange[1]
943 980
944 981 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
945 982
946 983 self.nProfiles = nProfiles
947 984 dataOut.nProfiles = self.nProfiles
948 985 dataOut.profileIndex = self.profileIndex
949 986 dataOut.flagNoData = False
950 987
951 988 self.incProfileIndex()
952 989
953 990 break
954 991
955 992 return True
956 993
957 994
958 995 if beam != None: #beam is only for AMISR data
959 996 if self.isThisProfileInList(dataOut.profileIndex, dataOut.beamRangeDict[beam]):
960 997 dataOut.flagNoData = False
961 998 dataOut.profileIndex = self.profileIndex
962 999
963 1000 self.incProfileIndex()
964 1001
965 1002 return True
966 1003
967 1004 raise ValueError, "ProfileSelector needs profileList, profileRangeList or rangeList parameter"
968 1005
969 1006 return False
970 1007
971 1008 class Reshaper(Operation):
972 1009
973 1010 def __init__(self, **kwargs):
974 1011
975 1012 Operation.__init__(self, **kwargs)
976 1013
977 1014 self.__buffer = None
978 1015 self.__nitems = 0
979 1016
980 1017 def __appendProfile(self, dataOut, nTxs):
981 1018
982 1019 if self.__buffer is None:
983 1020 shape = (dataOut.nChannels, int(dataOut.nHeights/nTxs) )
984 1021 self.__buffer = numpy.empty(shape, dtype = dataOut.data.dtype)
985 1022
986 1023 ini = dataOut.nHeights * self.__nitems
987 1024 end = ini + dataOut.nHeights
988 1025
989 1026 self.__buffer[:, ini:end] = dataOut.data
990 1027
991 1028 self.__nitems += 1
992 1029
993 1030 return int(self.__nitems*nTxs)
994 1031
995 1032 def __getBuffer(self):
996 1033
997 1034 if self.__nitems == int(1./self.__nTxs):
998 1035
999 1036 self.__nitems = 0
1000 1037
1001 1038 return self.__buffer.copy()
1002 1039
1003 1040 return None
1004 1041
1005 1042 def __checkInputs(self, dataOut, shape, nTxs):
1006 1043
1007 1044 if shape is None and nTxs is None:
1008 1045 raise ValueError, "Reshaper: shape of factor should be defined"
1009 1046
1010 1047 if nTxs:
1011 1048 if nTxs < 0:
1012 1049 raise ValueError, "nTxs should be greater than 0"
1013 1050
1014 1051 if nTxs < 1 and dataOut.nProfiles % (1./nTxs) != 0:
1015 1052 raise ValueError, "nProfiles= %d is not divisibled by (1./nTxs) = %f" %(dataOut.nProfiles, (1./nTxs))
1016 1053
1017 1054 shape = [dataOut.nChannels, dataOut.nProfiles*nTxs, dataOut.nHeights/nTxs]
1018 1055
1019 1056 return shape, nTxs
1020 1057
1021 1058 if len(shape) != 2 and len(shape) != 3:
1022 1059 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)
1023 1060
1024 1061 if len(shape) == 2:
1025 1062 shape_tuple = [dataOut.nChannels]
1026 1063 shape_tuple.extend(shape)
1027 1064 else:
1028 1065 shape_tuple = list(shape)
1029 1066
1030 1067 nTxs = 1.0*shape_tuple[1]/dataOut.nProfiles
1031 1068
1032 1069 return shape_tuple, nTxs
1033 1070
1034 1071 def run(self, dataOut, shape=None, nTxs=None):
1035 1072
1036 1073 shape_tuple, self.__nTxs = self.__checkInputs(dataOut, shape, nTxs)
1037 1074
1038 1075 dataOut.flagNoData = True
1039 1076 profileIndex = None
1040 1077
1041 1078 if dataOut.flagDataAsBlock:
1042 1079
1043 1080 dataOut.data = numpy.reshape(dataOut.data, shape_tuple)
1044 1081 dataOut.flagNoData = False
1045 1082
1046 1083 profileIndex = int(dataOut.nProfiles*self.__nTxs) - 1
1047 1084
1048 1085 else:
1049 1086
1050 1087 if self.__nTxs < 1:
1051 1088
1052 1089 self.__appendProfile(dataOut, self.__nTxs)
1053 1090 new_data = self.__getBuffer()
1054 1091
1055 1092 if new_data is not None:
1056 1093 dataOut.data = new_data
1057 1094 dataOut.flagNoData = False
1058 1095
1059 1096 profileIndex = dataOut.profileIndex*nTxs
1060 1097
1061 1098 else:
1062 1099 raise ValueError, "nTxs should be greater than 0 and lower than 1, or use VoltageReader(..., getblock=True)"
1063 1100
1064 1101 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1065 1102
1066 1103 dataOut.heightList = numpy.arange(dataOut.nHeights/self.__nTxs) * deltaHeight + dataOut.heightList[0]
1067 1104
1068 1105 dataOut.nProfiles = int(dataOut.nProfiles*self.__nTxs)
1069 1106
1070 1107 dataOut.profileIndex = profileIndex
1071 1108
1072 1109 dataOut.ippSeconds /= self.__nTxs
1073 1110
1074 1111 class SplitProfiles(Operation):
1075 1112
1076 1113 def __init__(self, **kwargs):
1077 1114
1078 1115 Operation.__init__(self, **kwargs)
1079 1116
1080 1117 def run(self, dataOut, n):
1081 1118
1082 1119 dataOut.flagNoData = True
1083 1120 profileIndex = None
1084 1121
1085 1122 if dataOut.flagDataAsBlock:
1086 1123
1087 1124 #nchannels, nprofiles, nsamples
1088 1125 shape = dataOut.data.shape
1089 1126
1090 1127 if shape[2] % n != 0:
1091 1128 raise ValueError, "Could not split the data, n=%d has to be multiple of %d" %(n, shape[2])
1092 1129
1093 1130 new_shape = shape[0], shape[1]*n, shape[2]/n
1094 1131
1095 1132 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1096 1133 dataOut.flagNoData = False
1097 1134
1098 1135 profileIndex = int(dataOut.nProfiles/n) - 1
1099 1136
1100 1137 else:
1101 1138
1102 1139 raise ValueError, "Could not split the data when is read Profile by Profile. Use VoltageReader(..., getblock=True)"
1103 1140
1104 1141 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1105 1142
1106 1143 dataOut.heightList = numpy.arange(dataOut.nHeights/n) * deltaHeight + dataOut.heightList[0]
1107 1144
1108 1145 dataOut.nProfiles = int(dataOut.nProfiles*n)
1109 1146
1110 1147 dataOut.profileIndex = profileIndex
1111 1148
1112 1149 dataOut.ippSeconds /= n
1113 1150
1114 1151 class CombineProfiles(Operation):
1115
1152 parameters = {
1153 'n': global_type_integer,
1154 }
1116 1155 def __init__(self, **kwargs):
1117 1156
1118 1157 Operation.__init__(self, **kwargs)
1119 1158
1120 1159 self.__remData = None
1121 1160 self.__profileIndex = 0
1122 1161
1123 1162 def run(self, dataOut, n):
1124 1163
1125 1164 dataOut.flagNoData = True
1126 1165 profileIndex = None
1127 1166
1128 1167 if dataOut.flagDataAsBlock:
1129 1168
1130 1169 #nchannels, nprofiles, nsamples
1131 1170 shape = dataOut.data.shape
1132 1171 new_shape = shape[0], shape[1]/n, shape[2]*n
1133 1172
1134 1173 if shape[1] % n != 0:
1135 1174 raise ValueError, "Could not split the data, n=%d has to be multiple of %d" %(n, shape[1])
1136 1175
1137 1176 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1138 1177 dataOut.flagNoData = False
1139 1178
1140 1179 profileIndex = int(dataOut.nProfiles*n) - 1
1141 1180
1142 1181 else:
1143 1182
1144 1183 #nchannels, nsamples
1145 1184 if self.__remData is None:
1146 1185 newData = dataOut.data
1147 1186 else:
1148 1187 newData = numpy.concatenate((self.__remData, dataOut.data), axis=1)
1149 1188
1150 1189 self.__profileIndex += 1
1151 1190
1152 1191 if self.__profileIndex < n:
1153 1192 self.__remData = newData
1154 1193 #continue
1155 1194 return
1156 1195
1157 1196 self.__profileIndex = 0
1158 1197 self.__remData = None
1159 1198
1160 1199 dataOut.data = newData
1161 1200 dataOut.flagNoData = False
1162 1201
1163 1202 profileIndex = dataOut.profileIndex/n
1164 1203
1165 1204
1166 1205 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1167 1206
1168 1207 dataOut.heightList = numpy.arange(dataOut.nHeights*n) * deltaHeight + dataOut.heightList[0]
1169 1208
1170 1209 dataOut.nProfiles = int(dataOut.nProfiles/n)
1171 1210
1172 1211 dataOut.profileIndex = profileIndex
1173 1212
1174 1213 dataOut.ippSeconds *= n
1175 1214
1176 1215 # import collections
1177 1216 # from scipy.stats import mode
1178 1217 #
1179 1218 # class Synchronize(Operation):
1180 1219 #
1181 1220 # isConfig = False
1182 1221 # __profIndex = 0
1183 1222 #
1184 1223 # def __init__(self, **kwargs):
1185 1224 #
1186 1225 # Operation.__init__(self, **kwargs)
1187 1226 # # self.isConfig = False
1188 1227 # self.__powBuffer = None
1189 1228 # self.__startIndex = 0
1190 1229 # self.__pulseFound = False
1191 1230 #
1192 1231 # def __findTxPulse(self, dataOut, channel=0, pulse_with = None):
1193 1232 #
1194 1233 # #Read data
1195 1234 #
1196 1235 # powerdB = dataOut.getPower(channel = channel)
1197 1236 # noisedB = dataOut.getNoise(channel = channel)[0]
1198 1237 #
1199 1238 # self.__powBuffer.extend(powerdB.flatten())
1200 1239 #
1201 1240 # dataArray = numpy.array(self.__powBuffer)
1202 1241 #
1203 1242 # filteredPower = numpy.correlate(dataArray, dataArray[0:self.__nSamples], "same")
1204 1243 #
1205 1244 # maxValue = numpy.nanmax(filteredPower)
1206 1245 #
1207 1246 # if maxValue < noisedB + 10:
1208 1247 # #No se encuentra ningun pulso de transmision
1209 1248 # return None
1210 1249 #
1211 1250 # maxValuesIndex = numpy.where(filteredPower > maxValue - 0.1*abs(maxValue))[0]
1212 1251 #
1213 1252 # if len(maxValuesIndex) < 2:
1214 1253 # #Solo se encontro un solo pulso de transmision de un baudio, esperando por el siguiente TX
1215 1254 # return None
1216 1255 #
1217 1256 # phasedMaxValuesIndex = maxValuesIndex - self.__nSamples
1218 1257 #
1219 1258 # #Seleccionar solo valores con un espaciamiento de nSamples
1220 1259 # pulseIndex = numpy.intersect1d(maxValuesIndex, phasedMaxValuesIndex)
1221 1260 #
1222 1261 # if len(pulseIndex) < 2:
1223 1262 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1224 1263 # return None
1225 1264 #
1226 1265 # spacing = pulseIndex[1:] - pulseIndex[:-1]
1227 1266 #
1228 1267 # #remover senales que se distancien menos de 10 unidades o muestras
1229 1268 # #(No deberian existir IPP menor a 10 unidades)
1230 1269 #
1231 1270 # realIndex = numpy.where(spacing > 10 )[0]
1232 1271 #
1233 1272 # if len(realIndex) < 2:
1234 1273 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1235 1274 # return None
1236 1275 #
1237 1276 # #Eliminar pulsos anchos (deja solo la diferencia entre IPPs)
1238 1277 # realPulseIndex = pulseIndex[realIndex]
1239 1278 #
1240 1279 # period = mode(realPulseIndex[1:] - realPulseIndex[:-1])[0][0]
1241 1280 #
1242 1281 # print "IPP = %d samples" %period
1243 1282 #
1244 1283 # self.__newNSamples = dataOut.nHeights #int(period)
1245 1284 # self.__startIndex = int(realPulseIndex[0])
1246 1285 #
1247 1286 # return 1
1248 1287 #
1249 1288 #
1250 1289 # def setup(self, nSamples, nChannels, buffer_size = 4):
1251 1290 #
1252 1291 # self.__powBuffer = collections.deque(numpy.zeros( buffer_size*nSamples,dtype=numpy.float),
1253 1292 # maxlen = buffer_size*nSamples)
1254 1293 #
1255 1294 # bufferList = []
1256 1295 #
1257 1296 # for i in range(nChannels):
1258 1297 # bufferByChannel = collections.deque(numpy.zeros( buffer_size*nSamples, dtype=numpy.complex) + numpy.NAN,
1259 1298 # maxlen = buffer_size*nSamples)
1260 1299 #
1261 1300 # bufferList.append(bufferByChannel)
1262 1301 #
1263 1302 # self.__nSamples = nSamples
1264 1303 # self.__nChannels = nChannels
1265 1304 # self.__bufferList = bufferList
1266 1305 #
1267 1306 # def run(self, dataOut, channel = 0):
1268 1307 #
1269 1308 # if not self.isConfig:
1270 1309 # nSamples = dataOut.nHeights
1271 1310 # nChannels = dataOut.nChannels
1272 1311 # self.setup(nSamples, nChannels)
1273 1312 # self.isConfig = True
1274 1313 #
1275 1314 # #Append new data to internal buffer
1276 1315 # for thisChannel in range(self.__nChannels):
1277 1316 # bufferByChannel = self.__bufferList[thisChannel]
1278 1317 # bufferByChannel.extend(dataOut.data[thisChannel])
1279 1318 #
1280 1319 # if self.__pulseFound:
1281 1320 # self.__startIndex -= self.__nSamples
1282 1321 #
1283 1322 # #Finding Tx Pulse
1284 1323 # if not self.__pulseFound:
1285 1324 # indexFound = self.__findTxPulse(dataOut, channel)
1286 1325 #
1287 1326 # if indexFound == None:
1288 1327 # dataOut.flagNoData = True
1289 1328 # return
1290 1329 #
1291 1330 # self.__arrayBuffer = numpy.zeros((self.__nChannels, self.__newNSamples), dtype = numpy.complex)
1292 1331 # self.__pulseFound = True
1293 1332 # self.__startIndex = indexFound
1294 1333 #
1295 1334 # #If pulse was found ...
1296 1335 # for thisChannel in range(self.__nChannels):
1297 1336 # bufferByChannel = self.__bufferList[thisChannel]
1298 1337 # #print self.__startIndex
1299 1338 # x = numpy.array(bufferByChannel)
1300 1339 # self.__arrayBuffer[thisChannel] = x[self.__startIndex:self.__startIndex+self.__newNSamples]
1301 1340 #
1302 1341 # deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1303 1342 # dataOut.heightList = numpy.arange(self.__newNSamples)*deltaHeight
1304 1343 # # dataOut.ippSeconds = (self.__newNSamples / deltaHeight)/1e6
1305 1344 #
1306 1345 # dataOut.data = self.__arrayBuffer
1307 1346 #
1308 1347 # self.__startIndex += self.__newNSamples
1309 1348 #
1310 1349 # return
General Comments 0
You need to be logged in to leave comments. Login now