##// END OF EJS Templates
bugs and formatting
Juan C. Espinoza -
r1096:fa511d6b9ad9
parent child
Show More
@@ -1,348 +1,354
1 '''
1 '''
2
2
3 $Author: murco $
3 $Author: murco $
4 $Id: jroproc_base.py 1 2012-11-12 18:56:07Z murco $
4 $Id: jroproc_base.py 1 2012-11-12 18:56:07Z murco $
5 '''
5 '''
6 import inspect
6 import inspect
7 from fuzzywuzzy import process
7 from fuzzywuzzy import process
8
8
9 def checkKwargs(method, kwargs):
9 def checkKwargs(method, kwargs):
10 currentKwargs = kwargs
10 currentKwargs = kwargs
11 choices = inspect.getargspec(method).args
11 choices = inspect.getargspec(method).args
12 try:
12 try:
13 choices.remove('self')
13 choices.remove('self')
14 except Exception as e:
14 except Exception as e:
15 pass
15 pass
16
16
17 try:
17 try:
18 choices.remove('dataOut')
18 choices.remove('dataOut')
19 except Exception as e:
19 except Exception as e:
20 pass
20 pass
21
21
22 for kwarg in kwargs:
22 for kwarg in kwargs:
23 fuzz = process.extractOne(kwarg, choices)
23 fuzz = process.extractOne(kwarg, choices)
24 if fuzz is None:
24 if fuzz is None:
25 continue
25 continue
26 if fuzz[1] < 100:
26 if fuzz[1] < 100:
27 raise Exception('\x1b[0;32;40mDid you mean {} instead of {} in {}? \x1b[0m'.
27 raise Exception('\x1b[0;32;40mDid you mean {} instead of {} in {}? \x1b[0m'.
28 format(fuzz[0], kwarg, method.__self__.__class__.__name__))
28 format(fuzz[0], kwarg, method.__self__.__class__.__name__))
29
29
30 class ProcessingUnit(object):
30 class ProcessingUnit(object):
31
31
32 """
32 """
33 Esta es la clase base para el procesamiento de datos.
33 Esta es la clase base para el procesamiento de datos.
34
34
35 Contiene el metodo "call" para llamar operaciones. Las operaciones pueden ser:
35 Contiene el metodo "call" para llamar operaciones. Las operaciones pueden ser:
36 - Metodos internos (callMethod)
36 - Metodos internos (callMethod)
37 - Objetos del tipo Operation (callObject). Antes de ser llamados, estos objetos
37 - Objetos del tipo Operation (callObject). Antes de ser llamados, estos objetos
38 tienen que ser agreagados con el metodo "add".
38 tienen que ser agreagados con el metodo "add".
39
39
40 """
40 """
41 # objeto de datos de entrada (Voltage, Spectra o Correlation)
41 # objeto de datos de entrada (Voltage, Spectra o Correlation)
42 dataIn = None
42 dataIn = None
43 dataInList = []
43 dataInList = []
44
44
45 # objeto de datos de entrada (Voltage, Spectra o Correlation)
45 # objeto de datos de entrada (Voltage, Spectra o Correlation)
46 dataOut = None
46 dataOut = None
47
47
48 operations2RunDict = None
48 operations2RunDict = None
49
49
50 isConfig = False
50 isConfig = False
51
51
52
52
53 def __init__(self, *args, **kwargs):
53 def __init__(self, *args, **kwargs):
54
54
55 self.dataIn = None
55 self.dataIn = None
56 self.dataInList = []
56 self.dataInList = []
57
57
58 self.dataOut = None
58 self.dataOut = None
59
59
60 self.operations2RunDict = {}
60 self.operations2RunDict = {}
61 self.operationKwargs = {}
61 self.operationKwargs = {}
62
62
63 self.isConfig = False
63 self.isConfig = False
64
64
65 self.args = args
65 self.args = args
66 self.kwargs = kwargs
66 self.kwargs = kwargs
67
68 if not hasattr(self, 'name'):
69 self.name = self.__class__.__name__
70
67 checkKwargs(self.run, kwargs)
71 checkKwargs(self.run, kwargs)
68
72
69 def getAllowedArgs(self):
73 def getAllowedArgs(self):
70 return inspect.getargspec(self.run).args
74 return inspect.getargspec(self.run).args
71
75
72 def addOperationKwargs(self, objId, **kwargs):
76 def addOperationKwargs(self, objId, **kwargs):
73 '''
77 '''
74 '''
78 '''
75
79
76 self.operationKwargs[objId] = kwargs
80 self.operationKwargs[objId] = kwargs
77
81
78
82
79 def addOperation(self, opObj, objId):
83 def addOperation(self, opObj, objId):
80
84
81 """
85 """
82 Agrega un objeto del tipo "Operation" (opObj) a la lista de objetos "self.objectList" y retorna el
86 Agrega un objeto del tipo "Operation" (opObj) a la lista de objetos "self.objectList" y retorna el
83 identificador asociado a este objeto.
87 identificador asociado a este objeto.
84
88
85 Input:
89 Input:
86
90
87 object : objeto de la clase "Operation"
91 object : objeto de la clase "Operation"
88
92
89 Return:
93 Return:
90
94
91 objId : identificador del objeto, necesario para ejecutar la operacion
95 objId : identificador del objeto, necesario para ejecutar la operacion
92 """
96 """
93
97
94 self.operations2RunDict[objId] = opObj
98 self.operations2RunDict[objId] = opObj
95
99
96 return objId
100 return objId
97
101
98 def getOperationObj(self, objId):
102 def getOperationObj(self, objId):
99
103
100 if objId not in self.operations2RunDict.keys():
104 if objId not in self.operations2RunDict.keys():
101 return None
105 return None
102
106
103 return self.operations2RunDict[objId]
107 return self.operations2RunDict[objId]
104
108
105 def operation(self, **kwargs):
109 def operation(self, **kwargs):
106
110
107 """
111 """
108 Operacion directa sobre la data (dataOut.data). Es necesario actualizar los valores de los
112 Operacion directa sobre la data (dataOut.data). Es necesario actualizar los valores de los
109 atributos del objeto dataOut
113 atributos del objeto dataOut
110
114
111 Input:
115 Input:
112
116
113 **kwargs : Diccionario de argumentos de la funcion a ejecutar
117 **kwargs : Diccionario de argumentos de la funcion a ejecutar
114 """
118 """
115
119
116 raise NotImplementedError
120 raise NotImplementedError
117
121
118 def callMethod(self, name, opId):
122 def callMethod(self, name, opId):
119
123
120 """
124 """
121 Ejecuta el metodo con el nombre "name" y con argumentos **kwargs de la propia clase.
125 Ejecuta el metodo con el nombre "name" y con argumentos **kwargs de la propia clase.
122
126
123 Input:
127 Input:
124 name : nombre del metodo a ejecutar
128 name : nombre del metodo a ejecutar
125
129
126 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
130 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
127
131
128 """
132 """
129
133
130 #Checking the inputs
134 #Checking the inputs
131 if name == 'run':
135 if name == 'run':
132
136
133 if not self.checkInputs():
137 if not self.checkInputs():
134 self.dataOut.flagNoData = True
138 self.dataOut.flagNoData = True
135 return False
139 return False
136 else:
140 else:
137 #Si no es un metodo RUN la entrada es la misma dataOut (interna)
141 #Si no es un metodo RUN la entrada es la misma dataOut (interna)
138 if self.dataOut is not None and self.dataOut.isEmpty():
142 if self.dataOut is not None and self.dataOut.isEmpty():
139 return False
143 return False
140
144
141 #Getting the pointer to method
145 #Getting the pointer to method
142 methodToCall = getattr(self, name)
146 methodToCall = getattr(self, name)
143
147
144 #Executing the self method
148 #Executing the self method
145
149
146 if hasattr(self, 'mp'):
150 if hasattr(self, 'mp'):
147 if name=='run':
151 if name=='run':
148 if self.mp is False:
152 if self.mp is False:
149 self.mp = True
153 self.mp = True
150 self.start()
154 self.start()
151 else:
155 else:
152 self.operationKwargs[opId]['parent'] = self.kwargs
156 self.operationKwargs[opId]['parent'] = self.kwargs
153 methodToCall(**self.operationKwargs[opId])
157 methodToCall(**self.operationKwargs[opId])
154 else:
158 else:
155 if name=='run':
159 if name=='run':
156 methodToCall(**self.kwargs)
160 methodToCall(**self.kwargs)
157 else:
161 else:
158 methodToCall(**self.operationKwargs[opId])
162 methodToCall(**self.operationKwargs[opId])
159
163
160 if self.dataOut is None:
164 if self.dataOut is None:
161 return False
165 return False
162
166
163 if self.dataOut.isEmpty():
167 if self.dataOut.isEmpty():
164 return False
168 return False
165
169
166 return True
170 return True
167
171
168 def callObject(self, objId):
172 def callObject(self, objId):
169
173
170 """
174 """
171 Ejecuta la operacion asociada al identificador del objeto "objId"
175 Ejecuta la operacion asociada al identificador del objeto "objId"
172
176
173 Input:
177 Input:
174
178
175 objId : identificador del objeto a ejecutar
179 objId : identificador del objeto a ejecutar
176
180
177 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
181 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
178
182
179 Return:
183 Return:
180
184
181 None
185 None
182 """
186 """
183
187
184 if self.dataOut is not None and self.dataOut.isEmpty():
188 if self.dataOut is not None and self.dataOut.isEmpty():
185 return False
189 return False
186
190
187 externalProcObj = self.operations2RunDict[objId]
191 externalProcObj = self.operations2RunDict[objId]
188
192
189 if hasattr(externalProcObj, 'mp'):
193 if hasattr(externalProcObj, 'mp'):
190 if externalProcObj.mp is False:
194 if externalProcObj.mp is False:
191 externalProcObj.kwargs['parent'] = self.kwargs
195 externalProcObj.kwargs['parent'] = self.kwargs
192 self.operationKwargs[objId] = externalProcObj.kwargs
196 self.operationKwargs[objId] = externalProcObj.kwargs
193 externalProcObj.mp = True
197 externalProcObj.mp = True
194 externalProcObj.start()
198 externalProcObj.start()
195 else:
199 else:
196 externalProcObj.run(self.dataOut, **externalProcObj.kwargs)
200 externalProcObj.run(self.dataOut, **externalProcObj.kwargs)
197 self.operationKwargs[objId] = externalProcObj.kwargs
201 self.operationKwargs[objId] = externalProcObj.kwargs
198
202
199
203
200 return True
204 return True
201
205
202 def call(self, opType, opName=None, opId=None):
206 def call(self, opType, opName=None, opId=None):
203 """
207 """
204 Return True si ejecuta la operacion interna nombrada "opName" o la operacion externa
208 Return True si ejecuta la operacion interna nombrada "opName" o la operacion externa
205 identificada con el id "opId"; con los argumentos "**kwargs".
209 identificada con el id "opId"; con los argumentos "**kwargs".
206
210
207 False si la operacion no se ha ejecutado.
211 False si la operacion no se ha ejecutado.
208
212
209 Input:
213 Input:
210
214
211 opType : Puede ser "self" o "external"
215 opType : Puede ser "self" o "external"
212
216
213 Depende del tipo de operacion para llamar a:callMethod or callObject:
217 Depende del tipo de operacion para llamar a:callMethod or callObject:
214
218
215 1. If opType = "self": Llama a un metodo propio de esta clase:
219 1. If opType = "self": Llama a un metodo propio de esta clase:
216
220
217 name_method = getattr(self, name)
221 name_method = getattr(self, name)
218 name_method(**kwargs)
222 name_method(**kwargs)
219
223
220
224
221 2. If opType = "other" o"external": Llama al metodo "run()" de una instancia de la
225 2. If opType = "other" o"external": Llama al metodo "run()" de una instancia de la
222 clase "Operation" o de un derivado de ella:
226 clase "Operation" o de un derivado de ella:
223
227
224 instanceName = self.operationList[opId]
228 instanceName = self.operationList[opId]
225 instanceName.run(**kwargs)
229 instanceName.run(**kwargs)
226
230
227 opName : Si la operacion es interna (opType = 'self'), entonces el "opName" sera
231 opName : Si la operacion es interna (opType = 'self'), entonces el "opName" sera
228 usada para llamar a un metodo interno de la clase Processing
232 usada para llamar a un metodo interno de la clase Processing
229
233
230 opId : Si la operacion es externa (opType = 'other' o 'external), entonces el
234 opId : Si la operacion es externa (opType = 'other' o 'external), entonces el
231 "opId" sera usada para llamar al metodo "run" de la clase Operation
235 "opId" sera usada para llamar al metodo "run" de la clase Operation
232 registrada anteriormente con ese Id
236 registrada anteriormente con ese Id
233
237
234 Exception:
238 Exception:
235 Este objeto de tipo Operation debe de haber sido agregado antes con el metodo:
239 Este objeto de tipo Operation debe de haber sido agregado antes con el metodo:
236 "addOperation" e identificado con el valor "opId" = el id de la operacion.
240 "addOperation" e identificado con el valor "opId" = el id de la operacion.
237 De lo contrario retornara un error del tipo ValueError
241 De lo contrario retornara un error del tipo ValueError
238
242
239 """
243 """
240
244
241 if opType == 'self':
245 if opType == 'self':
242
246
243 if not opName:
247 if not opName:
244 raise ValueError, "opName parameter should be defined"
248 raise ValueError, "opName parameter should be defined"
245
249
246 sts = self.callMethod(opName, opId)
250 sts = self.callMethod(opName, opId)
247
251
248 elif opType == 'other' or opType == 'external' or opType == 'plotter':
252 elif opType == 'other' or opType == 'external' or opType == 'plotter':
249
253
250 if not opId:
254 if not opId:
251 raise ValueError, "opId parameter should be defined"
255 raise ValueError, "opId parameter should be defined"
252
256
253 if opId not in self.operations2RunDict.keys():
257 if opId not in self.operations2RunDict.keys():
254 raise ValueError, "Any operation with id=%s has been added" %str(opId)
258 raise ValueError, "Any operation with id=%s has been added" %str(opId)
255
259
256 sts = self.callObject(opId)
260 sts = self.callObject(opId)
257
261
258 else:
262 else:
259 raise ValueError, "opType should be 'self', 'external' or 'plotter'; and not '%s'" %opType
263 raise ValueError, "opType should be 'self', 'external' or 'plotter'; and not '%s'" %opType
260
264
261 return sts
265 return sts
262
266
263 def setInput(self, dataIn):
267 def setInput(self, dataIn):
264
268
265 self.dataIn = dataIn
269 self.dataIn = dataIn
266 self.dataInList.append(dataIn)
270 self.dataInList.append(dataIn)
267
271
268 def getOutputObj(self):
272 def getOutputObj(self):
269
273
270 return self.dataOut
274 return self.dataOut
271
275
272 def checkInputs(self):
276 def checkInputs(self):
273
277
274 for thisDataIn in self.dataInList:
278 for thisDataIn in self.dataInList:
275
279
276 if thisDataIn.isEmpty():
280 if thisDataIn.isEmpty():
277 return False
281 return False
278
282
279 return True
283 return True
280
284
281 def setup(self):
285 def setup(self):
282
286
283 raise NotImplementedError
287 raise NotImplementedError
284
288
285 def run(self):
289 def run(self):
286
290
287 raise NotImplementedError
291 raise NotImplementedError
288
292
289 def close(self):
293 def close(self):
290 #Close every thread, queue or any other object here is it is neccesary.
294 #Close every thread, queue or any other object here is it is neccesary.
291 return
295 return
292
296
293 class Operation(object):
297 class Operation(object):
294
298
295 """
299 """
296 Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit
300 Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit
297 y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de
301 y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de
298 acumulacion dentro de esta clase
302 acumulacion dentro de esta clase
299
303
300 Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer)
304 Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer)
301
305
302 """
306 """
303
307
304 __buffer = None
308 __buffer = None
305 isConfig = False
309 isConfig = False
306
310
307 def __init__(self, **kwargs):
311 def __init__(self, **kwargs):
308
312
309 self.__buffer = None
313 self.__buffer = None
310 self.isConfig = False
314 self.isConfig = False
311 self.kwargs = kwargs
315 self.kwargs = kwargs
316 if not hasattr(self, 'name'):
317 self.name = self.__class__.__name__
312 checkKwargs(self.run, kwargs)
318 checkKwargs(self.run, kwargs)
313
319
314 def getAllowedArgs(self):
320 def getAllowedArgs(self):
315 return inspect.getargspec(self.run).args
321 return inspect.getargspec(self.run).args
316
322
317 def setup(self):
323 def setup(self):
318
324
319 self.isConfig = True
325 self.isConfig = True
320
326
321 raise NotImplementedError
327 raise NotImplementedError
322
328
323 def run(self, dataIn, **kwargs):
329 def run(self, dataIn, **kwargs):
324
330
325 """
331 """
326 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los
332 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los
327 atributos del objeto dataIn.
333 atributos del objeto dataIn.
328
334
329 Input:
335 Input:
330
336
331 dataIn : objeto del tipo JROData
337 dataIn : objeto del tipo JROData
332
338
333 Return:
339 Return:
334
340
335 None
341 None
336
342
337 Affected:
343 Affected:
338 __buffer : buffer de recepcion de datos.
344 __buffer : buffer de recepcion de datos.
339
345
340 """
346 """
341 if not self.isConfig:
347 if not self.isConfig:
342 self.setup(**kwargs)
348 self.setup(**kwargs)
343
349
344 raise NotImplementedError
350 raise NotImplementedError
345
351
346 def close(self):
352 def close(self):
347
353
348 pass
354 pass
@@ -1,4044 +1,4044
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 copy_reg
13 import copy_reg
14 import cPickle
14 import cPickle
15 import types
15 import types
16 from functools import partial
16 from functools import partial
17 import time
17 import time
18 #from sklearn.cluster import KMeans
18 #from sklearn.cluster import KMeans
19
19
20
20
21 from scipy.optimize import fmin_l_bfgs_b #optimize with bounds on state papameters
21 from scipy.optimize import fmin_l_bfgs_b #optimize with bounds on state papameters
22 from jroproc_base import ProcessingUnit, Operation
22 from jroproc_base import ProcessingUnit, Operation
23 from schainpy.model.data.jrodata import Parameters, hildebrand_sekhon
23 from schainpy.model.data.jrodata import Parameters, hildebrand_sekhon
24 from scipy import asarray as ar,exp
24 from scipy import asarray as ar,exp
25 from scipy.optimize import curve_fit
25 from scipy.optimize import curve_fit
26
26
27 import warnings
27 import warnings
28 from numpy import NaN
28 from numpy import NaN
29 from scipy.optimize.optimize import OptimizeWarning
29 from scipy.optimize.optimize import OptimizeWarning
30 warnings.filterwarnings('ignore')
30 warnings.filterwarnings('ignore')
31
31
32
32
33 SPEED_OF_LIGHT = 299792458
33 SPEED_OF_LIGHT = 299792458
34
34
35
35
36 '''solving pickling issue'''
36 '''solving pickling issue'''
37
37
38 def _pickle_method(method):
38 def _pickle_method(method):
39 func_name = method.im_func.__name__
39 func_name = method.im_func.__name__
40 obj = method.im_self
40 obj = method.im_self
41 cls = method.im_class
41 cls = method.im_class
42 return _unpickle_method, (func_name, obj, cls)
42 return _unpickle_method, (func_name, obj, cls)
43
43
44 def _unpickle_method(func_name, obj, cls):
44 def _unpickle_method(func_name, obj, cls):
45 for cls in cls.mro():
45 for cls in cls.mro():
46 try:
46 try:
47 func = cls.__dict__[func_name]
47 func = cls.__dict__[func_name]
48 except KeyError:
48 except KeyError:
49 pass
49 pass
50 else:
50 else:
51 break
51 break
52 return func.__get__(obj, cls)
52 return func.__get__(obj, cls)
53
53
54 class ParametersProc(ProcessingUnit):
54 class ParametersProc(ProcessingUnit):
55
55
56 nSeconds = None
56 nSeconds = None
57
57
58 def __init__(self):
58 def __init__(self):
59 ProcessingUnit.__init__(self)
59 ProcessingUnit.__init__(self)
60
60
61 # self.objectDict = {}
61 # self.objectDict = {}
62 self.buffer = None
62 self.buffer = None
63 self.firstdatatime = None
63 self.firstdatatime = None
64 self.profIndex = 0
64 self.profIndex = 0
65 self.dataOut = Parameters()
65 self.dataOut = Parameters()
66
66
67 def __updateObjFromInput(self):
67 def __updateObjFromInput(self):
68
68
69 self.dataOut.inputUnit = self.dataIn.type
69 self.dataOut.inputUnit = self.dataIn.type
70
70
71 self.dataOut.timeZone = self.dataIn.timeZone
71 self.dataOut.timeZone = self.dataIn.timeZone
72 self.dataOut.dstFlag = self.dataIn.dstFlag
72 self.dataOut.dstFlag = self.dataIn.dstFlag
73 self.dataOut.errorCount = self.dataIn.errorCount
73 self.dataOut.errorCount = self.dataIn.errorCount
74 self.dataOut.useLocalTime = self.dataIn.useLocalTime
74 self.dataOut.useLocalTime = self.dataIn.useLocalTime
75
75
76 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
76 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
77 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
77 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
78 self.dataOut.channelList = self.dataIn.channelList
78 self.dataOut.channelList = self.dataIn.channelList
79 self.dataOut.heightList = self.dataIn.heightList
79 self.dataOut.heightList = self.dataIn.heightList
80 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
80 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
81 # self.dataOut.nHeights = self.dataIn.nHeights
81 # self.dataOut.nHeights = self.dataIn.nHeights
82 # self.dataOut.nChannels = self.dataIn.nChannels
82 # self.dataOut.nChannels = self.dataIn.nChannels
83 self.dataOut.nBaud = self.dataIn.nBaud
83 self.dataOut.nBaud = self.dataIn.nBaud
84 self.dataOut.nCode = self.dataIn.nCode
84 self.dataOut.nCode = self.dataIn.nCode
85 self.dataOut.code = self.dataIn.code
85 self.dataOut.code = self.dataIn.code
86 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
86 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
87 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
87 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
88 # self.dataOut.utctime = self.firstdatatime
88 # self.dataOut.utctime = self.firstdatatime
89 self.dataOut.utctime = self.dataIn.utctime
89 self.dataOut.utctime = self.dataIn.utctime
90 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
90 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
91 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
91 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
92 self.dataOut.nCohInt = self.dataIn.nCohInt
92 self.dataOut.nCohInt = self.dataIn.nCohInt
93 # self.dataOut.nIncohInt = 1
93 # self.dataOut.nIncohInt = 1
94 self.dataOut.ippSeconds = self.dataIn.ippSeconds
94 self.dataOut.ippSeconds = self.dataIn.ippSeconds
95 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
95 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
96 self.dataOut.timeInterval1 = self.dataIn.timeInterval
96 self.dataOut.timeInterval1 = self.dataIn.timeInterval
97 self.dataOut.heightList = self.dataIn.getHeiRange()
97 self.dataOut.heightList = self.dataIn.getHeiRange()
98 self.dataOut.frequency = self.dataIn.frequency
98 self.dataOut.frequency = self.dataIn.frequency
99 # self.dataOut.noise = self.dataIn.noise
99 # self.dataOut.noise = self.dataIn.noise
100
100
101 def run(self):
101 def run(self):
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 return
112 return
113
113
114 #---------------------- Spectra Data ---------------------------
114 #---------------------- Spectra Data ---------------------------
115
115
116 if self.dataIn.type == "Spectra":
116 if self.dataIn.type == "Spectra":
117
117
118 self.dataOut.data_pre = (self.dataIn.data_spc, self.dataIn.data_cspc)
118 self.dataOut.data_pre = (self.dataIn.data_spc, self.dataIn.data_cspc)
119 self.dataOut.data_spc = self.dataIn.data_spc
119 self.dataOut.data_spc = self.dataIn.data_spc
120 self.dataOut.data_cspc = self.dataIn.data_cspc
120 self.dataOut.data_cspc = self.dataIn.data_cspc
121 self.dataOut.nProfiles = self.dataIn.nProfiles
121 self.dataOut.nProfiles = self.dataIn.nProfiles
122 self.dataOut.nIncohInt = self.dataIn.nIncohInt
122 self.dataOut.nIncohInt = self.dataIn.nIncohInt
123 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
123 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
124 self.dataOut.ippFactor = self.dataIn.ippFactor
124 self.dataOut.ippFactor = self.dataIn.ippFactor
125 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
125 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
126 self.dataOut.spc_noise = self.dataIn.getNoise()
126 self.dataOut.spc_noise = self.dataIn.getNoise()
127 self.dataOut.spc_range = (self.dataIn.getFreqRange(1)/1000. , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
127 self.dataOut.spc_range = (self.dataIn.getFreqRange(1)/1000. , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
128 self.dataOut.pairsList = self.dataIn.pairsList
128 self.dataOut.pairsList = self.dataIn.pairsList
129 self.dataOut.groupList = self.dataIn.pairsList
129 self.dataOut.groupList = self.dataIn.pairsList
130 self.dataOut.flagNoData = False
130 self.dataOut.flagNoData = False
131
131
132 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
132 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
133 self.dataOut.ChanDist = self.dataIn.ChanDist
133 self.dataOut.ChanDist = self.dataIn.ChanDist
134 else: self.dataOut.ChanDist = None
134 else: self.dataOut.ChanDist = None
135
135
136 if hasattr(self.dataIn, 'VelRange'): #Velocities range
136 if hasattr(self.dataIn, 'VelRange'): #Velocities range
137 self.dataOut.VelRange = self.dataIn.VelRange
137 self.dataOut.VelRange = self.dataIn.VelRange
138 else: self.dataOut.VelRange = None
138 else: self.dataOut.VelRange = None
139
139
140 if hasattr(self.dataIn, 'RadarConst'): #Radar Constant
140 if hasattr(self.dataIn, 'RadarConst'): #Radar Constant
141 self.dataOut.RadarConst = self.dataIn.RadarConst
141 self.dataOut.RadarConst = self.dataIn.RadarConst
142
142
143 if hasattr(self.dataIn, 'NPW'): #NPW
143 if hasattr(self.dataIn, 'NPW'): #NPW
144 self.dataOut.NPW = self.dataIn.NPW
144 self.dataOut.NPW = self.dataIn.NPW
145
145
146 if hasattr(self.dataIn, 'COFA'): #COFA
146 if hasattr(self.dataIn, 'COFA'): #COFA
147 self.dataOut.COFA = self.dataIn.COFA
147 self.dataOut.COFA = self.dataIn.COFA
148
148
149
149
150
150
151 #---------------------- Correlation Data ---------------------------
151 #---------------------- Correlation Data ---------------------------
152
152
153 if self.dataIn.type == "Correlation":
153 if self.dataIn.type == "Correlation":
154 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
154 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
155
155
156 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
156 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
157 self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
157 self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
158 self.dataOut.groupList = (acf_pairs, ccf_pairs)
158 self.dataOut.groupList = (acf_pairs, ccf_pairs)
159
159
160 self.dataOut.abscissaList = self.dataIn.lagRange
160 self.dataOut.abscissaList = self.dataIn.lagRange
161 self.dataOut.noise = self.dataIn.noise
161 self.dataOut.noise = self.dataIn.noise
162 self.dataOut.data_SNR = self.dataIn.SNR
162 self.dataOut.data_SNR = self.dataIn.SNR
163 self.dataOut.flagNoData = False
163 self.dataOut.flagNoData = False
164 self.dataOut.nAvg = self.dataIn.nAvg
164 self.dataOut.nAvg = self.dataIn.nAvg
165
165
166 #---------------------- Parameters Data ---------------------------
166 #---------------------- Parameters Data ---------------------------
167
167
168 if self.dataIn.type == "Parameters":
168 if self.dataIn.type == "Parameters":
169 self.dataOut.copy(self.dataIn)
169 self.dataOut.copy(self.dataIn)
170 self.dataOut.flagNoData = False
170 self.dataOut.flagNoData = False
171
171
172 return True
172 return True
173
173
174 self.__updateObjFromInput()
174 self.__updateObjFromInput()
175 self.dataOut.utctimeInit = self.dataIn.utctime
175 self.dataOut.utctimeInit = self.dataIn.utctime
176 self.dataOut.paramInterval = self.dataIn.timeInterval
176 self.dataOut.paramInterval = self.dataIn.timeInterval
177
177
178 return
178 return
179
179
180
180
181 def target(tups):
181 def target(tups):
182
182
183 obj, args = tups
183 obj, args = tups
184 #print 'TARGETTT', obj, args
184 #print 'TARGETTT', obj, args
185 return obj.FitGau(args)
185 return obj.FitGau(args)
186
186
187 class GaussianFit(Operation):
187 class GaussianFit(Operation):
188
188
189 '''
189 '''
190 Function that fit of one and two generalized gaussians (gg) based
190 Function that fit of one and two generalized gaussians (gg) based
191 on the PSD shape across an "power band" identified from a cumsum of
191 on the PSD shape across an "power band" identified from a cumsum of
192 the measured spectrum - noise.
192 the measured spectrum - noise.
193
193
194 Input:
194 Input:
195 self.dataOut.data_pre : SelfSpectra
195 self.dataOut.data_pre : SelfSpectra
196
196
197 Output:
197 Output:
198 self.dataOut.GauSPC : SPC_ch1, SPC_ch2
198 self.dataOut.GauSPC : SPC_ch1, SPC_ch2
199
199
200 '''
200 '''
201 def __init__(self, **kwargs):
201 def __init__(self, **kwargs):
202 Operation.__init__(self, **kwargs)
202 Operation.__init__(self, **kwargs)
203 self.i=0
203 self.i=0
204
204
205
205
206 def run(self, dataOut, num_intg=7, pnoise=1., vel_arr=None, SNRlimit=-9): #num_intg: Incoherent integrations, pnoise: Noise, vel_arr: range of velocities, similar to the ftt points
206 def run(self, dataOut, num_intg=7, pnoise=1., vel_arr=None, SNRlimit=-9): #num_intg: Incoherent integrations, pnoise: Noise, vel_arr: range of velocities, similar to the ftt points
207 """This routine will find a couple of generalized Gaussians to a power spectrum
207 """This routine will find a couple of generalized Gaussians to a power spectrum
208 input: spc
208 input: spc
209 output:
209 output:
210 Amplitude0,shift0,width0,p0,Amplitude1,shift1,width1,p1,noise
210 Amplitude0,shift0,width0,p0,Amplitude1,shift1,width1,p1,noise
211 """
211 """
212
212
213 self.spc = dataOut.data_pre[0].copy()
213 self.spc = dataOut.data_pre[0].copy()
214
214
215
215
216 print 'SelfSpectra Shape', numpy.asarray(self.spc).shape
216 print 'SelfSpectra Shape', numpy.asarray(self.spc).shape
217
217
218
218
219 #plt.figure(50)
219 #plt.figure(50)
220 #plt.subplot(121)
220 #plt.subplot(121)
221 #plt.plot(self.spc,'k',label='spc(66)')
221 #plt.plot(self.spc,'k',label='spc(66)')
222 #plt.plot(xFrec,ySamples[1],'g',label='Ch1')
222 #plt.plot(xFrec,ySamples[1],'g',label='Ch1')
223 #plt.plot(xFrec,ySamples[2],'r',label='Ch2')
223 #plt.plot(xFrec,ySamples[2],'r',label='Ch2')
224 #plt.plot(xFrec,FitGauss,'yo:',label='fit')
224 #plt.plot(xFrec,FitGauss,'yo:',label='fit')
225 #plt.legend()
225 #plt.legend()
226 #plt.title('DATOS A ALTURA DE 7500 METROS')
226 #plt.title('DATOS A ALTURA DE 7500 METROS')
227 #plt.show()
227 #plt.show()
228
228
229 self.Num_Hei = self.spc.shape[2]
229 self.Num_Hei = self.spc.shape[2]
230 #self.Num_Bin = len(self.spc)
230 #self.Num_Bin = len(self.spc)
231 self.Num_Bin = self.spc.shape[1]
231 self.Num_Bin = self.spc.shape[1]
232 self.Num_Chn = self.spc.shape[0]
232 self.Num_Chn = self.spc.shape[0]
233
233
234 Vrange = dataOut.abscissaList
234 Vrange = dataOut.abscissaList
235
235
236 #print 'self.spc2', numpy.asarray(self.spc).shape
236 #print 'self.spc2', numpy.asarray(self.spc).shape
237
237
238 GauSPC = numpy.empty([2,self.Num_Bin,self.Num_Hei])
238 GauSPC = numpy.empty([2,self.Num_Bin,self.Num_Hei])
239 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
239 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
240 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
240 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
241 SPC_ch1[:] = numpy.NaN
241 SPC_ch1[:] = numpy.NaN
242 SPC_ch2[:] = numpy.NaN
242 SPC_ch2[:] = numpy.NaN
243
243
244
244
245 start_time = time.time()
245 start_time = time.time()
246
246
247 noise_ = dataOut.spc_noise[0].copy()
247 noise_ = dataOut.spc_noise[0].copy()
248
248
249
249
250
250
251 pool = Pool(processes=self.Num_Chn)
251 pool = Pool(processes=self.Num_Chn)
252 args = [(Vrange, Ch, pnoise, noise_, num_intg, SNRlimit) for Ch in range(self.Num_Chn)]
252 args = [(Vrange, Ch, pnoise, noise_, num_intg, SNRlimit) for Ch in range(self.Num_Chn)]
253 objs = [self for __ in range(self.Num_Chn)]
253 objs = [self for __ in range(self.Num_Chn)]
254 attrs = zip(objs, args)
254 attrs = zip(objs, args)
255 gauSPC = pool.map(target, attrs)
255 gauSPC = pool.map(target, attrs)
256 dataOut.GauSPC = numpy.asarray(gauSPC)
256 dataOut.GauSPC = numpy.asarray(gauSPC)
257 # ret = []
257 # ret = []
258 # for n in range(self.Num_Chn):
258 # for n in range(self.Num_Chn):
259 # self.FitGau(args[n])
259 # self.FitGau(args[n])
260 # dataOut.GauSPC = ret
260 # dataOut.GauSPC = ret
261
261
262
262
263
263
264 # for ch in range(self.Num_Chn):
264 # for ch in range(self.Num_Chn):
265 #
265 #
266 # for ht in range(self.Num_Hei):
266 # for ht in range(self.Num_Hei):
267 # #print (numpy.asarray(self.spc).shape)
267 # #print (numpy.asarray(self.spc).shape)
268 # spc = numpy.asarray(self.spc)[ch,:,ht]
268 # spc = numpy.asarray(self.spc)[ch,:,ht]
269 #
269 #
270 # #############################################
270 # #############################################
271 # # normalizing spc and noise
271 # # normalizing spc and noise
272 # # This part differs from gg1
272 # # This part differs from gg1
273 # spc_norm_max = max(spc)
273 # spc_norm_max = max(spc)
274 # spc = spc / spc_norm_max
274 # spc = spc / spc_norm_max
275 # pnoise = pnoise / spc_norm_max
275 # pnoise = pnoise / spc_norm_max
276 # #############################################
276 # #############################################
277 #
277 #
278 # if abs(vel_arr[0])<15.0: # this switch is for spectra collected with different length IPP's
278 # if abs(vel_arr[0])<15.0: # this switch is for spectra collected with different length IPP's
279 # fatspectra=1.0
279 # fatspectra=1.0
280 # else:
280 # else:
281 # fatspectra=0.5
281 # fatspectra=0.5
282 #
282 #
283 # wnoise = noise_ / spc_norm_max
283 # wnoise = noise_ / spc_norm_max
284 # #print 'wnoise', noise_, dataOut.spc_noise[0], wnoise
284 # #print 'wnoise', noise_, dataOut.spc_noise[0], wnoise
285 # #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
285 # #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
286 # #if wnoise>1.1*pnoise: # to be tested later
286 # #if wnoise>1.1*pnoise: # to be tested later
287 # # wnoise=pnoise
287 # # wnoise=pnoise
288 # noisebl=wnoise*0.9; noisebh=wnoise*1.1
288 # noisebl=wnoise*0.9; noisebh=wnoise*1.1
289 # spc=spc-wnoise
289 # spc=spc-wnoise
290 #
290 #
291 # minx=numpy.argmin(spc)
291 # minx=numpy.argmin(spc)
292 # spcs=numpy.roll(spc,-minx)
292 # spcs=numpy.roll(spc,-minx)
293 # cum=numpy.cumsum(spcs)
293 # cum=numpy.cumsum(spcs)
294 # tot_noise=wnoise * self.Num_Bin #64;
294 # tot_noise=wnoise * self.Num_Bin #64;
295 # #tot_signal=sum(cum[-5:])/5.; ''' How does this line work? '''
295 # #tot_signal=sum(cum[-5:])/5.; ''' How does this line work? '''
296 # #snr=tot_signal/tot_noise
296 # #snr=tot_signal/tot_noise
297 # #snr=cum[-1]/tot_noise
297 # #snr=cum[-1]/tot_noise
298 #
298 #
299 # #print 'spc' , spcs[5:8] , 'tot_noise', tot_noise
299 # #print 'spc' , spcs[5:8] , 'tot_noise', tot_noise
300 #
300 #
301 # snr = sum(spcs)/tot_noise
301 # snr = sum(spcs)/tot_noise
302 # snrdB=10.*numpy.log10(snr)
302 # snrdB=10.*numpy.log10(snr)
303 #
303 #
304 # #if snrdB < -9 :
304 # #if snrdB < -9 :
305 # # snrdB = numpy.NaN
305 # # snrdB = numpy.NaN
306 # # continue
306 # # continue
307 #
307 #
308 # #print 'snr',snrdB # , sum(spcs) , tot_noise
308 # #print 'snr',snrdB # , sum(spcs) , tot_noise
309 #
309 #
310 #
310 #
311 # #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
311 # #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
312 # # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
312 # # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
313 #
313 #
314 # cummax=max(cum); epsi=0.08*fatspectra # cumsum to narrow down the energy region
314 # cummax=max(cum); epsi=0.08*fatspectra # cumsum to narrow down the energy region
315 # cumlo=cummax*epsi;
315 # cumlo=cummax*epsi;
316 # cumhi=cummax*(1-epsi)
316 # cumhi=cummax*(1-epsi)
317 # powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
317 # powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
318 #
318 #
319 # #if len(powerindex)==1:
319 # #if len(powerindex)==1:
320 # ##return [numpy.mod(powerindex[0]+minx,64),None,None,None,],[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
320 # ##return [numpy.mod(powerindex[0]+minx,64),None,None,None,],[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
321 # #return [numpy.mod(powerindex[0]+minx, self.Num_Bin ),None,None,None,],[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
321 # #return [numpy.mod(powerindex[0]+minx, self.Num_Bin ),None,None,None,],[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
322 # #elif len(powerindex)<4*fatspectra:
322 # #elif len(powerindex)<4*fatspectra:
323 # #return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
323 # #return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
324 #
324 #
325 # if len(powerindex) < 1:# case for powerindex 0
325 # if len(powerindex) < 1:# case for powerindex 0
326 # continue
326 # continue
327 # powerlo=powerindex[0]
327 # powerlo=powerindex[0]
328 # powerhi=powerindex[-1]
328 # powerhi=powerindex[-1]
329 # powerwidth=powerhi-powerlo
329 # powerwidth=powerhi-powerlo
330 #
330 #
331 # firstpeak=powerlo+powerwidth/10.# first gaussian energy location
331 # firstpeak=powerlo+powerwidth/10.# first gaussian energy location
332 # secondpeak=powerhi-powerwidth/10.#second gaussian energy location
332 # secondpeak=powerhi-powerwidth/10.#second gaussian energy location
333 # midpeak=(firstpeak+secondpeak)/2.
333 # midpeak=(firstpeak+secondpeak)/2.
334 # firstamp=spcs[int(firstpeak)]
334 # firstamp=spcs[int(firstpeak)]
335 # secondamp=spcs[int(secondpeak)]
335 # secondamp=spcs[int(secondpeak)]
336 # midamp=spcs[int(midpeak)]
336 # midamp=spcs[int(midpeak)]
337 # #x=numpy.spc.shape[1]
337 # #x=numpy.spc.shape[1]
338 #
338 #
339 # #x=numpy.arange(64)
339 # #x=numpy.arange(64)
340 # x=numpy.arange( self.Num_Bin )
340 # x=numpy.arange( self.Num_Bin )
341 # y_data=spc+wnoise
341 # y_data=spc+wnoise
342 #
342 #
343 # # single gaussian
343 # # single gaussian
344 # #shift0=numpy.mod(midpeak+minx,64)
344 # #shift0=numpy.mod(midpeak+minx,64)
345 # shift0=numpy.mod(midpeak+minx, self.Num_Bin )
345 # shift0=numpy.mod(midpeak+minx, self.Num_Bin )
346 # width0=powerwidth/4.#Initialization entire power of spectrum divided by 4
346 # width0=powerwidth/4.#Initialization entire power of spectrum divided by 4
347 # power0=2.
347 # power0=2.
348 # amplitude0=midamp
348 # amplitude0=midamp
349 # state0=[shift0,width0,amplitude0,power0,wnoise]
349 # state0=[shift0,width0,amplitude0,power0,wnoise]
350 # #bnds=((0,63),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
350 # #bnds=((0,63),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
351 # bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
351 # bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
352 # #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(0.1,0.5))
352 # #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(0.1,0.5))
353 # # bnds = range of fft, power width, amplitude, power, noise
353 # # bnds = range of fft, power width, amplitude, power, noise
354 # lsq1=fmin_l_bfgs_b(self.misfit1,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
354 # lsq1=fmin_l_bfgs_b(self.misfit1,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
355 #
355 #
356 # chiSq1=lsq1[1];
356 # chiSq1=lsq1[1];
357 # jack1= self.y_jacobian1(x,lsq1[0])
357 # jack1= self.y_jacobian1(x,lsq1[0])
358 #
358 #
359 #
359 #
360 # try:
360 # try:
361 # sigmas1=numpy.sqrt(chiSq1*numpy.diag(numpy.linalg.inv(numpy.dot(jack1.T,jack1))))
361 # sigmas1=numpy.sqrt(chiSq1*numpy.diag(numpy.linalg.inv(numpy.dot(jack1.T,jack1))))
362 # except:
362 # except:
363 # std1=32.; sigmas1=numpy.ones(5)
363 # std1=32.; sigmas1=numpy.ones(5)
364 # else:
364 # else:
365 # std1=sigmas1[0]
365 # std1=sigmas1[0]
366 #
366 #
367 #
367 #
368 # if fatspectra<1.0 and powerwidth<4:
368 # if fatspectra<1.0 and powerwidth<4:
369 # choice=0
369 # choice=0
370 # Amplitude0=lsq1[0][2]
370 # Amplitude0=lsq1[0][2]
371 # shift0=lsq1[0][0]
371 # shift0=lsq1[0][0]
372 # width0=lsq1[0][1]
372 # width0=lsq1[0][1]
373 # p0=lsq1[0][3]
373 # p0=lsq1[0][3]
374 # Amplitude1=0.
374 # Amplitude1=0.
375 # shift1=0.
375 # shift1=0.
376 # width1=0.
376 # width1=0.
377 # p1=0.
377 # p1=0.
378 # noise=lsq1[0][4]
378 # noise=lsq1[0][4]
379 # #return (numpy.array([shift0,width0,Amplitude0,p0]),
379 # #return (numpy.array([shift0,width0,Amplitude0,p0]),
380 # # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
380 # # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
381 #
381 #
382 # # two gaussians
382 # # two gaussians
383 # #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
383 # #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
384 # shift0=numpy.mod(firstpeak+minx, self.Num_Bin );
384 # shift0=numpy.mod(firstpeak+minx, self.Num_Bin );
385 # shift1=numpy.mod(secondpeak+minx, self.Num_Bin )
385 # shift1=numpy.mod(secondpeak+minx, self.Num_Bin )
386 # width0=powerwidth/6.;
386 # width0=powerwidth/6.;
387 # width1=width0
387 # width1=width0
388 # power0=2.;
388 # power0=2.;
389 # power1=power0
389 # power1=power0
390 # amplitude0=firstamp;
390 # amplitude0=firstamp;
391 # amplitude1=secondamp
391 # amplitude1=secondamp
392 # state0=[shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
392 # state0=[shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
393 # #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
393 # #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
394 # 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))
394 # 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))
395 # #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))
395 # #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))
396 #
396 #
397 # lsq2=fmin_l_bfgs_b(self.misfit2,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
397 # lsq2=fmin_l_bfgs_b(self.misfit2,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
398 #
398 #
399 #
399 #
400 # chiSq2=lsq2[1]; jack2=self.y_jacobian2(x,lsq2[0])
400 # chiSq2=lsq2[1]; jack2=self.y_jacobian2(x,lsq2[0])
401 #
401 #
402 #
402 #
403 # try:
403 # try:
404 # sigmas2=numpy.sqrt(chiSq2*numpy.diag(numpy.linalg.inv(numpy.dot(jack2.T,jack2))))
404 # sigmas2=numpy.sqrt(chiSq2*numpy.diag(numpy.linalg.inv(numpy.dot(jack2.T,jack2))))
405 # except:
405 # except:
406 # std2a=32.; std2b=32.; sigmas2=numpy.ones(9)
406 # std2a=32.; std2b=32.; sigmas2=numpy.ones(9)
407 # else:
407 # else:
408 # std2a=sigmas2[0]; std2b=sigmas2[4]
408 # std2a=sigmas2[0]; std2b=sigmas2[4]
409 #
409 #
410 #
410 #
411 #
411 #
412 # 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)
412 # 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)
413 #
413 #
414 # if snrdB>-9: # when SNR is strong pick the peak with least shift (LOS velocity) error
414 # if snrdB>-9: # when SNR is strong pick the peak with least shift (LOS velocity) error
415 # if oneG:
415 # if oneG:
416 # choice=0
416 # choice=0
417 # else:
417 # else:
418 # w1=lsq2[0][1]; w2=lsq2[0][5]
418 # w1=lsq2[0][1]; w2=lsq2[0][5]
419 # a1=lsq2[0][2]; a2=lsq2[0][6]
419 # a1=lsq2[0][2]; a2=lsq2[0][6]
420 # p1=lsq2[0][3]; p2=lsq2[0][7]
420 # p1=lsq2[0][3]; p2=lsq2[0][7]
421 # s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1; s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2;
421 # s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1; s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2;
422 # gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling
422 # gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling
423 #
423 #
424 # if gp1>gp2:
424 # if gp1>gp2:
425 # if a1>0.7*a2:
425 # if a1>0.7*a2:
426 # choice=1
426 # choice=1
427 # else:
427 # else:
428 # choice=2
428 # choice=2
429 # elif gp2>gp1:
429 # elif gp2>gp1:
430 # if a2>0.7*a1:
430 # if a2>0.7*a1:
431 # choice=2
431 # choice=2
432 # else:
432 # else:
433 # choice=1
433 # choice=1
434 # else:
434 # else:
435 # choice=numpy.argmax([a1,a2])+1
435 # choice=numpy.argmax([a1,a2])+1
436 # #else:
436 # #else:
437 # #choice=argmin([std2a,std2b])+1
437 # #choice=argmin([std2a,std2b])+1
438 #
438 #
439 # else: # with low SNR go to the most energetic peak
439 # else: # with low SNR go to the most energetic peak
440 # choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
440 # choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
441 #
441 #
442 # #print 'choice',choice
442 # #print 'choice',choice
443 #
443 #
444 # if choice==0: # pick the single gaussian fit
444 # if choice==0: # pick the single gaussian fit
445 # Amplitude0=lsq1[0][2]
445 # Amplitude0=lsq1[0][2]
446 # shift0=lsq1[0][0]
446 # shift0=lsq1[0][0]
447 # width0=lsq1[0][1]
447 # width0=lsq1[0][1]
448 # p0=lsq1[0][3]
448 # p0=lsq1[0][3]
449 # Amplitude1=0.
449 # Amplitude1=0.
450 # shift1=0.
450 # shift1=0.
451 # width1=0.
451 # width1=0.
452 # p1=0.
452 # p1=0.
453 # noise=lsq1[0][4]
453 # noise=lsq1[0][4]
454 # elif choice==1: # take the first one of the 2 gaussians fitted
454 # elif choice==1: # take the first one of the 2 gaussians fitted
455 # Amplitude0 = lsq2[0][2]
455 # Amplitude0 = lsq2[0][2]
456 # shift0 = lsq2[0][0]
456 # shift0 = lsq2[0][0]
457 # width0 = lsq2[0][1]
457 # width0 = lsq2[0][1]
458 # p0 = lsq2[0][3]
458 # p0 = lsq2[0][3]
459 # Amplitude1 = lsq2[0][6] # This is 0 in gg1
459 # Amplitude1 = lsq2[0][6] # This is 0 in gg1
460 # shift1 = lsq2[0][4] # This is 0 in gg1
460 # shift1 = lsq2[0][4] # This is 0 in gg1
461 # width1 = lsq2[0][5] # This is 0 in gg1
461 # width1 = lsq2[0][5] # This is 0 in gg1
462 # p1 = lsq2[0][7] # This is 0 in gg1
462 # p1 = lsq2[0][7] # This is 0 in gg1
463 # noise = lsq2[0][8]
463 # noise = lsq2[0][8]
464 # else: # the second one
464 # else: # the second one
465 # Amplitude0 = lsq2[0][6]
465 # Amplitude0 = lsq2[0][6]
466 # shift0 = lsq2[0][4]
466 # shift0 = lsq2[0][4]
467 # width0 = lsq2[0][5]
467 # width0 = lsq2[0][5]
468 # p0 = lsq2[0][7]
468 # p0 = lsq2[0][7]
469 # Amplitude1 = lsq2[0][2] # This is 0 in gg1
469 # Amplitude1 = lsq2[0][2] # This is 0 in gg1
470 # shift1 = lsq2[0][0] # This is 0 in gg1
470 # shift1 = lsq2[0][0] # This is 0 in gg1
471 # width1 = lsq2[0][1] # This is 0 in gg1
471 # width1 = lsq2[0][1] # This is 0 in gg1
472 # p1 = lsq2[0][3] # This is 0 in gg1
472 # p1 = lsq2[0][3] # This is 0 in gg1
473 # noise = lsq2[0][8]
473 # noise = lsq2[0][8]
474 #
474 #
475 # #print len(noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0)
475 # #print len(noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0)
476 # SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0
476 # SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0
477 # SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1
477 # SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1
478 # #print 'SPC_ch1.shape',SPC_ch1.shape
478 # #print 'SPC_ch1.shape',SPC_ch1.shape
479 # #print 'SPC_ch2.shape',SPC_ch2.shape
479 # #print 'SPC_ch2.shape',SPC_ch2.shape
480 # #dataOut.data_param = SPC_ch1
480 # #dataOut.data_param = SPC_ch1
481 # GauSPC[0] = SPC_ch1
481 # GauSPC[0] = SPC_ch1
482 # GauSPC[1] = SPC_ch2
482 # GauSPC[1] = SPC_ch2
483
483
484 # #plt.gcf().clear()
484 # #plt.gcf().clear()
485 # plt.figure(50+self.i)
485 # plt.figure(50+self.i)
486 # self.i=self.i+1
486 # self.i=self.i+1
487 # #plt.subplot(121)
487 # #plt.subplot(121)
488 # plt.plot(self.spc,'k')#,label='spc(66)')
488 # plt.plot(self.spc,'k')#,label='spc(66)')
489 # plt.plot(SPC_ch1[ch,ht],'b')#,label='gg1')
489 # plt.plot(SPC_ch1[ch,ht],'b')#,label='gg1')
490 # #plt.plot(SPC_ch2,'r')#,label='gg2')
490 # #plt.plot(SPC_ch2,'r')#,label='gg2')
491 # #plt.plot(xFrec,ySamples[1],'g',label='Ch1')
491 # #plt.plot(xFrec,ySamples[1],'g',label='Ch1')
492 # #plt.plot(xFrec,ySamples[2],'r',label='Ch2')
492 # #plt.plot(xFrec,ySamples[2],'r',label='Ch2')
493 # #plt.plot(xFrec,FitGauss,'yo:',label='fit')
493 # #plt.plot(xFrec,FitGauss,'yo:',label='fit')
494 # plt.legend()
494 # plt.legend()
495 # plt.title('DATOS A ALTURA DE 7500 METROS')
495 # plt.title('DATOS A ALTURA DE 7500 METROS')
496 # plt.show()
496 # plt.show()
497 # print 'shift0', shift0
497 # print 'shift0', shift0
498 # print 'Amplitude0', Amplitude0
498 # print 'Amplitude0', Amplitude0
499 # print 'width0', width0
499 # print 'width0', width0
500 # print 'p0', p0
500 # print 'p0', p0
501 # print '========================'
501 # print '========================'
502 # print 'shift1', shift1
502 # print 'shift1', shift1
503 # print 'Amplitude1', Amplitude1
503 # print 'Amplitude1', Amplitude1
504 # print 'width1', width1
504 # print 'width1', width1
505 # print 'p1', p1
505 # print 'p1', p1
506 # print 'noise', noise
506 # print 'noise', noise
507 # print 's_noise', wnoise
507 # print 's_noise', wnoise
508
508
509 print '========================================================'
509 print '========================================================'
510 print 'total_time: ', time.time()-start_time
510 print 'total_time: ', time.time()-start_time
511
511
512 # re-normalizing spc and noise
512 # re-normalizing spc and noise
513 # This part differs from gg1
513 # This part differs from gg1
514
514
515
515
516
516
517 ''' Parameters:
517 ''' Parameters:
518 1. Amplitude
518 1. Amplitude
519 2. Shift
519 2. Shift
520 3. Width
520 3. Width
521 4. Power
521 4. Power
522 '''
522 '''
523
523
524
524
525 ###############################################################################
525 ###############################################################################
526 def FitGau(self, X):
526 def FitGau(self, X):
527
527
528 Vrange, ch, pnoise, noise_, num_intg, SNRlimit = X
528 Vrange, ch, pnoise, noise_, num_intg, SNRlimit = X
529 #print 'VARSSSS', ch, pnoise, noise, num_intg
529 #print 'VARSSSS', ch, pnoise, noise, num_intg
530
530
531 #print 'HEIGHTS', self.Num_Hei
531 #print 'HEIGHTS', self.Num_Hei
532
532
533 GauSPC = []
533 GauSPC = []
534 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
534 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
535 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
535 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
536 SPC_ch1[:] = 0#numpy.NaN
536 SPC_ch1[:] = 0#numpy.NaN
537 SPC_ch2[:] = 0#numpy.NaN
537 SPC_ch2[:] = 0#numpy.NaN
538
538
539
539
540
540
541 for ht in range(self.Num_Hei):
541 for ht in range(self.Num_Hei):
542 #print (numpy.asarray(self.spc).shape)
542 #print (numpy.asarray(self.spc).shape)
543
543
544 #print 'TTTTT', ch , ht
544 #print 'TTTTT', ch , ht
545 #print self.spc.shape
545 #print self.spc.shape
546
546
547
547
548 spc = numpy.asarray(self.spc)[ch,:,ht]
548 spc = numpy.asarray(self.spc)[ch,:,ht]
549
549
550 #############################################
550 #############################################
551 # normalizing spc and noise
551 # normalizing spc and noise
552 # This part differs from gg1
552 # This part differs from gg1
553 spc_norm_max = max(spc)
553 spc_norm_max = max(spc)
554 spc = spc / spc_norm_max
554 spc = spc / spc_norm_max
555 pnoise = pnoise / spc_norm_max
555 pnoise = pnoise / spc_norm_max
556 #############################################
556 #############################################
557
557
558 fatspectra=1.0
558 fatspectra=1.0
559
559
560 wnoise = noise_ / spc_norm_max
560 wnoise = noise_ / spc_norm_max
561 #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
561 #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
562 #if wnoise>1.1*pnoise: # to be tested later
562 #if wnoise>1.1*pnoise: # to be tested later
563 # wnoise=pnoise
563 # wnoise=pnoise
564 noisebl=wnoise*0.9; noisebh=wnoise*1.1
564 noisebl=wnoise*0.9; noisebh=wnoise*1.1
565 spc=spc-wnoise
565 spc=spc-wnoise
566 # print 'wnoise', noise_[0], spc_norm_max, wnoise
566 # print 'wnoise', noise_[0], spc_norm_max, wnoise
567 minx=numpy.argmin(spc)
567 minx=numpy.argmin(spc)
568 spcs=numpy.roll(spc,-minx)
568 spcs=numpy.roll(spc,-minx)
569 cum=numpy.cumsum(spcs)
569 cum=numpy.cumsum(spcs)
570 tot_noise=wnoise * self.Num_Bin #64;
570 tot_noise=wnoise * self.Num_Bin #64;
571 #print 'spc' , spcs[5:8] , 'tot_noise', tot_noise
571 #print 'spc' , spcs[5:8] , 'tot_noise', tot_noise
572 #tot_signal=sum(cum[-5:])/5.; ''' How does this line work? '''
572 #tot_signal=sum(cum[-5:])/5.; ''' How does this line work? '''
573 #snr=tot_signal/tot_noise
573 #snr=tot_signal/tot_noise
574 #snr=cum[-1]/tot_noise
574 #snr=cum[-1]/tot_noise
575 snr = sum(spcs)/tot_noise
575 snr = sum(spcs)/tot_noise
576 snrdB=10.*numpy.log10(snr)
576 snrdB=10.*numpy.log10(snr)
577
577
578 if snrdB < SNRlimit :
578 if snrdB < SNRlimit :
579 snr = numpy.NaN
579 snr = numpy.NaN
580 SPC_ch1[:,ht] = 0#numpy.NaN
580 SPC_ch1[:,ht] = 0#numpy.NaN
581 SPC_ch1[:,ht] = 0#numpy.NaN
581 SPC_ch1[:,ht] = 0#numpy.NaN
582 GauSPC = (SPC_ch1,SPC_ch2)
582 GauSPC = (SPC_ch1,SPC_ch2)
583 continue
583 continue
584 #print 'snr',snrdB #, sum(spcs) , tot_noise
584 #print 'snr',snrdB #, sum(spcs) , tot_noise
585
585
586
586
587
587
588 #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
588 #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
589 # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
589 # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
590
590
591 cummax=max(cum); epsi=0.08*fatspectra # cumsum to narrow down the energy region
591 cummax=max(cum); epsi=0.08*fatspectra # cumsum to narrow down the energy region
592 cumlo=cummax*epsi;
592 cumlo=cummax*epsi;
593 cumhi=cummax*(1-epsi)
593 cumhi=cummax*(1-epsi)
594 powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
594 powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
595
595
596
596
597 if len(powerindex) < 1:# case for powerindex 0
597 if len(powerindex) < 1:# case for powerindex 0
598 continue
598 continue
599 powerlo=powerindex[0]
599 powerlo=powerindex[0]
600 powerhi=powerindex[-1]
600 powerhi=powerindex[-1]
601 powerwidth=powerhi-powerlo
601 powerwidth=powerhi-powerlo
602
602
603 firstpeak=powerlo+powerwidth/10.# first gaussian energy location
603 firstpeak=powerlo+powerwidth/10.# first gaussian energy location
604 secondpeak=powerhi-powerwidth/10.#second gaussian energy location
604 secondpeak=powerhi-powerwidth/10.#second gaussian energy location
605 midpeak=(firstpeak+secondpeak)/2.
605 midpeak=(firstpeak+secondpeak)/2.
606 firstamp=spcs[int(firstpeak)]
606 firstamp=spcs[int(firstpeak)]
607 secondamp=spcs[int(secondpeak)]
607 secondamp=spcs[int(secondpeak)]
608 midamp=spcs[int(midpeak)]
608 midamp=spcs[int(midpeak)]
609
609
610 x=numpy.arange( self.Num_Bin )
610 x=numpy.arange( self.Num_Bin )
611 y_data=spc+wnoise
611 y_data=spc+wnoise
612
612
613 # single gaussian
613 # single gaussian
614 shift0=numpy.mod(midpeak+minx, self.Num_Bin )
614 shift0=numpy.mod(midpeak+minx, self.Num_Bin )
615 width0=powerwidth/4.#Initialization entire power of spectrum divided by 4
615 width0=powerwidth/4.#Initialization entire power of spectrum divided by 4
616 power0=2.
616 power0=2.
617 amplitude0=midamp
617 amplitude0=midamp
618 state0=[shift0,width0,amplitude0,power0,wnoise]
618 state0=[shift0,width0,amplitude0,power0,wnoise]
619 bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
619 bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
620 lsq1=fmin_l_bfgs_b(self.misfit1,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
620 lsq1=fmin_l_bfgs_b(self.misfit1,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
621
621
622 chiSq1=lsq1[1];
622 chiSq1=lsq1[1];
623 jack1= self.y_jacobian1(x,lsq1[0])
623 jack1= self.y_jacobian1(x,lsq1[0])
624
624
625
625
626 try:
626 try:
627 sigmas1=numpy.sqrt(chiSq1*numpy.diag(numpy.linalg.inv(numpy.dot(jack1.T,jack1))))
627 sigmas1=numpy.sqrt(chiSq1*numpy.diag(numpy.linalg.inv(numpy.dot(jack1.T,jack1))))
628 except:
628 except:
629 std1=32.; sigmas1=numpy.ones(5)
629 std1=32.; sigmas1=numpy.ones(5)
630 else:
630 else:
631 std1=sigmas1[0]
631 std1=sigmas1[0]
632
632
633
633
634 if fatspectra<1.0 and powerwidth<4:
634 if fatspectra<1.0 and powerwidth<4:
635 choice=0
635 choice=0
636 Amplitude0=lsq1[0][2]
636 Amplitude0=lsq1[0][2]
637 shift0=lsq1[0][0]
637 shift0=lsq1[0][0]
638 width0=lsq1[0][1]
638 width0=lsq1[0][1]
639 p0=lsq1[0][3]
639 p0=lsq1[0][3]
640 Amplitude1=0.
640 Amplitude1=0.
641 shift1=0.
641 shift1=0.
642 width1=0.
642 width1=0.
643 p1=0.
643 p1=0.
644 noise=lsq1[0][4]
644 noise=lsq1[0][4]
645 #return (numpy.array([shift0,width0,Amplitude0,p0]),
645 #return (numpy.array([shift0,width0,Amplitude0,p0]),
646 # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
646 # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
647
647
648 # two gaussians
648 # two gaussians
649 #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
649 #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
650 shift0=numpy.mod(firstpeak+minx, self.Num_Bin );
650 shift0=numpy.mod(firstpeak+minx, self.Num_Bin );
651 shift1=numpy.mod(secondpeak+minx, self.Num_Bin )
651 shift1=numpy.mod(secondpeak+minx, self.Num_Bin )
652 width0=powerwidth/6.;
652 width0=powerwidth/6.;
653 width1=width0
653 width1=width0
654 power0=2.;
654 power0=2.;
655 power1=power0
655 power1=power0
656 amplitude0=firstamp;
656 amplitude0=firstamp;
657 amplitude1=secondamp
657 amplitude1=secondamp
658 state0=[shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
658 state0=[shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
659 #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
659 #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
660 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))
660 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))
661 #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))
661 #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))
662
662
663 lsq2=fmin_l_bfgs_b(self.misfit2,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
663 lsq2=fmin_l_bfgs_b(self.misfit2,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
664
664
665
665
666 chiSq2=lsq2[1]; jack2=self.y_jacobian2(x,lsq2[0])
666 chiSq2=lsq2[1]; jack2=self.y_jacobian2(x,lsq2[0])
667
667
668
668
669 try:
669 try:
670 sigmas2=numpy.sqrt(chiSq2*numpy.diag(numpy.linalg.inv(numpy.dot(jack2.T,jack2))))
670 sigmas2=numpy.sqrt(chiSq2*numpy.diag(numpy.linalg.inv(numpy.dot(jack2.T,jack2))))
671 except:
671 except:
672 std2a=32.; std2b=32.; sigmas2=numpy.ones(9)
672 std2a=32.; std2b=32.; sigmas2=numpy.ones(9)
673 else:
673 else:
674 std2a=sigmas2[0]; std2b=sigmas2[4]
674 std2a=sigmas2[0]; std2b=sigmas2[4]
675
675
676
676
677
677
678 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)
678 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)
679
679
680 if snrdB>-6: # when SNR is strong pick the peak with least shift (LOS velocity) error
680 if snrdB>-6: # when SNR is strong pick the peak with least shift (LOS velocity) error
681 if oneG:
681 if oneG:
682 choice=0
682 choice=0
683 else:
683 else:
684 w1=lsq2[0][1]; w2=lsq2[0][5]
684 w1=lsq2[0][1]; w2=lsq2[0][5]
685 a1=lsq2[0][2]; a2=lsq2[0][6]
685 a1=lsq2[0][2]; a2=lsq2[0][6]
686 p1=lsq2[0][3]; p2=lsq2[0][7]
686 p1=lsq2[0][3]; p2=lsq2[0][7]
687 s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1;
687 s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1;
688 s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2;
688 s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2;
689 gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling
689 gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling
690
690
691 if gp1>gp2:
691 if gp1>gp2:
692 if a1>0.7*a2:
692 if a1>0.7*a2:
693 choice=1
693 choice=1
694 else:
694 else:
695 choice=2
695 choice=2
696 elif gp2>gp1:
696 elif gp2>gp1:
697 if a2>0.7*a1:
697 if a2>0.7*a1:
698 choice=2
698 choice=2
699 else:
699 else:
700 choice=1
700 choice=1
701 else:
701 else:
702 choice=numpy.argmax([a1,a2])+1
702 choice=numpy.argmax([a1,a2])+1
703 #else:
703 #else:
704 #choice=argmin([std2a,std2b])+1
704 #choice=argmin([std2a,std2b])+1
705
705
706 else: # with low SNR go to the most energetic peak
706 else: # with low SNR go to the most energetic peak
707 choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
707 choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
708
708
709
709
710 shift0=lsq2[0][0]; vel0=Vrange[0] + shift0*(Vrange[1]-Vrange[0])
710 shift0=lsq2[0][0]; vel0=Vrange[0] + shift0*(Vrange[1]-Vrange[0])
711 shift1=lsq2[0][4]; vel1=Vrange[0] + shift1*(Vrange[1]-Vrange[0])
711 shift1=lsq2[0][4]; vel1=Vrange[0] + shift1*(Vrange[1]-Vrange[0])
712
712
713 max_vel = 20
713 max_vel = 20
714
714
715 #first peak will be 0, second peak will be 1
715 #first peak will be 0, second peak will be 1
716 if vel0 > 0 and vel0 < max_vel : #first peak is in the correct range
716 if vel0 > 0 and vel0 < max_vel : #first peak is in the correct range
717 shift0=lsq2[0][0]
717 shift0=lsq2[0][0]
718 width0=lsq2[0][1]
718 width0=lsq2[0][1]
719 Amplitude0=lsq2[0][2]
719 Amplitude0=lsq2[0][2]
720 p0=lsq2[0][3]
720 p0=lsq2[0][3]
721
721
722 shift1=lsq2[0][4]
722 shift1=lsq2[0][4]
723 width1=lsq2[0][5]
723 width1=lsq2[0][5]
724 Amplitude1=lsq2[0][6]
724 Amplitude1=lsq2[0][6]
725 p1=lsq2[0][7]
725 p1=lsq2[0][7]
726 noise=lsq2[0][8]
726 noise=lsq2[0][8]
727 else:
727 else:
728 shift1=lsq2[0][0]
728 shift1=lsq2[0][0]
729 width1=lsq2[0][1]
729 width1=lsq2[0][1]
730 Amplitude1=lsq2[0][2]
730 Amplitude1=lsq2[0][2]
731 p1=lsq2[0][3]
731 p1=lsq2[0][3]
732
732
733 shift0=lsq2[0][4]
733 shift0=lsq2[0][4]
734 width0=lsq2[0][5]
734 width0=lsq2[0][5]
735 Amplitude0=lsq2[0][6]
735 Amplitude0=lsq2[0][6]
736 p0=lsq2[0][7]
736 p0=lsq2[0][7]
737 noise=lsq2[0][8]
737 noise=lsq2[0][8]
738
738
739 if Amplitude0<0.1: # in case the peak is noise
739 if Amplitude0<0.1: # in case the peak is noise
740 shift0,width0,Amplitude0,p0 = 4*[numpy.NaN]
740 shift0,width0,Amplitude0,p0 = 4*[numpy.NaN]
741 if Amplitude1<0.1:
741 if Amplitude1<0.1:
742 shift1,width1,Amplitude1,p1 = 4*[numpy.NaN]
742 shift1,width1,Amplitude1,p1 = 4*[numpy.NaN]
743
743
744
744
745 # if choice==0: # pick the single gaussian fit
745 # if choice==0: # pick the single gaussian fit
746 # Amplitude0=lsq1[0][2]
746 # Amplitude0=lsq1[0][2]
747 # shift0=lsq1[0][0]
747 # shift0=lsq1[0][0]
748 # width0=lsq1[0][1]
748 # width0=lsq1[0][1]
749 # p0=lsq1[0][3]
749 # p0=lsq1[0][3]
750 # Amplitude1=0.
750 # Amplitude1=0.
751 # shift1=0.
751 # shift1=0.
752 # width1=0.
752 # width1=0.
753 # p1=0.
753 # p1=0.
754 # noise=lsq1[0][4]
754 # noise=lsq1[0][4]
755 # elif choice==1: # take the first one of the 2 gaussians fitted
755 # elif choice==1: # take the first one of the 2 gaussians fitted
756 # Amplitude0 = lsq2[0][2]
756 # Amplitude0 = lsq2[0][2]
757 # shift0 = lsq2[0][0]
757 # shift0 = lsq2[0][0]
758 # width0 = lsq2[0][1]
758 # width0 = lsq2[0][1]
759 # p0 = lsq2[0][3]
759 # p0 = lsq2[0][3]
760 # Amplitude1 = lsq2[0][6] # This is 0 in gg1
760 # Amplitude1 = lsq2[0][6] # This is 0 in gg1
761 # shift1 = lsq2[0][4] # This is 0 in gg1
761 # shift1 = lsq2[0][4] # This is 0 in gg1
762 # width1 = lsq2[0][5] # This is 0 in gg1
762 # width1 = lsq2[0][5] # This is 0 in gg1
763 # p1 = lsq2[0][7] # This is 0 in gg1
763 # p1 = lsq2[0][7] # This is 0 in gg1
764 # noise = lsq2[0][8]
764 # noise = lsq2[0][8]
765 # else: # the second one
765 # else: # the second one
766 # Amplitude0 = lsq2[0][6]
766 # Amplitude0 = lsq2[0][6]
767 # shift0 = lsq2[0][4]
767 # shift0 = lsq2[0][4]
768 # width0 = lsq2[0][5]
768 # width0 = lsq2[0][5]
769 # p0 = lsq2[0][7]
769 # p0 = lsq2[0][7]
770 # Amplitude1 = lsq2[0][2] # This is 0 in gg1
770 # Amplitude1 = lsq2[0][2] # This is 0 in gg1
771 # shift1 = lsq2[0][0] # This is 0 in gg1
771 # shift1 = lsq2[0][0] # This is 0 in gg1
772 # width1 = lsq2[0][1] # This is 0 in gg1
772 # width1 = lsq2[0][1] # This is 0 in gg1
773 # p1 = lsq2[0][3] # This is 0 in gg1
773 # p1 = lsq2[0][3] # This is 0 in gg1
774 # noise = lsq2[0][8]
774 # noise = lsq2[0][8]
775
775
776 #print len(noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0)
776 #print len(noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0)
777 SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0
777 SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0
778 SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1
778 SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1
779 #print 'SPC_ch1.shape',SPC_ch1.shape
779 #print 'SPC_ch1.shape',SPC_ch1.shape
780 #print 'SPC_ch2.shape',SPC_ch2.shape
780 #print 'SPC_ch2.shape',SPC_ch2.shape
781 #dataOut.data_param = SPC_ch1
781 #dataOut.data_param = SPC_ch1
782 GauSPC = (SPC_ch1,SPC_ch2)
782 GauSPC = (SPC_ch1,SPC_ch2)
783 #GauSPC[1] = SPC_ch2
783 #GauSPC[1] = SPC_ch2
784
784
785 # print 'shift0', shift0
785 # print 'shift0', shift0
786 # print 'Amplitude0', Amplitude0
786 # print 'Amplitude0', Amplitude0
787 # print 'width0', width0
787 # print 'width0', width0
788 # print 'p0', p0
788 # print 'p0', p0
789 # print '========================'
789 # print '========================'
790 # print 'shift1', shift1
790 # print 'shift1', shift1
791 # print 'Amplitude1', Amplitude1
791 # print 'Amplitude1', Amplitude1
792 # print 'width1', width1
792 # print 'width1', width1
793 # print 'p1', p1
793 # print 'p1', p1
794 # print 'noise', noise
794 # print 'noise', noise
795 # print 's_noise', wnoise
795 # print 's_noise', wnoise
796
796
797 return GauSPC
797 return GauSPC
798
798
799
799
800 def y_jacobian1(self,x,state): # This function is for further analysis of generalized Gaussians, it is not too importan for the signal discrimination.
800 def y_jacobian1(self,x,state): # This function is for further analysis of generalized Gaussians, it is not too importan for the signal discrimination.
801 y_model=self.y_model1(x,state)
801 y_model=self.y_model1(x,state)
802 s0,w0,a0,p0,n=state
802 s0,w0,a0,p0,n=state
803 e0=((x-s0)/w0)**2;
803 e0=((x-s0)/w0)**2;
804
804
805 e0u=((x-s0-self.Num_Bin)/w0)**2;
805 e0u=((x-s0-self.Num_Bin)/w0)**2;
806
806
807 e0d=((x-s0+self.Num_Bin)/w0)**2
807 e0d=((x-s0+self.Num_Bin)/w0)**2
808 m0=numpy.exp(-0.5*e0**(p0/2.));
808 m0=numpy.exp(-0.5*e0**(p0/2.));
809 m0u=numpy.exp(-0.5*e0u**(p0/2.));
809 m0u=numpy.exp(-0.5*e0u**(p0/2.));
810 m0d=numpy.exp(-0.5*e0d**(p0/2.))
810 m0d=numpy.exp(-0.5*e0d**(p0/2.))
811 JA=m0+m0u+m0d
811 JA=m0+m0u+m0d
812 JP=(-1/4.)*a0*m0*e0**(p0/2.)*numpy.log(e0)+(-1/4.)*a0*m0u*e0u**(p0/2.)*numpy.log(e0u)+(-1/4.)*a0*m0d*e0d**(p0/2.)*numpy.log(e0d)
812 JP=(-1/4.)*a0*m0*e0**(p0/2.)*numpy.log(e0)+(-1/4.)*a0*m0u*e0u**(p0/2.)*numpy.log(e0u)+(-1/4.)*a0*m0d*e0d**(p0/2.)*numpy.log(e0d)
813
813
814 JS=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)
814 JS=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)
815
815
816 JW=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)**2+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)**2+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)**2
816 JW=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)**2+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)**2+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)**2
817 jack1=numpy.sqrt(7)*numpy.array([JS/y_model,JW/y_model,JA/y_model,JP/y_model,1./y_model])
817 jack1=numpy.sqrt(7)*numpy.array([JS/y_model,JW/y_model,JA/y_model,JP/y_model,1./y_model])
818 return jack1.T
818 return jack1.T
819
819
820 def y_jacobian2(self,x,state):
820 def y_jacobian2(self,x,state):
821 y_model=self.y_model2(x,state)
821 y_model=self.y_model2(x,state)
822 s0,w0,a0,p0,s1,w1,a1,p1,n=state
822 s0,w0,a0,p0,s1,w1,a1,p1,n=state
823 e0=((x-s0)/w0)**2;
823 e0=((x-s0)/w0)**2;
824
824
825 e0u=((x-s0- self.Num_Bin )/w0)**2;
825 e0u=((x-s0- self.Num_Bin )/w0)**2;
826
826
827 e0d=((x-s0+ self.Num_Bin )/w0)**2
827 e0d=((x-s0+ self.Num_Bin )/w0)**2
828 e1=((x-s1)/w1)**2;
828 e1=((x-s1)/w1)**2;
829
829
830 e1u=((x-s1- self.Num_Bin )/w1)**2;
830 e1u=((x-s1- self.Num_Bin )/w1)**2;
831
831
832 e1d=((x-s1+ self.Num_Bin )/w1)**2
832 e1d=((x-s1+ self.Num_Bin )/w1)**2
833 m0=numpy.exp(-0.5*e0**(p0/2.));
833 m0=numpy.exp(-0.5*e0**(p0/2.));
834 m0u=numpy.exp(-0.5*e0u**(p0/2.));
834 m0u=numpy.exp(-0.5*e0u**(p0/2.));
835 m0d=numpy.exp(-0.5*e0d**(p0/2.))
835 m0d=numpy.exp(-0.5*e0d**(p0/2.))
836 m1=numpy.exp(-0.5*e1**(p1/2.));
836 m1=numpy.exp(-0.5*e1**(p1/2.));
837 m1u=numpy.exp(-0.5*e1u**(p1/2.));
837 m1u=numpy.exp(-0.5*e1u**(p1/2.));
838 m1d=numpy.exp(-0.5*e1d**(p1/2.))
838 m1d=numpy.exp(-0.5*e1d**(p1/2.))
839 JA=m0+m0u+m0d
839 JA=m0+m0u+m0d
840 JA1=m1+m1u+m1d
840 JA1=m1+m1u+m1d
841 JP=(-1/4.)*a0*m0*e0**(p0/2.)*numpy.log(e0)+(-1/4.)*a0*m0u*e0u**(p0/2.)*numpy.log(e0u)+(-1/4.)*a0*m0d*e0d**(p0/2.)*numpy.log(e0d)
841 JP=(-1/4.)*a0*m0*e0**(p0/2.)*numpy.log(e0)+(-1/4.)*a0*m0u*e0u**(p0/2.)*numpy.log(e0u)+(-1/4.)*a0*m0d*e0d**(p0/2.)*numpy.log(e0d)
842 JP1=(-1/4.)*a1*m1*e1**(p1/2.)*numpy.log(e1)+(-1/4.)*a1*m1u*e1u**(p1/2.)*numpy.log(e1u)+(-1/4.)*a1*m1d*e1d**(p1/2.)*numpy.log(e1d)
842 JP1=(-1/4.)*a1*m1*e1**(p1/2.)*numpy.log(e1)+(-1/4.)*a1*m1u*e1u**(p1/2.)*numpy.log(e1u)+(-1/4.)*a1*m1d*e1d**(p1/2.)*numpy.log(e1d)
843
843
844 JS=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)
844 JS=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)
845
845
846 JS1=(p1/w1/2.)*a1*m1*e1**(p1/2.-1)*((x-s1)/w1)+(p1/w1/2.)*a1*m1u*e1u**(p1/2.-1)*((x-s1- self.Num_Bin )/w1)+(p1/w1/2.)*a1*m1d*e1d**(p1/2.-1)*((x-s1+ self.Num_Bin )/w1)
846 JS1=(p1/w1/2.)*a1*m1*e1**(p1/2.-1)*((x-s1)/w1)+(p1/w1/2.)*a1*m1u*e1u**(p1/2.-1)*((x-s1- self.Num_Bin )/w1)+(p1/w1/2.)*a1*m1d*e1d**(p1/2.-1)*((x-s1+ self.Num_Bin )/w1)
847
847
848 JW=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)**2+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)**2+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)**2
848 JW=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)**2+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)**2+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)**2
849
849
850 JW1=(p1/w1/2.)*a1*m1*e1**(p1/2.-1)*((x-s1)/w1)**2+(p1/w1/2.)*a1*m1u*e1u**(p1/2.-1)*((x-s1- self.Num_Bin )/w1)**2+(p1/w1/2.)*a1*m1d*e1d**(p1/2.-1)*((x-s1+ self.Num_Bin )/w1)**2
850 JW1=(p1/w1/2.)*a1*m1*e1**(p1/2.-1)*((x-s1)/w1)**2+(p1/w1/2.)*a1*m1u*e1u**(p1/2.-1)*((x-s1- self.Num_Bin )/w1)**2+(p1/w1/2.)*a1*m1d*e1d**(p1/2.-1)*((x-s1+ self.Num_Bin )/w1)**2
851 jack2=numpy.sqrt(7)*numpy.array([JS/y_model,JW/y_model,JA/y_model,JP/y_model,JS1/y_model,JW1/y_model,JA1/y_model,JP1/y_model,1./y_model])
851 jack2=numpy.sqrt(7)*numpy.array([JS/y_model,JW/y_model,JA/y_model,JP/y_model,JS1/y_model,JW1/y_model,JA1/y_model,JP1/y_model,1./y_model])
852 return jack2.T
852 return jack2.T
853
853
854 def y_model1(self,x,state):
854 def y_model1(self,x,state):
855 shift0,width0,amplitude0,power0,noise=state
855 shift0,width0,amplitude0,power0,noise=state
856 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
856 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
857
857
858 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
858 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
859
859
860 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
860 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
861 return model0+model0u+model0d+noise
861 return model0+model0u+model0d+noise
862
862
863 def y_model2(self,x,state): #Equation for two generalized Gaussians with Nyquist
863 def y_model2(self,x,state): #Equation for two generalized Gaussians with Nyquist
864 shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,noise=state
864 shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,noise=state
865 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
865 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
866
866
867 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
867 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
868
868
869 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
869 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
870 model1=amplitude1*numpy.exp(-0.5*abs((x-shift1)/width1)**power1)
870 model1=amplitude1*numpy.exp(-0.5*abs((x-shift1)/width1)**power1)
871
871
872 model1u=amplitude1*numpy.exp(-0.5*abs((x-shift1- self.Num_Bin )/width1)**power1)
872 model1u=amplitude1*numpy.exp(-0.5*abs((x-shift1- self.Num_Bin )/width1)**power1)
873
873
874 model1d=amplitude1*numpy.exp(-0.5*abs((x-shift1+ self.Num_Bin )/width1)**power1)
874 model1d=amplitude1*numpy.exp(-0.5*abs((x-shift1+ self.Num_Bin )/width1)**power1)
875 return model0+model0u+model0d+model1+model1u+model1d+noise
875 return model0+model0u+model0d+model1+model1u+model1d+noise
876
876
877 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.
877 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.
878
878
879 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model1(x,state)))**2)#/(64-5.) # /(64-5.) can be commented
879 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model1(x,state)))**2)#/(64-5.) # /(64-5.) can be commented
880
880
881 def misfit2(self,state,y_data,x,num_intg):
881 def misfit2(self,state,y_data,x,num_intg):
882 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model2(x,state)))**2)#/(64-9.)
882 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model2(x,state)))**2)#/(64-9.)
883
883
884
884
885 class PrecipitationProc(Operation):
885 class PrecipitationProc(Operation):
886
886
887 '''
887 '''
888 Operator that estimates Reflectivity factor (Z), and estimates rainfall Rate (R)
888 Operator that estimates Reflectivity factor (Z), and estimates rainfall Rate (R)
889
889
890 Input:
890 Input:
891 self.dataOut.data_pre : SelfSpectra
891 self.dataOut.data_pre : SelfSpectra
892
892
893 Output:
893 Output:
894
894
895 self.dataOut.data_output : Reflectivity factor, rainfall Rate
895 self.dataOut.data_output : Reflectivity factor, rainfall Rate
896
896
897
897
898 Parameters affected:
898 Parameters affected:
899 '''
899 '''
900
900
901
901
902 def run(self, dataOut, radar=None, Pt=None, Gt=None, Gr=None, Lambda=None, aL=None,
902 def run(self, dataOut, radar=None, Pt=None, Gt=None, Gr=None, Lambda=None, aL=None,
903 tauW=None, ThetaT=None, ThetaR=None, Km = 0.93, Altitude=None):
903 tauW=None, ThetaT=None, ThetaR=None, Km = 0.93, Altitude=None):
904
904
905 self.spc = dataOut.data_pre[0].copy()
905 self.spc = dataOut.data_pre[0].copy()
906 self.Num_Hei = self.spc.shape[2]
906 self.Num_Hei = self.spc.shape[2]
907 self.Num_Bin = self.spc.shape[1]
907 self.Num_Bin = self.spc.shape[1]
908 self.Num_Chn = self.spc.shape[0]
908 self.Num_Chn = self.spc.shape[0]
909
909
910 Velrange = dataOut.abscissaList
910 Velrange = dataOut.abscissaList
911
911
912 if radar == "MIRA35C" :
912 if radar == "MIRA35C" :
913
913
914 Ze = self.dBZeMODE2(dataOut)
914 Ze = self.dBZeMODE2(dataOut)
915
915
916 else:
916 else:
917
917
918 self.Pt = Pt
918 self.Pt = Pt
919 self.Gt = Gt
919 self.Gt = Gt
920 self.Gr = Gr
920 self.Gr = Gr
921 self.Lambda = Lambda
921 self.Lambda = Lambda
922 self.aL = aL
922 self.aL = aL
923 self.tauW = tauW
923 self.tauW = tauW
924 self.ThetaT = ThetaT
924 self.ThetaT = ThetaT
925 self.ThetaR = ThetaR
925 self.ThetaR = ThetaR
926
926
927 RadarConstant = GetRadarConstant()
927 RadarConstant = GetRadarConstant()
928 SPCmean = numpy.mean(self.spc,0)
928 SPCmean = numpy.mean(self.spc,0)
929 ETA = numpy.zeros(self.Num_Hei)
929 ETA = numpy.zeros(self.Num_Hei)
930 Pr = numpy.sum(SPCmean,0)
930 Pr = numpy.sum(SPCmean,0)
931
931
932 #for R in range(self.Num_Hei):
932 #for R in range(self.Num_Hei):
933 # ETA[R] = RadarConstant * Pr[R] * R**2 #Reflectivity (ETA)
933 # ETA[R] = RadarConstant * Pr[R] * R**2 #Reflectivity (ETA)
934
934
935 D_range = numpy.zeros(self.Num_Hei)
935 D_range = numpy.zeros(self.Num_Hei)
936 EqSec = numpy.zeros(self.Num_Hei)
936 EqSec = numpy.zeros(self.Num_Hei)
937 del_V = numpy.zeros(self.Num_Hei)
937 del_V = numpy.zeros(self.Num_Hei)
938
938
939 for R in range(self.Num_Hei):
939 for R in range(self.Num_Hei):
940 ETA[R] = RadarConstant * Pr[R] * R**2 #Reflectivity (ETA)
940 ETA[R] = RadarConstant * Pr[R] * R**2 #Reflectivity (ETA)
941
941
942 h = R + Altitude #Range from ground to radar pulse altitude
942 h = R + Altitude #Range from ground to radar pulse altitude
943 del_V[R] = 1 + 3.68 * 10**-5 * h + 1.71 * 10**-9 * h**2 #Density change correction for velocity
943 del_V[R] = 1 + 3.68 * 10**-5 * h + 1.71 * 10**-9 * h**2 #Density change correction for velocity
944
944
945 D_range[R] = numpy.log( (9.65 - (Velrange[R]/del_V[R])) / 10.3 ) / -0.6 #Range of Diameter of drops related to velocity
945 D_range[R] = numpy.log( (9.65 - (Velrange[R]/del_V[R])) / 10.3 ) / -0.6 #Range of Diameter of drops related to velocity
946 SIGMA[R] = numpy.pi**5 / Lambda**4 * Km * D_range[R]**6 #Equivalent Section of drops (sigma)
946 SIGMA[R] = numpy.pi**5 / Lambda**4 * Km * D_range[R]**6 #Equivalent Section of drops (sigma)
947
947
948 N_dist[R] = ETA[R] / SIGMA[R]
948 N_dist[R] = ETA[R] / SIGMA[R]
949
949
950 Ze = (ETA * Lambda**4) / (numpy.pi * Km)
950 Ze = (ETA * Lambda**4) / (numpy.pi * Km)
951 Z = numpy.sum( N_dist * D_range**6 )
951 Z = numpy.sum( N_dist * D_range**6 )
952 RR = 6*10**-4*numpy.pi * numpy.sum( D_range**3 * N_dist * Velrange ) #Rainfall rate
952 RR = 6*10**-4*numpy.pi * numpy.sum( D_range**3 * N_dist * Velrange ) #Rainfall rate
953
953
954
954
955 RR = (Ze/200)**(1/1.6)
955 RR = (Ze/200)**(1/1.6)
956 dBRR = 10*numpy.log10(RR)
956 dBRR = 10*numpy.log10(RR)
957
957
958 dBZe = 10*numpy.log10(Ze)
958 dBZe = 10*numpy.log10(Ze)
959 dataOut.data_output = Ze
959 dataOut.data_output = Ze
960 dataOut.data_param = numpy.ones([2,self.Num_Hei])
960 dataOut.data_param = numpy.ones([2,self.Num_Hei])
961 dataOut.channelList = [0,1]
961 dataOut.channelList = [0,1]
962 print 'channelList', dataOut.channelList
962 print 'channelList', dataOut.channelList
963 dataOut.data_param[0]=dBZe
963 dataOut.data_param[0]=dBZe
964 dataOut.data_param[1]=dBRR
964 dataOut.data_param[1]=dBRR
965 print 'RR SHAPE', dBRR.shape
965 print 'RR SHAPE', dBRR.shape
966 print 'Ze SHAPE', dBZe.shape
966 print 'Ze SHAPE', dBZe.shape
967 print 'dataOut.data_param SHAPE', dataOut.data_param.shape
967 print 'dataOut.data_param SHAPE', dataOut.data_param.shape
968
968
969
969
970 def dBZeMODE2(self, dataOut): # Processing for MIRA35C
970 def dBZeMODE2(self, dataOut): # Processing for MIRA35C
971
971
972 NPW = dataOut.NPW
972 NPW = dataOut.NPW
973 COFA = dataOut.COFA
973 COFA = dataOut.COFA
974
974
975 SNR = numpy.array([self.spc[0,:,:] / NPW[0]]) #, self.spc[1,:,:] / NPW[1]])
975 SNR = numpy.array([self.spc[0,:,:] / NPW[0]]) #, self.spc[1,:,:] / NPW[1]])
976 RadarConst = dataOut.RadarConst
976 RadarConst = dataOut.RadarConst
977 #frequency = 34.85*10**9
977 #frequency = 34.85*10**9
978
978
979 ETA = numpy.zeros(([self.Num_Chn ,self.Num_Hei]))
979 ETA = numpy.zeros(([self.Num_Chn ,self.Num_Hei]))
980 data_output = numpy.ones([self.Num_Chn , self.Num_Hei])*numpy.NaN
980 data_output = numpy.ones([self.Num_Chn , self.Num_Hei])*numpy.NaN
981
981
982 ETA = numpy.sum(SNR,1)
982 ETA = numpy.sum(SNR,1)
983 print 'ETA' , ETA
983 print 'ETA' , ETA
984 ETA = numpy.where(ETA is not 0. , ETA, numpy.NaN)
984 ETA = numpy.where(ETA is not 0. , ETA, numpy.NaN)
985
985
986 Ze = numpy.ones([self.Num_Chn, self.Num_Hei] )
986 Ze = numpy.ones([self.Num_Chn, self.Num_Hei] )
987
987
988 for r in range(self.Num_Hei):
988 for r in range(self.Num_Hei):
989
989
990 Ze[0,r] = ( ETA[0,r] ) * COFA[0,r][0] * RadarConst * ((r/5000.)**2)
990 Ze[0,r] = ( ETA[0,r] ) * COFA[0,r][0] * RadarConst * ((r/5000.)**2)
991 #Ze[1,r] = ( ETA[1,r] ) * COFA[1,r][0] * RadarConst * ((r/5000.)**2)
991 #Ze[1,r] = ( ETA[1,r] ) * COFA[1,r][0] * RadarConst * ((r/5000.)**2)
992
992
993 return Ze
993 return Ze
994
994
995 def GetRadarConstant(self):
995 def GetRadarConstant(self):
996
996
997 """
997 """
998 Constants:
998 Constants:
999
999
1000 Pt: Transmission Power dB
1000 Pt: Transmission Power dB
1001 Gt: Transmission Gain dB
1001 Gt: Transmission Gain dB
1002 Gr: Reception Gain dB
1002 Gr: Reception Gain dB
1003 Lambda: Wavelenght m
1003 Lambda: Wavelenght m
1004 aL: Attenuation loses dB
1004 aL: Attenuation loses dB
1005 tauW: Width of transmission pulse s
1005 tauW: Width of transmission pulse s
1006 ThetaT: Transmission antenna bean angle rad
1006 ThetaT: Transmission antenna bean angle rad
1007 ThetaR: Reception antenna beam angle rad
1007 ThetaR: Reception antenna beam angle rad
1008
1008
1009 """
1009 """
1010 Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
1010 Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
1011 Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * TauW * numpy.pi * ThetaT * TheraR)
1011 Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * TauW * numpy.pi * ThetaT * TheraR)
1012 RadarConstant = Numerator / Denominator
1012 RadarConstant = Numerator / Denominator
1013
1013
1014 return RadarConstant
1014 return RadarConstant
1015
1015
1016
1016
1017
1017
1018 class FullSpectralAnalysis(Operation):
1018 class FullSpectralAnalysis(Operation):
1019
1019
1020 """
1020 """
1021 Function that implements Full Spectral Analisys technique.
1021 Function that implements Full Spectral Analisys technique.
1022
1022
1023 Input:
1023 Input:
1024 self.dataOut.data_pre : SelfSpectra and CrossSPectra data
1024 self.dataOut.data_pre : SelfSpectra and CrossSPectra data
1025 self.dataOut.groupList : Pairlist of channels
1025 self.dataOut.groupList : Pairlist of channels
1026 self.dataOut.ChanDist : Physical distance between receivers
1026 self.dataOut.ChanDist : Physical distance between receivers
1027
1027
1028
1028
1029 Output:
1029 Output:
1030
1030
1031 self.dataOut.data_output : Zonal wind, Meridional wind and Vertical wind
1031 self.dataOut.data_output : Zonal wind, Meridional wind and Vertical wind
1032
1032
1033
1033
1034 Parameters affected: Winds, height range, SNR
1034 Parameters affected: Winds, height range, SNR
1035
1035
1036 """
1036 """
1037 def run(self, dataOut, E01=None, E02=None, E12=None, N01=None, N02=None, N12=None, SNRlimit=7):
1037 def run(self, dataOut, E01=None, E02=None, E12=None, N01=None, N02=None, N12=None, SNRlimit=7):
1038
1038
1039 spc = dataOut.data_pre[0].copy()
1039 spc = dataOut.data_pre[0].copy()
1040 cspc = dataOut.data_pre[1].copy()
1040 cspc = dataOut.data_pre[1].copy()
1041
1041
1042 nChannel = spc.shape[0]
1042 nChannel = spc.shape[0]
1043 nProfiles = spc.shape[1]
1043 nProfiles = spc.shape[1]
1044 nHeights = spc.shape[2]
1044 nHeights = spc.shape[2]
1045
1045
1046 pairsList = dataOut.groupList
1046 pairsList = dataOut.groupList
1047 if dataOut.ChanDist is not None :
1047 if dataOut.ChanDist is not None :
1048 ChanDist = dataOut.ChanDist
1048 ChanDist = dataOut.ChanDist
1049 else:
1049 else:
1050 ChanDist = numpy.array([[E01, N01],[E02,N02],[E12,N12]])
1050 ChanDist = numpy.array([[E01, N01],[E02,N02],[E12,N12]])
1051
1051
1052 #print 'ChanDist', ChanDist
1052 #print 'ChanDist', ChanDist
1053
1053
1054 if dataOut.VelRange is not None:
1054 if dataOut.VelRange is not None:
1055 VelRange= dataOut.VelRange
1055 VelRange= dataOut.VelRange
1056 else:
1056 else:
1057 VelRange= dataOut.abscissaList
1057 VelRange= dataOut.abscissaList
1058
1058
1059 ySamples=numpy.ones([nChannel,nProfiles])
1059 ySamples=numpy.ones([nChannel,nProfiles])
1060 phase=numpy.ones([nChannel,nProfiles])
1060 phase=numpy.ones([nChannel,nProfiles])
1061 CSPCSamples=numpy.ones([nChannel,nProfiles],dtype=numpy.complex_)
1061 CSPCSamples=numpy.ones([nChannel,nProfiles],dtype=numpy.complex_)
1062 coherence=numpy.ones([nChannel,nProfiles])
1062 coherence=numpy.ones([nChannel,nProfiles])
1063 PhaseSlope=numpy.ones(nChannel)
1063 PhaseSlope=numpy.ones(nChannel)
1064 PhaseInter=numpy.ones(nChannel)
1064 PhaseInter=numpy.ones(nChannel)
1065 dataSNR = dataOut.data_SNR
1065 dataSNR = dataOut.data_SNR
1066
1066
1067
1067
1068
1068
1069 data = dataOut.data_pre
1069 data = dataOut.data_pre
1070 noise = dataOut.noise
1070 noise = dataOut.noise
1071 print 'noise',noise
1071 print 'noise',noise
1072 #SNRdB = 10*numpy.log10(dataOut.data_SNR)
1072 #SNRdB = 10*numpy.log10(dataOut.data_SNR)
1073
1073
1074 FirstMoment = numpy.average(dataOut.data_param[:,1,:],0)
1074 FirstMoment = numpy.average(dataOut.data_param[:,1,:],0)
1075 #SNRdBMean = []
1075 #SNRdBMean = []
1076
1076
1077
1077
1078 #for j in range(nHeights):
1078 #for j in range(nHeights):
1079 # FirstMoment = numpy.append(FirstMoment,numpy.mean([dataOut.data_param[0,1,j],dataOut.data_param[1,1,j],dataOut.data_param[2,1,j]]))
1079 # FirstMoment = numpy.append(FirstMoment,numpy.mean([dataOut.data_param[0,1,j],dataOut.data_param[1,1,j],dataOut.data_param[2,1,j]]))
1080 # SNRdBMean = numpy.append(SNRdBMean,numpy.mean([SNRdB[0,j],SNRdB[1,j],SNRdB[2,j]]))
1080 # SNRdBMean = numpy.append(SNRdBMean,numpy.mean([SNRdB[0,j],SNRdB[1,j],SNRdB[2,j]]))
1081
1081
1082 data_output=numpy.ones([3,spc.shape[2]])*numpy.NaN
1082 data_output=numpy.ones([3,spc.shape[2]])*numpy.NaN
1083
1083
1084 velocityX=[]
1084 velocityX=[]
1085 velocityY=[]
1085 velocityY=[]
1086 velocityV=[]
1086 velocityV=[]
1087
1087
1088 dbSNR = 10*numpy.log10(dataSNR)
1088 dbSNR = 10*numpy.log10(dataSNR)
1089 dbSNR = numpy.average(dbSNR,0)
1089 dbSNR = numpy.average(dbSNR,0)
1090 for Height in range(nHeights):
1090 for Height in range(nHeights):
1091
1091
1092 [Vzon,Vmer,Vver, GaussCenter]= self.WindEstimation(spc, cspc, pairsList, ChanDist, Height, noise, VelRange, dbSNR[Height], SNRlimit)
1092 [Vzon,Vmer,Vver, GaussCenter]= self.WindEstimation(spc, cspc, pairsList, ChanDist, Height, noise, VelRange, dbSNR[Height], SNRlimit)
1093
1093
1094 if abs(Vzon)<100. and abs(Vzon)> 0.:
1094 if abs(Vzon)<100. and abs(Vzon)> 0.:
1095 velocityX=numpy.append(velocityX, Vzon)#Vmag
1095 velocityX=numpy.append(velocityX, Vzon)#Vmag
1096
1096
1097 else:
1097 else:
1098 print 'Vzon',Vzon
1098 print 'Vzon',Vzon
1099 velocityX=numpy.append(velocityX, numpy.NaN)
1099 velocityX=numpy.append(velocityX, numpy.NaN)
1100
1100
1101 if abs(Vmer)<100. and abs(Vmer) > 0.:
1101 if abs(Vmer)<100. and abs(Vmer) > 0.:
1102 velocityY=numpy.append(velocityY, Vmer)#Vang
1102 velocityY=numpy.append(velocityY, Vmer)#Vang
1103
1103
1104 else:
1104 else:
1105 print 'Vmer',Vmer
1105 print 'Vmer',Vmer
1106 velocityY=numpy.append(velocityY, numpy.NaN)
1106 velocityY=numpy.append(velocityY, numpy.NaN)
1107
1107
1108 if dbSNR[Height] > SNRlimit:
1108 if dbSNR[Height] > SNRlimit:
1109 velocityV=numpy.append(velocityV, FirstMoment[Height])
1109 velocityV=numpy.append(velocityV, FirstMoment[Height])
1110 else:
1110 else:
1111 velocityV=numpy.append(velocityV, numpy.NaN)
1111 velocityV=numpy.append(velocityV, numpy.NaN)
1112 #FirstMoment[Height]= numpy.NaN
1112 #FirstMoment[Height]= numpy.NaN
1113 # if SNRdBMean[Height] <12:
1113 # if SNRdBMean[Height] <12:
1114 # FirstMoment[Height] = numpy.NaN
1114 # FirstMoment[Height] = numpy.NaN
1115 # velocityX[Height] = numpy.NaN
1115 # velocityX[Height] = numpy.NaN
1116 # velocityY[Height] = numpy.NaN
1116 # velocityY[Height] = numpy.NaN
1117
1117
1118
1118
1119 data_output[0]=numpy.array(velocityX)
1119 data_output[0]=numpy.array(velocityX)
1120 data_output[1]=numpy.array(velocityY)
1120 data_output[1]=numpy.array(velocityY)
1121 data_output[2]=-velocityV#FirstMoment
1121 data_output[2]=-velocityV#FirstMoment
1122
1122
1123 print ' '
1123 print ' '
1124 #print 'FirstMoment'
1124 #print 'FirstMoment'
1125 #print FirstMoment
1125 #print FirstMoment
1126 print 'velocityX',data_output[0]
1126 print 'velocityX',data_output[0]
1127 print ' '
1127 print ' '
1128 print 'velocityY',data_output[1]
1128 print 'velocityY',data_output[1]
1129 #print numpy.array(velocityY)
1129 #print numpy.array(velocityY)
1130 print ' '
1130 print ' '
1131 #print 'SNR'
1131 #print 'SNR'
1132 #print 10*numpy.log10(dataOut.data_SNR)
1132 #print 10*numpy.log10(dataOut.data_SNR)
1133 #print numpy.shape(10*numpy.log10(dataOut.data_SNR))
1133 #print numpy.shape(10*numpy.log10(dataOut.data_SNR))
1134 print ' '
1134 print ' '
1135
1135
1136
1136
1137 dataOut.data_output=data_output
1137 dataOut.data_output=data_output
1138 return
1138 return
1139
1139
1140
1140
1141 def moving_average(self,x, N=2):
1141 def moving_average(self,x, N=2):
1142 return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):]
1142 return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):]
1143
1143
1144 def gaus(self,xSamples,a,x0,sigma):
1144 def gaus(self,xSamples,a,x0,sigma):
1145 return a*numpy.exp(-(xSamples-x0)**2/(2*sigma**2))
1145 return a*numpy.exp(-(xSamples-x0)**2/(2*sigma**2))
1146
1146
1147 def Find(self,x,value):
1147 def Find(self,x,value):
1148 for index in range(len(x)):
1148 for index in range(len(x)):
1149 if x[index]==value:
1149 if x[index]==value:
1150 return index
1150 return index
1151
1151
1152 def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, VelRange, dbSNR, SNRlimit):
1152 def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, VelRange, dbSNR, SNRlimit):
1153
1153
1154 ySamples=numpy.ones([spc.shape[0],spc.shape[1]])
1154 ySamples=numpy.ones([spc.shape[0],spc.shape[1]])
1155 phase=numpy.ones([spc.shape[0],spc.shape[1]])
1155 phase=numpy.ones([spc.shape[0],spc.shape[1]])
1156 CSPCSamples=numpy.ones([spc.shape[0],spc.shape[1]],dtype=numpy.complex_)
1156 CSPCSamples=numpy.ones([spc.shape[0],spc.shape[1]],dtype=numpy.complex_)
1157 coherence=numpy.ones([spc.shape[0],spc.shape[1]])
1157 coherence=numpy.ones([spc.shape[0],spc.shape[1]])
1158 PhaseSlope=numpy.ones(spc.shape[0])
1158 PhaseSlope=numpy.ones(spc.shape[0])
1159 PhaseInter=numpy.ones(spc.shape[0])
1159 PhaseInter=numpy.ones(spc.shape[0])
1160 xFrec=VelRange
1160 xFrec=VelRange
1161
1161
1162 '''Getting Eij and Nij'''
1162 '''Getting Eij and Nij'''
1163
1163
1164 E01=ChanDist[0][0]
1164 E01=ChanDist[0][0]
1165 N01=ChanDist[0][1]
1165 N01=ChanDist[0][1]
1166
1166
1167 E02=ChanDist[1][0]
1167 E02=ChanDist[1][0]
1168 N02=ChanDist[1][1]
1168 N02=ChanDist[1][1]
1169
1169
1170 E12=ChanDist[2][0]
1170 E12=ChanDist[2][0]
1171 N12=ChanDist[2][1]
1171 N12=ChanDist[2][1]
1172
1172
1173 z = spc.copy()
1173 z = spc.copy()
1174 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1174 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1175
1175
1176 for i in range(spc.shape[0]):
1176 for i in range(spc.shape[0]):
1177
1177
1178 '''****** Line of Data SPC ******'''
1178 '''****** Line of Data SPC ******'''
1179 zline=z[i,:,Height]
1179 zline=z[i,:,Height]
1180
1180
1181 '''****** SPC is normalized ******'''
1181 '''****** SPC is normalized ******'''
1182 FactNorm= (zline.copy()-noise[i]) / numpy.sum(zline.copy())
1182 FactNorm= (zline.copy()-noise[i]) / numpy.sum(zline.copy())
1183 FactNorm= FactNorm/numpy.sum(FactNorm)
1183 FactNorm= FactNorm/numpy.sum(FactNorm)
1184
1184
1185 SmoothSPC=self.moving_average(FactNorm,N=3)
1185 SmoothSPC=self.moving_average(FactNorm,N=3)
1186
1186
1187 xSamples = ar(range(len(SmoothSPC)))
1187 xSamples = ar(range(len(SmoothSPC)))
1188 ySamples[i] = SmoothSPC
1188 ySamples[i] = SmoothSPC
1189
1189
1190 #dbSNR=10*numpy.log10(dataSNR)
1190 #dbSNR=10*numpy.log10(dataSNR)
1191 print ' '
1191 print ' '
1192 print ' '
1192 print ' '
1193 print ' '
1193 print ' '
1194
1194
1195 #print 'dataSNR', dbSNR.shape, dbSNR[0,40:120]
1195 #print 'dataSNR', dbSNR.shape, dbSNR[0,40:120]
1196 print 'SmoothSPC', SmoothSPC.shape, SmoothSPC[0:20]
1196 print 'SmoothSPC', SmoothSPC.shape, SmoothSPC[0:20]
1197 print 'noise',noise
1197 print 'noise',noise
1198 print 'zline',zline.shape, zline[0:20]
1198 print 'zline',zline.shape, zline[0:20]
1199 print 'FactNorm',FactNorm.shape, FactNorm[0:20]
1199 print 'FactNorm',FactNorm.shape, FactNorm[0:20]
1200 print 'FactNorm suma', numpy.sum(FactNorm)
1200 print 'FactNorm suma', numpy.sum(FactNorm)
1201
1201
1202 for i in range(spc.shape[0]):
1202 for i in range(spc.shape[0]):
1203
1203
1204 '''****** Line of Data CSPC ******'''
1204 '''****** Line of Data CSPC ******'''
1205 cspcLine=cspc[i,:,Height].copy()
1205 cspcLine=cspc[i,:,Height].copy()
1206
1206
1207 '''****** CSPC is normalized ******'''
1207 '''****** CSPC is normalized ******'''
1208 chan_index0 = pairsList[i][0]
1208 chan_index0 = pairsList[i][0]
1209 chan_index1 = pairsList[i][1]
1209 chan_index1 = pairsList[i][1]
1210 CSPCFactor= abs(numpy.sum(ySamples[chan_index0]) * numpy.sum(ySamples[chan_index1])) #
1210 CSPCFactor= abs(numpy.sum(ySamples[chan_index0]) * numpy.sum(ySamples[chan_index1])) #
1211
1211
1212 CSPCNorm = (cspcLine.copy() -noise[i]) / numpy.sqrt(CSPCFactor)
1212 CSPCNorm = (cspcLine.copy() -noise[i]) / numpy.sqrt(CSPCFactor)
1213
1213
1214 CSPCSamples[i] = CSPCNorm
1214 CSPCSamples[i] = CSPCNorm
1215 coherence[i] = numpy.abs(CSPCSamples[i]) / numpy.sqrt(CSPCFactor)
1215 coherence[i] = numpy.abs(CSPCSamples[i]) / numpy.sqrt(CSPCFactor)
1216
1216
1217 coherence[i]= self.moving_average(coherence[i],N=2)
1217 coherence[i]= self.moving_average(coherence[i],N=2)
1218
1218
1219 phase[i] = self.moving_average( numpy.arctan2(CSPCSamples[i].imag, CSPCSamples[i].real),N=1)#*180/numpy.pi
1219 phase[i] = self.moving_average( numpy.arctan2(CSPCSamples[i].imag, CSPCSamples[i].real),N=1)#*180/numpy.pi
1220
1220
1221 print 'cspcLine', cspcLine.shape, cspcLine[0:20]
1221 print 'cspcLine', cspcLine.shape, cspcLine[0:20]
1222 print 'CSPCFactor', CSPCFactor#, CSPCFactor[0:20]
1222 print 'CSPCFactor', CSPCFactor#, CSPCFactor[0:20]
1223 print numpy.sum(ySamples[chan_index0]), numpy.sum(ySamples[chan_index1]), -noise[i]
1223 print numpy.sum(ySamples[chan_index0]), numpy.sum(ySamples[chan_index1]), -noise[i]
1224 print 'CSPCNorm', CSPCNorm.shape, CSPCNorm[0:20]
1224 print 'CSPCNorm', CSPCNorm.shape, CSPCNorm[0:20]
1225 print 'CSPCNorm suma', numpy.sum(CSPCNorm)
1225 print 'CSPCNorm suma', numpy.sum(CSPCNorm)
1226 print 'CSPCSamples', CSPCSamples.shape, CSPCSamples[0,0:20]
1226 print 'CSPCSamples', CSPCSamples.shape, CSPCSamples[0,0:20]
1227
1227
1228 '''****** Getting fij width ******'''
1228 '''****** Getting fij width ******'''
1229
1229
1230 yMean=[]
1230 yMean=[]
1231 yMean2=[]
1231 yMean2=[]
1232
1232
1233 for j in range(len(ySamples[1])):
1233 for j in range(len(ySamples[1])):
1234 yMean=numpy.append(yMean,numpy.mean([ySamples[0,j],ySamples[1,j],ySamples[2,j]]))
1234 yMean=numpy.append(yMean,numpy.mean([ySamples[0,j],ySamples[1,j],ySamples[2,j]]))
1235
1235
1236 '''******* Getting fitting Gaussian ******'''
1236 '''******* Getting fitting Gaussian ******'''
1237 meanGauss=sum(xSamples*yMean) / len(xSamples)
1237 meanGauss=sum(xSamples*yMean) / len(xSamples)
1238 sigma=sum(yMean*(xSamples-meanGauss)**2) / len(xSamples)
1238 sigma=sum(yMean*(xSamples-meanGauss)**2) / len(xSamples)
1239
1239
1240 print '****************************'
1240 print '****************************'
1241 print 'len(xSamples): ',len(xSamples)
1241 print 'len(xSamples): ',len(xSamples)
1242 print 'yMean: ', yMean.shape, yMean[0:20]
1242 print 'yMean: ', yMean.shape, yMean[0:20]
1243 print 'ySamples', ySamples.shape, ySamples[0,0:20]
1243 print 'ySamples', ySamples.shape, ySamples[0,0:20]
1244 print 'xSamples: ',xSamples.shape, xSamples[0:20]
1244 print 'xSamples: ',xSamples.shape, xSamples[0:20]
1245
1245
1246 print 'meanGauss',meanGauss
1246 print 'meanGauss',meanGauss
1247 print 'sigma',sigma
1247 print 'sigma',sigma
1248
1248
1249 #if (abs(meanGauss/sigma**2) > 0.0001) : #0.000000001):
1249 #if (abs(meanGauss/sigma**2) > 0.0001) : #0.000000001):
1250 if dbSNR > SNRlimit :
1250 if dbSNR > SNRlimit :
1251 try:
1251 try:
1252 popt,pcov = curve_fit(self.gaus,xSamples,yMean,p0=[1,meanGauss,sigma])
1252 popt,pcov = curve_fit(self.gaus,xSamples,yMean,p0=[1,meanGauss,sigma])
1253
1253
1254 if numpy.amax(popt)>numpy.amax(yMean)*0.3:
1254 if numpy.amax(popt)>numpy.amax(yMean)*0.3:
1255 FitGauss=self.gaus(xSamples,*popt)
1255 FitGauss=self.gaus(xSamples,*popt)
1256
1256
1257 else:
1257 else:
1258 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1258 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1259 print 'Verificador: Dentro', Height
1259 print 'Verificador: Dentro', Height
1260 except :#RuntimeError:
1260 except :#RuntimeError:
1261 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1261 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1262
1262
1263
1263
1264 else:
1264 else:
1265 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1265 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1266
1266
1267 Maximun=numpy.amax(yMean)
1267 Maximun=numpy.amax(yMean)
1268 eMinus1=Maximun*numpy.exp(-1)#*0.8
1268 eMinus1=Maximun*numpy.exp(-1)#*0.8
1269
1269
1270 HWpos=self.Find(FitGauss,min(FitGauss, key=lambda value:abs(value-eMinus1)))
1270 HWpos=self.Find(FitGauss,min(FitGauss, key=lambda value:abs(value-eMinus1)))
1271 HalfWidth= xFrec[HWpos]
1271 HalfWidth= xFrec[HWpos]
1272 GCpos=self.Find(FitGauss, numpy.amax(FitGauss))
1272 GCpos=self.Find(FitGauss, numpy.amax(FitGauss))
1273 Vpos=self.Find(FactNorm, numpy.amax(FactNorm))
1273 Vpos=self.Find(FactNorm, numpy.amax(FactNorm))
1274
1274
1275 #Vpos=FirstMoment[]
1275 #Vpos=FirstMoment[]
1276
1276
1277 '''****** Getting Fij ******'''
1277 '''****** Getting Fij ******'''
1278
1278
1279 GaussCenter=xFrec[GCpos]
1279 GaussCenter=xFrec[GCpos]
1280 if (GaussCenter<0 and HalfWidth>0) or (GaussCenter>0 and HalfWidth<0):
1280 if (GaussCenter<0 and HalfWidth>0) or (GaussCenter>0 and HalfWidth<0):
1281 Fij=abs(GaussCenter)+abs(HalfWidth)+0.0000001
1281 Fij=abs(GaussCenter)+abs(HalfWidth)+0.0000001
1282 else:
1282 else:
1283 Fij=abs(GaussCenter-HalfWidth)+0.0000001
1283 Fij=abs(GaussCenter-HalfWidth)+0.0000001
1284
1284
1285 '''****** Getting Frecuency range of significant data ******'''
1285 '''****** Getting Frecuency range of significant data ******'''
1286
1286
1287 Rangpos=self.Find(FitGauss,min(FitGauss, key=lambda value:abs(value-Maximun*0.10)))
1287 Rangpos=self.Find(FitGauss,min(FitGauss, key=lambda value:abs(value-Maximun*0.10)))
1288
1288
1289 if Rangpos<GCpos:
1289 if Rangpos<GCpos:
1290 Range=numpy.array([Rangpos,2*GCpos-Rangpos])
1290 Range=numpy.array([Rangpos,2*GCpos-Rangpos])
1291 elif Rangpos< ( len(xFrec)- len(xFrec)*0.1):
1291 elif Rangpos< ( len(xFrec)- len(xFrec)*0.1):
1292 Range=numpy.array([2*GCpos-Rangpos,Rangpos])
1292 Range=numpy.array([2*GCpos-Rangpos,Rangpos])
1293 else:
1293 else:
1294 Range = numpy.array([0,0])
1294 Range = numpy.array([0,0])
1295
1295
1296 print ' '
1296 print ' '
1297 print 'GCpos',GCpos, ( len(xFrec)- len(xFrec)*0.1)
1297 print 'GCpos',GCpos, ( len(xFrec)- len(xFrec)*0.1)
1298 print 'Rangpos',Rangpos
1298 print 'Rangpos',Rangpos
1299 print 'RANGE: ', Range
1299 print 'RANGE: ', Range
1300 FrecRange=xFrec[Range[0]:Range[1]]
1300 FrecRange=xFrec[Range[0]:Range[1]]
1301
1301
1302 '''****** Getting SCPC Slope ******'''
1302 '''****** Getting SCPC Slope ******'''
1303
1303
1304 for i in range(spc.shape[0]):
1304 for i in range(spc.shape[0]):
1305
1305
1306 if len(FrecRange)>5 and len(FrecRange)<spc.shape[1]*0.5:
1306 if len(FrecRange)>5 and len(FrecRange)<spc.shape[1]*0.5:
1307 PhaseRange=self.moving_average(phase[i,Range[0]:Range[1]],N=3)
1307 PhaseRange=self.moving_average(phase[i,Range[0]:Range[1]],N=3)
1308
1308
1309 print 'FrecRange', len(FrecRange) , FrecRange
1309 print 'FrecRange', len(FrecRange) , FrecRange
1310 print 'PhaseRange', len(PhaseRange), PhaseRange
1310 print 'PhaseRange', len(PhaseRange), PhaseRange
1311 print ' '
1311 print ' '
1312 if len(FrecRange) == len(PhaseRange):
1312 if len(FrecRange) == len(PhaseRange):
1313 slope, intercept, r_value, p_value, std_err = stats.linregress(FrecRange,PhaseRange)
1313 slope, intercept, r_value, p_value, std_err = stats.linregress(FrecRange,PhaseRange)
1314 PhaseSlope[i]=slope
1314 PhaseSlope[i]=slope
1315 PhaseInter[i]=intercept
1315 PhaseInter[i]=intercept
1316 else:
1316 else:
1317 PhaseSlope[i]=0
1317 PhaseSlope[i]=0
1318 PhaseInter[i]=0
1318 PhaseInter[i]=0
1319 else:
1319 else:
1320 PhaseSlope[i]=0
1320 PhaseSlope[i]=0
1321 PhaseInter[i]=0
1321 PhaseInter[i]=0
1322
1322
1323 '''Getting constant C'''
1323 '''Getting constant C'''
1324 cC=(Fij*numpy.pi)**2
1324 cC=(Fij*numpy.pi)**2
1325
1325
1326 '''****** Getting constants F and G ******'''
1326 '''****** Getting constants F and G ******'''
1327 MijEijNij=numpy.array([[E02,N02], [E12,N12]])
1327 MijEijNij=numpy.array([[E02,N02], [E12,N12]])
1328 MijResult0=(-PhaseSlope[1]*cC) / (2*numpy.pi)
1328 MijResult0=(-PhaseSlope[1]*cC) / (2*numpy.pi)
1329 MijResult1=(-PhaseSlope[2]*cC) / (2*numpy.pi)
1329 MijResult1=(-PhaseSlope[2]*cC) / (2*numpy.pi)
1330 MijResults=numpy.array([MijResult0,MijResult1])
1330 MijResults=numpy.array([MijResult0,MijResult1])
1331 (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults)
1331 (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults)
1332
1332
1333 '''****** Getting constants A, B and H ******'''
1333 '''****** Getting constants A, B and H ******'''
1334 W01=numpy.amax(coherence[0])
1334 W01=numpy.amax(coherence[0])
1335 W02=numpy.amax(coherence[1])
1335 W02=numpy.amax(coherence[1])
1336 W12=numpy.amax(coherence[2])
1336 W12=numpy.amax(coherence[2])
1337
1337
1338 WijResult0=((cF*E01+cG*N01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi/cC))
1338 WijResult0=((cF*E01+cG*N01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi/cC))
1339 WijResult1=((cF*E02+cG*N02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi/cC))
1339 WijResult1=((cF*E02+cG*N02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi/cC))
1340 WijResult2=((cF*E12+cG*N12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi/cC))
1340 WijResult2=((cF*E12+cG*N12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi/cC))
1341
1341
1342 WijResults=numpy.array([WijResult0, WijResult1, WijResult2])
1342 WijResults=numpy.array([WijResult0, WijResult1, WijResult2])
1343
1343
1344 WijEijNij=numpy.array([ [E01**2, N01**2, 2*E01*N01] , [E02**2, N02**2, 2*E02*N02] , [E12**2, N12**2, 2*E12*N12] ])
1344 WijEijNij=numpy.array([ [E01**2, N01**2, 2*E01*N01] , [E02**2, N02**2, 2*E02*N02] , [E12**2, N12**2, 2*E12*N12] ])
1345 (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults)
1345 (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults)
1346
1346
1347 VxVy=numpy.array([[cA,cH],[cH,cB]])
1347 VxVy=numpy.array([[cA,cH],[cH,cB]])
1348
1348
1349 VxVyResults=numpy.array([-cF,-cG])
1349 VxVyResults=numpy.array([-cF,-cG])
1350 (Vx,Vy) = numpy.linalg.solve(VxVy, VxVyResults)
1350 (Vx,Vy) = numpy.linalg.solve(VxVy, VxVyResults)
1351
1351
1352 Vzon = Vy
1352 Vzon = Vy
1353 Vmer = Vx
1353 Vmer = Vx
1354 Vmag=numpy.sqrt(Vzon**2+Vmer**2)
1354 Vmag=numpy.sqrt(Vzon**2+Vmer**2)
1355 Vang=numpy.arctan2(Vmer,Vzon)
1355 Vang=numpy.arctan2(Vmer,Vzon)
1356 Vver=xFrec[Vpos]
1356 Vver=xFrec[Vpos]
1357 print 'vzon y vmer', Vzon, Vmer
1357 print 'vzon y vmer', Vzon, Vmer
1358 return Vzon, Vmer, Vver, GaussCenter
1358 return Vzon, Vmer, Vver, GaussCenter
1359
1359
1360 class SpectralMoments(Operation):
1360 class SpectralMoments(Operation):
1361
1361
1362 '''
1362 '''
1363 Function SpectralMoments()
1363 Function SpectralMoments()
1364
1364
1365 Calculates moments (power, mean, standard deviation) and SNR of the signal
1365 Calculates moments (power, mean, standard deviation) and SNR of the signal
1366
1366
1367 Type of dataIn: Spectra
1367 Type of dataIn: Spectra
1368
1368
1369 Configuration Parameters:
1369 Configuration Parameters:
1370
1370
1371 dirCosx : Cosine director in X axis
1371 dirCosx : Cosine director in X axis
1372 dirCosy : Cosine director in Y axis
1372 dirCosy : Cosine director in Y axis
1373
1373
1374 elevation :
1374 elevation :
1375 azimuth :
1375 azimuth :
1376
1376
1377 Input:
1377 Input:
1378 channelList : simple channel list to select e.g. [2,3,7]
1378 channelList : simple channel list to select e.g. [2,3,7]
1379 self.dataOut.data_pre : Spectral data
1379 self.dataOut.data_pre : Spectral data
1380 self.dataOut.abscissaList : List of frequencies
1380 self.dataOut.abscissaList : List of frequencies
1381 self.dataOut.noise : Noise level per channel
1381 self.dataOut.noise : Noise level per channel
1382
1382
1383 Affected:
1383 Affected:
1384 self.dataOut.data_param : Parameters per channel
1384 self.dataOut.data_param : Parameters per channel
1385 self.dataOut.data_SNR : SNR per channel
1385 self.dataOut.data_SNR : SNR per channel
1386
1386
1387 '''
1387 '''
1388
1388
1389 def run(self, dataOut):
1389 def run(self, dataOut):
1390
1390
1391 #dataOut.data_pre = dataOut.data_pre[0]
1391 #dataOut.data_pre = dataOut.data_pre[0]
1392 data = dataOut.data_pre[0]
1392 data = dataOut.data_pre[0]
1393 absc = dataOut.abscissaList[:-1]
1393 absc = dataOut.abscissaList[:-1]
1394 noise = dataOut.noise
1394 noise = dataOut.noise
1395 nChannel = data.shape[0]
1395 nChannel = data.shape[0]
1396 data_param = numpy.zeros((nChannel, 4, data.shape[2]))
1396 data_param = numpy.zeros((nChannel, 4, data.shape[2]))
1397
1397
1398 for ind in range(nChannel):
1398 for ind in range(nChannel):
1399 data_param[ind,:,:] = self.__calculateMoments( data[ind,:,:] , absc , noise[ind] )
1399 data_param[ind,:,:] = self.__calculateMoments( data[ind,:,:] , absc , noise[ind] )
1400
1400
1401 dataOut.data_param = data_param[:,1:,:]
1401 dataOut.data_param = data_param[:,1:,:]
1402 dataOut.data_SNR = data_param[:,0]
1402 dataOut.data_SNR = data_param[:,0]
1403 dataOut.data_DOP = data_param[:,1]
1403 dataOut.data_DOP = data_param[:,1]
1404 dataOut.data_MEAN = data_param[:,2]
1404 dataOut.data_MEAN = data_param[:,2]
1405 dataOut.data_STD = data_param[:,3]
1405 dataOut.data_STD = data_param[:,3]
1406 return
1406 return
1407
1407
1408 def __calculateMoments(self, oldspec, oldfreq, n0,
1408 def __calculateMoments(self, oldspec, oldfreq, n0,
1409 nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
1409 nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
1410
1410
1411 if (nicoh == None): nicoh = 1
1411 if (nicoh is None): nicoh = 1
1412 if (graph == None): graph = 0
1412 if (graph is None): graph = 0
1413 if (smooth == None): smooth = 0
1413 if (smooth is None): smooth = 0
1414 elif (self.smooth < 3): smooth = 0
1414 elif (self.smooth < 3): smooth = 0
1415
1415
1416 if (type1 == None): type1 = 0
1416 if (type1 is None): type1 = 0
1417 if (fwindow == None): fwindow = numpy.zeros(oldfreq.size) + 1
1417 if (fwindow is None): fwindow = numpy.zeros(oldfreq.size) + 1
1418 if (snrth == None): snrth = -3
1418 if (snrth is None): snrth = -3
1419 if (dc == None): dc = 0
1419 if (dc is None): dc = 0
1420 if (aliasing == None): aliasing = 0
1420 if (aliasing is None): aliasing = 0
1421 if (oldfd == None): oldfd = 0
1421 if (oldfd is None): oldfd = 0
1422 if (wwauto == None): wwauto = 0
1422 if (wwauto is None): wwauto = 0
1423
1423
1424 if (n0 < 1.e-20): n0 = 1.e-20
1424 if (n0 < 1.e-20): n0 = 1.e-20
1425
1425
1426 freq = oldfreq
1426 freq = oldfreq
1427 vec_power = numpy.zeros(oldspec.shape[1])
1427 vec_power = numpy.zeros(oldspec.shape[1])
1428 vec_fd = numpy.zeros(oldspec.shape[1])
1428 vec_fd = numpy.zeros(oldspec.shape[1])
1429 vec_w = numpy.zeros(oldspec.shape[1])
1429 vec_w = numpy.zeros(oldspec.shape[1])
1430 vec_snr = numpy.zeros(oldspec.shape[1])
1430 vec_snr = numpy.zeros(oldspec.shape[1])
1431
1431
1432 for ind in range(oldspec.shape[1]):
1432 for ind in range(oldspec.shape[1]):
1433
1433
1434 spec = oldspec[:,ind]
1434 spec = oldspec[:,ind]
1435 aux = spec*fwindow
1435 aux = spec*fwindow
1436 max_spec = aux.max()
1436 max_spec = aux.max()
1437 m = list(aux).index(max_spec)
1437 m = list(aux).index(max_spec)
1438
1438
1439 #Smooth
1439 #Smooth
1440 if (smooth == 0): spec2 = spec
1440 if (smooth == 0): spec2 = spec
1441 else: spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
1441 else: spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
1442
1442
1443 # Calculo de Momentos
1443 # Calculo de Momentos
1444 bb = spec2[range(m,spec2.size)]
1444 bb = spec2[range(m,spec2.size)]
1445 bb = (bb<n0).nonzero()
1445 bb = (bb<n0).nonzero()
1446 bb = bb[0]
1446 bb = bb[0]
1447
1447
1448 ss = spec2[range(0,m + 1)]
1448 ss = spec2[range(0,m + 1)]
1449 ss = (ss<n0).nonzero()
1449 ss = (ss<n0).nonzero()
1450 ss = ss[0]
1450 ss = ss[0]
1451
1451
1452 if (bb.size == 0):
1452 if (bb.size == 0):
1453 bb0 = spec.size - 1 - m
1453 bb0 = spec.size - 1 - m
1454 else:
1454 else:
1455 bb0 = bb[0] - 1
1455 bb0 = bb[0] - 1
1456 if (bb0 < 0):
1456 if (bb0 < 0):
1457 bb0 = 0
1457 bb0 = 0
1458
1458
1459 if (ss.size == 0): ss1 = 1
1459 if (ss.size == 0): ss1 = 1
1460 else: ss1 = max(ss) + 1
1460 else: ss1 = max(ss) + 1
1461
1461
1462 if (ss1 > m): ss1 = m
1462 if (ss1 > m): ss1 = m
1463
1463
1464 valid = numpy.asarray(range(int(m + bb0 - ss1 + 1))) + ss1
1464 valid = numpy.asarray(range(int(m + bb0 - ss1 + 1))) + ss1
1465 power = ((spec2[valid] - n0)*fwindow[valid]).sum()
1465 power = ((spec2[valid] - n0)*fwindow[valid]).sum()
1466 fd = ((spec2[valid]- n0)*freq[valid]*fwindow[valid]).sum()/power
1466 fd = ((spec2[valid]- n0)*freq[valid]*fwindow[valid]).sum()/power
1467 w = math.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum()/power)
1467 w = math.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum()/power)
1468 snr = (spec2.mean()-n0)/n0
1468 snr = (spec2.mean()-n0)/n0
1469
1469
1470 if (snr < 1.e-20) :
1470 if (snr < 1.e-20) :
1471 snr = 1.e-20
1471 snr = 1.e-20
1472
1472
1473 vec_power[ind] = power
1473 vec_power[ind] = power
1474 vec_fd[ind] = fd
1474 vec_fd[ind] = fd
1475 vec_w[ind] = w
1475 vec_w[ind] = w
1476 vec_snr[ind] = snr
1476 vec_snr[ind] = snr
1477
1477
1478 moments = numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
1478 moments = numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
1479 return moments
1479 return moments
1480
1480
1481 #------------------ Get SA Parameters --------------------------
1481 #------------------ Get SA Parameters --------------------------
1482
1482
1483 def GetSAParameters(self):
1483 def GetSAParameters(self):
1484 #SA en frecuencia
1484 #SA en frecuencia
1485 pairslist = self.dataOut.groupList
1485 pairslist = self.dataOut.groupList
1486 num_pairs = len(pairslist)
1486 num_pairs = len(pairslist)
1487
1487
1488 vel = self.dataOut.abscissaList
1488 vel = self.dataOut.abscissaList
1489 spectra = self.dataOut.data_pre
1489 spectra = self.dataOut.data_pre
1490 cspectra = self.dataIn.data_cspc
1490 cspectra = self.dataIn.data_cspc
1491 delta_v = vel[1] - vel[0]
1491 delta_v = vel[1] - vel[0]
1492
1492
1493 #Calculating the power spectrum
1493 #Calculating the power spectrum
1494 spc_pow = numpy.sum(spectra, 3)*delta_v
1494 spc_pow = numpy.sum(spectra, 3)*delta_v
1495 #Normalizing Spectra
1495 #Normalizing Spectra
1496 norm_spectra = spectra/spc_pow
1496 norm_spectra = spectra/spc_pow
1497 #Calculating the norm_spectra at peak
1497 #Calculating the norm_spectra at peak
1498 max_spectra = numpy.max(norm_spectra, 3)
1498 max_spectra = numpy.max(norm_spectra, 3)
1499
1499
1500 #Normalizing Cross Spectra
1500 #Normalizing Cross Spectra
1501 norm_cspectra = numpy.zeros(cspectra.shape)
1501 norm_cspectra = numpy.zeros(cspectra.shape)
1502
1502
1503 for i in range(num_chan):
1503 for i in range(num_chan):
1504 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
1504 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
1505
1505
1506 max_cspectra = numpy.max(norm_cspectra,2)
1506 max_cspectra = numpy.max(norm_cspectra,2)
1507 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
1507 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
1508
1508
1509 for i in range(num_pairs):
1509 for i in range(num_pairs):
1510 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
1510 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
1511 #------------------- Get Lags ----------------------------------
1511 #------------------- Get Lags ----------------------------------
1512
1512
1513 class SALags(Operation):
1513 class SALags(Operation):
1514 '''
1514 '''
1515 Function GetMoments()
1515 Function GetMoments()
1516
1516
1517 Input:
1517 Input:
1518 self.dataOut.data_pre
1518 self.dataOut.data_pre
1519 self.dataOut.abscissaList
1519 self.dataOut.abscissaList
1520 self.dataOut.noise
1520 self.dataOut.noise
1521 self.dataOut.normFactor
1521 self.dataOut.normFactor
1522 self.dataOut.data_SNR
1522 self.dataOut.data_SNR
1523 self.dataOut.groupList
1523 self.dataOut.groupList
1524 self.dataOut.nChannels
1524 self.dataOut.nChannels
1525
1525
1526 Affected:
1526 Affected:
1527 self.dataOut.data_param
1527 self.dataOut.data_param
1528
1528
1529 '''
1529 '''
1530 def run(self, dataOut):
1530 def run(self, dataOut):
1531 data_acf = dataOut.data_pre[0]
1531 data_acf = dataOut.data_pre[0]
1532 data_ccf = dataOut.data_pre[1]
1532 data_ccf = dataOut.data_pre[1]
1533 normFactor_acf = dataOut.normFactor[0]
1533 normFactor_acf = dataOut.normFactor[0]
1534 normFactor_ccf = dataOut.normFactor[1]
1534 normFactor_ccf = dataOut.normFactor[1]
1535 pairs_acf = dataOut.groupList[0]
1535 pairs_acf = dataOut.groupList[0]
1536 pairs_ccf = dataOut.groupList[1]
1536 pairs_ccf = dataOut.groupList[1]
1537
1537
1538 nHeights = dataOut.nHeights
1538 nHeights = dataOut.nHeights
1539 absc = dataOut.abscissaList
1539 absc = dataOut.abscissaList
1540 noise = dataOut.noise
1540 noise = dataOut.noise
1541 SNR = dataOut.data_SNR
1541 SNR = dataOut.data_SNR
1542 nChannels = dataOut.nChannels
1542 nChannels = dataOut.nChannels
1543 # pairsList = dataOut.groupList
1543 # pairsList = dataOut.groupList
1544 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
1544 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
1545
1545
1546 for l in range(len(pairs_acf)):
1546 for l in range(len(pairs_acf)):
1547 data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
1547 data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
1548
1548
1549 for l in range(len(pairs_ccf)):
1549 for l in range(len(pairs_ccf)):
1550 data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
1550 data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
1551
1551
1552 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
1552 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
1553 dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
1553 dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
1554 dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
1554 dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
1555 return
1555 return
1556
1556
1557 # def __getPairsAutoCorr(self, pairsList, nChannels):
1557 # def __getPairsAutoCorr(self, pairsList, nChannels):
1558 #
1558 #
1559 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1559 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1560 #
1560 #
1561 # for l in range(len(pairsList)):
1561 # for l in range(len(pairsList)):
1562 # firstChannel = pairsList[l][0]
1562 # firstChannel = pairsList[l][0]
1563 # secondChannel = pairsList[l][1]
1563 # secondChannel = pairsList[l][1]
1564 #
1564 #
1565 # #Obteniendo pares de Autocorrelacion
1565 # #Obteniendo pares de Autocorrelacion
1566 # if firstChannel == secondChannel:
1566 # if firstChannel == secondChannel:
1567 # pairsAutoCorr[firstChannel] = int(l)
1567 # pairsAutoCorr[firstChannel] = int(l)
1568 #
1568 #
1569 # pairsAutoCorr = pairsAutoCorr.astype(int)
1569 # pairsAutoCorr = pairsAutoCorr.astype(int)
1570 #
1570 #
1571 # pairsCrossCorr = range(len(pairsList))
1571 # pairsCrossCorr = range(len(pairsList))
1572 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1572 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1573 #
1573 #
1574 # return pairsAutoCorr, pairsCrossCorr
1574 # return pairsAutoCorr, pairsCrossCorr
1575
1575
1576 def __calculateTaus(self, data_acf, data_ccf, lagRange):
1576 def __calculateTaus(self, data_acf, data_ccf, lagRange):
1577
1577
1578 lag0 = data_acf.shape[1]/2
1578 lag0 = data_acf.shape[1]/2
1579 #Funcion de Autocorrelacion
1579 #Funcion de Autocorrelacion
1580 mean_acf = stats.nanmean(data_acf, axis = 0)
1580 mean_acf = stats.nanmean(data_acf, axis = 0)
1581
1581
1582 #Obtencion Indice de TauCross
1582 #Obtencion Indice de TauCross
1583 ind_ccf = data_ccf.argmax(axis = 1)
1583 ind_ccf = data_ccf.argmax(axis = 1)
1584 #Obtencion Indice de TauAuto
1584 #Obtencion Indice de TauAuto
1585 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
1585 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
1586 ccf_lag0 = data_ccf[:,lag0,:]
1586 ccf_lag0 = data_ccf[:,lag0,:]
1587
1587
1588 for i in range(ccf_lag0.shape[0]):
1588 for i in range(ccf_lag0.shape[0]):
1589 ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
1589 ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
1590
1590
1591 #Obtencion de TauCross y TauAuto
1591 #Obtencion de TauCross y TauAuto
1592 tau_ccf = lagRange[ind_ccf]
1592 tau_ccf = lagRange[ind_ccf]
1593 tau_acf = lagRange[ind_acf]
1593 tau_acf = lagRange[ind_acf]
1594
1594
1595 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
1595 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
1596
1596
1597 tau_ccf[Nan1,Nan2] = numpy.nan
1597 tau_ccf[Nan1,Nan2] = numpy.nan
1598 tau_acf[Nan1,Nan2] = numpy.nan
1598 tau_acf[Nan1,Nan2] = numpy.nan
1599 tau = numpy.vstack((tau_ccf,tau_acf))
1599 tau = numpy.vstack((tau_ccf,tau_acf))
1600
1600
1601 return tau
1601 return tau
1602
1602
1603 def __calculateLag1Phase(self, data, lagTRange):
1603 def __calculateLag1Phase(self, data, lagTRange):
1604 data1 = stats.nanmean(data, axis = 0)
1604 data1 = stats.nanmean(data, axis = 0)
1605 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
1605 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
1606
1606
1607 phase = numpy.angle(data1[lag1,:])
1607 phase = numpy.angle(data1[lag1,:])
1608
1608
1609 return phase
1609 return phase
1610
1610
1611 class SpectralFitting(Operation):
1611 class SpectralFitting(Operation):
1612 '''
1612 '''
1613 Function GetMoments()
1613 Function GetMoments()
1614
1614
1615 Input:
1615 Input:
1616 Output:
1616 Output:
1617 Variables modified:
1617 Variables modified:
1618 '''
1618 '''
1619
1619
1620 def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
1620 def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
1621
1621
1622
1622
1623 if path != None:
1623 if path != None:
1624 sys.path.append(path)
1624 sys.path.append(path)
1625 self.dataOut.library = importlib.import_module(file)
1625 self.dataOut.library = importlib.import_module(file)
1626
1626
1627 #To be inserted as a parameter
1627 #To be inserted as a parameter
1628 groupArray = numpy.array(groupList)
1628 groupArray = numpy.array(groupList)
1629 # groupArray = numpy.array([[0,1],[2,3]])
1629 # groupArray = numpy.array([[0,1],[2,3]])
1630 self.dataOut.groupList = groupArray
1630 self.dataOut.groupList = groupArray
1631
1631
1632 nGroups = groupArray.shape[0]
1632 nGroups = groupArray.shape[0]
1633 nChannels = self.dataIn.nChannels
1633 nChannels = self.dataIn.nChannels
1634 nHeights=self.dataIn.heightList.size
1634 nHeights=self.dataIn.heightList.size
1635
1635
1636 #Parameters Array
1636 #Parameters Array
1637 self.dataOut.data_param = None
1637 self.dataOut.data_param = None
1638
1638
1639 #Set constants
1639 #Set constants
1640 constants = self.dataOut.library.setConstants(self.dataIn)
1640 constants = self.dataOut.library.setConstants(self.dataIn)
1641 self.dataOut.constants = constants
1641 self.dataOut.constants = constants
1642 M = self.dataIn.normFactor
1642 M = self.dataIn.normFactor
1643 N = self.dataIn.nFFTPoints
1643 N = self.dataIn.nFFTPoints
1644 ippSeconds = self.dataIn.ippSeconds
1644 ippSeconds = self.dataIn.ippSeconds
1645 K = self.dataIn.nIncohInt
1645 K = self.dataIn.nIncohInt
1646 pairsArray = numpy.array(self.dataIn.pairsList)
1646 pairsArray = numpy.array(self.dataIn.pairsList)
1647
1647
1648 #List of possible combinations
1648 #List of possible combinations
1649 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1649 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1650 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1650 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1651
1651
1652 if getSNR:
1652 if getSNR:
1653 listChannels = groupArray.reshape((groupArray.size))
1653 listChannels = groupArray.reshape((groupArray.size))
1654 listChannels.sort()
1654 listChannels.sort()
1655 noise = self.dataIn.getNoise()
1655 noise = self.dataIn.getNoise()
1656 self.dataOut.data_SNR = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1656 self.dataOut.data_SNR = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1657
1657
1658 for i in range(nGroups):
1658 for i in range(nGroups):
1659 coord = groupArray[i,:]
1659 coord = groupArray[i,:]
1660
1660
1661 #Input data array
1661 #Input data array
1662 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1662 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1663 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1663 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1664
1664
1665 #Cross Spectra data array for Covariance Matrixes
1665 #Cross Spectra data array for Covariance Matrixes
1666 ind = 0
1666 ind = 0
1667 for pairs in listComb:
1667 for pairs in listComb:
1668 pairsSel = numpy.array([coord[x],coord[y]])
1668 pairsSel = numpy.array([coord[x],coord[y]])
1669 indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
1669 indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
1670 ind += 1
1670 ind += 1
1671 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1671 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1672 dataCross = dataCross**2/K
1672 dataCross = dataCross**2/K
1673
1673
1674 for h in range(nHeights):
1674 for h in range(nHeights):
1675 # print self.dataOut.heightList[h]
1675 # print self.dataOut.heightList[h]
1676
1676
1677 #Input
1677 #Input
1678 d = data[:,h]
1678 d = data[:,h]
1679
1679
1680 #Covariance Matrix
1680 #Covariance Matrix
1681 D = numpy.diag(d**2/K)
1681 D = numpy.diag(d**2/K)
1682 ind = 0
1682 ind = 0
1683 for pairs in listComb:
1683 for pairs in listComb:
1684 #Coordinates in Covariance Matrix
1684 #Coordinates in Covariance Matrix
1685 x = pairs[0]
1685 x = pairs[0]
1686 y = pairs[1]
1686 y = pairs[1]
1687 #Channel Index
1687 #Channel Index
1688 S12 = dataCross[ind,:,h]
1688 S12 = dataCross[ind,:,h]
1689 D12 = numpy.diag(S12)
1689 D12 = numpy.diag(S12)
1690 #Completing Covariance Matrix with Cross Spectras
1690 #Completing Covariance Matrix with Cross Spectras
1691 D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
1691 D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
1692 D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
1692 D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
1693 ind += 1
1693 ind += 1
1694 Dinv=numpy.linalg.inv(D)
1694 Dinv=numpy.linalg.inv(D)
1695 L=numpy.linalg.cholesky(Dinv)
1695 L=numpy.linalg.cholesky(Dinv)
1696 LT=L.T
1696 LT=L.T
1697
1697
1698 dp = numpy.dot(LT,d)
1698 dp = numpy.dot(LT,d)
1699
1699
1700 #Initial values
1700 #Initial values
1701 data_spc = self.dataIn.data_spc[coord,:,h]
1701 data_spc = self.dataIn.data_spc[coord,:,h]
1702
1702
1703 if (h>0)and(error1[3]<5):
1703 if (h>0)and(error1[3]<5):
1704 p0 = self.dataOut.data_param[i,:,h-1]
1704 p0 = self.dataOut.data_param[i,:,h-1]
1705 else:
1705 else:
1706 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1706 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1707
1707
1708 try:
1708 try:
1709 #Least Squares
1709 #Least Squares
1710 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
1710 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
1711 # minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
1711 # minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
1712 #Chi square error
1712 #Chi square error
1713 error0 = numpy.sum(infodict['fvec']**2)/(2*N)
1713 error0 = numpy.sum(infodict['fvec']**2)/(2*N)
1714 #Error with Jacobian
1714 #Error with Jacobian
1715 error1 = self.dataOut.library.errorFunction(minp,constants,LT)
1715 error1 = self.dataOut.library.errorFunction(minp,constants,LT)
1716 except:
1716 except:
1717 minp = p0*numpy.nan
1717 minp = p0*numpy.nan
1718 error0 = numpy.nan
1718 error0 = numpy.nan
1719 error1 = p0*numpy.nan
1719 error1 = p0*numpy.nan
1720
1720
1721 #Save
1721 #Save
1722 if self.dataOut.data_param == None:
1722 if self.dataOut.data_param is None:
1723 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1723 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1724 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1724 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1725
1725
1726 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1726 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1727 self.dataOut.data_param[i,:,h] = minp
1727 self.dataOut.data_param[i,:,h] = minp
1728 return
1728 return
1729
1729
1730 def __residFunction(self, p, dp, LT, constants):
1730 def __residFunction(self, p, dp, LT, constants):
1731
1731
1732 fm = self.dataOut.library.modelFunction(p, constants)
1732 fm = self.dataOut.library.modelFunction(p, constants)
1733 fmp=numpy.dot(LT,fm)
1733 fmp=numpy.dot(LT,fm)
1734
1734
1735 return dp-fmp
1735 return dp-fmp
1736
1736
1737 def __getSNR(self, z, noise):
1737 def __getSNR(self, z, noise):
1738
1738
1739 avg = numpy.average(z, axis=1)
1739 avg = numpy.average(z, axis=1)
1740 SNR = (avg.T-noise)/noise
1740 SNR = (avg.T-noise)/noise
1741 SNR = SNR.T
1741 SNR = SNR.T
1742 return SNR
1742 return SNR
1743
1743
1744 def __chisq(p,chindex,hindex):
1744 def __chisq(p,chindex,hindex):
1745 #similar to Resid but calculates CHI**2
1745 #similar to Resid but calculates CHI**2
1746 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
1746 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
1747 dp=numpy.dot(LT,d)
1747 dp=numpy.dot(LT,d)
1748 fmp=numpy.dot(LT,fm)
1748 fmp=numpy.dot(LT,fm)
1749 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1749 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1750 return chisq
1750 return chisq
1751
1751
1752 class WindProfiler(Operation):
1752 class WindProfiler(Operation):
1753
1753
1754 __isConfig = False
1754 __isConfig = False
1755
1755
1756 __initime = None
1756 __initime = None
1757 __lastdatatime = None
1757 __lastdatatime = None
1758 __integrationtime = None
1758 __integrationtime = None
1759
1759
1760 __buffer = None
1760 __buffer = None
1761
1761
1762 __dataReady = False
1762 __dataReady = False
1763
1763
1764 __firstdata = None
1764 __firstdata = None
1765
1765
1766 n = None
1766 n = None
1767
1767
1768 def __init__(self, **kwargs):
1768 def __init__(self, **kwargs):
1769 Operation.__init__(self, **kwargs)
1769 Operation.__init__(self, **kwargs)
1770
1770
1771 def __calculateCosDir(self, elev, azim):
1771 def __calculateCosDir(self, elev, azim):
1772 zen = (90 - elev)*numpy.pi/180
1772 zen = (90 - elev)*numpy.pi/180
1773 azim = azim*numpy.pi/180
1773 azim = azim*numpy.pi/180
1774 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1774 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1775 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1775 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1776
1776
1777 signX = numpy.sign(numpy.cos(azim))
1777 signX = numpy.sign(numpy.cos(azim))
1778 signY = numpy.sign(numpy.sin(azim))
1778 signY = numpy.sign(numpy.sin(azim))
1779
1779
1780 cosDirX = numpy.copysign(cosDirX, signX)
1780 cosDirX = numpy.copysign(cosDirX, signX)
1781 cosDirY = numpy.copysign(cosDirY, signY)
1781 cosDirY = numpy.copysign(cosDirY, signY)
1782 return cosDirX, cosDirY
1782 return cosDirX, cosDirY
1783
1783
1784 def __calculateAngles(self, theta_x, theta_y, azimuth):
1784 def __calculateAngles(self, theta_x, theta_y, azimuth):
1785
1785
1786 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1786 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1787 zenith_arr = numpy.arccos(dir_cosw)
1787 zenith_arr = numpy.arccos(dir_cosw)
1788 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1788 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1789
1789
1790 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1790 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1791 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1791 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1792
1792
1793 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1793 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1794
1794
1795 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1795 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1796
1796
1797 #
1797 #
1798 if horOnly:
1798 if horOnly:
1799 A = numpy.c_[dir_cosu,dir_cosv]
1799 A = numpy.c_[dir_cosu,dir_cosv]
1800 else:
1800 else:
1801 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
1801 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
1802 A = numpy.asmatrix(A)
1802 A = numpy.asmatrix(A)
1803 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
1803 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
1804
1804
1805 return A1
1805 return A1
1806
1806
1807 def __correctValues(self, heiRang, phi, velRadial, SNR):
1807 def __correctValues(self, heiRang, phi, velRadial, SNR):
1808 listPhi = phi.tolist()
1808 listPhi = phi.tolist()
1809 maxid = listPhi.index(max(listPhi))
1809 maxid = listPhi.index(max(listPhi))
1810 minid = listPhi.index(min(listPhi))
1810 minid = listPhi.index(min(listPhi))
1811
1811
1812 rango = range(len(phi))
1812 rango = range(len(phi))
1813 # rango = numpy.delete(rango,maxid)
1813 # rango = numpy.delete(rango,maxid)
1814
1814
1815 heiRang1 = heiRang*math.cos(phi[maxid])
1815 heiRang1 = heiRang*math.cos(phi[maxid])
1816 heiRangAux = heiRang*math.cos(phi[minid])
1816 heiRangAux = heiRang*math.cos(phi[minid])
1817 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1817 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1818 heiRang1 = numpy.delete(heiRang1,indOut)
1818 heiRang1 = numpy.delete(heiRang1,indOut)
1819
1819
1820 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1820 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1821 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1821 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1822
1822
1823 for i in rango:
1823 for i in rango:
1824 x = heiRang*math.cos(phi[i])
1824 x = heiRang*math.cos(phi[i])
1825 y1 = velRadial[i,:]
1825 y1 = velRadial[i,:]
1826 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1826 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1827
1827
1828 x1 = heiRang1
1828 x1 = heiRang1
1829 y11 = f1(x1)
1829 y11 = f1(x1)
1830
1830
1831 y2 = SNR[i,:]
1831 y2 = SNR[i,:]
1832 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1832 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1833 y21 = f2(x1)
1833 y21 = f2(x1)
1834
1834
1835 velRadial1[i,:] = y11
1835 velRadial1[i,:] = y11
1836 SNR1[i,:] = y21
1836 SNR1[i,:] = y21
1837
1837
1838 return heiRang1, velRadial1, SNR1
1838 return heiRang1, velRadial1, SNR1
1839
1839
1840 def __calculateVelUVW(self, A, velRadial):
1840 def __calculateVelUVW(self, A, velRadial):
1841
1841
1842 #Operacion Matricial
1842 #Operacion Matricial
1843 # velUVW = numpy.zeros((velRadial.shape[1],3))
1843 # velUVW = numpy.zeros((velRadial.shape[1],3))
1844 # for ind in range(velRadial.shape[1]):
1844 # for ind in range(velRadial.shape[1]):
1845 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
1845 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
1846 # velUVW = velUVW.transpose()
1846 # velUVW = velUVW.transpose()
1847 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1847 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1848 velUVW[:,:] = numpy.dot(A,velRadial)
1848 velUVW[:,:] = numpy.dot(A,velRadial)
1849
1849
1850
1850
1851 return velUVW
1851 return velUVW
1852
1852
1853 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1853 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1854
1854
1855 def techniqueDBS(self, kwargs):
1855 def techniqueDBS(self, kwargs):
1856 """
1856 """
1857 Function that implements Doppler Beam Swinging (DBS) technique.
1857 Function that implements Doppler Beam Swinging (DBS) technique.
1858
1858
1859 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1859 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1860 Direction correction (if necessary), Ranges and SNR
1860 Direction correction (if necessary), Ranges and SNR
1861
1861
1862 Output: Winds estimation (Zonal, Meridional and Vertical)
1862 Output: Winds estimation (Zonal, Meridional and Vertical)
1863
1863
1864 Parameters affected: Winds, height range, SNR
1864 Parameters affected: Winds, height range, SNR
1865 """
1865 """
1866 velRadial0 = kwargs['velRadial']
1866 velRadial0 = kwargs['velRadial']
1867 heiRang = kwargs['heightList']
1867 heiRang = kwargs['heightList']
1868 SNR0 = kwargs['SNR']
1868 SNR0 = kwargs['SNR']
1869
1869
1870 if kwargs.has_key('dirCosx') and kwargs.has_key('dirCosy'):
1870 if kwargs.has_key('dirCosx') and kwargs.has_key('dirCosy'):
1871 theta_x = numpy.array(kwargs['dirCosx'])
1871 theta_x = numpy.array(kwargs['dirCosx'])
1872 theta_y = numpy.array(kwargs['dirCosy'])
1872 theta_y = numpy.array(kwargs['dirCosy'])
1873 else:
1873 else:
1874 elev = numpy.array(kwargs['elevation'])
1874 elev = numpy.array(kwargs['elevation'])
1875 azim = numpy.array(kwargs['azimuth'])
1875 azim = numpy.array(kwargs['azimuth'])
1876 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1876 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1877 azimuth = kwargs['correctAzimuth']
1877 azimuth = kwargs['correctAzimuth']
1878 if kwargs.has_key('horizontalOnly'):
1878 if kwargs.has_key('horizontalOnly'):
1879 horizontalOnly = kwargs['horizontalOnly']
1879 horizontalOnly = kwargs['horizontalOnly']
1880 else: horizontalOnly = False
1880 else: horizontalOnly = False
1881 if kwargs.has_key('correctFactor'):
1881 if kwargs.has_key('correctFactor'):
1882 correctFactor = kwargs['correctFactor']
1882 correctFactor = kwargs['correctFactor']
1883 else: correctFactor = 1
1883 else: correctFactor = 1
1884 if kwargs.has_key('channelList'):
1884 if kwargs.has_key('channelList'):
1885 channelList = kwargs['channelList']
1885 channelList = kwargs['channelList']
1886 if len(channelList) == 2:
1886 if len(channelList) == 2:
1887 horizontalOnly = True
1887 horizontalOnly = True
1888 arrayChannel = numpy.array(channelList)
1888 arrayChannel = numpy.array(channelList)
1889 param = param[arrayChannel,:,:]
1889 param = param[arrayChannel,:,:]
1890 theta_x = theta_x[arrayChannel]
1890 theta_x = theta_x[arrayChannel]
1891 theta_y = theta_y[arrayChannel]
1891 theta_y = theta_y[arrayChannel]
1892
1892
1893 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
1893 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
1894 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
1894 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
1895 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1895 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1896
1896
1897 #Calculo de Componentes de la velocidad con DBS
1897 #Calculo de Componentes de la velocidad con DBS
1898 winds = self.__calculateVelUVW(A,velRadial1)
1898 winds = self.__calculateVelUVW(A,velRadial1)
1899
1899
1900 return winds, heiRang1, SNR1
1900 return winds, heiRang1, SNR1
1901
1901
1902 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
1902 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
1903
1903
1904 nPairs = len(pairs_ccf)
1904 nPairs = len(pairs_ccf)
1905 posx = numpy.asarray(posx)
1905 posx = numpy.asarray(posx)
1906 posy = numpy.asarray(posy)
1906 posy = numpy.asarray(posy)
1907
1907
1908 #Rotacion Inversa para alinear con el azimuth
1908 #Rotacion Inversa para alinear con el azimuth
1909 if azimuth!= None:
1909 if azimuth!= None:
1910 azimuth = azimuth*math.pi/180
1910 azimuth = azimuth*math.pi/180
1911 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
1911 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
1912 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
1912 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
1913 else:
1913 else:
1914 posx1 = posx
1914 posx1 = posx
1915 posy1 = posy
1915 posy1 = posy
1916
1916
1917 #Calculo de Distancias
1917 #Calculo de Distancias
1918 distx = numpy.zeros(nPairs)
1918 distx = numpy.zeros(nPairs)
1919 disty = numpy.zeros(nPairs)
1919 disty = numpy.zeros(nPairs)
1920 dist = numpy.zeros(nPairs)
1920 dist = numpy.zeros(nPairs)
1921 ang = numpy.zeros(nPairs)
1921 ang = numpy.zeros(nPairs)
1922
1922
1923 for i in range(nPairs):
1923 for i in range(nPairs):
1924 distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
1924 distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
1925 disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
1925 disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
1926 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1926 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1927 ang[i] = numpy.arctan2(disty[i],distx[i])
1927 ang[i] = numpy.arctan2(disty[i],distx[i])
1928
1928
1929 return distx, disty, dist, ang
1929 return distx, disty, dist, ang
1930 #Calculo de Matrices
1930 #Calculo de Matrices
1931 # nPairs = len(pairs)
1931 # nPairs = len(pairs)
1932 # ang1 = numpy.zeros((nPairs, 2, 1))
1932 # ang1 = numpy.zeros((nPairs, 2, 1))
1933 # dist1 = numpy.zeros((nPairs, 2, 1))
1933 # dist1 = numpy.zeros((nPairs, 2, 1))
1934 #
1934 #
1935 # for j in range(nPairs):
1935 # for j in range(nPairs):
1936 # dist1[j,0,0] = dist[pairs[j][0]]
1936 # dist1[j,0,0] = dist[pairs[j][0]]
1937 # dist1[j,1,0] = dist[pairs[j][1]]
1937 # dist1[j,1,0] = dist[pairs[j][1]]
1938 # ang1[j,0,0] = ang[pairs[j][0]]
1938 # ang1[j,0,0] = ang[pairs[j][0]]
1939 # ang1[j,1,0] = ang[pairs[j][1]]
1939 # ang1[j,1,0] = ang[pairs[j][1]]
1940 #
1940 #
1941 # return distx,disty, dist1,ang1
1941 # return distx,disty, dist1,ang1
1942
1942
1943
1943
1944 def __calculateVelVer(self, phase, lagTRange, _lambda):
1944 def __calculateVelVer(self, phase, lagTRange, _lambda):
1945
1945
1946 Ts = lagTRange[1] - lagTRange[0]
1946 Ts = lagTRange[1] - lagTRange[0]
1947 velW = -_lambda*phase/(4*math.pi*Ts)
1947 velW = -_lambda*phase/(4*math.pi*Ts)
1948
1948
1949 return velW
1949 return velW
1950
1950
1951 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1951 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1952 nPairs = tau1.shape[0]
1952 nPairs = tau1.shape[0]
1953 nHeights = tau1.shape[1]
1953 nHeights = tau1.shape[1]
1954 vel = numpy.zeros((nPairs,3,nHeights))
1954 vel = numpy.zeros((nPairs,3,nHeights))
1955 dist1 = numpy.reshape(dist, (dist.size,1))
1955 dist1 = numpy.reshape(dist, (dist.size,1))
1956
1956
1957 angCos = numpy.cos(ang)
1957 angCos = numpy.cos(ang)
1958 angSin = numpy.sin(ang)
1958 angSin = numpy.sin(ang)
1959
1959
1960 vel0 = dist1*tau1/(2*tau2**2)
1960 vel0 = dist1*tau1/(2*tau2**2)
1961 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1961 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1962 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1962 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1963
1963
1964 ind = numpy.where(numpy.isinf(vel))
1964 ind = numpy.where(numpy.isinf(vel))
1965 vel[ind] = numpy.nan
1965 vel[ind] = numpy.nan
1966
1966
1967 return vel
1967 return vel
1968
1968
1969 # def __getPairsAutoCorr(self, pairsList, nChannels):
1969 # def __getPairsAutoCorr(self, pairsList, nChannels):
1970 #
1970 #
1971 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1971 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1972 #
1972 #
1973 # for l in range(len(pairsList)):
1973 # for l in range(len(pairsList)):
1974 # firstChannel = pairsList[l][0]
1974 # firstChannel = pairsList[l][0]
1975 # secondChannel = pairsList[l][1]
1975 # secondChannel = pairsList[l][1]
1976 #
1976 #
1977 # #Obteniendo pares de Autocorrelacion
1977 # #Obteniendo pares de Autocorrelacion
1978 # if firstChannel == secondChannel:
1978 # if firstChannel == secondChannel:
1979 # pairsAutoCorr[firstChannel] = int(l)
1979 # pairsAutoCorr[firstChannel] = int(l)
1980 #
1980 #
1981 # pairsAutoCorr = pairsAutoCorr.astype(int)
1981 # pairsAutoCorr = pairsAutoCorr.astype(int)
1982 #
1982 #
1983 # pairsCrossCorr = range(len(pairsList))
1983 # pairsCrossCorr = range(len(pairsList))
1984 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1984 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1985 #
1985 #
1986 # return pairsAutoCorr, pairsCrossCorr
1986 # return pairsAutoCorr, pairsCrossCorr
1987
1987
1988 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1988 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1989 def techniqueSA(self, kwargs):
1989 def techniqueSA(self, kwargs):
1990
1990
1991 """
1991 """
1992 Function that implements Spaced Antenna (SA) technique.
1992 Function that implements Spaced Antenna (SA) technique.
1993
1993
1994 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1994 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1995 Direction correction (if necessary), Ranges and SNR
1995 Direction correction (if necessary), Ranges and SNR
1996
1996
1997 Output: Winds estimation (Zonal, Meridional and Vertical)
1997 Output: Winds estimation (Zonal, Meridional and Vertical)
1998
1998
1999 Parameters affected: Winds
1999 Parameters affected: Winds
2000 """
2000 """
2001 position_x = kwargs['positionX']
2001 position_x = kwargs['positionX']
2002 position_y = kwargs['positionY']
2002 position_y = kwargs['positionY']
2003 azimuth = kwargs['azimuth']
2003 azimuth = kwargs['azimuth']
2004
2004
2005 if kwargs.has_key('correctFactor'):
2005 if kwargs.has_key('correctFactor'):
2006 correctFactor = kwargs['correctFactor']
2006 correctFactor = kwargs['correctFactor']
2007 else:
2007 else:
2008 correctFactor = 1
2008 correctFactor = 1
2009
2009
2010 groupList = kwargs['groupList']
2010 groupList = kwargs['groupList']
2011 pairs_ccf = groupList[1]
2011 pairs_ccf = groupList[1]
2012 tau = kwargs['tau']
2012 tau = kwargs['tau']
2013 _lambda = kwargs['_lambda']
2013 _lambda = kwargs['_lambda']
2014
2014
2015 #Cross Correlation pairs obtained
2015 #Cross Correlation pairs obtained
2016 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
2016 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
2017 # pairsArray = numpy.array(pairsList)[pairsCrossCorr]
2017 # pairsArray = numpy.array(pairsList)[pairsCrossCorr]
2018 # pairsSelArray = numpy.array(pairsSelected)
2018 # pairsSelArray = numpy.array(pairsSelected)
2019 # pairs = []
2019 # pairs = []
2020 #
2020 #
2021 # #Wind estimation pairs obtained
2021 # #Wind estimation pairs obtained
2022 # for i in range(pairsSelArray.shape[0]/2):
2022 # for i in range(pairsSelArray.shape[0]/2):
2023 # ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
2023 # ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
2024 # ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
2024 # ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
2025 # pairs.append((ind1,ind2))
2025 # pairs.append((ind1,ind2))
2026
2026
2027 indtau = tau.shape[0]/2
2027 indtau = tau.shape[0]/2
2028 tau1 = tau[:indtau,:]
2028 tau1 = tau[:indtau,:]
2029 tau2 = tau[indtau:-1,:]
2029 tau2 = tau[indtau:-1,:]
2030 # tau1 = tau1[pairs,:]
2030 # tau1 = tau1[pairs,:]
2031 # tau2 = tau2[pairs,:]
2031 # tau2 = tau2[pairs,:]
2032 phase1 = tau[-1,:]
2032 phase1 = tau[-1,:]
2033
2033
2034 #---------------------------------------------------------------------
2034 #---------------------------------------------------------------------
2035 #Metodo Directo
2035 #Metodo Directo
2036 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
2036 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
2037 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
2037 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
2038 winds = stats.nanmean(winds, axis=0)
2038 winds = stats.nanmean(winds, axis=0)
2039 #---------------------------------------------------------------------
2039 #---------------------------------------------------------------------
2040 #Metodo General
2040 #Metodo General
2041 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
2041 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
2042 # #Calculo Coeficientes de Funcion de Correlacion
2042 # #Calculo Coeficientes de Funcion de Correlacion
2043 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
2043 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
2044 # #Calculo de Velocidades
2044 # #Calculo de Velocidades
2045 # winds = self.calculateVelUV(F,G,A,B,H)
2045 # winds = self.calculateVelUV(F,G,A,B,H)
2046
2046
2047 #---------------------------------------------------------------------
2047 #---------------------------------------------------------------------
2048 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
2048 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
2049 winds = correctFactor*winds
2049 winds = correctFactor*winds
2050 return winds
2050 return winds
2051
2051
2052 def __checkTime(self, currentTime, paramInterval, outputInterval):
2052 def __checkTime(self, currentTime, paramInterval, outputInterval):
2053
2053
2054 dataTime = currentTime + paramInterval
2054 dataTime = currentTime + paramInterval
2055 deltaTime = dataTime - self.__initime
2055 deltaTime = dataTime - self.__initime
2056
2056
2057 if deltaTime >= outputInterval or deltaTime < 0:
2057 if deltaTime >= outputInterval or deltaTime < 0:
2058 self.__dataReady = True
2058 self.__dataReady = True
2059 return
2059 return
2060
2060
2061 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
2061 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
2062 '''
2062 '''
2063 Function that implements winds estimation technique with detected meteors.
2063 Function that implements winds estimation technique with detected meteors.
2064
2064
2065 Input: Detected meteors, Minimum meteor quantity to wind estimation
2065 Input: Detected meteors, Minimum meteor quantity to wind estimation
2066
2066
2067 Output: Winds estimation (Zonal and Meridional)
2067 Output: Winds estimation (Zonal and Meridional)
2068
2068
2069 Parameters affected: Winds
2069 Parameters affected: Winds
2070 '''
2070 '''
2071 # print arrayMeteor.shape
2071 # print arrayMeteor.shape
2072 #Settings
2072 #Settings
2073 nInt = (heightMax - heightMin)/2
2073 nInt = (heightMax - heightMin)/2
2074 # print nInt
2074 # print nInt
2075 nInt = int(nInt)
2075 nInt = int(nInt)
2076 # print nInt
2076 # print nInt
2077 winds = numpy.zeros((2,nInt))*numpy.nan
2077 winds = numpy.zeros((2,nInt))*numpy.nan
2078
2078
2079 #Filter errors
2079 #Filter errors
2080 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
2080 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
2081 finalMeteor = arrayMeteor[error,:]
2081 finalMeteor = arrayMeteor[error,:]
2082
2082
2083 #Meteor Histogram
2083 #Meteor Histogram
2084 finalHeights = finalMeteor[:,2]
2084 finalHeights = finalMeteor[:,2]
2085 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
2085 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
2086 nMeteorsPerI = hist[0]
2086 nMeteorsPerI = hist[0]
2087 heightPerI = hist[1]
2087 heightPerI = hist[1]
2088
2088
2089 #Sort of meteors
2089 #Sort of meteors
2090 indSort = finalHeights.argsort()
2090 indSort = finalHeights.argsort()
2091 finalMeteor2 = finalMeteor[indSort,:]
2091 finalMeteor2 = finalMeteor[indSort,:]
2092
2092
2093 # Calculating winds
2093 # Calculating winds
2094 ind1 = 0
2094 ind1 = 0
2095 ind2 = 0
2095 ind2 = 0
2096
2096
2097 for i in range(nInt):
2097 for i in range(nInt):
2098 nMet = nMeteorsPerI[i]
2098 nMet = nMeteorsPerI[i]
2099 ind1 = ind2
2099 ind1 = ind2
2100 ind2 = ind1 + nMet
2100 ind2 = ind1 + nMet
2101
2101
2102 meteorAux = finalMeteor2[ind1:ind2,:]
2102 meteorAux = finalMeteor2[ind1:ind2,:]
2103
2103
2104 if meteorAux.shape[0] >= meteorThresh:
2104 if meteorAux.shape[0] >= meteorThresh:
2105 vel = meteorAux[:, 6]
2105 vel = meteorAux[:, 6]
2106 zen = meteorAux[:, 4]*numpy.pi/180
2106 zen = meteorAux[:, 4]*numpy.pi/180
2107 azim = meteorAux[:, 3]*numpy.pi/180
2107 azim = meteorAux[:, 3]*numpy.pi/180
2108
2108
2109 n = numpy.cos(zen)
2109 n = numpy.cos(zen)
2110 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
2110 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
2111 # l = m*numpy.tan(azim)
2111 # l = m*numpy.tan(azim)
2112 l = numpy.sin(zen)*numpy.sin(azim)
2112 l = numpy.sin(zen)*numpy.sin(azim)
2113 m = numpy.sin(zen)*numpy.cos(azim)
2113 m = numpy.sin(zen)*numpy.cos(azim)
2114
2114
2115 A = numpy.vstack((l, m)).transpose()
2115 A = numpy.vstack((l, m)).transpose()
2116 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
2116 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
2117 windsAux = numpy.dot(A1, vel)
2117 windsAux = numpy.dot(A1, vel)
2118
2118
2119 winds[0,i] = windsAux[0]
2119 winds[0,i] = windsAux[0]
2120 winds[1,i] = windsAux[1]
2120 winds[1,i] = windsAux[1]
2121
2121
2122 return winds, heightPerI[:-1]
2122 return winds, heightPerI[:-1]
2123
2123
2124 def techniqueNSM_SA(self, **kwargs):
2124 def techniqueNSM_SA(self, **kwargs):
2125 metArray = kwargs['metArray']
2125 metArray = kwargs['metArray']
2126 heightList = kwargs['heightList']
2126 heightList = kwargs['heightList']
2127 timeList = kwargs['timeList']
2127 timeList = kwargs['timeList']
2128
2128
2129 rx_location = kwargs['rx_location']
2129 rx_location = kwargs['rx_location']
2130 groupList = kwargs['groupList']
2130 groupList = kwargs['groupList']
2131 azimuth = kwargs['azimuth']
2131 azimuth = kwargs['azimuth']
2132 dfactor = kwargs['dfactor']
2132 dfactor = kwargs['dfactor']
2133 k = kwargs['k']
2133 k = kwargs['k']
2134
2134
2135 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
2135 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
2136 d = dist*dfactor
2136 d = dist*dfactor
2137 #Phase calculation
2137 #Phase calculation
2138 metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
2138 metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
2139
2139
2140 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
2140 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
2141
2141
2142 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2142 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2143 azimuth1 = azimuth1*numpy.pi/180
2143 azimuth1 = azimuth1*numpy.pi/180
2144
2144
2145 for i in range(heightList.size):
2145 for i in range(heightList.size):
2146 h = heightList[i]
2146 h = heightList[i]
2147 indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
2147 indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
2148 metHeight = metArray1[indH,:]
2148 metHeight = metArray1[indH,:]
2149 if metHeight.shape[0] >= 2:
2149 if metHeight.shape[0] >= 2:
2150 velAux = numpy.asmatrix(metHeight[:,-2]).T #Radial Velocities
2150 velAux = numpy.asmatrix(metHeight[:,-2]).T #Radial Velocities
2151 iazim = metHeight[:,1].astype(int)
2151 iazim = metHeight[:,1].astype(int)
2152 azimAux = numpy.asmatrix(azimuth1[iazim]).T #Azimuths
2152 azimAux = numpy.asmatrix(azimuth1[iazim]).T #Azimuths
2153 A = numpy.hstack((numpy.cos(azimAux),numpy.sin(azimAux)))
2153 A = numpy.hstack((numpy.cos(azimAux),numpy.sin(azimAux)))
2154 A = numpy.asmatrix(A)
2154 A = numpy.asmatrix(A)
2155 A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
2155 A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
2156 velHor = numpy.dot(A1,velAux)
2156 velHor = numpy.dot(A1,velAux)
2157
2157
2158 velEst[i,:] = numpy.squeeze(velHor)
2158 velEst[i,:] = numpy.squeeze(velHor)
2159 return velEst
2159 return velEst
2160
2160
2161 def __getPhaseSlope(self, metArray, heightList, timeList):
2161 def __getPhaseSlope(self, metArray, heightList, timeList):
2162 meteorList = []
2162 meteorList = []
2163 #utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
2163 #utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
2164 #Putting back together the meteor matrix
2164 #Putting back together the meteor matrix
2165 utctime = metArray[:,0]
2165 utctime = metArray[:,0]
2166 uniqueTime = numpy.unique(utctime)
2166 uniqueTime = numpy.unique(utctime)
2167
2167
2168 phaseDerThresh = 0.5
2168 phaseDerThresh = 0.5
2169 ippSeconds = timeList[1] - timeList[0]
2169 ippSeconds = timeList[1] - timeList[0]
2170 sec = numpy.where(timeList>1)[0][0]
2170 sec = numpy.where(timeList>1)[0][0]
2171 nPairs = metArray.shape[1] - 6
2171 nPairs = metArray.shape[1] - 6
2172 nHeights = len(heightList)
2172 nHeights = len(heightList)
2173
2173
2174 for t in uniqueTime:
2174 for t in uniqueTime:
2175 metArray1 = metArray[utctime==t,:]
2175 metArray1 = metArray[utctime==t,:]
2176 # phaseDerThresh = numpy.pi/4 #reducir Phase thresh
2176 # phaseDerThresh = numpy.pi/4 #reducir Phase thresh
2177 tmet = metArray1[:,1].astype(int)
2177 tmet = metArray1[:,1].astype(int)
2178 hmet = metArray1[:,2].astype(int)
2178 hmet = metArray1[:,2].astype(int)
2179
2179
2180 metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
2180 metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
2181 metPhase[:,:] = numpy.nan
2181 metPhase[:,:] = numpy.nan
2182 metPhase[:,hmet,tmet] = metArray1[:,6:].T
2182 metPhase[:,hmet,tmet] = metArray1[:,6:].T
2183
2183
2184 #Delete short trails
2184 #Delete short trails
2185 metBool = ~numpy.isnan(metPhase[0,:,:])
2185 metBool = ~numpy.isnan(metPhase[0,:,:])
2186 heightVect = numpy.sum(metBool, axis = 1)
2186 heightVect = numpy.sum(metBool, axis = 1)
2187 metBool[heightVect<sec,:] = False
2187 metBool[heightVect<sec,:] = False
2188 metPhase[:,heightVect<sec,:] = numpy.nan
2188 metPhase[:,heightVect<sec,:] = numpy.nan
2189
2189
2190 #Derivative
2190 #Derivative
2191 metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
2191 metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
2192 phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
2192 phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
2193 metPhase[phDerAux] = numpy.nan
2193 metPhase[phDerAux] = numpy.nan
2194
2194
2195 #--------------------------METEOR DETECTION -----------------------------------------
2195 #--------------------------METEOR DETECTION -----------------------------------------
2196 indMet = numpy.where(numpy.any(metBool,axis=1))[0]
2196 indMet = numpy.where(numpy.any(metBool,axis=1))[0]
2197
2197
2198 for p in numpy.arange(nPairs):
2198 for p in numpy.arange(nPairs):
2199 phase = metPhase[p,:,:]
2199 phase = metPhase[p,:,:]
2200 phDer = metDer[p,:,:]
2200 phDer = metDer[p,:,:]
2201
2201
2202 for h in indMet:
2202 for h in indMet:
2203 height = heightList[h]
2203 height = heightList[h]
2204 phase1 = phase[h,:] #82
2204 phase1 = phase[h,:] #82
2205 phDer1 = phDer[h,:]
2205 phDer1 = phDer[h,:]
2206
2206
2207 phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
2207 phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
2208
2208
2209 indValid = numpy.where(~numpy.isnan(phase1))[0]
2209 indValid = numpy.where(~numpy.isnan(phase1))[0]
2210 initMet = indValid[0]
2210 initMet = indValid[0]
2211 endMet = 0
2211 endMet = 0
2212
2212
2213 for i in range(len(indValid)-1):
2213 for i in range(len(indValid)-1):
2214
2214
2215 #Time difference
2215 #Time difference
2216 inow = indValid[i]
2216 inow = indValid[i]
2217 inext = indValid[i+1]
2217 inext = indValid[i+1]
2218 idiff = inext - inow
2218 idiff = inext - inow
2219 #Phase difference
2219 #Phase difference
2220 phDiff = numpy.abs(phase1[inext] - phase1[inow])
2220 phDiff = numpy.abs(phase1[inext] - phase1[inow])
2221
2221
2222 if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
2222 if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
2223 sizeTrail = inow - initMet + 1
2223 sizeTrail = inow - initMet + 1
2224 if sizeTrail>3*sec: #Too short meteors
2224 if sizeTrail>3*sec: #Too short meteors
2225 x = numpy.arange(initMet,inow+1)*ippSeconds
2225 x = numpy.arange(initMet,inow+1)*ippSeconds
2226 y = phase1[initMet:inow+1]
2226 y = phase1[initMet:inow+1]
2227 ynnan = ~numpy.isnan(y)
2227 ynnan = ~numpy.isnan(y)
2228 x = x[ynnan]
2228 x = x[ynnan]
2229 y = y[ynnan]
2229 y = y[ynnan]
2230 slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
2230 slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
2231 ylin = x*slope + intercept
2231 ylin = x*slope + intercept
2232 rsq = r_value**2
2232 rsq = r_value**2
2233 if rsq > 0.5:
2233 if rsq > 0.5:
2234 vel = slope#*height*1000/(k*d)
2234 vel = slope#*height*1000/(k*d)
2235 estAux = numpy.array([utctime,p,height, vel, rsq])
2235 estAux = numpy.array([utctime,p,height, vel, rsq])
2236 meteorList.append(estAux)
2236 meteorList.append(estAux)
2237 initMet = inext
2237 initMet = inext
2238 metArray2 = numpy.array(meteorList)
2238 metArray2 = numpy.array(meteorList)
2239
2239
2240 return metArray2
2240 return metArray2
2241
2241
2242 def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
2242 def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
2243
2243
2244 azimuth1 = numpy.zeros(len(pairslist))
2244 azimuth1 = numpy.zeros(len(pairslist))
2245 dist = numpy.zeros(len(pairslist))
2245 dist = numpy.zeros(len(pairslist))
2246
2246
2247 for i in range(len(rx_location)):
2247 for i in range(len(rx_location)):
2248 ch0 = pairslist[i][0]
2248 ch0 = pairslist[i][0]
2249 ch1 = pairslist[i][1]
2249 ch1 = pairslist[i][1]
2250
2250
2251 diffX = rx_location[ch0][0] - rx_location[ch1][0]
2251 diffX = rx_location[ch0][0] - rx_location[ch1][0]
2252 diffY = rx_location[ch0][1] - rx_location[ch1][1]
2252 diffY = rx_location[ch0][1] - rx_location[ch1][1]
2253 azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
2253 azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
2254 dist[i] = numpy.sqrt(diffX**2 + diffY**2)
2254 dist[i] = numpy.sqrt(diffX**2 + diffY**2)
2255
2255
2256 azimuth1 -= azimuth0
2256 azimuth1 -= azimuth0
2257 return azimuth1, dist
2257 return azimuth1, dist
2258
2258
2259 def techniqueNSM_DBS(self, **kwargs):
2259 def techniqueNSM_DBS(self, **kwargs):
2260 metArray = kwargs['metArray']
2260 metArray = kwargs['metArray']
2261 heightList = kwargs['heightList']
2261 heightList = kwargs['heightList']
2262 timeList = kwargs['timeList']
2262 timeList = kwargs['timeList']
2263 azimuth = kwargs['azimuth']
2263 azimuth = kwargs['azimuth']
2264 theta_x = numpy.array(kwargs['theta_x'])
2264 theta_x = numpy.array(kwargs['theta_x'])
2265 theta_y = numpy.array(kwargs['theta_y'])
2265 theta_y = numpy.array(kwargs['theta_y'])
2266
2266
2267 utctime = metArray[:,0]
2267 utctime = metArray[:,0]
2268 cmet = metArray[:,1].astype(int)
2268 cmet = metArray[:,1].astype(int)
2269 hmet = metArray[:,3].astype(int)
2269 hmet = metArray[:,3].astype(int)
2270 SNRmet = metArray[:,4]
2270 SNRmet = metArray[:,4]
2271 vmet = metArray[:,5]
2271 vmet = metArray[:,5]
2272 spcmet = metArray[:,6]
2272 spcmet = metArray[:,6]
2273
2273
2274 nChan = numpy.max(cmet) + 1
2274 nChan = numpy.max(cmet) + 1
2275 nHeights = len(heightList)
2275 nHeights = len(heightList)
2276
2276
2277 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
2277 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
2278 hmet = heightList[hmet]
2278 hmet = heightList[hmet]
2279 h1met = hmet*numpy.cos(zenith_arr[cmet]) #Corrected heights
2279 h1met = hmet*numpy.cos(zenith_arr[cmet]) #Corrected heights
2280
2280
2281 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2281 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2282
2282
2283 for i in range(nHeights - 1):
2283 for i in range(nHeights - 1):
2284 hmin = heightList[i]
2284 hmin = heightList[i]
2285 hmax = heightList[i + 1]
2285 hmax = heightList[i + 1]
2286
2286
2287 thisH = (h1met>=hmin) & (h1met<hmax) & (cmet!=2) & (SNRmet>8) & (vmet<50) & (spcmet<10)
2287 thisH = (h1met>=hmin) & (h1met<hmax) & (cmet!=2) & (SNRmet>8) & (vmet<50) & (spcmet<10)
2288 indthisH = numpy.where(thisH)
2288 indthisH = numpy.where(thisH)
2289
2289
2290 if numpy.size(indthisH) > 3:
2290 if numpy.size(indthisH) > 3:
2291
2291
2292 vel_aux = vmet[thisH]
2292 vel_aux = vmet[thisH]
2293 chan_aux = cmet[thisH]
2293 chan_aux = cmet[thisH]
2294 cosu_aux = dir_cosu[chan_aux]
2294 cosu_aux = dir_cosu[chan_aux]
2295 cosv_aux = dir_cosv[chan_aux]
2295 cosv_aux = dir_cosv[chan_aux]
2296 cosw_aux = dir_cosw[chan_aux]
2296 cosw_aux = dir_cosw[chan_aux]
2297
2297
2298 nch = numpy.size(numpy.unique(chan_aux))
2298 nch = numpy.size(numpy.unique(chan_aux))
2299 if nch > 1:
2299 if nch > 1:
2300 A = self.__calculateMatA(cosu_aux, cosv_aux, cosw_aux, True)
2300 A = self.__calculateMatA(cosu_aux, cosv_aux, cosw_aux, True)
2301 velEst[i,:] = numpy.dot(A,vel_aux)
2301 velEst[i,:] = numpy.dot(A,vel_aux)
2302
2302
2303 return velEst
2303 return velEst
2304
2304
2305 def run(self, dataOut, technique, nHours=1, hmin=70, hmax=110, **kwargs):
2305 def run(self, dataOut, technique, nHours=1, hmin=70, hmax=110, **kwargs):
2306
2306
2307 param = dataOut.data_param
2307 param = dataOut.data_param
2308 if dataOut.abscissaList != None:
2308 if dataOut.abscissaList != None:
2309 absc = dataOut.abscissaList[:-1]
2309 absc = dataOut.abscissaList[:-1]
2310 # noise = dataOut.noise
2310 # noise = dataOut.noise
2311 heightList = dataOut.heightList
2311 heightList = dataOut.heightList
2312 SNR = dataOut.data_SNR
2312 SNR = dataOut.data_SNR
2313
2313
2314 if technique == 'DBS':
2314 if technique == 'DBS':
2315
2315
2316 kwargs['velRadial'] = param[:,1,:] #Radial velocity
2316 kwargs['velRadial'] = param[:,1,:] #Radial velocity
2317 kwargs['heightList'] = heightList
2317 kwargs['heightList'] = heightList
2318 kwargs['SNR'] = SNR
2318 kwargs['SNR'] = SNR
2319
2319
2320 dataOut.data_output, dataOut.heightList, dataOut.data_SNR = self.techniqueDBS(kwargs) #DBS Function
2320 dataOut.data_output, dataOut.heightList, dataOut.data_SNR = self.techniqueDBS(kwargs) #DBS Function
2321 dataOut.utctimeInit = dataOut.utctime
2321 dataOut.utctimeInit = dataOut.utctime
2322 dataOut.outputInterval = dataOut.paramInterval
2322 dataOut.outputInterval = dataOut.paramInterval
2323
2323
2324 elif technique == 'SA':
2324 elif technique == 'SA':
2325
2325
2326 #Parameters
2326 #Parameters
2327 # position_x = kwargs['positionX']
2327 # position_x = kwargs['positionX']
2328 # position_y = kwargs['positionY']
2328 # position_y = kwargs['positionY']
2329 # azimuth = kwargs['azimuth']
2329 # azimuth = kwargs['azimuth']
2330 #
2330 #
2331 # if kwargs.has_key('crosspairsList'):
2331 # if kwargs.has_key('crosspairsList'):
2332 # pairs = kwargs['crosspairsList']
2332 # pairs = kwargs['crosspairsList']
2333 # else:
2333 # else:
2334 # pairs = None
2334 # pairs = None
2335 #
2335 #
2336 # if kwargs.has_key('correctFactor'):
2336 # if kwargs.has_key('correctFactor'):
2337 # correctFactor = kwargs['correctFactor']
2337 # correctFactor = kwargs['correctFactor']
2338 # else:
2338 # else:
2339 # correctFactor = 1
2339 # correctFactor = 1
2340
2340
2341 # tau = dataOut.data_param
2341 # tau = dataOut.data_param
2342 # _lambda = dataOut.C/dataOut.frequency
2342 # _lambda = dataOut.C/dataOut.frequency
2343 # pairsList = dataOut.groupList
2343 # pairsList = dataOut.groupList
2344 # nChannels = dataOut.nChannels
2344 # nChannels = dataOut.nChannels
2345
2345
2346 kwargs['groupList'] = dataOut.groupList
2346 kwargs['groupList'] = dataOut.groupList
2347 kwargs['tau'] = dataOut.data_param
2347 kwargs['tau'] = dataOut.data_param
2348 kwargs['_lambda'] = dataOut.C/dataOut.frequency
2348 kwargs['_lambda'] = dataOut.C/dataOut.frequency
2349 # dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
2349 # dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
2350 dataOut.data_output = self.techniqueSA(kwargs)
2350 dataOut.data_output = self.techniqueSA(kwargs)
2351 dataOut.utctimeInit = dataOut.utctime
2351 dataOut.utctimeInit = dataOut.utctime
2352 dataOut.outputInterval = dataOut.timeInterval
2352 dataOut.outputInterval = dataOut.timeInterval
2353
2353
2354 elif technique == 'Meteors':
2354 elif technique == 'Meteors':
2355 dataOut.flagNoData = True
2355 dataOut.flagNoData = True
2356 self.__dataReady = False
2356 self.__dataReady = False
2357
2357
2358 if kwargs.has_key('nHours'):
2358 if kwargs.has_key('nHours'):
2359 nHours = kwargs['nHours']
2359 nHours = kwargs['nHours']
2360 else:
2360 else:
2361 nHours = 1
2361 nHours = 1
2362
2362
2363 if kwargs.has_key('meteorsPerBin'):
2363 if kwargs.has_key('meteorsPerBin'):
2364 meteorThresh = kwargs['meteorsPerBin']
2364 meteorThresh = kwargs['meteorsPerBin']
2365 else:
2365 else:
2366 meteorThresh = 6
2366 meteorThresh = 6
2367
2367
2368 if kwargs.has_key('hmin'):
2368 if kwargs.has_key('hmin'):
2369 hmin = kwargs['hmin']
2369 hmin = kwargs['hmin']
2370 else: hmin = 70
2370 else: hmin = 70
2371 if kwargs.has_key('hmax'):
2371 if kwargs.has_key('hmax'):
2372 hmax = kwargs['hmax']
2372 hmax = kwargs['hmax']
2373 else: hmax = 110
2373 else: hmax = 110
2374
2374
2375 dataOut.outputInterval = nHours*3600
2375 dataOut.outputInterval = nHours*3600
2376
2376
2377 if self.__isConfig == False:
2377 if self.__isConfig == False:
2378 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2378 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2379 #Get Initial LTC time
2379 #Get Initial LTC time
2380 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2380 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2381 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2381 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2382
2382
2383 self.__isConfig = True
2383 self.__isConfig = True
2384
2384
2385 if self.__buffer == None:
2385 if self.__buffer is None:
2386 self.__buffer = dataOut.data_param
2386 self.__buffer = dataOut.data_param
2387 self.__firstdata = copy.copy(dataOut)
2387 self.__firstdata = copy.copy(dataOut)
2388
2388
2389 else:
2389 else:
2390 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2390 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2391
2391
2392 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2392 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2393
2393
2394 if self.__dataReady:
2394 if self.__dataReady:
2395 dataOut.utctimeInit = self.__initime
2395 dataOut.utctimeInit = self.__initime
2396
2396
2397 self.__initime += dataOut.outputInterval #to erase time offset
2397 self.__initime += dataOut.outputInterval #to erase time offset
2398
2398
2399 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
2399 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
2400 dataOut.flagNoData = False
2400 dataOut.flagNoData = False
2401 self.__buffer = None
2401 self.__buffer = None
2402
2402
2403 elif technique == 'Meteors1':
2403 elif technique == 'Meteors1':
2404 dataOut.flagNoData = True
2404 dataOut.flagNoData = True
2405 self.__dataReady = False
2405 self.__dataReady = False
2406
2406
2407 if kwargs.has_key('nMins'):
2407 if kwargs.has_key('nMins'):
2408 nMins = kwargs['nMins']
2408 nMins = kwargs['nMins']
2409 else: nMins = 20
2409 else: nMins = 20
2410 if kwargs.has_key('rx_location'):
2410 if kwargs.has_key('rx_location'):
2411 rx_location = kwargs['rx_location']
2411 rx_location = kwargs['rx_location']
2412 else: rx_location = [(0,1),(1,1),(1,0)]
2412 else: rx_location = [(0,1),(1,1),(1,0)]
2413 if kwargs.has_key('azimuth'):
2413 if kwargs.has_key('azimuth'):
2414 azimuth = kwargs['azimuth']
2414 azimuth = kwargs['azimuth']
2415 else: azimuth = 51.06
2415 else: azimuth = 51.06
2416 if kwargs.has_key('dfactor'):
2416 if kwargs.has_key('dfactor'):
2417 dfactor = kwargs['dfactor']
2417 dfactor = kwargs['dfactor']
2418 if kwargs.has_key('mode'):
2418 if kwargs.has_key('mode'):
2419 mode = kwargs['mode']
2419 mode = kwargs['mode']
2420 if kwargs.has_key('theta_x'):
2420 if kwargs.has_key('theta_x'):
2421 theta_x = kwargs['theta_x']
2421 theta_x = kwargs['theta_x']
2422 if kwargs.has_key('theta_y'):
2422 if kwargs.has_key('theta_y'):
2423 theta_y = kwargs['theta_y']
2423 theta_y = kwargs['theta_y']
2424 else: mode = 'SA'
2424 else: mode = 'SA'
2425
2425
2426 #Borrar luego esto
2426 #Borrar luego esto
2427 if dataOut.groupList == None:
2427 if dataOut.groupList is None:
2428 dataOut.groupList = [(0,1),(0,2),(1,2)]
2428 dataOut.groupList = [(0,1),(0,2),(1,2)]
2429 groupList = dataOut.groupList
2429 groupList = dataOut.groupList
2430 C = 3e8
2430 C = 3e8
2431 freq = 50e6
2431 freq = 50e6
2432 lamb = C/freq
2432 lamb = C/freq
2433 k = 2*numpy.pi/lamb
2433 k = 2*numpy.pi/lamb
2434
2434
2435 timeList = dataOut.abscissaList
2435 timeList = dataOut.abscissaList
2436 heightList = dataOut.heightList
2436 heightList = dataOut.heightList
2437
2437
2438 if self.__isConfig == False:
2438 if self.__isConfig == False:
2439 dataOut.outputInterval = nMins*60
2439 dataOut.outputInterval = nMins*60
2440 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2440 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2441 #Get Initial LTC time
2441 #Get Initial LTC time
2442 initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2442 initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2443 minuteAux = initime.minute
2443 minuteAux = initime.minute
2444 minuteNew = int(numpy.floor(minuteAux/nMins)*nMins)
2444 minuteNew = int(numpy.floor(minuteAux/nMins)*nMins)
2445 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2445 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2446
2446
2447 self.__isConfig = True
2447 self.__isConfig = True
2448
2448
2449 if self.__buffer == None:
2449 if self.__buffer is None:
2450 self.__buffer = dataOut.data_param
2450 self.__buffer = dataOut.data_param
2451 self.__firstdata = copy.copy(dataOut)
2451 self.__firstdata = copy.copy(dataOut)
2452
2452
2453 else:
2453 else:
2454 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2454 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2455
2455
2456 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2456 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2457
2457
2458 if self.__dataReady:
2458 if self.__dataReady:
2459 dataOut.utctimeInit = self.__initime
2459 dataOut.utctimeInit = self.__initime
2460 self.__initime += dataOut.outputInterval #to erase time offset
2460 self.__initime += dataOut.outputInterval #to erase time offset
2461
2461
2462 metArray = self.__buffer
2462 metArray = self.__buffer
2463 if mode == 'SA':
2463 if mode == 'SA':
2464 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
2464 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
2465 elif mode == 'DBS':
2465 elif mode == 'DBS':
2466 dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList, azimuth=azimuth, theta_x=theta_x, theta_y=theta_y)
2466 dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList, azimuth=azimuth, theta_x=theta_x, theta_y=theta_y)
2467 dataOut.data_output = dataOut.data_output.T
2467 dataOut.data_output = dataOut.data_output.T
2468 dataOut.flagNoData = False
2468 dataOut.flagNoData = False
2469 self.__buffer = None
2469 self.__buffer = None
2470
2470
2471 return
2471 return
2472
2472
2473 class EWDriftsEstimation(Operation):
2473 class EWDriftsEstimation(Operation):
2474
2474
2475 def __init__(self, **kwargs):
2475 def __init__(self, **kwargs):
2476 Operation.__init__(self, **kwargs)
2476 Operation.__init__(self, **kwargs)
2477
2477
2478 def __correctValues(self, heiRang, phi, velRadial, SNR):
2478 def __correctValues(self, heiRang, phi, velRadial, SNR):
2479 listPhi = phi.tolist()
2479 listPhi = phi.tolist()
2480 maxid = listPhi.index(max(listPhi))
2480 maxid = listPhi.index(max(listPhi))
2481 minid = listPhi.index(min(listPhi))
2481 minid = listPhi.index(min(listPhi))
2482
2482
2483 rango = range(len(phi))
2483 rango = range(len(phi))
2484 # rango = numpy.delete(rango,maxid)
2484 # rango = numpy.delete(rango,maxid)
2485
2485
2486 heiRang1 = heiRang*math.cos(phi[maxid])
2486 heiRang1 = heiRang*math.cos(phi[maxid])
2487 heiRangAux = heiRang*math.cos(phi[minid])
2487 heiRangAux = heiRang*math.cos(phi[minid])
2488 indOut = (heiRang1 < heiRangAux[0]).nonzero()
2488 indOut = (heiRang1 < heiRangAux[0]).nonzero()
2489 heiRang1 = numpy.delete(heiRang1,indOut)
2489 heiRang1 = numpy.delete(heiRang1,indOut)
2490
2490
2491 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
2491 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
2492 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
2492 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
2493
2493
2494 for i in rango:
2494 for i in rango:
2495 x = heiRang*math.cos(phi[i])
2495 x = heiRang*math.cos(phi[i])
2496 y1 = velRadial[i,:]
2496 y1 = velRadial[i,:]
2497 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
2497 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
2498
2498
2499 x1 = heiRang1
2499 x1 = heiRang1
2500 y11 = f1(x1)
2500 y11 = f1(x1)
2501
2501
2502 y2 = SNR[i,:]
2502 y2 = SNR[i,:]
2503 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
2503 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
2504 y21 = f2(x1)
2504 y21 = f2(x1)
2505
2505
2506 velRadial1[i,:] = y11
2506 velRadial1[i,:] = y11
2507 SNR1[i,:] = y21
2507 SNR1[i,:] = y21
2508
2508
2509 return heiRang1, velRadial1, SNR1
2509 return heiRang1, velRadial1, SNR1
2510
2510
2511 def run(self, dataOut, zenith, zenithCorrection):
2511 def run(self, dataOut, zenith, zenithCorrection):
2512 heiRang = dataOut.heightList
2512 heiRang = dataOut.heightList
2513 velRadial = dataOut.data_param[:,3,:]
2513 velRadial = dataOut.data_param[:,3,:]
2514 SNR = dataOut.data_SNR
2514 SNR = dataOut.data_SNR
2515
2515
2516 zenith = numpy.array(zenith)
2516 zenith = numpy.array(zenith)
2517 zenith -= zenithCorrection
2517 zenith -= zenithCorrection
2518 zenith *= numpy.pi/180
2518 zenith *= numpy.pi/180
2519
2519
2520 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
2520 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
2521
2521
2522 alp = zenith[0]
2522 alp = zenith[0]
2523 bet = zenith[1]
2523 bet = zenith[1]
2524
2524
2525 w_w = velRadial1[0,:]
2525 w_w = velRadial1[0,:]
2526 w_e = velRadial1[1,:]
2526 w_e = velRadial1[1,:]
2527
2527
2528 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
2528 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
2529 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
2529 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
2530
2530
2531 winds = numpy.vstack((u,w))
2531 winds = numpy.vstack((u,w))
2532
2532
2533 dataOut.heightList = heiRang1
2533 dataOut.heightList = heiRang1
2534 dataOut.data_output = winds
2534 dataOut.data_output = winds
2535 dataOut.data_SNR = SNR1
2535 dataOut.data_SNR = SNR1
2536
2536
2537 dataOut.utctimeInit = dataOut.utctime
2537 dataOut.utctimeInit = dataOut.utctime
2538 dataOut.outputInterval = dataOut.timeInterval
2538 dataOut.outputInterval = dataOut.timeInterval
2539 return
2539 return
2540
2540
2541 #--------------- Non Specular Meteor ----------------
2541 #--------------- Non Specular Meteor ----------------
2542
2542
2543 class NonSpecularMeteorDetection(Operation):
2543 class NonSpecularMeteorDetection(Operation):
2544
2544
2545 def run(self, dataOut, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False):
2545 def run(self, dataOut, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False):
2546 data_acf = dataOut.data_pre[0]
2546 data_acf = dataOut.data_pre[0]
2547 data_ccf = dataOut.data_pre[1]
2547 data_ccf = dataOut.data_pre[1]
2548 pairsList = dataOut.groupList[1]
2548 pairsList = dataOut.groupList[1]
2549
2549
2550 lamb = dataOut.C/dataOut.frequency
2550 lamb = dataOut.C/dataOut.frequency
2551 tSamp = dataOut.ippSeconds*dataOut.nCohInt
2551 tSamp = dataOut.ippSeconds*dataOut.nCohInt
2552 paramInterval = dataOut.paramInterval
2552 paramInterval = dataOut.paramInterval
2553
2553
2554 nChannels = data_acf.shape[0]
2554 nChannels = data_acf.shape[0]
2555 nLags = data_acf.shape[1]
2555 nLags = data_acf.shape[1]
2556 nProfiles = data_acf.shape[2]
2556 nProfiles = data_acf.shape[2]
2557 nHeights = dataOut.nHeights
2557 nHeights = dataOut.nHeights
2558 nCohInt = dataOut.nCohInt
2558 nCohInt = dataOut.nCohInt
2559 sec = numpy.round(nProfiles/dataOut.paramInterval)
2559 sec = numpy.round(nProfiles/dataOut.paramInterval)
2560 heightList = dataOut.heightList
2560 heightList = dataOut.heightList
2561 ippSeconds = dataOut.ippSeconds*dataOut.nCohInt*dataOut.nAvg
2561 ippSeconds = dataOut.ippSeconds*dataOut.nCohInt*dataOut.nAvg
2562 utctime = dataOut.utctime
2562 utctime = dataOut.utctime
2563
2563
2564 dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
2564 dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
2565
2565
2566 #------------------------ SNR --------------------------------------
2566 #------------------------ SNR --------------------------------------
2567 power = data_acf[:,0,:,:].real
2567 power = data_acf[:,0,:,:].real
2568 noise = numpy.zeros(nChannels)
2568 noise = numpy.zeros(nChannels)
2569 SNR = numpy.zeros(power.shape)
2569 SNR = numpy.zeros(power.shape)
2570 for i in range(nChannels):
2570 for i in range(nChannels):
2571 noise[i] = hildebrand_sekhon(power[i,:], nCohInt)
2571 noise[i] = hildebrand_sekhon(power[i,:], nCohInt)
2572 SNR[i] = (power[i]-noise[i])/noise[i]
2572 SNR[i] = (power[i]-noise[i])/noise[i]
2573 SNRm = numpy.nanmean(SNR, axis = 0)
2573 SNRm = numpy.nanmean(SNR, axis = 0)
2574 SNRdB = 10*numpy.log10(SNR)
2574 SNRdB = 10*numpy.log10(SNR)
2575
2575
2576 if mode == 'SA':
2576 if mode == 'SA':
2577 dataOut.groupList = dataOut.groupList[1]
2577 dataOut.groupList = dataOut.groupList[1]
2578 nPairs = data_ccf.shape[0]
2578 nPairs = data_ccf.shape[0]
2579 #---------------------- Coherence and Phase --------------------------
2579 #---------------------- Coherence and Phase --------------------------
2580 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
2580 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
2581 # phase1 = numpy.copy(phase)
2581 # phase1 = numpy.copy(phase)
2582 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
2582 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
2583
2583
2584 for p in range(nPairs):
2584 for p in range(nPairs):
2585 ch0 = pairsList[p][0]
2585 ch0 = pairsList[p][0]
2586 ch1 = pairsList[p][1]
2586 ch1 = pairsList[p][1]
2587 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
2587 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
2588 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
2588 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
2589 # phase1[p,:,:] = numpy.angle(ccf) #median filter
2589 # phase1[p,:,:] = numpy.angle(ccf) #median filter
2590 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
2590 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
2591 # coh1[p,:,:] = numpy.abs(ccf) #median filter
2591 # coh1[p,:,:] = numpy.abs(ccf) #median filter
2592 coh = numpy.nanmax(coh1, axis = 0)
2592 coh = numpy.nanmax(coh1, axis = 0)
2593 # struc = numpy.ones((5,1))
2593 # struc = numpy.ones((5,1))
2594 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
2594 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
2595 #---------------------- Radial Velocity ----------------------------
2595 #---------------------- Radial Velocity ----------------------------
2596 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
2596 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
2597 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
2597 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
2598
2598
2599 if allData:
2599 if allData:
2600 boolMetFin = ~numpy.isnan(SNRm)
2600 boolMetFin = ~numpy.isnan(SNRm)
2601 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2601 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2602 else:
2602 else:
2603 #------------------------ Meteor mask ---------------------------------
2603 #------------------------ Meteor mask ---------------------------------
2604 # #SNR mask
2604 # #SNR mask
2605 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
2605 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
2606 #
2606 #
2607 # #Erase small objects
2607 # #Erase small objects
2608 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
2608 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
2609 #
2609 #
2610 # auxEEJ = numpy.sum(boolMet1,axis=0)
2610 # auxEEJ = numpy.sum(boolMet1,axis=0)
2611 # indOver = auxEEJ>nProfiles*0.8 #Use this later
2611 # indOver = auxEEJ>nProfiles*0.8 #Use this later
2612 # indEEJ = numpy.where(indOver)[0]
2612 # indEEJ = numpy.where(indOver)[0]
2613 # indNEEJ = numpy.where(~indOver)[0]
2613 # indNEEJ = numpy.where(~indOver)[0]
2614 #
2614 #
2615 # boolMetFin = boolMet1
2615 # boolMetFin = boolMet1
2616 #
2616 #
2617 # if indEEJ.size > 0:
2617 # if indEEJ.size > 0:
2618 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
2618 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
2619 #
2619 #
2620 # boolMet2 = coh > cohThresh
2620 # boolMet2 = coh > cohThresh
2621 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
2621 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
2622 #
2622 #
2623 # #Final Meteor mask
2623 # #Final Meteor mask
2624 # boolMetFin = boolMet1|boolMet2
2624 # boolMetFin = boolMet1|boolMet2
2625
2625
2626 #Coherence mask
2626 #Coherence mask
2627 boolMet1 = coh > 0.75
2627 boolMet1 = coh > 0.75
2628 struc = numpy.ones((30,1))
2628 struc = numpy.ones((30,1))
2629 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
2629 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
2630
2630
2631 #Derivative mask
2631 #Derivative mask
2632 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2632 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2633 boolMet2 = derPhase < 0.2
2633 boolMet2 = derPhase < 0.2
2634 # boolMet2 = ndimage.morphology.binary_opening(boolMet2)
2634 # boolMet2 = ndimage.morphology.binary_opening(boolMet2)
2635 # boolMet2 = ndimage.morphology.binary_closing(boolMet2, structure = numpy.ones((10,1)))
2635 # boolMet2 = ndimage.morphology.binary_closing(boolMet2, structure = numpy.ones((10,1)))
2636 boolMet2 = ndimage.median_filter(boolMet2,size=5)
2636 boolMet2 = ndimage.median_filter(boolMet2,size=5)
2637 boolMet2 = numpy.vstack((boolMet2,numpy.full((1,nHeights), True, dtype=bool)))
2637 boolMet2 = numpy.vstack((boolMet2,numpy.full((1,nHeights), True, dtype=bool)))
2638 # #Final mask
2638 # #Final mask
2639 # boolMetFin = boolMet2
2639 # boolMetFin = boolMet2
2640 boolMetFin = boolMet1&boolMet2
2640 boolMetFin = boolMet1&boolMet2
2641 # boolMetFin = ndimage.morphology.binary_dilation(boolMetFin)
2641 # boolMetFin = ndimage.morphology.binary_dilation(boolMetFin)
2642 #Creating data_param
2642 #Creating data_param
2643 coordMet = numpy.where(boolMetFin)
2643 coordMet = numpy.where(boolMetFin)
2644
2644
2645 tmet = coordMet[0]
2645 tmet = coordMet[0]
2646 hmet = coordMet[1]
2646 hmet = coordMet[1]
2647
2647
2648 data_param = numpy.zeros((tmet.size, 6 + nPairs))
2648 data_param = numpy.zeros((tmet.size, 6 + nPairs))
2649 data_param[:,0] = utctime
2649 data_param[:,0] = utctime
2650 data_param[:,1] = tmet
2650 data_param[:,1] = tmet
2651 data_param[:,2] = hmet
2651 data_param[:,2] = hmet
2652 data_param[:,3] = SNRm[tmet,hmet]
2652 data_param[:,3] = SNRm[tmet,hmet]
2653 data_param[:,4] = velRad[tmet,hmet]
2653 data_param[:,4] = velRad[tmet,hmet]
2654 data_param[:,5] = coh[tmet,hmet]
2654 data_param[:,5] = coh[tmet,hmet]
2655 data_param[:,6:] = phase[:,tmet,hmet].T
2655 data_param[:,6:] = phase[:,tmet,hmet].T
2656
2656
2657 elif mode == 'DBS':
2657 elif mode == 'DBS':
2658 dataOut.groupList = numpy.arange(nChannels)
2658 dataOut.groupList = numpy.arange(nChannels)
2659
2659
2660 #Radial Velocities
2660 #Radial Velocities
2661 phase = numpy.angle(data_acf[:,1,:,:])
2661 phase = numpy.angle(data_acf[:,1,:,:])
2662 # phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
2662 # phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
2663 velRad = phase*lamb/(4*numpy.pi*tSamp)
2663 velRad = phase*lamb/(4*numpy.pi*tSamp)
2664
2664
2665 #Spectral width
2665 #Spectral width
2666 # acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
2666 # acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
2667 # acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
2667 # acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
2668 acf1 = data_acf[:,1,:,:]
2668 acf1 = data_acf[:,1,:,:]
2669 acf2 = data_acf[:,2,:,:]
2669 acf2 = data_acf[:,2,:,:]
2670
2670
2671 spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2))
2671 spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2))
2672 # velRad = ndimage.median_filter(velRad, size = (1,5,1))
2672 # velRad = ndimage.median_filter(velRad, size = (1,5,1))
2673 if allData:
2673 if allData:
2674 boolMetFin = ~numpy.isnan(SNRdB)
2674 boolMetFin = ~numpy.isnan(SNRdB)
2675 else:
2675 else:
2676 #SNR
2676 #SNR
2677 boolMet1 = (SNRdB>SNRthresh) #SNR mask
2677 boolMet1 = (SNRdB>SNRthresh) #SNR mask
2678 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
2678 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
2679
2679
2680 #Radial velocity
2680 #Radial velocity
2681 boolMet2 = numpy.abs(velRad) < 20
2681 boolMet2 = numpy.abs(velRad) < 20
2682 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
2682 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
2683
2683
2684 #Spectral Width
2684 #Spectral Width
2685 boolMet3 = spcWidth < 30
2685 boolMet3 = spcWidth < 30
2686 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
2686 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
2687 # boolMetFin = self.__erase_small(boolMet1, 10,5)
2687 # boolMetFin = self.__erase_small(boolMet1, 10,5)
2688 boolMetFin = boolMet1&boolMet2&boolMet3
2688 boolMetFin = boolMet1&boolMet2&boolMet3
2689
2689
2690 #Creating data_param
2690 #Creating data_param
2691 coordMet = numpy.where(boolMetFin)
2691 coordMet = numpy.where(boolMetFin)
2692
2692
2693 cmet = coordMet[0]
2693 cmet = coordMet[0]
2694 tmet = coordMet[1]
2694 tmet = coordMet[1]
2695 hmet = coordMet[2]
2695 hmet = coordMet[2]
2696
2696
2697 data_param = numpy.zeros((tmet.size, 7))
2697 data_param = numpy.zeros((tmet.size, 7))
2698 data_param[:,0] = utctime
2698 data_param[:,0] = utctime
2699 data_param[:,1] = cmet
2699 data_param[:,1] = cmet
2700 data_param[:,2] = tmet
2700 data_param[:,2] = tmet
2701 data_param[:,3] = hmet
2701 data_param[:,3] = hmet
2702 data_param[:,4] = SNR[cmet,tmet,hmet].T
2702 data_param[:,4] = SNR[cmet,tmet,hmet].T
2703 data_param[:,5] = velRad[cmet,tmet,hmet].T
2703 data_param[:,5] = velRad[cmet,tmet,hmet].T
2704 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
2704 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
2705
2705
2706 # self.dataOut.data_param = data_int
2706 # self.dataOut.data_param = data_int
2707 if len(data_param) == 0:
2707 if len(data_param) == 0:
2708 dataOut.flagNoData = True
2708 dataOut.flagNoData = True
2709 else:
2709 else:
2710 dataOut.data_param = data_param
2710 dataOut.data_param = data_param
2711
2711
2712 def __erase_small(self, binArray, threshX, threshY):
2712 def __erase_small(self, binArray, threshX, threshY):
2713 labarray, numfeat = ndimage.measurements.label(binArray)
2713 labarray, numfeat = ndimage.measurements.label(binArray)
2714 binArray1 = numpy.copy(binArray)
2714 binArray1 = numpy.copy(binArray)
2715
2715
2716 for i in range(1,numfeat + 1):
2716 for i in range(1,numfeat + 1):
2717 auxBin = (labarray==i)
2717 auxBin = (labarray==i)
2718 auxSize = auxBin.sum()
2718 auxSize = auxBin.sum()
2719
2719
2720 x,y = numpy.where(auxBin)
2720 x,y = numpy.where(auxBin)
2721 widthX = x.max() - x.min()
2721 widthX = x.max() - x.min()
2722 widthY = y.max() - y.min()
2722 widthY = y.max() - y.min()
2723
2723
2724 #width X: 3 seg -> 12.5*3
2724 #width X: 3 seg -> 12.5*3
2725 #width Y:
2725 #width Y:
2726
2726
2727 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
2727 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
2728 binArray1[auxBin] = False
2728 binArray1[auxBin] = False
2729
2729
2730 return binArray1
2730 return binArray1
2731
2731
2732 #--------------- Specular Meteor ----------------
2732 #--------------- Specular Meteor ----------------
2733
2733
2734 class SMDetection(Operation):
2734 class SMDetection(Operation):
2735 '''
2735 '''
2736 Function DetectMeteors()
2736 Function DetectMeteors()
2737 Project developed with paper:
2737 Project developed with paper:
2738 HOLDSWORTH ET AL. 2004
2738 HOLDSWORTH ET AL. 2004
2739
2739
2740 Input:
2740 Input:
2741 self.dataOut.data_pre
2741 self.dataOut.data_pre
2742
2742
2743 centerReceiverIndex: From the channels, which is the center receiver
2743 centerReceiverIndex: From the channels, which is the center receiver
2744
2744
2745 hei_ref: Height reference for the Beacon signal extraction
2745 hei_ref: Height reference for the Beacon signal extraction
2746 tauindex:
2746 tauindex:
2747 predefinedPhaseShifts: Predefined phase offset for the voltge signals
2747 predefinedPhaseShifts: Predefined phase offset for the voltge signals
2748
2748
2749 cohDetection: Whether to user Coherent detection or not
2749 cohDetection: Whether to user Coherent detection or not
2750 cohDet_timeStep: Coherent Detection calculation time step
2750 cohDet_timeStep: Coherent Detection calculation time step
2751 cohDet_thresh: Coherent Detection phase threshold to correct phases
2751 cohDet_thresh: Coherent Detection phase threshold to correct phases
2752
2752
2753 noise_timeStep: Noise calculation time step
2753 noise_timeStep: Noise calculation time step
2754 noise_multiple: Noise multiple to define signal threshold
2754 noise_multiple: Noise multiple to define signal threshold
2755
2755
2756 multDet_timeLimit: Multiple Detection Removal time limit in seconds
2756 multDet_timeLimit: Multiple Detection Removal time limit in seconds
2757 multDet_rangeLimit: Multiple Detection Removal range limit in km
2757 multDet_rangeLimit: Multiple Detection Removal range limit in km
2758
2758
2759 phaseThresh: Maximum phase difference between receiver to be consider a meteor
2759 phaseThresh: Maximum phase difference between receiver to be consider a meteor
2760 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
2760 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
2761
2761
2762 hmin: Minimum Height of the meteor to use it in the further wind estimations
2762 hmin: Minimum Height of the meteor to use it in the further wind estimations
2763 hmax: Maximum Height of the meteor to use it in the further wind estimations
2763 hmax: Maximum Height of the meteor to use it in the further wind estimations
2764 azimuth: Azimuth angle correction
2764 azimuth: Azimuth angle correction
2765
2765
2766 Affected:
2766 Affected:
2767 self.dataOut.data_param
2767 self.dataOut.data_param
2768
2768
2769 Rejection Criteria (Errors):
2769 Rejection Criteria (Errors):
2770 0: No error; analysis OK
2770 0: No error; analysis OK
2771 1: SNR < SNR threshold
2771 1: SNR < SNR threshold
2772 2: angle of arrival (AOA) ambiguously determined
2772 2: angle of arrival (AOA) ambiguously determined
2773 3: AOA estimate not feasible
2773 3: AOA estimate not feasible
2774 4: Large difference in AOAs obtained from different antenna baselines
2774 4: Large difference in AOAs obtained from different antenna baselines
2775 5: echo at start or end of time series
2775 5: echo at start or end of time series
2776 6: echo less than 5 examples long; too short for analysis
2776 6: echo less than 5 examples long; too short for analysis
2777 7: echo rise exceeds 0.3s
2777 7: echo rise exceeds 0.3s
2778 8: echo decay time less than twice rise time
2778 8: echo decay time less than twice rise time
2779 9: large power level before echo
2779 9: large power level before echo
2780 10: large power level after echo
2780 10: large power level after echo
2781 11: poor fit to amplitude for estimation of decay time
2781 11: poor fit to amplitude for estimation of decay time
2782 12: poor fit to CCF phase variation for estimation of radial drift velocity
2782 12: poor fit to CCF phase variation for estimation of radial drift velocity
2783 13: height unresolvable echo: not valid height within 70 to 110 km
2783 13: height unresolvable echo: not valid height within 70 to 110 km
2784 14: height ambiguous echo: more then one possible height within 70 to 110 km
2784 14: height ambiguous echo: more then one possible height within 70 to 110 km
2785 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
2785 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
2786 16: oscilatory echo, indicating event most likely not an underdense echo
2786 16: oscilatory echo, indicating event most likely not an underdense echo
2787
2787
2788 17: phase difference in meteor Reestimation
2788 17: phase difference in meteor Reestimation
2789
2789
2790 Data Storage:
2790 Data Storage:
2791 Meteors for Wind Estimation (8):
2791 Meteors for Wind Estimation (8):
2792 Utc Time | Range Height
2792 Utc Time | Range Height
2793 Azimuth Zenith errorCosDir
2793 Azimuth Zenith errorCosDir
2794 VelRad errorVelRad
2794 VelRad errorVelRad
2795 Phase0 Phase1 Phase2 Phase3
2795 Phase0 Phase1 Phase2 Phase3
2796 TypeError
2796 TypeError
2797
2797
2798 '''
2798 '''
2799
2799
2800 def run(self, dataOut, hei_ref = None, tauindex = 0,
2800 def run(self, dataOut, hei_ref = None, tauindex = 0,
2801 phaseOffsets = None,
2801 phaseOffsets = None,
2802 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
2802 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
2803 noise_timeStep = 4, noise_multiple = 4,
2803 noise_timeStep = 4, noise_multiple = 4,
2804 multDet_timeLimit = 1, multDet_rangeLimit = 3,
2804 multDet_timeLimit = 1, multDet_rangeLimit = 3,
2805 phaseThresh = 20, SNRThresh = 5,
2805 phaseThresh = 20, SNRThresh = 5,
2806 hmin = 50, hmax=150, azimuth = 0,
2806 hmin = 50, hmax=150, azimuth = 0,
2807 channelPositions = None) :
2807 channelPositions = None) :
2808
2808
2809
2809
2810 #Getting Pairslist
2810 #Getting Pairslist
2811 if channelPositions == None:
2811 if channelPositions is None:
2812 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2812 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2813 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2813 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2814 meteorOps = SMOperations()
2814 meteorOps = SMOperations()
2815 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2815 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2816 heiRang = dataOut.getHeiRange()
2816 heiRang = dataOut.getHeiRange()
2817 #Get Beacon signal - No Beacon signal anymore
2817 #Get Beacon signal - No Beacon signal anymore
2818 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
2818 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
2819 #
2819 #
2820 # if hei_ref != None:
2820 # if hei_ref != None:
2821 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
2821 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
2822 #
2822 #
2823
2823
2824
2824
2825 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
2825 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
2826 # see if the user put in pre defined phase shifts
2826 # see if the user put in pre defined phase shifts
2827 voltsPShift = dataOut.data_pre.copy()
2827 voltsPShift = dataOut.data_pre.copy()
2828
2828
2829 # if predefinedPhaseShifts != None:
2829 # if predefinedPhaseShifts != None:
2830 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
2830 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
2831 #
2831 #
2832 # # elif beaconPhaseShifts:
2832 # # elif beaconPhaseShifts:
2833 # # #get hardware phase shifts using beacon signal
2833 # # #get hardware phase shifts using beacon signal
2834 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
2834 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
2835 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
2835 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
2836 #
2836 #
2837 # else:
2837 # else:
2838 # hardwarePhaseShifts = numpy.zeros(5)
2838 # hardwarePhaseShifts = numpy.zeros(5)
2839 #
2839 #
2840 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
2840 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
2841 # for i in range(self.dataOut.data_pre.shape[0]):
2841 # for i in range(self.dataOut.data_pre.shape[0]):
2842 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
2842 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
2843
2843
2844 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
2844 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
2845
2845
2846 #Remove DC
2846 #Remove DC
2847 voltsDC = numpy.mean(voltsPShift,1)
2847 voltsDC = numpy.mean(voltsPShift,1)
2848 voltsDC = numpy.mean(voltsDC,1)
2848 voltsDC = numpy.mean(voltsDC,1)
2849 for i in range(voltsDC.shape[0]):
2849 for i in range(voltsDC.shape[0]):
2850 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
2850 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
2851
2851
2852 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
2852 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
2853 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
2853 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
2854
2854
2855 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
2855 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
2856 #Coherent Detection
2856 #Coherent Detection
2857 if cohDetection:
2857 if cohDetection:
2858 #use coherent detection to get the net power
2858 #use coherent detection to get the net power
2859 cohDet_thresh = cohDet_thresh*numpy.pi/180
2859 cohDet_thresh = cohDet_thresh*numpy.pi/180
2860 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
2860 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
2861
2861
2862 #Non-coherent detection!
2862 #Non-coherent detection!
2863 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
2863 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
2864 #********** END OF COH/NON-COH POWER CALCULATION**********************
2864 #********** END OF COH/NON-COH POWER CALCULATION**********************
2865
2865
2866 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
2866 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
2867 #Get noise
2867 #Get noise
2868 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
2868 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
2869 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
2869 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
2870 #Get signal threshold
2870 #Get signal threshold
2871 signalThresh = noise_multiple*noise
2871 signalThresh = noise_multiple*noise
2872 #Meteor echoes detection
2872 #Meteor echoes detection
2873 listMeteors = self.__findMeteors(powerNet, signalThresh)
2873 listMeteors = self.__findMeteors(powerNet, signalThresh)
2874 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
2874 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
2875
2875
2876 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
2876 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
2877 #Parameters
2877 #Parameters
2878 heiRange = dataOut.getHeiRange()
2878 heiRange = dataOut.getHeiRange()
2879 rangeInterval = heiRange[1] - heiRange[0]
2879 rangeInterval = heiRange[1] - heiRange[0]
2880 rangeLimit = multDet_rangeLimit/rangeInterval
2880 rangeLimit = multDet_rangeLimit/rangeInterval
2881 timeLimit = multDet_timeLimit/dataOut.timeInterval
2881 timeLimit = multDet_timeLimit/dataOut.timeInterval
2882 #Multiple detection removals
2882 #Multiple detection removals
2883 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
2883 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
2884 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
2884 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
2885
2885
2886 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
2886 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
2887 #Parameters
2887 #Parameters
2888 phaseThresh = phaseThresh*numpy.pi/180
2888 phaseThresh = phaseThresh*numpy.pi/180
2889 thresh = [phaseThresh, noise_multiple, SNRThresh]
2889 thresh = [phaseThresh, noise_multiple, SNRThresh]
2890 #Meteor reestimation (Errors N 1, 6, 12, 17)
2890 #Meteor reestimation (Errors N 1, 6, 12, 17)
2891 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist0, thresh, noise, dataOut.timeInterval, dataOut.frequency)
2891 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist0, thresh, noise, dataOut.timeInterval, dataOut.frequency)
2892 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
2892 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
2893 #Estimation of decay times (Errors N 7, 8, 11)
2893 #Estimation of decay times (Errors N 7, 8, 11)
2894 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
2894 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
2895 #******************* END OF METEOR REESTIMATION *******************
2895 #******************* END OF METEOR REESTIMATION *******************
2896
2896
2897 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
2897 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
2898 #Calculating Radial Velocity (Error N 15)
2898 #Calculating Radial Velocity (Error N 15)
2899 radialStdThresh = 10
2899 radialStdThresh = 10
2900 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
2900 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
2901
2901
2902 if len(listMeteors4) > 0:
2902 if len(listMeteors4) > 0:
2903 #Setting New Array
2903 #Setting New Array
2904 date = dataOut.utctime
2904 date = dataOut.utctime
2905 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
2905 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
2906
2906
2907 #Correcting phase offset
2907 #Correcting phase offset
2908 if phaseOffsets != None:
2908 if phaseOffsets != None:
2909 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2909 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2910 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2910 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2911
2911
2912 #Second Pairslist
2912 #Second Pairslist
2913 pairsList = []
2913 pairsList = []
2914 pairx = (0,1)
2914 pairx = (0,1)
2915 pairy = (2,3)
2915 pairy = (2,3)
2916 pairsList.append(pairx)
2916 pairsList.append(pairx)
2917 pairsList.append(pairy)
2917 pairsList.append(pairy)
2918
2918
2919 jph = numpy.array([0,0,0,0])
2919 jph = numpy.array([0,0,0,0])
2920 h = (hmin,hmax)
2920 h = (hmin,hmax)
2921 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2921 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2922
2922
2923 # #Calculate AOA (Error N 3, 4)
2923 # #Calculate AOA (Error N 3, 4)
2924 # #JONES ET AL. 1998
2924 # #JONES ET AL. 1998
2925 # error = arrayParameters[:,-1]
2925 # error = arrayParameters[:,-1]
2926 # AOAthresh = numpy.pi/8
2926 # AOAthresh = numpy.pi/8
2927 # phases = -arrayParameters[:,9:13]
2927 # phases = -arrayParameters[:,9:13]
2928 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
2928 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
2929 #
2929 #
2930 # #Calculate Heights (Error N 13 and 14)
2930 # #Calculate Heights (Error N 13 and 14)
2931 # error = arrayParameters[:,-1]
2931 # error = arrayParameters[:,-1]
2932 # Ranges = arrayParameters[:,2]
2932 # Ranges = arrayParameters[:,2]
2933 # zenith = arrayParameters[:,5]
2933 # zenith = arrayParameters[:,5]
2934 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
2934 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
2935 # error = arrayParameters[:,-1]
2935 # error = arrayParameters[:,-1]
2936 #********************* END OF PARAMETERS CALCULATION **************************
2936 #********************* END OF PARAMETERS CALCULATION **************************
2937
2937
2938 #***************************+ PASS DATA TO NEXT STEP **********************
2938 #***************************+ PASS DATA TO NEXT STEP **********************
2939 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
2939 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
2940 dataOut.data_param = arrayParameters
2940 dataOut.data_param = arrayParameters
2941
2941
2942 if arrayParameters == None:
2942 if arrayParameters is None:
2943 dataOut.flagNoData = True
2943 dataOut.flagNoData = True
2944 else:
2944 else:
2945 dataOut.flagNoData = True
2945 dataOut.flagNoData = True
2946
2946
2947 return
2947 return
2948
2948
2949 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
2949 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
2950
2950
2951 minIndex = min(newheis[0])
2951 minIndex = min(newheis[0])
2952 maxIndex = max(newheis[0])
2952 maxIndex = max(newheis[0])
2953
2953
2954 voltage = voltage0[:,:,minIndex:maxIndex+1]
2954 voltage = voltage0[:,:,minIndex:maxIndex+1]
2955 nLength = voltage.shape[1]/n
2955 nLength = voltage.shape[1]/n
2956 nMin = 0
2956 nMin = 0
2957 nMax = 0
2957 nMax = 0
2958 phaseOffset = numpy.zeros((len(pairslist),n))
2958 phaseOffset = numpy.zeros((len(pairslist),n))
2959
2959
2960 for i in range(n):
2960 for i in range(n):
2961 nMax += nLength
2961 nMax += nLength
2962 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
2962 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
2963 phaseCCF = numpy.mean(phaseCCF, axis = 2)
2963 phaseCCF = numpy.mean(phaseCCF, axis = 2)
2964 phaseOffset[:,i] = phaseCCF.transpose()
2964 phaseOffset[:,i] = phaseCCF.transpose()
2965 nMin = nMax
2965 nMin = nMax
2966 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
2966 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
2967
2967
2968 #Remove Outliers
2968 #Remove Outliers
2969 factor = 2
2969 factor = 2
2970 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
2970 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
2971 dw = numpy.std(wt,axis = 1)
2971 dw = numpy.std(wt,axis = 1)
2972 dw = dw.reshape((dw.size,1))
2972 dw = dw.reshape((dw.size,1))
2973 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
2973 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
2974 phaseOffset[ind] = numpy.nan
2974 phaseOffset[ind] = numpy.nan
2975 phaseOffset = stats.nanmean(phaseOffset, axis=1)
2975 phaseOffset = stats.nanmean(phaseOffset, axis=1)
2976
2976
2977 return phaseOffset
2977 return phaseOffset
2978
2978
2979 def __shiftPhase(self, data, phaseShift):
2979 def __shiftPhase(self, data, phaseShift):
2980 #this will shift the phase of a complex number
2980 #this will shift the phase of a complex number
2981 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
2981 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
2982 return dataShifted
2982 return dataShifted
2983
2983
2984 def __estimatePhaseDifference(self, array, pairslist):
2984 def __estimatePhaseDifference(self, array, pairslist):
2985 nChannel = array.shape[0]
2985 nChannel = array.shape[0]
2986 nHeights = array.shape[2]
2986 nHeights = array.shape[2]
2987 numPairs = len(pairslist)
2987 numPairs = len(pairslist)
2988 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
2988 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
2989 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
2989 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
2990
2990
2991 #Correct phases
2991 #Correct phases
2992 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
2992 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
2993 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2993 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2994
2994
2995 if indDer[0].shape[0] > 0:
2995 if indDer[0].shape[0] > 0:
2996 for i in range(indDer[0].shape[0]):
2996 for i in range(indDer[0].shape[0]):
2997 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
2997 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
2998 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
2998 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
2999
2999
3000 # for j in range(numSides):
3000 # for j in range(numSides):
3001 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
3001 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
3002 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
3002 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
3003 #
3003 #
3004 #Linear
3004 #Linear
3005 phaseInt = numpy.zeros((numPairs,1))
3005 phaseInt = numpy.zeros((numPairs,1))
3006 angAllCCF = phaseCCF[:,[0,1,3,4],0]
3006 angAllCCF = phaseCCF[:,[0,1,3,4],0]
3007 for j in range(numPairs):
3007 for j in range(numPairs):
3008 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
3008 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
3009 phaseInt[j] = fit[1]
3009 phaseInt[j] = fit[1]
3010 #Phase Differences
3010 #Phase Differences
3011 phaseDiff = phaseInt - phaseCCF[:,2,:]
3011 phaseDiff = phaseInt - phaseCCF[:,2,:]
3012 phaseArrival = phaseInt.reshape(phaseInt.size)
3012 phaseArrival = phaseInt.reshape(phaseInt.size)
3013
3013
3014 #Dealias
3014 #Dealias
3015 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
3015 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
3016 # indAlias = numpy.where(phaseArrival > numpy.pi)
3016 # indAlias = numpy.where(phaseArrival > numpy.pi)
3017 # phaseArrival[indAlias] -= 2*numpy.pi
3017 # phaseArrival[indAlias] -= 2*numpy.pi
3018 # indAlias = numpy.where(phaseArrival < -numpy.pi)
3018 # indAlias = numpy.where(phaseArrival < -numpy.pi)
3019 # phaseArrival[indAlias] += 2*numpy.pi
3019 # phaseArrival[indAlias] += 2*numpy.pi
3020
3020
3021 return phaseDiff, phaseArrival
3021 return phaseDiff, phaseArrival
3022
3022
3023 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
3023 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
3024 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
3024 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
3025 #find the phase shifts of each channel over 1 second intervals
3025 #find the phase shifts of each channel over 1 second intervals
3026 #only look at ranges below the beacon signal
3026 #only look at ranges below the beacon signal
3027 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
3027 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
3028 numBlocks = int(volts.shape[1]/numProfPerBlock)
3028 numBlocks = int(volts.shape[1]/numProfPerBlock)
3029 numHeights = volts.shape[2]
3029 numHeights = volts.shape[2]
3030 nChannel = volts.shape[0]
3030 nChannel = volts.shape[0]
3031 voltsCohDet = volts.copy()
3031 voltsCohDet = volts.copy()
3032
3032
3033 pairsarray = numpy.array(pairslist)
3033 pairsarray = numpy.array(pairslist)
3034 indSides = pairsarray[:,1]
3034 indSides = pairsarray[:,1]
3035 # indSides = numpy.array(range(nChannel))
3035 # indSides = numpy.array(range(nChannel))
3036 # indSides = numpy.delete(indSides, indCenter)
3036 # indSides = numpy.delete(indSides, indCenter)
3037 #
3037 #
3038 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
3038 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
3039 listBlocks = numpy.array_split(volts, numBlocks, 1)
3039 listBlocks = numpy.array_split(volts, numBlocks, 1)
3040
3040
3041 startInd = 0
3041 startInd = 0
3042 endInd = 0
3042 endInd = 0
3043
3043
3044 for i in range(numBlocks):
3044 for i in range(numBlocks):
3045 startInd = endInd
3045 startInd = endInd
3046 endInd = endInd + listBlocks[i].shape[1]
3046 endInd = endInd + listBlocks[i].shape[1]
3047
3047
3048 arrayBlock = listBlocks[i]
3048 arrayBlock = listBlocks[i]
3049 # arrayBlockCenter = listCenter[i]
3049 # arrayBlockCenter = listCenter[i]
3050
3050
3051 #Estimate the Phase Difference
3051 #Estimate the Phase Difference
3052 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
3052 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
3053 #Phase Difference RMS
3053 #Phase Difference RMS
3054 arrayPhaseRMS = numpy.abs(phaseDiff)
3054 arrayPhaseRMS = numpy.abs(phaseDiff)
3055 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
3055 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
3056 indPhase = numpy.where(phaseRMSaux==4)
3056 indPhase = numpy.where(phaseRMSaux==4)
3057 #Shifting
3057 #Shifting
3058 if indPhase[0].shape[0] > 0:
3058 if indPhase[0].shape[0] > 0:
3059 for j in range(indSides.size):
3059 for j in range(indSides.size):
3060 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
3060 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
3061 voltsCohDet[:,startInd:endInd,:] = arrayBlock
3061 voltsCohDet[:,startInd:endInd,:] = arrayBlock
3062
3062
3063 return voltsCohDet
3063 return voltsCohDet
3064
3064
3065 def __calculateCCF(self, volts, pairslist ,laglist):
3065 def __calculateCCF(self, volts, pairslist ,laglist):
3066
3066
3067 nHeights = volts.shape[2]
3067 nHeights = volts.shape[2]
3068 nPoints = volts.shape[1]
3068 nPoints = volts.shape[1]
3069 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
3069 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
3070
3070
3071 for i in range(len(pairslist)):
3071 for i in range(len(pairslist)):
3072 volts1 = volts[pairslist[i][0]]
3072 volts1 = volts[pairslist[i][0]]
3073 volts2 = volts[pairslist[i][1]]
3073 volts2 = volts[pairslist[i][1]]
3074
3074
3075 for t in range(len(laglist)):
3075 for t in range(len(laglist)):
3076 idxT = laglist[t]
3076 idxT = laglist[t]
3077 if idxT >= 0:
3077 if idxT >= 0:
3078 vStacked = numpy.vstack((volts2[idxT:,:],
3078 vStacked = numpy.vstack((volts2[idxT:,:],
3079 numpy.zeros((idxT, nHeights),dtype='complex')))
3079 numpy.zeros((idxT, nHeights),dtype='complex')))
3080 else:
3080 else:
3081 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
3081 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
3082 volts2[:(nPoints + idxT),:]))
3082 volts2[:(nPoints + idxT),:]))
3083 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
3083 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
3084
3084
3085 vStacked = None
3085 vStacked = None
3086 return voltsCCF
3086 return voltsCCF
3087
3087
3088 def __getNoise(self, power, timeSegment, timeInterval):
3088 def __getNoise(self, power, timeSegment, timeInterval):
3089 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
3089 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
3090 numBlocks = int(power.shape[0]/numProfPerBlock)
3090 numBlocks = int(power.shape[0]/numProfPerBlock)
3091 numHeights = power.shape[1]
3091 numHeights = power.shape[1]
3092
3092
3093 listPower = numpy.array_split(power, numBlocks, 0)
3093 listPower = numpy.array_split(power, numBlocks, 0)
3094 noise = numpy.zeros((power.shape[0], power.shape[1]))
3094 noise = numpy.zeros((power.shape[0], power.shape[1]))
3095 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
3095 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
3096
3096
3097 startInd = 0
3097 startInd = 0
3098 endInd = 0
3098 endInd = 0
3099
3099
3100 for i in range(numBlocks): #split por canal
3100 for i in range(numBlocks): #split por canal
3101 startInd = endInd
3101 startInd = endInd
3102 endInd = endInd + listPower[i].shape[0]
3102 endInd = endInd + listPower[i].shape[0]
3103
3103
3104 arrayBlock = listPower[i]
3104 arrayBlock = listPower[i]
3105 noiseAux = numpy.mean(arrayBlock, 0)
3105 noiseAux = numpy.mean(arrayBlock, 0)
3106 # noiseAux = numpy.median(noiseAux)
3106 # noiseAux = numpy.median(noiseAux)
3107 # noiseAux = numpy.mean(arrayBlock)
3107 # noiseAux = numpy.mean(arrayBlock)
3108 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
3108 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
3109
3109
3110 noiseAux1 = numpy.mean(arrayBlock)
3110 noiseAux1 = numpy.mean(arrayBlock)
3111 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
3111 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
3112
3112
3113 return noise, noise1
3113 return noise, noise1
3114
3114
3115 def __findMeteors(self, power, thresh):
3115 def __findMeteors(self, power, thresh):
3116 nProf = power.shape[0]
3116 nProf = power.shape[0]
3117 nHeights = power.shape[1]
3117 nHeights = power.shape[1]
3118 listMeteors = []
3118 listMeteors = []
3119
3119
3120 for i in range(nHeights):
3120 for i in range(nHeights):
3121 powerAux = power[:,i]
3121 powerAux = power[:,i]
3122 threshAux = thresh[:,i]
3122 threshAux = thresh[:,i]
3123
3123
3124 indUPthresh = numpy.where(powerAux > threshAux)[0]
3124 indUPthresh = numpy.where(powerAux > threshAux)[0]
3125 indDNthresh = numpy.where(powerAux <= threshAux)[0]
3125 indDNthresh = numpy.where(powerAux <= threshAux)[0]
3126
3126
3127 j = 0
3127 j = 0
3128
3128
3129 while (j < indUPthresh.size - 2):
3129 while (j < indUPthresh.size - 2):
3130 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
3130 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
3131 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
3131 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
3132 indDNthresh = indDNthresh[indDNAux]
3132 indDNthresh = indDNthresh[indDNAux]
3133
3133
3134 if (indDNthresh.size > 0):
3134 if (indDNthresh.size > 0):
3135 indEnd = indDNthresh[0] - 1
3135 indEnd = indDNthresh[0] - 1
3136 indInit = indUPthresh[j]
3136 indInit = indUPthresh[j]
3137
3137
3138 meteor = powerAux[indInit:indEnd + 1]
3138 meteor = powerAux[indInit:indEnd + 1]
3139 indPeak = meteor.argmax() + indInit
3139 indPeak = meteor.argmax() + indInit
3140 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
3140 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
3141
3141
3142 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
3142 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
3143 j = numpy.where(indUPthresh == indEnd)[0] + 1
3143 j = numpy.where(indUPthresh == indEnd)[0] + 1
3144 else: j+=1
3144 else: j+=1
3145 else: j+=1
3145 else: j+=1
3146
3146
3147 return listMeteors
3147 return listMeteors
3148
3148
3149 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
3149 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
3150
3150
3151 arrayMeteors = numpy.asarray(listMeteors)
3151 arrayMeteors = numpy.asarray(listMeteors)
3152 listMeteors1 = []
3152 listMeteors1 = []
3153
3153
3154 while arrayMeteors.shape[0] > 0:
3154 while arrayMeteors.shape[0] > 0:
3155 FLAs = arrayMeteors[:,4]
3155 FLAs = arrayMeteors[:,4]
3156 maxFLA = FLAs.argmax()
3156 maxFLA = FLAs.argmax()
3157 listMeteors1.append(arrayMeteors[maxFLA,:])
3157 listMeteors1.append(arrayMeteors[maxFLA,:])
3158
3158
3159 MeteorInitTime = arrayMeteors[maxFLA,1]
3159 MeteorInitTime = arrayMeteors[maxFLA,1]
3160 MeteorEndTime = arrayMeteors[maxFLA,3]
3160 MeteorEndTime = arrayMeteors[maxFLA,3]
3161 MeteorHeight = arrayMeteors[maxFLA,0]
3161 MeteorHeight = arrayMeteors[maxFLA,0]
3162
3162
3163 #Check neighborhood
3163 #Check neighborhood
3164 maxHeightIndex = MeteorHeight + rangeLimit
3164 maxHeightIndex = MeteorHeight + rangeLimit
3165 minHeightIndex = MeteorHeight - rangeLimit
3165 minHeightIndex = MeteorHeight - rangeLimit
3166 minTimeIndex = MeteorInitTime - timeLimit
3166 minTimeIndex = MeteorInitTime - timeLimit
3167 maxTimeIndex = MeteorEndTime + timeLimit
3167 maxTimeIndex = MeteorEndTime + timeLimit
3168
3168
3169 #Check Heights
3169 #Check Heights
3170 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
3170 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
3171 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
3171 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
3172 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
3172 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
3173
3173
3174 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
3174 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
3175
3175
3176 return listMeteors1
3176 return listMeteors1
3177
3177
3178 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
3178 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
3179 numHeights = volts.shape[2]
3179 numHeights = volts.shape[2]
3180 nChannel = volts.shape[0]
3180 nChannel = volts.shape[0]
3181
3181
3182 thresholdPhase = thresh[0]
3182 thresholdPhase = thresh[0]
3183 thresholdNoise = thresh[1]
3183 thresholdNoise = thresh[1]
3184 thresholdDB = float(thresh[2])
3184 thresholdDB = float(thresh[2])
3185
3185
3186 thresholdDB1 = 10**(thresholdDB/10)
3186 thresholdDB1 = 10**(thresholdDB/10)
3187 pairsarray = numpy.array(pairslist)
3187 pairsarray = numpy.array(pairslist)
3188 indSides = pairsarray[:,1]
3188 indSides = pairsarray[:,1]
3189
3189
3190 pairslist1 = list(pairslist)
3190 pairslist1 = list(pairslist)
3191 pairslist1.append((0,1))
3191 pairslist1.append((0,1))
3192 pairslist1.append((3,4))
3192 pairslist1.append((3,4))
3193
3193
3194 listMeteors1 = []
3194 listMeteors1 = []
3195 listPowerSeries = []
3195 listPowerSeries = []
3196 listVoltageSeries = []
3196 listVoltageSeries = []
3197 #volts has the war data
3197 #volts has the war data
3198
3198
3199 if frequency == 30e6:
3199 if frequency == 30e6:
3200 timeLag = 45*10**-3
3200 timeLag = 45*10**-3
3201 else:
3201 else:
3202 timeLag = 15*10**-3
3202 timeLag = 15*10**-3
3203 lag = numpy.ceil(timeLag/timeInterval)
3203 lag = numpy.ceil(timeLag/timeInterval)
3204
3204
3205 for i in range(len(listMeteors)):
3205 for i in range(len(listMeteors)):
3206
3206
3207 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
3207 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
3208 meteorAux = numpy.zeros(16)
3208 meteorAux = numpy.zeros(16)
3209
3209
3210 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
3210 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
3211 mHeight = listMeteors[i][0]
3211 mHeight = listMeteors[i][0]
3212 mStart = listMeteors[i][1]
3212 mStart = listMeteors[i][1]
3213 mPeak = listMeteors[i][2]
3213 mPeak = listMeteors[i][2]
3214 mEnd = listMeteors[i][3]
3214 mEnd = listMeteors[i][3]
3215
3215
3216 #get the volt data between the start and end times of the meteor
3216 #get the volt data between the start and end times of the meteor
3217 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
3217 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
3218 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3218 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3219
3219
3220 #3.6. Phase Difference estimation
3220 #3.6. Phase Difference estimation
3221 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
3221 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
3222
3222
3223 #3.7. Phase difference removal & meteor start, peak and end times reestimated
3223 #3.7. Phase difference removal & meteor start, peak and end times reestimated
3224 #meteorVolts0.- all Channels, all Profiles
3224 #meteorVolts0.- all Channels, all Profiles
3225 meteorVolts0 = volts[:,:,mHeight]
3225 meteorVolts0 = volts[:,:,mHeight]
3226 meteorThresh = noise[:,mHeight]*thresholdNoise
3226 meteorThresh = noise[:,mHeight]*thresholdNoise
3227 meteorNoise = noise[:,mHeight]
3227 meteorNoise = noise[:,mHeight]
3228 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
3228 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
3229 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
3229 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
3230
3230
3231 #Times reestimation
3231 #Times reestimation
3232 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
3232 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
3233 if mStart1.size > 0:
3233 if mStart1.size > 0:
3234 mStart1 = mStart1[-1] + 1
3234 mStart1 = mStart1[-1] + 1
3235
3235
3236 else:
3236 else:
3237 mStart1 = mPeak
3237 mStart1 = mPeak
3238
3238
3239 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
3239 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
3240 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
3240 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
3241 if mEndDecayTime1.size == 0:
3241 if mEndDecayTime1.size == 0:
3242 mEndDecayTime1 = powerNet0.size
3242 mEndDecayTime1 = powerNet0.size
3243 else:
3243 else:
3244 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
3244 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
3245 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
3245 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
3246
3246
3247 #meteorVolts1.- all Channels, from start to end
3247 #meteorVolts1.- all Channels, from start to end
3248 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
3248 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
3249 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
3249 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
3250 if meteorVolts2.shape[1] == 0:
3250 if meteorVolts2.shape[1] == 0:
3251 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
3251 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
3252 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
3252 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
3253 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
3253 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
3254 ##################### END PARAMETERS REESTIMATION #########################
3254 ##################### END PARAMETERS REESTIMATION #########################
3255
3255
3256 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
3256 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
3257 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
3257 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
3258 if meteorVolts2.shape[1] > 0:
3258 if meteorVolts2.shape[1] > 0:
3259 #Phase Difference re-estimation
3259 #Phase Difference re-estimation
3260 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
3260 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
3261 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
3261 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
3262 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
3262 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
3263 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
3263 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
3264 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
3264 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
3265
3265
3266 #Phase Difference RMS
3266 #Phase Difference RMS
3267 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
3267 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
3268 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
3268 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
3269 #Data from Meteor
3269 #Data from Meteor
3270 mPeak1 = powerNet1.argmax() + mStart1
3270 mPeak1 = powerNet1.argmax() + mStart1
3271 mPeakPower1 = powerNet1.max()
3271 mPeakPower1 = powerNet1.max()
3272 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
3272 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
3273 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
3273 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
3274 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
3274 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
3275 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
3275 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
3276 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
3276 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
3277 #Vectorize
3277 #Vectorize
3278 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
3278 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
3279 meteorAux[7:11] = phaseDiffint[0:4]
3279 meteorAux[7:11] = phaseDiffint[0:4]
3280
3280
3281 #Rejection Criterions
3281 #Rejection Criterions
3282 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
3282 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
3283 meteorAux[-1] = 17
3283 meteorAux[-1] = 17
3284 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
3284 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
3285 meteorAux[-1] = 1
3285 meteorAux[-1] = 1
3286
3286
3287
3287
3288 else:
3288 else:
3289 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
3289 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
3290 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
3290 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
3291 PowerSeries = 0
3291 PowerSeries = 0
3292
3292
3293 listMeteors1.append(meteorAux)
3293 listMeteors1.append(meteorAux)
3294 listPowerSeries.append(PowerSeries)
3294 listPowerSeries.append(PowerSeries)
3295 listVoltageSeries.append(meteorVolts1)
3295 listVoltageSeries.append(meteorVolts1)
3296
3296
3297 return listMeteors1, listPowerSeries, listVoltageSeries
3297 return listMeteors1, listPowerSeries, listVoltageSeries
3298
3298
3299 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
3299 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
3300
3300
3301 threshError = 10
3301 threshError = 10
3302 #Depending if it is 30 or 50 MHz
3302 #Depending if it is 30 or 50 MHz
3303 if frequency == 30e6:
3303 if frequency == 30e6:
3304 timeLag = 45*10**-3
3304 timeLag = 45*10**-3
3305 else:
3305 else:
3306 timeLag = 15*10**-3
3306 timeLag = 15*10**-3
3307 lag = numpy.ceil(timeLag/timeInterval)
3307 lag = numpy.ceil(timeLag/timeInterval)
3308
3308
3309 listMeteors1 = []
3309 listMeteors1 = []
3310
3310
3311 for i in range(len(listMeteors)):
3311 for i in range(len(listMeteors)):
3312 meteorPower = listPower[i]
3312 meteorPower = listPower[i]
3313 meteorAux = listMeteors[i]
3313 meteorAux = listMeteors[i]
3314
3314
3315 if meteorAux[-1] == 0:
3315 if meteorAux[-1] == 0:
3316
3316
3317 try:
3317 try:
3318 indmax = meteorPower.argmax()
3318 indmax = meteorPower.argmax()
3319 indlag = indmax + lag
3319 indlag = indmax + lag
3320
3320
3321 y = meteorPower[indlag:]
3321 y = meteorPower[indlag:]
3322 x = numpy.arange(0, y.size)*timeLag
3322 x = numpy.arange(0, y.size)*timeLag
3323
3323
3324 #first guess
3324 #first guess
3325 a = y[0]
3325 a = y[0]
3326 tau = timeLag
3326 tau = timeLag
3327 #exponential fit
3327 #exponential fit
3328 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
3328 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
3329 y1 = self.__exponential_function(x, *popt)
3329 y1 = self.__exponential_function(x, *popt)
3330 #error estimation
3330 #error estimation
3331 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
3331 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
3332
3332
3333 decayTime = popt[1]
3333 decayTime = popt[1]
3334 riseTime = indmax*timeInterval
3334 riseTime = indmax*timeInterval
3335 meteorAux[11:13] = [decayTime, error]
3335 meteorAux[11:13] = [decayTime, error]
3336
3336
3337 #Table items 7, 8 and 11
3337 #Table items 7, 8 and 11
3338 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
3338 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
3339 meteorAux[-1] = 7
3339 meteorAux[-1] = 7
3340 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
3340 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
3341 meteorAux[-1] = 8
3341 meteorAux[-1] = 8
3342 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
3342 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
3343 meteorAux[-1] = 11
3343 meteorAux[-1] = 11
3344
3344
3345
3345
3346 except:
3346 except:
3347 meteorAux[-1] = 11
3347 meteorAux[-1] = 11
3348
3348
3349
3349
3350 listMeteors1.append(meteorAux)
3350 listMeteors1.append(meteorAux)
3351
3351
3352 return listMeteors1
3352 return listMeteors1
3353
3353
3354 #Exponential Function
3354 #Exponential Function
3355
3355
3356 def __exponential_function(self, x, a, tau):
3356 def __exponential_function(self, x, a, tau):
3357 y = a*numpy.exp(-x/tau)
3357 y = a*numpy.exp(-x/tau)
3358 return y
3358 return y
3359
3359
3360 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
3360 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
3361
3361
3362 pairslist1 = list(pairslist)
3362 pairslist1 = list(pairslist)
3363 pairslist1.append((0,1))
3363 pairslist1.append((0,1))
3364 pairslist1.append((3,4))
3364 pairslist1.append((3,4))
3365 numPairs = len(pairslist1)
3365 numPairs = len(pairslist1)
3366 #Time Lag
3366 #Time Lag
3367 timeLag = 45*10**-3
3367 timeLag = 45*10**-3
3368 c = 3e8
3368 c = 3e8
3369 lag = numpy.ceil(timeLag/timeInterval)
3369 lag = numpy.ceil(timeLag/timeInterval)
3370 freq = 30e6
3370 freq = 30e6
3371
3371
3372 listMeteors1 = []
3372 listMeteors1 = []
3373
3373
3374 for i in range(len(listMeteors)):
3374 for i in range(len(listMeteors)):
3375 meteorAux = listMeteors[i]
3375 meteorAux = listMeteors[i]
3376 if meteorAux[-1] == 0:
3376 if meteorAux[-1] == 0:
3377 mStart = listMeteors[i][1]
3377 mStart = listMeteors[i][1]
3378 mPeak = listMeteors[i][2]
3378 mPeak = listMeteors[i][2]
3379 mLag = mPeak - mStart + lag
3379 mLag = mPeak - mStart + lag
3380
3380
3381 #get the volt data between the start and end times of the meteor
3381 #get the volt data between the start and end times of the meteor
3382 meteorVolts = listVolts[i]
3382 meteorVolts = listVolts[i]
3383 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3383 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3384
3384
3385 #Get CCF
3385 #Get CCF
3386 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
3386 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
3387
3387
3388 #Method 2
3388 #Method 2
3389 slopes = numpy.zeros(numPairs)
3389 slopes = numpy.zeros(numPairs)
3390 time = numpy.array([-2,-1,1,2])*timeInterval
3390 time = numpy.array([-2,-1,1,2])*timeInterval
3391 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
3391 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
3392
3392
3393 #Correct phases
3393 #Correct phases
3394 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
3394 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
3395 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
3395 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
3396
3396
3397 if indDer[0].shape[0] > 0:
3397 if indDer[0].shape[0] > 0:
3398 for i in range(indDer[0].shape[0]):
3398 for i in range(indDer[0].shape[0]):
3399 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
3399 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
3400 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
3400 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
3401
3401
3402 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
3402 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
3403 for j in range(numPairs):
3403 for j in range(numPairs):
3404 fit = stats.linregress(time, angAllCCF[j,:])
3404 fit = stats.linregress(time, angAllCCF[j,:])
3405 slopes[j] = fit[0]
3405 slopes[j] = fit[0]
3406
3406
3407 #Remove Outlier
3407 #Remove Outlier
3408 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3408 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3409 # slopes = numpy.delete(slopes,indOut)
3409 # slopes = numpy.delete(slopes,indOut)
3410 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3410 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3411 # slopes = numpy.delete(slopes,indOut)
3411 # slopes = numpy.delete(slopes,indOut)
3412
3412
3413 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
3413 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
3414 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
3414 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
3415 meteorAux[-2] = radialError
3415 meteorAux[-2] = radialError
3416 meteorAux[-3] = radialVelocity
3416 meteorAux[-3] = radialVelocity
3417
3417
3418 #Setting Error
3418 #Setting Error
3419 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
3419 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
3420 if numpy.abs(radialVelocity) > 200:
3420 if numpy.abs(radialVelocity) > 200:
3421 meteorAux[-1] = 15
3421 meteorAux[-1] = 15
3422 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
3422 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
3423 elif radialError > radialStdThresh:
3423 elif radialError > radialStdThresh:
3424 meteorAux[-1] = 12
3424 meteorAux[-1] = 12
3425
3425
3426 listMeteors1.append(meteorAux)
3426 listMeteors1.append(meteorAux)
3427 return listMeteors1
3427 return listMeteors1
3428
3428
3429 def __setNewArrays(self, listMeteors, date, heiRang):
3429 def __setNewArrays(self, listMeteors, date, heiRang):
3430
3430
3431 #New arrays
3431 #New arrays
3432 arrayMeteors = numpy.array(listMeteors)
3432 arrayMeteors = numpy.array(listMeteors)
3433 arrayParameters = numpy.zeros((len(listMeteors), 13))
3433 arrayParameters = numpy.zeros((len(listMeteors), 13))
3434
3434
3435 #Date inclusion
3435 #Date inclusion
3436 # date = re.findall(r'\((.*?)\)', date)
3436 # date = re.findall(r'\((.*?)\)', date)
3437 # date = date[0].split(',')
3437 # date = date[0].split(',')
3438 # date = map(int, date)
3438 # date = map(int, date)
3439 #
3439 #
3440 # if len(date)<6:
3440 # if len(date)<6:
3441 # date.append(0)
3441 # date.append(0)
3442 #
3442 #
3443 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
3443 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
3444 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
3444 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
3445 arrayDate = numpy.tile(date, (len(listMeteors)))
3445 arrayDate = numpy.tile(date, (len(listMeteors)))
3446
3446
3447 #Meteor array
3447 #Meteor array
3448 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
3448 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
3449 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
3449 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
3450
3450
3451 #Parameters Array
3451 #Parameters Array
3452 arrayParameters[:,0] = arrayDate #Date
3452 arrayParameters[:,0] = arrayDate #Date
3453 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
3453 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
3454 arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
3454 arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
3455 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
3455 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
3456 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
3456 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
3457
3457
3458
3458
3459 return arrayParameters
3459 return arrayParameters
3460
3460
3461 class CorrectSMPhases(Operation):
3461 class CorrectSMPhases(Operation):
3462
3462
3463 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
3463 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
3464
3464
3465 arrayParameters = dataOut.data_param
3465 arrayParameters = dataOut.data_param
3466 pairsList = []
3466 pairsList = []
3467 pairx = (0,1)
3467 pairx = (0,1)
3468 pairy = (2,3)
3468 pairy = (2,3)
3469 pairsList.append(pairx)
3469 pairsList.append(pairx)
3470 pairsList.append(pairy)
3470 pairsList.append(pairy)
3471 jph = numpy.zeros(4)
3471 jph = numpy.zeros(4)
3472
3472
3473 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
3473 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
3474 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
3474 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
3475 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
3475 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
3476
3476
3477 meteorOps = SMOperations()
3477 meteorOps = SMOperations()
3478 if channelPositions == None:
3478 if channelPositions is None:
3479 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3479 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3480 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3480 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3481
3481
3482 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3482 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3483 h = (hmin,hmax)
3483 h = (hmin,hmax)
3484
3484
3485 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
3485 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
3486
3486
3487 dataOut.data_param = arrayParameters
3487 dataOut.data_param = arrayParameters
3488 return
3488 return
3489
3489
3490 class SMPhaseCalibration(Operation):
3490 class SMPhaseCalibration(Operation):
3491
3491
3492 __buffer = None
3492 __buffer = None
3493
3493
3494 __initime = None
3494 __initime = None
3495
3495
3496 __dataReady = False
3496 __dataReady = False
3497
3497
3498 __isConfig = False
3498 __isConfig = False
3499
3499
3500 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
3500 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
3501
3501
3502 dataTime = currentTime + paramInterval
3502 dataTime = currentTime + paramInterval
3503 deltaTime = dataTime - initTime
3503 deltaTime = dataTime - initTime
3504
3504
3505 if deltaTime >= outputInterval or deltaTime < 0:
3505 if deltaTime >= outputInterval or deltaTime < 0:
3506 return True
3506 return True
3507
3507
3508 return False
3508 return False
3509
3509
3510 def __getGammas(self, pairs, d, phases):
3510 def __getGammas(self, pairs, d, phases):
3511 gammas = numpy.zeros(2)
3511 gammas = numpy.zeros(2)
3512
3512
3513 for i in range(len(pairs)):
3513 for i in range(len(pairs)):
3514
3514
3515 pairi = pairs[i]
3515 pairi = pairs[i]
3516
3516
3517 phip3 = phases[:,pairi[0]]
3517 phip3 = phases[:,pairi[0]]
3518 d3 = d[pairi[0]]
3518 d3 = d[pairi[0]]
3519 phip2 = phases[:,pairi[1]]
3519 phip2 = phases[:,pairi[1]]
3520 d2 = d[pairi[1]]
3520 d2 = d[pairi[1]]
3521 #Calculating gamma
3521 #Calculating gamma
3522 # jdcos = alp1/(k*d1)
3522 # jdcos = alp1/(k*d1)
3523 # jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0)))
3523 # jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0)))
3524 jgamma = -phip2*d3/d2 - phip3
3524 jgamma = -phip2*d3/d2 - phip3
3525 jgamma = numpy.angle(numpy.exp(1j*jgamma))
3525 jgamma = numpy.angle(numpy.exp(1j*jgamma))
3526 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
3526 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
3527 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
3527 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
3528
3528
3529 #Revised distribution
3529 #Revised distribution
3530 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
3530 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
3531
3531
3532 #Histogram
3532 #Histogram
3533 nBins = 64
3533 nBins = 64
3534 rmin = -0.5*numpy.pi
3534 rmin = -0.5*numpy.pi
3535 rmax = 0.5*numpy.pi
3535 rmax = 0.5*numpy.pi
3536 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
3536 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
3537
3537
3538 meteorsY = phaseHisto[0]
3538 meteorsY = phaseHisto[0]
3539 phasesX = phaseHisto[1][:-1]
3539 phasesX = phaseHisto[1][:-1]
3540 width = phasesX[1] - phasesX[0]
3540 width = phasesX[1] - phasesX[0]
3541 phasesX += width/2
3541 phasesX += width/2
3542
3542
3543 #Gaussian aproximation
3543 #Gaussian aproximation
3544 bpeak = meteorsY.argmax()
3544 bpeak = meteorsY.argmax()
3545 peak = meteorsY.max()
3545 peak = meteorsY.max()
3546 jmin = bpeak - 5
3546 jmin = bpeak - 5
3547 jmax = bpeak + 5 + 1
3547 jmax = bpeak + 5 + 1
3548
3548
3549 if jmin<0:
3549 if jmin<0:
3550 jmin = 0
3550 jmin = 0
3551 jmax = 6
3551 jmax = 6
3552 elif jmax > meteorsY.size:
3552 elif jmax > meteorsY.size:
3553 jmin = meteorsY.size - 6
3553 jmin = meteorsY.size - 6
3554 jmax = meteorsY.size
3554 jmax = meteorsY.size
3555
3555
3556 x0 = numpy.array([peak,bpeak,50])
3556 x0 = numpy.array([peak,bpeak,50])
3557 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
3557 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
3558
3558
3559 #Gammas
3559 #Gammas
3560 gammas[i] = coeff[0][1]
3560 gammas[i] = coeff[0][1]
3561
3561
3562 return gammas
3562 return gammas
3563
3563
3564 def __residualFunction(self, coeffs, y, t):
3564 def __residualFunction(self, coeffs, y, t):
3565
3565
3566 return y - self.__gauss_function(t, coeffs)
3566 return y - self.__gauss_function(t, coeffs)
3567
3567
3568 def __gauss_function(self, t, coeffs):
3568 def __gauss_function(self, t, coeffs):
3569
3569
3570 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
3570 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
3571
3571
3572 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
3572 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
3573 meteorOps = SMOperations()
3573 meteorOps = SMOperations()
3574 nchan = 4
3574 nchan = 4
3575 pairx = pairsList[0] #x es 0
3575 pairx = pairsList[0] #x es 0
3576 pairy = pairsList[1] #y es 1
3576 pairy = pairsList[1] #y es 1
3577 center_xangle = 0
3577 center_xangle = 0
3578 center_yangle = 0
3578 center_yangle = 0
3579 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
3579 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
3580 ntimes = len(range_angle)
3580 ntimes = len(range_angle)
3581
3581
3582 nstepsx = 20
3582 nstepsx = 20
3583 nstepsy = 20
3583 nstepsy = 20
3584
3584
3585 for iz in range(ntimes):
3585 for iz in range(ntimes):
3586 min_xangle = -range_angle[iz]/2 + center_xangle
3586 min_xangle = -range_angle[iz]/2 + center_xangle
3587 max_xangle = range_angle[iz]/2 + center_xangle
3587 max_xangle = range_angle[iz]/2 + center_xangle
3588 min_yangle = -range_angle[iz]/2 + center_yangle
3588 min_yangle = -range_angle[iz]/2 + center_yangle
3589 max_yangle = range_angle[iz]/2 + center_yangle
3589 max_yangle = range_angle[iz]/2 + center_yangle
3590
3590
3591 inc_x = (max_xangle-min_xangle)/nstepsx
3591 inc_x = (max_xangle-min_xangle)/nstepsx
3592 inc_y = (max_yangle-min_yangle)/nstepsy
3592 inc_y = (max_yangle-min_yangle)/nstepsy
3593
3593
3594 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
3594 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
3595 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
3595 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
3596 penalty = numpy.zeros((nstepsx,nstepsy))
3596 penalty = numpy.zeros((nstepsx,nstepsy))
3597 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
3597 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
3598 jph = numpy.zeros(nchan)
3598 jph = numpy.zeros(nchan)
3599
3599
3600 # Iterations looking for the offset
3600 # Iterations looking for the offset
3601 for iy in range(int(nstepsy)):
3601 for iy in range(int(nstepsy)):
3602 for ix in range(int(nstepsx)):
3602 for ix in range(int(nstepsx)):
3603 d3 = d[pairsList[1][0]]
3603 d3 = d[pairsList[1][0]]
3604 d2 = d[pairsList[1][1]]
3604 d2 = d[pairsList[1][1]]
3605 d5 = d[pairsList[0][0]]
3605 d5 = d[pairsList[0][0]]
3606 d4 = d[pairsList[0][1]]
3606 d4 = d[pairsList[0][1]]
3607
3607
3608 alp2 = alpha_y[iy] #gamma 1
3608 alp2 = alpha_y[iy] #gamma 1
3609 alp4 = alpha_x[ix] #gamma 0
3609 alp4 = alpha_x[ix] #gamma 0
3610
3610
3611 alp3 = -alp2*d3/d2 - gammas[1]
3611 alp3 = -alp2*d3/d2 - gammas[1]
3612 alp5 = -alp4*d5/d4 - gammas[0]
3612 alp5 = -alp4*d5/d4 - gammas[0]
3613 # jph[pairy[1]] = alpha_y[iy]
3613 # jph[pairy[1]] = alpha_y[iy]
3614 # jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
3614 # jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
3615
3615
3616 # jph[pairx[1]] = alpha_x[ix]
3616 # jph[pairx[1]] = alpha_x[ix]
3617 # jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
3617 # jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
3618 jph[pairsList[0][1]] = alp4
3618 jph[pairsList[0][1]] = alp4
3619 jph[pairsList[0][0]] = alp5
3619 jph[pairsList[0][0]] = alp5
3620 jph[pairsList[1][0]] = alp3
3620 jph[pairsList[1][0]] = alp3
3621 jph[pairsList[1][1]] = alp2
3621 jph[pairsList[1][1]] = alp2
3622 jph_array[:,ix,iy] = jph
3622 jph_array[:,ix,iy] = jph
3623 # d = [2.0,2.5,2.5,2.0]
3623 # d = [2.0,2.5,2.5,2.0]
3624 #falta chequear si va a leer bien los meteoros
3624 #falta chequear si va a leer bien los meteoros
3625 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
3625 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
3626 error = meteorsArray1[:,-1]
3626 error = meteorsArray1[:,-1]
3627 ind1 = numpy.where(error==0)[0]
3627 ind1 = numpy.where(error==0)[0]
3628 penalty[ix,iy] = ind1.size
3628 penalty[ix,iy] = ind1.size
3629
3629
3630 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
3630 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
3631 phOffset = jph_array[:,i,j]
3631 phOffset = jph_array[:,i,j]
3632
3632
3633 center_xangle = phOffset[pairx[1]]
3633 center_xangle = phOffset[pairx[1]]
3634 center_yangle = phOffset[pairy[1]]
3634 center_yangle = phOffset[pairy[1]]
3635
3635
3636 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
3636 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
3637 phOffset = phOffset*180/numpy.pi
3637 phOffset = phOffset*180/numpy.pi
3638 return phOffset
3638 return phOffset
3639
3639
3640
3640
3641 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
3641 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
3642
3642
3643 dataOut.flagNoData = True
3643 dataOut.flagNoData = True
3644 self.__dataReady = False
3644 self.__dataReady = False
3645 dataOut.outputInterval = nHours*3600
3645 dataOut.outputInterval = nHours*3600
3646
3646
3647 if self.__isConfig == False:
3647 if self.__isConfig == False:
3648 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
3648 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
3649 #Get Initial LTC time
3649 #Get Initial LTC time
3650 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
3650 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
3651 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
3651 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
3652
3652
3653 self.__isConfig = True
3653 self.__isConfig = True
3654
3654
3655 if self.__buffer == None:
3655 if self.__buffer is None:
3656 self.__buffer = dataOut.data_param.copy()
3656 self.__buffer = dataOut.data_param.copy()
3657
3657
3658 else:
3658 else:
3659 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
3659 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
3660
3660
3661 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
3661 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
3662
3662
3663 if self.__dataReady:
3663 if self.__dataReady:
3664 dataOut.utctimeInit = self.__initime
3664 dataOut.utctimeInit = self.__initime
3665 self.__initime += dataOut.outputInterval #to erase time offset
3665 self.__initime += dataOut.outputInterval #to erase time offset
3666
3666
3667 freq = dataOut.frequency
3667 freq = dataOut.frequency
3668 c = dataOut.C #m/s
3668 c = dataOut.C #m/s
3669 lamb = c/freq
3669 lamb = c/freq
3670 k = 2*numpy.pi/lamb
3670 k = 2*numpy.pi/lamb
3671 azimuth = 0
3671 azimuth = 0
3672 h = (hmin, hmax)
3672 h = (hmin, hmax)
3673 # pairs = ((0,1),(2,3)) #Estrella
3673 # pairs = ((0,1),(2,3)) #Estrella
3674 # pairs = ((1,0),(2,3)) #T
3674 # pairs = ((1,0),(2,3)) #T
3675
3675
3676 if channelPositions is None:
3676 if channelPositions is None:
3677 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3677 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3678 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3678 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3679 meteorOps = SMOperations()
3679 meteorOps = SMOperations()
3680 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3680 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3681
3681
3682 #Checking correct order of pairs
3682 #Checking correct order of pairs
3683 pairs = []
3683 pairs = []
3684 if distances[1] > distances[0]:
3684 if distances[1] > distances[0]:
3685 pairs.append((1,0))
3685 pairs.append((1,0))
3686 else:
3686 else:
3687 pairs.append((0,1))
3687 pairs.append((0,1))
3688
3688
3689 if distances[3] > distances[2]:
3689 if distances[3] > distances[2]:
3690 pairs.append((3,2))
3690 pairs.append((3,2))
3691 else:
3691 else:
3692 pairs.append((2,3))
3692 pairs.append((2,3))
3693 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
3693 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
3694
3694
3695 meteorsArray = self.__buffer
3695 meteorsArray = self.__buffer
3696 error = meteorsArray[:,-1]
3696 error = meteorsArray[:,-1]
3697 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
3697 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
3698 ind1 = numpy.where(boolError)[0]
3698 ind1 = numpy.where(boolError)[0]
3699 meteorsArray = meteorsArray[ind1,:]
3699 meteorsArray = meteorsArray[ind1,:]
3700 meteorsArray[:,-1] = 0
3700 meteorsArray[:,-1] = 0
3701 phases = meteorsArray[:,8:12]
3701 phases = meteorsArray[:,8:12]
3702
3702
3703 #Calculate Gammas
3703 #Calculate Gammas
3704 gammas = self.__getGammas(pairs, distances, phases)
3704 gammas = self.__getGammas(pairs, distances, phases)
3705 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
3705 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
3706 #Calculate Phases
3706 #Calculate Phases
3707 phasesOff = self.__getPhases(azimuth, h, pairs, distances, gammas, meteorsArray)
3707 phasesOff = self.__getPhases(azimuth, h, pairs, distances, gammas, meteorsArray)
3708 phasesOff = phasesOff.reshape((1,phasesOff.size))
3708 phasesOff = phasesOff.reshape((1,phasesOff.size))
3709 dataOut.data_output = -phasesOff
3709 dataOut.data_output = -phasesOff
3710 dataOut.flagNoData = False
3710 dataOut.flagNoData = False
3711 self.__buffer = None
3711 self.__buffer = None
3712
3712
3713
3713
3714 return
3714 return
3715
3715
3716 class SMOperations():
3716 class SMOperations():
3717
3717
3718 def __init__(self):
3718 def __init__(self):
3719
3719
3720 return
3720 return
3721
3721
3722 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
3722 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
3723
3723
3724 arrayParameters = arrayParameters0.copy()
3724 arrayParameters = arrayParameters0.copy()
3725 hmin = h[0]
3725 hmin = h[0]
3726 hmax = h[1]
3726 hmax = h[1]
3727
3727
3728 #Calculate AOA (Error N 3, 4)
3728 #Calculate AOA (Error N 3, 4)
3729 #JONES ET AL. 1998
3729 #JONES ET AL. 1998
3730 AOAthresh = numpy.pi/8
3730 AOAthresh = numpy.pi/8
3731 error = arrayParameters[:,-1]
3731 error = arrayParameters[:,-1]
3732 phases = -arrayParameters[:,8:12] + jph
3732 phases = -arrayParameters[:,8:12] + jph
3733 # phases = numpy.unwrap(phases)
3733 # phases = numpy.unwrap(phases)
3734 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
3734 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
3735
3735
3736 #Calculate Heights (Error N 13 and 14)
3736 #Calculate Heights (Error N 13 and 14)
3737 error = arrayParameters[:,-1]
3737 error = arrayParameters[:,-1]
3738 Ranges = arrayParameters[:,1]
3738 Ranges = arrayParameters[:,1]
3739 zenith = arrayParameters[:,4]
3739 zenith = arrayParameters[:,4]
3740 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
3740 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
3741
3741
3742 #----------------------- Get Final data ------------------------------------
3742 #----------------------- Get Final data ------------------------------------
3743 # error = arrayParameters[:,-1]
3743 # error = arrayParameters[:,-1]
3744 # ind1 = numpy.where(error==0)[0]
3744 # ind1 = numpy.where(error==0)[0]
3745 # arrayParameters = arrayParameters[ind1,:]
3745 # arrayParameters = arrayParameters[ind1,:]
3746
3746
3747 return arrayParameters
3747 return arrayParameters
3748
3748
3749 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
3749 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
3750
3750
3751 arrayAOA = numpy.zeros((phases.shape[0],3))
3751 arrayAOA = numpy.zeros((phases.shape[0],3))
3752 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
3752 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
3753
3753
3754 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3754 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3755 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3755 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3756 arrayAOA[:,2] = cosDirError
3756 arrayAOA[:,2] = cosDirError
3757
3757
3758 azimuthAngle = arrayAOA[:,0]
3758 azimuthAngle = arrayAOA[:,0]
3759 zenithAngle = arrayAOA[:,1]
3759 zenithAngle = arrayAOA[:,1]
3760
3760
3761 #Setting Error
3761 #Setting Error
3762 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
3762 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
3763 error[indError] = 0
3763 error[indError] = 0
3764 #Number 3: AOA not fesible
3764 #Number 3: AOA not fesible
3765 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3765 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3766 error[indInvalid] = 3
3766 error[indInvalid] = 3
3767 #Number 4: Large difference in AOAs obtained from different antenna baselines
3767 #Number 4: Large difference in AOAs obtained from different antenna baselines
3768 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3768 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3769 error[indInvalid] = 4
3769 error[indInvalid] = 4
3770 return arrayAOA, error
3770 return arrayAOA, error
3771
3771
3772 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
3772 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
3773
3773
3774 #Initializing some variables
3774 #Initializing some variables
3775 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3775 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3776 ang_aux = ang_aux.reshape(1,ang_aux.size)
3776 ang_aux = ang_aux.reshape(1,ang_aux.size)
3777
3777
3778 cosdir = numpy.zeros((arrayPhase.shape[0],2))
3778 cosdir = numpy.zeros((arrayPhase.shape[0],2))
3779 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3779 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3780
3780
3781
3781
3782 for i in range(2):
3782 for i in range(2):
3783 ph0 = arrayPhase[:,pairsList[i][0]]
3783 ph0 = arrayPhase[:,pairsList[i][0]]
3784 ph1 = arrayPhase[:,pairsList[i][1]]
3784 ph1 = arrayPhase[:,pairsList[i][1]]
3785 d0 = distances[pairsList[i][0]]
3785 d0 = distances[pairsList[i][0]]
3786 d1 = distances[pairsList[i][1]]
3786 d1 = distances[pairsList[i][1]]
3787
3787
3788 ph0_aux = ph0 + ph1
3788 ph0_aux = ph0 + ph1
3789 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
3789 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
3790 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
3790 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
3791 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
3791 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
3792 #First Estimation
3792 #First Estimation
3793 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
3793 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
3794
3794
3795 #Most-Accurate Second Estimation
3795 #Most-Accurate Second Estimation
3796 phi1_aux = ph0 - ph1
3796 phi1_aux = ph0 - ph1
3797 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3797 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3798 #Direction Cosine 1
3798 #Direction Cosine 1
3799 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
3799 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
3800
3800
3801 #Searching the correct Direction Cosine
3801 #Searching the correct Direction Cosine
3802 cosdir0_aux = cosdir0[:,i]
3802 cosdir0_aux = cosdir0[:,i]
3803 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3803 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3804 #Minimum Distance
3804 #Minimum Distance
3805 cosDiff = (cosdir1 - cosdir0_aux)**2
3805 cosDiff = (cosdir1 - cosdir0_aux)**2
3806 indcos = cosDiff.argmin(axis = 1)
3806 indcos = cosDiff.argmin(axis = 1)
3807 #Saving Value obtained
3807 #Saving Value obtained
3808 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3808 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3809
3809
3810 return cosdir0, cosdir
3810 return cosdir0, cosdir
3811
3811
3812 def __calculateAOA(self, cosdir, azimuth):
3812 def __calculateAOA(self, cosdir, azimuth):
3813 cosdirX = cosdir[:,0]
3813 cosdirX = cosdir[:,0]
3814 cosdirY = cosdir[:,1]
3814 cosdirY = cosdir[:,1]
3815
3815
3816 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3816 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3817 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
3817 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
3818 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3818 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3819
3819
3820 return angles
3820 return angles
3821
3821
3822 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3822 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3823
3823
3824 Ramb = 375 #Ramb = c/(2*PRF)
3824 Ramb = 375 #Ramb = c/(2*PRF)
3825 Re = 6371 #Earth Radius
3825 Re = 6371 #Earth Radius
3826 heights = numpy.zeros(Ranges.shape)
3826 heights = numpy.zeros(Ranges.shape)
3827
3827
3828 R_aux = numpy.array([0,1,2])*Ramb
3828 R_aux = numpy.array([0,1,2])*Ramb
3829 R_aux = R_aux.reshape(1,R_aux.size)
3829 R_aux = R_aux.reshape(1,R_aux.size)
3830
3830
3831 Ranges = Ranges.reshape(Ranges.size,1)
3831 Ranges = Ranges.reshape(Ranges.size,1)
3832
3832
3833 Ri = Ranges + R_aux
3833 Ri = Ranges + R_aux
3834 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3834 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3835
3835
3836 #Check if there is a height between 70 and 110 km
3836 #Check if there is a height between 70 and 110 km
3837 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3837 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3838 ind_h = numpy.where(h_bool == 1)[0]
3838 ind_h = numpy.where(h_bool == 1)[0]
3839
3839
3840 hCorr = hi[ind_h, :]
3840 hCorr = hi[ind_h, :]
3841 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3841 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3842
3842
3843 hCorr = hi[ind_hCorr][:len(ind_h)]
3843 hCorr = hi[ind_hCorr][:len(ind_h)]
3844 heights[ind_h] = hCorr
3844 heights[ind_h] = hCorr
3845
3845
3846 #Setting Error
3846 #Setting Error
3847 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3847 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3848 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3848 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3849 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
3849 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
3850 error[indError] = 0
3850 error[indError] = 0
3851 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3851 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3852 error[indInvalid2] = 14
3852 error[indInvalid2] = 14
3853 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3853 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3854 error[indInvalid1] = 13
3854 error[indInvalid1] = 13
3855
3855
3856 return heights, error
3856 return heights, error
3857
3857
3858 def getPhasePairs(self, channelPositions):
3858 def getPhasePairs(self, channelPositions):
3859 chanPos = numpy.array(channelPositions)
3859 chanPos = numpy.array(channelPositions)
3860 listOper = list(itertools.combinations(range(5),2))
3860 listOper = list(itertools.combinations(range(5),2))
3861
3861
3862 distances = numpy.zeros(4)
3862 distances = numpy.zeros(4)
3863 axisX = []
3863 axisX = []
3864 axisY = []
3864 axisY = []
3865 distX = numpy.zeros(3)
3865 distX = numpy.zeros(3)
3866 distY = numpy.zeros(3)
3866 distY = numpy.zeros(3)
3867 ix = 0
3867 ix = 0
3868 iy = 0
3868 iy = 0
3869
3869
3870 pairX = numpy.zeros((2,2))
3870 pairX = numpy.zeros((2,2))
3871 pairY = numpy.zeros((2,2))
3871 pairY = numpy.zeros((2,2))
3872
3872
3873 for i in range(len(listOper)):
3873 for i in range(len(listOper)):
3874 pairi = listOper[i]
3874 pairi = listOper[i]
3875
3875
3876 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
3876 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
3877
3877
3878 if posDif[0] == 0:
3878 if posDif[0] == 0:
3879 axisY.append(pairi)
3879 axisY.append(pairi)
3880 distY[iy] = posDif[1]
3880 distY[iy] = posDif[1]
3881 iy += 1
3881 iy += 1
3882 elif posDif[1] == 0:
3882 elif posDif[1] == 0:
3883 axisX.append(pairi)
3883 axisX.append(pairi)
3884 distX[ix] = posDif[0]
3884 distX[ix] = posDif[0]
3885 ix += 1
3885 ix += 1
3886
3886
3887 for i in range(2):
3887 for i in range(2):
3888 if i==0:
3888 if i==0:
3889 dist0 = distX
3889 dist0 = distX
3890 axis0 = axisX
3890 axis0 = axisX
3891 else:
3891 else:
3892 dist0 = distY
3892 dist0 = distY
3893 axis0 = axisY
3893 axis0 = axisY
3894
3894
3895 side = numpy.argsort(dist0)[:-1]
3895 side = numpy.argsort(dist0)[:-1]
3896 axis0 = numpy.array(axis0)[side,:]
3896 axis0 = numpy.array(axis0)[side,:]
3897 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
3897 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
3898 axis1 = numpy.unique(numpy.reshape(axis0,4))
3898 axis1 = numpy.unique(numpy.reshape(axis0,4))
3899 side = axis1[axis1 != chanC]
3899 side = axis1[axis1 != chanC]
3900 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
3900 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
3901 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
3901 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
3902 if diff1<0:
3902 if diff1<0:
3903 chan2 = side[0]
3903 chan2 = side[0]
3904 d2 = numpy.abs(diff1)
3904 d2 = numpy.abs(diff1)
3905 chan1 = side[1]
3905 chan1 = side[1]
3906 d1 = numpy.abs(diff2)
3906 d1 = numpy.abs(diff2)
3907 else:
3907 else:
3908 chan2 = side[1]
3908 chan2 = side[1]
3909 d2 = numpy.abs(diff2)
3909 d2 = numpy.abs(diff2)
3910 chan1 = side[0]
3910 chan1 = side[0]
3911 d1 = numpy.abs(diff1)
3911 d1 = numpy.abs(diff1)
3912
3912
3913 if i==0:
3913 if i==0:
3914 chanCX = chanC
3914 chanCX = chanC
3915 chan1X = chan1
3915 chan1X = chan1
3916 chan2X = chan2
3916 chan2X = chan2
3917 distances[0:2] = numpy.array([d1,d2])
3917 distances[0:2] = numpy.array([d1,d2])
3918 else:
3918 else:
3919 chanCY = chanC
3919 chanCY = chanC
3920 chan1Y = chan1
3920 chan1Y = chan1
3921 chan2Y = chan2
3921 chan2Y = chan2
3922 distances[2:4] = numpy.array([d1,d2])
3922 distances[2:4] = numpy.array([d1,d2])
3923 # axisXsides = numpy.reshape(axisX[ix,:],4)
3923 # axisXsides = numpy.reshape(axisX[ix,:],4)
3924 #
3924 #
3925 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
3925 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
3926 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
3926 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
3927 #
3927 #
3928 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
3928 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
3929 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
3929 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
3930 # channel25X = int(pairX[0,ind25X])
3930 # channel25X = int(pairX[0,ind25X])
3931 # channel20X = int(pairX[1,ind20X])
3931 # channel20X = int(pairX[1,ind20X])
3932 # ind25Y = numpy.where(pairY[0,:] != channelCentY)[0][0]
3932 # ind25Y = numpy.where(pairY[0,:] != channelCentY)[0][0]
3933 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
3933 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
3934 # channel25Y = int(pairY[0,ind25Y])
3934 # channel25Y = int(pairY[0,ind25Y])
3935 # channel20Y = int(pairY[1,ind20Y])
3935 # channel20Y = int(pairY[1,ind20Y])
3936
3936
3937 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
3937 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
3938 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
3938 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
3939
3939
3940 return pairslist, distances
3940 return pairslist, distances
3941 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
3941 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
3942 #
3942 #
3943 # arrayAOA = numpy.zeros((phases.shape[0],3))
3943 # arrayAOA = numpy.zeros((phases.shape[0],3))
3944 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
3944 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
3945 #
3945 #
3946 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3946 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3947 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3947 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3948 # arrayAOA[:,2] = cosDirError
3948 # arrayAOA[:,2] = cosDirError
3949 #
3949 #
3950 # azimuthAngle = arrayAOA[:,0]
3950 # azimuthAngle = arrayAOA[:,0]
3951 # zenithAngle = arrayAOA[:,1]
3951 # zenithAngle = arrayAOA[:,1]
3952 #
3952 #
3953 # #Setting Error
3953 # #Setting Error
3954 # #Number 3: AOA not fesible
3954 # #Number 3: AOA not fesible
3955 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3955 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3956 # error[indInvalid] = 3
3956 # error[indInvalid] = 3
3957 # #Number 4: Large difference in AOAs obtained from different antenna baselines
3957 # #Number 4: Large difference in AOAs obtained from different antenna baselines
3958 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3958 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3959 # error[indInvalid] = 4
3959 # error[indInvalid] = 4
3960 # return arrayAOA, error
3960 # return arrayAOA, error
3961 #
3961 #
3962 # def __getDirectionCosines(self, arrayPhase, pairsList):
3962 # def __getDirectionCosines(self, arrayPhase, pairsList):
3963 #
3963 #
3964 # #Initializing some variables
3964 # #Initializing some variables
3965 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3965 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3966 # ang_aux = ang_aux.reshape(1,ang_aux.size)
3966 # ang_aux = ang_aux.reshape(1,ang_aux.size)
3967 #
3967 #
3968 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
3968 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
3969 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3969 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3970 #
3970 #
3971 #
3971 #
3972 # for i in range(2):
3972 # for i in range(2):
3973 # #First Estimation
3973 # #First Estimation
3974 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
3974 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
3975 # #Dealias
3975 # #Dealias
3976 # indcsi = numpy.where(phi0_aux > numpy.pi)
3976 # indcsi = numpy.where(phi0_aux > numpy.pi)
3977 # phi0_aux[indcsi] -= 2*numpy.pi
3977 # phi0_aux[indcsi] -= 2*numpy.pi
3978 # indcsi = numpy.where(phi0_aux < -numpy.pi)
3978 # indcsi = numpy.where(phi0_aux < -numpy.pi)
3979 # phi0_aux[indcsi] += 2*numpy.pi
3979 # phi0_aux[indcsi] += 2*numpy.pi
3980 # #Direction Cosine 0
3980 # #Direction Cosine 0
3981 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
3981 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
3982 #
3982 #
3983 # #Most-Accurate Second Estimation
3983 # #Most-Accurate Second Estimation
3984 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
3984 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
3985 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3985 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3986 # #Direction Cosine 1
3986 # #Direction Cosine 1
3987 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
3987 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
3988 #
3988 #
3989 # #Searching the correct Direction Cosine
3989 # #Searching the correct Direction Cosine
3990 # cosdir0_aux = cosdir0[:,i]
3990 # cosdir0_aux = cosdir0[:,i]
3991 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3991 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3992 # #Minimum Distance
3992 # #Minimum Distance
3993 # cosDiff = (cosdir1 - cosdir0_aux)**2
3993 # cosDiff = (cosdir1 - cosdir0_aux)**2
3994 # indcos = cosDiff.argmin(axis = 1)
3994 # indcos = cosDiff.argmin(axis = 1)
3995 # #Saving Value obtained
3995 # #Saving Value obtained
3996 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3996 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3997 #
3997 #
3998 # return cosdir0, cosdir
3998 # return cosdir0, cosdir
3999 #
3999 #
4000 # def __calculateAOA(self, cosdir, azimuth):
4000 # def __calculateAOA(self, cosdir, azimuth):
4001 # cosdirX = cosdir[:,0]
4001 # cosdirX = cosdir[:,0]
4002 # cosdirY = cosdir[:,1]
4002 # cosdirY = cosdir[:,1]
4003 #
4003 #
4004 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
4004 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
4005 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
4005 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
4006 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
4006 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
4007 #
4007 #
4008 # return angles
4008 # return angles
4009 #
4009 #
4010 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
4010 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
4011 #
4011 #
4012 # Ramb = 375 #Ramb = c/(2*PRF)
4012 # Ramb = 375 #Ramb = c/(2*PRF)
4013 # Re = 6371 #Earth Radius
4013 # Re = 6371 #Earth Radius
4014 # heights = numpy.zeros(Ranges.shape)
4014 # heights = numpy.zeros(Ranges.shape)
4015 #
4015 #
4016 # R_aux = numpy.array([0,1,2])*Ramb
4016 # R_aux = numpy.array([0,1,2])*Ramb
4017 # R_aux = R_aux.reshape(1,R_aux.size)
4017 # R_aux = R_aux.reshape(1,R_aux.size)
4018 #
4018 #
4019 # Ranges = Ranges.reshape(Ranges.size,1)
4019 # Ranges = Ranges.reshape(Ranges.size,1)
4020 #
4020 #
4021 # Ri = Ranges + R_aux
4021 # Ri = Ranges + R_aux
4022 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
4022 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
4023 #
4023 #
4024 # #Check if there is a height between 70 and 110 km
4024 # #Check if there is a height between 70 and 110 km
4025 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
4025 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
4026 # ind_h = numpy.where(h_bool == 1)[0]
4026 # ind_h = numpy.where(h_bool == 1)[0]
4027 #
4027 #
4028 # hCorr = hi[ind_h, :]
4028 # hCorr = hi[ind_h, :]
4029 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
4029 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
4030 #
4030 #
4031 # hCorr = hi[ind_hCorr]
4031 # hCorr = hi[ind_hCorr]
4032 # heights[ind_h] = hCorr
4032 # heights[ind_h] = hCorr
4033 #
4033 #
4034 # #Setting Error
4034 # #Setting Error
4035 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
4035 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
4036 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
4036 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
4037 #
4037 #
4038 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
4038 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
4039 # error[indInvalid2] = 14
4039 # error[indInvalid2] = 14
4040 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
4040 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
4041 # error[indInvalid1] = 13
4041 # error[indInvalid1] = 13
4042 #
4042 #
4043 # return heights, error
4043 # return heights, error
4044 No newline at end of file
4044
General Comments 0
You need to be logged in to leave comments. Login now