##// END OF EJS Templates
Merge branch 'v3.0-devel' of http://jro-dev.igp.gob.pe/rhodecode/schain into v3.0-devel
Juan C. Espinoza -
r1323:133a5771abd8 merge
parent child
Show More
@@ -0,0 +1,87
1 import numpy
2 import sys
3 import zmq
4 import time
5 import h5py
6 import os
7
8 path="/home/alex/Downloads/pedestal"
9 ext=".hdf5"
10
11 port ="5556"
12 if len(sys.argv)>1:
13 port = sys.argv[1]
14 int(port)
15
16 if len(sys.argv)>2:
17 port1 = sys.argv[2]
18 int(port1)
19
20 #Socket to talk to server
21 context = zmq.Context()
22 socket = context.socket(zmq.SUB)
23
24 print("Collecting updates from weather server...")
25 socket.connect("tcp://localhost:%s"%port)
26
27 if len(sys.argv)>2:
28 socket.connect("tcp://localhost:%s"%port1)
29
30 #Subscribe to zipcode, default is NYC,10001
31 topicfilter = "10001"
32 socket.setsockopt_string(zmq.SUBSCRIBE,topicfilter)
33 #Process 5 updates
34 total_value=0
35 count= -1
36 azi= []
37 elev=[]
38 time0=[]
39 #for update_nbr in range(250):
40 while(True):
41 string= socket.recv()
42 topic,ang_elev,ang_elev_dec,ang_azi,ang_azi_dec,seconds,seconds_dec= string.split()
43 ang_azi =float(ang_azi)+1e-3*float(ang_azi_dec)
44 ang_elev =float(ang_elev)+1e-3*float(ang_elev_dec)
45 seconds =float(seconds) +1e-6*float(seconds_dec)
46 azi.append(ang_azi)
47 elev.append(ang_elev)
48 time0.append(seconds)
49 count +=1
50 if count == 100:
51 timetuple=time.localtime()
52 epoc = time.mktime(timetuple)
53 #print(epoc)
54 fullpath = path + ("/" if path[-1]!="/" else "")
55
56 if not os.path.exists(fullpath):
57 os.mkdir(fullpath)
58
59 azi_array = numpy.array(azi)
60 elev_array = numpy.array(elev)
61 time0_array= numpy.array(time0)
62 pedestal_array=numpy.array([azi,elev,time0])
63 count=0
64 azi= []
65 elev=[]
66 time0=[]
67 #print(pedestal_array[0])
68 #print(pedestal_array[1])
69
70 meta='PE'
71 filex="%s%4.4d%3.3d%10.4d%s"%(meta,timetuple.tm_year,timetuple.tm_yday,epoc,ext)
72 filename = os.path.join(fullpath,filex)
73 fp = h5py.File(filename,'w')
74 #print("Escribiendo HDF5...",epoc)
75 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· DataΒ·....Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
76 grp = fp.create_group("Data")
77 dset = grp.create_dataset("azimuth" , data=pedestal_array[0])
78 dset = grp.create_dataset("elevacion", data=pedestal_array[1])
79 dset = grp.create_dataset("utc" , data=pedestal_array[2])
80 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· MetadataΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
81 grp = fp.create_group("Metadata")
82 dset = grp.create_dataset("utctimeInit", data=pedestal_array[2][0])
83 timeInterval = pedestal_array[2][1]-pedestal_array[2][0]
84 dset = grp.create_dataset("timeInterval", data=timeInterval)
85 fp.close()
86
87 #print ("Average messagedata value for topic '%s' was %dF" % ( topicfilter,total_value / update_nbr))
@@ -0,0 +1,48
1 ###########################################################################
2 ############################### SERVIDOR###################################
3 ######################### SIMULADOR DE PEDESTAL############################
4 ###########################################################################
5 import time
6 import math
7 import numpy
8 import struct
9 from time import sleep
10 import zmq
11 import pickle
12 port="5556"
13 context = zmq.Context()
14 socket = context.socket(zmq.PUB)
15 socket.bind("tcp://*:%s"%port)
16 ###### PARAMETROS DE ENTRADA################################
17 print("PEDESTAL RESOLUCION 0.01")
18 print("MAXIMA VELOCIDAD DEL PEDESTAL")
19 ang_elev = 4.12
20 ang_azi = 30
21 velocidad= input ("Ingresa velocidad:")
22 velocidad= float(velocidad)
23 print (velocidad)
24 ############################################################
25 sleep(3)
26 print("Start program")
27 t1 = time.time()
28 count=0
29 while(True):
30 tmp_vuelta = int(360/velocidad)
31 t1=t1+tmp_vuelta*count
32 count= count+1
33 muestras_seg = 100
34 t2 = time.time()
35 for i in range(tmp_vuelta):
36 for j in range(muestras_seg):
37 tmp_variable = (i+j/100.0)
38 ang_azi = (tmp_variable)*float(velocidad)
39 seconds = t1+ tmp_variable
40 topic=10001
41 print ("AzimΒ°: ","%.4f"%ang_azi,"Time:" ,"%.5f"%seconds)
42 seconds_dec=(seconds-int(seconds))*1e6
43 ang_azi_dec= (ang_azi-int(ang_azi))*1e3
44 ang_elev_dec=(ang_elev-int(ang_elev))*1e3
45 sleep(0.0088)
46 socket.send_string("%d %d %d %d %d %d %d"%(topic,ang_elev,ang_elev_dec,ang_azi,ang_azi_dec,seconds,seconds_dec))
47 t3 = time.time()
48 print ("Total time for 1 vuelta in Seconds",t3-t2)
@@ -0,0 +1,82
1 import os, sys
2 import datetime
3 import time
4 from schainpy.controller import Project
5
6 desc = "USRP_test"
7 filename = "USRP_processing.xml"
8 controllerObj = Project()
9 controllerObj.setup(id = '191', name='Test_USRP', description=desc)
10
11 ############## USED TO PLOT IQ VOLTAGE, POWER AND SPECTRA #############
12 ######PATH DE LECTURA, ESCRITURA, GRAFICOS Y ENVIO WEB#################
13 path = '/home/alex/Downloads/test_rawdata'
14 figpath = '/home/alex/Downloads/hdf5_test'
15 ######################## UNIDAD DE LECTURA#############################
16 '''
17 readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader',
18 path=path,
19 startDate="2020/01/01", #"2020/01/01",#today,
20 endDate= "2020/12/01", #"2020/12/30",#today,
21 startTime='00:00:00',
22 endTime='23:59:59',
23 delay=0,
24 #set=0,
25 online=0,
26 walk=1)
27
28 '''
29 readUnitConfObj = controllerObj.addReadUnit(datatype='SimulatorReader',
30 frequency=9.345e9,
31 FixRCP_IPP= 60,
32 Tau_0 = 30,
33 AcqH0_0=0,
34 samples=330,
35 AcqDH_0=0.15,
36 FixRCP_TXA=0.15,
37 FixRCP_TXB=0.15,
38 Fdoppler=600.0,
39 Hdoppler=36,
40 Adoppler=300,#300
41 delay=0,
42 online=0,
43 walk=0,
44 profilesPerBlock=625,
45 dataBlocksPerFile=100)
46 #nTotalReadFiles=2)
47
48
49 #opObj11 = readUnitConfObj.addOperation(name='printInfo')
50
51 procUnitConfObjA = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId())
52
53 procUnitConfObjB = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjA.getId())
54 procUnitConfObjB.addParameter(name='nFFTPoints', value=625, format='int')
55 procUnitConfObjB.addParameter(name='nProfiles', value=625, format='int')
56
57 opObj11 = procUnitConfObjB.addOperation(name='removeDC')
58 opObj11.addParameter(name='mode', value=2)
59 #opObj11 = procUnitConfObjB.addOperation(name='SpectraPlot')
60 #opObj11 = procUnitConfObjB.addOperation(name='PowerProfilePlot')
61
62 procUnitConfObjC= controllerObj.addProcUnit(datatype='ParametersProc',inputId=procUnitConfObjB.getId())
63 procUnitConfObjC.addOperation(name='SpectralMoments')
64 #opObj11 = procUnitConfObjC.addOperation(name='PowerPlot')
65
66 '''
67 opObj11 = procUnitConfObjC.addOperation(name='SpectralMomentsPlot')
68 #opObj11.addParameter(name='xmin', value=14)
69 #opObj11.addParameter(name='xmax', value=15)
70 #opObj11.addParameter(name='save', value=figpath)
71 opObj11.addParameter(name='showprofile', value=1)
72 #opObj11.addParameter(name='save_period', value=10)
73 '''
74
75 opObj10 = procUnitConfObjC.addOperation(name='ParameterWriter')
76 opObj10.addParameter(name='path',value=figpath)
77 #opObj10.addParameter(name='mode',value=0)
78 opObj10.addParameter(name='blocksPerFile',value='100',format='int')
79 opObj10.addParameter(name='metadataList',value='utctimeInit,timeInterval',format='list')
80 opObj10.addParameter(name='dataList',value='data_POW,data_DOP,data_WIDTH,data_SNR')#,format='list'
81
82 controllerObj.start()
@@ -0,0 +1,162
1 import os,numpy,h5py
2 from shutil import copyfile
3
4 def isNumber(str):
5 try:
6 float(str)
7 return True
8 except:
9 return False
10
11 def getfirstFilefromPath(path,meta,ext):
12 validFilelist = []
13 fileList = os.listdir(path)
14 if len(fileList)<1:
15 return None
16 # meta 1234 567 8-18 BCDE
17 # H,D,PE YYYY DDD EPOC .ext
18
19 for thisFile in fileList:
20 if meta =="PE":
21 try:
22 number= int(thisFile[len(meta)+7:len(meta)+17])
23 except:
24 print("There is a file or folder with different format")
25 if meta == "D":
26 try:
27 number= int(thisFile[8:11])
28 except:
29 print("There is a file or folder with different format")
30
31 if not isNumber(str=number):
32 continue
33 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
34 continue
35 validFilelist.sort()
36 validFilelist.append(thisFile)
37 if len(validFilelist)>0:
38 validFilelist = sorted(validFilelist,key=str.lower)
39 return validFilelist
40 return None
41
42 def gettimeutcfromDirFilename(path,file):
43 dir_file= path+"/"+file
44 fp = h5py.File(dir_file,'r')
45 epoc = fp['Metadata'].get('utctimeInit')[()]
46 fp.close()
47 return epoc
48
49 def getDatavaluefromDirFilename(path,file,value):
50 dir_file= path+"/"+file
51 fp = h5py.File(dir_file,'r')
52 array = fp['Data'].get(value)[()]
53 fp.close()
54 return array
55
56
57 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Velocidad de PedestalΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
58 w = input ("Ingresa velocidad de Pedestal: ")
59 w = 4
60 w = float(w)
61 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Resolucion minimo en gradosΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
62 alfa = input ("Ingresa resolucion minima en grados: ")
63 alfa = 1
64 alfa = float(alfa)
65 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· IPP del Experimento Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
66 IPP = input ("Ingresa el IPP del experimento: ")
67 IPP = 0.0004
68 IPP = float(IPP)
69 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· MODE Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
70 mode = input ("Ingresa el MODO del experimento T or F: ")
71 mode = "T"
72 mode = str(mode)
73
74 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Tiempo en generar la resolucion minΒ·Β·Β·
75 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· MCU Β·Β· var_ang = w * (var_tiempo)Β·Β·Β·
76 var_tiempo = alfa/w
77 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Tiempo Equivalente en perfilesΒ·Β·Β·Β·Β·Β·Β·Β·
78 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· var_tiempo = IPP * ( num_perfiles )Β·
79 num_perfiles = int(var_tiempo/IPP)
80
81 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·DATA PEDESTALΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
82 dir_pedestal = "/home/alex/Downloads/pedestal"
83 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· DATA ADQΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
84 if mode=="T":
85 dir_adq = "/home/alex/Downloads/hdf5_testPP/d2020194" # Time domain
86 else:
87 dir_adq = "/home/alex/Downloads/hdf5_test/d2020194" # Frequency domain
88
89 print( "Velocidad angular :", w)
90 print( "Resolucion minima en grados :", alfa)
91 print( "Numero de perfiles equivalente:", num_perfiles)
92 print( "Mode :", mode)
93
94 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· First FileΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
95 list_pedestal = getfirstFilefromPath(path=dir_pedestal,meta="PE",ext=".hdf5")
96 list_adq = getfirstFilefromPath(path=dir_adq ,meta="D",ext=".hdf5")
97
98 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· utc time Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
99 utc_pedestal= gettimeutcfromDirFilename(path=dir_pedestal,file=list_pedestal[0])
100 utc_adq = gettimeutcfromDirFilename(path=dir_adq ,file=list_adq[0])
101
102 print("utc_pedestal :",utc_pedestal)
103 print("utc_adq :",utc_adq)
104 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Relacion: utc_adq (+/-) var_tiempo*nro_file= utc_pedestal
105 time_Interval_p = 0.01
106 n_perfiles_p = 100
107 if utc_adq>utc_pedestal:
108 nro_file = int((int(utc_adq) - int(utc_pedestal))/(time_Interval_p*n_perfiles_p))
109 ff_pedestal = list_pedestal[nro_file]
110 utc_pedestal = gettimeutcfromDirFilename(path=dir_pedestal,file=ff_pedestal)
111 nro_key_p = int((utc_adq-utc_pedestal)/time_Interval_p)
112 if utc_adq >utc_pedestal:
113 ff_pedestal = ff_pedestal
114 else:
115 nro_file = nro_file-1
116 ff_pedestal = list_pedestal[nro_file]
117 angulo = getDatavaluefromDirFilename(path=dir_pedestal,file=ff_pedestal,value="azimuth")
118 nro_key_p = int((utc_adq-utc_pedestal)/time_Interval_p)
119 print("nro_file :",nro_file)
120 print("name_file :",ff_pedestal)
121 print("utc_pedestal_file :",utc_pedestal)
122 print("nro_key_p :",nro_key_p)
123 print("utc_pedestal_init :",utc_pedestal+nro_key_p*time_Interval_p)
124 print("angulo_array :",angulo[nro_key_p])
125 #4+25+25+25+21
126 #while True:
127 list_pedestal = getfirstFilefromPath(path=dir_pedestal,meta="PE",ext=".hdf5")
128 list_adq = getfirstFilefromPath(path=dir_adq ,meta="D",ext=".hdf5")
129
130 nro_file = nro_file #10
131 nro_key_perfil = nro_key_p
132 blocksPerFile = 100
133 wr_path = "/home/alex/Downloads/hdf5_wr/"
134 # Lectura de archivos de adquisicion para adicion de azimuth
135 for thisFile in range(len(list_adq)):
136 print("thisFileAdq",thisFile)
137 angulo_adq = numpy.zeros(blocksPerFile)
138 tmp = 0
139 for j in range(blocksPerFile):
140 iterador = nro_key_perfil + 25*(j-tmp)
141 if iterador < n_perfiles_p:
142 nro_file = nro_file
143 else:
144 nro_file = nro_file+1
145 tmp = j
146 iterador = nro_key_perfil
147 ff_pedestal = list_pedestal[nro_file]
148 angulo = getDatavaluefromDirFilename(path=dir_pedestal,file=ff_pedestal,value="azimuth")
149 angulo_adq[j]= angulo[iterador]
150 copyfile(dir_adq+"/"+list_adq[thisFile],wr_path+list_adq[thisFile])
151 fp = h5py.File(wr_path+list_adq[thisFile],'a')
152 grp = fp.create_group("Pedestal")
153 dset = grp.create_dataset("azimuth" , data=angulo_adq)
154 fp.close()
155 print("Angulo",angulo_adq)
156 print("Angulo",len(angulo_adq))
157 nro_key_perfil=iterador + 25
158 if nro_key_perfil< n_perfiles_p:
159 nro_file = nro_file
160 else:
161 nro_file = nro_file+1
162 nro_key_perfil= nro_key_p
@@ -1,1397 +1,1403
1 '''
1 '''
2
2
3 $Author: murco $
3 $Author: murco $
4 $Id: JROData.py 173 2012-11-20 15:06:21Z murco $
4 $Id: JROData.py 173 2012-11-20 15:06:21Z murco $
5 '''
5 '''
6
6
7 import copy
7 import copy
8 import numpy
8 import numpy
9 import datetime
9 import datetime
10 import json
10 import json
11
11
12 import schainpy.admin
12 import schainpy.admin
13 from schainpy.utils import log
13 from schainpy.utils import log
14 from .jroheaderIO import SystemHeader, RadarControllerHeader
14 from .jroheaderIO import SystemHeader, RadarControllerHeader
15 from schainpy.model.data import _noise
15 from schainpy.model.data import _noise
16
16
17
17
18 def getNumpyDtype(dataTypeCode):
18 def getNumpyDtype(dataTypeCode):
19
19
20 if dataTypeCode == 0:
20 if dataTypeCode == 0:
21 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
21 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
22 elif dataTypeCode == 1:
22 elif dataTypeCode == 1:
23 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
23 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
24 elif dataTypeCode == 2:
24 elif dataTypeCode == 2:
25 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
25 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
26 elif dataTypeCode == 3:
26 elif dataTypeCode == 3:
27 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
27 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
28 elif dataTypeCode == 4:
28 elif dataTypeCode == 4:
29 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
29 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
30 elif dataTypeCode == 5:
30 elif dataTypeCode == 5:
31 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
31 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
32 else:
32 else:
33 raise ValueError('dataTypeCode was not defined')
33 raise ValueError('dataTypeCode was not defined')
34
34
35 return numpyDtype
35 return numpyDtype
36
36
37
37
38 def getDataTypeCode(numpyDtype):
38 def getDataTypeCode(numpyDtype):
39
39
40 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
40 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
41 datatype = 0
41 datatype = 0
42 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
42 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
43 datatype = 1
43 datatype = 1
44 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
44 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
45 datatype = 2
45 datatype = 2
46 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
46 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
47 datatype = 3
47 datatype = 3
48 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
48 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
49 datatype = 4
49 datatype = 4
50 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
50 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
51 datatype = 5
51 datatype = 5
52 else:
52 else:
53 datatype = None
53 datatype = None
54
54
55 return datatype
55 return datatype
56
56
57
57
58 def hildebrand_sekhon(data, navg):
58 def hildebrand_sekhon(data, navg):
59 """
59 """
60 This method is for the objective determination of the noise level in Doppler spectra. This
60 This method is for the objective determination of the noise level in Doppler spectra. This
61 implementation technique is based on the fact that the standard deviation of the spectral
61 implementation technique is based on the fact that the standard deviation of the spectral
62 densities is equal to the mean spectral density for white Gaussian noise
62 densities is equal to the mean spectral density for white Gaussian noise
63
63
64 Inputs:
64 Inputs:
65 Data : heights
65 Data : heights
66 navg : numbers of averages
66 navg : numbers of averages
67
67
68 Return:
68 Return:
69 mean : noise's level
69 mean : noise's level
70 """
70 """
71
71
72 sortdata = numpy.sort(data, axis=None)
72 sortdata = numpy.sort(data, axis=None)
73 '''
73 '''
74 lenOfData = len(sortdata)
74 lenOfData = len(sortdata)
75 nums_min = lenOfData*0.2
75 nums_min = lenOfData*0.2
76
76
77 if nums_min <= 5:
77 if nums_min <= 5:
78
78
79 nums_min = 5
79 nums_min = 5
80
80
81 sump = 0.
81 sump = 0.
82 sumq = 0.
82 sumq = 0.
83
83
84 j = 0
84 j = 0
85 cont = 1
85 cont = 1
86
86
87 while((cont == 1)and(j < lenOfData)):
87 while((cont == 1)and(j < lenOfData)):
88
88
89 sump += sortdata[j]
89 sump += sortdata[j]
90 sumq += sortdata[j]**2
90 sumq += sortdata[j]**2
91
91
92 if j > nums_min:
92 if j > nums_min:
93 rtest = float(j)/(j-1) + 1.0/navg
93 rtest = float(j)/(j-1) + 1.0/navg
94 if ((sumq*j) > (rtest*sump**2)):
94 if ((sumq*j) > (rtest*sump**2)):
95 j = j - 1
95 j = j - 1
96 sump = sump - sortdata[j]
96 sump = sump - sortdata[j]
97 sumq = sumq - sortdata[j]**2
97 sumq = sumq - sortdata[j]**2
98 cont = 0
98 cont = 0
99
99
100 j += 1
100 j += 1
101
101
102 lnoise = sump / j
102 lnoise = sump / j
103 '''
103 '''
104 return _noise.hildebrand_sekhon(sortdata, navg)
104 return _noise.hildebrand_sekhon(sortdata, navg)
105
105
106
106
107 class Beam:
107 class Beam:
108
108
109 def __init__(self):
109 def __init__(self):
110 self.codeList = []
110 self.codeList = []
111 self.azimuthList = []
111 self.azimuthList = []
112 self.zenithList = []
112 self.zenithList = []
113
113
114
114
115 class GenericData(object):
115 class GenericData(object):
116
116
117 flagNoData = True
117 flagNoData = True
118
118
119 def copy(self, inputObj=None):
119 def copy(self, inputObj=None):
120
120
121 if inputObj == None:
121 if inputObj == None:
122 return copy.deepcopy(self)
122 return copy.deepcopy(self)
123
123
124 for key in list(inputObj.__dict__.keys()):
124 for key in list(inputObj.__dict__.keys()):
125
125
126 attribute = inputObj.__dict__[key]
126 attribute = inputObj.__dict__[key]
127
127
128 # If this attribute is a tuple or list
128 # If this attribute is a tuple or list
129 if type(inputObj.__dict__[key]) in (tuple, list):
129 if type(inputObj.__dict__[key]) in (tuple, list):
130 self.__dict__[key] = attribute[:]
130 self.__dict__[key] = attribute[:]
131 continue
131 continue
132
132
133 # If this attribute is another object or instance
133 # If this attribute is another object or instance
134 if hasattr(attribute, '__dict__'):
134 if hasattr(attribute, '__dict__'):
135 self.__dict__[key] = attribute.copy()
135 self.__dict__[key] = attribute.copy()
136 continue
136 continue
137
137
138 self.__dict__[key] = inputObj.__dict__[key]
138 self.__dict__[key] = inputObj.__dict__[key]
139
139
140 def deepcopy(self):
140 def deepcopy(self):
141
141
142 return copy.deepcopy(self)
142 return copy.deepcopy(self)
143
143
144 def isEmpty(self):
144 def isEmpty(self):
145
145
146 return self.flagNoData
146 return self.flagNoData
147
147
148 def isReady(self):
148 def isReady(self):
149
149
150 return not self.flagNoData
150 return not self.flagNoData
151
151
152
152
153 class JROData(GenericData):
153 class JROData(GenericData):
154
154
155 # m_BasicHeader = BasicHeader()
155 # m_BasicHeader = BasicHeader()
156 # m_ProcessingHeader = ProcessingHeader()
156 # m_ProcessingHeader = ProcessingHeader()
157
157
158 systemHeaderObj = SystemHeader()
158 systemHeaderObj = SystemHeader()
159 radarControllerHeaderObj = RadarControllerHeader()
159 radarControllerHeaderObj = RadarControllerHeader()
160 # data = None
160 # data = None
161 type = None
161 type = None
162 datatype = None # dtype but in string
162 datatype = None # dtype but in string
163 # dtype = None
163 # dtype = None
164 # nChannels = None
164 # nChannels = None
165 # nHeights = None
165 # nHeights = None
166 nProfiles = None
166 nProfiles = None
167 heightList = None
167 heightList = None
168 channelList = None
168 channelList = None
169 flagDiscontinuousBlock = False
169 flagDiscontinuousBlock = False
170 useLocalTime = False
170 useLocalTime = False
171 utctime = None
171 utctime = None
172 timeZone = None
172 timeZone = None
173 dstFlag = None
173 dstFlag = None
174 errorCount = None
174 errorCount = None
175 blocksize = None
175 blocksize = None
176 # nCode = None
176 # nCode = None
177 # nBaud = None
177 # nBaud = None
178 # code = None
178 # code = None
179 flagDecodeData = False # asumo q la data no esta decodificada
179 flagDecodeData = False # asumo q la data no esta decodificada
180 flagDeflipData = False # asumo q la data no esta sin flip
180 flagDeflipData = False # asumo q la data no esta sin flip
181 flagShiftFFT = False
181 flagShiftFFT = False
182 # ippSeconds = None
182 # ippSeconds = None
183 # timeInterval = None
183 # timeInterval = None
184 nCohInt = None
184 nCohInt = None
185 # noise = None
185 # noise = None
186 windowOfFilter = 1
186 windowOfFilter = 1
187 # Speed of ligth
187 # Speed of ligth
188 C = 3e8
188 C = 3e8
189 frequency = 49.92e6
189 frequency = 49.92e6
190 realtime = False
190 realtime = False
191 beacon_heiIndexList = None
191 beacon_heiIndexList = None
192 last_block = None
192 last_block = None
193 blocknow = None
193 blocknow = None
194 azimuth = None
194 azimuth = None
195 zenith = None
195 zenith = None
196 beam = Beam()
196 beam = Beam()
197 profileIndex = None
197 profileIndex = None
198 error = None
198 error = None
199 data = None
199 data = None
200 nmodes = None
200 nmodes = None
201
201
202 def __str__(self):
202 def __str__(self):
203
203
204 return '{} - {}'.format(self.type, self.getDatatime())
204 return '{} - {}'.format(self.type, self.getDatatime())
205
205
206 def getNoise(self):
206 def getNoise(self):
207
207
208 raise NotImplementedError
208 raise NotImplementedError
209
209
210 def getNChannels(self):
210 def getNChannels(self):
211
211
212 return len(self.channelList)
212 return len(self.channelList)
213
213
214 def getChannelIndexList(self):
214 def getChannelIndexList(self):
215
215
216 return list(range(self.nChannels))
216 return list(range(self.nChannels))
217
217
218 def getNHeights(self):
218 def getNHeights(self):
219
219
220 return len(self.heightList)
220 return len(self.heightList)
221
221
222 def getHeiRange(self, extrapoints=0):
222 def getHeiRange(self, extrapoints=0):
223
223
224 heis = self.heightList
224 heis = self.heightList
225 # deltah = self.heightList[1] - self.heightList[0]
225 # deltah = self.heightList[1] - self.heightList[0]
226 #
226 #
227 # heis.append(self.heightList[-1])
227 # heis.append(self.heightList[-1])
228
228
229 return heis
229 return heis
230
230
231 def getDeltaH(self):
231 def getDeltaH(self):
232
232
233 delta = self.heightList[1] - self.heightList[0]
233 delta = self.heightList[1] - self.heightList[0]
234
234
235 return delta
235 return delta
236
236
237 def getltctime(self):
237 def getltctime(self):
238
238
239 if self.useLocalTime:
239 if self.useLocalTime:
240 return self.utctime - self.timeZone * 60
240 return self.utctime - self.timeZone * 60
241
241
242 return self.utctime
242 return self.utctime
243
243
244 def getDatatime(self):
244 def getDatatime(self):
245
245
246 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
246 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
247 return datatimeValue
247 return datatimeValue
248
248
249 def getTimeRange(self):
249 def getTimeRange(self):
250
250
251 datatime = []
251 datatime = []
252
252
253 datatime.append(self.ltctime)
253 datatime.append(self.ltctime)
254 datatime.append(self.ltctime + self.timeInterval + 1)
254 datatime.append(self.ltctime + self.timeInterval + 1)
255
255
256 datatime = numpy.array(datatime)
256 datatime = numpy.array(datatime)
257
257
258 return datatime
258 return datatime
259
259
260 def getFmaxTimeResponse(self):
260 def getFmaxTimeResponse(self):
261
261
262 period = (10**-6) * self.getDeltaH() / (0.15)
262 period = (10**-6) * self.getDeltaH() / (0.15)
263
263
264 PRF = 1. / (period * self.nCohInt)
264 PRF = 1. / (period * self.nCohInt)
265
265
266 fmax = PRF
266 fmax = PRF
267
267
268 return fmax
268 return fmax
269
269
270 def getFmax(self):
270 def getFmax(self):
271 PRF = 1. / (self.ippSeconds * self.nCohInt)
271 PRF = 1. / (self.ippSeconds * self.nCohInt)
272
272
273 fmax = PRF
273 fmax = PRF
274 return fmax
274 return fmax
275
275
276 def getVmax(self):
276 def getVmax(self):
277
277
278 _lambda = self.C / self.frequency
278 _lambda = self.C / self.frequency
279
279
280 vmax = self.getFmax() * _lambda / 2
280 vmax = self.getFmax() * _lambda / 2
281
281
282 return vmax
282 return vmax
283
283
284 def get_ippSeconds(self):
284 def get_ippSeconds(self):
285 '''
285 '''
286 '''
286 '''
287 return self.radarControllerHeaderObj.ippSeconds
287 return self.radarControllerHeaderObj.ippSeconds
288
288
289 def set_ippSeconds(self, ippSeconds):
289 def set_ippSeconds(self, ippSeconds):
290 '''
290 '''
291 '''
291 '''
292
292
293 self.radarControllerHeaderObj.ippSeconds = ippSeconds
293 self.radarControllerHeaderObj.ippSeconds = ippSeconds
294
294
295 return
295 return
296
296
297 def get_dtype(self):
297 def get_dtype(self):
298 '''
298 '''
299 '''
299 '''
300 return getNumpyDtype(self.datatype)
300 return getNumpyDtype(self.datatype)
301
301
302 def set_dtype(self, numpyDtype):
302 def set_dtype(self, numpyDtype):
303 '''
303 '''
304 '''
304 '''
305
305
306 self.datatype = getDataTypeCode(numpyDtype)
306 self.datatype = getDataTypeCode(numpyDtype)
307
307
308 def get_code(self):
308 def get_code(self):
309 '''
309 '''
310 '''
310 '''
311 return self.radarControllerHeaderObj.code
311 return self.radarControllerHeaderObj.code
312
312
313 def set_code(self, code):
313 def set_code(self, code):
314 '''
314 '''
315 '''
315 '''
316 self.radarControllerHeaderObj.code = code
316 self.radarControllerHeaderObj.code = code
317
317
318 return
318 return
319
319
320 def get_ncode(self):
320 def get_ncode(self):
321 '''
321 '''
322 '''
322 '''
323 return self.radarControllerHeaderObj.nCode
323 return self.radarControllerHeaderObj.nCode
324
324
325 def set_ncode(self, nCode):
325 def set_ncode(self, nCode):
326 '''
326 '''
327 '''
327 '''
328 self.radarControllerHeaderObj.nCode = nCode
328 self.radarControllerHeaderObj.nCode = nCode
329
329
330 return
330 return
331
331
332 def get_nbaud(self):
332 def get_nbaud(self):
333 '''
333 '''
334 '''
334 '''
335 return self.radarControllerHeaderObj.nBaud
335 return self.radarControllerHeaderObj.nBaud
336
336
337 def set_nbaud(self, nBaud):
337 def set_nbaud(self, nBaud):
338 '''
338 '''
339 '''
339 '''
340 self.radarControllerHeaderObj.nBaud = nBaud
340 self.radarControllerHeaderObj.nBaud = nBaud
341
341
342 return
342 return
343
343
344 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
344 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
345 channelIndexList = property(
345 channelIndexList = property(
346 getChannelIndexList, "I'm the 'channelIndexList' property.")
346 getChannelIndexList, "I'm the 'channelIndexList' property.")
347 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
347 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
348 #noise = property(getNoise, "I'm the 'nHeights' property.")
348 #noise = property(getNoise, "I'm the 'nHeights' property.")
349 datatime = property(getDatatime, "I'm the 'datatime' property")
349 datatime = property(getDatatime, "I'm the 'datatime' property")
350 ltctime = property(getltctime, "I'm the 'ltctime' property")
350 ltctime = property(getltctime, "I'm the 'ltctime' property")
351 ippSeconds = property(get_ippSeconds, set_ippSeconds)
351 ippSeconds = property(get_ippSeconds, set_ippSeconds)
352 dtype = property(get_dtype, set_dtype)
352 dtype = property(get_dtype, set_dtype)
353 # timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
353 # timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
354 code = property(get_code, set_code)
354 code = property(get_code, set_code)
355 nCode = property(get_ncode, set_ncode)
355 nCode = property(get_ncode, set_ncode)
356 nBaud = property(get_nbaud, set_nbaud)
356 nBaud = property(get_nbaud, set_nbaud)
357
357
358
358
359 class Voltage(JROData):
359 class Voltage(JROData):
360
360
361 # data es un numpy array de 2 dmensiones (canales, alturas)
361 # data es un numpy array de 2 dmensiones (canales, alturas)
362 data = None
362 data = None
363 data_intensity = None
363 dataPP_POW = None
364 data_velocity = None
364 dataPP_DOP = None
365 data_specwidth = None
365 dataPP_WIDTH = None
366 dataPP_SNR = None
367
366 def __init__(self):
368 def __init__(self):
367 '''
369 '''
368 Constructor
370 Constructor
369 '''
371 '''
370
372
371 self.useLocalTime = True
373 self.useLocalTime = True
372 self.radarControllerHeaderObj = RadarControllerHeader()
374 self.radarControllerHeaderObj = RadarControllerHeader()
373 self.systemHeaderObj = SystemHeader()
375 self.systemHeaderObj = SystemHeader()
374 self.type = "Voltage"
376 self.type = "Voltage"
375 self.data = None
377 self.data = None
376 # self.dtype = None
378 # self.dtype = None
377 # self.nChannels = 0
379 # self.nChannels = 0
378 # self.nHeights = 0
380 # self.nHeights = 0
379 self.nProfiles = None
381 self.nProfiles = None
380 self.heightList = None
382 self.heightList = None
381 self.channelList = None
383 self.channelList = None
382 # self.channelIndexList = None
384 # self.channelIndexList = None
383 self.flagNoData = True
385 self.flagNoData = True
384 self.flagDiscontinuousBlock = False
386 self.flagDiscontinuousBlock = False
385 self.utctime = None
387 self.utctime = None
386 self.timeZone = None
388 self.timeZone = None
387 self.dstFlag = None
389 self.dstFlag = None
388 self.errorCount = None
390 self.errorCount = None
389 self.nCohInt = None
391 self.nCohInt = None
390 self.blocksize = None
392 self.blocksize = None
391 self.flagCohInt = False
393 self.flagCohInt = False
392 self.flagDecodeData = False # asumo q la data no esta decodificada
394 self.flagDecodeData = False # asumo q la data no esta decodificada
393 self.flagDeflipData = False # asumo q la data no esta sin flip
395 self.flagDeflipData = False # asumo q la data no esta sin flip
394 self.flagShiftFFT = False
396 self.flagShiftFFT = False
395 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
397 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
396 self.profileIndex = 0
398 self.profileIndex = 0
397
399
398 def getNoisebyHildebrand(self, channel=None):
400 def getNoisebyHildebrand(self, channel=None):
399 """
401 """
400 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
402 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
401
403
402 Return:
404 Return:
403 noiselevel
405 noiselevel
404 """
406 """
405
407
406 if channel != None:
408 if channel != None:
407 data = self.data[channel]
409 data = self.data[channel]
408 nChannels = 1
410 nChannels = 1
409 else:
411 else:
410 data = self.data
412 data = self.data
411 nChannels = self.nChannels
413 nChannels = self.nChannels
412
414
413 noise = numpy.zeros(nChannels)
415 noise = numpy.zeros(nChannels)
414 power = data * numpy.conjugate(data)
416 power = data * numpy.conjugate(data)
415
417
416 for thisChannel in range(nChannels):
418 for thisChannel in range(nChannels):
417 if nChannels == 1:
419 if nChannels == 1:
418 daux = power[:].real
420 daux = power[:].real
419 else:
421 else:
420 daux = power[thisChannel, :].real
422 daux = power[thisChannel, :].real
421 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
423 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
422
424
423 return noise
425 return noise
424
426
425 def getNoise(self, type=1, channel=None):
427 def getNoise(self, type=1, channel=None):
426
428
427 if type == 1:
429 if type == 1:
428 noise = self.getNoisebyHildebrand(channel)
430 noise = self.getNoisebyHildebrand(channel)
429
431
430 return noise
432 return noise
431
433
432 def getPower(self, channel=None):
434 def getPower(self, channel=None):
433
435
434 if channel != None:
436 if channel != None:
435 data = self.data[channel]
437 data = self.data[channel]
436 else:
438 else:
437 data = self.data
439 data = self.data
438
440
439 power = data * numpy.conjugate(data)
441 power = data * numpy.conjugate(data)
440 powerdB = 10 * numpy.log10(power.real)
442 powerdB = 10 * numpy.log10(power.real)
441 powerdB = numpy.squeeze(powerdB)
443 powerdB = numpy.squeeze(powerdB)
442
444
443 return powerdB
445 return powerdB
444
446
445 def getTimeInterval(self):
447 def getTimeInterval(self):
446
448
447 timeInterval = self.ippSeconds * self.nCohInt
449 timeInterval = self.ippSeconds * self.nCohInt
448
450
449 return timeInterval
451 return timeInterval
450
452
451 noise = property(getNoise, "I'm the 'nHeights' property.")
453 noise = property(getNoise, "I'm the 'nHeights' property.")
452 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
454 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
453
455
454
456
455 class Spectra(JROData):
457 class Spectra(JROData):
456
458
457 # data spc es un numpy array de 2 dmensiones (canales, perfiles, alturas)
459 # data spc es un numpy array de 2 dmensiones (canales, perfiles, alturas)
458 data_spc = None
460 data_spc = None
459 # data cspc es un numpy array de 2 dmensiones (canales, pares, alturas)
461 # data cspc es un numpy array de 2 dmensiones (canales, pares, alturas)
460 data_cspc = None
462 data_cspc = None
461 # data dc es un numpy array de 2 dmensiones (canales, alturas)
463 # data dc es un numpy array de 2 dmensiones (canales, alturas)
462 data_dc = None
464 data_dc = None
463 # data power
465 # data power
464 data_pwr = None
466 data_pwr = None
465 nFFTPoints = None
467 nFFTPoints = None
466 # nPairs = None
468 # nPairs = None
467 pairsList = None
469 pairsList = None
468 nIncohInt = None
470 nIncohInt = None
469 wavelength = None # Necesario para cacular el rango de velocidad desde la frecuencia
471 wavelength = None # Necesario para cacular el rango de velocidad desde la frecuencia
470 nCohInt = None # se requiere para determinar el valor de timeInterval
472 nCohInt = None # se requiere para determinar el valor de timeInterval
471 ippFactor = None
473 ippFactor = None
472 profileIndex = 0
474 profileIndex = 0
473 plotting = "spectra"
475 plotting = "spectra"
474
476
475 def __init__(self):
477 def __init__(self):
476 '''
478 '''
477 Constructor
479 Constructor
478 '''
480 '''
479
481
480 self.useLocalTime = True
482 self.useLocalTime = True
481 self.radarControllerHeaderObj = RadarControllerHeader()
483 self.radarControllerHeaderObj = RadarControllerHeader()
482 self.systemHeaderObj = SystemHeader()
484 self.systemHeaderObj = SystemHeader()
483 self.type = "Spectra"
485 self.type = "Spectra"
484 # self.data = None
486 # self.data = None
485 # self.dtype = None
487 # self.dtype = None
486 # self.nChannels = 0
488 # self.nChannels = 0
487 # self.nHeights = 0
489 # self.nHeights = 0
488 self.nProfiles = None
490 self.nProfiles = None
489 self.heightList = None
491 self.heightList = None
490 self.channelList = None
492 self.channelList = None
491 # self.channelIndexList = None
493 # self.channelIndexList = None
492 self.pairsList = None
494 self.pairsList = None
493 self.flagNoData = True
495 self.flagNoData = True
494 self.flagDiscontinuousBlock = False
496 self.flagDiscontinuousBlock = False
495 self.utctime = None
497 self.utctime = None
496 self.nCohInt = None
498 self.nCohInt = None
497 self.nIncohInt = None
499 self.nIncohInt = None
498 self.blocksize = None
500 self.blocksize = None
499 self.nFFTPoints = None
501 self.nFFTPoints = None
500 self.wavelength = None
502 self.wavelength = None
501 self.flagDecodeData = False # asumo q la data no esta decodificada
503 self.flagDecodeData = False # asumo q la data no esta decodificada
502 self.flagDeflipData = False # asumo q la data no esta sin flip
504 self.flagDeflipData = False # asumo q la data no esta sin flip
503 self.flagShiftFFT = False
505 self.flagShiftFFT = False
504 self.ippFactor = 1
506 self.ippFactor = 1
505 #self.noise = None
507 #self.noise = None
506 self.beacon_heiIndexList = []
508 self.beacon_heiIndexList = []
507 self.noise_estimation = None
509 self.noise_estimation = None
508
510
509 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
511 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
510 """
512 """
511 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
513 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
512
514
513 Return:
515 Return:
514 noiselevel
516 noiselevel
515 """
517 """
516
518
517 noise = numpy.zeros(self.nChannels)
519 noise = numpy.zeros(self.nChannels)
518
520
519 for channel in range(self.nChannels):
521 for channel in range(self.nChannels):
520 daux = self.data_spc[channel,
522 daux = self.data_spc[channel,
521 xmin_index:xmax_index, ymin_index:ymax_index]
523 xmin_index:xmax_index, ymin_index:ymax_index]
522 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
524 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
523
525
524 return noise
526 return noise
525
527
526 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
528 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
527
529
528 if self.noise_estimation is not None:
530 if self.noise_estimation is not None:
529 # this was estimated by getNoise Operation defined in jroproc_spectra.py
531 # this was estimated by getNoise Operation defined in jroproc_spectra.py
530 return self.noise_estimation
532 return self.noise_estimation
531 else:
533 else:
532 noise = self.getNoisebyHildebrand(
534 noise = self.getNoisebyHildebrand(
533 xmin_index, xmax_index, ymin_index, ymax_index)
535 xmin_index, xmax_index, ymin_index, ymax_index)
534 return noise
536 return noise
535
537
536 def getFreqRangeTimeResponse(self, extrapoints=0):
538 def getFreqRangeTimeResponse(self, extrapoints=0):
537
539
538 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
540 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
539 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
541 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
540
542
541 return freqrange
543 return freqrange
542
544
543 def getAcfRange(self, extrapoints=0):
545 def getAcfRange(self, extrapoints=0):
544
546
545 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
547 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
546 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
548 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
547
549
548 return freqrange
550 return freqrange
549
551
550 def getFreqRange(self, extrapoints=0):
552 def getFreqRange(self, extrapoints=0):
551
553
552 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
554 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
553 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
555 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
554
556
555 return freqrange
557 return freqrange
556
558
557 def getVelRange(self, extrapoints=0):
559 def getVelRange(self, extrapoints=0):
558
560
559 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
561 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
560 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
562 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
561
563
562 if self.nmodes:
564 if self.nmodes:
563 return velrange/self.nmodes
565 return velrange/self.nmodes
564 else:
566 else:
565 return velrange
567 return velrange
566
568
567 def getNPairs(self):
569 def getNPairs(self):
568
570
569 return len(self.pairsList)
571 return len(self.pairsList)
570
572
571 def getPairsIndexList(self):
573 def getPairsIndexList(self):
572
574
573 return list(range(self.nPairs))
575 return list(range(self.nPairs))
574
576
575 def getNormFactor(self):
577 def getNormFactor(self):
576
578
577 pwcode = 1
579 pwcode = 1
578
580
579 if self.flagDecodeData:
581 if self.flagDecodeData:
580 pwcode = numpy.sum(self.code[0]**2)
582 pwcode = numpy.sum(self.code[0]**2)
581 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
583 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
582 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
584 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
583
585
584 return normFactor
586 return normFactor
585
587
586 def getFlagCspc(self):
588 def getFlagCspc(self):
587
589
588 if self.data_cspc is None:
590 if self.data_cspc is None:
589 return True
591 return True
590
592
591 return False
593 return False
592
594
593 def getFlagDc(self):
595 def getFlagDc(self):
594
596
595 if self.data_dc is None:
597 if self.data_dc is None:
596 return True
598 return True
597
599
598 return False
600 return False
599
601
600 def getTimeInterval(self):
602 def getTimeInterval(self):
601
603
602 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
604 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
603 if self.nmodes:
605 if self.nmodes:
604 return self.nmodes*timeInterval
606 return self.nmodes*timeInterval
605 else:
607 else:
606 return timeInterval
608 return timeInterval
607
609
608 def getPower(self):
610 def getPower(self):
609
611
610 factor = self.normFactor
612 factor = self.normFactor
611 z = self.data_spc / factor
613 z = self.data_spc / factor
612 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
614 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
613 avg = numpy.average(z, axis=1)
615 avg = numpy.average(z, axis=1)
614
616
615 return 10 * numpy.log10(avg)
617 return 10 * numpy.log10(avg)
616
618
617 def getCoherence(self, pairsList=None, phase=False):
619 def getCoherence(self, pairsList=None, phase=False):
618
620
619 z = []
621 z = []
620 if pairsList is None:
622 if pairsList is None:
621 pairsIndexList = self.pairsIndexList
623 pairsIndexList = self.pairsIndexList
622 else:
624 else:
623 pairsIndexList = []
625 pairsIndexList = []
624 for pair in pairsList:
626 for pair in pairsList:
625 if pair not in self.pairsList:
627 if pair not in self.pairsList:
626 raise ValueError("Pair %s is not in dataOut.pairsList" % (
628 raise ValueError("Pair %s is not in dataOut.pairsList" % (
627 pair))
629 pair))
628 pairsIndexList.append(self.pairsList.index(pair))
630 pairsIndexList.append(self.pairsList.index(pair))
629 for i in range(len(pairsIndexList)):
631 for i in range(len(pairsIndexList)):
630 pair = self.pairsList[pairsIndexList[i]]
632 pair = self.pairsList[pairsIndexList[i]]
631 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
633 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
632 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
634 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
633 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
635 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
634 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
636 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
635 if phase:
637 if phase:
636 data = numpy.arctan2(avgcoherenceComplex.imag,
638 data = numpy.arctan2(avgcoherenceComplex.imag,
637 avgcoherenceComplex.real) * 180 / numpy.pi
639 avgcoherenceComplex.real) * 180 / numpy.pi
638 else:
640 else:
639 data = numpy.abs(avgcoherenceComplex)
641 data = numpy.abs(avgcoherenceComplex)
640
642
641 z.append(data)
643 z.append(data)
642
644
643 return numpy.array(z)
645 return numpy.array(z)
644
646
645 def setValue(self, value):
647 def setValue(self, value):
646
648
647 print("This property should not be initialized")
649 print("This property should not be initialized")
648
650
649 return
651 return
650
652
651 nPairs = property(getNPairs, setValue, "I'm the 'nPairs' property.")
653 nPairs = property(getNPairs, setValue, "I'm the 'nPairs' property.")
652 pairsIndexList = property(
654 pairsIndexList = property(
653 getPairsIndexList, setValue, "I'm the 'pairsIndexList' property.")
655 getPairsIndexList, setValue, "I'm the 'pairsIndexList' property.")
654 normFactor = property(getNormFactor, setValue,
656 normFactor = property(getNormFactor, setValue,
655 "I'm the 'getNormFactor' property.")
657 "I'm the 'getNormFactor' property.")
656 flag_cspc = property(getFlagCspc, setValue)
658 flag_cspc = property(getFlagCspc, setValue)
657 flag_dc = property(getFlagDc, setValue)
659 flag_dc = property(getFlagDc, setValue)
658 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
660 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
659 timeInterval = property(getTimeInterval, setValue,
661 timeInterval = property(getTimeInterval, setValue,
660 "I'm the 'timeInterval' property")
662 "I'm the 'timeInterval' property")
661
663
662
664
663 class SpectraHeis(Spectra):
665 class SpectraHeis(Spectra):
664
666
665 data_spc = None
667 data_spc = None
666 data_cspc = None
668 data_cspc = None
667 data_dc = None
669 data_dc = None
668 nFFTPoints = None
670 nFFTPoints = None
669 # nPairs = None
671 # nPairs = None
670 pairsList = None
672 pairsList = None
671 nCohInt = None
673 nCohInt = None
672 nIncohInt = None
674 nIncohInt = None
673
675
674 def __init__(self):
676 def __init__(self):
675
677
676 self.radarControllerHeaderObj = RadarControllerHeader()
678 self.radarControllerHeaderObj = RadarControllerHeader()
677
679
678 self.systemHeaderObj = SystemHeader()
680 self.systemHeaderObj = SystemHeader()
679
681
680 self.type = "SpectraHeis"
682 self.type = "SpectraHeis"
681
683
682 # self.dtype = None
684 # self.dtype = None
683
685
684 # self.nChannels = 0
686 # self.nChannels = 0
685
687
686 # self.nHeights = 0
688 # self.nHeights = 0
687
689
688 self.nProfiles = None
690 self.nProfiles = None
689
691
690 self.heightList = None
692 self.heightList = None
691
693
692 self.channelList = None
694 self.channelList = None
693
695
694 # self.channelIndexList = None
696 # self.channelIndexList = None
695
697
696 self.flagNoData = True
698 self.flagNoData = True
697
699
698 self.flagDiscontinuousBlock = False
700 self.flagDiscontinuousBlock = False
699
701
700 # self.nPairs = 0
702 # self.nPairs = 0
701
703
702 self.utctime = None
704 self.utctime = None
703
705
704 self.blocksize = None
706 self.blocksize = None
705
707
706 self.profileIndex = 0
708 self.profileIndex = 0
707
709
708 self.nCohInt = 1
710 self.nCohInt = 1
709
711
710 self.nIncohInt = 1
712 self.nIncohInt = 1
711
713
712 def getNormFactor(self):
714 def getNormFactor(self):
713 pwcode = 1
715 pwcode = 1
714 if self.flagDecodeData:
716 if self.flagDecodeData:
715 pwcode = numpy.sum(self.code[0]**2)
717 pwcode = numpy.sum(self.code[0]**2)
716
718
717 normFactor = self.nIncohInt * self.nCohInt * pwcode
719 normFactor = self.nIncohInt * self.nCohInt * pwcode
718
720
719 return normFactor
721 return normFactor
720
722
721 def getTimeInterval(self):
723 def getTimeInterval(self):
722
724
723 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
725 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
724
726
725 return timeInterval
727 return timeInterval
726
728
727 normFactor = property(getNormFactor, "I'm the 'getNormFactor' property.")
729 normFactor = property(getNormFactor, "I'm the 'getNormFactor' property.")
728 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
730 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
729
731
730
732
731 class Fits(JROData):
733 class Fits(JROData):
732
734
733 heightList = None
735 heightList = None
734 channelList = None
736 channelList = None
735 flagNoData = True
737 flagNoData = True
736 flagDiscontinuousBlock = False
738 flagDiscontinuousBlock = False
737 useLocalTime = False
739 useLocalTime = False
738 utctime = None
740 utctime = None
739 timeZone = None
741 timeZone = None
740 # ippSeconds = None
742 # ippSeconds = None
741 # timeInterval = None
743 # timeInterval = None
742 nCohInt = None
744 nCohInt = None
743 nIncohInt = None
745 nIncohInt = None
744 noise = None
746 noise = None
745 windowOfFilter = 1
747 windowOfFilter = 1
746 # Speed of ligth
748 # Speed of ligth
747 C = 3e8
749 C = 3e8
748 frequency = 49.92e6
750 frequency = 49.92e6
749 realtime = False
751 realtime = False
750
752
751 def __init__(self):
753 def __init__(self):
752
754
753 self.type = "Fits"
755 self.type = "Fits"
754
756
755 self.nProfiles = None
757 self.nProfiles = None
756
758
757 self.heightList = None
759 self.heightList = None
758
760
759 self.channelList = None
761 self.channelList = None
760
762
761 # self.channelIndexList = None
763 # self.channelIndexList = None
762
764
763 self.flagNoData = True
765 self.flagNoData = True
764
766
765 self.utctime = None
767 self.utctime = None
766
768
767 self.nCohInt = 1
769 self.nCohInt = 1
768
770
769 self.nIncohInt = 1
771 self.nIncohInt = 1
770
772
771 self.useLocalTime = True
773 self.useLocalTime = True
772
774
773 self.profileIndex = 0
775 self.profileIndex = 0
774
776
775 # self.utctime = None
777 # self.utctime = None
776 # self.timeZone = None
778 # self.timeZone = None
777 # self.ltctime = None
779 # self.ltctime = None
778 # self.timeInterval = None
780 # self.timeInterval = None
779 # self.header = None
781 # self.header = None
780 # self.data_header = None
782 # self.data_header = None
781 # self.data = None
783 # self.data = None
782 # self.datatime = None
784 # self.datatime = None
783 # self.flagNoData = False
785 # self.flagNoData = False
784 # self.expName = ''
786 # self.expName = ''
785 # self.nChannels = None
787 # self.nChannels = None
786 # self.nSamples = None
788 # self.nSamples = None
787 # self.dataBlocksPerFile = None
789 # self.dataBlocksPerFile = None
788 # self.comments = ''
790 # self.comments = ''
789 #
791 #
790
792
791 def getltctime(self):
793 def getltctime(self):
792
794
793 if self.useLocalTime:
795 if self.useLocalTime:
794 return self.utctime - self.timeZone * 60
796 return self.utctime - self.timeZone * 60
795
797
796 return self.utctime
798 return self.utctime
797
799
798 def getDatatime(self):
800 def getDatatime(self):
799
801
800 datatime = datetime.datetime.utcfromtimestamp(self.ltctime)
802 datatime = datetime.datetime.utcfromtimestamp(self.ltctime)
801 return datatime
803 return datatime
802
804
803 def getTimeRange(self):
805 def getTimeRange(self):
804
806
805 datatime = []
807 datatime = []
806
808
807 datatime.append(self.ltctime)
809 datatime.append(self.ltctime)
808 datatime.append(self.ltctime + self.timeInterval)
810 datatime.append(self.ltctime + self.timeInterval)
809
811
810 datatime = numpy.array(datatime)
812 datatime = numpy.array(datatime)
811
813
812 return datatime
814 return datatime
813
815
814 def getHeiRange(self):
816 def getHeiRange(self):
815
817
816 heis = self.heightList
818 heis = self.heightList
817
819
818 return heis
820 return heis
819
821
820 def getNHeights(self):
822 def getNHeights(self):
821
823
822 return len(self.heightList)
824 return len(self.heightList)
823
825
824 def getNChannels(self):
826 def getNChannels(self):
825
827
826 return len(self.channelList)
828 return len(self.channelList)
827
829
828 def getChannelIndexList(self):
830 def getChannelIndexList(self):
829
831
830 return list(range(self.nChannels))
832 return list(range(self.nChannels))
831
833
832 def getNoise(self, type=1):
834 def getNoise(self, type=1):
833
835
834 #noise = numpy.zeros(self.nChannels)
836 #noise = numpy.zeros(self.nChannels)
835
837
836 if type == 1:
838 if type == 1:
837 noise = self.getNoisebyHildebrand()
839 noise = self.getNoisebyHildebrand()
838
840
839 if type == 2:
841 if type == 2:
840 noise = self.getNoisebySort()
842 noise = self.getNoisebySort()
841
843
842 if type == 3:
844 if type == 3:
843 noise = self.getNoisebyWindow()
845 noise = self.getNoisebyWindow()
844
846
845 return noise
847 return noise
846
848
847 def getTimeInterval(self):
849 def getTimeInterval(self):
848
850
849 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
851 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
850
852
851 return timeInterval
853 return timeInterval
852
854
853 def get_ippSeconds(self):
855 def get_ippSeconds(self):
854 '''
856 '''
855 '''
857 '''
856 return self.ipp_sec
858 return self.ipp_sec
857
859
858
860
859 datatime = property(getDatatime, "I'm the 'datatime' property")
861 datatime = property(getDatatime, "I'm the 'datatime' property")
860 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
862 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
861 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
863 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
862 channelIndexList = property(
864 channelIndexList = property(
863 getChannelIndexList, "I'm the 'channelIndexList' property.")
865 getChannelIndexList, "I'm the 'channelIndexList' property.")
864 noise = property(getNoise, "I'm the 'nHeights' property.")
866 noise = property(getNoise, "I'm the 'nHeights' property.")
865
867
866 ltctime = property(getltctime, "I'm the 'ltctime' property")
868 ltctime = property(getltctime, "I'm the 'ltctime' property")
867 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
869 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
868 ippSeconds = property(get_ippSeconds, '')
870 ippSeconds = property(get_ippSeconds, '')
869
871
870 class Correlation(JROData):
872 class Correlation(JROData):
871
873
872 noise = None
874 noise = None
873 SNR = None
875 SNR = None
874 #--------------------------------------------------
876 #--------------------------------------------------
875 mode = None
877 mode = None
876 split = False
878 split = False
877 data_cf = None
879 data_cf = None
878 lags = None
880 lags = None
879 lagRange = None
881 lagRange = None
880 pairsList = None
882 pairsList = None
881 normFactor = None
883 normFactor = None
882 #--------------------------------------------------
884 #--------------------------------------------------
883 # calculateVelocity = None
885 # calculateVelocity = None
884 nLags = None
886 nLags = None
885 nPairs = None
887 nPairs = None
886 nAvg = None
888 nAvg = None
887
889
888 def __init__(self):
890 def __init__(self):
889 '''
891 '''
890 Constructor
892 Constructor
891 '''
893 '''
892 self.radarControllerHeaderObj = RadarControllerHeader()
894 self.radarControllerHeaderObj = RadarControllerHeader()
893
895
894 self.systemHeaderObj = SystemHeader()
896 self.systemHeaderObj = SystemHeader()
895
897
896 self.type = "Correlation"
898 self.type = "Correlation"
897
899
898 self.data = None
900 self.data = None
899
901
900 self.dtype = None
902 self.dtype = None
901
903
902 self.nProfiles = None
904 self.nProfiles = None
903
905
904 self.heightList = None
906 self.heightList = None
905
907
906 self.channelList = None
908 self.channelList = None
907
909
908 self.flagNoData = True
910 self.flagNoData = True
909
911
910 self.flagDiscontinuousBlock = False
912 self.flagDiscontinuousBlock = False
911
913
912 self.utctime = None
914 self.utctime = None
913
915
914 self.timeZone = None
916 self.timeZone = None
915
917
916 self.dstFlag = None
918 self.dstFlag = None
917
919
918 self.errorCount = None
920 self.errorCount = None
919
921
920 self.blocksize = None
922 self.blocksize = None
921
923
922 self.flagDecodeData = False # asumo q la data no esta decodificada
924 self.flagDecodeData = False # asumo q la data no esta decodificada
923
925
924 self.flagDeflipData = False # asumo q la data no esta sin flip
926 self.flagDeflipData = False # asumo q la data no esta sin flip
925
927
926 self.pairsList = None
928 self.pairsList = None
927
929
928 self.nPoints = None
930 self.nPoints = None
929
931
930 def getPairsList(self):
932 def getPairsList(self):
931
933
932 return self.pairsList
934 return self.pairsList
933
935
934 def getNoise(self, mode=2):
936 def getNoise(self, mode=2):
935
937
936 indR = numpy.where(self.lagR == 0)[0][0]
938 indR = numpy.where(self.lagR == 0)[0][0]
937 indT = numpy.where(self.lagT == 0)[0][0]
939 indT = numpy.where(self.lagT == 0)[0][0]
938
940
939 jspectra0 = self.data_corr[:, :, indR, :]
941 jspectra0 = self.data_corr[:, :, indR, :]
940 jspectra = copy.copy(jspectra0)
942 jspectra = copy.copy(jspectra0)
941
943
942 num_chan = jspectra.shape[0]
944 num_chan = jspectra.shape[0]
943 num_hei = jspectra.shape[2]
945 num_hei = jspectra.shape[2]
944
946
945 freq_dc = jspectra.shape[1] / 2
947 freq_dc = jspectra.shape[1] / 2
946 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
948 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
947
949
948 if ind_vel[0] < 0:
950 if ind_vel[0] < 0:
949 ind_vel[list(range(0, 1))] = ind_vel[list(
951 ind_vel[list(range(0, 1))] = ind_vel[list(
950 range(0, 1))] + self.num_prof
952 range(0, 1))] + self.num_prof
951
953
952 if mode == 1:
954 if mode == 1:
953 jspectra[:, freq_dc, :] = (
955 jspectra[:, freq_dc, :] = (
954 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
956 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
955
957
956 if mode == 2:
958 if mode == 2:
957
959
958 vel = numpy.array([-2, -1, 1, 2])
960 vel = numpy.array([-2, -1, 1, 2])
959 xx = numpy.zeros([4, 4])
961 xx = numpy.zeros([4, 4])
960
962
961 for fil in range(4):
963 for fil in range(4):
962 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
964 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
963
965
964 xx_inv = numpy.linalg.inv(xx)
966 xx_inv = numpy.linalg.inv(xx)
965 xx_aux = xx_inv[0, :]
967 xx_aux = xx_inv[0, :]
966
968
967 for ich in range(num_chan):
969 for ich in range(num_chan):
968 yy = jspectra[ich, ind_vel, :]
970 yy = jspectra[ich, ind_vel, :]
969 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
971 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
970
972
971 junkid = jspectra[ich, freq_dc, :] <= 0
973 junkid = jspectra[ich, freq_dc, :] <= 0
972 cjunkid = sum(junkid)
974 cjunkid = sum(junkid)
973
975
974 if cjunkid.any():
976 if cjunkid.any():
975 jspectra[ich, freq_dc, junkid.nonzero()] = (
977 jspectra[ich, freq_dc, junkid.nonzero()] = (
976 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
978 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
977
979
978 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
980 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
979
981
980 return noise
982 return noise
981
983
982 def getTimeInterval(self):
984 def getTimeInterval(self):
983
985
984 timeInterval = self.ippSeconds * self.nCohInt * self.nProfiles
986 timeInterval = self.ippSeconds * self.nCohInt * self.nProfiles
985
987
986 return timeInterval
988 return timeInterval
987
989
988 def splitFunctions(self):
990 def splitFunctions(self):
989
991
990 pairsList = self.pairsList
992 pairsList = self.pairsList
991 ccf_pairs = []
993 ccf_pairs = []
992 acf_pairs = []
994 acf_pairs = []
993 ccf_ind = []
995 ccf_ind = []
994 acf_ind = []
996 acf_ind = []
995 for l in range(len(pairsList)):
997 for l in range(len(pairsList)):
996 chan0 = pairsList[l][0]
998 chan0 = pairsList[l][0]
997 chan1 = pairsList[l][1]
999 chan1 = pairsList[l][1]
998
1000
999 # Obteniendo pares de Autocorrelacion
1001 # Obteniendo pares de Autocorrelacion
1000 if chan0 == chan1:
1002 if chan0 == chan1:
1001 acf_pairs.append(chan0)
1003 acf_pairs.append(chan0)
1002 acf_ind.append(l)
1004 acf_ind.append(l)
1003 else:
1005 else:
1004 ccf_pairs.append(pairsList[l])
1006 ccf_pairs.append(pairsList[l])
1005 ccf_ind.append(l)
1007 ccf_ind.append(l)
1006
1008
1007 data_acf = self.data_cf[acf_ind]
1009 data_acf = self.data_cf[acf_ind]
1008 data_ccf = self.data_cf[ccf_ind]
1010 data_ccf = self.data_cf[ccf_ind]
1009
1011
1010 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
1012 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
1011
1013
1012 def getNormFactor(self):
1014 def getNormFactor(self):
1013 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
1015 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
1014 acf_pairs = numpy.array(acf_pairs)
1016 acf_pairs = numpy.array(acf_pairs)
1015 normFactor = numpy.zeros((self.nPairs, self.nHeights))
1017 normFactor = numpy.zeros((self.nPairs, self.nHeights))
1016
1018
1017 for p in range(self.nPairs):
1019 for p in range(self.nPairs):
1018 pair = self.pairsList[p]
1020 pair = self.pairsList[p]
1019
1021
1020 ch0 = pair[0]
1022 ch0 = pair[0]
1021 ch1 = pair[1]
1023 ch1 = pair[1]
1022
1024
1023 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
1025 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
1024 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
1026 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
1025 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
1027 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
1026
1028
1027 return normFactor
1029 return normFactor
1028
1030
1029 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
1031 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
1030 normFactor = property(getNormFactor, "I'm the 'normFactor property'")
1032 normFactor = property(getNormFactor, "I'm the 'normFactor property'")
1031
1033
1032
1034
1033 class Parameters(Spectra):
1035 class Parameters(Spectra):
1034
1036
1035 experimentInfo = None # Information about the experiment
1037 experimentInfo = None # Information about the experiment
1036 # Information from previous data
1038 # Information from previous data
1037 inputUnit = None # Type of data to be processed
1039 inputUnit = None # Type of data to be processed
1038 operation = None # Type of operation to parametrize
1040 operation = None # Type of operation to parametrize
1039 # normFactor = None #Normalization Factor
1041 # normFactor = None #Normalization Factor
1040 groupList = None # List of Pairs, Groups, etc
1042 groupList = None # List of Pairs, Groups, etc
1041 # Parameters
1043 # Parameters
1042 data_param = None # Parameters obtained
1044 data_param = None # Parameters obtained
1043 data_pre = None # Data Pre Parametrization
1045 data_pre = None # Data Pre Parametrization
1044 data_SNR = None # Signal to Noise Ratio
1046 data_SNR = None # Signal to Noise Ratio
1045 # heightRange = None #Heights
1047 # heightRange = None #Heights
1046 abscissaList = None # Abscissa, can be velocities, lags or time
1048 abscissaList = None # Abscissa, can be velocities, lags or time
1047 # noise = None #Noise Potency
1049 # noise = None #Noise Potency
1048 utctimeInit = None # Initial UTC time
1050 utctimeInit = None # Initial UTC time
1049 paramInterval = None # Time interval to calculate Parameters in seconds
1051 paramInterval = None # Time interval to calculate Parameters in seconds
1050 useLocalTime = True
1052 useLocalTime = True
1051 # Fitting
1053 # Fitting
1052 data_error = None # Error of the estimation
1054 data_error = None # Error of the estimation
1053 constants = None
1055 constants = None
1054 library = None
1056 library = None
1055 # Output signal
1057 # Output signal
1056 outputInterval = None # Time interval to calculate output signal in seconds
1058 outputInterval = None # Time interval to calculate output signal in seconds
1057 data_output = None # Out signal
1059 data_output = None # Out signal
1058 nAvg = None
1060 nAvg = None
1059 noise_estimation = None
1061 noise_estimation = None
1060 GauSPC = None # Fit gaussian SPC
1062 GauSPC = None # Fit gaussian SPC
1061
1063
1062 def __init__(self):
1064 def __init__(self):
1063 '''
1065 '''
1064 Constructor
1066 Constructor
1065 '''
1067 '''
1066 self.radarControllerHeaderObj = RadarControllerHeader()
1068 self.radarControllerHeaderObj = RadarControllerHeader()
1067
1069
1068 self.systemHeaderObj = SystemHeader()
1070 self.systemHeaderObj = SystemHeader()
1069
1071
1070 self.type = "Parameters"
1072 self.type = "Parameters"
1071
1073
1072 def getTimeRange1(self, interval):
1074 def getTimeRange1(self, interval):
1073
1075
1074 datatime = []
1076 datatime = []
1075
1077
1076 if self.useLocalTime:
1078 if self.useLocalTime:
1077 time1 = self.utctimeInit - self.timeZone * 60
1079 time1 = self.utctimeInit - self.timeZone * 60
1078 else:
1080 else:
1079 time1 = self.utctimeInit
1081 time1 = self.utctimeInit
1080
1082
1081 datatime.append(time1)
1083 datatime.append(time1)
1082 datatime.append(time1 + interval)
1084 datatime.append(time1 + interval)
1083 datatime = numpy.array(datatime)
1085 datatime = numpy.array(datatime)
1084
1086
1085 return datatime
1087 return datatime
1086
1088
1087 def getTimeInterval(self):
1089 def getTimeInterval(self):
1088
1090
1089 if hasattr(self, 'timeInterval1'):
1091 if hasattr(self, 'timeInterval1'):
1090 return self.timeInterval1
1092 return self.timeInterval1
1091 else:
1093 else:
1092 return self.paramInterval
1094 return self.paramInterval
1093
1095
1094 def setValue(self, value):
1096 def setValue(self, value):
1095
1097
1096 print("This property should not be initialized")
1098 print("This property should not be initialized")
1097
1099
1098 return
1100 return
1099
1101
1100 def getNoise(self):
1102 def getNoise(self):
1101
1103
1102 return self.spc_noise
1104 return self.spc_noise
1103
1105
1104 timeInterval = property(getTimeInterval)
1106 timeInterval = property(getTimeInterval)
1105 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
1107 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
1106
1108
1107
1109
1108 class PlotterData(object):
1110 class PlotterData(object):
1109 '''
1111 '''
1110 Object to hold data to be plotted
1112 Object to hold data to be plotted
1111 '''
1113 '''
1112
1114
1113 MAXNUMX = 200
1115 MAXNUMX = 200
1114 MAXNUMY = 200
1116 MAXNUMY = 200
1115
1117
1116 def __init__(self, code, throttle_value, exp_code, buffering=True, snr=False):
1118 def __init__(self, code, throttle_value, exp_code, buffering=True, snr=False):
1117
1119
1118 self.key = code
1120 self.key = code
1119 self.throttle = throttle_value
1121 self.throttle = throttle_value
1120 self.exp_code = exp_code
1122 self.exp_code = exp_code
1121 self.buffering = buffering
1123 self.buffering = buffering
1122 self.ready = False
1124 self.ready = False
1123 self.flagNoData = False
1125 self.flagNoData = False
1124 self.localtime = False
1126 self.localtime = False
1125 self.data = {}
1127 self.data = {}
1126 self.meta = {}
1128 self.meta = {}
1127 self.__heights = []
1129 self.__heights = []
1128
1130
1129 if 'snr' in code:
1131 if 'snr' in code:
1130 self.plottypes = ['snr']
1132 self.plottypes = ['snr']
1131 elif code == 'spc':
1133 elif code == 'spc':
1132 self.plottypes = ['spc', 'noise', 'rti']
1134 self.plottypes = ['spc', 'noise', 'rti']
1133 elif code == 'cspc':
1135 elif code == 'cspc':
1134 self.plottypes = ['cspc', 'spc', 'noise', 'rti']
1136 self.plottypes = ['cspc', 'spc', 'noise', 'rti']
1135 elif code == 'rti':
1137 elif code == 'rti':
1136 self.plottypes = ['noise', 'rti']
1138 self.plottypes = ['noise', 'rti']
1137 else:
1139 else:
1138 self.plottypes = [code]
1140 self.plottypes = [code]
1139
1141
1140 if 'snr' not in self.plottypes and snr:
1142 if 'snr' not in self.plottypes and snr:
1141 self.plottypes.append('snr')
1143 self.plottypes.append('snr')
1142
1144
1143 for plot in self.plottypes:
1145 for plot in self.plottypes:
1144 self.data[plot] = {}
1146 self.data[plot] = {}
1145
1147
1146
1148
1147 def __str__(self):
1149 def __str__(self):
1148 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
1150 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
1149 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
1151 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
1150
1152
1151 def __len__(self):
1153 def __len__(self):
1152 return len(self.data[self.key])
1154 return len(self.data[self.key])
1153
1155
1154 def __getitem__(self, key):
1156 def __getitem__(self, key):
1155
1157
1156 if key not in self.data:
1158 if key not in self.data:
1157 raise KeyError(log.error('Missing key: {}'.format(key)))
1159 raise KeyError(log.error('Missing key: {}'.format(key)))
1158 if 'spc' in key or not self.buffering:
1160 if 'spc' in key or not self.buffering:
1159 ret = self.data[key][self.tm]
1161 ret = self.data[key][self.tm]
1160 elif 'scope' in key:
1162 elif 'scope' in key:
1161 ret = numpy.array(self.data[key][float(self.tm)])
1163 ret = numpy.array(self.data[key][float(self.tm)])
1162 else:
1164 else:
1163 ret = numpy.array([self.data[key][x] for x in self.times])
1165 ret = numpy.array([self.data[key][x] for x in self.times])
1164 if ret.ndim > 1:
1166 if ret.ndim > 1:
1165 ret = numpy.swapaxes(ret, 0, 1)
1167 ret = numpy.swapaxes(ret, 0, 1)
1166 return ret
1168 return ret
1167
1169
1168 def __contains__(self, key):
1170 def __contains__(self, key):
1169 return key in self.data
1171 return key in self.data
1170
1172
1171 def setup(self):
1173 def setup(self):
1172 '''
1174 '''
1173 Configure object
1175 Configure object
1174 '''
1176 '''
1175 self.type = ''
1177 self.type = ''
1176 self.ready = False
1178 self.ready = False
1177 del self.data
1179 del self.data
1178 self.data = {}
1180 self.data = {}
1179 self.__heights = []
1181 self.__heights = []
1180 self.__all_heights = set()
1182 self.__all_heights = set()
1181 for plot in self.plottypes:
1183 for plot in self.plottypes:
1182 if 'snr' in plot:
1184 if 'snr' in plot:
1183 plot = 'snr'
1185 plot = 'snr'
1184 elif 'spc_moments' == plot:
1186 elif 'spc_moments' == plot:
1185 plot = 'moments'
1187 plot = 'moments'
1186 self.data[plot] = {}
1188 self.data[plot] = {}
1187
1189
1188 if 'spc' in self.data or 'rti' in self.data or 'cspc' in self.data or 'moments' in self.data:
1190 if 'spc' in self.data or 'rti' in self.data or 'cspc' in self.data or 'moments' in self.data:
1189 self.data['noise'] = {}
1191 self.data['noise'] = {}
1190 self.data['rti'] = {}
1192 self.data['rti'] = {}
1191 if 'noise' not in self.plottypes:
1193 if 'noise' not in self.plottypes:
1192 self.plottypes.append('noise')
1194 self.plottypes.append('noise')
1193 if 'rti' not in self.plottypes:
1195 if 'rti' not in self.plottypes:
1194 self.plottypes.append('rti')
1196 self.plottypes.append('rti')
1195
1197
1196 def shape(self, key):
1198 def shape(self, key):
1197 '''
1199 '''
1198 Get the shape of the one-element data for the given key
1200 Get the shape of the one-element data for the given key
1199 '''
1201 '''
1200
1202
1201 if len(self.data[key]):
1203 if len(self.data[key]):
1202 if 'spc' in key or not self.buffering:
1204 if 'spc' in key or not self.buffering:
1203 return self.data[key].shape
1205 return self.data[key].shape
1204 return self.data[key][self.times[0]].shape
1206 return self.data[key][self.times[0]].shape
1205 return (0,)
1207 return (0,)
1206
1208
1207 def update(self, dataOut, tm):
1209 def update(self, dataOut, tm):
1208 '''
1210 '''
1209 Update data object with new dataOut
1211 Update data object with new dataOut
1210 '''
1212 '''
1211
1213
1212 self.profileIndex = dataOut.profileIndex
1214 self.profileIndex = dataOut.profileIndex
1213 self.tm = tm
1215 self.tm = tm
1214 self.type = dataOut.type
1216 self.type = dataOut.type
1215 self.parameters = getattr(dataOut, 'parameters', [])
1217 self.parameters = getattr(dataOut, 'parameters', [])
1216
1218
1217 if hasattr(dataOut, 'meta'):
1219 if hasattr(dataOut, 'meta'):
1218 self.meta.update(dataOut.meta)
1220 self.meta.update(dataOut.meta)
1219
1221
1220 if hasattr(dataOut, 'pairsList'):
1222 if hasattr(dataOut, 'pairsList'):
1221 self.pairs = dataOut.pairsList
1223 self.pairs = dataOut.pairsList
1222
1224
1223 self.interval = dataOut.getTimeInterval()
1225 self.interval = dataOut.getTimeInterval()
1224 self.localtime = dataOut.useLocalTime
1226 self.localtime = dataOut.useLocalTime
1225 if True in ['spc' in ptype for ptype in self.plottypes]:
1227 if True in ['spc' in ptype for ptype in self.plottypes]:
1226 self.xrange = (dataOut.getFreqRange(1)/1000.,
1228 self.xrange = (dataOut.getFreqRange(1)/1000.,
1227 dataOut.getAcfRange(1), dataOut.getVelRange(1))
1229 dataOut.getAcfRange(1), dataOut.getVelRange(1))
1228 self.__heights.append(dataOut.heightList)
1230 self.__heights.append(dataOut.heightList)
1229 self.__all_heights.update(dataOut.heightList)
1231 self.__all_heights.update(dataOut.heightList)
1230
1232
1231 for plot in self.plottypes:
1233 for plot in self.plottypes:
1232 if plot in ('spc', 'spc_moments', 'spc_cut'):
1234 if plot in ('spc', 'spc_moments', 'spc_cut'):
1233 z = dataOut.data_spc/dataOut.normFactor
1235 z = dataOut.data_spc/dataOut.normFactor
1234 buffer = 10*numpy.log10(z)
1236 buffer = 10*numpy.log10(z)
1235 if plot == 'cspc':
1237 if plot == 'cspc':
1236 buffer = (dataOut.data_spc, dataOut.data_cspc)
1238 buffer = (dataOut.data_spc, dataOut.data_cspc)
1237 if plot == 'noise':
1239 if plot == 'noise':
1238 buffer = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
1240 buffer = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
1239 if plot in ('rti', 'spcprofile'):
1241 if plot in ('rti', 'spcprofile'):
1240 buffer = dataOut.getPower()
1242 buffer = dataOut.getPower()
1241 if plot == 'snr_db':
1243 if plot == 'snr_db':
1242 buffer = dataOut.data_SNR
1244 buffer = dataOut.data_SNR
1243 if plot == 'snr':
1245 if plot == 'snr':
1244 buffer = 10*numpy.log10(dataOut.data_SNR)
1246 buffer = 10*numpy.log10(dataOut.data_SNR)
1245 if plot == 'dop':
1247 if plot == 'dop':
1246 buffer = dataOut.data_DOP
1248 buffer = dataOut.data_DOP
1247 if plot == 'pow':
1249 if plot == 'pow':
1248 buffer = 10*numpy.log10(dataOut.data_POW)
1250 buffer = 10*numpy.log10(dataOut.data_POW)
1249 if plot == 'width':
1251 if plot == 'width':
1250 buffer = dataOut.data_WIDTH
1252 buffer = dataOut.data_WIDTH
1251 if plot == 'coh':
1253 if plot == 'coh':
1252 buffer = dataOut.getCoherence()
1254 buffer = dataOut.getCoherence()
1253 if plot == 'phase':
1255 if plot == 'phase':
1254 buffer = dataOut.getCoherence(phase=True)
1256 buffer = dataOut.getCoherence(phase=True)
1255 if plot == 'output':
1257 if plot == 'output':
1256 buffer = dataOut.data_output
1258 buffer = dataOut.data_output
1257 if plot == 'param':
1259 if plot == 'param':
1258 buffer = dataOut.data_param
1260 buffer = dataOut.data_param
1259 if plot == 'scope':
1261 if plot == 'scope':
1260 buffer = dataOut.data
1262 buffer = dataOut.data
1261 self.flagDataAsBlock = dataOut.flagDataAsBlock
1263 self.flagDataAsBlock = dataOut.flagDataAsBlock
1262 self.nProfiles = dataOut.nProfiles
1264 self.nProfiles = dataOut.nProfiles
1263 if plot == 'pp_power':
1265 if plot == 'pp_power':
1264 buffer = dataOut.data_intensity
1266 buffer = dataOut.dataPP_POWER
1267 self.flagDataAsBlock = dataOut.flagDataAsBlock
1268 self.nProfiles = dataOut.nProfiles
1269 if plot == 'pp_signal':
1270 buffer = dataOut.dataPP_POW
1265 self.flagDataAsBlock = dataOut.flagDataAsBlock
1271 self.flagDataAsBlock = dataOut.flagDataAsBlock
1266 self.nProfiles = dataOut.nProfiles
1272 self.nProfiles = dataOut.nProfiles
1267 if plot == 'pp_velocity':
1273 if plot == 'pp_velocity':
1268 buffer = dataOut.data_velocity
1274 buffer = dataOut.dataPP_DOP
1269 self.flagDataAsBlock = dataOut.flagDataAsBlock
1275 self.flagDataAsBlock = dataOut.flagDataAsBlock
1270 self.nProfiles = dataOut.nProfiles
1276 self.nProfiles = dataOut.nProfiles
1271 if plot == 'pp_specwidth':
1277 if plot == 'pp_specwidth':
1272 buffer = dataOut.data_specwidth
1278 buffer = dataOut.dataPP_WIDTH
1273 self.flagDataAsBlock = dataOut.flagDataAsBlock
1279 self.flagDataAsBlock = dataOut.flagDataAsBlock
1274 self.nProfiles = dataOut.nProfiles
1280 self.nProfiles = dataOut.nProfiles
1275
1281
1276 if plot == 'spc':
1282 if plot == 'spc':
1277 self.data['spc'][tm] = buffer
1283 self.data['spc'][tm] = buffer
1278 elif plot == 'cspc':
1284 elif plot == 'cspc':
1279 self.data['cspc'][tm] = buffer
1285 self.data['cspc'][tm] = buffer
1280 elif plot == 'spc_moments':
1286 elif plot == 'spc_moments':
1281 self.data['spc'][tm] = buffer
1287 self.data['spc'][tm] = buffer
1282 self.data['moments'][tm] = dataOut.moments
1288 self.data['moments'][tm] = dataOut.moments
1283 else:
1289 else:
1284 if self.buffering:
1290 if self.buffering:
1285 self.data[plot][tm] = buffer
1291 self.data[plot][tm] = buffer
1286 else:
1292 else:
1287 self.data[plot][tm] = buffer
1293 self.data[plot][tm] = buffer
1288
1294
1289 if dataOut.channelList is None:
1295 if dataOut.channelList is None:
1290 self.channels = range(buffer.shape[0])
1296 self.channels = range(buffer.shape[0])
1291 else:
1297 else:
1292 self.channels = dataOut.channelList
1298 self.channels = dataOut.channelList
1293
1299
1294 if buffer is None:
1300 if buffer is None:
1295 self.flagNoData = True
1301 self.flagNoData = True
1296 raise schainpy.admin.SchainWarning('Attribute data_{} is empty'.format(self.key))
1302 raise schainpy.admin.SchainWarning('Attribute data_{} is empty'.format(self.key))
1297
1303
1298 def normalize_heights(self):
1304 def normalize_heights(self):
1299 '''
1305 '''
1300 Ensure same-dimension of the data for different heighList
1306 Ensure same-dimension of the data for different heighList
1301 '''
1307 '''
1302
1308
1303 H = numpy.array(list(self.__all_heights))
1309 H = numpy.array(list(self.__all_heights))
1304 H.sort()
1310 H.sort()
1305 for key in self.data:
1311 for key in self.data:
1306 shape = self.shape(key)[:-1] + H.shape
1312 shape = self.shape(key)[:-1] + H.shape
1307 for tm, obj in list(self.data[key].items()):
1313 for tm, obj in list(self.data[key].items()):
1308 h = self.__heights[self.times.tolist().index(tm)]
1314 h = self.__heights[self.times.tolist().index(tm)]
1309 if H.size == h.size:
1315 if H.size == h.size:
1310 continue
1316 continue
1311 index = numpy.where(numpy.in1d(H, h))[0]
1317 index = numpy.where(numpy.in1d(H, h))[0]
1312 dummy = numpy.zeros(shape) + numpy.nan
1318 dummy = numpy.zeros(shape) + numpy.nan
1313 if len(shape) == 2:
1319 if len(shape) == 2:
1314 dummy[:, index] = obj
1320 dummy[:, index] = obj
1315 else:
1321 else:
1316 dummy[index] = obj
1322 dummy[index] = obj
1317 self.data[key][tm] = dummy
1323 self.data[key][tm] = dummy
1318
1324
1319 self.__heights = [H for tm in self.times]
1325 self.__heights = [H for tm in self.times]
1320
1326
1321 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1327 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1322 '''
1328 '''
1323 Convert data to json
1329 Convert data to json
1324 '''
1330 '''
1325
1331
1326 dy = int(self.heights.size/self.MAXNUMY) + 1
1332 dy = int(self.heights.size/self.MAXNUMY) + 1
1327 if self.key in ('spc', 'cspc'):
1333 if self.key in ('spc', 'cspc'):
1328 dx = int(self.data[self.key][tm].shape[1]/self.MAXNUMX) + 1
1334 dx = int(self.data[self.key][tm].shape[1]/self.MAXNUMX) + 1
1329 data = self.roundFloats(
1335 data = self.roundFloats(
1330 self.data[self.key][tm][::, ::dx, ::dy].tolist())
1336 self.data[self.key][tm][::, ::dx, ::dy].tolist())
1331 else:
1337 else:
1332 if self.key is 'noise':
1338 if self.key is 'noise':
1333 data = [[x] for x in self.roundFloats(self.data[self.key][tm].tolist())]
1339 data = [[x] for x in self.roundFloats(self.data[self.key][tm].tolist())]
1334 else:
1340 else:
1335 data = self.roundFloats(self.data[self.key][tm][::, ::dy].tolist())
1341 data = self.roundFloats(self.data[self.key][tm][::, ::dy].tolist())
1336
1342
1337 meta = {}
1343 meta = {}
1338 ret = {
1344 ret = {
1339 'plot': plot_name,
1345 'plot': plot_name,
1340 'code': self.exp_code,
1346 'code': self.exp_code,
1341 'time': float(tm),
1347 'time': float(tm),
1342 'data': data,
1348 'data': data,
1343 }
1349 }
1344 meta['type'] = plot_type
1350 meta['type'] = plot_type
1345 meta['interval'] = float(self.interval)
1351 meta['interval'] = float(self.interval)
1346 meta['localtime'] = self.localtime
1352 meta['localtime'] = self.localtime
1347 meta['yrange'] = self.roundFloats(self.heights[::dy].tolist())
1353 meta['yrange'] = self.roundFloats(self.heights[::dy].tolist())
1348 if 'spc' in self.data or 'cspc' in self.data:
1354 if 'spc' in self.data or 'cspc' in self.data:
1349 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1355 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1350 else:
1356 else:
1351 meta['xrange'] = []
1357 meta['xrange'] = []
1352
1358
1353 meta.update(self.meta)
1359 meta.update(self.meta)
1354 ret['metadata'] = meta
1360 ret['metadata'] = meta
1355 return json.dumps(ret)
1361 return json.dumps(ret)
1356
1362
1357 @property
1363 @property
1358 def times(self):
1364 def times(self):
1359 '''
1365 '''
1360 Return the list of times of the current data
1366 Return the list of times of the current data
1361 '''
1367 '''
1362
1368
1363 ret = numpy.array([*self.data[self.key]])
1369 ret = numpy.array([*self.data[self.key]])
1364 if self:
1370 if self:
1365 ret.sort()
1371 ret.sort()
1366 return ret
1372 return ret
1367
1373
1368 @property
1374 @property
1369 def min_time(self):
1375 def min_time(self):
1370 '''
1376 '''
1371 Return the minimun time value
1377 Return the minimun time value
1372 '''
1378 '''
1373
1379
1374 return self.times[0]
1380 return self.times[0]
1375
1381
1376 @property
1382 @property
1377 def max_time(self):
1383 def max_time(self):
1378 '''
1384 '''
1379 Return the maximun time value
1385 Return the maximun time value
1380 '''
1386 '''
1381
1387
1382 return self.times[-1]
1388 return self.times[-1]
1383
1389
1384 @property
1390 @property
1385 def heights(self):
1391 def heights(self):
1386 '''
1392 '''
1387 Return the list of heights of the current data
1393 Return the list of heights of the current data
1388 '''
1394 '''
1389
1395
1390 return numpy.array(self.__heights[-1])
1396 return numpy.array(self.__heights[-1])
1391
1397
1392 @staticmethod
1398 @staticmethod
1393 def roundFloats(obj):
1399 def roundFloats(obj):
1394 if isinstance(obj, list):
1400 if isinstance(obj, list):
1395 return list(map(PlotterData.roundFloats, obj))
1401 return list(map(PlotterData.roundFloats, obj))
1396 elif isinstance(obj, float):
1402 elif isinstance(obj, float):
1397 return round(obj, 2)
1403 return round(obj, 2)
@@ -1,276 +1,302
1 '''
1 '''
2 Created on Jul 9, 2014
2 Created on Jul 9, 2014
3
3
4 @author: roj-idl71
4 @author: roj-idl71
5 '''
5 '''
6 import os
6 import os
7 import datetime
7 import datetime
8 import numpy
8 import numpy
9
9
10 from schainpy.model.graphics.jroplot_base import Plot, plt
10 from schainpy.model.graphics.jroplot_base import Plot, plt
11
11
12
12
13 class ScopePlot(Plot):
13 class ScopePlot(Plot):
14
14
15 '''
15 '''
16 Plot for Scope
16 Plot for Scope
17 '''
17 '''
18
18
19 CODE = 'scope'
19 CODE = 'scope'
20 plot_name = 'Scope'
20 plot_name = 'Scope'
21 plot_type = 'scatter'
21 plot_type = 'scatter'
22
22
23 def setup(self):
23 def setup(self):
24
24
25 self.xaxis = 'Range (Km)'
25 self.xaxis = 'Range (Km)'
26 self.ncols = 1
26 self.ncols = 1
27 self.nrows = 1
27 self.nrows = 1
28 self.nplots = 1
28 self.nplots = 1
29 self.ylabel = 'Intensity [dB]'
29 self.ylabel = 'Intensity [dB]'
30 self.titles = ['Scope']
30 self.titles = ['Scope']
31 self.colorbar = False
31 self.colorbar = False
32 self.width = 6
32 self.width = 6
33 self.height = 4
33 self.height = 4
34
34
35 def plot_iq(self, x, y, channelIndexList, thisDatetime, wintitle):
35 def plot_iq(self, x, y, channelIndexList, thisDatetime, wintitle):
36
36
37 yreal = y[channelIndexList,:].real
37 yreal = y[channelIndexList,:].real
38 yimag = y[channelIndexList,:].imag
38 yimag = y[channelIndexList,:].imag
39 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y"))
39 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y"))
40 self.xlabel = "Range (Km)"
40 self.xlabel = "Range (Km)"
41 self.ylabel = "Intensity - IQ"
41 self.ylabel = "Intensity - IQ"
42
42
43 self.y = yreal
43 self.y = yreal
44 self.x = x
44 self.x = x
45 self.xmin = min(x)
45 self.xmin = min(x)
46 self.xmax = max(x)
46 self.xmax = max(x)
47
47
48
48
49 self.titles[0] = title
49 self.titles[0] = title
50
50
51 for i,ax in enumerate(self.axes):
51 for i,ax in enumerate(self.axes):
52 title = "Channel %d" %(i)
52 title = "Channel %d" %(i)
53 if ax.firsttime:
53 if ax.firsttime:
54 ax.plt_r = ax.plot(x, yreal[i,:], color='b')[0]
54 ax.plt_r = ax.plot(x, yreal[i,:], color='b')[0]
55 ax.plt_i = ax.plot(x, yimag[i,:], color='r')[0]
55 ax.plt_i = ax.plot(x, yimag[i,:], color='r')[0]
56 else:
56 else:
57 ax.plt_r.set_data(x, yreal[i,:])
57 ax.plt_r.set_data(x, yreal[i,:])
58 ax.plt_i.set_data(x, yimag[i,:])
58 ax.plt_i.set_data(x, yimag[i,:])
59
59
60 def plot_power(self, x, y, channelIndexList, thisDatetime, wintitle):
60 def plot_power(self, x, y, channelIndexList, thisDatetime, wintitle):
61 y = y[channelIndexList,:] * numpy.conjugate(y[channelIndexList,:])
61 y = y[channelIndexList,:] * numpy.conjugate(y[channelIndexList,:])
62 yreal = y.real
62 yreal = y.real
63 yreal = 10*numpy.log10(yreal)
63 yreal = 10*numpy.log10(yreal)
64 self.y = yreal
64 self.y = yreal
65 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y"))
65 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y"))
66 self.xlabel = "Range (Km)"
66 self.xlabel = "Range (Km)"
67 self.ylabel = "Intensity"
67 self.ylabel = "Intensity"
68 self.xmin = min(x)
68 self.xmin = min(x)
69 self.xmax = max(x)
69 self.xmax = max(x)
70
70
71
71
72 self.titles[0] = title
72 self.titles[0] = title
73
73
74 for i,ax in enumerate(self.axes):
74 for i,ax in enumerate(self.axes):
75 title = "Channel %d" %(i)
75 title = "Channel %d" %(i)
76
76
77 ychannel = yreal[i,:]
77 ychannel = yreal[i,:]
78
78
79 if ax.firsttime:
79 if ax.firsttime:
80 ax.plt_r = ax.plot(x, ychannel)[0]
80 ax.plt_r = ax.plot(x, ychannel)[0]
81 else:
81 else:
82 #pass
82 #pass
83 ax.plt_r.set_data(x, ychannel)
83 ax.plt_r.set_data(x, ychannel)
84
84
85 def plot_weatherpower(self, x, y, channelIndexList, thisDatetime, wintitle):
85 def plot_weatherpower(self, x, y, channelIndexList, thisDatetime, wintitle):
86
86
87
87
88 y = y[channelIndexList,:]
88 y = y[channelIndexList,:]
89 yreal = y.real
89 yreal = y.real
90 yreal = 10*numpy.log10(yreal)
90 yreal = 10*numpy.log10(yreal)
91 self.y = yreal
91 self.y = yreal
92 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
92 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
93 self.xlabel = "Range (Km)"
93 self.xlabel = "Range (Km)"
94 self.ylabel = "Intensity"
94 self.ylabel = "Intensity"
95 self.xmin = min(x)
95 self.xmin = min(x)
96 self.xmax = max(x)
96 self.xmax = max(x)
97
97
98 self.titles[0] =title
98 self.titles[0] =title
99 for i,ax in enumerate(self.axes):
99 for i,ax in enumerate(self.axes):
100 title = "Channel %d" %(i)
100 title = "Channel %d" %(i)
101
101
102 ychannel = yreal[i,:]
102 ychannel = yreal[i,:]
103
103
104 if ax.firsttime:
104 if ax.firsttime:
105 ax.plt_r = ax.plot(x, ychannel)[0]
105 ax.plt_r = ax.plot(x, ychannel)[0]
106 else:
106 else:
107 #pass
107 #pass
108 ax.plt_r.set_data(x, ychannel)
108 ax.plt_r.set_data(x, ychannel)
109
109
110 def plot_weathervelocity(self, x, y, channelIndexList, thisDatetime, wintitle):
110 def plot_weathervelocity(self, x, y, channelIndexList, thisDatetime, wintitle):
111
111
112 x = x[channelIndexList,:]
112 x = x[channelIndexList,:]
113 yreal = y
113 yreal = y
114 self.y = yreal
114 self.y = yreal
115 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
115 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
116 self.xlabel = "Velocity (m/s)"
116 self.xlabel = "Velocity (m/s)"
117 self.ylabel = "Range (Km)"
117 self.ylabel = "Range (Km)"
118 self.xmin = numpy.min(x)
118 self.xmin = numpy.min(x)
119 self.xmax = numpy.max(x)
119 self.xmax = numpy.max(x)
120 self.titles[0] =title
120 self.titles[0] =title
121 for i,ax in enumerate(self.axes):
121 for i,ax in enumerate(self.axes):
122 title = "Channel %d" %(i)
122 title = "Channel %d" %(i)
123 xchannel = x[i,:]
123 xchannel = x[i,:]
124 if ax.firsttime:
124 if ax.firsttime:
125 ax.plt_r = ax.plot(xchannel, yreal)[0]
125 ax.plt_r = ax.plot(xchannel, yreal)[0]
126 else:
126 else:
127 #pass
127 #pass
128 ax.plt_r.set_data(xchannel, yreal)
128 ax.plt_r.set_data(xchannel, yreal)
129
129
130 def plot_weatherspecwidth(self, x, y, channelIndexList, thisDatetime, wintitle):
130 def plot_weatherspecwidth(self, x, y, channelIndexList, thisDatetime, wintitle):
131
131
132 x = x[channelIndexList,:]
132 x = x[channelIndexList,:]
133 yreal = y
133 yreal = y
134 self.y = yreal
134 self.y = yreal
135 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
135 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
136 self.xlabel = "width "
136 self.xlabel = "width "
137 self.ylabel = "Range (Km)"
137 self.ylabel = "Range (Km)"
138 self.xmin = numpy.min(x)
138 self.xmin = numpy.min(x)
139 self.xmax = numpy.max(x)
139 self.xmax = numpy.max(x)
140 self.titles[0] =title
140 self.titles[0] =title
141 for i,ax in enumerate(self.axes):
141 for i,ax in enumerate(self.axes):
142 title = "Channel %d" %(i)
142 title = "Channel %d" %(i)
143 xchannel = x[i,:]
143 xchannel = x[i,:]
144 if ax.firsttime:
144 if ax.firsttime:
145 ax.plt_r = ax.plot(xchannel, yreal)[0]
145 ax.plt_r = ax.plot(xchannel, yreal)[0]
146 else:
146 else:
147 #pass
147 #pass
148 ax.plt_r.set_data(xchannel, yreal)
148 ax.plt_r.set_data(xchannel, yreal)
149
149
150 def plot(self):
150 def plot(self):
151 if self.channels:
151 if self.channels:
152 channels = self.channels
152 channels = self.channels
153 else:
153 else:
154 channels = self.data.channels
154 channels = self.data.channels
155
155
156 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1])
156 thisDatetime = datetime.datetime.utcfromtimestamp(self.data.times[-1])
157 if self.CODE == "pp_power":
157 if self.CODE == "pp_power":
158 scope = self.data['pp_power']
158 scope = self.data['pp_power']
159 elif self.CODE == "pp_signal":
160 scope = self.data["pp_signal"]
159 elif self.CODE == "pp_velocity":
161 elif self.CODE == "pp_velocity":
160 scope = self.data["pp_velocity"]
162 scope = self.data["pp_velocity"]
161 elif self.CODE == "pp_specwidth":
163 elif self.CODE == "pp_specwidth":
162 scope = self.data["pp_specwidth"]
164 scope = self.data["pp_specwidth"]
163 else:
165 else:
164 scope =self.data["scope"]
166 scope =self.data["scope"]
165
167
166 if self.data.flagDataAsBlock:
168 if self.data.flagDataAsBlock:
167
169
168 for i in range(self.data.nProfiles):
170 for i in range(self.data.nProfiles):
169
171
170 wintitle1 = " [Profile = %d] " %i
172 wintitle1 = " [Profile = %d] " %i
171 if self.CODE =="scope":
173 if self.CODE =="scope":
172 if self.type == "power":
174 if self.type == "power":
173 self.plot_power(self.data.heights,
175 self.plot_power(self.data.heights,
174 scope[:,i,:],
176 scope[:,i,:],
175 channels,
177 channels,
176 thisDatetime,
178 thisDatetime,
177 wintitle1
179 wintitle1
178 )
180 )
179
181
180 if self.type == "iq":
182 if self.type == "iq":
181 self.plot_iq(self.data.heights,
183 self.plot_iq(self.data.heights,
182 scope[:,i,:],
184 scope[:,i,:],
183 channels,
185 channels,
184 thisDatetime,
186 thisDatetime,
185 wintitle1
187 wintitle1
186 )
188 )
187 if self.CODE=="pp_power":
189 if self.CODE=="pp_power":
188 self.plot_weatherpower(self.data.heights,
190 self.plot_weatherpower(self.data.heights,
189 scope[:,i,:],
191 scope[:,i,:],
190 channels,
192 channels,
191 thisDatetime,
193 thisDatetime,
192 wintitle
194 wintitle
193 )
195 )
196 if self.CODE=="pp_signal":
197 self.plot_weatherpower(self.data.heights,
198 scope[:,i,:],
199 channels,
200 thisDatetime,
201 wintitle
202 )
194 if self.CODE=="pp_velocity":
203 if self.CODE=="pp_velocity":
195 self.plot_weathervelocity(scope[:,i,:],
204 self.plot_weathervelocity(scope[:,i,:],
196 self.data.heights,
205 self.data.heights,
197 channels,
206 channels,
198 thisDatetime,
207 thisDatetime,
199 wintitle
208 wintitle
200 )
209 )
201 if self.CODE=="pp_spcwidth":
210 if self.CODE=="pp_spcwidth":
202 self.plot_weatherspecwidth(scope[:,i,:],
211 self.plot_weatherspecwidth(scope[:,i,:],
203 self.data.heights,
212 self.data.heights,
204 channels,
213 channels,
205 thisDatetime,
214 thisDatetime,
206 wintitle
215 wintitle
207 )
216 )
208 else:
217 else:
209 wintitle = " [Profile = %d] " %self.data.profileIndex
218 wintitle = " [Profile = %d] " %self.data.profileIndex
210 if self.CODE== "scope":
219 if self.CODE== "scope":
211 if self.type == "power":
220 if self.type == "power":
212 self.plot_power(self.data.heights,
221 self.plot_power(self.data.heights,
213 scope,
222 scope,
214 channels,
223 channels,
215 thisDatetime,
224 thisDatetime,
216 wintitle
225 wintitle
217 )
226 )
218
227
219 if self.type == "iq":
228 if self.type == "iq":
220 self.plot_iq(self.data.heights,
229 self.plot_iq(self.data.heights,
221 scope,
230 scope,
222 channels,
231 channels,
223 thisDatetime,
232 thisDatetime,
224 wintitle
233 wintitle
225 )
234 )
226 if self.CODE=="pp_power":
235 if self.CODE=="pp_power":
227 self.plot_weatherpower(self.data.heights,
236 self.plot_weatherpower(self.data.heights,
228 scope,
237 scope,
229 channels,
238 channels,
230 thisDatetime,
239 thisDatetime,
231 wintitle
240 wintitle
232 )
241 )
242 if self.CODE=="pp_signal":
243 self.plot_weatherpower(self.data.heights,
244 scope,
245 channels,
246 thisDatetime,
247 wintitle
248 )
233 if self.CODE=="pp_velocity":
249 if self.CODE=="pp_velocity":
234 self.plot_weathervelocity(scope,
250 self.plot_weathervelocity(scope,
235 self.data.heights,
251 self.data.heights,
236 channels,
252 channels,
237 thisDatetime,
253 thisDatetime,
238 wintitle
254 wintitle
239 )
255 )
240 if self.CODE=="pp_specwidth":
256 if self.CODE=="pp_specwidth":
241 self.plot_weatherspecwidth(scope,
257 self.plot_weatherspecwidth(scope,
242 self.data.heights,
258 self.data.heights,
243 channels,
259 channels,
244 thisDatetime,
260 thisDatetime,
245 wintitle
261 wintitle
246 )
262 )
247
263
248
264
249
265
250 class PulsepairPowerPlot(ScopePlot):
266 class PulsepairPowerPlot(ScopePlot):
251 '''
267 '''
252 Plot for
268 Plot for P= S+N
253 '''
269 '''
254
270
255 CODE = 'pp_power'
271 CODE = 'pp_power'
256 plot_name = 'PulsepairPower'
272 plot_name = 'PulsepairPower'
257 plot_type = 'scatter'
273 plot_type = 'scatter'
258 buffering = False
274 buffering = False
259
275
260 class PulsepairVelocityPlot(ScopePlot):
276 class PulsepairVelocityPlot(ScopePlot):
261 '''
277 '''
262 Plot for
278 Plot for VELOCITY
263 '''
279 '''
264 CODE = 'pp_velocity'
280 CODE = 'pp_velocity'
265 plot_name = 'PulsepairVelocity'
281 plot_name = 'PulsepairVelocity'
266 plot_type = 'scatter'
282 plot_type = 'scatter'
267 buffering = False
283 buffering = False
268
284
269 class PulsepairSpecwidthPlot(ScopePlot):
285 class PulsepairSpecwidthPlot(ScopePlot):
270 '''
286 '''
271 Plot for
287 Plot for WIDTH
272 '''
288 '''
273 CODE = 'pp_specwidth'
289 CODE = 'pp_specwidth'
274 plot_name = 'PulsepairSpecwidth'
290 plot_name = 'PulsepairSpecwidth'
275 plot_type = 'scatter'
291 plot_type = 'scatter'
276 buffering = False
292 buffering = False
293
294 class PulsepairSignalPlot(ScopePlot):
295 '''
296 Plot for S
297 '''
298
299 CODE = 'pp_signal'
300 plot_name = 'PulsepairSignal'
301 plot_type = 'scatter'
302 buffering = False
@@ -1,512 +1,519
1 import numpy,math,random,time
1 import numpy,math,random,time
2 #---------------1 Heredamos JRODatareader
2 #---------------1 Heredamos JRODatareader
3 from schainpy.model.io.jroIO_base import *
3 from schainpy.model.io.jroIO_base import *
4 #---------------2 Heredamos las propiedades de ProcessingUnit
4 #---------------2 Heredamos las propiedades de ProcessingUnit
5 from schainpy.model.proc.jroproc_base import ProcessingUnit,Operation,MPDecorator
5 from schainpy.model.proc.jroproc_base import ProcessingUnit,Operation,MPDecorator
6 #---------------3 Importaremos las clases BascicHeader, SystemHeader, RadarControlHeader, ProcessingHeader
6 #---------------3 Importaremos las clases BascicHeader, SystemHeader, RadarControlHeader, ProcessingHeader
7 from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader,SystemHeader,RadarControllerHeader, ProcessingHeader
7 from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader,SystemHeader,RadarControllerHeader, ProcessingHeader
8 #---------------4 Importaremos el objeto Voltge
8 #---------------4 Importaremos el objeto Voltge
9 from schainpy.model.data.jrodata import Voltage
9 from schainpy.model.data.jrodata import Voltage
10
10
11 class SimulatorReader(JRODataReader, ProcessingUnit):
11 class SimulatorReader(JRODataReader, ProcessingUnit):
12 incIntFactor = 1
12 incIntFactor = 1
13 nFFTPoints = 0
13 nFFTPoints = 0
14 FixPP_IncInt = 1
14 FixPP_IncInt = 1
15 FixRCP_IPP = 1000
15 FixRCP_IPP = 1000
16 FixPP_CohInt = 1
16 FixPP_CohInt = 1
17 Tau_0 = 250
17 Tau_0 = 250
18 AcqH0_0 = 70
18 AcqH0_0 = 70
19 H0 = AcqH0_0
19 H0 = AcqH0_0
20 AcqDH_0 = 1.25
20 AcqDH_0 = 1.25
21 DH0 = AcqDH_0
21 DH0 = AcqDH_0
22 Bauds = 32
22 Bauds = 32
23 BaudWidth = None
23 BaudWidth = None
24 FixRCP_TXA = 40
24 FixRCP_TXA = 40
25 FixRCP_TXB = 70
25 FixRCP_TXB = 70
26 fAngle = 2.0*math.pi*(1/16)
26 fAngle = 2.0*math.pi*(1/16)
27 DC_level = 500
27 DC_level = 500
28 stdev = 8
28 stdev = 8
29 Num_Codes = 2
29 Num_Codes = 2
30 #code0 = numpy.array([1,1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,1,1,1,0,1,1,0,1,0,0,0,1,1,1,0,1])
30 #code0 = numpy.array([1,1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,1,1,1,0,1,1,0,1,0,0,0,1,1,1,0,1])
31 #code1 = numpy.array([1,1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,1,0,1,1,1,0,0,0,1,0])
31 #code1 = numpy.array([1,1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,1,0,1,1,1,0,0,0,1,0])
32 #Dyn_snCode = numpy.array([Num_Codes,Bauds])
32 #Dyn_snCode = numpy.array([Num_Codes,Bauds])
33 Dyn_snCode = None
33 Dyn_snCode = None
34 Samples = 200
34 Samples = 200
35 channels = 2
35 channels = 2
36 pulses = None
36 pulses = None
37 Reference = None
37 Reference = None
38 pulse_size = None
38 pulse_size = None
39 prof_gen = None
39 prof_gen = None
40 Fdoppler = 100
40 Fdoppler = 100
41 Hdoppler = 36
41 Hdoppler = 36
42 Adoppler = 300
42 Adoppler = 300
43 frequency = 9345
43 frequency = 9345
44 nTotalReadFiles = 1000
44 nTotalReadFiles = 1000
45
45
46 def __init__(self):
46 def __init__(self):
47 """
47 """
48 Inicializador de la clases SimulatorReader para
48 Inicializador de la clases SimulatorReader para
49 generar datos de voltage simulados.
49 generar datos de voltage simulados.
50 Input:
50 Input:
51 dataOut: Objeto de la clase Voltage.
51 dataOut: Objeto de la clase Voltage.
52 Este Objeto sera utilizado apra almacenar
52 Este Objeto sera utilizado apra almacenar
53 un perfil de datos cada vez qe se haga
53 un perfil de datos cada vez qe se haga
54 un requerimiento (getData)
54 un requerimiento (getData)
55 """
55 """
56 ProcessingUnit.__init__(self)
56 ProcessingUnit.__init__(self)
57 print(" [ START ] init - Metodo Simulator Reader")
57 print(" [ START ] init - Metodo Simulator Reader")
58
58
59 self.isConfig = False
59 self.isConfig = False
60 self.basicHeaderObj = BasicHeader(LOCALTIME)
60 self.basicHeaderObj = BasicHeader(LOCALTIME)
61 self.systemHeaderObj = SystemHeader()
61 self.systemHeaderObj = SystemHeader()
62 self.radarControllerHeaderObj = RadarControllerHeader()
62 self.radarControllerHeaderObj = RadarControllerHeader()
63 self.processingHeaderObj = ProcessingHeader()
63 self.processingHeaderObj = ProcessingHeader()
64 self.profileIndex = 2**32-1
64 self.profileIndex = 2**32-1
65 self.dataOut = Voltage()
65 self.dataOut = Voltage()
66 #code0 = numpy.array([1,1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,1,1,1,0,1,1,0,1,0,0,0,1,1,1,0,1])
66 #code0 = numpy.array([1,1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,1,1,1,0,1,1,0,1,0,0,0,1,1,1,0,1])
67 code0 = numpy.array([1,1,1,-1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,-1,-1,1,1,1,-1,1])
67 code0 = numpy.array([1,1,1,-1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,1,1,1,-1,1,1,-1,1,-1,-1,-1,1,1,1,-1,1])
68 #code1 = numpy.array([1,1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,1,0,1,1,1,0,0,0,1,0])
68 #code1 = numpy.array([1,1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,1,0,1,1,1,0,0,0,1,0])
69 code1 = numpy.array([1,1,1,-1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,-1])
69 code1 = numpy.array([1,1,1,-1,1,1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,-1,-1,-1,1,-1])
70 #self.Dyn_snCode = numpy.array([code0,code1])
70 #self.Dyn_snCode = numpy.array([code0,code1])
71 self.Dyn_snCode = None
71 self.Dyn_snCode = None
72
72
73 def set_kwargs(self, **kwargs):
73 def set_kwargs(self, **kwargs):
74 for key, value in kwargs.items():
74 for key, value in kwargs.items():
75 setattr(self, key, value)
75 setattr(self, key, value)
76
76
77 def __hasNotDataInBuffer(self):
77 def __hasNotDataInBuffer(self):
78
78
79 if self.profileIndex >= self.processingHeaderObj.profilesPerBlock* self.nTxs:
79 if self.profileIndex >= self.processingHeaderObj.profilesPerBlock* self.nTxs:
80 if self.nReadBlocks>0:
80 if self.nReadBlocks>0:
81 tmp = self.dataOut.utctime
81 tmp = self.dataOut.utctime
82 tmp_utc = int(self.dataOut.utctime)
82 tmp_utc = int(self.dataOut.utctime)
83 tmp_milisecond = int((tmp-tmp_utc)*1000)
83 tmp_milisecond = int((tmp-tmp_utc)*1000)
84 self.basicHeaderObj.utc = tmp_utc
84 self.basicHeaderObj.utc = tmp_utc
85 self.basicHeaderObj.miliSecond= tmp_milisecond
85 self.basicHeaderObj.miliSecond= tmp_milisecond
86 return 1
86 return 1
87 return 0
87 return 0
88
88
89 def setNextFile(self):
89 def setNextFile(self):
90 """Set the next file to be readed open it and parse de file header"""
90 """Set the next file to be readed open it and parse de file header"""
91
91
92 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
92 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
93 self.nReadFiles=self.nReadFiles+1
93 self.nReadFiles=self.nReadFiles+1
94 if self.nReadFiles > self.nTotalReadFiles:
94 if self.nReadFiles > self.nTotalReadFiles:
95 self.flagNoMoreFiles=1
95 self.flagNoMoreFiles=1
96 raise schainpy.admin.SchainWarning('No more files to read')
96 raise schainpy.admin.SchainWarning('No more files to read')
97
97
98 print('------------------- [Opening file] ------------------------------',self.nReadFiles)
98 print('------------------- [Opening file] ------------------------------',self.nReadFiles)
99 self.nReadBlocks = 0
99 self.nReadBlocks = 0
100 #if self.nReadBlocks==0:
100 #if self.nReadBlocks==0:
101 # self.readFirstHeader()
101 # self.readFirstHeader()
102
102
103 def __setNewBlock(self):
103 def __setNewBlock(self):
104 self.setNextFile()
104 self.setNextFile()
105 if self.flagIsNewFile:
105 if self.flagIsNewFile:
106 return 1
106 return 1
107
107
108 def readNextBlock(self):
108 def readNextBlock(self):
109 while True:
109 while True:
110 self.__setNewBlock()
110 self.__setNewBlock()
111 if not(self.readBlock()):
111 if not(self.readBlock()):
112 return 0
112 return 0
113 self.getBasicHeader()
113 self.getBasicHeader()
114 break
114 break
115 if self.verbose:
115 if self.verbose:
116 print("[Reading] Block No. %d/%d -> %s" %(self.nReadBlocks,
116 print("[Reading] Block No. %d/%d -> %s" %(self.nReadBlocks,
117 self.processingHeaderObj.dataBlocksPerFile,
117 self.processingHeaderObj.dataBlocksPerFile,
118 self.dataOut.datatime.ctime()) )
118 self.dataOut.datatime.ctime()) )
119 return 1
119 return 1
120
120
121 def getFirstHeader(self):
121 def getFirstHeader(self):
122 self.getBasicHeader()
122 self.getBasicHeader()
123 self.dataOut.processingHeaderObj = self.processingHeaderObj.copy()
123 self.dataOut.processingHeaderObj = self.processingHeaderObj.copy()
124 self.dataOut.systemHeaderObj = self.systemHeaderObj.copy()
124 self.dataOut.systemHeaderObj = self.systemHeaderObj.copy()
125 self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy()
125 self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy()
126 self.dataOut.dtype = self.dtype
126 self.dataOut.dtype = self.dtype
127
127
128 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock
128 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock
129 self.dataOut.heightList = numpy.arange(self.processingHeaderObj.nHeights) * self.processingHeaderObj.deltaHeight + self.processingHeaderObj.firstHeight
129 self.dataOut.heightList = numpy.arange(self.processingHeaderObj.nHeights) * self.processingHeaderObj.deltaHeight + self.processingHeaderObj.firstHeight
130 self.dataOut.channelList = list(range(self.systemHeaderObj.nChannels))
130 self.dataOut.channelList = list(range(self.systemHeaderObj.nChannels))
131 self.dataOut.nCohInt = self.processingHeaderObj.nCohInt
131 self.dataOut.nCohInt = self.processingHeaderObj.nCohInt
132 # asumo q la data no esta decodificada
132 # asumo q la data no esta decodificada
133 self.dataOut.flagDecodeData = self.processingHeaderObj.flag_decode
133 self.dataOut.flagDecodeData = self.processingHeaderObj.flag_decode
134 # asumo q la data no esta sin flip
134 # asumo q la data no esta sin flip
135 self.dataOut.flagDeflipData = self.processingHeaderObj.flag_deflip
135 self.dataOut.flagDeflipData = self.processingHeaderObj.flag_deflip
136 self.dataOut.flagShiftFFT = self.processingHeaderObj.shif_fft
136 self.dataOut.flagShiftFFT = self.processingHeaderObj.shif_fft
137 self.dataOut.frequency = self.frequency
137 self.dataOut.frequency = self.frequency
138
138
139 def getBasicHeader(self):
139 def getBasicHeader(self):
140 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond / \
140 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond / \
141 1000. + self.profileIndex * self.radarControllerHeaderObj.ippSeconds
141 1000. + self.profileIndex * self.radarControllerHeaderObj.ippSeconds
142
142
143 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
143 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
144 self.dataOut.timeZone = self.basicHeaderObj.timeZone
144 self.dataOut.timeZone = self.basicHeaderObj.timeZone
145 self.dataOut.dstFlag = self.basicHeaderObj.dstFlag
145 self.dataOut.dstFlag = self.basicHeaderObj.dstFlag
146 self.dataOut.errorCount = self.basicHeaderObj.errorCount
146 self.dataOut.errorCount = self.basicHeaderObj.errorCount
147 self.dataOut.useLocalTime = self.basicHeaderObj.useLocalTime
147 self.dataOut.useLocalTime = self.basicHeaderObj.useLocalTime
148 self.dataOut.ippSeconds = self.radarControllerHeaderObj.ippSeconds / self.nTxs
148 self.dataOut.ippSeconds = self.radarControllerHeaderObj.ippSeconds / self.nTxs
149
149
150 def readFirstHeader(self):
150 def readFirstHeader(self):
151
151
152 datatype = int(numpy.log2((self.processingHeaderObj.processFlags &
152 datatype = int(numpy.log2((self.processingHeaderObj.processFlags &
153 PROCFLAG.DATATYPE_MASK)) - numpy.log2(PROCFLAG.DATATYPE_CHAR))
153 PROCFLAG.DATATYPE_MASK)) - numpy.log2(PROCFLAG.DATATYPE_CHAR))
154 if datatype == 0:
154 if datatype == 0:
155 datatype_str = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
155 datatype_str = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
156 elif datatype == 1:
156 elif datatype == 1:
157 datatype_str = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
157 datatype_str = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
158 elif datatype == 2:
158 elif datatype == 2:
159 datatype_str = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
159 datatype_str = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
160 elif datatype == 3:
160 elif datatype == 3:
161 datatype_str = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
161 datatype_str = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
162 elif datatype == 4:
162 elif datatype == 4:
163 datatype_str = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
163 datatype_str = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
164 elif datatype == 5:
164 elif datatype == 5:
165 datatype_str = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
165 datatype_str = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
166 else:
166 else:
167 raise ValueError('Data type was not defined')
167 raise ValueError('Data type was not defined')
168
168
169 self.dtype = datatype_str
169 self.dtype = datatype_str
170
170
171
171
172 def set_RCH(self, expType=2, nTx=1,ipp=None, txA=0, txB=0,
172 def set_RCH(self, expType=2, nTx=1,ipp=None, txA=0, txB=0,
173 nWindows=None, nHeights=None, firstHeight=None, deltaHeight=None,
173 nWindows=None, nHeights=None, firstHeight=None, deltaHeight=None,
174 numTaus=0, line6Function=0, line5Function=0, fClock=None,
174 numTaus=0, line6Function=0, line5Function=0, fClock=None,
175 prePulseBefore=0, prePulseAfter=0,
175 prePulseBefore=0, prePulseAfter=0,
176 codeType=0, nCode=0, nBaud=0, code=None,
176 codeType=0, nCode=0, nBaud=0, code=None,
177 flip1=0, flip2=0,Taus=0):
177 flip1=0, flip2=0,Taus=0):
178 self.radarControllerHeaderObj.expType = expType
178 self.radarControllerHeaderObj.expType = expType
179 self.radarControllerHeaderObj.nTx = nTx
179 self.radarControllerHeaderObj.nTx = nTx
180 self.radarControllerHeaderObj.ipp = float(ipp)
180 self.radarControllerHeaderObj.ipp = float(ipp)
181 self.radarControllerHeaderObj.txA = float(txA)
181 self.radarControllerHeaderObj.txA = float(txA)
182 self.radarControllerHeaderObj.txB = float(txB)
182 self.radarControllerHeaderObj.txB = float(txB)
183 self.radarControllerHeaderObj.rangeIpp = b'A\n'#ipp
183 self.radarControllerHeaderObj.rangeIpp = b'A\n'#ipp
184 self.radarControllerHeaderObj.rangeTxA = b''
184 self.radarControllerHeaderObj.rangeTxA = b''
185 self.radarControllerHeaderObj.rangeTxB = b''
185 self.radarControllerHeaderObj.rangeTxB = b''
186
186
187 self.radarControllerHeaderObj.nHeights = int(nHeights)
187 self.radarControllerHeaderObj.nHeights = int(nHeights)
188 self.radarControllerHeaderObj.firstHeight = numpy.array([firstHeight])
188 self.radarControllerHeaderObj.firstHeight = numpy.array([firstHeight])
189 self.radarControllerHeaderObj.deltaHeight = numpy.array([deltaHeight])
189 self.radarControllerHeaderObj.deltaHeight = numpy.array([deltaHeight])
190 self.radarControllerHeaderObj.samplesWin = numpy.array([nHeights])
190 self.radarControllerHeaderObj.samplesWin = numpy.array([nHeights])
191
191
192
192
193 self.radarControllerHeaderObj.nWindows = nWindows
193 self.radarControllerHeaderObj.nWindows = nWindows
194 self.radarControllerHeaderObj.numTaus = numTaus
194 self.radarControllerHeaderObj.numTaus = numTaus
195 self.radarControllerHeaderObj.codeType = codeType
195 self.radarControllerHeaderObj.codeType = codeType
196 self.radarControllerHeaderObj.line6Function = line6Function
196 self.radarControllerHeaderObj.line6Function = line6Function
197 self.radarControllerHeaderObj.line5Function = line5Function
197 self.radarControllerHeaderObj.line5Function = line5Function
198 #self.radarControllerHeaderObj.fClock = fClock
198 #self.radarControllerHeaderObj.fClock = fClock
199 self.radarControllerHeaderObj.prePulseBefore= prePulseBefore
199 self.radarControllerHeaderObj.prePulseBefore= prePulseBefore
200 self.radarControllerHeaderObj.prePulseAfter = prePulseAfter
200 self.radarControllerHeaderObj.prePulseAfter = prePulseAfter
201
201
202 self.radarControllerHeaderObj.flip1 = flip1
202 self.radarControllerHeaderObj.flip1 = flip1
203 self.radarControllerHeaderObj.flip2 = flip2
203 self.radarControllerHeaderObj.flip2 = flip2
204
204
205 self.radarControllerHeaderObj.code_size = 0
205 self.radarControllerHeaderObj.code_size = 0
206 if self.radarControllerHeaderObj.codeType != 0:
206 if self.radarControllerHeaderObj.codeType != 0:
207 self.radarControllerHeaderObj.nCode = nCode
207 self.radarControllerHeaderObj.nCode = nCode
208 self.radarControllerHeaderObj.nBaud = nBaud
208 self.radarControllerHeaderObj.nBaud = nBaud
209 self.radarControllerHeaderObj.code = code
209 self.radarControllerHeaderObj.code = code
210 self.radarControllerHeaderObj.code_size = int(numpy.ceil(nBaud / 32.)) * nCode * 4
210 self.radarControllerHeaderObj.code_size = int(numpy.ceil(nBaud / 32.)) * nCode * 4
211
211
212 if fClock is None and deltaHeight is not None:
212 if fClock is None and deltaHeight is not None:
213 self.fClock = 0.15 / (deltaHeight * 1e-6)
213 self.fClock = 0.15 / (deltaHeight * 1e-6)
214 self.radarControllerHeaderObj.fClock = self.fClock
214 self.radarControllerHeaderObj.fClock = self.fClock
215 if numTaus==0:
215 if numTaus==0:
216 self.radarControllerHeaderObj.Taus = numpy.array(0,'<f4')
216 self.radarControllerHeaderObj.Taus = numpy.array(0,'<f4')
217 else:
217 else:
218 self.radarControllerHeaderObj.Taus = numpy.array(Taus,'<f4')
218 self.radarControllerHeaderObj.Taus = numpy.array(Taus,'<f4')
219
219
220 def set_PH(self, dtype=0, blockSize=0, profilesPerBlock=0,
220 def set_PH(self, dtype=0, blockSize=0, profilesPerBlock=0,
221 dataBlocksPerFile=0, nWindows=0, processFlags=0, nCohInt=0,
221 dataBlocksPerFile=0, nWindows=0, processFlags=0, nCohInt=0,
222 nIncohInt=0, totalSpectra=0, nHeights=0, firstHeight=0,
222 nIncohInt=0, totalSpectra=0, nHeights=0, firstHeight=0,
223 deltaHeight=0, samplesWin=0, spectraComb=0, nCode=0,
223 deltaHeight=0, samplesWin=0, spectraComb=0, nCode=0,
224 code=0, nBaud=None, shif_fft=False, flag_dc=False,
224 code=0, nBaud=None, shif_fft=False, flag_dc=False,
225 flag_cspc=False, flag_decode=False, flag_deflip=False):
225 flag_cspc=False, flag_decode=False, flag_deflip=False):
226
226
227 self.processingHeaderObj.dtype = dtype
227 self.processingHeaderObj.dtype = dtype
228 self.processingHeaderObj.profilesPerBlock = profilesPerBlock
228 self.processingHeaderObj.profilesPerBlock = profilesPerBlock
229 self.processingHeaderObj.dataBlocksPerFile = dataBlocksPerFile
229 self.processingHeaderObj.dataBlocksPerFile = dataBlocksPerFile
230 self.processingHeaderObj.nWindows = nWindows
230 self.processingHeaderObj.nWindows = nWindows
231 self.processingHeaderObj.processFlags = processFlags
231 self.processingHeaderObj.processFlags = processFlags
232 self.processingHeaderObj.nCohInt = nCohInt
232 self.processingHeaderObj.nCohInt = nCohInt
233 self.processingHeaderObj.nIncohInt = nIncohInt
233 self.processingHeaderObj.nIncohInt = nIncohInt
234 self.processingHeaderObj.totalSpectra = totalSpectra
234 self.processingHeaderObj.totalSpectra = totalSpectra
235
235
236 self.processingHeaderObj.nHeights = int(nHeights)
236 self.processingHeaderObj.nHeights = int(nHeights)
237 self.processingHeaderObj.firstHeight = firstHeight#numpy.array([firstHeight])#firstHeight
237 self.processingHeaderObj.firstHeight = firstHeight#numpy.array([firstHeight])#firstHeight
238 self.processingHeaderObj.deltaHeight = deltaHeight#numpy.array([deltaHeight])#deltaHeight
238 self.processingHeaderObj.deltaHeight = deltaHeight#numpy.array([deltaHeight])#deltaHeight
239 self.processingHeaderObj.samplesWin = nHeights#numpy.array([nHeights])#nHeights
239 self.processingHeaderObj.samplesWin = nHeights#numpy.array([nHeights])#nHeights
240
240
241 def set_BH(self, utc = 0, miliSecond = 0, timeZone = 0):
241 def set_BH(self, utc = 0, miliSecond = 0, timeZone = 0):
242 self.basicHeaderObj.utc = utc
242 self.basicHeaderObj.utc = utc
243 self.basicHeaderObj.miliSecond = miliSecond
243 self.basicHeaderObj.miliSecond = miliSecond
244 self.basicHeaderObj.timeZone = timeZone
244 self.basicHeaderObj.timeZone = timeZone
245
245
246 def set_SH(self, nSamples=0, nProfiles=0, nChannels=0, adcResolution=14, pciDioBusWidth=32):
246 def set_SH(self, nSamples=0, nProfiles=0, nChannels=0, adcResolution=14, pciDioBusWidth=32):
247 #self.systemHeaderObj.size = size
247 #self.systemHeaderObj.size = size
248 self.systemHeaderObj.nSamples = nSamples
248 self.systemHeaderObj.nSamples = nSamples
249 self.systemHeaderObj.nProfiles = nProfiles
249 self.systemHeaderObj.nProfiles = nProfiles
250 self.systemHeaderObj.nChannels = nChannels
250 self.systemHeaderObj.nChannels = nChannels
251 self.systemHeaderObj.adcResolution = adcResolution
251 self.systemHeaderObj.adcResolution = adcResolution
252 self.systemHeaderObj.pciDioBusWidth = pciDioBusWidth
252 self.systemHeaderObj.pciDioBusWidth = pciDioBusWidth
253
253
254 def init_acquisition(self):
254 def init_acquisition(self):
255
255
256 if self.nFFTPoints != 0:
256 if self.nFFTPoints != 0:
257 self.incIntFactor = m_nProfilesperBlock/self.nFFTPoints
257 self.incIntFactor = m_nProfilesperBlock/self.nFFTPoints
258 if (self.FixPP_IncInt > self.incIntFactor):
258 if (self.FixPP_IncInt > self.incIntFactor):
259 self.incIntFactor = self.FixPP_IncInt/ self.incIntFactor
259 self.incIntFactor = self.FixPP_IncInt/ self.incIntFactor
260 elif(self.FixPP_IncInt< self.incIntFactor):
260 elif(self.FixPP_IncInt< self.incIntFactor):
261 print("False alert...")
261 print("False alert...")
262
262
263 ProfilesperBlock = self.processingHeaderObj.profilesPerBlock
263 ProfilesperBlock = self.processingHeaderObj.profilesPerBlock
264
264
265 self.timeperblock =int(((self.FixRCP_IPP
265 self.timeperblock =int(((self.FixRCP_IPP
266 *ProfilesperBlock
266 *ProfilesperBlock
267 *self.FixPP_CohInt
267 *self.FixPP_CohInt
268 *self.incIntFactor)
268 *self.incIntFactor)
269 /150.0)
269 /150.0)
270 *0.9
270 *0.9
271 +0.5)
271 +0.5)
272 # para cada canal
272 # para cada canal
273 self.profiles = ProfilesperBlock*self.FixPP_CohInt
273 self.profiles = ProfilesperBlock*self.FixPP_CohInt
274 self.profiles = ProfilesperBlock
274 self.profiles = ProfilesperBlock
275 self.Reference = int((self.Tau_0-self.AcqH0_0)/(self.AcqDH_0)+0.5)
275 self.Reference = int((self.Tau_0-self.AcqH0_0)/(self.AcqDH_0)+0.5)
276 self.BaudWidth = int((self.FixRCP_TXA/self.AcqDH_0)/self.Bauds + 0.5 )
276 self.BaudWidth = int((self.FixRCP_TXA/self.AcqDH_0)/self.Bauds + 0.5 )
277
277
278 if (self.BaudWidth==0):
278 if (self.BaudWidth==0):
279 self.BaudWidth=1
279 self.BaudWidth=1
280
280
281 def init_pulse(self,Num_Codes=Num_Codes,Bauds=Bauds,BaudWidth=BaudWidth,Dyn_snCode=Dyn_snCode):
281 def init_pulse(self,Num_Codes=Num_Codes,Bauds=Bauds,BaudWidth=BaudWidth,Dyn_snCode=Dyn_snCode):
282
282
283 Num_Codes = Num_Codes
283 Num_Codes = Num_Codes
284 Bauds = Bauds
284 Bauds = Bauds
285 BaudWidth = BaudWidth
285 BaudWidth = BaudWidth
286 Dyn_snCode = Dyn_snCode
286 Dyn_snCode = Dyn_snCode
287
287
288 if Dyn_snCode:
288 if Dyn_snCode:
289 print("EXISTE")
289 print("EXISTE")
290 else:
290 else:
291 print("No existe")
291 print("No existe")
292
292
293 if Dyn_snCode: # if Bauds:
293 if Dyn_snCode: # if Bauds:
294 pulses = list(range(0,Num_Codes))
294 pulses = list(range(0,Num_Codes))
295 num_codes = Num_Codes
295 num_codes = Num_Codes
296 for i in range(num_codes):
296 for i in range(num_codes):
297 pulse_size = Bauds*BaudWidth
297 pulse_size = Bauds*BaudWidth
298 pulses[i] = numpy.zeros(pulse_size)
298 pulses[i] = numpy.zeros(pulse_size)
299 for j in range(Bauds):
299 for j in range(Bauds):
300 for k in range(BaudWidth):
300 for k in range(BaudWidth):
301 pulses[i][j*BaudWidth+k] = int(Dyn_snCode[i][j]*600)
301 pulses[i][j*BaudWidth+k] = int(Dyn_snCode[i][j]*600)
302 else:
302 else:
303 print("sin code")
303 print("sin code")
304 pulses = list(range(1))
304 pulses = list(range(1))
305 if self.AcqDH_0>0.149:
305 if self.AcqDH_0>0.149:
306 pulse_size = int(self.FixRCP_TXB/0.15+0.5)
306 pulse_size = int(self.FixRCP_TXB/0.15+0.5)
307 else:
307 else:
308 pulse_size = int((self.FixRCP_TXB/self.AcqDH_0)+0.5) #0.0375
308 pulse_size = int((self.FixRCP_TXB/self.AcqDH_0)+0.5) #0.0375
309 pulses[0] = numpy.ones(pulse_size)
309 pulses[0] = numpy.ones(pulse_size)
310 pulses = 600*pulses[0]
310 pulses = 600*pulses[0]
311
311
312 return pulses,pulse_size
312 return pulses,pulse_size
313
313
314 def jro_GenerateBlockOfData(self,Samples=Samples,DC_level= DC_level,stdev=stdev,
314 def jro_GenerateBlockOfData(self,Samples=Samples,DC_level= DC_level,stdev=stdev,
315 Reference= Reference,pulses= pulses,
315 Reference= Reference,pulses= pulses,
316 Num_Codes= Num_Codes,pulse_size=pulse_size,
316 Num_Codes= Num_Codes,pulse_size=pulse_size,
317 prof_gen= prof_gen,H0 = H0,DH0=DH0,
317 prof_gen= prof_gen,H0 = H0,DH0=DH0,
318 Adoppler=Adoppler,Fdoppler= Fdoppler,Hdoppler=Hdoppler):
318 Adoppler=Adoppler,Fdoppler= Fdoppler,Hdoppler=Hdoppler):
319 Samples = Samples
319 Samples = Samples
320 DC_level = DC_level
320 DC_level = DC_level
321 stdev = stdev
321 stdev = stdev
322 m_nR = Reference
322 m_nR = Reference
323 pulses = pulses
323 pulses = pulses
324 num_codes = Num_Codes
324 num_codes = Num_Codes
325 ps = pulse_size
325 ps = pulse_size
326 prof_gen = prof_gen
326 prof_gen = prof_gen
327 channels = self.channels
327 channels = self.channels
328 H0 = H0
328 H0 = H0
329 DH0 = DH0
329 DH0 = DH0
330 ippSec = self.radarControllerHeaderObj.ippSeconds
330 ippSec = self.radarControllerHeaderObj.ippSeconds
331 Fdoppler = self.Fdoppler
331 Fdoppler = self.Fdoppler
332 Hdoppler = self.Hdoppler
332 Hdoppler = self.Hdoppler
333 Adoppler = self.Adoppler
333 Adoppler = self.Adoppler
334
334
335 self.datablock = numpy.zeros([channels,prof_gen,Samples],dtype= numpy.complex64)
335 self.datablock = numpy.zeros([channels,prof_gen,Samples],dtype= numpy.complex64)
336 for i in range(channels):
336 for i in range(channels):
337 for k in range(prof_gen):
337 for k in range(prof_gen):
338 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·NOISEΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
338 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·NOISEΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
339 Noise_r = numpy.random.normal(DC_level,stdev,Samples)
339 Noise_r = numpy.random.normal(DC_level,stdev,Samples)
340 Noise_i = numpy.random.normal(DC_level,stdev,Samples)
340 Noise_i = numpy.random.normal(DC_level,stdev,Samples)
341 Noise = numpy.zeros(Samples,dtype=complex)
341 Noise = numpy.zeros(Samples,dtype=complex)
342 Noise.real = Noise_r
342 Noise.real = Noise_r
343 Noise.imag = Noise_i
343 Noise.imag = Noise_i
344 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·PULSOSΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
344 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·PULSOSΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
345 Pulso = numpy.zeros(pulse_size,dtype=complex)
345 Pulso = numpy.zeros(pulse_size,dtype=complex)
346 Pulso.real = pulses[k%num_codes]
346 Pulso.real = pulses[k%num_codes]
347 Pulso.imag = pulses[k%num_codes]
347 Pulso.imag = pulses[k%num_codes]
348 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· PULSES+NOISEΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·
348 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· PULSES+NOISEΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·
349 InBuffer = numpy.zeros(Samples,dtype=complex)
349 InBuffer = numpy.zeros(Samples,dtype=complex)
350 InBuffer[m_nR:m_nR+ps] = Pulso
350 InBuffer[m_nR:m_nR+ps] = Pulso
351 InBuffer = InBuffer+Noise
351 InBuffer = InBuffer+Noise
352 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· ANGLE Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
352 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· ANGLE Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
353 InBuffer.real[m_nR:m_nR+ps] = InBuffer.real[m_nR:m_nR+ps]*(math.cos( self.fAngle)*5)
353 InBuffer.real[m_nR:m_nR+ps] = InBuffer.real[m_nR:m_nR+ps]*(math.cos( self.fAngle)*5)
354 InBuffer.imag[m_nR:m_nR+ps] = InBuffer.imag[m_nR:m_nR+ps]*(math.sin( self.fAngle)*5)
354 InBuffer.imag[m_nR:m_nR+ps] = InBuffer.imag[m_nR:m_nR+ps]*(math.sin( self.fAngle)*5)
355 InBuffer=InBuffer
355 InBuffer=InBuffer
356 self.datablock[i][k]= InBuffer
356 self.datablock[i][k]= InBuffer
357
357
358 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·DOPPLER SIGNAL...............................................
358 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·DOPPLER SIGNAL...............................................
359 time_vec = numpy.linspace(0,(prof_gen-1)*ippSec,int(prof_gen))+self.nReadBlocks*ippSec*prof_gen+(self.nReadFiles-1)*ippSec*prof_gen
359 time_vec = numpy.linspace(0,(prof_gen-1)*ippSec,int(prof_gen))+self.nReadBlocks*ippSec*prof_gen+(self.nReadFiles-1)*ippSec*prof_gen
360 fd = Fdoppler #+(600.0/120)*self.nReadBlocks
360 fd = Fdoppler #+(600.0/120)*self.nReadBlocks
361 d_signal = Adoppler*numpy.array(numpy.exp(1.0j*2.0*math.pi*fd*time_vec),dtype=numpy.complex64)
361 d_signal = Adoppler*numpy.array(numpy.exp(1.0j*2.0*math.pi*fd*time_vec),dtype=numpy.complex64)
362 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·SeΓ±al con ancho espectralΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
362 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·SeΓ±al con ancho espectralΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
363 #specw_sig = numpy.linspace(-149,150,300)
363 if prof_gen%2==0:
364 #w = 8
364 min = int(prof_gen/2.0-1.0)
365 #A = 20
365 max = int(prof_gen/2.0)
366 #specw_sig = specw_sig/w
366 else:
367 #specw_sig = numpy.sinc(specw_sig)
367 min = int(prof_gen/2.0)
368 #specw_sig = A*numpy.array(specw_sig,dtype=numpy.complex64)
368 max = int(prof_gen/2.0)
369 specw_sig = numpy.linspace(-min,max,prof_gen)
370 w = 4
371 A = 20
372 specw_sig = specw_sig/w
373 specw_sig = numpy.sinc(specw_sig)
374 specw_sig = A*numpy.array(specw_sig,dtype=numpy.complex64)
369 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· DATABLOCK + DOPPLERΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
375 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· DATABLOCK + DOPPLERΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
370 HD=int(Hdoppler/self.AcqDH_0)
376 HD=int(Hdoppler/self.AcqDH_0)
371 for i in range(12):
377 for i in range(12):
372 self.datablock[0,:,HD+i]=self.datablock[0,:,HD+i]+ d_signal# RESULT
378 self.datablock[0,:,HD+i]=self.datablock[0,:,HD+i]+ d_signal# RESULT
373 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· DATABLOCK + DOPPLER*Sinc(x)Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
379 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· DATABLOCK + DOPPLER*Sinc(x)Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
374 #HD=int(Hdoppler/self.AcqDH_0)
380 HD=int(Hdoppler/self.AcqDH_0)
375 #HD=int(HD/2)
381 HD=int(HD/2)
376 #for i in range(12):
382 for i in range(12):
377 # self.datablock[0,:,HD+i]=self.datablock[0,:,HD+i]+ specw_sig*d_signal# RESULT
383 self.datablock[0,:,HD+i]=self.datablock[0,:,HD+i]+ specw_sig*d_signal# RESULT
378
384
379 def readBlock(self):
385 def readBlock(self):
380
386
381 self.jro_GenerateBlockOfData(Samples= self.samples,DC_level=self.DC_level,
387 self.jro_GenerateBlockOfData(Samples= self.samples,DC_level=self.DC_level,
382 stdev=self.stdev,Reference= self.Reference,
388 stdev=self.stdev,Reference= self.Reference,
383 pulses = self.pulses,Num_Codes=self.Num_Codes,
389 pulses = self.pulses,Num_Codes=self.Num_Codes,
384 pulse_size=self.pulse_size,prof_gen=self.profiles,
390 pulse_size=self.pulse_size,prof_gen=self.profiles,
385 H0=self.H0,DH0=self.DH0)
391 H0=self.H0,DH0=self.DH0)
386
392
387 self.profileIndex = 0
393 self.profileIndex = 0
388 self.flagIsNewFile = 0
394 self.flagIsNewFile = 0
389 self.flagIsNewBlock = 1
395 self.flagIsNewBlock = 1
390 self.nTotalBlocks += 1
396 self.nTotalBlocks += 1
391 self.nReadBlocks += 1
397 self.nReadBlocks += 1
392
398
393 return 1
399 return 1
394
400
395
401
396 def getData(self):
402 def getData(self):
397 if self.flagNoMoreFiles:
403 if self.flagNoMoreFiles:
398 self.dataOut.flagNodata = True
404 self.dataOut.flagNodata = True
399 return 0
405 return 0
400 self.flagDiscontinuousBlock = 0
406 self.flagDiscontinuousBlock = 0
401 self.flagIsNewBlock = 0
407 self.flagIsNewBlock = 0
402 if self.__hasNotDataInBuffer(): # aqui es verdad
408 if self.__hasNotDataInBuffer(): # aqui es verdad
403 if not(self.readNextBlock()): # return 1 y por eso el if not salta a getBasic Header
409 if not(self.readNextBlock()): # return 1 y por eso el if not salta a getBasic Header
404 return 0
410 return 0
405 self.getFirstHeader() # atributo
411 self.getFirstHeader() # atributo
406
412
407 if not self.getByBlock:
413 if not self.getByBlock:
408 self.dataOut.flagDataAsBlock = False
414 self.dataOut.flagDataAsBlock = False
409 self.dataOut.data = self.datablock[:, self.profileIndex, :]
415 self.dataOut.data = self.datablock[:, self.profileIndex, :]
410 self.dataOut.profileIndex = self.profileIndex
416 self.dataOut.profileIndex = self.profileIndex
411 self.profileIndex += 1
417 self.profileIndex += 1
412 else:
418 else:
413 pass
419 pass
414 self.dataOut.flagNoData = False
420 self.dataOut.flagNoData = False
415 self.getBasicHeader()
421 self.getBasicHeader()
416 self.dataOut.realtime = self.online
422 self.dataOut.realtime = self.online
417 return self.dataOut.data
423 return self.dataOut.data
418
424
419
425
420 def setup(self,frequency=49.92e6,incIntFactor= 1, nFFTPoints = 0, FixPP_IncInt=1,FixRCP_IPP=1000,
426 def setup(self,frequency=49.92e6,incIntFactor= 1, nFFTPoints = 0, FixPP_IncInt=1,FixRCP_IPP=1000,
421 FixPP_CohInt= 1,Tau_0= 250,AcqH0_0 = 70 ,AcqDH_0=1.25, Bauds= 32,
427 FixPP_CohInt= 1,Tau_0= 250,AcqH0_0 = 70 ,AcqDH_0=1.25, Bauds= 32,
422 FixRCP_TXA = 40, FixRCP_TXB = 50, fAngle = 2.0*math.pi*(1/16),DC_level= 50,
428 FixRCP_TXA = 40, FixRCP_TXB = 50, fAngle = 2.0*math.pi*(1/16),DC_level= 50,
423 stdev= 8,Num_Codes = 1 , Dyn_snCode = None, samples=200,
429 stdev= 8,Num_Codes = 1 , Dyn_snCode = None, samples=200,
424 channels=2,Fdoppler=20,Hdoppler=36,Adoppler=500,nTotalReadFiles=10000,
430 channels=2,Fdoppler=20,Hdoppler=36,Adoppler=500,
431 profilesPerBlock=300,dataBlocksPerFile=120,nTotalReadFiles=10000,
425 **kwargs):
432 **kwargs):
426
433
427 self.set_kwargs(**kwargs)
434 self.set_kwargs(**kwargs)
428 self.nReadBlocks = 0
435 self.nReadBlocks = 0
429 self.nReadFiles = 1
436 self.nReadFiles = 1
430 print('------------------- [Opening file: ] ------------------------------',self.nReadFiles)
437 print('------------------- [Opening file: ] ------------------------------',self.nReadFiles)
431
438
432 tmp = time.time()
439 tmp = time.time()
433 tmp_utc = int(tmp)
440 tmp_utc = int(tmp)
434 tmp_milisecond = int((tmp-tmp_utc)*1000)
441 tmp_milisecond = int((tmp-tmp_utc)*1000)
435 print(" SETUP -basicHeaderObj.utc",datetime.datetime.utcfromtimestamp(tmp))
442 print(" SETUP -basicHeaderObj.utc",datetime.datetime.utcfromtimestamp(tmp))
436 if Dyn_snCode is None:
443 if Dyn_snCode is None:
437 Num_Codes=1
444 Num_Codes=1
438 Bauds =1
445 Bauds =1
439
446
440
447
441
448
442 self.set_BH(utc= tmp_utc,miliSecond= tmp_milisecond,timeZone=300 )
449 self.set_BH(utc= tmp_utc,miliSecond= tmp_milisecond,timeZone=300 )
443 self.set_RCH( expType=0, nTx=150,ipp=FixRCP_IPP, txA=FixRCP_TXA, txB= FixRCP_TXB,
450 self.set_RCH( expType=0, nTx=150,ipp=FixRCP_IPP, txA=FixRCP_TXA, txB= FixRCP_TXB,
444 nWindows=1 , nHeights=samples, firstHeight=AcqH0_0, deltaHeight=AcqDH_0,
451 nWindows=1 , nHeights=samples, firstHeight=AcqH0_0, deltaHeight=AcqDH_0,
445 numTaus=1, line6Function=0, line5Function=0, fClock=None,
452 numTaus=1, line6Function=0, line5Function=0, fClock=None,
446 prePulseBefore=0, prePulseAfter=0,
453 prePulseBefore=0, prePulseAfter=0,
447 codeType=0, nCode=Num_Codes, nBaud=32, code=Dyn_snCode,
454 codeType=0, nCode=Num_Codes, nBaud=32, code=Dyn_snCode,
448 flip1=0, flip2=0,Taus=Tau_0)
455 flip1=0, flip2=0,Taus=Tau_0)
449
456
450 self.set_PH(dtype=0, blockSize=0, profilesPerBlock=300,
457 self.set_PH(dtype=0, blockSize=0, profilesPerBlock=profilesPerBlock,
451 dataBlocksPerFile=120, nWindows=1, processFlags=numpy.array([1024]), nCohInt=1,
458 dataBlocksPerFile=dataBlocksPerFile, nWindows=1, processFlags=numpy.array([1024]), nCohInt=1,
452 nIncohInt=1, totalSpectra=0, nHeights=samples, firstHeight=AcqH0_0,
459 nIncohInt=1, totalSpectra=0, nHeights=samples, firstHeight=AcqH0_0,
453 deltaHeight=AcqDH_0, samplesWin=samples, spectraComb=0, nCode=0,
460 deltaHeight=AcqDH_0, samplesWin=samples, spectraComb=0, nCode=0,
454 code=0, nBaud=None, shif_fft=False, flag_dc=False,
461 code=0, nBaud=None, shif_fft=False, flag_dc=False,
455 flag_cspc=False, flag_decode=False, flag_deflip=False)
462 flag_cspc=False, flag_decode=False, flag_deflip=False)
456
463
457 self.set_SH(nSamples=samples, nProfiles=300, nChannels=channels)
464 self.set_SH(nSamples=samples, nProfiles=profilesPerBlock, nChannels=channels)
458
465
459 self.readFirstHeader()
466 self.readFirstHeader()
460
467
461 self.frequency = frequency
468 self.frequency = frequency
462 self.incIntFactor = incIntFactor
469 self.incIntFactor = incIntFactor
463 self.nFFTPoints = nFFTPoints
470 self.nFFTPoints = nFFTPoints
464 self.FixPP_IncInt = FixPP_IncInt
471 self.FixPP_IncInt = FixPP_IncInt
465 self.FixRCP_IPP = FixRCP_IPP
472 self.FixRCP_IPP = FixRCP_IPP
466 self.FixPP_CohInt = FixPP_CohInt
473 self.FixPP_CohInt = FixPP_CohInt
467 self.Tau_0 = Tau_0
474 self.Tau_0 = Tau_0
468 self.AcqH0_0 = AcqH0_0
475 self.AcqH0_0 = AcqH0_0
469 self.H0 = AcqH0_0
476 self.H0 = AcqH0_0
470 self.AcqDH_0 = AcqDH_0
477 self.AcqDH_0 = AcqDH_0
471 self.DH0 = AcqDH_0
478 self.DH0 = AcqDH_0
472 self.Bauds = Bauds
479 self.Bauds = Bauds
473 self.FixRCP_TXA = FixRCP_TXA
480 self.FixRCP_TXA = FixRCP_TXA
474 self.FixRCP_TXB = FixRCP_TXB
481 self.FixRCP_TXB = FixRCP_TXB
475 self.fAngle = fAngle
482 self.fAngle = fAngle
476 self.DC_level = DC_level
483 self.DC_level = DC_level
477 self.stdev = stdev
484 self.stdev = stdev
478 self.Num_Codes = Num_Codes
485 self.Num_Codes = Num_Codes
479 self.Dyn_snCode = Dyn_snCode
486 self.Dyn_snCode = Dyn_snCode
480 self.samples = samples
487 self.samples = samples
481 self.channels = channels
488 self.channels = channels
482 self.profiles = None
489 self.profiles = None
483 self.m_nReference = None
490 self.m_nReference = None
484 self.Baudwidth = None
491 self.Baudwidth = None
485 self.Fdoppler = Fdoppler
492 self.Fdoppler = Fdoppler
486 self.Hdoppler = Hdoppler
493 self.Hdoppler = Hdoppler
487 self.Adoppler = Adoppler
494 self.Adoppler = Adoppler
488 self.nTotalReadFiles = int(nTotalReadFiles)
495 self.nTotalReadFiles = int(nTotalReadFiles)
489
496
490 print("IPP ", self.FixRCP_IPP)
497 print("IPP ", self.FixRCP_IPP)
491 print("Tau_0 ",self.Tau_0)
498 print("Tau_0 ",self.Tau_0)
492 print("AcqH0_0",self.AcqH0_0)
499 print("AcqH0_0",self.AcqH0_0)
493 print("samples,window ",self.samples)
500 print("samples,window ",self.samples)
494 print("AcqDH_0",AcqDH_0)
501 print("AcqDH_0",AcqDH_0)
495 print("FixRCP_TXA",self.FixRCP_TXA)
502 print("FixRCP_TXA",self.FixRCP_TXA)
496 print("FixRCP_TXB",self.FixRCP_TXB)
503 print("FixRCP_TXB",self.FixRCP_TXB)
497 print("Dyn_snCode",Dyn_snCode)
504 print("Dyn_snCode",Dyn_snCode)
498 print("Fdoppler", Fdoppler)
505 print("Fdoppler", Fdoppler)
499 print("Hdoppler",Hdoppler)
506 print("Hdoppler",Hdoppler)
500 print("Vdopplermax",Fdoppler*(3.0e8/self.frequency)/2.0)
507 print("Vdopplermax",Fdoppler*(3.0e8/self.frequency)/2.0)
501 print("nTotalReadFiles", nTotalReadFiles)
508 print("nTotalReadFiles", nTotalReadFiles)
502
509
503 self.init_acquisition()
510 self.init_acquisition()
504 self.pulses,self.pulse_size=self.init_pulse(Num_Codes=self.Num_Codes,Bauds=self.Bauds,BaudWidth=self.BaudWidth,Dyn_snCode=Dyn_snCode)
511 self.pulses,self.pulse_size=self.init_pulse(Num_Codes=self.Num_Codes,Bauds=self.Bauds,BaudWidth=self.BaudWidth,Dyn_snCode=Dyn_snCode)
505 print(" [ END ] - SETUP metodo")
512 print(" [ END ] - SETUP metodo")
506 return
513 return
507
514
508 def run(self,**kwargs): # metodo propio
515 def run(self,**kwargs): # metodo propio
509 if not(self.isConfig):
516 if not(self.isConfig):
510 self.setup(**kwargs)
517 self.setup(**kwargs)
511 self.isConfig = True
518 self.isConfig = True
512 self.getData()
519 self.getData()
This diff has been collapsed as it changes many lines, (2141 lines changed) Show them Hide them
@@ -1,3987 +1,4000
1 import numpy
1 import numpy
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
30
31 '''solving pickling issue'''
31 '''solving pickling issue'''
32
32
33 def _pickle_method(method):
33 def _pickle_method(method):
34 func_name = method.__func__.__name__
34 func_name = method.__func__.__name__
35 obj = method.__self__
35 obj = method.__self__
36 cls = method.__self__.__class__
36 cls = method.__self__.__class__
37 return _unpickle_method, (func_name, obj, cls)
37 return _unpickle_method, (func_name, obj, cls)
38
38
39 def _unpickle_method(func_name, obj, cls):
39 def _unpickle_method(func_name, obj, cls):
40 for cls in cls.mro():
40 for cls in cls.mro():
41 try:
41 try:
42 func = cls.__dict__[func_name]
42 func = cls.__dict__[func_name]
43 except KeyError:
43 except KeyError:
44 pass
44 pass
45 else:
45 else:
46 break
46 break
47 return func.__get__(obj, cls)
47 return func.__get__(obj, cls)
48
48
49
49
50 class ParametersProc(ProcessingUnit):
50 class ParametersProc(ProcessingUnit):
51
51
52 METHODS = {}
52 METHODS = {}
53 nSeconds = None
53 nSeconds = None
54
54
55 def __init__(self):
55 def __init__(self):
56 ProcessingUnit.__init__(self)
56 ProcessingUnit.__init__(self)
57
57
58 # self.objectDict = {}
58 # self.objectDict = {}
59 self.buffer = None
59 self.buffer = None
60 self.firstdatatime = None
60 self.firstdatatime = None
61 self.profIndex = 0
61 self.profIndex = 0
62 self.dataOut = Parameters()
62 self.dataOut = Parameters()
63 self.setupReq = False #Agregar a todas las unidades de proc
63 self.setupReq = False #Agregar a todas las unidades de proc
64
64
65 def __updateObjFromInput(self):
65 def __updateObjFromInput(self):
66
66
67 self.dataOut.inputUnit = self.dataIn.type
67 self.dataOut.inputUnit = self.dataIn.type
68
68
69 self.dataOut.timeZone = self.dataIn.timeZone
69 self.dataOut.timeZone = self.dataIn.timeZone
70 self.dataOut.dstFlag = self.dataIn.dstFlag
70 self.dataOut.dstFlag = self.dataIn.dstFlag
71 self.dataOut.errorCount = self.dataIn.errorCount
71 self.dataOut.errorCount = self.dataIn.errorCount
72 self.dataOut.useLocalTime = self.dataIn.useLocalTime
72 self.dataOut.useLocalTime = self.dataIn.useLocalTime
73
73
74 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
74 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
75 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
75 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
76 self.dataOut.channelList = self.dataIn.channelList
76 self.dataOut.channelList = self.dataIn.channelList
77 self.dataOut.heightList = self.dataIn.heightList
77 self.dataOut.heightList = self.dataIn.heightList
78 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
78 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
79 # self.dataOut.nHeights = self.dataIn.nHeights
79 # self.dataOut.nHeights = self.dataIn.nHeights
80 # self.dataOut.nChannels = self.dataIn.nChannels
80 # self.dataOut.nChannels = self.dataIn.nChannels
81 self.dataOut.nBaud = self.dataIn.nBaud
81 self.dataOut.nBaud = self.dataIn.nBaud
82 self.dataOut.nCode = self.dataIn.nCode
82 self.dataOut.nCode = self.dataIn.nCode
83 self.dataOut.code = self.dataIn.code
83 self.dataOut.code = self.dataIn.code
84 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
84 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
85 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
85 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
86 # self.dataOut.utctime = self.firstdatatime
86 # self.dataOut.utctime = self.firstdatatime
87 self.dataOut.utctime = self.dataIn.utctime
87 self.dataOut.utctime = self.dataIn.utctime
88 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
88 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
89 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
89 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
90 self.dataOut.nCohInt = self.dataIn.nCohInt
90 self.dataOut.nCohInt = self.dataIn.nCohInt
91 # self.dataOut.nIncohInt = 1
91 # self.dataOut.nIncohInt = 1
92 self.dataOut.ippSeconds = self.dataIn.ippSeconds
92 self.dataOut.ippSeconds = self.dataIn.ippSeconds
93 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
93 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
94 self.dataOut.timeInterval1 = self.dataIn.timeInterval
94 self.dataOut.timeInterval1 = self.dataIn.timeInterval
95 self.dataOut.heightList = self.dataIn.getHeiRange()
95 self.dataOut.heightList = self.dataIn.getHeiRange()
96 self.dataOut.frequency = self.dataIn.frequency
96 self.dataOut.frequency = self.dataIn.frequency
97 # self.dataOut.noise = self.dataIn.noise
97 # self.dataOut.noise = self.dataIn.noise
98
98
99 def run(self):
99 def run(self):
100
100
101
101
102
102
103 #---------------------- Voltage Data ---------------------------
103 #---------------------- Voltage Data ---------------------------
104
104
105 if self.dataIn.type == "Voltage":
105 if self.dataIn.type == "Voltage":
106
106
107 self.__updateObjFromInput()
107 self.__updateObjFromInput()
108 self.dataOut.data_pre = self.dataIn.data.copy()
108 self.dataOut.data_pre = self.dataIn.data.copy()
109 self.dataOut.flagNoData = False
109 self.dataOut.flagNoData = False
110 self.dataOut.utctimeInit = self.dataIn.utctime
110 self.dataOut.utctimeInit = self.dataIn.utctime
111 self.dataOut.paramInterval = self.dataIn.nProfiles*self.dataIn.nCohInt*self.dataIn.ippSeconds
111 self.dataOut.paramInterval = self.dataIn.nProfiles*self.dataIn.nCohInt*self.dataIn.ippSeconds
112 if hasattr(self.dataIn, 'dataPP_POW'):
113 self.dataOut.dataPP_POW = self.dataIn.dataPP_POW
114
115 if hasattr(self.dataIn, 'dataPP_POWER'):
116 self.dataOut.dataPP_POWER = self.dataIn.dataPP_POWER
117
118 if hasattr(self.dataIn, 'dataPP_DOP'):
119 self.dataOut.dataPP_DOP = self.dataIn.dataPP_DOP
120
121 if hasattr(self.dataIn, 'dataPP_SNR'):
122 self.dataOut.dataPP_SNR = self.dataIn.dataPP_SNR
123
124 if hasattr(self.dataIn, 'dataPP_WIDTH'):
125 self.dataOut.dataPP_WIDTH = self.dataIn.dataPP_WIDTH
112 return
126 return
113
127
114 #---------------------- Spectra Data ---------------------------
128 #---------------------- Spectra Data ---------------------------
115
129
116 if self.dataIn.type == "Spectra":
130 if self.dataIn.type == "Spectra":
117
131
118 self.dataOut.data_pre = (self.dataIn.data_spc, self.dataIn.data_cspc)
132 self.dataOut.data_pre = (self.dataIn.data_spc, self.dataIn.data_cspc)
119 self.dataOut.data_spc = self.dataIn.data_spc
133 self.dataOut.data_spc = self.dataIn.data_spc
120 self.dataOut.data_cspc = self.dataIn.data_cspc
134 self.dataOut.data_cspc = self.dataIn.data_cspc
121 self.dataOut.nProfiles = self.dataIn.nProfiles
135 self.dataOut.nProfiles = self.dataIn.nProfiles
122 self.dataOut.nIncohInt = self.dataIn.nIncohInt
136 self.dataOut.nIncohInt = self.dataIn.nIncohInt
123 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
137 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
124 self.dataOut.ippFactor = self.dataIn.ippFactor
138 self.dataOut.ippFactor = self.dataIn.ippFactor
125 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
139 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
126 self.dataOut.spc_noise = self.dataIn.getNoise()
140 self.dataOut.spc_noise = self.dataIn.getNoise()
127 self.dataOut.spc_range = (self.dataIn.getFreqRange(1) , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
141 self.dataOut.spc_range = (self.dataIn.getFreqRange(1) , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
128 # self.dataOut.normFactor = self.dataIn.normFactor
142 # self.dataOut.normFactor = self.dataIn.normFactor
129 self.dataOut.pairsList = self.dataIn.pairsList
143 self.dataOut.pairsList = self.dataIn.pairsList
130 self.dataOut.groupList = self.dataIn.pairsList
144 self.dataOut.groupList = self.dataIn.pairsList
131 self.dataOut.flagNoData = False
145 self.dataOut.flagNoData = False
132
146
133 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
147 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
134 self.dataOut.ChanDist = self.dataIn.ChanDist
148 self.dataOut.ChanDist = self.dataIn.ChanDist
135 else: self.dataOut.ChanDist = None
149 else: self.dataOut.ChanDist = None
136
150
137 #if hasattr(self.dataIn, 'VelRange'): #Velocities range
151 #if hasattr(self.dataIn, 'VelRange'): #Velocities range
138 # self.dataOut.VelRange = self.dataIn.VelRange
152 # self.dataOut.VelRange = self.dataIn.VelRange
139 #else: self.dataOut.VelRange = None
153 #else: self.dataOut.VelRange = None
140
154
141 if hasattr(self.dataIn, 'RadarConst'): #Radar Constant
155 if hasattr(self.dataIn, 'RadarConst'): #Radar Constant
142 self.dataOut.RadarConst = self.dataIn.RadarConst
156 self.dataOut.RadarConst = self.dataIn.RadarConst
143
157
144 if hasattr(self.dataIn, 'NPW'): #NPW
158 if hasattr(self.dataIn, 'NPW'): #NPW
145 self.dataOut.NPW = self.dataIn.NPW
159 self.dataOut.NPW = self.dataIn.NPW
146
160
147 if hasattr(self.dataIn, 'COFA'): #COFA
161 if hasattr(self.dataIn, 'COFA'): #COFA
148 self.dataOut.COFA = self.dataIn.COFA
162 self.dataOut.COFA = self.dataIn.COFA
149
163
150
164
151
165
152 #---------------------- Correlation Data ---------------------------
166 #---------------------- Correlation Data ---------------------------
153
167
154 if self.dataIn.type == "Correlation":
168 if self.dataIn.type == "Correlation":
155 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
169 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
156
170
157 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
171 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
158 self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
172 self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
159 self.dataOut.groupList = (acf_pairs, ccf_pairs)
173 self.dataOut.groupList = (acf_pairs, ccf_pairs)
160
174
161 self.dataOut.abscissaList = self.dataIn.lagRange
175 self.dataOut.abscissaList = self.dataIn.lagRange
162 self.dataOut.noise = self.dataIn.noise
176 self.dataOut.noise = self.dataIn.noise
163 self.dataOut.data_SNR = self.dataIn.SNR
177 self.dataOut.data_SNR = self.dataIn.SNR
164 self.dataOut.flagNoData = False
178 self.dataOut.flagNoData = False
165 self.dataOut.nAvg = self.dataIn.nAvg
179 self.dataOut.nAvg = self.dataIn.nAvg
166
180
167 #---------------------- Parameters Data ---------------------------
181 #---------------------- Parameters Data ---------------------------
168
182
169 if self.dataIn.type == "Parameters":
183 if self.dataIn.type == "Parameters":
170 self.dataOut.copy(self.dataIn)
184 self.dataOut.copy(self.dataIn)
171 self.dataOut.flagNoData = False
185 self.dataOut.flagNoData = False
172
186
173 return True
187 return True
174
188
175 self.__updateObjFromInput()
189 self.__updateObjFromInput()
176 self.dataOut.utctimeInit = self.dataIn.utctime
190 self.dataOut.utctimeInit = self.dataIn.utctime
177 self.dataOut.paramInterval = self.dataIn.timeInterval
191 self.dataOut.paramInterval = self.dataIn.timeInterval
178
192
179 return
193 return
180
194
181
195
182 def target(tups):
196 def target(tups):
183
197
184 obj, args = tups
198 obj, args = tups
185
199
186 return obj.FitGau(args)
200 return obj.FitGau(args)
187
201
188
202
189 class SpectralFilters(Operation):
203 class SpectralFilters(Operation):
190
204
191 '''This class allows the Rainfall / Wind Selection for CLAIRE RADAR
205 '''This class allows the Rainfall / Wind Selection for CLAIRE RADAR
192
206
193 LimitR : It is the limit in m/s of Rainfall
207 LimitR : It is the limit in m/s of Rainfall
194 LimitW : It is the limit in m/s for Winds
208 LimitW : It is the limit in m/s for Winds
195
209
196 Input:
210 Input:
197
211
198 self.dataOut.data_pre : SPC and CSPC
212 self.dataOut.data_pre : SPC and CSPC
199 self.dataOut.spc_range : To select wind and rainfall velocities
213 self.dataOut.spc_range : To select wind and rainfall velocities
200
214
201 Affected:
215 Affected:
202
216
203 self.dataOut.data_pre : It is used for the new SPC and CSPC ranges of wind
217 self.dataOut.data_pre : It is used for the new SPC and CSPC ranges of wind
204 self.dataOut.spcparam_range : Used in SpcParamPlot
218 self.dataOut.spcparam_range : Used in SpcParamPlot
205 self.dataOut.SPCparam : Used in PrecipitationProc
219 self.dataOut.SPCparam : Used in PrecipitationProc
206
220
207
221
208 '''
222 '''
209
223
210 def __init__(self):
224 def __init__(self):
211 Operation.__init__(self)
225 Operation.__init__(self)
212 self.i=0
226 self.i=0
213
227
214 def run(self, dataOut, PositiveLimit=1.5, NegativeLimit=2.5):
228 def run(self, dataOut, PositiveLimit=1.5, NegativeLimit=2.5):
215
229
216
230
217 #Limite de vientos
231 #Limite de vientos
218 LimitR = PositiveLimit
232 LimitR = PositiveLimit
219 LimitN = NegativeLimit
233 LimitN = NegativeLimit
220
234
221 self.spc = dataOut.data_pre[0].copy()
235 self.spc = dataOut.data_pre[0].copy()
222 self.cspc = dataOut.data_pre[1].copy()
236 self.cspc = dataOut.data_pre[1].copy()
223
237
224 self.Num_Hei = self.spc.shape[2]
238 self.Num_Hei = self.spc.shape[2]
225 self.Num_Bin = self.spc.shape[1]
239 self.Num_Bin = self.spc.shape[1]
226 self.Num_Chn = self.spc.shape[0]
240 self.Num_Chn = self.spc.shape[0]
227
241
228 VelRange = dataOut.spc_range[2]
242 VelRange = dataOut.spc_range[2]
229 TimeRange = dataOut.spc_range[1]
243 TimeRange = dataOut.spc_range[1]
230 FrecRange = dataOut.spc_range[0]
244 FrecRange = dataOut.spc_range[0]
231
245
232 Vmax= 2*numpy.max(dataOut.spc_range[2])
246 Vmax= 2*numpy.max(dataOut.spc_range[2])
233 Tmax= 2*numpy.max(dataOut.spc_range[1])
247 Tmax= 2*numpy.max(dataOut.spc_range[1])
234 Fmax= 2*numpy.max(dataOut.spc_range[0])
248 Fmax= 2*numpy.max(dataOut.spc_range[0])
235
249
236 Breaker1R=VelRange[numpy.abs(VelRange-(-LimitN)).argmin()]
250 Breaker1R=VelRange[numpy.abs(VelRange-(-LimitN)).argmin()]
237 Breaker1R=numpy.where(VelRange == Breaker1R)
251 Breaker1R=numpy.where(VelRange == Breaker1R)
238
252
239 Delta = self.Num_Bin/2 - Breaker1R[0]
253 Delta = self.Num_Bin/2 - Breaker1R[0]
240
254
241
255
242 '''Reacomodando SPCrange'''
256 '''Reacomodando SPCrange'''
243
257
244 VelRange=numpy.roll(VelRange,-(int(self.Num_Bin/2)) ,axis=0)
258 VelRange=numpy.roll(VelRange,-(int(self.Num_Bin/2)) ,axis=0)
245
259
246 VelRange[-(int(self.Num_Bin/2)):]+= Vmax
260 VelRange[-(int(self.Num_Bin/2)):]+= Vmax
247
261
248 FrecRange=numpy.roll(FrecRange,-(int(self.Num_Bin/2)),axis=0)
262 FrecRange=numpy.roll(FrecRange,-(int(self.Num_Bin/2)),axis=0)
249
263
250 FrecRange[-(int(self.Num_Bin/2)):]+= Fmax
264 FrecRange[-(int(self.Num_Bin/2)):]+= Fmax
251
265
252 TimeRange=numpy.roll(TimeRange,-(int(self.Num_Bin/2)),axis=0)
266 TimeRange=numpy.roll(TimeRange,-(int(self.Num_Bin/2)),axis=0)
253
267
254 TimeRange[-(int(self.Num_Bin/2)):]+= Tmax
268 TimeRange[-(int(self.Num_Bin/2)):]+= Tmax
255
269
256 ''' ------------------ '''
270 ''' ------------------ '''
257
271
258 Breaker2R=VelRange[numpy.abs(VelRange-(LimitR)).argmin()]
272 Breaker2R=VelRange[numpy.abs(VelRange-(LimitR)).argmin()]
259 Breaker2R=numpy.where(VelRange == Breaker2R)
273 Breaker2R=numpy.where(VelRange == Breaker2R)
260
274
261
275
262 SPCroll = numpy.roll(self.spc,-(int(self.Num_Bin/2)) ,axis=1)
276 SPCroll = numpy.roll(self.spc,-(int(self.Num_Bin/2)) ,axis=1)
263
277
264 SPCcut = SPCroll.copy()
278 SPCcut = SPCroll.copy()
265 for i in range(self.Num_Chn):
279 for i in range(self.Num_Chn):
266
280
267 SPCcut[i,0:int(Breaker2R[0]),:] = dataOut.noise[i]
281 SPCcut[i,0:int(Breaker2R[0]),:] = dataOut.noise[i]
268 SPCcut[i,-int(Delta):,:] = dataOut.noise[i]
282 SPCcut[i,-int(Delta):,:] = dataOut.noise[i]
269
283
270 SPCcut[i]=SPCcut[i]- dataOut.noise[i]
284 SPCcut[i]=SPCcut[i]- dataOut.noise[i]
271 SPCcut[ numpy.where( SPCcut<0 ) ] = 1e-20
285 SPCcut[ numpy.where( SPCcut<0 ) ] = 1e-20
272
286
273 SPCroll[i]=SPCroll[i]-dataOut.noise[i]
287 SPCroll[i]=SPCroll[i]-dataOut.noise[i]
274 SPCroll[ numpy.where( SPCroll<0 ) ] = 1e-20
288 SPCroll[ numpy.where( SPCroll<0 ) ] = 1e-20
275
289
276 SPC_ch1 = SPCroll
290 SPC_ch1 = SPCroll
277
291
278 SPC_ch2 = SPCcut
292 SPC_ch2 = SPCcut
279
293
280 SPCparam = (SPC_ch1, SPC_ch2, self.spc)
294 SPCparam = (SPC_ch1, SPC_ch2, self.spc)
281 dataOut.SPCparam = numpy.asarray(SPCparam)
295 dataOut.SPCparam = numpy.asarray(SPCparam)
282
296
283
297
284 dataOut.spcparam_range=numpy.zeros([self.Num_Chn,self.Num_Bin+1])
298 dataOut.spcparam_range=numpy.zeros([self.Num_Chn,self.Num_Bin+1])
285
299
286 dataOut.spcparam_range[2]=VelRange
300 dataOut.spcparam_range[2]=VelRange
287 dataOut.spcparam_range[1]=TimeRange
301 dataOut.spcparam_range[1]=TimeRange
288 dataOut.spcparam_range[0]=FrecRange
302 dataOut.spcparam_range[0]=FrecRange
289 return dataOut
303 return dataOut
290
304
291 class GaussianFit(Operation):
305 class GaussianFit(Operation):
292
306
293 '''
307 '''
294 Function that fit of one and two generalized gaussians (gg) based
308 Function that fit of one and two generalized gaussians (gg) based
295 on the PSD shape across an "power band" identified from a cumsum of
309 on the PSD shape across an "power band" identified from a cumsum of
296 the measured spectrum - noise.
310 the measured spectrum - noise.
297
311
298 Input:
312 Input:
299 self.dataOut.data_pre : SelfSpectra
313 self.dataOut.data_pre : SelfSpectra
300
314
301 Output:
315 Output:
302 self.dataOut.SPCparam : SPC_ch1, SPC_ch2
316 self.dataOut.SPCparam : SPC_ch1, SPC_ch2
303
317
304 '''
318 '''
305 def __init__(self):
319 def __init__(self):
306 Operation.__init__(self)
320 Operation.__init__(self)
307 self.i=0
321 self.i=0
308
322
309
323
310 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
324 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
311 """This routine will find a couple of generalized Gaussians to a power spectrum
325 """This routine will find a couple of generalized Gaussians to a power spectrum
312 input: spc
326 input: spc
313 output:
327 output:
314 Amplitude0,shift0,width0,p0,Amplitude1,shift1,width1,p1,noise
328 Amplitude0,shift0,width0,p0,Amplitude1,shift1,width1,p1,noise
315 """
329 """
316
330
317 self.spc = dataOut.data_pre[0].copy()
331 self.spc = dataOut.data_pre[0].copy()
318 self.Num_Hei = self.spc.shape[2]
332 self.Num_Hei = self.spc.shape[2]
319 self.Num_Bin = self.spc.shape[1]
333 self.Num_Bin = self.spc.shape[1]
320 self.Num_Chn = self.spc.shape[0]
334 self.Num_Chn = self.spc.shape[0]
321 Vrange = dataOut.abscissaList
335 Vrange = dataOut.abscissaList
322
336
323 GauSPC = numpy.empty([self.Num_Chn,self.Num_Bin,self.Num_Hei])
337 GauSPC = numpy.empty([self.Num_Chn,self.Num_Bin,self.Num_Hei])
324 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
338 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
325 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
339 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
326 SPC_ch1[:] = numpy.NaN
340 SPC_ch1[:] = numpy.NaN
327 SPC_ch2[:] = numpy.NaN
341 SPC_ch2[:] = numpy.NaN
328
342
329
343
330 start_time = time.time()
344 start_time = time.time()
331
345
332 noise_ = dataOut.spc_noise[0].copy()
346 noise_ = dataOut.spc_noise[0].copy()
333
347
334
348
335 pool = Pool(processes=self.Num_Chn)
349 pool = Pool(processes=self.Num_Chn)
336 args = [(Vrange, Ch, pnoise, noise_, num_intg, SNRlimit) for Ch in range(self.Num_Chn)]
350 args = [(Vrange, Ch, pnoise, noise_, num_intg, SNRlimit) for Ch in range(self.Num_Chn)]
337 objs = [self for __ in range(self.Num_Chn)]
351 objs = [self for __ in range(self.Num_Chn)]
338 attrs = list(zip(objs, args))
352 attrs = list(zip(objs, args))
339 gauSPC = pool.map(target, attrs)
353 gauSPC = pool.map(target, attrs)
340 dataOut.SPCparam = numpy.asarray(SPCparam)
354 dataOut.SPCparam = numpy.asarray(SPCparam)
341
355
342 ''' Parameters:
356 ''' Parameters:
343 1. Amplitude
357 1. Amplitude
344 2. Shift
358 2. Shift
345 3. Width
359 3. Width
346 4. Power
360 4. Power
347 '''
361 '''
348
362
349 def FitGau(self, X):
363 def FitGau(self, X):
350
364
351 Vrange, ch, pnoise, noise_, num_intg, SNRlimit = X
365 Vrange, ch, pnoise, noise_, num_intg, SNRlimit = X
352
366
353 SPCparam = []
367 SPCparam = []
354 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
368 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
355 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
369 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
356 SPC_ch1[:] = 0#numpy.NaN
370 SPC_ch1[:] = 0#numpy.NaN
357 SPC_ch2[:] = 0#numpy.NaN
371 SPC_ch2[:] = 0#numpy.NaN
358
372
359
373
360
374
361 for ht in range(self.Num_Hei):
375 for ht in range(self.Num_Hei):
362
376
363
377
364 spc = numpy.asarray(self.spc)[ch,:,ht]
378 spc = numpy.asarray(self.spc)[ch,:,ht]
365
379
366 #############################################
380 #############################################
367 # normalizing spc and noise
381 # normalizing spc and noise
368 # This part differs from gg1
382 # This part differs from gg1
369 spc_norm_max = max(spc)
383 spc_norm_max = max(spc)
370 #spc = spc / spc_norm_max
384 #spc = spc / spc_norm_max
371 pnoise = pnoise #/ spc_norm_max
385 pnoise = pnoise #/ spc_norm_max
372 #############################################
386 #############################################
373
387
374 fatspectra=1.0
388 fatspectra=1.0
375
389
376 wnoise = noise_ #/ spc_norm_max
390 wnoise = noise_ #/ spc_norm_max
377 #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
391 #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
378 #if wnoise>1.1*pnoise: # to be tested later
392 #if wnoise>1.1*pnoise: # to be tested later
379 # wnoise=pnoise
393 # wnoise=pnoise
380 noisebl=wnoise*0.9;
394 noisebl=wnoise*0.9;
381 noisebh=wnoise*1.1
395 noisebh=wnoise*1.1
382 spc=spc-wnoise
396 spc=spc-wnoise
383
397
384 minx=numpy.argmin(spc)
398 minx=numpy.argmin(spc)
385 #spcs=spc.copy()
399 #spcs=spc.copy()
386 spcs=numpy.roll(spc,-minx)
400 spcs=numpy.roll(spc,-minx)
387 cum=numpy.cumsum(spcs)
401 cum=numpy.cumsum(spcs)
388 tot_noise=wnoise * self.Num_Bin #64;
402 tot_noise=wnoise * self.Num_Bin #64;
389
403
390 snr = sum(spcs)/tot_noise
404 snr = sum(spcs)/tot_noise
391 snrdB=10.*numpy.log10(snr)
405 snrdB=10.*numpy.log10(snr)
392
406
393 if snrdB < SNRlimit :
407 if snrdB < SNRlimit :
394 snr = numpy.NaN
408 snr = numpy.NaN
395 SPC_ch1[:,ht] = 0#numpy.NaN
409 SPC_ch1[:,ht] = 0#numpy.NaN
396 SPC_ch1[:,ht] = 0#numpy.NaN
410 SPC_ch1[:,ht] = 0#numpy.NaN
397 SPCparam = (SPC_ch1,SPC_ch2)
411 SPCparam = (SPC_ch1,SPC_ch2)
398 continue
412 continue
399
413
400
414
401 #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
415 #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
402 # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
416 # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
403
417
404 cummax=max(cum);
418 cummax=max(cum);
405 epsi=0.08*fatspectra # cumsum to narrow down the energy region
419 epsi=0.08*fatspectra # cumsum to narrow down the energy region
406 cumlo=cummax*epsi;
420 cumlo=cummax*epsi;
407 cumhi=cummax*(1-epsi)
421 cumhi=cummax*(1-epsi)
408 powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
422 powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
409
423
410
424
411 if len(powerindex) < 1:# case for powerindex 0
425 if len(powerindex) < 1:# case for powerindex 0
412 continue
426 continue
413 powerlo=powerindex[0]
427 powerlo=powerindex[0]
414 powerhi=powerindex[-1]
428 powerhi=powerindex[-1]
415 powerwidth=powerhi-powerlo
429 powerwidth=powerhi-powerlo
416
430
417 firstpeak=powerlo+powerwidth/10.# first gaussian energy location
431 firstpeak=powerlo+powerwidth/10.# first gaussian energy location
418 secondpeak=powerhi-powerwidth/10.#second gaussian energy location
432 secondpeak=powerhi-powerwidth/10.#second gaussian energy location
419 midpeak=(firstpeak+secondpeak)/2.
433 midpeak=(firstpeak+secondpeak)/2.
420 firstamp=spcs[int(firstpeak)]
434 firstamp=spcs[int(firstpeak)]
421 secondamp=spcs[int(secondpeak)]
435 secondamp=spcs[int(secondpeak)]
422 midamp=spcs[int(midpeak)]
436 midamp=spcs[int(midpeak)]
423
437
424 x=numpy.arange( self.Num_Bin )
438 x=numpy.arange( self.Num_Bin )
425 y_data=spc+wnoise
439 y_data=spc+wnoise
426
440
427 ''' single Gaussian '''
441 ''' single Gaussian '''
428 shift0=numpy.mod(midpeak+minx, self.Num_Bin )
442 shift0=numpy.mod(midpeak+minx, self.Num_Bin )
429 width0=powerwidth/4.#Initialization entire power of spectrum divided by 4
443 width0=powerwidth/4.#Initialization entire power of spectrum divided by 4
430 power0=2.
444 power0=2.
431 amplitude0=midamp
445 amplitude0=midamp
432 state0=[shift0,width0,amplitude0,power0,wnoise]
446 state0=[shift0,width0,amplitude0,power0,wnoise]
433 bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
447 bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
434 lsq1=fmin_l_bfgs_b(self.misfit1,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
448 lsq1=fmin_l_bfgs_b(self.misfit1,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
435
436 chiSq1=lsq1[1];
437
449
438
450 chiSq1=lsq1[1];
451
452
439 if fatspectra<1.0 and powerwidth<4:
453 if fatspectra<1.0 and powerwidth<4:
440 choice=0
454 choice=0
441 Amplitude0=lsq1[0][2]
455 Amplitude0=lsq1[0][2]
442 shift0=lsq1[0][0]
456 shift0=lsq1[0][0]
443 width0=lsq1[0][1]
457 width0=lsq1[0][1]
444 p0=lsq1[0][3]
458 p0=lsq1[0][3]
445 Amplitude1=0.
459 Amplitude1=0.
446 shift1=0.
460 shift1=0.
447 width1=0.
461 width1=0.
448 p1=0.
462 p1=0.
449 noise=lsq1[0][4]
463 noise=lsq1[0][4]
450 #return (numpy.array([shift0,width0,Amplitude0,p0]),
464 #return (numpy.array([shift0,width0,Amplitude0,p0]),
451 # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
465 # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
452
466
453 ''' two gaussians '''
467 ''' two gaussians '''
454 #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
468 #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
455 shift0=numpy.mod(firstpeak+minx, self.Num_Bin );
469 shift0=numpy.mod(firstpeak+minx, self.Num_Bin );
456 shift1=numpy.mod(secondpeak+minx, self.Num_Bin )
470 shift1=numpy.mod(secondpeak+minx, self.Num_Bin )
457 width0=powerwidth/6.;
471 width0=powerwidth/6.;
458 width1=width0
472 width1=width0
459 power0=2.;
473 power0=2.;
460 power1=power0
474 power1=power0
461 amplitude0=firstamp;
475 amplitude0=firstamp;
462 amplitude1=secondamp
476 amplitude1=secondamp
463 state0=[shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
477 state0=[shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
464 #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
478 #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
465 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))
479 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))
466 #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))
480 #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))
467
481
468 lsq2 = fmin_l_bfgs_b( self.misfit2 , state0 , args=(y_data,x,num_intg) , bounds=bnds , approx_grad=True )
482 lsq2 = fmin_l_bfgs_b( self.misfit2 , state0 , args=(y_data,x,num_intg) , bounds=bnds , approx_grad=True )
469
483
470
484
471 chiSq2=lsq2[1];
485 chiSq2=lsq2[1];
472
486
473
487
474
488
475 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)
489 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)
476
490
477 if snrdB>-12: # when SNR is strong pick the peak with least shift (LOS velocity) error
491 if snrdB>-12: # when SNR is strong pick the peak with least shift (LOS velocity) error
478 if oneG:
492 if oneG:
479 choice=0
493 choice=0
480 else:
494 else:
481 w1=lsq2[0][1]; w2=lsq2[0][5]
495 w1=lsq2[0][1]; w2=lsq2[0][5]
482 a1=lsq2[0][2]; a2=lsq2[0][6]
496 a1=lsq2[0][2]; a2=lsq2[0][6]
483 p1=lsq2[0][3]; p2=lsq2[0][7]
497 p1=lsq2[0][3]; p2=lsq2[0][7]
484 s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1;
498 s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1;
485 s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2;
499 s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2;
486 gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling
500 gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling
487
501
488 if gp1>gp2:
502 if gp1>gp2:
489 if a1>0.7*a2:
503 if a1>0.7*a2:
490 choice=1
504 choice=1
491 else:
505 else:
492 choice=2
506 choice=2
493 elif gp2>gp1:
507 elif gp2>gp1:
494 if a2>0.7*a1:
508 if a2>0.7*a1:
495 choice=2
509 choice=2
496 else:
510 else:
497 choice=1
511 choice=1
498 else:
512 else:
499 choice=numpy.argmax([a1,a2])+1
513 choice=numpy.argmax([a1,a2])+1
500 #else:
514 #else:
501 #choice=argmin([std2a,std2b])+1
515 #choice=argmin([std2a,std2b])+1
502
516
503 else: # with low SNR go to the most energetic peak
517 else: # with low SNR go to the most energetic peak
504 choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
518 choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
505
519
506
520
507 shift0=lsq2[0][0];
521 shift0=lsq2[0][0];
508 vel0=Vrange[0] + shift0*(Vrange[1]-Vrange[0])
522 vel0=Vrange[0] + shift0*(Vrange[1]-Vrange[0])
509 shift1=lsq2[0][4];
523 shift1=lsq2[0][4];
510 vel1=Vrange[0] + shift1*(Vrange[1]-Vrange[0])
524 vel1=Vrange[0] + shift1*(Vrange[1]-Vrange[0])
511
525
512 max_vel = 1.0
526 max_vel = 1.0
513
527
514 #first peak will be 0, second peak will be 1
528 #first peak will be 0, second peak will be 1
515 if vel0 > -1.0 and vel0 < max_vel : #first peak is in the correct range
529 if vel0 > -1.0 and vel0 < max_vel : #first peak is in the correct range
516 shift0=lsq2[0][0]
530 shift0=lsq2[0][0]
517 width0=lsq2[0][1]
531 width0=lsq2[0][1]
518 Amplitude0=lsq2[0][2]
532 Amplitude0=lsq2[0][2]
519 p0=lsq2[0][3]
533 p0=lsq2[0][3]
520
534
521 shift1=lsq2[0][4]
535 shift1=lsq2[0][4]
522 width1=lsq2[0][5]
536 width1=lsq2[0][5]
523 Amplitude1=lsq2[0][6]
537 Amplitude1=lsq2[0][6]
524 p1=lsq2[0][7]
538 p1=lsq2[0][7]
525 noise=lsq2[0][8]
539 noise=lsq2[0][8]
526 else:
540 else:
527 shift1=lsq2[0][0]
541 shift1=lsq2[0][0]
528 width1=lsq2[0][1]
542 width1=lsq2[0][1]
529 Amplitude1=lsq2[0][2]
543 Amplitude1=lsq2[0][2]
530 p1=lsq2[0][3]
544 p1=lsq2[0][3]
531
545
532 shift0=lsq2[0][4]
546 shift0=lsq2[0][4]
533 width0=lsq2[0][5]
547 width0=lsq2[0][5]
534 Amplitude0=lsq2[0][6]
548 Amplitude0=lsq2[0][6]
535 p0=lsq2[0][7]
549 p0=lsq2[0][7]
536 noise=lsq2[0][8]
550 noise=lsq2[0][8]
537
551
538 if Amplitude0<0.05: # in case the peak is noise
552 if Amplitude0<0.05: # in case the peak is noise
539 shift0,width0,Amplitude0,p0 = [0,0,0,0]#4*[numpy.NaN]
553 shift0,width0,Amplitude0,p0 = [0,0,0,0]#4*[numpy.NaN]
540 if Amplitude1<0.05:
554 if Amplitude1<0.05:
541 shift1,width1,Amplitude1,p1 = [0,0,0,0]#4*[numpy.NaN]
555 shift1,width1,Amplitude1,p1 = [0,0,0,0]#4*[numpy.NaN]
542
556
543
557
544 SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0
558 SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0
545 SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1
559 SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1
546 SPCparam = (SPC_ch1,SPC_ch2)
560 SPCparam = (SPC_ch1,SPC_ch2)
547
561
548
562
549 return GauSPC
563 return GauSPC
550
564
551 def y_model1(self,x,state):
565 def y_model1(self,x,state):
552 shift0,width0,amplitude0,power0,noise=state
566 shift0,width0,amplitude0,power0,noise=state
553 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
567 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
554
568
555 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
569 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
556
570
557 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
571 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
558 return model0+model0u+model0d+noise
572 return model0+model0u+model0d+noise
559
573
560 def y_model2(self,x,state): #Equation for two generalized Gaussians with Nyquist
574 def y_model2(self,x,state): #Equation for two generalized Gaussians with Nyquist
561 shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,noise=state
575 shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,noise=state
562 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
576 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
563
577
564 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
578 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
565
579
566 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
580 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
567 model1=amplitude1*numpy.exp(-0.5*abs((x-shift1)/width1)**power1)
581 model1=amplitude1*numpy.exp(-0.5*abs((x-shift1)/width1)**power1)
568
582
569 model1u=amplitude1*numpy.exp(-0.5*abs((x-shift1- self.Num_Bin )/width1)**power1)
583 model1u=amplitude1*numpy.exp(-0.5*abs((x-shift1- self.Num_Bin )/width1)**power1)
570
584
571 model1d=amplitude1*numpy.exp(-0.5*abs((x-shift1+ self.Num_Bin )/width1)**power1)
585 model1d=amplitude1*numpy.exp(-0.5*abs((x-shift1+ self.Num_Bin )/width1)**power1)
572 return model0+model0u+model0d+model1+model1u+model1d+noise
586 return model0+model0u+model0d+model1+model1u+model1d+noise
573
587
574 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.
588 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.
575
589
576 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model1(x,state)))**2)#/(64-5.) # /(64-5.) can be commented
590 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model1(x,state)))**2)#/(64-5.) # /(64-5.) can be commented
577
591
578 def misfit2(self,state,y_data,x,num_intg):
592 def misfit2(self,state,y_data,x,num_intg):
579 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model2(x,state)))**2)#/(64-9.)
593 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model2(x,state)))**2)#/(64-9.)
580
594
581
595
582
596
583 class PrecipitationProc(Operation):
597 class PrecipitationProc(Operation):
584
598
585 '''
599 '''
586 Operator that estimates Reflectivity factor (Z), and estimates rainfall Rate (R)
600 Operator that estimates Reflectivity factor (Z), and estimates rainfall Rate (R)
587
601
588 Input:
602 Input:
589 self.dataOut.data_pre : SelfSpectra
603 self.dataOut.data_pre : SelfSpectra
590
604
591 Output:
605 Output:
592
606
593 self.dataOut.data_output : Reflectivity factor, rainfall Rate
607 self.dataOut.data_output : Reflectivity factor, rainfall Rate
594
608
595
609
596 Parameters affected:
610 Parameters affected:
597 '''
611 '''
598
612
599 def __init__(self):
613 def __init__(self):
600 Operation.__init__(self)
614 Operation.__init__(self)
601 self.i=0
615 self.i=0
602
616
603
617
604 def gaus(self,xSamples,Amp,Mu,Sigma):
618 def gaus(self,xSamples,Amp,Mu,Sigma):
605 return ( Amp / ((2*numpy.pi)**0.5 * Sigma) ) * numpy.exp( -( xSamples - Mu )**2 / ( 2 * (Sigma**2) ))
619 return ( Amp / ((2*numpy.pi)**0.5 * Sigma) ) * numpy.exp( -( xSamples - Mu )**2 / ( 2 * (Sigma**2) ))
606
620
607
621
608
622
609 def Moments(self, ySamples, xSamples):
623 def Moments(self, ySamples, xSamples):
610 Pot = numpy.nansum( ySamples ) # Potencia, momento 0
624 Pot = numpy.nansum( ySamples ) # Potencia, momento 0
611 yNorm = ySamples / Pot
625 yNorm = ySamples / Pot
612
626
613 Vr = numpy.nansum( yNorm * xSamples ) # Velocidad radial, mu, corrimiento doppler, primer momento
627 Vr = numpy.nansum( yNorm * xSamples ) # Velocidad radial, mu, corrimiento doppler, primer momento
614 Sigma2 = abs(numpy.nansum( yNorm * ( xSamples - Vr )**2 )) # Segundo Momento
628 Sigma2 = abs(numpy.nansum( yNorm * ( xSamples - Vr )**2 )) # Segundo Momento
615 Desv = Sigma2**0.5 # Desv. Estandar, Ancho espectral
629 Desv = Sigma2**0.5 # Desv. Estandar, Ancho espectral
616
630
617 return numpy.array([Pot, Vr, Desv])
631 return numpy.array([Pot, Vr, Desv])
618
632
619 def run(self, dataOut, radar=None, Pt=5000, Gt=295.1209, Gr=70.7945, Lambda=0.6741, aL=2.5118,
633 def run(self, dataOut, radar=None, Pt=5000, Gt=295.1209, Gr=70.7945, Lambda=0.6741, aL=2.5118,
620 tauW=4e-06, ThetaT=0.1656317, ThetaR=0.36774087, Km = 0.93, Altitude=3350):
634 tauW=4e-06, ThetaT=0.1656317, ThetaR=0.36774087, Km = 0.93, Altitude=3350):
621
635
622
636
623 Velrange = dataOut.spcparam_range[2]
637 Velrange = dataOut.spcparam_range[2]
624 FrecRange = dataOut.spcparam_range[0]
638 FrecRange = dataOut.spcparam_range[0]
625
639
626 dV= Velrange[1]-Velrange[0]
640 dV= Velrange[1]-Velrange[0]
627 dF= FrecRange[1]-FrecRange[0]
641 dF= FrecRange[1]-FrecRange[0]
628
642
629 if radar == "MIRA35C" :
643 if radar == "MIRA35C" :
630
644
631 self.spc = dataOut.data_pre[0].copy()
645 self.spc = dataOut.data_pre[0].copy()
632 self.Num_Hei = self.spc.shape[2]
646 self.Num_Hei = self.spc.shape[2]
633 self.Num_Bin = self.spc.shape[1]
647 self.Num_Bin = self.spc.shape[1]
634 self.Num_Chn = self.spc.shape[0]
648 self.Num_Chn = self.spc.shape[0]
635 Ze = self.dBZeMODE2(dataOut)
649 Ze = self.dBZeMODE2(dataOut)
636
650
637 else:
651 else:
638
652
639 self.spc = dataOut.SPCparam[1].copy() #dataOut.data_pre[0].copy() #
653 self.spc = dataOut.SPCparam[1].copy() #dataOut.data_pre[0].copy() #
640
654
641 """NOTA SE DEBE REMOVER EL RANGO DEL PULSO TX"""
655 """NOTA SE DEBE REMOVER EL RANGO DEL PULSO TX"""
642
656
643 self.spc[:,:,0:7]= numpy.NaN
657 self.spc[:,:,0:7]= numpy.NaN
644
658
645 """##########################################"""
659 """##########################################"""
646
660
647 self.Num_Hei = self.spc.shape[2]
661 self.Num_Hei = self.spc.shape[2]
648 self.Num_Bin = self.spc.shape[1]
662 self.Num_Bin = self.spc.shape[1]
649 self.Num_Chn = self.spc.shape[0]
663 self.Num_Chn = self.spc.shape[0]
650
664
651 ''' Se obtiene la constante del RADAR '''
665 ''' Se obtiene la constante del RADAR '''
652
666
653 self.Pt = Pt
667 self.Pt = Pt
654 self.Gt = Gt
668 self.Gt = Gt
655 self.Gr = Gr
669 self.Gr = Gr
656 self.Lambda = Lambda
670 self.Lambda = Lambda
657 self.aL = aL
671 self.aL = aL
658 self.tauW = tauW
672 self.tauW = tauW
659 self.ThetaT = ThetaT
673 self.ThetaT = ThetaT
660 self.ThetaR = ThetaR
674 self.ThetaR = ThetaR
661
675
662 Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
676 Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
663 Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * tauW * numpy.pi * ThetaT * ThetaR)
677 Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * tauW * numpy.pi * ThetaT * ThetaR)
664 RadarConstant = 10e-26 * Numerator / Denominator #
678 RadarConstant = 10e-26 * Numerator / Denominator #
665
679
666 ''' ============================= '''
680 ''' ============================= '''
667
681
668 self.spc[0] = (self.spc[0]-dataOut.noise[0])
682 self.spc[0] = (self.spc[0]-dataOut.noise[0])
669 self.spc[1] = (self.spc[1]-dataOut.noise[1])
683 self.spc[1] = (self.spc[1]-dataOut.noise[1])
670 self.spc[2] = (self.spc[2]-dataOut.noise[2])
684 self.spc[2] = (self.spc[2]-dataOut.noise[2])
671
685
672 self.spc[ numpy.where(self.spc < 0)] = 0
686 self.spc[ numpy.where(self.spc < 0)] = 0
673
687
674 SPCmean = (numpy.mean(self.spc,0) - numpy.mean(dataOut.noise))
688 SPCmean = (numpy.mean(self.spc,0) - numpy.mean(dataOut.noise))
675 SPCmean[ numpy.where(SPCmean < 0)] = 0
689 SPCmean[ numpy.where(SPCmean < 0)] = 0
676
690
677 ETAn = numpy.zeros([self.Num_Bin,self.Num_Hei])
691 ETAn = numpy.zeros([self.Num_Bin,self.Num_Hei])
678 ETAv = numpy.zeros([self.Num_Bin,self.Num_Hei])
692 ETAv = numpy.zeros([self.Num_Bin,self.Num_Hei])
679 ETAd = numpy.zeros([self.Num_Bin,self.Num_Hei])
693 ETAd = numpy.zeros([self.Num_Bin,self.Num_Hei])
680
694
681 Pr = SPCmean[:,:]
695 Pr = SPCmean[:,:]
682
696
683 VelMeteoro = numpy.mean(SPCmean,axis=0)
697 VelMeteoro = numpy.mean(SPCmean,axis=0)
684
698
685 D_range = numpy.zeros([self.Num_Bin,self.Num_Hei])
699 D_range = numpy.zeros([self.Num_Bin,self.Num_Hei])
686 SIGMA = numpy.zeros([self.Num_Bin,self.Num_Hei])
700 SIGMA = numpy.zeros([self.Num_Bin,self.Num_Hei])
687 N_dist = numpy.zeros([self.Num_Bin,self.Num_Hei])
701 N_dist = numpy.zeros([self.Num_Bin,self.Num_Hei])
688 V_mean = numpy.zeros(self.Num_Hei)
702 V_mean = numpy.zeros(self.Num_Hei)
689 del_V = numpy.zeros(self.Num_Hei)
703 del_V = numpy.zeros(self.Num_Hei)
690 Z = numpy.zeros(self.Num_Hei)
704 Z = numpy.zeros(self.Num_Hei)
691 Ze = numpy.zeros(self.Num_Hei)
705 Ze = numpy.zeros(self.Num_Hei)
692 RR = numpy.zeros(self.Num_Hei)
706 RR = numpy.zeros(self.Num_Hei)
693
707
694 Range = dataOut.heightList*1000.
708 Range = dataOut.heightList*1000.
695
709
696 for R in range(self.Num_Hei):
710 for R in range(self.Num_Hei):
697
711
698 h = Range[R] + Altitude #Range from ground to radar pulse altitude
712 h = Range[R] + Altitude #Range from ground to radar pulse altitude
699 del_V[R] = 1 + 3.68 * 10**-5 * h + 1.71 * 10**-9 * h**2 #Density change correction for velocity
713 del_V[R] = 1 + 3.68 * 10**-5 * h + 1.71 * 10**-9 * h**2 #Density change correction for velocity
700
714
701 D_range[:,R] = numpy.log( (9.65 - (Velrange[0:self.Num_Bin] / del_V[R])) / 10.3 ) / -0.6 #Diameter range [m]x10**-3
715 D_range[:,R] = numpy.log( (9.65 - (Velrange[0:self.Num_Bin] / del_V[R])) / 10.3 ) / -0.6 #Diameter range [m]x10**-3
702
716
703 '''NOTA: ETA(n) dn = ETA(f) df
717 '''NOTA: ETA(n) dn = ETA(f) df
704
718
705 dn = 1 Diferencial de muestreo
719 dn = 1 Diferencial de muestreo
706 df = ETA(n) / ETA(f)
720 df = ETA(n) / ETA(f)
707
721
708 '''
722 '''
709
723
710 ETAn[:,R] = RadarConstant * Pr[:,R] * (Range[R] )**2 #Reflectivity (ETA)
724 ETAn[:,R] = RadarConstant * Pr[:,R] * (Range[R] )**2 #Reflectivity (ETA)
711
725
712 ETAv[:,R]=ETAn[:,R]/dV
726 ETAv[:,R]=ETAn[:,R]/dV
713
727
714 ETAd[:,R]=ETAv[:,R]*6.18*exp(-0.6*D_range[:,R])
728 ETAd[:,R]=ETAv[:,R]*6.18*exp(-0.6*D_range[:,R])
715
729
716 SIGMA[:,R] = Km * (D_range[:,R] * 1e-3 )**6 * numpy.pi**5 / Lambda**4 #Equivalent Section of drops (sigma)
730 SIGMA[:,R] = Km * (D_range[:,R] * 1e-3 )**6 * numpy.pi**5 / Lambda**4 #Equivalent Section of drops (sigma)
717
731
718 N_dist[:,R] = ETAn[:,R] / SIGMA[:,R]
732 N_dist[:,R] = ETAn[:,R] / SIGMA[:,R]
719
733
720 DMoments = self.Moments(Pr[:,R], Velrange[0:self.Num_Bin])
734 DMoments = self.Moments(Pr[:,R], Velrange[0:self.Num_Bin])
721
735
722 try:
736 try:
723 popt01,pcov = curve_fit(self.gaus, Velrange[0:self.Num_Bin] , Pr[:,R] , p0=DMoments)
737 popt01,pcov = curve_fit(self.gaus, Velrange[0:self.Num_Bin] , Pr[:,R] , p0=DMoments)
724 except:
738 except:
725 popt01=numpy.zeros(3)
739 popt01=numpy.zeros(3)
726 popt01[1]= DMoments[1]
740 popt01[1]= DMoments[1]
727
741
728 if popt01[1]<0 or popt01[1]>20:
742 if popt01[1]<0 or popt01[1]>20:
729 popt01[1]=numpy.NaN
743 popt01[1]=numpy.NaN
730
744
731
745
732 V_mean[R]=popt01[1]
746 V_mean[R]=popt01[1]
733
747
734 Z[R] = numpy.nansum( N_dist[:,R] * (D_range[:,R])**6 )#*10**-18
748 Z[R] = numpy.nansum( N_dist[:,R] * (D_range[:,R])**6 )#*10**-18
735
749
736 RR[R] = 0.0006*numpy.pi * numpy.nansum( D_range[:,R]**3 * N_dist[:,R] * Velrange[0:self.Num_Bin] ) #Rainfall rate
750 RR[R] = 0.0006*numpy.pi * numpy.nansum( D_range[:,R]**3 * N_dist[:,R] * Velrange[0:self.Num_Bin] ) #Rainfall rate
737
751
738 Ze[R] = (numpy.nansum( ETAn[:,R]) * Lambda**4) / ( 10**-18*numpy.pi**5 * Km)
752 Ze[R] = (numpy.nansum( ETAn[:,R]) * Lambda**4) / ( 10**-18*numpy.pi**5 * Km)
739
753
740
754
741
755
742 RR2 = (Z/200)**(1/1.6)
756 RR2 = (Z/200)**(1/1.6)
743 dBRR = 10*numpy.log10(RR)
757 dBRR = 10*numpy.log10(RR)
744 dBRR2 = 10*numpy.log10(RR2)
758 dBRR2 = 10*numpy.log10(RR2)
745
759
746 dBZe = 10*numpy.log10(Ze)
760 dBZe = 10*numpy.log10(Ze)
747 dBZ = 10*numpy.log10(Z)
761 dBZ = 10*numpy.log10(Z)
748
762
749 dataOut.data_output = RR[8]
763 dataOut.data_output = RR[8]
750 dataOut.data_param = numpy.ones([3,self.Num_Hei])
764 dataOut.data_param = numpy.ones([3,self.Num_Hei])
751 dataOut.channelList = [0,1,2]
765 dataOut.channelList = [0,1,2]
752
766
753 dataOut.data_param[0]=dBZ
767 dataOut.data_param[0]=dBZ
754 dataOut.data_param[1]=V_mean
768 dataOut.data_param[1]=V_mean
755 dataOut.data_param[2]=RR
769 dataOut.data_param[2]=RR
756
770
757 return dataOut
771 return dataOut
758
772
759 def dBZeMODE2(self, dataOut): # Processing for MIRA35C
773 def dBZeMODE2(self, dataOut): # Processing for MIRA35C
760
774
761 NPW = dataOut.NPW
775 NPW = dataOut.NPW
762 COFA = dataOut.COFA
776 COFA = dataOut.COFA
763
777
764 SNR = numpy.array([self.spc[0,:,:] / NPW[0]]) #, self.spc[1,:,:] / NPW[1]])
778 SNR = numpy.array([self.spc[0,:,:] / NPW[0]]) #, self.spc[1,:,:] / NPW[1]])
765 RadarConst = dataOut.RadarConst
779 RadarConst = dataOut.RadarConst
766 #frequency = 34.85*10**9
780 #frequency = 34.85*10**9
767
781
768 ETA = numpy.zeros(([self.Num_Chn ,self.Num_Hei]))
782 ETA = numpy.zeros(([self.Num_Chn ,self.Num_Hei]))
769 data_output = numpy.ones([self.Num_Chn , self.Num_Hei])*numpy.NaN
783 data_output = numpy.ones([self.Num_Chn , self.Num_Hei])*numpy.NaN
770
784
771 ETA = numpy.sum(SNR,1)
785 ETA = numpy.sum(SNR,1)
772
786
773 ETA = numpy.where(ETA is not 0. , ETA, numpy.NaN)
787 ETA = numpy.where(ETA is not 0. , ETA, numpy.NaN)
774
788
775 Ze = numpy.ones([self.Num_Chn, self.Num_Hei] )
789 Ze = numpy.ones([self.Num_Chn, self.Num_Hei] )
776
790
777 for r in range(self.Num_Hei):
791 for r in range(self.Num_Hei):
778
792
779 Ze[0,r] = ( ETA[0,r] ) * COFA[0,r][0] * RadarConst * ((r/5000.)**2)
793 Ze[0,r] = ( ETA[0,r] ) * COFA[0,r][0] * RadarConst * ((r/5000.)**2)
780 #Ze[1,r] = ( ETA[1,r] ) * COFA[1,r][0] * RadarConst * ((r/5000.)**2)
794 #Ze[1,r] = ( ETA[1,r] ) * COFA[1,r][0] * RadarConst * ((r/5000.)**2)
781
795
782 return Ze
796 return Ze
783
797
784 # def GetRadarConstant(self):
798 # def GetRadarConstant(self):
785 #
799 #
786 # """
800 # """
787 # Constants:
801 # Constants:
788 #
802 #
789 # Pt: Transmission Power dB 5kW 5000
803 # Pt: Transmission Power dB 5kW 5000
790 # Gt: Transmission Gain dB 24.7 dB 295.1209
804 # Gt: Transmission Gain dB 24.7 dB 295.1209
791 # Gr: Reception Gain dB 18.5 dB 70.7945
805 # Gr: Reception Gain dB 18.5 dB 70.7945
792 # Lambda: Wavelenght m 0.6741 m 0.6741
806 # Lambda: Wavelenght m 0.6741 m 0.6741
793 # aL: Attenuation loses dB 4dB 2.5118
807 # aL: Attenuation loses dB 4dB 2.5118
794 # tauW: Width of transmission pulse s 4us 4e-6
808 # tauW: Width of transmission pulse s 4us 4e-6
795 # ThetaT: Transmission antenna bean angle rad 0.1656317 rad 0.1656317
809 # ThetaT: Transmission antenna bean angle rad 0.1656317 rad 0.1656317
796 # ThetaR: Reception antenna beam angle rad 0.36774087 rad 0.36774087
810 # ThetaR: Reception antenna beam angle rad 0.36774087 rad 0.36774087
797 #
811 #
798 # """
812 # """
799 #
813 #
800 # Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
814 # Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
801 # Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * TauW * numpy.pi * ThetaT * TheraR)
815 # Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * TauW * numpy.pi * ThetaT * TheraR)
802 # RadarConstant = Numerator / Denominator
816 # RadarConstant = Numerator / Denominator
803 #
817 #
804 # return RadarConstant
818 # return RadarConstant
805
819
806
820
807
821
808 class FullSpectralAnalysis(Operation):
822 class FullSpectralAnalysis(Operation):
809
823
810 """
824 """
811 Function that implements Full Spectral Analysis technique.
825 Function that implements Full Spectral Analysis technique.
812
826
813 Input:
827 Input:
814 self.dataOut.data_pre : SelfSpectra and CrossSpectra data
828 self.dataOut.data_pre : SelfSpectra and CrossSpectra data
815 self.dataOut.groupList : Pairlist of channels
829 self.dataOut.groupList : Pairlist of channels
816 self.dataOut.ChanDist : Physical distance between receivers
830 self.dataOut.ChanDist : Physical distance between receivers
817
831
818
832
819 Output:
833 Output:
820
834
821 self.dataOut.data_output : Zonal wind, Meridional wind and Vertical wind
835 self.dataOut.data_output : Zonal wind, Meridional wind and Vertical wind
822
836
823
837
824 Parameters affected: Winds, height range, SNR
838 Parameters affected: Winds, height range, SNR
825
839
826 """
840 """
827 def run(self, dataOut, Xi01=None, Xi02=None, Xi12=None, Eta01=None, Eta02=None, Eta12=None, SNRlimit=7, minheight=None, maxheight=None):
841 def run(self, dataOut, Xi01=None, Xi02=None, Xi12=None, Eta01=None, Eta02=None, Eta12=None, SNRlimit=7, minheight=None, maxheight=None):
828
842
829 self.indice=int(numpy.random.rand()*1000)
843 self.indice=int(numpy.random.rand()*1000)
830
844
831 spc = dataOut.data_pre[0].copy()
845 spc = dataOut.data_pre[0].copy()
832 cspc = dataOut.data_pre[1]
846 cspc = dataOut.data_pre[1]
833
847
834 """Erick: NOTE THE RANGE OF THE PULSE TX MUST BE REMOVED"""
848 """Erick: NOTE THE RANGE OF THE PULSE TX MUST BE REMOVED"""
835
849
836 SNRspc = spc.copy()
850 SNRspc = spc.copy()
837 SNRspc[:,:,0:7]= numpy.NaN
851 SNRspc[:,:,0:7]= numpy.NaN
838
852
839 """##########################################"""
853 """##########################################"""
840
854
841
855
842 nChannel = spc.shape[0]
856 nChannel = spc.shape[0]
843 nProfiles = spc.shape[1]
857 nProfiles = spc.shape[1]
844 nHeights = spc.shape[2]
858 nHeights = spc.shape[2]
845
859
846 # first_height = 0.75 #km (ref: data header 20170822)
860 # first_height = 0.75 #km (ref: data header 20170822)
847 # resolution_height = 0.075 #km
861 # resolution_height = 0.075 #km
848 '''
862 '''
849 finding height range. check this when radar parameters are changed!
863 finding height range. check this when radar parameters are changed!
850 '''
864 '''
851 if maxheight is not None:
865 if maxheight is not None:
852 # range_max = math.ceil((maxheight - first_height) / resolution_height) # theoretical
866 # range_max = math.ceil((maxheight - first_height) / resolution_height) # theoretical
853 range_max = math.ceil(13.26 * maxheight - 3) # empirical, works better
867 range_max = math.ceil(13.26 * maxheight - 3) # empirical, works better
854 else:
868 else:
855 range_max = nHeights
869 range_max = nHeights
856 if minheight is not None:
870 if minheight is not None:
857 # range_min = int((minheight - first_height) / resolution_height) # theoretical
871 # range_min = int((minheight - first_height) / resolution_height) # theoretical
858 range_min = int(13.26 * minheight - 5) # empirical, works better
872 range_min = int(13.26 * minheight - 5) # empirical, works better
859 if range_min < 0:
873 if range_min < 0:
860 range_min = 0
874 range_min = 0
861 else:
875 else:
862 range_min = 0
876 range_min = 0
863
877
864 pairsList = dataOut.groupList
878 pairsList = dataOut.groupList
865 if dataOut.ChanDist is not None :
879 if dataOut.ChanDist is not None :
866 ChanDist = dataOut.ChanDist
880 ChanDist = dataOut.ChanDist
867 else:
881 else:
868 ChanDist = numpy.array([[Xi01, Eta01],[Xi02,Eta02],[Xi12,Eta12]])
882 ChanDist = numpy.array([[Xi01, Eta01],[Xi02,Eta02],[Xi12,Eta12]])
869
883
870 FrecRange = dataOut.spc_range[0]
884 FrecRange = dataOut.spc_range[0]
871
885
872 data_SNR=numpy.zeros([nProfiles])
886 data_SNR=numpy.zeros([nProfiles])
873 noise = dataOut.noise
887 noise = dataOut.noise
874
888
875 dataOut.data_SNR = (numpy.mean(SNRspc,axis=1)- noise[0]) / noise[0]
889 dataOut.data_SNR = (numpy.mean(SNRspc,axis=1)- noise[0]) / noise[0]
876
890
877 dataOut.data_SNR[numpy.where( dataOut.data_SNR <0 )] = 1e-20
891 dataOut.data_SNR[numpy.where( dataOut.data_SNR <0 )] = 1e-20
878
892
879
893
880 data_output=numpy.ones([spc.shape[0],spc.shape[2]])*numpy.NaN
894 data_output=numpy.ones([spc.shape[0],spc.shape[2]])*numpy.NaN
881
895
882 velocityX=[]
896 velocityX=[]
883 velocityY=[]
897 velocityY=[]
884 velocityV=[]
898 velocityV=[]
885
899
886 dbSNR = 10*numpy.log10(dataOut.data_SNR)
900 dbSNR = 10*numpy.log10(dataOut.data_SNR)
887 dbSNR = numpy.average(dbSNR,0)
901 dbSNR = numpy.average(dbSNR,0)
888
902
889 '''***********************************************WIND ESTIMATION**************************************'''
903 '''***********************************************WIND ESTIMATION**************************************'''
890
904
891 for Height in range(nHeights):
905 for Height in range(nHeights):
892
906
893 if Height >= range_min and Height < range_max:
907 if Height >= range_min and Height < range_max:
894 # error_code unused, yet maybe useful for future analysis.
908 # error_code unused, yet maybe useful for future analysis.
895 [Vzon,Vmer,Vver, error_code] = self.WindEstimation(spc[:,:,Height], cspc[:,:,Height], pairsList, ChanDist, Height, noise, dataOut.spc_range, dbSNR[Height], SNRlimit)
909 [Vzon,Vmer,Vver, error_code] = self.WindEstimation(spc[:,:,Height], cspc[:,:,Height], pairsList, ChanDist, Height, noise, dataOut.spc_range, dbSNR[Height], SNRlimit)
896 else:
910 else:
897 Vzon,Vmer,Vver = 0., 0., numpy.NaN
911 Vzon,Vmer,Vver = 0., 0., numpy.NaN
898
912
899
913
900 if abs(Vzon) < 100. and abs(Vzon) > 0. and abs(Vmer) < 100. and abs(Vmer) > 0.:
914 if abs(Vzon) < 100. and abs(Vzon) > 0. and abs(Vmer) < 100. and abs(Vmer) > 0.:
901 velocityX=numpy.append(velocityX, Vzon)
915 velocityX=numpy.append(velocityX, Vzon)
902 velocityY=numpy.append(velocityY, -Vmer)
916 velocityY=numpy.append(velocityY, -Vmer)
903
917
904 else:
918 else:
905 velocityX=numpy.append(velocityX, numpy.NaN)
919 velocityX=numpy.append(velocityX, numpy.NaN)
906 velocityY=numpy.append(velocityY, numpy.NaN)
920 velocityY=numpy.append(velocityY, numpy.NaN)
907
921
908 if dbSNR[Height] > SNRlimit:
922 if dbSNR[Height] > SNRlimit:
909 velocityV=numpy.append(velocityV, -Vver) # reason for this minus sign -> convention? (taken from Ericks version)
923 velocityV=numpy.append(velocityV, -Vver) # reason for this minus sign -> convention? (taken from Ericks version)
910 else:
924 else:
911 velocityV=numpy.append(velocityV, numpy.NaN)
925 velocityV=numpy.append(velocityV, numpy.NaN)
912
926
913
927
914 '''Change the numpy.array (velocityX) sign when trying to process BLTR data (Erick)'''
928 '''Change the numpy.array (velocityX) sign when trying to process BLTR data (Erick)'''
915 data_output[0] = numpy.array(velocityX)
929 data_output[0] = numpy.array(velocityX)
916 data_output[1] = numpy.array(velocityY)
930 data_output[1] = numpy.array(velocityY)
917 data_output[2] = velocityV
931 data_output[2] = velocityV
918
932
919
933
920 dataOut.data_output = data_output
934 dataOut.data_output = data_output
921
935
922 return dataOut
936 return dataOut
923
937
924
938
925 def moving_average(self,x, N=2):
939 def moving_average(self,x, N=2):
926 """ convolution for smoothenig data. note that last N-1 values are convolution with zeroes """
940 """ convolution for smoothenig data. note that last N-1 values are convolution with zeroes """
927 return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):]
941 return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):]
928
942
929 def gaus(self,xSamples,Amp,Mu,Sigma):
943 def gaus(self,xSamples,Amp,Mu,Sigma):
930 return ( Amp / ((2*numpy.pi)**0.5 * Sigma) ) * numpy.exp( -( xSamples - Mu )**2 / ( 2 * (Sigma**2) ))
944 return ( Amp / ((2*numpy.pi)**0.5 * Sigma) ) * numpy.exp( -( xSamples - Mu )**2 / ( 2 * (Sigma**2) ))
931
945
932 def Moments(self, ySamples, xSamples):
946 def Moments(self, ySamples, xSamples):
933 '''***
947 '''***
934 Variables corresponding to moments of distribution.
948 Variables corresponding to moments of distribution.
935 Also used as initial coefficients for curve_fit.
949 Also used as initial coefficients for curve_fit.
936 Vr was corrected. Only a velocity when x is velocity, of course.
950 Vr was corrected. Only a velocity when x is velocity, of course.
937 ***'''
951 ***'''
938 Pot = numpy.nansum( ySamples ) # Potencia, momento 0
952 Pot = numpy.nansum( ySamples ) # Potencia, momento 0
939 yNorm = ySamples / Pot
953 yNorm = ySamples / Pot
940 x_range = (numpy.max(xSamples)-numpy.min(xSamples))
954 x_range = (numpy.max(xSamples)-numpy.min(xSamples))
941 Vr = numpy.nansum( yNorm * xSamples )*x_range/len(xSamples) # Velocidad radial, mu, corrimiento doppler, primer momento
955 Vr = numpy.nansum( yNorm * xSamples )*x_range/len(xSamples) # Velocidad radial, mu, corrimiento doppler, primer momento
942 Sigma2 = abs(numpy.nansum( yNorm * ( xSamples - Vr )**2 )) # Segundo Momento
956 Sigma2 = abs(numpy.nansum( yNorm * ( xSamples - Vr )**2 )) # Segundo Momento
943 Desv = Sigma2**0.5 # Desv. Estandar, Ancho espectral
957 Desv = Sigma2**0.5 # Desv. Estandar, Ancho espectral
944
958
945 return numpy.array([Pot, Vr, Desv])
959 return numpy.array([Pot, Vr, Desv])
946
960
947 def StopWindEstimation(self, error_code):
961 def StopWindEstimation(self, error_code):
948 '''
962 '''
949 the wind calculation and returns zeros
963 the wind calculation and returns zeros
950 '''
964 '''
951 Vzon = 0
965 Vzon = 0
952 Vmer = 0
966 Vmer = 0
953 Vver = numpy.nan
967 Vver = numpy.nan
954 return Vzon, Vmer, Vver, error_code
968 return Vzon, Vmer, Vver, error_code
955
969
956 def AntiAliasing(self, interval, maxstep):
970 def AntiAliasing(self, interval, maxstep):
957 """
971 """
958 function to prevent errors from aliased values when computing phaseslope
972 function to prevent errors from aliased values when computing phaseslope
959 """
973 """
960 antialiased = numpy.zeros(len(interval))*0.0
974 antialiased = numpy.zeros(len(interval))*0.0
961 copyinterval = interval.copy()
975 copyinterval = interval.copy()
962
976
963 antialiased[0] = copyinterval[0]
977 antialiased[0] = copyinterval[0]
964
978
965 for i in range(1,len(antialiased)):
979 for i in range(1,len(antialiased)):
966
980
967 step = interval[i] - interval[i-1]
981 step = interval[i] - interval[i-1]
968
982
969 if step > maxstep:
983 if step > maxstep:
970 copyinterval -= 2*numpy.pi
984 copyinterval -= 2*numpy.pi
971 antialiased[i] = copyinterval[i]
985 antialiased[i] = copyinterval[i]
972
986
973 elif step < maxstep*(-1):
987 elif step < maxstep*(-1):
974 copyinterval += 2*numpy.pi
988 copyinterval += 2*numpy.pi
975 antialiased[i] = copyinterval[i]
989 antialiased[i] = copyinterval[i]
976
990
977 else:
991 else:
978 antialiased[i] = copyinterval[i].copy()
992 antialiased[i] = copyinterval[i].copy()
979
993
980 return antialiased
994 return antialiased
981
995
982 def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, AbbsisaRange, dbSNR, SNRlimit):
996 def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, AbbsisaRange, dbSNR, SNRlimit):
983 """
997 """
984 Function that Calculates Zonal, Meridional and Vertical wind velocities.
998 Function that Calculates Zonal, Meridional and Vertical wind velocities.
985 Initial Version by E. Bocanegra updated by J. Zibell until Nov. 2019.
999 Initial Version by E. Bocanegra updated by J. Zibell until Nov. 2019.
986
1000
987 Input:
1001 Input:
988 spc, cspc : self spectra and cross spectra data. In Briggs notation something like S_i*(S_i)_conj, (S_j)_conj respectively.
1002 spc, cspc : self spectra and cross spectra data. In Briggs notation something like S_i*(S_i)_conj, (S_j)_conj respectively.
989 pairsList : Pairlist of channels
1003 pairsList : Pairlist of channels
990 ChanDist : array of xi_ij and eta_ij
1004 ChanDist : array of xi_ij and eta_ij
991 Height : height at which data is processed
1005 Height : height at which data is processed
992 noise : noise in [channels] format for specific height
1006 noise : noise in [channels] format for specific height
993 Abbsisarange : range of the frequencies or velocities
1007 Abbsisarange : range of the frequencies or velocities
994 dbSNR, SNRlimit : signal to noise ratio in db, lower limit
1008 dbSNR, SNRlimit : signal to noise ratio in db, lower limit
995
1009
996 Output:
1010 Output:
997 Vzon, Vmer, Vver : wind velocities
1011 Vzon, Vmer, Vver : wind velocities
998 error_code : int that states where code is terminated
1012 error_code : int that states where code is terminated
999
1013
1000 0 : no error detected
1014 0 : no error detected
1001 1 : Gaussian of mean spc exceeds widthlimit
1015 1 : Gaussian of mean spc exceeds widthlimit
1002 2 : no Gaussian of mean spc found
1016 2 : no Gaussian of mean spc found
1003 3 : SNR to low or velocity to high -> prec. e.g.
1017 3 : SNR to low or velocity to high -> prec. e.g.
1004 4 : at least one Gaussian of cspc exceeds widthlimit
1018 4 : at least one Gaussian of cspc exceeds widthlimit
1005 5 : zero out of three cspc Gaussian fits converged
1019 5 : zero out of three cspc Gaussian fits converged
1006 6 : phase slope fit could not be found
1020 6 : phase slope fit could not be found
1007 7 : arrays used to fit phase have different length
1021 7 : arrays used to fit phase have different length
1008 8 : frequency range is either too short (len <= 5) or very long (> 30% of cspc)
1022 8 : frequency range is either too short (len <= 5) or very long (> 30% of cspc)
1009
1023
1010 """
1024 """
1011
1025
1012 error_code = 0
1026 error_code = 0
1013
1027
1014
1028
1015 SPC_Samples = numpy.ones([spc.shape[0],spc.shape[1]]) # for normalized spc values for one height
1029 SPC_Samples = numpy.ones([spc.shape[0],spc.shape[1]]) # for normalized spc values for one height
1016 phase = numpy.ones([spc.shape[0],spc.shape[1]]) # phase between channels
1030 phase = numpy.ones([spc.shape[0],spc.shape[1]]) # phase between channels
1017 CSPC_Samples = numpy.ones([spc.shape[0],spc.shape[1]],dtype=numpy.complex_) # for normalized cspc values
1031 CSPC_Samples = numpy.ones([spc.shape[0],spc.shape[1]],dtype=numpy.complex_) # for normalized cspc values
1018 PhaseSlope = numpy.zeros(spc.shape[0]) # slope of the phases, channelwise
1032 PhaseSlope = numpy.zeros(spc.shape[0]) # slope of the phases, channelwise
1019 PhaseInter = numpy.ones(spc.shape[0]) # intercept to the slope of the phases, channelwise
1033 PhaseInter = numpy.ones(spc.shape[0]) # intercept to the slope of the phases, channelwise
1020 xFrec = AbbsisaRange[0][0:spc.shape[1]] # frequency range
1034 xFrec = AbbsisaRange[0][0:spc.shape[1]] # frequency range
1021 xVel = AbbsisaRange[2][0:spc.shape[1]] # velocity range
1035 xVel = AbbsisaRange[2][0:spc.shape[1]] # velocity range
1022 SPCav = numpy.average(spc, axis=0)-numpy.average(noise) # spc[0]-noise[0]
1036 SPCav = numpy.average(spc, axis=0)-numpy.average(noise) # spc[0]-noise[0]
1023
1037
1024 SPCmoments_vel = self.Moments(SPCav, xVel ) # SPCmoments_vel[1] corresponds to vertical velocity and is used to determine if signal corresponds to wind (if .. <3)
1038 SPCmoments_vel = self.Moments(SPCav, xVel ) # SPCmoments_vel[1] corresponds to vertical velocity and is used to determine if signal corresponds to wind (if .. <3)
1025 CSPCmoments = []
1039 CSPCmoments = []
1026
1040
1027
1041
1028 '''Getting Eij and Nij'''
1042 '''Getting Eij and Nij'''
1029
1043
1030 Xi01, Xi02, Xi12 = ChanDist[:,0]
1044 Xi01, Xi02, Xi12 = ChanDist[:,0]
1031 Eta01, Eta02, Eta12 = ChanDist[:,1]
1045 Eta01, Eta02, Eta12 = ChanDist[:,1]
1032
1046
1033 # update nov 19
1047 # update nov 19
1034 widthlimit = 7 # maximum width in Hz of the gaussian, empirically determined. Anything above 10 is unrealistic, often values between 1 and 5 correspond to proper fits.
1048 widthlimit = 7 # maximum width in Hz of the gaussian, empirically determined. Anything above 10 is unrealistic, often values between 1 and 5 correspond to proper fits.
1035
1049
1036 '''************************* SPC is normalized ********************************'''
1050 '''************************* SPC is normalized ********************************'''
1037
1051
1038 spc_norm = spc.copy() # need copy() because untouched spc is needed for normalization of cspc below
1052 spc_norm = spc.copy() # need copy() because untouched spc is needed for normalization of cspc below
1039 spc_norm = numpy.where(numpy.isfinite(spc_norm), spc_norm, numpy.NAN)
1053 spc_norm = numpy.where(numpy.isfinite(spc_norm), spc_norm, numpy.NAN)
1040
1054
1041 for i in range(spc.shape[0]):
1055 for i in range(spc.shape[0]):
1042
1056
1043 spc_sub = spc_norm[i,:] - noise[i] # spc not smoothed here or in previous version.
1057 spc_sub = spc_norm[i,:] - noise[i] # spc not smoothed here or in previous version.
1044
1058
1045 Factor_Norm = 2*numpy.max(xFrec) / numpy.count_nonzero(~numpy.isnan(spc_sub)) # usually = Freq range / nfft
1059 Factor_Norm = 2*numpy.max(xFrec) / numpy.count_nonzero(~numpy.isnan(spc_sub)) # usually = Freq range / nfft
1046 normalized_spc = spc_sub / (numpy.nansum(numpy.abs(spc_sub)) * Factor_Norm)
1060 normalized_spc = spc_sub / (numpy.nansum(numpy.abs(spc_sub)) * Factor_Norm)
1047
1061
1048 xSamples = xFrec # the frequency range is taken
1062 xSamples = xFrec # the frequency range is taken
1049 SPC_Samples[i] = normalized_spc # Normalized SPC values are taken
1063 SPC_Samples[i] = normalized_spc # Normalized SPC values are taken
1050
1064
1051 '''********************** FITTING MEAN SPC GAUSSIAN **********************'''
1065 '''********************** FITTING MEAN SPC GAUSSIAN **********************'''
1052
1066
1053 """ the gaussian of the mean: first subtract noise, then normalize. this is legal because
1067 """ the gaussian of the mean: first subtract noise, then normalize. this is legal because
1054 you only fit the curve and don't need the absolute value of height for calculation,
1068 you only fit the curve and don't need the absolute value of height for calculation,
1055 only for estimation of width. for normalization of cross spectra, you need initial,
1069 only for estimation of width. for normalization of cross spectra, you need initial,
1056 unnormalized self-spectra With noise.
1070 unnormalized self-spectra With noise.
1057
1071
1058 Technically, you don't even need to normalize the self-spectra, as you only need the
1072 Technically, you don't even need to normalize the self-spectra, as you only need the
1059 width of the peak. However, it was left this way. Note that the normalization has a flaw:
1073 width of the peak. However, it was left this way. Note that the normalization has a flaw:
1060 due to subtraction of the noise, some values are below zero. Raw "spc" values should be
1074 due to subtraction of the noise, some values are below zero. Raw "spc" values should be
1061 >= 0, as it is the modulus squared of the signals (complex * it's conjugate)
1075 >= 0, as it is the modulus squared of the signals (complex * it's conjugate)
1062 """
1076 """
1063
1077
1064 SPCMean = numpy.average(SPC_Samples, axis=0)
1078 SPCMean = numpy.average(SPC_Samples, axis=0)
1065
1079
1066 popt = [1e-10,0,1e-10]
1080 popt = [1e-10,0,1e-10]
1067 SPCMoments = self.Moments(SPCMean, xSamples)
1081 SPCMoments = self.Moments(SPCMean, xSamples)
1068
1082
1069 if dbSNR > SNRlimit and numpy.abs(SPCmoments_vel[1]) < 3:
1083 if dbSNR > SNRlimit and numpy.abs(SPCmoments_vel[1]) < 3:
1070 try:
1084 try:
1071 popt,pcov = curve_fit(self.gaus,xSamples,SPCMean,p0=SPCMoments)#, bounds=(-numpy.inf, [numpy.inf, numpy.inf, 10])). Setting bounds does not make the code faster but only keeps the fit from finding the minimum.
1085 popt,pcov = curve_fit(self.gaus,xSamples,SPCMean,p0=SPCMoments)#, bounds=(-numpy.inf, [numpy.inf, numpy.inf, 10])). Setting bounds does not make the code faster but only keeps the fit from finding the minimum.
1072 if popt[2] > widthlimit: # CONDITION
1086 if popt[2] > widthlimit: # CONDITION
1073 return self.StopWindEstimation(error_code = 1)
1087 return self.StopWindEstimation(error_code = 1)
1074
1088
1075 FitGauss = self.gaus(xSamples,*popt)
1089 FitGauss = self.gaus(xSamples,*popt)
1076
1090
1077 except :#RuntimeError:
1091 except :#RuntimeError:
1078 return self.StopWindEstimation(error_code = 2)
1092 return self.StopWindEstimation(error_code = 2)
1079
1093
1080 else:
1094 else:
1081 return self.StopWindEstimation(error_code = 3)
1095 return self.StopWindEstimation(error_code = 3)
1082
1096
1083
1097
1084
1098
1085 '''***************************** CSPC Normalization *************************
1099 '''***************************** CSPC Normalization *************************
1086 new section:
1100 new section:
1087 The Spc spectra are used to normalize the crossspectra. Peaks from precipitation
1101 The Spc spectra are used to normalize the crossspectra. Peaks from precipitation
1088 influence the norm which is not desired. First, a range is identified where the
1102 influence the norm which is not desired. First, a range is identified where the
1089 wind peak is estimated -> sum_wind is sum of those frequencies. Next, the area
1103 wind peak is estimated -> sum_wind is sum of those frequencies. Next, the area
1090 around it gets cut off and values replaced by mean determined by the boundary
1104 around it gets cut off and values replaced by mean determined by the boundary
1091 data -> sum_noise (spc is not normalized here, thats why the noise is important)
1105 data -> sum_noise (spc is not normalized here, thats why the noise is important)
1092
1106
1093 The sums are then added and multiplied by range/datapoints, because you need
1107 The sums are then added and multiplied by range/datapoints, because you need
1094 an integral and not a sum for normalization.
1108 an integral and not a sum for normalization.
1095
1109
1096 A norm is found according to Briggs 92.
1110 A norm is found according to Briggs 92.
1097 '''
1111 '''
1098
1112
1099 radarWavelength = 0.6741 # meters
1113 radarWavelength = 0.6741 # meters
1100 count_limit_freq = numpy.abs(popt[1]) + widthlimit # Hz, m/s can be also used if velocity is desired abscissa.
1114 count_limit_freq = numpy.abs(popt[1]) + widthlimit # Hz, m/s can be also used if velocity is desired abscissa.
1101 # count_limit_freq = numpy.max(xFrec)
1115 # count_limit_freq = numpy.max(xFrec)
1102
1116
1103 channel_integrals = numpy.zeros(3)
1117 channel_integrals = numpy.zeros(3)
1104
1118
1105 for i in range(spc.shape[0]):
1119 for i in range(spc.shape[0]):
1106 '''
1120 '''
1107 find the point in array corresponding to count_limit frequency.
1121 find the point in array corresponding to count_limit frequency.
1108 sum over all frequencies in the range around zero Hz @ math.ceil(N_freq/2)
1122 sum over all frequencies in the range around zero Hz @ math.ceil(N_freq/2)
1109 '''
1123 '''
1110 N_freq = numpy.count_nonzero(~numpy.isnan(spc[i,:]))
1124 N_freq = numpy.count_nonzero(~numpy.isnan(spc[i,:]))
1111 count_limit_int = int(math.ceil( count_limit_freq / numpy.max(xFrec) * (N_freq / 2) )) # gives integer point
1125 count_limit_int = int(math.ceil( count_limit_freq / numpy.max(xFrec) * (N_freq / 2) )) # gives integer point
1112 sum_wind = numpy.nansum( spc[i, (math.ceil(N_freq/2) - count_limit_int) : (math.ceil(N_freq / 2) + count_limit_int)] ) #N_freq/2 is where frequency (velocity) is zero, i.e. middle of spectrum.
1126 sum_wind = numpy.nansum( spc[i, (math.ceil(N_freq/2) - count_limit_int) : (math.ceil(N_freq / 2) + count_limit_int)] ) #N_freq/2 is where frequency (velocity) is zero, i.e. middle of spectrum.
1113 sum_noise = (numpy.mean(spc[i, :4]) + numpy.mean(spc[i, -6:-2]))/2.0 * (N_freq - 2*count_limit_int)
1127 sum_noise = (numpy.mean(spc[i, :4]) + numpy.mean(spc[i, -6:-2]))/2.0 * (N_freq - 2*count_limit_int)
1114 channel_integrals[i] = (sum_noise + sum_wind) * (2*numpy.max(xFrec) / N_freq)
1128 channel_integrals[i] = (sum_noise + sum_wind) * (2*numpy.max(xFrec) / N_freq)
1115
1129
1116
1130
1117 cross_integrals_peak = numpy.zeros(3)
1131 cross_integrals_peak = numpy.zeros(3)
1118 # cross_integrals_totalrange = numpy.zeros(3)
1132 # cross_integrals_totalrange = numpy.zeros(3)
1119
1133
1120 for i in range(spc.shape[0]):
1134 for i in range(spc.shape[0]):
1121
1135
1122 cspc_norm = cspc[i,:].copy() # cspc not smoothed here or in previous version
1136 cspc_norm = cspc[i,:].copy() # cspc not smoothed here or in previous version
1123
1137
1124 chan_index0 = pairsList[i][0]
1138 chan_index0 = pairsList[i][0]
1125 chan_index1 = pairsList[i][1]
1139 chan_index1 = pairsList[i][1]
1126
1140
1127 cross_integrals_peak[i] = channel_integrals[chan_index0]*channel_integrals[chan_index1]
1141 cross_integrals_peak[i] = channel_integrals[chan_index0]*channel_integrals[chan_index1]
1128 normalized_cspc = cspc_norm / numpy.sqrt(cross_integrals_peak[i])
1142 normalized_cspc = cspc_norm / numpy.sqrt(cross_integrals_peak[i])
1129 CSPC_Samples[i] = normalized_cspc
1143 CSPC_Samples[i] = normalized_cspc
1130
1144
1131 ''' Finding cross integrals without subtracting any peaks:'''
1145 ''' Finding cross integrals without subtracting any peaks:'''
1132 # FactorNorm0 = 2*numpy.max(xFrec) / numpy.count_nonzero(~numpy.isnan(spc[chan_index0,:]))
1146 # FactorNorm0 = 2*numpy.max(xFrec) / numpy.count_nonzero(~numpy.isnan(spc[chan_index0,:]))
1133 # FactorNorm1 = 2*numpy.max(xFrec) / numpy.count_nonzero(~numpy.isnan(spc[chan_index1,:]))
1147 # FactorNorm1 = 2*numpy.max(xFrec) / numpy.count_nonzero(~numpy.isnan(spc[chan_index1,:]))
1134 # cross_integrals_totalrange[i] = (numpy.nansum(spc[chan_index0,:])) * FactorNorm0 * (numpy.nansum(spc[chan_index1,:])) * FactorNorm1
1148 # cross_integrals_totalrange[i] = (numpy.nansum(spc[chan_index0,:])) * FactorNorm0 * (numpy.nansum(spc[chan_index1,:])) * FactorNorm1
1135 # normalized_cspc = cspc_norm / numpy.sqrt(cross_integrals_totalrange[i])
1149 # normalized_cspc = cspc_norm / numpy.sqrt(cross_integrals_totalrange[i])
1136 # CSPC_Samples[i] = normalized_cspc
1150 # CSPC_Samples[i] = normalized_cspc
1137
1151
1138
1152
1139 phase[i] = numpy.arctan2(CSPC_Samples[i].imag, CSPC_Samples[i].real)
1153 phase[i] = numpy.arctan2(CSPC_Samples[i].imag, CSPC_Samples[i].real)
1140
1154
1141
1155
1142 CSPCmoments = numpy.vstack([self.Moments(numpy.abs(CSPC_Samples[0]), xSamples),
1156 CSPCmoments = numpy.vstack([self.Moments(numpy.abs(CSPC_Samples[0]), xSamples),
1143 self.Moments(numpy.abs(CSPC_Samples[1]), xSamples),
1157 self.Moments(numpy.abs(CSPC_Samples[1]), xSamples),
1144 self.Moments(numpy.abs(CSPC_Samples[2]), xSamples)])
1158 self.Moments(numpy.abs(CSPC_Samples[2]), xSamples)])
1145
1159
1146
1160
1147 '''***Sorting out NaN entries***'''
1161 '''***Sorting out NaN entries***'''
1148 CSPCMask01 = numpy.abs(CSPC_Samples[0])
1162 CSPCMask01 = numpy.abs(CSPC_Samples[0])
1149 CSPCMask02 = numpy.abs(CSPC_Samples[1])
1163 CSPCMask02 = numpy.abs(CSPC_Samples[1])
1150 CSPCMask12 = numpy.abs(CSPC_Samples[2])
1164 CSPCMask12 = numpy.abs(CSPC_Samples[2])
1151
1165
1152 mask01 = ~numpy.isnan(CSPCMask01)
1166 mask01 = ~numpy.isnan(CSPCMask01)
1153 mask02 = ~numpy.isnan(CSPCMask02)
1167 mask02 = ~numpy.isnan(CSPCMask02)
1154 mask12 = ~numpy.isnan(CSPCMask12)
1168 mask12 = ~numpy.isnan(CSPCMask12)
1155
1169
1156 CSPCMask01 = CSPCMask01[mask01]
1170 CSPCMask01 = CSPCMask01[mask01]
1157 CSPCMask02 = CSPCMask02[mask02]
1171 CSPCMask02 = CSPCMask02[mask02]
1158 CSPCMask12 = CSPCMask12[mask12]
1172 CSPCMask12 = CSPCMask12[mask12]
1159
1173
1160
1174
1161 popt01, popt02, popt12 = [1e-10,1e-10,1e-10], [1e-10,1e-10,1e-10] ,[1e-10,1e-10,1e-10]
1175 popt01, popt02, popt12 = [1e-10,1e-10,1e-10], [1e-10,1e-10,1e-10] ,[1e-10,1e-10,1e-10]
1162 FitGauss01, FitGauss02, FitGauss12 = numpy.empty(len(xSamples))*0, numpy.empty(len(xSamples))*0, numpy.empty(len(xSamples))*0
1176 FitGauss01, FitGauss02, FitGauss12 = numpy.empty(len(xSamples))*0, numpy.empty(len(xSamples))*0, numpy.empty(len(xSamples))*0
1163
1177
1164 '''*******************************FIT GAUSS CSPC************************************'''
1178 '''*******************************FIT GAUSS CSPC************************************'''
1165
1179
1166 try:
1180 try:
1167 popt01,pcov = curve_fit(self.gaus,xSamples[mask01],numpy.abs(CSPCMask01),p0=CSPCmoments[0])
1181 popt01,pcov = curve_fit(self.gaus,xSamples[mask01],numpy.abs(CSPCMask01),p0=CSPCmoments[0])
1168 if popt01[2] > widthlimit: # CONDITION
1182 if popt01[2] > widthlimit: # CONDITION
1169 return self.StopWindEstimation(error_code = 4)
1183 return self.StopWindEstimation(error_code = 4)
1170
1184
1171 popt02,pcov = curve_fit(self.gaus,xSamples[mask02],numpy.abs(CSPCMask02),p0=CSPCmoments[1])
1185 popt02,pcov = curve_fit(self.gaus,xSamples[mask02],numpy.abs(CSPCMask02),p0=CSPCmoments[1])
1172 if popt02[2] > widthlimit: # CONDITION
1186 if popt02[2] > widthlimit: # CONDITION
1173 return self.StopWindEstimation(error_code = 4)
1187 return self.StopWindEstimation(error_code = 4)
1174
1188
1175 popt12,pcov = curve_fit(self.gaus,xSamples[mask12],numpy.abs(CSPCMask12),p0=CSPCmoments[2])
1189 popt12,pcov = curve_fit(self.gaus,xSamples[mask12],numpy.abs(CSPCMask12),p0=CSPCmoments[2])
1176 if popt12[2] > widthlimit: # CONDITION
1190 if popt12[2] > widthlimit: # CONDITION
1177 return self.StopWindEstimation(error_code = 4)
1191 return self.StopWindEstimation(error_code = 4)
1178
1192
1179 FitGauss01 = self.gaus(xSamples, *popt01)
1193 FitGauss01 = self.gaus(xSamples, *popt01)
1180 FitGauss02 = self.gaus(xSamples, *popt02)
1194 FitGauss02 = self.gaus(xSamples, *popt02)
1181 FitGauss12 = self.gaus(xSamples, *popt12)
1195 FitGauss12 = self.gaus(xSamples, *popt12)
1182
1196
1183 except:
1197 except:
1184 return self.StopWindEstimation(error_code = 5)
1198 return self.StopWindEstimation(error_code = 5)
1185
1199
1186
1200
1187 '''************* Getting Fij ***************'''
1201 '''************* Getting Fij ***************'''
1188
1202
1189
1203
1190 #Punto en Eje X de la Gaussiana donde se encuentra el centro -- x-axis point of the gaussian where the center is located
1204 #Punto en Eje X de la Gaussiana donde se encuentra el centro -- x-axis point of the gaussian where the center is located
1191 # -> PointGauCenter
1205 # -> PointGauCenter
1192 GaussCenter = popt[1]
1206 GaussCenter = popt[1]
1193 ClosestCenter = xSamples[numpy.abs(xSamples-GaussCenter).argmin()]
1207 ClosestCenter = xSamples[numpy.abs(xSamples-GaussCenter).argmin()]
1194 PointGauCenter = numpy.where(xSamples==ClosestCenter)[0][0]
1208 PointGauCenter = numpy.where(xSamples==ClosestCenter)[0][0]
1195
1209
1196 #Punto e^-1 hubicado en la Gaussiana -- point where e^-1 is located in the gaussian
1210 #Punto e^-1 hubicado en la Gaussiana -- point where e^-1 is located in the gaussian
1197 PeMinus1 = numpy.max(FitGauss) * numpy.exp(-1)
1211 PeMinus1 = numpy.max(FitGauss) * numpy.exp(-1)
1198 FijClosest = FitGauss[numpy.abs(FitGauss-PeMinus1).argmin()] # El punto mas cercano a "Peminus1" dentro de "FitGauss"
1212 FijClosest = FitGauss[numpy.abs(FitGauss-PeMinus1).argmin()] # El punto mas cercano a "Peminus1" dentro de "FitGauss"
1199 PointFij = numpy.where(FitGauss==FijClosest)[0][0]
1213 PointFij = numpy.where(FitGauss==FijClosest)[0][0]
1200
1214
1201 Fij = numpy.abs(xSamples[PointFij] - xSamples[PointGauCenter])
1215 Fij = numpy.abs(xSamples[PointFij] - xSamples[PointGauCenter])
1202
1216
1203 '''********** Taking frequency ranges from mean SPCs **********'''
1217 '''********** Taking frequency ranges from mean SPCs **********'''
1204
1218
1205 #GaussCenter = popt[1] #Primer momento 01
1219 #GaussCenter = popt[1] #Primer momento 01
1206 GauWidth = popt[2] * 3/2 #Ancho de banda de Gau01 -- Bandwidth of Gau01 TODO why *3/2?
1220 GauWidth = popt[2] * 3/2 #Ancho de banda de Gau01 -- Bandwidth of Gau01 TODO why *3/2?
1207 Range = numpy.empty(2)
1221 Range = numpy.empty(2)
1208 Range[0] = GaussCenter - GauWidth
1222 Range[0] = GaussCenter - GauWidth
1209 Range[1] = GaussCenter + GauWidth
1223 Range[1] = GaussCenter + GauWidth
1210 #Punto en Eje X de la Gaussiana donde se encuentra ancho de banda (min:max) -- Point in x-axis where the bandwidth is located (min:max)
1224 #Punto en Eje X de la Gaussiana donde se encuentra ancho de banda (min:max) -- Point in x-axis where the bandwidth is located (min:max)
1211 ClosRangeMin = xSamples[numpy.abs(xSamples-Range[0]).argmin()]
1225 ClosRangeMin = xSamples[numpy.abs(xSamples-Range[0]).argmin()]
1212 ClosRangeMax = xSamples[numpy.abs(xSamples-Range[1]).argmin()]
1226 ClosRangeMax = xSamples[numpy.abs(xSamples-Range[1]).argmin()]
1213
1227
1214 PointRangeMin = numpy.where(xSamples==ClosRangeMin)[0][0]
1228 PointRangeMin = numpy.where(xSamples==ClosRangeMin)[0][0]
1215 PointRangeMax = numpy.where(xSamples==ClosRangeMax)[0][0]
1229 PointRangeMax = numpy.where(xSamples==ClosRangeMax)[0][0]
1216
1230
1217 Range = numpy.array([ PointRangeMin, PointRangeMax ])
1231 Range = numpy.array([ PointRangeMin, PointRangeMax ])
1218
1232
1219 FrecRange = xFrec[ Range[0] : Range[1] ]
1233 FrecRange = xFrec[ Range[0] : Range[1] ]
1220
1234
1221
1235
1222 '''************************** Getting Phase Slope ***************************'''
1236 '''************************** Getting Phase Slope ***************************'''
1223
1237
1224 for i in range(1,3): # Changed to only compute two
1238 for i in range(1,3): # Changed to only compute two
1225
1239
1226 if len(FrecRange) > 5 and len(FrecRange) < spc.shape[1] * 0.3:
1240 if len(FrecRange) > 5 and len(FrecRange) < spc.shape[1] * 0.3:
1227 # PhaseRange=self.moving_average(phase[i,Range[0]:Range[1]],N=1) #used before to smooth phase with N=3
1241 # PhaseRange=self.moving_average(phase[i,Range[0]:Range[1]],N=1) #used before to smooth phase with N=3
1228 PhaseRange = phase[i,Range[0]:Range[1]].copy()
1242 PhaseRange = phase[i,Range[0]:Range[1]].copy()
1229
1243
1230 mask = ~numpy.isnan(FrecRange) & ~numpy.isnan(PhaseRange)
1244 mask = ~numpy.isnan(FrecRange) & ~numpy.isnan(PhaseRange)
1231
1245
1232
1246
1233 if len(FrecRange) == len(PhaseRange):
1247 if len(FrecRange) == len(PhaseRange):
1234
1248
1235 try:
1249 try:
1236 slope, intercept, _, _, _ = stats.linregress(FrecRange[mask], self.AntiAliasing(PhaseRange[mask], 4.5))
1250 slope, intercept, _, _, _ = stats.linregress(FrecRange[mask], self.AntiAliasing(PhaseRange[mask], 4.5))
1237 PhaseSlope[i] = slope
1251 PhaseSlope[i] = slope
1238 PhaseInter[i] = intercept
1252 PhaseInter[i] = intercept
1239
1253
1240 except:
1254 except:
1241 return self.StopWindEstimation(error_code = 6)
1255 return self.StopWindEstimation(error_code = 6)
1242
1256
1243 else:
1257 else:
1244 return self.StopWindEstimation(error_code = 7)
1258 return self.StopWindEstimation(error_code = 7)
1245
1259
1246 else:
1260 else:
1247 return self.StopWindEstimation(error_code = 8)
1261 return self.StopWindEstimation(error_code = 8)
1248
1262
1249
1263
1250
1264
1251 '''*** Constants A-H correspond to the convention as in Briggs and Vincent 1992 ***'''
1265 '''*** Constants A-H correspond to the convention as in Briggs and Vincent 1992 ***'''
1252
1266
1253 '''Getting constant C'''
1267 '''Getting constant C'''
1254 cC=(Fij*numpy.pi)**2
1268 cC=(Fij*numpy.pi)**2
1255
1269
1256 '''****** Getting constants F and G ******'''
1270 '''****** Getting constants F and G ******'''
1257 MijEijNij = numpy.array([[Xi02,Eta02], [Xi12,Eta12]])
1271 MijEijNij = numpy.array([[Xi02,Eta02], [Xi12,Eta12]])
1258 MijResult0 = (-PhaseSlope[1] * cC) / (2*numpy.pi)
1272 MijResult0 = (-PhaseSlope[1] * cC) / (2*numpy.pi)
1259 MijResult1 = (-PhaseSlope[2] * cC) / (2*numpy.pi)
1273 MijResult1 = (-PhaseSlope[2] * cC) / (2*numpy.pi)
1260 MijResults = numpy.array([MijResult0,MijResult1])
1274 MijResults = numpy.array([MijResult0,MijResult1])
1261 (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults)
1275 (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults)
1262
1276
1263 '''****** Getting constants A, B and H ******'''
1277 '''****** Getting constants A, B and H ******'''
1264 W01 = numpy.nanmax( FitGauss01 )
1278 W01 = numpy.nanmax( FitGauss01 )
1265 W02 = numpy.nanmax( FitGauss02 )
1279 W02 = numpy.nanmax( FitGauss02 )
1266 W12 = numpy.nanmax( FitGauss12 )
1280 W12 = numpy.nanmax( FitGauss12 )
1267
1281
1268 WijResult0 = ((cF * Xi01 + cG * Eta01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi / cC))
1282 WijResult0 = ((cF * Xi01 + cG * Eta01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi / cC))
1269 WijResult1 = ((cF * Xi02 + cG * Eta02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi / cC))
1283 WijResult1 = ((cF * Xi02 + cG * Eta02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi / cC))
1270 WijResult2 = ((cF * Xi12 + cG * Eta12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi / cC))
1284 WijResult2 = ((cF * Xi12 + cG * Eta12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi / cC))
1271
1285
1272 WijResults = numpy.array([WijResult0, WijResult1, WijResult2])
1286 WijResults = numpy.array([WijResult0, WijResult1, WijResult2])
1273
1287
1274 WijEijNij = numpy.array([ [Xi01**2, Eta01**2, 2*Xi01*Eta01] , [Xi02**2, Eta02**2, 2*Xi02*Eta02] , [Xi12**2, Eta12**2, 2*Xi12*Eta12] ])
1288 WijEijNij = numpy.array([ [Xi01**2, Eta01**2, 2*Xi01*Eta01] , [Xi02**2, Eta02**2, 2*Xi02*Eta02] , [Xi12**2, Eta12**2, 2*Xi12*Eta12] ])
1275 (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults)
1289 (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults)
1276
1290
1277 VxVy = numpy.array([[cA,cH],[cH,cB]])
1291 VxVy = numpy.array([[cA,cH],[cH,cB]])
1278 VxVyResults = numpy.array([-cF,-cG])
1292 VxVyResults = numpy.array([-cF,-cG])
1279 (Vx,Vy) = numpy.linalg.solve(VxVy, VxVyResults)
1293 (Vx,Vy) = numpy.linalg.solve(VxVy, VxVyResults)
1280
1294
1281 Vzon = Vy
1295 Vzon = Vy
1282 Vmer = Vx
1296 Vmer = Vx
1283
1297
1284 # Vmag=numpy.sqrt(Vzon**2+Vmer**2) # unused
1298 # Vmag=numpy.sqrt(Vzon**2+Vmer**2) # unused
1285 # Vang=numpy.arctan2(Vmer,Vzon) # unused
1299 # Vang=numpy.arctan2(Vmer,Vzon) # unused
1286
1300
1287
1301
1288 ''' using frequency as abscissa. Due to three channels, the offzenith angle is zero
1302 ''' using frequency as abscissa. Due to three channels, the offzenith angle is zero
1289 and Vrad equal to Vver. formula taken from Briggs 92, figure 4.
1303 and Vrad equal to Vver. formula taken from Briggs 92, figure 4.
1290 '''
1304 '''
1291 if numpy.abs( popt[1] ) < 3.5 and len(FrecRange) > 4:
1305 if numpy.abs( popt[1] ) < 3.5 and len(FrecRange) > 4:
1292 Vver = 0.5 * radarWavelength * popt[1] * 100 # *100 to get cm (/s)
1306 Vver = 0.5 * radarWavelength * popt[1] * 100 # *100 to get cm (/s)
1293 else:
1307 else:
1294 Vver = numpy.NaN
1308 Vver = numpy.NaN
1295
1309
1296 error_code = 0
1310 error_code = 0
1297
1311
1298 return Vzon, Vmer, Vver, error_code
1312 return Vzon, Vmer, Vver, error_code
1299
1313
1300
1314
1301 class SpectralMoments(Operation):
1315 class SpectralMoments(Operation):
1302
1316
1303 '''
1317 '''
1304 Function SpectralMoments()
1318 Function SpectralMoments()
1305
1319
1306 Calculates moments (power, mean, standard deviation) and SNR of the signal
1320 Calculates moments (power, mean, standard deviation) and SNR of the signal
1307
1321
1308 Type of dataIn: Spectra
1322 Type of dataIn: Spectra
1309
1323
1310 Configuration Parameters:
1324 Configuration Parameters:
1311
1325
1312 dirCosx : Cosine director in X axis
1326 dirCosx : Cosine director in X axis
1313 dirCosy : Cosine director in Y axis
1327 dirCosy : Cosine director in Y axis
1314
1328
1315 elevation :
1329 elevation :
1316 azimuth :
1330 azimuth :
1317
1331
1318 Input:
1332 Input:
1319 channelList : simple channel list to select e.g. [2,3,7]
1333 channelList : simple channel list to select e.g. [2,3,7]
1320 self.dataOut.data_pre : Spectral data
1334 self.dataOut.data_pre : Spectral data
1321 self.dataOut.abscissaList : List of frequencies
1335 self.dataOut.abscissaList : List of frequencies
1322 self.dataOut.noise : Noise level per channel
1336 self.dataOut.noise : Noise level per channel
1323
1337
1324 Affected:
1338 Affected:
1325 self.dataOut.moments : Parameters per channel
1339 self.dataOut.moments : Parameters per channel
1326 self.dataOut.data_SNR : SNR per channel
1340 self.dataOut.data_SNR : SNR per channel
1327
1341
1328 '''
1342 '''
1329
1343
1330 def run(self, dataOut):
1344 def run(self, dataOut):
1331
1345
1332 data = dataOut.data_pre[0]
1346 data = dataOut.data_pre[0]
1333 absc = dataOut.abscissaList[:-1]
1347 absc = dataOut.abscissaList[:-1]
1334 noise = dataOut.noise
1348 noise = dataOut.noise
1335 nChannel = data.shape[0]
1349 nChannel = data.shape[0]
1336 data_param = numpy.zeros((nChannel, 4, data.shape[2]))
1350 data_param = numpy.zeros((nChannel, 4, data.shape[2]))
1337
1351
1338 for ind in range(nChannel):
1352 for ind in range(nChannel):
1339 data_param[ind,:,:] = self.__calculateMoments( data[ind,:,:] , absc , noise[ind] )
1353 data_param[ind,:,:] = self.__calculateMoments( data[ind,:,:] , absc , noise[ind] )
1340
1354
1341 dataOut.moments = data_param[:,1:,:]
1355 dataOut.moments = data_param[:,1:,:]
1342 dataOut.data_SNR = data_param[:,0]
1356 dataOut.data_SNR = data_param[:,0]
1343 dataOut.data_POW = data_param[:,1]
1357 dataOut.data_POW = data_param[:,1]
1344 dataOut.data_DOP = data_param[:,2]
1358 dataOut.data_DOP = data_param[:,2]
1345 dataOut.data_WIDTH = data_param[:,3]
1359 dataOut.data_WIDTH = data_param[:,3]
1346
1360
1347 return dataOut
1361 return dataOut
1348
1362
1349 def __calculateMoments(self, oldspec, oldfreq, n0,
1363 def __calculateMoments(self, oldspec, oldfreq, n0,
1350 nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
1364 nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
1351
1365
1352 if (nicoh is None): nicoh = 1
1366 if (nicoh is None): nicoh = 1
1353 if (graph is None): graph = 0
1367 if (graph is None): graph = 0
1354 if (smooth is None): smooth = 0
1368 if (smooth is None): smooth = 0
1355 elif (self.smooth < 3): smooth = 0
1369 elif (self.smooth < 3): smooth = 0
1356
1370
1357 if (type1 is None): type1 = 0
1371 if (type1 is None): type1 = 0
1358 if (fwindow is None): fwindow = numpy.zeros(oldfreq.size) + 1
1372 if (fwindow is None): fwindow = numpy.zeros(oldfreq.size) + 1
1359 if (snrth is None): snrth = -3
1373 if (snrth is None): snrth = -3
1360 if (dc is None): dc = 0
1374 if (dc is None): dc = 0
1361 if (aliasing is None): aliasing = 0
1375 if (aliasing is None): aliasing = 0
1362 if (oldfd is None): oldfd = 0
1376 if (oldfd is None): oldfd = 0
1363 if (wwauto is None): wwauto = 0
1377 if (wwauto is None): wwauto = 0
1364
1378
1365 if (n0 < 1.e-20): n0 = 1.e-20
1379 if (n0 < 1.e-20): n0 = 1.e-20
1366
1380
1367 freq = oldfreq
1381 freq = oldfreq
1368 vec_power = numpy.zeros(oldspec.shape[1])
1382 vec_power = numpy.zeros(oldspec.shape[1])
1369 vec_fd = numpy.zeros(oldspec.shape[1])
1383 vec_fd = numpy.zeros(oldspec.shape[1])
1370 vec_w = numpy.zeros(oldspec.shape[1])
1384 vec_w = numpy.zeros(oldspec.shape[1])
1371 vec_snr = numpy.zeros(oldspec.shape[1])
1385 vec_snr = numpy.zeros(oldspec.shape[1])
1372
1386
1373 # oldspec = numpy.ma.masked_invalid(oldspec)
1387 # oldspec = numpy.ma.masked_invalid(oldspec)
1374
1388
1375 for ind in range(oldspec.shape[1]):
1389 for ind in range(oldspec.shape[1]):
1376
1390
1377 spec = oldspec[:,ind]
1391 spec = oldspec[:,ind]
1378 aux = spec*fwindow
1392 aux = spec*fwindow
1379 max_spec = aux.max()
1393 max_spec = aux.max()
1380 m = aux.tolist().index(max_spec)
1394 m = aux.tolist().index(max_spec)
1381
1395
1382 #Smooth
1396 #Smooth
1383 if (smooth == 0):
1397 if (smooth == 0):
1384 spec2 = spec
1398 spec2 = spec
1385 else:
1399 else:
1386 spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
1400 spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
1387
1401
1388 # Calculo de Momentos
1402 # Calculo de Momentos
1389 bb = spec2[numpy.arange(m,spec2.size)]
1403 bb = spec2[numpy.arange(m,spec2.size)]
1390 bb = (bb<n0).nonzero()
1404 bb = (bb<n0).nonzero()
1391 bb = bb[0]
1405 bb = bb[0]
1392
1406
1393 ss = spec2[numpy.arange(0,m + 1)]
1407 ss = spec2[numpy.arange(0,m + 1)]
1394 ss = (ss<n0).nonzero()
1408 ss = (ss<n0).nonzero()
1395 ss = ss[0]
1409 ss = ss[0]
1396
1410
1397 if (bb.size == 0):
1411 if (bb.size == 0):
1398 bb0 = spec.size - 1 - m
1412 bb0 = spec.size - 1 - m
1399 else:
1413 else:
1400 bb0 = bb[0] - 1
1414 bb0 = bb[0] - 1
1401 if (bb0 < 0):
1415 if (bb0 < 0):
1402 bb0 = 0
1416 bb0 = 0
1403
1417
1404 if (ss.size == 0):
1418 if (ss.size == 0):
1405 ss1 = 1
1419 ss1 = 1
1406 else:
1420 else:
1407 ss1 = max(ss) + 1
1421 ss1 = max(ss) + 1
1408
1422
1409 if (ss1 > m):
1423 if (ss1 > m):
1410 ss1 = m
1424 ss1 = m
1411
1425
1412 valid = numpy.arange(int(m + bb0 - ss1 + 1)) + ss1
1426 valid = numpy.arange(int(m + bb0 - ss1 + 1)) + ss1
1413
1427
1414 power = ((spec2[valid] - n0) * fwindow[valid]).sum()
1428 power = ((spec2[valid] - n0) * fwindow[valid]).sum()
1415 fd = ((spec2[valid]- n0)*freq[valid] * fwindow[valid]).sum() / power
1429 fd = ((spec2[valid]- n0)*freq[valid] * fwindow[valid]).sum() / power
1416 w = numpy.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum() / power)
1430 w = numpy.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum() / power)
1417 snr = (spec2.mean()-n0)/n0
1431 snr = (spec2.mean()-n0)/n0
1418 if (snr < 1.e-20) :
1432 if (snr < 1.e-20) :
1419 snr = 1.e-20
1433 snr = 1.e-20
1420
1434
1421 vec_power[ind] = power
1435 vec_power[ind] = power
1422 vec_fd[ind] = fd
1436 vec_fd[ind] = fd
1423 vec_w[ind] = w
1437 vec_w[ind] = w
1424 vec_snr[ind] = snr
1438 vec_snr[ind] = snr
1425
1439
1426 return numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
1440 return numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
1427
1441
1428 #------------------ Get SA Parameters --------------------------
1442 #------------------ Get SA Parameters --------------------------
1429
1443
1430 def GetSAParameters(self):
1444 def GetSAParameters(self):
1431 #SA en frecuencia
1445 #SA en frecuencia
1432 pairslist = self.dataOut.groupList
1446 pairslist = self.dataOut.groupList
1433 num_pairs = len(pairslist)
1447 num_pairs = len(pairslist)
1434
1448
1435 vel = self.dataOut.abscissaList
1449 vel = self.dataOut.abscissaList
1436 spectra = self.dataOut.data_pre
1450 spectra = self.dataOut.data_pre
1437 cspectra = self.dataIn.data_cspc
1451 cspectra = self.dataIn.data_cspc
1438 delta_v = vel[1] - vel[0]
1452 delta_v = vel[1] - vel[0]
1439
1453
1440 #Calculating the power spectrum
1454 #Calculating the power spectrum
1441 spc_pow = numpy.sum(spectra, 3)*delta_v
1455 spc_pow = numpy.sum(spectra, 3)*delta_v
1442 #Normalizing Spectra
1456 #Normalizing Spectra
1443 norm_spectra = spectra/spc_pow
1457 norm_spectra = spectra/spc_pow
1444 #Calculating the norm_spectra at peak
1458 #Calculating the norm_spectra at peak
1445 max_spectra = numpy.max(norm_spectra, 3)
1459 max_spectra = numpy.max(norm_spectra, 3)
1446
1460
1447 #Normalizing Cross Spectra
1461 #Normalizing Cross Spectra
1448 norm_cspectra = numpy.zeros(cspectra.shape)
1462 norm_cspectra = numpy.zeros(cspectra.shape)
1449
1463
1450 for i in range(num_chan):
1464 for i in range(num_chan):
1451 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
1465 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
1452
1466
1453 max_cspectra = numpy.max(norm_cspectra,2)
1467 max_cspectra = numpy.max(norm_cspectra,2)
1454 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
1468 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
1455
1469
1456 for i in range(num_pairs):
1470 for i in range(num_pairs):
1457 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
1471 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
1458 #------------------- Get Lags ----------------------------------
1472 #------------------- Get Lags ----------------------------------
1459
1473
1460 class SALags(Operation):
1474 class SALags(Operation):
1461 '''
1475 '''
1462 Function GetMoments()
1476 Function GetMoments()
1463
1477
1464 Input:
1478 Input:
1465 self.dataOut.data_pre
1479 self.dataOut.data_pre
1466 self.dataOut.abscissaList
1480 self.dataOut.abscissaList
1467 self.dataOut.noise
1481 self.dataOut.noise
1468 self.dataOut.normFactor
1482 self.dataOut.normFactor
1469 self.dataOut.data_SNR
1483 self.dataOut.data_SNR
1470 self.dataOut.groupList
1484 self.dataOut.groupList
1471 self.dataOut.nChannels
1485 self.dataOut.nChannels
1472
1486
1473 Affected:
1487 Affected:
1474 self.dataOut.data_param
1488 self.dataOut.data_param
1475
1489
1476 '''
1490 '''
1477 def run(self, dataOut):
1491 def run(self, dataOut):
1478 data_acf = dataOut.data_pre[0]
1492 data_acf = dataOut.data_pre[0]
1479 data_ccf = dataOut.data_pre[1]
1493 data_ccf = dataOut.data_pre[1]
1480 normFactor_acf = dataOut.normFactor[0]
1494 normFactor_acf = dataOut.normFactor[0]
1481 normFactor_ccf = dataOut.normFactor[1]
1495 normFactor_ccf = dataOut.normFactor[1]
1482 pairs_acf = dataOut.groupList[0]
1496 pairs_acf = dataOut.groupList[0]
1483 pairs_ccf = dataOut.groupList[1]
1497 pairs_ccf = dataOut.groupList[1]
1484
1498
1485 nHeights = dataOut.nHeights
1499 nHeights = dataOut.nHeights
1486 absc = dataOut.abscissaList
1500 absc = dataOut.abscissaList
1487 noise = dataOut.noise
1501 noise = dataOut.noise
1488 SNR = dataOut.data_SNR
1502 SNR = dataOut.data_SNR
1489 nChannels = dataOut.nChannels
1503 nChannels = dataOut.nChannels
1490 # pairsList = dataOut.groupList
1504 # pairsList = dataOut.groupList
1491 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
1505 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
1492
1506
1493 for l in range(len(pairs_acf)):
1507 for l in range(len(pairs_acf)):
1494 data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
1508 data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
1495
1509
1496 for l in range(len(pairs_ccf)):
1510 for l in range(len(pairs_ccf)):
1497 data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
1511 data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
1498
1512
1499 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
1513 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
1500 dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
1514 dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
1501 dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
1515 dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
1502 return
1516 return
1503
1517
1504 # def __getPairsAutoCorr(self, pairsList, nChannels):
1518 # def __getPairsAutoCorr(self, pairsList, nChannels):
1505 #
1519 #
1506 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1520 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1507 #
1521 #
1508 # for l in range(len(pairsList)):
1522 # for l in range(len(pairsList)):
1509 # firstChannel = pairsList[l][0]
1523 # firstChannel = pairsList[l][0]
1510 # secondChannel = pairsList[l][1]
1524 # secondChannel = pairsList[l][1]
1511 #
1525 #
1512 # #Obteniendo pares de Autocorrelacion
1526 # #Obteniendo pares de Autocorrelacion
1513 # if firstChannel == secondChannel:
1527 # if firstChannel == secondChannel:
1514 # pairsAutoCorr[firstChannel] = int(l)
1528 # pairsAutoCorr[firstChannel] = int(l)
1515 #
1529 #
1516 # pairsAutoCorr = pairsAutoCorr.astype(int)
1530 # pairsAutoCorr = pairsAutoCorr.astype(int)
1517 #
1531 #
1518 # pairsCrossCorr = range(len(pairsList))
1532 # pairsCrossCorr = range(len(pairsList))
1519 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1533 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1520 #
1534 #
1521 # return pairsAutoCorr, pairsCrossCorr
1535 # return pairsAutoCorr, pairsCrossCorr
1522
1536
1523 def __calculateTaus(self, data_acf, data_ccf, lagRange):
1537 def __calculateTaus(self, data_acf, data_ccf, lagRange):
1524
1538
1525 lag0 = data_acf.shape[1]/2
1539 lag0 = data_acf.shape[1]/2
1526 #Funcion de Autocorrelacion
1540 #Funcion de Autocorrelacion
1527 mean_acf = stats.nanmean(data_acf, axis = 0)
1541 mean_acf = stats.nanmean(data_acf, axis = 0)
1528
1542
1529 #Obtencion Indice de TauCross
1543 #Obtencion Indice de TauCross
1530 ind_ccf = data_ccf.argmax(axis = 1)
1544 ind_ccf = data_ccf.argmax(axis = 1)
1531 #Obtencion Indice de TauAuto
1545 #Obtencion Indice de TauAuto
1532 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
1546 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
1533 ccf_lag0 = data_ccf[:,lag0,:]
1547 ccf_lag0 = data_ccf[:,lag0,:]
1534
1548
1535 for i in range(ccf_lag0.shape[0]):
1549 for i in range(ccf_lag0.shape[0]):
1536 ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
1550 ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
1537
1551
1538 #Obtencion de TauCross y TauAuto
1552 #Obtencion de TauCross y TauAuto
1539 tau_ccf = lagRange[ind_ccf]
1553 tau_ccf = lagRange[ind_ccf]
1540 tau_acf = lagRange[ind_acf]
1554 tau_acf = lagRange[ind_acf]
1541
1555
1542 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
1556 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
1543
1557
1544 tau_ccf[Nan1,Nan2] = numpy.nan
1558 tau_ccf[Nan1,Nan2] = numpy.nan
1545 tau_acf[Nan1,Nan2] = numpy.nan
1559 tau_acf[Nan1,Nan2] = numpy.nan
1546 tau = numpy.vstack((tau_ccf,tau_acf))
1560 tau = numpy.vstack((tau_ccf,tau_acf))
1547
1561
1548 return tau
1562 return tau
1549
1563
1550 def __calculateLag1Phase(self, data, lagTRange):
1564 def __calculateLag1Phase(self, data, lagTRange):
1551 data1 = stats.nanmean(data, axis = 0)
1565 data1 = stats.nanmean(data, axis = 0)
1552 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
1566 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
1553
1567
1554 phase = numpy.angle(data1[lag1,:])
1568 phase = numpy.angle(data1[lag1,:])
1555
1569
1556 return phase
1570 return phase
1557
1571
1558 class SpectralFitting(Operation):
1572 class SpectralFitting(Operation):
1559 '''
1573 '''
1560 Function GetMoments()
1574 Function GetMoments()
1561
1575
1562 Input:
1576 Input:
1563 Output:
1577 Output:
1564 Variables modified:
1578 Variables modified:
1565 '''
1579 '''
1566
1580
1567 def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
1581 def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
1568
1582
1569
1583
1570 if path != None:
1584 if path != None:
1571 sys.path.append(path)
1585 sys.path.append(path)
1572 self.dataOut.library = importlib.import_module(file)
1586 self.dataOut.library = importlib.import_module(file)
1573
1587
1574 #To be inserted as a parameter
1588 #To be inserted as a parameter
1575 groupArray = numpy.array(groupList)
1589 groupArray = numpy.array(groupList)
1576 # groupArray = numpy.array([[0,1],[2,3]])
1590 # groupArray = numpy.array([[0,1],[2,3]])
1577 self.dataOut.groupList = groupArray
1591 self.dataOut.groupList = groupArray
1578
1592
1579 nGroups = groupArray.shape[0]
1593 nGroups = groupArray.shape[0]
1580 nChannels = self.dataIn.nChannels
1594 nChannels = self.dataIn.nChannels
1581 nHeights=self.dataIn.heightList.size
1595 nHeights=self.dataIn.heightList.size
1582
1596
1583 #Parameters Array
1597 #Parameters Array
1584 self.dataOut.data_param = None
1598 self.dataOut.data_param = None
1585
1599
1586 #Set constants
1600 #Set constants
1587 constants = self.dataOut.library.setConstants(self.dataIn)
1601 constants = self.dataOut.library.setConstants(self.dataIn)
1588 self.dataOut.constants = constants
1602 self.dataOut.constants = constants
1589 M = self.dataIn.normFactor
1603 M = self.dataIn.normFactor
1590 N = self.dataIn.nFFTPoints
1604 N = self.dataIn.nFFTPoints
1591 ippSeconds = self.dataIn.ippSeconds
1605 ippSeconds = self.dataIn.ippSeconds
1592 K = self.dataIn.nIncohInt
1606 K = self.dataIn.nIncohInt
1593 pairsArray = numpy.array(self.dataIn.pairsList)
1607 pairsArray = numpy.array(self.dataIn.pairsList)
1594
1608
1595 #List of possible combinations
1609 #List of possible combinations
1596 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1610 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1597 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1611 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1598
1612
1599 if getSNR:
1613 if getSNR:
1600 listChannels = groupArray.reshape((groupArray.size))
1614 listChannels = groupArray.reshape((groupArray.size))
1601 listChannels.sort()
1615 listChannels.sort()
1602 noise = self.dataIn.getNoise()
1616 noise = self.dataIn.getNoise()
1603 self.dataOut.data_SNR = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1617 self.dataOut.data_SNR = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1604
1618
1605 for i in range(nGroups):
1619 for i in range(nGroups):
1606 coord = groupArray[i,:]
1620 coord = groupArray[i,:]
1607
1621
1608 #Input data array
1622 #Input data array
1609 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1623 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1610 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1624 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1611
1625
1612 #Cross Spectra data array for Covariance Matrixes
1626 #Cross Spectra data array for Covariance Matrixes
1613 ind = 0
1627 ind = 0
1614 for pairs in listComb:
1628 for pairs in listComb:
1615 pairsSel = numpy.array([coord[x],coord[y]])
1629 pairsSel = numpy.array([coord[x],coord[y]])
1616 indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
1630 indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
1617 ind += 1
1631 ind += 1
1618 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1632 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1619 dataCross = dataCross**2/K
1633 dataCross = dataCross**2/K
1620
1634
1621 for h in range(nHeights):
1635 for h in range(nHeights):
1622
1636
1623 #Input
1637 #Input
1624 d = data[:,h]
1638 d = data[:,h]
1625
1639
1626 #Covariance Matrix
1640 #Covariance Matrix
1627 D = numpy.diag(d**2/K)
1641 D = numpy.diag(d**2/K)
1628 ind = 0
1642 ind = 0
1629 for pairs in listComb:
1643 for pairs in listComb:
1630 #Coordinates in Covariance Matrix
1644 #Coordinates in Covariance Matrix
1631 x = pairs[0]
1645 x = pairs[0]
1632 y = pairs[1]
1646 y = pairs[1]
1633 #Channel Index
1647 #Channel Index
1634 S12 = dataCross[ind,:,h]
1648 S12 = dataCross[ind,:,h]
1635 D12 = numpy.diag(S12)
1649 D12 = numpy.diag(S12)
1636 #Completing Covariance Matrix with Cross Spectras
1650 #Completing Covariance Matrix with Cross Spectras
1637 D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
1651 D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
1638 D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
1652 D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
1639 ind += 1
1653 ind += 1
1640 Dinv=numpy.linalg.inv(D)
1654 Dinv=numpy.linalg.inv(D)
1641 L=numpy.linalg.cholesky(Dinv)
1655 L=numpy.linalg.cholesky(Dinv)
1642 LT=L.T
1656 LT=L.T
1643
1657
1644 dp = numpy.dot(LT,d)
1658 dp = numpy.dot(LT,d)
1645
1659
1646 #Initial values
1660 #Initial values
1647 data_spc = self.dataIn.data_spc[coord,:,h]
1661 data_spc = self.dataIn.data_spc[coord,:,h]
1648
1662
1649 if (h>0)and(error1[3]<5):
1663 if (h>0)and(error1[3]<5):
1650 p0 = self.dataOut.data_param[i,:,h-1]
1664 p0 = self.dataOut.data_param[i,:,h-1]
1651 else:
1665 else:
1652 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1666 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1653
1667
1654 try:
1668 try:
1655 #Least Squares
1669 #Least Squares
1656 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
1670 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
1657 # minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
1671 # minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
1658 #Chi square error
1672 #Chi square error
1659 error0 = numpy.sum(infodict['fvec']**2)/(2*N)
1673 error0 = numpy.sum(infodict['fvec']**2)/(2*N)
1660 #Error with Jacobian
1674 #Error with Jacobian
1661 error1 = self.dataOut.library.errorFunction(minp,constants,LT)
1675 error1 = self.dataOut.library.errorFunction(minp,constants,LT)
1662 except:
1676 except:
1663 minp = p0*numpy.nan
1677 minp = p0*numpy.nan
1664 error0 = numpy.nan
1678 error0 = numpy.nan
1665 error1 = p0*numpy.nan
1679 error1 = p0*numpy.nan
1666
1680
1667 #Save
1681 #Save
1668 if self.dataOut.data_param is None:
1682 if self.dataOut.data_param is None:
1669 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1683 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1670 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1684 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1671
1685
1672 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1686 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1673 self.dataOut.data_param[i,:,h] = minp
1687 self.dataOut.data_param[i,:,h] = minp
1674 return
1688 return
1675
1689
1676 def __residFunction(self, p, dp, LT, constants):
1690 def __residFunction(self, p, dp, LT, constants):
1677
1691
1678 fm = self.dataOut.library.modelFunction(p, constants)
1692 fm = self.dataOut.library.modelFunction(p, constants)
1679 fmp=numpy.dot(LT,fm)
1693 fmp=numpy.dot(LT,fm)
1680
1694
1681 return dp-fmp
1695 return dp-fmp
1682
1696
1683 def __getSNR(self, z, noise):
1697 def __getSNR(self, z, noise):
1684
1698
1685 avg = numpy.average(z, axis=1)
1699 avg = numpy.average(z, axis=1)
1686 SNR = (avg.T-noise)/noise
1700 SNR = (avg.T-noise)/noise
1687 SNR = SNR.T
1701 SNR = SNR.T
1688 return SNR
1702 return SNR
1689
1703
1690 def __chisq(p,chindex,hindex):
1704 def __chisq(p,chindex,hindex):
1691 #similar to Resid but calculates CHI**2
1705 #similar to Resid but calculates CHI**2
1692 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
1706 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
1693 dp=numpy.dot(LT,d)
1707 dp=numpy.dot(LT,d)
1694 fmp=numpy.dot(LT,fm)
1708 fmp=numpy.dot(LT,fm)
1695 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1709 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1696 return chisq
1710 return chisq
1697
1711
1698 class WindProfiler(Operation):
1712 class WindProfiler(Operation):
1699
1713
1700 __isConfig = False
1714 __isConfig = False
1701
1715
1702 __initime = None
1716 __initime = None
1703 __lastdatatime = None
1717 __lastdatatime = None
1704 __integrationtime = None
1718 __integrationtime = None
1705
1719
1706 __buffer = None
1720 __buffer = None
1707
1721
1708 __dataReady = False
1722 __dataReady = False
1709
1723
1710 __firstdata = None
1724 __firstdata = None
1711
1725
1712 n = None
1726 n = None
1713
1727
1714 def __init__(self):
1728 def __init__(self):
1715 Operation.__init__(self)
1729 Operation.__init__(self)
1716
1730
1717 def __calculateCosDir(self, elev, azim):
1731 def __calculateCosDir(self, elev, azim):
1718 zen = (90 - elev)*numpy.pi/180
1732 zen = (90 - elev)*numpy.pi/180
1719 azim = azim*numpy.pi/180
1733 azim = azim*numpy.pi/180
1720 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1734 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1721 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1735 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1722
1736
1723 signX = numpy.sign(numpy.cos(azim))
1737 signX = numpy.sign(numpy.cos(azim))
1724 signY = numpy.sign(numpy.sin(azim))
1738 signY = numpy.sign(numpy.sin(azim))
1725
1739
1726 cosDirX = numpy.copysign(cosDirX, signX)
1740 cosDirX = numpy.copysign(cosDirX, signX)
1727 cosDirY = numpy.copysign(cosDirY, signY)
1741 cosDirY = numpy.copysign(cosDirY, signY)
1728 return cosDirX, cosDirY
1742 return cosDirX, cosDirY
1729
1743
1730 def __calculateAngles(self, theta_x, theta_y, azimuth):
1744 def __calculateAngles(self, theta_x, theta_y, azimuth):
1731
1745
1732 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1746 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1733 zenith_arr = numpy.arccos(dir_cosw)
1747 zenith_arr = numpy.arccos(dir_cosw)
1734 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1748 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1735
1749
1736 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1750 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1737 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1751 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1738
1752
1739 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1753 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1740
1754
1741 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1755 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1742
1756
1743 #
1757 #
1744 if horOnly:
1758 if horOnly:
1745 A = numpy.c_[dir_cosu,dir_cosv]
1759 A = numpy.c_[dir_cosu,dir_cosv]
1746 else:
1760 else:
1747 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
1761 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
1748 A = numpy.asmatrix(A)
1762 A = numpy.asmatrix(A)
1749 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
1763 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
1750
1764
1751 return A1
1765 return A1
1752
1766
1753 def __correctValues(self, heiRang, phi, velRadial, SNR):
1767 def __correctValues(self, heiRang, phi, velRadial, SNR):
1754 listPhi = phi.tolist()
1768 listPhi = phi.tolist()
1755 maxid = listPhi.index(max(listPhi))
1769 maxid = listPhi.index(max(listPhi))
1756 minid = listPhi.index(min(listPhi))
1770 minid = listPhi.index(min(listPhi))
1757
1771
1758 rango = list(range(len(phi)))
1772 rango = list(range(len(phi)))
1759 # rango = numpy.delete(rango,maxid)
1773 # rango = numpy.delete(rango,maxid)
1760
1774
1761 heiRang1 = heiRang*math.cos(phi[maxid])
1775 heiRang1 = heiRang*math.cos(phi[maxid])
1762 heiRangAux = heiRang*math.cos(phi[minid])
1776 heiRangAux = heiRang*math.cos(phi[minid])
1763 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1777 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1764 heiRang1 = numpy.delete(heiRang1,indOut)
1778 heiRang1 = numpy.delete(heiRang1,indOut)
1765
1779
1766 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1780 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1767 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1781 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1768
1782
1769 for i in rango:
1783 for i in rango:
1770 x = heiRang*math.cos(phi[i])
1784 x = heiRang*math.cos(phi[i])
1771 y1 = velRadial[i,:]
1785 y1 = velRadial[i,:]
1772 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1786 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1773
1787
1774 x1 = heiRang1
1788 x1 = heiRang1
1775 y11 = f1(x1)
1789 y11 = f1(x1)
1776
1790
1777 y2 = SNR[i,:]
1791 y2 = SNR[i,:]
1778 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1792 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1779 y21 = f2(x1)
1793 y21 = f2(x1)
1780
1794
1781 velRadial1[i,:] = y11
1795 velRadial1[i,:] = y11
1782 SNR1[i,:] = y21
1796 SNR1[i,:] = y21
1783
1797
1784 return heiRang1, velRadial1, SNR1
1798 return heiRang1, velRadial1, SNR1
1785
1799
1786 def __calculateVelUVW(self, A, velRadial):
1800 def __calculateVelUVW(self, A, velRadial):
1787
1801
1788 #Operacion Matricial
1802 #Operacion Matricial
1789 # velUVW = numpy.zeros((velRadial.shape[1],3))
1803 # velUVW = numpy.zeros((velRadial.shape[1],3))
1790 # for ind in range(velRadial.shape[1]):
1804 # for ind in range(velRadial.shape[1]):
1791 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
1805 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
1792 # velUVW = velUVW.transpose()
1806 # velUVW = velUVW.transpose()
1793 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1807 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1794 velUVW[:,:] = numpy.dot(A,velRadial)
1808 velUVW[:,:] = numpy.dot(A,velRadial)
1795
1809
1796
1810
1797 return velUVW
1811 return velUVW
1798
1812
1799 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1813 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1800
1814
1801 def techniqueDBS(self, kwargs):
1815 def techniqueDBS(self, kwargs):
1802 """
1816 """
1803 Function that implements Doppler Beam Swinging (DBS) technique.
1817 Function that implements Doppler Beam Swinging (DBS) technique.
1804
1818
1805 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1819 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1806 Direction correction (if necessary), Ranges and SNR
1820 Direction correction (if necessary), Ranges and SNR
1807
1821
1808 Output: Winds estimation (Zonal, Meridional and Vertical)
1822 Output: Winds estimation (Zonal, Meridional and Vertical)
1809
1823
1810 Parameters affected: Winds, height range, SNR
1824 Parameters affected: Winds, height range, SNR
1811 """
1825 """
1812 velRadial0 = kwargs['velRadial']
1826 velRadial0 = kwargs['velRadial']
1813 heiRang = kwargs['heightList']
1827 heiRang = kwargs['heightList']
1814 SNR0 = kwargs['SNR']
1828 SNR0 = kwargs['SNR']
1815
1829
1816 if 'dirCosx' in kwargs and 'dirCosy' in kwargs:
1830 if 'dirCosx' in kwargs and 'dirCosy' in kwargs:
1817 theta_x = numpy.array(kwargs['dirCosx'])
1831 theta_x = numpy.array(kwargs['dirCosx'])
1818 theta_y = numpy.array(kwargs['dirCosy'])
1832 theta_y = numpy.array(kwargs['dirCosy'])
1819 else:
1833 else:
1820 elev = numpy.array(kwargs['elevation'])
1834 elev = numpy.array(kwargs['elevation'])
1821 azim = numpy.array(kwargs['azimuth'])
1835 azim = numpy.array(kwargs['azimuth'])
1822 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1836 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1823 azimuth = kwargs['correctAzimuth']
1837 azimuth = kwargs['correctAzimuth']
1824 if 'horizontalOnly' in kwargs:
1838 if 'horizontalOnly' in kwargs:
1825 horizontalOnly = kwargs['horizontalOnly']
1839 horizontalOnly = kwargs['horizontalOnly']
1826 else: horizontalOnly = False
1840 else: horizontalOnly = False
1827 if 'correctFactor' in kwargs:
1841 if 'correctFactor' in kwargs:
1828 correctFactor = kwargs['correctFactor']
1842 correctFactor = kwargs['correctFactor']
1829 else: correctFactor = 1
1843 else: correctFactor = 1
1830 if 'channelList' in kwargs:
1844 if 'channelList' in kwargs:
1831 channelList = kwargs['channelList']
1845 channelList = kwargs['channelList']
1832 if len(channelList) == 2:
1846 if len(channelList) == 2:
1833 horizontalOnly = True
1847 horizontalOnly = True
1834 arrayChannel = numpy.array(channelList)
1848 arrayChannel = numpy.array(channelList)
1835 param = param[arrayChannel,:,:]
1849 param = param[arrayChannel,:,:]
1836 theta_x = theta_x[arrayChannel]
1850 theta_x = theta_x[arrayChannel]
1837 theta_y = theta_y[arrayChannel]
1851 theta_y = theta_y[arrayChannel]
1838
1852
1839 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
1853 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
1840 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
1854 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
1841 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1855 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1842
1856
1843 #Calculo de Componentes de la velocidad con DBS
1857 #Calculo de Componentes de la velocidad con DBS
1844 winds = self.__calculateVelUVW(A,velRadial1)
1858 winds = self.__calculateVelUVW(A,velRadial1)
1845
1859
1846 return winds, heiRang1, SNR1
1860 return winds, heiRang1, SNR1
1847
1861
1848 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
1862 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
1849
1863
1850 nPairs = len(pairs_ccf)
1864 nPairs = len(pairs_ccf)
1851 posx = numpy.asarray(posx)
1865 posx = numpy.asarray(posx)
1852 posy = numpy.asarray(posy)
1866 posy = numpy.asarray(posy)
1853
1867
1854 #Rotacion Inversa para alinear con el azimuth
1868 #Rotacion Inversa para alinear con el azimuth
1855 if azimuth!= None:
1869 if azimuth!= None:
1856 azimuth = azimuth*math.pi/180
1870 azimuth = azimuth*math.pi/180
1857 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
1871 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
1858 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
1872 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
1859 else:
1873 else:
1860 posx1 = posx
1874 posx1 = posx
1861 posy1 = posy
1875 posy1 = posy
1862
1876
1863 #Calculo de Distancias
1877 #Calculo de Distancias
1864 distx = numpy.zeros(nPairs)
1878 distx = numpy.zeros(nPairs)
1865 disty = numpy.zeros(nPairs)
1879 disty = numpy.zeros(nPairs)
1866 dist = numpy.zeros(nPairs)
1880 dist = numpy.zeros(nPairs)
1867 ang = numpy.zeros(nPairs)
1881 ang = numpy.zeros(nPairs)
1868
1882
1869 for i in range(nPairs):
1883 for i in range(nPairs):
1870 distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
1884 distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
1871 disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
1885 disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
1872 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1886 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1873 ang[i] = numpy.arctan2(disty[i],distx[i])
1887 ang[i] = numpy.arctan2(disty[i],distx[i])
1874
1888
1875 return distx, disty, dist, ang
1889 return distx, disty, dist, ang
1876 #Calculo de Matrices
1890 #Calculo de Matrices
1877 # nPairs = len(pairs)
1891 # nPairs = len(pairs)
1878 # ang1 = numpy.zeros((nPairs, 2, 1))
1892 # ang1 = numpy.zeros((nPairs, 2, 1))
1879 # dist1 = numpy.zeros((nPairs, 2, 1))
1893 # dist1 = numpy.zeros((nPairs, 2, 1))
1880 #
1894 #
1881 # for j in range(nPairs):
1895 # for j in range(nPairs):
1882 # dist1[j,0,0] = dist[pairs[j][0]]
1896 # dist1[j,0,0] = dist[pairs[j][0]]
1883 # dist1[j,1,0] = dist[pairs[j][1]]
1897 # dist1[j,1,0] = dist[pairs[j][1]]
1884 # ang1[j,0,0] = ang[pairs[j][0]]
1898 # ang1[j,0,0] = ang[pairs[j][0]]
1885 # ang1[j,1,0] = ang[pairs[j][1]]
1899 # ang1[j,1,0] = ang[pairs[j][1]]
1886 #
1900 #
1887 # return distx,disty, dist1,ang1
1901 # return distx,disty, dist1,ang1
1888
1902
1889
1903
1890 def __calculateVelVer(self, phase, lagTRange, _lambda):
1904 def __calculateVelVer(self, phase, lagTRange, _lambda):
1891
1905
1892 Ts = lagTRange[1] - lagTRange[0]
1906 Ts = lagTRange[1] - lagTRange[0]
1893 velW = -_lambda*phase/(4*math.pi*Ts)
1907 velW = -_lambda*phase/(4*math.pi*Ts)
1894
1908
1895 return velW
1909 return velW
1896
1910
1897 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1911 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1898 nPairs = tau1.shape[0]
1912 nPairs = tau1.shape[0]
1899 nHeights = tau1.shape[1]
1913 nHeights = tau1.shape[1]
1900 vel = numpy.zeros((nPairs,3,nHeights))
1914 vel = numpy.zeros((nPairs,3,nHeights))
1901 dist1 = numpy.reshape(dist, (dist.size,1))
1915 dist1 = numpy.reshape(dist, (dist.size,1))
1902
1916
1903 angCos = numpy.cos(ang)
1917 angCos = numpy.cos(ang)
1904 angSin = numpy.sin(ang)
1918 angSin = numpy.sin(ang)
1905
1919
1906 vel0 = dist1*tau1/(2*tau2**2)
1920 vel0 = dist1*tau1/(2*tau2**2)
1907 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1921 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1908 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1922 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1909
1923
1910 ind = numpy.where(numpy.isinf(vel))
1924 ind = numpy.where(numpy.isinf(vel))
1911 vel[ind] = numpy.nan
1925 vel[ind] = numpy.nan
1912
1926
1913 return vel
1927 return vel
1914
1928
1915 # def __getPairsAutoCorr(self, pairsList, nChannels):
1929 # def __getPairsAutoCorr(self, pairsList, nChannels):
1916 #
1930 #
1917 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1931 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1918 #
1932 #
1919 # for l in range(len(pairsList)):
1933 # for l in range(len(pairsList)):
1920 # firstChannel = pairsList[l][0]
1934 # firstChannel = pairsList[l][0]
1921 # secondChannel = pairsList[l][1]
1935 # secondChannel = pairsList[l][1]
1922 #
1936 #
1923 # #Obteniendo pares de Autocorrelacion
1937 # #Obteniendo pares de Autocorrelacion
1924 # if firstChannel == secondChannel:
1938 # if firstChannel == secondChannel:
1925 # pairsAutoCorr[firstChannel] = int(l)
1939 # pairsAutoCorr[firstChannel] = int(l)
1926 #
1940 #
1927 # pairsAutoCorr = pairsAutoCorr.astype(int)
1941 # pairsAutoCorr = pairsAutoCorr.astype(int)
1928 #
1942 #
1929 # pairsCrossCorr = range(len(pairsList))
1943 # pairsCrossCorr = range(len(pairsList))
1930 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1944 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1931 #
1945 #
1932 # return pairsAutoCorr, pairsCrossCorr
1946 # return pairsAutoCorr, pairsCrossCorr
1933
1947
1934 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1948 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1935 def techniqueSA(self, kwargs):
1949 def techniqueSA(self, kwargs):
1936
1950
1937 """
1951 """
1938 Function that implements Spaced Antenna (SA) technique.
1952 Function that implements Spaced Antenna (SA) technique.
1939
1953
1940 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1954 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1941 Direction correction (if necessary), Ranges and SNR
1955 Direction correction (if necessary), Ranges and SNR
1942
1956
1943 Output: Winds estimation (Zonal, Meridional and Vertical)
1957 Output: Winds estimation (Zonal, Meridional and Vertical)
1944
1958
1945 Parameters affected: Winds
1959 Parameters affected: Winds
1946 """
1960 """
1947 position_x = kwargs['positionX']
1961 position_x = kwargs['positionX']
1948 position_y = kwargs['positionY']
1962 position_y = kwargs['positionY']
1949 azimuth = kwargs['azimuth']
1963 azimuth = kwargs['azimuth']
1950
1964
1951 if 'correctFactor' in kwargs:
1965 if 'correctFactor' in kwargs:
1952 correctFactor = kwargs['correctFactor']
1966 correctFactor = kwargs['correctFactor']
1953 else:
1967 else:
1954 correctFactor = 1
1968 correctFactor = 1
1955
1969
1956 groupList = kwargs['groupList']
1970 groupList = kwargs['groupList']
1957 pairs_ccf = groupList[1]
1971 pairs_ccf = groupList[1]
1958 tau = kwargs['tau']
1972 tau = kwargs['tau']
1959 _lambda = kwargs['_lambda']
1973 _lambda = kwargs['_lambda']
1960
1974
1961 #Cross Correlation pairs obtained
1975 #Cross Correlation pairs obtained
1962 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
1976 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
1963 # pairsArray = numpy.array(pairsList)[pairsCrossCorr]
1977 # pairsArray = numpy.array(pairsList)[pairsCrossCorr]
1964 # pairsSelArray = numpy.array(pairsSelected)
1978 # pairsSelArray = numpy.array(pairsSelected)
1965 # pairs = []
1979 # pairs = []
1966 #
1980 #
1967 # #Wind estimation pairs obtained
1981 # #Wind estimation pairs obtained
1968 # for i in range(pairsSelArray.shape[0]/2):
1982 # for i in range(pairsSelArray.shape[0]/2):
1969 # ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
1983 # ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
1970 # ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
1984 # ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
1971 # pairs.append((ind1,ind2))
1985 # pairs.append((ind1,ind2))
1972
1986
1973 indtau = tau.shape[0]/2
1987 indtau = tau.shape[0]/2
1974 tau1 = tau[:indtau,:]
1988 tau1 = tau[:indtau,:]
1975 tau2 = tau[indtau:-1,:]
1989 tau2 = tau[indtau:-1,:]
1976 # tau1 = tau1[pairs,:]
1990 # tau1 = tau1[pairs,:]
1977 # tau2 = tau2[pairs,:]
1991 # tau2 = tau2[pairs,:]
1978 phase1 = tau[-1,:]
1992 phase1 = tau[-1,:]
1979
1993
1980 #---------------------------------------------------------------------
1994 #---------------------------------------------------------------------
1981 #Metodo Directo
1995 #Metodo Directo
1982 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
1996 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
1983 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
1997 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
1984 winds = stats.nanmean(winds, axis=0)
1998 winds = stats.nanmean(winds, axis=0)
1985 #---------------------------------------------------------------------
1999 #---------------------------------------------------------------------
1986 #Metodo General
2000 #Metodo General
1987 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
2001 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
1988 # #Calculo Coeficientes de Funcion de Correlacion
2002 # #Calculo Coeficientes de Funcion de Correlacion
1989 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
2003 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
1990 # #Calculo de Velocidades
2004 # #Calculo de Velocidades
1991 # winds = self.calculateVelUV(F,G,A,B,H)
2005 # winds = self.calculateVelUV(F,G,A,B,H)
1992
2006
1993 #---------------------------------------------------------------------
2007 #---------------------------------------------------------------------
1994 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
2008 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
1995 winds = correctFactor*winds
2009 winds = correctFactor*winds
1996 return winds
2010 return winds
1997
2011
1998 def __checkTime(self, currentTime, paramInterval, outputInterval):
2012 def __checkTime(self, currentTime, paramInterval, outputInterval):
1999
2013
2000 dataTime = currentTime + paramInterval
2014 dataTime = currentTime + paramInterval
2001 deltaTime = dataTime - self.__initime
2015 deltaTime = dataTime - self.__initime
2002
2016
2003 if deltaTime >= outputInterval or deltaTime < 0:
2017 if deltaTime >= outputInterval or deltaTime < 0:
2004 self.__dataReady = True
2018 self.__dataReady = True
2005 return
2019 return
2006
2020
2007 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
2021 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
2008 '''
2022 '''
2009 Function that implements winds estimation technique with detected meteors.
2023 Function that implements winds estimation technique with detected meteors.
2010
2024
2011 Input: Detected meteors, Minimum meteor quantity to wind estimation
2025 Input: Detected meteors, Minimum meteor quantity to wind estimation
2012
2026
2013 Output: Winds estimation (Zonal and Meridional)
2027 Output: Winds estimation (Zonal and Meridional)
2014
2028
2015 Parameters affected: Winds
2029 Parameters affected: Winds
2016 '''
2030 '''
2017 #Settings
2031 #Settings
2018 nInt = (heightMax - heightMin)/2
2032 nInt = (heightMax - heightMin)/2
2019 nInt = int(nInt)
2033 nInt = int(nInt)
2020 winds = numpy.zeros((2,nInt))*numpy.nan
2034 winds = numpy.zeros((2,nInt))*numpy.nan
2021
2035
2022 #Filter errors
2036 #Filter errors
2023 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
2037 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
2024 finalMeteor = arrayMeteor[error,:]
2038 finalMeteor = arrayMeteor[error,:]
2025
2039
2026 #Meteor Histogram
2040 #Meteor Histogram
2027 finalHeights = finalMeteor[:,2]
2041 finalHeights = finalMeteor[:,2]
2028 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
2042 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
2029 nMeteorsPerI = hist[0]
2043 nMeteorsPerI = hist[0]
2030 heightPerI = hist[1]
2044 heightPerI = hist[1]
2031
2045
2032 #Sort of meteors
2046 #Sort of meteors
2033 indSort = finalHeights.argsort()
2047 indSort = finalHeights.argsort()
2034 finalMeteor2 = finalMeteor[indSort,:]
2048 finalMeteor2 = finalMeteor[indSort,:]
2035
2049
2036 # Calculating winds
2050 # Calculating winds
2037 ind1 = 0
2051 ind1 = 0
2038 ind2 = 0
2052 ind2 = 0
2039
2053
2040 for i in range(nInt):
2054 for i in range(nInt):
2041 nMet = nMeteorsPerI[i]
2055 nMet = nMeteorsPerI[i]
2042 ind1 = ind2
2056 ind1 = ind2
2043 ind2 = ind1 + nMet
2057 ind2 = ind1 + nMet
2044
2058
2045 meteorAux = finalMeteor2[ind1:ind2,:]
2059 meteorAux = finalMeteor2[ind1:ind2,:]
2046
2060
2047 if meteorAux.shape[0] >= meteorThresh:
2061 if meteorAux.shape[0] >= meteorThresh:
2048 vel = meteorAux[:, 6]
2062 vel = meteorAux[:, 6]
2049 zen = meteorAux[:, 4]*numpy.pi/180
2063 zen = meteorAux[:, 4]*numpy.pi/180
2050 azim = meteorAux[:, 3]*numpy.pi/180
2064 azim = meteorAux[:, 3]*numpy.pi/180
2051
2065
2052 n = numpy.cos(zen)
2066 n = numpy.cos(zen)
2053 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
2067 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
2054 # l = m*numpy.tan(azim)
2068 # l = m*numpy.tan(azim)
2055 l = numpy.sin(zen)*numpy.sin(azim)
2069 l = numpy.sin(zen)*numpy.sin(azim)
2056 m = numpy.sin(zen)*numpy.cos(azim)
2070 m = numpy.sin(zen)*numpy.cos(azim)
2057
2071
2058 A = numpy.vstack((l, m)).transpose()
2072 A = numpy.vstack((l, m)).transpose()
2059 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
2073 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
2060 windsAux = numpy.dot(A1, vel)
2074 windsAux = numpy.dot(A1, vel)
2061
2075
2062 winds[0,i] = windsAux[0]
2076 winds[0,i] = windsAux[0]
2063 winds[1,i] = windsAux[1]
2077 winds[1,i] = windsAux[1]
2064
2078
2065 return winds, heightPerI[:-1]
2079 return winds, heightPerI[:-1]
2066
2080
2067 def techniqueNSM_SA(self, **kwargs):
2081 def techniqueNSM_SA(self, **kwargs):
2068 metArray = kwargs['metArray']
2082 metArray = kwargs['metArray']
2069 heightList = kwargs['heightList']
2083 heightList = kwargs['heightList']
2070 timeList = kwargs['timeList']
2084 timeList = kwargs['timeList']
2071
2085
2072 rx_location = kwargs['rx_location']
2086 rx_location = kwargs['rx_location']
2073 groupList = kwargs['groupList']
2087 groupList = kwargs['groupList']
2074 azimuth = kwargs['azimuth']
2088 azimuth = kwargs['azimuth']
2075 dfactor = kwargs['dfactor']
2089 dfactor = kwargs['dfactor']
2076 k = kwargs['k']
2090 k = kwargs['k']
2077
2091
2078 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
2092 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
2079 d = dist*dfactor
2093 d = dist*dfactor
2080 #Phase calculation
2094 #Phase calculation
2081 metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
2095 metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
2082
2096
2083 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
2097 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
2084
2098
2085 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2099 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2086 azimuth1 = azimuth1*numpy.pi/180
2100 azimuth1 = azimuth1*numpy.pi/180
2087
2101
2088 for i in range(heightList.size):
2102 for i in range(heightList.size):
2089 h = heightList[i]
2103 h = heightList[i]
2090 indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
2104 indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
2091 metHeight = metArray1[indH,:]
2105 metHeight = metArray1[indH,:]
2092 if metHeight.shape[0] >= 2:
2106 if metHeight.shape[0] >= 2:
2093 velAux = numpy.asmatrix(metHeight[:,-2]).T #Radial Velocities
2107 velAux = numpy.asmatrix(metHeight[:,-2]).T #Radial Velocities
2094 iazim = metHeight[:,1].astype(int)
2108 iazim = metHeight[:,1].astype(int)
2095 azimAux = numpy.asmatrix(azimuth1[iazim]).T #Azimuths
2109 azimAux = numpy.asmatrix(azimuth1[iazim]).T #Azimuths
2096 A = numpy.hstack((numpy.cos(azimAux),numpy.sin(azimAux)))
2110 A = numpy.hstack((numpy.cos(azimAux),numpy.sin(azimAux)))
2097 A = numpy.asmatrix(A)
2111 A = numpy.asmatrix(A)
2098 A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
2112 A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
2099 velHor = numpy.dot(A1,velAux)
2113 velHor = numpy.dot(A1,velAux)
2100
2114
2101 velEst[i,:] = numpy.squeeze(velHor)
2115 velEst[i,:] = numpy.squeeze(velHor)
2102 return velEst
2116 return velEst
2103
2117
2104 def __getPhaseSlope(self, metArray, heightList, timeList):
2118 def __getPhaseSlope(self, metArray, heightList, timeList):
2105 meteorList = []
2119 meteorList = []
2106 #utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
2120 #utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
2107 #Putting back together the meteor matrix
2121 #Putting back together the meteor matrix
2108 utctime = metArray[:,0]
2122 utctime = metArray[:,0]
2109 uniqueTime = numpy.unique(utctime)
2123 uniqueTime = numpy.unique(utctime)
2110
2124
2111 phaseDerThresh = 0.5
2125 phaseDerThresh = 0.5
2112 ippSeconds = timeList[1] - timeList[0]
2126 ippSeconds = timeList[1] - timeList[0]
2113 sec = numpy.where(timeList>1)[0][0]
2127 sec = numpy.where(timeList>1)[0][0]
2114 nPairs = metArray.shape[1] - 6
2128 nPairs = metArray.shape[1] - 6
2115 nHeights = len(heightList)
2129 nHeights = len(heightList)
2116
2130
2117 for t in uniqueTime:
2131 for t in uniqueTime:
2118 metArray1 = metArray[utctime==t,:]
2132 metArray1 = metArray[utctime==t,:]
2119 # phaseDerThresh = numpy.pi/4 #reducir Phase thresh
2133 # phaseDerThresh = numpy.pi/4 #reducir Phase thresh
2120 tmet = metArray1[:,1].astype(int)
2134 tmet = metArray1[:,1].astype(int)
2121 hmet = metArray1[:,2].astype(int)
2135 hmet = metArray1[:,2].astype(int)
2122
2136
2123 metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
2137 metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
2124 metPhase[:,:] = numpy.nan
2138 metPhase[:,:] = numpy.nan
2125 metPhase[:,hmet,tmet] = metArray1[:,6:].T
2139 metPhase[:,hmet,tmet] = metArray1[:,6:].T
2126
2140
2127 #Delete short trails
2141 #Delete short trails
2128 metBool = ~numpy.isnan(metPhase[0,:,:])
2142 metBool = ~numpy.isnan(metPhase[0,:,:])
2129 heightVect = numpy.sum(metBool, axis = 1)
2143 heightVect = numpy.sum(metBool, axis = 1)
2130 metBool[heightVect<sec,:] = False
2144 metBool[heightVect<sec,:] = False
2131 metPhase[:,heightVect<sec,:] = numpy.nan
2145 metPhase[:,heightVect<sec,:] = numpy.nan
2132
2146
2133 #Derivative
2147 #Derivative
2134 metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
2148 metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
2135 phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
2149 phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
2136 metPhase[phDerAux] = numpy.nan
2150 metPhase[phDerAux] = numpy.nan
2137
2151
2138 #--------------------------METEOR DETECTION -----------------------------------------
2152 #--------------------------METEOR DETECTION -----------------------------------------
2139 indMet = numpy.where(numpy.any(metBool,axis=1))[0]
2153 indMet = numpy.where(numpy.any(metBool,axis=1))[0]
2140
2154
2141 for p in numpy.arange(nPairs):
2155 for p in numpy.arange(nPairs):
2142 phase = metPhase[p,:,:]
2156 phase = metPhase[p,:,:]
2143 phDer = metDer[p,:,:]
2157 phDer = metDer[p,:,:]
2144
2158
2145 for h in indMet:
2159 for h in indMet:
2146 height = heightList[h]
2160 height = heightList[h]
2147 phase1 = phase[h,:] #82
2161 phase1 = phase[h,:] #82
2148 phDer1 = phDer[h,:]
2162 phDer1 = phDer[h,:]
2149
2163
2150 phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
2164 phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
2151
2165
2152 indValid = numpy.where(~numpy.isnan(phase1))[0]
2166 indValid = numpy.where(~numpy.isnan(phase1))[0]
2153 initMet = indValid[0]
2167 initMet = indValid[0]
2154 endMet = 0
2168 endMet = 0
2155
2169
2156 for i in range(len(indValid)-1):
2170 for i in range(len(indValid)-1):
2157
2171
2158 #Time difference
2172 #Time difference
2159 inow = indValid[i]
2173 inow = indValid[i]
2160 inext = indValid[i+1]
2174 inext = indValid[i+1]
2161 idiff = inext - inow
2175 idiff = inext - inow
2162 #Phase difference
2176 #Phase difference
2163 phDiff = numpy.abs(phase1[inext] - phase1[inow])
2177 phDiff = numpy.abs(phase1[inext] - phase1[inow])
2164
2178
2165 if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
2179 if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
2166 sizeTrail = inow - initMet + 1
2180 sizeTrail = inow - initMet + 1
2167 if sizeTrail>3*sec: #Too short meteors
2181 if sizeTrail>3*sec: #Too short meteors
2168 x = numpy.arange(initMet,inow+1)*ippSeconds
2182 x = numpy.arange(initMet,inow+1)*ippSeconds
2169 y = phase1[initMet:inow+1]
2183 y = phase1[initMet:inow+1]
2170 ynnan = ~numpy.isnan(y)
2184 ynnan = ~numpy.isnan(y)
2171 x = x[ynnan]
2185 x = x[ynnan]
2172 y = y[ynnan]
2186 y = y[ynnan]
2173 slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
2187 slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
2174 ylin = x*slope + intercept
2188 ylin = x*slope + intercept
2175 rsq = r_value**2
2189 rsq = r_value**2
2176 if rsq > 0.5:
2190 if rsq > 0.5:
2177 vel = slope#*height*1000/(k*d)
2191 vel = slope#*height*1000/(k*d)
2178 estAux = numpy.array([utctime,p,height, vel, rsq])
2192 estAux = numpy.array([utctime,p,height, vel, rsq])
2179 meteorList.append(estAux)
2193 meteorList.append(estAux)
2180 initMet = inext
2194 initMet = inext
2181 metArray2 = numpy.array(meteorList)
2195 metArray2 = numpy.array(meteorList)
2182
2196
2183 return metArray2
2197 return metArray2
2184
2198
2185 def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
2199 def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
2186
2200
2187 azimuth1 = numpy.zeros(len(pairslist))
2201 azimuth1 = numpy.zeros(len(pairslist))
2188 dist = numpy.zeros(len(pairslist))
2202 dist = numpy.zeros(len(pairslist))
2189
2203
2190 for i in range(len(rx_location)):
2204 for i in range(len(rx_location)):
2191 ch0 = pairslist[i][0]
2205 ch0 = pairslist[i][0]
2192 ch1 = pairslist[i][1]
2206 ch1 = pairslist[i][1]
2193
2207
2194 diffX = rx_location[ch0][0] - rx_location[ch1][0]
2208 diffX = rx_location[ch0][0] - rx_location[ch1][0]
2195 diffY = rx_location[ch0][1] - rx_location[ch1][1]
2209 diffY = rx_location[ch0][1] - rx_location[ch1][1]
2196 azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
2210 azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
2197 dist[i] = numpy.sqrt(diffX**2 + diffY**2)
2211 dist[i] = numpy.sqrt(diffX**2 + diffY**2)
2198
2212
2199 azimuth1 -= azimuth0
2213 azimuth1 -= azimuth0
2200 return azimuth1, dist
2214 return azimuth1, dist
2201
2215
2202 def techniqueNSM_DBS(self, **kwargs):
2216 def techniqueNSM_DBS(self, **kwargs):
2203 metArray = kwargs['metArray']
2217 metArray = kwargs['metArray']
2204 heightList = kwargs['heightList']
2218 heightList = kwargs['heightList']
2205 timeList = kwargs['timeList']
2219 timeList = kwargs['timeList']
2206 azimuth = kwargs['azimuth']
2220 azimuth = kwargs['azimuth']
2207 theta_x = numpy.array(kwargs['theta_x'])
2221 theta_x = numpy.array(kwargs['theta_x'])
2208 theta_y = numpy.array(kwargs['theta_y'])
2222 theta_y = numpy.array(kwargs['theta_y'])
2209
2223
2210 utctime = metArray[:,0]
2224 utctime = metArray[:,0]
2211 cmet = metArray[:,1].astype(int)
2225 cmet = metArray[:,1].astype(int)
2212 hmet = metArray[:,3].astype(int)
2226 hmet = metArray[:,3].astype(int)
2213 SNRmet = metArray[:,4]
2227 SNRmet = metArray[:,4]
2214 vmet = metArray[:,5]
2228 vmet = metArray[:,5]
2215 spcmet = metArray[:,6]
2229 spcmet = metArray[:,6]
2216
2230
2217 nChan = numpy.max(cmet) + 1
2231 nChan = numpy.max(cmet) + 1
2218 nHeights = len(heightList)
2232 nHeights = len(heightList)
2219
2233
2220 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
2234 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
2221 hmet = heightList[hmet]
2235 hmet = heightList[hmet]
2222 h1met = hmet*numpy.cos(zenith_arr[cmet]) #Corrected heights
2236 h1met = hmet*numpy.cos(zenith_arr[cmet]) #Corrected heights
2223
2237
2224 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2238 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2225
2239
2226 for i in range(nHeights - 1):
2240 for i in range(nHeights - 1):
2227 hmin = heightList[i]
2241 hmin = heightList[i]
2228 hmax = heightList[i + 1]
2242 hmax = heightList[i + 1]
2229
2243
2230 thisH = (h1met>=hmin) & (h1met<hmax) & (cmet!=2) & (SNRmet>8) & (vmet<50) & (spcmet<10)
2244 thisH = (h1met>=hmin) & (h1met<hmax) & (cmet!=2) & (SNRmet>8) & (vmet<50) & (spcmet<10)
2231 indthisH = numpy.where(thisH)
2245 indthisH = numpy.where(thisH)
2232
2246
2233 if numpy.size(indthisH) > 3:
2247 if numpy.size(indthisH) > 3:
2234
2248
2235 vel_aux = vmet[thisH]
2249 vel_aux = vmet[thisH]
2236 chan_aux = cmet[thisH]
2250 chan_aux = cmet[thisH]
2237 cosu_aux = dir_cosu[chan_aux]
2251 cosu_aux = dir_cosu[chan_aux]
2238 cosv_aux = dir_cosv[chan_aux]
2252 cosv_aux = dir_cosv[chan_aux]
2239 cosw_aux = dir_cosw[chan_aux]
2253 cosw_aux = dir_cosw[chan_aux]
2240
2254
2241 nch = numpy.size(numpy.unique(chan_aux))
2255 nch = numpy.size(numpy.unique(chan_aux))
2242 if nch > 1:
2256 if nch > 1:
2243 A = self.__calculateMatA(cosu_aux, cosv_aux, cosw_aux, True)
2257 A = self.__calculateMatA(cosu_aux, cosv_aux, cosw_aux, True)
2244 velEst[i,:] = numpy.dot(A,vel_aux)
2258 velEst[i,:] = numpy.dot(A,vel_aux)
2245
2259
2246 return velEst
2260 return velEst
2247
2261
2248 def run(self, dataOut, technique, nHours=1, hmin=70, hmax=110, **kwargs):
2262 def run(self, dataOut, technique, nHours=1, hmin=70, hmax=110, **kwargs):
2249
2263
2250 param = dataOut.data_param
2264 param = dataOut.data_param
2251 if dataOut.abscissaList != None:
2265 if dataOut.abscissaList != None:
2252 absc = dataOut.abscissaList[:-1]
2266 absc = dataOut.abscissaList[:-1]
2253 # noise = dataOut.noise
2267 # noise = dataOut.noise
2254 heightList = dataOut.heightList
2268 heightList = dataOut.heightList
2255 SNR = dataOut.data_SNR
2269 SNR = dataOut.data_SNR
2256
2270
2257 if technique == 'DBS':
2271 if technique == 'DBS':
2258
2272
2259 kwargs['velRadial'] = param[:,1,:] #Radial velocity
2273 kwargs['velRadial'] = param[:,1,:] #Radial velocity
2260 kwargs['heightList'] = heightList
2274 kwargs['heightList'] = heightList
2261 kwargs['SNR'] = SNR
2275 kwargs['SNR'] = SNR
2262
2276
2263 dataOut.data_output, dataOut.heightList, dataOut.data_SNR = self.techniqueDBS(kwargs) #DBS Function
2277 dataOut.data_output, dataOut.heightList, dataOut.data_SNR = self.techniqueDBS(kwargs) #DBS Function
2264 dataOut.utctimeInit = dataOut.utctime
2278 dataOut.utctimeInit = dataOut.utctime
2265 dataOut.outputInterval = dataOut.paramInterval
2279 dataOut.outputInterval = dataOut.paramInterval
2266
2280
2267 elif technique == 'SA':
2281 elif technique == 'SA':
2268
2282
2269 #Parameters
2283 #Parameters
2270 # position_x = kwargs['positionX']
2284 # position_x = kwargs['positionX']
2271 # position_y = kwargs['positionY']
2285 # position_y = kwargs['positionY']
2272 # azimuth = kwargs['azimuth']
2286 # azimuth = kwargs['azimuth']
2273 #
2287 #
2274 # if kwargs.has_key('crosspairsList'):
2288 # if kwargs.has_key('crosspairsList'):
2275 # pairs = kwargs['crosspairsList']
2289 # pairs = kwargs['crosspairsList']
2276 # else:
2290 # else:
2277 # pairs = None
2291 # pairs = None
2278 #
2292 #
2279 # if kwargs.has_key('correctFactor'):
2293 # if kwargs.has_key('correctFactor'):
2280 # correctFactor = kwargs['correctFactor']
2294 # correctFactor = kwargs['correctFactor']
2281 # else:
2295 # else:
2282 # correctFactor = 1
2296 # correctFactor = 1
2283
2297
2284 # tau = dataOut.data_param
2298 # tau = dataOut.data_param
2285 # _lambda = dataOut.C/dataOut.frequency
2299 # _lambda = dataOut.C/dataOut.frequency
2286 # pairsList = dataOut.groupList
2300 # pairsList = dataOut.groupList
2287 # nChannels = dataOut.nChannels
2301 # nChannels = dataOut.nChannels
2288
2302
2289 kwargs['groupList'] = dataOut.groupList
2303 kwargs['groupList'] = dataOut.groupList
2290 kwargs['tau'] = dataOut.data_param
2304 kwargs['tau'] = dataOut.data_param
2291 kwargs['_lambda'] = dataOut.C/dataOut.frequency
2305 kwargs['_lambda'] = dataOut.C/dataOut.frequency
2292 # dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
2306 # dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
2293 dataOut.data_output = self.techniqueSA(kwargs)
2307 dataOut.data_output = self.techniqueSA(kwargs)
2294 dataOut.utctimeInit = dataOut.utctime
2308 dataOut.utctimeInit = dataOut.utctime
2295 dataOut.outputInterval = dataOut.timeInterval
2309 dataOut.outputInterval = dataOut.timeInterval
2296
2310
2297 elif technique == 'Meteors':
2311 elif technique == 'Meteors':
2298 dataOut.flagNoData = True
2312 dataOut.flagNoData = True
2299 self.__dataReady = False
2313 self.__dataReady = False
2300
2314
2301 if 'nHours' in kwargs:
2315 if 'nHours' in kwargs:
2302 nHours = kwargs['nHours']
2316 nHours = kwargs['nHours']
2303 else:
2317 else:
2304 nHours = 1
2318 nHours = 1
2305
2319
2306 if 'meteorsPerBin' in kwargs:
2320 if 'meteorsPerBin' in kwargs:
2307 meteorThresh = kwargs['meteorsPerBin']
2321 meteorThresh = kwargs['meteorsPerBin']
2308 else:
2322 else:
2309 meteorThresh = 6
2323 meteorThresh = 6
2310
2324
2311 if 'hmin' in kwargs:
2325 if 'hmin' in kwargs:
2312 hmin = kwargs['hmin']
2326 hmin = kwargs['hmin']
2313 else: hmin = 70
2327 else: hmin = 70
2314 if 'hmax' in kwargs:
2328 if 'hmax' in kwargs:
2315 hmax = kwargs['hmax']
2329 hmax = kwargs['hmax']
2316 else: hmax = 110
2330 else: hmax = 110
2317
2331
2318 dataOut.outputInterval = nHours*3600
2332 dataOut.outputInterval = nHours*3600
2319
2333
2320 if self.__isConfig == False:
2334 if self.__isConfig == False:
2321 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2335 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2322 #Get Initial LTC time
2336 #Get Initial LTC time
2323 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2337 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2324 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2338 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2325
2339
2326 self.__isConfig = True
2340 self.__isConfig = True
2327
2341
2328 if self.__buffer is None:
2342 if self.__buffer is None:
2329 self.__buffer = dataOut.data_param
2343 self.__buffer = dataOut.data_param
2330 self.__firstdata = copy.copy(dataOut)
2344 self.__firstdata = copy.copy(dataOut)
2331
2345
2332 else:
2346 else:
2333 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2347 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2334
2348
2335 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2349 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2336
2350
2337 if self.__dataReady:
2351 if self.__dataReady:
2338 dataOut.utctimeInit = self.__initime
2352 dataOut.utctimeInit = self.__initime
2339
2353
2340 self.__initime += dataOut.outputInterval #to erase time offset
2354 self.__initime += dataOut.outputInterval #to erase time offset
2341
2355
2342 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
2356 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
2343 dataOut.flagNoData = False
2357 dataOut.flagNoData = False
2344 self.__buffer = None
2358 self.__buffer = None
2345
2359
2346 elif technique == 'Meteors1':
2360 elif technique == 'Meteors1':
2347 dataOut.flagNoData = True
2361 dataOut.flagNoData = True
2348 self.__dataReady = False
2362 self.__dataReady = False
2349
2363
2350 if 'nMins' in kwargs:
2364 if 'nMins' in kwargs:
2351 nMins = kwargs['nMins']
2365 nMins = kwargs['nMins']
2352 else: nMins = 20
2366 else: nMins = 20
2353 if 'rx_location' in kwargs:
2367 if 'rx_location' in kwargs:
2354 rx_location = kwargs['rx_location']
2368 rx_location = kwargs['rx_location']
2355 else: rx_location = [(0,1),(1,1),(1,0)]
2369 else: rx_location = [(0,1),(1,1),(1,0)]
2356 if 'azimuth' in kwargs:
2370 if 'azimuth' in kwargs:
2357 azimuth = kwargs['azimuth']
2371 azimuth = kwargs['azimuth']
2358 else: azimuth = 51.06
2372 else: azimuth = 51.06
2359 if 'dfactor' in kwargs:
2373 if 'dfactor' in kwargs:
2360 dfactor = kwargs['dfactor']
2374 dfactor = kwargs['dfactor']
2361 if 'mode' in kwargs:
2375 if 'mode' in kwargs:
2362 mode = kwargs['mode']
2376 mode = kwargs['mode']
2363 if 'theta_x' in kwargs:
2377 if 'theta_x' in kwargs:
2364 theta_x = kwargs['theta_x']
2378 theta_x = kwargs['theta_x']
2365 if 'theta_y' in kwargs:
2379 if 'theta_y' in kwargs:
2366 theta_y = kwargs['theta_y']
2380 theta_y = kwargs['theta_y']
2367 else: mode = 'SA'
2381 else: mode = 'SA'
2368
2382
2369 #Borrar luego esto
2383 #Borrar luego esto
2370 if dataOut.groupList is None:
2384 if dataOut.groupList is None:
2371 dataOut.groupList = [(0,1),(0,2),(1,2)]
2385 dataOut.groupList = [(0,1),(0,2),(1,2)]
2372 groupList = dataOut.groupList
2386 groupList = dataOut.groupList
2373 C = 3e8
2387 C = 3e8
2374 freq = 50e6
2388 freq = 50e6
2375 lamb = C/freq
2389 lamb = C/freq
2376 k = 2*numpy.pi/lamb
2390 k = 2*numpy.pi/lamb
2377
2391
2378 timeList = dataOut.abscissaList
2392 timeList = dataOut.abscissaList
2379 heightList = dataOut.heightList
2393 heightList = dataOut.heightList
2380
2394
2381 if self.__isConfig == False:
2395 if self.__isConfig == False:
2382 dataOut.outputInterval = nMins*60
2396 dataOut.outputInterval = nMins*60
2383 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2397 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2384 #Get Initial LTC time
2398 #Get Initial LTC time
2385 initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2399 initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2386 minuteAux = initime.minute
2400 minuteAux = initime.minute
2387 minuteNew = int(numpy.floor(minuteAux/nMins)*nMins)
2401 minuteNew = int(numpy.floor(minuteAux/nMins)*nMins)
2388 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2402 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2389
2403
2390 self.__isConfig = True
2404 self.__isConfig = True
2391
2405
2392 if self.__buffer is None:
2406 if self.__buffer is None:
2393 self.__buffer = dataOut.data_param
2407 self.__buffer = dataOut.data_param
2394 self.__firstdata = copy.copy(dataOut)
2408 self.__firstdata = copy.copy(dataOut)
2395
2409
2396 else:
2410 else:
2397 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2411 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2398
2412
2399 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2413 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2400
2414
2401 if self.__dataReady:
2415 if self.__dataReady:
2402 dataOut.utctimeInit = self.__initime
2416 dataOut.utctimeInit = self.__initime
2403 self.__initime += dataOut.outputInterval #to erase time offset
2417 self.__initime += dataOut.outputInterval #to erase time offset
2404
2418
2405 metArray = self.__buffer
2419 metArray = self.__buffer
2406 if mode == 'SA':
2420 if mode == 'SA':
2407 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
2421 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
2408 elif mode == 'DBS':
2422 elif mode == 'DBS':
2409 dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList, azimuth=azimuth, theta_x=theta_x, theta_y=theta_y)
2423 dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList, azimuth=azimuth, theta_x=theta_x, theta_y=theta_y)
2410 dataOut.data_output = dataOut.data_output.T
2424 dataOut.data_output = dataOut.data_output.T
2411 dataOut.flagNoData = False
2425 dataOut.flagNoData = False
2412 self.__buffer = None
2426 self.__buffer = None
2413
2427
2414 return
2428 return
2415
2429
2416 class EWDriftsEstimation(Operation):
2430 class EWDriftsEstimation(Operation):
2417
2431
2418 def __init__(self):
2432 def __init__(self):
2419 Operation.__init__(self)
2433 Operation.__init__(self)
2420
2434
2421 def __correctValues(self, heiRang, phi, velRadial, SNR):
2435 def __correctValues(self, heiRang, phi, velRadial, SNR):
2422 listPhi = phi.tolist()
2436 listPhi = phi.tolist()
2423 maxid = listPhi.index(max(listPhi))
2437 maxid = listPhi.index(max(listPhi))
2424 minid = listPhi.index(min(listPhi))
2438 minid = listPhi.index(min(listPhi))
2425
2439
2426 rango = list(range(len(phi)))
2440 rango = list(range(len(phi)))
2427 # rango = numpy.delete(rango,maxid)
2441 # rango = numpy.delete(rango,maxid)
2428
2442
2429 heiRang1 = heiRang*math.cos(phi[maxid])
2443 heiRang1 = heiRang*math.cos(phi[maxid])
2430 heiRangAux = heiRang*math.cos(phi[minid])
2444 heiRangAux = heiRang*math.cos(phi[minid])
2431 indOut = (heiRang1 < heiRangAux[0]).nonzero()
2445 indOut = (heiRang1 < heiRangAux[0]).nonzero()
2432 heiRang1 = numpy.delete(heiRang1,indOut)
2446 heiRang1 = numpy.delete(heiRang1,indOut)
2433
2447
2434 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
2448 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
2435 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
2449 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
2436
2450
2437 for i in rango:
2451 for i in rango:
2438 x = heiRang*math.cos(phi[i])
2452 x = heiRang*math.cos(phi[i])
2439 y1 = velRadial[i,:]
2453 y1 = velRadial[i,:]
2440 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
2454 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
2441
2455
2442 x1 = heiRang1
2456 x1 = heiRang1
2443 y11 = f1(x1)
2457 y11 = f1(x1)
2444
2458
2445 y2 = SNR[i,:]
2459 y2 = SNR[i,:]
2446 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
2460 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
2447 y21 = f2(x1)
2461 y21 = f2(x1)
2448
2462
2449 velRadial1[i,:] = y11
2463 velRadial1[i,:] = y11
2450 SNR1[i,:] = y21
2464 SNR1[i,:] = y21
2451
2465
2452 return heiRang1, velRadial1, SNR1
2466 return heiRang1, velRadial1, SNR1
2453
2467
2454 def run(self, dataOut, zenith, zenithCorrection):
2468 def run(self, dataOut, zenith, zenithCorrection):
2455 heiRang = dataOut.heightList
2469 heiRang = dataOut.heightList
2456 velRadial = dataOut.data_param[:,3,:]
2470 velRadial = dataOut.data_param[:,3,:]
2457 SNR = dataOut.data_SNR
2471 SNR = dataOut.data_SNR
2458
2472
2459 zenith = numpy.array(zenith)
2473 zenith = numpy.array(zenith)
2460 zenith -= zenithCorrection
2474 zenith -= zenithCorrection
2461 zenith *= numpy.pi/180
2475 zenith *= numpy.pi/180
2462
2476
2463 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
2477 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
2464
2478
2465 alp = zenith[0]
2479 alp = zenith[0]
2466 bet = zenith[1]
2480 bet = zenith[1]
2467
2481
2468 w_w = velRadial1[0,:]
2482 w_w = velRadial1[0,:]
2469 w_e = velRadial1[1,:]
2483 w_e = velRadial1[1,:]
2470
2484
2471 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
2485 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
2472 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
2486 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
2473
2487
2474 winds = numpy.vstack((u,w))
2488 winds = numpy.vstack((u,w))
2475
2489
2476 dataOut.heightList = heiRang1
2490 dataOut.heightList = heiRang1
2477 dataOut.data_output = winds
2491 dataOut.data_output = winds
2478 dataOut.data_SNR = SNR1
2492 dataOut.data_SNR = SNR1
2479
2493
2480 dataOut.utctimeInit = dataOut.utctime
2494 dataOut.utctimeInit = dataOut.utctime
2481 dataOut.outputInterval = dataOut.timeInterval
2495 dataOut.outputInterval = dataOut.timeInterval
2482 return
2496 return
2483
2497
2484 #--------------- Non Specular Meteor ----------------
2498 #--------------- Non Specular Meteor ----------------
2485
2499
2486 class NonSpecularMeteorDetection(Operation):
2500 class NonSpecularMeteorDetection(Operation):
2487
2501
2488 def run(self, dataOut, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False):
2502 def run(self, dataOut, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False):
2489 data_acf = dataOut.data_pre[0]
2503 data_acf = dataOut.data_pre[0]
2490 data_ccf = dataOut.data_pre[1]
2504 data_ccf = dataOut.data_pre[1]
2491 pairsList = dataOut.groupList[1]
2505 pairsList = dataOut.groupList[1]
2492
2506
2493 lamb = dataOut.C/dataOut.frequency
2507 lamb = dataOut.C/dataOut.frequency
2494 tSamp = dataOut.ippSeconds*dataOut.nCohInt
2508 tSamp = dataOut.ippSeconds*dataOut.nCohInt
2495 paramInterval = dataOut.paramInterval
2509 paramInterval = dataOut.paramInterval
2496
2510
2497 nChannels = data_acf.shape[0]
2511 nChannels = data_acf.shape[0]
2498 nLags = data_acf.shape[1]
2512 nLags = data_acf.shape[1]
2499 nProfiles = data_acf.shape[2]
2513 nProfiles = data_acf.shape[2]
2500 nHeights = dataOut.nHeights
2514 nHeights = dataOut.nHeights
2501 nCohInt = dataOut.nCohInt
2515 nCohInt = dataOut.nCohInt
2502 sec = numpy.round(nProfiles/dataOut.paramInterval)
2516 sec = numpy.round(nProfiles/dataOut.paramInterval)
2503 heightList = dataOut.heightList
2517 heightList = dataOut.heightList
2504 ippSeconds = dataOut.ippSeconds*dataOut.nCohInt*dataOut.nAvg
2518 ippSeconds = dataOut.ippSeconds*dataOut.nCohInt*dataOut.nAvg
2505 utctime = dataOut.utctime
2519 utctime = dataOut.utctime
2506
2520
2507 dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
2521 dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
2508
2522
2509 #------------------------ SNR --------------------------------------
2523 #------------------------ SNR --------------------------------------
2510 power = data_acf[:,0,:,:].real
2524 power = data_acf[:,0,:,:].real
2511 noise = numpy.zeros(nChannels)
2525 noise = numpy.zeros(nChannels)
2512 SNR = numpy.zeros(power.shape)
2526 SNR = numpy.zeros(power.shape)
2513 for i in range(nChannels):
2527 for i in range(nChannels):
2514 noise[i] = hildebrand_sekhon(power[i,:], nCohInt)
2528 noise[i] = hildebrand_sekhon(power[i,:], nCohInt)
2515 SNR[i] = (power[i]-noise[i])/noise[i]
2529 SNR[i] = (power[i]-noise[i])/noise[i]
2516 SNRm = numpy.nanmean(SNR, axis = 0)
2530 SNRm = numpy.nanmean(SNR, axis = 0)
2517 SNRdB = 10*numpy.log10(SNR)
2531 SNRdB = 10*numpy.log10(SNR)
2518
2532
2519 if mode == 'SA':
2533 if mode == 'SA':
2520 dataOut.groupList = dataOut.groupList[1]
2534 dataOut.groupList = dataOut.groupList[1]
2521 nPairs = data_ccf.shape[0]
2535 nPairs = data_ccf.shape[0]
2522 #---------------------- Coherence and Phase --------------------------
2536 #---------------------- Coherence and Phase --------------------------
2523 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
2537 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
2524 # phase1 = numpy.copy(phase)
2538 # phase1 = numpy.copy(phase)
2525 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
2539 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
2526
2540
2527 for p in range(nPairs):
2541 for p in range(nPairs):
2528 ch0 = pairsList[p][0]
2542 ch0 = pairsList[p][0]
2529 ch1 = pairsList[p][1]
2543 ch1 = pairsList[p][1]
2530 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
2544 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
2531 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
2545 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
2532 # phase1[p,:,:] = numpy.angle(ccf) #median filter
2546 # phase1[p,:,:] = numpy.angle(ccf) #median filter
2533 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
2547 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
2534 # coh1[p,:,:] = numpy.abs(ccf) #median filter
2548 # coh1[p,:,:] = numpy.abs(ccf) #median filter
2535 coh = numpy.nanmax(coh1, axis = 0)
2549 coh = numpy.nanmax(coh1, axis = 0)
2536 # struc = numpy.ones((5,1))
2550 # struc = numpy.ones((5,1))
2537 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
2551 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
2538 #---------------------- Radial Velocity ----------------------------
2552 #---------------------- Radial Velocity ----------------------------
2539 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
2553 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
2540 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
2554 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
2541
2555
2542 if allData:
2556 if allData:
2543 boolMetFin = ~numpy.isnan(SNRm)
2557 boolMetFin = ~numpy.isnan(SNRm)
2544 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2558 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2545 else:
2559 else:
2546 #------------------------ Meteor mask ---------------------------------
2560 #------------------------ Meteor mask ---------------------------------
2547 # #SNR mask
2561 # #SNR mask
2548 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
2562 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
2549 #
2563 #
2550 # #Erase small objects
2564 # #Erase small objects
2551 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
2565 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
2552 #
2566 #
2553 # auxEEJ = numpy.sum(boolMet1,axis=0)
2567 # auxEEJ = numpy.sum(boolMet1,axis=0)
2554 # indOver = auxEEJ>nProfiles*0.8 #Use this later
2568 # indOver = auxEEJ>nProfiles*0.8 #Use this later
2555 # indEEJ = numpy.where(indOver)[0]
2569 # indEEJ = numpy.where(indOver)[0]
2556 # indNEEJ = numpy.where(~indOver)[0]
2570 # indNEEJ = numpy.where(~indOver)[0]
2557 #
2571 #
2558 # boolMetFin = boolMet1
2572 # boolMetFin = boolMet1
2559 #
2573 #
2560 # if indEEJ.size > 0:
2574 # if indEEJ.size > 0:
2561 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
2575 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
2562 #
2576 #
2563 # boolMet2 = coh > cohThresh
2577 # boolMet2 = coh > cohThresh
2564 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
2578 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
2565 #
2579 #
2566 # #Final Meteor mask
2580 # #Final Meteor mask
2567 # boolMetFin = boolMet1|boolMet2
2581 # boolMetFin = boolMet1|boolMet2
2568
2582
2569 #Coherence mask
2583 #Coherence mask
2570 boolMet1 = coh > 0.75
2584 boolMet1 = coh > 0.75
2571 struc = numpy.ones((30,1))
2585 struc = numpy.ones((30,1))
2572 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
2586 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
2573
2587
2574 #Derivative mask
2588 #Derivative mask
2575 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2589 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2576 boolMet2 = derPhase < 0.2
2590 boolMet2 = derPhase < 0.2
2577 # boolMet2 = ndimage.morphology.binary_opening(boolMet2)
2591 # boolMet2 = ndimage.morphology.binary_opening(boolMet2)
2578 # boolMet2 = ndimage.morphology.binary_closing(boolMet2, structure = numpy.ones((10,1)))
2592 # boolMet2 = ndimage.morphology.binary_closing(boolMet2, structure = numpy.ones((10,1)))
2579 boolMet2 = ndimage.median_filter(boolMet2,size=5)
2593 boolMet2 = ndimage.median_filter(boolMet2,size=5)
2580 boolMet2 = numpy.vstack((boolMet2,numpy.full((1,nHeights), True, dtype=bool)))
2594 boolMet2 = numpy.vstack((boolMet2,numpy.full((1,nHeights), True, dtype=bool)))
2581 # #Final mask
2595 # #Final mask
2582 # boolMetFin = boolMet2
2596 # boolMetFin = boolMet2
2583 boolMetFin = boolMet1&boolMet2
2597 boolMetFin = boolMet1&boolMet2
2584 # boolMetFin = ndimage.morphology.binary_dilation(boolMetFin)
2598 # boolMetFin = ndimage.morphology.binary_dilation(boolMetFin)
2585 #Creating data_param
2599 #Creating data_param
2586 coordMet = numpy.where(boolMetFin)
2600 coordMet = numpy.where(boolMetFin)
2587
2601
2588 tmet = coordMet[0]
2602 tmet = coordMet[0]
2589 hmet = coordMet[1]
2603 hmet = coordMet[1]
2590
2604
2591 data_param = numpy.zeros((tmet.size, 6 + nPairs))
2605 data_param = numpy.zeros((tmet.size, 6 + nPairs))
2592 data_param[:,0] = utctime
2606 data_param[:,0] = utctime
2593 data_param[:,1] = tmet
2607 data_param[:,1] = tmet
2594 data_param[:,2] = hmet
2608 data_param[:,2] = hmet
2595 data_param[:,3] = SNRm[tmet,hmet]
2609 data_param[:,3] = SNRm[tmet,hmet]
2596 data_param[:,4] = velRad[tmet,hmet]
2610 data_param[:,4] = velRad[tmet,hmet]
2597 data_param[:,5] = coh[tmet,hmet]
2611 data_param[:,5] = coh[tmet,hmet]
2598 data_param[:,6:] = phase[:,tmet,hmet].T
2612 data_param[:,6:] = phase[:,tmet,hmet].T
2599
2613
2600 elif mode == 'DBS':
2614 elif mode == 'DBS':
2601 dataOut.groupList = numpy.arange(nChannels)
2615 dataOut.groupList = numpy.arange(nChannels)
2602
2616
2603 #Radial Velocities
2617 #Radial Velocities
2604 phase = numpy.angle(data_acf[:,1,:,:])
2618 phase = numpy.angle(data_acf[:,1,:,:])
2605 # phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
2619 # phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
2606 velRad = phase*lamb/(4*numpy.pi*tSamp)
2620 velRad = phase*lamb/(4*numpy.pi*tSamp)
2607
2621
2608 #Spectral width
2622 #Spectral width
2609 # acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
2623 # acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
2610 # acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
2624 # acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
2611 acf1 = data_acf[:,1,:,:]
2625 acf1 = data_acf[:,1,:,:]
2612 acf2 = data_acf[:,2,:,:]
2626 acf2 = data_acf[:,2,:,:]
2613
2627
2614 spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2))
2628 spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2))
2615 # velRad = ndimage.median_filter(velRad, size = (1,5,1))
2629 # velRad = ndimage.median_filter(velRad, size = (1,5,1))
2616 if allData:
2630 if allData:
2617 boolMetFin = ~numpy.isnan(SNRdB)
2631 boolMetFin = ~numpy.isnan(SNRdB)
2618 else:
2632 else:
2619 #SNR
2633 #SNR
2620 boolMet1 = (SNRdB>SNRthresh) #SNR mask
2634 boolMet1 = (SNRdB>SNRthresh) #SNR mask
2621 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
2635 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
2622
2636
2623 #Radial velocity
2637 #Radial velocity
2624 boolMet2 = numpy.abs(velRad) < 20
2638 boolMet2 = numpy.abs(velRad) < 20
2625 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
2639 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
2626
2640
2627 #Spectral Width
2641 #Spectral Width
2628 boolMet3 = spcWidth < 30
2642 boolMet3 = spcWidth < 30
2629 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
2643 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
2630 # boolMetFin = self.__erase_small(boolMet1, 10,5)
2644 # boolMetFin = self.__erase_small(boolMet1, 10,5)
2631 boolMetFin = boolMet1&boolMet2&boolMet3
2645 boolMetFin = boolMet1&boolMet2&boolMet3
2632
2646
2633 #Creating data_param
2647 #Creating data_param
2634 coordMet = numpy.where(boolMetFin)
2648 coordMet = numpy.where(boolMetFin)
2635
2649
2636 cmet = coordMet[0]
2650 cmet = coordMet[0]
2637 tmet = coordMet[1]
2651 tmet = coordMet[1]
2638 hmet = coordMet[2]
2652 hmet = coordMet[2]
2639
2653
2640 data_param = numpy.zeros((tmet.size, 7))
2654 data_param = numpy.zeros((tmet.size, 7))
2641 data_param[:,0] = utctime
2655 data_param[:,0] = utctime
2642 data_param[:,1] = cmet
2656 data_param[:,1] = cmet
2643 data_param[:,2] = tmet
2657 data_param[:,2] = tmet
2644 data_param[:,3] = hmet
2658 data_param[:,3] = hmet
2645 data_param[:,4] = SNR[cmet,tmet,hmet].T
2659 data_param[:,4] = SNR[cmet,tmet,hmet].T
2646 data_param[:,5] = velRad[cmet,tmet,hmet].T
2660 data_param[:,5] = velRad[cmet,tmet,hmet].T
2647 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
2661 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
2648
2662
2649 # self.dataOut.data_param = data_int
2663 # self.dataOut.data_param = data_int
2650 if len(data_param) == 0:
2664 if len(data_param) == 0:
2651 dataOut.flagNoData = True
2665 dataOut.flagNoData = True
2652 else:
2666 else:
2653 dataOut.data_param = data_param
2667 dataOut.data_param = data_param
2654
2668
2655 def __erase_small(self, binArray, threshX, threshY):
2669 def __erase_small(self, binArray, threshX, threshY):
2656 labarray, numfeat = ndimage.measurements.label(binArray)
2670 labarray, numfeat = ndimage.measurements.label(binArray)
2657 binArray1 = numpy.copy(binArray)
2671 binArray1 = numpy.copy(binArray)
2658
2672
2659 for i in range(1,numfeat + 1):
2673 for i in range(1,numfeat + 1):
2660 auxBin = (labarray==i)
2674 auxBin = (labarray==i)
2661 auxSize = auxBin.sum()
2675 auxSize = auxBin.sum()
2662
2676
2663 x,y = numpy.where(auxBin)
2677 x,y = numpy.where(auxBin)
2664 widthX = x.max() - x.min()
2678 widthX = x.max() - x.min()
2665 widthY = y.max() - y.min()
2679 widthY = y.max() - y.min()
2666
2680
2667 #width X: 3 seg -> 12.5*3
2681 #width X: 3 seg -> 12.5*3
2668 #width Y:
2682 #width Y:
2669
2683
2670 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
2684 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
2671 binArray1[auxBin] = False
2685 binArray1[auxBin] = False
2672
2686
2673 return binArray1
2687 return binArray1
2674
2688
2675 #--------------- Specular Meteor ----------------
2689 #--------------- Specular Meteor ----------------
2676
2690
2677 class SMDetection(Operation):
2691 class SMDetection(Operation):
2678 '''
2692 '''
2679 Function DetectMeteors()
2693 Function DetectMeteors()
2680 Project developed with paper:
2694 Project developed with paper:
2681 HOLDSWORTH ET AL. 2004
2695 HOLDSWORTH ET AL. 2004
2682
2696
2683 Input:
2697 Input:
2684 self.dataOut.data_pre
2698 self.dataOut.data_pre
2685
2699
2686 centerReceiverIndex: From the channels, which is the center receiver
2700 centerReceiverIndex: From the channels, which is the center receiver
2687
2701
2688 hei_ref: Height reference for the Beacon signal extraction
2702 hei_ref: Height reference for the Beacon signal extraction
2689 tauindex:
2703 tauindex:
2690 predefinedPhaseShifts: Predefined phase offset for the voltge signals
2704 predefinedPhaseShifts: Predefined phase offset for the voltge signals
2691
2705
2692 cohDetection: Whether to user Coherent detection or not
2706 cohDetection: Whether to user Coherent detection or not
2693 cohDet_timeStep: Coherent Detection calculation time step
2707 cohDet_timeStep: Coherent Detection calculation time step
2694 cohDet_thresh: Coherent Detection phase threshold to correct phases
2708 cohDet_thresh: Coherent Detection phase threshold to correct phases
2695
2709
2696 noise_timeStep: Noise calculation time step
2710 noise_timeStep: Noise calculation time step
2697 noise_multiple: Noise multiple to define signal threshold
2711 noise_multiple: Noise multiple to define signal threshold
2698
2712
2699 multDet_timeLimit: Multiple Detection Removal time limit in seconds
2713 multDet_timeLimit: Multiple Detection Removal time limit in seconds
2700 multDet_rangeLimit: Multiple Detection Removal range limit in km
2714 multDet_rangeLimit: Multiple Detection Removal range limit in km
2701
2715
2702 phaseThresh: Maximum phase difference between receiver to be consider a meteor
2716 phaseThresh: Maximum phase difference between receiver to be consider a meteor
2703 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
2717 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
2704
2718
2705 hmin: Minimum Height of the meteor to use it in the further wind estimations
2719 hmin: Minimum Height of the meteor to use it in the further wind estimations
2706 hmax: Maximum Height of the meteor to use it in the further wind estimations
2720 hmax: Maximum Height of the meteor to use it in the further wind estimations
2707 azimuth: Azimuth angle correction
2721 azimuth: Azimuth angle correction
2708
2722
2709 Affected:
2723 Affected:
2710 self.dataOut.data_param
2724 self.dataOut.data_param
2711
2725
2712 Rejection Criteria (Errors):
2726 Rejection Criteria (Errors):
2713 0: No error; analysis OK
2727 0: No error; analysis OK
2714 1: SNR < SNR threshold
2728 1: SNR < SNR threshold
2715 2: angle of arrival (AOA) ambiguously determined
2729 2: angle of arrival (AOA) ambiguously determined
2716 3: AOA estimate not feasible
2730 3: AOA estimate not feasible
2717 4: Large difference in AOAs obtained from different antenna baselines
2731 4: Large difference in AOAs obtained from different antenna baselines
2718 5: echo at start or end of time series
2732 5: echo at start or end of time series
2719 6: echo less than 5 examples long; too short for analysis
2733 6: echo less than 5 examples long; too short for analysis
2720 7: echo rise exceeds 0.3s
2734 7: echo rise exceeds 0.3s
2721 8: echo decay time less than twice rise time
2735 8: echo decay time less than twice rise time
2722 9: large power level before echo
2736 9: large power level before echo
2723 10: large power level after echo
2737 10: large power level after echo
2724 11: poor fit to amplitude for estimation of decay time
2738 11: poor fit to amplitude for estimation of decay time
2725 12: poor fit to CCF phase variation for estimation of radial drift velocity
2739 12: poor fit to CCF phase variation for estimation of radial drift velocity
2726 13: height unresolvable echo: not valid height within 70 to 110 km
2740 13: height unresolvable echo: not valid height within 70 to 110 km
2727 14: height ambiguous echo: more then one possible height within 70 to 110 km
2741 14: height ambiguous echo: more then one possible height within 70 to 110 km
2728 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
2742 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
2729 16: oscilatory echo, indicating event most likely not an underdense echo
2743 16: oscilatory echo, indicating event most likely not an underdense echo
2730
2744
2731 17: phase difference in meteor Reestimation
2745 17: phase difference in meteor Reestimation
2732
2746
2733 Data Storage:
2747 Data Storage:
2734 Meteors for Wind Estimation (8):
2748 Meteors for Wind Estimation (8):
2735 Utc Time | Range Height
2749 Utc Time | Range Height
2736 Azimuth Zenith errorCosDir
2750 Azimuth Zenith errorCosDir
2737 VelRad errorVelRad
2751 VelRad errorVelRad
2738 Phase0 Phase1 Phase2 Phase3
2752 Phase0 Phase1 Phase2 Phase3
2739 TypeError
2753 TypeError
2740
2754
2741 '''
2755 '''
2742
2756
2743 def run(self, dataOut, hei_ref = None, tauindex = 0,
2757 def run(self, dataOut, hei_ref = None, tauindex = 0,
2744 phaseOffsets = None,
2758 phaseOffsets = None,
2745 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
2759 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
2746 noise_timeStep = 4, noise_multiple = 4,
2760 noise_timeStep = 4, noise_multiple = 4,
2747 multDet_timeLimit = 1, multDet_rangeLimit = 3,
2761 multDet_timeLimit = 1, multDet_rangeLimit = 3,
2748 phaseThresh = 20, SNRThresh = 5,
2762 phaseThresh = 20, SNRThresh = 5,
2749 hmin = 50, hmax=150, azimuth = 0,
2763 hmin = 50, hmax=150, azimuth = 0,
2750 channelPositions = None) :
2764 channelPositions = None) :
2751
2765
2752
2766
2753 #Getting Pairslist
2767 #Getting Pairslist
2754 if channelPositions is None:
2768 if channelPositions is None:
2755 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2769 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2756 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2770 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2757 meteorOps = SMOperations()
2771 meteorOps = SMOperations()
2758 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2772 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2759 heiRang = dataOut.getHeiRange()
2773 heiRang = dataOut.getHeiRange()
2760 #Get Beacon signal - No Beacon signal anymore
2774 #Get Beacon signal - No Beacon signal anymore
2761 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
2775 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
2762 #
2776 #
2763 # if hei_ref != None:
2777 # if hei_ref != None:
2764 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
2778 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
2765 #
2779 #
2766
2780
2767
2781
2768 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
2782 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
2769 # see if the user put in pre defined phase shifts
2783 # see if the user put in pre defined phase shifts
2770 voltsPShift = dataOut.data_pre.copy()
2784 voltsPShift = dataOut.data_pre.copy()
2771
2785
2772 # if predefinedPhaseShifts != None:
2786 # if predefinedPhaseShifts != None:
2773 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
2787 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
2774 #
2788 #
2775 # # elif beaconPhaseShifts:
2789 # # elif beaconPhaseShifts:
2776 # # #get hardware phase shifts using beacon signal
2790 # # #get hardware phase shifts using beacon signal
2777 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
2791 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
2778 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
2792 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
2779 #
2793 #
2780 # else:
2794 # else:
2781 # hardwarePhaseShifts = numpy.zeros(5)
2795 # hardwarePhaseShifts = numpy.zeros(5)
2782 #
2796 #
2783 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
2797 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
2784 # for i in range(self.dataOut.data_pre.shape[0]):
2798 # for i in range(self.dataOut.data_pre.shape[0]):
2785 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
2799 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
2786
2800
2787 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
2801 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
2788
2802
2789 #Remove DC
2803 #Remove DC
2790 voltsDC = numpy.mean(voltsPShift,1)
2804 voltsDC = numpy.mean(voltsPShift,1)
2791 voltsDC = numpy.mean(voltsDC,1)
2805 voltsDC = numpy.mean(voltsDC,1)
2792 for i in range(voltsDC.shape[0]):
2806 for i in range(voltsDC.shape[0]):
2793 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
2807 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
2794
2808
2795 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
2809 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
2796 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
2810 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
2797
2811
2798 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
2812 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
2799 #Coherent Detection
2813 #Coherent Detection
2800 if cohDetection:
2814 if cohDetection:
2801 #use coherent detection to get the net power
2815 #use coherent detection to get the net power
2802 cohDet_thresh = cohDet_thresh*numpy.pi/180
2816 cohDet_thresh = cohDet_thresh*numpy.pi/180
2803 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
2817 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
2804
2818
2805 #Non-coherent detection!
2819 #Non-coherent detection!
2806 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
2820 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
2807 #********** END OF COH/NON-COH POWER CALCULATION**********************
2821 #********** END OF COH/NON-COH POWER CALCULATION**********************
2808
2822
2809 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
2823 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
2810 #Get noise
2824 #Get noise
2811 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
2825 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
2812 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
2826 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
2813 #Get signal threshold
2827 #Get signal threshold
2814 signalThresh = noise_multiple*noise
2828 signalThresh = noise_multiple*noise
2815 #Meteor echoes detection
2829 #Meteor echoes detection
2816 listMeteors = self.__findMeteors(powerNet, signalThresh)
2830 listMeteors = self.__findMeteors(powerNet, signalThresh)
2817 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
2831 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
2818
2832
2819 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
2833 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
2820 #Parameters
2834 #Parameters
2821 heiRange = dataOut.getHeiRange()
2835 heiRange = dataOut.getHeiRange()
2822 rangeInterval = heiRange[1] - heiRange[0]
2836 rangeInterval = heiRange[1] - heiRange[0]
2823 rangeLimit = multDet_rangeLimit/rangeInterval
2837 rangeLimit = multDet_rangeLimit/rangeInterval
2824 timeLimit = multDet_timeLimit/dataOut.timeInterval
2838 timeLimit = multDet_timeLimit/dataOut.timeInterval
2825 #Multiple detection removals
2839 #Multiple detection removals
2826 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
2840 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
2827 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
2841 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
2828
2842
2829 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
2843 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
2830 #Parameters
2844 #Parameters
2831 phaseThresh = phaseThresh*numpy.pi/180
2845 phaseThresh = phaseThresh*numpy.pi/180
2832 thresh = [phaseThresh, noise_multiple, SNRThresh]
2846 thresh = [phaseThresh, noise_multiple, SNRThresh]
2833 #Meteor reestimation (Errors N 1, 6, 12, 17)
2847 #Meteor reestimation (Errors N 1, 6, 12, 17)
2834 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist0, thresh, noise, dataOut.timeInterval, dataOut.frequency)
2848 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist0, thresh, noise, dataOut.timeInterval, dataOut.frequency)
2835 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
2849 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
2836 #Estimation of decay times (Errors N 7, 8, 11)
2850 #Estimation of decay times (Errors N 7, 8, 11)
2837 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
2851 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
2838 #******************* END OF METEOR REESTIMATION *******************
2852 #******************* END OF METEOR REESTIMATION *******************
2839
2853
2840 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
2854 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
2841 #Calculating Radial Velocity (Error N 15)
2855 #Calculating Radial Velocity (Error N 15)
2842 radialStdThresh = 10
2856 radialStdThresh = 10
2843 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
2857 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
2844
2858
2845 if len(listMeteors4) > 0:
2859 if len(listMeteors4) > 0:
2846 #Setting New Array
2860 #Setting New Array
2847 date = dataOut.utctime
2861 date = dataOut.utctime
2848 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
2862 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
2849
2863
2850 #Correcting phase offset
2864 #Correcting phase offset
2851 if phaseOffsets != None:
2865 if phaseOffsets != None:
2852 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2866 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2853 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2867 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2854
2868
2855 #Second Pairslist
2869 #Second Pairslist
2856 pairsList = []
2870 pairsList = []
2857 pairx = (0,1)
2871 pairx = (0,1)
2858 pairy = (2,3)
2872 pairy = (2,3)
2859 pairsList.append(pairx)
2873 pairsList.append(pairx)
2860 pairsList.append(pairy)
2874 pairsList.append(pairy)
2861
2875
2862 jph = numpy.array([0,0,0,0])
2876 jph = numpy.array([0,0,0,0])
2863 h = (hmin,hmax)
2877 h = (hmin,hmax)
2864 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2878 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2865
2879
2866 # #Calculate AOA (Error N 3, 4)
2880 # #Calculate AOA (Error N 3, 4)
2867 # #JONES ET AL. 1998
2881 # #JONES ET AL. 1998
2868 # error = arrayParameters[:,-1]
2882 # error = arrayParameters[:,-1]
2869 # AOAthresh = numpy.pi/8
2883 # AOAthresh = numpy.pi/8
2870 # phases = -arrayParameters[:,9:13]
2884 # phases = -arrayParameters[:,9:13]
2871 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
2885 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
2872 #
2886 #
2873 # #Calculate Heights (Error N 13 and 14)
2887 # #Calculate Heights (Error N 13 and 14)
2874 # error = arrayParameters[:,-1]
2888 # error = arrayParameters[:,-1]
2875 # Ranges = arrayParameters[:,2]
2889 # Ranges = arrayParameters[:,2]
2876 # zenith = arrayParameters[:,5]
2890 # zenith = arrayParameters[:,5]
2877 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
2891 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
2878 # error = arrayParameters[:,-1]
2892 # error = arrayParameters[:,-1]
2879 #********************* END OF PARAMETERS CALCULATION **************************
2893 #********************* END OF PARAMETERS CALCULATION **************************
2880
2894
2881 #***************************+ PASS DATA TO NEXT STEP **********************
2895 #***************************+ PASS DATA TO NEXT STEP **********************
2882 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
2896 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
2883 dataOut.data_param = arrayParameters
2897 dataOut.data_param = arrayParameters
2884
2898
2885 if arrayParameters is None:
2899 if arrayParameters is None:
2886 dataOut.flagNoData = True
2900 dataOut.flagNoData = True
2887 else:
2901 else:
2888 dataOut.flagNoData = True
2902 dataOut.flagNoData = True
2889
2903
2890 return
2904 return
2891
2905
2892 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
2906 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
2893
2907
2894 minIndex = min(newheis[0])
2908 minIndex = min(newheis[0])
2895 maxIndex = max(newheis[0])
2909 maxIndex = max(newheis[0])
2896
2910
2897 voltage = voltage0[:,:,minIndex:maxIndex+1]
2911 voltage = voltage0[:,:,minIndex:maxIndex+1]
2898 nLength = voltage.shape[1]/n
2912 nLength = voltage.shape[1]/n
2899 nMin = 0
2913 nMin = 0
2900 nMax = 0
2914 nMax = 0
2901 phaseOffset = numpy.zeros((len(pairslist),n))
2915 phaseOffset = numpy.zeros((len(pairslist),n))
2902
2916
2903 for i in range(n):
2917 for i in range(n):
2904 nMax += nLength
2918 nMax += nLength
2905 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
2919 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
2906 phaseCCF = numpy.mean(phaseCCF, axis = 2)
2920 phaseCCF = numpy.mean(phaseCCF, axis = 2)
2907 phaseOffset[:,i] = phaseCCF.transpose()
2921 phaseOffset[:,i] = phaseCCF.transpose()
2908 nMin = nMax
2922 nMin = nMax
2909 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
2923 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
2910
2924
2911 #Remove Outliers
2925 #Remove Outliers
2912 factor = 2
2926 factor = 2
2913 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
2927 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
2914 dw = numpy.std(wt,axis = 1)
2928 dw = numpy.std(wt,axis = 1)
2915 dw = dw.reshape((dw.size,1))
2929 dw = dw.reshape((dw.size,1))
2916 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
2930 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
2917 phaseOffset[ind] = numpy.nan
2931 phaseOffset[ind] = numpy.nan
2918 phaseOffset = stats.nanmean(phaseOffset, axis=1)
2932 phaseOffset = stats.nanmean(phaseOffset, axis=1)
2919
2933
2920 return phaseOffset
2934 return phaseOffset
2921
2935
2922 def __shiftPhase(self, data, phaseShift):
2936 def __shiftPhase(self, data, phaseShift):
2923 #this will shift the phase of a complex number
2937 #this will shift the phase of a complex number
2924 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
2938 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
2925 return dataShifted
2939 return dataShifted
2926
2940
2927 def __estimatePhaseDifference(self, array, pairslist):
2941 def __estimatePhaseDifference(self, array, pairslist):
2928 nChannel = array.shape[0]
2942 nChannel = array.shape[0]
2929 nHeights = array.shape[2]
2943 nHeights = array.shape[2]
2930 numPairs = len(pairslist)
2944 numPairs = len(pairslist)
2931 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
2945 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
2932 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
2946 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
2933
2947
2934 #Correct phases
2948 #Correct phases
2935 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
2949 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
2936 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2950 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2937
2951
2938 if indDer[0].shape[0] > 0:
2952 if indDer[0].shape[0] > 0:
2939 for i in range(indDer[0].shape[0]):
2953 for i in range(indDer[0].shape[0]):
2940 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
2954 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
2941 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
2955 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
2942
2956
2943 # for j in range(numSides):
2957 # for j in range(numSides):
2944 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
2958 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
2945 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
2959 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
2946 #
2960 #
2947 #Linear
2961 #Linear
2948 phaseInt = numpy.zeros((numPairs,1))
2962 phaseInt = numpy.zeros((numPairs,1))
2949 angAllCCF = phaseCCF[:,[0,1,3,4],0]
2963 angAllCCF = phaseCCF[:,[0,1,3,4],0]
2950 for j in range(numPairs):
2964 for j in range(numPairs):
2951 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
2965 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
2952 phaseInt[j] = fit[1]
2966 phaseInt[j] = fit[1]
2953 #Phase Differences
2967 #Phase Differences
2954 phaseDiff = phaseInt - phaseCCF[:,2,:]
2968 phaseDiff = phaseInt - phaseCCF[:,2,:]
2955 phaseArrival = phaseInt.reshape(phaseInt.size)
2969 phaseArrival = phaseInt.reshape(phaseInt.size)
2956
2970
2957 #Dealias
2971 #Dealias
2958 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
2972 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
2959 # indAlias = numpy.where(phaseArrival > numpy.pi)
2973 # indAlias = numpy.where(phaseArrival > numpy.pi)
2960 # phaseArrival[indAlias] -= 2*numpy.pi
2974 # phaseArrival[indAlias] -= 2*numpy.pi
2961 # indAlias = numpy.where(phaseArrival < -numpy.pi)
2975 # indAlias = numpy.where(phaseArrival < -numpy.pi)
2962 # phaseArrival[indAlias] += 2*numpy.pi
2976 # phaseArrival[indAlias] += 2*numpy.pi
2963
2977
2964 return phaseDiff, phaseArrival
2978 return phaseDiff, phaseArrival
2965
2979
2966 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
2980 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
2967 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
2981 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
2968 #find the phase shifts of each channel over 1 second intervals
2982 #find the phase shifts of each channel over 1 second intervals
2969 #only look at ranges below the beacon signal
2983 #only look at ranges below the beacon signal
2970 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
2984 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
2971 numBlocks = int(volts.shape[1]/numProfPerBlock)
2985 numBlocks = int(volts.shape[1]/numProfPerBlock)
2972 numHeights = volts.shape[2]
2986 numHeights = volts.shape[2]
2973 nChannel = volts.shape[0]
2987 nChannel = volts.shape[0]
2974 voltsCohDet = volts.copy()
2988 voltsCohDet = volts.copy()
2975
2989
2976 pairsarray = numpy.array(pairslist)
2990 pairsarray = numpy.array(pairslist)
2977 indSides = pairsarray[:,1]
2991 indSides = pairsarray[:,1]
2978 # indSides = numpy.array(range(nChannel))
2992 # indSides = numpy.array(range(nChannel))
2979 # indSides = numpy.delete(indSides, indCenter)
2993 # indSides = numpy.delete(indSides, indCenter)
2980 #
2994 #
2981 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
2995 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
2982 listBlocks = numpy.array_split(volts, numBlocks, 1)
2996 listBlocks = numpy.array_split(volts, numBlocks, 1)
2983
2997
2984 startInd = 0
2998 startInd = 0
2985 endInd = 0
2999 endInd = 0
2986
3000
2987 for i in range(numBlocks):
3001 for i in range(numBlocks):
2988 startInd = endInd
3002 startInd = endInd
2989 endInd = endInd + listBlocks[i].shape[1]
3003 endInd = endInd + listBlocks[i].shape[1]
2990
3004
2991 arrayBlock = listBlocks[i]
3005 arrayBlock = listBlocks[i]
2992 # arrayBlockCenter = listCenter[i]
3006 # arrayBlockCenter = listCenter[i]
2993
3007
2994 #Estimate the Phase Difference
3008 #Estimate the Phase Difference
2995 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
3009 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
2996 #Phase Difference RMS
3010 #Phase Difference RMS
2997 arrayPhaseRMS = numpy.abs(phaseDiff)
3011 arrayPhaseRMS = numpy.abs(phaseDiff)
2998 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
3012 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
2999 indPhase = numpy.where(phaseRMSaux==4)
3013 indPhase = numpy.where(phaseRMSaux==4)
3000 #Shifting
3014 #Shifting
3001 if indPhase[0].shape[0] > 0:
3015 if indPhase[0].shape[0] > 0:
3002 for j in range(indSides.size):
3016 for j in range(indSides.size):
3003 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
3017 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
3004 voltsCohDet[:,startInd:endInd,:] = arrayBlock
3018 voltsCohDet[:,startInd:endInd,:] = arrayBlock
3005
3019
3006 return voltsCohDet
3020 return voltsCohDet
3007
3021
3008 def __calculateCCF(self, volts, pairslist ,laglist):
3022 def __calculateCCF(self, volts, pairslist ,laglist):
3009
3023
3010 nHeights = volts.shape[2]
3024 nHeights = volts.shape[2]
3011 nPoints = volts.shape[1]
3025 nPoints = volts.shape[1]
3012 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
3026 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
3013
3027
3014 for i in range(len(pairslist)):
3028 for i in range(len(pairslist)):
3015 volts1 = volts[pairslist[i][0]]
3029 volts1 = volts[pairslist[i][0]]
3016 volts2 = volts[pairslist[i][1]]
3030 volts2 = volts[pairslist[i][1]]
3017
3031
3018 for t in range(len(laglist)):
3032 for t in range(len(laglist)):
3019 idxT = laglist[t]
3033 idxT = laglist[t]
3020 if idxT >= 0:
3034 if idxT >= 0:
3021 vStacked = numpy.vstack((volts2[idxT:,:],
3035 vStacked = numpy.vstack((volts2[idxT:,:],
3022 numpy.zeros((idxT, nHeights),dtype='complex')))
3036 numpy.zeros((idxT, nHeights),dtype='complex')))
3023 else:
3037 else:
3024 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
3038 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
3025 volts2[:(nPoints + idxT),:]))
3039 volts2[:(nPoints + idxT),:]))
3026 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
3040 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
3027
3041
3028 vStacked = None
3042 vStacked = None
3029 return voltsCCF
3043 return voltsCCF
3030
3044
3031 def __getNoise(self, power, timeSegment, timeInterval):
3045 def __getNoise(self, power, timeSegment, timeInterval):
3032 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
3046 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
3033 numBlocks = int(power.shape[0]/numProfPerBlock)
3047 numBlocks = int(power.shape[0]/numProfPerBlock)
3034 numHeights = power.shape[1]
3048 numHeights = power.shape[1]
3035
3049
3036 listPower = numpy.array_split(power, numBlocks, 0)
3050 listPower = numpy.array_split(power, numBlocks, 0)
3037 noise = numpy.zeros((power.shape[0], power.shape[1]))
3051 noise = numpy.zeros((power.shape[0], power.shape[1]))
3038 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
3052 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
3039
3053
3040 startInd = 0
3054 startInd = 0
3041 endInd = 0
3055 endInd = 0
3042
3056
3043 for i in range(numBlocks): #split por canal
3057 for i in range(numBlocks): #split por canal
3044 startInd = endInd
3058 startInd = endInd
3045 endInd = endInd + listPower[i].shape[0]
3059 endInd = endInd + listPower[i].shape[0]
3046
3060
3047 arrayBlock = listPower[i]
3061 arrayBlock = listPower[i]
3048 noiseAux = numpy.mean(arrayBlock, 0)
3062 noiseAux = numpy.mean(arrayBlock, 0)
3049 # noiseAux = numpy.median(noiseAux)
3063 # noiseAux = numpy.median(noiseAux)
3050 # noiseAux = numpy.mean(arrayBlock)
3064 # noiseAux = numpy.mean(arrayBlock)
3051 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
3065 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
3052
3066
3053 noiseAux1 = numpy.mean(arrayBlock)
3067 noiseAux1 = numpy.mean(arrayBlock)
3054 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
3068 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
3055
3069
3056 return noise, noise1
3070 return noise, noise1
3057
3071
3058 def __findMeteors(self, power, thresh):
3072 def __findMeteors(self, power, thresh):
3059 nProf = power.shape[0]
3073 nProf = power.shape[0]
3060 nHeights = power.shape[1]
3074 nHeights = power.shape[1]
3061 listMeteors = []
3075 listMeteors = []
3062
3076
3063 for i in range(nHeights):
3077 for i in range(nHeights):
3064 powerAux = power[:,i]
3078 powerAux = power[:,i]
3065 threshAux = thresh[:,i]
3079 threshAux = thresh[:,i]
3066
3080
3067 indUPthresh = numpy.where(powerAux > threshAux)[0]
3081 indUPthresh = numpy.where(powerAux > threshAux)[0]
3068 indDNthresh = numpy.where(powerAux <= threshAux)[0]
3082 indDNthresh = numpy.where(powerAux <= threshAux)[0]
3069
3083
3070 j = 0
3084 j = 0
3071
3085
3072 while (j < indUPthresh.size - 2):
3086 while (j < indUPthresh.size - 2):
3073 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
3087 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
3074 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
3088 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
3075 indDNthresh = indDNthresh[indDNAux]
3089 indDNthresh = indDNthresh[indDNAux]
3076
3090
3077 if (indDNthresh.size > 0):
3091 if (indDNthresh.size > 0):
3078 indEnd = indDNthresh[0] - 1
3092 indEnd = indDNthresh[0] - 1
3079 indInit = indUPthresh[j]
3093 indInit = indUPthresh[j]
3080
3094
3081 meteor = powerAux[indInit:indEnd + 1]
3095 meteor = powerAux[indInit:indEnd + 1]
3082 indPeak = meteor.argmax() + indInit
3096 indPeak = meteor.argmax() + indInit
3083 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
3097 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
3084
3098
3085 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
3099 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
3086 j = numpy.where(indUPthresh == indEnd)[0] + 1
3100 j = numpy.where(indUPthresh == indEnd)[0] + 1
3087 else: j+=1
3101 else: j+=1
3088 else: j+=1
3102 else: j+=1
3089
3103
3090 return listMeteors
3104 return listMeteors
3091
3105
3092 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
3106 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
3093
3107
3094 arrayMeteors = numpy.asarray(listMeteors)
3108 arrayMeteors = numpy.asarray(listMeteors)
3095 listMeteors1 = []
3109 listMeteors1 = []
3096
3110
3097 while arrayMeteors.shape[0] > 0:
3111 while arrayMeteors.shape[0] > 0:
3098 FLAs = arrayMeteors[:,4]
3112 FLAs = arrayMeteors[:,4]
3099 maxFLA = FLAs.argmax()
3113 maxFLA = FLAs.argmax()
3100 listMeteors1.append(arrayMeteors[maxFLA,:])
3114 listMeteors1.append(arrayMeteors[maxFLA,:])
3101
3115
3102 MeteorInitTime = arrayMeteors[maxFLA,1]
3116 MeteorInitTime = arrayMeteors[maxFLA,1]
3103 MeteorEndTime = arrayMeteors[maxFLA,3]
3117 MeteorEndTime = arrayMeteors[maxFLA,3]
3104 MeteorHeight = arrayMeteors[maxFLA,0]
3118 MeteorHeight = arrayMeteors[maxFLA,0]
3105
3119
3106 #Check neighborhood
3120 #Check neighborhood
3107 maxHeightIndex = MeteorHeight + rangeLimit
3121 maxHeightIndex = MeteorHeight + rangeLimit
3108 minHeightIndex = MeteorHeight - rangeLimit
3122 minHeightIndex = MeteorHeight - rangeLimit
3109 minTimeIndex = MeteorInitTime - timeLimit
3123 minTimeIndex = MeteorInitTime - timeLimit
3110 maxTimeIndex = MeteorEndTime + timeLimit
3124 maxTimeIndex = MeteorEndTime + timeLimit
3111
3125
3112 #Check Heights
3126 #Check Heights
3113 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
3127 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
3114 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
3128 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
3115 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
3129 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
3116
3130
3117 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
3131 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
3118
3132
3119 return listMeteors1
3133 return listMeteors1
3120
3134
3121 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
3135 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
3122 numHeights = volts.shape[2]
3136 numHeights = volts.shape[2]
3123 nChannel = volts.shape[0]
3137 nChannel = volts.shape[0]
3124
3138
3125 thresholdPhase = thresh[0]
3139 thresholdPhase = thresh[0]
3126 thresholdNoise = thresh[1]
3140 thresholdNoise = thresh[1]
3127 thresholdDB = float(thresh[2])
3141 thresholdDB = float(thresh[2])
3128
3142
3129 thresholdDB1 = 10**(thresholdDB/10)
3143 thresholdDB1 = 10**(thresholdDB/10)
3130 pairsarray = numpy.array(pairslist)
3144 pairsarray = numpy.array(pairslist)
3131 indSides = pairsarray[:,1]
3145 indSides = pairsarray[:,1]
3132
3146
3133 pairslist1 = list(pairslist)
3147 pairslist1 = list(pairslist)
3134 pairslist1.append((0,1))
3148 pairslist1.append((0,1))
3135 pairslist1.append((3,4))
3149 pairslist1.append((3,4))
3136
3150
3137 listMeteors1 = []
3151 listMeteors1 = []
3138 listPowerSeries = []
3152 listPowerSeries = []
3139 listVoltageSeries = []
3153 listVoltageSeries = []
3140 #volts has the war data
3154 #volts has the war data
3141
3155
3142 if frequency == 30e6:
3156 if frequency == 30e6:
3143 timeLag = 45*10**-3
3157 timeLag = 45*10**-3
3144 else:
3158 else:
3145 timeLag = 15*10**-3
3159 timeLag = 15*10**-3
3146 lag = numpy.ceil(timeLag/timeInterval)
3160 lag = numpy.ceil(timeLag/timeInterval)
3147
3161
3148 for i in range(len(listMeteors)):
3162 for i in range(len(listMeteors)):
3149
3163
3150 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
3164 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
3151 meteorAux = numpy.zeros(16)
3165 meteorAux = numpy.zeros(16)
3152
3166
3153 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
3167 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
3154 mHeight = listMeteors[i][0]
3168 mHeight = listMeteors[i][0]
3155 mStart = listMeteors[i][1]
3169 mStart = listMeteors[i][1]
3156 mPeak = listMeteors[i][2]
3170 mPeak = listMeteors[i][2]
3157 mEnd = listMeteors[i][3]
3171 mEnd = listMeteors[i][3]
3158
3172
3159 #get the volt data between the start and end times of the meteor
3173 #get the volt data between the start and end times of the meteor
3160 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
3174 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
3161 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3175 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3162
3176
3163 #3.6. Phase Difference estimation
3177 #3.6. Phase Difference estimation
3164 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
3178 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
3165
3179
3166 #3.7. Phase difference removal & meteor start, peak and end times reestimated
3180 #3.7. Phase difference removal & meteor start, peak and end times reestimated
3167 #meteorVolts0.- all Channels, all Profiles
3181 #meteorVolts0.- all Channels, all Profiles
3168 meteorVolts0 = volts[:,:,mHeight]
3182 meteorVolts0 = volts[:,:,mHeight]
3169 meteorThresh = noise[:,mHeight]*thresholdNoise
3183 meteorThresh = noise[:,mHeight]*thresholdNoise
3170 meteorNoise = noise[:,mHeight]
3184 meteorNoise = noise[:,mHeight]
3171 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
3185 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
3172 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
3186 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
3173
3187
3174 #Times reestimation
3188 #Times reestimation
3175 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
3189 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
3176 if mStart1.size > 0:
3190 if mStart1.size > 0:
3177 mStart1 = mStart1[-1] + 1
3191 mStart1 = mStart1[-1] + 1
3178
3192
3179 else:
3193 else:
3180 mStart1 = mPeak
3194 mStart1 = mPeak
3181
3195
3182 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
3196 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
3183 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
3197 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
3184 if mEndDecayTime1.size == 0:
3198 if mEndDecayTime1.size == 0:
3185 mEndDecayTime1 = powerNet0.size
3199 mEndDecayTime1 = powerNet0.size
3186 else:
3200 else:
3187 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
3201 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
3188 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
3202 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
3189
3203
3190 #meteorVolts1.- all Channels, from start to end
3204 #meteorVolts1.- all Channels, from start to end
3191 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
3205 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
3192 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
3206 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
3193 if meteorVolts2.shape[1] == 0:
3207 if meteorVolts2.shape[1] == 0:
3194 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
3208 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
3195 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
3209 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
3196 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
3210 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
3197 ##################### END PARAMETERS REESTIMATION #########################
3211 ##################### END PARAMETERS REESTIMATION #########################
3198
3212
3199 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
3213 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
3200 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
3214 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
3201 if meteorVolts2.shape[1] > 0:
3215 if meteorVolts2.shape[1] > 0:
3202 #Phase Difference re-estimation
3216 #Phase Difference re-estimation
3203 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
3217 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
3204 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
3218 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
3205 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
3219 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
3206 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
3220 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
3207 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
3221 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
3208
3222
3209 #Phase Difference RMS
3223 #Phase Difference RMS
3210 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
3224 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
3211 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
3225 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
3212 #Data from Meteor
3226 #Data from Meteor
3213 mPeak1 = powerNet1.argmax() + mStart1
3227 mPeak1 = powerNet1.argmax() + mStart1
3214 mPeakPower1 = powerNet1.max()
3228 mPeakPower1 = powerNet1.max()
3215 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
3229 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
3216 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
3230 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
3217 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
3231 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
3218 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
3232 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
3219 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
3233 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
3220 #Vectorize
3234 #Vectorize
3221 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
3235 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
3222 meteorAux[7:11] = phaseDiffint[0:4]
3236 meteorAux[7:11] = phaseDiffint[0:4]
3223
3237
3224 #Rejection Criterions
3238 #Rejection Criterions
3225 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
3239 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
3226 meteorAux[-1] = 17
3240 meteorAux[-1] = 17
3227 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
3241 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
3228 meteorAux[-1] = 1
3242 meteorAux[-1] = 1
3229
3243
3230
3244
3231 else:
3245 else:
3232 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
3246 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
3233 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
3247 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
3234 PowerSeries = 0
3248 PowerSeries = 0
3235
3249
3236 listMeteors1.append(meteorAux)
3250 listMeteors1.append(meteorAux)
3237 listPowerSeries.append(PowerSeries)
3251 listPowerSeries.append(PowerSeries)
3238 listVoltageSeries.append(meteorVolts1)
3252 listVoltageSeries.append(meteorVolts1)
3239
3253
3240 return listMeteors1, listPowerSeries, listVoltageSeries
3254 return listMeteors1, listPowerSeries, listVoltageSeries
3241
3255
3242 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
3256 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
3243
3257
3244 threshError = 10
3258 threshError = 10
3245 #Depending if it is 30 or 50 MHz
3259 #Depending if it is 30 or 50 MHz
3246 if frequency == 30e6:
3260 if frequency == 30e6:
3247 timeLag = 45*10**-3
3261 timeLag = 45*10**-3
3248 else:
3262 else:
3249 timeLag = 15*10**-3
3263 timeLag = 15*10**-3
3250 lag = numpy.ceil(timeLag/timeInterval)
3264 lag = numpy.ceil(timeLag/timeInterval)
3251
3265
3252 listMeteors1 = []
3266 listMeteors1 = []
3253
3267
3254 for i in range(len(listMeteors)):
3268 for i in range(len(listMeteors)):
3255 meteorPower = listPower[i]
3269 meteorPower = listPower[i]
3256 meteorAux = listMeteors[i]
3270 meteorAux = listMeteors[i]
3257
3271
3258 if meteorAux[-1] == 0:
3272 if meteorAux[-1] == 0:
3259
3273
3260 try:
3274 try:
3261 indmax = meteorPower.argmax()
3275 indmax = meteorPower.argmax()
3262 indlag = indmax + lag
3276 indlag = indmax + lag
3263
3277
3264 y = meteorPower[indlag:]
3278 y = meteorPower[indlag:]
3265 x = numpy.arange(0, y.size)*timeLag
3279 x = numpy.arange(0, y.size)*timeLag
3266
3280
3267 #first guess
3281 #first guess
3268 a = y[0]
3282 a = y[0]
3269 tau = timeLag
3283 tau = timeLag
3270 #exponential fit
3284 #exponential fit
3271 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
3285 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
3272 y1 = self.__exponential_function(x, *popt)
3286 y1 = self.__exponential_function(x, *popt)
3273 #error estimation
3287 #error estimation
3274 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
3288 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
3275
3289
3276 decayTime = popt[1]
3290 decayTime = popt[1]
3277 riseTime = indmax*timeInterval
3291 riseTime = indmax*timeInterval
3278 meteorAux[11:13] = [decayTime, error]
3292 meteorAux[11:13] = [decayTime, error]
3279
3293
3280 #Table items 7, 8 and 11
3294 #Table items 7, 8 and 11
3281 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
3295 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
3282 meteorAux[-1] = 7
3296 meteorAux[-1] = 7
3283 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
3297 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
3284 meteorAux[-1] = 8
3298 meteorAux[-1] = 8
3285 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
3299 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
3286 meteorAux[-1] = 11
3300 meteorAux[-1] = 11
3287
3301
3288
3302
3289 except:
3303 except:
3290 meteorAux[-1] = 11
3304 meteorAux[-1] = 11
3291
3305
3292
3306
3293 listMeteors1.append(meteorAux)
3307 listMeteors1.append(meteorAux)
3294
3308
3295 return listMeteors1
3309 return listMeteors1
3296
3310
3297 #Exponential Function
3311 #Exponential Function
3298
3312
3299 def __exponential_function(self, x, a, tau):
3313 def __exponential_function(self, x, a, tau):
3300 y = a*numpy.exp(-x/tau)
3314 y = a*numpy.exp(-x/tau)
3301 return y
3315 return y
3302
3316
3303 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
3317 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
3304
3318
3305 pairslist1 = list(pairslist)
3319 pairslist1 = list(pairslist)
3306 pairslist1.append((0,1))
3320 pairslist1.append((0,1))
3307 pairslist1.append((3,4))
3321 pairslist1.append((3,4))
3308 numPairs = len(pairslist1)
3322 numPairs = len(pairslist1)
3309 #Time Lag
3323 #Time Lag
3310 timeLag = 45*10**-3
3324 timeLag = 45*10**-3
3311 c = 3e8
3325 c = 3e8
3312 lag = numpy.ceil(timeLag/timeInterval)
3326 lag = numpy.ceil(timeLag/timeInterval)
3313 freq = 30e6
3327 freq = 30e6
3314
3328
3315 listMeteors1 = []
3329 listMeteors1 = []
3316
3330
3317 for i in range(len(listMeteors)):
3331 for i in range(len(listMeteors)):
3318 meteorAux = listMeteors[i]
3332 meteorAux = listMeteors[i]
3319 if meteorAux[-1] == 0:
3333 if meteorAux[-1] == 0:
3320 mStart = listMeteors[i][1]
3334 mStart = listMeteors[i][1]
3321 mPeak = listMeteors[i][2]
3335 mPeak = listMeteors[i][2]
3322 mLag = mPeak - mStart + lag
3336 mLag = mPeak - mStart + lag
3323
3337
3324 #get the volt data between the start and end times of the meteor
3338 #get the volt data between the start and end times of the meteor
3325 meteorVolts = listVolts[i]
3339 meteorVolts = listVolts[i]
3326 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3340 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3327
3341
3328 #Get CCF
3342 #Get CCF
3329 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
3343 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
3330
3344
3331 #Method 2
3345 #Method 2
3332 slopes = numpy.zeros(numPairs)
3346 slopes = numpy.zeros(numPairs)
3333 time = numpy.array([-2,-1,1,2])*timeInterval
3347 time = numpy.array([-2,-1,1,2])*timeInterval
3334 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
3348 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
3335
3349
3336 #Correct phases
3350 #Correct phases
3337 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
3351 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
3338 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
3352 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
3339
3353
3340 if indDer[0].shape[0] > 0:
3354 if indDer[0].shape[0] > 0:
3341 for i in range(indDer[0].shape[0]):
3355 for i in range(indDer[0].shape[0]):
3342 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
3356 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
3343 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
3357 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
3344
3358
3345 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
3359 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
3346 for j in range(numPairs):
3360 for j in range(numPairs):
3347 fit = stats.linregress(time, angAllCCF[j,:])
3361 fit = stats.linregress(time, angAllCCF[j,:])
3348 slopes[j] = fit[0]
3362 slopes[j] = fit[0]
3349
3363
3350 #Remove Outlier
3364 #Remove Outlier
3351 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3365 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3352 # slopes = numpy.delete(slopes,indOut)
3366 # slopes = numpy.delete(slopes,indOut)
3353 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3367 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3354 # slopes = numpy.delete(slopes,indOut)
3368 # slopes = numpy.delete(slopes,indOut)
3355
3369
3356 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
3370 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
3357 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
3371 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
3358 meteorAux[-2] = radialError
3372 meteorAux[-2] = radialError
3359 meteorAux[-3] = radialVelocity
3373 meteorAux[-3] = radialVelocity
3360
3374
3361 #Setting Error
3375 #Setting Error
3362 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
3376 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
3363 if numpy.abs(radialVelocity) > 200:
3377 if numpy.abs(radialVelocity) > 200:
3364 meteorAux[-1] = 15
3378 meteorAux[-1] = 15
3365 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
3379 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
3366 elif radialError > radialStdThresh:
3380 elif radialError > radialStdThresh:
3367 meteorAux[-1] = 12
3381 meteorAux[-1] = 12
3368
3382
3369 listMeteors1.append(meteorAux)
3383 listMeteors1.append(meteorAux)
3370 return listMeteors1
3384 return listMeteors1
3371
3385
3372 def __setNewArrays(self, listMeteors, date, heiRang):
3386 def __setNewArrays(self, listMeteors, date, heiRang):
3373
3387
3374 #New arrays
3388 #New arrays
3375 arrayMeteors = numpy.array(listMeteors)
3389 arrayMeteors = numpy.array(listMeteors)
3376 arrayParameters = numpy.zeros((len(listMeteors), 13))
3390 arrayParameters = numpy.zeros((len(listMeteors), 13))
3377
3391
3378 #Date inclusion
3392 #Date inclusion
3379 # date = re.findall(r'\((.*?)\)', date)
3393 # date = re.findall(r'\((.*?)\)', date)
3380 # date = date[0].split(',')
3394 # date = date[0].split(',')
3381 # date = map(int, date)
3395 # date = map(int, date)
3382 #
3396 #
3383 # if len(date)<6:
3397 # if len(date)<6:
3384 # date.append(0)
3398 # date.append(0)
3385 #
3399 #
3386 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
3400 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
3387 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
3401 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
3388 arrayDate = numpy.tile(date, (len(listMeteors)))
3402 arrayDate = numpy.tile(date, (len(listMeteors)))
3389
3403
3390 #Meteor array
3404 #Meteor array
3391 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
3405 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
3392 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
3406 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
3393
3407
3394 #Parameters Array
3408 #Parameters Array
3395 arrayParameters[:,0] = arrayDate #Date
3409 arrayParameters[:,0] = arrayDate #Date
3396 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
3410 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
3397 arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
3411 arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
3398 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
3412 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
3399 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
3413 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
3400
3414
3401
3415
3402 return arrayParameters
3416 return arrayParameters
3403
3417
3404 class CorrectSMPhases(Operation):
3418 class CorrectSMPhases(Operation):
3405
3419
3406 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
3420 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
3407
3421
3408 arrayParameters = dataOut.data_param
3422 arrayParameters = dataOut.data_param
3409 pairsList = []
3423 pairsList = []
3410 pairx = (0,1)
3424 pairx = (0,1)
3411 pairy = (2,3)
3425 pairy = (2,3)
3412 pairsList.append(pairx)
3426 pairsList.append(pairx)
3413 pairsList.append(pairy)
3427 pairsList.append(pairy)
3414 jph = numpy.zeros(4)
3428 jph = numpy.zeros(4)
3415
3429
3416 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
3430 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
3417 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
3431 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
3418 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
3432 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
3419
3433
3420 meteorOps = SMOperations()
3434 meteorOps = SMOperations()
3421 if channelPositions is None:
3435 if channelPositions is None:
3422 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3436 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3423 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3437 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3424
3438
3425 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3439 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3426 h = (hmin,hmax)
3440 h = (hmin,hmax)
3427
3441
3428 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
3442 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
3429
3443
3430 dataOut.data_param = arrayParameters
3444 dataOut.data_param = arrayParameters
3431 return
3445 return
3432
3446
3433 class SMPhaseCalibration(Operation):
3447 class SMPhaseCalibration(Operation):
3434
3448
3435 __buffer = None
3449 __buffer = None
3436
3450
3437 __initime = None
3451 __initime = None
3438
3452
3439 __dataReady = False
3453 __dataReady = False
3440
3454
3441 __isConfig = False
3455 __isConfig = False
3442
3456
3443 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
3457 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
3444
3458
3445 dataTime = currentTime + paramInterval
3459 dataTime = currentTime + paramInterval
3446 deltaTime = dataTime - initTime
3460 deltaTime = dataTime - initTime
3447
3461
3448 if deltaTime >= outputInterval or deltaTime < 0:
3462 if deltaTime >= outputInterval or deltaTime < 0:
3449 return True
3463 return True
3450
3464
3451 return False
3465 return False
3452
3466
3453 def __getGammas(self, pairs, d, phases):
3467 def __getGammas(self, pairs, d, phases):
3454 gammas = numpy.zeros(2)
3468 gammas = numpy.zeros(2)
3455
3469
3456 for i in range(len(pairs)):
3470 for i in range(len(pairs)):
3457
3471
3458 pairi = pairs[i]
3472 pairi = pairs[i]
3459
3473
3460 phip3 = phases[:,pairi[0]]
3474 phip3 = phases[:,pairi[0]]
3461 d3 = d[pairi[0]]
3475 d3 = d[pairi[0]]
3462 phip2 = phases[:,pairi[1]]
3476 phip2 = phases[:,pairi[1]]
3463 d2 = d[pairi[1]]
3477 d2 = d[pairi[1]]
3464 #Calculating gamma
3478 #Calculating gamma
3465 # jdcos = alp1/(k*d1)
3479 # jdcos = alp1/(k*d1)
3466 # jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0)))
3480 # jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0)))
3467 jgamma = -phip2*d3/d2 - phip3
3481 jgamma = -phip2*d3/d2 - phip3
3468 jgamma = numpy.angle(numpy.exp(1j*jgamma))
3482 jgamma = numpy.angle(numpy.exp(1j*jgamma))
3469 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
3483 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
3470 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
3484 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
3471
3485
3472 #Revised distribution
3486 #Revised distribution
3473 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
3487 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
3474
3488
3475 #Histogram
3489 #Histogram
3476 nBins = 64
3490 nBins = 64
3477 rmin = -0.5*numpy.pi
3491 rmin = -0.5*numpy.pi
3478 rmax = 0.5*numpy.pi
3492 rmax = 0.5*numpy.pi
3479 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
3493 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
3480
3494
3481 meteorsY = phaseHisto[0]
3495 meteorsY = phaseHisto[0]
3482 phasesX = phaseHisto[1][:-1]
3496 phasesX = phaseHisto[1][:-1]
3483 width = phasesX[1] - phasesX[0]
3497 width = phasesX[1] - phasesX[0]
3484 phasesX += width/2
3498 phasesX += width/2
3485
3499
3486 #Gaussian aproximation
3500 #Gaussian aproximation
3487 bpeak = meteorsY.argmax()
3501 bpeak = meteorsY.argmax()
3488 peak = meteorsY.max()
3502 peak = meteorsY.max()
3489 jmin = bpeak - 5
3503 jmin = bpeak - 5
3490 jmax = bpeak + 5 + 1
3504 jmax = bpeak + 5 + 1
3491
3505
3492 if jmin<0:
3506 if jmin<0:
3493 jmin = 0
3507 jmin = 0
3494 jmax = 6
3508 jmax = 6
3495 elif jmax > meteorsY.size:
3509 elif jmax > meteorsY.size:
3496 jmin = meteorsY.size - 6
3510 jmin = meteorsY.size - 6
3497 jmax = meteorsY.size
3511 jmax = meteorsY.size
3498
3512
3499 x0 = numpy.array([peak,bpeak,50])
3513 x0 = numpy.array([peak,bpeak,50])
3500 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
3514 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
3501
3515
3502 #Gammas
3516 #Gammas
3503 gammas[i] = coeff[0][1]
3517 gammas[i] = coeff[0][1]
3504
3518
3505 return gammas
3519 return gammas
3506
3520
3507 def __residualFunction(self, coeffs, y, t):
3521 def __residualFunction(self, coeffs, y, t):
3508
3522
3509 return y - self.__gauss_function(t, coeffs)
3523 return y - self.__gauss_function(t, coeffs)
3510
3524
3511 def __gauss_function(self, t, coeffs):
3525 def __gauss_function(self, t, coeffs):
3512
3526
3513 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
3527 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
3514
3528
3515 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
3529 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
3516 meteorOps = SMOperations()
3530 meteorOps = SMOperations()
3517 nchan = 4
3531 nchan = 4
3518 pairx = pairsList[0] #x es 0
3532 pairx = pairsList[0] #x es 0
3519 pairy = pairsList[1] #y es 1
3533 pairy = pairsList[1] #y es 1
3520 center_xangle = 0
3534 center_xangle = 0
3521 center_yangle = 0
3535 center_yangle = 0
3522 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
3536 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
3523 ntimes = len(range_angle)
3537 ntimes = len(range_angle)
3524
3538
3525 nstepsx = 20
3539 nstepsx = 20
3526 nstepsy = 20
3540 nstepsy = 20
3527
3541
3528 for iz in range(ntimes):
3542 for iz in range(ntimes):
3529 min_xangle = -range_angle[iz]/2 + center_xangle
3543 min_xangle = -range_angle[iz]/2 + center_xangle
3530 max_xangle = range_angle[iz]/2 + center_xangle
3544 max_xangle = range_angle[iz]/2 + center_xangle
3531 min_yangle = -range_angle[iz]/2 + center_yangle
3545 min_yangle = -range_angle[iz]/2 + center_yangle
3532 max_yangle = range_angle[iz]/2 + center_yangle
3546 max_yangle = range_angle[iz]/2 + center_yangle
3533
3547
3534 inc_x = (max_xangle-min_xangle)/nstepsx
3548 inc_x = (max_xangle-min_xangle)/nstepsx
3535 inc_y = (max_yangle-min_yangle)/nstepsy
3549 inc_y = (max_yangle-min_yangle)/nstepsy
3536
3550
3537 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
3551 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
3538 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
3552 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
3539 penalty = numpy.zeros((nstepsx,nstepsy))
3553 penalty = numpy.zeros((nstepsx,nstepsy))
3540 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
3554 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
3541 jph = numpy.zeros(nchan)
3555 jph = numpy.zeros(nchan)
3542
3556
3543 # Iterations looking for the offset
3557 # Iterations looking for the offset
3544 for iy in range(int(nstepsy)):
3558 for iy in range(int(nstepsy)):
3545 for ix in range(int(nstepsx)):
3559 for ix in range(int(nstepsx)):
3546 d3 = d[pairsList[1][0]]
3560 d3 = d[pairsList[1][0]]
3547 d2 = d[pairsList[1][1]]
3561 d2 = d[pairsList[1][1]]
3548 d5 = d[pairsList[0][0]]
3562 d5 = d[pairsList[0][0]]
3549 d4 = d[pairsList[0][1]]
3563 d4 = d[pairsList[0][1]]
3550
3564
3551 alp2 = alpha_y[iy] #gamma 1
3565 alp2 = alpha_y[iy] #gamma 1
3552 alp4 = alpha_x[ix] #gamma 0
3566 alp4 = alpha_x[ix] #gamma 0
3553
3567
3554 alp3 = -alp2*d3/d2 - gammas[1]
3568 alp3 = -alp2*d3/d2 - gammas[1]
3555 alp5 = -alp4*d5/d4 - gammas[0]
3569 alp5 = -alp4*d5/d4 - gammas[0]
3556 # jph[pairy[1]] = alpha_y[iy]
3570 # jph[pairy[1]] = alpha_y[iy]
3557 # jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
3571 # jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
3558
3572
3559 # jph[pairx[1]] = alpha_x[ix]
3573 # jph[pairx[1]] = alpha_x[ix]
3560 # jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
3574 # jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
3561 jph[pairsList[0][1]] = alp4
3575 jph[pairsList[0][1]] = alp4
3562 jph[pairsList[0][0]] = alp5
3576 jph[pairsList[0][0]] = alp5
3563 jph[pairsList[1][0]] = alp3
3577 jph[pairsList[1][0]] = alp3
3564 jph[pairsList[1][1]] = alp2
3578 jph[pairsList[1][1]] = alp2
3565 jph_array[:,ix,iy] = jph
3579 jph_array[:,ix,iy] = jph
3566 # d = [2.0,2.5,2.5,2.0]
3580 # d = [2.0,2.5,2.5,2.0]
3567 #falta chequear si va a leer bien los meteoros
3581 #falta chequear si va a leer bien los meteoros
3568 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
3582 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
3569 error = meteorsArray1[:,-1]
3583 error = meteorsArray1[:,-1]
3570 ind1 = numpy.where(error==0)[0]
3584 ind1 = numpy.where(error==0)[0]
3571 penalty[ix,iy] = ind1.size
3585 penalty[ix,iy] = ind1.size
3572
3586
3573 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
3587 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
3574 phOffset = jph_array[:,i,j]
3588 phOffset = jph_array[:,i,j]
3575
3589
3576 center_xangle = phOffset[pairx[1]]
3590 center_xangle = phOffset[pairx[1]]
3577 center_yangle = phOffset[pairy[1]]
3591 center_yangle = phOffset[pairy[1]]
3578
3592
3579 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
3593 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
3580 phOffset = phOffset*180/numpy.pi
3594 phOffset = phOffset*180/numpy.pi
3581 return phOffset
3595 return phOffset
3582
3596
3583
3597
3584 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
3598 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
3585
3599
3586 dataOut.flagNoData = True
3600 dataOut.flagNoData = True
3587 self.__dataReady = False
3601 self.__dataReady = False
3588 dataOut.outputInterval = nHours*3600
3602 dataOut.outputInterval = nHours*3600
3589
3603
3590 if self.__isConfig == False:
3604 if self.__isConfig == False:
3591 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
3605 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
3592 #Get Initial LTC time
3606 #Get Initial LTC time
3593 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
3607 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
3594 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
3608 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
3595
3609
3596 self.__isConfig = True
3610 self.__isConfig = True
3597
3611
3598 if self.__buffer is None:
3612 if self.__buffer is None:
3599 self.__buffer = dataOut.data_param.copy()
3613 self.__buffer = dataOut.data_param.copy()
3600
3614
3601 else:
3615 else:
3602 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
3616 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
3603
3617
3604 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
3618 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
3605
3619
3606 if self.__dataReady:
3620 if self.__dataReady:
3607 dataOut.utctimeInit = self.__initime
3621 dataOut.utctimeInit = self.__initime
3608 self.__initime += dataOut.outputInterval #to erase time offset
3622 self.__initime += dataOut.outputInterval #to erase time offset
3609
3623
3610 freq = dataOut.frequency
3624 freq = dataOut.frequency
3611 c = dataOut.C #m/s
3625 c = dataOut.C #m/s
3612 lamb = c/freq
3626 lamb = c/freq
3613 k = 2*numpy.pi/lamb
3627 k = 2*numpy.pi/lamb
3614 azimuth = 0
3628 azimuth = 0
3615 h = (hmin, hmax)
3629 h = (hmin, hmax)
3616 # pairs = ((0,1),(2,3)) #Estrella
3630 # pairs = ((0,1),(2,3)) #Estrella
3617 # pairs = ((1,0),(2,3)) #T
3631 # pairs = ((1,0),(2,3)) #T
3618
3632
3619 if channelPositions is None:
3633 if channelPositions is None:
3620 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3634 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3621 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3635 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3622 meteorOps = SMOperations()
3636 meteorOps = SMOperations()
3623 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3637 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3624
3638
3625 #Checking correct order of pairs
3639 #Checking correct order of pairs
3626 pairs = []
3640 pairs = []
3627 if distances[1] > distances[0]:
3641 if distances[1] > distances[0]:
3628 pairs.append((1,0))
3642 pairs.append((1,0))
3629 else:
3643 else:
3630 pairs.append((0,1))
3644 pairs.append((0,1))
3631
3645
3632 if distances[3] > distances[2]:
3646 if distances[3] > distances[2]:
3633 pairs.append((3,2))
3647 pairs.append((3,2))
3634 else:
3648 else:
3635 pairs.append((2,3))
3649 pairs.append((2,3))
3636 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
3650 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
3637
3651
3638 meteorsArray = self.__buffer
3652 meteorsArray = self.__buffer
3639 error = meteorsArray[:,-1]
3653 error = meteorsArray[:,-1]
3640 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
3654 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
3641 ind1 = numpy.where(boolError)[0]
3655 ind1 = numpy.where(boolError)[0]
3642 meteorsArray = meteorsArray[ind1,:]
3656 meteorsArray = meteorsArray[ind1,:]
3643 meteorsArray[:,-1] = 0
3657 meteorsArray[:,-1] = 0
3644 phases = meteorsArray[:,8:12]
3658 phases = meteorsArray[:,8:12]
3645
3659
3646 #Calculate Gammas
3660 #Calculate Gammas
3647 gammas = self.__getGammas(pairs, distances, phases)
3661 gammas = self.__getGammas(pairs, distances, phases)
3648 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
3662 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
3649 #Calculate Phases
3663 #Calculate Phases
3650 phasesOff = self.__getPhases(azimuth, h, pairs, distances, gammas, meteorsArray)
3664 phasesOff = self.__getPhases(azimuth, h, pairs, distances, gammas, meteorsArray)
3651 phasesOff = phasesOff.reshape((1,phasesOff.size))
3665 phasesOff = phasesOff.reshape((1,phasesOff.size))
3652 dataOut.data_output = -phasesOff
3666 dataOut.data_output = -phasesOff
3653 dataOut.flagNoData = False
3667 dataOut.flagNoData = False
3654 self.__buffer = None
3668 self.__buffer = None
3655
3669
3656
3670
3657 return
3671 return
3658
3672
3659 class SMOperations():
3673 class SMOperations():
3660
3674
3661 def __init__(self):
3675 def __init__(self):
3662
3676
3663 return
3677 return
3664
3678
3665 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
3679 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
3666
3680
3667 arrayParameters = arrayParameters0.copy()
3681 arrayParameters = arrayParameters0.copy()
3668 hmin = h[0]
3682 hmin = h[0]
3669 hmax = h[1]
3683 hmax = h[1]
3670
3684
3671 #Calculate AOA (Error N 3, 4)
3685 #Calculate AOA (Error N 3, 4)
3672 #JONES ET AL. 1998
3686 #JONES ET AL. 1998
3673 AOAthresh = numpy.pi/8
3687 AOAthresh = numpy.pi/8
3674 error = arrayParameters[:,-1]
3688 error = arrayParameters[:,-1]
3675 phases = -arrayParameters[:,8:12] + jph
3689 phases = -arrayParameters[:,8:12] + jph
3676 # phases = numpy.unwrap(phases)
3690 # phases = numpy.unwrap(phases)
3677 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
3691 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
3678
3692
3679 #Calculate Heights (Error N 13 and 14)
3693 #Calculate Heights (Error N 13 and 14)
3680 error = arrayParameters[:,-1]
3694 error = arrayParameters[:,-1]
3681 Ranges = arrayParameters[:,1]
3695 Ranges = arrayParameters[:,1]
3682 zenith = arrayParameters[:,4]
3696 zenith = arrayParameters[:,4]
3683 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
3697 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
3684
3698
3685 #----------------------- Get Final data ------------------------------------
3699 #----------------------- Get Final data ------------------------------------
3686 # error = arrayParameters[:,-1]
3700 # error = arrayParameters[:,-1]
3687 # ind1 = numpy.where(error==0)[0]
3701 # ind1 = numpy.where(error==0)[0]
3688 # arrayParameters = arrayParameters[ind1,:]
3702 # arrayParameters = arrayParameters[ind1,:]
3689
3703
3690 return arrayParameters
3704 return arrayParameters
3691
3705
3692 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
3706 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
3693
3707
3694 arrayAOA = numpy.zeros((phases.shape[0],3))
3708 arrayAOA = numpy.zeros((phases.shape[0],3))
3695 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
3709 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
3696
3710
3697 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3711 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3698 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3712 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3699 arrayAOA[:,2] = cosDirError
3713 arrayAOA[:,2] = cosDirError
3700
3714
3701 azimuthAngle = arrayAOA[:,0]
3715 azimuthAngle = arrayAOA[:,0]
3702 zenithAngle = arrayAOA[:,1]
3716 zenithAngle = arrayAOA[:,1]
3703
3717
3704 #Setting Error
3718 #Setting Error
3705 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
3719 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
3706 error[indError] = 0
3720 error[indError] = 0
3707 #Number 3: AOA not fesible
3721 #Number 3: AOA not fesible
3708 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3722 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3709 error[indInvalid] = 3
3723 error[indInvalid] = 3
3710 #Number 4: Large difference in AOAs obtained from different antenna baselines
3724 #Number 4: Large difference in AOAs obtained from different antenna baselines
3711 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3725 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3712 error[indInvalid] = 4
3726 error[indInvalid] = 4
3713 return arrayAOA, error
3727 return arrayAOA, error
3714
3728
3715 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
3729 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
3716
3730
3717 #Initializing some variables
3731 #Initializing some variables
3718 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3732 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3719 ang_aux = ang_aux.reshape(1,ang_aux.size)
3733 ang_aux = ang_aux.reshape(1,ang_aux.size)
3720
3734
3721 cosdir = numpy.zeros((arrayPhase.shape[0],2))
3735 cosdir = numpy.zeros((arrayPhase.shape[0],2))
3722 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3736 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3723
3737
3724
3738
3725 for i in range(2):
3739 for i in range(2):
3726 ph0 = arrayPhase[:,pairsList[i][0]]
3740 ph0 = arrayPhase[:,pairsList[i][0]]
3727 ph1 = arrayPhase[:,pairsList[i][1]]
3741 ph1 = arrayPhase[:,pairsList[i][1]]
3728 d0 = distances[pairsList[i][0]]
3742 d0 = distances[pairsList[i][0]]
3729 d1 = distances[pairsList[i][1]]
3743 d1 = distances[pairsList[i][1]]
3730
3744
3731 ph0_aux = ph0 + ph1
3745 ph0_aux = ph0 + ph1
3732 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
3746 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
3733 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
3747 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
3734 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
3748 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
3735 #First Estimation
3749 #First Estimation
3736 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
3750 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
3737
3751
3738 #Most-Accurate Second Estimation
3752 #Most-Accurate Second Estimation
3739 phi1_aux = ph0 - ph1
3753 phi1_aux = ph0 - ph1
3740 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3754 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3741 #Direction Cosine 1
3755 #Direction Cosine 1
3742 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
3756 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
3743
3757
3744 #Searching the correct Direction Cosine
3758 #Searching the correct Direction Cosine
3745 cosdir0_aux = cosdir0[:,i]
3759 cosdir0_aux = cosdir0[:,i]
3746 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3760 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3747 #Minimum Distance
3761 #Minimum Distance
3748 cosDiff = (cosdir1 - cosdir0_aux)**2
3762 cosDiff = (cosdir1 - cosdir0_aux)**2
3749 indcos = cosDiff.argmin(axis = 1)
3763 indcos = cosDiff.argmin(axis = 1)
3750 #Saving Value obtained
3764 #Saving Value obtained
3751 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3765 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3752
3766
3753 return cosdir0, cosdir
3767 return cosdir0, cosdir
3754
3768
3755 def __calculateAOA(self, cosdir, azimuth):
3769 def __calculateAOA(self, cosdir, azimuth):
3756 cosdirX = cosdir[:,0]
3770 cosdirX = cosdir[:,0]
3757 cosdirY = cosdir[:,1]
3771 cosdirY = cosdir[:,1]
3758
3772
3759 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3773 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3760 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
3774 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
3761 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3775 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3762
3776
3763 return angles
3777 return angles
3764
3778
3765 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3779 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3766
3780
3767 Ramb = 375 #Ramb = c/(2*PRF)
3781 Ramb = 375 #Ramb = c/(2*PRF)
3768 Re = 6371 #Earth Radius
3782 Re = 6371 #Earth Radius
3769 heights = numpy.zeros(Ranges.shape)
3783 heights = numpy.zeros(Ranges.shape)
3770
3784
3771 R_aux = numpy.array([0,1,2])*Ramb
3785 R_aux = numpy.array([0,1,2])*Ramb
3772 R_aux = R_aux.reshape(1,R_aux.size)
3786 R_aux = R_aux.reshape(1,R_aux.size)
3773
3787
3774 Ranges = Ranges.reshape(Ranges.size,1)
3788 Ranges = Ranges.reshape(Ranges.size,1)
3775
3789
3776 Ri = Ranges + R_aux
3790 Ri = Ranges + R_aux
3777 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3791 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3778
3792
3779 #Check if there is a height between 70 and 110 km
3793 #Check if there is a height between 70 and 110 km
3780 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3794 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3781 ind_h = numpy.where(h_bool == 1)[0]
3795 ind_h = numpy.where(h_bool == 1)[0]
3782
3796
3783 hCorr = hi[ind_h, :]
3797 hCorr = hi[ind_h, :]
3784 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3798 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3785
3799
3786 hCorr = hi[ind_hCorr][:len(ind_h)]
3800 hCorr = hi[ind_hCorr][:len(ind_h)]
3787 heights[ind_h] = hCorr
3801 heights[ind_h] = hCorr
3788
3802
3789 #Setting Error
3803 #Setting Error
3790 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3804 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3791 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3805 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3792 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
3806 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
3793 error[indError] = 0
3807 error[indError] = 0
3794 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3808 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3795 error[indInvalid2] = 14
3809 error[indInvalid2] = 14
3796 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3810 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3797 error[indInvalid1] = 13
3811 error[indInvalid1] = 13
3798
3812
3799 return heights, error
3813 return heights, error
3800
3814
3801 def getPhasePairs(self, channelPositions):
3815 def getPhasePairs(self, channelPositions):
3802 chanPos = numpy.array(channelPositions)
3816 chanPos = numpy.array(channelPositions)
3803 listOper = list(itertools.combinations(list(range(5)),2))
3817 listOper = list(itertools.combinations(list(range(5)),2))
3804
3818
3805 distances = numpy.zeros(4)
3819 distances = numpy.zeros(4)
3806 axisX = []
3820 axisX = []
3807 axisY = []
3821 axisY = []
3808 distX = numpy.zeros(3)
3822 distX = numpy.zeros(3)
3809 distY = numpy.zeros(3)
3823 distY = numpy.zeros(3)
3810 ix = 0
3824 ix = 0
3811 iy = 0
3825 iy = 0
3812
3826
3813 pairX = numpy.zeros((2,2))
3827 pairX = numpy.zeros((2,2))
3814 pairY = numpy.zeros((2,2))
3828 pairY = numpy.zeros((2,2))
3815
3829
3816 for i in range(len(listOper)):
3830 for i in range(len(listOper)):
3817 pairi = listOper[i]
3831 pairi = listOper[i]
3818
3832
3819 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
3833 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
3820
3834
3821 if posDif[0] == 0:
3835 if posDif[0] == 0:
3822 axisY.append(pairi)
3836 axisY.append(pairi)
3823 distY[iy] = posDif[1]
3837 distY[iy] = posDif[1]
3824 iy += 1
3838 iy += 1
3825 elif posDif[1] == 0:
3839 elif posDif[1] == 0:
3826 axisX.append(pairi)
3840 axisX.append(pairi)
3827 distX[ix] = posDif[0]
3841 distX[ix] = posDif[0]
3828 ix += 1
3842 ix += 1
3829
3843
3830 for i in range(2):
3844 for i in range(2):
3831 if i==0:
3845 if i==0:
3832 dist0 = distX
3846 dist0 = distX
3833 axis0 = axisX
3847 axis0 = axisX
3834 else:
3848 else:
3835 dist0 = distY
3849 dist0 = distY
3836 axis0 = axisY
3850 axis0 = axisY
3837
3851
3838 side = numpy.argsort(dist0)[:-1]
3852 side = numpy.argsort(dist0)[:-1]
3839 axis0 = numpy.array(axis0)[side,:]
3853 axis0 = numpy.array(axis0)[side,:]
3840 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
3854 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
3841 axis1 = numpy.unique(numpy.reshape(axis0,4))
3855 axis1 = numpy.unique(numpy.reshape(axis0,4))
3842 side = axis1[axis1 != chanC]
3856 side = axis1[axis1 != chanC]
3843 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
3857 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
3844 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
3858 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
3845 if diff1<0:
3859 if diff1<0:
3846 chan2 = side[0]
3860 chan2 = side[0]
3847 d2 = numpy.abs(diff1)
3861 d2 = numpy.abs(diff1)
3848 chan1 = side[1]
3862 chan1 = side[1]
3849 d1 = numpy.abs(diff2)
3863 d1 = numpy.abs(diff2)
3850 else:
3864 else:
3851 chan2 = side[1]
3865 chan2 = side[1]
3852 d2 = numpy.abs(diff2)
3866 d2 = numpy.abs(diff2)
3853 chan1 = side[0]
3867 chan1 = side[0]
3854 d1 = numpy.abs(diff1)
3868 d1 = numpy.abs(diff1)
3855
3869
3856 if i==0:
3870 if i==0:
3857 chanCX = chanC
3871 chanCX = chanC
3858 chan1X = chan1
3872 chan1X = chan1
3859 chan2X = chan2
3873 chan2X = chan2
3860 distances[0:2] = numpy.array([d1,d2])
3874 distances[0:2] = numpy.array([d1,d2])
3861 else:
3875 else:
3862 chanCY = chanC
3876 chanCY = chanC
3863 chan1Y = chan1
3877 chan1Y = chan1
3864 chan2Y = chan2
3878 chan2Y = chan2
3865 distances[2:4] = numpy.array([d1,d2])
3879 distances[2:4] = numpy.array([d1,d2])
3866 # axisXsides = numpy.reshape(axisX[ix,:],4)
3880 # axisXsides = numpy.reshape(axisX[ix,:],4)
3867 #
3881 #
3868 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
3882 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
3869 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
3883 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
3870 #
3884 #
3871 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
3885 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
3872 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
3886 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
3873 # channel25X = int(pairX[0,ind25X])
3887 # channel25X = int(pairX[0,ind25X])
3874 # channel20X = int(pairX[1,ind20X])
3888 # channel20X = int(pairX[1,ind20X])
3875 # ind25Y = numpy.where(pairY[0,:] != channelCentY)[0][0]
3889 # ind25Y = numpy.where(pairY[0,:] != channelCentY)[0][0]
3876 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
3890 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
3877 # channel25Y = int(pairY[0,ind25Y])
3891 # channel25Y = int(pairY[0,ind25Y])
3878 # channel20Y = int(pairY[1,ind20Y])
3892 # channel20Y = int(pairY[1,ind20Y])
3879
3893
3880 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
3894 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
3881 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
3895 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
3882
3896
3883 return pairslist, distances
3897 return pairslist, distances
3884 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
3898 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
3885 #
3899 #
3886 # arrayAOA = numpy.zeros((phases.shape[0],3))
3900 # arrayAOA = numpy.zeros((phases.shape[0],3))
3887 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
3901 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
3888 #
3902 #
3889 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3903 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3890 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3904 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3891 # arrayAOA[:,2] = cosDirError
3905 # arrayAOA[:,2] = cosDirError
3892 #
3906 #
3893 # azimuthAngle = arrayAOA[:,0]
3907 # azimuthAngle = arrayAOA[:,0]
3894 # zenithAngle = arrayAOA[:,1]
3908 # zenithAngle = arrayAOA[:,1]
3895 #
3909 #
3896 # #Setting Error
3910 # #Setting Error
3897 # #Number 3: AOA not fesible
3911 # #Number 3: AOA not fesible
3898 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3912 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3899 # error[indInvalid] = 3
3913 # error[indInvalid] = 3
3900 # #Number 4: Large difference in AOAs obtained from different antenna baselines
3914 # #Number 4: Large difference in AOAs obtained from different antenna baselines
3901 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3915 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3902 # error[indInvalid] = 4
3916 # error[indInvalid] = 4
3903 # return arrayAOA, error
3917 # return arrayAOA, error
3904 #
3918 #
3905 # def __getDirectionCosines(self, arrayPhase, pairsList):
3919 # def __getDirectionCosines(self, arrayPhase, pairsList):
3906 #
3920 #
3907 # #Initializing some variables
3921 # #Initializing some variables
3908 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3922 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3909 # ang_aux = ang_aux.reshape(1,ang_aux.size)
3923 # ang_aux = ang_aux.reshape(1,ang_aux.size)
3910 #
3924 #
3911 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
3925 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
3912 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3926 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3913 #
3927 #
3914 #
3928 #
3915 # for i in range(2):
3929 # for i in range(2):
3916 # #First Estimation
3930 # #First Estimation
3917 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
3931 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
3918 # #Dealias
3932 # #Dealias
3919 # indcsi = numpy.where(phi0_aux > numpy.pi)
3933 # indcsi = numpy.where(phi0_aux > numpy.pi)
3920 # phi0_aux[indcsi] -= 2*numpy.pi
3934 # phi0_aux[indcsi] -= 2*numpy.pi
3921 # indcsi = numpy.where(phi0_aux < -numpy.pi)
3935 # indcsi = numpy.where(phi0_aux < -numpy.pi)
3922 # phi0_aux[indcsi] += 2*numpy.pi
3936 # phi0_aux[indcsi] += 2*numpy.pi
3923 # #Direction Cosine 0
3937 # #Direction Cosine 0
3924 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
3938 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
3925 #
3939 #
3926 # #Most-Accurate Second Estimation
3940 # #Most-Accurate Second Estimation
3927 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
3941 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
3928 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3942 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3929 # #Direction Cosine 1
3943 # #Direction Cosine 1
3930 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
3944 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
3931 #
3945 #
3932 # #Searching the correct Direction Cosine
3946 # #Searching the correct Direction Cosine
3933 # cosdir0_aux = cosdir0[:,i]
3947 # cosdir0_aux = cosdir0[:,i]
3934 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3948 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3935 # #Minimum Distance
3949 # #Minimum Distance
3936 # cosDiff = (cosdir1 - cosdir0_aux)**2
3950 # cosDiff = (cosdir1 - cosdir0_aux)**2
3937 # indcos = cosDiff.argmin(axis = 1)
3951 # indcos = cosDiff.argmin(axis = 1)
3938 # #Saving Value obtained
3952 # #Saving Value obtained
3939 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3953 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3940 #
3954 #
3941 # return cosdir0, cosdir
3955 # return cosdir0, cosdir
3942 #
3956 #
3943 # def __calculateAOA(self, cosdir, azimuth):
3957 # def __calculateAOA(self, cosdir, azimuth):
3944 # cosdirX = cosdir[:,0]
3958 # cosdirX = cosdir[:,0]
3945 # cosdirY = cosdir[:,1]
3959 # cosdirY = cosdir[:,1]
3946 #
3960 #
3947 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3961 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3948 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
3962 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
3949 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3963 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3950 #
3964 #
3951 # return angles
3965 # return angles
3952 #
3966 #
3953 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3967 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3954 #
3968 #
3955 # Ramb = 375 #Ramb = c/(2*PRF)
3969 # Ramb = 375 #Ramb = c/(2*PRF)
3956 # Re = 6371 #Earth Radius
3970 # Re = 6371 #Earth Radius
3957 # heights = numpy.zeros(Ranges.shape)
3971 # heights = numpy.zeros(Ranges.shape)
3958 #
3972 #
3959 # R_aux = numpy.array([0,1,2])*Ramb
3973 # R_aux = numpy.array([0,1,2])*Ramb
3960 # R_aux = R_aux.reshape(1,R_aux.size)
3974 # R_aux = R_aux.reshape(1,R_aux.size)
3961 #
3975 #
3962 # Ranges = Ranges.reshape(Ranges.size,1)
3976 # Ranges = Ranges.reshape(Ranges.size,1)
3963 #
3977 #
3964 # Ri = Ranges + R_aux
3978 # Ri = Ranges + R_aux
3965 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3979 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3966 #
3980 #
3967 # #Check if there is a height between 70 and 110 km
3981 # #Check if there is a height between 70 and 110 km
3968 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3982 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3969 # ind_h = numpy.where(h_bool == 1)[0]
3983 # ind_h = numpy.where(h_bool == 1)[0]
3970 #
3984 #
3971 # hCorr = hi[ind_h, :]
3985 # hCorr = hi[ind_h, :]
3972 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3986 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3973 #
3987 #
3974 # hCorr = hi[ind_hCorr]
3988 # hCorr = hi[ind_hCorr]
3975 # heights[ind_h] = hCorr
3989 # heights[ind_h] = hCorr
3976 #
3990 #
3977 # #Setting Error
3991 # #Setting Error
3978 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3992 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3979 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3993 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3980 #
3994 #
3981 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3995 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3982 # error[indInvalid2] = 14
3996 # error[indInvalid2] = 14
3983 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3997 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3984 # error[indInvalid1] = 13
3998 # error[indInvalid1] = 13
3985 #
3999 #
3986 # return heights, error
4000 # return heights, error
3987 No newline at end of file
@@ -1,1604 +1,1627
1 import sys
1 import sys
2 import numpy,math
2 import numpy,math
3 from scipy import interpolate
3 from scipy import interpolate
4 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
4 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
5 from schainpy.model.data.jrodata import Voltage
5 from schainpy.model.data.jrodata import Voltage,hildebrand_sekhon
6 from schainpy.utils import log
6 from schainpy.utils import log
7 from time import time
7 from time import time
8
8
9
9
10
10
11 class VoltageProc(ProcessingUnit):
11 class VoltageProc(ProcessingUnit):
12
12
13 def __init__(self):
13 def __init__(self):
14
14
15 ProcessingUnit.__init__(self)
15 ProcessingUnit.__init__(self)
16
16
17 self.dataOut = Voltage()
17 self.dataOut = Voltage()
18 self.flip = 1
18 self.flip = 1
19 self.setupReq = False
19 self.setupReq = False
20
20
21 def run(self):
21 def run(self):
22
22
23 if self.dataIn.type == 'AMISR':
23 if self.dataIn.type == 'AMISR':
24 self.__updateObjFromAmisrInput()
24 self.__updateObjFromAmisrInput()
25
25
26 if self.dataIn.type == 'Voltage':
26 if self.dataIn.type == 'Voltage':
27 self.dataOut.copy(self.dataIn)
27 self.dataOut.copy(self.dataIn)
28
28
29 def __updateObjFromAmisrInput(self):
29 def __updateObjFromAmisrInput(self):
30
30
31 self.dataOut.timeZone = self.dataIn.timeZone
31 self.dataOut.timeZone = self.dataIn.timeZone
32 self.dataOut.dstFlag = self.dataIn.dstFlag
32 self.dataOut.dstFlag = self.dataIn.dstFlag
33 self.dataOut.errorCount = self.dataIn.errorCount
33 self.dataOut.errorCount = self.dataIn.errorCount
34 self.dataOut.useLocalTime = self.dataIn.useLocalTime
34 self.dataOut.useLocalTime = self.dataIn.useLocalTime
35
35
36 self.dataOut.flagNoData = self.dataIn.flagNoData
36 self.dataOut.flagNoData = self.dataIn.flagNoData
37 self.dataOut.data = self.dataIn.data
37 self.dataOut.data = self.dataIn.data
38 self.dataOut.utctime = self.dataIn.utctime
38 self.dataOut.utctime = self.dataIn.utctime
39 self.dataOut.channelList = self.dataIn.channelList
39 self.dataOut.channelList = self.dataIn.channelList
40 #self.dataOut.timeInterval = self.dataIn.timeInterval
40 #self.dataOut.timeInterval = self.dataIn.timeInterval
41 self.dataOut.heightList = self.dataIn.heightList
41 self.dataOut.heightList = self.dataIn.heightList
42 self.dataOut.nProfiles = self.dataIn.nProfiles
42 self.dataOut.nProfiles = self.dataIn.nProfiles
43
43
44 self.dataOut.nCohInt = self.dataIn.nCohInt
44 self.dataOut.nCohInt = self.dataIn.nCohInt
45 self.dataOut.ippSeconds = self.dataIn.ippSeconds
45 self.dataOut.ippSeconds = self.dataIn.ippSeconds
46 self.dataOut.frequency = self.dataIn.frequency
46 self.dataOut.frequency = self.dataIn.frequency
47
47
48 self.dataOut.azimuth = self.dataIn.azimuth
48 self.dataOut.azimuth = self.dataIn.azimuth
49 self.dataOut.zenith = self.dataIn.zenith
49 self.dataOut.zenith = self.dataIn.zenith
50
50
51 self.dataOut.beam.codeList = self.dataIn.beam.codeList
51 self.dataOut.beam.codeList = self.dataIn.beam.codeList
52 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
52 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
53 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
53 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
54
54
55
55
56 class selectChannels(Operation):
56 class selectChannels(Operation):
57
57
58 def run(self, dataOut, channelList):
58 def run(self, dataOut, channelList):
59
59
60 channelIndexList = []
60 channelIndexList = []
61 self.dataOut = dataOut
61 self.dataOut = dataOut
62 for channel in channelList:
62 for channel in channelList:
63 if channel not in self.dataOut.channelList:
63 if channel not in self.dataOut.channelList:
64 raise ValueError("Channel %d is not in %s" %(channel, str(self.dataOut.channelList)))
64 raise ValueError("Channel %d is not in %s" %(channel, str(self.dataOut.channelList)))
65
65
66 index = self.dataOut.channelList.index(channel)
66 index = self.dataOut.channelList.index(channel)
67 channelIndexList.append(index)
67 channelIndexList.append(index)
68 self.selectChannelsByIndex(channelIndexList)
68 self.selectChannelsByIndex(channelIndexList)
69 return self.dataOut
69 return self.dataOut
70
70
71 def selectChannelsByIndex(self, channelIndexList):
71 def selectChannelsByIndex(self, channelIndexList):
72 """
72 """
73 Selecciona un bloque de datos en base a canales segun el channelIndexList
73 Selecciona un bloque de datos en base a canales segun el channelIndexList
74
74
75 Input:
75 Input:
76 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
76 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
77
77
78 Affected:
78 Affected:
79 self.dataOut.data
79 self.dataOut.data
80 self.dataOut.channelIndexList
80 self.dataOut.channelIndexList
81 self.dataOut.nChannels
81 self.dataOut.nChannels
82 self.dataOut.m_ProcessingHeader.totalSpectra
82 self.dataOut.m_ProcessingHeader.totalSpectra
83 self.dataOut.systemHeaderObj.numChannels
83 self.dataOut.systemHeaderObj.numChannels
84 self.dataOut.m_ProcessingHeader.blockSize
84 self.dataOut.m_ProcessingHeader.blockSize
85
85
86 Return:
86 Return:
87 None
87 None
88 """
88 """
89
89
90 for channelIndex in channelIndexList:
90 for channelIndex in channelIndexList:
91 if channelIndex not in self.dataOut.channelIndexList:
91 if channelIndex not in self.dataOut.channelIndexList:
92 raise ValueError("The value %d in channelIndexList is not valid" %channelIndex)
92 raise ValueError("The value %d in channelIndexList is not valid" %channelIndex)
93
93
94 if self.dataOut.type == 'Voltage':
94 if self.dataOut.type == 'Voltage':
95 if self.dataOut.flagDataAsBlock:
95 if self.dataOut.flagDataAsBlock:
96 """
96 """
97 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
97 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
98 """
98 """
99 data = self.dataOut.data[channelIndexList,:,:]
99 data = self.dataOut.data[channelIndexList,:,:]
100 else:
100 else:
101 data = self.dataOut.data[channelIndexList,:]
101 data = self.dataOut.data[channelIndexList,:]
102
102
103 self.dataOut.data = data
103 self.dataOut.data = data
104 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
104 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
105 self.dataOut.channelList = range(len(channelIndexList))
105 self.dataOut.channelList = range(len(channelIndexList))
106
106
107 elif self.dataOut.type == 'Spectra':
107 elif self.dataOut.type == 'Spectra':
108 data_spc = self.dataOut.data_spc[channelIndexList, :]
108 data_spc = self.dataOut.data_spc[channelIndexList, :]
109 data_dc = self.dataOut.data_dc[channelIndexList, :]
109 data_dc = self.dataOut.data_dc[channelIndexList, :]
110
110
111 self.dataOut.data_spc = data_spc
111 self.dataOut.data_spc = data_spc
112 self.dataOut.data_dc = data_dc
112 self.dataOut.data_dc = data_dc
113
113
114 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
114 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
115 self.dataOut.channelList = range(len(channelIndexList))
115 self.dataOut.channelList = range(len(channelIndexList))
116 self.__selectPairsByChannel(channelIndexList)
116 self.__selectPairsByChannel(channelIndexList)
117
117
118 return 1
118 return 1
119
119
120 def __selectPairsByChannel(self, channelList=None):
120 def __selectPairsByChannel(self, channelList=None):
121
121
122 if channelList == None:
122 if channelList == None:
123 return
123 return
124
124
125 pairsIndexListSelected = []
125 pairsIndexListSelected = []
126 for pairIndex in self.dataOut.pairsIndexList:
126 for pairIndex in self.dataOut.pairsIndexList:
127 # First pair
127 # First pair
128 if self.dataOut.pairsList[pairIndex][0] not in channelList:
128 if self.dataOut.pairsList[pairIndex][0] not in channelList:
129 continue
129 continue
130 # Second pair
130 # Second pair
131 if self.dataOut.pairsList[pairIndex][1] not in channelList:
131 if self.dataOut.pairsList[pairIndex][1] not in channelList:
132 continue
132 continue
133
133
134 pairsIndexListSelected.append(pairIndex)
134 pairsIndexListSelected.append(pairIndex)
135
135
136 if not pairsIndexListSelected:
136 if not pairsIndexListSelected:
137 self.dataOut.data_cspc = None
137 self.dataOut.data_cspc = None
138 self.dataOut.pairsList = []
138 self.dataOut.pairsList = []
139 return
139 return
140
140
141 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndexListSelected]
141 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndexListSelected]
142 self.dataOut.pairsList = [self.dataOut.pairsList[i]
142 self.dataOut.pairsList = [self.dataOut.pairsList[i]
143 for i in pairsIndexListSelected]
143 for i in pairsIndexListSelected]
144
144
145 return
145 return
146
146
147 class selectHeights(Operation):
147 class selectHeights(Operation):
148
148
149 def run(self, dataOut, minHei=None, maxHei=None):
149 def run(self, dataOut, minHei=None, maxHei=None):
150 """
150 """
151 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
151 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
152 minHei <= height <= maxHei
152 minHei <= height <= maxHei
153
153
154 Input:
154 Input:
155 minHei : valor minimo de altura a considerar
155 minHei : valor minimo de altura a considerar
156 maxHei : valor maximo de altura a considerar
156 maxHei : valor maximo de altura a considerar
157
157
158 Affected:
158 Affected:
159 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
159 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
160
160
161 Return:
161 Return:
162 1 si el metodo se ejecuto con exito caso contrario devuelve 0
162 1 si el metodo se ejecuto con exito caso contrario devuelve 0
163 """
163 """
164
164
165 self.dataOut = dataOut
165 self.dataOut = dataOut
166
166
167 if minHei == None:
167 if minHei == None:
168 minHei = self.dataOut.heightList[0]
168 minHei = self.dataOut.heightList[0]
169
169
170 if maxHei == None:
170 if maxHei == None:
171 maxHei = self.dataOut.heightList[-1]
171 maxHei = self.dataOut.heightList[-1]
172
172
173 if (minHei < self.dataOut.heightList[0]):
173 if (minHei < self.dataOut.heightList[0]):
174 minHei = self.dataOut.heightList[0]
174 minHei = self.dataOut.heightList[0]
175
175
176 if (maxHei > self.dataOut.heightList[-1]):
176 if (maxHei > self.dataOut.heightList[-1]):
177 maxHei = self.dataOut.heightList[-1]
177 maxHei = self.dataOut.heightList[-1]
178
178
179 minIndex = 0
179 minIndex = 0
180 maxIndex = 0
180 maxIndex = 0
181 heights = self.dataOut.heightList
181 heights = self.dataOut.heightList
182
182
183 inda = numpy.where(heights >= minHei)
183 inda = numpy.where(heights >= minHei)
184 indb = numpy.where(heights <= maxHei)
184 indb = numpy.where(heights <= maxHei)
185
185
186 try:
186 try:
187 minIndex = inda[0][0]
187 minIndex = inda[0][0]
188 except:
188 except:
189 minIndex = 0
189 minIndex = 0
190
190
191 try:
191 try:
192 maxIndex = indb[0][-1]
192 maxIndex = indb[0][-1]
193 except:
193 except:
194 maxIndex = len(heights)
194 maxIndex = len(heights)
195
195
196 self.selectHeightsByIndex(minIndex, maxIndex)
196 self.selectHeightsByIndex(minIndex, maxIndex)
197
197
198 return self.dataOut
198 return self.dataOut
199
199
200 def selectHeightsByIndex(self, minIndex, maxIndex):
200 def selectHeightsByIndex(self, minIndex, maxIndex):
201 """
201 """
202 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
202 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
203 minIndex <= index <= maxIndex
203 minIndex <= index <= maxIndex
204
204
205 Input:
205 Input:
206 minIndex : valor de indice minimo de altura a considerar
206 minIndex : valor de indice minimo de altura a considerar
207 maxIndex : valor de indice maximo de altura a considerar
207 maxIndex : valor de indice maximo de altura a considerar
208
208
209 Affected:
209 Affected:
210 self.dataOut.data
210 self.dataOut.data
211 self.dataOut.heightList
211 self.dataOut.heightList
212
212
213 Return:
213 Return:
214 1 si el metodo se ejecuto con exito caso contrario devuelve 0
214 1 si el metodo se ejecuto con exito caso contrario devuelve 0
215 """
215 """
216
216
217 if self.dataOut.type == 'Voltage':
217 if self.dataOut.type == 'Voltage':
218 if (minIndex < 0) or (minIndex > maxIndex):
218 if (minIndex < 0) or (minIndex > maxIndex):
219 raise ValueError("Height index range (%d,%d) is not valid" % (minIndex, maxIndex))
219 raise ValueError("Height index range (%d,%d) is not valid" % (minIndex, maxIndex))
220
220
221 if (maxIndex >= self.dataOut.nHeights):
221 if (maxIndex >= self.dataOut.nHeights):
222 maxIndex = self.dataOut.nHeights
222 maxIndex = self.dataOut.nHeights
223
223
224 #voltage
224 #voltage
225 if self.dataOut.flagDataAsBlock:
225 if self.dataOut.flagDataAsBlock:
226 """
226 """
227 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
227 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
228 """
228 """
229 data = self.dataOut.data[:,:, minIndex:maxIndex]
229 data = self.dataOut.data[:,:, minIndex:maxIndex]
230 else:
230 else:
231 data = self.dataOut.data[:, minIndex:maxIndex]
231 data = self.dataOut.data[:, minIndex:maxIndex]
232
232
233 # firstHeight = self.dataOut.heightList[minIndex]
233 # firstHeight = self.dataOut.heightList[minIndex]
234
234
235 self.dataOut.data = data
235 self.dataOut.data = data
236 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex]
236 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex]
237
237
238 if self.dataOut.nHeights <= 1:
238 if self.dataOut.nHeights <= 1:
239 raise ValueError("selectHeights: Too few heights. Current number of heights is %d" %(self.dataOut.nHeights))
239 raise ValueError("selectHeights: Too few heights. Current number of heights is %d" %(self.dataOut.nHeights))
240 elif self.dataOut.type == 'Spectra':
240 elif self.dataOut.type == 'Spectra':
241 if (minIndex < 0) or (minIndex > maxIndex):
241 if (minIndex < 0) or (minIndex > maxIndex):
242 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (
242 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (
243 minIndex, maxIndex))
243 minIndex, maxIndex))
244
244
245 if (maxIndex >= self.dataOut.nHeights):
245 if (maxIndex >= self.dataOut.nHeights):
246 maxIndex = self.dataOut.nHeights - 1
246 maxIndex = self.dataOut.nHeights - 1
247
247
248 # Spectra
248 # Spectra
249 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
249 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
250
250
251 data_cspc = None
251 data_cspc = None
252 if self.dataOut.data_cspc is not None:
252 if self.dataOut.data_cspc is not None:
253 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
253 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
254
254
255 data_dc = None
255 data_dc = None
256 if self.dataOut.data_dc is not None:
256 if self.dataOut.data_dc is not None:
257 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
257 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
258
258
259 self.dataOut.data_spc = data_spc
259 self.dataOut.data_spc = data_spc
260 self.dataOut.data_cspc = data_cspc
260 self.dataOut.data_cspc = data_cspc
261 self.dataOut.data_dc = data_dc
261 self.dataOut.data_dc = data_dc
262
262
263 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
263 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
264
264
265 return 1
265 return 1
266
266
267
267
268 class filterByHeights(Operation):
268 class filterByHeights(Operation):
269
269
270 def run(self, dataOut, window):
270 def run(self, dataOut, window):
271
271
272 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
272 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
273
273
274 if window == None:
274 if window == None:
275 window = (dataOut.radarControllerHeaderObj.txA/dataOut.radarControllerHeaderObj.nBaud) / deltaHeight
275 window = (dataOut.radarControllerHeaderObj.txA/dataOut.radarControllerHeaderObj.nBaud) / deltaHeight
276
276
277 newdelta = deltaHeight * window
277 newdelta = deltaHeight * window
278 r = dataOut.nHeights % window
278 r = dataOut.nHeights % window
279 newheights = (dataOut.nHeights-r)/window
279 newheights = (dataOut.nHeights-r)/window
280
280
281 if newheights <= 1:
281 if newheights <= 1:
282 raise ValueError("filterByHeights: Too few heights. Current number of heights is %d and window is %d" %(dataOut.nHeights, window))
282 raise ValueError("filterByHeights: Too few heights. Current number of heights is %d and window is %d" %(dataOut.nHeights, window))
283
283
284 if dataOut.flagDataAsBlock:
284 if dataOut.flagDataAsBlock:
285 """
285 """
286 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
286 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
287 """
287 """
288 buffer = dataOut.data[:, :, 0:int(dataOut.nHeights-r)]
288 buffer = dataOut.data[:, :, 0:int(dataOut.nHeights-r)]
289 buffer = buffer.reshape(dataOut.nChannels, dataOut.nProfiles, int(dataOut.nHeights/window), window)
289 buffer = buffer.reshape(dataOut.nChannels, dataOut.nProfiles, int(dataOut.nHeights/window), window)
290 buffer = numpy.sum(buffer,3)
290 buffer = numpy.sum(buffer,3)
291
291
292 else:
292 else:
293 buffer = dataOut.data[:,0:int(dataOut.nHeights-r)]
293 buffer = dataOut.data[:,0:int(dataOut.nHeights-r)]
294 buffer = buffer.reshape(dataOut.nChannels,int(dataOut.nHeights/window),int(window))
294 buffer = buffer.reshape(dataOut.nChannels,int(dataOut.nHeights/window),int(window))
295 buffer = numpy.sum(buffer,2)
295 buffer = numpy.sum(buffer,2)
296
296
297 dataOut.data = buffer
297 dataOut.data = buffer
298 dataOut.heightList = dataOut.heightList[0] + numpy.arange( newheights )*newdelta
298 dataOut.heightList = dataOut.heightList[0] + numpy.arange( newheights )*newdelta
299 dataOut.windowOfFilter = window
299 dataOut.windowOfFilter = window
300
300
301 return dataOut
301 return dataOut
302
302
303
303
304 class setH0(Operation):
304 class setH0(Operation):
305
305
306 def run(self, dataOut, h0, deltaHeight = None):
306 def run(self, dataOut, h0, deltaHeight = None):
307
307
308 if not deltaHeight:
308 if not deltaHeight:
309 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
309 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
310
310
311 nHeights = dataOut.nHeights
311 nHeights = dataOut.nHeights
312
312
313 newHeiRange = h0 + numpy.arange(nHeights)*deltaHeight
313 newHeiRange = h0 + numpy.arange(nHeights)*deltaHeight
314
314
315 dataOut.heightList = newHeiRange
315 dataOut.heightList = newHeiRange
316
316
317 return dataOut
317 return dataOut
318
318
319
319
320 class deFlip(Operation):
320 class deFlip(Operation):
321
321
322 def run(self, dataOut, channelList = []):
322 def run(self, dataOut, channelList = []):
323
323
324 data = dataOut.data.copy()
324 data = dataOut.data.copy()
325
325
326 if dataOut.flagDataAsBlock:
326 if dataOut.flagDataAsBlock:
327 flip = self.flip
327 flip = self.flip
328 profileList = list(range(dataOut.nProfiles))
328 profileList = list(range(dataOut.nProfiles))
329
329
330 if not channelList:
330 if not channelList:
331 for thisProfile in profileList:
331 for thisProfile in profileList:
332 data[:,thisProfile,:] = data[:,thisProfile,:]*flip
332 data[:,thisProfile,:] = data[:,thisProfile,:]*flip
333 flip *= -1.0
333 flip *= -1.0
334 else:
334 else:
335 for thisChannel in channelList:
335 for thisChannel in channelList:
336 if thisChannel not in dataOut.channelList:
336 if thisChannel not in dataOut.channelList:
337 continue
337 continue
338
338
339 for thisProfile in profileList:
339 for thisProfile in profileList:
340 data[thisChannel,thisProfile,:] = data[thisChannel,thisProfile,:]*flip
340 data[thisChannel,thisProfile,:] = data[thisChannel,thisProfile,:]*flip
341 flip *= -1.0
341 flip *= -1.0
342
342
343 self.flip = flip
343 self.flip = flip
344
344
345 else:
345 else:
346 if not channelList:
346 if not channelList:
347 data[:,:] = data[:,:]*self.flip
347 data[:,:] = data[:,:]*self.flip
348 else:
348 else:
349 for thisChannel in channelList:
349 for thisChannel in channelList:
350 if thisChannel not in dataOut.channelList:
350 if thisChannel not in dataOut.channelList:
351 continue
351 continue
352
352
353 data[thisChannel,:] = data[thisChannel,:]*self.flip
353 data[thisChannel,:] = data[thisChannel,:]*self.flip
354
354
355 self.flip *= -1.
355 self.flip *= -1.
356
356
357 dataOut.data = data
357 dataOut.data = data
358
358
359 return dataOut
359 return dataOut
360
360
361
361
362 class setAttribute(Operation):
362 class setAttribute(Operation):
363 '''
363 '''
364 Set an arbitrary attribute(s) to dataOut
364 Set an arbitrary attribute(s) to dataOut
365 '''
365 '''
366
366
367 def __init__(self):
367 def __init__(self):
368
368
369 Operation.__init__(self)
369 Operation.__init__(self)
370 self._ready = False
370 self._ready = False
371
371
372 def run(self, dataOut, **kwargs):
372 def run(self, dataOut, **kwargs):
373
373
374 for key, value in kwargs.items():
374 for key, value in kwargs.items():
375 setattr(dataOut, key, value)
375 setattr(dataOut, key, value)
376
376
377 return dataOut
377 return dataOut
378
378
379
379
380 @MPDecorator
380 @MPDecorator
381 class printAttribute(Operation):
381 class printAttribute(Operation):
382 '''
382 '''
383 Print an arbitrary attribute of dataOut
383 Print an arbitrary attribute of dataOut
384 '''
384 '''
385
385
386 def __init__(self):
386 def __init__(self):
387
387
388 Operation.__init__(self)
388 Operation.__init__(self)
389
389
390 def run(self, dataOut, attributes):
390 def run(self, dataOut, attributes):
391
391
392 for attr in attributes:
392 for attr in attributes:
393 if hasattr(dataOut, attr):
393 if hasattr(dataOut, attr):
394 log.log(getattr(dataOut, attr), attr)
394 log.log(getattr(dataOut, attr), attr)
395
395
396
396
397 class interpolateHeights(Operation):
397 class interpolateHeights(Operation):
398
398
399 def run(self, dataOut, topLim, botLim):
399 def run(self, dataOut, topLim, botLim):
400 #69 al 72 para julia
400 #69 al 72 para julia
401 #82-84 para meteoros
401 #82-84 para meteoros
402 if len(numpy.shape(dataOut.data))==2:
402 if len(numpy.shape(dataOut.data))==2:
403 sampInterp = (dataOut.data[:,botLim-1] + dataOut.data[:,topLim+1])/2
403 sampInterp = (dataOut.data[:,botLim-1] + dataOut.data[:,topLim+1])/2
404 sampInterp = numpy.transpose(numpy.tile(sampInterp,(topLim-botLim + 1,1)))
404 sampInterp = numpy.transpose(numpy.tile(sampInterp,(topLim-botLim + 1,1)))
405 #dataOut.data[:,botLim:limSup+1] = sampInterp
405 #dataOut.data[:,botLim:limSup+1] = sampInterp
406 dataOut.data[:,botLim:topLim+1] = sampInterp
406 dataOut.data[:,botLim:topLim+1] = sampInterp
407 else:
407 else:
408 nHeights = dataOut.data.shape[2]
408 nHeights = dataOut.data.shape[2]
409 x = numpy.hstack((numpy.arange(botLim),numpy.arange(topLim+1,nHeights)))
409 x = numpy.hstack((numpy.arange(botLim),numpy.arange(topLim+1,nHeights)))
410 y = dataOut.data[:,:,list(range(botLim))+list(range(topLim+1,nHeights))]
410 y = dataOut.data[:,:,list(range(botLim))+list(range(topLim+1,nHeights))]
411 f = interpolate.interp1d(x, y, axis = 2)
411 f = interpolate.interp1d(x, y, axis = 2)
412 xnew = numpy.arange(botLim,topLim+1)
412 xnew = numpy.arange(botLim,topLim+1)
413 ynew = f(xnew)
413 ynew = f(xnew)
414 dataOut.data[:,:,botLim:topLim+1] = ynew
414 dataOut.data[:,:,botLim:topLim+1] = ynew
415
415
416 return dataOut
416 return dataOut
417
417
418
418
419 class CohInt(Operation):
419 class CohInt(Operation):
420
420
421 isConfig = False
421 isConfig = False
422 __profIndex = 0
422 __profIndex = 0
423 __byTime = False
423 __byTime = False
424 __initime = None
424 __initime = None
425 __lastdatatime = None
425 __lastdatatime = None
426 __integrationtime = None
426 __integrationtime = None
427 __buffer = None
427 __buffer = None
428 __bufferStride = []
428 __bufferStride = []
429 __dataReady = False
429 __dataReady = False
430 __profIndexStride = 0
430 __profIndexStride = 0
431 __dataToPutStride = False
431 __dataToPutStride = False
432 n = None
432 n = None
433
433
434 def __init__(self, **kwargs):
434 def __init__(self, **kwargs):
435
435
436 Operation.__init__(self, **kwargs)
436 Operation.__init__(self, **kwargs)
437
437
438 def setup(self, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False):
438 def setup(self, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False):
439 """
439 """
440 Set the parameters of the integration class.
440 Set the parameters of the integration class.
441
441
442 Inputs:
442 Inputs:
443
443
444 n : Number of coherent integrations
444 n : Number of coherent integrations
445 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
445 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
446 overlapping :
446 overlapping :
447 """
447 """
448
448
449 self.__initime = None
449 self.__initime = None
450 self.__lastdatatime = 0
450 self.__lastdatatime = 0
451 self.__buffer = None
451 self.__buffer = None
452 self.__dataReady = False
452 self.__dataReady = False
453 self.byblock = byblock
453 self.byblock = byblock
454 self.stride = stride
454 self.stride = stride
455
455
456 if n == None and timeInterval == None:
456 if n == None and timeInterval == None:
457 raise ValueError("n or timeInterval should be specified ...")
457 raise ValueError("n or timeInterval should be specified ...")
458
458
459 if n != None:
459 if n != None:
460 self.n = n
460 self.n = n
461 self.__byTime = False
461 self.__byTime = False
462 else:
462 else:
463 self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line
463 self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line
464 self.n = 9999
464 self.n = 9999
465 self.__byTime = True
465 self.__byTime = True
466
466
467 if overlapping:
467 if overlapping:
468 self.__withOverlapping = True
468 self.__withOverlapping = True
469 self.__buffer = None
469 self.__buffer = None
470 else:
470 else:
471 self.__withOverlapping = False
471 self.__withOverlapping = False
472 self.__buffer = 0
472 self.__buffer = 0
473
473
474 self.__profIndex = 0
474 self.__profIndex = 0
475
475
476 def putData(self, data):
476 def putData(self, data):
477
477
478 """
478 """
479 Add a profile to the __buffer and increase in one the __profileIndex
479 Add a profile to the __buffer and increase in one the __profileIndex
480
480
481 """
481 """
482
482
483 if not self.__withOverlapping:
483 if not self.__withOverlapping:
484 self.__buffer += data.copy()
484 self.__buffer += data.copy()
485 self.__profIndex += 1
485 self.__profIndex += 1
486 return
486 return
487
487
488 #Overlapping data
488 #Overlapping data
489 nChannels, nHeis = data.shape
489 nChannels, nHeis = data.shape
490 data = numpy.reshape(data, (1, nChannels, nHeis))
490 data = numpy.reshape(data, (1, nChannels, nHeis))
491
491
492 #If the buffer is empty then it takes the data value
492 #If the buffer is empty then it takes the data value
493 if self.__buffer is None:
493 if self.__buffer is None:
494 self.__buffer = data
494 self.__buffer = data
495 self.__profIndex += 1
495 self.__profIndex += 1
496 return
496 return
497
497
498 #If the buffer length is lower than n then stakcing the data value
498 #If the buffer length is lower than n then stakcing the data value
499 if self.__profIndex < self.n:
499 if self.__profIndex < self.n:
500 self.__buffer = numpy.vstack((self.__buffer, data))
500 self.__buffer = numpy.vstack((self.__buffer, data))
501 self.__profIndex += 1
501 self.__profIndex += 1
502 return
502 return
503
503
504 #If the buffer length is equal to n then replacing the last buffer value with the data value
504 #If the buffer length is equal to n then replacing the last buffer value with the data value
505 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
505 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
506 self.__buffer[self.n-1] = data
506 self.__buffer[self.n-1] = data
507 self.__profIndex = self.n
507 self.__profIndex = self.n
508 return
508 return
509
509
510
510
511 def pushData(self):
511 def pushData(self):
512 """
512 """
513 Return the sum of the last profiles and the profiles used in the sum.
513 Return the sum of the last profiles and the profiles used in the sum.
514
514
515 Affected:
515 Affected:
516
516
517 self.__profileIndex
517 self.__profileIndex
518
518
519 """
519 """
520
520
521 if not self.__withOverlapping:
521 if not self.__withOverlapping:
522 data = self.__buffer
522 data = self.__buffer
523 n = self.__profIndex
523 n = self.__profIndex
524
524
525 self.__buffer = 0
525 self.__buffer = 0
526 self.__profIndex = 0
526 self.__profIndex = 0
527
527
528 return data, n
528 return data, n
529
529
530 #Integration with Overlapping
530 #Integration with Overlapping
531 data = numpy.sum(self.__buffer, axis=0)
531 data = numpy.sum(self.__buffer, axis=0)
532 # print data
532 # print data
533 # raise
533 # raise
534 n = self.__profIndex
534 n = self.__profIndex
535
535
536 return data, n
536 return data, n
537
537
538 def byProfiles(self, data):
538 def byProfiles(self, data):
539
539
540 self.__dataReady = False
540 self.__dataReady = False
541 avgdata = None
541 avgdata = None
542 # n = None
542 # n = None
543 # print data
543 # print data
544 # raise
544 # raise
545 self.putData(data)
545 self.putData(data)
546
546
547 if self.__profIndex == self.n:
547 if self.__profIndex == self.n:
548 avgdata, n = self.pushData()
548 avgdata, n = self.pushData()
549 self.__dataReady = True
549 self.__dataReady = True
550
550
551 return avgdata
551 return avgdata
552
552
553 def byTime(self, data, datatime):
553 def byTime(self, data, datatime):
554
554
555 self.__dataReady = False
555 self.__dataReady = False
556 avgdata = None
556 avgdata = None
557 n = None
557 n = None
558
558
559 self.putData(data)
559 self.putData(data)
560
560
561 if (datatime - self.__initime) >= self.__integrationtime:
561 if (datatime - self.__initime) >= self.__integrationtime:
562 avgdata, n = self.pushData()
562 avgdata, n = self.pushData()
563 self.n = n
563 self.n = n
564 self.__dataReady = True
564 self.__dataReady = True
565
565
566 return avgdata
566 return avgdata
567
567
568 def integrateByStride(self, data, datatime):
568 def integrateByStride(self, data, datatime):
569 # print data
569 # print data
570 if self.__profIndex == 0:
570 if self.__profIndex == 0:
571 self.__buffer = [[data.copy(), datatime]]
571 self.__buffer = [[data.copy(), datatime]]
572 else:
572 else:
573 self.__buffer.append([data.copy(),datatime])
573 self.__buffer.append([data.copy(),datatime])
574 self.__profIndex += 1
574 self.__profIndex += 1
575 self.__dataReady = False
575 self.__dataReady = False
576
576
577 if self.__profIndex == self.n * self.stride :
577 if self.__profIndex == self.n * self.stride :
578 self.__dataToPutStride = True
578 self.__dataToPutStride = True
579 self.__profIndexStride = 0
579 self.__profIndexStride = 0
580 self.__profIndex = 0
580 self.__profIndex = 0
581 self.__bufferStride = []
581 self.__bufferStride = []
582 for i in range(self.stride):
582 for i in range(self.stride):
583 current = self.__buffer[i::self.stride]
583 current = self.__buffer[i::self.stride]
584 data = numpy.sum([t[0] for t in current], axis=0)
584 data = numpy.sum([t[0] for t in current], axis=0)
585 avgdatatime = numpy.average([t[1] for t in current])
585 avgdatatime = numpy.average([t[1] for t in current])
586 # print data
586 # print data
587 self.__bufferStride.append((data, avgdatatime))
587 self.__bufferStride.append((data, avgdatatime))
588
588
589 if self.__dataToPutStride:
589 if self.__dataToPutStride:
590 self.__dataReady = True
590 self.__dataReady = True
591 self.__profIndexStride += 1
591 self.__profIndexStride += 1
592 if self.__profIndexStride == self.stride:
592 if self.__profIndexStride == self.stride:
593 self.__dataToPutStride = False
593 self.__dataToPutStride = False
594 # print self.__bufferStride[self.__profIndexStride - 1]
594 # print self.__bufferStride[self.__profIndexStride - 1]
595 # raise
595 # raise
596 return self.__bufferStride[self.__profIndexStride - 1]
596 return self.__bufferStride[self.__profIndexStride - 1]
597
597
598
598
599 return None, None
599 return None, None
600
600
601 def integrate(self, data, datatime=None):
601 def integrate(self, data, datatime=None):
602
602
603 if self.__initime == None:
603 if self.__initime == None:
604 self.__initime = datatime
604 self.__initime = datatime
605
605
606 if self.__byTime:
606 if self.__byTime:
607 avgdata = self.byTime(data, datatime)
607 avgdata = self.byTime(data, datatime)
608 else:
608 else:
609 avgdata = self.byProfiles(data)
609 avgdata = self.byProfiles(data)
610
610
611
611
612 self.__lastdatatime = datatime
612 self.__lastdatatime = datatime
613
613
614 if avgdata is None:
614 if avgdata is None:
615 return None, None
615 return None, None
616
616
617 avgdatatime = self.__initime
617 avgdatatime = self.__initime
618
618
619 deltatime = datatime - self.__lastdatatime
619 deltatime = datatime - self.__lastdatatime
620
620
621 if not self.__withOverlapping:
621 if not self.__withOverlapping:
622 self.__initime = datatime
622 self.__initime = datatime
623 else:
623 else:
624 self.__initime += deltatime
624 self.__initime += deltatime
625
625
626 return avgdata, avgdatatime
626 return avgdata, avgdatatime
627
627
628 def integrateByBlock(self, dataOut):
628 def integrateByBlock(self, dataOut):
629
629
630 times = int(dataOut.data.shape[1]/self.n)
630 times = int(dataOut.data.shape[1]/self.n)
631 avgdata = numpy.zeros((dataOut.nChannels, times, dataOut.nHeights), dtype=numpy.complex)
631 avgdata = numpy.zeros((dataOut.nChannels, times, dataOut.nHeights), dtype=numpy.complex)
632
632
633 id_min = 0
633 id_min = 0
634 id_max = self.n
634 id_max = self.n
635
635
636 for i in range(times):
636 for i in range(times):
637 junk = dataOut.data[:,id_min:id_max,:]
637 junk = dataOut.data[:,id_min:id_max,:]
638 avgdata[:,i,:] = junk.sum(axis=1)
638 avgdata[:,i,:] = junk.sum(axis=1)
639 id_min += self.n
639 id_min += self.n
640 id_max += self.n
640 id_max += self.n
641
641
642 timeInterval = dataOut.ippSeconds*self.n
642 timeInterval = dataOut.ippSeconds*self.n
643 avgdatatime = (times - 1) * timeInterval + dataOut.utctime
643 avgdatatime = (times - 1) * timeInterval + dataOut.utctime
644 self.__dataReady = True
644 self.__dataReady = True
645 return avgdata, avgdatatime
645 return avgdata, avgdatatime
646
646
647 def run(self, dataOut, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False, **kwargs):
647 def run(self, dataOut, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False, **kwargs):
648
648
649 if not self.isConfig:
649 if not self.isConfig:
650 self.setup(n=n, stride=stride, timeInterval=timeInterval, overlapping=overlapping, byblock=byblock, **kwargs)
650 self.setup(n=n, stride=stride, timeInterval=timeInterval, overlapping=overlapping, byblock=byblock, **kwargs)
651 self.isConfig = True
651 self.isConfig = True
652
652
653 if dataOut.flagDataAsBlock:
653 if dataOut.flagDataAsBlock:
654 """
654 """
655 Si la data es leida por bloques, dimension = [nChannels, nProfiles, nHeis]
655 Si la data es leida por bloques, dimension = [nChannels, nProfiles, nHeis]
656 """
656 """
657 avgdata, avgdatatime = self.integrateByBlock(dataOut)
657 avgdata, avgdatatime = self.integrateByBlock(dataOut)
658 dataOut.nProfiles /= self.n
658 dataOut.nProfiles /= self.n
659 else:
659 else:
660 if stride is None:
660 if stride is None:
661 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
661 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
662 else:
662 else:
663 avgdata, avgdatatime = self.integrateByStride(dataOut.data, dataOut.utctime)
663 avgdata, avgdatatime = self.integrateByStride(dataOut.data, dataOut.utctime)
664
664
665
665
666 # dataOut.timeInterval *= n
666 # dataOut.timeInterval *= n
667 dataOut.flagNoData = True
667 dataOut.flagNoData = True
668
668
669 if self.__dataReady:
669 if self.__dataReady:
670 dataOut.data = avgdata
670 dataOut.data = avgdata
671 if not dataOut.flagCohInt:
671 if not dataOut.flagCohInt:
672 dataOut.nCohInt *= self.n
672 dataOut.nCohInt *= self.n
673 dataOut.flagCohInt = True
673 dataOut.flagCohInt = True
674 dataOut.utctime = avgdatatime
674 dataOut.utctime = avgdatatime
675 # print avgdata, avgdatatime
675 # print avgdata, avgdatatime
676 # raise
676 # raise
677 # dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
677 # dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
678 dataOut.flagNoData = False
678 dataOut.flagNoData = False
679 return dataOut
679 return dataOut
680
680
681 class Decoder(Operation):
681 class Decoder(Operation):
682
682
683 isConfig = False
683 isConfig = False
684 __profIndex = 0
684 __profIndex = 0
685
685
686 code = None
686 code = None
687
687
688 nCode = None
688 nCode = None
689 nBaud = None
689 nBaud = None
690
690
691 def __init__(self, **kwargs):
691 def __init__(self, **kwargs):
692
692
693 Operation.__init__(self, **kwargs)
693 Operation.__init__(self, **kwargs)
694
694
695 self.times = None
695 self.times = None
696 self.osamp = None
696 self.osamp = None
697 # self.__setValues = False
697 # self.__setValues = False
698 self.isConfig = False
698 self.isConfig = False
699 self.setupReq = False
699 self.setupReq = False
700 def setup(self, code, osamp, dataOut):
700 def setup(self, code, osamp, dataOut):
701
701
702 self.__profIndex = 0
702 self.__profIndex = 0
703
703
704 self.code = code
704 self.code = code
705
705
706 self.nCode = len(code)
706 self.nCode = len(code)
707 self.nBaud = len(code[0])
707 self.nBaud = len(code[0])
708
708
709 if (osamp != None) and (osamp >1):
709 if (osamp != None) and (osamp >1):
710 self.osamp = osamp
710 self.osamp = osamp
711 self.code = numpy.repeat(code, repeats=self.osamp, axis=1)
711 self.code = numpy.repeat(code, repeats=self.osamp, axis=1)
712 self.nBaud = self.nBaud*self.osamp
712 self.nBaud = self.nBaud*self.osamp
713
713
714 self.__nChannels = dataOut.nChannels
714 self.__nChannels = dataOut.nChannels
715 self.__nProfiles = dataOut.nProfiles
715 self.__nProfiles = dataOut.nProfiles
716 self.__nHeis = dataOut.nHeights
716 self.__nHeis = dataOut.nHeights
717
717
718 if self.__nHeis < self.nBaud:
718 if self.__nHeis < self.nBaud:
719 raise ValueError('Number of heights (%d) should be greater than number of bauds (%d)' %(self.__nHeis, self.nBaud))
719 raise ValueError('Number of heights (%d) should be greater than number of bauds (%d)' %(self.__nHeis, self.nBaud))
720
720
721 #Frequency
721 #Frequency
722 __codeBuffer = numpy.zeros((self.nCode, self.__nHeis), dtype=numpy.complex)
722 __codeBuffer = numpy.zeros((self.nCode, self.__nHeis), dtype=numpy.complex)
723
723
724 __codeBuffer[:,0:self.nBaud] = self.code
724 __codeBuffer[:,0:self.nBaud] = self.code
725
725
726 self.fft_code = numpy.conj(numpy.fft.fft(__codeBuffer, axis=1))
726 self.fft_code = numpy.conj(numpy.fft.fft(__codeBuffer, axis=1))
727
727
728 if dataOut.flagDataAsBlock:
728 if dataOut.flagDataAsBlock:
729
729
730 self.ndatadec = self.__nHeis #- self.nBaud + 1
730 self.ndatadec = self.__nHeis #- self.nBaud + 1
731
731
732 self.datadecTime = numpy.zeros((self.__nChannels, self.__nProfiles, self.ndatadec), dtype=numpy.complex)
732 self.datadecTime = numpy.zeros((self.__nChannels, self.__nProfiles, self.ndatadec), dtype=numpy.complex)
733
733
734 else:
734 else:
735
735
736 #Time
736 #Time
737 self.ndatadec = self.__nHeis #- self.nBaud + 1
737 self.ndatadec = self.__nHeis #- self.nBaud + 1
738
738
739 self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex)
739 self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex)
740
740
741 def __convolutionInFreq(self, data):
741 def __convolutionInFreq(self, data):
742
742
743 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
743 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
744
744
745 fft_data = numpy.fft.fft(data, axis=1)
745 fft_data = numpy.fft.fft(data, axis=1)
746
746
747 conv = fft_data*fft_code
747 conv = fft_data*fft_code
748
748
749 data = numpy.fft.ifft(conv,axis=1)
749 data = numpy.fft.ifft(conv,axis=1)
750
750
751 return data
751 return data
752
752
753 def __convolutionInFreqOpt(self, data):
753 def __convolutionInFreqOpt(self, data):
754
754
755 raise NotImplementedError
755 raise NotImplementedError
756
756
757 def __convolutionInTime(self, data):
757 def __convolutionInTime(self, data):
758
758
759 code = self.code[self.__profIndex]
759 code = self.code[self.__profIndex]
760 for i in range(self.__nChannels):
760 for i in range(self.__nChannels):
761 self.datadecTime[i,:] = numpy.correlate(data[i,:], code, mode='full')[self.nBaud-1:]
761 self.datadecTime[i,:] = numpy.correlate(data[i,:], code, mode='full')[self.nBaud-1:]
762
762
763 return self.datadecTime
763 return self.datadecTime
764
764
765 def __convolutionByBlockInTime(self, data):
765 def __convolutionByBlockInTime(self, data):
766
766
767 repetitions = int(self.__nProfiles / self.nCode)
767 repetitions = int(self.__nProfiles / self.nCode)
768 junk = numpy.lib.stride_tricks.as_strided(self.code, (repetitions, self.code.size), (0, self.code.itemsize))
768 junk = numpy.lib.stride_tricks.as_strided(self.code, (repetitions, self.code.size), (0, self.code.itemsize))
769 junk = junk.flatten()
769 junk = junk.flatten()
770 code_block = numpy.reshape(junk, (self.nCode*repetitions, self.nBaud))
770 code_block = numpy.reshape(junk, (self.nCode*repetitions, self.nBaud))
771 profilesList = range(self.__nProfiles)
771 profilesList = range(self.__nProfiles)
772
772
773 for i in range(self.__nChannels):
773 for i in range(self.__nChannels):
774 for j in profilesList:
774 for j in profilesList:
775 self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:]
775 self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:]
776 return self.datadecTime
776 return self.datadecTime
777
777
778 def __convolutionByBlockInFreq(self, data):
778 def __convolutionByBlockInFreq(self, data):
779
779
780 raise NotImplementedError("Decoder by frequency fro Blocks not implemented")
780 raise NotImplementedError("Decoder by frequency fro Blocks not implemented")
781
781
782
782
783 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
783 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
784
784
785 fft_data = numpy.fft.fft(data, axis=2)
785 fft_data = numpy.fft.fft(data, axis=2)
786
786
787 conv = fft_data*fft_code
787 conv = fft_data*fft_code
788
788
789 data = numpy.fft.ifft(conv,axis=2)
789 data = numpy.fft.ifft(conv,axis=2)
790
790
791 return data
791 return data
792
792
793
793
794 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0, osamp=None, times=None):
794 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0, osamp=None, times=None):
795
795
796 if dataOut.flagDecodeData:
796 if dataOut.flagDecodeData:
797 print("This data is already decoded, recoding again ...")
797 print("This data is already decoded, recoding again ...")
798
798
799 if not self.isConfig:
799 if not self.isConfig:
800
800
801 if code is None:
801 if code is None:
802 if dataOut.code is None:
802 if dataOut.code is None:
803 raise ValueError("Code could not be read from %s instance. Enter a value in Code parameter" %dataOut.type)
803 raise ValueError("Code could not be read from %s instance. Enter a value in Code parameter" %dataOut.type)
804
804
805 code = dataOut.code
805 code = dataOut.code
806 else:
806 else:
807 code = numpy.array(code).reshape(nCode,nBaud)
807 code = numpy.array(code).reshape(nCode,nBaud)
808 self.setup(code, osamp, dataOut)
808 self.setup(code, osamp, dataOut)
809
809
810 self.isConfig = True
810 self.isConfig = True
811
811
812 if mode == 3:
812 if mode == 3:
813 sys.stderr.write("Decoder Warning: mode=%d is not valid, using mode=0\n" %mode)
813 sys.stderr.write("Decoder Warning: mode=%d is not valid, using mode=0\n" %mode)
814
814
815 if times != None:
815 if times != None:
816 sys.stderr.write("Decoder Warning: Argument 'times' in not used anymore\n")
816 sys.stderr.write("Decoder Warning: Argument 'times' in not used anymore\n")
817
817
818 if self.code is None:
818 if self.code is None:
819 print("Fail decoding: Code is not defined.")
819 print("Fail decoding: Code is not defined.")
820 return
820 return
821
821
822 self.__nProfiles = dataOut.nProfiles
822 self.__nProfiles = dataOut.nProfiles
823 datadec = None
823 datadec = None
824
824
825 if mode == 3:
825 if mode == 3:
826 mode = 0
826 mode = 0
827
827
828 if dataOut.flagDataAsBlock:
828 if dataOut.flagDataAsBlock:
829 """
829 """
830 Decoding when data have been read as block,
830 Decoding when data have been read as block,
831 """
831 """
832
832
833 if mode == 0:
833 if mode == 0:
834 datadec = self.__convolutionByBlockInTime(dataOut.data)
834 datadec = self.__convolutionByBlockInTime(dataOut.data)
835 if mode == 1:
835 if mode == 1:
836 datadec = self.__convolutionByBlockInFreq(dataOut.data)
836 datadec = self.__convolutionByBlockInFreq(dataOut.data)
837 else:
837 else:
838 """
838 """
839 Decoding when data have been read profile by profile
839 Decoding when data have been read profile by profile
840 """
840 """
841 if mode == 0:
841 if mode == 0:
842 datadec = self.__convolutionInTime(dataOut.data)
842 datadec = self.__convolutionInTime(dataOut.data)
843
843
844 if mode == 1:
844 if mode == 1:
845 datadec = self.__convolutionInFreq(dataOut.data)
845 datadec = self.__convolutionInFreq(dataOut.data)
846
846
847 if mode == 2:
847 if mode == 2:
848 datadec = self.__convolutionInFreqOpt(dataOut.data)
848 datadec = self.__convolutionInFreqOpt(dataOut.data)
849
849
850 if datadec is None:
850 if datadec is None:
851 raise ValueError("Codification mode selected is not valid: mode=%d. Try selecting 0 or 1" %mode)
851 raise ValueError("Codification mode selected is not valid: mode=%d. Try selecting 0 or 1" %mode)
852
852
853 dataOut.code = self.code
853 dataOut.code = self.code
854 dataOut.nCode = self.nCode
854 dataOut.nCode = self.nCode
855 dataOut.nBaud = self.nBaud
855 dataOut.nBaud = self.nBaud
856
856
857 dataOut.data = datadec
857 dataOut.data = datadec
858
858
859 dataOut.heightList = dataOut.heightList[0:datadec.shape[-1]]
859 dataOut.heightList = dataOut.heightList[0:datadec.shape[-1]]
860
860
861 dataOut.flagDecodeData = True #asumo q la data esta decodificada
861 dataOut.flagDecodeData = True #asumo q la data esta decodificada
862
862
863 if self.__profIndex == self.nCode-1:
863 if self.__profIndex == self.nCode-1:
864 self.__profIndex = 0
864 self.__profIndex = 0
865 return dataOut
865 return dataOut
866
866
867 self.__profIndex += 1
867 self.__profIndex += 1
868
868
869 return dataOut
869 return dataOut
870 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
870 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
871
871
872
872
873 class ProfileConcat(Operation):
873 class ProfileConcat(Operation):
874
874
875 isConfig = False
875 isConfig = False
876 buffer = None
876 buffer = None
877
877
878 def __init__(self, **kwargs):
878 def __init__(self, **kwargs):
879
879
880 Operation.__init__(self, **kwargs)
880 Operation.__init__(self, **kwargs)
881 self.profileIndex = 0
881 self.profileIndex = 0
882
882
883 def reset(self):
883 def reset(self):
884 self.buffer = numpy.zeros_like(self.buffer)
884 self.buffer = numpy.zeros_like(self.buffer)
885 self.start_index = 0
885 self.start_index = 0
886 self.times = 1
886 self.times = 1
887
887
888 def setup(self, data, m, n=1):
888 def setup(self, data, m, n=1):
889 self.buffer = numpy.zeros((data.shape[0],data.shape[1]*m),dtype=type(data[0,0]))
889 self.buffer = numpy.zeros((data.shape[0],data.shape[1]*m),dtype=type(data[0,0]))
890 self.nHeights = data.shape[1]#.nHeights
890 self.nHeights = data.shape[1]#.nHeights
891 self.start_index = 0
891 self.start_index = 0
892 self.times = 1
892 self.times = 1
893
893
894 def concat(self, data):
894 def concat(self, data):
895
895
896 self.buffer[:,self.start_index:self.nHeights*self.times] = data.copy()
896 self.buffer[:,self.start_index:self.nHeights*self.times] = data.copy()
897 self.start_index = self.start_index + self.nHeights
897 self.start_index = self.start_index + self.nHeights
898
898
899 def run(self, dataOut, m):
899 def run(self, dataOut, m):
900 dataOut.flagNoData = True
900 dataOut.flagNoData = True
901
901
902 if not self.isConfig:
902 if not self.isConfig:
903 self.setup(dataOut.data, m, 1)
903 self.setup(dataOut.data, m, 1)
904 self.isConfig = True
904 self.isConfig = True
905
905
906 if dataOut.flagDataAsBlock:
906 if dataOut.flagDataAsBlock:
907 raise ValueError("ProfileConcat can only be used when voltage have been read profile by profile, getBlock = False")
907 raise ValueError("ProfileConcat can only be used when voltage have been read profile by profile, getBlock = False")
908
908
909 else:
909 else:
910 self.concat(dataOut.data)
910 self.concat(dataOut.data)
911 self.times += 1
911 self.times += 1
912 if self.times > m:
912 if self.times > m:
913 dataOut.data = self.buffer
913 dataOut.data = self.buffer
914 self.reset()
914 self.reset()
915 dataOut.flagNoData = False
915 dataOut.flagNoData = False
916 # se deben actualizar mas propiedades del header y del objeto dataOut, por ejemplo, las alturas
916 # se deben actualizar mas propiedades del header y del objeto dataOut, por ejemplo, las alturas
917 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
917 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
918 xf = dataOut.heightList[0] + dataOut.nHeights * deltaHeight * m
918 xf = dataOut.heightList[0] + dataOut.nHeights * deltaHeight * m
919 dataOut.heightList = numpy.arange(dataOut.heightList[0], xf, deltaHeight)
919 dataOut.heightList = numpy.arange(dataOut.heightList[0], xf, deltaHeight)
920 dataOut.ippSeconds *= m
920 dataOut.ippSeconds *= m
921 return dataOut
921 return dataOut
922
922
923 class ProfileSelector(Operation):
923 class ProfileSelector(Operation):
924
924
925 profileIndex = None
925 profileIndex = None
926 # Tamanho total de los perfiles
926 # Tamanho total de los perfiles
927 nProfiles = None
927 nProfiles = None
928
928
929 def __init__(self, **kwargs):
929 def __init__(self, **kwargs):
930
930
931 Operation.__init__(self, **kwargs)
931 Operation.__init__(self, **kwargs)
932 self.profileIndex = 0
932 self.profileIndex = 0
933
933
934 def incProfileIndex(self):
934 def incProfileIndex(self):
935
935
936 self.profileIndex += 1
936 self.profileIndex += 1
937
937
938 if self.profileIndex >= self.nProfiles:
938 if self.profileIndex >= self.nProfiles:
939 self.profileIndex = 0
939 self.profileIndex = 0
940
940
941 def isThisProfileInRange(self, profileIndex, minIndex, maxIndex):
941 def isThisProfileInRange(self, profileIndex, minIndex, maxIndex):
942
942
943 if profileIndex < minIndex:
943 if profileIndex < minIndex:
944 return False
944 return False
945
945
946 if profileIndex > maxIndex:
946 if profileIndex > maxIndex:
947 return False
947 return False
948
948
949 return True
949 return True
950
950
951 def isThisProfileInList(self, profileIndex, profileList):
951 def isThisProfileInList(self, profileIndex, profileList):
952
952
953 if profileIndex not in profileList:
953 if profileIndex not in profileList:
954 return False
954 return False
955
955
956 return True
956 return True
957
957
958 def run(self, dataOut, profileList=None, profileRangeList=None, beam=None, byblock=False, rangeList = None, nProfiles=None):
958 def run(self, dataOut, profileList=None, profileRangeList=None, beam=None, byblock=False, rangeList = None, nProfiles=None):
959
959
960 """
960 """
961 ProfileSelector:
961 ProfileSelector:
962
962
963 Inputs:
963 Inputs:
964 profileList : Index of profiles selected. Example: profileList = (0,1,2,7,8)
964 profileList : Index of profiles selected. Example: profileList = (0,1,2,7,8)
965
965
966 profileRangeList : Minimum and maximum profile indexes. Example: profileRangeList = (4, 30)
966 profileRangeList : Minimum and maximum profile indexes. Example: profileRangeList = (4, 30)
967
967
968 rangeList : List of profile ranges. Example: rangeList = ((4, 30), (32, 64), (128, 256))
968 rangeList : List of profile ranges. Example: rangeList = ((4, 30), (32, 64), (128, 256))
969
969
970 """
970 """
971
971
972 if rangeList is not None:
972 if rangeList is not None:
973 if type(rangeList[0]) not in (tuple, list):
973 if type(rangeList[0]) not in (tuple, list):
974 rangeList = [rangeList]
974 rangeList = [rangeList]
975
975
976 dataOut.flagNoData = True
976 dataOut.flagNoData = True
977
977
978 if dataOut.flagDataAsBlock:
978 if dataOut.flagDataAsBlock:
979 """
979 """
980 data dimension = [nChannels, nProfiles, nHeis]
980 data dimension = [nChannels, nProfiles, nHeis]
981 """
981 """
982 if profileList != None:
982 if profileList != None:
983 dataOut.data = dataOut.data[:,profileList,:]
983 dataOut.data = dataOut.data[:,profileList,:]
984
984
985 if profileRangeList != None:
985 if profileRangeList != None:
986 minIndex = profileRangeList[0]
986 minIndex = profileRangeList[0]
987 maxIndex = profileRangeList[1]
987 maxIndex = profileRangeList[1]
988 profileList = list(range(minIndex, maxIndex+1))
988 profileList = list(range(minIndex, maxIndex+1))
989
989
990 dataOut.data = dataOut.data[:,minIndex:maxIndex+1,:]
990 dataOut.data = dataOut.data[:,minIndex:maxIndex+1,:]
991
991
992 if rangeList != None:
992 if rangeList != None:
993
993
994 profileList = []
994 profileList = []
995
995
996 for thisRange in rangeList:
996 for thisRange in rangeList:
997 minIndex = thisRange[0]
997 minIndex = thisRange[0]
998 maxIndex = thisRange[1]
998 maxIndex = thisRange[1]
999
999
1000 profileList.extend(list(range(minIndex, maxIndex+1)))
1000 profileList.extend(list(range(minIndex, maxIndex+1)))
1001
1001
1002 dataOut.data = dataOut.data[:,profileList,:]
1002 dataOut.data = dataOut.data[:,profileList,:]
1003
1003
1004 dataOut.nProfiles = len(profileList)
1004 dataOut.nProfiles = len(profileList)
1005 dataOut.profileIndex = dataOut.nProfiles - 1
1005 dataOut.profileIndex = dataOut.nProfiles - 1
1006 dataOut.flagNoData = False
1006 dataOut.flagNoData = False
1007
1007
1008 return dataOut
1008 return dataOut
1009
1009
1010 """
1010 """
1011 data dimension = [nChannels, nHeis]
1011 data dimension = [nChannels, nHeis]
1012 """
1012 """
1013
1013
1014 if profileList != None:
1014 if profileList != None:
1015
1015
1016 if self.isThisProfileInList(dataOut.profileIndex, profileList):
1016 if self.isThisProfileInList(dataOut.profileIndex, profileList):
1017
1017
1018 self.nProfiles = len(profileList)
1018 self.nProfiles = len(profileList)
1019 dataOut.nProfiles = self.nProfiles
1019 dataOut.nProfiles = self.nProfiles
1020 dataOut.profileIndex = self.profileIndex
1020 dataOut.profileIndex = self.profileIndex
1021 dataOut.flagNoData = False
1021 dataOut.flagNoData = False
1022
1022
1023 self.incProfileIndex()
1023 self.incProfileIndex()
1024 return dataOut
1024 return dataOut
1025
1025
1026 if profileRangeList != None:
1026 if profileRangeList != None:
1027
1027
1028 minIndex = profileRangeList[0]
1028 minIndex = profileRangeList[0]
1029 maxIndex = profileRangeList[1]
1029 maxIndex = profileRangeList[1]
1030
1030
1031 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1031 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1032
1032
1033 self.nProfiles = maxIndex - minIndex + 1
1033 self.nProfiles = maxIndex - minIndex + 1
1034 dataOut.nProfiles = self.nProfiles
1034 dataOut.nProfiles = self.nProfiles
1035 dataOut.profileIndex = self.profileIndex
1035 dataOut.profileIndex = self.profileIndex
1036 dataOut.flagNoData = False
1036 dataOut.flagNoData = False
1037
1037
1038 self.incProfileIndex()
1038 self.incProfileIndex()
1039 return dataOut
1039 return dataOut
1040
1040
1041 if rangeList != None:
1041 if rangeList != None:
1042
1042
1043 nProfiles = 0
1043 nProfiles = 0
1044
1044
1045 for thisRange in rangeList:
1045 for thisRange in rangeList:
1046 minIndex = thisRange[0]
1046 minIndex = thisRange[0]
1047 maxIndex = thisRange[1]
1047 maxIndex = thisRange[1]
1048
1048
1049 nProfiles += maxIndex - minIndex + 1
1049 nProfiles += maxIndex - minIndex + 1
1050
1050
1051 for thisRange in rangeList:
1051 for thisRange in rangeList:
1052
1052
1053 minIndex = thisRange[0]
1053 minIndex = thisRange[0]
1054 maxIndex = thisRange[1]
1054 maxIndex = thisRange[1]
1055
1055
1056 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1056 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1057
1057
1058 self.nProfiles = nProfiles
1058 self.nProfiles = nProfiles
1059 dataOut.nProfiles = self.nProfiles
1059 dataOut.nProfiles = self.nProfiles
1060 dataOut.profileIndex = self.profileIndex
1060 dataOut.profileIndex = self.profileIndex
1061 dataOut.flagNoData = False
1061 dataOut.flagNoData = False
1062
1062
1063 self.incProfileIndex()
1063 self.incProfileIndex()
1064
1064
1065 break
1065 break
1066
1066
1067 return dataOut
1067 return dataOut
1068
1068
1069
1069
1070 if beam != None: #beam is only for AMISR data
1070 if beam != None: #beam is only for AMISR data
1071 if self.isThisProfileInList(dataOut.profileIndex, dataOut.beamRangeDict[beam]):
1071 if self.isThisProfileInList(dataOut.profileIndex, dataOut.beamRangeDict[beam]):
1072 dataOut.flagNoData = False
1072 dataOut.flagNoData = False
1073 dataOut.profileIndex = self.profileIndex
1073 dataOut.profileIndex = self.profileIndex
1074
1074
1075 self.incProfileIndex()
1075 self.incProfileIndex()
1076
1076
1077 return dataOut
1077 return dataOut
1078
1078
1079 raise ValueError("ProfileSelector needs profileList, profileRangeList or rangeList parameter")
1079 raise ValueError("ProfileSelector needs profileList, profileRangeList or rangeList parameter")
1080
1080
1081
1081
1082 class Reshaper(Operation):
1082 class Reshaper(Operation):
1083
1083
1084 def __init__(self, **kwargs):
1084 def __init__(self, **kwargs):
1085
1085
1086 Operation.__init__(self, **kwargs)
1086 Operation.__init__(self, **kwargs)
1087
1087
1088 self.__buffer = None
1088 self.__buffer = None
1089 self.__nitems = 0
1089 self.__nitems = 0
1090
1090
1091 def __appendProfile(self, dataOut, nTxs):
1091 def __appendProfile(self, dataOut, nTxs):
1092
1092
1093 if self.__buffer is None:
1093 if self.__buffer is None:
1094 shape = (dataOut.nChannels, int(dataOut.nHeights/nTxs) )
1094 shape = (dataOut.nChannels, int(dataOut.nHeights/nTxs) )
1095 self.__buffer = numpy.empty(shape, dtype = dataOut.data.dtype)
1095 self.__buffer = numpy.empty(shape, dtype = dataOut.data.dtype)
1096
1096
1097 ini = dataOut.nHeights * self.__nitems
1097 ini = dataOut.nHeights * self.__nitems
1098 end = ini + dataOut.nHeights
1098 end = ini + dataOut.nHeights
1099
1099
1100 self.__buffer[:, ini:end] = dataOut.data
1100 self.__buffer[:, ini:end] = dataOut.data
1101
1101
1102 self.__nitems += 1
1102 self.__nitems += 1
1103
1103
1104 return int(self.__nitems*nTxs)
1104 return int(self.__nitems*nTxs)
1105
1105
1106 def __getBuffer(self):
1106 def __getBuffer(self):
1107
1107
1108 if self.__nitems == int(1./self.__nTxs):
1108 if self.__nitems == int(1./self.__nTxs):
1109
1109
1110 self.__nitems = 0
1110 self.__nitems = 0
1111
1111
1112 return self.__buffer.copy()
1112 return self.__buffer.copy()
1113
1113
1114 return None
1114 return None
1115
1115
1116 def __checkInputs(self, dataOut, shape, nTxs):
1116 def __checkInputs(self, dataOut, shape, nTxs):
1117
1117
1118 if shape is None and nTxs is None:
1118 if shape is None and nTxs is None:
1119 raise ValueError("Reshaper: shape of factor should be defined")
1119 raise ValueError("Reshaper: shape of factor should be defined")
1120
1120
1121 if nTxs:
1121 if nTxs:
1122 if nTxs < 0:
1122 if nTxs < 0:
1123 raise ValueError("nTxs should be greater than 0")
1123 raise ValueError("nTxs should be greater than 0")
1124
1124
1125 if nTxs < 1 and dataOut.nProfiles % (1./nTxs) != 0:
1125 if nTxs < 1 and dataOut.nProfiles % (1./nTxs) != 0:
1126 raise ValueError("nProfiles= %d is not divisibled by (1./nTxs) = %f" %(dataOut.nProfiles, (1./nTxs)))
1126 raise ValueError("nProfiles= %d is not divisibled by (1./nTxs) = %f" %(dataOut.nProfiles, (1./nTxs)))
1127
1127
1128 shape = [dataOut.nChannels, dataOut.nProfiles*nTxs, dataOut.nHeights/nTxs]
1128 shape = [dataOut.nChannels, dataOut.nProfiles*nTxs, dataOut.nHeights/nTxs]
1129
1129
1130 return shape, nTxs
1130 return shape, nTxs
1131
1131
1132 if len(shape) != 2 and len(shape) != 3:
1132 if len(shape) != 2 and len(shape) != 3:
1133 raise ValueError("shape dimension should be equal to 2 or 3. shape = (nProfiles, nHeis) or (nChannels, nProfiles, nHeis). Actually shape = (%d, %d, %d)" %(dataOut.nChannels, dataOut.nProfiles, dataOut.nHeights))
1133 raise ValueError("shape dimension should be equal to 2 or 3. shape = (nProfiles, nHeis) or (nChannels, nProfiles, nHeis). Actually shape = (%d, %d, %d)" %(dataOut.nChannels, dataOut.nProfiles, dataOut.nHeights))
1134
1134
1135 if len(shape) == 2:
1135 if len(shape) == 2:
1136 shape_tuple = [dataOut.nChannels]
1136 shape_tuple = [dataOut.nChannels]
1137 shape_tuple.extend(shape)
1137 shape_tuple.extend(shape)
1138 else:
1138 else:
1139 shape_tuple = list(shape)
1139 shape_tuple = list(shape)
1140
1140
1141 nTxs = 1.0*shape_tuple[1]/dataOut.nProfiles
1141 nTxs = 1.0*shape_tuple[1]/dataOut.nProfiles
1142
1142
1143 return shape_tuple, nTxs
1143 return shape_tuple, nTxs
1144
1144
1145 def run(self, dataOut, shape=None, nTxs=None):
1145 def run(self, dataOut, shape=None, nTxs=None):
1146
1146
1147 shape_tuple, self.__nTxs = self.__checkInputs(dataOut, shape, nTxs)
1147 shape_tuple, self.__nTxs = self.__checkInputs(dataOut, shape, nTxs)
1148
1148
1149 dataOut.flagNoData = True
1149 dataOut.flagNoData = True
1150 profileIndex = None
1150 profileIndex = None
1151
1151
1152 if dataOut.flagDataAsBlock:
1152 if dataOut.flagDataAsBlock:
1153
1153
1154 dataOut.data = numpy.reshape(dataOut.data, shape_tuple)
1154 dataOut.data = numpy.reshape(dataOut.data, shape_tuple)
1155 dataOut.flagNoData = False
1155 dataOut.flagNoData = False
1156
1156
1157 profileIndex = int(dataOut.nProfiles*self.__nTxs) - 1
1157 profileIndex = int(dataOut.nProfiles*self.__nTxs) - 1
1158
1158
1159 else:
1159 else:
1160
1160
1161 if self.__nTxs < 1:
1161 if self.__nTxs < 1:
1162
1162
1163 self.__appendProfile(dataOut, self.__nTxs)
1163 self.__appendProfile(dataOut, self.__nTxs)
1164 new_data = self.__getBuffer()
1164 new_data = self.__getBuffer()
1165
1165
1166 if new_data is not None:
1166 if new_data is not None:
1167 dataOut.data = new_data
1167 dataOut.data = new_data
1168 dataOut.flagNoData = False
1168 dataOut.flagNoData = False
1169
1169
1170 profileIndex = dataOut.profileIndex*nTxs
1170 profileIndex = dataOut.profileIndex*nTxs
1171
1171
1172 else:
1172 else:
1173 raise ValueError("nTxs should be greater than 0 and lower than 1, or use VoltageReader(..., getblock=True)")
1173 raise ValueError("nTxs should be greater than 0 and lower than 1, or use VoltageReader(..., getblock=True)")
1174
1174
1175 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1175 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1176
1176
1177 dataOut.heightList = numpy.arange(dataOut.nHeights/self.__nTxs) * deltaHeight + dataOut.heightList[0]
1177 dataOut.heightList = numpy.arange(dataOut.nHeights/self.__nTxs) * deltaHeight + dataOut.heightList[0]
1178
1178
1179 dataOut.nProfiles = int(dataOut.nProfiles*self.__nTxs)
1179 dataOut.nProfiles = int(dataOut.nProfiles*self.__nTxs)
1180
1180
1181 dataOut.profileIndex = profileIndex
1181 dataOut.profileIndex = profileIndex
1182
1182
1183 dataOut.ippSeconds /= self.__nTxs
1183 dataOut.ippSeconds /= self.__nTxs
1184
1184
1185 return dataOut
1185 return dataOut
1186
1186
1187 class SplitProfiles(Operation):
1187 class SplitProfiles(Operation):
1188
1188
1189 def __init__(self, **kwargs):
1189 def __init__(self, **kwargs):
1190
1190
1191 Operation.__init__(self, **kwargs)
1191 Operation.__init__(self, **kwargs)
1192
1192
1193 def run(self, dataOut, n):
1193 def run(self, dataOut, n):
1194
1194
1195 dataOut.flagNoData = True
1195 dataOut.flagNoData = True
1196 profileIndex = None
1196 profileIndex = None
1197
1197
1198 if dataOut.flagDataAsBlock:
1198 if dataOut.flagDataAsBlock:
1199
1199
1200 #nchannels, nprofiles, nsamples
1200 #nchannels, nprofiles, nsamples
1201 shape = dataOut.data.shape
1201 shape = dataOut.data.shape
1202
1202
1203 if shape[2] % n != 0:
1203 if shape[2] % n != 0:
1204 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[2]))
1204 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[2]))
1205
1205
1206 new_shape = shape[0], shape[1]*n, int(shape[2]/n)
1206 new_shape = shape[0], shape[1]*n, int(shape[2]/n)
1207
1207
1208 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1208 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1209 dataOut.flagNoData = False
1209 dataOut.flagNoData = False
1210
1210
1211 profileIndex = int(dataOut.nProfiles/n) - 1
1211 profileIndex = int(dataOut.nProfiles/n) - 1
1212
1212
1213 else:
1213 else:
1214
1214
1215 raise ValueError("Could not split the data when is read Profile by Profile. Use VoltageReader(..., getblock=True)")
1215 raise ValueError("Could not split the data when is read Profile by Profile. Use VoltageReader(..., getblock=True)")
1216
1216
1217 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1217 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1218
1218
1219 dataOut.heightList = numpy.arange(dataOut.nHeights/n) * deltaHeight + dataOut.heightList[0]
1219 dataOut.heightList = numpy.arange(dataOut.nHeights/n) * deltaHeight + dataOut.heightList[0]
1220
1220
1221 dataOut.nProfiles = int(dataOut.nProfiles*n)
1221 dataOut.nProfiles = int(dataOut.nProfiles*n)
1222
1222
1223 dataOut.profileIndex = profileIndex
1223 dataOut.profileIndex = profileIndex
1224
1224
1225 dataOut.ippSeconds /= n
1225 dataOut.ippSeconds /= n
1226
1226
1227 return dataOut
1227 return dataOut
1228
1228
1229 class CombineProfiles(Operation):
1229 class CombineProfiles(Operation):
1230 def __init__(self, **kwargs):
1230 def __init__(self, **kwargs):
1231
1231
1232 Operation.__init__(self, **kwargs)
1232 Operation.__init__(self, **kwargs)
1233
1233
1234 self.__remData = None
1234 self.__remData = None
1235 self.__profileIndex = 0
1235 self.__profileIndex = 0
1236
1236
1237 def run(self, dataOut, n):
1237 def run(self, dataOut, n):
1238
1238
1239 dataOut.flagNoData = True
1239 dataOut.flagNoData = True
1240 profileIndex = None
1240 profileIndex = None
1241
1241
1242 if dataOut.flagDataAsBlock:
1242 if dataOut.flagDataAsBlock:
1243
1243
1244 #nchannels, nprofiles, nsamples
1244 #nchannels, nprofiles, nsamples
1245 shape = dataOut.data.shape
1245 shape = dataOut.data.shape
1246 new_shape = shape[0], shape[1]/n, shape[2]*n
1246 new_shape = shape[0], shape[1]/n, shape[2]*n
1247
1247
1248 if shape[1] % n != 0:
1248 if shape[1] % n != 0:
1249 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[1]))
1249 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[1]))
1250
1250
1251 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1251 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1252 dataOut.flagNoData = False
1252 dataOut.flagNoData = False
1253
1253
1254 profileIndex = int(dataOut.nProfiles*n) - 1
1254 profileIndex = int(dataOut.nProfiles*n) - 1
1255
1255
1256 else:
1256 else:
1257
1257
1258 #nchannels, nsamples
1258 #nchannels, nsamples
1259 if self.__remData is None:
1259 if self.__remData is None:
1260 newData = dataOut.data
1260 newData = dataOut.data
1261 else:
1261 else:
1262 newData = numpy.concatenate((self.__remData, dataOut.data), axis=1)
1262 newData = numpy.concatenate((self.__remData, dataOut.data), axis=1)
1263
1263
1264 self.__profileIndex += 1
1264 self.__profileIndex += 1
1265
1265
1266 if self.__profileIndex < n:
1266 if self.__profileIndex < n:
1267 self.__remData = newData
1267 self.__remData = newData
1268 #continue
1268 #continue
1269 return
1269 return
1270
1270
1271 self.__profileIndex = 0
1271 self.__profileIndex = 0
1272 self.__remData = None
1272 self.__remData = None
1273
1273
1274 dataOut.data = newData
1274 dataOut.data = newData
1275 dataOut.flagNoData = False
1275 dataOut.flagNoData = False
1276
1276
1277 profileIndex = dataOut.profileIndex/n
1277 profileIndex = dataOut.profileIndex/n
1278
1278
1279
1279
1280 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1280 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1281
1281
1282 dataOut.heightList = numpy.arange(dataOut.nHeights*n) * deltaHeight + dataOut.heightList[0]
1282 dataOut.heightList = numpy.arange(dataOut.nHeights*n) * deltaHeight + dataOut.heightList[0]
1283
1283
1284 dataOut.nProfiles = int(dataOut.nProfiles/n)
1284 dataOut.nProfiles = int(dataOut.nProfiles/n)
1285
1285
1286 dataOut.profileIndex = profileIndex
1286 dataOut.profileIndex = profileIndex
1287
1287
1288 dataOut.ippSeconds *= n
1288 dataOut.ippSeconds *= n
1289
1289
1290 return dataOut
1290 return dataOut
1291
1291
1292 class PulsePairVoltage(Operation):
1292 class PulsePairVoltage(Operation):
1293 '''
1293 '''
1294 Function PulsePair(Signal Power, Velocity)
1294 Function PulsePair(Signal Power, Velocity)
1295 The real component of Lag[0] provides Intensity Information
1295 The real component of Lag[0] provides Intensity Information
1296 The imag component of Lag[1] Phase provides Velocity Information
1296 The imag component of Lag[1] Phase provides Velocity Information
1297
1297
1298 Configuration Parameters:
1298 Configuration Parameters:
1299 nPRF = Number of Several PRF
1299 nPRF = Number of Several PRF
1300 theta = Degree Azimuth angel Boundaries
1300 theta = Degree Azimuth angel Boundaries
1301
1301
1302 Input:
1302 Input:
1303 self.dataOut
1303 self.dataOut
1304 lag[N]
1304 lag[N]
1305 Affected:
1305 Affected:
1306 self.dataOut.spc
1306 self.dataOut.spc
1307 '''
1307 '''
1308 isConfig = False
1308 isConfig = False
1309 __profIndex = 0
1309 __profIndex = 0
1310 __initime = None
1310 __initime = None
1311 __lastdatatime = None
1311 __lastdatatime = None
1312 __buffer = None
1312 __buffer = None
1313 noise = None
1313 noise = None
1314 __dataReady = False
1314 __dataReady = False
1315 n = None
1315 n = None
1316 __nch = 0
1316 __nch = 0
1317 __nHeis = 0
1317 __nHeis = 0
1318 removeDC = False
1318 removeDC = False
1319 ipp = None
1319 ipp = None
1320 lambda_ = 0
1320 lambda_ = 0
1321
1321
1322 def __init__(self,**kwargs):
1322 def __init__(self,**kwargs):
1323 Operation.__init__(self,**kwargs)
1323 Operation.__init__(self,**kwargs)
1324
1324
1325 def setup(self, dataOut, n = None, removeDC=False):
1325 def setup(self, dataOut, n = None, removeDC=False):
1326 '''
1326 '''
1327 n= Numero de PRF's de entrada
1327 n= Numero de PRF's de entrada
1328 '''
1328 '''
1329 self.__initime = None
1329 self.__initime = None
1330 self.__lastdatatime = 0
1330 self.__lastdatatime = 0
1331 self.__dataReady = False
1331 self.__dataReady = False
1332 self.__buffer = 0
1332 self.__buffer = 0
1333 self.__profIndex = 0
1333 self.__profIndex = 0
1334 self.noise = None
1334 self.noise = None
1335 self.__nch = dataOut.nChannels
1335 self.__nch = dataOut.nChannels
1336 self.__nHeis = dataOut.nHeights
1336 self.__nHeis = dataOut.nHeights
1337 self.removeDC = removeDC
1337 self.removeDC = removeDC
1338 self.lambda_ = 3.0e8/(9345.0e6)
1338 self.lambda_ = 3.0e8/(9345.0e6)
1339 self.ippSec = dataOut.ippSeconds
1339 self.ippSec = dataOut.ippSeconds
1340 self.nCohInt = dataOut.nCohInt
1340 self.nCohInt = dataOut.nCohInt
1341 print("IPPseconds",dataOut.ippSeconds)
1341 print("IPPseconds",dataOut.ippSeconds)
1342
1342
1343 print("ELVALOR DE n es:", n)
1343 print("ELVALOR DE n es:", n)
1344 if n == None:
1344 if n == None:
1345 raise ValueError("n should be specified.")
1345 raise ValueError("n should be specified.")
1346
1346
1347 if n != None:
1347 if n != None:
1348 if n<2:
1348 if n<2:
1349 raise ValueError("n should be greater than 2")
1349 raise ValueError("n should be greater than 2")
1350
1350
1351 self.n = n
1351 self.n = n
1352 self.__nProf = n
1352 self.__nProf = n
1353
1353
1354 self.__buffer = numpy.zeros((dataOut.nChannels,
1354 self.__buffer = numpy.zeros((dataOut.nChannels,
1355 n,
1355 n,
1356 dataOut.nHeights),
1356 dataOut.nHeights),
1357 dtype='complex')
1357 dtype='complex')
1358 #self.noise = numpy.zeros([self.__nch,self.__nHeis])
1359 #for i in range(self.__nch):
1360 # self.noise[i]=dataOut.getNoise(channel=i)
1361
1358
1362 def putData(self,data):
1359 def putData(self,data):
1363 '''
1360 '''
1364 Add a profile to he __buffer and increase in one the __profiel Index
1361 Add a profile to he __buffer and increase in one the __profiel Index
1365 '''
1362 '''
1366 self.__buffer[:,self.__profIndex,:]= data
1363 self.__buffer[:,self.__profIndex,:]= data
1367 self.__profIndex += 1
1364 self.__profIndex += 1
1368 return
1365 return
1369
1366
1370 def pushData(self,dataOut):
1367 def pushData(self,dataOut):
1371 '''
1368 '''
1372 Return the PULSEPAIR and the profiles used in the operation
1369 Return the PULSEPAIR and the profiles used in the operation
1373 Affected : self.__profileIndex
1370 Affected : self.__profileIndex
1374 '''
1371 '''
1372 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Remove DCΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
1375 if self.removeDC==True:
1373 if self.removeDC==True:
1376 mean = numpy.mean(self.__buffer,1)
1374 mean = numpy.mean(self.__buffer,1)
1377 tmp = mean.reshape(self.__nch,1,self.__nHeis)
1375 tmp = mean.reshape(self.__nch,1,self.__nHeis)
1378 dc= numpy.tile(tmp,[1,self.__nProf,1])
1376 dc= numpy.tile(tmp,[1,self.__nProf,1])
1379 self.__buffer = self.__buffer - dc
1377 self.__buffer = self.__buffer - dc
1378 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Calculo de Potencia Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
1379 pair0 = self.__buffer*numpy.conj(self.__buffer)
1380 pair0 = pair0.real
1381 lag_0 = numpy.sum(pair0,1)
1382 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Calculo de Ruido x canalΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
1383 self.noise = numpy.zeros(self.__nch)
1384 for i in range(self.__nch):
1385 daux = numpy.sort(pair0[i,:,:],axis= None)
1386 self.noise[i]=hildebrand_sekhon( daux ,self.nCohInt)
1387
1388 self.noise = self.noise.reshape(self.__nch,1)
1389 self.noise = numpy.tile(self.noise,[1,self.__nHeis])
1390 noise_buffer = self.noise.reshape(self.__nch,1,self.__nHeis)
1391 noise_buffer = numpy.tile(noise_buffer,[1,self.__nProf,1])
1392 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Potencia recibida= P , Potencia senal = S , Ruido= NΒ·Β·
1393 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· P= S+N ,P=lag_0/N Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
1394 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Power Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
1395 data_power = lag_0/(self.n*self.nCohInt)
1396 #------------------ Senal Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
1397 data_intensity = pair0 - noise_buffer
1398 data_intensity = numpy.sum(data_intensity,axis=1)*(self.n*self.nCohInt)#*self.nCohInt)
1399 #data_intensity = (lag_0-self.noise*self.n)*(self.n*self.nCohInt)
1400 for i in range(self.__nch):
1401 for j in range(self.__nHeis):
1402 if data_intensity[i][j] < 0:
1403 data_intensity[i][j] = numpy.min(numpy.absolute(data_intensity[i][j]))
1380
1404
1381 lag_0 = numpy.sum(self.__buffer*numpy.conj(self.__buffer),1)
1405 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Calculo de Frecuencia y Velocidad dopplerΒ·Β·Β·Β·Β·Β·Β·Β·
1382 data_intensity = lag_0/(self.n*self.nCohInt)#*self.nCohInt)
1383
1384 pair1 = self.__buffer[:,:-1,:]*numpy.conjugate(self.__buffer[:,1:,:])
1406 pair1 = self.__buffer[:,:-1,:]*numpy.conjugate(self.__buffer[:,1:,:])
1385 lag_1 = numpy.sum(pair1,1)
1407 lag_1 = numpy.sum(pair1,1)
1386 #angle = numpy.angle(numpy.sum(pair1,1))*180/(math.pi)
1408 data_freq = (-1/(2.0*math.pi*self.ippSec*self.nCohInt))*numpy.angle(lag_1)
1387 data_velocity = (-1.0*self.lambda_/(4*math.pi*self.ippSec))*numpy.angle(lag_1)#self.ippSec*self.nCohInt
1409 data_velocity = (self.lambda_/2.0)*data_freq
1388
1410
1389 self.noise = numpy.zeros([self.__nch,self.__nHeis])
1411 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Potencia promedio estimada de la SenalΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
1390 for i in range(self.__nch):
1412 lag_0 = lag_0/self.n
1391 self.noise[i]=dataOut.getNoise(channel=i)
1413 S = lag_0-self.noise
1392
1414
1393 lag_0 = lag_0.real/(self.n)
1415 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Frecuencia Doppler promedio Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
1394 lag_1 = lag_1/(self.n-1)
1416 lag_1 = lag_1/(self.n-1)
1395 R1 = numpy.abs(lag_1)
1417 R1 = numpy.abs(lag_1)
1396 S = (lag_0-self.noise)
1397
1418
1419 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Calculo del SNRΒ·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
1398 data_snrPP = S/self.noise
1420 data_snrPP = S/self.noise
1399 data_snrPP = numpy.where(data_snrPP<0,1,data_snrPP)
1421 for i in range(self.__nch):
1422 for j in range(self.__nHeis):
1423 if data_snrPP[i][j] < 1.e-20:
1424 data_snrPP[i][j] = 1.e-20
1400
1425
1426 #Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β· Calculo del ancho espectral Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·Β·
1401 L = S/R1
1427 L = S/R1
1402 L = numpy.where(L<0,1,L)
1428 L = numpy.where(L<0,1,L)
1403 L = numpy.log(L)
1429 L = numpy.log(L)
1404
1405 tmp = numpy.sqrt(numpy.absolute(L))
1430 tmp = numpy.sqrt(numpy.absolute(L))
1406
1431 data_specwidth = (self.lambda_/(2*math.sqrt(2)*math.pi*self.ippSec*self.nCohInt))*tmp*numpy.sign(L)
1407 data_specwidth = (self.lambda_/(2*math.sqrt(2)*math.pi*self.ippSec))*tmp*numpy.sign(L)
1408 #data_specwidth = (self.lambda_/(2*math.sqrt(2)*math.pi*self.ippSec))*k
1409 n = self.__profIndex
1432 n = self.__profIndex
1410
1433
1411 self.__buffer = numpy.zeros((self.__nch, self.__nProf,self.__nHeis), dtype='complex')
1434 self.__buffer = numpy.zeros((self.__nch, self.__nProf,self.__nHeis), dtype='complex')
1412 self.__profIndex = 0
1435 self.__profIndex = 0
1413 return data_intensity,data_velocity,data_snrPP,data_specwidth,n
1436 return data_power,data_intensity,data_velocity,data_snrPP,data_specwidth,n
1437
1414
1438
1415 def pulsePairbyProfiles(self,dataOut):
1439 def pulsePairbyProfiles(self,dataOut):
1416
1440
1417 self.__dataReady = False
1441 self.__dataReady = False
1442 data_power = None
1418 data_intensity = None
1443 data_intensity = None
1419 data_velocity = None
1444 data_velocity = None
1420 data_specwidth = None
1445 data_specwidth = None
1421 data_snrPP = None
1446 data_snrPP = None
1422 self.putData(data=dataOut.data)
1447 self.putData(data=dataOut.data)
1423 if self.__profIndex == self.n:
1448 if self.__profIndex == self.n:
1424 #self.noise = numpy.zeros([self.__nch,self.__nHeis])
1449 data_power,data_intensity, data_velocity,data_snrPP,data_specwidth, n = self.pushData(dataOut=dataOut)
1425 #for i in range(self.__nch):
1426 # self.noise[i]=data.getNoise(channel=i)
1427 #print(self.noise.shape)
1428 data_intensity, data_velocity,data_snrPP,data_specwidth, n = self.pushData(dataOut=dataOut)
1429 self.__dataReady = True
1450 self.__dataReady = True
1430
1451
1431 return data_intensity, data_velocity,data_snrPP,data_specwidth
1452 return data_power, data_intensity, data_velocity, data_snrPP, data_specwidth
1453
1432
1454
1433 def pulsePairOp(self, dataOut, datatime= None):
1455 def pulsePairOp(self, dataOut, datatime= None):
1434
1456
1435 if self.__initime == None:
1457 if self.__initime == None:
1436 self.__initime = datatime
1458 self.__initime = datatime
1437 #print("hola")
1459 data_power, data_intensity, data_velocity, data_snrPP, data_specwidth = self.pulsePairbyProfiles(dataOut)
1438 data_intensity, data_velocity,data_snrPP,data_specwidth = self.pulsePairbyProfiles(dataOut)
1439 self.__lastdatatime = datatime
1460 self.__lastdatatime = datatime
1440
1461
1441 if data_intensity is None:
1462 if data_power is None:
1442 return None, None,None,None,None
1463 return None, None, None,None,None,None
1443
1464
1444 avgdatatime = self.__initime
1465 avgdatatime = self.__initime
1445 deltatime = datatime - self.__lastdatatime
1466 deltatime = datatime - self.__lastdatatime
1446 self.__initime = datatime
1467 self.__initime = datatime
1447
1468
1448 return data_intensity, data_velocity,data_snrPP,data_specwidth,avgdatatime
1469 return data_power, data_intensity, data_velocity, data_snrPP, data_specwidth, avgdatatime
1449
1470
1450 def run(self, dataOut,n = None,removeDC= False, overlapping= False,**kwargs):
1471 def run(self, dataOut,n = None,removeDC= False, overlapping= False,**kwargs):
1451
1472
1452 if not self.isConfig:
1473 if not self.isConfig:
1453 self.setup(dataOut = dataOut, n = n , removeDC=removeDC , **kwargs)
1474 self.setup(dataOut = dataOut, n = n , removeDC=removeDC , **kwargs)
1454 self.isConfig = True
1475 self.isConfig = True
1455 data_intensity, data_velocity,data_snrPP,data_specwidth, avgdatatime = self.pulsePairOp(dataOut, dataOut.utctime)
1476 data_power, data_intensity, data_velocity,data_snrPP,data_specwidth, avgdatatime = self.pulsePairOp(dataOut, dataOut.utctime)
1456 dataOut.flagNoData = True
1477 dataOut.flagNoData = True
1457
1478
1458 if self.__dataReady:
1479 if self.__dataReady:
1459 dataOut.nCohInt *= self.n
1480 dataOut.nCohInt *= self.n
1460 dataOut.data_intensity = data_intensity #valor para intensidad
1481 dataOut.dataPP_POW = data_intensity # S
1461 dataOut.data_velocity = data_velocity #valor para velocidad
1482 dataOut.dataPP_POWER = data_power # P
1462 dataOut.data_snrPP = data_snrPP # valor para snr
1483 dataOut.dataPP_DOP = data_velocity
1463 dataOut.data_specwidth = data_specwidth
1484 dataOut.dataPP_SNR = data_snrPP
1485 dataOut.dataPP_WIDTH = data_specwidth
1464 dataOut.PRFbyAngle = self.n #numero de PRF*cada angulo rotado que equivale a un tiempo.
1486 dataOut.PRFbyAngle = self.n #numero de PRF*cada angulo rotado que equivale a un tiempo.
1465 dataOut.utctime = avgdatatime
1487 dataOut.utctime = avgdatatime
1466 dataOut.flagNoData = False
1488 dataOut.flagNoData = False
1467 return dataOut
1489 return dataOut
1468
1490
1469
1491
1492
1470 # import collections
1493 # import collections
1471 # from scipy.stats import mode
1494 # from scipy.stats import mode
1472 #
1495 #
1473 # class Synchronize(Operation):
1496 # class Synchronize(Operation):
1474 #
1497 #
1475 # isConfig = False
1498 # isConfig = False
1476 # __profIndex = 0
1499 # __profIndex = 0
1477 #
1500 #
1478 # def __init__(self, **kwargs):
1501 # def __init__(self, **kwargs):
1479 #
1502 #
1480 # Operation.__init__(self, **kwargs)
1503 # Operation.__init__(self, **kwargs)
1481 # # self.isConfig = False
1504 # # self.isConfig = False
1482 # self.__powBuffer = None
1505 # self.__powBuffer = None
1483 # self.__startIndex = 0
1506 # self.__startIndex = 0
1484 # self.__pulseFound = False
1507 # self.__pulseFound = False
1485 #
1508 #
1486 # def __findTxPulse(self, dataOut, channel=0, pulse_with = None):
1509 # def __findTxPulse(self, dataOut, channel=0, pulse_with = None):
1487 #
1510 #
1488 # #Read data
1511 # #Read data
1489 #
1512 #
1490 # powerdB = dataOut.getPower(channel = channel)
1513 # powerdB = dataOut.getPower(channel = channel)
1491 # noisedB = dataOut.getNoise(channel = channel)[0]
1514 # noisedB = dataOut.getNoise(channel = channel)[0]
1492 #
1515 #
1493 # self.__powBuffer.extend(powerdB.flatten())
1516 # self.__powBuffer.extend(powerdB.flatten())
1494 #
1517 #
1495 # dataArray = numpy.array(self.__powBuffer)
1518 # dataArray = numpy.array(self.__powBuffer)
1496 #
1519 #
1497 # filteredPower = numpy.correlate(dataArray, dataArray[0:self.__nSamples], "same")
1520 # filteredPower = numpy.correlate(dataArray, dataArray[0:self.__nSamples], "same")
1498 #
1521 #
1499 # maxValue = numpy.nanmax(filteredPower)
1522 # maxValue = numpy.nanmax(filteredPower)
1500 #
1523 #
1501 # if maxValue < noisedB + 10:
1524 # if maxValue < noisedB + 10:
1502 # #No se encuentra ningun pulso de transmision
1525 # #No se encuentra ningun pulso de transmision
1503 # return None
1526 # return None
1504 #
1527 #
1505 # maxValuesIndex = numpy.where(filteredPower > maxValue - 0.1*abs(maxValue))[0]
1528 # maxValuesIndex = numpy.where(filteredPower > maxValue - 0.1*abs(maxValue))[0]
1506 #
1529 #
1507 # if len(maxValuesIndex) < 2:
1530 # if len(maxValuesIndex) < 2:
1508 # #Solo se encontro un solo pulso de transmision de un baudio, esperando por el siguiente TX
1531 # #Solo se encontro un solo pulso de transmision de un baudio, esperando por el siguiente TX
1509 # return None
1532 # return None
1510 #
1533 #
1511 # phasedMaxValuesIndex = maxValuesIndex - self.__nSamples
1534 # phasedMaxValuesIndex = maxValuesIndex - self.__nSamples
1512 #
1535 #
1513 # #Seleccionar solo valores con un espaciamiento de nSamples
1536 # #Seleccionar solo valores con un espaciamiento de nSamples
1514 # pulseIndex = numpy.intersect1d(maxValuesIndex, phasedMaxValuesIndex)
1537 # pulseIndex = numpy.intersect1d(maxValuesIndex, phasedMaxValuesIndex)
1515 #
1538 #
1516 # if len(pulseIndex) < 2:
1539 # if len(pulseIndex) < 2:
1517 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1540 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1518 # return None
1541 # return None
1519 #
1542 #
1520 # spacing = pulseIndex[1:] - pulseIndex[:-1]
1543 # spacing = pulseIndex[1:] - pulseIndex[:-1]
1521 #
1544 #
1522 # #remover senales que se distancien menos de 10 unidades o muestras
1545 # #remover senales que se distancien menos de 10 unidades o muestras
1523 # #(No deberian existir IPP menor a 10 unidades)
1546 # #(No deberian existir IPP menor a 10 unidades)
1524 #
1547 #
1525 # realIndex = numpy.where(spacing > 10 )[0]
1548 # realIndex = numpy.where(spacing > 10 )[0]
1526 #
1549 #
1527 # if len(realIndex) < 2:
1550 # if len(realIndex) < 2:
1528 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1551 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1529 # return None
1552 # return None
1530 #
1553 #
1531 # #Eliminar pulsos anchos (deja solo la diferencia entre IPPs)
1554 # #Eliminar pulsos anchos (deja solo la diferencia entre IPPs)
1532 # realPulseIndex = pulseIndex[realIndex]
1555 # realPulseIndex = pulseIndex[realIndex]
1533 #
1556 #
1534 # period = mode(realPulseIndex[1:] - realPulseIndex[:-1])[0][0]
1557 # period = mode(realPulseIndex[1:] - realPulseIndex[:-1])[0][0]
1535 #
1558 #
1536 # print "IPP = %d samples" %period
1559 # print "IPP = %d samples" %period
1537 #
1560 #
1538 # self.__newNSamples = dataOut.nHeights #int(period)
1561 # self.__newNSamples = dataOut.nHeights #int(period)
1539 # self.__startIndex = int(realPulseIndex[0])
1562 # self.__startIndex = int(realPulseIndex[0])
1540 #
1563 #
1541 # return 1
1564 # return 1
1542 #
1565 #
1543 #
1566 #
1544 # def setup(self, nSamples, nChannels, buffer_size = 4):
1567 # def setup(self, nSamples, nChannels, buffer_size = 4):
1545 #
1568 #
1546 # self.__powBuffer = collections.deque(numpy.zeros( buffer_size*nSamples,dtype=numpy.float),
1569 # self.__powBuffer = collections.deque(numpy.zeros( buffer_size*nSamples,dtype=numpy.float),
1547 # maxlen = buffer_size*nSamples)
1570 # maxlen = buffer_size*nSamples)
1548 #
1571 #
1549 # bufferList = []
1572 # bufferList = []
1550 #
1573 #
1551 # for i in range(nChannels):
1574 # for i in range(nChannels):
1552 # bufferByChannel = collections.deque(numpy.zeros( buffer_size*nSamples, dtype=numpy.complex) + numpy.NAN,
1575 # bufferByChannel = collections.deque(numpy.zeros( buffer_size*nSamples, dtype=numpy.complex) + numpy.NAN,
1553 # maxlen = buffer_size*nSamples)
1576 # maxlen = buffer_size*nSamples)
1554 #
1577 #
1555 # bufferList.append(bufferByChannel)
1578 # bufferList.append(bufferByChannel)
1556 #
1579 #
1557 # self.__nSamples = nSamples
1580 # self.__nSamples = nSamples
1558 # self.__nChannels = nChannels
1581 # self.__nChannels = nChannels
1559 # self.__bufferList = bufferList
1582 # self.__bufferList = bufferList
1560 #
1583 #
1561 # def run(self, dataOut, channel = 0):
1584 # def run(self, dataOut, channel = 0):
1562 #
1585 #
1563 # if not self.isConfig:
1586 # if not self.isConfig:
1564 # nSamples = dataOut.nHeights
1587 # nSamples = dataOut.nHeights
1565 # nChannels = dataOut.nChannels
1588 # nChannels = dataOut.nChannels
1566 # self.setup(nSamples, nChannels)
1589 # self.setup(nSamples, nChannels)
1567 # self.isConfig = True
1590 # self.isConfig = True
1568 #
1591 #
1569 # #Append new data to internal buffer
1592 # #Append new data to internal buffer
1570 # for thisChannel in range(self.__nChannels):
1593 # for thisChannel in range(self.__nChannels):
1571 # bufferByChannel = self.__bufferList[thisChannel]
1594 # bufferByChannel = self.__bufferList[thisChannel]
1572 # bufferByChannel.extend(dataOut.data[thisChannel])
1595 # bufferByChannel.extend(dataOut.data[thisChannel])
1573 #
1596 #
1574 # if self.__pulseFound:
1597 # if self.__pulseFound:
1575 # self.__startIndex -= self.__nSamples
1598 # self.__startIndex -= self.__nSamples
1576 #
1599 #
1577 # #Finding Tx Pulse
1600 # #Finding Tx Pulse
1578 # if not self.__pulseFound:
1601 # if not self.__pulseFound:
1579 # indexFound = self.__findTxPulse(dataOut, channel)
1602 # indexFound = self.__findTxPulse(dataOut, channel)
1580 #
1603 #
1581 # if indexFound == None:
1604 # if indexFound == None:
1582 # dataOut.flagNoData = True
1605 # dataOut.flagNoData = True
1583 # return
1606 # return
1584 #
1607 #
1585 # self.__arrayBuffer = numpy.zeros((self.__nChannels, self.__newNSamples), dtype = numpy.complex)
1608 # self.__arrayBuffer = numpy.zeros((self.__nChannels, self.__newNSamples), dtype = numpy.complex)
1586 # self.__pulseFound = True
1609 # self.__pulseFound = True
1587 # self.__startIndex = indexFound
1610 # self.__startIndex = indexFound
1588 #
1611 #
1589 # #If pulse was found ...
1612 # #If pulse was found ...
1590 # for thisChannel in range(self.__nChannels):
1613 # for thisChannel in range(self.__nChannels):
1591 # bufferByChannel = self.__bufferList[thisChannel]
1614 # bufferByChannel = self.__bufferList[thisChannel]
1592 # #print self.__startIndex
1615 # #print self.__startIndex
1593 # x = numpy.array(bufferByChannel)
1616 # x = numpy.array(bufferByChannel)
1594 # self.__arrayBuffer[thisChannel] = x[self.__startIndex:self.__startIndex+self.__newNSamples]
1617 # self.__arrayBuffer[thisChannel] = x[self.__startIndex:self.__startIndex+self.__newNSamples]
1595 #
1618 #
1596 # deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1619 # deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1597 # dataOut.heightList = numpy.arange(self.__newNSamples)*deltaHeight
1620 # dataOut.heightList = numpy.arange(self.__newNSamples)*deltaHeight
1598 # # dataOut.ippSeconds = (self.__newNSamples / deltaHeight)/1e6
1621 # # dataOut.ippSeconds = (self.__newNSamples / deltaHeight)/1e6
1599 #
1622 #
1600 # dataOut.data = self.__arrayBuffer
1623 # dataOut.data = self.__arrayBuffer
1601 #
1624 #
1602 # self.__startIndex += self.__newNSamples
1625 # self.__startIndex += self.__newNSamples
1603 #
1626 #
1604 # return
1627 # return
@@ -1,49 +1,73
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 = '/home/alex/Downloads/NEW_WR2/spc16removeDC'
5 path = '/home/alex/Downloads/NEW_WR2/spc16removeDC'
6 figpath = path
6 figpath = path
7 desc = "Simulator Test"
7 desc = "Simulator Test"
8
8
9 controllerObj = Project()
9 controllerObj = Project()
10
10
11 controllerObj.setup(id='10',name='Test Simulator',description=desc)
11 controllerObj.setup(id='10',name='Test Simulator',description=desc)
12
12
13 readUnitConfObj = controllerObj.addReadUnit(datatype='SimulatorReader',
13 readUnitConfObj = controllerObj.addReadUnit(datatype='SimulatorReader',
14 frequency=9.345e9,
14 frequency=9.345e9,
15 FixRCP_IPP= 60,
15 FixRCP_IPP= 60,
16 Tau_0 = 30,
16 Tau_0 = 30,
17 AcqH0_0=0,
17 AcqH0_0=0,
18 samples=330,
18 samples=330,
19 AcqDH_0=0.15,
19 AcqDH_0=0.15,
20 FixRCP_TXA=0.15,
20 FixRCP_TXA=0.15,
21 FixRCP_TXB=0.15,
21 FixRCP_TXB=0.15,
22 Fdoppler=600.0,
22 Fdoppler=600.0,
23 Hdoppler=36,
23 Hdoppler=36,
24 Adoppler=300,#300
24 Adoppler=300,#300
25 delay=0,
25 delay=0,
26 online=0,
26 online=0,
27 walk=0,
27 walk=0,
28 nTotalReadFiles=3)
28 profilesPerBlock=625,
29
29 dataBlocksPerFile=100)#,#nTotalReadFiles=2)
30 '''
31 readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader',
32 path=path,
33 startDate="2020/01/01", #"2020/01/01",#today,
34 endDate= "2020/12/01", #"2020/12/30",#today,
35 startTime='00:00:00',
36 endTime='23:59:59',
37 delay=0,
38 #set=0,
39 online=0,
40 walk=1)
41 '''
30 opObj11 = readUnitConfObj.addOperation(name='printInfo')
42 opObj11 = readUnitConfObj.addOperation(name='printInfo')
31
43
32 procUnitConfObjA = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId())
44 procUnitConfObjA = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId())
33 #opObj11 = procUnitConfObjA.addOperation(name='CohInt', optype='other')
45 #opObj11 = procUnitConfObjA.addOperation(name='CohInt', optype='other')
34 #opObj11.addParameter(name='n', value='10', format='int')
46 #opObj11.addParameter(name='n', value='10', format='int')
35
47
36 #opObj10 = procUnitConfObjA.addOperation(name='selectChannels')
48 #opObj10 = procUnitConfObjA.addOperation(name='selectChannels')
37 #opObj10.addParameter(name='channelList', value=[0])
49 #opObj10.addParameter(name='channelList', value=[0])
38 opObj11 = procUnitConfObjA.addOperation(name='PulsePairVoltage', optype='other')
50 opObj11 = procUnitConfObjA.addOperation(name='PulsePairVoltage', optype='other')
39 opObj11.addParameter(name='n', value='300', format='int')#10
51 opObj11.addParameter(name='n', value='625', format='int')#10
40 opObj11.addParameter(name='removeDC', value=1, format='int')
52 opObj11.addParameter(name='removeDC', value=1, format='int')
41
53
42 #opObj11 = procUnitConfObjA.addOperation(name='PulsepairPowerPlot', optype='other')
54 #opObj11 = procUnitConfObjA.addOperation(name='PulsepairPowerPlot', optype='other')
55 #opObj11 = procUnitConfObjA.addOperation(name='PulsepairSignalPlot', optype='other')
56
43
57
44 opObj11 = procUnitConfObjA.addOperation(name='PulsepairVelocityPlot', optype='other')
58 #opObj11 = procUnitConfObjA.addOperation(name='PulsepairVelocityPlot', optype='other')
45 #opObj11.addParameter(name='xmax', value=8)
59 #opObj11.addParameter(name='xmax', value=8)
46
60
47 opObj11 = procUnitConfObjA.addOperation(name='PulsepairSpecwidthPlot', optype='other')
61 #opObj11 = procUnitConfObjA.addOperation(name='PulsepairSpecwidthPlot', optype='other')
62
63 procUnitConfObjB= controllerObj.addProcUnit(datatype='ParametersProc',inputId=procUnitConfObjA.getId())
64
65
66 opObj10 = procUnitConfObjB.addOperation(name='ParameterWriter')
67 opObj10.addParameter(name='path',value=figpath)
68 #opObj10.addParameter(name='mode',value=0)
69 opObj10.addParameter(name='blocksPerFile',value='100',format='int')
70 opObj10.addParameter(name='metadataList',value='utctimeInit,timeInterval',format='list')
71 opObj10.addParameter(name='dataList',value='dataPP_POW,dataPP_DOP,dataPP_SNR,dataPP_WIDTH')#,format='list'
48
72
49 controllerObj.start()
73 controllerObj.start()
General Comments 0
You need to be logged in to leave comments. Login now