##// END OF EJS Templates
LAST UPDATE INTEGRACION
avaldez -
r1388:ec0a56a3ee09
parent child
Show More
@@ -0,0 +1,213
1 # Ing. AVP
2 # 06/10/2021
3 # ARCHIVO DE LECTURA
4 import os, sys
5 import datetime
6 import time
7 from schainpy.controller import Project
8 #### NOTA###########################################
9 # INPUT :
10 # VELOCIDAD PARAMETRO : V = 2Β°/seg
11 # MODO PULSE PAIR O MOMENTOS: 0 : Pulse Pair ,1 : Momentos
12 ######################################################
13 ##### PROCESAMIENTO ##################################
14 ##### OJO TENER EN CUENTA EL n= para el Pulse Pair ##
15 ##### O EL n= nFFTPoints ###
16 ######################################################
17 ######## BUSCAMOS EL numero de IPP equivalente 1Β°#####
18 ######## Sea V la velocidad del Pedestal en Β°/seg#####
19 ######## 1Β° sera Recorrido en un tiempo de 1/V ######
20 ######## IPP del Radar 400 useg --> 60 Km ############
21 ######## n = 1/(V(Β°/seg)*IPP(Km)) , NUMERO DE IPP ##
22 ######## n = 1/(V*IPP) #############################
23 ######## VELOCIDAD DEL PEDESTAL ######################
24 print("SETUP- RADAR METEOROLOGICO")
25 V = 10
26 mode = 1
27 #path = '/DATA_RM/23/6v'
28 path = '/DATA_RM/TEST_INTEGRACION_2M'
29 path_ped='/DATA_RM/TEST_PEDESTAL/P20211012-082745'
30 figpath_pp = "/home/soporte/Pictures/TEST_PP"
31 figpath_mom = "/home/soporte/Pictures/TEST_MOM"
32 plot = 0
33 integration = 1
34 save = 0
35 if save == 1:
36 if mode==0:
37 path_save = '/DATA_RM/TEST_HDF5_PP_23/6v'
38 path_save = '/DATA_RM/TEST_HDF5_PP'
39 path_save = '/DATA_RM/TEST_HDF5_PP_100'
40 else:
41 path_save = '/DATA_RM/TEST_HDF5_SPEC_23_V2/6v'
42
43 print("* PATH data ADQ :", path)
44 print("* Velocidad Pedestal :",V,"Β°/seg")
45 ############################ NRO Perfiles PROCESAMIENTO ###################
46 V=V
47 IPP=400*1e-6
48 n= int(1/(V*IPP))
49 print("* n - NRO Perfiles Proc:", n )
50 ################################## MODE ###################################
51 print("* Modo de Operacion :",mode)
52 if mode ==0:
53 print("* Met. Seleccionado : Pulse Pair")
54 else:
55 print("* Met. Momentos : Momentos")
56
57 ################################## MODE ###################################
58 print("* Grabado de datos :",save)
59 if save ==1:
60 if mode==0:
61 ope= "Pulse Pair"
62 else:
63 ope= "Momentos"
64 print("* Path-Save Data -", ope , path_save)
65
66 print("* Integracion de datos :",integration)
67
68 time.sleep(15)
69 #remotefolder = "/home/wmaster/graficos"
70 #######################################################################
71 ################# RANGO DE PLOTEO######################################
72 dBmin = '1'
73 dBmax = '85'
74 xmin = '15'
75 xmax = '15.25'
76 ymin = '0'
77 ymax = '600'
78 #######################################################################
79 ########################FECHA##########################################
80 str = datetime.date.today()
81 today = str.strftime("%Y/%m/%d")
82 str2 = str - datetime.timedelta(days=1)
83 yesterday = str2.strftime("%Y/%m/%d")
84 #######################################################################
85 ########################SIGNAL CHAIN ##################################
86 #######################################################################
87 desc = "USRP_test"
88 filename = "USRP_processing.xml"
89 controllerObj = Project()
90 controllerObj.setup(id = '191', name='Test_USRP', description=desc)
91 #######################################################################
92 ######################## UNIDAD DE LECTURA#############################
93 #######################################################################
94 readUnitConfObj = controllerObj.addReadUnit(datatype='DigitalRFReader',
95 path=path,
96 startDate="2021/01/01",#today,
97 endDate="2021/12/30",#today,
98 startTime='00:00:00',
99 endTime='23:59:59',
100 delay=0,
101 #set=0,
102 online=0,
103 walk=1,
104 ippKm = 60)
105
106 opObj11 = readUnitConfObj.addOperation(name='printInfo')
107
108 procUnitConfObjA = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId())
109
110 if mode ==0:
111 ####################### METODO PULSE PAIR ######################################################################
112 opObj11 = procUnitConfObjA.addOperation(name='PulsePair', optype='other')
113 opObj11.addParameter(name='n', value=int(n), format='int')#10 VOY A USAR 250 DADO QUE LA VELOCIDAD ES 10 GRADOS
114 #opObj11.addParameter(name='removeDC', value=1, format='int')
115 ####################### METODO Parametros ######################################################################
116 procUnitConfObjB= controllerObj.addProcUnit(datatype='ParametersProc',inputId=procUnitConfObjA.getId())
117 if plot==1:
118 opObj11 = procUnitConfObjB.addOperation(name='GenericRTIPlot',optype='external')
119 opObj11.addParameter(name='attr_data', value='dataPP_POW')
120 opObj11.addParameter(name='colormap', value='jet')
121 opObj11.addParameter(name='xmin', value=xmin)
122 opObj11.addParameter(name='xmax', value=xmax)
123 opObj11.addParameter(name='zmin', value=dBmin)
124 opObj11.addParameter(name='zmax', value=dBmax)
125 opObj11.addParameter(name='save', value=figpath_pp)
126 opObj11.addParameter(name='showprofile', value=0)
127 opObj11.addParameter(name='save_period', value=50)
128
129 ####################### METODO ESCRITURA #######################################################################
130 if save==1:
131 opObj10 = procUnitConfObjB.addOperation(name='HDFWriter')
132 opObj10.addParameter(name='path',value=path_save)
133 #opObj10.addParameter(name='mode',value=0)
134 opObj10.addParameter(name='blocksPerFile',value='100',format='int')
135 opObj10.addParameter(name='metadataList',value='utctimeInit,timeZone,paramInterval,profileIndex,channelList,heightList,flagDataAsBlock',format='list')
136 opObj10.addParameter(name='dataList',value='dataPP_POW,dataPP_DOP,utctime',format='list')#,format='list'
137 if integration==1:
138 V=10
139 blocksPerfile=360
140 print("* Velocidad del Pedestal:",V)
141 tmp_blocksPerfile = 100
142 f_a_p= int(tmp_blocksPerfile/V)
143
144 opObj11 = procUnitConfObjB.addOperation(name='PedestalInformation')
145 opObj11.addParameter(name='path_ped', value=path_ped)
146 #opObj11.addParameter(name='path_adq', value=path_adq)
147 opObj11.addParameter(name='t_Interval_p', value='0.01', format='float')
148 opObj11.addParameter(name='blocksPerfile', value=blocksPerfile, format='int')
149 opObj11.addParameter(name='n_Muestras_p', value='100', format='float')
150 opObj11.addParameter(name='f_a_p', value=f_a_p, format='int')
151 opObj11.addParameter(name='online', value='0', format='int')
152
153 opObj11 = procUnitConfObjB.addOperation(name='Block360')
154 opObj11.addParameter(name='n', value='10', format='int')
155 opObj11.addParameter(name='mode', value=mode, format='int')
156
157 # este bloque funciona bien con divisores de 360 no olvidar 0 10 20 30 40 60 90 120 180
158
159 opObj11= procUnitConfObjB.addOperation(name='WeatherPlot',optype='other')
160
161
162 else:
163 ####################### METODO SPECTROS ######################################################################
164 procUnitConfObjB = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjA.getId())
165 procUnitConfObjB.addParameter(name='nFFTPoints', value=n, format='int')
166 procUnitConfObjB.addParameter(name='nProfiles' , value=n, format='int')
167
168 procUnitConfObjC = controllerObj.addProcUnit(datatype='ParametersProc',inputId=procUnitConfObjB.getId())
169 procUnitConfObjC.addOperation(name='SpectralMoments')
170 if plot==1:
171 dBmin = '1'
172 dBmax = '65'
173 opObj11 = procUnitConfObjC.addOperation(name='PowerPlot',optype='external')
174 opObj11.addParameter(name='xmin', value=xmin)
175 opObj11.addParameter(name='xmax', value=xmax)
176 opObj11.addParameter(name='zmin', value=dBmin)
177 opObj11.addParameter(name='zmax', value=dBmax)
178 opObj11.addParameter(name='save', value=figpath_mom)
179 opObj11.addParameter(name='showprofile', value=0)
180 opObj11.addParameter(name='save_period', value=100)
181
182 if save==1:
183 opObj10 = procUnitConfObjC.addOperation(name='HDFWriter')
184 opObj10.addParameter(name='path',value=path_save)
185 #opObj10.addParameter(name='mode',value=0)
186 opObj10.addParameter(name='blocksPerFile',value='360',format='int')
187 #opObj10.addParameter(name='metadataList',value='utctimeInit,heightList,nIncohInt,nCohInt,nProfiles,channelList',format='list')#profileIndex
188 opObj10.addParameter(name='metadataList',value='utctimeInit,heightList,nIncohInt,nCohInt,nProfiles,channelList',format='list')#profileIndex
189 opObj10.addParameter(name='dataList',value='data_pow,data_dop,utctime',format='list')#,format='list'
190
191 if integration==1:
192 V=10
193 blocksPerfile=360
194 print("* Velocidad del Pedestal:",V)
195 tmp_blocksPerfile = 100
196 f_a_p= int(tmp_blocksPerfile/V)
197
198 opObj11 = procUnitConfObjC.addOperation(name='PedestalInformation')
199 opObj11.addParameter(name='path_ped', value=path_ped)
200 #opObj11.addParameter(name='path_adq', value=path_adq)
201 opObj11.addParameter(name='t_Interval_p', value='0.01', format='float')
202 opObj11.addParameter(name='blocksPerfile', value=blocksPerfile, format='int')
203 opObj11.addParameter(name='n_Muestras_p', value='100', format='float')
204 opObj11.addParameter(name='f_a_p', value=f_a_p, format='int')
205 opObj11.addParameter(name='online', value='0', format='int')
206
207 opObj11 = procUnitConfObjC.addOperation(name='Block360')
208 opObj11.addParameter(name='n', value='10', format='int')
209 opObj11.addParameter(name='mode', value=mode, format='int')
210
211 # este bloque funciona bien con divisores de 360 no olvidar 0 10 20 30 40 60 90 120 180
212 opObj11= procUnitConfObjC.addOperation(name='WeatherPlot',optype='other')
213 controllerObj.start()
@@ -0,0 +1,112
1 # Ing-AlexanderValdez
2 # Monitoreo de Pedestal
3
4 ############## IMPORTA LIBRERIAS ###################
5 import os,numpy,h5py
6 import sys,time
7 import matplotlib.pyplot as plt
8 ####################################################
9 path_ped = '/DATA_RM/TEST_PEDESTAL/P20211012-082745'
10 # Metodo para verificar numero
11 def isNumber(str):
12 try:
13 float(str)
14 return True
15 except:
16 return False
17 # Metodo para extraer el arreglo
18 def getDatavaluefromDirFilename(path,file,value):
19 dir_file= path+"/"+file
20 fp = h5py.File(dir_file,'r')
21 array = fp['Data'].get(value)[()]
22 fp.close()
23 return array
24
25 # LISTA COMPLETA DE ARCHIVOS HDF5 Pedestal
26 LIST= sorted(os.listdir(path_ped))
27 m=len(LIST)
28 print("TOTAL DE ARCHIVOS DE PEDESTAL:",m)
29 # Contadores temporales
30 k= 0
31 l= 0
32 t= 0
33 # Marca de tiempo temporal
34 time_ = numpy.zeros([m])
35 # creacion de
36 for i in range(m):
37 tmp_azi_pos = getDatavaluefromDirFilename(path=path_ped,file=LIST[i],value="azi_pos")
38 tmp_ele_pos = getDatavaluefromDirFilename(path=path_ped,file=LIST[i],value="ele_pos")
39 tmp_azi_vel = getDatavaluefromDirFilename(path=path_ped,file=LIST[i],value="azi_vel")
40 tmp_ele_vel = getDatavaluefromDirFilename(path=path_ped,file=LIST[i],value="azi_vel")# nuevo :D
41
42 time_[i] = getDatavaluefromDirFilename(path=path_ped,file=LIST[i],value="utc")
43
44 k=k +tmp_azi_pos.shape[0]
45 l=l +tmp_ele_pos.shape[0]
46 t=t +tmp_azi_vel.shape[0]
47
48 print("TOTAL DE MUESTRAS, ARCHIVOS X100:",k)
49 time.sleep(5)
50 ######CREACION DE ARREGLOS CANTIDAD DE VALORES POR MUESTRA#################
51 azi_pos = numpy.zeros([k])
52 ele_pos = numpy.zeros([l])
53 time_azi_pos= numpy.zeros([k])
54 # Contadores temporales
55 p=0
56 r=0
57 z=0
58 # VARIABLES TMP para almacenar azimuth, elevacion y tiempo
59
60 #for filename in sorted(os.listdir(path_ped)):
61 # CONDICION POR LEER EN TIEMPO REAL NO OFFLINE
62
63 for filename in LIST:
64 tmp_azi_pos = getDatavaluefromDirFilename(path=path_ped,file=filename,value="azi_pos")
65 tmp_ele_pos = getDatavaluefromDirFilename(path=path_ped,file=filename,value="ele_pos")
66 # CONDICION POR LEER EN TIEMPO REAL NO OFFLINE
67
68 if z==(m-1):
69 tmp_azi_time=numpy.arange(time_[z],time_[z]+1,1/(tmp_azi_pos.shape[0]))
70 else:
71 tmp_azi_time=numpy.arange(time_[z],time_[z+1],(time_[z+1]-time_[z])/(tmp_azi_pos.shape[0]))
72
73 print(filename,time_[z])
74 print(z,tmp_azi_pos.shape[0])
75
76 i=0
77 for i in range(tmp_azi_pos.shape[0]):
78 index=p+i
79 azi_pos[index]=tmp_azi_pos[i]
80 time_azi_pos[index]=tmp_azi_time[i]
81 p=p+tmp_azi_pos.shape[0]
82 i=0
83 for i in range(tmp_ele_pos.shape[0]):
84 index=r+i
85 ele_pos[index]=tmp_ele_pos[i]
86 r=r+tmp_ele_pos.shape[0]
87
88
89 z+=1
90
91
92 ######## GRAFIQUEMOS Y VEAMOS LOS DATOS DEL Pedestal
93 fig, ax = plt.subplots(figsize=(16,8))
94 print(time_azi_pos.shape)
95 print(azi_pos.shape)
96 t=numpy.arange(time_azi_pos.shape[0])*0.01/(60.0)
97 plt.plot(t,azi_pos,label='AZIMUTH_POS',color='blue')
98
99 # AQUI ESTOY ADICIONANDO LA POSICION EN elevaciont=numpy.arange(len(ele_pos))*0.01/60.0
100 t=numpy.arange(len(ele_pos))*0.01/60.0
101 plt.plot(t,ele_pos,label='ELEVATION_POS',color='red')#*10
102
103 #ax.set_xlim(0, 9)
104 ax.set_ylim(-5, 400)
105 plt.ylabel("Azimuth Position")
106 plt.xlabel("Muestra")
107 plt.title('Azimuth Position vs Muestra ', fontsize=20)
108 axes = plt.gca()
109 axes.yaxis.grid()
110 plt.xticks(fontsize=16)
111 plt.yticks(fontsize=16)
112 plt.show()
@@ -0,0 +1,90
1 import os,sys,json
2 import datetime
3 import time
4 from schainpy.controller import Project
5 '''
6 NOTA:
7 Este script de prueba.
8 - Unidad del lectura 'HDFReader'.
9 - Unidad de procesamiento ParametersProc
10 - Operacion SpectralMomentsPlot
11
12 '''
13
14 #######################################################################
15 ################# RANGO DE PLOTEO######################################
16 #######################################################################
17 dBmin = '1'
18 dBmax = '65'
19 xmin = '0'
20 xmax ='24'
21 #tmmin = 16.2
22 #tmmax = 16.25
23 tmmin =15
24 tmmax =15.5
25 ymin = '0'
26 ymax = '600'
27 #######################################################################
28 #######################################################################
29 #######################################################################
30 #path = '/DATA_RM/TEST_HDF5_SPEC'
31 path = '/DATA_RM/TEST_HDF5_SPEC_23/6v/'
32 figpath = '/home/soporte/Downloads/23/6v'
33 path="/home/soporte/Downloads/params-20211015T174046Z-001/params"
34 desc = "Simulator Test"
35 desc_data = {
36 'Data': {
37 'data_spc': ['Data/data_spc/channel00','Data/data_spc/channel01'\
38 ,'Data/data_spc/channel02','Data/data_spc/channel03'\
39 ,'Data/data_spc/channel04','Data/data_spc/channel05'\
40 ,'Data/data_spc/channel06','Data/data_spc/channel07'\
41 ,'Data/data_spc/channel08','Data/data_spc/channel09'],
42 'utctime':'Data/utctime'
43 },
44 'Metadata': {
45 'type' :'Metadata/type',
46 'channelList' :'Metadata/channelList',
47 'heightList' :'Metadata/heightList',
48 'ippSeconds' :'Metadata/ippSeconds',
49 'nProfiles' :'Metadata/nProfiles',
50 'codeList' :'Metadata/codeList',
51 'timeZone' :'Metadata/timeZone',
52 'azimuthList' :'Metadata/azimuthList',
53 'elevationList' :'Metadata/elevationList',
54 'nCohInt' :'Metadata/nCohInt',
55 'nIncohInt' :'Metadata/nIncohInt',
56 'nFFTPoints' :'Metadata/nFFTPoints'
57
58 }
59 }
60
61 controllerObj = Project()
62
63 controllerObj.setup(id='10',name='Test Simulator',description=desc)
64
65 readUnitConfObj = controllerObj.addReadUnit(datatype='HDFReader',
66 path=path,
67 startDate="2021/01/01", #"2020/01/01",#today,
68 endDate= "2021/12/01", #"2020/12/30",#today,
69 startTime='00:00:00',
70 endTime='23:59:59',
71 delay=0,
72 #set=0,
73 online=0,
74 walk=0,
75 description= json.dumps(desc_data))#1
76
77 procUnitConfObjA = controllerObj.addProcUnit(datatype='ParametersProc',inputId=readUnitConfObj.getId())
78 procUnitConfObjA.addOperation(name='SpectralMoments')
79
80 '''
81 opObj11 = readUnitConfObj.addOperation(name='SpectraPlot',optype='external')
82 opObj11.addParameter(name='xmin', value=tmmin)
83 opObj11.addParameter(name='xmax', value=tmmax)
84 opObj11.addParameter(name='zmin', value=dBmin)
85 opObj11.addParameter(name='zmax', value=dBmax)
86 opObj11.addParameter(name='save', value=figpath)
87 opObj11.addParameter(name='showprofile', value=0)
88 opObj11.addParameter(name='save_period', value=10)
89 '''
90 controllerObj.start()
@@ -1,518 +1,519
1 import os
1 import os
2 import datetime
2 import datetime
3 import numpy
3 import numpy
4
4
5 from schainpy.model.graphics.jroplot_base import Plot, plt
5 from schainpy.model.graphics.jroplot_base import Plot, plt
6 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot, SpectraCutPlot
6 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot, SpectraCutPlot
7 from schainpy.utils import log
7 from schainpy.utils import log
8 # libreria wradlib
8 # libreria wradlib
9 import wradlib as wrl
9 import wradlib as wrl
10
10
11 EARTH_RADIUS = 6.3710e3
11 EARTH_RADIUS = 6.3710e3
12
12
13
13
14 def ll2xy(lat1, lon1, lat2, lon2):
14 def ll2xy(lat1, lon1, lat2, lon2):
15
15
16 p = 0.017453292519943295
16 p = 0.017453292519943295
17 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
17 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
18 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
18 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
19 r = 12742 * numpy.arcsin(numpy.sqrt(a))
19 r = 12742 * numpy.arcsin(numpy.sqrt(a))
20 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
20 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
21 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
21 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
22 theta = -theta + numpy.pi/2
22 theta = -theta + numpy.pi/2
23 return r*numpy.cos(theta), r*numpy.sin(theta)
23 return r*numpy.cos(theta), r*numpy.sin(theta)
24
24
25
25
26 def km2deg(km):
26 def km2deg(km):
27 '''
27 '''
28 Convert distance in km to degrees
28 Convert distance in km to degrees
29 '''
29 '''
30
30
31 return numpy.rad2deg(km/EARTH_RADIUS)
31 return numpy.rad2deg(km/EARTH_RADIUS)
32
32
33
33
34
34
35 class SpectralMomentsPlot(SpectraPlot):
35 class SpectralMomentsPlot(SpectraPlot):
36 '''
36 '''
37 Plot for Spectral Moments
37 Plot for Spectral Moments
38 '''
38 '''
39 CODE = 'spc_moments'
39 CODE = 'spc_moments'
40 # colormap = 'jet'
40 # colormap = 'jet'
41 # plot_type = 'pcolor'
41 # plot_type = 'pcolor'
42
42
43 class DobleGaussianPlot(SpectraPlot):
43 class DobleGaussianPlot(SpectraPlot):
44 '''
44 '''
45 Plot for Double Gaussian Plot
45 Plot for Double Gaussian Plot
46 '''
46 '''
47 CODE = 'gaussian_fit'
47 CODE = 'gaussian_fit'
48 # colormap = 'jet'
48 # colormap = 'jet'
49 # plot_type = 'pcolor'
49 # plot_type = 'pcolor'
50
50
51 class DoubleGaussianSpectraCutPlot(SpectraCutPlot):
51 class DoubleGaussianSpectraCutPlot(SpectraCutPlot):
52 '''
52 '''
53 Plot SpectraCut with Double Gaussian Fit
53 Plot SpectraCut with Double Gaussian Fit
54 '''
54 '''
55 CODE = 'cut_gaussian_fit'
55 CODE = 'cut_gaussian_fit'
56
56
57 class SnrPlot(RTIPlot):
57 class SnrPlot(RTIPlot):
58 '''
58 '''
59 Plot for SNR Data
59 Plot for SNR Data
60 '''
60 '''
61
61
62 CODE = 'snr'
62 CODE = 'snr'
63 colormap = 'jet'
63 colormap = 'jet'
64
64
65 def update(self, dataOut):
65 def update(self, dataOut):
66
66
67 data = {
67 data = {
68 'snr': 10*numpy.log10(dataOut.data_snr)
68 'snr': 10*numpy.log10(dataOut.data_snr)
69 }
69 }
70
70
71 return data, {}
71 return data, {}
72
72
73 class DopplerPlot(RTIPlot):
73 class DopplerPlot(RTIPlot):
74 '''
74 '''
75 Plot for DOPPLER Data (1st moment)
75 Plot for DOPPLER Data (1st moment)
76 '''
76 '''
77
77
78 CODE = 'dop'
78 CODE = 'dop'
79 colormap = 'jet'
79 colormap = 'jet'
80
80
81 def update(self, dataOut):
81 def update(self, dataOut):
82
82
83 data = {
83 data = {
84 'dop': 10*numpy.log10(dataOut.data_dop)
84 'dop': 10*numpy.log10(dataOut.data_dop)
85 }
85 }
86
86
87 return data, {}
87 return data, {}
88
88
89 class PowerPlot(RTIPlot):
89 class PowerPlot(RTIPlot):
90 '''
90 '''
91 Plot for Power Data (0 moment)
91 Plot for Power Data (0 moment)
92 '''
92 '''
93
93
94 CODE = 'pow'
94 CODE = 'pow'
95 colormap = 'jet'
95 colormap = 'jet'
96
96
97 def update(self, dataOut):
97 def update(self, dataOut):
98
98
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
102
103 return data, {}
103 return data, {}
104
104
105 class SpectralWidthPlot(RTIPlot):
105 class SpectralWidthPlot(RTIPlot):
106 '''
106 '''
107 Plot for Spectral Width Data (2nd moment)
107 Plot for Spectral Width Data (2nd moment)
108 '''
108 '''
109
109
110 CODE = 'width'
110 CODE = 'width'
111 colormap = 'jet'
111 colormap = 'jet'
112
112
113 def update(self, dataOut):
113 def update(self, dataOut):
114
114
115 data = {
115 data = {
116 'width': dataOut.data_width
116 'width': dataOut.data_width
117 }
117 }
118
118
119 return data, {}
119 return data, {}
120
120
121 class SkyMapPlot(Plot):
121 class SkyMapPlot(Plot):
122 '''
122 '''
123 Plot for meteors detection data
123 Plot for meteors detection data
124 '''
124 '''
125
125
126 CODE = 'param'
126 CODE = 'param'
127
127
128 def setup(self):
128 def setup(self):
129
129
130 self.ncols = 1
130 self.ncols = 1
131 self.nrows = 1
131 self.nrows = 1
132 self.width = 7.2
132 self.width = 7.2
133 self.height = 7.2
133 self.height = 7.2
134 self.nplots = 1
134 self.nplots = 1
135 self.xlabel = 'Zonal Zenith Angle (deg)'
135 self.xlabel = 'Zonal Zenith Angle (deg)'
136 self.ylabel = 'Meridional Zenith Angle (deg)'
136 self.ylabel = 'Meridional Zenith Angle (deg)'
137 self.polar = True
137 self.polar = True
138 self.ymin = -180
138 self.ymin = -180
139 self.ymax = 180
139 self.ymax = 180
140 self.colorbar = False
140 self.colorbar = False
141
141
142 def plot(self):
142 def plot(self):
143
143
144 arrayParameters = numpy.concatenate(self.data['param'])
144 arrayParameters = numpy.concatenate(self.data['param'])
145 error = arrayParameters[:, -1]
145 error = arrayParameters[:, -1]
146 indValid = numpy.where(error == 0)[0]
146 indValid = numpy.where(error == 0)[0]
147 finalMeteor = arrayParameters[indValid, :]
147 finalMeteor = arrayParameters[indValid, :]
148 finalAzimuth = finalMeteor[:, 3]
148 finalAzimuth = finalMeteor[:, 3]
149 finalZenith = finalMeteor[:, 4]
149 finalZenith = finalMeteor[:, 4]
150
150
151 x = finalAzimuth * numpy.pi / 180
151 x = finalAzimuth * numpy.pi / 180
152 y = finalZenith
152 y = finalZenith
153
153
154 ax = self.axes[0]
154 ax = self.axes[0]
155
155
156 if ax.firsttime:
156 if ax.firsttime:
157 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
157 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
158 else:
158 else:
159 ax.plot.set_data(x, y)
159 ax.plot.set_data(x, y)
160
160
161 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
161 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
162 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
162 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
163 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
163 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
164 dt2,
164 dt2,
165 len(x))
165 len(x))
166 self.titles[0] = title
166 self.titles[0] = title
167
167
168
168
169 class GenericRTIPlot(Plot):
169 class GenericRTIPlot(Plot):
170 '''
170 '''
171 Plot for data_xxxx object
171 Plot for data_xxxx object
172 '''
172 '''
173
173
174 CODE = 'param'
174 CODE = 'param'
175 colormap = 'viridis'
175 colormap = 'viridis'
176 plot_type = 'pcolorbuffer'
176 plot_type = 'pcolorbuffer'
177
177
178 def setup(self):
178 def setup(self):
179 self.xaxis = 'time'
179 self.xaxis = 'time'
180 self.ncols = 1
180 self.ncols = 1
181 self.nrows = self.data.shape('param')[0]
181 self.nrows = self.data.shape('param')[0]
182 self.nplots = self.nrows
182 self.nplots = self.nrows
183 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
183 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
184
184
185 if not self.xlabel:
185 if not self.xlabel:
186 self.xlabel = 'Time'
186 self.xlabel = 'Time'
187
187
188 self.ylabel = 'Range [km]'
188 self.ylabel = 'Range [km]'
189 if not self.titles:
189 if not self.titles:
190 self.titles = ['Param {}'.format(x) for x in range(self.nrows)]
190 self.titles = ['Param {}'.format(x) for x in range(self.nrows)]
191
191
192 def update(self, dataOut):
192 def update(self, dataOut):
193
193
194 data = {
194 data = {
195 'param' : numpy.concatenate([getattr(dataOut, attr) for attr in self.attr_data], axis=0)
195 'param' : numpy.concatenate([getattr(dataOut, attr) for attr in self.attr_data], axis=0)
196 }
196 }
197
197
198 meta = {}
198 meta = {}
199
199
200 return data, meta
200 return data, meta
201
201
202 def plot(self):
202 def plot(self):
203 # self.data.normalize_heights()
203 # self.data.normalize_heights()
204 self.x = self.data.times
204 self.x = self.data.times
205 self.y = self.data.yrange
205 self.y = self.data.yrange
206 self.z = self.data['param']
206 self.z = self.data['param']
207
207
208 self.z = 10*numpy.log10(self.z)
208 self.z = 10*numpy.log10(self.z)
209
209
210 self.z = numpy.ma.masked_invalid(self.z)
210 self.z = numpy.ma.masked_invalid(self.z)
211
211
212 if self.decimation is None:
212 if self.decimation is None:
213 x, y, z = self.fill_gaps(self.x, self.y, self.z)
213 x, y, z = self.fill_gaps(self.x, self.y, self.z)
214 else:
214 else:
215 x, y, z = self.fill_gaps(*self.decimate())
215 x, y, z = self.fill_gaps(*self.decimate())
216
216
217 for n, ax in enumerate(self.axes):
217 for n, ax in enumerate(self.axes):
218
218
219 self.zmax = self.zmax if self.zmax is not None else numpy.max(
219 self.zmax = self.zmax if self.zmax is not None else numpy.max(
220 self.z[n])
220 self.z[n])
221 self.zmin = self.zmin if self.zmin is not None else numpy.min(
221 self.zmin = self.zmin if self.zmin is not None else numpy.min(
222 self.z[n])
222 self.z[n])
223
223
224 if ax.firsttime:
224 if ax.firsttime:
225 if self.zlimits is not None:
225 if self.zlimits is not None:
226 self.zmin, self.zmax = self.zlimits[n]
226 self.zmin, self.zmax = self.zlimits[n]
227
227
228 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
228 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
229 vmin=self.zmin,
229 vmin=self.zmin,
230 vmax=self.zmax,
230 vmax=self.zmax,
231 cmap=self.cmaps[n]
231 cmap=self.cmaps[n]
232 )
232 )
233 else:
233 else:
234 if self.zlimits is not None:
234 if self.zlimits is not None:
235 self.zmin, self.zmax = self.zlimits[n]
235 self.zmin, self.zmax = self.zlimits[n]
236 ax.collections.remove(ax.collections[0])
236 ax.collections.remove(ax.collections[0])
237 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
237 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
238 vmin=self.zmin,
238 vmin=self.zmin,
239 vmax=self.zmax,
239 vmax=self.zmax,
240 cmap=self.cmaps[n]
240 cmap=self.cmaps[n]
241 )
241 )
242
242
243
243
244 class PolarMapPlot(Plot):
244 class PolarMapPlot(Plot):
245 '''
245 '''
246 Plot for weather radar
246 Plot for weather radar
247 '''
247 '''
248
248
249 CODE = 'param'
249 CODE = 'param'
250 colormap = 'seismic'
250 colormap = 'seismic'
251
251
252 def setup(self):
252 def setup(self):
253 self.ncols = 1
253 self.ncols = 1
254 self.nrows = 1
254 self.nrows = 1
255 self.width = 9
255 self.width = 9
256 self.height = 8
256 self.height = 8
257 self.mode = self.data.meta['mode']
257 self.mode = self.data.meta['mode']
258 if self.channels is not None:
258 if self.channels is not None:
259 self.nplots = len(self.channels)
259 self.nplots = len(self.channels)
260 self.nrows = len(self.channels)
260 self.nrows = len(self.channels)
261 else:
261 else:
262 self.nplots = self.data.shape(self.CODE)[0]
262 self.nplots = self.data.shape(self.CODE)[0]
263 self.nrows = self.nplots
263 self.nrows = self.nplots
264 self.channels = list(range(self.nplots))
264 self.channels = list(range(self.nplots))
265 if self.mode == 'E':
265 if self.mode == 'E':
266 self.xlabel = 'Longitude'
266 self.xlabel = 'Longitude'
267 self.ylabel = 'Latitude'
267 self.ylabel = 'Latitude'
268 else:
268 else:
269 self.xlabel = 'Range (km)'
269 self.xlabel = 'Range (km)'
270 self.ylabel = 'Height (km)'
270 self.ylabel = 'Height (km)'
271 self.bgcolor = 'white'
271 self.bgcolor = 'white'
272 self.cb_labels = self.data.meta['units']
272 self.cb_labels = self.data.meta['units']
273 self.lat = self.data.meta['latitude']
273 self.lat = self.data.meta['latitude']
274 self.lon = self.data.meta['longitude']
274 self.lon = self.data.meta['longitude']
275 self.xmin, self.xmax = float(
275 self.xmin, self.xmax = float(
276 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
276 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
277 self.ymin, self.ymax = float(
277 self.ymin, self.ymax = float(
278 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
278 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
279 # self.polar = True
279 # self.polar = True
280
280
281 def plot(self):
281 def plot(self):
282
282
283 for n, ax in enumerate(self.axes):
283 for n, ax in enumerate(self.axes):
284 data = self.data['param'][self.channels[n]]
284 data = self.data['param'][self.channels[n]]
285
285
286 zeniths = numpy.linspace(
286 zeniths = numpy.linspace(
287 0, self.data.meta['max_range'], data.shape[1])
287 0, self.data.meta['max_range'], data.shape[1])
288 if self.mode == 'E':
288 if self.mode == 'E':
289 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
289 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
290 r, theta = numpy.meshgrid(zeniths, azimuths)
290 r, theta = numpy.meshgrid(zeniths, azimuths)
291 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
291 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
292 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
292 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
293 x = km2deg(x) + self.lon
293 x = km2deg(x) + self.lon
294 y = km2deg(y) + self.lat
294 y = km2deg(y) + self.lat
295 else:
295 else:
296 azimuths = numpy.radians(self.data.yrange)
296 azimuths = numpy.radians(self.data.yrange)
297 r, theta = numpy.meshgrid(zeniths, azimuths)
297 r, theta = numpy.meshgrid(zeniths, azimuths)
298 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
298 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
299 self.y = zeniths
299 self.y = zeniths
300
300
301 if ax.firsttime:
301 if ax.firsttime:
302 if self.zlimits is not None:
302 if self.zlimits is not None:
303 self.zmin, self.zmax = self.zlimits[n]
303 self.zmin, self.zmax = self.zlimits[n]
304 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
304 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
305 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
305 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
306 vmin=self.zmin,
306 vmin=self.zmin,
307 vmax=self.zmax,
307 vmax=self.zmax,
308 cmap=self.cmaps[n])
308 cmap=self.cmaps[n])
309 else:
309 else:
310 if self.zlimits is not None:
310 if self.zlimits is not None:
311 self.zmin, self.zmax = self.zlimits[n]
311 self.zmin, self.zmax = self.zlimits[n]
312 ax.collections.remove(ax.collections[0])
312 ax.collections.remove(ax.collections[0])
313 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
313 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
314 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
314 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
315 vmin=self.zmin,
315 vmin=self.zmin,
316 vmax=self.zmax,
316 vmax=self.zmax,
317 cmap=self.cmaps[n])
317 cmap=self.cmaps[n])
318
318
319 if self.mode == 'A':
319 if self.mode == 'A':
320 continue
320 continue
321
321
322 # plot district names
322 # plot district names
323 f = open('/data/workspace/schain_scripts/distrito.csv')
323 f = open('/data/workspace/schain_scripts/distrito.csv')
324 for line in f:
324 for line in f:
325 label, lon, lat = [s.strip() for s in line.split(',') if s]
325 label, lon, lat = [s.strip() for s in line.split(',') if s]
326 lat = float(lat)
326 lat = float(lat)
327 lon = float(lon)
327 lon = float(lon)
328 # ax.plot(lon, lat, '.b', ms=2)
328 # ax.plot(lon, lat, '.b', ms=2)
329 ax.text(lon, lat, label.decode('utf8'), ha='center',
329 ax.text(lon, lat, label.decode('utf8'), ha='center',
330 va='bottom', size='8', color='black')
330 va='bottom', size='8', color='black')
331
331
332 # plot limites
332 # plot limites
333 limites = []
333 limites = []
334 tmp = []
334 tmp = []
335 for line in open('/data/workspace/schain_scripts/lima.csv'):
335 for line in open('/data/workspace/schain_scripts/lima.csv'):
336 if '#' in line:
336 if '#' in line:
337 if tmp:
337 if tmp:
338 limites.append(tmp)
338 limites.append(tmp)
339 tmp = []
339 tmp = []
340 continue
340 continue
341 values = line.strip().split(',')
341 values = line.strip().split(',')
342 tmp.append((float(values[0]), float(values[1])))
342 tmp.append((float(values[0]), float(values[1])))
343 for points in limites:
343 for points in limites:
344 ax.add_patch(
344 ax.add_patch(
345 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
345 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
346
346
347 # plot Cuencas
347 # plot Cuencas
348 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
348 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
349 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
349 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
350 values = [line.strip().split(',') for line in f]
350 values = [line.strip().split(',') for line in f]
351 points = [(float(s[0]), float(s[1])) for s in values]
351 points = [(float(s[0]), float(s[1])) for s in values]
352 ax.add_patch(Polygon(points, ec='b', fc='none'))
352 ax.add_patch(Polygon(points, ec='b', fc='none'))
353
353
354 # plot grid
354 # plot grid
355 for r in (15, 30, 45, 60):
355 for r in (15, 30, 45, 60):
356 ax.add_artist(plt.Circle((self.lon, self.lat),
356 ax.add_artist(plt.Circle((self.lon, self.lat),
357 km2deg(r), color='0.6', fill=False, lw=0.2))
357 km2deg(r), color='0.6', fill=False, lw=0.2))
358 ax.text(
358 ax.text(
359 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
359 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
360 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
360 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
361 '{}km'.format(r),
361 '{}km'.format(r),
362 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
362 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
363
363
364 if self.mode == 'E':
364 if self.mode == 'E':
365 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
365 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
366 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
366 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
367 else:
367 else:
368 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
368 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
369 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
369 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
370
370
371 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
371 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
372 self.titles = ['{} {}'.format(
372 self.titles = ['{} {}'.format(
373 self.data.parameters[x], title) for x in self.channels]
373 self.data.parameters[x], title) for x in self.channels]
374
374
375 class WeatherPlot(Plot):
375 class WeatherPlot(Plot):
376 CODE = 'weather'
376 CODE = 'weather'
377 plot_name = 'weather'
377 plot_name = 'weather'
378 plot_type = 'ppistyle'
378 plot_type = 'ppistyle'
379 buffering = False
379 buffering = False
380
380
381 def setup(self):
381 def setup(self):
382 self.ncols = 1
382 self.ncols = 1
383 self.nrows = 1
383 self.nrows = 1
384 self.nplots= 1
384 self.nplots= 1
385 self.ylabel= 'Range [Km]'
385 self.ylabel= 'Range [Km]'
386 self.titles= ['Weather']
386 self.titles= ['Weather']
387 self.colorbar=False
387 self.colorbar=False
388 self.width =8
388 self.width =8
389 self.height =8
389 self.height =8
390 self.ini =0
390 self.ini =0
391 self.len_azi =0
391 self.len_azi =0
392 self.buffer_ini = None
392 self.buffer_ini = None
393 self.buffer_azi = None
393 self.buffer_azi = None
394 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
394 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
395 self.flag =0
395 self.flag =0
396 self.indicador= 0
396 self.indicador= 0
397
397
398 def update(self, dataOut):
398 def update(self, dataOut):
399
399
400 data = {}
400 data = {}
401 meta = {}
401 meta = {}
402 data['weather'] = 10*numpy.log10(dataOut.data_360[0]/(250**2))
402 print("aprox",dataOut.data_360[0])
403 print(data['weather'])
403 data['weather'] = 10*numpy.log10(dataOut.data_360[0]/(250.0))
404 #print(data['weather'])
404 data['azi'] = dataOut.data_azi
405 data['azi'] = dataOut.data_azi
405 print("UPDATE",data['azi'])
406 print("UPDATE",data['azi'])
406 return data, meta
407 return data, meta
407
408
408 def const_ploteo(self,data_weather,data_azi,step,res):
409 def const_ploteo(self,data_weather,data_azi,step,res):
409 #print("data_weather",data_weather)
410 #print("data_weather",data_weather)
410 print("data_azi",data_azi)
411 print("data_azi",data_azi)
411 print("step",step)
412 print("step",step)
412 if self.ini==0:
413 if self.ini==0:
413 #------- AZIMUTH
414 #------- AZIMUTH
414 n = (360/res)-len(data_azi)
415 n = (360/res)-len(data_azi)
415 start = data_azi[-1] + res
416 start = data_azi[-1] + res
416 end = data_azi[0] - res
417 end = data_azi[0] - res
417 if start>end:
418 if start>end:
418 end = end + 360
419 end = end + 360
419 azi_vacia = numpy.linspace(start,end,int(n))
420 azi_vacia = numpy.linspace(start,end,int(n))
420 azi_vacia = numpy.where(azi_vacia>360,azi_vacia-360,azi_vacia)
421 azi_vacia = numpy.where(azi_vacia>360,azi_vacia-360,azi_vacia)
421 data_azi = numpy.hstack((data_azi,azi_vacia))
422 data_azi = numpy.hstack((data_azi,azi_vacia))
422 # RADAR
423 # RADAR
423 val_mean = numpy.mean(data_weather[:,0])
424 val_mean = numpy.mean(data_weather[:,0])
424 data_weather_cmp = numpy.ones([(360-data_weather.shape[0]),data_weather.shape[1]])*val_mean
425 data_weather_cmp = numpy.ones([(360-data_weather.shape[0]),data_weather.shape[1]])*val_mean
425 data_weather = numpy.vstack((data_weather,data_weather_cmp))
426 data_weather = numpy.vstack((data_weather,data_weather_cmp))
426 else:
427 else:
427 # azimuth
428 # azimuth
428 flag=0
429 flag=0
429 start_azi = self.res_azi[0]
430 start_azi = self.res_azi[0]
430 start = data_azi[0]
431 start = data_azi[0]
431 end = data_azi[-1]
432 end = data_azi[-1]
432 print("start",start)
433 print("start",start)
433 print("end",end)
434 print("end",end)
434 if start< start_azi:
435 if start< start_azi:
435 start = start +360
436 start = start +360
436 if end <start_azi:
437 if end <start_azi:
437 end = end +360
438 end = end +360
438
439
439 print("start",start)
440 print("start",start)
440 print("end",end)
441 print("end",end)
441 #### AQUI SERA LA MAGIA
442 #### AQUI SERA LA MAGIA
442 pos_ini = int((start-start_azi)/res)
443 pos_ini = int((start-start_azi)/res)
443 len_azi = len(data_azi)
444 len_azi = len(data_azi)
444 if (360-pos_ini)<len_azi:
445 if (360-pos_ini)<len_azi:
445 if pos_ini+1==360:
446 if pos_ini+1==360:
446 pos_ini=0
447 pos_ini=0
447 else:
448 else:
448 flag=1
449 flag=1
449 dif= 360-pos_ini
450 dif= 360-pos_ini
450 comp= len_azi-dif
451 comp= len_azi-dif
451
452
452 print(pos_ini)
453 print(pos_ini)
453 print(len_azi)
454 print(len_azi)
454 print("shape",self.res_azi.shape)
455 print("shape",self.res_azi.shape)
455 if flag==0:
456 if flag==0:
456 # AZIMUTH
457 # AZIMUTH
457 self.res_azi[pos_ini:pos_ini+len_azi] = data_azi
458 self.res_azi[pos_ini:pos_ini+len_azi] = data_azi
458 # RADAR
459 # RADAR
459 self.res_weather[pos_ini:pos_ini+len_azi,:] = data_weather
460 self.res_weather[pos_ini:pos_ini+len_azi,:] = data_weather
460 else:
461 else:
461 # AZIMUTH
462 # AZIMUTH
462 self.res_azi[pos_ini:pos_ini+dif] = data_azi[0:dif]
463 self.res_azi[pos_ini:pos_ini+dif] = data_azi[0:dif]
463 self.res_azi[0:comp] = data_azi[dif:]
464 self.res_azi[0:comp] = data_azi[dif:]
464 # RADAR
465 # RADAR
465 self.res_weather[pos_ini:pos_ini+dif,:] = data_weather[0:dif,:]
466 self.res_weather[pos_ini:pos_ini+dif,:] = data_weather[0:dif,:]
466 self.res_weather[0:comp,:] = data_weather[dif:,:]
467 self.res_weather[0:comp,:] = data_weather[dif:,:]
467 flag=0
468 flag=0
468 data_azi = self.res_azi
469 data_azi = self.res_azi
469 data_weather = self.res_weather
470 data_weather = self.res_weather
470
471
471 return data_weather,data_azi
472 return data_weather,data_azi
472
473
473 def plot(self):
474 def plot(self):
474 print("--------------------------------------",self.ini,"-----------------------------------")
475 print("--------------------------------------",self.ini,"-----------------------------------")
475 #numpy.set_printoptions(suppress=True)
476 #numpy.set_printoptions(suppress=True)
476 #print(self.data.times)
477 #print(self.data.times)
477 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1])
478 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1])
478 data = self.data[-1]
479 data = self.data[-1]
479 # ALTURA altura_tmp_h
480 # ALTURA altura_tmp_h
480 altura_h = (data['weather'].shape[1])/10.0
481 altura_h = (data['weather'].shape[1])/10.0
481 stoprange = float(altura_h*1.5)#stoprange = float(33*1.5) por ahora 400
482 stoprange = float(altura_h*1.5)#stoprange = float(33*1.5) por ahora 400
482 rangestep = float(0.15)
483 rangestep = float(0.15)
483 r = numpy.arange(0, stoprange, rangestep)
484 r = numpy.arange(0, stoprange, rangestep)
484 self.y = 2*r
485 self.y = 2*r
485 # RADAR
486 # RADAR
486 #data_weather = data['weather']
487 #data_weather = data['weather']
487 # PEDESTAL
488 # PEDESTAL
488 #data_azi = data['azi']
489 #data_azi = data['azi']
489 res = 1
490 res = 1
490 # STEP
491 # STEP
491 step = (360/(res*data['weather'].shape[0]))
492 step = (360/(res*data['weather'].shape[0]))
492 #print("shape wr_data", wr_data.shape)
493 #print("shape wr_data", wr_data.shape)
493 #print("shape wr_azi",wr_azi.shape)
494 #print("shape wr_azi",wr_azi.shape)
494 #print("step",step)
495 #print("step",step)
495 print("Time---->",self.data.times[-1],thisDatetime)
496 print("Time---->",self.data.times[-1],thisDatetime)
496 #print("alturas", len(self.y))
497 #print("alturas", len(self.y))
497 self.res_weather, self.res_azi = self.const_ploteo(data_weather=data['weather'],data_azi=data['azi'],step=step,res=res)
498 self.res_weather, self.res_azi = self.const_ploteo(data_weather=data['weather'],data_azi=data['azi'],step=step,res=res)
498 #numpy.set_printoptions(suppress=True)
499 #numpy.set_printoptions(suppress=True)
499 #print("resultado",self.res_azi)
500 #print("resultado",self.res_azi)
500 ##########################################################
501 ##########################################################
501 ################# PLOTEO ###################
502 ################# PLOTEO ###################
502 ##########################################################
503 ##########################################################
503
504
504 for i,ax in enumerate(self.axes):
505 for i,ax in enumerate(self.axes):
505 if ax.firsttime:
506 if ax.firsttime:
506 plt.clf()
507 plt.clf()
507 cgax, pm = wrl.vis.plot_ppi(self.res_weather,r=r,az=self.res_azi,fig=self.figures[0], proj='cg', vmin=1, vmax=60)
508 cgax, pm = wrl.vis.plot_ppi(self.res_weather,r=r,az=self.res_azi,fig=self.figures[0], proj='cg', vmin=1, vmax=60)
508 else:
509 else:
509 plt.clf()
510 plt.clf()
510 cgax, pm = wrl.vis.plot_ppi(self.res_weather,r=r,az=self.res_azi,fig=self.figures[0], proj='cg', vmin=1, vmax=60)
511 cgax, pm = wrl.vis.plot_ppi(self.res_weather,r=r,az=self.res_azi,fig=self.figures[0], proj='cg', vmin=0, vmax=60)
511 caax = cgax.parasites[0]
512 caax = cgax.parasites[0]
512 paax = cgax.parasites[1]
513 paax = cgax.parasites[1]
513 cbar = plt.gcf().colorbar(pm, pad=0.075)
514 cbar = plt.gcf().colorbar(pm, pad=0.075)
514 caax.set_xlabel('x_range [km]')
515 caax.set_xlabel('x_range [km]')
515 caax.set_ylabel('y_range [km]')
516 caax.set_ylabel('y_range [km]')
516 plt.text(1.0, 1.05, 'azimuth '+str(thisDatetime)+"step"+str(self.ini), transform=caax.transAxes, va='bottom',ha='right')
517 plt.text(1.0, 1.05, 'azimuth '+str(thisDatetime)+"step"+str(self.ini), transform=caax.transAxes, va='bottom',ha='right')
517
518
518 self.ini= self.ini+1
519 self.ini= self.ini+1
@@ -1,4450 +1,4475
1 import numpy,os,h5py
1 import numpy,os,h5py
2 import math
2 import math
3 from scipy import optimize, interpolate, signal, stats, ndimage
3 from scipy import optimize, interpolate, signal, stats, ndimage
4 import scipy
4 import scipy
5 import re
5 import re
6 import datetime
6 import datetime
7 import copy
7 import copy
8 import sys
8 import sys
9 import importlib
9 import importlib
10 import itertools
10 import itertools
11 from multiprocessing import Pool, TimeoutError
11 from multiprocessing import Pool, TimeoutError
12 from multiprocessing.pool import ThreadPool
12 from multiprocessing.pool import ThreadPool
13 import time
13 import time
14
14
15 from scipy.optimize import fmin_l_bfgs_b #optimize with bounds on state papameters
15 from scipy.optimize import fmin_l_bfgs_b #optimize with bounds on state papameters
16 from .jroproc_base import ProcessingUnit, Operation, MPDecorator
16 from .jroproc_base import ProcessingUnit, Operation, MPDecorator
17 from schainpy.model.data.jrodata import Parameters, hildebrand_sekhon
17 from schainpy.model.data.jrodata import Parameters, hildebrand_sekhon
18 from scipy import asarray as ar,exp
18 from scipy import asarray as ar,exp
19 from scipy.optimize import curve_fit
19 from scipy.optimize import curve_fit
20 from schainpy.utils import log
20 from schainpy.utils import log
21 import warnings
21 import warnings
22 from numpy import NaN
22 from numpy import NaN
23 from scipy.optimize.optimize import OptimizeWarning
23 from scipy.optimize.optimize import OptimizeWarning
24 warnings.filterwarnings('ignore')
24 warnings.filterwarnings('ignore')
25
25
26 import matplotlib.pyplot as plt
26 import matplotlib.pyplot as plt
27
27
28 SPEED_OF_LIGHT = 299792458
28 SPEED_OF_LIGHT = 299792458
29
29
30 '''solving pickling issue'''
30 '''solving pickling issue'''
31
31
32 def _pickle_method(method):
32 def _pickle_method(method):
33 func_name = method.__func__.__name__
33 func_name = method.__func__.__name__
34 obj = method.__self__
34 obj = method.__self__
35 cls = method.__self__.__class__
35 cls = method.__self__.__class__
36 return _unpickle_method, (func_name, obj, cls)
36 return _unpickle_method, (func_name, obj, cls)
37
37
38 def _unpickle_method(func_name, obj, cls):
38 def _unpickle_method(func_name, obj, cls):
39 for cls in cls.mro():
39 for cls in cls.mro():
40 try:
40 try:
41 func = cls.__dict__[func_name]
41 func = cls.__dict__[func_name]
42 except KeyError:
42 except KeyError:
43 pass
43 pass
44 else:
44 else:
45 break
45 break
46 return func.__get__(obj, cls)
46 return func.__get__(obj, cls)
47
47
48 def isNumber(str):
48 def isNumber(str):
49 try:
49 try:
50 float(str)
50 float(str)
51 return True
51 return True
52 except:
52 except:
53 return False
53 return False
54
54
55 class ParametersProc(ProcessingUnit):
55 class ParametersProc(ProcessingUnit):
56
56
57 METHODS = {}
57 METHODS = {}
58 nSeconds = None
58 nSeconds = None
59
59
60 def __init__(self):
60 def __init__(self):
61 ProcessingUnit.__init__(self)
61 ProcessingUnit.__init__(self)
62
62
63 # self.objectDict = {}
63 # self.objectDict = {}
64 self.buffer = None
64 self.buffer = None
65 self.firstdatatime = None
65 self.firstdatatime = None
66 self.profIndex = 0
66 self.profIndex = 0
67 self.dataOut = Parameters()
67 self.dataOut = Parameters()
68 self.setupReq = False #Agregar a todas las unidades de proc
68 self.setupReq = False #Agregar a todas las unidades de proc
69
69
70 def __updateObjFromInput(self):
70 def __updateObjFromInput(self):
71
71
72 self.dataOut.inputUnit = self.dataIn.type
72 self.dataOut.inputUnit = self.dataIn.type
73
73
74 self.dataOut.timeZone = self.dataIn.timeZone
74 self.dataOut.timeZone = self.dataIn.timeZone
75 self.dataOut.dstFlag = self.dataIn.dstFlag
75 self.dataOut.dstFlag = self.dataIn.dstFlag
76 self.dataOut.errorCount = self.dataIn.errorCount
76 self.dataOut.errorCount = self.dataIn.errorCount
77 self.dataOut.useLocalTime = self.dataIn.useLocalTime
77 self.dataOut.useLocalTime = self.dataIn.useLocalTime
78
78
79 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
79 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
80 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
80 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
81 self.dataOut.channelList = self.dataIn.channelList
81 self.dataOut.channelList = self.dataIn.channelList
82 self.dataOut.heightList = self.dataIn.heightList
82 self.dataOut.heightList = self.dataIn.heightList
83 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
83 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
84 # self.dataOut.nHeights = self.dataIn.nHeights
84 # self.dataOut.nHeights = self.dataIn.nHeights
85 # self.dataOut.nChannels = self.dataIn.nChannels
85 # self.dataOut.nChannels = self.dataIn.nChannels
86 # self.dataOut.nBaud = self.dataIn.nBaud
86 # self.dataOut.nBaud = self.dataIn.nBaud
87 # self.dataOut.nCode = self.dataIn.nCode
87 # self.dataOut.nCode = self.dataIn.nCode
88 # self.dataOut.code = self.dataIn.code
88 # self.dataOut.code = self.dataIn.code
89 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
89 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
90 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
90 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
91 # self.dataOut.utctime = self.firstdatatime
91 # self.dataOut.utctime = self.firstdatatime
92 self.dataOut.utctime = self.dataIn.utctime
92 self.dataOut.utctime = self.dataIn.utctime
93 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
93 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
94 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
94 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
95 self.dataOut.nCohInt = self.dataIn.nCohInt
95 self.dataOut.nCohInt = self.dataIn.nCohInt
96 # self.dataOut.nIncohInt = 1
96 # self.dataOut.nIncohInt = 1
97 # self.dataOut.ippSeconds = self.dataIn.ippSeconds
97 # self.dataOut.ippSeconds = self.dataIn.ippSeconds
98 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
98 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
99 self.dataOut.timeInterval1 = self.dataIn.timeInterval
99 self.dataOut.timeInterval1 = self.dataIn.timeInterval
100 self.dataOut.heightList = self.dataIn.heightList
100 self.dataOut.heightList = self.dataIn.heightList
101 self.dataOut.frequency = self.dataIn.frequency
101 self.dataOut.frequency = self.dataIn.frequency
102 # self.dataOut.noise = self.dataIn.noise
102 # self.dataOut.noise = self.dataIn.noise
103
103
104 def run(self):
104 def run(self):
105
105
106
106
107 #print("HOLA MUNDO SOY YO")
107 #print("HOLA MUNDO SOY YO")
108 #---------------------- Voltage Data ---------------------------
108 #---------------------- Voltage Data ---------------------------
109
109
110 if self.dataIn.type == "Voltage":
110 if self.dataIn.type == "Voltage":
111
111
112 self.__updateObjFromInput()
112 self.__updateObjFromInput()
113 self.dataOut.data_pre = self.dataIn.data.copy()
113 self.dataOut.data_pre = self.dataIn.data.copy()
114 self.dataOut.flagNoData = False
114 self.dataOut.flagNoData = False
115 self.dataOut.utctimeInit = self.dataIn.utctime
115 self.dataOut.utctimeInit = self.dataIn.utctime
116 self.dataOut.paramInterval = self.dataIn.nProfiles*self.dataIn.nCohInt*self.dataIn.ippSeconds
116 self.dataOut.paramInterval = self.dataIn.nProfiles*self.dataIn.nCohInt*self.dataIn.ippSeconds
117
117
118 if hasattr(self.dataIn, 'flagDataAsBlock'):
118 if hasattr(self.dataIn, 'flagDataAsBlock'):
119 self.dataOut.flagDataAsBlock = self.dataIn.flagDataAsBlock
119 self.dataOut.flagDataAsBlock = self.dataIn.flagDataAsBlock
120
120
121 if hasattr(self.dataIn, 'profileIndex'):
121 if hasattr(self.dataIn, 'profileIndex'):
122 self.dataOut.profileIndex = self.dataIn.profileIndex
122 self.dataOut.profileIndex = self.dataIn.profileIndex
123
123
124 if hasattr(self.dataIn, 'dataPP_POW'):
124 if hasattr(self.dataIn, 'dataPP_POW'):
125 self.dataOut.dataPP_POW = self.dataIn.dataPP_POW
125 self.dataOut.dataPP_POW = self.dataIn.dataPP_POW
126
126
127 if hasattr(self.dataIn, 'dataPP_POWER'):
127 if hasattr(self.dataIn, 'dataPP_POWER'):
128 self.dataOut.dataPP_POWER = self.dataIn.dataPP_POWER
128 self.dataOut.dataPP_POWER = self.dataIn.dataPP_POWER
129
129
130 if hasattr(self.dataIn, 'dataPP_DOP'):
130 if hasattr(self.dataIn, 'dataPP_DOP'):
131 self.dataOut.dataPP_DOP = self.dataIn.dataPP_DOP
131 self.dataOut.dataPP_DOP = self.dataIn.dataPP_DOP
132
132
133 if hasattr(self.dataIn, 'dataPP_SNR'):
133 if hasattr(self.dataIn, 'dataPP_SNR'):
134 self.dataOut.dataPP_SNR = self.dataIn.dataPP_SNR
134 self.dataOut.dataPP_SNR = self.dataIn.dataPP_SNR
135
135
136 if hasattr(self.dataIn, 'dataPP_WIDTH'):
136 if hasattr(self.dataIn, 'dataPP_WIDTH'):
137 self.dataOut.dataPP_WIDTH = self.dataIn.dataPP_WIDTH
137 self.dataOut.dataPP_WIDTH = self.dataIn.dataPP_WIDTH
138 return
138 return
139
139
140 #---------------------- Spectra Data ---------------------------
140 #---------------------- Spectra Data ---------------------------
141
141
142 if self.dataIn.type == "Spectra":
142 if self.dataIn.type == "Spectra":
143 #print("que paso en spectra")
143 #print("que paso en spectra")
144 self.dataOut.data_pre = [self.dataIn.data_spc, self.dataIn.data_cspc]
144 self.dataOut.data_pre = [self.dataIn.data_spc, self.dataIn.data_cspc]
145 self.dataOut.data_spc = self.dataIn.data_spc
145 self.dataOut.data_spc = self.dataIn.data_spc
146 self.dataOut.data_cspc = self.dataIn.data_cspc
146 self.dataOut.data_cspc = self.dataIn.data_cspc
147 self.dataOut.nProfiles = self.dataIn.nProfiles
147 self.dataOut.nProfiles = self.dataIn.nProfiles
148 self.dataOut.nIncohInt = self.dataIn.nIncohInt
148 self.dataOut.nIncohInt = self.dataIn.nIncohInt
149 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
149 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
150 self.dataOut.ippFactor = self.dataIn.ippFactor
150 self.dataOut.ippFactor = self.dataIn.ippFactor
151 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
151 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
152 self.dataOut.spc_noise = self.dataIn.getNoise()
152 self.dataOut.spc_noise = self.dataIn.getNoise()
153 self.dataOut.spc_range = (self.dataIn.getFreqRange(1) , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
153 self.dataOut.spc_range = (self.dataIn.getFreqRange(1) , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
154 # self.dataOut.normFactor = self.dataIn.normFactor
154 # self.dataOut.normFactor = self.dataIn.normFactor
155 self.dataOut.pairsList = self.dataIn.pairsList
155 self.dataOut.pairsList = self.dataIn.pairsList
156 self.dataOut.groupList = self.dataIn.pairsList
156 self.dataOut.groupList = self.dataIn.pairsList
157 self.dataOut.flagNoData = False
157 self.dataOut.flagNoData = False
158
158
159 if hasattr(self.dataIn, 'flagDataAsBlock'):
159 if hasattr(self.dataIn, 'flagDataAsBlock'):
160 self.dataOut.flagDataAsBlock = self.dataIn.flagDataAsBlock
160 self.dataOut.flagDataAsBlock = self.dataIn.flagDataAsBlock
161
161
162 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
162 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
163 self.dataOut.ChanDist = self.dataIn.ChanDist
163 self.dataOut.ChanDist = self.dataIn.ChanDist
164 else: self.dataOut.ChanDist = None
164 else: self.dataOut.ChanDist = None
165
165
166 #if hasattr(self.dataIn, 'VelRange'): #Velocities range
166 #if hasattr(self.dataIn, 'VelRange'): #Velocities range
167 # self.dataOut.VelRange = self.dataIn.VelRange
167 # self.dataOut.VelRange = self.dataIn.VelRange
168 #else: self.dataOut.VelRange = None
168 #else: self.dataOut.VelRange = None
169
169
170 if hasattr(self.dataIn, 'RadarConst'): #Radar Constant
170 if hasattr(self.dataIn, 'RadarConst'): #Radar Constant
171 self.dataOut.RadarConst = self.dataIn.RadarConst
171 self.dataOut.RadarConst = self.dataIn.RadarConst
172
172
173 if hasattr(self.dataIn, 'NPW'): #NPW
173 if hasattr(self.dataIn, 'NPW'): #NPW
174 self.dataOut.NPW = self.dataIn.NPW
174 self.dataOut.NPW = self.dataIn.NPW
175
175
176 if hasattr(self.dataIn, 'COFA'): #COFA
176 if hasattr(self.dataIn, 'COFA'): #COFA
177 self.dataOut.COFA = self.dataIn.COFA
177 self.dataOut.COFA = self.dataIn.COFA
178
178
179
179
180
180
181 #---------------------- Correlation Data ---------------------------
181 #---------------------- Correlation Data ---------------------------
182
182
183 if self.dataIn.type == "Correlation":
183 if self.dataIn.type == "Correlation":
184 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
184 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
185
185
186 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
186 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
187 self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
187 self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
188 self.dataOut.groupList = (acf_pairs, ccf_pairs)
188 self.dataOut.groupList = (acf_pairs, ccf_pairs)
189
189
190 self.dataOut.abscissaList = self.dataIn.lagRange
190 self.dataOut.abscissaList = self.dataIn.lagRange
191 self.dataOut.noise = self.dataIn.noise
191 self.dataOut.noise = self.dataIn.noise
192 self.dataOut.data_snr = self.dataIn.SNR
192 self.dataOut.data_snr = self.dataIn.SNR
193 self.dataOut.flagNoData = False
193 self.dataOut.flagNoData = False
194 self.dataOut.nAvg = self.dataIn.nAvg
194 self.dataOut.nAvg = self.dataIn.nAvg
195
195
196 #---------------------- Parameters Data ---------------------------
196 #---------------------- Parameters Data ---------------------------
197
197
198 if self.dataIn.type == "Parameters":
198 if self.dataIn.type == "Parameters":
199 self.dataOut.copy(self.dataIn)
199 self.dataOut.copy(self.dataIn)
200 self.dataOut.flagNoData = False
200 self.dataOut.flagNoData = False
201 #print("yo si entre")
201
202
202 return True
203 return True
203
204
204 self.__updateObjFromInput()
205 self.__updateObjFromInput()
206 #print("yo si entre2")
205
207
206 self.dataOut.utctimeInit = self.dataIn.utctime
208 self.dataOut.utctimeInit = self.dataIn.utctime
207 self.dataOut.paramInterval = self.dataIn.timeInterval
209 self.dataOut.paramInterval = self.dataIn.timeInterval
208 #print("soy spectra ",self.dataOut.utctimeInit)
210 #print("soy spectra ",self.dataOut.utctimeInit)
209 return
211 return
210
212
211
213
212 def target(tups):
214 def target(tups):
213
215
214 obj, args = tups
216 obj, args = tups
215
217
216 return obj.FitGau(args)
218 return obj.FitGau(args)
217
219
218 class RemoveWideGC(Operation):
220 class RemoveWideGC(Operation):
219 ''' This class remove the wide clutter and replace it with a simple interpolation points
221 ''' This class remove the wide clutter and replace it with a simple interpolation points
220 This mainly applies to CLAIRE radar
222 This mainly applies to CLAIRE radar
221
223
222 ClutterWidth : Width to look for the clutter peak
224 ClutterWidth : Width to look for the clutter peak
223
225
224 Input:
226 Input:
225
227
226 self.dataOut.data_pre : SPC and CSPC
228 self.dataOut.data_pre : SPC and CSPC
227 self.dataOut.spc_range : To select wind and rainfall velocities
229 self.dataOut.spc_range : To select wind and rainfall velocities
228
230
229 Affected:
231 Affected:
230
232
231 self.dataOut.data_pre : It is used for the new SPC and CSPC ranges of wind
233 self.dataOut.data_pre : It is used for the new SPC and CSPC ranges of wind
232
234
233 Written by D. ScipiΓ³n 25.02.2021
235 Written by D. ScipiΓ³n 25.02.2021
234 '''
236 '''
235 def __init__(self):
237 def __init__(self):
236 Operation.__init__(self)
238 Operation.__init__(self)
237 self.i = 0
239 self.i = 0
238 self.ich = 0
240 self.ich = 0
239 self.ir = 0
241 self.ir = 0
240
242
241 def run(self, dataOut, ClutterWidth=2.5):
243 def run(self, dataOut, ClutterWidth=2.5):
242 # print ('Entering RemoveWideGC ... ')
244 # print ('Entering RemoveWideGC ... ')
243
245
244 self.spc = dataOut.data_pre[0].copy()
246 self.spc = dataOut.data_pre[0].copy()
245 self.spc_out = dataOut.data_pre[0].copy()
247 self.spc_out = dataOut.data_pre[0].copy()
246 self.Num_Chn = self.spc.shape[0]
248 self.Num_Chn = self.spc.shape[0]
247 self.Num_Hei = self.spc.shape[2]
249 self.Num_Hei = self.spc.shape[2]
248 VelRange = dataOut.spc_range[2][:-1]
250 VelRange = dataOut.spc_range[2][:-1]
249 dv = VelRange[1]-VelRange[0]
251 dv = VelRange[1]-VelRange[0]
250
252
251 # Find the velocities that corresponds to zero
253 # Find the velocities that corresponds to zero
252 gc_values = numpy.squeeze(numpy.where(numpy.abs(VelRange) <= ClutterWidth))
254 gc_values = numpy.squeeze(numpy.where(numpy.abs(VelRange) <= ClutterWidth))
253
255
254 # Removing novalid data from the spectra
256 # Removing novalid data from the spectra
255 for ich in range(self.Num_Chn) :
257 for ich in range(self.Num_Chn) :
256 for ir in range(self.Num_Hei) :
258 for ir in range(self.Num_Hei) :
257 # Estimate the noise at each range
259 # Estimate the noise at each range
258 HSn = hildebrand_sekhon(self.spc[ich,:,ir],dataOut.nIncohInt)
260 HSn = hildebrand_sekhon(self.spc[ich,:,ir],dataOut.nIncohInt)
259
261
260 # Removing the noise floor at each range
262 # Removing the noise floor at each range
261 novalid = numpy.where(self.spc[ich,:,ir] < HSn)
263 novalid = numpy.where(self.spc[ich,:,ir] < HSn)
262 self.spc[ich,novalid,ir] = HSn
264 self.spc[ich,novalid,ir] = HSn
263
265
264 junk = numpy.append(numpy.insert(numpy.squeeze(self.spc[ich,gc_values,ir]),0,HSn),HSn)
266 junk = numpy.append(numpy.insert(numpy.squeeze(self.spc[ich,gc_values,ir]),0,HSn),HSn)
265 j1index = numpy.squeeze(numpy.where(numpy.diff(junk)>0))
267 j1index = numpy.squeeze(numpy.where(numpy.diff(junk)>0))
266 j2index = numpy.squeeze(numpy.where(numpy.diff(junk)<0))
268 j2index = numpy.squeeze(numpy.where(numpy.diff(junk)<0))
267 if ((numpy.size(j1index)<=1) | (numpy.size(j2index)<=1)) :
269 if ((numpy.size(j1index)<=1) | (numpy.size(j2index)<=1)) :
268 continue
270 continue
269 junk3 = numpy.squeeze(numpy.diff(j1index))
271 junk3 = numpy.squeeze(numpy.diff(j1index))
270 junk4 = numpy.squeeze(numpy.diff(j2index))
272 junk4 = numpy.squeeze(numpy.diff(j2index))
271
273
272 valleyindex = j2index[numpy.where(junk4>1)]
274 valleyindex = j2index[numpy.where(junk4>1)]
273 peakindex = j1index[numpy.where(junk3>1)]
275 peakindex = j1index[numpy.where(junk3>1)]
274
276
275 isvalid = numpy.squeeze(numpy.where(numpy.abs(VelRange[gc_values[peakindex]]) <= 2.5*dv))
277 isvalid = numpy.squeeze(numpy.where(numpy.abs(VelRange[gc_values[peakindex]]) <= 2.5*dv))
276 if numpy.size(isvalid) == 0 :
278 if numpy.size(isvalid) == 0 :
277 continue
279 continue
278 if numpy.size(isvalid) >1 :
280 if numpy.size(isvalid) >1 :
279 vindex = numpy.argmax(self.spc[ich,gc_values[peakindex[isvalid]],ir])
281 vindex = numpy.argmax(self.spc[ich,gc_values[peakindex[isvalid]],ir])
280 isvalid = isvalid[vindex]
282 isvalid = isvalid[vindex]
281
283
282 # clutter peak
284 # clutter peak
283 gcpeak = peakindex[isvalid]
285 gcpeak = peakindex[isvalid]
284 vl = numpy.where(valleyindex < gcpeak)
286 vl = numpy.where(valleyindex < gcpeak)
285 if numpy.size(vl) == 0:
287 if numpy.size(vl) == 0:
286 continue
288 continue
287 gcvl = valleyindex[vl[0][-1]]
289 gcvl = valleyindex[vl[0][-1]]
288 vr = numpy.where(valleyindex > gcpeak)
290 vr = numpy.where(valleyindex > gcpeak)
289 if numpy.size(vr) == 0:
291 if numpy.size(vr) == 0:
290 continue
292 continue
291 gcvr = valleyindex[vr[0][0]]
293 gcvr = valleyindex[vr[0][0]]
292
294
293 # Removing the clutter
295 # Removing the clutter
294 interpindex = numpy.array([gc_values[gcvl], gc_values[gcvr]])
296 interpindex = numpy.array([gc_values[gcvl], gc_values[gcvr]])
295 gcindex = gc_values[gcvl+1:gcvr-1]
297 gcindex = gc_values[gcvl+1:gcvr-1]
296 self.spc_out[ich,gcindex,ir] = numpy.interp(VelRange[gcindex],VelRange[interpindex],self.spc[ich,interpindex,ir])
298 self.spc_out[ich,gcindex,ir] = numpy.interp(VelRange[gcindex],VelRange[interpindex],self.spc[ich,interpindex,ir])
297
299
298 dataOut.data_pre[0] = self.spc_out
300 dataOut.data_pre[0] = self.spc_out
299 #print ('Leaving RemoveWideGC ... ')
301 #print ('Leaving RemoveWideGC ... ')
300 return dataOut
302 return dataOut
301
303
302 class SpectralFilters(Operation):
304 class SpectralFilters(Operation):
303 ''' This class allows to replace the novalid values with noise for each channel
305 ''' This class allows to replace the novalid values with noise for each channel
304 This applies to CLAIRE RADAR
306 This applies to CLAIRE RADAR
305
307
306 PositiveLimit : RightLimit of novalid data
308 PositiveLimit : RightLimit of novalid data
307 NegativeLimit : LeftLimit of novalid data
309 NegativeLimit : LeftLimit of novalid data
308
310
309 Input:
311 Input:
310
312
311 self.dataOut.data_pre : SPC and CSPC
313 self.dataOut.data_pre : SPC and CSPC
312 self.dataOut.spc_range : To select wind and rainfall velocities
314 self.dataOut.spc_range : To select wind and rainfall velocities
313
315
314 Affected:
316 Affected:
315
317
316 self.dataOut.data_pre : It is used for the new SPC and CSPC ranges of wind
318 self.dataOut.data_pre : It is used for the new SPC and CSPC ranges of wind
317
319
318 Written by D. ScipiΓ³n 29.01.2021
320 Written by D. ScipiΓ³n 29.01.2021
319 '''
321 '''
320 def __init__(self):
322 def __init__(self):
321 Operation.__init__(self)
323 Operation.__init__(self)
322 self.i = 0
324 self.i = 0
323
325
324 def run(self, dataOut, ):
326 def run(self, dataOut, ):
325
327
326 self.spc = dataOut.data_pre[0].copy()
328 self.spc = dataOut.data_pre[0].copy()
327 self.Num_Chn = self.spc.shape[0]
329 self.Num_Chn = self.spc.shape[0]
328 VelRange = dataOut.spc_range[2]
330 VelRange = dataOut.spc_range[2]
329
331
330 # novalid corresponds to data within the Negative and PositiveLimit
332 # novalid corresponds to data within the Negative and PositiveLimit
331
333
332
334
333 # Removing novalid data from the spectra
335 # Removing novalid data from the spectra
334 for i in range(self.Num_Chn):
336 for i in range(self.Num_Chn):
335 self.spc[i,novalid,:] = dataOut.noise[i]
337 self.spc[i,novalid,:] = dataOut.noise[i]
336 dataOut.data_pre[0] = self.spc
338 dataOut.data_pre[0] = self.spc
337 return dataOut
339 return dataOut
338
340
339 class GaussianFit(Operation):
341 class GaussianFit(Operation):
340
342
341 '''
343 '''
342 Function that fit of one and two generalized gaussians (gg) based
344 Function that fit of one and two generalized gaussians (gg) based
343 on the PSD shape across an "power band" identified from a cumsum of
345 on the PSD shape across an "power band" identified from a cumsum of
344 the measured spectrum - noise.
346 the measured spectrum - noise.
345
347
346 Input:
348 Input:
347 self.dataOut.data_pre : SelfSpectra
349 self.dataOut.data_pre : SelfSpectra
348
350
349 Output:
351 Output:
350 self.dataOut.SPCparam : SPC_ch1, SPC_ch2
352 self.dataOut.SPCparam : SPC_ch1, SPC_ch2
351
353
352 '''
354 '''
353 def __init__(self):
355 def __init__(self):
354 Operation.__init__(self)
356 Operation.__init__(self)
355 self.i=0
357 self.i=0
356
358
357
359
358 # 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
360 # 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
359 def run(self, dataOut, SNRdBlimit=-9, method='generalized'):
361 def run(self, dataOut, SNRdBlimit=-9, method='generalized'):
360 """This routine will find a couple of generalized Gaussians to a power spectrum
362 """This routine will find a couple of generalized Gaussians to a power spectrum
361 methods: generalized, squared
363 methods: generalized, squared
362 input: spc
364 input: spc
363 output:
365 output:
364 noise, amplitude0,shift0,width0,p0,Amplitude1,shift1,width1,p1
366 noise, amplitude0,shift0,width0,p0,Amplitude1,shift1,width1,p1
365 """
367 """
366 print ('Entering ',method,' double Gaussian fit')
368 print ('Entering ',method,' double Gaussian fit')
367 self.spc = dataOut.data_pre[0].copy()
369 self.spc = dataOut.data_pre[0].copy()
368 self.Num_Hei = self.spc.shape[2]
370 self.Num_Hei = self.spc.shape[2]
369 self.Num_Bin = self.spc.shape[1]
371 self.Num_Bin = self.spc.shape[1]
370 self.Num_Chn = self.spc.shape[0]
372 self.Num_Chn = self.spc.shape[0]
371
373
372 start_time = time.time()
374 start_time = time.time()
373
375
374 pool = Pool(processes=self.Num_Chn)
376 pool = Pool(processes=self.Num_Chn)
375 args = [(dataOut.spc_range[2], ich, dataOut.spc_noise[ich], dataOut.nIncohInt, SNRdBlimit) for ich in range(self.Num_Chn)]
377 args = [(dataOut.spc_range[2], ich, dataOut.spc_noise[ich], dataOut.nIncohInt, SNRdBlimit) for ich in range(self.Num_Chn)]
376 objs = [self for __ in range(self.Num_Chn)]
378 objs = [self for __ in range(self.Num_Chn)]
377 attrs = list(zip(objs, args))
379 attrs = list(zip(objs, args))
378 DGauFitParam = pool.map(target, attrs)
380 DGauFitParam = pool.map(target, attrs)
379 # Parameters:
381 # Parameters:
380 # 0. Noise, 1. Amplitude, 2. Shift, 3. Width 4. Power
382 # 0. Noise, 1. Amplitude, 2. Shift, 3. Width 4. Power
381 dataOut.DGauFitParams = numpy.asarray(DGauFitParam)
383 dataOut.DGauFitParams = numpy.asarray(DGauFitParam)
382
384
383 # Double Gaussian Curves
385 # Double Gaussian Curves
384 gau0 = numpy.zeros([self.Num_Chn,self.Num_Bin,self.Num_Hei])
386 gau0 = numpy.zeros([self.Num_Chn,self.Num_Bin,self.Num_Hei])
385 gau0[:] = numpy.NaN
387 gau0[:] = numpy.NaN
386 gau1 = numpy.zeros([self.Num_Chn,self.Num_Bin,self.Num_Hei])
388 gau1 = numpy.zeros([self.Num_Chn,self.Num_Bin,self.Num_Hei])
387 gau1[:] = numpy.NaN
389 gau1[:] = numpy.NaN
388 x_mtr = numpy.transpose(numpy.tile(dataOut.getVelRange(1)[:-1], (self.Num_Hei,1)))
390 x_mtr = numpy.transpose(numpy.tile(dataOut.getVelRange(1)[:-1], (self.Num_Hei,1)))
389 for iCh in range(self.Num_Chn):
391 for iCh in range(self.Num_Chn):
390 N0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][0,:,0]] * self.Num_Bin))
392 N0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][0,:,0]] * self.Num_Bin))
391 N1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][0,:,1]] * self.Num_Bin))
393 N1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][0,:,1]] * self.Num_Bin))
392 A0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][1,:,0]] * self.Num_Bin))
394 A0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][1,:,0]] * self.Num_Bin))
393 A1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][1,:,1]] * self.Num_Bin))
395 A1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][1,:,1]] * self.Num_Bin))
394 v0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][2,:,0]] * self.Num_Bin))
396 v0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][2,:,0]] * self.Num_Bin))
395 v1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][2,:,1]] * self.Num_Bin))
397 v1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][2,:,1]] * self.Num_Bin))
396 s0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][3,:,0]] * self.Num_Bin))
398 s0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][3,:,0]] * self.Num_Bin))
397 s1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][3,:,1]] * self.Num_Bin))
399 s1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][3,:,1]] * self.Num_Bin))
398 if method == 'genealized':
400 if method == 'genealized':
399 p0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][4,:,0]] * self.Num_Bin))
401 p0 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][4,:,0]] * self.Num_Bin))
400 p1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][4,:,1]] * self.Num_Bin))
402 p1 = numpy.transpose(numpy.transpose([dataOut.DGauFitParams[iCh][4,:,1]] * self.Num_Bin))
401 elif method == 'squared':
403 elif method == 'squared':
402 p0 = 2.
404 p0 = 2.
403 p1 = 2.
405 p1 = 2.
404 gau0[iCh] = A0*numpy.exp(-0.5*numpy.abs((x_mtr-v0)/s0)**p0)+N0
406 gau0[iCh] = A0*numpy.exp(-0.5*numpy.abs((x_mtr-v0)/s0)**p0)+N0
405 gau1[iCh] = A1*numpy.exp(-0.5*numpy.abs((x_mtr-v1)/s1)**p1)+N1
407 gau1[iCh] = A1*numpy.exp(-0.5*numpy.abs((x_mtr-v1)/s1)**p1)+N1
406 dataOut.GaussFit0 = gau0
408 dataOut.GaussFit0 = gau0
407 dataOut.GaussFit1 = gau1
409 dataOut.GaussFit1 = gau1
408
410
409 print('Leaving ',method ,' double Gaussian fit')
411 print('Leaving ',method ,' double Gaussian fit')
410 return dataOut
412 return dataOut
411
413
412 def FitGau(self, X):
414 def FitGau(self, X):
413 # print('Entering FitGau')
415 # print('Entering FitGau')
414 # Assigning the variables
416 # Assigning the variables
415 Vrange, ch, wnoise, num_intg, SNRlimit = X
417 Vrange, ch, wnoise, num_intg, SNRlimit = X
416 # Noise Limits
418 # Noise Limits
417 noisebl = wnoise * 0.9
419 noisebl = wnoise * 0.9
418 noisebh = wnoise * 1.1
420 noisebh = wnoise * 1.1
419 # Radar Velocity
421 # Radar Velocity
420 Va = max(Vrange)
422 Va = max(Vrange)
421 deltav = Vrange[1] - Vrange[0]
423 deltav = Vrange[1] - Vrange[0]
422 x = numpy.arange(self.Num_Bin)
424 x = numpy.arange(self.Num_Bin)
423
425
424 # print ('stop 0')
426 # print ('stop 0')
425
427
426 # 5 parameters, 2 Gaussians
428 # 5 parameters, 2 Gaussians
427 DGauFitParam = numpy.zeros([5, self.Num_Hei,2])
429 DGauFitParam = numpy.zeros([5, self.Num_Hei,2])
428 DGauFitParam[:] = numpy.NaN
430 DGauFitParam[:] = numpy.NaN
429
431
430 # SPCparam = []
432 # SPCparam = []
431 # SPC_ch1 = numpy.zeros([self.Num_Bin,self.Num_Hei])
433 # SPC_ch1 = numpy.zeros([self.Num_Bin,self.Num_Hei])
432 # SPC_ch2 = numpy.zeros([self.Num_Bin,self.Num_Hei])
434 # SPC_ch2 = numpy.zeros([self.Num_Bin,self.Num_Hei])
433 # SPC_ch1[:] = 0 #numpy.NaN
435 # SPC_ch1[:] = 0 #numpy.NaN
434 # SPC_ch2[:] = 0 #numpy.NaN
436 # SPC_ch2[:] = 0 #numpy.NaN
435 # print ('stop 1')
437 # print ('stop 1')
436 for ht in range(self.Num_Hei):
438 for ht in range(self.Num_Hei):
437 # print (ht)
439 # print (ht)
438 # print ('stop 2')
440 # print ('stop 2')
439 # Spectra at each range
441 # Spectra at each range
440 spc = numpy.asarray(self.spc)[ch,:,ht]
442 spc = numpy.asarray(self.spc)[ch,:,ht]
441 snr = ( spc.mean() - wnoise ) / wnoise
443 snr = ( spc.mean() - wnoise ) / wnoise
442 snrdB = 10.*numpy.log10(snr)
444 snrdB = 10.*numpy.log10(snr)
443
445
444 #print ('stop 3')
446 #print ('stop 3')
445 if snrdB < SNRlimit :
447 if snrdB < SNRlimit :
446 # snr = numpy.NaN
448 # snr = numpy.NaN
447 # SPC_ch1[:,ht] = 0#numpy.NaN
449 # SPC_ch1[:,ht] = 0#numpy.NaN
448 # SPC_ch1[:,ht] = 0#numpy.NaN
450 # SPC_ch1[:,ht] = 0#numpy.NaN
449 # SPCparam = (SPC_ch1,SPC_ch2)
451 # SPCparam = (SPC_ch1,SPC_ch2)
450 # print ('SNR less than SNRth')
452 # print ('SNR less than SNRth')
451 continue
453 continue
452 # wnoise = hildebrand_sekhon(spc,num_intg)
454 # wnoise = hildebrand_sekhon(spc,num_intg)
453 # print ('stop 2.01')
455 # print ('stop 2.01')
454 #############################################
456 #############################################
455 # normalizing spc and noise
457 # normalizing spc and noise
456 # This part differs from gg1
458 # This part differs from gg1
457 # spc_norm_max = max(spc) #commented by D. ScipiΓ³n 19.03.2021
459 # spc_norm_max = max(spc) #commented by D. ScipiΓ³n 19.03.2021
458 #spc = spc / spc_norm_max
460 #spc = spc / spc_norm_max
459 # pnoise = pnoise #/ spc_norm_max #commented by D. ScipiΓ³n 19.03.2021
461 # pnoise = pnoise #/ spc_norm_max #commented by D. ScipiΓ³n 19.03.2021
460 #############################################
462 #############################################
461
463
462 # print ('stop 2.1')
464 # print ('stop 2.1')
463 fatspectra=1.0
465 fatspectra=1.0
464 # noise per channel.... we might want to use the noise at each range
466 # noise per channel.... we might want to use the noise at each range
465
467
466 # wnoise = noise_ #/ spc_norm_max #commented by D. ScipiΓ³n 19.03.2021
468 # wnoise = noise_ #/ spc_norm_max #commented by D. ScipiΓ³n 19.03.2021
467 #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
469 #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
468 #if wnoise>1.1*pnoise: # to be tested later
470 #if wnoise>1.1*pnoise: # to be tested later
469 # wnoise=pnoise
471 # wnoise=pnoise
470 # noisebl = wnoise*0.9
472 # noisebl = wnoise*0.9
471 # noisebh = wnoise*1.1
473 # noisebh = wnoise*1.1
472 spc = spc - wnoise # signal
474 spc = spc - wnoise # signal
473
475
474 # print ('stop 2.2')
476 # print ('stop 2.2')
475 minx = numpy.argmin(spc)
477 minx = numpy.argmin(spc)
476 #spcs=spc.copy()
478 #spcs=spc.copy()
477 spcs = numpy.roll(spc,-minx)
479 spcs = numpy.roll(spc,-minx)
478 cum = numpy.cumsum(spcs)
480 cum = numpy.cumsum(spcs)
479 # tot_noise = wnoise * self.Num_Bin #64;
481 # tot_noise = wnoise * self.Num_Bin #64;
480
482
481 # print ('stop 2.3')
483 # print ('stop 2.3')
482 # snr = sum(spcs) / tot_noise
484 # snr = sum(spcs) / tot_noise
483 # snrdB = 10.*numpy.log10(snr)
485 # snrdB = 10.*numpy.log10(snr)
484 #print ('stop 3')
486 #print ('stop 3')
485 # if snrdB < SNRlimit :
487 # if snrdB < SNRlimit :
486 # snr = numpy.NaN
488 # snr = numpy.NaN
487 # SPC_ch1[:,ht] = 0#numpy.NaN
489 # SPC_ch1[:,ht] = 0#numpy.NaN
488 # SPC_ch1[:,ht] = 0#numpy.NaN
490 # SPC_ch1[:,ht] = 0#numpy.NaN
489 # SPCparam = (SPC_ch1,SPC_ch2)
491 # SPCparam = (SPC_ch1,SPC_ch2)
490 # print ('SNR less than SNRth')
492 # print ('SNR less than SNRth')
491 # continue
493 # continue
492
494
493
495
494 #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
496 #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
495 # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
497 # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
496 # print ('stop 4')
498 # print ('stop 4')
497 cummax = max(cum)
499 cummax = max(cum)
498 epsi = 0.08 * fatspectra # cumsum to narrow down the energy region
500 epsi = 0.08 * fatspectra # cumsum to narrow down the energy region
499 cumlo = cummax * epsi
501 cumlo = cummax * epsi
500 cumhi = cummax * (1-epsi)
502 cumhi = cummax * (1-epsi)
501 powerindex = numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
503 powerindex = numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
502
504
503 # print ('stop 5')
505 # print ('stop 5')
504 if len(powerindex) < 1:# case for powerindex 0
506 if len(powerindex) < 1:# case for powerindex 0
505 # print ('powerindex < 1')
507 # print ('powerindex < 1')
506 continue
508 continue
507 powerlo = powerindex[0]
509 powerlo = powerindex[0]
508 powerhi = powerindex[-1]
510 powerhi = powerindex[-1]
509 powerwidth = powerhi-powerlo
511 powerwidth = powerhi-powerlo
510 if powerwidth <= 1:
512 if powerwidth <= 1:
511 # print('powerwidth <= 1')
513 # print('powerwidth <= 1')
512 continue
514 continue
513
515
514 # print ('stop 6')
516 # print ('stop 6')
515 firstpeak = powerlo + powerwidth/10.# first gaussian energy location
517 firstpeak = powerlo + powerwidth/10.# first gaussian energy location
516 secondpeak = powerhi - powerwidth/10. #second gaussian energy location
518 secondpeak = powerhi - powerwidth/10. #second gaussian energy location
517 midpeak = (firstpeak + secondpeak)/2.
519 midpeak = (firstpeak + secondpeak)/2.
518 firstamp = spcs[int(firstpeak)]
520 firstamp = spcs[int(firstpeak)]
519 secondamp = spcs[int(secondpeak)]
521 secondamp = spcs[int(secondpeak)]
520 midamp = spcs[int(midpeak)]
522 midamp = spcs[int(midpeak)]
521
523
522 y_data = spc + wnoise
524 y_data = spc + wnoise
523
525
524 ''' single Gaussian '''
526 ''' single Gaussian '''
525 shift0 = numpy.mod(midpeak+minx, self.Num_Bin )
527 shift0 = numpy.mod(midpeak+minx, self.Num_Bin )
526 width0 = powerwidth/4.#Initialization entire power of spectrum divided by 4
528 width0 = powerwidth/4.#Initialization entire power of spectrum divided by 4
527 power0 = 2.
529 power0 = 2.
528 amplitude0 = midamp
530 amplitude0 = midamp
529 state0 = [shift0,width0,amplitude0,power0,wnoise]
531 state0 = [shift0,width0,amplitude0,power0,wnoise]
530 bnds = ((0,self.Num_Bin-1),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
532 bnds = ((0,self.Num_Bin-1),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
531 lsq1 = fmin_l_bfgs_b(self.misfit1, state0, args=(y_data,x,num_intg), bounds=bnds, approx_grad=True)
533 lsq1 = fmin_l_bfgs_b(self.misfit1, state0, args=(y_data,x,num_intg), bounds=bnds, approx_grad=True)
532 # print ('stop 7.1')
534 # print ('stop 7.1')
533 # print (bnds)
535 # print (bnds)
534
536
535 chiSq1=lsq1[1]
537 chiSq1=lsq1[1]
536
538
537 # print ('stop 8')
539 # print ('stop 8')
538 if fatspectra<1.0 and powerwidth<4:
540 if fatspectra<1.0 and powerwidth<4:
539 choice=0
541 choice=0
540 Amplitude0=lsq1[0][2]
542 Amplitude0=lsq1[0][2]
541 shift0=lsq1[0][0]
543 shift0=lsq1[0][0]
542 width0=lsq1[0][1]
544 width0=lsq1[0][1]
543 p0=lsq1[0][3]
545 p0=lsq1[0][3]
544 Amplitude1=0.
546 Amplitude1=0.
545 shift1=0.
547 shift1=0.
546 width1=0.
548 width1=0.
547 p1=0.
549 p1=0.
548 noise=lsq1[0][4]
550 noise=lsq1[0][4]
549 #return (numpy.array([shift0,width0,Amplitude0,p0]),
551 #return (numpy.array([shift0,width0,Amplitude0,p0]),
550 # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
552 # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
551
553
552 # print ('stop 9')
554 # print ('stop 9')
553 ''' two Gaussians '''
555 ''' two Gaussians '''
554 #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
556 #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
555 shift0 = numpy.mod(firstpeak+minx, self.Num_Bin )
557 shift0 = numpy.mod(firstpeak+minx, self.Num_Bin )
556 shift1 = numpy.mod(secondpeak+minx, self.Num_Bin )
558 shift1 = numpy.mod(secondpeak+minx, self.Num_Bin )
557 width0 = powerwidth/6.
559 width0 = powerwidth/6.
558 width1 = width0
560 width1 = width0
559 power0 = 2.
561 power0 = 2.
560 power1 = power0
562 power1 = power0
561 amplitude0 = firstamp
563 amplitude0 = firstamp
562 amplitude1 = secondamp
564 amplitude1 = secondamp
563 state0 = [shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
565 state0 = [shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
564 #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
566 #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
565 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))
567 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))
566 #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))
568 #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))
567
569
568 # print ('stop 10')
570 # print ('stop 10')
569 lsq2 = fmin_l_bfgs_b( self.misfit2 , state0 , args=(y_data,x,num_intg) , bounds=bnds , approx_grad=True )
571 lsq2 = fmin_l_bfgs_b( self.misfit2 , state0 , args=(y_data,x,num_intg) , bounds=bnds , approx_grad=True )
570
572
571 # print ('stop 11')
573 # print ('stop 11')
572 chiSq2 = lsq2[1]
574 chiSq2 = lsq2[1]
573
575
574 # print ('stop 12')
576 # print ('stop 12')
575
577
576 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)
578 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)
577
579
578 # print ('stop 13')
580 # print ('stop 13')
579 if snrdB>-12: # when SNR is strong pick the peak with least shift (LOS velocity) error
581 if snrdB>-12: # when SNR is strong pick the peak with least shift (LOS velocity) error
580 if oneG:
582 if oneG:
581 choice = 0
583 choice = 0
582 else:
584 else:
583 w1 = lsq2[0][1]; w2 = lsq2[0][5]
585 w1 = lsq2[0][1]; w2 = lsq2[0][5]
584 a1 = lsq2[0][2]; a2 = lsq2[0][6]
586 a1 = lsq2[0][2]; a2 = lsq2[0][6]
585 p1 = lsq2[0][3]; p2 = lsq2[0][7]
587 p1 = lsq2[0][3]; p2 = lsq2[0][7]
586 s1 = (2**(1+1./p1))*scipy.special.gamma(1./p1)/p1
588 s1 = (2**(1+1./p1))*scipy.special.gamma(1./p1)/p1
587 s2 = (2**(1+1./p2))*scipy.special.gamma(1./p2)/p2
589 s2 = (2**(1+1./p2))*scipy.special.gamma(1./p2)/p2
588 gp1 = a1*w1*s1; gp2 = a2*w2*s2 # power content of each ggaussian with proper p scaling
590 gp1 = a1*w1*s1; gp2 = a2*w2*s2 # power content of each ggaussian with proper p scaling
589
591
590 if gp1>gp2:
592 if gp1>gp2:
591 if a1>0.7*a2:
593 if a1>0.7*a2:
592 choice = 1
594 choice = 1
593 else:
595 else:
594 choice = 2
596 choice = 2
595 elif gp2>gp1:
597 elif gp2>gp1:
596 if a2>0.7*a1:
598 if a2>0.7*a1:
597 choice = 2
599 choice = 2
598 else:
600 else:
599 choice = 1
601 choice = 1
600 else:
602 else:
601 choice = numpy.argmax([a1,a2])+1
603 choice = numpy.argmax([a1,a2])+1
602 #else:
604 #else:
603 #choice=argmin([std2a,std2b])+1
605 #choice=argmin([std2a,std2b])+1
604
606
605 else: # with low SNR go to the most energetic peak
607 else: # with low SNR go to the most energetic peak
606 choice = numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
608 choice = numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
607
609
608 # print ('stop 14')
610 # print ('stop 14')
609 shift0 = lsq2[0][0]
611 shift0 = lsq2[0][0]
610 vel0 = Vrange[0] + shift0 * deltav
612 vel0 = Vrange[0] + shift0 * deltav
611 shift1 = lsq2[0][4]
613 shift1 = lsq2[0][4]
612 # vel1=Vrange[0] + shift1 * deltav
614 # vel1=Vrange[0] + shift1 * deltav
613
615
614 # max_vel = 1.0
616 # max_vel = 1.0
615 # Va = max(Vrange)
617 # Va = max(Vrange)
616 # deltav = Vrange[1]-Vrange[0]
618 # deltav = Vrange[1]-Vrange[0]
617 # print ('stop 15')
619 # print ('stop 15')
618 #first peak will be 0, second peak will be 1
620 #first peak will be 0, second peak will be 1
619 # if vel0 > -1.0 and vel0 < max_vel : #first peak is in the correct range # Commented by D.ScipiΓ³n 19.03.2021
621 # if vel0 > -1.0 and vel0 < max_vel : #first peak is in the correct range # Commented by D.ScipiΓ³n 19.03.2021
620 if vel0 > -Va and vel0 < Va : #first peak is in the correct range
622 if vel0 > -Va and vel0 < Va : #first peak is in the correct range
621 shift0 = lsq2[0][0]
623 shift0 = lsq2[0][0]
622 width0 = lsq2[0][1]
624 width0 = lsq2[0][1]
623 Amplitude0 = lsq2[0][2]
625 Amplitude0 = lsq2[0][2]
624 p0 = lsq2[0][3]
626 p0 = lsq2[0][3]
625
627
626 shift1 = lsq2[0][4]
628 shift1 = lsq2[0][4]
627 width1 = lsq2[0][5]
629 width1 = lsq2[0][5]
628 Amplitude1 = lsq2[0][6]
630 Amplitude1 = lsq2[0][6]
629 p1 = lsq2[0][7]
631 p1 = lsq2[0][7]
630 noise = lsq2[0][8]
632 noise = lsq2[0][8]
631 else:
633 else:
632 shift1 = lsq2[0][0]
634 shift1 = lsq2[0][0]
633 width1 = lsq2[0][1]
635 width1 = lsq2[0][1]
634 Amplitude1 = lsq2[0][2]
636 Amplitude1 = lsq2[0][2]
635 p1 = lsq2[0][3]
637 p1 = lsq2[0][3]
636
638
637 shift0 = lsq2[0][4]
639 shift0 = lsq2[0][4]
638 width0 = lsq2[0][5]
640 width0 = lsq2[0][5]
639 Amplitude0 = lsq2[0][6]
641 Amplitude0 = lsq2[0][6]
640 p0 = lsq2[0][7]
642 p0 = lsq2[0][7]
641 noise = lsq2[0][8]
643 noise = lsq2[0][8]
642
644
643 if Amplitude0<0.05: # in case the peak is noise
645 if Amplitude0<0.05: # in case the peak is noise
644 shift0,width0,Amplitude0,p0 = 4*[numpy.NaN]
646 shift0,width0,Amplitude0,p0 = 4*[numpy.NaN]
645 if Amplitude1<0.05:
647 if Amplitude1<0.05:
646 shift1,width1,Amplitude1,p1 = 4*[numpy.NaN]
648 shift1,width1,Amplitude1,p1 = 4*[numpy.NaN]
647
649
648 # print ('stop 16 ')
650 # print ('stop 16 ')
649 # SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0)/width0)**p0)
651 # SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0)/width0)**p0)
650 # SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1)/width1)**p1)
652 # SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1)/width1)**p1)
651 # SPCparam = (SPC_ch1,SPC_ch2)
653 # SPCparam = (SPC_ch1,SPC_ch2)
652
654
653 DGauFitParam[0,ht,0] = noise
655 DGauFitParam[0,ht,0] = noise
654 DGauFitParam[0,ht,1] = noise
656 DGauFitParam[0,ht,1] = noise
655 DGauFitParam[1,ht,0] = Amplitude0
657 DGauFitParam[1,ht,0] = Amplitude0
656 DGauFitParam[1,ht,1] = Amplitude1
658 DGauFitParam[1,ht,1] = Amplitude1
657 DGauFitParam[2,ht,0] = Vrange[0] + shift0 * deltav
659 DGauFitParam[2,ht,0] = Vrange[0] + shift0 * deltav
658 DGauFitParam[2,ht,1] = Vrange[0] + shift1 * deltav
660 DGauFitParam[2,ht,1] = Vrange[0] + shift1 * deltav
659 DGauFitParam[3,ht,0] = width0 * deltav
661 DGauFitParam[3,ht,0] = width0 * deltav
660 DGauFitParam[3,ht,1] = width1 * deltav
662 DGauFitParam[3,ht,1] = width1 * deltav
661 DGauFitParam[4,ht,0] = p0
663 DGauFitParam[4,ht,0] = p0
662 DGauFitParam[4,ht,1] = p1
664 DGauFitParam[4,ht,1] = p1
663
665
664 # print (DGauFitParam.shape)
666 # print (DGauFitParam.shape)
665 # print ('Leaving FitGau')
667 # print ('Leaving FitGau')
666 return DGauFitParam
668 return DGauFitParam
667 # return SPCparam
669 # return SPCparam
668 # return GauSPC
670 # return GauSPC
669
671
670 def y_model1(self,x,state):
672 def y_model1(self,x,state):
671 shift0, width0, amplitude0, power0, noise = state
673 shift0, width0, amplitude0, power0, noise = state
672 model0 = amplitude0*numpy.exp(-0.5*abs((x - shift0)/width0)**power0)
674 model0 = amplitude0*numpy.exp(-0.5*abs((x - shift0)/width0)**power0)
673 model0u = amplitude0*numpy.exp(-0.5*abs((x - shift0 - self.Num_Bin)/width0)**power0)
675 model0u = amplitude0*numpy.exp(-0.5*abs((x - shift0 - self.Num_Bin)/width0)**power0)
674 model0d = amplitude0*numpy.exp(-0.5*abs((x - shift0 + self.Num_Bin)/width0)**power0)
676 model0d = amplitude0*numpy.exp(-0.5*abs((x - shift0 + self.Num_Bin)/width0)**power0)
675 return model0 + model0u + model0d + noise
677 return model0 + model0u + model0d + noise
676
678
677 def y_model2(self,x,state): #Equation for two generalized Gaussians with Nyquist
679 def y_model2(self,x,state): #Equation for two generalized Gaussians with Nyquist
678 shift0, width0, amplitude0, power0, shift1, width1, amplitude1, power1, noise = state
680 shift0, width0, amplitude0, power0, shift1, width1, amplitude1, power1, noise = state
679 model0 = amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
681 model0 = amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
680 model0u = amplitude0*numpy.exp(-0.5*abs((x - shift0 - self.Num_Bin)/width0)**power0)
682 model0u = amplitude0*numpy.exp(-0.5*abs((x - shift0 - self.Num_Bin)/width0)**power0)
681 model0d = amplitude0*numpy.exp(-0.5*abs((x - shift0 + self.Num_Bin)/width0)**power0)
683 model0d = amplitude0*numpy.exp(-0.5*abs((x - shift0 + self.Num_Bin)/width0)**power0)
682
684
683 model1 = amplitude1*numpy.exp(-0.5*abs((x - shift1)/width1)**power1)
685 model1 = amplitude1*numpy.exp(-0.5*abs((x - shift1)/width1)**power1)
684 model1u = amplitude1*numpy.exp(-0.5*abs((x - shift1 - self.Num_Bin)/width1)**power1)
686 model1u = amplitude1*numpy.exp(-0.5*abs((x - shift1 - self.Num_Bin)/width1)**power1)
685 model1d = amplitude1*numpy.exp(-0.5*abs((x - shift1 + self.Num_Bin)/width1)**power1)
687 model1d = amplitude1*numpy.exp(-0.5*abs((x - shift1 + self.Num_Bin)/width1)**power1)
686 return model0 + model0u + model0d + model1 + model1u + model1d + noise
688 return model0 + model0u + model0d + model1 + model1u + model1d + noise
687
689
688 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.
690 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.
689
691
690 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model1(x,state)))**2)#/(64-5.) # /(64-5.) can be commented
692 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model1(x,state)))**2)#/(64-5.) # /(64-5.) can be commented
691
693
692 def misfit2(self,state,y_data,x,num_intg):
694 def misfit2(self,state,y_data,x,num_intg):
693 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model2(x,state)))**2)#/(64-9.)
695 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model2(x,state)))**2)#/(64-9.)
694
696
695
697
696
698
697 class PrecipitationProc(Operation):
699 class PrecipitationProc(Operation):
698
700
699 '''
701 '''
700 Operator that estimates Reflectivity factor (Z), and estimates rainfall Rate (R)
702 Operator that estimates Reflectivity factor (Z), and estimates rainfall Rate (R)
701
703
702 Input:
704 Input:
703 self.dataOut.data_pre : SelfSpectra
705 self.dataOut.data_pre : SelfSpectra
704
706
705 Output:
707 Output:
706
708
707 self.dataOut.data_output : Reflectivity factor, rainfall Rate
709 self.dataOut.data_output : Reflectivity factor, rainfall Rate
708
710
709
711
710 Parameters affected:
712 Parameters affected:
711 '''
713 '''
712
714
713 def __init__(self):
715 def __init__(self):
714 Operation.__init__(self)
716 Operation.__init__(self)
715 self.i=0
717 self.i=0
716
718
717 def run(self, dataOut, radar=None, Pt=5000, Gt=295.1209, Gr=70.7945, Lambda=0.6741, aL=2.5118,
719 def run(self, dataOut, radar=None, Pt=5000, Gt=295.1209, Gr=70.7945, Lambda=0.6741, aL=2.5118,
718 tauW=4e-06, ThetaT=0.1656317, ThetaR=0.36774087, Km2 = 0.93, Altitude=3350,SNRdBlimit=-30):
720 tauW=4e-06, ThetaT=0.1656317, ThetaR=0.36774087, Km2 = 0.93, Altitude=3350,SNRdBlimit=-30):
719
721
720 # print ('Entering PrecepitationProc ... ')
722 # print ('Entering PrecepitationProc ... ')
721
723
722 if radar == "MIRA35C" :
724 if radar == "MIRA35C" :
723
725
724 self.spc = dataOut.data_pre[0].copy()
726 self.spc = dataOut.data_pre[0].copy()
725 self.Num_Hei = self.spc.shape[2]
727 self.Num_Hei = self.spc.shape[2]
726 self.Num_Bin = self.spc.shape[1]
728 self.Num_Bin = self.spc.shape[1]
727 self.Num_Chn = self.spc.shape[0]
729 self.Num_Chn = self.spc.shape[0]
728 Ze = self.dBZeMODE2(dataOut)
730 Ze = self.dBZeMODE2(dataOut)
729
731
730 else:
732 else:
731
733
732 self.spc = dataOut.data_pre[0].copy()
734 self.spc = dataOut.data_pre[0].copy()
733
735
734 #NOTA SE DEBE REMOVER EL RANGO DEL PULSO TX
736 #NOTA SE DEBE REMOVER EL RANGO DEL PULSO TX
735 self.spc[:,:,0:7]= numpy.NaN
737 self.spc[:,:,0:7]= numpy.NaN
736
738
737 self.Num_Hei = self.spc.shape[2]
739 self.Num_Hei = self.spc.shape[2]
738 self.Num_Bin = self.spc.shape[1]
740 self.Num_Bin = self.spc.shape[1]
739 self.Num_Chn = self.spc.shape[0]
741 self.Num_Chn = self.spc.shape[0]
740
742
741 VelRange = dataOut.spc_range[2]
743 VelRange = dataOut.spc_range[2]
742
744
743 ''' Se obtiene la constante del RADAR '''
745 ''' Se obtiene la constante del RADAR '''
744
746
745 self.Pt = Pt
747 self.Pt = Pt
746 self.Gt = Gt
748 self.Gt = Gt
747 self.Gr = Gr
749 self.Gr = Gr
748 self.Lambda = Lambda
750 self.Lambda = Lambda
749 self.aL = aL
751 self.aL = aL
750 self.tauW = tauW
752 self.tauW = tauW
751 self.ThetaT = ThetaT
753 self.ThetaT = ThetaT
752 self.ThetaR = ThetaR
754 self.ThetaR = ThetaR
753 self.GSys = 10**(36.63/10) # Ganancia de los LNA 36.63 dB
755 self.GSys = 10**(36.63/10) # Ganancia de los LNA 36.63 dB
754 self.lt = 10**(1.67/10) # Perdida en cables Tx 1.67 dB
756 self.lt = 10**(1.67/10) # Perdida en cables Tx 1.67 dB
755 self.lr = 10**(5.73/10) # Perdida en cables Rx 5.73 dB
757 self.lr = 10**(5.73/10) # Perdida en cables Rx 5.73 dB
756
758
757 Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
759 Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
758 Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * tauW * numpy.pi * ThetaT * ThetaR)
760 Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * tauW * numpy.pi * ThetaT * ThetaR)
759 RadarConstant = 10e-26 * Numerator / Denominator #
761 RadarConstant = 10e-26 * Numerator / Denominator #
760 ExpConstant = 10**(40/10) #Constante Experimental
762 ExpConstant = 10**(40/10) #Constante Experimental
761
763
762 SignalPower = numpy.zeros([self.Num_Chn,self.Num_Bin,self.Num_Hei])
764 SignalPower = numpy.zeros([self.Num_Chn,self.Num_Bin,self.Num_Hei])
763 for i in range(self.Num_Chn):
765 for i in range(self.Num_Chn):
764 SignalPower[i,:,:] = self.spc[i,:,:] - dataOut.noise[i]
766 SignalPower[i,:,:] = self.spc[i,:,:] - dataOut.noise[i]
765 SignalPower[numpy.where(SignalPower < 0)] = 1e-20
767 SignalPower[numpy.where(SignalPower < 0)] = 1e-20
766
768
767 SPCmean = numpy.mean(SignalPower, 0)
769 SPCmean = numpy.mean(SignalPower, 0)
768 Pr = SPCmean[:,:]/dataOut.normFactor
770 Pr = SPCmean[:,:]/dataOut.normFactor
769
771
770 # Declaring auxiliary variables
772 # Declaring auxiliary variables
771 Range = dataOut.heightList*1000. #Range in m
773 Range = dataOut.heightList*1000. #Range in m
772 # replicate the heightlist to obtain a matrix [Num_Bin,Num_Hei]
774 # replicate the heightlist to obtain a matrix [Num_Bin,Num_Hei]
773 rMtrx = numpy.transpose(numpy.transpose([dataOut.heightList*1000.] * self.Num_Bin))
775 rMtrx = numpy.transpose(numpy.transpose([dataOut.heightList*1000.] * self.Num_Bin))
774 zMtrx = rMtrx+Altitude
776 zMtrx = rMtrx+Altitude
775 # replicate the VelRange to obtain a matrix [Num_Bin,Num_Hei]
777 # replicate the VelRange to obtain a matrix [Num_Bin,Num_Hei]
776 VelMtrx = numpy.transpose(numpy.tile(VelRange[:-1], (self.Num_Hei,1)))
778 VelMtrx = numpy.transpose(numpy.tile(VelRange[:-1], (self.Num_Hei,1)))
777
779
778 # height dependence to air density Foote and Du Toit (1969)
780 # height dependence to air density Foote and Du Toit (1969)
779 delv_z = 1 + 3.68e-5 * zMtrx + 1.71e-9 * zMtrx**2
781 delv_z = 1 + 3.68e-5 * zMtrx + 1.71e-9 * zMtrx**2
780 VMtrx = VelMtrx / delv_z #Normalized velocity
782 VMtrx = VelMtrx / delv_z #Normalized velocity
781 VMtrx[numpy.where(VMtrx> 9.6)] = numpy.NaN
783 VMtrx[numpy.where(VMtrx> 9.6)] = numpy.NaN
782 # Diameter is related to the fall speed of falling drops
784 # Diameter is related to the fall speed of falling drops
783 D_Vz = -1.667 * numpy.log( 0.9369 - 0.097087 * VMtrx ) # D in [mm]
785 D_Vz = -1.667 * numpy.log( 0.9369 - 0.097087 * VMtrx ) # D in [mm]
784 # Only valid for D>= 0.16 mm
786 # Only valid for D>= 0.16 mm
785 D_Vz[numpy.where(D_Vz < 0.16)] = numpy.NaN
787 D_Vz[numpy.where(D_Vz < 0.16)] = numpy.NaN
786
788
787 #Calculate Radar Reflectivity ETAn
789 #Calculate Radar Reflectivity ETAn
788 ETAn = (RadarConstant *ExpConstant) * Pr * rMtrx**2 #Reflectivity (ETA)
790 ETAn = (RadarConstant *ExpConstant) * Pr * rMtrx**2 #Reflectivity (ETA)
789 ETAd = ETAn * 6.18 * exp( -0.6 * D_Vz ) * delv_z
791 ETAd = ETAn * 6.18 * exp( -0.6 * D_Vz ) * delv_z
790 # Radar Cross Section
792 # Radar Cross Section
791 sigmaD = Km2 * (D_Vz * 1e-3 )**6 * numpy.pi**5 / Lambda**4
793 sigmaD = Km2 * (D_Vz * 1e-3 )**6 * numpy.pi**5 / Lambda**4
792 # Drop Size Distribution
794 # Drop Size Distribution
793 DSD = ETAn / sigmaD
795 DSD = ETAn / sigmaD
794 # Equivalente Reflectivy
796 # Equivalente Reflectivy
795 Ze_eqn = numpy.nansum( DSD * D_Vz**6 ,axis=0)
797 Ze_eqn = numpy.nansum( DSD * D_Vz**6 ,axis=0)
796 Ze_org = numpy.nansum(ETAn * Lambda**4, axis=0) / (1e-18*numpy.pi**5 * Km2) # [mm^6 /m^3]
798 Ze_org = numpy.nansum(ETAn * Lambda**4, axis=0) / (1e-18*numpy.pi**5 * Km2) # [mm^6 /m^3]
797 # RainFall Rate
799 # RainFall Rate
798 RR = 0.0006*numpy.pi * numpy.nansum( D_Vz**3 * DSD * VelMtrx ,0) #mm/hr
800 RR = 0.0006*numpy.pi * numpy.nansum( D_Vz**3 * DSD * VelMtrx ,0) #mm/hr
799
801
800 # Censoring the data
802 # Censoring the data
801 # Removing data with SNRth < 0dB se debe considerar el SNR por canal
803 # Removing data with SNRth < 0dB se debe considerar el SNR por canal
802 SNRth = 10**(SNRdBlimit/10) #-30dB
804 SNRth = 10**(SNRdBlimit/10) #-30dB
803 novalid = numpy.where((dataOut.data_snr[0,:] <SNRth) | (dataOut.data_snr[1,:] <SNRth) | (dataOut.data_snr[2,:] <SNRth)) # AND condition. Maybe OR condition better
805 novalid = numpy.where((dataOut.data_snr[0,:] <SNRth) | (dataOut.data_snr[1,:] <SNRth) | (dataOut.data_snr[2,:] <SNRth)) # AND condition. Maybe OR condition better
804 W = numpy.nanmean(dataOut.data_dop,0)
806 W = numpy.nanmean(dataOut.data_dop,0)
805 W[novalid] = numpy.NaN
807 W[novalid] = numpy.NaN
806 Ze_org[novalid] = numpy.NaN
808 Ze_org[novalid] = numpy.NaN
807 RR[novalid] = numpy.NaN
809 RR[novalid] = numpy.NaN
808
810
809 dataOut.data_output = RR[8]
811 dataOut.data_output = RR[8]
810 dataOut.data_param = numpy.ones([3,self.Num_Hei])
812 dataOut.data_param = numpy.ones([3,self.Num_Hei])
811 dataOut.channelList = [0,1,2]
813 dataOut.channelList = [0,1,2]
812
814
813 dataOut.data_param[0]=10*numpy.log10(Ze_org)
815 dataOut.data_param[0]=10*numpy.log10(Ze_org)
814 dataOut.data_param[1]=-W
816 dataOut.data_param[1]=-W
815 dataOut.data_param[2]=RR
817 dataOut.data_param[2]=RR
816
818
817 # print ('Leaving PrecepitationProc ... ')
819 # print ('Leaving PrecepitationProc ... ')
818 return dataOut
820 return dataOut
819
821
820 def dBZeMODE2(self, dataOut): # Processing for MIRA35C
822 def dBZeMODE2(self, dataOut): # Processing for MIRA35C
821
823
822 NPW = dataOut.NPW
824 NPW = dataOut.NPW
823 COFA = dataOut.COFA
825 COFA = dataOut.COFA
824
826
825 SNR = numpy.array([self.spc[0,:,:] / NPW[0]]) #, self.spc[1,:,:] / NPW[1]])
827 SNR = numpy.array([self.spc[0,:,:] / NPW[0]]) #, self.spc[1,:,:] / NPW[1]])
826 RadarConst = dataOut.RadarConst
828 RadarConst = dataOut.RadarConst
827 #frequency = 34.85*10**9
829 #frequency = 34.85*10**9
828
830
829 ETA = numpy.zeros(([self.Num_Chn ,self.Num_Hei]))
831 ETA = numpy.zeros(([self.Num_Chn ,self.Num_Hei]))
830 data_output = numpy.ones([self.Num_Chn , self.Num_Hei])*numpy.NaN
832 data_output = numpy.ones([self.Num_Chn , self.Num_Hei])*numpy.NaN
831
833
832 ETA = numpy.sum(SNR,1)
834 ETA = numpy.sum(SNR,1)
833
835
834 ETA = numpy.where(ETA != 0. , ETA, numpy.NaN)
836 ETA = numpy.where(ETA != 0. , ETA, numpy.NaN)
835
837
836 Ze = numpy.ones([self.Num_Chn, self.Num_Hei] )
838 Ze = numpy.ones([self.Num_Chn, self.Num_Hei] )
837
839
838 for r in range(self.Num_Hei):
840 for r in range(self.Num_Hei):
839
841
840 Ze[0,r] = ( ETA[0,r] ) * COFA[0,r][0] * RadarConst * ((r/5000.)**2)
842 Ze[0,r] = ( ETA[0,r] ) * COFA[0,r][0] * RadarConst * ((r/5000.)**2)
841 #Ze[1,r] = ( ETA[1,r] ) * COFA[1,r][0] * RadarConst * ((r/5000.)**2)
843 #Ze[1,r] = ( ETA[1,r] ) * COFA[1,r][0] * RadarConst * ((r/5000.)**2)
842
844
843 return Ze
845 return Ze
844
846
845 # def GetRadarConstant(self):
847 # def GetRadarConstant(self):
846 #
848 #
847 # """
849 # """
848 # Constants:
850 # Constants:
849 #
851 #
850 # Pt: Transmission Power dB 5kW 5000
852 # Pt: Transmission Power dB 5kW 5000
851 # Gt: Transmission Gain dB 24.7 dB 295.1209
853 # Gt: Transmission Gain dB 24.7 dB 295.1209
852 # Gr: Reception Gain dB 18.5 dB 70.7945
854 # Gr: Reception Gain dB 18.5 dB 70.7945
853 # Lambda: Wavelenght m 0.6741 m 0.6741
855 # Lambda: Wavelenght m 0.6741 m 0.6741
854 # aL: Attenuation loses dB 4dB 2.5118
856 # aL: Attenuation loses dB 4dB 2.5118
855 # tauW: Width of transmission pulse s 4us 4e-6
857 # tauW: Width of transmission pulse s 4us 4e-6
856 # ThetaT: Transmission antenna bean angle rad 0.1656317 rad 0.1656317
858 # ThetaT: Transmission antenna bean angle rad 0.1656317 rad 0.1656317
857 # ThetaR: Reception antenna beam angle rad 0.36774087 rad 0.36774087
859 # ThetaR: Reception antenna beam angle rad 0.36774087 rad 0.36774087
858 #
860 #
859 # """
861 # """
860 #
862 #
861 # Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
863 # Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
862 # Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * TauW * numpy.pi * ThetaT * TheraR)
864 # Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * TauW * numpy.pi * ThetaT * TheraR)
863 # RadarConstant = Numerator / Denominator
865 # RadarConstant = Numerator / Denominator
864 #
866 #
865 # return RadarConstant
867 # return RadarConstant
866
868
867
869
868
870
869 class FullSpectralAnalysis(Operation):
871 class FullSpectralAnalysis(Operation):
870
872
871 """
873 """
872 Function that implements Full Spectral Analysis technique.
874 Function that implements Full Spectral Analysis technique.
873
875
874 Input:
876 Input:
875 self.dataOut.data_pre : SelfSpectra and CrossSpectra data
877 self.dataOut.data_pre : SelfSpectra and CrossSpectra data
876 self.dataOut.groupList : Pairlist of channels
878 self.dataOut.groupList : Pairlist of channels
877 self.dataOut.ChanDist : Physical distance between receivers
879 self.dataOut.ChanDist : Physical distance between receivers
878
880
879
881
880 Output:
882 Output:
881
883
882 self.dataOut.data_output : Zonal wind, Meridional wind, and Vertical wind
884 self.dataOut.data_output : Zonal wind, Meridional wind, and Vertical wind
883
885
884
886
885 Parameters affected: Winds, height range, SNR
887 Parameters affected: Winds, height range, SNR
886
888
887 """
889 """
888 def run(self, dataOut, Xi01=None, Xi02=None, Xi12=None, Eta01=None, Eta02=None, Eta12=None, SNRdBlimit=-30,
890 def run(self, dataOut, Xi01=None, Xi02=None, Xi12=None, Eta01=None, Eta02=None, Eta12=None, SNRdBlimit=-30,
889 minheight=None, maxheight=None, NegativeLimit=None, PositiveLimit=None):
891 minheight=None, maxheight=None, NegativeLimit=None, PositiveLimit=None):
890
892
891 spc = dataOut.data_pre[0].copy()
893 spc = dataOut.data_pre[0].copy()
892 cspc = dataOut.data_pre[1]
894 cspc = dataOut.data_pre[1]
893 nHeights = spc.shape[2]
895 nHeights = spc.shape[2]
894
896
895 # first_height = 0.75 #km (ref: data header 20170822)
897 # first_height = 0.75 #km (ref: data header 20170822)
896 # resolution_height = 0.075 #km
898 # resolution_height = 0.075 #km
897 '''
899 '''
898 finding height range. check this when radar parameters are changed!
900 finding height range. check this when radar parameters are changed!
899 '''
901 '''
900 if maxheight is not None:
902 if maxheight is not None:
901 # range_max = math.ceil((maxheight - first_height) / resolution_height) # theoretical
903 # range_max = math.ceil((maxheight - first_height) / resolution_height) # theoretical
902 range_max = math.ceil(13.26 * maxheight - 3) # empirical, works better
904 range_max = math.ceil(13.26 * maxheight - 3) # empirical, works better
903 else:
905 else:
904 range_max = nHeights
906 range_max = nHeights
905 if minheight is not None:
907 if minheight is not None:
906 # range_min = int((minheight - first_height) / resolution_height) # theoretical
908 # range_min = int((minheight - first_height) / resolution_height) # theoretical
907 range_min = int(13.26 * minheight - 5) # empirical, works better
909 range_min = int(13.26 * minheight - 5) # empirical, works better
908 if range_min < 0:
910 if range_min < 0:
909 range_min = 0
911 range_min = 0
910 else:
912 else:
911 range_min = 0
913 range_min = 0
912
914
913 pairsList = dataOut.groupList
915 pairsList = dataOut.groupList
914 if dataOut.ChanDist is not None :
916 if dataOut.ChanDist is not None :
915 ChanDist = dataOut.ChanDist
917 ChanDist = dataOut.ChanDist
916 else:
918 else:
917 ChanDist = numpy.array([[Xi01, Eta01],[Xi02,Eta02],[Xi12,Eta12]])
919 ChanDist = numpy.array([[Xi01, Eta01],[Xi02,Eta02],[Xi12,Eta12]])
918
920
919 # 4 variables: zonal, meridional, vertical, and average SNR
921 # 4 variables: zonal, meridional, vertical, and average SNR
920 data_param = numpy.zeros([4,nHeights]) * numpy.NaN
922 data_param = numpy.zeros([4,nHeights]) * numpy.NaN
921 velocityX = numpy.zeros([nHeights]) * numpy.NaN
923 velocityX = numpy.zeros([nHeights]) * numpy.NaN
922 velocityY = numpy.zeros([nHeights]) * numpy.NaN
924 velocityY = numpy.zeros([nHeights]) * numpy.NaN
923 velocityZ = numpy.zeros([nHeights]) * numpy.NaN
925 velocityZ = numpy.zeros([nHeights]) * numpy.NaN
924
926
925 dbSNR = 10*numpy.log10(numpy.average(dataOut.data_snr,0))
927 dbSNR = 10*numpy.log10(numpy.average(dataOut.data_snr,0))
926
928
927 '''***********************************************WIND ESTIMATION**************************************'''
929 '''***********************************************WIND ESTIMATION**************************************'''
928 for Height in range(nHeights):
930 for Height in range(nHeights):
929
931
930 if Height >= range_min and Height < range_max:
932 if Height >= range_min and Height < range_max:
931 # error_code will be useful in future analysis
933 # error_code will be useful in future analysis
932 [Vzon,Vmer,Vver, error_code] = self.WindEstimation(spc[:,:,Height], cspc[:,:,Height], pairsList,
934 [Vzon,Vmer,Vver, error_code] = self.WindEstimation(spc[:,:,Height], cspc[:,:,Height], pairsList,
933 ChanDist, Height, dataOut.noise, dataOut.spc_range, dbSNR[Height], SNRdBlimit, NegativeLimit, PositiveLimit,dataOut.frequency)
935 ChanDist, Height, dataOut.noise, dataOut.spc_range, dbSNR[Height], SNRdBlimit, NegativeLimit, PositiveLimit,dataOut.frequency)
934
936
935 if abs(Vzon) < 100. and abs(Vmer) < 100.:
937 if abs(Vzon) < 100. and abs(Vmer) < 100.:
936 velocityX[Height] = Vzon
938 velocityX[Height] = Vzon
937 velocityY[Height] = -Vmer
939 velocityY[Height] = -Vmer
938 velocityZ[Height] = Vver
940 velocityZ[Height] = Vver
939
941
940 # Censoring data with SNR threshold
942 # Censoring data with SNR threshold
941 dbSNR [dbSNR < SNRdBlimit] = numpy.NaN
943 dbSNR [dbSNR < SNRdBlimit] = numpy.NaN
942
944
943 data_param[0] = velocityX
945 data_param[0] = velocityX
944 data_param[1] = velocityY
946 data_param[1] = velocityY
945 data_param[2] = velocityZ
947 data_param[2] = velocityZ
946 data_param[3] = dbSNR
948 data_param[3] = dbSNR
947 dataOut.data_param = data_param
949 dataOut.data_param = data_param
948 return dataOut
950 return dataOut
949
951
950 def moving_average(self,x, N=2):
952 def moving_average(self,x, N=2):
951 """ convolution for smoothenig data. note that last N-1 values are convolution with zeroes """
953 """ convolution for smoothenig data. note that last N-1 values are convolution with zeroes """
952 return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):]
954 return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):]
953
955
954 def gaus(self,xSamples,Amp,Mu,Sigma):
956 def gaus(self,xSamples,Amp,Mu,Sigma):
955 return Amp * numpy.exp(-0.5*((xSamples - Mu)/Sigma)**2)
957 return Amp * numpy.exp(-0.5*((xSamples - Mu)/Sigma)**2)
956
958
957 def Moments(self, ySamples, xSamples):
959 def Moments(self, ySamples, xSamples):
958 Power = numpy.nanmean(ySamples) # Power, 0th Moment
960 Power = numpy.nanmean(ySamples) # Power, 0th Moment
959 yNorm = ySamples / numpy.nansum(ySamples)
961 yNorm = ySamples / numpy.nansum(ySamples)
960 RadVel = numpy.nansum(xSamples * yNorm) # Radial Velocity, 1st Moment
962 RadVel = numpy.nansum(xSamples * yNorm) # Radial Velocity, 1st Moment
961 Sigma2 = numpy.nansum(yNorm * (xSamples - RadVel)**2) # Spectral Width, 2nd Moment
963 Sigma2 = numpy.nansum(yNorm * (xSamples - RadVel)**2) # Spectral Width, 2nd Moment
962 StdDev = numpy.sqrt(numpy.abs(Sigma2)) # Desv. Estandar, Ancho espectral
964 StdDev = numpy.sqrt(numpy.abs(Sigma2)) # Desv. Estandar, Ancho espectral
963 return numpy.array([Power,RadVel,StdDev])
965 return numpy.array([Power,RadVel,StdDev])
964
966
965 def StopWindEstimation(self, error_code):
967 def StopWindEstimation(self, error_code):
966 Vzon = numpy.NaN
968 Vzon = numpy.NaN
967 Vmer = numpy.NaN
969 Vmer = numpy.NaN
968 Vver = numpy.NaN
970 Vver = numpy.NaN
969 return Vzon, Vmer, Vver, error_code
971 return Vzon, Vmer, Vver, error_code
970
972
971 def AntiAliasing(self, interval, maxstep):
973 def AntiAliasing(self, interval, maxstep):
972 """
974 """
973 function to prevent errors from aliased values when computing phaseslope
975 function to prevent errors from aliased values when computing phaseslope
974 """
976 """
975 antialiased = numpy.zeros(len(interval))
977 antialiased = numpy.zeros(len(interval))
976 copyinterval = interval.copy()
978 copyinterval = interval.copy()
977
979
978 antialiased[0] = copyinterval[0]
980 antialiased[0] = copyinterval[0]
979
981
980 for i in range(1,len(antialiased)):
982 for i in range(1,len(antialiased)):
981 step = interval[i] - interval[i-1]
983 step = interval[i] - interval[i-1]
982 if step > maxstep:
984 if step > maxstep:
983 copyinterval -= 2*numpy.pi
985 copyinterval -= 2*numpy.pi
984 antialiased[i] = copyinterval[i]
986 antialiased[i] = copyinterval[i]
985 elif step < maxstep*(-1):
987 elif step < maxstep*(-1):
986 copyinterval += 2*numpy.pi
988 copyinterval += 2*numpy.pi
987 antialiased[i] = copyinterval[i]
989 antialiased[i] = copyinterval[i]
988 else:
990 else:
989 antialiased[i] = copyinterval[i].copy()
991 antialiased[i] = copyinterval[i].copy()
990
992
991 return antialiased
993 return antialiased
992
994
993 def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, AbbsisaRange, dbSNR, SNRlimit, NegativeLimit, PositiveLimit, radfreq):
995 def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, AbbsisaRange, dbSNR, SNRlimit, NegativeLimit, PositiveLimit, radfreq):
994 """
996 """
995 Function that Calculates Zonal, Meridional and Vertical wind velocities.
997 Function that Calculates Zonal, Meridional and Vertical wind velocities.
996 Initial Version by E. Bocanegra updated by J. Zibell until Nov. 2019.
998 Initial Version by E. Bocanegra updated by J. Zibell until Nov. 2019.
997
999
998 Input:
1000 Input:
999 spc, cspc : self spectra and cross spectra data. In Briggs notation something like S_i*(S_i)_conj, (S_j)_conj respectively.
1001 spc, cspc : self spectra and cross spectra data. In Briggs notation something like S_i*(S_i)_conj, (S_j)_conj respectively.
1000 pairsList : Pairlist of channels
1002 pairsList : Pairlist of channels
1001 ChanDist : array of xi_ij and eta_ij
1003 ChanDist : array of xi_ij and eta_ij
1002 Height : height at which data is processed
1004 Height : height at which data is processed
1003 noise : noise in [channels] format for specific height
1005 noise : noise in [channels] format for specific height
1004 Abbsisarange : range of the frequencies or velocities
1006 Abbsisarange : range of the frequencies or velocities
1005 dbSNR, SNRlimit : signal to noise ratio in db, lower limit
1007 dbSNR, SNRlimit : signal to noise ratio in db, lower limit
1006
1008
1007 Output:
1009 Output:
1008 Vzon, Vmer, Vver : wind velocities
1010 Vzon, Vmer, Vver : wind velocities
1009 error_code : int that states where code is terminated
1011 error_code : int that states where code is terminated
1010
1012
1011 0 : no error detected
1013 0 : no error detected
1012 1 : Gaussian of mean spc exceeds widthlimit
1014 1 : Gaussian of mean spc exceeds widthlimit
1013 2 : no Gaussian of mean spc found
1015 2 : no Gaussian of mean spc found
1014 3 : SNR to low or velocity to high -> prec. e.g.
1016 3 : SNR to low or velocity to high -> prec. e.g.
1015 4 : at least one Gaussian of cspc exceeds widthlimit
1017 4 : at least one Gaussian of cspc exceeds widthlimit
1016 5 : zero out of three cspc Gaussian fits converged
1018 5 : zero out of three cspc Gaussian fits converged
1017 6 : phase slope fit could not be found
1019 6 : phase slope fit could not be found
1018 7 : arrays used to fit phase have different length
1020 7 : arrays used to fit phase have different length
1019 8 : frequency range is either too short (len <= 5) or very long (> 30% of cspc)
1021 8 : frequency range is either too short (len <= 5) or very long (> 30% of cspc)
1020
1022
1021 """
1023 """
1022
1024
1023 error_code = 0
1025 error_code = 0
1024
1026
1025 nChan = spc.shape[0]
1027 nChan = spc.shape[0]
1026 nProf = spc.shape[1]
1028 nProf = spc.shape[1]
1027 nPair = cspc.shape[0]
1029 nPair = cspc.shape[0]
1028
1030
1029 SPC_Samples = numpy.zeros([nChan, nProf]) # for normalized spc values for one height
1031 SPC_Samples = numpy.zeros([nChan, nProf]) # for normalized spc values for one height
1030 CSPC_Samples = numpy.zeros([nPair, nProf], dtype=numpy.complex_) # for normalized cspc values
1032 CSPC_Samples = numpy.zeros([nPair, nProf], dtype=numpy.complex_) # for normalized cspc values
1031 phase = numpy.zeros([nPair, nProf]) # phase between channels
1033 phase = numpy.zeros([nPair, nProf]) # phase between channels
1032 PhaseSlope = numpy.zeros(nPair) # slope of the phases, channelwise
1034 PhaseSlope = numpy.zeros(nPair) # slope of the phases, channelwise
1033 PhaseInter = numpy.zeros(nPair) # intercept to the slope of the phases, channelwise
1035 PhaseInter = numpy.zeros(nPair) # intercept to the slope of the phases, channelwise
1034 xFrec = AbbsisaRange[0][:-1] # frequency range
1036 xFrec = AbbsisaRange[0][:-1] # frequency range
1035 xVel = AbbsisaRange[2][:-1] # velocity range
1037 xVel = AbbsisaRange[2][:-1] # velocity range
1036 xSamples = xFrec # the frequency range is taken
1038 xSamples = xFrec # the frequency range is taken
1037 delta_x = xSamples[1] - xSamples[0] # delta_f or delta_x
1039 delta_x = xSamples[1] - xSamples[0] # delta_f or delta_x
1038
1040
1039 # only consider velocities with in NegativeLimit and PositiveLimit
1041 # only consider velocities with in NegativeLimit and PositiveLimit
1040 if (NegativeLimit is None):
1042 if (NegativeLimit is None):
1041 NegativeLimit = numpy.min(xVel)
1043 NegativeLimit = numpy.min(xVel)
1042 if (PositiveLimit is None):
1044 if (PositiveLimit is None):
1043 PositiveLimit = numpy.max(xVel)
1045 PositiveLimit = numpy.max(xVel)
1044 xvalid = numpy.where((xVel > NegativeLimit) & (xVel < PositiveLimit))
1046 xvalid = numpy.where((xVel > NegativeLimit) & (xVel < PositiveLimit))
1045 xSamples_zoom = xSamples[xvalid]
1047 xSamples_zoom = xSamples[xvalid]
1046
1048
1047 '''Getting Eij and Nij'''
1049 '''Getting Eij and Nij'''
1048 Xi01, Xi02, Xi12 = ChanDist[:,0]
1050 Xi01, Xi02, Xi12 = ChanDist[:,0]
1049 Eta01, Eta02, Eta12 = ChanDist[:,1]
1051 Eta01, Eta02, Eta12 = ChanDist[:,1]
1050
1052
1051 # spwd limit - updated by D. ScipiΓ³n 30.03.2021
1053 # spwd limit - updated by D. ScipiΓ³n 30.03.2021
1052 widthlimit = 10
1054 widthlimit = 10
1053 '''************************* SPC is normalized ********************************'''
1055 '''************************* SPC is normalized ********************************'''
1054 spc_norm = spc.copy()
1056 spc_norm = spc.copy()
1055 # For each channel
1057 # For each channel
1056 for i in range(nChan):
1058 for i in range(nChan):
1057 spc_sub = spc_norm[i,:] - noise[i] # only the signal power
1059 spc_sub = spc_norm[i,:] - noise[i] # only the signal power
1058 SPC_Samples[i] = spc_sub / (numpy.nansum(spc_sub) * delta_x)
1060 SPC_Samples[i] = spc_sub / (numpy.nansum(spc_sub) * delta_x)
1059
1061
1060 '''********************** FITTING MEAN SPC GAUSSIAN **********************'''
1062 '''********************** FITTING MEAN SPC GAUSSIAN **********************'''
1061
1063
1062 """ the gaussian of the mean: first subtract noise, then normalize. this is legal because
1064 """ the gaussian of the mean: first subtract noise, then normalize. this is legal because
1063 you only fit the curve and don't need the absolute value of height for calculation,
1065 you only fit the curve and don't need the absolute value of height for calculation,
1064 only for estimation of width. for normalization of cross spectra, you need initial,
1066 only for estimation of width. for normalization of cross spectra, you need initial,
1065 unnormalized self-spectra With noise.
1067 unnormalized self-spectra With noise.
1066
1068
1067 Technically, you don't even need to normalize the self-spectra, as you only need the
1069 Technically, you don't even need to normalize the self-spectra, as you only need the
1068 width of the peak. However, it was left this way. Note that the normalization has a flaw:
1070 width of the peak. However, it was left this way. Note that the normalization has a flaw:
1069 due to subtraction of the noise, some values are below zero. Raw "spc" values should be
1071 due to subtraction of the noise, some values are below zero. Raw "spc" values should be
1070 >= 0, as it is the modulus squared of the signals (complex * it's conjugate)
1072 >= 0, as it is the modulus squared of the signals (complex * it's conjugate)
1071 """
1073 """
1072 # initial conditions
1074 # initial conditions
1073 popt = [1e-10,0,1e-10]
1075 popt = [1e-10,0,1e-10]
1074 # Spectra average
1076 # Spectra average
1075 SPCMean = numpy.average(SPC_Samples,0)
1077 SPCMean = numpy.average(SPC_Samples,0)
1076 # Moments in frequency
1078 # Moments in frequency
1077 SPCMoments = self.Moments(SPCMean[xvalid], xSamples_zoom)
1079 SPCMoments = self.Moments(SPCMean[xvalid], xSamples_zoom)
1078
1080
1079 # Gauss Fit SPC in frequency domain
1081 # Gauss Fit SPC in frequency domain
1080 if dbSNR > SNRlimit: # only if SNR > SNRth
1082 if dbSNR > SNRlimit: # only if SNR > SNRth
1081 try:
1083 try:
1082 popt,pcov = curve_fit(self.gaus,xSamples_zoom,SPCMean[xvalid],p0=SPCMoments)
1084 popt,pcov = curve_fit(self.gaus,xSamples_zoom,SPCMean[xvalid],p0=SPCMoments)
1083 if popt[2] <= 0 or popt[2] > widthlimit: # CONDITION
1085 if popt[2] <= 0 or popt[2] > widthlimit: # CONDITION
1084 return self.StopWindEstimation(error_code = 1)
1086 return self.StopWindEstimation(error_code = 1)
1085 FitGauss = self.gaus(xSamples_zoom,*popt)
1087 FitGauss = self.gaus(xSamples_zoom,*popt)
1086 except :#RuntimeError:
1088 except :#RuntimeError:
1087 return self.StopWindEstimation(error_code = 2)
1089 return self.StopWindEstimation(error_code = 2)
1088 else:
1090 else:
1089 return self.StopWindEstimation(error_code = 3)
1091 return self.StopWindEstimation(error_code = 3)
1090
1092
1091 '''***************************** CSPC Normalization *************************
1093 '''***************************** CSPC Normalization *************************
1092 The Spc spectra are used to normalize the crossspectra. Peaks from precipitation
1094 The Spc spectra are used to normalize the crossspectra. Peaks from precipitation
1093 influence the norm which is not desired. First, a range is identified where the
1095 influence the norm which is not desired. First, a range is identified where the
1094 wind peak is estimated -> sum_wind is sum of those frequencies. Next, the area
1096 wind peak is estimated -> sum_wind is sum of those frequencies. Next, the area
1095 around it gets cut off and values replaced by mean determined by the boundary
1097 around it gets cut off and values replaced by mean determined by the boundary
1096 data -> sum_noise (spc is not normalized here, thats why the noise is important)
1098 data -> sum_noise (spc is not normalized here, thats why the noise is important)
1097
1099
1098 The sums are then added and multiplied by range/datapoints, because you need
1100 The sums are then added and multiplied by range/datapoints, because you need
1099 an integral and not a sum for normalization.
1101 an integral and not a sum for normalization.
1100
1102
1101 A norm is found according to Briggs 92.
1103 A norm is found according to Briggs 92.
1102 '''
1104 '''
1103 # for each pair
1105 # for each pair
1104 for i in range(nPair):
1106 for i in range(nPair):
1105 cspc_norm = cspc[i,:].copy()
1107 cspc_norm = cspc[i,:].copy()
1106 chan_index0 = pairsList[i][0]
1108 chan_index0 = pairsList[i][0]
1107 chan_index1 = pairsList[i][1]
1109 chan_index1 = pairsList[i][1]
1108 CSPC_Samples[i] = cspc_norm / (numpy.sqrt(numpy.nansum(spc_norm[chan_index0])*numpy.nansum(spc_norm[chan_index1])) * delta_x)
1110 CSPC_Samples[i] = cspc_norm / (numpy.sqrt(numpy.nansum(spc_norm[chan_index0])*numpy.nansum(spc_norm[chan_index1])) * delta_x)
1109 phase[i] = numpy.arctan2(CSPC_Samples[i].imag, CSPC_Samples[i].real)
1111 phase[i] = numpy.arctan2(CSPC_Samples[i].imag, CSPC_Samples[i].real)
1110
1112
1111 CSPCmoments = numpy.vstack([self.Moments(numpy.abs(CSPC_Samples[0,xvalid]), xSamples_zoom),
1113 CSPCmoments = numpy.vstack([self.Moments(numpy.abs(CSPC_Samples[0,xvalid]), xSamples_zoom),
1112 self.Moments(numpy.abs(CSPC_Samples[1,xvalid]), xSamples_zoom),
1114 self.Moments(numpy.abs(CSPC_Samples[1,xvalid]), xSamples_zoom),
1113 self.Moments(numpy.abs(CSPC_Samples[2,xvalid]), xSamples_zoom)])
1115 self.Moments(numpy.abs(CSPC_Samples[2,xvalid]), xSamples_zoom)])
1114
1116
1115 popt01, popt02, popt12 = [1e-10,0,1e-10], [1e-10,0,1e-10] ,[1e-10,0,1e-10]
1117 popt01, popt02, popt12 = [1e-10,0,1e-10], [1e-10,0,1e-10] ,[1e-10,0,1e-10]
1116 FitGauss01, FitGauss02, FitGauss12 = numpy.zeros(len(xSamples)), numpy.zeros(len(xSamples)), numpy.zeros(len(xSamples))
1118 FitGauss01, FitGauss02, FitGauss12 = numpy.zeros(len(xSamples)), numpy.zeros(len(xSamples)), numpy.zeros(len(xSamples))
1117
1119
1118 '''*******************************FIT GAUSS CSPC************************************'''
1120 '''*******************************FIT GAUSS CSPC************************************'''
1119 try:
1121 try:
1120 popt01,pcov = curve_fit(self.gaus,xSamples_zoom,numpy.abs(CSPC_Samples[0][xvalid]),p0=CSPCmoments[0])
1122 popt01,pcov = curve_fit(self.gaus,xSamples_zoom,numpy.abs(CSPC_Samples[0][xvalid]),p0=CSPCmoments[0])
1121 if popt01[2] > widthlimit: # CONDITION
1123 if popt01[2] > widthlimit: # CONDITION
1122 return self.StopWindEstimation(error_code = 4)
1124 return self.StopWindEstimation(error_code = 4)
1123 popt02,pcov = curve_fit(self.gaus,xSamples_zoom,numpy.abs(CSPC_Samples[1][xvalid]),p0=CSPCmoments[1])
1125 popt02,pcov = curve_fit(self.gaus,xSamples_zoom,numpy.abs(CSPC_Samples[1][xvalid]),p0=CSPCmoments[1])
1124 if popt02[2] > widthlimit: # CONDITION
1126 if popt02[2] > widthlimit: # CONDITION
1125 return self.StopWindEstimation(error_code = 4)
1127 return self.StopWindEstimation(error_code = 4)
1126 popt12,pcov = curve_fit(self.gaus,xSamples_zoom,numpy.abs(CSPC_Samples[2][xvalid]),p0=CSPCmoments[2])
1128 popt12,pcov = curve_fit(self.gaus,xSamples_zoom,numpy.abs(CSPC_Samples[2][xvalid]),p0=CSPCmoments[2])
1127 if popt12[2] > widthlimit: # CONDITION
1129 if popt12[2] > widthlimit: # CONDITION
1128 return self.StopWindEstimation(error_code = 4)
1130 return self.StopWindEstimation(error_code = 4)
1129
1131
1130 FitGauss01 = self.gaus(xSamples_zoom, *popt01)
1132 FitGauss01 = self.gaus(xSamples_zoom, *popt01)
1131 FitGauss02 = self.gaus(xSamples_zoom, *popt02)
1133 FitGauss02 = self.gaus(xSamples_zoom, *popt02)
1132 FitGauss12 = self.gaus(xSamples_zoom, *popt12)
1134 FitGauss12 = self.gaus(xSamples_zoom, *popt12)
1133 except:
1135 except:
1134 return self.StopWindEstimation(error_code = 5)
1136 return self.StopWindEstimation(error_code = 5)
1135
1137
1136
1138
1137 '''************* Getting Fij ***************'''
1139 '''************* Getting Fij ***************'''
1138 # x-axis point of the gaussian where the center is located from GaussFit of spectra
1140 # x-axis point of the gaussian where the center is located from GaussFit of spectra
1139 GaussCenter = popt[1]
1141 GaussCenter = popt[1]
1140 ClosestCenter = xSamples_zoom[numpy.abs(xSamples_zoom-GaussCenter).argmin()]
1142 ClosestCenter = xSamples_zoom[numpy.abs(xSamples_zoom-GaussCenter).argmin()]
1141 PointGauCenter = numpy.where(xSamples_zoom==ClosestCenter)[0][0]
1143 PointGauCenter = numpy.where(xSamples_zoom==ClosestCenter)[0][0]
1142
1144
1143 # Point where e^-1 is located in the gaussian
1145 # Point where e^-1 is located in the gaussian
1144 PeMinus1 = numpy.max(FitGauss) * numpy.exp(-1)
1146 PeMinus1 = numpy.max(FitGauss) * numpy.exp(-1)
1145 FijClosest = FitGauss[numpy.abs(FitGauss-PeMinus1).argmin()] # The closest point to"Peminus1" in "FitGauss"
1147 FijClosest = FitGauss[numpy.abs(FitGauss-PeMinus1).argmin()] # The closest point to"Peminus1" in "FitGauss"
1146 PointFij = numpy.where(FitGauss==FijClosest)[0][0]
1148 PointFij = numpy.where(FitGauss==FijClosest)[0][0]
1147 Fij = numpy.abs(xSamples_zoom[PointFij] - xSamples_zoom[PointGauCenter])
1149 Fij = numpy.abs(xSamples_zoom[PointFij] - xSamples_zoom[PointGauCenter])
1148
1150
1149 '''********** Taking frequency ranges from mean SPCs **********'''
1151 '''********** Taking frequency ranges from mean SPCs **********'''
1150 GauWidth = popt[2] * 3/2 # Bandwidth of Gau01
1152 GauWidth = popt[2] * 3/2 # Bandwidth of Gau01
1151 Range = numpy.empty(2)
1153 Range = numpy.empty(2)
1152 Range[0] = GaussCenter - GauWidth
1154 Range[0] = GaussCenter - GauWidth
1153 Range[1] = GaussCenter + GauWidth
1155 Range[1] = GaussCenter + GauWidth
1154 # Point in x-axis where the bandwidth is located (min:max)
1156 # Point in x-axis where the bandwidth is located (min:max)
1155 ClosRangeMin = xSamples_zoom[numpy.abs(xSamples_zoom-Range[0]).argmin()]
1157 ClosRangeMin = xSamples_zoom[numpy.abs(xSamples_zoom-Range[0]).argmin()]
1156 ClosRangeMax = xSamples_zoom[numpy.abs(xSamples_zoom-Range[1]).argmin()]
1158 ClosRangeMax = xSamples_zoom[numpy.abs(xSamples_zoom-Range[1]).argmin()]
1157 PointRangeMin = numpy.where(xSamples_zoom==ClosRangeMin)[0][0]
1159 PointRangeMin = numpy.where(xSamples_zoom==ClosRangeMin)[0][0]
1158 PointRangeMax = numpy.where(xSamples_zoom==ClosRangeMax)[0][0]
1160 PointRangeMax = numpy.where(xSamples_zoom==ClosRangeMax)[0][0]
1159 Range = numpy.array([ PointRangeMin, PointRangeMax ])
1161 Range = numpy.array([ PointRangeMin, PointRangeMax ])
1160 FrecRange = xSamples_zoom[ Range[0] : Range[1] ]
1162 FrecRange = xSamples_zoom[ Range[0] : Range[1] ]
1161
1163
1162 '''************************** Getting Phase Slope ***************************'''
1164 '''************************** Getting Phase Slope ***************************'''
1163 for i in range(nPair):
1165 for i in range(nPair):
1164 if len(FrecRange) > 5:
1166 if len(FrecRange) > 5:
1165 PhaseRange = phase[i, xvalid[0][Range[0]:Range[1]]].copy()
1167 PhaseRange = phase[i, xvalid[0][Range[0]:Range[1]]].copy()
1166 mask = ~numpy.isnan(FrecRange) & ~numpy.isnan(PhaseRange)
1168 mask = ~numpy.isnan(FrecRange) & ~numpy.isnan(PhaseRange)
1167 if len(FrecRange) == len(PhaseRange):
1169 if len(FrecRange) == len(PhaseRange):
1168 try:
1170 try:
1169 slope, intercept, _, _, _ = stats.linregress(FrecRange[mask], self.AntiAliasing(PhaseRange[mask], 4.5))
1171 slope, intercept, _, _, _ = stats.linregress(FrecRange[mask], self.AntiAliasing(PhaseRange[mask], 4.5))
1170 PhaseSlope[i] = slope
1172 PhaseSlope[i] = slope
1171 PhaseInter[i] = intercept
1173 PhaseInter[i] = intercept
1172 except:
1174 except:
1173 return self.StopWindEstimation(error_code = 6)
1175 return self.StopWindEstimation(error_code = 6)
1174 else:
1176 else:
1175 return self.StopWindEstimation(error_code = 7)
1177 return self.StopWindEstimation(error_code = 7)
1176 else:
1178 else:
1177 return self.StopWindEstimation(error_code = 8)
1179 return self.StopWindEstimation(error_code = 8)
1178
1180
1179 '''*** Constants A-H correspond to the convention as in Briggs and Vincent 1992 ***'''
1181 '''*** Constants A-H correspond to the convention as in Briggs and Vincent 1992 ***'''
1180
1182
1181 '''Getting constant C'''
1183 '''Getting constant C'''
1182 cC=(Fij*numpy.pi)**2
1184 cC=(Fij*numpy.pi)**2
1183
1185
1184 '''****** Getting constants F and G ******'''
1186 '''****** Getting constants F and G ******'''
1185 MijEijNij = numpy.array([[Xi02,Eta02], [Xi12,Eta12]])
1187 MijEijNij = numpy.array([[Xi02,Eta02], [Xi12,Eta12]])
1186 # MijEijNij = numpy.array([[Xi01,Eta01], [Xi02,Eta02], [Xi12,Eta12]])
1188 # MijEijNij = numpy.array([[Xi01,Eta01], [Xi02,Eta02], [Xi12,Eta12]])
1187 # MijResult0 = (-PhaseSlope[0] * cC) / (2*numpy.pi)
1189 # MijResult0 = (-PhaseSlope[0] * cC) / (2*numpy.pi)
1188 MijResult1 = (-PhaseSlope[1] * cC) / (2*numpy.pi)
1190 MijResult1 = (-PhaseSlope[1] * cC) / (2*numpy.pi)
1189 MijResult2 = (-PhaseSlope[2] * cC) / (2*numpy.pi)
1191 MijResult2 = (-PhaseSlope[2] * cC) / (2*numpy.pi)
1190 # MijResults = numpy.array([MijResult0, MijResult1, MijResult2])
1192 # MijResults = numpy.array([MijResult0, MijResult1, MijResult2])
1191 MijResults = numpy.array([MijResult1, MijResult2])
1193 MijResults = numpy.array([MijResult1, MijResult2])
1192 (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults)
1194 (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults)
1193
1195
1194 '''****** Getting constants A, B and H ******'''
1196 '''****** Getting constants A, B and H ******'''
1195 W01 = numpy.nanmax( FitGauss01 )
1197 W01 = numpy.nanmax( FitGauss01 )
1196 W02 = numpy.nanmax( FitGauss02 )
1198 W02 = numpy.nanmax( FitGauss02 )
1197 W12 = numpy.nanmax( FitGauss12 )
1199 W12 = numpy.nanmax( FitGauss12 )
1198
1200
1199 WijResult01 = ((cF * Xi01 + cG * Eta01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi / cC))
1201 WijResult01 = ((cF * Xi01 + cG * Eta01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi / cC))
1200 WijResult02 = ((cF * Xi02 + cG * Eta02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi / cC))
1202 WijResult02 = ((cF * Xi02 + cG * Eta02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi / cC))
1201 WijResult12 = ((cF * Xi12 + cG * Eta12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi / cC))
1203 WijResult12 = ((cF * Xi12 + cG * Eta12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi / cC))
1202 WijResults = numpy.array([WijResult01, WijResult02, WijResult12])
1204 WijResults = numpy.array([WijResult01, WijResult02, WijResult12])
1203
1205
1204 WijEijNij = numpy.array([ [Xi01**2, Eta01**2, 2*Xi01*Eta01] , [Xi02**2, Eta02**2, 2*Xi02*Eta02] , [Xi12**2, Eta12**2, 2*Xi12*Eta12] ])
1206 WijEijNij = numpy.array([ [Xi01**2, Eta01**2, 2*Xi01*Eta01] , [Xi02**2, Eta02**2, 2*Xi02*Eta02] , [Xi12**2, Eta12**2, 2*Xi12*Eta12] ])
1205 (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults)
1207 (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults)
1206
1208
1207 VxVy = numpy.array([[cA,cH],[cH,cB]])
1209 VxVy = numpy.array([[cA,cH],[cH,cB]])
1208 VxVyResults = numpy.array([-cF,-cG])
1210 VxVyResults = numpy.array([-cF,-cG])
1209 (Vmer,Vzon) = numpy.linalg.solve(VxVy, VxVyResults)
1211 (Vmer,Vzon) = numpy.linalg.solve(VxVy, VxVyResults)
1210 Vver = -SPCMoments[1]*SPEED_OF_LIGHT/(2*radfreq)
1212 Vver = -SPCMoments[1]*SPEED_OF_LIGHT/(2*radfreq)
1211 error_code = 0
1213 error_code = 0
1212
1214
1213 return Vzon, Vmer, Vver, error_code
1215 return Vzon, Vmer, Vver, error_code
1214
1216
1215 class SpectralMoments(Operation):
1217 class SpectralMoments(Operation):
1216
1218
1217 '''
1219 '''
1218 Function SpectralMoments()
1220 Function SpectralMoments()
1219
1221
1220 Calculates moments (power, mean, standard deviation) and SNR of the signal
1222 Calculates moments (power, mean, standard deviation) and SNR of the signal
1221
1223
1222 Type of dataIn: Spectra
1224 Type of dataIn: Spectra
1223
1225
1224 Configuration Parameters:
1226 Configuration Parameters:
1225
1227
1226 dirCosx : Cosine director in X axis
1228 dirCosx : Cosine director in X axis
1227 dirCosy : Cosine director in Y axis
1229 dirCosy : Cosine director in Y axis
1228
1230
1229 elevation :
1231 elevation :
1230 azimuth :
1232 azimuth :
1231
1233
1232 Input:
1234 Input:
1233 channelList : simple channel list to select e.g. [2,3,7]
1235 channelList : simple channel list to select e.g. [2,3,7]
1234 self.dataOut.data_pre : Spectral data
1236 self.dataOut.data_pre : Spectral data
1235 self.dataOut.abscissaList : List of frequencies
1237 self.dataOut.abscissaList : List of frequencies
1236 self.dataOut.noise : Noise level per channel
1238 self.dataOut.noise : Noise level per channel
1237
1239
1238 Affected:
1240 Affected:
1239 self.dataOut.moments : Parameters per channel
1241 self.dataOut.moments : Parameters per channel
1240 self.dataOut.data_snr : SNR per channel
1242 self.dataOut.data_snr : SNR per channel
1241
1243
1242 '''
1244 '''
1243
1245
1244 def run(self, dataOut):
1246 def run(self, dataOut):
1245
1247
1246 data = dataOut.data_pre[0]
1248 data = dataOut.data_pre[0]
1247 absc = dataOut.abscissaList[:-1]
1249 absc = dataOut.abscissaList[:-1]
1248 noise = dataOut.noise
1250 noise = dataOut.noise
1249 nChannel = data.shape[0]
1251 nChannel = data.shape[0]
1250 data_param = numpy.zeros((nChannel, 4, data.shape[2]))
1252 data_param = numpy.zeros((nChannel, 4, data.shape[2]))
1251
1253
1252 for ind in range(nChannel):
1254 for ind in range(nChannel):
1253 data_param[ind,:,:] = self.__calculateMoments( data[ind,:,:] , absc , noise[ind] )
1255 data_param[ind,:,:] = self.__calculateMoments( data[ind,:,:] , absc , noise[ind] )
1254
1256
1255 dataOut.moments = data_param[:,1:,:]
1257 dataOut.moments = data_param[:,1:,:]
1256 dataOut.data_snr = data_param[:,0]
1258 dataOut.data_snr = data_param[:,0]
1257 dataOut.data_pow = data_param[:,1]
1259 dataOut.data_pow = data_param[:,1]
1258 dataOut.data_dop = data_param[:,2]
1260 dataOut.data_dop = data_param[:,2]
1259 dataOut.data_width = data_param[:,3]
1261 dataOut.data_width = data_param[:,3]
1260
1262
1261 return dataOut
1263 return dataOut
1262
1264
1263 def __calculateMoments(self, oldspec, oldfreq, n0,
1265 def __calculateMoments(self, oldspec, oldfreq, n0,
1264 nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
1266 nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
1265
1267
1266 if (nicoh is None): nicoh = 1
1268 if (nicoh is None): nicoh = 1
1267 if (graph is None): graph = 0
1269 if (graph is None): graph = 0
1268 if (smooth is None): smooth = 0
1270 if (smooth is None): smooth = 0
1269 elif (self.smooth < 3): smooth = 0
1271 elif (self.smooth < 3): smooth = 0
1270
1272
1271 if (type1 is None): type1 = 0
1273 if (type1 is None): type1 = 0
1272 if (fwindow is None): fwindow = numpy.zeros(oldfreq.size) + 1
1274 if (fwindow is None): fwindow = numpy.zeros(oldfreq.size) + 1
1273 if (snrth is None): snrth = -3
1275 if (snrth is None): snrth = -3
1274 if (dc is None): dc = 0
1276 if (dc is None): dc = 0
1275 if (aliasing is None): aliasing = 0
1277 if (aliasing is None): aliasing = 0
1276 if (oldfd is None): oldfd = 0
1278 if (oldfd is None): oldfd = 0
1277 if (wwauto is None): wwauto = 0
1279 if (wwauto is None): wwauto = 0
1278
1280
1279 if (n0 < 1.e-20): n0 = 1.e-20
1281 if (n0 < 1.e-20): n0 = 1.e-20
1280
1282
1281 freq = oldfreq
1283 freq = oldfreq
1282 vec_power = numpy.zeros(oldspec.shape[1])
1284 vec_power = numpy.zeros(oldspec.shape[1])
1283 vec_fd = numpy.zeros(oldspec.shape[1])
1285 vec_fd = numpy.zeros(oldspec.shape[1])
1284 vec_w = numpy.zeros(oldspec.shape[1])
1286 vec_w = numpy.zeros(oldspec.shape[1])
1285 vec_snr = numpy.zeros(oldspec.shape[1])
1287 vec_snr = numpy.zeros(oldspec.shape[1])
1286
1288
1287 # oldspec = numpy.ma.masked_invalid(oldspec)
1289 # oldspec = numpy.ma.masked_invalid(oldspec)
1288
1290
1289 for ind in range(oldspec.shape[1]):
1291 for ind in range(oldspec.shape[1]):
1290
1292
1291 spec = oldspec[:,ind]
1293 spec = oldspec[:,ind]
1292 aux = spec*fwindow
1294 aux = spec*fwindow
1293 max_spec = aux.max()
1295 max_spec = aux.max()
1294 m = aux.tolist().index(max_spec)
1296 m = aux.tolist().index(max_spec)
1295
1297
1296 # Smooth
1298 # Smooth
1297 if (smooth == 0):
1299 if (smooth == 0):
1298 spec2 = spec
1300 spec2 = spec
1299 else:
1301 else:
1300 spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
1302 spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
1301
1303
1302 # Moments Estimation
1304 # Moments Estimation
1303 bb = spec2[numpy.arange(m,spec2.size)]
1305 bb = spec2[numpy.arange(m,spec2.size)]
1304 bb = (bb<n0).nonzero()
1306 bb = (bb<n0).nonzero()
1305 bb = bb[0]
1307 bb = bb[0]
1306
1308
1307 ss = spec2[numpy.arange(0,m + 1)]
1309 ss = spec2[numpy.arange(0,m + 1)]
1308 ss = (ss<n0).nonzero()
1310 ss = (ss<n0).nonzero()
1309 ss = ss[0]
1311 ss = ss[0]
1310
1312
1311 if (bb.size == 0):
1313 if (bb.size == 0):
1312 bb0 = spec.size - 1 - m
1314 bb0 = spec.size - 1 - m
1313 else:
1315 else:
1314 bb0 = bb[0] - 1
1316 bb0 = bb[0] - 1
1315 if (bb0 < 0):
1317 if (bb0 < 0):
1316 bb0 = 0
1318 bb0 = 0
1317
1319
1318 if (ss.size == 0):
1320 if (ss.size == 0):
1319 ss1 = 1
1321 ss1 = 1
1320 else:
1322 else:
1321 ss1 = max(ss) + 1
1323 ss1 = max(ss) + 1
1322
1324
1323 if (ss1 > m):
1325 if (ss1 > m):
1324 ss1 = m
1326 ss1 = m
1325
1327
1326 valid = numpy.arange(int(m + bb0 - ss1 + 1)) + ss1
1328 valid = numpy.arange(int(m + bb0 - ss1 + 1)) + ss1
1327
1329
1328 signal_power = ((spec2[valid] - n0) * fwindow[valid]).mean() # D. ScipiΓ³n added with correct definition
1330 signal_power = ((spec2[valid] - n0) * fwindow[valid]).mean() # D. ScipiΓ³n added with correct definition
1329 total_power = (spec2[valid] * fwindow[valid]).mean() # D. ScipiΓ³n added with correct definition
1331 total_power = (spec2[valid] * fwindow[valid]).mean() # D. ScipiΓ³n added with correct definition
1330 power = ((spec2[valid] - n0) * fwindow[valid]).sum()
1332 power = ((spec2[valid] - n0) * fwindow[valid]).sum()
1331 fd = ((spec2[valid]- n0)*freq[valid] * fwindow[valid]).sum() / power
1333 fd = ((spec2[valid]- n0)*freq[valid] * fwindow[valid]).sum() / power
1332 w = numpy.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum() / power)
1334 w = numpy.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum() / power)
1333 snr = (spec2.mean()-n0)/n0
1335 snr = (spec2.mean()-n0)/n0
1334 if (snr < 1.e-20) :
1336 if (snr < 1.e-20) :
1335 snr = 1.e-20
1337 snr = 1.e-20
1336
1338
1337 # vec_power[ind] = power #D. ScipiΓ³n replaced with the line below
1339 # vec_power[ind] = power #D. ScipiΓ³n replaced with the line below
1338 vec_power[ind] = total_power
1340 vec_power[ind] = total_power
1339 vec_fd[ind] = fd
1341 vec_fd[ind] = fd
1340 vec_w[ind] = w
1342 vec_w[ind] = w
1341 vec_snr[ind] = snr
1343 vec_snr[ind] = snr
1342
1344
1343 return numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
1345 return numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
1344
1346
1345 #------------------ Get SA Parameters --------------------------
1347 #------------------ Get SA Parameters --------------------------
1346
1348
1347 def GetSAParameters(self):
1349 def GetSAParameters(self):
1348 #SA en frecuencia
1350 #SA en frecuencia
1349 pairslist = self.dataOut.groupList
1351 pairslist = self.dataOut.groupList
1350 num_pairs = len(pairslist)
1352 num_pairs = len(pairslist)
1351
1353
1352 vel = self.dataOut.abscissaList
1354 vel = self.dataOut.abscissaList
1353 spectra = self.dataOut.data_pre
1355 spectra = self.dataOut.data_pre
1354 cspectra = self.dataIn.data_cspc
1356 cspectra = self.dataIn.data_cspc
1355 delta_v = vel[1] - vel[0]
1357 delta_v = vel[1] - vel[0]
1356
1358
1357 #Calculating the power spectrum
1359 #Calculating the power spectrum
1358 spc_pow = numpy.sum(spectra, 3)*delta_v
1360 spc_pow = numpy.sum(spectra, 3)*delta_v
1359 #Normalizing Spectra
1361 #Normalizing Spectra
1360 norm_spectra = spectra/spc_pow
1362 norm_spectra = spectra/spc_pow
1361 #Calculating the norm_spectra at peak
1363 #Calculating the norm_spectra at peak
1362 max_spectra = numpy.max(norm_spectra, 3)
1364 max_spectra = numpy.max(norm_spectra, 3)
1363
1365
1364 #Normalizing Cross Spectra
1366 #Normalizing Cross Spectra
1365 norm_cspectra = numpy.zeros(cspectra.shape)
1367 norm_cspectra = numpy.zeros(cspectra.shape)
1366
1368
1367 for i in range(num_chan):
1369 for i in range(num_chan):
1368 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
1370 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
1369
1371
1370 max_cspectra = numpy.max(norm_cspectra,2)
1372 max_cspectra = numpy.max(norm_cspectra,2)
1371 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
1373 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
1372
1374
1373 for i in range(num_pairs):
1375 for i in range(num_pairs):
1374 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
1376 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
1375 #------------------- Get Lags ----------------------------------
1377 #------------------- Get Lags ----------------------------------
1376
1378
1377 class SALags(Operation):
1379 class SALags(Operation):
1378 '''
1380 '''
1379 Function GetMoments()
1381 Function GetMoments()
1380
1382
1381 Input:
1383 Input:
1382 self.dataOut.data_pre
1384 self.dataOut.data_pre
1383 self.dataOut.abscissaList
1385 self.dataOut.abscissaList
1384 self.dataOut.noise
1386 self.dataOut.noise
1385 self.dataOut.normFactor
1387 self.dataOut.normFactor
1386 self.dataOut.data_snr
1388 self.dataOut.data_snr
1387 self.dataOut.groupList
1389 self.dataOut.groupList
1388 self.dataOut.nChannels
1390 self.dataOut.nChannels
1389
1391
1390 Affected:
1392 Affected:
1391 self.dataOut.data_param
1393 self.dataOut.data_param
1392
1394
1393 '''
1395 '''
1394 def run(self, dataOut):
1396 def run(self, dataOut):
1395 data_acf = dataOut.data_pre[0]
1397 data_acf = dataOut.data_pre[0]
1396 data_ccf = dataOut.data_pre[1]
1398 data_ccf = dataOut.data_pre[1]
1397 normFactor_acf = dataOut.normFactor[0]
1399 normFactor_acf = dataOut.normFactor[0]
1398 normFactor_ccf = dataOut.normFactor[1]
1400 normFactor_ccf = dataOut.normFactor[1]
1399 pairs_acf = dataOut.groupList[0]
1401 pairs_acf = dataOut.groupList[0]
1400 pairs_ccf = dataOut.groupList[1]
1402 pairs_ccf = dataOut.groupList[1]
1401
1403
1402 nHeights = dataOut.nHeights
1404 nHeights = dataOut.nHeights
1403 absc = dataOut.abscissaList
1405 absc = dataOut.abscissaList
1404 noise = dataOut.noise
1406 noise = dataOut.noise
1405 SNR = dataOut.data_snr
1407 SNR = dataOut.data_snr
1406 nChannels = dataOut.nChannels
1408 nChannels = dataOut.nChannels
1407 # pairsList = dataOut.groupList
1409 # pairsList = dataOut.groupList
1408 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
1410 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
1409
1411
1410 for l in range(len(pairs_acf)):
1412 for l in range(len(pairs_acf)):
1411 data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
1413 data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
1412
1414
1413 for l in range(len(pairs_ccf)):
1415 for l in range(len(pairs_ccf)):
1414 data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
1416 data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
1415
1417
1416 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
1418 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
1417 dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
1419 dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
1418 dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
1420 dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
1419 return
1421 return
1420
1422
1421 # def __getPairsAutoCorr(self, pairsList, nChannels):
1423 # def __getPairsAutoCorr(self, pairsList, nChannels):
1422 #
1424 #
1423 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1425 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1424 #
1426 #
1425 # for l in range(len(pairsList)):
1427 # for l in range(len(pairsList)):
1426 # firstChannel = pairsList[l][0]
1428 # firstChannel = pairsList[l][0]
1427 # secondChannel = pairsList[l][1]
1429 # secondChannel = pairsList[l][1]
1428 #
1430 #
1429 # #Obteniendo pares de Autocorrelacion
1431 # #Obteniendo pares de Autocorrelacion
1430 # if firstChannel == secondChannel:
1432 # if firstChannel == secondChannel:
1431 # pairsAutoCorr[firstChannel] = int(l)
1433 # pairsAutoCorr[firstChannel] = int(l)
1432 #
1434 #
1433 # pairsAutoCorr = pairsAutoCorr.astype(int)
1435 # pairsAutoCorr = pairsAutoCorr.astype(int)
1434 #
1436 #
1435 # pairsCrossCorr = range(len(pairsList))
1437 # pairsCrossCorr = range(len(pairsList))
1436 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1438 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1437 #
1439 #
1438 # return pairsAutoCorr, pairsCrossCorr
1440 # return pairsAutoCorr, pairsCrossCorr
1439
1441
1440 def __calculateTaus(self, data_acf, data_ccf, lagRange):
1442 def __calculateTaus(self, data_acf, data_ccf, lagRange):
1441
1443
1442 lag0 = data_acf.shape[1]/2
1444 lag0 = data_acf.shape[1]/2
1443 #Funcion de Autocorrelacion
1445 #Funcion de Autocorrelacion
1444 mean_acf = stats.nanmean(data_acf, axis = 0)
1446 mean_acf = stats.nanmean(data_acf, axis = 0)
1445
1447
1446 #Obtencion Indice de TauCross
1448 #Obtencion Indice de TauCross
1447 ind_ccf = data_ccf.argmax(axis = 1)
1449 ind_ccf = data_ccf.argmax(axis = 1)
1448 #Obtencion Indice de TauAuto
1450 #Obtencion Indice de TauAuto
1449 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
1451 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
1450 ccf_lag0 = data_ccf[:,lag0,:]
1452 ccf_lag0 = data_ccf[:,lag0,:]
1451
1453
1452 for i in range(ccf_lag0.shape[0]):
1454 for i in range(ccf_lag0.shape[0]):
1453 ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
1455 ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
1454
1456
1455 #Obtencion de TauCross y TauAuto
1457 #Obtencion de TauCross y TauAuto
1456 tau_ccf = lagRange[ind_ccf]
1458 tau_ccf = lagRange[ind_ccf]
1457 tau_acf = lagRange[ind_acf]
1459 tau_acf = lagRange[ind_acf]
1458
1460
1459 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
1461 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
1460
1462
1461 tau_ccf[Nan1,Nan2] = numpy.nan
1463 tau_ccf[Nan1,Nan2] = numpy.nan
1462 tau_acf[Nan1,Nan2] = numpy.nan
1464 tau_acf[Nan1,Nan2] = numpy.nan
1463 tau = numpy.vstack((tau_ccf,tau_acf))
1465 tau = numpy.vstack((tau_ccf,tau_acf))
1464
1466
1465 return tau
1467 return tau
1466
1468
1467 def __calculateLag1Phase(self, data, lagTRange):
1469 def __calculateLag1Phase(self, data, lagTRange):
1468 data1 = stats.nanmean(data, axis = 0)
1470 data1 = stats.nanmean(data, axis = 0)
1469 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
1471 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
1470
1472
1471 phase = numpy.angle(data1[lag1,:])
1473 phase = numpy.angle(data1[lag1,:])
1472
1474
1473 return phase
1475 return phase
1474
1476
1475 class SpectralFitting(Operation):
1477 class SpectralFitting(Operation):
1476 '''
1478 '''
1477 Function GetMoments()
1479 Function GetMoments()
1478
1480
1479 Input:
1481 Input:
1480 Output:
1482 Output:
1481 Variables modified:
1483 Variables modified:
1482 '''
1484 '''
1483
1485
1484 def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
1486 def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
1485
1487
1486
1488
1487 if path != None:
1489 if path != None:
1488 sys.path.append(path)
1490 sys.path.append(path)
1489 self.dataOut.library = importlib.import_module(file)
1491 self.dataOut.library = importlib.import_module(file)
1490
1492
1491 #To be inserted as a parameter
1493 #To be inserted as a parameter
1492 groupArray = numpy.array(groupList)
1494 groupArray = numpy.array(groupList)
1493 # groupArray = numpy.array([[0,1],[2,3]])
1495 # groupArray = numpy.array([[0,1],[2,3]])
1494 self.dataOut.groupList = groupArray
1496 self.dataOut.groupList = groupArray
1495
1497
1496 nGroups = groupArray.shape[0]
1498 nGroups = groupArray.shape[0]
1497 nChannels = self.dataIn.nChannels
1499 nChannels = self.dataIn.nChannels
1498 nHeights=self.dataIn.heightList.size
1500 nHeights=self.dataIn.heightList.size
1499
1501
1500 #Parameters Array
1502 #Parameters Array
1501 self.dataOut.data_param = None
1503 self.dataOut.data_param = None
1502
1504
1503 #Set constants
1505 #Set constants
1504 constants = self.dataOut.library.setConstants(self.dataIn)
1506 constants = self.dataOut.library.setConstants(self.dataIn)
1505 self.dataOut.constants = constants
1507 self.dataOut.constants = constants
1506 M = self.dataIn.normFactor
1508 M = self.dataIn.normFactor
1507 N = self.dataIn.nFFTPoints
1509 N = self.dataIn.nFFTPoints
1508 ippSeconds = self.dataIn.ippSeconds
1510 ippSeconds = self.dataIn.ippSeconds
1509 K = self.dataIn.nIncohInt
1511 K = self.dataIn.nIncohInt
1510 pairsArray = numpy.array(self.dataIn.pairsList)
1512 pairsArray = numpy.array(self.dataIn.pairsList)
1511
1513
1512 #List of possible combinations
1514 #List of possible combinations
1513 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1515 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1514 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1516 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1515
1517
1516 if getSNR:
1518 if getSNR:
1517 listChannels = groupArray.reshape((groupArray.size))
1519 listChannels = groupArray.reshape((groupArray.size))
1518 listChannels.sort()
1520 listChannels.sort()
1519 noise = self.dataIn.getNoise()
1521 noise = self.dataIn.getNoise()
1520 self.dataOut.data_snr = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1522 self.dataOut.data_snr = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1521
1523
1522 for i in range(nGroups):
1524 for i in range(nGroups):
1523 coord = groupArray[i,:]
1525 coord = groupArray[i,:]
1524
1526
1525 #Input data array
1527 #Input data array
1526 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1528 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1527 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1529 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1528
1530
1529 #Cross Spectra data array for Covariance Matrixes
1531 #Cross Spectra data array for Covariance Matrixes
1530 ind = 0
1532 ind = 0
1531 for pairs in listComb:
1533 for pairs in listComb:
1532 pairsSel = numpy.array([coord[x],coord[y]])
1534 pairsSel = numpy.array([coord[x],coord[y]])
1533 indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
1535 indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
1534 ind += 1
1536 ind += 1
1535 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1537 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1536 dataCross = dataCross**2/K
1538 dataCross = dataCross**2/K
1537
1539
1538 for h in range(nHeights):
1540 for h in range(nHeights):
1539
1541
1540 #Input
1542 #Input
1541 d = data[:,h]
1543 d = data[:,h]
1542
1544
1543 #Covariance Matrix
1545 #Covariance Matrix
1544 D = numpy.diag(d**2/K)
1546 D = numpy.diag(d**2/K)
1545 ind = 0
1547 ind = 0
1546 for pairs in listComb:
1548 for pairs in listComb:
1547 #Coordinates in Covariance Matrix
1549 #Coordinates in Covariance Matrix
1548 x = pairs[0]
1550 x = pairs[0]
1549 y = pairs[1]
1551 y = pairs[1]
1550 #Channel Index
1552 #Channel Index
1551 S12 = dataCross[ind,:,h]
1553 S12 = dataCross[ind,:,h]
1552 D12 = numpy.diag(S12)
1554 D12 = numpy.diag(S12)
1553 #Completing Covariance Matrix with Cross Spectras
1555 #Completing Covariance Matrix with Cross Spectras
1554 D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
1556 D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
1555 D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
1557 D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
1556 ind += 1
1558 ind += 1
1557 Dinv=numpy.linalg.inv(D)
1559 Dinv=numpy.linalg.inv(D)
1558 L=numpy.linalg.cholesky(Dinv)
1560 L=numpy.linalg.cholesky(Dinv)
1559 LT=L.T
1561 LT=L.T
1560
1562
1561 dp = numpy.dot(LT,d)
1563 dp = numpy.dot(LT,d)
1562
1564
1563 #Initial values
1565 #Initial values
1564 data_spc = self.dataIn.data_spc[coord,:,h]
1566 data_spc = self.dataIn.data_spc[coord,:,h]
1565
1567
1566 if (h>0)and(error1[3]<5):
1568 if (h>0)and(error1[3]<5):
1567 p0 = self.dataOut.data_param[i,:,h-1]
1569 p0 = self.dataOut.data_param[i,:,h-1]
1568 else:
1570 else:
1569 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1571 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1570
1572
1571 try:
1573 try:
1572 #Least Squares
1574 #Least Squares
1573 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
1575 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
1574 # minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
1576 # minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
1575 #Chi square error
1577 #Chi square error
1576 error0 = numpy.sum(infodict['fvec']**2)/(2*N)
1578 error0 = numpy.sum(infodict['fvec']**2)/(2*N)
1577 #Error with Jacobian
1579 #Error with Jacobian
1578 error1 = self.dataOut.library.errorFunction(minp,constants,LT)
1580 error1 = self.dataOut.library.errorFunction(minp,constants,LT)
1579 except:
1581 except:
1580 minp = p0*numpy.nan
1582 minp = p0*numpy.nan
1581 error0 = numpy.nan
1583 error0 = numpy.nan
1582 error1 = p0*numpy.nan
1584 error1 = p0*numpy.nan
1583
1585
1584 #Save
1586 #Save
1585 if self.dataOut.data_param is None:
1587 if self.dataOut.data_param is None:
1586 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1588 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1587 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1589 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1588
1590
1589 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1591 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1590 self.dataOut.data_param[i,:,h] = minp
1592 self.dataOut.data_param[i,:,h] = minp
1591 return
1593 return
1592
1594
1593 def __residFunction(self, p, dp, LT, constants):
1595 def __residFunction(self, p, dp, LT, constants):
1594
1596
1595 fm = self.dataOut.library.modelFunction(p, constants)
1597 fm = self.dataOut.library.modelFunction(p, constants)
1596 fmp=numpy.dot(LT,fm)
1598 fmp=numpy.dot(LT,fm)
1597
1599
1598 return dp-fmp
1600 return dp-fmp
1599
1601
1600 def __getSNR(self, z, noise):
1602 def __getSNR(self, z, noise):
1601
1603
1602 avg = numpy.average(z, axis=1)
1604 avg = numpy.average(z, axis=1)
1603 SNR = (avg.T-noise)/noise
1605 SNR = (avg.T-noise)/noise
1604 SNR = SNR.T
1606 SNR = SNR.T
1605 return SNR
1607 return SNR
1606
1608
1607 def __chisq(p,chindex,hindex):
1609 def __chisq(p,chindex,hindex):
1608 #similar to Resid but calculates CHI**2
1610 #similar to Resid but calculates CHI**2
1609 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
1611 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
1610 dp=numpy.dot(LT,d)
1612 dp=numpy.dot(LT,d)
1611 fmp=numpy.dot(LT,fm)
1613 fmp=numpy.dot(LT,fm)
1612 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1614 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1613 return chisq
1615 return chisq
1614
1616
1615 class WindProfiler(Operation):
1617 class WindProfiler(Operation):
1616
1618
1617 __isConfig = False
1619 __isConfig = False
1618
1620
1619 __initime = None
1621 __initime = None
1620 __lastdatatime = None
1622 __lastdatatime = None
1621 __integrationtime = None
1623 __integrationtime = None
1622
1624
1623 __buffer = None
1625 __buffer = None
1624
1626
1625 __dataReady = False
1627 __dataReady = False
1626
1628
1627 __firstdata = None
1629 __firstdata = None
1628
1630
1629 n = None
1631 n = None
1630
1632
1631 def __init__(self):
1633 def __init__(self):
1632 Operation.__init__(self)
1634 Operation.__init__(self)
1633
1635
1634 def __calculateCosDir(self, elev, azim):
1636 def __calculateCosDir(self, elev, azim):
1635 zen = (90 - elev)*numpy.pi/180
1637 zen = (90 - elev)*numpy.pi/180
1636 azim = azim*numpy.pi/180
1638 azim = azim*numpy.pi/180
1637 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1639 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1638 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1640 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1639
1641
1640 signX = numpy.sign(numpy.cos(azim))
1642 signX = numpy.sign(numpy.cos(azim))
1641 signY = numpy.sign(numpy.sin(azim))
1643 signY = numpy.sign(numpy.sin(azim))
1642
1644
1643 cosDirX = numpy.copysign(cosDirX, signX)
1645 cosDirX = numpy.copysign(cosDirX, signX)
1644 cosDirY = numpy.copysign(cosDirY, signY)
1646 cosDirY = numpy.copysign(cosDirY, signY)
1645 return cosDirX, cosDirY
1647 return cosDirX, cosDirY
1646
1648
1647 def __calculateAngles(self, theta_x, theta_y, azimuth):
1649 def __calculateAngles(self, theta_x, theta_y, azimuth):
1648
1650
1649 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1651 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1650 zenith_arr = numpy.arccos(dir_cosw)
1652 zenith_arr = numpy.arccos(dir_cosw)
1651 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1653 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1652
1654
1653 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1655 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1654 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1656 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1655
1657
1656 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1658 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1657
1659
1658 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1660 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1659
1661
1660 #
1662 #
1661 if horOnly:
1663 if horOnly:
1662 A = numpy.c_[dir_cosu,dir_cosv]
1664 A = numpy.c_[dir_cosu,dir_cosv]
1663 else:
1665 else:
1664 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
1666 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
1665 A = numpy.asmatrix(A)
1667 A = numpy.asmatrix(A)
1666 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
1668 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
1667
1669
1668 return A1
1670 return A1
1669
1671
1670 def __correctValues(self, heiRang, phi, velRadial, SNR):
1672 def __correctValues(self, heiRang, phi, velRadial, SNR):
1671 listPhi = phi.tolist()
1673 listPhi = phi.tolist()
1672 maxid = listPhi.index(max(listPhi))
1674 maxid = listPhi.index(max(listPhi))
1673 minid = listPhi.index(min(listPhi))
1675 minid = listPhi.index(min(listPhi))
1674
1676
1675 rango = list(range(len(phi)))
1677 rango = list(range(len(phi)))
1676 # rango = numpy.delete(rango,maxid)
1678 # rango = numpy.delete(rango,maxid)
1677
1679
1678 heiRang1 = heiRang*math.cos(phi[maxid])
1680 heiRang1 = heiRang*math.cos(phi[maxid])
1679 heiRangAux = heiRang*math.cos(phi[minid])
1681 heiRangAux = heiRang*math.cos(phi[minid])
1680 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1682 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1681 heiRang1 = numpy.delete(heiRang1,indOut)
1683 heiRang1 = numpy.delete(heiRang1,indOut)
1682
1684
1683 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1685 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1684 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1686 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1685
1687
1686 for i in rango:
1688 for i in rango:
1687 x = heiRang*math.cos(phi[i])
1689 x = heiRang*math.cos(phi[i])
1688 y1 = velRadial[i,:]
1690 y1 = velRadial[i,:]
1689 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1691 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1690
1692
1691 x1 = heiRang1
1693 x1 = heiRang1
1692 y11 = f1(x1)
1694 y11 = f1(x1)
1693
1695
1694 y2 = SNR[i,:]
1696 y2 = SNR[i,:]
1695 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1697 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1696 y21 = f2(x1)
1698 y21 = f2(x1)
1697
1699
1698 velRadial1[i,:] = y11
1700 velRadial1[i,:] = y11
1699 SNR1[i,:] = y21
1701 SNR1[i,:] = y21
1700
1702
1701 return heiRang1, velRadial1, SNR1
1703 return heiRang1, velRadial1, SNR1
1702
1704
1703 def __calculateVelUVW(self, A, velRadial):
1705 def __calculateVelUVW(self, A, velRadial):
1704
1706
1705 #Operacion Matricial
1707 #Operacion Matricial
1706 # velUVW = numpy.zeros((velRadial.shape[1],3))
1708 # velUVW = numpy.zeros((velRadial.shape[1],3))
1707 # for ind in range(velRadial.shape[1]):
1709 # for ind in range(velRadial.shape[1]):
1708 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
1710 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
1709 # velUVW = velUVW.transpose()
1711 # velUVW = velUVW.transpose()
1710 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1712 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1711 velUVW[:,:] = numpy.dot(A,velRadial)
1713 velUVW[:,:] = numpy.dot(A,velRadial)
1712
1714
1713
1715
1714 return velUVW
1716 return velUVW
1715
1717
1716 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1718 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1717
1719
1718 def techniqueDBS(self, kwargs):
1720 def techniqueDBS(self, kwargs):
1719 """
1721 """
1720 Function that implements Doppler Beam Swinging (DBS) technique.
1722 Function that implements Doppler Beam Swinging (DBS) technique.
1721
1723
1722 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1724 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1723 Direction correction (if necessary), Ranges and SNR
1725 Direction correction (if necessary), Ranges and SNR
1724
1726
1725 Output: Winds estimation (Zonal, Meridional and Vertical)
1727 Output: Winds estimation (Zonal, Meridional and Vertical)
1726
1728
1727 Parameters affected: Winds, height range, SNR
1729 Parameters affected: Winds, height range, SNR
1728 """
1730 """
1729 velRadial0 = kwargs['velRadial']
1731 velRadial0 = kwargs['velRadial']
1730 heiRang = kwargs['heightList']
1732 heiRang = kwargs['heightList']
1731 SNR0 = kwargs['SNR']
1733 SNR0 = kwargs['SNR']
1732
1734
1733 if 'dirCosx' in kwargs and 'dirCosy' in kwargs:
1735 if 'dirCosx' in kwargs and 'dirCosy' in kwargs:
1734 theta_x = numpy.array(kwargs['dirCosx'])
1736 theta_x = numpy.array(kwargs['dirCosx'])
1735 theta_y = numpy.array(kwargs['dirCosy'])
1737 theta_y = numpy.array(kwargs['dirCosy'])
1736 else:
1738 else:
1737 elev = numpy.array(kwargs['elevation'])
1739 elev = numpy.array(kwargs['elevation'])
1738 azim = numpy.array(kwargs['azimuth'])
1740 azim = numpy.array(kwargs['azimuth'])
1739 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1741 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1740 azimuth = kwargs['correctAzimuth']
1742 azimuth = kwargs['correctAzimuth']
1741 if 'horizontalOnly' in kwargs:
1743 if 'horizontalOnly' in kwargs:
1742 horizontalOnly = kwargs['horizontalOnly']
1744 horizontalOnly = kwargs['horizontalOnly']
1743 else: horizontalOnly = False
1745 else: horizontalOnly = False
1744 if 'correctFactor' in kwargs:
1746 if 'correctFactor' in kwargs:
1745 correctFactor = kwargs['correctFactor']
1747 correctFactor = kwargs['correctFactor']
1746 else: correctFactor = 1
1748 else: correctFactor = 1
1747 if 'channelList' in kwargs:
1749 if 'channelList' in kwargs:
1748 channelList = kwargs['channelList']
1750 channelList = kwargs['channelList']
1749 if len(channelList) == 2:
1751 if len(channelList) == 2:
1750 horizontalOnly = True
1752 horizontalOnly = True
1751 arrayChannel = numpy.array(channelList)
1753 arrayChannel = numpy.array(channelList)
1752 param = param[arrayChannel,:,:]
1754 param = param[arrayChannel,:,:]
1753 theta_x = theta_x[arrayChannel]
1755 theta_x = theta_x[arrayChannel]
1754 theta_y = theta_y[arrayChannel]
1756 theta_y = theta_y[arrayChannel]
1755
1757
1756 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
1758 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
1757 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
1759 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
1758 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1760 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1759
1761
1760 #Calculo de Componentes de la velocidad con DBS
1762 #Calculo de Componentes de la velocidad con DBS
1761 winds = self.__calculateVelUVW(A,velRadial1)
1763 winds = self.__calculateVelUVW(A,velRadial1)
1762
1764
1763 return winds, heiRang1, SNR1
1765 return winds, heiRang1, SNR1
1764
1766
1765 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
1767 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
1766
1768
1767 nPairs = len(pairs_ccf)
1769 nPairs = len(pairs_ccf)
1768 posx = numpy.asarray(posx)
1770 posx = numpy.asarray(posx)
1769 posy = numpy.asarray(posy)
1771 posy = numpy.asarray(posy)
1770
1772
1771 #Rotacion Inversa para alinear con el azimuth
1773 #Rotacion Inversa para alinear con el azimuth
1772 if azimuth!= None:
1774 if azimuth!= None:
1773 azimuth = azimuth*math.pi/180
1775 azimuth = azimuth*math.pi/180
1774 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
1776 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
1775 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
1777 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
1776 else:
1778 else:
1777 posx1 = posx
1779 posx1 = posx
1778 posy1 = posy
1780 posy1 = posy
1779
1781
1780 #Calculo de Distancias
1782 #Calculo de Distancias
1781 distx = numpy.zeros(nPairs)
1783 distx = numpy.zeros(nPairs)
1782 disty = numpy.zeros(nPairs)
1784 disty = numpy.zeros(nPairs)
1783 dist = numpy.zeros(nPairs)
1785 dist = numpy.zeros(nPairs)
1784 ang = numpy.zeros(nPairs)
1786 ang = numpy.zeros(nPairs)
1785
1787
1786 for i in range(nPairs):
1788 for i in range(nPairs):
1787 distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
1789 distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
1788 disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
1790 disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
1789 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1791 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1790 ang[i] = numpy.arctan2(disty[i],distx[i])
1792 ang[i] = numpy.arctan2(disty[i],distx[i])
1791
1793
1792 return distx, disty, dist, ang
1794 return distx, disty, dist, ang
1793 #Calculo de Matrices
1795 #Calculo de Matrices
1794 # nPairs = len(pairs)
1796 # nPairs = len(pairs)
1795 # ang1 = numpy.zeros((nPairs, 2, 1))
1797 # ang1 = numpy.zeros((nPairs, 2, 1))
1796 # dist1 = numpy.zeros((nPairs, 2, 1))
1798 # dist1 = numpy.zeros((nPairs, 2, 1))
1797 #
1799 #
1798 # for j in range(nPairs):
1800 # for j in range(nPairs):
1799 # dist1[j,0,0] = dist[pairs[j][0]]
1801 # dist1[j,0,0] = dist[pairs[j][0]]
1800 # dist1[j,1,0] = dist[pairs[j][1]]
1802 # dist1[j,1,0] = dist[pairs[j][1]]
1801 # ang1[j,0,0] = ang[pairs[j][0]]
1803 # ang1[j,0,0] = ang[pairs[j][0]]
1802 # ang1[j,1,0] = ang[pairs[j][1]]
1804 # ang1[j,1,0] = ang[pairs[j][1]]
1803 #
1805 #
1804 # return distx,disty, dist1,ang1
1806 # return distx,disty, dist1,ang1
1805
1807
1806
1808
1807 def __calculateVelVer(self, phase, lagTRange, _lambda):
1809 def __calculateVelVer(self, phase, lagTRange, _lambda):
1808
1810
1809 Ts = lagTRange[1] - lagTRange[0]
1811 Ts = lagTRange[1] - lagTRange[0]
1810 velW = -_lambda*phase/(4*math.pi*Ts)
1812 velW = -_lambda*phase/(4*math.pi*Ts)
1811
1813
1812 return velW
1814 return velW
1813
1815
1814 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1816 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1815 nPairs = tau1.shape[0]
1817 nPairs = tau1.shape[0]
1816 nHeights = tau1.shape[1]
1818 nHeights = tau1.shape[1]
1817 vel = numpy.zeros((nPairs,3,nHeights))
1819 vel = numpy.zeros((nPairs,3,nHeights))
1818 dist1 = numpy.reshape(dist, (dist.size,1))
1820 dist1 = numpy.reshape(dist, (dist.size,1))
1819
1821
1820 angCos = numpy.cos(ang)
1822 angCos = numpy.cos(ang)
1821 angSin = numpy.sin(ang)
1823 angSin = numpy.sin(ang)
1822
1824
1823 vel0 = dist1*tau1/(2*tau2**2)
1825 vel0 = dist1*tau1/(2*tau2**2)
1824 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1826 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1825 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1827 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1826
1828
1827 ind = numpy.where(numpy.isinf(vel))
1829 ind = numpy.where(numpy.isinf(vel))
1828 vel[ind] = numpy.nan
1830 vel[ind] = numpy.nan
1829
1831
1830 return vel
1832 return vel
1831
1833
1832 # def __getPairsAutoCorr(self, pairsList, nChannels):
1834 # def __getPairsAutoCorr(self, pairsList, nChannels):
1833 #
1835 #
1834 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1836 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1835 #
1837 #
1836 # for l in range(len(pairsList)):
1838 # for l in range(len(pairsList)):
1837 # firstChannel = pairsList[l][0]
1839 # firstChannel = pairsList[l][0]
1838 # secondChannel = pairsList[l][1]
1840 # secondChannel = pairsList[l][1]
1839 #
1841 #
1840 # #Obteniendo pares de Autocorrelacion
1842 # #Obteniendo pares de Autocorrelacion
1841 # if firstChannel == secondChannel:
1843 # if firstChannel == secondChannel:
1842 # pairsAutoCorr[firstChannel] = int(l)
1844 # pairsAutoCorr[firstChannel] = int(l)
1843 #
1845 #
1844 # pairsAutoCorr = pairsAutoCorr.astype(int)
1846 # pairsAutoCorr = pairsAutoCorr.astype(int)
1845 #
1847 #
1846 # pairsCrossCorr = range(len(pairsList))
1848 # pairsCrossCorr = range(len(pairsList))
1847 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1849 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1848 #
1850 #
1849 # return pairsAutoCorr, pairsCrossCorr
1851 # return pairsAutoCorr, pairsCrossCorr
1850
1852
1851 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1853 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1852 def techniqueSA(self, kwargs):
1854 def techniqueSA(self, kwargs):
1853
1855
1854 """
1856 """
1855 Function that implements Spaced Antenna (SA) technique.
1857 Function that implements Spaced Antenna (SA) technique.
1856
1858
1857 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1859 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1858 Direction correction (if necessary), Ranges and SNR
1860 Direction correction (if necessary), Ranges and SNR
1859
1861
1860 Output: Winds estimation (Zonal, Meridional and Vertical)
1862 Output: Winds estimation (Zonal, Meridional and Vertical)
1861
1863
1862 Parameters affected: Winds
1864 Parameters affected: Winds
1863 """
1865 """
1864 position_x = kwargs['positionX']
1866 position_x = kwargs['positionX']
1865 position_y = kwargs['positionY']
1867 position_y = kwargs['positionY']
1866 azimuth = kwargs['azimuth']
1868 azimuth = kwargs['azimuth']
1867
1869
1868 if 'correctFactor' in kwargs:
1870 if 'correctFactor' in kwargs:
1869 correctFactor = kwargs['correctFactor']
1871 correctFactor = kwargs['correctFactor']
1870 else:
1872 else:
1871 correctFactor = 1
1873 correctFactor = 1
1872
1874
1873 groupList = kwargs['groupList']
1875 groupList = kwargs['groupList']
1874 pairs_ccf = groupList[1]
1876 pairs_ccf = groupList[1]
1875 tau = kwargs['tau']
1877 tau = kwargs['tau']
1876 _lambda = kwargs['_lambda']
1878 _lambda = kwargs['_lambda']
1877
1879
1878 #Cross Correlation pairs obtained
1880 #Cross Correlation pairs obtained
1879 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
1881 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
1880 # pairsArray = numpy.array(pairsList)[pairsCrossCorr]
1882 # pairsArray = numpy.array(pairsList)[pairsCrossCorr]
1881 # pairsSelArray = numpy.array(pairsSelected)
1883 # pairsSelArray = numpy.array(pairsSelected)
1882 # pairs = []
1884 # pairs = []
1883 #
1885 #
1884 # #Wind estimation pairs obtained
1886 # #Wind estimation pairs obtained
1885 # for i in range(pairsSelArray.shape[0]/2):
1887 # for i in range(pairsSelArray.shape[0]/2):
1886 # ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
1888 # ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
1887 # ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
1889 # ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
1888 # pairs.append((ind1,ind2))
1890 # pairs.append((ind1,ind2))
1889
1891
1890 indtau = tau.shape[0]/2
1892 indtau = tau.shape[0]/2
1891 tau1 = tau[:indtau,:]
1893 tau1 = tau[:indtau,:]
1892 tau2 = tau[indtau:-1,:]
1894 tau2 = tau[indtau:-1,:]
1893 # tau1 = tau1[pairs,:]
1895 # tau1 = tau1[pairs,:]
1894 # tau2 = tau2[pairs,:]
1896 # tau2 = tau2[pairs,:]
1895 phase1 = tau[-1,:]
1897 phase1 = tau[-1,:]
1896
1898
1897 #---------------------------------------------------------------------
1899 #---------------------------------------------------------------------
1898 #Metodo Directo
1900 #Metodo Directo
1899 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
1901 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
1900 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
1902 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
1901 winds = stats.nanmean(winds, axis=0)
1903 winds = stats.nanmean(winds, axis=0)
1902 #---------------------------------------------------------------------
1904 #---------------------------------------------------------------------
1903 #Metodo General
1905 #Metodo General
1904 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
1906 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
1905 # #Calculo Coeficientes de Funcion de Correlacion
1907 # #Calculo Coeficientes de Funcion de Correlacion
1906 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
1908 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
1907 # #Calculo de Velocidades
1909 # #Calculo de Velocidades
1908 # winds = self.calculateVelUV(F,G,A,B,H)
1910 # winds = self.calculateVelUV(F,G,A,B,H)
1909
1911
1910 #---------------------------------------------------------------------
1912 #---------------------------------------------------------------------
1911 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
1913 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
1912 winds = correctFactor*winds
1914 winds = correctFactor*winds
1913 return winds
1915 return winds
1914
1916
1915 def __checkTime(self, currentTime, paramInterval, outputInterval):
1917 def __checkTime(self, currentTime, paramInterval, outputInterval):
1916
1918
1917 dataTime = currentTime + paramInterval
1919 dataTime = currentTime + paramInterval
1918 deltaTime = dataTime - self.__initime
1920 deltaTime = dataTime - self.__initime
1919
1921
1920 if deltaTime >= outputInterval or deltaTime < 0:
1922 if deltaTime >= outputInterval or deltaTime < 0:
1921 self.__dataReady = True
1923 self.__dataReady = True
1922 return
1924 return
1923
1925
1924 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
1926 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
1925 '''
1927 '''
1926 Function that implements winds estimation technique with detected meteors.
1928 Function that implements winds estimation technique with detected meteors.
1927
1929
1928 Input: Detected meteors, Minimum meteor quantity to wind estimation
1930 Input: Detected meteors, Minimum meteor quantity to wind estimation
1929
1931
1930 Output: Winds estimation (Zonal and Meridional)
1932 Output: Winds estimation (Zonal and Meridional)
1931
1933
1932 Parameters affected: Winds
1934 Parameters affected: Winds
1933 '''
1935 '''
1934 #Settings
1936 #Settings
1935 nInt = (heightMax - heightMin)/2
1937 nInt = (heightMax - heightMin)/2
1936 nInt = int(nInt)
1938 nInt = int(nInt)
1937 winds = numpy.zeros((2,nInt))*numpy.nan
1939 winds = numpy.zeros((2,nInt))*numpy.nan
1938
1940
1939 #Filter errors
1941 #Filter errors
1940 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
1942 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
1941 finalMeteor = arrayMeteor[error,:]
1943 finalMeteor = arrayMeteor[error,:]
1942
1944
1943 #Meteor Histogram
1945 #Meteor Histogram
1944 finalHeights = finalMeteor[:,2]
1946 finalHeights = finalMeteor[:,2]
1945 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
1947 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
1946 nMeteorsPerI = hist[0]
1948 nMeteorsPerI = hist[0]
1947 heightPerI = hist[1]
1949 heightPerI = hist[1]
1948
1950
1949 #Sort of meteors
1951 #Sort of meteors
1950 indSort = finalHeights.argsort()
1952 indSort = finalHeights.argsort()
1951 finalMeteor2 = finalMeteor[indSort,:]
1953 finalMeteor2 = finalMeteor[indSort,:]
1952
1954
1953 # Calculating winds
1955 # Calculating winds
1954 ind1 = 0
1956 ind1 = 0
1955 ind2 = 0
1957 ind2 = 0
1956
1958
1957 for i in range(nInt):
1959 for i in range(nInt):
1958 nMet = nMeteorsPerI[i]
1960 nMet = nMeteorsPerI[i]
1959 ind1 = ind2
1961 ind1 = ind2
1960 ind2 = ind1 + nMet
1962 ind2 = ind1 + nMet
1961
1963
1962 meteorAux = finalMeteor2[ind1:ind2,:]
1964 meteorAux = finalMeteor2[ind1:ind2,:]
1963
1965
1964 if meteorAux.shape[0] >= meteorThresh:
1966 if meteorAux.shape[0] >= meteorThresh:
1965 vel = meteorAux[:, 6]
1967 vel = meteorAux[:, 6]
1966 zen = meteorAux[:, 4]*numpy.pi/180
1968 zen = meteorAux[:, 4]*numpy.pi/180
1967 azim = meteorAux[:, 3]*numpy.pi/180
1969 azim = meteorAux[:, 3]*numpy.pi/180
1968
1970
1969 n = numpy.cos(zen)
1971 n = numpy.cos(zen)
1970 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
1972 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
1971 # l = m*numpy.tan(azim)
1973 # l = m*numpy.tan(azim)
1972 l = numpy.sin(zen)*numpy.sin(azim)
1974 l = numpy.sin(zen)*numpy.sin(azim)
1973 m = numpy.sin(zen)*numpy.cos(azim)
1975 m = numpy.sin(zen)*numpy.cos(azim)
1974
1976
1975 A = numpy.vstack((l, m)).transpose()
1977 A = numpy.vstack((l, m)).transpose()
1976 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
1978 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
1977 windsAux = numpy.dot(A1, vel)
1979 windsAux = numpy.dot(A1, vel)
1978
1980
1979 winds[0,i] = windsAux[0]
1981 winds[0,i] = windsAux[0]
1980 winds[1,i] = windsAux[1]
1982 winds[1,i] = windsAux[1]
1981
1983
1982 return winds, heightPerI[:-1]
1984 return winds, heightPerI[:-1]
1983
1985
1984 def techniqueNSM_SA(self, **kwargs):
1986 def techniqueNSM_SA(self, **kwargs):
1985 metArray = kwargs['metArray']
1987 metArray = kwargs['metArray']
1986 heightList = kwargs['heightList']
1988 heightList = kwargs['heightList']
1987 timeList = kwargs['timeList']
1989 timeList = kwargs['timeList']
1988
1990
1989 rx_location = kwargs['rx_location']
1991 rx_location = kwargs['rx_location']
1990 groupList = kwargs['groupList']
1992 groupList = kwargs['groupList']
1991 azimuth = kwargs['azimuth']
1993 azimuth = kwargs['azimuth']
1992 dfactor = kwargs['dfactor']
1994 dfactor = kwargs['dfactor']
1993 k = kwargs['k']
1995 k = kwargs['k']
1994
1996
1995 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
1997 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
1996 d = dist*dfactor
1998 d = dist*dfactor
1997 #Phase calculation
1999 #Phase calculation
1998 metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
2000 metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
1999
2001
2000 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
2002 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
2001
2003
2002 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2004 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2003 azimuth1 = azimuth1*numpy.pi/180
2005 azimuth1 = azimuth1*numpy.pi/180
2004
2006
2005 for i in range(heightList.size):
2007 for i in range(heightList.size):
2006 h = heightList[i]
2008 h = heightList[i]
2007 indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
2009 indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
2008 metHeight = metArray1[indH,:]
2010 metHeight = metArray1[indH,:]
2009 if metHeight.shape[0] >= 2:
2011 if metHeight.shape[0] >= 2:
2010 velAux = numpy.asmatrix(metHeight[:,-2]).T #Radial Velocities
2012 velAux = numpy.asmatrix(metHeight[:,-2]).T #Radial Velocities
2011 iazim = metHeight[:,1].astype(int)
2013 iazim = metHeight[:,1].astype(int)
2012 azimAux = numpy.asmatrix(azimuth1[iazim]).T #Azimuths
2014 azimAux = numpy.asmatrix(azimuth1[iazim]).T #Azimuths
2013 A = numpy.hstack((numpy.cos(azimAux),numpy.sin(azimAux)))
2015 A = numpy.hstack((numpy.cos(azimAux),numpy.sin(azimAux)))
2014 A = numpy.asmatrix(A)
2016 A = numpy.asmatrix(A)
2015 A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
2017 A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
2016 velHor = numpy.dot(A1,velAux)
2018 velHor = numpy.dot(A1,velAux)
2017
2019
2018 velEst[i,:] = numpy.squeeze(velHor)
2020 velEst[i,:] = numpy.squeeze(velHor)
2019 return velEst
2021 return velEst
2020
2022
2021 def __getPhaseSlope(self, metArray, heightList, timeList):
2023 def __getPhaseSlope(self, metArray, heightList, timeList):
2022 meteorList = []
2024 meteorList = []
2023 #utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
2025 #utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
2024 #Putting back together the meteor matrix
2026 #Putting back together the meteor matrix
2025 utctime = metArray[:,0]
2027 utctime = metArray[:,0]
2026 uniqueTime = numpy.unique(utctime)
2028 uniqueTime = numpy.unique(utctime)
2027
2029
2028 phaseDerThresh = 0.5
2030 phaseDerThresh = 0.5
2029 ippSeconds = timeList[1] - timeList[0]
2031 ippSeconds = timeList[1] - timeList[0]
2030 sec = numpy.where(timeList>1)[0][0]
2032 sec = numpy.where(timeList>1)[0][0]
2031 nPairs = metArray.shape[1] - 6
2033 nPairs = metArray.shape[1] - 6
2032 nHeights = len(heightList)
2034 nHeights = len(heightList)
2033
2035
2034 for t in uniqueTime:
2036 for t in uniqueTime:
2035 metArray1 = metArray[utctime==t,:]
2037 metArray1 = metArray[utctime==t,:]
2036 # phaseDerThresh = numpy.pi/4 #reducir Phase thresh
2038 # phaseDerThresh = numpy.pi/4 #reducir Phase thresh
2037 tmet = metArray1[:,1].astype(int)
2039 tmet = metArray1[:,1].astype(int)
2038 hmet = metArray1[:,2].astype(int)
2040 hmet = metArray1[:,2].astype(int)
2039
2041
2040 metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
2042 metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
2041 metPhase[:,:] = numpy.nan
2043 metPhase[:,:] = numpy.nan
2042 metPhase[:,hmet,tmet] = metArray1[:,6:].T
2044 metPhase[:,hmet,tmet] = metArray1[:,6:].T
2043
2045
2044 #Delete short trails
2046 #Delete short trails
2045 metBool = ~numpy.isnan(metPhase[0,:,:])
2047 metBool = ~numpy.isnan(metPhase[0,:,:])
2046 heightVect = numpy.sum(metBool, axis = 1)
2048 heightVect = numpy.sum(metBool, axis = 1)
2047 metBool[heightVect<sec,:] = False
2049 metBool[heightVect<sec,:] = False
2048 metPhase[:,heightVect<sec,:] = numpy.nan
2050 metPhase[:,heightVect<sec,:] = numpy.nan
2049
2051
2050 #Derivative
2052 #Derivative
2051 metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
2053 metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
2052 phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
2054 phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
2053 metPhase[phDerAux] = numpy.nan
2055 metPhase[phDerAux] = numpy.nan
2054
2056
2055 #--------------------------METEOR DETECTION -----------------------------------------
2057 #--------------------------METEOR DETECTION -----------------------------------------
2056 indMet = numpy.where(numpy.any(metBool,axis=1))[0]
2058 indMet = numpy.where(numpy.any(metBool,axis=1))[0]
2057
2059
2058 for p in numpy.arange(nPairs):
2060 for p in numpy.arange(nPairs):
2059 phase = metPhase[p,:,:]
2061 phase = metPhase[p,:,:]
2060 phDer = metDer[p,:,:]
2062 phDer = metDer[p,:,:]
2061
2063
2062 for h in indMet:
2064 for h in indMet:
2063 height = heightList[h]
2065 height = heightList[h]
2064 phase1 = phase[h,:] #82
2066 phase1 = phase[h,:] #82
2065 phDer1 = phDer[h,:]
2067 phDer1 = phDer[h,:]
2066
2068
2067 phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
2069 phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
2068
2070
2069 indValid = numpy.where(~numpy.isnan(phase1))[0]
2071 indValid = numpy.where(~numpy.isnan(phase1))[0]
2070 initMet = indValid[0]
2072 initMet = indValid[0]
2071 endMet = 0
2073 endMet = 0
2072
2074
2073 for i in range(len(indValid)-1):
2075 for i in range(len(indValid)-1):
2074
2076
2075 #Time difference
2077 #Time difference
2076 inow = indValid[i]
2078 inow = indValid[i]
2077 inext = indValid[i+1]
2079 inext = indValid[i+1]
2078 idiff = inext - inow
2080 idiff = inext - inow
2079 #Phase difference
2081 #Phase difference
2080 phDiff = numpy.abs(phase1[inext] - phase1[inow])
2082 phDiff = numpy.abs(phase1[inext] - phase1[inow])
2081
2083
2082 if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
2084 if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
2083 sizeTrail = inow - initMet + 1
2085 sizeTrail = inow - initMet + 1
2084 if sizeTrail>3*sec: #Too short meteors
2086 if sizeTrail>3*sec: #Too short meteors
2085 x = numpy.arange(initMet,inow+1)*ippSeconds
2087 x = numpy.arange(initMet,inow+1)*ippSeconds
2086 y = phase1[initMet:inow+1]
2088 y = phase1[initMet:inow+1]
2087 ynnan = ~numpy.isnan(y)
2089 ynnan = ~numpy.isnan(y)
2088 x = x[ynnan]
2090 x = x[ynnan]
2089 y = y[ynnan]
2091 y = y[ynnan]
2090 slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
2092 slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
2091 ylin = x*slope + intercept
2093 ylin = x*slope + intercept
2092 rsq = r_value**2
2094 rsq = r_value**2
2093 if rsq > 0.5:
2095 if rsq > 0.5:
2094 vel = slope#*height*1000/(k*d)
2096 vel = slope#*height*1000/(k*d)
2095 estAux = numpy.array([utctime,p,height, vel, rsq])
2097 estAux = numpy.array([utctime,p,height, vel, rsq])
2096 meteorList.append(estAux)
2098 meteorList.append(estAux)
2097 initMet = inext
2099 initMet = inext
2098 metArray2 = numpy.array(meteorList)
2100 metArray2 = numpy.array(meteorList)
2099
2101
2100 return metArray2
2102 return metArray2
2101
2103
2102 def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
2104 def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
2103
2105
2104 azimuth1 = numpy.zeros(len(pairslist))
2106 azimuth1 = numpy.zeros(len(pairslist))
2105 dist = numpy.zeros(len(pairslist))
2107 dist = numpy.zeros(len(pairslist))
2106
2108
2107 for i in range(len(rx_location)):
2109 for i in range(len(rx_location)):
2108 ch0 = pairslist[i][0]
2110 ch0 = pairslist[i][0]
2109 ch1 = pairslist[i][1]
2111 ch1 = pairslist[i][1]
2110
2112
2111 diffX = rx_location[ch0][0] - rx_location[ch1][0]
2113 diffX = rx_location[ch0][0] - rx_location[ch1][0]
2112 diffY = rx_location[ch0][1] - rx_location[ch1][1]
2114 diffY = rx_location[ch0][1] - rx_location[ch1][1]
2113 azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
2115 azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
2114 dist[i] = numpy.sqrt(diffX**2 + diffY**2)
2116 dist[i] = numpy.sqrt(diffX**2 + diffY**2)
2115
2117
2116 azimuth1 -= azimuth0
2118 azimuth1 -= azimuth0
2117 return azimuth1, dist
2119 return azimuth1, dist
2118
2120
2119 def techniqueNSM_DBS(self, **kwargs):
2121 def techniqueNSM_DBS(self, **kwargs):
2120 metArray = kwargs['metArray']
2122 metArray = kwargs['metArray']
2121 heightList = kwargs['heightList']
2123 heightList = kwargs['heightList']
2122 timeList = kwargs['timeList']
2124 timeList = kwargs['timeList']
2123 azimuth = kwargs['azimuth']
2125 azimuth = kwargs['azimuth']
2124 theta_x = numpy.array(kwargs['theta_x'])
2126 theta_x = numpy.array(kwargs['theta_x'])
2125 theta_y = numpy.array(kwargs['theta_y'])
2127 theta_y = numpy.array(kwargs['theta_y'])
2126
2128
2127 utctime = metArray[:,0]
2129 utctime = metArray[:,0]
2128 cmet = metArray[:,1].astype(int)
2130 cmet = metArray[:,1].astype(int)
2129 hmet = metArray[:,3].astype(int)
2131 hmet = metArray[:,3].astype(int)
2130 SNRmet = metArray[:,4]
2132 SNRmet = metArray[:,4]
2131 vmet = metArray[:,5]
2133 vmet = metArray[:,5]
2132 spcmet = metArray[:,6]
2134 spcmet = metArray[:,6]
2133
2135
2134 nChan = numpy.max(cmet) + 1
2136 nChan = numpy.max(cmet) + 1
2135 nHeights = len(heightList)
2137 nHeights = len(heightList)
2136
2138
2137 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
2139 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
2138 hmet = heightList[hmet]
2140 hmet = heightList[hmet]
2139 h1met = hmet*numpy.cos(zenith_arr[cmet]) #Corrected heights
2141 h1met = hmet*numpy.cos(zenith_arr[cmet]) #Corrected heights
2140
2142
2141 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2143 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2142
2144
2143 for i in range(nHeights - 1):
2145 for i in range(nHeights - 1):
2144 hmin = heightList[i]
2146 hmin = heightList[i]
2145 hmax = heightList[i + 1]
2147 hmax = heightList[i + 1]
2146
2148
2147 thisH = (h1met>=hmin) & (h1met<hmax) & (cmet!=2) & (SNRmet>8) & (vmet<50) & (spcmet<10)
2149 thisH = (h1met>=hmin) & (h1met<hmax) & (cmet!=2) & (SNRmet>8) & (vmet<50) & (spcmet<10)
2148 indthisH = numpy.where(thisH)
2150 indthisH = numpy.where(thisH)
2149
2151
2150 if numpy.size(indthisH) > 3:
2152 if numpy.size(indthisH) > 3:
2151
2153
2152 vel_aux = vmet[thisH]
2154 vel_aux = vmet[thisH]
2153 chan_aux = cmet[thisH]
2155 chan_aux = cmet[thisH]
2154 cosu_aux = dir_cosu[chan_aux]
2156 cosu_aux = dir_cosu[chan_aux]
2155 cosv_aux = dir_cosv[chan_aux]
2157 cosv_aux = dir_cosv[chan_aux]
2156 cosw_aux = dir_cosw[chan_aux]
2158 cosw_aux = dir_cosw[chan_aux]
2157
2159
2158 nch = numpy.size(numpy.unique(chan_aux))
2160 nch = numpy.size(numpy.unique(chan_aux))
2159 if nch > 1:
2161 if nch > 1:
2160 A = self.__calculateMatA(cosu_aux, cosv_aux, cosw_aux, True)
2162 A = self.__calculateMatA(cosu_aux, cosv_aux, cosw_aux, True)
2161 velEst[i,:] = numpy.dot(A,vel_aux)
2163 velEst[i,:] = numpy.dot(A,vel_aux)
2162
2164
2163 return velEst
2165 return velEst
2164
2166
2165 def run(self, dataOut, technique, nHours=1, hmin=70, hmax=110, **kwargs):
2167 def run(self, dataOut, technique, nHours=1, hmin=70, hmax=110, **kwargs):
2166
2168
2167 param = dataOut.data_param
2169 param = dataOut.data_param
2168 if dataOut.abscissaList != None:
2170 if dataOut.abscissaList != None:
2169 absc = dataOut.abscissaList[:-1]
2171 absc = dataOut.abscissaList[:-1]
2170 # noise = dataOut.noise
2172 # noise = dataOut.noise
2171 heightList = dataOut.heightList
2173 heightList = dataOut.heightList
2172 SNR = dataOut.data_snr
2174 SNR = dataOut.data_snr
2173
2175
2174 if technique == 'DBS':
2176 if technique == 'DBS':
2175
2177
2176 kwargs['velRadial'] = param[:,1,:] #Radial velocity
2178 kwargs['velRadial'] = param[:,1,:] #Radial velocity
2177 kwargs['heightList'] = heightList
2179 kwargs['heightList'] = heightList
2178 kwargs['SNR'] = SNR
2180 kwargs['SNR'] = SNR
2179
2181
2180 dataOut.data_output, dataOut.heightList, dataOut.data_snr = self.techniqueDBS(kwargs) #DBS Function
2182 dataOut.data_output, dataOut.heightList, dataOut.data_snr = self.techniqueDBS(kwargs) #DBS Function
2181 dataOut.utctimeInit = dataOut.utctime
2183 dataOut.utctimeInit = dataOut.utctime
2182 dataOut.outputInterval = dataOut.paramInterval
2184 dataOut.outputInterval = dataOut.paramInterval
2183
2185
2184 elif technique == 'SA':
2186 elif technique == 'SA':
2185
2187
2186 #Parameters
2188 #Parameters
2187 # position_x = kwargs['positionX']
2189 # position_x = kwargs['positionX']
2188 # position_y = kwargs['positionY']
2190 # position_y = kwargs['positionY']
2189 # azimuth = kwargs['azimuth']
2191 # azimuth = kwargs['azimuth']
2190 #
2192 #
2191 # if kwargs.has_key('crosspairsList'):
2193 # if kwargs.has_key('crosspairsList'):
2192 # pairs = kwargs['crosspairsList']
2194 # pairs = kwargs['crosspairsList']
2193 # else:
2195 # else:
2194 # pairs = None
2196 # pairs = None
2195 #
2197 #
2196 # if kwargs.has_key('correctFactor'):
2198 # if kwargs.has_key('correctFactor'):
2197 # correctFactor = kwargs['correctFactor']
2199 # correctFactor = kwargs['correctFactor']
2198 # else:
2200 # else:
2199 # correctFactor = 1
2201 # correctFactor = 1
2200
2202
2201 # tau = dataOut.data_param
2203 # tau = dataOut.data_param
2202 # _lambda = dataOut.C/dataOut.frequency
2204 # _lambda = dataOut.C/dataOut.frequency
2203 # pairsList = dataOut.groupList
2205 # pairsList = dataOut.groupList
2204 # nChannels = dataOut.nChannels
2206 # nChannels = dataOut.nChannels
2205
2207
2206 kwargs['groupList'] = dataOut.groupList
2208 kwargs['groupList'] = dataOut.groupList
2207 kwargs['tau'] = dataOut.data_param
2209 kwargs['tau'] = dataOut.data_param
2208 kwargs['_lambda'] = dataOut.C/dataOut.frequency
2210 kwargs['_lambda'] = dataOut.C/dataOut.frequency
2209 # dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
2211 # dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
2210 dataOut.data_output = self.techniqueSA(kwargs)
2212 dataOut.data_output = self.techniqueSA(kwargs)
2211 dataOut.utctimeInit = dataOut.utctime
2213 dataOut.utctimeInit = dataOut.utctime
2212 dataOut.outputInterval = dataOut.timeInterval
2214 dataOut.outputInterval = dataOut.timeInterval
2213
2215
2214 elif technique == 'Meteors':
2216 elif technique == 'Meteors':
2215 dataOut.flagNoData = True
2217 dataOut.flagNoData = True
2216 self.__dataReady = False
2218 self.__dataReady = False
2217
2219
2218 if 'nHours' in kwargs:
2220 if 'nHours' in kwargs:
2219 nHours = kwargs['nHours']
2221 nHours = kwargs['nHours']
2220 else:
2222 else:
2221 nHours = 1
2223 nHours = 1
2222
2224
2223 if 'meteorsPerBin' in kwargs:
2225 if 'meteorsPerBin' in kwargs:
2224 meteorThresh = kwargs['meteorsPerBin']
2226 meteorThresh = kwargs['meteorsPerBin']
2225 else:
2227 else:
2226 meteorThresh = 6
2228 meteorThresh = 6
2227
2229
2228 if 'hmin' in kwargs:
2230 if 'hmin' in kwargs:
2229 hmin = kwargs['hmin']
2231 hmin = kwargs['hmin']
2230 else: hmin = 70
2232 else: hmin = 70
2231 if 'hmax' in kwargs:
2233 if 'hmax' in kwargs:
2232 hmax = kwargs['hmax']
2234 hmax = kwargs['hmax']
2233 else: hmax = 110
2235 else: hmax = 110
2234
2236
2235 dataOut.outputInterval = nHours*3600
2237 dataOut.outputInterval = nHours*3600
2236
2238
2237 if self.__isConfig == False:
2239 if self.__isConfig == False:
2238 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2240 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2239 #Get Initial LTC time
2241 #Get Initial LTC time
2240 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2242 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2241 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2243 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2242
2244
2243 self.__isConfig = True
2245 self.__isConfig = True
2244
2246
2245 if self.__buffer is None:
2247 if self.__buffer is None:
2246 self.__buffer = dataOut.data_param
2248 self.__buffer = dataOut.data_param
2247 self.__firstdata = copy.copy(dataOut)
2249 self.__firstdata = copy.copy(dataOut)
2248
2250
2249 else:
2251 else:
2250 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2252 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2251
2253
2252 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2254 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2253
2255
2254 if self.__dataReady:
2256 if self.__dataReady:
2255 dataOut.utctimeInit = self.__initime
2257 dataOut.utctimeInit = self.__initime
2256
2258
2257 self.__initime += dataOut.outputInterval #to erase time offset
2259 self.__initime += dataOut.outputInterval #to erase time offset
2258
2260
2259 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
2261 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
2260 dataOut.flagNoData = False
2262 dataOut.flagNoData = False
2261 self.__buffer = None
2263 self.__buffer = None
2262
2264
2263 elif technique == 'Meteors1':
2265 elif technique == 'Meteors1':
2264 dataOut.flagNoData = True
2266 dataOut.flagNoData = True
2265 self.__dataReady = False
2267 self.__dataReady = False
2266
2268
2267 if 'nMins' in kwargs:
2269 if 'nMins' in kwargs:
2268 nMins = kwargs['nMins']
2270 nMins = kwargs['nMins']
2269 else: nMins = 20
2271 else: nMins = 20
2270 if 'rx_location' in kwargs:
2272 if 'rx_location' in kwargs:
2271 rx_location = kwargs['rx_location']
2273 rx_location = kwargs['rx_location']
2272 else: rx_location = [(0,1),(1,1),(1,0)]
2274 else: rx_location = [(0,1),(1,1),(1,0)]
2273 if 'azimuth' in kwargs:
2275 if 'azimuth' in kwargs:
2274 azimuth = kwargs['azimuth']
2276 azimuth = kwargs['azimuth']
2275 else: azimuth = 51.06
2277 else: azimuth = 51.06
2276 if 'dfactor' in kwargs:
2278 if 'dfactor' in kwargs:
2277 dfactor = kwargs['dfactor']
2279 dfactor = kwargs['dfactor']
2278 if 'mode' in kwargs:
2280 if 'mode' in kwargs:
2279 mode = kwargs['mode']
2281 mode = kwargs['mode']
2280 if 'theta_x' in kwargs:
2282 if 'theta_x' in kwargs:
2281 theta_x = kwargs['theta_x']
2283 theta_x = kwargs['theta_x']
2282 if 'theta_y' in kwargs:
2284 if 'theta_y' in kwargs:
2283 theta_y = kwargs['theta_y']
2285 theta_y = kwargs['theta_y']
2284 else: mode = 'SA'
2286 else: mode = 'SA'
2285
2287
2286 #Borrar luego esto
2288 #Borrar luego esto
2287 if dataOut.groupList is None:
2289 if dataOut.groupList is None:
2288 dataOut.groupList = [(0,1),(0,2),(1,2)]
2290 dataOut.groupList = [(0,1),(0,2),(1,2)]
2289 groupList = dataOut.groupList
2291 groupList = dataOut.groupList
2290 C = 3e8
2292 C = 3e8
2291 freq = 50e6
2293 freq = 50e6
2292 lamb = C/freq
2294 lamb = C/freq
2293 k = 2*numpy.pi/lamb
2295 k = 2*numpy.pi/lamb
2294
2296
2295 timeList = dataOut.abscissaList
2297 timeList = dataOut.abscissaList
2296 heightList = dataOut.heightList
2298 heightList = dataOut.heightList
2297
2299
2298 if self.__isConfig == False:
2300 if self.__isConfig == False:
2299 dataOut.outputInterval = nMins*60
2301 dataOut.outputInterval = nMins*60
2300 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2302 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2301 #Get Initial LTC time
2303 #Get Initial LTC time
2302 initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2304 initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2303 minuteAux = initime.minute
2305 minuteAux = initime.minute
2304 minuteNew = int(numpy.floor(minuteAux/nMins)*nMins)
2306 minuteNew = int(numpy.floor(minuteAux/nMins)*nMins)
2305 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2307 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2306
2308
2307 self.__isConfig = True
2309 self.__isConfig = True
2308
2310
2309 if self.__buffer is None:
2311 if self.__buffer is None:
2310 self.__buffer = dataOut.data_param
2312 self.__buffer = dataOut.data_param
2311 self.__firstdata = copy.copy(dataOut)
2313 self.__firstdata = copy.copy(dataOut)
2312
2314
2313 else:
2315 else:
2314 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2316 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2315
2317
2316 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2318 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2317
2319
2318 if self.__dataReady:
2320 if self.__dataReady:
2319 dataOut.utctimeInit = self.__initime
2321 dataOut.utctimeInit = self.__initime
2320 self.__initime += dataOut.outputInterval #to erase time offset
2322 self.__initime += dataOut.outputInterval #to erase time offset
2321
2323
2322 metArray = self.__buffer
2324 metArray = self.__buffer
2323 if mode == 'SA':
2325 if mode == 'SA':
2324 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
2326 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
2325 elif mode == 'DBS':
2327 elif mode == 'DBS':
2326 dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList, azimuth=azimuth, theta_x=theta_x, theta_y=theta_y)
2328 dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList, azimuth=azimuth, theta_x=theta_x, theta_y=theta_y)
2327 dataOut.data_output = dataOut.data_output.T
2329 dataOut.data_output = dataOut.data_output.T
2328 dataOut.flagNoData = False
2330 dataOut.flagNoData = False
2329 self.__buffer = None
2331 self.__buffer = None
2330
2332
2331 return
2333 return
2332
2334
2333 class EWDriftsEstimation(Operation):
2335 class EWDriftsEstimation(Operation):
2334
2336
2335 def __init__(self):
2337 def __init__(self):
2336 Operation.__init__(self)
2338 Operation.__init__(self)
2337
2339
2338 def __correctValues(self, heiRang, phi, velRadial, SNR):
2340 def __correctValues(self, heiRang, phi, velRadial, SNR):
2339 listPhi = phi.tolist()
2341 listPhi = phi.tolist()
2340 maxid = listPhi.index(max(listPhi))
2342 maxid = listPhi.index(max(listPhi))
2341 minid = listPhi.index(min(listPhi))
2343 minid = listPhi.index(min(listPhi))
2342
2344
2343 rango = list(range(len(phi)))
2345 rango = list(range(len(phi)))
2344 # rango = numpy.delete(rango,maxid)
2346 # rango = numpy.delete(rango,maxid)
2345
2347
2346 heiRang1 = heiRang*math.cos(phi[maxid])
2348 heiRang1 = heiRang*math.cos(phi[maxid])
2347 heiRangAux = heiRang*math.cos(phi[minid])
2349 heiRangAux = heiRang*math.cos(phi[minid])
2348 indOut = (heiRang1 < heiRangAux[0]).nonzero()
2350 indOut = (heiRang1 < heiRangAux[0]).nonzero()
2349 heiRang1 = numpy.delete(heiRang1,indOut)
2351 heiRang1 = numpy.delete(heiRang1,indOut)
2350
2352
2351 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
2353 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
2352 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
2354 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
2353
2355
2354 for i in rango:
2356 for i in rango:
2355 x = heiRang*math.cos(phi[i])
2357 x = heiRang*math.cos(phi[i])
2356 y1 = velRadial[i,:]
2358 y1 = velRadial[i,:]
2357 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
2359 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
2358
2360
2359 x1 = heiRang1
2361 x1 = heiRang1
2360 y11 = f1(x1)
2362 y11 = f1(x1)
2361
2363
2362 y2 = SNR[i,:]
2364 y2 = SNR[i,:]
2363 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
2365 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
2364 y21 = f2(x1)
2366 y21 = f2(x1)
2365
2367
2366 velRadial1[i,:] = y11
2368 velRadial1[i,:] = y11
2367 SNR1[i,:] = y21
2369 SNR1[i,:] = y21
2368
2370
2369 return heiRang1, velRadial1, SNR1
2371 return heiRang1, velRadial1, SNR1
2370
2372
2371 def run(self, dataOut, zenith, zenithCorrection):
2373 def run(self, dataOut, zenith, zenithCorrection):
2372 heiRang = dataOut.heightList
2374 heiRang = dataOut.heightList
2373 velRadial = dataOut.data_param[:,3,:]
2375 velRadial = dataOut.data_param[:,3,:]
2374 SNR = dataOut.data_snr
2376 SNR = dataOut.data_snr
2375
2377
2376 zenith = numpy.array(zenith)
2378 zenith = numpy.array(zenith)
2377 zenith -= zenithCorrection
2379 zenith -= zenithCorrection
2378 zenith *= numpy.pi/180
2380 zenith *= numpy.pi/180
2379
2381
2380 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
2382 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
2381
2383
2382 alp = zenith[0]
2384 alp = zenith[0]
2383 bet = zenith[1]
2385 bet = zenith[1]
2384
2386
2385 w_w = velRadial1[0,:]
2387 w_w = velRadial1[0,:]
2386 w_e = velRadial1[1,:]
2388 w_e = velRadial1[1,:]
2387
2389
2388 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
2390 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
2389 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
2391 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
2390
2392
2391 winds = numpy.vstack((u,w))
2393 winds = numpy.vstack((u,w))
2392
2394
2393 dataOut.heightList = heiRang1
2395 dataOut.heightList = heiRang1
2394 dataOut.data_output = winds
2396 dataOut.data_output = winds
2395 dataOut.data_snr = SNR1
2397 dataOut.data_snr = SNR1
2396
2398
2397 dataOut.utctimeInit = dataOut.utctime
2399 dataOut.utctimeInit = dataOut.utctime
2398 dataOut.outputInterval = dataOut.timeInterval
2400 dataOut.outputInterval = dataOut.timeInterval
2399 return
2401 return
2400
2402
2401 #--------------- Non Specular Meteor ----------------
2403 #--------------- Non Specular Meteor ----------------
2402
2404
2403 class NonSpecularMeteorDetection(Operation):
2405 class NonSpecularMeteorDetection(Operation):
2404
2406
2405 def run(self, dataOut, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False):
2407 def run(self, dataOut, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False):
2406 data_acf = dataOut.data_pre[0]
2408 data_acf = dataOut.data_pre[0]
2407 data_ccf = dataOut.data_pre[1]
2409 data_ccf = dataOut.data_pre[1]
2408 pairsList = dataOut.groupList[1]
2410 pairsList = dataOut.groupList[1]
2409
2411
2410 lamb = dataOut.C/dataOut.frequency
2412 lamb = dataOut.C/dataOut.frequency
2411 tSamp = dataOut.ippSeconds*dataOut.nCohInt
2413 tSamp = dataOut.ippSeconds*dataOut.nCohInt
2412 paramInterval = dataOut.paramInterval
2414 paramInterval = dataOut.paramInterval
2413
2415
2414 nChannels = data_acf.shape[0]
2416 nChannels = data_acf.shape[0]
2415 nLags = data_acf.shape[1]
2417 nLags = data_acf.shape[1]
2416 nProfiles = data_acf.shape[2]
2418 nProfiles = data_acf.shape[2]
2417 nHeights = dataOut.nHeights
2419 nHeights = dataOut.nHeights
2418 nCohInt = dataOut.nCohInt
2420 nCohInt = dataOut.nCohInt
2419 sec = numpy.round(nProfiles/dataOut.paramInterval)
2421 sec = numpy.round(nProfiles/dataOut.paramInterval)
2420 heightList = dataOut.heightList
2422 heightList = dataOut.heightList
2421 ippSeconds = dataOut.ippSeconds*dataOut.nCohInt*dataOut.nAvg
2423 ippSeconds = dataOut.ippSeconds*dataOut.nCohInt*dataOut.nAvg
2422 utctime = dataOut.utctime
2424 utctime = dataOut.utctime
2423
2425
2424 dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
2426 dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
2425
2427
2426 #------------------------ SNR --------------------------------------
2428 #------------------------ SNR --------------------------------------
2427 power = data_acf[:,0,:,:].real
2429 power = data_acf[:,0,:,:].real
2428 noise = numpy.zeros(nChannels)
2430 noise = numpy.zeros(nChannels)
2429 SNR = numpy.zeros(power.shape)
2431 SNR = numpy.zeros(power.shape)
2430 for i in range(nChannels):
2432 for i in range(nChannels):
2431 noise[i] = hildebrand_sekhon(power[i,:], nCohInt)
2433 noise[i] = hildebrand_sekhon(power[i,:], nCohInt)
2432 SNR[i] = (power[i]-noise[i])/noise[i]
2434 SNR[i] = (power[i]-noise[i])/noise[i]
2433 SNRm = numpy.nanmean(SNR, axis = 0)
2435 SNRm = numpy.nanmean(SNR, axis = 0)
2434 SNRdB = 10*numpy.log10(SNR)
2436 SNRdB = 10*numpy.log10(SNR)
2435
2437
2436 if mode == 'SA':
2438 if mode == 'SA':
2437 dataOut.groupList = dataOut.groupList[1]
2439 dataOut.groupList = dataOut.groupList[1]
2438 nPairs = data_ccf.shape[0]
2440 nPairs = data_ccf.shape[0]
2439 #---------------------- Coherence and Phase --------------------------
2441 #---------------------- Coherence and Phase --------------------------
2440 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
2442 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
2441 # phase1 = numpy.copy(phase)
2443 # phase1 = numpy.copy(phase)
2442 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
2444 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
2443
2445
2444 for p in range(nPairs):
2446 for p in range(nPairs):
2445 ch0 = pairsList[p][0]
2447 ch0 = pairsList[p][0]
2446 ch1 = pairsList[p][1]
2448 ch1 = pairsList[p][1]
2447 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
2449 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
2448 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
2450 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
2449 # phase1[p,:,:] = numpy.angle(ccf) #median filter
2451 # phase1[p,:,:] = numpy.angle(ccf) #median filter
2450 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
2452 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
2451 # coh1[p,:,:] = numpy.abs(ccf) #median filter
2453 # coh1[p,:,:] = numpy.abs(ccf) #median filter
2452 coh = numpy.nanmax(coh1, axis = 0)
2454 coh = numpy.nanmax(coh1, axis = 0)
2453 # struc = numpy.ones((5,1))
2455 # struc = numpy.ones((5,1))
2454 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
2456 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
2455 #---------------------- Radial Velocity ----------------------------
2457 #---------------------- Radial Velocity ----------------------------
2456 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
2458 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
2457 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
2459 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
2458
2460
2459 if allData:
2461 if allData:
2460 boolMetFin = ~numpy.isnan(SNRm)
2462 boolMetFin = ~numpy.isnan(SNRm)
2461 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2463 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2462 else:
2464 else:
2463 #------------------------ Meteor mask ---------------------------------
2465 #------------------------ Meteor mask ---------------------------------
2464 # #SNR mask
2466 # #SNR mask
2465 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
2467 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
2466 #
2468 #
2467 # #Erase small objects
2469 # #Erase small objects
2468 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
2470 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
2469 #
2471 #
2470 # auxEEJ = numpy.sum(boolMet1,axis=0)
2472 # auxEEJ = numpy.sum(boolMet1,axis=0)
2471 # indOver = auxEEJ>nProfiles*0.8 #Use this later
2473 # indOver = auxEEJ>nProfiles*0.8 #Use this later
2472 # indEEJ = numpy.where(indOver)[0]
2474 # indEEJ = numpy.where(indOver)[0]
2473 # indNEEJ = numpy.where(~indOver)[0]
2475 # indNEEJ = numpy.where(~indOver)[0]
2474 #
2476 #
2475 # boolMetFin = boolMet1
2477 # boolMetFin = boolMet1
2476 #
2478 #
2477 # if indEEJ.size > 0:
2479 # if indEEJ.size > 0:
2478 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
2480 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
2479 #
2481 #
2480 # boolMet2 = coh > cohThresh
2482 # boolMet2 = coh > cohThresh
2481 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
2483 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
2482 #
2484 #
2483 # #Final Meteor mask
2485 # #Final Meteor mask
2484 # boolMetFin = boolMet1|boolMet2
2486 # boolMetFin = boolMet1|boolMet2
2485
2487
2486 #Coherence mask
2488 #Coherence mask
2487 boolMet1 = coh > 0.75
2489 boolMet1 = coh > 0.75
2488 struc = numpy.ones((30,1))
2490 struc = numpy.ones((30,1))
2489 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
2491 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
2490
2492
2491 #Derivative mask
2493 #Derivative mask
2492 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2494 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2493 boolMet2 = derPhase < 0.2
2495 boolMet2 = derPhase < 0.2
2494 # boolMet2 = ndimage.morphology.binary_opening(boolMet2)
2496 # boolMet2 = ndimage.morphology.binary_opening(boolMet2)
2495 # boolMet2 = ndimage.morphology.binary_closing(boolMet2, structure = numpy.ones((10,1)))
2497 # boolMet2 = ndimage.morphology.binary_closing(boolMet2, structure = numpy.ones((10,1)))
2496 boolMet2 = ndimage.median_filter(boolMet2,size=5)
2498 boolMet2 = ndimage.median_filter(boolMet2,size=5)
2497 boolMet2 = numpy.vstack((boolMet2,numpy.full((1,nHeights), True, dtype=bool)))
2499 boolMet2 = numpy.vstack((boolMet2,numpy.full((1,nHeights), True, dtype=bool)))
2498 # #Final mask
2500 # #Final mask
2499 # boolMetFin = boolMet2
2501 # boolMetFin = boolMet2
2500 boolMetFin = boolMet1&boolMet2
2502 boolMetFin = boolMet1&boolMet2
2501 # boolMetFin = ndimage.morphology.binary_dilation(boolMetFin)
2503 # boolMetFin = ndimage.morphology.binary_dilation(boolMetFin)
2502 #Creating data_param
2504 #Creating data_param
2503 coordMet = numpy.where(boolMetFin)
2505 coordMet = numpy.where(boolMetFin)
2504
2506
2505 tmet = coordMet[0]
2507 tmet = coordMet[0]
2506 hmet = coordMet[1]
2508 hmet = coordMet[1]
2507
2509
2508 data_param = numpy.zeros((tmet.size, 6 + nPairs))
2510 data_param = numpy.zeros((tmet.size, 6 + nPairs))
2509 data_param[:,0] = utctime
2511 data_param[:,0] = utctime
2510 data_param[:,1] = tmet
2512 data_param[:,1] = tmet
2511 data_param[:,2] = hmet
2513 data_param[:,2] = hmet
2512 data_param[:,3] = SNRm[tmet,hmet]
2514 data_param[:,3] = SNRm[tmet,hmet]
2513 data_param[:,4] = velRad[tmet,hmet]
2515 data_param[:,4] = velRad[tmet,hmet]
2514 data_param[:,5] = coh[tmet,hmet]
2516 data_param[:,5] = coh[tmet,hmet]
2515 data_param[:,6:] = phase[:,tmet,hmet].T
2517 data_param[:,6:] = phase[:,tmet,hmet].T
2516
2518
2517 elif mode == 'DBS':
2519 elif mode == 'DBS':
2518 dataOut.groupList = numpy.arange(nChannels)
2520 dataOut.groupList = numpy.arange(nChannels)
2519
2521
2520 #Radial Velocities
2522 #Radial Velocities
2521 phase = numpy.angle(data_acf[:,1,:,:])
2523 phase = numpy.angle(data_acf[:,1,:,:])
2522 # phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
2524 # phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
2523 velRad = phase*lamb/(4*numpy.pi*tSamp)
2525 velRad = phase*lamb/(4*numpy.pi*tSamp)
2524
2526
2525 #Spectral width
2527 #Spectral width
2526 # acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
2528 # acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
2527 # acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
2529 # acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
2528 acf1 = data_acf[:,1,:,:]
2530 acf1 = data_acf[:,1,:,:]
2529 acf2 = data_acf[:,2,:,:]
2531 acf2 = data_acf[:,2,:,:]
2530
2532
2531 spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2))
2533 spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2))
2532 # velRad = ndimage.median_filter(velRad, size = (1,5,1))
2534 # velRad = ndimage.median_filter(velRad, size = (1,5,1))
2533 if allData:
2535 if allData:
2534 boolMetFin = ~numpy.isnan(SNRdB)
2536 boolMetFin = ~numpy.isnan(SNRdB)
2535 else:
2537 else:
2536 #SNR
2538 #SNR
2537 boolMet1 = (SNRdB>SNRthresh) #SNR mask
2539 boolMet1 = (SNRdB>SNRthresh) #SNR mask
2538 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
2540 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
2539
2541
2540 #Radial velocity
2542 #Radial velocity
2541 boolMet2 = numpy.abs(velRad) < 20
2543 boolMet2 = numpy.abs(velRad) < 20
2542 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
2544 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
2543
2545
2544 #Spectral Width
2546 #Spectral Width
2545 boolMet3 = spcWidth < 30
2547 boolMet3 = spcWidth < 30
2546 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
2548 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
2547 # boolMetFin = self.__erase_small(boolMet1, 10,5)
2549 # boolMetFin = self.__erase_small(boolMet1, 10,5)
2548 boolMetFin = boolMet1&boolMet2&boolMet3
2550 boolMetFin = boolMet1&boolMet2&boolMet3
2549
2551
2550 #Creating data_param
2552 #Creating data_param
2551 coordMet = numpy.where(boolMetFin)
2553 coordMet = numpy.where(boolMetFin)
2552
2554
2553 cmet = coordMet[0]
2555 cmet = coordMet[0]
2554 tmet = coordMet[1]
2556 tmet = coordMet[1]
2555 hmet = coordMet[2]
2557 hmet = coordMet[2]
2556
2558
2557 data_param = numpy.zeros((tmet.size, 7))
2559 data_param = numpy.zeros((tmet.size, 7))
2558 data_param[:,0] = utctime
2560 data_param[:,0] = utctime
2559 data_param[:,1] = cmet
2561 data_param[:,1] = cmet
2560 data_param[:,2] = tmet
2562 data_param[:,2] = tmet
2561 data_param[:,3] = hmet
2563 data_param[:,3] = hmet
2562 data_param[:,4] = SNR[cmet,tmet,hmet].T
2564 data_param[:,4] = SNR[cmet,tmet,hmet].T
2563 data_param[:,5] = velRad[cmet,tmet,hmet].T
2565 data_param[:,5] = velRad[cmet,tmet,hmet].T
2564 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
2566 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
2565
2567
2566 # self.dataOut.data_param = data_int
2568 # self.dataOut.data_param = data_int
2567 if len(data_param) == 0:
2569 if len(data_param) == 0:
2568 dataOut.flagNoData = True
2570 dataOut.flagNoData = True
2569 else:
2571 else:
2570 dataOut.data_param = data_param
2572 dataOut.data_param = data_param
2571
2573
2572 def __erase_small(self, binArray, threshX, threshY):
2574 def __erase_small(self, binArray, threshX, threshY):
2573 labarray, numfeat = ndimage.measurements.label(binArray)
2575 labarray, numfeat = ndimage.measurements.label(binArray)
2574 binArray1 = numpy.copy(binArray)
2576 binArray1 = numpy.copy(binArray)
2575
2577
2576 for i in range(1,numfeat + 1):
2578 for i in range(1,numfeat + 1):
2577 auxBin = (labarray==i)
2579 auxBin = (labarray==i)
2578 auxSize = auxBin.sum()
2580 auxSize = auxBin.sum()
2579
2581
2580 x,y = numpy.where(auxBin)
2582 x,y = numpy.where(auxBin)
2581 widthX = x.max() - x.min()
2583 widthX = x.max() - x.min()
2582 widthY = y.max() - y.min()
2584 widthY = y.max() - y.min()
2583
2585
2584 #width X: 3 seg -> 12.5*3
2586 #width X: 3 seg -> 12.5*3
2585 #width Y:
2587 #width Y:
2586
2588
2587 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
2589 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
2588 binArray1[auxBin] = False
2590 binArray1[auxBin] = False
2589
2591
2590 return binArray1
2592 return binArray1
2591
2593
2592 #--------------- Specular Meteor ----------------
2594 #--------------- Specular Meteor ----------------
2593
2595
2594 class SMDetection(Operation):
2596 class SMDetection(Operation):
2595 '''
2597 '''
2596 Function DetectMeteors()
2598 Function DetectMeteors()
2597 Project developed with paper:
2599 Project developed with paper:
2598 HOLDSWORTH ET AL. 2004
2600 HOLDSWORTH ET AL. 2004
2599
2601
2600 Input:
2602 Input:
2601 self.dataOut.data_pre
2603 self.dataOut.data_pre
2602
2604
2603 centerReceiverIndex: From the channels, which is the center receiver
2605 centerReceiverIndex: From the channels, which is the center receiver
2604
2606
2605 hei_ref: Height reference for the Beacon signal extraction
2607 hei_ref: Height reference for the Beacon signal extraction
2606 tauindex:
2608 tauindex:
2607 predefinedPhaseShifts: Predefined phase offset for the voltge signals
2609 predefinedPhaseShifts: Predefined phase offset for the voltge signals
2608
2610
2609 cohDetection: Whether to user Coherent detection or not
2611 cohDetection: Whether to user Coherent detection or not
2610 cohDet_timeStep: Coherent Detection calculation time step
2612 cohDet_timeStep: Coherent Detection calculation time step
2611 cohDet_thresh: Coherent Detection phase threshold to correct phases
2613 cohDet_thresh: Coherent Detection phase threshold to correct phases
2612
2614
2613 noise_timeStep: Noise calculation time step
2615 noise_timeStep: Noise calculation time step
2614 noise_multiple: Noise multiple to define signal threshold
2616 noise_multiple: Noise multiple to define signal threshold
2615
2617
2616 multDet_timeLimit: Multiple Detection Removal time limit in seconds
2618 multDet_timeLimit: Multiple Detection Removal time limit in seconds
2617 multDet_rangeLimit: Multiple Detection Removal range limit in km
2619 multDet_rangeLimit: Multiple Detection Removal range limit in km
2618
2620
2619 phaseThresh: Maximum phase difference between receiver to be consider a meteor
2621 phaseThresh: Maximum phase difference between receiver to be consider a meteor
2620 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
2622 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
2621
2623
2622 hmin: Minimum Height of the meteor to use it in the further wind estimations
2624 hmin: Minimum Height of the meteor to use it in the further wind estimations
2623 hmax: Maximum Height of the meteor to use it in the further wind estimations
2625 hmax: Maximum Height of the meteor to use it in the further wind estimations
2624 azimuth: Azimuth angle correction
2626 azimuth: Azimuth angle correction
2625
2627
2626 Affected:
2628 Affected:
2627 self.dataOut.data_param
2629 self.dataOut.data_param
2628
2630
2629 Rejection Criteria (Errors):
2631 Rejection Criteria (Errors):
2630 0: No error; analysis OK
2632 0: No error; analysis OK
2631 1: SNR < SNR threshold
2633 1: SNR < SNR threshold
2632 2: angle of arrival (AOA) ambiguously determined
2634 2: angle of arrival (AOA) ambiguously determined
2633 3: AOA estimate not feasible
2635 3: AOA estimate not feasible
2634 4: Large difference in AOAs obtained from different antenna baselines
2636 4: Large difference in AOAs obtained from different antenna baselines
2635 5: echo at start or end of time series
2637 5: echo at start or end of time series
2636 6: echo less than 5 examples long; too short for analysis
2638 6: echo less than 5 examples long; too short for analysis
2637 7: echo rise exceeds 0.3s
2639 7: echo rise exceeds 0.3s
2638 8: echo decay time less than twice rise time
2640 8: echo decay time less than twice rise time
2639 9: large power level before echo
2641 9: large power level before echo
2640 10: large power level after echo
2642 10: large power level after echo
2641 11: poor fit to amplitude for estimation of decay time
2643 11: poor fit to amplitude for estimation of decay time
2642 12: poor fit to CCF phase variation for estimation of radial drift velocity
2644 12: poor fit to CCF phase variation for estimation of radial drift velocity
2643 13: height unresolvable echo: not valid height within 70 to 110 km
2645 13: height unresolvable echo: not valid height within 70 to 110 km
2644 14: height ambiguous echo: more then one possible height within 70 to 110 km
2646 14: height ambiguous echo: more then one possible height within 70 to 110 km
2645 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
2647 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
2646 16: oscilatory echo, indicating event most likely not an underdense echo
2648 16: oscilatory echo, indicating event most likely not an underdense echo
2647
2649
2648 17: phase difference in meteor Reestimation
2650 17: phase difference in meteor Reestimation
2649
2651
2650 Data Storage:
2652 Data Storage:
2651 Meteors for Wind Estimation (8):
2653 Meteors for Wind Estimation (8):
2652 Utc Time | Range Height
2654 Utc Time | Range Height
2653 Azimuth Zenith errorCosDir
2655 Azimuth Zenith errorCosDir
2654 VelRad errorVelRad
2656 VelRad errorVelRad
2655 Phase0 Phase1 Phase2 Phase3
2657 Phase0 Phase1 Phase2 Phase3
2656 TypeError
2658 TypeError
2657
2659
2658 '''
2660 '''
2659
2661
2660 def run(self, dataOut, hei_ref = None, tauindex = 0,
2662 def run(self, dataOut, hei_ref = None, tauindex = 0,
2661 phaseOffsets = None,
2663 phaseOffsets = None,
2662 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
2664 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
2663 noise_timeStep = 4, noise_multiple = 4,
2665 noise_timeStep = 4, noise_multiple = 4,
2664 multDet_timeLimit = 1, multDet_rangeLimit = 3,
2666 multDet_timeLimit = 1, multDet_rangeLimit = 3,
2665 phaseThresh = 20, SNRThresh = 5,
2667 phaseThresh = 20, SNRThresh = 5,
2666 hmin = 50, hmax=150, azimuth = 0,
2668 hmin = 50, hmax=150, azimuth = 0,
2667 channelPositions = None) :
2669 channelPositions = None) :
2668
2670
2669
2671
2670 #Getting Pairslist
2672 #Getting Pairslist
2671 if channelPositions is None:
2673 if channelPositions is None:
2672 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2674 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2673 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2675 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2674 meteorOps = SMOperations()
2676 meteorOps = SMOperations()
2675 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2677 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2676 heiRang = dataOut.heightList
2678 heiRang = dataOut.heightList
2677 #Get Beacon signal - No Beacon signal anymore
2679 #Get Beacon signal - No Beacon signal anymore
2678 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
2680 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
2679 #
2681 #
2680 # if hei_ref != None:
2682 # if hei_ref != None:
2681 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
2683 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
2682 #
2684 #
2683
2685
2684
2686
2685 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
2687 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
2686 # see if the user put in pre defined phase shifts
2688 # see if the user put in pre defined phase shifts
2687 voltsPShift = dataOut.data_pre.copy()
2689 voltsPShift = dataOut.data_pre.copy()
2688
2690
2689 # if predefinedPhaseShifts != None:
2691 # if predefinedPhaseShifts != None:
2690 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
2692 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
2691 #
2693 #
2692 # # elif beaconPhaseShifts:
2694 # # elif beaconPhaseShifts:
2693 # # #get hardware phase shifts using beacon signal
2695 # # #get hardware phase shifts using beacon signal
2694 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
2696 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
2695 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
2697 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
2696 #
2698 #
2697 # else:
2699 # else:
2698 # hardwarePhaseShifts = numpy.zeros(5)
2700 # hardwarePhaseShifts = numpy.zeros(5)
2699 #
2701 #
2700 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
2702 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
2701 # for i in range(self.dataOut.data_pre.shape[0]):
2703 # for i in range(self.dataOut.data_pre.shape[0]):
2702 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
2704 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
2703
2705
2704 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
2706 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
2705
2707
2706 #Remove DC
2708 #Remove DC
2707 voltsDC = numpy.mean(voltsPShift,1)
2709 voltsDC = numpy.mean(voltsPShift,1)
2708 voltsDC = numpy.mean(voltsDC,1)
2710 voltsDC = numpy.mean(voltsDC,1)
2709 for i in range(voltsDC.shape[0]):
2711 for i in range(voltsDC.shape[0]):
2710 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
2712 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
2711
2713
2712 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
2714 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
2713 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
2715 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
2714
2716
2715 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
2717 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
2716 #Coherent Detection
2718 #Coherent Detection
2717 if cohDetection:
2719 if cohDetection:
2718 #use coherent detection to get the net power
2720 #use coherent detection to get the net power
2719 cohDet_thresh = cohDet_thresh*numpy.pi/180
2721 cohDet_thresh = cohDet_thresh*numpy.pi/180
2720 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
2722 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
2721
2723
2722 #Non-coherent detection!
2724 #Non-coherent detection!
2723 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
2725 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
2724 #********** END OF COH/NON-COH POWER CALCULATION**********************
2726 #********** END OF COH/NON-COH POWER CALCULATION**********************
2725
2727
2726 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
2728 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
2727 #Get noise
2729 #Get noise
2728 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
2730 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
2729 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
2731 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
2730 #Get signal threshold
2732 #Get signal threshold
2731 signalThresh = noise_multiple*noise
2733 signalThresh = noise_multiple*noise
2732 #Meteor echoes detection
2734 #Meteor echoes detection
2733 listMeteors = self.__findMeteors(powerNet, signalThresh)
2735 listMeteors = self.__findMeteors(powerNet, signalThresh)
2734 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
2736 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
2735
2737
2736 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
2738 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
2737 #Parameters
2739 #Parameters
2738 heiRange = dataOut.heightList
2740 heiRange = dataOut.heightList
2739 rangeInterval = heiRange[1] - heiRange[0]
2741 rangeInterval = heiRange[1] - heiRange[0]
2740 rangeLimit = multDet_rangeLimit/rangeInterval
2742 rangeLimit = multDet_rangeLimit/rangeInterval
2741 timeLimit = multDet_timeLimit/dataOut.timeInterval
2743 timeLimit = multDet_timeLimit/dataOut.timeInterval
2742 #Multiple detection removals
2744 #Multiple detection removals
2743 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
2745 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
2744 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
2746 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
2745
2747
2746 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
2748 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
2747 #Parameters
2749 #Parameters
2748 phaseThresh = phaseThresh*numpy.pi/180
2750 phaseThresh = phaseThresh*numpy.pi/180
2749 thresh = [phaseThresh, noise_multiple, SNRThresh]
2751 thresh = [phaseThresh, noise_multiple, SNRThresh]
2750 #Meteor reestimation (Errors N 1, 6, 12, 17)
2752 #Meteor reestimation (Errors N 1, 6, 12, 17)
2751 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist0, thresh, noise, dataOut.timeInterval, dataOut.frequency)
2753 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist0, thresh, noise, dataOut.timeInterval, dataOut.frequency)
2752 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
2754 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
2753 #Estimation of decay times (Errors N 7, 8, 11)
2755 #Estimation of decay times (Errors N 7, 8, 11)
2754 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
2756 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
2755 #******************* END OF METEOR REESTIMATION *******************
2757 #******************* END OF METEOR REESTIMATION *******************
2756
2758
2757 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
2759 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
2758 #Calculating Radial Velocity (Error N 15)
2760 #Calculating Radial Velocity (Error N 15)
2759 radialStdThresh = 10
2761 radialStdThresh = 10
2760 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
2762 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
2761
2763
2762 if len(listMeteors4) > 0:
2764 if len(listMeteors4) > 0:
2763 #Setting New Array
2765 #Setting New Array
2764 date = dataOut.utctime
2766 date = dataOut.utctime
2765 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
2767 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
2766
2768
2767 #Correcting phase offset
2769 #Correcting phase offset
2768 if phaseOffsets != None:
2770 if phaseOffsets != None:
2769 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2771 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2770 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2772 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2771
2773
2772 #Second Pairslist
2774 #Second Pairslist
2773 pairsList = []
2775 pairsList = []
2774 pairx = (0,1)
2776 pairx = (0,1)
2775 pairy = (2,3)
2777 pairy = (2,3)
2776 pairsList.append(pairx)
2778 pairsList.append(pairx)
2777 pairsList.append(pairy)
2779 pairsList.append(pairy)
2778
2780
2779 jph = numpy.array([0,0,0,0])
2781 jph = numpy.array([0,0,0,0])
2780 h = (hmin,hmax)
2782 h = (hmin,hmax)
2781 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2783 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2782
2784
2783 # #Calculate AOA (Error N 3, 4)
2785 # #Calculate AOA (Error N 3, 4)
2784 # #JONES ET AL. 1998
2786 # #JONES ET AL. 1998
2785 # error = arrayParameters[:,-1]
2787 # error = arrayParameters[:,-1]
2786 # AOAthresh = numpy.pi/8
2788 # AOAthresh = numpy.pi/8
2787 # phases = -arrayParameters[:,9:13]
2789 # phases = -arrayParameters[:,9:13]
2788 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
2790 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
2789 #
2791 #
2790 # #Calculate Heights (Error N 13 and 14)
2792 # #Calculate Heights (Error N 13 and 14)
2791 # error = arrayParameters[:,-1]
2793 # error = arrayParameters[:,-1]
2792 # Ranges = arrayParameters[:,2]
2794 # Ranges = arrayParameters[:,2]
2793 # zenith = arrayParameters[:,5]
2795 # zenith = arrayParameters[:,5]
2794 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
2796 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
2795 # error = arrayParameters[:,-1]
2797 # error = arrayParameters[:,-1]
2796 #********************* END OF PARAMETERS CALCULATION **************************
2798 #********************* END OF PARAMETERS CALCULATION **************************
2797
2799
2798 #***************************+ PASS DATA TO NEXT STEP **********************
2800 #***************************+ PASS DATA TO NEXT STEP **********************
2799 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
2801 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
2800 dataOut.data_param = arrayParameters
2802 dataOut.data_param = arrayParameters
2801
2803
2802 if arrayParameters is None:
2804 if arrayParameters is None:
2803 dataOut.flagNoData = True
2805 dataOut.flagNoData = True
2804 else:
2806 else:
2805 dataOut.flagNoData = True
2807 dataOut.flagNoData = True
2806
2808
2807 return
2809 return
2808
2810
2809 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
2811 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
2810
2812
2811 minIndex = min(newheis[0])
2813 minIndex = min(newheis[0])
2812 maxIndex = max(newheis[0])
2814 maxIndex = max(newheis[0])
2813
2815
2814 voltage = voltage0[:,:,minIndex:maxIndex+1]
2816 voltage = voltage0[:,:,minIndex:maxIndex+1]
2815 nLength = voltage.shape[1]/n
2817 nLength = voltage.shape[1]/n
2816 nMin = 0
2818 nMin = 0
2817 nMax = 0
2819 nMax = 0
2818 phaseOffset = numpy.zeros((len(pairslist),n))
2820 phaseOffset = numpy.zeros((len(pairslist),n))
2819
2821
2820 for i in range(n):
2822 for i in range(n):
2821 nMax += nLength
2823 nMax += nLength
2822 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
2824 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
2823 phaseCCF = numpy.mean(phaseCCF, axis = 2)
2825 phaseCCF = numpy.mean(phaseCCF, axis = 2)
2824 phaseOffset[:,i] = phaseCCF.transpose()
2826 phaseOffset[:,i] = phaseCCF.transpose()
2825 nMin = nMax
2827 nMin = nMax
2826 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
2828 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
2827
2829
2828 #Remove Outliers
2830 #Remove Outliers
2829 factor = 2
2831 factor = 2
2830 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
2832 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
2831 dw = numpy.std(wt,axis = 1)
2833 dw = numpy.std(wt,axis = 1)
2832 dw = dw.reshape((dw.size,1))
2834 dw = dw.reshape((dw.size,1))
2833 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
2835 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
2834 phaseOffset[ind] = numpy.nan
2836 phaseOffset[ind] = numpy.nan
2835 phaseOffset = stats.nanmean(phaseOffset, axis=1)
2837 phaseOffset = stats.nanmean(phaseOffset, axis=1)
2836
2838
2837 return phaseOffset
2839 return phaseOffset
2838
2840
2839 def __shiftPhase(self, data, phaseShift):
2841 def __shiftPhase(self, data, phaseShift):
2840 #this will shift the phase of a complex number
2842 #this will shift the phase of a complex number
2841 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
2843 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
2842 return dataShifted
2844 return dataShifted
2843
2845
2844 def __estimatePhaseDifference(self, array, pairslist):
2846 def __estimatePhaseDifference(self, array, pairslist):
2845 nChannel = array.shape[0]
2847 nChannel = array.shape[0]
2846 nHeights = array.shape[2]
2848 nHeights = array.shape[2]
2847 numPairs = len(pairslist)
2849 numPairs = len(pairslist)
2848 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
2850 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
2849 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
2851 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
2850
2852
2851 #Correct phases
2853 #Correct phases
2852 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
2854 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
2853 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2855 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2854
2856
2855 if indDer[0].shape[0] > 0:
2857 if indDer[0].shape[0] > 0:
2856 for i in range(indDer[0].shape[0]):
2858 for i in range(indDer[0].shape[0]):
2857 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
2859 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
2858 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
2860 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
2859
2861
2860 # for j in range(numSides):
2862 # for j in range(numSides):
2861 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
2863 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
2862 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
2864 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
2863 #
2865 #
2864 #Linear
2866 #Linear
2865 phaseInt = numpy.zeros((numPairs,1))
2867 phaseInt = numpy.zeros((numPairs,1))
2866 angAllCCF = phaseCCF[:,[0,1,3,4],0]
2868 angAllCCF = phaseCCF[:,[0,1,3,4],0]
2867 for j in range(numPairs):
2869 for j in range(numPairs):
2868 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
2870 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
2869 phaseInt[j] = fit[1]
2871 phaseInt[j] = fit[1]
2870 #Phase Differences
2872 #Phase Differences
2871 phaseDiff = phaseInt - phaseCCF[:,2,:]
2873 phaseDiff = phaseInt - phaseCCF[:,2,:]
2872 phaseArrival = phaseInt.reshape(phaseInt.size)
2874 phaseArrival = phaseInt.reshape(phaseInt.size)
2873
2875
2874 #Dealias
2876 #Dealias
2875 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
2877 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
2876 # indAlias = numpy.where(phaseArrival > numpy.pi)
2878 # indAlias = numpy.where(phaseArrival > numpy.pi)
2877 # phaseArrival[indAlias] -= 2*numpy.pi
2879 # phaseArrival[indAlias] -= 2*numpy.pi
2878 # indAlias = numpy.where(phaseArrival < -numpy.pi)
2880 # indAlias = numpy.where(phaseArrival < -numpy.pi)
2879 # phaseArrival[indAlias] += 2*numpy.pi
2881 # phaseArrival[indAlias] += 2*numpy.pi
2880
2882
2881 return phaseDiff, phaseArrival
2883 return phaseDiff, phaseArrival
2882
2884
2883 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
2885 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
2884 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
2886 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
2885 #find the phase shifts of each channel over 1 second intervals
2887 #find the phase shifts of each channel over 1 second intervals
2886 #only look at ranges below the beacon signal
2888 #only look at ranges below the beacon signal
2887 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
2889 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
2888 numBlocks = int(volts.shape[1]/numProfPerBlock)
2890 numBlocks = int(volts.shape[1]/numProfPerBlock)
2889 numHeights = volts.shape[2]
2891 numHeights = volts.shape[2]
2890 nChannel = volts.shape[0]
2892 nChannel = volts.shape[0]
2891 voltsCohDet = volts.copy()
2893 voltsCohDet = volts.copy()
2892
2894
2893 pairsarray = numpy.array(pairslist)
2895 pairsarray = numpy.array(pairslist)
2894 indSides = pairsarray[:,1]
2896 indSides = pairsarray[:,1]
2895 # indSides = numpy.array(range(nChannel))
2897 # indSides = numpy.array(range(nChannel))
2896 # indSides = numpy.delete(indSides, indCenter)
2898 # indSides = numpy.delete(indSides, indCenter)
2897 #
2899 #
2898 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
2900 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
2899 listBlocks = numpy.array_split(volts, numBlocks, 1)
2901 listBlocks = numpy.array_split(volts, numBlocks, 1)
2900
2902
2901 startInd = 0
2903 startInd = 0
2902 endInd = 0
2904 endInd = 0
2903
2905
2904 for i in range(numBlocks):
2906 for i in range(numBlocks):
2905 startInd = endInd
2907 startInd = endInd
2906 endInd = endInd + listBlocks[i].shape[1]
2908 endInd = endInd + listBlocks[i].shape[1]
2907
2909
2908 arrayBlock = listBlocks[i]
2910 arrayBlock = listBlocks[i]
2909 # arrayBlockCenter = listCenter[i]
2911 # arrayBlockCenter = listCenter[i]
2910
2912
2911 #Estimate the Phase Difference
2913 #Estimate the Phase Difference
2912 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
2914 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
2913 #Phase Difference RMS
2915 #Phase Difference RMS
2914 arrayPhaseRMS = numpy.abs(phaseDiff)
2916 arrayPhaseRMS = numpy.abs(phaseDiff)
2915 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
2917 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
2916 indPhase = numpy.where(phaseRMSaux==4)
2918 indPhase = numpy.where(phaseRMSaux==4)
2917 #Shifting
2919 #Shifting
2918 if indPhase[0].shape[0] > 0:
2920 if indPhase[0].shape[0] > 0:
2919 for j in range(indSides.size):
2921 for j in range(indSides.size):
2920 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
2922 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
2921 voltsCohDet[:,startInd:endInd,:] = arrayBlock
2923 voltsCohDet[:,startInd:endInd,:] = arrayBlock
2922
2924
2923 return voltsCohDet
2925 return voltsCohDet
2924
2926
2925 def __calculateCCF(self, volts, pairslist ,laglist):
2927 def __calculateCCF(self, volts, pairslist ,laglist):
2926
2928
2927 nHeights = volts.shape[2]
2929 nHeights = volts.shape[2]
2928 nPoints = volts.shape[1]
2930 nPoints = volts.shape[1]
2929 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
2931 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
2930
2932
2931 for i in range(len(pairslist)):
2933 for i in range(len(pairslist)):
2932 volts1 = volts[pairslist[i][0]]
2934 volts1 = volts[pairslist[i][0]]
2933 volts2 = volts[pairslist[i][1]]
2935 volts2 = volts[pairslist[i][1]]
2934
2936
2935 for t in range(len(laglist)):
2937 for t in range(len(laglist)):
2936 idxT = laglist[t]
2938 idxT = laglist[t]
2937 if idxT >= 0:
2939 if idxT >= 0:
2938 vStacked = numpy.vstack((volts2[idxT:,:],
2940 vStacked = numpy.vstack((volts2[idxT:,:],
2939 numpy.zeros((idxT, nHeights),dtype='complex')))
2941 numpy.zeros((idxT, nHeights),dtype='complex')))
2940 else:
2942 else:
2941 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
2943 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
2942 volts2[:(nPoints + idxT),:]))
2944 volts2[:(nPoints + idxT),:]))
2943 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
2945 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
2944
2946
2945 vStacked = None
2947 vStacked = None
2946 return voltsCCF
2948 return voltsCCF
2947
2949
2948 def __getNoise(self, power, timeSegment, timeInterval):
2950 def __getNoise(self, power, timeSegment, timeInterval):
2949 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
2951 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
2950 numBlocks = int(power.shape[0]/numProfPerBlock)
2952 numBlocks = int(power.shape[0]/numProfPerBlock)
2951 numHeights = power.shape[1]
2953 numHeights = power.shape[1]
2952
2954
2953 listPower = numpy.array_split(power, numBlocks, 0)
2955 listPower = numpy.array_split(power, numBlocks, 0)
2954 noise = numpy.zeros((power.shape[0], power.shape[1]))
2956 noise = numpy.zeros((power.shape[0], power.shape[1]))
2955 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
2957 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
2956
2958
2957 startInd = 0
2959 startInd = 0
2958 endInd = 0
2960 endInd = 0
2959
2961
2960 for i in range(numBlocks): #split por canal
2962 for i in range(numBlocks): #split por canal
2961 startInd = endInd
2963 startInd = endInd
2962 endInd = endInd + listPower[i].shape[0]
2964 endInd = endInd + listPower[i].shape[0]
2963
2965
2964 arrayBlock = listPower[i]
2966 arrayBlock = listPower[i]
2965 noiseAux = numpy.mean(arrayBlock, 0)
2967 noiseAux = numpy.mean(arrayBlock, 0)
2966 # noiseAux = numpy.median(noiseAux)
2968 # noiseAux = numpy.median(noiseAux)
2967 # noiseAux = numpy.mean(arrayBlock)
2969 # noiseAux = numpy.mean(arrayBlock)
2968 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
2970 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
2969
2971
2970 noiseAux1 = numpy.mean(arrayBlock)
2972 noiseAux1 = numpy.mean(arrayBlock)
2971 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
2973 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
2972
2974
2973 return noise, noise1
2975 return noise, noise1
2974
2976
2975 def __findMeteors(self, power, thresh):
2977 def __findMeteors(self, power, thresh):
2976 nProf = power.shape[0]
2978 nProf = power.shape[0]
2977 nHeights = power.shape[1]
2979 nHeights = power.shape[1]
2978 listMeteors = []
2980 listMeteors = []
2979
2981
2980 for i in range(nHeights):
2982 for i in range(nHeights):
2981 powerAux = power[:,i]
2983 powerAux = power[:,i]
2982 threshAux = thresh[:,i]
2984 threshAux = thresh[:,i]
2983
2985
2984 indUPthresh = numpy.where(powerAux > threshAux)[0]
2986 indUPthresh = numpy.where(powerAux > threshAux)[0]
2985 indDNthresh = numpy.where(powerAux <= threshAux)[0]
2987 indDNthresh = numpy.where(powerAux <= threshAux)[0]
2986
2988
2987 j = 0
2989 j = 0
2988
2990
2989 while (j < indUPthresh.size - 2):
2991 while (j < indUPthresh.size - 2):
2990 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
2992 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
2991 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
2993 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
2992 indDNthresh = indDNthresh[indDNAux]
2994 indDNthresh = indDNthresh[indDNAux]
2993
2995
2994 if (indDNthresh.size > 0):
2996 if (indDNthresh.size > 0):
2995 indEnd = indDNthresh[0] - 1
2997 indEnd = indDNthresh[0] - 1
2996 indInit = indUPthresh[j]
2998 indInit = indUPthresh[j]
2997
2999
2998 meteor = powerAux[indInit:indEnd + 1]
3000 meteor = powerAux[indInit:indEnd + 1]
2999 indPeak = meteor.argmax() + indInit
3001 indPeak = meteor.argmax() + indInit
3000 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
3002 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
3001
3003
3002 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
3004 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
3003 j = numpy.where(indUPthresh == indEnd)[0] + 1
3005 j = numpy.where(indUPthresh == indEnd)[0] + 1
3004 else: j+=1
3006 else: j+=1
3005 else: j+=1
3007 else: j+=1
3006
3008
3007 return listMeteors
3009 return listMeteors
3008
3010
3009 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
3011 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
3010
3012
3011 arrayMeteors = numpy.asarray(listMeteors)
3013 arrayMeteors = numpy.asarray(listMeteors)
3012 listMeteors1 = []
3014 listMeteors1 = []
3013
3015
3014 while arrayMeteors.shape[0] > 0:
3016 while arrayMeteors.shape[0] > 0:
3015 FLAs = arrayMeteors[:,4]
3017 FLAs = arrayMeteors[:,4]
3016 maxFLA = FLAs.argmax()
3018 maxFLA = FLAs.argmax()
3017 listMeteors1.append(arrayMeteors[maxFLA,:])
3019 listMeteors1.append(arrayMeteors[maxFLA,:])
3018
3020
3019 MeteorInitTime = arrayMeteors[maxFLA,1]
3021 MeteorInitTime = arrayMeteors[maxFLA,1]
3020 MeteorEndTime = arrayMeteors[maxFLA,3]
3022 MeteorEndTime = arrayMeteors[maxFLA,3]
3021 MeteorHeight = arrayMeteors[maxFLA,0]
3023 MeteorHeight = arrayMeteors[maxFLA,0]
3022
3024
3023 #Check neighborhood
3025 #Check neighborhood
3024 maxHeightIndex = MeteorHeight + rangeLimit
3026 maxHeightIndex = MeteorHeight + rangeLimit
3025 minHeightIndex = MeteorHeight - rangeLimit
3027 minHeightIndex = MeteorHeight - rangeLimit
3026 minTimeIndex = MeteorInitTime - timeLimit
3028 minTimeIndex = MeteorInitTime - timeLimit
3027 maxTimeIndex = MeteorEndTime + timeLimit
3029 maxTimeIndex = MeteorEndTime + timeLimit
3028
3030
3029 #Check Heights
3031 #Check Heights
3030 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
3032 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
3031 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
3033 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
3032 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
3034 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
3033
3035
3034 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
3036 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
3035
3037
3036 return listMeteors1
3038 return listMeteors1
3037
3039
3038 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
3040 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
3039 numHeights = volts.shape[2]
3041 numHeights = volts.shape[2]
3040 nChannel = volts.shape[0]
3042 nChannel = volts.shape[0]
3041
3043
3042 thresholdPhase = thresh[0]
3044 thresholdPhase = thresh[0]
3043 thresholdNoise = thresh[1]
3045 thresholdNoise = thresh[1]
3044 thresholdDB = float(thresh[2])
3046 thresholdDB = float(thresh[2])
3045
3047
3046 thresholdDB1 = 10**(thresholdDB/10)
3048 thresholdDB1 = 10**(thresholdDB/10)
3047 pairsarray = numpy.array(pairslist)
3049 pairsarray = numpy.array(pairslist)
3048 indSides = pairsarray[:,1]
3050 indSides = pairsarray[:,1]
3049
3051
3050 pairslist1 = list(pairslist)
3052 pairslist1 = list(pairslist)
3051 pairslist1.append((0,1))
3053 pairslist1.append((0,1))
3052 pairslist1.append((3,4))
3054 pairslist1.append((3,4))
3053
3055
3054 listMeteors1 = []
3056 listMeteors1 = []
3055 listPowerSeries = []
3057 listPowerSeries = []
3056 listVoltageSeries = []
3058 listVoltageSeries = []
3057 #volts has the war data
3059 #volts has the war data
3058
3060
3059 if frequency == 30e6:
3061 if frequency == 30e6:
3060 timeLag = 45*10**-3
3062 timeLag = 45*10**-3
3061 else:
3063 else:
3062 timeLag = 15*10**-3
3064 timeLag = 15*10**-3
3063 lag = numpy.ceil(timeLag/timeInterval)
3065 lag = numpy.ceil(timeLag/timeInterval)
3064
3066
3065 for i in range(len(listMeteors)):
3067 for i in range(len(listMeteors)):
3066
3068
3067 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
3069 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
3068 meteorAux = numpy.zeros(16)
3070 meteorAux = numpy.zeros(16)
3069
3071
3070 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
3072 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
3071 mHeight = listMeteors[i][0]
3073 mHeight = listMeteors[i][0]
3072 mStart = listMeteors[i][1]
3074 mStart = listMeteors[i][1]
3073 mPeak = listMeteors[i][2]
3075 mPeak = listMeteors[i][2]
3074 mEnd = listMeteors[i][3]
3076 mEnd = listMeteors[i][3]
3075
3077
3076 #get the volt data between the start and end times of the meteor
3078 #get the volt data between the start and end times of the meteor
3077 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
3079 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
3078 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3080 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3079
3081
3080 #3.6. Phase Difference estimation
3082 #3.6. Phase Difference estimation
3081 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
3083 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
3082
3084
3083 #3.7. Phase difference removal & meteor start, peak and end times reestimated
3085 #3.7. Phase difference removal & meteor start, peak and end times reestimated
3084 #meteorVolts0.- all Channels, all Profiles
3086 #meteorVolts0.- all Channels, all Profiles
3085 meteorVolts0 = volts[:,:,mHeight]
3087 meteorVolts0 = volts[:,:,mHeight]
3086 meteorThresh = noise[:,mHeight]*thresholdNoise
3088 meteorThresh = noise[:,mHeight]*thresholdNoise
3087 meteorNoise = noise[:,mHeight]
3089 meteorNoise = noise[:,mHeight]
3088 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
3090 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
3089 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
3091 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
3090
3092
3091 #Times reestimation
3093 #Times reestimation
3092 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
3094 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
3093 if mStart1.size > 0:
3095 if mStart1.size > 0:
3094 mStart1 = mStart1[-1] + 1
3096 mStart1 = mStart1[-1] + 1
3095
3097
3096 else:
3098 else:
3097 mStart1 = mPeak
3099 mStart1 = mPeak
3098
3100
3099 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
3101 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
3100 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
3102 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
3101 if mEndDecayTime1.size == 0:
3103 if mEndDecayTime1.size == 0:
3102 mEndDecayTime1 = powerNet0.size
3104 mEndDecayTime1 = powerNet0.size
3103 else:
3105 else:
3104 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
3106 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
3105 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
3107 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
3106
3108
3107 #meteorVolts1.- all Channels, from start to end
3109 #meteorVolts1.- all Channels, from start to end
3108 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
3110 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
3109 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
3111 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
3110 if meteorVolts2.shape[1] == 0:
3112 if meteorVolts2.shape[1] == 0:
3111 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
3113 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
3112 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
3114 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
3113 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
3115 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
3114 ##################### END PARAMETERS REESTIMATION #########################
3116 ##################### END PARAMETERS REESTIMATION #########################
3115
3117
3116 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
3118 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
3117 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
3119 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
3118 if meteorVolts2.shape[1] > 0:
3120 if meteorVolts2.shape[1] > 0:
3119 #Phase Difference re-estimation
3121 #Phase Difference re-estimation
3120 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
3122 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
3121 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
3123 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
3122 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
3124 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
3123 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
3125 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
3124 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
3126 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
3125
3127
3126 #Phase Difference RMS
3128 #Phase Difference RMS
3127 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
3129 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
3128 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
3130 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
3129 #Data from Meteor
3131 #Data from Meteor
3130 mPeak1 = powerNet1.argmax() + mStart1
3132 mPeak1 = powerNet1.argmax() + mStart1
3131 mPeakPower1 = powerNet1.max()
3133 mPeakPower1 = powerNet1.max()
3132 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
3134 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
3133 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
3135 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
3134 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
3136 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
3135 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
3137 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
3136 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
3138 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
3137 #Vectorize
3139 #Vectorize
3138 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
3140 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
3139 meteorAux[7:11] = phaseDiffint[0:4]
3141 meteorAux[7:11] = phaseDiffint[0:4]
3140
3142
3141 #Rejection Criterions
3143 #Rejection Criterions
3142 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
3144 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
3143 meteorAux[-1] = 17
3145 meteorAux[-1] = 17
3144 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
3146 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
3145 meteorAux[-1] = 1
3147 meteorAux[-1] = 1
3146
3148
3147
3149
3148 else:
3150 else:
3149 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
3151 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
3150 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
3152 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
3151 PowerSeries = 0
3153 PowerSeries = 0
3152
3154
3153 listMeteors1.append(meteorAux)
3155 listMeteors1.append(meteorAux)
3154 listPowerSeries.append(PowerSeries)
3156 listPowerSeries.append(PowerSeries)
3155 listVoltageSeries.append(meteorVolts1)
3157 listVoltageSeries.append(meteorVolts1)
3156
3158
3157 return listMeteors1, listPowerSeries, listVoltageSeries
3159 return listMeteors1, listPowerSeries, listVoltageSeries
3158
3160
3159 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
3161 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
3160
3162
3161 threshError = 10
3163 threshError = 10
3162 #Depending if it is 30 or 50 MHz
3164 #Depending if it is 30 or 50 MHz
3163 if frequency == 30e6:
3165 if frequency == 30e6:
3164 timeLag = 45*10**-3
3166 timeLag = 45*10**-3
3165 else:
3167 else:
3166 timeLag = 15*10**-3
3168 timeLag = 15*10**-3
3167 lag = numpy.ceil(timeLag/timeInterval)
3169 lag = numpy.ceil(timeLag/timeInterval)
3168
3170
3169 listMeteors1 = []
3171 listMeteors1 = []
3170
3172
3171 for i in range(len(listMeteors)):
3173 for i in range(len(listMeteors)):
3172 meteorPower = listPower[i]
3174 meteorPower = listPower[i]
3173 meteorAux = listMeteors[i]
3175 meteorAux = listMeteors[i]
3174
3176
3175 if meteorAux[-1] == 0:
3177 if meteorAux[-1] == 0:
3176
3178
3177 try:
3179 try:
3178 indmax = meteorPower.argmax()
3180 indmax = meteorPower.argmax()
3179 indlag = indmax + lag
3181 indlag = indmax + lag
3180
3182
3181 y = meteorPower[indlag:]
3183 y = meteorPower[indlag:]
3182 x = numpy.arange(0, y.size)*timeLag
3184 x = numpy.arange(0, y.size)*timeLag
3183
3185
3184 #first guess
3186 #first guess
3185 a = y[0]
3187 a = y[0]
3186 tau = timeLag
3188 tau = timeLag
3187 #exponential fit
3189 #exponential fit
3188 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
3190 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
3189 y1 = self.__exponential_function(x, *popt)
3191 y1 = self.__exponential_function(x, *popt)
3190 #error estimation
3192 #error estimation
3191 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
3193 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
3192
3194
3193 decayTime = popt[1]
3195 decayTime = popt[1]
3194 riseTime = indmax*timeInterval
3196 riseTime = indmax*timeInterval
3195 meteorAux[11:13] = [decayTime, error]
3197 meteorAux[11:13] = [decayTime, error]
3196
3198
3197 #Table items 7, 8 and 11
3199 #Table items 7, 8 and 11
3198 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
3200 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
3199 meteorAux[-1] = 7
3201 meteorAux[-1] = 7
3200 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
3202 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
3201 meteorAux[-1] = 8
3203 meteorAux[-1] = 8
3202 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
3204 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
3203 meteorAux[-1] = 11
3205 meteorAux[-1] = 11
3204
3206
3205
3207
3206 except:
3208 except:
3207 meteorAux[-1] = 11
3209 meteorAux[-1] = 11
3208
3210
3209
3211
3210 listMeteors1.append(meteorAux)
3212 listMeteors1.append(meteorAux)
3211
3213
3212 return listMeteors1
3214 return listMeteors1
3213
3215
3214 #Exponential Function
3216 #Exponential Function
3215
3217
3216 def __exponential_function(self, x, a, tau):
3218 def __exponential_function(self, x, a, tau):
3217 y = a*numpy.exp(-x/tau)
3219 y = a*numpy.exp(-x/tau)
3218 return y
3220 return y
3219
3221
3220 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
3222 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
3221
3223
3222 pairslist1 = list(pairslist)
3224 pairslist1 = list(pairslist)
3223 pairslist1.append((0,1))
3225 pairslist1.append((0,1))
3224 pairslist1.append((3,4))
3226 pairslist1.append((3,4))
3225 numPairs = len(pairslist1)
3227 numPairs = len(pairslist1)
3226 #Time Lag
3228 #Time Lag
3227 timeLag = 45*10**-3
3229 timeLag = 45*10**-3
3228 c = 3e8
3230 c = 3e8
3229 lag = numpy.ceil(timeLag/timeInterval)
3231 lag = numpy.ceil(timeLag/timeInterval)
3230 freq = 30e6
3232 freq = 30e6
3231
3233
3232 listMeteors1 = []
3234 listMeteors1 = []
3233
3235
3234 for i in range(len(listMeteors)):
3236 for i in range(len(listMeteors)):
3235 meteorAux = listMeteors[i]
3237 meteorAux = listMeteors[i]
3236 if meteorAux[-1] == 0:
3238 if meteorAux[-1] == 0:
3237 mStart = listMeteors[i][1]
3239 mStart = listMeteors[i][1]
3238 mPeak = listMeteors[i][2]
3240 mPeak = listMeteors[i][2]
3239 mLag = mPeak - mStart + lag
3241 mLag = mPeak - mStart + lag
3240
3242
3241 #get the volt data between the start and end times of the meteor
3243 #get the volt data between the start and end times of the meteor
3242 meteorVolts = listVolts[i]
3244 meteorVolts = listVolts[i]
3243 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3245 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3244
3246
3245 #Get CCF
3247 #Get CCF
3246 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
3248 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
3247
3249
3248 #Method 2
3250 #Method 2
3249 slopes = numpy.zeros(numPairs)
3251 slopes = numpy.zeros(numPairs)
3250 time = numpy.array([-2,-1,1,2])*timeInterval
3252 time = numpy.array([-2,-1,1,2])*timeInterval
3251 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
3253 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
3252
3254
3253 #Correct phases
3255 #Correct phases
3254 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
3256 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
3255 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
3257 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
3256
3258
3257 if indDer[0].shape[0] > 0:
3259 if indDer[0].shape[0] > 0:
3258 for i in range(indDer[0].shape[0]):
3260 for i in range(indDer[0].shape[0]):
3259 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
3261 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
3260 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
3262 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
3261
3263
3262 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
3264 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
3263 for j in range(numPairs):
3265 for j in range(numPairs):
3264 fit = stats.linregress(time, angAllCCF[j,:])
3266 fit = stats.linregress(time, angAllCCF[j,:])
3265 slopes[j] = fit[0]
3267 slopes[j] = fit[0]
3266
3268
3267 #Remove Outlier
3269 #Remove Outlier
3268 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3270 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3269 # slopes = numpy.delete(slopes,indOut)
3271 # slopes = numpy.delete(slopes,indOut)
3270 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3272 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3271 # slopes = numpy.delete(slopes,indOut)
3273 # slopes = numpy.delete(slopes,indOut)
3272
3274
3273 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
3275 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
3274 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
3276 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
3275 meteorAux[-2] = radialError
3277 meteorAux[-2] = radialError
3276 meteorAux[-3] = radialVelocity
3278 meteorAux[-3] = radialVelocity
3277
3279
3278 #Setting Error
3280 #Setting Error
3279 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
3281 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
3280 if numpy.abs(radialVelocity) > 200:
3282 if numpy.abs(radialVelocity) > 200:
3281 meteorAux[-1] = 15
3283 meteorAux[-1] = 15
3282 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
3284 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
3283 elif radialError > radialStdThresh:
3285 elif radialError > radialStdThresh:
3284 meteorAux[-1] = 12
3286 meteorAux[-1] = 12
3285
3287
3286 listMeteors1.append(meteorAux)
3288 listMeteors1.append(meteorAux)
3287 return listMeteors1
3289 return listMeteors1
3288
3290
3289 def __setNewArrays(self, listMeteors, date, heiRang):
3291 def __setNewArrays(self, listMeteors, date, heiRang):
3290
3292
3291 #New arrays
3293 #New arrays
3292 arrayMeteors = numpy.array(listMeteors)
3294 arrayMeteors = numpy.array(listMeteors)
3293 arrayParameters = numpy.zeros((len(listMeteors), 13))
3295 arrayParameters = numpy.zeros((len(listMeteors), 13))
3294
3296
3295 #Date inclusion
3297 #Date inclusion
3296 # date = re.findall(r'\((.*?)\)', date)
3298 # date = re.findall(r'\((.*?)\)', date)
3297 # date = date[0].split(',')
3299 # date = date[0].split(',')
3298 # date = map(int, date)
3300 # date = map(int, date)
3299 #
3301 #
3300 # if len(date)<6:
3302 # if len(date)<6:
3301 # date.append(0)
3303 # date.append(0)
3302 #
3304 #
3303 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
3305 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
3304 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
3306 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
3305 arrayDate = numpy.tile(date, (len(listMeteors)))
3307 arrayDate = numpy.tile(date, (len(listMeteors)))
3306
3308
3307 #Meteor array
3309 #Meteor array
3308 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
3310 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
3309 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
3311 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
3310
3312
3311 #Parameters Array
3313 #Parameters Array
3312 arrayParameters[:,0] = arrayDate #Date
3314 arrayParameters[:,0] = arrayDate #Date
3313 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
3315 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
3314 arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
3316 arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
3315 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
3317 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
3316 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
3318 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
3317
3319
3318
3320
3319 return arrayParameters
3321 return arrayParameters
3320
3322
3321 class CorrectSMPhases(Operation):
3323 class CorrectSMPhases(Operation):
3322
3324
3323 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
3325 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
3324
3326
3325 arrayParameters = dataOut.data_param
3327 arrayParameters = dataOut.data_param
3326 pairsList = []
3328 pairsList = []
3327 pairx = (0,1)
3329 pairx = (0,1)
3328 pairy = (2,3)
3330 pairy = (2,3)
3329 pairsList.append(pairx)
3331 pairsList.append(pairx)
3330 pairsList.append(pairy)
3332 pairsList.append(pairy)
3331 jph = numpy.zeros(4)
3333 jph = numpy.zeros(4)
3332
3334
3333 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
3335 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
3334 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
3336 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
3335 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
3337 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
3336
3338
3337 meteorOps = SMOperations()
3339 meteorOps = SMOperations()
3338 if channelPositions is None:
3340 if channelPositions is None:
3339 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3341 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3340 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3342 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3341
3343
3342 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3344 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3343 h = (hmin,hmax)
3345 h = (hmin,hmax)
3344
3346
3345 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
3347 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
3346
3348
3347 dataOut.data_param = arrayParameters
3349 dataOut.data_param = arrayParameters
3348 return
3350 return
3349
3351
3350 class SMPhaseCalibration(Operation):
3352 class SMPhaseCalibration(Operation):
3351
3353
3352 __buffer = None
3354 __buffer = None
3353
3355
3354 __initime = None
3356 __initime = None
3355
3357
3356 __dataReady = False
3358 __dataReady = False
3357
3359
3358 __isConfig = False
3360 __isConfig = False
3359
3361
3360 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
3362 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
3361
3363
3362 dataTime = currentTime + paramInterval
3364 dataTime = currentTime + paramInterval
3363 deltaTime = dataTime - initTime
3365 deltaTime = dataTime - initTime
3364
3366
3365 if deltaTime >= outputInterval or deltaTime < 0:
3367 if deltaTime >= outputInterval or deltaTime < 0:
3366 return True
3368 return True
3367
3369
3368 return False
3370 return False
3369
3371
3370 def __getGammas(self, pairs, d, phases):
3372 def __getGammas(self, pairs, d, phases):
3371 gammas = numpy.zeros(2)
3373 gammas = numpy.zeros(2)
3372
3374
3373 for i in range(len(pairs)):
3375 for i in range(len(pairs)):
3374
3376
3375 pairi = pairs[i]
3377 pairi = pairs[i]
3376
3378
3377 phip3 = phases[:,pairi[0]]
3379 phip3 = phases[:,pairi[0]]
3378 d3 = d[pairi[0]]
3380 d3 = d[pairi[0]]
3379 phip2 = phases[:,pairi[1]]
3381 phip2 = phases[:,pairi[1]]
3380 d2 = d[pairi[1]]
3382 d2 = d[pairi[1]]
3381 #Calculating gamma
3383 #Calculating gamma
3382 # jdcos = alp1/(k*d1)
3384 # jdcos = alp1/(k*d1)
3383 # jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0)))
3385 # jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0)))
3384 jgamma = -phip2*d3/d2 - phip3
3386 jgamma = -phip2*d3/d2 - phip3
3385 jgamma = numpy.angle(numpy.exp(1j*jgamma))
3387 jgamma = numpy.angle(numpy.exp(1j*jgamma))
3386 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
3388 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
3387 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
3389 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
3388
3390
3389 #Revised distribution
3391 #Revised distribution
3390 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
3392 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
3391
3393
3392 #Histogram
3394 #Histogram
3393 nBins = 64
3395 nBins = 64
3394 rmin = -0.5*numpy.pi
3396 rmin = -0.5*numpy.pi
3395 rmax = 0.5*numpy.pi
3397 rmax = 0.5*numpy.pi
3396 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
3398 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
3397
3399
3398 meteorsY = phaseHisto[0]
3400 meteorsY = phaseHisto[0]
3399 phasesX = phaseHisto[1][:-1]
3401 phasesX = phaseHisto[1][:-1]
3400 width = phasesX[1] - phasesX[0]
3402 width = phasesX[1] - phasesX[0]
3401 phasesX += width/2
3403 phasesX += width/2
3402
3404
3403 #Gaussian aproximation
3405 #Gaussian aproximation
3404 bpeak = meteorsY.argmax()
3406 bpeak = meteorsY.argmax()
3405 peak = meteorsY.max()
3407 peak = meteorsY.max()
3406 jmin = bpeak - 5
3408 jmin = bpeak - 5
3407 jmax = bpeak + 5 + 1
3409 jmax = bpeak + 5 + 1
3408
3410
3409 if jmin<0:
3411 if jmin<0:
3410 jmin = 0
3412 jmin = 0
3411 jmax = 6
3413 jmax = 6
3412 elif jmax > meteorsY.size:
3414 elif jmax > meteorsY.size:
3413 jmin = meteorsY.size - 6
3415 jmin = meteorsY.size - 6
3414 jmax = meteorsY.size
3416 jmax = meteorsY.size
3415
3417
3416 x0 = numpy.array([peak,bpeak,50])
3418 x0 = numpy.array([peak,bpeak,50])
3417 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
3419 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
3418
3420
3419 #Gammas
3421 #Gammas
3420 gammas[i] = coeff[0][1]
3422 gammas[i] = coeff[0][1]
3421
3423
3422 return gammas
3424 return gammas
3423
3425
3424 def __residualFunction(self, coeffs, y, t):
3426 def __residualFunction(self, coeffs, y, t):
3425
3427
3426 return y - self.__gauss_function(t, coeffs)
3428 return y - self.__gauss_function(t, coeffs)
3427
3429
3428 def __gauss_function(self, t, coeffs):
3430 def __gauss_function(self, t, coeffs):
3429
3431
3430 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
3432 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
3431
3433
3432 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
3434 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
3433 meteorOps = SMOperations()
3435 meteorOps = SMOperations()
3434 nchan = 4
3436 nchan = 4
3435 pairx = pairsList[0] #x es 0
3437 pairx = pairsList[0] #x es 0
3436 pairy = pairsList[1] #y es 1
3438 pairy = pairsList[1] #y es 1
3437 center_xangle = 0
3439 center_xangle = 0
3438 center_yangle = 0
3440 center_yangle = 0
3439 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
3441 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
3440 ntimes = len(range_angle)
3442 ntimes = len(range_angle)
3441
3443
3442 nstepsx = 20
3444 nstepsx = 20
3443 nstepsy = 20
3445 nstepsy = 20
3444
3446
3445 for iz in range(ntimes):
3447 for iz in range(ntimes):
3446 min_xangle = -range_angle[iz]/2 + center_xangle
3448 min_xangle = -range_angle[iz]/2 + center_xangle
3447 max_xangle = range_angle[iz]/2 + center_xangle
3449 max_xangle = range_angle[iz]/2 + center_xangle
3448 min_yangle = -range_angle[iz]/2 + center_yangle
3450 min_yangle = -range_angle[iz]/2 + center_yangle
3449 max_yangle = range_angle[iz]/2 + center_yangle
3451 max_yangle = range_angle[iz]/2 + center_yangle
3450
3452
3451 inc_x = (max_xangle-min_xangle)/nstepsx
3453 inc_x = (max_xangle-min_xangle)/nstepsx
3452 inc_y = (max_yangle-min_yangle)/nstepsy
3454 inc_y = (max_yangle-min_yangle)/nstepsy
3453
3455
3454 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
3456 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
3455 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
3457 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
3456 penalty = numpy.zeros((nstepsx,nstepsy))
3458 penalty = numpy.zeros((nstepsx,nstepsy))
3457 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
3459 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
3458 jph = numpy.zeros(nchan)
3460 jph = numpy.zeros(nchan)
3459
3461
3460 # Iterations looking for the offset
3462 # Iterations looking for the offset
3461 for iy in range(int(nstepsy)):
3463 for iy in range(int(nstepsy)):
3462 for ix in range(int(nstepsx)):
3464 for ix in range(int(nstepsx)):
3463 d3 = d[pairsList[1][0]]
3465 d3 = d[pairsList[1][0]]
3464 d2 = d[pairsList[1][1]]
3466 d2 = d[pairsList[1][1]]
3465 d5 = d[pairsList[0][0]]
3467 d5 = d[pairsList[0][0]]
3466 d4 = d[pairsList[0][1]]
3468 d4 = d[pairsList[0][1]]
3467
3469
3468 alp2 = alpha_y[iy] #gamma 1
3470 alp2 = alpha_y[iy] #gamma 1
3469 alp4 = alpha_x[ix] #gamma 0
3471 alp4 = alpha_x[ix] #gamma 0
3470
3472
3471 alp3 = -alp2*d3/d2 - gammas[1]
3473 alp3 = -alp2*d3/d2 - gammas[1]
3472 alp5 = -alp4*d5/d4 - gammas[0]
3474 alp5 = -alp4*d5/d4 - gammas[0]
3473 # jph[pairy[1]] = alpha_y[iy]
3475 # jph[pairy[1]] = alpha_y[iy]
3474 # jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
3476 # jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
3475
3477
3476 # jph[pairx[1]] = alpha_x[ix]
3478 # jph[pairx[1]] = alpha_x[ix]
3477 # jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
3479 # jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
3478 jph[pairsList[0][1]] = alp4
3480 jph[pairsList[0][1]] = alp4
3479 jph[pairsList[0][0]] = alp5
3481 jph[pairsList[0][0]] = alp5
3480 jph[pairsList[1][0]] = alp3
3482 jph[pairsList[1][0]] = alp3
3481 jph[pairsList[1][1]] = alp2
3483 jph[pairsList[1][1]] = alp2
3482 jph_array[:,ix,iy] = jph
3484 jph_array[:,ix,iy] = jph
3483 # d = [2.0,2.5,2.5,2.0]
3485 # d = [2.0,2.5,2.5,2.0]
3484 #falta chequear si va a leer bien los meteoros
3486 #falta chequear si va a leer bien los meteoros
3485 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
3487 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
3486 error = meteorsArray1[:,-1]
3488 error = meteorsArray1[:,-1]
3487 ind1 = numpy.where(error==0)[0]
3489 ind1 = numpy.where(error==0)[0]
3488 penalty[ix,iy] = ind1.size
3490 penalty[ix,iy] = ind1.size
3489
3491
3490 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
3492 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
3491 phOffset = jph_array[:,i,j]
3493 phOffset = jph_array[:,i,j]
3492
3494
3493 center_xangle = phOffset[pairx[1]]
3495 center_xangle = phOffset[pairx[1]]
3494 center_yangle = phOffset[pairy[1]]
3496 center_yangle = phOffset[pairy[1]]
3495
3497
3496 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
3498 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
3497 phOffset = phOffset*180/numpy.pi
3499 phOffset = phOffset*180/numpy.pi
3498 return phOffset
3500 return phOffset
3499
3501
3500
3502
3501 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
3503 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
3502
3504
3503 dataOut.flagNoData = True
3505 dataOut.flagNoData = True
3504 self.__dataReady = False
3506 self.__dataReady = False
3505 dataOut.outputInterval = nHours*3600
3507 dataOut.outputInterval = nHours*3600
3506
3508
3507 if self.__isConfig == False:
3509 if self.__isConfig == False:
3508 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
3510 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
3509 #Get Initial LTC time
3511 #Get Initial LTC time
3510 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
3512 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
3511 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
3513 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
3512
3514
3513 self.__isConfig = True
3515 self.__isConfig = True
3514
3516
3515 if self.__buffer is None:
3517 if self.__buffer is None:
3516 self.__buffer = dataOut.data_param.copy()
3518 self.__buffer = dataOut.data_param.copy()
3517
3519
3518 else:
3520 else:
3519 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
3521 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
3520
3522
3521 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
3523 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
3522
3524
3523 if self.__dataReady:
3525 if self.__dataReady:
3524 dataOut.utctimeInit = self.__initime
3526 dataOut.utctimeInit = self.__initime
3525 self.__initime += dataOut.outputInterval #to erase time offset
3527 self.__initime += dataOut.outputInterval #to erase time offset
3526
3528
3527 freq = dataOut.frequency
3529 freq = dataOut.frequency
3528 c = dataOut.C #m/s
3530 c = dataOut.C #m/s
3529 lamb = c/freq
3531 lamb = c/freq
3530 k = 2*numpy.pi/lamb
3532 k = 2*numpy.pi/lamb
3531 azimuth = 0
3533 azimuth = 0
3532 h = (hmin, hmax)
3534 h = (hmin, hmax)
3533 # pairs = ((0,1),(2,3)) #Estrella
3535 # pairs = ((0,1),(2,3)) #Estrella
3534 # pairs = ((1,0),(2,3)) #T
3536 # pairs = ((1,0),(2,3)) #T
3535
3537
3536 if channelPositions is None:
3538 if channelPositions is None:
3537 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3539 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3538 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3540 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3539 meteorOps = SMOperations()
3541 meteorOps = SMOperations()
3540 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3542 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3541
3543
3542 #Checking correct order of pairs
3544 #Checking correct order of pairs
3543 pairs = []
3545 pairs = []
3544 if distances[1] > distances[0]:
3546 if distances[1] > distances[0]:
3545 pairs.append((1,0))
3547 pairs.append((1,0))
3546 else:
3548 else:
3547 pairs.append((0,1))
3549 pairs.append((0,1))
3548
3550
3549 if distances[3] > distances[2]:
3551 if distances[3] > distances[2]:
3550 pairs.append((3,2))
3552 pairs.append((3,2))
3551 else:
3553 else:
3552 pairs.append((2,3))
3554 pairs.append((2,3))
3553 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
3555 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
3554
3556
3555 meteorsArray = self.__buffer
3557 meteorsArray = self.__buffer
3556 error = meteorsArray[:,-1]
3558 error = meteorsArray[:,-1]
3557 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
3559 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
3558 ind1 = numpy.where(boolError)[0]
3560 ind1 = numpy.where(boolError)[0]
3559 meteorsArray = meteorsArray[ind1,:]
3561 meteorsArray = meteorsArray[ind1,:]
3560 meteorsArray[:,-1] = 0
3562 meteorsArray[:,-1] = 0
3561 phases = meteorsArray[:,8:12]
3563 phases = meteorsArray[:,8:12]
3562
3564
3563 #Calculate Gammas
3565 #Calculate Gammas
3564 gammas = self.__getGammas(pairs, distances, phases)
3566 gammas = self.__getGammas(pairs, distances, phases)
3565 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
3567 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
3566 #Calculate Phases
3568 #Calculate Phases
3567 phasesOff = self.__getPhases(azimuth, h, pairs, distances, gammas, meteorsArray)
3569 phasesOff = self.__getPhases(azimuth, h, pairs, distances, gammas, meteorsArray)
3568 phasesOff = phasesOff.reshape((1,phasesOff.size))
3570 phasesOff = phasesOff.reshape((1,phasesOff.size))
3569 dataOut.data_output = -phasesOff
3571 dataOut.data_output = -phasesOff
3570 dataOut.flagNoData = False
3572 dataOut.flagNoData = False
3571 self.__buffer = None
3573 self.__buffer = None
3572
3574
3573
3575
3574 return
3576 return
3575
3577
3576 class SMOperations():
3578 class SMOperations():
3577
3579
3578 def __init__(self):
3580 def __init__(self):
3579
3581
3580 return
3582 return
3581
3583
3582 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
3584 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
3583
3585
3584 arrayParameters = arrayParameters0.copy()
3586 arrayParameters = arrayParameters0.copy()
3585 hmin = h[0]
3587 hmin = h[0]
3586 hmax = h[1]
3588 hmax = h[1]
3587
3589
3588 #Calculate AOA (Error N 3, 4)
3590 #Calculate AOA (Error N 3, 4)
3589 #JONES ET AL. 1998
3591 #JONES ET AL. 1998
3590 AOAthresh = numpy.pi/8
3592 AOAthresh = numpy.pi/8
3591 error = arrayParameters[:,-1]
3593 error = arrayParameters[:,-1]
3592 phases = -arrayParameters[:,8:12] + jph
3594 phases = -arrayParameters[:,8:12] + jph
3593 # phases = numpy.unwrap(phases)
3595 # phases = numpy.unwrap(phases)
3594 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
3596 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
3595
3597
3596 #Calculate Heights (Error N 13 and 14)
3598 #Calculate Heights (Error N 13 and 14)
3597 error = arrayParameters[:,-1]
3599 error = arrayParameters[:,-1]
3598 Ranges = arrayParameters[:,1]
3600 Ranges = arrayParameters[:,1]
3599 zenith = arrayParameters[:,4]
3601 zenith = arrayParameters[:,4]
3600 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
3602 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
3601
3603
3602 #----------------------- Get Final data ------------------------------------
3604 #----------------------- Get Final data ------------------------------------
3603 # error = arrayParameters[:,-1]
3605 # error = arrayParameters[:,-1]
3604 # ind1 = numpy.where(error==0)[0]
3606 # ind1 = numpy.where(error==0)[0]
3605 # arrayParameters = arrayParameters[ind1,:]
3607 # arrayParameters = arrayParameters[ind1,:]
3606
3608
3607 return arrayParameters
3609 return arrayParameters
3608
3610
3609 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
3611 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
3610
3612
3611 arrayAOA = numpy.zeros((phases.shape[0],3))
3613 arrayAOA = numpy.zeros((phases.shape[0],3))
3612 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
3614 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
3613
3615
3614 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3616 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3615 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3617 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3616 arrayAOA[:,2] = cosDirError
3618 arrayAOA[:,2] = cosDirError
3617
3619
3618 azimuthAngle = arrayAOA[:,0]
3620 azimuthAngle = arrayAOA[:,0]
3619 zenithAngle = arrayAOA[:,1]
3621 zenithAngle = arrayAOA[:,1]
3620
3622
3621 #Setting Error
3623 #Setting Error
3622 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
3624 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
3623 error[indError] = 0
3625 error[indError] = 0
3624 #Number 3: AOA not fesible
3626 #Number 3: AOA not fesible
3625 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3627 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3626 error[indInvalid] = 3
3628 error[indInvalid] = 3
3627 #Number 4: Large difference in AOAs obtained from different antenna baselines
3629 #Number 4: Large difference in AOAs obtained from different antenna baselines
3628 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3630 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3629 error[indInvalid] = 4
3631 error[indInvalid] = 4
3630 return arrayAOA, error
3632 return arrayAOA, error
3631
3633
3632 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
3634 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
3633
3635
3634 #Initializing some variables
3636 #Initializing some variables
3635 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3637 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3636 ang_aux = ang_aux.reshape(1,ang_aux.size)
3638 ang_aux = ang_aux.reshape(1,ang_aux.size)
3637
3639
3638 cosdir = numpy.zeros((arrayPhase.shape[0],2))
3640 cosdir = numpy.zeros((arrayPhase.shape[0],2))
3639 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3641 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3640
3642
3641
3643
3642 for i in range(2):
3644 for i in range(2):
3643 ph0 = arrayPhase[:,pairsList[i][0]]
3645 ph0 = arrayPhase[:,pairsList[i][0]]
3644 ph1 = arrayPhase[:,pairsList[i][1]]
3646 ph1 = arrayPhase[:,pairsList[i][1]]
3645 d0 = distances[pairsList[i][0]]
3647 d0 = distances[pairsList[i][0]]
3646 d1 = distances[pairsList[i][1]]
3648 d1 = distances[pairsList[i][1]]
3647
3649
3648 ph0_aux = ph0 + ph1
3650 ph0_aux = ph0 + ph1
3649 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
3651 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
3650 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
3652 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
3651 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
3653 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
3652 #First Estimation
3654 #First Estimation
3653 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
3655 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
3654
3656
3655 #Most-Accurate Second Estimation
3657 #Most-Accurate Second Estimation
3656 phi1_aux = ph0 - ph1
3658 phi1_aux = ph0 - ph1
3657 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3659 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3658 #Direction Cosine 1
3660 #Direction Cosine 1
3659 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
3661 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
3660
3662
3661 #Searching the correct Direction Cosine
3663 #Searching the correct Direction Cosine
3662 cosdir0_aux = cosdir0[:,i]
3664 cosdir0_aux = cosdir0[:,i]
3663 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3665 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3664 #Minimum Distance
3666 #Minimum Distance
3665 cosDiff = (cosdir1 - cosdir0_aux)**2
3667 cosDiff = (cosdir1 - cosdir0_aux)**2
3666 indcos = cosDiff.argmin(axis = 1)
3668 indcos = cosDiff.argmin(axis = 1)
3667 #Saving Value obtained
3669 #Saving Value obtained
3668 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3670 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3669
3671
3670 return cosdir0, cosdir
3672 return cosdir0, cosdir
3671
3673
3672 def __calculateAOA(self, cosdir, azimuth):
3674 def __calculateAOA(self, cosdir, azimuth):
3673 cosdirX = cosdir[:,0]
3675 cosdirX = cosdir[:,0]
3674 cosdirY = cosdir[:,1]
3676 cosdirY = cosdir[:,1]
3675
3677
3676 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3678 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3677 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
3679 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
3678 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3680 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3679
3681
3680 return angles
3682 return angles
3681
3683
3682 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3684 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3683
3685
3684 Ramb = 375 #Ramb = c/(2*PRF)
3686 Ramb = 375 #Ramb = c/(2*PRF)
3685 Re = 6371 #Earth Radius
3687 Re = 6371 #Earth Radius
3686 heights = numpy.zeros(Ranges.shape)
3688 heights = numpy.zeros(Ranges.shape)
3687
3689
3688 R_aux = numpy.array([0,1,2])*Ramb
3690 R_aux = numpy.array([0,1,2])*Ramb
3689 R_aux = R_aux.reshape(1,R_aux.size)
3691 R_aux = R_aux.reshape(1,R_aux.size)
3690
3692
3691 Ranges = Ranges.reshape(Ranges.size,1)
3693 Ranges = Ranges.reshape(Ranges.size,1)
3692
3694
3693 Ri = Ranges + R_aux
3695 Ri = Ranges + R_aux
3694 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3696 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3695
3697
3696 #Check if there is a height between 70 and 110 km
3698 #Check if there is a height between 70 and 110 km
3697 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3699 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3698 ind_h = numpy.where(h_bool == 1)[0]
3700 ind_h = numpy.where(h_bool == 1)[0]
3699
3701
3700 hCorr = hi[ind_h, :]
3702 hCorr = hi[ind_h, :]
3701 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3703 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3702
3704
3703 hCorr = hi[ind_hCorr][:len(ind_h)]
3705 hCorr = hi[ind_hCorr][:len(ind_h)]
3704 heights[ind_h] = hCorr
3706 heights[ind_h] = hCorr
3705
3707
3706 #Setting Error
3708 #Setting Error
3707 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3709 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3708 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3710 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3709 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
3711 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
3710 error[indError] = 0
3712 error[indError] = 0
3711 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3713 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3712 error[indInvalid2] = 14
3714 error[indInvalid2] = 14
3713 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3715 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3714 error[indInvalid1] = 13
3716 error[indInvalid1] = 13
3715
3717
3716 return heights, error
3718 return heights, error
3717
3719
3718 def getPhasePairs(self, channelPositions):
3720 def getPhasePairs(self, channelPositions):
3719 chanPos = numpy.array(channelPositions)
3721 chanPos = numpy.array(channelPositions)
3720 listOper = list(itertools.combinations(list(range(5)),2))
3722 listOper = list(itertools.combinations(list(range(5)),2))
3721
3723
3722 distances = numpy.zeros(4)
3724 distances = numpy.zeros(4)
3723 axisX = []
3725 axisX = []
3724 axisY = []
3726 axisY = []
3725 distX = numpy.zeros(3)
3727 distX = numpy.zeros(3)
3726 distY = numpy.zeros(3)
3728 distY = numpy.zeros(3)
3727 ix = 0
3729 ix = 0
3728 iy = 0
3730 iy = 0
3729
3731
3730 pairX = numpy.zeros((2,2))
3732 pairX = numpy.zeros((2,2))
3731 pairY = numpy.zeros((2,2))
3733 pairY = numpy.zeros((2,2))
3732
3734
3733 for i in range(len(listOper)):
3735 for i in range(len(listOper)):
3734 pairi = listOper[i]
3736 pairi = listOper[i]
3735
3737
3736 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
3738 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
3737
3739
3738 if posDif[0] == 0:
3740 if posDif[0] == 0:
3739 axisY.append(pairi)
3741 axisY.append(pairi)
3740 distY[iy] = posDif[1]
3742 distY[iy] = posDif[1]
3741 iy += 1
3743 iy += 1
3742 elif posDif[1] == 0:
3744 elif posDif[1] == 0:
3743 axisX.append(pairi)
3745 axisX.append(pairi)
3744 distX[ix] = posDif[0]
3746 distX[ix] = posDif[0]
3745 ix += 1
3747 ix += 1
3746
3748
3747 for i in range(2):
3749 for i in range(2):
3748 if i==0:
3750 if i==0:
3749 dist0 = distX
3751 dist0 = distX
3750 axis0 = axisX
3752 axis0 = axisX
3751 else:
3753 else:
3752 dist0 = distY
3754 dist0 = distY
3753 axis0 = axisY
3755 axis0 = axisY
3754
3756
3755 side = numpy.argsort(dist0)[:-1]
3757 side = numpy.argsort(dist0)[:-1]
3756 axis0 = numpy.array(axis0)[side,:]
3758 axis0 = numpy.array(axis0)[side,:]
3757 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
3759 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
3758 axis1 = numpy.unique(numpy.reshape(axis0,4))
3760 axis1 = numpy.unique(numpy.reshape(axis0,4))
3759 side = axis1[axis1 != chanC]
3761 side = axis1[axis1 != chanC]
3760 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
3762 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
3761 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
3763 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
3762 if diff1<0:
3764 if diff1<0:
3763 chan2 = side[0]
3765 chan2 = side[0]
3764 d2 = numpy.abs(diff1)
3766 d2 = numpy.abs(diff1)
3765 chan1 = side[1]
3767 chan1 = side[1]
3766 d1 = numpy.abs(diff2)
3768 d1 = numpy.abs(diff2)
3767 else:
3769 else:
3768 chan2 = side[1]
3770 chan2 = side[1]
3769 d2 = numpy.abs(diff2)
3771 d2 = numpy.abs(diff2)
3770 chan1 = side[0]
3772 chan1 = side[0]
3771 d1 = numpy.abs(diff1)
3773 d1 = numpy.abs(diff1)
3772
3774
3773 if i==0:
3775 if i==0:
3774 chanCX = chanC
3776 chanCX = chanC
3775 chan1X = chan1
3777 chan1X = chan1
3776 chan2X = chan2
3778 chan2X = chan2
3777 distances[0:2] = numpy.array([d1,d2])
3779 distances[0:2] = numpy.array([d1,d2])
3778 else:
3780 else:
3779 chanCY = chanC
3781 chanCY = chanC
3780 chan1Y = chan1
3782 chan1Y = chan1
3781 chan2Y = chan2
3783 chan2Y = chan2
3782 distances[2:4] = numpy.array([d1,d2])
3784 distances[2:4] = numpy.array([d1,d2])
3783 # axisXsides = numpy.reshape(axisX[ix,:],4)
3785 # axisXsides = numpy.reshape(axisX[ix,:],4)
3784 #
3786 #
3785 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
3787 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
3786 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
3788 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
3787 #
3789 #
3788 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
3790 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
3789 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
3791 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
3790 # channel25X = int(pairX[0,ind25X])
3792 # channel25X = int(pairX[0,ind25X])
3791 # channel20X = int(pairX[1,ind20X])
3793 # channel20X = int(pairX[1,ind20X])
3792 # ind25Y = numpy.where(pairY[0,:] != channelCentY)[0][0]
3794 # ind25Y = numpy.where(pairY[0,:] != channelCentY)[0][0]
3793 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
3795 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
3794 # channel25Y = int(pairY[0,ind25Y])
3796 # channel25Y = int(pairY[0,ind25Y])
3795 # channel20Y = int(pairY[1,ind20Y])
3797 # channel20Y = int(pairY[1,ind20Y])
3796
3798
3797 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
3799 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
3798 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
3800 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
3799
3801
3800 return pairslist, distances
3802 return pairslist, distances
3801 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
3803 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
3802 #
3804 #
3803 # arrayAOA = numpy.zeros((phases.shape[0],3))
3805 # arrayAOA = numpy.zeros((phases.shape[0],3))
3804 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
3806 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
3805 #
3807 #
3806 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3808 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3807 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3809 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3808 # arrayAOA[:,2] = cosDirError
3810 # arrayAOA[:,2] = cosDirError
3809 #
3811 #
3810 # azimuthAngle = arrayAOA[:,0]
3812 # azimuthAngle = arrayAOA[:,0]
3811 # zenithAngle = arrayAOA[:,1]
3813 # zenithAngle = arrayAOA[:,1]
3812 #
3814 #
3813 # #Setting Error
3815 # #Setting Error
3814 # #Number 3: AOA not fesible
3816 # #Number 3: AOA not fesible
3815 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3817 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3816 # error[indInvalid] = 3
3818 # error[indInvalid] = 3
3817 # #Number 4: Large difference in AOAs obtained from different antenna baselines
3819 # #Number 4: Large difference in AOAs obtained from different antenna baselines
3818 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3820 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3819 # error[indInvalid] = 4
3821 # error[indInvalid] = 4
3820 # return arrayAOA, error
3822 # return arrayAOA, error
3821 #
3823 #
3822 # def __getDirectionCosines(self, arrayPhase, pairsList):
3824 # def __getDirectionCosines(self, arrayPhase, pairsList):
3823 #
3825 #
3824 # #Initializing some variables
3826 # #Initializing some variables
3825 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3827 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3826 # ang_aux = ang_aux.reshape(1,ang_aux.size)
3828 # ang_aux = ang_aux.reshape(1,ang_aux.size)
3827 #
3829 #
3828 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
3830 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
3829 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3831 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3830 #
3832 #
3831 #
3833 #
3832 # for i in range(2):
3834 # for i in range(2):
3833 # #First Estimation
3835 # #First Estimation
3834 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
3836 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
3835 # #Dealias
3837 # #Dealias
3836 # indcsi = numpy.where(phi0_aux > numpy.pi)
3838 # indcsi = numpy.where(phi0_aux > numpy.pi)
3837 # phi0_aux[indcsi] -= 2*numpy.pi
3839 # phi0_aux[indcsi] -= 2*numpy.pi
3838 # indcsi = numpy.where(phi0_aux < -numpy.pi)
3840 # indcsi = numpy.where(phi0_aux < -numpy.pi)
3839 # phi0_aux[indcsi] += 2*numpy.pi
3841 # phi0_aux[indcsi] += 2*numpy.pi
3840 # #Direction Cosine 0
3842 # #Direction Cosine 0
3841 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
3843 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
3842 #
3844 #
3843 # #Most-Accurate Second Estimation
3845 # #Most-Accurate Second Estimation
3844 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
3846 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
3845 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3847 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3846 # #Direction Cosine 1
3848 # #Direction Cosine 1
3847 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
3849 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
3848 #
3850 #
3849 # #Searching the correct Direction Cosine
3851 # #Searching the correct Direction Cosine
3850 # cosdir0_aux = cosdir0[:,i]
3852 # cosdir0_aux = cosdir0[:,i]
3851 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3853 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3852 # #Minimum Distance
3854 # #Minimum Distance
3853 # cosDiff = (cosdir1 - cosdir0_aux)**2
3855 # cosDiff = (cosdir1 - cosdir0_aux)**2
3854 # indcos = cosDiff.argmin(axis = 1)
3856 # indcos = cosDiff.argmin(axis = 1)
3855 # #Saving Value obtained
3857 # #Saving Value obtained
3856 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3858 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3857 #
3859 #
3858 # return cosdir0, cosdir
3860 # return cosdir0, cosdir
3859 #
3861 #
3860 # def __calculateAOA(self, cosdir, azimuth):
3862 # def __calculateAOA(self, cosdir, azimuth):
3861 # cosdirX = cosdir[:,0]
3863 # cosdirX = cosdir[:,0]
3862 # cosdirY = cosdir[:,1]
3864 # cosdirY = cosdir[:,1]
3863 #
3865 #
3864 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3866 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3865 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
3867 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
3866 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3868 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3867 #
3869 #
3868 # return angles
3870 # return angles
3869 #
3871 #
3870 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3872 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3871 #
3873 #
3872 # Ramb = 375 #Ramb = c/(2*PRF)
3874 # Ramb = 375 #Ramb = c/(2*PRF)
3873 # Re = 6371 #Earth Radius
3875 # Re = 6371 #Earth Radius
3874 # heights = numpy.zeros(Ranges.shape)
3876 # heights = numpy.zeros(Ranges.shape)
3875 #
3877 #
3876 # R_aux = numpy.array([0,1,2])*Ramb
3878 # R_aux = numpy.array([0,1,2])*Ramb
3877 # R_aux = R_aux.reshape(1,R_aux.size)
3879 # R_aux = R_aux.reshape(1,R_aux.size)
3878 #
3880 #
3879 # Ranges = Ranges.reshape(Ranges.size,1)
3881 # Ranges = Ranges.reshape(Ranges.size,1)
3880 #
3882 #
3881 # Ri = Ranges + R_aux
3883 # Ri = Ranges + R_aux
3882 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3884 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3883 #
3885 #
3884 # #Check if there is a height between 70 and 110 km
3886 # #Check if there is a height between 70 and 110 km
3885 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3887 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3886 # ind_h = numpy.where(h_bool == 1)[0]
3888 # ind_h = numpy.where(h_bool == 1)[0]
3887 #
3889 #
3888 # hCorr = hi[ind_h, :]
3890 # hCorr = hi[ind_h, :]
3889 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3891 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3890 #
3892 #
3891 # hCorr = hi[ind_hCorr]
3893 # hCorr = hi[ind_hCorr]
3892 # heights[ind_h] = hCorr
3894 # heights[ind_h] = hCorr
3893 #
3895 #
3894 # #Setting Error
3896 # #Setting Error
3895 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3897 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3896 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3898 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3897 #
3899 #
3898 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3900 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3899 # error[indInvalid2] = 14
3901 # error[indInvalid2] = 14
3900 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3902 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3901 # error[indInvalid1] = 13
3903 # error[indInvalid1] = 13
3902 #
3904 #
3903 # return heights, error
3905 # return heights, error
3904
3906
3905
3907
3906 class WeatherRadar(Operation):
3908 class WeatherRadar(Operation):
3907 '''
3909 '''
3908 Function tat implements Weather Radar operations-
3910 Function tat implements Weather Radar operations-
3909 Input:
3911 Input:
3910 Output:
3912 Output:
3911 Parameters affected:
3913 Parameters affected:
3912 '''
3914 '''
3913 isConfig = False
3915 isConfig = False
3914
3916
3915 def __init__(self):
3917 def __init__(self):
3916 Operation.__init__(self)
3918 Operation.__init__(self)
3917
3919
3918 def setup(self,dataOut,Pt=0,Gt=0,Gr=0,lambda_=0, aL=0,
3920 def setup(self,dataOut,Pt=0,Gt=0,Gr=0,lambda_=0, aL=0,
3919 tauW= 0,thetaT=0,thetaR=0,Km =0):
3921 tauW= 0,thetaT=0,thetaR=0,Km =0):
3920 self.nCh = dataOut.nChannels
3922 self.nCh = dataOut.nChannels
3921 self.nHeis = dataOut.nHeights
3923 self.nHeis = dataOut.nHeights
3922 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
3924 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
3923 self.Range = numpy.arange(dataOut.nHeights)*deltaHeight + dataOut.heightList[0]
3925 self.Range = numpy.arange(dataOut.nHeights)*deltaHeight + dataOut.heightList[0]
3924 self.Range = self.Range.reshape(1,self.nHeis)
3926 self.Range = self.Range.reshape(1,self.nHeis)
3925 self.Range = numpy.tile(self.Range,[self.nCh,1])
3927 self.Range = numpy.tile(self.Range,[self.nCh,1])
3926 '''-----------1 Constante del Radar----------'''
3928 '''-----------1 Constante del Radar----------'''
3927 self.Pt = Pt
3929 self.Pt = Pt
3928 self.Gt = Gt
3930 self.Gt = Gt
3929 self.Gr = Gr
3931 self.Gr = Gr
3930 self.lambda_ = lambda_
3932 self.lambda_ = lambda_
3931 self.aL = aL
3933 self.aL = aL
3932 self.tauW = tauW
3934 self.tauW = tauW
3933 self.thetaT = thetaT
3935 self.thetaT = thetaT
3934 self.thetaR = thetaR
3936 self.thetaR = thetaR
3935 self.Km = Km
3937 self.Km = Km
3936 Numerator = ((4*numpy.pi)**3 * aL**2 * 16 *numpy.log(2))
3938 Numerator = ((4*numpy.pi)**3 * aL**2 * 16 *numpy.log(2))
3937 Denominator = (Pt * Gt * Gr * lambda_**2 * SPEED_OF_LIGHT * tauW * numpy.pi*thetaT*thetaR)
3939 Denominator = (Pt * Gt * Gr * lambda_**2 * SPEED_OF_LIGHT * tauW * numpy.pi*thetaT*thetaR)
3938 self.RadarConstant = Numerator/Denominator
3940 self.RadarConstant = Numerator/Denominator
3939 '''-----------2 Reflectividad del Radar y Factor de Reflectividad------'''
3941 '''-----------2 Reflectividad del Radar y Factor de Reflectividad------'''
3940 self.n_radar = numpy.zeros((self.nCh,self.nHeis))
3942 self.n_radar = numpy.zeros((self.nCh,self.nHeis))
3941 self.Z_radar = numpy.zeros((self.nCh,self.nHeis))
3943 self.Z_radar = numpy.zeros((self.nCh,self.nHeis))
3942
3944
3943 def setMoments(self,dataOut,i):
3945 def setMoments(self,dataOut,i):
3944
3946
3945 type = dataOut.inputUnit
3947 type = dataOut.inputUnit
3946 nCh = dataOut.nChannels
3948 nCh = dataOut.nChannels
3947 nHeis= dataOut.nHeights
3949 nHeis= dataOut.nHeights
3948 data_param = numpy.zeros((nCh,4,nHeis))
3950 data_param = numpy.zeros((nCh,4,nHeis))
3949 if type == "Voltage":
3951 if type == "Voltage":
3950 data_param[:,0,:] = dataOut.dataPP_POW/(dataOut.nCohInt**2)
3952 data_param[:,0,:] = dataOut.dataPP_POW/(dataOut.nCohInt**2)
3951 data_param[:,1,:] = dataOut.dataPP_DOP
3953 data_param[:,1,:] = dataOut.dataPP_DOP
3952 data_param[:,2,:] = dataOut.dataPP_WIDTH
3954 data_param[:,2,:] = dataOut.dataPP_WIDTH
3953 data_param[:,3,:] = dataOut.dataPP_SNR
3955 data_param[:,3,:] = dataOut.dataPP_SNR
3954 if type == "Spectra":
3956 if type == "Spectra":
3955 data_param[:,0,:] = dataOut.data_POW
3957 data_param[:,0,:] = dataOut.data_POW
3956 data_param[:,1,:] = dataOut.data_DOP
3958 data_param[:,1,:] = dataOut.data_DOP
3957 data_param[:,2,:] = dataOut.data_WIDTH
3959 data_param[:,2,:] = dataOut.data_WIDTH
3958 def setMoments(self,dataOut,i):
3960 def setMoments(self,dataOut,i):
3959 data_param[:,3,:] = dataOut.data_SNR
3961 data_param[:,3,:] = dataOut.data_SNR
3960
3962
3961 return data_param[:,i,:]
3963 return data_param[:,i,:]
3962
3964
3963
3965
3964 def run(self,dataOut,Pt=25,Gt=200.0,Gr=50.0,lambda_=0.32, aL=2.5118,
3966 def run(self,dataOut,Pt=25,Gt=200.0,Gr=50.0,lambda_=0.32, aL=2.5118,
3965 tauW= 4.0e-6,thetaT=0.165,thetaR=0.367,Km =0.93):
3967 tauW= 4.0e-6,thetaT=0.165,thetaR=0.367,Km =0.93):
3966
3968
3967 if not self.isConfig:
3969 if not self.isConfig:
3968 self.setup(dataOut= dataOut,Pt=25,Gt=200.0,Gr=50.0,lambda_=0.32, aL=2.5118,
3970 self.setup(dataOut= dataOut,Pt=25,Gt=200.0,Gr=50.0,lambda_=0.32, aL=2.5118,
3969 tauW= 4.0e-6,thetaT=0.165,thetaR=0.367,Km =0.93)
3971 tauW= 4.0e-6,thetaT=0.165,thetaR=0.367,Km =0.93)
3970 self.isConfig = True
3972 self.isConfig = True
3971 '''-----------------------------Potencia de Radar -Signal S-----------------------------'''
3973 '''-----------------------------Potencia de Radar -Signal S-----------------------------'''
3972 Pr = self.setMoments(dataOut,0)
3974 Pr = self.setMoments(dataOut,0)
3973
3975
3974 for R in range(self.nHeis):
3976 for R in range(self.nHeis):
3975 self.n_radar[:,R] = self.RadarConstant*Pr[:,R]* (self.Range[:,R])**2
3977 self.n_radar[:,R] = self.RadarConstant*Pr[:,R]* (self.Range[:,R])**2
3976
3978
3977 self.Z_radar[:,R] = self.n_radar[:,R]* self.lambda_**4/( numpy.pi**5 * self.Km**2)
3979 self.Z_radar[:,R] = self.n_radar[:,R]* self.lambda_**4/( numpy.pi**5 * self.Km**2)
3978
3980
3979 '''----------- Factor de Reflectividad Equivalente lamda_ < 10 cm , lamda_= 3.2cm-------'''
3981 '''----------- Factor de Reflectividad Equivalente lamda_ < 10 cm , lamda_= 3.2cm-------'''
3980 Zeh = self.Z_radar
3982 Zeh = self.Z_radar
3981 dBZeh = 10*numpy.log10(Zeh)
3983 dBZeh = 10*numpy.log10(Zeh)
3982 dataOut.factor_Zeh= dBZeh
3984 dataOut.factor_Zeh= dBZeh
3983 self.n_radar = numpy.zeros((self.nCh,self.nHeis))
3985 self.n_radar = numpy.zeros((self.nCh,self.nHeis))
3984 self.Z_radar = numpy.zeros((self.nCh,self.nHeis))
3986 self.Z_radar = numpy.zeros((self.nCh,self.nHeis))
3985
3987
3986 return dataOut
3988 return dataOut
3987
3989
3988 class PedestalInformation(Operation):
3990 class PedestalInformation(Operation):
3989 path_ped = None
3991 path_ped = None
3990 path_adq = None
3992 path_adq = None
3991 t_Interval_p = None
3993 t_Interval_p = None
3992 n_Muestras_p = None
3994 n_Muestras_p = None
3993 isConfig = False
3995 isConfig = False
3994 blocksPerfile= None
3996 blocksPerfile= None
3995 f_a_p = None
3997 f_a_p = None
3996 online = None
3998 online = None
3997 angulo_adq = None
3999 angulo_adq = None
3998 nro_file = None
4000 nro_file = None
3999 nro_key_p = None
4001 nro_key_p = None
4000 tmp = None
4002 tmp = None
4001
4003
4002
4004
4003 def __init__(self):
4005 def __init__(self):
4004 Operation.__init__(self)
4006 Operation.__init__(self)
4005
4007
4006 def getfirstFilefromPath(self,path,meta,ext):
4008 def getfirstFilefromPath(self,path,meta,ext):
4007 validFilelist = []
4009 validFilelist = []
4008 #print("SEARH",path)
4010 #print("SEARH",path)
4009 try:
4011 try:
4010 fileList = os.listdir(path)
4012 fileList = os.listdir(path)
4011 except:
4013 except:
4012 print("check path - fileList")
4014 print("check path - fileList")
4013 if len(fileList)<1:
4015 if len(fileList)<1:
4014 return None
4016 return None
4015 # meta 1234 567 8-18 BCDE
4017 # meta 1234 567 8-18 BCDE
4016 # H,D,PE YYYY DDD EPOC .ext
4018 # H,D,PE YYYY DDD EPOC .ext
4017
4019
4018 for thisFile in fileList:
4020 for thisFile in fileList:
4019 #print("HI",thisFile)
4021 #print("HI",thisFile)
4020 if meta =="PE":
4022 if meta =="PE":
4021 try:
4023 try:
4022 number= int(thisFile[len(meta)+7:len(meta)+17])
4024 number= int(thisFile[len(meta)+7:len(meta)+17])
4023 except:
4025 except:
4024 print("There is a file or folder with different format")
4026 print("There is a file or folder with different format")
4025 if meta == "D":
4027 if meta == "D":
4026 try:
4028 try:
4027 number= int(thisFile[8:11])
4029 number= int(thisFile[8:11])
4028 except:
4030 except:
4029 print("There is a file or folder with different format")
4031 print("There is a file or folder with different format")
4030
4032
4031 if not isNumber(str=number):
4033 if not isNumber(str=number):
4032 continue
4034 continue
4033 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
4035 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
4034 continue
4036 continue
4035 validFilelist.sort()
4037 validFilelist.sort()
4036 validFilelist.append(thisFile)
4038 validFilelist.append(thisFile)
4037 if len(validFilelist)>0:
4039 if len(validFilelist)>0:
4038 validFilelist = sorted(validFilelist,key=str.lower)
4040 validFilelist = sorted(validFilelist,key=str.lower)
4039 return validFilelist
4041 return validFilelist
4040 return None
4042 return None
4041
4043
4042 def gettimeutcfromDirFilename(self,path,file):
4044 def gettimeutcfromDirFilename(self,path,file):
4043 dir_file= path+"/"+file
4045 dir_file= path+"/"+file
4044 fp = h5py.File(dir_file,'r')
4046 fp = h5py.File(dir_file,'r')
4045 #epoc = fp['Metadata'].get('utctimeInit')[()]
4047 #epoc = fp['Metadata'].get('utctimeInit')[()]
4046 epoc = fp['Data'].get('utc')[()]
4048 epoc = fp['Data'].get('utc')[()]
4047 fp.close()
4049 fp.close()
4048 return epoc
4050 return epoc
4049
4051
4050 def gettimeutcadqfromDirFilename(self,path,file):
4052 def gettimeutcadqfromDirFilename(self,path,file):
4051 dir_file= path+"/"+file
4053 dir_file= path+"/"+file
4052 fp = h5py.File(dir_file,'r')
4054 fp = h5py.File(dir_file,'r')
4053 epoc = fp['Metadata'].get('utctimeInit')[()]
4055 epoc = fp['Metadata'].get('utctimeInit')[()]
4054 #epoc = fp['Data'].get('utc')[()]
4056 #epoc = fp['Data'].get('utc')[()]
4055 fp.close()
4057 fp.close()
4056 return epoc
4058 return epoc
4057
4059
4058 def getDatavaluefromDirFilename(self,path,file,value):
4060 def getDatavaluefromDirFilename(self,path,file,value):
4059 dir_file= path+"/"+file
4061 dir_file= path+"/"+file
4060 fp = h5py.File(dir_file,'r')
4062 fp = h5py.File(dir_file,'r')
4061 array = fp['Data'].get(value)[()]
4063 array = fp['Data'].get(value)[()]
4062 fp.close()
4064 fp.close()
4063 return array
4065 return array
4064
4066
4065 def getFile_KeyP(self,list_pedestal,list_adq):
4067 def getFile_KeyP(self,list_pedestal,list_adq):
4066 print(list_pedestal)
4068 print(list_pedestal)
4067 print(list_adq)
4069 print(list_adq)
4068
4070
4069 def getNROFile(self,utc_adq,utc_ped_list):
4071 def getNROFile(self,utc_adq,utc_ped_list):
4070 c=0
4072 c=0
4071 print("insidegetNROFile")
4073 print("insidegetNROFile")
4072 print(utc_adq)
4074 print(utc_adq)
4073 print(len(utc_ped_list))
4075 print(len(utc_ped_list))
4074 for i in range(len(utc_ped_list)):
4076 for i in range(len(utc_ped_list)):
4075 if utc_adq>utc_ped_list[i]:
4077 if utc_adq>utc_ped_list[i]:
4076 #print("mayor")
4078 #print("mayor")
4077 #print("utc_ped_list",utc_ped_list[i])
4079 #print("utc_ped_list",utc_ped_list[i])
4078 c +=1
4080 c +=1
4079
4081
4080 return c-1,utc_ped_list[c-1],utc_ped_list[c]
4082 return c-1,utc_ped_list[c-1],utc_ped_list[c]
4081
4083
4082 def verificarNROFILE(self,dataOut,utc_ped,f_a_p,n_Muestras_p):
4084 def verificarNROFILE(self,dataOut,utc_ped,f_a_p,n_Muestras_p):
4083 var =int(f_a_p/n_Muestras_p)
4085 var =int(f_a_p/n_Muestras_p)
4084 flag=0
4086 flag=0
4085 for i in range(var):
4087 for i in range(var):
4086 if dataOut.utctime+i==utc_ped:
4088 if dataOut.utctime+i==utc_ped:
4087 flag==1
4089 flag==1
4088 break
4090 break
4089 return flag
4091 return flag
4090
4092
4091 def setup_offline(self,dataOut,list_pedestal,list_adq):
4093 #def setup_offline(self,dataOut,list_pedestal,list_adq):
4094 def setup_offline(self,dataOut,list_pedestal):
4095
4092 print("SETUP OFFLINE")
4096 print("SETUP OFFLINE")
4093 print(self.path_ped)
4097 print(self.path_ped)
4094 print(self.path_adq)
4098 #print(self.path_adq)
4095 print(len(self.list_pedestal))
4099 print(len(self.list_pedestal))
4096 print(len(self.list_adq))
4100 #print(len(self.list_adq))
4097 utc_ped_list=[]
4101 utc_ped_list=[]
4098 for i in range(len(self.list_pedestal)):
4102 for i in range(len(self.list_pedestal)):
4103 print(i)
4099 utc_ped_list.append(self.gettimeutcfromDirFilename(path=self.path_ped,file=self.list_pedestal[i]))
4104 utc_ped_list.append(self.gettimeutcfromDirFilename(path=self.path_ped,file=self.list_pedestal[i]))
4100
4105
4101 #utc_ped_list= utc_ped_list
4106 #utc_ped_list= utc_ped_list
4102 utc_adq = self.gettimeutcadqfromDirFilename(path=self.path_adq,file=self.list_adq[0])
4107 ###utc_adq = self.gettimeutcadqfromDirFilename(path=self.path_adq,file=self.list_adq[0])
4103 print("dios existe donde esta")
4108 print("dios existe donde esta")
4109
4104 #print("utc_ped_list",utc_ped_list)
4110 #print("utc_ped_list",utc_ped_list)
4105 print("utc_adq",utc_adq)
4111 ###print("utc_adq",utc_adq)
4106 # utc_adq_dataOut
4112 # utc_adq_dataOut
4107 utc_adq_dataOut =dataOut.utctime
4113 utc_adq_dataOut =dataOut.utctime
4108 print("Offline-utc_adq_dataout",utc_adq_dataOut)
4114 print("Offline-utc_adq_dataout",utc_adq_dataOut)
4109
4115
4110 nro_file,utc_ped,utc_ped_1 = self.getNROFile(utc_adq=utc_adq, utc_ped_list= utc_ped_list)
4116 nro_file,utc_ped,utc_ped_1 = self.getNROFile(utc_adq=utc_adq_dataOut, utc_ped_list= utc_ped_list)
4111
4117
4112 print("nro_file",nro_file,"utc_ped",utc_ped)
4118 print("nro_file",nro_file,"utc_ped",utc_ped)
4113 print("nro_file",i)
4119 print("nro_file",i)
4114 nro_key_p = int((utc_adq-utc_ped)/self.t_Interval_p)-1 # ojito al -1 estimado alex
4120 nro_key_p = int((utc_adq_dataOut-utc_ped)/self.t_Interval_p)-1 # ojito al -1 estimado alex
4115 print("nro_key_p",nro_key_p)
4121 print("nro_key_p",nro_key_p)
4116
4122
4117 ff_pedestal = self.list_pedestal[nro_file]
4123 ff_pedestal = self.list_pedestal[nro_file]
4118 #angulo = self.getDatavaluefromDirFilename(path=self.path_ped,file=ff_pedestal,value="azimuth")
4124 #angulo = self.getDatavaluefromDirFilename(path=self.path_ped,file=ff_pedestal,value="azimuth")
4119 angulo = self.getDatavaluefromDirFilename(path=self.path_ped,file=ff_pedestal,value="azi_pos")
4125 angulo = self.getDatavaluefromDirFilename(path=self.path_ped,file=ff_pedestal,value="azi_pos")
4120
4126
4121 print("utc_pedestal_init :",utc_ped+nro_key_p*self.t_Interval_p)
4127 print("utc_pedestal_init :",utc_ped+nro_key_p*self.t_Interval_p)
4122 print("angulo_array :",angulo[nro_key_p])
4128 print("angulo_array :",angulo[nro_key_p])
4123 self.nro_file = nro_file
4129 self.nro_file = nro_file
4124 self.nro_key_p = nro_key_p
4130 self.nro_key_p = nro_key_p
4125
4131
4126 def setup_online(self,dataOut):
4132 def setup_online(self,dataOut):
4127 utc_adq =dataOut.utctime
4133 utc_adq =dataOut.utctime
4128 print("Online-utc_adq",utc_adq)
4134 print("Online-utc_adq",utc_adq)
4129 print(len(self.list_pedestal))
4135 print(len(self.list_pedestal))
4130 utc_ped_list=[]
4136 utc_ped_list=[]
4131 for i in range(len(self.list_pedestal)):
4137 for i in range(len(self.list_pedestal)):
4132 utc_ped_list.append(self.gettimeutcfromDirFilename(path=self.path_ped,file=self.list_pedestal[i]))
4138 utc_ped_list.append(self.gettimeutcfromDirFilename(path=self.path_ped,file=self.list_pedestal[i]))
4133 print(utc_ped_list[:20])
4139 print(utc_ped_list[:20])
4134 #print(utc_ped_list[488:498])
4140 #print(utc_ped_list[488:498])
4135 print("ultimo UTC-PEDESTAL",utc_ped_list[-1])
4141 print("ultimo UTC-PEDESTAL",utc_ped_list[-1])
4136 nro_file,utc_ped,utc_ped_1 = self.getNROFile(utc_adq=utc_adq, utc_ped_list= utc_ped_list)
4142 nro_file,utc_ped,utc_ped_1 = self.getNROFile(utc_adq=utc_adq, utc_ped_list= utc_ped_list)
4137 print("nro_file",nro_file,"utc_ped",utc_ped,"utc_ped_1",utc_ped_1)
4143 print("nro_file",nro_file,"utc_ped",utc_ped,"utc_ped_1",utc_ped_1)
4138 print("name_PEDESTAL",self.list_pedestal[nro_file])
4144 print("name_PEDESTAL",self.list_pedestal[nro_file])
4139 nro_key_p = int((utc_adq-utc_ped)/self.t_Interval_p)-1
4145 nro_key_p = int((utc_adq-utc_ped)/self.t_Interval_p)-1
4140 print("nro_key_p",nro_key_p)
4146 print("nro_key_p",nro_key_p)
4141 ff_pedestal = self.list_pedestal[nro_file]
4147 ff_pedestal = self.list_pedestal[nro_file]
4142 #angulo = self.getDatavaluefromDirFilename(path=self.path_ped,file=ff_pedestal,value="azimuth")
4148 #angulo = self.getDatavaluefromDirFilename(path=self.path_ped,file=ff_pedestal,value="azimuth")
4143 angulo = self.getDatavaluefromDirFilename(path=self.path_ped,file=ff_pedestal,value="azi_pos")
4149 angulo = self.getDatavaluefromDirFilename(path=self.path_ped,file=ff_pedestal,value="azi_pos")
4144
4150
4145 print("utc_pedestal_init :",utc_ped+nro_key_p*self.t_Interval_p)
4151 print("utc_pedestal_init :",utc_ped+nro_key_p*self.t_Interval_p)
4146 print("angulo_array :",angulo[nro_key_p])
4152 print("angulo_array :",angulo[nro_key_p])
4147 self.nro_file = nro_file
4153 self.nro_file = nro_file
4148 self.nro_key_p = nro_key_p
4154 self.nro_key_p = nro_key_p
4149
4155
4150 def setup(self,dataOut,path_ped,path_adq,t_Interval_p,n_Muestras_p,blocksPerfile,f_a_p,online):
4156 #def setup(self,dataOut,path_ped,path_adq,t_Interval_p,n_Muestras_p,blocksPerfile,f_a_p,online):
4157 def setup(self,dataOut,path_ped,t_Interval_p,n_Muestras_p,blocksPerfile,f_a_p,online):
4158 print("SETUP PEDESTAL")
4151 self.__dataReady = False
4159 self.__dataReady = False
4152 self.path_ped = path_ped
4160 self.path_ped = path_ped
4153 self.path_adq = path_adq
4161 #self.path_adq = path_adq
4154 self.t_Interval_p = t_Interval_p
4162 self.t_Interval_p = t_Interval_p
4155 self.n_Muestras_p = n_Muestras_p
4163 self.n_Muestras_p = n_Muestras_p
4156 self.blocksPerfile= blocksPerfile
4164 self.blocksPerfile= blocksPerfile
4157 self.f_a_p = f_a_p
4165 self.f_a_p = f_a_p
4158 self.online = online
4166 self.online = online
4159 self.angulo_adq = numpy.zeros(self.blocksPerfile)
4167 self.angulo_adq = numpy.zeros(self.blocksPerfile)
4160 self.__profIndex = 0
4168 self.__profIndex = 0
4161 self.tmp = 0
4169 self.tmp = 0
4162 self.c_ped = 0
4170 self.c_ped = 0
4163 print(self.path_ped)
4171 print(self.path_ped)
4164 print(self.path_adq)
4172 #print(self.path_adq)
4165 self.list_pedestal = self.getfirstFilefromPath(path=self.path_ped,meta="PE",ext=".hdf5")
4173 self.list_pedestal = self.getfirstFilefromPath(path=self.path_ped,meta="PE",ext=".hdf5")
4166 print("LIST NEW", self.list_pedestal[:20])
4174 print("LIST NEW", self.list_pedestal[:20])
4167 self.list_adq = self.getfirstFilefromPath(path=self.path_adq,meta="D",ext=".hdf5")
4175 #self.list_adq = self.getfirstFilefromPath(path=self.path_adq,meta="D",ext=".hdf5")
4168 print("*************Longitud list pedestal****************",len(self.list_pedestal))
4176 print("*************Longitud list pedestal****************",len(self.list_pedestal))
4169
4177
4170 if self.online:
4178 if self.online:
4171 print("Enable Online")
4179 print("Enable Online")
4172 self.setup_online(dataOut)
4180 self.setup_online(dataOut)
4173 else:
4181 else:
4174 self.setup_offline(dataOut,list_pedestal=self.list_pedestal,list_adq=self.list_adq)
4182 #self.setup_offline(dataOut,list_pedestal=self.list_pedestal,list_adq=self.list_adq)
4183 self.setup_offline(dataOut,list_pedestal=self.list_pedestal)
4184
4175
4185
4176 def setNextFileP(self,dataOut):
4186 def setNextFileP(self,dataOut):
4177 if self.online:
4187 if self.online:
4178 data_pedestal = self.setNextFileonline()
4188 data_pedestal = self.setNextFileonline()
4179 else:
4189 else:
4180 data_pedestal = self.setNextFileoffline(dataOut)
4190 data_pedestal = self.setNextFileoffline(dataOut)
4181
4191
4182 return data_pedestal
4192 return data_pedestal
4183
4193
4184
4194
4185 def setNextFileoffline(self,dataOut):
4195 def setNextFileoffline(self,dataOut):
4186 ##tmp=0
4196 ##tmp=0
4187 for j in range(self.blocksPerfile):
4197 for j in range(self.blocksPerfile):
4188 ###print("NUMERO DEL BLOQUE---->",j)
4198 ###print("NUMERO DEL BLOQUE---->",j)
4189 ###print("nro_key_p",self.nro_key_p)
4199 ###print("nro_key_p",self.nro_key_p)
4190
4200
4191 #iterador = self.nro_key_p +self.f_a_p*(j-tmp)
4201 #iterador = self.nro_key_p +self.f_a_p*(j-tmp)
4192 iterador = self.nro_key_p +self.f_a_p*self.c_ped
4202 iterador = self.nro_key_p +self.f_a_p*self.c_ped
4193 self.c_ped = self.c_ped +1
4203 self.c_ped = self.c_ped +1
4194
4204
4195 ###print("iterador------------->",iterador)
4205 print("iterador------------->",iterador)
4196 if iterador < self.n_Muestras_p:
4206 if iterador < self.n_Muestras_p:
4197 self.nro_file = self.nro_file
4207 self.nro_file = self.nro_file
4198 else:
4208 else:
4199 self.nro_file = self.nro_file+1
4209 self.nro_file = self.nro_file+1
4200 print("PRUEBA-------------")
4210 print("PRUEBA-------------")
4201 utc_ped_setnext=self.gettimeutcfromDirFilename(path=self.path_ped,file=self.list_pedestal[self.nro_file])
4211 utc_ped_setnext=self.gettimeutcfromDirFilename(path=self.path_ped,file=self.list_pedestal[self.nro_file])
4202 utc_adq_setnext=dataOut.utctime
4212 utc_adq_setnext=dataOut.utctime
4203 print("utc_pedestal",utc_ped_setnext)
4213 print("utc_pedestal",utc_ped_setnext)
4204 print("utc_adq",utc_adq_setnext)
4214 print("utc_adq",utc_adq_setnext)
4205
4215
4216 print("self.c_ped",self.c_ped)
4217 #dif = self.blocksPerfile-(self.nro_key_p+self.f_a_p*(self.c_ped-2))
4218 dif = self.n_Muestras_p-(self.nro_key_p+self.f_a_p*(self.c_ped-2))
4206
4219
4207 dif = self.blocksPerfile-(self.nro_key_p+self.f_a_p*(self.c_ped-2))
4208 self.c_ped = 1
4220 self.c_ped = 1
4209 ##tmp = j
4221 ##tmp = j
4210 ##print("tmp else",tmp)
4222 ##print("tmp else",tmp)
4211 self.nro_key_p= self.f_a_p-dif
4223 self.nro_key_p= self.f_a_p-dif
4212 iterador = self.nro_key_p
4224 iterador = self.nro_key_p
4213 ###print("iterador else",iterador)
4225 print("iterador else",iterador)
4214 #self.c_ped = self.c_ped +1
4226 #self.c_ped = self.c_ped +1
4215
4227
4216 ###print("nro_file",self.nro_file)
4228 print("nro_file",self.nro_file)
4217 #print("tmp",tmp)
4229 #print("tmp",tmp)
4218 try:
4230 try:
4219 ff_pedestal = self.list_pedestal[self.nro_file]
4231 ff_pedestal = self.list_pedestal[self.nro_file]
4220 print("ff_pedestal",ff_pedestal)
4232 print("ff_pedestal",ff_pedestal)
4221 except:
4233 except:
4222 print("############# EXCEPCION ######################")
4234 print("############# EXCEPCION ######################")
4223 return numpy.ones(self.blocksPerfile)*numpy.nan
4235 return numpy.ones(self.blocksPerfile)*numpy.nan
4224
4236
4225 #angulo = self.getDatavaluefromDirFilename(path=self.path_ped,file=ff_pedestal,value="azimuth")
4237 #angulo = self.getDatavaluefromDirFilename(path=self.path_ped,file=ff_pedestal,value="azimuth")
4226 angulo = self.getDatavaluefromDirFilename(path=self.path_ped,file=ff_pedestal,value="azi_pos")
4238 angulo = self.getDatavaluefromDirFilename(path=self.path_ped,file=ff_pedestal,value="azi_pos")
4227
4239
4228 self.angulo_adq[j]= angulo[iterador]
4240 self.angulo_adq[j]= angulo[iterador]
4229
4241
4230 return self.angulo_adq
4242 return self.angulo_adq
4231
4243
4232 def setNextFileonline(self):
4244 def setNextFileonline(self):
4233 tmp = 0
4245 tmp = 0
4234 self.nTries_p = 3
4246 self.nTries_p = 3
4235 self.delay = 3
4247 self.delay = 3
4236 ready = 1
4248 ready = 1
4237 for j in range(self.blocksPerfile):
4249 for j in range(self.blocksPerfile):
4238 iterador = self.nro_key_p +self.f_a_p*(j-tmp)
4250 iterador = self.nro_key_p +self.f_a_p*(j-tmp)
4239 if iterador < self.n_Muestras_p:
4251 if iterador < self.n_Muestras_p:
4240 self.nro_file = self.nro_file
4252 self.nro_file = self.nro_file
4241 else:
4253 else:
4242 self.nro_file = self.nro_file+1
4254 self.nro_file = self.nro_file+1
4243 dif = self.blocksPerfile-(self.nro_key_p+self.f_a_p*(j-tmp-1))
4255 dif = self.blocksPerfile-(self.nro_key_p+self.f_a_p*(j-tmp-1))
4244 tmp = j
4256 tmp = j
4245 self.nro_key_p= self.f_a_p-dif
4257 self.nro_key_p= self.f_a_p-dif
4246 iterador = self.nro_key_p
4258 iterador = self.nro_key_p
4247 #print("nro_file---------------- :",self.nro_file)
4259 #print("nro_file---------------- :",self.nro_file)
4248 try:
4260 try:
4249 # update list_pedestal
4261 # update list_pedestal
4250 self.list_pedestal = self.getfirstFilefromPath(path=self.path_ped,meta="PE",ext=".hdf5")
4262 self.list_pedestal = self.getfirstFilefromPath(path=self.path_ped,meta="PE",ext=".hdf5")
4251 ff_pedestal = self.list_pedestal[self.nro_file]
4263 ff_pedestal = self.list_pedestal[self.nro_file]
4252 except:
4264 except:
4253 ff_pedestal = None
4265 ff_pedestal = None
4254 ready = 0
4266 ready = 0
4255 for nTries_p in range(self.nTries_p):
4267 for nTries_p in range(self.nTries_p):
4256 try:
4268 try:
4257 # update list_pedestal
4269 # update list_pedestal
4258 self.list_pedestal = self.getfirstFilefromPath(path=self.path_ped,meta="PE",ext=".hdf5")
4270 self.list_pedestal = self.getfirstFilefromPath(path=self.path_ped,meta="PE",ext=".hdf5")
4259 ff_pedestal = self.list_pedestal[self.nro_file]
4271 ff_pedestal = self.list_pedestal[self.nro_file]
4260 except:
4272 except:
4261 ff_pedestal = None
4273 ff_pedestal = None
4262 if ff_pedestal is not None:
4274 if ff_pedestal is not None:
4263 ready=1
4275 ready=1
4264 break
4276 break
4265 log.warning("Waiting %0.2f sec for the next file: \"%s\" , try %02d ..." % (self.delay, self.nro_file, nTries_p + 1))
4277 log.warning("Waiting %0.2f sec for the next file: \"%s\" , try %02d ..." % (self.delay, self.nro_file, nTries_p + 1))
4266 time.sleep(self.delay)
4278 time.sleep(self.delay)
4267 continue
4279 continue
4268 #return numpy.ones(self.blocksPerfile)*numpy.nan
4280 #return numpy.ones(self.blocksPerfile)*numpy.nan
4269
4281
4270 if ready == 1:
4282 if ready == 1:
4271 #angulo = self.getDatavaluefromDirFilename(path=self.path_ped,file=ff_pedestal,value="azimuth")
4283 #angulo = self.getDatavaluefromDirFilename(path=self.path_ped,file=ff_pedestal,value="azimuth")
4272 angulo = self.getDatavaluefromDirFilename(path=self.path_ped,file=ff_pedestal,value="azi_pos")
4284 angulo = self.getDatavaluefromDirFilename(path=self.path_ped,file=ff_pedestal,value="azi_pos")
4273
4285
4274 else:
4286 else:
4275 print("there is no pedestal file")
4287 print("there is no pedestal file")
4276 angulo = numpy.ones(self.n_Muestras_p)*numpy.nan
4288 angulo = numpy.ones(self.n_Muestras_p)*numpy.nan
4277 self.angulo_adq[j]= angulo[iterador]
4289 self.angulo_adq[j]= angulo[iterador]
4278 ####print("Angulo",self.angulo_adq)
4290 ####print("Angulo",self.angulo_adq)
4279 ####print("Angulo",len(self.angulo_adq))
4291 ####print("Angulo",len(self.angulo_adq))
4280 #self.nro_key_p=iterador + self.f_a_p
4292 #self.nro_key_p=iterador + self.f_a_p
4281 #if self.nro_key_p< self.n_Muestras_p:
4293 #if self.nro_key_p< self.n_Muestras_p:
4282 # self.nro_file = self.nro_file
4294 # self.nro_file = self.nro_file
4283 #else:
4295 #else:
4284 # self.nro_file = self.nro_file+1
4296 # self.nro_file = self.nro_file+1
4285 # self.nro_key_p= self.nro_key_p
4297 # self.nro_key_p= self.nro_key_p
4286 return self.angulo_adq
4298 return self.angulo_adq
4287
4299
4288
4300
4289 def run(self, dataOut,path_ped,path_adq,t_Interval_p,n_Muestras_p,blocksPerfile,f_a_p,online):
4301 #def run(self, dataOut,path_ped,path_adq,t_Interval_p,n_Muestras_p,blocksPerfile,f_a_p,online):
4302 def run(self, dataOut,path_ped,t_Interval_p,n_Muestras_p,blocksPerfile,f_a_p,online):
4303
4290 if not self.isConfig:
4304 if not self.isConfig:
4291 print("######################SETUP#########################################")
4305 print("######################SETUP#########################################")
4292 self.setup( dataOut, path_ped,path_adq,t_Interval_p,n_Muestras_p,blocksPerfile,f_a_p,online)
4306 #self.setup( dataOut, path_ped,path_adq,t_Interval_p,n_Muestras_p,blocksPerfile,f_a_p,online)
4307 self.setup( dataOut, path_ped,t_Interval_p,n_Muestras_p,blocksPerfile,f_a_p,online)
4293 self.isConfig = True
4308 self.isConfig = True
4294
4309
4295 dataOut.flagNoData = True
4310 dataOut.flagNoData = True
4296 #print("profIndex",self.__profIndex)
4311 print("profIndex",self.__profIndex)
4297
4312
4298 if self.__profIndex==0:
4313 if self.__profIndex==0:
4299 angulo_adq = self.setNextFileP(dataOut)
4314 angulo_adq = self.setNextFileP(dataOut)
4300 dataOut.azimuth = angulo_adq
4315 dataOut.azimuth = angulo_adq
4301 print("TIEMPO:",dataOut.utctime)
4316 print("TIEMPO:",dataOut.utctime)
4302 ##print("####################################################################")
4317 ##print("####################################################################")
4303 ##print("angulos",dataOut.azimuth,len(dataOut.azimuth))
4318 print("angulos",dataOut.azimuth,len(dataOut.azimuth))
4304 self.__dataReady = True
4319 self.__dataReady = True
4305 self.__profIndex += 1
4320 self.__profIndex += 1
4306 print("TIEMPO_bucle:",dataOut.utctime)
4321 print("TIEMPO_bucle:",dataOut.utctime)
4322 print("profIndex",self.__profIndex)
4307 if self.__profIndex== blocksPerfile:
4323 if self.__profIndex== blocksPerfile:
4308 self.__profIndex = 0
4324 self.__profIndex = 0
4309 if self.__dataReady:
4325 if self.__dataReady:
4310 #print(self.__profIndex,dataOut.azimuth[:10])
4326 #print(self.__profIndex,dataOut.azimuth[:10])
4311 dataOut.flagNoData = False
4327 dataOut.flagNoData = False
4312 return dataOut
4328 return dataOut
4313
4329
4314
4330
4315 class Block360(Operation):
4331 class Block360(Operation):
4316 '''
4332 '''
4317 '''
4333 '''
4318 isConfig = False
4334 isConfig = False
4319 __profIndex = 0
4335 __profIndex = 0
4320 __initime = None
4336 __initime = None
4321 __lastdatatime = None
4337 __lastdatatime = None
4322 __buffer = None
4338 __buffer = None
4323 __dataReady = False
4339 __dataReady = False
4324 n = None
4340 n = None
4325 __nch = 0
4341 __nch = 0
4326 __nHeis = 0
4342 __nHeis = 0
4327 index = 0
4343 index = 0
4344 mode = 0
4328
4345
4329 def __init__(self,**kwargs):
4346 def __init__(self,**kwargs):
4330 Operation.__init__(self,**kwargs)
4347 Operation.__init__(self,**kwargs)
4331
4348
4332 def setup(self, dataOut, n = None):
4349 def setup(self, dataOut, n = None, mode = None):
4333 '''
4350 '''
4334 n= Numero de PRF's de entrada
4351 n= Numero de PRF's de entrada
4335 '''
4352 '''
4336 self.__initime = None
4353 self.__initime = None
4337 self.__lastdatatime = 0
4354 self.__lastdatatime = 0
4338 self.__dataReady = False
4355 self.__dataReady = False
4339 self.__buffer = 0
4356 self.__buffer = 0
4340 self.__buffer_1D = 0
4357 self.__buffer_1D = 0
4341 self.__profIndex = 0
4358 self.__profIndex = 0
4342 self.index = 0
4359 self.index = 0
4343 self.__nch = dataOut.nChannels
4360 self.__nch = dataOut.nChannels
4344 self.__nHeis = dataOut.nHeights
4361 self.__nHeis = dataOut.nHeights
4345 ##print("ELVALOR DE n es:", n)
4362 ##print("ELVALOR DE n es:", n)
4346 if n == None:
4363 if n == None:
4347 raise ValueError("n should be specified.")
4364 raise ValueError("n should be specified.")
4348
4365
4366 if mode == None:
4367 raise ValueError("mode should be specified.")
4368
4349 if n != None:
4369 if n != None:
4350 if n<1:
4370 if n<1:
4351 print("n should be greater than 2")
4371 print("n should be greater than 2")
4352 raise ValueError("n should be greater than 2")
4372 raise ValueError("n should be greater than 2")
4353
4373
4354 self.n = n
4374 self.n = n
4375 self.mode = mode
4376 print("self.mode",self.mode)
4355 #print("nHeights")
4377 #print("nHeights")
4356 self.__buffer = numpy.zeros(( dataOut.nChannels,n, dataOut.nHeights))
4378 self.__buffer = numpy.zeros(( dataOut.nChannels,n, dataOut.nHeights))
4357 self.__buffer2= numpy.zeros(n)
4379 self.__buffer2= numpy.zeros(n)
4358
4380
4359 def putData(self,data):
4381 def putData(self,data,mode):
4360 '''
4382 '''
4361 Add a profile to he __buffer and increase in one the __profiel Index
4383 Add a profile to he __buffer and increase in one the __profiel Index
4362 '''
4384 '''
4363 #print("line 4049",data.dataPP_POW.shape,data.dataPP_POW[:10])
4385 #print("line 4049",data.dataPP_POW.shape,data.dataPP_POW[:10])
4364 #print("line 4049",data.azimuth.shape,data.azimuth)
4386 #print("line 4049",data.azimuth.shape,data.azimuth)
4365 self.__buffer[:,self.__profIndex,:]= data.dataPP_POW
4387 if self.mode==0:
4388 self.__buffer[:,self.__profIndex,:]= data.dataPP_POW
4389 if self.mode==1:
4390 self.__buffer[:,self.__profIndex,:]= data.data_pow
4366 #print("me casi",self.index,data.azimuth[self.index])
4391 #print("me casi",self.index,data.azimuth[self.index])
4367 #print(self.__profIndex, self.index , data.azimuth[self.index] )
4392 #print(self.__profIndex, self.index , data.azimuth[self.index] )
4368 #print("magic",data.profileIndex)
4393 #print("magic",data.profileIndex)
4369 #print(data.azimuth[self.index])
4394 #print(data.azimuth[self.index])
4370 #print("index",self.index)
4395 #print("index",self.index)
4371
4396
4372 self.__buffer2[self.__profIndex] = data.azimuth[self.index]
4397 self.__buffer2[self.__profIndex] = data.azimuth[self.index]
4373 #print("q pasa")
4398 #print("q pasa")
4374 self.index+=1
4399 self.index+=1
4375 #print("index",self.index,data.azimuth[:10])
4400 #print("index",self.index,data.azimuth[:10])
4376 self.__profIndex += 1
4401 self.__profIndex += 1
4377 return #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Remove DCΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
4402 return #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Remove DCΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
4378
4403
4379 def pushData(self,data):
4404 def pushData(self,data):
4380 '''
4405 '''
4381 Return the PULSEPAIR and the profiles used in the operation
4406 Return the PULSEPAIR and the profiles used in the operation
4382 Affected : self.__profileIndex
4407 Affected : self.__profileIndex
4383 '''
4408 '''
4384 #print("pushData")
4409 #print("pushData")
4385
4410
4386 data_360 = self.__buffer
4411 data_360 = self.__buffer
4387 data_p = self.__buffer2
4412 data_p = self.__buffer2
4388 n = self.__profIndex
4413 n = self.__profIndex
4389
4414
4390 self.__buffer = numpy.zeros((self.__nch, self.n,self.__nHeis))
4415 self.__buffer = numpy.zeros((self.__nch, self.n,self.__nHeis))
4391 self.__buffer2 = numpy.zeros(self.n)
4416 self.__buffer2 = numpy.zeros(self.n)
4392 self.__profIndex = 0
4417 self.__profIndex = 0
4393 #print("pushData")
4418 #print("pushData")
4394 return data_360,n,data_p
4419 return data_360,n,data_p
4395
4420
4396
4421
4397 def byProfiles(self,dataOut):
4422 def byProfiles(self,dataOut):
4398
4423
4399 self.__dataReady = False
4424 self.__dataReady = False
4400 data_360 = None
4425 data_360 = None
4401 data_p = None
4426 data_p = None
4402 #print("dataOu",dataOut.dataPP_POW)
4427 #print("dataOu",dataOut.dataPP_POW)
4403 self.putData(data=dataOut)
4428 self.putData(data=dataOut,mode = self.mode)
4404 #print("profIndex",self.__profIndex)
4429 #print("profIndex",self.__profIndex)
4405 if self.__profIndex == self.n:
4430 if self.__profIndex == self.n:
4406 data_360,n,data_p = self.pushData(data=dataOut)
4431 data_360,n,data_p = self.pushData(data=dataOut)
4407 self.__dataReady = True
4432 self.__dataReady = True
4408
4433
4409 return data_360,data_p
4434 return data_360,data_p
4410
4435
4411
4436
4412 def blockOp(self, dataOut, datatime= None):
4437 def blockOp(self, dataOut, datatime= None):
4413 if self.__initime == None:
4438 if self.__initime == None:
4414 self.__initime = datatime
4439 self.__initime = datatime
4415 data_360,data_p = self.byProfiles(dataOut)
4440 data_360,data_p = self.byProfiles(dataOut)
4416 self.__lastdatatime = datatime
4441 self.__lastdatatime = datatime
4417
4442
4418 if data_360 is None:
4443 if data_360 is None:
4419 return None, None,None
4444 return None, None,None
4420
4445
4421 avgdatatime = self.__initime
4446 avgdatatime = self.__initime
4422 deltatime = datatime - self.__lastdatatime
4447 deltatime = datatime - self.__lastdatatime
4423 self.__initime = datatime
4448 self.__initime = datatime
4424 #print(data_360.shape,avgdatatime,data_p.shape)
4449 #print(data_360.shape,avgdatatime,data_p.shape)
4425 return data_360,avgdatatime,data_p
4450 return data_360,avgdatatime,data_p
4426
4451
4427 def run(self, dataOut,n = None,**kwargs):
4452 def run(self, dataOut,n = None,mode=None,**kwargs):
4428
4453 print("BLOCK 360 HERE WE GO MOMENTOS")
4429 if not self.isConfig:
4454 if not self.isConfig:
4430 self.setup(dataOut = dataOut, n = n , **kwargs)
4455 self.setup(dataOut = dataOut, n = n ,mode= mode ,**kwargs)
4431 self.index = 0
4456 self.index = 0
4432 #print("comova",self.isConfig)
4457 #print("comova",self.isConfig)
4433 self.isConfig = True
4458 self.isConfig = True
4434 if self.index==dataOut.azimuth.shape[0]:
4459 if self.index==dataOut.azimuth.shape[0]:
4435 self.index=0
4460 self.index=0
4436 data_360, avgdatatime,data_p = self.blockOp(dataOut, dataOut.utctime)
4461 data_360, avgdatatime,data_p = self.blockOp(dataOut, dataOut.utctime)
4437 dataOut.flagNoData = True
4462 dataOut.flagNoData = True
4438
4463
4439 if self.__dataReady:
4464 if self.__dataReady:
4440 dataOut.data_360 = data_360 # S
4465 dataOut.data_360 = data_360 # S
4441 ##print("---------------------------------------------------------------------------------")
4466 ##print("---------------------------------------------------------------------------------")
4442 ##print("---------------------------DATAREADY---------------------------------------------")
4467 ##print("---------------------------DATAREADY---------------------------------------------")
4443 ##print("---------------------------------------------------------------------------------")
4468 ##print("---------------------------------------------------------------------------------")
4444 ##print("data_360",dataOut.data_360.shape)
4469 ##print("data_360",dataOut.data_360.shape)
4445 dataOut.data_azi = data_p
4470 dataOut.data_azi = data_p
4446 ##print("azi: ",dataOut.data_azi)
4471 ##print("azi: ",dataOut.data_azi)
4447 #print("jroproc_parameters",data_p[0],data_p[-1])#,data_360.shape,avgdatatime)
4472 #print("jroproc_parameters",data_p[0],data_p[-1])#,data_360.shape,avgdatatime)
4448 dataOut.utctime = avgdatatime
4473 dataOut.utctime = avgdatatime
4449 dataOut.flagNoData = False
4474 dataOut.flagNoData = False
4450 return dataOut
4475 return dataOut
@@ -1,75 +1,81
1 import os,sys
1 import os,sys
2 import datetime
2 import datetime
3 import time
3 import time
4 from schainpy.controller import Project
4 from schainpy.controller import Project
5 #path='/DATA_RM/TEST_HDF5/d2021200'
5 #path='/DATA_RM/TEST_HDF5/d2021200'
6 #path='/DATA_RM/TEST_HDF5/d2021200'
6 #path='/DATA_RM/TEST_HDF5/d2021200'
7 #path='/DATA_RM/TEST_HDF5/d2021214'
7 #path='/DATA_RM/TEST_HDF5/d2021214'
8 #path='/DATA_RM/TEST_HDF5/d2021229'
8 #path='/DATA_RM/TEST_HDF5/d2021229'
9
9
10 #path='/DATA_RM/TEST_HDF5/d2021231'
10 #path='/DATA_RM/TEST_HDF5/d2021231'
11 #path='/DATA_RM/TEST_HDF5/ADQ_OFFLINE/d2021231'
11 #path='/DATA_RM/TEST_HDF5/ADQ_OFFLINE/d2021231'
12 path='/DATA_RM/TEST_HDF5/d2021231'
12 path='/DATA_RM/TEST_HDF5/d2021231'
13 #path='/DATA_RM/TEST_14_HDF5/d2021257'
13 #path='/DATA_RM/TEST_14_HDF5/d2021257'
14 ## TEST ULTIMA PRUEBA 22 DE SEPTIEMBRE
14 ## TEST ULTIMA PRUEBA 22 DE SEPTIEMBRE
15 path = '/DATA_RM/TEST_HDF5_PP_22/d2021265'
15 path = '/DATA_RM/TEST_HDF5_PP_22/d2021265'
16 #path = '/DATA_RM/TEST_HDF5_PP_100/d2021285'
17 path = '/DATA_RM/TEST_HDF5_PP/d2021285'
18
19
16 path_adq=path
20 path_adq=path
17 #path_ped='/DATA_RM/TEST_PEDESTAL/P2021200'
21 #path_ped='/DATA_RM/TEST_PEDESTAL/P2021200'
18 #path_ped='/DATA_RM/TEST_PEDESTAL/P2021214'
22 #path_ped='/DATA_RM/TEST_PEDESTAL/P2021214'
19 #path_ped='/DATA_RM/TEST_PEDESTAL/P2021230'
23 #path_ped='/DATA_RM/TEST_PEDESTAL/P2021230'
20 #path_ped='/DATA_RM/TEST_PEDESTAL/P20210819'
24 #path_ped='/DATA_RM/TEST_PEDESTAL/P20210819'
21 #path_ped='/DATA_RM/TEST_PEDESTAL/P20210819-154315'
25 #path_ped='/DATA_RM/TEST_PEDESTAL/P20210819-154315'
22 #path_ped='/DATA_RM/TEST_PEDESTAL/P20210914-162434'
26 #path_ped='/DATA_RM/TEST_PEDESTAL/P20210914-162434'
23 #path_ped='/DATA_RM/TEST_PEDESTAL/PEDESTAL_OFFLINE/P20210819-161524'
27 #path_ped='/DATA_RM/TEST_PEDESTAL/PEDESTAL_OFFLINE/P20210819-161524'
24 #pruebas con perdida de datos
28 #pruebas con perdida de datos
25 #path_ped='/DATA_RM/TEST_PEDESTAL/PEDESTAL_OFFLINE/P20210819-161524_TEST'
29 #path_ped='/DATA_RM/TEST_PEDESTAL/PEDESTAL_OFFLINE/P20210819-161524_TEST'
26 ## TEST ULTIMA PRUEBA 22 DE SEPTIEMBRE
30 ## TEST ULTIMA PRUEBA 22 DE SEPTIEMBRE
27 path_ped='/DATA_RM/TEST_PEDESTAL/P20210922-122731'
31 path_ped='/DATA_RM/TEST_PEDESTAL/P20211012-082745'
28
32
29
33
30 figpath = '/home/soporte/Pictures'
34 figpath = '/home/soporte/Pictures'
31 desc = "Simulator Test"
35 desc = "Simulator Test"
32
36
33 controllerObj = Project()
37 controllerObj = Project()
34 controllerObj.setup(id='10',name='Test Simulator',description=desc)
38 controllerObj.setup(id='10',name='Test Simulator',description=desc)
35 readUnitConfObj = controllerObj.addReadUnit(datatype='HDFReader',
39 readUnitConfObj = controllerObj.addReadUnit(datatype='HDFReader',
36 path=path,
40 path=path,
37 startDate="2021/01/01", #"2020/01/01",#today,
41 startDate="2021/01/01", #"2020/01/01",#today,
38 endDate= "2021/12/01", #"2020/12/30",#today,
42 endDate= "2021/12/01", #"2020/12/30",#today,
39 startTime='00:00:00',
43 startTime='00:00:00',
40 endTime='23:59:59',
44 endTime='23:59:59',
41 t_Interval_p=0.01,
45 t_Interval_p=0.01,
42 n_Muestras_p=100,
46 n_Muestras_p=100,
43 delay=30,
47 delay=30,
44 #set=0,
48 #set=0,
45 online=0,
49 online=0,
46 walk=0,
50 walk=0,
47 nTries=6)#1
51 nTries=6)#1
48
52
49 procUnitConfObjA = controllerObj.addProcUnit(datatype='ParametersProc',inputId=readUnitConfObj.getId())
53 procUnitConfObjA = controllerObj.addProcUnit(datatype='ParametersProc',inputId=readUnitConfObj.getId())
50 V=2
54 V=10
51 blocksPerfile=100
55 blocksPerfile=360
52 print("Velocidad del Pedestal",V)
56 print("Velocidad del Pedestal",V)
53 f_a_p= int(blocksPerfile/V)
57 tmp_blocksPerfile=100
58 f_a_p= int(tmp_blocksPerfile/V)
54
59
55 opObj11 = procUnitConfObjA.addOperation(name='PedestalInformation')
60 opObj11 = procUnitConfObjA.addOperation(name='PedestalInformation')
56 opObj11.addParameter(name='path_ped', value=path_ped)
61 opObj11.addParameter(name='path_ped', value=path_ped)
57 opObj11.addParameter(name='path_adq', value=path_adq)
62 #opObj11.addParameter(name='path_adq', value=path_adq)
58 opObj11.addParameter(name='t_Interval_p', value='0.01', format='float')
63 opObj11.addParameter(name='t_Interval_p', value='0.01', format='float')
64 opObj11.addParameter(name='blocksPerfile', value=blocksPerfile, format='int')
59 opObj11.addParameter(name='n_Muestras_p', value='100', format='float')
65 opObj11.addParameter(name='n_Muestras_p', value='100', format='float')
60 opObj11.addParameter(name='blocksPerfile', value='100', format='int')
61 opObj11.addParameter(name='f_a_p', value=f_a_p, format='int')
66 opObj11.addParameter(name='f_a_p', value=f_a_p, format='int')
62 opObj11.addParameter(name='online', value='0', format='int')# habilitar el enable aqui tambien
67 opObj11.addParameter(name='online', value='0', format='int')# habilitar el enable aqui tambien
63
68
64
69
65 opObj11 = procUnitConfObjA.addOperation(name='Block360')
70 opObj11 = procUnitConfObjA.addOperation(name='Block360')
66 opObj11.addParameter(name='n', value='10', format='int')
71 opObj11.addParameter(name='n', value='10', format='int')
72 opObj11.addParameter(name='mode', value=0, format='int')
67 # este bloque funciona bien con divisores de 360 no olvidar 0 10 20 30 40 60 90 120 180
73 # este bloque funciona bien con divisores de 360 no olvidar 0 10 20 30 40 60 90 120 180
68
74
69 opObj11= procUnitConfObjA.addOperation(name='WeatherPlot',optype='other')
75 opObj11= procUnitConfObjA.addOperation(name='WeatherPlot',optype='other')
70 #opObj11.addParameter(name='save', value=figpath)
76 #opObj11.addParameter(name='save', value=figpath)
71 #opObj11.addParameter(name='save_period', value=1)
77 #opObj11.addParameter(name='save_period', value=1)
72
78
73 controllerObj.start()
79 controllerObj.start()
74 #online 1 utc_adq 1617490240.48
80 #online 1 utc_adq 1617490240.48
75 #online 0 utc_adq 1617489815.4804
81 #online 0 utc_adq 1617489815.4804
General Comments 0
You need to be logged in to leave comments. Login now