##// END OF EJS Templates
isr commit
rflores -
r1377:5453f456345b
parent child
Show More

The requested changes are too big and content was truncated. Show full diff

This diff has been collapsed as it changes many lines, (1156 lines changed) Show them Hide them
@@ -0,0 +1,1156
1
2 import os
3 import datetime
4 import numpy
5 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator #YONG
6
7 from .jroplot_spectra import RTIPlot, NoisePlot
8
9 from schainpy.utils import log
10 from .plotting_codes import *
11
12 from schainpy.model.graphics.jroplot_base import Plot, plt
13
14 import matplotlib.pyplot as plt
15 import matplotlib.colors as colors
16
17 import time
18 import math
19
20
21 from matplotlib.ticker import MultipleLocator
22
23
24
25 class RTIDPPlot(RTIPlot):
26
27 '''
28 Plot for RTI Double Pulse Experiment
29 '''
30
31 CODE = 'RTIDP'
32 colormap = 'jro'
33 plot_name = 'RTI'
34
35 #cb_label = 'Ne Electron Density (1/cm3)'
36
37 def setup(self):
38 self.xaxis = 'time'
39 self.ncols = 1
40 self.nrows = 3
41 self.nplots = self.nrows
42 #self.height=10
43 if self.showSNR:
44 self.nrows += 1
45 self.nplots += 1
46
47 self.ylabel = 'Height [km]'
48 self.xlabel = 'Time (LT)'
49
50 self.cb_label = 'Intensity (dB)'
51
52
53 #self.cb_label = cb_label
54
55 self.titles = ['{} Channel {}'.format(
56 self.plot_name.upper(), '0x1'),'{} Channel {}'.format(
57 self.plot_name.upper(), '0'),'{} Channel {}'.format(
58 self.plot_name.upper(), '1')]
59
60
61 def plot(self):
62
63 self.data.normalize_heights()
64 self.x = self.data.times
65 self.y = self.data.heights[0:self.data.NDP]
66
67 if self.showSNR:
68 self.z = numpy.concatenate(
69 (self.data[self.CODE], self.data['snr'])
70 )
71 else:
72
73 self.z = self.data[self.CODE]
74 #print(numpy.max(self.z[0,0:]))
75
76 self.z = numpy.ma.masked_invalid(self.z)
77
78 if self.decimation is None:
79 x, y, z = self.fill_gaps(self.x, self.y, self.z)
80 else:
81 x, y, z = self.fill_gaps(*self.decimate())
82
83 for n, ax in enumerate(self.axes):
84
85
86 self.zmax = self.zmax if self.zmax is not None else numpy.max(
87 self.z[1][0,12:40])
88 self.zmin = self.zmin if self.zmin is not None else numpy.min(
89 self.z[1][0,12:40])
90
91
92
93 if ax.firsttime:
94
95 if self.zlimits is not None:
96 self.zmin, self.zmax = self.zlimits[n]
97
98
99 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
100 vmin=self.zmin,
101 vmax=self.zmax,
102 cmap=self.cmaps[n]
103 )
104 #plt.tight_layout()
105 else:
106 if self.zlimits is not None:
107 self.zmin, self.zmax = self.zlimits[n]
108 ax.collections.remove(ax.collections[0])
109 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
110 vmin=self.zmin,
111 vmax=self.zmax,
112 cmap=self.cmaps[n]
113 )
114 #plt.tight_layout()
115
116
117 class RTILPPlot(RTIPlot):
118
119 '''
120 Plot for RTI Long Pulse
121 '''
122
123 CODE = 'RTILP'
124 colormap = 'jro'
125 plot_name = 'RTI LP'
126
127 #cb_label = 'Ne Electron Density (1/cm3)'
128
129 def setup(self):
130 self.xaxis = 'time'
131 self.ncols = 1
132 self.nrows = 4
133 self.nplots = self.nrows
134 if self.showSNR:
135 self.nrows += 1
136 self.nplots += 1
137
138 self.ylabel = 'Height [km]'
139 self.xlabel = 'Time (LT)'
140
141 self.cb_label = 'Intensity (dB)'
142
143
144
145 #self.cb_label = cb_label
146
147 self.titles = ['{} Channel {}'.format(
148 self.plot_name.upper(), '0'),'{} Channel {}'.format(
149 self.plot_name.upper(), '1'),'{} Channel {}'.format(
150 self.plot_name.upper(), '2'),'{} Channel {}'.format(
151 self.plot_name.upper(), '3')]
152
153
154 def plot(self):
155
156 self.data.normalize_heights()
157 self.x = self.data.times
158 self.y = self.data.heights[0:self.data.NRANGE]
159
160 if self.showSNR:
161 self.z = numpy.concatenate(
162 (self.data[self.CODE], self.data['snr'])
163 )
164 else:
165
166 self.z = self.data[self.CODE]
167 #print(numpy.max(self.z[0,0:]))
168
169 self.z = numpy.ma.masked_invalid(self.z)
170
171 if self.decimation is None:
172 x, y, z = self.fill_gaps(self.x, self.y, self.z)
173 else:
174 x, y, z = self.fill_gaps(*self.decimate())
175
176 for n, ax in enumerate(self.axes):
177
178
179 self.zmax = self.zmax if self.zmax is not None else numpy.max(
180 self.z[1][0,12:40])
181 self.zmin = self.zmin if self.zmin is not None else numpy.min(
182 self.z[1][0,12:40])
183
184 if ax.firsttime:
185
186 if self.zlimits is not None:
187 self.zmin, self.zmax = self.zlimits[n]
188
189
190 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
191 vmin=self.zmin,
192 vmax=self.zmax,
193 cmap=self.cmaps[n]
194 )
195 #plt.tight_layout()
196 else:
197 if self.zlimits is not None:
198 self.zmin, self.zmax = self.zlimits[n]
199 ax.collections.remove(ax.collections[0])
200 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
201 vmin=self.zmin,
202 vmax=self.zmax,
203 cmap=self.cmaps[n]
204 )
205 #plt.tight_layout()
206
207
208 class DenRTIPlot(RTIPlot):
209
210 '''
211 Plot for Den
212 '''
213
214 CODE = 'denrti'
215 colormap = 'jro'
216 plot_name = 'Electron Density'
217
218 #cb_label = 'Ne Electron Density (1/cm3)'
219
220 def setup(self):
221 self.xaxis = 'time'
222 self.ncols = 1
223 self.nrows = self.data.shape(self.CODE)[0]
224 self.nplots = self.nrows
225 if self.showSNR:
226 self.nrows += 1
227 self.nplots += 1
228
229 self.ylabel = 'Height [km]'
230 self.xlabel = 'Time (LT)'
231
232 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
233
234 if self.CODE == 'denrti' or self.CODE=='denrtiLP':
235 self.cb_label = r'$\mathrm{N_e}$ Electron Density ($\mathrm{1/cm^3}$)'
236
237 #self.cb_label = cb_label
238 if not self.titles:
239 self.titles = self.data.parameters \
240 if self.data.parameters else ['{}'.format(self.plot_name)]
241 if self.showSNR:
242 self.titles.append('SNR')
243
244 def plot(self):
245
246 self.data.normalize_heights()
247 self.x = self.data.times
248 self.y = self.data.heights
249
250
251
252 if self.showSNR:
253 self.z = numpy.concatenate(
254 (self.data[self.CODE], self.data['snr'])
255 )
256 else:
257 self.z = self.data[self.CODE]
258
259 self.z = numpy.ma.masked_invalid(self.z)
260
261 if self.decimation is None:
262 x, y, z = self.fill_gaps(self.x, self.y, self.z)
263 else:
264 x, y, z = self.fill_gaps(*self.decimate())
265
266 for n, ax in enumerate(self.axes):
267
268 self.zmax = self.zmax if self.zmax is not None else numpy.max(
269 self.z[n])
270 self.zmin = self.zmin if self.zmin is not None else numpy.min(
271 self.z[n])
272
273 if ax.firsttime:
274
275 if self.zlimits is not None:
276 self.zmin, self.zmax = self.zlimits[n]
277 if numpy.log10(self.zmin)<0:
278 self.zmin=1
279 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
280 vmin=self.zmin,
281 vmax=self.zmax,
282 cmap=self.cmaps[n],
283 norm=colors.LogNorm()
284 )
285 #plt.tight_layout()
286
287 else:
288 if self.zlimits is not None:
289 self.zmin, self.zmax = self.zlimits[n]
290 ax.collections.remove(ax.collections[0])
291 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
292 vmin=self.zmin,
293 vmax=self.zmax,
294 cmap=self.cmaps[n],
295 norm=colors.LogNorm()
296 )
297 #plt.tight_layout()
298
299
300
301 class DenRTILPPlot(DenRTIPlot):
302
303 '''
304 Plot for Electron Temperature
305 '''
306
307 CODE = 'denrtiLP'
308 colormap = 'jro'
309 plot_name = 'Electron Density'
310
311
312 class ETempRTIPlot(RTIPlot):
313
314 '''
315 Plot for Electron Temperature
316 '''
317
318 CODE = 'ETemp'
319 colormap = 'jet'
320 plot_name = 'Electron Temperature'
321
322 #cb_label = 'Ne Electron Density (1/cm3)'
323
324 def setup(self):
325 self.xaxis = 'time'
326 self.ncols = 1
327 self.nrows = self.data.shape(self.CODE)[0]
328 self.nplots = self.nrows
329 if self.showSNR:
330 self.nrows += 1
331 self.nplots += 1
332
333 self.ylabel = 'Height [km]'
334 self.xlabel = 'Time (LT)'
335 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
336 if self.CODE == 'ETemp' or self.CODE == 'ETempLP':
337 self.cb_label = 'Electron Temperature (K)'
338 if self.CODE == 'ITemp' or self.CODE == 'ITempLP':
339 self.cb_label = 'Ion Temperature (K)'
340
341
342 if not self.titles:
343 self.titles = self.data.parameters \
344 if self.data.parameters else ['{}'.format(self.plot_name)]
345 if self.showSNR:
346 self.titles.append('SNR')
347
348 def plot(self):
349
350 self.data.normalize_heights()
351 self.x = self.data.times
352 self.y = self.data.heights
353
354 if self.showSNR:
355 self.z = numpy.concatenate(
356 (self.data[self.CODE], self.data['snr'])
357 )
358 else:
359 self.z = self.data[self.CODE]
360
361 self.z = numpy.ma.masked_invalid(self.z)
362
363 if self.decimation is None:
364 x, y, z = self.fill_gaps(self.x, self.y, self.z)
365 else:
366 x, y, z = self.fill_gaps(*self.decimate())
367
368 for n, ax in enumerate(self.axes):
369
370 self.zmax = self.zmax if self.zmax is not None else numpy.max(
371 self.z[n])
372 self.zmin = self.zmin if self.zmin is not None else numpy.min(
373 self.z[n])
374
375 if ax.firsttime:
376
377 if self.zlimits is not None:
378 self.zmin, self.zmax = self.zlimits[n]
379
380 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
381 vmin=self.zmin,
382 vmax=self.zmax,
383 cmap=self.cmaps[n]
384 )
385 #plt.tight_layout()
386
387 else:
388 if self.zlimits is not None:
389 self.zmin, self.zmax = self.zlimits[n]
390 ax.collections.remove(ax.collections[0])
391 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
392 vmin=self.zmin,
393 vmax=self.zmax,
394 cmap=self.cmaps[n]
395 )
396 #plt.tight_layout()
397
398
399
400 class ITempRTIPlot(ETempRTIPlot):
401
402 '''
403 Plot for Ion Temperature
404 '''
405
406 CODE = 'ITemp'
407 colormap = 'jet'
408 plot_name = 'Ion Temperature'
409
410
411 class ElectronTempLPPlot(ETempRTIPlot):
412
413 '''
414 Plot for Electron Temperature LP
415 '''
416
417 CODE = 'ETempLP'
418 colormap = 'jet'
419 plot_name = 'Electron Temperature'
420
421
422 class IonTempLPPlot(ETempRTIPlot):
423
424 '''
425 Plot for Ion Temperature LP
426 '''
427
428 CODE = 'ITempLP'
429 colormap = 'jet'
430 plot_name = 'Ion Temperature'
431
432
433 class HFracRTIPlot(ETempRTIPlot):
434
435 '''
436 Plot for H+ LP
437 '''
438
439 CODE = 'HFracLP'
440 colormap = 'jet'
441 plot_name = 'H+ Frac'
442
443
444 class HeFracRTIPlot(ETempRTIPlot):
445
446 '''
447 Plot for He+ LP
448 '''
449
450 CODE = 'HeFracLP'
451 colormap = 'jet'
452 plot_name = 'He+ Frac'
453
454
455 class TempsDPPlot(Plot):
456 '''
457 Plot for Electron - Ion Temperatures
458 '''
459
460 CODE = 'tempsDP'
461 plot_name = 'Temperatures'
462 plot_type = 'scatterbuffer'
463
464
465 def setup(self):
466
467 self.ncols = 1
468 self.nrows = 1
469 self.nplots = 1
470 self.ylabel = 'Range [km]'
471 self.xlabel = 'Temperature (K)'
472 self.width = 3.5
473 self.height = 5.5
474 self.colorbar = False
475 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
476 if not self.titles:
477 self.titles = self.data.parameters \
478 if self.data.parameters else ['{}'.format(self.CODE.upper())]
479
480 def plot(self):
481
482 self.x = self.data['tempsDP'][:,-1]
483 self.y = self.data.heights[0:self.data.NSHTS]
484
485 self.xmin = -100
486 self.xmax = 5000
487 ax = self.axes[0]
488
489 if ax.firsttime:
490
491 ax.errorbar(self.x, self.y, xerr=self.data.ete2, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
492 ax.errorbar(self.data.ti2, self.y, fmt='k^', xerr=self.data.eti2,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
493 plt.legend(loc='lower right')
494 self.ystep_given = 50
495 ax.yaxis.set_minor_locator(MultipleLocator(15))
496 ax.grid(which='minor')
497 #plt.tight_layout()
498
499
500 else:
501 self.clear_figures()
502 ax.errorbar(self.x, self.y, xerr=self.data.ete2, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
503 ax.errorbar(self.data.ti2, self.y, fmt='k^', xerr=self.data.eti2,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
504 plt.legend(loc='lower right')
505 ax.yaxis.set_minor_locator(MultipleLocator(15))
506 #plt.tight_layout()
507
508
509 class TempsHPPlot(Plot):
510 '''
511 Plot for Temperatures Hybrid Experiment
512 '''
513
514 CODE = 'temps_LP'
515 plot_name = 'Temperatures'
516 plot_type = 'scatterbuffer'
517
518
519 def setup(self):
520
521 self.ncols = 1
522 self.nrows = 1
523 self.nplots = 1
524 self.ylabel = 'Range [km]'
525 self.xlabel = 'Temperature (K)'
526 self.width = 3.5
527 self.height = 6.5
528 self.colorbar = False
529 if not self.titles:
530 self.titles = self.data.parameters \
531 if self.data.parameters else ['{}'.format(self.CODE.upper())]
532
533 def plot(self):
534
535 self.x = self.data['temps_LP'][:,-1]
536 self.y = self.data.heights[0:self.data.NACF]
537 self.xmin = -100
538 self.xmax = 4500
539 ax = self.axes[0]
540
541 if ax.firsttime:
542
543 ax.errorbar(self.x, self.y, xerr=self.data.ete, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
544 ax.errorbar(self.data.ti, self.y, fmt='k^', xerr=self.data.eti,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
545 plt.legend(loc='lower right')
546 self.ystep_given = 200
547 ax.yaxis.set_minor_locator(MultipleLocator(15))
548 ax.grid(which='minor')
549 #plt.tight_layout()
550
551
552 else:
553 self.clear_figures()
554 ax.errorbar(self.x, self.y, xerr=self.data.ete, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
555 ax.errorbar(self.data.ti, self.y, fmt='k^', xerr=self.data.eti,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
556 plt.legend(loc='lower right')
557 ax.yaxis.set_minor_locator(MultipleLocator(15))
558 #plt.tight_layout()
559
560
561 class FracsHPPlot(Plot):
562 '''
563 Plot for Composition LP
564 '''
565
566 CODE = 'fracs_LP'
567 plot_name = 'Composition'
568 plot_type = 'scatterbuffer'
569
570
571 def setup(self):
572
573 self.ncols = 1
574 self.nrows = 1
575 self.nplots = 1
576 self.ylabel = 'Range [km]'
577 self.xlabel = 'Frac'
578 self.width = 3.5
579 self.height = 6.5
580 self.colorbar = False
581 if not self.titles:
582 self.titles = self.data.parameters \
583 if self.data.parameters else ['{}'.format(self.CODE.upper())]
584
585 def plot(self):
586
587 self.x = self.data['fracs_LP'][:,-1]
588 self.y = self.data.heights[0:self.data.NACF]
589
590 self.xmin = 0
591 self.xmax = 1
592 ax = self.axes[0]
593
594 if ax.firsttime:
595
596 ax.errorbar(self.x, self.y[self.data.cut:], xerr=self.data.eph, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='H+')
597 ax.errorbar(self.data.phe, self.y[self.data.cut:], fmt='k^', xerr=self.data.ephe,elinewidth=1.0,color='b',linewidth=2.0, label='He+')
598 plt.legend(loc='lower right')
599 self.xstep_given = 0.2
600 self.ystep_given = 200
601 ax.yaxis.set_minor_locator(MultipleLocator(15))
602 ax.grid(which='minor')
603 #plt.tight_layout()
604
605
606 else:
607 self.clear_figures()
608 ax.errorbar(self.x, self.y[self.data.cut:], xerr=self.data.eph, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='H+')
609 ax.errorbar(self.data.phe, self.y[self.data.cut:], fmt='k^', xerr=self.data.ephe,elinewidth=1.0,color='b',linewidth=2.0, label='He+')
610 plt.legend(loc='lower right')
611 ax.yaxis.set_minor_locator(MultipleLocator(15))
612 #plt.tight_layout()
613
614
615
616 class EDensityPlot(Plot):
617 '''
618 Plot for electron density
619 '''
620
621 CODE = 'den'
622 plot_name = 'Electron Density'
623 plot_type = 'scatterbuffer'
624
625
626 def setup(self):
627
628 self.ncols = 1
629 self.nrows = 1
630 self.nplots = 1
631 self.ylabel = 'Range [km]'
632 self.xlabel = r'$\mathrm{N_e}$ Electron Density ($\mathrm{1/cm^3}$)'
633 self.width = 4
634 self.height = 6.5
635 self.colorbar = False
636 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
637 if not self.titles:
638 self.titles = self.data.parameters \
639 if self.data.parameters else ['{}'.format(self.CODE.upper())]
640
641 def plot(self):
642
643
644 self.x = self.data[self.CODE]
645 self.y = self.data.heights
646 self.xmin = 1000
647 self.xmax = 10000000
648 ax = self.axes[0]
649
650 if ax.firsttime:
651 self.autoxticks=False
652 #if self.CODE=='den':
653 ax.errorbar(self.data.dphi, self.y[:self.data.NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
654 #ax.errorbar(self.data.dphi, self.y[:self.data.NSHTS], xerr=self.data.sdn1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
655
656 ax.errorbar(self.x[:,-1], self.y[:self.data.NSHTS], fmt='k^-', xerr=self.data.sdp2,elinewidth=1.0,color='b',linewidth=1.0, label='Power Profile',markersize=2)
657 #else:
658 #ax.errorbar(self.data.dphi[:self.data.cut], self.y[:self.data.cut], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
659 #ax.errorbar(self.x[:self.data.cut,-1], self.y[:self.data.cut], fmt='k^-', xerr=self.data.sdp2[:self.data.cut],elinewidth=1.0,color='b',linewidth=1.0, label='Power Profile',markersize=2)
660
661 if self.CODE=='denLP':
662 ax.errorbar(self.data.ne[self.data.cut:], self.y[self.data.cut:], xerr=self.data.ene[self.data.cut:], fmt='r^-',elinewidth=1.0,color='r',linewidth=1.0, label='LP Profile',markersize=2)
663
664 plt.legend(loc='upper right')
665 ax.set_xscale("log", nonposx='clip')
666 grid_y_ticks=numpy.arange(numpy.nanmin(self.y),numpy.nanmax(self.y),50)
667 self.ystep_given=100
668 if self.CODE=='denLP':
669 self.ystep_given=200
670 ax.set_yticks(grid_y_ticks,minor=True)
671 ax.grid(which='minor')
672 #plt.tight_layout()
673
674
675
676 else:
677
678 self.clear_figures()
679 #if self.CODE=='den':
680 ax.errorbar(self.data.dphi, self.y[:self.data.NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
681 #ax.errorbar(self.data.dphi, self.y[:self.data.NSHTS], xerr=self.data.sdn1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
682
683 ax.errorbar(self.x[:,-1], self.y[:self.data.NSHTS], fmt='k^-', xerr=self.data.sdp2,elinewidth=1.0,color='b',linewidth=1.0, label='Power Profile',markersize=2)
684 ax.errorbar(self.x[:,-2], self.y[:self.data.NSHTS], elinewidth=1.0,color='r',linewidth=0.5,linestyle="dashed")
685 #else:
686 #ax.errorbar(self.data.dphi[:self.data.cut], self.y[:self.data.cut], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
687 #ax.errorbar(self.x[:self.data.cut,-1], self.y[:self.data.cut], fmt='k^-', xerr=self.data.sdp2[:self.data.cut],elinewidth=1.0,color='b',linewidth=1.0, label='Power Profile',markersize=2)
688 #ax.errorbar(self.x[:self.data.cut,-2], self.y[:self.data.cut], elinewidth=1.0,color='r',linewidth=0.5,linestyle="dashed")
689
690 if self.CODE=='denLP':
691 ax.errorbar(self.data.ne[self.data.cut:], self.y[self.data.cut:], fmt='r^-', xerr=self.data.ene[self.data.cut:],elinewidth=1.0,color='r',linewidth=1.0, label='LP Profile',markersize=2)
692
693 ax.set_xscale("log", nonposx='clip')
694 grid_y_ticks=numpy.arange(numpy.nanmin(self.y),numpy.nanmax(self.y),50)
695 ax.set_yticks(grid_y_ticks,minor=True)
696 ax.grid(which='minor')
697 plt.legend(loc='upper right')
698 #plt.tight_layout()
699
700 class FaradayAnglePlot(Plot):
701 '''
702 Plot for electron density
703 '''
704
705 CODE = 'FaradayAngle'
706 plot_name = 'Faraday Angle'
707 plot_type = 'scatterbuffer'
708
709
710 def setup(self):
711
712 self.ncols = 1
713 self.nrows = 1
714 self.nplots = 1
715 self.ylabel = 'Range [km]'
716 self.xlabel = 'Faraday Angle (º)'
717 self.width = 4
718 self.height = 6.5
719 self.colorbar = False
720 if not self.titles:
721 self.titles = self.data.parameters \
722 if self.data.parameters else ['{}'.format(self.CODE.upper())]
723
724 def plot(self):
725
726
727 self.x = self.data[self.CODE]
728 self.y = self.data.heights
729 self.xmin = -180
730 self.xmax = 180
731 ax = self.axes[0]
732
733 if ax.firsttime:
734 self.autoxticks=False
735 #if self.CODE=='den':
736 ax.plot(self.x, self.y,marker='o',color='g',linewidth=1.0,markersize=2)
737
738 grid_y_ticks=numpy.arange(numpy.nanmin(self.y),numpy.nanmax(self.y),50)
739 self.ystep_given=100
740 if self.CODE=='denLP':
741 self.ystep_given=200
742 ax.set_yticks(grid_y_ticks,minor=True)
743 ax.grid(which='minor')
744 #plt.tight_layout()
745 else:
746
747 self.clear_figures()
748 #if self.CODE=='den':
749 #print(numpy.shape(self.x))
750 ax.plot(self.x[:,-1], self.y, marker='o',color='g',linewidth=1.0, markersize=2)
751
752 grid_y_ticks=numpy.arange(numpy.nanmin(self.y),numpy.nanmax(self.y),50)
753 ax.set_yticks(grid_y_ticks,minor=True)
754 ax.grid(which='minor')
755
756 class EDensityHPPlot(EDensityPlot):
757
758 '''
759 Plot for Electron Density Hybrid Experiment
760 '''
761
762 CODE = 'denLP'
763 plot_name = 'Electron Density'
764 plot_type = 'scatterbuffer'
765
766
767 class ACFsPlot(Plot):
768 '''
769 Plot for ACFs Double Pulse Experiment
770 '''
771
772 CODE = 'acfs'
773 plot_name = 'ACF'
774 plot_type = 'scatterbuffer'
775
776
777 def setup(self):
778 #self.xaxis = 'time'
779 self.ncols = 1
780 self.nrows = 1
781 self.nplots = 1
782 self.ylabel = 'Range [km]'
783 self.xlabel = 'lags (ms)'
784 self.width = 3.5
785 self.height = 6
786 self.colorbar = False
787 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
788 if not self.titles:
789 self.titles = self.data.parameters \
790 if self.data.parameters else ['{}'.format(self.CODE.upper())]
791
792 def plot(self):
793
794 self.x = self.data.lags_to_plot
795 self.y = self.data['acfs'][:,-1]
796
797
798 self.xmin = 0.0
799 self.xmax = 2.0
800
801 ax = self.axes[0]
802
803 if ax.firsttime:
804
805 for i in range(self.data.NSHTS):
806 x_aux = numpy.isfinite(self.x[i,:])
807 y_aux = numpy.isfinite(self.y[i,:])
808 yerr_aux = numpy.isfinite(self.data.acfs_error_to_plot[i,:])
809 x_igcej_aux = numpy.isfinite(self.data.x_igcej_to_plot[i,:])
810 y_igcej_aux = numpy.isfinite(self.data.y_igcej_to_plot[i,:])
811 x_ibad_aux = numpy.isfinite(self.data.x_ibad_to_plot[i,:])
812 y_ibad_aux = numpy.isfinite(self.data.y_ibad_to_plot[i,:])
813 if self.x[i,:][~numpy.isnan(self.x[i,:])].shape[0]>2:
814 ax.errorbar(self.x[i,x_aux], self.y[i,y_aux], yerr=self.data.acfs_error_to_plot[i,x_aux],color='b',marker='o',linewidth=1.0,markersize=2)
815 ax.plot(self.data.x_igcej_to_plot[i,x_igcej_aux],self.data.y_igcej_to_plot[i,y_igcej_aux],'x',color='red',markersize=2)
816 ax.plot(self.data.x_ibad_to_plot[i,x_ibad_aux],self.data.y_ibad_to_plot[i,y_ibad_aux],'X',color='red',markersize=2)
817
818 self.xstep_given = (self.xmax-self.xmin)/(self.data.DPL-1)
819 self.ystep_given = 50
820 ax.yaxis.set_minor_locator(MultipleLocator(15))
821 ax.grid(which='minor')
822
823
824
825 else:
826 self.clear_figures()
827
828 for i in range(self.data.NSHTS):
829 x_aux = numpy.isfinite(self.x[i,:])
830 y_aux = numpy.isfinite(self.y[i,:])
831 yerr_aux = numpy.isfinite(self.data.acfs_error_to_plot[i,:])
832 x_igcej_aux = numpy.isfinite(self.data.x_igcej_to_plot[i,:])
833 y_igcej_aux = numpy.isfinite(self.data.y_igcej_to_plot[i,:])
834 x_ibad_aux = numpy.isfinite(self.data.x_ibad_to_plot[i,:])
835 y_ibad_aux = numpy.isfinite(self.data.y_ibad_to_plot[i,:])
836 if self.x[i,:][~numpy.isnan(self.x[i,:])].shape[0]>2:
837 ax.errorbar(self.x[i,x_aux], self.y[i,y_aux], yerr=self.data.acfs_error_to_plot[i,x_aux],linewidth=1.0,markersize=2,color='b',marker='o')
838 ax.plot(self.data.x_igcej_to_plot[i,x_igcej_aux],self.data.y_igcej_to_plot[i,y_igcej_aux],'x',color='red',markersize=2)
839 ax.plot(self.data.x_ibad_to_plot[i,x_ibad_aux],self.data.y_ibad_to_plot[i,y_ibad_aux],'X',color='red',markersize=2)
840 ax.yaxis.set_minor_locator(MultipleLocator(15))
841
842
843
844
845 class ACFsLPPlot(Plot):
846 '''
847 Plot for ACFs Double Pulse Experiment
848 '''
849
850 CODE = 'acfs_LP'
851 plot_name = 'ACF'
852 plot_type = 'scatterbuffer'
853
854
855 def setup(self):
856 #self.xaxis = 'time'
857 self.ncols = 1
858 self.nrows = 1
859 self.nplots = 1
860 self.ylabel = 'Range [km]'
861 self.xlabel = 'lags (ms)'
862 self.width = 3.5
863 self.height = 7
864 self.colorbar = False
865 if not self.titles:
866 self.titles = self.data.parameters \
867 if self.data.parameters else ['{}'.format(self.CODE.upper())]
868
869
870
871 def plot(self):
872
873 self.x = self.data.lags_LP_to_plot
874 self.y = self.data['acfs_LP'][:,-1]
875
876 self.xmin = 0.0
877 self.xmax = 1.5
878
879 ax = self.axes[0]
880
881 if ax.firsttime:
882
883 for i in range(self.data.NACF):
884 x_aux = numpy.isfinite(self.x[i,:])
885 y_aux = numpy.isfinite(self.y[i,:])
886 yerr_aux = numpy.isfinite(self.data.errors[i,:])
887
888 if self.x[i,:][~numpy.isnan(self.x[i,:])].shape[0]>2:
889 ax.errorbar(self.x[i,x_aux], self.y[i,y_aux], yerr=self.data.errors[i,x_aux],color='b',linewidth=1.0,markersize=2,ecolor='r')
890
891 #self.xstep_given = (self.xmax-self.xmin)/(self.data.NLAG-1)
892 self.xstep_given=0.3
893 self.ystep_given = 200
894 ax.yaxis.set_minor_locator(MultipleLocator(15))
895 ax.grid(which='minor')
896
897 else:
898 self.clear_figures()
899
900 for i in range(self.data.NACF):
901 x_aux = numpy.isfinite(self.x[i,:])
902 y_aux = numpy.isfinite(self.y[i,:])
903 yerr_aux = numpy.isfinite(self.data.errors[i,:])
904
905 if self.x[i,:][~numpy.isnan(self.x[i,:])].shape[0]>2:
906 ax.errorbar(self.x[i,x_aux], self.y[i,y_aux], yerr=self.data.errors[i,x_aux],color='b',linewidth=1.0,markersize=2,ecolor='r')
907
908 ax.yaxis.set_minor_locator(MultipleLocator(15))
909
910
911 class CrossProductsPlot(Plot):
912 '''
913 Plot for cross products
914 '''
915
916 CODE = 'crossprod'
917 plot_name = 'Cross Products'
918 plot_type = 'scatterbuffer'
919
920
921 def setup(self):
922
923 self.ncols = 3
924 self.nrows = 1
925 self.nplots = 3
926 self.ylabel = 'Range [km]'
927
928 self.width = 3.5*self.nplots
929 self.height = 5.5
930 self.colorbar = False
931 self.titles = []
932
933 def plot(self):
934
935 self.x = self.data['crossprod'][:,-1,:,:,:,:]
936
937
938
939
940 self.y = self.data.heights[0:self.data.NDP]
941
942
943
944 for n, ax in enumerate(self.axes):
945
946 self.xmin=numpy.min(numpy.concatenate((self.x[n][0,20:30,0,0],self.x[n][1,20:30,0,0],self.x[n][2,20:30,0,0],self.x[n][3,20:30,0,0])))
947 self.xmax=numpy.max(numpy.concatenate((self.x[n][0,20:30,0,0],self.x[n][1,20:30,0,0],self.x[n][2,20:30,0,0],self.x[n][3,20:30,0,0])))
948
949
950 if ax.firsttime:
951
952 self.autoxticks=False
953 if n==0:
954 label1='kax'
955 label2='kay'
956 label3='kbx'
957 label4='kby'
958 self.xlimits=[(self.xmin,self.xmax)]
959 elif n==1:
960 label1='kax2'
961 label2='kay2'
962 label3='kbx2'
963 label4='kby2'
964 self.xlimits.append((self.xmin,self.xmax))
965 elif n==2:
966 label1='kaxay'
967 label2='kbxby'
968 label3='kaxbx'
969 label4='kaxby'
970 self.xlimits.append((self.xmin,self.xmax))
971
972
973 ax.plotline1 = ax.plot(self.x[n][0,:,0,0], self.y, color='r',linewidth=2.0, label=label1)
974 ax.plotline2 = ax.plot(self.x[n][1,:,0,0], self.y, color='k',linewidth=2.0, label=label2)
975 ax.plotline3 = ax.plot(self.x[n][2,:,0,0], self.y, color='b',linewidth=2.0, label=label3)
976 ax.plotline4 = ax.plot(self.x[n][3,:,0,0], self.y, color='m',linewidth=2.0, label=label4)
977 ax.legend(loc='upper right')
978 ax.set_xlim(self.xmin, self.xmax)
979 self.titles.append('{}'.format(self.plot_name.upper()))
980 #plt.tight_layout()
981
982
983 else:
984
985 if n==0:
986 self.xlimits=[(self.xmin,self.xmax)]
987 else:
988 self.xlimits.append((self.xmin,self.xmax))
989
990 ax.set_xlim(self.xmin, self.xmax)
991
992
993 ax.plotline1[0].set_data(self.x[n][0,:,0,0],self.y)
994 ax.plotline2[0].set_data(self.x[n][1,:,0,0],self.y)
995 ax.plotline3[0].set_data(self.x[n][2,:,0,0],self.y)
996 ax.plotline4[0].set_data(self.x[n][3,:,0,0],self.y)
997 self.titles.append('{}'.format(self.plot_name.upper()))
998 #plt.tight_layout()
999
1000
1001
1002 class CrossProductsLPPlot(Plot):
1003 '''
1004 Plot for cross products LP
1005 '''
1006
1007 CODE = 'crossprodlp'
1008 plot_name = 'Cross Products LP'
1009 plot_type = 'scatterbuffer'
1010
1011
1012 def setup(self):
1013
1014 self.ncols = 2
1015 self.nrows = 1
1016 self.nplots = 2
1017 self.ylabel = 'Range [km]'
1018 self.xlabel = 'dB'
1019 self.width = 3.5*self.nplots
1020 self.height = 5.5
1021 self.colorbar = False
1022 self.titles = []
1023 self.plotline_array=numpy.zeros((2,self.data.NLAG),dtype=object)
1024 def plot(self):
1025
1026
1027 self.x = self.data[self.CODE][:,-1,:,:]
1028
1029
1030 self.y = self.data.heights[0:self.data.NRANGE]
1031
1032
1033 label_array=numpy.array(['lag '+ str(x) for x in range(self.data.NLAG)])
1034 color_array=['r','k','g','b','c','m','y','orange','steelblue','purple','peru','darksalmon','grey','limegreen','olive','midnightblue']
1035
1036
1037 for n, ax in enumerate(self.axes):
1038
1039 self.xmin=30
1040 self.xmax=70
1041 #print(self.x[0,12:15,n])
1042 #input()
1043 #self.xmin=numpy.min(numpy.concatenate((self.x[0,:,n],self.x[1,:,n])))
1044 #self.xmax=numpy.max(numpy.concatenate((self.x[0,:,n],self.x[1,:,n])))
1045
1046 #print("before",self.plotline_array)
1047
1048 if ax.firsttime:
1049
1050 self.autoxticks=False
1051
1052
1053 for i in range(self.data.NLAG):
1054 #print(i)
1055 #print(numpy.shape(self.x))
1056 self.plotline_array[n,i], = ax.plot(self.x[i,:,n], self.y, color=color_array[i],linewidth=1.0, label=label_array[i])
1057 #ax.plotline1 = ax.plot(self.x[0,:,n], self.y, color='r',linewidth=2.0, label=label_array[0])
1058 #ax.plotline2 = ax.plot(self.x[n][1,:,0,0], self.y, color='k',linewidth=2.0, label=label2)
1059 #ax.plotline3 = ax.plot(self.x[n][2,:,0,0], self.y, color='b',linewidth=2.0, label=label3)
1060 #ax.plotline4 = ax.plot(self.x[n][3,:,0,0], self.y, color='m',linewidth=2.0, label=label4)
1061
1062
1063 #print(self.plotline_array)
1064
1065
1066
1067 ax.legend(loc='upper right')
1068 ax.set_xlim(self.xmin, self.xmax)
1069 if n==0:
1070 self.titles.append('{} CH0'.format(self.plot_name.upper()))
1071 if n==1:
1072 self.titles.append('{} CH1'.format(self.plot_name.upper()))
1073
1074 #plt.tight_layout()
1075
1076 else:
1077 #print(self.plotline_array)
1078 for i in range(self.data.NLAG):
1079
1080 self.plotline_array[n,i].set_data(self.x[i,:,n],self.y)
1081
1082
1083
1084 #ax.plotline1[0].set_data(self.x[n][0,:,0,0],self.y)
1085 #ax.plotline2[0].set_data(self.x[n][1,:,0,0],self.y)
1086 #ax.plotline3[0].set_data(self.x[n][2,:,0,0],self.y)
1087 #ax.plotline4[0].set_data(self.x[n][3,:,0,0],self.y)
1088
1089 if n==0:
1090 self.titles.append('{} CH0'.format(self.plot_name.upper()))
1091 if n==1:
1092 self.titles.append('{} CH1'.format(self.plot_name.upper()))
1093
1094 #plt.tight_layout()
1095
1096
1097 class NoiseDPPlot(NoisePlot):
1098 '''
1099 Plot for noise Double Pulse
1100 '''
1101
1102 CODE = 'noisedp'
1103 plot_name = 'Noise'
1104 plot_type = 'scatterbuffer'
1105
1106
1107 class XmitWaveformPlot(Plot):
1108 '''
1109 Plot for xmit waveform
1110 '''
1111
1112 CODE = 'xmit'
1113 plot_name = 'Xmit Waveform'
1114 plot_type = 'scatterbuffer'
1115
1116
1117 def setup(self):
1118
1119 self.ncols = 1
1120 self.nrows = 1
1121 self.nplots = 1
1122 self.ylabel = ''
1123 self.xlabel = 'Number of Lag'
1124 self.width = 5.5
1125 self.height = 3.5
1126 self.colorbar = False
1127 if not self.titles:
1128 self.titles = self.data.parameters \
1129 if self.data.parameters else ['{}'.format(self.plot_name.upper())]
1130
1131 def plot(self):
1132
1133 self.x = numpy.arange(0,self.data.NLAG,1,'float32')
1134 self.y = self.data['xmit'][:,-1,:]
1135
1136 self.xmin = 0
1137 self.xmax = self.data.NLAG-1
1138 self.ymin = -1.0
1139 self.ymax = 1.0
1140 ax = self.axes[0]
1141
1142 if ax.firsttime:
1143 ax.plotline0=ax.plot(self.x,self.y[0,:],color='blue')
1144 ax.plotline1=ax.plot(self.x,self.y[1,:],color='red')
1145 secax=ax.secondary_xaxis(location=0.5)
1146 secax.xaxis.tick_bottom()
1147 secax.tick_params( labelleft=False, labeltop=False,
1148 labelright=False, labelbottom=False)
1149
1150 self.xstep_given = 3
1151 self.ystep_given = .25
1152 secax.set_xticks(numpy.linspace(self.xmin, self.xmax, 6)) #only works on matplotlib.version>3.2
1153
1154 else:
1155 ax.plotline0[0].set_data(self.x,self.y[0,:])
1156 ax.plotline1[0].set_data(self.x,self.y[1,:])
This diff has been collapsed as it changes many lines, (683 lines changed) Show them Hide them
@@ -0,0 +1,683
1 '''
2 Created on Jun 9, 2020
3
4 @author: Roberto Flores
5 '''
6
7 import os
8 import sys
9 import time
10
11 import struct
12
13
14 import datetime
15
16 import numpy
17
18
19 import schainpy.admin
20 from schainpy.model.io.jroIO_base import LOCALTIME, Reader
21 from schainpy.model.data.jroheaderIO import BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader
22 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
23 from schainpy.model.data.jrodata import Voltage, Parameters
24 from schainpy.utils import log
25
26
27 class DatReader(Reader, ProcessingUnit):
28
29 def __init__(self):
30
31 ProcessingUnit.__init__(self)
32 self.basicHeaderObj = BasicHeader(LOCALTIME)
33 self.systemHeaderObj = SystemHeader()
34 self.radarControllerHeaderObj = RadarControllerHeader()
35 self.processingHeaderObj = ProcessingHeader()
36 self.dataOut = Parameters()
37 #print(self.basicHeaderObj.timezone)
38 #self.counter_block=0
39 self.format='dat'
40 self.flagNoMoreFiles = 0
41 self.filename = None
42 self.intervals = set()
43 #self.datatime = datetime.datetime(1900,1,1)
44
45 self.filefmt = "***%Y%m%d*******"
46
47 self.padding=numpy.zeros(1,'int32')
48 self.hsize=numpy.zeros(1,'int32')
49 self.bufsize=numpy.zeros(1,'int32')
50 self.nr=numpy.zeros(1,'int32')
51 self.ngates=numpy.zeros(1,'int32') ### ### ### 2
52 self.time1=numpy.zeros(1,'uint64') # pos 3
53 self.time2=numpy.zeros(1,'uint64') # pos 4
54 self.lcounter=numpy.zeros(1,'int32')
55 self.groups=numpy.zeros(1,'int32')
56 self.system=numpy.zeros(4,'int8') # pos 7
57 self.h0=numpy.zeros(1,'float32')
58 self.dh=numpy.zeros(1,'float32')
59 self.ipp=numpy.zeros(1,'float32')
60 self.process=numpy.zeros(1,'int32')
61 self.tx=numpy.zeros(1,'int32')
62
63 self.ngates1=numpy.zeros(1,'int32') ### ### ### 13
64 self.time0=numpy.zeros(1,'uint64') # pos 14
65 self.nlags=numpy.zeros(1,'int32')
66 self.nlags1=numpy.zeros(1,'int32')
67 self.txb=numpy.zeros(1,'float32') ### ### ### 17
68 self.time3=numpy.zeros(1,'uint64') # pos 18
69 self.time4=numpy.zeros(1,'uint64') # pos 19
70 self.h0_=numpy.zeros(1,'float32')
71 self.dh_=numpy.zeros(1,'float32')
72 self.ipp_=numpy.zeros(1,'float32')
73 self.txa_=numpy.zeros(1,'float32')
74
75 self.pad=numpy.zeros(100,'int32')
76
77 self.nbytes=numpy.zeros(1,'int32')
78 self.limits=numpy.zeros(1,'int32')
79 self.ngroups=numpy.zeros(1,'int32') ### ### ### 27
80 #Make the header list
81 #header=[hsize,bufsize,nr,ngates,time1,time2,lcounter,groups,system,h0,dh,ipp,process,tx,padding,ngates1,time0,nlags,nlags1,padding,txb,time3,time4,h0_,dh_,ipp_,txa_,pad,nbytes,limits,padding,ngroups]
82 self.header=[self.hsize,self.bufsize,self.nr,self.ngates,self.time1,self.time2,self.lcounter,self.groups,self.system,self.h0,self.dh,self.ipp,self.process,self.tx,self.ngates1,self.padding,self.time0,self.nlags,self.nlags1,self.padding,self.txb,self.time3,self.time4,self.h0_,self.dh_,self.ipp_,self.txa_,self.pad,self.nbytes,self.limits,self.padding,self.ngroups]
83
84
85
86 def setup(self, **kwargs):
87
88 self.set_kwargs(**kwargs)
89
90
91 if self.path is None:
92 raise ValueError('The path is not valid')
93
94 self.open_file = open
95 self.open_mode = 'rb'
96
97
98
99 if self.format is None:
100 raise ValueError('The format is not valid')
101 elif self.format.lower() in ('dat'):
102 self.ext = '.dat'
103 elif self.format.lower() in ('out'):
104 self.ext = '.out'
105
106
107 log.log("Searching files in {}".format(self.path), self.name)
108 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
109 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
110 #print(self.path)
111 #print(self.filenameList)
112 #input()
113
114
115 self.setNextFile()
116
117 def readFirstHeader(self):
118 '''Read header and data'''
119
120 #self.flag_same_file=1
121 self.counter_block=0
122 self.parseHeader()
123 self.parseData()
124 self.blockIndex = 0
125
126 return
127
128 def parseHeader(self):
129 '''
130 '''
131
132 for i in range(len(self.header)):
133 for j in range(len(self.header[i])):
134 #print("len(header[i]) ",len(header[i]))
135 #input()
136 temp=self.fp.read(int(self.header[i].itemsize))
137 if isinstance(self.header[i][0], numpy.int32):
138 #print(struct.unpack('i', temp)[0])
139 self.header[i][0]=struct.unpack('i', temp)[0]
140 if isinstance(self.header[i][0], numpy.uint64):
141 self.header[i][0]=struct.unpack('q', temp)[0]
142 if isinstance(self.header[i][0], numpy.int8):
143 self.header[i][0]=struct.unpack('B', temp)[0]
144 if isinstance(self.header[i][0], numpy.float32):
145 self.header[i][0]=struct.unpack('f', temp)[0]
146
147 self.fp.seek(0,0)
148 if int(self.header[1][0])==int(81864):
149 self.experiment='DP'
150
151 elif int(self.header[1][0])==int(185504):
152 self.experiment='HP'
153
154
155 self.total_blocks=os.stat(self.filename).st_size//self.header[1][0]
156
157
158 def parseData(self):
159 '''
160 '''
161 if self.experiment=='DP':
162 self.header[15][0]=66
163 self.header[18][0]=16
164 self.header[17][0]=11
165 self.header[2][0]=2
166
167
168 self.noise=numpy.zeros(self.header[2][0],'float32') #self.header[2][0]
169 #tmpx=numpy.zeros((self.header[15][0],self.header[17][0],2),'float32')
170 self.kax=numpy.zeros((self.header[15][0],self.header[17][0],2),'float32')
171 self.kay=numpy.zeros((self.header[15][0],self.header[17][0],2),'float32')
172 self.kbx=numpy.zeros((self.header[15][0],self.header[17][0],2),'float32')
173 self.kby=numpy.zeros((self.header[15][0],self.header[17][0],2),'float32')
174 self.kax2=numpy.zeros((self.header[15][0],self.header[17][0],2),'float32')
175 self.kay2=numpy.zeros((self.header[15][0],self.header[17][0],2),'float32')
176 self.kbx2=numpy.zeros((self.header[15][0],self.header[17][0],2),'float32')
177 self.kby2=numpy.zeros((self.header[15][0],self.header[17][0],2),'float32')
178 self.kaxbx=numpy.zeros((self.header[15][0],self.header[17][0],2),'float32')
179 self.kaxby=numpy.zeros((self.header[15][0],self.header[17][0],2),'float32')
180 self.kaybx=numpy.zeros((self.header[15][0],self.header[17][0],2),'float32')
181 self.kayby=numpy.zeros((self.header[15][0],self.header[17][0],2),'float32')
182 self.kaxay=numpy.zeros((self.header[15][0],self.header[17][0],2),'float32')
183 self.kbxby=numpy.zeros((self.header[15][0],self.header[17][0],2),'float32')
184 self.output_LP_real=numpy.zeros((self.header[18][0],200,self.header[2][0]),'float32')
185 self.output_LP_imag=numpy.zeros((self.header[18][0],200,self.header[2][0]),'float32')
186 self.final_cross_products=[self.kax,self.kay,self.kbx,self.kby,self.kax2,self.kay2,self.kbx2,self.kby2,self.kaxbx,self.kaxby,self.kaybx,self.kayby,self.kaxay,self.kbxby]
187 #self.final_cross_products=[tmpx,tmpx,tmpx,tmpx,tmpx,tmpx,tmpx,tmpx,tmpx,tmpx,tmpx,tmpx,tmpx,tmpx]
188
189 #print("pos: ",self.fp.tell())
190
191
192 def readNextBlock(self):
193
194 while True:
195 self.flagDiscontinuousBlock = 0
196 #print(os.stat(self.filename).st_size)
197 #print(os.stat(self.filename).st_size//self.header[1][0])
198 #os.stat(self.fp)
199 if self.counter_block == self.total_blocks:
200
201 self.setNextFile()
202
203 self.readBlock()
204 #self.counter_block+=1
205
206 if (self.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or \
207 (self.datatime > datetime.datetime.combine(self.endDate, self.endTime)):
208
209 #print(self.datatime)
210 #print(datetime.datetime.combine(self.startDate, self.startTime))
211 #print(datetime.datetime.combine(self.endDate, self.endTime))
212 #print("warning")
213 log.warning(
214 'Reading Block No. {}/{} -> {} [Skipping]'.format(
215 self.counter_block,
216 self.total_blocks,
217 self.datatime.ctime()),
218 'DATReader')
219 continue
220 break
221
222 log.log(
223 'Reading Block No. {}/{} -> {}'.format(
224 self.counter_block,
225 self.total_blocks,
226 self.datatime.ctime()),
227 'DATReader')
228
229 return 1
230
231 def readBlock(self):
232 '''
233 '''
234
235 self.npos=self.counter_block*self.header[1][0]
236 #print(self.counter_block)
237 self.fp.seek(self.npos, 0)
238 self.counter_block+=1
239 #print("fpos1: ",self.fp.tell())
240
241 self.read_header()
242
243 #put by hand because old files didn't save it in the header
244 if self.experiment=='DP':
245 self.header[15][0]=66
246 self.header[18][0]=16
247 self.header[17][0]=11
248 self.header[2][0]=2
249 #########################################
250
251 if self.experiment=="HP":
252 self.long_pulse_products()
253
254 self.read_cross_products()
255
256
257 self.read_noise()
258
259
260 return
261
262
263
264 def read_header(self):
265
266
267 for i in range(len(self.header)):
268 for j in range(len(self.header[i])):
269 #print("len(header[i]) ",len(header[i]))
270 #input()
271 temp=self.fp.read(int(self.header[i].itemsize))
272 #if(b''==temp):
273 # self.setNextFile()
274 # self.flag_same_file=0
275 if isinstance(self.header[i][0], numpy.int32):
276 #print(struct.unpack('i', temp)[0])
277 self.header[i][0]=struct.unpack('i', temp)[0]
278 if isinstance(self.header[i][0], numpy.uint64):
279 self.header[i][0]=struct.unpack('q', temp)[0]
280 if isinstance(self.header[i][0], numpy.int8):
281 self.header[i][0]=struct.unpack('B', temp)[0]
282 if isinstance(self.header[i][0], numpy.float32):
283 self.header[i][0]=struct.unpack('f', temp)[0]
284 #else:
285 # continue
286 #self.fp.seek(self.npos_aux, 0)
287 # break
288
289 #print("fpos2: ",self.fp.tell())
290 #log.success('Parameters found: {}'.format(self.parameters),
291 # 'DATReader')
292 #print("Success")
293 #self.TimeBlockSeconds_for_dp_power = self.header[4][0]#-((self.dataOut.nint-1)*self.dataOut.NAVG*2)
294 #print(dataOut.TimeBlockSeconds_for_dp_power)
295
296 #self.datatime=datetime.datetime.fromtimestamp(self.header[4][0]).strftime("%Y-%m-%d %H:%M:%S")
297 #print(self.header[4][0])
298 self.datatime=datetime.datetime.fromtimestamp(self.header[4][0])
299 #print(self.header[1][0])
300
301 def long_pulse_products(self):
302 temp=self.fp.read(self.header[18][0]*self.header[2][0]*200*8)
303 ii=0
304
305 for l in range(self.header[18][0]): #lag
306 for r in range(self.header[2][0]): # channels
307 for k in range(200): #RANGE## generalizar
308 self.output_LP_real[l,k,r]=struct.unpack('f', temp[ii:ii+4])[0]
309 ii=ii+4
310 self.output_LP_imag[l,k,r]=struct.unpack('f', temp[ii:ii+4])[0]
311 ii=ii+4
312
313 #print(self.output_LP_real[1,1,1])
314 #print(self.output_LP_imag[1,1,1])
315 def read_cross_products(self):
316
317 for ind in range(len(self.final_cross_products)): #final cross products
318 temp=self.fp.read(self.header[17][0]*2*self.header[15][0]*4) #*4 bytes
319 #if(b''==temp):
320 # self.setNextFile()
321 # self.flag_same_file=0
322 ii=0
323 #print("kabxys.shape ",kabxys.shape)
324 #print(kabxys)
325 #print("fpos3: ",self.fp.tell())
326 for l in range(self.header[17][0]): #lag
327 #print("fpos3: ",self.fp.tell())
328 for fl in range(2): # unflip and flip
329 for k in range(self.header[15][0]): #RANGE
330 #print("fpos3: ",self.fp.tell())
331 self.final_cross_products[ind][k,l,fl]=struct.unpack('f', temp[ii:ii+4])[0]
332 ii=ii+4
333 #print("fpos2: ",self.fp.tell())
334
335
336
337 def read_noise(self):
338
339 temp=self.fp.read(self.header[2][0]*4) #*4 bytes self.header[2][0]
340 for ii in range(self.header[2][0]): #self.header[2][0]
341 self.noise[ii]=struct.unpack('f', temp[ii*4:(ii+1)*4])[0]
342
343 #print("fpos5: ",self.fp.tell())
344
345
346
347 def set_output(self):
348 '''
349 Storing data from buffer to dataOut object
350 '''
351 #print("fpos2: ",self.fp.tell())
352 ##self.dataOut.header = self.header
353 #this is put by hand because it isn't saved in the header
354 if self.experiment=='DP':
355 self.dataOut.NRANGE=0
356 self.dataOut.NSCAN=132
357 self.dataOut.heightList=self.header[10][0]*(numpy.arange(self.header[15][0]))
358 elif self.experiment=='HP':
359 self.dataOut.output_LP=self.output_LP_real+1.j*self.output_LP_imag
360 self.dataOut.NRANGE=200
361 self.dataOut.NSCAN=128
362 self.dataOut.heightList=self.header[10][0]*(numpy.arange(90)) #NEEEDS TO BE GENERALIZED
363 #########################################
364 #print(self.dataOut.output_LP[1,1,1])
365 self.dataOut.MAXNRANGENDT=self.header[3][0]
366 self.dataOut.NDP=self.header[15][0]
367 self.dataOut.DPL=self.header[17][0]
368 self.dataOut.DH=self.header[10][0]
369 self.dataOut.NAVG=self.header[7][0]
370 self.dataOut.H0=self.header[9][0]
371 self.dataOut.NR=self.header[2][0]
372 self.dataOut.NLAG=self.header[18][0]
373 #self.dataOut.tmpx=self.tmpx
374 #self.dataOut.timeZone = 5
375 #self.dataOut.final_cross_products=self.final_cross_products
376 self.dataOut.kax=self.kax
377 #print(self.dataOut.kax[1,1,1])
378 self.dataOut.kay=self.kay
379 self.dataOut.kbx=self.kbx
380 self.dataOut.kby=self.kby
381 self.dataOut.kax2=self.kax2
382 self.dataOut.kay2=self.kay2
383 self.dataOut.kbx2=self.kbx2
384 self.dataOut.kby2=self.kby2
385 self.dataOut.kaxbx=self.kaxbx
386 self.dataOut.kaxby=self.kaxby
387 self.dataOut.kaybx=self.kaybx
388 self.dataOut.kayby=self.kayby
389 self.dataOut.kaxay=self.kaxay
390 self.dataOut.kbxby=self.kbxby
391 self.dataOut.noise_final=self.noise
392 #print("NOISE",self.noise)
393
394
395 self.dataOut.useLocalTime=True
396
397 #self.dataOut.experiment=self.experiment
398 #print(self.datatime)
399 #print(self.dataOut.datatime)
400
401
402 #self.dataOut.utctime = (self.datatime - datetime.datetime(1970, 1, 1)).total_seconds()
403 #self.dataOut.utctimeInit = self.dataOut.utctime
404
405
406
407 self.dataOut.lt=self.datatime.hour
408
409
410 #print(RadarControllerHeader().ippSeconds)
411 #print(RadarControllerHeader().ipp)
412 #self.dataOut.utctime=time.gmtime(self.header[4][0])- datetime.datetime(1970, 1, 1)
413 #self.dataOut.utctime=self.dataOut.utctime.total_seconds()
414 #time1 = self.header[4][0] # header.time1
415 #print("time1: ",time1)
416 #print(self.header[4][0])
417 #date = time.ctime(time1)
418 #print("DADSADA",time.strptime(date))
419 #print("date_before: ",date)
420 #bd_time=time.gmtime(time1)
421 #print(time.mktime(bd_time))
422 #self.dataOut.utctime=time.mktime(bd_time)
423 self.dataOut.utctime = self.header[4][0]
424 #self.dataOut.datatime=a
425 #print(datetime.datetime.utcfromtimestamp(self.dataOut.utctime))
426 #self.dataOut.TimeBlockDate=self.datatime.ctime()
427 self.dataOut.TimeBlockSeconds=time.mktime(time.strptime(self.dataOut.datatime.ctime()))
428
429 #self.dataOut.heightList = self.ranges
430 #self.dataOut.utctime = (self.datatime - datetime.datetime(1970, 1, 1)).total_seconds()
431 #self.dataOut.utctimeInit = self.dataOut.utctime
432 #self.dataOut.paramInterval = min(self.intervals)
433 #self.dataOut.useLocalTime = False
434 self.dataOut.flagNoData = False
435 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
436 #print(self.dataOut.channelIndexList)
437 self.dataOut.channelList=list(range(0,self.header[2][0]))
438 #print(self.dataOut.channelList)
439 #print(self.datatime)
440 #print(self.dataOut.final_cross_products[0])
441
442
443 #self.dataOut.heightList=self.header[10][0]*(numpy.arange(self.header[15][0]))
444
445 #print(numpy.shape(self.dataOut.heightList))
446
447
448 def getData(self):
449 '''
450 Storing data from databuffer to dataOut object
451 '''
452
453 if not self.readNextBlock():
454 self.dataOut.flagNoData = True
455 return 0
456
457 self.set_output()
458
459 return 1
460
461 def run(self, **kwargs):
462
463 if not(self.isConfig):
464 self.setup(**kwargs)
465 self.isConfig = True
466 #print("fpos1: ",self.fp.tell())
467 self.getData()
468
469 return
470
471 @MPDecorator
472 class DatWriter(Operation):
473
474
475 def __init__(self):
476
477 Operation.__init__(self)
478 #self.dataOut = Voltage()
479 self.counter = 0
480 self.path = None
481 self.fp = None
482 return
483 #self.ext= '.dat'
484
485 def run(self, dataOut, path, format='dat', experiment=None, **kwargs):
486 print(dataOut.flagNoData)
487 print(dataOut.datatime.ctime())
488 print(dataOut.TimeBlockDate)
489 input()
490 #if dataOut.flag_save:
491 self.experiment=experiment
492 self.path=path
493 if self.experiment=='DP':
494 dataOut.header[1][0]=81864
495 elif self.experiment=='HP':
496 dataOut.header[1][0]=185504#173216
497 #dataOut.header[1][0]=bufsize
498 self.dataOut = dataOut
499 #print(self.dataOut.nint)
500 #self.bufsize=bufsize
501 if format == 'dat':
502 self.ext = '.dat'
503 if format == 'out':
504 self.ext = '.out'
505 self.putData()
506
507 return
508
509
510
511 def setFile(self):
512 '''
513 Create new out file object
514 '''
515
516 #self.dataOut.TimeBlockSeconds=time.mktime(time.strptime(self.dataOut.TimeBlockDate))
517 date = datetime.datetime.fromtimestamp(self.dataOut.TimeBlockSeconds)
518
519 #print("date",date)
520
521 filename = '{}{}{}'.format('jro',
522 date.strftime('%Y%m%d_%H%M%S'),
523 self.ext)
524 #print(filename)
525 #print(self.path)
526
527 self.fullname = os.path.join(self.path, filename)
528
529 if os.path.isfile(self.fullname) :
530 log.warning(
531 'Destination file {} already exists, previous file deleted.'.format(
532 self.fullname),
533 'DatWriter')
534 os.remove(self.fullname)
535
536 try:
537 log.success(
538 'Creating file: {}'.format(self.fullname),
539 'DatWriter')
540 if not os.path.exists(self.path):
541 os.makedirs(self.path)
542 #self.fp = madrigal.cedar.MadrigalCedarFile(self.fullname, True)
543 self.fp = open(self.fullname,'wb')
544
545 except ValueError as e:
546 log.error(
547 'Impossible to create *.out file',
548 'DatWriter')
549 return
550
551 return 1
552
553 def writeBlock(self):
554
555 #self.dataOut.paramInterval=2
556 #startTime = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
557 #print(startTime)
558 #endTime = startTime + datetime.timedelta(seconds=self.dataOut.paramInterval)
559
560 self.dataOut.header[0].astype('int32').tofile(self.fp)
561 self.dataOut.header[1].astype('int32').tofile(self.fp)
562 self.dataOut.header[2].astype('int32').tofile(self.fp)
563 self.dataOut.header[3].astype('int32').tofile(self.fp)
564 self.dataOut.header[4].astype('uint64').tofile(self.fp)
565 self.dataOut.header[5].astype('uint64').tofile(self.fp)
566 self.dataOut.header[6].astype('int32').tofile(self.fp)
567 self.dataOut.header[7].astype('int32').tofile(self.fp)
568 #print(dataOut.header[7])
569 self.dataOut.header[8].astype('int8').tofile(self.fp)
570 self.dataOut.header[9].astype('float32').tofile(self.fp)
571 self.dataOut.header[10].astype('float32').tofile(self.fp)
572 self.dataOut.header[11].astype('float32').tofile(self.fp)
573 self.dataOut.header[12].astype('int32').tofile(self.fp)
574 self.dataOut.header[13].astype('int32').tofile(self.fp)
575 self.dataOut.header[14].astype('int32').tofile(self.fp)
576 self.dataOut.header[15].astype('int32').tofile(self.fp)
577 self.dataOut.header[16].astype('uint64').tofile(self.fp)
578 self.dataOut.header[17].astype('int32').tofile(self.fp)
579 self.dataOut.header[18].astype('int32').tofile(self.fp)
580 self.dataOut.header[19].astype('int32').tofile(self.fp)
581 self.dataOut.header[20].astype('float32').tofile(self.fp)
582 self.dataOut.header[21].astype('uint64').tofile(self.fp)
583 self.dataOut.header[22].astype('uint64').tofile(self.fp)
584 self.dataOut.header[23].astype('float32').tofile(self.fp)
585 self.dataOut.header[24].astype('float32').tofile(self.fp)
586 self.dataOut.header[25].astype('float32').tofile(self.fp)
587 self.dataOut.header[26].astype('float32').tofile(self.fp)
588 self.dataOut.header[27].astype('int32').tofile(self.fp)
589 self.dataOut.header[28].astype('int32').tofile(self.fp)
590 self.dataOut.header[29].astype('int32').tofile(self.fp)
591 self.dataOut.header[30].astype('int32').tofile(self.fp)
592 self.dataOut.header[31].astype('int32').tofile(self.fp)
593 #print("tell before 1 ",self.fp.tell())
594 #input()
595
596 if self.experiment=="HP":
597 #print("INSIDE")
598 #tmp=numpy.zeros(1,dtype='complex64')
599 #print("tmp ",tmp)
600 #input()
601 #print(dataOut.NLAG)
602 #print(dataOut.NR)
603 #print(dataOut.NRANGE)
604 for l in range(self.dataOut.NLAG): #lag
605 for r in range(self.dataOut.NR): # unflip and flip
606 for k in range(self.dataOut.NRANGE): #RANGE
607 self.dataOut.output_LP.real[l,k,r].astype('float32').tofile(self.fp)
608 self.dataOut.output_LP.imag[l,k,r].astype('float32').tofile(self.fp)
609
610
611 #print("tell before 2 ",self.outputfile.tell())
612
613
614
615
616
617 #print(self.dataOut.output_LP[1,1,1])
618
619 #print(self.dataOut.kax)
620 final_cross_products=[self.dataOut.kax,self.dataOut.kay,self.dataOut.kbx,self.dataOut.kby,
621 self.dataOut.kax2,self.dataOut.kay2,self.dataOut.kbx2,self.dataOut.kby2,
622 self.dataOut.kaxbx,self.dataOut.kaxby,self.dataOut.kaybx,self.dataOut.kayby,
623 self.dataOut.kaxay,self.dataOut.kbxby]
624
625 #print(self.dataOut.kax)
626 #print("tell before crossp saving ",self.outputfile.tell())
627 for kabxys in final_cross_products:
628
629 for l in range(self.dataOut.DPL): #lag
630 for fl in range(2): # unflip and flip
631 for k in range(self.dataOut.NDT): #RANGE
632 kabxys[k,l,fl].astype('float32').tofile(self.fp)
633
634
635 #print("tell before noise saving ",self.outputfile.tell())
636
637
638 for nch in range(self.dataOut.NR):
639 self.dataOut.noise_final[nch].astype('float32').tofile(self.fp)
640
641 #print("tell before noise saving ",self.fp.tell())
642 #input()
643
644
645
646
647 log.log(
648 'Writing {} blocks'.format(
649 self.counter+1),
650 'DatWriter')
651
652
653
654
655
656
657 def putData(self):
658 #print("flagNoData",self.dataOut.flagNoData)
659 #print("flagDiscontinuousBlock",self.dataOut.flagDiscontinuousBlock)
660 #print(self.dataOut.flagNoData)
661
662 if self.dataOut.flagNoData:
663 return 0
664
665 if self.dataOut.flagDiscontinuousBlock:
666
667 self.counter = 0
668
669 if self.counter == 0:
670 self.setFile()
671 #if self.experiment=="HP":
672 #if self.dataOut.debris_activated==0:
673 #self.writeBlock()
674 #self.counter += 1
675 #else:
676 self.writeBlock()
677 self.counter += 1
678
679 def close(self):
680
681 if self.counter > 0:
682 self.fp.close()
683 log.success('Closing file {}'.format(self.fullname), 'DatWriter')
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,1193 +1,1592
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 # All rights reserved.
2 # All rights reserved.
3 #
3 #
4 # Distributed under the terms of the BSD 3-clause license.
4 # Distributed under the terms of the BSD 3-clause license.
5 """Definition of diferent Data objects for different types of data
5 """Definition of diferent Data objects for different types of data
6
6
7 Here you will find the diferent data objects for the different types
7 Here you will find the diferent data objects for the different types
8 of data, this data objects must be used as dataIn or dataOut objects in
8 of data, this data objects must be used as dataIn or dataOut objects in
9 processing units and operations. Currently the supported data objects are:
9 processing units and operations. Currently the supported data objects are:
10 Voltage, Spectra, SpectraHeis, Fits, Correlation and Parameters
10 Voltage, Spectra, SpectraHeis, Fits, Correlation and Parameters
11 """
11 """
12
12
13 import copy
13 import copy
14 import numpy
14 import numpy
15 import datetime
15 import datetime
16 import json
16 import json
17
17
18 import schainpy.admin
18 import schainpy.admin
19 from schainpy.utils import log
19 from schainpy.utils import log
20 from .jroheaderIO import SystemHeader, RadarControllerHeader
20 from .jroheaderIO import SystemHeader, RadarControllerHeader
21 from schainpy.model.data import _noise
21 from schainpy.model.data import _noise
22
22
23
23
24 def getNumpyDtype(dataTypeCode):
24 def getNumpyDtype(dataTypeCode):
25
25
26 if dataTypeCode == 0:
26 if dataTypeCode == 0:
27 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
27 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
28 elif dataTypeCode == 1:
28 elif dataTypeCode == 1:
29 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
29 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
30 elif dataTypeCode == 2:
30 elif dataTypeCode == 2:
31 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
31 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
32 elif dataTypeCode == 3:
32 elif dataTypeCode == 3:
33 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
33 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
34 elif dataTypeCode == 4:
34 elif dataTypeCode == 4:
35 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
35 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
36 elif dataTypeCode == 5:
36 elif dataTypeCode == 5:
37 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
37 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
38 else:
38 else:
39 raise ValueError('dataTypeCode was not defined')
39 raise ValueError('dataTypeCode was not defined')
40
40
41 return numpyDtype
41 return numpyDtype
42
42
43
43
44 def getDataTypeCode(numpyDtype):
44 def getDataTypeCode(numpyDtype):
45
45
46 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
46 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
47 datatype = 0
47 datatype = 0
48 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
48 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
49 datatype = 1
49 datatype = 1
50 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
50 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
51 datatype = 2
51 datatype = 2
52 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
52 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
53 datatype = 3
53 datatype = 3
54 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
54 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
55 datatype = 4
55 datatype = 4
56 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
56 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
57 datatype = 5
57 datatype = 5
58 else:
58 else:
59 datatype = None
59 datatype = None
60
60
61 return datatype
61 return datatype
62
62
63
63
64 def hildebrand_sekhon(data, navg):
64 def hildebrand_sekhon(data, navg):
65 """
65 """
66 This method is for the objective determination of the noise level in Doppler spectra. This
66 This method is for the objective determination of the noise level in Doppler spectra. This
67 implementation technique is based on the fact that the standard deviation of the spectral
67 implementation technique is based on the fact that the standard deviation of the spectral
68 densities is equal to the mean spectral density for white Gaussian noise
68 densities is equal to the mean spectral density for white Gaussian noise
69
69
70 Inputs:
70 Inputs:
71 Data : heights
71 Data : heights
72 navg : numbers of averages
72 navg : numbers of averages
73
73
74 Return:
74 Return:
75 mean : noise's level
75 mean : noise's level
76 """
76 """
77
77
78 sortdata = numpy.sort(data, axis=None)
78 sortdata = numpy.sort(data, axis=None)
79 #print(numpy.shape(data))
80 #exit()
79 '''
81 '''
80 lenOfData = len(sortdata)
82 lenOfData = len(sortdata)
81 nums_min = lenOfData*0.2
83 nums_min = lenOfData*0.2
82
84
83 if nums_min <= 5:
85 if nums_min <= 5:
84
86
85 nums_min = 5
87 nums_min = 5
86
88
87 sump = 0.
89 sump = 0.
88 sumq = 0.
90 sumq = 0.
89
91
90 j = 0
92 j = 0
91 cont = 1
93 cont = 1
92
94
93 while((cont == 1)and(j < lenOfData)):
95 while((cont == 1)and(j < lenOfData)):
94
96
95 sump += sortdata[j]
97 sump += sortdata[j]
96 sumq += sortdata[j]**2
98 sumq += sortdata[j]**2
97
99
98 if j > nums_min:
100 if j > nums_min:
99 rtest = float(j)/(j-1) + 1.0/navg
101 rtest = float(j)/(j-1) + 1.0/navg
100 if ((sumq*j) > (rtest*sump**2)):
102 if ((sumq*j) > (rtest*sump**2)):
101 j = j - 1
103 j = j - 1
102 sump = sump - sortdata[j]
104 sump = sump - sortdata[j]
103 sumq = sumq - sortdata[j]**2
105 sumq = sumq - sortdata[j]**2
104 cont = 0
106 cont = 0
105
107
106 j += 1
108 j += 1
107
109
108 lnoise = sump / j
110 lnoise = sump / j
109 '''
111 '''
110 return _noise.hildebrand_sekhon(sortdata, navg)
112 return _noise.hildebrand_sekhon(sortdata, navg)
111
113
112
114
113 class Beam:
115 class Beam:
114
116
115 def __init__(self):
117 def __init__(self):
116 self.codeList = []
118 self.codeList = []
117 self.azimuthList = []
119 self.azimuthList = []
118 self.zenithList = []
120 self.zenithList = []
119
121
120
122
121 class GenericData(object):
123 class GenericData(object):
122
124
123 flagNoData = True
125 flagNoData = True
124
126
125 def copy(self, inputObj=None):
127 def copy(self, inputObj=None):
126
128
127 if inputObj == None:
129 if inputObj == None:
128 return copy.deepcopy(self)
130 return copy.deepcopy(self)
129
131
130 for key in list(inputObj.__dict__.keys()):
132 for key in list(inputObj.__dict__.keys()):
131
133
132 attribute = inputObj.__dict__[key]
134 attribute = inputObj.__dict__[key]
133
135
134 # If this attribute is a tuple or list
136 # If this attribute is a tuple or list
135 if type(inputObj.__dict__[key]) in (tuple, list):
137 if type(inputObj.__dict__[key]) in (tuple, list):
136 self.__dict__[key] = attribute[:]
138 self.__dict__[key] = attribute[:]
137 continue
139 continue
138
140
139 # If this attribute is another object or instance
141 # If this attribute is another object or instance
140 if hasattr(attribute, '__dict__'):
142 if hasattr(attribute, '__dict__'):
141 self.__dict__[key] = attribute.copy()
143 self.__dict__[key] = attribute.copy()
142 continue
144 continue
143
145
144 self.__dict__[key] = inputObj.__dict__[key]
146 self.__dict__[key] = inputObj.__dict__[key]
145
147
146 def deepcopy(self):
148 def deepcopy(self):
147
149
148 return copy.deepcopy(self)
150 return copy.deepcopy(self)
149
151
150 def isEmpty(self):
152 def isEmpty(self):
151
153
152 return self.flagNoData
154 return self.flagNoData
153
155
154 def isReady(self):
156 def isReady(self):
155
157
156 return not self.flagNoData
158 return not self.flagNoData
157
159
158
160
159 class JROData(GenericData):
161 class JROData(GenericData):
160
162
161 systemHeaderObj = SystemHeader()
163 systemHeaderObj = SystemHeader()
162 radarControllerHeaderObj = RadarControllerHeader()
164 radarControllerHeaderObj = RadarControllerHeader()
163 type = None
165 type = None
164 datatype = None # dtype but in string
166 datatype = None # dtype but in string
165 nProfiles = None
167 nProfiles = None
166 heightList = None
168 heightList = None
167 channelList = None
169 channelList = None
168 flagDiscontinuousBlock = False
170 flagDiscontinuousBlock = False
169 useLocalTime = False
171 useLocalTime = False
170 utctime = None
172 utctime = None
171 timeZone = None
173 timeZone = None
172 dstFlag = None
174 dstFlag = None
173 errorCount = None
175 errorCount = None
174 blocksize = None
176 blocksize = None
175 flagDecodeData = False # asumo q la data no esta decodificada
177 flagDecodeData = False # asumo q la data no esta decodificada
176 flagDeflipData = False # asumo q la data no esta sin flip
178 flagDeflipData = False # asumo q la data no esta sin flip
177 flagShiftFFT = False
179 flagShiftFFT = False
178 nCohInt = None
180 nCohInt = None
179 windowOfFilter = 1
181 windowOfFilter = 1
180 C = 3e8
182 C = 3e8
181 frequency = 49.92e6
183 frequency = 49.92e6
182 realtime = False
184 realtime = False
183 beacon_heiIndexList = None
185 beacon_heiIndexList = None
184 last_block = None
186 last_block = None
185 blocknow = None
187 blocknow = None
186 azimuth = None
188 azimuth = None
187 zenith = None
189 zenith = None
188 beam = Beam()
190 beam = Beam()
189 profileIndex = None
191 profileIndex = None
190 error = None
192 error = None
191 data = None
193 data = None
192 nmodes = None
194 nmodes = None
193 metadata_list = ['heightList', 'timeZone', 'type']
195 metadata_list = ['heightList', 'timeZone', 'type']
194
196
195 def __str__(self):
197 def __str__(self):
196
198
197 return '{} - {}'.format(self.type, self.datatime())
199 return '{} - {}'.format(self.type, self.datatime())
198
200
199 def getNoise(self):
201 def getNoise(self):
200
202
201 raise NotImplementedError
203 raise NotImplementedError
202
204
203 @property
205 @property
204 def nChannels(self):
206 def nChannels(self):
205
207
206 return len(self.channelList)
208 return len(self.channelList)
207
209
208 @property
210 @property
209 def channelIndexList(self):
211 def channelIndexList(self):
210
212
211 return list(range(self.nChannels))
213 return list(range(self.nChannels))
212
214
213 @property
215 @property
214 def nHeights(self):
216 def nHeights(self):
215
217
216 return len(self.heightList)
218 return len(self.heightList)
217
219
218 def getDeltaH(self):
220 def getDeltaH(self):
219
221
220 return self.heightList[1] - self.heightList[0]
222 return self.heightList[1] - self.heightList[0]
221
223
222 @property
224 @property
223 def ltctime(self):
225 def ltctime(self):
224
226
225 if self.useLocalTime:
227 if self.useLocalTime:
226 return self.utctime - self.timeZone * 60
228 return self.utctime - self.timeZone * 60
227
229
228 return self.utctime
230 return self.utctime
229
231
230 @property
232 @property
231 def datatime(self):
233 def datatime(self):
232
234
233 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
235 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
234 return datatimeValue
236 return datatimeValue
235
237
236 def getTimeRange(self):
238 def getTimeRange(self):
237
239
238 datatime = []
240 datatime = []
239
241
240 datatime.append(self.ltctime)
242 datatime.append(self.ltctime)
241 datatime.append(self.ltctime + self.timeInterval + 1)
243 datatime.append(self.ltctime + self.timeInterval + 1)
242
244
243 datatime = numpy.array(datatime)
245 datatime = numpy.array(datatime)
244
246
245 return datatime
247 return datatime
246
248
247 def getFmaxTimeResponse(self):
249 def getFmaxTimeResponse(self):
248
250
249 period = (10**-6) * self.getDeltaH() / (0.15)
251 period = (10**-6) * self.getDeltaH() / (0.15)
250
252
251 PRF = 1. / (period * self.nCohInt)
253 PRF = 1. / (period * self.nCohInt)
252
254
253 fmax = PRF
255 fmax = PRF
254
256
255 return fmax
257 return fmax
256
258
257 def getFmax(self):
259 def getFmax(self):
258 PRF = 1. / (self.ippSeconds * self.nCohInt)
260 PRF = 1. / (self.ippSeconds * self.nCohInt)
259
261
260 fmax = PRF
262 fmax = PRF
261 return fmax
263 return fmax
262
264
263 def getVmax(self):
265 def getVmax(self):
264
266
265 _lambda = self.C / self.frequency
267 _lambda = self.C / self.frequency
266
268
267 vmax = self.getFmax() * _lambda / 2
269 vmax = self.getFmax() * _lambda / 2
268
270
269 return vmax
271 return vmax
270
272
271 @property
273 @property
272 def ippSeconds(self):
274 def ippSeconds(self):
273 '''
275 '''
274 '''
276 '''
275 return self.radarControllerHeaderObj.ippSeconds
277 return self.radarControllerHeaderObj.ippSeconds
276
278
277 @ippSeconds.setter
279 @ippSeconds.setter
278 def ippSeconds(self, ippSeconds):
280 def ippSeconds(self, ippSeconds):
279 '''
281 '''
280 '''
282 '''
281 self.radarControllerHeaderObj.ippSeconds = ippSeconds
283 self.radarControllerHeaderObj.ippSeconds = ippSeconds
282
284
283 @property
285 @property
284 def code(self):
286 def code(self):
285 '''
287 '''
286 '''
288 '''
287 return self.radarControllerHeaderObj.code
289 return self.radarControllerHeaderObj.code
288
290
289 @code.setter
291 @code.setter
290 def code(self, code):
292 def code(self, code):
291 '''
293 '''
292 '''
294 '''
293 self.radarControllerHeaderObj.code = code
295 self.radarControllerHeaderObj.code = code
294
296
295 @property
297 @property
296 def nCode(self):
298 def nCode(self):
297 '''
299 '''
298 '''
300 '''
299 return self.radarControllerHeaderObj.nCode
301 return self.radarControllerHeaderObj.nCode
300
302
301 @nCode.setter
303 @nCode.setter
302 def nCode(self, ncode):
304 def nCode(self, ncode):
303 '''
305 '''
304 '''
306 '''
305 self.radarControllerHeaderObj.nCode = ncode
307 self.radarControllerHeaderObj.nCode = ncode
306
308
307 @property
309 @property
308 def nBaud(self):
310 def nBaud(self):
309 '''
311 '''
310 '''
312 '''
311 return self.radarControllerHeaderObj.nBaud
313 return self.radarControllerHeaderObj.nBaud
312
314
313 @nBaud.setter
315 @nBaud.setter
314 def nBaud(self, nbaud):
316 def nBaud(self, nbaud):
315 '''
317 '''
316 '''
318 '''
317 self.radarControllerHeaderObj.nBaud = nbaud
319 self.radarControllerHeaderObj.nBaud = nbaud
318
320
319 @property
321 @property
320 def ipp(self):
322 def ipp(self):
321 '''
323 '''
322 '''
324 '''
323 return self.radarControllerHeaderObj.ipp
325 return self.radarControllerHeaderObj.ipp
324
326
325 @ipp.setter
327 @ipp.setter
326 def ipp(self, ipp):
328 def ipp(self, ipp):
327 '''
329 '''
328 '''
330 '''
329 self.radarControllerHeaderObj.ipp = ipp
331 self.radarControllerHeaderObj.ipp = ipp
330
332
331 @property
333 @property
332 def metadata(self):
334 def metadata(self):
333 '''
335 '''
334 '''
336 '''
335
337
336 return {attr: getattr(self, attr) for attr in self.metadata_list}
338 return {attr: getattr(self, attr) for attr in self.metadata_list}
337
339
338
340
339 class Voltage(JROData):
341 class Voltage(JROData):
340
342
341 dataPP_POW = None
343 dataPP_POW = None
342 dataPP_DOP = None
344 dataPP_DOP = None
343 dataPP_WIDTH = None
345 dataPP_WIDTH = None
344 dataPP_SNR = None
346 dataPP_SNR = None
345
347
346 def __init__(self):
348 def __init__(self):
347 '''
349 '''
348 Constructor
350 Constructor
349 '''
351 '''
350
352
351 self.useLocalTime = True
353 self.useLocalTime = True
352 self.radarControllerHeaderObj = RadarControllerHeader()
354 self.radarControllerHeaderObj = RadarControllerHeader()
353 self.systemHeaderObj = SystemHeader()
355 self.systemHeaderObj = SystemHeader()
354 self.type = "Voltage"
356 self.type = "Voltage"
355 self.data = None
357 self.data = None
356 self.nProfiles = None
358 self.nProfiles = None
357 self.heightList = None
359 self.heightList = None
358 self.channelList = None
360 self.channelList = None
359 self.flagNoData = True
361 self.flagNoData = True
360 self.flagDiscontinuousBlock = False
362 self.flagDiscontinuousBlock = False
361 self.utctime = None
363 self.utctime = None
362 self.timeZone = 0
364 self.timeZone = 0
363 self.dstFlag = None
365 self.dstFlag = None
364 self.errorCount = None
366 self.errorCount = None
365 self.nCohInt = None
367 self.nCohInt = None
366 self.blocksize = None
368 self.blocksize = None
367 self.flagCohInt = False
369 self.flagCohInt = False
368 self.flagDecodeData = False # asumo q la data no esta decodificada
370 self.flagDecodeData = False # asumo q la data no esta decodificada
369 self.flagDeflipData = False # asumo q la data no esta sin flip
371 self.flagDeflipData = False # asumo q la data no esta sin flip
370 self.flagShiftFFT = False
372 self.flagShiftFFT = False
371 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
373 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
372 self.profileIndex = 0
374 self.profileIndex = 0
373 self.metadata_list = ['type', 'heightList', 'timeZone', 'nProfiles', 'channelList', 'nCohInt',
375 self.metadata_list = ['type', 'heightList', 'timeZone', 'nProfiles', 'channelList', 'nCohInt',
374 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp']
376 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp']
375
377
376 def getNoisebyHildebrand(self, channel=None):
378 def getNoisebyHildebrand(self, channel=None):
377 """
379 """
378 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
380 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
379
381
380 Return:
382 Return:
381 noiselevel
383 noiselevel
382 """
384 """
383
385
384 if channel != None:
386 if channel != None:
385 data = self.data[channel]
387 data = self.data[channel]
386 nChannels = 1
388 nChannels = 1
387 else:
389 else:
388 data = self.data
390 data = self.data
389 nChannels = self.nChannels
391 nChannels = self.nChannels
390
392
391 noise = numpy.zeros(nChannels)
393 noise = numpy.zeros(nChannels)
392 power = data * numpy.conjugate(data)
394 power = data * numpy.conjugate(data)
393
395
394 for thisChannel in range(nChannels):
396 for thisChannel in range(nChannels):
395 if nChannels == 1:
397 if nChannels == 1:
396 daux = power[:].real
398 daux = power[:].real
397 else:
399 else:
398 daux = power[thisChannel, :].real
400 daux = power[thisChannel, :].real
399 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
401 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
400
402
401 return noise
403 return noise
402
404
403 def getNoise(self, type=1, channel=None):
405 def getNoise(self, type=1, channel=None):
404
406
405 if type == 1:
407 if type == 1:
406 noise = self.getNoisebyHildebrand(channel)
408 noise = self.getNoisebyHildebrand(channel)
407
409
408 return noise
410 return noise
409
411
410 def getPower(self, channel=None):
412 def getPower(self, channel=None):
411
413
412 if channel != None:
414 if channel != None:
413 data = self.data[channel]
415 data = self.data[channel]
414 else:
416 else:
415 data = self.data
417 data = self.data
416
418
417 power = data * numpy.conjugate(data)
419 power = data * numpy.conjugate(data)
418 powerdB = 10 * numpy.log10(power.real)
420 powerdB = 10 * numpy.log10(power.real)
419 powerdB = numpy.squeeze(powerdB)
421 powerdB = numpy.squeeze(powerdB)
420
422
421 return powerdB
423 return powerdB
422
424
423 @property
425 @property
424 def timeInterval(self):
426 def timeInterval(self):
425
427
426 return self.ippSeconds * self.nCohInt
428 return self.ippSeconds * self.nCohInt
427
429
428 noise = property(getNoise, "I'm the 'nHeights' property.")
430 noise = property(getNoise, "I'm the 'nHeights' property.")
429
431
430
432
433 class CrossProds(JROData):
434
435 # data es un numpy array de 2 dmensiones (canales, alturas)
436 data = None
437
438 def __init__(self):
439 '''
440 Constructor
441 '''
442
443 self.useLocalTime = True
444 '''
445 self.radarControllerHeaderObj = RadarControllerHeader()
446 self.systemHeaderObj = SystemHeader()
447 self.type = "Voltage"
448 self.data = None
449 # self.dtype = None
450 # self.nChannels = 0
451 # self.nHeights = 0
452 self.nProfiles = None
453 self.heightList = None
454 self.channelList = None
455 # self.channelIndexList = None
456 self.flagNoData = True
457 self.flagDiscontinuousBlock = False
458 self.utctime = None
459 self.timeZone = None
460 self.dstFlag = None
461 self.errorCount = None
462 self.nCohInt = None
463 self.blocksize = None
464 self.flagDecodeData = False # asumo q la data no esta decodificada
465 self.flagDeflipData = False # asumo q la data no esta sin flip
466 self.flagShiftFFT = False
467 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
468 self.profileIndex = 0
469
470
471 def getNoisebyHildebrand(self, channel=None):
472
473
474 if channel != None:
475 data = self.data[channel]
476 nChannels = 1
477 else:
478 data = self.data
479 nChannels = self.nChannels
480
481 noise = numpy.zeros(nChannels)
482 power = data * numpy.conjugate(data)
483
484 for thisChannel in range(nChannels):
485 if nChannels == 1:
486 daux = power[:].real
487 else:
488 daux = power[thisChannel, :].real
489 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
490
491 return noise
492
493 def getNoise(self, type=1, channel=None):
494
495 if type == 1:
496 noise = self.getNoisebyHildebrand(channel)
497
498 return noise
499
500 def getPower(self, channel=None):
501
502 if channel != None:
503 data = self.data[channel]
504 else:
505 data = self.data
506
507 power = data * numpy.conjugate(data)
508 powerdB = 10 * numpy.log10(power.real)
509 powerdB = numpy.squeeze(powerdB)
510
511 return powerdB
512
513 def getTimeInterval(self):
514
515 timeInterval = self.ippSeconds * self.nCohInt
516
517 return timeInterval
518
519 noise = property(getNoise, "I'm the 'nHeights' property.")
520 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
521 '''
522 def getTimeInterval(self):
523
524 timeInterval = self.ippSeconds * self.nCohInt
525
526 return timeInterval
527
528
529
431 class Spectra(JROData):
530 class Spectra(JROData):
432
531
433 def __init__(self):
532 def __init__(self):
434 '''
533 '''
435 Constructor
534 Constructor
436 '''
535 '''
437
536
438 self.useLocalTime = True
537 self.useLocalTime = True
439 self.radarControllerHeaderObj = RadarControllerHeader()
538 self.radarControllerHeaderObj = RadarControllerHeader()
440 self.systemHeaderObj = SystemHeader()
539 self.systemHeaderObj = SystemHeader()
441 self.type = "Spectra"
540 self.type = "Spectra"
442 self.timeZone = 0
541 self.timeZone = 0
443 self.nProfiles = None
542 self.nProfiles = None
444 self.heightList = None
543 self.heightList = None
445 self.channelList = None
544 self.channelList = None
446 self.pairsList = None
545 self.pairsList = None
447 self.flagNoData = True
546 self.flagNoData = True
448 self.flagDiscontinuousBlock = False
547 self.flagDiscontinuousBlock = False
449 self.utctime = None
548 self.utctime = None
450 self.nCohInt = None
549 self.nCohInt = None
451 self.nIncohInt = None
550 self.nIncohInt = None
452 self.blocksize = None
551 self.blocksize = None
453 self.nFFTPoints = None
552 self.nFFTPoints = None
454 self.wavelength = None
553 self.wavelength = None
455 self.flagDecodeData = False # asumo q la data no esta decodificada
554 self.flagDecodeData = False # asumo q la data no esta decodificada
456 self.flagDeflipData = False # asumo q la data no esta sin flip
555 self.flagDeflipData = False # asumo q la data no esta sin flip
457 self.flagShiftFFT = False
556 self.flagShiftFFT = False
458 self.ippFactor = 1
557 self.ippFactor = 1
459 self.beacon_heiIndexList = []
558 self.beacon_heiIndexList = []
460 self.noise_estimation = None
559 self.noise_estimation = None
461 self.metadata_list = ['type', 'heightList', 'timeZone', 'pairsList', 'channelList', 'nCohInt',
560 self.metadata_list = ['type', 'heightList', 'timeZone', 'pairsList', 'channelList', 'nCohInt',
462 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp','nIncohInt', 'nFFTPoints', 'nProfiles']
561 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp','nIncohInt', 'nFFTPoints', 'nProfiles']
463
562
464 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
563 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
465 """
564 """
466 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
565 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
467
566
468 Return:
567 Return:
469 noiselevel
568 noiselevel
470 """
569 """
471
570
472 noise = numpy.zeros(self.nChannels)
571 noise = numpy.zeros(self.nChannels)
473
572
474 for channel in range(self.nChannels):
573 for channel in range(self.nChannels):
475 daux = self.data_spc[channel,
574 daux = self.data_spc[channel,
476 xmin_index:xmax_index, ymin_index:ymax_index]
575 xmin_index:xmax_index, ymin_index:ymax_index]
477 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
576 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
478
577
479 return noise
578 return noise
480
579
481 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
580 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
482
581
483 if self.noise_estimation is not None:
582 if self.noise_estimation is not None:
484 # this was estimated by getNoise Operation defined in jroproc_spectra.py
583 # this was estimated by getNoise Operation defined in jroproc_spectra.py
485 return self.noise_estimation
584 return self.noise_estimation
486 else:
585 else:
487 noise = self.getNoisebyHildebrand(
586 noise = self.getNoisebyHildebrand(
488 xmin_index, xmax_index, ymin_index, ymax_index)
587 xmin_index, xmax_index, ymin_index, ymax_index)
489 return noise
588 return noise
490
589
491 def getFreqRangeTimeResponse(self, extrapoints=0):
590 def getFreqRangeTimeResponse(self, extrapoints=0):
492
591
493 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
592 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
494 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
593 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
495
594
496 return freqrange
595 return freqrange
497
596
498 def getAcfRange(self, extrapoints=0):
597 def getAcfRange(self, extrapoints=0):
499
598
500 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
599 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
501 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
600 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
502
601
503 return freqrange
602 return freqrange
504
603
505 def getFreqRange(self, extrapoints=0):
604 def getFreqRange(self, extrapoints=0):
506
605
507 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
606 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
508 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
607 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
509
608
510 return freqrange
609 return freqrange
511
610
512 def getVelRange(self, extrapoints=0):
611 def getVelRange(self, extrapoints=0):
513
612
514 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
613 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
515 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
614 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
516
615
517 if self.nmodes:
616 if self.nmodes:
518 return velrange/self.nmodes
617 return velrange/self.nmodes
519 else:
618 else:
520 return velrange
619 return velrange
521
620
522 @property
621 @property
523 def nPairs(self):
622 def nPairs(self):
524
623
525 return len(self.pairsList)
624 return len(self.pairsList)
526
625
527 @property
626 @property
528 def pairsIndexList(self):
627 def pairsIndexList(self):
529
628
530 return list(range(self.nPairs))
629 return list(range(self.nPairs))
531
630
532 @property
631 @property
533 def normFactor(self):
632 def normFactor(self):
534
633
535 pwcode = 1
634 pwcode = 1
536
635
537 if self.flagDecodeData:
636 if self.flagDecodeData:
538 pwcode = numpy.sum(self.code[0]**2)
637 pwcode = numpy.sum(self.code[0]**2)
539 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
638 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
540 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
639 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
541
640
542 return normFactor
641 return normFactor
543
642
544 @property
643 @property
545 def flag_cspc(self):
644 def flag_cspc(self):
546
645
547 if self.data_cspc is None:
646 if self.data_cspc is None:
548 return True
647 return True
549
648
550 return False
649 return False
551
650
552 @property
651 @property
553 def flag_dc(self):
652 def flag_dc(self):
554
653
555 if self.data_dc is None:
654 if self.data_dc is None:
556 return True
655 return True
557
656
558 return False
657 return False
559
658
560 @property
659 @property
561 def timeInterval(self):
660 def timeInterval(self):
562
661
563 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
662 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
564 if self.nmodes:
663 if self.nmodes:
565 return self.nmodes*timeInterval
664 return self.nmodes*timeInterval
566 else:
665 else:
567 return timeInterval
666 return timeInterval
568
667
569 def getPower(self):
668 def getPower(self):
570
669
571 factor = self.normFactor
670 factor = self.normFactor
572 z = self.data_spc / factor
671 z = self.data_spc / factor
573 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
672 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
574 avg = numpy.average(z, axis=1)
673 avg = numpy.average(z, axis=1)
575
674
576 return 10 * numpy.log10(avg)
675 return 10 * numpy.log10(avg)
577
676
578 def getCoherence(self, pairsList=None, phase=False):
677 def getCoherence(self, pairsList=None, phase=False):
579
678
580 z = []
679 z = []
581 if pairsList is None:
680 if pairsList is None:
582 pairsIndexList = self.pairsIndexList
681 pairsIndexList = self.pairsIndexList
583 else:
682 else:
584 pairsIndexList = []
683 pairsIndexList = []
585 for pair in pairsList:
684 for pair in pairsList:
586 if pair not in self.pairsList:
685 if pair not in self.pairsList:
587 raise ValueError("Pair %s is not in dataOut.pairsList" % (
686 raise ValueError("Pair %s is not in dataOut.pairsList" % (
588 pair))
687 pair))
589 pairsIndexList.append(self.pairsList.index(pair))
688 pairsIndexList.append(self.pairsList.index(pair))
590 for i in range(len(pairsIndexList)):
689 for i in range(len(pairsIndexList)):
591 pair = self.pairsList[pairsIndexList[i]]
690 pair = self.pairsList[pairsIndexList[i]]
592 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
691 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
593 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
692 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
594 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
693 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
595 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
694 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
596 if phase:
695 if phase:
597 data = numpy.arctan2(avgcoherenceComplex.imag,
696 data = numpy.arctan2(avgcoherenceComplex.imag,
598 avgcoherenceComplex.real) * 180 / numpy.pi
697 avgcoherenceComplex.real) * 180 / numpy.pi
599 else:
698 else:
600 data = numpy.abs(avgcoherenceComplex)
699 data = numpy.abs(avgcoherenceComplex)
601
700
602 z.append(data)
701 z.append(data)
603
702
604 return numpy.array(z)
703 return numpy.array(z)
605
704
606 def setValue(self, value):
705 def setValue(self, value):
607
706
608 print("This property should not be initialized")
707 print("This property should not be initialized")
609
708
610 return
709 return
611
710
612 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
711 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
613
712
614
713
615 class SpectraHeis(Spectra):
714 class SpectraHeis(Spectra):
616
715
617 def __init__(self):
716 def __init__(self):
618
717
619 self.radarControllerHeaderObj = RadarControllerHeader()
718 self.radarControllerHeaderObj = RadarControllerHeader()
620 self.systemHeaderObj = SystemHeader()
719 self.systemHeaderObj = SystemHeader()
621 self.type = "SpectraHeis"
720 self.type = "SpectraHeis"
622 self.nProfiles = None
721 self.nProfiles = None
623 self.heightList = None
722 self.heightList = None
624 self.channelList = None
723 self.channelList = None
625 self.flagNoData = True
724 self.flagNoData = True
626 self.flagDiscontinuousBlock = False
725 self.flagDiscontinuousBlock = False
627 self.utctime = None
726 self.utctime = None
628 self.blocksize = None
727 self.blocksize = None
629 self.profileIndex = 0
728 self.profileIndex = 0
630 self.nCohInt = 1
729 self.nCohInt = 1
631 self.nIncohInt = 1
730 self.nIncohInt = 1
632
731
633 @property
732 @property
634 def normFactor(self):
733 def normFactor(self):
635 pwcode = 1
734 pwcode = 1
636 if self.flagDecodeData:
735 if self.flagDecodeData:
637 pwcode = numpy.sum(self.code[0]**2)
736 pwcode = numpy.sum(self.code[0]**2)
638
737
639 normFactor = self.nIncohInt * self.nCohInt * pwcode
738 normFactor = self.nIncohInt * self.nCohInt * pwcode
640
739
641 return normFactor
740 return normFactor
642
741
643 @property
742 @property
644 def timeInterval(self):
743 def timeInterval(self):
645
744
646 return self.ippSeconds * self.nCohInt * self.nIncohInt
745 return self.ippSeconds * self.nCohInt * self.nIncohInt
647
746
648
747
649 class Fits(JROData):
748 class Fits(JROData):
650
749
651 def __init__(self):
750 def __init__(self):
652
751
653 self.type = "Fits"
752 self.type = "Fits"
654 self.nProfiles = None
753 self.nProfiles = None
655 self.heightList = None
754 self.heightList = None
656 self.channelList = None
755 self.channelList = None
657 self.flagNoData = True
756 self.flagNoData = True
658 self.utctime = None
757 self.utctime = None
659 self.nCohInt = 1
758 self.nCohInt = 1
660 self.nIncohInt = 1
759 self.nIncohInt = 1
661 self.useLocalTime = True
760 self.useLocalTime = True
662 self.profileIndex = 0
761 self.profileIndex = 0
663 self.timeZone = 0
762 self.timeZone = 0
664
763
665 def getTimeRange(self):
764 def getTimeRange(self):
666
765
667 datatime = []
766 datatime = []
668
767
669 datatime.append(self.ltctime)
768 datatime.append(self.ltctime)
670 datatime.append(self.ltctime + self.timeInterval)
769 datatime.append(self.ltctime + self.timeInterval)
671
770
672 datatime = numpy.array(datatime)
771 datatime = numpy.array(datatime)
673
772
674 return datatime
773 return datatime
675
774
676 def getChannelIndexList(self):
775 def getChannelIndexList(self):
677
776
678 return list(range(self.nChannels))
777 return list(range(self.nChannels))
679
778
680 def getNoise(self, type=1):
779 def getNoise(self, type=1):
681
780
682
781
683 if type == 1:
782 if type == 1:
684 noise = self.getNoisebyHildebrand()
783 noise = self.getNoisebyHildebrand()
685
784
686 if type == 2:
785 if type == 2:
687 noise = self.getNoisebySort()
786 noise = self.getNoisebySort()
688
787
689 if type == 3:
788 if type == 3:
690 noise = self.getNoisebyWindow()
789 noise = self.getNoisebyWindow()
691
790
692 return noise
791 return noise
693
792
694 @property
793 @property
695 def timeInterval(self):
794 def timeInterval(self):
696
795
697 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
796 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
698
797
699 return timeInterval
798 return timeInterval
700
799
701 @property
800 @property
702 def ippSeconds(self):
801 def ippSeconds(self):
703 '''
802 '''
704 '''
803 '''
705 return self.ipp_sec
804 return self.ipp_sec
706
805
707 noise = property(getNoise, "I'm the 'nHeights' property.")
806 noise = property(getNoise, "I'm the 'nHeights' property.")
708
807
709
808
710 class Correlation(JROData):
809 class Correlation(JROData):
711
810
712 def __init__(self):
811 def __init__(self):
713 '''
812 '''
714 Constructor
813 Constructor
715 '''
814 '''
716 self.radarControllerHeaderObj = RadarControllerHeader()
815 self.radarControllerHeaderObj = RadarControllerHeader()
717 self.systemHeaderObj = SystemHeader()
816 self.systemHeaderObj = SystemHeader()
718 self.type = "Correlation"
817 self.type = "Correlation"
719 self.data = None
818 self.data = None
720 self.dtype = None
819 self.dtype = None
721 self.nProfiles = None
820 self.nProfiles = None
722 self.heightList = None
821 self.heightList = None
723 self.channelList = None
822 self.channelList = None
724 self.flagNoData = True
823 self.flagNoData = True
725 self.flagDiscontinuousBlock = False
824 self.flagDiscontinuousBlock = False
726 self.utctime = None
825 self.utctime = None
727 self.timeZone = 0
826 self.timeZone = 0
728 self.dstFlag = None
827 self.dstFlag = None
729 self.errorCount = None
828 self.errorCount = None
730 self.blocksize = None
829 self.blocksize = None
731 self.flagDecodeData = False # asumo q la data no esta decodificada
830 self.flagDecodeData = False # asumo q la data no esta decodificada
732 self.flagDeflipData = False # asumo q la data no esta sin flip
831 self.flagDeflipData = False # asumo q la data no esta sin flip
733 self.pairsList = None
832 self.pairsList = None
734 self.nPoints = None
833 self.nPoints = None
735
834
736 def getPairsList(self):
835 def getPairsList(self):
737
836
738 return self.pairsList
837 return self.pairsList
739
838
740 def getNoise(self, mode=2):
839 def getNoise(self, mode=2):
741
840
742 indR = numpy.where(self.lagR == 0)[0][0]
841 indR = numpy.where(self.lagR == 0)[0][0]
743 indT = numpy.where(self.lagT == 0)[0][0]
842 indT = numpy.where(self.lagT == 0)[0][0]
744
843
745 jspectra0 = self.data_corr[:, :, indR, :]
844 jspectra0 = self.data_corr[:, :, indR, :]
746 jspectra = copy.copy(jspectra0)
845 jspectra = copy.copy(jspectra0)
747
846
748 num_chan = jspectra.shape[0]
847 num_chan = jspectra.shape[0]
749 num_hei = jspectra.shape[2]
848 num_hei = jspectra.shape[2]
750
849
751 freq_dc = jspectra.shape[1] / 2
850 freq_dc = jspectra.shape[1] / 2
752 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
851 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
753
852
754 if ind_vel[0] < 0:
853 if ind_vel[0] < 0:
755 ind_vel[list(range(0, 1))] = ind_vel[list(
854 ind_vel[list(range(0, 1))] = ind_vel[list(
756 range(0, 1))] + self.num_prof
855 range(0, 1))] + self.num_prof
757
856
758 if mode == 1:
857 if mode == 1:
759 jspectra[:, freq_dc, :] = (
858 jspectra[:, freq_dc, :] = (
760 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
859 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
761
860
762 if mode == 2:
861 if mode == 2:
763
862
764 vel = numpy.array([-2, -1, 1, 2])
863 vel = numpy.array([-2, -1, 1, 2])
765 xx = numpy.zeros([4, 4])
864 xx = numpy.zeros([4, 4])
766
865
767 for fil in range(4):
866 for fil in range(4):
768 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
867 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
769
868
770 xx_inv = numpy.linalg.inv(xx)
869 xx_inv = numpy.linalg.inv(xx)
771 xx_aux = xx_inv[0, :]
870 xx_aux = xx_inv[0, :]
772
871
773 for ich in range(num_chan):
872 for ich in range(num_chan):
774 yy = jspectra[ich, ind_vel, :]
873 yy = jspectra[ich, ind_vel, :]
775 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
874 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
776
875
777 junkid = jspectra[ich, freq_dc, :] <= 0
876 junkid = jspectra[ich, freq_dc, :] <= 0
778 cjunkid = sum(junkid)
877 cjunkid = sum(junkid)
779
878
780 if cjunkid.any():
879 if cjunkid.any():
781 jspectra[ich, freq_dc, junkid.nonzero()] = (
880 jspectra[ich, freq_dc, junkid.nonzero()] = (
782 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
881 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
783
882
784 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
883 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
785
884
786 return noise
885 return noise
787
886
788 @property
887 @property
789 def timeInterval(self):
888 def timeInterval(self):
790
889
791 return self.ippSeconds * self.nCohInt * self.nProfiles
890 return self.ippSeconds * self.nCohInt * self.nProfiles
792
891
793 def splitFunctions(self):
892 def splitFunctions(self):
794
893
795 pairsList = self.pairsList
894 pairsList = self.pairsList
796 ccf_pairs = []
895 ccf_pairs = []
797 acf_pairs = []
896 acf_pairs = []
798 ccf_ind = []
897 ccf_ind = []
799 acf_ind = []
898 acf_ind = []
800 for l in range(len(pairsList)):
899 for l in range(len(pairsList)):
801 chan0 = pairsList[l][0]
900 chan0 = pairsList[l][0]
802 chan1 = pairsList[l][1]
901 chan1 = pairsList[l][1]
803
902
804 # Obteniendo pares de Autocorrelacion
903 # Obteniendo pares de Autocorrelacion
805 if chan0 == chan1:
904 if chan0 == chan1:
806 acf_pairs.append(chan0)
905 acf_pairs.append(chan0)
807 acf_ind.append(l)
906 acf_ind.append(l)
808 else:
907 else:
809 ccf_pairs.append(pairsList[l])
908 ccf_pairs.append(pairsList[l])
810 ccf_ind.append(l)
909 ccf_ind.append(l)
811
910
812 data_acf = self.data_cf[acf_ind]
911 data_acf = self.data_cf[acf_ind]
813 data_ccf = self.data_cf[ccf_ind]
912 data_ccf = self.data_cf[ccf_ind]
814
913
815 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
914 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
816
915
817 @property
916 @property
818 def normFactor(self):
917 def normFactor(self):
819 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
918 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
820 acf_pairs = numpy.array(acf_pairs)
919 acf_pairs = numpy.array(acf_pairs)
821 normFactor = numpy.zeros((self.nPairs, self.nHeights))
920 normFactor = numpy.zeros((self.nPairs, self.nHeights))
822
921
823 for p in range(self.nPairs):
922 for p in range(self.nPairs):
824 pair = self.pairsList[p]
923 pair = self.pairsList[p]
825
924
826 ch0 = pair[0]
925 ch0 = pair[0]
827 ch1 = pair[1]
926 ch1 = pair[1]
828
927
829 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
928 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
830 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
929 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
831 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
930 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
832
931
833 return normFactor
932 return normFactor
834
933
835
934
836 class Parameters(Spectra):
935 class Parameters(Spectra):
837
936
838 groupList = None # List of Pairs, Groups, etc
937 groupList = None # List of Pairs, Groups, etc
839 data_param = None # Parameters obtained
938 data_param = None # Parameters obtained
840 data_pre = None # Data Pre Parametrization
939 data_pre = None # Data Pre Parametrization
841 data_SNR = None # Signal to Noise Ratio
940 data_SNR = None # Signal to Noise Ratio
842 abscissaList = None # Abscissa, can be velocities, lags or time
941 abscissaList = None # Abscissa, can be velocities, lags or time
843 utctimeInit = None # Initial UTC time
942 utctimeInit = None # Initial UTC time
844 paramInterval = None # Time interval to calculate Parameters in seconds
943 paramInterval = None # Time interval to calculate Parameters in seconds
845 useLocalTime = True
944 useLocalTime = True
846 # Fitting
945 # Fitting
847 data_error = None # Error of the estimation
946 data_error = None # Error of the estimation
848 constants = None
947 constants = None
849 library = None
948 library = None
850 # Output signal
949 # Output signal
851 outputInterval = None # Time interval to calculate output signal in seconds
950 outputInterval = None # Time interval to calculate output signal in seconds
852 data_output = None # Out signal
951 data_output = None # Out signal
853 nAvg = None
952 nAvg = None
854 noise_estimation = None
953 noise_estimation = None
855 GauSPC = None # Fit gaussian SPC
954 GauSPC = None # Fit gaussian SPC
856
955
857 def __init__(self):
956 def __init__(self):
858 '''
957 '''
859 Constructor
958 Constructor
860 '''
959 '''
861 self.radarControllerHeaderObj = RadarControllerHeader()
960 self.radarControllerHeaderObj = RadarControllerHeader()
862 self.systemHeaderObj = SystemHeader()
961 self.systemHeaderObj = SystemHeader()
863 self.type = "Parameters"
962 self.type = "Parameters"
864 self.timeZone = 0
963 self.timeZone = 0
865
964
866 def getTimeRange1(self, interval):
965 def getTimeRange1(self, interval):
867
966
868 datatime = []
967 datatime = []
869
968
870 if self.useLocalTime:
969 if self.useLocalTime:
871 time1 = self.utctimeInit - self.timeZone * 60
970 time1 = self.utctimeInit - self.timeZone * 60
872 else:
971 else:
873 time1 = self.utctimeInit
972 time1 = self.utctimeInit
874
973
875 datatime.append(time1)
974 datatime.append(time1)
876 datatime.append(time1 + interval)
975 datatime.append(time1 + interval)
877 datatime = numpy.array(datatime)
976 datatime = numpy.array(datatime)
878
977
879 return datatime
978 return datatime
880
979
881 @property
980 @property
882 def timeInterval(self):
981 def timeInterval(self):
883
982
884 if hasattr(self, 'timeInterval1'):
983 if hasattr(self, 'timeInterval1'):
885 return self.timeInterval1
984 return self.timeInterval1
886 else:
985 else:
887 return self.paramInterval
986 return self.paramInterval
888
987
988
889 def setValue(self, value):
989 def setValue(self, value):
890
990
891 print("This property should not be initialized")
991 print("This property should not be initialized")
892
992
893 return
993 return
894
994
895 def getNoise(self):
995 def getNoise(self):
896
996
897 return self.spc_noise
997 return self.spc_noise
898
998
899 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
999 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
900
1000
901
1001
902 class PlotterData(object):
1002 class PlotterData(object):
903 '''
1003 '''
904 Object to hold data to be plotted
1004 Object to hold data to be plotted
905 '''
1005 '''
906
1006
907 MAXNUMX = 200
1007 MAXNUMX = 200
908 MAXNUMY = 200
1008 MAXNUMY = 200
909
1009
910 def __init__(self, code, throttle_value, exp_code, localtime=True, buffering=True, snr=False):
1010 def __init__(self, code, throttle_value, exp_code, localtime=True, buffering=True, snr=False):
911
1011
912 self.key = code
1012 self.key = code
913 self.throttle = throttle_value
1013 self.throttle = throttle_value
914 self.exp_code = exp_code
1014 self.exp_code = exp_code
915 self.buffering = buffering
1015 self.buffering = buffering
916 self.ready = False
1016 self.ready = False
917 self.flagNoData = False
1017 self.flagNoData = False
918 self.localtime = localtime
1018 self.localtime = localtime
919 self.data = {}
1019 self.data = {}
920 self.meta = {}
1020 self.meta = {}
921 self.__heights = []
1021 self.__heights = []
922
1022
923 if 'snr' in code:
1023 if 'snr' in code:
924 self.plottypes = ['snr']
1024 self.plottypes = ['snr']
925 elif code == 'spc':
1025 elif code == 'spc':
926 self.plottypes = ['spc', 'noise', 'rti']
1026 self.plottypes = ['spc', 'noise', 'rti']
927 elif code == 'cspc':
1027 elif code == 'cspc':
928 self.plottypes = ['cspc', 'spc', 'noise', 'rti']
1028 self.plottypes = ['cspc', 'spc', 'noise', 'rti']
929 elif code == 'rti':
1029 elif code == 'rti':
930 self.plottypes = ['noise', 'rti']
1030 self.plottypes = ['noise', 'rti']
1031 elif code == 'crossprod':
1032 self.plottypes = ['crossprod', 'kay']
1033 elif code == 'spectrogram':
1034 self.plottypes = ['spc', 'spectrogram']
931 else:
1035 else:
932 self.plottypes = [code]
1036 self.plottypes = [code]
933
1037
934 if 'snr' not in self.plottypes and snr:
1038 if 'snr' not in self.plottypes and snr:
935 self.plottypes.append('snr')
1039 self.plottypes.append('snr')
936
1040
937 for plot in self.plottypes:
1041 for plot in self.plottypes:
938 self.data[plot] = {}
1042 self.data[plot] = {}
939
1043
940 def __str__(self):
1044 def __str__(self):
941 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
1045 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
942 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
1046 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
943
1047
944 def __len__(self):
1048 def __len__(self):
945 return len(self.data[self.key])
1049 return len(self.data[self.key])
946
1050
947 def __getitem__(self, key):
1051 def __getitem__(self, key):
948
1052
949 if key not in self.data:
1053 if key not in self.data:
950 raise KeyError(log.error('Missing key: {}'.format(key)))
1054 raise KeyError(log.error('Missing key: {}'.format(key)))
951 if 'spc' in key or not self.buffering:
1055 if 'spc' in key or not self.buffering:
952 ret = self.data[key][self.tm]
1056 ret = self.data[key][self.tm]
953 elif 'scope' in key:
1057 elif 'scope' in key:
954 ret = numpy.array(self.data[key][float(self.tm)])
1058 ret = numpy.array(self.data[key][float(self.tm)])
955 else:
1059 else:
956 ret = numpy.array([self.data[key][x] for x in self.times])
1060 ret = numpy.array([self.data[key][x] for x in self.times])
957 if ret.ndim > 1:
1061 if ret.ndim > 1:
958 ret = numpy.swapaxes(ret, 0, 1)
1062 ret = numpy.swapaxes(ret, 0, 1)
959 return ret
1063 return ret
960
1064
961 def __contains__(self, key):
1065 def __contains__(self, key):
962 return key in self.data
1066 return key in self.data
963
1067
964 def setup(self):
1068 def setup(self):
965 '''
1069 '''
966 Configure object
1070 Configure object
967 '''
1071 '''
968 self.type = ''
1072 self.type = ''
969 self.ready = False
1073 self.ready = False
970 del self.data
1074 del self.data
971 self.data = {}
1075 self.data = {}
972 self.__heights = []
1076 self.__heights = []
973 self.__all_heights = set()
1077 self.__all_heights = set()
974 for plot in self.plottypes:
1078 for plot in self.plottypes:
975 if 'snr' in plot:
1079 if 'snr' in plot:
976 plot = 'snr'
1080 plot = 'snr'
977 elif 'spc_moments' == plot:
1081 elif 'spc_moments' == plot:
978 plot = 'moments'
1082 plot = 'moments'
1083 elif 'spc_oblique' == plot:
1084 plot = 'oblique'
979 self.data[plot] = {}
1085 self.data[plot] = {}
980
1086
981 if 'spc' in self.data or 'rti' in self.data or 'cspc' in self.data or 'moments' in self.data:
1087 if 'spc' in self.data or 'rti' in self.data or 'cspc' in self.data or 'moments' in self.data or 'oblique' in self.data:
982 self.data['noise'] = {}
1088 self.data['noise'] = {}
983 self.data['rti'] = {}
1089 self.data['rti'] = {}
984 if 'noise' not in self.plottypes:
1090 if 'noise' not in self.plottypes:
985 self.plottypes.append('noise')
1091 self.plottypes.append('noise')
986 if 'rti' not in self.plottypes:
1092 if 'rti' not in self.plottypes:
987 self.plottypes.append('rti')
1093 self.plottypes.append('rti')
988
1094
989 def shape(self, key):
1095 def shape(self, key):
990 '''
1096 '''
991 Get the shape of the one-element data for the given key
1097 Get the shape of the one-element data for the given key
992 '''
1098 '''
993
1099
994 if len(self.data[key]):
1100 if len(self.data[key]):
995 if 'spc' in key or not self.buffering:
1101 if 'spc' in key or not self.buffering:
996 return self.data[key].shape
1102 return self.data[key].shape
997 return self.data[key][self.times[0]].shape
1103 return self.data[key][self.times[0]].shape
998 return (0,)
1104 return (0,)
999
1105
1000 def update(self, dataOut, tm):
1106 def update(self, dataOut, tm):
1001 '''
1107 '''
1002 Update data object with new dataOut
1108 Update data object with new dataOut
1003 '''
1109 '''
1004
1110
1005 self.profileIndex = dataOut.profileIndex
1111 self.profileIndex = dataOut.profileIndex
1006 self.tm = tm
1112 self.tm = tm
1007 self.type = dataOut.type
1113 self.type = dataOut.type
1008 self.parameters = getattr(dataOut, 'parameters', [])
1114 self.parameters = getattr(dataOut, 'parameters', [])
1009
1115
1010 if hasattr(dataOut, 'meta'):
1116 if hasattr(dataOut, 'meta'):
1011 self.meta.update(dataOut.meta)
1117 self.meta.update(dataOut.meta)
1012
1118
1013 if hasattr(dataOut, 'pairsList'):
1119 if hasattr(dataOut, 'pairsList'):
1014 self.pairs = dataOut.pairsList
1120 self.pairs = dataOut.pairsList
1015
1121
1016 self.interval = dataOut.timeInterval
1122 self.interval = dataOut.timeInterval
1017 if True in ['spc' in ptype for ptype in self.plottypes]:
1123 if True in ['spc' in ptype for ptype in self.plottypes]:
1018 self.xrange = (dataOut.getFreqRange(1)/1000.,
1124 self.xrange = (dataOut.getFreqRange(1)/1000.,
1019 dataOut.getAcfRange(1), dataOut.getVelRange(1))
1125 dataOut.getAcfRange(1), dataOut.getVelRange(1))
1020 self.__heights.append(dataOut.heightList)
1126 self.__heights.append(dataOut.heightList)
1021 self.__all_heights.update(dataOut.heightList)
1127 self.__all_heights.update(dataOut.heightList)
1022
1128
1129
1130
1023 for plot in self.plottypes:
1131 for plot in self.plottypes:
1024 if plot in ('spc', 'spc_moments', 'spc_cut'):
1132 if plot in ('spc', 'spc_moments', 'spc_cut', 'spc_oblique'):
1133
1134
1135 self.shift1 = dataOut.Oblique_params[0][1]
1136 self.shift2 = dataOut.Oblique_params[0][4]
1137 self.shift1_error = dataOut.Oblique_param_errors[0][1]
1138 self.shift2_error = dataOut.Oblique_param_errors[0][4]
1139
1025 z = dataOut.data_spc/dataOut.normFactor
1140 z = dataOut.data_spc/dataOut.normFactor
1141 #print(dataOut.normFactor)
1142 #print(z[0,3,15])
1143 #print("here")
1144 #print(dataOut.data_spc[0,0,0])
1145 #exit()
1026 buffer = 10*numpy.log10(z)
1146 buffer = 10*numpy.log10(z)
1027 if plot == 'cspc':
1147 if plot == 'cspc':
1028 buffer = (dataOut.data_spc, dataOut.data_cspc)
1148 buffer = (dataOut.data_spc, dataOut.data_cspc)
1149 self.nFactor=dataOut.normFactor
1029 if plot == 'noise':
1150 if plot == 'noise':
1030 buffer = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
1151 buffer = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
1031 if plot in ('rti', 'spcprofile'):
1152 if plot in ('rti', 'spcprofile'):
1032 buffer = dataOut.getPower()
1153 buffer = dataOut.getPower()
1154 #print(buffer[0,0])
1155 #exit()
1033 if plot == 'snr_db':
1156 if plot == 'snr_db':
1034 buffer = dataOut.data_SNR
1157 buffer = dataOut.data_SNR
1035 if plot == 'snr':
1158 if plot == 'snr':
1036 buffer = 10*numpy.log10(dataOut.data_SNR)
1159 buffer = 10*numpy.log10(dataOut.data_SNR)
1037 if plot == 'dop':
1160 if plot == 'dop':
1038 buffer = dataOut.data_DOP
1161 buffer = dataOut.data_DOP
1039 if plot == 'pow':
1162 if plot == 'pow':
1040 buffer = 10*numpy.log10(dataOut.data_POW)
1163 buffer = 10*numpy.log10(dataOut.data_POW)
1041 if plot == 'width':
1164 if plot == 'width':
1042 buffer = dataOut.data_WIDTH
1165 buffer = dataOut.data_WIDTH
1043 if plot == 'coh':
1166 if plot == 'coh':
1044 buffer = dataOut.getCoherence()
1167 buffer = dataOut.getCoherence()
1045 if plot == 'phase':
1168 if plot == 'phase':
1046 buffer = dataOut.getCoherence(phase=True)
1169 buffer = dataOut.getCoherence(phase=True)
1047 if plot == 'output':
1170 if plot == 'output':
1048 buffer = dataOut.data_output
1171 buffer = dataOut.data_output
1049 if plot == 'param':
1172 if plot == 'param':
1050 buffer = dataOut.data_param
1173 buffer = dataOut.data_param
1174 if plot == 'spectrogram':
1175 maxHei = 1350 #11
1176 #maxHei = 2500
1177 maxHei = 0
1178 #maxHei = 990 #12
1179 ###maxHei = 990
1180 indb = numpy.where(dataOut.heightList <= maxHei)
1181 hei = indb[0][-1]
1182 #hei = 19
1183 print(hei)
1184 #hei = 0
1185 factor = dataOut.nIncohInt
1186 #print(factor)
1187
1188 #exit(1)
1189 z = dataOut.data_spc[:,:,hei] / factor
1190
1191 #for j in range(z.shape[1]):
1192 #z[:,j] = z[:,j]/hildebrand_sekhon(z[], self.nCohInt)
1193
1194 ##z = z/hildebrand_sekhon(z, factor)
1195 noise = numpy.zeros(dataOut.nChannels)
1196 for i in range(dataOut.nChannels):
1197 #daux = numpy.sort(pair0[i,:,:],axis= None)
1198 noise[i]=hildebrand_sekhon( z[i,:] ,dataOut.nIncohInt)
1199 #for j in range(z.shape[1]):
1200 #z[:,j] = z[:,j]/noise
1201
1202 #print(z.shape[1])
1203 norm_factor = numpy.copy(z[:,int(z.shape[1]/2)])#/z[:,int(z.shape[1]/2)])*8000
1204 #print(norm_factor)
1205 #print(z[0,315:325])
1206 #norm_factor = norm_factor.reshape((z.shape[0],z.shape[1]))
1207 #print(norm_factor)
1208 #exit(1)
1209 #print(z.shape[1])
1210
1211 #for j in range(z.shape[1]):
1212 #z[:,j] = z[:,j]/norm_factor
1213
1214 #print(z[0,315:325])
1215 #exit(1)
1216
1217 #z = numpy.mean(dataOut.data_spc[:,:,:],axis=2) / factor
1218 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1219 #avg = numpy.average(z, axis=1)
1220 #print((dataOut.data_spc.shape))
1221 #exit(1)
1222 self.hei = hei
1223 self.heightList = dataOut.heightList
1224 self.DH = (dataOut.heightList[1] - dataOut.heightList[0])/dataOut.step
1225 self.nProfiles = dataOut.nProfiles
1226 #print(dataOut.heightList)
1227
1228
1229 buffer = 10 * numpy.log10(z)
1230
1231
1232 ###buffer = z
1233 import matplotlib.pyplot as plt
1234 fig, axes = plt.subplots(figsize=(14, 10))
1235 x = numpy.linspace(0,20,numpy.shape(buffer)[1])
1236 x = numpy.fft.fftfreq(numpy.shape(buffer)[1],0.00001)
1237 x = numpy.fft.fftshift(x)
1238
1239 plt.plot(x,buffer[0,:])
1240 axes = plt.gca()
1241 axes.set_xlim([-10000,10000])
1242
1243 #axes.set_xlim([0,30000])
1244 #axes.set_ylim([-100,0.0025*1e10])
1245 plt.show()
1246 import time
1247 #time.sleep(20)
1248 #exit(1)
1249
1250
1251
1252 #if dataOut.profileIndex
1253
1254 if plot == 'xmit':
1255 y_1=numpy.arctan2(dataOut.output_LP[:,0,2].imag,dataOut.output_LP[:,0,2].real)* 180 / (numpy.pi*10)
1256 y_2=numpy.abs(dataOut.output_LP[:,0,2])
1257 norm=numpy.max(y_2)
1258 norm=max(norm,0.1)
1259 y_2=y_2/norm
1260
1261 buffer = numpy.vstack((y_1,y_2))
1262 self.NLAG = dataOut.NLAG
1263
1264 if plot == 'crossprod':
1265 buffer = dataOut.crossprods
1266 self.NDP = dataOut.NDP
1267
1268 if plot == 'crossprodlp':
1269 buffer = 10*numpy.log10(numpy.abs(dataOut.output_LP))
1270 self.NRANGE = dataOut.NRANGE
1271 self.NLAG = dataOut.NLAG
1272
1273
1274 if plot == 'noisedp':
1275 buffer = 10*numpy.log10(dataOut.noise_final)
1276 #print(buffer)
1277
1278 if plot == 'FaradayAngle':
1279 buffer = numpy.degrees(dataOut.phi)
1280 #print(buffer)
1281
1282 if plot == 'RTIDP':
1283 buffer = dataOut.data_for_RTI_DP
1284 self.NDP = dataOut.NDP
1285
1286 if plot == 'RTILP':
1287 buffer = dataOut.data_for_RTI_LP
1288 self.NRANGE = dataOut.NRANGE
1289
1290
1291 if plot == 'denrti':
1292 buffer = dataOut.DensityFinal
1293
1294
1295 if plot == 'denrtiLP':
1296
1297 #buffer = numpy.reshape(numpy.concatenate((dataOut.ph2[:dataOut.cut],dataOut.ne[dataOut.cut:dataOut.NACF])),(1,-1))
1298 buffer = dataOut.DensityFinal
1299 #self.flagDataAsBlock = dataOut.flagDataAsBlock
1300 #self.NDP = dataOut.NDP
1301 if plot == 'den':
1302 buffer = dataOut.ph2[:dataOut.NSHTS]
1303 self.dphi=dataOut.dphi[:dataOut.NSHTS]
1304 self.sdp2=dataOut.sdp2[:dataOut.NSHTS]
1305 self.sdn1=dataOut.sdn1[:dataOut.NSHTS]#/self.dphi
1306 self.NSHTS=dataOut.NSHTS
1307 '''
1308 flag1=False
1309 flag0=True
1310 for i in range(12,dataOut.NSHTS):
1311 print("H: ",i*15)
1312 print(abs((dataOut.sdn1[i]/(dataOut.dphi[i]**2))*100))
1313 if flag0:
1314 if abs((dataOut.sdn1[i]/dataOut.dphi[i]))<0.0005*abs(dataOut.dphi[i]):
1315 print("***************************** FIRST: ",(i)*15,"*****************************")
1316 flag1=True
1317 flag0=False
1318 #pass
1319 #print("****************************************GOOD****************************************")
1320 #else:
1321 #print("****************************************",(i-1)*15,"****************************************")
1322 #break
1323 if flag1:
1324 if abs((dataOut.sdn1[i]/dataOut.dphi[i]))>0.0005*abs(dataOut.dphi[i]):
1325 print("***************************** LAST: ",(i-1)*15,"*****************************")
1326 break
1327 #print("H: ",i*15)
1328 #print(dataOut.sdn1[i])
1329 '''
1330 if plot == 'denLP':
1331 buffer = dataOut.ph2[:dataOut.NSHTS]
1332 self.dphi=dataOut.dphi[:dataOut.NSHTS]
1333 self.sdp2=dataOut.sdp2[:dataOut.NSHTS]
1334 self.ne=dataOut.ne[:dataOut.NACF]
1335 self.ene=dataOut.ene[:dataOut.NACF]*dataOut.ne[:dataOut.NACF]*0.434
1336 #self.ene=10**dataOut.ene[:dataOut.NACF]
1337 self.NSHTS=dataOut.NSHTS
1338 self.cut=dataOut.cut
1339
1340 if plot == 'ETemp':
1341 #buffer = dataOut.ElecTempClean
1342 buffer = dataOut.ElecTempFinal
1343 if plot == 'ITemp':
1344 #buffer = dataOut.IonTempClean
1345 buffer = dataOut.IonTempFinal
1346 if plot == 'ETempLP':
1347 #buffer = dataOut.IonTempClean
1348 #buffer = numpy.reshape(numpy.concatenate((dataOut.te2[:dataOut.cut],dataOut.te[dataOut.cut:])),(1,-1))
1349 buffer = dataOut.ElecTempFinal
1350 #print(buffer)
1351 if plot == 'ITempLP':
1352 #buffer = dataOut.IonTempClean
1353 #buffer = numpy.reshape(numpy.concatenate((dataOut.ti2[:dataOut.cut],dataOut.ti[dataOut.cut:])),(1,-1))
1354 buffer = dataOut.IonTempFinal
1355
1356 if plot == 'HFracLP':
1357 #buffer = dataOut.IonTempClean
1358 #buffer = numpy.reshape(numpy.concatenate((dataOut.phy2[:dataOut.cut],dataOut.ph[dataOut.cut:])),(1,-1))
1359 buffer = dataOut.PhyFinal
1360 if plot == 'HeFracLP':
1361 #buffer = dataOut.IonTempClean
1362 #nan_array=numpy.empty((dataOut.cut))
1363 #nan_array[:]=numpy.nan
1364 #buffer = numpy.reshape(numpy.concatenate((nan_array,dataOut.phe[dataOut.cut:])),(1,-1))
1365 buffer = dataOut.PheFinal
1366
1367
1368
1369
1370
1371 if plot =='acfs':
1372 buffer = dataOut.acfs_to_plot
1373 self.acfs_error_to_plot=dataOut.acfs_error_to_plot
1374 self.lags_to_plot=dataOut.lags_to_plot
1375 self.x_igcej_to_plot=dataOut.x_igcej_to_plot
1376 self.x_ibad_to_plot=dataOut.x_ibad_to_plot
1377 self.y_igcej_to_plot=dataOut.y_igcej_to_plot
1378 self.y_ibad_to_plot=dataOut.y_ibad_to_plot
1379 self.NSHTS = dataOut.NSHTS
1380 self.DPL = dataOut.DPL
1381 if plot =='acfs_LP':
1382
1383 aux=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
1384 self.errors=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
1385 self.lags_LP_to_plot=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
1386 '''
1387 for i in range(dataOut.NACF):
1388 for j in range(dataOut.IBITS):
1389 aux[i,j]=dataOut.fit_array_real[i,j]/dataOut.fit_array_real[i,0]
1390 aux[i,j]=max(min(aux[i,j],1.0),-1.0)*dataOut.DH+dataOut.heightList[i]
1391 '''
1392 for i in range(dataOut.NACF):
1393 for j in range(dataOut.IBITS):
1394 if numpy.abs(dataOut.errors[j,i]/dataOut.output_LP_integrated.real[0,i,0])<1.0:
1395 aux[i,j]=dataOut.output_LP_integrated.real[j,i,0]/dataOut.output_LP_integrated.real[0,i,0]
1396 aux[i,j]=max(min(aux[i,j],1.0),-1.0)*dataOut.DH+dataOut.heightList[i]
1397 self.lags_LP_to_plot[i,j]=dataOut.lags_LP[j]
1398 self.errors[i,j]=dataOut.errors[j,i]/dataOut.output_LP_integrated.real[0,i,0]*dataOut.DH
1399 else:
1400 aux[i,j]=numpy.nan
1401 self.lags_LP_to_plot[i,j]=numpy.nan
1402 self.errors[i,j]=numpy.nan
1403
1404
1405
1406 buffer = aux
1407
1408 #self.lags_LP_to_plot=dataOut.lags_LP
1409
1410 self.NACF = dataOut.NACF
1411 self.NLAG = dataOut.NLAG
1412
1413 if plot == 'tempsDP':
1414
1415 buffer = dataOut.te2
1416 self.ete2 = dataOut.ete2
1417 self.ti2 = dataOut.ti2
1418 self.eti2 = dataOut.eti2
1419
1420 self.NSHTS = dataOut.NSHTS
1421
1422 if plot == 'temps_LP':
1423
1424 buffer = numpy.concatenate((dataOut.te2[:dataOut.cut],dataOut.te[dataOut.cut:]))
1425 self.ete = numpy.concatenate((dataOut.ete2[:dataOut.cut],dataOut.ete[dataOut.cut:]))
1426 self.ti = numpy.concatenate((dataOut.ti2[:dataOut.cut],dataOut.ti[dataOut.cut:]))
1427 self.eti = numpy.concatenate((dataOut.eti2[:dataOut.cut],dataOut.eti[dataOut.cut:]))
1428
1429 self.NACF = dataOut.NACF
1430
1431
1432 if plot == 'fracs_LP':
1433
1434 aux_nan=numpy.zeros(dataOut.cut,'float32')
1435 aux_nan[:]=numpy.nan
1436 buffer = numpy.concatenate((aux_nan,dataOut.ph[dataOut.cut:]))
1437 self.eph = numpy.concatenate((aux_nan,dataOut.eph[dataOut.cut:]))
1438 self.phe = dataOut.phe[dataOut.cut:]
1439 self.ephe = dataOut.ephe[dataOut.cut:]
1440
1441 self.NACF = dataOut.NACF
1442 self.cut = dataOut.cut
1443
1444
1051 if plot == 'scope':
1445 if plot == 'scope':
1052 buffer = dataOut.data
1446 buffer = dataOut.data
1053 self.flagDataAsBlock = dataOut.flagDataAsBlock
1447 self.flagDataAsBlock = dataOut.flagDataAsBlock
1054 self.nProfiles = dataOut.nProfiles
1448 self.nProfiles = dataOut.nProfiles
1055 if plot == 'pp_power':
1449 if plot == 'pp_power':
1056 buffer = dataOut.dataPP_POWER
1450 buffer = dataOut.dataPP_POWER
1057 self.flagDataAsBlock = dataOut.flagDataAsBlock
1451 self.flagDataAsBlock = dataOut.flagDataAsBlock
1058 self.nProfiles = dataOut.nProfiles
1452 self.nProfiles = dataOut.nProfiles
1059 if plot == 'pp_signal':
1453 if plot == 'pp_signal':
1060 buffer = dataOut.dataPP_POW
1454 buffer = dataOut.dataPP_POW
1061 self.flagDataAsBlock = dataOut.flagDataAsBlock
1455 self.flagDataAsBlock = dataOut.flagDataAsBlock
1062 self.nProfiles = dataOut.nProfiles
1456 self.nProfiles = dataOut.nProfiles
1063 if plot == 'pp_velocity':
1457 if plot == 'pp_velocity':
1064 buffer = dataOut.dataPP_DOP
1458 buffer = dataOut.dataPP_DOP
1065 self.flagDataAsBlock = dataOut.flagDataAsBlock
1459 self.flagDataAsBlock = dataOut.flagDataAsBlock
1066 self.nProfiles = dataOut.nProfiles
1460 self.nProfiles = dataOut.nProfiles
1067 if plot == 'pp_specwidth':
1461 if plot == 'pp_specwidth':
1068 buffer = dataOut.dataPP_WIDTH
1462 buffer = dataOut.dataPP_WIDTH
1069 self.flagDataAsBlock = dataOut.flagDataAsBlock
1463 self.flagDataAsBlock = dataOut.flagDataAsBlock
1070 self.nProfiles = dataOut.nProfiles
1464 self.nProfiles = dataOut.nProfiles
1071
1465
1072 if plot == 'spc':
1466 if plot == 'spc':
1073 self.data['spc'][tm] = buffer
1467 self.data['spc'][tm] = buffer
1074 elif plot == 'cspc':
1468 elif plot == 'cspc':
1075 self.data['cspc'][tm] = buffer
1469 self.data['cspc'][tm] = buffer
1076 elif plot == 'spc_moments':
1470 elif plot == 'spc_moments':
1077 self.data['spc'][tm] = buffer
1471 self.data['spc'][tm] = buffer
1078 self.data['moments'][tm] = dataOut.moments
1472 self.data['moments'][tm] = dataOut.moments
1473 elif plot == 'spc_oblique':
1474 self.data['spc'][tm] = buffer
1475 self.data['shift1'][tm] = dataOut.Oblique_params[0]
1476 self.data['shift2'][tm] = dataOut.Oblique_params[3]
1079 else:
1477 else:
1080 if self.buffering:
1478 if self.buffering:
1081 self.data[plot][tm] = buffer
1479 self.data[plot][tm] = buffer
1082 else:
1480 else:
1083 self.data[plot][tm] = buffer
1481 self.data[plot][tm] = buffer
1084
1482
1085 if dataOut.channelList is None:
1483 if dataOut.channelList is None:
1086 self.channels = range(buffer.shape[0])
1484 self.channels = range(buffer.shape[0])
1087 else:
1485 else:
1088 self.channels = dataOut.channelList
1486 self.channels = dataOut.channelList
1089
1487
1090 if buffer is None:
1488 if buffer is None:
1091 self.flagNoData = True
1489 self.flagNoData = True
1092 raise schainpy.admin.SchainWarning('Attribute data_{} is empty'.format(self.key))
1490 raise schainpy.admin.SchainWarning('Attribute data_{} is empty'.format(self.key))
1093
1491
1094 def normalize_heights(self):
1492 def normalize_heights(self):
1095 '''
1493 '''
1096 Ensure same-dimension of the data for different heighList
1494 Ensure same-dimension of the data for different heighList
1097 '''
1495 '''
1098
1496
1099 H = numpy.array(list(self.__all_heights))
1497 H = numpy.array(list(self.__all_heights))
1100 H.sort()
1498 H.sort()
1101 for key in self.data:
1499 for key in self.data:
1102 shape = self.shape(key)[:-1] + H.shape
1500 shape = self.shape(key)[:-1] + H.shape
1103 for tm, obj in list(self.data[key].items()):
1501 for tm, obj in list(self.data[key].items()):
1104 h = self.__heights[self.times.tolist().index(tm)]
1502 h = self.__heights[self.times.tolist().index(tm)]
1105 if H.size == h.size:
1503 if H.size == h.size:
1106 continue
1504 continue
1107 index = numpy.where(numpy.in1d(H, h))[0]
1505 index = numpy.where(numpy.in1d(H, h))[0]
1108 dummy = numpy.zeros(shape) + numpy.nan
1506 dummy = numpy.zeros(shape) + numpy.nan
1109 if len(shape) == 2:
1507 if len(shape) == 2:
1110 dummy[:, index] = obj
1508 dummy[:, index] = obj
1111 else:
1509 else:
1112 dummy[index] = obj
1510 dummy[index] = obj
1113 self.data[key][tm] = dummy
1511 self.data[key][tm] = dummy
1114
1512
1115 self.__heights = [H for tm in self.times]
1513 self.__heights = [H for tm in self.times]
1116
1514
1117 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1515 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1118 '''
1516 '''
1119 Convert data to json
1517 Convert data to json
1120 '''
1518 '''
1121
1519
1122 dy = int(self.heights.size/self.MAXNUMY) + 1
1520 dy = int(self.heights.size/self.MAXNUMY) + 1
1123 if self.key in ('spc', 'cspc'):
1521 if self.key in ('spc', 'cspc'):
1124 dx = int(self.data[self.key][tm].shape[1]/self.MAXNUMX) + 1
1522 dx = int(self.data[self.key][tm].shape[1]/self.MAXNUMX) + 1
1125 data = self.roundFloats(
1523 data = self.roundFloats(
1126 self.data[self.key][tm][::, ::dx, ::dy].tolist())
1524 self.data[self.key][tm][::, ::dx, ::dy].tolist())
1127 else:
1525 else:
1128 if self.key is 'noise':
1526 if self.key is 'noise':
1129 data = [[x] for x in self.roundFloats(self.data[self.key][tm].tolist())]
1527 data = [[x] for x in self.roundFloats(self.data[self.key][tm].tolist())]
1130 else:
1528 else:
1131 data = self.roundFloats(self.data[self.key][tm][::, ::dy].tolist())
1529 data = self.roundFloats(self.data[self.key][tm][::, ::dy].tolist())
1132
1530
1133 meta = {}
1531 meta = {}
1134 ret = {
1532 ret = {
1135 'plot': plot_name,
1533 'plot': plot_name,
1136 'code': self.exp_code,
1534 'code': self.exp_code,
1137 'time': float(tm),
1535 'time': float(tm),
1138 'data': data,
1536 'data': data,
1139 }
1537 }
1140 meta['type'] = plot_type
1538 meta['type'] = plot_type
1141 meta['interval'] = float(self.interval)
1539 meta['interval'] = float(self.interval)
1142 meta['localtime'] = self.localtime
1540 meta['localtime'] = self.localtime
1143 meta['yrange'] = self.roundFloats(self.heights[::dy].tolist())
1541 meta['yrange'] = self.roundFloats(self.heights[::dy].tolist())
1542
1144 if 'spc' in self.data or 'cspc' in self.data:
1543 if 'spc' in self.data or 'cspc' in self.data:
1145 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1544 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1146 else:
1545 else:
1147 meta['xrange'] = []
1546 meta['xrange'] = []
1148
1547
1149 meta.update(self.meta)
1548 meta.update(self.meta)
1150 ret['metadata'] = meta
1549 ret['metadata'] = meta
1151 return json.dumps(ret)
1550 return json.dumps(ret)
1152
1551
1153 @property
1552 @property
1154 def times(self):
1553 def times(self):
1155 '''
1554 '''
1156 Return the list of times of the current data
1555 Return the list of times of the current data
1157 '''
1556 '''
1158
1557
1159 ret = numpy.array([t for t in self.data[self.key]])
1558 ret = numpy.array([t for t in self.data[self.key]])
1160 if self:
1559 if self:
1161 ret.sort()
1560 ret.sort()
1162 return ret
1561 return ret
1163
1562
1164 @property
1563 @property
1165 def min_time(self):
1564 def min_time(self):
1166 '''
1565 '''
1167 Return the minimun time value
1566 Return the minimun time value
1168 '''
1567 '''
1169
1568
1170 return self.times[0]
1569 return self.times[0]
1171
1570
1172 @property
1571 @property
1173 def max_time(self):
1572 def max_time(self):
1174 '''
1573 '''
1175 Return the maximun time value
1574 Return the maximun time value
1176 '''
1575 '''
1177
1576
1178 return self.times[-1]
1577 return self.times[-1]
1179
1578
1180 @property
1579 @property
1181 def heights(self):
1580 def heights(self):
1182 '''
1581 '''
1183 Return the list of heights of the current data
1582 Return the list of heights of the current data
1184 '''
1583 '''
1185
1584
1186 return numpy.array(self.__heights[-1])
1585 return numpy.array(self.__heights[-1])
1187
1586
1188 @staticmethod
1587 @staticmethod
1189 def roundFloats(obj):
1588 def roundFloats(obj):
1190 if isinstance(obj, list):
1589 if isinstance(obj, list):
1191 return list(map(PlotterData.roundFloats, obj))
1590 return list(map(PlotterData.roundFloats, obj))
1192 elif isinstance(obj, float):
1591 elif isinstance(obj, float):
1193 return round(obj, 2)
1592 return round(obj, 2)
@@ -1,906 +1,909
1 '''
1 '''
2
2
3 $Author: murco $
3 $Author: murco $
4 $Id: JROHeaderIO.py 151 2012-10-31 19:00:51Z murco $
4 $Id: JROHeaderIO.py 151 2012-10-31 19:00:51Z murco $
5 '''
5 '''
6 import sys
6 import sys
7 import numpy
7 import numpy
8 import copy
8 import copy
9 import datetime
9 import datetime
10 import inspect
10 import inspect
11 from schainpy.utils import log
11 from schainpy.utils import log
12
12
13 SPEED_OF_LIGHT = 299792458
13 SPEED_OF_LIGHT = 299792458
14 SPEED_OF_LIGHT = 3e8
14 SPEED_OF_LIGHT = 3e8
15
15
16 BASIC_STRUCTURE = numpy.dtype([
16 BASIC_STRUCTURE = numpy.dtype([
17 ('nSize', '<u4'),
17 ('nSize', '<u4'),
18 ('nVersion', '<u2'),
18 ('nVersion', '<u2'),
19 ('nDataBlockId', '<u4'),
19 ('nDataBlockId', '<u4'),
20 ('nUtime', '<u4'),
20 ('nUtime', '<u4'),
21 ('nMilsec', '<u2'),
21 ('nMilsec', '<u2'),
22 ('nTimezone', '<i2'),
22 ('nTimezone', '<i2'),
23 ('nDstflag', '<i2'),
23 ('nDstflag', '<i2'),
24 ('nErrorCount', '<u4')
24 ('nErrorCount', '<u4')
25 ])
25 ])
26
26
27 SYSTEM_STRUCTURE = numpy.dtype([
27 SYSTEM_STRUCTURE = numpy.dtype([
28 ('nSize', '<u4'),
28 ('nSize', '<u4'),
29 ('nNumSamples', '<u4'),
29 ('nNumSamples', '<u4'),
30 ('nNumProfiles', '<u4'),
30 ('nNumProfiles', '<u4'),
31 ('nNumChannels', '<u4'),
31 ('nNumChannels', '<u4'),
32 ('nADCResolution', '<u4'),
32 ('nADCResolution', '<u4'),
33 ('nPCDIOBusWidth', '<u4'),
33 ('nPCDIOBusWidth', '<u4'),
34 ])
34 ])
35
35
36 RADAR_STRUCTURE = numpy.dtype([
36 RADAR_STRUCTURE = numpy.dtype([
37 ('nSize', '<u4'),
37 ('nSize', '<u4'),
38 ('nExpType', '<u4'),
38 ('nExpType', '<u4'),
39 ('nNTx', '<u4'),
39 ('nNTx', '<u4'),
40 ('fIpp', '<f4'),
40 ('fIpp', '<f4'),
41 ('fTxA', '<f4'),
41 ('fTxA', '<f4'),
42 ('fTxB', '<f4'),
42 ('fTxB', '<f4'),
43 ('nNumWindows', '<u4'),
43 ('nNumWindows', '<u4'),
44 ('nNumTaus', '<u4'),
44 ('nNumTaus', '<u4'),
45 ('nCodeType', '<u4'),
45 ('nCodeType', '<u4'),
46 ('nLine6Function', '<u4'),
46 ('nLine6Function', '<u4'),
47 ('nLine5Function', '<u4'),
47 ('nLine5Function', '<u4'),
48 ('fClock', '<f4'),
48 ('fClock', '<f4'),
49 ('nPrePulseBefore', '<u4'),
49 ('nPrePulseBefore', '<u4'),
50 ('nPrePulseAfter', '<u4'),
50 ('nPrePulseAfter', '<u4'),
51 ('sRangeIPP', '<a20'),
51 ('sRangeIPP', '<a20'),
52 ('sRangeTxA', '<a20'),
52 ('sRangeTxA', '<a20'),
53 ('sRangeTxB', '<a20'),
53 ('sRangeTxB', '<a20'),
54 ])
54 ])
55
55
56 SAMPLING_STRUCTURE = numpy.dtype(
56 SAMPLING_STRUCTURE = numpy.dtype(
57 [('h0', '<f4'), ('dh', '<f4'), ('nsa', '<u4')])
57 [('h0', '<f4'), ('dh', '<f4'), ('nsa', '<u4')])
58
58
59
59
60 PROCESSING_STRUCTURE = numpy.dtype([
60 PROCESSING_STRUCTURE = numpy.dtype([
61 ('nSize', '<u4'),
61 ('nSize', '<u4'),
62 ('nDataType', '<u4'),
62 ('nDataType', '<u4'),
63 ('nSizeOfDataBlock', '<u4'),
63 ('nSizeOfDataBlock', '<u4'),
64 ('nProfilesperBlock', '<u4'),
64 ('nProfilesperBlock', '<u4'),
65 ('nDataBlocksperFile', '<u4'),
65 ('nDataBlocksperFile', '<u4'),
66 ('nNumWindows', '<u4'),
66 ('nNumWindows', '<u4'),
67 ('nProcessFlags', '<u4'),
67 ('nProcessFlags', '<u4'),
68 ('nCoherentIntegrations', '<u4'),
68 ('nCoherentIntegrations', '<u4'),
69 ('nIncoherentIntegrations', '<u4'),
69 ('nIncoherentIntegrations', '<u4'),
70 ('nTotalSpectra', '<u4')
70 ('nTotalSpectra', '<u4')
71 ])
71 ])
72
72
73
73
74 class Header(object):
74 class Header(object):
75
75
76 def __init__(self):
76 def __init__(self):
77 raise NotImplementedError
77 raise NotImplementedError
78
78
79 def copy(self):
79 def copy(self):
80 return copy.deepcopy(self)
80 return copy.deepcopy(self)
81
81
82 def read(self):
82 def read(self):
83
83
84 raise NotImplementedError
84 raise NotImplementedError
85
85
86 def write(self):
86 def write(self):
87
87
88 raise NotImplementedError
88 raise NotImplementedError
89
89
90 def getAllowedArgs(self):
90 def getAllowedArgs(self):
91 args = inspect.getargspec(self.__init__).args
91 args = inspect.getargspec(self.__init__).args
92 try:
92 try:
93 args.remove('self')
93 args.remove('self')
94 except:
94 except:
95 pass
95 pass
96 return args
96 return args
97
97
98 def getAsDict(self):
98 def getAsDict(self):
99 args = self.getAllowedArgs()
99 args = self.getAllowedArgs()
100 asDict = {}
100 asDict = {}
101 for x in args:
101 for x in args:
102 asDict[x] = self[x]
102 asDict[x] = self[x]
103 return asDict
103 return asDict
104
104
105 def __getitem__(self, name):
105 def __getitem__(self, name):
106 return getattr(self, name)
106 return getattr(self, name)
107
107
108 def printInfo(self):
108 def printInfo(self):
109
109
110 message = "#" * 50 + "\n"
110 message = "#" * 50 + "\n"
111 message += self.__class__.__name__.upper() + "\n"
111 message += self.__class__.__name__.upper() + "\n"
112 message += "#" * 50 + "\n"
112 message += "#" * 50 + "\n"
113
113
114 keyList = list(self.__dict__.keys())
114 keyList = list(self.__dict__.keys())
115 keyList.sort()
115 keyList.sort()
116
116
117 for key in keyList:
117 for key in keyList:
118 message += "%s = %s" % (key, self.__dict__[key]) + "\n"
118 message += "%s = %s" % (key, self.__dict__[key]) + "\n"
119
119
120 if "size" not in keyList:
120 if "size" not in keyList:
121 attr = getattr(self, "size")
121 attr = getattr(self, "size")
122
122
123 if attr:
123 if attr:
124 message += "%s = %s" % ("size", attr) + "\n"
124 message += "%s = %s" % ("size", attr) + "\n"
125
125
126 print(message)
126 print(message)
127
127
128
128
129 class BasicHeader(Header):
129 class BasicHeader(Header):
130
130
131 size = None
131 size = None
132 version = None
132 version = None
133 dataBlock = None
133 dataBlock = None
134 utc = None
134 utc = None
135 ltc = None
135 ltc = None
136 miliSecond = None
136 miliSecond = None
137 timeZone = None
137 timeZone = None
138 dstFlag = None
138 dstFlag = None
139 errorCount = None
139 errorCount = None
140 datatime = None
140 F = None
141 structure = BASIC_STRUCTURE
141 structure = BASIC_STRUCTURE
142 __LOCALTIME = None
142 __LOCALTIME = None
143
143
144 def __init__(self, useLocalTime=True):
144 def __init__(self, useLocalTime=True):
145
145
146 self.size = 24
146 self.size = 24
147 self.version = 0
147 self.version = 0
148 self.dataBlock = 0
148 self.dataBlock = 0
149 self.utc = 0
149 self.utc = 0
150 self.miliSecond = 0
150 self.miliSecond = 0
151 self.timeZone = 0
151 self.timeZone = 0
152 self.dstFlag = 0
152 self.dstFlag = 0
153 self.errorCount = 0
153 self.errorCount = 0
154
154
155 self.useLocalTime = useLocalTime
155 self.useLocalTime = useLocalTime
156
156
157 def read(self, fp):
157 def read(self, fp):
158
158
159 self.length = 0
159 self.length = 0
160 try:
160 try:
161 if hasattr(fp, 'read'):
161 if hasattr(fp, 'read'):
162 header = numpy.fromfile(fp, BASIC_STRUCTURE, 1)
162 header = numpy.fromfile(fp, BASIC_STRUCTURE, 1)
163 else:
163 else:
164 header = numpy.fromstring(fp, BASIC_STRUCTURE, 1)
164 header = numpy.fromstring(fp, BASIC_STRUCTURE, 1)
165 except Exception as e:
165 except Exception as e:
166 print("BasicHeader: ")
166 print("BasicHeader: ")
167 print(e)
167 print(e)
168 return 0
168 return 0
169
169
170 self.size = int(header['nSize'][0])
170 self.size = int(header['nSize'][0])
171 self.version = int(header['nVersion'][0])
171 self.version = int(header['nVersion'][0])
172 self.dataBlock = int(header['nDataBlockId'][0])
172 self.dataBlock = int(header['nDataBlockId'][0])
173 self.utc = int(header['nUtime'][0])
173 self.utc = int(header['nUtime'][0])
174 self.miliSecond = int(header['nMilsec'][0])
174 self.miliSecond = int(header['nMilsec'][0])
175 self.timeZone = int(header['nTimezone'][0])
175 self.timeZone = int(header['nTimezone'][0])
176 self.dstFlag = int(header['nDstflag'][0])
176 self.dstFlag = int(header['nDstflag'][0])
177 self.errorCount = int(header['nErrorCount'][0])
177 self.errorCount = int(header['nErrorCount'][0])
178
178
179 if self.size < 24:
179 if self.size < 24:
180 return 0
180 return 0
181
181
182 self.length = header.nbytes
182 self.length = header.nbytes
183 return 1
183 return 1
184
184
185 def write(self, fp):
185 def write(self, fp):
186
186
187 headerTuple = (self.size, self.version, self.dataBlock, self.utc,
187 headerTuple = (self.size, self.version, self.dataBlock, self.utc,
188 self.miliSecond, self.timeZone, self.dstFlag, self.errorCount)
188 self.miliSecond, self.timeZone, self.dstFlag, self.errorCount)
189 header = numpy.array(headerTuple, BASIC_STRUCTURE)
189 header = numpy.array(headerTuple, BASIC_STRUCTURE)
190 header.tofile(fp)
190 header.tofile(fp)
191
191
192 return 1
192 return 1
193
193
194 def get_ltc(self):
194 def get_ltc(self):
195
195
196 return self.utc - self.timeZone * 60
196 return self.utc - self.timeZone * 60
197
197
198 def set_ltc(self, value):
198 def set_ltc(self, value):
199
199
200 self.utc = value + self.timeZone * 60
200 self.utc = value + self.timeZone * 60
201
201
202 def get_datatime(self):
202 def get_datatime(self):
203
203
204 return datetime.datetime.utcfromtimestamp(self.ltc)
204 return datetime.datetime.utcfromtimestamp(self.ltc)
205
205
206 ltc = property(get_ltc, set_ltc)
206 ltc = property(get_ltc, set_ltc)
207 datatime = property(get_datatime)
207 datatime = property(get_datatime)
208
208
209
209
210 class SystemHeader(Header):
210 class SystemHeader(Header):
211
211
212 size = None
212 size = None
213 nSamples = None
213 nSamples = None
214 nProfiles = None
214 nProfiles = None
215 nChannels = None
215 nChannels = None
216 adcResolution = None
216 adcResolution = None
217 pciDioBusWidth = None
217 pciDioBusWidth = None
218 structure = SYSTEM_STRUCTURE
218 structure = SYSTEM_STRUCTURE
219
219
220 def __init__(self, nSamples=0, nProfiles=0, nChannels=0, adcResolution=14, pciDioBusWidth=0):
220 def __init__(self, nSamples=0, nProfiles=0, nChannels=0, adcResolution=14, pciDioBusWidth=0):
221
221
222 self.size = 24
222 self.size = 24
223 self.nSamples = nSamples
223 self.nSamples = nSamples
224 self.nProfiles = nProfiles
224 self.nProfiles = nProfiles
225 self.nChannels = nChannels
225 self.nChannels = nChannels
226 self.adcResolution = adcResolution
226 self.adcResolution = adcResolution
227 self.pciDioBusWidth = pciDioBusWidth
227 self.pciDioBusWidth = pciDioBusWidth
228
228
229 def read(self, fp):
229 def read(self, fp):
230 self.length = 0
230 self.length = 0
231 try:
231 try:
232 startFp = fp.tell()
232 startFp = fp.tell()
233 except Exception as e:
233 except Exception as e:
234 startFp = None
234 startFp = None
235 pass
235 pass
236
236
237 try:
237 try:
238 if hasattr(fp, 'read'):
238 if hasattr(fp, 'read'):
239 header = numpy.fromfile(fp, SYSTEM_STRUCTURE, 1)
239 header = numpy.fromfile(fp, SYSTEM_STRUCTURE, 1)
240 else:
240 else:
241 header = numpy.fromstring(fp, SYSTEM_STRUCTURE, 1)
241 header = numpy.fromstring(fp, SYSTEM_STRUCTURE, 1)
242 except Exception as e:
242 except Exception as e:
243 print("System Header: " + str(e))
243 print("System Header: " + str(e))
244 return 0
244 return 0
245
245
246 self.size = header['nSize'][0]
246 self.size = header['nSize'][0]
247 self.nSamples = header['nNumSamples'][0]
247 self.nSamples = header['nNumSamples'][0]
248 self.nProfiles = header['nNumProfiles'][0]
248 self.nProfiles = header['nNumProfiles'][0]
249 self.nChannels = header['nNumChannels'][0]
249 self.nChannels = header['nNumChannels'][0]
250 self.adcResolution = header['nADCResolution'][0]
250 self.adcResolution = header['nADCResolution'][0]
251 self.pciDioBusWidth = header['nPCDIOBusWidth'][0]
251 self.pciDioBusWidth = header['nPCDIOBusWidth'][0]
252
252
253 if startFp is not None:
253 if startFp is not None:
254 endFp = self.size + startFp
254 endFp = self.size + startFp
255
255
256 if fp.tell() > endFp:
256 if fp.tell() > endFp:
257 sys.stderr.write(
257 sys.stderr.write(
258 "Warning %s: Size value read from System Header is lower than it has to be\n" % fp.name)
258 "Warning %s: Size value read from System Header is lower than it has to be\n" % fp.name)
259 return 0
259 return 0
260
260
261 if fp.tell() < endFp:
261 if fp.tell() < endFp:
262 sys.stderr.write(
262 sys.stderr.write(
263 "Warning %s: Size value read from System Header size is greater than it has to be\n" % fp.name)
263 "Warning %s: Size value read from System Header size is greater than it has to be\n" % fp.name)
264 return 0
264 return 0
265
265
266 self.length = header.nbytes
266 self.length = header.nbytes
267 return 1
267 return 1
268
268
269 def write(self, fp):
269 def write(self, fp):
270
270
271 headerTuple = (self.size, self.nSamples, self.nProfiles,
271 headerTuple = (self.size, self.nSamples, self.nProfiles,
272 self.nChannels, self.adcResolution, self.pciDioBusWidth)
272 self.nChannels, self.adcResolution, self.pciDioBusWidth)
273 header = numpy.array(headerTuple, SYSTEM_STRUCTURE)
273 header = numpy.array(headerTuple, SYSTEM_STRUCTURE)
274 header.tofile(fp)
274 header.tofile(fp)
275
275
276 return 1
276 return 1
277
277
278
278
279 class RadarControllerHeader(Header):
279 class RadarControllerHeader(Header):
280
280
281 expType = None
281 expType = None
282 nTx = None
282 nTx = None
283 ipp = None
283 ipp = None
284 txA = None
284 txA = None
285 txB = None
285 txB = None
286 nWindows = None
286 nWindows = None
287 numTaus = None
287 numTaus = None
288 codeType = None
288 codeType = None
289 line6Function = None
289 line6Function = None
290 line5Function = None
290 line5Function = None
291 fClock = None
291 fClock = None
292 prePulseBefore = None
292 prePulseBefore = None
293 prePulseAfter = None
293 prePulseAfter = None
294 rangeIpp = None
294 rangeIpp = None
295 rangeTxA = None
295 rangeTxA = None
296 rangeTxB = None
296 rangeTxB = None
297 structure = RADAR_STRUCTURE
297 structure = RADAR_STRUCTURE
298 __size = None
298 __size = None
299
299
300 def __init__(self, expType=2, nTx=1,
300 def __init__(self, expType=2, nTx=1,
301 ipp=None, txA=0, txB=0,
301 ipp=None, txA=0, txB=0,
302 nWindows=None, nHeights=None, firstHeight=None, deltaHeight=None,
302 nWindows=None, nHeights=None, firstHeight=None, deltaHeight=None,
303 numTaus=0, line6Function=0, line5Function=0, fClock=None,
303 numTaus=0, line6Function=0, line5Function=0, fClock=None,
304 prePulseBefore=0, prePulseAfter=0,
304 prePulseBefore=0, prePulseAfter=0,
305 codeType=0, nCode=0, nBaud=0, code=None,
305 codeType=0, nCode=0, nBaud=0, code=None,
306 flip1=0, flip2=0):
306 flip1=0, flip2=0):
307
307
308 # self.size = 116
308 # self.size = 116
309 self.expType = expType
309 self.expType = expType
310 self.nTx = nTx
310 self.nTx = nTx
311 self.ipp = ipp
311 self.ipp = ipp
312 self.txA = txA
312 self.txA = txA
313 self.txB = txB
313 self.txB = txB
314 self.rangeIpp = ipp
314 self.rangeIpp = ipp
315 self.rangeTxA = txA
315 self.rangeTxA = txA
316 self.rangeTxB = txB
316 self.rangeTxB = txB
317
317
318 self.nWindows = nWindows
318 self.nWindows = nWindows
319 self.numTaus = numTaus
319 self.numTaus = numTaus
320 self.codeType = codeType
320 self.codeType = codeType
321 self.line6Function = line6Function
321 self.line6Function = line6Function
322 self.line5Function = line5Function
322 self.line5Function = line5Function
323 self.fClock = fClock
323 self.fClock = fClock
324 self.prePulseBefore = prePulseBefore
324 self.prePulseBefore = prePulseBefore
325 self.prePulseAfter = prePulseAfter
325 self.prePulseAfter = prePulseAfter
326
326
327 self.nHeights = nHeights
327 self.nHeights = nHeights
328 self.firstHeight = firstHeight
328 self.firstHeight = firstHeight
329 self.deltaHeight = deltaHeight
329 self.deltaHeight = deltaHeight
330 self.samplesWin = nHeights
330 self.samplesWin = nHeights
331
331
332 self.nCode = nCode
332 self.nCode = nCode
333 self.nBaud = nBaud
333 self.nBaud = nBaud
334 self.code = code
334 self.code = code
335 self.flip1 = flip1
335 self.flip1 = flip1
336 self.flip2 = flip2
336 self.flip2 = flip2
337
337
338 self.code_size = int(numpy.ceil(self.nBaud / 32.)) * self.nCode * 4
338 self.code_size = int(numpy.ceil(self.nBaud / 32.)) * self.nCode * 4
339 # self.dynamic = numpy.array([],numpy.dtype('byte'))
339 # self.dynamic = numpy.array([],numpy.dtype('byte'))
340
340
341 if self.fClock is None and self.deltaHeight is not None:
341 if self.fClock is None and self.deltaHeight is not None:
342 self.fClock = 0.15 / (deltaHeight * 1e-6) # 0.15Km / (height * 1u)
342 self.fClock = 0.15 / (deltaHeight * 1e-6) # 0.15Km / (height * 1u)
343
343
344 def read(self, fp):
344 def read(self, fp):
345 self.length = 0
345 self.length = 0
346 try:
346 try:
347 startFp = fp.tell()
347 startFp = fp.tell()
348 except Exception as e:
348 except Exception as e:
349 startFp = None
349 startFp = None
350 pass
350 pass
351
351
352 try:
352 try:
353 if hasattr(fp, 'read'):
353 if hasattr(fp, 'read'):
354 header = numpy.fromfile(fp, RADAR_STRUCTURE, 1)
354 header = numpy.fromfile(fp, RADAR_STRUCTURE, 1)
355 else:
355 else:
356 header = numpy.fromstring(fp, RADAR_STRUCTURE, 1)
356 header = numpy.fromstring(fp, RADAR_STRUCTURE, 1)
357 self.length += header.nbytes
357 self.length += header.nbytes
358 except Exception as e:
358 except Exception as e:
359 print("RadarControllerHeader: " + str(e))
359 print("RadarControllerHeader: " + str(e))
360 return 0
360 return 0
361
361
362 size = int(header['nSize'][0])
362 size = int(header['nSize'][0])
363 self.expType = int(header['nExpType'][0])
363 self.expType = int(header['nExpType'][0])
364 self.nTx = int(header['nNTx'][0])
364 self.nTx = int(header['nNTx'][0])
365 self.ipp = float(header['fIpp'][0])
365 self.ipp = float(header['fIpp'][0])
366 #print(self.ipp)
366 self.txA = float(header['fTxA'][0])
367 self.txA = float(header['fTxA'][0])
367 self.txB = float(header['fTxB'][0])
368 self.txB = float(header['fTxB'][0])
368 self.nWindows = int(header['nNumWindows'][0])
369 self.nWindows = int(header['nNumWindows'][0])
369 self.numTaus = int(header['nNumTaus'][0])
370 self.numTaus = int(header['nNumTaus'][0])
370 self.codeType = int(header['nCodeType'][0])
371 self.codeType = int(header['nCodeType'][0])
371 self.line6Function = int(header['nLine6Function'][0])
372 self.line6Function = int(header['nLine6Function'][0])
372 self.line5Function = int(header['nLine5Function'][0])
373 self.line5Function = int(header['nLine5Function'][0])
373 self.fClock = float(header['fClock'][0])
374 self.fClock = float(header['fClock'][0])
374 self.prePulseBefore = int(header['nPrePulseBefore'][0])
375 self.prePulseBefore = int(header['nPrePulseBefore'][0])
375 self.prePulseAfter = int(header['nPrePulseAfter'][0])
376 self.prePulseAfter = int(header['nPrePulseAfter'][0])
376 self.rangeIpp = header['sRangeIPP'][0]
377 self.rangeIpp = header['sRangeIPP'][0]
377 self.rangeTxA = header['sRangeTxA'][0]
378 self.rangeTxA = header['sRangeTxA'][0]
378 self.rangeTxB = header['sRangeTxB'][0]
379 self.rangeTxB = header['sRangeTxB'][0]
379
380
380 try:
381 try:
381 if hasattr(fp, 'read'):
382 if hasattr(fp, 'read'):
382 samplingWindow = numpy.fromfile(
383 samplingWindow = numpy.fromfile(
383 fp, SAMPLING_STRUCTURE, self.nWindows)
384 fp, SAMPLING_STRUCTURE, self.nWindows)
384 else:
385 else:
385 samplingWindow = numpy.fromstring(
386 samplingWindow = numpy.fromstring(
386 fp[self.length:], SAMPLING_STRUCTURE, self.nWindows)
387 fp[self.length:], SAMPLING_STRUCTURE, self.nWindows)
387 self.length += samplingWindow.nbytes
388 self.length += samplingWindow.nbytes
388 except Exception as e:
389 except Exception as e:
389 print("RadarControllerHeader: " + str(e))
390 print("RadarControllerHeader: " + str(e))
390 return 0
391 return 0
391 self.nHeights = int(numpy.sum(samplingWindow['nsa']))
392 self.nHeights = int(numpy.sum(samplingWindow['nsa']))
392 self.firstHeight = samplingWindow['h0']
393 self.firstHeight = samplingWindow['h0']
393 self.deltaHeight = samplingWindow['dh']
394 self.deltaHeight = samplingWindow['dh']
394 self.samplesWin = samplingWindow['nsa']
395 self.samplesWin = samplingWindow['nsa']
395
396
396 try:
397 try:
397 if hasattr(fp, 'read'):
398 if hasattr(fp, 'read'):
398 self.Taus = numpy.fromfile(fp, '<f4', self.numTaus)
399 self.Taus = numpy.fromfile(fp, '<f4', self.numTaus)
399 else:
400 else:
400 self.Taus = numpy.fromstring(
401 self.Taus = numpy.fromstring(
401 fp[self.length:], '<f4', self.numTaus)
402 fp[self.length:], '<f4', self.numTaus)
402 self.length += self.Taus.nbytes
403 self.length += self.Taus.nbytes
403 except Exception as e:
404 except Exception as e:
404 print("RadarControllerHeader: " + str(e))
405 print("RadarControllerHeader: " + str(e))
405 return 0
406 return 0
406
407
407 self.code_size = 0
408 self.code_size = 0
408 if self.codeType != 0:
409 if self.codeType != 0:
409
410
410 try:
411 try:
411 if hasattr(fp, 'read'):
412 if hasattr(fp, 'read'):
412 self.nCode = numpy.fromfile(fp, '<u4', 1)[0]
413 self.nCode = numpy.fromfile(fp, '<u4', 1)[0]
413 self.length += self.nCode.nbytes
414 self.length += self.nCode.nbytes
414 self.nBaud = numpy.fromfile(fp, '<u4', 1)[0]
415 self.nBaud = numpy.fromfile(fp, '<u4', 1)[0]
415 self.length += self.nBaud.nbytes
416 self.length += self.nBaud.nbytes
416 else:
417 else:
417 self.nCode = numpy.fromstring(
418 self.nCode = numpy.fromstring(
418 fp[self.length:], '<u4', 1)[0]
419 fp[self.length:], '<u4', 1)[0]
419 self.length += self.nCode.nbytes
420 self.length += self.nCode.nbytes
420 self.nBaud = numpy.fromstring(
421 self.nBaud = numpy.fromstring(
421 fp[self.length:], '<u4', 1)[0]
422 fp[self.length:], '<u4', 1)[0]
422 self.length += self.nBaud.nbytes
423 self.length += self.nBaud.nbytes
423 except Exception as e:
424 except Exception as e:
424 print("RadarControllerHeader: " + str(e))
425 print("RadarControllerHeader: " + str(e))
425 return 0
426 return 0
426 code = numpy.empty([self.nCode, self.nBaud], dtype='i1')
427 code = numpy.empty([self.nCode, self.nBaud], dtype='i1')
427
428
428 for ic in range(self.nCode):
429 for ic in range(self.nCode):
429 try:
430 try:
430 if hasattr(fp, 'read'):
431 if hasattr(fp, 'read'):
431 temp = numpy.fromfile(fp, 'u4', int(
432 temp = numpy.fromfile(fp, 'u4', int(
432 numpy.ceil(self.nBaud / 32.)))
433 numpy.ceil(self.nBaud / 32.)))
433 else:
434 else:
434 temp = numpy.fromstring(
435 temp = numpy.fromstring(
435 fp, 'u4', int(numpy.ceil(self.nBaud / 32.)))
436 fp, 'u4', int(numpy.ceil(self.nBaud / 32.)))
436 self.length += temp.nbytes
437 self.length += temp.nbytes
437 except Exception as e:
438 except Exception as e:
438 print("RadarControllerHeader: " + str(e))
439 print("RadarControllerHeader: " + str(e))
439 return 0
440 return 0
440
441
441 for ib in range(self.nBaud - 1, -1, -1):
442 for ib in range(self.nBaud - 1, -1, -1):
442 code[ic, ib] = temp[int(ib / 32)] % 2
443 code[ic, ib] = temp[int(ib / 32)] % 2
443 temp[int(ib / 32)] = temp[int(ib / 32)] / 2
444 temp[int(ib / 32)] = temp[int(ib / 32)] / 2
444
445
445 self.code = 2.0 * code - 1.0
446 self.code = 2.0 * code - 1.0
446 self.code_size = int(numpy.ceil(self.nBaud / 32.)) * self.nCode * 4
447 self.code_size = int(numpy.ceil(self.nBaud / 32.)) * self.nCode * 4
447
448
448 # if self.line5Function == RCfunction.FLIP:
449 # if self.line5Function == RCfunction.FLIP:
449 # self.flip1 = numpy.fromfile(fp,'<u4',1)
450 # self.flip1 = numpy.fromfile(fp,'<u4',1)
450 #
451 #
451 # if self.line6Function == RCfunction.FLIP:
452 # if self.line6Function == RCfunction.FLIP:
452 # self.flip2 = numpy.fromfile(fp,'<u4',1)
453 # self.flip2 = numpy.fromfile(fp,'<u4',1)
453 if startFp is not None:
454 if startFp is not None:
454 endFp = size + startFp
455 endFp = size + startFp
455
456
456 if fp.tell() != endFp:
457 if fp.tell() != endFp:
457 # fp.seek(endFp)
458 # fp.seek(endFp)
458 print("%s: Radar Controller Header size is not consistent: from data [%d] != from header field [%d]" % (fp.name, fp.tell() - startFp, size))
459 print("%s: Radar Controller Header size is not consistent: from data [%d] != from header field [%d]" % (fp.name, fp.tell() - startFp, size))
459 # return 0
460 # return 0
460
461
461 if fp.tell() > endFp:
462 if fp.tell() > endFp:
462 sys.stderr.write(
463 sys.stderr.write(
463 "Warning %s: Size value read from Radar Controller header is lower than it has to be\n" % fp.name)
464 "Warning %s: Size value read from Radar Controller header is lower than it has to be\n" % fp.name)
464 # return 0
465 # return 0
465
466
466 if fp.tell() < endFp:
467 if fp.tell() < endFp:
467 sys.stderr.write(
468 sys.stderr.write(
468 "Warning %s: Size value read from Radar Controller header is greater than it has to be\n" % fp.name)
469 "Warning %s: Size value read from Radar Controller header is greater than it has to be\n" % fp.name)
469
470
470 return 1
471 return 1
471
472
472 def write(self, fp):
473 def write(self, fp):
473
474
474 headerTuple = (self.size,
475 headerTuple = (self.size,
475 self.expType,
476 self.expType,
476 self.nTx,
477 self.nTx,
477 self.ipp,
478 self.ipp,
478 self.txA,
479 self.txA,
479 self.txB,
480 self.txB,
480 self.nWindows,
481 self.nWindows,
481 self.numTaus,
482 self.numTaus,
482 self.codeType,
483 self.codeType,
483 self.line6Function,
484 self.line6Function,
484 self.line5Function,
485 self.line5Function,
485 self.fClock,
486 self.fClock,
486 self.prePulseBefore,
487 self.prePulseBefore,
487 self.prePulseAfter,
488 self.prePulseAfter,
488 self.rangeIpp,
489 self.rangeIpp,
489 self.rangeTxA,
490 self.rangeTxA,
490 self.rangeTxB)
491 self.rangeTxB)
491
492
492 header = numpy.array(headerTuple, RADAR_STRUCTURE)
493 header = numpy.array(headerTuple, RADAR_STRUCTURE)
493 header.tofile(fp)
494 header.tofile(fp)
494
495
495 sampleWindowTuple = (
496 sampleWindowTuple = (
496 self.firstHeight, self.deltaHeight, self.samplesWin)
497 self.firstHeight, self.deltaHeight, self.samplesWin)
497 samplingWindow = numpy.array(sampleWindowTuple, SAMPLING_STRUCTURE)
498 samplingWindow = numpy.array(sampleWindowTuple, SAMPLING_STRUCTURE)
498 samplingWindow.tofile(fp)
499 samplingWindow.tofile(fp)
499
500
500 if self.numTaus > 0:
501 if self.numTaus > 0:
501 self.Taus.tofile(fp)
502 self.Taus.tofile(fp)
502
503
503 if self.codeType != 0:
504 if self.codeType != 0:
504 nCode = numpy.array(self.nCode, '<u4')
505 nCode = numpy.array(self.nCode, '<u4')
505 nCode.tofile(fp)
506 nCode.tofile(fp)
506 nBaud = numpy.array(self.nBaud, '<u4')
507 nBaud = numpy.array(self.nBaud, '<u4')
507 nBaud.tofile(fp)
508 nBaud.tofile(fp)
508 code1 = (self.code + 1.0) / 2.
509 code1 = (self.code + 1.0) / 2.
509
510
510 for ic in range(self.nCode):
511 for ic in range(self.nCode):
511 tempx = numpy.zeros(int(numpy.ceil(self.nBaud / 32.)))
512 tempx = numpy.zeros(int(numpy.ceil(self.nBaud / 32.)))
512 start = 0
513 start = 0
513 end = 32
514 end = 32
514 for i in range(len(tempx)):
515 for i in range(len(tempx)):
515 code_selected = code1[ic, start:end]
516 code_selected = code1[ic, start:end]
516 for j in range(len(code_selected) - 1, -1, -1):
517 for j in range(len(code_selected) - 1, -1, -1):
517 if code_selected[j] == 1:
518 if code_selected[j] == 1:
518 tempx[i] = tempx[i] + \
519 tempx[i] = tempx[i] + \
519 2**(len(code_selected) - 1 - j)
520 2**(len(code_selected) - 1 - j)
520 start = start + 32
521 start = start + 32
521 end = end + 32
522 end = end + 32
522
523
523 tempx = tempx.astype('u4')
524 tempx = tempx.astype('u4')
524 tempx.tofile(fp)
525 tempx.tofile(fp)
525
526
526 # if self.line5Function == RCfunction.FLIP:
527 # if self.line5Function == RCfunction.FLIP:
527 # self.flip1.tofile(fp)
528 # self.flip1.tofile(fp)
528 #
529 #
529 # if self.line6Function == RCfunction.FLIP:
530 # if self.line6Function == RCfunction.FLIP:
530 # self.flip2.tofile(fp)
531 # self.flip2.tofile(fp)
531
532
532 return 1
533 return 1
533
534
534 def get_ippSeconds(self):
535 def get_ippSeconds(self):
535 '''
536 '''
536 '''
537 '''
538
537 ippSeconds = 2.0 * 1000 * self.ipp / SPEED_OF_LIGHT
539 ippSeconds = 2.0 * 1000 * self.ipp / SPEED_OF_LIGHT
538
540
539 return ippSeconds
541 return ippSeconds
540
542
541 def set_ippSeconds(self, ippSeconds):
543 def set_ippSeconds(self, ippSeconds):
542 '''
544 '''
543 '''
545 '''
544
546
545 self.ipp = ippSeconds * SPEED_OF_LIGHT / (2.0 * 1000)
547 self.ipp = ippSeconds * SPEED_OF_LIGHT / (2.0 * 1000)
546
548
547 return
549 return
548
550
549 def get_size(self):
551 def get_size(self):
550
552
551 self.__size = 116 + 12 * self.nWindows + 4 * self.numTaus
553 self.__size = 116 + 12 * self.nWindows + 4 * self.numTaus
552
554
553 if self.codeType != 0:
555 if self.codeType != 0:
554 self.__size += 4 + 4 + 4 * self.nCode * \
556 self.__size += 4 + 4 + 4 * self.nCode * \
555 numpy.ceil(self.nBaud / 32.)
557 numpy.ceil(self.nBaud / 32.)
556
558
557 return self.__size
559 return self.__size
558
560
559 def set_size(self, value):
561 def set_size(self, value):
560
562
561 raise IOError("size is a property and it cannot be set, just read")
563 raise IOError("size is a property and it cannot be set, just read")
562
564
563 return
565 return
564
566
565 ippSeconds = property(get_ippSeconds, set_ippSeconds)
567 ippSeconds = property(get_ippSeconds, set_ippSeconds)
566 size = property(get_size, set_size)
568 size = property(get_size, set_size)
567
569
568
570
569 class ProcessingHeader(Header):
571 class ProcessingHeader(Header):
570
572
571 # size = None
573 # size = None
572 dtype = None
574 dtype = None
573 blockSize = None
575 blockSize = None
574 profilesPerBlock = None
576 profilesPerBlock = None
575 dataBlocksPerFile = None
577 dataBlocksPerFile = None
576 nWindows = None
578 nWindows = None
577 processFlags = None
579 processFlags = None
578 nCohInt = None
580 nCohInt = None
579 nIncohInt = None
581 nIncohInt = None
580 totalSpectra = None
582 totalSpectra = None
581 structure = PROCESSING_STRUCTURE
583 structure = PROCESSING_STRUCTURE
582 flag_dc = None
584 flag_dc = None
583 flag_cspc = None
585 flag_cspc = None
584
586
585 def __init__(self, dtype=0, blockSize=0, profilesPerBlock=0, dataBlocksPerFile=0, nWindows=0, processFlags=0, nCohInt=0,
587 def __init__(self, dtype=0, blockSize=0, profilesPerBlock=0, dataBlocksPerFile=0, nWindows=0, processFlags=0, nCohInt=0,
586 nIncohInt=0, totalSpectra=0, nHeights=0, firstHeight=0, deltaHeight=0, samplesWin=0, spectraComb=0, nCode=0,
588 nIncohInt=0, totalSpectra=0, nHeights=0, firstHeight=0, deltaHeight=0, samplesWin=0, spectraComb=0, nCode=0,
587 code=0, nBaud=None, shif_fft=False, flag_dc=False, flag_cspc=False, flag_decode=False, flag_deflip=False
589 code=0, nBaud=None, shif_fft=False, flag_dc=False, flag_cspc=False, flag_decode=False, flag_deflip=False
588 ):
590 ):
589
591
590 # self.size = 0
592 # self.size = 0
591 self.dtype = dtype
593 self.dtype = dtype
592 self.blockSize = blockSize
594 self.blockSize = blockSize
593 self.profilesPerBlock = 0
595 self.profilesPerBlock = 0
594 self.dataBlocksPerFile = 0
596 self.dataBlocksPerFile = 0
595 self.nWindows = 0
597 self.nWindows = 0
596 self.processFlags = 0
598 self.processFlags = 0
597 self.nCohInt = 0
599 self.nCohInt = 0
598 self.nIncohInt = 0
600 self.nIncohInt = 0
599 self.totalSpectra = 0
601 self.totalSpectra = 0
600
602
601 self.nHeights = 0
603 self.nHeights = 0
602 self.firstHeight = 0
604 self.firstHeight = 0
603 self.deltaHeight = 0
605 self.deltaHeight = 0
604 self.samplesWin = 0
606 self.samplesWin = 0
605 self.spectraComb = 0
607 self.spectraComb = 0
606 self.nCode = None
608 self.nCode = None
607 self.code = None
609 self.code = None
608 self.nBaud = None
610 self.nBaud = None
609
611
610 self.shif_fft = False
612 self.shif_fft = False
611 self.flag_dc = False
613 self.flag_dc = False
612 self.flag_cspc = False
614 self.flag_cspc = False
613 self.flag_decode = False
615 self.flag_decode = False
614 self.flag_deflip = False
616 self.flag_deflip = False
615 self.length = 0
617 self.length = 0
616
618
617 def read(self, fp):
619 def read(self, fp):
618 self.length = 0
620 self.length = 0
619 try:
621 try:
620 startFp = fp.tell()
622 startFp = fp.tell()
621 except Exception as e:
623 except Exception as e:
622 startFp = None
624 startFp = None
623 pass
625 pass
624
626
625 try:
627 try:
626 if hasattr(fp, 'read'):
628 if hasattr(fp, 'read'):
627 header = numpy.fromfile(fp, PROCESSING_STRUCTURE, 1)
629 header = numpy.fromfile(fp, PROCESSING_STRUCTURE, 1)
628 else:
630 else:
629 header = numpy.fromstring(fp, PROCESSING_STRUCTURE, 1)
631 header = numpy.fromstring(fp, PROCESSING_STRUCTURE, 1)
630 self.length += header.nbytes
632 self.length += header.nbytes
631 except Exception as e:
633 except Exception as e:
632 print("ProcessingHeader: " + str(e))
634 print("ProcessingHeader: " + str(e))
633 return 0
635 return 0
634
636
635 size = int(header['nSize'][0])
637 size = int(header['nSize'][0])
636 self.dtype = int(header['nDataType'][0])
638 self.dtype = int(header['nDataType'][0])
637 self.blockSize = int(header['nSizeOfDataBlock'][0])
639 self.blockSize = int(header['nSizeOfDataBlock'][0])
638 self.profilesPerBlock = int(header['nProfilesperBlock'][0])
640 self.profilesPerBlock = int(header['nProfilesperBlock'][0])
639 self.dataBlocksPerFile = int(header['nDataBlocksperFile'][0])
641 self.dataBlocksPerFile = int(header['nDataBlocksperFile'][0])
640 self.nWindows = int(header['nNumWindows'][0])
642 self.nWindows = int(header['nNumWindows'][0])
641 self.processFlags = header['nProcessFlags']
643 self.processFlags = header['nProcessFlags']
642 self.nCohInt = int(header['nCoherentIntegrations'][0])
644 self.nCohInt = int(header['nCoherentIntegrations'][0])
645
643 self.nIncohInt = int(header['nIncoherentIntegrations'][0])
646 self.nIncohInt = int(header['nIncoherentIntegrations'][0])
644 self.totalSpectra = int(header['nTotalSpectra'][0])
647 self.totalSpectra = int(header['nTotalSpectra'][0])
645
648
646 try:
649 try:
647 if hasattr(fp, 'read'):
650 if hasattr(fp, 'read'):
648 samplingWindow = numpy.fromfile(
651 samplingWindow = numpy.fromfile(
649 fp, SAMPLING_STRUCTURE, self.nWindows)
652 fp, SAMPLING_STRUCTURE, self.nWindows)
650 else:
653 else:
651 samplingWindow = numpy.fromstring(
654 samplingWindow = numpy.fromstring(
652 fp[self.length:], SAMPLING_STRUCTURE, self.nWindows)
655 fp[self.length:], SAMPLING_STRUCTURE, self.nWindows)
653 self.length += samplingWindow.nbytes
656 self.length += samplingWindow.nbytes
654 except Exception as e:
657 except Exception as e:
655 print("ProcessingHeader: " + str(e))
658 print("ProcessingHeader: " + str(e))
656 return 0
659 return 0
657
660
658 self.nHeights = int(numpy.sum(samplingWindow['nsa']))
661 self.nHeights = int(numpy.sum(samplingWindow['nsa']))
659 self.firstHeight = float(samplingWindow['h0'][0])
662 self.firstHeight = float(samplingWindow['h0'][0])
660 self.deltaHeight = float(samplingWindow['dh'][0])
663 self.deltaHeight = float(samplingWindow['dh'][0])
661 self.samplesWin = samplingWindow['nsa'][0]
664 self.samplesWin = samplingWindow['nsa'][0]
662
665
663 try:
666 try:
664 if hasattr(fp, 'read'):
667 if hasattr(fp, 'read'):
665 self.spectraComb = numpy.fromfile(
668 self.spectraComb = numpy.fromfile(
666 fp, 'u1', 2 * self.totalSpectra)
669 fp, 'u1', 2 * self.totalSpectra)
667 else:
670 else:
668 self.spectraComb = numpy.fromstring(
671 self.spectraComb = numpy.fromstring(
669 fp[self.length:], 'u1', 2 * self.totalSpectra)
672 fp[self.length:], 'u1', 2 * self.totalSpectra)
670 self.length += self.spectraComb.nbytes
673 self.length += self.spectraComb.nbytes
671 except Exception as e:
674 except Exception as e:
672 print("ProcessingHeader: " + str(e))
675 print("ProcessingHeader: " + str(e))
673 return 0
676 return 0
674
677
675 if ((self.processFlags & PROCFLAG.DEFINE_PROCESS_CODE) == PROCFLAG.DEFINE_PROCESS_CODE):
678 if ((self.processFlags & PROCFLAG.DEFINE_PROCESS_CODE) == PROCFLAG.DEFINE_PROCESS_CODE):
676 self.nCode = int(numpy.fromfile(fp, '<u4', 1))
679 self.nCode = int(numpy.fromfile(fp, '<u4', 1))
677 self.nBaud = int(numpy.fromfile(fp, '<u4', 1))
680 self.nBaud = int(numpy.fromfile(fp, '<u4', 1))
678 self.code = numpy.fromfile(
681 self.code = numpy.fromfile(
679 fp, '<f4', self.nCode * self.nBaud).reshape(self.nCode, self.nBaud)
682 fp, '<f4', self.nCode * self.nBaud).reshape(self.nCode, self.nBaud)
680
683
681 if ((self.processFlags & PROCFLAG.EXP_NAME_ESP) == PROCFLAG.EXP_NAME_ESP):
684 if ((self.processFlags & PROCFLAG.EXP_NAME_ESP) == PROCFLAG.EXP_NAME_ESP):
682 exp_name_len = int(numpy.fromfile(fp, '<u4', 1))
685 exp_name_len = int(numpy.fromfile(fp, '<u4', 1))
683 exp_name = numpy.fromfile(fp, 'u1', exp_name_len + 1)
686 exp_name = numpy.fromfile(fp, 'u1', exp_name_len + 1)
684
687
685 if ((self.processFlags & PROCFLAG.SHIFT_FFT_DATA) == PROCFLAG.SHIFT_FFT_DATA):
688 if ((self.processFlags & PROCFLAG.SHIFT_FFT_DATA) == PROCFLAG.SHIFT_FFT_DATA):
686 self.shif_fft = True
689 self.shif_fft = True
687 else:
690 else:
688 self.shif_fft = False
691 self.shif_fft = False
689
692
690 if ((self.processFlags & PROCFLAG.SAVE_CHANNELS_DC) == PROCFLAG.SAVE_CHANNELS_DC):
693 if ((self.processFlags & PROCFLAG.SAVE_CHANNELS_DC) == PROCFLAG.SAVE_CHANNELS_DC):
691 self.flag_dc = True
694 self.flag_dc = True
692 else:
695 else:
693 self.flag_dc = False
696 self.flag_dc = False
694
697
695 if ((self.processFlags & PROCFLAG.DECODE_DATA) == PROCFLAG.DECODE_DATA):
698 if ((self.processFlags & PROCFLAG.DECODE_DATA) == PROCFLAG.DECODE_DATA):
696 self.flag_decode = True
699 self.flag_decode = True
697 else:
700 else:
698 self.flag_decode = False
701 self.flag_decode = False
699
702
700 if ((self.processFlags & PROCFLAG.DEFLIP_DATA) == PROCFLAG.DEFLIP_DATA):
703 if ((self.processFlags & PROCFLAG.DEFLIP_DATA) == PROCFLAG.DEFLIP_DATA):
701 self.flag_deflip = True
704 self.flag_deflip = True
702 else:
705 else:
703 self.flag_deflip = False
706 self.flag_deflip = False
704
707
705 nChannels = 0
708 nChannels = 0
706 nPairs = 0
709 nPairs = 0
707 pairList = []
710 pairList = []
708
711
709 for i in range(0, self.totalSpectra * 2, 2):
712 for i in range(0, self.totalSpectra * 2, 2):
710 if self.spectraComb[i] == self.spectraComb[i + 1]:
713 if self.spectraComb[i] == self.spectraComb[i + 1]:
711 nChannels = nChannels + 1 # par de canales iguales
714 nChannels = nChannels + 1 # par de canales iguales
712 else:
715 else:
713 nPairs = nPairs + 1 # par de canales diferentes
716 nPairs = nPairs + 1 # par de canales diferentes
714 pairList.append((self.spectraComb[i], self.spectraComb[i + 1]))
717 pairList.append((self.spectraComb[i], self.spectraComb[i + 1]))
715
718
716 self.flag_cspc = False
719 self.flag_cspc = False
717 if nPairs > 0:
720 if nPairs > 0:
718 self.flag_cspc = True
721 self.flag_cspc = True
719
722
720 if startFp is not None:
723 if startFp is not None:
721 endFp = size + startFp
724 endFp = size + startFp
722 if fp.tell() > endFp:
725 if fp.tell() > endFp:
723 sys.stderr.write(
726 sys.stderr.write(
724 "Warning: Processing header size is lower than it has to be")
727 "Warning: Processing header size is lower than it has to be")
725 return 0
728 return 0
726
729
727 if fp.tell() < endFp:
730 if fp.tell() < endFp:
728 sys.stderr.write(
731 sys.stderr.write(
729 "Warning: Processing header size is greater than it is considered")
732 "Warning: Processing header size is greater than it is considered")
730
733
731 return 1
734 return 1
732
735
733 def write(self, fp):
736 def write(self, fp):
734 # Clear DEFINE_PROCESS_CODE
737 # Clear DEFINE_PROCESS_CODE
735 self.processFlags = self.processFlags & (~PROCFLAG.DEFINE_PROCESS_CODE)
738 self.processFlags = self.processFlags & (~PROCFLAG.DEFINE_PROCESS_CODE)
736
739
737 headerTuple = (self.size,
740 headerTuple = (self.size,
738 self.dtype,
741 self.dtype,
739 self.blockSize,
742 self.blockSize,
740 self.profilesPerBlock,
743 self.profilesPerBlock,
741 self.dataBlocksPerFile,
744 self.dataBlocksPerFile,
742 self.nWindows,
745 self.nWindows,
743 self.processFlags,
746 self.processFlags,
744 self.nCohInt,
747 self.nCohInt,
745 self.nIncohInt,
748 self.nIncohInt,
746 self.totalSpectra)
749 self.totalSpectra)
747
750
748 header = numpy.array(headerTuple, PROCESSING_STRUCTURE)
751 header = numpy.array(headerTuple, PROCESSING_STRUCTURE)
749 header.tofile(fp)
752 header.tofile(fp)
750
753
751 if self.nWindows != 0:
754 if self.nWindows != 0:
752 sampleWindowTuple = (
755 sampleWindowTuple = (
753 self.firstHeight, self.deltaHeight, self.samplesWin)
756 self.firstHeight, self.deltaHeight, self.samplesWin)
754 samplingWindow = numpy.array(sampleWindowTuple, SAMPLING_STRUCTURE)
757 samplingWindow = numpy.array(sampleWindowTuple, SAMPLING_STRUCTURE)
755 samplingWindow.tofile(fp)
758 samplingWindow.tofile(fp)
756
759
757 if self.totalSpectra != 0:
760 if self.totalSpectra != 0:
758 # spectraComb = numpy.array([],numpy.dtype('u1'))
761 # spectraComb = numpy.array([],numpy.dtype('u1'))
759 spectraComb = self.spectraComb
762 spectraComb = self.spectraComb
760 spectraComb.tofile(fp)
763 spectraComb.tofile(fp)
761
764
762 # if self.processFlags & PROCFLAG.DEFINE_PROCESS_CODE == PROCFLAG.DEFINE_PROCESS_CODE:
765 # if self.processFlags & PROCFLAG.DEFINE_PROCESS_CODE == PROCFLAG.DEFINE_PROCESS_CODE:
763 # nCode = numpy.array([self.nCode], numpy.dtype('u4')) #Probar con un dato que almacene codigo, hasta el momento no se hizo la prueba
766 # nCode = numpy.array([self.nCode], numpy.dtype('u4')) #Probar con un dato que almacene codigo, hasta el momento no se hizo la prueba
764 # nCode.tofile(fp)
767 # nCode.tofile(fp)
765 #
768 #
766 # nBaud = numpy.array([self.nBaud], numpy.dtype('u4'))
769 # nBaud = numpy.array([self.nBaud], numpy.dtype('u4'))
767 # nBaud.tofile(fp)
770 # nBaud.tofile(fp)
768 #
771 #
769 # code = self.code.reshape(self.nCode*self.nBaud)
772 # code = self.code.reshape(self.nCode*self.nBaud)
770 # code = code.astype(numpy.dtype('<f4'))
773 # code = code.astype(numpy.dtype('<f4'))
771 # code.tofile(fp)
774 # code.tofile(fp)
772
775
773 return 1
776 return 1
774
777
775 def get_size(self):
778 def get_size(self):
776
779
777 self.__size = 40 + 12 * self.nWindows + 2 * self.totalSpectra
780 self.__size = 40 + 12 * self.nWindows + 2 * self.totalSpectra
778
781
779 # if self.processFlags & PROCFLAG.DEFINE_PROCESS_CODE == PROCFLAG.DEFINE_PROCESS_CODE:
782 # if self.processFlags & PROCFLAG.DEFINE_PROCESS_CODE == PROCFLAG.DEFINE_PROCESS_CODE:
780 # self.__size += 4 + 4 + 4*self.nCode*numpy.ceil(self.nBaud/32.)
783 # self.__size += 4 + 4 + 4*self.nCode*numpy.ceil(self.nBaud/32.)
781 # self.__size += 4 + 4 + 4 * self.nCode * self.nBaud
784 # self.__size += 4 + 4 + 4 * self.nCode * self.nBaud
782
785
783 return self.__size
786 return self.__size
784
787
785 def set_size(self, value):
788 def set_size(self, value):
786
789
787 raise IOError("size is a property and it cannot be set, just read")
790 raise IOError("size is a property and it cannot be set, just read")
788
791
789 return
792 return
790
793
791 size = property(get_size, set_size)
794 size = property(get_size, set_size)
792
795
793
796
794 class RCfunction:
797 class RCfunction:
795 NONE = 0
798 NONE = 0
796 FLIP = 1
799 FLIP = 1
797 CODE = 2
800 CODE = 2
798 SAMPLING = 3
801 SAMPLING = 3
799 LIN6DIV256 = 4
802 LIN6DIV256 = 4
800 SYNCHRO = 5
803 SYNCHRO = 5
801
804
802
805
803 class nCodeType:
806 class nCodeType:
804 NONE = 0
807 NONE = 0
805 USERDEFINE = 1
808 USERDEFINE = 1
806 BARKER2 = 2
809 BARKER2 = 2
807 BARKER3 = 3
810 BARKER3 = 3
808 BARKER4 = 4
811 BARKER4 = 4
809 BARKER5 = 5
812 BARKER5 = 5
810 BARKER7 = 6
813 BARKER7 = 6
811 BARKER11 = 7
814 BARKER11 = 7
812 BARKER13 = 8
815 BARKER13 = 8
813 AC128 = 9
816 AC128 = 9
814 COMPLEMENTARYCODE2 = 10
817 COMPLEMENTARYCODE2 = 10
815 COMPLEMENTARYCODE4 = 11
818 COMPLEMENTARYCODE4 = 11
816 COMPLEMENTARYCODE8 = 12
819 COMPLEMENTARYCODE8 = 12
817 COMPLEMENTARYCODE16 = 13
820 COMPLEMENTARYCODE16 = 13
818 COMPLEMENTARYCODE32 = 14
821 COMPLEMENTARYCODE32 = 14
819 COMPLEMENTARYCODE64 = 15
822 COMPLEMENTARYCODE64 = 15
820 COMPLEMENTARYCODE128 = 16
823 COMPLEMENTARYCODE128 = 16
821 CODE_BINARY28 = 17
824 CODE_BINARY28 = 17
822
825
823
826
824 class PROCFLAG:
827 class PROCFLAG:
825
828
826 COHERENT_INTEGRATION = numpy.uint32(0x00000001)
829 COHERENT_INTEGRATION = numpy.uint32(0x00000001)
827 DECODE_DATA = numpy.uint32(0x00000002)
830 DECODE_DATA = numpy.uint32(0x00000002)
828 SPECTRA_CALC = numpy.uint32(0x00000004)
831 SPECTRA_CALC = numpy.uint32(0x00000004)
829 INCOHERENT_INTEGRATION = numpy.uint32(0x00000008)
832 INCOHERENT_INTEGRATION = numpy.uint32(0x00000008)
830 POST_COHERENT_INTEGRATION = numpy.uint32(0x00000010)
833 POST_COHERENT_INTEGRATION = numpy.uint32(0x00000010)
831 SHIFT_FFT_DATA = numpy.uint32(0x00000020)
834 SHIFT_FFT_DATA = numpy.uint32(0x00000020)
832
835
833 DATATYPE_CHAR = numpy.uint32(0x00000040)
836 DATATYPE_CHAR = numpy.uint32(0x00000040)
834 DATATYPE_SHORT = numpy.uint32(0x00000080)
837 DATATYPE_SHORT = numpy.uint32(0x00000080)
835 DATATYPE_LONG = numpy.uint32(0x00000100)
838 DATATYPE_LONG = numpy.uint32(0x00000100)
836 DATATYPE_INT64 = numpy.uint32(0x00000200)
839 DATATYPE_INT64 = numpy.uint32(0x00000200)
837 DATATYPE_FLOAT = numpy.uint32(0x00000400)
840 DATATYPE_FLOAT = numpy.uint32(0x00000400)
838 DATATYPE_DOUBLE = numpy.uint32(0x00000800)
841 DATATYPE_DOUBLE = numpy.uint32(0x00000800)
839
842
840 DATAARRANGE_CONTIGUOUS_CH = numpy.uint32(0x00001000)
843 DATAARRANGE_CONTIGUOUS_CH = numpy.uint32(0x00001000)
841 DATAARRANGE_CONTIGUOUS_H = numpy.uint32(0x00002000)
844 DATAARRANGE_CONTIGUOUS_H = numpy.uint32(0x00002000)
842 DATAARRANGE_CONTIGUOUS_P = numpy.uint32(0x00004000)
845 DATAARRANGE_CONTIGUOUS_P = numpy.uint32(0x00004000)
843
846
844 SAVE_CHANNELS_DC = numpy.uint32(0x00008000)
847 SAVE_CHANNELS_DC = numpy.uint32(0x00008000)
845 DEFLIP_DATA = numpy.uint32(0x00010000)
848 DEFLIP_DATA = numpy.uint32(0x00010000)
846 DEFINE_PROCESS_CODE = numpy.uint32(0x00020000)
849 DEFINE_PROCESS_CODE = numpy.uint32(0x00020000)
847
850
848 ACQ_SYS_NATALIA = numpy.uint32(0x00040000)
851 ACQ_SYS_NATALIA = numpy.uint32(0x00040000)
849 ACQ_SYS_ECHOTEK = numpy.uint32(0x00080000)
852 ACQ_SYS_ECHOTEK = numpy.uint32(0x00080000)
850 ACQ_SYS_ADRXD = numpy.uint32(0x000C0000)
853 ACQ_SYS_ADRXD = numpy.uint32(0x000C0000)
851 ACQ_SYS_JULIA = numpy.uint32(0x00100000)
854 ACQ_SYS_JULIA = numpy.uint32(0x00100000)
852 ACQ_SYS_XXXXXX = numpy.uint32(0x00140000)
855 ACQ_SYS_XXXXXX = numpy.uint32(0x00140000)
853
856
854 EXP_NAME_ESP = numpy.uint32(0x00200000)
857 EXP_NAME_ESP = numpy.uint32(0x00200000)
855 CHANNEL_NAMES_ESP = numpy.uint32(0x00400000)
858 CHANNEL_NAMES_ESP = numpy.uint32(0x00400000)
856
859
857 OPERATION_MASK = numpy.uint32(0x0000003F)
860 OPERATION_MASK = numpy.uint32(0x0000003F)
858 DATATYPE_MASK = numpy.uint32(0x00000FC0)
861 DATATYPE_MASK = numpy.uint32(0x00000FC0)
859 DATAARRANGE_MASK = numpy.uint32(0x00007000)
862 DATAARRANGE_MASK = numpy.uint32(0x00007000)
860 ACQ_SYS_MASK = numpy.uint32(0x001C0000)
863 ACQ_SYS_MASK = numpy.uint32(0x001C0000)
861
864
862
865
863 dtype0 = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
866 dtype0 = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
864 dtype1 = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
867 dtype1 = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
865 dtype2 = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
868 dtype2 = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
866 dtype3 = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
869 dtype3 = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
867 dtype4 = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
870 dtype4 = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
868 dtype5 = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
871 dtype5 = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
869
872
870 NUMPY_DTYPE_LIST = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
873 NUMPY_DTYPE_LIST = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
871
874
872 PROCFLAG_DTYPE_LIST = [PROCFLAG.DATATYPE_CHAR,
875 PROCFLAG_DTYPE_LIST = [PROCFLAG.DATATYPE_CHAR,
873 PROCFLAG.DATATYPE_SHORT,
876 PROCFLAG.DATATYPE_SHORT,
874 PROCFLAG.DATATYPE_LONG,
877 PROCFLAG.DATATYPE_LONG,
875 PROCFLAG.DATATYPE_INT64,
878 PROCFLAG.DATATYPE_INT64,
876 PROCFLAG.DATATYPE_FLOAT,
879 PROCFLAG.DATATYPE_FLOAT,
877 PROCFLAG.DATATYPE_DOUBLE]
880 PROCFLAG.DATATYPE_DOUBLE]
878
881
879 DTYPE_WIDTH = [1, 2, 4, 8, 4, 8]
882 DTYPE_WIDTH = [1, 2, 4, 8, 4, 8]
880
883
881
884
882 def get_dtype_index(numpy_dtype):
885 def get_dtype_index(numpy_dtype):
883
886
884 index = None
887 index = None
885
888
886 for i in range(len(NUMPY_DTYPE_LIST)):
889 for i in range(len(NUMPY_DTYPE_LIST)):
887 if numpy_dtype == NUMPY_DTYPE_LIST[i]:
890 if numpy_dtype == NUMPY_DTYPE_LIST[i]:
888 index = i
891 index = i
889 break
892 break
890
893
891 return index
894 return index
892
895
893
896
894 def get_numpy_dtype(index):
897 def get_numpy_dtype(index):
895
898
896 return NUMPY_DTYPE_LIST[index]
899 return NUMPY_DTYPE_LIST[index]
897
900
898
901
899 def get_procflag_dtype(index):
902 def get_procflag_dtype(index):
900
903
901 return PROCFLAG_DTYPE_LIST[index]
904 return PROCFLAG_DTYPE_LIST[index]
902
905
903
906
904 def get_dtype_width(index):
907 def get_dtype_width(index):
905
908
906 return DTYPE_WIDTH[index]
909 return DTYPE_WIDTH[index]
@@ -1,5 +1,6
1 from .jroplot_voltage import *
1 from .jroplot_voltage import *
2 from .jroplot_spectra import *
2 from .jroplot_spectra import *
3 from .jroplot_heispectra import *
3 from .jroplot_heispectra import *
4 from .jroplot_correlation import *
4 from .jroplot_correlation import *
5 from .jroplot_parameters import *
5 from .jroplot_parameters import *
6 from .jroplot_voltage_lags import *
@@ -1,665 +1,669
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 # All rights reserved.
2 # All rights reserved.
3 #
3 #
4 # Distributed under the terms of the BSD 3-clause license.
4 # Distributed under the terms of the BSD 3-clause license.
5 """Base class to create plot operations
5 """Base class to create plot operations
6
6
7 """
7 """
8
8
9 import os
9 import os
10 import sys
10 import sys
11 import zmq
11 import zmq
12 import time
12 import time
13 import numpy
13 import numpy
14 import datetime
14 import datetime
15 from multiprocessing import Queue
15 from multiprocessing import Queue
16 from functools import wraps
16 from functools import wraps
17 from threading import Thread
17 from threading import Thread
18 import matplotlib
18 import matplotlib
19
19
20 if 'BACKEND' in os.environ:
20 if 'BACKEND' in os.environ:
21 matplotlib.use(os.environ['BACKEND'])
21 matplotlib.use(os.environ['BACKEND'])
22 elif 'linux' in sys.platform:
22 elif 'linux' in sys.platform:
23 matplotlib.use("TkAgg")
23 matplotlib.use("TkAgg")
24 elif 'darwin' in sys.platform:
24 elif 'darwin' in sys.platform:
25 matplotlib.use('WxAgg')
25 matplotlib.use('WxAgg')
26 else:
26 else:
27 from schainpy.utils import log
27 from schainpy.utils import log
28 log.warning('Using default Backend="Agg"', 'INFO')
28 log.warning('Using default Backend="Agg"', 'INFO')
29 matplotlib.use('Agg')
29 matplotlib.use('Agg')
30
30
31 import matplotlib.pyplot as plt
31 import matplotlib.pyplot as plt
32 from matplotlib.patches import Polygon
32 from matplotlib.patches import Polygon
33 from mpl_toolkits.axes_grid1 import make_axes_locatable
33 from mpl_toolkits.axes_grid1 import make_axes_locatable
34 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
34 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
35
35
36 from schainpy.model.data.jrodata import PlotterData
36 from schainpy.model.data.jrodata import PlotterData
37 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
37 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
38 from schainpy.utils import log
38 from schainpy.utils import log
39
39
40 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
40 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
41 blu_values = matplotlib.pyplot.get_cmap(
41 blu_values = matplotlib.pyplot.get_cmap(
42 'seismic_r', 20)(numpy.arange(20))[10:15]
42 'seismic_r', 20)(numpy.arange(20))[10:15]
43 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
43 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
44 'jro', numpy.vstack((blu_values, jet_values)))
44 'jro', numpy.vstack((blu_values, jet_values)))
45 matplotlib.pyplot.register_cmap(cmap=ncmap)
45 matplotlib.pyplot.register_cmap(cmap=ncmap)
46
46
47 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
47 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
48 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
48 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
49
49
50 EARTH_RADIUS = 6.3710e3
50 EARTH_RADIUS = 6.3710e3
51
51
52 def ll2xy(lat1, lon1, lat2, lon2):
52 def ll2xy(lat1, lon1, lat2, lon2):
53
53
54 p = 0.017453292519943295
54 p = 0.017453292519943295
55 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
55 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
56 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
56 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
57 r = 12742 * numpy.arcsin(numpy.sqrt(a))
57 r = 12742 * numpy.arcsin(numpy.sqrt(a))
58 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
58 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
59 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
59 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
60 theta = -theta + numpy.pi/2
60 theta = -theta + numpy.pi/2
61 return r*numpy.cos(theta), r*numpy.sin(theta)
61 return r*numpy.cos(theta), r*numpy.sin(theta)
62
62
63
63
64 def km2deg(km):
64 def km2deg(km):
65 '''
65 '''
66 Convert distance in km to degrees
66 Convert distance in km to degrees
67 '''
67 '''
68
68
69 return numpy.rad2deg(km/EARTH_RADIUS)
69 return numpy.rad2deg(km/EARTH_RADIUS)
70
70
71
71
72 def figpause(interval):
72 def figpause(interval):
73 backend = plt.rcParams['backend']
73 backend = plt.rcParams['backend']
74 if backend in matplotlib.rcsetup.interactive_bk:
74 if backend in matplotlib.rcsetup.interactive_bk:
75 figManager = matplotlib._pylab_helpers.Gcf.get_active()
75 figManager = matplotlib._pylab_helpers.Gcf.get_active()
76 if figManager is not None:
76 if figManager is not None:
77 canvas = figManager.canvas
77 canvas = figManager.canvas
78 if canvas.figure.stale:
78 if canvas.figure.stale:
79 canvas.draw()
79 canvas.draw()
80 try:
80 try:
81 canvas.start_event_loop(interval)
81 canvas.start_event_loop(interval)
82 except:
82 except:
83 pass
83 pass
84 return
84 return
85
85
86
86
87 def popup(message):
87 def popup(message):
88 '''
88 '''
89 '''
89 '''
90
90
91 fig = plt.figure(figsize=(12, 8), facecolor='r')
91 fig = plt.figure(figsize=(12, 8), facecolor='r')
92 text = '\n'.join([s.strip() for s in message.split(':')])
92 text = '\n'.join([s.strip() for s in message.split(':')])
93 fig.text(0.01, 0.5, text, ha='left', va='center',
93 fig.text(0.01, 0.5, text, ha='left', va='center',
94 size='20', weight='heavy', color='w')
94 size='20', weight='heavy', color='w')
95 fig.show()
95 fig.show()
96 figpause(1000)
96 figpause(1000)
97
97
98
98
99 class Throttle(object):
99 class Throttle(object):
100 '''
100 '''
101 Decorator that prevents a function from being called more than once every
101 Decorator that prevents a function from being called more than once every
102 time period.
102 time period.
103 To create a function that cannot be called more than once a minute, but
103 To create a function that cannot be called more than once a minute, but
104 will sleep until it can be called:
104 will sleep until it can be called:
105 @Throttle(minutes=1)
105 @Throttle(minutes=1)
106 def foo():
106 def foo():
107 pass
107 pass
108
108
109 for i in range(10):
109 for i in range(10):
110 foo()
110 foo()
111 print "This function has run %s times." % i
111 print "This function has run %s times." % i
112 '''
112 '''
113
113
114 def __init__(self, seconds=0, minutes=0, hours=0):
114 def __init__(self, seconds=0, minutes=0, hours=0):
115 self.throttle_period = datetime.timedelta(
115 self.throttle_period = datetime.timedelta(
116 seconds=seconds, minutes=minutes, hours=hours
116 seconds=seconds, minutes=minutes, hours=hours
117 )
117 )
118
118
119 self.time_of_last_call = datetime.datetime.min
119 self.time_of_last_call = datetime.datetime.min
120
120
121 def __call__(self, fn):
121 def __call__(self, fn):
122 @wraps(fn)
122 @wraps(fn)
123 def wrapper(*args, **kwargs):
123 def wrapper(*args, **kwargs):
124 coerce = kwargs.pop('coerce', None)
124 coerce = kwargs.pop('coerce', None)
125 if coerce:
125 if coerce:
126 self.time_of_last_call = datetime.datetime.now()
126 self.time_of_last_call = datetime.datetime.now()
127 return fn(*args, **kwargs)
127 return fn(*args, **kwargs)
128 else:
128 else:
129 now = datetime.datetime.now()
129 now = datetime.datetime.now()
130 time_since_last_call = now - self.time_of_last_call
130 time_since_last_call = now - self.time_of_last_call
131 time_left = self.throttle_period - time_since_last_call
131 time_left = self.throttle_period - time_since_last_call
132
132
133 if time_left > datetime.timedelta(seconds=0):
133 if time_left > datetime.timedelta(seconds=0):
134 return
134 return
135
135
136 self.time_of_last_call = datetime.datetime.now()
136 self.time_of_last_call = datetime.datetime.now()
137 return fn(*args, **kwargs)
137 return fn(*args, **kwargs)
138
138
139 return wrapper
139 return wrapper
140
140
141 def apply_throttle(value):
141 def apply_throttle(value):
142
142
143 @Throttle(seconds=value)
143 @Throttle(seconds=value)
144 def fnThrottled(fn):
144 def fnThrottled(fn):
145 fn()
145 fn()
146
146
147 return fnThrottled
147 return fnThrottled
148
148
149
149
150 @MPDecorator
150 @MPDecorator
151 class Plot(Operation):
151 class Plot(Operation):
152 """Base class for Schain plotting operations
152 """Base class for Schain plotting operations
153
153
154 This class should never be use directtly you must subclass a new operation,
154 This class should never be use directtly you must subclass a new operation,
155 children classes must be defined as follow:
155 children classes must be defined as follow:
156
156
157 ExamplePlot(Plot):
157 ExamplePlot(Plot):
158
158
159 CODE = 'code'
159 CODE = 'code'
160 colormap = 'jet'
160 colormap = 'jet'
161 plot_type = 'pcolor' # options are ('pcolor', 'pcolorbuffer', 'scatter', 'scatterbuffer')
161 plot_type = 'pcolor' # options are ('pcolor', 'pcolorbuffer', 'scatter', 'scatterbuffer')
162
162
163 def setup(self):
163 def setup(self):
164 pass
164 pass
165
165
166 def plot(self):
166 def plot(self):
167 pass
167 pass
168
168
169 """
169 """
170
170
171 CODE = 'Figure'
171 CODE = 'Figure'
172 colormap = 'jet'
172 colormap = 'jet'
173 bgcolor = 'white'
173 bgcolor = 'white'
174 buffering = True
174 buffering = True
175 __missing = 1E30
175 __missing = 1E30
176
176
177 __attrs__ = ['show', 'save', 'ymin', 'ymax', 'zmin', 'zmax', 'title',
177 __attrs__ = ['show', 'save', 'ymin', 'ymax', 'zmin', 'zmax', 'title',
178 'showprofile']
178 'showprofile']
179
179
180 def __init__(self):
180 def __init__(self):
181
181
182 Operation.__init__(self)
182 Operation.__init__(self)
183 self.isConfig = False
183 self.isConfig = False
184 self.isPlotConfig = False
184 self.isPlotConfig = False
185 self.save_time = 0
185 self.save_time = 0
186 self.sender_time = 0
186 self.sender_time = 0
187 self.data = None
187 self.data = None
188 self.firsttime = True
188 self.firsttime = True
189 self.sender_queue = Queue(maxsize=60)
189 self.sender_queue = Queue(maxsize=60)
190 self.plots_adjust = {'left': 0.125, 'right': 0.9, 'bottom': 0.15, 'top': 0.9, 'wspace': 0.2, 'hspace': 0.2}
190 self.plots_adjust = {'left': 0.125, 'right': 0.9, 'bottom': 0.15, 'top': 0.9, 'wspace': 0.2, 'hspace': 0.2}
191
191
192 def __fmtTime(self, x, pos):
192 def __fmtTime(self, x, pos):
193 '''
193 '''
194 '''
194 '''
195
195
196 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
196 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
197
197
198 def __setup(self, **kwargs):
198 def __setup(self, **kwargs):
199 '''
199 '''
200 Initialize variables
200 Initialize variables
201 '''
201 '''
202
202
203 self.figures = []
203 self.figures = []
204 self.axes = []
204 self.axes = []
205 self.cb_axes = []
205 self.cb_axes = []
206 self.localtime = kwargs.pop('localtime', True)
206 self.localtime = kwargs.pop('localtime', True)
207 self.show = kwargs.get('show', True)
207 self.show = kwargs.get('show', True)
208 self.save = kwargs.get('save', False)
208 self.save = kwargs.get('save', False)
209 self.save_period = kwargs.get('save_period', 0)
209 self.save_period = kwargs.get('save_period', 0)
210 self.colormap = kwargs.get('colormap', self.colormap)
210 self.colormap = kwargs.get('colormap', self.colormap)
211 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
211 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
212 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
212 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
213 self.colormaps = kwargs.get('colormaps', None)
213 self.colormaps = kwargs.get('colormaps', None)
214 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
214 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
215 self.showprofile = kwargs.get('showprofile', False)
215 self.showprofile = kwargs.get('showprofile', False)
216 self.title = kwargs.get('wintitle', self.CODE.upper())
216 self.title = kwargs.get('wintitle', self.CODE.upper())
217 self.cb_label = kwargs.get('cb_label', None)
217 self.cb_label = kwargs.get('cb_label', None)
218 self.cb_labels = kwargs.get('cb_labels', None)
218 self.cb_labels = kwargs.get('cb_labels', None)
219 self.labels = kwargs.get('labels', None)
219 self.labels = kwargs.get('labels', None)
220 self.xaxis = kwargs.get('xaxis', 'frequency')
220 self.xaxis = kwargs.get('xaxis', 'frequency')
221 self.zmin = kwargs.get('zmin', None)
221 self.zmin = kwargs.get('zmin', None)
222 self.zmax = kwargs.get('zmax', None)
222 self.zmax = kwargs.get('zmax', None)
223 self.zlimits = kwargs.get('zlimits', None)
223 self.zlimits = kwargs.get('zlimits', None)
224 self.xlimits = kwargs.get('xlimits', None)
225 self.xstep_given = kwargs.get('xstep_given', None)
226 self.ystep_given = kwargs.get('ystep_given', None)
227 self.autoxticks = kwargs.get('autoxticks', True)
224 self.xmin = kwargs.get('xmin', None)
228 self.xmin = kwargs.get('xmin', None)
225 self.xmax = kwargs.get('xmax', None)
229 self.xmax = kwargs.get('xmax', None)
226 self.xrange = kwargs.get('xrange', 12)
230 self.xrange = kwargs.get('xrange', 12)
227 self.xscale = kwargs.get('xscale', None)
231 self.xscale = kwargs.get('xscale', None)
228 self.ymin = kwargs.get('ymin', None)
232 self.ymin = kwargs.get('ymin', None)
229 self.ymax = kwargs.get('ymax', None)
233 self.ymax = kwargs.get('ymax', None)
230 self.yscale = kwargs.get('yscale', None)
234 self.yscale = kwargs.get('yscale', None)
231 self.xlabel = kwargs.get('xlabel', None)
235 self.xlabel = kwargs.get('xlabel', None)
232 self.attr_time = kwargs.get('attr_time', 'utctime')
236 self.attr_time = kwargs.get('attr_time', 'utctime')
233 self.decimation = kwargs.get('decimation', None)
237 self.decimation = kwargs.get('decimation', None)
234 self.showSNR = kwargs.get('showSNR', False)
238 self.showSNR = kwargs.get('showSNR', False)
235 self.oneFigure = kwargs.get('oneFigure', True)
239 self.oneFigure = kwargs.get('oneFigure', True)
236 self.width = kwargs.get('width', None)
240 self.width = kwargs.get('width', None)
237 self.height = kwargs.get('height', None)
241 self.height = kwargs.get('height', None)
238 self.colorbar = kwargs.get('colorbar', True)
242 self.colorbar = kwargs.get('colorbar', True)
239 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
243 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
240 self.channels = kwargs.get('channels', None)
244 self.channels = kwargs.get('channels', None)
241 self.titles = kwargs.get('titles', [])
245 self.titles = kwargs.get('titles', [])
242 self.polar = False
246 self.polar = False
243 self.type = kwargs.get('type', 'iq')
247 self.type = kwargs.get('type', 'iq')
244 self.grid = kwargs.get('grid', False)
248 self.grid = kwargs.get('grid', False)
245 self.pause = kwargs.get('pause', False)
249 self.pause = kwargs.get('pause', False)
246 self.save_code = kwargs.get('save_code', self.CODE)
250 self.save_code = kwargs.get('save_code', self.CODE)
247 self.throttle = kwargs.get('throttle', 0)
251 self.throttle = kwargs.get('throttle', 0)
248 self.exp_code = kwargs.get('exp_code', None)
252 self.exp_code = kwargs.get('exp_code', None)
249 self.server = kwargs.get('server', False)
253 self.server = kwargs.get('server', False)
250 self.sender_period = kwargs.get('sender_period', 60)
254 self.sender_period = kwargs.get('sender_period', 60)
251 self.tag = kwargs.get('tag', '')
255 self.tag = kwargs.get('tag', '')
252 self.height_index = kwargs.get('height_index', None)
256 self.height_index = kwargs.get('height_index', None)
253 self.__throttle_plot = apply_throttle(self.throttle)
257 self.__throttle_plot = apply_throttle(self.throttle)
254 self.data = PlotterData(
258 self.data = PlotterData(
255 self.CODE, self.throttle, self.exp_code, self.localtime, self.buffering, snr=self.showSNR)
259 self.CODE, self.throttle, self.exp_code, self.localtime, self.buffering, snr=self.showSNR)
256
260
257 if self.server:
261 if self.server:
258 if not self.server.startswith('tcp://'):
262 if not self.server.startswith('tcp://'):
259 self.server = 'tcp://{}'.format(self.server)
263 self.server = 'tcp://{}'.format(self.server)
260 log.success(
264 log.success(
261 'Sending to server: {}'.format(self.server),
265 'Sending to server: {}'.format(self.server),
262 self.name
266 self.name
263 )
267 )
264
268
265 def __setup_plot(self):
269 def __setup_plot(self):
266 '''
270 '''
267 Common setup for all figures, here figures and axes are created
271 Common setup for all figures, here figures and axes are created
268 '''
272 '''
269
273
270 self.setup()
274 self.setup()
271
275
272 self.time_label = 'LT' if self.localtime else 'UTC'
276 self.time_label = 'LT' if self.localtime else 'UTC'
273
277
274 if self.width is None:
278 if self.width is None:
275 self.width = 8
279 self.width = 8
276
280
277 self.figures = []
281 self.figures = []
278 self.axes = []
282 self.axes = []
279 self.cb_axes = []
283 self.cb_axes = []
280 self.pf_axes = []
284 self.pf_axes = []
281 self.cmaps = []
285 self.cmaps = []
282
286
283 size = '15%' if self.ncols == 1 else '30%'
287 size = '15%' if self.ncols == 1 else '30%'
284 pad = '4%' if self.ncols == 1 else '8%'
288 pad = '4%' if self.ncols == 1 else '8%'
285
289
286 if self.oneFigure:
290 if self.oneFigure:
287 if self.height is None:
291 if self.height is None:
288 self.height = 1.4 * self.nrows + 1
292 self.height = 1.4 * self.nrows + 1
289 fig = plt.figure(figsize=(self.width, self.height),
293 fig = plt.figure(figsize=(self.width, self.height),
290 edgecolor='k',
294 edgecolor='k',
291 facecolor='w')
295 facecolor='w')
292 self.figures.append(fig)
296 self.figures.append(fig)
293 for n in range(self.nplots):
297 for n in range(self.nplots):
294 ax = fig.add_subplot(self.nrows, self.ncols,
298 ax = fig.add_subplot(self.nrows, self.ncols,
295 n + 1, polar=self.polar)
299 n + 1, polar=self.polar)
296 ax.tick_params(labelsize=8)
300 ax.tick_params(labelsize=8)
297 ax.firsttime = True
301 ax.firsttime = True
298 ax.index = 0
302 ax.index = 0
299 ax.press = None
303 ax.press = None
300 self.axes.append(ax)
304 self.axes.append(ax)
301 if self.showprofile:
305 if self.showprofile:
302 cax = self.__add_axes(ax, size=size, pad=pad)
306 cax = self.__add_axes(ax, size=size, pad=pad)
303 cax.tick_params(labelsize=8)
307 cax.tick_params(labelsize=8)
304 self.pf_axes.append(cax)
308 self.pf_axes.append(cax)
305 else:
309 else:
306 if self.height is None:
310 if self.height is None:
307 self.height = 3
311 self.height = 3
308 for n in range(self.nplots):
312 for n in range(self.nplots):
309 fig = plt.figure(figsize=(self.width, self.height),
313 fig = plt.figure(figsize=(self.width, self.height),
310 edgecolor='k',
314 edgecolor='k',
311 facecolor='w')
315 facecolor='w')
312 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
316 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
313 ax.tick_params(labelsize=8)
317 ax.tick_params(labelsize=8)
314 ax.firsttime = True
318 ax.firsttime = True
315 ax.index = 0
319 ax.index = 0
316 ax.press = None
320 ax.press = None
317 self.figures.append(fig)
321 self.figures.append(fig)
318 self.axes.append(ax)
322 self.axes.append(ax)
319 if self.showprofile:
323 if self.showprofile:
320 cax = self.__add_axes(ax, size=size, pad=pad)
324 cax = self.__add_axes(ax, size=size, pad=pad)
321 cax.tick_params(labelsize=8)
325 cax.tick_params(labelsize=8)
322 self.pf_axes.append(cax)
326 self.pf_axes.append(cax)
323
327
324 for n in range(self.nrows):
328 for n in range(self.nrows):
325 if self.colormaps is not None:
329 if self.colormaps is not None:
326 cmap = plt.get_cmap(self.colormaps[n])
330 cmap = plt.get_cmap(self.colormaps[n])
327 else:
331 else:
328 cmap = plt.get_cmap(self.colormap)
332 cmap = plt.get_cmap(self.colormap)
329 cmap.set_bad(self.bgcolor, 1.)
333 cmap.set_bad(self.bgcolor, 1.)
330 self.cmaps.append(cmap)
334 self.cmaps.append(cmap)
331
335
332 def __add_axes(self, ax, size='30%', pad='8%'):
336 def __add_axes(self, ax, size='30%', pad='8%'):
333 '''
337 '''
334 Add new axes to the given figure
338 Add new axes to the given figure
335 '''
339 '''
336 divider = make_axes_locatable(ax)
340 divider = make_axes_locatable(ax)
337 nax = divider.new_horizontal(size=size, pad=pad)
341 nax = divider.new_horizontal(size=size, pad=pad)
338 ax.figure.add_axes(nax)
342 ax.figure.add_axes(nax)
339 return nax
343 return nax
340
344
341 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
345 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
342 '''
346 '''
343 Create a masked array for missing data
347 Create a masked array for missing data
344 '''
348 '''
345 if x_buffer.shape[0] < 2:
349 if x_buffer.shape[0] < 2:
346 return x_buffer, y_buffer, z_buffer
350 return x_buffer, y_buffer, z_buffer
347
351
348 deltas = x_buffer[1:] - x_buffer[0:-1]
352 deltas = x_buffer[1:] - x_buffer[0:-1]
349 x_median = numpy.median(deltas)
353 x_median = numpy.median(deltas)
350
354
351 index = numpy.where(deltas > 5 * x_median)
355 index = numpy.where(deltas > 5 * x_median)
352
356
353 if len(index[0]) != 0:
357 if len(index[0]) != 0:
354 z_buffer[::, index[0], ::] = self.__missing
358 z_buffer[::, index[0], ::] = self.__missing
355 z_buffer = numpy.ma.masked_inside(z_buffer,
359 z_buffer = numpy.ma.masked_inside(z_buffer,
356 0.99 * self.__missing,
360 0.99 * self.__missing,
357 1.01 * self.__missing)
361 1.01 * self.__missing)
358
362
359 return x_buffer, y_buffer, z_buffer
363 return x_buffer, y_buffer, z_buffer
360
364
361 def decimate(self):
365 def decimate(self):
362
366
363 # dx = int(len(self.x)/self.__MAXNUMX) + 1
367 # dx = int(len(self.x)/self.__MAXNUMX) + 1
364 dy = int(len(self.y) / self.decimation) + 1
368 dy = int(len(self.y) / self.decimation) + 1
365
369
366 # x = self.x[::dx]
370 # x = self.x[::dx]
367 x = self.x
371 x = self.x
368 y = self.y[::dy]
372 y = self.y[::dy]
369 z = self.z[::, ::, ::dy]
373 z = self.z[::, ::, ::dy]
370
374
371 return x, y, z
375 return x, y, z
372
376
373 def format(self):
377 def format(self):
374 '''
378 '''
375 Set min and max values, labels, ticks and titles
379 Set min and max values, labels, ticks and titles
376 '''
380 '''
377
381
378 for n, ax in enumerate(self.axes):
382 for n, ax in enumerate(self.axes):
379 if ax.firsttime:
383 if ax.firsttime:
380 if self.xaxis != 'time':
384 if self.xaxis != 'time':
381 xmin = self.xmin
385 xmin = self.xmin
382 xmax = self.xmax
386 xmax = self.xmax
383 else:
387 else:
384 xmin = self.tmin
388 xmin = self.tmin
385 xmax = self.tmin + self.xrange*60*60
389 xmax = self.tmin + self.xrange*60*60
386 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
390 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
387 ax.xaxis.set_major_locator(LinearLocator(9))
391 ax.xaxis.set_major_locator(LinearLocator(9))
388 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
392 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
389 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
393 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
390 ax.set_facecolor(self.bgcolor)
394 ax.set_facecolor(self.bgcolor)
391 if self.xscale:
395 if self.xscale:
392 ax.xaxis.set_major_formatter(FuncFormatter(
396 ax.xaxis.set_major_formatter(FuncFormatter(
393 lambda x, pos: '{0:g}'.format(x*self.xscale)))
397 lambda x, pos: '{0:g}'.format(x*self.xscale)))
394 if self.yscale:
398 if self.yscale:
395 ax.yaxis.set_major_formatter(FuncFormatter(
399 ax.yaxis.set_major_formatter(FuncFormatter(
396 lambda x, pos: '{0:g}'.format(x*self.yscale)))
400 lambda x, pos: '{0:g}'.format(x*self.yscale)))
397 if self.xlabel is not None:
401 if self.xlabel is not None:
398 ax.set_xlabel(self.xlabel)
402 ax.set_xlabel(self.xlabel)
399 if self.ylabel is not None:
403 if self.ylabel is not None:
400 ax.set_ylabel(self.ylabel)
404 ax.set_ylabel(self.ylabel)
401 if self.showprofile:
405 if self.showprofile:
402 self.pf_axes[n].set_ylim(ymin, ymax)
406 self.pf_axes[n].set_ylim(ymin, ymax)
403 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
407 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
404 self.pf_axes[n].set_xlabel('dB')
408 self.pf_axes[n].set_xlabel('dB')
405 self.pf_axes[n].grid(b=True, axis='x')
409 self.pf_axes[n].grid(b=True, axis='x')
406 [tick.set_visible(False)
410 [tick.set_visible(False)
407 for tick in self.pf_axes[n].get_yticklabels()]
411 for tick in self.pf_axes[n].get_yticklabels()]
408 if self.colorbar:
412 if self.colorbar:
409 ax.cbar = plt.colorbar(
413 ax.cbar = plt.colorbar(
410 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
414 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
411 ax.cbar.ax.tick_params(labelsize=8)
415 ax.cbar.ax.tick_params(labelsize=8)
412 ax.cbar.ax.press = None
416 ax.cbar.ax.press = None
413 if self.cb_label:
417 if self.cb_label:
414 ax.cbar.set_label(self.cb_label, size=8)
418 ax.cbar.set_label(self.cb_label, size=8)
415 elif self.cb_labels:
419 elif self.cb_labels:
416 ax.cbar.set_label(self.cb_labels[n], size=8)
420 ax.cbar.set_label(self.cb_labels[n], size=8)
417 else:
421 else:
418 ax.cbar = None
422 ax.cbar = None
419 ax.set_xlim(xmin, xmax)
423 ax.set_xlim(xmin, xmax)
420 ax.set_ylim(ymin, ymax)
424 ax.set_ylim(ymin, ymax)
421 ax.firsttime = False
425 ax.firsttime = False
422 if self.grid:
426 if self.grid:
423 ax.grid(True)
427 ax.grid(True)
424 if not self.polar:
428 if not self.polar:
425 ax.set_title('{} {} {}'.format(
429 ax.set_title('{} {} {}'.format(
426 self.titles[n],
430 self.titles[n],
427 self.getDateTime(self.data.max_time).strftime(
431 self.getDateTime(self.data.max_time).strftime(
428 '%Y-%m-%d %H:%M:%S'),
432 '%Y-%m-%d %H:%M:%S'),
429 self.time_label),
433 self.time_label),
430 size=8)
434 size=8)
431 else:
435 else:
432 ax.set_title('{}'.format(self.titles[n]), size=8)
436 ax.set_title('{}'.format(self.titles[n]), size=8)
433 ax.set_ylim(0, 90)
437 ax.set_ylim(0, 90)
434 ax.set_yticks(numpy.arange(0, 90, 20))
438 ax.set_yticks(numpy.arange(0, 90, 20))
435 ax.yaxis.labelpad = 40
439 ax.yaxis.labelpad = 40
436
440
437 if self.firsttime:
441 if self.firsttime:
438 for n, fig in enumerate(self.figures):
442 for n, fig in enumerate(self.figures):
439 fig.subplots_adjust(**self.plots_adjust)
443 fig.subplots_adjust(**self.plots_adjust)
440 self.firsttime = False
444 self.firsttime = False
441
445
442 def clear_figures(self):
446 def clear_figures(self):
443 '''
447 '''
444 Reset axes for redraw plots
448 Reset axes for redraw plots
445 '''
449 '''
446
450
447 for ax in self.axes+self.pf_axes+self.cb_axes:
451 for ax in self.axes+self.pf_axes+self.cb_axes:
448 ax.clear()
452 ax.clear()
449 ax.firsttime = True
453 ax.firsttime = True
450 if hasattr(ax, 'cbar') and ax.cbar:
454 if hasattr(ax, 'cbar') and ax.cbar:
451 ax.cbar.remove()
455 ax.cbar.remove()
452
456
453 def __plot(self):
457 def __plot(self):
454 '''
458 '''
455 Main function to plot, format and save figures
459 Main function to plot, format and save figures
456 '''
460 '''
457
461
458 self.plot()
462 self.plot()
459 self.format()
463 self.format()
460
464
461 for n, fig in enumerate(self.figures):
465 for n, fig in enumerate(self.figures):
462 if self.nrows == 0 or self.nplots == 0:
466 if self.nrows == 0 or self.nplots == 0:
463 log.warning('No data', self.name)
467 log.warning('No data', self.name)
464 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
468 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
465 fig.canvas.manager.set_window_title(self.CODE)
469 fig.canvas.manager.set_window_title(self.CODE)
466 continue
470 continue
467
471
468 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
472 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
469 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
473 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
470 fig.canvas.draw()
474 fig.canvas.draw()
471 if self.show:
475 if self.show:
472 fig.show()
476 fig.show()
473 figpause(0.01)
477 figpause(0.01)
474
478
475 if self.save:
479 if self.save:
476 self.save_figure(n)
480 self.save_figure(n)
477
481
478 if self.server:
482 if self.server:
479 self.send_to_server()
483 self.send_to_server()
480
484
481 def save_figure(self, n):
485 def save_figure(self, n):
482 '''
486 '''
483 '''
487 '''
484
488
485 if (self.data.tm - self.save_time) <= self.save_period:
489 if (self.data.tm - self.save_time) <= self.save_period:
486 return
490 return
487
491
488 self.save_time = self.data.tm
492 self.save_time = self.data.tm
489
493
490 fig = self.figures[n]
494 fig = self.figures[n]
491
495
492 figname = os.path.join(
496 figname = os.path.join(
493 self.save,
497 self.save,
494 self.save_code,
498 self.save_code,
495 '{}_{}.png'.format(
499 '{}_{}.png'.format(
496 self.save_code,
500 self.save_code,
497 self.getDateTime(self.data.max_time).strftime(
501 self.getDateTime(self.data.max_time).strftime(
498 '%Y%m%d_%H%M%S'
502 '%Y%m%d_%H%M%S'
499 ),
503 ),
500 )
504 )
501 )
505 )
502 log.log('Saving figure: {}'.format(figname), self.name)
506 log.log('Saving figure: {}'.format(figname), self.name)
503 if not os.path.isdir(os.path.dirname(figname)):
507 if not os.path.isdir(os.path.dirname(figname)):
504 os.makedirs(os.path.dirname(figname))
508 os.makedirs(os.path.dirname(figname))
505 fig.savefig(figname)
509 fig.savefig(figname)
506
510
507 if self.throttle == 0:
511 if self.throttle == 0:
508 figname = os.path.join(
512 figname = os.path.join(
509 self.save,
513 self.save,
510 '{}_{}.png'.format(
514 '{}_{}.png'.format(
511 self.save_code,
515 self.save_code,
512 self.getDateTime(self.data.min_time).strftime(
516 self.getDateTime(self.data.min_time).strftime(
513 '%Y%m%d'
517 '%Y%m%d'
514 ),
518 ),
515 )
519 )
516 )
520 )
517 fig.savefig(figname)
521 fig.savefig(figname)
518
522
519 def send_to_server(self):
523 def send_to_server(self):
520 '''
524 '''
521 '''
525 '''
522
526
523 interval = self.data.tm - self.sender_time
527 interval = self.data.tm - self.sender_time
524 if interval < self.sender_period:
528 if interval < self.sender_period:
525 return
529 return
526
530
527 self.sender_time = self.data.tm
531 self.sender_time = self.data.tm
528
532
529 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
533 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
530 for attr in attrs:
534 for attr in attrs:
531 value = getattr(self, attr)
535 value = getattr(self, attr)
532 if value:
536 if value:
533 if isinstance(value, (numpy.float32, numpy.float64)):
537 if isinstance(value, (numpy.float32, numpy.float64)):
534 value = round(float(value), 2)
538 value = round(float(value), 2)
535 self.data.meta[attr] = value
539 self.data.meta[attr] = value
536 if self.colormap == 'jet':
540 if self.colormap == 'jet':
537 self.data.meta['colormap'] = 'Jet'
541 self.data.meta['colormap'] = 'Jet'
538 elif 'RdBu' in self.colormap:
542 elif 'RdBu' in self.colormap:
539 self.data.meta['colormap'] = 'RdBu'
543 self.data.meta['colormap'] = 'RdBu'
540 else:
544 else:
541 self.data.meta['colormap'] = 'Viridis'
545 self.data.meta['colormap'] = 'Viridis'
542 self.data.meta['interval'] = int(interval)
546 self.data.meta['interval'] = int(interval)
543
547
544 try:
548 try:
545 self.sender_queue.put(self.data.tm, block=False)
549 self.sender_queue.put(self.data.tm, block=False)
546 except:
550 except:
547 tm = self.sender_queue.get()
551 tm = self.sender_queue.get()
548 self.sender_queue.put(self.data.tm)
552 self.sender_queue.put(self.data.tm)
549
553
550 while True:
554 while True:
551 if self.sender_queue.empty():
555 if self.sender_queue.empty():
552 break
556 break
553 tm = self.sender_queue.get()
557 tm = self.sender_queue.get()
554 try:
558 try:
555 msg = self.data.jsonify(tm, self.save_code, self.plot_type)
559 msg = self.data.jsonify(tm, self.save_code, self.plot_type)
556 except:
560 except:
557 continue
561 continue
558 self.socket.send_string(msg)
562 self.socket.send_string(msg)
559 socks = dict(self.poll.poll(5000))
563 socks = dict(self.poll.poll(5000))
560 if socks.get(self.socket) == zmq.POLLIN:
564 if socks.get(self.socket) == zmq.POLLIN:
561 reply = self.socket.recv_string()
565 reply = self.socket.recv_string()
562 if reply == 'ok':
566 if reply == 'ok':
563 log.log("Response from server ok", self.name)
567 log.log("Response from server ok", self.name)
564 time.sleep(0.2)
568 time.sleep(0.2)
565 continue
569 continue
566 else:
570 else:
567 log.warning(
571 log.warning(
568 "Malformed reply from server: {}".format(reply), self.name)
572 "Malformed reply from server: {}".format(reply), self.name)
569 else:
573 else:
570 log.warning(
574 log.warning(
571 "No response from server, retrying...", self.name)
575 "No response from server, retrying...", self.name)
572 self.sender_queue.put(self.data.tm)
576 self.sender_queue.put(self.data.tm)
573 self.socket.setsockopt(zmq.LINGER, 0)
577 self.socket.setsockopt(zmq.LINGER, 0)
574 self.socket.close()
578 self.socket.close()
575 self.poll.unregister(self.socket)
579 self.poll.unregister(self.socket)
576 time.sleep(0.1)
580 time.sleep(0.1)
577 self.socket = self.context.socket(zmq.REQ)
581 self.socket = self.context.socket(zmq.REQ)
578 self.socket.connect(self.server)
582 self.socket.connect(self.server)
579 self.poll.register(self.socket, zmq.POLLIN)
583 self.poll.register(self.socket, zmq.POLLIN)
580 break
584 break
581
585
582 def setup(self):
586 def setup(self):
583 '''
587 '''
584 This method should be implemented in the child class, the following
588 This method should be implemented in the child class, the following
585 attributes should be set:
589 attributes should be set:
586
590
587 self.nrows: number of rows
591 self.nrows: number of rows
588 self.ncols: number of cols
592 self.ncols: number of cols
589 self.nplots: number of plots (channels or pairs)
593 self.nplots: number of plots (channels or pairs)
590 self.ylabel: label for Y axes
594 self.ylabel: label for Y axes
591 self.titles: list of axes title
595 self.titles: list of axes title
592
596
593 '''
597 '''
594 raise NotImplementedError
598 raise NotImplementedError
595
599
596 def plot(self):
600 def plot(self):
597 '''
601 '''
598 Must be defined in the child class
602 Must be defined in the child class
599 '''
603 '''
600 raise NotImplementedError
604 raise NotImplementedError
601
605
602 def run(self, dataOut, **kwargs):
606 def run(self, dataOut, **kwargs):
603 '''
607 '''
604 Main plotting routine
608 Main plotting routine
605 '''
609 '''
606
610 print("time_inside_plot: ",dataOut.datatime)
611 print(dataOut.flagNoData)
607 if self.isConfig is False:
612 if self.isConfig is False:
608 self.__setup(**kwargs)
613 self.__setup(**kwargs)
609
614
610 if self.localtime:
615 if self.localtime:
611 self.getDateTime = datetime.datetime.fromtimestamp
616 self.getDateTime = datetime.datetime.fromtimestamp
612 else:
617 else:
613 self.getDateTime = datetime.datetime.utcfromtimestamp
618 self.getDateTime = datetime.datetime.utcfromtimestamp
614
619
615 self.data.setup()
620 self.data.setup()
616 self.isConfig = True
621 self.isConfig = True
617 if self.server:
622 if self.server:
618 self.context = zmq.Context()
623 self.context = zmq.Context()
619 self.socket = self.context.socket(zmq.REQ)
624 self.socket = self.context.socket(zmq.REQ)
620 self.socket.connect(self.server)
625 self.socket.connect(self.server)
621 self.poll = zmq.Poller()
626 self.poll = zmq.Poller()
622 self.poll.register(self.socket, zmq.POLLIN)
627 self.poll.register(self.socket, zmq.POLLIN)
623
628
624 tm = getattr(dataOut, self.attr_time)
629 tm = getattr(dataOut, self.attr_time)
625
630
626 if self.data and 'time' in self.xaxis and (tm - self.tmin) >= self.xrange*60*60:
631 if self.data and 'time' in self.xaxis and (tm - self.tmin) >= self.xrange*60*60:
627 self.save_time = tm
632 self.save_time = tm
628 self.__plot()
633 self.__plot()
629 self.tmin += self.xrange*60*60
634 self.tmin += self.xrange*60*60
630 self.data.setup()
635 self.data.setup()
631 self.clear_figures()
636 self.clear_figures()
632
637
633 self.data.update(dataOut, tm)
638 self.data.update(dataOut, tm)
634
639
635 if self.isPlotConfig is False:
640 if self.isPlotConfig is False:
636 self.__setup_plot()
641 self.__setup_plot()
637 self.isPlotConfig = True
642 self.isPlotConfig = True
638 if self.xaxis == 'time':
643 if self.xaxis == 'time':
639 dt = self.getDateTime(tm)
644 dt = self.getDateTime(tm)
640 if self.xmin is None:
645 if self.xmin is None:
641 self.tmin = tm
646 self.tmin = tm
642 self.xmin = dt.hour
647 self.xmin = dt.hour
643 minutes = (self.xmin-int(self.xmin)) * 60
648 minutes = (self.xmin-int(self.xmin)) * 60
644 seconds = (minutes - int(minutes)) * 60
649 seconds = (minutes - int(minutes)) * 60
645 self.tmin = (dt.replace(hour=int(self.xmin), minute=int(minutes), second=int(seconds)) -
650 self.tmin = (dt.replace(hour=int(self.xmin), minute=int(minutes), second=int(seconds)) -
646 datetime.datetime(1970, 1, 1)).total_seconds()
651 datetime.datetime(1970, 1, 1)).total_seconds()
647 if self.localtime:
652 if self.localtime:
648 self.tmin += time.timezone
653 self.tmin += time.timezone
649
654
650 if self.xmin is not None and self.xmax is not None:
655 if self.xmin is not None and self.xmax is not None:
651 self.xrange = self.xmax - self.xmin
656 self.xrange = self.xmax - self.xmin
652
657
653 if self.throttle == 0:
658 if self.throttle == 0:
654 self.__plot()
659 self.__plot()
655 else:
660 else:
656 self.__throttle_plot(self.__plot)#, coerce=coerce)
661 self.__throttle_plot(self.__plot)#, coerce=coerce)
657
662
658 def close(self):
663 def close(self):
659
664
660 if self.data and not self.data.flagNoData:
665 if self.data and not self.data.flagNoData:
661 self.save_time = self.data.tm
666 self.save_time = self.data.tm
662 self.__plot()
667 self.__plot()
663 if self.data and not self.data.flagNoData and self.pause:
668 if self.data and not self.data.flagNoData and self.pause:
664 figpause(10)
669 figpause(10)
665
@@ -1,339 +1,347
1 import os
1 import os
2 import datetime
2 import datetime
3 import numpy
3 import numpy
4
4
5 from schainpy.model.graphics.jroplot_base import Plot, plt
5 from schainpy.model.graphics.jroplot_base import Plot, plt
6 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot
6 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot
7 from schainpy.utils import log
7 from schainpy.utils import log
8
8
9 EARTH_RADIUS = 6.3710e3
9 EARTH_RADIUS = 6.3710e3
10
10
11
11
12 def ll2xy(lat1, lon1, lat2, lon2):
12 def ll2xy(lat1, lon1, lat2, lon2):
13
13
14 p = 0.017453292519943295
14 p = 0.017453292519943295
15 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
15 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
16 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
16 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
17 r = 12742 * numpy.arcsin(numpy.sqrt(a))
17 r = 12742 * numpy.arcsin(numpy.sqrt(a))
18 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
18 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
19 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
19 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
20 theta = -theta + numpy.pi/2
20 theta = -theta + numpy.pi/2
21 return r*numpy.cos(theta), r*numpy.sin(theta)
21 return r*numpy.cos(theta), r*numpy.sin(theta)
22
22
23
23
24 def km2deg(km):
24 def km2deg(km):
25 '''
25 '''
26 Convert distance in km to degrees
26 Convert distance in km to degrees
27 '''
27 '''
28
28
29 return numpy.rad2deg(km/EARTH_RADIUS)
29 return numpy.rad2deg(km/EARTH_RADIUS)
30
30
31
31
32
32
33 class SpectralMomentsPlot(SpectraPlot):
33 class SpectralMomentsPlot(SpectraPlot):
34 '''
34 '''
35 Plot for Spectral Moments
35 Plot for Spectral Moments
36 '''
36 '''
37 CODE = 'spc_moments'
37 CODE = 'spc_moments'
38 colormap = 'jet'
38 colormap = 'jet'
39 plot_type = 'pcolor'
39 plot_type = 'pcolor'
40
40
41 class SpectralFitObliquePlot(SpectraPlot):
42 '''
43 Plot for Spectral Oblique
44 '''
45 CODE = 'spc_moments'
46 colormap = 'jet'
47 plot_type = 'pcolor'
48
49
41
50
42 class SnrPlot(RTIPlot):
51 class SnrPlot(RTIPlot):
43 '''
52 '''
44 Plot for SNR Data
53 Plot for SNR Data
45 '''
54 '''
46
55
47 CODE = 'snr'
56 CODE = 'snr'
48 colormap = 'jet'
57 colormap = 'jet'
49
58
50
59
51 class DopplerPlot(RTIPlot):
60 class DopplerPlot(RTIPlot):
52 '''
61 '''
53 Plot for DOPPLER Data (1st moment)
62 Plot for DOPPLER Data (1st moment)
54 '''
63 '''
55
64
56 CODE = 'dop'
65 CODE = 'dop'
57 colormap = 'jet'
66 colormap = 'jet'
58
67
59
68
60 class PowerPlot(RTIPlot):
69 class PowerPlot(RTIPlot):
61 '''
70 '''
62 Plot for Power Data (0 moment)
71 Plot for Power Data (0 moment)
63 '''
72 '''
64
73
65 CODE = 'pow'
74 CODE = 'pow'
66 colormap = 'jet'
75 colormap = 'jet'
67
76
68
77
69 class SpectralWidthPlot(RTIPlot):
78 class SpectralWidthPlot(RTIPlot):
70 '''
79 '''
71 Plot for Spectral Width Data (2nd moment)
80 Plot for Spectral Width Data (2nd moment)
72 '''
81 '''
73
82
74 CODE = 'width'
83 CODE = 'width'
75 colormap = 'jet'
84 colormap = 'jet'
76
85
77
86
78 class SkyMapPlot(Plot):
87 class SkyMapPlot(Plot):
79 '''
88 '''
80 Plot for meteors detection data
89 Plot for meteors detection data
81 '''
90 '''
82
91
83 CODE = 'param'
92 CODE = 'param'
84
93
85 def setup(self):
94 def setup(self):
86
95
87 self.ncols = 1
96 self.ncols = 1
88 self.nrows = 1
97 self.nrows = 1
89 self.width = 7.2
98 self.width = 7.2
90 self.height = 7.2
99 self.height = 7.2
91 self.nplots = 1
100 self.nplots = 1
92 self.xlabel = 'Zonal Zenith Angle (deg)'
101 self.xlabel = 'Zonal Zenith Angle (deg)'
93 self.ylabel = 'Meridional Zenith Angle (deg)'
102 self.ylabel = 'Meridional Zenith Angle (deg)'
94 self.polar = True
103 self.polar = True
95 self.ymin = -180
104 self.ymin = -180
96 self.ymax = 180
105 self.ymax = 180
97 self.colorbar = False
106 self.colorbar = False
98
107
99 def plot(self):
108 def plot(self):
100
109
101 arrayParameters = numpy.concatenate(self.data['param'])
110 arrayParameters = numpy.concatenate(self.data['param'])
102 error = arrayParameters[:, -1]
111 error = arrayParameters[:, -1]
103 indValid = numpy.where(error == 0)[0]
112 indValid = numpy.where(error == 0)[0]
104 finalMeteor = arrayParameters[indValid, :]
113 finalMeteor = arrayParameters[indValid, :]
105 finalAzimuth = finalMeteor[:, 3]
114 finalAzimuth = finalMeteor[:, 3]
106 finalZenith = finalMeteor[:, 4]
115 finalZenith = finalMeteor[:, 4]
107
116
108 x = finalAzimuth * numpy.pi / 180
117 x = finalAzimuth * numpy.pi / 180
109 y = finalZenith
118 y = finalZenith
110
119
111 ax = self.axes[0]
120 ax = self.axes[0]
112
121
113 if ax.firsttime:
122 if ax.firsttime:
114 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
123 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
115 else:
124 else:
116 ax.plot.set_data(x, y)
125 ax.plot.set_data(x, y)
117
126
118 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
127 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
119 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
128 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
120 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
129 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
121 dt2,
130 dt2,
122 len(x))
131 len(x))
123 self.titles[0] = title
132 self.titles[0] = title
124
133
125
134
126 class ParametersPlot(RTIPlot):
135 class ParametersPlot(RTIPlot):
127 '''
136 '''
128 Plot for data_param object
137 Plot for data_param object
129 '''
138 '''
130
139
131 CODE = 'param'
140 CODE = 'param'
132 colormap = 'seismic'
141 colormap = 'seismic'
133
142
134 def setup(self):
143 def setup(self):
135 self.xaxis = 'time'
144 self.xaxis = 'time'
136 self.ncols = 1
145 self.ncols = 1
137 self.nrows = self.data.shape(self.CODE)[0]
146 self.nrows = self.data.shape(self.CODE)[0]
138 self.nplots = self.nrows
147 self.nplots = self.nrows
139 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
148 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
140
149
141 if not self.xlabel:
150 if not self.xlabel:
142 self.xlabel = 'Time'
151 self.xlabel = 'Time'
143
152
144 if self.showSNR:
153 if self.showSNR:
145 self.nrows += 1
154 self.nrows += 1
146 self.nplots += 1
155 self.nplots += 1
147
156
148 self.ylabel = 'Height [km]'
157 self.ylabel = 'Height [km]'
149 if not self.titles:
158 if not self.titles:
150 self.titles = self.data.parameters \
159 self.titles = self.data.parameters \
151 if self.data.parameters else ['Param {}'.format(x) for x in range(self.nrows)]
160 if self.data.parameters else ['Param {}'.format(x) for x in range(self.nrows)]
152 if self.showSNR:
161 if self.showSNR:
153 self.titles.append('SNR')
162 self.titles.append('SNR')
154
163
155 def plot(self):
164 def plot(self):
156 self.data.normalize_heights()
165 self.data.normalize_heights()
157 self.x = self.data.times
166 self.x = self.data.times
158 self.y = self.data.heights
167 self.y = self.data.heights
159 if self.showSNR:
168 if self.showSNR:
160 self.z = numpy.concatenate(
169 self.z = numpy.concatenate(
161 (self.data[self.CODE], self.data['snr'])
170 (self.data[self.CODE], self.data['snr'])
162 )
171 )
163 else:
172 else:
164 self.z = self.data[self.CODE]
173 self.z = self.data[self.CODE]
165
174
166 self.z = numpy.ma.masked_invalid(self.z)
175 self.z = numpy.ma.masked_invalid(self.z)
167
176
168 if self.decimation is None:
177 if self.decimation is None:
169 x, y, z = self.fill_gaps(self.x, self.y, self.z)
178 x, y, z = self.fill_gaps(self.x, self.y, self.z)
170 else:
179 else:
171 x, y, z = self.fill_gaps(*self.decimate())
180 x, y, z = self.fill_gaps(*self.decimate())
172
181
173 for n, ax in enumerate(self.axes):
182 for n, ax in enumerate(self.axes):
174
183
175 self.zmax = self.zmax if self.zmax is not None else numpy.max(
184 self.zmax = self.zmax if self.zmax is not None else numpy.max(
176 self.z[n])
185 self.z[n])
177 self.zmin = self.zmin if self.zmin is not None else numpy.min(
186 self.zmin = self.zmin if self.zmin is not None else numpy.min(
178 self.z[n])
187 self.z[n])
179
188
180 if ax.firsttime:
189 if ax.firsttime:
181 if self.zlimits is not None:
190 if self.zlimits is not None:
182 self.zmin, self.zmax = self.zlimits[n]
191 self.zmin, self.zmax = self.zlimits[n]
183
192
184 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
193 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
185 vmin=self.zmin,
194 vmin=self.zmin,
186 vmax=self.zmax,
195 vmax=self.zmax,
187 cmap=self.cmaps[n]
196 cmap=self.cmaps[n]
188 )
197 )
189 else:
198 else:
190 if self.zlimits is not None:
199 if self.zlimits is not None:
191 self.zmin, self.zmax = self.zlimits[n]
200 self.zmin, self.zmax = self.zlimits[n]
192 ax.collections.remove(ax.collections[0])
201 ax.collections.remove(ax.collections[0])
193 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
202 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
194 vmin=self.zmin,
203 vmin=self.zmin,
195 vmax=self.zmax,
204 vmax=self.zmax,
196 cmap=self.cmaps[n]
205 cmap=self.cmaps[n]
197 )
206 )
198
207
199
208
200 class OutputPlot(ParametersPlot):
209 class OutputPlot(ParametersPlot):
201 '''
210 '''
202 Plot data_output object
211 Plot data_output object
203 '''
212 '''
204
213
205 CODE = 'output'
214 CODE = 'output'
206 colormap = 'seismic'
215 colormap = 'seismic'
207
216
208
217
209 class PolarMapPlot(Plot):
218 class PolarMapPlot(Plot):
210 '''
219 '''
211 Plot for weather radar
220 Plot for weather radar
212 '''
221 '''
213
222
214 CODE = 'param'
223 CODE = 'param'
215 colormap = 'seismic'
224 colormap = 'seismic'
216
225
217 def setup(self):
226 def setup(self):
218 self.ncols = 1
227 self.ncols = 1
219 self.nrows = 1
228 self.nrows = 1
220 self.width = 9
229 self.width = 9
221 self.height = 8
230 self.height = 8
222 self.mode = self.data.meta['mode']
231 self.mode = self.data.meta['mode']
223 if self.channels is not None:
232 if self.channels is not None:
224 self.nplots = len(self.channels)
233 self.nplots = len(self.channels)
225 self.nrows = len(self.channels)
234 self.nrows = len(self.channels)
226 else:
235 else:
227 self.nplots = self.data.shape(self.CODE)[0]
236 self.nplots = self.data.shape(self.CODE)[0]
228 self.nrows = self.nplots
237 self.nrows = self.nplots
229 self.channels = list(range(self.nplots))
238 self.channels = list(range(self.nplots))
230 if self.mode == 'E':
239 if self.mode == 'E':
231 self.xlabel = 'Longitude'
240 self.xlabel = 'Longitude'
232 self.ylabel = 'Latitude'
241 self.ylabel = 'Latitude'
233 else:
242 else:
234 self.xlabel = 'Range (km)'
243 self.xlabel = 'Range (km)'
235 self.ylabel = 'Height (km)'
244 self.ylabel = 'Height (km)'
236 self.bgcolor = 'white'
245 self.bgcolor = 'white'
237 self.cb_labels = self.data.meta['units']
246 self.cb_labels = self.data.meta['units']
238 self.lat = self.data.meta['latitude']
247 self.lat = self.data.meta['latitude']
239 self.lon = self.data.meta['longitude']
248 self.lon = self.data.meta['longitude']
240 self.xmin, self.xmax = float(
249 self.xmin, self.xmax = float(
241 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
250 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
242 self.ymin, self.ymax = float(
251 self.ymin, self.ymax = float(
243 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
252 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
244 # self.polar = True
253 # self.polar = True
245
254
246 def plot(self):
255 def plot(self):
247
256
248 for n, ax in enumerate(self.axes):
257 for n, ax in enumerate(self.axes):
249 data = self.data['param'][self.channels[n]]
258 data = self.data['param'][self.channels[n]]
250
259
251 zeniths = numpy.linspace(
260 zeniths = numpy.linspace(
252 0, self.data.meta['max_range'], data.shape[1])
261 0, self.data.meta['max_range'], data.shape[1])
253 if self.mode == 'E':
262 if self.mode == 'E':
254 azimuths = -numpy.radians(self.data.heights)+numpy.pi/2
263 azimuths = -numpy.radians(self.data.heights)+numpy.pi/2
255 r, theta = numpy.meshgrid(zeniths, azimuths)
264 r, theta = numpy.meshgrid(zeniths, azimuths)
256 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
265 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
257 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
266 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
258 x = km2deg(x) + self.lon
267 x = km2deg(x) + self.lon
259 y = km2deg(y) + self.lat
268 y = km2deg(y) + self.lat
260 else:
269 else:
261 azimuths = numpy.radians(self.data.heights)
270 azimuths = numpy.radians(self.data.heights)
262 r, theta = numpy.meshgrid(zeniths, azimuths)
271 r, theta = numpy.meshgrid(zeniths, azimuths)
263 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
272 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
264 self.y = zeniths
273 self.y = zeniths
265
274
266 if ax.firsttime:
275 if ax.firsttime:
267 if self.zlimits is not None:
276 if self.zlimits is not None:
268 self.zmin, self.zmax = self.zlimits[n]
277 self.zmin, self.zmax = self.zlimits[n]
269 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
278 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
270 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
279 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
271 vmin=self.zmin,
280 vmin=self.zmin,
272 vmax=self.zmax,
281 vmax=self.zmax,
273 cmap=self.cmaps[n])
282 cmap=self.cmaps[n])
274 else:
283 else:
275 if self.zlimits is not None:
284 if self.zlimits is not None:
276 self.zmin, self.zmax = self.zlimits[n]
285 self.zmin, self.zmax = self.zlimits[n]
277 ax.collections.remove(ax.collections[0])
286 ax.collections.remove(ax.collections[0])
278 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
287 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
279 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
288 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
280 vmin=self.zmin,
289 vmin=self.zmin,
281 vmax=self.zmax,
290 vmax=self.zmax,
282 cmap=self.cmaps[n])
291 cmap=self.cmaps[n])
283
292
284 if self.mode == 'A':
293 if self.mode == 'A':
285 continue
294 continue
286
295
287 # plot district names
296 # plot district names
288 f = open('/data/workspace/schain_scripts/distrito.csv')
297 f = open('/data/workspace/schain_scripts/distrito.csv')
289 for line in f:
298 for line in f:
290 label, lon, lat = [s.strip() for s in line.split(',') if s]
299 label, lon, lat = [s.strip() for s in line.split(',') if s]
291 lat = float(lat)
300 lat = float(lat)
292 lon = float(lon)
301 lon = float(lon)
293 # ax.plot(lon, lat, '.b', ms=2)
302 # ax.plot(lon, lat, '.b', ms=2)
294 ax.text(lon, lat, label.decode('utf8'), ha='center',
303 ax.text(lon, lat, label.decode('utf8'), ha='center',
295 va='bottom', size='8', color='black')
304 va='bottom', size='8', color='black')
296
305
297 # plot limites
306 # plot limites
298 limites = []
307 limites = []
299 tmp = []
308 tmp = []
300 for line in open('/data/workspace/schain_scripts/lima.csv'):
309 for line in open('/data/workspace/schain_scripts/lima.csv'):
301 if '#' in line:
310 if '#' in line:
302 if tmp:
311 if tmp:
303 limites.append(tmp)
312 limites.append(tmp)
304 tmp = []
313 tmp = []
305 continue
314 continue
306 values = line.strip().split(',')
315 values = line.strip().split(',')
307 tmp.append((float(values[0]), float(values[1])))
316 tmp.append((float(values[0]), float(values[1])))
308 for points in limites:
317 for points in limites:
309 ax.add_patch(
318 ax.add_patch(
310 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
319 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
311
320
312 # plot Cuencas
321 # plot Cuencas
313 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
322 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
314 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
323 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
315 values = [line.strip().split(',') for line in f]
324 values = [line.strip().split(',') for line in f]
316 points = [(float(s[0]), float(s[1])) for s in values]
325 points = [(float(s[0]), float(s[1])) for s in values]
317 ax.add_patch(Polygon(points, ec='b', fc='none'))
326 ax.add_patch(Polygon(points, ec='b', fc='none'))
318
327
319 # plot grid
328 # plot grid
320 for r in (15, 30, 45, 60):
329 for r in (15, 30, 45, 60):
321 ax.add_artist(plt.Circle((self.lon, self.lat),
330 ax.add_artist(plt.Circle((self.lon, self.lat),
322 km2deg(r), color='0.6', fill=False, lw=0.2))
331 km2deg(r), color='0.6', fill=False, lw=0.2))
323 ax.text(
332 ax.text(
324 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
333 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
325 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
334 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
326 '{}km'.format(r),
335 '{}km'.format(r),
327 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
336 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
328
337
329 if self.mode == 'E':
338 if self.mode == 'E':
330 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
339 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
331 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
340 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
332 else:
341 else:
333 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
342 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
334 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
343 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
335
344
336 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
345 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
337 self.titles = ['{} {}'.format(
346 self.titles = ['{} {}'.format(
338 self.data.parameters[x], title) for x in self.channels]
347 self.data.parameters[x], title) for x in self.channels]
339
This diff has been collapsed as it changes many lines, (540 lines changed) Show them Hide them
@@ -1,641 +1,1171
1 '''
1 '''
2 Created on Jul 9, 2014
2 Created on Jul 9, 2014
3 Modified on May 10, 2020
3 Modified on May 10, 2020
4
4
5 @author: Juan C. Espinoza
5 @author: Juan C. Espinoza
6 '''
6 '''
7
7
8 import os
8 import os
9 import datetime
9 import datetime
10 import numpy
10 import numpy
11
11
12 from schainpy.model.graphics.jroplot_base import Plot, plt
12 from schainpy.model.graphics.jroplot_base import Plot, plt
13
13
14
14
15 class SpectraPlot(Plot):
15 class SpectraPlot(Plot):
16 '''
16 '''
17 Plot for Spectra data
17 Plot for Spectra data
18 '''
18 '''
19
19
20 CODE = 'spc'
20 CODE = 'spc'
21 colormap = 'jet'
21 colormap = 'jet'
22 plot_type = 'pcolor'
22 plot_type = 'pcolor'
23
23
24 def setup(self):
24 def setup(self):
25
25 self.nplots = len(self.data.channels)
26 self.nplots = len(self.data.channels)
26 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
27 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
27 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
28 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
28 self.height = 2.6 * self.nrows
29 self.height = 2.6 * self.nrows
29 self.cb_label = 'dB'
30 self.cb_label = 'dB'
30 if self.showprofile:
31 if self.showprofile:
31 self.width = 4 * self.ncols
32 self.width = 4 * self.ncols
32 else:
33 else:
33 self.width = 3.5 * self.ncols
34 self.width = 3.5 * self.ncols
34 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
35 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
35 self.ylabel = 'Range [km]'
36 self.ylabel = 'Range [km]'
36
37
37 def plot(self):
38 def plot(self):
39
40 #print(self.xaxis)
41 #exit(1)
38 if self.xaxis == "frequency":
42 if self.xaxis == "frequency":
39 x = self.data.xrange[0]
43 x = self.data.xrange[0]
40 self.xlabel = "Frequency (kHz)"
44 self.xlabel = "Frequency (kHz)"
41 elif self.xaxis == "time":
45 elif self.xaxis == "time":
42 x = self.data.xrange[1]
46 x = self.data.xrange[1]
43 self.xlabel = "Time (ms)"
47 self.xlabel = "Time (ms)"
44 else:
48 else:
45 x = self.data.xrange[2]
49 x = self.data.xrange[2]
46 self.xlabel = "Velocity (m/s)"
50 self.xlabel = "Velocity (m/s)"
47
51
48 if self.CODE == 'spc_moments':
52 if self.CODE == 'spc_moments':
49 x = self.data.xrange[2]
53 x = self.data.xrange[2]
50 self.xlabel = "Velocity (m/s)"
54 self.xlabel = "Velocity (m/s)"
51
55
52 self.titles = []
56 self.titles = []
53
57
58
54 y = self.data.heights
59 y = self.data.heights
55 self.y = y
60 self.y = y
56 z = self.data['spc']
61 z = self.data['spc']
57
62
63 self.CODE2 = 'spc_oblique'
64
65
58 for n, ax in enumerate(self.axes):
66 for n, ax in enumerate(self.axes):
59 noise = self.data['noise'][n][-1]
67 noise = self.data['noise'][n][-1]
60 if self.CODE == 'spc_moments':
68 if self.CODE == 'spc_moments':
61 mean = self.data['moments'][n, :, 1, :][-1]
69 mean = self.data['moments'][n, :, 1, :][-1]
70
62 if ax.firsttime:
71 if ax.firsttime:
63 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
72 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
64 self.xmin = self.xmin if self.xmin else -self.xmax
73 self.xmin = self.xmin if self.xmin else -self.xmax
65 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
74 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
66 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
75 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
76 #print(numpy.shape(x))
67 ax.plt = ax.pcolormesh(x, y, z[n].T,
77 ax.plt = ax.pcolormesh(x, y, z[n].T,
68 vmin=self.zmin,
78 vmin=self.zmin,
69 vmax=self.zmax,
79 vmax=self.zmax,
70 cmap=plt.get_cmap(self.colormap)
80 cmap=plt.get_cmap(self.colormap)
71 )
81 )
72
82
73 if self.showprofile:
83 if self.showprofile:
74 ax.plt_profile = self.pf_axes[n].plot(
84 ax.plt_profile = self.pf_axes[n].plot(
75 self.data['rti'][n][-1], y)[0]
85 self.data['rti'][n][-1], y)[0]
76 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
86 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
77 color="k", linestyle="dashed", lw=1)[0]
87 color="k", linestyle="dashed", lw=1)[0]
78 if self.CODE == 'spc_moments':
88 if self.CODE == 'spc_moments':
79 ax.plt_mean = ax.plot(mean, y, color='k')[0]
89 ax.plt_mean = ax.plot(mean, y, color='k')[0]
90
80 else:
91 else:
92
81 ax.plt.set_array(z[n].T.ravel())
93 ax.plt.set_array(z[n].T.ravel())
82 if self.showprofile:
94 if self.showprofile:
83 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
95 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
84 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
96 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
85 if self.CODE == 'spc_moments':
97 if self.CODE == 'spc_moments':
86 ax.plt_mean.set_data(mean, y)
98 ax.plt_mean.set_data(mean, y)
99
87 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
100 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
88
101
102 class SpectraObliquePlot(Plot):
103 '''
104 Plot for Spectra data
105 '''
106
107 CODE = 'spc'
108 colormap = 'jet'
109 plot_type = 'pcolor'
110
111 def setup(self):
112 self.xaxis = "oblique"
113 self.nplots = len(self.data.channels)
114 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
115 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
116 self.height = 2.6 * self.nrows
117 self.cb_label = 'dB'
118 if self.showprofile:
119 self.width = 4 * self.ncols
120 else:
121 self.width = 3.5 * self.ncols
122 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
123 self.ylabel = 'Range [km]'
124
125 def plot(self):
126
127 #print(self.xaxis)
128 #exit(1)
129 if self.xaxis == "frequency":
130 x = self.data.xrange[0]
131 self.xlabel = "Frequency (kHz)"
132 elif self.xaxis == "time":
133 x = self.data.xrange[1]
134 self.xlabel = "Time (ms)"
135 else:
136 x = self.data.xrange[2]
137 self.xlabel = "Velocity (m/s)"
138
139 if self.CODE == 'spc_moments':
140 x = self.data.xrange[2]
141 self.xlabel = "Velocity (m/s)"
142
143 self.titles = []
144 #self.xlabel = "Velocidad (m/s)"
145 #self.ylabel = 'Rango (km)'
146
147
148 y = self.data.heights
149 self.y = y
150 z = self.data['spc']
151
152 self.CODE2 = 'spc_oblique'
153
154
155 for n, ax in enumerate(self.axes):
156 noise = self.data['noise'][n][-1]
157 if self.CODE == 'spc_moments':
158 mean = self.data['moments'][n, :, 1, :][-1]
159 if self.CODE2 == 'spc_oblique':
160 shift1 = self.data.shift1
161 shift2 = self.data.shift2
162 if ax.firsttime:
163 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
164 self.xmin = self.xmin if self.xmin else -self.xmax
165 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
166 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
167 #print(numpy.shape(x))
168 ax.plt = ax.pcolormesh(x, y, z[n].T,
169 vmin=self.zmin,
170 vmax=self.zmax,
171 cmap=plt.get_cmap(self.colormap)
172 )
173
174 if self.showprofile:
175 ax.plt_profile = self.pf_axes[n].plot(
176 self.data['rti'][n][-1], y)[0]
177 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
178 color="k", linestyle="dashed", lw=1)[0]
179 if self.CODE == 'spc_moments':
180 ax.plt_mean = ax.plot(mean, y, color='k')[0]
181
182 if self.CODE2 == 'spc_oblique':
183 #ax.plt_shift1 = ax.plot(shift1, y, color='k', marker='x', linestyle='None', markersize=0.5)[0]
184 #ax.plt_shift2 = ax.plot(shift2, y, color='m', marker='x', linestyle='None', markersize=0.5)[0]
185 self.ploterr1 = ax.errorbar(shift1, y, xerr=self.data.shift1_error,fmt='k^',elinewidth=0.2,marker='x',linestyle='None',markersize=0.5,capsize=0.3,markeredgewidth=0.2)
186 self.ploterr2 = ax.errorbar(shift2, y, xerr=self.data.shift2_error,fmt='m^',elinewidth=0.2,marker='x',linestyle='None',markersize=0.5,capsize=0.3,markeredgewidth=0.2)
187
188 else:
189 self.ploterr1.remove()
190 self.ploterr2.remove()
191 ax.plt.set_array(z[n].T.ravel())
192 if self.showprofile:
193 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
194 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
195 if self.CODE == 'spc_moments':
196 ax.plt_mean.set_data(mean, y)
197 if self.CODE2 == 'spc_oblique':
198 #ax.plt_shift1.set_data(shift1, y)
199 #ax.plt_shift2.set_data(shift2, y)
200 #ax.clf()
201 self.ploterr1 = ax.errorbar(shift1, y, xerr=self.data.shift1_error,fmt='k^',elinewidth=0.2,marker='x',linestyle='None',markersize=0.5,capsize=0.3,markeredgewidth=0.2)
202 self.ploterr2 = ax.errorbar(shift2, y, xerr=self.data.shift2_error,fmt='m^',elinewidth=0.2,marker='x',linestyle='None',markersize=0.5,capsize=0.3,markeredgewidth=0.2)
203
204 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
205 #self.titles.append('{}'.format('Velocidad Doppler'))
89
206
90 class CrossSpectraPlot(Plot):
207 class CrossSpectraPlot(Plot):
91
208
92 CODE = 'cspc'
209 CODE = 'cspc'
93 colormap = 'jet'
210 colormap = 'jet'
94 plot_type = 'pcolor'
211 plot_type = 'pcolor'
95 zmin_coh = None
212 zmin_coh = None
96 zmax_coh = None
213 zmax_coh = None
97 zmin_phase = None
214 zmin_phase = None
98 zmax_phase = None
215 zmax_phase = None
99
216
100 def setup(self):
217 def setup(self):
101
218
102 self.ncols = 4
219 self.ncols = 4
103 self.nrows = len(self.data.pairs)
220 self.nrows = len(self.data.pairs)
104 self.nplots = self.nrows * 4
221 self.nplots = self.nrows * 4
105 self.width = 3.1 * self.ncols
222 self.width = 3.1 * self.ncols
106 self.height = 2.6 * self.nrows
223 self.height = 5 * self.nrows
107 self.ylabel = 'Range [km]'
224 self.ylabel = 'Range [km]'
108 self.showprofile = False
225 self.showprofile = False
109 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
226 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
110
227
111 def plot(self):
228 def plot(self):
112
229
113 if self.xaxis == "frequency":
230 if self.xaxis == "frequency":
114 x = self.data.xrange[0]
231 x = self.data.xrange[0]
115 self.xlabel = "Frequency (kHz)"
232 self.xlabel = "Frequency (kHz)"
116 elif self.xaxis == "time":
233 elif self.xaxis == "time":
117 x = self.data.xrange[1]
234 x = self.data.xrange[1]
118 self.xlabel = "Time (ms)"
235 self.xlabel = "Time (ms)"
119 else:
236 else:
120 x = self.data.xrange[2]
237 x = self.data.xrange[2]
121 self.xlabel = "Velocity (m/s)"
238 self.xlabel = "Velocity (m/s)"
122
239
123 self.titles = []
240 self.titles = []
124
241
242
125 y = self.data.heights
243 y = self.data.heights
126 self.y = y
244 self.y = y
127 nspc = self.data['spc']
245 nspc = self.data['spc']
246 #print(numpy.shape(self.data['spc']))
128 spc = self.data['cspc'][0]
247 spc = self.data['cspc'][0]
248 #print(numpy.shape(spc))
249 #exit()
129 cspc = self.data['cspc'][1]
250 cspc = self.data['cspc'][1]
251 #print(numpy.shape(cspc))
252 #exit()
130
253
131 for n in range(self.nrows):
254 for n in range(self.nrows):
132 noise = self.data['noise'][:,-1]
255 noise = self.data['noise'][:,-1]
133 pair = self.data.pairs[n]
256 pair = self.data.pairs[n]
257 #print(pair)
258 #exit()
134 ax = self.axes[4 * n]
259 ax = self.axes[4 * n]
135 if ax.firsttime:
260 if ax.firsttime:
136 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
261 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
137 self.xmin = self.xmin if self.xmin else -self.xmax
262 #self.xmin = self.xmin if self.xmin else -self.xmax
263 self.xmin = self.xmin if self.xmin else numpy.nanmin(x)
138 self.zmin = self.zmin if self.zmin else numpy.nanmin(nspc)
264 self.zmin = self.zmin if self.zmin else numpy.nanmin(nspc)
139 self.zmax = self.zmax if self.zmax else numpy.nanmax(nspc)
265 self.zmax = self.zmax if self.zmax else numpy.nanmax(nspc)
266 #print(numpy.nanmin(x))
267 #print(self.xmax)
268 #print(self.xmin)
269 #exit()
270 #self.xmin=-.1
140 ax.plt = ax.pcolormesh(x , y , nspc[pair[0]].T,
271 ax.plt = ax.pcolormesh(x , y , nspc[pair[0]].T,
141 vmin=self.zmin,
272 vmin=self.zmin,
142 vmax=self.zmax,
273 vmax=self.zmax,
143 cmap=plt.get_cmap(self.colormap)
274 cmap=plt.get_cmap(self.colormap)
144 )
275 )
145 else:
276 else:
146 ax.plt.set_array(nspc[pair[0]].T.ravel())
277 ax.plt.set_array(nspc[pair[0]].T.ravel())
147 self.titles.append('CH {}: {:3.2f}dB'.format(pair[0], noise[pair[0]]))
278 self.titles.append('CH {}: {:3.2f}dB'.format(pair[0], noise[pair[0]]))
148
279
149 ax = self.axes[4 * n + 1]
280 ax = self.axes[4 * n + 1]
150 if ax.firsttime:
281 if ax.firsttime:
151 ax.plt = ax.pcolormesh(x , y, nspc[pair[1]].T,
282 ax.plt = ax.pcolormesh(x , y, nspc[pair[1]].T,
152 vmin=self.zmin,
283 vmin=self.zmin,
153 vmax=self.zmax,
284 vmax=self.zmax,
154 cmap=plt.get_cmap(self.colormap)
285 cmap=plt.get_cmap(self.colormap)
155 )
286 )
156 else:
287 else:
157 ax.plt.set_array(nspc[pair[1]].T.ravel())
288 ax.plt.set_array(nspc[pair[1]].T.ravel())
158 self.titles.append('CH {}: {:3.2f}dB'.format(pair[1], noise[pair[1]]))
289 self.titles.append('CH {}: {:3.2f}dB'.format(pair[1], noise[pair[1]]))
159
290
160 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
291 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
161 coh = numpy.abs(out)
292 coh = numpy.abs(out)
162 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
293 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
163
294
164 ax = self.axes[4 * n + 2]
295 ax = self.axes[4 * n + 2]
165 if ax.firsttime:
296 if ax.firsttime:
166 ax.plt = ax.pcolormesh(x, y, coh.T,
297 ax.plt = ax.pcolormesh(x, y, coh.T,
167 vmin=0,
298 vmin=0,
168 vmax=1,
299 vmax=1,
169 cmap=plt.get_cmap(self.colormap_coh)
300 cmap=plt.get_cmap(self.colormap_coh)
170 )
301 )
171 else:
302 else:
172 ax.plt.set_array(coh.T.ravel())
303 ax.plt.set_array(coh.T.ravel())
173 self.titles.append(
304 self.titles.append(
174 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
305 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
175
306
176 ax = self.axes[4 * n + 3]
307 ax = self.axes[4 * n + 3]
177 if ax.firsttime:
308 if ax.firsttime:
178 ax.plt = ax.pcolormesh(x, y, phase.T,
309 ax.plt = ax.pcolormesh(x, y, phase.T,
179 vmin=-180,
310 vmin=-180,
180 vmax=180,
311 vmax=180,
181 cmap=plt.get_cmap(self.colormap_phase)
312 cmap=plt.get_cmap(self.colormap_phase)
182 )
313 )
183 else:
314 else:
184 ax.plt.set_array(phase.T.ravel())
315 ax.plt.set_array(phase.T.ravel())
185 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
316 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
186
317
187
318
319 class CrossSpectra4Plot(Plot):
320
321 CODE = 'cspc'
322 colormap = 'jet'
323 plot_type = 'pcolor'
324 zmin_coh = None
325 zmax_coh = None
326 zmin_phase = None
327 zmax_phase = None
328
329 def setup(self):
330
331 self.ncols = 4
332 self.nrows = len(self.data.pairs)
333 self.nplots = self.nrows * 4
334 self.width = 3.1 * self.ncols
335 self.height = 5 * self.nrows
336 self.ylabel = 'Range [km]'
337 self.showprofile = False
338 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
339
340 def plot(self):
341
342 if self.xaxis == "frequency":
343 x = self.data.xrange[0]
344 self.xlabel = "Frequency (kHz)"
345 elif self.xaxis == "time":
346 x = self.data.xrange[1]
347 self.xlabel = "Time (ms)"
348 else:
349 x = self.data.xrange[2]
350 self.xlabel = "Velocity (m/s)"
351
352 self.titles = []
353
354
355 y = self.data.heights
356 self.y = y
357 nspc = self.data['spc']
358 #print(numpy.shape(self.data['spc']))
359 spc = self.data['cspc'][0]
360 #print(numpy.shape(nspc))
361 #exit()
362 #nspc[1,:,:] = numpy.flip(nspc[1,:,:],axis=0)
363 #print(numpy.shape(spc))
364 #exit()
365 cspc = self.data['cspc'][1]
366
367 #xflip=numpy.flip(x)
368 #print(numpy.shape(cspc))
369 #exit()
370
371 for n in range(self.nrows):
372 noise = self.data['noise'][:,-1]
373 pair = self.data.pairs[n]
374 #print(pair)
375 #exit()
376 ax = self.axes[4 * n]
377 if ax.firsttime:
378 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
379 self.xmin = self.xmin if self.xmin else -self.xmax
380 self.zmin = self.zmin if self.zmin else numpy.nanmin(nspc)
381 self.zmax = self.zmax if self.zmax else numpy.nanmax(nspc)
382 ax.plt = ax.pcolormesh(x , y , nspc[pair[0]].T,
383 vmin=self.zmin,
384 vmax=self.zmax,
385 cmap=plt.get_cmap(self.colormap)
386 )
387 else:
388 #print(numpy.shape(nspc[pair[0]].T))
389 #exit()
390 ax.plt.set_array(nspc[pair[0]].T.ravel())
391 self.titles.append('CH {}: {:3.2f}dB'.format(pair[0], noise[pair[0]]))
392
393 ax = self.axes[4 * n + 1]
394
395 if ax.firsttime:
396 ax.plt = ax.pcolormesh(x , y, numpy.flip(nspc[pair[1]],axis=0).T,
397 vmin=self.zmin,
398 vmax=self.zmax,
399 cmap=plt.get_cmap(self.colormap)
400 )
401 else:
402
403 ax.plt.set_array(numpy.flip(nspc[pair[1]],axis=0).T.ravel())
404 self.titles.append('CH {}: {:3.2f}dB'.format(pair[1], noise[pair[1]]))
405
406 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
407 coh = numpy.abs(out)
408 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
409
410 ax = self.axes[4 * n + 2]
411 if ax.firsttime:
412 ax.plt = ax.pcolormesh(x, y, numpy.flip(coh,axis=0).T,
413 vmin=0,
414 vmax=1,
415 cmap=plt.get_cmap(self.colormap_coh)
416 )
417 else:
418 ax.plt.set_array(numpy.flip(coh,axis=0).T.ravel())
419 self.titles.append(
420 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
421
422 ax = self.axes[4 * n + 3]
423 if ax.firsttime:
424 ax.plt = ax.pcolormesh(x, y, numpy.flip(phase,axis=0).T,
425 vmin=-180,
426 vmax=180,
427 cmap=plt.get_cmap(self.colormap_phase)
428 )
429 else:
430 ax.plt.set_array(numpy.flip(phase,axis=0).T.ravel())
431 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
432
433
434 class CrossSpectra2Plot(Plot):
435
436 CODE = 'cspc'
437 colormap = 'jet'
438 plot_type = 'pcolor'
439 zmin_coh = None
440 zmax_coh = None
441 zmin_phase = None
442 zmax_phase = None
443
444 def setup(self):
445
446 self.ncols = 1
447 self.nrows = len(self.data.pairs)
448 self.nplots = self.nrows * 1
449 self.width = 3.1 * self.ncols
450 self.height = 5 * self.nrows
451 self.ylabel = 'Range [km]'
452 self.showprofile = False
453 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
454
455 def plot(self):
456
457 if self.xaxis == "frequency":
458 x = self.data.xrange[0]
459 self.xlabel = "Frequency (kHz)"
460 elif self.xaxis == "time":
461 x = self.data.xrange[1]
462 self.xlabel = "Time (ms)"
463 else:
464 x = self.data.xrange[2]
465 self.xlabel = "Velocity (m/s)"
466
467 self.titles = []
468
469
470 y = self.data.heights
471 self.y = y
472 #nspc = self.data['spc']
473 #print(numpy.shape(self.data['spc']))
474 #spc = self.data['cspc'][0]
475 #print(numpy.shape(spc))
476 #exit()
477 cspc = self.data['cspc'][1]
478 #print(numpy.shape(cspc))
479 #exit()
480
481 for n in range(self.nrows):
482 noise = self.data['noise'][:,-1]
483 pair = self.data.pairs[n]
484 #print(pair) #exit()
485
486
487
488 out = cspc[n]# / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
489
490 #print(out[:,53])
491 #exit()
492 cross = numpy.abs(out)
493 z = cross/self.data.nFactor
494 #print("here")
495 #print(dataOut.data_spc[0,0,0])
496 #exit()
497
498 cross = 10*numpy.log10(z)
499 #print(numpy.shape(cross))
500 #print(cross[0,:])
501 #print(self.data.nFactor)
502 #exit()
503 #phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
504
505 ax = self.axes[1 * n]
506 if ax.firsttime:
507 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
508 self.xmin = self.xmin if self.xmin else -self.xmax
509 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
510 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
511 ax.plt = ax.pcolormesh(x, y, cross.T,
512 vmin=self.zmin,
513 vmax=self.zmax,
514 cmap=plt.get_cmap(self.colormap)
515 )
516 else:
517 ax.plt.set_array(cross.T.ravel())
518 self.titles.append(
519 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
520
521
522 class CrossSpectra3Plot(Plot):
523
524 CODE = 'cspc'
525 colormap = 'jet'
526 plot_type = 'pcolor'
527 zmin_coh = None
528 zmax_coh = None
529 zmin_phase = None
530 zmax_phase = None
531
532 def setup(self):
533
534 self.ncols = 3
535 self.nrows = len(self.data.pairs)
536 self.nplots = self.nrows * 3
537 self.width = 3.1 * self.ncols
538 self.height = 5 * self.nrows
539 self.ylabel = 'Range [km]'
540 self.showprofile = False
541 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
542
543 def plot(self):
544
545 if self.xaxis == "frequency":
546 x = self.data.xrange[0]
547 self.xlabel = "Frequency (kHz)"
548 elif self.xaxis == "time":
549 x = self.data.xrange[1]
550 self.xlabel = "Time (ms)"
551 else:
552 x = self.data.xrange[2]
553 self.xlabel = "Velocity (m/s)"
554
555 self.titles = []
556
557
558 y = self.data.heights
559 self.y = y
560 #nspc = self.data['spc']
561 #print(numpy.shape(self.data['spc']))
562 #spc = self.data['cspc'][0]
563 #print(numpy.shape(spc))
564 #exit()
565 cspc = self.data['cspc'][1]
566 #print(numpy.shape(cspc))
567 #exit()
568
569 for n in range(self.nrows):
570 noise = self.data['noise'][:,-1]
571 pair = self.data.pairs[n]
572 #print(pair) #exit()
573
574
575
576 out = cspc[n]# / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
577
578 #print(out[:,53])
579 #exit()
580 cross = numpy.abs(out)
581 z = cross/self.data.nFactor
582 cross = 10*numpy.log10(z)
583
584 out_r= out.real/self.data.nFactor
585 #out_r = 10*numpy.log10(out_r)
586
587 out_i= out.imag/self.data.nFactor
588 #out_i = 10*numpy.log10(out_i)
589 #print(numpy.shape(cross))
590 #print(cross[0,:])
591 #print(self.data.nFactor)
592 #exit()
593 #phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
594
595 ax = self.axes[3 * n]
596 if ax.firsttime:
597 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
598 self.xmin = self.xmin if self.xmin else -self.xmax
599 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
600 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
601 ax.plt = ax.pcolormesh(x, y, cross.T,
602 vmin=self.zmin,
603 vmax=self.zmax,
604 cmap=plt.get_cmap(self.colormap)
605 )
606 else:
607 ax.plt.set_array(cross.T.ravel())
608 self.titles.append(
609 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
610
611 ax = self.axes[3 * n + 1]
612 if ax.firsttime:
613 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
614 self.xmin = self.xmin if self.xmin else -self.xmax
615 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
616 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
617 ax.plt = ax.pcolormesh(x, y, out_r.T,
618 vmin=-1.e6,
619 vmax=0,
620 cmap=plt.get_cmap(self.colormap)
621 )
622 else:
623 ax.plt.set_array(out_r.T.ravel())
624 self.titles.append(
625 'Cross Spectra Real Ch{} * Ch{}'.format(pair[0], pair[1]))
626
627 ax = self.axes[3 * n + 2]
628
629
630 if ax.firsttime:
631 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
632 self.xmin = self.xmin if self.xmin else -self.xmax
633 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
634 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
635 ax.plt = ax.pcolormesh(x, y, out_i.T,
636 vmin=-1.e6,
637 vmax=1.e6,
638 cmap=plt.get_cmap(self.colormap)
639 )
640 else:
641 ax.plt.set_array(out_i.T.ravel())
642 self.titles.append(
643 'Cross Spectra Imag Ch{} * Ch{}'.format(pair[0], pair[1]))
644
188 class RTIPlot(Plot):
645 class RTIPlot(Plot):
189 '''
646 '''
190 Plot for RTI data
647 Plot for RTI data
191 '''
648 '''
192
649
193 CODE = 'rti'
650 CODE = 'rti'
194 colormap = 'jet'
651 colormap = 'jet'
195 plot_type = 'pcolorbuffer'
652 plot_type = 'pcolorbuffer'
196
653
197 def setup(self):
654 def setup(self):
198 self.xaxis = 'time'
655 self.xaxis = 'time'
199 self.ncols = 1
656 self.ncols = 1
200 self.nrows = len(self.data.channels)
657 self.nrows = len(self.data.channels)
201 self.nplots = len(self.data.channels)
658 self.nplots = len(self.data.channels)
202 self.ylabel = 'Range [km]'
659 self.ylabel = 'Range [km]'
203 self.xlabel = 'Time'
660 self.xlabel = 'Time'
204 self.cb_label = 'dB'
661 self.cb_label = 'dB'
205 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95})
662 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
206 self.titles = ['{} Channel {}'.format(
663 self.titles = ['{} Channel {}'.format(
207 self.CODE.upper(), x) for x in range(self.nrows)]
664 self.CODE.upper(), x) for x in range(self.nrows)]
208
665
209 def plot(self):
666 def plot(self):
210 self.x = self.data.times
667 self.x = self.data.times
211 self.y = self.data.heights
668 self.y = self.data.heights
212 self.z = self.data[self.CODE]
669 self.z = self.data[self.CODE]
670
671 self.z = numpy.ma.masked_invalid(self.z)
672
673 if self.decimation is None:
674 x, y, z = self.fill_gaps(self.x, self.y, self.z)
675 else:
676 x, y, z = self.fill_gaps(*self.decimate())
677
678 for n, ax in enumerate(self.axes):
679 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
680 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
681 if ax.firsttime:
682 ax.plt = ax.pcolormesh(x, y, z[n].T,
683 vmin=self.zmin,
684 vmax=self.zmax,
685 cmap=plt.get_cmap(self.colormap)
686 )
687 if self.showprofile:
688 ax.plot_profile = self.pf_axes[n].plot(
689 self.data['rti'][n][-1], self.y)[0]
690 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
691 color="k", linestyle="dashed", lw=1)[0]
692 else:
693 ax.collections.remove(ax.collections[0])
694 ax.plt = ax.pcolormesh(x, y, z[n].T,
695 vmin=self.zmin,
696 vmax=self.zmax,
697 cmap=plt.get_cmap(self.colormap)
698 )
699 if self.showprofile:
700 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
701 ax.plot_noise.set_data(numpy.repeat(
702 self.data['noise'][n][-1], len(self.y)), self.y)
703
704
705 class SpectrogramPlot(Plot):
706 '''
707 Plot for Spectrogram data
708 '''
709
710 CODE = 'spectrogram'
711 colormap = 'binary'
712 plot_type = 'pcolorbuffer'
713
714 def setup(self):
715 self.xaxis = 'time'
716 self.ncols = 1
717 self.nrows = len(self.data.channels)
718 self.nplots = len(self.data.channels)
719 #print(self.dataOut.heightList)
720 #self.ylabel = 'Range [km]'
721 self.xlabel = 'Time'
722 self.cb_label = 'dB'
723 self.plots_adjust.update({'hspace':1.2, 'left': 0.1, 'bottom': 0.12, 'right':0.95})
724 self.titles = ['{} Channel {} \n H = {} km ({} - {})'.format(
725 self.CODE.upper(), x, self.data.heightList[self.data.hei], self.data.heightList[self.data.hei],self.data.heightList[self.data.hei]+(self.data.DH*self.data.nProfiles)) for x in range(self.nrows)]
726
727 def plot(self):
728 self.x = self.data.times
729 #self.y = self.data.heights
730 self.z = self.data[self.CODE]
731 self.y = self.data.xrange[0]
732 #import time
733 #print(time.ctime(self.x))
734
735 '''
736 print(numpy.shape(self.x))
737 print(numpy.shape(self.y))
738 print(numpy.shape(self.z))
739 '''
740 self.ylabel = "Frequency (kHz)"
741
213 self.z = numpy.ma.masked_invalid(self.z)
742 self.z = numpy.ma.masked_invalid(self.z)
214
743
215 if self.decimation is None:
744 if self.decimation is None:
216 x, y, z = self.fill_gaps(self.x, self.y, self.z)
745 x, y, z = self.fill_gaps(self.x, self.y, self.z)
217 else:
746 else:
218 x, y, z = self.fill_gaps(*self.decimate())
747 x, y, z = self.fill_gaps(*self.decimate())
219
748
220 for n, ax in enumerate(self.axes):
749 for n, ax in enumerate(self.axes):
221 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
750 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
222 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
751 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
223 if ax.firsttime:
752 if ax.firsttime:
224 ax.plt = ax.pcolormesh(x, y, z[n].T,
753 ax.plt = ax.pcolormesh(x, y, z[n].T,
225 vmin=self.zmin,
754 vmin=self.zmin,
226 vmax=self.zmax,
755 vmax=self.zmax,
227 cmap=plt.get_cmap(self.colormap)
756 cmap=plt.get_cmap(self.colormap)
228 )
757 )
229 if self.showprofile:
758 if self.showprofile:
230 ax.plot_profile = self.pf_axes[n].plot(
759 ax.plot_profile = self.pf_axes[n].plot(
231 self.data['rti'][n][-1], self.y)[0]
760 self.data['rti'][n][-1], self.y)[0]
232 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
761 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
233 color="k", linestyle="dashed", lw=1)[0]
762 color="k", linestyle="dashed", lw=1)[0]
234 else:
763 else:
235 ax.collections.remove(ax.collections[0])
764 ax.collections.remove(ax.collections[0])
236 ax.plt = ax.pcolormesh(x, y, z[n].T,
765 ax.plt = ax.pcolormesh(x, y, z[n].T,
237 vmin=self.zmin,
766 vmin=self.zmin,
238 vmax=self.zmax,
767 vmax=self.zmax,
239 cmap=plt.get_cmap(self.colormap)
768 cmap=plt.get_cmap(self.colormap)
240 )
769 )
241 if self.showprofile:
770 if self.showprofile:
242 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
771 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
243 ax.plot_noise.set_data(numpy.repeat(
772 ax.plot_noise.set_data(numpy.repeat(
244 self.data['noise'][n][-1], len(self.y)), self.y)
773 self.data['noise'][n][-1], len(self.y)), self.y)
245
774
246
775
247 class CoherencePlot(RTIPlot):
776 class CoherencePlot(RTIPlot):
248 '''
777 '''
249 Plot for Coherence data
778 Plot for Coherence data
250 '''
779 '''
251
780
252 CODE = 'coh'
781 CODE = 'coh'
253
782
254 def setup(self):
783 def setup(self):
255 self.xaxis = 'time'
784 self.xaxis = 'time'
256 self.ncols = 1
785 self.ncols = 1
257 self.nrows = len(self.data.pairs)
786 self.nrows = len(self.data.pairs)
258 self.nplots = len(self.data.pairs)
787 self.nplots = len(self.data.pairs)
259 self.ylabel = 'Range [km]'
788 self.ylabel = 'Range [km]'
260 self.xlabel = 'Time'
789 self.xlabel = 'Time'
261 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
790 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
262 if self.CODE == 'coh':
791 if self.CODE == 'coh':
263 self.cb_label = ''
792 self.cb_label = ''
264 self.titles = [
793 self.titles = [
265 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
794 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
266 else:
795 else:
267 self.cb_label = 'Degrees'
796 self.cb_label = 'Degrees'
268 self.titles = [
797 self.titles = [
269 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
798 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
270
799
271
800
272 class PhasePlot(CoherencePlot):
801 class PhasePlot(CoherencePlot):
273 '''
802 '''
274 Plot for Phase map data
803 Plot for Phase map data
275 '''
804 '''
276
805
277 CODE = 'phase'
806 CODE = 'phase'
278 colormap = 'seismic'
807 colormap = 'seismic'
279
808
280
809
281 class NoisePlot(Plot):
810 class NoisePlot(Plot):
282 '''
811 '''
283 Plot for noise
812 Plot for noise
284 '''
813 '''
285
814
286 CODE = 'noise'
815 CODE = 'noise'
287 plot_type = 'scatterbuffer'
816 plot_type = 'scatterbuffer'
288
817
289
818
290 def setup(self):
819 def setup(self):
291 self.xaxis = 'time'
820 self.xaxis = 'time'
292 self.ncols = 1
821 self.ncols = 1
293 self.nrows = 1
822 self.nrows = 1
294 self.nplots = 1
823 self.nplots = 1
295 self.ylabel = 'Intensity [dB]'
824 self.ylabel = 'Intensity [dB]'
296 self.xlabel = 'Time'
825 self.xlabel = 'Time'
297 self.titles = ['Noise']
826 self.titles = ['Noise']
298 self.colorbar = False
827 self.colorbar = False
828 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.17, 'right':0.95})
299
829
300 def plot(self):
830 def plot(self):
301
831
302 x = self.data.times
832 x = self.data.times
303 xmin = self.data.min_time
833 xmin = self.data.min_time
304 xmax = xmin + self.xrange * 60 * 60
834 xmax = xmin + self.xrange * 60 * 60
305 Y = self.data[self.CODE]
835 Y = self.data[self.CODE]
306
836
307 if self.axes[0].firsttime:
837 if self.axes[0].firsttime:
308 for ch in self.data.channels:
838 for ch in self.data.channels:
309 y = Y[ch]
839 y = Y[ch]
310 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
840 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
311 plt.legend()
841 plt.legend()
312 else:
842 else:
313 for ch in self.data.channels:
843 for ch in self.data.channels:
314 y = Y[ch]
844 y = Y[ch]
315 self.axes[0].lines[ch].set_data(x, y)
845 self.axes[0].lines[ch].set_data(x, y)
316
846
317 self.ymin = numpy.nanmin(Y) - 5
847 self.ymin = numpy.nanmin(Y) - 5
318 self.ymax = numpy.nanmax(Y) + 5
848 self.ymax = numpy.nanmax(Y) + 10
319
849
320
850
321 class PowerProfilePlot(Plot):
851 class PowerProfilePlot(Plot):
322
852
323 CODE = 'spcprofile'
853 CODE = 'spcprofile'
324 plot_type = 'scatter'
854 plot_type = 'scatter'
325 buffering = False
855 buffering = False
326
856
327 def setup(self):
857 def setup(self):
328
858
329 self.ncols = 1
859 self.ncols = 1
330 self.nrows = 1
860 self.nrows = 1
331 self.nplots = 1
861 self.nplots = 1
332 self.height = 4
862 self.height = 4
333 self.width = 3
863 self.width = 3
334 self.ylabel = 'Range [km]'
864 self.ylabel = 'Range [km]'
335 self.xlabel = 'Intensity [dB]'
865 self.xlabel = 'Intensity [dB]'
336 self.titles = ['Power Profile']
866 self.titles = ['Power Profile']
337 self.colorbar = False
867 self.colorbar = False
338
868
339 def plot(self):
869 def plot(self):
340
870
341 y = self.data.heights
871 y = self.data.heights
342 self.y = y
872 self.y = y
343
873
344 x = self.data['spcprofile']
874 x = self.data['spcprofile']
345
875
346 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
876 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
347 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
877 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
348
878
349 if self.axes[0].firsttime:
879 if self.axes[0].firsttime:
350 for ch in self.data.channels:
880 for ch in self.data.channels:
351 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
881 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
352 plt.legend()
882 plt.legend()
353 else:
883 else:
354 for ch in self.data.channels:
884 for ch in self.data.channels:
355 self.axes[0].lines[ch].set_data(x[ch], y)
885 self.axes[0].lines[ch].set_data(x[ch], y)
356
886
357
887
358 class SpectraCutPlot(Plot):
888 class SpectraCutPlot(Plot):
359
889
360 CODE = 'spc_cut'
890 CODE = 'spc_cut'
361 plot_type = 'scatter'
891 plot_type = 'scatter'
362 buffering = False
892 buffering = False
363
893
364 def setup(self):
894 def setup(self):
365
895
366 self.nplots = len(self.data.channels)
896 self.nplots = len(self.data.channels)
367 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
897 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
368 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
898 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
369 self.width = 3.4 * self.ncols + 1.5
899 self.width = 3.4 * self.ncols + 1.5
370 self.height = 3 * self.nrows
900 self.height = 3 * self.nrows
371 self.ylabel = 'Power [dB]'
901 self.ylabel = 'Power [dB]'
372 self.colorbar = False
902 self.colorbar = False
373 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.75, 'bottom':0.08})
903 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.75, 'bottom':0.08})
374
904
375 def plot(self):
905 def plot(self):
376 if self.xaxis == "frequency":
906 if self.xaxis == "frequency":
377 x = self.data.xrange[0][1:]
907 x = self.data.xrange[0][1:]
378 self.xlabel = "Frequency (kHz)"
908 self.xlabel = "Frequency (kHz)"
379 elif self.xaxis == "time":
909 elif self.xaxis == "time":
380 x = self.data.xrange[1]
910 x = self.data.xrange[1]
381 self.xlabel = "Time (ms)"
911 self.xlabel = "Time (ms)"
382 else:
912 else:
383 x = self.data.xrange[2]
913 x = self.data.xrange[2]
384 self.xlabel = "Velocity (m/s)"
914 self.xlabel = "Velocity (m/s)"
385
915
386 self.titles = []
916 self.titles = []
387
917
388 y = self.data.heights
918 y = self.data.heights
389 #self.y = y
919 #self.y = y
390 z = self.data['spc_cut']
920 z = self.data['spc_cut']
391
921
392 if self.height_index:
922 if self.height_index:
393 index = numpy.array(self.height_index)
923 index = numpy.array(self.height_index)
394 else:
924 else:
395 index = numpy.arange(0, len(y), int((len(y))/9))
925 index = numpy.arange(0, len(y), int((len(y))/9))
396
926
397 for n, ax in enumerate(self.axes):
927 for n, ax in enumerate(self.axes):
398 if ax.firsttime:
928 if ax.firsttime:
399 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
929 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
400 self.xmin = self.xmin if self.xmin else -self.xmax
930 self.xmin = self.xmin if self.xmin else -self.xmax
401 self.ymin = self.ymin if self.ymin else numpy.nanmin(z)
931 self.ymin = self.ymin if self.ymin else numpy.nanmin(z)
402 self.ymax = self.ymax if self.ymax else numpy.nanmax(z)
932 self.ymax = self.ymax if self.ymax else numpy.nanmax(z)
403 ax.plt = ax.plot(x, z[n, :, index].T)
933 ax.plt = ax.plot(x, z[n, :, index].T)
404 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
934 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
405 self.figures[0].legend(ax.plt, labels, loc='center right')
935 self.figures[0].legend(ax.plt, labels, loc='center right')
406 else:
936 else:
407 for i, line in enumerate(ax.plt):
937 for i, line in enumerate(ax.plt):
408 line.set_data(x, z[n, :, i])
938 line.set_data(x, z[n, :, i])
409 self.titles.append('CH {}'.format(n))
939 self.titles.append('CH {}'.format(n))
410
940
411
941
412 class BeaconPhase(Plot):
942 class BeaconPhase(Plot):
413
943
414 __isConfig = None
944 __isConfig = None
415 __nsubplots = None
945 __nsubplots = None
416
946
417 PREFIX = 'beacon_phase'
947 PREFIX = 'beacon_phase'
418
948
419 def __init__(self):
949 def __init__(self):
420 Plot.__init__(self)
950 Plot.__init__(self)
421 self.timerange = 24*60*60
951 self.timerange = 24*60*60
422 self.isConfig = False
952 self.isConfig = False
423 self.__nsubplots = 1
953 self.__nsubplots = 1
424 self.counter_imagwr = 0
954 self.counter_imagwr = 0
425 self.WIDTH = 800
955 self.WIDTH = 800
426 self.HEIGHT = 400
956 self.HEIGHT = 400
427 self.WIDTHPROF = 120
957 self.WIDTHPROF = 120
428 self.HEIGHTPROF = 0
958 self.HEIGHTPROF = 0
429 self.xdata = None
959 self.xdata = None
430 self.ydata = None
960 self.ydata = None
431
961
432 self.PLOT_CODE = BEACON_CODE
962 self.PLOT_CODE = BEACON_CODE
433
963
434 self.FTP_WEI = None
964 self.FTP_WEI = None
435 self.EXP_CODE = None
965 self.EXP_CODE = None
436 self.SUB_EXP_CODE = None
966 self.SUB_EXP_CODE = None
437 self.PLOT_POS = None
967 self.PLOT_POS = None
438
968
439 self.filename_phase = None
969 self.filename_phase = None
440
970
441 self.figfile = None
971 self.figfile = None
442
972
443 self.xmin = None
973 self.xmin = None
444 self.xmax = None
974 self.xmax = None
445
975
446 def getSubplots(self):
976 def getSubplots(self):
447
977
448 ncol = 1
978 ncol = 1
449 nrow = 1
979 nrow = 1
450
980
451 return nrow, ncol
981 return nrow, ncol
452
982
453 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
983 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
454
984
455 self.__showprofile = showprofile
985 self.__showprofile = showprofile
456 self.nplots = nplots
986 self.nplots = nplots
457
987
458 ncolspan = 7
988 ncolspan = 7
459 colspan = 6
989 colspan = 6
460 self.__nsubplots = 2
990 self.__nsubplots = 2
461
991
462 self.createFigure(id = id,
992 self.createFigure(id = id,
463 wintitle = wintitle,
993 wintitle = wintitle,
464 widthplot = self.WIDTH+self.WIDTHPROF,
994 widthplot = self.WIDTH+self.WIDTHPROF,
465 heightplot = self.HEIGHT+self.HEIGHTPROF,
995 heightplot = self.HEIGHT+self.HEIGHTPROF,
466 show=show)
996 show=show)
467
997
468 nrow, ncol = self.getSubplots()
998 nrow, ncol = self.getSubplots()
469
999
470 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1000 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
471
1001
472 def save_phase(self, filename_phase):
1002 def save_phase(self, filename_phase):
473 f = open(filename_phase,'w+')
1003 f = open(filename_phase,'w+')
474 f.write('\n\n')
1004 f.write('\n\n')
475 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
1005 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
476 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
1006 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
477 f.close()
1007 f.close()
478
1008
479 def save_data(self, filename_phase, data, data_datetime):
1009 def save_data(self, filename_phase, data, data_datetime):
480 f=open(filename_phase,'a')
1010 f=open(filename_phase,'a')
481 timetuple_data = data_datetime.timetuple()
1011 timetuple_data = data_datetime.timetuple()
482 day = str(timetuple_data.tm_mday)
1012 day = str(timetuple_data.tm_mday)
483 month = str(timetuple_data.tm_mon)
1013 month = str(timetuple_data.tm_mon)
484 year = str(timetuple_data.tm_year)
1014 year = str(timetuple_data.tm_year)
485 hour = str(timetuple_data.tm_hour)
1015 hour = str(timetuple_data.tm_hour)
486 minute = str(timetuple_data.tm_min)
1016 minute = str(timetuple_data.tm_min)
487 second = str(timetuple_data.tm_sec)
1017 second = str(timetuple_data.tm_sec)
488 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
1018 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
489 f.close()
1019 f.close()
490
1020
491 def plot(self):
1021 def plot(self):
492 log.warning('TODO: Not yet implemented...')
1022 log.warning('TODO: Not yet implemented...')
493
1023
494 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1024 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
495 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
1025 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
496 timerange=None,
1026 timerange=None,
497 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1027 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
498 server=None, folder=None, username=None, password=None,
1028 server=None, folder=None, username=None, password=None,
499 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1029 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
500
1030
501 if dataOut.flagNoData:
1031 if dataOut.flagNoData:
502 return dataOut
1032 return dataOut
503
1033
504 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1034 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
505 return
1035 return
506
1036
507 if pairsList == None:
1037 if pairsList == None:
508 pairsIndexList = dataOut.pairsIndexList[:10]
1038 pairsIndexList = dataOut.pairsIndexList[:10]
509 else:
1039 else:
510 pairsIndexList = []
1040 pairsIndexList = []
511 for pair in pairsList:
1041 for pair in pairsList:
512 if pair not in dataOut.pairsList:
1042 if pair not in dataOut.pairsList:
513 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
1043 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
514 pairsIndexList.append(dataOut.pairsList.index(pair))
1044 pairsIndexList.append(dataOut.pairsList.index(pair))
515
1045
516 if pairsIndexList == []:
1046 if pairsIndexList == []:
517 return
1047 return
518
1048
519 # if len(pairsIndexList) > 4:
1049 # if len(pairsIndexList) > 4:
520 # pairsIndexList = pairsIndexList[0:4]
1050 # pairsIndexList = pairsIndexList[0:4]
521
1051
522 hmin_index = None
1052 hmin_index = None
523 hmax_index = None
1053 hmax_index = None
524
1054
525 if hmin != None and hmax != None:
1055 if hmin != None and hmax != None:
526 indexes = numpy.arange(dataOut.nHeights)
1056 indexes = numpy.arange(dataOut.nHeights)
527 hmin_list = indexes[dataOut.heightList >= hmin]
1057 hmin_list = indexes[dataOut.heightList >= hmin]
528 hmax_list = indexes[dataOut.heightList <= hmax]
1058 hmax_list = indexes[dataOut.heightList <= hmax]
529
1059
530 if hmin_list.any():
1060 if hmin_list.any():
531 hmin_index = hmin_list[0]
1061 hmin_index = hmin_list[0]
532
1062
533 if hmax_list.any():
1063 if hmax_list.any():
534 hmax_index = hmax_list[-1]+1
1064 hmax_index = hmax_list[-1]+1
535
1065
536 x = dataOut.getTimeRange()
1066 x = dataOut.getTimeRange()
537
1067
538 thisDatetime = dataOut.datatime
1068 thisDatetime = dataOut.datatime
539
1069
540 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1070 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
541 xlabel = "Local Time"
1071 xlabel = "Local Time"
542 ylabel = "Phase (degrees)"
1072 ylabel = "Phase (degrees)"
543
1073
544 update_figfile = False
1074 update_figfile = False
545
1075
546 nplots = len(pairsIndexList)
1076 nplots = len(pairsIndexList)
547 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1077 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
548 phase_beacon = numpy.zeros(len(pairsIndexList))
1078 phase_beacon = numpy.zeros(len(pairsIndexList))
549 for i in range(nplots):
1079 for i in range(nplots):
550 pair = dataOut.pairsList[pairsIndexList[i]]
1080 pair = dataOut.pairsList[pairsIndexList[i]]
551 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
1081 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
552 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
1082 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
553 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
1083 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
554 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
1084 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
555 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
1085 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
556
1086
557 if dataOut.beacon_heiIndexList:
1087 if dataOut.beacon_heiIndexList:
558 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
1088 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
559 else:
1089 else:
560 phase_beacon[i] = numpy.average(phase)
1090 phase_beacon[i] = numpy.average(phase)
561
1091
562 if not self.isConfig:
1092 if not self.isConfig:
563
1093
564 nplots = len(pairsIndexList)
1094 nplots = len(pairsIndexList)
565
1095
566 self.setup(id=id,
1096 self.setup(id=id,
567 nplots=nplots,
1097 nplots=nplots,
568 wintitle=wintitle,
1098 wintitle=wintitle,
569 showprofile=showprofile,
1099 showprofile=showprofile,
570 show=show)
1100 show=show)
571
1101
572 if timerange != None:
1102 if timerange != None:
573 self.timerange = timerange
1103 self.timerange = timerange
574
1104
575 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1105 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
576
1106
577 if ymin == None: ymin = 0
1107 if ymin == None: ymin = 0
578 if ymax == None: ymax = 360
1108 if ymax == None: ymax = 360
579
1109
580 self.FTP_WEI = ftp_wei
1110 self.FTP_WEI = ftp_wei
581 self.EXP_CODE = exp_code
1111 self.EXP_CODE = exp_code
582 self.SUB_EXP_CODE = sub_exp_code
1112 self.SUB_EXP_CODE = sub_exp_code
583 self.PLOT_POS = plot_pos
1113 self.PLOT_POS = plot_pos
584
1114
585 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1115 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
586 self.isConfig = True
1116 self.isConfig = True
587 self.figfile = figfile
1117 self.figfile = figfile
588 self.xdata = numpy.array([])
1118 self.xdata = numpy.array([])
589 self.ydata = numpy.array([])
1119 self.ydata = numpy.array([])
590
1120
591 update_figfile = True
1121 update_figfile = True
592
1122
593 #open file beacon phase
1123 #open file beacon phase
594 path = '%s%03d' %(self.PREFIX, self.id)
1124 path = '%s%03d' %(self.PREFIX, self.id)
595 beacon_file = os.path.join(path,'%s.txt'%self.name)
1125 beacon_file = os.path.join(path,'%s.txt'%self.name)
596 self.filename_phase = os.path.join(figpath,beacon_file)
1126 self.filename_phase = os.path.join(figpath,beacon_file)
597 #self.save_phase(self.filename_phase)
1127 #self.save_phase(self.filename_phase)
598
1128
599
1129
600 #store data beacon phase
1130 #store data beacon phase
601 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1131 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
602
1132
603 self.setWinTitle(title)
1133 self.setWinTitle(title)
604
1134
605
1135
606 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1136 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
607
1137
608 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
1138 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
609
1139
610 axes = self.axesList[0]
1140 axes = self.axesList[0]
611
1141
612 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1142 self.xdata = numpy.hstack((self.xdata, x[0:1]))
613
1143
614 if len(self.ydata)==0:
1144 if len(self.ydata)==0:
615 self.ydata = phase_beacon.reshape(-1,1)
1145 self.ydata = phase_beacon.reshape(-1,1)
616 else:
1146 else:
617 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1147 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
618
1148
619
1149
620 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1150 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
621 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1151 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
622 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1152 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
623 XAxisAsTime=True, grid='both'
1153 XAxisAsTime=True, grid='both'
624 )
1154 )
625
1155
626 self.draw()
1156 self.draw()
627
1157
628 if dataOut.ltctime >= self.xmax:
1158 if dataOut.ltctime >= self.xmax:
629 self.counter_imagwr = wr_period
1159 self.counter_imagwr = wr_period
630 self.isConfig = False
1160 self.isConfig = False
631 update_figfile = True
1161 update_figfile = True
632
1162
633 self.save(figpath=figpath,
1163 self.save(figpath=figpath,
634 figfile=figfile,
1164 figfile=figfile,
635 save=save,
1165 save=save,
636 ftp=ftp,
1166 ftp=ftp,
637 wr_period=wr_period,
1167 wr_period=wr_period,
638 thisDatetime=thisDatetime,
1168 thisDatetime=thisDatetime,
639 update_figfile=update_figfile)
1169 update_figfile=update_figfile)
640
1170
641 return dataOut
1171 return dataOut
@@ -1,24 +1,29
1 '''
1 '''
2
2
3 $Author: murco $
3 $Author: murco $
4 $Id: JRODataIO.py 169 2012-11-19 21:57:03Z murco $
4 $Id: JRODataIO.py 169 2012-11-19 21:57:03Z murco $
5 '''
5 '''
6
6
7 from .jroIO_voltage import *
7 from .jroIO_voltage import *
8 from .jroIO_spectra import *
8 from .jroIO_spectra import *
9 from .jroIO_heispectra import *
9 from .jroIO_heispectra import *
10 from .jroIO_usrp import *
10 from .jroIO_usrp import *
11 from .jroIO_digitalRF import *
11 from .jroIO_digitalRF import *
12 from .jroIO_kamisr import *
12 from .jroIO_kamisr import *
13 from .jroIO_param import *
13 from .jroIO_param import *
14 from .jroIO_hf import *
14 from .jroIO_hf import *
15
15
16 from .jroIO_madrigal import *
16 from .jroIO_madrigal import *
17
17
18 from .bltrIO_param import *
18 from .bltrIO_param import *
19 from .bltrIO_spectra import *
19 from .bltrIO_spectra import *
20 from .jroIO_mira35c import *
20 from .jroIO_mira35c import *
21 from .julIO_param import *
21 from .julIO_param import *
22
22
23 from .pxIO_param import *
23 from .pxIO_param import *
24 from .jroIO_simulator import *
24 from .jroIO_simulator import *
25
26 ############DP############
27 from .jroIO_dat import *
28
29 ############DP############
@@ -1,1575 +1,1615
1 """
1 """
2 Created on Jul 2, 2014
2 Created on Jul 2, 2014
3
3
4 @author: roj-idl71
4 @author: roj-idl71
5 """
5 """
6 import os
6 import os
7 import sys
7 import sys
8 import glob
8 import glob
9 import time
9 import time
10 import numpy
10 import numpy
11 import fnmatch
11 import fnmatch
12 import inspect
12 import inspect
13 import time
13 import time
14 import datetime
14 import datetime
15 import zmq
15 import zmq
16
16
17 from schainpy.model.proc.jroproc_base import Operation, MPDecorator
17 from schainpy.model.proc.jroproc_base import Operation, MPDecorator
18 from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader
18 from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader
19 from schainpy.model.data.jroheaderIO import get_dtype_index, get_numpy_dtype, get_procflag_dtype, get_dtype_width
19 from schainpy.model.data.jroheaderIO import get_dtype_index, get_numpy_dtype, get_procflag_dtype, get_dtype_width
20 from schainpy.utils import log
20 from schainpy.utils import log
21 import schainpy.admin
21 import schainpy.admin
22
22
23 LOCALTIME = True
23 LOCALTIME = True
24 DT_DIRECTIVES = {
24 DT_DIRECTIVES = {
25 '%Y': 4,
25 '%Y': 4,
26 '%y': 2,
26 '%y': 2,
27 '%m': 2,
27 '%m': 2,
28 '%d': 2,
28 '%d': 2,
29 '%j': 3,
29 '%j': 3,
30 '%H': 2,
30 '%H': 2,
31 '%M': 2,
31 '%M': 2,
32 '%S': 2,
32 '%S': 2,
33 '%f': 6
33 '%f': 6
34 }
34 }
35
35
36
36
37 def isNumber(cad):
37 def isNumber(cad):
38 """
38 """
39 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
39 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
40
40
41 Excepciones:
41 Excepciones:
42 Si un determinado string no puede ser convertido a numero
42 Si un determinado string no puede ser convertido a numero
43 Input:
43 Input:
44 str, string al cual se le analiza para determinar si convertible a un numero o no
44 str, string al cual se le analiza para determinar si convertible a un numero o no
45
45
46 Return:
46 Return:
47 True : si el string es uno numerico
47 True : si el string es uno numerico
48 False : no es un string numerico
48 False : no es un string numerico
49 """
49 """
50 try:
50 try:
51 float(cad)
51 float(cad)
52 return True
52 return True
53 except:
53 except:
54 return False
54 return False
55
55
56
56
57 def isFileInEpoch(filename, startUTSeconds, endUTSeconds):
57 def isFileInEpoch(filename, startUTSeconds, endUTSeconds):
58 """
58 """
59 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
59 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
60
60
61 Inputs:
61 Inputs:
62 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
62 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
63
63
64 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
64 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
65 segundos contados desde 01/01/1970.
65 segundos contados desde 01/01/1970.
66 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
66 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
67 segundos contados desde 01/01/1970.
67 segundos contados desde 01/01/1970.
68
68
69 Return:
69 Return:
70 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
70 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
71 fecha especificado, de lo contrario retorna False.
71 fecha especificado, de lo contrario retorna False.
72
72
73 Excepciones:
73 Excepciones:
74 Si el archivo no existe o no puede ser abierto
74 Si el archivo no existe o no puede ser abierto
75 Si la cabecera no puede ser leida.
75 Si la cabecera no puede ser leida.
76
76
77 """
77 """
78 basicHeaderObj = BasicHeader(LOCALTIME)
78 basicHeaderObj = BasicHeader(LOCALTIME)
79
79
80 try:
80 try:
81
81 fp = open(filename, 'rb')
82 fp = open(filename, 'rb')
82 except IOError:
83 except IOError:
83 print("The file %s can't be opened" % (filename))
84 print("The file %s can't be opened" % (filename))
84 return 0
85 return 0
85
86
86 sts = basicHeaderObj.read(fp)
87 sts = basicHeaderObj.read(fp)
87 fp.close()
88 fp.close()
88
89
89 if not(sts):
90 if not(sts):
90 print("Skipping the file %s because it has not a valid header" % (filename))
91 print("Skipping the file %s because it has not a valid header" % (filename))
91 return 0
92 return 0
92
93
93 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
94 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
94 return 0
95 return 0
95
96
96 return 1
97 return 1
97
98
98
99
99 def isTimeInRange(thisTime, startTime, endTime):
100 def isTimeInRange(thisTime, startTime, endTime):
100 if endTime >= startTime:
101 if endTime >= startTime:
101 if (thisTime < startTime) or (thisTime > endTime):
102 if (thisTime < startTime) or (thisTime > endTime):
102 return 0
103 return 0
103 return 1
104 return 1
104 else:
105 else:
105 if (thisTime < startTime) and (thisTime > endTime):
106 if (thisTime < startTime) and (thisTime > endTime):
106 return 0
107 return 0
107 return 1
108 return 1
108
109
109
110
110 def isFileInTimeRange(filename, startDate, endDate, startTime, endTime):
111 def isFileInTimeRange(filename, startDate, endDate, startTime, endTime):
111 """
112 """
112 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
113 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
113
114
114 Inputs:
115 Inputs:
115 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
116 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
116
117
117 startDate : fecha inicial del rango seleccionado en formato datetime.date
118 startDate : fecha inicial del rango seleccionado en formato datetime.date
118
119
119 endDate : fecha final del rango seleccionado en formato datetime.date
120 endDate : fecha final del rango seleccionado en formato datetime.date
120
121
121 startTime : tiempo inicial del rango seleccionado en formato datetime.time
122 startTime : tiempo inicial del rango seleccionado en formato datetime.time
122
123
123 endTime : tiempo final del rango seleccionado en formato datetime.time
124 endTime : tiempo final del rango seleccionado en formato datetime.time
124
125
125 Return:
126 Return:
126 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
127 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
127 fecha especificado, de lo contrario retorna False.
128 fecha especificado, de lo contrario retorna False.
128
129
129 Excepciones:
130 Excepciones:
130 Si el archivo no existe o no puede ser abierto
131 Si el archivo no existe o no puede ser abierto
131 Si la cabecera no puede ser leida.
132 Si la cabecera no puede ser leida.
132
133
133 """
134 """
134
135
135 try:
136 try:
136 fp = open(filename, 'rb')
137 fp = open(filename, 'rb')
137 except IOError:
138 except IOError:
138 print("The file %s can't be opened" % (filename))
139 print("The file %s can't be opened" % (filename))
139 return None
140 return None
140
141
141 firstBasicHeaderObj = BasicHeader(LOCALTIME)
142 firstBasicHeaderObj = BasicHeader(LOCALTIME)
142 systemHeaderObj = SystemHeader()
143 systemHeaderObj = SystemHeader()
144
143 radarControllerHeaderObj = RadarControllerHeader()
145 radarControllerHeaderObj = RadarControllerHeader()
144 processingHeaderObj = ProcessingHeader()
146 processingHeaderObj = ProcessingHeader()
145
147
146 lastBasicHeaderObj = BasicHeader(LOCALTIME)
148 lastBasicHeaderObj = BasicHeader(LOCALTIME)
147
149
148 sts = firstBasicHeaderObj.read(fp)
150 sts = firstBasicHeaderObj.read(fp)
149
151
150 if not(sts):
152 if not(sts):
151 print("[Reading] Skipping the file %s because it has not a valid header" % (filename))
153 print("[Reading] Skipping the file %s because it has not a valid header" % (filename))
152 return None
154 return None
153
155
154 if not systemHeaderObj.read(fp):
156 if not systemHeaderObj.read(fp):
155 return None
157 return None
156
158
157 if not radarControllerHeaderObj.read(fp):
159 if not radarControllerHeaderObj.read(fp):
158 return None
160 return None
159
161
160 if not processingHeaderObj.read(fp):
162 if not processingHeaderObj.read(fp):
161 return None
163 return None
162
164
163 filesize = os.path.getsize(filename)
165 filesize = os.path.getsize(filename)
164
166
165 offset = processingHeaderObj.blockSize + 24 # header size
167 offset = processingHeaderObj.blockSize + 24 # header size
166
168
167 if filesize <= offset:
169 if filesize <= offset:
168 print("[Reading] %s: This file has not enough data" % filename)
170 print("[Reading] %s: This file has not enough data" % filename)
169 return None
171 return None
170
172
171 fp.seek(-offset, 2)
173 fp.seek(-offset, 2)
172
174
173 sts = lastBasicHeaderObj.read(fp)
175 sts = lastBasicHeaderObj.read(fp)
174
176
175 fp.close()
177 fp.close()
176
178
177 thisDatetime = lastBasicHeaderObj.datatime
179 thisDatetime = lastBasicHeaderObj.datatime
178 thisTime_last_block = thisDatetime.time()
180 thisTime_last_block = thisDatetime.time()
179
181
180 thisDatetime = firstBasicHeaderObj.datatime
182 thisDatetime = firstBasicHeaderObj.datatime
181 thisDate = thisDatetime.date()
183 thisDate = thisDatetime.date()
182 thisTime_first_block = thisDatetime.time()
184 thisTime_first_block = thisDatetime.time()
183
185
184 # General case
186 # General case
185 # o>>>>>>>>>>>>>><<<<<<<<<<<<<<o
187 # o>>>>>>>>>>>>>><<<<<<<<<<<<<<o
186 #-----------o----------------------------o-----------
188 #-----------o----------------------------o-----------
187 # startTime endTime
189 # startTime endTime
188
190
189 if endTime >= startTime:
191 if endTime >= startTime:
190 if (thisTime_last_block < startTime) or (thisTime_first_block > endTime):
192 if (thisTime_last_block < startTime) or (thisTime_first_block > endTime):
191 return None
193 return None
192
194
193 return thisDatetime
195 return thisDatetime
194
196
195 # If endTime < startTime then endTime belongs to the next day
197 # If endTime < startTime then endTime belongs to the next day
196
198
197 #<<<<<<<<<<<o o>>>>>>>>>>>
199 #<<<<<<<<<<<o o>>>>>>>>>>>
198 #-----------o----------------------------o-----------
200 #-----------o----------------------------o-----------
199 # endTime startTime
201 # endTime startTime
200
202
201 if (thisDate == startDate) and (thisTime_last_block < startTime):
203 if (thisDate == startDate) and (thisTime_last_block < startTime):
202 return None
204 return None
203
205
204 if (thisDate == endDate) and (thisTime_first_block > endTime):
206 if (thisDate == endDate) and (thisTime_first_block > endTime):
205 return None
207 return None
206
208
207 if (thisTime_last_block < startTime) and (thisTime_first_block > endTime):
209 if (thisTime_last_block < startTime) and (thisTime_first_block > endTime):
208 return None
210 return None
209
211
210 return thisDatetime
212 return thisDatetime
211
213
212
214
213 def isFolderInDateRange(folder, startDate=None, endDate=None):
215 def isFolderInDateRange(folder, startDate=None, endDate=None):
214 """
216 """
215 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
217 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
216
218
217 Inputs:
219 Inputs:
218 folder : nombre completo del directorio.
220 folder : nombre completo del directorio.
219 Su formato deberia ser "/path_root/?YYYYDDD"
221 Su formato deberia ser "/path_root/?YYYYDDD"
220
222
221 siendo:
223 siendo:
222 YYYY : Anio (ejemplo 2015)
224 YYYY : Anio (ejemplo 2015)
223 DDD : Dia del anio (ejemplo 305)
225 DDD : Dia del anio (ejemplo 305)
224
226
225 startDate : fecha inicial del rango seleccionado en formato datetime.date
227 startDate : fecha inicial del rango seleccionado en formato datetime.date
226
228
227 endDate : fecha final del rango seleccionado en formato datetime.date
229 endDate : fecha final del rango seleccionado en formato datetime.date
228
230
229 Return:
231 Return:
230 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
232 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
231 fecha especificado, de lo contrario retorna False.
233 fecha especificado, de lo contrario retorna False.
232 Excepciones:
234 Excepciones:
233 Si el directorio no tiene el formato adecuado
235 Si el directorio no tiene el formato adecuado
234 """
236 """
235
237
236 basename = os.path.basename(folder)
238 basename = os.path.basename(folder)
237
239
238 if not isRadarFolder(basename):
240 if not isRadarFolder(basename):
239 print("The folder %s has not the rigth format" % folder)
241 print("The folder %s has not the rigth format" % folder)
240 return 0
242 return 0
241
243
242 if startDate and endDate:
244 if startDate and endDate:
243 thisDate = getDateFromRadarFolder(basename)
245 thisDate = getDateFromRadarFolder(basename)
244
246
245 if thisDate < startDate:
247 if thisDate < startDate:
246 return 0
248 return 0
247
249
248 if thisDate > endDate:
250 if thisDate > endDate:
249 return 0
251 return 0
250
252
251 return 1
253 return 1
252
254
253
255
254 def isFileInDateRange(filename, startDate=None, endDate=None):
256 def isFileInDateRange(filename, startDate=None, endDate=None):
255 """
257 """
256 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
258 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
257
259
258 Inputs:
260 Inputs:
259 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
261 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
260
262
261 Su formato deberia ser "?YYYYDDDsss"
263 Su formato deberia ser "?YYYYDDDsss"
262
264
263 siendo:
265 siendo:
264 YYYY : Anio (ejemplo 2015)
266 YYYY : Anio (ejemplo 2015)
265 DDD : Dia del anio (ejemplo 305)
267 DDD : Dia del anio (ejemplo 305)
266 sss : set
268 sss : set
267
269
268 startDate : fecha inicial del rango seleccionado en formato datetime.date
270 startDate : fecha inicial del rango seleccionado en formato datetime.date
269
271
270 endDate : fecha final del rango seleccionado en formato datetime.date
272 endDate : fecha final del rango seleccionado en formato datetime.date
271
273
272 Return:
274 Return:
273 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
275 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
274 fecha especificado, de lo contrario retorna False.
276 fecha especificado, de lo contrario retorna False.
275 Excepciones:
277 Excepciones:
276 Si el archivo no tiene el formato adecuado
278 Si el archivo no tiene el formato adecuado
277 """
279 """
278
280
279 basename = os.path.basename(filename)
281 basename = os.path.basename(filename)
280
282
281 if not isRadarFile(basename):
283 if not isRadarFile(basename):
282 print("The filename %s has not the rigth format" % filename)
284 print("The filename %s has not the rigth format" % filename)
283 return 0
285 return 0
284
286
285 if startDate and endDate:
287 if startDate and endDate:
286 thisDate = getDateFromRadarFile(basename)
288 thisDate = getDateFromRadarFile(basename)
287
289
288 if thisDate < startDate:
290 if thisDate < startDate:
289 return 0
291 return 0
290
292
291 if thisDate > endDate:
293 if thisDate > endDate:
292 return 0
294 return 0
293
295
294 return 1
296 return 1
295
297
296
298
297 def getFileFromSet(path, ext, set):
299 def getFileFromSet(path, ext, set):
298 validFilelist = []
300 validFilelist = []
299 fileList = os.listdir(path)
301 fileList = os.listdir(path)
300
302
301 # 0 1234 567 89A BCDE
303 # 0 1234 567 89A BCDE
302 # H YYYY DDD SSS .ext
304 # H YYYY DDD SSS .ext
303
305
304 for thisFile in fileList:
306 for thisFile in fileList:
305 try:
307 try:
306 year = int(thisFile[1:5])
308 year = int(thisFile[1:5])
307 doy = int(thisFile[5:8])
309 doy = int(thisFile[5:8])
308 except:
310 except:
309 continue
311 continue
310
312
311 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
313 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
312 continue
314 continue
313
315
314 validFilelist.append(thisFile)
316 validFilelist.append(thisFile)
315
317
316 myfile = fnmatch.filter(
318 myfile = fnmatch.filter(
317 validFilelist, '*%4.4d%3.3d%3.3d*' % (year, doy, set))
319 validFilelist, '*%4.4d%3.3d%3.3d*' % (year, doy, set))
318
320
319 if len(myfile) != 0:
321 if len(myfile) != 0:
320 return myfile[0]
322 return myfile[0]
321 else:
323 else:
322 filename = '*%4.4d%3.3d%3.3d%s' % (year, doy, set, ext.lower())
324 filename = '*%4.4d%3.3d%3.3d%s' % (year, doy, set, ext.lower())
323 print('the filename %s does not exist' % filename)
325 print('the filename %s does not exist' % filename)
324 print('...going to the last file: ')
326 print('...going to the last file: ')
325
327
326 if validFilelist:
328 if validFilelist:
327 validFilelist = sorted(validFilelist, key=str.lower)
329 validFilelist = sorted(validFilelist, key=str.lower)
328 return validFilelist[-1]
330 return validFilelist[-1]
329
331
330 return None
332 return None
331
333
332
334
333 def getlastFileFromPath(path, ext):
335 def getlastFileFromPath(path, ext):
334 """
336 """
335 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
337 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
336 al final de la depuracion devuelve el ultimo file de la lista que quedo.
338 al final de la depuracion devuelve el ultimo file de la lista que quedo.
337
339
338 Input:
340 Input:
339 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
341 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
340 ext : extension de los files contenidos en una carpeta
342 ext : extension de los files contenidos en una carpeta
341
343
342 Return:
344 Return:
343 El ultimo file de una determinada carpeta, no se considera el path.
345 El ultimo file de una determinada carpeta, no se considera el path.
344 """
346 """
345 validFilelist = []
347 validFilelist = []
346 fileList = os.listdir(path)
348 fileList = os.listdir(path)
347
349
348 # 0 1234 567 89A BCDE
350 # 0 1234 567 89A BCDE
349 # H YYYY DDD SSS .ext
351 # H YYYY DDD SSS .ext
350
352
351 for thisFile in fileList:
353 for thisFile in fileList:
352
354
353 year = thisFile[1:5]
355 year = thisFile[1:5]
354 if not isNumber(year):
356 if not isNumber(year):
355 continue
357 continue
356
358
357 doy = thisFile[5:8]
359 doy = thisFile[5:8]
358 if not isNumber(doy):
360 if not isNumber(doy):
359 continue
361 continue
360
362
361 year = int(year)
363 year = int(year)
362 doy = int(doy)
364 doy = int(doy)
363
365
364 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
366 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
365 continue
367 continue
366
368
367 validFilelist.append(thisFile)
369 validFilelist.append(thisFile)
368
370
369 if validFilelist:
371 if validFilelist:
370 validFilelist = sorted(validFilelist, key=str.lower)
372 validFilelist = sorted(validFilelist, key=str.lower)
371 return validFilelist[-1]
373 return validFilelist[-1]
372
374
373 return None
375 return None
374
376
375
377
376 def isRadarFolder(folder):
378 def isRadarFolder(folder):
377 try:
379 try:
378 year = int(folder[1:5])
380 year = int(folder[1:5])
379 doy = int(folder[5:8])
381 doy = int(folder[5:8])
380 except:
382 except:
381 return 0
383 return 0
382
384
383 return 1
385 return 1
384
386
385
387
386 def isRadarFile(file):
388 def isRadarFile(file):
387 try:
389 try:
388 year = int(file[1:5])
390 year = int(file[1:5])
389 doy = int(file[5:8])
391 doy = int(file[5:8])
390 set = int(file[8:11])
392 set = int(file[8:11])
391 except:
393 except:
392 return 0
394 return 0
393
395
394 return 1
396 return 1
395
397
396
398
397 def getDateFromRadarFile(file):
399 def getDateFromRadarFile(file):
398 try:
400 try:
399 year = int(file[1:5])
401 year = int(file[1:5])
400 doy = int(file[5:8])
402 doy = int(file[5:8])
401 set = int(file[8:11])
403 set = int(file[8:11])
402 except:
404 except:
403 return None
405 return None
404
406
405 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
407 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
406 return thisDate
408 return thisDate
407
409
408
410
409 def getDateFromRadarFolder(folder):
411 def getDateFromRadarFolder(folder):
410 try:
412 try:
411 year = int(folder[1:5])
413 year = int(folder[1:5])
412 doy = int(folder[5:8])
414 doy = int(folder[5:8])
413 except:
415 except:
414 return None
416 return None
415
417
416 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
418 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
417 return thisDate
419 return thisDate
418
420
419 def parse_format(s, fmt):
421 def parse_format(s, fmt):
420
422
421 for i in range(fmt.count('%')):
423 for i in range(fmt.count('%')):
422 x = fmt.index('%')
424 x = fmt.index('%')
423 d = DT_DIRECTIVES[fmt[x:x+2]]
425 d = DT_DIRECTIVES[fmt[x:x+2]]
424 fmt = fmt.replace(fmt[x:x+2], s[x:x+d])
426 fmt = fmt.replace(fmt[x:x+2], s[x:x+d])
425 return fmt
427 return fmt
426
428
427 class Reader(object):
429 class Reader(object):
428
430
429 c = 3E8
431 c = 3E8
430 isConfig = False
432 isConfig = False
431 dtype = None
433 dtype = None
432 pathList = []
434 pathList = []
433 filenameList = []
435 filenameList = []
434 datetimeList = []
436 datetimeList = []
435 filename = None
437 filename = None
436 ext = None
438 ext = None
437 flagIsNewFile = 1
439 flagIsNewFile = 1
438 flagDiscontinuousBlock = 0
440 flagDiscontinuousBlock = 0
439 flagIsNewBlock = 0
441 flagIsNewBlock = 0
440 flagNoMoreFiles = 0
442 flagNoMoreFiles = 0
441 fp = None
443 fp = None
442 firstHeaderSize = 0
444 firstHeaderSize = 0
443 basicHeaderSize = 24
445 basicHeaderSize = 24
444 versionFile = 1103
446 versionFile = 1103
445 fileSize = None
447 fileSize = None
446 fileSizeByHeader = None
448 fileSizeByHeader = None
447 fileIndex = -1
449 fileIndex = -1
448 profileIndex = None
450 profileIndex = None
449 blockIndex = 0
451 blockIndex = 0
450 nTotalBlocks = 0
452 nTotalBlocks = 0
451 maxTimeStep = 30
453 maxTimeStep = 30
452 lastUTTime = None
454 lastUTTime = None
453 datablock = None
455 datablock = None
454 dataOut = None
456 dataOut = None
455 getByBlock = False
457 getByBlock = False
456 path = None
458 path = None
457 startDate = None
459 startDate = None
458 endDate = None
460 endDate = None
459 startTime = datetime.time(0, 0, 0)
461 startTime = datetime.time(0, 0, 0)
460 endTime = datetime.time(23, 59, 59)
462 endTime = datetime.time(23, 59, 59)
461 set = None
463 set = None
462 expLabel = ""
464 expLabel = ""
463 online = False
465 online = False
464 delay = 60
466 delay = 60
465 nTries = 3 # quantity tries
467 nTries = 3 # quantity tries
466 nFiles = 3 # number of files for searching
468 nFiles = 3 # number of files for searching
467 walk = True
469 walk = True
468 getblock = False
470 getblock = False
469 nTxs = 1
471 nTxs = 1
470 realtime = False
472 realtime = False
471 blocksize = 0
473 blocksize = 0
472 blocktime = None
474 blocktime = None
473 warnings = True
475 warnings = True
474 verbose = True
476 verbose = True
475 server = None
477 server = None
476 format = None
478 format = None
477 oneDDict = None
479 oneDDict = None
478 twoDDict = None
480 twoDDict = None
479 independentParam = None
481 independentParam = None
480 filefmt = None
482 filefmt = None
481 folderfmt = None
483 folderfmt = None
482 open_file = open
484 open_file = open
483 open_mode = 'rb'
485 open_mode = 'rb'
484
486
485 def run(self):
487 def run(self):
486
488
487 raise NotImplementedError
489 raise NotImplementedError
488
490
489 def getAllowedArgs(self):
491 def getAllowedArgs(self):
490 if hasattr(self, '__attrs__'):
492 if hasattr(self, '__attrs__'):
491 return self.__attrs__
493 return self.__attrs__
492 else:
494 else:
493 return inspect.getargspec(self.run).args
495 return inspect.getargspec(self.run).args
494
496
495 def set_kwargs(self, **kwargs):
497 def set_kwargs(self, **kwargs):
496
498
497 for key, value in kwargs.items():
499 for key, value in kwargs.items():
498 setattr(self, key, value)
500 setattr(self, key, value)
499
501
500 def find_folders(self, path, startDate, endDate, folderfmt, last=False):
502 def find_folders(self, path, startDate, endDate, folderfmt, last=False):
501
503
502 folders = [x for f in path.split(',')
504 folders = [x for f in path.split(',')
503 for x in os.listdir(f) if os.path.isdir(os.path.join(f, x))]
505 for x in os.listdir(f) if os.path.isdir(os.path.join(f, x))]
504 folders.sort()
506 folders.sort()
505
507
506 if last:
508 if last:
507 folders = [folders[-1]]
509 folders = [folders[-1]]
508
510
509 for folder in folders:
511 for folder in folders:
510 try:
512 try:
511 dt = datetime.datetime.strptime(parse_format(folder, folderfmt), folderfmt).date()
513 dt = datetime.datetime.strptime(parse_format(folder, folderfmt), folderfmt).date()
512 if dt >= startDate and dt <= endDate:
514 if dt >= startDate and dt <= endDate:
513 yield os.path.join(path, folder)
515 yield os.path.join(path, folder)
514 else:
516 else:
515 log.log('Skiping folder {}'.format(folder), self.name)
517 log.log('Skiping folder {}'.format(folder), self.name)
516 except Exception as e:
518 except Exception as e:
517 log.log('Skiping folder {}'.format(folder), self.name)
519 log.log('Skiping folder {}'.format(folder), self.name)
518 continue
520 continue
519 return
521 return
520
522
521 def find_files(self, folders, ext, filefmt, startDate=None, endDate=None,
523 def find_files(self, folders, ext, filefmt, startDate=None, endDate=None,
522 expLabel='', last=False):
524 expLabel='', last=False):
523
525
524 for path in folders:
526 for path in folders:
525 files = glob.glob1(path, '*{}'.format(ext))
527 files = glob.glob1(path, '*{}'.format(ext))
526 files.sort()
528 files.sort()
527 if last:
529 if last:
528 if files:
530 if files:
529 fo = files[-1]
531 fo = files[-1]
530 try:
532 try:
531 dt = datetime.datetime.strptime(parse_format(fo, filefmt), filefmt).date()
533 dt = datetime.datetime.strptime(parse_format(fo, filefmt), filefmt).date()
532 yield os.path.join(path, expLabel, fo)
534 yield os.path.join(path, expLabel, fo)
533 except Exception as e:
535 except Exception as e:
534 pass
536 pass
535 return
537 return
536 else:
538 else:
537 return
539 return
538
540
539 for fo in files:
541 for fo in files:
540 try:
542 try:
541 dt = datetime.datetime.strptime(parse_format(fo, filefmt), filefmt).date()
543 dt = datetime.datetime.strptime(parse_format(fo, filefmt), filefmt).date()
544 #print(dt)
545 #print(startDate)
546 #print(endDate)
542 if dt >= startDate and dt <= endDate:
547 if dt >= startDate and dt <= endDate:
548
543 yield os.path.join(path, expLabel, fo)
549 yield os.path.join(path, expLabel, fo)
550
544 else:
551 else:
552
545 log.log('Skiping file {}'.format(fo), self.name)
553 log.log('Skiping file {}'.format(fo), self.name)
546 except Exception as e:
554 except Exception as e:
547 log.log('Skiping file {}'.format(fo), self.name)
555 log.log('Skiping file {}'.format(fo), self.name)
548 continue
556 continue
549
557
550 def searchFilesOffLine(self, path, startDate, endDate,
558 def searchFilesOffLine(self, path, startDate, endDate,
551 expLabel, ext, walk,
559 expLabel, ext, walk,
552 filefmt, folderfmt):
560 filefmt, folderfmt):
553 """Search files in offline mode for the given arguments
561 """Search files in offline mode for the given arguments
554
562
555 Return:
563 Return:
556 Generator of files
564 Generator of files
557 """
565 """
558
566
559 if walk:
567 if walk:
560 folders = self.find_folders(
568 folders = self.find_folders(
561 path, startDate, endDate, folderfmt)
569 path, startDate, endDate, folderfmt)
562 else:
570 else:
563 folders = path.split(',')
571 folders = path.split(',')
564
572
565 return self.find_files(
573 return self.find_files(
566 folders, ext, filefmt, startDate, endDate, expLabel)
574 folders, ext, filefmt, startDate, endDate, expLabel)
567
575
568 def searchFilesOnLine(self, path, startDate, endDate,
576 def searchFilesOnLine(self, path, startDate, endDate,
569 expLabel, ext, walk,
577 expLabel, ext, walk,
570 filefmt, folderfmt):
578 filefmt, folderfmt):
571 """Search for the last file of the last folder
579 """Search for the last file of the last folder
572
580
573 Arguments:
581 Arguments:
574 path : carpeta donde estan contenidos los files que contiene data
582 path : carpeta donde estan contenidos los files que contiene data
575 expLabel : Nombre del subexperimento (subfolder)
583 expLabel : Nombre del subexperimento (subfolder)
576 ext : extension de los files
584 ext : extension de los files
577 walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath)
585 walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath)
578
586
579 Return:
587 Return:
580 generator with the full path of last filename
588 generator with the full path of last filename
581 """
589 """
582
590
583 if walk:
591 if walk:
584 folders = self.find_folders(
592 folders = self.find_folders(
585 path, startDate, endDate, folderfmt, last=True)
593 path, startDate, endDate, folderfmt, last=True)
586 else:
594 else:
587 folders = path.split(',')
595 folders = path.split(',')
588
596
589 return self.find_files(
597 return self.find_files(
590 folders, ext, filefmt, startDate, endDate, expLabel, last=True)
598 folders, ext, filefmt, startDate, endDate, expLabel, last=True)
591
599
592 def setNextFile(self):
600 def setNextFile(self):
593 """Set the next file to be readed open it and parse de file header"""
601 """Set the next file to be readed open it and parse de file header"""
594
602
603 #print("fp: ",self.fp)
595 while True:
604 while True:
605
606 #print(self.fp)
596 if self.fp != None:
607 if self.fp != None:
597 self.fp.close()
608 self.fp.close()
598
609
610 #print("setNextFile")
611 #print("BEFORE OPENING",self.filename)
599 if self.online:
612 if self.online:
600 newFile = self.setNextFileOnline()
613 newFile = self.setNextFileOnline()
614
601 else:
615 else:
616
602 newFile = self.setNextFileOffline()
617 newFile = self.setNextFileOffline()
603
618
619 #print("newFile: ",newFile)
604 if not(newFile):
620 if not(newFile):
621
605 if self.online:
622 if self.online:
606 raise schainpy.admin.SchainError('Time to wait for new files reach')
623 raise schainpy.admin.SchainError('Time to wait for new files reach')
607 else:
624 else:
608 if self.fileIndex == -1:
625 if self.fileIndex == -1:
626 #print("OKK")
609 raise schainpy.admin.SchainWarning('No files found in the given path')
627 raise schainpy.admin.SchainWarning('No files found in the given path')
610 else:
628 else:
629
611 raise schainpy.admin.SchainWarning('No more files to read')
630 raise schainpy.admin.SchainWarning('No more files to read')
612
631
613 if self.verifyFile(self.filename):
632 if self.verifyFile(self.filename):
633
614 break
634 break
615
635
636 ##print("BEFORE OPENING",self.filename)
637
616 log.log('Opening file: %s' % self.filename, self.name)
638 log.log('Opening file: %s' % self.filename, self.name)
617
639
618 self.readFirstHeader()
640 self.readFirstHeader()
619 self.nReadBlocks = 0
641 self.nReadBlocks = 0
620
642
621 def setNextFileOnline(self):
643 def setNextFileOnline(self):
622 """Check for the next file to be readed in online mode.
644 """Check for the next file to be readed in online mode.
623
645
624 Set:
646 Set:
625 self.filename
647 self.filename
626 self.fp
648 self.fp
627 self.filesize
649 self.filesize
628
650
629 Return:
651 Return:
630 boolean
652 boolean
631
653
632 """
654 """
655
633 nextFile = True
656 nextFile = True
634 nextDay = False
657 nextDay = False
635
658
636 for nFiles in range(self.nFiles+1):
659 for nFiles in range(self.nFiles+1):
637 for nTries in range(self.nTries):
660 for nTries in range(self.nTries):
638 fullfilename, filename = self.checkForRealPath(nextFile, nextDay)
661 fullfilename, filename = self.checkForRealPath(nextFile, nextDay)
639 if fullfilename is not None:
662 if fullfilename is not None:
640 break
663 break
641 log.warning(
664 log.warning(
642 "Waiting %0.2f sec for the next file: \"%s\" , try %02d ..." % (self.delay, filename, nTries + 1),
665 "Waiting %0.2f sec for the next file: \"%s\" , try %02d ..." % (self.delay, filename, nTries + 1),
643 self.name)
666 self.name)
644 time.sleep(self.delay)
667 time.sleep(self.delay)
645 nextFile = False
668 nextFile = False
646 continue
669 continue
647
670
648 if fullfilename is not None:
671 if fullfilename is not None:
649 break
672 break
650
673
651 self.nTries = 1
674 #self.nTries = 1
652 nextFile = True
675 nextFile = True
653
676
654 if nFiles == (self.nFiles - 1):
677 if nFiles == (self.nFiles - 1):
655 log.log('Trying with next day...', self.name)
678 log.log('Trying with next day...', self.name)
656 nextDay = True
679 nextDay = True
657 self.nTries = 3
680 self.nTries = 3
658
681
659 if fullfilename:
682 if fullfilename:
660 self.fileSize = os.path.getsize(fullfilename)
683 self.fileSize = os.path.getsize(fullfilename)
661 self.filename = fullfilename
684 self.filename = fullfilename
662 self.flagIsNewFile = 1
685 self.flagIsNewFile = 1
663 if self.fp != None:
686 if self.fp != None:
664 self.fp.close()
687 self.fp.close()
688 #print(fullfilename)
665 self.fp = self.open_file(fullfilename, self.open_mode)
689 self.fp = self.open_file(fullfilename, self.open_mode)
690
666 self.flagNoMoreFiles = 0
691 self.flagNoMoreFiles = 0
667 self.fileIndex += 1
692 self.fileIndex += 1
668 return 1
693 return 1
669 else:
694 else:
670 return 0
695 return 0
671
696
672 def setNextFileOffline(self):
697 def setNextFileOffline(self):
673 """Open the next file to be readed in offline mode"""
698 """Open the next file to be readed in offline mode"""
674
699
675 try:
700 try:
676 filename = next(self.filenameList)
701 filename = next(self.filenameList)
677 self.fileIndex +=1
702 self.fileIndex +=1
678 except StopIteration:
703 except StopIteration:
679 self.flagNoMoreFiles = 1
704 self.flagNoMoreFiles = 1
680 return 0
705 return 0
681
706 #print(self.fileIndex)
707 #print(filename)
682 self.filename = filename
708 self.filename = filename
683 self.fileSize = os.path.getsize(filename)
709 self.fileSize = os.path.getsize(filename)
684 self.fp = self.open_file(filename, self.open_mode)
710 self.fp = self.open_file(filename, self.open_mode)
685 self.flagIsNewFile = 1
711 self.flagIsNewFile = 1
686
712
687 return 1
713 return 1
688
714
689 @staticmethod
715 @staticmethod
690 def isDateTimeInRange(dt, startDate, endDate, startTime, endTime):
716 def isDateTimeInRange(dt, startDate, endDate, startTime, endTime):
691 """Check if the given datetime is in range"""
717 """Check if the given datetime is in range"""
692
718
693 if startDate <= dt.date() <= endDate:
719 if startDate <= dt.date() <= endDate:
694 if startTime <= dt.time() <= endTime:
720 if startTime <= dt.time() <= endTime:
695 return True
721 return True
696 return False
722 return False
697
723
698 def verifyFile(self, filename):
724 def verifyFile(self, filename):
699 """Check for a valid file
725 """Check for a valid file
700
726
701 Arguments:
727 Arguments:
702 filename -- full path filename
728 filename -- full path filename
703
729
704 Return:
730 Return:
705 boolean
731 boolean
706 """
732 """
707
733
708 return True
734 return True
709
735
710 def checkForRealPath(self, nextFile, nextDay):
736 def checkForRealPath(self, nextFile, nextDay):
711 """Check if the next file to be readed exists"""
737 """Check if the next file to be readed exists"""
712
738
713 raise NotImplementedError
739 raise NotImplementedError
714
740
715 def readFirstHeader(self):
741 def readFirstHeader(self):
716 """Parse the file header"""
742 """Parse the file header"""
717
743
744
718 pass
745 pass
719
746
720 def waitDataBlock(self, pointer_location, blocksize=None):
747 def waitDataBlock(self, pointer_location, blocksize=None):
721 """
748 """
722 """
749 """
723
750
724 currentPointer = pointer_location
751 currentPointer = pointer_location
725 if blocksize is None:
752 if blocksize is None:
726 neededSize = self.processingHeaderObj.blockSize # + self.basicHeaderSize
753 neededSize = self.processingHeaderObj.blockSize # + self.basicHeaderSize
727 else:
754 else:
728 neededSize = blocksize
755 neededSize = blocksize
729
756
730 for nTries in range(self.nTries):
757 for nTries in range(self.nTries):
731 self.fp.close()
758 self.fp.close()
732 self.fp = open(self.filename, 'rb')
759 self.fp = open(self.filename, 'rb')
733 self.fp.seek(currentPointer)
760 self.fp.seek(currentPointer)
734
761
735 self.fileSize = os.path.getsize(self.filename)
762 self.fileSize = os.path.getsize(self.filename)
736 currentSize = self.fileSize - currentPointer
763 currentSize = self.fileSize - currentPointer
737
764
738 if (currentSize >= neededSize):
765 if (currentSize >= neededSize):
739 return 1
766 return 1
740
767
741 log.warning(
768 log.warning(
742 "Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1),
769 "Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1),
743 self.name
770 self.name
744 )
771 )
745 time.sleep(self.delay)
772 time.sleep(self.delay)
746
773
747 return 0
774 return 0
748
775
749 class JRODataReader(Reader):
776 class JRODataReader(Reader):
750
777
751 utc = 0
778 utc = 0
752 nReadBlocks = 0
779 nReadBlocks = 0
753 foldercounter = 0
780 foldercounter = 0
754 firstHeaderSize = 0
781 firstHeaderSize = 0
755 basicHeaderSize = 24
782 basicHeaderSize = 24
756 __isFirstTimeOnline = 1
783 __isFirstTimeOnline = 1
757 filefmt = "*%Y%j***"
784 filefmt = "*%Y%j***"
758 folderfmt = "*%Y%j"
785 folderfmt = "*%Y%j"
759 __attrs__ = ['path', 'startDate', 'endDate', 'startTime', 'endTime', 'online', 'delay', 'walk']
786 __attrs__ = ['path', 'startDate', 'endDate', 'startTime', 'endTime', 'online', 'delay', 'walk']
760
787
761 def getDtypeWidth(self):
788 def getDtypeWidth(self):
762
789
763 dtype_index = get_dtype_index(self.dtype)
790 dtype_index = get_dtype_index(self.dtype)
764 dtype_width = get_dtype_width(dtype_index)
791 dtype_width = get_dtype_width(dtype_index)
765
792
766 return dtype_width
793 return dtype_width
767
794
768 def checkForRealPath(self, nextFile, nextDay):
795 def checkForRealPath(self, nextFile, nextDay):
769 """Check if the next file to be readed exists.
796 """Check if the next file to be readed exists.
770
797
771 Example :
798 Example :
772 nombre correcto del file es .../.../D2009307/P2009307367.ext
799 nombre correcto del file es .../.../D2009307/P2009307367.ext
773
800
774 Entonces la funcion prueba con las siguientes combinaciones
801 Entonces la funcion prueba con las siguientes combinaciones
775 .../.../y2009307367.ext
802 .../.../y2009307367.ext
776 .../.../Y2009307367.ext
803 .../.../Y2009307367.ext
777 .../.../x2009307/y2009307367.ext
804 .../.../x2009307/y2009307367.ext
778 .../.../x2009307/Y2009307367.ext
805 .../.../x2009307/Y2009307367.ext
779 .../.../X2009307/y2009307367.ext
806 .../.../X2009307/y2009307367.ext
780 .../.../X2009307/Y2009307367.ext
807 .../.../X2009307/Y2009307367.ext
781 siendo para este caso, la ultima combinacion de letras, identica al file buscado
808 siendo para este caso, la ultima combinacion de letras, identica al file buscado
782
809
783 Return:
810 Return:
784 str -- fullpath of the file
811 str -- fullpath of the file
785 """
812 """
786
813
787
814
788 if nextFile:
815 if nextFile:
789 self.set += 1
816 self.set += 1
790 if nextDay:
817 if nextDay:
791 self.set = 0
818 self.set = 0
792 self.doy += 1
819 self.doy += 1
793 foldercounter = 0
820 foldercounter = 0
794 prefixDirList = [None, 'd', 'D']
821 prefixDirList = [None, 'd', 'D']
795 if self.ext.lower() == ".r": # voltage
822 if self.ext.lower() == ".r": # voltage
796 prefixFileList = ['d', 'D']
823 prefixFileList = ['d', 'D']
797 elif self.ext.lower() == ".pdata": # spectra
824 elif self.ext.lower() == ".pdata": # spectra
798 prefixFileList = ['p', 'P']
825 prefixFileList = ['p', 'P']
799
826
827 ##############DP##############
828
829 elif self.ext.lower() == ".dat": # dat
830 prefixFileList = ['z', 'Z']
831
832
833
834 ##############DP##############
800 # barrido por las combinaciones posibles
835 # barrido por las combinaciones posibles
801 for prefixDir in prefixDirList:
836 for prefixDir in prefixDirList:
802 thispath = self.path
837 thispath = self.path
803 if prefixDir != None:
838 if prefixDir != None:
804 # formo el nombre del directorio xYYYYDDD (x=d o x=D)
839 # formo el nombre del directorio xYYYYDDD (x=d o x=D)
805 if foldercounter == 0:
840 if foldercounter == 0:
806 thispath = os.path.join(self.path, "%s%04d%03d" %
841 thispath = os.path.join(self.path, "%s%04d%03d" %
807 (prefixDir, self.year, self.doy))
842 (prefixDir, self.year, self.doy))
808 else:
843 else:
809 thispath = os.path.join(self.path, "%s%04d%03d_%02d" % (
844 thispath = os.path.join(self.path, "%s%04d%03d_%02d" % (
810 prefixDir, self.year, self.doy, foldercounter))
845 prefixDir, self.year, self.doy, foldercounter))
811 for prefixFile in prefixFileList: # barrido por las dos combinaciones posibles de "D"
846 for prefixFile in prefixFileList: # barrido por las dos combinaciones posibles de "D"
812 # formo el nombre del file xYYYYDDDSSS.ext
847 # formo el nombre del file xYYYYDDDSSS.ext
813 filename = "%s%04d%03d%03d%s" % (prefixFile, self.year, self.doy, self.set, self.ext)
848 filename = "%s%04d%03d%03d%s" % (prefixFile, self.year, self.doy, self.set, self.ext)
814 fullfilename = os.path.join(
849 fullfilename = os.path.join(
815 thispath, filename)
850 thispath, filename)
816
851
817 if os.path.exists(fullfilename):
852 if os.path.exists(fullfilename):
818 return fullfilename, filename
853 return fullfilename, filename
819
854
820 return None, filename
855 return None, filename
821
856
822 def __waitNewBlock(self):
857 def __waitNewBlock(self):
823 """
858 """
824 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
859 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
825
860
826 Si el modo de lectura es OffLine siempre retorn 0
861 Si el modo de lectura es OffLine siempre retorn 0
827 """
862 """
828 if not self.online:
863 if not self.online:
829 return 0
864 return 0
830
865
831 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
866 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
832 return 0
867 return 0
833
868
834 currentPointer = self.fp.tell()
869 currentPointer = self.fp.tell()
835
870
836 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
871 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
837
872
838 for nTries in range(self.nTries):
873 for nTries in range(self.nTries):
839
874
840 self.fp.close()
875 self.fp.close()
841 self.fp = open(self.filename, 'rb')
876 self.fp = open(self.filename, 'rb')
842 self.fp.seek(currentPointer)
877 self.fp.seek(currentPointer)
843
878
844 self.fileSize = os.path.getsize(self.filename)
879 self.fileSize = os.path.getsize(self.filename)
845 currentSize = self.fileSize - currentPointer
880 currentSize = self.fileSize - currentPointer
846
881
847 if (currentSize >= neededSize):
882 if (currentSize >= neededSize):
848 self.basicHeaderObj.read(self.fp)
883 self.basicHeaderObj.read(self.fp)
849 return 1
884 return 1
850
885
851 if self.fileSize == self.fileSizeByHeader:
886 if self.fileSize == self.fileSizeByHeader:
852 # self.flagEoF = True
887 # self.flagEoF = True
853 return 0
888 return 0
854
889
855 print("[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1))
890 print("[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1))
891 #print(self.filename)
856 time.sleep(self.delay)
892 time.sleep(self.delay)
857
893
858 return 0
894 return 0
859
895
860 def __setNewBlock(self):
896 def __setNewBlock(self):
861
897
862 if self.fp == None:
898 if self.fp == None:
863 return 0
899 return 0
864
900
865 if self.flagIsNewFile:
901 if self.flagIsNewFile:
866 self.lastUTTime = self.basicHeaderObj.utc
902 self.lastUTTime = self.basicHeaderObj.utc
867 return 1
903 return 1
868
904
869 if self.realtime:
905 if self.realtime:
870 self.flagDiscontinuousBlock = 1
906 self.flagDiscontinuousBlock = 1
871 if not(self.setNextFile()):
907 if not(self.setNextFile()):
872 return 0
908 return 0
873 else:
909 else:
874 return 1
910 return 1
875
911
876 currentSize = self.fileSize - self.fp.tell()
912 currentSize = self.fileSize - self.fp.tell()
877 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
913 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
878
914
879 if (currentSize >= neededSize):
915 if (currentSize >= neededSize):
880 self.basicHeaderObj.read(self.fp)
916 self.basicHeaderObj.read(self.fp)
881 self.lastUTTime = self.basicHeaderObj.utc
917 self.lastUTTime = self.basicHeaderObj.utc
882 return 1
918 return 1
883
919
884 if self.__waitNewBlock():
920 if self.__waitNewBlock():
885 self.lastUTTime = self.basicHeaderObj.utc
921 self.lastUTTime = self.basicHeaderObj.utc
886 return 1
922 return 1
887
923
888 if not(self.setNextFile()):
924 if not(self.setNextFile()):
889 return 0
925 return 0
890
926
891 deltaTime = self.basicHeaderObj.utc - self.lastUTTime
927 deltaTime = self.basicHeaderObj.utc - self.lastUTTime
892 self.lastUTTime = self.basicHeaderObj.utc
928 self.lastUTTime = self.basicHeaderObj.utc
893
929
894 self.flagDiscontinuousBlock = 0
930 self.flagDiscontinuousBlock = 0
895
931
896 if deltaTime > self.maxTimeStep:
932 if deltaTime > self.maxTimeStep:
897 self.flagDiscontinuousBlock = 1
933 self.flagDiscontinuousBlock = 1
898
934
899 return 1
935 return 1
900
936
901 def readNextBlock(self):
937 def readNextBlock(self):
902
938
903 while True:
939 while True:
904 if not(self.__setNewBlock()):
940 if not(self.__setNewBlock()):
905 continue
941 continue
906
942
907 if not(self.readBlock()):
943 if not(self.readBlock()):
908 return 0
944 return 0
909
945
910 self.getBasicHeader()
946 self.getBasicHeader()
911
947
912 if not self.isDateTimeInRange(self.dataOut.datatime, self.startDate, self.endDate, self.startTime, self.endTime):
948 if not self.isDateTimeInRange(self.dataOut.datatime, self.startDate, self.endDate, self.startTime, self.endTime):
913 print("[Reading] Block No. %d/%d -> %s [Skipping]" % (self.nReadBlocks,
949 print("[Reading] Block No. %d/%d -> %s [Skipping]" % (self.nReadBlocks,
914 self.processingHeaderObj.dataBlocksPerFile,
950 self.processingHeaderObj.dataBlocksPerFile,
915 self.dataOut.datatime.ctime()))
951 self.dataOut.datatime.ctime()))
916 continue
952 continue
917
953
918 break
954 break
919
955
920 if self.verbose:
956 if self.verbose:
921 print("[Reading] Block No. %d/%d -> %s" % (self.nReadBlocks,
957 print("[Reading] Block No. %d/%d -> %s" % (self.nReadBlocks,
922 self.processingHeaderObj.dataBlocksPerFile,
958 self.processingHeaderObj.dataBlocksPerFile,
923 self.dataOut.datatime.ctime()))
959 self.dataOut.datatime.ctime()))
960 #################DP#################
961 self.dataOut.TimeBlockDate=self.dataOut.datatime.ctime()
962 self.dataOut.TimeBlockSeconds=time.mktime(time.strptime(self.dataOut.datatime.ctime()))
963 #################DP#################
924 return 1
964 return 1
925
965
926 def readFirstHeader(self):
966 def readFirstHeader(self):
927
967
928 self.basicHeaderObj.read(self.fp)
968 self.basicHeaderObj.read(self.fp)
929 self.systemHeaderObj.read(self.fp)
969 self.systemHeaderObj.read(self.fp)
930 self.radarControllerHeaderObj.read(self.fp)
970 self.radarControllerHeaderObj.read(self.fp)
931 self.processingHeaderObj.read(self.fp)
971 self.processingHeaderObj.read(self.fp)
932 self.firstHeaderSize = self.basicHeaderObj.size
972 self.firstHeaderSize = self.basicHeaderObj.size
933
973
934 datatype = int(numpy.log2((self.processingHeaderObj.processFlags &
974 datatype = int(numpy.log2((self.processingHeaderObj.processFlags &
935 PROCFLAG.DATATYPE_MASK)) - numpy.log2(PROCFLAG.DATATYPE_CHAR))
975 PROCFLAG.DATATYPE_MASK)) - numpy.log2(PROCFLAG.DATATYPE_CHAR))
936 if datatype == 0:
976 if datatype == 0:
937 datatype_str = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
977 datatype_str = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
938 elif datatype == 1:
978 elif datatype == 1:
939 datatype_str = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
979 datatype_str = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
940 elif datatype == 2:
980 elif datatype == 2:
941 datatype_str = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
981 datatype_str = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
942 elif datatype == 3:
982 elif datatype == 3:
943 datatype_str = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
983 datatype_str = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
944 elif datatype == 4:
984 elif datatype == 4:
945 datatype_str = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
985 datatype_str = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
946 elif datatype == 5:
986 elif datatype == 5:
947 datatype_str = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
987 datatype_str = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
948 else:
988 else:
949 raise ValueError('Data type was not defined')
989 raise ValueError('Data type was not defined')
950
990
951 self.dtype = datatype_str
991 self.dtype = datatype_str
952 #self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
992 #self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
953 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + \
993 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + \
954 self.firstHeaderSize + self.basicHeaderSize * \
994 self.firstHeaderSize + self.basicHeaderSize * \
955 (self.processingHeaderObj.dataBlocksPerFile - 1)
995 (self.processingHeaderObj.dataBlocksPerFile - 1)
956 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
996 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
957 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
997 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
958 self.getBlockDimension()
998 self.getBlockDimension()
959
999
960 def verifyFile(self, filename):
1000 def verifyFile(self, filename):
961
1001
962 flag = True
1002 flag = True
963
1003
964 try:
1004 try:
965 fp = open(filename, 'rb')
1005 fp = open(filename, 'rb')
966 except IOError:
1006 except IOError:
967 log.error("File {} can't be opened".format(filename), self.name)
1007 log.error("File {} can't be opened".format(filename), self.name)
968 return False
1008 return False
969
1009
970 if self.online and self.waitDataBlock(0):
1010 if self.online and self.waitDataBlock(0):
971 pass
1011 pass
972
1012
973 basicHeaderObj = BasicHeader(LOCALTIME)
1013 basicHeaderObj = BasicHeader(LOCALTIME)
974 systemHeaderObj = SystemHeader()
1014 systemHeaderObj = SystemHeader()
975 radarControllerHeaderObj = RadarControllerHeader()
1015 radarControllerHeaderObj = RadarControllerHeader()
976 processingHeaderObj = ProcessingHeader()
1016 processingHeaderObj = ProcessingHeader()
977
1017
978 if not(basicHeaderObj.read(fp)):
1018 if not(basicHeaderObj.read(fp)):
979 flag = False
1019 flag = False
980 if not(systemHeaderObj.read(fp)):
1020 if not(systemHeaderObj.read(fp)):
981 flag = False
1021 flag = False
982 if not(radarControllerHeaderObj.read(fp)):
1022 if not(radarControllerHeaderObj.read(fp)):
983 flag = False
1023 flag = False
984 if not(processingHeaderObj.read(fp)):
1024 if not(processingHeaderObj.read(fp)):
985 flag = False
1025 flag = False
986 if not self.online:
1026 if not self.online:
987 dt1 = basicHeaderObj.datatime
1027 dt1 = basicHeaderObj.datatime
988 pos = self.fileSize-processingHeaderObj.blockSize-24
1028 pos = self.fileSize-processingHeaderObj.blockSize-24
989 if pos<0:
1029 if pos<0:
990 flag = False
1030 flag = False
991 log.error('Invalid size for file: {}'.format(self.filename), self.name)
1031 log.error('Invalid size for file: {}'.format(self.filename), self.name)
992 else:
1032 else:
993 fp.seek(pos)
1033 fp.seek(pos)
994 if not(basicHeaderObj.read(fp)):
1034 if not(basicHeaderObj.read(fp)):
995 flag = False
1035 flag = False
996 dt2 = basicHeaderObj.datatime
1036 dt2 = basicHeaderObj.datatime
997 if not self.isDateTimeInRange(dt1, self.startDate, self.endDate, self.startTime, self.endTime) and not \
1037 if not self.isDateTimeInRange(dt1, self.startDate, self.endDate, self.startTime, self.endTime) and not \
998 self.isDateTimeInRange(dt2, self.startDate, self.endDate, self.startTime, self.endTime):
1038 self.isDateTimeInRange(dt2, self.startDate, self.endDate, self.startTime, self.endTime):
999 flag = False
1039 flag = False
1000
1040
1001 fp.close()
1041 fp.close()
1002 return flag
1042 return flag
1003
1043
1004 def findDatafiles(self, path, startDate=None, endDate=None, expLabel='', ext='.r', walk=True, include_path=False):
1044 def findDatafiles(self, path, startDate=None, endDate=None, expLabel='', ext='.r', walk=True, include_path=False):
1005
1045
1006 path_empty = True
1046 path_empty = True
1007
1047
1008 dateList = []
1048 dateList = []
1009 pathList = []
1049 pathList = []
1010
1050
1011 multi_path = path.split(',')
1051 multi_path = path.split(',')
1012
1052
1013 if not walk:
1053 if not walk:
1014
1054
1015 for single_path in multi_path:
1055 for single_path in multi_path:
1016
1056
1017 if not os.path.isdir(single_path):
1057 if not os.path.isdir(single_path):
1018 continue
1058 continue
1019
1059
1020 fileList = glob.glob1(single_path, "*" + ext)
1060 fileList = glob.glob1(single_path, "*" + ext)
1021
1061
1022 if not fileList:
1062 if not fileList:
1023 continue
1063 continue
1024
1064
1025 path_empty = False
1065 path_empty = False
1026
1066
1027 fileList.sort()
1067 fileList.sort()
1028
1068
1029 for thisFile in fileList:
1069 for thisFile in fileList:
1030
1070
1031 if not os.path.isfile(os.path.join(single_path, thisFile)):
1071 if not os.path.isfile(os.path.join(single_path, thisFile)):
1032 continue
1072 continue
1033
1073
1034 if not isRadarFile(thisFile):
1074 if not isRadarFile(thisFile):
1035 continue
1075 continue
1036
1076
1037 if not isFileInDateRange(thisFile, startDate, endDate):
1077 if not isFileInDateRange(thisFile, startDate, endDate):
1038 continue
1078 continue
1039
1079
1040 thisDate = getDateFromRadarFile(thisFile)
1080 thisDate = getDateFromRadarFile(thisFile)
1041
1081
1042 if thisDate in dateList or single_path in pathList:
1082 if thisDate in dateList or single_path in pathList:
1043 continue
1083 continue
1044
1084
1045 dateList.append(thisDate)
1085 dateList.append(thisDate)
1046 pathList.append(single_path)
1086 pathList.append(single_path)
1047
1087
1048 else:
1088 else:
1049 for single_path in multi_path:
1089 for single_path in multi_path:
1050
1090
1051 if not os.path.isdir(single_path):
1091 if not os.path.isdir(single_path):
1052 continue
1092 continue
1053
1093
1054 dirList = []
1094 dirList = []
1055
1095
1056 for thisPath in os.listdir(single_path):
1096 for thisPath in os.listdir(single_path):
1057
1097
1058 if not os.path.isdir(os.path.join(single_path, thisPath)):
1098 if not os.path.isdir(os.path.join(single_path, thisPath)):
1059 continue
1099 continue
1060
1100
1061 if not isRadarFolder(thisPath):
1101 if not isRadarFolder(thisPath):
1062 continue
1102 continue
1063
1103
1064 if not isFolderInDateRange(thisPath, startDate, endDate):
1104 if not isFolderInDateRange(thisPath, startDate, endDate):
1065 continue
1105 continue
1066
1106
1067 dirList.append(thisPath)
1107 dirList.append(thisPath)
1068
1108
1069 if not dirList:
1109 if not dirList:
1070 continue
1110 continue
1071
1111
1072 dirList.sort()
1112 dirList.sort()
1073
1113
1074 for thisDir in dirList:
1114 for thisDir in dirList:
1075
1115
1076 datapath = os.path.join(single_path, thisDir, expLabel)
1116 datapath = os.path.join(single_path, thisDir, expLabel)
1077 fileList = glob.glob1(datapath, "*" + ext)
1117 fileList = glob.glob1(datapath, "*" + ext)
1078
1118
1079 if not fileList:
1119 if not fileList:
1080 continue
1120 continue
1081
1121
1082 path_empty = False
1122 path_empty = False
1083
1123
1084 thisDate = getDateFromRadarFolder(thisDir)
1124 thisDate = getDateFromRadarFolder(thisDir)
1085
1125
1086 pathList.append(datapath)
1126 pathList.append(datapath)
1087 dateList.append(thisDate)
1127 dateList.append(thisDate)
1088
1128
1089 dateList.sort()
1129 dateList.sort()
1090
1130
1091 if walk:
1131 if walk:
1092 pattern_path = os.path.join(multi_path[0], "[dYYYYDDD]", expLabel)
1132 pattern_path = os.path.join(multi_path[0], "[dYYYYDDD]", expLabel)
1093 else:
1133 else:
1094 pattern_path = multi_path[0]
1134 pattern_path = multi_path[0]
1095
1135
1096 if path_empty:
1136 if path_empty:
1097 raise schainpy.admin.SchainError("[Reading] No *%s files in %s for %s to %s" % (ext, pattern_path, startDate, endDate))
1137 raise schainpy.admin.SchainError("[Reading] No *%s files in %s for %s to %s" % (ext, pattern_path, startDate, endDate))
1098 else:
1138 else:
1099 if not dateList:
1139 if not dateList:
1100 raise schainpy.admin.SchainError("[Reading] Date range selected invalid [%s - %s]: No *%s files in %s)" % (startDate, endDate, ext, path))
1140 raise schainpy.admin.SchainError("[Reading] Date range selected invalid [%s - %s]: No *%s files in %s)" % (startDate, endDate, ext, path))
1101
1141
1102 if include_path:
1142 if include_path:
1103 return dateList, pathList
1143 return dateList, pathList
1104
1144
1105 return dateList
1145 return dateList
1106
1146
1107 def setup(self, **kwargs):
1147 def setup(self, **kwargs):
1108
1148
1109 self.set_kwargs(**kwargs)
1149 self.set_kwargs(**kwargs)
1110 if not self.ext.startswith('.'):
1150 if not self.ext.startswith('.'):
1111 self.ext = '.{}'.format(self.ext)
1151 self.ext = '.{}'.format(self.ext)
1112
1152
1113 if self.server is not None:
1153 if self.server is not None:
1114 if 'tcp://' in self.server:
1154 if 'tcp://' in self.server:
1115 address = server
1155 address = server
1116 else:
1156 else:
1117 address = 'ipc:///tmp/%s' % self.server
1157 address = 'ipc:///tmp/%s' % self.server
1118 self.server = address
1158 self.server = address
1119 self.context = zmq.Context()
1159 self.context = zmq.Context()
1120 self.receiver = self.context.socket(zmq.PULL)
1160 self.receiver = self.context.socket(zmq.PULL)
1121 self.receiver.connect(self.server)
1161 self.receiver.connect(self.server)
1122 time.sleep(0.5)
1162 time.sleep(0.5)
1123 print('[Starting] ReceiverData from {}'.format(self.server))
1163 print('[Starting] ReceiverData from {}'.format(self.server))
1124 else:
1164 else:
1125 self.server = None
1165 self.server = None
1126 if self.path == None:
1166 if self.path == None:
1127 raise ValueError("[Reading] The path is not valid")
1167 raise ValueError("[Reading] The path is not valid")
1128
1168
1129 if self.online:
1169 if self.online:
1130 log.log("[Reading] Searching files in online mode...", self.name)
1170 log.log("[Reading] Searching files in online mode...", self.name)
1131
1171
1132 for nTries in range(self.nTries):
1172 for nTries in range(self.nTries):
1133 fullpath = self.searchFilesOnLine(self.path, self.startDate,
1173 fullpath = self.searchFilesOnLine(self.path, self.startDate,
1134 self.endDate, self.expLabel, self.ext, self.walk,
1174 self.endDate, self.expLabel, self.ext, self.walk,
1135 self.filefmt, self.folderfmt)
1175 self.filefmt, self.folderfmt)
1136
1176
1137 try:
1177 try:
1138 fullpath = next(fullpath)
1178 fullpath = next(fullpath)
1139 except:
1179 except:
1140 fullpath = None
1180 fullpath = None
1141
1181
1142 if fullpath:
1182 if fullpath:
1143 break
1183 break
1144
1184
1145 log.warning(
1185 log.warning(
1146 'Waiting {} sec for a valid file in {}: try {} ...'.format(
1186 'Waiting {} sec for a valid file in {}: try {} ...'.format(
1147 self.delay, self.path, nTries + 1),
1187 self.delay, self.path, nTries + 1),
1148 self.name)
1188 self.name)
1149 time.sleep(self.delay)
1189 time.sleep(self.delay)
1150
1190
1151 if not(fullpath):
1191 if not(fullpath):
1152 raise schainpy.admin.SchainError(
1192 raise schainpy.admin.SchainError(
1153 'There isn\'t any valid file in {}'.format(self.path))
1193 'There isn\'t any valid file in {}'.format(self.path))
1154
1194
1155 pathname, filename = os.path.split(fullpath)
1195 pathname, filename = os.path.split(fullpath)
1156 self.year = int(filename[1:5])
1196 self.year = int(filename[1:5])
1157 self.doy = int(filename[5:8])
1197 self.doy = int(filename[5:8])
1158 self.set = int(filename[8:11]) - 1
1198 self.set = int(filename[8:11]) - 1
1159 else:
1199 else:
1160 log.log("Searching files in {}".format(self.path), self.name)
1200 log.log("Searching files in {}".format(self.path), self.name)
1161 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
1201 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
1162 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
1202 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
1163
1203
1164 self.setNextFile()
1204 self.setNextFile()
1165
1205
1166 return
1206 return
1167
1207
1168 def getBasicHeader(self):
1208 def getBasicHeader(self):
1169
1209
1170 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond / \
1210 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond / \
1171 1000. + self.profileIndex * self.radarControllerHeaderObj.ippSeconds
1211 1000. + self.profileIndex * self.radarControllerHeaderObj.ippSeconds
1172
1212
1173 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
1213 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
1174
1214
1175 self.dataOut.timeZone = self.basicHeaderObj.timeZone
1215 self.dataOut.timeZone = self.basicHeaderObj.timeZone
1176
1216
1177 self.dataOut.dstFlag = self.basicHeaderObj.dstFlag
1217 self.dataOut.dstFlag = self.basicHeaderObj.dstFlag
1178
1218
1179 self.dataOut.errorCount = self.basicHeaderObj.errorCount
1219 self.dataOut.errorCount = self.basicHeaderObj.errorCount
1180
1220
1181 self.dataOut.useLocalTime = self.basicHeaderObj.useLocalTime
1221 self.dataOut.useLocalTime = self.basicHeaderObj.useLocalTime
1182
1222
1183 self.dataOut.ippSeconds = self.radarControllerHeaderObj.ippSeconds / self.nTxs
1223 self.dataOut.ippSeconds = self.radarControllerHeaderObj.ippSeconds / self.nTxs
1184
1224
1185 def getFirstHeader(self):
1225 def getFirstHeader(self):
1186
1226
1187 raise NotImplementedError
1227 raise NotImplementedError
1188
1228
1189 def getData(self):
1229 def getData(self):
1190
1230
1191 raise NotImplementedError
1231 raise NotImplementedError
1192
1232
1193 def hasNotDataInBuffer(self):
1233 def hasNotDataInBuffer(self):
1194
1234
1195 raise NotImplementedError
1235 raise NotImplementedError
1196
1236
1197 def readBlock(self):
1237 def readBlock(self):
1198
1238
1199 raise NotImplementedError
1239 raise NotImplementedError
1200
1240
1201 def isEndProcess(self):
1241 def isEndProcess(self):
1202
1242
1203 return self.flagNoMoreFiles
1243 return self.flagNoMoreFiles
1204
1244
1205 def printReadBlocks(self):
1245 def printReadBlocks(self):
1206
1246
1207 print("[Reading] Number of read blocks per file %04d" % self.nReadBlocks)
1247 print("[Reading] Number of read blocks per file %04d" % self.nReadBlocks)
1208
1248
1209 def printTotalBlocks(self):
1249 def printTotalBlocks(self):
1210
1250
1211 print("[Reading] Number of read blocks %04d" % self.nTotalBlocks)
1251 print("[Reading] Number of read blocks %04d" % self.nTotalBlocks)
1212
1252
1213 def run(self, **kwargs):
1253 def run(self, **kwargs):
1214 """
1254 """
1215
1255
1216 Arguments:
1256 Arguments:
1217 path :
1257 path :
1218 startDate :
1258 startDate :
1219 endDate :
1259 endDate :
1220 startTime :
1260 startTime :
1221 endTime :
1261 endTime :
1222 set :
1262 set :
1223 expLabel :
1263 expLabel :
1224 ext :
1264 ext :
1225 online :
1265 online :
1226 delay :
1266 delay :
1227 walk :
1267 walk :
1228 getblock :
1268 getblock :
1229 nTxs :
1269 nTxs :
1230 realtime :
1270 realtime :
1231 blocksize :
1271 blocksize :
1232 blocktime :
1272 blocktime :
1233 skip :
1273 skip :
1234 cursor :
1274 cursor :
1235 warnings :
1275 warnings :
1236 server :
1276 server :
1237 verbose :
1277 verbose :
1238 format :
1278 format :
1239 oneDDict :
1279 oneDDict :
1240 twoDDict :
1280 twoDDict :
1241 independentParam :
1281 independentParam :
1242 """
1282 """
1243
1283
1244 if not(self.isConfig):
1284 if not(self.isConfig):
1245 self.setup(**kwargs)
1285 self.setup(**kwargs)
1246 self.isConfig = True
1286 self.isConfig = True
1247 if self.server is None:
1287 if self.server is None:
1248 self.getData()
1288 self.getData()
1249 else:
1289 else:
1250 self.getFromServer()
1290 self.getFromServer()
1251
1291
1252
1292
1253 class JRODataWriter(Reader):
1293 class JRODataWriter(Reader):
1254
1294
1255 """
1295 """
1256 Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura
1296 Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura
1257 de los datos siempre se realiza por bloques.
1297 de los datos siempre se realiza por bloques.
1258 """
1298 """
1259
1299
1260 setFile = None
1300 setFile = None
1261 profilesPerBlock = None
1301 profilesPerBlock = None
1262 blocksPerFile = None
1302 blocksPerFile = None
1263 nWriteBlocks = 0
1303 nWriteBlocks = 0
1264 fileDate = None
1304 fileDate = None
1265
1305
1266 def __init__(self, dataOut=None):
1306 def __init__(self, dataOut=None):
1267 raise NotImplementedError
1307 raise NotImplementedError
1268
1308
1269 def hasAllDataInBuffer(self):
1309 def hasAllDataInBuffer(self):
1270 raise NotImplementedError
1310 raise NotImplementedError
1271
1311
1272 def setBlockDimension(self):
1312 def setBlockDimension(self):
1273 raise NotImplementedError
1313 raise NotImplementedError
1274
1314
1275 def writeBlock(self):
1315 def writeBlock(self):
1276 raise NotImplementedError
1316 raise NotImplementedError
1277
1317
1278 def putData(self):
1318 def putData(self):
1279 raise NotImplementedError
1319 raise NotImplementedError
1280
1320
1281 def getDtypeWidth(self):
1321 def getDtypeWidth(self):
1282
1322
1283 dtype_index = get_dtype_index(self.dtype)
1323 dtype_index = get_dtype_index(self.dtype)
1284 dtype_width = get_dtype_width(dtype_index)
1324 dtype_width = get_dtype_width(dtype_index)
1285
1325
1286 return dtype_width
1326 return dtype_width
1287
1327
1288 def getProcessFlags(self):
1328 def getProcessFlags(self):
1289
1329
1290 processFlags = 0
1330 processFlags = 0
1291
1331
1292 dtype_index = get_dtype_index(self.dtype)
1332 dtype_index = get_dtype_index(self.dtype)
1293 procflag_dtype = get_procflag_dtype(dtype_index)
1333 procflag_dtype = get_procflag_dtype(dtype_index)
1294
1334
1295 processFlags += procflag_dtype
1335 processFlags += procflag_dtype
1296
1336
1297 if self.dataOut.flagDecodeData:
1337 if self.dataOut.flagDecodeData:
1298 processFlags += PROCFLAG.DECODE_DATA
1338 processFlags += PROCFLAG.DECODE_DATA
1299
1339
1300 if self.dataOut.flagDeflipData:
1340 if self.dataOut.flagDeflipData:
1301 processFlags += PROCFLAG.DEFLIP_DATA
1341 processFlags += PROCFLAG.DEFLIP_DATA
1302
1342
1303 if self.dataOut.code is not None:
1343 if self.dataOut.code is not None:
1304 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
1344 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
1305
1345
1306 if self.dataOut.nCohInt > 1:
1346 if self.dataOut.nCohInt > 1:
1307 processFlags += PROCFLAG.COHERENT_INTEGRATION
1347 processFlags += PROCFLAG.COHERENT_INTEGRATION
1308
1348
1309 if self.dataOut.type == "Spectra":
1349 if self.dataOut.type == "Spectra":
1310 if self.dataOut.nIncohInt > 1:
1350 if self.dataOut.nIncohInt > 1:
1311 processFlags += PROCFLAG.INCOHERENT_INTEGRATION
1351 processFlags += PROCFLAG.INCOHERENT_INTEGRATION
1312
1352
1313 if self.dataOut.data_dc is not None:
1353 if self.dataOut.data_dc is not None:
1314 processFlags += PROCFLAG.SAVE_CHANNELS_DC
1354 processFlags += PROCFLAG.SAVE_CHANNELS_DC
1315
1355
1316 if self.dataOut.flagShiftFFT:
1356 if self.dataOut.flagShiftFFT:
1317 processFlags += PROCFLAG.SHIFT_FFT_DATA
1357 processFlags += PROCFLAG.SHIFT_FFT_DATA
1318
1358
1319 return processFlags
1359 return processFlags
1320
1360
1321 def setBasicHeader(self):
1361 def setBasicHeader(self):
1322
1362
1323 self.basicHeaderObj.size = self.basicHeaderSize # bytes
1363 self.basicHeaderObj.size = self.basicHeaderSize # bytes
1324 self.basicHeaderObj.version = self.versionFile
1364 self.basicHeaderObj.version = self.versionFile
1325 self.basicHeaderObj.dataBlock = self.nTotalBlocks
1365 self.basicHeaderObj.dataBlock = self.nTotalBlocks
1326 utc = numpy.floor(self.dataOut.utctime)
1366 utc = numpy.floor(self.dataOut.utctime)
1327 milisecond = (self.dataOut.utctime - utc) * 1000.0
1367 milisecond = (self.dataOut.utctime - utc) * 1000.0
1328 self.basicHeaderObj.utc = utc
1368 self.basicHeaderObj.utc = utc
1329 self.basicHeaderObj.miliSecond = milisecond
1369 self.basicHeaderObj.miliSecond = milisecond
1330 self.basicHeaderObj.timeZone = self.dataOut.timeZone
1370 self.basicHeaderObj.timeZone = self.dataOut.timeZone
1331 self.basicHeaderObj.dstFlag = self.dataOut.dstFlag
1371 self.basicHeaderObj.dstFlag = self.dataOut.dstFlag
1332 self.basicHeaderObj.errorCount = self.dataOut.errorCount
1372 self.basicHeaderObj.errorCount = self.dataOut.errorCount
1333
1373
1334 def setFirstHeader(self):
1374 def setFirstHeader(self):
1335 """
1375 """
1336 Obtiene una copia del First Header
1376 Obtiene una copia del First Header
1337
1377
1338 Affected:
1378 Affected:
1339
1379
1340 self.basicHeaderObj
1380 self.basicHeaderObj
1341 self.systemHeaderObj
1381 self.systemHeaderObj
1342 self.radarControllerHeaderObj
1382 self.radarControllerHeaderObj
1343 self.processingHeaderObj self.
1383 self.processingHeaderObj self.
1344
1384
1345 Return:
1385 Return:
1346 None
1386 None
1347 """
1387 """
1348
1388
1349 raise NotImplementedError
1389 raise NotImplementedError
1350
1390
1351 def __writeFirstHeader(self):
1391 def __writeFirstHeader(self):
1352 """
1392 """
1353 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
1393 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
1354
1394
1355 Affected:
1395 Affected:
1356 __dataType
1396 __dataType
1357
1397
1358 Return:
1398 Return:
1359 None
1399 None
1360 """
1400 """
1361
1401
1362 # CALCULAR PARAMETROS
1402 # CALCULAR PARAMETROS
1363
1403
1364 sizeLongHeader = self.systemHeaderObj.size + \
1404 sizeLongHeader = self.systemHeaderObj.size + \
1365 self.radarControllerHeaderObj.size + self.processingHeaderObj.size
1405 self.radarControllerHeaderObj.size + self.processingHeaderObj.size
1366 self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader
1406 self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader
1367
1407
1368 self.basicHeaderObj.write(self.fp)
1408 self.basicHeaderObj.write(self.fp)
1369 self.systemHeaderObj.write(self.fp)
1409 self.systemHeaderObj.write(self.fp)
1370 self.radarControllerHeaderObj.write(self.fp)
1410 self.radarControllerHeaderObj.write(self.fp)
1371 self.processingHeaderObj.write(self.fp)
1411 self.processingHeaderObj.write(self.fp)
1372
1412
1373 def __setNewBlock(self):
1413 def __setNewBlock(self):
1374 """
1414 """
1375 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
1415 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
1376
1416
1377 Return:
1417 Return:
1378 0 : si no pudo escribir nada
1418 0 : si no pudo escribir nada
1379 1 : Si escribio el Basic el First Header
1419 1 : Si escribio el Basic el First Header
1380 """
1420 """
1381 if self.fp == None:
1421 if self.fp == None:
1382 self.setNextFile()
1422 self.setNextFile()
1383
1423
1384 if self.flagIsNewFile:
1424 if self.flagIsNewFile:
1385 return 1
1425 return 1
1386
1426
1387 if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile:
1427 if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile:
1388 self.basicHeaderObj.write(self.fp)
1428 self.basicHeaderObj.write(self.fp)
1389 return 1
1429 return 1
1390
1430
1391 if not(self.setNextFile()):
1431 if not(self.setNextFile()):
1392 return 0
1432 return 0
1393
1433
1394 return 1
1434 return 1
1395
1435
1396 def writeNextBlock(self):
1436 def writeNextBlock(self):
1397 """
1437 """
1398 Selecciona el bloque siguiente de datos y los escribe en un file
1438 Selecciona el bloque siguiente de datos y los escribe en un file
1399
1439
1400 Return:
1440 Return:
1401 0 : Si no hizo pudo escribir el bloque de datos
1441 0 : Si no hizo pudo escribir el bloque de datos
1402 1 : Si no pudo escribir el bloque de datos
1442 1 : Si no pudo escribir el bloque de datos
1403 """
1443 """
1404 if not(self.__setNewBlock()):
1444 if not(self.__setNewBlock()):
1405 return 0
1445 return 0
1406
1446
1407 self.writeBlock()
1447 self.writeBlock()
1408
1448
1409 print("[Writing] Block No. %d/%d" % (self.blockIndex,
1449 print("[Writing] Block No. %d/%d" % (self.blockIndex,
1410 self.processingHeaderObj.dataBlocksPerFile))
1450 self.processingHeaderObj.dataBlocksPerFile))
1411
1451
1412 return 1
1452 return 1
1413
1453
1414 def setNextFile(self):
1454 def setNextFile(self):
1415 """Determina el siguiente file que sera escrito
1455 """Determina el siguiente file que sera escrito
1416
1456
1417 Affected:
1457 Affected:
1418 self.filename
1458 self.filename
1419 self.subfolder
1459 self.subfolder
1420 self.fp
1460 self.fp
1421 self.setFile
1461 self.setFile
1422 self.flagIsNewFile
1462 self.flagIsNewFile
1423
1463
1424 Return:
1464 Return:
1425 0 : Si el archivo no puede ser escrito
1465 0 : Si el archivo no puede ser escrito
1426 1 : Si el archivo esta listo para ser escrito
1466 1 : Si el archivo esta listo para ser escrito
1427 """
1467 """
1428 ext = self.ext
1468 ext = self.ext
1429 path = self.path
1469 path = self.path
1430
1470
1431 if self.fp != None:
1471 if self.fp != None:
1432 self.fp.close()
1472 self.fp.close()
1433
1473
1434 if not os.path.exists(path):
1474 if not os.path.exists(path):
1435 os.mkdir(path)
1475 os.mkdir(path)
1436
1476
1437 timeTuple = time.localtime(self.dataOut.utctime)
1477 timeTuple = time.localtime(self.dataOut.utctime)
1438 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year, timeTuple.tm_yday)
1478 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year, timeTuple.tm_yday)
1439
1479
1440 fullpath = os.path.join(path, subfolder)
1480 fullpath = os.path.join(path, subfolder)
1441 setFile = self.setFile
1481 setFile = self.setFile
1442
1482
1443 if not(os.path.exists(fullpath)):
1483 if not(os.path.exists(fullpath)):
1444 os.mkdir(fullpath)
1484 os.mkdir(fullpath)
1445 setFile = -1 # inicializo mi contador de seteo
1485 setFile = -1 # inicializo mi contador de seteo
1446 else:
1486 else:
1447 filesList = os.listdir(fullpath)
1487 filesList = os.listdir(fullpath)
1448 if len(filesList) > 0:
1488 if len(filesList) > 0:
1449 filesList = sorted(filesList, key=str.lower)
1489 filesList = sorted(filesList, key=str.lower)
1450 filen = filesList[-1]
1490 filen = filesList[-1]
1451 # el filename debera tener el siguiente formato
1491 # el filename debera tener el siguiente formato
1452 # 0 1234 567 89A BCDE (hex)
1492 # 0 1234 567 89A BCDE (hex)
1453 # x YYYY DDD SSS .ext
1493 # x YYYY DDD SSS .ext
1454 if isNumber(filen[8:11]):
1494 if isNumber(filen[8:11]):
1455 # inicializo mi contador de seteo al seteo del ultimo file
1495 # inicializo mi contador de seteo al seteo del ultimo file
1456 setFile = int(filen[8:11])
1496 setFile = int(filen[8:11])
1457 else:
1497 else:
1458 setFile = -1
1498 setFile = -1
1459 else:
1499 else:
1460 setFile = -1 # inicializo mi contador de seteo
1500 setFile = -1 # inicializo mi contador de seteo
1461
1501
1462 setFile += 1
1502 setFile += 1
1463
1503
1464 # If this is a new day it resets some values
1504 # If this is a new day it resets some values
1465 if self.dataOut.datatime.date() > self.fileDate:
1505 if self.dataOut.datatime.date() > self.fileDate:
1466 setFile = 0
1506 setFile = 0
1467 self.nTotalBlocks = 0
1507 self.nTotalBlocks = 0
1468
1508
1469 filen = '{}{:04d}{:03d}{:03d}{}'.format(
1509 filen = '{}{:04d}{:03d}{:03d}{}'.format(
1470 self.optchar, timeTuple.tm_year, timeTuple.tm_yday, setFile, ext)
1510 self.optchar, timeTuple.tm_year, timeTuple.tm_yday, setFile, ext)
1471
1511
1472 filename = os.path.join(path, subfolder, filen)
1512 filename = os.path.join(path, subfolder, filen)
1473
1513
1474 fp = open(filename, 'wb')
1514 fp = open(filename, 'wb')
1475
1515
1476 self.blockIndex = 0
1516 self.blockIndex = 0
1477 self.filename = filename
1517 self.filename = filename
1478 self.subfolder = subfolder
1518 self.subfolder = subfolder
1479 self.fp = fp
1519 self.fp = fp
1480 self.setFile = setFile
1520 self.setFile = setFile
1481 self.flagIsNewFile = 1
1521 self.flagIsNewFile = 1
1482 self.fileDate = self.dataOut.datatime.date()
1522 self.fileDate = self.dataOut.datatime.date()
1483 self.setFirstHeader()
1523 self.setFirstHeader()
1484
1524
1485 print('[Writing] Opening file: %s' % self.filename)
1525 print('[Writing] Opening file: %s' % self.filename)
1486
1526
1487 self.__writeFirstHeader()
1527 self.__writeFirstHeader()
1488
1528
1489 return 1
1529 return 1
1490
1530
1491 def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4):
1531 def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4):
1492 """
1532 """
1493 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1533 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1494
1534
1495 Inputs:
1535 Inputs:
1496 path : directory where data will be saved
1536 path : directory where data will be saved
1497 profilesPerBlock : number of profiles per block
1537 profilesPerBlock : number of profiles per block
1498 set : initial file set
1538 set : initial file set
1499 datatype : An integer number that defines data type:
1539 datatype : An integer number that defines data type:
1500 0 : int8 (1 byte)
1540 0 : int8 (1 byte)
1501 1 : int16 (2 bytes)
1541 1 : int16 (2 bytes)
1502 2 : int32 (4 bytes)
1542 2 : int32 (4 bytes)
1503 3 : int64 (8 bytes)
1543 3 : int64 (8 bytes)
1504 4 : float32 (4 bytes)
1544 4 : float32 (4 bytes)
1505 5 : double64 (8 bytes)
1545 5 : double64 (8 bytes)
1506
1546
1507 Return:
1547 Return:
1508 0 : Si no realizo un buen seteo
1548 0 : Si no realizo un buen seteo
1509 1 : Si realizo un buen seteo
1549 1 : Si realizo un buen seteo
1510 """
1550 """
1511
1551
1512 if ext == None:
1552 if ext == None:
1513 ext = self.ext
1553 ext = self.ext
1514
1554
1515 self.ext = ext.lower()
1555 self.ext = ext.lower()
1516
1556
1517 self.path = path
1557 self.path = path
1518
1558
1519 if set is None:
1559 if set is None:
1520 self.setFile = -1
1560 self.setFile = -1
1521 else:
1561 else:
1522 self.setFile = set - 1
1562 self.setFile = set - 1
1523
1563
1524 self.blocksPerFile = blocksPerFile
1564 self.blocksPerFile = blocksPerFile
1525 self.profilesPerBlock = profilesPerBlock
1565 self.profilesPerBlock = profilesPerBlock
1526 self.dataOut = dataOut
1566 self.dataOut = dataOut
1527 self.fileDate = self.dataOut.datatime.date()
1567 self.fileDate = self.dataOut.datatime.date()
1528 self.dtype = self.dataOut.dtype
1568 self.dtype = self.dataOut.dtype
1529
1569
1530 if datatype is not None:
1570 if datatype is not None:
1531 self.dtype = get_numpy_dtype(datatype)
1571 self.dtype = get_numpy_dtype(datatype)
1532
1572
1533 if not(self.setNextFile()):
1573 if not(self.setNextFile()):
1534 print("[Writing] There isn't a next file")
1574 print("[Writing] There isn't a next file")
1535 return 0
1575 return 0
1536
1576
1537 self.setBlockDimension()
1577 self.setBlockDimension()
1538
1578
1539 return 1
1579 return 1
1540
1580
1541 def run(self, dataOut, path, blocksPerFile=100, profilesPerBlock=64, set=None, ext=None, datatype=4, **kwargs):
1581 def run(self, dataOut, path, blocksPerFile=100, profilesPerBlock=64, set=None, ext=None, datatype=4, **kwargs):
1542
1582
1543 if not(self.isConfig):
1583 if not(self.isConfig):
1544
1584
1545 self.setup(dataOut, path, blocksPerFile, profilesPerBlock=profilesPerBlock,
1585 self.setup(dataOut, path, blocksPerFile, profilesPerBlock=profilesPerBlock,
1546 set=set, ext=ext, datatype=datatype, **kwargs)
1586 set=set, ext=ext, datatype=datatype, **kwargs)
1547 self.isConfig = True
1587 self.isConfig = True
1548
1588
1549 self.dataOut = dataOut
1589 self.dataOut = dataOut
1550 self.putData()
1590 self.putData()
1551 return self.dataOut
1591 return self.dataOut
1552
1592
1553 @MPDecorator
1593 @MPDecorator
1554 class printInfo(Operation):
1594 class printInfo(Operation):
1555
1595
1556 def __init__(self):
1596 def __init__(self):
1557
1597
1558 Operation.__init__(self)
1598 Operation.__init__(self)
1559 self.__printInfo = True
1599 self.__printInfo = True
1560
1600
1561 def run(self, dataOut, headers = ['systemHeaderObj', 'radarControllerHeaderObj', 'processingHeaderObj']):
1601 def run(self, dataOut, headers = ['systemHeaderObj', 'radarControllerHeaderObj', 'processingHeaderObj']):
1562 if self.__printInfo == False:
1602 if self.__printInfo == False:
1563 return
1603 return
1564
1604
1565 for header in headers:
1605 for header in headers:
1566 if hasattr(dataOut, header):
1606 if hasattr(dataOut, header):
1567 obj = getattr(dataOut, header)
1607 obj = getattr(dataOut, header)
1568 if hasattr(obj, 'printInfo'):
1608 if hasattr(obj, 'printInfo'):
1569 obj.printInfo()
1609 obj.printInfo()
1570 else:
1610 else:
1571 print(obj)
1611 print(obj)
1572 else:
1612 else:
1573 log.warning('Header {} Not found in object'.format(header))
1613 log.warning('Header {} Not found in object'.format(header))
1574
1614
1575 self.__printInfo = False
1615 self.__printInfo = False
@@ -1,595 +1,629
1 '''
1 '''
2 Created on Aug 1, 2017
2 Created on Aug 1, 2017
3
3
4 @author: Juan C. Espinoza
4 @author: Juan C. Espinoza
5 '''
5 '''
6
6
7 import os
7 import os
8 import sys
8 import sys
9 import time
9 import time
10 import json
10 import json
11 import glob
11 import glob
12 import datetime
12 import datetime
13
13
14 import numpy
14 import numpy
15 import h5py
15 import h5py
16
16
17 import schainpy.admin
17 import schainpy.admin
18 from schainpy.model.io.jroIO_base import LOCALTIME, Reader
18 from schainpy.model.io.jroIO_base import LOCALTIME, Reader
19 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
19 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
20 from schainpy.model.data.jrodata import Parameters
20 from schainpy.model.data.jrodata import Parameters
21 from schainpy.utils import log
21 from schainpy.utils import log
22
22
23 try:
23 try:
24 import madrigal.cedar
24 import madrigal.cedar
25 except:
25 except:
26 pass
26 pass
27
27
28 try:
28 try:
29 basestring
29 basestring
30 except:
30 except:
31 basestring = str
31 basestring = str
32
32
33 DEF_CATALOG = {
33 DEF_CATALOG = {
34 'principleInvestigator': 'Marco Milla',
34 'principleInvestigator': 'Marco Milla',
35 'expPurpose': '',
35 'expPurpose': '',
36 'cycleTime': '',
36 'cycleTime': '',
37 'correlativeExp': '',
37 'correlativeExp': '',
38 'sciRemarks': '',
38 'sciRemarks': '',
39 'instRemarks': ''
39 'instRemarks': ''
40 }
40 }
41
41
42 DEF_HEADER = {
42 DEF_HEADER = {
43 'kindatDesc': '',
43 'kindatDesc': '',
44 'analyst': 'Jicamarca User',
44 'analyst': 'Jicamarca User',
45 'comments': '',
45 'comments': '',
46 'history': ''
46 'history': ''
47 }
47 }
48
48
49 MNEMONICS = {
49 MNEMONICS = {
50 10: 'jro',
50 10: 'jro',
51 11: 'jbr',
51 11: 'jbr',
52 840: 'jul',
52 840: 'jul',
53 13: 'jas',
53 13: 'jas',
54 1000: 'pbr',
54 1000: 'pbr',
55 1001: 'hbr',
55 1001: 'hbr',
56 1002: 'obr',
56 1002: 'obr',
57 400: 'clr'
57 400: 'clr'
58
58
59 }
59 }
60
60
61 UT1970 = datetime.datetime(1970, 1, 1) - datetime.timedelta(seconds=time.timezone)
61 UT1970 = datetime.datetime(1970, 1, 1) - datetime.timedelta(seconds=time.timezone)
62
62
63 def load_json(obj):
63 def load_json(obj):
64 '''
64 '''
65 Parse json as string instead of unicode
65 Parse json as string instead of unicode
66 '''
66 '''
67
67
68 if isinstance(obj, str):
68 if isinstance(obj, str):
69 iterable = json.loads(obj)
69 iterable = json.loads(obj)
70 else:
70 else:
71 iterable = obj
71 iterable = obj
72
72
73 if isinstance(iterable, dict):
73 if isinstance(iterable, dict):
74 return {str(k): load_json(v) if isinstance(v, dict) else str(v) if isinstance(v, basestring) else v
74 return {str(k): load_json(v) if isinstance(v, dict) else str(v) if isinstance(v, basestring) else v
75 for k, v in list(iterable.items())}
75 for k, v in list(iterable.items())}
76 elif isinstance(iterable, (list, tuple)):
76 elif isinstance(iterable, (list, tuple)):
77 return [str(v) if isinstance(v, basestring) else v for v in iterable]
77 return [str(v) if isinstance(v, basestring) else v for v in iterable]
78
78
79 return iterable
79 return iterable
80
80
81
81
82 class MADReader(Reader, ProcessingUnit):
82 class MADReader(Reader, ProcessingUnit):
83
83
84 def __init__(self):
84 def __init__(self):
85
85
86 ProcessingUnit.__init__(self)
86 ProcessingUnit.__init__(self)
87
87
88 self.dataOut = Parameters()
88 self.dataOut = Parameters()
89 self.counter_records = 0
89 self.counter_records = 0
90 self.nrecords = None
90 self.nrecords = None
91 self.flagNoMoreFiles = 0
91 self.flagNoMoreFiles = 0
92 self.filename = None
92 self.filename = None
93 self.intervals = set()
93 self.intervals = set()
94 self.datatime = datetime.datetime(1900,1,1)
94 self.datatime = datetime.datetime(1900,1,1)
95 self.format = None
95 self.format = None
96 self.filefmt = "***%Y%m%d*******"
96 self.filefmt = "***%Y%m%d*******"
97
97
98 def setup(self, **kwargs):
98 def setup(self, **kwargs):
99
99
100 self.set_kwargs(**kwargs)
100 self.set_kwargs(**kwargs)
101 self.oneDDict = load_json(self.oneDDict)
101 self.oneDDict = load_json(self.oneDDict)
102 self.twoDDict = load_json(self.twoDDict)
102 self.twoDDict = load_json(self.twoDDict)
103 self.ind2DList = load_json(self.ind2DList)
103 self.ind2DList = load_json(self.ind2DList)
104 self.independentParam = self.ind2DList[0]
104 self.independentParam = self.ind2DList[0]
105
105
106 if self.path is None:
106 if self.path is None:
107 raise ValueError('The path is not valid')
107 raise ValueError('The path is not valid')
108
108
109 self.open_file = open
109 self.open_file = open
110 self.open_mode = 'rb'
110 self.open_mode = 'rb'
111
111
112 if self.format is None:
112 if self.format is None:
113 raise ValueError('The format is not valid choose simple or hdf5')
113 raise ValueError('The format is not valid choose simple or hdf5')
114 elif self.format.lower() in ('simple', 'txt'):
114 elif self.format.lower() in ('simple', 'txt'):
115 self.ext = '.txt'
115 self.ext = '.txt'
116 elif self.format.lower() in ('cedar',):
116 elif self.format.lower() in ('cedar',):
117 self.ext = '.001'
117 self.ext = '.001'
118 else:
118 else:
119 self.ext = '.hdf5'
119 self.ext = '.hdf5'
120 self.open_file = h5py.File
120 self.open_file = h5py.File
121 self.open_mode = 'r'
121 self.open_mode = 'r'
122
122
123 if self.online:
123 if self.online:
124 log.log("Searching files in online mode...", self.name)
124 log.log("Searching files in online mode...", self.name)
125
125
126 for nTries in range(self.nTries):
126 for nTries in range(self.nTries):
127 fullpath = self.searchFilesOnLine(self.path, self.startDate,
127 fullpath = self.searchFilesOnLine(self.path, self.startDate,
128 self.endDate, self.expLabel, self.ext, self.walk,
128 self.endDate, self.expLabel, self.ext, self.walk,
129 self.filefmt, self.folderfmt)
129 self.filefmt, self.folderfmt)
130
130
131 try:
131 try:
132 fullpath = next(fullpath)
132 fullpath = next(fullpath)
133 except:
133 except:
134 fullpath = None
134 fullpath = None
135
135
136 if fullpath:
136 if fullpath:
137 break
137 break
138
138
139 log.warning(
139 log.warning(
140 'Waiting {} sec for a valid file in {}: try {} ...'.format(
140 'Waiting {} sec for a valid file in {}: try {} ...'.format(
141 self.delay, self.path, nTries + 1),
141 self.delay, self.path, nTries + 1),
142 self.name)
142 self.name)
143 time.sleep(self.delay)
143 time.sleep(self.delay)
144
144
145 if not(fullpath):
145 if not(fullpath):
146 raise schainpy.admin.SchainError(
146 raise schainpy.admin.SchainError(
147 'There isn\'t any valid file in {}'.format(self.path))
147 'There isn\'t any valid file in {}'.format(self.path))
148
148
149 else:
149 else:
150 log.log("Searching files in {}".format(self.path), self.name)
150 log.log("Searching files in {}".format(self.path), self.name)
151 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
151 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
152 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
152 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
153
153
154 self.setNextFile()
154 self.setNextFile()
155
155
156 def readFirstHeader(self):
156 def readFirstHeader(self):
157 '''Read header and data'''
157 '''Read header and data'''
158
158
159 self.parseHeader()
159 self.parseHeader()
160 self.parseData()
160 self.parseData()
161 self.blockIndex = 0
161 self.blockIndex = 0
162
162
163 return
163 return
164
164
165 def parseHeader(self):
165 def parseHeader(self):
166 '''
166 '''
167 '''
167 '''
168
168
169 self.output = {}
169 self.output = {}
170 self.version = '2'
170 self.version = '2'
171 s_parameters = None
171 s_parameters = None
172 if self.ext == '.txt':
172 if self.ext == '.txt':
173 self.parameters = [s.strip().lower() for s in self.fp.readline().decode().strip().split(' ') if s]
173 self.parameters = [s.strip().lower() for s in self.fp.readline().decode().strip().split(' ') if s]
174 elif self.ext == '.hdf5':
174 elif self.ext == '.hdf5':
175 self.metadata = self.fp['Metadata']
175 self.metadata = self.fp['Metadata']
176 if '_record_layout' in self.metadata:
176 if '_record_layout' in self.metadata:
177 s_parameters = [s[0].lower().decode() for s in self.metadata['Independent Spatial Parameters']]
177 s_parameters = [s[0].lower().decode() for s in self.metadata['Independent Spatial Parameters']]
178 self.version = '3'
178 self.version = '3'
179 self.parameters = [s[0].lower().decode() for s in self.metadata['Data Parameters']]
179 self.parameters = [s[0].lower().decode() for s in self.metadata['Data Parameters']]
180
180
181 log.success('Parameters found: {}'.format(self.parameters),
181 log.success('Parameters found: {}'.format(self.parameters),
182 'MADReader')
182 'MADReader')
183 if s_parameters:
183 if s_parameters:
184 log.success('Spatial parameters found: {}'.format(s_parameters),
184 log.success('Spatial parameters found: {}'.format(s_parameters),
185 'MADReader')
185 'MADReader')
186
186
187 for param in list(self.oneDDict.keys()):
187 for param in list(self.oneDDict.keys()):
188 if param.lower() not in self.parameters:
188 if param.lower() not in self.parameters:
189 log.warning(
189 log.warning(
190 'Parameter {} not found will be ignored'.format(
190 'Parameter {} not found will be ignored'.format(
191 param),
191 param),
192 'MADReader')
192 'MADReader')
193 self.oneDDict.pop(param, None)
193 self.oneDDict.pop(param, None)
194
194
195 for param, value in list(self.twoDDict.items()):
195 for param, value in list(self.twoDDict.items()):
196 if param.lower() not in self.parameters:
196 if param.lower() not in self.parameters:
197 log.warning(
197 log.warning(
198 'Parameter {} not found, it will be ignored'.format(
198 'Parameter {} not found, it will be ignored'.format(
199 param),
199 param),
200 'MADReader')
200 'MADReader')
201 self.twoDDict.pop(param, None)
201 self.twoDDict.pop(param, None)
202 continue
202 continue
203 if isinstance(value, list):
203 if isinstance(value, list):
204 if value[0] not in self.output:
204 if value[0] not in self.output:
205 self.output[value[0]] = []
205 self.output[value[0]] = []
206 self.output[value[0]].append([])
206 self.output[value[0]].append([])
207
207
208 def parseData(self):
208 def parseData(self):
209 '''
209 '''
210 '''
210 '''
211
211
212 if self.ext == '.txt':
212 if self.ext == '.txt':
213 self.data = numpy.genfromtxt(self.fp, missing_values=('missing'))
213 self.data = numpy.genfromtxt(self.fp, missing_values=('missing'))
214 self.nrecords = self.data.shape[0]
214 self.nrecords = self.data.shape[0]
215 self.ranges = numpy.unique(self.data[:,self.parameters.index(self.independentParam.lower())])
215 self.ranges = numpy.unique(self.data[:,self.parameters.index(self.independentParam.lower())])
216 self.counter_records = 0
216 self.counter_records = 0
217 elif self.ext == '.hdf5':
217 elif self.ext == '.hdf5':
218 self.data = self.fp['Data']
218 self.data = self.fp['Data']
219 self.ranges = numpy.unique(self.data['Table Layout'][self.independentParam.lower()])
219 self.ranges = numpy.unique(self.data['Table Layout'][self.independentParam.lower()])
220 self.times = numpy.unique(self.data['Table Layout']['ut1_unix'])
220 self.times = numpy.unique(self.data['Table Layout']['ut1_unix'])
221 self.counter_records = int(self.data['Table Layout']['recno'][0])
221 self.counter_records = int(self.data['Table Layout']['recno'][0])
222 self.nrecords = int(self.data['Table Layout']['recno'][-1])
222 self.nrecords = int(self.data['Table Layout']['recno'][-1])
223
223
224 def readNextBlock(self):
224 def readNextBlock(self):
225
225
226 while True:
226 while True:
227 self.flagDiscontinuousBlock = 0
227 self.flagDiscontinuousBlock = 0
228 if self.counter_records == self.nrecords:
228 if self.counter_records == self.nrecords:
229 self.setNextFile()
229 self.setNextFile()
230
230
231 self.readBlock()
231 self.readBlock()
232
232
233 if (self.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or \
233 if (self.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or \
234 (self.datatime > datetime.datetime.combine(self.endDate, self.endTime)):
234 (self.datatime > datetime.datetime.combine(self.endDate, self.endTime)):
235 log.warning(
235 log.warning(
236 'Reading Record No. {}/{} -> {} [Skipping]'.format(
236 'Reading Record No. {}/{} -> {} [Skipping]'.format(
237 self.counter_records,
237 self.counter_records,
238 self.nrecords,
238 self.nrecords,
239 self.datatime.ctime()),
239 self.datatime.ctime()),
240 'MADReader')
240 'MADReader')
241 continue
241 continue
242 break
242 break
243
243
244 log.log(
244 log.log(
245 'Reading Record No. {}/{} -> {}'.format(
245 'Reading Record No. {}/{} -> {}'.format(
246 self.counter_records,
246 self.counter_records,
247 self.nrecords,
247 self.nrecords,
248 self.datatime.ctime()),
248 self.datatime.ctime()),
249 'MADReader')
249 'MADReader')
250
250
251 return 1
251 return 1
252
252
253 def readBlock(self):
253 def readBlock(self):
254 '''
254 '''
255 '''
255 '''
256 dum = []
256 dum = []
257 if self.ext == '.txt':
257 if self.ext == '.txt':
258 dt = self.data[self.counter_records][:6].astype(int)
258 dt = self.data[self.counter_records][:6].astype(int)
259 if datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5]).date() > self.datatime.date():
259 if datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5]).date() > self.datatime.date():
260 self.flagDiscontinuousBlock = 1
260 self.flagDiscontinuousBlock = 1
261 self.datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5])
261 self.datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5])
262 while True:
262 while True:
263 dt = self.data[self.counter_records][:6].astype(int)
263 dt = self.data[self.counter_records][:6].astype(int)
264 datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5])
264 datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5])
265 if datatime == self.datatime:
265 if datatime == self.datatime:
266 dum.append(self.data[self.counter_records])
266 dum.append(self.data[self.counter_records])
267 self.counter_records += 1
267 self.counter_records += 1
268 if self.counter_records == self.nrecords:
268 if self.counter_records == self.nrecords:
269 break
269 break
270 continue
270 continue
271 self.intervals.add((datatime-self.datatime).seconds)
271 self.intervals.add((datatime-self.datatime).seconds)
272 break
272 break
273 elif self.ext == '.hdf5':
273 elif self.ext == '.hdf5':
274 datatime = datetime.datetime.utcfromtimestamp(
274 datatime = datetime.datetime.utcfromtimestamp(
275 self.times[self.counter_records])
275 self.times[self.counter_records])
276 dum = self.data['Table Layout'][self.data['Table Layout']['recno']==self.counter_records]
276 dum = self.data['Table Layout'][self.data['Table Layout']['recno']==self.counter_records]
277 self.intervals.add((datatime-self.datatime).seconds)
277 self.intervals.add((datatime-self.datatime).seconds)
278 if datatime.date()>self.datatime.date():
278 if datatime.date()>self.datatime.date():
279 self.flagDiscontinuousBlock = 1
279 self.flagDiscontinuousBlock = 1
280 self.datatime = datatime
280 self.datatime = datatime
281 self.counter_records += 1
281 self.counter_records += 1
282
282
283 self.buffer = numpy.array(dum)
283 self.buffer = numpy.array(dum)
284 return
284 return
285
285
286 def set_output(self):
286 def set_output(self):
287 '''
287 '''
288 Storing data from buffer to dataOut object
288 Storing data from buffer to dataOut object
289 '''
289 '''
290
290
291 parameters = [None for __ in self.parameters]
291 parameters = [None for __ in self.parameters]
292
292
293 for param, attr in list(self.oneDDict.items()):
293 for param, attr in list(self.oneDDict.items()):
294 x = self.parameters.index(param.lower())
294 x = self.parameters.index(param.lower())
295 setattr(self.dataOut, attr, self.buffer[0][x])
295 setattr(self.dataOut, attr, self.buffer[0][x])
296
296
297 for param, value in list(self.twoDDict.items()):
297 for param, value in list(self.twoDDict.items()):
298 dummy = numpy.zeros(self.ranges.shape) + numpy.nan
298 dummy = numpy.zeros(self.ranges.shape) + numpy.nan
299 if self.ext == '.txt':
299 if self.ext == '.txt':
300 x = self.parameters.index(param.lower())
300 x = self.parameters.index(param.lower())
301 y = self.parameters.index(self.independentParam.lower())
301 y = self.parameters.index(self.independentParam.lower())
302 ranges = self.buffer[:,y]
302 ranges = self.buffer[:,y]
303 #if self.ranges.size == ranges.size:
303 #if self.ranges.size == ranges.size:
304 # continue
304 # continue
305 index = numpy.where(numpy.in1d(self.ranges, ranges))[0]
305 index = numpy.where(numpy.in1d(self.ranges, ranges))[0]
306 dummy[index] = self.buffer[:,x]
306 dummy[index] = self.buffer[:,x]
307 else:
307 else:
308 ranges = self.buffer[self.independentParam.lower()]
308 ranges = self.buffer[self.independentParam.lower()]
309 index = numpy.where(numpy.in1d(self.ranges, ranges))[0]
309 index = numpy.where(numpy.in1d(self.ranges, ranges))[0]
310 dummy[index] = self.buffer[param.lower()]
310 dummy[index] = self.buffer[param.lower()]
311
311
312 if isinstance(value, str):
312 if isinstance(value, str):
313 if value not in self.independentParam:
313 if value not in self.independentParam:
314 setattr(self.dataOut, value, dummy.reshape(1,-1))
314 setattr(self.dataOut, value, dummy.reshape(1,-1))
315 elif isinstance(value, list):
315 elif isinstance(value, list):
316 self.output[value[0]][value[1]] = dummy
316 self.output[value[0]][value[1]] = dummy
317 parameters[value[1]] = param
317 parameters[value[1]] = param
318 for key, value in list(self.output.items()):
318 for key, value in list(self.output.items()):
319 setattr(self.dataOut, key, numpy.array(value))
319 setattr(self.dataOut, key, numpy.array(value))
320
320
321 self.dataOut.parameters = [s for s in parameters if s]
321 self.dataOut.parameters = [s for s in parameters if s]
322 self.dataOut.heightList = self.ranges
322 self.dataOut.heightList = self.ranges
323 self.dataOut.utctime = (self.datatime - datetime.datetime(1970, 1, 1)).total_seconds()
323 self.dataOut.utctime = (self.datatime - datetime.datetime(1970, 1, 1)).total_seconds()
324 self.dataOut.utctimeInit = self.dataOut.utctime
324 self.dataOut.utctimeInit = self.dataOut.utctime
325 self.dataOut.paramInterval = min(self.intervals)
325 self.dataOut.paramInterval = min(self.intervals)
326 self.dataOut.useLocalTime = False
326 self.dataOut.useLocalTime = False
327 self.dataOut.flagNoData = False
327 self.dataOut.flagNoData = False
328 self.dataOut.nrecords = self.nrecords
328 self.dataOut.nrecords = self.nrecords
329 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
329 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
330
330
331 def getData(self):
331 def getData(self):
332 '''
332 '''
333 Storing data from databuffer to dataOut object
333 Storing data from databuffer to dataOut object
334 '''
334 '''
335
335
336 if not self.readNextBlock():
336 if not self.readNextBlock():
337 self.dataOut.flagNoData = True
337 self.dataOut.flagNoData = True
338 return 0
338 return 0
339
339
340 self.set_output()
340 self.set_output()
341
341
342 return 1
342 return 1
343
343
344 def run(self, **kwargs):
344 def run(self, **kwargs):
345
345
346 if not(self.isConfig):
346 if not(self.isConfig):
347 self.setup(**kwargs)
347 self.setup(**kwargs)
348 self.isConfig = True
348 self.isConfig = True
349
349
350 self.getData()
350 self.getData()
351
351
352 return
352 return
353
353
354 @MPDecorator
354 @MPDecorator
355 class MADWriter(Operation):
355 class MADWriter(Operation):
356 '''Writing module for Madrigal files
356 '''Writing module for Madrigal files
357
357
358 type: external
358 type: external
359
359
360 Inputs:
360 Inputs:
361 path path where files will be created
361 path path where files will be created
362 oneDDict json of one-dimensional parameters in record where keys
362 oneDDict json of one-dimensional parameters in record where keys
363 are Madrigal codes (integers or mnemonics) and values the corresponding
363 are Madrigal codes (integers or mnemonics) and values the corresponding
364 dataOut attribute e.g: {
364 dataOut attribute e.g: {
365 'gdlatr': 'lat',
365 'gdlatr': 'lat',
366 'gdlonr': 'lon',
366 'gdlonr': 'lon',
367 'gdlat2':'lat',
367 'gdlat2':'lat',
368 'glon2':'lon'}
368 'glon2':'lon'}
369 ind2DList list of independent spatial two-dimensional parameters e.g:
369 ind2DList list of independent spatial two-dimensional parameters e.g:
370 ['heigthList']
370 ['heigthList']
371 twoDDict json of two-dimensional parameters in record where keys
371 twoDDict json of two-dimensional parameters in record where keys
372 are Madrigal codes (integers or mnemonics) and values the corresponding
372 are Madrigal codes (integers or mnemonics) and values the corresponding
373 dataOut attribute if multidimensional array specify as tupple
373 dataOut attribute if multidimensional array specify as tupple
374 ('attr', pos) e.g: {
374 ('attr', pos) e.g: {
375 'gdalt': 'heightList',
375 'gdalt': 'heightList',
376 'vn1p2': ('data_output', 0),
376 'vn1p2': ('data_output', 0),
377 'vn2p2': ('data_output', 1),
377 'vn2p2': ('data_output', 1),
378 'vn3': ('data_output', 2),
378 'vn3': ('data_output', 2),
379 'snl': ('data_SNR', 'db')
379 'snl': ('data_SNR', 'db')
380 }
380 }
381 metadata json of madrigal metadata (kinst, kindat, catalog and header)
381 metadata json of madrigal metadata (kinst, kindat, catalog and header)
382 format hdf5, cedar
382 format hdf5, cedar
383 blocks number of blocks per file'''
383 blocks number of blocks per file'''
384
384
385 __attrs__ = ['path', 'oneDDict', 'ind2DList', 'twoDDict','metadata', 'format', 'blocks']
385 __attrs__ = ['path', 'oneDDict', 'ind2DList', 'twoDDict','metadata', 'format', 'blocks']
386 missing = -32767
386 missing = -32767
387
387
388 def __init__(self):
388 def __init__(self):
389
389
390 Operation.__init__(self)
390 Operation.__init__(self)
391 self.dataOut = Parameters()
391 self.dataOut = Parameters()
392 self.counter = 0
392 self.counter = 0
393 self.path = None
393 self.path = None
394 self.fp = None
394 self.fp = None
395
395
396 def run(self, dataOut, path, oneDDict, ind2DList='[]', twoDDict='{}',
396 def run(self, dataOut, path, oneDDict, ind2DList='[]', twoDDict='{}',
397 metadata='{}', format='cedar', **kwargs):
397 metadata='{}', format='cedar', **kwargs):
398
398
399
400 #if dataOut.AUX==1: #Modified
401
399 if not self.isConfig:
402 if not self.isConfig:
400 self.setup(path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs)
403 self.setup(path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs)
401 self.isConfig = True
404 self.isConfig = True
402
405
403 self.dataOut = dataOut
406 self.dataOut = dataOut
404 self.putData()
407 self.putData()
408
405 return 1
409 return 1
406
410
407 def setup(self, path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs):
411 def setup(self, path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs):
408 '''
412 '''
409 Configure Operation
413 Configure Operation
410 '''
414 '''
411
415
412 self.path = path
416 self.path = path
413 self.blocks = kwargs.get('blocks', None)
417 self.blocks = kwargs.get('blocks', None)
414 self.counter = 0
418 self.counter = 0
415 self.oneDDict = load_json(oneDDict)
419 self.oneDDict = load_json(oneDDict)
416 self.twoDDict = load_json(twoDDict)
420 self.twoDDict = load_json(twoDDict)
417 self.ind2DList = load_json(ind2DList)
421 self.ind2DList = load_json(ind2DList)
418 meta = load_json(metadata)
422 meta = load_json(metadata)
419 self.kinst = meta.get('kinst')
423 self.kinst = meta.get('kinst')
420 self.kindat = meta.get('kindat')
424 self.kindat = meta.get('kindat')
421 self.catalog = meta.get('catalog', DEF_CATALOG)
425 self.catalog = meta.get('catalog', DEF_CATALOG)
422 self.header = meta.get('header', DEF_HEADER)
426 self.header = meta.get('header', DEF_HEADER)
423 if format == 'cedar':
427 if format == 'cedar':
424 self.ext = '.dat'
428 self.ext = '.dat'
425 self.extra_args = {}
429 self.extra_args = {}
426 elif format == 'hdf5':
430 elif format == 'hdf5':
427 self.ext = '.hdf5'
431 self.ext = '.hdf5'
428 self.extra_args = {'ind2DList': self.ind2DList}
432 self.extra_args = {'ind2DList': self.ind2DList}
429
433
430 self.keys = [k.lower() for k in self.twoDDict]
434 self.keys = [k.lower() for k in self.twoDDict]
431 if 'range' in self.keys:
435 if 'range' in self.keys:
432 self.keys.remove('range')
436 self.keys.remove('range')
433 if 'gdalt' in self.keys:
437 if 'gdalt' in self.keys:
434 self.keys.remove('gdalt')
438 self.keys.remove('gdalt')
435
439
436 def setFile(self):
440 def setFile(self):
437 '''
441 '''
438 Create new cedar file object
442 Create new cedar file object
439 '''
443 '''
440
444
441 self.mnemonic = MNEMONICS[self.kinst] #TODO get mnemonic from madrigal
445 self.mnemonic = MNEMONICS[self.kinst] #TODO get mnemonic from madrigal
442 date = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
446 date = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
447 #if self.dataOut.input_dat_type:
448 #date=datetime.datetime.fromtimestamp(self.dataOut.TimeBlockSeconds_for_dp_power)
449 #print("date",date)
443
450
444 filename = '{}{}{}'.format(self.mnemonic,
451 filename = '{}{}{}'.format(self.mnemonic,
445 date.strftime('%Y%m%d_%H%M%S'),
452 date.strftime('%Y%m%d_%H%M%S'),
446 self.ext)
453 self.ext)
447
454
448 self.fullname = os.path.join(self.path, filename)
455 self.fullname = os.path.join(self.path, filename)
449
456
450 if os.path.isfile(self.fullname) :
457 if os.path.isfile(self.fullname) :
451 log.warning(
458 log.warning(
452 'Destination file {} already exists, previous file deleted.'.format(
459 'Destination file {} already exists, previous file deleted.'.format(
453 self.fullname),
460 self.fullname),
454 'MADWriter')
461 'MADWriter')
455 os.remove(self.fullname)
462 os.remove(self.fullname)
456
463
457 try:
464 try:
458 log.success(
465 log.success(
459 'Creating file: {}'.format(self.fullname),
466 'Creating file: {}'.format(self.fullname),
460 'MADWriter')
467 'MADWriter')
461 if not os.path.exists(self.path):
468 if not os.path.exists(self.path):
462 os.makedirs(self.path)
469 os.makedirs(self.path)
463 self.fp = madrigal.cedar.MadrigalCedarFile(self.fullname, True)
470 self.fp = madrigal.cedar.MadrigalCedarFile(self.fullname, True)
471
472
464 except ValueError as e:
473 except ValueError as e:
465 log.error(
474 log.error(
466 'Impossible to create a cedar object with "madrigal.cedar.MadrigalCedarFile"',
475 'Impossible to create a cedar object with "madrigal.cedar.MadrigalCedarFile"',
467 'MADWriter')
476 'MADWriter')
468 return
477 return
469
478
470 return 1
479 return 1
471
480
472 def writeBlock(self):
481 def writeBlock(self):
473 '''
482 '''
474 Add data records to cedar file taking data from oneDDict and twoDDict
483 Add data records to cedar file taking data from oneDDict and twoDDict
475 attributes.
484 attributes.
476 Allowed parameters in: parcodes.tab
485 Allowed parameters in: parcodes.tab
477 '''
486 '''
478
487 #self.dataOut.paramInterval=2
479 startTime = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
488 startTime = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
489
480 endTime = startTime + datetime.timedelta(seconds=self.dataOut.paramInterval)
490 endTime = startTime + datetime.timedelta(seconds=self.dataOut.paramInterval)
491
492 #if self.dataOut.input_dat_type:
493 #if self.dataOut.experiment=="DP":
494 #startTime=datetime.datetime.fromtimestamp(self.dataOut.TimeBlockSeconds_for_dp_power)
495 #endTime = startTime + datetime.timedelta(seconds=self.dataOut.paramInterval)
496
497
498 #print("2: ",startTime)
499 #print(endTime)
481 heights = self.dataOut.heightList
500 heights = self.dataOut.heightList
482
501
502 #print(self.blocks)
503 #print(startTime)
504 #print(endTime)
505 #print(heights)
506 #input()
483 if self.ext == '.dat':
507 if self.ext == '.dat':
484 for key, value in list(self.twoDDict.items()):
508 for key, value in list(self.twoDDict.items()):
485 if isinstance(value, str):
509 if isinstance(value, str):
486 data = getattr(self.dataOut, value)
510 data = getattr(self.dataOut, value)
487 invalid = numpy.isnan(data)
511 invalid = numpy.isnan(data)
488 data[invalid] = self.missing
512 data[invalid] = self.missing
489 elif isinstance(value, (tuple, list)):
513 elif isinstance(value, (tuple, list)):
490 attr, key = value
514 attr, key = value
491 data = getattr(self.dataOut, attr)
515 data = getattr(self.dataOut, attr)
492 invalid = numpy.isnan(data)
516 invalid = numpy.isnan(data)
493 data[invalid] = self.missing
517 data[invalid] = self.missing
494
518
495 out = {}
519 out = {}
496 for key, value in list(self.twoDDict.items()):
520 for key, value in list(self.twoDDict.items()):
497 key = key.lower()
521 key = key.lower()
498 if isinstance(value, str):
522 if isinstance(value, str):
499 if 'db' in value.lower():
523 if 'db' in value.lower():
500 tmp = getattr(self.dataOut, value.replace('_db', ''))
524 tmp = getattr(self.dataOut, value.replace('_db', ''))
501 SNRavg = numpy.average(tmp, axis=0)
525 SNRavg = numpy.average(tmp, axis=0)
502 tmp = 10*numpy.log10(SNRavg)
526 tmp = 10*numpy.log10(SNRavg)
503 else:
527 else:
504 tmp = getattr(self.dataOut, value)
528 tmp = getattr(self.dataOut, value)
505 out[key] = tmp.flatten()[:len(heights)]
529 out[key] = tmp.flatten()[:len(heights)]
506 elif isinstance(value, (tuple, list)):
530 elif isinstance(value, (tuple, list)):
507 attr, x = value
531 attr, x = value
508 data = getattr(self.dataOut, attr)
532 data = getattr(self.dataOut, attr)
533 #print(x)
534 #print(len(heights))
535 #print(data[int(x)][:len(heights)])
536 #print(numpy.shape(out))
537 #print(numpy.shape(data))
538
509 out[key] = data[int(x)][:len(heights)]
539 out[key] = data[int(x)][:len(heights)]
510
540
511 a = numpy.array([out[k] for k in self.keys])
541 a = numpy.array([out[k] for k in self.keys])
542 #print(a)
512 nrows = numpy.array([numpy.isnan(a[:, x]).all() for x in range(len(heights))])
543 nrows = numpy.array([numpy.isnan(a[:, x]).all() for x in range(len(heights))])
513 index = numpy.where(nrows == False)[0]
544 index = numpy.where(nrows == False)[0]
514
545
546 #print(startTime.minute)
515 rec = madrigal.cedar.MadrigalDataRecord(
547 rec = madrigal.cedar.MadrigalDataRecord(
516 self.kinst,
548 self.kinst,
517 self.kindat,
549 self.kindat,
518 startTime.year,
550 startTime.year,
519 startTime.month,
551 startTime.month,
520 startTime.day,
552 startTime.day,
521 startTime.hour,
553 startTime.hour,
522 startTime.minute,
554 startTime.minute,
523 startTime.second,
555 startTime.second,
524 startTime.microsecond/10000,
556 startTime.microsecond/10000,
525 endTime.year,
557 endTime.year,
526 endTime.month,
558 endTime.month,
527 endTime.day,
559 endTime.day,
528 endTime.hour,
560 endTime.hour,
529 endTime.minute,
561 endTime.minute,
530 endTime.second,
562 endTime.second,
531 endTime.microsecond/10000,
563 endTime.microsecond/10000,
532 list(self.oneDDict.keys()),
564 list(self.oneDDict.keys()),
533 list(self.twoDDict.keys()),
565 list(self.twoDDict.keys()),
534 len(index),
566 len(index),
535 **self.extra_args
567 **self.extra_args
536 )
568 )
537
569 #print("rec",rec)
538 # Setting 1d values
570 # Setting 1d values
539 for key in self.oneDDict:
571 for key in self.oneDDict:
540 rec.set1D(key, getattr(self.dataOut, self.oneDDict[key]))
572 rec.set1D(key, getattr(self.dataOut, self.oneDDict[key]))
541
573
542 # Setting 2d values
574 # Setting 2d values
543 nrec = 0
575 nrec = 0
544 for n in index:
576 for n in index:
545 for key in out:
577 for key in out:
546 rec.set2D(key, nrec, out[key][n])
578 rec.set2D(key, nrec, out[key][n])
547 nrec += 1
579 nrec += 1
548
580
549 self.fp.append(rec)
581 self.fp.append(rec)
550 if self.ext == '.hdf5' and self.counter % 500 == 0 and self.counter > 0:
582 if self.ext == '.hdf5' and self.counter %2 == 0 and self.counter > 0:
583 #print("here")
551 self.fp.dump()
584 self.fp.dump()
552 if self.counter % 20 == 0 and self.counter > 0:
585 if self.counter % 20 == 0 and self.counter > 0:
586 #self.fp.write()
553 log.log(
587 log.log(
554 'Writing {} records'.format(
588 'Writing {} records'.format(
555 self.counter),
589 self.counter),
556 'MADWriter')
590 'MADWriter')
557
591
558 def setHeader(self):
592 def setHeader(self):
559 '''
593 '''
560 Create an add catalog and header to cedar file
594 Create an add catalog and header to cedar file
561 '''
595 '''
562
596
563 log.success('Closing file {}'.format(self.fullname), 'MADWriter')
597 log.success('Closing file {}'.format(self.fullname), 'MADWriter')
564
598
565 if self.ext == '.dat':
599 if self.ext == '.dat':
566 self.fp.write()
600 self.fp.write()
567 else:
601 else:
568 self.fp.dump()
602 self.fp.dump()
569 self.fp.close()
603 self.fp.close()
570
604
571 header = madrigal.cedar.CatalogHeaderCreator(self.fullname)
605 header = madrigal.cedar.CatalogHeaderCreator(self.fullname)
572 header.createCatalog(**self.catalog)
606 header.createCatalog(**self.catalog)
573 header.createHeader(**self.header)
607 header.createHeader(**self.header)
574 header.write()
608 header.write()
575
609
576 def putData(self):
610 def putData(self):
577
611
578 if self.dataOut.flagNoData:
612 if self.dataOut.flagNoData:
579 return 0
613 return 0
580
614
581 if self.dataOut.flagDiscontinuousBlock or self.counter == self.blocks:
615 if self.dataOut.flagDiscontinuousBlock or self.counter == self.blocks:
582 if self.counter > 0:
616 if self.counter > 0:
583 self.setHeader()
617 self.setHeader()
584 self.counter = 0
618 self.counter = 0
585
619
586 if self.counter == 0:
620 if self.counter == 0:
587 self.setFile()
621 self.setFile()
588
622
589 self.writeBlock()
623 self.writeBlock()
590 self.counter += 1
624 self.counter += 1
591
625
592 def close(self):
626 def close(self):
593
627
594 if self.counter > 0:
628 if self.counter > 0:
595 self.setHeader()
629 self.setHeader()
@@ -1,626 +1,627
1 import os
1 import os
2 import time
2 import time
3 import datetime
3 import datetime
4
4
5 import numpy
5 import numpy
6 import h5py
6 import h5py
7
7
8 import schainpy.admin
8 import schainpy.admin
9 from schainpy.model.data.jrodata import *
9 from schainpy.model.data.jrodata import *
10 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
10 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
11 from schainpy.model.io.jroIO_base import *
11 from schainpy.model.io.jroIO_base import *
12 from schainpy.utils import log
12 from schainpy.utils import log
13
13
14
14
15 class HDFReader(Reader, ProcessingUnit):
15 class HDFReader(Reader, ProcessingUnit):
16 """Processing unit to read HDF5 format files
16 """Processing unit to read HDF5 format files
17
17
18 This unit reads HDF5 files created with `HDFWriter` operation contains
18 This unit reads HDF5 files created with `HDFWriter` operation contains
19 by default two groups Data and Metadata all variables would be saved as `dataOut`
19 by default two groups Data and Metadata all variables would be saved as `dataOut`
20 attributes.
20 attributes.
21 It is possible to read any HDF5 file by given the structure in the `description`
21 It is possible to read any HDF5 file by given the structure in the `description`
22 parameter, also you can add extra values to metadata with the parameter `extras`.
22 parameter, also you can add extra values to metadata with the parameter `extras`.
23
23
24 Parameters:
24 Parameters:
25 -----------
25 -----------
26 path : str
26 path : str
27 Path where files are located.
27 Path where files are located.
28 startDate : date
28 startDate : date
29 Start date of the files
29 Start date of the files
30 endDate : list
30 endDate : list
31 End date of the files
31 End date of the files
32 startTime : time
32 startTime : time
33 Start time of the files
33 Start time of the files
34 endTime : time
34 endTime : time
35 End time of the files
35 End time of the files
36 description : dict, optional
36 description : dict, optional
37 Dictionary with the description of the HDF5 file
37 Dictionary with the description of the HDF5 file
38 extras : dict, optional
38 extras : dict, optional
39 Dictionary with extra metadata to be be added to `dataOut`
39 Dictionary with extra metadata to be be added to `dataOut`
40
40
41 Examples
41 Examples
42 --------
42 --------
43
43
44 desc = {
44 desc = {
45 'Data': {
45 'Data': {
46 'data_output': ['u', 'v', 'w'],
46 'data_output': ['u', 'v', 'w'],
47 'utctime': 'timestamps',
47 'utctime': 'timestamps',
48 } ,
48 } ,
49 'Metadata': {
49 'Metadata': {
50 'heightList': 'heights'
50 'heightList': 'heights'
51 }
51 }
52 }
52 }
53
53
54 desc = {
54 desc = {
55 'Data': {
55 'Data': {
56 'data_output': 'winds',
56 'data_output': 'winds',
57 'utctime': 'timestamps'
57 'utctime': 'timestamps'
58 },
58 },
59 'Metadata': {
59 'Metadata': {
60 'heightList': 'heights'
60 'heightList': 'heights'
61 }
61 }
62 }
62 }
63
63
64 extras = {
64 extras = {
65 'timeZone': 300
65 'timeZone': 300
66 }
66 }
67
67
68 reader = project.addReadUnit(
68 reader = project.addReadUnit(
69 name='HDFReader',
69 name='HDFReader',
70 path='/path/to/files',
70 path='/path/to/files',
71 startDate='2019/01/01',
71 startDate='2019/01/01',
72 endDate='2019/01/31',
72 endDate='2019/01/31',
73 startTime='00:00:00',
73 startTime='00:00:00',
74 endTime='23:59:59',
74 endTime='23:59:59',
75 # description=json.dumps(desc),
75 # description=json.dumps(desc),
76 # extras=json.dumps(extras),
76 # extras=json.dumps(extras),
77 )
77 )
78
78
79 """
79 """
80
80
81 __attrs__ = ['path', 'startDate', 'endDate', 'startTime', 'endTime', 'description', 'extras']
81 __attrs__ = ['path', 'startDate', 'endDate', 'startTime', 'endTime', 'description', 'extras']
82
82
83 def __init__(self):
83 def __init__(self):
84 ProcessingUnit.__init__(self)
84 ProcessingUnit.__init__(self)
85 self.dataOut = Parameters()
85 self.dataOut = Parameters()
86 self.ext = ".hdf5"
86 self.ext = ".hdf5"
87 self.optchar = "D"
87 self.optchar = "D"
88 self.meta = {}
88 self.meta = {}
89 self.data = {}
89 self.data = {}
90 self.open_file = h5py.File
90 self.open_file = h5py.File
91 self.open_mode = 'r'
91 self.open_mode = 'r'
92 self.description = {}
92 self.description = {}
93 self.extras = {}
93 self.extras = {}
94 self.filefmt = "*%Y%j***"
94 self.filefmt = "*%Y%j***"
95 self.folderfmt = "*%Y%j"
95 self.folderfmt = "*%Y%j"
96
96
97 def setup(self, **kwargs):
97 def setup(self, **kwargs):
98
98
99 self.set_kwargs(**kwargs)
99 self.set_kwargs(**kwargs)
100 if not self.ext.startswith('.'):
100 if not self.ext.startswith('.'):
101 self.ext = '.{}'.format(self.ext)
101 self.ext = '.{}'.format(self.ext)
102
102
103 if self.online:
103 if self.online:
104 log.log("Searching files in online mode...", self.name)
104 log.log("Searching files in online mode...", self.name)
105
105
106 for nTries in range(self.nTries):
106 for nTries in range(self.nTries):
107 fullpath = self.searchFilesOnLine(self.path, self.startDate,
107 fullpath = self.searchFilesOnLine(self.path, self.startDate,
108 self.endDate, self.expLabel, self.ext, self.walk,
108 self.endDate, self.expLabel, self.ext, self.walk,
109 self.filefmt, self.folderfmt)
109 self.filefmt, self.folderfmt)
110 try:
110 try:
111 fullpath = next(fullpath)
111 fullpath = next(fullpath)
112 except:
112 except:
113 fullpath = None
113 fullpath = None
114
114
115 if fullpath:
115 if fullpath:
116 break
116 break
117
117
118 log.warning(
118 log.warning(
119 'Waiting {} sec for a valid file in {}: try {} ...'.format(
119 'Waiting {} sec for a valid file in {}: try {} ...'.format(
120 self.delay, self.path, nTries + 1),
120 self.delay, self.path, nTries + 1),
121 self.name)
121 self.name)
122 time.sleep(self.delay)
122 time.sleep(self.delay)
123
123
124 if not(fullpath):
124 if not(fullpath):
125 raise schainpy.admin.SchainError(
125 raise schainpy.admin.SchainError(
126 'There isn\'t any valid file in {}'.format(self.path))
126 'There isn\'t any valid file in {}'.format(self.path))
127
127
128 pathname, filename = os.path.split(fullpath)
128 pathname, filename = os.path.split(fullpath)
129 self.year = int(filename[1:5])
129 self.year = int(filename[1:5])
130 self.doy = int(filename[5:8])
130 self.doy = int(filename[5:8])
131 self.set = int(filename[8:11]) - 1
131 self.set = int(filename[8:11]) - 1
132 else:
132 else:
133 log.log("Searching files in {}".format(self.path), self.name)
133 log.log("Searching files in {}".format(self.path), self.name)
134 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
134 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
135 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
135 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
136
136
137 self.setNextFile()
137 self.setNextFile()
138
138
139 return
139 return
140
140
141 def readFirstHeader(self):
141 def readFirstHeader(self):
142 '''Read metadata and data'''
142 '''Read metadata and data'''
143
143
144 self.__readMetadata()
144 self.__readMetadata()
145 self.__readData()
145 self.__readData()
146 self.__setBlockList()
146 self.__setBlockList()
147
147
148 if 'type' in self.meta:
148 if 'type' in self.meta:
149 self.dataOut = eval(self.meta['type'])()
149 self.dataOut = eval(self.meta['type'])()
150
150
151 for attr in self.meta:
151 for attr in self.meta:
152 setattr(self.dataOut, attr, self.meta[attr])
152 setattr(self.dataOut, attr, self.meta[attr])
153
153
154 self.blockIndex = 0
154 self.blockIndex = 0
155
155
156 return
156 return
157
157
158 def __setBlockList(self):
158 def __setBlockList(self):
159 '''
159 '''
160 Selects the data within the times defined
160 Selects the data within the times defined
161
161
162 self.fp
162 self.fp
163 self.startTime
163 self.startTime
164 self.endTime
164 self.endTime
165 self.blockList
165 self.blockList
166 self.blocksPerFile
166 self.blocksPerFile
167
167
168 '''
168 '''
169
169
170 startTime = self.startTime
170 startTime = self.startTime
171 endTime = self.endTime
171 endTime = self.endTime
172
172
173 thisUtcTime = self.data['utctime']
173 thisUtcTime = self.data['utctime']
174 self.interval = numpy.min(thisUtcTime[1:] - thisUtcTime[:-1])
174 self.interval = numpy.min(thisUtcTime[1:] - thisUtcTime[:-1])
175
175
176 thisDatetime = datetime.datetime.utcfromtimestamp(thisUtcTime[0])
176 thisDatetime = datetime.datetime.utcfromtimestamp(thisUtcTime[0])
177
177
178 thisDate = thisDatetime.date()
178 thisDate = thisDatetime.date()
179 thisTime = thisDatetime.time()
179 thisTime = thisDatetime.time()
180
180
181 startUtcTime = (datetime.datetime.combine(thisDate, startTime) - datetime.datetime(1970, 1, 1)).total_seconds()
181 startUtcTime = (datetime.datetime.combine(thisDate, startTime) - datetime.datetime(1970, 1, 1)).total_seconds()
182 endUtcTime = (datetime.datetime.combine(thisDate, endTime) - datetime.datetime(1970, 1, 1)).total_seconds()
182 endUtcTime = (datetime.datetime.combine(thisDate, endTime) - datetime.datetime(1970, 1, 1)).total_seconds()
183
183
184 ind = numpy.where(numpy.logical_and(thisUtcTime >= startUtcTime, thisUtcTime < endUtcTime))[0]
184 ind = numpy.where(numpy.logical_and(thisUtcTime >= startUtcTime, thisUtcTime < endUtcTime))[0]
185
185
186 self.blockList = ind
186 self.blockList = ind
187 self.blocksPerFile = len(ind)
187 self.blocksPerFile = len(ind)
188 return
188 return
189
189
190 def __readMetadata(self):
190 def __readMetadata(self):
191 '''
191 '''
192 Reads Metadata
192 Reads Metadata
193 '''
193 '''
194
194
195 meta = {}
195 meta = {}
196
196
197 if self.description:
197 if self.description:
198 for key, value in self.description['Metadata'].items():
198 for key, value in self.description['Metadata'].items():
199 meta[key] = self.fp[value].value
199 meta[key] = self.fp[value].value
200 else:
200 else:
201 grp = self.fp['Metadata']
201 grp = self.fp['Metadata']
202 for name in grp:
202 for name in grp:
203 meta[name] = grp[name].value
203 meta[name] = grp[name].value
204
204
205 if self.extras:
205 if self.extras:
206 for key, value in self.extras.items():
206 for key, value in self.extras.items():
207 meta[key] = value
207 meta[key] = value
208 self.meta = meta
208 self.meta = meta
209
209
210 return
210 return
211
211
212 def __readData(self):
212 def __readData(self):
213
213
214 data = {}
214 data = {}
215
215
216 if self.description:
216 if self.description:
217 for key, value in self.description['Data'].items():
217 for key, value in self.description['Data'].items():
218 if isinstance(value, str):
218 if isinstance(value, str):
219 if isinstance(self.fp[value], h5py.Dataset):
219 if isinstance(self.fp[value], h5py.Dataset):
220 data[key] = self.fp[value].value
220 data[key] = self.fp[value].value
221 elif isinstance(self.fp[value], h5py.Group):
221 elif isinstance(self.fp[value], h5py.Group):
222 array = []
222 array = []
223 for ch in self.fp[value]:
223 for ch in self.fp[value]:
224 array.append(self.fp[value][ch].value)
224 array.append(self.fp[value][ch].value)
225 data[key] = numpy.array(array)
225 data[key] = numpy.array(array)
226 elif isinstance(value, list):
226 elif isinstance(value, list):
227 array = []
227 array = []
228 for ch in value:
228 for ch in value:
229 array.append(self.fp[ch].value)
229 array.append(self.fp[ch].value)
230 data[key] = numpy.array(array)
230 data[key] = numpy.array(array)
231 else:
231 else:
232 grp = self.fp['Data']
232 grp = self.fp['Data']
233 for name in grp:
233 for name in grp:
234 if isinstance(grp[name], h5py.Dataset):
234 if isinstance(grp[name], h5py.Dataset):
235 array = grp[name].value
235 array = grp[name].value
236 elif isinstance(grp[name], h5py.Group):
236 elif isinstance(grp[name], h5py.Group):
237 array = []
237 array = []
238 for ch in grp[name]:
238 for ch in grp[name]:
239 array.append(grp[name][ch].value)
239 array.append(grp[name][ch].value)
240 array = numpy.array(array)
240 array = numpy.array(array)
241 else:
241 else:
242 log.warning('Unknown type: {}'.format(name))
242 log.warning('Unknown type: {}'.format(name))
243
243
244 if name in self.description:
244 if name in self.description:
245 key = self.description[name]
245 key = self.description[name]
246 else:
246 else:
247 key = name
247 key = name
248 data[key] = array
248 data[key] = array
249
249
250 self.data = data
250 self.data = data
251 return
251 return
252
252
253 def getData(self):
253 def getData(self):
254
254
255 for attr in self.data:
255 for attr in self.data:
256 if self.data[attr].ndim == 1:
256 if self.data[attr].ndim == 1:
257 setattr(self.dataOut, attr, self.data[attr][self.blockIndex])
257 setattr(self.dataOut, attr, self.data[attr][self.blockIndex])
258 else:
258 else:
259 setattr(self.dataOut, attr, self.data[attr][:, self.blockIndex])
259 setattr(self.dataOut, attr, self.data[attr][:, self.blockIndex])
260
260
261 self.dataOut.flagNoData = False
261 self.dataOut.flagNoData = False
262 self.blockIndex += 1
262 self.blockIndex += 1
263
263
264 log.log("Block No. {}/{} -> {}".format(
264 log.log("Block No. {}/{} -> {}".format(
265 self.blockIndex,
265 self.blockIndex,
266 self.blocksPerFile,
266 self.blocksPerFile,
267 self.dataOut.datatime.ctime()), self.name)
267 self.dataOut.datatime.ctime()), self.name)
268
268
269 return
269 return
270
270
271 def run(self, **kwargs):
271 def run(self, **kwargs):
272
272
273 if not(self.isConfig):
273 if not(self.isConfig):
274 self.setup(**kwargs)
274 self.setup(**kwargs)
275 self.isConfig = True
275 self.isConfig = True
276
276
277 if self.blockIndex == self.blocksPerFile:
277 if self.blockIndex == self.blocksPerFile:
278 self.setNextFile()
278 self.setNextFile()
279
279
280 self.getData()
280 self.getData()
281
281
282 return
282 return
283
283
284 @MPDecorator
284 @MPDecorator
285 class HDFWriter(Operation):
285 class HDFWriter(Operation):
286 """Operation to write HDF5 files.
286 """Operation to write HDF5 files.
287
287
288 The HDF5 file contains by default two groups Data and Metadata where
288 The HDF5 file contains by default two groups Data and Metadata where
289 you can save any `dataOut` attribute specified by `dataList` and `metadataList`
289 you can save any `dataOut` attribute specified by `dataList` and `metadataList`
290 parameters, data attributes are normaly time dependent where the metadata
290 parameters, data attributes are normaly time dependent where the metadata
291 are not.
291 are not.
292 It is possible to customize the structure of the HDF5 file with the
292 It is possible to customize the structure of the HDF5 file with the
293 optional description parameter see the examples.
293 optional description parameter see the examples.
294
294
295 Parameters:
295 Parameters:
296 -----------
296 -----------
297 path : str
297 path : str
298 Path where files will be saved.
298 Path where files will be saved.
299 blocksPerFile : int
299 blocksPerFile : int
300 Number of blocks per file
300 Number of blocks per file
301 metadataList : list
301 metadataList : list
302 List of the dataOut attributes that will be saved as metadata
302 List of the dataOut attributes that will be saved as metadata
303 dataList : int
303 dataList : int
304 List of the dataOut attributes that will be saved as data
304 List of the dataOut attributes that will be saved as data
305 setType : bool
305 setType : bool
306 If True the name of the files corresponds to the timestamp of the data
306 If True the name of the files corresponds to the timestamp of the data
307 description : dict, optional
307 description : dict, optional
308 Dictionary with the desired description of the HDF5 file
308 Dictionary with the desired description of the HDF5 file
309
309
310 Examples
310 Examples
311 --------
311 --------
312
312
313 desc = {
313 desc = {
314 'data_output': {'winds': ['z', 'w', 'v']},
314 'data_output': {'winds': ['z', 'w', 'v']},
315 'utctime': 'timestamps',
315 'utctime': 'timestamps',
316 'heightList': 'heights'
316 'heightList': 'heights'
317 }
317 }
318 desc = {
318 desc = {
319 'data_output': ['z', 'w', 'v'],
319 'data_output': ['z', 'w', 'v'],
320 'utctime': 'timestamps',
320 'utctime': 'timestamps',
321 'heightList': 'heights'
321 'heightList': 'heights'
322 }
322 }
323 desc = {
323 desc = {
324 'Data': {
324 'Data': {
325 'data_output': 'winds',
325 'data_output': 'winds',
326 'utctime': 'timestamps'
326 'utctime': 'timestamps'
327 },
327 },
328 'Metadata': {
328 'Metadata': {
329 'heightList': 'heights'
329 'heightList': 'heights'
330 }
330 }
331 }
331 }
332
332
333 writer = proc_unit.addOperation(name='HDFWriter')
333 writer = proc_unit.addOperation(name='HDFWriter')
334 writer.addParameter(name='path', value='/path/to/file')
334 writer.addParameter(name='path', value='/path/to/file')
335 writer.addParameter(name='blocksPerFile', value='32')
335 writer.addParameter(name='blocksPerFile', value='32')
336 writer.addParameter(name='metadataList', value='heightList,timeZone')
336 writer.addParameter(name='metadataList', value='heightList,timeZone')
337 writer.addParameter(name='dataList',value='data_output,utctime')
337 writer.addParameter(name='dataList',value='data_output,utctime')
338 # writer.addParameter(name='description',value=json.dumps(desc))
338 # writer.addParameter(name='description',value=json.dumps(desc))
339
339
340 """
340 """
341
341
342 ext = ".hdf5"
342 ext = ".hdf5"
343 optchar = "D"
343 optchar = "D"
344 filename = None
344 filename = None
345 path = None
345 path = None
346 setFile = None
346 setFile = None
347 fp = None
347 fp = None
348 firsttime = True
348 firsttime = True
349 #Configurations
349 #Configurations
350 blocksPerFile = None
350 blocksPerFile = None
351 blockIndex = None
351 blockIndex = None
352 dataOut = None
352 dataOut = None
353 #Data Arrays
353 #Data Arrays
354 dataList = None
354 dataList = None
355 metadataList = None
355 metadataList = None
356 currentDay = None
356 currentDay = None
357 lastTime = None
357 lastTime = None
358
358
359 def __init__(self):
359 def __init__(self):
360
360
361 Operation.__init__(self)
361 Operation.__init__(self)
362 return
362 return
363
363
364 def setup(self, path=None, blocksPerFile=10, metadataList=None, dataList=None, setType=None, description=None):
364 def setup(self, path=None, blocksPerFile=10, metadataList=None, dataList=None, setType=None, description=None):
365 self.path = path
365 self.path = path
366 self.blocksPerFile = blocksPerFile
366 self.blocksPerFile = blocksPerFile
367 self.metadataList = metadataList
367 self.metadataList = metadataList
368 self.dataList = [s.strip() for s in dataList]
368 self.dataList = [s.strip() for s in dataList]
369 self.setType = setType
369 self.setType = setType
370 self.description = description
370 self.description = description
371
371
372 if self.metadataList is None:
372 if self.metadataList is None:
373 self.metadataList = self.dataOut.metadata_list
373 self.metadataList = self.dataOut.metadata_list
374
374
375 tableList = []
375 tableList = []
376 dsList = []
376 dsList = []
377
377
378 for i in range(len(self.dataList)):
378 for i in range(len(self.dataList)):
379 dsDict = {}
379 dsDict = {}
380 if hasattr(self.dataOut, self.dataList[i]):
380 if hasattr(self.dataOut, self.dataList[i]):
381 dataAux = getattr(self.dataOut, self.dataList[i])
381 dataAux = getattr(self.dataOut, self.dataList[i])
382 dsDict['variable'] = self.dataList[i]
382 dsDict['variable'] = self.dataList[i]
383 else:
383 else:
384 log.warning('Attribute {} not found in dataOut', self.name)
384 log.warning('Attribute {} not found in dataOut', self.name)
385 continue
385 continue
386
386
387 if dataAux is None:
387 if dataAux is None:
388 continue
388 continue
389 elif isinstance(dataAux, (int, float, numpy.integer, numpy.float)):
389 elif isinstance(dataAux, (int, float, numpy.integer, numpy.float)):
390 dsDict['nDim'] = 0
390 dsDict['nDim'] = 0
391 else:
391 else:
392 dsDict['nDim'] = len(dataAux.shape)
392 dsDict['nDim'] = len(dataAux.shape)
393 dsDict['shape'] = dataAux.shape
393 dsDict['shape'] = dataAux.shape
394 dsDict['dsNumber'] = dataAux.shape[0]
394 dsDict['dsNumber'] = dataAux.shape[0]
395 dsDict['dtype'] = dataAux.dtype
395 dsDict['dtype'] = dataAux.dtype
396
396
397 dsList.append(dsDict)
397 dsList.append(dsDict)
398
398
399 self.dsList = dsList
399 self.dsList = dsList
400 self.currentDay = self.dataOut.datatime.date()
400 self.currentDay = self.dataOut.datatime.date()
401
401
402 def timeFlag(self):
402 def timeFlag(self):
403 currentTime = self.dataOut.utctime
403 currentTime = self.dataOut.utctime
404 timeTuple = time.localtime(currentTime)
404 timeTuple = time.localtime(currentTime)
405 dataDay = timeTuple.tm_yday
405 dataDay = timeTuple.tm_yday
406
406
407 if self.lastTime is None:
407 if self.lastTime is None:
408 self.lastTime = currentTime
408 self.lastTime = currentTime
409 self.currentDay = dataDay
409 self.currentDay = dataDay
410 return False
410 return False
411
411
412 timeDiff = currentTime - self.lastTime
412 timeDiff = currentTime - self.lastTime
413
413
414 #Si el dia es diferente o si la diferencia entre un dato y otro supera la hora
414 #Si el dia es diferente o si la diferencia entre un dato y otro supera la hora
415 if dataDay != self.currentDay:
415 if dataDay != self.currentDay:
416 self.currentDay = dataDay
416 self.currentDay = dataDay
417 return True
417 return True
418 elif timeDiff > 3*60*60:
418 elif timeDiff > 3*60*60:
419 self.lastTime = currentTime
419 self.lastTime = currentTime
420 return True
420 return True
421 else:
421 else:
422 self.lastTime = currentTime
422 self.lastTime = currentTime
423 return False
423 return False
424
424
425 def run(self, dataOut, path, blocksPerFile=10, metadataList=None,
425 def run(self, dataOut, path, blocksPerFile=10, metadataList=None,
426 dataList=[], setType=None, description={}):
426 dataList=[], setType=None, description={}):
427
427 print("hdf",dataOut.flagNoData)
428 print(dataOut.datatime.ctime())
428 self.dataOut = dataOut
429 self.dataOut = dataOut
429 if not(self.isConfig):
430 if not(self.isConfig):
430 self.setup(path=path, blocksPerFile=blocksPerFile,
431 self.setup(path=path, blocksPerFile=blocksPerFile,
431 metadataList=metadataList, dataList=dataList,
432 metadataList=metadataList, dataList=dataList,
432 setType=setType, description=description)
433 setType=setType, description=description)
433
434
434 self.isConfig = True
435 self.isConfig = True
435 self.setNextFile()
436 self.setNextFile()
436
437
437 self.putData()
438 self.putData()
438 return
439 return
439
440
440 def setNextFile(self):
441 def setNextFile(self):
441
442
442 ext = self.ext
443 ext = self.ext
443 path = self.path
444 path = self.path
444 setFile = self.setFile
445 setFile = self.setFile
445
446
446 timeTuple = time.localtime(self.dataOut.utctime)
447 timeTuple = time.localtime(self.dataOut.utctime)
447 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
448 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
448 fullpath = os.path.join(path, subfolder)
449 fullpath = os.path.join(path, subfolder)
449
450
450 if os.path.exists(fullpath):
451 if os.path.exists(fullpath):
451 filesList = os.listdir(fullpath)
452 filesList = os.listdir(fullpath)
452 filesList = [k for k in filesList if k.startswith(self.optchar)]
453 filesList = [k for k in filesList if k.startswith(self.optchar)]
453 if len( filesList ) > 0:
454 if len( filesList ) > 0:
454 filesList = sorted(filesList, key=str.lower)
455 filesList = sorted(filesList, key=str.lower)
455 filen = filesList[-1]
456 filen = filesList[-1]
456 # el filename debera tener el siguiente formato
457 # el filename debera tener el siguiente formato
457 # 0 1234 567 89A BCDE (hex)
458 # 0 1234 567 89A BCDE (hex)
458 # x YYYY DDD SSS .ext
459 # x YYYY DDD SSS .ext
459 if isNumber(filen[8:11]):
460 if isNumber(filen[8:11]):
460 setFile = int(filen[8:11]) #inicializo mi contador de seteo al seteo del ultimo file
461 setFile = int(filen[8:11]) #inicializo mi contador de seteo al seteo del ultimo file
461 else:
462 else:
462 setFile = -1
463 setFile = -1
463 else:
464 else:
464 setFile = -1 #inicializo mi contador de seteo
465 setFile = -1 #inicializo mi contador de seteo
465 else:
466 else:
466 os.makedirs(fullpath)
467 os.makedirs(fullpath)
467 setFile = -1 #inicializo mi contador de seteo
468 setFile = -1 #inicializo mi contador de seteo
468
469
469 if self.setType is None:
470 if self.setType is None:
470 setFile += 1
471 setFile += 1
471 file = '%s%4.4d%3.3d%03d%s' % (self.optchar,
472 file = '%s%4.4d%3.3d%03d%s' % (self.optchar,
472 timeTuple.tm_year,
473 timeTuple.tm_year,
473 timeTuple.tm_yday,
474 timeTuple.tm_yday,
474 setFile,
475 setFile,
475 ext )
476 ext )
476 else:
477 else:
477 setFile = timeTuple.tm_hour*60+timeTuple.tm_min
478 setFile = timeTuple.tm_hour*60+timeTuple.tm_min
478 file = '%s%4.4d%3.3d%04d%s' % (self.optchar,
479 file = '%s%4.4d%3.3d%04d%s' % (self.optchar,
479 timeTuple.tm_year,
480 timeTuple.tm_year,
480 timeTuple.tm_yday,
481 timeTuple.tm_yday,
481 setFile,
482 setFile,
482 ext )
483 ext )
483
484
484 self.filename = os.path.join( path, subfolder, file )
485 self.filename = os.path.join( path, subfolder, file )
485
486
486 #Setting HDF5 File
487 #Setting HDF5 File
487 self.fp = h5py.File(self.filename, 'w')
488 self.fp = h5py.File(self.filename, 'w')
488 #write metadata
489 #write metadata
489 self.writeMetadata(self.fp)
490 self.writeMetadata(self.fp)
490 #Write data
491 #Write data
491 self.writeData(self.fp)
492 self.writeData(self.fp)
492
493
493 def getLabel(self, name, x=None):
494 def getLabel(self, name, x=None):
494
495
495 if x is None:
496 if x is None:
496 if 'Data' in self.description:
497 if 'Data' in self.description:
497 data = self.description['Data']
498 data = self.description['Data']
498 if 'Metadata' in self.description:
499 if 'Metadata' in self.description:
499 data.update(self.description['Metadata'])
500 data.update(self.description['Metadata'])
500 else:
501 else:
501 data = self.description
502 data = self.description
502 if name in data:
503 if name in data:
503 if isinstance(data[name], str):
504 if isinstance(data[name], str):
504 return data[name]
505 return data[name]
505 elif isinstance(data[name], list):
506 elif isinstance(data[name], list):
506 return None
507 return None
507 elif isinstance(data[name], dict):
508 elif isinstance(data[name], dict):
508 for key, value in data[name].items():
509 for key, value in data[name].items():
509 return key
510 return key
510 return name
511 return name
511 else:
512 else:
512 if 'Metadata' in self.description:
513 if 'Metadata' in self.description:
513 meta = self.description['Metadata']
514 meta = self.description['Metadata']
514 else:
515 else:
515 meta = self.description
516 meta = self.description
516 if name in meta:
517 if name in meta:
517 if isinstance(meta[name], list):
518 if isinstance(meta[name], list):
518 return meta[name][x]
519 return meta[name][x]
519 elif isinstance(meta[name], dict):
520 elif isinstance(meta[name], dict):
520 for key, value in meta[name].items():
521 for key, value in meta[name].items():
521 return value[x]
522 return value[x]
522 if 'cspc' in name:
523 if 'cspc' in name:
523 return 'pair{:02d}'.format(x)
524 return 'pair{:02d}'.format(x)
524 else:
525 else:
525 return 'channel{:02d}'.format(x)
526 return 'channel{:02d}'.format(x)
526
527
527 def writeMetadata(self, fp):
528 def writeMetadata(self, fp):
528
529
529 if self.description:
530 if self.description:
530 if 'Metadata' in self.description:
531 if 'Metadata' in self.description:
531 grp = fp.create_group('Metadata')
532 grp = fp.create_group('Metadata')
532 else:
533 else:
533 grp = fp
534 grp = fp
534 else:
535 else:
535 grp = fp.create_group('Metadata')
536 grp = fp.create_group('Metadata')
536
537
537 for i in range(len(self.metadataList)):
538 for i in range(len(self.metadataList)):
538 if not hasattr(self.dataOut, self.metadataList[i]):
539 if not hasattr(self.dataOut, self.metadataList[i]):
539 log.warning('Metadata: `{}` not found'.format(self.metadataList[i]), self.name)
540 log.warning('Metadata: `{}` not found'.format(self.metadataList[i]), self.name)
540 continue
541 continue
541 value = getattr(self.dataOut, self.metadataList[i])
542 value = getattr(self.dataOut, self.metadataList[i])
542 if isinstance(value, bool):
543 if isinstance(value, bool):
543 if value is True:
544 if value is True:
544 value = 1
545 value = 1
545 else:
546 else:
546 value = 0
547 value = 0
547 grp.create_dataset(self.getLabel(self.metadataList[i]), data=value)
548 grp.create_dataset(self.getLabel(self.metadataList[i]), data=value)
548 return
549 return
549
550
550 def writeData(self, fp):
551 def writeData(self, fp):
551
552
552 if self.description:
553 if self.description:
553 if 'Data' in self.description:
554 if 'Data' in self.description:
554 grp = fp.create_group('Data')
555 grp = fp.create_group('Data')
555 else:
556 else:
556 grp = fp
557 grp = fp
557 else:
558 else:
558 grp = fp.create_group('Data')
559 grp = fp.create_group('Data')
559
560
560 dtsets = []
561 dtsets = []
561 data = []
562 data = []
562
563
563 for dsInfo in self.dsList:
564 for dsInfo in self.dsList:
564 if dsInfo['nDim'] == 0:
565 if dsInfo['nDim'] == 0:
565 ds = grp.create_dataset(
566 ds = grp.create_dataset(
566 self.getLabel(dsInfo['variable']),
567 self.getLabel(dsInfo['variable']),
567 (self.blocksPerFile, ),
568 (self.blocksPerFile, ),
568 chunks=True,
569 chunks=True,
569 dtype=numpy.float64)
570 dtype=numpy.float64)
570 dtsets.append(ds)
571 dtsets.append(ds)
571 data.append((dsInfo['variable'], -1))
572 data.append((dsInfo['variable'], -1))
572 else:
573 else:
573 label = self.getLabel(dsInfo['variable'])
574 label = self.getLabel(dsInfo['variable'])
574 if label is not None:
575 if label is not None:
575 sgrp = grp.create_group(label)
576 sgrp = grp.create_group(label)
576 else:
577 else:
577 sgrp = grp
578 sgrp = grp
578 for i in range(dsInfo['dsNumber']):
579 for i in range(dsInfo['dsNumber']):
579 ds = sgrp.create_dataset(
580 ds = sgrp.create_dataset(
580 self.getLabel(dsInfo['variable'], i),
581 self.getLabel(dsInfo['variable'], i),
581 (self.blocksPerFile, ) + dsInfo['shape'][1:],
582 (self.blocksPerFile, ) + dsInfo['shape'][1:],
582 chunks=True,
583 chunks=True,
583 dtype=dsInfo['dtype'])
584 dtype=dsInfo['dtype'])
584 dtsets.append(ds)
585 dtsets.append(ds)
585 data.append((dsInfo['variable'], i))
586 data.append((dsInfo['variable'], i))
586 fp.flush()
587 fp.flush()
587
588
588 log.log('Creating file: {}'.format(fp.filename), self.name)
589 log.log('Creating file: {}'.format(fp.filename), self.name)
589
590
590 self.ds = dtsets
591 self.ds = dtsets
591 self.data = data
592 self.data = data
592 self.firsttime = True
593 self.firsttime = True
593 self.blockIndex = 0
594 self.blockIndex = 0
594 return
595 return
595
596
596 def putData(self):
597 def putData(self):
597
598
598 if (self.blockIndex == self.blocksPerFile) or self.timeFlag():
599 if (self.blockIndex == self.blocksPerFile) or self.timeFlag():
599 self.closeFile()
600 self.closeFile()
600 self.setNextFile()
601 self.setNextFile()
601
602
602 for i, ds in enumerate(self.ds):
603 for i, ds in enumerate(self.ds):
603 attr, ch = self.data[i]
604 attr, ch = self.data[i]
604 if ch == -1:
605 if ch == -1:
605 ds[self.blockIndex] = getattr(self.dataOut, attr)
606 ds[self.blockIndex] = getattr(self.dataOut, attr)
606 else:
607 else:
607 ds[self.blockIndex] = getattr(self.dataOut, attr)[ch]
608 ds[self.blockIndex] = getattr(self.dataOut, attr)[ch]
608
609
609 self.fp.flush()
610 self.fp.flush()
610 self.blockIndex += 1
611 self.blockIndex += 1
611 log.log('Block No. {}/{}'.format(self.blockIndex, self.blocksPerFile), self.name)
612 log.log('Block No. {}/{}'.format(self.blockIndex, self.blocksPerFile), self.name)
612
613
613 return
614 return
614
615
615 def closeFile(self):
616 def closeFile(self):
616
617
617 if self.blockIndex != self.blocksPerFile:
618 if self.blockIndex != self.blocksPerFile:
618 for ds in self.ds:
619 for ds in self.ds:
619 ds.resize(self.blockIndex, axis=0)
620 ds.resize(self.blockIndex, axis=0)
620
621
621 self.fp.flush()
622 self.fp.flush()
622 self.fp.close()
623 self.fp.close()
623
624
624 def close(self):
625 def close(self):
625
626
626 self.closeFile()
627 self.closeFile()
@@ -1,676 +1,692
1 '''
1 '''
2 Created on Jul 2, 2014
2 Created on Jul 2, 2014
3
3
4 @author: roj-idl71
4 @author: roj-idl71
5 '''
5 '''
6
6
7 import numpy
7 import numpy
8
8
9 from .jroIO_base import LOCALTIME, JRODataReader, JRODataWriter
9 from .jroIO_base import LOCALTIME, JRODataReader, JRODataWriter
10 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
10 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
11 from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader
11 from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader
12 from schainpy.model.data.jrodata import Voltage
12 from schainpy.model.data.jrodata import Voltage
13
13
14
14
15 class VoltageReader(JRODataReader, ProcessingUnit):
15 class VoltageReader(JRODataReader, ProcessingUnit):
16 """
16 """
17 Esta clase permite leer datos de voltage desde archivos en formato rawdata (.r). La lectura
17 Esta clase permite leer datos de voltage desde archivos en formato rawdata (.r). La lectura
18 de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones:
18 de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones:
19 perfiles*alturas*canales) son almacenados en la variable "buffer".
19 perfiles*alturas*canales) son almacenados en la variable "buffer".
20
20
21 perfiles * alturas * canales
21 perfiles * alturas * canales
22
22
23 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
23 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
24 RadarControllerHeader y Voltage. Los tres primeros se usan para almacenar informacion de la
24 RadarControllerHeader y Voltage. Los tres primeros se usan para almacenar informacion de la
25 cabecera de datos (metadata), y el cuarto (Voltage) para obtener y almacenar un perfil de
25 cabecera de datos (metadata), y el cuarto (Voltage) para obtener y almacenar un perfil de
26 datos desde el "buffer" cada vez que se ejecute el metodo "getData".
26 datos desde el "buffer" cada vez que se ejecute el metodo "getData".
27
27
28 Example:
28 Example:
29
29
30 dpath = "/home/myuser/data"
30 dpath = "/home/myuser/data"
31
31
32 startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0)
32 startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0)
33
33
34 endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0)
34 endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0)
35
35
36 readerObj = VoltageReader()
36 readerObj = VoltageReader()
37
37
38 readerObj.setup(dpath, startTime, endTime)
38 readerObj.setup(dpath, startTime, endTime)
39
39
40 while(True):
40 while(True):
41
41
42 #to get one profile
42 #to get one profile
43 profile = readerObj.getData()
43 profile = readerObj.getData()
44
44
45 #print the profile
45 #print the profile
46 print profile
46 print profile
47
47
48 #If you want to see all datablock
48 #If you want to see all datablock
49 print readerObj.datablock
49 print readerObj.datablock
50
50
51 if readerObj.flagNoMoreFiles:
51 if readerObj.flagNoMoreFiles:
52 break
52 break
53
53
54 """
54 """
55
55
56 def __init__(self):
56 def __init__(self):
57 """
57 """
58 Inicializador de la clase VoltageReader para la lectura de datos de voltage.
58 Inicializador de la clase VoltageReader para la lectura de datos de voltage.
59
59
60 Input:
60 Input:
61 dataOut : Objeto de la clase Voltage. Este objeto sera utilizado para
61 dataOut : Objeto de la clase Voltage. Este objeto sera utilizado para
62 almacenar un perfil de datos cada vez que se haga un requerimiento
62 almacenar un perfil de datos cada vez que se haga un requerimiento
63 (getData). El perfil sera obtenido a partir del buffer de datos,
63 (getData). El perfil sera obtenido a partir del buffer de datos,
64 si el buffer esta vacio se hara un nuevo proceso de lectura de un
64 si el buffer esta vacio se hara un nuevo proceso de lectura de un
65 bloque de datos.
65 bloque de datos.
66 Si este parametro no es pasado se creara uno internamente.
66 Si este parametro no es pasado se creara uno internamente.
67
67
68 Variables afectadas:
68 Variables afectadas:
69 self.dataOut
69 self.dataOut
70
70
71 Return:
71 Return:
72 None
72 None
73 """
73 """
74
74
75 ProcessingUnit.__init__(self)
75 ProcessingUnit.__init__(self)
76
76
77 self.ext = ".r"
77 self.ext = ".r"
78 self.optchar = "D"
78 self.optchar = "D"
79 self.basicHeaderObj = BasicHeader(LOCALTIME)
79 self.basicHeaderObj = BasicHeader(LOCALTIME)
80 self.systemHeaderObj = SystemHeader()
80 self.systemHeaderObj = SystemHeader()
81 self.radarControllerHeaderObj = RadarControllerHeader()
81 self.radarControllerHeaderObj = RadarControllerHeader()
82
82 self.processingHeaderObj = ProcessingHeader()
83 self.processingHeaderObj = ProcessingHeader()
83 self.lastUTTime = 0
84 self.lastUTTime = 0
84 self.profileIndex = 2**32 - 1
85 self.profileIndex = 2**32 - 1
85 self.dataOut = Voltage()
86 self.dataOut = Voltage()
86 self.selBlocksize = None
87 self.selBlocksize = None
87 self.selBlocktime = None
88 self.selBlocktime = None
88
89 ##print("1--OKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK")
89 def createObjByDefault(self):
90 def createObjByDefault(self):
90
91 ##print("2--OKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK")
91 dataObj = Voltage()
92 dataObj = Voltage()
92
93
93 return dataObj
94 return dataObj
94
95
95 def __hasNotDataInBuffer(self):
96 def __hasNotDataInBuffer(self):
96
97 ##print("3--OKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK")
97 if self.profileIndex >= self.processingHeaderObj.profilesPerBlock * self.nTxs:
98 if self.profileIndex >= self.processingHeaderObj.profilesPerBlock * self.nTxs:
98 return 1
99 return 1
99
100
100 return 0
101 return 0
101
102
102 def getBlockDimension(self):
103 def getBlockDimension(self):
103 """
104 """
104 Obtiene la cantidad de puntos a leer por cada bloque de datos
105 Obtiene la cantidad de puntos a leer por cada bloque de datos
105
106
106 Affected:
107 Affected:
107 self.blocksize
108 self.blocksize
108
109
109 Return:
110 Return:
110 None
111 None
111 """
112 """
113 ##print("4--OKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK")
112 pts2read = self.processingHeaderObj.profilesPerBlock * \
114 pts2read = self.processingHeaderObj.profilesPerBlock * \
113 self.processingHeaderObj.nHeights * self.systemHeaderObj.nChannels
115 self.processingHeaderObj.nHeights * self.systemHeaderObj.nChannels
114 self.blocksize = pts2read
116 self.blocksize = pts2read
115
117
116 def readBlock(self):
118 def readBlock(self):
119
117 """
120 """
118 readBlock lee el bloque de datos desde la posicion actual del puntero del archivo
121 readBlock lee el bloque de datos desde la posicion actual del puntero del archivo
119 (self.fp) y actualiza todos los parametros relacionados al bloque de datos
122 (self.fp) y actualiza todos los parametros relacionados al bloque de datos
120 (metadata + data). La data leida es almacenada en el buffer y el contador del buffer
123 (metadata + data). La data leida es almacenada en el buffer y el contador del buffer
121 es seteado a 0
124 es seteado a 0
122
125
123 Inputs:
126 Inputs:
124 None
127 None
125
128
126 Return:
129 Return:
127 None
130 None
128
131
129 Affected:
132 Affected:
130 self.profileIndex
133 self.profileIndex
131 self.datablock
134 self.datablock
132 self.flagIsNewFile
135 self.flagIsNewFile
133 self.flagIsNewBlock
136 self.flagIsNewBlock
134 self.nTotalBlocks
137 self.nTotalBlocks
135
138
136 Exceptions:
139 Exceptions:
137 Si un bloque leido no es un bloque valido
140 Si un bloque leido no es un bloque valido
138 """
141 """
139
142 ##print("5--OKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK")
140 # if self.server is not None:
143 # if self.server is not None:
141 # self.zBlock = self.receiver.recv()
144 # self.zBlock = self.receiver.recv()
142 # self.zHeader = self.zBlock[:24]
145 # self.zHeader = self.zBlock[:24]
143 # self.zDataBlock = self.zBlock[24:]
146 # self.zDataBlock = self.zBlock[24:]
144 # junk = numpy.fromstring(self.zDataBlock, numpy.dtype([('real','<i4'),('imag','<i4')]))
147 # junk = numpy.fromstring(self.zDataBlock, numpy.dtype([('real','<i4'),('imag','<i4')]))
145 # self.processingHeaderObj.profilesPerBlock = 240
148 # self.processingHeaderObj.profilesPerBlock = 240
146 # self.processingHeaderObj.nHeights = 248
149 # self.processingHeaderObj.nHeights = 248
147 # self.systemHeaderObj.nChannels
150 # self.systemHeaderObj.nChannels
148 # else:
151 # else:
149 current_pointer_location = self.fp.tell()
152 current_pointer_location = self.fp.tell()
150 junk = numpy.fromfile(self.fp, self.dtype, self.blocksize)
153 junk = numpy.fromfile(self.fp, self.dtype, self.blocksize)
151
154
152 try:
155 try:
153 junk = junk.reshape((self.processingHeaderObj.profilesPerBlock,
156 junk = junk.reshape((self.processingHeaderObj.profilesPerBlock,
154 self.processingHeaderObj.nHeights, self.systemHeaderObj.nChannels))
157 self.processingHeaderObj.nHeights, self.systemHeaderObj.nChannels))
155 except:
158 except:
156 # print "The read block (%3d) has not enough data" %self.nReadBlocks
159 # print "The read block (%3d) has not enough data" %self.nReadBlocks
157
160
158 if self.waitDataBlock(pointer_location=current_pointer_location):
161 if self.waitDataBlock(pointer_location=current_pointer_location):
159 junk = numpy.fromfile(self.fp, self.dtype, self.blocksize)
162 junk = numpy.fromfile(self.fp, self.dtype, self.blocksize)
160 junk = junk.reshape((self.processingHeaderObj.profilesPerBlock,
163 junk = junk.reshape((self.processingHeaderObj.profilesPerBlock,
161 self.processingHeaderObj.nHeights, self.systemHeaderObj.nChannels))
164 self.processingHeaderObj.nHeights, self.systemHeaderObj.nChannels))
162 # return 0
165 # return 0
163
166
164 # Dimensions : nChannels, nProfiles, nSamples
167 # Dimensions : nChannels, nProfiles, nSamples
165
168
166 junk = numpy.transpose(junk, (2, 0, 1))
169 junk = numpy.transpose(junk, (2, 0, 1))
167 self.datablock = junk['real'] + junk['imag'] * 1j
170 self.datablock = junk['real'] + junk['imag'] * 1j
168
171
169 self.profileIndex = 0
172 self.profileIndex = 0
170
173
171 self.flagIsNewFile = 0
174 self.flagIsNewFile = 0
172 self.flagIsNewBlock = 1
175 self.flagIsNewBlock = 1
173
176
174 self.nTotalBlocks += 1
177 self.nTotalBlocks += 1
175 self.nReadBlocks += 1
178 self.nReadBlocks += 1
176
179
177 return 1
180 return 1
178
181
179 def getFirstHeader(self):
182 def getFirstHeader(self):
183 ##print("6--OKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK")
180
184
181 self.getBasicHeader()
185 self.getBasicHeader()
182
186
183 self.dataOut.processingHeaderObj = self.processingHeaderObj.copy()
187 self.dataOut.processingHeaderObj = self.processingHeaderObj.copy()
184
188
185 self.dataOut.systemHeaderObj = self.systemHeaderObj.copy()
189 self.dataOut.systemHeaderObj = self.systemHeaderObj.copy()
186
190
187 self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy()
191 self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy()
188
192
193 #self.dataOut.ippSeconds_general=self.radarControllerHeaderObj.ippSeconds
194 #print(self.nTxs)
189 if self.nTxs > 1:
195 if self.nTxs > 1:
196 #print(self.radarControllerHeaderObj.ippSeconds)
190 self.dataOut.radarControllerHeaderObj.ippSeconds = self.radarControllerHeaderObj.ippSeconds / self.nTxs
197 self.dataOut.radarControllerHeaderObj.ippSeconds = self.radarControllerHeaderObj.ippSeconds / self.nTxs
198 #print(self.radarControllerHeaderObj.ippSeconds)
191 # Time interval and code are propierties of dataOut. Its value depends of radarControllerHeaderObj.
199 # Time interval and code are propierties of dataOut. Its value depends of radarControllerHeaderObj.
192
200
193 # self.dataOut.timeInterval = self.radarControllerHeaderObj.ippSeconds * self.processingHeaderObj.nCohInt
201 # self.dataOut.timeInterval = self.radarControllerHeaderObj.ippSeconds * self.processingHeaderObj.nCohInt
194 #
202 #
195 # if self.radarControllerHeaderObj.code is not None:
203 # if self.radarControllerHeaderObj.code is not None:
196 #
204 #
197 # self.dataOut.nCode = self.radarControllerHeaderObj.nCode
205 # self.dataOut.nCode = self.radarControllerHeaderObj.nCode
198 #
206 #
199 # self.dataOut.nBaud = self.radarControllerHeaderObj.nBaud
207 # self.dataOut.nBaud = self.radarControllerHeaderObj.nBaud
200 #
208 #
201 # self.dataOut.code = self.radarControllerHeaderObj.code
209 # self.dataOut.code = self.radarControllerHeaderObj.code
202
210
203 self.dataOut.dtype = self.dtype
211 self.dataOut.dtype = self.dtype
204
212
205 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock
213 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock
206
214
207 self.dataOut.heightList = numpy.arange(
215 self.dataOut.heightList = numpy.arange(
208 self.processingHeaderObj.nHeights) * self.processingHeaderObj.deltaHeight + self.processingHeaderObj.firstHeight
216 self.processingHeaderObj.nHeights) * self.processingHeaderObj.deltaHeight + self.processingHeaderObj.firstHeight
209
217
210 self.dataOut.channelList = list(range(self.systemHeaderObj.nChannels))
218 self.dataOut.channelList = list(range(self.systemHeaderObj.nChannels))
211
219
212 self.dataOut.nCohInt = self.processingHeaderObj.nCohInt
220 self.dataOut.nCohInt = self.processingHeaderObj.nCohInt
213
221
214 # asumo q la data no esta decodificada
222 # asumo q la data no esta decodificada
215 self.dataOut.flagDecodeData = self.processingHeaderObj.flag_decode
223 self.dataOut.flagDecodeData = self.processingHeaderObj.flag_decode
216
224
217 # asumo q la data no esta sin flip
225 # asumo q la data no esta sin flip
218 self.dataOut.flagDeflipData = self.processingHeaderObj.flag_deflip
226 self.dataOut.flagDeflipData = self.processingHeaderObj.flag_deflip
219
227
220 self.dataOut.flagShiftFFT = self.processingHeaderObj.shif_fft
228 self.dataOut.flagShiftFFT = self.processingHeaderObj.shif_fft
221
229
222 def reshapeData(self):
230 def reshapeData(self):
223
231 ##print("7--OKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK")
224 if self.nTxs < 0:
232 if self.nTxs < 0:
225 return
233 return
226
234
227 if self.nTxs == 1:
235 if self.nTxs == 1:
228 return
236 return
229
237
230 if self.nTxs < 1 and self.processingHeaderObj.profilesPerBlock % (1. / self.nTxs) != 0:
238 if self.nTxs < 1 and self.processingHeaderObj.profilesPerBlock % (1. / self.nTxs) != 0:
231 raise ValueError("1./nTxs (=%f), should be a multiple of nProfiles (=%d)" % (
239 raise ValueError("1./nTxs (=%f), should be a multiple of nProfiles (=%d)" % (
232 1. / self.nTxs, self.processingHeaderObj.profilesPerBlock))
240 1. / self.nTxs, self.processingHeaderObj.profilesPerBlock))
233
241
234 if self.nTxs > 1 and self.processingHeaderObj.nHeights % self.nTxs != 0:
242 if self.nTxs > 1 and self.processingHeaderObj.nHeights % self.nTxs != 0:
235 raise ValueError("nTxs (=%d), should be a multiple of nHeights (=%d)" % (
243 raise ValueError("nTxs (=%d), should be a multiple of nHeights (=%d)" % (
236 self.nTxs, self.processingHeaderObj.nHeights))
244 self.nTxs, self.processingHeaderObj.nHeights))
237
245
238 self.datablock = self.datablock.reshape(
246 self.datablock = self.datablock.reshape(
239 (self.systemHeaderObj.nChannels, self.processingHeaderObj.profilesPerBlock * self.nTxs, int(self.processingHeaderObj.nHeights / self.nTxs)))
247 (self.systemHeaderObj.nChannels, self.processingHeaderObj.profilesPerBlock * self.nTxs, int(self.processingHeaderObj.nHeights / self.nTxs)))
240
248
241 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock * self.nTxs
249 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock * self.nTxs
242 self.dataOut.heightList = numpy.arange(self.processingHeaderObj.nHeights / self.nTxs) * \
250 self.dataOut.heightList = numpy.arange(self.processingHeaderObj.nHeights / self.nTxs) * \
243 self.processingHeaderObj.deltaHeight + self.processingHeaderObj.firstHeight
251 self.processingHeaderObj.deltaHeight + self.processingHeaderObj.firstHeight
244 self.dataOut.radarControllerHeaderObj.ippSeconds = self.radarControllerHeaderObj.ippSeconds / self.nTxs
252 self.dataOut.radarControllerHeaderObj.ippSeconds = self.radarControllerHeaderObj.ippSeconds / self.nTxs
245
253
246 return
254 return
247
255
248 def readFirstHeaderFromServer(self):
256 def readFirstHeaderFromServer(self):
249
257
258 ##print("8--OKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK")
250 self.getFirstHeader()
259 self.getFirstHeader()
251
260
252 self.firstHeaderSize = self.basicHeaderObj.size
261 self.firstHeaderSize = self.basicHeaderObj.size
253
262
254 datatype = int(numpy.log2((self.processingHeaderObj.processFlags &
263 datatype = int(numpy.log2((self.processingHeaderObj.processFlags &
255 PROCFLAG.DATATYPE_MASK)) - numpy.log2(PROCFLAG.DATATYPE_CHAR))
264 PROCFLAG.DATATYPE_MASK)) - numpy.log2(PROCFLAG.DATATYPE_CHAR))
256 if datatype == 0:
265 if datatype == 0:
257 datatype_str = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
266 datatype_str = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
258 elif datatype == 1:
267 elif datatype == 1:
259 datatype_str = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
268 datatype_str = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
260 elif datatype == 2:
269 elif datatype == 2:
261 datatype_str = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
270 datatype_str = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
262 elif datatype == 3:
271 elif datatype == 3:
263 datatype_str = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
272 datatype_str = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
264 elif datatype == 4:
273 elif datatype == 4:
265 datatype_str = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
274 datatype_str = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
266 elif datatype == 5:
275 elif datatype == 5:
267 datatype_str = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
276 datatype_str = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
268 else:
277 else:
269 raise ValueError('Data type was not defined')
278 raise ValueError('Data type was not defined')
270
279
271 self.dtype = datatype_str
280 self.dtype = datatype_str
272 #self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
281 #self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
273 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + \
282 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + \
274 self.firstHeaderSize + self.basicHeaderSize * \
283 self.firstHeaderSize + self.basicHeaderSize * \
275 (self.processingHeaderObj.dataBlocksPerFile - 1)
284 (self.processingHeaderObj.dataBlocksPerFile - 1)
276 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
285 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
277 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
286 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
278 self.getBlockDimension()
287 self.getBlockDimension()
279
288
280 def getFromServer(self):
289 def getFromServer(self):
290 ##print("9--OKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK")
281 self.flagDiscontinuousBlock = 0
291 self.flagDiscontinuousBlock = 0
282 self.profileIndex = 0
292 self.profileIndex = 0
283 self.flagIsNewBlock = 1
293 self.flagIsNewBlock = 1
284 self.dataOut.flagNoData = False
294 self.dataOut.flagNoData = False
285 self.nTotalBlocks += 1
295 self.nTotalBlocks += 1
286 self.nReadBlocks += 1
296 self.nReadBlocks += 1
287 self.blockPointer = 0
297 self.blockPointer = 0
288
298
289 block = self.receiver.recv()
299 block = self.receiver.recv()
290
300
291 self.basicHeaderObj.read(block[self.blockPointer:])
301 self.basicHeaderObj.read(block[self.blockPointer:])
292 self.blockPointer += self.basicHeaderObj.length
302 self.blockPointer += self.basicHeaderObj.length
293 self.systemHeaderObj.read(block[self.blockPointer:])
303 self.systemHeaderObj.read(block[self.blockPointer:])
294 self.blockPointer += self.systemHeaderObj.length
304 self.blockPointer += self.systemHeaderObj.length
295 self.radarControllerHeaderObj.read(block[self.blockPointer:])
305 self.radarControllerHeaderObj.read(block[self.blockPointer:])
296 self.blockPointer += self.radarControllerHeaderObj.length
306 self.blockPointer += self.radarControllerHeaderObj.length
297 self.processingHeaderObj.read(block[self.blockPointer:])
307 self.processingHeaderObj.read(block[self.blockPointer:])
298 self.blockPointer += self.processingHeaderObj.length
308 self.blockPointer += self.processingHeaderObj.length
299 self.readFirstHeaderFromServer()
309 self.readFirstHeaderFromServer()
300
310
301 timestamp = self.basicHeaderObj.get_datatime()
311 timestamp = self.basicHeaderObj.get_datatime()
302 print('[Reading] - Block {} - {}'.format(self.nTotalBlocks, timestamp))
312 print('[Reading] - Block {} - {}'.format(self.nTotalBlocks, timestamp))
303 current_pointer_location = self.blockPointer
313 current_pointer_location = self.blockPointer
304 junk = numpy.fromstring(
314 junk = numpy.fromstring(
305 block[self.blockPointer:], self.dtype, self.blocksize)
315 block[self.blockPointer:], self.dtype, self.blocksize)
306
316
307 try:
317 try:
308 junk = junk.reshape((self.processingHeaderObj.profilesPerBlock,
318 junk = junk.reshape((self.processingHeaderObj.profilesPerBlock,
309 self.processingHeaderObj.nHeights, self.systemHeaderObj.nChannels))
319 self.processingHeaderObj.nHeights, self.systemHeaderObj.nChannels))
310 except:
320 except:
311 # print "The read block (%3d) has not enough data" %self.nReadBlocks
321 # print "The read block (%3d) has not enough data" %self.nReadBlocks
312 if self.waitDataBlock(pointer_location=current_pointer_location):
322 if self.waitDataBlock(pointer_location=current_pointer_location):
313 junk = numpy.fromstring(
323 junk = numpy.fromstring(
314 block[self.blockPointer:], self.dtype, self.blocksize)
324 block[self.blockPointer:], self.dtype, self.blocksize)
315 junk = junk.reshape((self.processingHeaderObj.profilesPerBlock,
325 junk = junk.reshape((self.processingHeaderObj.profilesPerBlock,
316 self.processingHeaderObj.nHeights, self.systemHeaderObj.nChannels))
326 self.processingHeaderObj.nHeights, self.systemHeaderObj.nChannels))
317 # return 0
327 # return 0
318
328
319 # Dimensions : nChannels, nProfiles, nSamples
329 # Dimensions : nChannels, nProfiles, nSamples
320
330
321 junk = numpy.transpose(junk, (2, 0, 1))
331 junk = numpy.transpose(junk, (2, 0, 1))
322 self.datablock = junk['real'] + junk['imag'] * 1j
332 self.datablock = junk['real'] + junk['imag'] * 1j
323 self.profileIndex = 0
333 self.profileIndex = 0
324 if self.selBlocksize == None:
334 if self.selBlocksize == None:
325 self.selBlocksize = self.dataOut.nProfiles
335 self.selBlocksize = self.dataOut.nProfiles
326 if self.selBlocktime != None:
336 if self.selBlocktime != None:
327 if self.dataOut.nCohInt is not None:
337 if self.dataOut.nCohInt is not None:
328 nCohInt = self.dataOut.nCohInt
338 nCohInt = self.dataOut.nCohInt
329 else:
339 else:
330 nCohInt = 1
340 nCohInt = 1
331 self.selBlocksize = int(self.dataOut.nProfiles * round(self.selBlocktime / (
341 self.selBlocksize = int(self.dataOut.nProfiles * round(self.selBlocktime / (
332 nCohInt * self.dataOut.ippSeconds * self.dataOut.nProfiles)))
342 nCohInt * self.dataOut.ippSeconds * self.dataOut.nProfiles)))
333 self.dataOut.data = self.datablock[:,
343 self.dataOut.data = self.datablock[:,
334 self.profileIndex:self.profileIndex + self.selBlocksize, :]
344 self.profileIndex:self.profileIndex + self.selBlocksize, :]
335 datasize = self.dataOut.data.shape[1]
345 datasize = self.dataOut.data.shape[1]
336 if datasize < self.selBlocksize:
346 if datasize < self.selBlocksize:
337 buffer = numpy.zeros(
347 buffer = numpy.zeros(
338 (self.dataOut.data.shape[0], self.selBlocksize, self.dataOut.data.shape[2]), dtype='complex')
348 (self.dataOut.data.shape[0], self.selBlocksize, self.dataOut.data.shape[2]), dtype='complex')
339 buffer[:, :datasize, :] = self.dataOut.data
349 buffer[:, :datasize, :] = self.dataOut.data
340 self.dataOut.data = buffer
350 self.dataOut.data = buffer
341 self.profileIndex = blockIndex
351 self.profileIndex = blockIndex
342
352
343 self.dataOut.flagDataAsBlock = True
353 self.dataOut.flagDataAsBlock = True
344 self.flagIsNewBlock = 1
354 self.flagIsNewBlock = 1
345 self.dataOut.realtime = self.online
355 self.dataOut.realtime = self.online
346
356
347 return self.dataOut.data
357 return self.dataOut.data
348
358
349 def getData(self):
359 def getData(self):
350 """
360 """
351 getData obtiene una unidad de datos del buffer de lectura, un perfil, y la copia al objeto self.dataOut
361 getData obtiene una unidad de datos del buffer de lectura, un perfil, y la copia al objeto self.dataOut
352 del tipo "Voltage" con todos los parametros asociados a este (metadata). cuando no hay datos
362 del tipo "Voltage" con todos los parametros asociados a este (metadata). cuando no hay datos
353 en el buffer de lectura es necesario hacer una nueva lectura de los bloques de datos usando
363 en el buffer de lectura es necesario hacer una nueva lectura de los bloques de datos usando
354 "readNextBlock"
364 "readNextBlock"
355
365
356 Ademas incrementa el contador del buffer "self.profileIndex" en 1.
366 Ademas incrementa el contador del buffer "self.profileIndex" en 1.
357
367
358 Return:
368 Return:
359
369
360 Si el flag self.getByBlock ha sido seteado el bloque completo es copiado a self.dataOut y el self.profileIndex
370 Si el flag self.getByBlock ha sido seteado el bloque completo es copiado a self.dataOut y el self.profileIndex
361 es igual al total de perfiles leidos desde el archivo.
371 es igual al total de perfiles leidos desde el archivo.
362
372
363 Si self.getByBlock == False:
373 Si self.getByBlock == False:
364
374
365 self.dataOut.data = buffer[:, thisProfile, :]
375 self.dataOut.data = buffer[:, thisProfile, :]
366
376
367 shape = [nChannels, nHeis]
377 shape = [nChannels, nHeis]
368
378
369 Si self.getByBlock == True:
379 Si self.getByBlock == True:
370
380
371 self.dataOut.data = buffer[:, :, :]
381 self.dataOut.data = buffer[:, :, :]
372
382
373 shape = [nChannels, nProfiles, nHeis]
383 shape = [nChannels, nProfiles, nHeis]
374
384
375 Variables afectadas:
385 Variables afectadas:
376 self.dataOut
386 self.dataOut
377 self.profileIndex
387 self.profileIndex
378
388
379 Affected:
389 Affected:
380 self.dataOut
390 self.dataOut
381 self.profileIndex
391 self.profileIndex
382 self.flagDiscontinuousBlock
392 self.flagDiscontinuousBlock
383 self.flagIsNewBlock
393 self.flagIsNewBlock
384 """
394 """
395
396 ##print("10--OKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK")
385 if self.flagNoMoreFiles:
397 if self.flagNoMoreFiles:
386 self.dataOut.flagNoData = True
398 self.dataOut.flagNoData = True
387 return 0
399 return 0
388 self.flagDiscontinuousBlock = 0
400 self.flagDiscontinuousBlock = 0
389 self.flagIsNewBlock = 0
401 self.flagIsNewBlock = 0
390 if self.__hasNotDataInBuffer():
402 if self.__hasNotDataInBuffer():
391 if not(self.readNextBlock()):
403 if not(self.readNextBlock()):
392 return 0
404 return 0
393
405
394 self.getFirstHeader()
406 self.getFirstHeader()
395
407
396 self.reshapeData()
408 self.reshapeData()
397 if self.datablock is None:
409 if self.datablock is None:
398 self.dataOut.flagNoData = True
410 self.dataOut.flagNoData = True
399 return 0
411 return 0
400
412
401 if not self.getByBlock:
413 if not self.getByBlock:
402
414
403 """
415 """
404 Return profile by profile
416 Return profile by profile
405
417
406 If nTxs > 1 then one profile is divided by nTxs and number of total
418 If nTxs > 1 then one profile is divided by nTxs and number of total
407 blocks is increased by nTxs (nProfiles *= nTxs)
419 blocks is increased by nTxs (nProfiles *= nTxs)
408 """
420 """
409 self.dataOut.flagDataAsBlock = False
421 self.dataOut.flagDataAsBlock = False
410 self.dataOut.data = self.datablock[:, self.profileIndex, :]
422 self.dataOut.data = self.datablock[:, self.profileIndex, :]
411 self.dataOut.profileIndex = self.profileIndex
423 self.dataOut.profileIndex = self.profileIndex
412
424
425
413 self.profileIndex += 1
426 self.profileIndex += 1
414
427
415 else:
428 else:
416 """
429 """
417 Return a block
430 Return a block
418 """
431 """
419 if self.selBlocksize == None:
432 if self.selBlocksize == None:
420 self.selBlocksize = self.dataOut.nProfiles
433 self.selBlocksize = self.dataOut.nProfiles
421 if self.selBlocktime != None:
434 if self.selBlocktime != None:
422 if self.dataOut.nCohInt is not None:
435 if self.dataOut.nCohInt is not None:
423 nCohInt = self.dataOut.nCohInt
436 nCohInt = self.dataOut.nCohInt
424 else:
437 else:
425 nCohInt = 1
438 nCohInt = 1
426 self.selBlocksize = int(self.dataOut.nProfiles * round(self.selBlocktime / (
439 self.selBlocksize = int(self.dataOut.nProfiles * round(self.selBlocktime / (
427 nCohInt * self.dataOut.ippSeconds * self.dataOut.nProfiles)))
440 nCohInt * self.dataOut.ippSeconds * self.dataOut.nProfiles)))
428
441
429 self.dataOut.data = self.datablock[:,
442 self.dataOut.data = self.datablock[:,
430 self.profileIndex:self.profileIndex + self.selBlocksize, :]
443 self.profileIndex:self.profileIndex + self.selBlocksize, :]
431 self.profileIndex += self.selBlocksize
444 self.profileIndex += self.selBlocksize
432 datasize = self.dataOut.data.shape[1]
445 datasize = self.dataOut.data.shape[1]
433
446
434 if datasize < self.selBlocksize:
447 if datasize < self.selBlocksize:
435 buffer = numpy.zeros(
448 buffer = numpy.zeros(
436 (self.dataOut.data.shape[0], self.selBlocksize, self.dataOut.data.shape[2]), dtype='complex')
449 (self.dataOut.data.shape[0], self.selBlocksize, self.dataOut.data.shape[2]), dtype='complex')
437 buffer[:, :datasize, :] = self.dataOut.data
450 buffer[:, :datasize, :] = self.dataOut.data
438
451
439 while datasize < self.selBlocksize: # Not enough profiles to fill the block
452 while datasize < self.selBlocksize: # Not enough profiles to fill the block
440 if not(self.readNextBlock()):
453 if not(self.readNextBlock()):
441 return 0
454 return 0
442 self.getFirstHeader()
455 self.getFirstHeader()
443 self.reshapeData()
456 self.reshapeData()
444 if self.datablock is None:
457 if self.datablock is None:
445 self.dataOut.flagNoData = True
458 self.dataOut.flagNoData = True
446 return 0
459 return 0
447 # stack data
460 # stack data
448 blockIndex = self.selBlocksize - datasize
461 blockIndex = self.selBlocksize - datasize
449 datablock1 = self.datablock[:, :blockIndex, :]
462 datablock1 = self.datablock[:, :blockIndex, :]
450
463
451 buffer[:, datasize:datasize +
464 buffer[:, datasize:datasize +
452 datablock1.shape[1], :] = datablock1
465 datablock1.shape[1], :] = datablock1
453 datasize += datablock1.shape[1]
466 datasize += datablock1.shape[1]
454
467
455 self.dataOut.data = buffer
468 self.dataOut.data = buffer
456 self.profileIndex = blockIndex
469 self.profileIndex = blockIndex
457
470
458 self.dataOut.flagDataAsBlock = True
471 self.dataOut.flagDataAsBlock = True
459 self.dataOut.nProfiles = self.dataOut.data.shape[1]
472 self.dataOut.nProfiles = self.dataOut.data.shape[1]
460
473
474 #######################DP#######################
475 self.dataOut.CurrentBlock=self.nReadBlocks
476 self.dataOut.LastBlock=self.processingHeaderObj.dataBlocksPerFile
477 #######################DP#######################
461 self.dataOut.flagNoData = False
478 self.dataOut.flagNoData = False
462
479
463 self.getBasicHeader()
480 #self.getBasicHeader()
464
481
465 self.dataOut.realtime = self.online
482 self.dataOut.realtime = self.online
466
483
467 return self.dataOut.data
484 return self.dataOut.data
468
485
469
486
470 @MPDecorator
487 @MPDecorator
471 class VoltageWriter(JRODataWriter, Operation):
488 class VoltageWriter(JRODataWriter, Operation):
472 """
489 """
473 Esta clase permite escribir datos de voltajes a archivos procesados (.r). La escritura
490 Esta clase permite escribir datos de voltajes a archivos procesados (.r). La escritura
474 de los datos siempre se realiza por bloques.
491 de los datos siempre se realiza por bloques.
475 """
492 """
476
493
477 ext = ".r"
494 ext = ".r"
478
495
479 optchar = "D"
496 optchar = "D"
480
497
481 shapeBuffer = None
498 shapeBuffer = None
482
499
483 def __init__(self):#, **kwargs):
500 def __init__(self):#, **kwargs):
484 """
501 """
485 Inicializador de la clase VoltageWriter para la escritura de datos de espectros.
502 Inicializador de la clase VoltageWriter para la escritura de datos de espectros.
486
503
487 Affected:
504 Affected:
488 self.dataOut
505 self.dataOut
489
506
490 Return: None
507 Return: None
491 """
508 """
492 Operation.__init__(self)#, **kwargs)
509 Operation.__init__(self)#, **kwargs)
493
510
494 self.nTotalBlocks = 0
511 self.nTotalBlocks = 0
495
512
496 self.profileIndex = 0
513 self.profileIndex = 0
497
514
498 self.isConfig = False
515 self.isConfig = False
499
516
500 self.fp = None
517 self.fp = None
501
518
502 self.flagIsNewFile = 1
519 self.flagIsNewFile = 1
503
520
504 self.blockIndex = 0
521 self.blockIndex = 0
505
522
506 self.flagIsNewBlock = 0
523 self.flagIsNewBlock = 0
507
524
508 self.setFile = None
525 self.setFile = None
509
526
510 self.dtype = None
527 self.dtype = None
511
528
512 self.path = None
529 self.path = None
513
530
514 self.filename = None
531 self.filename = None
515
532
516 self.basicHeaderObj = BasicHeader(LOCALTIME)
533 self.basicHeaderObj = BasicHeader(LOCALTIME)
517
534
518 self.systemHeaderObj = SystemHeader()
535 self.systemHeaderObj = SystemHeader()
519
536
520 self.radarControllerHeaderObj = RadarControllerHeader()
537 self.radarControllerHeaderObj = RadarControllerHeader()
521
538
522 self.processingHeaderObj = ProcessingHeader()
539 self.processingHeaderObj = ProcessingHeader()
523
540
524 def hasAllDataInBuffer(self):
541 def hasAllDataInBuffer(self):
525 if self.profileIndex >= self.processingHeaderObj.profilesPerBlock:
542 if self.profileIndex >= self.processingHeaderObj.profilesPerBlock:
526 return 1
543 return 1
527 return 0
544 return 0
528
545
529 def setBlockDimension(self):
546 def setBlockDimension(self):
530 """
547 """
531 Obtiene las formas dimensionales del los subbloques de datos que componen un bloque
548 Obtiene las formas dimensionales del los subbloques de datos que componen un bloque
532
549
533 Affected:
550 Affected:
534 self.shape_spc_Buffer
551 self.shape_spc_Buffer
535 self.shape_cspc_Buffer
552 self.shape_cspc_Buffer
536 self.shape_dc_Buffer
553 self.shape_dc_Buffer
537
554
538 Return: None
555 Return: None
539 """
556 """
540 self.shapeBuffer = (self.processingHeaderObj.profilesPerBlock,
557 self.shapeBuffer = (self.processingHeaderObj.profilesPerBlock,
541 self.processingHeaderObj.nHeights,
558 self.processingHeaderObj.nHeights,
542 self.systemHeaderObj.nChannels)
559 self.systemHeaderObj.nChannels)
543
560
544 self.datablock = numpy.zeros((self.systemHeaderObj.nChannels,
561 self.datablock = numpy.zeros((self.systemHeaderObj.nChannels,
545 self.processingHeaderObj.profilesPerBlock,
562 self.processingHeaderObj.profilesPerBlock,
546 self.processingHeaderObj.nHeights),
563 self.processingHeaderObj.nHeights),
547 dtype=numpy.dtype('complex64'))
564 dtype=numpy.dtype('complex64'))
548
565
549 def writeBlock(self):
566 def writeBlock(self):
550 """
567 """
551 Escribe el buffer en el file designado
568 Escribe el buffer en el file designado
552
569
553 Affected:
570 Affected:
554 self.profileIndex
571 self.profileIndex
555 self.flagIsNewFile
572 self.flagIsNewFile
556 self.flagIsNewBlock
573 self.flagIsNewBlock
557 self.nTotalBlocks
574 self.nTotalBlocks
558 self.blockIndex
575 self.blockIndex
559
576
560 Return: None
577 Return: None
561 """
578 """
562 data = numpy.zeros(self.shapeBuffer, self.dtype)
579 data = numpy.zeros(self.shapeBuffer, self.dtype)
563
580
564 junk = numpy.transpose(self.datablock, (1, 2, 0))
581 junk = numpy.transpose(self.datablock, (1, 2, 0))
565
582
566 data['real'] = junk.real
583 data['real'] = junk.real
567 data['imag'] = junk.imag
584 data['imag'] = junk.imag
568
585
569 data = data.reshape((-1))
586 data = data.reshape((-1))
570
587
571 data.tofile(self.fp)
588 data.tofile(self.fp)
572
589
573 self.datablock.fill(0)
590 self.datablock.fill(0)
574
591
575 self.profileIndex = 0
592 self.profileIndex = 0
576 self.flagIsNewFile = 0
593 self.flagIsNewFile = 0
577 self.flagIsNewBlock = 1
594 self.flagIsNewBlock = 1
578
595
579 self.blockIndex += 1
596 self.blockIndex += 1
580 self.nTotalBlocks += 1
597 self.nTotalBlocks += 1
581
598
582 # print "[Writing] Block = %04d" %self.blockIndex
599 # print "[Writing] Block = %04d" %self.blockIndex
583
600
584 def putData(self):
601 def putData(self):
585 """
602 """
586 Setea un bloque de datos y luego los escribe en un file
603 Setea un bloque de datos y luego los escribe en un file
587
604
588 Affected:
605 Affected:
589 self.flagIsNewBlock
606 self.flagIsNewBlock
590 self.profileIndex
607 self.profileIndex
591
608
592 Return:
609 Return:
593 0 : Si no hay data o no hay mas files que puedan escribirse
610 0 : Si no hay data o no hay mas files que puedan escribirse
594 1 : Si se escribio la data de un bloque en un file
611 1 : Si se escribio la data de un bloque en un file
595 """
612 """
596 if self.dataOut.flagNoData:
613 if self.dataOut.flagNoData:
597 return 0
614 return 0
598
615
599 self.flagIsNewBlock = 0
616 self.flagIsNewBlock = 0
600
617
601 if self.dataOut.flagDiscontinuousBlock:
618 if self.dataOut.flagDiscontinuousBlock:
602 self.datablock.fill(0)
619 self.datablock.fill(0)
603 self.profileIndex = 0
620 self.profileIndex = 0
604 self.setNextFile()
621 self.setNextFile()
605
622
606 if self.profileIndex == 0:
623 if self.profileIndex == 0:
607 self.setBasicHeader()
624 self.setBasicHeader()
608
625
609 self.datablock[:, self.profileIndex, :] = self.dataOut.data
626 self.datablock[:, self.profileIndex, :] = self.dataOut.data
610
627
611 self.profileIndex += 1
628 self.profileIndex += 1
612
629
613 if self.hasAllDataInBuffer():
630 if self.hasAllDataInBuffer():
614 # if self.flagIsNewFile:
631 # if self.flagIsNewFile:
615 self.writeNextBlock()
632 self.writeNextBlock()
616 # self.setFirstHeader()
633 # self.setFirstHeader()
617
634
618 return 1
635 return 1
619
636
620 def __getBlockSize(self):
637 def __getBlockSize(self):
621 '''
638 '''
622 Este metodos determina el cantidad de bytes para un bloque de datos de tipo Voltage
639 Este metodos determina el cantidad de bytes para un bloque de datos de tipo Voltage
623 '''
640 '''
624
641
625 dtype_width = self.getDtypeWidth()
642 dtype_width = self.getDtypeWidth()
626
643
627 blocksize = int(self.dataOut.nHeights * self.dataOut.nChannels *
644 blocksize = int(self.dataOut.nHeights * self.dataOut.nChannels *
628 self.profilesPerBlock * dtype_width * 2)
645 self.profilesPerBlock * dtype_width * 2)
629
646
630 return blocksize
647 return blocksize
631
648
632 def setFirstHeader(self):
649 def setFirstHeader(self):
633 """
650 """
634 Obtiene una copia del First Header
651 Obtiene una copia del First Header
635
652
636 Affected:
653 Affected:
637 self.systemHeaderObj
654 self.systemHeaderObj
638 self.radarControllerHeaderObj
655 self.radarControllerHeaderObj
639 self.dtype
656 self.dtype
640
657
641 Return:
658 Return:
642 None
659 None
643 """
660 """
644
661
645 self.systemHeaderObj = self.dataOut.systemHeaderObj.copy()
662 self.systemHeaderObj = self.dataOut.systemHeaderObj.copy()
646 self.systemHeaderObj.nChannels = self.dataOut.nChannels
663 self.systemHeaderObj.nChannels = self.dataOut.nChannels
647 self.radarControllerHeaderObj = self.dataOut.radarControllerHeaderObj.copy()
664 self.radarControllerHeaderObj = self.dataOut.radarControllerHeaderObj.copy()
648
665
649 self.processingHeaderObj.dtype = 0 # Voltage
666 self.processingHeaderObj.dtype = 0 # Voltage
650 self.processingHeaderObj.blockSize = self.__getBlockSize()
667 self.processingHeaderObj.blockSize = self.__getBlockSize()
651 self.processingHeaderObj.profilesPerBlock = self.profilesPerBlock
668 self.processingHeaderObj.profilesPerBlock = self.profilesPerBlock
652 self.processingHeaderObj.dataBlocksPerFile = self.blocksPerFile
669 self.processingHeaderObj.dataBlocksPerFile = self.blocksPerFile
653 # podria ser 1 o self.dataOut.processingHeaderObj.nWindows
670 # podria ser 1 o self.dataOut.processingHeaderObj.nWindows
654 self.processingHeaderObj.nWindows = 1
671 self.processingHeaderObj.nWindows = 1
655 self.processingHeaderObj.nCohInt = self.dataOut.nCohInt
672 self.processingHeaderObj.nCohInt = self.dataOut.nCohInt
656 # Cuando la data de origen es de tipo Voltage
673 # Cuando la data de origen es de tipo Voltage
657 self.processingHeaderObj.nIncohInt = 1
674 self.processingHeaderObj.nIncohInt = 1
658 # Cuando la data de origen es de tipo Voltage
675 # Cuando la data de origen es de tipo Voltage
659 self.processingHeaderObj.totalSpectra = 0
676 self.processingHeaderObj.totalSpectra = 0
660
677
661 if self.dataOut.code is not None:
678 if self.dataOut.code is not None:
662 self.processingHeaderObj.code = self.dataOut.code
679 self.processingHeaderObj.code = self.dataOut.code
663 self.processingHeaderObj.nCode = self.dataOut.nCode
680 self.processingHeaderObj.nCode = self.dataOut.nCode
664 self.processingHeaderObj.nBaud = self.dataOut.nBaud
681 self.processingHeaderObj.nBaud = self.dataOut.nBaud
665
682
666 if self.processingHeaderObj.nWindows != 0:
683 if self.processingHeaderObj.nWindows != 0:
667 self.processingHeaderObj.firstHeight = self.dataOut.heightList[0]
684 self.processingHeaderObj.firstHeight = self.dataOut.heightList[0]
668 self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - \
685 self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - \
669 self.dataOut.heightList[0]
686 self.dataOut.heightList[0]
670 self.processingHeaderObj.nHeights = self.dataOut.nHeights
687 self.processingHeaderObj.nHeights = self.dataOut.nHeights
671 self.processingHeaderObj.samplesWin = self.dataOut.nHeights
688 self.processingHeaderObj.samplesWin = self.dataOut.nHeights
672
689
673 self.processingHeaderObj.processFlags = self.getProcessFlags()
690 self.processingHeaderObj.processFlags = self.getProcessFlags()
674
691
675 self.setBasicHeader()
692 self.setBasicHeader()
676 No newline at end of file
@@ -1,16 +1,22
1 '''
1 '''
2
2
3 $Author: murco $
3 $Author: murco $
4 $Id: Processor.py 1 2012-11-12 18:56:07Z murco $
4 $Id: Processor.py 1 2012-11-12 18:56:07Z murco $
5 '''
5 '''
6
6
7 from .jroproc_voltage import *
7 from .jroproc_voltage import *
8 from .jroproc_spectra import *
8 from .jroproc_spectra import *
9 from .jroproc_heispectra import *
9 from .jroproc_heispectra import *
10 from .jroproc_amisr import *
10 from .jroproc_amisr import *
11 from .jroproc_correlation import *
11 from .jroproc_correlation import *
12 from .jroproc_parameters import *
12 from .jroproc_parameters import *
13 from .jroproc_spectra_lags import *
13 from .jroproc_spectra_lags import *
14 from .jroproc_spectra_acf import *
14 from .jroproc_spectra_acf import *
15 from .bltrproc_parameters import *
15 from .bltrproc_parameters import *
16 from .pxproc_parameters import *
16 from .pxproc_parameters import *
17
18
19 ###########DP###########
20 from .jroproc_voltage_lags import *
21 ###########DP###########
22 from .jroproc_spectra_lags_faraday import *
1 NO CONTENT: modified file
NO CONTENT: modified file
1 NO CONTENT: modified file chmod 100755 => 100644
NO CONTENT: modified file chmod 100755 => 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now