##// END OF EJS Templates
Fix zlimits when showprofile and flagSpreadF(Faraday) no needed
rflores -
r1551:15bafdde09b9
parent child
Show More

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

@@ -1,698 +1,702
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 """Base class to create plot operations
6 6
7 7 """
8 8
9 9 import os
10 10 import sys
11 11 import zmq
12 12 import time
13 13 import numpy
14 14 import datetime
15 15 from collections import deque
16 16 from functools import wraps
17 17 from threading import Thread
18 18 import matplotlib
19 19
20 20 if 'BACKEND' in os.environ:
21 21 matplotlib.use(os.environ['BACKEND'])
22 22 elif 'linux' in sys.platform:
23 23 matplotlib.use("TkAgg")
24 24 elif 'darwin' in sys.platform:
25 25 matplotlib.use('MacOSX')
26 26 else:
27 27 from schainpy.utils import log
28 28 log.warning('Using default Backend="Agg"', 'INFO')
29 29 matplotlib.use('Agg')
30 30
31 31 import matplotlib.pyplot as plt
32 32 from matplotlib.patches import Polygon
33 33 from mpl_toolkits.axes_grid1 import make_axes_locatable
34 34 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
35 35
36 36 from schainpy.model.data.jrodata import PlotterData
37 37 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
38 38 from schainpy.utils import log
39 39
40 40 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
41 41 blu_values = matplotlib.pyplot.get_cmap(
42 42 'seismic_r', 20)(numpy.arange(20))[10:15]
43 43 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
44 44 'jro', numpy.vstack((blu_values, jet_values)))
45 45 matplotlib.pyplot.register_cmap(cmap=ncmap)
46 46
47 47 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
48 48 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
49 49
50 50 EARTH_RADIUS = 6.3710e3
51 51
52 52 def ll2xy(lat1, lon1, lat2, lon2):
53 53
54 54 p = 0.017453292519943295
55 55 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
56 56 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
57 57 r = 12742 * numpy.arcsin(numpy.sqrt(a))
58 58 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
59 59 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
60 60 theta = -theta + numpy.pi/2
61 61 return r*numpy.cos(theta), r*numpy.sin(theta)
62 62
63 63
64 64 def km2deg(km):
65 65 '''
66 66 Convert distance in km to degrees
67 67 '''
68 68
69 69 return numpy.rad2deg(km/EARTH_RADIUS)
70 70
71 71
72 72 def figpause(interval):
73 73 backend = plt.rcParams['backend']
74 74 if backend in matplotlib.rcsetup.interactive_bk:
75 75 figManager = matplotlib._pylab_helpers.Gcf.get_active()
76 76 if figManager is not None:
77 77 canvas = figManager.canvas
78 78 if canvas.figure.stale:
79 79 canvas.draw()
80 80 try:
81 81 canvas.start_event_loop(interval)
82 82 except:
83 83 pass
84 84 return
85 85
86 86 def popup(message):
87 87 '''
88 88 '''
89 89
90 90 fig = plt.figure(figsize=(12, 8), facecolor='r')
91 91 text = '\n'.join([s.strip() for s in message.split(':')])
92 92 fig.text(0.01, 0.5, text, ha='left', va='center',
93 93 size='20', weight='heavy', color='w')
94 94 fig.show()
95 95 figpause(1000)
96 96
97 97
98 98 class Throttle(object):
99 99 '''
100 100 Decorator that prevents a function from being called more than once every
101 101 time period.
102 102 To create a function that cannot be called more than once a minute, but
103 103 will sleep until it can be called:
104 104 @Throttle(minutes=1)
105 105 def foo():
106 106 pass
107 107
108 108 for i in range(10):
109 109 foo()
110 110 print "This function has run %s times." % i
111 111 '''
112 112
113 113 def __init__(self, seconds=0, minutes=0, hours=0):
114 114 self.throttle_period = datetime.timedelta(
115 115 seconds=seconds, minutes=minutes, hours=hours
116 116 )
117 117
118 118 self.time_of_last_call = datetime.datetime.min
119 119
120 120 def __call__(self, fn):
121 121 @wraps(fn)
122 122 def wrapper(*args, **kwargs):
123 123 coerce = kwargs.pop('coerce', None)
124 124 if coerce:
125 125 self.time_of_last_call = datetime.datetime.now()
126 126 return fn(*args, **kwargs)
127 127 else:
128 128 now = datetime.datetime.now()
129 129 time_since_last_call = now - self.time_of_last_call
130 130 time_left = self.throttle_period - time_since_last_call
131 131
132 132 if time_left > datetime.timedelta(seconds=0):
133 133 return
134 134
135 135 self.time_of_last_call = datetime.datetime.now()
136 136 return fn(*args, **kwargs)
137 137
138 138 return wrapper
139 139
140 140 def apply_throttle(value):
141 141
142 142 @Throttle(seconds=value)
143 143 def fnThrottled(fn):
144 144 fn()
145 145
146 146 return fnThrottled
147 147
148 148
149 149 @MPDecorator
150 150 class Plot(Operation):
151 151 """Base class for Schain plotting operations
152 152
153 153 This class should never be use directtly you must subclass a new operation,
154 154 children classes must be defined as follow:
155 155
156 156 ExamplePlot(Plot):
157 157
158 158 CODE = 'code'
159 159 colormap = 'jet'
160 160 plot_type = 'pcolor' # options are ('pcolor', 'pcolorbuffer', 'scatter', 'scatterbuffer')
161 161
162 162 def setup(self):
163 163 pass
164 164
165 165 def plot(self):
166 166 pass
167 167
168 168 """
169 169
170 170 CODE = 'Figure'
171 171 colormap = 'jet'
172 172 bgcolor = 'white'
173 173 buffering = True
174 174 __missing = 1E30
175 175
176 176 __attrs__ = ['show', 'save', 'ymin', 'ymax', 'zmin', 'zmax', 'title',
177 177 'showprofile']
178 178
179 179 def __init__(self):
180 180
181 181 Operation.__init__(self)
182 182 self.isConfig = False
183 183 self.isPlotConfig = False
184 184 self.save_time = 0
185 185 self.sender_time = 0
186 186 self.data = None
187 187 self.firsttime = True
188 188 self.sender_queue = deque(maxlen=10)
189 189 self.plots_adjust = {'left': 0.125, 'right': 0.9, 'bottom': 0.15, 'top': 0.9, 'wspace': 0.2, 'hspace': 0.2}
190 190
191 191 def __fmtTime(self, x, pos):
192 192 '''
193 193 '''
194 194
195 195 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
196 196
197 197 def __setup(self, **kwargs):
198 198 '''
199 199 Initialize variables
200 200 '''
201 201
202 202 self.figures = []
203 203 self.axes = []
204 204 self.cb_axes = []
205 205 self.localtime = kwargs.pop('localtime', True)
206 206 self.show = kwargs.get('show', True)
207 207 self.save = kwargs.get('save', False)
208 208 self.save_period = kwargs.get('save_period', 0)
209 209 self.colormap = kwargs.get('colormap', self.colormap)
210 210 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
211 211 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
212 212 self.colormaps = kwargs.get('colormaps', None)
213 213 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
214 214 self.showprofile = kwargs.get('showprofile', False)
215 215 self.title = kwargs.get('wintitle', self.CODE.upper())
216 216 self.cb_label = kwargs.get('cb_label', None)
217 217 self.cb_labels = kwargs.get('cb_labels', None)
218 218 self.labels = kwargs.get('labels', None)
219 219 self.xaxis = kwargs.get('xaxis', 'frequency')
220 220 self.zmin = kwargs.get('zmin', None)
221 221 self.zmax = kwargs.get('zmax', None)
222 222 self.zlimits = kwargs.get('zlimits', None)
223 223 self.xlimits = kwargs.get('xlimits', None)
224 224 self.xstep_given = kwargs.get('xstep_given', None)
225 225 self.ystep_given = kwargs.get('ystep_given', None)
226 226 self.autoxticks = kwargs.get('autoxticks', True)
227 227 self.xmin = kwargs.get('xmin', None)
228 228 self.xmax = kwargs.get('xmax', None)
229 229 self.xrange = kwargs.get('xrange', 12)
230 230 self.xscale = kwargs.get('xscale', None)
231 231 self.ymin = kwargs.get('ymin', None)
232 232 self.ymax = kwargs.get('ymax', None)
233 233 self.yscale = kwargs.get('yscale', None)
234 234 self.xlabel = kwargs.get('xlabel', None)
235 235 self.attr_time = kwargs.get('attr_time', 'utctime')
236 236 self.attr_data = kwargs.get('attr_data', 'data_param')
237 237 self.decimation = kwargs.get('decimation', None)
238 238 self.oneFigure = kwargs.get('oneFigure', True)
239 239 self.width = kwargs.get('width', None)
240 240 self.height = kwargs.get('height', None)
241 241 self.colorbar = kwargs.get('colorbar', True)
242 242 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
243 243 self.channels = kwargs.get('channels', None)
244 244 self.titles = kwargs.get('titles', [])
245 245 self.polar = False
246 246 self.type = kwargs.get('type', 'iq')
247 247 self.grid = kwargs.get('grid', False)
248 248 self.pause = kwargs.get('pause', False)
249 249 self.save_code = kwargs.get('save_code', self.CODE)
250 250 self.throttle = kwargs.get('throttle', 0)
251 251 self.exp_code = kwargs.get('exp_code', None)
252 252 self.server = kwargs.get('server', False)
253 253 self.sender_period = kwargs.get('sender_period', 60)
254 254 self.tag = kwargs.get('tag', '')
255 255 self.height_index = kwargs.get('height_index', None)
256 256 self.__throttle_plot = apply_throttle(self.throttle)
257 257 code = self.attr_data if self.attr_data else self.CODE
258 258 self.data = PlotterData(self.CODE, self.exp_code, self.localtime)
259 259 #self.EEJtype = kwargs.get('EEJtype', 2)
260 260
261 261 if self.server:
262 262 if not self.server.startswith('tcp://'):
263 263 self.server = 'tcp://{}'.format(self.server)
264 264 log.success(
265 265 'Sending to server: {}'.format(self.server),
266 266 self.name
267 267 )
268 268
269 269 if isinstance(self.attr_data, str):
270 270 self.attr_data = [self.attr_data]
271 271
272 272 def __setup_plot(self):
273 273 '''
274 274 Common setup for all figures, here figures and axes are created
275 275 '''
276 276
277 277 self.setup()
278 278
279 279 self.time_label = 'LT' if self.localtime else 'UTC'
280 280
281 281 if self.width is None:
282 282 self.width = 8
283 283
284 284 self.figures = []
285 285 self.axes = []
286 286 self.cb_axes = []
287 287 self.pf_axes = []
288 288 self.cmaps = []
289 289
290 290 size = '15%' if self.ncols == 1 else '30%'
291 291 pad = '4%' if self.ncols == 1 else '8%'
292 292
293 293 if self.oneFigure:
294 294 if self.height is None:
295 295 self.height = 1.4 * self.nrows + 1
296 296 fig = plt.figure(figsize=(self.width, self.height),
297 297 edgecolor='k',
298 298 facecolor='w')
299 299 self.figures.append(fig)
300 300 for n in range(self.nplots):
301 301 ax = fig.add_subplot(self.nrows, self.ncols,
302 302 n + 1, polar=self.polar)
303 303 ax.tick_params(labelsize=8)
304 304 ax.firsttime = True
305 305 ax.index = 0
306 306 ax.press = None
307 307 self.axes.append(ax)
308 308 if self.showprofile:
309 309 cax = self.__add_axes(ax, size=size, pad=pad)
310 310 cax.tick_params(labelsize=8)
311 311 self.pf_axes.append(cax)
312 312 else:
313 313 if self.height is None:
314 314 self.height = 3
315 315 for n in range(self.nplots):
316 316 fig = plt.figure(figsize=(self.width, self.height),
317 317 edgecolor='k',
318 318 facecolor='w')
319 319 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
320 320 ax.tick_params(labelsize=8)
321 321 ax.firsttime = True
322 322 ax.index = 0
323 323 ax.press = None
324 324 self.figures.append(fig)
325 325 self.axes.append(ax)
326 326 if self.showprofile:
327 327 cax = self.__add_axes(ax, size=size, pad=pad)
328 328 cax.tick_params(labelsize=8)
329 329 self.pf_axes.append(cax)
330 330
331 331 for n in range(self.nrows):
332 332 if self.colormaps is not None:
333 333 cmap = plt.get_cmap(self.colormaps[n])
334 334 else:
335 335 cmap = plt.get_cmap(self.colormap)
336 336 cmap.set_bad(self.bgcolor, 1.)
337 337 self.cmaps.append(cmap)
338 338
339 339 def __add_axes(self, ax, size='30%', pad='8%'):
340 340 '''
341 341 Add new axes to the given figure
342 342 '''
343 343 divider = make_axes_locatable(ax)
344 344 nax = divider.new_horizontal(size=size, pad=pad)
345 345 ax.figure.add_axes(nax)
346 346 return nax
347 347
348 348 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
349 349 '''
350 350 Create a masked array for missing data
351 351 '''
352 352 if x_buffer.shape[0] < 2:
353 353 return x_buffer, y_buffer, z_buffer
354 354
355 355 deltas = x_buffer[1:] - x_buffer[0:-1]
356 356 x_median = numpy.median(deltas)
357 357
358 358 index = numpy.where(deltas > 5 * x_median)
359 359
360 360 if len(index[0]) != 0:
361 361 z_buffer[::, index[0], ::] = self.__missing
362 362 z_buffer = numpy.ma.masked_inside(z_buffer,
363 363 0.99 * self.__missing,
364 364 1.01 * self.__missing)
365 365
366 366 return x_buffer, y_buffer, z_buffer
367 367
368 368 def decimate(self):
369 369
370 370 # dx = int(len(self.x)/self.__MAXNUMX) + 1
371 371 dy = int(len(self.y) / self.decimation) + 1
372 372
373 373 # x = self.x[::dx]
374 374 x = self.x
375 375 y = self.y[::dy]
376 376 z = self.z[::, ::, ::dy]
377 377
378 378 return x, y, z
379 379
380 380 def format(self):
381 381 '''
382 382 Set min and max values, labels, ticks and titles
383 383 '''
384 384
385 385 for n, ax in enumerate(self.axes):
386 386 if ax.firsttime:
387 387 if self.xaxis != 'time':
388 388 xmin = self.xmin
389 389 xmax = self.xmax
390 390 else:
391 391 xmin = self.tmin
392 392 xmax = self.tmin + self.xrange*60*60
393 393 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
394 394 ax.xaxis.set_major_locator(LinearLocator(9))
395 395 ymin = self.ymin if self.ymin is not None else numpy.nanmin(self.y[numpy.isfinite(self.y)])
396 396 ymax = self.ymax if self.ymax is not None else numpy.nanmax(self.y[numpy.isfinite(self.y)])
397 397 ax.set_facecolor(self.bgcolor)
398 398 if self.xscale:
399 399 ax.xaxis.set_major_formatter(FuncFormatter(
400 400 lambda x, pos: '{0:g}'.format(x*self.xscale)))
401 401 if self.yscale:
402 402 ax.yaxis.set_major_formatter(FuncFormatter(
403 403 lambda x, pos: '{0:g}'.format(x*self.yscale)))
404 404 if self.xlabel is not None:
405 405 ax.set_xlabel(self.xlabel)
406 406 if self.ylabel is not None:
407 407 ax.set_ylabel(self.ylabel)
408 408 if self.showprofile:
409 if self.zlimits is not None:
410 self.zmin, self.zmax = self.zlimits[n]
409 411 self.pf_axes[n].set_ylim(ymin, ymax)
410 self.pf_axes[n].set_xlim(self.zmin[n], self.zmax[n])
412 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
411 413 self.pf_axes[n].set_xlabel('dB')
412 414 self.pf_axes[n].grid(b=True, axis='x')
413 415 [tick.set_visible(False)
414 416 for tick in self.pf_axes[n].get_yticklabels()]
415 417 if self.colorbar:
416 418 ax.cbar = plt.colorbar(
417 419 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
418 420 ax.cbar.ax.tick_params(labelsize=8)
419 421 ax.cbar.ax.press = None
420 422 if self.cb_label:
421 423 ax.cbar.set_label(self.cb_label, size=8)
422 424 elif self.cb_labels:
423 425 ax.cbar.set_label(self.cb_labels[n], size=8)
424 426 else:
425 427 ax.cbar = None
426 428 ax.set_xlim(xmin, xmax)
427 429 ax.set_ylim(ymin, ymax)
428 430 ax.firsttime = False
429 431 if self.grid:
430 432 ax.grid(True)
431 433 if not self.polar:
432 434 ax.set_title('{} {} {}'.format(
433 435 self.titles[n],
434 436 self.getDateTime(self.data.max_time).strftime(
435 437 '%Y-%m-%d %H:%M:%S'),
436 438 self.time_label),
437 439 size=8)
438 440 else:
439 441 ax.set_title('{}'.format(self.titles[n]), size=8)
440 442 ax.set_ylim(0, 90)
441 443 ax.set_yticks(numpy.arange(0, 90, 20))
442 444 ax.yaxis.labelpad = 40
443 445
444 446 if self.firsttime:
445 447 for n, fig in enumerate(self.figures):
446 448 fig.subplots_adjust(**self.plots_adjust)
447 449 self.firsttime = False
448 450
449 451 def clear_figures(self):
450 452 '''
451 453 Reset axes for redraw plots
452 454 '''
453 455
454 456 for ax in self.axes+self.pf_axes+self.cb_axes:
455 457 ax.clear()
456 458 ax.firsttime = True
457 459 if hasattr(ax, 'cbar') and ax.cbar:
458 460 ax.cbar.remove()
459 461
460 462 def __plot(self):
461 463 '''
462 464 Main function to plot, format and save figures
463 465 '''
464 466
465 467 self.plot()
466 468 self.format()
467 469
468 470 for n, fig in enumerate(self.figures):
469 471 if self.nrows == 0 or self.nplots == 0:
470 472 log.warning('No data', self.name)
471 473 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
472 474 fig.canvas.manager.set_window_title(self.CODE)
473 475 continue
474 476
475 477 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
476 478 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
477 479 fig.canvas.draw()
478 480 if self.show:
479 481 fig.show()
480 482 figpause(0.01)
481 483
482 484 if self.save:
483 485 self.save_figure(n)
484 486
485 487 if self.server:
486 488 self.send_to_server()
487 489
488 490 def __update(self, dataOut, timestamp):
489 491 '''
490 492 '''
491 493
492 494 metadata = {
493 495 'yrange': dataOut.heightList,
494 496 'interval': dataOut.timeInterval,
495 497 'channels': dataOut.channelList
496 498 }
497 499
498 500 data, meta = self.update(dataOut)
499 501 metadata.update(meta)
500 502 self.data.update(data, timestamp, metadata)
501 503
502 504 def save_figure(self, n):
503 505 '''
504 506 '''
505 507
506 508 if (self.data.max_time - self.save_time) <= self.save_period:
507 509 return
508 510
509 511 self.save_time = self.data.max_time
510 512
511 513 fig = self.figures[n]
512 514
513 515 if self.throttle == 0:
514 516 figname = os.path.join(
515 517 self.save,
516 518 self.save_code,
517 519 '{}_{}.png'.format(
518 520 self.save_code,
519 521 self.getDateTime(self.data.max_time).strftime(
520 522 '%Y%m%d_%H%M%S'
521 523 ),
522 524 )
523 525 )
524 526 log.log('Saving figure: {}'.format(figname), self.name)
525 527 if not os.path.isdir(os.path.dirname(figname)):
526 528 os.makedirs(os.path.dirname(figname))
527 529 fig.savefig(figname)
528 530
529 531 figname = os.path.join(
530 532 self.save,
531 533 #self.save_code,
532 534 '{}_{}.png'.format(
533 535 self.save_code,
534 536 self.getDateTime(self.data.min_time).strftime(
535 537 '%Y%m%d'
536 538 ),
537 539 )
538 540 )
539 541 log.log('Saving figure: {}'.format(figname), self.name)
540 542 if not os.path.isdir(os.path.dirname(figname)):
541 543 os.makedirs(os.path.dirname(figname))
542 544 fig.savefig(figname)
543 545
544 546 def send_to_server(self):
545 547 '''
546 548 '''
547 549
548 550 if self.exp_code == None:
549 551 log.warning('Missing `exp_code` skipping sending to server...')
550 552
551 553 last_time = self.data.max_time
552 554 interval = last_time - self.sender_time
553 555 if interval < self.sender_period:
554 556 return
555 557
556 558 self.sender_time = last_time
557 559
558 560 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
559 561 for attr in attrs:
560 562 value = getattr(self, attr)
561 563 if value:
562 564 if isinstance(value, (numpy.float32, numpy.float64)):
563 565 value = round(float(value), 2)
564 566 self.data.meta[attr] = value
565 567 if self.colormap == 'jet':
566 568 self.data.meta['colormap'] = 'Jet'
567 569 elif 'RdBu' in self.colormap:
568 570 self.data.meta['colormap'] = 'RdBu'
569 571 else:
570 572 self.data.meta['colormap'] = 'Viridis'
571 573 self.data.meta['interval'] = int(interval)
572
574 #print(last_time)
575 #print(time.time())
576 #exit(1)
573 577 self.sender_queue.append(last_time)
574 578
575 579 while True:
576 580 try:
577 581 tm = self.sender_queue.popleft()
578 582 except IndexError:
579 583 break
580 584 msg = self.data.jsonify(tm, self.save_code, self.plot_type)
581 585 self.socket.send_string(msg)
582 586 socks = dict(self.poll.poll(2000))
583 587 if socks.get(self.socket) == zmq.POLLIN:
584 588 reply = self.socket.recv_string()
585 589 if reply == 'ok':
586 590 log.log("Response from server ok", self.name)
587 591 time.sleep(0.1)
588 592 continue
589 593 else:
590 594 log.warning(
591 595 "Malformed reply from server: {}".format(reply), self.name)
592 596 else:
593 597 log.warning(
594 598 "No response from server, retrying...", self.name)
595 599 self.sender_queue.appendleft(tm)
596 600 self.socket.setsockopt(zmq.LINGER, 0)
597 601 self.socket.close()
598 602 self.poll.unregister(self.socket)
599 603 self.socket = self.context.socket(zmq.REQ)
600 604 self.socket.connect(self.server)
601 605 self.poll.register(self.socket, zmq.POLLIN)
602 606 break
603 607
604 608 def setup(self):
605 609 '''
606 610 This method should be implemented in the child class, the following
607 611 attributes should be set:
608 612
609 613 self.nrows: number of rows
610 614 self.ncols: number of cols
611 615 self.nplots: number of plots (channels or pairs)
612 616 self.ylabel: label for Y axes
613 617 self.titles: list of axes title
614 618
615 619 '''
616 620 raise NotImplementedError
617 621
618 622 def plot(self):
619 623 '''
620 624 Must be defined in the child class, the actual plotting method
621 625 '''
622 626 raise NotImplementedError
623 627
624 628 def update(self, dataOut):
625 629 '''
626 630 Must be defined in the child class, update self.data with new data
627 631 '''
628 632
629 633 data = {
630 634 self.CODE: getattr(dataOut, 'data_{}'.format(self.CODE))
631 635 }
632 636 meta = {}
633 637
634 638 return data, meta
635 639
636 640 def run(self, dataOut, **kwargs):
637 641 '''
638 642 Main plotting routine
639 643 '''
640 644
641 645 if self.isConfig is False:
642 646 self.__setup(**kwargs)
643 647
644 648 if self.localtime:
645 649 self.getDateTime = datetime.datetime.fromtimestamp
646 650 else:
647 651 self.getDateTime = datetime.datetime.utcfromtimestamp
648 652
649 653 self.data.setup()
650 654 self.isConfig = True
651 655 if self.server:
652 656 self.context = zmq.Context()
653 657 self.socket = self.context.socket(zmq.REQ)
654 658 self.socket.connect(self.server)
655 659 self.poll = zmq.Poller()
656 660 self.poll.register(self.socket, zmq.POLLIN)
657 661
658 662 tm = getattr(dataOut, self.attr_time)
659 663
660 664 if self.data and 'time' in self.xaxis and (tm - self.tmin) >= self.xrange*60*60:
661 665 self.save_time = tm
662 666 self.__plot()
663 667 self.tmin += self.xrange*60*60
664 668 self.data.setup()
665 669 self.clear_figures()
666 670
667 671 self.__update(dataOut, tm)
668 672
669 673 if self.isPlotConfig is False:
670 674 self.__setup_plot()
671 675 self.isPlotConfig = True
672 676 if self.xaxis == 'time':
673 677 dt = self.getDateTime(tm)
674 678 if self.xmin is None:
675 679 self.tmin = tm
676 680 self.xmin = dt.hour
677 681 minutes = (self.xmin-int(self.xmin)) * 60
678 682 seconds = (minutes - int(minutes)) * 60
679 683 self.tmin = (dt.replace(hour=int(self.xmin), minute=int(minutes), second=int(seconds)) -
680 684 datetime.datetime(1970, 1, 1)).total_seconds()
681 685 if self.localtime:
682 686 self.tmin += time.timezone
683 687
684 688 if self.xmin is not None and self.xmax is not None:
685 689 self.xrange = self.xmax - self.xmin
686 690
687 691 if self.throttle == 0:
688 692 self.__plot()
689 693 else:
690 694 self.__throttle_plot(self.__plot)#, coerce=coerce)
691 695
692 696 def close(self):
693 697
694 698 if self.data and not self.data.flagNoData:
695 699 self.save_time = 0
696 700 self.__plot()
697 701 if self.data and not self.data.flagNoData and self.pause:
698 702 figpause(10)
@@ -1,1341 +1,1337
1 1 # Copyright (c) 2012-2021 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 import collections.abc
12 12
13 13 from schainpy.model.graphics.jroplot_base import Plot, plt, log
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 24
25 25 def setup(self):
26 26
27 27 self.nplots = len(self.data.channels)
28 28 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
29 29 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
30 30 self.height = 2.6 * self.nrows
31 31 self.cb_label = 'dB'
32 32 if self.showprofile:
33 33 self.width = 4 * self.ncols
34 34 else:
35 35 self.width = 3.5 * self.ncols
36 36 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
37 37 self.ylabel = 'Range [km]'
38 38
39 39 def update(self, dataOut):
40 40
41 41 data = {}
42 42 meta = {}
43 43
44 44 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
45 45 #print("Spc: ",spc[0])
46 46 #exit(1)
47 47 data['spc'] = spc
48 48 data['rti'] = dataOut.getPower()
49 49 #print(data['rti'][0])
50 50 #exit(1)
51 51 #print("NormFactor: ",dataOut.normFactor)
52 52 #data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
53 53 if hasattr(dataOut, 'LagPlot'): #Double Pulse
54 54 max_hei_id = dataOut.nHeights - 2*dataOut.LagPlot
55 55 #data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=46,ymax_index=max_hei_id)/dataOut.normFactor)
56 56 #data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=40,ymax_index=max_hei_id)/dataOut.normFactor)
57 57 data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=53,ymax_index=max_hei_id)/dataOut.normFactor)
58 58 data['noise'][0] = 10*numpy.log10(dataOut.getNoise(ymin_index=53)[0]/dataOut.normFactor)
59 59 #data['noise'][1] = 22.035507
60 60 else:
61 61 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
62 62 #data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=26,ymax_index=44)/dataOut.normFactor)
63 63 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
64 64
65 65 if self.CODE == 'spc_moments':
66 66 data['moments'] = dataOut.moments
67 67 if self.CODE == 'gaussian_fit':
68 68 data['gaussfit'] = dataOut.DGauFitParams
69 69
70 70 return data, meta
71 71
72 72 def plot(self):
73 73
74 74 if self.xaxis == "frequency":
75 75 x = self.data.xrange[0]
76 76 self.xlabel = "Frequency (kHz)"
77 77 elif self.xaxis == "time":
78 78 x = self.data.xrange[1]
79 79 self.xlabel = "Time (ms)"
80 80 else:
81 81 x = self.data.xrange[2]
82 82 self.xlabel = "Velocity (m/s)"
83 83
84 84 if (self.CODE == 'spc_moments') | (self.CODE == 'gaussian_fit'):
85 85 x = self.data.xrange[2]
86 86 self.xlabel = "Velocity (m/s)"
87 87
88 88 self.titles = []
89 89
90 90 y = self.data.yrange
91 91 self.y = y
92 92
93 93 data = self.data[-1]
94 94 z = data['spc']
95 95
96 96 self.CODE2 = 'spc_oblique'
97 97
98 if not isinstance(self.zmin, collections.abc.Sequence):
99 if not self.zmin:
100 self.zmin = [numpy.min(self.z)]*len(self.axes)
101 else:
102 self.zmin = [self.zmin]*len(self.axes)
103
104 if not isinstance(self.zmax, collections.abc.Sequence):
105 if not self.zmax:
106 self.zmax = [numpy.max(self.z)]*len(self.axes)
107 else:
108 self.zmax = [self.zmax]*len(self.axes)
109
110 98 for n, ax in enumerate(self.axes):
111 99 noise = data['noise'][n]
112 100 if self.CODE == 'spc_moments':
113 101 mean = data['moments'][n, 1]
114 102 if self.CODE == 'gaussian_fit':
115 103 gau0 = data['gaussfit'][n][2,:,0]
116 104 gau1 = data['gaussfit'][n][2,:,1]
117 105 if ax.firsttime:
118 106 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
119 107 self.xmin = self.xmin if self.xmin else numpy.nanmin(x)#-self.xmax
120 108 #self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
121 109 #self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
110 if self.zlimits is not None:
111 self.zmin, self.zmax = self.zlimits[n]
122 112
123 113 ax.plt = ax.pcolormesh(x, y, z[n].T,
124 vmin=self.zmin[n],
125 vmax=self.zmax[n],
114 vmin=self.zmin,
115 vmax=self.zmax,
126 116 cmap=plt.get_cmap(self.colormap),
127 117 )
128 118
129 119 if self.showprofile:
130 120 ax.plt_profile = self.pf_axes[n].plot(
131 121 data['rti'][n], y)[0]
132 122 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
133 123 color="k", linestyle="dashed", lw=1)[0]
134 124 if self.CODE == 'spc_moments':
135 125 ax.plt_mean = ax.plot(mean, y, color='k', lw=1)[0]
136 126 if self.CODE == 'gaussian_fit':
137 127 ax.plt_gau0 = ax.plot(gau0, y, color='r', lw=1)[0]
138 128 ax.plt_gau1 = ax.plot(gau1, y, color='y', lw=1)[0]
139 129 else:
130 if self.zlimits is not None:
131 self.zmin, self.zmax = self.zlimits[n]
140 132 ax.plt.set_array(z[n].T.ravel())
141 133 if self.showprofile:
142 134 ax.plt_profile.set_data(data['rti'][n], y)
143 135 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
144 136 if self.CODE == 'spc_moments':
145 137 ax.plt_mean.set_data(mean, y)
146 138 if self.CODE == 'gaussian_fit':
147 139 ax.plt_gau0.set_data(gau0, y)
148 140 ax.plt_gau1.set_data(gau1, y)
149 141 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
150 142
151 143 class SpectraObliquePlot(Plot):
152 144 '''
153 145 Plot for Spectra data
154 146 '''
155 147
156 148 CODE = 'spc_oblique'
157 149 colormap = 'jet'
158 150 plot_type = 'pcolor'
159 151
160 152 def setup(self):
161 153 self.xaxis = "oblique"
162 154 self.nplots = len(self.data.channels)
163 155 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
164 156 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
165 157 self.height = 2.6 * self.nrows
166 158 self.cb_label = 'dB'
167 159 if self.showprofile:
168 160 self.width = 4 * self.ncols
169 161 else:
170 162 self.width = 3.5 * self.ncols
171 163 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
172 164 self.ylabel = 'Range [km]'
173 165
174 166 def update(self, dataOut):
175 167
176 168 data = {}
177 169 meta = {}
178 170 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
179 171 data['spc'] = spc
180 172 data['rti'] = dataOut.getPower()
181 173 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
182 174 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
183 175 '''
184 176 data['shift1'] = dataOut.Oblique_params[0,-2,:]
185 177 data['shift2'] = dataOut.Oblique_params[0,-1,:]
186 178 data['shift1_error'] = dataOut.Oblique_param_errors[0,-2,:]
187 179 data['shift2_error'] = dataOut.Oblique_param_errors[0,-1,:]
188 180 '''
189 181 '''
190 182 data['shift1'] = dataOut.Oblique_params[0,1,:]
191 183 data['shift2'] = dataOut.Oblique_params[0,4,:]
192 184 data['shift1_error'] = dataOut.Oblique_param_errors[0,1,:]
193 185 data['shift2_error'] = dataOut.Oblique_param_errors[0,4,:]
194 186 '''
195 187 data['shift1'] = dataOut.Dop_EEJ_T1[0]
196 188 data['shift2'] = dataOut.Dop_EEJ_T2[0]
197 189 data['shift1_error'] = dataOut.Err_Dop_EEJ_T1[0]
198 190 data['shift2_error'] = dataOut.Err_Dop_EEJ_T2[0]
199 191
200 192 return data, meta
201 193
202 194 def plot(self):
203 195
204 196 if self.xaxis == "frequency":
205 197 x = self.data.xrange[0]
206 198 self.xlabel = "Frequency (kHz)"
207 199 elif self.xaxis == "time":
208 200 x = self.data.xrange[1]
209 201 self.xlabel = "Time (ms)"
210 202 else:
211 203 x = self.data.xrange[2]
212 204 self.xlabel = "Velocity (m/s)"
213 205
214 206 self.titles = []
215 207
216 208 y = self.data.yrange
217 209 self.y = y
218 210
219 211 data = self.data[-1]
220 212 z = data['spc']
221 213
222 214 for n, ax in enumerate(self.axes):
223 215 noise = self.data['noise'][n][-1]
224 216 shift1 = data['shift1']
225 217 #print(shift1)
226 218 shift2 = data['shift2']
227 219 err1 = data['shift1_error']
228 220 err2 = data['shift2_error']
229 221 if ax.firsttime:
230 222
231 223 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
232 224 self.xmin = self.xmin if self.xmin else -self.xmax
233 225 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
234 226 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
235 227 ax.plt = ax.pcolormesh(x, y, z[n].T,
236 228 vmin=self.zmin,
237 229 vmax=self.zmax,
238 230 cmap=plt.get_cmap(self.colormap)
239 231 )
240 232
241 233 if self.showprofile:
242 234 ax.plt_profile = self.pf_axes[n].plot(
243 235 self.data['rti'][n][-1], y)[0]
244 236 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
245 237 color="k", linestyle="dashed", lw=1)[0]
246 238
247 239 self.ploterr1 = ax.errorbar(shift1, y, xerr=err1, fmt='k^', elinewidth=2.2, marker='o', linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
248 240 self.ploterr2 = ax.errorbar(shift2, y, xerr=err2, fmt='m^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
249 241 #print("plotter1: ", self.ploterr1,shift1)
250 242
251 243 else:
252 244 #print("else plotter1: ", self.ploterr1,shift1)
253 245 self.ploterr1.remove()
254 246 self.ploterr2.remove()
255 247 ax.plt.set_array(z[n].T.ravel())
256 248 if self.showprofile:
257 249 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
258 250 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
259 251 self.ploterr1 = ax.errorbar(shift1, y, xerr=err1, fmt='k^', elinewidth=2.2, marker='o', linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
260 252 self.ploterr2 = ax.errorbar(shift2, y, xerr=err2, fmt='m^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
261 253
262 254 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
263 255
264 256
265 257 class CrossSpectraPlot(Plot):
266 258
267 259 CODE = 'cspc'
268 260 colormap = 'jet'
269 261 plot_type = 'pcolor'
270 262 zmin_coh = None
271 263 zmax_coh = None
272 264 zmin_phase = None
273 265 zmax_phase = None
274 266
275 267 def setup(self):
276 268
277 269 self.ncols = 4
278 270 self.nplots = len(self.data.pairs) * 2
279 271 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
280 272 self.width = 3.1 * self.ncols
281 273 self.height = 5 * self.nrows
282 274 self.ylabel = 'Range [km]'
283 275 self.showprofile = False
284 276 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
285 277
286 278 def update(self, dataOut):
287 279
288 280 data = {}
289 281 meta = {}
290 282
291 283 spc = dataOut.data_spc
292 284 cspc = dataOut.data_cspc
293 285 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
294 286 meta['pairs'] = dataOut.pairsList
295 287
296 288 tmp = []
297 289
298 290 for n, pair in enumerate(meta['pairs']):
299 291 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
300 292 coh = numpy.abs(out)
301 293 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
302 294 tmp.append(coh)
303 295 tmp.append(phase)
304 296
305 297 data['cspc'] = numpy.array(tmp)
306 298
307 299 return data, meta
308 300
309 301 def plot(self):
310 302
311 303 if self.xaxis == "frequency":
312 304 x = self.data.xrange[0]
313 305 self.xlabel = "Frequency (kHz)"
314 306 elif self.xaxis == "time":
315 307 x = self.data.xrange[1]
316 308 self.xlabel = "Time (ms)"
317 309 else:
318 310 x = self.data.xrange[2]
319 311 self.xlabel = "Velocity (m/s)"
320 312
321 313 self.titles = []
322 314
323 315 y = self.data.yrange
324 316 self.y = y
325 317
326 318 data = self.data[-1]
327 319 cspc = data['cspc']
328 320
329 321 for n in range(len(self.data.pairs)):
330 322 pair = self.data.pairs[n]
331 323 coh = cspc[n*2]
332 324 phase = cspc[n*2+1]
333 325 ax = self.axes[2 * n]
334 326 if ax.firsttime:
335 327 ax.plt = ax.pcolormesh(x, y, coh.T,
336 328 vmin=0,
337 329 vmax=1,
338 330 cmap=plt.get_cmap(self.colormap_coh)
339 331 )
340 332 else:
341 333 ax.plt.set_array(coh.T.ravel())
342 334 self.titles.append(
343 335 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
344 336
345 337 ax = self.axes[2 * n + 1]
346 338 if ax.firsttime:
347 339 ax.plt = ax.pcolormesh(x, y, phase.T,
348 340 vmin=-180,
349 341 vmax=180,
350 342 cmap=plt.get_cmap(self.colormap_phase)
351 343 )
352 344 else:
353 345 ax.plt.set_array(phase.T.ravel())
354 346 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
355 347
356 348
357 349 class CrossSpectra4Plot(Plot):
358 350
359 351 CODE = 'cspc'
360 352 colormap = 'jet'
361 353 plot_type = 'pcolor'
362 354 zmin_coh = None
363 355 zmax_coh = None
364 356 zmin_phase = None
365 357 zmax_phase = None
366 358
367 359 def setup(self):
368 360
369 361 self.ncols = 4
370 362 self.nrows = len(self.data.pairs)
371 363 self.nplots = self.nrows * 4
372 364 self.width = 3.1 * self.ncols
373 365 self.height = 5 * self.nrows
374 366 self.ylabel = 'Range [km]'
375 367 self.showprofile = False
376 368 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
377 369
378 370 def plot(self):
379 371
380 372 if self.xaxis == "frequency":
381 373 x = self.data.xrange[0]
382 374 self.xlabel = "Frequency (kHz)"
383 375 elif self.xaxis == "time":
384 376 x = self.data.xrange[1]
385 377 self.xlabel = "Time (ms)"
386 378 else:
387 379 x = self.data.xrange[2]
388 380 self.xlabel = "Velocity (m/s)"
389 381
390 382 self.titles = []
391 383
392 384
393 385 y = self.data.heights
394 386 self.y = y
395 387 nspc = self.data['spc']
396 388 #print(numpy.shape(self.data['spc']))
397 389 spc = self.data['cspc'][0]
398 390 #print(numpy.shape(nspc))
399 391 #exit()
400 392 #nspc[1,:,:] = numpy.flip(nspc[1,:,:],axis=0)
401 393 #print(numpy.shape(spc))
402 394 #exit()
403 395 cspc = self.data['cspc'][1]
404 396
405 397 #xflip=numpy.flip(x)
406 398 #print(numpy.shape(cspc))
407 399 #exit()
408 400
409 401 for n in range(self.nrows):
410 402 noise = self.data['noise'][:,-1]
411 403 pair = self.data.pairs[n]
412 404 #print(pair)
413 405 #exit()
414 406 ax = self.axes[4 * n]
415 407 if ax.firsttime:
416 408 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
417 409 self.xmin = self.xmin if self.xmin else -self.xmax
418 410 self.zmin = self.zmin if self.zmin else numpy.nanmin(nspc)
419 411 self.zmax = self.zmax if self.zmax else numpy.nanmax(nspc)
420 412 ax.plt = ax.pcolormesh(x , y , nspc[pair[0]].T,
421 413 vmin=self.zmin,
422 414 vmax=self.zmax,
423 415 cmap=plt.get_cmap(self.colormap)
424 416 )
425 417 else:
426 418 #print(numpy.shape(nspc[pair[0]].T))
427 419 #exit()
428 420 ax.plt.set_array(nspc[pair[0]].T.ravel())
429 421 self.titles.append('CH {}: {:3.2f}dB'.format(pair[0], noise[pair[0]]))
430 422
431 423 ax = self.axes[4 * n + 1]
432 424
433 425 if ax.firsttime:
434 426 ax.plt = ax.pcolormesh(x , y, numpy.flip(nspc[pair[1]],axis=0).T,
435 427 vmin=self.zmin,
436 428 vmax=self.zmax,
437 429 cmap=plt.get_cmap(self.colormap)
438 430 )
439 431 else:
440 432
441 433 ax.plt.set_array(numpy.flip(nspc[pair[1]],axis=0).T.ravel())
442 434 self.titles.append('CH {}: {:3.2f}dB'.format(pair[1], noise[pair[1]]))
443 435
444 436 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
445 437 coh = numpy.abs(out)
446 438 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
447 439
448 440 ax = self.axes[4 * n + 2]
449 441 if ax.firsttime:
450 442 ax.plt = ax.pcolormesh(x, y, numpy.flip(coh,axis=0).T,
451 443 vmin=0,
452 444 vmax=1,
453 445 cmap=plt.get_cmap(self.colormap_coh)
454 446 )
455 447 else:
456 448 ax.plt.set_array(numpy.flip(coh,axis=0).T.ravel())
457 449 self.titles.append(
458 450 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
459 451
460 452 ax = self.axes[4 * n + 3]
461 453 if ax.firsttime:
462 454 ax.plt = ax.pcolormesh(x, y, numpy.flip(phase,axis=0).T,
463 455 vmin=-180,
464 456 vmax=180,
465 457 cmap=plt.get_cmap(self.colormap_phase)
466 458 )
467 459 else:
468 460 ax.plt.set_array(numpy.flip(phase,axis=0).T.ravel())
469 461 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
470 462
471 463
472 464 class CrossSpectra2Plot(Plot):
473 465
474 466 CODE = 'cspc'
475 467 colormap = 'jet'
476 468 plot_type = 'pcolor'
477 469 zmin_coh = None
478 470 zmax_coh = None
479 471 zmin_phase = None
480 472 zmax_phase = None
481 473
482 474 def setup(self):
483 475
484 476 self.ncols = 1
485 477 self.nrows = len(self.data.pairs)
486 478 self.nplots = self.nrows * 1
487 479 self.width = 3.1 * self.ncols
488 480 self.height = 5 * self.nrows
489 481 self.ylabel = 'Range [km]'
490 482 self.showprofile = False
491 483 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
492 484
493 485 def plot(self):
494 486
495 487 if self.xaxis == "frequency":
496 488 x = self.data.xrange[0]
497 489 self.xlabel = "Frequency (kHz)"
498 490 elif self.xaxis == "time":
499 491 x = self.data.xrange[1]
500 492 self.xlabel = "Time (ms)"
501 493 else:
502 494 x = self.data.xrange[2]
503 495 self.xlabel = "Velocity (m/s)"
504 496
505 497 self.titles = []
506 498
507 499
508 500 y = self.data.heights
509 501 self.y = y
510 502 #nspc = self.data['spc']
511 503 #print(numpy.shape(self.data['spc']))
512 504 #spc = self.data['cspc'][0]
513 505 #print(numpy.shape(spc))
514 506 #exit()
515 507 cspc = self.data['cspc'][1]
516 508 #print(numpy.shape(cspc))
517 509 #exit()
518 510
519 511 for n in range(self.nrows):
520 512 noise = self.data['noise'][:,-1]
521 513 pair = self.data.pairs[n]
522 514 #print(pair) #exit()
523 515
524 516
525 517
526 518 out = cspc[n]# / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
527 519
528 520 #print(out[:,53])
529 521 #exit()
530 522 cross = numpy.abs(out)
531 523 z = cross/self.data.nFactor
532 524 #print("here")
533 525 #print(dataOut.data_spc[0,0,0])
534 526 #exit()
535 527
536 528 cross = 10*numpy.log10(z)
537 529 #print(numpy.shape(cross))
538 530 #print(cross[0,:])
539 531 #print(self.data.nFactor)
540 532 #exit()
541 533 #phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
542 534
543 535 ax = self.axes[1 * n]
544 536 if ax.firsttime:
545 537 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
546 538 self.xmin = self.xmin if self.xmin else -self.xmax
547 539 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
548 540 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
549 541 ax.plt = ax.pcolormesh(x, y, cross.T,
550 542 vmin=self.zmin,
551 543 vmax=self.zmax,
552 544 cmap=plt.get_cmap(self.colormap)
553 545 )
554 546 else:
555 547 ax.plt.set_array(cross.T.ravel())
556 548 self.titles.append(
557 549 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
558 550
559 551
560 552 class CrossSpectra3Plot(Plot):
561 553
562 554 CODE = 'cspc'
563 555 colormap = 'jet'
564 556 plot_type = 'pcolor'
565 557 zmin_coh = None
566 558 zmax_coh = None
567 559 zmin_phase = None
568 560 zmax_phase = None
569 561
570 562 def setup(self):
571 563
572 564 self.ncols = 3
573 565 self.nrows = len(self.data.pairs)
574 566 self.nplots = self.nrows * 3
575 567 self.width = 3.1 * self.ncols
576 568 self.height = 5 * self.nrows
577 569 self.ylabel = 'Range [km]'
578 570 self.showprofile = False
579 571 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
580 572
581 573 def plot(self):
582 574
583 575 if self.xaxis == "frequency":
584 576 x = self.data.xrange[0]
585 577 self.xlabel = "Frequency (kHz)"
586 578 elif self.xaxis == "time":
587 579 x = self.data.xrange[1]
588 580 self.xlabel = "Time (ms)"
589 581 else:
590 582 x = self.data.xrange[2]
591 583 self.xlabel = "Velocity (m/s)"
592 584
593 585 self.titles = []
594 586
595 587
596 588 y = self.data.heights
597 589 self.y = y
598 590 #nspc = self.data['spc']
599 591 #print(numpy.shape(self.data['spc']))
600 592 #spc = self.data['cspc'][0]
601 593 #print(numpy.shape(spc))
602 594 #exit()
603 595 cspc = self.data['cspc'][1]
604 596 #print(numpy.shape(cspc))
605 597 #exit()
606 598
607 599 for n in range(self.nrows):
608 600 noise = self.data['noise'][:,-1]
609 601 pair = self.data.pairs[n]
610 602 #print(pair) #exit()
611 603
612 604
613 605
614 606 out = cspc[n]# / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
615 607
616 608 #print(out[:,53])
617 609 #exit()
618 610 cross = numpy.abs(out)
619 611 z = cross/self.data.nFactor
620 612 cross = 10*numpy.log10(z)
621 613
622 614 out_r= out.real/self.data.nFactor
623 615 #out_r = 10*numpy.log10(out_r)
624 616
625 617 out_i= out.imag/self.data.nFactor
626 618 #out_i = 10*numpy.log10(out_i)
627 619 #print(numpy.shape(cross))
628 620 #print(cross[0,:])
629 621 #print(self.data.nFactor)
630 622 #exit()
631 623 #phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
632 624
633 625 ax = self.axes[3 * n]
634 626 if ax.firsttime:
635 627 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
636 628 self.xmin = self.xmin if self.xmin else -self.xmax
637 629 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
638 630 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
639 631 ax.plt = ax.pcolormesh(x, y, cross.T,
640 632 vmin=self.zmin,
641 633 vmax=self.zmax,
642 634 cmap=plt.get_cmap(self.colormap)
643 635 )
644 636 else:
645 637 ax.plt.set_array(cross.T.ravel())
646 638 self.titles.append(
647 639 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
648 640
649 641 ax = self.axes[3 * n + 1]
650 642 if ax.firsttime:
651 643 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
652 644 self.xmin = self.xmin if self.xmin else -self.xmax
653 645 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
654 646 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
655 647 ax.plt = ax.pcolormesh(x, y, out_r.T,
656 648 vmin=-1.e6,
657 649 vmax=0,
658 650 cmap=plt.get_cmap(self.colormap)
659 651 )
660 652 else:
661 653 ax.plt.set_array(out_r.T.ravel())
662 654 self.titles.append(
663 655 'Cross Spectra Real Ch{} * Ch{}'.format(pair[0], pair[1]))
664 656
665 657 ax = self.axes[3 * n + 2]
666 658
667 659
668 660 if ax.firsttime:
669 661 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
670 662 self.xmin = self.xmin if self.xmin else -self.xmax
671 663 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
672 664 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
673 665 ax.plt = ax.pcolormesh(x, y, out_i.T,
674 666 vmin=-1.e6,
675 667 vmax=1.e6,
676 668 cmap=plt.get_cmap(self.colormap)
677 669 )
678 670 else:
679 671 ax.plt.set_array(out_i.T.ravel())
680 672 self.titles.append(
681 673 'Cross Spectra Imag Ch{} * Ch{}'.format(pair[0], pair[1]))
682 674
683 675 class RTIPlot(Plot):
684 676 '''
685 677 Plot for RTI data
686 678 '''
687 679
688 680 CODE = 'rti'
689 681 colormap = 'jet'
690 682 plot_type = 'pcolorbuffer'
691 683
692 684 def setup(self):
693 685 self.xaxis = 'time'
694 686 self.ncols = 1
695 687 self.nrows = len(self.data.channels)
696 688 self.nplots = len(self.data.channels)
697 689 self.ylabel = 'Range [km]'
698 690 self.xlabel = 'Time'
699 691 self.cb_label = 'dB'
700 692 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
701 693 self.titles = ['{} Channel {}'.format(
702 694 self.CODE.upper(), x) for x in range(self.nrows)]
703 695
704 696 def update(self, dataOut):
705 697
706 698 data = {}
707 699 meta = {}
708 700 data['rti'] = dataOut.getPower()
709 701 #print(numpy.shape(data['rti']))
710 702
711 703 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
712 704
713 705 return data, meta
714 706
715 707 def plot(self):
716 708
717 709 self.x = self.data.times
718 710 self.y = self.data.yrange
719 711 self.z = self.data[self.CODE]
720 712
721 713 self.z = numpy.ma.masked_invalid(self.z)
722 714
723 715 if self.decimation is None:
724 716 x, y, z = self.fill_gaps(self.x, self.y, self.z)
725 717 else:
726 718 x, y, z = self.fill_gaps(*self.decimate())
727 719
728
720 '''
729 721 if not isinstance(self.zmin, collections.abc.Sequence):
730 722 if not self.zmin:
731 723 self.zmin = [numpy.min(self.z)]*len(self.axes)
732 724 else:
733 725 self.zmin = [self.zmin]*len(self.axes)
734 726
735 727 if not isinstance(self.zmax, collections.abc.Sequence):
736 728 if not self.zmax:
737 729 self.zmax = [numpy.max(self.z)]*len(self.axes)
738 730 else:
739 731 self.zmax = [self.zmax]*len(self.axes)
740
732 '''
741 733 for n, ax in enumerate(self.axes):
742 734
743 #self.zmin = self.zmin if self.zmin else numpy.min(self.z)
744 #self.zmax = self.zmax if self.zmax else numpy.max(self.z)
735 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
736 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
745 737
746 738 if ax.firsttime:
739 if self.zlimits is not None:
740 self.zmin, self.zmax = self.zlimits[n]
747 741 ax.plt = ax.pcolormesh(x, y, z[n].T,
748 vmin=self.zmin[n],
749 vmax=self.zmax[n],
742 vmin=self.zmin,
743 vmax=self.zmax,
750 744 cmap=plt.get_cmap(self.colormap)
751 745 )
752 746 if self.showprofile:
753 747 ax.plot_profile = self.pf_axes[n].plot(
754 748 self.data['rti'][n][-1], self.y)[0]
755 749 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
756 750 color="k", linestyle="dashed", lw=1)[0]
757 751 else:
752 if self.zlimits is not None:
753 self.zmin, self.zmax = self.zlimits[n]
758 754 ax.collections.remove(ax.collections[0])
759 755 ax.plt = ax.pcolormesh(x, y, z[n].T,
760 vmin=self.zmin[n],
761 vmax=self.zmax[n],
756 vmin=self.zmin,
757 vmax=self.zmax,
762 758 cmap=plt.get_cmap(self.colormap)
763 759 )
764 760 if self.showprofile:
765 761 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
766 762 ax.plot_noise.set_data(numpy.repeat(
767 763 self.data['noise'][n][-1], len(self.y)), self.y)
768 764
769 765
770 766 class SpectrogramPlot(Plot):
771 767 '''
772 768 Plot for Spectrogram data
773 769 '''
774 770
775 771 CODE = 'Spectrogram_Profile'
776 772 colormap = 'binary'
777 773 plot_type = 'pcolorbuffer'
778 774
779 775 def setup(self):
780 776 self.xaxis = 'time'
781 777 self.ncols = 1
782 778 self.nrows = len(self.data.channels)
783 779 self.nplots = len(self.data.channels)
784 780 self.xlabel = 'Time'
785 781 #self.cb_label = 'dB'
786 782 self.plots_adjust.update({'hspace':1.2, 'left': 0.1, 'bottom': 0.12, 'right':0.95})
787 783 self.titles = []
788 784
789 785 #self.titles = ['{} Channel {} \n H = {} km ({} - {})'.format(
790 786 #self.CODE.upper(), x, self.data.heightList[self.data.hei], self.data.heightList[self.data.hei],self.data.heightList[self.data.hei]+(self.data.DH*self.data.nProfiles)) for x in range(self.nrows)]
791 787
792 788 self.titles = ['{} Channel {}'.format(
793 789 self.CODE.upper(), x) for x in range(self.nrows)]
794 790
795 791
796 792 def update(self, dataOut):
797 793 data = {}
798 794 meta = {}
799 795
800 796 maxHei = 1620#+12000
801 797 indb = numpy.where(dataOut.heightList <= maxHei)
802 798 hei = indb[0][-1]
803 799 #print(dataOut.heightList)
804 800
805 801 factor = dataOut.nIncohInt
806 802 z = dataOut.data_spc[:,:,hei] / factor
807 803 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
808 804 #buffer = 10 * numpy.log10(z)
809 805
810 806 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
811 807
812 808
813 809 #self.hei = hei
814 810 #self.heightList = dataOut.heightList
815 811 #self.DH = (dataOut.heightList[1] - dataOut.heightList[0])/dataOut.step
816 812 #self.nProfiles = dataOut.nProfiles
817 813
818 814 data['Spectrogram_Profile'] = 10 * numpy.log10(z)
819 815
820 816 data['hei'] = hei
821 817 data['DH'] = (dataOut.heightList[1] - dataOut.heightList[0])/dataOut.step
822 818 data['nProfiles'] = dataOut.nProfiles
823 819 #meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
824 820 '''
825 821 import matplotlib.pyplot as plt
826 822 plt.plot(10 * numpy.log10(z[0,:]))
827 823 plt.show()
828 824
829 825 from time import sleep
830 826 sleep(10)
831 827 '''
832 828 return data, meta
833 829
834 830 def plot(self):
835 831
836 832 self.x = self.data.times
837 833 self.z = self.data[self.CODE]
838 834 self.y = self.data.xrange[0]
839 835
840 836 hei = self.data['hei'][-1]
841 837 DH = self.data['DH'][-1]
842 838 nProfiles = self.data['nProfiles'][-1]
843 839
844 840 self.ylabel = "Frequency (kHz)"
845 841
846 842 self.z = numpy.ma.masked_invalid(self.z)
847 843
848 844 if self.decimation is None:
849 845 x, y, z = self.fill_gaps(self.x, self.y, self.z)
850 846 else:
851 847 x, y, z = self.fill_gaps(*self.decimate())
852 848
853 849 for n, ax in enumerate(self.axes):
854 850 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
855 851 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
856 852 data = self.data[-1]
857 853 if ax.firsttime:
858 854 ax.plt = ax.pcolormesh(x, y, z[n].T,
859 855 vmin=self.zmin,
860 856 vmax=self.zmax,
861 857 cmap=plt.get_cmap(self.colormap)
862 858 )
863 859 else:
864 860 ax.collections.remove(ax.collections[0])
865 861 ax.plt = ax.pcolormesh(x, y, z[n].T,
866 862 vmin=self.zmin,
867 863 vmax=self.zmax,
868 864 cmap=plt.get_cmap(self.colormap)
869 865 )
870 866
871 867 #self.titles.append('Spectrogram')
872 868
873 869 #self.titles.append('{} Channel {} \n H = {} km ({} - {})'.format(
874 870 #self.CODE.upper(), x, y[hei], y[hei],y[hei]+(DH*nProfiles)))
875 871
876 872
877 873
878 874
879 875 class CoherencePlot(RTIPlot):
880 876 '''
881 877 Plot for Coherence data
882 878 '''
883 879
884 880 CODE = 'coh'
885 881
886 882 def setup(self):
887 883 self.xaxis = 'time'
888 884 self.ncols = 1
889 885 self.nrows = len(self.data.pairs)
890 886 self.nplots = len(self.data.pairs)
891 887 self.ylabel = 'Range [km]'
892 888 self.xlabel = 'Time'
893 889 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
894 890 if self.CODE == 'coh':
895 891 self.cb_label = ''
896 892 self.titles = [
897 893 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
898 894 else:
899 895 self.cb_label = 'Degrees'
900 896 self.titles = [
901 897 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
902 898
903 899 def update(self, dataOut):
904 900
905 901 data = {}
906 902 meta = {}
907 903 data['coh'] = dataOut.getCoherence()
908 904 meta['pairs'] = dataOut.pairsList
909 905
910 906 return data, meta
911 907
912 908 class PhasePlot(CoherencePlot):
913 909 '''
914 910 Plot for Phase map data
915 911 '''
916 912
917 913 CODE = 'phase'
918 914 colormap = 'seismic'
919 915
920 916 def update(self, dataOut):
921 917
922 918 data = {}
923 919 meta = {}
924 920 data['phase'] = dataOut.getCoherence(phase=True)
925 921 meta['pairs'] = dataOut.pairsList
926 922
927 923 return data, meta
928 924
929 925 class NoisePlot(Plot):
930 926 '''
931 927 Plot for noise
932 928 '''
933 929
934 930 CODE = 'noise'
935 931 plot_type = 'scatterbuffer'
936 932
937 933 def setup(self):
938 934 self.xaxis = 'time'
939 935 self.ncols = 1
940 936 self.nrows = 1
941 937 self.nplots = 1
942 938 self.ylabel = 'Intensity [dB]'
943 939 self.xlabel = 'Time'
944 940 self.titles = ['Noise']
945 941 self.colorbar = False
946 942 self.plots_adjust.update({'right': 0.85 })
947 943
948 944 def update(self, dataOut):
949 945
950 946 data = {}
951 947 meta = {}
952 948 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor).reshape(dataOut.nChannels, 1)
953 949 meta['yrange'] = numpy.array([])
954 950
955 951 return data, meta
956 952
957 953 def plot(self):
958 954
959 955 x = self.data.times
960 956 xmin = self.data.min_time
961 957 xmax = xmin + self.xrange * 60 * 60
962 958 Y = self.data['noise']
963 959
964 960 if self.axes[0].firsttime:
965 961 self.ymin = numpy.nanmin(Y) - 5
966 962 self.ymax = numpy.nanmax(Y) + 5
967 963 for ch in self.data.channels:
968 964 y = Y[ch]
969 965 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
970 966 plt.legend(bbox_to_anchor=(1.18, 1.0))
971 967 else:
972 968 for ch in self.data.channels:
973 969 y = Y[ch]
974 970 self.axes[0].lines[ch].set_data(x, y)
975 971
976 972 self.ymin = numpy.nanmin(Y) - 5
977 973 self.ymax = numpy.nanmax(Y) + 10
978 974
979 975
980 976 class PowerProfilePlot(Plot):
981 977
982 978 CODE = 'pow_profile'
983 979 plot_type = 'scatter'
984 980
985 981 def setup(self):
986 982
987 983 self.ncols = 1
988 984 self.nrows = 1
989 985 self.nplots = 1
990 986 self.height = 4
991 987 self.width = 3
992 988 self.ylabel = 'Range [km]'
993 989 self.xlabel = 'Intensity [dB]'
994 990 self.titles = ['Power Profile']
995 991 self.colorbar = False
996 992
997 993 def update(self, dataOut):
998 994
999 995 data = {}
1000 996 meta = {}
1001 997 data[self.CODE] = dataOut.getPower()
1002 998
1003 999 return data, meta
1004 1000
1005 1001 def plot(self):
1006 1002
1007 1003 y = self.data.yrange
1008 1004 self.y = y
1009 1005
1010 1006 x = self.data[-1][self.CODE]
1011 1007
1012 1008 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
1013 1009 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
1014 1010
1015 1011 if self.axes[0].firsttime:
1016 1012 for ch in self.data.channels:
1017 1013 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
1018 1014 plt.legend()
1019 1015 else:
1020 1016 for ch in self.data.channels:
1021 1017 self.axes[0].lines[ch].set_data(x[ch], y)
1022 1018
1023 1019
1024 1020 class SpectraCutPlot(Plot):
1025 1021
1026 1022 CODE = 'spc_cut'
1027 1023 plot_type = 'scatter'
1028 1024 buffering = False
1029 1025
1030 1026 def setup(self):
1031 1027
1032 1028 self.nplots = len(self.data.channels)
1033 1029 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
1034 1030 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
1035 1031 self.width = 3.4 * self.ncols + 1.5
1036 1032 self.height = 3 * self.nrows
1037 1033 self.ylabel = 'Power [dB]'
1038 1034 self.colorbar = False
1039 1035 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.75, 'bottom':0.08})
1040 1036
1041 1037 def update(self, dataOut):
1042 1038
1043 1039 data = {}
1044 1040 meta = {}
1045 1041 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
1046 1042 data['spc'] = spc
1047 1043 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
1048 1044 if self.CODE == 'cut_gaussian_fit':
1049 1045 data['gauss_fit0'] = 10*numpy.log10(dataOut.GaussFit0/dataOut.normFactor)
1050 1046 data['gauss_fit1'] = 10*numpy.log10(dataOut.GaussFit1/dataOut.normFactor)
1051 1047 return data, meta
1052 1048
1053 1049 def plot(self):
1054 1050 if self.xaxis == "frequency":
1055 1051 x = self.data.xrange[0][1:]
1056 1052 self.xlabel = "Frequency (kHz)"
1057 1053 elif self.xaxis == "time":
1058 1054 x = self.data.xrange[1]
1059 1055 self.xlabel = "Time (ms)"
1060 1056 else:
1061 1057 x = self.data.xrange[2][:-1]
1062 1058 self.xlabel = "Velocity (m/s)"
1063 1059
1064 1060 if self.CODE == 'cut_gaussian_fit':
1065 1061 x = self.data.xrange[2][:-1]
1066 1062 self.xlabel = "Velocity (m/s)"
1067 1063
1068 1064 self.titles = []
1069 1065
1070 1066 y = self.data.yrange
1071 1067 data = self.data[-1]
1072 1068 z = data['spc']
1073 1069
1074 1070 if self.height_index:
1075 1071 index = numpy.array(self.height_index)
1076 1072 else:
1077 1073 index = numpy.arange(0, len(y), int((len(y))/9))
1078 1074
1079 1075 for n, ax in enumerate(self.axes):
1080 1076 if self.CODE == 'cut_gaussian_fit':
1081 1077 gau0 = data['gauss_fit0']
1082 1078 gau1 = data['gauss_fit1']
1083 1079 if ax.firsttime:
1084 1080 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
1085 1081 self.xmin = self.xmin if self.xmin else -self.xmax
1086 1082 self.ymin = self.ymin if self.ymin else numpy.nanmin(z[:,:,index])
1087 1083 self.ymax = self.ymax if self.ymax else numpy.nanmax(z[:,:,index])
1088 1084 #print(self.ymax)
1089 1085 #print(z[n, :, index])
1090 1086 ax.plt = ax.plot(x, z[n, :, index].T, lw=0.25)
1091 1087 if self.CODE == 'cut_gaussian_fit':
1092 1088 ax.plt_gau0 = ax.plot(x, gau0[n, :, index].T, lw=1, linestyle='-.')
1093 1089 for i, line in enumerate(ax.plt_gau0):
1094 1090 line.set_color(ax.plt[i].get_color())
1095 1091 ax.plt_gau1 = ax.plot(x, gau1[n, :, index].T, lw=1, linestyle='--')
1096 1092 for i, line in enumerate(ax.plt_gau1):
1097 1093 line.set_color(ax.plt[i].get_color())
1098 1094 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
1099 1095 self.figures[0].legend(ax.plt, labels, loc='center right')
1100 1096 else:
1101 1097 for i, line in enumerate(ax.plt):
1102 1098 line.set_data(x, z[n, :, index[i]].T)
1103 1099 for i, line in enumerate(ax.plt_gau0):
1104 1100 line.set_data(x, gau0[n, :, index[i]].T)
1105 1101 line.set_color(ax.plt[i].get_color())
1106 1102 for i, line in enumerate(ax.plt_gau1):
1107 1103 line.set_data(x, gau1[n, :, index[i]].T)
1108 1104 line.set_color(ax.plt[i].get_color())
1109 1105 self.titles.append('CH {}'.format(n))
1110 1106
1111 1107
1112 1108 class BeaconPhase(Plot):
1113 1109
1114 1110 __isConfig = None
1115 1111 __nsubplots = None
1116 1112
1117 1113 PREFIX = 'beacon_phase'
1118 1114
1119 1115 def __init__(self):
1120 1116 Plot.__init__(self)
1121 1117 self.timerange = 24*60*60
1122 1118 self.isConfig = False
1123 1119 self.__nsubplots = 1
1124 1120 self.counter_imagwr = 0
1125 1121 self.WIDTH = 800
1126 1122 self.HEIGHT = 400
1127 1123 self.WIDTHPROF = 120
1128 1124 self.HEIGHTPROF = 0
1129 1125 self.xdata = None
1130 1126 self.ydata = None
1131 1127
1132 1128 self.PLOT_CODE = BEACON_CODE
1133 1129
1134 1130 self.FTP_WEI = None
1135 1131 self.EXP_CODE = None
1136 1132 self.SUB_EXP_CODE = None
1137 1133 self.PLOT_POS = None
1138 1134
1139 1135 self.filename_phase = None
1140 1136
1141 1137 self.figfile = None
1142 1138
1143 1139 self.xmin = None
1144 1140 self.xmax = None
1145 1141
1146 1142 def getSubplots(self):
1147 1143
1148 1144 ncol = 1
1149 1145 nrow = 1
1150 1146
1151 1147 return nrow, ncol
1152 1148
1153 1149 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1154 1150
1155 1151 self.__showprofile = showprofile
1156 1152 self.nplots = nplots
1157 1153
1158 1154 ncolspan = 7
1159 1155 colspan = 6
1160 1156 self.__nsubplots = 2
1161 1157
1162 1158 self.createFigure(id = id,
1163 1159 wintitle = wintitle,
1164 1160 widthplot = self.WIDTH+self.WIDTHPROF,
1165 1161 heightplot = self.HEIGHT+self.HEIGHTPROF,
1166 1162 show=show)
1167 1163
1168 1164 nrow, ncol = self.getSubplots()
1169 1165
1170 1166 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1171 1167
1172 1168 def save_phase(self, filename_phase):
1173 1169 f = open(filename_phase,'w+')
1174 1170 f.write('\n\n')
1175 1171 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
1176 1172 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
1177 1173 f.close()
1178 1174
1179 1175 def save_data(self, filename_phase, data, data_datetime):
1180 1176 f=open(filename_phase,'a')
1181 1177 timetuple_data = data_datetime.timetuple()
1182 1178 day = str(timetuple_data.tm_mday)
1183 1179 month = str(timetuple_data.tm_mon)
1184 1180 year = str(timetuple_data.tm_year)
1185 1181 hour = str(timetuple_data.tm_hour)
1186 1182 minute = str(timetuple_data.tm_min)
1187 1183 second = str(timetuple_data.tm_sec)
1188 1184 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
1189 1185 f.close()
1190 1186
1191 1187 def plot(self):
1192 1188 log.warning('TODO: Not yet implemented...')
1193 1189
1194 1190 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1195 1191 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
1196 1192 timerange=None,
1197 1193 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1198 1194 server=None, folder=None, username=None, password=None,
1199 1195 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1200 1196
1201 1197 if dataOut.flagNoData:
1202 1198 return dataOut
1203 1199
1204 1200 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1205 1201 return
1206 1202
1207 1203 if pairsList == None:
1208 1204 pairsIndexList = dataOut.pairsIndexList[:10]
1209 1205 else:
1210 1206 pairsIndexList = []
1211 1207 for pair in pairsList:
1212 1208 if pair not in dataOut.pairsList:
1213 1209 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
1214 1210 pairsIndexList.append(dataOut.pairsList.index(pair))
1215 1211
1216 1212 if pairsIndexList == []:
1217 1213 return
1218 1214
1219 1215 # if len(pairsIndexList) > 4:
1220 1216 # pairsIndexList = pairsIndexList[0:4]
1221 1217
1222 1218 hmin_index = None
1223 1219 hmax_index = None
1224 1220
1225 1221 if hmin != None and hmax != None:
1226 1222 indexes = numpy.arange(dataOut.nHeights)
1227 1223 hmin_list = indexes[dataOut.heightList >= hmin]
1228 1224 hmax_list = indexes[dataOut.heightList <= hmax]
1229 1225
1230 1226 if hmin_list.any():
1231 1227 hmin_index = hmin_list[0]
1232 1228
1233 1229 if hmax_list.any():
1234 1230 hmax_index = hmax_list[-1]+1
1235 1231
1236 1232 x = dataOut.getTimeRange()
1237 1233
1238 1234 thisDatetime = dataOut.datatime
1239 1235
1240 1236 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1241 1237 xlabel = "Local Time"
1242 1238 ylabel = "Phase (degrees)"
1243 1239
1244 1240 update_figfile = False
1245 1241
1246 1242 nplots = len(pairsIndexList)
1247 1243 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1248 1244 phase_beacon = numpy.zeros(len(pairsIndexList))
1249 1245 for i in range(nplots):
1250 1246 pair = dataOut.pairsList[pairsIndexList[i]]
1251 1247 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
1252 1248 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
1253 1249 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
1254 1250 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
1255 1251 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
1256 1252
1257 1253 if dataOut.beacon_heiIndexList:
1258 1254 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
1259 1255 else:
1260 1256 phase_beacon[i] = numpy.average(phase)
1261 1257
1262 1258 if not self.isConfig:
1263 1259
1264 1260 nplots = len(pairsIndexList)
1265 1261
1266 1262 self.setup(id=id,
1267 1263 nplots=nplots,
1268 1264 wintitle=wintitle,
1269 1265 showprofile=showprofile,
1270 1266 show=show)
1271 1267
1272 1268 if timerange != None:
1273 1269 self.timerange = timerange
1274 1270
1275 1271 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1276 1272
1277 1273 if ymin == None: ymin = 0
1278 1274 if ymax == None: ymax = 360
1279 1275
1280 1276 self.FTP_WEI = ftp_wei
1281 1277 self.EXP_CODE = exp_code
1282 1278 self.SUB_EXP_CODE = sub_exp_code
1283 1279 self.PLOT_POS = plot_pos
1284 1280
1285 1281 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1286 1282 self.isConfig = True
1287 1283 self.figfile = figfile
1288 1284 self.xdata = numpy.array([])
1289 1285 self.ydata = numpy.array([])
1290 1286
1291 1287 update_figfile = True
1292 1288
1293 1289 #open file beacon phase
1294 1290 path = '%s%03d' %(self.PREFIX, self.id)
1295 1291 beacon_file = os.path.join(path,'%s.txt'%self.name)
1296 1292 self.filename_phase = os.path.join(figpath,beacon_file)
1297 1293 #self.save_phase(self.filename_phase)
1298 1294
1299 1295
1300 1296 #store data beacon phase
1301 1297 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1302 1298
1303 1299 self.setWinTitle(title)
1304 1300
1305 1301
1306 1302 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1307 1303
1308 1304 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
1309 1305
1310 1306 axes = self.axesList[0]
1311 1307
1312 1308 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1313 1309
1314 1310 if len(self.ydata)==0:
1315 1311 self.ydata = phase_beacon.reshape(-1,1)
1316 1312 else:
1317 1313 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1318 1314
1319 1315
1320 1316 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1321 1317 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1322 1318 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1323 1319 XAxisAsTime=True, grid='both'
1324 1320 )
1325 1321
1326 1322 self.draw()
1327 1323
1328 1324 if dataOut.ltctime >= self.xmax:
1329 1325 self.counter_imagwr = wr_period
1330 1326 self.isConfig = False
1331 1327 update_figfile = True
1332 1328
1333 1329 self.save(figpath=figpath,
1334 1330 figfile=figfile,
1335 1331 save=save,
1336 1332 ftp=ftp,
1337 1333 wr_period=wr_period,
1338 1334 thisDatetime=thisDatetime,
1339 1335 update_figfile=update_figfile)
1340 1336
1341 1337 return dataOut
@@ -1,1299 +1,1287
1 1
2 2 import os
3 3 import time
4 4 import math
5 5 import datetime
6 6 import numpy
7 7 import collections.abc
8 8 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator #YONG
9 9
10 10 from .jroplot_spectra import RTIPlot, NoisePlot
11 11
12 12 from schainpy.utils import log
13 13 from .plotting_codes import *
14 14
15 15 from schainpy.model.graphics.jroplot_base import Plot, plt
16 16
17 17 import matplotlib.pyplot as plt
18 18 import matplotlib.colors as colors
19 19 from matplotlib.ticker import MultipleLocator
20 20
21 21
22 22 class RTIDPPlot(RTIPlot):
23 23
24 24 '''Plot for RTI Double Pulse Experiment
25 25 '''
26 26
27 27 CODE = 'RTIDP'
28 28 colormap = 'jet'
29 29 plot_name = 'RTI'
30 30 plot_type = 'pcolorbuffer'
31 31
32 32 def setup(self):
33 33 self.xaxis = 'time'
34 34 self.ncols = 1
35 35 self.nrows = 3
36 36 self.nplots = self.nrows
37 37
38 38 self.ylabel = 'Range [km]'
39 39 self.xlabel = 'Time (LT)'
40 40
41 41 self.cb_label = 'Intensity (dB)'
42 42
43 43 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
44 44
45 45 self.titles = ['{} Channel {}'.format(
46 46 self.plot_name.upper(), '0x1'),'{} Channel {}'.format(
47 47 self.plot_name.upper(), '0'),'{} Channel {}'.format(
48 48 self.plot_name.upper(), '1')]
49 49
50 50 def update(self, dataOut):
51 51
52 52 data = {}
53 53 meta = {}
54 54 data['rti'] = dataOut.data_for_RTI_DP
55 55 data['NDP'] = dataOut.NDP
56 56
57 57 return data, meta
58 58
59 59 def plot(self):
60 60
61 61 NDP = self.data['NDP'][-1]
62 62 self.x = self.data.times
63 63 self.y = self.data.yrange[0:NDP]
64 64 self.z = self.data['rti']
65 65 self.z = numpy.ma.masked_invalid(self.z)
66 66
67 67 if self.decimation is None:
68 68 x, y, z = self.fill_gaps(self.x, self.y, self.z)
69 69 else:
70 70 x, y, z = self.fill_gaps(*self.decimate())
71 71
72 72 for n, ax in enumerate(self.axes):
73 73
74 74 self.zmax = self.zmax if self.zmax is not None else numpy.max(
75 75 self.z[1][0,12:40])
76 76 self.zmin = self.zmin if self.zmin is not None else numpy.min(
77 77 self.z[1][0,12:40])
78 78
79 79 if ax.firsttime:
80 80
81 81 if self.zlimits is not None:
82 82 self.zmin, self.zmax = self.zlimits[n]
83 83
84 84 ax.plt = ax.pcolormesh(x, y, z[n].T,
85 85 vmin=self.zmin,
86 86 vmax=self.zmax,
87 87 cmap=plt.get_cmap(self.colormap)
88 88 )
89 89 else:
90 90 #if self.zlimits is not None:
91 91 #self.zmin, self.zmax = self.zlimits[n]
92 92 ax.collections.remove(ax.collections[0])
93 93 ax.plt = ax.pcolormesh(x, y, z[n].T,
94 94 vmin=self.zmin,
95 95 vmax=self.zmax,
96 96 cmap=plt.get_cmap(self.colormap)
97 97 )
98 98
99 99
100 100 class RTILPPlot(RTIPlot):
101 101
102 102 '''
103 103 Plot for RTI Long Pulse
104 104 '''
105 105
106 106 CODE = 'RTILP'
107 107 colormap = 'jet'
108 108 plot_name = 'RTI LP'
109 109 plot_type = 'pcolorbuffer'
110 110
111 111 def setup(self):
112 112 self.xaxis = 'time'
113 113 self.ncols = 1
114 114 self.nrows = 2
115 115 self.nplots = self.nrows
116 116
117 117 self.ylabel = 'Range [km]'
118 118 self.xlabel = 'Time (LT)'
119 119
120 120 self.cb_label = 'Intensity (dB)'
121 121
122 122 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
123 123
124 124
125 125 self.titles = ['{} Channel {}'.format(
126 126 self.plot_name.upper(), '0'),'{} Channel {}'.format(
127 127 self.plot_name.upper(), '1'),'{} Channel {}'.format(
128 128 self.plot_name.upper(), '2'),'{} Channel {}'.format(
129 129 self.plot_name.upper(), '3')]
130 130
131 131
132 132 def update(self, dataOut):
133 133
134 134 data = {}
135 135 meta = {}
136 136 data['rti'] = dataOut.data_for_RTI_LP
137 137 data['NRANGE'] = dataOut.NRANGE
138 138
139 139 return data, meta
140 140
141 141 def plot(self):
142 142
143 143 NRANGE = self.data['NRANGE'][-1]
144 144 self.x = self.data.times
145 145 self.y = self.data.yrange[0:NRANGE]
146 146
147 147 self.z = self.data['rti']
148 148
149 149 self.z = numpy.ma.masked_invalid(self.z)
150 150
151 151 if self.decimation is None:
152 152 x, y, z = self.fill_gaps(self.x, self.y, self.z)
153 153 else:
154 154 x, y, z = self.fill_gaps(*self.decimate())
155 155
156 if not isinstance(self.zmin, collections.abc.Sequence):
157 if not self.zmin:
158 self.zmin = [numpy.min(self.z)]*len(self.axes)
159 else:
160 self.zmin = [self.zmin]*len(self.axes)
161
162 if not isinstance(self.zmax, collections.abc.Sequence):
163 if not self.zmax:
164 self.zmax = [numpy.max(self.z)]*len(self.axes)
165 else:
166 self.zmax = [self.zmax]*len(self.axes)
167
168 156 for n, ax in enumerate(self.axes):
169 157
170 #self.zmax = self.zmax if self.zmax is not None else numpy.max(
171 #self.z[1][0,12:40])
172 #self.zmin = self.zmin if self.zmin is not None else numpy.min(
173 #self.z[1][0,12:40])
158 self.zmax = self.zmax if self.zmax is not None else numpy.max(
159 self.z[1][0,12:40])
160 self.zmin = self.zmin if self.zmin is not None else numpy.min(
161 self.z[1][0,12:40])
174 162
175 163 if ax.firsttime:
176 164
177 165 if self.zlimits is not None:
178 166 self.zmin, self.zmax = self.zlimits[n]
179 167
180 168
181 169 ax.plt = ax.pcolormesh(x, y, z[n].T,
182 vmin=self.zmin[n],
183 vmax=self.zmax[n],
170 vmin=self.zmin,
171 vmax=self.zmax,
184 172 cmap=plt.get_cmap(self.colormap)
185 173 )
186 174
187 175 else:
188 #if self.zlimits is not None:
189 #self.zmin, self.zmax = self.zlimits[n]
176 if self.zlimits is not None:
177 self.zmin, self.zmax = self.zlimits[n]
190 178 ax.collections.remove(ax.collections[0])
191 179 ax.plt = ax.pcolormesh(x, y, z[n].T,
192 vmin=self.zmin[n],
193 vmax=self.zmax[n],
180 vmin=self.zmin,
181 vmax=self.zmax,
194 182 cmap=plt.get_cmap(self.colormap)
195 183 )
196 184
197 185
198 186 class DenRTIPlot(RTIPlot):
199 187
200 188 '''
201 189 Plot for Den
202 190 '''
203 191
204 192 CODE = 'denrti'
205 193 colormap = 'jet'
206 194
207 195 def setup(self):
208 196 self.xaxis = 'time'
209 197 self.ncols = 1
210 198 self.nrows = self.data.shape(self.CODE)[0]
211 199 self.nplots = self.nrows
212 200
213 201 self.ylabel = 'Range [km]'
214 202 self.xlabel = 'Time (LT)'
215 203
216 204 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
217 205
218 206 if self.CODE == 'denrti':
219 207 self.cb_label = r'$\mathrm{N_e}$ Electron Density ($\mathrm{1/cm^3}$)'
220 208
221 209
222 210 self.titles = ['Electron Density RTI']
223 211
224 212 def update(self, dataOut):
225 213
226 214 data = {}
227 215 meta = {}
228 216
229 217 data['denrti'] = dataOut.DensityFinal*1.e-6 #To Plot in cm^-3
230 218
231 219 return data, meta
232 220
233 221 def plot(self):
234 222
235 223 self.x = self.data.times
236 224 self.y = self.data.yrange
237 225
238 226 self.z = self.data[self.CODE]
239 227
240 228 self.z = numpy.ma.masked_invalid(self.z)
241 229
242 230 if self.decimation is None:
243 231 x, y, z = self.fill_gaps(self.x, self.y, self.z)
244 232 else:
245 233 x, y, z = self.fill_gaps(*self.decimate())
246 234
247 235 for n, ax in enumerate(self.axes):
248 236
249 237 self.zmax = self.zmax if self.zmax is not None else numpy.max(
250 238 self.z[n])
251 239 self.zmin = self.zmin if self.zmin is not None else numpy.min(
252 240 self.z[n])
253 241
254 242 if ax.firsttime:
255 243
256 244 if self.zlimits is not None:
257 245 self.zmin, self.zmax = self.zlimits[n]
258 246 if numpy.log10(self.zmin)<0:
259 247 self.zmin=1
260 248 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
261 249 vmin=self.zmin,
262 250 vmax=self.zmax,
263 251 cmap=self.cmaps[n],
264 252 norm=colors.LogNorm()
265 253 )
266 254
267 255 else:
268 256 if self.zlimits is not None:
269 257 self.zmin, self.zmax = self.zlimits[n]
270 258 ax.collections.remove(ax.collections[0])
271 259 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
272 260 vmin=self.zmin,
273 261 vmax=self.zmax,
274 262 cmap=self.cmaps[n],
275 263 norm=colors.LogNorm()
276 264 )
277 265
278 266
279 267 class ETempRTIPlot(RTIPlot):
280 268
281 269 '''
282 270 Plot for Electron Temperature
283 271 '''
284 272
285 273 CODE = 'ETemp'
286 274 colormap = 'jet'
287 275
288 276 def setup(self):
289 277 self.xaxis = 'time'
290 278 self.ncols = 1
291 279 self.nrows = self.data.shape(self.CODE)[0]
292 280 self.nplots = self.nrows
293 281
294 282 self.ylabel = 'Range [km]'
295 283 self.xlabel = 'Time (LT)'
296 284 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
297 285 if self.CODE == 'ETemp':
298 286 self.cb_label = 'Electron Temperature (K)'
299 287 self.titles = ['Electron Temperature RTI']
300 288 if self.CODE == 'ITemp':
301 289 self.cb_label = 'Ion Temperature (K)'
302 290 self.titles = ['Ion Temperature RTI']
303 291 if self.CODE == 'HeFracLP':
304 292 self.cb_label='He+ Fraction'
305 293 self.titles = ['He+ Fraction RTI']
306 294 self.zmax=0.16
307 295 if self.CODE== 'HFracLP':
308 296 self.cb_label='H+ Fraction'
309 297 self.titles = ['H+ Fraction RTI']
310 298
311 299 def update(self, dataOut):
312 300
313 301 data = {}
314 302 meta = {}
315 303
316 304 data['ETemp'] = dataOut.ElecTempFinal
317 305
318 306 return data, meta
319 307
320 308 def plot(self):
321 309
322 310 self.x = self.data.times
323 311 self.y = self.data.yrange
324 312
325 313
326 314 self.z = self.data[self.CODE]
327 315
328 316 self.z = numpy.ma.masked_invalid(self.z)
329 317
330 318 if self.decimation is None:
331 319 x, y, z = self.fill_gaps(self.x, self.y, self.z)
332 320 else:
333 321 x, y, z = self.fill_gaps(*self.decimate())
334 322
335 323 for n, ax in enumerate(self.axes):
336 324
337 325 self.zmax = self.zmax if self.zmax is not None else numpy.max(
338 326 self.z[n])
339 327 self.zmin = self.zmin if self.zmin is not None else numpy.min(
340 328 self.z[n])
341 329
342 330 if ax.firsttime:
343 331
344 332 if self.zlimits is not None:
345 333 self.zmin, self.zmax = self.zlimits[n]
346 334
347 335 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
348 336 vmin=self.zmin,
349 337 vmax=self.zmax,
350 338 cmap=self.cmaps[n]
351 339 )
352 340 #plt.tight_layout()
353 341
354 342 else:
355 343 if self.zlimits is not None:
356 344 self.zmin, self.zmax = self.zlimits[n]
357 345 ax.collections.remove(ax.collections[0])
358 346 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
359 347 vmin=self.zmin,
360 348 vmax=self.zmax,
361 349 cmap=self.cmaps[n]
362 350 )
363 351
364 352
365 353 class ITempRTIPlot(ETempRTIPlot):
366 354
367 355 '''
368 356 Plot for Ion Temperature
369 357 '''
370 358
371 359 CODE = 'ITemp'
372 360 colormap = 'jet'
373 361 plot_name = 'Ion Temperature'
374 362
375 363 def update(self, dataOut):
376 364
377 365 data = {}
378 366 meta = {}
379 367
380 368 data['ITemp'] = dataOut.IonTempFinal
381 369
382 370 return data, meta
383 371
384 372
385 373 class HFracRTIPlot(ETempRTIPlot):
386 374
387 375 '''
388 376 Plot for H+ LP
389 377 '''
390 378
391 379 CODE = 'HFracLP'
392 380 colormap = 'jet'
393 381 plot_name = 'H+ Frac'
394 382
395 383 def update(self, dataOut):
396 384
397 385 data = {}
398 386 meta = {}
399 387 data['HFracLP'] = dataOut.PhyFinal
400 388
401 389 return data, meta
402 390
403 391
404 392 class HeFracRTIPlot(ETempRTIPlot):
405 393
406 394 '''
407 395 Plot for He+ LP
408 396 '''
409 397
410 398 CODE = 'HeFracLP'
411 399 colormap = 'jet'
412 400 plot_name = 'He+ Frac'
413 401
414 402 def update(self, dataOut):
415 403
416 404 data = {}
417 405 meta = {}
418 406 data['HeFracLP'] = dataOut.PheFinal
419 407
420 408 return data, meta
421 409
422 410
423 411 class TempsDPPlot(Plot):
424 412 '''
425 413 Plot for Electron - Ion Temperatures
426 414 '''
427 415
428 416 CODE = 'tempsDP'
429 417 #plot_name = 'Temperatures'
430 418 plot_type = 'scatterbuffer'
431 419
432 420 def setup(self):
433 421
434 422 self.ncols = 1
435 423 self.nrows = 1
436 424 self.nplots = 1
437 425 self.ylabel = 'Range [km]'
438 426 self.xlabel = 'Temperature (K)'
439 427 self.titles = ['Electron/Ion Temperatures']
440 428 self.width = 3.5
441 429 self.height = 5.5
442 430 self.colorbar = False
443 431 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
444 432
445 433 def update(self, dataOut):
446 434 data = {}
447 435 meta = {}
448 436
449 437 data['Te'] = dataOut.te2
450 438 data['Ti'] = dataOut.ti2
451 439 data['Te_error'] = dataOut.ete2
452 440 data['Ti_error'] = dataOut.eti2
453 441
454 442 meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
455 443
456 444 return data, meta
457 445
458 446 def plot(self):
459 447
460 448 y = self.data.yrange
461 449
462 450 self.xmin = -100
463 451 self.xmax = 5000
464 452
465 453 ax = self.axes[0]
466 454
467 455 data = self.data[-1]
468 456
469 457 Te = data['Te']
470 458 Ti = data['Ti']
471 459 errTe = data['Te_error']
472 460 errTi = data['Ti_error']
473 461
474 462 if ax.firsttime:
475 463 ax.errorbar(Te, y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
476 464 ax.errorbar(Ti, y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
477 465 plt.legend(loc='lower right')
478 466 self.ystep_given = 50
479 467 ax.yaxis.set_minor_locator(MultipleLocator(15))
480 468 ax.grid(which='minor')
481 469
482 470 else:
483 471 self.clear_figures()
484 472 ax.errorbar(Te, y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
485 473 ax.errorbar(Ti, y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
486 474 plt.legend(loc='lower right')
487 475 ax.yaxis.set_minor_locator(MultipleLocator(15))
488 476
489 477
490 478 class TempsHPPlot(Plot):
491 479 '''
492 480 Plot for Temperatures Hybrid Experiment
493 481 '''
494 482
495 483 CODE = 'temps_LP'
496 484 #plot_name = 'Temperatures'
497 485 plot_type = 'scatterbuffer'
498 486
499 487
500 488 def setup(self):
501 489
502 490 self.ncols = 1
503 491 self.nrows = 1
504 492 self.nplots = 1
505 493 self.ylabel = 'Range [km]'
506 494 self.xlabel = 'Temperature (K)'
507 495 self.titles = ['Electron/Ion Temperatures']
508 496 self.width = 3.5
509 497 self.height = 6.5
510 498 self.colorbar = False
511 499 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
512 500
513 501 def update(self, dataOut):
514 502 data = {}
515 503 meta = {}
516 504
517 505
518 506 data['Te'] = numpy.concatenate((dataOut.te2[:dataOut.cut],dataOut.te[dataOut.cut:]))
519 507 data['Ti'] = numpy.concatenate((dataOut.ti2[:dataOut.cut],dataOut.ti[dataOut.cut:]))
520 508 data['Te_error'] = numpy.concatenate((dataOut.ete2[:dataOut.cut],dataOut.ete[dataOut.cut:]))
521 509 data['Ti_error'] = numpy.concatenate((dataOut.eti2[:dataOut.cut],dataOut.eti[dataOut.cut:]))
522 510
523 511 meta['yrange'] = dataOut.heightList[0:dataOut.NACF]
524 512
525 513 return data, meta
526 514
527 515 def plot(self):
528 516
529 517
530 518 self.y = self.data.yrange
531 519 self.xmin = -100
532 520 self.xmax = 4500
533 521 ax = self.axes[0]
534 522
535 523 data = self.data[-1]
536 524
537 525 Te = data['Te']
538 526 Ti = data['Ti']
539 527 errTe = data['Te_error']
540 528 errTi = data['Ti_error']
541 529
542 530 if ax.firsttime:
543 531
544 532 ax.errorbar(Te, self.y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
545 533 ax.errorbar(Ti, self.y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
546 534 plt.legend(loc='lower right')
547 535 self.ystep_given = 200
548 536 ax.yaxis.set_minor_locator(MultipleLocator(15))
549 537 ax.grid(which='minor')
550 538
551 539 else:
552 540 self.clear_figures()
553 541 ax.errorbar(Te, self.y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
554 542 ax.errorbar(Ti, self.y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
555 543 plt.legend(loc='lower right')
556 544 ax.yaxis.set_minor_locator(MultipleLocator(15))
557 545 ax.grid(which='minor')
558 546
559 547
560 548 class FracsHPPlot(Plot):
561 549 '''
562 550 Plot for Composition LP
563 551 '''
564 552
565 553 CODE = 'fracs_LP'
566 554 plot_type = 'scatterbuffer'
567 555
568 556
569 557 def setup(self):
570 558
571 559 self.ncols = 1
572 560 self.nrows = 1
573 561 self.nplots = 1
574 562 self.ylabel = 'Range [km]'
575 563 self.xlabel = 'Frac'
576 564 self.titles = ['Composition']
577 565 self.width = 3.5
578 566 self.height = 6.5
579 567 self.colorbar = False
580 568 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
581 569
582 570 def update(self, dataOut):
583 571 data = {}
584 572 meta = {}
585 573
586 574 #aux_nan=numpy.zeros(dataOut.cut,'float32')
587 575 #aux_nan[:]=numpy.nan
588 576 #data['ph'] = numpy.concatenate((aux_nan,dataOut.ph[dataOut.cut:]))
589 577 #data['eph'] = numpy.concatenate((aux_nan,dataOut.eph[dataOut.cut:]))
590 578
591 579 data['ph'] = dataOut.ph[dataOut.cut:]
592 580 data['eph'] = dataOut.eph[dataOut.cut:]
593 581 data['phe'] = dataOut.phe[dataOut.cut:]
594 582 data['ephe'] = dataOut.ephe[dataOut.cut:]
595 583
596 584 data['cut'] = dataOut.cut
597 585
598 586 meta['yrange'] = dataOut.heightList[0:dataOut.NACF]
599 587
600 588
601 589 return data, meta
602 590
603 591 def plot(self):
604 592
605 593 data = self.data[-1]
606 594
607 595 ph = data['ph']
608 596 eph = data['eph']
609 597 phe = data['phe']
610 598 ephe = data['ephe']
611 599 cut = data['cut']
612 600 self.y = self.data.yrange
613 601
614 602 self.xmin = 0
615 603 self.xmax = 1
616 604 ax = self.axes[0]
617 605
618 606 if ax.firsttime:
619 607
620 608 ax.errorbar(ph, self.y[cut:], xerr=eph, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='H+')
621 609 ax.errorbar(phe, self.y[cut:], fmt='k^', xerr=ephe,elinewidth=1.0,color='b',linewidth=2.0, label='He+')
622 610 plt.legend(loc='lower right')
623 611 self.xstep_given = 0.2
624 612 self.ystep_given = 200
625 613 ax.yaxis.set_minor_locator(MultipleLocator(15))
626 614 ax.grid(which='minor')
627 615
628 616 else:
629 617 self.clear_figures()
630 618 ax.errorbar(ph, self.y[cut:], xerr=eph, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='H+')
631 619 ax.errorbar(phe, self.y[cut:], fmt='k^', xerr=ephe,elinewidth=1.0,color='b',linewidth=2.0, label='He+')
632 620 plt.legend(loc='lower right')
633 621 ax.yaxis.set_minor_locator(MultipleLocator(15))
634 622 ax.grid(which='minor')
635 623
636 624 class EDensityPlot(Plot):
637 625 '''
638 626 Plot for electron density
639 627 '''
640 628
641 629 CODE = 'den'
642 630 #plot_name = 'Electron Density'
643 631 plot_type = 'scatterbuffer'
644 632
645 633 def setup(self):
646 634
647 635 self.ncols = 1
648 636 self.nrows = 1
649 637 self.nplots = 1
650 638 self.ylabel = 'Range [km]'
651 639 self.xlabel = r'$\mathrm{N_e}$ Electron Density ($\mathrm{1/cm^3}$)'
652 640 self.titles = ['Electron Density']
653 641 self.width = 3.5
654 642 self.height = 5.5
655 643 self.colorbar = False
656 644 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
657 645
658 646 def update(self, dataOut):
659 647 data = {}
660 648 meta = {}
661 649
662 650 data['den_power'] = dataOut.ph2[:dataOut.NSHTS]
663 651 data['den_Faraday'] = dataOut.dphi[:dataOut.NSHTS]
664 652 data['den_error'] = dataOut.sdp2[:dataOut.NSHTS]
665 653 #data['err_Faraday'] = dataOut.sdn1[:dataOut.NSHTS]
666 654
667 655 data['NSHTS'] = dataOut.NSHTS
668 656
669 657 meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
670 658
671 659 return data, meta
672 660
673 661 def plot(self):
674 662
675 663 y = self.data.yrange
676 664
677 665 self.xmin = 1e3
678 666 self.xmax = 1e7
679 667
680 668 ax = self.axes[0]
681 669
682 670 data = self.data[-1]
683 671
684 672 DenPow = data['den_power']
685 673 DenFar = data['den_Faraday']
686 674 errDenPow = data['den_error']
687 675 #errFaraday = data['err_Faraday']
688 676
689 677 NSHTS = data['NSHTS']
690 678
691 679 if self.CODE == 'denLP':
692 680 DenPowLP = data['den_LP']
693 681 errDenPowLP = data['den_LP_error']
694 682 cut = data['cut']
695 683
696 684 if ax.firsttime:
697 685 self.autoxticks=False
698 686 #ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
699 687 ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday',markersize=2)
700 688 #ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power Profile',markersize=2)
701 689 ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power',markersize=2)
702 690
703 691 if self.CODE=='denLP':
704 692 ax.errorbar(DenPowLP[cut:], y[cut:], xerr=errDenPowLP[cut:], fmt='r^-',elinewidth=1.0,color='r',linewidth=1.0, label='LP Profile',markersize=2)
705 693
706 694 plt.legend(loc='upper left',fontsize=8.5)
707 695 #plt.legend(loc='lower left',fontsize=8.5)
708 696 ax.set_xscale("log", nonposx='clip')
709 697 grid_y_ticks=numpy.arange(numpy.nanmin(y),numpy.nanmax(y),50)
710 698 self.ystep_given=100
711 699 if self.CODE=='denLP':
712 700 self.ystep_given=200
713 701 ax.set_yticks(grid_y_ticks,minor=True)
714 702 ax.grid(which='minor')
715 703
716 704 else:
717 705 dataBefore = self.data[-2]
718 706 DenPowBefore = dataBefore['den_power']
719 707 self.clear_figures()
720 708 #ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
721 709 ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday',markersize=2)
722 710 #ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power Profile',markersize=2)
723 711 ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power',markersize=2)
724 712 ax.errorbar(DenPowBefore, y[:NSHTS], elinewidth=1.0,color='r',linewidth=0.5,linestyle="dashed")
725 713
726 714 if self.CODE=='denLP':
727 715 ax.errorbar(DenPowLP[cut:], y[cut:], fmt='r^-', xerr=errDenPowLP[cut:],elinewidth=1.0,color='r',linewidth=1.0, label='LP Profile',markersize=2)
728 716
729 717 ax.set_xscale("log", nonposx='clip')
730 718 grid_y_ticks=numpy.arange(numpy.nanmin(y),numpy.nanmax(y),50)
731 719 ax.set_yticks(grid_y_ticks,minor=True)
732 720 ax.grid(which='minor')
733 721 plt.legend(loc='upper left',fontsize=8.5)
734 722 #plt.legend(loc='lower left',fontsize=8.5)
735 723
736 724 class FaradayAnglePlot(Plot):
737 725 '''
738 726 Plot for electron density
739 727 '''
740 728
741 729 CODE = 'angle'
742 730 plot_name = 'Faraday Angle'
743 731 plot_type = 'scatterbuffer'
744 732
745 733 def setup(self):
746 734
747 735 self.ncols = 1
748 736 self.nrows = 1
749 737 self.nplots = 1
750 738 self.ylabel = 'Range [km]'
751 739 self.xlabel = 'Faraday Angle (º)'
752 740 self.titles = ['Electron Density']
753 741 self.width = 3.5
754 742 self.height = 5.5
755 743 self.colorbar = False
756 744 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
757 745
758 746 def update(self, dataOut):
759 747 data = {}
760 748 meta = {}
761 749
762 750 data['angle'] = numpy.degrees(dataOut.phi)
763 751 #'''
764 752 print(dataOut.phi_uwrp)
765 753 print(data['angle'])
766 754 exit(1)
767 755 #'''
768 756 data['dphi'] = dataOut.dphi_uc*10
769 757 #print(dataOut.dphi)
770 758
771 759 #data['NSHTS'] = dataOut.NSHTS
772 760
773 761 #meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
774 762
775 763 return data, meta
776 764
777 765 def plot(self):
778 766
779 767 data = self.data[-1]
780 768 self.x = data[self.CODE]
781 769 dphi = data['dphi']
782 770 self.y = self.data.yrange
783 771 self.xmin = -360#-180
784 772 self.xmax = 360#180
785 773 ax = self.axes[0]
786 774
787 775 if ax.firsttime:
788 776 self.autoxticks=False
789 777 #if self.CODE=='den':
790 778 ax.plot(self.x, self.y,marker='o',color='g',linewidth=1.0,markersize=2)
791 779 ax.plot(dphi, self.y,marker='o',color='blue',linewidth=1.0,markersize=2)
792 780
793 781 grid_y_ticks=numpy.arange(numpy.nanmin(self.y),numpy.nanmax(self.y),50)
794 782 self.ystep_given=100
795 783 if self.CODE=='denLP':
796 784 self.ystep_given=200
797 785 ax.set_yticks(grid_y_ticks,minor=True)
798 786 ax.grid(which='minor')
799 787 #plt.tight_layout()
800 788 else:
801 789
802 790 self.clear_figures()
803 791 #if self.CODE=='den':
804 792 #print(numpy.shape(self.x))
805 793 ax.plot(self.x, self.y, marker='o',color='g',linewidth=1.0, markersize=2)
806 794 ax.plot(dphi, self.y,marker='o',color='blue',linewidth=1.0,markersize=2)
807 795
808 796 grid_y_ticks=numpy.arange(numpy.nanmin(self.y),numpy.nanmax(self.y),50)
809 797 ax.set_yticks(grid_y_ticks,minor=True)
810 798 ax.grid(which='minor')
811 799
812 800 class EDensityHPPlot(EDensityPlot):
813 801
814 802 '''
815 803 Plot for Electron Density Hybrid Experiment
816 804 '''
817 805
818 806 CODE = 'denLP'
819 807 plot_name = 'Electron Density'
820 808 plot_type = 'scatterbuffer'
821 809
822 810 def update(self, dataOut):
823 811 data = {}
824 812 meta = {}
825 813
826 814 data['den_power'] = dataOut.ph2[:dataOut.NSHTS]
827 815 data['den_Faraday']=dataOut.dphi[:dataOut.NSHTS]
828 816 data['den_error']=dataOut.sdp2[:dataOut.NSHTS]
829 817 data['den_LP']=dataOut.ne[:dataOut.NACF]
830 818 data['den_LP_error']=dataOut.ene[:dataOut.NACF]*dataOut.ne[:dataOut.NACF]*0.434
831 819 #self.ene=10**dataOut.ene[:dataOut.NACF]
832 820 data['NSHTS']=dataOut.NSHTS
833 821 data['cut']=dataOut.cut
834 822
835 823 return data, meta
836 824
837 825
838 826 class ACFsPlot(Plot):
839 827 '''
840 828 Plot for ACFs Double Pulse Experiment
841 829 '''
842 830
843 831 CODE = 'acfs'
844 832 #plot_name = 'ACF'
845 833 plot_type = 'scatterbuffer'
846 834
847 835
848 836 def setup(self):
849 837 self.ncols = 1
850 838 self.nrows = 1
851 839 self.nplots = 1
852 840 self.ylabel = 'Range [km]'
853 841 self.xlabel = 'Lag (ms)'
854 842 self.titles = ['ACFs']
855 843 self.width = 3.5
856 844 self.height = 5.5
857 845 self.colorbar = False
858 846 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
859 847
860 848 def update(self, dataOut):
861 849 data = {}
862 850 meta = {}
863 851
864 852 data['ACFs'] = dataOut.acfs_to_plot
865 853 data['ACFs_error'] = dataOut.acfs_error_to_plot
866 854 data['lags'] = dataOut.lags_to_plot
867 855 data['Lag_contaminated_1'] = dataOut.x_igcej_to_plot
868 856 data['Lag_contaminated_2'] = dataOut.x_ibad_to_plot
869 857 data['Height_contaminated_1'] = dataOut.y_igcej_to_plot
870 858 data['Height_contaminated_2'] = dataOut.y_ibad_to_plot
871 859
872 860 meta['yrange'] = numpy.array([])
873 861 #meta['NSHTS'] = dataOut.NSHTS
874 862 #meta['DPL'] = dataOut.DPL
875 863 data['NSHTS'] = dataOut.NSHTS #This is metadata
876 864 data['DPL'] = dataOut.DPL #This is metadata
877 865
878 866 return data, meta
879 867
880 868 def plot(self):
881 869
882 870 data = self.data[-1]
883 871 #NSHTS = self.meta['NSHTS']
884 872 #DPL = self.meta['DPL']
885 873 NSHTS = data['NSHTS'] #This is metadata
886 874 DPL = data['DPL'] #This is metadata
887 875
888 876 lags = data['lags']
889 877 ACFs = data['ACFs']
890 878 errACFs = data['ACFs_error']
891 879 BadLag1 = data['Lag_contaminated_1']
892 880 BadLag2 = data['Lag_contaminated_2']
893 881 BadHei1 = data['Height_contaminated_1']
894 882 BadHei2 = data['Height_contaminated_2']
895 883
896 884 self.xmin = 0.0
897 885 self.xmax = 2.0
898 886 self.y = ACFs
899 887
900 888 ax = self.axes[0]
901 889
902 890 if ax.firsttime:
903 891
904 892 for i in range(NSHTS):
905 893 x_aux = numpy.isfinite(lags[i,:])
906 894 y_aux = numpy.isfinite(ACFs[i,:])
907 895 yerr_aux = numpy.isfinite(errACFs[i,:])
908 896 x_igcej_aux = numpy.isfinite(BadLag1[i,:])
909 897 y_igcej_aux = numpy.isfinite(BadHei1[i,:])
910 898 x_ibad_aux = numpy.isfinite(BadLag2[i,:])
911 899 y_ibad_aux = numpy.isfinite(BadHei2[i,:])
912 900 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
913 901 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',marker='o',linewidth=1.0,markersize=2)
914 902 ax.plot(BadLag1[i,x_igcej_aux],BadHei1[i,y_igcej_aux],'x',color='red',markersize=2)
915 903 ax.plot(BadLag2[i,x_ibad_aux],BadHei2[i,y_ibad_aux],'X',color='red',markersize=2)
916 904
917 905 self.xstep_given = (self.xmax-self.xmin)/(DPL-1)
918 906 self.ystep_given = 50
919 907 ax.yaxis.set_minor_locator(MultipleLocator(15))
920 908 ax.grid(which='minor')
921 909
922 910 else:
923 911 self.clear_figures()
924 912 for i in range(NSHTS):
925 913 x_aux = numpy.isfinite(lags[i,:])
926 914 y_aux = numpy.isfinite(ACFs[i,:])
927 915 yerr_aux = numpy.isfinite(errACFs[i,:])
928 916 x_igcej_aux = numpy.isfinite(BadLag1[i,:])
929 917 y_igcej_aux = numpy.isfinite(BadHei1[i,:])
930 918 x_ibad_aux = numpy.isfinite(BadLag2[i,:])
931 919 y_ibad_aux = numpy.isfinite(BadHei2[i,:])
932 920 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
933 921 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],linewidth=1.0,markersize=2,color='b',marker='o')
934 922 ax.plot(BadLag1[i,x_igcej_aux],BadHei1[i,y_igcej_aux],'x',color='red',markersize=2)
935 923 ax.plot(BadLag2[i,x_ibad_aux],BadHei2[i,y_ibad_aux],'X',color='red',markersize=2)
936 924 ax.yaxis.set_minor_locator(MultipleLocator(15))
937 925
938 926 class ACFsLPPlot(Plot):
939 927 '''
940 928 Plot for ACFs Double Pulse Experiment
941 929 '''
942 930
943 931 CODE = 'acfs_LP'
944 932 #plot_name = 'ACF'
945 933 plot_type = 'scatterbuffer'
946 934
947 935
948 936 def setup(self):
949 937 self.ncols = 1
950 938 self.nrows = 1
951 939 self.nplots = 1
952 940 self.ylabel = 'Range [km]'
953 941 self.xlabel = 'Lag (ms)'
954 942 self.titles = ['ACFs']
955 943 self.width = 3.5
956 944 self.height = 5.5
957 945 self.colorbar = False
958 946 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
959 947
960 948 def update(self, dataOut):
961 949 data = {}
962 950 meta = {}
963 951
964 952 aux=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
965 953 errors=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
966 954 lags_LP_to_plot=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
967 955
968 956 for i in range(dataOut.NACF):
969 957 for j in range(dataOut.IBITS):
970 958 if numpy.abs(dataOut.errors[j,i]/dataOut.output_LP_integrated.real[0,i,0])<1.0:
971 959 aux[i,j]=dataOut.output_LP_integrated.real[j,i,0]/dataOut.output_LP_integrated.real[0,i,0]
972 960 aux[i,j]=max(min(aux[i,j],1.0),-1.0)*dataOut.DH+dataOut.heightList[i]
973 961 lags_LP_to_plot[i,j]=dataOut.lags_LP[j]
974 962 errors[i,j]=dataOut.errors[j,i]/dataOut.output_LP_integrated.real[0,i,0]*dataOut.DH
975 963 else:
976 964 aux[i,j]=numpy.nan
977 965 lags_LP_to_plot[i,j]=numpy.nan
978 966 errors[i,j]=numpy.nan
979 967
980 968 data['ACFs'] = aux
981 969 data['ACFs_error'] = errors
982 970 data['lags'] = lags_LP_to_plot
983 971
984 972 meta['yrange'] = numpy.array([])
985 973 #meta['NACF'] = dataOut.NACF
986 974 #meta['NLAG'] = dataOut.NLAG
987 975 data['NACF'] = dataOut.NACF #This is metadata
988 976 data['NLAG'] = dataOut.NLAG #This is metadata
989 977
990 978 return data, meta
991 979
992 980 def plot(self):
993 981
994 982 data = self.data[-1]
995 983 #NACF = self.meta['NACF']
996 984 #NLAG = self.meta['NLAG']
997 985 NACF = data['NACF'] #This is metadata
998 986 NLAG = data['NLAG'] #This is metadata
999 987
1000 988 lags = data['lags']
1001 989 ACFs = data['ACFs']
1002 990 errACFs = data['ACFs_error']
1003 991
1004 992 self.xmin = 0.0
1005 993 self.xmax = 1.5
1006 994
1007 995 self.y = ACFs
1008 996
1009 997 ax = self.axes[0]
1010 998
1011 999 if ax.firsttime:
1012 1000
1013 1001 for i in range(NACF):
1014 1002 x_aux = numpy.isfinite(lags[i,:])
1015 1003 y_aux = numpy.isfinite(ACFs[i,:])
1016 1004 yerr_aux = numpy.isfinite(errACFs[i,:])
1017 1005
1018 1006 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
1019 1007 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',linewidth=1.0,markersize=2,ecolor='r')
1020 1008
1021 1009 #self.xstep_given = (self.xmax-self.xmin)/(self.data.NLAG-1)
1022 1010 self.xstep_given=0.3
1023 1011 self.ystep_given = 200
1024 1012 ax.yaxis.set_minor_locator(MultipleLocator(15))
1025 1013 ax.grid(which='minor')
1026 1014
1027 1015 else:
1028 1016 self.clear_figures()
1029 1017
1030 1018 for i in range(NACF):
1031 1019 x_aux = numpy.isfinite(lags[i,:])
1032 1020 y_aux = numpy.isfinite(ACFs[i,:])
1033 1021 yerr_aux = numpy.isfinite(errACFs[i,:])
1034 1022
1035 1023 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
1036 1024 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',linewidth=1.0,markersize=2,ecolor='r')
1037 1025
1038 1026 ax.yaxis.set_minor_locator(MultipleLocator(15))
1039 1027
1040 1028
1041 1029 class CrossProductsPlot(Plot):
1042 1030 '''
1043 1031 Plot for cross products
1044 1032 '''
1045 1033
1046 1034 CODE = 'crossprod'
1047 1035 plot_name = 'Cross Products'
1048 1036 plot_type = 'scatterbuffer'
1049 1037
1050 1038 def setup(self):
1051 1039
1052 1040 self.ncols = 3
1053 1041 self.nrows = 1
1054 1042 self.nplots = 3
1055 1043 self.ylabel = 'Range [km]'
1056 1044 self.titles = []
1057 1045 self.width = 3.5*self.nplots
1058 1046 self.height = 5.5
1059 1047 self.colorbar = False
1060 1048 self.plots_adjust.update({'wspace':.3, 'left': 0.12, 'right': 0.92, 'bottom': 0.1})
1061 1049
1062 1050
1063 1051 def update(self, dataOut):
1064 1052
1065 1053 data = {}
1066 1054 meta = {}
1067 1055
1068 1056 data['crossprod'] = dataOut.crossprods
1069 1057 data['NDP'] = dataOut.NDP
1070 1058
1071 1059 return data, meta
1072 1060
1073 1061 def plot(self):
1074 1062
1075 1063 NDP = self.data['NDP'][-1]
1076 1064 x = self.data['crossprod'][:,-1,:,:,:,:]
1077 1065 y = self.data.yrange[0:NDP]
1078 1066
1079 1067 for n, ax in enumerate(self.axes):
1080 1068
1081 1069 self.xmin=numpy.min(numpy.concatenate((x[n][0,20:30,0,0],x[n][1,20:30,0,0],x[n][2,20:30,0,0],x[n][3,20:30,0,0])))
1082 1070 self.xmax=numpy.max(numpy.concatenate((x[n][0,20:30,0,0],x[n][1,20:30,0,0],x[n][2,20:30,0,0],x[n][3,20:30,0,0])))
1083 1071
1084 1072 if ax.firsttime:
1085 1073
1086 1074 self.autoxticks=False
1087 1075 if n==0:
1088 1076 label1='kax'
1089 1077 label2='kay'
1090 1078 label3='kbx'
1091 1079 label4='kby'
1092 1080 self.xlimits=[(self.xmin,self.xmax)]
1093 1081 elif n==1:
1094 1082 label1='kax2'
1095 1083 label2='kay2'
1096 1084 label3='kbx2'
1097 1085 label4='kby2'
1098 1086 self.xlimits.append((self.xmin,self.xmax))
1099 1087 elif n==2:
1100 1088 label1='kaxay'
1101 1089 label2='kbxby'
1102 1090 label3='kaxbx'
1103 1091 label4='kaxby'
1104 1092 self.xlimits.append((self.xmin,self.xmax))
1105 1093
1106 1094 ax.plotline1 = ax.plot(x[n][0,:,0,0], y, color='r',linewidth=2.0, label=label1)
1107 1095 ax.plotline2 = ax.plot(x[n][1,:,0,0], y, color='k',linewidth=2.0, label=label2)
1108 1096 ax.plotline3 = ax.plot(x[n][2,:,0,0], y, color='b',linewidth=2.0, label=label3)
1109 1097 ax.plotline4 = ax.plot(x[n][3,:,0,0], y, color='m',linewidth=2.0, label=label4)
1110 1098 ax.legend(loc='upper right')
1111 1099 ax.set_xlim(self.xmin, self.xmax)
1112 1100 self.titles.append('{}'.format(self.plot_name.upper()))
1113 1101
1114 1102 else:
1115 1103
1116 1104 if n==0:
1117 1105 self.xlimits=[(self.xmin,self.xmax)]
1118 1106 else:
1119 1107 self.xlimits.append((self.xmin,self.xmax))
1120 1108
1121 1109 ax.set_xlim(self.xmin, self.xmax)
1122 1110
1123 1111 ax.plotline1[0].set_data(x[n][0,:,0,0],y)
1124 1112 ax.plotline2[0].set_data(x[n][1,:,0,0],y)
1125 1113 ax.plotline3[0].set_data(x[n][2,:,0,0],y)
1126 1114 ax.plotline4[0].set_data(x[n][3,:,0,0],y)
1127 1115 self.titles.append('{}'.format(self.plot_name.upper()))
1128 1116
1129 1117
1130 1118 class CrossProductsLPPlot(Plot):
1131 1119 '''
1132 1120 Plot for cross products LP
1133 1121 '''
1134 1122
1135 1123 CODE = 'crossprodslp'
1136 1124 plot_name = 'Cross Products LP'
1137 1125 plot_type = 'scatterbuffer'
1138 1126
1139 1127
1140 1128 def setup(self):
1141 1129
1142 1130 self.ncols = 2
1143 1131 self.nrows = 1
1144 1132 self.nplots = 2
1145 1133 self.ylabel = 'Range [km]'
1146 1134 self.xlabel = 'dB'
1147 1135 self.width = 3.5*self.nplots
1148 1136 self.height = 5.5
1149 1137 self.colorbar = False
1150 1138 self.titles = []
1151 1139 self.plots_adjust.update({'wspace': .8 ,'left': 0.17, 'right': 0.88, 'bottom': 0.1})
1152 1140
1153 1141 def update(self, dataOut):
1154 1142 data = {}
1155 1143 meta = {}
1156 1144
1157 1145 data['crossprodslp'] = 10*numpy.log10(numpy.abs(dataOut.output_LP))
1158 1146
1159 1147 data['NRANGE'] = dataOut.NRANGE #This is metadata
1160 1148 data['NLAG'] = dataOut.NLAG #This is metadata
1161 1149
1162 1150 return data, meta
1163 1151
1164 1152 def plot(self):
1165 1153
1166 1154 NRANGE = self.data['NRANGE'][-1]
1167 1155 NLAG = self.data['NLAG'][-1]
1168 1156
1169 1157 x = self.data[self.CODE][:,-1,:,:]
1170 1158 self.y = self.data.yrange[0:NRANGE]
1171 1159
1172 1160 label_array=numpy.array(['lag '+ str(x) for x in range(NLAG)])
1173 1161 color_array=['r','k','g','b','c','m','y','orange','steelblue','purple','peru','darksalmon','grey','limegreen','olive','midnightblue']
1174 1162
1175 1163
1176 1164 for n, ax in enumerate(self.axes):
1177 1165
1178 1166 self.xmin=28#30
1179 1167 self.xmax=70#70
1180 1168 #self.xmin=numpy.min(numpy.concatenate((self.x[0,:,n],self.x[1,:,n])))
1181 1169 #self.xmax=numpy.max(numpy.concatenate((self.x[0,:,n],self.x[1,:,n])))
1182 1170
1183 1171 if ax.firsttime:
1184 1172
1185 1173 self.autoxticks=False
1186 1174 if n == 0:
1187 1175 self.plotline_array=numpy.zeros((2,NLAG),dtype=object)
1188 1176
1189 1177 for i in range(NLAG):
1190 1178 self.plotline_array[n,i], = ax.plot(x[i,:,n], self.y, color=color_array[i],linewidth=1.0, label=label_array[i])
1191 1179
1192 1180 ax.legend(loc='upper right')
1193 1181 ax.set_xlim(self.xmin, self.xmax)
1194 1182 if n==0:
1195 1183 self.titles.append('{} CH0'.format(self.plot_name.upper()))
1196 1184 if n==1:
1197 1185 self.titles.append('{} CH1'.format(self.plot_name.upper()))
1198 1186 else:
1199 1187 for i in range(NLAG):
1200 1188 self.plotline_array[n,i].set_data(x[i,:,n],self.y)
1201 1189
1202 1190 if n==0:
1203 1191 self.titles.append('{} CH0'.format(self.plot_name.upper()))
1204 1192 if n==1:
1205 1193 self.titles.append('{} CH1'.format(self.plot_name.upper()))
1206 1194
1207 1195
1208 1196 class NoiseDPPlot(NoisePlot):
1209 1197 '''
1210 1198 Plot for noise Double Pulse
1211 1199 '''
1212 1200
1213 1201 CODE = 'noise'
1214 1202 #plot_name = 'Noise'
1215 1203 #plot_type = 'scatterbuffer'
1216 1204
1217 1205 def update(self, dataOut):
1218 1206
1219 1207 data = {}
1220 1208 meta = {}
1221 1209 data['noise'] = 10*numpy.log10(dataOut.noise_final)
1222 1210
1223 1211 return data, meta
1224 1212
1225 1213
1226 1214 class XmitWaveformPlot(Plot):
1227 1215 '''
1228 1216 Plot for xmit waveform
1229 1217 '''
1230 1218
1231 1219 CODE = 'xmit'
1232 1220 plot_name = 'Xmit Waveform'
1233 1221 plot_type = 'scatterbuffer'
1234 1222
1235 1223
1236 1224 def setup(self):
1237 1225
1238 1226 self.ncols = 1
1239 1227 self.nrows = 1
1240 1228 self.nplots = 1
1241 1229 self.ylabel = ''
1242 1230 self.xlabel = 'Number of Lag'
1243 1231 self.width = 5.5
1244 1232 self.height = 3.5
1245 1233 self.colorbar = False
1246 1234 self.plots_adjust.update({'right': 0.85 })
1247 1235 self.titles = [self.plot_name]
1248 1236 #self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
1249 1237
1250 1238 #if not self.titles:
1251 1239 #self.titles = self.data.parameters \
1252 1240 #if self.data.parameters else ['{}'.format(self.plot_name.upper())]
1253 1241
1254 1242 def update(self, dataOut):
1255 1243
1256 1244 data = {}
1257 1245 meta = {}
1258 1246
1259 1247 y_1=numpy.arctan2(dataOut.output_LP[:,0,2].imag,dataOut.output_LP[:,0,2].real)* 180 / (numpy.pi*10)
1260 1248 y_2=numpy.abs(dataOut.output_LP[:,0,2])
1261 1249 norm=numpy.max(y_2)
1262 1250 norm=max(norm,0.1)
1263 1251 y_2=y_2/norm
1264 1252
1265 1253 meta['yrange'] = numpy.array([])
1266 1254
1267 1255 data['xmit'] = numpy.vstack((y_1,y_2))
1268 1256 data['NLAG'] = dataOut.NLAG
1269 1257
1270 1258 return data, meta
1271 1259
1272 1260 def plot(self):
1273 1261
1274 1262 data = self.data[-1]
1275 1263 NLAG = data['NLAG']
1276 1264 x = numpy.arange(0,NLAG,1,'float32')
1277 1265 y = data['xmit']
1278 1266
1279 1267 self.xmin = 0
1280 1268 self.xmax = NLAG-1
1281 1269 self.ymin = -1.0
1282 1270 self.ymax = 1.0
1283 1271 ax = self.axes[0]
1284 1272
1285 1273 if ax.firsttime:
1286 1274 ax.plotline0=ax.plot(x,y[0,:],color='blue')
1287 1275 ax.plotline1=ax.plot(x,y[1,:],color='red')
1288 1276 secax=ax.secondary_xaxis(location=0.5)
1289 1277 secax.xaxis.tick_bottom()
1290 1278 secax.tick_params( labelleft=False, labeltop=False,
1291 1279 labelright=False, labelbottom=False)
1292 1280
1293 1281 self.xstep_given = 3
1294 1282 self.ystep_given = .25
1295 1283 secax.set_xticks(numpy.linspace(self.xmin, self.xmax, 6)) #only works on matplotlib.version>3.2
1296 1284
1297 1285 else:
1298 1286 ax.plotline0[0].set_data(x,y[0,:])
1299 1287 ax.plotline1[0].set_data(x,y[1,:])
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now