##// END OF EJS Templates
Now RTIPlot and SpcPlot can show different dBrange
rflores -
r1550:f7e4a1824cf4
parent child
Show More

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

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