@@ -43,12 +43,14 desc = "{desc}" | |||
|
43 | 43 | plotter = Project() |
|
44 | 44 | plotter.setup(id='100', name='receiver', description=desc) |
|
45 | 45 | |
|
46 |
receiver_p |
|
|
47 |
receiver_p |
|
|
46 | receiver_plot = plotter.addProcUnit(name='PlotterReceiver') | |
|
47 | receiver_plot.addParameter(name='throttle', value=20, format='int') | |
|
48 | receiver_plot.addParameter(name='plottypes', value='rti', format='str') | |
|
48 | 49 | |
|
49 |
rti = receiver_p |
|
|
50 | rti = receiver_plot.addOperation(name='PlotRTIData', optype='other') | |
|
50 | 51 | rti.addParameter(name='zmin', value='-40.0', format='float') |
|
51 | 52 | rti.addParameter(name='zmax', value='100.0', format='float') |
|
53 | rti.addParameter(name='decimation', value='200', format='int') | |
|
52 | 54 | rti.addParameter(name='xmin', value='0.0', format='int') |
|
53 | 55 | rti.addParameter(name='colormap', value='jet', format='str') |
|
54 | 56 |
@@ -1,11 +1,11 | |||
|
1 | 1 | ## CHANGELOG: |
|
2 | 2 | |
|
3 | 3 | ### 2.3 |
|
4 |
* Added high order function ` |
|
|
4 | * Added high order function `MPProject` for multiprocessing scripts. | |
|
5 | 5 | * Added two new Processing Units `PublishData` and `ReceiverData` for receiving and sending dataOut through multiple ways (tcp, ipc, inproc). |
|
6 | 6 | * Added a new graphics Processing Unit `PlotterReceiver`. It is decoupled from normal processing sequence with support for data generated by multiprocessing scripts. |
|
7 | 7 | * Added support for sending realtime graphic to web server. |
|
8 |
* GUI command `schain` |
|
|
8 | * GUI command `schain` is now `schainGUI`. | |
|
9 | 9 | * Added a CLI tool named `schain`. |
|
10 | 10 | * Scripts templates can be now generated with `schain generate`. |
|
11 | 11 | * Now it is possible to search Processing Units and Operations with `schain search [module]` to get the right name and its allowed parameters. |
@@ -16,16 +16,23 from schainpy.model.proc.jroproc_base import Operation | |||
|
16 | 16 | from schainpy.utils import log |
|
17 | 17 | |
|
18 | 18 | jet_values = matplotlib.pyplot.get_cmap("jet", 100)(numpy.arange(100))[10:90] |
|
19 |
blu_values = matplotlib.pyplot.get_cmap( |
|
|
20 | ncmap = matplotlib.colors.LinearSegmentedColormap.from_list("jro", numpy.vstack((blu_values, jet_values))) | |
|
19 | blu_values = matplotlib.pyplot.get_cmap( | |
|
20 | "seismic_r", 20)(numpy.arange(20))[10:15] | |
|
21 | ncmap = matplotlib.colors.LinearSegmentedColormap.from_list( | |
|
22 | "jro", numpy.vstack((blu_values, jet_values))) | |
|
21 | 23 | matplotlib.pyplot.register_cmap(cmap=ncmap) |
|
22 | 24 | |
|
23 | func = lambda x, pos: '{}'.format(datetime.datetime.fromtimestamp(x).strftime('%H:%M')) | |
|
24 | 25 | |
|
25 | UT1970 = datetime.datetime(1970, 1, 1) - datetime.timedelta(seconds=time.timezone) | |
|
26 | def func(x, pos): return '{}'.format( | |
|
27 | datetime.datetime.fromtimestamp(x).strftime('%H:%M')) | |
|
28 | ||
|
29 | ||
|
30 | UT1970 = datetime.datetime(1970, 1, 1) - \ | |
|
31 | datetime.timedelta(seconds=time.timezone) | |
|
26 | 32 | |
|
27 | 33 | CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'RdBu_r', 'seismic')] |
|
28 | 34 | |
|
35 | ||
|
29 | 36 | class PlotData(Operation, Process): |
|
30 | 37 | ''' |
|
31 | 38 | Base class for Schain plotting operations |
@@ -45,7 +52,7 class PlotData(Operation, Process): | |||
|
45 | 52 | self.kwargs['code'] = self.CODE |
|
46 | 53 | self.mp = False |
|
47 | 54 | self.data = None |
|
48 |
self.isConfig = False |
|
|
55 | self.isConfig = False | |
|
49 | 56 | self.figures = [] |
|
50 | 57 | self.axes = [] |
|
51 | 58 | self.cb_axes = [] |
@@ -65,13 +72,13 class PlotData(Operation, Process): | |||
|
65 | 72 | self.zmin = kwargs.get('zmin', None) |
|
66 | 73 | self.zmax = kwargs.get('zmax', None) |
|
67 | 74 | self.zlimits = kwargs.get('zlimits', None) |
|
68 |
self.xmin = kwargs.get('xmin', None) |
|
|
75 | self.xmin = kwargs.get('xmin', None) | |
|
69 | 76 | self.xmax = kwargs.get('xmax', None) |
|
70 | 77 | self.xrange = kwargs.get('xrange', 24) |
|
71 | 78 | self.ymin = kwargs.get('ymin', None) |
|
72 | 79 | self.ymax = kwargs.get('ymax', None) |
|
73 | 80 | self.xlabel = kwargs.get('xlabel', None) |
|
74 |
self.__MAXNUMY = kwargs.get('decimation', 100) |
|
|
81 | self.__MAXNUMY = kwargs.get('decimation', 100) | |
|
75 | 82 | self.showSNR = kwargs.get('showSNR', False) |
|
76 | 83 | self.oneFigure = kwargs.get('oneFigure', True) |
|
77 | 84 | self.width = kwargs.get('width', None) |
@@ -98,47 +105,47 class PlotData(Operation, Process): | |||
|
98 | 105 | self.pf_axes = [] |
|
99 | 106 | self.cmaps = [] |
|
100 | 107 | |
|
101 | size = '15%' if self.ncols==1 else '30%' | |
|
102 | pad = '4%' if self.ncols==1 else '8%' | |
|
108 | size = '15%' if self.ncols == 1 else '30%' | |
|
109 | pad = '4%' if self.ncols == 1 else '8%' | |
|
103 | 110 | |
|
104 | 111 | if self.oneFigure: |
|
105 | 112 | if self.height is None: |
|
106 | self.height = 1.4*self.nrows + 1 | |
|
113 | self.height = 1.4 * self.nrows + 1 | |
|
107 | 114 | fig = plt.figure(figsize=(self.width, self.height), |
|
108 | 115 | edgecolor='k', |
|
109 | 116 | facecolor='w') |
|
110 | 117 | self.figures.append(fig) |
|
111 |
for n in range(self.nplots): |
|
|
112 | ax = fig.add_subplot(self.nrows, self.ncols, n+1) | |
|
118 | for n in range(self.nplots): | |
|
119 | ax = fig.add_subplot(self.nrows, self.ncols, n + 1) | |
|
113 | 120 | ax.tick_params(labelsize=8) |
|
114 | 121 | ax.firsttime = True |
|
115 | 122 | ax.index = 0 |
|
116 |
self.axes.append(ax) |
|
|
123 | self.axes.append(ax) | |
|
117 | 124 | if self.showprofile: |
|
118 | 125 | cax = self.__add_axes(ax, size=size, pad=pad) |
|
119 |
cax.tick_params(labelsize=8) |
|
|
126 | cax.tick_params(labelsize=8) | |
|
120 | 127 | self.pf_axes.append(cax) |
|
121 | 128 | else: |
|
122 | 129 | if self.height is None: |
|
123 | 130 | self.height = 3 |
|
124 | 131 | for n in range(self.nplots): |
|
125 | 132 | fig = plt.figure(figsize=(self.width, self.height), |
|
126 |
|
|
|
127 |
|
|
|
133 | edgecolor='k', | |
|
134 | facecolor='w') | |
|
128 | 135 | ax = fig.add_subplot(1, 1, 1) |
|
129 | 136 | ax.tick_params(labelsize=8) |
|
130 | 137 | ax.firsttime = True |
|
131 | 138 | ax.index = 0 |
|
132 |
self.figures.append(fig) |
|
|
139 | self.figures.append(fig) | |
|
133 | 140 | self.axes.append(ax) |
|
134 | 141 | if self.showprofile: |
|
135 | 142 | cax = self.__add_axes(ax, size=size, pad=pad) |
|
136 |
cax.tick_params(labelsize=8) |
|
|
143 | cax.tick_params(labelsize=8) | |
|
137 | 144 | self.pf_axes.append(cax) |
|
138 | ||
|
145 | ||
|
139 | 146 | for n in range(self.nrows): |
|
140 | 147 | if self.colormaps is not None: |
|
141 |
cmap = plt.get_cmap(self.colormaps[n]) |
|
|
148 | cmap = plt.get_cmap(self.colormaps[n]) | |
|
142 | 149 | else: |
|
143 | 150 | cmap = plt.get_cmap(self.colormap) |
|
144 | 151 | cmap.set_bad(self.bgcolor, 1.) |
@@ -158,13 +165,13 class PlotData(Operation, Process): | |||
|
158 | 165 | elif event.key == 'up': |
|
159 | 166 | ax.index -= 1 |
|
160 | 167 | if ax.index < 0: |
|
161 |
ax.index = len(CMAPS) - 1 |
|
|
168 | ax.index = len(CMAPS) - 1 | |
|
162 | 169 | elif ax.index == len(CMAPS): |
|
163 | 170 | ax.index = 0 |
|
164 | 171 | cmap = CMAPS[ax.index] |
|
165 | 172 | ax.cbar.set_cmap(cmap) |
|
166 | 173 | ax.cbar.draw_all() |
|
167 |
ax.plt.set_cmap(cmap) |
|
|
174 | ax.plt.set_cmap(cmap) | |
|
168 | 175 | ax.cbar.patch.figure.canvas.draw() |
|
169 | 176 | |
|
170 | 177 | def __add_axes(self, ax, size='30%', pad='8%'): |
@@ -173,7 +180,7 class PlotData(Operation, Process): | |||
|
173 | 180 | ''' |
|
174 | 181 | divider = make_axes_locatable(ax) |
|
175 | 182 | nax = divider.new_horizontal(size=size, pad=pad) |
|
176 |
ax.figure.add_axes(nax) |
|
|
183 | ax.figure.add_axes(nax) | |
|
177 | 184 | return nax |
|
178 | 185 | |
|
179 | 186 | self.setup() |
@@ -182,7 +189,7 class PlotData(Operation, Process): | |||
|
182 | 189 | ''' |
|
183 | 190 | This method should be implemented in the child class, the following |
|
184 | 191 | attributes should be set: |
|
185 | ||
|
192 | ||
|
186 | 193 | self.nrows: number of rows |
|
187 | 194 | self.ncols: number of cols |
|
188 | 195 | self.nplots: number of plots (channels or pairs) |
@@ -202,26 +209,26 class PlotData(Operation, Process): | |||
|
202 | 209 | deltas = x_buffer[1:] - x_buffer[0:-1] |
|
203 | 210 | x_median = numpy.median(deltas) |
|
204 | 211 | |
|
205 | index = numpy.where(deltas > 5*x_median) | |
|
212 | index = numpy.where(deltas > 5 * x_median) | |
|
206 | 213 | |
|
207 | 214 | if len(index[0]) != 0: |
|
208 | 215 | z_buffer[::, index[0], ::] = self.__missing |
|
209 | 216 | z_buffer = numpy.ma.masked_inside(z_buffer, |
|
210 | 0.99*self.__missing, | |
|
211 | 1.01*self.__missing) | |
|
217 | 0.99 * self.__missing, | |
|
218 | 1.01 * self.__missing) | |
|
212 | 219 | |
|
213 | 220 | return x_buffer, y_buffer, z_buffer |
|
214 | 221 | |
|
215 | 222 | def decimate(self): |
|
216 | 223 | |
|
217 | 224 | # dx = int(len(self.x)/self.__MAXNUMX) + 1 |
|
218 | dy = int(len(self.y)/self.__MAXNUMY) + 1 | |
|
225 | dy = int(len(self.y) / self.__MAXNUMY) + 1 | |
|
219 | 226 | |
|
220 | 227 | # x = self.x[::dx] |
|
221 | 228 | x = self.x |
|
222 | 229 | y = self.y[::dy] |
|
223 | 230 | z = self.z[::, ::, ::dy] |
|
224 | ||
|
231 | ||
|
225 | 232 | return x, y, z |
|
226 | 233 | |
|
227 | 234 | def format(self): |
@@ -235,42 +242,43 class PlotData(Operation, Process): | |||
|
235 | 242 | if self.xaxis is 'time': |
|
236 | 243 | dt = datetime.datetime.fromtimestamp(self.min_time) |
|
237 | 244 | xmin = (datetime.datetime.combine(dt.date(), |
|
238 | datetime.time(int(self.xmin), 0, 0))-UT1970).total_seconds() | |
|
245 | datetime.time(int(self.xmin), 0, 0)) - UT1970).total_seconds() | |
|
239 | 246 | else: |
|
240 | 247 | xmin = self.xmin |
|
241 | 248 | |
|
242 | 249 | if self.xmax is None: |
|
243 | xmax = xmin+self.xrange*60*60 | |
|
250 | xmax = xmin + self.xrange * 60 * 60 | |
|
244 | 251 | else: |
|
245 | 252 | if self.xaxis is 'time': |
|
246 | 253 | dt = datetime.datetime.fromtimestamp(self.min_time) |
|
247 | 254 | xmax = (datetime.datetime.combine(dt.date(), |
|
248 | datetime.time(int(self.xmax), 0, 0))-UT1970).total_seconds() | |
|
255 | datetime.time(int(self.xmax), 0, 0)) - UT1970).total_seconds() | |
|
249 | 256 | else: |
|
250 | 257 | xmax = self.xmax |
|
251 | ||
|
258 | ||
|
252 | 259 | ymin = self.ymin if self.ymin else numpy.nanmin(self.y) |
|
253 | 260 | ymax = self.ymax if self.ymax else numpy.nanmax(self.y) |
|
254 | ||
|
255 | ystep = 200 if ymax>= 800 else 100 if ymax>=400 else 50 if ymax>=200 else 20 | |
|
256 | 261 | |
|
257 | for n, ax in enumerate(self.axes): | |
|
262 | ystep = 200 if ymax >= 800 else 100 if ymax >= 400 else 50 if ymax >= 200 else 20 | |
|
263 | ||
|
264 | for n, ax in enumerate(self.axes): | |
|
258 | 265 | if ax.firsttime: |
|
259 | 266 | ax.set_facecolor(self.bgcolor) |
|
260 | 267 | ax.yaxis.set_major_locator(MultipleLocator(ystep)) |
|
261 |
if self.xaxis is 'time': |
|
|
268 | if self.xaxis is 'time': | |
|
262 | 269 | ax.xaxis.set_major_formatter(FuncFormatter(func)) |
|
263 |
ax.xaxis.set_major_locator(LinearLocator(9)) |
|
|
270 | ax.xaxis.set_major_locator(LinearLocator(9)) | |
|
264 | 271 | if self.xlabel is not None: |
|
265 | 272 | ax.set_xlabel(self.xlabel) |
|
266 |
ax.set_ylabel(self.ylabel) |
|
|
273 | ax.set_ylabel(self.ylabel) | |
|
267 | 274 | ax.firsttime = False |
|
268 | 275 | if self.showprofile: |
|
269 | 276 | self.pf_axes[n].set_ylim(ymin, ymax) |
|
270 |
self.pf_axes[n].set_xlim(self.zmin, self.zmax) |
|
|
277 | self.pf_axes[n].set_xlim(self.zmin, self.zmax) | |
|
271 | 278 | self.pf_axes[n].set_xlabel('dB') |
|
272 | 279 | self.pf_axes[n].grid(b=True, axis='x') |
|
273 |
[tick.set_visible(False) |
|
|
280 | [tick.set_visible(False) | |
|
281 | for tick in self.pf_axes[n].get_yticklabels()] | |
|
274 | 282 | if self.colorbar: |
|
275 | 283 | ax.cbar = plt.colorbar(ax.plt, ax=ax, pad=0.02, aspect=10) |
|
276 | 284 | ax.cbar.ax.tick_params(labelsize=8) |
@@ -278,11 +286,12 class PlotData(Operation, Process): | |||
|
278 | 286 | ax.cbar.set_label(self.cb_label, size=8) |
|
279 | 287 | elif self.cb_labels: |
|
280 | 288 | ax.cbar.set_label(self.cb_labels[n], size=8) |
|
281 | ||
|
289 | ||
|
282 | 290 | ax.set_title('{} - {} {}'.format( |
|
283 |
|
|
|
284 |
|
|
|
285 |
self. |
|
|
291 | self.titles[n], | |
|
292 | datetime.datetime.fromtimestamp( | |
|
293 | self.max_time).strftime('%H:%M:%S'), | |
|
294 | self.time_label), | |
|
286 | 295 | size=8) |
|
287 | 296 | ax.set_xlim(xmin, xmax) |
|
288 | 297 | ax.set_ylim(ymin, ymax) |
@@ -291,22 +300,22 class PlotData(Operation, Process): | |||
|
291 | 300 | ''' |
|
292 | 301 | ''' |
|
293 | 302 | log.success('Plotting', self.name) |
|
294 | ||
|
303 | ||
|
295 | 304 | self.plot() |
|
296 | 305 | self.format() |
|
297 | ||
|
306 | ||
|
298 | 307 | for n, fig in enumerate(self.figures): |
|
299 | 308 | if self.nrows == 0 or self.nplots == 0: |
|
300 | 309 | log.warning('No data', self.name) |
|
301 | 310 | continue |
|
302 | 311 | if self.show: |
|
303 | 312 | fig.show() |
|
304 | ||
|
313 | ||
|
305 | 314 | fig.tight_layout() |
|
306 |
fig.canvas.manager.set_window_title('{} - {}'.format(self.title, |
|
|
315 | fig.canvas.manager.set_window_title('{} - {}'.format(self.title, | |
|
307 | 316 | datetime.datetime.fromtimestamp(self.max_time).strftime('%Y/%m/%d'))) |
|
308 | 317 | # fig.canvas.draw() |
|
309 | ||
|
318 | ||
|
310 | 319 | if self.save and self.data.ended: |
|
311 | 320 | channels = range(self.nrows) |
|
312 | 321 | if self.oneFigure: |
@@ -318,7 +327,8 class PlotData(Operation, Process): | |||
|
318 | 327 | '{}{}_{}.png'.format( |
|
319 | 328 | self.CODE, |
|
320 | 329 | label, |
|
321 |
datetime.datetime.fromtimestamp( |
|
|
330 | datetime.datetime.fromtimestamp( | |
|
331 | self.saveTime).strftime('%y%m%d_%H%M%S') | |
|
322 | 332 | ) |
|
323 | 333 | ) |
|
324 | 334 | print 'Saving figure: {}'.format(figname) |
@@ -339,26 +349,27 class PlotData(Operation, Process): | |||
|
339 | 349 | receiver.setsockopt(zmq.CONFLATE, self.CONFLATE) |
|
340 | 350 | |
|
341 | 351 | if 'server' in self.kwargs['parent']: |
|
342 | receiver.connect('ipc:///tmp/{}.plots'.format(self.kwargs['parent']['server'])) | |
|
352 | receiver.connect( | |
|
353 | 'ipc:///tmp/{}.plots'.format(self.kwargs['parent']['server'])) | |
|
343 | 354 | else: |
|
344 |
receiver.connect("ipc:///tmp/zmq.plots") |
|
|
355 | receiver.connect("ipc:///tmp/zmq.plots") | |
|
345 | 356 | |
|
346 | 357 | while True: |
|
347 | 358 | try: |
|
348 | 359 | self.data = receiver.recv_pyobj(flags=zmq.NOBLOCK) |
|
349 | ||
|
360 | ||
|
350 | 361 | if self.localtime: |
|
351 | 362 | self.times = self.data.times - time.timezone |
|
352 | 363 | else: |
|
353 | 364 | self.times = self.data.times |
|
354 | ||
|
365 | ||
|
355 | 366 | self.min_time = self.times[0] |
|
356 | 367 | self.max_time = self.times[-1] |
|
357 | 368 | |
|
358 | 369 | if self.isConfig is False: |
|
359 | 370 | self.__setup() |
|
360 | 371 | self.isConfig = True |
|
361 | ||
|
372 | ||
|
362 | 373 | self.__plot() |
|
363 | 374 | |
|
364 | 375 | except zmq.Again as e: |
@@ -372,23 +383,24 class PlotData(Operation, Process): | |||
|
372 | 383 | if self.data: |
|
373 | 384 | self.__plot() |
|
374 | 385 | |
|
386 | ||
|
375 | 387 | class PlotSpectraData(PlotData): |
|
376 | 388 | ''' |
|
377 | 389 | Plot for Spectra data |
|
378 | 390 | ''' |
|
379 | 391 | |
|
380 | 392 | CODE = 'spc' |
|
381 |
colormap = 'jro' |
|
|
393 | colormap = 'jro' | |
|
382 | 394 | |
|
383 | 395 | def setup(self): |
|
384 | 396 | self.nplots = len(self.data.channels) |
|
385 | self.ncols = int(numpy.sqrt(self.nplots)+ 0.9) | |
|
386 | self.nrows = int((1.0*self.nplots/self.ncols) + 0.9) | |
|
387 | self.width = 3.4*self.ncols | |
|
388 | self.height = 3*self.nrows | |
|
397 | self.ncols = int(numpy.sqrt(self.nplots) + 0.9) | |
|
398 | self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9) | |
|
399 | self.width = 3.4 * self.ncols | |
|
400 | self.height = 3 * self.nrows | |
|
389 | 401 | self.cb_label = 'dB' |
|
390 |
if self.showprofile: |
|
|
391 | self.width += 0.8*self.ncols | |
|
402 | if self.showprofile: | |
|
403 | self.width += 0.8 * self.ncols | |
|
392 | 404 | |
|
393 | 405 | self.ylabel = 'Range [Km]' |
|
394 | 406 | |
@@ -412,7 +424,7 class PlotSpectraData(PlotData): | |||
|
412 | 424 | y = self.data.heights |
|
413 | 425 | self.y = y |
|
414 | 426 | z = self.data['spc'] |
|
415 | ||
|
427 | ||
|
416 | 428 | for n, ax in enumerate(self.axes): |
|
417 | 429 | noise = self.data['noise'][n][-1] |
|
418 | 430 | if self.CODE == 'spc_mean': |
@@ -423,15 +435,16 class PlotSpectraData(PlotData): | |||
|
423 | 435 | self.zmin = self.zmin if self.zmin else numpy.nanmin(z) |
|
424 | 436 | self.zmax = self.zmax if self.zmax else numpy.nanmax(z) |
|
425 | 437 | ax.plt = ax.pcolormesh(x, y, z[n].T, |
|
426 | vmin=self.zmin, | |
|
427 | vmax=self.zmax, | |
|
428 | cmap=plt.get_cmap(self.colormap) | |
|
429 |
) |
|
|
438 | vmin=self.zmin, | |
|
439 | vmax=self.zmax, | |
|
440 | cmap=plt.get_cmap(self.colormap) | |
|
441 | ) | |
|
430 | 442 | |
|
431 | 443 | if self.showprofile: |
|
432 |
ax.plt_profile= self.pf_axes[n].plot( |
|
|
444 | ax.plt_profile = self.pf_axes[n].plot( | |
|
445 | self.data['rti'][n][-1], y)[0] | |
|
433 | 446 | ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y, |
|
434 |
|
|
|
447 | color="k", linestyle="dashed", lw=1)[0] | |
|
435 | 448 | if self.CODE == 'spc_mean': |
|
436 | 449 | ax.plt_mean = ax.plot(mean, y, color='k')[0] |
|
437 | 450 | else: |
@@ -452,17 +465,17 class PlotCrossSpectraData(PlotData): | |||
|
452 | 465 | zmin_coh = None |
|
453 | 466 | zmax_coh = None |
|
454 | 467 | zmin_phase = None |
|
455 |
zmax_phase = None |
|
|
468 | zmax_phase = None | |
|
456 | 469 | |
|
457 | 470 | def setup(self): |
|
458 | 471 | |
|
459 | 472 | self.ncols = 4 |
|
460 | 473 | self.nrows = len(self.data.pairs) |
|
461 | self.nplots = self.nrows*4 | |
|
462 | self.width = 3.4*self.ncols | |
|
463 | self.height = 3*self.nrows | |
|
474 | self.nplots = self.nrows * 4 | |
|
475 | self.width = 3.4 * self.ncols | |
|
476 | self.height = 3 * self.nrows | |
|
464 | 477 | self.ylabel = 'Range [Km]' |
|
465 |
self.showprofile = False |
|
|
478 | self.showprofile = False | |
|
466 | 479 | |
|
467 | 480 | def plot(self): |
|
468 | 481 | |
@@ -486,24 +499,24 class PlotCrossSpectraData(PlotData): | |||
|
486 | 499 | for n in range(self.nrows): |
|
487 | 500 | noise = self.data['noise'][n][-1] |
|
488 | 501 | pair = self.data.pairs[n] |
|
489 | ax = self.axes[4*n] | |
|
490 | ax3 = self.axes[4*n+3] | |
|
502 | ax = self.axes[4 * n] | |
|
503 | ax3 = self.axes[4 * n + 3] | |
|
491 | 504 | if ax.firsttime: |
|
492 | 505 | self.xmax = self.xmax if self.xmax else numpy.nanmax(x) |
|
493 | 506 | self.xmin = self.xmin if self.xmin else -self.xmax |
|
494 | 507 | self.zmin = self.zmin if self.zmin else numpy.nanmin(spc) |
|
495 |
self.zmax = self.zmax if self.zmax else numpy.nanmax(spc) |
|
|
508 | self.zmax = self.zmax if self.zmax else numpy.nanmax(spc) | |
|
496 | 509 | ax.plt = ax.pcolormesh(x, y, spc[pair[0]].T, |
|
497 | 510 | vmin=self.zmin, |
|
498 | 511 | vmax=self.zmax, |
|
499 | 512 | cmap=plt.get_cmap(self.colormap) |
|
500 |
) |
|
|
513 | ) | |
|
501 | 514 | else: |
|
502 | 515 | ax.plt.set_array(spc[pair[0]].T.ravel()) |
|
503 | 516 | self.titles.append('CH {}: {:3.2f}dB'.format(n, noise)) |
|
504 | 517 | |
|
505 | ax = self.axes[4*n+1] | |
|
506 |
if ax.firsttime: |
|
|
518 | ax = self.axes[4 * n + 1] | |
|
519 | if ax.firsttime: | |
|
507 | 520 | ax.plt = ax.pcolormesh(x, y, spc[pair[1]].T, |
|
508 | 521 | vmin=self.zmin, |
|
509 | 522 | vmax=self.zmax, |
@@ -513,12 +526,12 class PlotCrossSpectraData(PlotData): | |||
|
513 | 526 | ax.plt.set_array(spc[pair[1]].T.ravel()) |
|
514 | 527 | self.titles.append('CH {}: {:3.2f}dB'.format(n, noise)) |
|
515 | 528 | |
|
516 | out = cspc[n]/numpy.sqrt(spc[pair[0]]*spc[pair[1]]) | |
|
529 | out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]]) | |
|
517 | 530 | coh = numpy.abs(out) |
|
518 | phase = numpy.arctan2(out.imag, out.real)*180/numpy.pi | |
|
519 | ||
|
520 | ax = self.axes[4*n+2] | |
|
521 |
if ax.firsttime: |
|
|
531 | phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi | |
|
532 | ||
|
533 | ax = self.axes[4 * n + 2] | |
|
534 | if ax.firsttime: | |
|
522 | 535 | ax.plt = ax.pcolormesh(x, y, coh.T, |
|
523 | 536 | vmin=0, |
|
524 | 537 | vmax=1, |
@@ -526,9 +539,10 class PlotCrossSpectraData(PlotData): | |||
|
526 | 539 | ) |
|
527 | 540 | else: |
|
528 | 541 | ax.plt.set_array(coh.T.ravel()) |
|
529 | self.titles.append('Coherence Ch{} * Ch{}'.format(pair[0], pair[1])) | |
|
542 | self.titles.append( | |
|
543 | 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1])) | |
|
530 | 544 | |
|
531 | ax = self.axes[4*n+3] | |
|
545 | ax = self.axes[4 * n + 3] | |
|
532 | 546 | if ax.firsttime: |
|
533 | 547 | ax.plt = ax.pcolormesh(x, y, phase.T, |
|
534 | 548 | vmin=-180, |
@@ -538,7 +552,7 class PlotCrossSpectraData(PlotData): | |||
|
538 | 552 | else: |
|
539 | 553 | ax.plt.set_array(phase.T.ravel()) |
|
540 | 554 | self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1])) |
|
541 | ||
|
555 | ||
|
542 | 556 | self.saveTime = self.max_time |
|
543 | 557 | |
|
544 | 558 | |
@@ -560,12 +574,13 class PlotRTIData(PlotData): | |||
|
560 | 574 | |
|
561 | 575 | def setup(self): |
|
562 | 576 | self.xaxis = 'time' |
|
563 |
self.ncols = 1 |
|
|
577 | self.ncols = 1 | |
|
564 | 578 | self.nrows = len(self.data.channels) |
|
565 | 579 | self.nplots = len(self.data.channels) |
|
566 | 580 | self.ylabel = 'Range [Km]' |
|
567 | 581 | self.cb_label = 'dB' |
|
568 |
self.titles = ['{} Channel {}'.format( |
|
|
582 | self.titles = ['{} Channel {}'.format( | |
|
583 | self.CODE.upper(), x) for x in range(self.nrows)] | |
|
569 | 584 | |
|
570 | 585 | def plot(self): |
|
571 | 586 | self.x = self.times |
@@ -574,17 +589,18 class PlotRTIData(PlotData): | |||
|
574 | 589 | self.z = numpy.ma.masked_invalid(self.z) |
|
575 | 590 | |
|
576 | 591 | for n, ax in enumerate(self.axes): |
|
577 |
x, y, z = self.fill_gaps(*self.decimate()) |
|
|
592 | x, y, z = self.fill_gaps(*self.decimate()) | |
|
578 | 593 | self.zmin = self.zmin if self.zmin else numpy.min(self.z) |
|
579 | 594 | self.zmax = self.zmax if self.zmax else numpy.max(self.z) |
|
580 |
if ax.firsttime: |
|
|
595 | if ax.firsttime: | |
|
581 | 596 | ax.plt = ax.pcolormesh(x, y, z[n].T, |
|
582 | vmin=self.zmin, | |
|
583 | vmax=self.zmax, | |
|
584 | cmap=plt.get_cmap(self.colormap) | |
|
585 | ) | |
|
597 | vmin=self.zmin, | |
|
598 | vmax=self.zmax, | |
|
599 | cmap=plt.get_cmap(self.colormap) | |
|
600 | ) | |
|
586 | 601 | if self.showprofile: |
|
587 |
ax.plot_profile= self.pf_axes[n].plot( |
|
|
602 | ax.plot_profile = self.pf_axes[n].plot( | |
|
603 | self.data['rti'][n][-1], self.y)[0] | |
|
588 | 604 | ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y, |
|
589 | 605 | color="k", linestyle="dashed", lw=1)[0] |
|
590 | 606 | else: |
@@ -593,12 +609,13 class PlotRTIData(PlotData): | |||
|
593 | 609 | vmin=self.zmin, |
|
594 | 610 | vmax=self.zmax, |
|
595 | 611 | cmap=plt.get_cmap(self.colormap) |
|
596 | ) | |
|
612 | ) | |
|
597 | 613 | if self.showprofile: |
|
598 | 614 | ax.plot_profile.set_data(self.data['rti'][n][-1], self.y) |
|
599 |
ax.plot_noise.set_data(numpy.repeat( |
|
|
615 | ax.plot_noise.set_data(numpy.repeat( | |
|
616 | self.data['noise'][n][-1], len(self.y)), self.y) | |
|
600 | 617 | |
|
601 |
self.saveTime = self.min_time |
|
|
618 | self.saveTime = self.min_time | |
|
602 | 619 | |
|
603 | 620 | |
|
604 | 621 | class PlotCOHData(PlotRTIData): |
@@ -613,13 +630,15 class PlotCOHData(PlotRTIData): | |||
|
613 | 630 | self.ncols = 1 |
|
614 | 631 | self.nrows = len(self.data.pairs) |
|
615 | 632 | self.nplots = len(self.data.pairs) |
|
616 |
self.ylabel = 'Range [Km]' |
|
|
633 | self.ylabel = 'Range [Km]' | |
|
617 | 634 | if self.CODE == 'coh': |
|
618 | 635 | self.cb_label = '' |
|
619 | self.titles = ['Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs] | |
|
636 | self.titles = [ | |
|
637 | 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs] | |
|
620 | 638 | else: |
|
621 | 639 | self.cb_label = 'Degrees' |
|
622 | self.titles = ['Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs] | |
|
640 | self.titles = [ | |
|
641 | 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs] | |
|
623 | 642 | |
|
624 | 643 | |
|
625 | 644 | class PlotPHASEData(PlotCOHData): |
@@ -651,9 +670,9 class PlotNoiseData(PlotData): | |||
|
651 | 670 | |
|
652 | 671 | x = self.times |
|
653 | 672 | xmin = self.min_time |
|
654 | xmax = xmin+self.xrange*60*60 | |
|
673 | xmax = xmin + self.xrange * 60 * 60 | |
|
655 | 674 | Y = self.data[self.CODE] |
|
656 | ||
|
675 | ||
|
657 | 676 | if self.axes[0].firsttime: |
|
658 | 677 | for ch in self.data.channels: |
|
659 | 678 | y = Y[ch] |
@@ -663,7 +682,7 class PlotNoiseData(PlotData): | |||
|
663 | 682 | for ch in self.data.channels: |
|
664 | 683 | y = Y[ch] |
|
665 | 684 | self.axes[0].lines[ch].set_data(x, y) |
|
666 | ||
|
685 | ||
|
667 | 686 | self.ymin = numpy.nanmin(Y) - 5 |
|
668 | 687 | self.ymax = numpy.nanmax(Y) + 5 |
|
669 | 688 | self.saveTime = self.min_time |
@@ -711,26 +730,27 class PlotSkyMapData(PlotData): | |||
|
711 | 730 | else: |
|
712 | 731 | self.figure.clf() |
|
713 | 732 | |
|
714 | self.ax = plt.subplot2grid((self.nrows, self.ncols), (0, 0), 1, 1, polar=True) | |
|
733 | self.ax = plt.subplot2grid( | |
|
734 | (self.nrows, self.ncols), (0, 0), 1, 1, polar=True) | |
|
715 | 735 | self.ax.firsttime = True |
|
716 | 736 | |
|
717 | ||
|
718 | 737 | def plot(self): |
|
719 | 738 | |
|
720 |
arrayParameters = numpy.concatenate( |
|
|
721 | error = arrayParameters[:,-1] | |
|
739 | arrayParameters = numpy.concatenate( | |
|
740 | [self.data['param'][t] for t in self.times]) | |
|
741 | error = arrayParameters[:, -1] | |
|
722 | 742 | indValid = numpy.where(error == 0)[0] |
|
723 | finalMeteor = arrayParameters[indValid,:] | |
|
724 | finalAzimuth = finalMeteor[:,3] | |
|
725 | finalZenith = finalMeteor[:,4] | |
|
743 | finalMeteor = arrayParameters[indValid, :] | |
|
744 | finalAzimuth = finalMeteor[:, 3] | |
|
745 | finalZenith = finalMeteor[:, 4] | |
|
726 | 746 | |
|
727 | x = finalAzimuth*numpy.pi/180 | |
|
747 | x = finalAzimuth * numpy.pi / 180 | |
|
728 | 748 | y = finalZenith |
|
729 | 749 | |
|
730 | 750 | if self.ax.firsttime: |
|
731 | 751 | self.ax.plot = self.ax.plot(x, y, 'bo', markersize=5)[0] |
|
732 | self.ax.set_ylim(0,90) | |
|
733 | self.ax.set_yticks(numpy.arange(0,90,20)) | |
|
752 | self.ax.set_ylim(0, 90) | |
|
753 | self.ax.set_yticks(numpy.arange(0, 90, 20)) | |
|
734 | 754 | self.ax.set_xlabel(self.xlabel) |
|
735 | 755 | self.ax.set_ylabel(self.ylabel) |
|
736 | 756 | self.ax.yaxis.labelpad = 40 |
@@ -738,9 +758,10 class PlotSkyMapData(PlotData): | |||
|
738 | 758 | else: |
|
739 | 759 | self.ax.plot.set_data(x, y) |
|
740 | 760 | |
|
741 | ||
|
742 |
|
|
|
743 |
dt2 = datetime.datetime.fromtimestamp( |
|
|
761 | dt1 = datetime.datetime.fromtimestamp( | |
|
762 | self.min_time).strftime('%y/%m/%d %H:%M:%S') | |
|
763 | dt2 = datetime.datetime.fromtimestamp( | |
|
764 | self.max_time).strftime('%y/%m/%d %H:%M:%S') | |
|
744 | 765 | title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1, |
|
745 | 766 | dt2, |
|
746 | 767 | len(x)) |
@@ -748,6 +769,7 class PlotSkyMapData(PlotData): | |||
|
748 | 769 | |
|
749 | 770 | self.saveTime = self.max_time |
|
750 | 771 | |
|
772 | ||
|
751 | 773 | class PlotParamData(PlotRTIData): |
|
752 | 774 | ''' |
|
753 | 775 | Plot for data_param object |
@@ -764,7 +786,7 class PlotParamData(PlotRTIData): | |||
|
764 | 786 | if self.showSNR: |
|
765 | 787 | self.nrows += 1 |
|
766 | 788 | self.nplots += 1 |
|
767 | ||
|
789 | ||
|
768 | 790 | self.ylabel = 'Height [Km]' |
|
769 | 791 | self.titles = self.data.parameters \ |
|
770 | 792 | if self.data.parameters else ['Param {}'.format(x) for x in xrange(self.nrows)] |
@@ -772,10 +794,10 class PlotParamData(PlotRTIData): | |||
|
772 | 794 | self.titles.append('SNR') |
|
773 | 795 | |
|
774 | 796 | def plot(self): |
|
775 |
self.data.normalize_heights() |
|
|
797 | self.data.normalize_heights() | |
|
776 | 798 | self.x = self.times |
|
777 | 799 | self.y = self.data.heights |
|
778 |
if self.showSNR: |
|
|
800 | if self.showSNR: | |
|
779 | 801 | self.z = numpy.concatenate( |
|
780 | 802 | (self.data[self.CODE], self.data['snr']) |
|
781 | 803 | ) |
@@ -791,25 +813,27 class PlotParamData(PlotRTIData): | |||
|
791 | 813 | if ax.firsttime: |
|
792 | 814 | if self.zlimits is not None: |
|
793 | 815 | self.zmin, self.zmax = self.zlimits[n] |
|
794 |
self.zmax = self.zmax if self.zmax is not None else numpy.nanmax( |
|
|
816 | self.zmax = self.zmax if self.zmax is not None else numpy.nanmax( | |
|
817 | abs(self.z[:-1, :])) | |
|
795 | 818 | self.zmin = self.zmin if self.zmin is not None else -self.zmax |
|
796 | ax.plt = ax.pcolormesh(x, y, z[n, :, :].T*self.factors[n], | |
|
819 | ax.plt = ax.pcolormesh(x, y, z[n, :, :].T * self.factors[n], | |
|
797 | 820 | vmin=self.zmin, |
|
798 | 821 | vmax=self.zmax, |
|
799 | 822 | cmap=self.cmaps[n] |
|
800 |
) |
|
|
823 | ) | |
|
801 | 824 | else: |
|
802 | 825 | if self.zlimits is not None: |
|
803 | 826 | self.zmin, self.zmax = self.zlimits[n] |
|
804 | 827 | ax.collections.remove(ax.collections[0]) |
|
805 | ax.plt = ax.pcolormesh(x, y, z[n, :, :].T*self.factors[n], | |
|
828 | ax.plt = ax.pcolormesh(x, y, z[n, :, :].T * self.factors[n], | |
|
806 | 829 | vmin=self.zmin, |
|
807 | 830 | vmax=self.zmax, |
|
808 | 831 | cmap=self.cmaps[n] |
|
809 | ) | |
|
832 | ) | |
|
810 | 833 | |
|
811 | 834 | self.saveTime = self.min_time |
|
812 | 835 | |
|
836 | ||
|
813 | 837 | class PlotOuputData(PlotParamData): |
|
814 | 838 | ''' |
|
815 | 839 | Plot data_output object |
@@ -6,8 +6,8 from jroproc_base import ProcessingUnit, Operation | |||
|
6 | 6 | from schainpy.model.data.jroamisr import AMISR |
|
7 | 7 | |
|
8 | 8 | class AMISRProc(ProcessingUnit): |
|
9 | def __init__(self): | |
|
10 | ProcessingUnit.__init__(self) | |
|
9 | def __init__(self, **kwargs): | |
|
10 | ProcessingUnit.__init__(self, **kwargs) | |
|
11 | 11 | self.objectDict = {} |
|
12 | 12 | self.dataOut = AMISR() |
|
13 | 13 | |
@@ -17,7 +17,8 class AMISRProc(ProcessingUnit): | |||
|
17 | 17 | |
|
18 | 18 | |
|
19 | 19 | class PrintInfo(Operation): |
|
20 | def __init__(self): | |
|
20 | def __init__(self, **kwargs): | |
|
21 | Operation.__init__(self, **kwargs) | |
|
21 | 22 | self.__isPrinted = False |
|
22 | 23 | |
|
23 | 24 | def run(self, dataOut): |
@@ -42,8 +43,8 class BeamSelector(Operation): | |||
|
42 | 43 | profileIndex = None |
|
43 | 44 | nProfiles = None |
|
44 | 45 | |
|
45 | def __init__(self): | |
|
46 | ||
|
46 | def __init__(self, **kwargs): | |
|
47 | Operation.__init__(self, **kwargs) | |
|
47 | 48 | self.profileIndex = 0 |
|
48 | 49 | self.__isConfig = False |
|
49 | 50 | |
@@ -98,7 +99,8 class BeamSelector(Operation): | |||
|
98 | 99 | |
|
99 | 100 | class ProfileToChannels(Operation): |
|
100 | 101 | |
|
101 | def __init__(self): | |
|
102 | def __init__(self, **kwargs): | |
|
103 | Operation.__init__(self, **kwargs) | |
|
102 | 104 | self.__isConfig = False |
|
103 | 105 | self.__counter_chan = 0 |
|
104 | 106 | self.buffer = None |
@@ -1765,8 +1765,8 class WindProfiler(Operation): | |||
|
1765 | 1765 | |
|
1766 | 1766 | n = None |
|
1767 | 1767 | |
|
1768 | def __init__(self): | |
|
1769 | Operation.__init__(self) | |
|
1768 | def __init__(self, **kwargs): | |
|
1769 | Operation.__init__(self, **kwargs) | |
|
1770 | 1770 | |
|
1771 | 1771 | def __calculateCosDir(self, elev, azim): |
|
1772 | 1772 | zen = (90 - elev)*numpy.pi/180 |
@@ -2472,8 +2472,8 class WindProfiler(Operation): | |||
|
2472 | 2472 | |
|
2473 | 2473 | class EWDriftsEstimation(Operation): |
|
2474 | 2474 | |
|
2475 | def __init__(self): | |
|
2476 | Operation.__init__(self) | |
|
2475 | def __init__(self, **kwargs): | |
|
2476 | Operation.__init__(self, **kwargs) | |
|
2477 | 2477 | |
|
2478 | 2478 | def __correctValues(self, heiRang, phi, velRadial, SNR): |
|
2479 | 2479 | listPhi = phi.tolist() |
General Comments 0
You need to be logged in to leave comments.
Login now