##// END OF EJS Templates
UPDATE de operaciones en el Dominio de la Frecuencia y 2 scripts de prueba
sebastianVP -
r1778:799ea06d41f3
parent child
Show More

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

@@ -0,0 +1,386
1 #!python
2 '''
3 '''
4
5 import os, sys, json, argparse
6 import datetime
7 import time
8
9 from schainpy.controller import Project
10
11 PATH = "/home/pc-igp-179/Documentos/SOPHy"
12
13
14 PARAM = {
15 'S': {'zmin': -80, 'zmax':-45, 'colormap': 'jet' , 'label': 'Power', 'wrname': 'power','cb_label': 'dBm', 'ch':0},
16 'SNR':{'zmin': -10, 'zmax': 15, 'colormap': 'jet' , 'label': 'SNR', 'wrname': 'snr','cb_label': 'dB', 'ch':0},
17 'V': {'zmin': -12, 'zmax': 12, 'colormap': 'sophy_v', 'label': 'Velocity', 'wrname': 'velocity', 'cb_label': 'm/s', 'ch':0},
18 'R': {'zmin': 0.5, 'zmax': 1 , 'colormap': 'sophy_r', 'label': 'RhoHV', 'wrname':'rhoHV', 'cb_label': '', 'ch':0},
19 'P': {'zmin': -180,'zmax': 180,'colormap': 'sophy_p', 'label': 'PhiDP', 'wrname':'phiDP' , 'cb_label': 'degrees', 'ch':0},
20 'D': {'zmin': -9 , 'zmax': 12, 'colormap': 'sophy_d', 'label': 'ZDR','wrname':'differential_reflectivity' , 'cb_label': 'dB','ch':0},
21 'Z': {'zmin': -20, 'zmax': 80, 'colormap': 'sophy_z', 'label': 'Reflectivity ', 'wrname':'reflectivity', 'cb_label': 'dBz','ch':0},
22 'W': {'zmin': 0 , 'zmax': 12, 'colormap': 'sophy_w', 'label': 'Spectral Width', 'wrname':'spectral_width', 'cb_label': 'm/s', 'ch':0}
23 }
24
25 META = ['heightList', 'data_azi', 'data_ele', 'mode_op', 'latitude', 'longitude', 'altitude', 'heading', 'radar_name',
26 'institution', 'contact', 'h0', 'range_unit', 'prf', 'prf_unit', 'variable', 'variable_unit', 'n_pulses',
27 'pulse1_range', 'pulse1_width', 'pulse2_width', 'pulse1_repetitions', 'pulse2_repetitions', 'pulse_width_unit',
28 'snr_threshold', 'data_noise']
29
30
31 def max_index(r, sample_rate, ipp, h0,ipp_km):
32
33 return int(sample_rate*ipp*1e6 * r / ipp_km) + int(sample_rate*ipp*1e6 * -h0 / ipp_km)
34
35
36 def main(args):
37 experiment = args.experiment
38
39 fp = open(os.path.join(PATH, experiment, 'experiment.json'))
40 conf = json.loads(fp.read())
41
42 ipp_km = conf['usrp_tx']['ipp']
43 bottom = conf['pedestal']['bottom']
44 ipp = ipp_km * 2 /300000
45 sample_rate = conf['usrp_rx']['sample_rate']
46 speed_axis = conf['pedestal']['speed']
47
48 if args.angles:
49 angles = args.angles
50 else:
51 angles = conf['pedestal']['table']
52
53
54
55 start_date = conf['name'].split('@')[1].split('T')[0].replace('-', '/')
56 end_date = start_date
57 if args.start_time:
58 start_time = args.start_time
59 else:
60 start_time = conf['name'].split('@')[1].split('T')[1].replace('-', ':')
61
62 if args.end_time:
63 end_time = args.end_time
64 else:
65 end_time = '23:59:59'
66
67
68 if args.label:
69 label = '-{}'.format(args.label)
70 else:
71 label = ''
72
73 path_plots = os.path.join(PATH, experiment, 'plots{}'.format(label))
74 path_save = os.path.join(PATH, experiment, 'param{}'.format(label))
75
76
77 time_offset = args.time_offset
78 parameters = args.parameters
79
80 N = int(1.0/(abs(speed_axis[0])*ipp))
81 RMIX = 6.0
82 H0 = -1.33
83 MASK = args.mask
84
85 path = os.path.join(PATH, experiment, 'rawdata')
86 path_ped = os.path.join(PATH, experiment, 'position')
87
88 proyecto = Project()
89 proyecto.setup(id = '2', name='Test_2025', description="PRUEBA")
90
91 lectura = proyecto.addReadUnit(datatype='DigitalRFReader',
92 path=path,
93 startDate= "2025/01/06",#today,
94 endDate= "2025/01/06",#today,
95 startTime= start_time,
96 endTime= end_time,
97 delay=30,
98 #set=0,
99 online=0,
100 walk=1,
101 ippKm = ipp_km,
102 getByBlock = 1,
103 nProfileBlocks = N
104 )
105
106 n_pulses = 1
107 pulse_1_width = conf['usrp_tx']['pulse_1']
108 pulse_1_repetitions = conf['usrp_tx']['repetitions_1']
109 pulse_2_width = conf['usrp_tx']['pulse_2']
110 pulse_2_repetitions = conf['usrp_tx']['repetitions_2']
111
112 if '1' in args.pulses:
113 voltage1 = proyecto.addProcUnit(
114 datatype='VoltageProc',
115 inputId=lectura.getId()
116 )
117
118 op = voltage1.addOperation(
119 name='ProfileSelector'
120 )
121 op.addParameter(
122 name='profileRangeList',
123 value='0,{}'.format(conf['usrp_tx']['repetitions_1']-1)
124 )
125
126 if conf['usrp_tx']['code_type_1'] != 'None':
127 codes = [ c.strip() for c in conf['usrp_tx']['code_1'].split(',')]
128 code = []
129 for c in codes:
130 code.append([int(x) for x in c])
131 op = voltage1.addOperation(name='Decoder', optype='other')
132 op.addParameter(name='code', value=code)
133 op.addParameter(name='nCode', value=len(code), format='int')
134 op.addParameter(name='nBaud', value=len(code[0]), format='int')
135 ncode = len(code)
136 else:
137 ncode = 1
138 code = ['0']
139
140 op = voltage1.addOperation(name='CohInt', optype='other')
141 op.addParameter(name='n', value=ncode, format='int')
142
143 op = voltage1.addOperation(name='setH0')
144 op.addParameter(name='h0', value=H0, format='float')
145
146 if args.range > 0:
147 op = voltage1.addOperation(name='selectHeights')
148 op.addParameter(name='minIndex', value=max_index(0, sample_rate, ipp, H0,ipp_km), format='int')
149 op.addParameter(name='maxIndex', value=max_index(args.range, sample_rate, ipp, H0,ipp_km), format='int')
150
151
152 op = voltage1.addOperation(name='PulsePair_vRF', optype='other')
153 op.addParameter(name='n', value=int(conf['usrp_tx']['repetitions_1'])/ncode, format='int')
154
155 if args.rmDC:
156 op.addParameter(name='removeDC', value=1, format='int')
157
158 proc1 = proyecto.addProcUnit(datatype='ParametersProc', inputId=voltage1.getId())
159 proc1.addParameter(name='runNextUnit', value=True)
160
161 opObj10 = proc1.addOperation(name="WeatherRadar")
162 opObj10.addParameter(name='CR_Flag',value=True)
163 print(1, len(code[0]))
164 opObj10.addParameter(name='tauW',value=(1e-6/sample_rate)*len(code[0]))
165 opObj10.addParameter(name='Pt',value=200)
166 opObj10.addParameter(name='min_index',value=max_index(0, sample_rate, ipp, H0,ipp_km))
167
168
169 op = proc1.addOperation(name='PedestalInformation')
170 op.addParameter(name='path', value=path_ped, format='str')
171 op.addParameter(name='interval', value='0.04')
172 op.addParameter(name='time_offset', value=time_offset)
173 op.addParameter(name='mode', value=args.mode)
174
175 op = proc1.addOperation(name='Block360')
176 op.addParameter(name='attr_data', value='data_param')
177 op.addParameter(name='runNextOp', value=True)
178 op.addParameter(name='angles', value=angles)
179 op.addParameter(name='heading', value=conf['heading'])
180
181
182 if '2' in args.pulses:
183 voltage2 = proyecto.addProcUnit(
184 datatype='VoltageProc',
185 inputId=lectura.getId()
186 )
187
188 op = voltage2.addOperation(
189 name='ProfileSelector'
190 )
191 op.addParameter(
192 name='profileRangeList',
193 value='{},{}'.format(conf['usrp_tx']['repetitions_1'], conf['usrp_tx']['repetitions_1']+conf['usrp_tx']['repetitions_2']-1)
194 )
195
196 if conf['usrp_tx']['code_type_2']:
197 codes = [ c.strip() for c in conf['usrp_tx']['code_2'].split(',')]
198 code = []
199 for c in codes:
200 code.append([int(x) for x in c])
201 op = voltage2.addOperation(name='Decoder', optype='other')
202 op.addParameter(name='code', value=code)
203 op.addParameter(name='nCode', value=len(code), format='int')
204 op.addParameter(name='nBaud', value=len(code[0]), format='int')
205
206 op = voltage2.addOperation(name='CohInt', optype='other')
207 op.addParameter(name='n', value=len(code), format='int')
208
209 ncode = len(code)
210 else:
211 ncode = 1
212
213 op = voltage2.addOperation(name='setH0')
214 op.addParameter(name='h0', value=H0, format='float')
215
216 if args.range > 0:
217 op = voltage2.addOperation(name='selectHeights')
218 op.addParameter(name='minIndex', value=max_index(0, sample_rate, ipp, H0,ipp_km), format='int')
219 op.addParameter(name='maxIndex', value=max_index(args.range, sample_rate, ipp, H0,ipp_km), format='int')
220
221
222 op = voltage2.addOperation(name='PulsePair_vRF', optype='other')
223 op.addParameter(name='n', value=int(conf['usrp_tx']['repetitions_1'])/ncode, format='int')
224
225 proc2 = proyecto.addProcUnit(datatype='ParametersProc', inputId=voltage2.getId())
226 proc2.addParameter(name='runNextUnit', value=True)
227
228 opObj10 = proc2.addOperation(name="WeatherRadar")
229 opObj10.addParameter(name='CR_Flag',value=True,format='bool')
230 print(2, len(code[0]))
231 opObj10.addParameter(name='tauW',value=(1e-6/sample_rate)*len(code[0]))
232 opObj10.addParameter(name='Pt',value=200)
233 opObj10.addParameter(name='min_index',value=max_index(RMIX, sample_rate, ipp, H0,ipp_km))
234
235 op = proc2.addOperation(name='PedestalInformation')
236 op.addParameter(name='path', value=path_ped, format='str')
237 op.addParameter(name='interval', value='0.04')
238 op.addParameter(name='time_offset', value=time_offset)
239 op.addParameter(name='mode', value=args.mode)
240 op.addParameter(name='heading', value=conf['heading'])
241
242 op = proc2.addOperation(name='Block360')
243 op.addParameter(name='attr_data', value='data_param')
244 op.addParameter(name='runNextOp', value=True)
245 op.addParameter(name='angles', value=angles)
246 op.addParameter(name='heading', value=conf['heading'])
247
248 if '1' in args.pulses and '2' in args.pulses:
249 merge = proyecto.addProcUnit(datatype='MergeProc', inputId=[proc1.getId(), proc2.getId()])
250 merge.addParameter(name='attr_data', value='data_param')
251 merge.addParameter(name='mode', value='7')
252 merge.addParameter(name='index', value=max_index(RMIX, sample_rate, ipp, H0,ipp_km))
253
254 elif '1' in args.pulses:
255 merge = proc1
256 elif '2' in args.pulses:
257 merge = proc2
258
259 for param in parameters:
260
261 if args.plot:
262 op= merge.addOperation(name='WeatherParamsPlot')
263 if args.save:
264 op.addParameter(name='save', value=path_plots, format='str')
265 op.addParameter(name='save_period', value=-1)
266 op.addParameter(name='show', value=args.show)
267 op.addParameter(name='channels', value='0,')
268 op.addParameter(name='zmin', value=PARAM[param]['zmin'], format='int')
269 op.addParameter(name='zmax', value=PARAM[param]['zmax'], format='int')
270 op.addParameter(name='yrange', value=20, format='int')
271 op.addParameter(name='xrange', value=args.range, format='int')
272 op.addParameter(name='attr_data', value=param, format='str')
273 op.addParameter(name='labels', value=[[PARAM[param]['label']], [PARAM[param]['label']]])
274 op.addParameter(name='save_code', value=param)
275 op.addParameter(name='cb_label', value=PARAM[param]['cb_label'])
276 op.addParameter(name='colormap', value=PARAM[param]['colormap'])
277 op.addParameter(name='bgcolor', value='black')
278 op.addParameter(name='localtime', value=False)
279 op.addParameter(name='shapes', value='./shapes')
280 op.addParameter(name='latitude', value=conf['latitude'], format='float')
281 op.addParameter(name='longitude', value=conf['longitude'], format='float')
282 op.addParameter(name='map', value=True)
283
284 if MASK: op.addParameter(name='mask', value=MASK, format='float')
285 if args.server:
286 op.addParameter(name='server', value='190.187.237.239:4444')
287 op.addParameter(name='exp_code', value='400')
288
289 desc = {
290 'Data': {
291 'data_param': {PARAM[param]['wrname']: ['H', 'V']},
292 'utctime': 'time'
293 },
294 'Metadata': {
295 'heightList': 'range',
296 'data_azi': 'azimuth',
297 'data_ele': 'elevation',
298 'mode_op': 'scan_type',
299 'h0': 'range_correction',
300 'dataPP_NOISE': 'noise',
301 }
302 }
303
304 if args.save:
305 writer = merge.addOperation(name='HDFWriter')
306 writer.addParameter(name='path', value=path_save, format='str')
307 writer.addParameter(name='Reset', value=True)
308 writer.addParameter(name='setType', value='weather')
309 writer.addParameter(name='setChannel', value='0') #new parameter choose ch 0 H or ch 1 V
310 writer.addParameter(name='description', value=json.dumps(desc))
311 writer.addParameter(name='blocksPerFile', value='1',format='int')
312 writer.addParameter(name='metadataList', value=','.join(META))
313 writer.addParameter(name='dataList', value='data_param,utctime')
314 writer.addParameter(name='weather_var', value=param)
315 writer.addParameter(name='mask', value=MASK, format='float')
316 writer.addParameter(name='localtime', value=False)
317 # meta
318 writer.addParameter(name='latitude', value=conf['latitude'])
319 writer.addParameter(name='longitude', value=conf['longitude'])
320 writer.addParameter(name='altitude', value=conf['altitude'])
321 writer.addParameter(name='heading', value=conf['heading'])
322 writer.addParameter(name='radar_name', value='SOPHy')
323 writer.addParameter(name='institution', value='IGP')
324 writer.addParameter(name='contact', value='dscipion@igp.gob.pe')
325 writer.addParameter(name='created_by', value='Signal Chain (https://pypi.org/project/schainpy/)')
326 writer.addParameter(name='range_unit', value='km')
327 writer.addParameter(name='prf', value=1/ipp)
328 writer.addParameter(name='prf_unit', value='hertz')
329 writer.addParameter(name='variable', value=PARAM[param]['label'])
330 writer.addParameter(name='variable_unit', value=PARAM[param]['cb_label'])
331 writer.addParameter(name='n_pulses', value=n_pulses)
332 writer.addParameter(name='pulse1_range', value=RMIX)
333 writer.addParameter(name='pulse1_width', value=pulse_1_width)
334 writer.addParameter(name='pulse2_width', value=pulse_2_width)
335 writer.addParameter(name='pulse1_repetitions', value=pulse_1_repetitions)
336 writer.addParameter(name='pulse2_repetitions', value=pulse_2_repetitions)
337 writer.addParameter(name='pulse_width_unit', value='microseconds')
338 writer.addParameter(name='snr_threshold', value=MASK)
339 writer.addParameter(name='cr_hv', value=[67.41,67.17]) #new parameter
340
341
342 return proyecto
343
344
345
346
347 if __name__ == '__main__':
348
349 parser = argparse.ArgumentParser(description='Script to process SOPHy data.')
350 parser.add_argument('experiment',
351 help='Experiment name')
352 parser.add_argument('--parameters', nargs='*', default=['S'],
353 help='Variables to process: P, Z, V')
354 parser.add_argument('--pulses', nargs='*', default=['1', '2'],
355 help='Variables to process: 1, 2')
356 parser.add_argument('--range', default=60, type=float,
357 help='Max range to plot')
358 parser.add_argument('--server', action='store_true',
359 help='Send to realtime')
360 parser.add_argument('--start_time', default='',
361 help='Set start time.')
362 parser.add_argument('--end_time', default='',
363 help='Set end time.')
364 parser.add_argument('--rmDC', action='store_true',
365 help='Apply remove DC.')
366 parser.add_argument('--time_offset', default=0,
367 help='Fix time offset')
368 parser.add_argument('--mode', default=None,
369 help='Type of scan')
370 parser.add_argument('--angles', nargs='*', default=[], type=int,
371 help='Angles to process')
372 parser.add_argument('--plot', action='store_true',
373 help='Create plot files')
374 parser.add_argument('--save', action='store_true',
375 help='Create output files')
376 parser.add_argument('--show', action='store_true',
377 help='Show matplotlib plot.')
378 parser.add_argument('--mask', default=0.36, type=float,
379 help='Filter mask over SNR')
380 parser.add_argument('--label', default='',
381 help='Label for plot & param folder')
382
383 args = parser.parse_args()
384
385 proyecto= main(args)
386 proyecto.start() No newline at end of file
@@ -0,0 +1,381
1 import os, sys, json, argparse
2 import multiprocessing
3 import datetime
4 import time
5
6 PATH = "/home/pc-igp-179/Documentos/SOPHy"
7
8 PARAM = {
9 'S': {'zmin': -80, 'zmax':-45, 'colormap': 'jet' , 'label': 'Power', 'wrname': 'power','cb_label': 'dBm', 'ch':0},
10 'SNR':{'zmin': -10, 'zmax': 15, 'colormap': 'jet' , 'label': 'SNR', 'wrname': 'snr','cb_label': 'dB', 'ch':0},
11 'V': {'zmin': -12, 'zmax': 12, 'colormap': 'sophy_v', 'label': 'Velocity', 'wrname': 'velocity', 'cb_label': 'm/s', 'ch':0},
12 'R': {'zmin': 0.5, 'zmax': 1 , 'colormap': 'sophy_r', 'label': 'RhoHV', 'wrname':'rhoHV', 'cb_label': '', 'ch':0},
13 'P': {'zmin': -180,'zmax': 180,'colormap': 'sophy_p', 'label': 'PhiDP', 'wrname':'phiDP' , 'cb_label': 'degrees', 'ch':0},
14 'D': {'zmin': -9 , 'zmax': 12, 'colormap': 'sophy_d', 'label': 'ZDR','wrname':'differential_reflectivity' , 'cb_label': 'dB','ch':0},
15 'Z': {'zmin': -20, 'zmax': 80, 'colormap': 'sophy_z', 'label': 'Reflectivity ', 'wrname':'reflectivity', 'cb_label': 'dBz','ch':0},
16 'W': {'zmin': 0 , 'zmax': 12, 'colormap': 'sophy_w', 'label': 'Spectral Width', 'wrname':'spectral_width', 'cb_label': 'm/s', 'ch':0}
17 }
18
19 META = ['heightList', 'data_azi', 'data_ele', 'mode_op', 'latitude', 'longitude', 'altitude', 'heading', 'radar_name',
20 'institution', 'contact', 'h0', 'range_unit', 'prf', 'prf_unit', 'variable', 'variable_unit', 'n_pulses',
21 'pulse1_range', 'pulse1_width', 'pulse2_width', 'pulse1_repetitions', 'pulse2_repetitions', 'pulse_width_unit',
22 'snr_threshold', 'data_noise']
23
24
25 def max_index(r, sample_rate, ipp, h0,ipp_km):
26
27 return int(sample_rate*ipp*1e6 * r / ipp_km) + int(sample_rate*ipp*1e6 * -h0 / ipp_km)
28
29 def main(args):
30
31 experiment = args.experiment
32 fp = open(os.path.join(PATH, experiment, 'experiment.json'))
33 conf = json.loads(fp.read())
34
35 ipp_km = conf['usrp_tx']['ipp']
36 bottom = conf['pedestal']['bottom']
37 ipp = ipp_km * 2 /300000
38 sample_rate = conf['usrp_rx']['sample_rate']
39 speed_axis = conf['pedestal']['speed']
40 if args.angles:
41 angles = args.angles
42 else:
43 angles = conf['pedestal']['table']
44 time_offset = args.time_offset
45 parameters = args.parameters
46 start_date = conf['name'].split('@')[1].split('T')[0].replace('-', '/')
47 end_date = start_date
48 if args.start_time:
49 start_time = args.start_time
50 else:
51 start_time = conf['name'].split('@')[1].split('T')[1].replace('-', ':')
52
53 if args.end_time:
54 end_time = args.end_time
55 else:
56 end_time = '23:59:59'
57
58 N = int(1.0/(abs(speed_axis[0])*ipp))
59
60 path = os.path.join(PATH, experiment, 'rawdata')
61
62 path_ped = os.path.join(PATH, experiment, 'position')
63 if args.label:
64 label = '-{}'.format(args.label)
65 else:
66 label = ''
67 path_plots = os.path.join(PATH, experiment, 'plots{}'.format(label))
68 path_save = os.path.join(PATH, experiment, 'param{}'.format(label))
69 RMIX = 6.0
70 H0 = -1.33
71 MASK = args.mask
72
73 from schainpy.controller import Project
74
75 project = Project()
76 project.setup(id='1', name='Sophy', description='sophy proc')
77
78 reader = project.addReadUnit(datatype='DigitalRFReader',
79 path=path,
80 startDate=start_date,
81 endDate=end_date,
82 startTime=start_time,
83 endTime=end_time,
84 delay=0,
85 online=args.online,
86 walk=0,
87 ippKm = ipp_km,
88 getByBlock = 1,
89 nProfileBlocks = N,
90 )
91
92
93 n_pulses = 1
94 pulse_1_width = conf['usrp_tx']['pulse_1']
95 pulse_1_repetitions = conf['usrp_tx']['repetitions_1']
96 pulse_2_width = conf['usrp_tx']['pulse_2']
97 pulse_2_repetitions = conf['usrp_tx']['repetitions_2']
98
99 if '1' in args.pulses:
100 voltage1 = project.addProcUnit(datatype='VoltageProc', inputId=reader.getId())
101
102 op = voltage1.addOperation(name='ProfileSelector')
103 op.addParameter(name='profileRangeList', value='0,{}'.format(conf['usrp_tx']['repetitions_1']-1))
104
105 if conf['usrp_tx']['code_type_1'] != 'None':
106 codes = [ c.strip() for c in conf['usrp_tx']['code_1'].split(',')]
107 code = []
108 for c in codes:
109 code.append([int(x) for x in c])
110 op = voltage1.addOperation(name='Decoder', optype='other')
111 op.addParameter(name='code', value=code)
112 op.addParameter(name='nCode', value=len(code), format='int')
113 op.addParameter(name='nBaud', value=len(code[0]), format='int')
114 ncode = len(code)
115 else:
116 ncode = 1
117 code = ['0']
118
119
120 op = voltage1.addOperation(name='CohInt', optype='other')
121 op.addParameter(name='n', value=ncode, format='int')
122
123 op = voltage1.addOperation(name='setH0')
124 op.addParameter(name='h0', value=H0, format='float')
125
126 if args.range > 0:
127 op = voltage1.addOperation(name='selectHeights')
128 op.addParameter(name='minIndex', value=max_index(0, sample_rate, ipp, H0,ipp_km), format='int')
129 op.addParameter(name='maxIndex', value=max_index(args.range, sample_rate, ipp, H0,ipp_km), format='int')
130
131
132
133 #op = voltage1.addOperation(name='PulsePair_vRF', optype='other')
134 #op.addParameter(name='n', value=int(conf['usrp_tx']['repetitions_1'])/ncode, format='int')
135
136 procUnitConfObjA = project.addProcUnit(datatype='SpectraProc', inputId=voltage1.getId())
137 procUnitConfObjA.addParameter(name='nFFTPoints', value=int(conf['usrp_tx']['repetitions_1'])/ncode, format='int')
138 procUnitConfObjA.addParameter(name='nProfiles', value=int(conf['usrp_tx']['repetitions_1'])/ncode, format='int')
139
140
141 #opObj11 = procUnitConfObjA.addOperation(name='setRadarFrequency')
142 #opObj11.addParameter(name='frequency', value='9.345e9', format='float')
143 #procUnitConfObjA.addOperation(name='removeDC')
144 #if args.rmDC:
145 # op.addParameter(name='removeDC', value=1, format='int')
146
147 proc1 = project.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObjA.getId())
148 proc1.addOperation(name='SpectralMoments')
149
150 proc1.addParameter(name='runNextUnit', value=True)
151
152 opObj10 = proc1.addOperation(name="WeatherRadar")
153 opObj10.addParameter(name='CR_Flag',value=True)
154 #print(1, len(code[0]))
155 opObj10.addParameter(name='tauW',value=(1e-6/sample_rate)*len(code[0]))
156 opObj10.addParameter(name='Pt',value=200)
157 opObj10.addParameter(name='min_index',value=max_index(0, sample_rate, ipp, H0,ipp_km))
158
159
160 op = proc1.addOperation(name='PedestalInformation')
161 op.addParameter(name='path', value=path_ped, format='str')
162 op.addParameter(name='interval', value='0.04')
163 op.addParameter(name='time_offset', value=time_offset)
164 op.addParameter(name='mode', value=args.mode)
165
166 op = proc1.addOperation(name='Block360')
167 op.addParameter(name='attr_data', value='data_param')
168 op.addParameter(name='runNextOp', value=True)
169 op.addParameter(name='angles', value=angles)
170 op.addParameter(name='heading', value=conf['heading'])
171
172
173 if '2' in args.pulses:
174 voltage2 = project.addProcUnit(datatype='VoltageProc', inputId=reader.getId())
175
176 op = voltage2.addOperation(name='ProfileSelector')
177 op.addParameter(name='profileRangeList', value='{},{}'.format(conf['usrp_tx']['repetitions_1'], conf['usrp_tx']['repetitions_1']+conf['usrp_tx']['repetitions_2']-1))
178
179 if conf['usrp_tx']['code_type_2']:
180 codes = [ c.strip() for c in conf['usrp_tx']['code_2'].split(',')]
181 code = []
182 for c in codes:
183 code.append([int(x) for x in c])
184 op = voltage2.addOperation(name='Decoder', optype='other')
185 op.addParameter(name='code', value=code)
186 op.addParameter(name='nCode', value=len(code), format='int')
187 op.addParameter(name='nBaud', value=len(code[0]), format='int')
188
189 op = voltage2.addOperation(name='CohInt', optype='other')
190 op.addParameter(name='n', value=len(code), format='int')
191
192 ncode = len(code)
193 else:
194 ncode = 1
195
196 op = voltage2.addOperation(name='setH0')
197 op.addParameter(name='h0', value=H0, format='float')
198
199 if args.range > 0:
200 op = voltage2.addOperation(name='selectHeights')
201 op.addParameter(name='minIndex', value=max_index(0, sample_rate, ipp, H0,ipp_km), format='int')
202 op.addParameter(name='maxIndex', value=max_index(args.range, sample_rate, ipp, H0,ipp_km), format='int')
203
204
205
206
207 procUnitConfObjB = project.addProcUnit(datatype='SpectraProc', inputId=voltage2.getId())
208 procUnitConfObjB.addParameter(name='nFFTPoints', value=int(conf['usrp_tx']['repetitions_2'])/ncode, format='int')
209 procUnitConfObjB.addParameter(name='nProfiles', value=int(conf['usrp_tx']['repetitions_2'])/ncode, format='int')
210
211
212
213 #opObj11 = procUnitConfObjB.addOperation(name='setRadarFrequency')
214 #opObj11.addParameter(name='frequency', value='9.345e9', format='float')
215 #procUnitConfObjB.addOperation(name='removeDC')
216
217 #if args.rmDC:
218 # op.addParameter(name='removeDC', value=1, format='int')
219
220 proc2 = project.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObjB.getId())
221 proc2.addOperation(name='SpectralMoments')
222 proc2.addParameter(name='runNextUnit', value=True)
223
224 opObj10 = proc2.addOperation(name="WeatherRadar")
225 opObj10.addParameter(name='CR_Flag',value=True,format='bool')
226 opObj10.addParameter(name='tauW',value=(1e-6/sample_rate)*len(code[0]))
227 opObj10.addParameter(name='Pt',value=200)
228 opObj10.addParameter(name='min_index',value=max_index(RMIX, sample_rate, ipp, H0,ipp_km))
229
230 op = proc2.addOperation(name='PedestalInformation')
231 op.addParameter(name='path', value=path_ped, format='str')
232 op.addParameter(name='interval', value='0.04')
233 op.addParameter(name='time_offset', value=time_offset)
234 op.addParameter(name='mode', value=args.mode)
235 op.addParameter(name='heading', value=conf['heading'])
236
237 op = proc2.addOperation(name='Block360')
238 op.addParameter(name='attr_data', value='data_param')
239 op.addParameter(name='runNextOp', value=True)
240 op.addParameter(name='angles', value=angles)
241 op.addParameter(name='heading', value=conf['heading'])
242
243
244 if '1' in args.pulses and '2' in args.pulses:
245 merge = project.addProcUnit(datatype='MergeProc', inputId=[proc1.getId(), proc2.getId()])
246 merge.addParameter(name='attr_data', value='data_param')
247 merge.addParameter(name='mode', value='7')
248 merge.addParameter(name='index', value=max_index(RMIX, sample_rate, ipp, H0,ipp_km))
249
250 elif '1' in args.pulses:
251 merge = proc1
252 elif '2' in args.pulses:
253 merge = proc2
254
255
256 for param in parameters:
257
258 if args.plot:
259 op= merge.addOperation(name='WeatherParamsPlot')
260 if args.save:
261 op.addParameter(name='save', value=path_plots, format='str')
262 op.addParameter(name='save_period', value=-1)
263 op.addParameter(name='show', value=args.show)
264 op.addParameter(name='channels', value='0,')
265 op.addParameter(name='zmin', value=PARAM[param]['zmin'], format='int')
266 op.addParameter(name='zmax', value=PARAM[param]['zmax'], format='int')
267 op.addParameter(name='yrange', value=20, format='int')
268 op.addParameter(name='xrange', value=args.range, format='int')
269 op.addParameter(name='attr_data', value=param, format='str')
270 op.addParameter(name='labels', value=[[PARAM[param]['label']], [PARAM[param]['label']]])
271 op.addParameter(name='save_code', value=param)
272 op.addParameter(name='cb_label', value=PARAM[param]['cb_label'])
273 op.addParameter(name='colormap', value=PARAM[param]['colormap'])
274 op.addParameter(name='bgcolor', value='black')
275 op.addParameter(name='localtime', value=False)
276 op.addParameter(name='shapes', value='./shapes')
277 op.addParameter(name='latitude', value=conf['latitude'], format='float')
278 op.addParameter(name='longitude', value=conf['longitude'], format='float')
279 op.addParameter(name='map', value=True)
280
281 if MASK: op.addParameter(name='mask', value=MASK, format='float')
282 #if args.server:
283 # op.addParameter(name='server', value='190.187.237.239:4444')
284 # op.addParameter(name='exp_code', value='400')
285
286 desc = {
287 'Data': {
288 'data_param': {PARAM[param]['wrname']: ['H', 'V']},
289 'utctime': 'time'
290 },
291 'Metadata': {
292 'heightList': 'range',
293 'data_azi': 'azimuth',
294 'data_ele': 'elevation',
295 'mode_op': 'scan_type',
296 'h0': 'range_correction',
297 'dataPP_NOISE': 'noise',
298 }
299 }
300
301 if args.save:
302 writer = merge.addOperation(name='HDFWriter')
303 writer.addParameter(name='path', value=path_save, format='str')
304 writer.addParameter(name='Reset', value=True)
305 writer.addParameter(name='setType', value='weather')
306 writer.addParameter(name='setChannel', value='0') #new parameter choose ch 0 H or ch 1 V
307 writer.addParameter(name='description', value=json.dumps(desc))
308 writer.addParameter(name='blocksPerFile', value='1',format='int')
309 writer.addParameter(name='metadataList', value=','.join(META))
310 writer.addParameter(name='dataList', value='data_param,utctime')
311 writer.addParameter(name='weather_var', value=param)
312 writer.addParameter(name='mask', value=MASK, format='float')
313 writer.addParameter(name='localtime', value=False)
314 # meta
315 writer.addParameter(name='latitude', value=conf['latitude'])
316 writer.addParameter(name='longitude', value=conf['longitude'])
317 writer.addParameter(name='altitude', value=conf['altitude'])
318 writer.addParameter(name='heading', value=conf['heading'])
319 writer.addParameter(name='radar_name', value='SOPHy')
320 writer.addParameter(name='institution', value='IGP')
321 writer.addParameter(name='contact', value='dscipion@igp.gob.pe')
322 writer.addParameter(name='created_by', value='Signal Chain (https://pypi.org/project/schainpy/)')
323 writer.addParameter(name='range_unit', value='km')
324 writer.addParameter(name='prf', value=1/ipp)
325 writer.addParameter(name='prf_unit', value='hertz')
326 writer.addParameter(name='variable', value=PARAM[param]['label'])
327 writer.addParameter(name='variable_unit', value=PARAM[param]['cb_label'])
328 writer.addParameter(name='n_pulses', value=n_pulses)
329 writer.addParameter(name='pulse1_range', value=RMIX)
330 writer.addParameter(name='pulse1_width', value=pulse_1_width)
331 writer.addParameter(name='pulse2_width', value=pulse_2_width)
332 writer.addParameter(name='pulse1_repetitions', value=pulse_1_repetitions)
333 writer.addParameter(name='pulse2_repetitions', value=pulse_2_repetitions)
334 writer.addParameter(name='pulse_width_unit', value='microseconds')
335 writer.addParameter(name='snr_threshold', value=MASK)
336 writer.addParameter(name='cr_hv', value=[67.41,67.17]) #new parameter
337
338 return project
339
340 if __name__ == '__main__':
341
342 parser = argparse.ArgumentParser(description='Script to process SOPHy data.')
343 parser.add_argument('experiment',
344 help='Experiment name')
345 parser.add_argument('--parameters', nargs='*', default=['S'],
346 help='Variables to process: P, Z, V')
347 parser.add_argument('--pulses', nargs='*', default=['1', '2'],
348 help='Variables to process: 1, 2')
349 parser.add_argument('--angles', nargs='*', default=[], type=int,
350 help='Angles to process')
351 parser.add_argument('--time_offset', default=0,
352 help='Fix time offset')
353 parser.add_argument('--range', default=60, type=float,
354 help='Max range to plot')
355
356 parser.add_argument('--save', action='store_true',
357 help='Create output files')
358 parser.add_argument('--plot', action='store_true',
359 help='Create plot files')
360 parser.add_argument('--show', action='store_true',
361 help='Show matplotlib plot.')
362 parser.add_argument('--online', action='store_true',
363 help='Set online mode.')
364 parser.add_argument('--server', action='store_true',
365 help='Send to realtime')
366 parser.add_argument('--start_time', default='',
367 help='Set start time.')
368 parser.add_argument('--end_time', default='',
369 help='Set end time.')
370 parser.add_argument('--label', default='',
371 help='Label for plot & param folder')
372 parser.add_argument('--mode', default=None,
373 help='Type of scan')
374 #parser.add_argument('--rmDC', action='store_true',
375 # help='Apply remove DC.')
376 parser.add_argument('--mask', default=0, type=float,
377 help='Set SNR threshold.')
378 args = parser.parse_args()
379
380 project = main(args)
381 project.start() No newline at end of file
@@ -1,769 +1,784
1 import os
1 import os
2 import datetime
2 import datetime
3 import warnings
3 import warnings
4 import numpy
4 import numpy
5 from mpl_toolkits.axisartist.grid_finder import FixedLocator, DictFormatter
5 from mpl_toolkits.axisartist.grid_finder import FixedLocator, DictFormatter
6 from matplotlib.patches import Circle
6 from matplotlib.patches import Circle
7 from cartopy.feature import ShapelyFeature
7 from cartopy.feature import ShapelyFeature
8 import cartopy.io.shapereader as shpreader
8 import cartopy.io.shapereader as shpreader
9
9
10 from schainpy.model.graphics.jroplot_base import Plot, plt, ccrs
10 from schainpy.model.graphics.jroplot_base import Plot, plt, ccrs
11 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot, SpectraCutPlot
11 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot, SpectraCutPlot
12 from schainpy.utils import log
12 from schainpy.utils import log
13 from schainpy.model.graphics.plotting_codes import cb_tables
13 from schainpy.model.graphics.plotting_codes import cb_tables
14
14
15
15
16 EARTH_RADIUS = 6.3710e3
16 EARTH_RADIUS = 6.3710e3
17
17
18
18
19 def antenna_to_cartesian(ranges, azimuths, elevations):
19 def antenna_to_cartesian(ranges, azimuths, elevations):
20 """
20 """
21 Return Cartesian coordinates from antenna coordinates.
21 Return Cartesian coordinates from antenna coordinates.
22
22
23 Parameters
23 Parameters
24 ----------
24 ----------
25 ranges : array
25 ranges : array
26 Distances to the center of the radar gates (bins) in kilometers.
26 Distances to the center of the radar gates (bins) in kilometers.
27 azimuths : array
27 azimuths : array
28 Azimuth angle of the radar in degrees.
28 Azimuth angle of the radar in degrees.
29 elevations : array
29 elevations : array
30 Elevation angle of the radar in degrees.
30 Elevation angle of the radar in degrees.
31
31
32 Returns
32 Returns
33 -------
33 -------
34 x, y, z : array
34 x, y, z : array
35 Cartesian coordinates in meters from the radar.
35 Cartesian coordinates in meters from the radar.
36
36
37 Notes
37 Notes
38 -----
38 -----
39 The calculation for Cartesian coordinate is adapted from equations
39 The calculation for Cartesian coordinate is adapted from equations
40 2.28(b) and 2.28(c) of Doviak and Zrnic [1]_ assuming a
40 2.28(b) and 2.28(c) of Doviak and Zrnic [1]_ assuming a
41 standard atmosphere (4/3 Earth's radius model).
41 standard atmosphere (4/3 Earth's radius model).
42
42
43 .. math::
43 .. math::
44
44
45 z = \\sqrt{r^2+R^2+2*r*R*sin(\\theta_e)} - R
45 z = \\sqrt{r^2+R^2+2*r*R*sin(\\theta_e)} - R
46
46
47 s = R * arcsin(\\frac{r*cos(\\theta_e)}{R+z})
47 s = R * arcsin(\\frac{r*cos(\\theta_e)}{R+z})
48
48
49 x = s * sin(\\theta_a)
49 x = s * sin(\\theta_a)
50
50
51 y = s * cos(\\theta_a)
51 y = s * cos(\\theta_a)
52
52
53 Where r is the distance from the radar to the center of the gate,
53 Where r is the distance from the radar to the center of the gate,
54 :math:`\\theta_a` is the azimuth angle, :math:`\\theta_e` is the
54 :math:`\\theta_a` is the azimuth angle, :math:`\\theta_e` is the
55 elevation angle, s is the arc length, and R is the effective radius
55 elevation angle, s is the arc length, and R is the effective radius
56 of the earth, taken to be 4/3 the mean radius of earth (6371 km).
56 of the earth, taken to be 4/3 the mean radius of earth (6371 km).
57
57
58 References
58 References
59 ----------
59 ----------
60 .. [1] Doviak and Zrnic, Doppler Radar and Weather Observations, Second
60 .. [1] Doviak and Zrnic, Doppler Radar and Weather Observations, Second
61 Edition, 1993, p. 21.
61 Edition, 1993, p. 21.
62
62
63 """
63 """
64 theta_e = numpy.deg2rad(elevations) # elevation angle in radians.
64 theta_e = numpy.deg2rad(elevations) # elevation angle in radians.
65 theta_a = numpy.deg2rad(azimuths) # azimuth angle in radians.
65 theta_a = numpy.deg2rad(azimuths) # azimuth angle in radians.
66 R = 6371.0 * 1000.0 * 4.0 / 3.0 # effective radius of earth in meters.
66 R = 6371.0 * 1000.0 * 4.0 / 3.0 # effective radius of earth in meters.
67 r = ranges * 1000.0 # distances to gates in meters.
67 r = ranges * 1000.0 # distances to gates in meters.
68
68
69 z = (r ** 2 + R ** 2 + 2.0 * r * R * numpy.sin(theta_e)) ** 0.5 - R
69 z = (r ** 2 + R ** 2 + 2.0 * r * R * numpy.sin(theta_e)) ** 0.5 - R
70 s = R * numpy.arcsin(r * numpy.cos(theta_e) / (R + z)) # arc length in m.
70 s = R * numpy.arcsin(r * numpy.cos(theta_e) / (R + z)) # arc length in m.
71 x = s * numpy.sin(theta_a)
71 x = s * numpy.sin(theta_a)
72 y = s * numpy.cos(theta_a)
72 y = s * numpy.cos(theta_a)
73 return x, y, z
73 return x, y, z
74
74
75 def cartesian_to_geographic_aeqd(x, y, lon_0, lat_0, R=EARTH_RADIUS):
75 def cartesian_to_geographic_aeqd(x, y, lon_0, lat_0, R=EARTH_RADIUS):
76 """
76 """
77 Azimuthal equidistant Cartesian to geographic coordinate transform.
77 Azimuthal equidistant Cartesian to geographic coordinate transform.
78
78
79 Transform a set of Cartesian/Cartographic coordinates (x, y) to
79 Transform a set of Cartesian/Cartographic coordinates (x, y) to
80 geographic coordinate system (lat, lon) using a azimuthal equidistant
80 geographic coordinate system (lat, lon) using a azimuthal equidistant
81 map projection [1]_.
81 map projection [1]_.
82
82
83 .. math::
83 .. math::
84
84
85 lat = \\arcsin(\\cos(c) * \\sin(lat_0) +
85 lat = \\arcsin(\\cos(c) * \\sin(lat_0) +
86 (y * \\sin(c) * \\cos(lat_0) / \\rho))
86 (y * \\sin(c) * \\cos(lat_0) / \\rho))
87
87
88 lon = lon_0 + \\arctan2(
88 lon = lon_0 + \\arctan2(
89 x * \\sin(c),
89 x * \\sin(c),
90 \\rho * \\cos(lat_0) * \\cos(c) - y * \\sin(lat_0) * \\sin(c))
90 \\rho * \\cos(lat_0) * \\cos(c) - y * \\sin(lat_0) * \\sin(c))
91
91
92 \\rho = \\sqrt(x^2 + y^2)
92 \\rho = \\sqrt(x^2 + y^2)
93
93
94 c = \\rho / R
94 c = \\rho / R
95
95
96 Where x, y are the Cartesian position from the center of projection;
96 Where x, y are the Cartesian position from the center of projection;
97 lat, lon the corresponding latitude and longitude; lat_0, lon_0 are the
97 lat, lon the corresponding latitude and longitude; lat_0, lon_0 are the
98 latitude and longitude of the center of the projection; R is the radius of
98 latitude and longitude of the center of the projection; R is the radius of
99 the earth (defaults to ~6371 km). lon is adjusted to be between -180 and
99 the earth (defaults to ~6371 km). lon is adjusted to be between -180 and
100 180.
100 180.
101
101
102 Parameters
102 Parameters
103 ----------
103 ----------
104 x, y : array-like
104 x, y : array-like
105 Cartesian coordinates in the same units as R, typically meters.
105 Cartesian coordinates in the same units as R, typically meters.
106 lon_0, lat_0 : float
106 lon_0, lat_0 : float
107 Longitude and latitude, in degrees, of the center of the projection.
107 Longitude and latitude, in degrees, of the center of the projection.
108 R : float, optional
108 R : float, optional
109 Earth radius in the same units as x and y. The default value is in
109 Earth radius in the same units as x and y. The default value is in
110 units of meters.
110 units of meters.
111
111
112 Returns
112 Returns
113 -------
113 -------
114 lon, lat : array
114 lon, lat : array
115 Longitude and latitude of Cartesian coordinates in degrees.
115 Longitude and latitude of Cartesian coordinates in degrees.
116
116
117 References
117 References
118 ----------
118 ----------
119 .. [1] Snyder, J. P. Map Projections--A Working Manual. U. S. Geological
119 .. [1] Snyder, J. P. Map Projections--A Working Manual. U. S. Geological
120 Survey Professional Paper 1395, 1987, pp. 191-202.
120 Survey Professional Paper 1395, 1987, pp. 191-202.
121
121
122 """
122 """
123 x = numpy.atleast_1d(numpy.asarray(x))
123 x = numpy.atleast_1d(numpy.asarray(x))
124 y = numpy.atleast_1d(numpy.asarray(y))
124 y = numpy.atleast_1d(numpy.asarray(y))
125
125
126 lat_0_rad = numpy.deg2rad(lat_0)
126 lat_0_rad = numpy.deg2rad(lat_0)
127 lon_0_rad = numpy.deg2rad(lon_0)
127 lon_0_rad = numpy.deg2rad(lon_0)
128
128
129 rho = numpy.sqrt(x*x + y*y)
129 rho = numpy.sqrt(x*x + y*y)
130 c = rho / R
130 c = rho / R
131
131
132 with warnings.catch_warnings():
132 with warnings.catch_warnings():
133 # division by zero may occur here but is properly addressed below so
133 # division by zero may occur here but is properly addressed below so
134 # the warnings can be ignored
134 # the warnings can be ignored
135 warnings.simplefilter("ignore", RuntimeWarning)
135 warnings.simplefilter("ignore", RuntimeWarning)
136 lat_rad = numpy.arcsin(numpy.cos(c) * numpy.sin(lat_0_rad) +
136 lat_rad = numpy.arcsin(numpy.cos(c) * numpy.sin(lat_0_rad) +
137 y * numpy.sin(c) * numpy.cos(lat_0_rad) / rho)
137 y * numpy.sin(c) * numpy.cos(lat_0_rad) / rho)
138 lat_deg = numpy.rad2deg(lat_rad)
138 lat_deg = numpy.rad2deg(lat_rad)
139 # fix cases where the distance from the center of the projection is zero
139 # fix cases where the distance from the center of the projection is zero
140 lat_deg[rho == 0] = lat_0
140 lat_deg[rho == 0] = lat_0
141
141
142 x1 = x * numpy.sin(c)
142 x1 = x * numpy.sin(c)
143 x2 = rho*numpy.cos(lat_0_rad)*numpy.cos(c) - y*numpy.sin(lat_0_rad)*numpy.sin(c)
143 x2 = rho*numpy.cos(lat_0_rad)*numpy.cos(c) - y*numpy.sin(lat_0_rad)*numpy.sin(c)
144 lon_rad = lon_0_rad + numpy.arctan2(x1, x2)
144 lon_rad = lon_0_rad + numpy.arctan2(x1, x2)
145 lon_deg = numpy.rad2deg(lon_rad)
145 lon_deg = numpy.rad2deg(lon_rad)
146 # Longitudes should be from -180 to 180 degrees
146 # Longitudes should be from -180 to 180 degrees
147 lon_deg[lon_deg > 180] -= 360.
147 lon_deg[lon_deg > 180] -= 360.
148 lon_deg[lon_deg < -180] += 360.
148 lon_deg[lon_deg < -180] += 360.
149
149
150 return lon_deg, lat_deg
150 return lon_deg, lat_deg
151
151
152 def antenna_to_geographic(ranges, azimuths, elevations, site):
152 def antenna_to_geographic(ranges, azimuths, elevations, site):
153
153
154 x, y, z = antenna_to_cartesian(numpy.array(ranges), numpy.array(azimuths), numpy.array(elevations))
154 x, y, z = antenna_to_cartesian(numpy.array(ranges), numpy.array(azimuths), numpy.array(elevations))
155 lon, lat = cartesian_to_geographic_aeqd(x, y, site[0], site[1], R=6370997.)
155 lon, lat = cartesian_to_geographic_aeqd(x, y, site[0], site[1], R=6370997.)
156
156
157 return lon, lat
157 return lon, lat
158
158
159 def ll2xy(lat1, lon1, lat2, lon2):
159 def ll2xy(lat1, lon1, lat2, lon2):
160
160
161 p = 0.017453292519943295
161 p = 0.017453292519943295
162 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
162 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
163 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
163 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
164 r = 12742 * numpy.arcsin(numpy.sqrt(a))
164 r = 12742 * numpy.arcsin(numpy.sqrt(a))
165 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
165 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
166 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
166 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
167 theta = -theta + numpy.pi/2
167 theta = -theta + numpy.pi/2
168 return r*numpy.cos(theta), r*numpy.sin(theta)
168 return r*numpy.cos(theta), r*numpy.sin(theta)
169
169
170
170
171 def km2deg(km):
171 def km2deg(km):
172 '''
172 '''
173 Convert distance in km to degrees
173 Convert distance in km to degrees
174 '''
174 '''
175
175
176 return numpy.rad2deg(km/EARTH_RADIUS)
176 return numpy.rad2deg(km/EARTH_RADIUS)
177
177
178
178
179
179
180 class SpectralMomentsPlot(SpectraPlot):
180 class SpectralMomentsPlot(SpectraPlot):
181 '''
181 '''
182 Plot for Spectral Moments
182 Plot for Spectral Moments
183 '''
183 '''
184 CODE = 'spc_moments'
184 CODE = 'spc_moments'
185 # colormap = 'jet'
185 # colormap = 'jet'
186 # plot_type = 'pcolor'
186 # plot_type = 'pcolor'
187
187
188 class DobleGaussianPlot(SpectraPlot):
188 class DobleGaussianPlot(SpectraPlot):
189 '''
189 '''
190 Plot for Double Gaussian Plot
190 Plot for Double Gaussian Plot
191 '''
191 '''
192 CODE = 'gaussian_fit'
192 CODE = 'gaussian_fit'
193 # colormap = 'jet'
193 # colormap = 'jet'
194 # plot_type = 'pcolor'
194 # plot_type = 'pcolor'
195
195
196 class DoubleGaussianSpectraCutPlot(SpectraCutPlot):
196 class DoubleGaussianSpectraCutPlot(SpectraCutPlot):
197 '''
197 '''
198 Plot SpectraCut with Double Gaussian Fit
198 Plot SpectraCut with Double Gaussian Fit
199 '''
199 '''
200 CODE = 'cut_gaussian_fit'
200 CODE = 'cut_gaussian_fit'
201
201
202 class SnrPlot(RTIPlot):
202 class SnrPlot(RTIPlot):
203 '''
203 '''
204 Plot for SNR Data
204 Plot for SNR Data
205 '''
205 '''
206
206
207 CODE = 'snr'
207 CODE = 'snr'
208 colormap = 'jet'
208 colormap = 'jet'
209
209
210 def update(self, dataOut):
210 def update(self, dataOut):
211
211
212 data = {
212 data = {
213 'snr': 10*numpy.log10(dataOut.data_snr)
213 'snr': 10*numpy.log10(dataOut.data_snr)
214 }
214 }
215
215
216 return data, {}
216 return data, {}
217
217
218 class DopplerPlot(RTIPlot):
218 class DopplerPlot(RTIPlot):
219 '''
219 '''
220 Plot for DOPPLER Data (1st moment)
220 Plot for DOPPLER Data (1st moment)
221 '''
221 '''
222
222
223 CODE = 'dop'
223 CODE = 'dop'
224 colormap = 'jet'
224 colormap = 'jet'
225
225
226 def update(self, dataOut):
226 def update(self, dataOut):
227
227
228 data = {
228 data = {
229 'dop': 10*numpy.log10(dataOut.data_dop)
229 'dop': 10*numpy.log10(dataOut.data_dop)
230 }
230 }
231
231
232 return data, {}
232 return data, {}
233
233
234 class PowerPlot(RTIPlot):
234 class PowerPlot(RTIPlot):
235 '''
235 '''
236 Plot for Power Data (0 moment)
236 Plot for Power Data (0 moment)
237 '''
237 '''
238
238
239 CODE = 'pow'
239 CODE = 'pow'
240 colormap = 'jet'
240 colormap = 'jet'
241
241
242 def update(self, dataOut):
242 def update(self, dataOut):
243 data = {
243 data = {
244 'pow': 10*numpy.log10(dataOut.data_pow/dataOut.normFactor)
244 'pow': 10*numpy.log10(dataOut.data_pow/dataOut.normFactor)
245 }
245 }
246 return data, {}
246 return data, {}
247
247
248 class SpectralWidthPlot(RTIPlot):
248 class SpectralWidthPlot(RTIPlot):
249 '''
249 '''
250 Plot for Spectral Width Data (2nd moment)
250 Plot for Spectral Width Data (2nd moment)
251 '''
251 '''
252
252
253 CODE = 'width'
253 CODE = 'width'
254 colormap = 'jet'
254 colormap = 'jet'
255
255
256 def update(self, dataOut):
256 def update(self, dataOut):
257
257
258 data = {
258 data = {
259 'width': dataOut.data_width
259 'width': dataOut.data_width
260 }
260 }
261
261
262 return data, {}
262 return data, {}
263
263
264 class SkyMapPlot(Plot):
264 class SkyMapPlot(Plot):
265 '''
265 '''
266 Plot for meteors detection data
266 Plot for meteors detection data
267 '''
267 '''
268
268
269 CODE = 'param'
269 CODE = 'param'
270
270
271 def setup(self):
271 def setup(self):
272
272
273 self.ncols = 1
273 self.ncols = 1
274 self.nrows = 1
274 self.nrows = 1
275 self.width = 7.2
275 self.width = 7.2
276 self.height = 7.2
276 self.height = 7.2
277 self.nplots = 1
277 self.nplots = 1
278 self.xlabel = 'Zonal Zenith Angle (deg)'
278 self.xlabel = 'Zonal Zenith Angle (deg)'
279 self.ylabel = 'Meridional Zenith Angle (deg)'
279 self.ylabel = 'Meridional Zenith Angle (deg)'
280 self.polar = True
280 self.polar = True
281 self.ymin = -180
281 self.ymin = -180
282 self.ymax = 180
282 self.ymax = 180
283 self.colorbar = False
283 self.colorbar = False
284
284
285 def plot(self):
285 def plot(self):
286
286
287 arrayParameters = numpy.concatenate(self.data['param'])
287 arrayParameters = numpy.concatenate(self.data['param'])
288 error = arrayParameters[:, -1]
288 error = arrayParameters[:, -1]
289 indValid = numpy.where(error == 0)[0]
289 indValid = numpy.where(error == 0)[0]
290 finalMeteor = arrayParameters[indValid, :]
290 finalMeteor = arrayParameters[indValid, :]
291 finalAzimuth = finalMeteor[:, 3]
291 finalAzimuth = finalMeteor[:, 3]
292 finalZenith = finalMeteor[:, 4]
292 finalZenith = finalMeteor[:, 4]
293
293
294 x = finalAzimuth * numpy.pi / 180
294 x = finalAzimuth * numpy.pi / 180
295 y = finalZenith
295 y = finalZenith
296
296
297 ax = self.axes[0]
297 ax = self.axes[0]
298
298
299 if ax.firsttime:
299 if ax.firsttime:
300 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
300 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
301 else:
301 else:
302 ax.plot.set_data(x, y)
302 ax.plot.set_data(x, y)
303
303
304 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
304 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
305 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
305 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
306 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
306 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
307 dt2,
307 dt2,
308 len(x))
308 len(x))
309 self.titles[0] = title
309 self.titles[0] = title
310
310
311
311
312 class GenericRTIPlot(Plot):
312 class GenericRTIPlot(Plot):
313 '''
313 '''
314 Plot for data_xxxx object
314 Plot for data_xxxx object
315 '''
315 '''
316
316
317 CODE = 'param'
317 CODE = 'param'
318 colormap = 'viridis'
318 colormap = 'viridis'
319 plot_type = 'pcolorbuffer'
319 plot_type = 'pcolorbuffer'
320
320
321 def setup(self):
321 def setup(self):
322 self.xaxis = 'time'
322 self.xaxis = 'time'
323 self.ncols = 1
323 self.ncols = 1
324 self.nrows = self.data.shape('param')[0]
324 self.nrows = self.data.shape('param')[0]
325 self.nplots = self.nrows
325 self.nplots = self.nrows
326 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
326 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
327
327
328 if not self.xlabel:
328 if not self.xlabel:
329 self.xlabel = 'Time'
329 self.xlabel = 'Time'
330
330
331 self.ylabel = 'Range [km]'
331 self.ylabel = 'Range [km]'
332 if not self.titles:
332 if not self.titles:
333 self.titles = ['Param {}'.format(x) for x in range(self.nrows)]
333 self.titles = ['Param {}'.format(x) for x in range(self.nrows)]
334
334
335 def update(self, dataOut):
335 def update(self, dataOut):
336
336
337 data = {
337 data = {
338 'param' : numpy.concatenate([getattr(dataOut, attr) for attr in self.attr_data], axis=0)
338 'param' : numpy.concatenate([getattr(dataOut, attr) for attr in self.attr_data], axis=0)
339 }
339 }
340
340
341 meta = {}
341 meta = {}
342
342
343 return data, meta
343 return data, meta
344
344
345 def plot(self):
345 def plot(self):
346 # self.data.normalize_heights()
346 # self.data.normalize_heights()
347 self.x = self.data.times
347 self.x = self.data.times
348 self.y = self.data.yrange
348 self.y = self.data.yrange
349 self.z = self.data['param']
349 self.z = self.data['param']
350 self.z = 10*numpy.log10(self.z)
350 self.z = 10*numpy.log10(self.z)
351 self.z = numpy.ma.masked_invalid(self.z)
351 self.z = numpy.ma.masked_invalid(self.z)
352
352
353 if self.decimation is None:
353 if self.decimation is None:
354 x, y, z = self.fill_gaps(self.x, self.y, self.z)
354 x, y, z = self.fill_gaps(self.x, self.y, self.z)
355 else:
355 else:
356 x, y, z = self.fill_gaps(*self.decimate())
356 x, y, z = self.fill_gaps(*self.decimate())
357
357
358 for n, ax in enumerate(self.axes):
358 for n, ax in enumerate(self.axes):
359
359
360 self.zmax = self.zmax if self.zmax is not None else numpy.max(
360 self.zmax = self.zmax if self.zmax is not None else numpy.max(
361 self.z[n])
361 self.z[n])
362 self.zmin = self.zmin if self.zmin is not None else numpy.min(
362 self.zmin = self.zmin if self.zmin is not None else numpy.min(
363 self.z[n])
363 self.z[n])
364
364
365 if ax.firsttime:
365 if ax.firsttime:
366 if self.zlimits is not None:
366 if self.zlimits is not None:
367 self.zmin, self.zmax = self.zlimits[n]
367 self.zmin, self.zmax = self.zlimits[n]
368
368
369 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
369 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
370 vmin=self.zmin,
370 vmin=self.zmin,
371 vmax=self.zmax,
371 vmax=self.zmax,
372 cmap=self.cmaps[n]
372 cmap=self.cmaps[n]
373 )
373 )
374 else:
374 else:
375 if self.zlimits is not None:
375 if self.zlimits is not None:
376 self.zmin, self.zmax = self.zlimits[n]
376 self.zmin, self.zmax = self.zlimits[n]
377 ax.collections.remove(ax.collections[0])
377 ax.collections.remove(ax.collections[0])
378 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
378 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
379 vmin=self.zmin,
379 vmin=self.zmin,
380 vmax=self.zmax,
380 vmax=self.zmax,
381 cmap=self.cmaps[n]
381 cmap=self.cmaps[n]
382 )
382 )
383
383
384
384
385 class PolarMapPlot(Plot):
385 class PolarMapPlot(Plot):
386 '''
386 '''
387 Plot for weather radar
387 Plot for weather radar
388 '''
388 '''
389
389
390 CODE = 'param'
390 CODE = 'param'
391 colormap = 'seismic'
391 colormap = 'seismic'
392
392
393 def setup(self):
393 def setup(self):
394 self.ncols = 1
394 self.ncols = 1
395 self.nrows = 1
395 self.nrows = 1
396 self.width = 9
396 self.width = 9
397 self.height = 8
397 self.height = 8
398 self.mode = self.data.meta['mode']
398 self.mode = self.data.meta['mode']
399 if self.channels is not None:
399 if self.channels is not None:
400 self.nplots = len(self.channels)
400 self.nplots = len(self.channels)
401 self.nrows = len(self.channels)
401 self.nrows = len(self.channels)
402 else:
402 else:
403 self.nplots = self.data.shape(self.CODE)[0]
403 self.nplots = self.data.shape(self.CODE)[0]
404 self.nrows = self.nplots
404 self.nrows = self.nplots
405 self.channels = list(range(self.nplots))
405 self.channels = list(range(self.nplots))
406 if self.mode == 'E':
406 if self.mode == 'E':
407 self.xlabel = 'Longitude'
407 self.xlabel = 'Longitude'
408 self.ylabel = 'Latitude'
408 self.ylabel = 'Latitude'
409 else:
409 else:
410 self.xlabel = 'Range (km)'
410 self.xlabel = 'Range (km)'
411 self.ylabel = 'Height (km)'
411 self.ylabel = 'Height (km)'
412 self.bgcolor = 'white'
412 self.bgcolor = 'white'
413 self.cb_labels = self.data.meta['units']
413 self.cb_labels = self.data.meta['units']
414 self.lat = self.data.meta['latitude']
414 self.lat = self.data.meta['latitude']
415 self.lon = self.data.meta['longitude']
415 self.lon = self.data.meta['longitude']
416 self.xmin, self.xmax = float(
416 self.xmin, self.xmax = float(
417 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
417 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
418 self.ymin, self.ymax = float(
418 self.ymin, self.ymax = float(
419 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
419 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
420 # self.polar = True
420 # self.polar = True
421
421
422 def plot(self):
422 def plot(self):
423
423
424 for n, ax in enumerate(self.axes):
424 for n, ax in enumerate(self.axes):
425 data = self.data['param'][self.channels[n]]
425 data = self.data['param'][self.channels[n]]
426
426
427 zeniths = numpy.linspace(
427 zeniths = numpy.linspace(
428 0, self.data.meta['max_range'], data.shape[1])
428 0, self.data.meta['max_range'], data.shape[1])
429 if self.mode == 'E':
429 if self.mode == 'E':
430 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
430 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
431 r, theta = numpy.meshgrid(zeniths, azimuths)
431 r, theta = numpy.meshgrid(zeniths, azimuths)
432 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
432 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
433 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
433 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
434 x = km2deg(x) + self.lon
434 x = km2deg(x) + self.lon
435 y = km2deg(y) + self.lat
435 y = km2deg(y) + self.lat
436 else:
436 else:
437 azimuths = numpy.radians(self.data.yrange)
437 azimuths = numpy.radians(self.data.yrange)
438 r, theta = numpy.meshgrid(zeniths, azimuths)
438 r, theta = numpy.meshgrid(zeniths, azimuths)
439 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
439 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
440 self.y = zeniths
440 self.y = zeniths
441
441
442 if ax.firsttime:
442 if ax.firsttime:
443 if self.zlimits is not None:
443 if self.zlimits is not None:
444 self.zmin, self.zmax = self.zlimits[n]
444 self.zmin, self.zmax = self.zlimits[n]
445 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
445 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
446 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
446 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
447 vmin=self.zmin,
447 vmin=self.zmin,
448 vmax=self.zmax,
448 vmax=self.zmax,
449 cmap=self.cmaps[n])
449 cmap=self.cmaps[n])
450 else:
450 else:
451 if self.zlimits is not None:
451 if self.zlimits is not None:
452 self.zmin, self.zmax = self.zlimits[n]
452 self.zmin, self.zmax = self.zlimits[n]
453 ax.collections.remove(ax.collections[0])
453 ax.collections.remove(ax.collections[0])
454 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
454 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
455 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
455 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
456 vmin=self.zmin,
456 vmin=self.zmin,
457 vmax=self.zmax,
457 vmax=self.zmax,
458 cmap=self.cmaps[n])
458 cmap=self.cmaps[n])
459
459
460 if self.mode == 'A':
460 if self.mode == 'A':
461 continue
461 continue
462
462
463 # plot district names
463 # plot district names
464 f = open('/data/workspace/schain_scripts/distrito.csv')
464 f = open('/data/workspace/schain_scripts/distrito.csv')
465 for line in f:
465 for line in f:
466 label, lon, lat = [s.strip() for s in line.split(',') if s]
466 label, lon, lat = [s.strip() for s in line.split(',') if s]
467 lat = float(lat)
467 lat = float(lat)
468 lon = float(lon)
468 lon = float(lon)
469 # ax.plot(lon, lat, '.b', ms=2)
469 # ax.plot(lon, lat, '.b', ms=2)
470 ax.text(lon, lat, label.decode('utf8'), ha='center',
470 ax.text(lon, lat, label.decode('utf8'), ha='center',
471 va='bottom', size='8', color='black')
471 va='bottom', size='8', color='black')
472
472
473 # plot limites
473 # plot limites
474 limites = []
474 limites = []
475 tmp = []
475 tmp = []
476 for line in open('/data/workspace/schain_scripts/lima.csv'):
476 for line in open('/data/workspace/schain_scripts/lima.csv'):
477 if '#' in line:
477 if '#' in line:
478 if tmp:
478 if tmp:
479 limites.append(tmp)
479 limites.append(tmp)
480 tmp = []
480 tmp = []
481 continue
481 continue
482 values = line.strip().split(',')
482 values = line.strip().split(',')
483 tmp.append((float(values[0]), float(values[1])))
483 tmp.append((float(values[0]), float(values[1])))
484 for points in limites:
484 for points in limites:
485 ax.add_patch(
485 ax.add_patch(
486 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
486 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
487
487
488 # plot Cuencas
488 # plot Cuencas
489 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
489 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
490 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
490 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
491 values = [line.strip().split(',') for line in f]
491 values = [line.strip().split(',') for line in f]
492 points = [(float(s[0]), float(s[1])) for s in values]
492 points = [(float(s[0]), float(s[1])) for s in values]
493 ax.add_patch(Polygon(points, ec='b', fc='none'))
493 ax.add_patch(Polygon(points, ec='b', fc='none'))
494
494
495 # plot grid
495 # plot grid
496 for r in (15, 30, 45, 60):
496 for r in (15, 30, 45, 60):
497 ax.add_artist(plt.Circle((self.lon, self.lat),
497 ax.add_artist(plt.Circle((self.lon, self.lat),
498 km2deg(r), color='0.6', fill=False, lw=0.2))
498 km2deg(r), color='0.6', fill=False, lw=0.2))
499 ax.text(
499 ax.text(
500 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
500 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
501 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
501 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
502 '{}km'.format(r),
502 '{}km'.format(r),
503 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
503 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
504
504
505 if self.mode == 'E':
505 if self.mode == 'E':
506 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
506 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
507 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
507 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
508 else:
508 else:
509 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
509 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
510 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
510 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
511
511
512 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
512 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
513 self.titles = ['{} {}'.format(
513 self.titles = ['{} {}'.format(
514 self.data.parameters[x], title) for x in self.channels]
514 self.data.parameters[x], title) for x in self.channels]
515
515
516
517
516 class WeatherParamsPlot(Plot):
518 class WeatherParamsPlot(Plot):
517
519
518 plot_type = 'scattermap'
520 plot_type = 'scattermap'
519 buffering = False
521 buffering = False
520
522
521 def setup(self):
523 def setup(self):
522
524
523 self.ncols = 1
525 self.ncols = 1
524 self.nrows = 1
526 self.nrows = 1
525 self.nplots= 1
527 self.nplots= 1
526
528
527 if self.channels is not None:
529 if self.channels is not None:
528 self.nplots = len(self.channels)
530 self.nplots = len(self.channels)
529 self.ncols = len(self.channels)
531 self.ncols = len(self.channels)
530 else:
532 else:
531 self.nplots = self.data.shape(self.CODE)[0]
533 self.nplots = self.data.shape(self.CODE)[0]
532 self.ncols = self.nplots
534 self.ncols = self.nplots
533 self.channels = list(range(self.nplots))
535 self.channels = list(range(self.nplots))
534
536
535 self.colorbar=True
537 self.colorbar=True
536 if len(self.channels)>1:
538 if len(self.channels)>1:
537 self.width = 12
539 self.width = 12
538 else:
540 else:
539 self.width =8
541 self.width =8
540 self.height =7
542 self.height =7
541 self.ini =0
543 self.ini =0
542 self.len_azi =0
544 self.len_azi =0
543 self.buffer_ini = None
545 self.buffer_ini = None
544 self.buffer_ele = None
546 self.buffer_ele = None
545 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.1})
547 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.1})
546 self.flag =0
548 self.flag =0
547 self.indicador= 0
549 self.indicador= 0
548 self.last_data_ele = None
550 self.last_data_ele = None
549 self.val_mean = None
551 self.val_mean = None
550
552
551 def update(self, dataOut):
553 def update(self, dataOut):
552
554
553 vars = {
555 vars = {
554 'S' : 0,
556 'S' : 0,
555 'V' : 1,
557 'V' : 1,
556 'W' : 2,
558 'W' : 2,
557 'SNR' : 3,
559 'SNR' : 3,
558 'Z' : 4,
560 'Z' : 4,
559 'D' : 5,
561 'D' : 5,
560 'P' : 6,
562 'P' : 6,
561 'R' : 7,
563 'R' : 7,
562 }
564 }
563
565
564 data = {}
566 data = {}
565 meta = {}
567 meta = {}
566
568
567 if hasattr(dataOut, 'nFFTPoints'):
569 ##if hasattr(dataOut, 'nFFTPoints'):
568 factor = dataOut.normFactor
570 ## factor = dataOut.normFactor*10.0 # CONSIDERACION ENTRE PULSE PAIR Y FFT
569 else:
571 ##else:
570 factor = 1
572 ## factor = 1
571
573
572 if hasattr(dataOut, 'dparam'):
574 if hasattr(dataOut, 'dparam'):
573 tmp = getattr(dataOut, 'data_param')
575 tmp = getattr(dataOut, 'data_param')
574 else:
576 else:
575 #print("-------------------self.attr_data[0]",self.attr_data[0])
577 #print("-------------------self.attr_data[0]",self.attr_data[0])
576 if 'S' in self.attr_data[0]:
578 if 'S' in self.attr_data[0]:
577 if self.attr_data[0]=='S':
579 if self.attr_data[0]=='S':
578 tmp = 10*numpy.log10(10.0*getattr(dataOut, 'data_param')[:,0,:]/(factor))
580 tmp = 10*numpy.log10(10.0*getattr(dataOut, 'data_param')[:,0,:]) ## /(factor)) ya no considerar factor se aplica factor jroproc_parametrs
579 if self.attr_data[0]=='SNR':
581 if self.attr_data[0]=='SNR':
580 tmp = 10*numpy.log10(getattr(dataOut, 'data_param')[:,3,:])
582 tmp = 10*numpy.log10(getattr(dataOut, 'data_param')[:,3,:])
581 else:
583 else:
582 tmp = getattr(dataOut, 'data_param')[:,vars[self.attr_data[0]],:]
584 tmp = getattr(dataOut, 'data_param')[:,vars[self.attr_data[0]],:]
583
585
584 if self.mask:
586 if self.mask:
585 mask = dataOut.data_param[:,3,:] < self.mask
587 mask = dataOut.data_param[:,3,:] < self.mask
586 tmp[mask] = numpy.nan
588 tmp[mask] = numpy.nan
587 mask = numpy.nansum((tmp, numpy.roll(tmp, 1),numpy.roll(tmp, -1)), axis=0) == tmp
589 mask = numpy.nansum((tmp, numpy.roll(tmp, 1),numpy.roll(tmp, -1)), axis=0) == tmp
588 tmp[mask] = numpy.nan
590 tmp[mask] = numpy.nan
589
591
592 ####################################################################
593 #SE GUARDAN LOS DATOS DE LOS PARAMETROS YA SEA PP O SPECTRA EN UN ARCHIVO .npy
594 ##elapsed_time = time.time() - self.start_time
595 ##filename = f'{dataOut.inputUnit}_{self.attr_data[0]}_{elapsed_time:.0f}.npy' # Nombre único con timestamp
596
597 # Guardar el array en el nuevo archivo
598 ##with open(filename, 'wb') as f:
599 ## numpy.save(f, tmp)
600
601 ##print("Se creó el archivo:", filename)
602
603
604 #####################################################################
590 r = dataOut.heightList
605 r = dataOut.heightList
591 delta_height = r[1]-r[0]
606 delta_height = r[1]-r[0]
592 valid = numpy.where(r>=0)[0]
607 valid = numpy.where(r>=0)[0]
593 data['r'] = numpy.arange(len(valid))*delta_height
608 data['r'] = numpy.arange(len(valid))*delta_height
594
609
595 data['data'] = [0, 0]
610 data['data'] = [0, 0]
596
611
597 try:
612 try:
598 data['data'][0] = tmp[0][:,valid]
613 data['data'][0] = tmp[0][:,valid]
599 data['data'][1] = tmp[1][:,valid]
614 data['data'][1] = tmp[1][:,valid]
600 except:
615 except:
601 data['data'][0] = tmp[0][:,valid]
616 data['data'][0] = tmp[0][:,valid]
602 data['data'][1] = tmp[0][:,valid]
617 data['data'][1] = tmp[0][:,valid]
603
618
604 if dataOut.mode_op == 'PPI':
619 if dataOut.mode_op == 'PPI':
605 self.CODE = 'PPI'
620 self.CODE = 'PPI'
606 self.title = self.CODE
621 self.title = self.CODE
607 elif dataOut.mode_op == 'RHI':
622 elif dataOut.mode_op == 'RHI':
608 self.CODE = 'RHI'
623 self.CODE = 'RHI'
609 self.title = self.CODE
624 self.title = self.CODE
610
625
611 data['azi'] = dataOut.data_azi
626 data['azi'] = dataOut.data_azi
612 data['ele'] = dataOut.data_ele
627 data['ele'] = dataOut.data_ele
613
628
614 if isinstance(dataOut.mode_op, bytes):
629 if isinstance(dataOut.mode_op, bytes):
615 try:
630 try:
616 dataOut.mode_op = dataOut.mode_op.decode()
631 dataOut.mode_op = dataOut.mode_op.decode()
617 except:
632 except:
618 dataOut.mode_op = str(dataOut.mode_op, 'utf-8')
633 dataOut.mode_op = str(dataOut.mode_op, 'utf-8')
619 data['mode_op'] = dataOut.mode_op
634 data['mode_op'] = dataOut.mode_op
620 self.mode = dataOut.mode_op
635 self.mode = dataOut.mode_op
621
636
622 return data, meta
637 return data, meta
623
638
624 def plot(self):
639 def plot(self):
625 data = self.data[-1]
640 data = self.data[-1]
626 z = data['data']
641 z = data['data']
627 r = data['r']
642 r = data['r']
628 self.titles = []
643 self.titles = []
629
644
630 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
645 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
631 self.zmin = self.zmin if self.zmin is not None else numpy.nanmin(z)
646 self.zmin = self.zmin if self.zmin is not None else numpy.nanmin(z)
632
647
633 if isinstance(data['mode_op'], bytes):
648 if isinstance(data['mode_op'], bytes):
634 data['mode_op'] = data['mode_op'].decode()
649 data['mode_op'] = data['mode_op'].decode()
635
650
636 if data['mode_op'] == 'RHI':
651 if data['mode_op'] == 'RHI':
637 r, theta = numpy.meshgrid(r, numpy.radians(data['ele']))
652 r, theta = numpy.meshgrid(r, numpy.radians(data['ele']))
638 len_aux = int(data['azi'].shape[0]/4)
653 len_aux = int(data['azi'].shape[0]/4)
639 mean = numpy.mean(data['azi'][len_aux:-len_aux])
654 mean = numpy.mean(data['azi'][len_aux:-len_aux])
640 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
655 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
641 if self.yrange:
656 if self.yrange:
642 self.ylabel= 'Height [km]'
657 self.ylabel= 'Height [km]'
643 self.xlabel= 'Distance from radar [km]'
658 self.xlabel= 'Distance from radar [km]'
644 self.ymax = self.yrange
659 self.ymax = self.yrange
645 self.ymin = 0
660 self.ymin = 0
646 self.xmax = self.xrange if self.xrange else numpy.nanmax(r)
661 self.xmax = self.xrange if self.xrange else numpy.nanmax(r)
647 self.xmin = -self.xrange if self.xrange else -numpy.nanmax(r)
662 self.xmin = -self.xrange if self.xrange else -numpy.nanmax(r)
648 self.setrhilimits = False
663 self.setrhilimits = False
649 else:
664 else:
650 self.ymin = 0
665 self.ymin = 0
651 self.ymax = numpy.nanmax(r)
666 self.ymax = numpy.nanmax(r)
652 self.xmin = -numpy.nanmax(r)
667 self.xmin = -numpy.nanmax(r)
653 self.xmax = numpy.nanmax(r)
668 self.xmax = numpy.nanmax(r)
654
669
655 elif data['mode_op'] == 'PPI':
670 elif data['mode_op'] == 'PPI':
656 r, theta = numpy.meshgrid(r, -numpy.radians(data['azi'])+numpy.pi/2)
671 r, theta = numpy.meshgrid(r, -numpy.radians(data['azi'])+numpy.pi/2)
657 len_aux = int(data['ele'].shape[0]/4)
672 len_aux = int(data['ele'].shape[0]/4)
658 mean = numpy.mean(data['ele'][len_aux:-len_aux])
673 mean = numpy.mean(data['ele'][len_aux:-len_aux])
659 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(mean)), r*numpy.sin(
674 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(mean)), r*numpy.sin(
660 theta)*numpy.cos(numpy.radians(mean))
675 theta)*numpy.cos(numpy.radians(mean))
661 x = km2deg(x) + self.longitude
676 x = km2deg(x) + self.longitude
662 y = km2deg(y) + self.latitude
677 y = km2deg(y) + self.latitude
663 if self.xrange:
678 if self.xrange:
664 self.ylabel= 'Latitude'
679 self.ylabel= 'Latitude'
665 self.xlabel= 'Longitude'
680 self.xlabel= 'Longitude'
666
681
667 self.xmin = km2deg(-self.xrange) + self.longitude
682 self.xmin = km2deg(-self.xrange) + self.longitude
668 self.xmax = km2deg(self.xrange) + self.longitude
683 self.xmax = km2deg(self.xrange) + self.longitude
669
684
670 self.ymin = km2deg(-self.xrange) + self.latitude
685 self.ymin = km2deg(-self.xrange) + self.latitude
671 self.ymax = km2deg(self.xrange) + self.latitude
686 self.ymax = km2deg(self.xrange) + self.latitude
672 else:
687 else:
673 self.xmin = km2deg(-numpy.nanmax(r)) + self.longitude
688 self.xmin = km2deg(-numpy.nanmax(r)) + self.longitude
674 self.xmax = km2deg(numpy.nanmax(r)) + self.longitude
689 self.xmax = km2deg(numpy.nanmax(r)) + self.longitude
675
690
676 self.ymin = km2deg(-numpy.nanmax(r)) + self.latitude
691 self.ymin = km2deg(-numpy.nanmax(r)) + self.latitude
677 self.ymax = km2deg(numpy.nanmax(r)) + self.latitude
692 self.ymax = km2deg(numpy.nanmax(r)) + self.latitude
678
693
679 self.clear_figures()
694 self.clear_figures()
680
695
681 if data['mode_op'] == 'PPI':
696 if data['mode_op'] == 'PPI':
682 axes = self.axes['PPI']
697 axes = self.axes['PPI']
683 else:
698 else:
684 axes = self.axes['RHI']
699 axes = self.axes['RHI']
685
700
686 if self.colormap in cb_tables:
701 if self.colormap in cb_tables:
687 norm = cb_tables[self.colormap]['norm']
702 norm = cb_tables[self.colormap]['norm']
688 else:
703 else:
689 norm = None
704 norm = None
690
705
691 for i, ax in enumerate(axes):
706 for i, ax in enumerate(axes):
692
707
693 if norm is None:
708 if norm is None:
694 ax.plt = ax.pcolormesh(x, y, z[i], cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
709 ax.plt = ax.pcolormesh(x, y, z[i], cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
695 else:
710 else:
696 ax.plt = ax.pcolormesh(x, y, z[i], cmap=self.colormap, norm=norm)
711 ax.plt = ax.pcolormesh(x, y, z[i], cmap=self.colormap, norm=norm)
697
712
698 if data['mode_op'] == 'RHI':
713 if data['mode_op'] == 'RHI':
699 len_aux = int(data['azi'].shape[0]/4)
714 len_aux = int(data['azi'].shape[0]/4)
700 mean = numpy.mean(data['azi'][len_aux:-len_aux])
715 mean = numpy.mean(data['azi'][len_aux:-len_aux])
701 if len(self.channels) !=1:
716 if len(self.channels) !=1:
702 self.titles = ['RHI {} at AZ: {} CH {}'.format(self.labels[x], str(round(mean,1)), x) for x in self.channels]
717 self.titles = ['RHI {} at AZ: {} CH {}'.format(self.labels[x], str(round(mean,1)), x) for x in self.channels]
703 else:
718 else:
704 self.titles = ['RHI {} at AZ: {} CH {}'.format(self.labels[0], str(round(mean,1)), self.channels[0])]
719 self.titles = ['RHI {} at AZ: {} CH {}'.format(self.labels[0], str(round(mean,1)), self.channels[0])]
705 elif data['mode_op'] == 'PPI':
720 elif data['mode_op'] == 'PPI':
706 len_aux = int(data['ele'].shape[0]/4)
721 len_aux = int(data['ele'].shape[0]/4)
707 mean = numpy.mean(data['ele'][len_aux:-len_aux])
722 mean = numpy.mean(data['ele'][len_aux:-len_aux])
708 if len(self.channels) !=1:
723 if len(self.channels) !=1:
709 self.titles = ['PPI {} at EL: {} CH {}'.format(self.labels[x], str(round(mean,1)), x) for x in self.channels]
724 self.titles = ['PPI {} at EL: {} CH {}'.format(self.labels[x], str(round(mean,1)), x) for x in self.channels]
710 else:
725 else:
711 self.titles = ['PPI {} at EL: {} CH {}'.format(self.labels[0], str(round(mean,1)), self.channels[0])]
726 self.titles = ['PPI {} at EL: {} CH {}'.format(self.labels[0], str(round(mean,1)), self.channels[0])]
712 self.mode_value = round(mean,1)
727 self.mode_value = round(mean,1)
713
728
714 if data['mode_op'] == 'PPI':
729 if data['mode_op'] == 'PPI':
715 if self.map:
730 if self.map:
716 gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,
731 gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,
717 linewidth=1, color='gray', alpha=0.5, linestyle='--')
732 linewidth=1, color='gray', alpha=0.5, linestyle='--')
718 gl.xlabel_style = {'size': 8}
733 gl.xlabel_style = {'size': 8}
719 gl.ylabel_style = {'size': 8}
734 gl.ylabel_style = {'size': 8}
720 gl.xlabels_top = False
735 gl.xlabels_top = False
721 gl.ylabels_right = False
736 gl.ylabels_right = False
722 shape_d = os.path.join(self.shapes,'Distritos/PER_adm3.shp')
737 shape_d = os.path.join(self.shapes,'Distritos/PER_adm3.shp')
723 shape_p = os.path.join(self.shapes,'PER_ADM2/PER_ADM2.shp')
738 shape_p = os.path.join(self.shapes,'PER_ADM2/PER_ADM2.shp')
724 capitales = os.path.join(self.shapes,'CAPITALES/cap_distrito.shp')
739 capitales = os.path.join(self.shapes,'CAPITALES/cap_distrito.shp')
725 vias = os.path.join(self.shapes,'Carreteras/VIAS_NACIONAL_250000.shp')
740 vias = os.path.join(self.shapes,'Carreteras/VIAS_NACIONAL_250000.shp')
726 reader_d = shpreader.BasicReader(shape_d, encoding='latin1')
741 reader_d = shpreader.BasicReader(shape_d, encoding='latin1')
727 reader_p = shpreader.BasicReader(shape_p, encoding='latin1')
742 reader_p = shpreader.BasicReader(shape_p, encoding='latin1')
728 reader_c = shpreader.BasicReader(capitales, encoding='latin1')
743 reader_c = shpreader.BasicReader(capitales, encoding='latin1')
729 reader_v = shpreader.BasicReader(vias, encoding='latin1')
744 reader_v = shpreader.BasicReader(vias, encoding='latin1')
730 caps = [x for x in reader_c.records() if x.attributes['DEPARTA']=='PIURA' and x.attributes['CATEGORIA']=='CIUDAD']
745 caps = [x for x in reader_c.records() if x.attributes['DEPARTA']=='PIURA' and x.attributes['CATEGORIA']=='CIUDAD']
731 districts = [x for x in reader_d.records() if x.attributes['NAME_1']=='Piura']
746 districts = [x for x in reader_d.records() if x.attributes['NAME_1']=='Piura']
732 provs = [x for x in reader_p.records()]
747 provs = [x for x in reader_p.records()]
733 vias = [x for x in reader_v.records()]
748 vias = [x for x in reader_v.records()]
734
749
735 # Display limits and streets
750 # Display limits and streets
736 shape_feature = ShapelyFeature([x.geometry for x in districts], ccrs.PlateCarree(), facecolor="none", edgecolor='grey', lw=0.5)
751 shape_feature = ShapelyFeature([x.geometry for x in districts], ccrs.PlateCarree(), facecolor="none", edgecolor='grey', lw=0.5)
737 ax.add_feature(shape_feature)
752 ax.add_feature(shape_feature)
738 shape_feature = ShapelyFeature([x.geometry for x in provs], ccrs.PlateCarree(), facecolor="none", edgecolor='white', lw=1)
753 shape_feature = ShapelyFeature([x.geometry for x in provs], ccrs.PlateCarree(), facecolor="none", edgecolor='white', lw=1)
739 ax.add_feature(shape_feature)
754 ax.add_feature(shape_feature)
740 shape_feature = ShapelyFeature([x.geometry for x in vias], ccrs.PlateCarree(), facecolor="none", edgecolor='yellow', lw=1)
755 shape_feature = ShapelyFeature([x.geometry for x in vias], ccrs.PlateCarree(), facecolor="none", edgecolor='yellow', lw=1)
741 ax.add_feature(shape_feature)
756 ax.add_feature(shape_feature)
742
757
743 for cap in caps:
758 for cap in caps:
744 if cap.attributes['NOMBRE'] in ('PIURA', 'SULLANA', 'PAITA', 'SECHURA', 'TALARA'):
759 if cap.attributes['NOMBRE'] in ('PIURA', 'SULLANA', 'PAITA', 'SECHURA', 'TALARA'):
745 ax.text(cap.attributes['X'], cap.attributes['Y'], cap.attributes['NOMBRE'], size=8, color='white', weight='bold')
760 ax.text(cap.attributes['X'], cap.attributes['Y'], cap.attributes['NOMBRE'], size=8, color='white', weight='bold')
746 elif cap.attributes['NOMBRE'] in ('NEGRITOS', 'SAN LUCAS', 'QUERECOTILLO', 'TAMBO GRANDE', 'CHULUCANAS', 'CATACAOS', 'LA UNION'):
761 elif cap.attributes['NOMBRE'] in ('NEGRITOS', 'SAN LUCAS', 'QUERECOTILLO', 'TAMBO GRANDE', 'CHULUCANAS', 'CATACAOS', 'LA UNION'):
747 ax.text(cap.attributes['X'], cap.attributes['Y'], cap.attributes['NOMBRE'].title(), size=7, color='white')
762 ax.text(cap.attributes['X'], cap.attributes['Y'], cap.attributes['NOMBRE'].title(), size=7, color='white')
748 else:
763 else:
749 ax.grid(color='grey', alpha=0.5, linestyle='--', linewidth=1)
764 ax.grid(color='grey', alpha=0.5, linestyle='--', linewidth=1)
750
765
751 if self.xrange<=10:
766 if self.xrange<=10:
752 ranges = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
767 ranges = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
753 elif self.xrange<=30:
768 elif self.xrange<=30:
754 ranges = [5, 10, 15, 20, 25, 30, 35]
769 ranges = [5, 10, 15, 20, 25, 30, 35]
755 elif self.xrange<=60:
770 elif self.xrange<=60:
756 ranges = [10, 20, 30, 40, 50, 60]
771 ranges = [10, 20, 30, 40, 50, 60]
757 elif self.xrange<=100:
772 elif self.xrange<=100:
758 ranges = [15, 30, 45, 60, 75, 90]
773 ranges = [15, 30, 45, 60, 75, 90]
759
774
760 for R in ranges:
775 for R in ranges:
761 if R <= self.xrange:
776 if R <= self.xrange:
762 circle = Circle((self.longitude, self.latitude), km2deg(R), facecolor='none',
777 circle = Circle((self.longitude, self.latitude), km2deg(R), facecolor='none',
763 edgecolor='skyblue', linewidth=1, alpha=0.5)
778 edgecolor='skyblue', linewidth=1, alpha=0.5)
764 ax.add_patch(circle)
779 ax.add_patch(circle)
765 ax.text(km2deg(R)*numpy.cos(numpy.radians(45))+self.longitude,
780 ax.text(km2deg(R)*numpy.cos(numpy.radians(45))+self.longitude,
766 km2deg(R)*numpy.sin(numpy.radians(45))+self.latitude,
781 km2deg(R)*numpy.sin(numpy.radians(45))+self.latitude,
767 '{}km'.format(R), color='skyblue', size=7)
782 '{}km'.format(R), color='skyblue', size=7)
768 elif data['mode_op'] == 'RHI':
783 elif data['mode_op'] == 'RHI':
769 ax.grid(color='grey', alpha=0.5, linestyle='--', linewidth=1)
784 ax.grid(color='grey', alpha=0.5, linestyle='--', linewidth=1)
@@ -1,863 +1,865
1 '''
1 '''
2 Created on Jul 3, 2014
2 Created on Jul 3, 2014
3
3
4 @author: roj-idl71
4 @author: roj-idl71
5 '''
5 '''
6 # SUBCHANNELS EN VEZ DE CHANNELS
6 # SUBCHANNELS EN VEZ DE CHANNELS
7 # BENCHMARKS -> PROBLEMAS CON ARCHIVOS GRANDES -> INCONSTANTE EN EL TIEMPO
7 # BENCHMARKS -> PROBLEMAS CON ARCHIVOS GRANDES -> INCONSTANTE EN EL TIEMPO
8 # ACTUALIZACION DE VERSION
8 # ACTUALIZACION DE VERSION
9 # HEADERS
9 # HEADERS
10 # MODULO DE ESCRITURA
10 # MODULO DE ESCRITURA
11 # METADATA
11 # METADATA
12
12
13 import os
13 import os
14 import time
14 import time
15 import datetime
15 import datetime
16 import numpy
16 import numpy
17 import timeit
17 import timeit
18 from fractions import Fraction
18 from fractions import Fraction
19 from time import time
19 from time import time
20 from time import sleep
20 from time import sleep
21
21
22 import schainpy.admin
22 import schainpy.admin
23 from schainpy.model.data.jroheaderIO import RadarControllerHeader, SystemHeader
23 from schainpy.model.data.jroheaderIO import RadarControllerHeader, SystemHeader
24 from schainpy.model.data.jrodata import Voltage
24 from schainpy.model.data.jrodata import Voltage
25 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
25 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
26
26
27 import pickle
27 import pickle
28 try:
28 try:
29 os.environ["HDF5_USE_FILE_LOCKING"] = "FALSE"
29 os.environ["HDF5_USE_FILE_LOCKING"] = "FALSE"
30 import digital_rf
30 import digital_rf
31 except:
31 except:
32 pass
32 pass
33
33
34
34
35 class DigitalRFReader(ProcessingUnit):
35 class DigitalRFReader(ProcessingUnit):
36 '''
36 '''
37 classdocs
37 classdocs
38 '''
38 '''
39
39
40 def __init__(self):
40 def __init__(self):
41 '''
41 '''
42 Constructor
42 Constructor
43 '''
43 '''
44
44
45 ProcessingUnit.__init__(self)
45 ProcessingUnit.__init__(self)
46
46
47 self.dataOut = Voltage()
47 self.dataOut = Voltage()
48 self.__printInfo = True
48 self.__printInfo = True
49 self.__flagDiscontinuousBlock = False
49 self.__flagDiscontinuousBlock = False
50 self.__bufferIndex = 9999999
50 self.__bufferIndex = 9999999
51 self.__codeType = 0
51 self.__codeType = 0
52 self.__ippKm = None
52 self.__ippKm = None
53 self.__nCode = None
53 self.__nCode = None
54 self.__nBaud = None
54 self.__nBaud = None
55 self.__code = None
55 self.__code = None
56 self.dtype = None
56 self.dtype = None
57 self.oldAverage = None
57 self.oldAverage = None
58 self.path = None
58 self.path = None
59
59
60 def close(self):
60 def close(self):
61 print('Average of writing to digital rf format is ', self.oldAverage * 1000)
61 print('Average of writing to digital rf format is ', self.oldAverage * 1000)
62 return
62 return
63
63
64 def __getCurrentSecond(self):
64 def __getCurrentSecond(self):
65
65
66 return self.__thisUnixSample / self.__sample_rate
66 return self.__thisUnixSample / self.__sample_rate
67
67
68 thisSecond = property(__getCurrentSecond, "I'm the 'thisSecond' property.")
68 thisSecond = property(__getCurrentSecond, "I'm the 'thisSecond' property.")
69
69
70 def __setFileHeader(self):
70 def __setFileHeader(self):
71 '''
71 '''
72 In this method will be initialized every parameter of dataOut object (header, no data)
72 In this method will be initialized every parameter of dataOut object (header, no data)
73 '''
73 '''
74 ippSeconds = 1.0 * self.__nSamples / self.__sample_rate
74 ippSeconds = 1.0 * self.__nSamples / self.__sample_rate
75 if not self.getByBlock:
75 if not self.getByBlock:
76 nProfiles = 1.0 / ippSeconds # Number of profiles in one second
76 nProfiles = 1.0 / ippSeconds # Number of profiles in one second
77 else:
77 else:
78 nProfiles = self.nProfileBlocks # Number of profiles in one block
78 nProfiles = self.nProfileBlocks # Number of profiles in one block
79
79
80 try:
80 try:
81 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(
81 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(
82 self.__radarControllerHeader)
82 self.__radarControllerHeader)
83 except:
83 except:
84 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(
84 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(
85 txA=0,
85 txA=0,
86 txB=0,
86 txB=0,
87 nWindows=1,
87 nWindows=1,
88 nHeights=self.__nSamples,
88 nHeights=self.__nSamples,
89 firstHeight=self.__firstHeigth,
89 firstHeight=self.__firstHeigth,
90 deltaHeight=self.__deltaHeigth,
90 deltaHeight=self.__deltaHeigth,
91 codeType=self.__codeType,
91 codeType=self.__codeType,
92 nCode=self.__nCode, nBaud=self.__nBaud,
92 nCode=self.__nCode, nBaud=self.__nBaud,
93 code=self.__code)
93 code=self.__code)
94
94
95 try:
95 try:
96 self.dataOut.systemHeaderObj = SystemHeader(self.__systemHeader)
96 self.dataOut.systemHeaderObj = SystemHeader(self.__systemHeader)
97 except:
97 except:
98 self.dataOut.systemHeaderObj = SystemHeader(nSamples=self.__nSamples,
98 self.dataOut.systemHeaderObj = SystemHeader(nSamples=self.__nSamples,
99 nProfiles=nProfiles,
99 nProfiles=nProfiles,
100 nChannels=len(
100 nChannels=len(
101 self.__channelList),
101 self.__channelList),
102 adcResolution=14)
102 adcResolution=14)
103 self.dataOut.type = "Voltage"
103 self.dataOut.type = "Voltage"
104
104
105 self.dataOut.data = None
105 self.dataOut.data = None
106
106
107 self.dataOut.dtype = self.dtype
107 self.dataOut.dtype = self.dtype
108
108
109 # self.dataOut.nChannels = 0
109 # self.dataOut.nChannels = 0
110
110
111 # self.dataOut.nHeights = 0
111 # self.dataOut.nHeights = 0
112
112
113 self.dataOut.nProfiles = int(nProfiles)
113 self.dataOut.nProfiles = int(nProfiles)
114
114
115 self.dataOut.heightList = self.__firstHeigth + \
115 self.dataOut.heightList = self.__firstHeigth + \
116 numpy.arange(self.__nSamples, dtype=numpy.float_) * \
116 numpy.arange(self.__nSamples, dtype=numpy.float_) * \
117 self.__deltaHeigth
117 self.__deltaHeigth
118
118
119 #self.dataOut.channelList = list(range(self.__num_subchannels))
119 #self.dataOut.channelList = list(range(self.__num_subchannels))
120 self.dataOut.channelList = list(range(len(self.__channelList)))
120 self.dataOut.channelList = list(range(len(self.__channelList)))
121 if not self.getByBlock:
121 if not self.getByBlock:
122
122
123 self.dataOut.blocksize = self.dataOut.nChannels * self.dataOut.nHeights
123 self.dataOut.blocksize = self.dataOut.nChannels * self.dataOut.nHeights
124 else:
124 else:
125 self.dataOut.blocksize = self.dataOut.nChannels * self.dataOut.nHeights*self.nProfileBlocks
125 self.dataOut.blocksize = self.dataOut.nChannels * self.dataOut.nHeights*self.nProfileBlocks
126
126
127 # self.dataOut.channelIndexList = None
127 # self.dataOut.channelIndexList = None
128
128
129 self.dataOut.flagNoData = True
129 self.dataOut.flagNoData = True
130 if not self.getByBlock:
130 if not self.getByBlock:
131 self.dataOut.flagDataAsBlock = False
131 self.dataOut.flagDataAsBlock = False
132 else:
132 else:
133 self.dataOut.flagDataAsBlock = True
133 self.dataOut.flagDataAsBlock = True
134 # Set to TRUE if the data is discontinuous
134 # Set to TRUE if the data is discontinuous
135 self.dataOut.flagDiscontinuousBlock = False
135 self.dataOut.flagDiscontinuousBlock = False
136
136
137 self.dataOut.utctime = None
137 self.dataOut.utctime = None
138
138
139 # timezone like jroheader, difference in minutes between UTC and localtime
139 # timezone like jroheader, difference in minutes between UTC and localtime
140 self.dataOut.timeZone = self.__timezone / 60
140 self.dataOut.timeZone = self.__timezone / 60
141
141
142 self.dataOut.dstFlag = 0
142 self.dataOut.dstFlag = 0
143
143
144 self.dataOut.errorCount = 0
144 self.dataOut.errorCount = 0
145
145
146 try:
146 try:
147 self.dataOut.nCohInt = self.fixed_metadata_dict.get(
147 self.dataOut.nCohInt = self.fixed_metadata_dict.get(
148 'nCohInt', self.nCohInt)
148 'nCohInt', self.nCohInt)
149
149
150 # asumo que la data esta decodificada
150 # asumo que la data esta decodificada
151 self.dataOut.flagDecodeData = self.fixed_metadata_dict.get(
151 self.dataOut.flagDecodeData = self.fixed_metadata_dict.get(
152 'flagDecodeData', self.flagDecodeData)
152 'flagDecodeData', self.flagDecodeData)
153
153
154 # asumo que la data esta sin flip
154 # asumo que la data esta sin flip
155 self.dataOut.flagDeflipData = self.fixed_metadata_dict['flagDeflipData']
155 self.dataOut.flagDeflipData = self.fixed_metadata_dict['flagDeflipData']
156
156
157 self.dataOut.flagShiftFFT = self.fixed_metadata_dict['flagShiftFFT']
157 self.dataOut.flagShiftFFT = self.fixed_metadata_dict['flagShiftFFT']
158
158
159 self.dataOut.useLocalTime = self.fixed_metadata_dict['useLocalTime']
159 self.dataOut.useLocalTime = self.fixed_metadata_dict['useLocalTime']
160 except:
160 except:
161 pass
161 pass
162
162
163 self.dataOut.ippSeconds = ippSeconds
163 self.dataOut.ippSeconds = ippSeconds
164
164
165 # Time interval between profiles
165 # Time interval between profiles
166 # self.dataOut.timeInterval = self.dataOut.ippSeconds * self.dataOut.nCohInt
166 # self.dataOut.timeInterval = self.dataOut.ippSeconds * self.dataOut.nCohInt
167
167
168 self.dataOut.frequency = self.__frequency
168 self.dataOut.frequency = self.__frequency
169
169
170 self.dataOut.realtime = self.__online
170 self.dataOut.realtime = self.__online
171
171
172 def findDatafiles(self, path, startDate=None, endDate=None):
172 def findDatafiles(self, path, startDate=None, endDate=None):
173
173
174 if not os.path.isdir(path):
174 if not os.path.isdir(path):
175 return []
175 return []
176
176
177 try:
177 try:
178 digitalReadObj = digital_rf.DigitalRFReader(
178 digitalReadObj = digital_rf.DigitalRFReader(
179 path, load_all_metadata=True)
179 path, load_all_metadata=True)
180 except:
180 except:
181 digitalReadObj = digital_rf.DigitalRFReader(path)
181 digitalReadObj = digital_rf.DigitalRFReader(path)
182
182
183 channelNameList = digitalReadObj.get_channels()
183 channelNameList = digitalReadObj.get_channels()
184
184
185 if not channelNameList:
185 if not channelNameList:
186 return []
186 return []
187
187
188 metadata_dict = digitalReadObj.get_rf_file_metadata(channelNameList[0])
188 metadata_dict = digitalReadObj.get_rf_file_metadata(channelNameList[0])
189
189
190 sample_rate = metadata_dict['sample_rate'][0]
190 sample_rate = metadata_dict['sample_rate'][0]
191
191
192 this_metadata_file = digitalReadObj.get_metadata(channelNameList[0])
192 this_metadata_file = digitalReadObj.get_metadata(channelNameList[0])
193
193
194 try:
194 try:
195 timezone = this_metadata_file['timezone'].value
195 timezone = this_metadata_file['timezone'].value
196 except:
196 except:
197 timezone = 0
197 timezone = 0
198
198
199 startUTCSecond, endUTCSecond = digitalReadObj.get_bounds(
199 startUTCSecond, endUTCSecond = digitalReadObj.get_bounds(
200 channelNameList[0]) / sample_rate - timezone
200 channelNameList[0]) / sample_rate - timezone
201
201
202 startDatetime = datetime.datetime.utcfromtimestamp(startUTCSecond)
202 startDatetime = datetime.datetime.utcfromtimestamp(startUTCSecond)
203 endDatatime = datetime.datetime.utcfromtimestamp(endUTCSecond)
203 endDatatime = datetime.datetime.utcfromtimestamp(endUTCSecond)
204
204
205 if not startDate:
205 if not startDate:
206 startDate = startDatetime.date()
206 startDate = startDatetime.date()
207
207
208 if not endDate:
208 if not endDate:
209 endDate = endDatatime.date()
209 endDate = endDatatime.date()
210
210
211 dateList = []
211 dateList = []
212
212
213 thisDatetime = startDatetime
213 thisDatetime = startDatetime
214
214
215 while(thisDatetime <= endDatatime):
215 while(thisDatetime <= endDatatime):
216
216
217 thisDate = thisDatetime.date()
217 thisDate = thisDatetime.date()
218
218
219 if thisDate < startDate:
219 if thisDate < startDate:
220 continue
220 continue
221
221
222 if thisDate > endDate:
222 if thisDate > endDate:
223 break
223 break
224
224
225 dateList.append(thisDate)
225 dateList.append(thisDate)
226 thisDatetime += datetime.timedelta(1)
226 thisDatetime += datetime.timedelta(1)
227
227
228 return dateList
228 return dateList
229
229
230 def setup(self, path=None,
230 def setup(self, path=None,
231 startDate=None,
231 startDate=None,
232 endDate=None,
232 endDate=None,
233 startTime=datetime.time(0, 0, 0),
233 startTime=datetime.time(0, 0, 0),
234 endTime=datetime.time(23, 59, 59),
234 endTime=datetime.time(23, 59, 59),
235 channelList=None,
235 channelList=None,
236 nSamples=None,
236 nSamples=None,
237 online=False,
237 online=False,
238 delay=60,
238 delay=60,
239 buffer_size=1024,
239 buffer_size=1024,
240 ippKm=None,
240 ippKm=None,
241 nCohInt=1,
241 nCohInt=1,
242 nCode=1,
242 nCode=1,
243 nBaud=1,
243 nBaud=1,
244 flagDecodeData=False,
244 flagDecodeData=False,
245 code=numpy.ones((1, 1), dtype=int),
245 code=numpy.ones((1, 1), dtype=int),
246 getByBlock=0,
246 getByBlock=0,
247 nProfileBlocks=1,
247 nProfileBlocks=1,
248 **kwargs):
248 **kwargs):
249 '''
249 '''
250 In this method we should set all initial parameters.
250 In this method we should set all initial parameters.
251
251
252 Inputs:
252 Inputs:
253 path
253 path
254 startDate
254 startDate
255 endDate
255 endDate
256 startTime
256 startTime
257 endTime
257 endTime
258 set
258 set
259 expLabel
259 expLabel
260 ext
260 ext
261 online
261 online
262 delay
262 delay
263 '''
263 '''
264 self.path = path
264 self.path = path
265 self.nCohInt = nCohInt
265 self.nCohInt = nCohInt
266 self.flagDecodeData = flagDecodeData
266 self.flagDecodeData = flagDecodeData
267 self.i = 0
267 self.i = 0
268
268
269 self.getByBlock = getByBlock
269 self.getByBlock = getByBlock
270 self.nProfileBlocks = nProfileBlocks
270 self.nProfileBlocks = nProfileBlocks
271 if online:
271 if online:
272 print('Waiting for RF data..')
272 print('Waiting for RF data..')
273 sleep(40)
273 sleep(40)
274
274
275 if not os.path.isdir(path):
275 if not os.path.isdir(path):
276 raise ValueError("[Reading] Directory %s does not exist" % path)
276 raise ValueError("[Reading] Directory %s does not exist" % path)
277
277
278 #print("path",path)
278 #print("path",path)
279 try:
279 try:
280 self.digitalReadObj = digital_rf.DigitalRFReader(
280 self.digitalReadObj = digital_rf.DigitalRFReader(
281 path, load_all_metadata=True)
281 path, load_all_metadata=True)
282 except:
282 except:
283 self.digitalReadObj = digital_rf.DigitalRFReader(path)
283 self.digitalReadObj = digital_rf.DigitalRFReader(path)
284
284
285 channelNameList = self.digitalReadObj.get_channels()
285 channelNameList = self.digitalReadObj.get_channels()
286
286
287 if not channelNameList:
287 if not channelNameList:
288 raise ValueError("[Reading] Directory %s does not have any files" % path)
288 raise ValueError("[Reading] Directory %s does not have any files" % path)
289
289
290 if not channelList:
290 if not channelList:
291 channelList = list(range(len(channelNameList)))
291 channelList = list(range(len(channelNameList)))
292
292
293 ########## Reading metadata ######################
293 ########## Reading metadata ######################
294
294
295 top_properties = self.digitalReadObj.get_properties(
295 top_properties = self.digitalReadObj.get_properties(
296 channelNameList[channelList[0]])
296 channelNameList[channelList[0]])
297
297
298 self.__num_subchannels = top_properties['num_subchannels']
298 self.__num_subchannels = top_properties['num_subchannels']
299 self.__sample_rate = 1.0 * \
299 self.__sample_rate = 1.0 * \
300 top_properties['sample_rate_numerator'] / \
300 top_properties['sample_rate_numerator'] / \
301 top_properties['sample_rate_denominator']
301 top_properties['sample_rate_denominator']
302 # self.__samples_per_file = top_properties['samples_per_file'][0]
302 # self.__samples_per_file = top_properties['samples_per_file'][0]
303 self.__deltaHeigth = 1e6 * 0.15 / self.__sample_rate # why 0.15?
303 self.__deltaHeigth = 1e6 * 0.15 / self.__sample_rate # why 0.15?
304
304
305 this_metadata_file = self.digitalReadObj.get_digital_metadata(
305 this_metadata_file = self.digitalReadObj.get_digital_metadata(
306 channelNameList[channelList[0]])
306 channelNameList[channelList[0]])
307 metadata_bounds = this_metadata_file.get_bounds()
307 metadata_bounds = this_metadata_file.get_bounds()
308 self.fixed_metadata_dict = this_metadata_file.read(
308 self.fixed_metadata_dict = this_metadata_file.read(
309 metadata_bounds[0])[metadata_bounds[0]] # GET FIRST HEADER
309 metadata_bounds[0])[metadata_bounds[0]] # GET FIRST HEADER
310
310
311 try:
311 try:
312 self.__processingHeader = self.fixed_metadata_dict['processingHeader']
312 self.__processingHeader = self.fixed_metadata_dict['processingHeader']
313 self.__radarControllerHeader = self.fixed_metadata_dict['radarControllerHeader']
313 self.__radarControllerHeader = self.fixed_metadata_dict['radarControllerHeader']
314 self.__systemHeader = self.fixed_metadata_dict['systemHeader']
314 self.__systemHeader = self.fixed_metadata_dict['systemHeader']
315 self.dtype = pickle.loads(self.fixed_metadata_dict['dtype'])
315 self.dtype = pickle.loads(self.fixed_metadata_dict['dtype'])
316 except:
316 except:
317 pass
317 pass
318
318
319 self.__frequency = None
319 self.__frequency = None
320
320
321 self.__frequency = self.fixed_metadata_dict.get('frequency', 1)
321 self.__frequency = self.fixed_metadata_dict.get('frequency', 1)
322
322
323 self.__frequency = 9.345e9
324
323 self.__timezone = self.fixed_metadata_dict.get('timezone', 18000)
325 self.__timezone = self.fixed_metadata_dict.get('timezone', 18000)
324
326
325 try:
327 try:
326 nSamples = self.fixed_metadata_dict['nSamples']
328 nSamples = self.fixed_metadata_dict['nSamples']
327 except:
329 except:
328 nSamples = None
330 nSamples = None
329
331
330 self.__firstHeigth = 0
332 self.__firstHeigth = 0
331
333
332 try:
334 try:
333 codeType = self.__radarControllerHeader['codeType']
335 codeType = self.__radarControllerHeader['codeType']
334 except:
336 except:
335 codeType = 0
337 codeType = 0
336
338
337 try:
339 try:
338 if codeType:
340 if codeType:
339 nCode = self.__radarControllerHeader['nCode']
341 nCode = self.__radarControllerHeader['nCode']
340 nBaud = self.__radarControllerHeader['nBaud']
342 nBaud = self.__radarControllerHeader['nBaud']
341 code = self.__radarControllerHeader['code']
343 code = self.__radarControllerHeader['code']
342 except:
344 except:
343 pass
345 pass
344
346
345 if not ippKm:
347 if not ippKm:
346 try:
348 try:
347 # seconds to km
349 # seconds to km
348 ippKm = self.__radarControllerHeader['ipp']
350 ippKm = self.__radarControllerHeader['ipp']
349 except:
351 except:
350 ippKm = None
352 ippKm = None
351 ####################################################
353 ####################################################
352 self.__ippKm = ippKm
354 self.__ippKm = ippKm
353 startUTCSecond = None
355 startUTCSecond = None
354 endUTCSecond = None
356 endUTCSecond = None
355
357
356 if startDate:
358 if startDate:
357 startDatetime = datetime.datetime.combine(startDate, startTime)
359 startDatetime = datetime.datetime.combine(startDate, startTime)
358 startUTCSecond = (
360 startUTCSecond = (
359 startDatetime - datetime.datetime(1970, 1, 1)).total_seconds()# + self.__timezone
361 startDatetime - datetime.datetime(1970, 1, 1)).total_seconds()# + self.__timezone
360
362
361 if endDate:
363 if endDate:
362 endDatetime = datetime.datetime.combine(endDate, endTime)
364 endDatetime = datetime.datetime.combine(endDate, endTime)
363 endUTCSecond = (endDatetime - datetime.datetime(1970,
365 endUTCSecond = (endDatetime - datetime.datetime(1970,
364 1, 1)).total_seconds()# + self.__timezone
366 1, 1)).total_seconds()# + self.__timezone
365 start_index, end_index = self.digitalReadObj.get_bounds(channelNameList[channelList[0]])
367 start_index, end_index = self.digitalReadObj.get_bounds(channelNameList[channelList[0]])
366 if start_index==None or end_index==None:
368 if start_index==None or end_index==None:
367 print("Check error No data, start_index: ",start_index,",end_index: ",end_index)
369 print("Check error No data, start_index: ",start_index,",end_index: ",end_index)
368 #return 0
370 #return 0
369 if not startUTCSecond:
371 if not startUTCSecond:
370 startUTCSecond = start_index / self.__sample_rate
372 startUTCSecond = start_index / self.__sample_rate
371 if start_index > startUTCSecond * self.__sample_rate:
373 if start_index > startUTCSecond * self.__sample_rate:
372 startUTCSecond = start_index / self.__sample_rate
374 startUTCSecond = start_index / self.__sample_rate
373
375
374 if not endUTCSecond:
376 if not endUTCSecond:
375 endUTCSecond = end_index / self.__sample_rate
377 endUTCSecond = end_index / self.__sample_rate
376
378
377 if end_index < endUTCSecond * self.__sample_rate:
379 if end_index < endUTCSecond * self.__sample_rate:
378 endUTCSecond = end_index / self.__sample_rate #Check UTC and LT time
380 endUTCSecond = end_index / self.__sample_rate #Check UTC and LT time
379
381
380 if not nSamples:
382 if not nSamples:
381 if not ippKm:
383 if not ippKm:
382 raise ValueError("[Reading] nSamples or ippKm should be defined")
384 raise ValueError("[Reading] nSamples or ippKm should be defined")
383 nSamples = int(ippKm / (1e6 * 0.15 / self.__sample_rate))
385 nSamples = int(ippKm / (1e6 * 0.15 / self.__sample_rate))
384
386
385 channelBoundList = []
387 channelBoundList = []
386 channelNameListFiltered = []
388 channelNameListFiltered = []
387
389
388 for thisIndexChannel in channelList:
390 for thisIndexChannel in channelList:
389 thisChannelName = channelNameList[thisIndexChannel]
391 thisChannelName = channelNameList[thisIndexChannel]
390 start_index, end_index = self.digitalReadObj.get_bounds(
392 start_index, end_index = self.digitalReadObj.get_bounds(
391 thisChannelName)
393 thisChannelName)
392 channelBoundList.append((start_index, end_index))
394 channelBoundList.append((start_index, end_index))
393 channelNameListFiltered.append(thisChannelName)
395 channelNameListFiltered.append(thisChannelName)
394
396
395 self.profileIndex = 0
397 self.profileIndex = 0
396 self.i = 0
398 self.i = 0
397 self.__delay = delay
399 self.__delay = delay
398
400
399 self.__codeType = codeType
401 self.__codeType = codeType
400 self.__nCode = nCode
402 self.__nCode = nCode
401 self.__nBaud = nBaud
403 self.__nBaud = nBaud
402 self.__code = code
404 self.__code = code
403
405
404 self.__datapath = path
406 self.__datapath = path
405 self.__online = online
407 self.__online = online
406 self.__channelList = channelList
408 self.__channelList = channelList
407 self.__channelNameList = channelNameListFiltered
409 self.__channelNameList = channelNameListFiltered
408 self.__channelBoundList = channelBoundList
410 self.__channelBoundList = channelBoundList
409 self.__nSamples = nSamples
411 self.__nSamples = nSamples
410 if self.getByBlock:
412 if self.getByBlock:
411 nSamples = nSamples*nProfileBlocks
413 nSamples = nSamples*nProfileBlocks
412
414
413
415
414 self.__samples_to_read = int(nSamples) # FIJO: AHORA 40
416 self.__samples_to_read = int(nSamples) # FIJO: AHORA 40
415 self.__nChannels = len(self.__channelList)
417 self.__nChannels = len(self.__channelList)
416 #print("------------------------------------------")
418 #print("------------------------------------------")
417 #print("self.__samples_to_read",self.__samples_to_read)
419 #print("self.__samples_to_read",self.__samples_to_read)
418 #print("self.__nSamples",self.__nSamples)
420 #print("self.__nSamples",self.__nSamples)
419 # son iguales y el buffer_index da 0
421 # son iguales y el buffer_index da 0
420 self.__startUTCSecond = startUTCSecond
422 self.__startUTCSecond = startUTCSecond
421 self.__endUTCSecond = endUTCSecond
423 self.__endUTCSecond = endUTCSecond
422
424
423 self.__timeInterval = 1.0 * self.__samples_to_read / \
425 self.__timeInterval = 1.0 * self.__samples_to_read / \
424 self.__sample_rate # Time interval
426 self.__sample_rate # Time interval
425
427
426 if online:
428 if online:
427 # self.__thisUnixSample = int(endUTCSecond*self.__sample_rate - 4*self.__samples_to_read)
429 # self.__thisUnixSample = int(endUTCSecond*self.__sample_rate - 4*self.__samples_to_read)
428 startUTCSecond = numpy.floor(endUTCSecond)
430 startUTCSecond = numpy.floor(endUTCSecond)
429
431
430 # por que en el otro metodo lo primero q se hace es sumar samplestoread
432 # por que en el otro metodo lo primero q se hace es sumar samplestoread
431 self.__thisUnixSample = int(startUTCSecond * self.__sample_rate) - self.__samples_to_read
433 self.__thisUnixSample = int(startUTCSecond * self.__sample_rate) - self.__samples_to_read
432
434
433 #self.__data_buffer = numpy.zeros(
435 #self.__data_buffer = numpy.zeros(
434 # (self.__num_subchannels, self.__samples_to_read), dtype=numpy.complex)
436 # (self.__num_subchannels, self.__samples_to_read), dtype=numpy.complex)
435 print("samplestoread",self.__samples_to_read)
437 print("samplestoread",self.__samples_to_read)
436 self.__data_buffer = numpy.zeros((int(len(channelList)), self.__samples_to_read), dtype=numpy.complex_)
438 self.__data_buffer = numpy.zeros((int(len(channelList)), self.__samples_to_read), dtype=numpy.complex_)
437
439
438
440
439 self.__setFileHeader()
441 self.__setFileHeader()
440 self.isConfig = True
442 self.isConfig = True
441
443
442 print("[Reading] Digital RF Data was found from %s to %s " % (
444 print("[Reading] Digital RF Data was found from %s to %s " % (
443 datetime.datetime.utcfromtimestamp(
445 datetime.datetime.utcfromtimestamp(
444 self.__startUTCSecond - self.__timezone),
446 self.__startUTCSecond - self.__timezone),
445 datetime.datetime.utcfromtimestamp(
447 datetime.datetime.utcfromtimestamp(
446 self.__endUTCSecond - self.__timezone)
448 self.__endUTCSecond - self.__timezone)
447 ))
449 ))
448
450
449 print("[Reading] Starting process from %s to %s" % (datetime.datetime.utcfromtimestamp(startUTCSecond - self.__timezone),
451 print("[Reading] Starting process from %s to %s" % (datetime.datetime.utcfromtimestamp(startUTCSecond - self.__timezone),
450 datetime.datetime.utcfromtimestamp(endUTCSecond - self.__timezone)))
452 datetime.datetime.utcfromtimestamp(endUTCSecond - self.__timezone)))
451 self.oldAverage = None
453 self.oldAverage = None
452 self.count = 0
454 self.count = 0
453 self.executionTime = 0
455 self.executionTime = 0
454
456
455 def __reload(self):
457 def __reload(self):
456 # print
458 # print
457 # print "%s not in range [%s, %s]" %(
459 # print "%s not in range [%s, %s]" %(
458 # datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
460 # datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
459 # datetime.datetime.utcfromtimestamp(self.__startUTCSecond - self.__timezone),
461 # datetime.datetime.utcfromtimestamp(self.__startUTCSecond - self.__timezone),
460 # datetime.datetime.utcfromtimestamp(self.__endUTCSecond - self.__timezone)
462 # datetime.datetime.utcfromtimestamp(self.__endUTCSecond - self.__timezone)
461 # )
463 # )
462 print("[Reading] reloading metadata ...")
464 print("[Reading] reloading metadata ...")
463
465
464 try:
466 try:
465 self.digitalReadObj.reload(complete_update=True)
467 self.digitalReadObj.reload(complete_update=True)
466 except:
468 except:
467 self.digitalReadObj = digital_rf.DigitalRFReader(self.path)
469 self.digitalReadObj = digital_rf.DigitalRFReader(self.path)
468
470
469 start_index, end_index = self.digitalReadObj.get_bounds(
471 start_index, end_index = self.digitalReadObj.get_bounds(
470 self.__channelNameList[self.__channelList[0]])
472 self.__channelNameList[self.__channelList[0]])
471
473
472 if start_index > self.__startUTCSecond * self.__sample_rate:
474 if start_index > self.__startUTCSecond * self.__sample_rate:
473 self.__startUTCSecond = 1.0 * start_index / self.__sample_rate
475 self.__startUTCSecond = 1.0 * start_index / self.__sample_rate
474
476
475 if end_index > self.__endUTCSecond * self.__sample_rate:
477 if end_index > self.__endUTCSecond * self.__sample_rate:
476 self.__endUTCSecond = 1.0 * end_index / self.__sample_rate
478 self.__endUTCSecond = 1.0 * end_index / self.__sample_rate
477 print()
479 print()
478 print("[Reading] New timerange found [%s, %s] " % (
480 print("[Reading] New timerange found [%s, %s] " % (
479 datetime.datetime.utcfromtimestamp(
481 datetime.datetime.utcfromtimestamp(
480 self.__startUTCSecond - self.__timezone),
482 self.__startUTCSecond - self.__timezone),
481 datetime.datetime.utcfromtimestamp(
483 datetime.datetime.utcfromtimestamp(
482 self.__endUTCSecond - self.__timezone)
484 self.__endUTCSecond - self.__timezone)
483 ))
485 ))
484
486
485 return True
487 return True
486
488
487 return False
489 return False
488
490
489 def timeit(self, toExecute):
491 def timeit(self, toExecute):
490 t0 = time.time()
492 t0 = time.time()
491 toExecute()
493 toExecute()
492 self.executionTime = time.time() - t0
494 self.executionTime = time.time() - t0
493 if self.oldAverage is None:
495 if self.oldAverage is None:
494 self.oldAverage = self.executionTime
496 self.oldAverage = self.executionTime
495 self.oldAverage = (self.executionTime + self.count *
497 self.oldAverage = (self.executionTime + self.count *
496 self.oldAverage) / (self.count + 1.0)
498 self.oldAverage) / (self.count + 1.0)
497 self.count = self.count + 1.0
499 self.count = self.count + 1.0
498 return
500 return
499
501
500 def __readNextBlock(self, seconds=30, volt_scale=1/20000.0):
502 def __readNextBlock(self, seconds=30, volt_scale=1/20000.0):
501 '''
503 '''
502 NOTA: APLICACION RADAR METEOROLOGICO
504 NOTA: APLICACION RADAR METEOROLOGICO
503 VALORES OBTENIDOS CON LA USRP, volt_scale = 1,conexion directa al Ch Rx.
505 VALORES OBTENIDOS CON LA USRP, volt_scale = 1,conexion directa al Ch Rx.
504
506
505 MAXIMO
507 MAXIMO
506 9886 -> 0.980 Voltiospp
508 9886 -> 0.980 Voltiospp
507 4939 -> 0.480 Voltiospp
509 4939 -> 0.480 Voltiospp
508 14825 -> 1.440 Voltiospp
510 14825 -> 1.440 Voltiospp
509 18129 -> 1.940 Voltiospp
511 18129 -> 1.940 Voltiospp
510 Para llevar al valor correspondiente de Voltaje, debemos dividir por 20000
512 Para llevar al valor correspondiente de Voltaje, debemos dividir por 20000
511 y obtenemos la Amplitud correspondiente de entrada IQ.
513 y obtenemos la Amplitud correspondiente de entrada IQ.
512 volt_scale = (1/20000.0)
514 volt_scale = (1/20000.0)
513 '''
515 '''
514 # Set the next data
516 # Set the next data
515 self.__flagDiscontinuousBlock = False
517 self.__flagDiscontinuousBlock = False
516 self.__thisUnixSample += self.__samples_to_read
518 self.__thisUnixSample += self.__samples_to_read
517
519
518 if self.__thisUnixSample + 2 * self.__samples_to_read > self.__endUTCSecond * self.__sample_rate:
520 if self.__thisUnixSample + 2 * self.__samples_to_read > self.__endUTCSecond * self.__sample_rate:
519 print ("[Reading] There are no more data into selected time-range")
521 print ("[Reading] There are no more data into selected time-range")
520 if self.__online:
522 if self.__online:
521 sleep(3)
523 sleep(3)
522 self.__reload()
524 self.__reload()
523 else:
525 else:
524 return False
526 return False
525
527
526 if self.__thisUnixSample + 2 * self.__samples_to_read > self.__endUTCSecond * self.__sample_rate:
528 if self.__thisUnixSample + 2 * self.__samples_to_read > self.__endUTCSecond * self.__sample_rate:
527 return False
529 return False
528 self.__thisUnixSample -= self.__samples_to_read
530 self.__thisUnixSample -= self.__samples_to_read
529
531
530 indexChannel = 0
532 indexChannel = 0
531
533
532 dataOk = False
534 dataOk = False
533
535
534 for thisChannelName in self.__channelNameList: # TODO VARIOS CHANNELS?
536 for thisChannelName in self.__channelNameList: # TODO VARIOS CHANNELS?
535 for indexSubchannel in range(self.__num_subchannels):
537 for indexSubchannel in range(self.__num_subchannels):
536 try:
538 try:
537 t0 = time()
539 t0 = time()
538 #print("thisUNixSample",self.__thisUnixSample)
540 #print("thisUNixSample",self.__thisUnixSample)
539 result = self.digitalReadObj.read_vector_c81d(self.__thisUnixSample,
541 result = self.digitalReadObj.read_vector_c81d(self.__thisUnixSample,
540 self.__samples_to_read,
542 self.__samples_to_read,
541 thisChannelName, sub_channel=indexSubchannel)
543 thisChannelName, sub_channel=indexSubchannel)
542 #print("result--------------",result)
544 #print("result--------------",result)
543 self.executionTime = time() - t0
545 self.executionTime = time() - t0
544 if self.oldAverage is None:
546 if self.oldAverage is None:
545 self.oldAverage = self.executionTime
547 self.oldAverage = self.executionTime
546 self.oldAverage = (
548 self.oldAverage = (
547 self.executionTime + self.count * self.oldAverage) / (self.count + 1.0)
549 self.executionTime + self.count * self.oldAverage) / (self.count + 1.0)
548 self.count = self.count + 1.0
550 self.count = self.count + 1.0
549
551
550 except IOError as e:
552 except IOError as e:
551 # read next profile
553 # read next profile
552 self.__flagDiscontinuousBlock = True
554 self.__flagDiscontinuousBlock = True
553 print("[Reading] %s" % datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone), e)
555 print("[Reading] %s" % datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone), e)
554 bot = 0
556 bot = 0
555 while(self.__flagDiscontinuousBlock):
557 while(self.__flagDiscontinuousBlock):
556 bot +=1
558 bot +=1
557 self.__thisUnixSample += self.__samples_to_read
559 self.__thisUnixSample += self.__samples_to_read
558 try:
560 try:
559 result = result = self.digitalReadObj.read_vector_c81d(self.__thisUnixSample,self.__samples_to_read,thisChannelName, sub_channel=indexSubchannel)
561 result = result = self.digitalReadObj.read_vector_c81d(self.__thisUnixSample,self.__samples_to_read,thisChannelName, sub_channel=indexSubchannel)
560 self.__flagDiscontinuousBlock=False
562 self.__flagDiscontinuousBlock=False
561 print("Searching.. N°: ",bot,"Success",self.__thisUnixSample)
563 print("Searching.. N°: ",bot,"Success",self.__thisUnixSample)
562 except:
564 except:
563 print("Searching...N°: ",bot,"Fail", self.__thisUnixSample)
565 print("Searching...N°: ",bot,"Fail", self.__thisUnixSample)
564 if self.__flagDiscontinuousBlock==True:
566 if self.__flagDiscontinuousBlock==True:
565 break
567 break
566 else:
568 else:
567 print("New data index found...",self.__thisUnixSample)
569 print("New data index found...",self.__thisUnixSample)
568 #break
570 #break
569
571
570 if result.shape[0] != self.__samples_to_read:
572 if result.shape[0] != self.__samples_to_read:
571 self.__flagDiscontinuousBlock = True
573 self.__flagDiscontinuousBlock = True
572 print("[Reading] %s: Too few samples were found, just %d/%d samples" % (datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
574 print("[Reading] %s: Too few samples were found, just %d/%d samples" % (datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
573 result.shape[0],
575 result.shape[0],
574 self.__samples_to_read))
576 self.__samples_to_read))
575 break
577 break
576
578
577 self.__data_buffer[indexChannel, :] = result * volt_scale
579 self.__data_buffer[indexChannel, :] = result * volt_scale
578 indexChannel+=1
580 indexChannel+=1
579
581
580 dataOk = True
582 dataOk = True
581
583
582 self.__utctime = self.__thisUnixSample / self.__sample_rate
584 self.__utctime = self.__thisUnixSample / self.__sample_rate
583
585
584 if not dataOk:
586 if not dataOk:
585 return False
587 return False
586
588
587 print("[Reading] %s: %d samples <> %f sec" % (datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
589 print("[Reading] %s: %d samples <> %f sec" % (datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
588 self.__samples_to_read,
590 self.__samples_to_read,
589 self.__timeInterval))
591 self.__timeInterval))
590
592
591 self.__bufferIndex = 0
593 self.__bufferIndex = 0
592
594
593 return True
595 return True
594
596
595 def __isBufferEmpty(self):
597 def __isBufferEmpty(self):
596
598
597 return self.__bufferIndex > self.__samples_to_read - self.__nSamples # 40960 - 40
599 return self.__bufferIndex > self.__samples_to_read - self.__nSamples # 40960 - 40
598
600
599 def getData(self, seconds=30, nTries=5):
601 def getData(self, seconds=30, nTries=5):
600 '''
602 '''
601 This method gets the data from files and put the data into the dataOut object
603 This method gets the data from files and put the data into the dataOut object
602
604
603 In addition, increase el the buffer counter in one.
605 In addition, increase el the buffer counter in one.
604
606
605 Return:
607 Return:
606 data : retorna un perfil de voltages (alturas * canales) copiados desde el
608 data : retorna un perfil de voltages (alturas * canales) copiados desde el
607 buffer. Si no hay mas archivos a leer retorna None.
609 buffer. Si no hay mas archivos a leer retorna None.
608
610
609 Affected:
611 Affected:
610 self.dataOut
612 self.dataOut
611 self.profileIndex
613 self.profileIndex
612 self.flagDiscontinuousBlock
614 self.flagDiscontinuousBlock
613 self.flagIsNewBlock
615 self.flagIsNewBlock
614 '''
616 '''
615 #print("getdata")
617 #print("getdata")
616 err_counter = 0
618 err_counter = 0
617 self.dataOut.flagNoData = True
619 self.dataOut.flagNoData = True
618
620
619
621
620 if self.__isBufferEmpty():
622 if self.__isBufferEmpty():
621 #print("hi")
623 #print("hi")
622 self.__flagDiscontinuousBlock = False
624 self.__flagDiscontinuousBlock = False
623
625
624 while True:
626 while True:
625 if self.__readNextBlock():
627 if self.__readNextBlock():
626 break
628 break
627 if self.__thisUnixSample > self.__endUTCSecond * self.__sample_rate:
629 if self.__thisUnixSample > self.__endUTCSecond * self.__sample_rate:
628 raise schainpy.admin.SchainError('Error')
630 raise schainpy.admin.SchainError('Error')
629 return
631 return
630
632
631 if self.__flagDiscontinuousBlock:
633 if self.__flagDiscontinuousBlock:
632 raise schainpy.admin.SchainError('discontinuous block found')
634 raise schainpy.admin.SchainError('discontinuous block found')
633 return
635 return
634
636
635 if not self.__online:
637 if not self.__online:
636 raise schainpy.admin.SchainError('Online?')
638 raise schainpy.admin.SchainError('Online?')
637 return
639 return
638
640
639 err_counter += 1
641 err_counter += 1
640 if err_counter > nTries:
642 if err_counter > nTries:
641 raise schainpy.admin.SchainError('Max retrys reach')
643 raise schainpy.admin.SchainError('Max retrys reach')
642 return
644 return
643
645
644 print('[Reading] waiting %d seconds to read a new block' % seconds)
646 print('[Reading] waiting %d seconds to read a new block' % seconds)
645 sleep(seconds)
647 sleep(seconds)
646
648
647
649
648 if not self.getByBlock:
650 if not self.getByBlock:
649
651
650 #print("self.__bufferIndex",self.__bufferIndex)# este valor siempre es cero aparentemente
652 #print("self.__bufferIndex",self.__bufferIndex)# este valor siempre es cero aparentemente
651 self.dataOut.data = self.__data_buffer[:, self.__bufferIndex:self.__bufferIndex + self.__nSamples]
653 self.dataOut.data = self.__data_buffer[:, self.__bufferIndex:self.__bufferIndex + self.__nSamples]
652 self.dataOut.utctime = ( self.__thisUnixSample + self.__bufferIndex) / self.__sample_rate
654 self.dataOut.utctime = ( self.__thisUnixSample + self.__bufferIndex) / self.__sample_rate
653 self.dataOut.flagNoData = False
655 self.dataOut.flagNoData = False
654 self.dataOut.flagDiscontinuousBlock = self.__flagDiscontinuousBlock
656 self.dataOut.flagDiscontinuousBlock = self.__flagDiscontinuousBlock
655 self.dataOut.profileIndex = self.profileIndex
657 self.dataOut.profileIndex = self.profileIndex
656
658
657 self.__bufferIndex += self.__nSamples
659 self.__bufferIndex += self.__nSamples
658 self.profileIndex += 1
660 self.profileIndex += 1
659
661
660 if self.profileIndex == self.dataOut.nProfiles:
662 if self.profileIndex == self.dataOut.nProfiles:
661 self.profileIndex = 0
663 self.profileIndex = 0
662 else:
664 else:
663 # ojo debo anadir el readNextBLock y el __isBufferEmpty(
665 # ojo debo anadir el readNextBLock y el __isBufferEmpty(
664 self.dataOut.flagNoData = False
666 self.dataOut.flagNoData = False
665 buffer = self.__data_buffer[:,self.__bufferIndex:self.__bufferIndex + self.__samples_to_read]
667 buffer = self.__data_buffer[:,self.__bufferIndex:self.__bufferIndex + self.__samples_to_read]
666 buffer = buffer.reshape((self.__nChannels, self.nProfileBlocks, int(self.__samples_to_read/self.nProfileBlocks)))
668 buffer = buffer.reshape((self.__nChannels, self.nProfileBlocks, int(self.__samples_to_read/self.nProfileBlocks)))
667 self.dataOut.nProfileBlocks = self.nProfileBlocks
669 self.dataOut.nProfileBlocks = self.nProfileBlocks
668 self.dataOut.data = buffer
670 self.dataOut.data = buffer
669 self.dataOut.utctime = ( self.__thisUnixSample + self.__bufferIndex) / self.__sample_rate
671 self.dataOut.utctime = ( self.__thisUnixSample + self.__bufferIndex) / self.__sample_rate
670 self.profileIndex += self.__samples_to_read
672 self.profileIndex += self.__samples_to_read
671 self.__bufferIndex += self.__samples_to_read
673 self.__bufferIndex += self.__samples_to_read
672 self.dataOut.flagDiscontinuousBlock = self.__flagDiscontinuousBlock
674 self.dataOut.flagDiscontinuousBlock = self.__flagDiscontinuousBlock
673 return True
675 return True
674
676
675
677
676 def printInfo(self):
678 def printInfo(self):
677 '''
679 '''
678 '''
680 '''
679 if self.__printInfo == False:
681 if self.__printInfo == False:
680 return
682 return
681
683
682 # self.systemHeaderObj.printInfo()
684 # self.systemHeaderObj.printInfo()
683 # self.radarControllerHeaderObj.printInfo()
685 # self.radarControllerHeaderObj.printInfo()
684
686
685 self.__printInfo = False
687 self.__printInfo = False
686
688
687 def printNumberOfBlock(self):
689 def printNumberOfBlock(self):
688 '''
690 '''
689 '''
691 '''
690 return
692 return
691 # print self.profileIndex
693 # print self.profileIndex
692
694
693 def run(self, **kwargs):
695 def run(self, **kwargs):
694 '''
696 '''
695 This method will be called many times so here you should put all your code
697 This method will be called many times so here you should put all your code
696 '''
698 '''
697
699
698 if not self.isConfig:
700 if not self.isConfig:
699 self.setup(**kwargs)
701 self.setup(**kwargs)
700
702
701 self.getData(seconds=self.__delay)
703 self.getData(seconds=self.__delay)
702
704
703 return
705 return
704
706
705 @MPDecorator
707 @MPDecorator
706 class DigitalRFWriter(Operation):
708 class DigitalRFWriter(Operation):
707 '''
709 '''
708 classdocs
710 classdocs
709 '''
711 '''
710
712
711 def __init__(self, **kwargs):
713 def __init__(self, **kwargs):
712 '''
714 '''
713 Constructor
715 Constructor
714 '''
716 '''
715 Operation.__init__(self, **kwargs)
717 Operation.__init__(self, **kwargs)
716 self.metadata_dict = {}
718 self.metadata_dict = {}
717 self.dataOut = None
719 self.dataOut = None
718 self.dtype = None
720 self.dtype = None
719 self.oldAverage = 0
721 self.oldAverage = 0
720
722
721 def setHeader(self):
723 def setHeader(self):
722
724
723 self.metadata_dict['frequency'] = self.dataOut.frequency
725 self.metadata_dict['frequency'] = self.dataOut.frequency
724 self.metadata_dict['timezone'] = self.dataOut.timeZone
726 self.metadata_dict['timezone'] = self.dataOut.timeZone
725 self.metadata_dict['dtype'] = pickle.dumps(self.dataOut.dtype)
727 self.metadata_dict['dtype'] = pickle.dumps(self.dataOut.dtype)
726 self.metadata_dict['nProfiles'] = self.dataOut.nProfiles
728 self.metadata_dict['nProfiles'] = self.dataOut.nProfiles
727 self.metadata_dict['heightList'] = self.dataOut.heightList
729 self.metadata_dict['heightList'] = self.dataOut.heightList
728 self.metadata_dict['channelList'] = self.dataOut.channelList
730 self.metadata_dict['channelList'] = self.dataOut.channelList
729 self.metadata_dict['flagDecodeData'] = self.dataOut.flagDecodeData
731 self.metadata_dict['flagDecodeData'] = self.dataOut.flagDecodeData
730 self.metadata_dict['flagDeflipData'] = self.dataOut.flagDeflipData
732 self.metadata_dict['flagDeflipData'] = self.dataOut.flagDeflipData
731 self.metadata_dict['flagShiftFFT'] = self.dataOut.flagShiftFFT
733 self.metadata_dict['flagShiftFFT'] = self.dataOut.flagShiftFFT
732 self.metadata_dict['useLocalTime'] = self.dataOut.useLocalTime
734 self.metadata_dict['useLocalTime'] = self.dataOut.useLocalTime
733 self.metadata_dict['nCohInt'] = self.dataOut.nCohInt
735 self.metadata_dict['nCohInt'] = self.dataOut.nCohInt
734 self.metadata_dict['type'] = self.dataOut.type
736 self.metadata_dict['type'] = self.dataOut.type
735 self.metadata_dict['flagDataAsBlock']= getattr(
737 self.metadata_dict['flagDataAsBlock']= getattr(
736 self.dataOut, 'flagDataAsBlock', None) # chequear
738 self.dataOut, 'flagDataAsBlock', None) # chequear
737
739
738 def setup(self, dataOut, path, frequency, fileCadence, dirCadence, metadataCadence, set=0, metadataFile='metadata', ext='.h5'):
740 def setup(self, dataOut, path, frequency, fileCadence, dirCadence, metadataCadence, set=0, metadataFile='metadata', ext='.h5'):
739 '''
741 '''
740 In this method we should set all initial parameters.
742 In this method we should set all initial parameters.
741 Input:
743 Input:
742 dataOut: Input data will also be outputa data
744 dataOut: Input data will also be outputa data
743 '''
745 '''
744 self.setHeader()
746 self.setHeader()
745 self.__ippSeconds = dataOut.ippSeconds
747 self.__ippSeconds = dataOut.ippSeconds
746 self.__deltaH = dataOut.getDeltaH()
748 self.__deltaH = dataOut.getDeltaH()
747 self.__sample_rate = 1e6 * 0.15 / self.__deltaH
749 self.__sample_rate = 1e6 * 0.15 / self.__deltaH
748 self.__dtype = dataOut.dtype
750 self.__dtype = dataOut.dtype
749 if len(dataOut.dtype) == 2:
751 if len(dataOut.dtype) == 2:
750 self.__dtype = dataOut.dtype[0]
752 self.__dtype = dataOut.dtype[0]
751 self.__nSamples = dataOut.systemHeaderObj.nSamples
753 self.__nSamples = dataOut.systemHeaderObj.nSamples
752 self.__nProfiles = dataOut.nProfiles
754 self.__nProfiles = dataOut.nProfiles
753
755
754 if self.dataOut.type != 'Voltage':
756 if self.dataOut.type != 'Voltage':
755 raise 'Digital RF cannot be used with this data type'
757 raise 'Digital RF cannot be used with this data type'
756 self.arr_data = numpy.ones((1, dataOut.nFFTPoints * len(
758 self.arr_data = numpy.ones((1, dataOut.nFFTPoints * len(
757 self.dataOut.channelList)), dtype=[('r', self.__dtype), ('i', self.__dtype)])
759 self.dataOut.channelList)), dtype=[('r', self.__dtype), ('i', self.__dtype)])
758 else:
760 else:
759 self.arr_data = numpy.ones((self.__nSamples, len(
761 self.arr_data = numpy.ones((self.__nSamples, len(
760 self.dataOut.channelList)), dtype=[('r', self.__dtype), ('i', self.__dtype)])
762 self.dataOut.channelList)), dtype=[('r', self.__dtype), ('i', self.__dtype)])
761
763
762 file_cadence_millisecs = 1000
764 file_cadence_millisecs = 1000
763
765
764 sample_rate_fraction = Fraction(self.__sample_rate).limit_denominator()
766 sample_rate_fraction = Fraction(self.__sample_rate).limit_denominator()
765 sample_rate_numerator = int(sample_rate_fraction.numerator)
767 sample_rate_numerator = int(sample_rate_fraction.numerator)
766 sample_rate_denominator = int(sample_rate_fraction.denominator)
768 sample_rate_denominator = int(sample_rate_fraction.denominator)
767 start_global_index = dataOut.utctime * self.__sample_rate
769 start_global_index = dataOut.utctime * self.__sample_rate
768
770
769 uuid = 'prueba'
771 uuid = 'prueba'
770 compression_level = 0
772 compression_level = 0
771 checksum = False
773 checksum = False
772 is_complex = True
774 is_complex = True
773 num_subchannels = len(dataOut.channelList)
775 num_subchannels = len(dataOut.channelList)
774 is_continuous = True
776 is_continuous = True
775 marching_periods = False
777 marching_periods = False
776
778
777 self.digitalWriteObj = digital_rf.DigitalRFWriter(path, self.__dtype, dirCadence,
779 self.digitalWriteObj = digital_rf.DigitalRFWriter(path, self.__dtype, dirCadence,
778 fileCadence, start_global_index,
780 fileCadence, start_global_index,
779 sample_rate_numerator, sample_rate_denominator, uuid, compression_level, checksum,
781 sample_rate_numerator, sample_rate_denominator, uuid, compression_level, checksum,
780 is_complex, num_subchannels, is_continuous, marching_periods)
782 is_complex, num_subchannels, is_continuous, marching_periods)
781 metadata_dir = os.path.join(path, 'metadata')
783 metadata_dir = os.path.join(path, 'metadata')
782 os.system('mkdir %s' % (metadata_dir))
784 os.system('mkdir %s' % (metadata_dir))
783 self.digitalMetadataWriteObj = digital_rf.DigitalMetadataWriter(metadata_dir, dirCadence, 1, # 236, file_cadence_millisecs / 1000
785 self.digitalMetadataWriteObj = digital_rf.DigitalMetadataWriter(metadata_dir, dirCadence, 1, # 236, file_cadence_millisecs / 1000
784 sample_rate_numerator, sample_rate_denominator,
786 sample_rate_numerator, sample_rate_denominator,
785 metadataFile)
787 metadataFile)
786 self.isConfig = True
788 self.isConfig = True
787 self.currentSample = 0
789 self.currentSample = 0
788 self.oldAverage = 0
790 self.oldAverage = 0
789 self.count = 0
791 self.count = 0
790 return
792 return
791
793
792 def writeMetadata(self):
794 def writeMetadata(self):
793 start_idx = self.__sample_rate * self.dataOut.utctime
795 start_idx = self.__sample_rate * self.dataOut.utctime
794
796
795 self.metadata_dict['processingHeader'] = self.dataOut.processingHeaderObj.getAsDict(
797 self.metadata_dict['processingHeader'] = self.dataOut.processingHeaderObj.getAsDict(
796 )
798 )
797 self.metadata_dict['radarControllerHeader'] = self.dataOut.radarControllerHeaderObj.getAsDict(
799 self.metadata_dict['radarControllerHeader'] = self.dataOut.radarControllerHeaderObj.getAsDict(
798 )
800 )
799 self.metadata_dict['systemHeader'] = self.dataOut.systemHeaderObj.getAsDict(
801 self.metadata_dict['systemHeader'] = self.dataOut.systemHeaderObj.getAsDict(
800 )
802 )
801 self.digitalMetadataWriteObj.write(start_idx, self.metadata_dict)
803 self.digitalMetadataWriteObj.write(start_idx, self.metadata_dict)
802 return
804 return
803
805
804 def timeit(self, toExecute):
806 def timeit(self, toExecute):
805 t0 = time()
807 t0 = time()
806 toExecute()
808 toExecute()
807 self.executionTime = time() - t0
809 self.executionTime = time() - t0
808 if self.oldAverage is None:
810 if self.oldAverage is None:
809 self.oldAverage = self.executionTime
811 self.oldAverage = self.executionTime
810 self.oldAverage = (self.executionTime + self.count *
812 self.oldAverage = (self.executionTime + self.count *
811 self.oldAverage) / (self.count + 1.0)
813 self.oldAverage) / (self.count + 1.0)
812 self.count = self.count + 1.0
814 self.count = self.count + 1.0
813 return
815 return
814
816
815 def writeData(self):
817 def writeData(self):
816 if self.dataOut.type != 'Voltage':
818 if self.dataOut.type != 'Voltage':
817 raise 'Digital RF cannot be used with this data type'
819 raise 'Digital RF cannot be used with this data type'
818 for channel in self.dataOut.channelList:
820 for channel in self.dataOut.channelList:
819 for i in range(self.dataOut.nFFTPoints):
821 for i in range(self.dataOut.nFFTPoints):
820 self.arr_data[1][channel * self.dataOut.nFFTPoints +
822 self.arr_data[1][channel * self.dataOut.nFFTPoints +
821 i]['r'] = self.dataOut.data[channel][i].real
823 i]['r'] = self.dataOut.data[channel][i].real
822 self.arr_data[1][channel * self.dataOut.nFFTPoints +
824 self.arr_data[1][channel * self.dataOut.nFFTPoints +
823 i]['i'] = self.dataOut.data[channel][i].imag
825 i]['i'] = self.dataOut.data[channel][i].imag
824 else:
826 else:
825 for i in range(self.dataOut.systemHeaderObj.nSamples):
827 for i in range(self.dataOut.systemHeaderObj.nSamples):
826 for channel in self.dataOut.channelList:
828 for channel in self.dataOut.channelList:
827 self.arr_data[i][channel]['r'] = self.dataOut.data[channel][i].real
829 self.arr_data[i][channel]['r'] = self.dataOut.data[channel][i].real
828 self.arr_data[i][channel]['i'] = self.dataOut.data[channel][i].imag
830 self.arr_data[i][channel]['i'] = self.dataOut.data[channel][i].imag
829
831
830 def f(): return self.digitalWriteObj.rf_write(self.arr_data)
832 def f(): return self.digitalWriteObj.rf_write(self.arr_data)
831 self.timeit(f)
833 self.timeit(f)
832
834
833 return
835 return
834
836
835 def run(self, dataOut, frequency=49.92e6, path=None, fileCadence=1000, dirCadence=36000, metadataCadence=1, **kwargs):
837 def run(self, dataOut, frequency=49.92e6, path=None, fileCadence=1000, dirCadence=36000, metadataCadence=1, **kwargs):
836 '''
838 '''
837 This method will be called many times so here you should put all your code
839 This method will be called many times so here you should put all your code
838 Inputs:
840 Inputs:
839 dataOut: object with the data
841 dataOut: object with the data
840 '''
842 '''
841 # print dataOut.__dict__
843 # print dataOut.__dict__
842 self.dataOut = dataOut
844 self.dataOut = dataOut
843 if not self.isConfig:
845 if not self.isConfig:
844 self.setup(dataOut, path, frequency, fileCadence,
846 self.setup(dataOut, path, frequency, fileCadence,
845 dirCadence, metadataCadence, **kwargs)
847 dirCadence, metadataCadence, **kwargs)
846 self.writeMetadata()
848 self.writeMetadata()
847
849
848 self.writeData()
850 self.writeData()
849
851
850 ## self.currentSample += 1
852 ## self.currentSample += 1
851 # if self.dataOut.flagDataAsBlock or self.currentSample == 1:
853 # if self.dataOut.flagDataAsBlock or self.currentSample == 1:
852 # self.writeMetadata()
854 # self.writeMetadata()
853 ## if self.currentSample == self.__nProfiles: self.currentSample = 0
855 ## if self.currentSample == self.__nProfiles: self.currentSample = 0
854
856
855 return dataOut# en la version 2.7 no aparece este return
857 return dataOut# en la version 2.7 no aparece este return
856
858
857 def close(self):
859 def close(self):
858 print('[Writing] - Closing files ')
860 print('[Writing] - Closing files ')
859 print('Average of writing to digital rf format is ', self.oldAverage * 1000)
861 print('Average of writing to digital rf format is ', self.oldAverage * 1000)
860 try:
862 try:
861 self.digitalWriteObj.close()
863 self.digitalWriteObj.close()
862 except:
864 except:
863 pass
865 pass
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