##// END OF EJS Templates
Merge branch 'v3.0-WR' of http://intranet.igp.gob.pe:8082/schain into v3.0-WR
Juan C. Espinoza -
r1480:ab3389190ff4 merge
parent child
Show More
@@ -0,0 +1,362
1 #!python
2 '''
3 '''
4
5 import os, sys
6 import datetime
7 import time
8
9 #path = os.path.dirname(os.getcwd())
10 #path = os.path.dirname(path)
11 #sys.path.insert(0, path)
12
13 from schainpy.controller import Project
14
15 desc = "USRP_test"
16 filename = "USRP_processing.xml"
17 controllerObj = Project()
18 controllerObj.setup(id = '191', name='Test_USRP', description=desc)
19
20 ############## USED TO PLOT IQ VOLTAGE, POWER AND SPECTRA #############
21
22 #######################################################################
23 ######PATH DE LECTURA, ESCRITURA, GRAFICOS Y ENVIO WEB#################
24 #######################################################################
25 #path = '/media/data/data/vientos/57.2063km/echoes/NCO_Woodman'
26 #path = '/DATA_RM/TEST_INTEGRACION'
27 #path = '/DATA_RM/PRUEBA_USRP_RP'
28 #path = '/DATA_RM/PRUEBA_USRP_RP'
29
30 path = '/DATA_RM/TEST_2M'
31 path = '/DATA_RM/TEST_2M_UD'
32 path = '/DATA_RM/2MHZ17022022'
33 path = '/DATA_RM/10MHZTEST/'
34 path = '/DATA_RM/10MHZDRONE/'
35
36
37 path= '/home/soporte/TEST_500mVPP'
38 path= '/home/soporte/TEST_1VPP+500mVDC'
39 path = '/home/soporte/TEST_500mVPP+500mVDC'
40 path = '/home/soporte/TEST_1.5VPP'
41 path = '/home/soporte/TEST_2VPP'
42 path= '/home/soporte/TEST_1VPP'
43 path = '/home/soporte/Documents/HUANCAYO/TEST_HYO_PM@2022-05-14T11-28-19/rawdata'
44
45 #HYO_PM@2022-05-28T00-00-17
46 path = '/DATA_RM/DATA/HYO_PM@2022-05-28T00-00-17/rawdata'
47
48 #figpath = '/home/soporte/Pictures/TEST_RP_0001'
49 #figpath = '/home/soporte/Pictures/TEST_RP_6000'
50 figpath = '/home/soporte/Pictures/USRP_TEST_2M'
51 figpath = '/home/soporte/Pictures/USRP_TEST_2M_UD'
52 figpath = '/home/soporte/Pictures/10MHZDRONE'
53 figpath = '/home/soporte/Pictures/500mVPP'
54 figpath = '/home/soporte/Pictures/1VPP+500mVDC'
55 figpath = '/home/soporte/Pictures/TEST_500mVPP+500mVDC'
56 figpath = '/home/soporte/Pictures/TEST_1.5VPP'
57 figpath = '/home/soporte/Pictures/TEST_2VPP'
58 figpath = '/home/soporte/Pictures/TEST_1VPP'
59
60
61
62
63 #remotefolder = "/home/wmaster/graficos"
64 #######################################################################
65 ################# RANGO DE PLOTEO######################################
66 #######################################################################
67 dBmin = '-60'#'-20'
68 dBmax = '-5'#'-85'
69 xmin = '0'
70 xmax ='24'
71 ymin = '0'
72 ymax = '10'
73 #######################################################################
74 ########################FECHA##########################################
75 #######################################################################
76 str = datetime.date.today()
77 today = str.strftime("%Y/%m/%d")
78 str2 = str - datetime.timedelta(days=1)
79 yesterday = str2.strftime("%Y/%m/%d")
80 #######################################################################
81 ######################## UNIDAD DE LECTURA#############################
82 #######################################################################
83 readUnitConfObj = controllerObj.addReadUnit(datatype='DigitalRFReader',
84 path=path,
85 startDate="2022/05/28",#today,
86 endDate="2022/05/28",#today,
87 startTime='00:00:00',# inicio libre
88 #startTime='00:00:00',
89 endTime='23:59:59',
90 delay=0,
91 #set=0,
92 online=0,
93 walk=1,
94 ippKm = 60)
95
96 opObj11 = readUnitConfObj.addOperation(name='printInfo')
97 #opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock')
98 #######################################################################
99 ################ OPERACIONES DOMINIO DEL TIEMPO########################
100 #######################################################################
101
102 procUnitConfObjA = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId())
103
104 op3 = procUnitConfObjA.addOperation(name='ProfileSelector', optype='other')
105 op3.addParameter(name='profileRangeList', value='1,123')
106
107
108 code=[[1]]
109
110 opObj11 = procUnitConfObjA.addOperation(name='Decoder', optype='other')
111 opObj11.addParameter(name='code', value=code)
112 opObj11.addParameter(name='nCode', value='1', format='int')
113 opObj11.addParameter(name='nBaud', value='1', format='int')
114
115
116 '''
117 op3 = procUnitConfObjA.addOperation(name='ProfileSelector', optype='other')
118 op3.addParameter(name='profileRangeList', value='122,249')
119 code8=[[1,1,1,0,1,1,0,1],[1,1,1,0,0,0,1,0]]
120
121 opObj11 = procUnitConfObjA.addOperation(name='Decoder', optype='other')
122 opObj11.addParameter(name='code', value=code8)
123 opObj11.addParameter(name='nCode', value='2', format='int')
124 opObj11.addParameter(name='nBaud', value='8', format='int')
125 '''
126 op = procUnitConfObjA.addOperation(name='CohInt', optype='other') #Minimo integrar 2 perfiles por ser codigo complementario
127 op.addParameter(name='n', value=2, format='int')
128
129
130 '''
131
132 # OJO SCOPE
133 opObj10 = procUnitConfObjA.addOperation(name='ScopePlot', optype='external')
134 opObj10.addParameter(name='id', value='10', format='int')
135 opObj10.addParameter(name='xmin', value='0', format='int')
136 opObj10.addParameter(name='xmax', value='60', format='int')
137 opObj10.addParameter(name='type', value='iq')
138 #opObj10.addParameter(name='ymin', value='-0.20000', format='int')
139 #opObj10.addParameter(name='ymax', value='0.20000', format='int')
140 opObj10.addParameter(name='save', value=figpath, format='str')
141 opObj10.addParameter(name='save_period', value=1, format='int')
142 '''
143 '''
144 opObj11 = procUnitConfObjA.addOperation(name='selectHeights')
145 opObj11.addParameter(name='minIndex', value='1', format='int')
146 # opObj11.addParameter(name='maxIndex', value='10000', format='int')
147 opObj11.addParameter(name='maxIndex', value='200', format='int')
148 '''
149 #
150 # codigo64='1,1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,1,1,1,0,1,1,0,1,0,0,0,1,1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,1,0,1,1,1,0,0,0,1,0,'+\
151 # '1,1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,1,1,1,0,1,1,0,1,0,0,0,1,1,1,0,1,0,0,0,1,0,0,1,0,0,0,0,1,1,1,0,1,1,1,1,0,1,1,0,1,0,0,0,1,1,1,0,1'
152
153 #opObj11 = procUnitConfObjA.addOperation(name='setRadarFrequency')
154 #opObj11.addParameter(name='frequency', value='49920000')
155
156 '''
157 opObj11 = procUnitConfObjA.addOperation(name='PulsePair', optype='other')
158 opObj11.addParameter(name='n', value='625', format='int')#10
159 opObj11.addParameter(name='removeDC', value=1, format='int')
160 '''
161
162 # Ploteo TEST
163 '''
164 opObj11 = procUnitConfObjA.addOperation(name='PulsepairPowerPlot', optype='other')
165 opObj11 = procUnitConfObjA.addOperation(name='PulsepairSignalPlot', optype='other')
166 opObj11 = procUnitConfObjA.addOperation(name='PulsepairVelocityPlot', optype='other')
167 #opObj11.addParameter(name='xmax', value=8)
168 opObj11 = procUnitConfObjA.addOperation(name='PulsepairSpecwidthPlot', optype='other')
169 '''
170 # OJO SCOPE
171 #opObj10 = procUnitConfObjA.addOperation(name='ScopePlot', optype='external')
172 #opObj10.addParameter(name='id', value='10', format='int')
173 ##opObj10.addParameter(name='xmin', value='0', format='int')
174 ##opObj10.addParameter(name='xmax', value='50', format='int')
175 #opObj10.addParameter(name='type', value='iq')
176 ##opObj10.addParameter(name='ymin', value='-5000', format='int')
177 ##opObj10.addParameter(name='ymax', value='8500', format='int')
178 #opObj11.addParameter(name='save', value=figpath, format='str')
179 #opObj11.addParameter(name='save_period', value=10, format='int')
180
181 #opObj10 = procUnitConfObjA.addOperation(name='setH0')
182 #opObj10.addParameter(name='h0', value='-5000', format='float')
183
184 #opObj11 = procUnitConfObjA.addOperation(name='filterByHeights')
185 #opObj11.addParameter(name='window', value='1', format='int')
186
187 #codigo='1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1'
188 #opObj11 = procUnitConfObjSousy.addOperation(name='Decoder', optype='other')
189 #opObj11.addParameter(name='code', value=codigo, format='floatlist')
190 #opObj11.addParameter(name='nCode', value='1', format='int')
191 #opObj11.addParameter(name='nBaud', value='28', format='int')
192
193 #opObj11 = procUnitConfObjA.addOperation(name='CohInt', optype='other')
194 #opObj11.addParameter(name='n', value='100', format='int')
195
196 #######################################################################
197 ########## OPERACIONES ParametersProc########################
198 #######################################################################
199 ###procUnitConfObjB= controllerObj.addProcUnit(datatype='ParametersProc',inputId=procUnitConfObjA.getId())
200 '''
201
202 opObj11 = procUnitConfObjA.addOperation(name='PedestalInformation')
203 opObj11.addParameter(name='path_ped', value=path_ped)
204 opObj11.addParameter(name='path_adq', value=path_adq)
205 opObj11.addParameter(name='t_Interval_p', value='0.01', format='float')
206 opObj11.addParameter(name='n_Muestras_p', value='100', format='float')
207 opObj11.addParameter(name='blocksPerfile', value='100', format='int')
208 opObj11.addParameter(name='f_a_p', value='25', format='int')
209 opObj11.addParameter(name='online', value='0', format='int')
210
211 opObj11 = procUnitConfObjA.addOperation(name='Block360')
212 opObj11.addParameter(name='n', value='40', format='int')
213
214 opObj11= procUnitConfObjA.addOperation(name='WeatherPlot',optype='other')
215 opObj11.addParameter(name='save', value=figpath)
216 opObj11.addParameter(name='save_period', value=1)
217
218 8
219 '''
220
221
222 '''
223 opObj11 = procUnitConfObjA.addOperation(name='CohInt', optype='other')
224 opObj11.addParameter(name='n', value='250', format='int')
225 '''
226 #######################################################################
227 ########## OPERACIONES DOMINIO DE LA FRECUENCIA########################
228 #######################################################################
229 '''
230 procUnitConfObjB = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjA.getId())
231 procUnitConfObjB.addParameter(name='nFFTPoints', value='64', format='int')
232 procUnitConfObjB.addParameter(name='nProfiles', value='64', format='int')
233 '''
234
235 procUnitConfObjB = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjA.getId())
236 procUnitConfObjB.addParameter(name='nFFTPoints', value='61', format='int')
237 procUnitConfObjB.addParameter(name='nProfiles', value='61', format='int')
238
239 '''
240 procUnitConfObjC = controllerObj.addProcUnit(datatype='SpectraHeisProc', inputId=procUnitConfObjA.getId())
241 #procUnitConfObjB.addParameter(name='nFFTPoints', value='64', format='int')
242 #procUnitConfObjB.addParameter(name='nProfiles', value='64', format='int')
243 opObj11 = procUnitConfObjC.addOperation(name='IncohInt4SpectraHeis', optype='other')
244 #opObj11.addParameter(name='timeInterval', value='4', format='int')
245 opObj11.addParameter(name='n', value='100', format='int')
246
247 #procUnitConfObjB.addParameter(name='pairsList', value='(0,0),(1,1),(0,1)', format='pairsList')
248
249 #opObj13 = procUnitConfObjB.addOperation(name='removeDC')
250 #opObj13.addParameter(name='mode', value='2', format='int')
251
252 #opObj11 = procUnitConfObjB.addOperation(name='IncohInt', optype='other')
253 #opObj11.addParameter(name='n', value='8', format='float')
254 #######################################################################
255 ########## PLOTEO DOMINIO DE LA FRECUENCIA#############################
256 #######################################################################
257 #----
258 '''
259 '''
260 opObj11 = procUnitConfObjC.addOperation(name='SpectraHeisPlot')
261 opObj11.addParameter(name='id', value='10', format='int')
262 opObj11.addParameter(name='wintitle', value='Spectra_Alturas', format='str')
263 #opObj11.addParameter(name='xmin', value=-100000, format='float')
264 #opObj11.addParameter(name='xmax', value=100000, format='float')
265 opObj11.addParameter(name='oneFigure', value=False,format='bool')
266 #opObj11.addParameter(name='zmin', value=-10, format='int')
267 #opObj11.addParameter(name='zmax', value=40, format='int')
268 opObj11.addParameter(name='ymin', value=10, format='int')
269 opObj11.addParameter(name='ymax', value=55, format='int')
270 opObj11.addParameter(name='grid', value=True, format
271 [Reading] 2022-05-23 12:27:32.732775: 21333 samples <> 0.010667 sec
272 ='bool')
273 #opObj11.addParameter(name='showprofile', value='1', format='int')
274 opObj11.addParameter(name='save', value=figpath, format='str')
275 #opObj11.addParameter(name='save_period', value=10, format='int')
276 '''
277 '''
278 opObj11 = procUnitConfObjC.addOperation(name='RTIHeisPlot')
279 opObj11.addParameter(name='id', value='10', format='int')
280 opObj11.addParameter(name='wintitle', value='RTI_Alturas', format='str')
281 opObj11.addParameter(name='xmin', value=11.0, format='float')
282 opObj11.addParameter(name='xmax', value=18.0, format='float')
283 opObj11.addParameter(name='zmin', value=10, format='int')
284 opObj11.addParameter(name='zmax', value=30, format='int')
285 opObj11.addParameter(name='ymin', value=5, format='int')
286 opObj11.addParameter(name='ymax', value=28, format='int')
287 opObj11.addParameter(name='showprofile', value='1', format='int')
288 opObj11.addParameter(name='save', value=figpath, format='str')
289 opObj11.addParameter(name='save_period', value=10, format='int')
290 '''
291
292 #SpectraPlot
293
294 opObj11 = procUnitConfObjB.addOperation(name='SpectraPlot', optype='external')
295 opObj11.addParameter(name='id', value='1', format='int')
296 opObj11.addParameter(name='wintitle', value='Spectra', format='str')
297 #opObj11.addParameter(name='xmin', value=-0.01, format='float')
298 #opObj11.addParameter(name='xmax', value=0.01, format='float')
299 opObj11.addParameter(name='zmin', value=dBmin, format='int')
300 opObj11.addParameter(name='zmax', value=dBmax, format='int')
301 opObj11.addParameter(name='ymin', value=ymin, format='int')
302 opObj11.addParameter(name='ymax', value=ymax, format='int')
303 opObj11.addParameter(name='showprofile', value='1', format='int')
304 opObj11.addParameter(name='save', value=figpath, format='str')
305 opObj11.addParameter(name='save_period', value=10, format='int')
306
307
308 #RTIPLOT
309 '''
310 opObj11 = procUnitConfObjB.addOperation(name='RTIPlot', optype='external')
311 opObj11.addParameter(name='id', value='2', format='int')
312 opObj11.addParameter(name='wintitle', value='RTIPlot', format='str')
313 opObj11.addParameter(name='zmin', value=dBmin, format='int')
314 opObj11.addParameter(name='zmax', value=dBmax, format='int')
315 #opObj11.addParameter(name='ymin', value=ymin, format='int')
316 #opObj11.addParameter(name='ymax', value=ymax, format='int')
317 #opObj11.addParameter(name='xmin', value=15, format='int')
318 #opObj11.addParameter(name='xmax', value=16, format='int')
319 opObj11.addParameter(name='zmin', value=dBmin, format='int')
320 opObj11.addParameter(name='zmax', value=dBmax, format='int')
321
322 opObj11.addParameter(name='showprofile', value='1', format='int')
323 opObj11.addParameter(name='save', value=figpath, format='str')
324 opObj11.addParameter(name='save_period', value=10, format='int')
325 '''
326 '''
327 # opObj11 = procUnitConfObjB.addOperation(name='CrossSpectraPlot', optype='other')
328 # opObj11.addParameter(name='id', value='3', format='int')
329 # opObj11.addParameter(name='wintitle', value='CrossSpectraPlot', format='str')
330 # opObj11.addParameter(name='ymin', value=ymin, format='int')
331 # opObj11.addParameter(name='ymax', value=ymax, format='int')
332 # opObj11.addParameter(name='phase_cmap', value='jet', format='str')
333 # opObj11.addParameter(name='zmin', value=dBmin, format='int')
334 # opObj11.addParameter(name='zmax', value=dBmax, format='int')
335 # opObj11.addParameter(name='figpath', value=figures_path, format='str')
336 # opObj11.addParameter(name='save', value=0, format='bool')
337 # opObj11.addParameter(name='pairsList', value='(0,1)', format='pairsList')
338 # #
339 # opObj11 = procUnitConfObjB.addOperation(name='CoherenceMap', optype='other')
340 # opObj11.addParameter(name='id', value='4', format='int')
341 # opObj11.addParameter(name='wintitle', value='Coherence', format='str')
342 # opObj11.addParameter(name='phase_cmap', value='jet', format='str')
343 # opObj11.addParameter(name='xmin', value=xmin, format='float')
344 # opObj11.addParameter(name='xmax', value=xmax, format='float')
345 # opObj11.addParameter(name='figpath', value=figures_path, format='str')
346 # opObj11.addParameter(name='save', value=0, format='bool')
347 # opObj11.addParameter(name='pairsList', value='(0,1)', format='pairsList')
348 #
349 '''
350 '''
351 #######################################################################
352 ############### UNIDAD DE ESCRITURA ###################################
353 #######################################################################
354 #opObj11 = procUnitConfObjB.addOperation(name='SpectraWriter', optype='other')
355 #opObj11.addParameter(name='path', value=wr_path)
356 #opObj11.addParameter(name='blocksPerFile', value='50', format='int')
357 print ("Escribiendo el archivo XML")
358 print ("Leyendo el archivo XML")
359 '''
360
361
362 controllerObj.start()
@@ -0,0 +1,378
1
2 # SOPHY PROC script
3 import os, sys, json, argparse
4 import datetime
5 import time
6
7 PATH = '/DATA_RM/DATA'
8 # PATH = '/Users/jespinoza/workspace/data/'
9 #PATH = '/home/soporte/Documents/HUANCAYO'
10 PARAM = {
11 'P': {'name': 'dataPP_POWER', 'zmin': -45, 'zmax': -25, 'colormap': 'jet', 'label': 'Power', 'wrname': 'Pow','cb_label': 'dB', 'ch':0},
12 'V': {'name': 'dataPP_DOP', 'zmin': -20, 'zmax': 20, 'colormap': 'seismic', 'label': 'Velocity', 'wrname': 'Vel', 'cb_label': 'm/s', 'ch':0},
13 'RH': {'name': 'RhoHV_R', 'zmin': 0, 'zmax': 1, 'colormap': 'jet', 'label': 'Coef.Correlacion', 'wrname':'R', 'cb_label': '*', 'ch':0},
14 'FD': {'name': 'PhiD_P', 'zmin': -180,'zmax': 180,'colormap': 'RdBu_r', 'label': 'Fase Diferencial', 'wrname':'P' , 'cb_label': 'ΒΊ', 'ch':0},
15 'ZD': {'name': 'Zdb_D', 'zmin': -20, 'zmax': 60, 'colormap': 'viridis','label': 'Reflect.Diferencial','wrname':'D' , 'cb_label': 'dBz','ch':0},
16 'Z': {'name': 'Zdb', 'zmin': -20, 'zmax': 70, 'colormap': 'gist_ncar','label': 'Reflectividad', 'wrname':'Z', 'cb_label': 'dBz','ch':1},
17 'W': {'name': 'Sigmav_W', 'zmin': 0, 'zmax':5, 'colormap': 'viridis','label': 'AnchoEspectral', 'wrname':'S', 'cb_label': 'hz', 'ch':1}
18 }
19
20 #
21 def max_index(r, sample_rate, ipp):
22
23 return int(sample_rate*ipp*1e6 * r / 60) + int(sample_rate*ipp*1e6 * 1.2 / 60)
24
25 def main(args):
26
27 experiment = args.experiment
28 fp = open(os.path.join(PATH, experiment, 'experiment.conf'))
29 conf = json.loads(fp.read())
30
31 ipp_km = conf['usrp_tx']['ipp']
32 ipp = ipp_km * 2 /300000
33 sample_rate = conf['usrp_rx']['sample_rate']
34 axis = ['0' if x=='elevation' else '1' for x in conf['pedestal']['axis']] # AZIMUTH 1 ELEVACION 0
35 speed_axis = conf['pedestal']['speed']
36 steeps = conf['pedestal']['table']
37 time_offset = args.time_offset
38 parameters = args.parameters
39 start_date = experiment.split('@')[1].split('T')[0].replace('-', '/')
40 end_date = start_date
41 start_time = experiment.split('@')[1].split('T')[1].replace('-', ':')
42 end_time = '23:59:59'
43 N = int(1/(speed_axis[0]*ipp)) # 1 GRADO DE RESOLUCION
44 path = os.path.join(PATH, experiment, 'rawdata')
45 path_ped = os.path.join(PATH, experiment, 'position')
46 path_plots = os.path.join(PATH, experiment, 'plots_ch0')
47 path_save = os.path.join(PATH, experiment, 'param')
48 RMIX = 20
49
50 from schainpy.controller import Project
51
52 project = Project()
53 project.setup(id='1', name='Sophy', description='sophy proc')
54
55 reader = project.addReadUnit(datatype='DigitalRFReader',
56 path=path,
57 startDate=start_date,
58 endDate=end_date,
59 startTime=start_time,
60 endTime=end_time,
61 delay=30,
62 channelList='0',
63 online=args.online,
64 walk=1,
65 ippKm = ipp_km,
66 getByBlock = 1,
67 nProfileBlocks = N,
68 )
69
70 if not conf['usrp_tx']['enable_2']: # One Pulse
71 voltage = project.addProcUnit(datatype='VoltageProc', inputId=reader.getId())
72
73 if conf['usrp_tx']['code_type_1']:
74 code = [c.split() for c in conf['usrp']['code_1']]
75 op = voltage.addOperation(name='Decoder', optype='other')
76 op.addParameter(name='code', value=code)
77 op.addParameter(name='nCode', value=len(code), format='int')
78 op.addParameter(name='nBaud', value=len(code[0]), format='int')
79
80 op = voltage.addOperation(name='setH0')
81 op.addParameter(name='h0', value='-1.2')
82
83 if args.range >= 0:
84 op = voltage.addOperation(name='selectHeights')
85 op.addParameter(name='minIndex', value='0', format='int')
86 op.addParameter(name='maxIndex', value=max_index(RMIX, sample_rate, ipp), format='int')
87
88 code=[[1]]
89 opObj11 = voltage.addOperation(name='Decoder', optype='other')
90 opObj11.addParameter(name='code', value=code)
91 opObj11.addParameter(name='nCode', value='1', format='int')
92 opObj11.addParameter(name='nBaud', value='1', format='int')
93
94 op = voltage2.addOperation(name='CohInt', optype='other') #Minimo integrar 2 perfiles por ser codigo complementario
95 op.addParameter(name='n', value=2*len(code), format='int')
96
97 #op = voltage.addOperation(name='PulsePair_vRF', optype='other')
98 #op.addParameter(name='n', value=int(N), format='int')
99
100 if args.range >= 0:
101 op = voltage.addOperation(name='selectHeights')
102 op.addParameter(name='minIndex', value='0', format='int')
103 op.addParameter(name='maxIndex', value=max_index(RMIX, sample_rate, ipp), format='int')
104
105
106 op = voltage.addOperation(name='PulsePair_vRF', optype='other')
107 op.addParameter(name='n', value=125, format='int')
108
109
110 proc = project.addProcUnit(datatype='ParametersProc', inputId=voltage.getId())
111 #procUnitConfObjB.addParameter(name='runNextUnit', value=True)
112
113 opObj10 = proc.addOperation(name="WeatherRadar")
114 opObj10.addParameter(name='variableList',value='Reflectividad,VelocidadRadial,AnchoEspectral')
115
116 # {"latitude": -12.0404828587, "longitude": -75.2147483647, "altitude": 3379.2147483647}
117
118 op = proc.addOperation(name='PedestalInformation')
119 op.addParameter(name='path', value=path_ped, format='str')
120 op.addParameter(name='interval', value='0.04')
121 op.addParameter(name='time_offset', value=time_offset)
122 op.addParameter(name='az_offset', value=-26.2)
123
124 for param in parameters:
125 op = proc.addOperation(name='Block360_vRF4')
126 #op.addParameter(name='axis', value=','.join(axis))
127 op.addParameter(name='attr_data', value=PARAM[param]['name'])
128 op.addParameter(name='runNextOp', value=True)
129
130 op= proc.addOperation(name='WeatherParamsPlot')
131 if args.save: op.addParameter(name='save', value=path_plots, format='str')
132 op.addParameter(name='save_period', value=-1)
133 op.addParameter(name='show', value=args.show)
134 op.addParameter(name='channels', value='0,')
135 op.addParameter(name='zmin', value=PARAM[param]['zmin'])
136 op.addParameter(name='zmax', value=PARAM[param]['zmax'])
137 op.addParameter(name='attr_data', value=PARAM[param]['name'], format='str')
138 op.addParameter(name='labels', value=[PARAM[param]['label']])
139 op.addParameter(name='save_code', value=param)
140 op.addParameter(name='cb_label', value=PARAM[param]['cb_label'])
141 op.addParameter(name='colormap', value=PARAM[param]['colormap'])
142
143 desc = {
144 'Data': {
145 PARAM[param]['name']: PARAM[param]['label'],
146 'utctime': 'time'
147 },
148 'Metadata': {
149 'heightList': 'range',
150 'data_azi': 'azimuth',
151 'data_ele': 'elevation',
152 }
153 }
154
155 if args.save:
156 opObj10 = proc.addOperation(name='HDFWriter')
157 opObj10.addParameter(name='path',value=path_save+'-{}'.format(param), format='str')
158 opObj10.addParameter(name='Reset',value=True)
159 opObj10.addParameter(name='setType',value='weather')
160 opObj10.addParameter(name='description',value='desc')
161 opObj10.addParameter(name='blocksPerFile',value='1',format='int')
162 opObj10.addParameter(name='metadataList',value='heightList,data_azi,data_ele')
163 opObj10.addParameter(name='dataList',value='{},utctime'.format(PARAM[param]['name']))
164
165 else: #Two pulses
166
167 voltage1 = project.addProcUnit(datatype='VoltageProc', inputId=reader.getId())
168
169 print("repetions",conf['usrp_tx']['repetitions_1'])
170
171 op = voltage1.addOperation(name='ProfileSelector')
172 op.addParameter(name='profileRangeList', value='0,{}'.format(conf['usrp_tx']['repetitions_1']-1))
173
174
175 #op3 = voltage1.addOperation(name='ProfileSelector', optype='other')
176 #op3.addParameter(name='profileRangeList', value='1,123')
177
178 '''
179 if conf['usrp_tx']['code_type_1'] != 'None':
180 code = [c.split() for c in conf['usrp_tx']['code_1']]
181 op = voltage1.addOperation(name='Decoder', optype='other')
182 op.addParameter(name='code', value=code)
183 op.addParameter(name='nCode', value=len(code), format='int')
184 op.addParameter(name='nBaud', value=len(code[0]), format='int')
185 '''
186
187 code=[[1]]
188
189 opObj11 = voltage1.addOperation(name='Decoder', optype='other')
190 opObj11.addParameter(name='code', value=code)
191 opObj11.addParameter(name='nCode', value='1', format='int')
192 opObj11.addParameter(name='nBaud', value='1', format='int')
193
194 op = voltage1.addOperation(name='setH0')
195 op.addParameter(name='h0', value='-1.2')
196
197 if args.range >= 0:
198 op = voltage1.addOperation(name='selectHeights')
199 op.addParameter(name='minIndex', value='0', format='int')
200 op.addParameter(name='maxIndex', value=max_index(RMIX, sample_rate, ipp), format='int')
201
202 op = voltage1.addOperation(name='CohInt', optype='other') #Minimo integrar 2 perfiles por ser codigo complementario
203 op.addParameter(name='n', value=2, format='int')
204
205 op = voltage1.addOperation(name='PulsePair_vRF', optype='other')
206 #op.addParameter(name='n', value=int(N), format='int')
207 op.addParameter(name='n', value=61, format='int')
208 #op.addParameter(name='removeDC',value=True)
209
210 '''
211 if args.range >= 0:
212 print("corto",max_index(RMIX, sample_rate, ipp))
213 op = voltage1.addOperation(name='selectHeights')
214 op.addParameter(name='minIndex', value='0', format='int')
215 op.addParameter(name='maxIndex', value=max_index(RMIX, sample_rate, ipp), format='int')
216 '''
217 proc1 = project.addProcUnit(datatype='ParametersProc', inputId=voltage1.getId())
218 proc1.addParameter(name='runNextUnit', value=True)
219
220 opObj10 = proc1.addOperation(name="WeatherRadar")
221 opObj10.addParameter(name='variableList',value='Reflectividad,VelocidadRadial,AnchoEspectral')
222 opObj10.addParameter(name='tauW',value=0.4*1e-6)
223 opObj10.addParameter(name='Pt',value=0.2)
224
225 # {"latitude": -12.0404828587, "longitude": -75.2147483647, "altitude": 3379.2147483647}
226
227 op = proc1.addOperation(name='PedestalInformation')
228 op.addParameter(name='path', value=path_ped, format='str')
229 op.addParameter(name='interval', value='0.04')
230 op.addParameter(name='time_offset', value=time_offset)
231 op.addParameter(name='az_offset', value=-26.2)
232
233 for param in parameters:
234 op = proc1.addOperation(name='Block360_vRF4')
235 op.addParameter(name='attr_data', value=PARAM[param]['name'])
236 op.addParameter(name='runNextOp', value=True)
237
238 voltage2 = project.addProcUnit(datatype='VoltageProc', inputId=reader.getId())
239
240 op = voltage2.addOperation(name='ProfileSelector')
241 op.addParameter(name='profileRangeList', value='{},{}'.format(conf['usrp_tx']['repetitions_1'], conf['usrp_tx']['repetitions_1']+conf['usrp_tx']['repetitions_2']-1))
242
243
244 if conf['usrp_tx']['code_type_2']:
245 print(conf['usrp_tx']['code_2'])
246 codes = [ c.strip() for c in conf['usrp_tx']['code_2'].split(',')]
247 code = []
248 for c in codes:
249 code.append([int(x) for x in c])
250 print(code)
251 print(code[0])
252 op = voltage2.addOperation(name='Decoder', optype='other')
253 op.addParameter(name='code', value=code)
254 op.addParameter(name='nCode', value=len(code), format='int')
255 op.addParameter(name='nBaud', value=len(code[0]), format='int')
256 import numpy
257 pwcode = numpy.sum(numpy.array(code[0])**2)
258 print("pwcode",pwcode)
259
260 op = voltage2.addOperation(name='CohInt', optype='other') #Minimo integrar 2 perfiles por ser codigo complementario
261 op.addParameter(name='n', value=len(code), format='int')
262 ncode = len(code)
263 else:
264 ncode = 1
265
266 op = voltage2.addOperation(name='setH0')
267 op.addParameter(name='h0', value='-1.2')
268
269 if args.range >= 0:
270 if args.range==0:
271 args.range= ipp_km
272 op = voltage2.addOperation(name='selectHeights')
273 op.addParameter(name='minIndex', value=max_index(RMIX, sample_rate, ipp), format='int')
274 op.addParameter(name='maxIndex', value=max_index(args.range, sample_rate, ipp), format='int')
275
276 #op = voltage2.addOperation(name='PulsePair_vRF', optype='other')
277 #op.addParameter(name='n', value=int(N)/ncode, format='int')
278 op = voltage2.addOperation(name='PulsePair_vRF', optype='other')
279 op.addParameter(name='n', value=64, format='int')
280 #op.addParameter(name='removeDC',value=True)
281
282 '''
283
284 if args.range >= 0:
285 if args.range==0:
286 args.range= ipp_km
287 op = voltage2.addOperation(name='selectHeights')
288 print("largo",max_index(RMIX, sample_rate, ipp))
289 print("largo2",max_index(args.range, sample_rate, ipp))
290
291 op.addParameter(name='minIndex', value=max_index(RMIX, sample_rate, ipp), format='int')
292 op.addParameter(name='maxIndex', value=max_index(args.range, sample_rate, ipp), format='int')
293 '''
294
295 proc2 = project.addProcUnit(datatype='ParametersProc', inputId=voltage2.getId())
296
297 opObj10 = proc2.addOperation(name="WeatherRadar")
298 opObj10.addParameter(name='variableList',value='Reflectividad,AnchoEspectral')
299 opObj10.addParameter(name='tauW',value=6.3*1e-6)
300 opObj10.addParameter(name='Pt',value=3.2)
301
302
303 # {"latitude": -12.0404828587, "longitude": -75.2147483647, "altitude": 3379.2147483647}
304
305 op = proc2.addOperation(name='PedestalInformation')
306 op.addParameter(name='path', value=path_ped, format='str')
307 op.addParameter(name='interval', value='0.04')
308 op.addParameter(name='time_offset', value=time_offset)
309 op.addParameter(name='az_offset', value=-26.2)
310
311 for param in parameters:
312 op = proc2.addOperation(name='Block360_vRF4')
313 #op.addParameter(name='axis', value=','.join(axis))
314 op.addParameter(name='attr_data', value=PARAM[param]['name'])
315 op.addParameter(name='runNextOp', value=True)
316
317 merge = project.addProcUnit(datatype='MergeProc', inputId=[proc1.getId(), proc2.getId()])
318 merge.addParameter(name='attr_data', value=PARAM[param]['name'])
319 merge.addParameter(name='mode', value='7') #RM
320
321 op= merge.addOperation(name='WeatherParamsPlot')
322 if args.save: op.addParameter(name='save', value=path_plots, format='str')
323 op.addParameter(name='save_period', value=-1)
324 op.addParameter(name='show', value=args.show)
325 op.addParameter(name='channels', value='0,')
326 op.addParameter(name='zmin', value=PARAM[param]['zmin'])
327 op.addParameter(name='zmax', value=PARAM[param]['zmax'])
328 op.addParameter(name='attr_data', value=PARAM[param]['name'], format='str')
329 op.addParameter(name='labels', value=[PARAM[param]['label']])
330 op.addParameter(name='save_code', value=param)
331 op.addParameter(name='cb_label', value=PARAM[param]['cb_label'])
332 op.addParameter(name='colormap', value=PARAM[param]['colormap'])
333
334 desc = {
335 'Data': {
336 PARAM[param]['name']: PARAM[param]['label'],
337 'utctime': 'time'
338 },
339 'Metadata': {
340 'heightList': 'range',
341 'data_azi': 'azimuth',
342 'data_ele': 'elevation',
343 }
344 }
345
346 if args.save:
347 opObj10 = merge.addOperation(name='HDFWriter')
348 opObj10.addParameter(name='path',value=path_save, format='str')
349 opObj10.addParameter(name='Reset',value=True)
350 opObj10.addParameter(name='setType',value='weather')
351 opObj10.addParameter(name='description',value='desc')
352 opObj10.addParameter(name='blocksPerFile',value='1',format='int')
353 opObj10.addParameter(name='metadataList',value='heightList,data_azi,data_ele')
354 opObj10.addParameter(name='dataList',value='{},utctime'.format(PARAM[param]['name']))
355
356 project.start()
357
358 if __name__ == '__main__':
359
360 parser = argparse.ArgumentParser(description='Script to process SOPHy data.')
361 parser.add_argument('experiment',
362 help='Experiment name')
363 parser.add_argument('--parameters', nargs='*', default=['P'],
364 help='Variables to process: P, Z, V')
365 parser.add_argument('--time_offset', default=0,
366 help='Fix time offset')
367 parser.add_argument('--range', default=0, type=float,
368 help='Max range to plot')
369 parser.add_argument('--save', action='store_true',
370 help='Create output files')
371 parser.add_argument('--show', action='store_true',
372 help='Show matplotlib plot.')
373 parser.add_argument('--online', action='store_true',
374 help='Set online mode.')
375
376 args = parser.parse_args()
377
378 main(args)
@@ -0,0 +1,376
1 # SOPHY PROC script
2 import os, sys, json, argparse
3 import datetime
4 import time
5
6 PATH = '/DATA_RM/DATA'
7 # PATH = '/Users/jespinoza/workspace/data/'
8 #PATH = '/home/soporte/Documents/HUANCAYO'
9 PARAM = {
10 'P': {'name': 'dataPP_POWER', 'zmin': -50, 'zmax': -15, 'colormap': 'jet', 'label': 'Power', 'wrname': 'Pow','cb_label': 'dB', 'ch':0},
11 'V': {'name': 'dataPP_DOP', 'zmin': -20, 'zmax': 20, 'colormap': 'seismic', 'label': 'Velocity', 'wrname': 'Vel', 'cb_label': 'm/s', 'ch':0},
12 'RH': {'name': 'RhoHV_R', 'zmin': 0, 'zmax': 1, 'colormap': 'jet', 'label': 'Coef.Correlacion', 'wrname':'R', 'cb_label': '*', 'ch':0},
13 'FD': {'name': 'PhiD_P', 'zmin': -180,'zmax': 180,'colormap': 'RdBu_r', 'label': 'Fase Diferencial', 'wrname':'P' , 'cb_label': 'ΒΊ', 'ch':0},
14 'ZD': {'name': 'Zdb_D', 'zmin': -20, 'zmax': 60, 'colormap': 'viridis','label': 'Reflect.Diferencial','wrname':'D' , 'cb_label': 'dBz','ch':0},
15 'Z': {'name': 'Zdb', 'zmin': -20, 'zmax': 70, 'colormap': 'gist_ncar','label': 'Reflectividad', 'wrname':'Z', 'cb_label': 'dBz','ch':1},
16 'W': {'name': 'Sigmav_W', 'zmin': 0, 'zmax':5, 'colormap': 'viridis','label': 'AnchoEspectral', 'wrname':'S', 'cb_label': 'hz', 'ch':1}
17 }
18
19 def max_index(r, sample_rate, ipp):
20
21 return int(sample_rate*ipp*1e6 * r / 60) + int(sample_rate*ipp*1e6 * 1.2 / 60)
22
23 def main(args):
24
25 experiment = args.experiment
26 fp = open(os.path.join(PATH, experiment, 'experiment.conf'))
27 conf = json.loads(fp.read())
28
29 ipp_km = conf['usrp_tx']['ipp']
30 ipp = ipp_km * 2 /300000
31 sample_rate = conf['usrp_rx']['sample_rate']
32 axis = ['0' if x=='elevation' else '1' for x in conf['pedestal']['axis']] # AZIMUTH 1 ELEVACION 0
33 speed_axis = conf['pedestal']['speed']
34 steeps = conf['pedestal']['table']
35 time_offset = args.time_offset
36 parameters = args.parameters
37 start_date = experiment.split('@')[1].split('T')[0].replace('-', '/')
38 end_date = start_date
39 start_time = experiment.split('@')[1].split('T')[1].replace('-', ':')
40 end_time = '23:59:59'
41 N = int(1/(speed_axis[0]*ipp)) # 1 GRADO DE RESOLUCION
42 path = os.path.join(PATH, experiment, 'rawdata')
43 path_ped = os.path.join(PATH, experiment, 'position')
44 path_plots = os.path.join(PATH, experiment, 'plots_ch1')
45 path_save = os.path.join(PATH, experiment, 'param')
46 RMIX = 2
47
48 from schainpy.controller import Project
49
50 project = Project()
51 project.setup(id='1', name='Sophy', description='sophy proc')
52
53 reader = project.addReadUnit(datatype='DigitalRFReader',
54 path=path,
55 startDate=start_date,
56 endDate=end_date,
57 startTime=start_time,
58 endTime=end_time,
59 delay=30,
60 channelList='0',
61 online=args.online,
62 walk=1,
63 ippKm = ipp_km,
64 getByBlock = 1,
65 nProfileBlocks = N,
66 )
67
68 if not conf['usrp_tx']['enable_2']: # One Pulse
69 voltage = project.addProcUnit(datatype='VoltageProc', inputId=reader.getId())
70
71 if conf['usrp_tx']['code_type_1']:
72 code = [c.split() for c in conf['usrp']['code_1']]
73 op = voltage.addOperation(name='Decoder', optype='other')
74 op.addParameter(name='code', value=code)
75 op.addParameter(name='nCode', value=len(code), format='int')
76 op.addParameter(name='nBaud', value=len(code[0]), format='int')
77
78 op = voltage.addOperation(name='setH0')
79 op.addParameter(name='h0', value='-1.2')
80
81 if args.range >= 0:
82 op = voltage.addOperation(name='selectHeights')
83 op.addParameter(name='minIndex', value='0', format='int')
84 op.addParameter(name='maxIndex', value=max_index(RMIX, sample_rate, ipp), format='int')
85
86 code=[[1]]
87 opObj11 = voltage.addOperation(name='Decoder', optype='other')
88 opObj11.addParameter(name='code', value=code)
89 opObj11.addParameter(name='nCode', value='1', format='int')
90 opObj11.addParameter(name='nBaud', value='1', format='int')
91
92 op = voltage2.addOperation(name='CohInt', optype='other') #Minimo integrar 2 perfiles por ser codigo complementario
93 op.addParameter(name='n', value=2*len(code), format='int')
94
95 #op = voltage.addOperation(name='PulsePair_vRF', optype='other')
96 #op.addParameter(name='n', value=int(N), format='int')
97
98 if args.range >= 0:
99 op = voltage.addOperation(name='selectHeights')
100 op.addParameter(name='minIndex', value='0', format='int')
101 op.addParameter(name='maxIndex', value=max_index(RMIX, sample_rate, ipp), format='int')
102
103
104 op = voltage.addOperation(name='PulsePair_vRF', optype='other')
105 op.addParameter(name='n', value=125, format='int')
106
107
108 proc = project.addProcUnit(datatype='ParametersProc', inputId=voltage.getId())
109 #procUnitConfObjB.addParameter(name='runNextUnit', value=True)
110
111 opObj10 = proc.addOperation(name="WeatherRadar")
112 opObj10.addParameter(name='variableList',value='Reflectividad,VelocidadRadial,AnchoEspectral')
113
114 # {"latitude": -12.0404828587, "longitude": -75.2147483647, "altitude": 3379.2147483647}
115
116 op = proc.addOperation(name='PedestalInformation')
117 op.addParameter(name='path', value=path_ped, format='str')
118 op.addParameter(name='interval', value='0.04')
119 op.addParameter(name='time_offset', value=time_offset)
120 op.addParameter(name='az_offset', value=-26.2)
121
122 for param in parameters:
123 op = proc.addOperation(name='Block360_vRF4')
124 #op.addParameter(name='axis', value=','.join(axis))
125 op.addParameter(name='attr_data', value=PARAM[param]['name'])
126 op.addParameter(name='runNextOp', value=True)
127
128 op= proc.addOperation(name='WeatherParamsPlot')
129 if args.save: op.addParameter(name='save', value=path_plots, format='str')
130 op.addParameter(name='save_period', value=-1)
131 op.addParameter(name='show', value=args.show)
132 op.addParameter(name='channels', value='1,')
133 op.addParameter(name='zmin', value=PARAM[param]['zmin'])
134 op.addParameter(name='zmax', value=PARAM[param]['zmax'])
135 op.addParameter(name='attr_data', value=PARAM[param]['name'], format='str')
136 op.addParameter(name='labels', value=[PARAM[param]['label']])
137 op.addParameter(name='save_code', value=param)
138 op.addParameter(name='cb_label', value=PARAM[param]['cb_label'])
139 op.addParameter(name='colormap', value=PARAM[param]['colormap'])
140
141 desc = {
142 'Data': {
143 PARAM[param]['name']: PARAM[param]['label'],
144 'utctime': 'time'
145 },
146 'Metadata': {
147 'heightList': 'range',
148 'data_azi': 'azimuth',
149 'data_ele': 'elevation',
150 }
151 }
152
153 if args.save:
154 opObj10 = proc.addOperation(name='HDFWriter')
155 opObj10.addParameter(name='path',value=path_save+'-{}'.format(param), format='str')
156 opObj10.addParameter(name='Reset',value=True)
157 opObj10.addParameter(name='setType',value='weather')
158 opObj10.addParameter(name='description',value='desc')
159 opObj10.addParameter(name='blocksPerFile',value='1',format='int')
160 opObj10.addParameter(name='metadataList',value='heightList,data_azi,data_ele')
161 opObj10.addParameter(name='dataList',value='{},utctime'.format(PARAM[param]['name']))
162
163 else: #Two pulses
164
165 voltage1 = project.addProcUnit(datatype='VoltageProc', inputId=reader.getId())
166
167 print("repetions",conf['usrp_tx']['repetitions_1'])
168
169 op = voltage1.addOperation(name='ProfileSelector')
170 op.addParameter(name='profileRangeList', value='0,{}'.format(conf['usrp_tx']['repetitions_1']-1))
171
172
173 #op3 = voltage1.addOperation(name='ProfileSelector', optype='other')
174 #op3.addParameter(name='profileRangeList', value='1,123')
175
176 '''
177 if conf['usrp_tx']['code_type_1'] != 'None':
178 code = [c.split() for c in conf['usrp_tx']['code_1']]
179 op = voltage1.addOperation(name='Decoder', optype='other')
180 op.addParameter(name='code', value=code)
181 op.addParameter(name='nCode', value=len(code), format='int')
182 op.addParameter(name='nBaud', value=len(code[0]), format='int')
183 '''
184
185 code=[[1]]
186
187 opObj11 = voltage1.addOperation(name='Decoder', optype='other')
188 opObj11.addParameter(name='code', value=code)
189 opObj11.addParameter(name='nCode', value='1', format='int')
190 opObj11.addParameter(name='nBaud', value='1', format='int')
191
192 op = voltage1.addOperation(name='setH0')
193 op.addParameter(name='h0', value='-1.2')
194
195 if args.range >= 0:
196 op = voltage1.addOperation(name='selectHeights')
197 op.addParameter(name='minIndex', value='0', format='int')
198 op.addParameter(name='maxIndex', value=max_index(RMIX, sample_rate, ipp), format='int')
199
200 op = voltage1.addOperation(name='CohInt', optype='other') #Minimo integrar 2 perfiles por ser codigo complementario
201 op.addParameter(name='n', value=2, format='int')
202
203 op = voltage1.addOperation(name='PulsePair_vRF', optype='other')
204 #op.addParameter(name='n', value=int(N), format='int')
205 op.addParameter(name='n', value=61, format='int')
206 #op.addParameter(name='removeDC',value=True)
207
208 '''
209 if args.range >= 0:
210 print("corto",max_index(RMIX, sample_rate, ipp))
211 op = voltage1.addOperation(name='selectHeights')
212 op.addParameter(name='minIndex', value='0', format='int')
213 op.addParameter(name='maxIndex', value=max_index(RMIX, sample_rate, ipp), format='int')
214 '''
215 proc1 = project.addProcUnit(datatype='ParametersProc', inputId=voltage1.getId())
216 proc1.addParameter(name='runNextUnit', value=True)
217
218 opObj10 = proc1.addOperation(name="WeatherRadar")
219 opObj10.addParameter(name='variableList',value='Reflectividad,VelocidadRadial,AnchoEspectral')
220 opObj10.addParameter(name='tauW',value=0.4*1e-6)
221 opObj10.addParameter(name='Pt',value=0.2)
222
223 # {"latitude": -12.0404828587, "longitude": -75.2147483647, "altitude": 3379.2147483647}
224
225 op = proc1.addOperation(name='PedestalInformation')
226 op.addParameter(name='path', value=path_ped, format='str')
227 op.addParameter(name='interval', value='0.04')
228 op.addParameter(name='time_offset', value=time_offset)
229 op.addParameter(name='az_offset', value=-26.2)
230
231 for param in parameters:
232 op = proc1.addOperation(name='Block360_vRF4')
233 op.addParameter(name='attr_data', value=PARAM[param]['name'])
234 op.addParameter(name='runNextOp', value=True)
235
236 voltage2 = project.addProcUnit(datatype='VoltageProc', inputId=reader.getId())
237
238 op = voltage2.addOperation(name='ProfileSelector')
239 op.addParameter(name='profileRangeList', value='{},{}'.format(conf['usrp_tx']['repetitions_1'], conf['usrp_tx']['repetitions_1']+conf['usrp_tx']['repetitions_2']-1))
240
241
242 if conf['usrp_tx']['code_type_2']:
243 print(conf['usrp_tx']['code_2'])
244 codes = [ c.strip() for c in conf['usrp_tx']['code_2'].split(',')]
245 code = []
246 for c in codes:
247 code.append([int(x) for x in c])
248 print(code)
249 print(code[0])
250 op = voltage2.addOperation(name='Decoder', optype='other')
251 op.addParameter(name='code', value=code)
252 op.addParameter(name='nCode', value=len(code), format='int')
253 op.addParameter(name='nBaud', value=len(code[0]), format='int')
254 import numpy
255 pwcode = numpy.sum(numpy.array(code[0])**2)
256 print("pwcode",pwcode)
257
258 op = voltage2.addOperation(name='CohInt', optype='other') #Minimo integrar 2 perfiles por ser codigo complementario
259 op.addParameter(name='n', value=len(code), format='int')
260 ncode = len(code)
261 else:
262 ncode = 1
263
264 op = voltage2.addOperation(name='setH0')
265 op.addParameter(name='h0', value='-1.2')
266
267 if args.range >= 0:
268 if args.range==0:
269 args.range= ipp_km
270 op = voltage2.addOperation(name='selectHeights')
271 op.addParameter(name='minIndex', value=max_index(RMIX, sample_rate, ipp), format='int')
272 op.addParameter(name='maxIndex', value=max_index(args.range, sample_rate, ipp), format='int')
273
274 #op = voltage2.addOperation(name='PulsePair_vRF', optype='other')
275 #op.addParameter(name='n', value=int(N)/ncode, format='int')
276 op = voltage2.addOperation(name='PulsePair_vRF', optype='other')
277 op.addParameter(name='n', value=64, format='int')
278 #op.addParameter(name='removeDC',value=True)
279
280 '''
281
282 if args.range >= 0:
283 if args.range==0:
284 args.range= ipp_km
285 op = voltage2.addOperation(name='selectHeights')
286 print("largo",max_index(RMIX, sample_rate, ipp))
287 print("largo2",max_index(args.range, sample_rate, ipp))
288
289 op.addParameter(name='minIndex', value=max_index(RMIX, sample_rate, ipp), format='int')
290 op.addParameter(name='maxIndex', value=max_index(args.range, sample_rate, ipp), format='int')
291 '''
292
293 proc2 = project.addProcUnit(datatype='ParametersProc', inputId=voltage2.getId())
294
295 opObj10 = proc2.addOperation(name="WeatherRadar")
296 opObj10.addParameter(name='variableList',value='Reflectividad,AnchoEspectral')
297 opObj10.addParameter(name='tauW',value=3.2*1e-6)
298 opObj10.addParameter(name='Pt',value=1.6)
299
300
301 # {"latitude": -12.0404828587, "longitude": -75.2147483647, "altitude": 3379.2147483647}
302
303 op = proc2.addOperation(name='PedestalInformation')
304 op.addParameter(name='path', value=path_ped, format='str')
305 op.addParameter(name='interval', value='0.04')
306 op.addParameter(name='time_offset', value=time_offset)
307 op.addParameter(name='az_offset', value=-26.2)
308
309 for param in parameters:
310 op = proc2.addOperation(name='Block360_vRF4')
311 #op.addParameter(name='axis', value=','.join(axis))
312 op.addParameter(name='attr_data', value=PARAM[param]['name'])
313 op.addParameter(name='runNextOp', value=True)
314
315 merge = project.addProcUnit(datatype='MergeProc', inputId=[proc1.getId(), proc2.getId()])
316 merge.addParameter(name='attr_data', value=PARAM[param]['name'])
317 merge.addParameter(name='mode', value='7') #RM
318
319 op= merge.addOperation(name='WeatherParamsPlot')
320 if args.save: op.addParameter(name='save', value=path_plots, format='str')
321 op.addParameter(name='save_period', value=-1)
322 op.addParameter(name='show', value=args.show)
323 op.addParameter(name='channels', value='1,')
324 op.addParameter(name='zmin', value=PARAM[param]['zmin'])
325 op.addParameter(name='zmax', value=PARAM[param]['zmax'])
326 op.addParameter(name='attr_data', value=PARAM[param]['name'], format='str')
327 op.addParameter(name='labels', value=[PARAM[param]['label']])
328 op.addParameter(name='save_code', value=param)
329 op.addParameter(name='cb_label', value=PARAM[param]['cb_label'])
330 op.addParameter(name='colormap', value=PARAM[param]['colormap'])
331
332 desc = {
333 'Data': {
334 PARAM[param]['name']: PARAM[param]['label'],
335 'utctime': 'time'
336 },
337 'Metadata': {
338 'heightList': 'range',
339 'data_azi': 'azimuth',
340 'data_ele': 'elevation',
341 }
342 }
343
344 if args.save:
345 opObj10 = merge.addOperation(name='HDFWriter')
346 opObj10.addParameter(name='path',value=path_save, format='str')
347 opObj10.addParameter(name='Reset',value=True)
348 opObj10.addParameter(name='setType',value='weather')
349 opObj10.addParameter(name='description',value='desc')
350 opObj10.addParameter(name='blocksPerFile',value='1',format='int')
351 opObj10.addParameter(name='metadataList',value='heightList,data_azi,data_ele')
352 opObj10.addParameter(name='dataList',value='{},utctime'.format(PARAM[param]['name']))
353
354 project.start()
355
356 if __name__ == '__main__':
357
358 parser = argparse.ArgumentParser(description='Script to process SOPHy data.')
359 parser.add_argument('experiment',
360 help='Experiment name')
361 parser.add_argument('--parameters', nargs='*', default=['P'],
362 help='Variables to process: P, Z, V')
363 parser.add_argument('--time_offset', default=0,
364 help='Fix time offset')
365 parser.add_argument('--range', default=0, type=float,
366 help='Max range to plot')
367 parser.add_argument('--save', action='store_true',
368 help='Create output files')
369 parser.add_argument('--show', action='store_true',
370 help='Show matplotlib plot.')
371 parser.add_argument('--online', action='store_true',
372 help='Set online mode.')
373
374 args = parser.parse_args()
375
376 main(args)
@@ -1,716 +1,739
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 # All rights reserved.
2 # All rights reserved.
3 #
3 #
4 # Distributed under the terms of the BSD 3-clause license.
4 # Distributed under the terms of the BSD 3-clause license.
5 """Base class to create plot operations
5 """Base class to create plot operations
6
6
7 """
7 """
8
8
9 import os
9 import os
10 import sys
10 import sys
11 import zmq
11 import zmq
12 import time
12 import time
13 import numpy
13 import numpy
14 import datetime
14 import datetime
15 from collections import deque
15 from collections import deque
16 from functools import wraps
16 from functools import wraps
17 from threading import Thread
17 from threading import Thread
18 import matplotlib
18 import matplotlib,re
19
19
20 if 'BACKEND' in os.environ:
20 if 'BACKEND' in os.environ:
21 matplotlib.use(os.environ['BACKEND'])
21 matplotlib.use(os.environ['BACKEND'])
22 elif 'linux' in sys.platform:
22 elif 'linux' in sys.platform:
23 matplotlib.use("TkAgg")
23 matplotlib.use("Agg")#TkAgg
24 elif 'darwin' in sys.platform:
24 elif 'darwin' in sys.platform:
25 matplotlib.use('MacOSX')
25 matplotlib.use('MacOSX')
26 else:
26 else:
27 from schainpy.utils import log
27 from schainpy.utils import log
28 log.warning('Using default Backend="Agg"', 'INFO')
28 log.warning('Using default Backend="Agg"', 'INFO')
29 matplotlib.use('Agg')
29 matplotlib.use('Agg')
30
30
31 import matplotlib.pyplot as plt
31 import matplotlib.pyplot as plt
32 from matplotlib.patches import Polygon
32 from matplotlib.patches import Polygon
33 from mpl_toolkits.axes_grid1 import make_axes_locatable
33 from mpl_toolkits.axes_grid1 import make_axes_locatable
34 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
34 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
35
35
36 from schainpy.model.data.jrodata import PlotterData
36 from schainpy.model.data.jrodata import PlotterData
37 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
37 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
38 from schainpy.utils import log
38 from schainpy.utils import log
39
39
40 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
40 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
41 blu_values = matplotlib.pyplot.get_cmap(
41 blu_values = matplotlib.pyplot.get_cmap(
42 'seismic_r', 20)(numpy.arange(20))[10:15]
42 'seismic_r', 20)(numpy.arange(20))[10:15]
43 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
43 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
44 'jro', numpy.vstack((blu_values, jet_values)))
44 'jro', numpy.vstack((blu_values, jet_values)))
45 matplotlib.pyplot.register_cmap(cmap=ncmap)
45 matplotlib.pyplot.register_cmap(cmap=ncmap)
46
46
47 rwg=matplotlib.colors.LinearSegmentedColormap.from_list('rwg',["r", "w", "g"], N=256)
48 matplotlib.pyplot.register_cmap(cmap=rwg)
49
47 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
50 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
48 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
51 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm','rwg')]
49
52
50 EARTH_RADIUS = 6.3710e3
53 EARTH_RADIUS = 6.3710e3
51
54
52 def ll2xy(lat1, lon1, lat2, lon2):
55 def ll2xy(lat1, lon1, lat2, lon2):
53
56
54 p = 0.017453292519943295
57 p = 0.017453292519943295
55 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
58 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
56 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
59 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
57 r = 12742 * numpy.arcsin(numpy.sqrt(a))
60 r = 12742 * numpy.arcsin(numpy.sqrt(a))
58 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
61 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
59 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
62 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
60 theta = -theta + numpy.pi/2
63 theta = -theta + numpy.pi/2
61 return r*numpy.cos(theta), r*numpy.sin(theta)
64 return r*numpy.cos(theta), r*numpy.sin(theta)
62
65
63
66
64 def km2deg(km):
67 def km2deg(km):
65 '''
68 '''
66 Convert distance in km to degrees
69 Convert distance in km to degrees
67 '''
70 '''
68
71
69 return numpy.rad2deg(km/EARTH_RADIUS)
72 return numpy.rad2deg(km/EARTH_RADIUS)
70
73
71
74
72 def figpause(interval):
75 def figpause(interval):
73 backend = plt.rcParams['backend']
76 backend = plt.rcParams['backend']
74 if backend in matplotlib.rcsetup.interactive_bk:
77 if backend in matplotlib.rcsetup.interactive_bk:
75 figManager = matplotlib._pylab_helpers.Gcf.get_active()
78 figManager = matplotlib._pylab_helpers.Gcf.get_active()
76 if figManager is not None:
79 if figManager is not None:
77 canvas = figManager.canvas
80 canvas = figManager.canvas
78 if canvas.figure.stale:
81 if canvas.figure.stale:
79 canvas.draw()
82 canvas.draw()
80 try:
83 try:
81 canvas.start_event_loop(interval)
84 canvas.start_event_loop(interval)
82 except:
85 except:
83 pass
86 pass
84 return
87 return
85
88
86 def popup(message):
89 def popup(message):
87 '''
90 '''
88 '''
91 '''
89
92
90 fig = plt.figure(figsize=(12, 8), facecolor='r')
93 fig = plt.figure(figsize=(12, 8), facecolor='r')
91 text = '\n'.join([s.strip() for s in message.split(':')])
94 text = '\n'.join([s.strip() for s in message.split(':')])
92 fig.text(0.01, 0.5, text, ha='left', va='center',
95 fig.text(0.01, 0.5, text, ha='left', va='center',
93 size='20', weight='heavy', color='w')
96 size='20', weight='heavy', color='w')
94 fig.show()
97 fig.show()
95 figpause(1000)
98 figpause(1000)
96
99
97
100
98 class Throttle(object):
101 class Throttle(object):
99 '''
102 '''
100 Decorator that prevents a function from being called more than once every
103 Decorator that prevents a function from being called more than once every
101 time period.
104 time period.
102 To create a function that cannot be called more than once a minute, but
105 To create a function that cannot be called more than once a minute, but
103 will sleep until it can be called:
106 will sleep until it can be called:
104 @Throttle(minutes=1)
107 @Throttle(minutes=1)
105 def foo():
108 def foo():
106 pass
109 pass
107
110
108 for i in range(10):
111 for i in range(10):
109 foo()
112 foo()
110 print "This function has run %s times." % i
113 print "This function has run %s times." % i
111 '''
114 '''
112
115
113 def __init__(self, seconds=0, minutes=0, hours=0):
116 def __init__(self, seconds=0, minutes=0, hours=0):
114 self.throttle_period = datetime.timedelta(
117 self.throttle_period = datetime.timedelta(
115 seconds=seconds, minutes=minutes, hours=hours
118 seconds=seconds, minutes=minutes, hours=hours
116 )
119 )
117
120
118 self.time_of_last_call = datetime.datetime.min
121 self.time_of_last_call = datetime.datetime.min
119
122
120 def __call__(self, fn):
123 def __call__(self, fn):
121 @wraps(fn)
124 @wraps(fn)
122 def wrapper(*args, **kwargs):
125 def wrapper(*args, **kwargs):
123 coerce = kwargs.pop('coerce', None)
126 coerce = kwargs.pop('coerce', None)
124 if coerce:
127 if coerce:
125 self.time_of_last_call = datetime.datetime.now()
128 self.time_of_last_call = datetime.datetime.now()
126 return fn(*args, **kwargs)
129 return fn(*args, **kwargs)
127 else:
130 else:
128 now = datetime.datetime.now()
131 now = datetime.datetime.now()
129 time_since_last_call = now - self.time_of_last_call
132 time_since_last_call = now - self.time_of_last_call
130 time_left = self.throttle_period - time_since_last_call
133 time_left = self.throttle_period - time_since_last_call
131
134
132 if time_left > datetime.timedelta(seconds=0):
135 if time_left > datetime.timedelta(seconds=0):
133 return
136 return
134
137
135 self.time_of_last_call = datetime.datetime.now()
138 self.time_of_last_call = datetime.datetime.now()
136 return fn(*args, **kwargs)
139 return fn(*args, **kwargs)
137
140
138 return wrapper
141 return wrapper
139
142
140 def apply_throttle(value):
143 def apply_throttle(value):
141
144
142 @Throttle(seconds=value)
145 @Throttle(seconds=value)
143 def fnThrottled(fn):
146 def fnThrottled(fn):
144 fn()
147 fn()
145
148
146 return fnThrottled
149 return fnThrottled
147
150
148
151
149 @MPDecorator
152 @MPDecorator
150 class Plot(Operation):
153 class Plot(Operation):
151 """Base class for Schain plotting operations
154 """Base class for Schain plotting operations
152
155
153 This class should never be use directtly you must subclass a new operation,
156 This class should never be use directtly you must subclass a new operation,
154 children classes must be defined as follow:
157 children classes must be defined as follow:
155
158
156 ExamplePlot(Plot):
159 ExamplePlot(Plot):
157
160
158 CODE = 'code'
161 CODE = 'code'
159 colormap = 'jet'
162 colormap = 'jet'
160 plot_type = 'pcolor' # options are ('pcolor', 'pcolorbuffer', 'scatter', 'scatterbuffer')
163 plot_type = 'pcolor' # options are ('pcolor', 'pcolorbuffer', 'scatter', 'scatterbuffer')
161
164
162 def setup(self):
165 def setup(self):
163 pass
166 pass
164
167
165 def plot(self):
168 def plot(self):
166 pass
169 pass
167
170
168 """
171 """
169
172
170 CODE = 'Figure'
173 CODE = 'Figure'
171 colormap = 'jet'
174 colormap = 'jet'
172 bgcolor = 'white'
175 bgcolor = 'white'
173 buffering = True
176 buffering = True
174 __missing = 1E30
177 __missing = 1E30
175
178
176 __attrs__ = ['show', 'save', 'ymin', 'ymax', 'zmin', 'zmax', 'title',
179 __attrs__ = ['show', 'save', 'ymin', 'ymax', 'zmin', 'zmax', 'title',
177 'showprofile']
180 'showprofile']
178
181
179 def __init__(self):
182 def __init__(self):
180
183
181 Operation.__init__(self)
184 Operation.__init__(self)
182 self.isConfig = False
185 self.isConfig = False
183 self.isPlotConfig = False
186 self.isPlotConfig = False
184 self.save_time = 0
187 self.save_time = 0
185 self.sender_time = 0
188 self.sender_time = 0
186 self.data = None
189 self.data = None
187 self.firsttime = True
190 self.firsttime = True
188 self.sender_queue = deque(maxlen=10)
191 self.sender_queue = deque(maxlen=10)
189 self.plots_adjust = {'left': 0.125, 'right': 0.9, 'bottom': 0.15, 'top': 0.9, 'wspace': 0.2, 'hspace': 0.2}
192 self.plots_adjust = {'left': 0.125, 'right': 0.9, 'bottom': 0.15, 'top': 0.9, 'wspace': 0.2, 'hspace': 0.2}
190
193
191 def __fmtTime(self, x, pos):
194 def __fmtTime(self, x, pos):
192 '''
195 '''
193 '''
196 '''
194
197
195 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
198 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
196
199
197 def __setup(self, **kwargs):
200 def __setup(self, **kwargs):
198 '''
201 '''
199 Initialize variables
202 Initialize variables
200 '''
203 '''
201
204
202 self.figures = []
205 self.figures = []
203 self.axes = []
206 self.axes = []
204 self.cb_axes = []
207 self.cb_axes = []
205 self.localtime = kwargs.pop('localtime', True)
208 self.localtime = kwargs.pop('localtime', True)
206 self.show = kwargs.get('show', True)
209 self.show = kwargs.get('show', True)
207 self.save = kwargs.get('save', False)
210 self.save = kwargs.get('save', False)
208 self.save_period = kwargs.get('save_period', 0)
211 self.save_period = kwargs.get('save_period', 0)
209 self.colormap = kwargs.get('colormap', self.colormap)
212 self.colormap = kwargs.get('colormap', self.colormap)
210 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
213 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
211 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
214 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
212 self.colormaps = kwargs.get('colormaps', None)
215 self.colormaps = kwargs.get('colormaps', None)
213 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
216 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
214 self.showprofile = kwargs.get('showprofile', False)
217 self.showprofile = kwargs.get('showprofile', False)
215 self.title = kwargs.get('wintitle', self.CODE.upper())
218 self.title = kwargs.get('wintitle', self.CODE.upper())
216 self.cb_label = kwargs.get('cb_label', None)
219 self.cb_label = kwargs.get('cb_label', None)
217 self.cb_labels = kwargs.get('cb_labels', None)
220 self.cb_labels = kwargs.get('cb_labels', None)
218 self.labels = kwargs.get('labels', None)
221 self.labels = kwargs.get('labels', None)
219 self.xaxis = kwargs.get('xaxis', 'frequency')
222 self.xaxis = kwargs.get('xaxis', 'frequency')
220 self.zmin = kwargs.get('zmin', None)
223 self.zmin = kwargs.get('zmin', None)
221 self.zmax = kwargs.get('zmax', None)
224 self.zmax = kwargs.get('zmax', None)
222 self.zlimits = kwargs.get('zlimits', None)
225 self.zlimits = kwargs.get('zlimits', None)
223 self.xmin = kwargs.get('xmin', None)
226 self.xmin = kwargs.get('xmin', None)
224 self.xmax = kwargs.get('xmax', None)
227 self.xmax = kwargs.get('xmax', None)
225 self.xrange = kwargs.get('xrange', 12)
228 self.xrange = kwargs.get('xrange', 12)
226 self.xscale = kwargs.get('xscale', None)
229 self.xscale = kwargs.get('xscale', None)
227 self.ymin = kwargs.get('ymin', None)
230 self.ymin = kwargs.get('ymin', None)
228 self.ymax = kwargs.get('ymax', None)
231 self.ymax = kwargs.get('ymax', None)
229 self.yscale = kwargs.get('yscale', None)
232 self.yscale = kwargs.get('yscale', None)
230 self.xlabel = kwargs.get('xlabel', None)
233 self.xlabel = kwargs.get('xlabel', None)
231 self.attr_time = kwargs.get('attr_time', 'utctime')
234 self.attr_time = kwargs.get('attr_time', 'utctime')
232 self.attr_data = kwargs.get('attr_data', 'data_param')
235 self.attr_data = kwargs.get('attr_data', 'data_param')
233 self.decimation = kwargs.get('decimation', None)
236 self.decimation = kwargs.get('decimation', None)
234 self.oneFigure = kwargs.get('oneFigure', True)
237 self.oneFigure = kwargs.get('oneFigure', True)
235 self.width = kwargs.get('width', None)
238 self.width = kwargs.get('width', None)
236 self.height = kwargs.get('height', None)
239 self.height = kwargs.get('height', None)
237 self.colorbar = kwargs.get('colorbar', True)
240 self.colorbar = kwargs.get('colorbar', True)
238 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
241 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
239 self.channels = kwargs.get('channels', None)
242 self.channels = kwargs.get('channels', None)
240 self.titles = kwargs.get('titles', [])
243 self.titles = kwargs.get('titles', [])
241 self.polar = False
244 self.polar = False
242 self.type = kwargs.get('type', 'iq')
245 self.type = kwargs.get('type', 'iq')
243 self.grid = kwargs.get('grid', False)
246 self.grid = kwargs.get('grid', False)
244 self.pause = kwargs.get('pause', False)
247 self.pause = kwargs.get('pause', False)
245 self.save_code = kwargs.get('save_code', self.CODE)
248 self.save_code = kwargs.get('save_code', self.CODE)
246 self.throttle = kwargs.get('throttle', 0)
249 self.throttle = kwargs.get('throttle', 0)
247 self.exp_code = kwargs.get('exp_code', None)
250 self.exp_code = kwargs.get('exp_code', None)
248 self.server = kwargs.get('server', False)
251 self.server = kwargs.get('server', False)
249 self.sender_period = kwargs.get('sender_period', 60)
252 self.sender_period = kwargs.get('sender_period', 60)
250 self.tag = kwargs.get('tag', '')
253 self.tag = kwargs.get('tag', '')
251 self.height_index = kwargs.get('height_index', None)
254 self.height_index = kwargs.get('height_index', None)
252 self.__throttle_plot = apply_throttle(self.throttle)
255 self.__throttle_plot = apply_throttle(self.throttle)
253 code = self.attr_data if self.attr_data else self.CODE
256 code = self.attr_data if self.attr_data else self.CODE
254 self.data = PlotterData(self.CODE, self.exp_code, self.localtime)
257 self.data = PlotterData(self.CODE, self.exp_code, self.localtime)
255 self.ang_min = kwargs.get('ang_min', None)
258 self.ang_min = kwargs.get('ang_min', None)
256 self.ang_max = kwargs.get('ang_max', None)
259 self.ang_max = kwargs.get('ang_max', None)
257 self.mode = kwargs.get('mode', None)
260 self.mode = kwargs.get('mode', None)
258
261
259
262
260
263
261 if self.server:
264 if self.server:
262 if not self.server.startswith('tcp://'):
265 if not self.server.startswith('tcp://'):
263 self.server = 'tcp://{}'.format(self.server)
266 self.server = 'tcp://{}'.format(self.server)
264 log.success(
267 log.success(
265 'Sending to server: {}'.format(self.server),
268 'Sending to server: {}'.format(self.server),
266 self.name
269 self.name
267 )
270 )
268
271
269 if isinstance(self.attr_data, str):
272 if isinstance(self.attr_data, str):
270 self.attr_data = [self.attr_data]
273 self.attr_data = [self.attr_data]
271
274
272 def __setup_plot(self):
275 def __setup_plot(self):
273 '''
276 '''
274 Common setup for all figures, here figures and axes are created
277 Common setup for all figures, here figures and axes are created
275 '''
278 '''
276
279
277 self.setup()
280 self.setup()
278
281
279 self.time_label = 'LT' if self.localtime else 'UTC'
282 self.time_label = 'LT' if self.localtime else 'UTC'
280
283
281 if self.width is None:
284 if self.width is None:
282 self.width = 8
285 self.width = 8
283
286
284 self.figures = []
287 self.figures = []
285 self.axes = []
288 self.axes = []
286 self.cb_axes = []
289 self.cb_axes = []
287 self.pf_axes = []
290 self.pf_axes = []
288 self.cmaps = []
291 self.cmaps = []
289
292
290 size = '15%' if self.ncols == 1 else '30%'
293 size = '15%' if self.ncols == 1 else '30%'
291 pad = '4%' if self.ncols == 1 else '8%'
294 pad = '4%' if self.ncols == 1 else '8%'
292
295
293 if self.oneFigure:
296 if self.oneFigure:
294 if self.height is None:
297 if self.height is None:
295 self.height = 1.4 * self.nrows + 1
298 self.height = 1.4 * self.nrows + 1
296 fig = plt.figure(figsize=(self.width, self.height),
299 fig = plt.figure(figsize=(self.width, self.height),
297 edgecolor='k',
300 edgecolor='k',
298 facecolor='w')
301 facecolor='w')
299 self.figures.append(fig)
302 self.figures.append(fig)
300 for n in range(self.nplots):
303 for n in range(self.nplots):
301 ax = fig.add_subplot(self.nrows, self.ncols,
304 ax = fig.add_subplot(self.nrows, self.ncols,
302 n + 1, polar=self.polar)
305 n + 1, polar=self.polar)
303 ax.tick_params(labelsize=8)
306 ax.tick_params(labelsize=8)
304 ax.firsttime = True
307 ax.firsttime = True
305 ax.index = 0
308 ax.index = 0
306 ax.press = None
309 ax.press = None
307 self.axes.append(ax)
310 self.axes.append(ax)
308 if self.showprofile:
311 if self.showprofile:
309 cax = self.__add_axes(ax, size=size, pad=pad)
312 cax = self.__add_axes(ax, size=size, pad=pad)
310 cax.tick_params(labelsize=8)
313 cax.tick_params(labelsize=8)
311 self.pf_axes.append(cax)
314 self.pf_axes.append(cax)
312 else:
315 else:
313 if self.height is None:
316 if self.height is None:
314 self.height = 3
317 self.height = 3
315 for n in range(self.nplots):
318 for n in range(self.nplots):
316 fig = plt.figure(figsize=(self.width, self.height),
319 fig = plt.figure(figsize=(self.width, self.height),
317 edgecolor='k',
320 edgecolor='k',
318 facecolor='w')
321 facecolor='w')
319 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
322 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
320 ax.tick_params(labelsize=8)
323 ax.tick_params(labelsize=8)
321 ax.firsttime = True
324 ax.firsttime = True
322 ax.index = 0
325 ax.index = 0
323 ax.press = None
326 ax.press = None
324 self.figures.append(fig)
327 self.figures.append(fig)
325 self.axes.append(ax)
328 self.axes.append(ax)
326 if self.showprofile:
329 if self.showprofile:
327 cax = self.__add_axes(ax, size=size, pad=pad)
330 cax = self.__add_axes(ax, size=size, pad=pad)
328 cax.tick_params(labelsize=8)
331 cax.tick_params(labelsize=8)
329 self.pf_axes.append(cax)
332 self.pf_axes.append(cax)
330
333
331 for n in range(self.nrows):
334 for n in range(self.nrows):
332 if self.colormaps is not None:
335 if self.colormaps is not None:
333 cmap = plt.get_cmap(self.colormaps[n])
336 cmap = plt.get_cmap(self.colormaps[n])
334 else:
337 else:
335 cmap = plt.get_cmap(self.colormap)
338 cmap = plt.get_cmap(self.colormap)
336 cmap.set_bad(self.bgcolor, 1.)
339 cmap.set_bad(self.bgcolor, 1.)
337 self.cmaps.append(cmap)
340 self.cmaps.append(cmap)
338
341
339 def __add_axes(self, ax, size='30%', pad='8%'):
342 def __add_axes(self, ax, size='30%', pad='8%'):
340 '''
343 '''
341 Add new axes to the given figure
344 Add new axes to the given figure
342 '''
345 '''
343 divider = make_axes_locatable(ax)
346 divider = make_axes_locatable(ax)
344 nax = divider.new_horizontal(size=size, pad=pad)
347 nax = divider.new_horizontal(size=size, pad=pad)
345 ax.figure.add_axes(nax)
348 ax.figure.add_axes(nax)
346 return nax
349 return nax
347
350
348 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
351 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
349 '''
352 '''
350 Create a masked array for missing data
353 Create a masked array for missing data
351 '''
354 '''
352 if x_buffer.shape[0] < 2:
355 if x_buffer.shape[0] < 2:
353 return x_buffer, y_buffer, z_buffer
356 return x_buffer, y_buffer, z_buffer
354
357
355 deltas = x_buffer[1:] - x_buffer[0:-1]
358 deltas = x_buffer[1:] - x_buffer[0:-1]
356 x_median = numpy.median(deltas)
359 x_median = numpy.median(deltas)
357
360
358 index = numpy.where(deltas > 5 * x_median)
361 index = numpy.where(deltas > 5 * x_median)
359
362
360 if len(index[0]) != 0:
363 if len(index[0]) != 0:
361 z_buffer[::, index[0], ::] = self.__missing
364 z_buffer[::, index[0], ::] = self.__missing
362 z_buffer = numpy.ma.masked_inside(z_buffer,
365 z_buffer = numpy.ma.masked_inside(z_buffer,
363 0.99 * self.__missing,
366 0.99 * self.__missing,
364 1.01 * self.__missing)
367 1.01 * self.__missing)
365
368
366 return x_buffer, y_buffer, z_buffer
369 return x_buffer, y_buffer, z_buffer
367
370
368 def decimate(self):
371 def decimate(self):
369
372
370 # dx = int(len(self.x)/self.__MAXNUMX) + 1
373 # dx = int(len(self.x)/self.__MAXNUMX) + 1
371 dy = int(len(self.y) / self.decimation) + 1
374 dy = int(len(self.y) / self.decimation) + 1
372
375
373 # x = self.x[::dx]
376 # x = self.x[::dx]
374 x = self.x
377 x = self.x
375 y = self.y[::dy]
378 y = self.y[::dy]
376 z = self.z[::, ::, ::dy]
379 z = self.z[::, ::, ::dy]
377
380
378 return x, y, z
381 return x, y, z
379
382
380 def format(self):
383 def format(self):
381 '''
384 '''
382 Set min and max values, labels, ticks and titles
385 Set min and max values, labels, ticks and titles
383 '''
386 '''
384
387
385 for n, ax in enumerate(self.axes):
388 for n, ax in enumerate(self.axes):
386 if ax.firsttime:
389 if ax.firsttime:
387 if self.xaxis != 'time':
390 if self.xaxis != 'time':
388 xmin = self.xmin
391 xmin = self.xmin
389 xmax = self.xmax
392 xmax = self.xmax
390 else:
393 else:
391 xmin = self.tmin
394 xmin = self.tmin
392 xmax = self.tmin + self.xrange*60*60
395 xmax = self.tmin + self.xrange*60*60
393 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
396 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
394 ax.xaxis.set_major_locator(LinearLocator(9))
397 ax.xaxis.set_major_locator(LinearLocator(9))
395 ymin = self.ymin if self.ymin is not None else numpy.nanmin(self.y[numpy.isfinite(self.y)])
398 ymin = self.ymin if self.ymin is not None else numpy.nanmin(self.y[numpy.isfinite(self.y)])
396 ymax = self.ymax if self.ymax is not None else numpy.nanmax(self.y[numpy.isfinite(self.y)])
399 ymax = self.ymax if self.ymax is not None else numpy.nanmax(self.y[numpy.isfinite(self.y)])
397 ax.set_facecolor(self.bgcolor)
400 ax.set_facecolor(self.bgcolor)
398 if self.xscale:
401 if self.xscale:
399 ax.xaxis.set_major_formatter(FuncFormatter(
402 ax.xaxis.set_major_formatter(FuncFormatter(
400 lambda x, pos: '{0:g}'.format(x*self.xscale)))
403 lambda x, pos: '{0:g}'.format(x*self.xscale)))
401 if self.yscale:
404 if self.yscale:
402 ax.yaxis.set_major_formatter(FuncFormatter(
405 ax.yaxis.set_major_formatter(FuncFormatter(
403 lambda x, pos: '{0:g}'.format(x*self.yscale)))
406 lambda x, pos: '{0:g}'.format(x*self.yscale)))
404 if self.xlabel is not None:
407 if self.xlabel is not None:
405 ax.set_xlabel(self.xlabel)
408 ax.set_xlabel(self.xlabel)
406 if self.ylabel is not None:
409 if self.ylabel is not None:
407 ax.set_ylabel(self.ylabel)
410 ax.set_ylabel(self.ylabel)
408 if self.showprofile:
411 if self.showprofile:
409 self.pf_axes[n].set_ylim(ymin, ymax)
412 self.pf_axes[n].set_ylim(ymin, ymax)
410 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
413 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
411 self.pf_axes[n].set_xlabel('dB')
414 self.pf_axes[n].set_xlabel('dB')
412 self.pf_axes[n].grid(b=True, axis='x')
415 self.pf_axes[n].grid(b=True, axis='x')
413 [tick.set_visible(False)
416 [tick.set_visible(False)
414 for tick in self.pf_axes[n].get_yticklabels()]
417 for tick in self.pf_axes[n].get_yticklabels()]
415 if self.colorbar:
418 if self.colorbar:
416 ax.cbar = plt.colorbar(
419 ax.cbar = plt.colorbar(
417 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
420 ax.plt, ax=ax, fraction=0.05, pad=0.06, aspect=10)
418 ax.cbar.ax.tick_params(labelsize=8)
421 ax.cbar.ax.tick_params(labelsize=8)
419 ax.cbar.ax.press = None
422 ax.cbar.ax.press = None
420 if self.cb_label:
423 if self.cb_label:
421 ax.cbar.set_label(self.cb_label, size=8)
424 ax.cbar.set_label(self.cb_label, size=8)
422 elif self.cb_labels:
425 elif self.cb_labels:
423 ax.cbar.set_label(self.cb_labels[n], size=8)
426 ax.cbar.set_label(self.cb_labels[n], size=8)
424 else:
427 else:
425 ax.cbar = None
428 ax.cbar = None
426 ax.set_xlim(xmin, xmax)
429 ax.set_xlim(xmin, xmax)
427 ax.set_ylim(ymin, ymax)
430 ax.set_ylim(ymin, ymax)
428 ax.firsttime = False
431 ax.firsttime = False
429 if self.grid:
432 if self.grid:
430 ax.grid(True)
433 ax.grid(True)
431 if not self.polar:
434 if not self.polar:
432 ax.set_title('{} {} {}'.format(
435 ax.set_title('{} {} {}'.format(
433 self.titles[n],
436 self.titles[n],
434 self.getDateTime(self.data.max_time).strftime(
437 self.getDateTime(self.data.max_time).strftime(
435 '%Y-%m-%d %H:%M:%S'),
438 '%Y-%m-%d %H:%M:%S'),
436 self.time_label),
439 self.time_label),
437 size=8)
440 size=8)
438 else:
441 else:
439 #ax.set_title('{}'.format(self.titles[n]), size=8)
442 #ax.set_title('{}'.format(self.titles[n]), size=8)
440 ax.set_title('{} {} {}'.format(
443 ax.set_title('{} {} {}'.format(
441 self.titles[n],
444 self.titles[n],
442 self.getDateTime(self.data.max_time).strftime(
445 self.getDateTime(self.data.max_time).strftime(
443 '%Y-%m-%d %H:%M:%S'),
446 '%Y-%m-%d %H:%M:%S'),
444 self.time_label),
447 self.time_label),
445 size=8)
448 size=8)
446 ax.set_ylim(0, self.ymax)
449 ax.set_ylim(0, self.ymax)
447 #ax.set_yticks(numpy.arange(0, self.ymax, 20))
450 #ax.set_yticks(numpy.arange(0, self.ymax, 20))
448 ax.yaxis.labelpad = 20
451 ax.yaxis.labelpad = 28
449
452
450 if self.firsttime:
453 if self.firsttime:
451 for n, fig in enumerate(self.figures):
454 for n, fig in enumerate(self.figures):
452 fig.subplots_adjust(**self.plots_adjust)
455 fig.subplots_adjust(**self.plots_adjust)
453 self.firsttime = False
456 self.firsttime = False
454
457
455 def clear_figures(self):
458 def clear_figures(self):
456 '''
459 '''
457 Reset axes for redraw plots
460 Reset axes for redraw plots
458 '''
461 '''
459
462
460 for ax in self.axes+self.pf_axes+self.cb_axes:
463 for ax in self.axes+self.pf_axes+self.cb_axes:
461 ax.clear()
464 ax.clear()
462 ax.firsttime = True
465 ax.firsttime = True
463 if hasattr(ax, 'cbar') and ax.cbar:
466 if hasattr(ax, 'cbar') and ax.cbar:
464 ax.cbar.remove()
467 ax.cbar.remove()
465
468
466 def __plot(self):
469 def __plot(self):
467 '''
470 '''
468 Main function to plot, format and save figures
471 Main function to plot, format and save figures
469 '''
472 '''
470
473
471 self.plot()
474 self.plot()
472 self.format()
475 self.format()
473
476
474 for n, fig in enumerate(self.figures):
477 for n, fig in enumerate(self.figures):
475 if self.nrows == 0 or self.nplots == 0:
478 if self.nrows == 0 or self.nplots == 0:
476 log.warning('No data', self.name)
479 log.warning('No data', self.name)
477 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
480 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
478 fig.canvas.manager.set_window_title(self.CODE)
481 fig.canvas.manager.set_window_title(self.CODE)
479 continue
482 continue
480
483
481 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
484 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
482 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
485 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
483 fig.canvas.draw()
486 fig.canvas.draw()
484 if self.show:
487 if self.show:
485 fig.show()
488 fig.show()
486 figpause(0.01)
489 figpause(0.01)
487
490
488 if self.save:
491 if self.save:
489 self.save_figure(n)
492 if self.CODE=="PPI" or self.CODE=="RHI":
493 self.save_figure(n,stitle =self.titles)
494 else:
495 self.save_figure(n)
490
496
491 if self.server:
497 if self.server:
492 self.send_to_server()
498 self.send_to_server()
493
499
494 def __update(self, dataOut, timestamp):
500 def __update(self, dataOut, timestamp):
495 '''
501 '''
496 '''
502 '''
497
503
498 metadata = {
504 metadata = {
499 'yrange': dataOut.heightList,
505 'yrange': dataOut.heightList,
500 'interval': dataOut.timeInterval,
506 'interval': dataOut.timeInterval,
501 'channels': dataOut.channelList
507 'channels': dataOut.channelList
502 }
508 }
503
509
504 data, meta = self.update(dataOut)
510 data, meta = self.update(dataOut)
505 metadata.update(meta)
511 metadata.update(meta)
506 self.data.update(data, timestamp, metadata)
512 self.data.update(data, timestamp, metadata)
507
513
508 def save_figure(self, n):
514 def save_figure(self, n,stitle=None):
509 '''
515 '''
510 '''
516 '''
517 if stitle is not None:
518 s_string = re.sub(r"[^A-Z0-9.]","",str(stitle))
519 new_string=s_string[:3]+"_"+"_"+s_string[4:6]+"_"+s_string[6:]
520
511 if self.oneFigure:
521 if self.oneFigure:
512 if (self.data.max_time - self.save_time) <= self.save_period:
522 if (self.data.max_time - self.save_time) <= self.save_period:
513 return
523 return
514
524
515 self.save_time = self.data.max_time
525 self.save_time = self.data.max_time
516
526
517 fig = self.figures[n]
527 fig = self.figures[n]
518
528
519 if self.throttle == 0:
529 if self.throttle == 0:
520 if self.oneFigure:
530 if self.oneFigure:
521 figname = os.path.join(
531 if stitle is not None:
522 self.save,
532 figname = os.path.join(
523 self.save_code,
533 self.save,
524 '{}_{}.png'.format(
525 self.save_code,
534 self.save_code,
526 self.getDateTime(self.data.max_time).strftime(
535 '{}_{}_{}.png'.format(
527 '%Y%m%d_%H%M%S'
536 self.save_code,
528 ),
537 self.getDateTime(self.data.max_time).strftime(
538 '%Y%m%d_%H%M%S',
539 ),
540 new_string,
541 )
529 )
542 )
530 )
543 else:
544 figname = os.path.join(
545 self.save,
546 self.save_code,
547 '{}_{}.png'.format(
548 self.save_code,
549 self.getDateTime(self.data.max_time).strftime(
550 '%Y%m%d_%H%M%S'
551 ),
552 )
553 )
531 else:
554 else:
532 figname = os.path.join(
555 figname = os.path.join(
533 self.save,
556 self.save,
534 self.save_code,
557 self.save_code,
535 '{}_ch{}_{}.png'.format(
558 '{}_ch{}_{}.png'.format(
536 self.save_code,n,
559 self.save_code,n,
537 self.getDateTime(self.data.max_time).strftime(
560 self.getDateTime(self.data.max_time).strftime(
538 '%Y%m%d_%H%M%S'
561 '%Y%m%d_%H%M%S'
539 ),
562 ),
540 )
563 )
541 )
564 )
542 log.log('Saving figure: {}'.format(figname), self.name)
565 log.log('Saving figure: {}'.format(figname), self.name)
543 if not os.path.isdir(os.path.dirname(figname)):
566 if not os.path.isdir(os.path.dirname(figname)):
544 os.makedirs(os.path.dirname(figname))
567 os.makedirs(os.path.dirname(figname))
545 fig.savefig(figname)
568 fig.savefig(figname)
546
569
547 figname = os.path.join(
570 figname = os.path.join(
548 self.save,
571 self.save,
549 '{}_{}.png'.format(
572 '{}_{}.png'.format(
550 self.save_code,
573 self.save_code,
551 self.getDateTime(self.data.min_time).strftime(
574 self.getDateTime(self.data.min_time).strftime(
552 '%Y%m%d'
575 '%Y%m%d'
553 ),
576 ),
554 )
577 )
555 )
578 )
556
579
557 log.log('Saving figure: {}'.format(figname), self.name)
580 log.log('Saving figure: {}'.format(figname), self.name)
558 if not os.path.isdir(os.path.dirname(figname)):
581 if not os.path.isdir(os.path.dirname(figname)):
559 os.makedirs(os.path.dirname(figname))
582 os.makedirs(os.path.dirname(figname))
560 fig.savefig(figname)
583 fig.savefig(figname)
561
584
562 def send_to_server(self):
585 def send_to_server(self):
563 '''
586 '''
564 '''
587 '''
565
588
566 if self.exp_code == None:
589 if self.exp_code == None:
567 log.warning('Missing `exp_code` skipping sending to server...')
590 log.warning('Missing `exp_code` skipping sending to server...')
568
591
569 last_time = self.data.max_time
592 last_time = self.data.max_time
570 interval = last_time - self.sender_time
593 interval = last_time - self.sender_time
571 if interval < self.sender_period:
594 if interval < self.sender_period:
572 return
595 return
573
596
574 self.sender_time = last_time
597 self.sender_time = last_time
575
598
576 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
599 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
577 for attr in attrs:
600 for attr in attrs:
578 value = getattr(self, attr)
601 value = getattr(self, attr)
579 if value:
602 if value:
580 if isinstance(value, (numpy.float32, numpy.float64)):
603 if isinstance(value, (numpy.float32, numpy.float64)):
581 value = round(float(value), 2)
604 value = round(float(value), 2)
582 self.data.meta[attr] = value
605 self.data.meta[attr] = value
583 if self.colormap == 'jet':
606 if self.colormap == 'jet':
584 self.data.meta['colormap'] = 'Jet'
607 self.data.meta['colormap'] = 'Jet'
585 elif 'RdBu' in self.colormap:
608 elif 'RdBu' in self.colormap:
586 self.data.meta['colormap'] = 'RdBu'
609 self.data.meta['colormap'] = 'RdBu'
587 else:
610 else:
588 self.data.meta['colormap'] = 'Viridis'
611 self.data.meta['colormap'] = 'Viridis'
589 self.data.meta['interval'] = int(interval)
612 self.data.meta['interval'] = int(interval)
590
613
591 self.sender_queue.append(last_time)
614 self.sender_queue.append(last_time)
592
615
593 while True:
616 while True:
594 try:
617 try:
595 tm = self.sender_queue.popleft()
618 tm = self.sender_queue.popleft()
596 except IndexError:
619 except IndexError:
597 break
620 break
598 msg = self.data.jsonify(tm, self.save_code, self.plot_type)
621 msg = self.data.jsonify(tm, self.save_code, self.plot_type)
599 self.socket.send_string(msg)
622 self.socket.send_string(msg)
600 socks = dict(self.poll.poll(2000))
623 socks = dict(self.poll.poll(2000))
601 if socks.get(self.socket) == zmq.POLLIN:
624 if socks.get(self.socket) == zmq.POLLIN:
602 reply = self.socket.recv_string()
625 reply = self.socket.recv_string()
603 if reply == 'ok':
626 if reply == 'ok':
604 log.log("Response from server ok", self.name)
627 log.log("Response from server ok", self.name)
605 time.sleep(0.1)
628 time.sleep(0.1)
606 continue
629 continue
607 else:
630 else:
608 log.warning(
631 log.warning(
609 "Malformed reply from server: {}".format(reply), self.name)
632 "Malformed reply from server: {}".format(reply), self.name)
610 else:
633 else:
611 log.warning(
634 log.warning(
612 "No response from server, retrying...", self.name)
635 "No response from server, retrying...", self.name)
613 self.sender_queue.appendleft(tm)
636 self.sender_queue.appendleft(tm)
614 self.socket.setsockopt(zmq.LINGER, 0)
637 self.socket.setsockopt(zmq.LINGER, 0)
615 self.socket.close()
638 self.socket.close()
616 self.poll.unregister(self.socket)
639 self.poll.unregister(self.socket)
617 self.socket = self.context.socket(zmq.REQ)
640 self.socket = self.context.socket(zmq.REQ)
618 self.socket.connect(self.server)
641 self.socket.connect(self.server)
619 self.poll.register(self.socket, zmq.POLLIN)
642 self.poll.register(self.socket, zmq.POLLIN)
620 break
643 break
621
644
622 def setup(self):
645 def setup(self):
623 '''
646 '''
624 This method should be implemented in the child class, the following
647 This method should be implemented in the child class, the following
625 attributes should be set:
648 attributes should be set:
626
649
627 self.nrows: number of rows
650 self.nrows: number of rows
628 self.ncols: number of cols
651 self.ncols: number of cols
629 self.nplots: number of plots (channels or pairs)
652 self.nplots: number of plots (channels or pairs)
630 self.ylabel: label for Y axes
653 self.ylabel: label for Y axes
631 self.titles: list of axes title
654 self.titles: list of axes title
632
655
633 '''
656 '''
634 raise NotImplementedError
657 raise NotImplementedError
635
658
636 def plot(self):
659 def plot(self):
637 '''
660 '''
638 Must be defined in the child class, the actual plotting method
661 Must be defined in the child class, the actual plotting method
639 '''
662 '''
640 raise NotImplementedError
663 raise NotImplementedError
641
664
642 def update(self, dataOut):
665 def update(self, dataOut):
643 '''
666 '''
644 Must be defined in the child class, update self.data with new data
667 Must be defined in the child class, update self.data with new data
645 '''
668 '''
646
669
647 data = {
670 data = {
648 self.CODE: getattr(dataOut, 'data_{}'.format(self.CODE))
671 self.CODE: getattr(dataOut, 'data_{}'.format(self.CODE))
649 }
672 }
650 meta = {}
673 meta = {}
651
674
652 return data, meta
675 return data, meta
653
676
654 def run(self, dataOut, **kwargs):
677 def run(self, dataOut, **kwargs):
655 '''
678 '''
656 Main plotting routine
679 Main plotting routine
657 '''
680 '''
658
681
659 if self.isConfig is False:
682 if self.isConfig is False:
660 self.__setup(**kwargs)
683 self.__setup(**kwargs)
661
684
662 if self.localtime:
685 if self.localtime:
663 self.getDateTime = datetime.datetime.fromtimestamp
686 self.getDateTime = datetime.datetime.fromtimestamp
664 else:
687 else:
665 self.getDateTime = datetime.datetime.utcfromtimestamp
688 self.getDateTime = datetime.datetime.utcfromtimestamp
666
689
667 self.data.setup()
690 self.data.setup()
668 self.isConfig = True
691 self.isConfig = True
669 if self.server:
692 if self.server:
670 self.context = zmq.Context()
693 self.context = zmq.Context()
671 self.socket = self.context.socket(zmq.REQ)
694 self.socket = self.context.socket(zmq.REQ)
672 self.socket.connect(self.server)
695 self.socket.connect(self.server)
673 self.poll = zmq.Poller()
696 self.poll = zmq.Poller()
674 self.poll.register(self.socket, zmq.POLLIN)
697 self.poll.register(self.socket, zmq.POLLIN)
675
698
676 tm = getattr(dataOut, self.attr_time)
699 tm = getattr(dataOut, self.attr_time)
677
700
678 if self.data and 'time' in self.xaxis and (tm - self.tmin) >= self.xrange*60*60:
701 if self.data and 'time' in self.xaxis and (tm - self.tmin) >= self.xrange*60*60:
679 self.save_time = tm
702 self.save_time = tm
680 self.__plot()
703 self.__plot()
681 self.tmin += self.xrange*60*60
704 self.tmin += self.xrange*60*60
682 self.data.setup()
705 self.data.setup()
683 self.clear_figures()
706 self.clear_figures()
684
707
685 self.__update(dataOut, tm)
708 self.__update(dataOut, tm)
686
709
687 if self.isPlotConfig is False:
710 if self.isPlotConfig is False:
688 self.__setup_plot()
711 self.__setup_plot()
689 self.isPlotConfig = True
712 self.isPlotConfig = True
690 if self.xaxis == 'time':
713 if self.xaxis == 'time':
691 dt = self.getDateTime(tm)
714 dt = self.getDateTime(tm)
692 if self.xmin is None:
715 if self.xmin is None:
693 self.tmin = tm
716 self.tmin = tm
694 self.xmin = dt.hour
717 self.xmin = dt.hour
695 minutes = (self.xmin-int(self.xmin)) * 60
718 minutes = (self.xmin-int(self.xmin)) * 60
696 seconds = (minutes - int(minutes)) * 60
719 seconds = (minutes - int(minutes)) * 60
697 self.tmin = (dt.replace(hour=int(self.xmin), minute=int(minutes), second=int(seconds)) -
720 self.tmin = (dt.replace(hour=int(self.xmin), minute=int(minutes), second=int(seconds)) -
698 datetime.datetime(1970, 1, 1)).total_seconds()
721 datetime.datetime(1970, 1, 1)).total_seconds()
699 if self.localtime:
722 if self.localtime:
700 self.tmin += time.timezone
723 self.tmin += time.timezone
701
724
702 if self.xmin is not None and self.xmax is not None:
725 if self.xmin is not None and self.xmax is not None:
703 self.xrange = self.xmax - self.xmin
726 self.xrange = self.xmax - self.xmin
704
727
705 if self.throttle == 0:
728 if self.throttle == 0:
706 self.__plot()
729 self.__plot()
707 else:
730 else:
708 self.__throttle_plot(self.__plot)#, coerce=coerce)
731 self.__throttle_plot(self.__plot)#, coerce=coerce)
709
732
710 def close(self):
733 def close(self):
711
734
712 if self.data and not self.data.flagNoData:
735 if self.data and not self.data.flagNoData:
713 self.save_time = 0
736 self.save_time = 0
714 self.__plot()
737 self.__plot()
715 if self.data and not self.data.flagNoData and self.pause:
738 if self.data and not self.data.flagNoData and self.pause:
716 figpause(10)
739 figpause(10)
@@ -1,1936 +1,1936
1 import os
1 import os
2 import datetime
2 import datetime
3 import numpy
3 import numpy
4 from mpl_toolkits.axisartist.grid_finder import FixedLocator, DictFormatter
4 from mpl_toolkits.axisartist.grid_finder import FixedLocator, DictFormatter
5
5
6 from schainpy.model.graphics.jroplot_base import Plot, plt
6 from schainpy.model.graphics.jroplot_base import Plot, plt
7 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot, SpectraCutPlot
7 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot, SpectraCutPlot
8 from schainpy.utils import log
8 from schainpy.utils import log
9 # libreria wradlib
9 # libreria wradlib
10 #import wradlib as wrl
10 #import wradlib as wrl
11
11
12 EARTH_RADIUS = 6.3710e3
12 EARTH_RADIUS = 6.3710e3
13
13
14
14
15 def ll2xy(lat1, lon1, lat2, lon2):
15 def ll2xy(lat1, lon1, lat2, lon2):
16
16
17 p = 0.017453292519943295
17 p = 0.017453292519943295
18 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
18 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
19 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
19 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
20 r = 12742 * numpy.arcsin(numpy.sqrt(a))
20 r = 12742 * numpy.arcsin(numpy.sqrt(a))
21 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
21 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
22 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
22 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
23 theta = -theta + numpy.pi/2
23 theta = -theta + numpy.pi/2
24 return r*numpy.cos(theta), r*numpy.sin(theta)
24 return r*numpy.cos(theta), r*numpy.sin(theta)
25
25
26
26
27 def km2deg(km):
27 def km2deg(km):
28 '''
28 '''
29 Convert distance in km to degrees
29 Convert distance in km to degrees
30 '''
30 '''
31
31
32 return numpy.rad2deg(km/EARTH_RADIUS)
32 return numpy.rad2deg(km/EARTH_RADIUS)
33
33
34
34
35
35
36 class SpectralMomentsPlot(SpectraPlot):
36 class SpectralMomentsPlot(SpectraPlot):
37 '''
37 '''
38 Plot for Spectral Moments
38 Plot for Spectral Moments
39 '''
39 '''
40 CODE = 'spc_moments'
40 CODE = 'spc_moments'
41 # colormap = 'jet'
41 # colormap = 'jet'
42 # plot_type = 'pcolor'
42 # plot_type = 'pcolor'
43
43
44 class DobleGaussianPlot(SpectraPlot):
44 class DobleGaussianPlot(SpectraPlot):
45 '''
45 '''
46 Plot for Double Gaussian Plot
46 Plot for Double Gaussian Plot
47 '''
47 '''
48 CODE = 'gaussian_fit'
48 CODE = 'gaussian_fit'
49 # colormap = 'jet'
49 # colormap = 'jet'
50 # plot_type = 'pcolor'
50 # plot_type = 'pcolor'
51
51
52 class DoubleGaussianSpectraCutPlot(SpectraCutPlot):
52 class DoubleGaussianSpectraCutPlot(SpectraCutPlot):
53 '''
53 '''
54 Plot SpectraCut with Double Gaussian Fit
54 Plot SpectraCut with Double Gaussian Fit
55 '''
55 '''
56 CODE = 'cut_gaussian_fit'
56 CODE = 'cut_gaussian_fit'
57
57
58 class SnrPlot(RTIPlot):
58 class SnrPlot(RTIPlot):
59 '''
59 '''
60 Plot for SNR Data
60 Plot for SNR Data
61 '''
61 '''
62
62
63 CODE = 'snr'
63 CODE = 'snr'
64 colormap = 'jet'
64 colormap = 'jet'
65
65
66 def update(self, dataOut):
66 def update(self, dataOut):
67
67
68 data = {
68 data = {
69 'snr': 10*numpy.log10(dataOut.data_snr)
69 'snr': 10*numpy.log10(dataOut.data_snr)
70 }
70 }
71
71
72 return data, {}
72 return data, {}
73
73
74 class DopplerPlot(RTIPlot):
74 class DopplerPlot(RTIPlot):
75 '''
75 '''
76 Plot for DOPPLER Data (1st moment)
76 Plot for DOPPLER Data (1st moment)
77 '''
77 '''
78
78
79 CODE = 'dop'
79 CODE = 'dop'
80 colormap = 'jet'
80 colormap = 'jet'
81
81
82 def update(self, dataOut):
82 def update(self, dataOut):
83
83
84 data = {
84 data = {
85 'dop': 10*numpy.log10(dataOut.data_dop)
85 'dop': 10*numpy.log10(dataOut.data_dop)
86 }
86 }
87
87
88 return data, {}
88 return data, {}
89
89
90 class PowerPlot(RTIPlot):
90 class PowerPlot(RTIPlot):
91 '''
91 '''
92 Plot for Power Data (0 moment)
92 Plot for Power Data (0 moment)
93 '''
93 '''
94
94
95 CODE = 'pow'
95 CODE = 'pow'
96 colormap = 'jet'
96 colormap = 'jet'
97
97
98 def update(self, dataOut):
98 def update(self, dataOut):
99 data = {
99 data = {
100 'pow': 10*numpy.log10(dataOut.data_pow/dataOut.normFactor)
100 'pow': 10*numpy.log10(dataOut.data_pow/dataOut.normFactor)
101 }
101 }
102 return data, {}
102 return data, {}
103
103
104 class SpectralWidthPlot(RTIPlot):
104 class SpectralWidthPlot(RTIPlot):
105 '''
105 '''
106 Plot for Spectral Width Data (2nd moment)
106 Plot for Spectral Width Data (2nd moment)
107 '''
107 '''
108
108
109 CODE = 'width'
109 CODE = 'width'
110 colormap = 'jet'
110 colormap = 'jet'
111
111
112 def update(self, dataOut):
112 def update(self, dataOut):
113
113
114 data = {
114 data = {
115 'width': dataOut.data_width
115 'width': dataOut.data_width
116 }
116 }
117
117
118 return data, {}
118 return data, {}
119
119
120 class SkyMapPlot(Plot):
120 class SkyMapPlot(Plot):
121 '''
121 '''
122 Plot for meteors detection data
122 Plot for meteors detection data
123 '''
123 '''
124
124
125 CODE = 'param'
125 CODE = 'param'
126
126
127 def setup(self):
127 def setup(self):
128
128
129 self.ncols = 1
129 self.ncols = 1
130 self.nrows = 1
130 self.nrows = 1
131 self.width = 7.2
131 self.width = 7.2
132 self.height = 7.2
132 self.height = 7.2
133 self.nplots = 1
133 self.nplots = 1
134 self.xlabel = 'Zonal Zenith Angle (deg)'
134 self.xlabel = 'Zonal Zenith Angle (deg)'
135 self.ylabel = 'Meridional Zenith Angle (deg)'
135 self.ylabel = 'Meridional Zenith Angle (deg)'
136 self.polar = True
136 self.polar = True
137 self.ymin = -180
137 self.ymin = -180
138 self.ymax = 180
138 self.ymax = 180
139 self.colorbar = False
139 self.colorbar = False
140
140
141 def plot(self):
141 def plot(self):
142
142
143 arrayParameters = numpy.concatenate(self.data['param'])
143 arrayParameters = numpy.concatenate(self.data['param'])
144 error = arrayParameters[:, -1]
144 error = arrayParameters[:, -1]
145 indValid = numpy.where(error == 0)[0]
145 indValid = numpy.where(error == 0)[0]
146 finalMeteor = arrayParameters[indValid, :]
146 finalMeteor = arrayParameters[indValid, :]
147 finalAzimuth = finalMeteor[:, 3]
147 finalAzimuth = finalMeteor[:, 3]
148 finalZenith = finalMeteor[:, 4]
148 finalZenith = finalMeteor[:, 4]
149
149
150 x = finalAzimuth * numpy.pi / 180
150 x = finalAzimuth * numpy.pi / 180
151 y = finalZenith
151 y = finalZenith
152
152
153 ax = self.axes[0]
153 ax = self.axes[0]
154
154
155 if ax.firsttime:
155 if ax.firsttime:
156 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
156 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
157 else:
157 else:
158 ax.plot.set_data(x, y)
158 ax.plot.set_data(x, y)
159
159
160 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
160 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
161 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
161 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
162 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
162 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
163 dt2,
163 dt2,
164 len(x))
164 len(x))
165 self.titles[0] = title
165 self.titles[0] = title
166
166
167
167
168 class GenericRTIPlot(Plot):
168 class GenericRTIPlot(Plot):
169 '''
169 '''
170 Plot for data_xxxx object
170 Plot for data_xxxx object
171 '''
171 '''
172
172
173 CODE = 'param'
173 CODE = 'param'
174 colormap = 'viridis'
174 colormap = 'viridis'
175 plot_type = 'pcolorbuffer'
175 plot_type = 'pcolorbuffer'
176
176
177 def setup(self):
177 def setup(self):
178 self.xaxis = 'time'
178 self.xaxis = 'time'
179 self.ncols = 1
179 self.ncols = 1
180 self.nrows = self.data.shape('param')[0]
180 self.nrows = self.data.shape('param')[0]
181 self.nplots = self.nrows
181 self.nplots = self.nrows
182 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
182 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
183
183
184 if not self.xlabel:
184 if not self.xlabel:
185 self.xlabel = 'Time'
185 self.xlabel = 'Time'
186
186
187 self.ylabel = 'Range [km]'
187 self.ylabel = 'Range [km]'
188 if not self.titles:
188 if not self.titles:
189 self.titles = ['Param {}'.format(x) for x in range(self.nrows)]
189 self.titles = ['Param {}'.format(x) for x in range(self.nrows)]
190
190
191 def update(self, dataOut):
191 def update(self, dataOut):
192
192
193 data = {
193 data = {
194 'param' : numpy.concatenate([getattr(dataOut, attr) for attr in self.attr_data], axis=0)
194 'param' : numpy.concatenate([getattr(dataOut, attr) for attr in self.attr_data], axis=0)
195 }
195 }
196
196
197 meta = {}
197 meta = {}
198
198
199 return data, meta
199 return data, meta
200
200
201 def plot(self):
201 def plot(self):
202 # self.data.normalize_heights()
202 # self.data.normalize_heights()
203 self.x = self.data.times
203 self.x = self.data.times
204 self.y = self.data.yrange
204 self.y = self.data.yrange
205 self.z = self.data['param']
205 self.z = self.data['param']
206 self.z = 10*numpy.log10(self.z)
206 self.z = 10*numpy.log10(self.z)
207 self.z = numpy.ma.masked_invalid(self.z)
207 self.z = numpy.ma.masked_invalid(self.z)
208
208
209 if self.decimation is None:
209 if self.decimation is None:
210 x, y, z = self.fill_gaps(self.x, self.y, self.z)
210 x, y, z = self.fill_gaps(self.x, self.y, self.z)
211 else:
211 else:
212 x, y, z = self.fill_gaps(*self.decimate())
212 x, y, z = self.fill_gaps(*self.decimate())
213
213
214 for n, ax in enumerate(self.axes):
214 for n, ax in enumerate(self.axes):
215
215
216 self.zmax = self.zmax if self.zmax is not None else numpy.max(
216 self.zmax = self.zmax if self.zmax is not None else numpy.max(
217 self.z[n])
217 self.z[n])
218 self.zmin = self.zmin if self.zmin is not None else numpy.min(
218 self.zmin = self.zmin if self.zmin is not None else numpy.min(
219 self.z[n])
219 self.z[n])
220
220
221 if ax.firsttime:
221 if ax.firsttime:
222 if self.zlimits is not None:
222 if self.zlimits is not None:
223 self.zmin, self.zmax = self.zlimits[n]
223 self.zmin, self.zmax = self.zlimits[n]
224
224
225 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
225 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
226 vmin=self.zmin,
226 vmin=self.zmin,
227 vmax=self.zmax,
227 vmax=self.zmax,
228 cmap=self.cmaps[n]
228 cmap=self.cmaps[n]
229 )
229 )
230 else:
230 else:
231 if self.zlimits is not None:
231 if self.zlimits is not None:
232 self.zmin, self.zmax = self.zlimits[n]
232 self.zmin, self.zmax = self.zlimits[n]
233 ax.collections.remove(ax.collections[0])
233 ax.collections.remove(ax.collections[0])
234 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
234 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
235 vmin=self.zmin,
235 vmin=self.zmin,
236 vmax=self.zmax,
236 vmax=self.zmax,
237 cmap=self.cmaps[n]
237 cmap=self.cmaps[n]
238 )
238 )
239
239
240
240
241 class PolarMapPlot(Plot):
241 class PolarMapPlot(Plot):
242 '''
242 '''
243 Plot for weather radar
243 Plot for weather radar
244 '''
244 '''
245
245
246 CODE = 'param'
246 CODE = 'param'
247 colormap = 'seismic'
247 colormap = 'seismic'
248
248
249 def setup(self):
249 def setup(self):
250 self.ncols = 1
250 self.ncols = 1
251 self.nrows = 1
251 self.nrows = 1
252 self.width = 9
252 self.width = 9
253 self.height = 8
253 self.height = 8
254 self.mode = self.data.meta['mode']
254 self.mode = self.data.meta['mode']
255 if self.channels is not None:
255 if self.channels is not None:
256 self.nplots = len(self.channels)
256 self.nplots = len(self.channels)
257 self.nrows = len(self.channels)
257 self.nrows = len(self.channels)
258 else:
258 else:
259 self.nplots = self.data.shape(self.CODE)[0]
259 self.nplots = self.data.shape(self.CODE)[0]
260 self.nrows = self.nplots
260 self.nrows = self.nplots
261 self.channels = list(range(self.nplots))
261 self.channels = list(range(self.nplots))
262 if self.mode == 'E':
262 if self.mode == 'E':
263 self.xlabel = 'Longitude'
263 self.xlabel = 'Longitude'
264 self.ylabel = 'Latitude'
264 self.ylabel = 'Latitude'
265 else:
265 else:
266 self.xlabel = 'Range (km)'
266 self.xlabel = 'Range (km)'
267 self.ylabel = 'Height (km)'
267 self.ylabel = 'Height (km)'
268 self.bgcolor = 'white'
268 self.bgcolor = 'white'
269 self.cb_labels = self.data.meta['units']
269 self.cb_labels = self.data.meta['units']
270 self.lat = self.data.meta['latitude']
270 self.lat = self.data.meta['latitude']
271 self.lon = self.data.meta['longitude']
271 self.lon = self.data.meta['longitude']
272 self.xmin, self.xmax = float(
272 self.xmin, self.xmax = float(
273 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
273 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
274 self.ymin, self.ymax = float(
274 self.ymin, self.ymax = float(
275 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
275 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
276 # self.polar = True
276 # self.polar = True
277
277
278 def plot(self):
278 def plot(self):
279
279
280 for n, ax in enumerate(self.axes):
280 for n, ax in enumerate(self.axes):
281 data = self.data['param'][self.channels[n]]
281 data = self.data['param'][self.channels[n]]
282
282
283 zeniths = numpy.linspace(
283 zeniths = numpy.linspace(
284 0, self.data.meta['max_range'], data.shape[1])
284 0, self.data.meta['max_range'], data.shape[1])
285 if self.mode == 'E':
285 if self.mode == 'E':
286 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
286 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
287 r, theta = numpy.meshgrid(zeniths, azimuths)
287 r, theta = numpy.meshgrid(zeniths, azimuths)
288 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
288 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
289 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
289 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
290 x = km2deg(x) + self.lon
290 x = km2deg(x) + self.lon
291 y = km2deg(y) + self.lat
291 y = km2deg(y) + self.lat
292 else:
292 else:
293 azimuths = numpy.radians(self.data.yrange)
293 azimuths = numpy.radians(self.data.yrange)
294 r, theta = numpy.meshgrid(zeniths, azimuths)
294 r, theta = numpy.meshgrid(zeniths, azimuths)
295 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
295 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
296 self.y = zeniths
296 self.y = zeniths
297
297
298 if ax.firsttime:
298 if ax.firsttime:
299 if self.zlimits is not None:
299 if self.zlimits is not None:
300 self.zmin, self.zmax = self.zlimits[n]
300 self.zmin, self.zmax = self.zlimits[n]
301 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
301 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
302 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
302 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
303 vmin=self.zmin,
303 vmin=self.zmin,
304 vmax=self.zmax,
304 vmax=self.zmax,
305 cmap=self.cmaps[n])
305 cmap=self.cmaps[n])
306 else:
306 else:
307 if self.zlimits is not None:
307 if self.zlimits is not None:
308 self.zmin, self.zmax = self.zlimits[n]
308 self.zmin, self.zmax = self.zlimits[n]
309 ax.collections.remove(ax.collections[0])
309 ax.collections.remove(ax.collections[0])
310 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
310 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
311 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
311 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
312 vmin=self.zmin,
312 vmin=self.zmin,
313 vmax=self.zmax,
313 vmax=self.zmax,
314 cmap=self.cmaps[n])
314 cmap=self.cmaps[n])
315
315
316 if self.mode == 'A':
316 if self.mode == 'A':
317 continue
317 continue
318
318
319 # plot district names
319 # plot district names
320 f = open('/data/workspace/schain_scripts/distrito.csv')
320 f = open('/data/workspace/schain_scripts/distrito.csv')
321 for line in f:
321 for line in f:
322 label, lon, lat = [s.strip() for s in line.split(',') if s]
322 label, lon, lat = [s.strip() for s in line.split(',') if s]
323 lat = float(lat)
323 lat = float(lat)
324 lon = float(lon)
324 lon = float(lon)
325 # ax.plot(lon, lat, '.b', ms=2)
325 # ax.plot(lon, lat, '.b', ms=2)
326 ax.text(lon, lat, label.decode('utf8'), ha='center',
326 ax.text(lon, lat, label.decode('utf8'), ha='center',
327 va='bottom', size='8', color='black')
327 va='bottom', size='8', color='black')
328
328
329 # plot limites
329 # plot limites
330 limites = []
330 limites = []
331 tmp = []
331 tmp = []
332 for line in open('/data/workspace/schain_scripts/lima.csv'):
332 for line in open('/data/workspace/schain_scripts/lima.csv'):
333 if '#' in line:
333 if '#' in line:
334 if tmp:
334 if tmp:
335 limites.append(tmp)
335 limites.append(tmp)
336 tmp = []
336 tmp = []
337 continue
337 continue
338 values = line.strip().split(',')
338 values = line.strip().split(',')
339 tmp.append((float(values[0]), float(values[1])))
339 tmp.append((float(values[0]), float(values[1])))
340 for points in limites:
340 for points in limites:
341 ax.add_patch(
341 ax.add_patch(
342 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
342 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
343
343
344 # plot Cuencas
344 # plot Cuencas
345 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
345 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
346 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
346 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
347 values = [line.strip().split(',') for line in f]
347 values = [line.strip().split(',') for line in f]
348 points = [(float(s[0]), float(s[1])) for s in values]
348 points = [(float(s[0]), float(s[1])) for s in values]
349 ax.add_patch(Polygon(points, ec='b', fc='none'))
349 ax.add_patch(Polygon(points, ec='b', fc='none'))
350
350
351 # plot grid
351 # plot grid
352 for r in (15, 30, 45, 60):
352 for r in (15, 30, 45, 60):
353 ax.add_artist(plt.Circle((self.lon, self.lat),
353 ax.add_artist(plt.Circle((self.lon, self.lat),
354 km2deg(r), color='0.6', fill=False, lw=0.2))
354 km2deg(r), color='0.6', fill=False, lw=0.2))
355 ax.text(
355 ax.text(
356 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
356 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
357 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
357 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
358 '{}km'.format(r),
358 '{}km'.format(r),
359 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
359 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
360
360
361 if self.mode == 'E':
361 if self.mode == 'E':
362 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
362 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
363 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
363 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
364 else:
364 else:
365 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
365 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
366 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
366 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
367
367
368 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
368 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
369 self.titles = ['{} {}'.format(
369 self.titles = ['{} {}'.format(
370 self.data.parameters[x], title) for x in self.channels]
370 self.data.parameters[x], title) for x in self.channels]
371
371
372 class WeatherPlot(Plot):
372 class WeatherPlot(Plot):
373 CODE = 'weather'
373 CODE = 'weather'
374 plot_name = 'weather'
374 plot_name = 'weather'
375 plot_type = 'ppistyle'
375 plot_type = 'ppistyle'
376 buffering = False
376 buffering = False
377
377
378 def setup(self):
378 def setup(self):
379 self.ncols = 1
379 self.ncols = 1
380 self.nrows = 1
380 self.nrows = 1
381 self.width =8
381 self.width =8
382 self.height =8
382 self.height =8
383 self.nplots= 1
383 self.nplots= 1
384 self.ylabel= 'Range [Km]'
384 self.ylabel= 'Range [Km]'
385 self.titles= ['Weather']
385 self.titles= ['Weather']
386 self.colorbar=False
386 self.colorbar=False
387 self.ini =0
387 self.ini =0
388 self.len_azi =0
388 self.len_azi =0
389 self.buffer_ini = None
389 self.buffer_ini = None
390 self.buffer_azi = None
390 self.buffer_azi = None
391 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
391 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
392 self.flag =0
392 self.flag =0
393 self.indicador= 0
393 self.indicador= 0
394 self.last_data_azi = None
394 self.last_data_azi = None
395 self.val_mean = None
395 self.val_mean = None
396
396
397 def update(self, dataOut):
397 def update(self, dataOut):
398
398
399 data = {}
399 data = {}
400 meta = {}
400 meta = {}
401 if hasattr(dataOut, 'dataPP_POWER'):
401 if hasattr(dataOut, 'dataPP_POWER'):
402 factor = 1
402 factor = 1
403 if hasattr(dataOut, 'nFFTPoints'):
403 if hasattr(dataOut, 'nFFTPoints'):
404 factor = dataOut.normFactor
404 factor = dataOut.normFactor
405 #print("DIME EL SHAPE PORFAVOR",dataOut.data_360.shape)
405 #print("DIME EL SHAPE PORFAVOR",dataOut.data_360.shape)
406 data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
406 data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
407 data['azi'] = dataOut.data_azi
407 data['azi'] = dataOut.data_azi
408 data['ele'] = dataOut.data_ele
408 data['ele'] = dataOut.data_ele
409 return data, meta
409 return data, meta
410
410
411 def get2List(self,angulos):
411 def get2List(self,angulos):
412 list1=[]
412 list1=[]
413 list2=[]
413 list2=[]
414 for i in reversed(range(len(angulos))):
414 for i in reversed(range(len(angulos))):
415 diff_ = angulos[i]-angulos[i-1]
415 diff_ = angulos[i]-angulos[i-1]
416 if diff_ >1.5:
416 if diff_ >1.5:
417 list1.append(i-1)
417 list1.append(i-1)
418 list2.append(diff_)
418 list2.append(diff_)
419 return list(reversed(list1)),list(reversed(list2))
419 return list(reversed(list1)),list(reversed(list2))
420
420
421 def fixData360(self,list_,ang_):
421 def fixData360(self,list_,ang_):
422 if list_[0]==-1:
422 if list_[0]==-1:
423 vec = numpy.where(ang_<ang_[0])
423 vec = numpy.where(ang_<ang_[0])
424 ang_[vec] = ang_[vec]+360
424 ang_[vec] = ang_[vec]+360
425 return ang_
425 return ang_
426 return ang_
426 return ang_
427
427
428 def fixData360HL(self,angulos):
428 def fixData360HL(self,angulos):
429 vec = numpy.where(angulos>=360)
429 vec = numpy.where(angulos>=360)
430 angulos[vec]=angulos[vec]-360
430 angulos[vec]=angulos[vec]-360
431 return angulos
431 return angulos
432
432
433 def search_pos(self,pos,list_):
433 def search_pos(self,pos,list_):
434 for i in range(len(list_)):
434 for i in range(len(list_)):
435 if pos == list_[i]:
435 if pos == list_[i]:
436 return True,i
436 return True,i
437 i=None
437 i=None
438 return False,i
438 return False,i
439
439
440 def fixDataComp(self,ang_,list1_,list2_):
440 def fixDataComp(self,ang_,list1_,list2_):
441 size = len(ang_)
441 size = len(ang_)
442 size2 = 0
442 size2 = 0
443 for i in range(len(list2_)):
443 for i in range(len(list2_)):
444 size2=size2+round(list2_[i])-1
444 size2=size2+round(list2_[i])-1
445 new_size= size+size2
445 new_size= size+size2
446 ang_new = numpy.zeros(new_size)
446 ang_new = numpy.zeros(new_size)
447 ang_new2 = numpy.zeros(new_size)
447 ang_new2 = numpy.zeros(new_size)
448
448
449 tmp = 0
449 tmp = 0
450 c = 0
450 c = 0
451 for i in range(len(ang_)):
451 for i in range(len(ang_)):
452 ang_new[tmp +c] = ang_[i]
452 ang_new[tmp +c] = ang_[i]
453 ang_new2[tmp+c] = ang_[i]
453 ang_new2[tmp+c] = ang_[i]
454 condition , value = self.search_pos(i,list1_)
454 condition , value = self.search_pos(i,list1_)
455 if condition:
455 if condition:
456 pos = tmp + c + 1
456 pos = tmp + c + 1
457 for k in range(round(list2_[value])-1):
457 for k in range(round(list2_[value])-1):
458 ang_new[pos+k] = ang_new[pos+k-1]+1
458 ang_new[pos+k] = ang_new[pos+k-1]+1
459 ang_new2[pos+k] = numpy.nan
459 ang_new2[pos+k] = numpy.nan
460 tmp = pos +k
460 tmp = pos +k
461 c = 0
461 c = 0
462 c=c+1
462 c=c+1
463 return ang_new,ang_new2
463 return ang_new,ang_new2
464
464
465 def globalCheckPED(self,angulos):
465 def globalCheckPED(self,angulos):
466 l1,l2 = self.get2List(angulos)
466 l1,l2 = self.get2List(angulos)
467 if len(l1)>0:
467 if len(l1)>0:
468 angulos2 = self.fixData360(list_=l1,ang_=angulos)
468 angulos2 = self.fixData360(list_=l1,ang_=angulos)
469 l1,l2 = self.get2List(angulos2)
469 l1,l2 = self.get2List(angulos2)
470
470
471 ang1_,ang2_ = self.fixDataComp(ang_=angulos2,list1_=l1,list2_=l2)
471 ang1_,ang2_ = self.fixDataComp(ang_=angulos2,list1_=l1,list2_=l2)
472 ang1_ = self.fixData360HL(ang1_)
472 ang1_ = self.fixData360HL(ang1_)
473 ang2_ = self.fixData360HL(ang2_)
473 ang2_ = self.fixData360HL(ang2_)
474 else:
474 else:
475 ang1_= angulos
475 ang1_= angulos
476 ang2_= angulos
476 ang2_= angulos
477 return ang1_,ang2_
477 return ang1_,ang2_
478
478
479 def analizeDATA(self,data_azi):
479 def analizeDATA(self,data_azi):
480 list1 = []
480 list1 = []
481 list2 = []
481 list2 = []
482 dat = data_azi
482 dat = data_azi
483 for i in reversed(range(1,len(dat))):
483 for i in reversed(range(1,len(dat))):
484 if dat[i]>dat[i-1]:
484 if dat[i]>dat[i-1]:
485 diff = int(dat[i])-int(dat[i-1])
485 diff = int(dat[i])-int(dat[i-1])
486 else:
486 else:
487 diff = 360+int(dat[i])-int(dat[i-1])
487 diff = 360+int(dat[i])-int(dat[i-1])
488 if diff > 1:
488 if diff > 1:
489 list1.append(i-1)
489 list1.append(i-1)
490 list2.append(diff-1)
490 list2.append(diff-1)
491 return list1,list2
491 return list1,list2
492
492
493 def fixDATANEW(self,data_azi,data_weather):
493 def fixDATANEW(self,data_azi,data_weather):
494 list1,list2 = self.analizeDATA(data_azi)
494 list1,list2 = self.analizeDATA(data_azi)
495 if len(list1)== 0:
495 if len(list1)== 0:
496 return data_azi,data_weather
496 return data_azi,data_weather
497 else:
497 else:
498 resize = 0
498 resize = 0
499 for i in range(len(list2)):
499 for i in range(len(list2)):
500 resize= resize + list2[i]
500 resize= resize + list2[i]
501 new_data_azi = numpy.resize(data_azi,resize)
501 new_data_azi = numpy.resize(data_azi,resize)
502 new_data_weather= numpy.resize(date_weather,resize)
502 new_data_weather= numpy.resize(date_weather,resize)
503
503
504 for i in range(len(list2)):
504 for i in range(len(list2)):
505 j=0
505 j=0
506 position=list1[i]+1
506 position=list1[i]+1
507 for j in range(list2[i]):
507 for j in range(list2[i]):
508 new_data_azi[position+j]=new_data_azi[position+j-1]+1
508 new_data_azi[position+j]=new_data_azi[position+j-1]+1
509 return new_data_azi
509 return new_data_azi
510
510
511 def fixDATA(self,data_azi):
511 def fixDATA(self,data_azi):
512 data=data_azi
512 data=data_azi
513 for i in range(len(data)):
513 for i in range(len(data)):
514 if numpy.isnan(data[i]):
514 if numpy.isnan(data[i]):
515 data[i]=data[i-1]+1
515 data[i]=data[i-1]+1
516 return data
516 return data
517
517
518 def replaceNAN(self,data_weather,data_azi,val):
518 def replaceNAN(self,data_weather,data_azi,val):
519 data= data_azi
519 data= data_azi
520 data_T= data_weather
520 data_T= data_weather
521 if data.shape[0]> data_T.shape[0]:
521 if data.shape[0]> data_T.shape[0]:
522 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
522 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
523 c = 0
523 c = 0
524 for i in range(len(data)):
524 for i in range(len(data)):
525 if numpy.isnan(data[i]):
525 if numpy.isnan(data[i]):
526 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
526 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
527 else:
527 else:
528 data_N[i,:]=data_T[c,:]
528 data_N[i,:]=data_T[c,:]
529 c=c+1
529 c=c+1
530 return data_N
530 return data_N
531 else:
531 else:
532 for i in range(len(data)):
532 for i in range(len(data)):
533 if numpy.isnan(data[i]):
533 if numpy.isnan(data[i]):
534 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
534 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
535 return data_T
535 return data_T
536
536
537 def const_ploteo(self,data_weather,data_azi,step,res):
537 def const_ploteo(self,data_weather,data_azi,step,res):
538 if self.ini==0:
538 if self.ini==0:
539 #-------
539 #-------
540 n = (360/res)-len(data_azi)
540 n = (360/res)-len(data_azi)
541 #--------------------- new -------------------------
541 #--------------------- new -------------------------
542 data_azi_new ,data_azi_old= self.globalCheckPED(data_azi)
542 data_azi_new ,data_azi_old= self.globalCheckPED(data_azi)
543 #------------------------
543 #------------------------
544 start = data_azi_new[-1] + res
544 start = data_azi_new[-1] + res
545 end = data_azi_new[0] - res
545 end = data_azi_new[0] - res
546 #------ new
546 #------ new
547 self.last_data_azi = end
547 self.last_data_azi = end
548 if start>end:
548 if start>end:
549 end = end + 360
549 end = end + 360
550 azi_vacia = numpy.linspace(start,end,int(n))
550 azi_vacia = numpy.linspace(start,end,int(n))
551 azi_vacia = numpy.where(azi_vacia>360,azi_vacia-360,azi_vacia)
551 azi_vacia = numpy.where(azi_vacia>360,azi_vacia-360,azi_vacia)
552 data_azi = numpy.hstack((data_azi_new,azi_vacia))
552 data_azi = numpy.hstack((data_azi_new,azi_vacia))
553 # RADAR
553 # RADAR
554 val_mean = numpy.mean(data_weather[:,-1])
554 val_mean = numpy.mean(data_weather[:,-1])
555 self.val_mean = val_mean
555 self.val_mean = val_mean
556 data_weather_cmp = numpy.ones([(360-data_weather.shape[0]),data_weather.shape[1]])*val_mean
556 data_weather_cmp = numpy.ones([(360-data_weather.shape[0]),data_weather.shape[1]])*val_mean
557 data_weather = self.replaceNAN(data_weather=data_weather,data_azi=data_azi_old,val=self.val_mean)
557 data_weather = self.replaceNAN(data_weather=data_weather,data_azi=data_azi_old,val=self.val_mean)
558 data_weather = numpy.vstack((data_weather,data_weather_cmp))
558 data_weather = numpy.vstack((data_weather,data_weather_cmp))
559 else:
559 else:
560 # azimuth
560 # azimuth
561 flag=0
561 flag=0
562 start_azi = self.res_azi[0]
562 start_azi = self.res_azi[0]
563 #-----------new------------
563 #-----------new------------
564 data_azi ,data_azi_old= self.globalCheckPED(data_azi)
564 data_azi ,data_azi_old= self.globalCheckPED(data_azi)
565 data_weather = self.replaceNAN(data_weather=data_weather,data_azi=data_azi_old,val=self.val_mean)
565 data_weather = self.replaceNAN(data_weather=data_weather,data_azi=data_azi_old,val=self.val_mean)
566 #--------------------------
566 #--------------------------
567 start = data_azi[0]
567 start = data_azi[0]
568 end = data_azi[-1]
568 end = data_azi[-1]
569 self.last_data_azi= end
569 self.last_data_azi= end
570 if start< start_azi:
570 if start< start_azi:
571 start = start +360
571 start = start +360
572 if end <start_azi:
572 if end <start_azi:
573 end = end +360
573 end = end +360
574
574
575 pos_ini = int((start-start_azi)/res)
575 pos_ini = int((start-start_azi)/res)
576 len_azi = len(data_azi)
576 len_azi = len(data_azi)
577 if (360-pos_ini)<len_azi:
577 if (360-pos_ini)<len_azi:
578 if pos_ini+1==360:
578 if pos_ini+1==360:
579 pos_ini=0
579 pos_ini=0
580 else:
580 else:
581 flag=1
581 flag=1
582 dif= 360-pos_ini
582 dif= 360-pos_ini
583 comp= len_azi-dif
583 comp= len_azi-dif
584 #-----------------
584 #-----------------
585 if flag==0:
585 if flag==0:
586 # AZIMUTH
586 # AZIMUTH
587 self.res_azi[pos_ini:pos_ini+len_azi] = data_azi
587 self.res_azi[pos_ini:pos_ini+len_azi] = data_azi
588 # RADAR
588 # RADAR
589 self.res_weather[pos_ini:pos_ini+len_azi,:] = data_weather
589 self.res_weather[pos_ini:pos_ini+len_azi,:] = data_weather
590 else:
590 else:
591 # AZIMUTH
591 # AZIMUTH
592 self.res_azi[pos_ini:pos_ini+dif] = data_azi[0:dif]
592 self.res_azi[pos_ini:pos_ini+dif] = data_azi[0:dif]
593 self.res_azi[0:comp] = data_azi[dif:]
593 self.res_azi[0:comp] = data_azi[dif:]
594 # RADAR
594 # RADAR
595 self.res_weather[pos_ini:pos_ini+dif,:] = data_weather[0:dif,:]
595 self.res_weather[pos_ini:pos_ini+dif,:] = data_weather[0:dif,:]
596 self.res_weather[0:comp,:] = data_weather[dif:,:]
596 self.res_weather[0:comp,:] = data_weather[dif:,:]
597 flag=0
597 flag=0
598 data_azi = self.res_azi
598 data_azi = self.res_azi
599 data_weather = self.res_weather
599 data_weather = self.res_weather
600
600
601 return data_weather,data_azi
601 return data_weather,data_azi
602
602
603 def plot(self):
603 def plot(self):
604 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
604 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
605 data = self.data[-1]
605 data = self.data[-1]
606 r = self.data.yrange
606 r = self.data.yrange
607 delta_height = r[1]-r[0]
607 delta_height = r[1]-r[0]
608 r_mask = numpy.where(r>=0)[0]
608 r_mask = numpy.where(r>=0)[0]
609 r = numpy.arange(len(r_mask))*delta_height
609 r = numpy.arange(len(r_mask))*delta_height
610 self.y = 2*r
610 self.y = 2*r
611 # RADAR
611 # RADAR
612 #data_weather = data['weather']
612 #data_weather = data['weather']
613 # PEDESTAL
613 # PEDESTAL
614 #data_azi = data['azi']
614 #data_azi = data['azi']
615 res = 1
615 res = 1
616 # STEP
616 # STEP
617 step = (360/(res*data['weather'].shape[0]))
617 step = (360/(res*data['weather'].shape[0]))
618
618
619 self.res_weather, self.res_azi = self.const_ploteo(data_weather=data['weather'][:,r_mask],data_azi=data['azi'],step=step,res=res)
619 self.res_weather, self.res_azi = self.const_ploteo(data_weather=data['weather'][:,r_mask],data_azi=data['azi'],step=step,res=res)
620 self.res_ele = numpy.mean(data['ele'])
620 self.res_ele = numpy.mean(data['ele'])
621 ################# PLOTEO ###################
621 ################# PLOTEO ###################
622 for i,ax in enumerate(self.axes):
622 for i,ax in enumerate(self.axes):
623 self.zmin = self.zmin if self.zmin else 20
623 self.zmin = self.zmin if self.zmin else 20
624 self.zmax = self.zmax if self.zmax else 80
624 self.zmax = self.zmax if self.zmax else 80
625 if ax.firsttime:
625 if ax.firsttime:
626 plt.clf()
626 plt.clf()
627 cgax, pm = wrl.vis.plot_ppi(self.res_weather,r=r,az=self.res_azi,fig=self.figures[0], proj='cg', vmin=self.zmin, vmax=self.zmax)
627 cgax, pm = wrl.vis.plot_ppi(self.res_weather,r=r,az=self.res_azi,fig=self.figures[0], proj='cg', vmin=self.zmin, vmax=self.zmax)
628 else:
628 else:
629 plt.clf()
629 plt.clf()
630 cgax, pm = wrl.vis.plot_ppi(self.res_weather,r=r,az=self.res_azi,fig=self.figures[0], proj='cg', vmin=self.zmin, vmax=self.zmax)
630 cgax, pm = wrl.vis.plot_ppi(self.res_weather,r=r,az=self.res_azi,fig=self.figures[0], proj='cg', vmin=self.zmin, vmax=self.zmax)
631 caax = cgax.parasites[0]
631 caax = cgax.parasites[0]
632 paax = cgax.parasites[1]
632 paax = cgax.parasites[1]
633 cbar = plt.gcf().colorbar(pm, pad=0.075)
633 cbar = plt.gcf().colorbar(pm, pad=0.075)
634 caax.set_xlabel('x_range [km]')
634 caax.set_xlabel('x_range [km]')
635 caax.set_ylabel('y_range [km]')
635 caax.set_ylabel('y_range [km]')
636 plt.text(1.0, 1.05, 'Azimuth '+str(thisDatetime)+" Step "+str(self.ini)+ " EL: "+str(round(self.res_ele, 1)), transform=caax.transAxes, va='bottom',ha='right')
636 plt.text(1.0, 1.05, 'Azimuth '+str(thisDatetime)+" Step "+str(self.ini)+ " EL: "+str(round(self.res_ele, 1)), transform=caax.transAxes, va='bottom',ha='right')
637
637
638 self.ini= self.ini+1
638 self.ini= self.ini+1
639
639
640
640
641 class WeatherRHIPlot(Plot):
641 class WeatherRHIPlot(Plot):
642 CODE = 'weather'
642 CODE = 'weather'
643 plot_name = 'weather'
643 plot_name = 'weather'
644 plot_type = 'rhistyle'
644 plot_type = 'rhistyle'
645 buffering = False
645 buffering = False
646 data_ele_tmp = None
646 data_ele_tmp = None
647
647
648 def setup(self):
648 def setup(self):
649 print("********************")
649 print("********************")
650 print("********************")
650 print("********************")
651 print("********************")
651 print("********************")
652 print("SETUP WEATHER PLOT")
652 print("SETUP WEATHER PLOT")
653 self.ncols = 1
653 self.ncols = 1
654 self.nrows = 1
654 self.nrows = 1
655 self.nplots= 1
655 self.nplots= 1
656 self.ylabel= 'Range [Km]'
656 self.ylabel= 'Range [Km]'
657 self.titles= ['Weather']
657 self.titles= ['Weather']
658 if self.channels is not None:
658 if self.channels is not None:
659 self.nplots = len(self.channels)
659 self.nplots = len(self.channels)
660 self.nrows = len(self.channels)
660 self.nrows = len(self.channels)
661 else:
661 else:
662 self.nplots = self.data.shape(self.CODE)[0]
662 self.nplots = self.data.shape(self.CODE)[0]
663 self.nrows = self.nplots
663 self.nrows = self.nplots
664 self.channels = list(range(self.nplots))
664 self.channels = list(range(self.nplots))
665 print("channels",self.channels)
665 print("channels",self.channels)
666 print("que saldra", self.data.shape(self.CODE)[0])
666 print("que saldra", self.data.shape(self.CODE)[0])
667 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
667 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
668 print("self.titles",self.titles)
668 print("self.titles",self.titles)
669 self.colorbar=False
669 self.colorbar=False
670 self.width =12
670 self.width =12
671 self.height =8
671 self.height =8
672 self.ini =0
672 self.ini =0
673 self.len_azi =0
673 self.len_azi =0
674 self.buffer_ini = None
674 self.buffer_ini = None
675 self.buffer_ele = None
675 self.buffer_ele = None
676 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
676 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
677 self.flag =0
677 self.flag =0
678 self.indicador= 0
678 self.indicador= 0
679 self.last_data_ele = None
679 self.last_data_ele = None
680 self.val_mean = None
680 self.val_mean = None
681
681
682 def update(self, dataOut):
682 def update(self, dataOut):
683
683
684 data = {}
684 data = {}
685 meta = {}
685 meta = {}
686 if hasattr(dataOut, 'dataPP_POWER'):
686 if hasattr(dataOut, 'dataPP_POWER'):
687 factor = 1
687 factor = 1
688 if hasattr(dataOut, 'nFFTPoints'):
688 if hasattr(dataOut, 'nFFTPoints'):
689 factor = dataOut.normFactor
689 factor = dataOut.normFactor
690 print("dataOut",dataOut.data_360.shape)
690 print("dataOut",dataOut.data_360.shape)
691 #
691 #
692 data['weather'] = 10*numpy.log10(dataOut.data_360/(factor))
692 data['weather'] = 10*numpy.log10(dataOut.data_360/(factor))
693 #
693 #
694 #data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
694 #data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
695 data['azi'] = dataOut.data_azi
695 data['azi'] = dataOut.data_azi
696 data['ele'] = dataOut.data_ele
696 data['ele'] = dataOut.data_ele
697 #print("UPDATE")
697 #print("UPDATE")
698 #print("data[weather]",data['weather'].shape)
698 #print("data[weather]",data['weather'].shape)
699 #print("data[azi]",data['azi'])
699 #print("data[azi]",data['azi'])
700 return data, meta
700 return data, meta
701
701
702 def get2List(self,angulos):
702 def get2List(self,angulos):
703 list1=[]
703 list1=[]
704 list2=[]
704 list2=[]
705 for i in reversed(range(len(angulos))):
705 for i in reversed(range(len(angulos))):
706 if not i==0:#el caso de i=0 evalula el primero de la lista con el ultimo y no es relevante
706 if not i==0:#el caso de i=0 evalula el primero de la lista con el ultimo y no es relevante
707 diff_ = angulos[i]-angulos[i-1]
707 diff_ = angulos[i]-angulos[i-1]
708 if abs(diff_) >1.5:
708 if abs(diff_) >1.5:
709 list1.append(i-1)
709 list1.append(i-1)
710 list2.append(diff_)
710 list2.append(diff_)
711 return list(reversed(list1)),list(reversed(list2))
711 return list(reversed(list1)),list(reversed(list2))
712
712
713 def fixData90(self,list_,ang_):
713 def fixData90(self,list_,ang_):
714 if list_[0]==-1:
714 if list_[0]==-1:
715 vec = numpy.where(ang_<ang_[0])
715 vec = numpy.where(ang_<ang_[0])
716 ang_[vec] = ang_[vec]+90
716 ang_[vec] = ang_[vec]+90
717 return ang_
717 return ang_
718 return ang_
718 return ang_
719
719
720 def fixData90HL(self,angulos):
720 def fixData90HL(self,angulos):
721 vec = numpy.where(angulos>=90)
721 vec = numpy.where(angulos>=90)
722 angulos[vec]=angulos[vec]-90
722 angulos[vec]=angulos[vec]-90
723 return angulos
723 return angulos
724
724
725
725
726 def search_pos(self,pos,list_):
726 def search_pos(self,pos,list_):
727 for i in range(len(list_)):
727 for i in range(len(list_)):
728 if pos == list_[i]:
728 if pos == list_[i]:
729 return True,i
729 return True,i
730 i=None
730 i=None
731 return False,i
731 return False,i
732
732
733 def fixDataComp(self,ang_,list1_,list2_,tipo_case):
733 def fixDataComp(self,ang_,list1_,list2_,tipo_case):
734 size = len(ang_)
734 size = len(ang_)
735 size2 = 0
735 size2 = 0
736 for i in range(len(list2_)):
736 for i in range(len(list2_)):
737 size2=size2+round(abs(list2_[i]))-1
737 size2=size2+round(abs(list2_[i]))-1
738 new_size= size+size2
738 new_size= size+size2
739 ang_new = numpy.zeros(new_size)
739 ang_new = numpy.zeros(new_size)
740 ang_new2 = numpy.zeros(new_size)
740 ang_new2 = numpy.zeros(new_size)
741
741
742 tmp = 0
742 tmp = 0
743 c = 0
743 c = 0
744 for i in range(len(ang_)):
744 for i in range(len(ang_)):
745 ang_new[tmp +c] = ang_[i]
745 ang_new[tmp +c] = ang_[i]
746 ang_new2[tmp+c] = ang_[i]
746 ang_new2[tmp+c] = ang_[i]
747 condition , value = self.search_pos(i,list1_)
747 condition , value = self.search_pos(i,list1_)
748 if condition:
748 if condition:
749 pos = tmp + c + 1
749 pos = tmp + c + 1
750 for k in range(round(abs(list2_[value]))-1):
750 for k in range(round(abs(list2_[value]))-1):
751 if tipo_case==0 or tipo_case==3:#subida
751 if tipo_case==0 or tipo_case==3:#subida
752 ang_new[pos+k] = ang_new[pos+k-1]+1
752 ang_new[pos+k] = ang_new[pos+k-1]+1
753 ang_new2[pos+k] = numpy.nan
753 ang_new2[pos+k] = numpy.nan
754 elif tipo_case==1 or tipo_case==2:#bajada
754 elif tipo_case==1 or tipo_case==2:#bajada
755 ang_new[pos+k] = ang_new[pos+k-1]-1
755 ang_new[pos+k] = ang_new[pos+k-1]-1
756 ang_new2[pos+k] = numpy.nan
756 ang_new2[pos+k] = numpy.nan
757
757
758 tmp = pos +k
758 tmp = pos +k
759 c = 0
759 c = 0
760 c=c+1
760 c=c+1
761 return ang_new,ang_new2
761 return ang_new,ang_new2
762
762
763 def globalCheckPED(self,angulos,tipo_case):
763 def globalCheckPED(self,angulos,tipo_case):
764 l1,l2 = self.get2List(angulos)
764 l1,l2 = self.get2List(angulos)
765 ##print("l1",l1)
765 ##print("l1",l1)
766 ##print("l2",l2)
766 ##print("l2",l2)
767 if len(l1)>0:
767 if len(l1)>0:
768 #angulos2 = self.fixData90(list_=l1,ang_=angulos)
768 #angulos2 = self.fixData90(list_=l1,ang_=angulos)
769 #l1,l2 = self.get2List(angulos2)
769 #l1,l2 = self.get2List(angulos2)
770 ang1_,ang2_ = self.fixDataComp(ang_=angulos,list1_=l1,list2_=l2,tipo_case=tipo_case)
770 ang1_,ang2_ = self.fixDataComp(ang_=angulos,list1_=l1,list2_=l2,tipo_case=tipo_case)
771 #ang1_ = self.fixData90HL(ang1_)
771 #ang1_ = self.fixData90HL(ang1_)
772 #ang2_ = self.fixData90HL(ang2_)
772 #ang2_ = self.fixData90HL(ang2_)
773 else:
773 else:
774 ang1_= angulos
774 ang1_= angulos
775 ang2_= angulos
775 ang2_= angulos
776 return ang1_,ang2_
776 return ang1_,ang2_
777
777
778
778
779 def replaceNAN(self,data_weather,data_ele,val):
779 def replaceNAN(self,data_weather,data_ele,val):
780 data= data_ele
780 data= data_ele
781 data_T= data_weather
781 data_T= data_weather
782 if data.shape[0]> data_T.shape[0]:
782 if data.shape[0]> data_T.shape[0]:
783 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
783 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
784 c = 0
784 c = 0
785 for i in range(len(data)):
785 for i in range(len(data)):
786 if numpy.isnan(data[i]):
786 if numpy.isnan(data[i]):
787 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
787 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
788 else:
788 else:
789 data_N[i,:]=data_T[c,:]
789 data_N[i,:]=data_T[c,:]
790 c=c+1
790 c=c+1
791 return data_N
791 return data_N
792 else:
792 else:
793 for i in range(len(data)):
793 for i in range(len(data)):
794 if numpy.isnan(data[i]):
794 if numpy.isnan(data[i]):
795 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
795 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
796 return data_T
796 return data_T
797
797
798 def check_case(self,data_ele,ang_max,ang_min):
798 def check_case(self,data_ele,ang_max,ang_min):
799 start = data_ele[0]
799 start = data_ele[0]
800 end = data_ele[-1]
800 end = data_ele[-1]
801 number = (end-start)
801 number = (end-start)
802 len_ang=len(data_ele)
802 len_ang=len(data_ele)
803 print("start",start)
803 print("start",start)
804 print("end",end)
804 print("end",end)
805 print("number",number)
805 print("number",number)
806
806
807 print("len_ang",len_ang)
807 print("len_ang",len_ang)
808
808
809 #exit(1)
809 #exit(1)
810
810
811 if start<end and (round(abs(number)+1)>=len_ang or (numpy.argmin(data_ele)==0)):#caso subida
811 if start<end and (round(abs(number)+1)>=len_ang or (numpy.argmin(data_ele)==0)):#caso subida
812 return 0
812 return 0
813 #elif start>end and (round(abs(number)+1)>=len_ang or(numpy.argmax(data_ele)==0)):#caso bajada
813 #elif start>end and (round(abs(number)+1)>=len_ang or(numpy.argmax(data_ele)==0)):#caso bajada
814 # return 1
814 # return 1
815 elif round(abs(number)+1)>=len_ang and (start>end or(numpy.argmax(data_ele)==0)):#caso bajada
815 elif round(abs(number)+1)>=len_ang and (start>end or(numpy.argmax(data_ele)==0)):#caso bajada
816 return 1
816 return 1
817 elif round(abs(number)+1)<len_ang and data_ele[-2]>data_ele[-1]:# caso BAJADA CAMBIO ANG MAX
817 elif round(abs(number)+1)<len_ang and data_ele[-2]>data_ele[-1]:# caso BAJADA CAMBIO ANG MAX
818 return 2
818 return 2
819 elif round(abs(number)+1)<len_ang and data_ele[-2]<data_ele[-1] :# caso SUBIDA CAMBIO ANG MIN
819 elif round(abs(number)+1)<len_ang and data_ele[-2]<data_ele[-1] :# caso SUBIDA CAMBIO ANG MIN
820 return 3
820 return 3
821
821
822
822
823 def const_ploteo(self,val_ch,data_weather,data_ele,step,res,ang_max,ang_min):
823 def const_ploteo(self,val_ch,data_weather,data_ele,step,res,ang_max,ang_min):
824 ang_max= ang_max
824 ang_max= ang_max
825 ang_min= ang_min
825 ang_min= ang_min
826 data_weather=data_weather
826 data_weather=data_weather
827 val_ch=val_ch
827 val_ch=val_ch
828 ##print("*********************DATA WEATHER**************************************")
828 ##print("*********************DATA WEATHER**************************************")
829 ##print(data_weather)
829 ##print(data_weather)
830 if self.ini==0:
830 if self.ini==0:
831 '''
831 '''
832 print("**********************************************")
832 print("**********************************************")
833 print("**********************************************")
833 print("**********************************************")
834 print("***************ini**************")
834 print("***************ini**************")
835 print("**********************************************")
835 print("**********************************************")
836 print("**********************************************")
836 print("**********************************************")
837 '''
837 '''
838 #print("data_ele",data_ele)
838 #print("data_ele",data_ele)
839 #----------------------------------------------------------
839 #----------------------------------------------------------
840 tipo_case = self.check_case(data_ele,ang_max,ang_min)
840 tipo_case = self.check_case(data_ele,ang_max,ang_min)
841 print("check_case",tipo_case)
841 print("check_case",tipo_case)
842 #exit(1)
842 #exit(1)
843 #--------------------- new -------------------------
843 #--------------------- new -------------------------
844 data_ele_new ,data_ele_old= self.globalCheckPED(data_ele,tipo_case)
844 data_ele_new ,data_ele_old= self.globalCheckPED(data_ele,tipo_case)
845
845
846 #-------------------------CAMBIOS RHI---------------------------------
846 #-------------------------CAMBIOS RHI---------------------------------
847 start= ang_min
847 start= ang_min
848 end = ang_max
848 end = ang_max
849 n= (ang_max-ang_min)/res
849 n= (ang_max-ang_min)/res
850 #------ new
850 #------ new
851 self.start_data_ele = data_ele_new[0]
851 self.start_data_ele = data_ele_new[0]
852 self.end_data_ele = data_ele_new[-1]
852 self.end_data_ele = data_ele_new[-1]
853 if tipo_case==0 or tipo_case==3: # SUBIDA
853 if tipo_case==0 or tipo_case==3: # SUBIDA
854 n1= round(self.start_data_ele)- start
854 n1= round(self.start_data_ele)- start
855 n2= end - round(self.end_data_ele)
855 n2= end - round(self.end_data_ele)
856 print(self.start_data_ele)
856 print(self.start_data_ele)
857 print(self.end_data_ele)
857 print(self.end_data_ele)
858 if n1>0:
858 if n1>0:
859 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
859 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
860 ele1_nan= numpy.ones(n1)*numpy.nan
860 ele1_nan= numpy.ones(n1)*numpy.nan
861 data_ele = numpy.hstack((ele1,data_ele_new))
861 data_ele = numpy.hstack((ele1,data_ele_new))
862 print("ele1_nan",ele1_nan.shape)
862 print("ele1_nan",ele1_nan.shape)
863 print("data_ele_old",data_ele_old.shape)
863 print("data_ele_old",data_ele_old.shape)
864 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
864 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
865 if n2>0:
865 if n2>0:
866 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
866 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
867 ele2_nan= numpy.ones(n2)*numpy.nan
867 ele2_nan= numpy.ones(n2)*numpy.nan
868 data_ele = numpy.hstack((data_ele,ele2))
868 data_ele = numpy.hstack((data_ele,ele2))
869 print("ele2_nan",ele2_nan.shape)
869 print("ele2_nan",ele2_nan.shape)
870 print("data_ele_old",data_ele_old.shape)
870 print("data_ele_old",data_ele_old.shape)
871 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
871 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
872
872
873 if tipo_case==1 or tipo_case==2: # BAJADA
873 if tipo_case==1 or tipo_case==2: # BAJADA
874 data_ele_new = data_ele_new[::-1] # reversa
874 data_ele_new = data_ele_new[::-1] # reversa
875 data_ele_old = data_ele_old[::-1]# reversa
875 data_ele_old = data_ele_old[::-1]# reversa
876 data_weather = data_weather[::-1,:]# reversa
876 data_weather = data_weather[::-1,:]# reversa
877 vec= numpy.where(data_ele_new<ang_max)
877 vec= numpy.where(data_ele_new<ang_max)
878 data_ele_new = data_ele_new[vec]
878 data_ele_new = data_ele_new[vec]
879 data_ele_old = data_ele_old[vec]
879 data_ele_old = data_ele_old[vec]
880 data_weather = data_weather[vec[0]]
880 data_weather = data_weather[vec[0]]
881 vec2= numpy.where(0<data_ele_new)
881 vec2= numpy.where(0<data_ele_new)
882 data_ele_new = data_ele_new[vec2]
882 data_ele_new = data_ele_new[vec2]
883 data_ele_old = data_ele_old[vec2]
883 data_ele_old = data_ele_old[vec2]
884 data_weather = data_weather[vec2[0]]
884 data_weather = data_weather[vec2[0]]
885 self.start_data_ele = data_ele_new[0]
885 self.start_data_ele = data_ele_new[0]
886 self.end_data_ele = data_ele_new[-1]
886 self.end_data_ele = data_ele_new[-1]
887
887
888 n1= round(self.start_data_ele)- start
888 n1= round(self.start_data_ele)- start
889 n2= end - round(self.end_data_ele)-1
889 n2= end - round(self.end_data_ele)-1
890 print(self.start_data_ele)
890 print(self.start_data_ele)
891 print(self.end_data_ele)
891 print(self.end_data_ele)
892 if n1>0:
892 if n1>0:
893 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
893 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
894 ele1_nan= numpy.ones(n1)*numpy.nan
894 ele1_nan= numpy.ones(n1)*numpy.nan
895 data_ele = numpy.hstack((ele1,data_ele_new))
895 data_ele = numpy.hstack((ele1,data_ele_new))
896 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
896 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
897 if n2>0:
897 if n2>0:
898 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
898 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
899 ele2_nan= numpy.ones(n2)*numpy.nan
899 ele2_nan= numpy.ones(n2)*numpy.nan
900 data_ele = numpy.hstack((data_ele,ele2))
900 data_ele = numpy.hstack((data_ele,ele2))
901 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
901 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
902 # RADAR
902 # RADAR
903 # NOTA data_ele y data_weather es la variable que retorna
903 # NOTA data_ele y data_weather es la variable que retorna
904 val_mean = numpy.mean(data_weather[:,-1])
904 val_mean = numpy.mean(data_weather[:,-1])
905 self.val_mean = val_mean
905 self.val_mean = val_mean
906 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
906 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
907 self.data_ele_tmp[val_ch]= data_ele_old
907 self.data_ele_tmp[val_ch]= data_ele_old
908 else:
908 else:
909 #print("**********************************************")
909 #print("**********************************************")
910 #print("****************VARIABLE**********************")
910 #print("****************VARIABLE**********************")
911 #-------------------------CAMBIOS RHI---------------------------------
911 #-------------------------CAMBIOS RHI---------------------------------
912 #---------------------------------------------------------------------
912 #---------------------------------------------------------------------
913 ##print("INPUT data_ele",data_ele)
913 ##print("INPUT data_ele",data_ele)
914 flag=0
914 flag=0
915 start_ele = self.res_ele[0]
915 start_ele = self.res_ele[0]
916 tipo_case = self.check_case(data_ele,ang_max,ang_min)
916 tipo_case = self.check_case(data_ele,ang_max,ang_min)
917 #print("TIPO DE DATA",tipo_case)
917 #print("TIPO DE DATA",tipo_case)
918 #-----------new------------
918 #-----------new------------
919 data_ele ,data_ele_old = self.globalCheckPED(data_ele,tipo_case)
919 data_ele ,data_ele_old = self.globalCheckPED(data_ele,tipo_case)
920 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
920 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
921
921
922 #-------------------------------NEW RHI ITERATIVO-------------------------
922 #-------------------------------NEW RHI ITERATIVO-------------------------
923
923
924 if tipo_case==0 : # SUBIDA
924 if tipo_case==0 : # SUBIDA
925 vec = numpy.where(data_ele<ang_max)
925 vec = numpy.where(data_ele<ang_max)
926 data_ele = data_ele[vec]
926 data_ele = data_ele[vec]
927 data_ele_old = data_ele_old[vec]
927 data_ele_old = data_ele_old[vec]
928 data_weather = data_weather[vec[0]]
928 data_weather = data_weather[vec[0]]
929
929
930 vec2 = numpy.where(0<data_ele)
930 vec2 = numpy.where(0<data_ele)
931 data_ele= data_ele[vec2]
931 data_ele= data_ele[vec2]
932 data_ele_old= data_ele_old[vec2]
932 data_ele_old= data_ele_old[vec2]
933 ##print(data_ele_new)
933 ##print(data_ele_new)
934 data_weather= data_weather[vec2[0]]
934 data_weather= data_weather[vec2[0]]
935
935
936 new_i_ele = int(round(data_ele[0]))
936 new_i_ele = int(round(data_ele[0]))
937 new_f_ele = int(round(data_ele[-1]))
937 new_f_ele = int(round(data_ele[-1]))
938 #print(new_i_ele)
938 #print(new_i_ele)
939 #print(new_f_ele)
939 #print(new_f_ele)
940 #print(data_ele,len(data_ele))
940 #print(data_ele,len(data_ele))
941 #print(data_ele_old,len(data_ele_old))
941 #print(data_ele_old,len(data_ele_old))
942 if new_i_ele< 2:
942 if new_i_ele< 2:
943 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
943 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
944 self.res_weather[val_ch] = self.replaceNAN(data_weather=self.res_weather[val_ch],data_ele=self.data_ele_tmp[val_ch],val=self.val_mean)
944 self.res_weather[val_ch] = self.replaceNAN(data_weather=self.res_weather[val_ch],data_ele=self.data_ele_tmp[val_ch],val=self.val_mean)
945 self.data_ele_tmp[val_ch][new_i_ele:new_i_ele+len(data_ele)]=data_ele_old
945 self.data_ele_tmp[val_ch][new_i_ele:new_i_ele+len(data_ele)]=data_ele_old
946 self.res_ele[new_i_ele:new_i_ele+len(data_ele)]= data_ele
946 self.res_ele[new_i_ele:new_i_ele+len(data_ele)]= data_ele
947 self.res_weather[val_ch][new_i_ele:new_i_ele+len(data_ele),:]= data_weather
947 self.res_weather[val_ch][new_i_ele:new_i_ele+len(data_ele),:]= data_weather
948 data_ele = self.res_ele
948 data_ele = self.res_ele
949 data_weather = self.res_weather[val_ch]
949 data_weather = self.res_weather[val_ch]
950
950
951 elif tipo_case==1 : #BAJADA
951 elif tipo_case==1 : #BAJADA
952 data_ele = data_ele[::-1] # reversa
952 data_ele = data_ele[::-1] # reversa
953 data_ele_old = data_ele_old[::-1]# reversa
953 data_ele_old = data_ele_old[::-1]# reversa
954 data_weather = data_weather[::-1,:]# reversa
954 data_weather = data_weather[::-1,:]# reversa
955 vec= numpy.where(data_ele<ang_max)
955 vec= numpy.where(data_ele<ang_max)
956 data_ele = data_ele[vec]
956 data_ele = data_ele[vec]
957 data_ele_old = data_ele_old[vec]
957 data_ele_old = data_ele_old[vec]
958 data_weather = data_weather[vec[0]]
958 data_weather = data_weather[vec[0]]
959 vec2= numpy.where(0<data_ele)
959 vec2= numpy.where(0<data_ele)
960 data_ele = data_ele[vec2]
960 data_ele = data_ele[vec2]
961 data_ele_old = data_ele_old[vec2]
961 data_ele_old = data_ele_old[vec2]
962 data_weather = data_weather[vec2[0]]
962 data_weather = data_weather[vec2[0]]
963
963
964
964
965 new_i_ele = int(round(data_ele[0]))
965 new_i_ele = int(round(data_ele[0]))
966 new_f_ele = int(round(data_ele[-1]))
966 new_f_ele = int(round(data_ele[-1]))
967 #print(data_ele)
967 #print(data_ele)
968 #print(ang_max)
968 #print(ang_max)
969 #print(data_ele_old)
969 #print(data_ele_old)
970 if new_i_ele <= 1:
970 if new_i_ele <= 1:
971 new_i_ele = 1
971 new_i_ele = 1
972 if round(data_ele[-1])>=ang_max-1:
972 if round(data_ele[-1])>=ang_max-1:
973 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
973 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
974 self.res_weather[val_ch] = self.replaceNAN(data_weather=self.res_weather[val_ch],data_ele=self.data_ele_tmp[val_ch],val=self.val_mean)
974 self.res_weather[val_ch] = self.replaceNAN(data_weather=self.res_weather[val_ch],data_ele=self.data_ele_tmp[val_ch],val=self.val_mean)
975 self.data_ele_tmp[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1]=data_ele_old
975 self.data_ele_tmp[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1]=data_ele_old
976 self.res_ele[new_i_ele-1:new_i_ele+len(data_ele)-1]= data_ele
976 self.res_ele[new_i_ele-1:new_i_ele+len(data_ele)-1]= data_ele
977 self.res_weather[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1,:]= data_weather
977 self.res_weather[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1,:]= data_weather
978 data_ele = self.res_ele
978 data_ele = self.res_ele
979 data_weather = self.res_weather[val_ch]
979 data_weather = self.res_weather[val_ch]
980
980
981 elif tipo_case==2: #bajada
981 elif tipo_case==2: #bajada
982 vec = numpy.where(data_ele<ang_max)
982 vec = numpy.where(data_ele<ang_max)
983 data_ele = data_ele[vec]
983 data_ele = data_ele[vec]
984 data_weather= data_weather[vec[0]]
984 data_weather= data_weather[vec[0]]
985
985
986 len_vec = len(vec)
986 len_vec = len(vec)
987 data_ele_new = data_ele[::-1] # reversa
987 data_ele_new = data_ele[::-1] # reversa
988 data_weather = data_weather[::-1,:]
988 data_weather = data_weather[::-1,:]
989 new_i_ele = int(data_ele_new[0])
989 new_i_ele = int(data_ele_new[0])
990 new_f_ele = int(data_ele_new[-1])
990 new_f_ele = int(data_ele_new[-1])
991
991
992 n1= new_i_ele- ang_min
992 n1= new_i_ele- ang_min
993 n2= ang_max - new_f_ele-1
993 n2= ang_max - new_f_ele-1
994 if n1>0:
994 if n1>0:
995 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
995 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
996 ele1_nan= numpy.ones(n1)*numpy.nan
996 ele1_nan= numpy.ones(n1)*numpy.nan
997 data_ele = numpy.hstack((ele1,data_ele_new))
997 data_ele = numpy.hstack((ele1,data_ele_new))
998 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
998 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
999 if n2>0:
999 if n2>0:
1000 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1000 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1001 ele2_nan= numpy.ones(n2)*numpy.nan
1001 ele2_nan= numpy.ones(n2)*numpy.nan
1002 data_ele = numpy.hstack((data_ele,ele2))
1002 data_ele = numpy.hstack((data_ele,ele2))
1003 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1003 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1004
1004
1005 self.data_ele_tmp[val_ch] = data_ele_old
1005 self.data_ele_tmp[val_ch] = data_ele_old
1006 self.res_ele = data_ele
1006 self.res_ele = data_ele
1007 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1007 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1008 data_ele = self.res_ele
1008 data_ele = self.res_ele
1009 data_weather = self.res_weather[val_ch]
1009 data_weather = self.res_weather[val_ch]
1010
1010
1011 elif tipo_case==3:#subida
1011 elif tipo_case==3:#subida
1012 vec = numpy.where(0<data_ele)
1012 vec = numpy.where(0<data_ele)
1013 data_ele= data_ele[vec]
1013 data_ele= data_ele[vec]
1014 data_ele_new = data_ele
1014 data_ele_new = data_ele
1015 data_ele_old= data_ele_old[vec]
1015 data_ele_old= data_ele_old[vec]
1016 data_weather= data_weather[vec[0]]
1016 data_weather= data_weather[vec[0]]
1017 pos_ini = numpy.argmin(data_ele)
1017 pos_ini = numpy.argmin(data_ele)
1018 if pos_ini>0:
1018 if pos_ini>0:
1019 len_vec= len(data_ele)
1019 len_vec= len(data_ele)
1020 vec3 = numpy.linspace(pos_ini,len_vec-1,len_vec-pos_ini).astype(int)
1020 vec3 = numpy.linspace(pos_ini,len_vec-1,len_vec-pos_ini).astype(int)
1021 #print(vec3)
1021 #print(vec3)
1022 data_ele= data_ele[vec3]
1022 data_ele= data_ele[vec3]
1023 data_ele_new = data_ele
1023 data_ele_new = data_ele
1024 data_ele_old= data_ele_old[vec3]
1024 data_ele_old= data_ele_old[vec3]
1025 data_weather= data_weather[vec3]
1025 data_weather= data_weather[vec3]
1026
1026
1027 new_i_ele = int(data_ele_new[0])
1027 new_i_ele = int(data_ele_new[0])
1028 new_f_ele = int(data_ele_new[-1])
1028 new_f_ele = int(data_ele_new[-1])
1029 n1= new_i_ele- ang_min
1029 n1= new_i_ele- ang_min
1030 n2= ang_max - new_f_ele-1
1030 n2= ang_max - new_f_ele-1
1031 if n1>0:
1031 if n1>0:
1032 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
1032 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
1033 ele1_nan= numpy.ones(n1)*numpy.nan
1033 ele1_nan= numpy.ones(n1)*numpy.nan
1034 data_ele = numpy.hstack((ele1,data_ele_new))
1034 data_ele = numpy.hstack((ele1,data_ele_new))
1035 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
1035 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
1036 if n2>0:
1036 if n2>0:
1037 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1037 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1038 ele2_nan= numpy.ones(n2)*numpy.nan
1038 ele2_nan= numpy.ones(n2)*numpy.nan
1039 data_ele = numpy.hstack((data_ele,ele2))
1039 data_ele = numpy.hstack((data_ele,ele2))
1040 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1040 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1041
1041
1042 self.data_ele_tmp[val_ch] = data_ele_old
1042 self.data_ele_tmp[val_ch] = data_ele_old
1043 self.res_ele = data_ele
1043 self.res_ele = data_ele
1044 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1044 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1045 data_ele = self.res_ele
1045 data_ele = self.res_ele
1046 data_weather = self.res_weather[val_ch]
1046 data_weather = self.res_weather[val_ch]
1047 #print("self.data_ele_tmp",self.data_ele_tmp)
1047 #print("self.data_ele_tmp",self.data_ele_tmp)
1048 return data_weather,data_ele
1048 return data_weather,data_ele
1049
1049
1050
1050
1051 def plot(self):
1051 def plot(self):
1052 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
1052 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
1053 data = self.data[-1]
1053 data = self.data[-1]
1054 r = self.data.yrange
1054 r = self.data.yrange
1055 delta_height = r[1]-r[0]
1055 delta_height = r[1]-r[0]
1056 r_mask = numpy.where(r>=0)[0]
1056 r_mask = numpy.where(r>=0)[0]
1057 ##print("delta_height",delta_height)
1057 ##print("delta_height",delta_height)
1058 #print("r_mask",r_mask,len(r_mask))
1058 #print("r_mask",r_mask,len(r_mask))
1059 r = numpy.arange(len(r_mask))*delta_height
1059 r = numpy.arange(len(r_mask))*delta_height
1060 self.y = 2*r
1060 self.y = 2*r
1061 res = 1
1061 res = 1
1062 ###print("data['weather'].shape[0]",data['weather'].shape[0])
1062 ###print("data['weather'].shape[0]",data['weather'].shape[0])
1063 ang_max = self.ang_max
1063 ang_max = self.ang_max
1064 ang_min = self.ang_min
1064 ang_min = self.ang_min
1065 var_ang =ang_max - ang_min
1065 var_ang =ang_max - ang_min
1066 step = (int(var_ang)/(res*data['weather'].shape[0]))
1066 step = (int(var_ang)/(res*data['weather'].shape[0]))
1067 ###print("step",step)
1067 ###print("step",step)
1068 #--------------------------------------------------------
1068 #--------------------------------------------------------
1069 ##print('weather',data['weather'].shape)
1069 ##print('weather',data['weather'].shape)
1070 ##print('ele',data['ele'].shape)
1070 ##print('ele',data['ele'].shape)
1071
1071
1072 ###self.res_weather, self.res_ele = self.const_ploteo(data_weather=data['weather'][:,r_mask],data_ele=data['ele'],step=step,res=res,ang_max=ang_max,ang_min=ang_min)
1072 ###self.res_weather, self.res_ele = self.const_ploteo(data_weather=data['weather'][:,r_mask],data_ele=data['ele'],step=step,res=res,ang_max=ang_max,ang_min=ang_min)
1073 ###self.res_azi = numpy.mean(data['azi'])
1073 ###self.res_azi = numpy.mean(data['azi'])
1074 ###print("self.res_ele",self.res_ele)
1074 ###print("self.res_ele",self.res_ele)
1075 plt.clf()
1075 plt.clf()
1076 subplots = [121, 122]
1076 subplots = [121, 122]
1077 cg={'angular_spacing': 20.}
1077 cg={'angular_spacing': 20.}
1078 if self.ini==0:
1078 if self.ini==0:
1079 self.data_ele_tmp = numpy.ones([self.nplots,int(var_ang)])*numpy.nan
1079 self.data_ele_tmp = numpy.ones([self.nplots,int(var_ang)])*numpy.nan
1080 self.res_weather= numpy.ones([self.nplots,int(var_ang),len(r_mask)])*numpy.nan
1080 self.res_weather= numpy.ones([self.nplots,int(var_ang),len(r_mask)])*numpy.nan
1081 print("SHAPE",self.data_ele_tmp.shape)
1081 print("SHAPE",self.data_ele_tmp.shape)
1082
1082
1083 for i,ax in enumerate(self.axes):
1083 for i,ax in enumerate(self.axes):
1084 self.res_weather[i], self.res_ele = self.const_ploteo(val_ch=i, data_weather=data['weather'][i][:,r_mask],data_ele=data['ele'],step=step,res=res,ang_max=ang_max,ang_min=ang_min)
1084 self.res_weather[i], self.res_ele = self.const_ploteo(val_ch=i, data_weather=data['weather'][i][:,r_mask],data_ele=data['ele'],step=step,res=res,ang_max=ang_max,ang_min=ang_min)
1085 self.res_azi = numpy.mean(data['azi'])
1085 self.res_azi = numpy.mean(data['azi'])
1086 if i==0:
1086 if i==0:
1087 print("*****************************************************************************to plot**************************",self.res_weather[i].shape)
1087 print("*****************************************************************************to plot**************************",self.res_weather[i].shape)
1088 self.zmin = self.zmin if self.zmin else 20
1088 self.zmin = self.zmin if self.zmin else 20
1089 self.zmax = self.zmax if self.zmax else 80
1089 self.zmax = self.zmax if self.zmax else 80
1090 if ax.firsttime:
1090 if ax.firsttime:
1091 #plt.clf()
1091 #plt.clf()
1092 cgax, pm = wrl.vis.plot_rhi(self.res_weather[i],r=r,th=self.res_ele,ax=subplots[i], proj=cg,vmin=self.zmin, vmax=self.zmax)
1092 cgax, pm = wrl.vis.plot_rhi(self.res_weather[i],r=r,th=self.res_ele,ax=subplots[i], proj=cg,vmin=self.zmin, vmax=self.zmax)
1093 #fig=self.figures[0]
1093 #fig=self.figures[0]
1094 else:
1094 else:
1095 #plt.clf()
1095 #plt.clf()
1096 if i==0:
1096 if i==0:
1097 print(self.res_weather[i])
1097 print(self.res_weather[i])
1098 print(self.res_ele)
1098 print(self.res_ele)
1099 cgax, pm = wrl.vis.plot_rhi(self.res_weather[i],r=r,th=self.res_ele,ax=subplots[i], proj=cg,vmin=self.zmin, vmax=self.zmax)
1099 cgax, pm = wrl.vis.plot_rhi(self.res_weather[i],r=r,th=self.res_ele,ax=subplots[i], proj=cg,vmin=self.zmin, vmax=self.zmax)
1100 caax = cgax.parasites[0]
1100 caax = cgax.parasites[0]
1101 paax = cgax.parasites[1]
1101 paax = cgax.parasites[1]
1102 cbar = plt.gcf().colorbar(pm, pad=0.075)
1102 cbar = plt.gcf().colorbar(pm, pad=0.075)
1103 caax.set_xlabel('x_range [km]')
1103 caax.set_xlabel('x_range [km]')
1104 caax.set_ylabel('y_range [km]')
1104 caax.set_ylabel('y_range [km]')
1105 plt.text(1.0, 1.05, 'Elevacion '+str(thisDatetime)+" Step "+str(self.ini)+ " Azi: "+str(round(self.res_azi,2)), transform=caax.transAxes, va='bottom',ha='right')
1105 plt.text(1.0, 1.05, 'Elevacion '+str(thisDatetime)+" Step "+str(self.ini)+ " Azi: "+str(round(self.res_azi,2)), transform=caax.transAxes, va='bottom',ha='right')
1106 print("***************************self.ini****************************",self.ini)
1106 print("***************************self.ini****************************",self.ini)
1107 self.ini= self.ini+1
1107 self.ini= self.ini+1
1108
1108
1109 class Weather_vRF_Plot(Plot):
1109 class Weather_vRF_Plot(Plot):
1110 CODE = 'PPI'
1110 CODE = 'PPI'
1111 plot_name = 'PPI'
1111 plot_name = 'PPI'
1112 #plot_type = 'ppistyle'
1112 #plot_type = 'ppistyle'
1113 buffering = False
1113 buffering = False
1114
1114
1115 def setup(self):
1115 def setup(self):
1116
1116
1117 self.ncols = 1
1117 self.ncols = 1
1118 self.nrows = 1
1118 self.nrows = 1
1119 self.width =8
1119 self.width =8
1120 self.height =8
1120 self.height =8
1121 self.nplots= 1
1121 self.nplots= 1
1122 self.ylabel= 'Range [Km]'
1122 self.ylabel= 'Range [Km]'
1123 self.xlabel= 'Range [Km]'
1123 self.xlabel= 'Range [Km]'
1124 self.titles= ['PPI']
1124 self.titles= ['PPI']
1125 self.polar = True
1125 self.polar = True
1126 if self.channels is not None:
1126 if self.channels is not None:
1127 self.nplots = len(self.channels)
1127 self.nplots = len(self.channels)
1128 self.nrows = len(self.channels)
1128 self.nrows = len(self.channels)
1129 else:
1129 else:
1130 self.nplots = self.data.shape(self.CODE)[0]
1130 self.nplots = self.data.shape(self.CODE)[0]
1131 self.nrows = self.nplots
1131 self.nrows = self.nplots
1132 self.channels = list(range(self.nplots))
1132 self.channels = list(range(self.nplots))
1133
1133
1134 if self.CODE == 'POWER':
1134 if self.CODE == 'POWER':
1135 self.cb_label = r'Power (dB)'
1135 self.cb_label = r'Power (dB)'
1136 elif self.CODE == 'DOPPLER':
1136 elif self.CODE == 'DOPPLER':
1137 self.cb_label = r'Velocity (m/s)'
1137 self.cb_label = r'Velocity (m/s)'
1138 self.colorbar=True
1138 self.colorbar=True
1139 self.width = 9
1139 self.width = 9
1140 self.height =8
1140 self.height =8
1141 self.ini =0
1141 self.ini =0
1142 self.len_azi =0
1142 self.len_azi =0
1143 self.buffer_ini = None
1143 self.buffer_ini = None
1144 self.buffer_ele = None
1144 self.buffer_ele = None
1145 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.15, 'right': 0.9, 'bottom': 0.08})
1145 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.15, 'right': 0.9, 'bottom': 0.08})
1146 self.flag =0
1146 self.flag =0
1147 self.indicador= 0
1147 self.indicador= 0
1148 self.last_data_ele = None
1148 self.last_data_ele = None
1149 self.val_mean = None
1149 self.val_mean = None
1150
1150
1151 def update(self, dataOut):
1151 def update(self, dataOut):
1152
1152
1153 data = {}
1153 data = {}
1154 meta = {}
1154 meta = {}
1155 if hasattr(dataOut, 'dataPP_POWER'):
1155 if hasattr(dataOut, 'dataPP_POWER'):
1156 factor = 1
1156 factor = 1
1157 if hasattr(dataOut, 'nFFTPoints'):
1157 if hasattr(dataOut, 'nFFTPoints'):
1158 factor = dataOut.normFactor
1158 factor = dataOut.normFactor
1159
1159
1160 if 'pow' in self.attr_data[0].lower():
1160 if 'pow' in self.attr_data[0].lower():
1161 data['data'] = 10*numpy.log10(getattr(dataOut, self.attr_data[0])/(factor))
1161 data['data'] = 10*numpy.log10(getattr(dataOut, self.attr_data[0])/(factor))
1162 else:
1162 else:
1163 data['data'] = getattr(dataOut, self.attr_data[0])/(factor)
1163 data['data'] = getattr(dataOut, self.attr_data[0])/(factor)
1164
1164
1165 data['azi'] = dataOut.data_azi
1165 data['azi'] = dataOut.data_azi
1166 data['ele'] = dataOut.data_ele
1166 data['ele'] = dataOut.data_ele
1167
1167
1168 return data, meta
1168 return data, meta
1169
1169
1170 def plot(self):
1170 def plot(self):
1171 data = self.data[-1]
1171 data = self.data[-1]
1172 r = self.data.yrange
1172 r = self.data.yrange
1173 delta_height = r[1]-r[0]
1173 delta_height = r[1]-r[0]
1174 r_mask = numpy.where(r>=0)[0]
1174 r_mask = numpy.where(r>=0)[0]
1175 self.r_mask = r_mask
1175 self.r_mask = r_mask
1176 r = numpy.arange(len(r_mask))*delta_height
1176 r = numpy.arange(len(r_mask))*delta_height
1177 self.y = 2*r
1177 self.y = 2*r
1178
1178
1179 try:
1179 try:
1180 z = data['data'][self.channels[0]][:,r_mask]
1180 z = data['data'][self.channels[0]][:,r_mask]
1181
1181
1182 except:
1182 except:
1183 z = data['data'][0][:,r_mask]
1183 z = data['data'][0][:,r_mask]
1184
1184
1185 self.titles = []
1185 self.titles = []
1186
1186
1187 self.ymax = self.ymax if self.ymax else numpy.nanmax(r)
1187 self.ymax = self.ymax if self.ymax else numpy.nanmax(r)
1188 self.ymin = self.ymin if self.ymin else numpy.nanmin(r)
1188 self.ymin = self.ymin if self.ymin else numpy.nanmin(r)
1189 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
1189 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
1190 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
1190 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
1191 self.ang_min = self.ang_min if self.ang_min else 0
1191 self.ang_min = self.ang_min if self.ang_min else 0
1192 self.ang_max = self.ang_max if self.ang_max else 360
1192 self.ang_max = self.ang_max if self.ang_max else 360
1193
1193
1194 r, theta = numpy.meshgrid(r, numpy.radians(data['azi']) )
1194 r, theta = numpy.meshgrid(r, numpy.radians(data['azi']) )
1195
1195
1196 for i,ax in enumerate(self.axes):
1196 for i,ax in enumerate(self.axes):
1197
1197
1198 if ax.firsttime:
1198 if ax.firsttime:
1199 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1199 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1200 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1200 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1201 ax.set_theta_direction(-1)
1201 ax.set_theta_direction(-1)
1202
1202
1203 else:
1203 else:
1204 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1204 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1205 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1205 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1206 ax.set_theta_direction(-1)
1206 ax.set_theta_direction(-1)
1207
1207
1208 ax.grid(True)
1208 ax.grid(True)
1209
1209
1210 if len(self.channels) !=1:
1210 if len(self.channels) !=1:
1211 self.titles = ['PPI {} at EL: {} Channel {}'.format(self.self.labels[x], str(round(numpy.mean(data['ele']),1)), x) for x in range(self.nrows)]
1211 self.titles = ['PPI {} at EL: {} Channel {}'.format(self.self.labels[x], str(round(numpy.mean(data['ele']),1)), x) for x in range(self.nrows)]
1212 else:
1212 else:
1213 self.titles = ['PPI {} at EL: {} Channel {}'.format(self.labels[0], str(round(numpy.mean(data['ele']),1)), self.channels[0])]
1213 self.titles = ['PPI {} at EL: {} Channel {}'.format(self.labels[0], str(round(numpy.mean(data['ele']),1)), self.channels[0])]
1214
1214
1215 class WeatherRHI_vRF2_Plot(Plot):
1215 class WeatherRHI_vRF2_Plot(Plot):
1216 CODE = 'weather'
1216 CODE = 'weather'
1217 plot_name = 'weather'
1217 plot_name = 'weather'
1218 plot_type = 'rhistyle'
1218 plot_type = 'rhistyle'
1219 buffering = False
1219 buffering = False
1220 data_ele_tmp = None
1220 data_ele_tmp = None
1221
1221
1222 def setup(self):
1222 def setup(self):
1223 print("********************")
1223 print("********************")
1224 print("********************")
1224 print("********************")
1225 print("********************")
1225 print("********************")
1226 print("SETUP WEATHER PLOT")
1226 print("SETUP WEATHER PLOT")
1227 self.ncols = 1
1227 self.ncols = 1
1228 self.nrows = 1
1228 self.nrows = 1
1229 self.nplots= 1
1229 self.nplots= 1
1230 self.ylabel= 'Range [Km]'
1230 self.ylabel= 'Range [Km]'
1231 self.titles= ['Weather']
1231 self.titles= ['Weather']
1232 if self.channels is not None:
1232 if self.channels is not None:
1233 self.nplots = len(self.channels)
1233 self.nplots = len(self.channels)
1234 self.nrows = len(self.channels)
1234 self.nrows = len(self.channels)
1235 else:
1235 else:
1236 self.nplots = self.data.shape(self.CODE)[0]
1236 self.nplots = self.data.shape(self.CODE)[0]
1237 self.nrows = self.nplots
1237 self.nrows = self.nplots
1238 self.channels = list(range(self.nplots))
1238 self.channels = list(range(self.nplots))
1239 print("channels",self.channels)
1239 print("channels",self.channels)
1240 print("que saldra", self.data.shape(self.CODE)[0])
1240 print("que saldra", self.data.shape(self.CODE)[0])
1241 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
1241 self.titles = ['{} Channel {}'.format(self.CODE.upper(), x) for x in range(self.nrows)]
1242 print("self.titles",self.titles)
1242 print("self.titles",self.titles)
1243 self.colorbar=False
1243 self.colorbar=False
1244 self.width =8
1244 self.width =8
1245 self.height =8
1245 self.height =8
1246 self.ini =0
1246 self.ini =0
1247 self.len_azi =0
1247 self.len_azi =0
1248 self.buffer_ini = None
1248 self.buffer_ini = None
1249 self.buffer_ele = None
1249 self.buffer_ele = None
1250 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
1250 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
1251 self.flag =0
1251 self.flag =0
1252 self.indicador= 0
1252 self.indicador= 0
1253 self.last_data_ele = None
1253 self.last_data_ele = None
1254 self.val_mean = None
1254 self.val_mean = None
1255
1255
1256 def update(self, dataOut):
1256 def update(self, dataOut):
1257
1257
1258 data = {}
1258 data = {}
1259 meta = {}
1259 meta = {}
1260 if hasattr(dataOut, 'dataPP_POWER'):
1260 if hasattr(dataOut, 'dataPP_POWER'):
1261 factor = 1
1261 factor = 1
1262 if hasattr(dataOut, 'nFFTPoints'):
1262 if hasattr(dataOut, 'nFFTPoints'):
1263 factor = dataOut.normFactor
1263 factor = dataOut.normFactor
1264 print("dataOut",dataOut.data_360.shape)
1264 print("dataOut",dataOut.data_360.shape)
1265 #
1265 #
1266 data['weather'] = 10*numpy.log10(dataOut.data_360/(factor))
1266 data['weather'] = 10*numpy.log10(dataOut.data_360/(factor))
1267 #
1267 #
1268 #data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
1268 #data['weather'] = 10*numpy.log10(dataOut.data_360[1]/(factor))
1269 data['azi'] = dataOut.data_azi
1269 data['azi'] = dataOut.data_azi
1270 data['ele'] = dataOut.data_ele
1270 data['ele'] = dataOut.data_ele
1271 data['case_flag'] = dataOut.case_flag
1271 data['case_flag'] = dataOut.case_flag
1272 #print("UPDATE")
1272 #print("UPDATE")
1273 #print("data[weather]",data['weather'].shape)
1273 #print("data[weather]",data['weather'].shape)
1274 #print("data[azi]",data['azi'])
1274 #print("data[azi]",data['azi'])
1275 return data, meta
1275 return data, meta
1276
1276
1277 def get2List(self,angulos):
1277 def get2List(self,angulos):
1278 list1=[]
1278 list1=[]
1279 list2=[]
1279 list2=[]
1280 for i in reversed(range(len(angulos))):
1280 for i in reversed(range(len(angulos))):
1281 if not i==0:#el caso de i=0 evalula el primero de la lista con el ultimo y no es relevante
1281 if not i==0:#el caso de i=0 evalula el primero de la lista con el ultimo y no es relevante
1282 diff_ = angulos[i]-angulos[i-1]
1282 diff_ = angulos[i]-angulos[i-1]
1283 if abs(diff_) >1.5:
1283 if abs(diff_) >1.5:
1284 list1.append(i-1)
1284 list1.append(i-1)
1285 list2.append(diff_)
1285 list2.append(diff_)
1286 return list(reversed(list1)),list(reversed(list2))
1286 return list(reversed(list1)),list(reversed(list2))
1287
1287
1288 def fixData90(self,list_,ang_):
1288 def fixData90(self,list_,ang_):
1289 if list_[0]==-1:
1289 if list_[0]==-1:
1290 vec = numpy.where(ang_<ang_[0])
1290 vec = numpy.where(ang_<ang_[0])
1291 ang_[vec] = ang_[vec]+90
1291 ang_[vec] = ang_[vec]+90
1292 return ang_
1292 return ang_
1293 return ang_
1293 return ang_
1294
1294
1295 def fixData90HL(self,angulos):
1295 def fixData90HL(self,angulos):
1296 vec = numpy.where(angulos>=90)
1296 vec = numpy.where(angulos>=90)
1297 angulos[vec]=angulos[vec]-90
1297 angulos[vec]=angulos[vec]-90
1298 return angulos
1298 return angulos
1299
1299
1300
1300
1301 def search_pos(self,pos,list_):
1301 def search_pos(self,pos,list_):
1302 for i in range(len(list_)):
1302 for i in range(len(list_)):
1303 if pos == list_[i]:
1303 if pos == list_[i]:
1304 return True,i
1304 return True,i
1305 i=None
1305 i=None
1306 return False,i
1306 return False,i
1307
1307
1308 def fixDataComp(self,ang_,list1_,list2_,tipo_case):
1308 def fixDataComp(self,ang_,list1_,list2_,tipo_case):
1309 size = len(ang_)
1309 size = len(ang_)
1310 size2 = 0
1310 size2 = 0
1311 for i in range(len(list2_)):
1311 for i in range(len(list2_)):
1312 size2=size2+round(abs(list2_[i]))-1
1312 size2=size2+round(abs(list2_[i]))-1
1313 new_size= size+size2
1313 new_size= size+size2
1314 ang_new = numpy.zeros(new_size)
1314 ang_new = numpy.zeros(new_size)
1315 ang_new2 = numpy.zeros(new_size)
1315 ang_new2 = numpy.zeros(new_size)
1316
1316
1317 tmp = 0
1317 tmp = 0
1318 c = 0
1318 c = 0
1319 for i in range(len(ang_)):
1319 for i in range(len(ang_)):
1320 ang_new[tmp +c] = ang_[i]
1320 ang_new[tmp +c] = ang_[i]
1321 ang_new2[tmp+c] = ang_[i]
1321 ang_new2[tmp+c] = ang_[i]
1322 condition , value = self.search_pos(i,list1_)
1322 condition , value = self.search_pos(i,list1_)
1323 if condition:
1323 if condition:
1324 pos = tmp + c + 1
1324 pos = tmp + c + 1
1325 for k in range(round(abs(list2_[value]))-1):
1325 for k in range(round(abs(list2_[value]))-1):
1326 if tipo_case==0 or tipo_case==3:#subida
1326 if tipo_case==0 or tipo_case==3:#subida
1327 ang_new[pos+k] = ang_new[pos+k-1]+1
1327 ang_new[pos+k] = ang_new[pos+k-1]+1
1328 ang_new2[pos+k] = numpy.nan
1328 ang_new2[pos+k] = numpy.nan
1329 elif tipo_case==1 or tipo_case==2:#bajada
1329 elif tipo_case==1 or tipo_case==2:#bajada
1330 ang_new[pos+k] = ang_new[pos+k-1]-1
1330 ang_new[pos+k] = ang_new[pos+k-1]-1
1331 ang_new2[pos+k] = numpy.nan
1331 ang_new2[pos+k] = numpy.nan
1332
1332
1333 tmp = pos +k
1333 tmp = pos +k
1334 c = 0
1334 c = 0
1335 c=c+1
1335 c=c+1
1336 return ang_new,ang_new2
1336 return ang_new,ang_new2
1337
1337
1338 def globalCheckPED(self,angulos,tipo_case):
1338 def globalCheckPED(self,angulos,tipo_case):
1339 l1,l2 = self.get2List(angulos)
1339 l1,l2 = self.get2List(angulos)
1340 ##print("l1",l1)
1340 ##print("l1",l1)
1341 ##print("l2",l2)
1341 ##print("l2",l2)
1342 if len(l1)>0:
1342 if len(l1)>0:
1343 #angulos2 = self.fixData90(list_=l1,ang_=angulos)
1343 #angulos2 = self.fixData90(list_=l1,ang_=angulos)
1344 #l1,l2 = self.get2List(angulos2)
1344 #l1,l2 = self.get2List(angulos2)
1345 ang1_,ang2_ = self.fixDataComp(ang_=angulos,list1_=l1,list2_=l2,tipo_case=tipo_case)
1345 ang1_,ang2_ = self.fixDataComp(ang_=angulos,list1_=l1,list2_=l2,tipo_case=tipo_case)
1346 #ang1_ = self.fixData90HL(ang1_)
1346 #ang1_ = self.fixData90HL(ang1_)
1347 #ang2_ = self.fixData90HL(ang2_)
1347 #ang2_ = self.fixData90HL(ang2_)
1348 else:
1348 else:
1349 ang1_= angulos
1349 ang1_= angulos
1350 ang2_= angulos
1350 ang2_= angulos
1351 return ang1_,ang2_
1351 return ang1_,ang2_
1352
1352
1353
1353
1354 def replaceNAN(self,data_weather,data_ele,val):
1354 def replaceNAN(self,data_weather,data_ele,val):
1355 data= data_ele
1355 data= data_ele
1356 data_T= data_weather
1356 data_T= data_weather
1357 if data.shape[0]> data_T.shape[0]:
1357 if data.shape[0]> data_T.shape[0]:
1358 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
1358 data_N = numpy.ones( [data.shape[0],data_T.shape[1]])
1359 c = 0
1359 c = 0
1360 for i in range(len(data)):
1360 for i in range(len(data)):
1361 if numpy.isnan(data[i]):
1361 if numpy.isnan(data[i]):
1362 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
1362 data_N[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
1363 else:
1363 else:
1364 data_N[i,:]=data_T[c,:]
1364 data_N[i,:]=data_T[c,:]
1365 c=c+1
1365 c=c+1
1366 return data_N
1366 return data_N
1367 else:
1367 else:
1368 for i in range(len(data)):
1368 for i in range(len(data)):
1369 if numpy.isnan(data[i]):
1369 if numpy.isnan(data[i]):
1370 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
1370 data_T[i,:]=numpy.ones(data_T.shape[1])*numpy.nan
1371 return data_T
1371 return data_T
1372
1372
1373 def check_case(self,data_ele,ang_max,ang_min):
1373 def check_case(self,data_ele,ang_max,ang_min):
1374 start = data_ele[0]
1374 start = data_ele[0]
1375 end = data_ele[-1]
1375 end = data_ele[-1]
1376 number = (end-start)
1376 number = (end-start)
1377 len_ang=len(data_ele)
1377 len_ang=len(data_ele)
1378 print("start",start)
1378 print("start",start)
1379 print("end",end)
1379 print("end",end)
1380 print("number",number)
1380 print("number",number)
1381
1381
1382 print("len_ang",len_ang)
1382 print("len_ang",len_ang)
1383
1383
1384 #exit(1)
1384 #exit(1)
1385
1385
1386 if start<end and (round(abs(number)+1)>=len_ang or (numpy.argmin(data_ele)==0)):#caso subida
1386 if start<end and (round(abs(number)+1)>=len_ang or (numpy.argmin(data_ele)==0)):#caso subida
1387 return 0
1387 return 0
1388 #elif start>end and (round(abs(number)+1)>=len_ang or(numpy.argmax(data_ele)==0)):#caso bajada
1388 #elif start>end and (round(abs(number)+1)>=len_ang or(numpy.argmax(data_ele)==0)):#caso bajada
1389 # return 1
1389 # return 1
1390 elif round(abs(number)+1)>=len_ang and (start>end or(numpy.argmax(data_ele)==0)):#caso bajada
1390 elif round(abs(number)+1)>=len_ang and (start>end or(numpy.argmax(data_ele)==0)):#caso bajada
1391 return 1
1391 return 1
1392 elif round(abs(number)+1)<len_ang and data_ele[-2]>data_ele[-1]:# caso BAJADA CAMBIO ANG MAX
1392 elif round(abs(number)+1)<len_ang and data_ele[-2]>data_ele[-1]:# caso BAJADA CAMBIO ANG MAX
1393 return 2
1393 return 2
1394 elif round(abs(number)+1)<len_ang and data_ele[-2]<data_ele[-1] :# caso SUBIDA CAMBIO ANG MIN
1394 elif round(abs(number)+1)<len_ang and data_ele[-2]<data_ele[-1] :# caso SUBIDA CAMBIO ANG MIN
1395 return 3
1395 return 3
1396
1396
1397
1397
1398 def const_ploteo(self,val_ch,data_weather,data_ele,step,res,ang_max,ang_min,case_flag):
1398 def const_ploteo(self,val_ch,data_weather,data_ele,step,res,ang_max,ang_min,case_flag):
1399 ang_max= ang_max
1399 ang_max= ang_max
1400 ang_min= ang_min
1400 ang_min= ang_min
1401 data_weather=data_weather
1401 data_weather=data_weather
1402 val_ch=val_ch
1402 val_ch=val_ch
1403 ##print("*********************DATA WEATHER**************************************")
1403 ##print("*********************DATA WEATHER**************************************")
1404 ##print(data_weather)
1404 ##print(data_weather)
1405 if self.ini==0:
1405 if self.ini==0:
1406 '''
1406 '''
1407 print("**********************************************")
1407 print("**********************************************")
1408 print("**********************************************")
1408 print("**********************************************")
1409 print("***************ini**************")
1409 print("***************ini**************")
1410 print("**********************************************")
1410 print("**********************************************")
1411 print("**********************************************")
1411 print("**********************************************")
1412 '''
1412 '''
1413 #print("data_ele",data_ele)
1413 #print("data_ele",data_ele)
1414 #----------------------------------------------------------
1414 #----------------------------------------------------------
1415 tipo_case = case_flag[-1]
1415 tipo_case = case_flag[-1]
1416 #tipo_case = self.check_case(data_ele,ang_max,ang_min)
1416 #tipo_case = self.check_case(data_ele,ang_max,ang_min)
1417 print("check_case",tipo_case)
1417 print("check_case",tipo_case)
1418 #exit(1)
1418 #exit(1)
1419 #--------------------- new -------------------------
1419 #--------------------- new -------------------------
1420 data_ele_new ,data_ele_old= self.globalCheckPED(data_ele,tipo_case)
1420 data_ele_new ,data_ele_old= self.globalCheckPED(data_ele,tipo_case)
1421
1421
1422 #-------------------------CAMBIOS RHI---------------------------------
1422 #-------------------------CAMBIOS RHI---------------------------------
1423 start= ang_min
1423 start= ang_min
1424 end = ang_max
1424 end = ang_max
1425 n= (ang_max-ang_min)/res
1425 n= (ang_max-ang_min)/res
1426 #------ new
1426 #------ new
1427 self.start_data_ele = data_ele_new[0]
1427 self.start_data_ele = data_ele_new[0]
1428 self.end_data_ele = data_ele_new[-1]
1428 self.end_data_ele = data_ele_new[-1]
1429 if tipo_case==0 or tipo_case==3: # SUBIDA
1429 if tipo_case==0 or tipo_case==3: # SUBIDA
1430 n1= round(self.start_data_ele)- start
1430 n1= round(self.start_data_ele)- start
1431 n2= end - round(self.end_data_ele)
1431 n2= end - round(self.end_data_ele)
1432 print(self.start_data_ele)
1432 print(self.start_data_ele)
1433 print(self.end_data_ele)
1433 print(self.end_data_ele)
1434 if n1>0:
1434 if n1>0:
1435 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
1435 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
1436 ele1_nan= numpy.ones(n1)*numpy.nan
1436 ele1_nan= numpy.ones(n1)*numpy.nan
1437 data_ele = numpy.hstack((ele1,data_ele_new))
1437 data_ele = numpy.hstack((ele1,data_ele_new))
1438 print("ele1_nan",ele1_nan.shape)
1438 print("ele1_nan",ele1_nan.shape)
1439 print("data_ele_old",data_ele_old.shape)
1439 print("data_ele_old",data_ele_old.shape)
1440 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
1440 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
1441 if n2>0:
1441 if n2>0:
1442 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
1442 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
1443 ele2_nan= numpy.ones(n2)*numpy.nan
1443 ele2_nan= numpy.ones(n2)*numpy.nan
1444 data_ele = numpy.hstack((data_ele,ele2))
1444 data_ele = numpy.hstack((data_ele,ele2))
1445 print("ele2_nan",ele2_nan.shape)
1445 print("ele2_nan",ele2_nan.shape)
1446 print("data_ele_old",data_ele_old.shape)
1446 print("data_ele_old",data_ele_old.shape)
1447 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1447 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1448
1448
1449 if tipo_case==1 or tipo_case==2: # BAJADA
1449 if tipo_case==1 or tipo_case==2: # BAJADA
1450 data_ele_new = data_ele_new[::-1] # reversa
1450 data_ele_new = data_ele_new[::-1] # reversa
1451 data_ele_old = data_ele_old[::-1]# reversa
1451 data_ele_old = data_ele_old[::-1]# reversa
1452 data_weather = data_weather[::-1,:]# reversa
1452 data_weather = data_weather[::-1,:]# reversa
1453 vec= numpy.where(data_ele_new<ang_max)
1453 vec= numpy.where(data_ele_new<ang_max)
1454 data_ele_new = data_ele_new[vec]
1454 data_ele_new = data_ele_new[vec]
1455 data_ele_old = data_ele_old[vec]
1455 data_ele_old = data_ele_old[vec]
1456 data_weather = data_weather[vec[0]]
1456 data_weather = data_weather[vec[0]]
1457 vec2= numpy.where(0<data_ele_new)
1457 vec2= numpy.where(0<data_ele_new)
1458 data_ele_new = data_ele_new[vec2]
1458 data_ele_new = data_ele_new[vec2]
1459 data_ele_old = data_ele_old[vec2]
1459 data_ele_old = data_ele_old[vec2]
1460 data_weather = data_weather[vec2[0]]
1460 data_weather = data_weather[vec2[0]]
1461 self.start_data_ele = data_ele_new[0]
1461 self.start_data_ele = data_ele_new[0]
1462 self.end_data_ele = data_ele_new[-1]
1462 self.end_data_ele = data_ele_new[-1]
1463
1463
1464 n1= round(self.start_data_ele)- start
1464 n1= round(self.start_data_ele)- start
1465 n2= end - round(self.end_data_ele)-1
1465 n2= end - round(self.end_data_ele)-1
1466 print(self.start_data_ele)
1466 print(self.start_data_ele)
1467 print(self.end_data_ele)
1467 print(self.end_data_ele)
1468 if n1>0:
1468 if n1>0:
1469 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
1469 ele1= numpy.linspace(ang_min+1,self.start_data_ele-1,n1)
1470 ele1_nan= numpy.ones(n1)*numpy.nan
1470 ele1_nan= numpy.ones(n1)*numpy.nan
1471 data_ele = numpy.hstack((ele1,data_ele_new))
1471 data_ele = numpy.hstack((ele1,data_ele_new))
1472 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
1472 data_ele_old = numpy.hstack((ele1_nan,data_ele_old))
1473 if n2>0:
1473 if n2>0:
1474 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
1474 ele2= numpy.linspace(self.end_data_ele+1,end,n2)
1475 ele2_nan= numpy.ones(n2)*numpy.nan
1475 ele2_nan= numpy.ones(n2)*numpy.nan
1476 data_ele = numpy.hstack((data_ele,ele2))
1476 data_ele = numpy.hstack((data_ele,ele2))
1477 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1477 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1478 # RADAR
1478 # RADAR
1479 # NOTA data_ele y data_weather es la variable que retorna
1479 # NOTA data_ele y data_weather es la variable que retorna
1480 val_mean = numpy.mean(data_weather[:,-1])
1480 val_mean = numpy.mean(data_weather[:,-1])
1481 self.val_mean = val_mean
1481 self.val_mean = val_mean
1482 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1482 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1483 print("eleold",data_ele_old)
1483 print("eleold",data_ele_old)
1484 print(self.data_ele_tmp[val_ch])
1484 print(self.data_ele_tmp[val_ch])
1485 print(data_ele_old.shape[0])
1485 print(data_ele_old.shape[0])
1486 print(self.data_ele_tmp[val_ch].shape[0])
1486 print(self.data_ele_tmp[val_ch].shape[0])
1487 if (data_ele_old.shape[0]==91 or self.data_ele_tmp[val_ch].shape[0]==91):
1487 if (data_ele_old.shape[0]==91 or self.data_ele_tmp[val_ch].shape[0]==91):
1488 import sys
1488 import sys
1489 print("EXIT",self.ini)
1489 print("EXIT",self.ini)
1490
1490
1491 sys.exit(1)
1491 sys.exit(1)
1492 self.data_ele_tmp[val_ch]= data_ele_old
1492 self.data_ele_tmp[val_ch]= data_ele_old
1493 else:
1493 else:
1494 #print("**********************************************")
1494 #print("**********************************************")
1495 #print("****************VARIABLE**********************")
1495 #print("****************VARIABLE**********************")
1496 #-------------------------CAMBIOS RHI---------------------------------
1496 #-------------------------CAMBIOS RHI---------------------------------
1497 #---------------------------------------------------------------------
1497 #---------------------------------------------------------------------
1498 ##print("INPUT data_ele",data_ele)
1498 ##print("INPUT data_ele",data_ele)
1499 flag=0
1499 flag=0
1500 start_ele = self.res_ele[0]
1500 start_ele = self.res_ele[0]
1501 #tipo_case = self.check_case(data_ele,ang_max,ang_min)
1501 #tipo_case = self.check_case(data_ele,ang_max,ang_min)
1502 tipo_case = case_flag[-1]
1502 tipo_case = case_flag[-1]
1503 #print("TIPO DE DATA",tipo_case)
1503 #print("TIPO DE DATA",tipo_case)
1504 #-----------new------------
1504 #-----------new------------
1505 data_ele ,data_ele_old = self.globalCheckPED(data_ele,tipo_case)
1505 data_ele ,data_ele_old = self.globalCheckPED(data_ele,tipo_case)
1506 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1506 data_weather = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1507
1507
1508 #-------------------------------NEW RHI ITERATIVO-------------------------
1508 #-------------------------------NEW RHI ITERATIVO-------------------------
1509
1509
1510 if tipo_case==0 : # SUBIDA
1510 if tipo_case==0 : # SUBIDA
1511 vec = numpy.where(data_ele<ang_max)
1511 vec = numpy.where(data_ele<ang_max)
1512 data_ele = data_ele[vec]
1512 data_ele = data_ele[vec]
1513 data_ele_old = data_ele_old[vec]
1513 data_ele_old = data_ele_old[vec]
1514 data_weather = data_weather[vec[0]]
1514 data_weather = data_weather[vec[0]]
1515
1515
1516 vec2 = numpy.where(0<data_ele)
1516 vec2 = numpy.where(0<data_ele)
1517 data_ele= data_ele[vec2]
1517 data_ele= data_ele[vec2]
1518 data_ele_old= data_ele_old[vec2]
1518 data_ele_old= data_ele_old[vec2]
1519 ##print(data_ele_new)
1519 ##print(data_ele_new)
1520 data_weather= data_weather[vec2[0]]
1520 data_weather= data_weather[vec2[0]]
1521
1521
1522 new_i_ele = int(round(data_ele[0]))
1522 new_i_ele = int(round(data_ele[0]))
1523 new_f_ele = int(round(data_ele[-1]))
1523 new_f_ele = int(round(data_ele[-1]))
1524 #print(new_i_ele)
1524 #print(new_i_ele)
1525 #print(new_f_ele)
1525 #print(new_f_ele)
1526 #print(data_ele,len(data_ele))
1526 #print(data_ele,len(data_ele))
1527 #print(data_ele_old,len(data_ele_old))
1527 #print(data_ele_old,len(data_ele_old))
1528 if new_i_ele< 2:
1528 if new_i_ele< 2:
1529 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
1529 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
1530 self.res_weather[val_ch] = self.replaceNAN(data_weather=self.res_weather[val_ch],data_ele=self.data_ele_tmp[val_ch],val=self.val_mean)
1530 self.res_weather[val_ch] = self.replaceNAN(data_weather=self.res_weather[val_ch],data_ele=self.data_ele_tmp[val_ch],val=self.val_mean)
1531 self.data_ele_tmp[val_ch][new_i_ele:new_i_ele+len(data_ele)]=data_ele_old
1531 self.data_ele_tmp[val_ch][new_i_ele:new_i_ele+len(data_ele)]=data_ele_old
1532 self.res_ele[new_i_ele:new_i_ele+len(data_ele)]= data_ele
1532 self.res_ele[new_i_ele:new_i_ele+len(data_ele)]= data_ele
1533 self.res_weather[val_ch][new_i_ele:new_i_ele+len(data_ele),:]= data_weather
1533 self.res_weather[val_ch][new_i_ele:new_i_ele+len(data_ele),:]= data_weather
1534 data_ele = self.res_ele
1534 data_ele = self.res_ele
1535 data_weather = self.res_weather[val_ch]
1535 data_weather = self.res_weather[val_ch]
1536
1536
1537 elif tipo_case==1 : #BAJADA
1537 elif tipo_case==1 : #BAJADA
1538 data_ele = data_ele[::-1] # reversa
1538 data_ele = data_ele[::-1] # reversa
1539 data_ele_old = data_ele_old[::-1]# reversa
1539 data_ele_old = data_ele_old[::-1]# reversa
1540 data_weather = data_weather[::-1,:]# reversa
1540 data_weather = data_weather[::-1,:]# reversa
1541 vec= numpy.where(data_ele<ang_max)
1541 vec= numpy.where(data_ele<ang_max)
1542 data_ele = data_ele[vec]
1542 data_ele = data_ele[vec]
1543 data_ele_old = data_ele_old[vec]
1543 data_ele_old = data_ele_old[vec]
1544 data_weather = data_weather[vec[0]]
1544 data_weather = data_weather[vec[0]]
1545 vec2= numpy.where(0<data_ele)
1545 vec2= numpy.where(0<data_ele)
1546 data_ele = data_ele[vec2]
1546 data_ele = data_ele[vec2]
1547 data_ele_old = data_ele_old[vec2]
1547 data_ele_old = data_ele_old[vec2]
1548 data_weather = data_weather[vec2[0]]
1548 data_weather = data_weather[vec2[0]]
1549
1549
1550
1550
1551 new_i_ele = int(round(data_ele[0]))
1551 new_i_ele = int(round(data_ele[0]))
1552 new_f_ele = int(round(data_ele[-1]))
1552 new_f_ele = int(round(data_ele[-1]))
1553 #print(data_ele)
1553 #print(data_ele)
1554 #print(ang_max)
1554 #print(ang_max)
1555 #print(data_ele_old)
1555 #print(data_ele_old)
1556 if new_i_ele <= 1:
1556 if new_i_ele <= 1:
1557 new_i_ele = 1
1557 new_i_ele = 1
1558 if round(data_ele[-1])>=ang_max-1:
1558 if round(data_ele[-1])>=ang_max-1:
1559 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
1559 self.data_ele_tmp[val_ch] = numpy.ones(ang_max-ang_min)*numpy.nan
1560 self.res_weather[val_ch] = self.replaceNAN(data_weather=self.res_weather[val_ch],data_ele=self.data_ele_tmp[val_ch],val=self.val_mean)
1560 self.res_weather[val_ch] = self.replaceNAN(data_weather=self.res_weather[val_ch],data_ele=self.data_ele_tmp[val_ch],val=self.val_mean)
1561 self.data_ele_tmp[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1]=data_ele_old
1561 self.data_ele_tmp[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1]=data_ele_old
1562 self.res_ele[new_i_ele-1:new_i_ele+len(data_ele)-1]= data_ele
1562 self.res_ele[new_i_ele-1:new_i_ele+len(data_ele)-1]= data_ele
1563 self.res_weather[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1,:]= data_weather
1563 self.res_weather[val_ch][new_i_ele-1:new_i_ele+len(data_ele)-1,:]= data_weather
1564 data_ele = self.res_ele
1564 data_ele = self.res_ele
1565 data_weather = self.res_weather[val_ch]
1565 data_weather = self.res_weather[val_ch]
1566
1566
1567 elif tipo_case==2: #bajada
1567 elif tipo_case==2: #bajada
1568 vec = numpy.where(data_ele<ang_max)
1568 vec = numpy.where(data_ele<ang_max)
1569 data_ele = data_ele[vec]
1569 data_ele = data_ele[vec]
1570 data_weather= data_weather[vec[0]]
1570 data_weather= data_weather[vec[0]]
1571
1571
1572 len_vec = len(vec)
1572 len_vec = len(vec)
1573 data_ele_new = data_ele[::-1] # reversa
1573 data_ele_new = data_ele[::-1] # reversa
1574 data_weather = data_weather[::-1,:]
1574 data_weather = data_weather[::-1,:]
1575 new_i_ele = int(data_ele_new[0])
1575 new_i_ele = int(data_ele_new[0])
1576 new_f_ele = int(data_ele_new[-1])
1576 new_f_ele = int(data_ele_new[-1])
1577
1577
1578 n1= new_i_ele- ang_min
1578 n1= new_i_ele- ang_min
1579 n2= ang_max - new_f_ele-1
1579 n2= ang_max - new_f_ele-1
1580 if n1>0:
1580 if n1>0:
1581 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
1581 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
1582 ele1_nan= numpy.ones(n1)*numpy.nan
1582 ele1_nan= numpy.ones(n1)*numpy.nan
1583 data_ele = numpy.hstack((ele1,data_ele_new))
1583 data_ele = numpy.hstack((ele1,data_ele_new))
1584 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
1584 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
1585 if n2>0:
1585 if n2>0:
1586 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1586 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1587 ele2_nan= numpy.ones(n2)*numpy.nan
1587 ele2_nan= numpy.ones(n2)*numpy.nan
1588 data_ele = numpy.hstack((data_ele,ele2))
1588 data_ele = numpy.hstack((data_ele,ele2))
1589 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1589 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1590
1590
1591 self.data_ele_tmp[val_ch] = data_ele_old
1591 self.data_ele_tmp[val_ch] = data_ele_old
1592 self.res_ele = data_ele
1592 self.res_ele = data_ele
1593 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1593 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1594 data_ele = self.res_ele
1594 data_ele = self.res_ele
1595 data_weather = self.res_weather[val_ch]
1595 data_weather = self.res_weather[val_ch]
1596
1596
1597 elif tipo_case==3:#subida
1597 elif tipo_case==3:#subida
1598 vec = numpy.where(0<data_ele)
1598 vec = numpy.where(0<data_ele)
1599 data_ele= data_ele[vec]
1599 data_ele= data_ele[vec]
1600 data_ele_new = data_ele
1600 data_ele_new = data_ele
1601 data_ele_old= data_ele_old[vec]
1601 data_ele_old= data_ele_old[vec]
1602 data_weather= data_weather[vec[0]]
1602 data_weather= data_weather[vec[0]]
1603 pos_ini = numpy.argmin(data_ele)
1603 pos_ini = numpy.argmin(data_ele)
1604 if pos_ini>0:
1604 if pos_ini>0:
1605 len_vec= len(data_ele)
1605 len_vec= len(data_ele)
1606 vec3 = numpy.linspace(pos_ini,len_vec-1,len_vec-pos_ini).astype(int)
1606 vec3 = numpy.linspace(pos_ini,len_vec-1,len_vec-pos_ini).astype(int)
1607 #print(vec3)
1607 #print(vec3)
1608 data_ele= data_ele[vec3]
1608 data_ele= data_ele[vec3]
1609 data_ele_new = data_ele
1609 data_ele_new = data_ele
1610 data_ele_old= data_ele_old[vec3]
1610 data_ele_old= data_ele_old[vec3]
1611 data_weather= data_weather[vec3]
1611 data_weather= data_weather[vec3]
1612
1612
1613 new_i_ele = int(data_ele_new[0])
1613 new_i_ele = int(data_ele_new[0])
1614 new_f_ele = int(data_ele_new[-1])
1614 new_f_ele = int(data_ele_new[-1])
1615 n1= new_i_ele- ang_min
1615 n1= new_i_ele- ang_min
1616 n2= ang_max - new_f_ele-1
1616 n2= ang_max - new_f_ele-1
1617 if n1>0:
1617 if n1>0:
1618 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
1618 ele1= numpy.linspace(ang_min+1,new_i_ele-1,n1)
1619 ele1_nan= numpy.ones(n1)*numpy.nan
1619 ele1_nan= numpy.ones(n1)*numpy.nan
1620 data_ele = numpy.hstack((ele1,data_ele_new))
1620 data_ele = numpy.hstack((ele1,data_ele_new))
1621 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
1621 data_ele_old = numpy.hstack((ele1_nan,data_ele_new))
1622 if n2>0:
1622 if n2>0:
1623 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1623 ele2= numpy.linspace(new_f_ele+1,ang_max,n2)
1624 ele2_nan= numpy.ones(n2)*numpy.nan
1624 ele2_nan= numpy.ones(n2)*numpy.nan
1625 data_ele = numpy.hstack((data_ele,ele2))
1625 data_ele = numpy.hstack((data_ele,ele2))
1626 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1626 data_ele_old = numpy.hstack((data_ele_old,ele2_nan))
1627
1627
1628 self.data_ele_tmp[val_ch] = data_ele_old
1628 self.data_ele_tmp[val_ch] = data_ele_old
1629 self.res_ele = data_ele
1629 self.res_ele = data_ele
1630 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1630 self.res_weather[val_ch] = self.replaceNAN(data_weather=data_weather,data_ele=data_ele_old,val=self.val_mean)
1631 data_ele = self.res_ele
1631 data_ele = self.res_ele
1632 data_weather = self.res_weather[val_ch]
1632 data_weather = self.res_weather[val_ch]
1633 #print("self.data_ele_tmp",self.data_ele_tmp)
1633 #print("self.data_ele_tmp",self.data_ele_tmp)
1634 return data_weather,data_ele
1634 return data_weather,data_ele
1635
1635
1636
1636
1637 def plot(self):
1637 def plot(self):
1638 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
1638 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1]).strftime('%Y-%m-%d %H:%M:%S')
1639 data = self.data[-1]
1639 data = self.data[-1]
1640 r = self.data.yrange
1640 r = self.data.yrange
1641 delta_height = r[1]-r[0]
1641 delta_height = r[1]-r[0]
1642 r_mask = numpy.where(r>=0)[0]
1642 r_mask = numpy.where(r>=0)[0]
1643 ##print("delta_height",delta_height)
1643 ##print("delta_height",delta_height)
1644 #print("r_mask",r_mask,len(r_mask))
1644 #print("r_mask",r_mask,len(r_mask))
1645 r = numpy.arange(len(r_mask))*delta_height
1645 r = numpy.arange(len(r_mask))*delta_height
1646 self.y = 2*r
1646 self.y = 2*r
1647 res = 1
1647 res = 1
1648 ###print("data['weather'].shape[0]",data['weather'].shape[0])
1648 ###print("data['weather'].shape[0]",data['weather'].shape[0])
1649 ang_max = self.ang_max
1649 ang_max = self.ang_max
1650 ang_min = self.ang_min
1650 ang_min = self.ang_min
1651 var_ang =ang_max - ang_min
1651 var_ang =ang_max - ang_min
1652 step = (int(var_ang)/(res*data['weather'].shape[0]))
1652 step = (int(var_ang)/(res*data['weather'].shape[0]))
1653 ###print("step",step)
1653 ###print("step",step)
1654 #--------------------------------------------------------
1654 #--------------------------------------------------------
1655 ##print('weather',data['weather'].shape)
1655 ##print('weather',data['weather'].shape)
1656 ##print('ele',data['ele'].shape)
1656 ##print('ele',data['ele'].shape)
1657
1657
1658 ###self.res_weather, self.res_ele = self.const_ploteo(data_weather=data['weather'][:,r_mask],data_ele=data['ele'],step=step,res=res,ang_max=ang_max,ang_min=ang_min)
1658 ###self.res_weather, self.res_ele = self.const_ploteo(data_weather=data['weather'][:,r_mask],data_ele=data['ele'],step=step,res=res,ang_max=ang_max,ang_min=ang_min)
1659 ###self.res_azi = numpy.mean(data['azi'])
1659 ###self.res_azi = numpy.mean(data['azi'])
1660 ###print("self.res_ele",self.res_ele)
1660 ###print("self.res_ele",self.res_ele)
1661 plt.clf()
1661 plt.clf()
1662 subplots = [121, 122]
1662 subplots = [121, 122]
1663 try:
1663 try:
1664 if self.data[-2]['ele'].max()<data['ele'].max():
1664 if self.data[-2]['ele'].max()<data['ele'].max():
1665 self.ini=0
1665 self.ini=0
1666 except:
1666 except:
1667 pass
1667 pass
1668 if self.ini==0:
1668 if self.ini==0:
1669 self.data_ele_tmp = numpy.ones([self.nplots,int(var_ang)])*numpy.nan
1669 self.data_ele_tmp = numpy.ones([self.nplots,int(var_ang)])*numpy.nan
1670 self.res_weather= numpy.ones([self.nplots,int(var_ang),len(r_mask)])*numpy.nan
1670 self.res_weather= numpy.ones([self.nplots,int(var_ang),len(r_mask)])*numpy.nan
1671 print("SHAPE",self.data_ele_tmp.shape)
1671 print("SHAPE",self.data_ele_tmp.shape)
1672
1672
1673 for i,ax in enumerate(self.axes):
1673 for i,ax in enumerate(self.axes):
1674 self.res_weather[i], self.res_ele = self.const_ploteo(val_ch=i, data_weather=data['weather'][i][:,r_mask],data_ele=data['ele'],step=step,res=res,ang_max=ang_max,ang_min=ang_min,case_flag=self.data['case_flag'])
1674 self.res_weather[i], self.res_ele = self.const_ploteo(val_ch=i, data_weather=data['weather'][i][:,r_mask],data_ele=data['ele'],step=step,res=res,ang_max=ang_max,ang_min=ang_min,case_flag=self.data['case_flag'])
1675 self.res_azi = numpy.mean(data['azi'])
1675 self.res_azi = numpy.mean(data['azi'])
1676
1676
1677 if ax.firsttime:
1677 if ax.firsttime:
1678 #plt.clf()
1678 #plt.clf()
1679 print("Frist Plot")
1679 print("Frist Plot")
1680 cgax, pm = wrl.vis.plot_rhi(self.res_weather[i],r=r,th=self.res_ele,ax=subplots[i], proj='cg',vmin=20, vmax=80)
1680 cgax, pm = wrl.vis.plot_rhi(self.res_weather[i],r=r,th=self.res_ele,ax=subplots[i], proj='cg',vmin=20, vmax=80)
1681 #fig=self.figures[0]
1681 #fig=self.figures[0]
1682 else:
1682 else:
1683 #plt.clf()
1683 #plt.clf()
1684 print("ELSE PLOT")
1684 print("ELSE PLOT")
1685 cgax, pm = wrl.vis.plot_rhi(self.res_weather[i],r=r,th=self.res_ele,ax=subplots[i], proj='cg',vmin=20, vmax=80)
1685 cgax, pm = wrl.vis.plot_rhi(self.res_weather[i],r=r,th=self.res_ele,ax=subplots[i], proj='cg',vmin=20, vmax=80)
1686 caax = cgax.parasites[0]
1686 caax = cgax.parasites[0]
1687 paax = cgax.parasites[1]
1687 paax = cgax.parasites[1]
1688 cbar = plt.gcf().colorbar(pm, pad=0.075)
1688 cbar = plt.gcf().colorbar(pm, pad=0.075)
1689 caax.set_xlabel('x_range [km]')
1689 caax.set_xlabel('x_range [km]')
1690 caax.set_ylabel('y_range [km]')
1690 caax.set_ylabel('y_range [km]')
1691 plt.text(1.0, 1.05, 'Elevacion '+str(thisDatetime)+" Step "+str(self.ini)+ " Azi: "+str(round(self.res_azi,2)), transform=caax.transAxes, va='bottom',ha='right')
1691 plt.text(1.0, 1.05, 'Elevacion '+str(thisDatetime)+" Step "+str(self.ini)+ " Azi: "+str(round(self.res_azi,2)), transform=caax.transAxes, va='bottom',ha='right')
1692 print("***************************self.ini****************************",self.ini)
1692 print("***************************self.ini****************************",self.ini)
1693 self.ini= self.ini+1
1693 self.ini= self.ini+1
1694
1694
1695
1695
1696
1696
1697
1697
1698
1698
1699 class WeatherRHI_vRF4_Plot(Plot):
1699 class WeatherRHI_vRF4_Plot(Plot):
1700 CODE = 'RHI'
1700 CODE = 'RHI'
1701 plot_name = 'RHI'
1701 plot_name = 'RHI'
1702 #plot_type = 'rhistyle'
1702 #plot_type = 'rhistyle'
1703 buffering = False
1703 buffering = False
1704
1704
1705 def setup(self):
1705 def setup(self):
1706
1706
1707 self.ncols = 1
1707 self.ncols = 1
1708 self.nrows = 1
1708 self.nrows = 1
1709 self.nplots= 1
1709 self.nplots= 1
1710 self.ylabel= 'Range [Km]'
1710 self.ylabel= 'Range [Km]'
1711 self.xlabel= 'Range [Km]'
1711 self.xlabel= 'Range [Km]'
1712 self.titles= ['RHI']
1712 self.titles= ['RHI']
1713 self.polar = True
1713 self.polar = True
1714 self.grid = True
1714 self.grid = True
1715 if self.channels is not None:
1715 if self.channels is not None:
1716 self.nplots = len(self.channels)
1716 self.nplots = len(self.channels)
1717 self.nrows = len(self.channels)
1717 self.nrows = len(self.channels)
1718 else:
1718 else:
1719 self.nplots = self.data.shape(self.CODE)[0]
1719 self.nplots = self.data.shape(self.CODE)[0]
1720 self.nrows = self.nplots
1720 self.nrows = self.nplots
1721 self.channels = list(range(self.nplots))
1721 self.channels = list(range(self.nplots))
1722
1722
1723 if self.CODE == 'Power':
1723 if self.CODE == 'Power':
1724 self.cb_label = r'Power (dB)'
1724 self.cb_label = r'Power (dB)'
1725 elif self.CODE == 'Doppler':
1725 elif self.CODE == 'Doppler':
1726 self.cb_label = r'Velocity (m/s)'
1726 self.cb_label = r'Velocity (m/s)'
1727 self.colorbar=True
1727 self.colorbar=True
1728 self.width =8
1728 self.width =8
1729 self.height =8
1729 self.height =8
1730 self.ini =0
1730 self.ini =0
1731 self.len_azi =0
1731 self.len_azi =0
1732 self.buffer_ini = None
1732 self.buffer_ini = None
1733 self.buffer_ele = None
1733 self.buffer_ele = None
1734 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
1734 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
1735 self.flag =0
1735 self.flag =0
1736 self.indicador= 0
1736 self.indicador= 0
1737 self.last_data_ele = None
1737 self.last_data_ele = None
1738 self.val_mean = None
1738 self.val_mean = None
1739
1739
1740 def update(self, dataOut):
1740 def update(self, dataOut):
1741
1741
1742 data = {}
1742 data = {}
1743 meta = {}
1743 meta = {}
1744 if hasattr(dataOut, 'dataPP_POWER'):
1744 if hasattr(dataOut, 'dataPP_POWER'):
1745 factor = 1
1745 factor = 1
1746 if hasattr(dataOut, 'nFFTPoints'):
1746 if hasattr(dataOut, 'nFFTPoints'):
1747 factor = dataOut.normFactor
1747 factor = dataOut.normFactor
1748
1748
1749 if 'pow' in self.attr_data[0].lower():
1749 if 'pow' in self.attr_data[0].lower():
1750 data['data'] = 10*numpy.log10(getattr(dataOut, self.attr_data[0])/(factor))
1750 data['data'] = 10*numpy.log10(getattr(dataOut, self.attr_data[0])/(factor))
1751 else:
1751 else:
1752 data['data'] = getattr(dataOut, self.attr_data[0])/(factor)
1752 data['data'] = getattr(dataOut, self.attr_data[0])/(factor)
1753
1753
1754 data['azi'] = dataOut.data_azi
1754 data['azi'] = dataOut.data_azi
1755 data['ele'] = dataOut.data_ele
1755 data['ele'] = dataOut.data_ele
1756
1756
1757 return data, meta
1757 return data, meta
1758
1758
1759 def plot(self):
1759 def plot(self):
1760 data = self.data[-1]
1760 data = self.data[-1]
1761 r = self.data.yrange
1761 r = self.data.yrange
1762 delta_height = r[1]-r[0]
1762 delta_height = r[1]-r[0]
1763 r_mask = numpy.where(r>=0)[0]
1763 r_mask = numpy.where(r>=0)[0]
1764 self.r_mask =r_mask
1764 self.r_mask =r_mask
1765 r = numpy.arange(len(r_mask))*delta_height
1765 r = numpy.arange(len(r_mask))*delta_height
1766 self.y = 2*r
1766 self.y = 2*r
1767
1767
1768 try:
1768 try:
1769 z = data['data'][self.channels[0]][:,r_mask]
1769 z = data['data'][self.channels[0]][:,r_mask]
1770 except:
1770 except:
1771 z = data['data'][0][:,r_mask]
1771 z = data['data'][0][:,r_mask]
1772
1772
1773 self.titles = []
1773 self.titles = []
1774
1774
1775 self.ymax = self.ymax if self.ymax else numpy.nanmax(r)
1775 self.ymax = self.ymax if self.ymax else numpy.nanmax(r)
1776 self.ymin = self.ymin if self.ymin else numpy.nanmin(r)
1776 self.ymin = self.ymin if self.ymin else numpy.nanmin(r)
1777 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
1777 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
1778 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
1778 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
1779 self.ang_min = self.ang_min if self.ang_min else 0
1779 self.ang_min = self.ang_min if self.ang_min else 0
1780 self.ang_max = self.ang_max if self.ang_max else 90
1780 self.ang_max = self.ang_max if self.ang_max else 90
1781
1781
1782 r, theta = numpy.meshgrid(r, numpy.radians(data['ele']) )
1782 r, theta = numpy.meshgrid(r, numpy.radians(data['ele']) )
1783
1783
1784 for i,ax in enumerate(self.axes):
1784 for i,ax in enumerate(self.axes):
1785
1785
1786 if ax.firsttime:
1786 if ax.firsttime:
1787 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1787 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1788 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1788 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1789
1789
1790 else:
1790 else:
1791 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1791 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1792 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1792 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1793 ax.grid(True)
1793 ax.grid(True)
1794 if len(self.channels) !=1:
1794 if len(self.channels) !=1:
1795 self.titles = ['RHI {} at AZ: {} Channel {}'.format(self.labels[x], str(round(numpy.mean(data['azi']),1)), x) for x in range(self.nrows)]
1795 self.titles = ['RHI {} at AZ: {} Channel {}'.format(self.labels[x], str(round(numpy.mean(data['azi']),1)), x) for x in range(self.nrows)]
1796 else:
1796 else:
1797 self.titles = ['RHI {} at AZ: {} Channel {}'.format(self.labels[0], str(round(numpy.mean(data['azi']),1)), self.channels[0])]
1797 self.titles = ['RHI {} at AZ: {} Channel {}'.format(self.labels[0], str(round(numpy.mean(data['azi']),1)), self.channels[0])]
1798
1798
1799 class WeatherParamsPlot(Plot):
1799 class WeatherParamsPlot(Plot):
1800 #CODE = 'RHI'
1800 #CODE = 'RHI'
1801 #plot_name = 'RHI'
1801 #plot_name = 'RHI'
1802 #plot_type = 'rhistyle'
1802 #plot_type = 'rhistyle'
1803 buffering = False
1803 buffering = False
1804
1804
1805 def setup(self):
1805 def setup(self):
1806
1806
1807 self.ncols = 1
1807 self.ncols = 1
1808 self.nrows = 1
1808 self.nrows = 1
1809 self.nplots= 1
1809 self.nplots= 1
1810 self.ylabel= 'Range [km]'
1810 self.ylabel= 'Range [km]'
1811 self.xlabel= 'Range [km]'
1811 self.xlabel= 'Range [km]'
1812 self.polar = True
1812 self.polar = True
1813 self.grid = True
1813 self.grid = True
1814 if self.channels is not None:
1814 if self.channels is not None:
1815 self.nplots = len(self.channels)
1815 self.nplots = len(self.channels)
1816 self.nrows = len(self.channels)
1816 self.nrows = len(self.channels)
1817 else:
1817 else:
1818 self.nplots = self.data.shape(self.CODE)[0]
1818 self.nplots = self.data.shape(self.CODE)[0]
1819 self.nrows = self.nplots
1819 self.nrows = self.nplots
1820 self.channels = list(range(self.nplots))
1820 self.channels = list(range(self.nplots))
1821
1821
1822 self.colorbar=True
1822 self.colorbar=True
1823 self.width =8
1823 self.width =8
1824 self.height =8
1824 self.height =8
1825 self.ini =0
1825 self.ini =0
1826 self.len_azi =0
1826 self.len_azi =0
1827 self.buffer_ini = None
1827 self.buffer_ini = None
1828 self.buffer_ele = None
1828 self.buffer_ele = None
1829 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.08, 'right': 0.92, 'bottom': 0.01,'top':0.99})
1829 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
1830 self.flag =0
1830 self.flag =0
1831 self.indicador= 0
1831 self.indicador= 0
1832 self.last_data_ele = None
1832 self.last_data_ele = None
1833 self.val_mean = None
1833 self.val_mean = None
1834
1834
1835 def update(self, dataOut):
1835 def update(self, dataOut):
1836
1836
1837 data = {}
1837 data = {}
1838 meta = {}
1838 meta = {}
1839 if hasattr(dataOut, 'dataPP_POWER'):
1839 if hasattr(dataOut, 'dataPP_POWER'):
1840 factor = 1
1840 factor = 1
1841 if hasattr(dataOut, 'nFFTPoints'):
1841 if hasattr(dataOut, 'nFFTPoints'):
1842 factor = dataOut.normFactor
1842 factor = dataOut.normFactor
1843
1843
1844 if 'pow' in self.attr_data[0].lower():
1844 if 'pow' in self.attr_data[0].lower():
1845 data['data'] = 10*numpy.log10(getattr(dataOut, self.attr_data[0])/(factor))
1845 data['data'] = 10*numpy.log10(getattr(dataOut, self.attr_data[0])/(factor))
1846 else:
1846 else:
1847 data['data'] = getattr(dataOut, self.attr_data[0])/(factor)
1847 data['data'] = getattr(dataOut, self.attr_data[0])/(factor)
1848
1848
1849 if dataOut.mode_op == 'PPI':
1849 if dataOut.mode_op == 'PPI':
1850 self.CODE = 'PPI'
1850 self.CODE = 'PPI'
1851 self.title = self.CODE
1851 self.title = self.CODE
1852 elif dataOut.mode_op == 'RHI':
1852 elif dataOut.mode_op == 'RHI':
1853 self.CODE = 'RHI'
1853 self.CODE = 'RHI'
1854 self.title = self.CODE
1854 self.title = self.CODE
1855
1855
1856 data['azi'] = dataOut.data_azi
1856 data['azi'] = dataOut.data_azi
1857 data['ele'] = dataOut.data_ele
1857 data['ele'] = dataOut.data_ele
1858 data['mode_op'] = dataOut.mode_op
1858 data['mode_op'] = dataOut.mode_op
1859
1859
1860 return data, meta
1860 return data, meta
1861
1861
1862 def plot(self):
1862 def plot(self):
1863 data = self.data[-1]
1863 data = self.data[-1]
1864 r = self.data.yrange
1864 r = self.data.yrange
1865 delta_height = r[1]-r[0]
1865 delta_height = r[1]-r[0]
1866 r_mask = numpy.where(r>=0)[0]
1866 r_mask = numpy.where(r>=0)[0]
1867 self.r_mask =r_mask
1867 self.r_mask =r_mask
1868 r = numpy.arange(len(r_mask))*delta_height
1868 r = numpy.arange(len(r_mask))*delta_height
1869 self.y = 2*r
1869 self.y = 2*r
1870
1870
1871 try:
1871 try:
1872 z = data['data'][self.channels[0]][:,r_mask]
1872 z = data['data'][self.channels[0]][:,r_mask]
1873 except:
1873 except:
1874 z = data['data'][0][:,r_mask]
1874 z = data['data'][0][:,r_mask]
1875
1875
1876 self.titles = []
1876 self.titles = []
1877
1877
1878 self.ymax = self.ymax if self.ymax else numpy.nanmax(r)
1878 self.ymax = self.ymax if self.ymax else numpy.nanmax(r)
1879 self.ymin = self.ymin if self.ymin else numpy.nanmin(r)
1879 self.ymin = self.ymin if self.ymin else numpy.nanmin(r)
1880 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
1880 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
1881 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
1881 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
1882 print("mode inside plot",self.data['mode_op'],data['mode_op'])
1882 print("mode inside plot",self.data['mode_op'],data['mode_op'])
1883 if data['mode_op'] == 'RHI':
1883 if data['mode_op'] == 'RHI':
1884 try:
1884 try:
1885 if self.data['mode_op'][-2] == 'PPI':
1885 if self.data['mode_op'][-2] == 'PPI':
1886 self.ang_min = None
1886 self.ang_min = None
1887 self.ang_max = None
1887 self.ang_max = None
1888 except:
1888 except:
1889 pass
1889 pass
1890 self.ang_min = self.ang_min if self.ang_min else 0
1890 self.ang_min = self.ang_min if self.ang_min else 0
1891 self.ang_max = self.ang_max if self.ang_max else 90
1891 self.ang_max = self.ang_max if self.ang_max else 90
1892 r, theta = numpy.meshgrid(r, numpy.radians(data['ele']) )
1892 r, theta = numpy.meshgrid(r, numpy.radians(data['ele']) )
1893 elif data['mode_op'] == 'PPI':
1893 elif data['mode_op'] == 'PPI':
1894 try:
1894 try:
1895 if self.data['mode_op'][-2] == 'RHI':
1895 if self.data['mode_op'][-2] == 'RHI':
1896 self.ang_min = None
1896 self.ang_min = None
1897 self.ang_max = None
1897 self.ang_max = None
1898 except:
1898 except:
1899 pass
1899 pass
1900 self.ang_min = self.ang_min if self.ang_min else 0
1900 self.ang_min = self.ang_min if self.ang_min else 0
1901 self.ang_max = self.ang_max if self.ang_max else 360
1901 self.ang_max = self.ang_max if self.ang_max else 360
1902 r, theta = numpy.meshgrid(r, numpy.radians(data['azi']) )
1902 r, theta = numpy.meshgrid(r, numpy.radians(data['azi']) )
1903
1903
1904 self.clear_figures()
1904 self.clear_figures()
1905
1905
1906 for i,ax in enumerate(self.axes):
1906 for i,ax in enumerate(self.axes):
1907
1907
1908 if ax.firsttime:
1908 if ax.firsttime:
1909 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1909 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1910 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1910 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1911 if data['mode_op'] == 'PPI':
1911 if data['mode_op'] == 'PPI':
1912 ax.set_theta_direction(-1)
1912 ax.set_theta_direction(-1)
1913 ax.set_theta_offset(numpy.pi/2)
1913 ax.set_theta_offset(numpy.pi/2)
1914
1914
1915 else:
1915 else:
1916 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1916 ax.set_xlim(numpy.radians(self.ang_min),numpy.radians(self.ang_max))
1917 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1917 ax.plt = ax.pcolormesh(theta, r, z, cmap=self.colormap, vmin=self.zmin, vmax=self.zmax)
1918 if data['mode_op'] == 'PPI':
1918 if data['mode_op'] == 'PPI':
1919 ax.set_theta_direction(-1)
1919 ax.set_theta_direction(-1)
1920 ax.set_theta_offset(numpy.pi/2)
1920 ax.set_theta_offset(numpy.pi/2)
1921
1921
1922 ax.grid(True)
1922 ax.grid(True)
1923 if data['mode_op'] == 'RHI':
1923 if data['mode_op'] == 'RHI':
1924 len_aux = int(data['azi'].shape[0]/4)
1924 len_aux = int(data['azi'].shape[0]/4)
1925 mean = numpy.mean(data['azi'][len_aux:-len_aux])
1925 mean = numpy.mean(data['azi'][len_aux:-len_aux])
1926 if len(self.channels) !=1:
1926 if len(self.channels) !=1:
1927 self.titles = ['RHI {} at AZ: {} Channel {}'.format(self.labels[x], str(round(mean,1)), x) for x in range(self.nrows)]
1927 self.titles = ['RHI {} at AZ: {} Channel {}'.format(self.labels[x], str(round(mean,1)), x) for x in range(self.nrows)]
1928 else:
1928 else:
1929 self.titles = ['RHI {} at AZ: {} Channel {}'.format(self.labels[0], str(round(mean,1)), self.channels[0])]
1929 self.titles = ['RHI {} at AZ: {} Channel {}'.format(self.labels[0], str(round(mean,1)), self.channels[0])]
1930 elif data['mode_op'] == 'PPI':
1930 elif data['mode_op'] == 'PPI':
1931 len_aux = int(data['ele'].shape[0]/4)
1931 len_aux = int(data['ele'].shape[0]/4)
1932 mean = numpy.mean(data['ele'][len_aux:-len_aux])
1932 mean = numpy.mean(data['ele'][len_aux:-len_aux])
1933 if len(self.channels) !=1:
1933 if len(self.channels) !=1:
1934 self.titles = ['PPI {} at EL: {} Channel {}'.format(self.self.labels[x], str(round(mean,1)), x) for x in range(self.nrows)]
1934 self.titles = ['PPI {} at EL: {} Channel {}'.format(self.self.labels[x], str(round(mean,1)), x) for x in range(self.nrows)]
1935 else:
1935 else:
1936 self.titles = ['PPI {} at EL: {} Channel {}'.format(self.labels[0], str(round(mean,1)), self.channels[0])]
1936 self.titles = ['PPI {} at EL: {} Channel {}'.format(self.labels[0], str(round(mean,1)), self.channels[0])]
@@ -1,5193 +1,5216
1
1
2 import os
2 import os
3 import time
3 import time
4 import math
4 import math
5
5
6 import re
6 import re
7 import datetime
7 import datetime
8 import copy
8 import copy
9 import sys
9 import sys
10 import importlib
10 import importlib
11 import itertools
11 import itertools
12
12
13 from multiprocessing import Pool, TimeoutError
13 from multiprocessing import Pool, TimeoutError
14 from multiprocessing.pool import ThreadPool
14 from multiprocessing.pool import ThreadPool
15 import numpy
15 import numpy
16 import glob
16 import glob
17 import scipy
17 import scipy
18 import h5py
18 import h5py
19 from scipy.optimize import fmin_l_bfgs_b #optimize with bounds on state papameters
19 from scipy.optimize import fmin_l_bfgs_b #optimize with bounds on state papameters
20 from .jroproc_base import ProcessingUnit, Operation, MPDecorator
20 from .jroproc_base import ProcessingUnit, Operation, MPDecorator
21 from schainpy.model.data.jrodata import Parameters, hildebrand_sekhon
21 from schainpy.model.data.jrodata import Parameters, hildebrand_sekhon
22 from scipy import asarray as ar,exp
22 from scipy import asarray as ar,exp
23 from scipy.optimize import curve_fit
23 from scipy.optimize import curve_fit
24 from schainpy.utils import log
24 from schainpy.utils import log
25 import schainpy.admin
25 import schainpy.admin
26 import warnings
26 import warnings
27 from scipy import optimize, interpolate, signal, stats, ndimage
27 from scipy import optimize, interpolate, signal, stats, ndimage
28 from scipy.optimize.optimize import OptimizeWarning
28 from scipy.optimize.optimize import OptimizeWarning
29 warnings.filterwarnings('ignore')
29 warnings.filterwarnings('ignore')
30
30
31
31
32 SPEED_OF_LIGHT = 299792458
32 SPEED_OF_LIGHT = 299792458
33
33
34 '''solving pickling issue'''
34 '''solving pickling issue'''
35
35
36 def _pickle_method(method):
36 def _pickle_method(method):
37 func_name = method.__func__.__name__
37 func_name = method.__func__.__name__
38 obj = method.__self__
38 obj = method.__self__
39 cls = method.__self__.__class__
39 cls = method.__self__.__class__
40 return _unpickle_method, (func_name, obj, cls)
40 return _unpickle_method, (func_name, obj, cls)
41
41
42 def _unpickle_method(func_name, obj, cls):
42 def _unpickle_method(func_name, obj, cls):
43 for cls in cls.mro():
43 for cls in cls.mro():
44 try:
44 try:
45 func = cls.__dict__[func_name]
45 func = cls.__dict__[func_name]
46 except KeyError:
46 except KeyError:
47 pass
47 pass
48 else:
48 else:
49 break
49 break
50 return func.__get__(obj, cls)
50 return func.__get__(obj, cls)
51
51
52 def isNumber(str):
52 def isNumber(str):
53 try:
53 try:
54 float(str)
54 float(str)
55 return True
55 return True
56 except:
56 except:
57 return False
57 return False
58
58
59 class ParametersProc(ProcessingUnit):
59 class ParametersProc(ProcessingUnit):
60
60
61 METHODS = {}
61 METHODS = {}
62 nSeconds = None
62 nSeconds = None
63
63
64 def __init__(self):
64 def __init__(self):
65 ProcessingUnit.__init__(self)
65 ProcessingUnit.__init__(self)
66
66
67 # self.objectDict = {}
67 # self.objectDict = {}
68 self.buffer = None
68 self.buffer = None
69 self.firstdatatime = None
69 self.firstdatatime = None
70 self.profIndex = 0
70 self.profIndex = 0
71 self.dataOut = Parameters()
71 self.dataOut = Parameters()
72 self.setupReq = False #Agregar a todas las unidades de proc
72 self.setupReq = False #Agregar a todas las unidades de proc
73
73
74 def __updateObjFromInput(self):
74 def __updateObjFromInput(self):
75
75
76 self.dataOut.inputUnit = self.dataIn.type
76 self.dataOut.inputUnit = self.dataIn.type
77
77
78 self.dataOut.timeZone = self.dataIn.timeZone
78 self.dataOut.timeZone = self.dataIn.timeZone
79 self.dataOut.dstFlag = self.dataIn.dstFlag
79 self.dataOut.dstFlag = self.dataIn.dstFlag
80 self.dataOut.errorCount = self.dataIn.errorCount
80 self.dataOut.errorCount = self.dataIn.errorCount
81 self.dataOut.useLocalTime = self.dataIn.useLocalTime
81 self.dataOut.useLocalTime = self.dataIn.useLocalTime
82
82
83 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
83 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
84 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
84 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
85 self.dataOut.channelList = self.dataIn.channelList
85 self.dataOut.channelList = self.dataIn.channelList
86 self.dataOut.heightList = self.dataIn.heightList
86 self.dataOut.heightList = self.dataIn.heightList
87 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
87 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
88 # self.dataOut.nHeights = self.dataIn.nHeights
88 # self.dataOut.nHeights = self.dataIn.nHeights
89 # self.dataOut.nChannels = self.dataIn.nChannels
89 # self.dataOut.nChannels = self.dataIn.nChannels
90 # self.dataOut.nBaud = self.dataIn.nBaud
90 # self.dataOut.nBaud = self.dataIn.nBaud
91 # self.dataOut.nCode = self.dataIn.nCode
91 # self.dataOut.nCode = self.dataIn.nCode
92 # self.dataOut.code = self.dataIn.code
92 # self.dataOut.code = self.dataIn.code
93 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
93 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
94 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
94 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
95 # self.dataOut.utctime = self.firstdatatime
95 # self.dataOut.utctime = self.firstdatatime
96 self.dataOut.utctime = self.dataIn.utctime
96 self.dataOut.utctime = self.dataIn.utctime
97 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
97 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
98 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
98 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
99 self.dataOut.nCohInt = self.dataIn.nCohInt
99 self.dataOut.nCohInt = self.dataIn.nCohInt
100 # self.dataOut.nIncohInt = 1
100 # self.dataOut.nIncohInt = 1
101 # self.dataOut.ippSeconds = self.dataIn.ippSeconds
101 # self.dataOut.ippSeconds = self.dataIn.ippSeconds
102 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
102 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
103 self.dataOut.timeInterval1 = self.dataIn.timeInterval
103 self.dataOut.timeInterval1 = self.dataIn.timeInterval
104 self.dataOut.heightList = self.dataIn.heightList
104 self.dataOut.heightList = self.dataIn.heightList
105 self.dataOut.frequency = self.dataIn.frequency
105 self.dataOut.frequency = self.dataIn.frequency
106 # self.dataOut.noise = self.dataIn.noise
106 # self.dataOut.noise = self.dataIn.noise
107 self.dataOut.runNextUnit = self.dataIn.runNextUnit
107 self.dataOut.runNextUnit = self.dataIn.runNextUnit
108
108
109 def run(self, runNextUnit = 0):
109 def run(self, runNextUnit = 0):
110
110
111 self.dataIn.runNextUnit = runNextUnit
111 self.dataIn.runNextUnit = runNextUnit
112 #print("HOLA MUNDO SOY YO")
112 #print("HOLA MUNDO SOY YO")
113 #---------------------- Voltage Data ---------------------------
113 #---------------------- Voltage Data ---------------------------
114
114
115 if self.dataIn.type == "Voltage":
115 if self.dataIn.type == "Voltage":
116
116
117 self.__updateObjFromInput()
117 self.__updateObjFromInput()
118 self.dataOut.data_pre = self.dataIn.data.copy()
118 self.dataOut.data_pre = self.dataIn.data.copy()
119 self.dataOut.flagNoData = False
119 self.dataOut.flagNoData = False
120 self.dataOut.utctimeInit = self.dataIn.utctime
120 self.dataOut.utctimeInit = self.dataIn.utctime
121 self.dataOut.paramInterval = self.dataIn.nProfiles*self.dataIn.nCohInt*self.dataIn.ippSeconds
121 self.dataOut.paramInterval = self.dataIn.nProfiles*self.dataIn.nCohInt*self.dataIn.ippSeconds
122
122
123 if hasattr(self.dataIn, 'flagDataAsBlock'):
123 if hasattr(self.dataIn, 'flagDataAsBlock'):
124 self.dataOut.flagDataAsBlock = self.dataIn.flagDataAsBlock
124 self.dataOut.flagDataAsBlock = self.dataIn.flagDataAsBlock
125
125
126 if hasattr(self.dataIn, 'profileIndex'):
126 if hasattr(self.dataIn, 'profileIndex'):
127 self.dataOut.profileIndex = self.dataIn.profileIndex
127 self.dataOut.profileIndex = self.dataIn.profileIndex
128
128
129 if hasattr(self.dataIn, 'dataPP_POW'):
129 if hasattr(self.dataIn, 'dataPP_POW'):
130 self.dataOut.dataPP_POW = self.dataIn.dataPP_POW
130 self.dataOut.dataPP_POW = self.dataIn.dataPP_POW
131
131
132 if hasattr(self.dataIn, 'dataPP_POWER'):
132 if hasattr(self.dataIn, 'dataPP_POWER'):
133 self.dataOut.dataPP_POWER = self.dataIn.dataPP_POWER
133 self.dataOut.dataPP_POWER = self.dataIn.dataPP_POWER
134
134
135 if hasattr(self.dataIn, 'dataPP_DOP'):
135 if hasattr(self.dataIn, 'dataPP_DOP'):
136 self.dataOut.dataPP_DOP = self.dataIn.dataPP_DOP
136 self.dataOut.dataPP_DOP = self.dataIn.dataPP_DOP
137
137
138 if hasattr(self.dataIn, 'dataPP_SNR'):
138 if hasattr(self.dataIn, 'dataPP_SNR'):
139 self.dataOut.dataPP_SNR = self.dataIn.dataPP_SNR
139 self.dataOut.dataPP_SNR = self.dataIn.dataPP_SNR
140
140
141 if hasattr(self.dataIn, 'dataPP_WIDTH'):
141 if hasattr(self.dataIn, 'dataPP_WIDTH'):
142 self.dataOut.dataPP_WIDTH = self.dataIn.dataPP_WIDTH
142 self.dataOut.dataPP_WIDTH = self.dataIn.dataPP_WIDTH
143
143
144 if hasattr(self.dataIn, 'dataPP_CCF'):
144 if hasattr(self.dataIn, 'dataPP_CCF'):
145 self.dataOut.dataPP_CCF = self.dataIn.dataPP_CCF
145 self.dataOut.dataPP_CCF = self.dataIn.dataPP_CCF
146 if hasattr(self.dataIn, 'flagAskMode'):
146 if hasattr(self.dataIn, 'flagAskMode'):
147 self.dataOut.flagAskMode = self.dataIn.flagAskMode
147 self.dataOut.flagAskMode = self.dataIn.flagAskMode
148
148
149 return
149 return
150
150
151 #---------------------- Spectra Data ---------------------------
151 #---------------------- Spectra Data ---------------------------
152
152
153 if self.dataIn.type == "Spectra":
153 if self.dataIn.type == "Spectra":
154 #print("que paso en spectra")
154 #print("que paso en spectra")
155 self.dataOut.data_pre = [self.dataIn.data_spc, self.dataIn.data_cspc]
155 self.dataOut.data_pre = [self.dataIn.data_spc, self.dataIn.data_cspc]
156 self.dataOut.data_spc = self.dataIn.data_spc
156 self.dataOut.data_spc = self.dataIn.data_spc
157 self.dataOut.data_cspc = self.dataIn.data_cspc
157 self.dataOut.data_cspc = self.dataIn.data_cspc
158 self.dataOut.nProfiles = self.dataIn.nProfiles
158 self.dataOut.nProfiles = self.dataIn.nProfiles
159 self.dataOut.nIncohInt = self.dataIn.nIncohInt
159 self.dataOut.nIncohInt = self.dataIn.nIncohInt
160 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
160 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
161 self.dataOut.ippFactor = self.dataIn.ippFactor
161 self.dataOut.ippFactor = self.dataIn.ippFactor
162 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
162 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
163 self.dataOut.spc_noise = self.dataIn.getNoise()
163 self.dataOut.spc_noise = self.dataIn.getNoise()
164 self.dataOut.spc_range = (self.dataIn.getFreqRange(1) , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
164 self.dataOut.spc_range = (self.dataIn.getFreqRange(1) , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
165 # self.dataOut.normFactor = self.dataIn.normFactor
165 # self.dataOut.normFactor = self.dataIn.normFactor
166 self.dataOut.pairsList = self.dataIn.pairsList
166 self.dataOut.pairsList = self.dataIn.pairsList
167 self.dataOut.groupList = self.dataIn.pairsList
167 self.dataOut.groupList = self.dataIn.pairsList
168 self.dataOut.flagNoData = False
168 self.dataOut.flagNoData = False
169
169
170 if hasattr(self.dataIn, 'flagDataAsBlock'):
170 if hasattr(self.dataIn, 'flagDataAsBlock'):
171 self.dataOut.flagDataAsBlock = self.dataIn.flagDataAsBlock
171 self.dataOut.flagDataAsBlock = self.dataIn.flagDataAsBlock
172
172
173 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
173 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
174 self.dataOut.ChanDist = self.dataIn.ChanDist
174 self.dataOut.ChanDist = self.dataIn.ChanDist
175 else: self.dataOut.ChanDist = None
175 else: self.dataOut.ChanDist = None
176
176
177 #if hasattr(self.dataIn, 'VelRange'): #Velocities range
177 #if hasattr(self.dataIn, 'VelRange'): #Velocities range
178 # self.dataOut.VelRange = self.dataIn.VelRange
178 # self.dataOut.VelRange = self.dataIn.VelRange
179 #else: self.dataOut.VelRange = None
179 #else: self.dataOut.VelRange = None
180
180
181 if hasattr(self.dataIn, 'RadarConst'): #Radar Constant
181 if hasattr(self.dataIn, 'RadarConst'): #Radar Constant
182 self.dataOut.RadarConst = self.dataIn.RadarConst
182 self.dataOut.RadarConst = self.dataIn.RadarConst
183
183
184 if hasattr(self.dataIn, 'NPW'): #NPW
184 if hasattr(self.dataIn, 'NPW'): #NPW
185 self.dataOut.NPW = self.dataIn.NPW
185 self.dataOut.NPW = self.dataIn.NPW
186
186
187 if hasattr(self.dataIn, 'COFA'): #COFA
187 if hasattr(self.dataIn, 'COFA'): #COFA
188 self.dataOut.COFA = self.dataIn.COFA
188 self.dataOut.COFA = self.dataIn.COFA
189
189
190
190
191
191
192 #---------------------- Correlation Data ---------------------------
192 #---------------------- Correlation Data ---------------------------
193
193
194 if self.dataIn.type == "Correlation":
194 if self.dataIn.type == "Correlation":
195 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
195 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
196
196
197 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
197 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
198 self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
198 self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
199 self.dataOut.groupList = (acf_pairs, ccf_pairs)
199 self.dataOut.groupList = (acf_pairs, ccf_pairs)
200
200
201 self.dataOut.abscissaList = self.dataIn.lagRange
201 self.dataOut.abscissaList = self.dataIn.lagRange
202 self.dataOut.noise = self.dataIn.noise
202 self.dataOut.noise = self.dataIn.noise
203 self.dataOut.data_snr = self.dataIn.SNR
203 self.dataOut.data_snr = self.dataIn.SNR
204 self.dataOut.flagNoData = False
204 self.dataOut.flagNoData = False
205 self.dataOut.nAvg = self.dataIn.nAvg
205 self.dataOut.nAvg = self.dataIn.nAvg
206
206
207 #---------------------- Parameters Data ---------------------------
207 #---------------------- Parameters Data ---------------------------
208
208
209 if self.dataIn.type == "Parameters":
209 if self.dataIn.type == "Parameters":
210 self.dataOut.copy(self.dataIn)
210 self.dataOut.copy(self.dataIn)
211 self.dataOut.flagNoData = False
211 self.dataOut.flagNoData = False
212 #print("yo si entre")
212 #print("yo si entre")
213
213
214 return True
214 return True
215
215
216 self.__updateObjFromInput()
216 self.__updateObjFromInput()
217 #print("yo si entre2")
217 #print("yo si entre2")
218
218
219 self.dataOut.utctimeInit = self.dataIn.utctime
219 self.dataOut.utctimeInit = self.dataIn.utctime
220 self.dataOut.paramInterval = self.dataIn.timeInterval
220 self.dataOut.paramInterval = self.dataIn.timeInterval
221 #print("soy spectra ",self.dataOut.utctimeInit)
221 #print("soy spectra ",self.dataOut.utctimeInit)
222 return
222 return
223
223
224
224
225 def target(tups):
225 def target(tups):
226
226
227 obj, args = tups
227 obj, args = tups
228
228
229 return obj.FitGau(args)
229 return obj.FitGau(args)
230
230
231 class RemoveWideGC(Operation):
231 class RemoveWideGC(Operation):
232 ''' This class remove the wide clutter and replace it with a simple interpolation points
232 ''' This class remove the wide clutter and replace it with a simple interpolation points
233 This mainly applies to CLAIRE radar
233 This mainly applies to CLAIRE radar
234
234
235 ClutterWidth : Width to look for the clutter peak
235 ClutterWidth : Width to look for the clutter peak
236
236
237 Input:
237 Input:
238
238
239 self.dataOut.data_pre : SPC and CSPC
239 self.dataOut.data_pre : SPC and CSPC
240 self.dataOut.spc_range : To select wind and rainfall velocities
240 self.dataOut.spc_range : To select wind and rainfall velocities
241
241
242 Affected:
242 Affected:
243
243
244 self.dataOut.data_pre : It is used for the new SPC and CSPC ranges of wind
244 self.dataOut.data_pre : It is used for the new SPC and CSPC ranges of wind
245
245
246 Written by D. ScipiΓ³n 25.02.2021
246 Written by D. ScipiΓ³n 25.02.2021
247 '''
247 '''
248 def __init__(self):
248 def __init__(self):
249 Operation.__init__(self)
249 Operation.__init__(self)
250 self.i = 0
250 self.i = 0
251 self.ich = 0
251 self.ich = 0
252 self.ir = 0
252 self.ir = 0
253
253
254 def run(self, dataOut, ClutterWidth=2.5):
254 def run(self, dataOut, ClutterWidth=2.5):
255 # print ('Entering RemoveWideGC ... ')
255 # print ('Entering RemoveWideGC ... ')
256
256
257 self.spc = dataOut.data_pre[0].copy()
257 self.spc = dataOut.data_pre[0].copy()
258 self.spc_out = dataOut.data_pre[0].copy()
258 self.spc_out = dataOut.data_pre[0].copy()
259 self.Num_Chn = self.spc.shape[0]
259 self.Num_Chn = self.spc.shape[0]
260 self.Num_Hei = self.spc.shape[2]
260 self.Num_Hei = self.spc.shape[2]
261 VelRange = dataOut.spc_range[2][:-1]
261 VelRange = dataOut.spc_range[2][:-1]
262 dv = VelRange[1]-VelRange[0]
262 dv = VelRange[1]-VelRange[0]
263
263
264 # Find the velocities that corresponds to zero
264 # Find the velocities that corresponds to zero
265 gc_values = numpy.squeeze(numpy.where(numpy.abs(VelRange) <= ClutterWidth))
265 gc_values = numpy.squeeze(numpy.where(numpy.abs(VelRange) <= ClutterWidth))
266
266
267 # Removing novalid data from the spectra
267 # Removing novalid data from the spectra
268 for ich in range(self.Num_Chn) :
268 for ich in range(self.Num_Chn) :
269 for ir in range(self.Num_Hei) :
269 for ir in range(self.Num_Hei) :
270 # Estimate the noise at each range
270 # Estimate the noise at each range
271 HSn = hildebrand_sekhon(self.spc[ich,:,ir],dataOut.nIncohInt)
271 HSn = hildebrand_sekhon(self.spc[ich,:,ir],dataOut.nIncohInt)
272
272
273 # Removing the noise floor at each range
273 # Removing the noise floor at each range
274 novalid = numpy.where(self.spc[ich,:,ir] < HSn)
274 novalid = numpy.where(self.spc[ich,:,ir] < HSn)
275 self.spc[ich,novalid,ir] = HSn
275 self.spc[ich,novalid,ir] = HSn
276
276
277 junk = numpy.append(numpy.insert(numpy.squeeze(self.spc[ich,gc_values,ir]),0,HSn),HSn)
277 junk = numpy.append(numpy.insert(numpy.squeeze(self.spc[ich,gc_values,ir]),0,HSn),HSn)
278 j1index = numpy.squeeze(numpy.where(numpy.diff(junk)>0))
278 j1index = numpy.squeeze(numpy.where(numpy.diff(junk)>0))
279 j2index = numpy.squeeze(numpy.where(numpy.diff(junk)<0))
279 j2index = numpy.squeeze(numpy.where(numpy.diff(junk)<0))
280 if ((numpy.size(j1index)<=1) | (numpy.size(j2index)<=1)) :
280 if ((numpy.size(j1index)<=1) | (numpy.size(j2index)<=1)) :
281 continue
281 continue
282 junk3 = numpy.squeeze(numpy.diff(j1index))
282 junk3 = numpy.squeeze(numpy.diff(j1index))
283 junk4 = numpy.squeeze(numpy.diff(j2index))
283 junk4 = numpy.squeeze(numpy.diff(j2index))
284
284
285 valleyindex = j2index[numpy.where(junk4>1)]
285 valleyindex = j2index[numpy.where(junk4>1)]
286 peakindex = j1index[numpy.where(junk3>1)]
286 peakindex = j1index[numpy.where(junk3>1)]
287
287
288 isvalid = numpy.squeeze(numpy.where(numpy.abs(VelRange[gc_values[peakindex]]) <= 2.5*dv))
288 isvalid = numpy.squeeze(numpy.where(numpy.abs(VelRange[gc_values[peakindex]]) <= 2.5*dv))
289 if numpy.size(isvalid) == 0 :
289 if numpy.size(isvalid) == 0 :
290 continue
290 continue
291 if numpy.size(isvalid) >1 :
291 if numpy.size(isvalid) >1 :
292 vindex = numpy.argmax(self.spc[ich,gc_values[peakindex[isvalid]],ir])
292 vindex = numpy.argmax(self.spc[ich,gc_values[peakindex[isvalid]],ir])
293 isvalid = isvalid[vindex]
293 isvalid = isvalid[vindex]
294
294
295 # clutter peak
295 # clutter peak
296 gcpeak = peakindex[isvalid]
296 gcpeak = peakindex[isvalid]
297 vl = numpy.where(valleyindex < gcpeak)
297 vl = numpy.where(valleyindex < gcpeak)
298 if numpy.size(vl) == 0:
298 if numpy.size(vl) == 0:
299 continue
299 continue
300 gcvl = valleyindex[vl[0][-1]]
300 gcvl = valleyindex[vl[0][-1]]
301 vr = numpy.where(valleyindex > gcpeak)
301 vr = numpy.where(valleyindex > gcpeak)
302 if numpy.size(vr) == 0:
302 if numpy.size(vr) == 0:
303 continue
303 continue
304 gcvr = valleyindex[vr[0][0]]
304 gcvr = valleyindex[vr[0][0]]
305
305
306 # Removing the clutter
306 # Removing the clutter
307 interpindex = numpy.array([gc_values[gcvl], gc_values[gcvr]])
307 interpindex = numpy.array([gc_values[gcvl], gc_values[gcvr]])
308 gcindex = gc_values[gcvl+1:gcvr-1]
308 gcindex = gc_values[gcvl+1:gcvr-1]
309 self.spc_out[ich,gcindex,ir] = numpy.interp(VelRange[gcindex],VelRange[interpindex],self.spc[ich,interpindex,ir])
309 self.spc_out[ich,gcindex,ir] = numpy.interp(VelRange[gcindex],VelRange[interpindex],self.spc[ich,interpindex,ir])
310
310
311 dataOut.data_pre[0] = self.spc_out
311 dataOut.data_pre[0] = self.spc_out
312 #print ('Leaving RemoveWideGC ... ')
312 #print ('Leaving RemoveWideGC ... ')
313 return dataOut
313 return dataOut
314
314
315 class SpectralFilters(Operation):
315 class SpectralFilters(Operation):
316 ''' This class allows to replace the novalid values with noise for each channel
316 ''' This class allows to replace the novalid values with noise for each channel
317 This applies to CLAIRE RADAR
317 This applies to CLAIRE RADAR
318
318
319 PositiveLimit : RightLimit of novalid data
319 PositiveLimit : RightLimit of novalid data
320 NegativeLimit : LeftLimit of novalid data
320 NegativeLimit : LeftLimit of novalid data
321
321
322 Input:
322 Input:
323
323
324 self.dataOut.data_pre : SPC and CSPC
324 self.dataOut.data_pre : SPC and CSPC
325 self.dataOut.spc_range : To select wind and rainfall velocities
325 self.dataOut.spc_range : To select wind and rainfall velocities
326
326
327 Affected:
327 Affected:
328
328
329 self.dataOut.data_pre : It is used for the new SPC and CSPC ranges of wind
329 self.dataOut.data_pre : It is used for the new SPC and CSPC ranges of wind
330
330
331 Written by D. ScipiΓ³n 29.01.2021
331 Written by D. ScipiΓ³n 29.01.2021
332 '''
332 '''
333 def __init__(self):
333 def __init__(self):
334 Operation.__init__(self)
334 Operation.__init__(self)
335 self.i = 0
335 self.i = 0
336
336
337 def run(self, dataOut, ):
337 def run(self, dataOut, ):
338
338
339 self.spc = dataOut.data_pre[0].copy()
339 self.spc = dataOut.data_pre[0].copy()
340 self.Num_Chn = self.spc.shape[0]
340 self.Num_Chn = self.spc.shape[0]
341 VelRange = dataOut.spc_range[2]
341 VelRange = dataOut.spc_range[2]
342
342
343 # novalid corresponds to data within the Negative and PositiveLimit
343 # novalid corresponds to data within the Negative and PositiveLimit
344
344
345
345
346 # Removing novalid data from the spectra
346 # Removing novalid data from the spectra
347 for i in range(self.Num_Chn):
347 for i in range(self.Num_Chn):
348 self.spc[i,novalid,:] = dataOut.noise[i]
348 self.spc[i,novalid,:] = dataOut.noise[i]
349 dataOut.data_pre[0] = self.spc
349 dataOut.data_pre[0] = self.spc
350 return dataOut
350 return dataOut
351
351
352 class GaussianFit(Operation):
352 class GaussianFit(Operation):
353
353
354 '''
354 '''
355 Function that fit of one and two generalized gaussians (gg) based
355 Function that fit of one and two generalized gaussians (gg) based
356 on the PSD shape across an "power band" identified from a cumsum of
356 on the PSD shape across an "power band" identified from a cumsum of
357 the measured spectrum - noise.
357 the measured spectrum - noise.
358
358
359 Input:
359 Input:
360 self.dataOut.data_pre : SelfSpectra
360 self.dataOut.data_pre : SelfSpectra
361
361
362 Output:
362 Output:
363 self.dataOut.SPCparam : SPC_ch1, SPC_ch2
363 self.dataOut.SPCparam : SPC_ch1, SPC_ch2
364
364
365 '''
365 '''
366 def __init__(self):
366 def __init__(self):
367 Operation.__init__(self)
367 Operation.__init__(self)
368 self.i=0
368 self.i=0
369
369
370
370
371 # def run(self, dataOut, num_intg=7, pnoise=1., SNRlimit=-9): #num_intg: Incoherent integrations, pnoise: Noise, vel_arr: range of velocities, similar to the ftt points
371 # def run(self, dataOut, num_intg=7, pnoise=1., SNRlimit=-9): #num_intg: Incoherent integrations, pnoise: Noise, vel_arr: range of velocities, similar to the ftt points
372 def run(self, dataOut, SNRdBlimit=-9, method='generalized'):
372 def run(self, dataOut, SNRdBlimit=-9, method='generalized'):
373 """This routine will find a couple of generalized Gaussians to a power spectrum
373 """This routine will find a couple of generalized Gaussians to a power spectrum
374 methods: generalized, squared
374 methods: generalized, squared
375 input: spc
375 input: spc
376 output:
376 output:
377 noise, amplitude0,shift0,width0,p0,Amplitude1,shift1,width1,p1
377 noise, amplitude0,shift0,width0,p0,Amplitude1,shift1,width1,p1
378 """
378 """
379 print ('Entering ',method,' double Gaussian fit')
379 print ('Entering ',method,' double Gaussian fit')
380 self.spc = dataOut.data_pre[0].copy()
380 self.spc = dataOut.data_pre[0].copy()
381 self.Num_Hei = self.spc.shape[2]
381 self.Num_Hei = self.spc.shape[2]
382 self.Num_Bin = self.spc.shape[1]
382 self.Num_Bin = self.spc.shape[1]
383 self.Num_Chn = self.spc.shape[0]
383 self.Num_Chn = self.spc.shape[0]
384
384
385 start_time = time.time()
385 start_time = time.time()
386
386
387 pool = Pool(processes=self.Num_Chn)
387 pool = Pool(processes=self.Num_Chn)
388 args = [(dataOut.spc_range[2], ich, dataOut.spc_noise[ich], dataOut.nIncohInt, SNRdBlimit) for ich in range(self.Num_Chn)]
388 args = [(dataOut.spc_range[2], ich, dataOut.spc_noise[ich], dataOut.nIncohInt, SNRdBlimit) for ich in range(self.Num_Chn)]
389 objs = [self for __ in range(self.Num_Chn)]
389 objs = [self for __ in range(self.Num_Chn)]
390 attrs = list(zip(objs, args))
390 attrs = list(zip(objs, args))
391 DGauFitParam = pool.map(target, attrs)
391 DGauFitParam = pool.map(target, attrs)
392 # Parameters:
392 # Parameters:
393 # 0. Noise, 1. Amplitude, 2. Shift, 3. Width 4. Power
393 # 0. Noise, 1. Amplitude, 2. Shift, 3. Width 4. Power
394 dataOut.DGauFitParams = numpy.asarray(DGauFitParam)
394 dataOut.DGauFitParams = numpy.asarray(DGauFitParam)
395
395
396 # Double Gaussian Curves
396 # Double Gaussian Curves
397 gau0 = numpy.zeros([self.Num_Chn,self.Num_Bin,self.Num_Hei])
397 gau0 = numpy.zeros([self.Num_Chn,self.Num_Bin,self.Num_Hei])
398 gau0[:] = numpy.NaN
398 gau0[:] = numpy.NaN
399 gau1 = numpy.zeros([self.Num_Chn,self.Num_Bin,self.Num_Hei])
399 gau1 = numpy.zeros([self.Num_Chn,self.Num_Bin,self.Num_Hei])
400 gau1[:] = numpy.NaN
400 gau1[:] = numpy.NaN
401 x_mtr = numpy.transpose(numpy.tile(dataOut.getVelRange(1)[:-1], (self.Num_Hei,1)))
401 x_mtr = numpy.transpose(numpy.tile(dataOut.getVelRange(1)[:-1], (self.Num_Hei,1)))
402 for iCh in range(self.Num_Chn):
402 for iCh in range(self.Num_Chn):
403 N0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][0,:,0]] * self.Num_Bin))
403 N0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][0,:,0]] * self.Num_Bin))
404 N1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][0,:,1]] * self.Num_Bin))
404 N1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][0,:,1]] * self.Num_Bin))
405 A0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][1,:,0]] * self.Num_Bin))
405 A0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][1,:,0]] * self.Num_Bin))
406 A1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][1,:,1]] * self.Num_Bin))
406 A1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][1,:,1]] * self.Num_Bin))
407 v0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][2,:,0]] * self.Num_Bin))
407 v0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][2,:,0]] * self.Num_Bin))
408 v1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][2,:,1]] * self.Num_Bin))
408 v1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][2,:,1]] * self.Num_Bin))
409 s0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][3,:,0]] * self.Num_Bin))
409 s0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][3,:,0]] * self.Num_Bin))
410 s1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][3,:,1]] * self.Num_Bin))
410 s1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][3,:,1]] * self.Num_Bin))
411 if method == 'genealized':
411 if method == 'genealized':
412 p0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][4,:,0]] * self.Num_Bin))
412 p0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][4,:,0]] * self.Num_Bin))
413 p1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][4,:,1]] * self.Num_Bin))
413 p1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][4,:,1]] * self.Num_Bin))
414 elif method == 'squared':
414 elif method == 'squared':
415 p0 = 2.
415 p0 = 2.
416 p1 = 2.
416 p1 = 2.
417 gau0[iCh] = A0*numpy.exp(-0.5*numpy.abs((x_mtr-v0)/s0)**p0)+N0
417 gau0[iCh] = A0*numpy.exp(-0.5*numpy.abs((x_mtr-v0)/s0)**p0)+N0
418 gau1[iCh] = A1*numpy.exp(-0.5*numpy.abs((x_mtr-v1)/s1)**p1)+N1
418 gau1[iCh] = A1*numpy.exp(-0.5*numpy.abs((x_mtr-v1)/s1)**p1)+N1
419 dataOut.GaussFit0 = gau0
419 dataOut.GaussFit0 = gau0
420 dataOut.GaussFit1 = gau1
420 dataOut.GaussFit1 = gau1
421
421
422 print('Leaving ',method ,' double Gaussian fit')
422 print('Leaving ',method ,' double Gaussian fit')
423 return dataOut
423 return dataOut
424
424
425 def FitGau(self, X):
425 def FitGau(self, X):
426 # print('Entering FitGau')
426 # print('Entering FitGau')
427 # Assigning the variables
427 # Assigning the variables
428 Vrange, ch, wnoise, num_intg, SNRlimit = X
428 Vrange, ch, wnoise, num_intg, SNRlimit = X
429 # Noise Limits
429 # Noise Limits
430 noisebl = wnoise * 0.9
430 noisebl = wnoise * 0.9
431 noisebh = wnoise * 1.1
431 noisebh = wnoise * 1.1
432 # Radar Velocity
432 # Radar Velocity
433 Va = max(Vrange)
433 Va = max(Vrange)
434 deltav = Vrange[1] - Vrange[0]
434 deltav = Vrange[1] - Vrange[0]
435 x = numpy.arange(self.Num_Bin)
435 x = numpy.arange(self.Num_Bin)
436
436
437 # print ('stop 0')
437 # print ('stop 0')
438
438
439 # 5 parameters, 2 Gaussians
439 # 5 parameters, 2 Gaussians
440 DGauFitParam = numpy.zeros([5, self.Num_Hei,2])
440 DGauFitParam = numpy.zeros([5, self.Num_Hei,2])
441 DGauFitParam[:] = numpy.NaN
441 DGauFitParam[:] = numpy.NaN
442
442
443 # SPCparam = []
443 # SPCparam = []
444 # SPC_ch1 = numpy.zeros([self.Num_Bin,self.Num_Hei])
444 # SPC_ch1 = numpy.zeros([self.Num_Bin,self.Num_Hei])
445 # SPC_ch2 = numpy.zeros([self.Num_Bin,self.Num_Hei])
445 # SPC_ch2 = numpy.zeros([self.Num_Bin,self.Num_Hei])
446 # SPC_ch1[:] = 0 #numpy.NaN
446 # SPC_ch1[:] = 0 #numpy.NaN
447 # SPC_ch2[:] = 0 #numpy.NaN
447 # SPC_ch2[:] = 0 #numpy.NaN
448 # print ('stop 1')
448 # print ('stop 1')
449 for ht in range(self.Num_Hei):
449 for ht in range(self.Num_Hei):
450 # print (ht)
450 # print (ht)
451 # print ('stop 2')
451 # print ('stop 2')
452 # Spectra at each range
452 # Spectra at each range
453 spc = numpy.asarray(self.spc)[ch,:,ht]
453 spc = numpy.asarray(self.spc)[ch,:,ht]
454 snr = ( spc.mean() - wnoise ) / wnoise
454 snr = ( spc.mean() - wnoise ) / wnoise
455 snrdB = 10.*numpy.log10(snr)
455 snrdB = 10.*numpy.log10(snr)
456
456
457 #print ('stop 3')
457 #print ('stop 3')
458 if snrdB < SNRlimit :
458 if snrdB < SNRlimit :
459 # snr = numpy.NaN
459 # snr = numpy.NaN
460 # SPC_ch1[:,ht] = 0#numpy.NaN
460 # SPC_ch1[:,ht] = 0#numpy.NaN
461 # SPC_ch1[:,ht] = 0#numpy.NaN
461 # SPC_ch1[:,ht] = 0#numpy.NaN
462 # SPCparam = (SPC_ch1,SPC_ch2)
462 # SPCparam = (SPC_ch1,SPC_ch2)
463 # print ('SNR less than SNRth')
463 # print ('SNR less than SNRth')
464 continue
464 continue
465 # wnoise = hildebrand_sekhon(spc,num_intg)
465 # wnoise = hildebrand_sekhon(spc,num_intg)
466 # print ('stop 2.01')
466 # print ('stop 2.01')
467 #############################################
467 #############################################
468 # normalizing spc and noise
468 # normalizing spc and noise
469 # This part differs from gg1
469 # This part differs from gg1
470 # spc_norm_max = max(spc) #commented by D. ScipiΓ³n 19.03.2021
470 # spc_norm_max = max(spc) #commented by D. ScipiΓ³n 19.03.2021
471 #spc = spc / spc_norm_max
471 #spc = spc / spc_norm_max
472 # pnoise = pnoise #/ spc_norm_max #commented by D. ScipiΓ³n 19.03.2021
472 # pnoise = pnoise #/ spc_norm_max #commented by D. ScipiΓ³n 19.03.2021
473 #############################################
473 #############################################
474
474
475 # print ('stop 2.1')
475 # print ('stop 2.1')
476 fatspectra=1.0
476 fatspectra=1.0
477 # noise per channel.... we might want to use the noise at each range
477 # noise per channel.... we might want to use the noise at each range
478
478
479 # wnoise = noise_ #/ spc_norm_max #commented by D. ScipiΓ³n 19.03.2021
479 # wnoise = noise_ #/ spc_norm_max #commented by D. ScipiΓ³n 19.03.2021
480 #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
480 #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
481 #if wnoise>1.1*pnoise: # to be tested later
481 #if wnoise>1.1*pnoise: # to be tested later
482 # wnoise=pnoise
482 # wnoise=pnoise
483 # noisebl = wnoise*0.9
483 # noisebl = wnoise*0.9
484 # noisebh = wnoise*1.1
484 # noisebh = wnoise*1.1
485 spc = spc - wnoise # signal
485 spc = spc - wnoise # signal
486
486
487 # print ('stop 2.2')
487 # print ('stop 2.2')
488 minx = numpy.argmin(spc)
488 minx = numpy.argmin(spc)
489 #spcs=spc.copy()
489 #spcs=spc.copy()
490 spcs = numpy.roll(spc,-minx)
490 spcs = numpy.roll(spc,-minx)
491 cum = numpy.cumsum(spcs)
491 cum = numpy.cumsum(spcs)
492 # tot_noise = wnoise * self.Num_Bin #64;
492 # tot_noise = wnoise * self.Num_Bin #64;
493
493
494 # print ('stop 2.3')
494 # print ('stop 2.3')
495 # snr = sum(spcs) / tot_noise
495 # snr = sum(spcs) / tot_noise
496 # snrdB = 10.*numpy.log10(snr)
496 # snrdB = 10.*numpy.log10(snr)
497 #print ('stop 3')
497 #print ('stop 3')
498 # if snrdB < SNRlimit :
498 # if snrdB < SNRlimit :
499 # snr = numpy.NaN
499 # snr = numpy.NaN
500 # SPC_ch1[:,ht] = 0#numpy.NaN
500 # SPC_ch1[:,ht] = 0#numpy.NaN
501 # SPC_ch1[:,ht] = 0#numpy.NaN
501 # SPC_ch1[:,ht] = 0#numpy.NaN
502 # SPCparam = (SPC_ch1,SPC_ch2)
502 # SPCparam = (SPC_ch1,SPC_ch2)
503 # print ('SNR less than SNRth')
503 # print ('SNR less than SNRth')
504 # continue
504 # continue
505
505
506
506
507 #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
507 #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
508 # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
508 # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
509 # print ('stop 4')
509 # print ('stop 4')
510 cummax = max(cum)
510 cummax = max(cum)
511 epsi = 0.08 * fatspectra # cumsum to narrow down the energy region
511 epsi = 0.08 * fatspectra # cumsum to narrow down the energy region
512 cumlo = cummax * epsi
512 cumlo = cummax * epsi
513 cumhi = cummax * (1-epsi)
513 cumhi = cummax * (1-epsi)
514 powerindex = numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
514 powerindex = numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
515
515
516 # print ('stop 5')
516 # print ('stop 5')
517 if len(powerindex) < 1:# case for powerindex 0
517 if len(powerindex) < 1:# case for powerindex 0
518 # print ('powerindex < 1')
518 # print ('powerindex < 1')
519 continue
519 continue
520 powerlo = powerindex[0]
520 powerlo = powerindex[0]
521 powerhi = powerindex[-1]
521 powerhi = powerindex[-1]
522 powerwidth = powerhi-powerlo
522 powerwidth = powerhi-powerlo
523 if powerwidth <= 1:
523 if powerwidth <= 1:
524 # print('powerwidth <= 1')
524 # print('powerwidth <= 1')
525 continue
525 continue
526
526
527 # print ('stop 6')
527 # print ('stop 6')
528 firstpeak = powerlo + powerwidth/10.# first gaussian energy location
528 firstpeak = powerlo + powerwidth/10.# first gaussian energy location
529 secondpeak = powerhi - powerwidth/10. #second gaussian energy location
529 secondpeak = powerhi - powerwidth/10. #second gaussian energy location
530 midpeak = (firstpeak + secondpeak)/2.
530 midpeak = (firstpeak + secondpeak)/2.
531 firstamp = spcs[int(firstpeak)]
531 firstamp = spcs[int(firstpeak)]
532 secondamp = spcs[int(secondpeak)]
532 secondamp = spcs[int(secondpeak)]
533 midamp = spcs[int(midpeak)]
533 midamp = spcs[int(midpeak)]
534
534
535 y_data = spc + wnoise
535 y_data = spc + wnoise
536
536
537 ''' single Gaussian '''
537 ''' single Gaussian '''
538 shift0 = numpy.mod(midpeak+minx, self.Num_Bin )
538 shift0 = numpy.mod(midpeak+minx, self.Num_Bin )
539 width0 = powerwidth/4.#Initialization entire power of spectrum divided by 4
539 width0 = powerwidth/4.#Initialization entire power of spectrum divided by 4
540 power0 = 2.
540 power0 = 2.
541 amplitude0 = midamp
541 amplitude0 = midamp
542 state0 = [shift0,width0,amplitude0,power0,wnoise]
542 state0 = [shift0,width0,amplitude0,power0,wnoise]
543 bnds = ((0,self.Num_Bin-1),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
543 bnds = ((0,self.Num_Bin-1),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
544 lsq1 = fmin_l_bfgs_b(self.misfit1, state0, args=(y_data,x,num_intg), bounds=bnds, approx_grad=True)
544 lsq1 = fmin_l_bfgs_b(self.misfit1, state0, args=(y_data,x,num_intg), bounds=bnds, approx_grad=True)
545 # print ('stop 7.1')
545 # print ('stop 7.1')
546 # print (bnds)
546 # print (bnds)
547
547
548 chiSq1=lsq1[1]
548 chiSq1=lsq1[1]
549
549
550 # print ('stop 8')
550 # print ('stop 8')
551 if fatspectra<1.0 and powerwidth<4:
551 if fatspectra<1.0 and powerwidth<4:
552 choice=0
552 choice=0
553 Amplitude0=lsq1[0][2]
553 Amplitude0=lsq1[0][2]
554 shift0=lsq1[0][0]
554 shift0=lsq1[0][0]
555 width0=lsq1[0][1]
555 width0=lsq1[0][1]
556 p0=lsq1[0][3]
556 p0=lsq1[0][3]
557 Amplitude1=0.
557 Amplitude1=0.
558 shift1=0.
558 shift1=0.
559 width1=0.
559 width1=0.
560 p1=0.
560 p1=0.
561 noise=lsq1[0][4]
561 noise=lsq1[0][4]
562 #return (numpy.array([shift0,width0,Amplitude0,p0]),
562 #return (numpy.array([shift0,width0,Amplitude0,p0]),
563 # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
563 # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
564
564
565 # print ('stop 9')
565 # print ('stop 9')
566 ''' two Gaussians '''
566 ''' two Gaussians '''
567 #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
567 #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
568 shift0 = numpy.mod(firstpeak+minx, self.Num_Bin )
568 shift0 = numpy.mod(firstpeak+minx, self.Num_Bin )
569 shift1 = numpy.mod(secondpeak+minx, self.Num_Bin )
569 shift1 = numpy.mod(secondpeak+minx, self.Num_Bin )
570 width0 = powerwidth/6.
570 width0 = powerwidth/6.
571 width1 = width0
571 width1 = width0
572 power0 = 2.
572 power0 = 2.
573 power1 = power0
573 power1 = power0
574 amplitude0 = firstamp
574 amplitude0 = firstamp
575 amplitude1 = secondamp
575 amplitude1 = secondamp
576 state0 = [shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
576 state0 = [shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
577 #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
577 #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
578 bnds=((0,self.Num_Bin-1),(1,powerwidth/2.),(0,None),(0.5,3.),(0,self.Num_Bin-1),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
578 bnds=((0,self.Num_Bin-1),(1,powerwidth/2.),(0,None),(0.5,3.),(0,self.Num_Bin-1),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
579 #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(0.1,0.5))
579 #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(0.1,0.5))
580
580
581 # print ('stop 10')
581 # print ('stop 10')
582 lsq2 = fmin_l_bfgs_b( self.misfit2 , state0 , args=(y_data,x,num_intg) , bounds=bnds , approx_grad=True )
582 lsq2 = fmin_l_bfgs_b( self.misfit2 , state0 , args=(y_data,x,num_intg) , bounds=bnds , approx_grad=True )
583
583
584 # print ('stop 11')
584 # print ('stop 11')
585 chiSq2 = lsq2[1]
585 chiSq2 = lsq2[1]
586
586
587 # print ('stop 12')
587 # print ('stop 12')
588
588
589 oneG = (chiSq1<5 and chiSq1/chiSq2<2.0) and (abs(lsq2[0][0]-lsq2[0][4])<(lsq2[0][1]+lsq2[0][5])/3. or abs(lsq2[0][0]-lsq2[0][4])<10)
589 oneG = (chiSq1<5 and chiSq1/chiSq2<2.0) and (abs(lsq2[0][0]-lsq2[0][4])<(lsq2[0][1]+lsq2[0][5])/3. or abs(lsq2[0][0]-lsq2[0][4])<10)
590
590
591 # print ('stop 13')
591 # print ('stop 13')
592 if snrdB>-12: # when SNR is strong pick the peak with least shift (LOS velocity) error
592 if snrdB>-12: # when SNR is strong pick the peak with least shift (LOS velocity) error
593 if oneG:
593 if oneG:
594 choice = 0
594 choice = 0
595 else:
595 else:
596 w1 = lsq2[0][1]; w2 = lsq2[0][5]
596 w1 = lsq2[0][1]; w2 = lsq2[0][5]
597 a1 = lsq2[0][2]; a2 = lsq2[0][6]
597 a1 = lsq2[0][2]; a2 = lsq2[0][6]
598 p1 = lsq2[0][3]; p2 = lsq2[0][7]
598 p1 = lsq2[0][3]; p2 = lsq2[0][7]
599 s1 = (2**(1+1./p1))*scipy.special.gamma(1./p1)/p1
599 s1 = (2**(1+1./p1))*scipy.special.gamma(1./p1)/p1
600 s2 = (2**(1+1./p2))*scipy.special.gamma(1./p2)/p2
600 s2 = (2**(1+1./p2))*scipy.special.gamma(1./p2)/p2
601 gp1 = a1*w1*s1; gp2 = a2*w2*s2 # power content of each ggaussian with proper p scaling
601 gp1 = a1*w1*s1; gp2 = a2*w2*s2 # power content of each ggaussian with proper p scaling
602
602
603 if gp1>gp2:
603 if gp1>gp2:
604 if a1>0.7*a2:
604 if a1>0.7*a2:
605 choice = 1
605 choice = 1
606 else:
606 else:
607 choice = 2
607 choice = 2
608 elif gp2>gp1:
608 elif gp2>gp1:
609 if a2>0.7*a1:
609 if a2>0.7*a1:
610 choice = 2
610 choice = 2
611 else:
611 else:
612 choice = 1
612 choice = 1
613 else:
613 else:
614 choice = numpy.argmax([a1,a2])+1
614 choice = numpy.argmax([a1,a2])+1
615 #else:
615 #else:
616 #choice=argmin([std2a,std2b])+1
616 #choice=argmin([std2a,std2b])+1
617
617
618 else: # with low SNR go to the most energetic peak
618 else: # with low SNR go to the most energetic peak
619 choice = numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
619 choice = numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
620
620
621 # print ('stop 14')
621 # print ('stop 14')
622 shift0 = lsq2[0][0]
622 shift0 = lsq2[0][0]
623 vel0 = Vrange[0] + shift0 * deltav
623 vel0 = Vrange[0] + shift0 * deltav
624 shift1 = lsq2[0][4]
624 shift1 = lsq2[0][4]
625 # vel1=Vrange[0] + shift1 * deltav
625 # vel1=Vrange[0] + shift1 * deltav
626
626
627 # max_vel = 1.0
627 # max_vel = 1.0
628 # Va = max(Vrange)
628 # Va = max(Vrange)
629 # deltav = Vrange[1]-Vrange[0]
629 # deltav = Vrange[1]-Vrange[0]
630 # print ('stop 15')
630 # print ('stop 15')
631 #first peak will be 0, second peak will be 1
631 #first peak will be 0, second peak will be 1
632 # if vel0 > -1.0 and vel0 < max_vel : #first peak is in the correct range # Commented by D.ScipiΓ³n 19.03.2021
632 # if vel0 > -1.0 and vel0 < max_vel : #first peak is in the correct range # Commented by D.ScipiΓ³n 19.03.2021
633 if vel0 > -Va and vel0 < Va : #first peak is in the correct range
633 if vel0 > -Va and vel0 < Va : #first peak is in the correct range
634 shift0 = lsq2[0][0]
634 shift0 = lsq2[0][0]
635 width0 = lsq2[0][1]
635 width0 = lsq2[0][1]
636 Amplitude0 = lsq2[0][2]
636 Amplitude0 = lsq2[0][2]
637 p0 = lsq2[0][3]
637 p0 = lsq2[0][3]
638
638
639 shift1 = lsq2[0][4]
639 shift1 = lsq2[0][4]
640 width1 = lsq2[0][5]
640 width1 = lsq2[0][5]
641 Amplitude1 = lsq2[0][6]
641 Amplitude1 = lsq2[0][6]
642 p1 = lsq2[0][7]
642 p1 = lsq2[0][7]
643 noise = lsq2[0][8]
643 noise = lsq2[0][8]
644 else:
644 else:
645 shift1 = lsq2[0][0]
645 shift1 = lsq2[0][0]
646 width1 = lsq2[0][1]
646 width1 = lsq2[0][1]
647 Amplitude1 = lsq2[0][2]
647 Amplitude1 = lsq2[0][2]
648 p1 = lsq2[0][3]
648 p1 = lsq2[0][3]
649
649
650 shift0 = lsq2[0][4]
650 shift0 = lsq2[0][4]
651 width0 = lsq2[0][5]
651 width0 = lsq2[0][5]
652 Amplitude0 = lsq2[0][6]
652 Amplitude0 = lsq2[0][6]
653 p0 = lsq2[0][7]
653 p0 = lsq2[0][7]
654 noise = lsq2[0][8]
654 noise = lsq2[0][8]
655
655
656 if Amplitude0<0.05: # in case the peak is noise
656 if Amplitude0<0.05: # in case the peak is noise
657 shift0,width0,Amplitude0,p0 = 4*[numpy.NaN]
657 shift0,width0,Amplitude0,p0 = 4*[numpy.NaN]
658 if Amplitude1<0.05:
658 if Amplitude1<0.05:
659 shift1,width1,Amplitude1,p1 = 4*[numpy.NaN]
659 shift1,width1,Amplitude1,p1 = 4*[numpy.NaN]
660
660
661 # print ('stop 16 ')
661 # print ('stop 16 ')
662 # SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0)/width0)**p0)
662 # SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0)/width0)**p0)
663 # SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1)/width1)**p1)
663 # SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1)/width1)**p1)
664 # SPCparam = (SPC_ch1,SPC_ch2)
664 # SPCparam = (SPC_ch1,SPC_ch2)
665
665
666 DGauFitParam[0,ht,0] = noise
666 DGauFitParam[0,ht,0] = noise
667 DGauFitParam[0,ht,1] = noise
667 DGauFitParam[0,ht,1] = noise
668 DGauFitParam[1,ht,0] = Amplitude0
668 DGauFitParam[1,ht,0] = Amplitude0
669 DGauFitParam[1,ht,1] = Amplitude1
669 DGauFitParam[1,ht,1] = Amplitude1
670 DGauFitParam[2,ht,0] = Vrange[0] + shift0 * deltav
670 DGauFitParam[2,ht,0] = Vrange[0] + shift0 * deltav
671 DGauFitParam[2,ht,1] = Vrange[0] + shift1 * deltav
671 DGauFitParam[2,ht,1] = Vrange[0] + shift1 * deltav
672 DGauFitParam[3,ht,0] = width0 * deltav
672 DGauFitParam[3,ht,0] = width0 * deltav
673 DGauFitParam[3,ht,1] = width1 * deltav
673 DGauFitParam[3,ht,1] = width1 * deltav
674 DGauFitParam[4,ht,0] = p0
674 DGauFitParam[4,ht,0] = p0
675 DGauFitParam[4,ht,1] = p1
675 DGauFitParam[4,ht,1] = p1
676
676
677 # print (DGauFitParam.shape)
677 # print (DGauFitParam.shape)
678 # print ('Leaving FitGau')
678 # print ('Leaving FitGau')
679 return DGauFitParam
679 return DGauFitParam
680 # return SPCparam
680 # return SPCparam
681 # return GauSPC
681 # return GauSPC
682
682
683 def y_model1(self,x,state):
683 def y_model1(self,x,state):
684 shift0, width0, amplitude0, power0, noise = state
684 shift0, width0, amplitude0, power0, noise = state
685 model0 = amplitude0*numpy.exp(-0.5*abs((x - shift0)/width0)**power0)
685 model0 = amplitude0*numpy.exp(-0.5*abs((x - shift0)/width0)**power0)
686 model0u = amplitude0*numpy.exp(-0.5*abs((x - shift0 - self.Num_Bin)/width0)**power0)
686 model0u = amplitude0*numpy.exp(-0.5*abs((x - shift0 - self.Num_Bin)/width0)**power0)
687 model0d = amplitude0*numpy.exp(-0.5*abs((x - shift0 + self.Num_Bin)/width0)**power0)
687 model0d = amplitude0*numpy.exp(-0.5*abs((x - shift0 + self.Num_Bin)/width0)**power0)
688 return model0 + model0u + model0d + noise
688 return model0 + model0u + model0d + noise
689
689
690 def y_model2(self,x,state): #Equation for two generalized Gaussians with Nyquist
690 def y_model2(self,x,state): #Equation for two generalized Gaussians with Nyquist
691 shift0, width0, amplitude0, power0, shift1, width1, amplitude1, power1, noise = state
691 shift0, width0, amplitude0, power0, shift1, width1, amplitude1, power1, noise = state
692 model0 = amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
692 model0 = amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
693 model0u = amplitude0*numpy.exp(-0.5*abs((x - shift0 - self.Num_Bin)/width0)**power0)
693 model0u = amplitude0*numpy.exp(-0.5*abs((x - shift0 - self.Num_Bin)/width0)**power0)
694 model0d = amplitude0*numpy.exp(-0.5*abs((x - shift0 + self.Num_Bin)/width0)**power0)
694 model0d = amplitude0*numpy.exp(-0.5*abs((x - shift0 + self.Num_Bin)/width0)**power0)
695
695
696 model1 = amplitude1*numpy.exp(-0.5*abs((x - shift1)/width1)**power1)
696 model1 = amplitude1*numpy.exp(-0.5*abs((x - shift1)/width1)**power1)
697 model1u = amplitude1*numpy.exp(-0.5*abs((x - shift1 - self.Num_Bin)/width1)**power1)
697 model1u = amplitude1*numpy.exp(-0.5*abs((x - shift1 - self.Num_Bin)/width1)**power1)
698 model1d = amplitude1*numpy.exp(-0.5*abs((x - shift1 + self.Num_Bin)/width1)**power1)
698 model1d = amplitude1*numpy.exp(-0.5*abs((x - shift1 + self.Num_Bin)/width1)**power1)
699 return model0 + model0u + model0d + model1 + model1u + model1d + noise
699 return model0 + model0u + model0d + model1 + model1u + model1d + noise
700
700
701 def misfit1(self,state,y_data,x,num_intg): # This function compares how close real data is with the model data, the close it is, the better it is.
701 def misfit1(self,state,y_data,x,num_intg): # This function compares how close real data is with the model data, the close it is, the better it is.
702
702
703 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model1(x,state)))**2)#/(64-5.) # /(64-5.) can be commented
703 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model1(x,state)))**2)#/(64-5.) # /(64-5.) can be commented
704
704
705 def misfit2(self,state,y_data,x,num_intg):
705 def misfit2(self,state,y_data,x,num_intg):
706 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model2(x,state)))**2)#/(64-9.)
706 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model2(x,state)))**2)#/(64-9.)
707
707
708
708
709
709
710 class PrecipitationProc(Operation):
710 class PrecipitationProc(Operation):
711
711
712 '''
712 '''
713 Operator that estimates Reflectivity factor (Z), and estimates rainfall Rate (R)
713 Operator that estimates Reflectivity factor (Z), and estimates rainfall Rate (R)
714
714
715 Input:
715 Input:
716 self.dataOut.data_pre : SelfSpectra
716 self.dataOut.data_pre : SelfSpectra
717
717
718 Output:
718 Output:
719
719
720 self.dataOut.data_output : Reflectivity factor, rainfall Rate
720 self.dataOut.data_output : Reflectivity factor, rainfall Rate
721
721
722
722
723 Parameters affected:
723 Parameters affected:
724 '''
724 '''
725
725
726 def __init__(self):
726 def __init__(self):
727 Operation.__init__(self)
727 Operation.__init__(self)
728 self.i=0
728 self.i=0
729
729
730 def run(self, dataOut, radar=None, Pt=5000, Gt=295.1209, Gr=70.7945, Lambda=0.6741, aL=2.5118,
730 def run(self, dataOut, radar=None, Pt=5000, Gt=295.1209, Gr=70.7945, Lambda=0.6741, aL=2.5118,
731 tauW=4e-06, ThetaT=0.1656317, ThetaR=0.36774087, Km2 = 0.93, Altitude=3350,SNRdBlimit=-30):
731 tauW=4e-06, ThetaT=0.1656317, ThetaR=0.36774087, Km2 = 0.93, Altitude=3350,SNRdBlimit=-30):
732
732
733 # print ('Entering PrecepitationProc ... ')
733 # print ('Entering PrecepitationProc ... ')
734
734
735 if radar == "MIRA35C" :
735 if radar == "MIRA35C" :
736
736
737 self.spc = dataOut.data_pre[0].copy()
737 self.spc = dataOut.data_pre[0].copy()
738 self.Num_Hei = self.spc.shape[2]
738 self.Num_Hei = self.spc.shape[2]
739 self.Num_Bin = self.spc.shape[1]
739 self.Num_Bin = self.spc.shape[1]
740 self.Num_Chn = self.spc.shape[0]
740 self.Num_Chn = self.spc.shape[0]
741 Ze = self.dBZeMODE2(dataOut)
741 Ze = self.dBZeMODE2(dataOut)
742
742
743 else:
743 else:
744
744
745 self.spc = dataOut.data_pre[0].copy()
745 self.spc = dataOut.data_pre[0].copy()
746
746
747 #NOTA SE DEBE REMOVER EL RANGO DEL PULSO TX
747 #NOTA SE DEBE REMOVER EL RANGO DEL PULSO TX
748 self.spc[:,:,0:7]= numpy.NaN
748 self.spc[:,:,0:7]= numpy.NaN
749
749
750 self.Num_Hei = self.spc.shape[2]
750 self.Num_Hei = self.spc.shape[2]
751 self.Num_Bin = self.spc.shape[1]
751 self.Num_Bin = self.spc.shape[1]
752 self.Num_Chn = self.spc.shape[0]
752 self.Num_Chn = self.spc.shape[0]
753
753
754 VelRange = dataOut.spc_range[2]
754 VelRange = dataOut.spc_range[2]
755
755
756 ''' Se obtiene la constante del RADAR '''
756 ''' Se obtiene la constante del RADAR '''
757
757
758 self.Pt = Pt
758 self.Pt = Pt
759 self.Gt = Gt
759 self.Gt = Gt
760 self.Gr = Gr
760 self.Gr = Gr
761 self.Lambda = Lambda
761 self.Lambda = Lambda
762 self.aL = aL
762 self.aL = aL
763 self.tauW = tauW
763 self.tauW = tauW
764 self.ThetaT = ThetaT
764 self.ThetaT = ThetaT
765 self.ThetaR = ThetaR
765 self.ThetaR = ThetaR
766 self.GSys = 10**(36.63/10) # Ganancia de los LNA 36.63 dB
766 self.GSys = 10**(36.63/10) # Ganancia de los LNA 36.63 dB
767 self.lt = 10**(1.67/10) # Perdida en cables Tx 1.67 dB
767 self.lt = 10**(1.67/10) # Perdida en cables Tx 1.67 dB
768 self.lr = 10**(5.73/10) # Perdida en cables Rx 5.73 dB
768 self.lr = 10**(5.73/10) # Perdida en cables Rx 5.73 dB
769
769
770 Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
770 Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
771 Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * tauW * numpy.pi * ThetaT * ThetaR)
771 Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * tauW * numpy.pi * ThetaT * ThetaR)
772 RadarConstant = 10e-26 * Numerator / Denominator #
772 RadarConstant = 10e-26 * Numerator / Denominator #
773 ExpConstant = 10**(40/10) #Constante Experimental
773 ExpConstant = 10**(40/10) #Constante Experimental
774
774
775 SignalPower = numpy.zeros([self.Num_Chn,self.Num_Bin,self.Num_Hei])
775 SignalPower = numpy.zeros([self.Num_Chn,self.Num_Bin,self.Num_Hei])
776 for i in range(self.Num_Chn):
776 for i in range(self.Num_Chn):
777 SignalPower[i,:,:] = self.spc[i,:,:] - dataOut.noise[i]
777 SignalPower[i,:,:] = self.spc[i,:,:] - dataOut.noise[i]
778 SignalPower[numpy.where(SignalPower < 0)] = 1e-20
778 SignalPower[numpy.where(SignalPower < 0)] = 1e-20
779
779
780 SPCmean = numpy.mean(SignalPower, 0)
780 SPCmean = numpy.mean(SignalPower, 0)
781 Pr = SPCmean[:,:]/dataOut.normFactor
781 Pr = SPCmean[:,:]/dataOut.normFactor
782
782
783 # Declaring auxiliary variables
783 # Declaring auxiliary variables
784 Range = dataOut.heightList*1000. #Range in m
784 Range = dataOut.heightList*1000. #Range in m
785 # replicate the heightlist to obtain a matrix [Num_Bin,Num_Hei]
785 # replicate the heightlist to obtain a matrix [Num_Bin,Num_Hei]
786 rMtrx = numpy.transpose(numpy.transpose([dataOut.heightList*1000.] * self.Num_Bin))
786 rMtrx = numpy.transpose(numpy.transpose([dataOut.heightList*1000.] * self.Num_Bin))
787 zMtrx = rMtrx+Altitude
787 zMtrx = rMtrx+Altitude
788 # replicate the VelRange to obtain a matrix [Num_Bin,Num_Hei]
788 # replicate the VelRange to obtain a matrix [Num_Bin,Num_Hei]
789 VelMtrx = numpy.transpose(numpy.tile(VelRange[:-1], (self.Num_Hei,1)))
789 VelMtrx = numpy.transpose(numpy.tile(VelRange[:-1], (self.Num_Hei,1)))
790
790
791 # height dependence to air density Foote and Du Toit (1969)
791 # height dependence to air density Foote and Du Toit (1969)
792 delv_z = 1 + 3.68e-5 * zMtrx + 1.71e-9 * zMtrx**2
792 delv_z = 1 + 3.68e-5 * zMtrx + 1.71e-9 * zMtrx**2
793 VMtrx = VelMtrx / delv_z #Normalized velocity
793 VMtrx = VelMtrx / delv_z #Normalized velocity
794 VMtrx[numpy.where(VMtrx> 9.6)] = numpy.NaN
794 VMtrx[numpy.where(VMtrx> 9.6)] = numpy.NaN
795 # Diameter is related to the fall speed of falling drops
795 # Diameter is related to the fall speed of falling drops
796 D_Vz = -1.667 * numpy.log( 0.9369 - 0.097087 * VMtrx ) # D in [mm]
796 D_Vz = -1.667 * numpy.log( 0.9369 - 0.097087 * VMtrx ) # D in [mm]
797 # Only valid for D>= 0.16 mm
797 # Only valid for D>= 0.16 mm
798 D_Vz[numpy.where(D_Vz < 0.16)] = numpy.NaN
798 D_Vz[numpy.where(D_Vz < 0.16)] = numpy.NaN
799
799
800 #Calculate Radar Reflectivity ETAn
800 #Calculate Radar Reflectivity ETAn
801 ETAn = (RadarConstant *ExpConstant) * Pr * rMtrx**2 #Reflectivity (ETA)
801 ETAn = (RadarConstant *ExpConstant) * Pr * rMtrx**2 #Reflectivity (ETA)
802 ETAd = ETAn * 6.18 * exp( -0.6 * D_Vz ) * delv_z
802 ETAd = ETAn * 6.18 * exp( -0.6 * D_Vz ) * delv_z
803 # Radar Cross Section
803 # Radar Cross Section
804 sigmaD = Km2 * (D_Vz * 1e-3 )**6 * numpy.pi**5 / Lambda**4
804 sigmaD = Km2 * (D_Vz * 1e-3 )**6 * numpy.pi**5 / Lambda**4
805 # Drop Size Distribution
805 # Drop Size Distribution
806 DSD = ETAn / sigmaD
806 DSD = ETAn / sigmaD
807 # Equivalente Reflectivy
807 # Equivalente Reflectivy
808 Ze_eqn = numpy.nansum( DSD * D_Vz**6 ,axis=0)
808 Ze_eqn = numpy.nansum( DSD * D_Vz**6 ,axis=0)
809 Ze_org = numpy.nansum(ETAn * Lambda**4, axis=0) / (1e-18*numpy.pi**5 * Km2) # [mm^6 /m^3]
809 Ze_org = numpy.nansum(ETAn * Lambda**4, axis=0) / (1e-18*numpy.pi**5 * Km2) # [mm^6 /m^3]
810 # RainFall Rate
810 # RainFall Rate
811 RR = 0.0006*numpy.pi * numpy.nansum( D_Vz**3 * DSD * VelMtrx ,0) #mm/hr
811 RR = 0.0006*numpy.pi * numpy.nansum( D_Vz**3 * DSD * VelMtrx ,0) #mm/hr
812
812
813 # Censoring the data
813 # Censoring the data
814 # Removing data with SNRth < 0dB se debe considerar el SNR por canal
814 # Removing data with SNRth < 0dB se debe considerar el SNR por canal
815 SNRth = 10**(SNRdBlimit/10) #-30dB
815 SNRth = 10**(SNRdBlimit/10) #-30dB
816 novalid = numpy.where((dataOut.data_snr[0,:] <SNRth) | (dataOut.data_snr[1,:] <SNRth) | (dataOut.data_snr[2,:] <SNRth)) # AND condition. Maybe OR condition better
816 novalid = numpy.where((dataOut.data_snr[0,:] <SNRth) | (dataOut.data_snr[1,:] <SNRth) | (dataOut.data_snr[2,:] <SNRth)) # AND condition. Maybe OR condition better
817 W = numpy.nanmean(dataOut.data_dop,0)
817 W = numpy.nanmean(dataOut.data_dop,0)
818 W[novalid] = numpy.NaN
818 W[novalid] = numpy.NaN
819 Ze_org[novalid] = numpy.NaN
819 Ze_org[novalid] = numpy.NaN
820 RR[novalid] = numpy.NaN
820 RR[novalid] = numpy.NaN
821
821
822 dataOut.data_output = RR[8]
822 dataOut.data_output = RR[8]
823 dataOut.data_param = numpy.ones([3,self.Num_Hei])
823 dataOut.data_param = numpy.ones([3,self.Num_Hei])
824 dataOut.channelList = [0,1,2]
824 dataOut.channelList = [0,1,2]
825
825
826 dataOut.data_param[0]=10*numpy.log10(Ze_org)
826 dataOut.data_param[0]=10*numpy.log10(Ze_org)
827 dataOut.data_param[1]=-W
827 dataOut.data_param[1]=-W
828 dataOut.data_param[2]=RR
828 dataOut.data_param[2]=RR
829
829
830 # print ('Leaving PrecepitationProc ... ')
830 # print ('Leaving PrecepitationProc ... ')
831 return dataOut
831 return dataOut
832
832
833 def dBZeMODE2(self, dataOut): # Processing for MIRA35C
833 def dBZeMODE2(self, dataOut): # Processing for MIRA35C
834
834
835 NPW = dataOut.NPW
835 NPW = dataOut.NPW
836 COFA = dataOut.COFA
836 COFA = dataOut.COFA
837
837
838 SNR = numpy.array([self.spc[0,:,:] / NPW[0]]) #, self.spc[1,:,:] / NPW[1]])
838 SNR = numpy.array([self.spc[0,:,:] / NPW[0]]) #, self.spc[1,:,:] / NPW[1]])
839 RadarConst = dataOut.RadarConst
839 RadarConst = dataOut.RadarConst
840 #frequency = 34.85*10**9
840 #frequency = 34.85*10**9
841
841
842 ETA = numpy.zeros(([self.Num_Chn ,self.Num_Hei]))
842 ETA = numpy.zeros(([self.Num_Chn ,self.Num_Hei]))
843 data_output = numpy.ones([self.Num_Chn , self.Num_Hei])*numpy.NaN
843 data_output = numpy.ones([self.Num_Chn , self.Num_Hei])*numpy.NaN
844
844
845 ETA = numpy.sum(SNR,1)
845 ETA = numpy.sum(SNR,1)
846
846
847 ETA = numpy.where(ETA != 0. , ETA, numpy.NaN)
847 ETA = numpy.where(ETA != 0. , ETA, numpy.NaN)
848
848
849 Ze = numpy.ones([self.Num_Chn, self.Num_Hei] )
849 Ze = numpy.ones([self.Num_Chn, self.Num_Hei] )
850
850
851 for r in range(self.Num_Hei):
851 for r in range(self.Num_Hei):
852
852
853 Ze[0,r] = ( ETA[0,r] ) * COFA[0,r][0] * RadarConst * ((r/5000.)**2)
853 Ze[0,r] = ( ETA[0,r] ) * COFA[0,r][0] * RadarConst * ((r/5000.)**2)
854 #Ze[1,r] = ( ETA[1,r] ) * COFA[1,r][0] * RadarConst * ((r/5000.)**2)
854 #Ze[1,r] = ( ETA[1,r] ) * COFA[1,r][0] * RadarConst * ((r/5000.)**2)
855
855
856 return Ze
856 return Ze
857
857
858 # def GetRadarConstant(self):
858 # def GetRadarConstant(self):
859 #
859 #
860 # """
860 # """
861 # Constants:
861 # Constants:
862 #
862 #
863 # Pt: Transmission Power dB 5kW 5000
863 # Pt: Transmission Power dB 5kW 5000
864 # Gt: Transmission Gain dB 24.7 dB 295.1209
864 # Gt: Transmission Gain dB 24.7 dB 295.1209
865 # Gr: Reception Gain dB 18.5 dB 70.7945
865 # Gr: Reception Gain dB 18.5 dB 70.7945
866 # Lambda: Wavelenght m 0.6741 m 0.6741
866 # Lambda: Wavelenght m 0.6741 m 0.6741
867 # aL: Attenuation loses dB 4dB 2.5118
867 # aL: Attenuation loses dB 4dB 2.5118
868 # tauW: Width of transmission pulse s 4us 4e-6
868 # tauW: Width of transmission pulse s 4us 4e-6
869 # ThetaT: Transmission antenna bean angle rad 0.1656317 rad 0.1656317
869 # ThetaT: Transmission antenna bean angle rad 0.1656317 rad 0.1656317
870 # ThetaR: Reception antenna beam angle rad 0.36774087 rad 0.36774087
870 # ThetaR: Reception antenna beam angle rad 0.36774087 rad 0.36774087
871 #
871 #
872 # """
872 # """
873 #
873 #
874 # Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
874 # Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
875 # Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * TauW * numpy.pi * ThetaT * TheraR)
875 # Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * TauW * numpy.pi * ThetaT * TheraR)
876 # RadarConstant = Numerator / Denominator
876 # RadarConstant = Numerator / Denominator
877 #
877 #
878 # return RadarConstant
878 # return RadarConstant
879
879
880
880
881
881
882 class FullSpectralAnalysis(Operation):
882 class FullSpectralAnalysis(Operation):
883
883
884 """
884 """
885 Function that implements Full Spectral Analysis technique.
885 Function that implements Full Spectral Analysis technique.
886
886
887 Input:
887 Input:
888 self.dataOut.data_pre : SelfSpectra and CrossSpectra data
888 self.dataOut.data_pre : SelfSpectra and CrossSpectra data
889 self.dataOut.groupList : Pairlist of channels
889 self.dataOut.groupList : Pairlist of channels
890 self.dataOut.ChanDist : Physical distance between receivers
890 self.dataOut.ChanDist : Physical distance between receivers
891
891
892
892
893 Output:
893 Output:
894
894
895 self.dataOut.data_output : Zonal wind, Meridional wind, and Vertical wind
895 self.dataOut.data_output : Zonal wind, Meridional wind, and Vertical wind
896
896
897
897
898 Parameters affected: Winds, height range, SNR
898 Parameters affected: Winds, height range, SNR
899
899
900 """
900 """
901 def run(self, dataOut, Xi01=None, Xi02=None, Xi12=None, Eta01=None, Eta02=None, Eta12=None, SNRdBlimit=-30,
901 def run(self, dataOut, Xi01=None, Xi02=None, Xi12=None, Eta01=None, Eta02=None, Eta12=None, SNRdBlimit=-30,
902 minheight=None, maxheight=None, NegativeLimit=None, PositiveLimit=None):
902 minheight=None, maxheight=None, NegativeLimit=None, PositiveLimit=None):
903
903
904 spc = dataOut.data_pre[0].copy()
904 spc = dataOut.data_pre[0].copy()
905 cspc = dataOut.data_pre[1]
905 cspc = dataOut.data_pre[1]
906 nHeights = spc.shape[2]
906 nHeights = spc.shape[2]
907
907
908 # first_height = 0.75 #km (ref: data header 20170822)
908 # first_height = 0.75 #km (ref: data header 20170822)
909 # resolution_height = 0.075 #km
909 # resolution_height = 0.075 #km
910 '''
910 '''
911 finding height range. check this when radar parameters are changed!
911 finding height range. check this when radar parameters are changed!
912 '''
912 '''
913 if maxheight is not None:
913 if maxheight is not None:
914 # range_max = math.ceil((maxheight - first_height) / resolution_height) # theoretical
914 # range_max = math.ceil((maxheight - first_height) / resolution_height) # theoretical
915 range_max = math.ceil(13.26 * maxheight - 3) # empirical, works better
915 range_max = math.ceil(13.26 * maxheight - 3) # empirical, works better
916 else:
916 else:
917 range_max = nHeights
917 range_max = nHeights
918 if minheight is not None:
918 if minheight is not None:
919 # range_min = int((minheight - first_height) / resolution_height) # theoretical
919 # range_min = int((minheight - first_height) / resolution_height) # theoretical
920 range_min = int(13.26 * minheight - 5) # empirical, works better
920 range_min = int(13.26 * minheight - 5) # empirical, works better
921 if range_min < 0:
921 if range_min < 0:
922 range_min = 0
922 range_min = 0
923 else:
923 else:
924 range_min = 0
924 range_min = 0
925
925
926 pairsList = dataOut.groupList
926 pairsList = dataOut.groupList
927 if dataOut.ChanDist is not None :
927 if dataOut.ChanDist is not None :
928 ChanDist = dataOut.ChanDist
928 ChanDist = dataOut.ChanDist
929 else:
929 else:
930 ChanDist = numpy.array([[Xi01, Eta01],[Xi02,Eta02],[Xi12,Eta12]])
930 ChanDist = numpy.array([[Xi01, Eta01],[Xi02,Eta02],[Xi12,Eta12]])
931
931
932 # 4 variables: zonal, meridional, vertical, and average SNR
932 # 4 variables: zonal, meridional, vertical, and average SNR
933 data_param = numpy.zeros([4,nHeights]) * numpy.NaN
933 data_param = numpy.zeros([4,nHeights]) * numpy.NaN
934 velocityX = numpy.zeros([nHeights]) * numpy.NaN
934 velocityX = numpy.zeros([nHeights]) * numpy.NaN
935 velocityY = numpy.zeros([nHeights]) * numpy.NaN
935 velocityY = numpy.zeros([nHeights]) * numpy.NaN
936 velocityZ = numpy.zeros([nHeights]) * numpy.NaN
936 velocityZ = numpy.zeros([nHeights]) * numpy.NaN
937
937
938 dbSNR = 10*numpy.log10(numpy.average(dataOut.data_snr,0))
938 dbSNR = 10*numpy.log10(numpy.average(dataOut.data_snr,0))
939
939
940 '''***********************************************WIND ESTIMATION**************************************'''
940 '''***********************************************WIND ESTIMATION**************************************'''
941 for Height in range(nHeights):
941 for Height in range(nHeights):
942
942
943 if Height >= range_min and Height < range_max:
943 if Height >= range_min and Height < range_max:
944 # error_code will be useful in future analysis
944 # error_code will be useful in future analysis
945 [Vzon,Vmer,Vver, error_code] = self.WindEstimation(spc[:,:,Height], cspc[:,:,Height], pairsList,
945 [Vzon,Vmer,Vver, error_code] = self.WindEstimation(spc[:,:,Height], cspc[:,:,Height], pairsList,
946 ChanDist, Height, dataOut.noise, dataOut.spc_range, dbSNR[Height], SNRdBlimit, NegativeLimit, PositiveLimit,dataOut.frequency)
946 ChanDist, Height, dataOut.noise, dataOut.spc_range, dbSNR[Height], SNRdBlimit, NegativeLimit, PositiveLimit,dataOut.frequency)
947
947
948 if abs(Vzon) < 100. and abs(Vmer) < 100.:
948 if abs(Vzon) < 100. and abs(Vmer) < 100.:
949 velocityX[Height] = Vzon
949 velocityX[Height] = Vzon
950 velocityY[Height] = -Vmer
950 velocityY[Height] = -Vmer
951 velocityZ[Height] = Vver
951 velocityZ[Height] = Vver
952
952
953 # Censoring data with SNR threshold
953 # Censoring data with SNR threshold
954 dbSNR [dbSNR < SNRdBlimit] = numpy.NaN
954 dbSNR [dbSNR < SNRdBlimit] = numpy.NaN
955
955
956 data_param[0] = velocityX
956 data_param[0] = velocityX
957 data_param[1] = velocityY
957 data_param[1] = velocityY
958 data_param[2] = velocityZ
958 data_param[2] = velocityZ
959 data_param[3] = dbSNR
959 data_param[3] = dbSNR
960 dataOut.data_param = data_param
960 dataOut.data_param = data_param
961 return dataOut
961 return dataOut
962
962
963 def moving_average(self,x, N=2):
963 def moving_average(self,x, N=2):
964 """ convolution for smoothenig data. note that last N-1 values are convolution with zeroes """
964 """ convolution for smoothenig data. note that last N-1 values are convolution with zeroes """
965 return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):]
965 return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):]
966
966
967 def gaus(self,xSamples,Amp,Mu,Sigma):
967 def gaus(self,xSamples,Amp,Mu,Sigma):
968 return Amp * numpy.exp(-0.5*((xSamples - Mu)/Sigma)**2)
968 return Amp * numpy.exp(-0.5*((xSamples - Mu)/Sigma)**2)
969
969
970 def Moments(self, ySamples, xSamples):
970 def Moments(self, ySamples, xSamples):
971 Power = numpy.nanmean(ySamples) # Power, 0th Moment
971 Power = numpy.nanmean(ySamples) # Power, 0th Moment
972 yNorm = ySamples / numpy.nansum(ySamples)
972 yNorm = ySamples / numpy.nansum(ySamples)
973 RadVel = numpy.nansum(xSamples * yNorm) # Radial Velocity, 1st Moment
973 RadVel = numpy.nansum(xSamples * yNorm) # Radial Velocity, 1st Moment
974 Sigma2 = numpy.nansum(yNorm * (xSamples - RadVel)**2) # Spectral Width, 2nd Moment
974 Sigma2 = numpy.nansum(yNorm * (xSamples - RadVel)**2) # Spectral Width, 2nd Moment
975 StdDev = numpy.sqrt(numpy.abs(Sigma2)) # Desv. Estandar, Ancho espectral
975 StdDev = numpy.sqrt(numpy.abs(Sigma2)) # Desv. Estandar, Ancho espectral
976 return numpy.array([Power,RadVel,StdDev])
976 return numpy.array([Power,RadVel,StdDev])
977
977
978 def StopWindEstimation(self, error_code):
978 def StopWindEstimation(self, error_code):
979 Vzon = numpy.NaN
979 Vzon = numpy.NaN
980 Vmer = numpy.NaN
980 Vmer = numpy.NaN
981 Vver = numpy.NaN
981 Vver = numpy.NaN
982 return Vzon, Vmer, Vver, error_code
982 return Vzon, Vmer, Vver, error_code
983
983
984 def AntiAliasing(self, interval, maxstep):
984 def AntiAliasing(self, interval, maxstep):
985 """
985 """
986 function to prevent errors from aliased values when computing phaseslope
986 function to prevent errors from aliased values when computing phaseslope
987 """
987 """
988 antialiased = numpy.zeros(len(interval))
988 antialiased = numpy.zeros(len(interval))
989 copyinterval = interval.copy()
989 copyinterval = interval.copy()
990
990
991 antialiased[0] = copyinterval[0]
991 antialiased[0] = copyinterval[0]
992
992
993 for i in range(1,len(antialiased)):
993 for i in range(1,len(antialiased)):
994 step = interval[i] - interval[i-1]
994 step = interval[i] - interval[i-1]
995 if step > maxstep:
995 if step > maxstep:
996 copyinterval -= 2*numpy.pi
996 copyinterval -= 2*numpy.pi
997 antialiased[i] = copyinterval[i]
997 antialiased[i] = copyinterval[i]
998 elif step < maxstep*(-1):
998 elif step < maxstep*(-1):
999 copyinterval += 2*numpy.pi
999 copyinterval += 2*numpy.pi
1000 antialiased[i] = copyinterval[i]
1000 antialiased[i] = copyinterval[i]
1001 else:
1001 else:
1002 antialiased[i] = copyinterval[i].copy()
1002 antialiased[i] = copyinterval[i].copy()
1003
1003
1004 return antialiased
1004 return antialiased
1005
1005
1006 def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, AbbsisaRange, dbSNR, SNRlimit, NegativeLimit, PositiveLimit, radfreq):
1006 def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, AbbsisaRange, dbSNR, SNRlimit, NegativeLimit, PositiveLimit, radfreq):
1007 """
1007 """
1008 Function that Calculates Zonal, Meridional and Vertical wind velocities.
1008 Function that Calculates Zonal, Meridional and Vertical wind velocities.
1009 Initial Version by E. Bocanegra updated by J. Zibell until Nov. 2019.
1009 Initial Version by E. Bocanegra updated by J. Zibell until Nov. 2019.
1010
1010
1011 Input:
1011 Input:
1012 spc, cspc : self spectra and cross spectra data. In Briggs notation something like S_i*(S_i)_conj, (S_j)_conj respectively.
1012 spc, cspc : self spectra and cross spectra data. In Briggs notation something like S_i*(S_i)_conj, (S_j)_conj respectively.
1013 pairsList : Pairlist of channels
1013 pairsList : Pairlist of channels
1014 ChanDist : array of xi_ij and eta_ij
1014 ChanDist : array of xi_ij and eta_ij
1015 Height : height at which data is processed
1015 Height : height at which data is processed
1016 noise : noise in [channels] format for specific height
1016 noise : noise in [channels] format for specific height
1017 Abbsisarange : range of the frequencies or velocities
1017 Abbsisarange : range of the frequencies or velocities
1018 dbSNR, SNRlimit : signal to noise ratio in db, lower limit
1018 dbSNR, SNRlimit : signal to noise ratio in db, lower limit
1019
1019
1020 Output:
1020 Output:
1021 Vzon, Vmer, Vver : wind velocities
1021 Vzon, Vmer, Vver : wind velocities
1022 error_code : int that states where code is terminated
1022 error_code : int that states where code is terminated
1023
1023
1024 0 : no error detected
1024 0 : no error detected
1025 1 : Gaussian of mean spc exceeds widthlimit
1025 1 : Gaussian of mean spc exceeds widthlimit
1026 2 : no Gaussian of mean spc found
1026 2 : no Gaussian of mean spc found
1027 3 : SNR to low or velocity to high -> prec. e.g.
1027 3 : SNR to low or velocity to high -> prec. e.g.
1028 4 : at least one Gaussian of cspc exceeds widthlimit
1028 4 : at least one Gaussian of cspc exceeds widthlimit
1029 5 : zero out of three cspc Gaussian fits converged
1029 5 : zero out of three cspc Gaussian fits converged
1030 6 : phase slope fit could not be found
1030 6 : phase slope fit could not be found
1031 7 : arrays used to fit phase have different length
1031 7 : arrays used to fit phase have different length
1032 8 : frequency range is either too short (len <= 5) or very long (> 30% of cspc)
1032 8 : frequency range is either too short (len <= 5) or very long (> 30% of cspc)
1033
1033
1034 """
1034 """
1035
1035
1036 error_code = 0
1036 error_code = 0
1037
1037
1038 nChan = spc.shape[0]
1038 nChan = spc.shape[0]
1039 nProf = spc.shape[1]
1039 nProf = spc.shape[1]
1040 nPair = cspc.shape[0]
1040 nPair = cspc.shape[0]
1041
1041
1042 SPC_Samples = numpy.zeros([nChan, nProf]) # for normalized spc values for one height
1042 SPC_Samples = numpy.zeros([nChan, nProf]) # for normalized spc values for one height
1043 CSPC_Samples = numpy.zeros([nPair, nProf], dtype=numpy.complex_) # for normalized cspc values
1043 CSPC_Samples = numpy.zeros([nPair, nProf], dtype=numpy.complex_) # for normalized cspc values
1044 phase = numpy.zeros([nPair, nProf]) # phase between channels
1044 phase = numpy.zeros([nPair, nProf]) # phase between channels
1045 PhaseSlope = numpy.zeros(nPair) # slope of the phases, channelwise
1045 PhaseSlope = numpy.zeros(nPair) # slope of the phases, channelwise
1046 PhaseInter = numpy.zeros(nPair) # intercept to the slope of the phases, channelwise
1046 PhaseInter = numpy.zeros(nPair) # intercept to the slope of the phases, channelwise
1047 xFrec = AbbsisaRange[0][:-1] # frequency range
1047 xFrec = AbbsisaRange[0][:-1] # frequency range
1048 xVel = AbbsisaRange[2][:-1] # velocity range
1048 xVel = AbbsisaRange[2][:-1] # velocity range
1049 xSamples = xFrec # the frequency range is taken
1049 xSamples = xFrec # the frequency range is taken
1050 delta_x = xSamples[1] - xSamples[0] # delta_f or delta_x
1050 delta_x = xSamples[1] - xSamples[0] # delta_f or delta_x
1051
1051
1052 # only consider velocities with in NegativeLimit and PositiveLimit
1052 # only consider velocities with in NegativeLimit and PositiveLimit
1053 if (NegativeLimit is None):
1053 if (NegativeLimit is None):
1054 NegativeLimit = numpy.min(xVel)
1054 NegativeLimit = numpy.min(xVel)
1055 if (PositiveLimit is None):
1055 if (PositiveLimit is None):
1056 PositiveLimit = numpy.max(xVel)
1056 PositiveLimit = numpy.max(xVel)
1057 xvalid = numpy.where((xVel > NegativeLimit) & (xVel < PositiveLimit))
1057 xvalid = numpy.where((xVel > NegativeLimit) & (xVel < PositiveLimit))
1058 xSamples_zoom = xSamples[xvalid]
1058 xSamples_zoom = xSamples[xvalid]
1059
1059
1060 '''Getting Eij and Nij'''
1060 '''Getting Eij and Nij'''
1061 Xi01, Xi02, Xi12 = ChanDist[:,0]
1061 Xi01, Xi02, Xi12 = ChanDist[:,0]
1062 Eta01, Eta02, Eta12 = ChanDist[:,1]
1062 Eta01, Eta02, Eta12 = ChanDist[:,1]
1063
1063
1064 # spwd limit - updated by D. ScipiΓ³n 30.03.2021
1064 # spwd limit - updated by D. ScipiΓ³n 30.03.2021
1065 widthlimit = 10
1065 widthlimit = 10
1066 '''************************* SPC is normalized ********************************'''
1066 '''************************* SPC is normalized ********************************'''
1067 spc_norm = spc.copy()
1067 spc_norm = spc.copy()
1068 # For each channel
1068 # For each channel
1069 for i in range(nChan):
1069 for i in range(nChan):
1070 spc_sub = spc_norm[i,:] - noise[i] # only the signal power
1070 spc_sub = spc_norm[i,:] - noise[i] # only the signal power
1071 SPC_Samples[i] = spc_sub / (numpy.nansum(spc_sub) * delta_x)
1071 SPC_Samples[i] = spc_sub / (numpy.nansum(spc_sub) * delta_x)
1072
1072
1073 '''********************** FITTING MEAN SPC GAUSSIAN **********************'''
1073 '''********************** FITTING MEAN SPC GAUSSIAN **********************'''
1074
1074
1075 """ the gaussian of the mean: first subtract noise, then normalize. this is legal because
1075 """ the gaussian of the mean: first subtract noise, then normalize. this is legal because
1076 you only fit the curve and don't need the absolute value of height for calculation,
1076 you only fit the curve and don't need the absolute value of height for calculation,
1077 only for estimation of width. for normalization of cross spectra, you need initial,
1077 only for estimation of width. for normalization of cross spectra, you need initial,
1078 unnormalized self-spectra With noise.
1078 unnormalized self-spectra With noise.
1079
1079
1080 Technically, you don't even need to normalize the self-spectra, as you only need the
1080 Technically, you don't even need to normalize the self-spectra, as you only need the
1081 width of the peak. However, it was left this way. Note that the normalization has a flaw:
1081 width of the peak. However, it was left this way. Note that the normalization has a flaw:
1082 due to subtraction of the noise, some values are below zero. Raw "spc" values should be
1082 due to subtraction of the noise, some values are below zero. Raw "spc" values should be
1083 >= 0, as it is the modulus squared of the signals (complex * it's conjugate)
1083 >= 0, as it is the modulus squared of the signals (complex * it's conjugate)
1084 """
1084 """
1085 # initial conditions
1085 # initial conditions
1086 popt = [1e-10,0,1e-10]
1086 popt = [1e-10,0,1e-10]
1087 # Spectra average
1087 # Spectra average
1088 SPCMean = numpy.average(SPC_Samples,0)
1088 SPCMean = numpy.average(SPC_Samples,0)
1089 # Moments in frequency
1089 # Moments in frequency
1090 SPCMoments = self.Moments(SPCMean[xvalid], xSamples_zoom)
1090 SPCMoments = self.Moments(SPCMean[xvalid], xSamples_zoom)
1091
1091
1092 # Gauss Fit SPC in frequency domain
1092 # Gauss Fit SPC in frequency domain
1093 if dbSNR > SNRlimit: # only if SNR > SNRth
1093 if dbSNR > SNRlimit: # only if SNR > SNRth
1094 try:
1094 try:
1095 popt,pcov = curve_fit(self.gaus,xSamples_zoom,SPCMean[xvalid],p0=SPCMoments)
1095 popt,pcov = curve_fit(self.gaus,xSamples_zoom,SPCMean[xvalid],p0=SPCMoments)
1096 if popt[2] <= 0 or popt[2] > widthlimit: # CONDITION
1096 if popt[2] <= 0 or popt[2] > widthlimit: # CONDITION
1097 return self.StopWindEstimation(error_code = 1)
1097 return self.StopWindEstimation(error_code = 1)
1098 FitGauss = self.gaus(xSamples_zoom,*popt)
1098 FitGauss = self.gaus(xSamples_zoom,*popt)
1099 except :#RuntimeError:
1099 except :#RuntimeError:
1100 return self.StopWindEstimation(error_code = 2)
1100 return self.StopWindEstimation(error_code = 2)
1101 else:
1101 else:
1102 return self.StopWindEstimation(error_code = 3)
1102 return self.StopWindEstimation(error_code = 3)
1103
1103
1104 '''***************************** CSPC Normalization *************************
1104 '''***************************** CSPC Normalization *************************
1105 The Spc spectra are used to normalize the crossspectra. Peaks from precipitation
1105 The Spc spectra are used to normalize the crossspectra. Peaks from precipitation
1106 influence the norm which is not desired. First, a range is identified where the
1106 influence the norm which is not desired. First, a range is identified where the
1107 wind peak is estimated -> sum_wind is sum of those frequencies. Next, the area
1107 wind peak is estimated -> sum_wind is sum of those frequencies. Next, the area
1108 around it gets cut off and values replaced by mean determined by the boundary
1108 around it gets cut off and values replaced by mean determined by the boundary
1109 data -> sum_noise (spc is not normalized here, thats why the noise is important)
1109 data -> sum_noise (spc is not normalized here, thats why the noise is important)
1110
1110
1111 The sums are then added and multiplied by range/datapoints, because you need
1111 The sums are then added and multiplied by range/datapoints, because you need
1112 an integral and not a sum for normalization.
1112 an integral and not a sum for normalization.
1113
1113
1114 A norm is found according to Briggs 92.
1114 A norm is found according to Briggs 92.
1115 '''
1115 '''
1116 # for each pair
1116 # for each pair
1117 for i in range(nPair):
1117 for i in range(nPair):
1118 cspc_norm = cspc[i,:].copy()
1118 cspc_norm = cspc[i,:].copy()
1119 chan_index0 = pairsList[i][0]
1119 chan_index0 = pairsList[i][0]
1120 chan_index1 = pairsList[i][1]
1120 chan_index1 = pairsList[i][1]
1121 CSPC_Samples[i] = cspc_norm / (numpy.sqrt(numpy.nansum(spc_norm[chan_index0])*numpy.nansum(spc_norm[chan_index1])) * delta_x)
1121 CSPC_Samples[i] = cspc_norm / (numpy.sqrt(numpy.nansum(spc_norm[chan_index0])*numpy.nansum(spc_norm[chan_index1])) * delta_x)
1122 phase[i] = numpy.arctan2(CSPC_Samples[i].imag, CSPC_Samples[i].real)
1122 phase[i] = numpy.arctan2(CSPC_Samples[i].imag, CSPC_Samples[i].real)
1123
1123
1124 CSPCmoments = numpy.vstack([self.Moments(numpy.abs(CSPC_Samples[0,xvalid]), xSamples_zoom),
1124 CSPCmoments = numpy.vstack([self.Moments(numpy.abs(CSPC_Samples[0,xvalid]), xSamples_zoom),
1125 self.Moments(numpy.abs(CSPC_Samples[1,xvalid]), xSamples_zoom),
1125 self.Moments(numpy.abs(CSPC_Samples[1,xvalid]), xSamples_zoom),
1126 self.Moments(numpy.abs(CSPC_Samples[2,xvalid]), xSamples_zoom)])
1126 self.Moments(numpy.abs(CSPC_Samples[2,xvalid]), xSamples_zoom)])
1127
1127
1128 popt01, popt02, popt12 = [1e-10,0,1e-10], [1e-10,0,1e-10] ,[1e-10,0,1e-10]
1128 popt01, popt02, popt12 = [1e-10,0,1e-10], [1e-10,0,1e-10] ,[1e-10,0,1e-10]
1129 FitGauss01, FitGauss02, FitGauss12 = numpy.zeros(len(xSamples)), numpy.zeros(len(xSamples)), numpy.zeros(len(xSamples))
1129 FitGauss01, FitGauss02, FitGauss12 = numpy.zeros(len(xSamples)), numpy.zeros(len(xSamples)), numpy.zeros(len(xSamples))
1130
1130
1131 '''*******************************FIT GAUSS CSPC************************************'''
1131 '''*******************************FIT GAUSS CSPC************************************'''
1132 try:
1132 try:
1133 popt01,pcov = curve_fit(self.gaus,xSamples_zoom,numpy.abs(CSPC_Samples[0][xvalid]),p0=CSPCmoments[0])
1133 popt01,pcov = curve_fit(self.gaus,xSamples_zoom,numpy.abs(CSPC_Samples[0][xvalid]),p0=CSPCmoments[0])
1134 if popt01[2] > widthlimit: # CONDITION
1134 if popt01[2] > widthlimit: # CONDITION
1135 return self.StopWindEstimation(error_code = 4)
1135 return self.StopWindEstimation(error_code = 4)
1136 popt02,pcov = curve_fit(self.gaus,xSamples_zoom,numpy.abs(CSPC_Samples[1][xvalid]),p0=CSPCmoments[1])
1136 popt02,pcov = curve_fit(self.gaus,xSamples_zoom,numpy.abs(CSPC_Samples[1][xvalid]),p0=CSPCmoments[1])
1137 if popt02[2] > widthlimit: # CONDITION
1137 if popt02[2] > widthlimit: # CONDITION
1138 return self.StopWindEstimation(error_code = 4)
1138 return self.StopWindEstimation(error_code = 4)
1139 popt12,pcov = curve_fit(self.gaus,xSamples_zoom,numpy.abs(CSPC_Samples[2][xvalid]),p0=CSPCmoments[2])
1139 popt12,pcov = curve_fit(self.gaus,xSamples_zoom,numpy.abs(CSPC_Samples[2][xvalid]),p0=CSPCmoments[2])
1140 if popt12[2] > widthlimit: # CONDITION
1140 if popt12[2] > widthlimit: # CONDITION
1141 return self.StopWindEstimation(error_code = 4)
1141 return self.StopWindEstimation(error_code = 4)
1142
1142
1143 FitGauss01 = self.gaus(xSamples_zoom, *popt01)
1143 FitGauss01 = self.gaus(xSamples_zoom, *popt01)
1144 FitGauss02 = self.gaus(xSamples_zoom, *popt02)
1144 FitGauss02 = self.gaus(xSamples_zoom, *popt02)
1145 FitGauss12 = self.gaus(xSamples_zoom, *popt12)
1145 FitGauss12 = self.gaus(xSamples_zoom, *popt12)
1146 except:
1146 except:
1147 return self.StopWindEstimation(error_code = 5)
1147 return self.StopWindEstimation(error_code = 5)
1148
1148
1149
1149
1150 '''************* Getting Fij ***************'''
1150 '''************* Getting Fij ***************'''
1151 # x-axis point of the gaussian where the center is located from GaussFit of spectra
1151 # x-axis point of the gaussian where the center is located from GaussFit of spectra
1152 GaussCenter = popt[1]
1152 GaussCenter = popt[1]
1153 ClosestCenter = xSamples_zoom[numpy.abs(xSamples_zoom-GaussCenter).argmin()]
1153 ClosestCenter = xSamples_zoom[numpy.abs(xSamples_zoom-GaussCenter).argmin()]
1154 PointGauCenter = numpy.where(xSamples_zoom==ClosestCenter)[0][0]
1154 PointGauCenter = numpy.where(xSamples_zoom==ClosestCenter)[0][0]
1155
1155
1156 # Point where e^-1 is located in the gaussian
1156 # Point where e^-1 is located in the gaussian
1157 PeMinus1 = numpy.max(FitGauss) * numpy.exp(-1)
1157 PeMinus1 = numpy.max(FitGauss) * numpy.exp(-1)
1158 FijClosest = FitGauss[numpy.abs(FitGauss-PeMinus1).argmin()] # The closest point to"Peminus1" in "FitGauss"
1158 FijClosest = FitGauss[numpy.abs(FitGauss-PeMinus1).argmin()] # The closest point to"Peminus1" in "FitGauss"
1159 PointFij = numpy.where(FitGauss==FijClosest)[0][0]
1159 PointFij = numpy.where(FitGauss==FijClosest)[0][0]
1160 Fij = numpy.abs(xSamples_zoom[PointFij] - xSamples_zoom[PointGauCenter])
1160 Fij = numpy.abs(xSamples_zoom[PointFij] - xSamples_zoom[PointGauCenter])
1161
1161
1162 '''********** Taking frequency ranges from mean SPCs **********'''
1162 '''********** Taking frequency ranges from mean SPCs **********'''
1163 GauWidth = popt[2] * 3/2 # Bandwidth of Gau01
1163 GauWidth = popt[2] * 3/2 # Bandwidth of Gau01
1164 Range = numpy.empty(2)
1164 Range = numpy.empty(2)
1165 Range[0] = GaussCenter - GauWidth
1165 Range[0] = GaussCenter - GauWidth
1166 Range[1] = GaussCenter + GauWidth
1166 Range[1] = GaussCenter + GauWidth
1167 # Point in x-axis where the bandwidth is located (min:max)
1167 # Point in x-axis where the bandwidth is located (min:max)
1168 ClosRangeMin = xSamples_zoom[numpy.abs(xSamples_zoom-Range[0]).argmin()]
1168 ClosRangeMin = xSamples_zoom[numpy.abs(xSamples_zoom-Range[0]).argmin()]
1169 ClosRangeMax = xSamples_zoom[numpy.abs(xSamples_zoom-Range[1]).argmin()]
1169 ClosRangeMax = xSamples_zoom[numpy.abs(xSamples_zoom-Range[1]).argmin()]
1170 PointRangeMin = numpy.where(xSamples_zoom==ClosRangeMin)[0][0]
1170 PointRangeMin = numpy.where(xSamples_zoom==ClosRangeMin)[0][0]
1171 PointRangeMax = numpy.where(xSamples_zoom==ClosRangeMax)[0][0]
1171 PointRangeMax = numpy.where(xSamples_zoom==ClosRangeMax)[0][0]
1172 Range = numpy.array([ PointRangeMin, PointRangeMax ])
1172 Range = numpy.array([ PointRangeMin, PointRangeMax ])
1173 FrecRange = xSamples_zoom[ Range[0] : Range[1] ]
1173 FrecRange = xSamples_zoom[ Range[0] : Range[1] ]
1174
1174
1175 '''************************** Getting Phase Slope ***************************'''
1175 '''************************** Getting Phase Slope ***************************'''
1176 for i in range(nPair):
1176 for i in range(nPair):
1177 if len(FrecRange) > 5:
1177 if len(FrecRange) > 5:
1178 PhaseRange = phase[i, xvalid[0][Range[0]:Range[1]]].copy()
1178 PhaseRange = phase[i, xvalid[0][Range[0]:Range[1]]].copy()
1179 mask = ~numpy.isnan(FrecRange) & ~numpy.isnan(PhaseRange)
1179 mask = ~numpy.isnan(FrecRange) & ~numpy.isnan(PhaseRange)
1180 if len(FrecRange) == len(PhaseRange):
1180 if len(FrecRange) == len(PhaseRange):
1181 try:
1181 try:
1182 slope, intercept, _, _, _ = stats.linregress(FrecRange[mask], self.AntiAliasing(PhaseRange[mask], 4.5))
1182 slope, intercept, _, _, _ = stats.linregress(FrecRange[mask], self.AntiAliasing(PhaseRange[mask], 4.5))
1183 PhaseSlope[i] = slope
1183 PhaseSlope[i] = slope
1184 PhaseInter[i] = intercept
1184 PhaseInter[i] = intercept
1185 except:
1185 except:
1186 return self.StopWindEstimation(error_code = 6)
1186 return self.StopWindEstimation(error_code = 6)
1187 else:
1187 else:
1188 return self.StopWindEstimation(error_code = 7)
1188 return self.StopWindEstimation(error_code = 7)
1189 else:
1189 else:
1190 return self.StopWindEstimation(error_code = 8)
1190 return self.StopWindEstimation(error_code = 8)
1191
1191
1192 '''*** Constants A-H correspond to the convention as in Briggs and Vincent 1992 ***'''
1192 '''*** Constants A-H correspond to the convention as in Briggs and Vincent 1992 ***'''
1193
1193
1194 '''Getting constant C'''
1194 '''Getting constant C'''
1195 cC=(Fij*numpy.pi)**2
1195 cC=(Fij*numpy.pi)**2
1196
1196
1197 '''****** Getting constants F and G ******'''
1197 '''****** Getting constants F and G ******'''
1198 MijEijNij = numpy.array([[Xi02,Eta02], [Xi12,Eta12]])
1198 MijEijNij = numpy.array([[Xi02,Eta02], [Xi12,Eta12]])
1199 # MijEijNij = numpy.array([[Xi01,Eta01], [Xi02,Eta02], [Xi12,Eta12]])
1199 # MijEijNij = numpy.array([[Xi01,Eta01], [Xi02,Eta02], [Xi12,Eta12]])
1200 # MijResult0 = (-PhaseSlope[0] * cC) / (2*numpy.pi)
1200 # MijResult0 = (-PhaseSlope[0] * cC) / (2*numpy.pi)
1201 MijResult1 = (-PhaseSlope[1] * cC) / (2*numpy.pi)
1201 MijResult1 = (-PhaseSlope[1] * cC) / (2*numpy.pi)
1202 MijResult2 = (-PhaseSlope[2] * cC) / (2*numpy.pi)
1202 MijResult2 = (-PhaseSlope[2] * cC) / (2*numpy.pi)
1203 # MijResults = numpy.array([MijResult0, MijResult1, MijResult2])
1203 # MijResults = numpy.array([MijResult0, MijResult1, MijResult2])
1204 MijResults = numpy.array([MijResult1, MijResult2])
1204 MijResults = numpy.array([MijResult1, MijResult2])
1205 (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults)
1205 (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults)
1206
1206
1207 '''****** Getting constants A, B and H ******'''
1207 '''****** Getting constants A, B and H ******'''
1208 W01 = numpy.nanmax( FitGauss01 )
1208 W01 = numpy.nanmax( FitGauss01 )
1209 W02 = numpy.nanmax( FitGauss02 )
1209 W02 = numpy.nanmax( FitGauss02 )
1210 W12 = numpy.nanmax( FitGauss12 )
1210 W12 = numpy.nanmax( FitGauss12 )
1211
1211
1212 WijResult01 = ((cF * Xi01 + cG * Eta01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi / cC))
1212 WijResult01 = ((cF * Xi01 + cG * Eta01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi / cC))
1213 WijResult02 = ((cF * Xi02 + cG * Eta02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi / cC))
1213 WijResult02 = ((cF * Xi02 + cG * Eta02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi / cC))
1214 WijResult12 = ((cF * Xi12 + cG * Eta12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi / cC))
1214 WijResult12 = ((cF * Xi12 + cG * Eta12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi / cC))
1215 WijResults = numpy.array([WijResult01, WijResult02, WijResult12])
1215 WijResults = numpy.array([WijResult01, WijResult02, WijResult12])
1216
1216
1217 WijEijNij = numpy.array([ [Xi01**2, Eta01**2, 2*Xi01*Eta01] , [Xi02**2, Eta02**2, 2*Xi02*Eta02] , [Xi12**2, Eta12**2, 2*Xi12*Eta12] ])
1217 WijEijNij = numpy.array([ [Xi01**2, Eta01**2, 2*Xi01*Eta01] , [Xi02**2, Eta02**2, 2*Xi02*Eta02] , [Xi12**2, Eta12**2, 2*Xi12*Eta12] ])
1218 (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults)
1218 (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults)
1219
1219
1220 VxVy = numpy.array([[cA,cH],[cH,cB]])
1220 VxVy = numpy.array([[cA,cH],[cH,cB]])
1221 VxVyResults = numpy.array([-cF,-cG])
1221 VxVyResults = numpy.array([-cF,-cG])
1222 (Vmer,Vzon) = numpy.linalg.solve(VxVy, VxVyResults)
1222 (Vmer,Vzon) = numpy.linalg.solve(VxVy, VxVyResults)
1223 Vver = -SPCMoments[1]*SPEED_OF_LIGHT/(2*radfreq)
1223 Vver = -SPCMoments[1]*SPEED_OF_LIGHT/(2*radfreq)
1224 error_code = 0
1224 error_code = 0
1225
1225
1226 return Vzon, Vmer, Vver, error_code
1226 return Vzon, Vmer, Vver, error_code
1227
1227
1228 class SpectralMoments(Operation):
1228 class SpectralMoments(Operation):
1229
1229
1230 '''
1230 '''
1231 Function SpectralMoments()
1231 Function SpectralMoments()
1232
1232
1233 Calculates moments (power, mean, standard deviation) and SNR of the signal
1233 Calculates moments (power, mean, standard deviation) and SNR of the signal
1234
1234
1235 Type of dataIn: Spectra
1235 Type of dataIn: Spectra
1236
1236
1237 Configuration Parameters:
1237 Configuration Parameters:
1238
1238
1239 dirCosx : Cosine director in X axis
1239 dirCosx : Cosine director in X axis
1240 dirCosy : Cosine director in Y axis
1240 dirCosy : Cosine director in Y axis
1241
1241
1242 elevation :
1242 elevation :
1243 azimuth :
1243 azimuth :
1244
1244
1245 Input:
1245 Input:
1246 channelList : simple channel list to select e.g. [2,3,7]
1246 channelList : simple channel list to select e.g. [2,3,7]
1247 self.dataOut.data_pre : Spectral data
1247 self.dataOut.data_pre : Spectral data
1248 self.dataOut.abscissaList : List of frequencies
1248 self.dataOut.abscissaList : List of frequencies
1249 self.dataOut.noise : Noise level per channel
1249 self.dataOut.noise : Noise level per channel
1250
1250
1251 Affected:
1251 Affected:
1252 self.dataOut.moments : Parameters per channel
1252 self.dataOut.moments : Parameters per channel
1253 self.dataOut.data_snr : SNR per channel
1253 self.dataOut.data_snr : SNR per channel
1254
1254
1255 '''
1255 '''
1256
1256
1257 def run(self, dataOut):
1257 def run(self, dataOut):
1258
1258
1259 data = dataOut.data_pre[0]
1259 data = dataOut.data_pre[0]
1260 absc = dataOut.abscissaList[:-1]
1260 absc = dataOut.abscissaList[:-1]
1261 noise = dataOut.noise
1261 noise = dataOut.noise
1262 nChannel = data.shape[0]
1262 nChannel = data.shape[0]
1263 data_param = numpy.zeros((nChannel, 4, data.shape[2]))
1263 data_param = numpy.zeros((nChannel, 4, data.shape[2]))
1264
1264
1265 for ind in range(nChannel):
1265 for ind in range(nChannel):
1266 data_param[ind,:,:] = self.__calculateMoments( data[ind,:,:] , absc , noise[ind] )
1266 data_param[ind,:,:] = self.__calculateMoments( data[ind,:,:] , absc , noise[ind] )
1267
1267
1268 dataOut.moments = data_param[:,1:,:]
1268 dataOut.moments = data_param[:,1:,:]
1269 dataOut.data_snr = data_param[:,0]
1269 dataOut.data_snr = data_param[:,0]
1270 dataOut.data_pow = data_param[:,1]
1270 dataOut.data_pow = data_param[:,1]
1271 dataOut.data_dop = data_param[:,2]
1271 dataOut.data_dop = data_param[:,2]
1272 dataOut.data_width = data_param[:,3]
1272 dataOut.data_width = data_param[:,3]
1273 return dataOut
1273 return dataOut
1274
1274
1275 def __calculateMoments(self, oldspec, oldfreq, n0,
1275 def __calculateMoments(self, oldspec, oldfreq, n0,
1276 nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
1276 nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
1277
1277
1278 if (nicoh is None): nicoh = 1
1278 if (nicoh is None): nicoh = 1
1279 if (graph is None): graph = 0
1279 if (graph is None): graph = 0
1280 if (smooth is None): smooth = 0
1280 if (smooth is None): smooth = 0
1281 elif (self.smooth < 3): smooth = 0
1281 elif (self.smooth < 3): smooth = 0
1282
1282
1283 if (type1 is None): type1 = 0
1283 if (type1 is None): type1 = 0
1284 if (fwindow is None): fwindow = numpy.zeros(oldfreq.size) + 1
1284 if (fwindow is None): fwindow = numpy.zeros(oldfreq.size) + 1
1285 if (snrth is None): snrth = -3
1285 if (snrth is None): snrth = -3
1286 if (dc is None): dc = 0
1286 if (dc is None): dc = 0
1287 if (aliasing is None): aliasing = 0
1287 if (aliasing is None): aliasing = 0
1288 if (oldfd is None): oldfd = 0
1288 if (oldfd is None): oldfd = 0
1289 if (wwauto is None): wwauto = 0
1289 if (wwauto is None): wwauto = 0
1290
1290
1291 if (n0 < 1.e-20): n0 = 1.e-20
1291 if (n0 < 1.e-20): n0 = 1.e-20
1292
1292
1293 freq = oldfreq
1293 freq = oldfreq
1294 vec_power = numpy.zeros(oldspec.shape[1])
1294 vec_power = numpy.zeros(oldspec.shape[1])
1295 vec_fd = numpy.zeros(oldspec.shape[1])
1295 vec_fd = numpy.zeros(oldspec.shape[1])
1296 vec_w = numpy.zeros(oldspec.shape[1])
1296 vec_w = numpy.zeros(oldspec.shape[1])
1297 vec_snr = numpy.zeros(oldspec.shape[1])
1297 vec_snr = numpy.zeros(oldspec.shape[1])
1298
1298
1299 # oldspec = numpy.ma.masked_invalid(oldspec)
1299 # oldspec = numpy.ma.masked_invalid(oldspec)
1300 for ind in range(oldspec.shape[1]):
1300 for ind in range(oldspec.shape[1]):
1301
1301
1302 spec = oldspec[:,ind]
1302 spec = oldspec[:,ind]
1303 aux = spec*fwindow
1303 aux = spec*fwindow
1304 max_spec = aux.max()
1304 max_spec = aux.max()
1305 m = aux.tolist().index(max_spec)
1305 m = aux.tolist().index(max_spec)
1306
1306
1307 # Smooth
1307 # Smooth
1308 if (smooth == 0):
1308 if (smooth == 0):
1309 spec2 = spec
1309 spec2 = spec
1310 else:
1310 else:
1311 spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
1311 spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
1312
1312
1313 # Moments Estimation
1313 # Moments Estimation
1314 bb = spec2[numpy.arange(m,spec2.size)]
1314 bb = spec2[numpy.arange(m,spec2.size)]
1315 bb = (bb<n0).nonzero()
1315 bb = (bb<n0).nonzero()
1316 bb = bb[0]
1316 bb = bb[0]
1317
1317
1318 ss = spec2[numpy.arange(0,m + 1)]
1318 ss = spec2[numpy.arange(0,m + 1)]
1319 ss = (ss<n0).nonzero()
1319 ss = (ss<n0).nonzero()
1320 ss = ss[0]
1320 ss = ss[0]
1321
1321
1322 if (bb.size == 0):
1322 if (bb.size == 0):
1323 bb0 = spec.size - 1 - m
1323 bb0 = spec.size - 1 - m
1324 else:
1324 else:
1325 bb0 = bb[0] - 1
1325 bb0 = bb[0] - 1
1326 if (bb0 < 0):
1326 if (bb0 < 0):
1327 bb0 = 0
1327 bb0 = 0
1328
1328
1329 if (ss.size == 0):
1329 if (ss.size == 0):
1330 ss1 = 1
1330 ss1 = 1
1331 else:
1331 else:
1332 ss1 = max(ss) + 1
1332 ss1 = max(ss) + 1
1333
1333
1334 if (ss1 > m):
1334 if (ss1 > m):
1335 ss1 = m
1335 ss1 = m
1336
1336
1337 #valid = numpy.arange(int(m + bb0 - ss1 + 1)) + ss1
1337 #valid = numpy.arange(int(m + bb0 - ss1 + 1)) + ss1
1338 valid = numpy.arange(1,oldspec.shape[0])# valid perfil completo igual pulsepair
1338 valid = numpy.arange(1,oldspec.shape[0])# valid perfil completo igual pulsepair
1339 signal_power = ((spec2[valid] - n0) * fwindow[valid]).mean() # D. ScipiΓ³n added with correct definition
1339 signal_power = ((spec2[valid] - n0) * fwindow[valid]).mean() # D. ScipiΓ³n added with correct definition
1340 total_power = (spec2[valid] * fwindow[valid]).mean() # D. ScipiΓ³n added with correct definition
1340 total_power = (spec2[valid] * fwindow[valid]).mean() # D. ScipiΓ³n added with correct definition
1341 power = ((spec2[valid] - n0) * fwindow[valid]).sum()
1341 power = ((spec2[valid] - n0) * fwindow[valid]).sum()
1342 fd = ((spec2[valid]- n0)*freq[valid] * fwindow[valid]).sum() / power
1342 fd = ((spec2[valid]- n0)*freq[valid] * fwindow[valid]).sum() / power
1343 w = numpy.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum() / power)
1343 w = numpy.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum() / power)
1344 snr = (spec2.mean()-n0)/n0
1344 snr = (spec2.mean()-n0)/n0
1345 if (snr < 1.e-20) :
1345 if (snr < 1.e-20) :
1346 snr = 1.e-20
1346 snr = 1.e-20
1347
1347
1348 # vec_power[ind] = power #D. ScipiΓ³n replaced with the line below
1348 # vec_power[ind] = power #D. ScipiΓ³n replaced with the line below
1349 vec_power[ind] = total_power
1349 vec_power[ind] = total_power
1350 vec_fd[ind] = fd
1350 vec_fd[ind] = fd
1351 vec_w[ind] = w
1351 vec_w[ind] = w
1352 vec_snr[ind] = snr
1352 vec_snr[ind] = snr
1353
1353
1354 return numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
1354 return numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
1355
1355
1356 #------------------ Get SA Parameters --------------------------
1356 #------------------ Get SA Parameters --------------------------
1357
1357
1358 def GetSAParameters(self):
1358 def GetSAParameters(self):
1359 #SA en frecuencia
1359 #SA en frecuencia
1360 pairslist = self.dataOut.groupList
1360 pairslist = self.dataOut.groupList
1361 num_pairs = len(pairslist)
1361 num_pairs = len(pairslist)
1362
1362
1363 vel = self.dataOut.abscissaList
1363 vel = self.dataOut.abscissaList
1364 spectra = self.dataOut.data_pre
1364 spectra = self.dataOut.data_pre
1365 cspectra = self.dataIn.data_cspc
1365 cspectra = self.dataIn.data_cspc
1366 delta_v = vel[1] - vel[0]
1366 delta_v = vel[1] - vel[0]
1367
1367
1368 #Calculating the power spectrum
1368 #Calculating the power spectrum
1369 spc_pow = numpy.sum(spectra, 3)*delta_v
1369 spc_pow = numpy.sum(spectra, 3)*delta_v
1370 #Normalizing Spectra
1370 #Normalizing Spectra
1371 norm_spectra = spectra/spc_pow
1371 norm_spectra = spectra/spc_pow
1372 #Calculating the norm_spectra at peak
1372 #Calculating the norm_spectra at peak
1373 max_spectra = numpy.max(norm_spectra, 3)
1373 max_spectra = numpy.max(norm_spectra, 3)
1374
1374
1375 #Normalizing Cross Spectra
1375 #Normalizing Cross Spectra
1376 norm_cspectra = numpy.zeros(cspectra.shape)
1376 norm_cspectra = numpy.zeros(cspectra.shape)
1377
1377
1378 for i in range(num_chan):
1378 for i in range(num_chan):
1379 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
1379 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
1380
1380
1381 max_cspectra = numpy.max(norm_cspectra,2)
1381 max_cspectra = numpy.max(norm_cspectra,2)
1382 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
1382 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
1383
1383
1384 for i in range(num_pairs):
1384 for i in range(num_pairs):
1385 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
1385 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
1386 #------------------- Get Lags ----------------------------------
1386 #------------------- Get Lags ----------------------------------
1387
1387
1388 class SALags(Operation):
1388 class SALags(Operation):
1389 '''
1389 '''
1390 Function GetMoments()
1390 Function GetMoments()
1391
1391
1392 Input:
1392 Input:
1393 self.dataOut.data_pre
1393 self.dataOut.data_pre
1394 self.dataOut.abscissaList
1394 self.dataOut.abscissaList
1395 self.dataOut.noise
1395 self.dataOut.noise
1396 self.dataOut.normFactor
1396 self.dataOut.normFactor
1397 self.dataOut.data_snr
1397 self.dataOut.data_snr
1398 self.dataOut.groupList
1398 self.dataOut.groupList
1399 self.dataOut.nChannels
1399 self.dataOut.nChannels
1400
1400
1401 Affected:
1401 Affected:
1402 self.dataOut.data_param
1402 self.dataOut.data_param
1403
1403
1404 '''
1404 '''
1405 def run(self, dataOut):
1405 def run(self, dataOut):
1406 data_acf = dataOut.data_pre[0]
1406 data_acf = dataOut.data_pre[0]
1407 data_ccf = dataOut.data_pre[1]
1407 data_ccf = dataOut.data_pre[1]
1408 normFactor_acf = dataOut.normFactor[0]
1408 normFactor_acf = dataOut.normFactor[0]
1409 normFactor_ccf = dataOut.normFactor[1]
1409 normFactor_ccf = dataOut.normFactor[1]
1410 pairs_acf = dataOut.groupList[0]
1410 pairs_acf = dataOut.groupList[0]
1411 pairs_ccf = dataOut.groupList[1]
1411 pairs_ccf = dataOut.groupList[1]
1412
1412
1413 nHeights = dataOut.nHeights
1413 nHeights = dataOut.nHeights
1414 absc = dataOut.abscissaList
1414 absc = dataOut.abscissaList
1415 noise = dataOut.noise
1415 noise = dataOut.noise
1416 SNR = dataOut.data_snr
1416 SNR = dataOut.data_snr
1417 nChannels = dataOut.nChannels
1417 nChannels = dataOut.nChannels
1418 # pairsList = dataOut.groupList
1418 # pairsList = dataOut.groupList
1419 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
1419 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
1420
1420
1421 for l in range(len(pairs_acf)):
1421 for l in range(len(pairs_acf)):
1422 data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
1422 data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
1423
1423
1424 for l in range(len(pairs_ccf)):
1424 for l in range(len(pairs_ccf)):
1425 data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
1425 data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
1426
1426
1427 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
1427 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
1428 dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
1428 dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
1429 dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
1429 dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
1430 return
1430 return
1431
1431
1432 # def __getPairsAutoCorr(self, pairsList, nChannels):
1432 # def __getPairsAutoCorr(self, pairsList, nChannels):
1433 #
1433 #
1434 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1434 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1435 #
1435 #
1436 # for l in range(len(pairsList)):
1436 # for l in range(len(pairsList)):
1437 # firstChannel = pairsList[l][0]
1437 # firstChannel = pairsList[l][0]
1438 # secondChannel = pairsList[l][1]
1438 # secondChannel = pairsList[l][1]
1439 #
1439 #
1440 # #Obteniendo pares de Autocorrelacion
1440 # #Obteniendo pares de Autocorrelacion
1441 # if firstChannel == secondChannel:
1441 # if firstChannel == secondChannel:
1442 # pairsAutoCorr[firstChannel] = int(l)
1442 # pairsAutoCorr[firstChannel] = int(l)
1443 #
1443 #
1444 # pairsAutoCorr = pairsAutoCorr.astype(int)
1444 # pairsAutoCorr = pairsAutoCorr.astype(int)
1445 #
1445 #
1446 # pairsCrossCorr = range(len(pairsList))
1446 # pairsCrossCorr = range(len(pairsList))
1447 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1447 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1448 #
1448 #
1449 # return pairsAutoCorr, pairsCrossCorr
1449 # return pairsAutoCorr, pairsCrossCorr
1450
1450
1451 def __calculateTaus(self, data_acf, data_ccf, lagRange):
1451 def __calculateTaus(self, data_acf, data_ccf, lagRange):
1452
1452
1453 lag0 = data_acf.shape[1]/2
1453 lag0 = data_acf.shape[1]/2
1454 #Funcion de Autocorrelacion
1454 #Funcion de Autocorrelacion
1455 mean_acf = stats.nanmean(data_acf, axis = 0)
1455 mean_acf = stats.nanmean(data_acf, axis = 0)
1456
1456
1457 #Obtencion Indice de TauCross
1457 #Obtencion Indice de TauCross
1458 ind_ccf = data_ccf.argmax(axis = 1)
1458 ind_ccf = data_ccf.argmax(axis = 1)
1459 #Obtencion Indice de TauAuto
1459 #Obtencion Indice de TauAuto
1460 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
1460 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
1461 ccf_lag0 = data_ccf[:,lag0,:]
1461 ccf_lag0 = data_ccf[:,lag0,:]
1462
1462
1463 for i in range(ccf_lag0.shape[0]):
1463 for i in range(ccf_lag0.shape[0]):
1464 ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
1464 ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
1465
1465
1466 #Obtencion de TauCross y TauAuto
1466 #Obtencion de TauCross y TauAuto
1467 tau_ccf = lagRange[ind_ccf]
1467 tau_ccf = lagRange[ind_ccf]
1468 tau_acf = lagRange[ind_acf]
1468 tau_acf = lagRange[ind_acf]
1469
1469
1470 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
1470 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
1471
1471
1472 tau_ccf[Nan1,Nan2] = numpy.nan
1472 tau_ccf[Nan1,Nan2] = numpy.nan
1473 tau_acf[Nan1,Nan2] = numpy.nan
1473 tau_acf[Nan1,Nan2] = numpy.nan
1474 tau = numpy.vstack((tau_ccf,tau_acf))
1474 tau = numpy.vstack((tau_ccf,tau_acf))
1475
1475
1476 return tau
1476 return tau
1477
1477
1478 def __calculateLag1Phase(self, data, lagTRange):
1478 def __calculateLag1Phase(self, data, lagTRange):
1479 data1 = stats.nanmean(data, axis = 0)
1479 data1 = stats.nanmean(data, axis = 0)
1480 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
1480 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
1481
1481
1482 phase = numpy.angle(data1[lag1,:])
1482 phase = numpy.angle(data1[lag1,:])
1483
1483
1484 return phase
1484 return phase
1485
1485
1486 class SpectralFitting(Operation):
1486 class SpectralFitting(Operation):
1487 '''
1487 '''
1488 Function GetMoments()
1488 Function GetMoments()
1489
1489
1490 Input:
1490 Input:
1491 Output:
1491 Output:
1492 Variables modified:
1492 Variables modified:
1493 '''
1493 '''
1494
1494
1495 def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
1495 def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
1496
1496
1497
1497
1498 if path != None:
1498 if path != None:
1499 sys.path.append(path)
1499 sys.path.append(path)
1500 self.dataOut.library = importlib.import_module(file)
1500 self.dataOut.library = importlib.import_module(file)
1501
1501
1502 #To be inserted as a parameter
1502 #To be inserted as a parameter
1503 groupArray = numpy.array(groupList)
1503 groupArray = numpy.array(groupList)
1504 # groupArray = numpy.array([[0,1],[2,3]])
1504 # groupArray = numpy.array([[0,1],[2,3]])
1505 self.dataOut.groupList = groupArray
1505 self.dataOut.groupList = groupArray
1506
1506
1507 nGroups = groupArray.shape[0]
1507 nGroups = groupArray.shape[0]
1508 nChannels = self.dataIn.nChannels
1508 nChannels = self.dataIn.nChannels
1509 nHeights=self.dataIn.heightList.size
1509 nHeights=self.dataIn.heightList.size
1510
1510
1511 #Parameters Array
1511 #Parameters Array
1512 self.dataOut.data_param = None
1512 self.dataOut.data_param = None
1513
1513
1514 #Set constants
1514 #Set constants
1515 constants = self.dataOut.library.setConstants(self.dataIn)
1515 constants = self.dataOut.library.setConstants(self.dataIn)
1516 self.dataOut.constants = constants
1516 self.dataOut.constants = constants
1517 M = self.dataIn.normFactor
1517 M = self.dataIn.normFactor
1518 N = self.dataIn.nFFTPoints
1518 N = self.dataIn.nFFTPoints
1519 ippSeconds = self.dataIn.ippSeconds
1519 ippSeconds = self.dataIn.ippSeconds
1520 K = self.dataIn.nIncohInt
1520 K = self.dataIn.nIncohInt
1521 pairsArray = numpy.array(self.dataIn.pairsList)
1521 pairsArray = numpy.array(self.dataIn.pairsList)
1522
1522
1523 #List of possible combinations
1523 #List of possible combinations
1524 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1524 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1525 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1525 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1526
1526
1527 if getSNR:
1527 if getSNR:
1528 listChannels = groupArray.reshape((groupArray.size))
1528 listChannels = groupArray.reshape((groupArray.size))
1529 listChannels.sort()
1529 listChannels.sort()
1530 noise = self.dataIn.getNoise()
1530 noise = self.dataIn.getNoise()
1531 self.dataOut.data_snr = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1531 self.dataOut.data_snr = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1532
1532
1533 for i in range(nGroups):
1533 for i in range(nGroups):
1534 coord = groupArray[i,:]
1534 coord = groupArray[i,:]
1535
1535
1536 #Input data array
1536 #Input data array
1537 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1537 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1538 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1538 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1539
1539
1540 #Cross Spectra data array for Covariance Matrixes
1540 #Cross Spectra data array for Covariance Matrixes
1541 ind = 0
1541 ind = 0
1542 for pairs in listComb:
1542 for pairs in listComb:
1543 pairsSel = numpy.array([coord[x],coord[y]])
1543 pairsSel = numpy.array([coord[x],coord[y]])
1544 indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
1544 indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
1545 ind += 1
1545 ind += 1
1546 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1546 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1547 dataCross = dataCross**2/K
1547 dataCross = dataCross**2/K
1548
1548
1549 for h in range(nHeights):
1549 for h in range(nHeights):
1550
1550
1551 #Input
1551 #Input
1552 d = data[:,h]
1552 d = data[:,h]
1553
1553
1554 #Covariance Matrix
1554 #Covariance Matrix
1555 D = numpy.diag(d**2/K)
1555 D = numpy.diag(d**2/K)
1556 ind = 0
1556 ind = 0
1557 for pairs in listComb:
1557 for pairs in listComb:
1558 #Coordinates in Covariance Matrix
1558 #Coordinates in Covariance Matrix
1559 x = pairs[0]
1559 x = pairs[0]
1560 y = pairs[1]
1560 y = pairs[1]
1561 #Channel Index
1561 #Channel Index
1562 S12 = dataCross[ind,:,h]
1562 S12 = dataCross[ind,:,h]
1563 D12 = numpy.diag(S12)
1563 D12 = numpy.diag(S12)
1564 #Completing Covariance Matrix with Cross Spectras
1564 #Completing Covariance Matrix with Cross Spectras
1565 D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
1565 D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
1566 D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
1566 D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
1567 ind += 1
1567 ind += 1
1568 Dinv=numpy.linalg.inv(D)
1568 Dinv=numpy.linalg.inv(D)
1569 L=numpy.linalg.cholesky(Dinv)
1569 L=numpy.linalg.cholesky(Dinv)
1570 LT=L.T
1570 LT=L.T
1571
1571
1572 dp = numpy.dot(LT,d)
1572 dp = numpy.dot(LT,d)
1573
1573
1574 #Initial values
1574 #Initial values
1575 data_spc = self.dataIn.data_spc[coord,:,h]
1575 data_spc = self.dataIn.data_spc[coord,:,h]
1576
1576
1577 if (h>0)and(error1[3]<5):
1577 if (h>0)and(error1[3]<5):
1578 p0 = self.dataOut.data_param[i,:,h-1]
1578 p0 = self.dataOut.data_param[i,:,h-1]
1579 else:
1579 else:
1580 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1580 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1581
1581
1582 try:
1582 try:
1583 #Least Squares
1583 #Least Squares
1584 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
1584 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
1585 # minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
1585 # minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
1586 #Chi square error
1586 #Chi square error
1587 error0 = numpy.sum(infodict['fvec']**2)/(2*N)
1587 error0 = numpy.sum(infodict['fvec']**2)/(2*N)
1588 #Error with Jacobian
1588 #Error with Jacobian
1589 error1 = self.dataOut.library.errorFunction(minp,constants,LT)
1589 error1 = self.dataOut.library.errorFunction(minp,constants,LT)
1590 except:
1590 except:
1591 minp = p0*numpy.nan
1591 minp = p0*numpy.nan
1592 error0 = numpy.nan
1592 error0 = numpy.nan
1593 error1 = p0*numpy.nan
1593 error1 = p0*numpy.nan
1594
1594
1595 #Save
1595 #Save
1596 if self.dataOut.data_param is None:
1596 if self.dataOut.data_param is None:
1597 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1597 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1598 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1598 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1599
1599
1600 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1600 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1601 self.dataOut.data_param[i,:,h] = minp
1601 self.dataOut.data_param[i,:,h] = minp
1602 return
1602 return
1603
1603
1604 def __residFunction(self, p, dp, LT, constants):
1604 def __residFunction(self, p, dp, LT, constants):
1605
1605
1606 fm = self.dataOut.library.modelFunction(p, constants)
1606 fm = self.dataOut.library.modelFunction(p, constants)
1607 fmp=numpy.dot(LT,fm)
1607 fmp=numpy.dot(LT,fm)
1608
1608
1609 return dp-fmp
1609 return dp-fmp
1610
1610
1611 def __getSNR(self, z, noise):
1611 def __getSNR(self, z, noise):
1612
1612
1613 avg = numpy.average(z, axis=1)
1613 avg = numpy.average(z, axis=1)
1614 SNR = (avg.T-noise)/noise
1614 SNR = (avg.T-noise)/noise
1615 SNR = SNR.T
1615 SNR = SNR.T
1616 return SNR
1616 return SNR
1617
1617
1618 def __chisq(p,chindex,hindex):
1618 def __chisq(p,chindex,hindex):
1619 #similar to Resid but calculates CHI**2
1619 #similar to Resid but calculates CHI**2
1620 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
1620 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
1621 dp=numpy.dot(LT,d)
1621 dp=numpy.dot(LT,d)
1622 fmp=numpy.dot(LT,fm)
1622 fmp=numpy.dot(LT,fm)
1623 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1623 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1624 return chisq
1624 return chisq
1625
1625
1626 class WindProfiler(Operation):
1626 class WindProfiler(Operation):
1627
1627
1628 __isConfig = False
1628 __isConfig = False
1629
1629
1630 __initime = None
1630 __initime = None
1631 __lastdatatime = None
1631 __lastdatatime = None
1632 __integrationtime = None
1632 __integrationtime = None
1633
1633
1634 __buffer = None
1634 __buffer = None
1635
1635
1636 __dataReady = False
1636 __dataReady = False
1637
1637
1638 __firstdata = None
1638 __firstdata = None
1639
1639
1640 n = None
1640 n = None
1641
1641
1642 def __init__(self):
1642 def __init__(self):
1643 Operation.__init__(self)
1643 Operation.__init__(self)
1644
1644
1645 def __calculateCosDir(self, elev, azim):
1645 def __calculateCosDir(self, elev, azim):
1646 zen = (90 - elev)*numpy.pi/180
1646 zen = (90 - elev)*numpy.pi/180
1647 azim = azim*numpy.pi/180
1647 azim = azim*numpy.pi/180
1648 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1648 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1649 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1649 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1650
1650
1651 signX = numpy.sign(numpy.cos(azim))
1651 signX = numpy.sign(numpy.cos(azim))
1652 signY = numpy.sign(numpy.sin(azim))
1652 signY = numpy.sign(numpy.sin(azim))
1653
1653
1654 cosDirX = numpy.copysign(cosDirX, signX)
1654 cosDirX = numpy.copysign(cosDirX, signX)
1655 cosDirY = numpy.copysign(cosDirY, signY)
1655 cosDirY = numpy.copysign(cosDirY, signY)
1656 return cosDirX, cosDirY
1656 return cosDirX, cosDirY
1657
1657
1658 def __calculateAngles(self, theta_x, theta_y, azimuth):
1658 def __calculateAngles(self, theta_x, theta_y, azimuth):
1659
1659
1660 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1660 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1661 zenith_arr = numpy.arccos(dir_cosw)
1661 zenith_arr = numpy.arccos(dir_cosw)
1662 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1662 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1663
1663
1664 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1664 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1665 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1665 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1666
1666
1667 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1667 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1668
1668
1669 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1669 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1670
1670
1671 #
1671 #
1672 if horOnly:
1672 if horOnly:
1673 A = numpy.c_[dir_cosu,dir_cosv]
1673 A = numpy.c_[dir_cosu,dir_cosv]
1674 else:
1674 else:
1675 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
1675 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
1676 A = numpy.asmatrix(A)
1676 A = numpy.asmatrix(A)
1677 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
1677 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
1678
1678
1679 return A1
1679 return A1
1680
1680
1681 def __correctValues(self, heiRang, phi, velRadial, SNR):
1681 def __correctValues(self, heiRang, phi, velRadial, SNR):
1682 listPhi = phi.tolist()
1682 listPhi = phi.tolist()
1683 maxid = listPhi.index(max(listPhi))
1683 maxid = listPhi.index(max(listPhi))
1684 minid = listPhi.index(min(listPhi))
1684 minid = listPhi.index(min(listPhi))
1685
1685
1686 rango = list(range(len(phi)))
1686 rango = list(range(len(phi)))
1687 # rango = numpy.delete(rango,maxid)
1687 # rango = numpy.delete(rango,maxid)
1688
1688
1689 heiRang1 = heiRang*math.cos(phi[maxid])
1689 heiRang1 = heiRang*math.cos(phi[maxid])
1690 heiRangAux = heiRang*math.cos(phi[minid])
1690 heiRangAux = heiRang*math.cos(phi[minid])
1691 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1691 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1692 heiRang1 = numpy.delete(heiRang1,indOut)
1692 heiRang1 = numpy.delete(heiRang1,indOut)
1693
1693
1694 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1694 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1695 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1695 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1696
1696
1697 for i in rango:
1697 for i in rango:
1698 x = heiRang*math.cos(phi[i])
1698 x = heiRang*math.cos(phi[i])
1699 y1 = velRadial[i,:]
1699 y1 = velRadial[i,:]
1700 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1700 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1701
1701
1702 x1 = heiRang1
1702 x1 = heiRang1
1703 y11 = f1(x1)
1703 y11 = f1(x1)
1704
1704
1705 y2 = SNR[i,:]
1705 y2 = SNR[i,:]
1706 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1706 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1707 y21 = f2(x1)
1707 y21 = f2(x1)
1708
1708
1709 velRadial1[i,:] = y11
1709 velRadial1[i,:] = y11
1710 SNR1[i,:] = y21
1710 SNR1[i,:] = y21
1711
1711
1712 return heiRang1, velRadial1, SNR1
1712 return heiRang1, velRadial1, SNR1
1713
1713
1714 def __calculateVelUVW(self, A, velRadial):
1714 def __calculateVelUVW(self, A, velRadial):
1715
1715
1716 #Operacion Matricial
1716 #Operacion Matricial
1717 # velUVW = numpy.zeros((velRadial.shape[1],3))
1717 # velUVW = numpy.zeros((velRadial.shape[1],3))
1718 # for ind in range(velRadial.shape[1]):
1718 # for ind in range(velRadial.shape[1]):
1719 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
1719 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
1720 # velUVW = velUVW.transpose()
1720 # velUVW = velUVW.transpose()
1721 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1721 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1722 velUVW[:,:] = numpy.dot(A,velRadial)
1722 velUVW[:,:] = numpy.dot(A,velRadial)
1723
1723
1724
1724
1725 return velUVW
1725 return velUVW
1726
1726
1727 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1727 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1728
1728
1729 def techniqueDBS(self, kwargs):
1729 def techniqueDBS(self, kwargs):
1730 """
1730 """
1731 Function that implements Doppler Beam Swinging (DBS) technique.
1731 Function that implements Doppler Beam Swinging (DBS) technique.
1732
1732
1733 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1733 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1734 Direction correction (if necessary), Ranges and SNR
1734 Direction correction (if necessary), Ranges and SNR
1735
1735
1736 Output: Winds estimation (Zonal, Meridional and Vertical)
1736 Output: Winds estimation (Zonal, Meridional and Vertical)
1737
1737
1738 Parameters affected: Winds, height range, SNR
1738 Parameters affected: Winds, height range, SNR
1739 """
1739 """
1740 velRadial0 = kwargs['velRadial']
1740 velRadial0 = kwargs['velRadial']
1741 heiRang = kwargs['heightList']
1741 heiRang = kwargs['heightList']
1742 SNR0 = kwargs['SNR']
1742 SNR0 = kwargs['SNR']
1743
1743
1744 if 'dirCosx' in kwargs and 'dirCosy' in kwargs:
1744 if 'dirCosx' in kwargs and 'dirCosy' in kwargs:
1745 theta_x = numpy.array(kwargs['dirCosx'])
1745 theta_x = numpy.array(kwargs['dirCosx'])
1746 theta_y = numpy.array(kwargs['dirCosy'])
1746 theta_y = numpy.array(kwargs['dirCosy'])
1747 else:
1747 else:
1748 elev = numpy.array(kwargs['elevation'])
1748 elev = numpy.array(kwargs['elevation'])
1749 azim = numpy.array(kwargs['azimuth'])
1749 azim = numpy.array(kwargs['azimuth'])
1750 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1750 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1751 azimuth = kwargs['correctAzimuth']
1751 azimuth = kwargs['correctAzimuth']
1752 if 'horizontalOnly' in kwargs:
1752 if 'horizontalOnly' in kwargs:
1753 horizontalOnly = kwargs['horizontalOnly']
1753 horizontalOnly = kwargs['horizontalOnly']
1754 else: horizontalOnly = False
1754 else: horizontalOnly = False
1755 if 'correctFactor' in kwargs:
1755 if 'correctFactor' in kwargs:
1756 correctFactor = kwargs['correctFactor']
1756 correctFactor = kwargs['correctFactor']
1757 else: correctFactor = 1
1757 else: correctFactor = 1
1758 if 'channelList' in kwargs:
1758 if 'channelList' in kwargs:
1759 channelList = kwargs['channelList']
1759 channelList = kwargs['channelList']
1760 if len(channelList) == 2:
1760 if len(channelList) == 2:
1761 horizontalOnly = True
1761 horizontalOnly = True
1762 arrayChannel = numpy.array(channelList)
1762 arrayChannel = numpy.array(channelList)
1763 param = param[arrayChannel,:,:]
1763 param = param[arrayChannel,:,:]
1764 theta_x = theta_x[arrayChannel]
1764 theta_x = theta_x[arrayChannel]
1765 theta_y = theta_y[arrayChannel]
1765 theta_y = theta_y[arrayChannel]
1766
1766
1767 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
1767 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
1768 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
1768 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
1769 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1769 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1770
1770
1771 #Calculo de Componentes de la velocidad con DBS
1771 #Calculo de Componentes de la velocidad con DBS
1772 winds = self.__calculateVelUVW(A,velRadial1)
1772 winds = self.__calculateVelUVW(A,velRadial1)
1773
1773
1774 return winds, heiRang1, SNR1
1774 return winds, heiRang1, SNR1
1775
1775
1776 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
1776 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
1777
1777
1778 nPairs = len(pairs_ccf)
1778 nPairs = len(pairs_ccf)
1779 posx = numpy.asarray(posx)
1779 posx = numpy.asarray(posx)
1780 posy = numpy.asarray(posy)
1780 posy = numpy.asarray(posy)
1781
1781
1782 #Rotacion Inversa para alinear con el azimuth
1782 #Rotacion Inversa para alinear con el azimuth
1783 if azimuth!= None:
1783 if azimuth!= None:
1784 azimuth = azimuth*math.pi/180
1784 azimuth = azimuth*math.pi/180
1785 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
1785 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
1786 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
1786 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
1787 else:
1787 else:
1788 posx1 = posx
1788 posx1 = posx
1789 posy1 = posy
1789 posy1 = posy
1790
1790
1791 #Calculo de Distancias
1791 #Calculo de Distancias
1792 distx = numpy.zeros(nPairs)
1792 distx = numpy.zeros(nPairs)
1793 disty = numpy.zeros(nPairs)
1793 disty = numpy.zeros(nPairs)
1794 dist = numpy.zeros(nPairs)
1794 dist = numpy.zeros(nPairs)
1795 ang = numpy.zeros(nPairs)
1795 ang = numpy.zeros(nPairs)
1796
1796
1797 for i in range(nPairs):
1797 for i in range(nPairs):
1798 distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
1798 distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
1799 disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
1799 disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
1800 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1800 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1801 ang[i] = numpy.arctan2(disty[i],distx[i])
1801 ang[i] = numpy.arctan2(disty[i],distx[i])
1802
1802
1803 return distx, disty, dist, ang
1803 return distx, disty, dist, ang
1804 #Calculo de Matrices
1804 #Calculo de Matrices
1805 # nPairs = len(pairs)
1805 # nPairs = len(pairs)
1806 # ang1 = numpy.zeros((nPairs, 2, 1))
1806 # ang1 = numpy.zeros((nPairs, 2, 1))
1807 # dist1 = numpy.zeros((nPairs, 2, 1))
1807 # dist1 = numpy.zeros((nPairs, 2, 1))
1808 #
1808 #
1809 # for j in range(nPairs):
1809 # for j in range(nPairs):
1810 # dist1[j,0,0] = dist[pairs[j][0]]
1810 # dist1[j,0,0] = dist[pairs[j][0]]
1811 # dist1[j,1,0] = dist[pairs[j][1]]
1811 # dist1[j,1,0] = dist[pairs[j][1]]
1812 # ang1[j,0,0] = ang[pairs[j][0]]
1812 # ang1[j,0,0] = ang[pairs[j][0]]
1813 # ang1[j,1,0] = ang[pairs[j][1]]
1813 # ang1[j,1,0] = ang[pairs[j][1]]
1814 #
1814 #
1815 # return distx,disty, dist1,ang1
1815 # return distx,disty, dist1,ang1
1816
1816
1817
1817
1818 def __calculateVelVer(self, phase, lagTRange, _lambda):
1818 def __calculateVelVer(self, phase, lagTRange, _lambda):
1819
1819
1820 Ts = lagTRange[1] - lagTRange[0]
1820 Ts = lagTRange[1] - lagTRange[0]
1821 velW = -_lambda*phase/(4*math.pi*Ts)
1821 velW = -_lambda*phase/(4*math.pi*Ts)
1822
1822
1823 return velW
1823 return velW
1824
1824
1825 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1825 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1826 nPairs = tau1.shape[0]
1826 nPairs = tau1.shape[0]
1827 nHeights = tau1.shape[1]
1827 nHeights = tau1.shape[1]
1828 vel = numpy.zeros((nPairs,3,nHeights))
1828 vel = numpy.zeros((nPairs,3,nHeights))
1829 dist1 = numpy.reshape(dist, (dist.size,1))
1829 dist1 = numpy.reshape(dist, (dist.size,1))
1830
1830
1831 angCos = numpy.cos(ang)
1831 angCos = numpy.cos(ang)
1832 angSin = numpy.sin(ang)
1832 angSin = numpy.sin(ang)
1833
1833
1834 vel0 = dist1*tau1/(2*tau2**2)
1834 vel0 = dist1*tau1/(2*tau2**2)
1835 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1835 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1836 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1836 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1837
1837
1838 ind = numpy.where(numpy.isinf(vel))
1838 ind = numpy.where(numpy.isinf(vel))
1839 vel[ind] = numpy.nan
1839 vel[ind] = numpy.nan
1840
1840
1841 return vel
1841 return vel
1842
1842
1843 # def __getPairsAutoCorr(self, pairsList, nChannels):
1843 # def __getPairsAutoCorr(self, pairsList, nChannels):
1844 #
1844 #
1845 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1845 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1846 #
1846 #
1847 # for l in range(len(pairsList)):
1847 # for l in range(len(pairsList)):
1848 # firstChannel = pairsList[l][0]
1848 # firstChannel = pairsList[l][0]
1849 # secondChannel = pairsList[l][1]
1849 # secondChannel = pairsList[l][1]
1850 #
1850 #
1851 # #Obteniendo pares de Autocorrelacion
1851 # #Obteniendo pares de Autocorrelacion
1852 # if firstChannel == secondChannel:
1852 # if firstChannel == secondChannel:
1853 # pairsAutoCorr[firstChannel] = int(l)
1853 # pairsAutoCorr[firstChannel] = int(l)
1854 #
1854 #
1855 # pairsAutoCorr = pairsAutoCorr.astype(int)
1855 # pairsAutoCorr = pairsAutoCorr.astype(int)
1856 #
1856 #
1857 # pairsCrossCorr = range(len(pairsList))
1857 # pairsCrossCorr = range(len(pairsList))
1858 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1858 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1859 #
1859 #
1860 # return pairsAutoCorr, pairsCrossCorr
1860 # return pairsAutoCorr, pairsCrossCorr
1861
1861
1862 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1862 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1863 def techniqueSA(self, kwargs):
1863 def techniqueSA(self, kwargs):
1864
1864
1865 """
1865 """
1866 Function that implements Spaced Antenna (SA) technique.
1866 Function that implements Spaced Antenna (SA) technique.
1867
1867
1868 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1868 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1869 Direction correction (if necessary), Ranges and SNR
1869 Direction correction (if necessary), Ranges and SNR
1870
1870
1871 Output: Winds estimation (Zonal, Meridional and Vertical)
1871 Output: Winds estimation (Zonal, Meridional and Vertical)
1872
1872
1873 Parameters affected: Winds
1873 Parameters affected: Winds
1874 """
1874 """
1875 position_x = kwargs['positionX']
1875 position_x = kwargs['positionX']
1876 position_y = kwargs['positionY']
1876 position_y = kwargs['positionY']
1877 azimuth = kwargs['azimuth']
1877 azimuth = kwargs['azimuth']
1878
1878
1879 if 'correctFactor' in kwargs:
1879 if 'correctFactor' in kwargs:
1880 correctFactor = kwargs['correctFactor']
1880 correctFactor = kwargs['correctFactor']
1881 else:
1881 else:
1882 correctFactor = 1
1882 correctFactor = 1
1883
1883
1884 groupList = kwargs['groupList']
1884 groupList = kwargs['groupList']
1885 pairs_ccf = groupList[1]
1885 pairs_ccf = groupList[1]
1886 tau = kwargs['tau']
1886 tau = kwargs['tau']
1887 _lambda = kwargs['_lambda']
1887 _lambda = kwargs['_lambda']
1888
1888
1889 #Cross Correlation pairs obtained
1889 #Cross Correlation pairs obtained
1890 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
1890 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
1891 # pairsArray = numpy.array(pairsList)[pairsCrossCorr]
1891 # pairsArray = numpy.array(pairsList)[pairsCrossCorr]
1892 # pairsSelArray = numpy.array(pairsSelected)
1892 # pairsSelArray = numpy.array(pairsSelected)
1893 # pairs = []
1893 # pairs = []
1894 #
1894 #
1895 # #Wind estimation pairs obtained
1895 # #Wind estimation pairs obtained
1896 # for i in range(pairsSelArray.shape[0]/2):
1896 # for i in range(pairsSelArray.shape[0]/2):
1897 # ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
1897 # ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
1898 # ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
1898 # ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
1899 # pairs.append((ind1,ind2))
1899 # pairs.append((ind1,ind2))
1900
1900
1901 indtau = tau.shape[0]/2
1901 indtau = tau.shape[0]/2
1902 tau1 = tau[:indtau,:]
1902 tau1 = tau[:indtau,:]
1903 tau2 = tau[indtau:-1,:]
1903 tau2 = tau[indtau:-1,:]
1904 # tau1 = tau1[pairs,:]
1904 # tau1 = tau1[pairs,:]
1905 # tau2 = tau2[pairs,:]
1905 # tau2 = tau2[pairs,:]
1906 phase1 = tau[-1,:]
1906 phase1 = tau[-1,:]
1907
1907
1908 #---------------------------------------------------------------------
1908 #---------------------------------------------------------------------
1909 #Metodo Directo
1909 #Metodo Directo
1910 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
1910 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
1911 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
1911 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
1912 winds = stats.nanmean(winds, axis=0)
1912 winds = stats.nanmean(winds, axis=0)
1913 #---------------------------------------------------------------------
1913 #---------------------------------------------------------------------
1914 #Metodo General
1914 #Metodo General
1915 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
1915 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
1916 # #Calculo Coeficientes de Funcion de Correlacion
1916 # #Calculo Coeficientes de Funcion de Correlacion
1917 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
1917 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
1918 # #Calculo de Velocidades
1918 # #Calculo de Velocidades
1919 # winds = self.calculateVelUV(F,G,A,B,H)
1919 # winds = self.calculateVelUV(F,G,A,B,H)
1920
1920
1921 #---------------------------------------------------------------------
1921 #---------------------------------------------------------------------
1922 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
1922 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
1923 winds = correctFactor*winds
1923 winds = correctFactor*winds
1924 return winds
1924 return winds
1925
1925
1926 def __checkTime(self, currentTime, paramInterval, outputInterval):
1926 def __checkTime(self, currentTime, paramInterval, outputInterval):
1927
1927
1928 dataTime = currentTime + paramInterval
1928 dataTime = currentTime + paramInterval
1929 deltaTime = dataTime - self.__initime
1929 deltaTime = dataTime - self.__initime
1930
1930
1931 if deltaTime >= outputInterval or deltaTime < 0:
1931 if deltaTime >= outputInterval or deltaTime < 0:
1932 self.__dataReady = True
1932 self.__dataReady = True
1933 return
1933 return
1934
1934
1935 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
1935 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
1936 '''
1936 '''
1937 Function that implements winds estimation technique with detected meteors.
1937 Function that implements winds estimation technique with detected meteors.
1938
1938
1939 Input: Detected meteors, Minimum meteor quantity to wind estimation
1939 Input: Detected meteors, Minimum meteor quantity to wind estimation
1940
1940
1941 Output: Winds estimation (Zonal and Meridional)
1941 Output: Winds estimation (Zonal and Meridional)
1942
1942
1943 Parameters affected: Winds
1943 Parameters affected: Winds
1944 '''
1944 '''
1945 #Settings
1945 #Settings
1946 nInt = (heightMax - heightMin)/2
1946 nInt = (heightMax - heightMin)/2
1947 nInt = int(nInt)
1947 nInt = int(nInt)
1948 winds = numpy.zeros((2,nInt))*numpy.nan
1948 winds = numpy.zeros((2,nInt))*numpy.nan
1949
1949
1950 #Filter errors
1950 #Filter errors
1951 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
1951 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
1952 finalMeteor = arrayMeteor[error,:]
1952 finalMeteor = arrayMeteor[error,:]
1953
1953
1954 #Meteor Histogram
1954 #Meteor Histogram
1955 finalHeights = finalMeteor[:,2]
1955 finalHeights = finalMeteor[:,2]
1956 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
1956 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
1957 nMeteorsPerI = hist[0]
1957 nMeteorsPerI = hist[0]
1958 heightPerI = hist[1]
1958 heightPerI = hist[1]
1959
1959
1960 #Sort of meteors
1960 #Sort of meteors
1961 indSort = finalHeights.argsort()
1961 indSort = finalHeights.argsort()
1962 finalMeteor2 = finalMeteor[indSort,:]
1962 finalMeteor2 = finalMeteor[indSort,:]
1963
1963
1964 # Calculating winds
1964 # Calculating winds
1965 ind1 = 0
1965 ind1 = 0
1966 ind2 = 0
1966 ind2 = 0
1967
1967
1968 for i in range(nInt):
1968 for i in range(nInt):
1969 nMet = nMeteorsPerI[i]
1969 nMet = nMeteorsPerI[i]
1970 ind1 = ind2
1970 ind1 = ind2
1971 ind2 = ind1 + nMet
1971 ind2 = ind1 + nMet
1972
1972
1973 meteorAux = finalMeteor2[ind1:ind2,:]
1973 meteorAux = finalMeteor2[ind1:ind2,:]
1974
1974
1975 if meteorAux.shape[0] >= meteorThresh:
1975 if meteorAux.shape[0] >= meteorThresh:
1976 vel = meteorAux[:, 6]
1976 vel = meteorAux[:, 6]
1977 zen = meteorAux[:, 4]*numpy.pi/180
1977 zen = meteorAux[:, 4]*numpy.pi/180
1978 azim = meteorAux[:, 3]*numpy.pi/180
1978 azim = meteorAux[:, 3]*numpy.pi/180
1979
1979
1980 n = numpy.cos(zen)
1980 n = numpy.cos(zen)
1981 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
1981 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
1982 # l = m*numpy.tan(azim)
1982 # l = m*numpy.tan(azim)
1983 l = numpy.sin(zen)*numpy.sin(azim)
1983 l = numpy.sin(zen)*numpy.sin(azim)
1984 m = numpy.sin(zen)*numpy.cos(azim)
1984 m = numpy.sin(zen)*numpy.cos(azim)
1985
1985
1986 A = numpy.vstack((l, m)).transpose()
1986 A = numpy.vstack((l, m)).transpose()
1987 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
1987 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
1988 windsAux = numpy.dot(A1, vel)
1988 windsAux = numpy.dot(A1, vel)
1989
1989
1990 winds[0,i] = windsAux[0]
1990 winds[0,i] = windsAux[0]
1991 winds[1,i] = windsAux[1]
1991 winds[1,i] = windsAux[1]
1992
1992
1993 return winds, heightPerI[:-1]
1993 return winds, heightPerI[:-1]
1994
1994
1995 def techniqueNSM_SA(self, **kwargs):
1995 def techniqueNSM_SA(self, **kwargs):
1996 metArray = kwargs['metArray']
1996 metArray = kwargs['metArray']
1997 heightList = kwargs['heightList']
1997 heightList = kwargs['heightList']
1998 timeList = kwargs['timeList']
1998 timeList = kwargs['timeList']
1999
1999
2000 rx_location = kwargs['rx_location']
2000 rx_location = kwargs['rx_location']
2001 groupList = kwargs['groupList']
2001 groupList = kwargs['groupList']
2002 azimuth = kwargs['azimuth']
2002 azimuth = kwargs['azimuth']
2003 dfactor = kwargs['dfactor']
2003 dfactor = kwargs['dfactor']
2004 k = kwargs['k']
2004 k = kwargs['k']
2005
2005
2006 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
2006 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
2007 d = dist*dfactor
2007 d = dist*dfactor
2008 #Phase calculation
2008 #Phase calculation
2009 metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
2009 metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
2010
2010
2011 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
2011 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
2012
2012
2013 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2013 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2014 azimuth1 = azimuth1*numpy.pi/180
2014 azimuth1 = azimuth1*numpy.pi/180
2015
2015
2016 for i in range(heightList.size):
2016 for i in range(heightList.size):
2017 h = heightList[i]
2017 h = heightList[i]
2018 indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
2018 indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
2019 metHeight = metArray1[indH,:]
2019 metHeight = metArray1[indH,:]
2020 if metHeight.shape[0] >= 2:
2020 if metHeight.shape[0] >= 2:
2021 velAux = numpy.asmatrix(metHeight[:,-2]).T #Radial Velocities
2021 velAux = numpy.asmatrix(metHeight[:,-2]).T #Radial Velocities
2022 iazim = metHeight[:,1].astype(int)
2022 iazim = metHeight[:,1].astype(int)
2023 azimAux = numpy.asmatrix(azimuth1[iazim]).T #Azimuths
2023 azimAux = numpy.asmatrix(azimuth1[iazim]).T #Azimuths
2024 A = numpy.hstack((numpy.cos(azimAux),numpy.sin(azimAux)))
2024 A = numpy.hstack((numpy.cos(azimAux),numpy.sin(azimAux)))
2025 A = numpy.asmatrix(A)
2025 A = numpy.asmatrix(A)
2026 A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
2026 A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
2027 velHor = numpy.dot(A1,velAux)
2027 velHor = numpy.dot(A1,velAux)
2028
2028
2029 velEst[i,:] = numpy.squeeze(velHor)
2029 velEst[i,:] = numpy.squeeze(velHor)
2030 return velEst
2030 return velEst
2031
2031
2032 def __getPhaseSlope(self, metArray, heightList, timeList):
2032 def __getPhaseSlope(self, metArray, heightList, timeList):
2033 meteorList = []
2033 meteorList = []
2034 #utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
2034 #utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
2035 #Putting back together the meteor matrix
2035 #Putting back together the meteor matrix
2036 utctime = metArray[:,0]
2036 utctime = metArray[:,0]
2037 uniqueTime = numpy.unique(utctime)
2037 uniqueTime = numpy.unique(utctime)
2038
2038
2039 phaseDerThresh = 0.5
2039 phaseDerThresh = 0.5
2040 ippSeconds = timeList[1] - timeList[0]
2040 ippSeconds = timeList[1] - timeList[0]
2041 sec = numpy.where(timeList>1)[0][0]
2041 sec = numpy.where(timeList>1)[0][0]
2042 nPairs = metArray.shape[1] - 6
2042 nPairs = metArray.shape[1] - 6
2043 nHeights = len(heightList)
2043 nHeights = len(heightList)
2044
2044
2045 for t in uniqueTime:
2045 for t in uniqueTime:
2046 metArray1 = metArray[utctime==t,:]
2046 metArray1 = metArray[utctime==t,:]
2047 # phaseDerThresh = numpy.pi/4 #reducir Phase thresh
2047 # phaseDerThresh = numpy.pi/4 #reducir Phase thresh
2048 tmet = metArray1[:,1].astype(int)
2048 tmet = metArray1[:,1].astype(int)
2049 hmet = metArray1[:,2].astype(int)
2049 hmet = metArray1[:,2].astype(int)
2050
2050
2051 metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
2051 metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
2052 metPhase[:,:] = numpy.nan
2052 metPhase[:,:] = numpy.nan
2053 metPhase[:,hmet,tmet] = metArray1[:,6:].T
2053 metPhase[:,hmet,tmet] = metArray1[:,6:].T
2054
2054
2055 #Delete short trails
2055 #Delete short trails
2056 metBool = ~numpy.isnan(metPhase[0,:,:])
2056 metBool = ~numpy.isnan(metPhase[0,:,:])
2057 heightVect = numpy.sum(metBool, axis = 1)
2057 heightVect = numpy.sum(metBool, axis = 1)
2058 metBool[heightVect<sec,:] = False
2058 metBool[heightVect<sec,:] = False
2059 metPhase[:,heightVect<sec,:] = numpy.nan
2059 metPhase[:,heightVect<sec,:] = numpy.nan
2060
2060
2061 #Derivative
2061 #Derivative
2062 metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
2062 metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
2063 phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
2063 phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
2064 metPhase[phDerAux] = numpy.nan
2064 metPhase[phDerAux] = numpy.nan
2065
2065
2066 #--------------------------METEOR DETECTION -----------------------------------------
2066 #--------------------------METEOR DETECTION -----------------------------------------
2067 indMet = numpy.where(numpy.any(metBool,axis=1))[0]
2067 indMet = numpy.where(numpy.any(metBool,axis=1))[0]
2068
2068
2069 for p in numpy.arange(nPairs):
2069 for p in numpy.arange(nPairs):
2070 phase = metPhase[p,:,:]
2070 phase = metPhase[p,:,:]
2071 phDer = metDer[p,:,:]
2071 phDer = metDer[p,:,:]
2072
2072
2073 for h in indMet:
2073 for h in indMet:
2074 height = heightList[h]
2074 height = heightList[h]
2075 phase1 = phase[h,:] #82
2075 phase1 = phase[h,:] #82
2076 phDer1 = phDer[h,:]
2076 phDer1 = phDer[h,:]
2077
2077
2078 phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
2078 phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
2079
2079
2080 indValid = numpy.where(~numpy.isnan(phase1))[0]
2080 indValid = numpy.where(~numpy.isnan(phase1))[0]
2081 initMet = indValid[0]
2081 initMet = indValid[0]
2082 endMet = 0
2082 endMet = 0
2083
2083
2084 for i in range(len(indValid)-1):
2084 for i in range(len(indValid)-1):
2085
2085
2086 #Time difference
2086 #Time difference
2087 inow = indValid[i]
2087 inow = indValid[i]
2088 inext = indValid[i+1]
2088 inext = indValid[i+1]
2089 idiff = inext - inow
2089 idiff = inext - inow
2090 #Phase difference
2090 #Phase difference
2091 phDiff = numpy.abs(phase1[inext] - phase1[inow])
2091 phDiff = numpy.abs(phase1[inext] - phase1[inow])
2092
2092
2093 if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
2093 if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
2094 sizeTrail = inow - initMet + 1
2094 sizeTrail = inow - initMet + 1
2095 if sizeTrail>3*sec: #Too short meteors
2095 if sizeTrail>3*sec: #Too short meteors
2096 x = numpy.arange(initMet,inow+1)*ippSeconds
2096 x = numpy.arange(initMet,inow+1)*ippSeconds
2097 y = phase1[initMet:inow+1]
2097 y = phase1[initMet:inow+1]
2098 ynnan = ~numpy.isnan(y)
2098 ynnan = ~numpy.isnan(y)
2099 x = x[ynnan]
2099 x = x[ynnan]
2100 y = y[ynnan]
2100 y = y[ynnan]
2101 slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
2101 slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
2102 ylin = x*slope + intercept
2102 ylin = x*slope + intercept
2103 rsq = r_value**2
2103 rsq = r_value**2
2104 if rsq > 0.5:
2104 if rsq > 0.5:
2105 vel = slope#*height*1000/(k*d)
2105 vel = slope#*height*1000/(k*d)
2106 estAux = numpy.array([utctime,p,height, vel, rsq])
2106 estAux = numpy.array([utctime,p,height, vel, rsq])
2107 meteorList.append(estAux)
2107 meteorList.append(estAux)
2108 initMet = inext
2108 initMet = inext
2109 metArray2 = numpy.array(meteorList)
2109 metArray2 = numpy.array(meteorList)
2110
2110
2111 return metArray2
2111 return metArray2
2112
2112
2113 def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
2113 def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
2114
2114
2115 azimuth1 = numpy.zeros(len(pairslist))
2115 azimuth1 = numpy.zeros(len(pairslist))
2116 dist = numpy.zeros(len(pairslist))
2116 dist = numpy.zeros(len(pairslist))
2117
2117
2118 for i in range(len(rx_location)):
2118 for i in range(len(rx_location)):
2119 ch0 = pairslist[i][0]
2119 ch0 = pairslist[i][0]
2120 ch1 = pairslist[i][1]
2120 ch1 = pairslist[i][1]
2121
2121
2122 diffX = rx_location[ch0][0] - rx_location[ch1][0]
2122 diffX = rx_location[ch0][0] - rx_location[ch1][0]
2123 diffY = rx_location[ch0][1] - rx_location[ch1][1]
2123 diffY = rx_location[ch0][1] - rx_location[ch1][1]
2124 azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
2124 azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
2125 dist[i] = numpy.sqrt(diffX**2 + diffY**2)
2125 dist[i] = numpy.sqrt(diffX**2 + diffY**2)
2126
2126
2127 azimuth1 -= azimuth0
2127 azimuth1 -= azimuth0
2128 return azimuth1, dist
2128 return azimuth1, dist
2129
2129
2130 def techniqueNSM_DBS(self, **kwargs):
2130 def techniqueNSM_DBS(self, **kwargs):
2131 metArray = kwargs['metArray']
2131 metArray = kwargs['metArray']
2132 heightList = kwargs['heightList']
2132 heightList = kwargs['heightList']
2133 timeList = kwargs['timeList']
2133 timeList = kwargs['timeList']
2134 azimuth = kwargs['azimuth']
2134 azimuth = kwargs['azimuth']
2135 theta_x = numpy.array(kwargs['theta_x'])
2135 theta_x = numpy.array(kwargs['theta_x'])
2136 theta_y = numpy.array(kwargs['theta_y'])
2136 theta_y = numpy.array(kwargs['theta_y'])
2137
2137
2138 utctime = metArray[:,0]
2138 utctime = metArray[:,0]
2139 cmet = metArray[:,1].astype(int)
2139 cmet = metArray[:,1].astype(int)
2140 hmet = metArray[:,3].astype(int)
2140 hmet = metArray[:,3].astype(int)
2141 SNRmet = metArray[:,4]
2141 SNRmet = metArray[:,4]
2142 vmet = metArray[:,5]
2142 vmet = metArray[:,5]
2143 spcmet = metArray[:,6]
2143 spcmet = metArray[:,6]
2144
2144
2145 nChan = numpy.max(cmet) + 1
2145 nChan = numpy.max(cmet) + 1
2146 nHeights = len(heightList)
2146 nHeights = len(heightList)
2147
2147
2148 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
2148 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
2149 hmet = heightList[hmet]
2149 hmet = heightList[hmet]
2150 h1met = hmet*numpy.cos(zenith_arr[cmet]) #Corrected heights
2150 h1met = hmet*numpy.cos(zenith_arr[cmet]) #Corrected heights
2151
2151
2152 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2152 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2153
2153
2154 for i in range(nHeights - 1):
2154 for i in range(nHeights - 1):
2155 hmin = heightList[i]
2155 hmin = heightList[i]
2156 hmax = heightList[i + 1]
2156 hmax = heightList[i + 1]
2157
2157
2158 thisH = (h1met>=hmin) & (h1met<hmax) & (cmet!=2) & (SNRmet>8) & (vmet<50) & (spcmet<10)
2158 thisH = (h1met>=hmin) & (h1met<hmax) & (cmet!=2) & (SNRmet>8) & (vmet<50) & (spcmet<10)
2159 indthisH = numpy.where(thisH)
2159 indthisH = numpy.where(thisH)
2160
2160
2161 if numpy.size(indthisH) > 3:
2161 if numpy.size(indthisH) > 3:
2162
2162
2163 vel_aux = vmet[thisH]
2163 vel_aux = vmet[thisH]
2164 chan_aux = cmet[thisH]
2164 chan_aux = cmet[thisH]
2165 cosu_aux = dir_cosu[chan_aux]
2165 cosu_aux = dir_cosu[chan_aux]
2166 cosv_aux = dir_cosv[chan_aux]
2166 cosv_aux = dir_cosv[chan_aux]
2167 cosw_aux = dir_cosw[chan_aux]
2167 cosw_aux = dir_cosw[chan_aux]
2168
2168
2169 nch = numpy.size(numpy.unique(chan_aux))
2169 nch = numpy.size(numpy.unique(chan_aux))
2170 if nch > 1:
2170 if nch > 1:
2171 A = self.__calculateMatA(cosu_aux, cosv_aux, cosw_aux, True)
2171 A = self.__calculateMatA(cosu_aux, cosv_aux, cosw_aux, True)
2172 velEst[i,:] = numpy.dot(A,vel_aux)
2172 velEst[i,:] = numpy.dot(A,vel_aux)
2173
2173
2174 return velEst
2174 return velEst
2175
2175
2176 def run(self, dataOut, technique, nHours=1, hmin=70, hmax=110, **kwargs):
2176 def run(self, dataOut, technique, nHours=1, hmin=70, hmax=110, **kwargs):
2177
2177
2178 param = dataOut.data_param
2178 param = dataOut.data_param
2179 if dataOut.abscissaList != None:
2179 if dataOut.abscissaList != None:
2180 absc = dataOut.abscissaList[:-1]
2180 absc = dataOut.abscissaList[:-1]
2181 # noise = dataOut.noise
2181 # noise = dataOut.noise
2182 heightList = dataOut.heightList
2182 heightList = dataOut.heightList
2183 SNR = dataOut.data_snr
2183 SNR = dataOut.data_snr
2184
2184
2185 if technique == 'DBS':
2185 if technique == 'DBS':
2186
2186
2187 kwargs['velRadial'] = param[:,1,:] #Radial velocity
2187 kwargs['velRadial'] = param[:,1,:] #Radial velocity
2188 kwargs['heightList'] = heightList
2188 kwargs['heightList'] = heightList
2189 kwargs['SNR'] = SNR
2189 kwargs['SNR'] = SNR
2190
2190
2191 dataOut.data_output, dataOut.heightList, dataOut.data_snr = self.techniqueDBS(kwargs) #DBS Function
2191 dataOut.data_output, dataOut.heightList, dataOut.data_snr = self.techniqueDBS(kwargs) #DBS Function
2192 dataOut.utctimeInit = dataOut.utctime
2192 dataOut.utctimeInit = dataOut.utctime
2193 dataOut.outputInterval = dataOut.paramInterval
2193 dataOut.outputInterval = dataOut.paramInterval
2194
2194
2195 elif technique == 'SA':
2195 elif technique == 'SA':
2196
2196
2197 #Parameters
2197 #Parameters
2198 # position_x = kwargs['positionX']
2198 # position_x = kwargs['positionX']
2199 # position_y = kwargs['positionY']
2199 # position_y = kwargs['positionY']
2200 # azimuth = kwargs['azimuth']
2200 # azimuth = kwargs['azimuth']
2201 #
2201 #
2202 # if kwargs.has_key('crosspairsList'):
2202 # if kwargs.has_key('crosspairsList'):
2203 # pairs = kwargs['crosspairsList']
2203 # pairs = kwargs['crosspairsList']
2204 # else:
2204 # else:
2205 # pairs = None
2205 # pairs = None
2206 #
2206 #
2207 # if kwargs.has_key('correctFactor'):
2207 # if kwargs.has_key('correctFactor'):
2208 # correctFactor = kwargs['correctFactor']
2208 # correctFactor = kwargs['correctFactor']
2209 # else:
2209 # else:
2210 # correctFactor = 1
2210 # correctFactor = 1
2211
2211
2212 # tau = dataOut.data_param
2212 # tau = dataOut.data_param
2213 # _lambda = dataOut.C/dataOut.frequency
2213 # _lambda = dataOut.C/dataOut.frequency
2214 # pairsList = dataOut.groupList
2214 # pairsList = dataOut.groupList
2215 # nChannels = dataOut.nChannels
2215 # nChannels = dataOut.nChannels
2216
2216
2217 kwargs['groupList'] = dataOut.groupList
2217 kwargs['groupList'] = dataOut.groupList
2218 kwargs['tau'] = dataOut.data_param
2218 kwargs['tau'] = dataOut.data_param
2219 kwargs['_lambda'] = dataOut.C/dataOut.frequency
2219 kwargs['_lambda'] = dataOut.C/dataOut.frequency
2220 # dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
2220 # dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
2221 dataOut.data_output = self.techniqueSA(kwargs)
2221 dataOut.data_output = self.techniqueSA(kwargs)
2222 dataOut.utctimeInit = dataOut.utctime
2222 dataOut.utctimeInit = dataOut.utctime
2223 dataOut.outputInterval = dataOut.timeInterval
2223 dataOut.outputInterval = dataOut.timeInterval
2224
2224
2225 elif technique == 'Meteors':
2225 elif technique == 'Meteors':
2226 dataOut.flagNoData = True
2226 dataOut.flagNoData = True
2227 self.__dataReady = False
2227 self.__dataReady = False
2228
2228
2229 if 'nHours' in kwargs:
2229 if 'nHours' in kwargs:
2230 nHours = kwargs['nHours']
2230 nHours = kwargs['nHours']
2231 else:
2231 else:
2232 nHours = 1
2232 nHours = 1
2233
2233
2234 if 'meteorsPerBin' in kwargs:
2234 if 'meteorsPerBin' in kwargs:
2235 meteorThresh = kwargs['meteorsPerBin']
2235 meteorThresh = kwargs['meteorsPerBin']
2236 else:
2236 else:
2237 meteorThresh = 6
2237 meteorThresh = 6
2238
2238
2239 if 'hmin' in kwargs:
2239 if 'hmin' in kwargs:
2240 hmin = kwargs['hmin']
2240 hmin = kwargs['hmin']
2241 else: hmin = 70
2241 else: hmin = 70
2242 if 'hmax' in kwargs:
2242 if 'hmax' in kwargs:
2243 hmax = kwargs['hmax']
2243 hmax = kwargs['hmax']
2244 else: hmax = 110
2244 else: hmax = 110
2245
2245
2246 dataOut.outputInterval = nHours*3600
2246 dataOut.outputInterval = nHours*3600
2247
2247
2248 if self.__isConfig == False:
2248 if self.__isConfig == False:
2249 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2249 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2250 #Get Initial LTC time
2250 #Get Initial LTC time
2251 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2251 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2252 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2252 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2253
2253
2254 self.__isConfig = True
2254 self.__isConfig = True
2255
2255
2256 if self.__buffer is None:
2256 if self.__buffer is None:
2257 self.__buffer = dataOut.data_param
2257 self.__buffer = dataOut.data_param
2258 self.__firstdata = copy.copy(dataOut)
2258 self.__firstdata = copy.copy(dataOut)
2259
2259
2260 else:
2260 else:
2261 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2261 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2262
2262
2263 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2263 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2264
2264
2265 if self.__dataReady:
2265 if self.__dataReady:
2266 dataOut.utctimeInit = self.__initime
2266 dataOut.utctimeInit = self.__initime
2267
2267
2268 self.__initime += dataOut.outputInterval #to erase time offset
2268 self.__initime += dataOut.outputInterval #to erase time offset
2269
2269
2270 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
2270 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
2271 dataOut.flagNoData = False
2271 dataOut.flagNoData = False
2272 self.__buffer = None
2272 self.__buffer = None
2273
2273
2274 elif technique == 'Meteors1':
2274 elif technique == 'Meteors1':
2275 dataOut.flagNoData = True
2275 dataOut.flagNoData = True
2276 self.__dataReady = False
2276 self.__dataReady = False
2277
2277
2278 if 'nMins' in kwargs:
2278 if 'nMins' in kwargs:
2279 nMins = kwargs['nMins']
2279 nMins = kwargs['nMins']
2280 else: nMins = 20
2280 else: nMins = 20
2281 if 'rx_location' in kwargs:
2281 if 'rx_location' in kwargs:
2282 rx_location = kwargs['rx_location']
2282 rx_location = kwargs['rx_location']
2283 else: rx_location = [(0,1),(1,1),(1,0)]
2283 else: rx_location = [(0,1),(1,1),(1,0)]
2284 if 'azimuth' in kwargs:
2284 if 'azimuth' in kwargs:
2285 azimuth = kwargs['azimuth']
2285 azimuth = kwargs['azimuth']
2286 else: azimuth = 51.06
2286 else: azimuth = 51.06
2287 if 'dfactor' in kwargs:
2287 if 'dfactor' in kwargs:
2288 dfactor = kwargs['dfactor']
2288 dfactor = kwargs['dfactor']
2289 if 'mode' in kwargs:
2289 if 'mode' in kwargs:
2290 mode = kwargs['mode']
2290 mode = kwargs['mode']
2291 if 'theta_x' in kwargs:
2291 if 'theta_x' in kwargs:
2292 theta_x = kwargs['theta_x']
2292 theta_x = kwargs['theta_x']
2293 if 'theta_y' in kwargs:
2293 if 'theta_y' in kwargs:
2294 theta_y = kwargs['theta_y']
2294 theta_y = kwargs['theta_y']
2295 else: mode = 'SA'
2295 else: mode = 'SA'
2296
2296
2297 #Borrar luego esto
2297 #Borrar luego esto
2298 if dataOut.groupList is None:
2298 if dataOut.groupList is None:
2299 dataOut.groupList = [(0,1),(0,2),(1,2)]
2299 dataOut.groupList = [(0,1),(0,2),(1,2)]
2300 groupList = dataOut.groupList
2300 groupList = dataOut.groupList
2301 C = 3e8
2301 C = 3e8
2302 freq = 50e6
2302 freq = 50e6
2303 lamb = C/freq
2303 lamb = C/freq
2304 k = 2*numpy.pi/lamb
2304 k = 2*numpy.pi/lamb
2305
2305
2306 timeList = dataOut.abscissaList
2306 timeList = dataOut.abscissaList
2307 heightList = dataOut.heightList
2307 heightList = dataOut.heightList
2308
2308
2309 if self.__isConfig == False:
2309 if self.__isConfig == False:
2310 dataOut.outputInterval = nMins*60
2310 dataOut.outputInterval = nMins*60
2311 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2311 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2312 #Get Initial LTC time
2312 #Get Initial LTC time
2313 initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2313 initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2314 minuteAux = initime.minute
2314 minuteAux = initime.minute
2315 minuteNew = int(numpy.floor(minuteAux/nMins)*nMins)
2315 minuteNew = int(numpy.floor(minuteAux/nMins)*nMins)
2316 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2316 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2317
2317
2318 self.__isConfig = True
2318 self.__isConfig = True
2319
2319
2320 if self.__buffer is None:
2320 if self.__buffer is None:
2321 self.__buffer = dataOut.data_param
2321 self.__buffer = dataOut.data_param
2322 self.__firstdata = copy.copy(dataOut)
2322 self.__firstdata = copy.copy(dataOut)
2323
2323
2324 else:
2324 else:
2325 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2325 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2326
2326
2327 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2327 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2328
2328
2329 if self.__dataReady:
2329 if self.__dataReady:
2330 dataOut.utctimeInit = self.__initime
2330 dataOut.utctimeInit = self.__initime
2331 self.__initime += dataOut.outputInterval #to erase time offset
2331 self.__initime += dataOut.outputInterval #to erase time offset
2332
2332
2333 metArray = self.__buffer
2333 metArray = self.__buffer
2334 if mode == 'SA':
2334 if mode == 'SA':
2335 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
2335 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
2336 elif mode == 'DBS':
2336 elif mode == 'DBS':
2337 dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList, azimuth=azimuth, theta_x=theta_x, theta_y=theta_y)
2337 dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList, azimuth=azimuth, theta_x=theta_x, theta_y=theta_y)
2338 dataOut.data_output = dataOut.data_output.T
2338 dataOut.data_output = dataOut.data_output.T
2339 dataOut.flagNoData = False
2339 dataOut.flagNoData = False
2340 self.__buffer = None
2340 self.__buffer = None
2341
2341
2342 return
2342 return
2343
2343
2344 class EWDriftsEstimation(Operation):
2344 class EWDriftsEstimation(Operation):
2345
2345
2346 def __init__(self):
2346 def __init__(self):
2347 Operation.__init__(self)
2347 Operation.__init__(self)
2348
2348
2349 def __correctValues(self, heiRang, phi, velRadial, SNR):
2349 def __correctValues(self, heiRang, phi, velRadial, SNR):
2350 listPhi = phi.tolist()
2350 listPhi = phi.tolist()
2351 maxid = listPhi.index(max(listPhi))
2351 maxid = listPhi.index(max(listPhi))
2352 minid = listPhi.index(min(listPhi))
2352 minid = listPhi.index(min(listPhi))
2353
2353
2354 rango = list(range(len(phi)))
2354 rango = list(range(len(phi)))
2355 # rango = numpy.delete(rango,maxid)
2355 # rango = numpy.delete(rango,maxid)
2356
2356
2357 heiRang1 = heiRang*math.cos(phi[maxid])
2357 heiRang1 = heiRang*math.cos(phi[maxid])
2358 heiRangAux = heiRang*math.cos(phi[minid])
2358 heiRangAux = heiRang*math.cos(phi[minid])
2359 indOut = (heiRang1 < heiRangAux[0]).nonzero()
2359 indOut = (heiRang1 < heiRangAux[0]).nonzero()
2360 heiRang1 = numpy.delete(heiRang1,indOut)
2360 heiRang1 = numpy.delete(heiRang1,indOut)
2361
2361
2362 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
2362 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
2363 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
2363 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
2364
2364
2365 for i in rango:
2365 for i in rango:
2366 x = heiRang*math.cos(phi[i])
2366 x = heiRang*math.cos(phi[i])
2367 y1 = velRadial[i,:]
2367 y1 = velRadial[i,:]
2368 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
2368 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
2369
2369
2370 x1 = heiRang1
2370 x1 = heiRang1
2371 y11 = f1(x1)
2371 y11 = f1(x1)
2372
2372
2373 y2 = SNR[i,:]
2373 y2 = SNR[i,:]
2374 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
2374 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
2375 y21 = f2(x1)
2375 y21 = f2(x1)
2376
2376
2377 velRadial1[i,:] = y11
2377 velRadial1[i,:] = y11
2378 SNR1[i,:] = y21
2378 SNR1[i,:] = y21
2379
2379
2380 return heiRang1, velRadial1, SNR1
2380 return heiRang1, velRadial1, SNR1
2381
2381
2382 def run(self, dataOut, zenith, zenithCorrection):
2382 def run(self, dataOut, zenith, zenithCorrection):
2383 heiRang = dataOut.heightList
2383 heiRang = dataOut.heightList
2384 velRadial = dataOut.data_param[:,3,:]
2384 velRadial = dataOut.data_param[:,3,:]
2385 SNR = dataOut.data_snr
2385 SNR = dataOut.data_snr
2386
2386
2387 zenith = numpy.array(zenith)
2387 zenith = numpy.array(zenith)
2388 zenith -= zenithCorrection
2388 zenith -= zenithCorrection
2389 zenith *= numpy.pi/180
2389 zenith *= numpy.pi/180
2390
2390
2391 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
2391 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
2392
2392
2393 alp = zenith[0]
2393 alp = zenith[0]
2394 bet = zenith[1]
2394 bet = zenith[1]
2395
2395
2396 w_w = velRadial1[0,:]
2396 w_w = velRadial1[0,:]
2397 w_e = velRadial1[1,:]
2397 w_e = velRadial1[1,:]
2398
2398
2399 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
2399 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
2400 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
2400 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
2401
2401
2402 winds = numpy.vstack((u,w))
2402 winds = numpy.vstack((u,w))
2403
2403
2404 dataOut.heightList = heiRang1
2404 dataOut.heightList = heiRang1
2405 dataOut.data_output = winds
2405 dataOut.data_output = winds
2406 dataOut.data_snr = SNR1
2406 dataOut.data_snr = SNR1
2407
2407
2408 dataOut.utctimeInit = dataOut.utctime
2408 dataOut.utctimeInit = dataOut.utctime
2409 dataOut.outputInterval = dataOut.timeInterval
2409 dataOut.outputInterval = dataOut.timeInterval
2410 return
2410 return
2411
2411
2412 #--------------- Non Specular Meteor ----------------
2412 #--------------- Non Specular Meteor ----------------
2413
2413
2414 class NonSpecularMeteorDetection(Operation):
2414 class NonSpecularMeteorDetection(Operation):
2415
2415
2416 def run(self, dataOut, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False):
2416 def run(self, dataOut, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False):
2417 data_acf = dataOut.data_pre[0]
2417 data_acf = dataOut.data_pre[0]
2418 data_ccf = dataOut.data_pre[1]
2418 data_ccf = dataOut.data_pre[1]
2419 pairsList = dataOut.groupList[1]
2419 pairsList = dataOut.groupList[1]
2420
2420
2421 lamb = dataOut.C/dataOut.frequency
2421 lamb = dataOut.C/dataOut.frequency
2422 tSamp = dataOut.ippSeconds*dataOut.nCohInt
2422 tSamp = dataOut.ippSeconds*dataOut.nCohInt
2423 paramInterval = dataOut.paramInterval
2423 paramInterval = dataOut.paramInterval
2424
2424
2425 nChannels = data_acf.shape[0]
2425 nChannels = data_acf.shape[0]
2426 nLags = data_acf.shape[1]
2426 nLags = data_acf.shape[1]
2427 nProfiles = data_acf.shape[2]
2427 nProfiles = data_acf.shape[2]
2428 nHeights = dataOut.nHeights
2428 nHeights = dataOut.nHeights
2429 nCohInt = dataOut.nCohInt
2429 nCohInt = dataOut.nCohInt
2430 sec = numpy.round(nProfiles/dataOut.paramInterval)
2430 sec = numpy.round(nProfiles/dataOut.paramInterval)
2431 heightList = dataOut.heightList
2431 heightList = dataOut.heightList
2432 ippSeconds = dataOut.ippSeconds*dataOut.nCohInt*dataOut.nAvg
2432 ippSeconds = dataOut.ippSeconds*dataOut.nCohInt*dataOut.nAvg
2433 utctime = dataOut.utctime
2433 utctime = dataOut.utctime
2434
2434
2435 dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
2435 dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
2436
2436
2437 #------------------------ SNR --------------------------------------
2437 #------------------------ SNR --------------------------------------
2438 power = data_acf[:,0,:,:].real
2438 power = data_acf[:,0,:,:].real
2439 noise = numpy.zeros(nChannels)
2439 noise = numpy.zeros(nChannels)
2440 SNR = numpy.zeros(power.shape)
2440 SNR = numpy.zeros(power.shape)
2441 for i in range(nChannels):
2441 for i in range(nChannels):
2442 noise[i] = hildebrand_sekhon(power[i,:], nCohInt)
2442 noise[i] = hildebrand_sekhon(power[i,:], nCohInt)
2443 SNR[i] = (power[i]-noise[i])/noise[i]
2443 SNR[i] = (power[i]-noise[i])/noise[i]
2444 SNRm = numpy.nanmean(SNR, axis = 0)
2444 SNRm = numpy.nanmean(SNR, axis = 0)
2445 SNRdB = 10*numpy.log10(SNR)
2445 SNRdB = 10*numpy.log10(SNR)
2446
2446
2447 if mode == 'SA':
2447 if mode == 'SA':
2448 dataOut.groupList = dataOut.groupList[1]
2448 dataOut.groupList = dataOut.groupList[1]
2449 nPairs = data_ccf.shape[0]
2449 nPairs = data_ccf.shape[0]
2450 #---------------------- Coherence and Phase --------------------------
2450 #---------------------- Coherence and Phase --------------------------
2451 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
2451 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
2452 # phase1 = numpy.copy(phase)
2452 # phase1 = numpy.copy(phase)
2453 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
2453 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
2454
2454
2455 for p in range(nPairs):
2455 for p in range(nPairs):
2456 ch0 = pairsList[p][0]
2456 ch0 = pairsList[p][0]
2457 ch1 = pairsList[p][1]
2457 ch1 = pairsList[p][1]
2458 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
2458 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
2459 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
2459 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
2460 # phase1[p,:,:] = numpy.angle(ccf) #median filter
2460 # phase1[p,:,:] = numpy.angle(ccf) #median filter
2461 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
2461 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
2462 # coh1[p,:,:] = numpy.abs(ccf) #median filter
2462 # coh1[p,:,:] = numpy.abs(ccf) #median filter
2463 coh = numpy.nanmax(coh1, axis = 0)
2463 coh = numpy.nanmax(coh1, axis = 0)
2464 # struc = numpy.ones((5,1))
2464 # struc = numpy.ones((5,1))
2465 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
2465 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
2466 #---------------------- Radial Velocity ----------------------------
2466 #---------------------- Radial Velocity ----------------------------
2467 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
2467 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
2468 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
2468 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
2469
2469
2470 if allData:
2470 if allData:
2471 boolMetFin = ~numpy.isnan(SNRm)
2471 boolMetFin = ~numpy.isnan(SNRm)
2472 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2472 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2473 else:
2473 else:
2474 #------------------------ Meteor mask ---------------------------------
2474 #------------------------ Meteor mask ---------------------------------
2475 # #SNR mask
2475 # #SNR mask
2476 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
2476 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
2477 #
2477 #
2478 # #Erase small objects
2478 # #Erase small objects
2479 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
2479 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
2480 #
2480 #
2481 # auxEEJ = numpy.sum(boolMet1,axis=0)
2481 # auxEEJ = numpy.sum(boolMet1,axis=0)
2482 # indOver = auxEEJ>nProfiles*0.8 #Use this later
2482 # indOver = auxEEJ>nProfiles*0.8 #Use this later
2483 # indEEJ = numpy.where(indOver)[0]
2483 # indEEJ = numpy.where(indOver)[0]
2484 # indNEEJ = numpy.where(~indOver)[0]
2484 # indNEEJ = numpy.where(~indOver)[0]
2485 #
2485 #
2486 # boolMetFin = boolMet1
2486 # boolMetFin = boolMet1
2487 #
2487 #
2488 # if indEEJ.size > 0:
2488 # if indEEJ.size > 0:
2489 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
2489 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
2490 #
2490 #
2491 # boolMet2 = coh > cohThresh
2491 # boolMet2 = coh > cohThresh
2492 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
2492 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
2493 #
2493 #
2494 # #Final Meteor mask
2494 # #Final Meteor mask
2495 # boolMetFin = boolMet1|boolMet2
2495 # boolMetFin = boolMet1|boolMet2
2496
2496
2497 #Coherence mask
2497 #Coherence mask
2498 boolMet1 = coh > 0.75
2498 boolMet1 = coh > 0.75
2499 struc = numpy.ones((30,1))
2499 struc = numpy.ones((30,1))
2500 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
2500 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
2501
2501
2502 #Derivative mask
2502 #Derivative mask
2503 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2503 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2504 boolMet2 = derPhase < 0.2
2504 boolMet2 = derPhase < 0.2
2505 # boolMet2 = ndimage.morphology.binary_opening(boolMet2)
2505 # boolMet2 = ndimage.morphology.binary_opening(boolMet2)
2506 # boolMet2 = ndimage.morphology.binary_closing(boolMet2, structure = numpy.ones((10,1)))
2506 # boolMet2 = ndimage.morphology.binary_closing(boolMet2, structure = numpy.ones((10,1)))
2507 boolMet2 = ndimage.median_filter(boolMet2,size=5)
2507 boolMet2 = ndimage.median_filter(boolMet2,size=5)
2508 boolMet2 = numpy.vstack((boolMet2,numpy.full((1,nHeights), True, dtype=bool)))
2508 boolMet2 = numpy.vstack((boolMet2,numpy.full((1,nHeights), True, dtype=bool)))
2509 # #Final mask
2509 # #Final mask
2510 # boolMetFin = boolMet2
2510 # boolMetFin = boolMet2
2511 boolMetFin = boolMet1&boolMet2
2511 boolMetFin = boolMet1&boolMet2
2512 # boolMetFin = ndimage.morphology.binary_dilation(boolMetFin)
2512 # boolMetFin = ndimage.morphology.binary_dilation(boolMetFin)
2513 #Creating data_param
2513 #Creating data_param
2514 coordMet = numpy.where(boolMetFin)
2514 coordMet = numpy.where(boolMetFin)
2515
2515
2516 tmet = coordMet[0]
2516 tmet = coordMet[0]
2517 hmet = coordMet[1]
2517 hmet = coordMet[1]
2518
2518
2519 data_param = numpy.zeros((tmet.size, 6 + nPairs))
2519 data_param = numpy.zeros((tmet.size, 6 + nPairs))
2520 data_param[:,0] = utctime
2520 data_param[:,0] = utctime
2521 data_param[:,1] = tmet
2521 data_param[:,1] = tmet
2522 data_param[:,2] = hmet
2522 data_param[:,2] = hmet
2523 data_param[:,3] = SNRm[tmet,hmet]
2523 data_param[:,3] = SNRm[tmet,hmet]
2524 data_param[:,4] = velRad[tmet,hmet]
2524 data_param[:,4] = velRad[tmet,hmet]
2525 data_param[:,5] = coh[tmet,hmet]
2525 data_param[:,5] = coh[tmet,hmet]
2526 data_param[:,6:] = phase[:,tmet,hmet].T
2526 data_param[:,6:] = phase[:,tmet,hmet].T
2527
2527
2528 elif mode == 'DBS':
2528 elif mode == 'DBS':
2529 dataOut.groupList = numpy.arange(nChannels)
2529 dataOut.groupList = numpy.arange(nChannels)
2530
2530
2531 #Radial Velocities
2531 #Radial Velocities
2532 phase = numpy.angle(data_acf[:,1,:,:])
2532 phase = numpy.angle(data_acf[:,1,:,:])
2533 # phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
2533 # phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
2534 velRad = phase*lamb/(4*numpy.pi*tSamp)
2534 velRad = phase*lamb/(4*numpy.pi*tSamp)
2535
2535
2536 #Spectral width
2536 #Spectral width
2537 # acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
2537 # acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
2538 # acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
2538 # acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
2539 acf1 = data_acf[:,1,:,:]
2539 acf1 = data_acf[:,1,:,:]
2540 acf2 = data_acf[:,2,:,:]
2540 acf2 = data_acf[:,2,:,:]
2541
2541
2542 spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2))
2542 spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2))
2543 # velRad = ndimage.median_filter(velRad, size = (1,5,1))
2543 # velRad = ndimage.median_filter(velRad, size = (1,5,1))
2544 if allData:
2544 if allData:
2545 boolMetFin = ~numpy.isnan(SNRdB)
2545 boolMetFin = ~numpy.isnan(SNRdB)
2546 else:
2546 else:
2547 #SNR
2547 #SNR
2548 boolMet1 = (SNRdB>SNRthresh) #SNR mask
2548 boolMet1 = (SNRdB>SNRthresh) #SNR mask
2549 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
2549 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
2550
2550
2551 #Radial velocity
2551 #Radial velocity
2552 boolMet2 = numpy.abs(velRad) < 20
2552 boolMet2 = numpy.abs(velRad) < 20
2553 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
2553 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
2554
2554
2555 #Spectral Width
2555 #Spectral Width
2556 boolMet3 = spcWidth < 30
2556 boolMet3 = spcWidth < 30
2557 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
2557 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
2558 # boolMetFin = self.__erase_small(boolMet1, 10,5)
2558 # boolMetFin = self.__erase_small(boolMet1, 10,5)
2559 boolMetFin = boolMet1&boolMet2&boolMet3
2559 boolMetFin = boolMet1&boolMet2&boolMet3
2560
2560
2561 #Creating data_param
2561 #Creating data_param
2562 coordMet = numpy.where(boolMetFin)
2562 coordMet = numpy.where(boolMetFin)
2563
2563
2564 cmet = coordMet[0]
2564 cmet = coordMet[0]
2565 tmet = coordMet[1]
2565 tmet = coordMet[1]
2566 hmet = coordMet[2]
2566 hmet = coordMet[2]
2567
2567
2568 data_param = numpy.zeros((tmet.size, 7))
2568 data_param = numpy.zeros((tmet.size, 7))
2569 data_param[:,0] = utctime
2569 data_param[:,0] = utctime
2570 data_param[:,1] = cmet
2570 data_param[:,1] = cmet
2571 data_param[:,2] = tmet
2571 data_param[:,2] = tmet
2572 data_param[:,3] = hmet
2572 data_param[:,3] = hmet
2573 data_param[:,4] = SNR[cmet,tmet,hmet].T
2573 data_param[:,4] = SNR[cmet,tmet,hmet].T
2574 data_param[:,5] = velRad[cmet,tmet,hmet].T
2574 data_param[:,5] = velRad[cmet,tmet,hmet].T
2575 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
2575 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
2576
2576
2577 # self.dataOut.data_param = data_int
2577 # self.dataOut.data_param = data_int
2578 if len(data_param) == 0:
2578 if len(data_param) == 0:
2579 dataOut.flagNoData = True
2579 dataOut.flagNoData = True
2580 else:
2580 else:
2581 dataOut.data_param = data_param
2581 dataOut.data_param = data_param
2582
2582
2583 def __erase_small(self, binArray, threshX, threshY):
2583 def __erase_small(self, binArray, threshX, threshY):
2584 labarray, numfeat = ndimage.measurements.label(binArray)
2584 labarray, numfeat = ndimage.measurements.label(binArray)
2585 binArray1 = numpy.copy(binArray)
2585 binArray1 = numpy.copy(binArray)
2586
2586
2587 for i in range(1,numfeat + 1):
2587 for i in range(1,numfeat + 1):
2588 auxBin = (labarray==i)
2588 auxBin = (labarray==i)
2589 auxSize = auxBin.sum()
2589 auxSize = auxBin.sum()
2590
2590
2591 x,y = numpy.where(auxBin)
2591 x,y = numpy.where(auxBin)
2592 widthX = x.max() - x.min()
2592 widthX = x.max() - x.min()
2593 widthY = y.max() - y.min()
2593 widthY = y.max() - y.min()
2594
2594
2595 #width X: 3 seg -> 12.5*3
2595 #width X: 3 seg -> 12.5*3
2596 #width Y:
2596 #width Y:
2597
2597
2598 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
2598 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
2599 binArray1[auxBin] = False
2599 binArray1[auxBin] = False
2600
2600
2601 return binArray1
2601 return binArray1
2602
2602
2603 #--------------- Specular Meteor ----------------
2603 #--------------- Specular Meteor ----------------
2604
2604
2605 class SMDetection(Operation):
2605 class SMDetection(Operation):
2606 '''
2606 '''
2607 Function DetectMeteors()
2607 Function DetectMeteors()
2608 Project developed with paper:
2608 Project developed with paper:
2609 HOLDSWORTH ET AL. 2004
2609 HOLDSWORTH ET AL. 2004
2610
2610
2611 Input:
2611 Input:
2612 self.dataOut.data_pre
2612 self.dataOut.data_pre
2613
2613
2614 centerReceiverIndex: From the channels, which is the center receiver
2614 centerReceiverIndex: From the channels, which is the center receiver
2615
2615
2616 hei_ref: Height reference for the Beacon signal extraction
2616 hei_ref: Height reference for the Beacon signal extraction
2617 tauindex:
2617 tauindex:
2618 predefinedPhaseShifts: Predefined phase offset for the voltge signals
2618 predefinedPhaseShifts: Predefined phase offset for the voltge signals
2619
2619
2620 cohDetection: Whether to user Coherent detection or not
2620 cohDetection: Whether to user Coherent detection or not
2621 cohDet_timeStep: Coherent Detection calculation time step
2621 cohDet_timeStep: Coherent Detection calculation time step
2622 cohDet_thresh: Coherent Detection phase threshold to correct phases
2622 cohDet_thresh: Coherent Detection phase threshold to correct phases
2623
2623
2624 noise_timeStep: Noise calculation time step
2624 noise_timeStep: Noise calculation time step
2625 noise_multiple: Noise multiple to define signal threshold
2625 noise_multiple: Noise multiple to define signal threshold
2626
2626
2627 multDet_timeLimit: Multiple Detection Removal time limit in seconds
2627 multDet_timeLimit: Multiple Detection Removal time limit in seconds
2628 multDet_rangeLimit: Multiple Detection Removal range limit in km
2628 multDet_rangeLimit: Multiple Detection Removal range limit in km
2629
2629
2630 phaseThresh: Maximum phase difference between receiver to be consider a meteor
2630 phaseThresh: Maximum phase difference between receiver to be consider a meteor
2631 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
2631 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
2632
2632
2633 hmin: Minimum Height of the meteor to use it in the further wind estimations
2633 hmin: Minimum Height of the meteor to use it in the further wind estimations
2634 hmax: Maximum Height of the meteor to use it in the further wind estimations
2634 hmax: Maximum Height of the meteor to use it in the further wind estimations
2635 azimuth: Azimuth angle correction
2635 azimuth: Azimuth angle correction
2636
2636
2637 Affected:
2637 Affected:
2638 self.dataOut.data_param
2638 self.dataOut.data_param
2639
2639
2640 Rejection Criteria (Errors):
2640 Rejection Criteria (Errors):
2641 0: No error; analysis OK
2641 0: No error; analysis OK
2642 1: SNR < SNR threshold
2642 1: SNR < SNR threshold
2643 2: angle of arrival (AOA) ambiguously determined
2643 2: angle of arrival (AOA) ambiguously determined
2644 3: AOA estimate not feasible
2644 3: AOA estimate not feasible
2645 4: Large difference in AOAs obtained from different antenna baselines
2645 4: Large difference in AOAs obtained from different antenna baselines
2646 5: echo at start or end of time series
2646 5: echo at start or end of time series
2647 6: echo less than 5 examples long; too short for analysis
2647 6: echo less than 5 examples long; too short for analysis
2648 7: echo rise exceeds 0.3s
2648 7: echo rise exceeds 0.3s
2649 8: echo decay time less than twice rise time
2649 8: echo decay time less than twice rise time
2650 9: large power level before echo
2650 9: large power level before echo
2651 10: large power level after echo
2651 10: large power level after echo
2652 11: poor fit to amplitude for estimation of decay time
2652 11: poor fit to amplitude for estimation of decay time
2653 12: poor fit to CCF phase variation for estimation of radial drift velocity
2653 12: poor fit to CCF phase variation for estimation of radial drift velocity
2654 13: height unresolvable echo: not valid height within 70 to 110 km
2654 13: height unresolvable echo: not valid height within 70 to 110 km
2655 14: height ambiguous echo: more then one possible height within 70 to 110 km
2655 14: height ambiguous echo: more then one possible height within 70 to 110 km
2656 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
2656 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
2657 16: oscilatory echo, indicating event most likely not an underdense echo
2657 16: oscilatory echo, indicating event most likely not an underdense echo
2658
2658
2659 17: phase difference in meteor Reestimation
2659 17: phase difference in meteor Reestimation
2660
2660
2661 Data Storage:
2661 Data Storage:
2662 Meteors for Wind Estimation (8):
2662 Meteors for Wind Estimation (8):
2663 Utc Time | Range Height
2663 Utc Time | Range Height
2664 Azimuth Zenith errorCosDir
2664 Azimuth Zenith errorCosDir
2665 VelRad errorVelRad
2665 VelRad errorVelRad
2666 Phase0 Phase1 Phase2 Phase3
2666 Phase0 Phase1 Phase2 Phase3
2667 TypeError
2667 TypeError
2668
2668
2669 '''
2669 '''
2670
2670
2671 def run(self, dataOut, hei_ref = None, tauindex = 0,
2671 def run(self, dataOut, hei_ref = None, tauindex = 0,
2672 phaseOffsets = None,
2672 phaseOffsets = None,
2673 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
2673 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
2674 noise_timeStep = 4, noise_multiple = 4,
2674 noise_timeStep = 4, noise_multiple = 4,
2675 multDet_timeLimit = 1, multDet_rangeLimit = 3,
2675 multDet_timeLimit = 1, multDet_rangeLimit = 3,
2676 phaseThresh = 20, SNRThresh = 5,
2676 phaseThresh = 20, SNRThresh = 5,
2677 hmin = 50, hmax=150, azimuth = 0,
2677 hmin = 50, hmax=150, azimuth = 0,
2678 channelPositions = None) :
2678 channelPositions = None) :
2679
2679
2680
2680
2681 #Getting Pairslist
2681 #Getting Pairslist
2682 if channelPositions is None:
2682 if channelPositions is None:
2683 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2683 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2684 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2684 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2685 meteorOps = SMOperations()
2685 meteorOps = SMOperations()
2686 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2686 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2687 heiRang = dataOut.heightList
2687 heiRang = dataOut.heightList
2688 #Get Beacon signal - No Beacon signal anymore
2688 #Get Beacon signal - No Beacon signal anymore
2689 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
2689 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
2690 #
2690 #
2691 # if hei_ref != None:
2691 # if hei_ref != None:
2692 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
2692 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
2693 #
2693 #
2694
2694
2695
2695
2696 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
2696 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
2697 # see if the user put in pre defined phase shifts
2697 # see if the user put in pre defined phase shifts
2698 voltsPShift = dataOut.data_pre.copy()
2698 voltsPShift = dataOut.data_pre.copy()
2699
2699
2700 # if predefinedPhaseShifts != None:
2700 # if predefinedPhaseShifts != None:
2701 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
2701 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
2702 #
2702 #
2703 # # elif beaconPhaseShifts:
2703 # # elif beaconPhaseShifts:
2704 # # #get hardware phase shifts using beacon signal
2704 # # #get hardware phase shifts using beacon signal
2705 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
2705 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
2706 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
2706 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
2707 #
2707 #
2708 # else:
2708 # else:
2709 # hardwarePhaseShifts = numpy.zeros(5)
2709 # hardwarePhaseShifts = numpy.zeros(5)
2710 #
2710 #
2711 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
2711 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
2712 # for i in range(self.dataOut.data_pre.shape[0]):
2712 # for i in range(self.dataOut.data_pre.shape[0]):
2713 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
2713 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
2714
2714
2715 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
2715 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
2716
2716
2717 #Remove DC
2717 #Remove DC
2718 voltsDC = numpy.mean(voltsPShift,1)
2718 voltsDC = numpy.mean(voltsPShift,1)
2719 voltsDC = numpy.mean(voltsDC,1)
2719 voltsDC = numpy.mean(voltsDC,1)
2720 for i in range(voltsDC.shape[0]):
2720 for i in range(voltsDC.shape[0]):
2721 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
2721 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
2722
2722
2723 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
2723 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
2724 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
2724 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
2725
2725
2726 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
2726 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
2727 #Coherent Detection
2727 #Coherent Detection
2728 if cohDetection:
2728 if cohDetection:
2729 #use coherent detection to get the net power
2729 #use coherent detection to get the net power
2730 cohDet_thresh = cohDet_thresh*numpy.pi/180
2730 cohDet_thresh = cohDet_thresh*numpy.pi/180
2731 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
2731 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
2732
2732
2733 #Non-coherent detection!
2733 #Non-coherent detection!
2734 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
2734 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
2735 #********** END OF COH/NON-COH POWER CALCULATION**********************
2735 #********** END OF COH/NON-COH POWER CALCULATION**********************
2736
2736
2737 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
2737 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
2738 #Get noise
2738 #Get noise
2739 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
2739 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
2740 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
2740 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
2741 #Get signal threshold
2741 #Get signal threshold
2742 signalThresh = noise_multiple*noise
2742 signalThresh = noise_multiple*noise
2743 #Meteor echoes detection
2743 #Meteor echoes detection
2744 listMeteors = self.__findMeteors(powerNet, signalThresh)
2744 listMeteors = self.__findMeteors(powerNet, signalThresh)
2745 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
2745 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
2746
2746
2747 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
2747 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
2748 #Parameters
2748 #Parameters
2749 heiRange = dataOut.heightList
2749 heiRange = dataOut.heightList
2750 rangeInterval = heiRange[1] - heiRange[0]
2750 rangeInterval = heiRange[1] - heiRange[0]
2751 rangeLimit = multDet_rangeLimit/rangeInterval
2751 rangeLimit = multDet_rangeLimit/rangeInterval
2752 timeLimit = multDet_timeLimit/dataOut.timeInterval
2752 timeLimit = multDet_timeLimit/dataOut.timeInterval
2753 #Multiple detection removals
2753 #Multiple detection removals
2754 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
2754 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
2755 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
2755 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
2756
2756
2757 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
2757 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
2758 #Parameters
2758 #Parameters
2759 phaseThresh = phaseThresh*numpy.pi/180
2759 phaseThresh = phaseThresh*numpy.pi/180
2760 thresh = [phaseThresh, noise_multiple, SNRThresh]
2760 thresh = [phaseThresh, noise_multiple, SNRThresh]
2761 #Meteor reestimation (Errors N 1, 6, 12, 17)
2761 #Meteor reestimation (Errors N 1, 6, 12, 17)
2762 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist0, thresh, noise, dataOut.timeInterval, dataOut.frequency)
2762 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist0, thresh, noise, dataOut.timeInterval, dataOut.frequency)
2763 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
2763 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
2764 #Estimation of decay times (Errors N 7, 8, 11)
2764 #Estimation of decay times (Errors N 7, 8, 11)
2765 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
2765 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
2766 #******************* END OF METEOR REESTIMATION *******************
2766 #******************* END OF METEOR REESTIMATION *******************
2767
2767
2768 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
2768 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
2769 #Calculating Radial Velocity (Error N 15)
2769 #Calculating Radial Velocity (Error N 15)
2770 radialStdThresh = 10
2770 radialStdThresh = 10
2771 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
2771 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
2772
2772
2773 if len(listMeteors4) > 0:
2773 if len(listMeteors4) > 0:
2774 #Setting New Array
2774 #Setting New Array
2775 date = dataOut.utctime
2775 date = dataOut.utctime
2776 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
2776 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
2777
2777
2778 #Correcting phase offset
2778 #Correcting phase offset
2779 if phaseOffsets != None:
2779 if phaseOffsets != None:
2780 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2780 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2781 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2781 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2782
2782
2783 #Second Pairslist
2783 #Second Pairslist
2784 pairsList = []
2784 pairsList = []
2785 pairx = (0,1)
2785 pairx = (0,1)
2786 pairy = (2,3)
2786 pairy = (2,3)
2787 pairsList.append(pairx)
2787 pairsList.append(pairx)
2788 pairsList.append(pairy)
2788 pairsList.append(pairy)
2789
2789
2790 jph = numpy.array([0,0,0,0])
2790 jph = numpy.array([0,0,0,0])
2791 h = (hmin,hmax)
2791 h = (hmin,hmax)
2792 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2792 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2793
2793
2794 # #Calculate AOA (Error N 3, 4)
2794 # #Calculate AOA (Error N 3, 4)
2795 # #JONES ET AL. 1998
2795 # #JONES ET AL. 1998
2796 # error = arrayParameters[:,-1]
2796 # error = arrayParameters[:,-1]
2797 # AOAthresh = numpy.pi/8
2797 # AOAthresh = numpy.pi/8
2798 # phases = -arrayParameters[:,9:13]
2798 # phases = -arrayParameters[:,9:13]
2799 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
2799 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
2800 #
2800 #
2801 # #Calculate Heights (Error N 13 and 14)
2801 # #Calculate Heights (Error N 13 and 14)
2802 # error = arrayParameters[:,-1]
2802 # error = arrayParameters[:,-1]
2803 # Ranges = arrayParameters[:,2]
2803 # Ranges = arrayParameters[:,2]
2804 # zenith = arrayParameters[:,5]
2804 # zenith = arrayParameters[:,5]
2805 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
2805 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
2806 # error = arrayParameters[:,-1]
2806 # error = arrayParameters[:,-1]
2807 #********************* END OF PARAMETERS CALCULATION **************************
2807 #********************* END OF PARAMETERS CALCULATION **************************
2808
2808
2809 #***************************+ PASS DATA TO NEXT STEP **********************
2809 #***************************+ PASS DATA TO NEXT STEP **********************
2810 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
2810 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
2811 dataOut.data_param = arrayParameters
2811 dataOut.data_param = arrayParameters
2812
2812
2813 if arrayParameters is None:
2813 if arrayParameters is None:
2814 dataOut.flagNoData = True
2814 dataOut.flagNoData = True
2815 else:
2815 else:
2816 dataOut.flagNoData = True
2816 dataOut.flagNoData = True
2817
2817
2818 return
2818 return
2819
2819
2820 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
2820 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
2821
2821
2822 minIndex = min(newheis[0])
2822 minIndex = min(newheis[0])
2823 maxIndex = max(newheis[0])
2823 maxIndex = max(newheis[0])
2824
2824
2825 voltage = voltage0[:,:,minIndex:maxIndex+1]
2825 voltage = voltage0[:,:,minIndex:maxIndex+1]
2826 nLength = voltage.shape[1]/n
2826 nLength = voltage.shape[1]/n
2827 nMin = 0
2827 nMin = 0
2828 nMax = 0
2828 nMax = 0
2829 phaseOffset = numpy.zeros((len(pairslist),n))
2829 phaseOffset = numpy.zeros((len(pairslist),n))
2830
2830
2831 for i in range(n):
2831 for i in range(n):
2832 nMax += nLength
2832 nMax += nLength
2833 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
2833 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
2834 phaseCCF = numpy.mean(phaseCCF, axis = 2)
2834 phaseCCF = numpy.mean(phaseCCF, axis = 2)
2835 phaseOffset[:,i] = phaseCCF.transpose()
2835 phaseOffset[:,i] = phaseCCF.transpose()
2836 nMin = nMax
2836 nMin = nMax
2837 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
2837 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
2838
2838
2839 #Remove Outliers
2839 #Remove Outliers
2840 factor = 2
2840 factor = 2
2841 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
2841 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
2842 dw = numpy.std(wt,axis = 1)
2842 dw = numpy.std(wt,axis = 1)
2843 dw = dw.reshape((dw.size,1))
2843 dw = dw.reshape((dw.size,1))
2844 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
2844 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
2845 phaseOffset[ind] = numpy.nan
2845 phaseOffset[ind] = numpy.nan
2846 phaseOffset = stats.nanmean(phaseOffset, axis=1)
2846 phaseOffset = stats.nanmean(phaseOffset, axis=1)
2847
2847
2848 return phaseOffset
2848 return phaseOffset
2849
2849
2850 def __shiftPhase(self, data, phaseShift):
2850 def __shiftPhase(self, data, phaseShift):
2851 #this will shift the phase of a complex number
2851 #this will shift the phase of a complex number
2852 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
2852 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
2853 return dataShifted
2853 return dataShifted
2854
2854
2855 def __estimatePhaseDifference(self, array, pairslist):
2855 def __estimatePhaseDifference(self, array, pairslist):
2856 nChannel = array.shape[0]
2856 nChannel = array.shape[0]
2857 nHeights = array.shape[2]
2857 nHeights = array.shape[2]
2858 numPairs = len(pairslist)
2858 numPairs = len(pairslist)
2859 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
2859 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
2860 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
2860 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
2861
2861
2862 #Correct phases
2862 #Correct phases
2863 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
2863 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
2864 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2864 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2865
2865
2866 if indDer[0].shape[0] > 0:
2866 if indDer[0].shape[0] > 0:
2867 for i in range(indDer[0].shape[0]):
2867 for i in range(indDer[0].shape[0]):
2868 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
2868 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
2869 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
2869 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
2870
2870
2871 # for j in range(numSides):
2871 # for j in range(numSides):
2872 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
2872 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
2873 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
2873 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
2874 #
2874 #
2875 #Linear
2875 #Linear
2876 phaseInt = numpy.zeros((numPairs,1))
2876 phaseInt = numpy.zeros((numPairs,1))
2877 angAllCCF = phaseCCF[:,[0,1,3,4],0]
2877 angAllCCF = phaseCCF[:,[0,1,3,4],0]
2878 for j in range(numPairs):
2878 for j in range(numPairs):
2879 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
2879 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
2880 phaseInt[j] = fit[1]
2880 phaseInt[j] = fit[1]
2881 #Phase Differences
2881 #Phase Differences
2882 phaseDiff = phaseInt - phaseCCF[:,2,:]
2882 phaseDiff = phaseInt - phaseCCF[:,2,:]
2883 phaseArrival = phaseInt.reshape(phaseInt.size)
2883 phaseArrival = phaseInt.reshape(phaseInt.size)
2884
2884
2885 #Dealias
2885 #Dealias
2886 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
2886 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
2887 # indAlias = numpy.where(phaseArrival > numpy.pi)
2887 # indAlias = numpy.where(phaseArrival > numpy.pi)
2888 # phaseArrival[indAlias] -= 2*numpy.pi
2888 # phaseArrival[indAlias] -= 2*numpy.pi
2889 # indAlias = numpy.where(phaseArrival < -numpy.pi)
2889 # indAlias = numpy.where(phaseArrival < -numpy.pi)
2890 # phaseArrival[indAlias] += 2*numpy.pi
2890 # phaseArrival[indAlias] += 2*numpy.pi
2891
2891
2892 return phaseDiff, phaseArrival
2892 return phaseDiff, phaseArrival
2893
2893
2894 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
2894 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
2895 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
2895 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
2896 #find the phase shifts of each channel over 1 second intervals
2896 #find the phase shifts of each channel over 1 second intervals
2897 #only look at ranges below the beacon signal
2897 #only look at ranges below the beacon signal
2898 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
2898 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
2899 numBlocks = int(volts.shape[1]/numProfPerBlock)
2899 numBlocks = int(volts.shape[1]/numProfPerBlock)
2900 numHeights = volts.shape[2]
2900 numHeights = volts.shape[2]
2901 nChannel = volts.shape[0]
2901 nChannel = volts.shape[0]
2902 voltsCohDet = volts.copy()
2902 voltsCohDet = volts.copy()
2903
2903
2904 pairsarray = numpy.array(pairslist)
2904 pairsarray = numpy.array(pairslist)
2905 indSides = pairsarray[:,1]
2905 indSides = pairsarray[:,1]
2906 # indSides = numpy.array(range(nChannel))
2906 # indSides = numpy.array(range(nChannel))
2907 # indSides = numpy.delete(indSides, indCenter)
2907 # indSides = numpy.delete(indSides, indCenter)
2908 #
2908 #
2909 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
2909 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
2910 listBlocks = numpy.array_split(volts, numBlocks, 1)
2910 listBlocks = numpy.array_split(volts, numBlocks, 1)
2911
2911
2912 startInd = 0
2912 startInd = 0
2913 endInd = 0
2913 endInd = 0
2914
2914
2915 for i in range(numBlocks):
2915 for i in range(numBlocks):
2916 startInd = endInd
2916 startInd = endInd
2917 endInd = endInd + listBlocks[i].shape[1]
2917 endInd = endInd + listBlocks[i].shape[1]
2918
2918
2919 arrayBlock = listBlocks[i]
2919 arrayBlock = listBlocks[i]
2920 # arrayBlockCenter = listCenter[i]
2920 # arrayBlockCenter = listCenter[i]
2921
2921
2922 #Estimate the Phase Difference
2922 #Estimate the Phase Difference
2923 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
2923 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
2924 #Phase Difference RMS
2924 #Phase Difference RMS
2925 arrayPhaseRMS = numpy.abs(phaseDiff)
2925 arrayPhaseRMS = numpy.abs(phaseDiff)
2926 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
2926 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
2927 indPhase = numpy.where(phaseRMSaux==4)
2927 indPhase = numpy.where(phaseRMSaux==4)
2928 #Shifting
2928 #Shifting
2929 if indPhase[0].shape[0] > 0:
2929 if indPhase[0].shape[0] > 0:
2930 for j in range(indSides.size):
2930 for j in range(indSides.size):
2931 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
2931 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
2932 voltsCohDet[:,startInd:endInd,:] = arrayBlock
2932 voltsCohDet[:,startInd:endInd,:] = arrayBlock
2933
2933
2934 return voltsCohDet
2934 return voltsCohDet
2935
2935
2936 def __calculateCCF(self, volts, pairslist ,laglist):
2936 def __calculateCCF(self, volts, pairslist ,laglist):
2937
2937
2938 nHeights = volts.shape[2]
2938 nHeights = volts.shape[2]
2939 nPoints = volts.shape[1]
2939 nPoints = volts.shape[1]
2940 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
2940 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
2941
2941
2942 for i in range(len(pairslist)):
2942 for i in range(len(pairslist)):
2943 volts1 = volts[pairslist[i][0]]
2943 volts1 = volts[pairslist[i][0]]
2944 volts2 = volts[pairslist[i][1]]
2944 volts2 = volts[pairslist[i][1]]
2945
2945
2946 for t in range(len(laglist)):
2946 for t in range(len(laglist)):
2947 idxT = laglist[t]
2947 idxT = laglist[t]
2948 if idxT >= 0:
2948 if idxT >= 0:
2949 vStacked = numpy.vstack((volts2[idxT:,:],
2949 vStacked = numpy.vstack((volts2[idxT:,:],
2950 numpy.zeros((idxT, nHeights),dtype='complex')))
2950 numpy.zeros((idxT, nHeights),dtype='complex')))
2951 else:
2951 else:
2952 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
2952 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
2953 volts2[:(nPoints + idxT),:]))
2953 volts2[:(nPoints + idxT),:]))
2954 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
2954 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
2955
2955
2956 vStacked = None
2956 vStacked = None
2957 return voltsCCF
2957 return voltsCCF
2958
2958
2959 def __getNoise(self, power, timeSegment, timeInterval):
2959 def __getNoise(self, power, timeSegment, timeInterval):
2960 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
2960 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
2961 numBlocks = int(power.shape[0]/numProfPerBlock)
2961 numBlocks = int(power.shape[0]/numProfPerBlock)
2962 numHeights = power.shape[1]
2962 numHeights = power.shape[1]
2963
2963
2964 listPower = numpy.array_split(power, numBlocks, 0)
2964 listPower = numpy.array_split(power, numBlocks, 0)
2965 noise = numpy.zeros((power.shape[0], power.shape[1]))
2965 noise = numpy.zeros((power.shape[0], power.shape[1]))
2966 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
2966 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
2967
2967
2968 startInd = 0
2968 startInd = 0
2969 endInd = 0
2969 endInd = 0
2970
2970
2971 for i in range(numBlocks): #split por canal
2971 for i in range(numBlocks): #split por canal
2972 startInd = endInd
2972 startInd = endInd
2973 endInd = endInd + listPower[i].shape[0]
2973 endInd = endInd + listPower[i].shape[0]
2974
2974
2975 arrayBlock = listPower[i]
2975 arrayBlock = listPower[i]
2976 noiseAux = numpy.mean(arrayBlock, 0)
2976 noiseAux = numpy.mean(arrayBlock, 0)
2977 # noiseAux = numpy.median(noiseAux)
2977 # noiseAux = numpy.median(noiseAux)
2978 # noiseAux = numpy.mean(arrayBlock)
2978 # noiseAux = numpy.mean(arrayBlock)
2979 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
2979 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
2980
2980
2981 noiseAux1 = numpy.mean(arrayBlock)
2981 noiseAux1 = numpy.mean(arrayBlock)
2982 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
2982 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
2983
2983
2984 return noise, noise1
2984 return noise, noise1
2985
2985
2986 def __findMeteors(self, power, thresh):
2986 def __findMeteors(self, power, thresh):
2987 nProf = power.shape[0]
2987 nProf = power.shape[0]
2988 nHeights = power.shape[1]
2988 nHeights = power.shape[1]
2989 listMeteors = []
2989 listMeteors = []
2990
2990
2991 for i in range(nHeights):
2991 for i in range(nHeights):
2992 powerAux = power[:,i]
2992 powerAux = power[:,i]
2993 threshAux = thresh[:,i]
2993 threshAux = thresh[:,i]
2994
2994
2995 indUPthresh = numpy.where(powerAux > threshAux)[0]
2995 indUPthresh = numpy.where(powerAux > threshAux)[0]
2996 indDNthresh = numpy.where(powerAux <= threshAux)[0]
2996 indDNthresh = numpy.where(powerAux <= threshAux)[0]
2997
2997
2998 j = 0
2998 j = 0
2999
2999
3000 while (j < indUPthresh.size - 2):
3000 while (j < indUPthresh.size - 2):
3001 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
3001 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
3002 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
3002 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
3003 indDNthresh = indDNthresh[indDNAux]
3003 indDNthresh = indDNthresh[indDNAux]
3004
3004
3005 if (indDNthresh.size > 0):
3005 if (indDNthresh.size > 0):
3006 indEnd = indDNthresh[0] - 1
3006 indEnd = indDNthresh[0] - 1
3007 indInit = indUPthresh[j]
3007 indInit = indUPthresh[j]
3008
3008
3009 meteor = powerAux[indInit:indEnd + 1]
3009 meteor = powerAux[indInit:indEnd + 1]
3010 indPeak = meteor.argmax() + indInit
3010 indPeak = meteor.argmax() + indInit
3011 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
3011 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
3012
3012
3013 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
3013 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
3014 j = numpy.where(indUPthresh == indEnd)[0] + 1
3014 j = numpy.where(indUPthresh == indEnd)[0] + 1
3015 else: j+=1
3015 else: j+=1
3016 else: j+=1
3016 else: j+=1
3017
3017
3018 return listMeteors
3018 return listMeteors
3019
3019
3020 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
3020 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
3021
3021
3022 arrayMeteors = numpy.asarray(listMeteors)
3022 arrayMeteors = numpy.asarray(listMeteors)
3023 listMeteors1 = []
3023 listMeteors1 = []
3024
3024
3025 while arrayMeteors.shape[0] > 0:
3025 while arrayMeteors.shape[0] > 0:
3026 FLAs = arrayMeteors[:,4]
3026 FLAs = arrayMeteors[:,4]
3027 maxFLA = FLAs.argmax()
3027 maxFLA = FLAs.argmax()
3028 listMeteors1.append(arrayMeteors[maxFLA,:])
3028 listMeteors1.append(arrayMeteors[maxFLA,:])
3029
3029
3030 MeteorInitTime = arrayMeteors[maxFLA,1]
3030 MeteorInitTime = arrayMeteors[maxFLA,1]
3031 MeteorEndTime = arrayMeteors[maxFLA,3]
3031 MeteorEndTime = arrayMeteors[maxFLA,3]
3032 MeteorHeight = arrayMeteors[maxFLA,0]
3032 MeteorHeight = arrayMeteors[maxFLA,0]
3033
3033
3034 #Check neighborhood
3034 #Check neighborhood
3035 maxHeightIndex = MeteorHeight + rangeLimit
3035 maxHeightIndex = MeteorHeight + rangeLimit
3036 minHeightIndex = MeteorHeight - rangeLimit
3036 minHeightIndex = MeteorHeight - rangeLimit
3037 minTimeIndex = MeteorInitTime - timeLimit
3037 minTimeIndex = MeteorInitTime - timeLimit
3038 maxTimeIndex = MeteorEndTime + timeLimit
3038 maxTimeIndex = MeteorEndTime + timeLimit
3039
3039
3040 #Check Heights
3040 #Check Heights
3041 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
3041 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
3042 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
3042 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
3043 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
3043 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
3044
3044
3045 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
3045 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
3046
3046
3047 return listMeteors1
3047 return listMeteors1
3048
3048
3049 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
3049 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
3050 numHeights = volts.shape[2]
3050 numHeights = volts.shape[2]
3051 nChannel = volts.shape[0]
3051 nChannel = volts.shape[0]
3052
3052
3053 thresholdPhase = thresh[0]
3053 thresholdPhase = thresh[0]
3054 thresholdNoise = thresh[1]
3054 thresholdNoise = thresh[1]
3055 thresholdDB = float(thresh[2])
3055 thresholdDB = float(thresh[2])
3056
3056
3057 thresholdDB1 = 10**(thresholdDB/10)
3057 thresholdDB1 = 10**(thresholdDB/10)
3058 pairsarray = numpy.array(pairslist)
3058 pairsarray = numpy.array(pairslist)
3059 indSides = pairsarray[:,1]
3059 indSides = pairsarray[:,1]
3060
3060
3061 pairslist1 = list(pairslist)
3061 pairslist1 = list(pairslist)
3062 pairslist1.append((0,1))
3062 pairslist1.append((0,1))
3063 pairslist1.append((3,4))
3063 pairslist1.append((3,4))
3064
3064
3065 listMeteors1 = []
3065 listMeteors1 = []
3066 listPowerSeries = []
3066 listPowerSeries = []
3067 listVoltageSeries = []
3067 listVoltageSeries = []
3068 #volts has the war data
3068 #volts has the war data
3069
3069
3070 if frequency == 30e6:
3070 if frequency == 30e6:
3071 timeLag = 45*10**-3
3071 timeLag = 45*10**-3
3072 else:
3072 else:
3073 timeLag = 15*10**-3
3073 timeLag = 15*10**-3
3074 lag = numpy.ceil(timeLag/timeInterval)
3074 lag = numpy.ceil(timeLag/timeInterval)
3075
3075
3076 for i in range(len(listMeteors)):
3076 for i in range(len(listMeteors)):
3077
3077
3078 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
3078 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
3079 meteorAux = numpy.zeros(16)
3079 meteorAux = numpy.zeros(16)
3080
3080
3081 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
3081 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
3082 mHeight = listMeteors[i][0]
3082 mHeight = listMeteors[i][0]
3083 mStart = listMeteors[i][1]
3083 mStart = listMeteors[i][1]
3084 mPeak = listMeteors[i][2]
3084 mPeak = listMeteors[i][2]
3085 mEnd = listMeteors[i][3]
3085 mEnd = listMeteors[i][3]
3086
3086
3087 #get the volt data between the start and end times of the meteor
3087 #get the volt data between the start and end times of the meteor
3088 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
3088 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
3089 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3089 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3090
3090
3091 #3.6. Phase Difference estimation
3091 #3.6. Phase Difference estimation
3092 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
3092 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
3093
3093
3094 #3.7. Phase difference removal & meteor start, peak and end times reestimated
3094 #3.7. Phase difference removal & meteor start, peak and end times reestimated
3095 #meteorVolts0.- all Channels, all Profiles
3095 #meteorVolts0.- all Channels, all Profiles
3096 meteorVolts0 = volts[:,:,mHeight]
3096 meteorVolts0 = volts[:,:,mHeight]
3097 meteorThresh = noise[:,mHeight]*thresholdNoise
3097 meteorThresh = noise[:,mHeight]*thresholdNoise
3098 meteorNoise = noise[:,mHeight]
3098 meteorNoise = noise[:,mHeight]
3099 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
3099 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
3100 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
3100 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
3101
3101
3102 #Times reestimation
3102 #Times reestimation
3103 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
3103 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
3104 if mStart1.size > 0:
3104 if mStart1.size > 0:
3105 mStart1 = mStart1[-1] + 1
3105 mStart1 = mStart1[-1] + 1
3106
3106
3107 else:
3107 else:
3108 mStart1 = mPeak
3108 mStart1 = mPeak
3109
3109
3110 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
3110 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
3111 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
3111 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
3112 if mEndDecayTime1.size == 0:
3112 if mEndDecayTime1.size == 0:
3113 mEndDecayTime1 = powerNet0.size
3113 mEndDecayTime1 = powerNet0.size
3114 else:
3114 else:
3115 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
3115 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
3116 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
3116 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
3117
3117
3118 #meteorVolts1.- all Channels, from start to end
3118 #meteorVolts1.- all Channels, from start to end
3119 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
3119 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
3120 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
3120 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
3121 if meteorVolts2.shape[1] == 0:
3121 if meteorVolts2.shape[1] == 0:
3122 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
3122 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
3123 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
3123 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
3124 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
3124 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
3125 ##################### END PARAMETERS REESTIMATION #########################
3125 ##################### END PARAMETERS REESTIMATION #########################
3126
3126
3127 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
3127 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
3128 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
3128 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
3129 if meteorVolts2.shape[1] > 0:
3129 if meteorVolts2.shape[1] > 0:
3130 #Phase Difference re-estimation
3130 #Phase Difference re-estimation
3131 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
3131 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
3132 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
3132 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
3133 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
3133 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
3134 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
3134 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
3135 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
3135 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
3136
3136
3137 #Phase Difference RMS
3137 #Phase Difference RMS
3138 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
3138 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
3139 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
3139 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
3140 #Data from Meteor
3140 #Data from Meteor
3141 mPeak1 = powerNet1.argmax() + mStart1
3141 mPeak1 = powerNet1.argmax() + mStart1
3142 mPeakPower1 = powerNet1.max()
3142 mPeakPower1 = powerNet1.max()
3143 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
3143 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
3144 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
3144 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
3145 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
3145 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
3146 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
3146 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
3147 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
3147 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
3148 #Vectorize
3148 #Vectorize
3149 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
3149 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
3150 meteorAux[7:11] = phaseDiffint[0:4]
3150 meteorAux[7:11] = phaseDiffint[0:4]
3151
3151
3152 #Rejection Criterions
3152 #Rejection Criterions
3153 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
3153 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
3154 meteorAux[-1] = 17
3154 meteorAux[-1] = 17
3155 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
3155 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
3156 meteorAux[-1] = 1
3156 meteorAux[-1] = 1
3157
3157
3158
3158
3159 else:
3159 else:
3160 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
3160 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
3161 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
3161 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
3162 PowerSeries = 0
3162 PowerSeries = 0
3163
3163
3164 listMeteors1.append(meteorAux)
3164 listMeteors1.append(meteorAux)
3165 listPowerSeries.append(PowerSeries)
3165 listPowerSeries.append(PowerSeries)
3166 listVoltageSeries.append(meteorVolts1)
3166 listVoltageSeries.append(meteorVolts1)
3167
3167
3168 return listMeteors1, listPowerSeries, listVoltageSeries
3168 return listMeteors1, listPowerSeries, listVoltageSeries
3169
3169
3170 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
3170 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
3171
3171
3172 threshError = 10
3172 threshError = 10
3173 #Depending if it is 30 or 50 MHz
3173 #Depending if it is 30 or 50 MHz
3174 if frequency == 30e6:
3174 if frequency == 30e6:
3175 timeLag = 45*10**-3
3175 timeLag = 45*10**-3
3176 else:
3176 else:
3177 timeLag = 15*10**-3
3177 timeLag = 15*10**-3
3178 lag = numpy.ceil(timeLag/timeInterval)
3178 lag = numpy.ceil(timeLag/timeInterval)
3179
3179
3180 listMeteors1 = []
3180 listMeteors1 = []
3181
3181
3182 for i in range(len(listMeteors)):
3182 for i in range(len(listMeteors)):
3183 meteorPower = listPower[i]
3183 meteorPower = listPower[i]
3184 meteorAux = listMeteors[i]
3184 meteorAux = listMeteors[i]
3185
3185
3186 if meteorAux[-1] == 0:
3186 if meteorAux[-1] == 0:
3187
3187
3188 try:
3188 try:
3189 indmax = meteorPower.argmax()
3189 indmax = meteorPower.argmax()
3190 indlag = indmax + lag
3190 indlag = indmax + lag
3191
3191
3192 y = meteorPower[indlag:]
3192 y = meteorPower[indlag:]
3193 x = numpy.arange(0, y.size)*timeLag
3193 x = numpy.arange(0, y.size)*timeLag
3194
3194
3195 #first guess
3195 #first guess
3196 a = y[0]
3196 a = y[0]
3197 tau = timeLag
3197 tau = timeLag
3198 #exponential fit
3198 #exponential fit
3199 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
3199 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
3200 y1 = self.__exponential_function(x, *popt)
3200 y1 = self.__exponential_function(x, *popt)
3201 #error estimation
3201 #error estimation
3202 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
3202 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
3203
3203
3204 decayTime = popt[1]
3204 decayTime = popt[1]
3205 riseTime = indmax*timeInterval
3205 riseTime = indmax*timeInterval
3206 meteorAux[11:13] = [decayTime, error]
3206 meteorAux[11:13] = [decayTime, error]
3207
3207
3208 #Table items 7, 8 and 11
3208 #Table items 7, 8 and 11
3209 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
3209 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
3210 meteorAux[-1] = 7
3210 meteorAux[-1] = 7
3211 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
3211 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
3212 meteorAux[-1] = 8
3212 meteorAux[-1] = 8
3213 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
3213 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
3214 meteorAux[-1] = 11
3214 meteorAux[-1] = 11
3215
3215
3216
3216
3217 except:
3217 except:
3218 meteorAux[-1] = 11
3218 meteorAux[-1] = 11
3219
3219
3220
3220
3221 listMeteors1.append(meteorAux)
3221 listMeteors1.append(meteorAux)
3222
3222
3223 return listMeteors1
3223 return listMeteors1
3224
3224
3225 #Exponential Function
3225 #Exponential Function
3226
3226
3227 def __exponential_function(self, x, a, tau):
3227 def __exponential_function(self, x, a, tau):
3228 y = a*numpy.exp(-x/tau)
3228 y = a*numpy.exp(-x/tau)
3229 return y
3229 return y
3230
3230
3231 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
3231 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
3232
3232
3233 pairslist1 = list(pairslist)
3233 pairslist1 = list(pairslist)
3234 pairslist1.append((0,1))
3234 pairslist1.append((0,1))
3235 pairslist1.append((3,4))
3235 pairslist1.append((3,4))
3236 numPairs = len(pairslist1)
3236 numPairs = len(pairslist1)
3237 #Time Lag
3237 #Time Lag
3238 timeLag = 45*10**-3
3238 timeLag = 45*10**-3
3239 c = 3e8
3239 c = 3e8
3240 lag = numpy.ceil(timeLag/timeInterval)
3240 lag = numpy.ceil(timeLag/timeInterval)
3241 freq = 30e6
3241 freq = 30e6
3242
3242
3243 listMeteors1 = []
3243 listMeteors1 = []
3244
3244
3245 for i in range(len(listMeteors)):
3245 for i in range(len(listMeteors)):
3246 meteorAux = listMeteors[i]
3246 meteorAux = listMeteors[i]
3247 if meteorAux[-1] == 0:
3247 if meteorAux[-1] == 0:
3248 mStart = listMeteors[i][1]
3248 mStart = listMeteors[i][1]
3249 mPeak = listMeteors[i][2]
3249 mPeak = listMeteors[i][2]
3250 mLag = mPeak - mStart + lag
3250 mLag = mPeak - mStart + lag
3251
3251
3252 #get the volt data between the start and end times of the meteor
3252 #get the volt data between the start and end times of the meteor
3253 meteorVolts = listVolts[i]
3253 meteorVolts = listVolts[i]
3254 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3254 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3255
3255
3256 #Get CCF
3256 #Get CCF
3257 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
3257 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
3258
3258
3259 #Method 2
3259 #Method 2
3260 slopes = numpy.zeros(numPairs)
3260 slopes = numpy.zeros(numPairs)
3261 time = numpy.array([-2,-1,1,2])*timeInterval
3261 time = numpy.array([-2,-1,1,2])*timeInterval
3262 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
3262 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
3263
3263
3264 #Correct phases
3264 #Correct phases
3265 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
3265 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
3266 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
3266 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
3267
3267
3268 if indDer[0].shape[0] > 0:
3268 if indDer[0].shape[0] > 0:
3269 for i in range(indDer[0].shape[0]):
3269 for i in range(indDer[0].shape[0]):
3270 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
3270 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
3271 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
3271 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
3272
3272
3273 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
3273 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
3274 for j in range(numPairs):
3274 for j in range(numPairs):
3275 fit = stats.linregress(time, angAllCCF[j,:])
3275 fit = stats.linregress(time, angAllCCF[j,:])
3276 slopes[j] = fit[0]
3276 slopes[j] = fit[0]
3277
3277
3278 #Remove Outlier
3278 #Remove Outlier
3279 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3279 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3280 # slopes = numpy.delete(slopes,indOut)
3280 # slopes = numpy.delete(slopes,indOut)
3281 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3281 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3282 # slopes = numpy.delete(slopes,indOut)
3282 # slopes = numpy.delete(slopes,indOut)
3283
3283
3284 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
3284 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
3285 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
3285 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
3286 meteorAux[-2] = radialError
3286 meteorAux[-2] = radialError
3287 meteorAux[-3] = radialVelocity
3287 meteorAux[-3] = radialVelocity
3288
3288
3289 #Setting Error
3289 #Setting Error
3290 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
3290 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
3291 if numpy.abs(radialVelocity) > 200:
3291 if numpy.abs(radialVelocity) > 200:
3292 meteorAux[-1] = 15
3292 meteorAux[-1] = 15
3293 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
3293 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
3294 elif radialError > radialStdThresh:
3294 elif radialError > radialStdThresh:
3295 meteorAux[-1] = 12
3295 meteorAux[-1] = 12
3296
3296
3297 listMeteors1.append(meteorAux)
3297 listMeteors1.append(meteorAux)
3298 return listMeteors1
3298 return listMeteors1
3299
3299
3300 def __setNewArrays(self, listMeteors, date, heiRang):
3300 def __setNewArrays(self, listMeteors, date, heiRang):
3301
3301
3302 #New arrays
3302 #New arrays
3303 arrayMeteors = numpy.array(listMeteors)
3303 arrayMeteors = numpy.array(listMeteors)
3304 arrayParameters = numpy.zeros((len(listMeteors), 13))
3304 arrayParameters = numpy.zeros((len(listMeteors), 13))
3305
3305
3306 #Date inclusion
3306 #Date inclusion
3307 # date = re.findall(r'\((.*?)\)', date)
3307 # date = re.findall(r'\((.*?)\)', date)
3308 # date = date[0].split(',')
3308 # date = date[0].split(',')
3309 # date = map(int, date)
3309 # date = map(int, date)
3310 #
3310 #
3311 # if len(date)<6:
3311 # if len(date)<6:
3312 # date.append(0)
3312 # date.append(0)
3313 #
3313 #
3314 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
3314 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
3315 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
3315 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
3316 arrayDate = numpy.tile(date, (len(listMeteors)))
3316 arrayDate = numpy.tile(date, (len(listMeteors)))
3317
3317
3318 #Meteor array
3318 #Meteor array
3319 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
3319 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
3320 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
3320 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
3321
3321
3322 #Parameters Array
3322 #Parameters Array
3323 arrayParameters[:,0] = arrayDate #Date
3323 arrayParameters[:,0] = arrayDate #Date
3324 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
3324 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
3325 arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
3325 arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
3326 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
3326 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
3327 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
3327 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
3328
3328
3329
3329
3330 return arrayParameters
3330 return arrayParameters
3331
3331
3332 class CorrectSMPhases(Operation):
3332 class CorrectSMPhases(Operation):
3333
3333
3334 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
3334 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
3335
3335
3336 arrayParameters = dataOut.data_param
3336 arrayParameters = dataOut.data_param
3337 pairsList = []
3337 pairsList = []
3338 pairx = (0,1)
3338 pairx = (0,1)
3339 pairy = (2,3)
3339 pairy = (2,3)
3340 pairsList.append(pairx)
3340 pairsList.append(pairx)
3341 pairsList.append(pairy)
3341 pairsList.append(pairy)
3342 jph = numpy.zeros(4)
3342 jph = numpy.zeros(4)
3343
3343
3344 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
3344 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
3345 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
3345 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
3346 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
3346 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
3347
3347
3348 meteorOps = SMOperations()
3348 meteorOps = SMOperations()
3349 if channelPositions is None:
3349 if channelPositions is None:
3350 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3350 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3351 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3351 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3352
3352
3353 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3353 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3354 h = (hmin,hmax)
3354 h = (hmin,hmax)
3355
3355
3356 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
3356 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
3357
3357
3358 dataOut.data_param = arrayParameters
3358 dataOut.data_param = arrayParameters
3359 return
3359 return
3360
3360
3361 class SMPhaseCalibration(Operation):
3361 class SMPhaseCalibration(Operation):
3362
3362
3363 __buffer = None
3363 __buffer = None
3364
3364
3365 __initime = None
3365 __initime = None
3366
3366
3367 __dataReady = False
3367 __dataReady = False
3368
3368
3369 __isConfig = False
3369 __isConfig = False
3370
3370
3371 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
3371 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
3372
3372
3373 dataTime = currentTime + paramInterval
3373 dataTime = currentTime + paramInterval
3374 deltaTime = dataTime - initTime
3374 deltaTime = dataTime - initTime
3375
3375
3376 if deltaTime >= outputInterval or deltaTime < 0:
3376 if deltaTime >= outputInterval or deltaTime < 0:
3377 return True
3377 return True
3378
3378
3379 return False
3379 return False
3380
3380
3381 def __getGammas(self, pairs, d, phases):
3381 def __getGammas(self, pairs, d, phases):
3382 gammas = numpy.zeros(2)
3382 gammas = numpy.zeros(2)
3383
3383
3384 for i in range(len(pairs)):
3384 for i in range(len(pairs)):
3385
3385
3386 pairi = pairs[i]
3386 pairi = pairs[i]
3387
3387
3388 phip3 = phases[:,pairi[0]]
3388 phip3 = phases[:,pairi[0]]
3389 d3 = d[pairi[0]]
3389 d3 = d[pairi[0]]
3390 phip2 = phases[:,pairi[1]]
3390 phip2 = phases[:,pairi[1]]
3391 d2 = d[pairi[1]]
3391 d2 = d[pairi[1]]
3392 #Calculating gamma
3392 #Calculating gamma
3393 # jdcos = alp1/(k*d1)
3393 # jdcos = alp1/(k*d1)
3394 # jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0)))
3394 # jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0)))
3395 jgamma = -phip2*d3/d2 - phip3
3395 jgamma = -phip2*d3/d2 - phip3
3396 jgamma = numpy.angle(numpy.exp(1j*jgamma))
3396 jgamma = numpy.angle(numpy.exp(1j*jgamma))
3397 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
3397 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
3398 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
3398 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
3399
3399
3400 #Revised distribution
3400 #Revised distribution
3401 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
3401 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
3402
3402
3403 #Histogram
3403 #Histogram
3404 nBins = 64
3404 nBins = 64
3405 rmin = -0.5*numpy.pi
3405 rmin = -0.5*numpy.pi
3406 rmax = 0.5*numpy.pi
3406 rmax = 0.5*numpy.pi
3407 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
3407 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
3408
3408
3409 meteorsY = phaseHisto[0]
3409 meteorsY = phaseHisto[0]
3410 phasesX = phaseHisto[1][:-1]
3410 phasesX = phaseHisto[1][:-1]
3411 width = phasesX[1] - phasesX[0]
3411 width = phasesX[1] - phasesX[0]
3412 phasesX += width/2
3412 phasesX += width/2
3413
3413
3414 #Gaussian aproximation
3414 #Gaussian aproximation
3415 bpeak = meteorsY.argmax()
3415 bpeak = meteorsY.argmax()
3416 peak = meteorsY.max()
3416 peak = meteorsY.max()
3417 jmin = bpeak - 5
3417 jmin = bpeak - 5
3418 jmax = bpeak + 5 + 1
3418 jmax = bpeak + 5 + 1
3419
3419
3420 if jmin<0:
3420 if jmin<0:
3421 jmin = 0
3421 jmin = 0
3422 jmax = 6
3422 jmax = 6
3423 elif jmax > meteorsY.size:
3423 elif jmax > meteorsY.size:
3424 jmin = meteorsY.size - 6
3424 jmin = meteorsY.size - 6
3425 jmax = meteorsY.size
3425 jmax = meteorsY.size
3426
3426
3427 x0 = numpy.array([peak,bpeak,50])
3427 x0 = numpy.array([peak,bpeak,50])
3428 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
3428 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
3429
3429
3430 #Gammas
3430 #Gammas
3431 gammas[i] = coeff[0][1]
3431 gammas[i] = coeff[0][1]
3432
3432
3433 return gammas
3433 return gammas
3434
3434
3435 def __residualFunction(self, coeffs, y, t):
3435 def __residualFunction(self, coeffs, y, t):
3436
3436
3437 return y - self.__gauss_function(t, coeffs)
3437 return y - self.__gauss_function(t, coeffs)
3438
3438
3439 def __gauss_function(self, t, coeffs):
3439 def __gauss_function(self, t, coeffs):
3440
3440
3441 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
3441 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
3442
3442
3443 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
3443 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
3444 meteorOps = SMOperations()
3444 meteorOps = SMOperations()
3445 nchan = 4
3445 nchan = 4
3446 pairx = pairsList[0] #x es 0
3446 pairx = pairsList[0] #x es 0
3447 pairy = pairsList[1] #y es 1
3447 pairy = pairsList[1] #y es 1
3448 center_xangle = 0
3448 center_xangle = 0
3449 center_yangle = 0
3449 center_yangle = 0
3450 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
3450 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
3451 ntimes = len(range_angle)
3451 ntimes = len(range_angle)
3452
3452
3453 nstepsx = 20
3453 nstepsx = 20
3454 nstepsy = 20
3454 nstepsy = 20
3455
3455
3456 for iz in range(ntimes):
3456 for iz in range(ntimes):
3457 min_xangle = -range_angle[iz]/2 + center_xangle
3457 min_xangle = -range_angle[iz]/2 + center_xangle
3458 max_xangle = range_angle[iz]/2 + center_xangle
3458 max_xangle = range_angle[iz]/2 + center_xangle
3459 min_yangle = -range_angle[iz]/2 + center_yangle
3459 min_yangle = -range_angle[iz]/2 + center_yangle
3460 max_yangle = range_angle[iz]/2 + center_yangle
3460 max_yangle = range_angle[iz]/2 + center_yangle
3461
3461
3462 inc_x = (max_xangle-min_xangle)/nstepsx
3462 inc_x = (max_xangle-min_xangle)/nstepsx
3463 inc_y = (max_yangle-min_yangle)/nstepsy
3463 inc_y = (max_yangle-min_yangle)/nstepsy
3464
3464
3465 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
3465 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
3466 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
3466 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
3467 penalty = numpy.zeros((nstepsx,nstepsy))
3467 penalty = numpy.zeros((nstepsx,nstepsy))
3468 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
3468 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
3469 jph = numpy.zeros(nchan)
3469 jph = numpy.zeros(nchan)
3470
3470
3471 # Iterations looking for the offset
3471 # Iterations looking for the offset
3472 for iy in range(int(nstepsy)):
3472 for iy in range(int(nstepsy)):
3473 for ix in range(int(nstepsx)):
3473 for ix in range(int(nstepsx)):
3474 d3 = d[pairsList[1][0]]
3474 d3 = d[pairsList[1][0]]
3475 d2 = d[pairsList[1][1]]
3475 d2 = d[pairsList[1][1]]
3476 d5 = d[pairsList[0][0]]
3476 d5 = d[pairsList[0][0]]
3477 d4 = d[pairsList[0][1]]
3477 d4 = d[pairsList[0][1]]
3478
3478
3479 alp2 = alpha_y[iy] #gamma 1
3479 alp2 = alpha_y[iy] #gamma 1
3480 alp4 = alpha_x[ix] #gamma 0
3480 alp4 = alpha_x[ix] #gamma 0
3481
3481
3482 alp3 = -alp2*d3/d2 - gammas[1]
3482 alp3 = -alp2*d3/d2 - gammas[1]
3483 alp5 = -alp4*d5/d4 - gammas[0]
3483 alp5 = -alp4*d5/d4 - gammas[0]
3484 # jph[pairy[1]] = alpha_y[iy]
3484 # jph[pairy[1]] = alpha_y[iy]
3485 # jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
3485 # jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
3486
3486
3487 # jph[pairx[1]] = alpha_x[ix]
3487 # jph[pairx[1]] = alpha_x[ix]
3488 # jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
3488 # jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
3489 jph[pairsList[0][1]] = alp4
3489 jph[pairsList[0][1]] = alp4
3490 jph[pairsList[0][0]] = alp5
3490 jph[pairsList[0][0]] = alp5
3491 jph[pairsList[1][0]] = alp3
3491 jph[pairsList[1][0]] = alp3
3492 jph[pairsList[1][1]] = alp2
3492 jph[pairsList[1][1]] = alp2
3493 jph_array[:,ix,iy] = jph
3493 jph_array[:,ix,iy] = jph
3494 # d = [2.0,2.5,2.5,2.0]
3494 # d = [2.0,2.5,2.5,2.0]
3495 #falta chequear si va a leer bien los meteoros
3495 #falta chequear si va a leer bien los meteoros
3496 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
3496 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
3497 error = meteorsArray1[:,-1]
3497 error = meteorsArray1[:,-1]
3498 ind1 = numpy.where(error==0)[0]
3498 ind1 = numpy.where(error==0)[0]
3499 penalty[ix,iy] = ind1.size
3499 penalty[ix,iy] = ind1.size
3500
3500
3501 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
3501 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
3502 phOffset = jph_array[:,i,j]
3502 phOffset = jph_array[:,i,j]
3503
3503
3504 center_xangle = phOffset[pairx[1]]
3504 center_xangle = phOffset[pairx[1]]
3505 center_yangle = phOffset[pairy[1]]
3505 center_yangle = phOffset[pairy[1]]
3506
3506
3507 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
3507 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
3508 phOffset = phOffset*180/numpy.pi
3508 phOffset = phOffset*180/numpy.pi
3509 return phOffset
3509 return phOffset
3510
3510
3511
3511
3512 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
3512 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
3513
3513
3514 dataOut.flagNoData = True
3514 dataOut.flagNoData = True
3515 self.__dataReady = False
3515 self.__dataReady = False
3516 dataOut.outputInterval = nHours*3600
3516 dataOut.outputInterval = nHours*3600
3517
3517
3518 if self.__isConfig == False:
3518 if self.__isConfig == False:
3519 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
3519 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
3520 #Get Initial LTC time
3520 #Get Initial LTC time
3521 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
3521 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
3522 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
3522 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
3523
3523
3524 self.__isConfig = True
3524 self.__isConfig = True
3525
3525
3526 if self.__buffer is None:
3526 if self.__buffer is None:
3527 self.__buffer = dataOut.data_param.copy()
3527 self.__buffer = dataOut.data_param.copy()
3528
3528
3529 else:
3529 else:
3530 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
3530 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
3531
3531
3532 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
3532 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
3533
3533
3534 if self.__dataReady:
3534 if self.__dataReady:
3535 dataOut.utctimeInit = self.__initime
3535 dataOut.utctimeInit = self.__initime
3536 self.__initime += dataOut.outputInterval #to erase time offset
3536 self.__initime += dataOut.outputInterval #to erase time offset
3537
3537
3538 freq = dataOut.frequency
3538 freq = dataOut.frequency
3539 c = dataOut.C #m/s
3539 c = dataOut.C #m/s
3540 lamb = c/freq
3540 lamb = c/freq
3541 k = 2*numpy.pi/lamb
3541 k = 2*numpy.pi/lamb
3542 azimuth = 0
3542 azimuth = 0
3543 h = (hmin, hmax)
3543 h = (hmin, hmax)
3544 # pairs = ((0,1),(2,3)) #Estrella
3544 # pairs = ((0,1),(2,3)) #Estrella
3545 # pairs = ((1,0),(2,3)) #T
3545 # pairs = ((1,0),(2,3)) #T
3546
3546
3547 if channelPositions is None:
3547 if channelPositions is None:
3548 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3548 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3549 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3549 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3550 meteorOps = SMOperations()
3550 meteorOps = SMOperations()
3551 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3551 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3552
3552
3553 #Checking correct order of pairs
3553 #Checking correct order of pairs
3554 pairs = []
3554 pairs = []
3555 if distances[1] > distances[0]:
3555 if distances[1] > distances[0]:
3556 pairs.append((1,0))
3556 pairs.append((1,0))
3557 else:
3557 else:
3558 pairs.append((0,1))
3558 pairs.append((0,1))
3559
3559
3560 if distances[3] > distances[2]:
3560 if distances[3] > distances[2]:
3561 pairs.append((3,2))
3561 pairs.append((3,2))
3562 else:
3562 else:
3563 pairs.append((2,3))
3563 pairs.append((2,3))
3564 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
3564 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
3565
3565
3566 meteorsArray = self.__buffer
3566 meteorsArray = self.__buffer
3567 error = meteorsArray[:,-1]
3567 error = meteorsArray[:,-1]
3568 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
3568 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
3569 ind1 = numpy.where(boolError)[0]
3569 ind1 = numpy.where(boolError)[0]
3570 meteorsArray = meteorsArray[ind1,:]
3570 meteorsArray = meteorsArray[ind1,:]
3571 meteorsArray[:,-1] = 0
3571 meteorsArray[:,-1] = 0
3572 phases = meteorsArray[:,8:12]
3572 phases = meteorsArray[:,8:12]
3573
3573
3574 #Calculate Gammas
3574 #Calculate Gammas
3575 gammas = self.__getGammas(pairs, distances, phases)
3575 gammas = self.__getGammas(pairs, distances, phases)
3576 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
3576 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
3577 #Calculate Phases
3577 #Calculate Phases
3578 phasesOff = self.__getPhases(azimuth, h, pairs, distances, gammas, meteorsArray)
3578 phasesOff = self.__getPhases(azimuth, h, pairs, distances, gammas, meteorsArray)
3579 phasesOff = phasesOff.reshape((1,phasesOff.size))
3579 phasesOff = phasesOff.reshape((1,phasesOff.size))
3580 dataOut.data_output = -phasesOff
3580 dataOut.data_output = -phasesOff
3581 dataOut.flagNoData = False
3581 dataOut.flagNoData = False
3582 self.__buffer = None
3582 self.__buffer = None
3583
3583
3584
3584
3585 return
3585 return
3586
3586
3587 class SMOperations():
3587 class SMOperations():
3588
3588
3589 def __init__(self):
3589 def __init__(self):
3590
3590
3591 return
3591 return
3592
3592
3593 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
3593 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
3594
3594
3595 arrayParameters = arrayParameters0.copy()
3595 arrayParameters = arrayParameters0.copy()
3596 hmin = h[0]
3596 hmin = h[0]
3597 hmax = h[1]
3597 hmax = h[1]
3598
3598
3599 #Calculate AOA (Error N 3, 4)
3599 #Calculate AOA (Error N 3, 4)
3600 #JONES ET AL. 1998
3600 #JONES ET AL. 1998
3601 AOAthresh = numpy.pi/8
3601 AOAthresh = numpy.pi/8
3602 error = arrayParameters[:,-1]
3602 error = arrayParameters[:,-1]
3603 phases = -arrayParameters[:,8:12] + jph
3603 phases = -arrayParameters[:,8:12] + jph
3604 # phases = numpy.unwrap(phases)
3604 # phases = numpy.unwrap(phases)
3605 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
3605 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
3606
3606
3607 #Calculate Heights (Error N 13 and 14)
3607 #Calculate Heights (Error N 13 and 14)
3608 error = arrayParameters[:,-1]
3608 error = arrayParameters[:,-1]
3609 Ranges = arrayParameters[:,1]
3609 Ranges = arrayParameters[:,1]
3610 zenith = arrayParameters[:,4]
3610 zenith = arrayParameters[:,4]
3611 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
3611 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
3612
3612
3613 #----------------------- Get Final data ------------------------------------
3613 #----------------------- Get Final data ------------------------------------
3614 # error = arrayParameters[:,-1]
3614 # error = arrayParameters[:,-1]
3615 # ind1 = numpy.where(error==0)[0]
3615 # ind1 = numpy.where(error==0)[0]
3616 # arrayParameters = arrayParameters[ind1,:]
3616 # arrayParameters = arrayParameters[ind1,:]
3617
3617
3618 return arrayParameters
3618 return arrayParameters
3619
3619
3620 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
3620 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
3621
3621
3622 arrayAOA = numpy.zeros((phases.shape[0],3))
3622 arrayAOA = numpy.zeros((phases.shape[0],3))
3623 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
3623 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
3624
3624
3625 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3625 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3626 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3626 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3627 arrayAOA[:,2] = cosDirError
3627 arrayAOA[:,2] = cosDirError
3628
3628
3629 azimuthAngle = arrayAOA[:,0]
3629 azimuthAngle = arrayAOA[:,0]
3630 zenithAngle = arrayAOA[:,1]
3630 zenithAngle = arrayAOA[:,1]
3631
3631
3632 #Setting Error
3632 #Setting Error
3633 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
3633 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
3634 error[indError] = 0
3634 error[indError] = 0
3635 #Number 3: AOA not fesible
3635 #Number 3: AOA not fesible
3636 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3636 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3637 error[indInvalid] = 3
3637 error[indInvalid] = 3
3638 #Number 4: Large difference in AOAs obtained from different antenna baselines
3638 #Number 4: Large difference in AOAs obtained from different antenna baselines
3639 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3639 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3640 error[indInvalid] = 4
3640 error[indInvalid] = 4
3641 return arrayAOA, error
3641 return arrayAOA, error
3642
3642
3643 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
3643 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
3644
3644
3645 #Initializing some variables
3645 #Initializing some variables
3646 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3646 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3647 ang_aux = ang_aux.reshape(1,ang_aux.size)
3647 ang_aux = ang_aux.reshape(1,ang_aux.size)
3648
3648
3649 cosdir = numpy.zeros((arrayPhase.shape[0],2))
3649 cosdir = numpy.zeros((arrayPhase.shape[0],2))
3650 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3650 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3651
3651
3652
3652
3653 for i in range(2):
3653 for i in range(2):
3654 ph0 = arrayPhase[:,pairsList[i][0]]
3654 ph0 = arrayPhase[:,pairsList[i][0]]
3655 ph1 = arrayPhase[:,pairsList[i][1]]
3655 ph1 = arrayPhase[:,pairsList[i][1]]
3656 d0 = distances[pairsList[i][0]]
3656 d0 = distances[pairsList[i][0]]
3657 d1 = distances[pairsList[i][1]]
3657 d1 = distances[pairsList[i][1]]
3658
3658
3659 ph0_aux = ph0 + ph1
3659 ph0_aux = ph0 + ph1
3660 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
3660 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
3661 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
3661 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
3662 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
3662 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
3663 #First Estimation
3663 #First Estimation
3664 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
3664 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
3665
3665
3666 #Most-Accurate Second Estimation
3666 #Most-Accurate Second Estimation
3667 phi1_aux = ph0 - ph1
3667 phi1_aux = ph0 - ph1
3668 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3668 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3669 #Direction Cosine 1
3669 #Direction Cosine 1
3670 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
3670 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
3671
3671
3672 #Searching the correct Direction Cosine
3672 #Searching the correct Direction Cosine
3673 cosdir0_aux = cosdir0[:,i]
3673 cosdir0_aux = cosdir0[:,i]
3674 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3674 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3675 #Minimum Distance
3675 #Minimum Distance
3676 cosDiff = (cosdir1 - cosdir0_aux)**2
3676 cosDiff = (cosdir1 - cosdir0_aux)**2
3677 indcos = cosDiff.argmin(axis = 1)
3677 indcos = cosDiff.argmin(axis = 1)
3678 #Saving Value obtained
3678 #Saving Value obtained
3679 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3679 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3680
3680
3681 return cosdir0, cosdir
3681 return cosdir0, cosdir
3682
3682
3683 def __calculateAOA(self, cosdir, azimuth):
3683 def __calculateAOA(self, cosdir, azimuth):
3684 cosdirX = cosdir[:,0]
3684 cosdirX = cosdir[:,0]
3685 cosdirY = cosdir[:,1]
3685 cosdirY = cosdir[:,1]
3686
3686
3687 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3687 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3688 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
3688 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
3689 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3689 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3690
3690
3691 return angles
3691 return angles
3692
3692
3693 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3693 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3694
3694
3695 Ramb = 375 #Ramb = c/(2*PRF)
3695 Ramb = 375 #Ramb = c/(2*PRF)
3696 Re = 6371 #Earth Radius
3696 Re = 6371 #Earth Radius
3697 heights = numpy.zeros(Ranges.shape)
3697 heights = numpy.zeros(Ranges.shape)
3698
3698
3699 R_aux = numpy.array([0,1,2])*Ramb
3699 R_aux = numpy.array([0,1,2])*Ramb
3700 R_aux = R_aux.reshape(1,R_aux.size)
3700 R_aux = R_aux.reshape(1,R_aux.size)
3701
3701
3702 Ranges = Ranges.reshape(Ranges.size,1)
3702 Ranges = Ranges.reshape(Ranges.size,1)
3703
3703
3704 Ri = Ranges + R_aux
3704 Ri = Ranges + R_aux
3705 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3705 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3706
3706
3707 #Check if there is a height between 70 and 110 km
3707 #Check if there is a height between 70 and 110 km
3708 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3708 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3709 ind_h = numpy.where(h_bool == 1)[0]
3709 ind_h = numpy.where(h_bool == 1)[0]
3710
3710
3711 hCorr = hi[ind_h, :]
3711 hCorr = hi[ind_h, :]
3712 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3712 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3713
3713
3714 hCorr = hi[ind_hCorr][:len(ind_h)]
3714 hCorr = hi[ind_hCorr][:len(ind_h)]
3715 heights[ind_h] = hCorr
3715 heights[ind_h] = hCorr
3716
3716
3717 #Setting Error
3717 #Setting Error
3718 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3718 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3719 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3719 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3720 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
3720 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
3721 error[indError] = 0
3721 error[indError] = 0
3722 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3722 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3723 error[indInvalid2] = 14
3723 error[indInvalid2] = 14
3724 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3724 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3725 error[indInvalid1] = 13
3725 error[indInvalid1] = 13
3726
3726
3727 return heights, error
3727 return heights, error
3728
3728
3729 def getPhasePairs(self, channelPositions):
3729 def getPhasePairs(self, channelPositions):
3730 chanPos = numpy.array(channelPositions)
3730 chanPos = numpy.array(channelPositions)
3731 listOper = list(itertools.combinations(list(range(5)),2))
3731 listOper = list(itertools.combinations(list(range(5)),2))
3732
3732
3733 distances = numpy.zeros(4)
3733 distances = numpy.zeros(4)
3734 axisX = []
3734 axisX = []
3735 axisY = []
3735 axisY = []
3736 distX = numpy.zeros(3)
3736 distX = numpy.zeros(3)
3737 distY = numpy.zeros(3)
3737 distY = numpy.zeros(3)
3738 ix = 0
3738 ix = 0
3739 iy = 0
3739 iy = 0
3740
3740
3741 pairX = numpy.zeros((2,2))
3741 pairX = numpy.zeros((2,2))
3742 pairY = numpy.zeros((2,2))
3742 pairY = numpy.zeros((2,2))
3743
3743
3744 for i in range(len(listOper)):
3744 for i in range(len(listOper)):
3745 pairi = listOper[i]
3745 pairi = listOper[i]
3746
3746
3747 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
3747 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
3748
3748
3749 if posDif[0] == 0:
3749 if posDif[0] == 0:
3750 axisY.append(pairi)
3750 axisY.append(pairi)
3751 distY[iy] = posDif[1]
3751 distY[iy] = posDif[1]
3752 iy += 1
3752 iy += 1
3753 elif posDif[1] == 0:
3753 elif posDif[1] == 0:
3754 axisX.append(pairi)
3754 axisX.append(pairi)
3755 distX[ix] = posDif[0]
3755 distX[ix] = posDif[0]
3756 ix += 1
3756 ix += 1
3757
3757
3758 for i in range(2):
3758 for i in range(2):
3759 if i==0:
3759 if i==0:
3760 dist0 = distX
3760 dist0 = distX
3761 axis0 = axisX
3761 axis0 = axisX
3762 else:
3762 else:
3763 dist0 = distY
3763 dist0 = distY
3764 axis0 = axisY
3764 axis0 = axisY
3765
3765
3766 side = numpy.argsort(dist0)[:-1]
3766 side = numpy.argsort(dist0)[:-1]
3767 axis0 = numpy.array(axis0)[side,:]
3767 axis0 = numpy.array(axis0)[side,:]
3768 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
3768 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
3769 axis1 = numpy.unique(numpy.reshape(axis0,4))
3769 axis1 = numpy.unique(numpy.reshape(axis0,4))
3770 side = axis1[axis1 != chanC]
3770 side = axis1[axis1 != chanC]
3771 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
3771 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
3772 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
3772 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
3773 if diff1<0:
3773 if diff1<0:
3774 chan2 = side[0]
3774 chan2 = side[0]
3775 d2 = numpy.abs(diff1)
3775 d2 = numpy.abs(diff1)
3776 chan1 = side[1]
3776 chan1 = side[1]
3777 d1 = numpy.abs(diff2)
3777 d1 = numpy.abs(diff2)
3778 else:
3778 else:
3779 chan2 = side[1]
3779 chan2 = side[1]
3780 d2 = numpy.abs(diff2)
3780 d2 = numpy.abs(diff2)
3781 chan1 = side[0]
3781 chan1 = side[0]
3782 d1 = numpy.abs(diff1)
3782 d1 = numpy.abs(diff1)
3783
3783
3784 if i==0:
3784 if i==0:
3785 chanCX = chanC
3785 chanCX = chanC
3786 chan1X = chan1
3786 chan1X = chan1
3787 chan2X = chan2
3787 chan2X = chan2
3788 distances[0:2] = numpy.array([d1,d2])
3788 distances[0:2] = numpy.array([d1,d2])
3789 else:
3789 else:
3790 chanCY = chanC
3790 chanCY = chanC
3791 chan1Y = chan1
3791 chan1Y = chan1
3792 chan2Y = chan2
3792 chan2Y = chan2
3793 distances[2:4] = numpy.array([d1,d2])
3793 distances[2:4] = numpy.array([d1,d2])
3794 # axisXsides = numpy.reshape(axisX[ix,:],4)
3794 # axisXsides = numpy.reshape(axisX[ix,:],4)
3795 #
3795 #
3796 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
3796 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
3797 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
3797 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
3798 #
3798 #
3799 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
3799 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
3800 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
3800 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
3801 # channel25X = int(pairX[0,ind25X])
3801 # channel25X = int(pairX[0,ind25X])
3802 # channel20X = int(pairX[1,ind20X])
3802 # channel20X = int(pairX[1,ind20X])
3803 # ind25Y = numpy.where(pairY[0,:] != channelCentY)[0][0]
3803 # ind25Y = numpy.where(pairY[0,:] != channelCentY)[0][0]
3804 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
3804 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
3805 # channel25Y = int(pairY[0,ind25Y])
3805 # channel25Y = int(pairY[0,ind25Y])
3806 # channel20Y = int(pairY[1,ind20Y])
3806 # channel20Y = int(pairY[1,ind20Y])
3807
3807
3808 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
3808 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
3809 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
3809 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
3810
3810
3811 return pairslist, distances
3811 return pairslist, distances
3812 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
3812 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
3813 #
3813 #
3814 # arrayAOA = numpy.zeros((phases.shape[0],3))
3814 # arrayAOA = numpy.zeros((phases.shape[0],3))
3815 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
3815 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
3816 #
3816 #
3817 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3817 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3818 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3818 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3819 # arrayAOA[:,2] = cosDirError
3819 # arrayAOA[:,2] = cosDirError
3820 #
3820 #
3821 # azimuthAngle = arrayAOA[:,0]
3821 # azimuthAngle = arrayAOA[:,0]
3822 # zenithAngle = arrayAOA[:,1]
3822 # zenithAngle = arrayAOA[:,1]
3823 #
3823 #
3824 # #Setting Error
3824 # #Setting Error
3825 # #Number 3: AOA not fesible
3825 # #Number 3: AOA not fesible
3826 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3826 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3827 # error[indInvalid] = 3
3827 # error[indInvalid] = 3
3828 # #Number 4: Large difference in AOAs obtained from different antenna baselines
3828 # #Number 4: Large difference in AOAs obtained from different antenna baselines
3829 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3829 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3830 # error[indInvalid] = 4
3830 # error[indInvalid] = 4
3831 # return arrayAOA, error
3831 # return arrayAOA, error
3832 #
3832 #
3833 # def __getDirectionCosines(self, arrayPhase, pairsList):
3833 # def __getDirectionCosines(self, arrayPhase, pairsList):
3834 #
3834 #
3835 # #Initializing some variables
3835 # #Initializing some variables
3836 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3836 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3837 # ang_aux = ang_aux.reshape(1,ang_aux.size)
3837 # ang_aux = ang_aux.reshape(1,ang_aux.size)
3838 #
3838 #
3839 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
3839 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
3840 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3840 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3841 #
3841 #
3842 #
3842 #
3843 # for i in range(2):
3843 # for i in range(2):
3844 # #First Estimation
3844 # #First Estimation
3845 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
3845 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
3846 # #Dealias
3846 # #Dealias
3847 # indcsi = numpy.where(phi0_aux > numpy.pi)
3847 # indcsi = numpy.where(phi0_aux > numpy.pi)
3848 # phi0_aux[indcsi] -= 2*numpy.pi
3848 # phi0_aux[indcsi] -= 2*numpy.pi
3849 # indcsi = numpy.where(phi0_aux < -numpy.pi)
3849 # indcsi = numpy.where(phi0_aux < -numpy.pi)
3850 # phi0_aux[indcsi] += 2*numpy.pi
3850 # phi0_aux[indcsi] += 2*numpy.pi
3851 # #Direction Cosine 0
3851 # #Direction Cosine 0
3852 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
3852 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
3853 #
3853 #
3854 # #Most-Accurate Second Estimation
3854 # #Most-Accurate Second Estimation
3855 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
3855 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
3856 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3856 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3857 # #Direction Cosine 1
3857 # #Direction Cosine 1
3858 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
3858 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
3859 #
3859 #
3860 # #Searching the correct Direction Cosine
3860 # #Searching the correct Direction Cosine
3861 # cosdir0_aux = cosdir0[:,i]
3861 # cosdir0_aux = cosdir0[:,i]
3862 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3862 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3863 # #Minimum Distance
3863 # #Minimum Distance
3864 # cosDiff = (cosdir1 - cosdir0_aux)**2
3864 # cosDiff = (cosdir1 - cosdir0_aux)**2
3865 # indcos = cosDiff.argmin(axis = 1)
3865 # indcos = cosDiff.argmin(axis = 1)
3866 # #Saving Value obtained
3866 # #Saving Value obtained
3867 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3867 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3868 #
3868 #
3869 # return cosdir0, cosdir
3869 # return cosdir0, cosdir
3870 #
3870 #
3871 # def __calculateAOA(self, cosdir, azimuth):
3871 # def __calculateAOA(self, cosdir, azimuth):
3872 # cosdirX = cosdir[:,0]
3872 # cosdirX = cosdir[:,0]
3873 # cosdirY = cosdir[:,1]
3873 # cosdirY = cosdir[:,1]
3874 #
3874 #
3875 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3875 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3876 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
3876 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
3877 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3877 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3878 #
3878 #
3879 # return angles
3879 # return angles
3880 #
3880 #
3881 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3881 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3882 #
3882 #
3883 # Ramb = 375 #Ramb = c/(2*PRF)
3883 # Ramb = 375 #Ramb = c/(2*PRF)
3884 # Re = 6371 #Earth Radius
3884 # Re = 6371 #Earth Radius
3885 # heights = numpy.zeros(Ranges.shape)
3885 # heights = numpy.zeros(Ranges.shape)
3886 #
3886 #
3887 # R_aux = numpy.array([0,1,2])*Ramb
3887 # R_aux = numpy.array([0,1,2])*Ramb
3888 # R_aux = R_aux.reshape(1,R_aux.size)
3888 # R_aux = R_aux.reshape(1,R_aux.size)
3889 #
3889 #
3890 # Ranges = Ranges.reshape(Ranges.size,1)
3890 # Ranges = Ranges.reshape(Ranges.size,1)
3891 #
3891 #
3892 # Ri = Ranges + R_aux
3892 # Ri = Ranges + R_aux
3893 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3893 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3894 #
3894 #
3895 # #Check if there is a height between 70 and 110 km
3895 # #Check if there is a height between 70 and 110 km
3896 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3896 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3897 # ind_h = numpy.where(h_bool == 1)[0]
3897 # ind_h = numpy.where(h_bool == 1)[0]
3898 #
3898 #
3899 # hCorr = hi[ind_h, :]
3899 # hCorr = hi[ind_h, :]
3900 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3900 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3901 #
3901 #
3902 # hCorr = hi[ind_hCorr]
3902 # hCorr = hi[ind_hCorr]
3903 # heights[ind_h] = hCorr
3903 # heights[ind_h] = hCorr
3904 #
3904 #
3905 # #Setting Error
3905 # #Setting Error
3906 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3906 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3907 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3907 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3908 #
3908 #
3909 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3909 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3910 # error[indInvalid2] = 14
3910 # error[indInvalid2] = 14
3911 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3911 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3912 # error[indInvalid1] = 13
3912 # error[indInvalid1] = 13
3913 #
3913 #
3914 # return heights, error
3914 # return heights, error
3915
3915
3916
3916
3917 class WeatherRadar(Operation):
3917 class WeatherRadar(Operation):
3918 '''
3918 '''
3919 Function tat implements Weather Radar operations-
3919 Function tat implements Weather Radar operations-
3920 Input:
3920 Input:
3921 Output:
3921 Output:
3922 Parameters affected:
3922 Parameters affected:
3923
3924 Conversion Watt
3925 Referencia
3926 https://www.tek.com/en/blog/calculating-rf-power-iq-samples
3923 '''
3927 '''
3924 isConfig = False
3928 isConfig = False
3925 variableList = None
3929 variableList = None
3926
3930
3927 def __init__(self):
3931 def __init__(self):
3928 Operation.__init__(self)
3932 Operation.__init__(self)
3929
3933
3930 def setup(self,dataOut,variableList= None,Pt=0,Gt=0,Gr=0,Glna=0,lambda_=0, aL=0,
3934 def setup(self,dataOut,variableList= None,Pt=0,Gt=0,Gr=0,Glna=0,lambda_=0, aL=0,
3931 tauW= 0,thetaT=0,thetaR=0,Km =0):
3935 tauW= 0,thetaT=0,thetaR=0,Km =0):
3932
3936
3933 self.nCh = dataOut.nChannels
3937 self.nCh = dataOut.nChannels
3934 self.nHeis = dataOut.nHeights
3938 self.nHeis = dataOut.nHeights
3935 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
3939 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
3936 self.Range = numpy.arange(dataOut.nHeights)*deltaHeight + dataOut.heightList[0]
3940 self.Range = numpy.arange(dataOut.nHeights)*deltaHeight + dataOut.heightList[0]
3937 self.Range = self.Range.reshape(1,self.nHeis)
3941 self.Range = self.Range.reshape(1,self.nHeis)
3938 self.Range = numpy.tile(self.Range,[self.nCh,1])
3942 self.Range = numpy.tile(self.Range,[self.nCh,1])
3939 '''-----------1 Constante del Radar----------'''
3943 '''-----------1 Constante del Radar----------'''
3940 self.Pt = Pt # Pmax =200 W x DC=(0.2 useg/400useg)
3944 self.Pt = Pt # Pmax =200 W x DC=(0.2 useg/400useg)
3941 self.Gt = Gt # 38 db
3945 self.Gt = Gt # 38 db
3942 self.Gr = Gr # 38 dB
3946 self.Gr = Gr # 38 dB
3943 self.Glna = Glna # 60 dB
3947 self.Glna = Glna # 60 dB
3944 self.lambda_ = lambda_ # 3.2 cm 0.032 m.
3948 self.lambda_ = lambda_ # 3.2 cm 0.032 m.
3945 self.aL = aL # Perdidas
3949 self.aL = aL # Perdidas
3946 self.tauW = tauW #ancho de pulso 0.2useg pulso corto.
3950 self.tauW = tauW #ancho de pulso 0.2useg pulso corto.
3947 self.thetaT = thetaT # 1.8ΒΊ -- 0.0314 rad
3951 self.thetaT = thetaT # 1.8ΒΊ -- 0.0314 rad
3948 self.thetaR = thetaR # 1.8Βͺ --0.0314 rad
3952 self.thetaR = thetaR # 1.8Βͺ --0.0314 rad
3949 self.Km = Km
3953 self.Km = Km
3950 Numerator = ((4*numpy.pi)**3 * aL**2 * 16 *numpy.log(2)*(10**18))
3954 Numerator = ((4*numpy.pi)**3 * aL**2 * 16 *numpy.log(2)*(10**18))
3951 Denominator = (Pt *(10**(Gt/10.0))*(10**(Gr/10.0))*(10**(Glna/10.0))* lambda_**2 * SPEED_OF_LIGHT * tauW * numpy.pi*thetaT*thetaR)
3955 Denominator = (Pt *(10**(Gt/10.0))*(10**(Gr/10.0))*(10**(Glna/10.0))* lambda_**2 * SPEED_OF_LIGHT * tauW * numpy.pi*thetaT*thetaR)
3952 self.RadarConstant = Numerator/Denominator
3956 self.RadarConstant = Numerator/Denominator
3957 self.variableList = variableList
3953 if self.variableList== None:
3958 if self.variableList== None:
3954 self.variableList= ['Reflectividad','ReflectividadDiferencial','CoeficienteCorrelacion','FaseDiferencial','VelocidadRadial','AnchoEspectral']
3959 self.variableList= ['Reflectividad','ReflectividadDiferencial','CoeficienteCorrelacion','FaseDiferencial','VelocidadRadial','AnchoEspectral']
3955
3960
3956 def setMoments(self,dataOut,i):
3961 def setMoments(self,dataOut,i):
3957
3962
3958 type = dataOut.inputUnit
3963 type = dataOut.inputUnit
3959 nCh = dataOut.nChannels
3964 nCh = dataOut.nChannels
3960 nHeis = dataOut.nHeights
3965 nHeis = dataOut.nHeights
3961 data_param = numpy.zeros((nCh,4,nHeis))
3966 data_param = numpy.zeros((nCh,4,nHeis))
3962 if type == "Voltage":
3967 if type == "Voltage":
3963 factor = 1
3968 factor = 1
3964 data_param[:,0,:] = dataOut.dataPP_POW/(factor)
3969 data_param[:,0,:] = dataOut.dataPP_POWER/(factor)
3965 data_param[:,1,:] = dataOut.dataPP_DOP
3970 data_param[:,1,:] = dataOut.dataPP_DOP
3966 data_param[:,2,:] = dataOut.dataPP_WIDTH
3971 data_param[:,2,:] = dataOut.dataPP_WIDTH
3967 data_param[:,3,:] = dataOut.dataPP_SNR
3972 data_param[:,3,:] = dataOut.dataPP_SNR
3968 if type == "Spectra":
3973 if type == "Spectra":
3969 factor = dataOut.normFactor
3974 factor = dataOut.normFactor
3970 data_param[:,0,:] = dataOut.data_POW/(factor)
3975 data_param[:,0,:] = dataOut.data_POW/(factor)
3971 data_param[:,1,:] = dataOut.data_DOP
3976 data_param[:,1,:] = dataOut.data_DOP
3972 data_param[:,2,:] = dataOut.data_WIDTH
3977 data_param[:,2,:] = dataOut.data_WIDTH
3973 data_param[:,3,:] = dataOut.data_SNR
3978 data_param[:,3,:] = dataOut.data_SNR
3974
3979
3975 return data_param[:,i,:]
3980 return data_param[:,i,:]
3976
3981
3977 def getCoeficienteCorrelacionROhv_R(self,dataOut):
3982 def getCoeficienteCorrelacionROhv_R(self,dataOut):
3978 type = dataOut.inputUnit
3983 type = dataOut.inputUnit
3979 nHeis = dataOut.nHeights
3984 nHeis = dataOut.nHeights
3980 data_RhoHV_R = numpy.zeros((nHeis))
3985 data_RhoHV_R = numpy.zeros((nHeis))
3981 if type == "Voltage":
3986 if type == "Voltage":
3982 powa = dataOut.dataPP_POWER[0]
3987 powa = dataOut.dataPP_POWER[0]
3983 powb = dataOut.dataPP_POWER[1]
3988 powb = dataOut.dataPP_POWER[1]
3984 ccf = dataOut.dataPP_CCF
3989 ccf = dataOut.dataPP_CCF
3985 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
3990 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
3986 data_RhoHV_R = numpy.abs(avgcoherenceComplex)
3991 data_RhoHV_R = numpy.abs(avgcoherenceComplex)
3987 if type == "Spectra":
3992 if type == "Spectra":
3988 data_RhoHV_R = dataOut.getCoherence()
3993 data_RhoHV_R = dataOut.getCoherence()
3989
3994
3990 return data_RhoHV_R
3995 return data_RhoHV_R
3991
3996
3992 def getFasediferencialPhiD_P(self,dataOut,phase= True):
3997 def getFasediferencialPhiD_P(self,dataOut,phase= True):
3993 type = dataOut.inputUnit
3998 type = dataOut.inputUnit
3994 nHeis = dataOut.nHeights
3999 nHeis = dataOut.nHeights
3995 data_PhiD_P = numpy.zeros((nHeis))
4000 data_PhiD_P = numpy.zeros((nHeis))
3996 if type == "Voltage":
4001 if type == "Voltage":
3997 powa = dataOut.dataPP_POWER[0]
4002 powa = dataOut.dataPP_POWER[0]
3998 powb = dataOut.dataPP_POWER[1]
4003 powb = dataOut.dataPP_POWER[1]
3999 ccf = dataOut.dataPP_CCF
4004 ccf = dataOut.dataPP_CCF
4000 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
4005 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
4001 if phase:
4006 if phase:
4002 data_PhiD_P = numpy.arctan2(avgcoherenceComplex.imag,
4007 data_PhiD_P = numpy.arctan2(avgcoherenceComplex.imag,
4003 avgcoherenceComplex.real) * 180 / numpy.pi
4008 avgcoherenceComplex.real) * 180 / numpy.pi
4004 if type == "Spectra":
4009 if type == "Spectra":
4005 data_PhiD_P = dataOut.getCoherence(phase = phase)
4010 data_PhiD_P = dataOut.getCoherence(phase = phase)
4006
4011
4007 return data_PhiD_P
4012 return data_PhiD_P
4008
4013
4009 def getReflectividad_D(self,dataOut,type):
4014 def getReflectividad_D(self,dataOut,type):
4010 '''-----------------------------Potencia de Radar -Signal S-----------------------------'''
4015 '''-----------------------------Potencia de Radar -Signal S-----------------------------'''
4011
4016
4012 Pr = self.setMoments(dataOut,0)
4017 Pr = self.setMoments(dataOut,0)
4013
4018 '''---------------------------- Calculo de Noise y threshold para Reflectividad---------'''
4019 noise = numpy.zeros(self.nCh)
4020 for i in range(self.nCh):
4021 noise[i] = hildebrand_sekhon(Pr[i,:], 1)
4022 window = numpy.where(Pr[i,:]<1.3*noise[i])
4023 Pr[i,window]= 1e-10
4024 Pr = Pr/1000.0 # Conversion Watt
4014 '''-----------2 Reflectividad del Radar y Factor de Reflectividad------'''
4025 '''-----------2 Reflectividad del Radar y Factor de Reflectividad------'''
4015 self.n_radar = numpy.zeros((self.nCh,self.nHeis))
4026 self.n_radar = numpy.zeros((self.nCh,self.nHeis))
4016 self.Z_radar = numpy.zeros((self.nCh,self.nHeis))
4027 self.Z_radar = numpy.zeros((self.nCh,self.nHeis))
4028
4017 for R in range(self.nHeis):
4029 for R in range(self.nHeis):
4018 self.n_radar[:,R] = self.RadarConstant*Pr[:,R]* (self.Range[:,R])**2*(10**-10.246)
4030 self.n_radar[:,R] = self.RadarConstant*Pr[:,R]* (self.Range[:,R]*(10**3))**2
4019
4031
4020 self.Z_radar[:,R] = self.n_radar[:,R]* self.lambda_**4/( numpy.pi**5 * self.Km**2)
4032 self.Z_radar[:,R] = self.n_radar[:,R]* self.lambda_**4/( numpy.pi**5 * self.Km**2)
4021
4033
4022 '''----------- Factor de Reflectividad Equivalente lamda_ < 10 cm , lamda_= 3.2cm-------'''
4034 '''----------- Factor de Reflectividad Equivalente lamda_ < 10 cm , lamda_= 3.2cm-------'''
4023 Zeh = self.Z_radar
4035 Zeh = self.Z_radar
4024 dBZeh = 10*numpy.log10(Zeh)
4036 #print("---------------------------------------------------------------------")
4037 #print("RangedBz",10*numpy.log10((self.Range[0,-10:]*(10**3))**2))
4038 #print("CTE",10*numpy.log10(self.RadarConstant))
4039 #print("Pr first10",10*numpy.log10(Pr[0,:20]))
4040 #print("Pr last10",10*numpy.log10(Pr[0,-20:]))
4041 #print("LCTE",10*numpy.log10(self.lambda_**4/( numpy.pi**5 * self.Km**2)))
4042 if self.Pt<0.3:
4043 factor=-20.0
4044 else:
4045 factor=0
4046
4047 dBZeh = 10*numpy.log10(Zeh) + factor
4025 if type=='N':
4048 if type=='N':
4026 return dBZeh
4049 return dBZeh
4027 elif type=='D':
4050 elif type=='D':
4028 Zdb_D = dBZeh[0] - dBZeh[1]
4051 Zdb_D = dBZeh[0] - dBZeh[1]
4029 return Zdb_D
4052 return Zdb_D
4030
4053
4031 def getRadialVelocity_V(self,dataOut):
4054 def getRadialVelocity_V(self,dataOut):
4032 velRadial_V = self.setMoments(dataOut,1)
4055 velRadial_V = self.setMoments(dataOut,1)
4033 return velRadial_V
4056 return velRadial_V
4034
4057
4035 def getAnchoEspectral_W(self,dataOut):
4058 def getAnchoEspectral_W(self,dataOut):
4036 Sigmav_W = self.setMoments(dataOut,2)
4059 Sigmav_W = self.setMoments(dataOut,2)
4037 return Sigmav_W
4060 return Sigmav_W
4038
4061
4039
4062
4040 def run(self,dataOut,variableList=variableList,Pt=1.58,Gt=38.5,Gr=38.5,Glna=70.0,lambda_=0.032, aL=1,
4063 def run(self,dataOut,variableList=variableList,Pt=1.58,Gt=38.5,Gr=38.5,Glna=70.0,lambda_=0.032, aL=1,
4041 tauW= 0.2,thetaT=0.0314,thetaR=0.0314,Km =0.93):
4064 tauW= 0.2,thetaT=0.0314,thetaR=0.0314,Km =0.93):
4042
4065
4043 if not self.isConfig:
4066 if not self.isConfig:
4044 self.setup(dataOut= dataOut,variableList=variableList,Pt=Pt,Gt=Gt,Gr=Gr,Glna=Glna,lambda_=lambda_, aL=aL,
4067 self.setup(dataOut= dataOut,variableList=variableList,Pt=Pt,Gt=Gt,Gr=Gr,Glna=Glna,lambda_=lambda_, aL=aL,
4045 tauW= tauW,thetaT=thetaT,thetaR=thetaR,Km =Km)
4068 tauW= tauW,thetaT=thetaT,thetaR=thetaR,Km =Km)
4046 self.isConfig = True
4069 self.isConfig = True
4047 for i in range(len(self.variableList)):
4070 for i in range(len(self.variableList)):
4048 if self.variableList[i]=='Reflectividad':
4071 if self.variableList[i]=='Reflectividad':
4049 dataOut.Zdb =self.getReflectividad_D(dataOut=dataOut,type='N')
4072 dataOut.Zdb =self.getReflectividad_D(dataOut=dataOut,type='N')
4050 if self.variableList[i]=='ReflectividadDiferencial':
4073 if self.variableList[i]=='ReflectividadDiferencial':
4051 dataOut.Zdb_D =self.getReflectividad_D(dataOut=dataOut,type='D')
4074 dataOut.Zdb_D =self.getReflectividad_D(dataOut=dataOut,type='D')
4052 if self.variableList[i]=='FaseDiferencial':
4075 if self.variableList[i]=='FaseDiferencial':
4053 dataOut.PhiD_P =self.getFasediferencialPhiD_P(dataOut=dataOut, phase=True)
4076 dataOut.PhiD_P =self.getFasediferencialPhiD_P(dataOut=dataOut, phase=True)
4054 if self.variableList[i] == "CoeficienteCorrelacion":
4077 if self.variableList[i] == "CoeficienteCorrelacion":
4055 dataOut.RhoHV_R = self.getCoeficienteCorrelacionROhv_R(dataOut)
4078 dataOut.RhoHV_R = self.getCoeficienteCorrelacionROhv_R(dataOut)
4056 if self.variableList[i] =="VelocidadRadial":
4079 if self.variableList[i] =="VelocidadRadial":
4057 dataOut.velRadial_V = self.getRadialVelocity_V(dataOut)
4080 dataOut.velRadial_V = self.getRadialVelocity_V(dataOut)
4058 if self.variableList[i] =="AnchoEspectral":
4081 if self.variableList[i] =="AnchoEspectral":
4059 dataOut.Sigmav_W = self.getAnchoEspectral_W(dataOut)
4082 dataOut.Sigmav_W = self.getAnchoEspectral_W(dataOut)
4060 return dataOut
4083 return dataOut
4061
4084
4062 class PedestalInformation(Operation):
4085 class PedestalInformation(Operation):
4063
4086
4064 def __init__(self):
4087 def __init__(self):
4065 Operation.__init__(self)
4088 Operation.__init__(self)
4066 self.filename = False
4089 self.filename = False
4067 self.delay = 32
4090 self.delay = 32
4068 self.nTries = 3
4091 self.nTries = 3
4069
4092
4070 def find_file(self, timestamp):
4093 def find_file(self, timestamp):
4071
4094
4072 dt = datetime.datetime.utcfromtimestamp(timestamp)
4095 dt = datetime.datetime.utcfromtimestamp(timestamp)
4073 path = os.path.join(self.path, dt.strftime('%Y-%m-%dT%H-00-00'))
4096 path = os.path.join(self.path, dt.strftime('%Y-%m-%dT%H-00-00'))
4074
4097
4075 if not os.path.exists(path):
4098 if not os.path.exists(path):
4076 return False
4099 return False
4077 fileList = glob.glob(os.path.join(path, '*.h5'))
4100 fileList = glob.glob(os.path.join(path, '*.h5'))
4078 fileList.sort()
4101 fileList.sort()
4079 return fileList
4102 return fileList
4080
4103
4081 def find_next_file(self):
4104 def find_next_file(self):
4082
4105
4083 while True:
4106 while True:
4084 if self.utctime < self.utcfile:
4107 if self.utctime < self.utcfile:
4085 self.flagNoData = True
4108 self.flagNoData = True
4086 break
4109 break
4087 self.flagNoData = False
4110 self.flagNoData = False
4088 file_size = len(self.fp['Data']['utc'])
4111 file_size = len(self.fp['Data']['utc'])
4089 if self.utctime < self.utcfile+file_size*self.interval:
4112 if self.utctime < self.utcfile+file_size*self.interval:
4090 break
4113 break
4091 dt = datetime.datetime.utcfromtimestamp(self.utcfile)
4114 dt = datetime.datetime.utcfromtimestamp(self.utcfile)
4092 if dt.second > 0:
4115 if dt.second > 0:
4093 self.utcfile -= dt.second
4116 self.utcfile -= dt.second
4094 self.utcfile += self.samples*self.interval
4117 self.utcfile += self.samples*self.interval
4095 dt = datetime.datetime.utcfromtimestamp(self.utcfile)
4118 dt = datetime.datetime.utcfromtimestamp(self.utcfile)
4096 path = os.path.join(self.path, dt.strftime('%Y-%m-%dT%H-00-00'))
4119 path = os.path.join(self.path, dt.strftime('%Y-%m-%dT%H-00-00'))
4097 self.filename = os.path.join(path, 'pos@{}.000.h5'.format(int(self.utcfile)))
4120 self.filename = os.path.join(path, 'pos@{}.000.h5'.format(int(self.utcfile)))
4098
4121
4099 for i in range(2):
4122 for i in range(2):
4100 ok = False
4123 ok = False
4101 for j in range(self.nTries):
4124 for j in range(self.nTries):
4102 ok = False
4125 ok = False
4103 try:
4126 try:
4104 if not os.path.exists(self.filename):
4127 if not os.path.exists(self.filename):
4105 log.warning('Waiting {}s for position files...'.format(self.delay), self.name)
4128 log.warning('Waiting {}s for position files...'.format(self.delay), self.name)
4106 time.sleep(self.delay)
4129 time.sleep(self.delay)
4107 continue
4130 continue
4108 self.fp.close()
4131 self.fp.close()
4109 self.fp = h5py.File(self.filename, 'r')
4132 self.fp = h5py.File(self.filename, 'r')
4110 log.log('Opening file: {}'.format(self.filename), self.name)
4133 log.log('Opening file: {}'.format(self.filename), self.name)
4111 ok = True
4134 ok = True
4112 break
4135 break
4113 except Exception as e:
4136 except Exception as e:
4114 print(e)
4137 print(e)
4115 log.warning('Waiting {}s for position file to be ready...'.format(self.delay), self.name)
4138 log.warning('Waiting {}s for position file to be ready...'.format(self.delay), self.name)
4116 time.sleep(self.delay)
4139 time.sleep(self.delay)
4117 continue
4140 continue
4118 if ok:
4141 if ok:
4119 break
4142 break
4120 log.warning('Trying next file...', self.name)
4143 log.warning('Trying next file...', self.name)
4121 self.utcfile += self.samples*self.interval
4144 self.utcfile += self.samples*self.interval
4122 dt = datetime.datetime.utcfromtimestamp(self.utcfile)
4145 dt = datetime.datetime.utcfromtimestamp(self.utcfile)
4123 path = os.path.join(self.path, dt.strftime('%Y-%m-%dT%H-00-00'))
4146 path = os.path.join(self.path, dt.strftime('%Y-%m-%dT%H-00-00'))
4124 self.filename = os.path.join(path, 'pos@{}.000.h5'.format(int(self.utcfile)))
4147 self.filename = os.path.join(path, 'pos@{}.000.h5'.format(int(self.utcfile)))
4125 if not ok:
4148 if not ok:
4126 log.error('No new position files found in {}'.format(path))
4149 log.error('No new position files found in {}'.format(path))
4127 raise IOError('No new position files found in {}'.format(path))
4150 raise IOError('No new position files found in {}'.format(path))
4128
4151
4129
4152
4130 def find_mode(self,index):
4153 def find_mode(self,index):
4131 sample_max = 20
4154 sample_max = 20
4132 start = index
4155 start = index
4133 flag_mode = None
4156 flag_mode = None
4134 azi = self.fp['Data']['azi_pos'][:]
4157 azi = self.fp['Data']['azi_pos'][:]
4135 ele = self.fp['Data']['ele_pos'][:]
4158 ele = self.fp['Data']['ele_pos'][:]
4136 #print("az: ",az)
4159 #print("az: ",az)
4137 #exit(1)
4160 #exit(1)
4138 while True:
4161 while True:
4139 if start+sample_max > numpy.shape(ele)[0]:
4162 if start+sample_max > numpy.shape(ele)[0]:
4140 print("CANNOT KNOW IF MODE IS PPI OR RHI, ANALIZE NEXT FILE")
4163 print("CANNOT KNOW IF MODE IS PPI OR RHI, ANALIZE NEXT FILE")
4141 print("ele",ele[start-sample_max:start+sample_max])
4164 print("ele",ele[start-sample_max:start+sample_max])
4142 print("azi",ele[start-sample_max:start+sample_max])
4165 print("azi",ele[start-sample_max:start+sample_max])
4143 if sample_max == 10:
4166 if sample_max == 10:
4144 break
4167 break
4145 else:
4168 else:
4146 sample_max = 10
4169 sample_max = 10
4147 continue
4170 continue
4148 sigma_ele = numpy.nanstd(ele[start:start+sample_max])
4171 sigma_ele = numpy.nanstd(ele[start:start+sample_max])
4149 sigma_azi = numpy.nanstd(azi[start:start+sample_max])
4172 sigma_azi = numpy.nanstd(azi[start:start+sample_max])
4150 print("Start",start)
4173 print("Start",start)
4151 print("ele",ele[start:start+sample_max])
4174 print("ele",ele[start:start+sample_max])
4152 print("s_ele",sigma_ele)
4175 print("s_ele",sigma_ele)
4153 print("azi",azi[start:start+sample_max])
4176 print("azi",azi[start:start+sample_max])
4154 print("s_azi",sigma_azi)
4177 print("s_azi",sigma_azi)
4155 #print(start)
4178 #print(start)
4156 if sigma_ele<.5 and sigma_azi<.5:
4179 if sigma_ele<.5 and sigma_azi<.5:
4157 if sigma_ele<sigma_azi:
4180 if sigma_ele<sigma_azi:
4158 flag_mode = 'PPI'
4181 flag_mode = 'PPI'
4159 break
4182 break
4160 else:
4183 else:
4161 flag_mode = 'RHI'
4184 flag_mode = 'RHI'
4162 break
4185 break
4163 elif sigma_ele<.5:
4186 elif sigma_ele<.5:
4164 #print(sigma_ele)
4187 #print(sigma_ele)
4165 #print(round(numpy.nanmean(ele[start:start+sample_max]),1))
4188 #print(round(numpy.nanmean(ele[start:start+sample_max]),1))
4166 #print(start)
4189 #print(start)
4167 #print(ele[start:start+sample_max])
4190 #print(ele[start:start+sample_max])
4168 flag_mode = 'PPI'
4191 flag_mode = 'PPI'
4169 break
4192 break
4170 elif sigma_azi<.5:
4193 elif sigma_azi<.5:
4171 #print(sigma_azi)
4194 #print(sigma_azi)
4172 #print(azi[start:start+sample_max])
4195 #print(azi[start:start+sample_max])
4173 #print("round",round(numpy.nanmean(azi[start:start+sample_max]),1))
4196 #print("round",round(numpy.nanmean(azi[start:start+sample_max]),1))
4174 flag_mode = 'RHI'
4197 flag_mode = 'RHI'
4175 break
4198 break
4176 #else:
4199 #else:
4177 #print("STD mayor que .5")
4200 #print("STD mayor que .5")
4178 start += sample_max
4201 start += sample_max
4179 print("MODE: ",flag_mode)
4202 print("MODE: ",flag_mode)
4180 return flag_mode
4203 return flag_mode
4181
4204
4182 def get_values(self):
4205 def get_values(self):
4183
4206
4184 if self.flagNoData:
4207 if self.flagNoData:
4185 return numpy.nan, numpy.nan, numpy.nan #Should be self.mode?
4208 return numpy.nan, numpy.nan, numpy.nan #Should be self.mode?
4186 else:
4209 else:
4187 index = int((self.utctime-self.utcfile)/self.interval)
4210 index = int((self.utctime-self.utcfile)/self.interval)
4188
4211
4189 if self.flagAskMode:
4212 if self.flagAskMode:
4190 mode = self.find_mode(index)
4213 mode = self.find_mode(index)
4191 else:
4214 else:
4192 mode = self.mode
4215 mode = self.mode
4193
4216
4194 if mode is not None:
4217 if mode is not None:
4195 return self.fp['Data']['azi_pos'][index], self.fp['Data']['ele_pos'][index], mode
4218 return self.fp['Data']['azi_pos'][index], self.fp['Data']['ele_pos'][index], mode
4196 else:
4219 else:
4197 return numpy.nan, numpy.nan, numpy.nan
4220 return numpy.nan, numpy.nan, numpy.nan
4198
4221
4199 def setup(self, dataOut, path, conf, samples, interval, mode):
4222 def setup(self, dataOut, path, conf, samples, interval, mode):
4200
4223
4201 self.path = path
4224 self.path = path
4202 self.conf = conf
4225 self.conf = conf
4203 self.samples = samples
4226 self.samples = samples
4204 self.interval = interval
4227 self.interval = interval
4205 self.mode = mode
4228 self.mode = mode
4206 filelist = self.find_file(dataOut.utctime)
4229 filelist = self.find_file(dataOut.utctime)
4207
4230
4208 if not filelist:
4231 if not filelist:
4209 log.error('No position files found in {}'.format(path), self.name)
4232 log.error('No position files found in {}'.format(path), self.name)
4210 raise IOError('No position files found in {}'.format(path))
4233 raise IOError('No position files found in {}'.format(path))
4211 else:
4234 else:
4212 self.filename = filelist[0]
4235 self.filename = filelist[0]
4213 self.utcfile = int(self.filename.split('/')[-1][4:14])
4236 self.utcfile = int(self.filename.split('/')[-1][4:14])
4214 log.log('Opening file: {}'.format(self.filename), self.name)
4237 log.log('Opening file: {}'.format(self.filename), self.name)
4215 self.fp = h5py.File(self.filename, 'r')
4238 self.fp = h5py.File(self.filename, 'r')
4216
4239
4217 def run(self, dataOut, path, conf=None, samples=1500, interval=0.04, az_offset=0, time_offset=0, mode=None):
4240 def run(self, dataOut, path, conf=None, samples=1500, interval=0.04, az_offset=0, time_offset=0, mode=None):
4218
4241
4219 if not self.isConfig:
4242 if not self.isConfig:
4220 self.setup(dataOut, path, conf, samples, interval, mode)
4243 self.setup(dataOut, path, conf, samples, interval, mode)
4221 self.isConfig = True
4244 self.isConfig = True
4222
4245
4223 self.utctime = dataOut.utctime + time_offset
4246 self.utctime = dataOut.utctime + time_offset
4224
4247
4225 if hasattr(dataOut, 'flagAskMode'):
4248 if hasattr(dataOut, 'flagAskMode'):
4226 self.flagAskMode = dataOut.flagAskMode
4249 self.flagAskMode = dataOut.flagAskMode
4227 else:
4250 else:
4228 self.flagAskMode = True
4251 self.flagAskMode = True
4229
4252
4230 self.find_next_file()
4253 self.find_next_file()
4231
4254
4232 az, el, scan = self.get_values()
4255 az, el, scan = self.get_values()
4233 dataOut.flagNoData = False
4256 dataOut.flagNoData = False
4234 if numpy.isnan(az) or numpy.isnan(el) :
4257 if numpy.isnan(az) or numpy.isnan(el) :
4235 dataOut.flagNoData = True
4258 dataOut.flagNoData = True
4236 #print("NAN")
4259 #print("NAN")
4237 return dataOut
4260 return dataOut
4238
4261
4239 dataOut.azimuth = az - az_offset
4262 dataOut.azimuth = az - az_offset
4240 if dataOut.azimuth < 0:
4263 if dataOut.azimuth < 0:
4241 dataOut.azimuth += 360
4264 dataOut.azimuth += 360
4242 dataOut.elevation = el
4265 dataOut.elevation = el
4243 dataOut.mode_op = scan
4266 dataOut.mode_op = scan
4244
4267
4245 return dataOut
4268 return dataOut
4246
4269
4247 class Block360(Operation):
4270 class Block360(Operation):
4248 '''
4271 '''
4249 '''
4272 '''
4250 isConfig = False
4273 isConfig = False
4251 __profIndex = 0
4274 __profIndex = 0
4252 __initime = None
4275 __initime = None
4253 __lastdatatime = None
4276 __lastdatatime = None
4254 __buffer = None
4277 __buffer = None
4255 __dataReady = False
4278 __dataReady = False
4256 n = None
4279 n = None
4257 __nch = 0
4280 __nch = 0
4258 __nHeis = 0
4281 __nHeis = 0
4259 index = 0
4282 index = 0
4260 mode = 0
4283 mode = 0
4261
4284
4262 def __init__(self,**kwargs):
4285 def __init__(self,**kwargs):
4263 Operation.__init__(self,**kwargs)
4286 Operation.__init__(self,**kwargs)
4264
4287
4265 def setup(self, dataOut, n = None, mode = None):
4288 def setup(self, dataOut, n = None, mode = None):
4266 '''
4289 '''
4267 n= Numero de PRF's de entrada
4290 n= Numero de PRF's de entrada
4268 '''
4291 '''
4269 self.__initime = None
4292 self.__initime = None
4270 self.__lastdatatime = 0
4293 self.__lastdatatime = 0
4271 self.__dataReady = False
4294 self.__dataReady = False
4272 self.__buffer = 0
4295 self.__buffer = 0
4273 self.__buffer_1D = 0
4296 self.__buffer_1D = 0
4274 self.__profIndex = 0
4297 self.__profIndex = 0
4275 self.index = 0
4298 self.index = 0
4276 self.__nch = dataOut.nChannels
4299 self.__nch = dataOut.nChannels
4277 self.__nHeis = dataOut.nHeights
4300 self.__nHeis = dataOut.nHeights
4278 ##print("ELVALOR DE n es:", n)
4301 ##print("ELVALOR DE n es:", n)
4279 if n == None:
4302 if n == None:
4280 raise ValueError("n should be specified.")
4303 raise ValueError("n should be specified.")
4281
4304
4282 if mode == None:
4305 if mode == None:
4283 raise ValueError("mode should be specified.")
4306 raise ValueError("mode should be specified.")
4284
4307
4285 if n != None:
4308 if n != None:
4286 if n<1:
4309 if n<1:
4287 print("n should be greater than 2")
4310 print("n should be greater than 2")
4288 raise ValueError("n should be greater than 2")
4311 raise ValueError("n should be greater than 2")
4289
4312
4290 self.n = n
4313 self.n = n
4291 self.mode = mode
4314 self.mode = mode
4292 #print("self.mode",self.mode)
4315 #print("self.mode",self.mode)
4293 #print("nHeights")
4316 #print("nHeights")
4294 self.__buffer = numpy.zeros(( dataOut.nChannels,n, dataOut.nHeights))
4317 self.__buffer = numpy.zeros(( dataOut.nChannels,n, dataOut.nHeights))
4295 self.__buffer2 = numpy.zeros(n)
4318 self.__buffer2 = numpy.zeros(n)
4296 self.__buffer3 = numpy.zeros(n)
4319 self.__buffer3 = numpy.zeros(n)
4297
4320
4298
4321
4299
4322
4300
4323
4301 def putData(self,data,mode):
4324 def putData(self,data,mode):
4302 '''
4325 '''
4303 Add a profile to he __buffer and increase in one the __profiel Index
4326 Add a profile to he __buffer and increase in one the __profiel Index
4304 '''
4327 '''
4305 #print("line 4049",data.dataPP_POW.shape,data.dataPP_POW[:10])
4328 #print("line 4049",data.dataPP_POW.shape,data.dataPP_POW[:10])
4306 #print("line 4049",data.azimuth.shape,data.azimuth)
4329 #print("line 4049",data.azimuth.shape,data.azimuth)
4307 if self.mode==0:
4330 if self.mode==0:
4308 self.__buffer[:,self.__profIndex,:]= data.dataPP_POWER# PRIMER MOMENTO
4331 self.__buffer[:,self.__profIndex,:]= data.dataPP_POWER# PRIMER MOMENTO
4309 if self.mode==1:
4332 if self.mode==1:
4310 self.__buffer[:,self.__profIndex,:]= data.data_pow
4333 self.__buffer[:,self.__profIndex,:]= data.data_pow
4311 #print("me casi",self.index,data.azimuth[self.index])
4334 #print("me casi",self.index,data.azimuth[self.index])
4312 #print(self.__profIndex, self.index , data.azimuth[self.index] )
4335 #print(self.__profIndex, self.index , data.azimuth[self.index] )
4313 #print("magic",data.profileIndex)
4336 #print("magic",data.profileIndex)
4314 #print(data.azimuth[self.index])
4337 #print(data.azimuth[self.index])
4315 #print("index",self.index)
4338 #print("index",self.index)
4316
4339
4317 #####self.__buffer2[self.__profIndex] = data.azimuth[self.index]
4340 #####self.__buffer2[self.__profIndex] = data.azimuth[self.index]
4318 self.__buffer2[self.__profIndex] = data.azimuth
4341 self.__buffer2[self.__profIndex] = data.azimuth
4319 self.__buffer3[self.__profIndex] = data.elevation
4342 self.__buffer3[self.__profIndex] = data.elevation
4320 #print("q pasa")
4343 #print("q pasa")
4321 #####self.index+=1
4344 #####self.index+=1
4322 #print("index",self.index,data.azimuth[:10])
4345 #print("index",self.index,data.azimuth[:10])
4323 self.__profIndex += 1
4346 self.__profIndex += 1
4324 return #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Remove DCΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
4347 return #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Remove DCΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
4325
4348
4326 def pushData(self,data):
4349 def pushData(self,data):
4327 '''
4350 '''
4328 Return the PULSEPAIR and the profiles used in the operation
4351 Return the PULSEPAIR and the profiles used in the operation
4329 Affected : self.__profileIndex
4352 Affected : self.__profileIndex
4330 '''
4353 '''
4331 #print("pushData")
4354 #print("pushData")
4332
4355
4333 data_360 = self.__buffer
4356 data_360 = self.__buffer
4334 data_p = self.__buffer2
4357 data_p = self.__buffer2
4335 data_e = self.__buffer3
4358 data_e = self.__buffer3
4336 n = self.__profIndex
4359 n = self.__profIndex
4337
4360
4338 self.__buffer = numpy.zeros((self.__nch, self.n,self.__nHeis))
4361 self.__buffer = numpy.zeros((self.__nch, self.n,self.__nHeis))
4339 self.__buffer2 = numpy.zeros(self.n)
4362 self.__buffer2 = numpy.zeros(self.n)
4340 self.__buffer3 = numpy.zeros(self.n)
4363 self.__buffer3 = numpy.zeros(self.n)
4341 self.__profIndex = 0
4364 self.__profIndex = 0
4342 #print("pushData")
4365 #print("pushData")
4343 return data_360,n,data_p,data_e
4366 return data_360,n,data_p,data_e
4344
4367
4345
4368
4346 def byProfiles(self,dataOut):
4369 def byProfiles(self,dataOut):
4347
4370
4348 self.__dataReady = False
4371 self.__dataReady = False
4349 data_360 = None
4372 data_360 = None
4350 data_p = None
4373 data_p = None
4351 data_e = None
4374 data_e = None
4352 #print("dataOu",dataOut.dataPP_POW)
4375 #print("dataOu",dataOut.dataPP_POW)
4353 self.putData(data=dataOut,mode = self.mode)
4376 self.putData(data=dataOut,mode = self.mode)
4354 ##### print("profIndex",self.__profIndex)
4377 ##### print("profIndex",self.__profIndex)
4355 if self.__profIndex == self.n:
4378 if self.__profIndex == self.n:
4356 data_360,n,data_p,data_e = self.pushData(data=dataOut)
4379 data_360,n,data_p,data_e = self.pushData(data=dataOut)
4357 self.__dataReady = True
4380 self.__dataReady = True
4358
4381
4359 return data_360,data_p,data_e
4382 return data_360,data_p,data_e
4360
4383
4361
4384
4362 def blockOp(self, dataOut, datatime= None):
4385 def blockOp(self, dataOut, datatime= None):
4363 if self.__initime == None:
4386 if self.__initime == None:
4364 self.__initime = datatime
4387 self.__initime = datatime
4365 data_360,data_p,data_e = self.byProfiles(dataOut)
4388 data_360,data_p,data_e = self.byProfiles(dataOut)
4366 self.__lastdatatime = datatime
4389 self.__lastdatatime = datatime
4367
4390
4368 if data_360 is None:
4391 if data_360 is None:
4369 return None, None,None,None
4392 return None, None,None,None
4370
4393
4371
4394
4372 avgdatatime = self.__initime
4395 avgdatatime = self.__initime
4373 if self.n==1:
4396 if self.n==1:
4374 avgdatatime = datatime
4397 avgdatatime = datatime
4375 deltatime = datatime - self.__lastdatatime
4398 deltatime = datatime - self.__lastdatatime
4376 self.__initime = datatime
4399 self.__initime = datatime
4377 #print(data_360.shape,avgdatatime,data_p.shape)
4400 #print(data_360.shape,avgdatatime,data_p.shape)
4378 return data_360,avgdatatime,data_p,data_e
4401 return data_360,avgdatatime,data_p,data_e
4379
4402
4380 def run(self, dataOut,n = None,mode=None,**kwargs):
4403 def run(self, dataOut,n = None,mode=None,**kwargs):
4381 #print("BLOCK 360 HERE WE GO MOMENTOS")
4404 #print("BLOCK 360 HERE WE GO MOMENTOS")
4382 print("Block 360")
4405 print("Block 360")
4383 #exit(1)
4406 #exit(1)
4384 if not self.isConfig:
4407 if not self.isConfig:
4385 self.setup(dataOut = dataOut, n = n ,mode= mode ,**kwargs)
4408 self.setup(dataOut = dataOut, n = n ,mode= mode ,**kwargs)
4386 ####self.index = 0
4409 ####self.index = 0
4387 #print("comova",self.isConfig)
4410 #print("comova",self.isConfig)
4388 self.isConfig = True
4411 self.isConfig = True
4389 ####if self.index==dataOut.azimuth.shape[0]:
4412 ####if self.index==dataOut.azimuth.shape[0]:
4390 #### self.index=0
4413 #### self.index=0
4391 data_360, avgdatatime,data_p,data_e = self.blockOp(dataOut, dataOut.utctime)
4414 data_360, avgdatatime,data_p,data_e = self.blockOp(dataOut, dataOut.utctime)
4392 dataOut.flagNoData = True
4415 dataOut.flagNoData = True
4393
4416
4394 if self.__dataReady:
4417 if self.__dataReady:
4395 dataOut.data_360 = data_360 # S
4418 dataOut.data_360 = data_360 # S
4396 #print("DATA 360")
4419 #print("DATA 360")
4397 #print(dataOut.data_360)
4420 #print(dataOut.data_360)
4398 #print("---------------------------------------------------------------------------------")
4421 #print("---------------------------------------------------------------------------------")
4399 print("---------------------------DATAREADY---------------------------------------------")
4422 print("---------------------------DATAREADY---------------------------------------------")
4400 #print("---------------------------------------------------------------------------------")
4423 #print("---------------------------------------------------------------------------------")
4401 #print("data_360",dataOut.data_360.shape)
4424 #print("data_360",dataOut.data_360.shape)
4402 dataOut.data_azi = data_p
4425 dataOut.data_azi = data_p
4403 dataOut.data_ele = data_e
4426 dataOut.data_ele = data_e
4404 ###print("azi: ",dataOut.data_azi)
4427 ###print("azi: ",dataOut.data_azi)
4405 #print("ele: ",dataOut.data_ele)
4428 #print("ele: ",dataOut.data_ele)
4406 #print("jroproc_parameters",data_p[0],data_p[-1])#,data_360.shape,avgdatatime)
4429 #print("jroproc_parameters",data_p[0],data_p[-1])#,data_360.shape,avgdatatime)
4407 dataOut.utctime = avgdatatime
4430 dataOut.utctime = avgdatatime
4408 dataOut.flagNoData = False
4431 dataOut.flagNoData = False
4409 return dataOut
4432 return dataOut
4410
4433
4411 class Block360_vRF(Operation):
4434 class Block360_vRF(Operation):
4412 '''
4435 '''
4413 '''
4436 '''
4414 isConfig = False
4437 isConfig = False
4415 __profIndex = 0
4438 __profIndex = 0
4416 __initime = None
4439 __initime = None
4417 __lastdatatime = None
4440 __lastdatatime = None
4418 __buffer = None
4441 __buffer = None
4419 __dataReady = False
4442 __dataReady = False
4420 n = None
4443 n = None
4421 __nch = 0
4444 __nch = 0
4422 __nHeis = 0
4445 __nHeis = 0
4423 index = 0
4446 index = 0
4424 mode = 0
4447 mode = 0
4425
4448
4426 def __init__(self,**kwargs):
4449 def __init__(self,**kwargs):
4427 Operation.__init__(self,**kwargs)
4450 Operation.__init__(self,**kwargs)
4428
4451
4429 def setup(self, dataOut, n = None, mode = None):
4452 def setup(self, dataOut, n = None, mode = None):
4430 '''
4453 '''
4431 n= Numero de PRF's de entrada
4454 n= Numero de PRF's de entrada
4432 '''
4455 '''
4433 self.__initime = None
4456 self.__initime = None
4434 self.__lastdatatime = 0
4457 self.__lastdatatime = 0
4435 self.__dataReady = False
4458 self.__dataReady = False
4436 self.__buffer = 0
4459 self.__buffer = 0
4437 self.__buffer_1D = 0
4460 self.__buffer_1D = 0
4438 self.__profIndex = 0
4461 self.__profIndex = 0
4439 self.index = 0
4462 self.index = 0
4440 self.__nch = dataOut.nChannels
4463 self.__nch = dataOut.nChannels
4441 self.__nHeis = dataOut.nHeights
4464 self.__nHeis = dataOut.nHeights
4442 ##print("ELVALOR DE n es:", n)
4465 ##print("ELVALOR DE n es:", n)
4443 if n == None:
4466 if n == None:
4444 raise ValueError("n should be specified.")
4467 raise ValueError("n should be specified.")
4445
4468
4446 if mode == None:
4469 if mode == None:
4447 raise ValueError("mode should be specified.")
4470 raise ValueError("mode should be specified.")
4448
4471
4449 if n != None:
4472 if n != None:
4450 if n<1:
4473 if n<1:
4451 print("n should be greater than 2")
4474 print("n should be greater than 2")
4452 raise ValueError("n should be greater than 2")
4475 raise ValueError("n should be greater than 2")
4453
4476
4454 self.n = n
4477 self.n = n
4455 self.mode = mode
4478 self.mode = mode
4456 #print("self.mode",self.mode)
4479 #print("self.mode",self.mode)
4457 #print("nHeights")
4480 #print("nHeights")
4458 self.__buffer = numpy.zeros(( dataOut.nChannels,n, dataOut.nHeights))
4481 self.__buffer = numpy.zeros(( dataOut.nChannels,n, dataOut.nHeights))
4459 self.__buffer2 = numpy.zeros(n)
4482 self.__buffer2 = numpy.zeros(n)
4460 self.__buffer3 = numpy.zeros(n)
4483 self.__buffer3 = numpy.zeros(n)
4461
4484
4462
4485
4463
4486
4464
4487
4465 def putData(self,data,mode):
4488 def putData(self,data,mode):
4466 '''
4489 '''
4467 Add a profile to he __buffer and increase in one the __profiel Index
4490 Add a profile to he __buffer and increase in one the __profiel Index
4468 '''
4491 '''
4469 #print("line 4049",data.dataPP_POW.shape,data.dataPP_POW[:10])
4492 #print("line 4049",data.dataPP_POW.shape,data.dataPP_POW[:10])
4470 #print("line 4049",data.azimuth.shape,data.azimuth)
4493 #print("line 4049",data.azimuth.shape,data.azimuth)
4471 if self.mode==0:
4494 if self.mode==0:
4472 self.__buffer[:,self.__profIndex,:]= data.dataPP_POWER# PRIMER MOMENTO
4495 self.__buffer[:,self.__profIndex,:]= data.dataPP_POWER# PRIMER MOMENTO
4473 if self.mode==1:
4496 if self.mode==1:
4474 self.__buffer[:,self.__profIndex,:]= data.data_pow
4497 self.__buffer[:,self.__profIndex,:]= data.data_pow
4475 #print("me casi",self.index,data.azimuth[self.index])
4498 #print("me casi",self.index,data.azimuth[self.index])
4476 #print(self.__profIndex, self.index , data.azimuth[self.index] )
4499 #print(self.__profIndex, self.index , data.azimuth[self.index] )
4477 #print("magic",data.profileIndex)
4500 #print("magic",data.profileIndex)
4478 #print(data.azimuth[self.index])
4501 #print(data.azimuth[self.index])
4479 #print("index",self.index)
4502 #print("index",self.index)
4480
4503
4481 #####self.__buffer2[self.__profIndex] = data.azimuth[self.index]
4504 #####self.__buffer2[self.__profIndex] = data.azimuth[self.index]
4482 self.__buffer2[self.__profIndex] = data.azimuth
4505 self.__buffer2[self.__profIndex] = data.azimuth
4483 self.__buffer3[self.__profIndex] = data.elevation
4506 self.__buffer3[self.__profIndex] = data.elevation
4484 #print("q pasa")
4507 #print("q pasa")
4485 #####self.index+=1
4508 #####self.index+=1
4486 #print("index",self.index,data.azimuth[:10])
4509 #print("index",self.index,data.azimuth[:10])
4487 self.__profIndex += 1
4510 self.__profIndex += 1
4488 return #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Remove DCΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
4511 return #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Remove DCΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
4489
4512
4490 def pushData(self,data):
4513 def pushData(self,data):
4491 '''
4514 '''
4492 Return the PULSEPAIR and the profiles used in the operation
4515 Return the PULSEPAIR and the profiles used in the operation
4493 Affected : self.__profileIndex
4516 Affected : self.__profileIndex
4494 '''
4517 '''
4495 #print("pushData")
4518 #print("pushData")
4496
4519
4497 data_360 = self.__buffer
4520 data_360 = self.__buffer
4498 data_p = self.__buffer2
4521 data_p = self.__buffer2
4499 data_e = self.__buffer3
4522 data_e = self.__buffer3
4500 n = self.__profIndex
4523 n = self.__profIndex
4501
4524
4502 self.__buffer = numpy.zeros((self.__nch, self.n,self.__nHeis))
4525 self.__buffer = numpy.zeros((self.__nch, self.n,self.__nHeis))
4503 self.__buffer2 = numpy.zeros(self.n)
4526 self.__buffer2 = numpy.zeros(self.n)
4504 self.__buffer3 = numpy.zeros(self.n)
4527 self.__buffer3 = numpy.zeros(self.n)
4505 self.__profIndex = 0
4528 self.__profIndex = 0
4506 #print("pushData")
4529 #print("pushData")
4507 return data_360,n,data_p,data_e
4530 return data_360,n,data_p,data_e
4508
4531
4509
4532
4510 def byProfiles(self,dataOut):
4533 def byProfiles(self,dataOut):
4511
4534
4512 self.__dataReady = False
4535 self.__dataReady = False
4513 data_360 = None
4536 data_360 = None
4514 data_p = None
4537 data_p = None
4515 data_e = None
4538 data_e = None
4516 #print("dataOu",dataOut.dataPP_POW)
4539 #print("dataOu",dataOut.dataPP_POW)
4517 self.putData(data=dataOut,mode = self.mode)
4540 self.putData(data=dataOut,mode = self.mode)
4518 ##### print("profIndex",self.__profIndex)
4541 ##### print("profIndex",self.__profIndex)
4519 if self.__profIndex == self.n:
4542 if self.__profIndex == self.n:
4520 data_360,n,data_p,data_e = self.pushData(data=dataOut)
4543 data_360,n,data_p,data_e = self.pushData(data=dataOut)
4521 self.__dataReady = True
4544 self.__dataReady = True
4522
4545
4523 return data_360,data_p,data_e
4546 return data_360,data_p,data_e
4524
4547
4525
4548
4526 def blockOp(self, dataOut, datatime= None):
4549 def blockOp(self, dataOut, datatime= None):
4527 if self.__initime == None:
4550 if self.__initime == None:
4528 self.__initime = datatime
4551 self.__initime = datatime
4529 data_360,data_p,data_e = self.byProfiles(dataOut)
4552 data_360,data_p,data_e = self.byProfiles(dataOut)
4530 self.__lastdatatime = datatime
4553 self.__lastdatatime = datatime
4531
4554
4532 if data_360 is None:
4555 if data_360 is None:
4533 return None, None,None,None
4556 return None, None,None,None
4534
4557
4535
4558
4536 avgdatatime = self.__initime
4559 avgdatatime = self.__initime
4537 if self.n==1:
4560 if self.n==1:
4538 avgdatatime = datatime
4561 avgdatatime = datatime
4539 deltatime = datatime - self.__lastdatatime
4562 deltatime = datatime - self.__lastdatatime
4540 self.__initime = datatime
4563 self.__initime = datatime
4541 #print(data_360.shape,avgdatatime,data_p.shape)
4564 #print(data_360.shape,avgdatatime,data_p.shape)
4542 return data_360,avgdatatime,data_p,data_e
4565 return data_360,avgdatatime,data_p,data_e
4543
4566
4544 def checkcase(self,data_ele):
4567 def checkcase(self,data_ele):
4545 start = data_ele[0]
4568 start = data_ele[0]
4546 end = data_ele[-1]
4569 end = data_ele[-1]
4547 diff_angle = (end-start)
4570 diff_angle = (end-start)
4548 len_ang=len(data_ele)
4571 len_ang=len(data_ele)
4549 print("start",start)
4572 print("start",start)
4550 print("end",end)
4573 print("end",end)
4551 print("number",diff_angle)
4574 print("number",diff_angle)
4552
4575
4553 print("len_ang",len_ang)
4576 print("len_ang",len_ang)
4554
4577
4555 aux = (data_ele<0).any(axis=0)
4578 aux = (data_ele<0).any(axis=0)
4556
4579
4557 #exit(1)
4580 #exit(1)
4558 if diff_angle<0 and aux!=1: #Bajada
4581 if diff_angle<0 and aux!=1: #Bajada
4559 return 1
4582 return 1
4560 elif diff_angle<0 and aux==1: #Bajada con angulos negativos
4583 elif diff_angle<0 and aux==1: #Bajada con angulos negativos
4561 return 0
4584 return 0
4562 elif diff_angle == 0: # This case happens when the angle reaches the max_angle if n = 2
4585 elif diff_angle == 0: # This case happens when the angle reaches the max_angle if n = 2
4563 self.flagEraseFirstData = 1
4586 self.flagEraseFirstData = 1
4564 print("ToDO this case")
4587 print("ToDO this case")
4565 exit(1)
4588 exit(1)
4566 elif diff_angle>0: #Subida
4589 elif diff_angle>0: #Subida
4567 return 0
4590 return 0
4568
4591
4569 def run(self, dataOut,n = None,mode=None,**kwargs):
4592 def run(self, dataOut,n = None,mode=None,**kwargs):
4570 #print("BLOCK 360 HERE WE GO MOMENTOS")
4593 #print("BLOCK 360 HERE WE GO MOMENTOS")
4571 print("Block 360")
4594 print("Block 360")
4572
4595
4573 #exit(1)
4596 #exit(1)
4574 if not self.isConfig:
4597 if not self.isConfig:
4575 if n == 1:
4598 if n == 1:
4576 print("*******************Min Value is 2. Setting n = 2*******************")
4599 print("*******************Min Value is 2. Setting n = 2*******************")
4577 n = 2
4600 n = 2
4578 #exit(1)
4601 #exit(1)
4579 print(n)
4602 print(n)
4580 self.setup(dataOut = dataOut, n = n ,mode= mode ,**kwargs)
4603 self.setup(dataOut = dataOut, n = n ,mode= mode ,**kwargs)
4581 ####self.index = 0
4604 ####self.index = 0
4582 #print("comova",self.isConfig)
4605 #print("comova",self.isConfig)
4583 self.isConfig = True
4606 self.isConfig = True
4584 ####if self.index==dataOut.azimuth.shape[0]:
4607 ####if self.index==dataOut.azimuth.shape[0]:
4585 #### self.index=0
4608 #### self.index=0
4586 data_360, avgdatatime,data_p,data_e = self.blockOp(dataOut, dataOut.utctime)
4609 data_360, avgdatatime,data_p,data_e = self.blockOp(dataOut, dataOut.utctime)
4587 dataOut.flagNoData = True
4610 dataOut.flagNoData = True
4588
4611
4589 if self.__dataReady:
4612 if self.__dataReady:
4590 dataOut.data_360 = data_360 # S
4613 dataOut.data_360 = data_360 # S
4591 #print("DATA 360")
4614 #print("DATA 360")
4592 #print(dataOut.data_360)
4615 #print(dataOut.data_360)
4593 #print("---------------------------------------------------------------------------------")
4616 #print("---------------------------------------------------------------------------------")
4594 print("---------------------------DATAREADY---------------------------------------------")
4617 print("---------------------------DATAREADY---------------------------------------------")
4595 #print("---------------------------------------------------------------------------------")
4618 #print("---------------------------------------------------------------------------------")
4596 #print("data_360",dataOut.data_360.shape)
4619 #print("data_360",dataOut.data_360.shape)
4597 dataOut.data_azi = data_p
4620 dataOut.data_azi = data_p
4598 dataOut.data_ele = data_e
4621 dataOut.data_ele = data_e
4599 ###print("azi: ",dataOut.data_azi)
4622 ###print("azi: ",dataOut.data_azi)
4600 #print("ele: ",dataOut.data_ele)
4623 #print("ele: ",dataOut.data_ele)
4601 #print("jroproc_parameters",data_p[0],data_p[-1])#,data_360.shape,avgdatatime)
4624 #print("jroproc_parameters",data_p[0],data_p[-1])#,data_360.shape,avgdatatime)
4602 dataOut.utctime = avgdatatime
4625 dataOut.utctime = avgdatatime
4603
4626
4604 dataOut.case_flag = self.checkcase(dataOut.data_ele)
4627 dataOut.case_flag = self.checkcase(dataOut.data_ele)
4605 if dataOut.case_flag: #Si estΓ‘ de bajada empieza a plotear
4628 if dataOut.case_flag: #Si estΓ‘ de bajada empieza a plotear
4606 print("INSIDE CASE FLAG BAJADA")
4629 print("INSIDE CASE FLAG BAJADA")
4607 dataOut.flagNoData = False
4630 dataOut.flagNoData = False
4608 else:
4631 else:
4609 print("CASE SUBIDA")
4632 print("CASE SUBIDA")
4610 dataOut.flagNoData = True
4633 dataOut.flagNoData = True
4611
4634
4612 #dataOut.flagNoData = False
4635 #dataOut.flagNoData = False
4613 return dataOut
4636 return dataOut
4614
4637
4615 class Block360_vRF2(Operation):
4638 class Block360_vRF2(Operation):
4616 '''
4639 '''
4617 '''
4640 '''
4618 isConfig = False
4641 isConfig = False
4619 __profIndex = 0
4642 __profIndex = 0
4620 __initime = None
4643 __initime = None
4621 __lastdatatime = None
4644 __lastdatatime = None
4622 __buffer = None
4645 __buffer = None
4623 __dataReady = False
4646 __dataReady = False
4624 n = None
4647 n = None
4625 __nch = 0
4648 __nch = 0
4626 __nHeis = 0
4649 __nHeis = 0
4627 index = 0
4650 index = 0
4628 mode = None
4651 mode = None
4629
4652
4630 def __init__(self,**kwargs):
4653 def __init__(self,**kwargs):
4631 Operation.__init__(self,**kwargs)
4654 Operation.__init__(self,**kwargs)
4632
4655
4633 def setup(self, dataOut, n = None, mode = None):
4656 def setup(self, dataOut, n = None, mode = None):
4634 '''
4657 '''
4635 n= Numero de PRF's de entrada
4658 n= Numero de PRF's de entrada
4636 '''
4659 '''
4637 self.__initime = None
4660 self.__initime = None
4638 self.__lastdatatime = 0
4661 self.__lastdatatime = 0
4639 self.__dataReady = False
4662 self.__dataReady = False
4640 self.__buffer = 0
4663 self.__buffer = 0
4641 self.__buffer_1D = 0
4664 self.__buffer_1D = 0
4642 #self.__profIndex = 0
4665 #self.__profIndex = 0
4643 self.index = 0
4666 self.index = 0
4644 self.__nch = dataOut.nChannels
4667 self.__nch = dataOut.nChannels
4645 self.__nHeis = dataOut.nHeights
4668 self.__nHeis = dataOut.nHeights
4646
4669
4647 self.mode = mode
4670 self.mode = mode
4648 #print("self.mode",self.mode)
4671 #print("self.mode",self.mode)
4649 #print("nHeights")
4672 #print("nHeights")
4650 self.__buffer = []
4673 self.__buffer = []
4651 self.__buffer2 = []
4674 self.__buffer2 = []
4652 self.__buffer3 = []
4675 self.__buffer3 = []
4653 self.__buffer4 = []
4676 self.__buffer4 = []
4654
4677
4655 def putData(self,data,mode):
4678 def putData(self,data,mode):
4656 '''
4679 '''
4657 Add a profile to he __buffer and increase in one the __profiel Index
4680 Add a profile to he __buffer and increase in one the __profiel Index
4658 '''
4681 '''
4659
4682
4660 if self.mode==0:
4683 if self.mode==0:
4661 self.__buffer.append(data.dataPP_POWER)# PRIMER MOMENTO
4684 self.__buffer.append(data.dataPP_POWER)# PRIMER MOMENTO
4662 if self.mode==1:
4685 if self.mode==1:
4663 self.__buffer.append(data.data_pow)
4686 self.__buffer.append(data.data_pow)
4664
4687
4665 self.__buffer4.append(data.dataPP_DOP)
4688 self.__buffer4.append(data.dataPP_DOP)
4666
4689
4667 self.__buffer2.append(data.azimuth)
4690 self.__buffer2.append(data.azimuth)
4668 self.__buffer3.append(data.elevation)
4691 self.__buffer3.append(data.elevation)
4669 self.__profIndex += 1
4692 self.__profIndex += 1
4670
4693
4671 return numpy.array(self.__buffer3) #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Remove DCΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
4694 return numpy.array(self.__buffer3) #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Remove DCΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
4672
4695
4673 def pushData(self,data):
4696 def pushData(self,data):
4674 '''
4697 '''
4675 Return the PULSEPAIR and the profiles used in the operation
4698 Return the PULSEPAIR and the profiles used in the operation
4676 Affected : self.__profileIndex
4699 Affected : self.__profileIndex
4677 '''
4700 '''
4678
4701
4679 data_360_Power = numpy.array(self.__buffer).transpose(1,0,2)
4702 data_360_Power = numpy.array(self.__buffer).transpose(1,0,2)
4680 data_360_Velocity = numpy.array(self.__buffer4).transpose(1,0,2)
4703 data_360_Velocity = numpy.array(self.__buffer4).transpose(1,0,2)
4681 data_p = numpy.array(self.__buffer2)
4704 data_p = numpy.array(self.__buffer2)
4682 data_e = numpy.array(self.__buffer3)
4705 data_e = numpy.array(self.__buffer3)
4683 n = self.__profIndex
4706 n = self.__profIndex
4684
4707
4685 self.__buffer = []
4708 self.__buffer = []
4686 self.__buffer4 = []
4709 self.__buffer4 = []
4687 self.__buffer2 = []
4710 self.__buffer2 = []
4688 self.__buffer3 = []
4711 self.__buffer3 = []
4689 self.__profIndex = 0
4712 self.__profIndex = 0
4690 return data_360_Power,data_360_Velocity,n,data_p,data_e
4713 return data_360_Power,data_360_Velocity,n,data_p,data_e
4691
4714
4692
4715
4693 def byProfiles(self,dataOut):
4716 def byProfiles(self,dataOut):
4694
4717
4695 self.__dataReady = False
4718 self.__dataReady = False
4696 data_360_Power = []
4719 data_360_Power = []
4697 data_360_Velocity = []
4720 data_360_Velocity = []
4698 data_p = None
4721 data_p = None
4699 data_e = None
4722 data_e = None
4700
4723
4701 elevations = self.putData(data=dataOut,mode = self.mode)
4724 elevations = self.putData(data=dataOut,mode = self.mode)
4702
4725
4703 if self.__profIndex > 1:
4726 if self.__profIndex > 1:
4704 case_flag = self.checkcase(elevations)
4727 case_flag = self.checkcase(elevations)
4705
4728
4706 if case_flag == 0: #Subida
4729 if case_flag == 0: #Subida
4707
4730
4708 if len(self.__buffer) == 2: #Cuando estΓ‘ de subida
4731 if len(self.__buffer) == 2: #Cuando estΓ‘ de subida
4709 #Se borra el dato anterior para liberar buffer y comparar el dato actual con el siguiente
4732 #Se borra el dato anterior para liberar buffer y comparar el dato actual con el siguiente
4710 self.__buffer.pop(0) #Erase first data
4733 self.__buffer.pop(0) #Erase first data
4711 self.__buffer2.pop(0)
4734 self.__buffer2.pop(0)
4712 self.__buffer3.pop(0)
4735 self.__buffer3.pop(0)
4713 self.__buffer4.pop(0)
4736 self.__buffer4.pop(0)
4714 self.__profIndex -= 1
4737 self.__profIndex -= 1
4715 else: #Cuando ha estado de bajada y ha vuelto a subir
4738 else: #Cuando ha estado de bajada y ha vuelto a subir
4716 #Se borra el ΓΊltimo dato
4739 #Se borra el ΓΊltimo dato
4717 self.__buffer.pop() #Erase last data
4740 self.__buffer.pop() #Erase last data
4718 self.__buffer2.pop()
4741 self.__buffer2.pop()
4719 self.__buffer3.pop()
4742 self.__buffer3.pop()
4720 self.__buffer4.pop()
4743 self.__buffer4.pop()
4721 data_360_Power,data_360_Velocity,n,data_p,data_e = self.pushData(data=dataOut)
4744 data_360_Power,data_360_Velocity,n,data_p,data_e = self.pushData(data=dataOut)
4722
4745
4723 self.__dataReady = True
4746 self.__dataReady = True
4724
4747
4725 return data_360_Power,data_360_Velocity,data_p,data_e
4748 return data_360_Power,data_360_Velocity,data_p,data_e
4726
4749
4727
4750
4728 def blockOp(self, dataOut, datatime= None):
4751 def blockOp(self, dataOut, datatime= None):
4729 if self.__initime == None:
4752 if self.__initime == None:
4730 self.__initime = datatime
4753 self.__initime = datatime
4731 data_360_Power,data_360_Velocity,data_p,data_e = self.byProfiles(dataOut)
4754 data_360_Power,data_360_Velocity,data_p,data_e = self.byProfiles(dataOut)
4732 self.__lastdatatime = datatime
4755 self.__lastdatatime = datatime
4733
4756
4734 avgdatatime = self.__initime
4757 avgdatatime = self.__initime
4735 if self.n==1:
4758 if self.n==1:
4736 avgdatatime = datatime
4759 avgdatatime = datatime
4737 deltatime = datatime - self.__lastdatatime
4760 deltatime = datatime - self.__lastdatatime
4738 self.__initime = datatime
4761 self.__initime = datatime
4739 return data_360_Power,data_360_Velocity,avgdatatime,data_p,data_e
4762 return data_360_Power,data_360_Velocity,avgdatatime,data_p,data_e
4740
4763
4741 def checkcase(self,data_ele):
4764 def checkcase(self,data_ele):
4742 #print(data_ele)
4765 #print(data_ele)
4743 start = data_ele[-2]
4766 start = data_ele[-2]
4744 end = data_ele[-1]
4767 end = data_ele[-1]
4745 diff_angle = (end-start)
4768 diff_angle = (end-start)
4746 len_ang=len(data_ele)
4769 len_ang=len(data_ele)
4747
4770
4748 if diff_angle > 0: #Subida
4771 if diff_angle > 0: #Subida
4749 return 0
4772 return 0
4750
4773
4751 def run(self, dataOut,mode='Power',**kwargs):
4774 def run(self, dataOut,mode='Power',**kwargs):
4752 #print("BLOCK 360 HERE WE GO MOMENTOS")
4775 #print("BLOCK 360 HERE WE GO MOMENTOS")
4753 #print("Block 360")
4776 #print("Block 360")
4754 dataOut.mode = mode
4777 dataOut.mode = mode
4755
4778
4756 if not self.isConfig:
4779 if not self.isConfig:
4757 self.setup(dataOut = dataOut ,mode= mode ,**kwargs)
4780 self.setup(dataOut = dataOut ,mode= mode ,**kwargs)
4758 self.isConfig = True
4781 self.isConfig = True
4759
4782
4760
4783
4761 data_360_Power, data_360_Velocity, avgdatatime,data_p,data_e = self.blockOp(dataOut, dataOut.utctime)
4784 data_360_Power, data_360_Velocity, avgdatatime,data_p,data_e = self.blockOp(dataOut, dataOut.utctime)
4762
4785
4763
4786
4764 dataOut.flagNoData = True
4787 dataOut.flagNoData = True
4765
4788
4766
4789
4767 if self.__dataReady:
4790 if self.__dataReady:
4768 dataOut.data_360_Power = data_360_Power # S
4791 dataOut.data_360_Power = data_360_Power # S
4769 dataOut.data_360_Velocity = data_360_Velocity
4792 dataOut.data_360_Velocity = data_360_Velocity
4770 dataOut.data_azi = data_p
4793 dataOut.data_azi = data_p
4771 dataOut.data_ele = data_e
4794 dataOut.data_ele = data_e
4772 dataOut.utctime = avgdatatime
4795 dataOut.utctime = avgdatatime
4773 dataOut.flagNoData = False
4796 dataOut.flagNoData = False
4774
4797
4775 return dataOut
4798 return dataOut
4776
4799
4777 class Block360_vRF3(Operation):
4800 class Block360_vRF3(Operation):
4778 '''
4801 '''
4779 '''
4802 '''
4780 isConfig = False
4803 isConfig = False
4781 __profIndex = 0
4804 __profIndex = 0
4782 __initime = None
4805 __initime = None
4783 __lastdatatime = None
4806 __lastdatatime = None
4784 __buffer = None
4807 __buffer = None
4785 __dataReady = False
4808 __dataReady = False
4786 n = None
4809 n = None
4787 __nch = 0
4810 __nch = 0
4788 __nHeis = 0
4811 __nHeis = 0
4789 index = 0
4812 index = 0
4790 mode = None
4813 mode = None
4791
4814
4792 def __init__(self,**kwargs):
4815 def __init__(self,**kwargs):
4793 Operation.__init__(self,**kwargs)
4816 Operation.__init__(self,**kwargs)
4794
4817
4795 def setup(self, dataOut, attr):
4818 def setup(self, dataOut, attr):
4796 '''
4819 '''
4797 n= Numero de PRF's de entrada
4820 n= Numero de PRF's de entrada
4798 '''
4821 '''
4799 self.__initime = None
4822 self.__initime = None
4800 self.__lastdatatime = 0
4823 self.__lastdatatime = 0
4801 self.__dataReady = False
4824 self.__dataReady = False
4802 self.__buffer = 0
4825 self.__buffer = 0
4803 self.__buffer_1D = 0
4826 self.__buffer_1D = 0
4804 self.index = 0
4827 self.index = 0
4805 self.__nch = dataOut.nChannels
4828 self.__nch = dataOut.nChannels
4806 self.__nHeis = dataOut.nHeights
4829 self.__nHeis = dataOut.nHeights
4807
4830
4808 self.attr = attr
4831 self.attr = attr
4809 #print("self.mode",self.mode)
4832 #print("self.mode",self.mode)
4810 #print("nHeights")
4833 #print("nHeights")
4811 self.__buffer = []
4834 self.__buffer = []
4812 self.__buffer2 = []
4835 self.__buffer2 = []
4813 self.__buffer3 = []
4836 self.__buffer3 = []
4814
4837
4815 def putData(self, data, attr):
4838 def putData(self, data, attr):
4816 '''
4839 '''
4817 Add a profile to he __buffer and increase in one the __profiel Index
4840 Add a profile to he __buffer and increase in one the __profiel Index
4818 '''
4841 '''
4819
4842
4820 self.__buffer.append(getattr(data, attr))
4843 self.__buffer.append(getattr(data, attr))
4821 self.__buffer2.append(data.azimuth)
4844 self.__buffer2.append(data.azimuth)
4822 self.__buffer3.append(data.elevation)
4845 self.__buffer3.append(data.elevation)
4823 self.__profIndex += 1
4846 self.__profIndex += 1
4824
4847
4825 return numpy.array(self.__buffer3)
4848 return numpy.array(self.__buffer3)
4826
4849
4827 def pushData(self, data):
4850 def pushData(self, data):
4828 '''
4851 '''
4829 Return the PULSEPAIR and the profiles used in the operation
4852 Return the PULSEPAIR and the profiles used in the operation
4830 Affected : self.__profileIndex
4853 Affected : self.__profileIndex
4831 '''
4854 '''
4832
4855
4833 data_360 = numpy.array(self.__buffer).transpose(1, 0, 2)
4856 data_360 = numpy.array(self.__buffer).transpose(1, 0, 2)
4834 data_p = numpy.array(self.__buffer2)
4857 data_p = numpy.array(self.__buffer2)
4835 data_e = numpy.array(self.__buffer3)
4858 data_e = numpy.array(self.__buffer3)
4836 n = self.__profIndex
4859 n = self.__profIndex
4837
4860
4838 self.__buffer = []
4861 self.__buffer = []
4839 self.__buffer2 = []
4862 self.__buffer2 = []
4840 self.__buffer3 = []
4863 self.__buffer3 = []
4841 self.__profIndex = 0
4864 self.__profIndex = 0
4842 return data_360, n, data_p, data_e
4865 return data_360, n, data_p, data_e
4843
4866
4844
4867
4845 def byProfiles(self,dataOut):
4868 def byProfiles(self,dataOut):
4846
4869
4847 self.__dataReady = False
4870 self.__dataReady = False
4848 data_360 = []
4871 data_360 = []
4849 data_p = None
4872 data_p = None
4850 data_e = None
4873 data_e = None
4851
4874
4852 elevations = self.putData(data=dataOut, attr = self.attr)
4875 elevations = self.putData(data=dataOut, attr = self.attr)
4853
4876
4854 if self.__profIndex > 1:
4877 if self.__profIndex > 1:
4855 case_flag = self.checkcase(elevations)
4878 case_flag = self.checkcase(elevations)
4856
4879
4857 if case_flag == 0: #Subida
4880 if case_flag == 0: #Subida
4858
4881
4859 if len(self.__buffer) == 2: #Cuando estΓ‘ de subida
4882 if len(self.__buffer) == 2: #Cuando estΓ‘ de subida
4860 #Se borra el dato anterior para liberar buffer y comparar el dato actual con el siguiente
4883 #Se borra el dato anterior para liberar buffer y comparar el dato actual con el siguiente
4861 self.__buffer.pop(0) #Erase first data
4884 self.__buffer.pop(0) #Erase first data
4862 self.__buffer2.pop(0)
4885 self.__buffer2.pop(0)
4863 self.__buffer3.pop(0)
4886 self.__buffer3.pop(0)
4864 self.__profIndex -= 1
4887 self.__profIndex -= 1
4865 else: #Cuando ha estado de bajada y ha vuelto a subir
4888 else: #Cuando ha estado de bajada y ha vuelto a subir
4866 #Se borra el ΓΊltimo dato
4889 #Se borra el ΓΊltimo dato
4867 self.__buffer.pop() #Erase last data
4890 self.__buffer.pop() #Erase last data
4868 self.__buffer2.pop()
4891 self.__buffer2.pop()
4869 self.__buffer3.pop()
4892 self.__buffer3.pop()
4870 data_360, n, data_p, data_e = self.pushData(data=dataOut)
4893 data_360, n, data_p, data_e = self.pushData(data=dataOut)
4871
4894
4872 self.__dataReady = True
4895 self.__dataReady = True
4873
4896
4874 return data_360, data_p, data_e
4897 return data_360, data_p, data_e
4875
4898
4876
4899
4877 def blockOp(self, dataOut, datatime= None):
4900 def blockOp(self, dataOut, datatime= None):
4878 if self.__initime == None:
4901 if self.__initime == None:
4879 self.__initime = datatime
4902 self.__initime = datatime
4880 data_360, data_p, data_e = self.byProfiles(dataOut)
4903 data_360, data_p, data_e = self.byProfiles(dataOut)
4881 self.__lastdatatime = datatime
4904 self.__lastdatatime = datatime
4882
4905
4883 avgdatatime = self.__initime
4906 avgdatatime = self.__initime
4884 if self.n==1:
4907 if self.n==1:
4885 avgdatatime = datatime
4908 avgdatatime = datatime
4886 deltatime = datatime - self.__lastdatatime
4909 deltatime = datatime - self.__lastdatatime
4887 self.__initime = datatime
4910 self.__initime = datatime
4888 return data_360, avgdatatime, data_p, data_e
4911 return data_360, avgdatatime, data_p, data_e
4889
4912
4890 def checkcase(self, data_ele):
4913 def checkcase(self, data_ele):
4891
4914
4892 start = data_ele[-2]
4915 start = data_ele[-2]
4893 end = data_ele[-1]
4916 end = data_ele[-1]
4894 diff_angle = (end-start)
4917 diff_angle = (end-start)
4895 len_ang=len(data_ele)
4918 len_ang=len(data_ele)
4896
4919
4897 if diff_angle > 0: #Subida
4920 if diff_angle > 0: #Subida
4898 return 0
4921 return 0
4899
4922
4900 def run(self, dataOut, attr_data='dataPP_POWER',**kwargs):
4923 def run(self, dataOut, attr_data='dataPP_POWER',**kwargs):
4901
4924
4902 dataOut.attr_data = attr_data
4925 dataOut.attr_data = attr_data
4903
4926
4904 if not self.isConfig:
4927 if not self.isConfig:
4905 self.setup(dataOut = dataOut, attr = attr_data ,**kwargs)
4928 self.setup(dataOut = dataOut, attr = attr_data ,**kwargs)
4906 self.isConfig = True
4929 self.isConfig = True
4907
4930
4908 data_360, avgdatatime, data_p, data_e = self.blockOp(dataOut, dataOut.utctime)
4931 data_360, avgdatatime, data_p, data_e = self.blockOp(dataOut, dataOut.utctime)
4909
4932
4910 dataOut.flagNoData = True
4933 dataOut.flagNoData = True
4911
4934
4912 if self.__dataReady:
4935 if self.__dataReady:
4913 setattr(dataOut, attr_data, data_360 )
4936 setattr(dataOut, attr_data, data_360 )
4914 dataOut.data_azi = data_p
4937 dataOut.data_azi = data_p
4915 dataOut.data_ele = data_e
4938 dataOut.data_ele = data_e
4916 dataOut.utctime = avgdatatime
4939 dataOut.utctime = avgdatatime
4917 dataOut.flagNoData = False
4940 dataOut.flagNoData = False
4918
4941
4919 return dataOut
4942 return dataOut
4920
4943
4921 class Block360_vRF4(Operation):
4944 class Block360_vRF4(Operation):
4922 '''
4945 '''
4923 '''
4946 '''
4924 isConfig = False
4947 isConfig = False
4925 __profIndex = 0
4948 __profIndex = 0
4926 __initime = None
4949 __initime = None
4927 __lastdatatime = None
4950 __lastdatatime = None
4928 __buffer = None
4951 __buffer = None
4929 __dataReady = False
4952 __dataReady = False
4930 n = None
4953 n = None
4931 __nch = 0
4954 __nch = 0
4932 __nHeis = 0
4955 __nHeis = 0
4933 index = 0
4956 index = 0
4934 mode = None
4957 mode = None
4935
4958
4936 def __init__(self,**kwargs):
4959 def __init__(self,**kwargs):
4937 Operation.__init__(self,**kwargs)
4960 Operation.__init__(self,**kwargs)
4938
4961
4939 def setup(self, dataOut, attr):
4962 def setup(self, dataOut, attr):
4940 '''
4963 '''
4941 n= Numero de PRF's de entrada
4964 n= Numero de PRF's de entrada
4942 '''
4965 '''
4943 self.__initime = None
4966 self.__initime = None
4944 self.__lastdatatime = 0
4967 self.__lastdatatime = 0
4945 self.__dataReady = False
4968 self.__dataReady = False
4946 self.__buffer = 0
4969 self.__buffer = 0
4947 self.__buffer_1D = 0
4970 self.__buffer_1D = 0
4948 self.index = 0
4971 self.index = 0
4949 self.__nch = dataOut.nChannels
4972 self.__nch = dataOut.nChannels
4950 self.__nHeis = dataOut.nHeights
4973 self.__nHeis = dataOut.nHeights
4951
4974
4952 self.attr = attr
4975 self.attr = attr
4953
4976
4954 self.__buffer = []
4977 self.__buffer = []
4955 self.__buffer2 = []
4978 self.__buffer2 = []
4956 self.__buffer3 = []
4979 self.__buffer3 = []
4957
4980
4958 def putData(self, data, attr, flagMode):
4981 def putData(self, data, attr, flagMode):
4959 '''
4982 '''
4960 Add a profile to he __buffer and increase in one the __profiel Index
4983 Add a profile to he __buffer and increase in one the __profiel Index
4961 '''
4984 '''
4962 tmp= getattr(data, attr)
4985 tmp= getattr(data, attr)
4963 if tmp.shape[0] != 2:
4986 if tmp.shape[0] != 2:
4964 size_tmp= tmp.shape[0]
4987 size_tmp= tmp.shape[0]
4965 tmp=tmp.reshape(1,size_tmp)
4988 tmp=tmp.reshape(1,size_tmp)
4966
4989
4967 self.__buffer.append(tmp)
4990 self.__buffer.append(tmp)
4968 self.__buffer2.append(data.azimuth)
4991 self.__buffer2.append(data.azimuth)
4969 self.__buffer3.append(data.elevation)
4992 self.__buffer3.append(data.elevation)
4970 self.__profIndex += 1
4993 self.__profIndex += 1
4971
4994
4972 if flagMode == 1: #'AZI'
4995 if flagMode == 1: #'AZI'
4973 return numpy.array(self.__buffer2)
4996 return numpy.array(self.__buffer2)
4974 elif flagMode == 0: #'ELE'
4997 elif flagMode == 0: #'ELE'
4975 return numpy.array(self.__buffer3)
4998 return numpy.array(self.__buffer3)
4976
4999
4977 def pushData(self, data,flagMode,case_flag):
5000 def pushData(self, data,flagMode,case_flag):
4978 '''
5001 '''
4979 Return the PULSEPAIR and the profiles used in the operation
5002 Return the PULSEPAIR and the profiles used in the operation
4980 Affected : self.__profileIndex
5003 Affected : self.__profileIndex
4981 '''
5004 '''
4982
5005
4983 data_360 = numpy.array(self.__buffer).transpose(1, 0, 2)
5006 data_360 = numpy.array(self.__buffer).transpose(1, 0, 2)
4984 data_p = numpy.array(self.__buffer2)
5007 data_p = numpy.array(self.__buffer2)
4985 data_e = numpy.array(self.__buffer3)
5008 data_e = numpy.array(self.__buffer3)
4986 n = self.__profIndex
5009 n = self.__profIndex
4987
5010
4988 self.__buffer = []
5011 self.__buffer = []
4989 self.__buffer2 = []
5012 self.__buffer2 = []
4990 self.__buffer3 = []
5013 self.__buffer3 = []
4991 self.__profIndex = 0
5014 self.__profIndex = 0
4992
5015
4993 if flagMode == 1 and case_flag == 0: #'AZI' y ha girado
5016 if flagMode == 1 and case_flag == 0: #'AZI' y ha girado
4994 self.putData(data=data, attr = self.attr, flagMode=flagMode)
5017 self.putData(data=data, attr = self.attr, flagMode=flagMode)
4995
5018
4996 return data_360, n, data_p, data_e
5019 return data_360, n, data_p, data_e
4997
5020
4998
5021
4999 def byProfiles(self,dataOut,flagMode):
5022 def byProfiles(self,dataOut,flagMode):
5000
5023
5001 self.__dataReady = False
5024 self.__dataReady = False
5002 data_360 = []
5025 data_360 = []
5003 data_p = None
5026 data_p = None
5004 data_e = None
5027 data_e = None
5005
5028
5006 angles = self.putData(data=dataOut, attr = self.attr, flagMode=flagMode)
5029 angles = self.putData(data=dataOut, attr = self.attr, flagMode=flagMode)
5007 #print("ANGLES",angles)
5030 #print("ANGLES",angles)
5008 if self.__profIndex > 1:
5031 if self.__profIndex > 1:
5009 case_flag = self.checkcase(angles,flagMode)
5032 case_flag = self.checkcase(angles,flagMode)
5010
5033
5011 if flagMode == 1: #'AZI':
5034 if flagMode == 1: #'AZI':
5012 if case_flag == 0: #Ya girΓ³
5035 if case_flag == 0: #Ya girΓ³
5013 self.__buffer.pop() #Erase last data
5036 self.__buffer.pop() #Erase last data
5014 self.__buffer2.pop()
5037 self.__buffer2.pop()
5015 self.__buffer3.pop()
5038 self.__buffer3.pop()
5016 data_360,n,data_p,data_e = self.pushData(data=dataOut,flagMode=flagMode,case_flag=case_flag)
5039 data_360,n,data_p,data_e = self.pushData(data=dataOut,flagMode=flagMode,case_flag=case_flag)
5017
5040
5018 self.__dataReady = True
5041 self.__dataReady = True
5019
5042
5020 elif flagMode == 0: #'ELE'
5043 elif flagMode == 0: #'ELE'
5021
5044
5022 if case_flag == 0: #Subida
5045 if case_flag == 0: #Subida
5023
5046
5024 if len(self.__buffer) == 2: #Cuando estΓ‘ de subida
5047 if len(self.__buffer) == 2: #Cuando estΓ‘ de subida
5025 #Se borra el dato anterior para liberar buffer y comparar el dato actual con el siguiente
5048 #Se borra el dato anterior para liberar buffer y comparar el dato actual con el siguiente
5026 self.__buffer.pop(0) #Erase first data
5049 self.__buffer.pop(0) #Erase first data
5027 self.__buffer2.pop(0)
5050 self.__buffer2.pop(0)
5028 self.__buffer3.pop(0)
5051 self.__buffer3.pop(0)
5029 self.__profIndex -= 1
5052 self.__profIndex -= 1
5030 else: #Cuando ha estado de bajada y ha vuelto a subir
5053 else: #Cuando ha estado de bajada y ha vuelto a subir
5031 #Se borra el ΓΊltimo dato
5054 #Se borra el ΓΊltimo dato
5032 self.__buffer.pop() #Erase last data
5055 self.__buffer.pop() #Erase last data
5033 self.__buffer2.pop()
5056 self.__buffer2.pop()
5034 self.__buffer3.pop()
5057 self.__buffer3.pop()
5035 data_360, n, data_p, data_e = self.pushData(data=dataOut,flagMode=flagMode,case_flag=case_flag)
5058 data_360, n, data_p, data_e = self.pushData(data=dataOut,flagMode=flagMode,case_flag=case_flag)
5036
5059
5037 self.__dataReady = True
5060 self.__dataReady = True
5038
5061
5039 return data_360, data_p, data_e
5062 return data_360, data_p, data_e
5040
5063
5041
5064
5042 def blockOp(self, dataOut, flagMode, datatime= None):
5065 def blockOp(self, dataOut, flagMode, datatime= None):
5043 if self.__initime == None:
5066 if self.__initime == None:
5044 self.__initime = datatime
5067 self.__initime = datatime
5045 data_360, data_p, data_e = self.byProfiles(dataOut,flagMode)
5068 data_360, data_p, data_e = self.byProfiles(dataOut,flagMode)
5046 self.__lastdatatime = datatime
5069 self.__lastdatatime = datatime
5047
5070
5048 avgdatatime = self.__initime
5071 avgdatatime = self.__initime
5049 if self.n==1:
5072 if self.n==1:
5050 avgdatatime = datatime
5073 avgdatatime = datatime
5051 deltatime = datatime - self.__lastdatatime
5074 deltatime = datatime - self.__lastdatatime
5052 self.__initime = datatime
5075 self.__initime = datatime
5053 return data_360, avgdatatime, data_p, data_e
5076 return data_360, avgdatatime, data_p, data_e
5054
5077
5055 def checkcase(self, angles, flagMode):
5078 def checkcase(self, angles, flagMode):
5056
5079
5057 if flagMode == 1: #'AZI'
5080 if flagMode == 1: #'AZI'
5058 start = angles[-2]
5081 start = angles[-2]
5059 end = angles[-1]
5082 end = angles[-1]
5060 diff_angle = (end-start)
5083 diff_angle = (end-start)
5061
5084
5062 if diff_angle < 0: #Ya girΓ³
5085 if diff_angle < 0: #Ya girΓ³
5063 return 0
5086 return 0
5064
5087
5065 elif flagMode == 0: #'ELE'
5088 elif flagMode == 0: #'ELE'
5066
5089
5067 start = angles[-2]
5090 start = angles[-2]
5068 end = angles[-1]
5091 end = angles[-1]
5069 diff_angle = (end-start)
5092 diff_angle = (end-start)
5070
5093
5071 if diff_angle > 0: #Subida
5094 if diff_angle > 0: #Subida
5072 return 0
5095 return 0
5073
5096
5074 def run(self, dataOut, attr_data='dataPP_POWER', runNextOp = False,**kwargs):
5097 def run(self, dataOut, attr_data='dataPP_POWER', runNextOp = False,**kwargs):
5075
5098
5076 dataOut.attr_data = attr_data
5099 dataOut.attr_data = attr_data
5077 dataOut.runNextOp = runNextOp
5100 dataOut.runNextOp = runNextOp
5078 dataOut.flagAskMode = False
5101 dataOut.flagAskMode = False
5079 #print("Block 360")
5102 #print("Block 360")
5080 #dataOut.flagMode = axis[0] #Provisional, deberΓ­a venir del header
5103 #dataOut.flagMode = axis[0] #Provisional, deberΓ­a venir del header
5081 if dataOut.mode_op == 'PPI':
5104 if dataOut.mode_op == 'PPI':
5082 dataOut.flagMode = 1
5105 dataOut.flagMode = 1
5083 elif dataOut.mode_op == 'RHI':
5106 elif dataOut.mode_op == 'RHI':
5084 dataOut.flagMode = 0
5107 dataOut.flagMode = 0
5085
5108
5086 if not self.isConfig:
5109 if not self.isConfig:
5087 self.setup(dataOut = dataOut, attr = attr_data ,**kwargs)
5110 self.setup(dataOut = dataOut, attr = attr_data ,**kwargs)
5088 self.isConfig = True
5111 self.isConfig = True
5089
5112
5090 data_360, avgdatatime, data_p, data_e = self.blockOp(dataOut, dataOut.flagMode, dataOut.utctime)
5113 data_360, avgdatatime, data_p, data_e = self.blockOp(dataOut, dataOut.flagMode, dataOut.utctime)
5091
5114
5092 dataOut.flagNoData = True
5115 dataOut.flagNoData = True
5093
5116
5094 if self.__dataReady:
5117 if self.__dataReady:
5095 setattr(dataOut, attr_data, data_360 )
5118 setattr(dataOut, attr_data, data_360 )
5096 dataOut.data_azi = data_p
5119 dataOut.data_azi = data_p
5097 dataOut.data_ele = data_e
5120 dataOut.data_ele = data_e
5098 dataOut.utctime = avgdatatime
5121 dataOut.utctime = avgdatatime
5099 dataOut.flagNoData = False
5122 dataOut.flagNoData = False
5100 dataOut.flagAskMode = True
5123 dataOut.flagAskMode = True
5101 print("AZI: ",dataOut.data_azi)
5124 print("AZI: ",dataOut.data_azi)
5102 print("ELE: ",dataOut.data_ele)
5125 print("ELE: ",dataOut.data_ele)
5103 #print("********************attr_data********************",attr_data)
5126 #print("********************attr_data********************",attr_data)
5104 #print(data_360.shape)
5127 #print(data_360.shape)
5105 #print(dataOut.heightList)
5128 #print(dataOut.heightList)
5106
5129
5107 return dataOut
5130 return dataOut
5108
5131
5109 class MergeProc(ProcessingUnit):
5132 class MergeProc(ProcessingUnit):
5110
5133
5111 def __init__(self):
5134 def __init__(self):
5112 ProcessingUnit.__init__(self)
5135 ProcessingUnit.__init__(self)
5113
5136
5114 def run(self, attr_data, mode=0):
5137 def run(self, attr_data, mode=0):
5115
5138
5116 #exit(1)
5139 #exit(1)
5117 self.dataOut = getattr(self, self.inputs[0])
5140 self.dataOut = getattr(self, self.inputs[0])
5118 data_inputs = [getattr(self, attr) for attr in self.inputs]
5141 data_inputs = [getattr(self, attr) for attr in self.inputs]
5119 #print(data_inputs)
5142 #print(data_inputs)
5120 #print(numpy.shape([getattr(data, attr_data) for data in data_inputs][1]))
5143 #print(numpy.shape([getattr(data, attr_data) for data in data_inputs][1]))
5121 #exit(1)
5144 #exit(1)
5122 if mode==0:
5145 if mode==0:
5123 data = numpy.concatenate([getattr(data, attr_data) for data in data_inputs])
5146 data = numpy.concatenate([getattr(data, attr_data) for data in data_inputs])
5124 setattr(self.dataOut, attr_data, data)
5147 setattr(self.dataOut, attr_data, data)
5125
5148
5126 if mode==1: #Hybrid
5149 if mode==1: #Hybrid
5127 #data = numpy.concatenate([getattr(data, attr_data) for data in data_inputs],axis=1)
5150 #data = numpy.concatenate([getattr(data, attr_data) for data in data_inputs],axis=1)
5128 #setattr(self.dataOut, attr_data, data)
5151 #setattr(self.dataOut, attr_data, data)
5129 setattr(self.dataOut, 'dataLag_spc', [getattr(data, attr_data) for data in data_inputs][0])
5152 setattr(self.dataOut, 'dataLag_spc', [getattr(data, attr_data) for data in data_inputs][0])
5130 setattr(self.dataOut, 'dataLag_spc_LP', [getattr(data, attr_data) for data in data_inputs][1])
5153 setattr(self.dataOut, 'dataLag_spc_LP', [getattr(data, attr_data) for data in data_inputs][1])
5131 setattr(self.dataOut, 'dataLag_cspc', [getattr(data, attr_data_2) for data in data_inputs][0])
5154 setattr(self.dataOut, 'dataLag_cspc', [getattr(data, attr_data_2) for data in data_inputs][0])
5132 setattr(self.dataOut, 'dataLag_cspc_LP', [getattr(data, attr_data_2) for data in data_inputs][1])
5155 setattr(self.dataOut, 'dataLag_cspc_LP', [getattr(data, attr_data_2) for data in data_inputs][1])
5133 #setattr(self.dataOut, 'nIncohInt', [getattr(data, attr_data_3) for data in data_inputs][0])
5156 #setattr(self.dataOut, 'nIncohInt', [getattr(data, attr_data_3) for data in data_inputs][0])
5134 #setattr(self.dataOut, 'nIncohInt_LP', [getattr(data, attr_data_3) for data in data_inputs][1])
5157 #setattr(self.dataOut, 'nIncohInt_LP', [getattr(data, attr_data_3) for data in data_inputs][1])
5135 '''
5158 '''
5136 print(self.dataOut.dataLag_spc_LP.shape)
5159 print(self.dataOut.dataLag_spc_LP.shape)
5137 print(self.dataOut.dataLag_cspc_LP.shape)
5160 print(self.dataOut.dataLag_cspc_LP.shape)
5138 exit(1)
5161 exit(1)
5139 '''
5162 '''
5140
5163
5141 #self.dataOut.dataLag_spc_LP = numpy.transpose(self.dataOut.dataLag_spc_LP[0],(2,0,1))
5164 #self.dataOut.dataLag_spc_LP = numpy.transpose(self.dataOut.dataLag_spc_LP[0],(2,0,1))
5142 #self.dataOut.dataLag_cspc_LP = numpy.transpose(self.dataOut.dataLag_cspc_LP,(3,1,2,0))
5165 #self.dataOut.dataLag_cspc_LP = numpy.transpose(self.dataOut.dataLag_cspc_LP,(3,1,2,0))
5143 '''
5166 '''
5144 print("Merge")
5167 print("Merge")
5145 print(numpy.shape(self.dataOut.dataLag_spc))
5168 print(numpy.shape(self.dataOut.dataLag_spc))
5146 print(numpy.shape(self.dataOut.dataLag_spc_LP))
5169 print(numpy.shape(self.dataOut.dataLag_spc_LP))
5147 print(numpy.shape(self.dataOut.dataLag_cspc))
5170 print(numpy.shape(self.dataOut.dataLag_cspc))
5148 print(numpy.shape(self.dataOut.dataLag_cspc_LP))
5171 print(numpy.shape(self.dataOut.dataLag_cspc_LP))
5149 exit(1)
5172 exit(1)
5150 '''
5173 '''
5151 #print(numpy.sum(self.dataOut.dataLag_spc_LP[2,:,164])/128)
5174 #print(numpy.sum(self.dataOut.dataLag_spc_LP[2,:,164])/128)
5152 #print(numpy.sum(self.dataOut.dataLag_cspc_LP[0,:,30,1])/128)
5175 #print(numpy.sum(self.dataOut.dataLag_cspc_LP[0,:,30,1])/128)
5153 #exit(1)
5176 #exit(1)
5154 #print(self.dataOut.NDP)
5177 #print(self.dataOut.NDP)
5155 #print(self.dataOut.nNoiseProfiles)
5178 #print(self.dataOut.nNoiseProfiles)
5156
5179
5157 #self.dataOut.nIncohInt_LP = 128
5180 #self.dataOut.nIncohInt_LP = 128
5158 self.dataOut.nProfiles_LP = 128#self.dataOut.nIncohInt_LP
5181 self.dataOut.nProfiles_LP = 128#self.dataOut.nIncohInt_LP
5159 self.dataOut.nIncohInt_LP = self.dataOut.nIncohInt
5182 self.dataOut.nIncohInt_LP = self.dataOut.nIncohInt
5160 self.dataOut.NLAG = 16
5183 self.dataOut.NLAG = 16
5161 self.dataOut.NRANGE = 200
5184 self.dataOut.NRANGE = 200
5162 self.dataOut.NSCAN = 128
5185 self.dataOut.NSCAN = 128
5163 #print(numpy.shape(self.dataOut.data_spc))
5186 #print(numpy.shape(self.dataOut.data_spc))
5164
5187
5165 #exit(1)
5188 #exit(1)
5166
5189
5167 if mode==2: #HAE 2022
5190 if mode==2: #HAE 2022
5168 data = numpy.sum([getattr(data, attr_data) for data in data_inputs],axis=0)
5191 data = numpy.sum([getattr(data, attr_data) for data in data_inputs],axis=0)
5169 setattr(self.dataOut, attr_data, data)
5192 setattr(self.dataOut, attr_data, data)
5170
5193
5171 self.dataOut.nIncohInt *= 2
5194 self.dataOut.nIncohInt *= 2
5172 #meta = self.dataOut.getFreqRange(1)/1000.
5195 #meta = self.dataOut.getFreqRange(1)/1000.
5173 self.dataOut.freqRange = self.dataOut.getFreqRange(1)/1000.
5196 self.dataOut.freqRange = self.dataOut.getFreqRange(1)/1000.
5174
5197
5175 #exit(1)
5198 #exit(1)
5176
5199
5177 if mode==7: #RM
5200 if mode==7: #RM
5178
5201
5179 f = [getattr(data, attr_data) for data in data_inputs][0]
5202 f = [getattr(data, attr_data) for data in data_inputs][0]
5180 g = [getattr(data, attr_data) for data in data_inputs][1]
5203 g = [getattr(data, attr_data) for data in data_inputs][1]
5181
5204
5182 data = numpy.concatenate((f,g),axis=2)
5205 data = numpy.concatenate((f,g),axis=2)
5183 #print(data)
5206 #print(data)
5184 setattr(self.dataOut, attr_data, data)
5207 setattr(self.dataOut, attr_data, data)
5185 #print(self.dataOut.dataPP_POWER.shape)
5208 #print(self.dataOut.dataPP_POWER.shape)
5186 #CONSTRUIR NUEVA ALTURAS
5209 #CONSTRUIR NUEVA ALTURAS
5187 #print("hei_merge",self.dataOut.heightList)
5210 #print("hei_merge",self.dataOut.heightList)
5188 dh = self.dataOut.heightList[1]-self.dataOut.heightList[0]
5211 dh = self.dataOut.heightList[1]-self.dataOut.heightList[0]
5189 heightList_2 = (self.dataOut.heightList[-1]+dh) + numpy.arange(g.shape[-1], dtype=numpy.float) * dh
5212 heightList_2 = (self.dataOut.heightList[-1]+dh) + numpy.arange(g.shape[-1], dtype=numpy.float) * dh
5190
5213
5191 self.dataOut.heightList = numpy.concatenate((self.dataOut.heightList,heightList_2))
5214 self.dataOut.heightList = numpy.concatenate((self.dataOut.heightList,heightList_2))
5192 #print("hei_merge_total",self.dataOut.heightList)
5215 #print("hei_merge_total",self.dataOut.heightList)
5193 #exit(1)
5216 #exit(1)
General Comments 0
You need to be logged in to leave comments. Login now