##// END OF EJS Templates
Se cambió los títulos en SpectraPlot y RTIPlot para que muestre los canales reales luego de la operación selectChannels
joabAM -
r1386:029f5a79c540
parent child
Show More
@@ -1,702 +1,711
1 1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 2 # All rights reserved.
3 3 #
4 4 # Distributed under the terms of the BSD 3-clause license.
5 5 """Classes to plot Spectra data
6 6
7 7 """
8 8
9 9 import os
10 10 import numpy
11 11
12 12 from schainpy.model.graphics.jroplot_base import Plot, plt, log
13 13
14 14
15 15 class SpectraPlot(Plot):
16 16 '''
17 17 Plot for Spectra data
18 18 '''
19 19
20 20 CODE = 'spc'
21 21 colormap = 'jet'
22 22 plot_type = 'pcolor'
23 23 buffering = False
24 channelList = None
24 25
25 26 def setup(self):
26 27 self.nplots = len(self.data.channels)
27 28 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
28 29 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
29 30 self.height = 2.6 * self.nrows
31
30 32 self.cb_label = 'dB'
31 33 if self.showprofile:
32 34 self.width = 4 * self.ncols
33 35 else:
34 36 self.width = 3.5 * self.ncols
35 37 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
36 38 self.ylabel = 'Range [km]'
37 39
38 40 def update(self, dataOut):
39
41 if self.channelList == None:
42 self.channelList = dataOut.channelList
40 43 data = {}
41 44 meta = {}
42 45 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
43 46 data['spc'] = spc
44 47 data['rti'] = dataOut.getPower()
45 48 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
46 49 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
47 50 if self.CODE == 'spc_moments':
48 51 data['moments'] = dataOut.moments
49
50 return data, meta
51
52
53 return data, meta
54
52 55 def plot(self):
53 56 if self.xaxis == "frequency":
54 57 x = self.data.xrange[0]
55 58 self.xlabel = "Frequency (kHz)"
56 59 elif self.xaxis == "time":
57 60 x = self.data.xrange[1]
58 61 self.xlabel = "Time (ms)"
59 62 else:
60 63 x = self.data.xrange[2]
61 64 self.xlabel = "Velocity (m/s)"
62 65
63 66 if self.CODE == 'spc_moments':
64 67 x = self.data.xrange[2]
65 68 self.xlabel = "Velocity (m/s)"
66 69
67 70 self.titles = []
68 71
69 72 y = self.data.yrange
70 73 self.y = y
71 74
72 75 data = self.data[-1]
73 76 z = data['spc']
74 77
75 78 for n, ax in enumerate(self.axes):
76 79 noise = data['noise'][n]
77 80 if self.CODE == 'spc_moments':
78 81 mean = data['moments'][n, 1]
79 82 if ax.firsttime:
80 83 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
81 84 self.xmin = self.xmin if self.xmin else -self.xmax
82 85 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
83 86 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
84 87 ax.plt = ax.pcolormesh(x, y, z[n].T,
85 88 vmin=self.zmin,
86 89 vmax=self.zmax,
87 90 cmap=plt.get_cmap(self.colormap)
88 91 )
89 92
90 93 if self.showprofile:
91 94 ax.plt_profile = self.pf_axes[n].plot(
92 95 data['rti'][n], y)[0]
93 96 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
94 97 color="k", linestyle="dashed", lw=1)[0]
95 98 if self.CODE == 'spc_moments':
96 99 ax.plt_mean = ax.plot(mean, y, color='k')[0]
97 100 else:
98 101 ax.plt.set_array(z[n].T.ravel())
99 102 if self.showprofile:
100 103 ax.plt_profile.set_data(data['rti'][n], y)
101 104 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
102 105 if self.CODE == 'spc_moments':
103 106 ax.plt_mean.set_data(mean, y)
104 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
107 self.titles.append('CH {}: {:3.2f}dB'.format(self.channelList[n], noise))
105 108
106 109
107 110 class CrossSpectraPlot(Plot):
108 111
109 112 CODE = 'cspc'
110 113 colormap = 'jet'
111 114 plot_type = 'pcolor'
112 115 zmin_coh = None
113 116 zmax_coh = None
114 117 zmin_phase = None
115 118 zmax_phase = None
116 119
117 120 def setup(self):
118 121
119 122 self.ncols = 4
120 123 self.nplots = len(self.data.pairs) * 2
121 124 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
122 125 self.width = 3.1 * self.ncols
123 126 self.height = 2.6 * self.nrows
124 127 self.ylabel = 'Range [km]'
125 128 self.showprofile = False
126 129 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
127 130
128 131 def update(self, dataOut):
129 132
130 133 data = {}
131 134 meta = {}
132 135
133 136 spc = dataOut.data_spc
134 137 cspc = dataOut.data_cspc
135 138 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
136 139 meta['pairs'] = dataOut.pairsList
137 140
138 141 tmp = []
139 142
140 143 for n, pair in enumerate(meta['pairs']):
141 144 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
142 145 coh = numpy.abs(out)
143 146 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
144 147 tmp.append(coh)
145 148 tmp.append(phase)
146 149
147 150 data['cspc'] = numpy.array(tmp)
148 151
149 return data, meta
150
152 return data, meta
153
151 154 def plot(self):
152 155
153 156 if self.xaxis == "frequency":
154 157 x = self.data.xrange[0]
155 158 self.xlabel = "Frequency (kHz)"
156 159 elif self.xaxis == "time":
157 160 x = self.data.xrange[1]
158 161 self.xlabel = "Time (ms)"
159 162 else:
160 163 x = self.data.xrange[2]
161 164 self.xlabel = "Velocity (m/s)"
162
165
163 166 self.titles = []
164 167
165 168 y = self.data.yrange
166 169 self.y = y
167 170
168 171 data = self.data[-1]
169 172 cspc = data['cspc']
170 173
171 174 for n in range(len(self.data.pairs)):
172 175 pair = self.data.pairs[n]
173 176 coh = cspc[n*2]
174 177 phase = cspc[n*2+1]
175 178 ax = self.axes[2 * n]
176 179 if ax.firsttime:
177 180 ax.plt = ax.pcolormesh(x, y, coh.T,
178 181 vmin=0,
179 182 vmax=1,
180 183 cmap=plt.get_cmap(self.colormap_coh)
181 184 )
182 185 else:
183 186 ax.plt.set_array(coh.T.ravel())
184 187 self.titles.append(
185 188 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
186
189
187 190 ax = self.axes[2 * n + 1]
188 191 if ax.firsttime:
189 192 ax.plt = ax.pcolormesh(x, y, phase.T,
190 193 vmin=-180,
191 194 vmax=180,
192 cmap=plt.get_cmap(self.colormap_phase)
195 cmap=plt.get_cmap(self.colormap_phase)
193 196 )
194 197 else:
195 198 ax.plt.set_array(phase.T.ravel())
196 199 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
197 200
198 201
199 202 class RTIPlot(Plot):
200 203 '''
201 204 Plot for RTI data
202 205 '''
203 206
204 207 CODE = 'rti'
205 208 colormap = 'jet'
206 209 plot_type = 'pcolorbuffer'
210 titles = None
211 channelList = None
207 212
208 213 def setup(self):
209 214 self.xaxis = 'time'
210 215 self.ncols = 1
211 216 self.nrows = len(self.data.channels)
212 217 self.nplots = len(self.data.channels)
213 218 self.ylabel = 'Range [km]'
214 219 self.xlabel = 'Time'
215 220 self.cb_label = 'dB'
216 221 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95})
217 222 self.titles = ['{} Channel {}'.format(
218 self.CODE.upper(), x) for x in range(self.nrows)]
223 self.CODE.upper(), x) for x in range(self.nplots)]
219 224
220 225 def update(self, dataOut):
221
226 if self.channelList == None:
227 self.channelList = dataOut.channelList
222 228 data = {}
223 229 meta = {}
224 230 data['rti'] = dataOut.getPower()
225 231 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
226 232
227 233 return data, meta
228 234
229 235 def plot(self):
230 236 self.x = self.data.times
231 237 self.y = self.data.yrange
232 238 self.z = self.data[self.CODE]
233 239 self.z = numpy.ma.masked_invalid(self.z)
240 if self.channelList != None:
241 self.titles = ['{} Channel {}'.format(
242 self.CODE.upper(), x) for x in self.channelList]
234 243
235 244 if self.decimation is None:
236 245 x, y, z = self.fill_gaps(self.x, self.y, self.z)
237 246 else:
238 247 x, y, z = self.fill_gaps(*self.decimate())
239 248
240 249 for n, ax in enumerate(self.axes):
241 250 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
242 251 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
243 252 data = self.data[-1]
244 253 if ax.firsttime:
245 254 ax.plt = ax.pcolormesh(x, y, z[n].T,
246 255 vmin=self.zmin,
247 256 vmax=self.zmax,
248 257 cmap=plt.get_cmap(self.colormap)
249 258 )
250 259 if self.showprofile:
251 260 ax.plot_profile = self.pf_axes[n].plot(
252 261 data['rti'][n], self.y)[0]
253 262 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(data['noise'][n], len(self.y)), self.y,
254 263 color="k", linestyle="dashed", lw=1)[0]
255 264 else:
256 265 ax.collections.remove(ax.collections[0])
257 266 ax.plt = ax.pcolormesh(x, y, z[n].T,
258 267 vmin=self.zmin,
259 268 vmax=self.zmax,
260 269 cmap=plt.get_cmap(self.colormap)
261 270 )
262 271 if self.showprofile:
263 272 ax.plot_profile.set_data(data['rti'][n], self.y)
264 273 ax.plot_noise.set_data(numpy.repeat(
265 274 data['noise'][n], len(self.y)), self.y)
266 275
267 276
268 277 class CoherencePlot(RTIPlot):
269 278 '''
270 279 Plot for Coherence data
271 280 '''
272 281
273 282 CODE = 'coh'
274 283
275 284 def setup(self):
276 285 self.xaxis = 'time'
277 286 self.ncols = 1
278 287 self.nrows = len(self.data.pairs)
279 288 self.nplots = len(self.data.pairs)
280 289 self.ylabel = 'Range [km]'
281 290 self.xlabel = 'Time'
282 291 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
283 292 if self.CODE == 'coh':
284 293 self.cb_label = ''
285 294 self.titles = [
286 295 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
287 296 else:
288 297 self.cb_label = 'Degrees'
289 298 self.titles = [
290 299 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
291 300
292 301 def update(self, dataOut):
293 302
294 303 data = {}
295 304 meta = {}
296 305 data['coh'] = dataOut.getCoherence()
297 306 meta['pairs'] = dataOut.pairsList
298 307
299 308 return data, meta
300 309
301 310 class PhasePlot(CoherencePlot):
302 311 '''
303 312 Plot for Phase map data
304 313 '''
305 314
306 315 CODE = 'phase'
307 316 colormap = 'seismic'
308 317
309 318 def update(self, dataOut):
310 319
311 320 data = {}
312 321 meta = {}
313 322 data['phase'] = dataOut.getCoherence(phase=True)
314 323 meta['pairs'] = dataOut.pairsList
315 324
316 325 return data, meta
317 326
318 327 class NoisePlot(Plot):
319 328 '''
320 Plot for noise
329 Plot for noise
321 330 '''
322 331
323 332 CODE = 'noise'
324 333 plot_type = 'scatterbuffer'
325 334
326 335 def setup(self):
327 336 self.xaxis = 'time'
328 337 self.ncols = 1
329 338 self.nrows = 1
330 339 self.nplots = 1
331 340 self.ylabel = 'Intensity [dB]'
332 341 self.xlabel = 'Time'
333 342 self.titles = ['Noise']
334 343 self.colorbar = False
335 344 self.plots_adjust.update({'right': 0.85 })
336 345
337 346 def update(self, dataOut):
338 347
339 348 data = {}
340 349 meta = {}
341 350 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor).reshape(dataOut.nChannels, 1)
342 351 meta['yrange'] = numpy.array([])
343 352
344 353 return data, meta
345 354
346 355 def plot(self):
347 356
348 357 x = self.data.times
349 358 xmin = self.data.min_time
350 359 xmax = xmin + self.xrange * 60 * 60
351 360 Y = self.data['noise']
352 361
353 362 if self.axes[0].firsttime:
354 363 self.ymin = numpy.nanmin(Y) - 5
355 364 self.ymax = numpy.nanmax(Y) + 5
356 365 for ch in self.data.channels:
357 366 y = Y[ch]
358 367 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
359 368 plt.legend(bbox_to_anchor=(1.18, 1.0))
360 369 else:
361 370 for ch in self.data.channels:
362 371 y = Y[ch]
363 372 self.axes[0].lines[ch].set_data(x, y)
364 373
365
374
366 375 class PowerProfilePlot(Plot):
367 376
368 377 CODE = 'pow_profile'
369 378 plot_type = 'scatter'
370 379
371 380 def setup(self):
372 381
373 382 self.ncols = 1
374 383 self.nrows = 1
375 384 self.nplots = 1
376 385 self.height = 4
377 386 self.width = 3
378 387 self.ylabel = 'Range [km]'
379 388 self.xlabel = 'Intensity [dB]'
380 389 self.titles = ['Power Profile']
381 390 self.colorbar = False
382 391
383 392 def update(self, dataOut):
384 393
385 394 data = {}
386 395 meta = {}
387 396 data[self.CODE] = dataOut.getPower()
388 397
389 398 return data, meta
390 399
391 400 def plot(self):
392 401
393 402 y = self.data.yrange
394 403 self.y = y
395 404
396 405 x = self.data[-1][self.CODE]
397
406
398 407 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
399 408 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
400
409
401 410 if self.axes[0].firsttime:
402 411 for ch in self.data.channels:
403 412 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
404 413 plt.legend()
405 414 else:
406 415 for ch in self.data.channels:
407 416 self.axes[0].lines[ch].set_data(x[ch], y)
408 417
409 418
410 419 class SpectraCutPlot(Plot):
411 420
412 421 CODE = 'spc_cut'
413 422 plot_type = 'scatter'
414 423 buffering = False
415 424
416 425 def setup(self):
417 426
418 427 self.nplots = len(self.data.channels)
419 428 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
420 429 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
421 430 self.width = 3.4 * self.ncols + 1.5
422 431 self.height = 3 * self.nrows
423 432 self.ylabel = 'Power [dB]'
424 433 self.colorbar = False
425 434 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.75, 'bottom':0.08})
426 435
427 436 def update(self, dataOut):
428 437
429 438 data = {}
430 439 meta = {}
431 440 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
432 441 data['spc'] = spc
433 442 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
434 443
435 444 return data, meta
436 445
437 446 def plot(self):
438 447 if self.xaxis == "frequency":
439 448 x = self.data.xrange[0][1:]
440 449 self.xlabel = "Frequency (kHz)"
441 450 elif self.xaxis == "time":
442 451 x = self.data.xrange[1]
443 452 self.xlabel = "Time (ms)"
444 453 else:
445 454 x = self.data.xrange[2]
446 455 self.xlabel = "Velocity (m/s)"
447 456
448 457 self.titles = []
449 458
450 459 y = self.data.yrange
451 460 z = self.data[-1]['spc']
452 461
453 462 if self.height_index:
454 463 index = numpy.array(self.height_index)
455 464 else:
456 465 index = numpy.arange(0, len(y), int((len(y))/9))
457 466
458 467 for n, ax in enumerate(self.axes):
459 468 if ax.firsttime:
460 469 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
461 470 self.xmin = self.xmin if self.xmin else -self.xmax
462 471 self.ymin = self.ymin if self.ymin else numpy.nanmin(z)
463 472 self.ymax = self.ymax if self.ymax else numpy.nanmax(z)
464 473 ax.plt = ax.plot(x, z[n, :, index].T)
465 474 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
466 475 self.figures[0].legend(ax.plt, labels, loc='center right')
467 476 else:
468 477 for i, line in enumerate(ax.plt):
469 478 line.set_data(x, z[n, :, index[i]])
470 479 self.titles.append('CH {}'.format(n))
471 480
472 481
473 482 class BeaconPhase(Plot):
474 483
475 484 __isConfig = None
476 485 __nsubplots = None
477 486
478 487 PREFIX = 'beacon_phase'
479 488
480 489 def __init__(self):
481 490 Plot.__init__(self)
482 491 self.timerange = 24*60*60
483 492 self.isConfig = False
484 493 self.__nsubplots = 1
485 494 self.counter_imagwr = 0
486 495 self.WIDTH = 800
487 496 self.HEIGHT = 400
488 497 self.WIDTHPROF = 120
489 498 self.HEIGHTPROF = 0
490 499 self.xdata = None
491 500 self.ydata = None
492 501
493 502 self.PLOT_CODE = BEACON_CODE
494 503
495 504 self.FTP_WEI = None
496 505 self.EXP_CODE = None
497 506 self.SUB_EXP_CODE = None
498 507 self.PLOT_POS = None
499 508
500 509 self.filename_phase = None
501 510
502 511 self.figfile = None
503 512
504 513 self.xmin = None
505 514 self.xmax = None
506 515
507 516 def getSubplots(self):
508 517
509 518 ncol = 1
510 519 nrow = 1
511 520
512 521 return nrow, ncol
513 522
514 523 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
515 524
516 525 self.__showprofile = showprofile
517 526 self.nplots = nplots
518 527
519 528 ncolspan = 7
520 529 colspan = 6
521 530 self.__nsubplots = 2
522 531
523 532 self.createFigure(id = id,
524 533 wintitle = wintitle,
525 534 widthplot = self.WIDTH+self.WIDTHPROF,
526 535 heightplot = self.HEIGHT+self.HEIGHTPROF,
527 536 show=show)
528 537
529 538 nrow, ncol = self.getSubplots()
530 539
531 540 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
532 541
533 542 def save_phase(self, filename_phase):
534 543 f = open(filename_phase,'w+')
535 544 f.write('\n\n')
536 545 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
537 546 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
538 547 f.close()
539 548
540 549 def save_data(self, filename_phase, data, data_datetime):
541 550 f=open(filename_phase,'a')
542 551 timetuple_data = data_datetime.timetuple()
543 552 day = str(timetuple_data.tm_mday)
544 553 month = str(timetuple_data.tm_mon)
545 554 year = str(timetuple_data.tm_year)
546 555 hour = str(timetuple_data.tm_hour)
547 556 minute = str(timetuple_data.tm_min)
548 557 second = str(timetuple_data.tm_sec)
549 558 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
550 559 f.close()
551 560
552 561 def plot(self):
553 562 log.warning('TODO: Not yet implemented...')
554 563
555 564 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
556 565 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
557 566 timerange=None,
558 567 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
559 568 server=None, folder=None, username=None, password=None,
560 569 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
561 570
562 if dataOut.flagNoData:
571 if dataOut.flagNoData:
563 572 return dataOut
564 573
565 574 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
566 575 return
567 576
568 577 if pairsList == None:
569 578 pairsIndexList = dataOut.pairsIndexList[:10]
570 579 else:
571 580 pairsIndexList = []
572 581 for pair in pairsList:
573 582 if pair not in dataOut.pairsList:
574 583 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
575 584 pairsIndexList.append(dataOut.pairsList.index(pair))
576 585
577 586 if pairsIndexList == []:
578 587 return
579 588
580 589 # if len(pairsIndexList) > 4:
581 590 # pairsIndexList = pairsIndexList[0:4]
582 591
583 592 hmin_index = None
584 593 hmax_index = None
585 594
586 595 if hmin != None and hmax != None:
587 596 indexes = numpy.arange(dataOut.nHeights)
588 597 hmin_list = indexes[dataOut.heightList >= hmin]
589 598 hmax_list = indexes[dataOut.heightList <= hmax]
590 599
591 600 if hmin_list.any():
592 601 hmin_index = hmin_list[0]
593 602
594 603 if hmax_list.any():
595 604 hmax_index = hmax_list[-1]+1
596 605
597 606 x = dataOut.getTimeRange()
598 607
599 608 thisDatetime = dataOut.datatime
600 609
601 610 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
602 611 xlabel = "Local Time"
603 612 ylabel = "Phase (degrees)"
604 613
605 614 update_figfile = False
606 615
607 616 nplots = len(pairsIndexList)
608 617 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
609 618 phase_beacon = numpy.zeros(len(pairsIndexList))
610 619 for i in range(nplots):
611 620 pair = dataOut.pairsList[pairsIndexList[i]]
612 621 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
613 622 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
614 623 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
615 624 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
616 625 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
617 626
618 627 if dataOut.beacon_heiIndexList:
619 628 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
620 629 else:
621 630 phase_beacon[i] = numpy.average(phase)
622 631
623 632 if not self.isConfig:
624 633
625 634 nplots = len(pairsIndexList)
626 635
627 636 self.setup(id=id,
628 637 nplots=nplots,
629 638 wintitle=wintitle,
630 639 showprofile=showprofile,
631 640 show=show)
632 641
633 642 if timerange != None:
634 643 self.timerange = timerange
635 644
636 645 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
637 646
638 647 if ymin == None: ymin = 0
639 648 if ymax == None: ymax = 360
640 649
641 650 self.FTP_WEI = ftp_wei
642 651 self.EXP_CODE = exp_code
643 652 self.SUB_EXP_CODE = sub_exp_code
644 653 self.PLOT_POS = plot_pos
645 654
646 655 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
647 656 self.isConfig = True
648 657 self.figfile = figfile
649 658 self.xdata = numpy.array([])
650 659 self.ydata = numpy.array([])
651 660
652 661 update_figfile = True
653 662
654 663 #open file beacon phase
655 664 path = '%s%03d' %(self.PREFIX, self.id)
656 665 beacon_file = os.path.join(path,'%s.txt'%self.name)
657 666 self.filename_phase = os.path.join(figpath,beacon_file)
658 667 #self.save_phase(self.filename_phase)
659 668
660 669
661 670 #store data beacon phase
662 671 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
663 672
664 673 self.setWinTitle(title)
665 674
666 675
667 676 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
668 677
669 678 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
670 679
671 680 axes = self.axesList[0]
672 681
673 682 self.xdata = numpy.hstack((self.xdata, x[0:1]))
674 683
675 684 if len(self.ydata)==0:
676 685 self.ydata = phase_beacon.reshape(-1,1)
677 686 else:
678 687 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
679 688
680 689
681 690 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
682 691 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
683 692 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
684 693 XAxisAsTime=True, grid='both'
685 694 )
686 695
687 696 self.draw()
688 697
689 698 if dataOut.ltctime >= self.xmax:
690 699 self.counter_imagwr = wr_period
691 700 self.isConfig = False
692 701 update_figfile = True
693 702
694 703 self.save(figpath=figpath,
695 704 figfile=figfile,
696 705 save=save,
697 706 ftp=ftp,
698 707 wr_period=wr_period,
699 708 thisDatetime=thisDatetime,
700 709 update_figfile=update_figfile)
701 710
702 return dataOut No newline at end of file
711 return dataOut
@@ -1,1457 +1,1456
1 1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 2 # All rights reserved.
3 3 #
4 4 # Distributed under the terms of the BSD 3-clause license.
5 5 """Spectra processing Unit and operations
6 6
7 7 Here you will find the processing unit `SpectraProc` and several operations
8 8 to work with Spectra data type
9 9 """
10 10
11 11 import time
12 12 import itertools
13 13
14 14 import numpy
15 15 import math
16 16
17 17 from schainpy.model.proc.jroproc_base import ProcessingUnit, MPDecorator, Operation
18 18 from schainpy.model.data.jrodata import Spectra
19 19 from schainpy.model.data.jrodata import hildebrand_sekhon
20 20 from schainpy.utils import log
21 21
22 22 from scipy.optimize import curve_fit
23 23
24 24
25 25 class SpectraProc(ProcessingUnit):
26 26
27 27 def __init__(self):
28 28
29 29 ProcessingUnit.__init__(self)
30 30
31 31 self.buffer = None
32 32 self.firstdatatime = None
33 33 self.profIndex = 0
34 34 self.dataOut = Spectra()
35 35 self.id_min = None
36 36 self.id_max = None
37 37 self.setupReq = False #Agregar a todas las unidades de proc
38 38
39 39 def __updateSpecFromVoltage(self):
40 40
41 41 self.dataOut.timeZone = self.dataIn.timeZone
42 42 self.dataOut.dstFlag = self.dataIn.dstFlag
43 43 self.dataOut.errorCount = self.dataIn.errorCount
44 44 self.dataOut.useLocalTime = self.dataIn.useLocalTime
45 45 try:
46 46 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
47 47 except:
48 48 pass
49 49 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
50 50 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
51 51 self.dataOut.channelList = self.dataIn.channelList
52 52 self.dataOut.heightList = self.dataIn.heightList
53 53 self.dataOut.dtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
54 54 self.dataOut.nProfiles = self.dataOut.nFFTPoints
55 55 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
56 56 self.dataOut.utctime = self.firstdatatime
57 57 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData
58 58 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData
59 59 self.dataOut.flagShiftFFT = False
60 60 self.dataOut.nCohInt = self.dataIn.nCohInt
61 61 self.dataOut.nIncohInt = 1
62 62 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
63 63 self.dataOut.frequency = self.dataIn.frequency
64 64 self.dataOut.realtime = self.dataIn.realtime
65 65 self.dataOut.azimuth = self.dataIn.azimuth
66 66 self.dataOut.zenith = self.dataIn.zenith
67 67 self.dataOut.beam.codeList = self.dataIn.beam.codeList
68 68 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
69 69 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
70 70
71 71 def __getFft(self):
72 72 """
73 73 Convierte valores de Voltaje a Spectra
74 74
75 75 Affected:
76 76 self.dataOut.data_spc
77 77 self.dataOut.data_cspc
78 78 self.dataOut.data_dc
79 79 self.dataOut.heightList
80 80 self.profIndex
81 81 self.buffer
82 82 self.dataOut.flagNoData
83 83 """
84 84 fft_volt = numpy.fft.fft(
85 85 self.buffer, n=self.dataOut.nFFTPoints, axis=1)
86 86 fft_volt = fft_volt.astype(numpy.dtype('complex'))
87 87 dc = fft_volt[:, 0, :]
88 88
89 89 # calculo de self-spectra
90 90 fft_volt = numpy.fft.fftshift(fft_volt, axes=(1,))
91 91 spc = fft_volt * numpy.conjugate(fft_volt)
92 92 spc = spc.real
93 93
94 94 blocksize = 0
95 95 blocksize += dc.size
96 96 blocksize += spc.size
97 97
98 98 cspc = None
99 99 pairIndex = 0
100 100 if self.dataOut.pairsList != None:
101 101 # calculo de cross-spectra
102 102 cspc = numpy.zeros(
103 103 (self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
104 104 for pair in self.dataOut.pairsList:
105 105 if pair[0] not in self.dataOut.channelList:
106 106 raise ValueError("Error getting CrossSpectra: pair 0 of %s is not in channelList = %s" % (
107 107 str(pair), str(self.dataOut.channelList)))
108 108 if pair[1] not in self.dataOut.channelList:
109 109 raise ValueError("Error getting CrossSpectra: pair 1 of %s is not in channelList = %s" % (
110 110 str(pair), str(self.dataOut.channelList)))
111 111
112 112 cspc[pairIndex, :, :] = fft_volt[pair[0], :, :] * \
113 113 numpy.conjugate(fft_volt[pair[1], :, :])
114 114 pairIndex += 1
115 115 blocksize += cspc.size
116 116
117 117 self.dataOut.data_spc = spc
118 118 self.dataOut.data_cspc = cspc
119 119 self.dataOut.data_dc = dc
120 120 self.dataOut.blockSize = blocksize
121 121 self.dataOut.flagShiftFFT = False
122 122
123 123 def run(self, nProfiles=None, nFFTPoints=None, pairsList=None, ippFactor=None, shift_fft=False):
124 124
125 125 if self.dataIn.type == "Spectra":
126 126 self.dataOut.copy(self.dataIn)
127 127 if shift_fft:
128 128 #desplaza a la derecha en el eje 2 determinadas posiciones
129 129 shift = int(self.dataOut.nFFTPoints/2)
130 130 self.dataOut.data_spc = numpy.roll(self.dataOut.data_spc, shift , axis=1)
131 131
132 132 if self.dataOut.data_cspc is not None:
133 133 #desplaza a la derecha en el eje 2 determinadas posiciones
134 134 self.dataOut.data_cspc = numpy.roll(self.dataOut.data_cspc, shift, axis=1)
135 135 if pairsList:
136 136 self.__selectPairs(pairsList)
137 137
138 138 elif self.dataIn.type == "Voltage":
139 139
140 140 self.dataOut.flagNoData = True
141 141
142 142 if nFFTPoints == None:
143 143 raise ValueError("This SpectraProc.run() need nFFTPoints input variable")
144 144
145 145 if nProfiles == None:
146 146 nProfiles = nFFTPoints
147 147
148 148 if ippFactor == None:
149 149 self.dataOut.ippFactor = 1
150 150
151 151 self.dataOut.nFFTPoints = nFFTPoints
152 152
153 153 if self.buffer is None:
154 154 self.buffer = numpy.zeros((self.dataIn.nChannels,
155 155 nProfiles,
156 156 self.dataIn.nHeights),
157 157 dtype='complex')
158 158
159 159 if self.dataIn.flagDataAsBlock:
160 160 nVoltProfiles = self.dataIn.data.shape[1]
161 161
162 162 if nVoltProfiles == nProfiles:
163 163 self.buffer = self.dataIn.data.copy()
164 164 self.profIndex = nVoltProfiles
165 165
166 166 elif nVoltProfiles < nProfiles:
167 167
168 168 if self.profIndex == 0:
169 169 self.id_min = 0
170 170 self.id_max = nVoltProfiles
171 171
172 172 self.buffer[:, self.id_min:self.id_max,
173 173 :] = self.dataIn.data
174 174 self.profIndex += nVoltProfiles
175 175 self.id_min += nVoltProfiles
176 176 self.id_max += nVoltProfiles
177 177 else:
178 178 raise ValueError("The type object %s has %d profiles, it should just has %d profiles" % (
179 179 self.dataIn.type, self.dataIn.data.shape[1], nProfiles))
180 180 self.dataOut.flagNoData = True
181 181 else:
182 182 self.buffer[:, self.profIndex, :] = self.dataIn.data.copy()
183 183 self.profIndex += 1
184 184
185 185 if self.firstdatatime == None:
186 186 self.firstdatatime = self.dataIn.utctime
187 187
188 188 if self.profIndex == nProfiles:
189 189 self.__updateSpecFromVoltage()
190 190 if pairsList == None:
191 191 self.dataOut.pairsList = [pair for pair in itertools.combinations(self.dataOut.channelList, 2)]
192 192 else:
193 193 self.dataOut.pairsList = pairsList
194 194 self.__getFft()
195 195 self.dataOut.flagNoData = False
196 196 self.firstdatatime = None
197 197 self.profIndex = 0
198 198 else:
199 199 raise ValueError("The type of input object '%s' is not valid".format(
200 200 self.dataIn.type))
201 201
202 202 def __selectPairs(self, pairsList):
203 203
204 204 if not pairsList:
205 205 return
206 206
207 207 pairs = []
208 208 pairsIndex = []
209 209
210 210 for pair in pairsList:
211 211 if pair[0] not in self.dataOut.channelList or pair[1] not in self.dataOut.channelList:
212 212 continue
213 213 pairs.append(pair)
214 214 pairsIndex.append(pairs.index(pair))
215 215
216 216 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndex]
217 217 self.dataOut.pairsList = pairs
218 218
219 219 return
220 220
221 221 def selectFFTs(self, minFFT, maxFFT ):
222 222 """
223 223 Selecciona un bloque de datos en base a un grupo de valores de puntos FFTs segun el rango
224 224 minFFT<= FFT <= maxFFT
225 225 """
226 226
227 227 if (minFFT > maxFFT):
228 228 raise ValueError("Error selecting heights: Height range (%d,%d) is not valid" % (minFFT, maxFFT))
229 229
230 230 if (minFFT < self.dataOut.getFreqRange()[0]):
231 231 minFFT = self.dataOut.getFreqRange()[0]
232 232
233 233 if (maxFFT > self.dataOut.getFreqRange()[-1]):
234 234 maxFFT = self.dataOut.getFreqRange()[-1]
235 235
236 236 minIndex = 0
237 237 maxIndex = 0
238 238 FFTs = self.dataOut.getFreqRange()
239 239
240 240 inda = numpy.where(FFTs >= minFFT)
241 241 indb = numpy.where(FFTs <= maxFFT)
242 242
243 243 try:
244 244 minIndex = inda[0][0]
245 245 except:
246 246 minIndex = 0
247 247
248 248 try:
249 249 maxIndex = indb[0][-1]
250 250 except:
251 251 maxIndex = len(FFTs)
252 252
253 253 self.selectFFTsByIndex(minIndex, maxIndex)
254 254
255 255 return 1
256 256
257 257 def getBeaconSignal(self, tauindex=0, channelindex=0, hei_ref=None):
258 258 newheis = numpy.where(
259 259 self.dataOut.heightList > self.dataOut.radarControllerHeaderObj.Taus[tauindex])
260 260
261 261 if hei_ref != None:
262 262 newheis = numpy.where(self.dataOut.heightList > hei_ref)
263 263
264 264 minIndex = min(newheis[0])
265 265 maxIndex = max(newheis[0])
266 266 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
267 267 heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
268 268
269 269 # determina indices
270 270 nheis = int(self.dataOut.radarControllerHeaderObj.txB /
271 271 (self.dataOut.heightList[1] - self.dataOut.heightList[0]))
272 272 avg_dB = 10 * \
273 273 numpy.log10(numpy.sum(data_spc[channelindex, :, :], axis=0))
274 274 beacon_dB = numpy.sort(avg_dB)[-nheis:]
275 275 beacon_heiIndexList = []
276 276 for val in avg_dB.tolist():
277 277 if val >= beacon_dB[0]:
278 278 beacon_heiIndexList.append(avg_dB.tolist().index(val))
279 279
280 280 #data_spc = data_spc[:,:,beacon_heiIndexList]
281 281 data_cspc = None
282 282 if self.dataOut.data_cspc is not None:
283 283 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
284 284 #data_cspc = data_cspc[:,:,beacon_heiIndexList]
285 285
286 286 data_dc = None
287 287 if self.dataOut.data_dc is not None:
288 288 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
289 289 #data_dc = data_dc[:,beacon_heiIndexList]
290 290
291 291 self.dataOut.data_spc = data_spc
292 292 self.dataOut.data_cspc = data_cspc
293 293 self.dataOut.data_dc = data_dc
294 294 self.dataOut.heightList = heightList
295 295 self.dataOut.beacon_heiIndexList = beacon_heiIndexList
296 296
297 297 return 1
298 298
299 299 def selectFFTsByIndex(self, minIndex, maxIndex):
300 300 """
301 301
302 302 """
303 303
304 304 if (minIndex < 0) or (minIndex > maxIndex):
305 305 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex))
306 306
307 307 if (maxIndex >= self.dataOut.nProfiles):
308 308 maxIndex = self.dataOut.nProfiles-1
309 309
310 310 #Spectra
311 311 data_spc = self.dataOut.data_spc[:,minIndex:maxIndex+1,:]
312 312
313 313 data_cspc = None
314 314 if self.dataOut.data_cspc is not None:
315 315 data_cspc = self.dataOut.data_cspc[:,minIndex:maxIndex+1,:]
316 316
317 317 data_dc = None
318 318 if self.dataOut.data_dc is not None:
319 319 data_dc = self.dataOut.data_dc[minIndex:maxIndex+1,:]
320 320
321 321 self.dataOut.data_spc = data_spc
322 322 self.dataOut.data_cspc = data_cspc
323 323 self.dataOut.data_dc = data_dc
324 324
325 325 self.dataOut.ippSeconds = self.dataOut.ippSeconds*(self.dataOut.nFFTPoints / numpy.shape(data_cspc)[1])
326 326 self.dataOut.nFFTPoints = numpy.shape(data_cspc)[1]
327 327 self.dataOut.profilesPerBlock = numpy.shape(data_cspc)[1]
328 328
329 329 return 1
330 330
331 331 def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None):
332 332 # validacion de rango
333 333 if minHei == None:
334 334 minHei = self.dataOut.heightList[0]
335 335
336 336 if maxHei == None:
337 337 maxHei = self.dataOut.heightList[-1]
338 338
339 339 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
340 340 print('minHei: %.2f is out of the heights range' % (minHei))
341 341 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
342 342 minHei = self.dataOut.heightList[0]
343 343
344 344 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
345 345 print('maxHei: %.2f is out of the heights range' % (maxHei))
346 346 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
347 347 maxHei = self.dataOut.heightList[-1]
348 348
349 349 # validacion de velocidades
350 350 velrange = self.dataOut.getVelRange(1)
351 351
352 352 if minVel == None:
353 353 minVel = velrange[0]
354 354
355 355 if maxVel == None:
356 356 maxVel = velrange[-1]
357 357
358 358 if (minVel < velrange[0]) or (minVel > maxVel):
359 359 print('minVel: %.2f is out of the velocity range' % (minVel))
360 360 print('minVel is setting to %.2f' % (velrange[0]))
361 361 minVel = velrange[0]
362 362
363 363 if (maxVel > velrange[-1]) or (maxVel < minVel):
364 364 print('maxVel: %.2f is out of the velocity range' % (maxVel))
365 365 print('maxVel is setting to %.2f' % (velrange[-1]))
366 366 maxVel = velrange[-1]
367 367
368 368 # seleccion de indices para rango
369 369 minIndex = 0
370 370 maxIndex = 0
371 371 heights = self.dataOut.heightList
372 372
373 373 inda = numpy.where(heights >= minHei)
374 374 indb = numpy.where(heights <= maxHei)
375 375
376 376 try:
377 377 minIndex = inda[0][0]
378 378 except:
379 379 minIndex = 0
380 380
381 381 try:
382 382 maxIndex = indb[0][-1]
383 383 except:
384 384 maxIndex = len(heights)
385 385
386 386 if (minIndex < 0) or (minIndex > maxIndex):
387 387 raise ValueError("some value in (%d,%d) is not valid" % (
388 388 minIndex, maxIndex))
389 389
390 390 if (maxIndex >= self.dataOut.nHeights):
391 391 maxIndex = self.dataOut.nHeights - 1
392 392
393 393 # seleccion de indices para velocidades
394 394 indminvel = numpy.where(velrange >= minVel)
395 395 indmaxvel = numpy.where(velrange <= maxVel)
396 396 try:
397 397 minIndexVel = indminvel[0][0]
398 398 except:
399 399 minIndexVel = 0
400 400
401 401 try:
402 402 maxIndexVel = indmaxvel[0][-1]
403 403 except:
404 404 maxIndexVel = len(velrange)
405 405
406 406 # seleccion del espectro
407 407 data_spc = self.dataOut.data_spc[:,
408 408 minIndexVel:maxIndexVel + 1, minIndex:maxIndex + 1]
409 409 # estimacion de ruido
410 410 noise = numpy.zeros(self.dataOut.nChannels)
411 411
412 412 for channel in range(self.dataOut.nChannels):
413 413 daux = data_spc[channel, :, :]
414 414 sortdata = numpy.sort(daux, axis=None)
415 415 noise[channel] = hildebrand_sekhon(sortdata, self.dataOut.nIncohInt)
416 416
417 417 self.dataOut.noise_estimation = noise.copy()
418 418
419 419 return 1
420 420
421 421 class removeDC(Operation):
422 422
423 423 def run(self, dataOut, mode=2):
424 424 self.dataOut = dataOut
425 425 jspectra = self.dataOut.data_spc
426 426 jcspectra = self.dataOut.data_cspc
427 427
428 428 num_chan = jspectra.shape[0]
429 429 num_hei = jspectra.shape[2]
430 430
431 431 if jcspectra is not None:
432 432 jcspectraExist = True
433 433 num_pairs = jcspectra.shape[0]
434 434 else:
435 435 jcspectraExist = False
436 436
437 437 freq_dc = int(jspectra.shape[1] / 2)
438 438 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
439 439 ind_vel = ind_vel.astype(int)
440 440
441 441 if ind_vel[0] < 0:
442 442 ind_vel[list(range(0, 1))] = ind_vel[list(range(0, 1))] + self.num_prof
443 443
444 444 if mode == 1:
445 445 jspectra[:, freq_dc, :] = (
446 446 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
447 447
448 448 if jcspectraExist:
449 449 jcspectra[:, freq_dc, :] = (
450 450 jcspectra[:, ind_vel[1], :] + jcspectra[:, ind_vel[2], :]) / 2
451 451
452 452 if mode == 2:
453 453
454 454 vel = numpy.array([-2, -1, 1, 2])
455 455 xx = numpy.zeros([4, 4])
456 456
457 457 for fil in range(4):
458 458 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
459 459
460 460 xx_inv = numpy.linalg.inv(xx)
461 461 xx_aux = xx_inv[0, :]
462 462
463 463 for ich in range(num_chan):
464 464 yy = jspectra[ich, ind_vel, :]
465 465 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
466 466
467 467 junkid = jspectra[ich, freq_dc, :] <= 0
468 468 cjunkid = sum(junkid)
469 469
470 470 if cjunkid.any():
471 471 jspectra[ich, freq_dc, junkid.nonzero()] = (
472 472 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
473 473
474 474 if jcspectraExist:
475 475 for ip in range(num_pairs):
476 476 yy = jcspectra[ip, ind_vel, :]
477 477 jcspectra[ip, freq_dc, :] = numpy.dot(xx_aux, yy)
478 478
479 479 self.dataOut.data_spc = jspectra
480 480 self.dataOut.data_cspc = jcspectra
481 481
482 482 return self.dataOut
483 483
484 484 # import matplotlib.pyplot as plt
485 485
486 486 def fit_func( x, a0, a1, a2): #, a3, a4, a5):
487 487 z = (x - a1) / a2
488 488 y = a0 * numpy.exp(-z**2 / a2) #+ a3 + a4 * x + a5 * x**2
489 489 return y
490 490 class CleanRayleigh(Operation):
491 491
492 492 def __init__(self):
493 493
494 494 Operation.__init__(self)
495 495 self.i=0
496 496 self.isConfig = False
497 497 self.__dataReady = False
498 498 self.__profIndex = 0
499 499 self.byTime = False
500 500 self.byProfiles = False
501 501
502 502 self.bloques = None
503 503 self.bloque0 = None
504 504
505 505 self.index = 0
506 506
507 507 self.buffer = 0
508 508 self.buffer2 = 0
509 509 self.buffer3 = 0
510 #self.min_hei = None
511 #self.max_hei = None
510
512 511
513 512 def setup(self,dataOut,min_hei,max_hei,n, timeInterval,factor_stdv):
514 513
515 514 self.nChannels = dataOut.nChannels
516 515 self.nProf = dataOut.nProfiles
517 516 self.nPairs = dataOut.data_cspc.shape[0]
518 517 self.pairsArray = numpy.array(dataOut.pairsList)
519 518 self.spectra = dataOut.data_spc
520 519 self.cspectra = dataOut.data_cspc
521 520 self.heights = dataOut.heightList #alturas totales
522 521 self.nHeights = len(self.heights)
523 522 self.min_hei = min_hei
524 523 self.max_hei = max_hei
525 524 if (self.min_hei == None):
526 525 self.min_hei = 0
527 526 if (self.max_hei == None):
528 527 self.max_hei = dataOut.heightList[-1]
529 528 self.hval = ((self.max_hei>=self.heights) & (self.heights >= self.min_hei)).nonzero()
530 529 self.heightsClean = self.heights[self.hval] #alturas filtradas
531 530 self.hval = self.hval[0] # forma (N,), an solo N elementos -> Indices de alturas
532 531 self.nHeightsClean = len(self.heightsClean)
533 532 self.channels = dataOut.channelList
534 533 self.nChan = len(self.channels)
535 534 self.nIncohInt = dataOut.nIncohInt
536 535 self.__initime = dataOut.utctime
537 536 self.maxAltInd = self.hval[-1]+1
538 537 self.minAltInd = self.hval[0]
539 538
540 539 self.crosspairs = dataOut.pairsList
541 540 self.nPairs = len(self.crosspairs)
542 541 self.normFactor = dataOut.normFactor
543 542 self.nFFTPoints = dataOut.nFFTPoints
544 543 self.ippSeconds = dataOut.ippSeconds
545 544 self.currentTime = self.__initime
546 545 self.pairsArray = numpy.array(dataOut.pairsList)
547 546 self.factor_stdv = factor_stdv
548
549
547 print("CHANNELS: ",[x for x in self.channels])
550 548
551 549 if n != None :
552 550 self.byProfiles = True
553 551 self.nIntProfiles = n
554 552 else:
555 553 self.__integrationtime = timeInterval
556 554
557 555 self.__dataReady = False
558 556 self.isConfig = True
559 557
560 558
561 559
562 560 def run(self, dataOut,min_hei=None,max_hei=None, n=None, timeInterval=10,factor_stdv=2.5):
563 561 #print (dataOut.utctime)
564 562 if not self.isConfig :
565 563 #print("Setting config")
566 564 self.setup(dataOut, min_hei,max_hei,n,timeInterval,factor_stdv)
567 565 #print("Config Done")
568 566 tini=dataOut.utctime
569 567
570 568 if self.byProfiles:
571 569 if self.__profIndex == self.nIntProfiles:
572 570 self.__dataReady = True
573 571 else:
574 572 if (tini - self.__initime) >= self.__integrationtime:
575 573 #print(tini - self.__initime,self.__profIndex)
576 574 self.__dataReady = True
577 575 self.__initime = tini
578 576
579 577 #if (tini.tm_min % 2) == 0 and (tini.tm_sec < 5 and self.fint==0):
580 578
581 579 if self.__dataReady:
582 580 print("Data ready",self.__profIndex)
583 581 self.__profIndex = 0
584 582 jspc = self.buffer
585 583 jcspc = self.buffer2
586 584 #jnoise = self.buffer3
587 585 self.buffer = dataOut.data_spc
588 586 self.buffer2 = dataOut.data_cspc
589 587 #self.buffer3 = dataOut.noise
590 588 self.currentTime = dataOut.utctime
591 589 if numpy.any(jspc) :
592 590 #print( jspc.shape, jcspc.shape)
593 591 jspc = numpy.reshape(jspc,(int(len(jspc)/self.nChannels),self.nChannels,self.nFFTPoints,self.nHeights))
594 592 jcspc= numpy.reshape(jcspc,(int(len(jcspc)/self.nPairs),self.nPairs,self.nFFTPoints,self.nHeights))
595 593 self.__dataReady = False
596 594 #print( jspc.shape, jcspc.shape)
597 595 dataOut.flagNoData = False
598 596 else:
599 597 dataOut.flagNoData = True
600 598 self.__dataReady = False
601 599 return dataOut
602 600 else:
603 601 #print( len(self.buffer))
604 602 if numpy.any(self.buffer):
605 603 self.buffer = numpy.concatenate((self.buffer,dataOut.data_spc), axis=0)
606 604 self.buffer2 = numpy.concatenate((self.buffer2,dataOut.data_cspc), axis=0)
607 605 self.buffer3 += dataOut.data_dc
608 606 else:
609 607 self.buffer = dataOut.data_spc
610 608 self.buffer2 = dataOut.data_cspc
611 609 self.buffer3 = dataOut.data_dc
612 610 #print self.index, self.fint
613 611 #print self.buffer2.shape
614 612 dataOut.flagNoData = True ## NOTE: ?? revisar LUEGO
615 613 self.__profIndex += 1
616 614 return dataOut ## NOTE: REV
617 615
618 616 # if self.index == 0 and self.fint == 1 :
619 617 # if jspc != None:
620 618 # print len(jspc), jspc.shape
621 619 # jspc= numpy.reshape(jspc,(4,128,63,len(jspc)/4))
622 620 # print jspc.shape
623 621 # dataOut.flagNoData = True
624 622 # return dataOut
625 623 # if path != None:
626 624 # sys.path.append(path)
627 625 # self.library = importlib.import_module(file)
628 626 #
629 627 # To be inserted as a parameter
630 628
631 629 #Set constants
632 630 #constants = self.library.setConstants(dataOut)
633 631 #dataOut.constants = constants
634 632
635 633 #snrth= 20
636 634
637 635 #crosspairs = dataOut.groupList
638 636 #noise = dataOut.noise
639 637 #print( nProf,heights)
640 638 #print( jspc.shape, jspc.shape[0])
641 639 #print noise
642 640 #print jnoise[len(jnoise)-1,:], numpy.nansum(jnoise,axis=0)/len(jnoise)
643 641 #jnoise = jnoise/N
644 642 #noise = numpy.nansum(jnoise,axis=0)#/len(jnoise)
645 643 #print( noise)
646 644 #power = numpy.sum(spectra, axis=1)
647 645 #print power[0,:]
648 646 #print("CROSSPAIRS",crosspairs)
649 647 #nPairs = len(crosspairs)
650 648 #print(numpy.shape(dataOut.data_spc))
651 649
652 650 #absc = dataOut.abscissaList[:-1]
653 651
654 652 #print absc.shape
655 653 #nBlocks=149
656 654 #print('spectra', spectra.shape)
657 655 #print('noise print', crosspairs)
658 656 #print('spectra', spectra.shape)
659 657 #print('cspectra', cspectra.shape)
660 658 #print numpy.array(dataOut.data_pre[1]).shape
661 659 #spec, cspec = self.__DiffCoherent(snrth, spectra, cspectra, nProf, heights,nChan, nHei, nPairs, channels, noise*nProf, crosspairs)
662 660
663 661
664 662 #index = tini.tm_hour*12+tini.tm_min/5
665 663 # jspc = jspc/self.nFFTPoints/self.normFactor
666 664 # jcspc = jcspc/self.nFFTPoints/self.normFactor
667 665
668 666
669 667
670 668 #dataOut.data_spc,dataOut.data_cspc = self.CleanRayleigh(dataOut,jspc,jcspc,crosspairs,heights,channels,nProf,nHei,nChan,nPairs,nIncohInt,nBlocks=nBlocks)
671 669 #tmp_spectra,tmp_cspectra,sat_spectra,sat_cspectra = self.cleanRayleigh(dataOut,jspc,jcspc,self.min_hei,self.max_hei)
672 670 tmp_spectra,tmp_cspectra = self.cleanRayleigh(dataOut,jspc,jcspc,self.factor_stdv)
673 671 #jspectra = tmp_spectra*len(jspc[:,0,0,0])
674 672 #jcspectra = tmp_cspectra*len(jspc[:,0,0,0])
675 673
676 674 dataOut.data_spc = tmp_spectra
677 675 dataOut.data_cspc = tmp_cspectra
678 676 dataOut.data_dc = self.buffer3
679 677 dataOut.nIncohInt *= self.nIntProfiles
680 678 dataOut.utctime = self.currentTime #tiempo promediado
681 print("Time: ",time.localtime(dataOut.utctime))
679 #print("Time: ",time.localtime(dataOut.utctime))
682 680 # dataOut.data_spc = sat_spectra
683 681 # dataOut.data_cspc = sat_cspectra
684 682 self.buffer = 0
685 683 self.buffer2 = 0
686 684 self.buffer3 = 0
687 685
688 686 return dataOut
689 687
690 688 def cleanRayleigh(self,dataOut,spectra,cspectra,factor_stdv):
691 689 print("OP cleanRayleigh")
692 690 #import matplotlib.pyplot as plt
693 691 #for k in range(149):
694 692
695 693 rfunc = cspectra.copy() #self.bloques
696 694 val_spc = spectra*0.0 #self.bloque0*0.0
697 695 val_cspc = cspectra*0.0 #self.bloques*0.0
698 696 in_sat_spectra = spectra.copy() #self.bloque0
699 697 in_sat_cspectra = cspectra.copy() #self.bloques
700 698
701 699 raxs = math.ceil(math.sqrt(self.nPairs))
702 700 caxs = math.ceil(self.nPairs/raxs)
703 701
704 702 #print(self.hval)
705 703 #print numpy.absolute(rfunc[:,0,0,14])
706 704 for ih in range(self.minAltInd,self.maxAltInd):
707 705 for ifreq in range(self.nFFTPoints):
708 706 # fig, axs = plt.subplots(raxs, caxs)
709 707 # fig2, axs2 = plt.subplots(raxs, caxs)
710 708 col_ax = 0
711 709 row_ax = 0
712 710 for ii in range(self.nPairs): #PARES DE CANALES SELF y CROSS
713 711 #print("ii: ",ii)
714 712 if (col_ax%caxs==0 and col_ax!=0):
715 713 col_ax = 0
716 714 row_ax += 1
717 715 func2clean = 10*numpy.log10(numpy.absolute(rfunc[:,ii,ifreq,ih])) #Potencia?
718 716 #print(func2clean.shape)
719 717 val = (numpy.isfinite(func2clean)==True).nonzero()
720 718
721 719 if len(val)>0: #limitador
722 720 min_val = numpy.around(numpy.amin(func2clean)-2) #> (-40)
723 721 if min_val <= -40 :
724 722 min_val = -40
725 723 max_val = numpy.around(numpy.amax(func2clean)+2) #< 200
726 724 if max_val >= 200 :
727 725 max_val = 200
728 726 #print min_val, max_val
729 727 step = 1
730 728 #print("Getting bins and the histogram")
731 729 x_dist = min_val + numpy.arange(1 + ((max_val-(min_val))/step))*step
732 730 y_dist,binstep = numpy.histogram(func2clean,bins=range(int(min_val),int(max_val+2),step))
733 731 #print(len(y_dist),len(binstep[:-1]))
734 732 #print(row_ax,col_ax, " ..")
735 733 #print(self.pairsArray[ii][0],self.pairsArray[ii][1])
736 734 mean = numpy.sum(x_dist * y_dist) / numpy.sum(y_dist)
737 735 sigma = numpy.sqrt(numpy.sum(y_dist * (x_dist - mean)**2) / numpy.sum(y_dist))
738 736 parg = [numpy.amax(y_dist),mean,sigma]
739 737 gauss_fit, covariance = None, None
740 738 newY = None
741 739 try :
742 740 gauss_fit, covariance = curve_fit(fit_func, x_dist, y_dist,p0=parg)
743 741 mode = gauss_fit[1]
744 742 stdv = gauss_fit[2]
745 743 #print(" FIT OK",gauss_fit)
746 744 '''
747 745 newY = fit_func(x_dist,gauss_fit[0],gauss_fit[1],gauss_fit[2])
748 746 axs[row_ax,col_ax].plot(binstep[:-1],y_dist,color='green')
749 747 axs[row_ax,col_ax].plot(binstep[:-1],newY,color='red')
750 748 axs[row_ax,col_ax].set_title("Pair "+str(self.crosspairs[ii]))'''
751 749 except:
752 750 mode = mean
753 751 stdv = sigma
754 752 #print("FIT FAIL")
755 753
756 754
757 755 #print(mode,stdv)
758 756 #Removing echoes greater than mode + 3*stdv
759 757 #factor_stdv = 2
760 758 noval = (abs(func2clean - mode)>=(factor_stdv*stdv)).nonzero()
761 759 #noval tiene los indices que se van a remover
762 760 #print("Pair ",ii," novals: ",len(noval[0]))
763 761 if len(noval[0]) > 0: #forma de array (N,) es igual a longitud (N)
764 762 novall = ((func2clean - mode) >= (factor_stdv*stdv)).nonzero()
765 763 #print(novall)
766 #print(" ")
764 #print(" ",self.pairsArray[ii])
767 765 cross_pairs = self.pairsArray[ii]
768 766 #Getting coherent echoes which are removed.
769 if len(novall[0]) > 0:
770
771 val_spc[novall[0],cross_pairs[0],ifreq,ih] = 1
772 val_spc[novall[0],cross_pairs[1],ifreq,ih] = 1
773 val_cspc[novall[0],ii,ifreq,ih] = 1
767 # if len(novall[0]) > 0:
768 #
769 # val_spc[novall[0],cross_pairs[0],ifreq,ih] = 1
770 # val_spc[novall[0],cross_pairs[1],ifreq,ih] = 1
771 # val_cspc[novall[0],ii,ifreq,ih] = 1
774 772 #print("OUT NOVALL 1")
775 773 #Removing coherent from ISR data
774 chA = self.channels.index(cross_pairs[0])
775 chB = self.channels.index(cross_pairs[1])
776 776
777 #print(spectra[:,ii,ifreq,ih])
778 777 new_a = numpy.delete(cspectra[:,ii,ifreq,ih], noval[0])
779 778 mean_cspc = numpy.mean(new_a)
780 new_b = numpy.delete(spectra[:,cross_pairs[0],ifreq,ih], noval[0])
779 new_b = numpy.delete(spectra[:,chA,ifreq,ih], noval[0])
781 780 mean_spc0 = numpy.mean(new_b)
782 new_c = numpy.delete(spectra[:,cross_pairs[1],ifreq,ih], noval[0])
781 new_c = numpy.delete(spectra[:,chB,ifreq,ih], noval[0])
783 782 mean_spc1 = numpy.mean(new_c)
784 spectra[noval,cross_pairs[0],ifreq,ih] = mean_spc0
785 spectra[noval,cross_pairs[1],ifreq,ih] = mean_spc1
783 spectra[noval,chA,ifreq,ih] = mean_spc0
784 spectra[noval,chB,ifreq,ih] = mean_spc1
786 785 cspectra[noval,ii,ifreq,ih] = mean_cspc
787 786
788 787 '''
789 788 func2clean = 10*numpy.log10(numpy.absolute(cspectra[:,ii,ifreq,ih]))
790 789 y_dist,binstep = numpy.histogram(func2clean,bins=range(int(min_val),int(max_val+2),step))
791 790 axs2[row_ax,col_ax].plot(binstep[:-1],newY,color='red')
792 791 axs2[row_ax,col_ax].plot(binstep[:-1],y_dist,color='green')
793 792 axs2[row_ax,col_ax].set_title("Pair "+str(self.crosspairs[ii]))
794 793 '''
795 794
796 795 col_ax += 1 #contador de ploteo columnas
797 796 ##print(col_ax)
798 797 '''
799 798 title = str(dataOut.datatime)+" nFFT: "+str(ifreq)+" Alt: "+str(self.heights[ih])+ " km"
800 799 title2 = str(dataOut.datatime)+" nFFT: "+str(ifreq)+" Alt: "+str(self.heights[ih])+ " km CLEANED"
801 800 fig.suptitle(title)
802 801 fig2.suptitle(title2)
803 802 plt.show()'''
804 803
805 804 ''' channels = channels
806 805 cross_pairs = cross_pairs
807 806 #print("OUT NOVALL 2")
808 807
809 808 vcross0 = (cross_pairs[0] == channels[ii]).nonzero()
810 809 vcross1 = (cross_pairs[1] == channels[ii]).nonzero()
811 810 vcross = numpy.concatenate((vcross0,vcross1),axis=None)
812 811 #print('vcros =', vcross)
813 812
814 813 #Getting coherent echoes which are removed.
815 814 if len(novall) > 0:
816 815 #val_spc[novall,ii,ifreq,ih] = 1
817 816 val_spc[ii,ifreq,ih,novall] = 1
818 817 if len(vcross) > 0:
819 818 val_cspc[vcross,ifreq,ih,novall] = 1
820 819
821 820 #Removing coherent from ISR data.
822 821 self.bloque0[ii,ifreq,ih,noval] = numpy.nan
823 822 if len(vcross) > 0:
824 823 self.bloques[vcross,ifreq,ih,noval] = numpy.nan
825 824 '''
826 825
827 826 print("Getting average of the spectra and cross-spectra from incoherent echoes.")
828 827 out_spectra = numpy.zeros([self.nChan,self.nFFTPoints,self.nHeights], dtype=float) #+numpy.nan
829 828 out_cspectra = numpy.zeros([self.nPairs,self.nFFTPoints,self.nHeights], dtype=complex) #+numpy.nan
830 829 for ih in range(self.nHeights):
831 830 for ifreq in range(self.nFFTPoints):
832 831 for ich in range(self.nChan):
833 832 tmp = spectra[:,ich,ifreq,ih]
834 833 valid = (numpy.isfinite(tmp[:])==True).nonzero()
835 834 # if ich == 0 and ifreq == 0 and ih == 17 :
836 835 # print tmp
837 836 # print valid
838 837 # print len(valid[0])
839 838 #print('TMP',tmp)
840 839 if len(valid[0]) >0 :
841 840 out_spectra[ich,ifreq,ih] = numpy.nansum(tmp)#/len(valid[0])
842 841 #for icr in range(nPairs):
843 842 for icr in range(self.nPairs):
844 843 tmp = numpy.squeeze(cspectra[:,icr,ifreq,ih])
845 844 valid = (numpy.isfinite(tmp)==True).nonzero()
846 845 if len(valid[0]) > 0:
847 846 out_cspectra[icr,ifreq,ih] = numpy.nansum(tmp)#/len(valid[0])
848 847 '''
849 848 # print('##########################################################')
850 849 print("Removing fake coherent echoes (at least 4 points around the point)")
851 850
852 851 val_spectra = numpy.sum(val_spc,0)
853 852 val_cspectra = numpy.sum(val_cspc,0)
854 853
855 854 val_spectra = self.REM_ISOLATED_POINTS(val_spectra,4)
856 855 val_cspectra = self.REM_ISOLATED_POINTS(val_cspectra,4)
857 856
858 857 for i in range(nChan):
859 858 for j in range(nProf):
860 859 for k in range(nHeights):
861 860 if numpy.isfinite(val_spectra[i,j,k]) and val_spectra[i,j,k] < 1 :
862 861 val_spc[:,i,j,k] = 0.0
863 862 for i in range(nPairs):
864 863 for j in range(nProf):
865 864 for k in range(nHeights):
866 865 if numpy.isfinite(val_cspectra[i,j,k]) and val_cspectra[i,j,k] < 1 :
867 866 val_cspc[:,i,j,k] = 0.0
868 867
869 868 # val_spc = numpy.reshape(val_spc, (len(spectra[:,0,0,0]),nProf*nHeights*nChan))
870 869 # if numpy.isfinite(val_spectra)==str(True):
871 870 # noval = (val_spectra<1).nonzero()
872 871 # if len(noval) > 0:
873 872 # val_spc[:,noval] = 0.0
874 873 # val_spc = numpy.reshape(val_spc, (149,nChan,nProf,nHeights))
875 874
876 875 #val_cspc = numpy.reshape(val_spc, (149,nChan*nHeights*nProf))
877 876 #if numpy.isfinite(val_cspectra)==str(True):
878 877 # noval = (val_cspectra<1).nonzero()
879 878 # if len(noval) > 0:
880 879 # val_cspc[:,noval] = 0.0
881 880 # val_cspc = numpy.reshape(val_cspc, (149,nChan,nProf,nHeights))
882 881 tmp_sat_spectra = spectra.copy()
883 882 tmp_sat_spectra = tmp_sat_spectra*numpy.nan
884 883 tmp_sat_cspectra = cspectra.copy()
885 884 tmp_sat_cspectra = tmp_sat_cspectra*numpy.nan
886 885 '''
887 886 # fig = plt.figure(figsize=(6,5))
888 887 # left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
889 888 # ax = fig.add_axes([left, bottom, width, height])
890 889 # cp = ax.contour(10*numpy.log10(numpy.absolute(spectra[0,0,:,:])))
891 890 # ax.clabel(cp, inline=True,fontsize=10)
892 891 # plt.show()
893 892 '''
894 893 val = (val_spc > 0).nonzero()
895 894 if len(val[0]) > 0:
896 895 tmp_sat_spectra[val] = in_sat_spectra[val]
897 896 val = (val_cspc > 0).nonzero()
898 897 if len(val[0]) > 0:
899 898 tmp_sat_cspectra[val] = in_sat_cspectra[val]
900 899
901 900 print("Getting average of the spectra and cross-spectra from incoherent echoes 2")
902 901 sat_spectra = numpy.zeros((nChan,nProf,nHeights), dtype=float)
903 902 sat_cspectra = numpy.zeros((nPairs,nProf,nHeights), dtype=complex)
904 903 for ih in range(nHeights):
905 904 for ifreq in range(nProf):
906 905 for ich in range(nChan):
907 906 tmp = numpy.squeeze(tmp_sat_spectra[:,ich,ifreq,ih])
908 907 valid = (numpy.isfinite(tmp)).nonzero()
909 908 if len(valid[0]) > 0:
910 909 sat_spectra[ich,ifreq,ih] = numpy.nansum(tmp)/len(valid[0])
911 910
912 911 for icr in range(nPairs):
913 912 tmp = numpy.squeeze(tmp_sat_cspectra[:,icr,ifreq,ih])
914 913 valid = (numpy.isfinite(tmp)).nonzero()
915 914 if len(valid[0]) > 0:
916 915 sat_cspectra[icr,ifreq,ih] = numpy.nansum(tmp)/len(valid[0])
917 916 '''
918 917 #self.__dataReady= True
919 918 #sat_spectra, sat_cspectra= sat_spectra, sat_cspectra
920 919 #if not self.__dataReady:
921 920 #return None, None
922 921 #return out_spectra, out_cspectra ,sat_spectra,sat_cspectra
923 922 return out_spectra, out_cspectra
924 923
925 924 def REM_ISOLATED_POINTS(self,array,rth):
926 925 # import matplotlib.pyplot as plt
927 926 if rth == None :
928 927 rth = 4
929 928 print("REM ISO")
930 929 num_prof = len(array[0,:,0])
931 930 num_hei = len(array[0,0,:])
932 931 n2d = len(array[:,0,0])
933 932
934 933 for ii in range(n2d) :
935 934 #print ii,n2d
936 935 tmp = array[ii,:,:]
937 936 #print tmp.shape, array[ii,101,:],array[ii,102,:]
938 937
939 938 # fig = plt.figure(figsize=(6,5))
940 939 # left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
941 940 # ax = fig.add_axes([left, bottom, width, height])
942 941 # x = range(num_prof)
943 942 # y = range(num_hei)
944 943 # cp = ax.contour(y,x,tmp)
945 944 # ax.clabel(cp, inline=True,fontsize=10)
946 945 # plt.show()
947 946
948 947 #indxs = WHERE(FINITE(tmp) AND tmp GT 0,cindxs)
949 948 tmp = numpy.reshape(tmp,num_prof*num_hei)
950 949 indxs1 = (numpy.isfinite(tmp)==True).nonzero()
951 950 indxs2 = (tmp > 0).nonzero()
952 951
953 952 indxs1 = (indxs1[0])
954 953 indxs2 = indxs2[0]
955 954 #indxs1 = numpy.array(indxs1[0])
956 955 #indxs2 = numpy.array(indxs2[0])
957 956 indxs = None
958 957 #print indxs1 , indxs2
959 958 for iv in range(len(indxs2)):
960 959 indv = numpy.array((indxs1 == indxs2[iv]).nonzero())
961 960 #print len(indxs2), indv
962 961 if len(indv[0]) > 0 :
963 962 indxs = numpy.concatenate((indxs,indxs2[iv]), axis=None)
964 963 # print indxs
965 964 indxs = indxs[1:]
966 965 #print(indxs, len(indxs))
967 966 if len(indxs) < 4 :
968 967 array[ii,:,:] = 0.
969 968 return
970 969
971 970 xpos = numpy.mod(indxs ,num_hei)
972 971 ypos = (indxs / num_hei)
973 972 sx = numpy.argsort(xpos) # Ordering respect to "x" (time)
974 973 #print sx
975 974 xpos = xpos[sx]
976 975 ypos = ypos[sx]
977 976
978 977 # *********************************** Cleaning isolated points **********************************
979 978 ic = 0
980 979 while True :
981 980 r = numpy.sqrt(list(numpy.power((xpos[ic]-xpos),2)+ numpy.power((ypos[ic]-ypos),2)))
982 981 #no_coh = WHERE(FINITE(r) AND (r LE rth),cno_coh)
983 982 #plt.plot(r)
984 983 #plt.show()
985 984 no_coh1 = (numpy.isfinite(r)==True).nonzero()
986 985 no_coh2 = (r <= rth).nonzero()
987 986 #print r, no_coh1, no_coh2
988 987 no_coh1 = numpy.array(no_coh1[0])
989 988 no_coh2 = numpy.array(no_coh2[0])
990 989 no_coh = None
991 990 #print valid1 , valid2
992 991 for iv in range(len(no_coh2)):
993 992 indv = numpy.array((no_coh1 == no_coh2[iv]).nonzero())
994 993 if len(indv[0]) > 0 :
995 994 no_coh = numpy.concatenate((no_coh,no_coh2[iv]), axis=None)
996 995 no_coh = no_coh[1:]
997 996 #print len(no_coh), no_coh
998 997 if len(no_coh) < 4 :
999 998 #print xpos[ic], ypos[ic], ic
1000 999 # plt.plot(r)
1001 1000 # plt.show()
1002 1001 xpos[ic] = numpy.nan
1003 1002 ypos[ic] = numpy.nan
1004 1003
1005 1004 ic = ic + 1
1006 1005 if (ic == len(indxs)) :
1007 1006 break
1008 1007 #print( xpos, ypos)
1009 1008
1010 1009 indxs = (numpy.isfinite(list(xpos))==True).nonzero()
1011 1010 #print indxs[0]
1012 1011 if len(indxs[0]) < 4 :
1013 1012 array[ii,:,:] = 0.
1014 1013 return
1015 1014
1016 1015 xpos = xpos[indxs[0]]
1017 1016 ypos = ypos[indxs[0]]
1018 1017 for i in range(0,len(ypos)):
1019 1018 ypos[i]=int(ypos[i])
1020 1019 junk = tmp
1021 1020 tmp = junk*0.0
1022 1021
1023 1022 tmp[list(xpos + (ypos*num_hei))] = junk[list(xpos + (ypos*num_hei))]
1024 1023 array[ii,:,:] = numpy.reshape(tmp,(num_prof,num_hei))
1025 1024
1026 1025 #print array.shape
1027 1026 #tmp = numpy.reshape(tmp,(num_prof,num_hei))
1028 1027 #print tmp.shape
1029 1028
1030 1029 # fig = plt.figure(figsize=(6,5))
1031 1030 # left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
1032 1031 # ax = fig.add_axes([left, bottom, width, height])
1033 1032 # x = range(num_prof)
1034 1033 # y = range(num_hei)
1035 1034 # cp = ax.contour(y,x,array[ii,:,:])
1036 1035 # ax.clabel(cp, inline=True,fontsize=10)
1037 1036 # plt.show()
1038 1037 return array
1039 1038
1040 1039 class removeInterference(Operation):
1041 1040
1042 1041 def removeInterference2(self):
1043 1042
1044 1043 cspc = self.dataOut.data_cspc
1045 1044 spc = self.dataOut.data_spc
1046 1045 Heights = numpy.arange(cspc.shape[2])
1047 1046 realCspc = numpy.abs(cspc)
1048 1047
1049 1048 for i in range(cspc.shape[0]):
1050 1049 LinePower= numpy.sum(realCspc[i], axis=0)
1051 1050 Threshold = numpy.amax(LinePower)-numpy.sort(LinePower)[len(Heights)-int(len(Heights)*0.1)]
1052 1051 SelectedHeights = Heights[ numpy.where( LinePower < Threshold ) ]
1053 1052 InterferenceSum = numpy.sum( realCspc[i,:,SelectedHeights], axis=0 )
1054 1053 InterferenceThresholdMin = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.98)]
1055 1054 InterferenceThresholdMax = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.99)]
1056 1055
1057 1056
1058 1057 InterferenceRange = numpy.where( ([InterferenceSum > InterferenceThresholdMin]))# , InterferenceSum < InterferenceThresholdMax]) )
1059 1058 #InterferenceRange = numpy.where( ([InterferenceRange < InterferenceThresholdMax]))
1060 1059 if len(InterferenceRange)<int(cspc.shape[1]*0.3):
1061 1060 cspc[i,InterferenceRange,:] = numpy.NaN
1062 1061
1063 1062 self.dataOut.data_cspc = cspc
1064 1063
1065 1064 def removeInterference(self, interf = 2, hei_interf = None, nhei_interf = None, offhei_interf = None):
1066 1065
1067 1066 jspectra = self.dataOut.data_spc
1068 1067 jcspectra = self.dataOut.data_cspc
1069 1068 jnoise = self.dataOut.getNoise()
1070 1069 num_incoh = self.dataOut.nIncohInt
1071 1070
1072 1071 num_channel = jspectra.shape[0]
1073 1072 num_prof = jspectra.shape[1]
1074 1073 num_hei = jspectra.shape[2]
1075 1074
1076 1075 # hei_interf
1077 1076 if hei_interf is None:
1078 1077 count_hei = int(num_hei / 2)
1079 1078 hei_interf = numpy.asmatrix(list(range(count_hei))) + num_hei - count_hei
1080 1079 hei_interf = numpy.asarray(hei_interf)[0]
1081 1080 # nhei_interf
1082 1081 if (nhei_interf == None):
1083 1082 nhei_interf = 5
1084 1083 if (nhei_interf < 1):
1085 1084 nhei_interf = 1
1086 1085 if (nhei_interf > count_hei):
1087 1086 nhei_interf = count_hei
1088 1087 if (offhei_interf == None):
1089 1088 offhei_interf = 0
1090 1089
1091 1090 ind_hei = list(range(num_hei))
1092 1091 # mask_prof = numpy.asarray(range(num_prof - 2)) + 1
1093 1092 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1
1094 1093 mask_prof = numpy.asarray(list(range(num_prof)))
1095 1094 num_mask_prof = mask_prof.size
1096 1095 comp_mask_prof = [0, num_prof / 2]
1097 1096
1098 1097 # noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal
1099 1098 if (jnoise.size < num_channel or numpy.isnan(jnoise).any()):
1100 1099 jnoise = numpy.nan
1101 1100 noise_exist = jnoise[0] < numpy.Inf
1102 1101
1103 1102 # Subrutina de Remocion de la Interferencia
1104 1103 for ich in range(num_channel):
1105 1104 # Se ordena los espectros segun su potencia (menor a mayor)
1106 1105 power = jspectra[ich, mask_prof, :]
1107 1106 power = power[:, hei_interf]
1108 1107 power = power.sum(axis=0)
1109 1108 psort = power.ravel().argsort()
1110 1109
1111 1110 # Se estima la interferencia promedio en los Espectros de Potencia empleando
1112 1111 junkspc_interf = jspectra[ich, :, hei_interf[psort[list(range(
1113 1112 offhei_interf, nhei_interf + offhei_interf))]]]
1114 1113
1115 1114 if noise_exist:
1116 1115 # tmp_noise = jnoise[ich] / num_prof
1117 1116 tmp_noise = jnoise[ich]
1118 1117 junkspc_interf = junkspc_interf - tmp_noise
1119 1118 #junkspc_interf[:,comp_mask_prof] = 0
1120 1119
1121 1120 jspc_interf = junkspc_interf.sum(axis=0) / nhei_interf
1122 1121 jspc_interf = jspc_interf.transpose()
1123 1122 # Calculando el espectro de interferencia promedio
1124 1123 noiseid = numpy.where(
1125 1124 jspc_interf <= tmp_noise / numpy.sqrt(num_incoh))
1126 1125 noiseid = noiseid[0]
1127 1126 cnoiseid = noiseid.size
1128 1127 interfid = numpy.where(
1129 1128 jspc_interf > tmp_noise / numpy.sqrt(num_incoh))
1130 1129 interfid = interfid[0]
1131 1130 cinterfid = interfid.size
1132 1131
1133 1132 if (cnoiseid > 0):
1134 1133 jspc_interf[noiseid] = 0
1135 1134
1136 1135 # Expandiendo los perfiles a limpiar
1137 1136 if (cinterfid > 0):
1138 1137 new_interfid = (
1139 1138 numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof) % num_prof
1140 1139 new_interfid = numpy.asarray(new_interfid)
1141 1140 new_interfid = {x for x in new_interfid}
1142 1141 new_interfid = numpy.array(list(new_interfid))
1143 1142 new_cinterfid = new_interfid.size
1144 1143 else:
1145 1144 new_cinterfid = 0
1146 1145
1147 1146 for ip in range(new_cinterfid):
1148 1147 ind = junkspc_interf[:, new_interfid[ip]].ravel().argsort()
1149 1148 jspc_interf[new_interfid[ip]
1150 1149 ] = junkspc_interf[ind[nhei_interf // 2], new_interfid[ip]]
1151 1150
1152 1151 jspectra[ich, :, ind_hei] = jspectra[ich, :,
1153 1152 ind_hei] - jspc_interf # Corregir indices
1154 1153
1155 1154 # Removiendo la interferencia del punto de mayor interferencia
1156 1155 ListAux = jspc_interf[mask_prof].tolist()
1157 1156 maxid = ListAux.index(max(ListAux))
1158 1157
1159 1158 if cinterfid > 0:
1160 1159 for ip in range(cinterfid * (interf == 2) - 1):
1161 1160 ind = (jspectra[ich, interfid[ip], :] < tmp_noise *
1162 1161 (1 + 1 / numpy.sqrt(num_incoh))).nonzero()
1163 1162 cind = len(ind)
1164 1163
1165 1164 if (cind > 0):
1166 1165 jspectra[ich, interfid[ip], ind] = tmp_noise * \
1167 1166 (1 + (numpy.random.uniform(cind) - 0.5) /
1168 1167 numpy.sqrt(num_incoh))
1169 1168
1170 1169 ind = numpy.array([-2, -1, 1, 2])
1171 1170 xx = numpy.zeros([4, 4])
1172 1171
1173 1172 for id1 in range(4):
1174 1173 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
1175 1174
1176 1175 xx_inv = numpy.linalg.inv(xx)
1177 1176 xx = xx_inv[:, 0]
1178 1177 ind = (ind + maxid + num_mask_prof) % num_mask_prof
1179 1178 yy = jspectra[ich, mask_prof[ind], :]
1180 1179 jspectra[ich, mask_prof[maxid], :] = numpy.dot(
1181 1180 yy.transpose(), xx)
1182 1181
1183 1182 indAux = (jspectra[ich, :, :] < tmp_noise *
1184 1183 (1 - 1 / numpy.sqrt(num_incoh))).nonzero()
1185 1184 jspectra[ich, indAux[0], indAux[1]] = tmp_noise * \
1186 1185 (1 - 1 / numpy.sqrt(num_incoh))
1187 1186
1188 1187 # Remocion de Interferencia en el Cross Spectra
1189 1188 if jcspectra is None:
1190 1189 return jspectra, jcspectra
1191 1190 num_pairs = int(jcspectra.size / (num_prof * num_hei))
1192 1191 jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei)
1193 1192
1194 1193 for ip in range(num_pairs):
1195 1194
1196 1195 #-------------------------------------------
1197 1196
1198 1197 cspower = numpy.abs(jcspectra[ip, mask_prof, :])
1199 1198 cspower = cspower[:, hei_interf]
1200 1199 cspower = cspower.sum(axis=0)
1201 1200
1202 1201 cspsort = cspower.ravel().argsort()
1203 1202 junkcspc_interf = jcspectra[ip, :, hei_interf[cspsort[list(range(
1204 1203 offhei_interf, nhei_interf + offhei_interf))]]]
1205 1204 junkcspc_interf = junkcspc_interf.transpose()
1206 1205 jcspc_interf = junkcspc_interf.sum(axis=1) / nhei_interf
1207 1206
1208 1207 ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort()
1209 1208
1210 1209 median_real = int(numpy.median(numpy.real(
1211 1210 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1212 1211 median_imag = int(numpy.median(numpy.imag(
1213 1212 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1214 1213 comp_mask_prof = [int(e) for e in comp_mask_prof]
1215 1214 junkcspc_interf[comp_mask_prof, :] = numpy.complex(
1216 1215 median_real, median_imag)
1217 1216
1218 1217 for iprof in range(num_prof):
1219 1218 ind = numpy.abs(junkcspc_interf[iprof, :]).ravel().argsort()
1220 1219 jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf // 2]]
1221 1220
1222 1221 # Removiendo la Interferencia
1223 1222 jcspectra[ip, :, ind_hei] = jcspectra[ip,
1224 1223 :, ind_hei] - jcspc_interf
1225 1224
1226 1225 ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist()
1227 1226 maxid = ListAux.index(max(ListAux))
1228 1227
1229 1228 ind = numpy.array([-2, -1, 1, 2])
1230 1229 xx = numpy.zeros([4, 4])
1231 1230
1232 1231 for id1 in range(4):
1233 1232 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
1234 1233
1235 1234 xx_inv = numpy.linalg.inv(xx)
1236 1235 xx = xx_inv[:, 0]
1237 1236
1238 1237 ind = (ind + maxid + num_mask_prof) % num_mask_prof
1239 1238 yy = jcspectra[ip, mask_prof[ind], :]
1240 1239 jcspectra[ip, mask_prof[maxid], :] = numpy.dot(yy.transpose(), xx)
1241 1240
1242 1241 # Guardar Resultados
1243 1242 self.dataOut.data_spc = jspectra
1244 1243 self.dataOut.data_cspc = jcspectra
1245 1244
1246 1245 return 1
1247 1246
1248 1247 def run(self, dataOut, interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None, mode=1):
1249 1248
1250 1249 self.dataOut = dataOut
1251 1250
1252 1251 if mode == 1:
1253 1252 self.removeInterference(interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None)
1254 1253 elif mode == 2:
1255 1254 self.removeInterference2()
1256 1255
1257 1256 return self.dataOut
1258 1257
1259 1258
1260 1259 class IncohInt(Operation):
1261 1260
1262 1261 __profIndex = 0
1263 1262 __withOverapping = False
1264 1263
1265 1264 __byTime = False
1266 1265 __initime = None
1267 1266 __lastdatatime = None
1268 1267 __integrationtime = None
1269 1268
1270 1269 __buffer_spc = None
1271 1270 __buffer_cspc = None
1272 1271 __buffer_dc = None
1273 1272
1274 1273 __dataReady = False
1275 1274
1276 1275 __timeInterval = None
1277 1276
1278 1277 n = None
1279 1278
1280 1279 def __init__(self):
1281 1280
1282 1281 Operation.__init__(self)
1283 1282
1284 1283 def setup(self, n=None, timeInterval=None, overlapping=False):
1285 1284 """
1286 1285 Set the parameters of the integration class.
1287 1286
1288 1287 Inputs:
1289 1288
1290 1289 n : Number of coherent integrations
1291 1290 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1292 1291 overlapping :
1293 1292
1294 1293 """
1295 1294
1296 1295 self.__initime = None
1297 1296 self.__lastdatatime = 0
1298 1297
1299 1298 self.__buffer_spc = 0
1300 1299 self.__buffer_cspc = 0
1301 1300 self.__buffer_dc = 0
1302 1301
1303 1302 self.__profIndex = 0
1304 1303 self.__dataReady = False
1305 1304 self.__byTime = False
1306 1305
1307 1306 if n is None and timeInterval is None:
1308 1307 raise ValueError("n or timeInterval should be specified ...")
1309 1308
1310 1309 if n is not None:
1311 1310 self.n = int(n)
1312 1311 else:
1313 1312
1314 1313 self.__integrationtime = int(timeInterval)
1315 1314 self.n = None
1316 1315 self.__byTime = True
1317 1316
1318 1317 def putData(self, data_spc, data_cspc, data_dc):
1319 1318 """
1320 1319 Add a profile to the __buffer_spc and increase in one the __profileIndex
1321 1320
1322 1321 """
1323 1322
1324 1323 self.__buffer_spc += data_spc
1325 1324
1326 1325 if data_cspc is None:
1327 1326 self.__buffer_cspc = None
1328 1327 else:
1329 1328 self.__buffer_cspc += data_cspc
1330 1329
1331 1330 if data_dc is None:
1332 1331 self.__buffer_dc = None
1333 1332 else:
1334 1333 self.__buffer_dc += data_dc
1335 1334
1336 1335 self.__profIndex += 1
1337 1336
1338 1337 return
1339 1338
1340 1339 def pushData(self):
1341 1340 """
1342 1341 Return the sum of the last profiles and the profiles used in the sum.
1343 1342
1344 1343 Affected:
1345 1344
1346 1345 self.__profileIndex
1347 1346
1348 1347 """
1349 1348
1350 1349 data_spc = self.__buffer_spc
1351 1350 data_cspc = self.__buffer_cspc
1352 1351 data_dc = self.__buffer_dc
1353 1352 n = self.__profIndex
1354 1353
1355 1354 self.__buffer_spc = 0
1356 1355 self.__buffer_cspc = 0
1357 1356 self.__buffer_dc = 0
1358 1357 self.__profIndex = 0
1359 1358
1360 1359 return data_spc, data_cspc, data_dc, n
1361 1360
1362 1361 def byProfiles(self, *args):
1363 1362
1364 1363 self.__dataReady = False
1365 1364 avgdata_spc = None
1366 1365 avgdata_cspc = None
1367 1366 avgdata_dc = None
1368 1367
1369 1368 self.putData(*args)
1370 1369
1371 1370 if self.__profIndex == self.n:
1372 1371
1373 1372 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1374 1373 self.n = n
1375 1374 self.__dataReady = True
1376 1375
1377 1376 return avgdata_spc, avgdata_cspc, avgdata_dc
1378 1377
1379 1378 def byTime(self, datatime, *args):
1380 1379
1381 1380 self.__dataReady = False
1382 1381 avgdata_spc = None
1383 1382 avgdata_cspc = None
1384 1383 avgdata_dc = None
1385 1384
1386 1385 self.putData(*args)
1387 1386
1388 1387 if (datatime - self.__initime) >= self.__integrationtime:
1389 1388 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1390 1389 self.n = n
1391 1390 self.__dataReady = True
1392 1391
1393 1392 return avgdata_spc, avgdata_cspc, avgdata_dc
1394 1393
1395 1394 def integrate(self, datatime, *args):
1396 1395
1397 1396 if self.__profIndex == 0:
1398 1397 self.__initime = datatime
1399 1398
1400 1399 if self.__byTime:
1401 1400 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1402 1401 datatime, *args)
1403 1402 else:
1404 1403 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1405 1404
1406 1405 if not self.__dataReady:
1407 1406 return None, None, None, None
1408 1407
1409 1408 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1410 1409
1411 1410 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
1412 1411 if n == 1:
1413 1412 return dataOut
1414 1413
1415 1414 dataOut.flagNoData = True
1416 1415
1417 1416 if not self.isConfig:
1418 1417 self.setup(n, timeInterval, overlapping)
1419 1418 self.isConfig = True
1420 1419
1421 1420 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1422 1421 dataOut.data_spc,
1423 1422 dataOut.data_cspc,
1424 1423 dataOut.data_dc)
1425 1424
1426 1425 if self.__dataReady:
1427 1426
1428 1427 dataOut.data_spc = avgdata_spc
1429 1428 dataOut.data_cspc = avgdata_cspc
1430 1429 dataOut.data_dc = avgdata_dc
1431 1430 dataOut.nIncohInt *= self.n
1432 1431 dataOut.utctime = avgdatatime
1433 1432 dataOut.flagNoData = False
1434 1433
1435 1434 return dataOut
1436 1435
1437 1436 class dopplerFlip(Operation):
1438 1437
1439 1438 def run(self, dataOut):
1440 1439 # arreglo 1: (num_chan, num_profiles, num_heights)
1441 1440 self.dataOut = dataOut
1442 1441 # JULIA-oblicua, indice 2
1443 1442 # arreglo 2: (num_profiles, num_heights)
1444 1443 jspectra = self.dataOut.data_spc[2]
1445 1444 jspectra_tmp = numpy.zeros(jspectra.shape)
1446 1445 num_profiles = jspectra.shape[0]
1447 1446 freq_dc = int(num_profiles / 2)
1448 1447 # Flip con for
1449 1448 for j in range(num_profiles):
1450 1449 jspectra_tmp[num_profiles-j-1]= jspectra[j]
1451 1450 # Intercambio perfil de DC con perfil inmediato anterior
1452 1451 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
1453 1452 jspectra_tmp[freq_dc]= jspectra[freq_dc]
1454 1453 # canal modificado es re-escrito en el arreglo de canales
1455 1454 self.dataOut.data_spc[2] = jspectra_tmp
1456 1455
1457 1456 return self.dataOut
@@ -1,1624 +1,1624
1 1 import sys
2 2 import numpy,math
3 3 from scipy import interpolate
4 4 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
5 5 from schainpy.model.data.jrodata import Voltage,hildebrand_sekhon
6 6 from schainpy.utils import log
7 7 from time import time
8 8
9 9
10 10
11 11 class VoltageProc(ProcessingUnit):
12 12
13 13 def __init__(self):
14 14
15 15 ProcessingUnit.__init__(self)
16 16
17 17 self.dataOut = Voltage()
18 18 self.flip = 1
19 19 self.setupReq = False
20 20
21 21 def run(self):
22 22
23 23 if self.dataIn.type == 'AMISR':
24 24 self.__updateObjFromAmisrInput()
25 25
26 26 if self.dataIn.type == 'Voltage':
27 27 self.dataOut.copy(self.dataIn)
28 28
29 29 def __updateObjFromAmisrInput(self):
30 30
31 31 self.dataOut.timeZone = self.dataIn.timeZone
32 32 self.dataOut.dstFlag = self.dataIn.dstFlag
33 33 self.dataOut.errorCount = self.dataIn.errorCount
34 34 self.dataOut.useLocalTime = self.dataIn.useLocalTime
35 35
36 36 self.dataOut.flagNoData = self.dataIn.flagNoData
37 37 self.dataOut.data = self.dataIn.data
38 38 self.dataOut.utctime = self.dataIn.utctime
39 39 self.dataOut.channelList = self.dataIn.channelList
40 40 #self.dataOut.timeInterval = self.dataIn.timeInterval
41 41 self.dataOut.heightList = self.dataIn.heightList
42 42 self.dataOut.nProfiles = self.dataIn.nProfiles
43 43
44 44 self.dataOut.nCohInt = self.dataIn.nCohInt
45 45 self.dataOut.ippSeconds = self.dataIn.ippSeconds
46 46 self.dataOut.frequency = self.dataIn.frequency
47 47
48 48 self.dataOut.azimuth = self.dataIn.azimuth
49 49 self.dataOut.zenith = self.dataIn.zenith
50 50
51 51 self.dataOut.beam.codeList = self.dataIn.beam.codeList
52 52 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
53 53 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
54 54
55 55
56 56 class selectChannels(Operation):
57 57
58 58 def run(self, dataOut, channelList):
59 59
60 60 channelIndexList = []
61 61 self.dataOut = dataOut
62 62 for channel in channelList:
63 63 if channel not in self.dataOut.channelList:
64 64 raise ValueError("Channel %d is not in %s" %(channel, str(self.dataOut.channelList)))
65 65
66 66 index = self.dataOut.channelList.index(channel)
67 67 channelIndexList.append(index)
68 68 self.selectChannelsByIndex(channelIndexList)
69 69 return self.dataOut
70 70
71 71 def selectChannelsByIndex(self, channelIndexList):
72 72 """
73 73 Selecciona un bloque de datos en base a canales segun el channelIndexList
74 74
75 75 Input:
76 76 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
77 77
78 78 Affected:
79 79 self.dataOut.data
80 80 self.dataOut.channelIndexList
81 81 self.dataOut.nChannels
82 82 self.dataOut.m_ProcessingHeader.totalSpectra
83 83 self.dataOut.systemHeaderObj.numChannels
84 84 self.dataOut.m_ProcessingHeader.blockSize
85 85
86 86 Return:
87 87 None
88 88 """
89 89
90 90 for channelIndex in channelIndexList:
91 91 if channelIndex not in self.dataOut.channelIndexList:
92 92 raise ValueError("The value %d in channelIndexList is not valid" %channelIndex)
93 93
94 94 if self.dataOut.type == 'Voltage':
95 95 if self.dataOut.flagDataAsBlock:
96 96 """
97 97 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
98 98 """
99 99 data = self.dataOut.data[channelIndexList,:,:]
100 100 else:
101 101 data = self.dataOut.data[channelIndexList,:]
102 102
103 103 self.dataOut.data = data
104 104 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
105 105 self.dataOut.channelList = range(len(channelIndexList))
106 106
107 107 elif self.dataOut.type == 'Spectra':
108 108 data_spc = self.dataOut.data_spc[channelIndexList, :]
109 109 data_dc = self.dataOut.data_dc[channelIndexList, :]
110 110
111 111 self.dataOut.data_spc = data_spc
112 112 self.dataOut.data_dc = data_dc
113 113
114 114 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
115 self.dataOut.channelList = range(len(channelIndexList))
115 self.dataOut.channelList = channelIndexList
116 116 self.__selectPairsByChannel(channelIndexList)
117 117
118 118 return 1
119 119
120 120 def __selectPairsByChannel(self, channelList=None):
121 121
122 122 if channelList == None:
123 123 return
124 124
125 125 pairsIndexListSelected = []
126 126 for pairIndex in self.dataOut.pairsIndexList:
127 127 # First pair
128 128 if self.dataOut.pairsList[pairIndex][0] not in channelList:
129 129 continue
130 130 # Second pair
131 131 if self.dataOut.pairsList[pairIndex][1] not in channelList:
132 132 continue
133 133
134 134 pairsIndexListSelected.append(pairIndex)
135 135
136 136 if not pairsIndexListSelected:
137 137 self.dataOut.data_cspc = None
138 138 self.dataOut.pairsList = []
139 139 return
140 140
141 141 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndexListSelected]
142 142 self.dataOut.pairsList = [self.dataOut.pairsList[i]
143 143 for i in pairsIndexListSelected]
144 144
145 145 return
146 146
147 147 class selectHeights(Operation):
148 148
149 149 def run(self, dataOut, minHei=None, maxHei=None, minIndex=None, maxIndex=None):
150 150 """
151 151 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
152 152 minHei <= height <= maxHei
153 153
154 154 Input:
155 155 minHei : valor minimo de altura a considerar
156 156 maxHei : valor maximo de altura a considerar
157 157
158 158 Affected:
159 159 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
160 160
161 161 Return:
162 162 1 si el metodo se ejecuto con exito caso contrario devuelve 0
163 163 """
164 164
165 165 self.dataOut = dataOut
166 166
167 167 if minHei and maxHei:
168 168
169 169 if (minHei < self.dataOut.heightList[0]):
170 170 minHei = self.dataOut.heightList[0]
171 171
172 172 if (maxHei > self.dataOut.heightList[-1]):
173 173 maxHei = self.dataOut.heightList[-1]
174 174
175 175 minIndex = 0
176 176 maxIndex = 0
177 177 heights = self.dataOut.heightList
178 178
179 179 inda = numpy.where(heights >= minHei)
180 180 indb = numpy.where(heights <= maxHei)
181 181
182 182 try:
183 183 minIndex = inda[0][0]
184 184 except:
185 185 minIndex = 0
186 186
187 187 try:
188 188 maxIndex = indb[0][-1]
189 189 except:
190 190 maxIndex = len(heights)
191 191
192 192 self.selectHeightsByIndex(minIndex, maxIndex)
193 193
194 194 return self.dataOut
195 195
196 196 def selectHeightsByIndex(self, minIndex, maxIndex):
197 197 """
198 198 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
199 199 minIndex <= index <= maxIndex
200 200
201 201 Input:
202 202 minIndex : valor de indice minimo de altura a considerar
203 203 maxIndex : valor de indice maximo de altura a considerar
204 204
205 205 Affected:
206 206 self.dataOut.data
207 207 self.dataOut.heightList
208 208
209 209 Return:
210 210 1 si el metodo se ejecuto con exito caso contrario devuelve 0
211 211 """
212 212
213 213 if self.dataOut.type == 'Voltage':
214 214 if (minIndex < 0) or (minIndex > maxIndex):
215 215 raise ValueError("Height index range (%d,%d) is not valid" % (minIndex, maxIndex))
216 216
217 217 if (maxIndex >= self.dataOut.nHeights):
218 218 maxIndex = self.dataOut.nHeights
219 219
220 220 #voltage
221 221 if self.dataOut.flagDataAsBlock:
222 222 """
223 223 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
224 224 """
225 225 data = self.dataOut.data[:,:, minIndex:maxIndex]
226 226 else:
227 227 data = self.dataOut.data[:, minIndex:maxIndex]
228 228
229 229 # firstHeight = self.dataOut.heightList[minIndex]
230 230
231 231 self.dataOut.data = data
232 232 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex]
233 233
234 234 if self.dataOut.nHeights <= 1:
235 235 raise ValueError("selectHeights: Too few heights. Current number of heights is %d" %(self.dataOut.nHeights))
236 236 elif self.dataOut.type == 'Spectra':
237 237 if (minIndex < 0) or (minIndex > maxIndex):
238 238 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (
239 239 minIndex, maxIndex))
240 240
241 241 if (maxIndex >= self.dataOut.nHeights):
242 242 maxIndex = self.dataOut.nHeights - 1
243 243
244 244 # Spectra
245 245 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
246 246
247 247 data_cspc = None
248 248 if self.dataOut.data_cspc is not None:
249 249 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
250 250
251 251 data_dc = None
252 252 if self.dataOut.data_dc is not None:
253 253 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
254 254
255 255 self.dataOut.data_spc = data_spc
256 256 self.dataOut.data_cspc = data_cspc
257 257 self.dataOut.data_dc = data_dc
258 258
259 259 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
260 260
261 261 return 1
262 262
263 263
264 264 class filterByHeights(Operation):
265 265
266 266 def run(self, dataOut, window):
267 267
268 268 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
269 269
270 270 if window == None:
271 271 window = (dataOut.radarControllerHeaderObj.txA/dataOut.radarControllerHeaderObj.nBaud) / deltaHeight
272 272
273 273 newdelta = deltaHeight * window
274 274 r = dataOut.nHeights % window
275 275 newheights = (dataOut.nHeights-r)/window
276 276
277 277 if newheights <= 1:
278 278 raise ValueError("filterByHeights: Too few heights. Current number of heights is %d and window is %d" %(dataOut.nHeights, window))
279 279
280 280 if dataOut.flagDataAsBlock:
281 281 """
282 282 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
283 283 """
284 284 buffer = dataOut.data[:, :, 0:int(dataOut.nHeights-r)]
285 285 buffer = buffer.reshape(dataOut.nChannels, dataOut.nProfiles, int(dataOut.nHeights/window), window)
286 286 buffer = numpy.sum(buffer,3)
287 287
288 288 else:
289 289 buffer = dataOut.data[:,0:int(dataOut.nHeights-r)]
290 290 buffer = buffer.reshape(dataOut.nChannels,int(dataOut.nHeights/window),int(window))
291 291 buffer = numpy.sum(buffer,2)
292 292
293 293 dataOut.data = buffer
294 294 dataOut.heightList = dataOut.heightList[0] + numpy.arange( newheights )*newdelta
295 295 dataOut.windowOfFilter = window
296 296
297 297 return dataOut
298 298
299 299
300 300 class setH0(Operation):
301 301
302 302 def run(self, dataOut, h0, deltaHeight = None):
303 303
304 304 if not deltaHeight:
305 305 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
306 306
307 307 nHeights = dataOut.nHeights
308 308
309 309 newHeiRange = h0 + numpy.arange(nHeights)*deltaHeight
310 310
311 311 dataOut.heightList = newHeiRange
312 312
313 313 return dataOut
314 314
315 315
316 316 class deFlip(Operation):
317 317
318 318 def run(self, dataOut, channelList = []):
319 319
320 320 data = dataOut.data.copy()
321 321
322 322 if dataOut.flagDataAsBlock:
323 323 flip = self.flip
324 324 profileList = list(range(dataOut.nProfiles))
325 325
326 326 if not channelList:
327 327 for thisProfile in profileList:
328 328 data[:,thisProfile,:] = data[:,thisProfile,:]*flip
329 329 flip *= -1.0
330 330 else:
331 331 for thisChannel in channelList:
332 332 if thisChannel not in dataOut.channelList:
333 333 continue
334 334
335 335 for thisProfile in profileList:
336 336 data[thisChannel,thisProfile,:] = data[thisChannel,thisProfile,:]*flip
337 337 flip *= -1.0
338 338
339 339 self.flip = flip
340 340
341 341 else:
342 342 if not channelList:
343 343 data[:,:] = data[:,:]*self.flip
344 344 else:
345 345 for thisChannel in channelList:
346 346 if thisChannel not in dataOut.channelList:
347 347 continue
348 348
349 349 data[thisChannel,:] = data[thisChannel,:]*self.flip
350 350
351 351 self.flip *= -1.
352 352
353 353 dataOut.data = data
354 354
355 355 return dataOut
356 356
357 357
358 358 class setAttribute(Operation):
359 359 '''
360 360 Set an arbitrary attribute(s) to dataOut
361 361 '''
362 362
363 363 def __init__(self):
364 364
365 365 Operation.__init__(self)
366 366 self._ready = False
367 367
368 368 def run(self, dataOut, **kwargs):
369 369
370 370 for key, value in kwargs.items():
371 371 setattr(dataOut, key, value)
372 372
373 373 return dataOut
374 374
375 375
376 376 @MPDecorator
377 377 class printAttribute(Operation):
378 378 '''
379 379 Print an arbitrary attribute of dataOut
380 380 '''
381 381
382 382 def __init__(self):
383 383
384 384 Operation.__init__(self)
385 385
386 386 def run(self, dataOut, attributes):
387 387
388 388 if isinstance(attributes, str):
389 389 attributes = [attributes]
390 390 for attr in attributes:
391 391 if hasattr(dataOut, attr):
392 392 log.log(getattr(dataOut, attr), attr)
393 393
394 394
395 395 class interpolateHeights(Operation):
396 396
397 397 def run(self, dataOut, topLim, botLim):
398 398 #69 al 72 para julia
399 399 #82-84 para meteoros
400 400 if len(numpy.shape(dataOut.data))==2:
401 401 sampInterp = (dataOut.data[:,botLim-1] + dataOut.data[:,topLim+1])/2
402 402 sampInterp = numpy.transpose(numpy.tile(sampInterp,(topLim-botLim + 1,1)))
403 403 #dataOut.data[:,botLim:limSup+1] = sampInterp
404 404 dataOut.data[:,botLim:topLim+1] = sampInterp
405 405 else:
406 406 nHeights = dataOut.data.shape[2]
407 407 x = numpy.hstack((numpy.arange(botLim),numpy.arange(topLim+1,nHeights)))
408 408 y = dataOut.data[:,:,list(range(botLim))+list(range(topLim+1,nHeights))]
409 409 f = interpolate.interp1d(x, y, axis = 2)
410 410 xnew = numpy.arange(botLim,topLim+1)
411 411 ynew = f(xnew)
412 412 dataOut.data[:,:,botLim:topLim+1] = ynew
413 413
414 414 return dataOut
415 415
416 416
417 417 class CohInt(Operation):
418 418
419 419 isConfig = False
420 420 __profIndex = 0
421 421 __byTime = False
422 422 __initime = None
423 423 __lastdatatime = None
424 424 __integrationtime = None
425 425 __buffer = None
426 426 __bufferStride = []
427 427 __dataReady = False
428 428 __profIndexStride = 0
429 429 __dataToPutStride = False
430 430 n = None
431 431
432 432 def __init__(self, **kwargs):
433 433
434 434 Operation.__init__(self, **kwargs)
435 435
436 436 def setup(self, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False):
437 437 """
438 438 Set the parameters of the integration class.
439 439
440 440 Inputs:
441 441
442 442 n : Number of coherent integrations
443 443 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
444 444 overlapping :
445 445 """
446 446
447 447 self.__initime = None
448 448 self.__lastdatatime = 0
449 449 self.__buffer = None
450 450 self.__dataReady = False
451 451 self.byblock = byblock
452 452 self.stride = stride
453 453
454 454 if n == None and timeInterval == None:
455 455 raise ValueError("n or timeInterval should be specified ...")
456 456
457 457 if n != None:
458 458 self.n = n
459 459 self.__byTime = False
460 460 else:
461 461 self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line
462 462 self.n = 9999
463 463 self.__byTime = True
464 464
465 465 if overlapping:
466 466 self.__withOverlapping = True
467 467 self.__buffer = None
468 468 else:
469 469 self.__withOverlapping = False
470 470 self.__buffer = 0
471 471
472 472 self.__profIndex = 0
473 473
474 474 def putData(self, data):
475 475
476 476 """
477 477 Add a profile to the __buffer and increase in one the __profileIndex
478 478
479 479 """
480 480
481 481 if not self.__withOverlapping:
482 482 self.__buffer += data.copy()
483 483 self.__profIndex += 1
484 484 return
485 485
486 486 #Overlapping data
487 487 nChannels, nHeis = data.shape
488 488 data = numpy.reshape(data, (1, nChannels, nHeis))
489 489
490 490 #If the buffer is empty then it takes the data value
491 491 if self.__buffer is None:
492 492 self.__buffer = data
493 493 self.__profIndex += 1
494 494 return
495 495
496 496 #If the buffer length is lower than n then stakcing the data value
497 497 if self.__profIndex < self.n:
498 498 self.__buffer = numpy.vstack((self.__buffer, data))
499 499 self.__profIndex += 1
500 500 return
501 501
502 502 #If the buffer length is equal to n then replacing the last buffer value with the data value
503 503 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
504 504 self.__buffer[self.n-1] = data
505 505 self.__profIndex = self.n
506 506 return
507 507
508 508
509 509 def pushData(self):
510 510 """
511 511 Return the sum of the last profiles and the profiles used in the sum.
512 512
513 513 Affected:
514 514
515 515 self.__profileIndex
516 516
517 517 """
518 518
519 519 if not self.__withOverlapping:
520 520 data = self.__buffer
521 521 n = self.__profIndex
522 522
523 523 self.__buffer = 0
524 524 self.__profIndex = 0
525 525
526 526 return data, n
527 527
528 528 #Integration with Overlapping
529 529 data = numpy.sum(self.__buffer, axis=0)
530 530 # print data
531 531 # raise
532 532 n = self.__profIndex
533 533
534 534 return data, n
535 535
536 536 def byProfiles(self, data):
537 537
538 538 self.__dataReady = False
539 539 avgdata = None
540 540 # n = None
541 541 # print data
542 542 # raise
543 543 self.putData(data)
544 544
545 545 if self.__profIndex == self.n:
546 546 avgdata, n = self.pushData()
547 547 self.__dataReady = True
548 548
549 549 return avgdata
550 550
551 551 def byTime(self, data, datatime):
552 552
553 553 self.__dataReady = False
554 554 avgdata = None
555 555 n = None
556 556
557 557 self.putData(data)
558 558
559 559 if (datatime - self.__initime) >= self.__integrationtime:
560 560 avgdata, n = self.pushData()
561 561 self.n = n
562 562 self.__dataReady = True
563 563
564 564 return avgdata
565 565
566 566 def integrateByStride(self, data, datatime):
567 567 # print data
568 568 if self.__profIndex == 0:
569 569 self.__buffer = [[data.copy(), datatime]]
570 570 else:
571 571 self.__buffer.append([data.copy(),datatime])
572 572 self.__profIndex += 1
573 573 self.__dataReady = False
574 574
575 575 if self.__profIndex == self.n * self.stride :
576 576 self.__dataToPutStride = True
577 577 self.__profIndexStride = 0
578 578 self.__profIndex = 0
579 579 self.__bufferStride = []
580 580 for i in range(self.stride):
581 581 current = self.__buffer[i::self.stride]
582 582 data = numpy.sum([t[0] for t in current], axis=0)
583 583 avgdatatime = numpy.average([t[1] for t in current])
584 584 # print data
585 585 self.__bufferStride.append((data, avgdatatime))
586 586
587 587 if self.__dataToPutStride:
588 588 self.__dataReady = True
589 589 self.__profIndexStride += 1
590 590 if self.__profIndexStride == self.stride:
591 591 self.__dataToPutStride = False
592 592 # print self.__bufferStride[self.__profIndexStride - 1]
593 593 # raise
594 594 return self.__bufferStride[self.__profIndexStride - 1]
595 595
596 596
597 597 return None, None
598 598
599 599 def integrate(self, data, datatime=None):
600 600
601 601 if self.__initime == None:
602 602 self.__initime = datatime
603 603
604 604 if self.__byTime:
605 605 avgdata = self.byTime(data, datatime)
606 606 else:
607 607 avgdata = self.byProfiles(data)
608 608
609 609
610 610 self.__lastdatatime = datatime
611 611
612 612 if avgdata is None:
613 613 return None, None
614 614
615 615 avgdatatime = self.__initime
616 616
617 617 deltatime = datatime - self.__lastdatatime
618 618
619 619 if not self.__withOverlapping:
620 620 self.__initime = datatime
621 621 else:
622 622 self.__initime += deltatime
623 623
624 624 return avgdata, avgdatatime
625 625
626 626 def integrateByBlock(self, dataOut):
627 627
628 628 times = int(dataOut.data.shape[1]/self.n)
629 629 avgdata = numpy.zeros((dataOut.nChannels, times, dataOut.nHeights), dtype=numpy.complex)
630 630
631 631 id_min = 0
632 632 id_max = self.n
633 633
634 634 for i in range(times):
635 635 junk = dataOut.data[:,id_min:id_max,:]
636 636 avgdata[:,i,:] = junk.sum(axis=1)
637 637 id_min += self.n
638 638 id_max += self.n
639 639
640 640 timeInterval = dataOut.ippSeconds*self.n
641 641 avgdatatime = (times - 1) * timeInterval + dataOut.utctime
642 642 self.__dataReady = True
643 643 return avgdata, avgdatatime
644 644
645 645 def run(self, dataOut, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False, **kwargs):
646 646
647 647 if not self.isConfig:
648 648 self.setup(n=n, stride=stride, timeInterval=timeInterval, overlapping=overlapping, byblock=byblock, **kwargs)
649 649 self.isConfig = True
650 650
651 651 if dataOut.flagDataAsBlock:
652 652 """
653 653 Si la data es leida por bloques, dimension = [nChannels, nProfiles, nHeis]
654 654 """
655 655 avgdata, avgdatatime = self.integrateByBlock(dataOut)
656 656 dataOut.nProfiles /= self.n
657 657 else:
658 658 if stride is None:
659 659 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
660 660 else:
661 661 avgdata, avgdatatime = self.integrateByStride(dataOut.data, dataOut.utctime)
662 662
663 663
664 664 # dataOut.timeInterval *= n
665 665 dataOut.flagNoData = True
666 666
667 667 if self.__dataReady:
668 668 dataOut.data = avgdata
669 669 if not dataOut.flagCohInt:
670 670 dataOut.nCohInt *= self.n
671 671 dataOut.flagCohInt = True
672 672 dataOut.utctime = avgdatatime
673 673 # print avgdata, avgdatatime
674 674 # raise
675 675 # dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
676 676 dataOut.flagNoData = False
677 677 return dataOut
678 678
679 679 class Decoder(Operation):
680 680
681 681 isConfig = False
682 682 __profIndex = 0
683 683
684 684 code = None
685 685
686 686 nCode = None
687 687 nBaud = None
688 688
689 689 def __init__(self, **kwargs):
690 690
691 691 Operation.__init__(self, **kwargs)
692 692
693 693 self.times = None
694 694 self.osamp = None
695 695 # self.__setValues = False
696 696 self.isConfig = False
697 697 self.setupReq = False
698 698 def setup(self, code, osamp, dataOut):
699 699
700 700 self.__profIndex = 0
701 701
702 702 self.code = code
703 703
704 704 self.nCode = len(code)
705 705 self.nBaud = len(code[0])
706 706 if (osamp != None) and (osamp >1):
707 707 self.osamp = osamp
708 708 self.code = numpy.repeat(code, repeats=self.osamp, axis=1)
709 709 self.nBaud = self.nBaud*self.osamp
710 710
711 711 self.__nChannels = dataOut.nChannels
712 712 self.__nProfiles = dataOut.nProfiles
713 713 self.__nHeis = dataOut.nHeights
714 714
715 715 if self.__nHeis < self.nBaud:
716 716 raise ValueError('Number of heights (%d) should be greater than number of bauds (%d)' %(self.__nHeis, self.nBaud))
717 717
718 718 #Frequency
719 719 __codeBuffer = numpy.zeros((self.nCode, self.__nHeis), dtype=numpy.complex)
720 720
721 721 __codeBuffer[:,0:self.nBaud] = self.code
722 722
723 723 self.fft_code = numpy.conj(numpy.fft.fft(__codeBuffer, axis=1))
724 724
725 725 if dataOut.flagDataAsBlock:
726 726
727 727 self.ndatadec = self.__nHeis #- self.nBaud + 1
728 728
729 729 self.datadecTime = numpy.zeros((self.__nChannels, self.__nProfiles, self.ndatadec), dtype=numpy.complex)
730 730
731 731 else:
732 732
733 733 #Time
734 734 self.ndatadec = self.__nHeis #- self.nBaud + 1
735 735
736 736 self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex)
737 737
738 738 def __convolutionInFreq(self, data):
739 739
740 740 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
741 741
742 742 fft_data = numpy.fft.fft(data, axis=1)
743 743
744 744 conv = fft_data*fft_code
745 745
746 746 data = numpy.fft.ifft(conv,axis=1)
747 747
748 748 return data
749 749
750 750 def __convolutionInFreqOpt(self, data):
751 751
752 752 raise NotImplementedError
753 753
754 754 def __convolutionInTime(self, data):
755 755
756 756 code = self.code[self.__profIndex]
757 757 for i in range(self.__nChannels):
758 758 self.datadecTime[i,:] = numpy.correlate(data[i,:], code, mode='full')[self.nBaud-1:]
759 759
760 760 return self.datadecTime
761 761
762 762 def __convolutionByBlockInTime(self, data):
763 763
764 764 repetitions = int(self.__nProfiles / self.nCode)
765 765 junk = numpy.lib.stride_tricks.as_strided(self.code, (repetitions, self.code.size), (0, self.code.itemsize))
766 766 junk = junk.flatten()
767 767 code_block = numpy.reshape(junk, (self.nCode*repetitions, self.nBaud))
768 768 profilesList = range(self.__nProfiles)
769 769
770 770 for i in range(self.__nChannels):
771 771 for j in profilesList:
772 772 self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:]
773 773 return self.datadecTime
774 774
775 775 def __convolutionByBlockInFreq(self, data):
776 776
777 777 raise NotImplementedError("Decoder by frequency fro Blocks not implemented")
778 778
779 779
780 780 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
781 781
782 782 fft_data = numpy.fft.fft(data, axis=2)
783 783
784 784 conv = fft_data*fft_code
785 785
786 786 data = numpy.fft.ifft(conv,axis=2)
787 787
788 788 return data
789 789
790 790
791 791 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0, osamp=None, times=None):
792 792
793 793 if dataOut.flagDecodeData:
794 794 print("This data is already decoded, recoding again ...")
795 795
796 796 if not self.isConfig:
797 797
798 798 if code is None:
799 799 if dataOut.code is None:
800 800 raise ValueError("Code could not be read from %s instance. Enter a value in Code parameter" %dataOut.type)
801 801
802 802 code = dataOut.code
803 803 else:
804 804 code = numpy.array(code).reshape(nCode,nBaud)
805 805 self.setup(code, osamp, dataOut)
806 806
807 807 self.isConfig = True
808 808
809 809 if mode == 3:
810 810 sys.stderr.write("Decoder Warning: mode=%d is not valid, using mode=0\n" %mode)
811 811
812 812 if times != None:
813 813 sys.stderr.write("Decoder Warning: Argument 'times' in not used anymore\n")
814 814
815 815 if self.code is None:
816 816 print("Fail decoding: Code is not defined.")
817 817 return
818 818
819 819 self.__nProfiles = dataOut.nProfiles
820 820 datadec = None
821 821
822 822 if mode == 3:
823 823 mode = 0
824 824
825 825 if dataOut.flagDataAsBlock:
826 826 """
827 827 Decoding when data have been read as block,
828 828 """
829 829
830 830 if mode == 0:
831 831 datadec = self.__convolutionByBlockInTime(dataOut.data)
832 832 if mode == 1:
833 833 datadec = self.__convolutionByBlockInFreq(dataOut.data)
834 834 else:
835 835 """
836 836 Decoding when data have been read profile by profile
837 837 """
838 838 if mode == 0:
839 839 datadec = self.__convolutionInTime(dataOut.data)
840 840
841 841 if mode == 1:
842 842 datadec = self.__convolutionInFreq(dataOut.data)
843 843
844 844 if mode == 2:
845 845 datadec = self.__convolutionInFreqOpt(dataOut.data)
846 846
847 847 if datadec is None:
848 848 raise ValueError("Codification mode selected is not valid: mode=%d. Try selecting 0 or 1" %mode)
849 849
850 850 dataOut.code = self.code
851 851 dataOut.nCode = self.nCode
852 852 dataOut.nBaud = self.nBaud
853 853
854 854 dataOut.data = datadec
855 855
856 856 dataOut.heightList = dataOut.heightList[0:datadec.shape[-1]]
857 857
858 858 dataOut.flagDecodeData = True #asumo q la data esta decodificada
859 859
860 860 if self.__profIndex == self.nCode-1:
861 861 self.__profIndex = 0
862 862 return dataOut
863 863
864 864 self.__profIndex += 1
865 865
866 866 return dataOut
867 867 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
868 868
869 869
870 870 class ProfileConcat(Operation):
871 871
872 872 isConfig = False
873 873 buffer = None
874 874
875 875 def __init__(self, **kwargs):
876 876
877 877 Operation.__init__(self, **kwargs)
878 878 self.profileIndex = 0
879 879
880 880 def reset(self):
881 881 self.buffer = numpy.zeros_like(self.buffer)
882 882 self.start_index = 0
883 883 self.times = 1
884 884
885 885 def setup(self, data, m, n=1):
886 886 self.buffer = numpy.zeros((data.shape[0],data.shape[1]*m),dtype=type(data[0,0]))
887 887 self.nHeights = data.shape[1]#.nHeights
888 888 self.start_index = 0
889 889 self.times = 1
890 890
891 891 def concat(self, data):
892 892
893 893 self.buffer[:,self.start_index:self.nHeights*self.times] = data.copy()
894 894 self.start_index = self.start_index + self.nHeights
895 895
896 896 def run(self, dataOut, m):
897 897 dataOut.flagNoData = True
898 898
899 899 if not self.isConfig:
900 900 self.setup(dataOut.data, m, 1)
901 901 self.isConfig = True
902 902
903 903 if dataOut.flagDataAsBlock:
904 904 raise ValueError("ProfileConcat can only be used when voltage have been read profile by profile, getBlock = False")
905 905
906 906 else:
907 907 self.concat(dataOut.data)
908 908 self.times += 1
909 909 if self.times > m:
910 910 dataOut.data = self.buffer
911 911 self.reset()
912 912 dataOut.flagNoData = False
913 913 # se deben actualizar mas propiedades del header y del objeto dataOut, por ejemplo, las alturas
914 914 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
915 915 xf = dataOut.heightList[0] + dataOut.nHeights * deltaHeight * m
916 916 dataOut.heightList = numpy.arange(dataOut.heightList[0], xf, deltaHeight)
917 917 dataOut.ippSeconds *= m
918 918 return dataOut
919 919
920 920 class ProfileSelector(Operation):
921 921
922 922 profileIndex = None
923 923 # Tamanho total de los perfiles
924 924 nProfiles = None
925 925
926 926 def __init__(self, **kwargs):
927 927
928 928 Operation.__init__(self, **kwargs)
929 929 self.profileIndex = 0
930 930
931 931 def incProfileIndex(self):
932 932
933 933 self.profileIndex += 1
934 934
935 935 if self.profileIndex >= self.nProfiles:
936 936 self.profileIndex = 0
937 937
938 938 def isThisProfileInRange(self, profileIndex, minIndex, maxIndex):
939 939
940 940 if profileIndex < minIndex:
941 941 return False
942 942
943 943 if profileIndex > maxIndex:
944 944 return False
945 945
946 946 return True
947 947
948 948 def isThisProfileInList(self, profileIndex, profileList):
949 949
950 950 if profileIndex not in profileList:
951 951 return False
952 952
953 953 return True
954 954
955 955 def run(self, dataOut, profileList=None, profileRangeList=None, beam=None, byblock=False, rangeList = None, nProfiles=None):
956 956
957 957 """
958 958 ProfileSelector:
959 959
960 960 Inputs:
961 961 profileList : Index of profiles selected. Example: profileList = (0,1,2,7,8)
962 962
963 963 profileRangeList : Minimum and maximum profile indexes. Example: profileRangeList = (4, 30)
964 964
965 965 rangeList : List of profile ranges. Example: rangeList = ((4, 30), (32, 64), (128, 256))
966 966
967 967 """
968 968
969 969 if rangeList is not None:
970 970 if type(rangeList[0]) not in (tuple, list):
971 971 rangeList = [rangeList]
972 972
973 973 dataOut.flagNoData = True
974 974
975 975 if dataOut.flagDataAsBlock:
976 976 """
977 977 data dimension = [nChannels, nProfiles, nHeis]
978 978 """
979 979 if profileList != None:
980 980 dataOut.data = dataOut.data[:,profileList,:]
981 981
982 982 if profileRangeList != None:
983 983 minIndex = profileRangeList[0]
984 984 maxIndex = profileRangeList[1]
985 985 profileList = list(range(minIndex, maxIndex+1))
986 986
987 987 dataOut.data = dataOut.data[:,minIndex:maxIndex+1,:]
988 988
989 989 if rangeList != None:
990 990
991 991 profileList = []
992 992
993 993 for thisRange in rangeList:
994 994 minIndex = thisRange[0]
995 995 maxIndex = thisRange[1]
996 996
997 997 profileList.extend(list(range(minIndex, maxIndex+1)))
998 998
999 999 dataOut.data = dataOut.data[:,profileList,:]
1000 1000
1001 1001 dataOut.nProfiles = len(profileList)
1002 1002 dataOut.profileIndex = dataOut.nProfiles - 1
1003 1003 dataOut.flagNoData = False
1004 1004
1005 1005 return dataOut
1006 1006
1007 1007 """
1008 1008 data dimension = [nChannels, nHeis]
1009 1009 """
1010 1010
1011 1011 if profileList != None:
1012 1012
1013 1013 if self.isThisProfileInList(dataOut.profileIndex, profileList):
1014 1014
1015 1015 self.nProfiles = len(profileList)
1016 1016 dataOut.nProfiles = self.nProfiles
1017 1017 dataOut.profileIndex = self.profileIndex
1018 1018 dataOut.flagNoData = False
1019 1019
1020 1020 self.incProfileIndex()
1021 1021 return dataOut
1022 1022
1023 1023 if profileRangeList != None:
1024 1024
1025 1025 minIndex = profileRangeList[0]
1026 1026 maxIndex = profileRangeList[1]
1027 1027
1028 1028 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1029 1029
1030 1030 self.nProfiles = maxIndex - minIndex + 1
1031 1031 dataOut.nProfiles = self.nProfiles
1032 1032 dataOut.profileIndex = self.profileIndex
1033 1033 dataOut.flagNoData = False
1034 1034
1035 1035 self.incProfileIndex()
1036 1036 return dataOut
1037 1037
1038 1038 if rangeList != None:
1039 1039
1040 1040 nProfiles = 0
1041 1041
1042 1042 for thisRange in rangeList:
1043 1043 minIndex = thisRange[0]
1044 1044 maxIndex = thisRange[1]
1045 1045
1046 1046 nProfiles += maxIndex - minIndex + 1
1047 1047
1048 1048 for thisRange in rangeList:
1049 1049
1050 1050 minIndex = thisRange[0]
1051 1051 maxIndex = thisRange[1]
1052 1052
1053 1053 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1054 1054
1055 1055 self.nProfiles = nProfiles
1056 1056 dataOut.nProfiles = self.nProfiles
1057 1057 dataOut.profileIndex = self.profileIndex
1058 1058 dataOut.flagNoData = False
1059 1059
1060 1060 self.incProfileIndex()
1061 1061
1062 1062 break
1063 1063
1064 1064 return dataOut
1065 1065
1066 1066
1067 1067 if beam != None: #beam is only for AMISR data
1068 1068 if self.isThisProfileInList(dataOut.profileIndex, dataOut.beamRangeDict[beam]):
1069 1069 dataOut.flagNoData = False
1070 1070 dataOut.profileIndex = self.profileIndex
1071 1071
1072 1072 self.incProfileIndex()
1073 1073
1074 1074 return dataOut
1075 1075
1076 1076 raise ValueError("ProfileSelector needs profileList, profileRangeList or rangeList parameter")
1077 1077
1078 1078
1079 1079 class Reshaper(Operation):
1080 1080
1081 1081 def __init__(self, **kwargs):
1082 1082
1083 1083 Operation.__init__(self, **kwargs)
1084 1084
1085 1085 self.__buffer = None
1086 1086 self.__nitems = 0
1087 1087
1088 1088 def __appendProfile(self, dataOut, nTxs):
1089 1089
1090 1090 if self.__buffer is None:
1091 1091 shape = (dataOut.nChannels, int(dataOut.nHeights/nTxs) )
1092 1092 self.__buffer = numpy.empty(shape, dtype = dataOut.data.dtype)
1093 1093
1094 1094 ini = dataOut.nHeights * self.__nitems
1095 1095 end = ini + dataOut.nHeights
1096 1096
1097 1097 self.__buffer[:, ini:end] = dataOut.data
1098 1098
1099 1099 self.__nitems += 1
1100 1100
1101 1101 return int(self.__nitems*nTxs)
1102 1102
1103 1103 def __getBuffer(self):
1104 1104
1105 1105 if self.__nitems == int(1./self.__nTxs):
1106 1106
1107 1107 self.__nitems = 0
1108 1108
1109 1109 return self.__buffer.copy()
1110 1110
1111 1111 return None
1112 1112
1113 1113 def __checkInputs(self, dataOut, shape, nTxs):
1114 1114
1115 1115 if shape is None and nTxs is None:
1116 1116 raise ValueError("Reshaper: shape of factor should be defined")
1117 1117
1118 1118 if nTxs:
1119 1119 if nTxs < 0:
1120 1120 raise ValueError("nTxs should be greater than 0")
1121 1121
1122 1122 if nTxs < 1 and dataOut.nProfiles % (1./nTxs) != 0:
1123 1123 raise ValueError("nProfiles= %d is not divisibled by (1./nTxs) = %f" %(dataOut.nProfiles, (1./nTxs)))
1124 1124
1125 1125 shape = [dataOut.nChannels, dataOut.nProfiles*nTxs, dataOut.nHeights/nTxs]
1126 1126
1127 1127 return shape, nTxs
1128 1128
1129 1129 if len(shape) != 2 and len(shape) != 3:
1130 1130 raise ValueError("shape dimension should be equal to 2 or 3. shape = (nProfiles, nHeis) or (nChannels, nProfiles, nHeis). Actually shape = (%d, %d, %d)" %(dataOut.nChannels, dataOut.nProfiles, dataOut.nHeights))
1131 1131
1132 1132 if len(shape) == 2:
1133 1133 shape_tuple = [dataOut.nChannels]
1134 1134 shape_tuple.extend(shape)
1135 1135 else:
1136 1136 shape_tuple = list(shape)
1137 1137
1138 1138 nTxs = 1.0*shape_tuple[1]/dataOut.nProfiles
1139 1139
1140 1140 return shape_tuple, nTxs
1141 1141
1142 1142 def run(self, dataOut, shape=None, nTxs=None):
1143 1143
1144 1144 shape_tuple, self.__nTxs = self.__checkInputs(dataOut, shape, nTxs)
1145 1145
1146 1146 dataOut.flagNoData = True
1147 1147 profileIndex = None
1148 1148
1149 1149 if dataOut.flagDataAsBlock:
1150 1150
1151 1151 dataOut.data = numpy.reshape(dataOut.data, shape_tuple)
1152 1152 dataOut.flagNoData = False
1153 1153
1154 1154 profileIndex = int(dataOut.nProfiles*self.__nTxs) - 1
1155 1155
1156 1156 else:
1157 1157
1158 1158 if self.__nTxs < 1:
1159 1159
1160 1160 self.__appendProfile(dataOut, self.__nTxs)
1161 1161 new_data = self.__getBuffer()
1162 1162
1163 1163 if new_data is not None:
1164 1164 dataOut.data = new_data
1165 1165 dataOut.flagNoData = False
1166 1166
1167 1167 profileIndex = dataOut.profileIndex*nTxs
1168 1168
1169 1169 else:
1170 1170 raise ValueError("nTxs should be greater than 0 and lower than 1, or use VoltageReader(..., getblock=True)")
1171 1171
1172 1172 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1173 1173
1174 1174 dataOut.heightList = numpy.arange(dataOut.nHeights/self.__nTxs) * deltaHeight + dataOut.heightList[0]
1175 1175
1176 1176 dataOut.nProfiles = int(dataOut.nProfiles*self.__nTxs)
1177 1177
1178 1178 dataOut.profileIndex = profileIndex
1179 1179
1180 1180 dataOut.ippSeconds /= self.__nTxs
1181 1181
1182 1182 return dataOut
1183 1183
1184 1184 class SplitProfiles(Operation):
1185 1185
1186 1186 def __init__(self, **kwargs):
1187 1187
1188 1188 Operation.__init__(self, **kwargs)
1189 1189
1190 1190 def run(self, dataOut, n):
1191 1191
1192 1192 dataOut.flagNoData = True
1193 1193 profileIndex = None
1194 1194
1195 1195 if dataOut.flagDataAsBlock:
1196 1196
1197 1197 #nchannels, nprofiles, nsamples
1198 1198 shape = dataOut.data.shape
1199 1199
1200 1200 if shape[2] % n != 0:
1201 1201 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[2]))
1202 1202
1203 1203 new_shape = shape[0], shape[1]*n, int(shape[2]/n)
1204 1204
1205 1205 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1206 1206 dataOut.flagNoData = False
1207 1207
1208 1208 profileIndex = int(dataOut.nProfiles/n) - 1
1209 1209
1210 1210 else:
1211 1211
1212 1212 raise ValueError("Could not split the data when is read Profile by Profile. Use VoltageReader(..., getblock=True)")
1213 1213
1214 1214 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1215 1215
1216 1216 dataOut.heightList = numpy.arange(dataOut.nHeights/n) * deltaHeight + dataOut.heightList[0]
1217 1217
1218 1218 dataOut.nProfiles = int(dataOut.nProfiles*n)
1219 1219
1220 1220 dataOut.profileIndex = profileIndex
1221 1221
1222 1222 dataOut.ippSeconds /= n
1223 1223
1224 1224 return dataOut
1225 1225
1226 1226 class CombineProfiles(Operation):
1227 1227 def __init__(self, **kwargs):
1228 1228
1229 1229 Operation.__init__(self, **kwargs)
1230 1230
1231 1231 self.__remData = None
1232 1232 self.__profileIndex = 0
1233 1233
1234 1234 def run(self, dataOut, n):
1235 1235
1236 1236 dataOut.flagNoData = True
1237 1237 profileIndex = None
1238 1238
1239 1239 if dataOut.flagDataAsBlock:
1240 1240
1241 1241 #nchannels, nprofiles, nsamples
1242 1242 shape = dataOut.data.shape
1243 1243 new_shape = shape[0], shape[1]/n, shape[2]*n
1244 1244
1245 1245 if shape[1] % n != 0:
1246 1246 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[1]))
1247 1247
1248 1248 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1249 1249 dataOut.flagNoData = False
1250 1250
1251 1251 profileIndex = int(dataOut.nProfiles*n) - 1
1252 1252
1253 1253 else:
1254 1254
1255 1255 #nchannels, nsamples
1256 1256 if self.__remData is None:
1257 1257 newData = dataOut.data
1258 1258 else:
1259 1259 newData = numpy.concatenate((self.__remData, dataOut.data), axis=1)
1260 1260
1261 1261 self.__profileIndex += 1
1262 1262
1263 1263 if self.__profileIndex < n:
1264 1264 self.__remData = newData
1265 1265 #continue
1266 1266 return
1267 1267
1268 1268 self.__profileIndex = 0
1269 1269 self.__remData = None
1270 1270
1271 1271 dataOut.data = newData
1272 1272 dataOut.flagNoData = False
1273 1273
1274 1274 profileIndex = dataOut.profileIndex/n
1275 1275
1276 1276
1277 1277 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1278 1278
1279 1279 dataOut.heightList = numpy.arange(dataOut.nHeights*n) * deltaHeight + dataOut.heightList[0]
1280 1280
1281 1281 dataOut.nProfiles = int(dataOut.nProfiles/n)
1282 1282
1283 1283 dataOut.profileIndex = profileIndex
1284 1284
1285 1285 dataOut.ippSeconds *= n
1286 1286
1287 1287 return dataOut
1288 1288
1289 1289 class PulsePairVoltage(Operation):
1290 1290 '''
1291 1291 Function PulsePair(Signal Power, Velocity)
1292 1292 The real component of Lag[0] provides Intensity Information
1293 1293 The imag component of Lag[1] Phase provides Velocity Information
1294 1294
1295 1295 Configuration Parameters:
1296 1296 nPRF = Number of Several PRF
1297 1297 theta = Degree Azimuth angel Boundaries
1298 1298
1299 1299 Input:
1300 1300 self.dataOut
1301 1301 lag[N]
1302 1302 Affected:
1303 1303 self.dataOut.spc
1304 1304 '''
1305 1305 isConfig = False
1306 1306 __profIndex = 0
1307 1307 __initime = None
1308 1308 __lastdatatime = None
1309 1309 __buffer = None
1310 1310 noise = None
1311 1311 __dataReady = False
1312 1312 n = None
1313 1313 __nch = 0
1314 1314 __nHeis = 0
1315 1315 removeDC = False
1316 1316 ipp = None
1317 1317 lambda_ = 0
1318 1318
1319 1319 def __init__(self,**kwargs):
1320 1320 Operation.__init__(self,**kwargs)
1321 1321
1322 1322 def setup(self, dataOut, n = None, removeDC=False):
1323 1323 '''
1324 1324 n= Numero de PRF's de entrada
1325 1325 '''
1326 1326 self.__initime = None
1327 1327 self.__lastdatatime = 0
1328 1328 self.__dataReady = False
1329 1329 self.__buffer = 0
1330 1330 self.__profIndex = 0
1331 1331 self.noise = None
1332 1332 self.__nch = dataOut.nChannels
1333 1333 self.__nHeis = dataOut.nHeights
1334 1334 self.removeDC = removeDC
1335 1335 self.lambda_ = 3.0e8/(9345.0e6)
1336 1336 self.ippSec = dataOut.ippSeconds
1337 1337 self.nCohInt = dataOut.nCohInt
1338 1338 print("IPPseconds",dataOut.ippSeconds)
1339 1339
1340 1340 print("ELVALOR DE n es:", n)
1341 1341 if n == None:
1342 1342 raise ValueError("n should be specified.")
1343 1343
1344 1344 if n != None:
1345 1345 if n<2:
1346 1346 raise ValueError("n should be greater than 2")
1347 1347
1348 1348 self.n = n
1349 1349 self.__nProf = n
1350 1350
1351 1351 self.__buffer = numpy.zeros((dataOut.nChannels,
1352 1352 n,
1353 1353 dataOut.nHeights),
1354 1354 dtype='complex')
1355 1355
1356 1356 def putData(self,data):
1357 1357 '''
1358 1358 Add a profile to he __buffer and increase in one the __profiel Index
1359 1359 '''
1360 1360 self.__buffer[:,self.__profIndex,:]= data
1361 1361 self.__profIndex += 1
1362 1362 return
1363 1363
1364 1364 def pushData(self,dataOut):
1365 1365 '''
1366 1366 Return the PULSEPAIR and the profiles used in the operation
1367 1367 Affected : self.__profileIndex
1368 1368 '''
1369 1369 #----------------- Remove DC-----------------------------------
1370 1370 if self.removeDC==True:
1371 1371 mean = numpy.mean(self.__buffer,1)
1372 1372 tmp = mean.reshape(self.__nch,1,self.__nHeis)
1373 1373 dc= numpy.tile(tmp,[1,self.__nProf,1])
1374 1374 self.__buffer = self.__buffer - dc
1375 1375 #------------------Calculo de Potencia ------------------------
1376 1376 pair0 = self.__buffer*numpy.conj(self.__buffer)
1377 1377 pair0 = pair0.real
1378 1378 lag_0 = numpy.sum(pair0,1)
1379 1379 #------------------Calculo de Ruido x canal--------------------
1380 1380 self.noise = numpy.zeros(self.__nch)
1381 1381 for i in range(self.__nch):
1382 1382 daux = numpy.sort(pair0[i,:,:],axis= None)
1383 1383 self.noise[i]=hildebrand_sekhon( daux ,self.nCohInt)
1384 1384
1385 1385 self.noise = self.noise.reshape(self.__nch,1)
1386 1386 self.noise = numpy.tile(self.noise,[1,self.__nHeis])
1387 1387 noise_buffer = self.noise.reshape(self.__nch,1,self.__nHeis)
1388 1388 noise_buffer = numpy.tile(noise_buffer,[1,self.__nProf,1])
1389 1389 #------------------ Potencia recibida= P , Potencia senal = S , Ruido= N--
1390 1390 #------------------ P= S+N ,P=lag_0/N ---------------------------------
1391 1391 #-------------------- Power --------------------------------------------------
1392 1392 data_power = lag_0/(self.n*self.nCohInt)
1393 1393 #------------------ Senal ---------------------------------------------------
1394 1394 data_intensity = pair0 - noise_buffer
1395 1395 data_intensity = numpy.sum(data_intensity,axis=1)*(self.n*self.nCohInt)#*self.nCohInt)
1396 1396 #data_intensity = (lag_0-self.noise*self.n)*(self.n*self.nCohInt)
1397 1397 for i in range(self.__nch):
1398 1398 for j in range(self.__nHeis):
1399 1399 if data_intensity[i][j] < 0:
1400 1400 data_intensity[i][j] = numpy.min(numpy.absolute(data_intensity[i][j]))
1401 1401
1402 1402 #----------------- Calculo de Frecuencia y Velocidad doppler--------
1403 1403 pair1 = self.__buffer[:,:-1,:]*numpy.conjugate(self.__buffer[:,1:,:])
1404 1404 lag_1 = numpy.sum(pair1,1)
1405 1405 data_freq = (-1/(2.0*math.pi*self.ippSec*self.nCohInt))*numpy.angle(lag_1)
1406 1406 data_velocity = (self.lambda_/2.0)*data_freq
1407 1407
1408 1408 #---------------- Potencia promedio estimada de la Senal-----------
1409 1409 lag_0 = lag_0/self.n
1410 1410 S = lag_0-self.noise
1411 1411
1412 1412 #---------------- Frecuencia Doppler promedio ---------------------
1413 1413 lag_1 = lag_1/(self.n-1)
1414 1414 R1 = numpy.abs(lag_1)
1415 1415
1416 1416 #---------------- Calculo del SNR----------------------------------
1417 1417 data_snrPP = S/self.noise
1418 1418 for i in range(self.__nch):
1419 1419 for j in range(self.__nHeis):
1420 1420 if data_snrPP[i][j] < 1.e-20:
1421 1421 data_snrPP[i][j] = 1.e-20
1422 1422
1423 1423 #----------------- Calculo del ancho espectral ----------------------
1424 1424 L = S/R1
1425 1425 L = numpy.where(L<0,1,L)
1426 1426 L = numpy.log(L)
1427 1427 tmp = numpy.sqrt(numpy.absolute(L))
1428 1428 data_specwidth = (self.lambda_/(2*math.sqrt(2)*math.pi*self.ippSec*self.nCohInt))*tmp*numpy.sign(L)
1429 1429 n = self.__profIndex
1430 1430
1431 1431 self.__buffer = numpy.zeros((self.__nch, self.__nProf,self.__nHeis), dtype='complex')
1432 1432 self.__profIndex = 0
1433 1433 return data_power,data_intensity,data_velocity,data_snrPP,data_specwidth,n
1434 1434
1435 1435
1436 1436 def pulsePairbyProfiles(self,dataOut):
1437 1437
1438 1438 self.__dataReady = False
1439 1439 data_power = None
1440 1440 data_intensity = None
1441 1441 data_velocity = None
1442 1442 data_specwidth = None
1443 1443 data_snrPP = None
1444 1444 self.putData(data=dataOut.data)
1445 1445 if self.__profIndex == self.n:
1446 1446 data_power,data_intensity, data_velocity,data_snrPP,data_specwidth, n = self.pushData(dataOut=dataOut)
1447 1447 self.__dataReady = True
1448 1448
1449 1449 return data_power, data_intensity, data_velocity, data_snrPP, data_specwidth
1450 1450
1451 1451
1452 1452 def pulsePairOp(self, dataOut, datatime= None):
1453 1453
1454 1454 if self.__initime == None:
1455 1455 self.__initime = datatime
1456 1456 data_power, data_intensity, data_velocity, data_snrPP, data_specwidth = self.pulsePairbyProfiles(dataOut)
1457 1457 self.__lastdatatime = datatime
1458 1458
1459 1459 if data_power is None:
1460 1460 return None, None, None,None,None,None
1461 1461
1462 1462 avgdatatime = self.__initime
1463 1463 deltatime = datatime - self.__lastdatatime
1464 1464 self.__initime = datatime
1465 1465
1466 1466 return data_power, data_intensity, data_velocity, data_snrPP, data_specwidth, avgdatatime
1467 1467
1468 1468 def run(self, dataOut,n = None,removeDC= False, overlapping= False,**kwargs):
1469 1469
1470 1470 if not self.isConfig:
1471 1471 self.setup(dataOut = dataOut, n = n , removeDC=removeDC , **kwargs)
1472 1472 self.isConfig = True
1473 1473 data_power, data_intensity, data_velocity,data_snrPP,data_specwidth, avgdatatime = self.pulsePairOp(dataOut, dataOut.utctime)
1474 1474 dataOut.flagNoData = True
1475 1475
1476 1476 if self.__dataReady:
1477 1477 dataOut.nCohInt *= self.n
1478 1478 dataOut.dataPP_POW = data_intensity # S
1479 1479 dataOut.dataPP_POWER = data_power # P
1480 1480 dataOut.dataPP_DOP = data_velocity
1481 1481 dataOut.dataPP_SNR = data_snrPP
1482 1482 dataOut.dataPP_WIDTH = data_specwidth
1483 1483 dataOut.PRFbyAngle = self.n #numero de PRF*cada angulo rotado que equivale a un tiempo.
1484 1484 dataOut.utctime = avgdatatime
1485 1485 dataOut.flagNoData = False
1486 1486 return dataOut
1487 1487
1488 1488
1489 1489
1490 1490 # import collections
1491 1491 # from scipy.stats import mode
1492 1492 #
1493 1493 # class Synchronize(Operation):
1494 1494 #
1495 1495 # isConfig = False
1496 1496 # __profIndex = 0
1497 1497 #
1498 1498 # def __init__(self, **kwargs):
1499 1499 #
1500 1500 # Operation.__init__(self, **kwargs)
1501 1501 # # self.isConfig = False
1502 1502 # self.__powBuffer = None
1503 1503 # self.__startIndex = 0
1504 1504 # self.__pulseFound = False
1505 1505 #
1506 1506 # def __findTxPulse(self, dataOut, channel=0, pulse_with = None):
1507 1507 #
1508 1508 # #Read data
1509 1509 #
1510 1510 # powerdB = dataOut.getPower(channel = channel)
1511 1511 # noisedB = dataOut.getNoise(channel = channel)[0]
1512 1512 #
1513 1513 # self.__powBuffer.extend(powerdB.flatten())
1514 1514 #
1515 1515 # dataArray = numpy.array(self.__powBuffer)
1516 1516 #
1517 1517 # filteredPower = numpy.correlate(dataArray, dataArray[0:self.__nSamples], "same")
1518 1518 #
1519 1519 # maxValue = numpy.nanmax(filteredPower)
1520 1520 #
1521 1521 # if maxValue < noisedB + 10:
1522 1522 # #No se encuentra ningun pulso de transmision
1523 1523 # return None
1524 1524 #
1525 1525 # maxValuesIndex = numpy.where(filteredPower > maxValue - 0.1*abs(maxValue))[0]
1526 1526 #
1527 1527 # if len(maxValuesIndex) < 2:
1528 1528 # #Solo se encontro un solo pulso de transmision de un baudio, esperando por el siguiente TX
1529 1529 # return None
1530 1530 #
1531 1531 # phasedMaxValuesIndex = maxValuesIndex - self.__nSamples
1532 1532 #
1533 1533 # #Seleccionar solo valores con un espaciamiento de nSamples
1534 1534 # pulseIndex = numpy.intersect1d(maxValuesIndex, phasedMaxValuesIndex)
1535 1535 #
1536 1536 # if len(pulseIndex) < 2:
1537 1537 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1538 1538 # return None
1539 1539 #
1540 1540 # spacing = pulseIndex[1:] - pulseIndex[:-1]
1541 1541 #
1542 1542 # #remover senales que se distancien menos de 10 unidades o muestras
1543 1543 # #(No deberian existir IPP menor a 10 unidades)
1544 1544 #
1545 1545 # realIndex = numpy.where(spacing > 10 )[0]
1546 1546 #
1547 1547 # if len(realIndex) < 2:
1548 1548 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1549 1549 # return None
1550 1550 #
1551 1551 # #Eliminar pulsos anchos (deja solo la diferencia entre IPPs)
1552 1552 # realPulseIndex = pulseIndex[realIndex]
1553 1553 #
1554 1554 # period = mode(realPulseIndex[1:] - realPulseIndex[:-1])[0][0]
1555 1555 #
1556 1556 # print "IPP = %d samples" %period
1557 1557 #
1558 1558 # self.__newNSamples = dataOut.nHeights #int(period)
1559 1559 # self.__startIndex = int(realPulseIndex[0])
1560 1560 #
1561 1561 # return 1
1562 1562 #
1563 1563 #
1564 1564 # def setup(self, nSamples, nChannels, buffer_size = 4):
1565 1565 #
1566 1566 # self.__powBuffer = collections.deque(numpy.zeros( buffer_size*nSamples,dtype=numpy.float),
1567 1567 # maxlen = buffer_size*nSamples)
1568 1568 #
1569 1569 # bufferList = []
1570 1570 #
1571 1571 # for i in range(nChannels):
1572 1572 # bufferByChannel = collections.deque(numpy.zeros( buffer_size*nSamples, dtype=numpy.complex) + numpy.NAN,
1573 1573 # maxlen = buffer_size*nSamples)
1574 1574 #
1575 1575 # bufferList.append(bufferByChannel)
1576 1576 #
1577 1577 # self.__nSamples = nSamples
1578 1578 # self.__nChannels = nChannels
1579 1579 # self.__bufferList = bufferList
1580 1580 #
1581 1581 # def run(self, dataOut, channel = 0):
1582 1582 #
1583 1583 # if not self.isConfig:
1584 1584 # nSamples = dataOut.nHeights
1585 1585 # nChannels = dataOut.nChannels
1586 1586 # self.setup(nSamples, nChannels)
1587 1587 # self.isConfig = True
1588 1588 #
1589 1589 # #Append new data to internal buffer
1590 1590 # for thisChannel in range(self.__nChannels):
1591 1591 # bufferByChannel = self.__bufferList[thisChannel]
1592 1592 # bufferByChannel.extend(dataOut.data[thisChannel])
1593 1593 #
1594 1594 # if self.__pulseFound:
1595 1595 # self.__startIndex -= self.__nSamples
1596 1596 #
1597 1597 # #Finding Tx Pulse
1598 1598 # if not self.__pulseFound:
1599 1599 # indexFound = self.__findTxPulse(dataOut, channel)
1600 1600 #
1601 1601 # if indexFound == None:
1602 1602 # dataOut.flagNoData = True
1603 1603 # return
1604 1604 #
1605 1605 # self.__arrayBuffer = numpy.zeros((self.__nChannels, self.__newNSamples), dtype = numpy.complex)
1606 1606 # self.__pulseFound = True
1607 1607 # self.__startIndex = indexFound
1608 1608 #
1609 1609 # #If pulse was found ...
1610 1610 # for thisChannel in range(self.__nChannels):
1611 1611 # bufferByChannel = self.__bufferList[thisChannel]
1612 1612 # #print self.__startIndex
1613 1613 # x = numpy.array(bufferByChannel)
1614 1614 # self.__arrayBuffer[thisChannel] = x[self.__startIndex:self.__startIndex+self.__newNSamples]
1615 1615 #
1616 1616 # deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1617 1617 # dataOut.heightList = numpy.arange(self.__newNSamples)*deltaHeight
1618 1618 # # dataOut.ippSeconds = (self.__newNSamples / deltaHeight)/1e6
1619 1619 #
1620 1620 # dataOut.data = self.__arrayBuffer
1621 1621 #
1622 1622 # self.__startIndex += self.__newNSamples
1623 1623 #
1624 1624 # return
General Comments 0
You need to be logged in to leave comments. Login now