##// END OF EJS Templates
New Updates
rflores -
r1561:3446c343bac9
parent child
Show More

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

@@ -1,702 +1,704
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 # All rights reserved.
2 # All rights reserved.
3 #
3 #
4 # Distributed under the terms of the BSD 3-clause license.
4 # Distributed under the terms of the BSD 3-clause license.
5 """Base class to create plot operations
5 """Base class to create plot operations
6
6
7 """
7 """
8
8
9 import os
9 import os
10 import sys
10 import sys
11 import zmq
11 import zmq
12 import time
12 import time
13 import numpy
13 import numpy
14 import datetime
14 import datetime
15 from collections import deque
15 from collections import deque
16 from functools import wraps
16 from functools import wraps
17 from threading import Thread
17 from threading import Thread
18 import matplotlib
18 import matplotlib
19
19
20 if 'BACKEND' in os.environ:
20 if 'BACKEND' in os.environ:
21 matplotlib.use(os.environ['BACKEND'])
21 matplotlib.use(os.environ['BACKEND'])
22 elif 'linux' in sys.platform:
22 elif 'linux' in sys.platform:
23 matplotlib.use("TkAgg")
23 matplotlib.use("TkAgg")
24 elif 'darwin' in sys.platform:
24 elif 'darwin' in sys.platform:
25 matplotlib.use('MacOSX')
25 matplotlib.use('MacOSX')
26 else:
26 else:
27 from schainpy.utils import log
27 from schainpy.utils import log
28 log.warning('Using default Backend="Agg"', 'INFO')
28 log.warning('Using default Backend="Agg"', 'INFO')
29 matplotlib.use('Agg')
29 matplotlib.use('Agg')
30
30
31 import matplotlib.pyplot as plt
31 import matplotlib.pyplot as plt
32 from matplotlib.patches import Polygon
32 from matplotlib.patches import Polygon
33 from mpl_toolkits.axes_grid1 import make_axes_locatable
33 from mpl_toolkits.axes_grid1 import make_axes_locatable
34 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
34 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
35
35
36 from schainpy.model.data.jrodata import PlotterData
36 from schainpy.model.data.jrodata import PlotterData
37 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
37 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
38 from schainpy.utils import log
38 from schainpy.utils import log
39
39
40 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
40 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
41 blu_values = matplotlib.pyplot.get_cmap(
41 blu_values = matplotlib.pyplot.get_cmap(
42 'seismic_r', 20)(numpy.arange(20))[10:15]
42 'seismic_r', 20)(numpy.arange(20))[10:15]
43 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
43 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
44 'jro', numpy.vstack((blu_values, jet_values)))
44 'jro', numpy.vstack((blu_values, jet_values)))
45 matplotlib.pyplot.register_cmap(cmap=ncmap)
45 matplotlib.pyplot.register_cmap(cmap=ncmap)
46
46
47 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
47 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
48 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
48 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
49
49
50 EARTH_RADIUS = 6.3710e3
50 EARTH_RADIUS = 6.3710e3
51
51
52 def ll2xy(lat1, lon1, lat2, lon2):
52 def ll2xy(lat1, lon1, lat2, lon2):
53
53
54 p = 0.017453292519943295
54 p = 0.017453292519943295
55 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
55 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
56 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
56 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
57 r = 12742 * numpy.arcsin(numpy.sqrt(a))
57 r = 12742 * numpy.arcsin(numpy.sqrt(a))
58 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
58 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
59 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
59 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
60 theta = -theta + numpy.pi/2
60 theta = -theta + numpy.pi/2
61 return r*numpy.cos(theta), r*numpy.sin(theta)
61 return r*numpy.cos(theta), r*numpy.sin(theta)
62
62
63
63
64 def km2deg(km):
64 def km2deg(km):
65 '''
65 '''
66 Convert distance in km to degrees
66 Convert distance in km to degrees
67 '''
67 '''
68
68
69 return numpy.rad2deg(km/EARTH_RADIUS)
69 return numpy.rad2deg(km/EARTH_RADIUS)
70
70
71
71
72 def figpause(interval):
72 def figpause(interval):
73 backend = plt.rcParams['backend']
73 backend = plt.rcParams['backend']
74 if backend in matplotlib.rcsetup.interactive_bk:
74 if backend in matplotlib.rcsetup.interactive_bk:
75 figManager = matplotlib._pylab_helpers.Gcf.get_active()
75 figManager = matplotlib._pylab_helpers.Gcf.get_active()
76 if figManager is not None:
76 if figManager is not None:
77 canvas = figManager.canvas
77 canvas = figManager.canvas
78 if canvas.figure.stale:
78 if canvas.figure.stale:
79 canvas.draw()
79 canvas.draw()
80 try:
80 try:
81 canvas.start_event_loop(interval)
81 canvas.start_event_loop(interval)
82 except:
82 except:
83 pass
83 pass
84 return
84 return
85
85
86 def popup(message):
86 def popup(message):
87 '''
87 '''
88 '''
88 '''
89
89
90 fig = plt.figure(figsize=(12, 8), facecolor='r')
90 fig = plt.figure(figsize=(12, 8), facecolor='r')
91 text = '\n'.join([s.strip() for s in message.split(':')])
91 text = '\n'.join([s.strip() for s in message.split(':')])
92 fig.text(0.01, 0.5, text, ha='left', va='center',
92 fig.text(0.01, 0.5, text, ha='left', va='center',
93 size='20', weight='heavy', color='w')
93 size='20', weight='heavy', color='w')
94 fig.show()
94 fig.show()
95 figpause(1000)
95 figpause(1000)
96
96
97
97
98 class Throttle(object):
98 class Throttle(object):
99 '''
99 '''
100 Decorator that prevents a function from being called more than once every
100 Decorator that prevents a function from being called more than once every
101 time period.
101 time period.
102 To create a function that cannot be called more than once a minute, but
102 To create a function that cannot be called more than once a minute, but
103 will sleep until it can be called:
103 will sleep until it can be called:
104 @Throttle(minutes=1)
104 @Throttle(minutes=1)
105 def foo():
105 def foo():
106 pass
106 pass
107
107
108 for i in range(10):
108 for i in range(10):
109 foo()
109 foo()
110 print "This function has run %s times." % i
110 print "This function has run %s times." % i
111 '''
111 '''
112
112
113 def __init__(self, seconds=0, minutes=0, hours=0):
113 def __init__(self, seconds=0, minutes=0, hours=0):
114 self.throttle_period = datetime.timedelta(
114 self.throttle_period = datetime.timedelta(
115 seconds=seconds, minutes=minutes, hours=hours
115 seconds=seconds, minutes=minutes, hours=hours
116 )
116 )
117
117
118 self.time_of_last_call = datetime.datetime.min
118 self.time_of_last_call = datetime.datetime.min
119
119
120 def __call__(self, fn):
120 def __call__(self, fn):
121 @wraps(fn)
121 @wraps(fn)
122 def wrapper(*args, **kwargs):
122 def wrapper(*args, **kwargs):
123 coerce = kwargs.pop('coerce', None)
123 coerce = kwargs.pop('coerce', None)
124 if coerce:
124 if coerce:
125 self.time_of_last_call = datetime.datetime.now()
125 self.time_of_last_call = datetime.datetime.now()
126 return fn(*args, **kwargs)
126 return fn(*args, **kwargs)
127 else:
127 else:
128 now = datetime.datetime.now()
128 now = datetime.datetime.now()
129 time_since_last_call = now - self.time_of_last_call
129 time_since_last_call = now - self.time_of_last_call
130 time_left = self.throttle_period - time_since_last_call
130 time_left = self.throttle_period - time_since_last_call
131
131
132 if time_left > datetime.timedelta(seconds=0):
132 if time_left > datetime.timedelta(seconds=0):
133 return
133 return
134
134
135 self.time_of_last_call = datetime.datetime.now()
135 self.time_of_last_call = datetime.datetime.now()
136 return fn(*args, **kwargs)
136 return fn(*args, **kwargs)
137
137
138 return wrapper
138 return wrapper
139
139
140 def apply_throttle(value):
140 def apply_throttle(value):
141
141
142 @Throttle(seconds=value)
142 @Throttle(seconds=value)
143 def fnThrottled(fn):
143 def fnThrottled(fn):
144 fn()
144 fn()
145
145
146 return fnThrottled
146 return fnThrottled
147
147
148
148
149 @MPDecorator
149 @MPDecorator
150 class Plot(Operation):
150 class Plot(Operation):
151 """Base class for Schain plotting operations
151 """Base class for Schain plotting operations
152
152
153 This class should never be use directtly you must subclass a new operation,
153 This class should never be use directtly you must subclass a new operation,
154 children classes must be defined as follow:
154 children classes must be defined as follow:
155
155
156 ExamplePlot(Plot):
156 ExamplePlot(Plot):
157
157
158 CODE = 'code'
158 CODE = 'code'
159 colormap = 'jet'
159 colormap = 'jet'
160 plot_type = 'pcolor' # options are ('pcolor', 'pcolorbuffer', 'scatter', 'scatterbuffer')
160 plot_type = 'pcolor' # options are ('pcolor', 'pcolorbuffer', 'scatter', 'scatterbuffer')
161
161
162 def setup(self):
162 def setup(self):
163 pass
163 pass
164
164
165 def plot(self):
165 def plot(self):
166 pass
166 pass
167
167
168 """
168 """
169
169
170 CODE = 'Figure'
170 CODE = 'Figure'
171 colormap = 'jet'
171 colormap = 'jet'
172 bgcolor = 'white'
172 bgcolor = 'white'
173 buffering = True
173 buffering = True
174 __missing = 1E30
174 __missing = 1E30
175
175
176 __attrs__ = ['show', 'save', 'ymin', 'ymax', 'zmin', 'zmax', 'title',
176 __attrs__ = ['show', 'save', 'ymin', 'ymax', 'zmin', 'zmax', 'title',
177 'showprofile']
177 'showprofile']
178
178
179 def __init__(self):
179 def __init__(self):
180
180
181 Operation.__init__(self)
181 Operation.__init__(self)
182 self.isConfig = False
182 self.isConfig = False
183 self.isPlotConfig = False
183 self.isPlotConfig = False
184 self.save_time = 0
184 self.save_time = 0
185 self.sender_time = 0
185 self.sender_time = 0
186 self.data = None
186 self.data = None
187 self.firsttime = True
187 self.firsttime = True
188 self.sender_queue = deque(maxlen=10)
188 self.sender_queue = deque(maxlen=10)
189 self.plots_adjust = {'left': 0.125, 'right': 0.9, 'bottom': 0.15, 'top': 0.9, 'wspace': 0.2, 'hspace': 0.2}
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 def __fmtTime(self, x, pos):
191 def __fmtTime(self, x, pos):
192 '''
192 '''
193 '''
193 '''
194
194
195 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
195 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
196
196
197 def __setup(self, **kwargs):
197 def __setup(self, **kwargs):
198 '''
198 '''
199 Initialize variables
199 Initialize variables
200 '''
200 '''
201
201
202 self.figures = []
202 self.figures = []
203 self.axes = []
203 self.axes = []
204 self.cb_axes = []
204 self.cb_axes = []
205 self.localtime = kwargs.pop('localtime', True)
205 self.localtime = kwargs.pop('localtime', True)
206 self.show = kwargs.get('show', True)
206 self.show = kwargs.get('show', True)
207 self.save = kwargs.get('save', False)
207 self.save = kwargs.get('save', False)
208 self.save_period = kwargs.get('save_period', 0)
208 self.save_period = kwargs.get('save_period', 0)
209 self.colormap = kwargs.get('colormap', self.colormap)
209 self.colormap = kwargs.get('colormap', self.colormap)
210 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
210 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
211 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
211 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
212 self.colormaps = kwargs.get('colormaps', None)
212 self.colormaps = kwargs.get('colormaps', None)
213 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
213 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
214 self.showprofile = kwargs.get('showprofile', False)
214 self.showprofile = kwargs.get('showprofile', False)
215 self.title = kwargs.get('wintitle', self.CODE.upper())
215 self.title = kwargs.get('wintitle', self.CODE.upper())
216 self.cb_label = kwargs.get('cb_label', None)
216 self.cb_label = kwargs.get('cb_label', None)
217 self.cb_labels = kwargs.get('cb_labels', None)
217 self.cb_labels = kwargs.get('cb_labels', None)
218 self.labels = kwargs.get('labels', None)
218 self.labels = kwargs.get('labels', None)
219 self.xaxis = kwargs.get('xaxis', 'frequency')
219 self.xaxis = kwargs.get('xaxis', 'frequency')
220 self.zmin = kwargs.get('zmin', None)
220 self.zmin = kwargs.get('zmin', None)
221 self.zmax = kwargs.get('zmax', None)
221 self.zmax = kwargs.get('zmax', None)
222 self.zlimits = kwargs.get('zlimits', None)
222 self.zlimits = kwargs.get('zlimits', None)
223 self.xlimits = kwargs.get('xlimits', None)
223 self.xlimits = kwargs.get('xlimits', None)
224 self.xstep_given = kwargs.get('xstep_given', None)
224 self.xstep_given = kwargs.get('xstep_given', None)
225 self.ystep_given = kwargs.get('ystep_given', None)
225 self.ystep_given = kwargs.get('ystep_given', None)
226 self.autoxticks = kwargs.get('autoxticks', True)
226 self.autoxticks = kwargs.get('autoxticks', True)
227 self.xmin = kwargs.get('xmin', None)
227 self.xmin = kwargs.get('xmin', None)
228 self.xmax = kwargs.get('xmax', None)
228 self.xmax = kwargs.get('xmax', None)
229 self.xrange = kwargs.get('xrange', 12)
229 self.xrange = kwargs.get('xrange', 12)
230 self.xscale = kwargs.get('xscale', None)
230 self.xscale = kwargs.get('xscale', None)
231 self.ymin = kwargs.get('ymin', None)
231 self.ymin = kwargs.get('ymin', None)
232 self.ymax = kwargs.get('ymax', None)
232 self.ymax = kwargs.get('ymax', None)
233 self.yscale = kwargs.get('yscale', None)
233 self.yscale = kwargs.get('yscale', None)
234 self.xlabel = kwargs.get('xlabel', None)
234 self.xlabel = kwargs.get('xlabel', None)
235 self.attr_time = kwargs.get('attr_time', 'utctime')
235 self.attr_time = kwargs.get('attr_time', 'utctime')
236 self.attr_data = kwargs.get('attr_data', 'data_param')
236 self.attr_data = kwargs.get('attr_data', 'data_param')
237 self.decimation = kwargs.get('decimation', None)
237 self.decimation = kwargs.get('decimation', None)
238 self.oneFigure = kwargs.get('oneFigure', True)
238 self.oneFigure = kwargs.get('oneFigure', True)
239 self.width = kwargs.get('width', None)
239 self.width = kwargs.get('width', None)
240 self.height = kwargs.get('height', None)
240 self.height = kwargs.get('height', None)
241 self.colorbar = kwargs.get('colorbar', True)
241 self.colorbar = kwargs.get('colorbar', True)
242 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
242 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
243 self.channels = kwargs.get('channels', None)
243 self.channels = kwargs.get('channels', None)
244 self.titles = kwargs.get('titles', [])
244 self.titles = kwargs.get('titles', [])
245 self.polar = False
245 self.polar = False
246 self.type = kwargs.get('type', 'iq')
246 self.type = kwargs.get('type', 'iq')
247 self.grid = kwargs.get('grid', False)
247 self.grid = kwargs.get('grid', False)
248 self.pause = kwargs.get('pause', False)
248 self.pause = kwargs.get('pause', False)
249 self.save_code = kwargs.get('save_code', self.CODE)
249 self.save_code = kwargs.get('save_code', self.CODE)
250 self.throttle = kwargs.get('throttle', 0)
250 self.throttle = kwargs.get('throttle', 0)
251 self.exp_code = kwargs.get('exp_code', None)
251 self.exp_code = kwargs.get('exp_code', None)
252 self.server = kwargs.get('server', False)
252 self.server = kwargs.get('server', False)
253 self.sender_period = kwargs.get('sender_period', 60)
253 self.sender_period = kwargs.get('sender_period', 60)
254 self.tag = kwargs.get('tag', '')
254 self.tag = kwargs.get('tag', '')
255 self.height_index = kwargs.get('height_index', None)
255 self.height_index = kwargs.get('height_index', None)
256 self.__throttle_plot = apply_throttle(self.throttle)
256 self.__throttle_plot = apply_throttle(self.throttle)
257 code = self.attr_data if self.attr_data else self.CODE
257 code = self.attr_data if self.attr_data else self.CODE
258 self.data = PlotterData(self.CODE, self.exp_code, self.localtime)
258 self.data = PlotterData(self.CODE, self.exp_code, self.localtime)
259 #self.EEJtype = kwargs.get('EEJtype', 2)
259 #self.EEJtype = kwargs.get('EEJtype', 2)
260
260
261 if self.server:
261 if self.server:
262 if not self.server.startswith('tcp://'):
262 if not self.server.startswith('tcp://'):
263 self.server = 'tcp://{}'.format(self.server)
263 self.server = 'tcp://{}'.format(self.server)
264 log.success(
264 log.success(
265 'Sending to server: {}'.format(self.server),
265 'Sending to server: {}'.format(self.server),
266 self.name
266 self.name
267 )
267 )
268
268
269 if isinstance(self.attr_data, str):
269 if isinstance(self.attr_data, str):
270 self.attr_data = [self.attr_data]
270 self.attr_data = [self.attr_data]
271
271
272 def __setup_plot(self):
272 def __setup_plot(self):
273 '''
273 '''
274 Common setup for all figures, here figures and axes are created
274 Common setup for all figures, here figures and axes are created
275 '''
275 '''
276
276
277 self.setup()
277 self.setup()
278
278
279 self.time_label = 'LT' if self.localtime else 'UTC'
279 self.time_label = 'LT' if self.localtime else 'UTC'
280
280
281 if self.width is None:
281 if self.width is None:
282 self.width = 8
282 self.width = 8
283
283
284 self.figures = []
284 self.figures = []
285 self.axes = []
285 self.axes = []
286 self.cb_axes = []
286 self.cb_axes = []
287 self.pf_axes = []
287 self.pf_axes = []
288 self.cmaps = []
288 self.cmaps = []
289
289
290 size = '15%' if self.ncols == 1 else '30%'
290 size = '15%' if self.ncols == 1 else '30%'
291 pad = '4%' if self.ncols == 1 else '8%'
291 pad = '4%' if self.ncols == 1 else '8%'
292
292
293 if self.oneFigure:
293 if self.oneFigure:
294 if self.height is None:
294 if self.height is None:
295 self.height = 1.4 * self.nrows + 1
295 self.height = 1.4 * self.nrows + 1
296 fig = plt.figure(figsize=(self.width, self.height),
296 fig = plt.figure(figsize=(self.width, self.height),
297 edgecolor='k',
297 edgecolor='k',
298 facecolor='w')
298 facecolor='w')
299 self.figures.append(fig)
299 self.figures.append(fig)
300 for n in range(self.nplots):
300 for n in range(self.nplots):
301 ax = fig.add_subplot(self.nrows, self.ncols,
301 ax = fig.add_subplot(self.nrows, self.ncols,
302 n + 1, polar=self.polar)
302 n + 1, polar=self.polar)
303 ax.tick_params(labelsize=8)
303 ax.tick_params(labelsize=8)
304 ax.firsttime = True
304 ax.firsttime = True
305 ax.index = 0
305 ax.index = 0
306 ax.press = None
306 ax.press = None
307 self.axes.append(ax)
307 self.axes.append(ax)
308 if self.showprofile:
308 if self.showprofile:
309 cax = self.__add_axes(ax, size=size, pad=pad)
309 cax = self.__add_axes(ax, size=size, pad=pad)
310 cax.tick_params(labelsize=8)
310 cax.tick_params(labelsize=8)
311 self.pf_axes.append(cax)
311 self.pf_axes.append(cax)
312 else:
312 else:
313 if self.height is None:
313 if self.height is None:
314 self.height = 3
314 self.height = 3
315 for n in range(self.nplots):
315 for n in range(self.nplots):
316 fig = plt.figure(figsize=(self.width, self.height),
316 fig = plt.figure(figsize=(self.width, self.height),
317 edgecolor='k',
317 edgecolor='k',
318 facecolor='w')
318 facecolor='w')
319 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
319 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
320 ax.tick_params(labelsize=8)
320 ax.tick_params(labelsize=8)
321 ax.firsttime = True
321 ax.firsttime = True
322 ax.index = 0
322 ax.index = 0
323 ax.press = None
323 ax.press = None
324 self.figures.append(fig)
324 self.figures.append(fig)
325 self.axes.append(ax)
325 self.axes.append(ax)
326 if self.showprofile:
326 if self.showprofile:
327 cax = self.__add_axes(ax, size=size, pad=pad)
327 cax = self.__add_axes(ax, size=size, pad=pad)
328 cax.tick_params(labelsize=8)
328 cax.tick_params(labelsize=8)
329 self.pf_axes.append(cax)
329 self.pf_axes.append(cax)
330
330
331 for n in range(self.nrows):
331 for n in range(self.nrows):
332 if self.colormaps is not None:
332 if self.colormaps is not None:
333 cmap = plt.get_cmap(self.colormaps[n])
333 cmap = plt.get_cmap(self.colormaps[n])
334 else:
334 else:
335 cmap = plt.get_cmap(self.colormap)
335 cmap = plt.get_cmap(self.colormap)
336 cmap.set_bad(self.bgcolor, 1.)
336 cmap.set_bad(self.bgcolor, 1.)
337 self.cmaps.append(cmap)
337 self.cmaps.append(cmap)
338
338
339 def __add_axes(self, ax, size='30%', pad='8%'):
339 def __add_axes(self, ax, size='30%', pad='8%'):
340 '''
340 '''
341 Add new axes to the given figure
341 Add new axes to the given figure
342 '''
342 '''
343 divider = make_axes_locatable(ax)
343 divider = make_axes_locatable(ax)
344 nax = divider.new_horizontal(size=size, pad=pad)
344 nax = divider.new_horizontal(size=size, pad=pad)
345 ax.figure.add_axes(nax)
345 ax.figure.add_axes(nax)
346 return nax
346 return nax
347
347
348 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
348 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
349 '''
349 '''
350 Create a masked array for missing data
350 Create a masked array for missing data
351 '''
351 '''
352 if x_buffer.shape[0] < 2:
352 if x_buffer.shape[0] < 2:
353 return x_buffer, y_buffer, z_buffer
353 return x_buffer, y_buffer, z_buffer
354
354
355 deltas = x_buffer[1:] - x_buffer[0:-1]
355 deltas = x_buffer[1:] - x_buffer[0:-1]
356 x_median = numpy.median(deltas)
356 x_median = numpy.median(deltas)
357
357
358 index = numpy.where(deltas > 5 * x_median)
358 index = numpy.where(deltas > 5 * x_median)
359
359
360 if len(index[0]) != 0:
360 if len(index[0]) != 0:
361 z_buffer[::, index[0], ::] = self.__missing
361 z_buffer[::, index[0], ::] = self.__missing
362 z_buffer = numpy.ma.masked_inside(z_buffer,
362 z_buffer = numpy.ma.masked_inside(z_buffer,
363 0.99 * self.__missing,
363 0.99 * self.__missing,
364 1.01 * self.__missing)
364 1.01 * self.__missing)
365
365
366 return x_buffer, y_buffer, z_buffer
366 return x_buffer, y_buffer, z_buffer
367
367
368 def decimate(self):
368 def decimate(self):
369
369
370 # dx = int(len(self.x)/self.__MAXNUMX) + 1
370 # dx = int(len(self.x)/self.__MAXNUMX) + 1
371 dy = int(len(self.y) / self.decimation) + 1
371 dy = int(len(self.y) / self.decimation) + 1
372
372
373 # x = self.x[::dx]
373 # x = self.x[::dx]
374 x = self.x
374 x = self.x
375 y = self.y[::dy]
375 y = self.y[::dy]
376 z = self.z[::, ::, ::dy]
376 z = self.z[::, ::, ::dy]
377
377
378 return x, y, z
378 return x, y, z
379
379
380 def format(self):
380 def format(self):
381 '''
381 '''
382 Set min and max values, labels, ticks and titles
382 Set min and max values, labels, ticks and titles
383 '''
383 '''
384
384
385 for n, ax in enumerate(self.axes):
385 for n, ax in enumerate(self.axes):
386 if ax.firsttime:
386 if ax.firsttime:
387 if self.xaxis != 'time':
387 if self.xaxis != 'time':
388 xmin = self.xmin
388 xmin = self.xmin
389 xmax = self.xmax
389 xmax = self.xmax
390 else:
390 else:
391 xmin = self.tmin
391 xmin = self.tmin
392 xmax = self.tmin + self.xrange*60*60
392 xmax = self.tmin + self.xrange*60*60
393 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
393 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
394 ax.xaxis.set_major_locator(LinearLocator(9))
394 ax.xaxis.set_major_locator(LinearLocator(9))
395 ymin = self.ymin if self.ymin is not None else numpy.nanmin(self.y[numpy.isfinite(self.y)])
395 ymin = self.ymin if self.ymin is not None else numpy.nanmin(self.y[numpy.isfinite(self.y)])
396 ymax = self.ymax if self.ymax is not None else numpy.nanmax(self.y[numpy.isfinite(self.y)])
396 ymax = self.ymax if self.ymax is not None else numpy.nanmax(self.y[numpy.isfinite(self.y)])
397 ax.set_facecolor(self.bgcolor)
397 ax.set_facecolor(self.bgcolor)
398 if self.xscale:
398 if self.xscale:
399 ax.xaxis.set_major_formatter(FuncFormatter(
399 ax.xaxis.set_major_formatter(FuncFormatter(
400 lambda x, pos: '{0:g}'.format(x*self.xscale)))
400 lambda x, pos: '{0:g}'.format(x*self.xscale)))
401 if self.yscale:
401 if self.yscale:
402 ax.yaxis.set_major_formatter(FuncFormatter(
402 ax.yaxis.set_major_formatter(FuncFormatter(
403 lambda x, pos: '{0:g}'.format(x*self.yscale)))
403 lambda x, pos: '{0:g}'.format(x*self.yscale)))
404 if self.xlabel is not None:
404 if self.xlabel is not None:
405 ax.set_xlabel(self.xlabel)
405 ax.set_xlabel(self.xlabel)
406 if self.ylabel is not None:
406 if self.ylabel is not None:
407 ax.set_ylabel(self.ylabel)
407 ax.set_ylabel(self.ylabel)
408 if self.showprofile:
408 if self.showprofile:
409 if self.zlimits is not None:
409 if self.zlimits is not None:
410 self.zmin, self.zmax = self.zlimits[n]
410 self.zmin, self.zmax = self.zlimits[n]
411 self.pf_axes[n].set_ylim(ymin, ymax)
411 self.pf_axes[n].set_ylim(ymin, ymax)
412 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
412 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
413 self.pf_axes[n].set_xlabel('dB')
413 self.pf_axes[n].set_xlabel('dB')
414 self.pf_axes[n].grid(b=True, axis='x')
414 self.pf_axes[n].grid(b=True, axis='x')
415 [tick.set_visible(False)
415 [tick.set_visible(False)
416 for tick in self.pf_axes[n].get_yticklabels()]
416 for tick in self.pf_axes[n].get_yticklabels()]
417 if self.colorbar:
417 if self.colorbar:
418 ax.cbar = plt.colorbar(
418 ax.cbar = plt.colorbar(
419 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
419 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
420 ax.cbar.ax.tick_params(labelsize=8)
420 ax.cbar.ax.tick_params(labelsize=8)
421 ax.cbar.ax.press = None
421 ax.cbar.ax.press = None
422 if self.cb_label:
422 if self.cb_label:
423 ax.cbar.set_label(self.cb_label, size=8)
423 ax.cbar.set_label(self.cb_label, size=8)
424 elif self.cb_labels:
424 elif self.cb_labels:
425 ax.cbar.set_label(self.cb_labels[n], size=8)
425 ax.cbar.set_label(self.cb_labels[n], size=8)
426 else:
426 else:
427 ax.cbar = None
427 ax.cbar = None
428 ax.set_xlim(xmin, xmax)
428 ax.set_xlim(xmin, xmax)
429 ax.set_ylim(ymin, ymax)
429 ax.set_ylim(ymin, ymax)
430 ax.firsttime = False
430 ax.firsttime = False
431 if self.grid:
431 if self.grid:
432 ax.grid(True)
432 ax.grid(True)
433 if not self.polar:
433 if not self.polar:
434 ax.set_title('{} {} {}'.format(
434 ax.set_title('{} {} {}'.format(
435 self.titles[n],
435 self.titles[n],
436 self.getDateTime(self.data.max_time).strftime(
436 self.getDateTime(self.data.max_time).strftime(
437 '%Y-%m-%d %H:%M:%S'),
437 '%Y-%m-%d %H:%M:%S'),
438 self.time_label),
438 self.time_label),
439 size=8)
439 size=8)
440 else:
440 else:
441 ax.set_title('{}'.format(self.titles[n]), size=8)
441 ax.set_title('{}'.format(self.titles[n]), size=8)
442 ax.set_ylim(0, 90)
442 ax.set_ylim(0, 90)
443 ax.set_yticks(numpy.arange(0, 90, 20))
443 ax.set_yticks(numpy.arange(0, 90, 20))
444 ax.yaxis.labelpad = 40
444 ax.yaxis.labelpad = 40
445
445
446 if self.firsttime:
446 if self.firsttime:
447 for n, fig in enumerate(self.figures):
447 for n, fig in enumerate(self.figures):
448 fig.subplots_adjust(**self.plots_adjust)
448 fig.subplots_adjust(**self.plots_adjust)
449 self.firsttime = False
449 self.firsttime = False
450
450
451 def clear_figures(self):
451 def clear_figures(self):
452 '''
452 '''
453 Reset axes for redraw plots
453 Reset axes for redraw plots
454 '''
454 '''
455
455
456 for ax in self.axes+self.pf_axes+self.cb_axes:
456 for ax in self.axes+self.pf_axes+self.cb_axes:
457 ax.clear()
457 ax.clear()
458 ax.firsttime = True
458 ax.firsttime = True
459 if hasattr(ax, 'cbar') and ax.cbar:
459 if hasattr(ax, 'cbar') and ax.cbar:
460 ax.cbar.remove()
460 ax.cbar.remove()
461
461
462 def __plot(self):
462 def __plot(self):
463 '''
463 '''
464 Main function to plot, format and save figures
464 Main function to plot, format and save figures
465 '''
465 '''
466
466
467 self.plot()
467 self.plot()
468 self.format()
468 self.format()
469
469
470 for n, fig in enumerate(self.figures):
470 for n, fig in enumerate(self.figures):
471 if self.nrows == 0 or self.nplots == 0:
471 if self.nrows == 0 or self.nplots == 0:
472 log.warning('No data', self.name)
472 log.warning('No data', self.name)
473 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
473 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
474 fig.canvas.manager.set_window_title(self.CODE)
474 fig.canvas.manager.set_window_title(self.CODE)
475 continue
475 continue
476
476
477 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
477 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
478 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
478 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
479 fig.canvas.draw()
479 fig.canvas.draw()
480 if self.show:
480 if self.show:
481 fig.show()
481 fig.show()
482 figpause(0.01)
482 figpause(0.01)
483
483
484 if self.save:
484 if self.save:
485 self.save_figure(n)
485 self.save_figure(n)
486
486
487 if self.server:
487 if self.server:
488 self.send_to_server()
488 self.send_to_server()
489
489
490 def __update(self, dataOut, timestamp):
490 def __update(self, dataOut, timestamp):
491 '''
491 '''
492 '''
492 '''
493
493
494 metadata = {
494 metadata = {
495 'yrange': dataOut.heightList,
495 'yrange': dataOut.heightList,
496 'interval': dataOut.timeInterval,
496 'interval': dataOut.timeInterval,
497 'channels': dataOut.channelList
497 'channels': dataOut.channelList
498 }
498 }
499
499
500 data, meta = self.update(dataOut)
500 data, meta = self.update(dataOut)
501 metadata.update(meta)
501 metadata.update(meta)
502 self.data.update(data, timestamp, metadata)
502 self.data.update(data, timestamp, metadata)
503
503
504 def save_figure(self, n):
504 def save_figure(self, n):
505 '''
505 '''
506 '''
506 '''
507
507
508 if (self.data.max_time - self.save_time) <= self.save_period:
508 if (self.data.max_time - self.save_time) <= self.save_period:
509 return
509 return
510
510
511 self.save_time = self.data.max_time
511 self.save_time = self.data.max_time
512
512
513 fig = self.figures[n]
513 fig = self.figures[n]
514
514
515 if self.throttle == 0:
515 if self.throttle == 0:
516 figname = os.path.join(
516 figname = os.path.join(
517 self.save,
517 self.save,
518 self.save_code,
518 self.save_code,
519 '{}_{}.png'.format(
519 '{}_{}.png'.format(
520 self.save_code,
520 self.save_code,
521 self.getDateTime(self.data.max_time).strftime(
521 self.getDateTime(self.data.max_time).strftime(
522 '%Y%m%d_%H%M%S'
522 '%Y%m%d_%H%M%S'
523 ),
523 ),
524 )
524 )
525 )
525 )
526 log.log('Saving figure: {}'.format(figname), self.name)
526 log.log('Saving figure: {}'.format(figname), self.name)
527 if not os.path.isdir(os.path.dirname(figname)):
527 if not os.path.isdir(os.path.dirname(figname)):
528 os.makedirs(os.path.dirname(figname))
528 os.makedirs(os.path.dirname(figname))
529 fig.savefig(figname)
529 fig.savefig(figname)
530
530
531 figname = os.path.join(
531 figname = os.path.join(
532 self.save,
532 self.save,
533 #self.save_code,
533 #self.save_code,
534 '{}_{}.png'.format(
534 '{}_{}.png'.format(
535 self.save_code,
535 self.save_code,
536 self.getDateTime(self.data.min_time).strftime(
536 self.getDateTime(self.data.min_time).strftime(
537 '%Y%m%d'
537 '%Y%m%d'
538 ),
538 ),
539 )
539 )
540 )
540 )
541 log.log('Saving figure: {}'.format(figname), self.name)
541 log.log('Saving figure: {}'.format(figname), self.name)
542 if not os.path.isdir(os.path.dirname(figname)):
542 if not os.path.isdir(os.path.dirname(figname)):
543 os.makedirs(os.path.dirname(figname))
543 os.makedirs(os.path.dirname(figname))
544 fig.savefig(figname)
544 fig.savefig(figname)
545
545
546 def send_to_server(self):
546 def send_to_server(self):
547 '''
547 '''
548 '''
548 '''
549
549
550 if self.exp_code == None:
550 if self.exp_code == None:
551 log.warning('Missing `exp_code` skipping sending to server...')
551 log.warning('Missing `exp_code` skipping sending to server...')
552
552
553 last_time = self.data.max_time
553 last_time = self.data.max_time
554 interval = last_time - self.sender_time
554 interval = last_time - self.sender_time
555 if interval < self.sender_period:
555 if interval < self.sender_period:
556 return
556 return
557
557
558 self.sender_time = last_time
558 self.sender_time = last_time
559
559
560 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
560 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax', 'zlimits']
561 for attr in attrs:
561 for attr in attrs:
562 value = getattr(self, attr)
562 value = getattr(self, attr)
563 if value:
563 if value:
564 if isinstance(value, (numpy.float32, numpy.float64)):
564 if isinstance(value, (numpy.float32, numpy.float64)):
565 value = round(float(value), 2)
565 value = round(float(value), 2)
566 self.data.meta[attr] = value
566 self.data.meta[attr] = value
567 if self.colormap == 'jet':
567 if self.colormap == 'jet':
568 self.data.meta['colormap'] = 'Jet'
568 self.data.meta['colormap'] = 'Jet'
569 elif 'RdBu' in self.colormap:
569 elif 'RdBu' in self.colormap:
570 self.data.meta['colormap'] = 'RdBu'
570 self.data.meta['colormap'] = 'RdBu'
571 else:
571 else:
572 self.data.meta['colormap'] = 'Viridis'
572 self.data.meta['colormap'] = 'Viridis'
573 self.data.meta['interval'] = int(interval)
573 self.data.meta['interval'] = int(interval)
574 #print(last_time)
574 #print(last_time)
575 #print(time.time())
575 #print(time.time())
576 #exit(1)
576 #exit(1)
577 self.sender_queue.append(last_time)
577 self.sender_queue.append(last_time)
578
578
579 while True:
579 while True:
580 try:
580 try:
581 tm = self.sender_queue.popleft()
581 tm = self.sender_queue.popleft()
582 except IndexError:
582 except IndexError:
583 break
583 break
584 msg = self.data.jsonify(tm, self.save_code, self.plot_type)
584 msg = self.data.jsonify(tm, self.save_code, self.plot_type)
585 self.socket.send_string(msg)
585 self.socket.send_string(msg)
586 socks = dict(self.poll.poll(2000))
586 socks = dict(self.poll.poll(2000))
587 if socks.get(self.socket) == zmq.POLLIN:
587 if socks.get(self.socket) == zmq.POLLIN:
588 reply = self.socket.recv_string()
588 reply = self.socket.recv_string()
589 if reply == 'ok':
589 if reply == 'ok':
590 log.log("Response from server ok", self.name)
590 log.log("Response from server ok", self.name)
591 time.sleep(0.1)
591 time.sleep(0.1)
592 continue
592 continue
593 else:
593 else:
594 log.warning(
594 log.warning(
595 "Malformed reply from server: {}".format(reply), self.name)
595 "Malformed reply from server: {}".format(reply), self.name)
596 else:
596 else:
597 log.warning(
597 log.warning(
598 "No response from server, retrying...", self.name)
598 "No response from server, retrying...", self.name)
599 self.sender_queue.appendleft(tm)
599 self.sender_queue.appendleft(tm)
600 self.socket.setsockopt(zmq.LINGER, 0)
600 self.socket.setsockopt(zmq.LINGER, 0)
601 self.socket.close()
601 self.socket.close()
602 self.poll.unregister(self.socket)
602 self.poll.unregister(self.socket)
603 self.socket = self.context.socket(zmq.REQ)
603 self.socket = self.context.socket(zmq.REQ)
604 self.socket.connect(self.server)
604 self.socket.connect(self.server)
605 self.poll.register(self.socket, zmq.POLLIN)
605 self.poll.register(self.socket, zmq.POLLIN)
606 break
606 break
607
607
608 def setup(self):
608 def setup(self):
609 '''
609 '''
610 This method should be implemented in the child class, the following
610 This method should be implemented in the child class, the following
611 attributes should be set:
611 attributes should be set:
612
612
613 self.nrows: number of rows
613 self.nrows: number of rows
614 self.ncols: number of cols
614 self.ncols: number of cols
615 self.nplots: number of plots (channels or pairs)
615 self.nplots: number of plots (channels or pairs)
616 self.ylabel: label for Y axes
616 self.ylabel: label for Y axes
617 self.titles: list of axes title
617 self.titles: list of axes title
618
618
619 '''
619 '''
620 raise NotImplementedError
620 raise NotImplementedError
621
621
622 def plot(self):
622 def plot(self):
623 '''
623 '''
624 Must be defined in the child class, the actual plotting method
624 Must be defined in the child class, the actual plotting method
625 '''
625 '''
626 raise NotImplementedError
626 raise NotImplementedError
627
627
628 def update(self, dataOut):
628 def update(self, dataOut):
629 '''
629 '''
630 Must be defined in the child class, update self.data with new data
630 Must be defined in the child class, update self.data with new data
631 '''
631 '''
632
632
633 data = {
633 data = {
634 self.CODE: getattr(dataOut, 'data_{}'.format(self.CODE))
634 self.CODE: getattr(dataOut, 'data_{}'.format(self.CODE))
635 }
635 }
636 meta = {}
636 meta = {}
637
637
638 return data, meta
638 return data, meta
639
639
640 def run(self, dataOut, **kwargs):
640 def run(self, dataOut, **kwargs):
641 '''
641 '''
642 Main plotting routine
642 Main plotting routine
643 '''
643 '''
644
644
645 if self.isConfig is False:
645 if self.isConfig is False:
646 self.__setup(**kwargs)
646 self.__setup(**kwargs)
647
647
648 if self.localtime:
648 if self.localtime:
649 self.getDateTime = datetime.datetime.fromtimestamp
649 self.getDateTime = datetime.datetime.fromtimestamp
650 else:
650 else:
651 self.getDateTime = datetime.datetime.utcfromtimestamp
651 self.getDateTime = datetime.datetime.utcfromtimestamp
652
652
653 self.data.setup()
653 self.data.setup()
654 self.isConfig = True
654 self.isConfig = True
655 if self.server:
655 if self.server:
656 self.context = zmq.Context()
656 self.context = zmq.Context()
657 self.socket = self.context.socket(zmq.REQ)
657 self.socket = self.context.socket(zmq.REQ)
658 self.socket.connect(self.server)
658 self.socket.connect(self.server)
659 self.poll = zmq.Poller()
659 self.poll = zmq.Poller()
660 self.poll.register(self.socket, zmq.POLLIN)
660 self.poll.register(self.socket, zmq.POLLIN)
661
661
662 tm = getattr(dataOut, self.attr_time)
662 tm = getattr(dataOut, self.attr_time)
663
664 if self.data and 'time' in self.xaxis and (tm - self.tmin) >= self.xrange*60*60:
663 if self.data and 'time' in self.xaxis and (tm - self.tmin) >= self.xrange*60*60:
665 self.save_time = tm
664 self.save_time = tm
666 self.__plot()
665 self.__plot()
667 self.tmin += self.xrange*60*60
666 #self.tmin += self.xrange*60*60 #Modified by R. Flores
667 self.tmin += 24*60*60 #Modified by R. Flores
668
668 self.data.setup()
669 self.data.setup()
669 self.clear_figures()
670 self.clear_figures()
670
671
671 self.__update(dataOut, tm)
672 self.__update(dataOut, tm)
672
673
673 if self.isPlotConfig is False:
674 if self.isPlotConfig is False:
674 self.__setup_plot()
675 self.__setup_plot()
675 self.isPlotConfig = True
676 self.isPlotConfig = True
676 if self.xaxis == 'time':
677 if self.xaxis == 'time':
677 dt = self.getDateTime(tm)
678 dt = self.getDateTime(tm)
679
678 if self.xmin is None:
680 if self.xmin is None:
679 self.tmin = tm
681 self.tmin = tm
680 self.xmin = dt.hour
682 self.xmin = dt.hour
681 minutes = (self.xmin-int(self.xmin)) * 60
683 minutes = (self.xmin-int(self.xmin)) * 60
682 seconds = (minutes - int(minutes)) * 60
684 seconds = (minutes - int(minutes)) * 60
683 self.tmin = (dt.replace(hour=int(self.xmin), minute=int(minutes), second=int(seconds)) -
685 self.tmin = (dt.replace(hour=int(self.xmin), minute=int(minutes), second=int(seconds)) -
684 datetime.datetime(1970, 1, 1)).total_seconds()
686 datetime.datetime(1970, 1, 1)).total_seconds()
685 if self.localtime:
687 if self.localtime:
686 self.tmin += time.timezone
688 self.tmin += time.timezone
687
689
688 if self.xmin is not None and self.xmax is not None:
690 if self.xmin is not None and self.xmax is not None:
689 self.xrange = self.xmax - self.xmin
691 self.xrange = self.xmax - self.xmin
690
692
691 if self.throttle == 0:
693 if self.throttle == 0:
692 self.__plot()
694 self.__plot()
693 else:
695 else:
694 self.__throttle_plot(self.__plot)#, coerce=coerce)
696 self.__throttle_plot(self.__plot)#, coerce=coerce)
695
697
696 def close(self):
698 def close(self):
697
699
698 if self.data and not self.data.flagNoData:
700 if self.data and not self.data.flagNoData:
699 self.save_time = 0
701 self.save_time = 0
700 self.__plot()
702 self.__plot()
701 if self.data and not self.data.flagNoData and self.pause:
703 if self.data and not self.data.flagNoData and self.pause:
702 figpause(10)
704 figpause(10)
@@ -1,1337 +1,1343
1 # Copyright (c) 2012-2021 Jicamarca Radio Observatory
1 # Copyright (c) 2012-2021 Jicamarca Radio Observatory
2 # All rights reserved.
2 # All rights reserved.
3 #
3 #
4 # Distributed under the terms of the BSD 3-clause license.
4 # Distributed under the terms of the BSD 3-clause license.
5 """Classes to plot Spectra data
5 """Classes to plot Spectra data
6
6
7 """
7 """
8
8
9 import os
9 import os
10 import numpy
10 import numpy
11 import collections.abc
11 #import collections.abc
12
12
13 from schainpy.model.graphics.jroplot_base import Plot, plt, log
13 from schainpy.model.graphics.jroplot_base import Plot, plt, log
14
14
15 class SpectraPlot(Plot):
15 class SpectraPlot(Plot):
16 '''
16 '''
17 Plot for Spectra data
17 Plot for Spectra data
18 '''
18 '''
19
19
20 CODE = 'spc'
20 CODE = 'spc'
21 colormap = 'jet'
21 colormap = 'jet'
22 plot_type = 'pcolor'
22 plot_type = 'pcolor'
23 buffering = False
23 buffering = False
24
24
25 def setup(self):
25 def setup(self):
26
26
27 self.nplots = len(self.data.channels)
27 self.nplots = len(self.data.channels)
28 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
28 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
29 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
29 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
30 self.height = 2.6 * self.nrows
30 self.height = 2.6 * self.nrows
31 self.cb_label = 'dB'
31 self.cb_label = 'dB'
32 if self.showprofile:
32 if self.showprofile:
33 self.width = 4 * self.ncols
33 self.width = 4 * self.ncols
34 else:
34 else:
35 self.width = 3.5 * self.ncols
35 self.width = 3.5 * self.ncols
36 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
36 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
37 self.ylabel = 'Range [km]'
37 self.ylabel = 'Range [km]'
38
38
39 def update(self, dataOut):
39 def update(self, dataOut):
40
40
41 data = {}
41 data = {}
42 meta = {}
42 meta = {}
43
43
44 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
44 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
45 #print("Spc: ",spc[0])
45 #print("Spc: ",spc[0])
46 #exit(1)
46 #exit(1)
47 data['spc'] = spc
47 data['spc'] = spc
48 data['rti'] = dataOut.getPower()
48 data['rti'] = dataOut.getPower()
49 #print(data['rti'][0])
49 #print(data['rti'][0])
50 #exit(1)
50 #exit(1)
51 #print("NormFactor: ",dataOut.normFactor)
51 #print("NormFactor: ",dataOut.normFactor)
52 #data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
52 #data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
53 if hasattr(dataOut, 'LagPlot'): #Double Pulse
53 if hasattr(dataOut, 'LagPlot'): #Double Pulse
54 max_hei_id = dataOut.nHeights - 2*dataOut.LagPlot
54 max_hei_id = dataOut.nHeights - 2*dataOut.LagPlot
55 #data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=46,ymax_index=max_hei_id)/dataOut.normFactor)
55 #data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=46,ymax_index=max_hei_id)/dataOut.normFactor)
56 #data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=40,ymax_index=max_hei_id)/dataOut.normFactor)
56 #data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=40,ymax_index=max_hei_id)/dataOut.normFactor)
57 data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=53,ymax_index=max_hei_id)/dataOut.normFactor)
57 data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=53,ymax_index=max_hei_id)/dataOut.normFactor)
58 data['noise'][0] = 10*numpy.log10(dataOut.getNoise(ymin_index=53)[0]/dataOut.normFactor)
58 data['noise'][0] = 10*numpy.log10(dataOut.getNoise(ymin_index=53)[0]/dataOut.normFactor)
59 #data['noise'][1] = 22.035507
59 #data['noise'][1] = 22.035507
60 else:
60 else:
61 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
61 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
62 #data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=26,ymax_index=44)/dataOut.normFactor)
62 #data['noise'] = 10*numpy.log10(dataOut.getNoise(ymin_index=26,ymax_index=44)/dataOut.normFactor)
63 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
63 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
64
64
65 if self.CODE == 'spc_moments':
65 if self.CODE == 'spc_moments':
66 data['moments'] = dataOut.moments
66 data['moments'] = dataOut.moments
67 if self.CODE == 'gaussian_fit':
67 if self.CODE == 'gaussian_fit':
68 data['gaussfit'] = dataOut.DGauFitParams
68 data['gaussfit'] = dataOut.DGauFitParams
69
69
70 return data, meta
70 return data, meta
71
71
72 def plot(self):
72 def plot(self):
73
73
74 if self.xaxis == "frequency":
74 if self.xaxis == "frequency":
75 x = self.data.xrange[0]
75 x = self.data.xrange[0]
76 self.xlabel = "Frequency (kHz)"
76 self.xlabel = "Frequency (kHz)"
77 elif self.xaxis == "time":
77 elif self.xaxis == "time":
78 x = self.data.xrange[1]
78 x = self.data.xrange[1]
79 self.xlabel = "Time (ms)"
79 self.xlabel = "Time (ms)"
80 else:
80 else:
81 x = self.data.xrange[2]
81 x = self.data.xrange[2]
82 self.xlabel = "Velocity (m/s)"
82 self.xlabel = "Velocity (m/s)"
83
83
84 if (self.CODE == 'spc_moments') | (self.CODE == 'gaussian_fit'):
84 if (self.CODE == 'spc_moments') | (self.CODE == 'gaussian_fit'):
85 x = self.data.xrange[2]
85 x = self.data.xrange[2]
86 self.xlabel = "Velocity (m/s)"
86 self.xlabel = "Velocity (m/s)"
87
87
88 self.titles = []
88 self.titles = []
89
89
90 y = self.data.yrange
90 y = self.data.yrange
91 self.y = y
91 self.y = y
92
92
93 data = self.data[-1]
93 data = self.data[-1]
94 z = data['spc']
94 z = data['spc']
95
95
96 self.CODE2 = 'spc_oblique'
96 self.CODE2 = 'spc_oblique'
97
97
98 for n, ax in enumerate(self.axes):
98 for n, ax in enumerate(self.axes):
99 noise = data['noise'][n]
99 noise = data['noise'][n]
100 if self.CODE == 'spc_moments':
100 if self.CODE == 'spc_moments':
101 mean = data['moments'][n, 1]
101 mean = data['moments'][n, 1]
102 if self.CODE == 'gaussian_fit':
102 if self.CODE == 'gaussian_fit':
103 gau0 = data['gaussfit'][n][2,:,0]
103 gau0 = data['gaussfit'][n][2,:,0]
104 gau1 = data['gaussfit'][n][2,:,1]
104 gau1 = data['gaussfit'][n][2,:,1]
105 if ax.firsttime:
105 if ax.firsttime:
106 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
106 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
107 self.xmin = self.xmin if self.xmin else numpy.nanmin(x)#-self.xmax
107 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)
108 #self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
109 #self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
109 #self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
110 if self.zlimits is not None:
110 if self.zlimits is not None:
111 self.zmin, self.zmax = self.zlimits[n]
111 self.zmin, self.zmax = self.zlimits[n]
112
112
113 ax.plt = ax.pcolormesh(x, y, z[n].T,
113 ax.plt = ax.pcolormesh(x, y, z[n].T,
114 vmin=self.zmin,
114 vmin=self.zmin,
115 vmax=self.zmax,
115 vmax=self.zmax,
116 cmap=plt.get_cmap(self.colormap),
116 cmap=plt.get_cmap(self.colormap),
117 )
117 )
118
118
119 if self.showprofile:
119 if self.showprofile:
120 ax.plt_profile = self.pf_axes[n].plot(
120 ax.plt_profile = self.pf_axes[n].plot(
121 data['rti'][n], y)[0]
121 data['rti'][n], y)[0]
122 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
122 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
123 color="k", linestyle="dashed", lw=1)[0]
123 color="k", linestyle="dashed", lw=1)[0]
124 if self.CODE == 'spc_moments':
124 if self.CODE == 'spc_moments':
125 ax.plt_mean = ax.plot(mean, y, color='k', lw=1)[0]
125 ax.plt_mean = ax.plot(mean, y, color='k', lw=1)[0]
126 if self.CODE == 'gaussian_fit':
126 if self.CODE == 'gaussian_fit':
127 ax.plt_gau0 = ax.plot(gau0, y, color='r', lw=1)[0]
127 ax.plt_gau0 = ax.plot(gau0, y, color='r', lw=1)[0]
128 ax.plt_gau1 = ax.plot(gau1, y, color='y', lw=1)[0]
128 ax.plt_gau1 = ax.plot(gau1, y, color='y', lw=1)[0]
129 else:
129 else:
130 if self.zlimits is not None:
130 if self.zlimits is not None:
131 self.zmin, self.zmax = self.zlimits[n]
131 self.zmin, self.zmax = self.zlimits[n]
132 ax.plt.set_array(z[n].T.ravel())
132 ax.plt.set_array(z[n].T.ravel())
133 if self.showprofile:
133 if self.showprofile:
134 ax.plt_profile.set_data(data['rti'][n], y)
134 ax.plt_profile.set_data(data['rti'][n], y)
135 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
135 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
136 if self.CODE == 'spc_moments':
136 if self.CODE == 'spc_moments':
137 ax.plt_mean.set_data(mean, y)
137 ax.plt_mean.set_data(mean, y)
138 if self.CODE == 'gaussian_fit':
138 if self.CODE == 'gaussian_fit':
139 ax.plt_gau0.set_data(gau0, y)
139 ax.plt_gau0.set_data(gau0, y)
140 ax.plt_gau1.set_data(gau1, y)
140 ax.plt_gau1.set_data(gau1, y)
141 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
141 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
142
142
143 class SpectraObliquePlot(Plot):
143 class SpectraObliquePlot(Plot):
144 '''
144 '''
145 Plot for Spectra data
145 Plot for Spectra data
146 '''
146 '''
147
147
148 CODE = 'spc_oblique'
148 CODE = 'spc_oblique'
149 colormap = 'jet'
149 colormap = 'jet'
150 plot_type = 'pcolor'
150 plot_type = 'pcolor'
151
151
152 def setup(self):
152 def setup(self):
153 self.xaxis = "oblique"
153 self.xaxis = "oblique"
154 self.nplots = len(self.data.channels)
154 self.nplots = len(self.data.channels)
155 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
155 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
156 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
156 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
157 self.height = 2.6 * self.nrows
157 self.height = 2.6 * self.nrows
158 self.cb_label = 'dB'
158 self.cb_label = 'dB'
159 if self.showprofile:
159 if self.showprofile:
160 self.width = 4 * self.ncols
160 self.width = 4 * self.ncols
161 else:
161 else:
162 self.width = 3.5 * self.ncols
162 self.width = 3.5 * self.ncols
163 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
163 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
164 self.ylabel = 'Range [km]'
164 self.ylabel = 'Range [km]'
165
165
166 def update(self, dataOut):
166 def update(self, dataOut):
167
167
168 data = {}
168 data = {}
169 meta = {}
169 meta = {}
170 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
170 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
171 data['spc'] = spc
171 data['spc'] = spc
172 data['rti'] = dataOut.getPower()
172 data['rti'] = dataOut.getPower()
173 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
173 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
174 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
174 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
175 '''
175 '''
176 data['shift1'] = dataOut.Oblique_params[0,-2,:]
176 data['shift1'] = dataOut.Oblique_params[0,-2,:]
177 data['shift2'] = dataOut.Oblique_params[0,-1,:]
177 data['shift2'] = dataOut.Oblique_params[0,-1,:]
178 data['shift1_error'] = dataOut.Oblique_param_errors[0,-2,:]
178 data['shift1_error'] = dataOut.Oblique_param_errors[0,-2,:]
179 data['shift2_error'] = dataOut.Oblique_param_errors[0,-1,:]
179 data['shift2_error'] = dataOut.Oblique_param_errors[0,-1,:]
180 '''
180 '''
181 '''
181 '''
182 data['shift1'] = dataOut.Oblique_params[0,1,:]
182 data['shift1'] = dataOut.Oblique_params[0,1,:]
183 data['shift2'] = dataOut.Oblique_params[0,4,:]
183 data['shift2'] = dataOut.Oblique_params[0,4,:]
184 data['shift1_error'] = dataOut.Oblique_param_errors[0,1,:]
184 data['shift1_error'] = dataOut.Oblique_param_errors[0,1,:]
185 data['shift2_error'] = dataOut.Oblique_param_errors[0,4,:]
185 data['shift2_error'] = dataOut.Oblique_param_errors[0,4,:]
186 '''
186 '''
187 data['shift1'] = dataOut.Dop_EEJ_T1[0]
187 data['shift1'] = dataOut.Dop_EEJ_T1[0]
188 data['shift2'] = dataOut.Dop_EEJ_T2[0]
188 data['shift2'] = dataOut.Dop_EEJ_T2[0]
189 data['max_val_2'] = dataOut.Oblique_params[0,-1,:]
189 data['shift1_error'] = dataOut.Err_Dop_EEJ_T1[0]
190 data['shift1_error'] = dataOut.Err_Dop_EEJ_T1[0]
190 data['shift2_error'] = dataOut.Err_Dop_EEJ_T2[0]
191 data['shift2_error'] = dataOut.Err_Dop_EEJ_T2[0]
191
192
192 return data, meta
193 return data, meta
193
194
194 def plot(self):
195 def plot(self):
195
196
196 if self.xaxis == "frequency":
197 if self.xaxis == "frequency":
197 x = self.data.xrange[0]
198 x = self.data.xrange[0]
198 self.xlabel = "Frequency (kHz)"
199 self.xlabel = "Frequency (kHz)"
199 elif self.xaxis == "time":
200 elif self.xaxis == "time":
200 x = self.data.xrange[1]
201 x = self.data.xrange[1]
201 self.xlabel = "Time (ms)"
202 self.xlabel = "Time (ms)"
202 else:
203 else:
203 x = self.data.xrange[2]
204 x = self.data.xrange[2]
204 self.xlabel = "Velocity (m/s)"
205 self.xlabel = "Velocity (m/s)"
205
206
206 self.titles = []
207 self.titles = []
207
208
208 y = self.data.yrange
209 y = self.data.yrange
209 self.y = y
210 self.y = y
210
211
211 data = self.data[-1]
212 data = self.data[-1]
212 z = data['spc']
213 z = data['spc']
213
214
214 for n, ax in enumerate(self.axes):
215 for n, ax in enumerate(self.axes):
215 noise = self.data['noise'][n][-1]
216 noise = self.data['noise'][n][-1]
216 shift1 = data['shift1']
217 shift1 = data['shift1']
217 #print(shift1)
218 #print(shift1)
218 shift2 = data['shift2']
219 shift2 = data['shift2']
220 max_val_2 = data['max_val_2']
219 err1 = data['shift1_error']
221 err1 = data['shift1_error']
220 err2 = data['shift2_error']
222 err2 = data['shift2_error']
221 if ax.firsttime:
223 if ax.firsttime:
222
224
223 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
225 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
224 self.xmin = self.xmin if self.xmin else -self.xmax
226 self.xmin = self.xmin if self.xmin else -self.xmax
225 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
227 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
226 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
228 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
227 ax.plt = ax.pcolormesh(x, y, z[n].T,
229 ax.plt = ax.pcolormesh(x, y, z[n].T,
228 vmin=self.zmin,
230 vmin=self.zmin,
229 vmax=self.zmax,
231 vmax=self.zmax,
230 cmap=plt.get_cmap(self.colormap)
232 cmap=plt.get_cmap(self.colormap)
231 )
233 )
232
234
233 if self.showprofile:
235 if self.showprofile:
234 ax.plt_profile = self.pf_axes[n].plot(
236 ax.plt_profile = self.pf_axes[n].plot(
235 self.data['rti'][n][-1], y)[0]
237 self.data['rti'][n][-1], y)[0]
236 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
238 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
237 color="k", linestyle="dashed", lw=1)[0]
239 color="k", linestyle="dashed", lw=1)[0]
238
240
239 self.ploterr1 = ax.errorbar(shift1, y, xerr=err1, fmt='k^', elinewidth=2.2, marker='o', linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
241 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)
240 self.ploterr2 = ax.errorbar(shift2, y, xerr=err2, fmt='m^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
242 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)
243 self.ploterr3 = ax.errorbar(max_val_2, y, xerr=0, fmt='g^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
244
241 #print("plotter1: ", self.ploterr1,shift1)
245 #print("plotter1: ", self.ploterr1,shift1)
242
246
243 else:
247 else:
244 #print("else plotter1: ", self.ploterr1,shift1)
248 #print("else plotter1: ", self.ploterr1,shift1)
245 self.ploterr1.remove()
249 self.ploterr1.remove()
246 self.ploterr2.remove()
250 self.ploterr2.remove()
251 self.ploterr3.remove()
247 ax.plt.set_array(z[n].T.ravel())
252 ax.plt.set_array(z[n].T.ravel())
248 if self.showprofile:
253 if self.showprofile:
249 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
254 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
250 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
255 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
251 self.ploterr1 = ax.errorbar(shift1, y, xerr=err1, fmt='k^', elinewidth=2.2, marker='o', linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
256 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)
252 self.ploterr2 = ax.errorbar(shift2, y, xerr=err2, fmt='m^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
257 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)
258 self.ploterr3 = ax.errorbar(max_val_2, y, xerr=0, fmt='g^',elinewidth=2.2,marker='o',linestyle='None',markersize=2.5,capsize=0.3,markeredgewidth=0.2)
253
259
254 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
260 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
255
261
256
262
257 class CrossSpectraPlot(Plot):
263 class CrossSpectraPlot(Plot):
258
264
259 CODE = 'cspc'
265 CODE = 'cspc'
260 colormap = 'jet'
266 colormap = 'jet'
261 plot_type = 'pcolor'
267 plot_type = 'pcolor'
262 zmin_coh = None
268 zmin_coh = None
263 zmax_coh = None
269 zmax_coh = None
264 zmin_phase = None
270 zmin_phase = None
265 zmax_phase = None
271 zmax_phase = None
266
272
267 def setup(self):
273 def setup(self):
268
274
269 self.ncols = 4
275 self.ncols = 4
270 self.nplots = len(self.data.pairs) * 2
276 self.nplots = len(self.data.pairs) * 2
271 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
277 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
272 self.width = 3.1 * self.ncols
278 self.width = 3.1 * self.ncols
273 self.height = 5 * self.nrows
279 self.height = 5 * self.nrows
274 self.ylabel = 'Range [km]'
280 self.ylabel = 'Range [km]'
275 self.showprofile = False
281 self.showprofile = False
276 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
282 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
277
283
278 def update(self, dataOut):
284 def update(self, dataOut):
279
285
280 data = {}
286 data = {}
281 meta = {}
287 meta = {}
282
288
283 spc = dataOut.data_spc
289 spc = dataOut.data_spc
284 cspc = dataOut.data_cspc
290 cspc = dataOut.data_cspc
285 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
291 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
286 meta['pairs'] = dataOut.pairsList
292 meta['pairs'] = dataOut.pairsList
287
293
288 tmp = []
294 tmp = []
289
295
290 for n, pair in enumerate(meta['pairs']):
296 for n, pair in enumerate(meta['pairs']):
291 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
297 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
292 coh = numpy.abs(out)
298 coh = numpy.abs(out)
293 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
299 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
294 tmp.append(coh)
300 tmp.append(coh)
295 tmp.append(phase)
301 tmp.append(phase)
296
302
297 data['cspc'] = numpy.array(tmp)
303 data['cspc'] = numpy.array(tmp)
298
304
299 return data, meta
305 return data, meta
300
306
301 def plot(self):
307 def plot(self):
302
308
303 if self.xaxis == "frequency":
309 if self.xaxis == "frequency":
304 x = self.data.xrange[0]
310 x = self.data.xrange[0]
305 self.xlabel = "Frequency (kHz)"
311 self.xlabel = "Frequency (kHz)"
306 elif self.xaxis == "time":
312 elif self.xaxis == "time":
307 x = self.data.xrange[1]
313 x = self.data.xrange[1]
308 self.xlabel = "Time (ms)"
314 self.xlabel = "Time (ms)"
309 else:
315 else:
310 x = self.data.xrange[2]
316 x = self.data.xrange[2]
311 self.xlabel = "Velocity (m/s)"
317 self.xlabel = "Velocity (m/s)"
312
318
313 self.titles = []
319 self.titles = []
314
320
315 y = self.data.yrange
321 y = self.data.yrange
316 self.y = y
322 self.y = y
317
323
318 data = self.data[-1]
324 data = self.data[-1]
319 cspc = data['cspc']
325 cspc = data['cspc']
320
326
321 for n in range(len(self.data.pairs)):
327 for n in range(len(self.data.pairs)):
322 pair = self.data.pairs[n]
328 pair = self.data.pairs[n]
323 coh = cspc[n*2]
329 coh = cspc[n*2]
324 phase = cspc[n*2+1]
330 phase = cspc[n*2+1]
325 ax = self.axes[2 * n]
331 ax = self.axes[2 * n]
326 if ax.firsttime:
332 if ax.firsttime:
327 ax.plt = ax.pcolormesh(x, y, coh.T,
333 ax.plt = ax.pcolormesh(x, y, coh.T,
328 vmin=0,
334 vmin=0,
329 vmax=1,
335 vmax=1,
330 cmap=plt.get_cmap(self.colormap_coh)
336 cmap=plt.get_cmap(self.colormap_coh)
331 )
337 )
332 else:
338 else:
333 ax.plt.set_array(coh.T.ravel())
339 ax.plt.set_array(coh.T.ravel())
334 self.titles.append(
340 self.titles.append(
335 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
341 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
336
342
337 ax = self.axes[2 * n + 1]
343 ax = self.axes[2 * n + 1]
338 if ax.firsttime:
344 if ax.firsttime:
339 ax.plt = ax.pcolormesh(x, y, phase.T,
345 ax.plt = ax.pcolormesh(x, y, phase.T,
340 vmin=-180,
346 vmin=-180,
341 vmax=180,
347 vmax=180,
342 cmap=plt.get_cmap(self.colormap_phase)
348 cmap=plt.get_cmap(self.colormap_phase)
343 )
349 )
344 else:
350 else:
345 ax.plt.set_array(phase.T.ravel())
351 ax.plt.set_array(phase.T.ravel())
346 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
352 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
347
353
348
354
349 class CrossSpectra4Plot(Plot):
355 class CrossSpectra4Plot(Plot):
350
356
351 CODE = 'cspc'
357 CODE = 'cspc'
352 colormap = 'jet'
358 colormap = 'jet'
353 plot_type = 'pcolor'
359 plot_type = 'pcolor'
354 zmin_coh = None
360 zmin_coh = None
355 zmax_coh = None
361 zmax_coh = None
356 zmin_phase = None
362 zmin_phase = None
357 zmax_phase = None
363 zmax_phase = None
358
364
359 def setup(self):
365 def setup(self):
360
366
361 self.ncols = 4
367 self.ncols = 4
362 self.nrows = len(self.data.pairs)
368 self.nrows = len(self.data.pairs)
363 self.nplots = self.nrows * 4
369 self.nplots = self.nrows * 4
364 self.width = 3.1 * self.ncols
370 self.width = 3.1 * self.ncols
365 self.height = 5 * self.nrows
371 self.height = 5 * self.nrows
366 self.ylabel = 'Range [km]'
372 self.ylabel = 'Range [km]'
367 self.showprofile = False
373 self.showprofile = False
368 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
374 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
369
375
370 def plot(self):
376 def plot(self):
371
377
372 if self.xaxis == "frequency":
378 if self.xaxis == "frequency":
373 x = self.data.xrange[0]
379 x = self.data.xrange[0]
374 self.xlabel = "Frequency (kHz)"
380 self.xlabel = "Frequency (kHz)"
375 elif self.xaxis == "time":
381 elif self.xaxis == "time":
376 x = self.data.xrange[1]
382 x = self.data.xrange[1]
377 self.xlabel = "Time (ms)"
383 self.xlabel = "Time (ms)"
378 else:
384 else:
379 x = self.data.xrange[2]
385 x = self.data.xrange[2]
380 self.xlabel = "Velocity (m/s)"
386 self.xlabel = "Velocity (m/s)"
381
387
382 self.titles = []
388 self.titles = []
383
389
384
390
385 y = self.data.heights
391 y = self.data.heights
386 self.y = y
392 self.y = y
387 nspc = self.data['spc']
393 nspc = self.data['spc']
388 #print(numpy.shape(self.data['spc']))
394 #print(numpy.shape(self.data['spc']))
389 spc = self.data['cspc'][0]
395 spc = self.data['cspc'][0]
390 #print(numpy.shape(nspc))
396 #print(numpy.shape(nspc))
391 #exit()
397 #exit()
392 #nspc[1,:,:] = numpy.flip(nspc[1,:,:],axis=0)
398 #nspc[1,:,:] = numpy.flip(nspc[1,:,:],axis=0)
393 #print(numpy.shape(spc))
399 #print(numpy.shape(spc))
394 #exit()
400 #exit()
395 cspc = self.data['cspc'][1]
401 cspc = self.data['cspc'][1]
396
402
397 #xflip=numpy.flip(x)
403 #xflip=numpy.flip(x)
398 #print(numpy.shape(cspc))
404 #print(numpy.shape(cspc))
399 #exit()
405 #exit()
400
406
401 for n in range(self.nrows):
407 for n in range(self.nrows):
402 noise = self.data['noise'][:,-1]
408 noise = self.data['noise'][:,-1]
403 pair = self.data.pairs[n]
409 pair = self.data.pairs[n]
404 #print(pair)
410 #print(pair)
405 #exit()
411 #exit()
406 ax = self.axes[4 * n]
412 ax = self.axes[4 * n]
407 if ax.firsttime:
413 if ax.firsttime:
408 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
414 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
409 self.xmin = self.xmin if self.xmin else -self.xmax
415 self.xmin = self.xmin if self.xmin else -self.xmax
410 self.zmin = self.zmin if self.zmin else numpy.nanmin(nspc)
416 self.zmin = self.zmin if self.zmin else numpy.nanmin(nspc)
411 self.zmax = self.zmax if self.zmax else numpy.nanmax(nspc)
417 self.zmax = self.zmax if self.zmax else numpy.nanmax(nspc)
412 ax.plt = ax.pcolormesh(x , y , nspc[pair[0]].T,
418 ax.plt = ax.pcolormesh(x , y , nspc[pair[0]].T,
413 vmin=self.zmin,
419 vmin=self.zmin,
414 vmax=self.zmax,
420 vmax=self.zmax,
415 cmap=plt.get_cmap(self.colormap)
421 cmap=plt.get_cmap(self.colormap)
416 )
422 )
417 else:
423 else:
418 #print(numpy.shape(nspc[pair[0]].T))
424 #print(numpy.shape(nspc[pair[0]].T))
419 #exit()
425 #exit()
420 ax.plt.set_array(nspc[pair[0]].T.ravel())
426 ax.plt.set_array(nspc[pair[0]].T.ravel())
421 self.titles.append('CH {}: {:3.2f}dB'.format(pair[0], noise[pair[0]]))
427 self.titles.append('CH {}: {:3.2f}dB'.format(pair[0], noise[pair[0]]))
422
428
423 ax = self.axes[4 * n + 1]
429 ax = self.axes[4 * n + 1]
424
430
425 if ax.firsttime:
431 if ax.firsttime:
426 ax.plt = ax.pcolormesh(x , y, numpy.flip(nspc[pair[1]],axis=0).T,
432 ax.plt = ax.pcolormesh(x , y, numpy.flip(nspc[pair[1]],axis=0).T,
427 vmin=self.zmin,
433 vmin=self.zmin,
428 vmax=self.zmax,
434 vmax=self.zmax,
429 cmap=plt.get_cmap(self.colormap)
435 cmap=plt.get_cmap(self.colormap)
430 )
436 )
431 else:
437 else:
432
438
433 ax.plt.set_array(numpy.flip(nspc[pair[1]],axis=0).T.ravel())
439 ax.plt.set_array(numpy.flip(nspc[pair[1]],axis=0).T.ravel())
434 self.titles.append('CH {}: {:3.2f}dB'.format(pair[1], noise[pair[1]]))
440 self.titles.append('CH {}: {:3.2f}dB'.format(pair[1], noise[pair[1]]))
435
441
436 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
442 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
437 coh = numpy.abs(out)
443 coh = numpy.abs(out)
438 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
444 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
439
445
440 ax = self.axes[4 * n + 2]
446 ax = self.axes[4 * n + 2]
441 if ax.firsttime:
447 if ax.firsttime:
442 ax.plt = ax.pcolormesh(x, y, numpy.flip(coh,axis=0).T,
448 ax.plt = ax.pcolormesh(x, y, numpy.flip(coh,axis=0).T,
443 vmin=0,
449 vmin=0,
444 vmax=1,
450 vmax=1,
445 cmap=plt.get_cmap(self.colormap_coh)
451 cmap=plt.get_cmap(self.colormap_coh)
446 )
452 )
447 else:
453 else:
448 ax.plt.set_array(numpy.flip(coh,axis=0).T.ravel())
454 ax.plt.set_array(numpy.flip(coh,axis=0).T.ravel())
449 self.titles.append(
455 self.titles.append(
450 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
456 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
451
457
452 ax = self.axes[4 * n + 3]
458 ax = self.axes[4 * n + 3]
453 if ax.firsttime:
459 if ax.firsttime:
454 ax.plt = ax.pcolormesh(x, y, numpy.flip(phase,axis=0).T,
460 ax.plt = ax.pcolormesh(x, y, numpy.flip(phase,axis=0).T,
455 vmin=-180,
461 vmin=-180,
456 vmax=180,
462 vmax=180,
457 cmap=plt.get_cmap(self.colormap_phase)
463 cmap=plt.get_cmap(self.colormap_phase)
458 )
464 )
459 else:
465 else:
460 ax.plt.set_array(numpy.flip(phase,axis=0).T.ravel())
466 ax.plt.set_array(numpy.flip(phase,axis=0).T.ravel())
461 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
467 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
462
468
463
469
464 class CrossSpectra2Plot(Plot):
470 class CrossSpectra2Plot(Plot):
465
471
466 CODE = 'cspc'
472 CODE = 'cspc'
467 colormap = 'jet'
473 colormap = 'jet'
468 plot_type = 'pcolor'
474 plot_type = 'pcolor'
469 zmin_coh = None
475 zmin_coh = None
470 zmax_coh = None
476 zmax_coh = None
471 zmin_phase = None
477 zmin_phase = None
472 zmax_phase = None
478 zmax_phase = None
473
479
474 def setup(self):
480 def setup(self):
475
481
476 self.ncols = 1
482 self.ncols = 1
477 self.nrows = len(self.data.pairs)
483 self.nrows = len(self.data.pairs)
478 self.nplots = self.nrows * 1
484 self.nplots = self.nrows * 1
479 self.width = 3.1 * self.ncols
485 self.width = 3.1 * self.ncols
480 self.height = 5 * self.nrows
486 self.height = 5 * self.nrows
481 self.ylabel = 'Range [km]'
487 self.ylabel = 'Range [km]'
482 self.showprofile = False
488 self.showprofile = False
483 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
489 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
484
490
485 def plot(self):
491 def plot(self):
486
492
487 if self.xaxis == "frequency":
493 if self.xaxis == "frequency":
488 x = self.data.xrange[0]
494 x = self.data.xrange[0]
489 self.xlabel = "Frequency (kHz)"
495 self.xlabel = "Frequency (kHz)"
490 elif self.xaxis == "time":
496 elif self.xaxis == "time":
491 x = self.data.xrange[1]
497 x = self.data.xrange[1]
492 self.xlabel = "Time (ms)"
498 self.xlabel = "Time (ms)"
493 else:
499 else:
494 x = self.data.xrange[2]
500 x = self.data.xrange[2]
495 self.xlabel = "Velocity (m/s)"
501 self.xlabel = "Velocity (m/s)"
496
502
497 self.titles = []
503 self.titles = []
498
504
499
505
500 y = self.data.heights
506 y = self.data.heights
501 self.y = y
507 self.y = y
502 #nspc = self.data['spc']
508 #nspc = self.data['spc']
503 #print(numpy.shape(self.data['spc']))
509 #print(numpy.shape(self.data['spc']))
504 #spc = self.data['cspc'][0]
510 #spc = self.data['cspc'][0]
505 #print(numpy.shape(spc))
511 #print(numpy.shape(spc))
506 #exit()
512 #exit()
507 cspc = self.data['cspc'][1]
513 cspc = self.data['cspc'][1]
508 #print(numpy.shape(cspc))
514 #print(numpy.shape(cspc))
509 #exit()
515 #exit()
510
516
511 for n in range(self.nrows):
517 for n in range(self.nrows):
512 noise = self.data['noise'][:,-1]
518 noise = self.data['noise'][:,-1]
513 pair = self.data.pairs[n]
519 pair = self.data.pairs[n]
514 #print(pair) #exit()
520 #print(pair) #exit()
515
521
516
522
517
523
518 out = cspc[n]# / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
524 out = cspc[n]# / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
519
525
520 #print(out[:,53])
526 #print(out[:,53])
521 #exit()
527 #exit()
522 cross = numpy.abs(out)
528 cross = numpy.abs(out)
523 z = cross/self.data.nFactor
529 z = cross/self.data.nFactor
524 #print("here")
530 #print("here")
525 #print(dataOut.data_spc[0,0,0])
531 #print(dataOut.data_spc[0,0,0])
526 #exit()
532 #exit()
527
533
528 cross = 10*numpy.log10(z)
534 cross = 10*numpy.log10(z)
529 #print(numpy.shape(cross))
535 #print(numpy.shape(cross))
530 #print(cross[0,:])
536 #print(cross[0,:])
531 #print(self.data.nFactor)
537 #print(self.data.nFactor)
532 #exit()
538 #exit()
533 #phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
539 #phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
534
540
535 ax = self.axes[1 * n]
541 ax = self.axes[1 * n]
536 if ax.firsttime:
542 if ax.firsttime:
537 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
543 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
538 self.xmin = self.xmin if self.xmin else -self.xmax
544 self.xmin = self.xmin if self.xmin else -self.xmax
539 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
545 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
540 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
546 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
541 ax.plt = ax.pcolormesh(x, y, cross.T,
547 ax.plt = ax.pcolormesh(x, y, cross.T,
542 vmin=self.zmin,
548 vmin=self.zmin,
543 vmax=self.zmax,
549 vmax=self.zmax,
544 cmap=plt.get_cmap(self.colormap)
550 cmap=plt.get_cmap(self.colormap)
545 )
551 )
546 else:
552 else:
547 ax.plt.set_array(cross.T.ravel())
553 ax.plt.set_array(cross.T.ravel())
548 self.titles.append(
554 self.titles.append(
549 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
555 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
550
556
551
557
552 class CrossSpectra3Plot(Plot):
558 class CrossSpectra3Plot(Plot):
553
559
554 CODE = 'cspc'
560 CODE = 'cspc'
555 colormap = 'jet'
561 colormap = 'jet'
556 plot_type = 'pcolor'
562 plot_type = 'pcolor'
557 zmin_coh = None
563 zmin_coh = None
558 zmax_coh = None
564 zmax_coh = None
559 zmin_phase = None
565 zmin_phase = None
560 zmax_phase = None
566 zmax_phase = None
561
567
562 def setup(self):
568 def setup(self):
563
569
564 self.ncols = 3
570 self.ncols = 3
565 self.nrows = len(self.data.pairs)
571 self.nrows = len(self.data.pairs)
566 self.nplots = self.nrows * 3
572 self.nplots = self.nrows * 3
567 self.width = 3.1 * self.ncols
573 self.width = 3.1 * self.ncols
568 self.height = 5 * self.nrows
574 self.height = 5 * self.nrows
569 self.ylabel = 'Range [km]'
575 self.ylabel = 'Range [km]'
570 self.showprofile = False
576 self.showprofile = False
571 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
577 self.plots_adjust.update({'left': 0.22, 'right': .90, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
572
578
573 def plot(self):
579 def plot(self):
574
580
575 if self.xaxis == "frequency":
581 if self.xaxis == "frequency":
576 x = self.data.xrange[0]
582 x = self.data.xrange[0]
577 self.xlabel = "Frequency (kHz)"
583 self.xlabel = "Frequency (kHz)"
578 elif self.xaxis == "time":
584 elif self.xaxis == "time":
579 x = self.data.xrange[1]
585 x = self.data.xrange[1]
580 self.xlabel = "Time (ms)"
586 self.xlabel = "Time (ms)"
581 else:
587 else:
582 x = self.data.xrange[2]
588 x = self.data.xrange[2]
583 self.xlabel = "Velocity (m/s)"
589 self.xlabel = "Velocity (m/s)"
584
590
585 self.titles = []
591 self.titles = []
586
592
587
593
588 y = self.data.heights
594 y = self.data.heights
589 self.y = y
595 self.y = y
590 #nspc = self.data['spc']
596 #nspc = self.data['spc']
591 #print(numpy.shape(self.data['spc']))
597 #print(numpy.shape(self.data['spc']))
592 #spc = self.data['cspc'][0]
598 #spc = self.data['cspc'][0]
593 #print(numpy.shape(spc))
599 #print(numpy.shape(spc))
594 #exit()
600 #exit()
595 cspc = self.data['cspc'][1]
601 cspc = self.data['cspc'][1]
596 #print(numpy.shape(cspc))
602 #print(numpy.shape(cspc))
597 #exit()
603 #exit()
598
604
599 for n in range(self.nrows):
605 for n in range(self.nrows):
600 noise = self.data['noise'][:,-1]
606 noise = self.data['noise'][:,-1]
601 pair = self.data.pairs[n]
607 pair = self.data.pairs[n]
602 #print(pair) #exit()
608 #print(pair) #exit()
603
609
604
610
605
611
606 out = cspc[n]# / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
612 out = cspc[n]# / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
607
613
608 #print(out[:,53])
614 #print(out[:,53])
609 #exit()
615 #exit()
610 cross = numpy.abs(out)
616 cross = numpy.abs(out)
611 z = cross/self.data.nFactor
617 z = cross/self.data.nFactor
612 cross = 10*numpy.log10(z)
618 cross = 10*numpy.log10(z)
613
619
614 out_r= out.real/self.data.nFactor
620 out_r= out.real/self.data.nFactor
615 #out_r = 10*numpy.log10(out_r)
621 #out_r = 10*numpy.log10(out_r)
616
622
617 out_i= out.imag/self.data.nFactor
623 out_i= out.imag/self.data.nFactor
618 #out_i = 10*numpy.log10(out_i)
624 #out_i = 10*numpy.log10(out_i)
619 #print(numpy.shape(cross))
625 #print(numpy.shape(cross))
620 #print(cross[0,:])
626 #print(cross[0,:])
621 #print(self.data.nFactor)
627 #print(self.data.nFactor)
622 #exit()
628 #exit()
623 #phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
629 #phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
624
630
625 ax = self.axes[3 * n]
631 ax = self.axes[3 * n]
626 if ax.firsttime:
632 if ax.firsttime:
627 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
633 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
628 self.xmin = self.xmin if self.xmin else -self.xmax
634 self.xmin = self.xmin if self.xmin else -self.xmax
629 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
635 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
630 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
636 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
631 ax.plt = ax.pcolormesh(x, y, cross.T,
637 ax.plt = ax.pcolormesh(x, y, cross.T,
632 vmin=self.zmin,
638 vmin=self.zmin,
633 vmax=self.zmax,
639 vmax=self.zmax,
634 cmap=plt.get_cmap(self.colormap)
640 cmap=plt.get_cmap(self.colormap)
635 )
641 )
636 else:
642 else:
637 ax.plt.set_array(cross.T.ravel())
643 ax.plt.set_array(cross.T.ravel())
638 self.titles.append(
644 self.titles.append(
639 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
645 'Cross Spectra Power Ch{} * Ch{}'.format(pair[0], pair[1]))
640
646
641 ax = self.axes[3 * n + 1]
647 ax = self.axes[3 * n + 1]
642 if ax.firsttime:
648 if ax.firsttime:
643 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
649 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
644 self.xmin = self.xmin if self.xmin else -self.xmax
650 self.xmin = self.xmin if self.xmin else -self.xmax
645 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
651 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
646 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
652 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
647 ax.plt = ax.pcolormesh(x, y, out_r.T,
653 ax.plt = ax.pcolormesh(x, y, out_r.T,
648 vmin=-1.e6,
654 vmin=-1.e6,
649 vmax=0,
655 vmax=0,
650 cmap=plt.get_cmap(self.colormap)
656 cmap=plt.get_cmap(self.colormap)
651 )
657 )
652 else:
658 else:
653 ax.plt.set_array(out_r.T.ravel())
659 ax.plt.set_array(out_r.T.ravel())
654 self.titles.append(
660 self.titles.append(
655 'Cross Spectra Real Ch{} * Ch{}'.format(pair[0], pair[1]))
661 'Cross Spectra Real Ch{} * Ch{}'.format(pair[0], pair[1]))
656
662
657 ax = self.axes[3 * n + 2]
663 ax = self.axes[3 * n + 2]
658
664
659
665
660 if ax.firsttime:
666 if ax.firsttime:
661 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
667 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
662 self.xmin = self.xmin if self.xmin else -self.xmax
668 self.xmin = self.xmin if self.xmin else -self.xmax
663 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
669 self.zmin = self.zmin if self.zmin else numpy.nanmin(cross)
664 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
670 self.zmax = self.zmax if self.zmax else numpy.nanmax(cross)
665 ax.plt = ax.pcolormesh(x, y, out_i.T,
671 ax.plt = ax.pcolormesh(x, y, out_i.T,
666 vmin=-1.e6,
672 vmin=-1.e6,
667 vmax=1.e6,
673 vmax=1.e6,
668 cmap=plt.get_cmap(self.colormap)
674 cmap=plt.get_cmap(self.colormap)
669 )
675 )
670 else:
676 else:
671 ax.plt.set_array(out_i.T.ravel())
677 ax.plt.set_array(out_i.T.ravel())
672 self.titles.append(
678 self.titles.append(
673 'Cross Spectra Imag Ch{} * Ch{}'.format(pair[0], pair[1]))
679 'Cross Spectra Imag Ch{} * Ch{}'.format(pair[0], pair[1]))
674
680
675 class RTIPlot(Plot):
681 class RTIPlot(Plot):
676 '''
682 '''
677 Plot for RTI data
683 Plot for RTI data
678 '''
684 '''
679
685
680 CODE = 'rti'
686 CODE = 'rti'
681 colormap = 'jet'
687 colormap = 'jet'
682 plot_type = 'pcolorbuffer'
688 plot_type = 'pcolorbuffer'
683
689
684 def setup(self):
690 def setup(self):
685 self.xaxis = 'time'
691 self.xaxis = 'time'
686 self.ncols = 1
692 self.ncols = 1
687 self.nrows = len(self.data.channels)
693 self.nrows = len(self.data.channels)
688 self.nplots = len(self.data.channels)
694 self.nplots = len(self.data.channels)
689 self.ylabel = 'Range [km]'
695 self.ylabel = 'Range [km]'
690 self.xlabel = 'Time'
696 self.xlabel = 'Time'
691 self.cb_label = 'dB'
697 self.cb_label = 'dB'
692 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
698 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
693 self.titles = ['{} Channel {}'.format(
699 self.titles = ['{} Channel {}'.format(
694 self.CODE.upper(), x) for x in range(self.nrows)]
700 self.CODE.upper(), x) for x in range(self.nrows)]
695
701
696 def update(self, dataOut):
702 def update(self, dataOut):
697
703
698 data = {}
704 data = {}
699 meta = {}
705 meta = {}
700 data['rti'] = dataOut.getPower()
706 data['rti'] = dataOut.getPower()
701 #print(numpy.shape(data['rti']))
707 #print(numpy.shape(data['rti']))
702
708
703 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
709 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
704
710
705 return data, meta
711 return data, meta
706
712
707 def plot(self):
713 def plot(self):
708
714
709 self.x = self.data.times
715 self.x = self.data.times
710 self.y = self.data.yrange
716 self.y = self.data.yrange
711 self.z = self.data[self.CODE]
717 self.z = self.data[self.CODE]
712
718
713 self.z = numpy.ma.masked_invalid(self.z)
719 self.z = numpy.ma.masked_invalid(self.z)
714
720
715 if self.decimation is None:
721 if self.decimation is None:
716 x, y, z = self.fill_gaps(self.x, self.y, self.z)
722 x, y, z = self.fill_gaps(self.x, self.y, self.z)
717 else:
723 else:
718 x, y, z = self.fill_gaps(*self.decimate())
724 x, y, z = self.fill_gaps(*self.decimate())
719
725
720 '''
726 '''
721 if not isinstance(self.zmin, collections.abc.Sequence):
727 if not isinstance(self.zmin, collections.abc.Sequence):
722 if not self.zmin:
728 if not self.zmin:
723 self.zmin = [numpy.min(self.z)]*len(self.axes)
729 self.zmin = [numpy.min(self.z)]*len(self.axes)
724 else:
730 else:
725 self.zmin = [self.zmin]*len(self.axes)
731 self.zmin = [self.zmin]*len(self.axes)
726
732
727 if not isinstance(self.zmax, collections.abc.Sequence):
733 if not isinstance(self.zmax, collections.abc.Sequence):
728 if not self.zmax:
734 if not self.zmax:
729 self.zmax = [numpy.max(self.z)]*len(self.axes)
735 self.zmax = [numpy.max(self.z)]*len(self.axes)
730 else:
736 else:
731 self.zmax = [self.zmax]*len(self.axes)
737 self.zmax = [self.zmax]*len(self.axes)
732 '''
738 '''
733 for n, ax in enumerate(self.axes):
739 for n, ax in enumerate(self.axes):
734
740
735 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
741 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
736 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
742 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
737
743
738 if ax.firsttime:
744 if ax.firsttime:
739 if self.zlimits is not None:
745 if self.zlimits is not None:
740 self.zmin, self.zmax = self.zlimits[n]
746 self.zmin, self.zmax = self.zlimits[n]
741 ax.plt = ax.pcolormesh(x, y, z[n].T,
747 ax.plt = ax.pcolormesh(x, y, z[n].T,
742 vmin=self.zmin,
748 vmin=self.zmin,
743 vmax=self.zmax,
749 vmax=self.zmax,
744 cmap=plt.get_cmap(self.colormap)
750 cmap=plt.get_cmap(self.colormap)
745 )
751 )
746 if self.showprofile:
752 if self.showprofile:
747 ax.plot_profile = self.pf_axes[n].plot(
753 ax.plot_profile = self.pf_axes[n].plot(
748 self.data['rti'][n][-1], self.y)[0]
754 self.data['rti'][n][-1], self.y)[0]
749 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
755 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
750 color="k", linestyle="dashed", lw=1)[0]
756 color="k", linestyle="dashed", lw=1)[0]
751 else:
757 else:
752 if self.zlimits is not None:
758 if self.zlimits is not None:
753 self.zmin, self.zmax = self.zlimits[n]
759 self.zmin, self.zmax = self.zlimits[n]
754 ax.collections.remove(ax.collections[0])
760 ax.collections.remove(ax.collections[0])
755 ax.plt = ax.pcolormesh(x, y, z[n].T,
761 ax.plt = ax.pcolormesh(x, y, z[n].T,
756 vmin=self.zmin,
762 vmin=self.zmin,
757 vmax=self.zmax,
763 vmax=self.zmax,
758 cmap=plt.get_cmap(self.colormap)
764 cmap=plt.get_cmap(self.colormap)
759 )
765 )
760 if self.showprofile:
766 if self.showprofile:
761 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
767 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
762 ax.plot_noise.set_data(numpy.repeat(
768 ax.plot_noise.set_data(numpy.repeat(
763 self.data['noise'][n][-1], len(self.y)), self.y)
769 self.data['noise'][n][-1], len(self.y)), self.y)
764
770
765
771
766 class SpectrogramPlot(Plot):
772 class SpectrogramPlot(Plot):
767 '''
773 '''
768 Plot for Spectrogram data
774 Plot for Spectrogram data
769 '''
775 '''
770
776
771 CODE = 'Spectrogram_Profile'
777 CODE = 'Spectrogram_Profile'
772 colormap = 'binary'
778 colormap = 'binary'
773 plot_type = 'pcolorbuffer'
779 plot_type = 'pcolorbuffer'
774
780
775 def setup(self):
781 def setup(self):
776 self.xaxis = 'time'
782 self.xaxis = 'time'
777 self.ncols = 1
783 self.ncols = 1
778 self.nrows = len(self.data.channels)
784 self.nrows = len(self.data.channels)
779 self.nplots = len(self.data.channels)
785 self.nplots = len(self.data.channels)
780 self.xlabel = 'Time'
786 self.xlabel = 'Time'
781 #self.cb_label = 'dB'
787 #self.cb_label = 'dB'
782 self.plots_adjust.update({'hspace':1.2, 'left': 0.1, 'bottom': 0.12, 'right':0.95})
788 self.plots_adjust.update({'hspace':1.2, 'left': 0.1, 'bottom': 0.12, 'right':0.95})
783 self.titles = []
789 self.titles = []
784
790
785 #self.titles = ['{} Channel {} \n H = {} km ({} - {})'.format(
791 #self.titles = ['{} Channel {} \n H = {} km ({} - {})'.format(
786 #self.CODE.upper(), x, self.data.heightList[self.data.hei], self.data.heightList[self.data.hei],self.data.heightList[self.data.hei]+(self.data.DH*self.data.nProfiles)) for x in range(self.nrows)]
792 #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)]
787
793
788 self.titles = ['{} Channel {}'.format(
794 self.titles = ['{} Channel {}'.format(
789 self.CODE.upper(), x) for x in range(self.nrows)]
795 self.CODE.upper(), x) for x in range(self.nrows)]
790
796
791
797
792 def update(self, dataOut):
798 def update(self, dataOut):
793 data = {}
799 data = {}
794 meta = {}
800 meta = {}
795
801
796 maxHei = 1620#+12000
802 maxHei = 1620#+12000
797 indb = numpy.where(dataOut.heightList <= maxHei)
803 indb = numpy.where(dataOut.heightList <= maxHei)
798 hei = indb[0][-1]
804 hei = indb[0][-1]
799 #print(dataOut.heightList)
805 #print(dataOut.heightList)
800
806
801 factor = dataOut.nIncohInt
807 factor = dataOut.nIncohInt
802 z = dataOut.data_spc[:,:,hei] / factor
808 z = dataOut.data_spc[:,:,hei] / factor
803 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
809 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
804 #buffer = 10 * numpy.log10(z)
810 #buffer = 10 * numpy.log10(z)
805
811
806 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
812 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
807
813
808
814
809 #self.hei = hei
815 #self.hei = hei
810 #self.heightList = dataOut.heightList
816 #self.heightList = dataOut.heightList
811 #self.DH = (dataOut.heightList[1] - dataOut.heightList[0])/dataOut.step
817 #self.DH = (dataOut.heightList[1] - dataOut.heightList[0])/dataOut.step
812 #self.nProfiles = dataOut.nProfiles
818 #self.nProfiles = dataOut.nProfiles
813
819
814 data['Spectrogram_Profile'] = 10 * numpy.log10(z)
820 data['Spectrogram_Profile'] = 10 * numpy.log10(z)
815
821
816 data['hei'] = hei
822 data['hei'] = hei
817 data['DH'] = (dataOut.heightList[1] - dataOut.heightList[0])/dataOut.step
823 data['DH'] = (dataOut.heightList[1] - dataOut.heightList[0])/dataOut.step
818 data['nProfiles'] = dataOut.nProfiles
824 data['nProfiles'] = dataOut.nProfiles
819 #meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
825 #meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
820 '''
826 '''
821 import matplotlib.pyplot as plt
827 import matplotlib.pyplot as plt
822 plt.plot(10 * numpy.log10(z[0,:]))
828 plt.plot(10 * numpy.log10(z[0,:]))
823 plt.show()
829 plt.show()
824
830
825 from time import sleep
831 from time import sleep
826 sleep(10)
832 sleep(10)
827 '''
833 '''
828 return data, meta
834 return data, meta
829
835
830 def plot(self):
836 def plot(self):
831
837
832 self.x = self.data.times
838 self.x = self.data.times
833 self.z = self.data[self.CODE]
839 self.z = self.data[self.CODE]
834 self.y = self.data.xrange[0]
840 self.y = self.data.xrange[0]
835
841
836 hei = self.data['hei'][-1]
842 hei = self.data['hei'][-1]
837 DH = self.data['DH'][-1]
843 DH = self.data['DH'][-1]
838 nProfiles = self.data['nProfiles'][-1]
844 nProfiles = self.data['nProfiles'][-1]
839
845
840 self.ylabel = "Frequency (kHz)"
846 self.ylabel = "Frequency (kHz)"
841
847
842 self.z = numpy.ma.masked_invalid(self.z)
848 self.z = numpy.ma.masked_invalid(self.z)
843
849
844 if self.decimation is None:
850 if self.decimation is None:
845 x, y, z = self.fill_gaps(self.x, self.y, self.z)
851 x, y, z = self.fill_gaps(self.x, self.y, self.z)
846 else:
852 else:
847 x, y, z = self.fill_gaps(*self.decimate())
853 x, y, z = self.fill_gaps(*self.decimate())
848
854
849 for n, ax in enumerate(self.axes):
855 for n, ax in enumerate(self.axes):
850 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
856 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
851 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
857 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
852 data = self.data[-1]
858 data = self.data[-1]
853 if ax.firsttime:
859 if ax.firsttime:
854 ax.plt = ax.pcolormesh(x, y, z[n].T,
860 ax.plt = ax.pcolormesh(x, y, z[n].T,
855 vmin=self.zmin,
861 vmin=self.zmin,
856 vmax=self.zmax,
862 vmax=self.zmax,
857 cmap=plt.get_cmap(self.colormap)
863 cmap=plt.get_cmap(self.colormap)
858 )
864 )
859 else:
865 else:
860 ax.collections.remove(ax.collections[0])
866 ax.collections.remove(ax.collections[0])
861 ax.plt = ax.pcolormesh(x, y, z[n].T,
867 ax.plt = ax.pcolormesh(x, y, z[n].T,
862 vmin=self.zmin,
868 vmin=self.zmin,
863 vmax=self.zmax,
869 vmax=self.zmax,
864 cmap=plt.get_cmap(self.colormap)
870 cmap=plt.get_cmap(self.colormap)
865 )
871 )
866
872
867 #self.titles.append('Spectrogram')
873 #self.titles.append('Spectrogram')
868
874
869 #self.titles.append('{} Channel {} \n H = {} km ({} - {})'.format(
875 #self.titles.append('{} Channel {} \n H = {} km ({} - {})'.format(
870 #self.CODE.upper(), x, y[hei], y[hei],y[hei]+(DH*nProfiles)))
876 #self.CODE.upper(), x, y[hei], y[hei],y[hei]+(DH*nProfiles)))
871
877
872
878
873
879
874
880
875 class CoherencePlot(RTIPlot):
881 class CoherencePlot(RTIPlot):
876 '''
882 '''
877 Plot for Coherence data
883 Plot for Coherence data
878 '''
884 '''
879
885
880 CODE = 'coh'
886 CODE = 'coh'
881
887
882 def setup(self):
888 def setup(self):
883 self.xaxis = 'time'
889 self.xaxis = 'time'
884 self.ncols = 1
890 self.ncols = 1
885 self.nrows = len(self.data.pairs)
891 self.nrows = len(self.data.pairs)
886 self.nplots = len(self.data.pairs)
892 self.nplots = len(self.data.pairs)
887 self.ylabel = 'Range [km]'
893 self.ylabel = 'Range [km]'
888 self.xlabel = 'Time'
894 self.xlabel = 'Time'
889 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
895 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
890 if self.CODE == 'coh':
896 if self.CODE == 'coh':
891 self.cb_label = ''
897 self.cb_label = ''
892 self.titles = [
898 self.titles = [
893 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
899 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
894 else:
900 else:
895 self.cb_label = 'Degrees'
901 self.cb_label = 'Degrees'
896 self.titles = [
902 self.titles = [
897 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
903 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
898
904
899 def update(self, dataOut):
905 def update(self, dataOut):
900
906
901 data = {}
907 data = {}
902 meta = {}
908 meta = {}
903 data['coh'] = dataOut.getCoherence()
909 data['coh'] = dataOut.getCoherence()
904 meta['pairs'] = dataOut.pairsList
910 meta['pairs'] = dataOut.pairsList
905
911
906 return data, meta
912 return data, meta
907
913
908 class PhasePlot(CoherencePlot):
914 class PhasePlot(CoherencePlot):
909 '''
915 '''
910 Plot for Phase map data
916 Plot for Phase map data
911 '''
917 '''
912
918
913 CODE = 'phase'
919 CODE = 'phase'
914 colormap = 'seismic'
920 colormap = 'seismic'
915
921
916 def update(self, dataOut):
922 def update(self, dataOut):
917
923
918 data = {}
924 data = {}
919 meta = {}
925 meta = {}
920 data['phase'] = dataOut.getCoherence(phase=True)
926 data['phase'] = dataOut.getCoherence(phase=True)
921 meta['pairs'] = dataOut.pairsList
927 meta['pairs'] = dataOut.pairsList
922
928
923 return data, meta
929 return data, meta
924
930
925 class NoisePlot(Plot):
931 class NoisePlot(Plot):
926 '''
932 '''
927 Plot for noise
933 Plot for noise
928 '''
934 '''
929
935
930 CODE = 'noise'
936 CODE = 'noise'
931 plot_type = 'scatterbuffer'
937 plot_type = 'scatterbuffer'
932
938
933 def setup(self):
939 def setup(self):
934 self.xaxis = 'time'
940 self.xaxis = 'time'
935 self.ncols = 1
941 self.ncols = 1
936 self.nrows = 1
942 self.nrows = 1
937 self.nplots = 1
943 self.nplots = 1
938 self.ylabel = 'Intensity [dB]'
944 self.ylabel = 'Intensity [dB]'
939 self.xlabel = 'Time'
945 self.xlabel = 'Time'
940 self.titles = ['Noise']
946 self.titles = ['Noise']
941 self.colorbar = False
947 self.colorbar = False
942 self.plots_adjust.update({'right': 0.85 })
948 self.plots_adjust.update({'right': 0.85 })
943
949
944 def update(self, dataOut):
950 def update(self, dataOut):
945
951
946 data = {}
952 data = {}
947 meta = {}
953 meta = {}
948 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor).reshape(dataOut.nChannels, 1)
954 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor).reshape(dataOut.nChannels, 1)
949 meta['yrange'] = numpy.array([])
955 meta['yrange'] = numpy.array([])
950
956
951 return data, meta
957 return data, meta
952
958
953 def plot(self):
959 def plot(self):
954
960
955 x = self.data.times
961 x = self.data.times
956 xmin = self.data.min_time
962 xmin = self.data.min_time
957 xmax = xmin + self.xrange * 60 * 60
963 xmax = xmin + self.xrange * 60 * 60
958 Y = self.data['noise']
964 Y = self.data['noise']
959
965
960 if self.axes[0].firsttime:
966 if self.axes[0].firsttime:
961 self.ymin = numpy.nanmin(Y) - 5
967 self.ymin = numpy.nanmin(Y) - 5
962 self.ymax = numpy.nanmax(Y) + 5
968 self.ymax = numpy.nanmax(Y) + 5
963 for ch in self.data.channels:
969 for ch in self.data.channels:
964 y = Y[ch]
970 y = Y[ch]
965 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
971 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
966 plt.legend(bbox_to_anchor=(1.18, 1.0))
972 plt.legend(bbox_to_anchor=(1.18, 1.0))
967 else:
973 else:
968 for ch in self.data.channels:
974 for ch in self.data.channels:
969 y = Y[ch]
975 y = Y[ch]
970 self.axes[0].lines[ch].set_data(x, y)
976 self.axes[0].lines[ch].set_data(x, y)
971
977
972 self.ymin = numpy.nanmin(Y) - 5
978 self.ymin = numpy.nanmin(Y) - 5
973 self.ymax = numpy.nanmax(Y) + 10
979 self.ymax = numpy.nanmax(Y) + 10
974
980
975
981
976 class PowerProfilePlot(Plot):
982 class PowerProfilePlot(Plot):
977
983
978 CODE = 'pow_profile'
984 CODE = 'pow_profile'
979 plot_type = 'scatter'
985 plot_type = 'scatter'
980
986
981 def setup(self):
987 def setup(self):
982
988
983 self.ncols = 1
989 self.ncols = 1
984 self.nrows = 1
990 self.nrows = 1
985 self.nplots = 1
991 self.nplots = 1
986 self.height = 4
992 self.height = 4
987 self.width = 3
993 self.width = 3
988 self.ylabel = 'Range [km]'
994 self.ylabel = 'Range [km]'
989 self.xlabel = 'Intensity [dB]'
995 self.xlabel = 'Intensity [dB]'
990 self.titles = ['Power Profile']
996 self.titles = ['Power Profile']
991 self.colorbar = False
997 self.colorbar = False
992
998
993 def update(self, dataOut):
999 def update(self, dataOut):
994
1000
995 data = {}
1001 data = {}
996 meta = {}
1002 meta = {}
997 data[self.CODE] = dataOut.getPower()
1003 data[self.CODE] = dataOut.getPower()
998
1004
999 return data, meta
1005 return data, meta
1000
1006
1001 def plot(self):
1007 def plot(self):
1002
1008
1003 y = self.data.yrange
1009 y = self.data.yrange
1004 self.y = y
1010 self.y = y
1005
1011
1006 x = self.data[-1][self.CODE]
1012 x = self.data[-1][self.CODE]
1007
1013
1008 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
1014 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
1009 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
1015 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
1010
1016
1011 if self.axes[0].firsttime:
1017 if self.axes[0].firsttime:
1012 for ch in self.data.channels:
1018 for ch in self.data.channels:
1013 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
1019 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
1014 plt.legend()
1020 plt.legend()
1015 else:
1021 else:
1016 for ch in self.data.channels:
1022 for ch in self.data.channels:
1017 self.axes[0].lines[ch].set_data(x[ch], y)
1023 self.axes[0].lines[ch].set_data(x[ch], y)
1018
1024
1019
1025
1020 class SpectraCutPlot(Plot):
1026 class SpectraCutPlot(Plot):
1021
1027
1022 CODE = 'spc_cut'
1028 CODE = 'spc_cut'
1023 plot_type = 'scatter'
1029 plot_type = 'scatter'
1024 buffering = False
1030 buffering = False
1025
1031
1026 def setup(self):
1032 def setup(self):
1027
1033
1028 self.nplots = len(self.data.channels)
1034 self.nplots = len(self.data.channels)
1029 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
1035 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
1030 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
1036 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
1031 self.width = 3.4 * self.ncols + 1.5
1037 self.width = 3.4 * self.ncols + 1.5
1032 self.height = 3 * self.nrows
1038 self.height = 3 * self.nrows
1033 self.ylabel = 'Power [dB]'
1039 self.ylabel = 'Power [dB]'
1034 self.colorbar = False
1040 self.colorbar = False
1035 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.75, 'bottom':0.08})
1041 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.75, 'bottom':0.08})
1036
1042
1037 def update(self, dataOut):
1043 def update(self, dataOut):
1038
1044
1039 data = {}
1045 data = {}
1040 meta = {}
1046 meta = {}
1041 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
1047 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
1042 data['spc'] = spc
1048 data['spc'] = spc
1043 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
1049 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
1044 if self.CODE == 'cut_gaussian_fit':
1050 if self.CODE == 'cut_gaussian_fit':
1045 data['gauss_fit0'] = 10*numpy.log10(dataOut.GaussFit0/dataOut.normFactor)
1051 data['gauss_fit0'] = 10*numpy.log10(dataOut.GaussFit0/dataOut.normFactor)
1046 data['gauss_fit1'] = 10*numpy.log10(dataOut.GaussFit1/dataOut.normFactor)
1052 data['gauss_fit1'] = 10*numpy.log10(dataOut.GaussFit1/dataOut.normFactor)
1047 return data, meta
1053 return data, meta
1048
1054
1049 def plot(self):
1055 def plot(self):
1050 if self.xaxis == "frequency":
1056 if self.xaxis == "frequency":
1051 x = self.data.xrange[0][1:]
1057 x = self.data.xrange[0][1:]
1052 self.xlabel = "Frequency (kHz)"
1058 self.xlabel = "Frequency (kHz)"
1053 elif self.xaxis == "time":
1059 elif self.xaxis == "time":
1054 x = self.data.xrange[1]
1060 x = self.data.xrange[1]
1055 self.xlabel = "Time (ms)"
1061 self.xlabel = "Time (ms)"
1056 else:
1062 else:
1057 x = self.data.xrange[2][:-1]
1063 x = self.data.xrange[2][:-1]
1058 self.xlabel = "Velocity (m/s)"
1064 self.xlabel = "Velocity (m/s)"
1059
1065
1060 if self.CODE == 'cut_gaussian_fit':
1066 if self.CODE == 'cut_gaussian_fit':
1061 x = self.data.xrange[2][:-1]
1067 x = self.data.xrange[2][:-1]
1062 self.xlabel = "Velocity (m/s)"
1068 self.xlabel = "Velocity (m/s)"
1063
1069
1064 self.titles = []
1070 self.titles = []
1065
1071
1066 y = self.data.yrange
1072 y = self.data.yrange
1067 data = self.data[-1]
1073 data = self.data[-1]
1068 z = data['spc']
1074 z = data['spc']
1069
1075
1070 if self.height_index:
1076 if self.height_index:
1071 index = numpy.array(self.height_index)
1077 index = numpy.array(self.height_index)
1072 else:
1078 else:
1073 index = numpy.arange(0, len(y), int((len(y))/9))
1079 index = numpy.arange(0, len(y), int((len(y))/9))
1074
1080
1075 for n, ax in enumerate(self.axes):
1081 for n, ax in enumerate(self.axes):
1076 if self.CODE == 'cut_gaussian_fit':
1082 if self.CODE == 'cut_gaussian_fit':
1077 gau0 = data['gauss_fit0']
1083 gau0 = data['gauss_fit0']
1078 gau1 = data['gauss_fit1']
1084 gau1 = data['gauss_fit1']
1079 if ax.firsttime:
1085 if ax.firsttime:
1080 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
1086 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
1081 self.xmin = self.xmin if self.xmin else -self.xmax
1087 self.xmin = self.xmin if self.xmin else -self.xmax
1082 self.ymin = self.ymin if self.ymin else numpy.nanmin(z[:,:,index])
1088 self.ymin = self.ymin if self.ymin else numpy.nanmin(z[:,:,index])
1083 self.ymax = self.ymax if self.ymax else numpy.nanmax(z[:,:,index])
1089 self.ymax = self.ymax if self.ymax else numpy.nanmax(z[:,:,index])
1084 #print(self.ymax)
1090 #print(self.ymax)
1085 #print(z[n, :, index])
1091 #print(z[n, :, index])
1086 ax.plt = ax.plot(x, z[n, :, index].T, lw=0.25)
1092 ax.plt = ax.plot(x, z[n, :, index].T, lw=0.25)
1087 if self.CODE == 'cut_gaussian_fit':
1093 if self.CODE == 'cut_gaussian_fit':
1088 ax.plt_gau0 = ax.plot(x, gau0[n, :, index].T, lw=1, linestyle='-.')
1094 ax.plt_gau0 = ax.plot(x, gau0[n, :, index].T, lw=1, linestyle='-.')
1089 for i, line in enumerate(ax.plt_gau0):
1095 for i, line in enumerate(ax.plt_gau0):
1090 line.set_color(ax.plt[i].get_color())
1096 line.set_color(ax.plt[i].get_color())
1091 ax.plt_gau1 = ax.plot(x, gau1[n, :, index].T, lw=1, linestyle='--')
1097 ax.plt_gau1 = ax.plot(x, gau1[n, :, index].T, lw=1, linestyle='--')
1092 for i, line in enumerate(ax.plt_gau1):
1098 for i, line in enumerate(ax.plt_gau1):
1093 line.set_color(ax.plt[i].get_color())
1099 line.set_color(ax.plt[i].get_color())
1094 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
1100 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
1095 self.figures[0].legend(ax.plt, labels, loc='center right')
1101 self.figures[0].legend(ax.plt, labels, loc='center right')
1096 else:
1102 else:
1097 for i, line in enumerate(ax.plt):
1103 for i, line in enumerate(ax.plt):
1098 line.set_data(x, z[n, :, index[i]].T)
1104 line.set_data(x, z[n, :, index[i]].T)
1099 for i, line in enumerate(ax.plt_gau0):
1105 for i, line in enumerate(ax.plt_gau0):
1100 line.set_data(x, gau0[n, :, index[i]].T)
1106 line.set_data(x, gau0[n, :, index[i]].T)
1101 line.set_color(ax.plt[i].get_color())
1107 line.set_color(ax.plt[i].get_color())
1102 for i, line in enumerate(ax.plt_gau1):
1108 for i, line in enumerate(ax.plt_gau1):
1103 line.set_data(x, gau1[n, :, index[i]].T)
1109 line.set_data(x, gau1[n, :, index[i]].T)
1104 line.set_color(ax.plt[i].get_color())
1110 line.set_color(ax.plt[i].get_color())
1105 self.titles.append('CH {}'.format(n))
1111 self.titles.append('CH {}'.format(n))
1106
1112
1107
1113
1108 class BeaconPhase(Plot):
1114 class BeaconPhase(Plot):
1109
1115
1110 __isConfig = None
1116 __isConfig = None
1111 __nsubplots = None
1117 __nsubplots = None
1112
1118
1113 PREFIX = 'beacon_phase'
1119 PREFIX = 'beacon_phase'
1114
1120
1115 def __init__(self):
1121 def __init__(self):
1116 Plot.__init__(self)
1122 Plot.__init__(self)
1117 self.timerange = 24*60*60
1123 self.timerange = 24*60*60
1118 self.isConfig = False
1124 self.isConfig = False
1119 self.__nsubplots = 1
1125 self.__nsubplots = 1
1120 self.counter_imagwr = 0
1126 self.counter_imagwr = 0
1121 self.WIDTH = 800
1127 self.WIDTH = 800
1122 self.HEIGHT = 400
1128 self.HEIGHT = 400
1123 self.WIDTHPROF = 120
1129 self.WIDTHPROF = 120
1124 self.HEIGHTPROF = 0
1130 self.HEIGHTPROF = 0
1125 self.xdata = None
1131 self.xdata = None
1126 self.ydata = None
1132 self.ydata = None
1127
1133
1128 self.PLOT_CODE = BEACON_CODE
1134 self.PLOT_CODE = BEACON_CODE
1129
1135
1130 self.FTP_WEI = None
1136 self.FTP_WEI = None
1131 self.EXP_CODE = None
1137 self.EXP_CODE = None
1132 self.SUB_EXP_CODE = None
1138 self.SUB_EXP_CODE = None
1133 self.PLOT_POS = None
1139 self.PLOT_POS = None
1134
1140
1135 self.filename_phase = None
1141 self.filename_phase = None
1136
1142
1137 self.figfile = None
1143 self.figfile = None
1138
1144
1139 self.xmin = None
1145 self.xmin = None
1140 self.xmax = None
1146 self.xmax = None
1141
1147
1142 def getSubplots(self):
1148 def getSubplots(self):
1143
1149
1144 ncol = 1
1150 ncol = 1
1145 nrow = 1
1151 nrow = 1
1146
1152
1147 return nrow, ncol
1153 return nrow, ncol
1148
1154
1149 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1155 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1150
1156
1151 self.__showprofile = showprofile
1157 self.__showprofile = showprofile
1152 self.nplots = nplots
1158 self.nplots = nplots
1153
1159
1154 ncolspan = 7
1160 ncolspan = 7
1155 colspan = 6
1161 colspan = 6
1156 self.__nsubplots = 2
1162 self.__nsubplots = 2
1157
1163
1158 self.createFigure(id = id,
1164 self.createFigure(id = id,
1159 wintitle = wintitle,
1165 wintitle = wintitle,
1160 widthplot = self.WIDTH+self.WIDTHPROF,
1166 widthplot = self.WIDTH+self.WIDTHPROF,
1161 heightplot = self.HEIGHT+self.HEIGHTPROF,
1167 heightplot = self.HEIGHT+self.HEIGHTPROF,
1162 show=show)
1168 show=show)
1163
1169
1164 nrow, ncol = self.getSubplots()
1170 nrow, ncol = self.getSubplots()
1165
1171
1166 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1172 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1167
1173
1168 def save_phase(self, filename_phase):
1174 def save_phase(self, filename_phase):
1169 f = open(filename_phase,'w+')
1175 f = open(filename_phase,'w+')
1170 f.write('\n\n')
1176 f.write('\n\n')
1171 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
1177 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
1172 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
1178 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
1173 f.close()
1179 f.close()
1174
1180
1175 def save_data(self, filename_phase, data, data_datetime):
1181 def save_data(self, filename_phase, data, data_datetime):
1176 f=open(filename_phase,'a')
1182 f=open(filename_phase,'a')
1177 timetuple_data = data_datetime.timetuple()
1183 timetuple_data = data_datetime.timetuple()
1178 day = str(timetuple_data.tm_mday)
1184 day = str(timetuple_data.tm_mday)
1179 month = str(timetuple_data.tm_mon)
1185 month = str(timetuple_data.tm_mon)
1180 year = str(timetuple_data.tm_year)
1186 year = str(timetuple_data.tm_year)
1181 hour = str(timetuple_data.tm_hour)
1187 hour = str(timetuple_data.tm_hour)
1182 minute = str(timetuple_data.tm_min)
1188 minute = str(timetuple_data.tm_min)
1183 second = str(timetuple_data.tm_sec)
1189 second = str(timetuple_data.tm_sec)
1184 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
1190 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
1185 f.close()
1191 f.close()
1186
1192
1187 def plot(self):
1193 def plot(self):
1188 log.warning('TODO: Not yet implemented...')
1194 log.warning('TODO: Not yet implemented...')
1189
1195
1190 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1196 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
1191 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
1197 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
1192 timerange=None,
1198 timerange=None,
1193 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1199 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
1194 server=None, folder=None, username=None, password=None,
1200 server=None, folder=None, username=None, password=None,
1195 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1201 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
1196
1202
1197 if dataOut.flagNoData:
1203 if dataOut.flagNoData:
1198 return dataOut
1204 return dataOut
1199
1205
1200 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1206 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
1201 return
1207 return
1202
1208
1203 if pairsList == None:
1209 if pairsList == None:
1204 pairsIndexList = dataOut.pairsIndexList[:10]
1210 pairsIndexList = dataOut.pairsIndexList[:10]
1205 else:
1211 else:
1206 pairsIndexList = []
1212 pairsIndexList = []
1207 for pair in pairsList:
1213 for pair in pairsList:
1208 if pair not in dataOut.pairsList:
1214 if pair not in dataOut.pairsList:
1209 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
1215 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
1210 pairsIndexList.append(dataOut.pairsList.index(pair))
1216 pairsIndexList.append(dataOut.pairsList.index(pair))
1211
1217
1212 if pairsIndexList == []:
1218 if pairsIndexList == []:
1213 return
1219 return
1214
1220
1215 # if len(pairsIndexList) > 4:
1221 # if len(pairsIndexList) > 4:
1216 # pairsIndexList = pairsIndexList[0:4]
1222 # pairsIndexList = pairsIndexList[0:4]
1217
1223
1218 hmin_index = None
1224 hmin_index = None
1219 hmax_index = None
1225 hmax_index = None
1220
1226
1221 if hmin != None and hmax != None:
1227 if hmin != None and hmax != None:
1222 indexes = numpy.arange(dataOut.nHeights)
1228 indexes = numpy.arange(dataOut.nHeights)
1223 hmin_list = indexes[dataOut.heightList >= hmin]
1229 hmin_list = indexes[dataOut.heightList >= hmin]
1224 hmax_list = indexes[dataOut.heightList <= hmax]
1230 hmax_list = indexes[dataOut.heightList <= hmax]
1225
1231
1226 if hmin_list.any():
1232 if hmin_list.any():
1227 hmin_index = hmin_list[0]
1233 hmin_index = hmin_list[0]
1228
1234
1229 if hmax_list.any():
1235 if hmax_list.any():
1230 hmax_index = hmax_list[-1]+1
1236 hmax_index = hmax_list[-1]+1
1231
1237
1232 x = dataOut.getTimeRange()
1238 x = dataOut.getTimeRange()
1233
1239
1234 thisDatetime = dataOut.datatime
1240 thisDatetime = dataOut.datatime
1235
1241
1236 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1242 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
1237 xlabel = "Local Time"
1243 xlabel = "Local Time"
1238 ylabel = "Phase (degrees)"
1244 ylabel = "Phase (degrees)"
1239
1245
1240 update_figfile = False
1246 update_figfile = False
1241
1247
1242 nplots = len(pairsIndexList)
1248 nplots = len(pairsIndexList)
1243 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1249 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
1244 phase_beacon = numpy.zeros(len(pairsIndexList))
1250 phase_beacon = numpy.zeros(len(pairsIndexList))
1245 for i in range(nplots):
1251 for i in range(nplots):
1246 pair = dataOut.pairsList[pairsIndexList[i]]
1252 pair = dataOut.pairsList[pairsIndexList[i]]
1247 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
1253 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
1248 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
1254 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
1249 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
1255 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
1250 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
1256 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
1251 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
1257 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
1252
1258
1253 if dataOut.beacon_heiIndexList:
1259 if dataOut.beacon_heiIndexList:
1254 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
1260 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
1255 else:
1261 else:
1256 phase_beacon[i] = numpy.average(phase)
1262 phase_beacon[i] = numpy.average(phase)
1257
1263
1258 if not self.isConfig:
1264 if not self.isConfig:
1259
1265
1260 nplots = len(pairsIndexList)
1266 nplots = len(pairsIndexList)
1261
1267
1262 self.setup(id=id,
1268 self.setup(id=id,
1263 nplots=nplots,
1269 nplots=nplots,
1264 wintitle=wintitle,
1270 wintitle=wintitle,
1265 showprofile=showprofile,
1271 showprofile=showprofile,
1266 show=show)
1272 show=show)
1267
1273
1268 if timerange != None:
1274 if timerange != None:
1269 self.timerange = timerange
1275 self.timerange = timerange
1270
1276
1271 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1277 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
1272
1278
1273 if ymin == None: ymin = 0
1279 if ymin == None: ymin = 0
1274 if ymax == None: ymax = 360
1280 if ymax == None: ymax = 360
1275
1281
1276 self.FTP_WEI = ftp_wei
1282 self.FTP_WEI = ftp_wei
1277 self.EXP_CODE = exp_code
1283 self.EXP_CODE = exp_code
1278 self.SUB_EXP_CODE = sub_exp_code
1284 self.SUB_EXP_CODE = sub_exp_code
1279 self.PLOT_POS = plot_pos
1285 self.PLOT_POS = plot_pos
1280
1286
1281 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1287 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1282 self.isConfig = True
1288 self.isConfig = True
1283 self.figfile = figfile
1289 self.figfile = figfile
1284 self.xdata = numpy.array([])
1290 self.xdata = numpy.array([])
1285 self.ydata = numpy.array([])
1291 self.ydata = numpy.array([])
1286
1292
1287 update_figfile = True
1293 update_figfile = True
1288
1294
1289 #open file beacon phase
1295 #open file beacon phase
1290 path = '%s%03d' %(self.PREFIX, self.id)
1296 path = '%s%03d' %(self.PREFIX, self.id)
1291 beacon_file = os.path.join(path,'%s.txt'%self.name)
1297 beacon_file = os.path.join(path,'%s.txt'%self.name)
1292 self.filename_phase = os.path.join(figpath,beacon_file)
1298 self.filename_phase = os.path.join(figpath,beacon_file)
1293 #self.save_phase(self.filename_phase)
1299 #self.save_phase(self.filename_phase)
1294
1300
1295
1301
1296 #store data beacon phase
1302 #store data beacon phase
1297 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1303 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
1298
1304
1299 self.setWinTitle(title)
1305 self.setWinTitle(title)
1300
1306
1301
1307
1302 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1308 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
1303
1309
1304 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
1310 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
1305
1311
1306 axes = self.axesList[0]
1312 axes = self.axesList[0]
1307
1313
1308 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1314 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1309
1315
1310 if len(self.ydata)==0:
1316 if len(self.ydata)==0:
1311 self.ydata = phase_beacon.reshape(-1,1)
1317 self.ydata = phase_beacon.reshape(-1,1)
1312 else:
1318 else:
1313 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1319 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
1314
1320
1315
1321
1316 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1322 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1317 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1323 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
1318 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1324 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1319 XAxisAsTime=True, grid='both'
1325 XAxisAsTime=True, grid='both'
1320 )
1326 )
1321
1327
1322 self.draw()
1328 self.draw()
1323
1329
1324 if dataOut.ltctime >= self.xmax:
1330 if dataOut.ltctime >= self.xmax:
1325 self.counter_imagwr = wr_period
1331 self.counter_imagwr = wr_period
1326 self.isConfig = False
1332 self.isConfig = False
1327 update_figfile = True
1333 update_figfile = True
1328
1334
1329 self.save(figpath=figpath,
1335 self.save(figpath=figpath,
1330 figfile=figfile,
1336 figfile=figfile,
1331 save=save,
1337 save=save,
1332 ftp=ftp,
1338 ftp=ftp,
1333 wr_period=wr_period,
1339 wr_period=wr_period,
1334 thisDatetime=thisDatetime,
1340 thisDatetime=thisDatetime,
1335 update_figfile=update_figfile)
1341 update_figfile=update_figfile)
1336
1342
1337 return dataOut
1343 return dataOut
@@ -1,1287 +1,1287
1
1
2 import os
2 import os
3 import time
3 import time
4 import math
4 import math
5 import datetime
5 import datetime
6 import numpy
6 import numpy
7 import collections.abc
7
8 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator #YONG
8 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator #YONG
9
9
10 from .jroplot_spectra import RTIPlot, NoisePlot
10 from .jroplot_spectra import RTIPlot, NoisePlot
11
11
12 from schainpy.utils import log
12 from schainpy.utils import log
13 from .plotting_codes import *
13 from .plotting_codes import *
14
14
15 from schainpy.model.graphics.jroplot_base import Plot, plt
15 from schainpy.model.graphics.jroplot_base import Plot, plt
16
16
17 import matplotlib.pyplot as plt
17 import matplotlib.pyplot as plt
18 import matplotlib.colors as colors
18 import matplotlib.colors as colors
19 from matplotlib.ticker import MultipleLocator
19 from matplotlib.ticker import MultipleLocator
20
20
21
21
22 class RTIDPPlot(RTIPlot):
22 class RTIDPPlot(RTIPlot):
23
23
24 '''Plot for RTI Double Pulse Experiment
24 '''Plot for RTI Double Pulse Experiment
25 '''
25 '''
26
26
27 CODE = 'RTIDP'
27 CODE = 'RTIDP'
28 colormap = 'jet'
28 colormap = 'jet'
29 plot_name = 'RTI'
29 plot_name = 'RTI'
30 plot_type = 'pcolorbuffer'
30 plot_type = 'pcolorbuffer'
31
31
32 def setup(self):
32 def setup(self):
33 self.xaxis = 'time'
33 self.xaxis = 'time'
34 self.ncols = 1
34 self.ncols = 1
35 self.nrows = 3
35 self.nrows = 3
36 self.nplots = self.nrows
36 self.nplots = self.nrows
37
37
38 self.ylabel = 'Range [km]'
38 self.ylabel = 'Range [km]'
39 self.xlabel = 'Time (LT)'
39 self.xlabel = 'Time (LT)'
40
40
41 self.cb_label = 'Intensity (dB)'
41 self.cb_label = 'Intensity (dB)'
42
42
43 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
43 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
44
44
45 self.titles = ['{} Channel {}'.format(
45 self.titles = ['{} Channel {}'.format(
46 self.plot_name.upper(), '0x1'),'{} Channel {}'.format(
46 self.plot_name.upper(), '0x1'),'{} Channel {}'.format(
47 self.plot_name.upper(), '0'),'{} Channel {}'.format(
47 self.plot_name.upper(), '0'),'{} Channel {}'.format(
48 self.plot_name.upper(), '1')]
48 self.plot_name.upper(), '1')]
49
49
50 def update(self, dataOut):
50 def update(self, dataOut):
51
51
52 data = {}
52 data = {}
53 meta = {}
53 meta = {}
54 data['rti'] = dataOut.data_for_RTI_DP
54 data['rti'] = dataOut.data_for_RTI_DP
55 data['NDP'] = dataOut.NDP
55 data['NDP'] = dataOut.NDP
56
56
57 return data, meta
57 return data, meta
58
58
59 def plot(self):
59 def plot(self):
60
60
61 NDP = self.data['NDP'][-1]
61 NDP = self.data['NDP'][-1]
62 self.x = self.data.times
62 self.x = self.data.times
63 self.y = self.data.yrange[0:NDP]
63 self.y = self.data.yrange[0:NDP]
64 self.z = self.data['rti']
64 self.z = self.data['rti']
65 self.z = numpy.ma.masked_invalid(self.z)
65 self.z = numpy.ma.masked_invalid(self.z)
66
66
67 if self.decimation is None:
67 if self.decimation is None:
68 x, y, z = self.fill_gaps(self.x, self.y, self.z)
68 x, y, z = self.fill_gaps(self.x, self.y, self.z)
69 else:
69 else:
70 x, y, z = self.fill_gaps(*self.decimate())
70 x, y, z = self.fill_gaps(*self.decimate())
71
71
72 for n, ax in enumerate(self.axes):
72 for n, ax in enumerate(self.axes):
73
73
74 self.zmax = self.zmax if self.zmax is not None else numpy.max(
74 self.zmax = self.zmax if self.zmax is not None else numpy.max(
75 self.z[1][0,12:40])
75 self.z[1][0,12:40])
76 self.zmin = self.zmin if self.zmin is not None else numpy.min(
76 self.zmin = self.zmin if self.zmin is not None else numpy.min(
77 self.z[1][0,12:40])
77 self.z[1][0,12:40])
78
78
79 if ax.firsttime:
79 if ax.firsttime:
80
80
81 if self.zlimits is not None:
81 if self.zlimits is not None:
82 self.zmin, self.zmax = self.zlimits[n]
82 self.zmin, self.zmax = self.zlimits[n]
83
83
84 ax.plt = ax.pcolormesh(x, y, z[n].T,
84 ax.plt = ax.pcolormesh(x, y, z[n].T,
85 vmin=self.zmin,
85 vmin=self.zmin,
86 vmax=self.zmax,
86 vmax=self.zmax,
87 cmap=plt.get_cmap(self.colormap)
87 cmap=plt.get_cmap(self.colormap)
88 )
88 )
89 else:
89 else:
90 #if self.zlimits is not None:
90 #if self.zlimits is not None:
91 #self.zmin, self.zmax = self.zlimits[n]
91 #self.zmin, self.zmax = self.zlimits[n]
92 ax.collections.remove(ax.collections[0])
92 ax.collections.remove(ax.collections[0])
93 ax.plt = ax.pcolormesh(x, y, z[n].T,
93 ax.plt = ax.pcolormesh(x, y, z[n].T,
94 vmin=self.zmin,
94 vmin=self.zmin,
95 vmax=self.zmax,
95 vmax=self.zmax,
96 cmap=plt.get_cmap(self.colormap)
96 cmap=plt.get_cmap(self.colormap)
97 )
97 )
98
98
99
99
100 class RTILPPlot(RTIPlot):
100 class RTILPPlot(RTIPlot):
101
101
102 '''
102 '''
103 Plot for RTI Long Pulse
103 Plot for RTI Long Pulse
104 '''
104 '''
105
105
106 CODE = 'RTILP'
106 CODE = 'RTILP'
107 colormap = 'jet'
107 colormap = 'jet'
108 plot_name = 'RTI LP'
108 plot_name = 'RTI LP'
109 plot_type = 'pcolorbuffer'
109 plot_type = 'pcolorbuffer'
110
110
111 def setup(self):
111 def setup(self):
112 self.xaxis = 'time'
112 self.xaxis = 'time'
113 self.ncols = 1
113 self.ncols = 1
114 self.nrows = 2
114 self.nrows = 2
115 self.nplots = self.nrows
115 self.nplots = self.nrows
116
116
117 self.ylabel = 'Range [km]'
117 self.ylabel = 'Range [km]'
118 self.xlabel = 'Time (LT)'
118 self.xlabel = 'Time (LT)'
119
119
120 self.cb_label = 'Intensity (dB)'
120 self.cb_label = 'Intensity (dB)'
121
121
122 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
122 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.1, 'right':0.95})
123
123
124
124
125 self.titles = ['{} Channel {}'.format(
125 self.titles = ['{} Channel {}'.format(
126 self.plot_name.upper(), '0'),'{} Channel {}'.format(
126 self.plot_name.upper(), '0'),'{} Channel {}'.format(
127 self.plot_name.upper(), '1'),'{} Channel {}'.format(
127 self.plot_name.upper(), '1'),'{} Channel {}'.format(
128 self.plot_name.upper(), '2'),'{} Channel {}'.format(
128 self.plot_name.upper(), '2'),'{} Channel {}'.format(
129 self.plot_name.upper(), '3')]
129 self.plot_name.upper(), '3')]
130
130
131
131
132 def update(self, dataOut):
132 def update(self, dataOut):
133
133
134 data = {}
134 data = {}
135 meta = {}
135 meta = {}
136 data['rti'] = dataOut.data_for_RTI_LP
136 data['rti'] = dataOut.data_for_RTI_LP
137 data['NRANGE'] = dataOut.NRANGE
137 data['NRANGE'] = dataOut.NRANGE
138
138
139 return data, meta
139 return data, meta
140
140
141 def plot(self):
141 def plot(self):
142
142
143 NRANGE = self.data['NRANGE'][-1]
143 NRANGE = self.data['NRANGE'][-1]
144 self.x = self.data.times
144 self.x = self.data.times
145 self.y = self.data.yrange[0:NRANGE]
145 self.y = self.data.yrange[0:NRANGE]
146
146
147 self.z = self.data['rti']
147 self.z = self.data['rti']
148
148
149 self.z = numpy.ma.masked_invalid(self.z)
149 self.z = numpy.ma.masked_invalid(self.z)
150
150
151 if self.decimation is None:
151 if self.decimation is None:
152 x, y, z = self.fill_gaps(self.x, self.y, self.z)
152 x, y, z = self.fill_gaps(self.x, self.y, self.z)
153 else:
153 else:
154 x, y, z = self.fill_gaps(*self.decimate())
154 x, y, z = self.fill_gaps(*self.decimate())
155
155
156 for n, ax in enumerate(self.axes):
156 for n, ax in enumerate(self.axes):
157
157
158 self.zmax = self.zmax if self.zmax is not None else numpy.max(
158 self.zmax = self.zmax if self.zmax is not None else numpy.max(
159 self.z[1][0,12:40])
159 self.z[1][0,12:40])
160 self.zmin = self.zmin if self.zmin is not None else numpy.min(
160 self.zmin = self.zmin if self.zmin is not None else numpy.min(
161 self.z[1][0,12:40])
161 self.z[1][0,12:40])
162
162
163 if ax.firsttime:
163 if ax.firsttime:
164
164
165 if self.zlimits is not None:
165 if self.zlimits is not None:
166 self.zmin, self.zmax = self.zlimits[n]
166 self.zmin, self.zmax = self.zlimits[n]
167
167
168
168
169 ax.plt = ax.pcolormesh(x, y, z[n].T,
169 ax.plt = ax.pcolormesh(x, y, z[n].T,
170 vmin=self.zmin,
170 vmin=self.zmin,
171 vmax=self.zmax,
171 vmax=self.zmax,
172 cmap=plt.get_cmap(self.colormap)
172 cmap=plt.get_cmap(self.colormap)
173 )
173 )
174
174
175 else:
175 else:
176 if self.zlimits is not None:
176 if self.zlimits is not None:
177 self.zmin, self.zmax = self.zlimits[n]
177 self.zmin, self.zmax = self.zlimits[n]
178 ax.collections.remove(ax.collections[0])
178 ax.collections.remove(ax.collections[0])
179 ax.plt = ax.pcolormesh(x, y, z[n].T,
179 ax.plt = ax.pcolormesh(x, y, z[n].T,
180 vmin=self.zmin,
180 vmin=self.zmin,
181 vmax=self.zmax,
181 vmax=self.zmax,
182 cmap=plt.get_cmap(self.colormap)
182 cmap=plt.get_cmap(self.colormap)
183 )
183 )
184
184
185
185
186 class DenRTIPlot(RTIPlot):
186 class DenRTIPlot(RTIPlot):
187
187
188 '''
188 '''
189 Plot for Den
189 Plot for Den
190 '''
190 '''
191
191
192 CODE = 'denrti'
192 CODE = 'denrti'
193 colormap = 'jet'
193 colormap = 'jet'
194
194
195 def setup(self):
195 def setup(self):
196 self.xaxis = 'time'
196 self.xaxis = 'time'
197 self.ncols = 1
197 self.ncols = 1
198 self.nrows = self.data.shape(self.CODE)[0]
198 self.nrows = self.data.shape(self.CODE)[0]
199 self.nplots = self.nrows
199 self.nplots = self.nrows
200
200
201 self.ylabel = 'Range [km]'
201 self.ylabel = 'Range [km]'
202 self.xlabel = 'Time (LT)'
202 self.xlabel = 'Time (LT)'
203
203
204 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
204 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
205
205
206 if self.CODE == 'denrti':
206 if self.CODE == 'denrti':
207 self.cb_label = r'$\mathrm{N_e}$ Electron Density ($\mathrm{1/cm^3}$)'
207 self.cb_label = r'$\mathrm{N_e}$ Electron Density ($\mathrm{1/cm^3}$)'
208
208
209
209
210 self.titles = ['Electron Density RTI']
210 self.titles = ['Electron Density RTI']
211
211
212 def update(self, dataOut):
212 def update(self, dataOut):
213
213
214 data = {}
214 data = {}
215 meta = {}
215 meta = {}
216
216
217 data['denrti'] = dataOut.DensityFinal*1.e-6 #To Plot in cm^-3
217 data['denrti'] = dataOut.DensityFinal*1.e-6 #To Plot in cm^-3
218
218
219 return data, meta
219 return data, meta
220
220
221 def plot(self):
221 def plot(self):
222
222
223 self.x = self.data.times
223 self.x = self.data.times
224 self.y = self.data.yrange
224 self.y = self.data.yrange
225
225
226 self.z = self.data[self.CODE]
226 self.z = self.data[self.CODE]
227
227
228 self.z = numpy.ma.masked_invalid(self.z)
228 self.z = numpy.ma.masked_invalid(self.z)
229
229
230 if self.decimation is None:
230 if self.decimation is None:
231 x, y, z = self.fill_gaps(self.x, self.y, self.z)
231 x, y, z = self.fill_gaps(self.x, self.y, self.z)
232 else:
232 else:
233 x, y, z = self.fill_gaps(*self.decimate())
233 x, y, z = self.fill_gaps(*self.decimate())
234
234
235 for n, ax in enumerate(self.axes):
235 for n, ax in enumerate(self.axes):
236
236
237 self.zmax = self.zmax if self.zmax is not None else numpy.max(
237 self.zmax = self.zmax if self.zmax is not None else numpy.max(
238 self.z[n])
238 self.z[n])
239 self.zmin = self.zmin if self.zmin is not None else numpy.min(
239 self.zmin = self.zmin if self.zmin is not None else numpy.min(
240 self.z[n])
240 self.z[n])
241
241
242 if ax.firsttime:
242 if ax.firsttime:
243
243
244 if self.zlimits is not None:
244 if self.zlimits is not None:
245 self.zmin, self.zmax = self.zlimits[n]
245 self.zmin, self.zmax = self.zlimits[n]
246 if numpy.log10(self.zmin)<0:
246 if numpy.log10(self.zmin)<0:
247 self.zmin=1
247 self.zmin=1
248 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
248 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
249 vmin=self.zmin,
249 vmin=self.zmin,
250 vmax=self.zmax,
250 vmax=self.zmax,
251 cmap=self.cmaps[n],
251 cmap=self.cmaps[n],
252 norm=colors.LogNorm()
252 norm=colors.LogNorm()
253 )
253 )
254
254
255 else:
255 else:
256 if self.zlimits is not None:
256 if self.zlimits is not None:
257 self.zmin, self.zmax = self.zlimits[n]
257 self.zmin, self.zmax = self.zlimits[n]
258 ax.collections.remove(ax.collections[0])
258 ax.collections.remove(ax.collections[0])
259 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
259 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
260 vmin=self.zmin,
260 vmin=self.zmin,
261 vmax=self.zmax,
261 vmax=self.zmax,
262 cmap=self.cmaps[n],
262 cmap=self.cmaps[n],
263 norm=colors.LogNorm()
263 norm=colors.LogNorm()
264 )
264 )
265
265
266
266
267 class ETempRTIPlot(RTIPlot):
267 class ETempRTIPlot(RTIPlot):
268
268
269 '''
269 '''
270 Plot for Electron Temperature
270 Plot for Electron Temperature
271 '''
271 '''
272
272
273 CODE = 'ETemp'
273 CODE = 'ETemp'
274 colormap = 'jet'
274 colormap = 'jet'
275
275
276 def setup(self):
276 def setup(self):
277 self.xaxis = 'time'
277 self.xaxis = 'time'
278 self.ncols = 1
278 self.ncols = 1
279 self.nrows = self.data.shape(self.CODE)[0]
279 self.nrows = self.data.shape(self.CODE)[0]
280 self.nplots = self.nrows
280 self.nplots = self.nrows
281
281
282 self.ylabel = 'Range [km]'
282 self.ylabel = 'Range [km]'
283 self.xlabel = 'Time (LT)'
283 self.xlabel = 'Time (LT)'
284 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
284 self.plots_adjust.update({'wspace': 0.8, 'hspace':0.2, 'left': 0.2, 'right': 0.9, 'bottom': 0.18})
285 if self.CODE == 'ETemp':
285 if self.CODE == 'ETemp':
286 self.cb_label = 'Electron Temperature (K)'
286 self.cb_label = 'Electron Temperature (K)'
287 self.titles = ['Electron Temperature RTI']
287 self.titles = ['Electron Temperature RTI']
288 if self.CODE == 'ITemp':
288 if self.CODE == 'ITemp':
289 self.cb_label = 'Ion Temperature (K)'
289 self.cb_label = 'Ion Temperature (K)'
290 self.titles = ['Ion Temperature RTI']
290 self.titles = ['Ion Temperature RTI']
291 if self.CODE == 'HeFracLP':
291 if self.CODE == 'HeFracLP':
292 self.cb_label='He+ Fraction'
292 self.cb_label='He+ Fraction'
293 self.titles = ['He+ Fraction RTI']
293 self.titles = ['He+ Fraction RTI']
294 self.zmax=0.16
294 self.zmax=0.16
295 if self.CODE== 'HFracLP':
295 if self.CODE== 'HFracLP':
296 self.cb_label='H+ Fraction'
296 self.cb_label='H+ Fraction'
297 self.titles = ['H+ Fraction RTI']
297 self.titles = ['H+ Fraction RTI']
298
298
299 def update(self, dataOut):
299 def update(self, dataOut):
300
300
301 data = {}
301 data = {}
302 meta = {}
302 meta = {}
303
303
304 data['ETemp'] = dataOut.ElecTempFinal
304 data['ETemp'] = dataOut.ElecTempFinal
305
305
306 return data, meta
306 return data, meta
307
307
308 def plot(self):
308 def plot(self):
309
309
310 self.x = self.data.times
310 self.x = self.data.times
311 self.y = self.data.yrange
311 self.y = self.data.yrange
312
312
313
313
314 self.z = self.data[self.CODE]
314 self.z = self.data[self.CODE]
315
315
316 self.z = numpy.ma.masked_invalid(self.z)
316 self.z = numpy.ma.masked_invalid(self.z)
317
317
318 if self.decimation is None:
318 if self.decimation is None:
319 x, y, z = self.fill_gaps(self.x, self.y, self.z)
319 x, y, z = self.fill_gaps(self.x, self.y, self.z)
320 else:
320 else:
321 x, y, z = self.fill_gaps(*self.decimate())
321 x, y, z = self.fill_gaps(*self.decimate())
322
322
323 for n, ax in enumerate(self.axes):
323 for n, ax in enumerate(self.axes):
324
324
325 self.zmax = self.zmax if self.zmax is not None else numpy.max(
325 self.zmax = self.zmax if self.zmax is not None else numpy.max(
326 self.z[n])
326 self.z[n])
327 self.zmin = self.zmin if self.zmin is not None else numpy.min(
327 self.zmin = self.zmin if self.zmin is not None else numpy.min(
328 self.z[n])
328 self.z[n])
329
329
330 if ax.firsttime:
330 if ax.firsttime:
331
331
332 if self.zlimits is not None:
332 if self.zlimits is not None:
333 self.zmin, self.zmax = self.zlimits[n]
333 self.zmin, self.zmax = self.zlimits[n]
334
334
335 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
335 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
336 vmin=self.zmin,
336 vmin=self.zmin,
337 vmax=self.zmax,
337 vmax=self.zmax,
338 cmap=self.cmaps[n]
338 cmap=self.cmaps[n]
339 )
339 )
340 #plt.tight_layout()
340 #plt.tight_layout()
341
341
342 else:
342 else:
343 if self.zlimits is not None:
343 if self.zlimits is not None:
344 self.zmin, self.zmax = self.zlimits[n]
344 self.zmin, self.zmax = self.zlimits[n]
345 ax.collections.remove(ax.collections[0])
345 ax.collections.remove(ax.collections[0])
346 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
346 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
347 vmin=self.zmin,
347 vmin=self.zmin,
348 vmax=self.zmax,
348 vmax=self.zmax,
349 cmap=self.cmaps[n]
349 cmap=self.cmaps[n]
350 )
350 )
351
351
352
352
353 class ITempRTIPlot(ETempRTIPlot):
353 class ITempRTIPlot(ETempRTIPlot):
354
354
355 '''
355 '''
356 Plot for Ion Temperature
356 Plot for Ion Temperature
357 '''
357 '''
358
358
359 CODE = 'ITemp'
359 CODE = 'ITemp'
360 colormap = 'jet'
360 colormap = 'jet'
361 plot_name = 'Ion Temperature'
361 plot_name = 'Ion Temperature'
362
362
363 def update(self, dataOut):
363 def update(self, dataOut):
364
364
365 data = {}
365 data = {}
366 meta = {}
366 meta = {}
367
367
368 data['ITemp'] = dataOut.IonTempFinal
368 data['ITemp'] = dataOut.IonTempFinal
369
369
370 return data, meta
370 return data, meta
371
371
372
372
373 class HFracRTIPlot(ETempRTIPlot):
373 class HFracRTIPlot(ETempRTIPlot):
374
374
375 '''
375 '''
376 Plot for H+ LP
376 Plot for H+ LP
377 '''
377 '''
378
378
379 CODE = 'HFracLP'
379 CODE = 'HFracLP'
380 colormap = 'jet'
380 colormap = 'jet'
381 plot_name = 'H+ Frac'
381 plot_name = 'H+ Frac'
382
382
383 def update(self, dataOut):
383 def update(self, dataOut):
384
384
385 data = {}
385 data = {}
386 meta = {}
386 meta = {}
387 data['HFracLP'] = dataOut.PhyFinal
387 data['HFracLP'] = dataOut.PhyFinal
388
388
389 return data, meta
389 return data, meta
390
390
391
391
392 class HeFracRTIPlot(ETempRTIPlot):
392 class HeFracRTIPlot(ETempRTIPlot):
393
393
394 '''
394 '''
395 Plot for He+ LP
395 Plot for He+ LP
396 '''
396 '''
397
397
398 CODE = 'HeFracLP'
398 CODE = 'HeFracLP'
399 colormap = 'jet'
399 colormap = 'jet'
400 plot_name = 'He+ Frac'
400 plot_name = 'He+ Frac'
401
401
402 def update(self, dataOut):
402 def update(self, dataOut):
403
403
404 data = {}
404 data = {}
405 meta = {}
405 meta = {}
406 data['HeFracLP'] = dataOut.PheFinal
406 data['HeFracLP'] = dataOut.PheFinal
407
407
408 return data, meta
408 return data, meta
409
409
410
410
411 class TempsDPPlot(Plot):
411 class TempsDPPlot(Plot):
412 '''
412 '''
413 Plot for Electron - Ion Temperatures
413 Plot for Electron - Ion Temperatures
414 '''
414 '''
415
415
416 CODE = 'tempsDP'
416 CODE = 'tempsDP'
417 #plot_name = 'Temperatures'
417 #plot_name = 'Temperatures'
418 plot_type = 'scatterbuffer'
418 plot_type = 'scatterbuffer'
419
419
420 def setup(self):
420 def setup(self):
421
421
422 self.ncols = 1
422 self.ncols = 1
423 self.nrows = 1
423 self.nrows = 1
424 self.nplots = 1
424 self.nplots = 1
425 self.ylabel = 'Range [km]'
425 self.ylabel = 'Range [km]'
426 self.xlabel = 'Temperature (K)'
426 self.xlabel = 'Temperature (K)'
427 self.titles = ['Electron/Ion Temperatures']
427 self.titles = ['Electron/Ion Temperatures']
428 self.width = 3.5
428 self.width = 3.5
429 self.height = 5.5
429 self.height = 5.5
430 self.colorbar = False
430 self.colorbar = False
431 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
431 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
432
432
433 def update(self, dataOut):
433 def update(self, dataOut):
434 data = {}
434 data = {}
435 meta = {}
435 meta = {}
436
436
437 data['Te'] = dataOut.te2
437 data['Te'] = dataOut.te2
438 data['Ti'] = dataOut.ti2
438 data['Ti'] = dataOut.ti2
439 data['Te_error'] = dataOut.ete2
439 data['Te_error'] = dataOut.ete2
440 data['Ti_error'] = dataOut.eti2
440 data['Ti_error'] = dataOut.eti2
441
441
442 meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
442 meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
443
443
444 return data, meta
444 return data, meta
445
445
446 def plot(self):
446 def plot(self):
447
447
448 y = self.data.yrange
448 y = self.data.yrange
449
449
450 self.xmin = -100
450 self.xmin = -100
451 self.xmax = 5000
451 self.xmax = 5000
452
452
453 ax = self.axes[0]
453 ax = self.axes[0]
454
454
455 data = self.data[-1]
455 data = self.data[-1]
456
456
457 Te = data['Te']
457 Te = data['Te']
458 Ti = data['Ti']
458 Ti = data['Ti']
459 errTe = data['Te_error']
459 errTe = data['Te_error']
460 errTi = data['Ti_error']
460 errTi = data['Ti_error']
461
461
462 if ax.firsttime:
462 if ax.firsttime:
463 ax.errorbar(Te, y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
463 ax.errorbar(Te, y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
464 ax.errorbar(Ti, y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
464 ax.errorbar(Ti, y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
465 plt.legend(loc='lower right')
465 plt.legend(loc='lower right')
466 self.ystep_given = 50
466 self.ystep_given = 50
467 ax.yaxis.set_minor_locator(MultipleLocator(15))
467 ax.yaxis.set_minor_locator(MultipleLocator(15))
468 ax.grid(which='minor')
468 ax.grid(which='minor')
469
469
470 else:
470 else:
471 self.clear_figures()
471 self.clear_figures()
472 ax.errorbar(Te, y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
472 ax.errorbar(Te, y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
473 ax.errorbar(Ti, y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
473 ax.errorbar(Ti, y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
474 plt.legend(loc='lower right')
474 plt.legend(loc='lower right')
475 ax.yaxis.set_minor_locator(MultipleLocator(15))
475 ax.yaxis.set_minor_locator(MultipleLocator(15))
476
476
477
477
478 class TempsHPPlot(Plot):
478 class TempsHPPlot(Plot):
479 '''
479 '''
480 Plot for Temperatures Hybrid Experiment
480 Plot for Temperatures Hybrid Experiment
481 '''
481 '''
482
482
483 CODE = 'temps_LP'
483 CODE = 'temps_LP'
484 #plot_name = 'Temperatures'
484 #plot_name = 'Temperatures'
485 plot_type = 'scatterbuffer'
485 plot_type = 'scatterbuffer'
486
486
487
487
488 def setup(self):
488 def setup(self):
489
489
490 self.ncols = 1
490 self.ncols = 1
491 self.nrows = 1
491 self.nrows = 1
492 self.nplots = 1
492 self.nplots = 1
493 self.ylabel = 'Range [km]'
493 self.ylabel = 'Range [km]'
494 self.xlabel = 'Temperature (K)'
494 self.xlabel = 'Temperature (K)'
495 self.titles = ['Electron/Ion Temperatures']
495 self.titles = ['Electron/Ion Temperatures']
496 self.width = 3.5
496 self.width = 3.5
497 self.height = 6.5
497 self.height = 6.5
498 self.colorbar = False
498 self.colorbar = False
499 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
499 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
500
500
501 def update(self, dataOut):
501 def update(self, dataOut):
502 data = {}
502 data = {}
503 meta = {}
503 meta = {}
504
504
505
505
506 data['Te'] = numpy.concatenate((dataOut.te2[:dataOut.cut],dataOut.te[dataOut.cut:]))
506 data['Te'] = numpy.concatenate((dataOut.te2[:dataOut.cut],dataOut.te[dataOut.cut:]))
507 data['Ti'] = numpy.concatenate((dataOut.ti2[:dataOut.cut],dataOut.ti[dataOut.cut:]))
507 data['Ti'] = numpy.concatenate((dataOut.ti2[:dataOut.cut],dataOut.ti[dataOut.cut:]))
508 data['Te_error'] = numpy.concatenate((dataOut.ete2[:dataOut.cut],dataOut.ete[dataOut.cut:]))
508 data['Te_error'] = numpy.concatenate((dataOut.ete2[:dataOut.cut],dataOut.ete[dataOut.cut:]))
509 data['Ti_error'] = numpy.concatenate((dataOut.eti2[:dataOut.cut],dataOut.eti[dataOut.cut:]))
509 data['Ti_error'] = numpy.concatenate((dataOut.eti2[:dataOut.cut],dataOut.eti[dataOut.cut:]))
510
510
511 meta['yrange'] = dataOut.heightList[0:dataOut.NACF]
511 meta['yrange'] = dataOut.heightList[0:dataOut.NACF]
512
512
513 return data, meta
513 return data, meta
514
514
515 def plot(self):
515 def plot(self):
516
516
517
517
518 self.y = self.data.yrange
518 self.y = self.data.yrange
519 self.xmin = -100
519 self.xmin = -100
520 self.xmax = 4500
520 self.xmax = 4500
521 ax = self.axes[0]
521 ax = self.axes[0]
522
522
523 data = self.data[-1]
523 data = self.data[-1]
524
524
525 Te = data['Te']
525 Te = data['Te']
526 Ti = data['Ti']
526 Ti = data['Ti']
527 errTe = data['Te_error']
527 errTe = data['Te_error']
528 errTi = data['Ti_error']
528 errTi = data['Ti_error']
529
529
530 if ax.firsttime:
530 if ax.firsttime:
531
531
532 ax.errorbar(Te, self.y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
532 ax.errorbar(Te, self.y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
533 ax.errorbar(Ti, self.y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
533 ax.errorbar(Ti, self.y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
534 plt.legend(loc='lower right')
534 plt.legend(loc='lower right')
535 self.ystep_given = 200
535 self.ystep_given = 200
536 ax.yaxis.set_minor_locator(MultipleLocator(15))
536 ax.yaxis.set_minor_locator(MultipleLocator(15))
537 ax.grid(which='minor')
537 ax.grid(which='minor')
538
538
539 else:
539 else:
540 self.clear_figures()
540 self.clear_figures()
541 ax.errorbar(Te, self.y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
541 ax.errorbar(Te, self.y, xerr=errTe, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='Te')
542 ax.errorbar(Ti, self.y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
542 ax.errorbar(Ti, self.y, fmt='k^', xerr=errTi,elinewidth=1.0,color='b',linewidth=2.0, label='Ti')
543 plt.legend(loc='lower right')
543 plt.legend(loc='lower right')
544 ax.yaxis.set_minor_locator(MultipleLocator(15))
544 ax.yaxis.set_minor_locator(MultipleLocator(15))
545 ax.grid(which='minor')
545 ax.grid(which='minor')
546
546
547
547
548 class FracsHPPlot(Plot):
548 class FracsHPPlot(Plot):
549 '''
549 '''
550 Plot for Composition LP
550 Plot for Composition LP
551 '''
551 '''
552
552
553 CODE = 'fracs_LP'
553 CODE = 'fracs_LP'
554 plot_type = 'scatterbuffer'
554 plot_type = 'scatterbuffer'
555
555
556
556
557 def setup(self):
557 def setup(self):
558
558
559 self.ncols = 1
559 self.ncols = 1
560 self.nrows = 1
560 self.nrows = 1
561 self.nplots = 1
561 self.nplots = 1
562 self.ylabel = 'Range [km]'
562 self.ylabel = 'Range [km]'
563 self.xlabel = 'Frac'
563 self.xlabel = 'Frac'
564 self.titles = ['Composition']
564 self.titles = ['Composition']
565 self.width = 3.5
565 self.width = 3.5
566 self.height = 6.5
566 self.height = 6.5
567 self.colorbar = False
567 self.colorbar = False
568 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
568 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
569
569
570 def update(self, dataOut):
570 def update(self, dataOut):
571 data = {}
571 data = {}
572 meta = {}
572 meta = {}
573
573
574 #aux_nan=numpy.zeros(dataOut.cut,'float32')
574 #aux_nan=numpy.zeros(dataOut.cut,'float32')
575 #aux_nan[:]=numpy.nan
575 #aux_nan[:]=numpy.nan
576 #data['ph'] = numpy.concatenate((aux_nan,dataOut.ph[dataOut.cut:]))
576 #data['ph'] = numpy.concatenate((aux_nan,dataOut.ph[dataOut.cut:]))
577 #data['eph'] = numpy.concatenate((aux_nan,dataOut.eph[dataOut.cut:]))
577 #data['eph'] = numpy.concatenate((aux_nan,dataOut.eph[dataOut.cut:]))
578
578
579 data['ph'] = dataOut.ph[dataOut.cut:]
579 data['ph'] = dataOut.ph[dataOut.cut:]
580 data['eph'] = dataOut.eph[dataOut.cut:]
580 data['eph'] = dataOut.eph[dataOut.cut:]
581 data['phe'] = dataOut.phe[dataOut.cut:]
581 data['phe'] = dataOut.phe[dataOut.cut:]
582 data['ephe'] = dataOut.ephe[dataOut.cut:]
582 data['ephe'] = dataOut.ephe[dataOut.cut:]
583
583
584 data['cut'] = dataOut.cut
584 data['cut'] = dataOut.cut
585
585
586 meta['yrange'] = dataOut.heightList[0:dataOut.NACF]
586 meta['yrange'] = dataOut.heightList[0:dataOut.NACF]
587
587
588
588
589 return data, meta
589 return data, meta
590
590
591 def plot(self):
591 def plot(self):
592
592
593 data = self.data[-1]
593 data = self.data[-1]
594
594
595 ph = data['ph']
595 ph = data['ph']
596 eph = data['eph']
596 eph = data['eph']
597 phe = data['phe']
597 phe = data['phe']
598 ephe = data['ephe']
598 ephe = data['ephe']
599 cut = data['cut']
599 cut = data['cut']
600 self.y = self.data.yrange
600 self.y = self.data.yrange
601
601
602 self.xmin = 0
602 self.xmin = 0
603 self.xmax = 1
603 self.xmax = 1
604 ax = self.axes[0]
604 ax = self.axes[0]
605
605
606 if ax.firsttime:
606 if ax.firsttime:
607
607
608 ax.errorbar(ph, self.y[cut:], xerr=eph, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='H+')
608 ax.errorbar(ph, self.y[cut:], xerr=eph, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='H+')
609 ax.errorbar(phe, self.y[cut:], fmt='k^', xerr=ephe,elinewidth=1.0,color='b',linewidth=2.0, label='He+')
609 ax.errorbar(phe, self.y[cut:], fmt='k^', xerr=ephe,elinewidth=1.0,color='b',linewidth=2.0, label='He+')
610 plt.legend(loc='lower right')
610 plt.legend(loc='lower right')
611 self.xstep_given = 0.2
611 self.xstep_given = 0.2
612 self.ystep_given = 200
612 self.ystep_given = 200
613 ax.yaxis.set_minor_locator(MultipleLocator(15))
613 ax.yaxis.set_minor_locator(MultipleLocator(15))
614 ax.grid(which='minor')
614 ax.grid(which='minor')
615
615
616 else:
616 else:
617 self.clear_figures()
617 self.clear_figures()
618 ax.errorbar(ph, self.y[cut:], xerr=eph, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='H+')
618 ax.errorbar(ph, self.y[cut:], xerr=eph, fmt='r^',elinewidth=1.0,color='b',linewidth=2.0, label='H+')
619 ax.errorbar(phe, self.y[cut:], fmt='k^', xerr=ephe,elinewidth=1.0,color='b',linewidth=2.0, label='He+')
619 ax.errorbar(phe, self.y[cut:], fmt='k^', xerr=ephe,elinewidth=1.0,color='b',linewidth=2.0, label='He+')
620 plt.legend(loc='lower right')
620 plt.legend(loc='lower right')
621 ax.yaxis.set_minor_locator(MultipleLocator(15))
621 ax.yaxis.set_minor_locator(MultipleLocator(15))
622 ax.grid(which='minor')
622 ax.grid(which='minor')
623
623
624 class EDensityPlot(Plot):
624 class EDensityPlot(Plot):
625 '''
625 '''
626 Plot for electron density
626 Plot for electron density
627 '''
627 '''
628
628
629 CODE = 'den'
629 CODE = 'den'
630 #plot_name = 'Electron Density'
630 #plot_name = 'Electron Density'
631 plot_type = 'scatterbuffer'
631 plot_type = 'scatterbuffer'
632
632
633 def setup(self):
633 def setup(self):
634
634
635 self.ncols = 1
635 self.ncols = 1
636 self.nrows = 1
636 self.nrows = 1
637 self.nplots = 1
637 self.nplots = 1
638 self.ylabel = 'Range [km]'
638 self.ylabel = 'Range [km]'
639 self.xlabel = r'$\mathrm{N_e}$ Electron Density ($\mathrm{1/cm^3}$)'
639 self.xlabel = r'$\mathrm{N_e}$ Electron Density ($\mathrm{1/cm^3}$)'
640 self.titles = ['Electron Density']
640 self.titles = ['Electron Density']
641 self.width = 3.5
641 self.width = 3.5
642 self.height = 5.5
642 self.height = 5.5
643 self.colorbar = False
643 self.colorbar = False
644 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
644 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
645
645
646 def update(self, dataOut):
646 def update(self, dataOut):
647 data = {}
647 data = {}
648 meta = {}
648 meta = {}
649
649
650 data['den_power'] = dataOut.ph2[:dataOut.NSHTS]
650 data['den_power'] = dataOut.ph2[:dataOut.NSHTS]
651 data['den_Faraday'] = dataOut.dphi[:dataOut.NSHTS]
651 data['den_Faraday'] = dataOut.dphi[:dataOut.NSHTS]
652 data['den_error'] = dataOut.sdp2[:dataOut.NSHTS]
652 data['den_error'] = dataOut.sdp2[:dataOut.NSHTS]
653 #data['err_Faraday'] = dataOut.sdn1[:dataOut.NSHTS]
653 #data['err_Faraday'] = dataOut.sdn1[:dataOut.NSHTS]
654
654
655 data['NSHTS'] = dataOut.NSHTS
655 data['NSHTS'] = dataOut.NSHTS
656
656
657 meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
657 meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
658
658
659 return data, meta
659 return data, meta
660
660
661 def plot(self):
661 def plot(self):
662
662
663 y = self.data.yrange
663 y = self.data.yrange
664
664
665 self.xmin = 1e3
665 self.xmin = 1e3
666 self.xmax = 1e7
666 self.xmax = 1e7
667
667
668 ax = self.axes[0]
668 ax = self.axes[0]
669
669
670 data = self.data[-1]
670 data = self.data[-1]
671
671
672 DenPow = data['den_power']
672 DenPow = data['den_power']
673 DenFar = data['den_Faraday']
673 DenFar = data['den_Faraday']
674 errDenPow = data['den_error']
674 errDenPow = data['den_error']
675 #errFaraday = data['err_Faraday']
675 #errFaraday = data['err_Faraday']
676
676
677 NSHTS = data['NSHTS']
677 NSHTS = data['NSHTS']
678
678
679 if self.CODE == 'denLP':
679 if self.CODE == 'denLP':
680 DenPowLP = data['den_LP']
680 DenPowLP = data['den_LP']
681 errDenPowLP = data['den_LP_error']
681 errDenPowLP = data['den_LP_error']
682 cut = data['cut']
682 cut = data['cut']
683
683
684 if ax.firsttime:
684 if ax.firsttime:
685 self.autoxticks=False
685 self.autoxticks=False
686 #ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
686 #ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
687 ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday',markersize=2)
687 ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday',markersize=2)
688 #ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power Profile',markersize=2)
688 #ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power Profile',markersize=2)
689 ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power',markersize=2)
689 ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power',markersize=2)
690
690
691 if self.CODE=='denLP':
691 if self.CODE=='denLP':
692 ax.errorbar(DenPowLP[cut:], y[cut:], xerr=errDenPowLP[cut:], fmt='r^-',elinewidth=1.0,color='r',linewidth=1.0, label='LP Profile',markersize=2)
692 ax.errorbar(DenPowLP[cut:], y[cut:], xerr=errDenPowLP[cut:], fmt='r^-',elinewidth=1.0,color='r',linewidth=1.0, label='LP Profile',markersize=2)
693
693
694 plt.legend(loc='upper left',fontsize=8.5)
694 plt.legend(loc='upper left',fontsize=8.5)
695 #plt.legend(loc='lower left',fontsize=8.5)
695 #plt.legend(loc='lower left',fontsize=8.5)
696 ax.set_xscale("log", nonposx='clip')
696 ax.set_xscale("log", nonposx='clip')
697 grid_y_ticks=numpy.arange(numpy.nanmin(y),numpy.nanmax(y),50)
697 grid_y_ticks=numpy.arange(numpy.nanmin(y),numpy.nanmax(y),50)
698 self.ystep_given=100
698 self.ystep_given=100
699 if self.CODE=='denLP':
699 if self.CODE=='denLP':
700 self.ystep_given=200
700 self.ystep_given=200
701 ax.set_yticks(grid_y_ticks,minor=True)
701 ax.set_yticks(grid_y_ticks,minor=True)
702 ax.grid(which='minor')
702 ax.grid(which='minor')
703
703
704 else:
704 else:
705 dataBefore = self.data[-2]
705 dataBefore = self.data[-2]
706 DenPowBefore = dataBefore['den_power']
706 DenPowBefore = dataBefore['den_power']
707 self.clear_figures()
707 self.clear_figures()
708 #ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
708 #ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday Profile',markersize=2)
709 ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday',markersize=2)
709 ax.errorbar(DenFar, y[:NSHTS], xerr=1, fmt='h-',elinewidth=1.0,color='g',linewidth=1.0, label='Faraday',markersize=2)
710 #ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power Profile',markersize=2)
710 #ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power Profile',markersize=2)
711 ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power',markersize=2)
711 ax.errorbar(DenPow, y[:NSHTS], fmt='k^-', xerr=errDenPow,elinewidth=1.0,color='b',linewidth=1.0, label='Power',markersize=2)
712 ax.errorbar(DenPowBefore, y[:NSHTS], elinewidth=1.0,color='r',linewidth=0.5,linestyle="dashed")
712 ax.errorbar(DenPowBefore, y[:NSHTS], elinewidth=1.0,color='r',linewidth=0.5,linestyle="dashed")
713
713
714 if self.CODE=='denLP':
714 if self.CODE=='denLP':
715 ax.errorbar(DenPowLP[cut:], y[cut:], fmt='r^-', xerr=errDenPowLP[cut:],elinewidth=1.0,color='r',linewidth=1.0, label='LP Profile',markersize=2)
715 ax.errorbar(DenPowLP[cut:], y[cut:], fmt='r^-', xerr=errDenPowLP[cut:],elinewidth=1.0,color='r',linewidth=1.0, label='LP Profile',markersize=2)
716
716
717 ax.set_xscale("log", nonposx='clip')
717 ax.set_xscale("log", nonposx='clip')
718 grid_y_ticks=numpy.arange(numpy.nanmin(y),numpy.nanmax(y),50)
718 grid_y_ticks=numpy.arange(numpy.nanmin(y),numpy.nanmax(y),50)
719 ax.set_yticks(grid_y_ticks,minor=True)
719 ax.set_yticks(grid_y_ticks,minor=True)
720 ax.grid(which='minor')
720 ax.grid(which='minor')
721 plt.legend(loc='upper left',fontsize=8.5)
721 plt.legend(loc='upper left',fontsize=8.5)
722 #plt.legend(loc='lower left',fontsize=8.5)
722 #plt.legend(loc='lower left',fontsize=8.5)
723
723
724 class FaradayAnglePlot(Plot):
724 class FaradayAnglePlot(Plot):
725 '''
725 '''
726 Plot for electron density
726 Plot for electron density
727 '''
727 '''
728
728
729 CODE = 'angle'
729 CODE = 'angle'
730 plot_name = 'Faraday Angle'
730 plot_name = 'Faraday Angle'
731 plot_type = 'scatterbuffer'
731 plot_type = 'scatterbuffer'
732
732
733 def setup(self):
733 def setup(self):
734
734
735 self.ncols = 1
735 self.ncols = 1
736 self.nrows = 1
736 self.nrows = 1
737 self.nplots = 1
737 self.nplots = 1
738 self.ylabel = 'Range [km]'
738 self.ylabel = 'Range [km]'
739 self.xlabel = 'Faraday Angle (º)'
739 self.xlabel = 'Faraday Angle (º)'
740 self.titles = ['Electron Density']
740 self.titles = ['Electron Density']
741 self.width = 3.5
741 self.width = 3.5
742 self.height = 5.5
742 self.height = 5.5
743 self.colorbar = False
743 self.colorbar = False
744 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
744 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
745
745
746 def update(self, dataOut):
746 def update(self, dataOut):
747 data = {}
747 data = {}
748 meta = {}
748 meta = {}
749
749
750 data['angle'] = numpy.degrees(dataOut.phi)
750 data['angle'] = numpy.degrees(dataOut.phi)
751 #'''
751 #'''
752 print(dataOut.phi_uwrp)
752 #print(dataOut.phi_uwrp)
753 print(data['angle'])
753 #print(data['angle'])
754 exit(1)
754 #exit(1)
755 #'''
755 #'''
756 data['dphi'] = dataOut.dphi_uc*10
756 data['dphi'] = dataOut.dphi_uc*10
757 #print(dataOut.dphi)
757 #print(dataOut.dphi)
758
758
759 #data['NSHTS'] = dataOut.NSHTS
759 #data['NSHTS'] = dataOut.NSHTS
760
760
761 #meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
761 #meta['yrange'] = dataOut.heightList[0:dataOut.NSHTS]
762
762
763 return data, meta
763 return data, meta
764
764
765 def plot(self):
765 def plot(self):
766
766
767 data = self.data[-1]
767 data = self.data[-1]
768 self.x = data[self.CODE]
768 self.x = data[self.CODE]
769 dphi = data['dphi']
769 dphi = data['dphi']
770 self.y = self.data.yrange
770 self.y = self.data.yrange
771 self.xmin = -360#-180
771 self.xmin = -360#-180
772 self.xmax = 360#180
772 self.xmax = 360#180
773 ax = self.axes[0]
773 ax = self.axes[0]
774
774
775 if ax.firsttime:
775 if ax.firsttime:
776 self.autoxticks=False
776 self.autoxticks=False
777 #if self.CODE=='den':
777 #if self.CODE=='den':
778 ax.plot(self.x, self.y,marker='o',color='g',linewidth=1.0,markersize=2)
778 ax.plot(self.x, self.y,marker='o',color='g',linewidth=1.0,markersize=2)
779 ax.plot(dphi, self.y,marker='o',color='blue',linewidth=1.0,markersize=2)
779 ax.plot(dphi, self.y,marker='o',color='blue',linewidth=1.0,markersize=2)
780
780
781 grid_y_ticks=numpy.arange(numpy.nanmin(self.y),numpy.nanmax(self.y),50)
781 grid_y_ticks=numpy.arange(numpy.nanmin(self.y),numpy.nanmax(self.y),50)
782 self.ystep_given=100
782 self.ystep_given=100
783 if self.CODE=='denLP':
783 if self.CODE=='denLP':
784 self.ystep_given=200
784 self.ystep_given=200
785 ax.set_yticks(grid_y_ticks,minor=True)
785 ax.set_yticks(grid_y_ticks,minor=True)
786 ax.grid(which='minor')
786 ax.grid(which='minor')
787 #plt.tight_layout()
787 #plt.tight_layout()
788 else:
788 else:
789
789
790 self.clear_figures()
790 self.clear_figures()
791 #if self.CODE=='den':
791 #if self.CODE=='den':
792 #print(numpy.shape(self.x))
792 #print(numpy.shape(self.x))
793 ax.plot(self.x, self.y, marker='o',color='g',linewidth=1.0, markersize=2)
793 ax.plot(self.x, self.y, marker='o',color='g',linewidth=1.0, markersize=2)
794 ax.plot(dphi, self.y,marker='o',color='blue',linewidth=1.0,markersize=2)
794 ax.plot(dphi, self.y,marker='o',color='blue',linewidth=1.0,markersize=2)
795
795
796 grid_y_ticks=numpy.arange(numpy.nanmin(self.y),numpy.nanmax(self.y),50)
796 grid_y_ticks=numpy.arange(numpy.nanmin(self.y),numpy.nanmax(self.y),50)
797 ax.set_yticks(grid_y_ticks,minor=True)
797 ax.set_yticks(grid_y_ticks,minor=True)
798 ax.grid(which='minor')
798 ax.grid(which='minor')
799
799
800 class EDensityHPPlot(EDensityPlot):
800 class EDensityHPPlot(EDensityPlot):
801
801
802 '''
802 '''
803 Plot for Electron Density Hybrid Experiment
803 Plot for Electron Density Hybrid Experiment
804 '''
804 '''
805
805
806 CODE = 'denLP'
806 CODE = 'denLP'
807 plot_name = 'Electron Density'
807 plot_name = 'Electron Density'
808 plot_type = 'scatterbuffer'
808 plot_type = 'scatterbuffer'
809
809
810 def update(self, dataOut):
810 def update(self, dataOut):
811 data = {}
811 data = {}
812 meta = {}
812 meta = {}
813
813
814 data['den_power'] = dataOut.ph2[:dataOut.NSHTS]
814 data['den_power'] = dataOut.ph2[:dataOut.NSHTS]
815 data['den_Faraday']=dataOut.dphi[:dataOut.NSHTS]
815 data['den_Faraday']=dataOut.dphi[:dataOut.NSHTS]
816 data['den_error']=dataOut.sdp2[:dataOut.NSHTS]
816 data['den_error']=dataOut.sdp2[:dataOut.NSHTS]
817 data['den_LP']=dataOut.ne[:dataOut.NACF]
817 data['den_LP']=dataOut.ne[:dataOut.NACF]
818 data['den_LP_error']=dataOut.ene[:dataOut.NACF]*dataOut.ne[:dataOut.NACF]*0.434
818 data['den_LP_error']=dataOut.ene[:dataOut.NACF]*dataOut.ne[:dataOut.NACF]*0.434
819 #self.ene=10**dataOut.ene[:dataOut.NACF]
819 #self.ene=10**dataOut.ene[:dataOut.NACF]
820 data['NSHTS']=dataOut.NSHTS
820 data['NSHTS']=dataOut.NSHTS
821 data['cut']=dataOut.cut
821 data['cut']=dataOut.cut
822
822
823 return data, meta
823 return data, meta
824
824
825
825
826 class ACFsPlot(Plot):
826 class ACFsPlot(Plot):
827 '''
827 '''
828 Plot for ACFs Double Pulse Experiment
828 Plot for ACFs Double Pulse Experiment
829 '''
829 '''
830
830
831 CODE = 'acfs'
831 CODE = 'acfs'
832 #plot_name = 'ACF'
832 #plot_name = 'ACF'
833 plot_type = 'scatterbuffer'
833 plot_type = 'scatterbuffer'
834
834
835
835
836 def setup(self):
836 def setup(self):
837 self.ncols = 1
837 self.ncols = 1
838 self.nrows = 1
838 self.nrows = 1
839 self.nplots = 1
839 self.nplots = 1
840 self.ylabel = 'Range [km]'
840 self.ylabel = 'Range [km]'
841 self.xlabel = 'Lag (ms)'
841 self.xlabel = 'Lag (ms)'
842 self.titles = ['ACFs']
842 self.titles = ['ACFs']
843 self.width = 3.5
843 self.width = 3.5
844 self.height = 5.5
844 self.height = 5.5
845 self.colorbar = False
845 self.colorbar = False
846 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
846 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
847
847
848 def update(self, dataOut):
848 def update(self, dataOut):
849 data = {}
849 data = {}
850 meta = {}
850 meta = {}
851
851
852 data['ACFs'] = dataOut.acfs_to_plot
852 data['ACFs'] = dataOut.acfs_to_plot
853 data['ACFs_error'] = dataOut.acfs_error_to_plot
853 data['ACFs_error'] = dataOut.acfs_error_to_plot
854 data['lags'] = dataOut.lags_to_plot
854 data['lags'] = dataOut.lags_to_plot
855 data['Lag_contaminated_1'] = dataOut.x_igcej_to_plot
855 data['Lag_contaminated_1'] = dataOut.x_igcej_to_plot
856 data['Lag_contaminated_2'] = dataOut.x_ibad_to_plot
856 data['Lag_contaminated_2'] = dataOut.x_ibad_to_plot
857 data['Height_contaminated_1'] = dataOut.y_igcej_to_plot
857 data['Height_contaminated_1'] = dataOut.y_igcej_to_plot
858 data['Height_contaminated_2'] = dataOut.y_ibad_to_plot
858 data['Height_contaminated_2'] = dataOut.y_ibad_to_plot
859
859
860 meta['yrange'] = numpy.array([])
860 meta['yrange'] = numpy.array([])
861 #meta['NSHTS'] = dataOut.NSHTS
861 #meta['NSHTS'] = dataOut.NSHTS
862 #meta['DPL'] = dataOut.DPL
862 #meta['DPL'] = dataOut.DPL
863 data['NSHTS'] = dataOut.NSHTS #This is metadata
863 data['NSHTS'] = dataOut.NSHTS #This is metadata
864 data['DPL'] = dataOut.DPL #This is metadata
864 data['DPL'] = dataOut.DPL #This is metadata
865
865
866 return data, meta
866 return data, meta
867
867
868 def plot(self):
868 def plot(self):
869
869
870 data = self.data[-1]
870 data = self.data[-1]
871 #NSHTS = self.meta['NSHTS']
871 #NSHTS = self.meta['NSHTS']
872 #DPL = self.meta['DPL']
872 #DPL = self.meta['DPL']
873 NSHTS = data['NSHTS'] #This is metadata
873 NSHTS = data['NSHTS'] #This is metadata
874 DPL = data['DPL'] #This is metadata
874 DPL = data['DPL'] #This is metadata
875
875
876 lags = data['lags']
876 lags = data['lags']
877 ACFs = data['ACFs']
877 ACFs = data['ACFs']
878 errACFs = data['ACFs_error']
878 errACFs = data['ACFs_error']
879 BadLag1 = data['Lag_contaminated_1']
879 BadLag1 = data['Lag_contaminated_1']
880 BadLag2 = data['Lag_contaminated_2']
880 BadLag2 = data['Lag_contaminated_2']
881 BadHei1 = data['Height_contaminated_1']
881 BadHei1 = data['Height_contaminated_1']
882 BadHei2 = data['Height_contaminated_2']
882 BadHei2 = data['Height_contaminated_2']
883
883
884 self.xmin = 0.0
884 self.xmin = 0.0
885 self.xmax = 2.0
885 self.xmax = 2.0
886 self.y = ACFs
886 self.y = ACFs
887
887
888 ax = self.axes[0]
888 ax = self.axes[0]
889
889
890 if ax.firsttime:
890 if ax.firsttime:
891
891
892 for i in range(NSHTS):
892 for i in range(NSHTS):
893 x_aux = numpy.isfinite(lags[i,:])
893 x_aux = numpy.isfinite(lags[i,:])
894 y_aux = numpy.isfinite(ACFs[i,:])
894 y_aux = numpy.isfinite(ACFs[i,:])
895 yerr_aux = numpy.isfinite(errACFs[i,:])
895 yerr_aux = numpy.isfinite(errACFs[i,:])
896 x_igcej_aux = numpy.isfinite(BadLag1[i,:])
896 x_igcej_aux = numpy.isfinite(BadLag1[i,:])
897 y_igcej_aux = numpy.isfinite(BadHei1[i,:])
897 y_igcej_aux = numpy.isfinite(BadHei1[i,:])
898 x_ibad_aux = numpy.isfinite(BadLag2[i,:])
898 x_ibad_aux = numpy.isfinite(BadLag2[i,:])
899 y_ibad_aux = numpy.isfinite(BadHei2[i,:])
899 y_ibad_aux = numpy.isfinite(BadHei2[i,:])
900 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
900 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
901 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',marker='o',linewidth=1.0,markersize=2)
901 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',marker='o',linewidth=1.0,markersize=2)
902 ax.plot(BadLag1[i,x_igcej_aux],BadHei1[i,y_igcej_aux],'x',color='red',markersize=2)
902 ax.plot(BadLag1[i,x_igcej_aux],BadHei1[i,y_igcej_aux],'x',color='red',markersize=2)
903 ax.plot(BadLag2[i,x_ibad_aux],BadHei2[i,y_ibad_aux],'X',color='red',markersize=2)
903 ax.plot(BadLag2[i,x_ibad_aux],BadHei2[i,y_ibad_aux],'X',color='red',markersize=2)
904
904
905 self.xstep_given = (self.xmax-self.xmin)/(DPL-1)
905 self.xstep_given = (self.xmax-self.xmin)/(DPL-1)
906 self.ystep_given = 50
906 self.ystep_given = 50
907 ax.yaxis.set_minor_locator(MultipleLocator(15))
907 ax.yaxis.set_minor_locator(MultipleLocator(15))
908 ax.grid(which='minor')
908 ax.grid(which='minor')
909
909
910 else:
910 else:
911 self.clear_figures()
911 self.clear_figures()
912 for i in range(NSHTS):
912 for i in range(NSHTS):
913 x_aux = numpy.isfinite(lags[i,:])
913 x_aux = numpy.isfinite(lags[i,:])
914 y_aux = numpy.isfinite(ACFs[i,:])
914 y_aux = numpy.isfinite(ACFs[i,:])
915 yerr_aux = numpy.isfinite(errACFs[i,:])
915 yerr_aux = numpy.isfinite(errACFs[i,:])
916 x_igcej_aux = numpy.isfinite(BadLag1[i,:])
916 x_igcej_aux = numpy.isfinite(BadLag1[i,:])
917 y_igcej_aux = numpy.isfinite(BadHei1[i,:])
917 y_igcej_aux = numpy.isfinite(BadHei1[i,:])
918 x_ibad_aux = numpy.isfinite(BadLag2[i,:])
918 x_ibad_aux = numpy.isfinite(BadLag2[i,:])
919 y_ibad_aux = numpy.isfinite(BadHei2[i,:])
919 y_ibad_aux = numpy.isfinite(BadHei2[i,:])
920 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
920 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
921 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],linewidth=1.0,markersize=2,color='b',marker='o')
921 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],linewidth=1.0,markersize=2,color='b',marker='o')
922 ax.plot(BadLag1[i,x_igcej_aux],BadHei1[i,y_igcej_aux],'x',color='red',markersize=2)
922 ax.plot(BadLag1[i,x_igcej_aux],BadHei1[i,y_igcej_aux],'x',color='red',markersize=2)
923 ax.plot(BadLag2[i,x_ibad_aux],BadHei2[i,y_ibad_aux],'X',color='red',markersize=2)
923 ax.plot(BadLag2[i,x_ibad_aux],BadHei2[i,y_ibad_aux],'X',color='red',markersize=2)
924 ax.yaxis.set_minor_locator(MultipleLocator(15))
924 ax.yaxis.set_minor_locator(MultipleLocator(15))
925
925
926 class ACFsLPPlot(Plot):
926 class ACFsLPPlot(Plot):
927 '''
927 '''
928 Plot for ACFs Double Pulse Experiment
928 Plot for ACFs Double Pulse Experiment
929 '''
929 '''
930
930
931 CODE = 'acfs_LP'
931 CODE = 'acfs_LP'
932 #plot_name = 'ACF'
932 #plot_name = 'ACF'
933 plot_type = 'scatterbuffer'
933 plot_type = 'scatterbuffer'
934
934
935
935
936 def setup(self):
936 def setup(self):
937 self.ncols = 1
937 self.ncols = 1
938 self.nrows = 1
938 self.nrows = 1
939 self.nplots = 1
939 self.nplots = 1
940 self.ylabel = 'Range [km]'
940 self.ylabel = 'Range [km]'
941 self.xlabel = 'Lag (ms)'
941 self.xlabel = 'Lag (ms)'
942 self.titles = ['ACFs']
942 self.titles = ['ACFs']
943 self.width = 3.5
943 self.width = 3.5
944 self.height = 5.5
944 self.height = 5.5
945 self.colorbar = False
945 self.colorbar = False
946 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
946 self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
947
947
948 def update(self, dataOut):
948 def update(self, dataOut):
949 data = {}
949 data = {}
950 meta = {}
950 meta = {}
951
951
952 aux=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
952 aux=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
953 errors=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
953 errors=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
954 lags_LP_to_plot=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
954 lags_LP_to_plot=numpy.zeros((dataOut.NACF,dataOut.IBITS),'float32')
955
955
956 for i in range(dataOut.NACF):
956 for i in range(dataOut.NACF):
957 for j in range(dataOut.IBITS):
957 for j in range(dataOut.IBITS):
958 if numpy.abs(dataOut.errors[j,i]/dataOut.output_LP_integrated.real[0,i,0])<1.0:
958 if numpy.abs(dataOut.errors[j,i]/dataOut.output_LP_integrated.real[0,i,0])<1.0:
959 aux[i,j]=dataOut.output_LP_integrated.real[j,i,0]/dataOut.output_LP_integrated.real[0,i,0]
959 aux[i,j]=dataOut.output_LP_integrated.real[j,i,0]/dataOut.output_LP_integrated.real[0,i,0]
960 aux[i,j]=max(min(aux[i,j],1.0),-1.0)*dataOut.DH+dataOut.heightList[i]
960 aux[i,j]=max(min(aux[i,j],1.0),-1.0)*dataOut.DH+dataOut.heightList[i]
961 lags_LP_to_plot[i,j]=dataOut.lags_LP[j]
961 lags_LP_to_plot[i,j]=dataOut.lags_LP[j]
962 errors[i,j]=dataOut.errors[j,i]/dataOut.output_LP_integrated.real[0,i,0]*dataOut.DH
962 errors[i,j]=dataOut.errors[j,i]/dataOut.output_LP_integrated.real[0,i,0]*dataOut.DH
963 else:
963 else:
964 aux[i,j]=numpy.nan
964 aux[i,j]=numpy.nan
965 lags_LP_to_plot[i,j]=numpy.nan
965 lags_LP_to_plot[i,j]=numpy.nan
966 errors[i,j]=numpy.nan
966 errors[i,j]=numpy.nan
967
967
968 data['ACFs'] = aux
968 data['ACFs'] = aux
969 data['ACFs_error'] = errors
969 data['ACFs_error'] = errors
970 data['lags'] = lags_LP_to_plot
970 data['lags'] = lags_LP_to_plot
971
971
972 meta['yrange'] = numpy.array([])
972 meta['yrange'] = numpy.array([])
973 #meta['NACF'] = dataOut.NACF
973 #meta['NACF'] = dataOut.NACF
974 #meta['NLAG'] = dataOut.NLAG
974 #meta['NLAG'] = dataOut.NLAG
975 data['NACF'] = dataOut.NACF #This is metadata
975 data['NACF'] = dataOut.NACF #This is metadata
976 data['NLAG'] = dataOut.NLAG #This is metadata
976 data['NLAG'] = dataOut.NLAG #This is metadata
977
977
978 return data, meta
978 return data, meta
979
979
980 def plot(self):
980 def plot(self):
981
981
982 data = self.data[-1]
982 data = self.data[-1]
983 #NACF = self.meta['NACF']
983 #NACF = self.meta['NACF']
984 #NLAG = self.meta['NLAG']
984 #NLAG = self.meta['NLAG']
985 NACF = data['NACF'] #This is metadata
985 NACF = data['NACF'] #This is metadata
986 NLAG = data['NLAG'] #This is metadata
986 NLAG = data['NLAG'] #This is metadata
987
987
988 lags = data['lags']
988 lags = data['lags']
989 ACFs = data['ACFs']
989 ACFs = data['ACFs']
990 errACFs = data['ACFs_error']
990 errACFs = data['ACFs_error']
991
991
992 self.xmin = 0.0
992 self.xmin = 0.0
993 self.xmax = 1.5
993 self.xmax = 1.5
994
994
995 self.y = ACFs
995 self.y = ACFs
996
996
997 ax = self.axes[0]
997 ax = self.axes[0]
998
998
999 if ax.firsttime:
999 if ax.firsttime:
1000
1000
1001 for i in range(NACF):
1001 for i in range(NACF):
1002 x_aux = numpy.isfinite(lags[i,:])
1002 x_aux = numpy.isfinite(lags[i,:])
1003 y_aux = numpy.isfinite(ACFs[i,:])
1003 y_aux = numpy.isfinite(ACFs[i,:])
1004 yerr_aux = numpy.isfinite(errACFs[i,:])
1004 yerr_aux = numpy.isfinite(errACFs[i,:])
1005
1005
1006 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
1006 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
1007 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',linewidth=1.0,markersize=2,ecolor='r')
1007 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',linewidth=1.0,markersize=2,ecolor='r')
1008
1008
1009 #self.xstep_given = (self.xmax-self.xmin)/(self.data.NLAG-1)
1009 #self.xstep_given = (self.xmax-self.xmin)/(self.data.NLAG-1)
1010 self.xstep_given=0.3
1010 self.xstep_given=0.3
1011 self.ystep_given = 200
1011 self.ystep_given = 200
1012 ax.yaxis.set_minor_locator(MultipleLocator(15))
1012 ax.yaxis.set_minor_locator(MultipleLocator(15))
1013 ax.grid(which='minor')
1013 ax.grid(which='minor')
1014
1014
1015 else:
1015 else:
1016 self.clear_figures()
1016 self.clear_figures()
1017
1017
1018 for i in range(NACF):
1018 for i in range(NACF):
1019 x_aux = numpy.isfinite(lags[i,:])
1019 x_aux = numpy.isfinite(lags[i,:])
1020 y_aux = numpy.isfinite(ACFs[i,:])
1020 y_aux = numpy.isfinite(ACFs[i,:])
1021 yerr_aux = numpy.isfinite(errACFs[i,:])
1021 yerr_aux = numpy.isfinite(errACFs[i,:])
1022
1022
1023 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
1023 if lags[i,:][~numpy.isnan(lags[i,:])].shape[0]>2:
1024 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',linewidth=1.0,markersize=2,ecolor='r')
1024 ax.errorbar(lags[i,x_aux], ACFs[i,y_aux], yerr=errACFs[i,x_aux],color='b',linewidth=1.0,markersize=2,ecolor='r')
1025
1025
1026 ax.yaxis.set_minor_locator(MultipleLocator(15))
1026 ax.yaxis.set_minor_locator(MultipleLocator(15))
1027
1027
1028
1028
1029 class CrossProductsPlot(Plot):
1029 class CrossProductsPlot(Plot):
1030 '''
1030 '''
1031 Plot for cross products
1031 Plot for cross products
1032 '''
1032 '''
1033
1033
1034 CODE = 'crossprod'
1034 CODE = 'crossprod'
1035 plot_name = 'Cross Products'
1035 plot_name = 'Cross Products'
1036 plot_type = 'scatterbuffer'
1036 plot_type = 'scatterbuffer'
1037
1037
1038 def setup(self):
1038 def setup(self):
1039
1039
1040 self.ncols = 3
1040 self.ncols = 3
1041 self.nrows = 1
1041 self.nrows = 1
1042 self.nplots = 3
1042 self.nplots = 3
1043 self.ylabel = 'Range [km]'
1043 self.ylabel = 'Range [km]'
1044 self.titles = []
1044 self.titles = []
1045 self.width = 3.5*self.nplots
1045 self.width = 3.5*self.nplots
1046 self.height = 5.5
1046 self.height = 5.5
1047 self.colorbar = False
1047 self.colorbar = False
1048 self.plots_adjust.update({'wspace':.3, 'left': 0.12, 'right': 0.92, 'bottom': 0.1})
1048 self.plots_adjust.update({'wspace':.3, 'left': 0.12, 'right': 0.92, 'bottom': 0.1})
1049
1049
1050
1050
1051 def update(self, dataOut):
1051 def update(self, dataOut):
1052
1052
1053 data = {}
1053 data = {}
1054 meta = {}
1054 meta = {}
1055
1055
1056 data['crossprod'] = dataOut.crossprods
1056 data['crossprod'] = dataOut.crossprods
1057 data['NDP'] = dataOut.NDP
1057 data['NDP'] = dataOut.NDP
1058
1058
1059 return data, meta
1059 return data, meta
1060
1060
1061 def plot(self):
1061 def plot(self):
1062
1062
1063 NDP = self.data['NDP'][-1]
1063 NDP = self.data['NDP'][-1]
1064 x = self.data['crossprod'][:,-1,:,:,:,:]
1064 x = self.data['crossprod'][:,-1,:,:,:,:]
1065 y = self.data.yrange[0:NDP]
1065 y = self.data.yrange[0:NDP]
1066
1066
1067 for n, ax in enumerate(self.axes):
1067 for n, ax in enumerate(self.axes):
1068
1068
1069 self.xmin=numpy.min(numpy.concatenate((x[n][0,20:30,0,0],x[n][1,20:30,0,0],x[n][2,20:30,0,0],x[n][3,20:30,0,0])))
1069 self.xmin=numpy.min(numpy.concatenate((x[n][0,20:30,0,0],x[n][1,20:30,0,0],x[n][2,20:30,0,0],x[n][3,20:30,0,0])))
1070 self.xmax=numpy.max(numpy.concatenate((x[n][0,20:30,0,0],x[n][1,20:30,0,0],x[n][2,20:30,0,0],x[n][3,20:30,0,0])))
1070 self.xmax=numpy.max(numpy.concatenate((x[n][0,20:30,0,0],x[n][1,20:30,0,0],x[n][2,20:30,0,0],x[n][3,20:30,0,0])))
1071
1071
1072 if ax.firsttime:
1072 if ax.firsttime:
1073
1073
1074 self.autoxticks=False
1074 self.autoxticks=False
1075 if n==0:
1075 if n==0:
1076 label1='kax'
1076 label1='kax'
1077 label2='kay'
1077 label2='kay'
1078 label3='kbx'
1078 label3='kbx'
1079 label4='kby'
1079 label4='kby'
1080 self.xlimits=[(self.xmin,self.xmax)]
1080 self.xlimits=[(self.xmin,self.xmax)]
1081 elif n==1:
1081 elif n==1:
1082 label1='kax2'
1082 label1='kax2'
1083 label2='kay2'
1083 label2='kay2'
1084 label3='kbx2'
1084 label3='kbx2'
1085 label4='kby2'
1085 label4='kby2'
1086 self.xlimits.append((self.xmin,self.xmax))
1086 self.xlimits.append((self.xmin,self.xmax))
1087 elif n==2:
1087 elif n==2:
1088 label1='kaxay'
1088 label1='kaxay'
1089 label2='kbxby'
1089 label2='kbxby'
1090 label3='kaxbx'
1090 label3='kaxbx'
1091 label4='kaxby'
1091 label4='kaxby'
1092 self.xlimits.append((self.xmin,self.xmax))
1092 self.xlimits.append((self.xmin,self.xmax))
1093
1093
1094 ax.plotline1 = ax.plot(x[n][0,:,0,0], y, color='r',linewidth=2.0, label=label1)
1094 ax.plotline1 = ax.plot(x[n][0,:,0,0], y, color='r',linewidth=2.0, label=label1)
1095 ax.plotline2 = ax.plot(x[n][1,:,0,0], y, color='k',linewidth=2.0, label=label2)
1095 ax.plotline2 = ax.plot(x[n][1,:,0,0], y, color='k',linewidth=2.0, label=label2)
1096 ax.plotline3 = ax.plot(x[n][2,:,0,0], y, color='b',linewidth=2.0, label=label3)
1096 ax.plotline3 = ax.plot(x[n][2,:,0,0], y, color='b',linewidth=2.0, label=label3)
1097 ax.plotline4 = ax.plot(x[n][3,:,0,0], y, color='m',linewidth=2.0, label=label4)
1097 ax.plotline4 = ax.plot(x[n][3,:,0,0], y, color='m',linewidth=2.0, label=label4)
1098 ax.legend(loc='upper right')
1098 ax.legend(loc='upper right')
1099 ax.set_xlim(self.xmin, self.xmax)
1099 ax.set_xlim(self.xmin, self.xmax)
1100 self.titles.append('{}'.format(self.plot_name.upper()))
1100 self.titles.append('{}'.format(self.plot_name.upper()))
1101
1101
1102 else:
1102 else:
1103
1103
1104 if n==0:
1104 if n==0:
1105 self.xlimits=[(self.xmin,self.xmax)]
1105 self.xlimits=[(self.xmin,self.xmax)]
1106 else:
1106 else:
1107 self.xlimits.append((self.xmin,self.xmax))
1107 self.xlimits.append((self.xmin,self.xmax))
1108
1108
1109 ax.set_xlim(self.xmin, self.xmax)
1109 ax.set_xlim(self.xmin, self.xmax)
1110
1110
1111 ax.plotline1[0].set_data(x[n][0,:,0,0],y)
1111 ax.plotline1[0].set_data(x[n][0,:,0,0],y)
1112 ax.plotline2[0].set_data(x[n][1,:,0,0],y)
1112 ax.plotline2[0].set_data(x[n][1,:,0,0],y)
1113 ax.plotline3[0].set_data(x[n][2,:,0,0],y)
1113 ax.plotline3[0].set_data(x[n][2,:,0,0],y)
1114 ax.plotline4[0].set_data(x[n][3,:,0,0],y)
1114 ax.plotline4[0].set_data(x[n][3,:,0,0],y)
1115 self.titles.append('{}'.format(self.plot_name.upper()))
1115 self.titles.append('{}'.format(self.plot_name.upper()))
1116
1116
1117
1117
1118 class CrossProductsLPPlot(Plot):
1118 class CrossProductsLPPlot(Plot):
1119 '''
1119 '''
1120 Plot for cross products LP
1120 Plot for cross products LP
1121 '''
1121 '''
1122
1122
1123 CODE = 'crossprodslp'
1123 CODE = 'crossprodslp'
1124 plot_name = 'Cross Products LP'
1124 plot_name = 'Cross Products LP'
1125 plot_type = 'scatterbuffer'
1125 plot_type = 'scatterbuffer'
1126
1126
1127
1127
1128 def setup(self):
1128 def setup(self):
1129
1129
1130 self.ncols = 2
1130 self.ncols = 2
1131 self.nrows = 1
1131 self.nrows = 1
1132 self.nplots = 2
1132 self.nplots = 2
1133 self.ylabel = 'Range [km]'
1133 self.ylabel = 'Range [km]'
1134 self.xlabel = 'dB'
1134 self.xlabel = 'dB'
1135 self.width = 3.5*self.nplots
1135 self.width = 3.5*self.nplots
1136 self.height = 5.5
1136 self.height = 5.5
1137 self.colorbar = False
1137 self.colorbar = False
1138 self.titles = []
1138 self.titles = []
1139 self.plots_adjust.update({'wspace': .8 ,'left': 0.17, 'right': 0.88, 'bottom': 0.1})
1139 self.plots_adjust.update({'wspace': .8 ,'left': 0.17, 'right': 0.88, 'bottom': 0.1})
1140
1140
1141 def update(self, dataOut):
1141 def update(self, dataOut):
1142 data = {}
1142 data = {}
1143 meta = {}
1143 meta = {}
1144
1144
1145 data['crossprodslp'] = 10*numpy.log10(numpy.abs(dataOut.output_LP))
1145 data['crossprodslp'] = 10*numpy.log10(numpy.abs(dataOut.output_LP))
1146
1146
1147 data['NRANGE'] = dataOut.NRANGE #This is metadata
1147 data['NRANGE'] = dataOut.NRANGE #This is metadata
1148 data['NLAG'] = dataOut.NLAG #This is metadata
1148 data['NLAG'] = dataOut.NLAG #This is metadata
1149
1149
1150 return data, meta
1150 return data, meta
1151
1151
1152 def plot(self):
1152 def plot(self):
1153
1153
1154 NRANGE = self.data['NRANGE'][-1]
1154 NRANGE = self.data['NRANGE'][-1]
1155 NLAG = self.data['NLAG'][-1]
1155 NLAG = self.data['NLAG'][-1]
1156
1156
1157 x = self.data[self.CODE][:,-1,:,:]
1157 x = self.data[self.CODE][:,-1,:,:]
1158 self.y = self.data.yrange[0:NRANGE]
1158 self.y = self.data.yrange[0:NRANGE]
1159
1159
1160 label_array=numpy.array(['lag '+ str(x) for x in range(NLAG)])
1160 label_array=numpy.array(['lag '+ str(x) for x in range(NLAG)])
1161 color_array=['r','k','g','b','c','m','y','orange','steelblue','purple','peru','darksalmon','grey','limegreen','olive','midnightblue']
1161 color_array=['r','k','g','b','c','m','y','orange','steelblue','purple','peru','darksalmon','grey','limegreen','olive','midnightblue']
1162
1162
1163
1163
1164 for n, ax in enumerate(self.axes):
1164 for n, ax in enumerate(self.axes):
1165
1165
1166 self.xmin=28#30
1166 self.xmin=28#30
1167 self.xmax=70#70
1167 self.xmax=70#70
1168 #self.xmin=numpy.min(numpy.concatenate((self.x[0,:,n],self.x[1,:,n])))
1168 #self.xmin=numpy.min(numpy.concatenate((self.x[0,:,n],self.x[1,:,n])))
1169 #self.xmax=numpy.max(numpy.concatenate((self.x[0,:,n],self.x[1,:,n])))
1169 #self.xmax=numpy.max(numpy.concatenate((self.x[0,:,n],self.x[1,:,n])))
1170
1170
1171 if ax.firsttime:
1171 if ax.firsttime:
1172
1172
1173 self.autoxticks=False
1173 self.autoxticks=False
1174 if n == 0:
1174 if n == 0:
1175 self.plotline_array=numpy.zeros((2,NLAG),dtype=object)
1175 self.plotline_array=numpy.zeros((2,NLAG),dtype=object)
1176
1176
1177 for i in range(NLAG):
1177 for i in range(NLAG):
1178 self.plotline_array[n,i], = ax.plot(x[i,:,n], self.y, color=color_array[i],linewidth=1.0, label=label_array[i])
1178 self.plotline_array[n,i], = ax.plot(x[i,:,n], self.y, color=color_array[i],linewidth=1.0, label=label_array[i])
1179
1179
1180 ax.legend(loc='upper right')
1180 ax.legend(loc='upper right')
1181 ax.set_xlim(self.xmin, self.xmax)
1181 ax.set_xlim(self.xmin, self.xmax)
1182 if n==0:
1182 if n==0:
1183 self.titles.append('{} CH0'.format(self.plot_name.upper()))
1183 self.titles.append('{} CH0'.format(self.plot_name.upper()))
1184 if n==1:
1184 if n==1:
1185 self.titles.append('{} CH1'.format(self.plot_name.upper()))
1185 self.titles.append('{} CH1'.format(self.plot_name.upper()))
1186 else:
1186 else:
1187 for i in range(NLAG):
1187 for i in range(NLAG):
1188 self.plotline_array[n,i].set_data(x[i,:,n],self.y)
1188 self.plotline_array[n,i].set_data(x[i,:,n],self.y)
1189
1189
1190 if n==0:
1190 if n==0:
1191 self.titles.append('{} CH0'.format(self.plot_name.upper()))
1191 self.titles.append('{} CH0'.format(self.plot_name.upper()))
1192 if n==1:
1192 if n==1:
1193 self.titles.append('{} CH1'.format(self.plot_name.upper()))
1193 self.titles.append('{} CH1'.format(self.plot_name.upper()))
1194
1194
1195
1195
1196 class NoiseDPPlot(NoisePlot):
1196 class NoiseDPPlot(NoisePlot):
1197 '''
1197 '''
1198 Plot for noise Double Pulse
1198 Plot for noise Double Pulse
1199 '''
1199 '''
1200
1200
1201 CODE = 'noise'
1201 CODE = 'noise'
1202 #plot_name = 'Noise'
1202 #plot_name = 'Noise'
1203 #plot_type = 'scatterbuffer'
1203 #plot_type = 'scatterbuffer'
1204
1204
1205 def update(self, dataOut):
1205 def update(self, dataOut):
1206
1206
1207 data = {}
1207 data = {}
1208 meta = {}
1208 meta = {}
1209 data['noise'] = 10*numpy.log10(dataOut.noise_final)
1209 data['noise'] = 10*numpy.log10(dataOut.noise_final)
1210
1210
1211 return data, meta
1211 return data, meta
1212
1212
1213
1213
1214 class XmitWaveformPlot(Plot):
1214 class XmitWaveformPlot(Plot):
1215 '''
1215 '''
1216 Plot for xmit waveform
1216 Plot for xmit waveform
1217 '''
1217 '''
1218
1218
1219 CODE = 'xmit'
1219 CODE = 'xmit'
1220 plot_name = 'Xmit Waveform'
1220 plot_name = 'Xmit Waveform'
1221 plot_type = 'scatterbuffer'
1221 plot_type = 'scatterbuffer'
1222
1222
1223
1223
1224 def setup(self):
1224 def setup(self):
1225
1225
1226 self.ncols = 1
1226 self.ncols = 1
1227 self.nrows = 1
1227 self.nrows = 1
1228 self.nplots = 1
1228 self.nplots = 1
1229 self.ylabel = ''
1229 self.ylabel = ''
1230 self.xlabel = 'Number of Lag'
1230 self.xlabel = 'Number of Lag'
1231 self.width = 5.5
1231 self.width = 5.5
1232 self.height = 3.5
1232 self.height = 3.5
1233 self.colorbar = False
1233 self.colorbar = False
1234 self.plots_adjust.update({'right': 0.85 })
1234 self.plots_adjust.update({'right': 0.85 })
1235 self.titles = [self.plot_name]
1235 self.titles = [self.plot_name]
1236 #self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
1236 #self.plots_adjust.update({'left': 0.17, 'right': 0.88, 'bottom': 0.1})
1237
1237
1238 #if not self.titles:
1238 #if not self.titles:
1239 #self.titles = self.data.parameters \
1239 #self.titles = self.data.parameters \
1240 #if self.data.parameters else ['{}'.format(self.plot_name.upper())]
1240 #if self.data.parameters else ['{}'.format(self.plot_name.upper())]
1241
1241
1242 def update(self, dataOut):
1242 def update(self, dataOut):
1243
1243
1244 data = {}
1244 data = {}
1245 meta = {}
1245 meta = {}
1246
1246
1247 y_1=numpy.arctan2(dataOut.output_LP[:,0,2].imag,dataOut.output_LP[:,0,2].real)* 180 / (numpy.pi*10)
1247 y_1=numpy.arctan2(dataOut.output_LP[:,0,2].imag,dataOut.output_LP[:,0,2].real)* 180 / (numpy.pi*10)
1248 y_2=numpy.abs(dataOut.output_LP[:,0,2])
1248 y_2=numpy.abs(dataOut.output_LP[:,0,2])
1249 norm=numpy.max(y_2)
1249 norm=numpy.max(y_2)
1250 norm=max(norm,0.1)
1250 norm=max(norm,0.1)
1251 y_2=y_2/norm
1251 y_2=y_2/norm
1252
1252
1253 meta['yrange'] = numpy.array([])
1253 meta['yrange'] = numpy.array([])
1254
1254
1255 data['xmit'] = numpy.vstack((y_1,y_2))
1255 data['xmit'] = numpy.vstack((y_1,y_2))
1256 data['NLAG'] = dataOut.NLAG
1256 data['NLAG'] = dataOut.NLAG
1257
1257
1258 return data, meta
1258 return data, meta
1259
1259
1260 def plot(self):
1260 def plot(self):
1261
1261
1262 data = self.data[-1]
1262 data = self.data[-1]
1263 NLAG = data['NLAG']
1263 NLAG = data['NLAG']
1264 x = numpy.arange(0,NLAG,1,'float32')
1264 x = numpy.arange(0,NLAG,1,'float32')
1265 y = data['xmit']
1265 y = data['xmit']
1266
1266
1267 self.xmin = 0
1267 self.xmin = 0
1268 self.xmax = NLAG-1
1268 self.xmax = NLAG-1
1269 self.ymin = -1.0
1269 self.ymin = -1.0
1270 self.ymax = 1.0
1270 self.ymax = 1.0
1271 ax = self.axes[0]
1271 ax = self.axes[0]
1272
1272
1273 if ax.firsttime:
1273 if ax.firsttime:
1274 ax.plotline0=ax.plot(x,y[0,:],color='blue')
1274 ax.plotline0=ax.plot(x,y[0,:],color='blue')
1275 ax.plotline1=ax.plot(x,y[1,:],color='red')
1275 ax.plotline1=ax.plot(x,y[1,:],color='red')
1276 secax=ax.secondary_xaxis(location=0.5)
1276 secax=ax.secondary_xaxis(location=0.5)
1277 secax.xaxis.tick_bottom()
1277 secax.xaxis.tick_bottom()
1278 secax.tick_params( labelleft=False, labeltop=False,
1278 secax.tick_params( labelleft=False, labeltop=False,
1279 labelright=False, labelbottom=False)
1279 labelright=False, labelbottom=False)
1280
1280
1281 self.xstep_given = 3
1281 self.xstep_given = 3
1282 self.ystep_given = .25
1282 self.ystep_given = .25
1283 secax.set_xticks(numpy.linspace(self.xmin, self.xmax, 6)) #only works on matplotlib.version>3.2
1283 secax.set_xticks(numpy.linspace(self.xmin, self.xmax, 6)) #only works on matplotlib.version>3.2
1284
1284
1285 else:
1285 else:
1286 ax.plotline0[0].set_data(x,y[0,:])
1286 ax.plotline0[0].set_data(x,y[0,:])
1287 ax.plotline1[0].set_data(x,y[1,:])
1287 ax.plotline1[0].set_data(x,y[1,:])
@@ -1,1615 +1,1614
1 """
1 """
2 Created on Jul 2, 2014
2 Created on Jul 2, 2014
3
3
4 @author: roj-idl71
4 @author: roj-idl71
5 """
5 """
6 import os
6 import os
7 import sys
7 import sys
8 import glob
8 import glob
9 import time
9 import time
10 import numpy
10 import numpy
11 import fnmatch
11 import fnmatch
12 import inspect
12 import inspect
13 import time
13 import time
14 import datetime
14 import datetime
15 import zmq
15 import zmq
16
16
17 from schainpy.model.proc.jroproc_base import Operation, MPDecorator
17 from schainpy.model.proc.jroproc_base import Operation, MPDecorator
18 from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader
18 from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader
19 from schainpy.model.data.jroheaderIO import get_dtype_index, get_numpy_dtype, get_procflag_dtype, get_dtype_width
19 from schainpy.model.data.jroheaderIO import get_dtype_index, get_numpy_dtype, get_procflag_dtype, get_dtype_width
20 from schainpy.utils import log
20 from schainpy.utils import log
21 import schainpy.admin
21 import schainpy.admin
22
22
23 LOCALTIME = True
23 LOCALTIME = True
24 DT_DIRECTIVES = {
24 DT_DIRECTIVES = {
25 '%Y': 4,
25 '%Y': 4,
26 '%y': 2,
26 '%y': 2,
27 '%m': 2,
27 '%m': 2,
28 '%d': 2,
28 '%d': 2,
29 '%j': 3,
29 '%j': 3,
30 '%H': 2,
30 '%H': 2,
31 '%M': 2,
31 '%M': 2,
32 '%S': 2,
32 '%S': 2,
33 '%f': 6
33 '%f': 6
34 }
34 }
35
35
36
36
37 def isNumber(cad):
37 def isNumber(cad):
38 """
38 """
39 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
39 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
40
40
41 Excepciones:
41 Excepciones:
42 Si un determinado string no puede ser convertido a numero
42 Si un determinado string no puede ser convertido a numero
43 Input:
43 Input:
44 str, string al cual se le analiza para determinar si convertible a un numero o no
44 str, string al cual se le analiza para determinar si convertible a un numero o no
45
45
46 Return:
46 Return:
47 True : si el string es uno numerico
47 True : si el string es uno numerico
48 False : no es un string numerico
48 False : no es un string numerico
49 """
49 """
50 try:
50 try:
51 float(cad)
51 float(cad)
52 return True
52 return True
53 except:
53 except:
54 return False
54 return False
55
55
56
56
57 def isFileInEpoch(filename, startUTSeconds, endUTSeconds):
57 def isFileInEpoch(filename, startUTSeconds, endUTSeconds):
58 """
58 """
59 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
59 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
60
60
61 Inputs:
61 Inputs:
62 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
62 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
63
63
64 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
64 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
65 segundos contados desde 01/01/1970.
65 segundos contados desde 01/01/1970.
66 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
66 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
67 segundos contados desde 01/01/1970.
67 segundos contados desde 01/01/1970.
68
68
69 Return:
69 Return:
70 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
70 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
71 fecha especificado, de lo contrario retorna False.
71 fecha especificado, de lo contrario retorna False.
72
72
73 Excepciones:
73 Excepciones:
74 Si el archivo no existe o no puede ser abierto
74 Si el archivo no existe o no puede ser abierto
75 Si la cabecera no puede ser leida.
75 Si la cabecera no puede ser leida.
76
76
77 """
77 """
78 basicHeaderObj = BasicHeader(LOCALTIME)
78 basicHeaderObj = BasicHeader(LOCALTIME)
79
79
80 try:
80 try:
81
81
82 fp = open(filename, 'rb')
82 fp = open(filename, 'rb')
83 except IOError:
83 except IOError:
84 print("The file %s can't be opened" % (filename))
84 print("The file %s can't be opened" % (filename))
85 return 0
85 return 0
86
86
87 sts = basicHeaderObj.read(fp)
87 sts = basicHeaderObj.read(fp)
88 fp.close()
88 fp.close()
89
89
90 if not(sts):
90 if not(sts):
91 print("Skipping the file %s because it has not a valid header" % (filename))
91 print("Skipping the file %s because it has not a valid header" % (filename))
92 return 0
92 return 0
93
93
94 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
94 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
95 return 0
95 return 0
96
96
97 return 1
97 return 1
98
98
99
99
100 def isTimeInRange(thisTime, startTime, endTime):
100 def isTimeInRange(thisTime, startTime, endTime):
101 if endTime >= startTime:
101 if endTime >= startTime:
102 if (thisTime < startTime) or (thisTime > endTime):
102 if (thisTime < startTime) or (thisTime > endTime):
103 return 0
103 return 0
104 return 1
104 return 1
105 else:
105 else:
106 if (thisTime < startTime) and (thisTime > endTime):
106 if (thisTime < startTime) and (thisTime > endTime):
107 return 0
107 return 0
108 return 1
108 return 1
109
109
110
110
111 def isFileInTimeRange(filename, startDate, endDate, startTime, endTime):
111 def isFileInTimeRange(filename, startDate, endDate, startTime, endTime):
112 """
112 """
113 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
113 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
114
114
115 Inputs:
115 Inputs:
116 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
116 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
117
117
118 startDate : fecha inicial del rango seleccionado en formato datetime.date
118 startDate : fecha inicial del rango seleccionado en formato datetime.date
119
119
120 endDate : fecha final del rango seleccionado en formato datetime.date
120 endDate : fecha final del rango seleccionado en formato datetime.date
121
121
122 startTime : tiempo inicial del rango seleccionado en formato datetime.time
122 startTime : tiempo inicial del rango seleccionado en formato datetime.time
123
123
124 endTime : tiempo final del rango seleccionado en formato datetime.time
124 endTime : tiempo final del rango seleccionado en formato datetime.time
125
125
126 Return:
126 Return:
127 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
127 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
128 fecha especificado, de lo contrario retorna False.
128 fecha especificado, de lo contrario retorna False.
129
129
130 Excepciones:
130 Excepciones:
131 Si el archivo no existe o no puede ser abierto
131 Si el archivo no existe o no puede ser abierto
132 Si la cabecera no puede ser leida.
132 Si la cabecera no puede ser leida.
133
133
134 """
134 """
135
135
136 try:
136 try:
137 fp = open(filename, 'rb')
137 fp = open(filename, 'rb')
138 except IOError:
138 except IOError:
139 print("The file %s can't be opened" % (filename))
139 print("The file %s can't be opened" % (filename))
140 return None
140 return None
141
141
142 firstBasicHeaderObj = BasicHeader(LOCALTIME)
142 firstBasicHeaderObj = BasicHeader(LOCALTIME)
143 systemHeaderObj = SystemHeader()
143 systemHeaderObj = SystemHeader()
144
144
145 radarControllerHeaderObj = RadarControllerHeader()
145 radarControllerHeaderObj = RadarControllerHeader()
146 processingHeaderObj = ProcessingHeader()
146 processingHeaderObj = ProcessingHeader()
147
147
148 lastBasicHeaderObj = BasicHeader(LOCALTIME)
148 lastBasicHeaderObj = BasicHeader(LOCALTIME)
149
149
150 sts = firstBasicHeaderObj.read(fp)
150 sts = firstBasicHeaderObj.read(fp)
151
151
152 if not(sts):
152 if not(sts):
153 print("[Reading] Skipping the file %s because it has not a valid header" % (filename))
153 print("[Reading] Skipping the file %s because it has not a valid header" % (filename))
154 return None
154 return None
155
155
156 if not systemHeaderObj.read(fp):
156 if not systemHeaderObj.read(fp):
157 return None
157 return None
158
158
159 if not radarControllerHeaderObj.read(fp):
159 if not radarControllerHeaderObj.read(fp):
160 return None
160 return None
161
161
162 if not processingHeaderObj.read(fp):
162 if not processingHeaderObj.read(fp):
163 return None
163 return None
164
164
165 filesize = os.path.getsize(filename)
165 filesize = os.path.getsize(filename)
166
166
167 offset = processingHeaderObj.blockSize + 24 # header size
167 offset = processingHeaderObj.blockSize + 24 # header size
168
168
169 if filesize <= offset:
169 if filesize <= offset:
170 print("[Reading] %s: This file has not enough data" % filename)
170 print("[Reading] %s: This file has not enough data" % filename)
171 return None
171 return None
172
172
173 fp.seek(-offset, 2)
173 fp.seek(-offset, 2)
174
174
175 sts = lastBasicHeaderObj.read(fp)
175 sts = lastBasicHeaderObj.read(fp)
176
176
177 fp.close()
177 fp.close()
178
178
179 thisDatetime = lastBasicHeaderObj.datatime
179 thisDatetime = lastBasicHeaderObj.datatime
180 thisTime_last_block = thisDatetime.time()
180 thisTime_last_block = thisDatetime.time()
181
181
182 thisDatetime = firstBasicHeaderObj.datatime
182 thisDatetime = firstBasicHeaderObj.datatime
183 thisDate = thisDatetime.date()
183 thisDate = thisDatetime.date()
184 thisTime_first_block = thisDatetime.time()
184 thisTime_first_block = thisDatetime.time()
185
185
186 # General case
186 # General case
187 # o>>>>>>>>>>>>>><<<<<<<<<<<<<<o
187 # o>>>>>>>>>>>>>><<<<<<<<<<<<<<o
188 #-----------o----------------------------o-----------
188 #-----------o----------------------------o-----------
189 # startTime endTime
189 # startTime endTime
190
190
191 if endTime >= startTime:
191 if endTime >= startTime:
192 if (thisTime_last_block < startTime) or (thisTime_first_block > endTime):
192 if (thisTime_last_block < startTime) or (thisTime_first_block > endTime):
193 return None
193 return None
194
194
195 return thisDatetime
195 return thisDatetime
196
196
197 # If endTime < startTime then endTime belongs to the next day
197 # If endTime < startTime then endTime belongs to the next day
198
198
199 #<<<<<<<<<<<o o>>>>>>>>>>>
199 #<<<<<<<<<<<o o>>>>>>>>>>>
200 #-----------o----------------------------o-----------
200 #-----------o----------------------------o-----------
201 # endTime startTime
201 # endTime startTime
202
202
203 if (thisDate == startDate) and (thisTime_last_block < startTime):
203 if (thisDate == startDate) and (thisTime_last_block < startTime):
204 return None
204 return None
205
205
206 if (thisDate == endDate) and (thisTime_first_block > endTime):
206 if (thisDate == endDate) and (thisTime_first_block > endTime):
207 return None
207 return None
208
208
209 if (thisTime_last_block < startTime) and (thisTime_first_block > endTime):
209 if (thisTime_last_block < startTime) and (thisTime_first_block > endTime):
210 return None
210 return None
211
211
212 return thisDatetime
212 return thisDatetime
213
213
214
214
215 def isFolderInDateRange(folder, startDate=None, endDate=None):
215 def isFolderInDateRange(folder, startDate=None, endDate=None):
216 """
216 """
217 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
217 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
218
218
219 Inputs:
219 Inputs:
220 folder : nombre completo del directorio.
220 folder : nombre completo del directorio.
221 Su formato deberia ser "/path_root/?YYYYDDD"
221 Su formato deberia ser "/path_root/?YYYYDDD"
222
222
223 siendo:
223 siendo:
224 YYYY : Anio (ejemplo 2015)
224 YYYY : Anio (ejemplo 2015)
225 DDD : Dia del anio (ejemplo 305)
225 DDD : Dia del anio (ejemplo 305)
226
226
227 startDate : fecha inicial del rango seleccionado en formato datetime.date
227 startDate : fecha inicial del rango seleccionado en formato datetime.date
228
228
229 endDate : fecha final del rango seleccionado en formato datetime.date
229 endDate : fecha final del rango seleccionado en formato datetime.date
230
230
231 Return:
231 Return:
232 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
232 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
233 fecha especificado, de lo contrario retorna False.
233 fecha especificado, de lo contrario retorna False.
234 Excepciones:
234 Excepciones:
235 Si el directorio no tiene el formato adecuado
235 Si el directorio no tiene el formato adecuado
236 """
236 """
237
237
238 basename = os.path.basename(folder)
238 basename = os.path.basename(folder)
239
239
240 if not isRadarFolder(basename):
240 if not isRadarFolder(basename):
241 print("The folder %s has not the rigth format" % folder)
241 print("The folder %s has not the rigth format" % folder)
242 return 0
242 return 0
243
243
244 if startDate and endDate:
244 if startDate and endDate:
245 thisDate = getDateFromRadarFolder(basename)
245 thisDate = getDateFromRadarFolder(basename)
246
246
247 if thisDate < startDate:
247 if thisDate < startDate:
248 return 0
248 return 0
249
249
250 if thisDate > endDate:
250 if thisDate > endDate:
251 return 0
251 return 0
252
252
253 return 1
253 return 1
254
254
255
255
256 def isFileInDateRange(filename, startDate=None, endDate=None):
256 def isFileInDateRange(filename, startDate=None, endDate=None):
257 """
257 """
258 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
258 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
259
259
260 Inputs:
260 Inputs:
261 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
261 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
262
262
263 Su formato deberia ser "?YYYYDDDsss"
263 Su formato deberia ser "?YYYYDDDsss"
264
264
265 siendo:
265 siendo:
266 YYYY : Anio (ejemplo 2015)
266 YYYY : Anio (ejemplo 2015)
267 DDD : Dia del anio (ejemplo 305)
267 DDD : Dia del anio (ejemplo 305)
268 sss : set
268 sss : set
269
269
270 startDate : fecha inicial del rango seleccionado en formato datetime.date
270 startDate : fecha inicial del rango seleccionado en formato datetime.date
271
271
272 endDate : fecha final del rango seleccionado en formato datetime.date
272 endDate : fecha final del rango seleccionado en formato datetime.date
273
273
274 Return:
274 Return:
275 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
275 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
276 fecha especificado, de lo contrario retorna False.
276 fecha especificado, de lo contrario retorna False.
277 Excepciones:
277 Excepciones:
278 Si el archivo no tiene el formato adecuado
278 Si el archivo no tiene el formato adecuado
279 """
279 """
280
280
281 basename = os.path.basename(filename)
281 basename = os.path.basename(filename)
282
282
283 if not isRadarFile(basename):
283 if not isRadarFile(basename):
284 print("The filename %s has not the rigth format" % filename)
284 print("The filename %s has not the rigth format" % filename)
285 return 0
285 return 0
286
286
287 if startDate and endDate:
287 if startDate and endDate:
288 thisDate = getDateFromRadarFile(basename)
288 thisDate = getDateFromRadarFile(basename)
289
289
290 if thisDate < startDate:
290 if thisDate < startDate:
291 return 0
291 return 0
292
292
293 if thisDate > endDate:
293 if thisDate > endDate:
294 return 0
294 return 0
295
295
296 return 1
296 return 1
297
297
298
298
299 def getFileFromSet(path, ext, set):
299 def getFileFromSet(path, ext, set):
300 validFilelist = []
300 validFilelist = []
301 fileList = os.listdir(path)
301 fileList = os.listdir(path)
302
302
303 # 0 1234 567 89A BCDE
303 # 0 1234 567 89A BCDE
304 # H YYYY DDD SSS .ext
304 # H YYYY DDD SSS .ext
305
305
306 for thisFile in fileList:
306 for thisFile in fileList:
307 try:
307 try:
308 year = int(thisFile[1:5])
308 year = int(thisFile[1:5])
309 doy = int(thisFile[5:8])
309 doy = int(thisFile[5:8])
310 except:
310 except:
311 continue
311 continue
312
312
313 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
313 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
314 continue
314 continue
315
315
316 validFilelist.append(thisFile)
316 validFilelist.append(thisFile)
317
317
318 myfile = fnmatch.filter(
318 myfile = fnmatch.filter(
319 validFilelist, '*%4.4d%3.3d%3.3d*' % (year, doy, set))
319 validFilelist, '*%4.4d%3.3d%3.3d*' % (year, doy, set))
320
320
321 if len(myfile) != 0:
321 if len(myfile) != 0:
322 return myfile[0]
322 return myfile[0]
323 else:
323 else:
324 filename = '*%4.4d%3.3d%3.3d%s' % (year, doy, set, ext.lower())
324 filename = '*%4.4d%3.3d%3.3d%s' % (year, doy, set, ext.lower())
325 print('the filename %s does not exist' % filename)
325 print('the filename %s does not exist' % filename)
326 print('...going to the last file: ')
326 print('...going to the last file: ')
327
327
328 if validFilelist:
328 if validFilelist:
329 validFilelist = sorted(validFilelist, key=str.lower)
329 validFilelist = sorted(validFilelist, key=str.lower)
330 return validFilelist[-1]
330 return validFilelist[-1]
331
331
332 return None
332 return None
333
333
334
334
335 def getlastFileFromPath(path, ext):
335 def getlastFileFromPath(path, ext):
336 """
336 """
337 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
337 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
338 al final de la depuracion devuelve el ultimo file de la lista que quedo.
338 al final de la depuracion devuelve el ultimo file de la lista que quedo.
339
339
340 Input:
340 Input:
341 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
341 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
342 ext : extension de los files contenidos en una carpeta
342 ext : extension de los files contenidos en una carpeta
343
343
344 Return:
344 Return:
345 El ultimo file de una determinada carpeta, no se considera el path.
345 El ultimo file de una determinada carpeta, no se considera el path.
346 """
346 """
347 validFilelist = []
347 validFilelist = []
348 fileList = os.listdir(path)
348 fileList = os.listdir(path)
349
349
350 # 0 1234 567 89A BCDE
350 # 0 1234 567 89A BCDE
351 # H YYYY DDD SSS .ext
351 # H YYYY DDD SSS .ext
352
352
353 for thisFile in fileList:
353 for thisFile in fileList:
354
354
355 year = thisFile[1:5]
355 year = thisFile[1:5]
356 if not isNumber(year):
356 if not isNumber(year):
357 continue
357 continue
358
358
359 doy = thisFile[5:8]
359 doy = thisFile[5:8]
360 if not isNumber(doy):
360 if not isNumber(doy):
361 continue
361 continue
362
362
363 year = int(year)
363 year = int(year)
364 doy = int(doy)
364 doy = int(doy)
365
365
366 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
366 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
367 continue
367 continue
368
368
369 validFilelist.append(thisFile)
369 validFilelist.append(thisFile)
370
370
371 if validFilelist:
371 if validFilelist:
372 validFilelist = sorted(validFilelist, key=str.lower)
372 validFilelist = sorted(validFilelist, key=str.lower)
373 return validFilelist[-1]
373 return validFilelist[-1]
374
374
375 return None
375 return None
376
376
377
377
378 def isRadarFolder(folder):
378 def isRadarFolder(folder):
379 try:
379 try:
380 year = int(folder[1:5])
380 year = int(folder[1:5])
381 doy = int(folder[5:8])
381 doy = int(folder[5:8])
382 except:
382 except:
383 return 0
383 return 0
384
384
385 return 1
385 return 1
386
386
387
387
388 def isRadarFile(file):
388 def isRadarFile(file):
389 try:
389 try:
390 year = int(file[1:5])
390 year = int(file[1:5])
391 doy = int(file[5:8])
391 doy = int(file[5:8])
392 set = int(file[8:11])
392 set = int(file[8:11])
393 except:
393 except:
394 return 0
394 return 0
395
395
396 return 1
396 return 1
397
397
398
398
399 def getDateFromRadarFile(file):
399 def getDateFromRadarFile(file):
400 try:
400 try:
401 year = int(file[1:5])
401 year = int(file[1:5])
402 doy = int(file[5:8])
402 doy = int(file[5:8])
403 set = int(file[8:11])
403 set = int(file[8:11])
404 except:
404 except:
405 return None
405 return None
406
406
407 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
407 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
408 return thisDate
408 return thisDate
409
409
410
410
411 def getDateFromRadarFolder(folder):
411 def getDateFromRadarFolder(folder):
412 try:
412 try:
413 year = int(folder[1:5])
413 year = int(folder[1:5])
414 doy = int(folder[5:8])
414 doy = int(folder[5:8])
415 except:
415 except:
416 return None
416 return None
417
417
418 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
418 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
419 return thisDate
419 return thisDate
420
420
421 def parse_format(s, fmt):
421 def parse_format(s, fmt):
422
422
423 for i in range(fmt.count('%')):
423 for i in range(fmt.count('%')):
424 x = fmt.index('%')
424 x = fmt.index('%')
425 d = DT_DIRECTIVES[fmt[x:x+2]]
425 d = DT_DIRECTIVES[fmt[x:x+2]]
426 fmt = fmt.replace(fmt[x:x+2], s[x:x+d])
426 fmt = fmt.replace(fmt[x:x+2], s[x:x+d])
427 return fmt
427 return fmt
428
428
429 class Reader(object):
429 class Reader(object):
430
430
431 c = 3E8
431 c = 3E8
432 isConfig = False
432 isConfig = False
433 dtype = None
433 dtype = None
434 pathList = []
434 pathList = []
435 filenameList = []
435 filenameList = []
436 datetimeList = []
436 datetimeList = []
437 filename = None
437 filename = None
438 ext = None
438 ext = None
439 flagIsNewFile = 1
439 flagIsNewFile = 1
440 flagDiscontinuousBlock = 0
440 flagDiscontinuousBlock = 0
441 flagIsNewBlock = 0
441 flagIsNewBlock = 0
442 flagNoMoreFiles = 0
442 flagNoMoreFiles = 0
443 fp = None
443 fp = None
444 firstHeaderSize = 0
444 firstHeaderSize = 0
445 basicHeaderSize = 24
445 basicHeaderSize = 24
446 versionFile = 1103
446 versionFile = 1103
447 fileSize = None
447 fileSize = None
448 fileSizeByHeader = None
448 fileSizeByHeader = None
449 fileIndex = -1
449 fileIndex = -1
450 profileIndex = None
450 profileIndex = None
451 blockIndex = 0
451 blockIndex = 0
452 nTotalBlocks = 0
452 nTotalBlocks = 0
453 maxTimeStep = 30
453 maxTimeStep = 30
454 lastUTTime = None
454 lastUTTime = None
455 datablock = None
455 datablock = None
456 dataOut = None
456 dataOut = None
457 getByBlock = False
457 getByBlock = False
458 path = None
458 path = None
459 startDate = None
459 startDate = None
460 endDate = None
460 endDate = None
461 startTime = datetime.time(0, 0, 0)
461 startTime = datetime.time(0, 0, 0)
462 endTime = datetime.time(23, 59, 59)
462 endTime = datetime.time(23, 59, 59)
463 set = None
463 set = None
464 expLabel = ""
464 expLabel = ""
465 online = False
465 online = False
466 delay = 60
466 delay = 60
467 nTries = 3 # quantity tries
467 nTries = 3 # quantity tries
468 nFiles = 3 # number of files for searching
468 nFiles = 3 # number of files for searching
469 walk = True
469 walk = True
470 getblock = False
470 getblock = False
471 nTxs = 1
471 nTxs = 1
472 realtime = False
472 realtime = False
473 blocksize = 0
473 blocksize = 0
474 blocktime = None
474 blocktime = None
475 warnings = True
475 warnings = True
476 verbose = True
476 verbose = True
477 server = None
477 server = None
478 format = None
478 format = None
479 oneDDict = None
479 oneDDict = None
480 twoDDict = None
480 twoDDict = None
481 independentParam = None
481 independentParam = None
482 filefmt = None
482 filefmt = None
483 folderfmt = None
483 folderfmt = None
484 open_file = open
484 open_file = open
485 open_mode = 'rb'
485 open_mode = 'rb'
486
486
487 def run(self):
487 def run(self):
488
488
489 raise NotImplementedError
489 raise NotImplementedError
490
490
491 def getAllowedArgs(self):
491 def getAllowedArgs(self):
492 if hasattr(self, '__attrs__'):
492 if hasattr(self, '__attrs__'):
493 return self.__attrs__
493 return self.__attrs__
494 else:
494 else:
495 return inspect.getargspec(self.run).args
495 return inspect.getargspec(self.run).args
496
496
497 def set_kwargs(self, **kwargs):
497 def set_kwargs(self, **kwargs):
498
498
499 for key, value in kwargs.items():
499 for key, value in kwargs.items():
500 setattr(self, key, value)
500 setattr(self, key, value)
501
501
502 def find_folders(self, path, startDate, endDate, folderfmt, last=False):
502 def find_folders(self, path, startDate, endDate, folderfmt, last=False):
503
503
504 folders = [x for f in path.split(',')
504 folders = [x for f in path.split(',')
505 for x in os.listdir(f) if os.path.isdir(os.path.join(f, x))]
505 for x in os.listdir(f) if os.path.isdir(os.path.join(f, x))]
506 folders.sort()
506 folders.sort()
507
507
508 if last:
508 if last:
509 folders = [folders[-1]]
509 folders = [folders[-1]]
510
510
511 for folder in folders:
511 for folder in folders:
512 try:
512 try:
513 dt = datetime.datetime.strptime(parse_format(folder, folderfmt), folderfmt).date()
513 dt = datetime.datetime.strptime(parse_format(folder, folderfmt), folderfmt).date()
514 if dt >= startDate and dt <= endDate:
514 if dt >= startDate and dt <= endDate:
515 yield os.path.join(path, folder)
515 yield os.path.join(path, folder)
516 else:
516 else:
517 log.log('Skiping folder {}'.format(folder), self.name)
517 log.log('Skiping folder {}'.format(folder), self.name)
518 except Exception as e:
518 except Exception as e:
519 log.log('Skiping folder {}'.format(folder), self.name)
519 log.log('Skiping folder {}'.format(folder), self.name)
520 continue
520 continue
521 return
521 return
522
522
523 def find_files(self, folders, ext, filefmt, startDate=None, endDate=None,
523 def find_files(self, folders, ext, filefmt, startDate=None, endDate=None,
524 expLabel='', last=False):
524 expLabel='', last=False):
525
526 for path in folders:
525 for path in folders:
527 files = glob.glob1(path, '*{}'.format(ext))
526 files = glob.glob1(path+'/'+expLabel, '*{}'.format(ext))
528 files.sort()
527 files.sort()
529 if last:
528 if last:
530 if files:
529 if files:
531 fo = files[-1]
530 fo = files[-1]
532 try:
531 try:
533 dt = datetime.datetime.strptime(parse_format(fo, filefmt), filefmt).date()
532 dt = datetime.datetime.strptime(parse_format(fo, filefmt), filefmt).date()
534 yield os.path.join(path, expLabel, fo)
533 yield os.path.join(path, expLabel, fo)
535 except Exception as e:
534 except Exception as e:
536 pass
535 pass
537 return
536 return
538 else:
537 else:
539 return
538 return
540
539
541 for fo in files:
540 for fo in files:
542 try:
541 try:
543 dt = datetime.datetime.strptime(parse_format(fo, filefmt), filefmt).date()
542 dt = datetime.datetime.strptime(parse_format(fo, filefmt), filefmt).date()
544 #print(dt)
543 #print(dt)
545 #print(startDate)
544 #print(startDate)
546 #print(endDate)
545 #print(endDate)
547 if dt >= startDate and dt <= endDate:
546 if dt >= startDate and dt <= endDate:
548
547
549 yield os.path.join(path, expLabel, fo)
548 yield os.path.join(path, expLabel, fo)
550
549
551 else:
550 else:
552
551
553 log.log('Skiping file {}'.format(fo), self.name)
552 log.log('Skiping file {}'.format(fo), self.name)
554 except Exception as e:
553 except Exception as e:
555 log.log('Skiping file {}'.format(fo), self.name)
554 log.log('Skiping file {}'.format(fo), self.name)
556 continue
555 continue
557
556
558 def searchFilesOffLine(self, path, startDate, endDate,
557 def searchFilesOffLine(self, path, startDate, endDate,
559 expLabel, ext, walk,
558 expLabel, ext, walk,
560 filefmt, folderfmt):
559 filefmt, folderfmt):
561 """Search files in offline mode for the given arguments
560 """Search files in offline mode for the given arguments
562
561
563 Return:
562 Return:
564 Generator of files
563 Generator of files
565 """
564 """
566
565
567 if walk:
566 if walk:
568 folders = self.find_folders(
567 folders = self.find_folders(
569 path, startDate, endDate, folderfmt)
568 path, startDate, endDate, folderfmt)
569 #print("folders: ", folders)
570 else:
570 else:
571 folders = path.split(',')
571 folders = path.split(',')
572
572
573 return self.find_files(
573 return self.find_files(
574 folders, ext, filefmt, startDate, endDate, expLabel)
574 folders, ext, filefmt, startDate, endDate, expLabel)
575
575
576 def searchFilesOnLine(self, path, startDate, endDate,
576 def searchFilesOnLine(self, path, startDate, endDate,
577 expLabel, ext, walk,
577 expLabel, ext, walk,
578 filefmt, folderfmt):
578 filefmt, folderfmt):
579 """Search for the last file of the last folder
579 """Search for the last file of the last folder
580
580
581 Arguments:
581 Arguments:
582 path : carpeta donde estan contenidos los files que contiene data
582 path : carpeta donde estan contenidos los files que contiene data
583 expLabel : Nombre del subexperimento (subfolder)
583 expLabel : Nombre del subexperimento (subfolder)
584 ext : extension de los files
584 ext : extension de los files
585 walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath)
585 walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath)
586
586
587 Return:
587 Return:
588 generator with the full path of last filename
588 generator with the full path of last filename
589 """
589 """
590
590
591 if walk:
591 if walk:
592 folders = self.find_folders(
592 folders = self.find_folders(
593 path, startDate, endDate, folderfmt, last=True)
593 path, startDate, endDate, folderfmt, last=True)
594 else:
594 else:
595 folders = path.split(',')
595 folders = path.split(',')
596
596
597 return self.find_files(
597 return self.find_files(
598 folders, ext, filefmt, startDate, endDate, expLabel, last=True)
598 folders, ext, filefmt, startDate, endDate, expLabel, last=True)
599
599
600 def setNextFile(self):
600 def setNextFile(self):
601 """Set the next file to be readed open it and parse de file header"""
601 """Set the next file to be readed open it and parse de file header"""
602
602
603 #print("fp: ",self.fp)
603 #print("fp: ",self.fp)
604 while True:
604 while True:
605
605
606 #print(self.fp)
606 #print(self.fp)
607 if self.fp != None:
607 if self.fp != None:
608 self.fp.close()
608 self.fp.close()
609
609
610 #print("setNextFile")
610 #print("setNextFile")
611 #print("BEFORE OPENING",self.filename)
611 #print("BEFORE OPENING",self.filename)
612 if self.online:
612 if self.online:
613 newFile = self.setNextFileOnline()
613 newFile = self.setNextFileOnline()
614
614
615 else:
615 else:
616
616
617 newFile = self.setNextFileOffline()
617 newFile = self.setNextFileOffline()
618
618
619 #print("newFile: ",newFile)
619 #print("newFile: ",newFile)
620 if not(newFile):
620 if not(newFile):
621
621
622 if self.online:
622 if self.online:
623 raise schainpy.admin.SchainError('Time to wait for new files reach')
623 raise schainpy.admin.SchainError('Time to wait for new files reach')
624 else:
624 else:
625 if self.fileIndex == -1:
625 if self.fileIndex == -1:
626 #print("OKK")
626 #print("OKK")
627 raise schainpy.admin.SchainWarning('No files found in the given path')
627 raise schainpy.admin.SchainWarning('No files found in the given path')
628 else:
628 else:
629
629
630 raise schainpy.admin.SchainWarning('No more files to read')
630 raise schainpy.admin.SchainWarning('No more files to read')
631
631
632 if self.verifyFile(self.filename):
632 if self.verifyFile(self.filename):
633
633
634 break
634 break
635
635
636 ##print("BEFORE OPENING",self.filename)
636 ##print("BEFORE OPENING",self.filename)
637
637
638 log.log('Opening file: %s' % self.filename, self.name)
638 log.log('Opening file: %s' % self.filename, self.name)
639
639
640 self.readFirstHeader()
640 self.readFirstHeader()
641 self.nReadBlocks = 0
641 self.nReadBlocks = 0
642
642
643 def setNextFileOnline(self):
643 def setNextFileOnline(self):
644 """Check for the next file to be readed in online mode.
644 """Check for the next file to be readed in online mode.
645
645
646 Set:
646 Set:
647 self.filename
647 self.filename
648 self.fp
648 self.fp
649 self.filesize
649 self.filesize
650
650
651 Return:
651 Return:
652 boolean
652 boolean
653
653
654 """
654 """
655
655
656 nextFile = True
656 nextFile = True
657 nextDay = False
657 nextDay = False
658
658
659 for nFiles in range(self.nFiles+1):
659 for nFiles in range(self.nFiles+1):
660 for nTries in range(self.nTries):
660 for nTries in range(self.nTries):
661 fullfilename, filename = self.checkForRealPath(nextFile, nextDay)
661 fullfilename, filename = self.checkForRealPath(nextFile, nextDay)
662 if fullfilename is not None:
662 if fullfilename is not None:
663 break
663 break
664 log.warning(
664 log.warning(
665 "Waiting %0.2f sec for the next file: \"%s\" , try %02d ..." % (self.delay, filename, nTries + 1),
665 "Waiting %0.2f sec for the next file: \"%s\" , try %02d ..." % (self.delay, filename, nTries + 1),
666 self.name)
666 self.name)
667 time.sleep(self.delay)
667 time.sleep(self.delay)
668 nextFile = False
668 nextFile = False
669 continue
669 continue
670
670
671 if fullfilename is not None:
671 if fullfilename is not None:
672 break
672 break
673
673
674 #self.nTries = 1
674 #self.nTries = 1
675 nextFile = True
675 nextFile = True
676
676
677 if nFiles == (self.nFiles - 1):
677 if nFiles == (self.nFiles - 1):
678 log.log('Trying with next day...', self.name)
678 log.log('Trying with next day...', self.name)
679 nextDay = True
679 nextDay = True
680 self.nTries = 3
680 self.nTries = 3
681
681
682 if fullfilename:
682 if fullfilename:
683 self.fileSize = os.path.getsize(fullfilename)
683 self.fileSize = os.path.getsize(fullfilename)
684 self.filename = fullfilename
684 self.filename = fullfilename
685 self.flagIsNewFile = 1
685 self.flagIsNewFile = 1
686 if self.fp != None:
686 if self.fp != None:
687 self.fp.close()
687 self.fp.close()
688 #print(fullfilename)
688 #print(fullfilename)
689 self.fp = self.open_file(fullfilename, self.open_mode)
689 self.fp = self.open_file(fullfilename, self.open_mode)
690
690
691 self.flagNoMoreFiles = 0
691 self.flagNoMoreFiles = 0
692 self.fileIndex += 1
692 self.fileIndex += 1
693 return 1
693 return 1
694 else:
694 else:
695 return 0
695 return 0
696
696
697 def setNextFileOffline(self):
697 def setNextFileOffline(self):
698 """Open the next file to be readed in offline mode"""
698 """Open the next file to be readed in offline mode"""
699
699
700 try:
700 try:
701 filename = next(self.filenameList)
701 filename = next(self.filenameList)
702 self.fileIndex +=1
702 self.fileIndex +=1
703 except StopIteration:
703 except StopIteration:
704 self.flagNoMoreFiles = 1
704 self.flagNoMoreFiles = 1
705 return 0
705 return 0
706 #print(self.fileIndex)
706 #print(self.fileIndex)
707 #print(filename)
707 #print(filename)
708 self.filename = filename
708 self.filename = filename
709 self.fileSize = os.path.getsize(filename)
709 self.fileSize = os.path.getsize(filename)
710 self.fp = self.open_file(filename, self.open_mode)
710 self.fp = self.open_file(filename, self.open_mode)
711 self.flagIsNewFile = 1
711 self.flagIsNewFile = 1
712
712
713 return 1
713 return 1
714
714
715 @staticmethod
715 @staticmethod
716 def isDateTimeInRange(dt, startDate, endDate, startTime, endTime):
716 def isDateTimeInRange(dt, startDate, endDate, startTime, endTime):
717 """Check if the given datetime is in range"""
717 """Check if the given datetime is in range"""
718
718
719 if startDate <= dt.date() <= endDate:
719 if startDate <= dt.date() <= endDate:
720 if startTime <= dt.time() <= endTime:
720 if startTime <= dt.time() <= endTime:
721 return True
721 return True
722 return False
722 return False
723
723
724 def verifyFile(self, filename):
724 def verifyFile(self, filename):
725 """Check for a valid file
725 """Check for a valid file
726
726
727 Arguments:
727 Arguments:
728 filename -- full path filename
728 filename -- full path filename
729
729
730 Return:
730 Return:
731 boolean
731 boolean
732 """
732 """
733
733
734 return True
734 return True
735
735
736 def checkForRealPath(self, nextFile, nextDay):
736 def checkForRealPath(self, nextFile, nextDay):
737 """Check if the next file to be readed exists"""
737 """Check if the next file to be readed exists"""
738
738
739 raise NotImplementedError
739 raise NotImplementedError
740
740
741 def readFirstHeader(self):
741 def readFirstHeader(self):
742 """Parse the file header"""
742 """Parse the file header"""
743
743
744
744
745 pass
745 pass
746
746
747 def waitDataBlock(self, pointer_location, blocksize=None):
747 def waitDataBlock(self, pointer_location, blocksize=None):
748 """
748 """
749 """
749 """
750
750
751 currentPointer = pointer_location
751 currentPointer = pointer_location
752 if blocksize is None:
752 if blocksize is None:
753 neededSize = self.processingHeaderObj.blockSize # + self.basicHeaderSize
753 neededSize = self.processingHeaderObj.blockSize # + self.basicHeaderSize
754 else:
754 else:
755 neededSize = blocksize
755 neededSize = blocksize
756
756
757 for nTries in range(self.nTries):
757 for nTries in range(self.nTries):
758 self.fp.close()
758 self.fp.close()
759 self.fp = open(self.filename, 'rb')
759 self.fp = open(self.filename, 'rb')
760 self.fp.seek(currentPointer)
760 self.fp.seek(currentPointer)
761
761
762 self.fileSize = os.path.getsize(self.filename)
762 self.fileSize = os.path.getsize(self.filename)
763 currentSize = self.fileSize - currentPointer
763 currentSize = self.fileSize - currentPointer
764
764
765 if (currentSize >= neededSize):
765 if (currentSize >= neededSize):
766 return 1
766 return 1
767
767
768 log.warning(
768 log.warning(
769 "Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1),
769 "Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1),
770 self.name
770 self.name
771 )
771 )
772 time.sleep(self.delay)
772 time.sleep(self.delay)
773
773
774 return 0
774 return 0
775
775
776 class JRODataReader(Reader):
776 class JRODataReader(Reader):
777
777
778 utc = 0
778 utc = 0
779 nReadBlocks = 0
779 nReadBlocks = 0
780 foldercounter = 0
780 foldercounter = 0
781 firstHeaderSize = 0
781 firstHeaderSize = 0
782 basicHeaderSize = 24
782 basicHeaderSize = 24
783 __isFirstTimeOnline = 1
783 __isFirstTimeOnline = 1
784 filefmt = "*%Y%j***"
784 filefmt = "*%Y%j***"
785 folderfmt = "*%Y%j"
785 folderfmt = "*%Y%j"
786 __attrs__ = ['path', 'startDate', 'endDate', 'startTime', 'endTime', 'online', 'delay', 'walk']
786 __attrs__ = ['path', 'startDate', 'endDate', 'startTime', 'endTime', 'online', 'delay', 'walk']
787
787
788 def getDtypeWidth(self):
788 def getDtypeWidth(self):
789
789
790 dtype_index = get_dtype_index(self.dtype)
790 dtype_index = get_dtype_index(self.dtype)
791 dtype_width = get_dtype_width(dtype_index)
791 dtype_width = get_dtype_width(dtype_index)
792
792
793 return dtype_width
793 return dtype_width
794
794
795 def checkForRealPath(self, nextFile, nextDay):
795 def checkForRealPath(self, nextFile, nextDay):
796 """Check if the next file to be readed exists.
796 """Check if the next file to be readed exists.
797
797
798 Example :
798 Example :
799 nombre correcto del file es .../.../D2009307/P2009307367.ext
799 nombre correcto del file es .../.../D2009307/P2009307367.ext
800
800
801 Entonces la funcion prueba con las siguientes combinaciones
801 Entonces la funcion prueba con las siguientes combinaciones
802 .../.../y2009307367.ext
802 .../.../y2009307367.ext
803 .../.../Y2009307367.ext
803 .../.../Y2009307367.ext
804 .../.../x2009307/y2009307367.ext
804 .../.../x2009307/y2009307367.ext
805 .../.../x2009307/Y2009307367.ext
805 .../.../x2009307/Y2009307367.ext
806 .../.../X2009307/y2009307367.ext
806 .../.../X2009307/y2009307367.ext
807 .../.../X2009307/Y2009307367.ext
807 .../.../X2009307/Y2009307367.ext
808 siendo para este caso, la ultima combinacion de letras, identica al file buscado
808 siendo para este caso, la ultima combinacion de letras, identica al file buscado
809
809
810 Return:
810 Return:
811 str -- fullpath of the file
811 str -- fullpath of the file
812 """
812 """
813
813
814
814
815 if nextFile:
815 if nextFile:
816 self.set += 1
816 self.set += 1
817 if nextDay:
817 if nextDay:
818 self.set = 0
818 self.set = 0
819 self.doy += 1
819 self.doy += 1
820 foldercounter = 0
820 foldercounter = 0
821 prefixDirList = [None, 'd', 'D']
821 prefixDirList = [None, 'd', 'D']
822 if self.ext.lower() == ".r": # voltage
822 if self.ext.lower() == ".r": # voltage
823 prefixFileList = ['d', 'D']
823 prefixFileList = ['d', 'D']
824 elif self.ext.lower() == ".pdata": # spectra
824 elif self.ext.lower() == ".pdata": # spectra
825 prefixFileList = ['p', 'P']
825 prefixFileList = ['p', 'P']
826
826
827 ##############DP##############
827 ##############DP##############
828
828
829 elif self.ext.lower() == ".dat": # dat
829 elif self.ext.lower() == ".dat": # dat
830 prefixFileList = ['z', 'Z']
830 prefixFileList = ['z', 'Z']
831
831
832
832
833
833
834 ##############DP##############
834 ##############DP##############
835 # barrido por las combinaciones posibles
835 # barrido por las combinaciones posibles
836 for prefixDir in prefixDirList:
836 for prefixDir in prefixDirList:
837 thispath = self.path
837 thispath = self.path
838 if prefixDir != None:
838 if prefixDir != None:
839 # formo el nombre del directorio xYYYYDDD (x=d o x=D)
839 # formo el nombre del directorio xYYYYDDD (x=d o x=D)
840 if foldercounter == 0:
840 if foldercounter == 0:
841 thispath = os.path.join(self.path, "%s%04d%03d" %
841 thispath = os.path.join(self.path, "%s%04d%03d" %
842 (prefixDir, self.year, self.doy))
842 (prefixDir, self.year, self.doy))
843 else:
843 else:
844 thispath = os.path.join(self.path, "%s%04d%03d_%02d" % (
844 thispath = os.path.join(self.path, "%s%04d%03d_%02d" % (
845 prefixDir, self.year, self.doy, foldercounter))
845 prefixDir, self.year, self.doy, foldercounter))
846 for prefixFile in prefixFileList: # barrido por las dos combinaciones posibles de "D"
846 for prefixFile in prefixFileList: # barrido por las dos combinaciones posibles de "D"
847 # formo el nombre del file xYYYYDDDSSS.ext
847 # formo el nombre del file xYYYYDDDSSS.ext
848 filename = "%s%04d%03d%03d%s" % (prefixFile, self.year, self.doy, self.set, self.ext)
848 filename = "%s%04d%03d%03d%s" % (prefixFile, self.year, self.doy, self.set, self.ext)
849 fullfilename = os.path.join(
849 fullfilename = os.path.join(
850 thispath, filename)
850 thispath, filename)
851
851
852 if os.path.exists(fullfilename):
852 if os.path.exists(fullfilename):
853 return fullfilename, filename
853 return fullfilename, filename
854
854
855 return None, filename
855 return None, filename
856
856
857 def __waitNewBlock(self):
857 def __waitNewBlock(self):
858 """
858 """
859 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
859 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
860
860
861 Si el modo de lectura es OffLine siempre retorn 0
861 Si el modo de lectura es OffLine siempre retorn 0
862 """
862 """
863 if not self.online:
863 if not self.online:
864 return 0
864 return 0
865
865
866 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
866 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
867 return 0
867 return 0
868
868
869 currentPointer = self.fp.tell()
869 currentPointer = self.fp.tell()
870
870
871 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
871 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
872
872
873 for nTries in range(self.nTries):
873 for nTries in range(self.nTries):
874
874
875 self.fp.close()
875 self.fp.close()
876 self.fp = open(self.filename, 'rb')
876 self.fp = open(self.filename, 'rb')
877 self.fp.seek(currentPointer)
877 self.fp.seek(currentPointer)
878
878
879 self.fileSize = os.path.getsize(self.filename)
879 self.fileSize = os.path.getsize(self.filename)
880 currentSize = self.fileSize - currentPointer
880 currentSize = self.fileSize - currentPointer
881
881
882 if (currentSize >= neededSize):
882 if (currentSize >= neededSize):
883 self.basicHeaderObj.read(self.fp)
883 self.basicHeaderObj.read(self.fp)
884 return 1
884 return 1
885
885
886 if self.fileSize == self.fileSizeByHeader:
886 if self.fileSize == self.fileSizeByHeader:
887 # self.flagEoF = True
887 # self.flagEoF = True
888 return 0
888 return 0
889
889
890 print("[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1))
890 print("[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1))
891 #print(self.filename)
891 #print(self.filename)
892 time.sleep(self.delay)
892 time.sleep(self.delay)
893
893
894 return 0
894 return 0
895
895
896 def __setNewBlock(self):
896 def __setNewBlock(self):
897
897
898 if self.fp == None:
898 if self.fp == None:
899 return 0
899 return 0
900
900
901 if self.flagIsNewFile:
901 if self.flagIsNewFile:
902 self.lastUTTime = self.basicHeaderObj.utc
902 self.lastUTTime = self.basicHeaderObj.utc
903 return 1
903 return 1
904
904
905 if self.realtime:
905 if self.realtime:
906 self.flagDiscontinuousBlock = 1
906 self.flagDiscontinuousBlock = 1
907 if not(self.setNextFile()):
907 if not(self.setNextFile()):
908 return 0
908 return 0
909 else:
909 else:
910 return 1
910 return 1
911
911
912 currentSize = self.fileSize - self.fp.tell()
912 currentSize = self.fileSize - self.fp.tell()
913 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
913 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
914
914
915 if (currentSize >= neededSize):
915 if (currentSize >= neededSize):
916 self.basicHeaderObj.read(self.fp)
916 self.basicHeaderObj.read(self.fp)
917 self.lastUTTime = self.basicHeaderObj.utc
917 self.lastUTTime = self.basicHeaderObj.utc
918 return 1
918 return 1
919
919
920 if self.__waitNewBlock():
920 if self.__waitNewBlock():
921 self.lastUTTime = self.basicHeaderObj.utc
921 self.lastUTTime = self.basicHeaderObj.utc
922 return 1
922 return 1
923
923
924 if not(self.setNextFile()):
924 if not(self.setNextFile()):
925 return 0
925 return 0
926
926
927 deltaTime = self.basicHeaderObj.utc - self.lastUTTime
927 deltaTime = self.basicHeaderObj.utc - self.lastUTTime
928 self.lastUTTime = self.basicHeaderObj.utc
928 self.lastUTTime = self.basicHeaderObj.utc
929
929
930 self.flagDiscontinuousBlock = 0
930 self.flagDiscontinuousBlock = 0
931
932 if deltaTime > self.maxTimeStep:
931 if deltaTime > self.maxTimeStep:
933 self.flagDiscontinuousBlock = 1
932 self.flagDiscontinuousBlock = 1
934
933
935 return 1
934 return 1
936
935
937 def readNextBlock(self):
936 def readNextBlock(self):
938
937
939 while True:
938 while True:
940 if not(self.__setNewBlock()):
939 if not(self.__setNewBlock()):
941 continue
940 continue
942
941
943 if not(self.readBlock()):
942 if not(self.readBlock()):
944 return 0
943 return 0
945
944
946 self.getBasicHeader()
945 self.getBasicHeader()
947
946
948 if not self.isDateTimeInRange(self.dataOut.datatime, self.startDate, self.endDate, self.startTime, self.endTime):
947 if not self.isDateTimeInRange(self.dataOut.datatime, self.startDate, self.endDate, self.startTime, self.endTime):
949 print("[Reading] Block No. %d/%d -> %s [Skipping]" % (self.nReadBlocks,
948 print("[Reading] Block No. %d/%d -> %s [Skipping]" % (self.nReadBlocks,
950 self.processingHeaderObj.dataBlocksPerFile,
949 self.processingHeaderObj.dataBlocksPerFile,
951 self.dataOut.datatime.ctime()))
950 self.dataOut.datatime.ctime()))
952 continue
951 continue
953
952
954 break
953 break
955
954
956 if self.verbose:
955 if self.verbose:
957 print("[Reading] Block No. %d/%d -> %s" % (self.nReadBlocks,
956 print("[Reading] Block No. %d/%d -> %s" % (self.nReadBlocks,
958 self.processingHeaderObj.dataBlocksPerFile,
957 self.processingHeaderObj.dataBlocksPerFile,
959 self.dataOut.datatime.ctime()))
958 self.dataOut.datatime.ctime()))
960 #################DP#################
959 #################DP#################
961 self.dataOut.TimeBlockDate=self.dataOut.datatime.ctime()
960 self.dataOut.TimeBlockDate=self.dataOut.datatime.ctime()
962 self.dataOut.TimeBlockSeconds=time.mktime(time.strptime(self.dataOut.datatime.ctime()))
961 self.dataOut.TimeBlockSeconds=time.mktime(time.strptime(self.dataOut.datatime.ctime()))
963 #################DP#################
962 #################DP#################
964 return 1
963 return 1
965
964
966 def readFirstHeader(self):
965 def readFirstHeader(self):
967
966
968 self.basicHeaderObj.read(self.fp)
967 self.basicHeaderObj.read(self.fp)
969 self.systemHeaderObj.read(self.fp)
968 self.systemHeaderObj.read(self.fp)
970 self.radarControllerHeaderObj.read(self.fp)
969 self.radarControllerHeaderObj.read(self.fp)
971 self.processingHeaderObj.read(self.fp)
970 self.processingHeaderObj.read(self.fp)
972 self.firstHeaderSize = self.basicHeaderObj.size
971 self.firstHeaderSize = self.basicHeaderObj.size
973
972
974 datatype = int(numpy.log2((self.processingHeaderObj.processFlags &
973 datatype = int(numpy.log2((self.processingHeaderObj.processFlags &
975 PROCFLAG.DATATYPE_MASK)) - numpy.log2(PROCFLAG.DATATYPE_CHAR))
974 PROCFLAG.DATATYPE_MASK)) - numpy.log2(PROCFLAG.DATATYPE_CHAR))
976 if datatype == 0:
975 if datatype == 0:
977 datatype_str = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
976 datatype_str = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
978 elif datatype == 1:
977 elif datatype == 1:
979 datatype_str = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
978 datatype_str = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
980 elif datatype == 2:
979 elif datatype == 2:
981 datatype_str = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
980 datatype_str = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
982 elif datatype == 3:
981 elif datatype == 3:
983 datatype_str = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
982 datatype_str = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
984 elif datatype == 4:
983 elif datatype == 4:
985 datatype_str = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
984 datatype_str = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
986 elif datatype == 5:
985 elif datatype == 5:
987 datatype_str = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
986 datatype_str = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
988 else:
987 else:
989 raise ValueError('Data type was not defined')
988 raise ValueError('Data type was not defined')
990
989
991 self.dtype = datatype_str
990 self.dtype = datatype_str
992 #self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
991 #self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
993 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + \
992 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + \
994 self.firstHeaderSize + self.basicHeaderSize * \
993 self.firstHeaderSize + self.basicHeaderSize * \
995 (self.processingHeaderObj.dataBlocksPerFile - 1)
994 (self.processingHeaderObj.dataBlocksPerFile - 1)
996 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
995 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
997 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
996 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
998 self.getBlockDimension()
997 self.getBlockDimension()
999
998
1000 def verifyFile(self, filename):
999 def verifyFile(self, filename):
1001
1000
1002 flag = True
1001 flag = True
1003
1002
1004 try:
1003 try:
1005 fp = open(filename, 'rb')
1004 fp = open(filename, 'rb')
1006 except IOError:
1005 except IOError:
1007 log.error("File {} can't be opened".format(filename), self.name)
1006 log.error("File {} can't be opened".format(filename), self.name)
1008 return False
1007 return False
1009
1008
1010 if self.online and self.waitDataBlock(0):
1009 if self.online and self.waitDataBlock(0):
1011 pass
1010 pass
1012
1011
1013 basicHeaderObj = BasicHeader(LOCALTIME)
1012 basicHeaderObj = BasicHeader(LOCALTIME)
1014 systemHeaderObj = SystemHeader()
1013 systemHeaderObj = SystemHeader()
1015 radarControllerHeaderObj = RadarControllerHeader()
1014 radarControllerHeaderObj = RadarControllerHeader()
1016 processingHeaderObj = ProcessingHeader()
1015 processingHeaderObj = ProcessingHeader()
1017
1016
1018 if not(basicHeaderObj.read(fp)):
1017 if not(basicHeaderObj.read(fp)):
1019 flag = False
1018 flag = False
1020 if not(systemHeaderObj.read(fp)):
1019 if not(systemHeaderObj.read(fp)):
1021 flag = False
1020 flag = False
1022 if not(radarControllerHeaderObj.read(fp)):
1021 if not(radarControllerHeaderObj.read(fp)):
1023 flag = False
1022 flag = False
1024 if not(processingHeaderObj.read(fp)):
1023 if not(processingHeaderObj.read(fp)):
1025 flag = False
1024 flag = False
1026 if not self.online:
1025 if not self.online:
1027 dt1 = basicHeaderObj.datatime
1026 dt1 = basicHeaderObj.datatime
1028 pos = self.fileSize-processingHeaderObj.blockSize-24
1027 pos = self.fileSize-processingHeaderObj.blockSize-24
1029 if pos<0:
1028 if pos<0:
1030 flag = False
1029 flag = False
1031 log.error('Invalid size for file: {}'.format(self.filename), self.name)
1030 log.error('Invalid size for file: {}'.format(self.filename), self.name)
1032 else:
1031 else:
1033 fp.seek(pos)
1032 fp.seek(pos)
1034 if not(basicHeaderObj.read(fp)):
1033 if not(basicHeaderObj.read(fp)):
1035 flag = False
1034 flag = False
1036 dt2 = basicHeaderObj.datatime
1035 dt2 = basicHeaderObj.datatime
1037 if not self.isDateTimeInRange(dt1, self.startDate, self.endDate, self.startTime, self.endTime) and not \
1036 if not self.isDateTimeInRange(dt1, self.startDate, self.endDate, self.startTime, self.endTime) and not \
1038 self.isDateTimeInRange(dt2, self.startDate, self.endDate, self.startTime, self.endTime):
1037 self.isDateTimeInRange(dt2, self.startDate, self.endDate, self.startTime, self.endTime):
1039 flag = False
1038 flag = False
1040
1039
1041 fp.close()
1040 fp.close()
1042 return flag
1041 return flag
1043
1042
1044 def findDatafiles(self, path, startDate=None, endDate=None, expLabel='', ext='.r', walk=True, include_path=False):
1043 def findDatafiles(self, path, startDate=None, endDate=None, expLabel='', ext='.r', walk=True, include_path=False):
1045
1044
1046 path_empty = True
1045 path_empty = True
1047
1046
1048 dateList = []
1047 dateList = []
1049 pathList = []
1048 pathList = []
1050
1049
1051 multi_path = path.split(',')
1050 multi_path = path.split(',')
1052
1051
1053 if not walk:
1052 if not walk:
1054
1053
1055 for single_path in multi_path:
1054 for single_path in multi_path:
1056
1055
1057 if not os.path.isdir(single_path):
1056 if not os.path.isdir(single_path):
1058 continue
1057 continue
1059
1058
1060 fileList = glob.glob1(single_path, "*" + ext)
1059 fileList = glob.glob1(single_path, "*" + ext)
1061
1060
1062 if not fileList:
1061 if not fileList:
1063 continue
1062 continue
1064
1063
1065 path_empty = False
1064 path_empty = False
1066
1065
1067 fileList.sort()
1066 fileList.sort()
1068
1067
1069 for thisFile in fileList:
1068 for thisFile in fileList:
1070
1069
1071 if not os.path.isfile(os.path.join(single_path, thisFile)):
1070 if not os.path.isfile(os.path.join(single_path, thisFile)):
1072 continue
1071 continue
1073
1072
1074 if not isRadarFile(thisFile):
1073 if not isRadarFile(thisFile):
1075 continue
1074 continue
1076
1075
1077 if not isFileInDateRange(thisFile, startDate, endDate):
1076 if not isFileInDateRange(thisFile, startDate, endDate):
1078 continue
1077 continue
1079
1078
1080 thisDate = getDateFromRadarFile(thisFile)
1079 thisDate = getDateFromRadarFile(thisFile)
1081
1080
1082 if thisDate in dateList or single_path in pathList:
1081 if thisDate in dateList or single_path in pathList:
1083 continue
1082 continue
1084
1083
1085 dateList.append(thisDate)
1084 dateList.append(thisDate)
1086 pathList.append(single_path)
1085 pathList.append(single_path)
1087
1086
1088 else:
1087 else:
1089 for single_path in multi_path:
1088 for single_path in multi_path:
1090
1089
1091 if not os.path.isdir(single_path):
1090 if not os.path.isdir(single_path):
1092 continue
1091 continue
1093
1092
1094 dirList = []
1093 dirList = []
1095
1094
1096 for thisPath in os.listdir(single_path):
1095 for thisPath in os.listdir(single_path):
1097
1096
1098 if not os.path.isdir(os.path.join(single_path, thisPath)):
1097 if not os.path.isdir(os.path.join(single_path, thisPath)):
1099 continue
1098 continue
1100
1099
1101 if not isRadarFolder(thisPath):
1100 if not isRadarFolder(thisPath):
1102 continue
1101 continue
1103
1102
1104 if not isFolderInDateRange(thisPath, startDate, endDate):
1103 if not isFolderInDateRange(thisPath, startDate, endDate):
1105 continue
1104 continue
1106
1105
1107 dirList.append(thisPath)
1106 dirList.append(thisPath)
1108
1107
1109 if not dirList:
1108 if not dirList:
1110 continue
1109 continue
1111
1110
1112 dirList.sort()
1111 dirList.sort()
1113
1112
1114 for thisDir in dirList:
1113 for thisDir in dirList:
1115
1114
1116 datapath = os.path.join(single_path, thisDir, expLabel)
1115 datapath = os.path.join(single_path, thisDir, expLabel)
1117 fileList = glob.glob1(datapath, "*" + ext)
1116 fileList = glob.glob1(datapath, "*" + ext)
1118
1117
1119 if not fileList:
1118 if not fileList:
1120 continue
1119 continue
1121
1120
1122 path_empty = False
1121 path_empty = False
1123
1122
1124 thisDate = getDateFromRadarFolder(thisDir)
1123 thisDate = getDateFromRadarFolder(thisDir)
1125
1124
1126 pathList.append(datapath)
1125 pathList.append(datapath)
1127 dateList.append(thisDate)
1126 dateList.append(thisDate)
1128
1127
1129 dateList.sort()
1128 dateList.sort()
1130
1129
1131 if walk:
1130 if walk:
1132 pattern_path = os.path.join(multi_path[0], "[dYYYYDDD]", expLabel)
1131 pattern_path = os.path.join(multi_path[0], "[dYYYYDDD]", expLabel)
1133 else:
1132 else:
1134 pattern_path = multi_path[0]
1133 pattern_path = multi_path[0]
1135
1134
1136 if path_empty:
1135 if path_empty:
1137 raise schainpy.admin.SchainError("[Reading] No *%s files in %s for %s to %s" % (ext, pattern_path, startDate, endDate))
1136 raise schainpy.admin.SchainError("[Reading] No *%s files in %s for %s to %s" % (ext, pattern_path, startDate, endDate))
1138 else:
1137 else:
1139 if not dateList:
1138 if not dateList:
1140 raise schainpy.admin.SchainError("[Reading] Date range selected invalid [%s - %s]: No *%s files in %s)" % (startDate, endDate, ext, path))
1139 raise schainpy.admin.SchainError("[Reading] Date range selected invalid [%s - %s]: No *%s files in %s)" % (startDate, endDate, ext, path))
1141
1140
1142 if include_path:
1141 if include_path:
1143 return dateList, pathList
1142 return dateList, pathList
1144
1143
1145 return dateList
1144 return dateList
1146
1145
1147 def setup(self, **kwargs):
1146 def setup(self, **kwargs):
1148
1147
1149 self.set_kwargs(**kwargs)
1148 self.set_kwargs(**kwargs)
1150 if not self.ext.startswith('.'):
1149 if not self.ext.startswith('.'):
1151 self.ext = '.{}'.format(self.ext)
1150 self.ext = '.{}'.format(self.ext)
1152
1151
1153 if self.server is not None:
1152 if self.server is not None:
1154 if 'tcp://' in self.server:
1153 if 'tcp://' in self.server:
1155 address = server
1154 address = server
1156 else:
1155 else:
1157 address = 'ipc:///tmp/%s' % self.server
1156 address = 'ipc:///tmp/%s' % self.server
1158 self.server = address
1157 self.server = address
1159 self.context = zmq.Context()
1158 self.context = zmq.Context()
1160 self.receiver = self.context.socket(zmq.PULL)
1159 self.receiver = self.context.socket(zmq.PULL)
1161 self.receiver.connect(self.server)
1160 self.receiver.connect(self.server)
1162 time.sleep(0.5)
1161 time.sleep(0.5)
1163 print('[Starting] ReceiverData from {}'.format(self.server))
1162 print('[Starting] ReceiverData from {}'.format(self.server))
1164 else:
1163 else:
1165 self.server = None
1164 self.server = None
1166 if self.path == None:
1165 if self.path == None:
1167 raise ValueError("[Reading] The path is not valid")
1166 raise ValueError("[Reading] The path is not valid")
1168
1167
1169 if self.online:
1168 if self.online:
1170 log.log("[Reading] Searching files in online mode...", self.name)
1169 log.log("[Reading] Searching files in online mode...", self.name)
1171
1170
1172 for nTries in range(self.nTries):
1171 for nTries in range(self.nTries):
1173 fullpath = self.searchFilesOnLine(self.path, self.startDate,
1172 fullpath = self.searchFilesOnLine(self.path, self.startDate,
1174 self.endDate, self.expLabel, self.ext, self.walk,
1173 self.endDate, self.expLabel, self.ext, self.walk,
1175 self.filefmt, self.folderfmt)
1174 self.filefmt, self.folderfmt)
1176
1175
1177 try:
1176 try:
1178 fullpath = next(fullpath)
1177 fullpath = next(fullpath)
1179 except:
1178 except:
1180 fullpath = None
1179 fullpath = None
1181
1180
1182 if fullpath:
1181 if fullpath:
1183 break
1182 break
1184
1183
1185 log.warning(
1184 log.warning(
1186 'Waiting {} sec for a valid file in {}: try {} ...'.format(
1185 'Waiting {} sec for a valid file in {}: try {} ...'.format(
1187 self.delay, self.path, nTries + 1),
1186 self.delay, self.path, nTries + 1),
1188 self.name)
1187 self.name)
1189 time.sleep(self.delay)
1188 time.sleep(self.delay)
1190
1189
1191 if not(fullpath):
1190 if not(fullpath):
1192 raise schainpy.admin.SchainError(
1191 raise schainpy.admin.SchainError(
1193 'There isn\'t any valid file in {}'.format(self.path))
1192 'There isn\'t any valid file in {}'.format(self.path))
1194
1193
1195 pathname, filename = os.path.split(fullpath)
1194 pathname, filename = os.path.split(fullpath)
1196 self.year = int(filename[1:5])
1195 self.year = int(filename[1:5])
1197 self.doy = int(filename[5:8])
1196 self.doy = int(filename[5:8])
1198 self.set = int(filename[8:11]) - 1
1197 self.set = int(filename[8:11]) - 1
1199 else:
1198 else:
1200 log.log("Searching files in {}".format(self.path), self.name)
1199 log.log("Searching files in {}".format(self.path), self.name)
1201 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
1200 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
1202 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
1201 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
1203
1202
1204 self.setNextFile()
1203 self.setNextFile()
1205
1204
1206 return
1205 return
1207
1206
1208 def getBasicHeader(self):
1207 def getBasicHeader(self):
1209
1208
1210 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond / \
1209 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond / \
1211 1000. + self.profileIndex * self.radarControllerHeaderObj.ippSeconds
1210 1000. + self.profileIndex * self.radarControllerHeaderObj.ippSeconds
1212
1211
1213 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
1212 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
1214
1213
1215 self.dataOut.timeZone = self.basicHeaderObj.timeZone
1214 self.dataOut.timeZone = self.basicHeaderObj.timeZone
1216
1215
1217 self.dataOut.dstFlag = self.basicHeaderObj.dstFlag
1216 self.dataOut.dstFlag = self.basicHeaderObj.dstFlag
1218
1217
1219 self.dataOut.errorCount = self.basicHeaderObj.errorCount
1218 self.dataOut.errorCount = self.basicHeaderObj.errorCount
1220
1219
1221 self.dataOut.useLocalTime = self.basicHeaderObj.useLocalTime
1220 self.dataOut.useLocalTime = self.basicHeaderObj.useLocalTime
1222
1221
1223 self.dataOut.ippSeconds = self.radarControllerHeaderObj.ippSeconds / self.nTxs
1222 self.dataOut.ippSeconds = self.radarControllerHeaderObj.ippSeconds / self.nTxs
1224
1223
1225 def getFirstHeader(self):
1224 def getFirstHeader(self):
1226
1225
1227 raise NotImplementedError
1226 raise NotImplementedError
1228
1227
1229 def getData(self):
1228 def getData(self):
1230
1229
1231 raise NotImplementedError
1230 raise NotImplementedError
1232
1231
1233 def hasNotDataInBuffer(self):
1232 def hasNotDataInBuffer(self):
1234
1233
1235 raise NotImplementedError
1234 raise NotImplementedError
1236
1235
1237 def readBlock(self):
1236 def readBlock(self):
1238
1237
1239 raise NotImplementedError
1238 raise NotImplementedError
1240
1239
1241 def isEndProcess(self):
1240 def isEndProcess(self):
1242
1241
1243 return self.flagNoMoreFiles
1242 return self.flagNoMoreFiles
1244
1243
1245 def printReadBlocks(self):
1244 def printReadBlocks(self):
1246
1245
1247 print("[Reading] Number of read blocks per file %04d" % self.nReadBlocks)
1246 print("[Reading] Number of read blocks per file %04d" % self.nReadBlocks)
1248
1247
1249 def printTotalBlocks(self):
1248 def printTotalBlocks(self):
1250
1249
1251 print("[Reading] Number of read blocks %04d" % self.nTotalBlocks)
1250 print("[Reading] Number of read blocks %04d" % self.nTotalBlocks)
1252
1251
1253 def run(self, **kwargs):
1252 def run(self, **kwargs):
1254 """
1253 """
1255
1254
1256 Arguments:
1255 Arguments:
1257 path :
1256 path :
1258 startDate :
1257 startDate :
1259 endDate :
1258 endDate :
1260 startTime :
1259 startTime :
1261 endTime :
1260 endTime :
1262 set :
1261 set :
1263 expLabel :
1262 expLabel :
1264 ext :
1263 ext :
1265 online :
1264 online :
1266 delay :
1265 delay :
1267 walk :
1266 walk :
1268 getblock :
1267 getblock :
1269 nTxs :
1268 nTxs :
1270 realtime :
1269 realtime :
1271 blocksize :
1270 blocksize :
1272 blocktime :
1271 blocktime :
1273 skip :
1272 skip :
1274 cursor :
1273 cursor :
1275 warnings :
1274 warnings :
1276 server :
1275 server :
1277 verbose :
1276 verbose :
1278 format :
1277 format :
1279 oneDDict :
1278 oneDDict :
1280 twoDDict :
1279 twoDDict :
1281 independentParam :
1280 independentParam :
1282 """
1281 """
1283
1282
1284 if not(self.isConfig):
1283 if not(self.isConfig):
1285 self.setup(**kwargs)
1284 self.setup(**kwargs)
1286 self.isConfig = True
1285 self.isConfig = True
1287 if self.server is None:
1286 if self.server is None:
1288 self.getData()
1287 self.getData()
1289 else:
1288 else:
1290 self.getFromServer()
1289 self.getFromServer()
1291
1290
1292
1291
1293 class JRODataWriter(Reader):
1292 class JRODataWriter(Reader):
1294
1293
1295 """
1294 """
1296 Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura
1295 Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura
1297 de los datos siempre se realiza por bloques.
1296 de los datos siempre se realiza por bloques.
1298 """
1297 """
1299
1298
1300 setFile = None
1299 setFile = None
1301 profilesPerBlock = None
1300 profilesPerBlock = None
1302 blocksPerFile = None
1301 blocksPerFile = None
1303 nWriteBlocks = 0
1302 nWriteBlocks = 0
1304 fileDate = None
1303 fileDate = None
1305
1304
1306 def __init__(self, dataOut=None):
1305 def __init__(self, dataOut=None):
1307 raise NotImplementedError
1306 raise NotImplementedError
1308
1307
1309 def hasAllDataInBuffer(self):
1308 def hasAllDataInBuffer(self):
1310 raise NotImplementedError
1309 raise NotImplementedError
1311
1310
1312 def setBlockDimension(self):
1311 def setBlockDimension(self):
1313 raise NotImplementedError
1312 raise NotImplementedError
1314
1313
1315 def writeBlock(self):
1314 def writeBlock(self):
1316 raise NotImplementedError
1315 raise NotImplementedError
1317
1316
1318 def putData(self):
1317 def putData(self):
1319 raise NotImplementedError
1318 raise NotImplementedError
1320
1319
1321 def getDtypeWidth(self):
1320 def getDtypeWidth(self):
1322
1321
1323 dtype_index = get_dtype_index(self.dtype)
1322 dtype_index = get_dtype_index(self.dtype)
1324 dtype_width = get_dtype_width(dtype_index)
1323 dtype_width = get_dtype_width(dtype_index)
1325
1324
1326 return dtype_width
1325 return dtype_width
1327
1326
1328 def getProcessFlags(self):
1327 def getProcessFlags(self):
1329
1328
1330 processFlags = 0
1329 processFlags = 0
1331
1330
1332 dtype_index = get_dtype_index(self.dtype)
1331 dtype_index = get_dtype_index(self.dtype)
1333 procflag_dtype = get_procflag_dtype(dtype_index)
1332 procflag_dtype = get_procflag_dtype(dtype_index)
1334
1333
1335 processFlags += procflag_dtype
1334 processFlags += procflag_dtype
1336
1335
1337 if self.dataOut.flagDecodeData:
1336 if self.dataOut.flagDecodeData:
1338 processFlags += PROCFLAG.DECODE_DATA
1337 processFlags += PROCFLAG.DECODE_DATA
1339
1338
1340 if self.dataOut.flagDeflipData:
1339 if self.dataOut.flagDeflipData:
1341 processFlags += PROCFLAG.DEFLIP_DATA
1340 processFlags += PROCFLAG.DEFLIP_DATA
1342
1341
1343 if self.dataOut.code is not None:
1342 if self.dataOut.code is not None:
1344 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
1343 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
1345
1344
1346 if self.dataOut.nCohInt > 1:
1345 if self.dataOut.nCohInt > 1:
1347 processFlags += PROCFLAG.COHERENT_INTEGRATION
1346 processFlags += PROCFLAG.COHERENT_INTEGRATION
1348
1347
1349 if self.dataOut.type == "Spectra":
1348 if self.dataOut.type == "Spectra":
1350 if self.dataOut.nIncohInt > 1:
1349 if self.dataOut.nIncohInt > 1:
1351 processFlags += PROCFLAG.INCOHERENT_INTEGRATION
1350 processFlags += PROCFLAG.INCOHERENT_INTEGRATION
1352
1351
1353 if self.dataOut.data_dc is not None:
1352 if self.dataOut.data_dc is not None:
1354 processFlags += PROCFLAG.SAVE_CHANNELS_DC
1353 processFlags += PROCFLAG.SAVE_CHANNELS_DC
1355
1354
1356 if self.dataOut.flagShiftFFT:
1355 if self.dataOut.flagShiftFFT:
1357 processFlags += PROCFLAG.SHIFT_FFT_DATA
1356 processFlags += PROCFLAG.SHIFT_FFT_DATA
1358
1357
1359 return processFlags
1358 return processFlags
1360
1359
1361 def setBasicHeader(self):
1360 def setBasicHeader(self):
1362
1361
1363 self.basicHeaderObj.size = self.basicHeaderSize # bytes
1362 self.basicHeaderObj.size = self.basicHeaderSize # bytes
1364 self.basicHeaderObj.version = self.versionFile
1363 self.basicHeaderObj.version = self.versionFile
1365 self.basicHeaderObj.dataBlock = self.nTotalBlocks
1364 self.basicHeaderObj.dataBlock = self.nTotalBlocks
1366 utc = numpy.floor(self.dataOut.utctime)
1365 utc = numpy.floor(self.dataOut.utctime)
1367 milisecond = (self.dataOut.utctime - utc) * 1000.0
1366 milisecond = (self.dataOut.utctime - utc) * 1000.0
1368 self.basicHeaderObj.utc = utc
1367 self.basicHeaderObj.utc = utc
1369 self.basicHeaderObj.miliSecond = milisecond
1368 self.basicHeaderObj.miliSecond = milisecond
1370 self.basicHeaderObj.timeZone = self.dataOut.timeZone
1369 self.basicHeaderObj.timeZone = self.dataOut.timeZone
1371 self.basicHeaderObj.dstFlag = self.dataOut.dstFlag
1370 self.basicHeaderObj.dstFlag = self.dataOut.dstFlag
1372 self.basicHeaderObj.errorCount = self.dataOut.errorCount
1371 self.basicHeaderObj.errorCount = self.dataOut.errorCount
1373
1372
1374 def setFirstHeader(self):
1373 def setFirstHeader(self):
1375 """
1374 """
1376 Obtiene una copia del First Header
1375 Obtiene una copia del First Header
1377
1376
1378 Affected:
1377 Affected:
1379
1378
1380 self.basicHeaderObj
1379 self.basicHeaderObj
1381 self.systemHeaderObj
1380 self.systemHeaderObj
1382 self.radarControllerHeaderObj
1381 self.radarControllerHeaderObj
1383 self.processingHeaderObj self.
1382 self.processingHeaderObj self.
1384
1383
1385 Return:
1384 Return:
1386 None
1385 None
1387 """
1386 """
1388
1387
1389 raise NotImplementedError
1388 raise NotImplementedError
1390
1389
1391 def __writeFirstHeader(self):
1390 def __writeFirstHeader(self):
1392 """
1391 """
1393 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
1392 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
1394
1393
1395 Affected:
1394 Affected:
1396 __dataType
1395 __dataType
1397
1396
1398 Return:
1397 Return:
1399 None
1398 None
1400 """
1399 """
1401
1400
1402 # CALCULAR PARAMETROS
1401 # CALCULAR PARAMETROS
1403
1402
1404 sizeLongHeader = self.systemHeaderObj.size + \
1403 sizeLongHeader = self.systemHeaderObj.size + \
1405 self.radarControllerHeaderObj.size + self.processingHeaderObj.size
1404 self.radarControllerHeaderObj.size + self.processingHeaderObj.size
1406 self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader
1405 self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader
1407
1406
1408 self.basicHeaderObj.write(self.fp)
1407 self.basicHeaderObj.write(self.fp)
1409 self.systemHeaderObj.write(self.fp)
1408 self.systemHeaderObj.write(self.fp)
1410 self.radarControllerHeaderObj.write(self.fp)
1409 self.radarControllerHeaderObj.write(self.fp)
1411 self.processingHeaderObj.write(self.fp)
1410 self.processingHeaderObj.write(self.fp)
1412
1411
1413 def __setNewBlock(self):
1412 def __setNewBlock(self):
1414 """
1413 """
1415 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
1414 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
1416
1415
1417 Return:
1416 Return:
1418 0 : si no pudo escribir nada
1417 0 : si no pudo escribir nada
1419 1 : Si escribio el Basic el First Header
1418 1 : Si escribio el Basic el First Header
1420 """
1419 """
1421 if self.fp == None:
1420 if self.fp == None:
1422 self.setNextFile()
1421 self.setNextFile()
1423
1422
1424 if self.flagIsNewFile:
1423 if self.flagIsNewFile:
1425 return 1
1424 return 1
1426
1425
1427 if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile:
1426 if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile:
1428 self.basicHeaderObj.write(self.fp)
1427 self.basicHeaderObj.write(self.fp)
1429 return 1
1428 return 1
1430
1429
1431 if not(self.setNextFile()):
1430 if not(self.setNextFile()):
1432 return 0
1431 return 0
1433
1432
1434 return 1
1433 return 1
1435
1434
1436 def writeNextBlock(self):
1435 def writeNextBlock(self):
1437 """
1436 """
1438 Selecciona el bloque siguiente de datos y los escribe en un file
1437 Selecciona el bloque siguiente de datos y los escribe en un file
1439
1438
1440 Return:
1439 Return:
1441 0 : Si no hizo pudo escribir el bloque de datos
1440 0 : Si no hizo pudo escribir el bloque de datos
1442 1 : Si no pudo escribir el bloque de datos
1441 1 : Si no pudo escribir el bloque de datos
1443 """
1442 """
1444 if not(self.__setNewBlock()):
1443 if not(self.__setNewBlock()):
1445 return 0
1444 return 0
1446
1445
1447 self.writeBlock()
1446 self.writeBlock()
1448
1447
1449 print("[Writing] Block No. %d/%d" % (self.blockIndex,
1448 print("[Writing] Block No. %d/%d" % (self.blockIndex,
1450 self.processingHeaderObj.dataBlocksPerFile))
1449 self.processingHeaderObj.dataBlocksPerFile))
1451
1450
1452 return 1
1451 return 1
1453
1452
1454 def setNextFile(self):
1453 def setNextFile(self):
1455 """Determina el siguiente file que sera escrito
1454 """Determina el siguiente file que sera escrito
1456
1455
1457 Affected:
1456 Affected:
1458 self.filename
1457 self.filename
1459 self.subfolder
1458 self.subfolder
1460 self.fp
1459 self.fp
1461 self.setFile
1460 self.setFile
1462 self.flagIsNewFile
1461 self.flagIsNewFile
1463
1462
1464 Return:
1463 Return:
1465 0 : Si el archivo no puede ser escrito
1464 0 : Si el archivo no puede ser escrito
1466 1 : Si el archivo esta listo para ser escrito
1465 1 : Si el archivo esta listo para ser escrito
1467 """
1466 """
1468 ext = self.ext
1467 ext = self.ext
1469 path = self.path
1468 path = self.path
1470
1469
1471 if self.fp != None:
1470 if self.fp != None:
1472 self.fp.close()
1471 self.fp.close()
1473
1472
1474 if not os.path.exists(path):
1473 if not os.path.exists(path):
1475 os.mkdir(path)
1474 os.mkdir(path)
1476
1475
1477 timeTuple = time.localtime(self.dataOut.utctime)
1476 timeTuple = time.localtime(self.dataOut.utctime)
1478 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year, timeTuple.tm_yday)
1477 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year, timeTuple.tm_yday)
1479
1478
1480 fullpath = os.path.join(path, subfolder)
1479 fullpath = os.path.join(path, subfolder)
1481 setFile = self.setFile
1480 setFile = self.setFile
1482
1481
1483 if not(os.path.exists(fullpath)):
1482 if not(os.path.exists(fullpath)):
1484 os.mkdir(fullpath)
1483 os.mkdir(fullpath)
1485 setFile = -1 # inicializo mi contador de seteo
1484 setFile = -1 # inicializo mi contador de seteo
1486 else:
1485 else:
1487 filesList = os.listdir(fullpath)
1486 filesList = os.listdir(fullpath)
1488 if len(filesList) > 0:
1487 if len(filesList) > 0:
1489 filesList = sorted(filesList, key=str.lower)
1488 filesList = sorted(filesList, key=str.lower)
1490 filen = filesList[-1]
1489 filen = filesList[-1]
1491 # el filename debera tener el siguiente formato
1490 # el filename debera tener el siguiente formato
1492 # 0 1234 567 89A BCDE (hex)
1491 # 0 1234 567 89A BCDE (hex)
1493 # x YYYY DDD SSS .ext
1492 # x YYYY DDD SSS .ext
1494 if isNumber(filen[8:11]):
1493 if isNumber(filen[8:11]):
1495 # inicializo mi contador de seteo al seteo del ultimo file
1494 # inicializo mi contador de seteo al seteo del ultimo file
1496 setFile = int(filen[8:11])
1495 setFile = int(filen[8:11])
1497 else:
1496 else:
1498 setFile = -1
1497 setFile = -1
1499 else:
1498 else:
1500 setFile = -1 # inicializo mi contador de seteo
1499 setFile = -1 # inicializo mi contador de seteo
1501
1500
1502 setFile += 1
1501 setFile += 1
1503
1502
1504 # If this is a new day it resets some values
1503 # If this is a new day it resets some values
1505 if self.dataOut.datatime.date() > self.fileDate:
1504 if self.dataOut.datatime.date() > self.fileDate:
1506 setFile = 0
1505 setFile = 0
1507 self.nTotalBlocks = 0
1506 self.nTotalBlocks = 0
1508
1507
1509 filen = '{}{:04d}{:03d}{:03d}{}'.format(
1508 filen = '{}{:04d}{:03d}{:03d}{}'.format(
1510 self.optchar, timeTuple.tm_year, timeTuple.tm_yday, setFile, ext)
1509 self.optchar, timeTuple.tm_year, timeTuple.tm_yday, setFile, ext)
1511
1510
1512 filename = os.path.join(path, subfolder, filen)
1511 filename = os.path.join(path, subfolder, filen)
1513
1512
1514 fp = open(filename, 'wb')
1513 fp = open(filename, 'wb')
1515
1514
1516 self.blockIndex = 0
1515 self.blockIndex = 0
1517 self.filename = filename
1516 self.filename = filename
1518 self.subfolder = subfolder
1517 self.subfolder = subfolder
1519 self.fp = fp
1518 self.fp = fp
1520 self.setFile = setFile
1519 self.setFile = setFile
1521 self.flagIsNewFile = 1
1520 self.flagIsNewFile = 1
1522 self.fileDate = self.dataOut.datatime.date()
1521 self.fileDate = self.dataOut.datatime.date()
1523 self.setFirstHeader()
1522 self.setFirstHeader()
1524
1523
1525 print('[Writing] Opening file: %s' % self.filename)
1524 print('[Writing] Opening file: %s' % self.filename)
1526
1525
1527 self.__writeFirstHeader()
1526 self.__writeFirstHeader()
1528
1527
1529 return 1
1528 return 1
1530
1529
1531 def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4):
1530 def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4):
1532 """
1531 """
1533 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1532 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1534
1533
1535 Inputs:
1534 Inputs:
1536 path : directory where data will be saved
1535 path : directory where data will be saved
1537 profilesPerBlock : number of profiles per block
1536 profilesPerBlock : number of profiles per block
1538 set : initial file set
1537 set : initial file set
1539 datatype : An integer number that defines data type:
1538 datatype : An integer number that defines data type:
1540 0 : int8 (1 byte)
1539 0 : int8 (1 byte)
1541 1 : int16 (2 bytes)
1540 1 : int16 (2 bytes)
1542 2 : int32 (4 bytes)
1541 2 : int32 (4 bytes)
1543 3 : int64 (8 bytes)
1542 3 : int64 (8 bytes)
1544 4 : float32 (4 bytes)
1543 4 : float32 (4 bytes)
1545 5 : double64 (8 bytes)
1544 5 : double64 (8 bytes)
1546
1545
1547 Return:
1546 Return:
1548 0 : Si no realizo un buen seteo
1547 0 : Si no realizo un buen seteo
1549 1 : Si realizo un buen seteo
1548 1 : Si realizo un buen seteo
1550 """
1549 """
1551
1550
1552 if ext == None:
1551 if ext == None:
1553 ext = self.ext
1552 ext = self.ext
1554
1553
1555 self.ext = ext.lower()
1554 self.ext = ext.lower()
1556
1555
1557 self.path = path
1556 self.path = path
1558
1557
1559 if set is None:
1558 if set is None:
1560 self.setFile = -1
1559 self.setFile = -1
1561 else:
1560 else:
1562 self.setFile = set - 1
1561 self.setFile = set - 1
1563
1562
1564 self.blocksPerFile = blocksPerFile
1563 self.blocksPerFile = blocksPerFile
1565 self.profilesPerBlock = profilesPerBlock
1564 self.profilesPerBlock = profilesPerBlock
1566 self.dataOut = dataOut
1565 self.dataOut = dataOut
1567 self.fileDate = self.dataOut.datatime.date()
1566 self.fileDate = self.dataOut.datatime.date()
1568 self.dtype = self.dataOut.dtype
1567 self.dtype = self.dataOut.dtype
1569
1568
1570 if datatype is not None:
1569 if datatype is not None:
1571 self.dtype = get_numpy_dtype(datatype)
1570 self.dtype = get_numpy_dtype(datatype)
1572
1571
1573 if not(self.setNextFile()):
1572 if not(self.setNextFile()):
1574 print("[Writing] There isn't a next file")
1573 print("[Writing] There isn't a next file")
1575 return 0
1574 return 0
1576
1575
1577 self.setBlockDimension()
1576 self.setBlockDimension()
1578
1577
1579 return 1
1578 return 1
1580
1579
1581 def run(self, dataOut, path, blocksPerFile=100, profilesPerBlock=64, set=None, ext=None, datatype=4, **kwargs):
1580 def run(self, dataOut, path, blocksPerFile=100, profilesPerBlock=64, set=None, ext=None, datatype=4, **kwargs):
1582
1581
1583 if not(self.isConfig):
1582 if not(self.isConfig):
1584
1583
1585 self.setup(dataOut, path, blocksPerFile, profilesPerBlock=profilesPerBlock,
1584 self.setup(dataOut, path, blocksPerFile, profilesPerBlock=profilesPerBlock,
1586 set=set, ext=ext, datatype=datatype, **kwargs)
1585 set=set, ext=ext, datatype=datatype, **kwargs)
1587 self.isConfig = True
1586 self.isConfig = True
1588
1587
1589 self.dataOut = dataOut
1588 self.dataOut = dataOut
1590 self.putData()
1589 self.putData()
1591 return self.dataOut
1590 return self.dataOut
1592
1591
1593 @MPDecorator
1592 @MPDecorator
1594 class printInfo(Operation):
1593 class printInfo(Operation):
1595
1594
1596 def __init__(self):
1595 def __init__(self):
1597
1596
1598 Operation.__init__(self)
1597 Operation.__init__(self)
1599 self.__printInfo = True
1598 self.__printInfo = True
1600
1599
1601 def run(self, dataOut, headers = ['systemHeaderObj', 'radarControllerHeaderObj', 'processingHeaderObj']):
1600 def run(self, dataOut, headers = ['systemHeaderObj', 'radarControllerHeaderObj', 'processingHeaderObj']):
1602 if self.__printInfo == False:
1601 if self.__printInfo == False:
1603 return
1602 return
1604
1603
1605 for header in headers:
1604 for header in headers:
1606 if hasattr(dataOut, header):
1605 if hasattr(dataOut, header):
1607 obj = getattr(dataOut, header)
1606 obj = getattr(dataOut, header)
1608 if hasattr(obj, 'printInfo'):
1607 if hasattr(obj, 'printInfo'):
1609 obj.printInfo()
1608 obj.printInfo()
1610 else:
1609 else:
1611 print(obj)
1610 print(obj)
1612 else:
1611 else:
1613 log.warning('Header {} Not found in object'.format(header))
1612 log.warning('Header {} Not found in object'.format(header))
1614
1613
1615 self.__printInfo = False
1614 self.__printInfo = False
@@ -1,630 +1,648
1 '''
1 '''
2 Created on Aug 1, 2017
2 Created on Aug 1, 2017
3
3
4 @author: Juan C. Espinoza
4 @author: Juan C. Espinoza
5 '''
5 '''
6
6
7 import os
7 import os
8 import sys
8 import sys
9 import time
9 import time
10 import json
10 import json
11 import glob
11 import glob
12 import datetime
12 import datetime
13
13
14 import numpy
14 import numpy
15 import h5py
15 import h5py
16
16
17 import schainpy.admin
17 import schainpy.admin
18 from schainpy.model.io.jroIO_base import LOCALTIME, Reader
18 from schainpy.model.io.jroIO_base import LOCALTIME, Reader
19 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
19 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
20 from schainpy.model.data.jrodata import Parameters
20 from schainpy.model.data.jrodata import Parameters
21 from schainpy.utils import log
21 from schainpy.utils import log
22
22
23 try:
23 try:
24 import madrigal.cedar
24 import madrigal.cedar
25 except:
25 except:
26 pass
26 pass
27
27
28 try:
28 try:
29 basestring
29 basestring
30 except:
30 except:
31 basestring = str
31 basestring = str
32
32
33 DEF_CATALOG = {
33 DEF_CATALOG = {
34 'principleInvestigator': 'Marco Milla',
34 'principleInvestigator': 'Marco Milla',
35 'expPurpose': '',
35 'expPurpose': '',
36 'cycleTime': '',
36 'cycleTime': '',
37 'correlativeExp': '',
37 'correlativeExp': '',
38 'sciRemarks': '',
38 'sciRemarks': '',
39 'instRemarks': ''
39 'instRemarks': ''
40 }
40 }
41
41
42 DEF_HEADER = {
42 DEF_HEADER = {
43 'kindatDesc': '',
43 'kindatDesc': '',
44 'analyst': 'Jicamarca User',
44 'analyst': 'Jicamarca User',
45 'comments': '',
45 'comments': '',
46 'history': ''
46 'history': ''
47 }
47 }
48
48
49 MNEMONICS = {
49 MNEMONICS = {
50 10: 'jro',
50 10: 'jro',
51 11: 'jbr',
51 11: 'jbr',
52 840: 'jul',
52 840: 'jul',
53 13: 'jas',
53 13: 'jas',
54 1000: 'pbr',
54 1000: 'pbr',
55 1001: 'hbr',
55 1001: 'hbr',
56 1002: 'obr',
56 1002: 'obr',
57 400: 'clr'
57 400: 'clr'
58
58
59 }
59 }
60
60
61 UT1970 = datetime.datetime(1970, 1, 1) - datetime.timedelta(seconds=time.timezone)
61 UT1970 = datetime.datetime(1970, 1, 1) - datetime.timedelta(seconds=time.timezone)
62
62
63 def load_json(obj):
63 def load_json(obj):
64 '''
64 '''
65 Parse json as string instead of unicode
65 Parse json as string instead of unicode
66 '''
66 '''
67
67
68 if isinstance(obj, str):
68 if isinstance(obj, str):
69 iterable = json.loads(obj)
69 iterable = json.loads(obj)
70 else:
70 else:
71 iterable = obj
71 iterable = obj
72
72
73 if isinstance(iterable, dict):
73 if isinstance(iterable, dict):
74 return {str(k): load_json(v) if isinstance(v, dict) else str(v) if isinstance(v, basestring) else v
74 return {str(k): load_json(v) if isinstance(v, dict) else str(v) if isinstance(v, basestring) else v
75 for k, v in list(iterable.items())}
75 for k, v in list(iterable.items())}
76 elif isinstance(iterable, (list, tuple)):
76 elif isinstance(iterable, (list, tuple)):
77 return [str(v) if isinstance(v, basestring) else v for v in iterable]
77 return [str(v) if isinstance(v, basestring) else v for v in iterable]
78
78
79 return iterable
79 return iterable
80
80
81
81
82 class MADReader(Reader, ProcessingUnit):
82 class MADReader(Reader, ProcessingUnit):
83
83
84 def __init__(self):
84 def __init__(self):
85
85
86 ProcessingUnit.__init__(self)
86 ProcessingUnit.__init__(self)
87
87
88 self.dataOut = Parameters()
88 self.dataOut = Parameters()
89 self.counter_records = 0
89 self.counter_records = 0
90 self.nrecords = None
90 self.nrecords = None
91 self.flagNoMoreFiles = 0
91 self.flagNoMoreFiles = 0
92 self.filename = None
92 self.filename = None
93 self.intervals = set()
93 self.intervals = set()
94 self.datatime = datetime.datetime(1900,1,1)
94 self.datatime = datetime.datetime(1900,1,1)
95 self.format = None
95 self.format = None
96 self.filefmt = "***%Y%m%d*******"
96 self.filefmt = "***%Y%m%d*******"
97
97
98 def setup(self, **kwargs):
98 def setup(self, **kwargs):
99
99
100 self.set_kwargs(**kwargs)
100 self.set_kwargs(**kwargs)
101 self.oneDDict = load_json(self.oneDDict)
101 self.oneDDict = load_json(self.oneDDict)
102 self.twoDDict = load_json(self.twoDDict)
102 self.twoDDict = load_json(self.twoDDict)
103 self.ind2DList = load_json(self.ind2DList)
103 self.ind2DList = load_json(self.ind2DList)
104 self.independentParam = self.ind2DList[0]
104 self.independentParam = self.ind2DList[0]
105
105
106 if self.path is None:
106 if self.path is None:
107 raise ValueError('The path is not valid')
107 raise ValueError('The path is not valid')
108
108
109 self.open_file = open
109 self.open_file = open
110 self.open_mode = 'rb'
110 self.open_mode = 'rb'
111
111
112 if self.format is None:
112 if self.format is None:
113 raise ValueError('The format is not valid choose simple or hdf5')
113 raise ValueError('The format is not valid choose simple or hdf5')
114 elif self.format.lower() in ('simple', 'txt'):
114 elif self.format.lower() in ('simple', 'txt'):
115 self.ext = '.txt'
115 self.ext = '.txt'
116 elif self.format.lower() in ('cedar',):
116 elif self.format.lower() in ('cedar',):
117 self.ext = '.001'
117 self.ext = '.001'
118 else:
118 else:
119 self.ext = '.hdf5'
119 self.ext = '.hdf5'
120 self.open_file = h5py.File
120 self.open_file = h5py.File
121 self.open_mode = 'r'
121 self.open_mode = 'r'
122
122
123 if self.online:
123 if self.online:
124 log.log("Searching files in online mode...", self.name)
124 log.log("Searching files in online mode...", self.name)
125
125
126 for nTries in range(self.nTries):
126 for nTries in range(self.nTries):
127 fullpath = self.searchFilesOnLine(self.path, self.startDate,
127 fullpath = self.searchFilesOnLine(self.path, self.startDate,
128 self.endDate, self.expLabel, self.ext, self.walk,
128 self.endDate, self.expLabel, self.ext, self.walk,
129 self.filefmt, self.folderfmt)
129 self.filefmt, self.folderfmt)
130
130
131 try:
131 try:
132 fullpath = next(fullpath)
132 fullpath = next(fullpath)
133 except:
133 except:
134 fullpath = None
134 fullpath = None
135
135
136 if fullpath:
136 if fullpath:
137 break
137 break
138
138
139 log.warning(
139 log.warning(
140 'Waiting {} sec for a valid file in {}: try {} ...'.format(
140 'Waiting {} sec for a valid file in {}: try {} ...'.format(
141 self.delay, self.path, nTries + 1),
141 self.delay, self.path, nTries + 1),
142 self.name)
142 self.name)
143 time.sleep(self.delay)
143 time.sleep(self.delay)
144
144
145 if not(fullpath):
145 if not(fullpath):
146 raise schainpy.admin.SchainError(
146 raise schainpy.admin.SchainError(
147 'There isn\'t any valid file in {}'.format(self.path))
147 'There isn\'t any valid file in {}'.format(self.path))
148
148
149 else:
149 else:
150 log.log("Searching files in {}".format(self.path), self.name)
150 log.log("Searching files in {}".format(self.path), self.name)
151 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
151 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
152 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
152 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
153
153
154 self.setNextFile()
154 self.setNextFile()
155
155
156 def readFirstHeader(self):
156 def readFirstHeader(self):
157 '''Read header and data'''
157 '''Read header and data'''
158
158
159 self.parseHeader()
159 self.parseHeader()
160 self.parseData()
160 self.parseData()
161 self.blockIndex = 0
161 self.blockIndex = 0
162
162
163 return
163 return
164
164
165 def parseHeader(self):
165 def parseHeader(self):
166 '''
166 '''
167 '''
167 '''
168
168
169 self.output = {}
169 self.output = {}
170 self.version = '2'
170 self.version = '2'
171 s_parameters = None
171 s_parameters = None
172 if self.ext == '.txt':
172 if self.ext == '.txt':
173 self.parameters = [s.strip().lower() for s in self.fp.readline().decode().strip().split(' ') if s]
173 self.parameters = [s.strip().lower() for s in self.fp.readline().decode().strip().split(' ') if s]
174 elif self.ext == '.hdf5':
174 elif self.ext == '.hdf5':
175 self.metadata = self.fp['Metadata']
175 self.metadata = self.fp['Metadata']
176 if '_record_layout' in self.metadata:
176 if '_record_layout' in self.metadata:
177 s_parameters = [s[0].lower().decode() for s in self.metadata['Independent Spatial Parameters']]
177 s_parameters = [s[0].lower().decode() for s in self.metadata['Independent Spatial Parameters']]
178 self.version = '3'
178 self.version = '3'
179 self.parameters = [s[0].lower().decode() for s in self.metadata['Data Parameters']]
179 self.parameters = [s[0].lower().decode() for s in self.metadata['Data Parameters']]
180
180
181 log.success('Parameters found: {}'.format(self.parameters),
181 log.success('Parameters found: {}'.format(self.parameters),
182 'MADReader')
182 'MADReader')
183 if s_parameters:
183 if s_parameters:
184 log.success('Spatial parameters found: {}'.format(s_parameters),
184 log.success('Spatial parameters found: {}'.format(s_parameters),
185 'MADReader')
185 'MADReader')
186
186
187 for param in list(self.oneDDict.keys()):
187 for param in list(self.oneDDict.keys()):
188 if param.lower() not in self.parameters:
188 if param.lower() not in self.parameters:
189 log.warning(
189 log.warning(
190 'Parameter {} not found will be ignored'.format(
190 'Parameter {} not found will be ignored'.format(
191 param),
191 param),
192 'MADReader')
192 'MADReader')
193 self.oneDDict.pop(param, None)
193 self.oneDDict.pop(param, None)
194
194
195 for param, value in list(self.twoDDict.items()):
195 for param, value in list(self.twoDDict.items()):
196 if param.lower() not in self.parameters:
196 if param.lower() not in self.parameters:
197 log.warning(
197 log.warning(
198 'Parameter {} not found, it will be ignored'.format(
198 'Parameter {} not found, it will be ignored'.format(
199 param),
199 param),
200 'MADReader')
200 'MADReader')
201 self.twoDDict.pop(param, None)
201 self.twoDDict.pop(param, None)
202 continue
202 continue
203 if isinstance(value, list):
203 if isinstance(value, list):
204 if value[0] not in self.output:
204 if value[0] not in self.output:
205 self.output[value[0]] = []
205 self.output[value[0]] = []
206 self.output[value[0]].append([])
206 self.output[value[0]].append([])
207
207
208 def parseData(self):
208 def parseData(self):
209 '''
209 '''
210 '''
210 '''
211
211
212 if self.ext == '.txt':
212 if self.ext == '.txt':
213 self.data = numpy.genfromtxt(self.fp, missing_values=('missing'))
213 self.data = numpy.genfromtxt(self.fp, missing_values=('missing'))
214 self.nrecords = self.data.shape[0]
214 self.nrecords = self.data.shape[0]
215 self.ranges = numpy.unique(self.data[:,self.parameters.index(self.independentParam.lower())])
215 self.ranges = numpy.unique(self.data[:,self.parameters.index(self.independentParam.lower())])
216 self.counter_records = 0
216 self.counter_records = 0
217 elif self.ext == '.hdf5':
217 elif self.ext == '.hdf5':
218 self.data = self.fp['Data']
218 self.data = self.fp['Data']
219 self.ranges = numpy.unique(self.data['Table Layout'][self.independentParam.lower()])
219 self.ranges = numpy.unique(self.data['Table Layout'][self.independentParam.lower()])
220 self.times = numpy.unique(self.data['Table Layout']['ut1_unix'])
220 self.times = numpy.unique(self.data['Table Layout']['ut1_unix'])
221 self.counter_records = int(self.data['Table Layout']['recno'][0])
221 self.counter_records = int(self.data['Table Layout']['recno'][0])
222 self.nrecords = int(self.data['Table Layout']['recno'][-1])
222 self.nrecords = int(self.data['Table Layout']['recno'][-1])
223
223
224 def readNextBlock(self):
224 def readNextBlock(self):
225
225
226 while True:
226 while True:
227 self.flagDiscontinuousBlock = 0
227 self.flagDiscontinuousBlock = 0
228 if self.counter_records == self.nrecords:
228 if self.counter_records == self.nrecords:
229 self.setNextFile()
229 self.setNextFile()
230
230
231 self.readBlock()
231 self.readBlock()
232
232
233 if (self.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or \
233 if (self.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or \
234 (self.datatime > datetime.datetime.combine(self.endDate, self.endTime)):
234 (self.datatime > datetime.datetime.combine(self.endDate, self.endTime)):
235 log.warning(
235 log.warning(
236 'Reading Record No. {}/{} -> {} [Skipping]'.format(
236 'Reading Record No. {}/{} -> {} [Skipping]'.format(
237 self.counter_records,
237 self.counter_records,
238 self.nrecords,
238 self.nrecords,
239 self.datatime.ctime()),
239 self.datatime.ctime()),
240 'MADReader')
240 'MADReader')
241 continue
241 continue
242 break
242 break
243
243
244 log.log(
244 log.log(
245 'Reading Record No. {}/{} -> {}'.format(
245 'Reading Record No. {}/{} -> {}'.format(
246 self.counter_records,
246 self.counter_records,
247 self.nrecords,
247 self.nrecords,
248 self.datatime.ctime()),
248 self.datatime.ctime()),
249 'MADReader')
249 'MADReader')
250
250
251 return 1
251 return 1
252
252
253 def readBlock(self):
253 def readBlock(self):
254 '''
254 '''
255 '''
255 '''
256 dum = []
256 dum = []
257 if self.ext == '.txt':
257 if self.ext == '.txt':
258 dt = self.data[self.counter_records][:6].astype(int)
258 dt = self.data[self.counter_records][:6].astype(int)
259 if datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5]).date() > self.datatime.date():
259 if datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5]).date() > self.datatime.date():
260 self.flagDiscontinuousBlock = 1
260 self.flagDiscontinuousBlock = 1
261 self.datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5])
261 self.datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5])
262 while True:
262 while True:
263 dt = self.data[self.counter_records][:6].astype(int)
263 dt = self.data[self.counter_records][:6].astype(int)
264 datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5])
264 datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5])
265 if datatime == self.datatime:
265 if datatime == self.datatime:
266 dum.append(self.data[self.counter_records])
266 dum.append(self.data[self.counter_records])
267 self.counter_records += 1
267 self.counter_records += 1
268 if self.counter_records == self.nrecords:
268 if self.counter_records == self.nrecords:
269 break
269 break
270 continue
270 continue
271 self.intervals.add((datatime-self.datatime).seconds)
271 self.intervals.add((datatime-self.datatime).seconds)
272 break
272 break
273 elif self.ext == '.hdf5':
273 elif self.ext == '.hdf5':
274 datatime = datetime.datetime.utcfromtimestamp(
274 datatime = datetime.datetime.utcfromtimestamp(
275 self.times[self.counter_records])
275 self.times[self.counter_records])
276 dum = self.data['Table Layout'][self.data['Table Layout']['recno']==self.counter_records]
276 dum = self.data['Table Layout'][self.data['Table Layout']['recno']==self.counter_records]
277 self.intervals.add((datatime-self.datatime).seconds)
277 self.intervals.add((datatime-self.datatime).seconds)
278 if datatime.date()>self.datatime.date():
278 if datatime.date()>self.datatime.date():
279 self.flagDiscontinuousBlock = 1
279 self.flagDiscontinuousBlock = 1
280 self.datatime = datatime
280 self.datatime = datatime
281 self.counter_records += 1
281 self.counter_records += 1
282
282
283 self.buffer = numpy.array(dum)
283 self.buffer = numpy.array(dum)
284 return
284 return
285
285
286 def set_output(self):
286 def set_output(self):
287 '''
287 '''
288 Storing data from buffer to dataOut object
288 Storing data from buffer to dataOut object
289 '''
289 '''
290
290
291 parameters = [None for __ in self.parameters]
291 parameters = [None for __ in self.parameters]
292
292
293 for param, attr in list(self.oneDDict.items()):
293 for param, attr in list(self.oneDDict.items()):
294 x = self.parameters.index(param.lower())
294 x = self.parameters.index(param.lower())
295 setattr(self.dataOut, attr, self.buffer[0][x])
295 setattr(self.dataOut, attr, self.buffer[0][x])
296
296
297 for param, value in list(self.twoDDict.items()):
297 for param, value in list(self.twoDDict.items()):
298 dummy = numpy.zeros(self.ranges.shape) + numpy.nan
298 dummy = numpy.zeros(self.ranges.shape) + numpy.nan
299 if self.ext == '.txt':
299 if self.ext == '.txt':
300 x = self.parameters.index(param.lower())
300 x = self.parameters.index(param.lower())
301 y = self.parameters.index(self.independentParam.lower())
301 y = self.parameters.index(self.independentParam.lower())
302 ranges = self.buffer[:,y]
302 ranges = self.buffer[:,y]
303 #if self.ranges.size == ranges.size:
303 #if self.ranges.size == ranges.size:
304 # continue
304 # continue
305 index = numpy.where(numpy.in1d(self.ranges, ranges))[0]
305 index = numpy.where(numpy.in1d(self.ranges, ranges))[0]
306 dummy[index] = self.buffer[:,x]
306 dummy[index] = self.buffer[:,x]
307 else:
307 else:
308 ranges = self.buffer[self.independentParam.lower()]
308 ranges = self.buffer[self.independentParam.lower()]
309 index = numpy.where(numpy.in1d(self.ranges, ranges))[0]
309 index = numpy.where(numpy.in1d(self.ranges, ranges))[0]
310 dummy[index] = self.buffer[param.lower()]
310 dummy[index] = self.buffer[param.lower()]
311
311
312 if isinstance(value, str):
312 if isinstance(value, str):
313 if value not in self.independentParam:
313 if value not in self.independentParam:
314 setattr(self.dataOut, value, dummy.reshape(1,-1))
314 setattr(self.dataOut, value, dummy.reshape(1,-1))
315 elif isinstance(value, list):
315 elif isinstance(value, list):
316 self.output[value[0]][value[1]] = dummy
316 self.output[value[0]][value[1]] = dummy
317 parameters[value[1]] = param
317 parameters[value[1]] = param
318 for key, value in list(self.output.items()):
318 for key, value in list(self.output.items()):
319 setattr(self.dataOut, key, numpy.array(value))
319 setattr(self.dataOut, key, numpy.array(value))
320
320
321 self.dataOut.parameters = [s for s in parameters if s]
321 self.dataOut.parameters = [s for s in parameters if s]
322 self.dataOut.heightList = self.ranges
322 self.dataOut.heightList = self.ranges
323 self.dataOut.utctime = (self.datatime - datetime.datetime(1970, 1, 1)).total_seconds()
323 self.dataOut.utctime = (self.datatime - datetime.datetime(1970, 1, 1)).total_seconds()
324 self.dataOut.utctimeInit = self.dataOut.utctime
324 self.dataOut.utctimeInit = self.dataOut.utctime
325 self.dataOut.paramInterval = min(self.intervals)
325 self.dataOut.paramInterval = min(self.intervals)
326 self.dataOut.useLocalTime = False
326 self.dataOut.useLocalTime = False
327 self.dataOut.flagNoData = False
327 self.dataOut.flagNoData = False
328 self.dataOut.nrecords = self.nrecords
328 self.dataOut.nrecords = self.nrecords
329 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
329 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
330
330
331 def getData(self):
331 def getData(self):
332 '''
332 '''
333 Storing data from databuffer to dataOut object
333 Storing data from databuffer to dataOut object
334 '''
334 '''
335
335
336 if not self.readNextBlock():
336 if not self.readNextBlock():
337 self.dataOut.flagNoData = True
337 self.dataOut.flagNoData = True
338 return 0
338 return 0
339
339
340 self.set_output()
340 self.set_output()
341
341
342 return 1
342 return 1
343
343
344 def run(self, **kwargs):
344 def run(self, **kwargs):
345
345
346 if not(self.isConfig):
346 if not(self.isConfig):
347 self.setup(**kwargs)
347 self.setup(**kwargs)
348 self.isConfig = True
348 self.isConfig = True
349
349
350 self.getData()
350 self.getData()
351
351
352 return
352 return
353
353
354 @MPDecorator
354 @MPDecorator
355 class MADWriter(Operation):
355 class MADWriter(Operation):
356 '''Writing module for Madrigal files
356 '''Writing module for Madrigal files
357
357
358 type: external
358 type: external
359
359
360 Inputs:
360 Inputs:
361 path path where files will be created
361 path path where files will be created
362 oneDDict json of one-dimensional parameters in record where keys
362 oneDDict json of one-dimensional parameters in record where keys
363 are Madrigal codes (integers or mnemonics) and values the corresponding
363 are Madrigal codes (integers or mnemonics) and values the corresponding
364 dataOut attribute e.g: {
364 dataOut attribute e.g: {
365 'gdlatr': 'lat',
365 'gdlatr': 'lat',
366 'gdlonr': 'lon',
366 'gdlonr': 'lon',
367 'gdlat2':'lat',
367 'gdlat2':'lat',
368 'glon2':'lon'}
368 'glon2':'lon'}
369 ind2DList list of independent spatial two-dimensional parameters e.g:
369 ind2DList list of independent spatial two-dimensional parameters e.g:
370 ['heigthList']
370 ['heigthList']
371 twoDDict json of two-dimensional parameters in record where keys
371 twoDDict json of two-dimensional parameters in record where keys
372 are Madrigal codes (integers or mnemonics) and values the corresponding
372 are Madrigal codes (integers or mnemonics) and values the corresponding
373 dataOut attribute if multidimensional array specify as tupple
373 dataOut attribute if multidimensional array specify as tupple
374 ('attr', pos) e.g: {
374 ('attr', pos) e.g: {
375 'gdalt': 'heightList',
375 'gdalt': 'heightList',
376 'vn1p2': ('data_output', 0),
376 'vn1p2': ('data_output', 0),
377 'vn2p2': ('data_output', 1),
377 'vn2p2': ('data_output', 1),
378 'vn3': ('data_output', 2),
378 'vn3': ('data_output', 2),
379 'snl': ('data_SNR', 'db')
379 'snl': ('data_SNR', 'db')
380 }
380 }
381 metadata json of madrigal metadata (kinst, kindat, catalog and header)
381 metadata json of madrigal metadata (kinst, kindat, catalog and header)
382 format hdf5, cedar
382 format hdf5, cedar
383 blocks number of blocks per file'''
383 blocks number of blocks per file'''
384
384
385 __attrs__ = ['path', 'oneDDict', 'ind2DList', 'twoDDict','metadata', 'format', 'blocks']
385 __attrs__ = ['path', 'oneDDict', 'ind2DList', 'twoDDict','metadata', 'format', 'blocks']
386 missing = -32767
386 missing = -32767
387 currentDay = None
387
388
388 def __init__(self):
389 def __init__(self):
389
390
390 Operation.__init__(self)
391 Operation.__init__(self)
391 self.dataOut = Parameters()
392 self.dataOut = Parameters()
392 self.counter = 0
393 self.counter = 0
393 self.path = None
394 self.path = None
394 self.fp = None
395 self.fp = None
395
396
396 def run(self, dataOut, path, oneDDict, ind2DList='[]', twoDDict='{}',
397 def run(self, dataOut, path, oneDDict, ind2DList='[]', twoDDict='{}',
397 metadata='{}', format='cedar', **kwargs):
398 metadata='{}', format='cedar', **kwargs):
398
399
399
400
400 #if dataOut.AUX==1: #Modified
401 #if dataOut.AUX==1: #Modified
401
402
402 if not self.isConfig:
403 if not self.isConfig:
403 self.setup(path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs)
404 self.setup(path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs)
404 self.isConfig = True
405 self.isConfig = True
405
406
406 self.dataOut = dataOut
407 self.dataOut = dataOut
407 self.putData()
408 self.putData()
408
409
409 return 1
410 return 1
410
411
411 def setup(self, path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs):
412 def setup(self, path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs):
412 '''
413 '''
413 Configure Operation
414 Configure Operation
414 '''
415 '''
415
416
416 self.path = path
417 self.path = path
417 self.blocks = kwargs.get('blocks', None)
418 self.blocks = kwargs.get('blocks', None)
418 self.counter = 0
419 self.counter = 0
419 self.oneDDict = load_json(oneDDict)
420 self.oneDDict = load_json(oneDDict)
420 self.twoDDict = load_json(twoDDict)
421 self.twoDDict = load_json(twoDDict)
421 self.ind2DList = load_json(ind2DList)
422 self.ind2DList = load_json(ind2DList)
422 meta = load_json(metadata)
423 meta = load_json(metadata)
423 self.kinst = meta.get('kinst')
424 self.kinst = meta.get('kinst')
424 self.kindat = meta.get('kindat')
425 self.kindat = meta.get('kindat')
425 self.catalog = meta.get('catalog', DEF_CATALOG)
426 self.catalog = meta.get('catalog', DEF_CATALOG)
426 self.header = meta.get('header', DEF_HEADER)
427 self.header = meta.get('header', DEF_HEADER)
427 if format == 'cedar':
428 if format == 'cedar':
428 self.ext = '.dat'
429 self.ext = '.dat'
429 self.extra_args = {}
430 self.extra_args = {}
430 elif format == 'hdf5':
431 elif format == 'hdf5':
431 self.ext = '.hdf5'
432 self.ext = '.hdf5'
432 self.extra_args = {'ind2DList': self.ind2DList}
433 self.extra_args = {'ind2DList': self.ind2DList}
433
434
434 self.keys = [k.lower() for k in self.twoDDict]
435 self.keys = [k.lower() for k in self.twoDDict]
435 if 'range' in self.keys:
436 if 'range' in self.keys:
436 self.keys.remove('range')
437 self.keys.remove('range')
437 if 'gdalt' in self.keys:
438 if 'gdalt' in self.keys:
438 self.keys.remove('gdalt')
439 self.keys.remove('gdalt')
439
440
440 def setFile(self):
441 def setFile(self):
441 '''
442 '''
442 Create new cedar file object
443 Create new cedar file object
443 '''
444 '''
444
445
445 self.mnemonic = MNEMONICS[self.kinst] #TODO get mnemonic from madrigal
446 self.mnemonic = MNEMONICS[self.kinst] #TODO get mnemonic from madrigal
446 date = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
447 date = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
447 #if self.dataOut.input_dat_type:
448 #if self.dataOut.input_dat_type:
448 #date=datetime.datetime.fromtimestamp(self.dataOut.TimeBlockSeconds_for_dp_power)
449 #date=datetime.datetime.fromtimestamp(self.dataOut.TimeBlockSeconds_for_dp_power)
449 #print("date",date)
450 #print("date",date)
450
451
451 filename = '{}{}{}'.format(self.mnemonic,
452 filename = '{}{}{}'.format(self.mnemonic,
452 date.strftime('%Y%m%d_%H%M%S'),
453 date.strftime('%Y%m%d_%H%M%S'),
453 self.ext)
454 self.ext)
454
455
455 self.fullname = os.path.join(self.path, filename)
456 self.fullname = os.path.join(self.path, filename)
456
457
457 if os.path.isfile(self.fullname) :
458 if os.path.isfile(self.fullname) :
458 log.warning(
459 log.warning(
459 'Destination file {} already exists, previous file deleted.'.format(
460 'Destination file {} already exists, previous file deleted.'.format(
460 self.fullname),
461 self.fullname),
461 'MADWriter')
462 'MADWriter')
462 os.remove(self.fullname)
463 os.remove(self.fullname)
463
464
464 try:
465 try:
465 log.success(
466 log.success(
466 'Creating file: {}'.format(self.fullname),
467 'Creating file: {}'.format(self.fullname),
467 'MADWriter')
468 'MADWriter')
468 if not os.path.exists(self.path):
469 if not os.path.exists(self.path):
469 os.makedirs(self.path)
470 os.makedirs(self.path)
470 self.fp = madrigal.cedar.MadrigalCedarFile(self.fullname, True)
471 self.fp = madrigal.cedar.MadrigalCedarFile(self.fullname, True)
471
472
472
473
473 except ValueError as e:
474 except ValueError as e:
474 log.error(
475 log.error(
475 'Impossible to create a cedar object with "madrigal.cedar.MadrigalCedarFile"',
476 'Impossible to create a cedar object with "madrigal.cedar.MadrigalCedarFile"',
476 'MADWriter')
477 'MADWriter')
477 return
478 return
478
479
479 return 1
480 return 1
480
481
481 def writeBlock(self):
482 def writeBlock(self):
482 '''
483 '''
483 Add data records to cedar file taking data from oneDDict and twoDDict
484 Add data records to cedar file taking data from oneDDict and twoDDict
484 attributes.
485 attributes.
485 Allowed parameters in: parcodes.tab
486 Allowed parameters in: parcodes.tab
486 '''
487 '''
487 #self.dataOut.paramInterval=2
488 #self.dataOut.paramInterval=2
488 startTime = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
489 startTime = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
489
490
490 endTime = startTime + datetime.timedelta(seconds=self.dataOut.paramInterval)
491 endTime = startTime + datetime.timedelta(seconds=self.dataOut.paramInterval)
491
492
492 #if self.dataOut.input_dat_type:
493 #if self.dataOut.input_dat_type:
493 #if self.dataOut.experiment=="DP":
494 #if self.dataOut.experiment=="DP":
494 #startTime=datetime.datetime.fromtimestamp(self.dataOut.TimeBlockSeconds_for_dp_power)
495 #startTime=datetime.datetime.fromtimestamp(self.dataOut.TimeBlockSeconds_for_dp_power)
495 #endTime = startTime + datetime.timedelta(seconds=self.dataOut.paramInterval)
496 #endTime = startTime + datetime.timedelta(seconds=self.dataOut.paramInterval)
496
497
497
498
498 #print("2: ",startTime)
499 #print("2: ",startTime)
499 #print(endTime)
500 #print(endTime)
500 heights = self.dataOut.heightList
501 heights = self.dataOut.heightList
501 #print(heights)
502 #print(heights)
502 #exit(1)
503 #exit(1)
503 #print(self.blocks)
504 #print(self.blocks)
504 #print(startTime)
505 #print(startTime)
505 #print(endTime)
506 #print(endTime)
506 #print(heights)
507 #print(heights)
507 #input()
508 #input()
508 if self.ext == '.dat':
509 if self.ext == '.dat':
509 for key, value in list(self.twoDDict.items()):
510 for key, value in list(self.twoDDict.items()):
510 if isinstance(value, str):
511 if isinstance(value, str):
511 data = getattr(self.dataOut, value)
512 data = getattr(self.dataOut, value)
512 invalid = numpy.isnan(data)
513 invalid = numpy.isnan(data)
513 data[invalid] = self.missing
514 data[invalid] = self.missing
514 elif isinstance(value, (tuple, list)):
515 elif isinstance(value, (tuple, list)):
515 attr, key = value
516 attr, key = value
516 data = getattr(self.dataOut, attr)
517 data = getattr(self.dataOut, attr)
517 invalid = numpy.isnan(data)
518 invalid = numpy.isnan(data)
518 data[invalid] = self.missing
519 data[invalid] = self.missing
519
520
520 out = {}
521 out = {}
521 for key, value in list(self.twoDDict.items()):
522 for key, value in list(self.twoDDict.items()):
522 key = key.lower()
523 key = key.lower()
523 if isinstance(value, str):
524 if isinstance(value, str):
524 if 'db' in value.lower():
525 if 'db' in value.lower():
525 tmp = getattr(self.dataOut, value.replace('_db', ''))
526 tmp = getattr(self.dataOut, value.replace('_db', ''))
526 SNRavg = numpy.average(tmp, axis=0)
527 SNRavg = numpy.average(tmp, axis=0)
527 tmp = 10*numpy.log10(SNRavg)
528 tmp = 10*numpy.log10(SNRavg)
528 else:
529 else:
529 tmp = getattr(self.dataOut, value)
530 tmp = getattr(self.dataOut, value)
530 out[key] = tmp.flatten()[:len(heights)]
531 out[key] = tmp.flatten()[:len(heights)]
531 elif isinstance(value, (tuple, list)):
532 elif isinstance(value, (tuple, list)):
532 attr, x = value
533 attr, x = value
533 data = getattr(self.dataOut, attr)
534 data = getattr(self.dataOut, attr)
534 #print(x)
535 #print(x)
535 #print(len(heights))
536 #print(len(heights))
536 #print(data[int(x)][:len(heights)])
537 #print(data[int(x)][:len(heights)])
537 #print(numpy.shape(out))
538 #print(numpy.shape(out))
538 #print(numpy.shape(data))
539 #print(numpy.shape(data))
539
540
540 out[key] = data[int(x)][:len(heights)]
541 out[key] = data[int(x)][:len(heights)]
541
542
542 a = numpy.array([out[k] for k in self.keys])
543 a = numpy.array([out[k] for k in self.keys])
543 #print(a)
544 #print(a)
544 nrows = numpy.array([numpy.isnan(a[:, x]).all() for x in range(len(heights))])
545 nrows = numpy.array([numpy.isnan(a[:, x]).all() for x in range(len(heights))])
545 index = numpy.where(nrows == False)[0]
546 index = numpy.where(nrows == False)[0]
546
547
547 #print(startTime.minute)
548 #print(startTime.minute)
548 rec = madrigal.cedar.MadrigalDataRecord(
549 rec = madrigal.cedar.MadrigalDataRecord(
549 self.kinst,
550 self.kinst,
550 self.kindat,
551 self.kindat,
551 startTime.year,
552 startTime.year,
552 startTime.month,
553 startTime.month,
553 startTime.day,
554 startTime.day,
554 startTime.hour,
555 startTime.hour,
555 startTime.minute,
556 startTime.minute,
556 startTime.second,
557 startTime.second,
557 startTime.microsecond/10000,
558 startTime.microsecond/10000,
558 endTime.year,
559 endTime.year,
559 endTime.month,
560 endTime.month,
560 endTime.day,
561 endTime.day,
561 endTime.hour,
562 endTime.hour,
562 endTime.minute,
563 endTime.minute,
563 endTime.second,
564 endTime.second,
564 endTime.microsecond/10000,
565 endTime.microsecond/10000,
565 list(self.oneDDict.keys()),
566 list(self.oneDDict.keys()),
566 list(self.twoDDict.keys()),
567 list(self.twoDDict.keys()),
567 len(index),
568 len(index),
568 **self.extra_args
569 **self.extra_args
569 )
570 )
570 #print("rec",rec)
571 #print("rec",rec)
571 # Setting 1d values
572 # Setting 1d values
572 for key in self.oneDDict:
573 for key in self.oneDDict:
573 rec.set1D(key, getattr(self.dataOut, self.oneDDict[key]))
574 rec.set1D(key, getattr(self.dataOut, self.oneDDict[key]))
574
575
575 # Setting 2d values
576 # Setting 2d values
576 nrec = 0
577 nrec = 0
577 for n in index:
578 for n in index:
578 for key in out:
579 for key in out:
579 rec.set2D(key, nrec, out[key][n])
580 rec.set2D(key, nrec, out[key][n])
580 nrec += 1
581 nrec += 1
581
582
582 self.fp.append(rec)
583 self.fp.append(rec)
583 if self.ext == '.hdf5' and self.counter %2 == 0 and self.counter > 0:
584 if self.ext == '.hdf5' and self.counter %2 == 0 and self.counter > 0:
584 #print("here")
585 #print("here")
585 self.fp.dump()
586 self.fp.dump()
586 if self.counter % 20 == 0 and self.counter > 0:
587 if self.counter % 20 == 0 and self.counter > 0:
587 #self.fp.write()
588 #self.fp.write()
588 log.log(
589 log.log(
589 'Writing {} records'.format(
590 'Writing {} records'.format(
590 self.counter),
591 self.counter),
591 'MADWriter')
592 'MADWriter')
592
593
593 def setHeader(self):
594 def setHeader(self):
594 '''
595 '''
595 Create an add catalog and header to cedar file
596 Create an add catalog and header to cedar file
596 '''
597 '''
597
598
598 log.success('Closing file {}'.format(self.fullname), 'MADWriter')
599 log.success('Closing file {}'.format(self.fullname), 'MADWriter')
599
600
600 if self.ext == '.dat':
601 if self.ext == '.dat':
601 self.fp.write()
602 self.fp.write()
602 else:
603 else:
603 self.fp.dump()
604 self.fp.dump()
604 self.fp.close()
605 self.fp.close()
605
606
606 header = madrigal.cedar.CatalogHeaderCreator(self.fullname)
607 header = madrigal.cedar.CatalogHeaderCreator(self.fullname)
607 header.createCatalog(**self.catalog)
608 header.createCatalog(**self.catalog)
608 header.createHeader(**self.header)
609 header.createHeader(**self.header)
609 header.write()
610 header.write()
610
611
612 def timeFlag(self):
613 currentTime = self.dataOut.utctime
614 timeTuple = time.localtime(currentTime)
615 dataDay = timeTuple.tm_yday
616
617 if self.currentDay is None:
618 self.currentDay = dataDay
619 return False
620
621 #Si el dia es diferente
622 if dataDay != self.currentDay:
623 self.currentDay = dataDay
624 return True
625
626 else:
627 return False
628
611 def putData(self):
629 def putData(self):
612
630
613 if self.dataOut.flagNoData:
631 if self.dataOut.flagNoData:
614 return 0
632 return 0
615
633
616 if self.dataOut.flagDiscontinuousBlock or self.counter == self.blocks:
634 if self.dataOut.flagDiscontinuousBlock or self.counter == self.blocks or self.timeFlag():
617 if self.counter > 0:
635 if self.counter > 0:
618 self.setHeader()
636 self.setHeader()
619 self.counter = 0
637 self.counter = 0
620
638
621 if self.counter == 0:
639 if self.counter == 0:
622 self.setFile()
640 self.setFile()
623
641
624 self.writeBlock()
642 self.writeBlock()
625 self.counter += 1
643 self.counter += 1
626
644
627 def close(self):
645 def close(self):
628
646
629 if self.counter > 0:
647 if self.counter > 0:
630 self.setHeader()
648 self.setHeader()
1 NO CONTENT: modified file
NO CONTENT: modified file
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now