##// END OF EJS Templates
Changes in Correlations Processing unit
Changes in Correlations Processing unit

File last commit:

r854:23b4ca740232
r854:23b4ca740232
Show More
jroproc_parameters.py
2738 lines | 108.4 KiB | text/x-python | PythonLexer
/ schainpy / model / proc / jroproc_parameters.py
Julio Valdez
Processing Modules added:...
r502 import numpy
import math
Julio Valdez
Non Specular Meteors module
r839 from scipy import optimize, interpolate, signal, stats, ndimage
Julio Valdez
Processing Modules added:...
r502 import re
import datetime
import copy
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513 import sys
import importlib
import itertools
Julio Valdez
Processing Modules added:...
r502
from jroproc_base import ProcessingUnit, Operation
Julio Valdez
Non Specular Meteors module
r839 from schainpy.model.data.jrodata import Parameters, hildebrand_sekhon
Julio Valdez
Processing Modules added:...
r502
class ParametersProc(ProcessingUnit):
nSeconds = None
def __init__(self):
ProcessingUnit.__init__(self)
Julio Valdez
-Functional HDF5 file writer unit...
r543 # self.objectDict = {}
Julio Valdez
Processing Modules added:...
r502 self.buffer = None
self.firstdatatime = None
self.profIndex = 0
self.dataOut = Parameters()
def __updateObjFromInput(self):
self.dataOut.inputUnit = self.dataIn.type
self.dataOut.timeZone = self.dataIn.timeZone
self.dataOut.dstFlag = self.dataIn.dstFlag
self.dataOut.errorCount = self.dataIn.errorCount
self.dataOut.useLocalTime = self.dataIn.useLocalTime
self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
self.dataOut.channelList = self.dataIn.channelList
self.dataOut.heightList = self.dataIn.heightList
self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
# self.dataOut.nHeights = self.dataIn.nHeights
# self.dataOut.nChannels = self.dataIn.nChannels
self.dataOut.nBaud = self.dataIn.nBaud
self.dataOut.nCode = self.dataIn.nCode
self.dataOut.code = self.dataIn.code
# self.dataOut.nProfiles = self.dataOut.nFFTPoints
Miguel Valdez
Merge with branch schain_julia_drifts from rev. 803 to 995....
r568 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
Julio Valdez
Modification due to new block reader option in Voltage reader
r835 # self.dataOut.utctime = self.firstdatatime
self.dataOut.utctime = self.dataIn.utctime
Julio Valdez
Processing Modules added:...
r502 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
Julio Valdez
Non Specular Meteors module
r839 self.dataOut.nCohInt = self.dataIn.nCohInt
Julio Valdez
Processing Modules added:...
r502 # self.dataOut.nIncohInt = 1
self.dataOut.ippSeconds = self.dataIn.ippSeconds
# self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
self.dataOut.timeInterval = self.dataIn.timeInterval
Julio Valdez
-Functional HDF5 file writer unit...
r543 self.dataOut.heightList = self.dataIn.getHeiRange()
Julio Valdez
Processing Modules added:...
r502 self.dataOut.frequency = self.dataIn.frequency
Julio Valdez
Non Specular Meteors module
r839 self.dataOut.noise = self.dataIn.noise
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Modification due to new block reader option in Voltage reader
r835 def run(self):
Julio Valdez
Processing Modules added:...
r502
#---------------------- Voltage Data ---------------------------
if self.dataIn.type == "Voltage":
Julio Valdez
Correction to Spaced Antenna libraries
r762
Julio Valdez
Modification due to new block reader option in Voltage reader
r835 self.__updateObjFromInput()
self.dataOut.data_pre = self.dataIn.data.copy()
self.dataOut.flagNoData = False
self.dataOut.utctimeInit = self.dataIn.utctime
self.dataOut.paramInterval = self.dataIn.nProfiles*self.dataIn.nCohInt*self.dataIn.ippSeconds
return
Julio Valdez
Processing Modules added:...
r502
#---------------------- Spectra Data ---------------------------
if self.dataIn.type == "Spectra":
Julio Valdez
Non Specular Meteors module
r839
self.dataOut.data_pre = (self.dataIn.data_spc,self.dataIn.data_cspc)
Julio Valdez
-Functional HDF5 file writer unit...
r543 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
Julio Valdez
Processing Modules added:...
r502 self.dataOut.noise = self.dataIn.getNoise()
self.dataOut.normFactor = self.dataIn.normFactor
Julio Valdez
GetMoments bug fixed
r549 self.dataOut.groupList = self.dataIn.pairsList
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513 self.dataOut.flagNoData = False
Julio Valdez
-Added Radial Velocity graphic ...
r511
Julio Valdez
Processing Modules added:...
r502 #---------------------- Correlation Data ---------------------------
if self.dataIn.type == "Correlation":
Julio Valdez
Changes in Correlations Processing unit
r854 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Changes in Correlations Processing unit
r854 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
self.dataOut.groupList = (acf_pairs, ccf_pairs)
Julio Valdez
Non Specular Meteors module
r839
self.dataOut.abscissaList = self.dataIn.lagRange
Julio Valdez
Processing Modules added:...
r502 self.dataOut.noise = self.dataIn.noise
Julio Valdez
First Draft HDF5 IO module
r514 self.dataOut.data_SNR = self.dataIn.SNR
Julio Valdez
-Functional HDF5 file writer unit...
r543 self.dataOut.flagNoData = False
Julio Valdez
Non Specular Meteors module
r839 self.dataOut.nAvg = self.dataIn.nAvg
Julio Valdez
-Functional HDF5 file writer unit...
r543
Julio Valdez
Changes in Correlations Processing unit
r854 #---------------------- Parameters Data ---------------------------
Julio Valdez
-Functional HDF5 file writer unit...
r543
if self.dataIn.type == "Parameters":
self.dataOut.copy(self.dataIn)
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513 self.dataOut.flagNoData = False
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
-Functional HDF5 file writer unit...
r543 return True
Julio Valdez
-Added Radial Velocity graphic ...
r511
self.__updateObjFromInput()
Julio Valdez
-Functional HDF5 file writer unit...
r543 self.dataOut.utctimeInit = self.dataIn.utctime
Julio Valdez
Correction to Spaced Antenna libraries
r762 self.dataOut.paramInterval = self.dataIn.timeInterval
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842
return
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 class SpectralMoments(Operation):
'''
Function SpectralMoments()
Calculates moments (power, mean, standard deviation) and SNR of the signal
Type of dataIn: Spectra
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Changes in Correlations Processing unit
r854 Configuration Parameters:
dirCosx : Cosine director in X axis
dirCosy : Cosine director in Y axis
elevation :
azimuth :
Julio Valdez
Processing Modules added:...
r502 Input:
channelList : simple channel list to select e.g. [2,3,7]
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 self.dataOut.data_pre : Spectral data
self.dataOut.abscissaList : List of frequencies
Julio Valdez
Changes in Correlations Processing unit
r854 self.dataOut.noise : Noise level per channel
Julio Valdez
Processing Modules added:...
r502
Affected:
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 self.dataOut.data_param : Parameters per channel
self.dataOut.data_SNR : SNR per channel
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 '''
Julio Valdez
Changes in Correlations Processing unit
r854 def run(self, dataOut):
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842
dataOut.data_pre = dataOut.data_pre[0]
data = dataOut.data_pre
absc = dataOut.abscissaList[:-1]
noise = dataOut.noise
Julio Valdez
Changes in Correlations Processing unit
r854 nChannel = data.shape[0]
data_param = numpy.zeros((nChannel, 4, data.shape[2]))
for ind in range(nChannel):
Julio Valdez
Processing Modules added:...
r502 data_param[ind,:,:] = self.__calculateMoments(data[ind,:,:], absc, noise[ind])
Julio Valdez
-Added Radial Velocity graphic ...
r511
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 dataOut.data_param = data_param[:,1:,:]
dataOut.data_SNR = data_param[:,0]
Julio Valdez
Processing Modules added:...
r502 return
def __calculateMoments(self, oldspec, oldfreq, n0, nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
if (nicoh == None): nicoh = 1
if (graph == None): graph = 0
if (smooth == None): smooth = 0
elif (self.smooth < 3): smooth = 0
if (type1 == None): type1 = 0
Julio Valdez
Correction to Spaced Antenna libraries
r762 if (fwindow == None): fwindow = numpy.zeros(oldfreq.size) + 1
Julio Valdez
Processing Modules added:...
r502 if (snrth == None): snrth = -3
if (dc == None): dc = 0
if (aliasing == None): aliasing = 0
if (oldfd == None): oldfd = 0
if (wwauto == None): wwauto = 0
if (n0 < 1.e-20): n0 = 1.e-20
freq = oldfreq
vec_power = numpy.zeros(oldspec.shape[1])
vec_fd = numpy.zeros(oldspec.shape[1])
vec_w = numpy.zeros(oldspec.shape[1])
vec_snr = numpy.zeros(oldspec.shape[1])
for ind in range(oldspec.shape[1]):
spec = oldspec[:,ind]
aux = spec*fwindow
max_spec = aux.max()
m = list(aux).index(max_spec)
#Smooth
if (smooth == 0): spec2 = spec
else: spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
# Calculo de Momentos
bb = spec2[range(m,spec2.size)]
bb = (bb<n0).nonzero()
bb = bb[0]
ss = spec2[range(0,m + 1)]
ss = (ss<n0).nonzero()
ss = ss[0]
if (bb.size == 0):
bb0 = spec.size - 1 - m
else:
bb0 = bb[0] - 1
if (bb0 < 0):
bb0 = 0
if (ss.size == 0): ss1 = 1
else: ss1 = max(ss) + 1
if (ss1 > m): ss1 = m
valid = numpy.asarray(range(int(m + bb0 - ss1 + 1))) + ss1
power = ((spec2[valid] - n0)*fwindow[valid]).sum()
fd = ((spec2[valid]- n0)*freq[valid]*fwindow[valid]).sum()/power
w = math.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum()/power)
snr = (spec2.mean()-n0)/n0
if (snr < 1.e-20) :
snr = 1.e-20
vec_power[ind] = power
vec_fd[ind] = fd
vec_w[ind] = w
vec_snr[ind] = snr
moments = numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
return moments
Julio Valdez
GetMoments bug fixed
r549 #------------------ Get SA Parameters --------------------------
Julio Valdez
data...
r608 def GetSAParameters(self):
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #SA en frecuencia
Julio Valdez
data...
r608 pairslist = self.dataOut.groupList
num_pairs = len(pairslist)
vel = self.dataOut.abscissaList
spectra = self.dataOut.data_pre
cspectra = self.dataIn.data_cspc
delta_v = vel[1] - vel[0]
#Calculating the power spectrum
spc_pow = numpy.sum(spectra, 3)*delta_v
#Normalizing Spectra
norm_spectra = spectra/spc_pow
#Calculating the norm_spectra at peak
max_spectra = numpy.max(norm_spectra, 3)
#Normalizing Cross Spectra
norm_cspectra = numpy.zeros(cspectra.shape)
for i in range(num_chan):
norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
max_cspectra = numpy.max(norm_cspectra,2)
max_cspectra_index = numpy.argmax(norm_cspectra, 2)
for i in range(num_pairs):
cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
Julio Valdez
Processing Modules added:...
r502 #------------------- Get Lags ----------------------------------
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 class SALags(Operation):
'''
Function GetMoments()
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 Input:
self.dataOut.data_pre
self.dataOut.abscissaList
self.dataOut.noise
self.dataOut.normFactor
self.dataOut.data_SNR
self.dataOut.groupList
self.dataOut.nChannels
Affected:
self.dataOut.data_param
'''
def run(self, dataOut):
data_acf = dataOut.data_pre[0]
data_ccf = dataOut.data_pre[1]
Julio Valdez
Changes in Correlations Processing unit
r854 normFactor_acf = dataOut.normFactor[0]
normFactor_ccf = dataOut.normFactor[1]
pairs_acf = dataOut.groupList[0]
pairs_ccf = dataOut.groupList[1]
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842
nHeights = dataOut.nHeights
Julio Valdez
Changes in Correlations Processing unit
r854 absc = dataOut.abscissaList
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 noise = dataOut.noise
SNR = dataOut.data_SNR
nChannels = dataOut.nChannels
Julio Valdez
Changes in Correlations Processing unit
r854 # pairsList = dataOut.groupList
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
Julio Valdez
Changes in Correlations Processing unit
r854
for l in range(len(pairs_acf)):
data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
for l in range(len(pairs_ccf)):
data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Changes in Correlations Processing unit
r854 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
Julio Valdez
Processing Modules added:...
r502 return
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 # def __getPairsAutoCorr(self, pairsList, nChannels):
#
# pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
#
# for l in range(len(pairsList)):
# firstChannel = pairsList[l][0]
# secondChannel = pairsList[l][1]
#
# #Obteniendo pares de Autocorrelacion
# if firstChannel == secondChannel:
# pairsAutoCorr[firstChannel] = int(l)
#
# pairsAutoCorr = pairsAutoCorr.astype(int)
#
# pairsCrossCorr = range(len(pairsList))
# pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
#
# return pairsAutoCorr, pairsCrossCorr
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Changes in Correlations Processing unit
r854 def __calculateTaus(self, data_acf, data_ccf, lagRange):
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Changes in Correlations Processing unit
r854 lag0 = data_acf.shape[1]/2
Julio Valdez
Processing Modules added:...
r502 #Funcion de Autocorrelacion
Julio Valdez
Changes in Correlations Processing unit
r854 mean_acf = stats.nanmean(data_acf, axis = 0)
Julio Valdez
Processing Modules added:...
r502
#Obtencion Indice de TauCross
Julio Valdez
Changes in Correlations Processing unit
r854 ind_ccf = data_ccf.argmax(axis = 1)
Julio Valdez
Processing Modules added:...
r502 #Obtencion Indice de TauAuto
Julio Valdez
Changes in Correlations Processing unit
r854 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
ccf_lag0 = data_ccf[:,lag0,:]
for i in range(ccf_lag0.shape[0]):
ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
Julio Valdez
Processing Modules added:...
r502
#Obtencion de TauCross y TauAuto
Julio Valdez
Changes in Correlations Processing unit
r854 tau_ccf = lagRange[ind_ccf]
tau_acf = lagRange[ind_acf]
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Changes in Correlations Processing unit
r854 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Changes in Correlations Processing unit
r854 tau_ccf[Nan1,Nan2] = numpy.nan
tau_acf[Nan1,Nan2] = numpy.nan
tau = numpy.vstack((tau_ccf,tau_acf))
Julio Valdez
Processing Modules added:...
r502
return tau
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 def __calculateLag1Phase(self, data, lagTRange):
data1 = stats.nanmean(data, axis = 0)
Julio Valdez
Processing Modules added:...
r502 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
phase = numpy.angle(data1[lag1,:])
return phase
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 class SpectralFitting(Operation):
'''
Function GetMoments()
Julio Valdez
Processing Modules added:...
r502
Input:
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 Output:
Variables modified:
'''
def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
Julio Valdez
Specular Meteor module modifications
r840
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 if path != None:
sys.path.append(path)
self.dataOut.library = importlib.import_module(file)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #To be inserted as a parameter
groupArray = numpy.array(groupList)
# groupArray = numpy.array([[0,1],[2,3]])
self.dataOut.groupList = groupArray
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 nGroups = groupArray.shape[0]
nChannels = self.dataIn.nChannels
nHeights=self.dataIn.heightList.size
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Parameters Array
self.dataOut.data_param = None
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Set constants
constants = self.dataOut.library.setConstants(self.dataIn)
self.dataOut.constants = constants
M = self.dataIn.normFactor
N = self.dataIn.nFFTPoints
ippSeconds = self.dataIn.ippSeconds
K = self.dataIn.nIncohInt
pairsArray = numpy.array(self.dataIn.pairsList)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #List of possible combinations
listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 if getSNR:
listChannels = groupArray.reshape((groupArray.size))
listChannels.sort()
noise = self.dataIn.getNoise()
self.dataOut.data_SNR = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 for i in range(nGroups):
coord = groupArray[i,:]
Julio Valdez
Changes to meteor detection and phase correction because of relocation of antenna
r819
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Input data array
data = self.dataIn.data_spc[coord,:,:]/(M*N)
data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
Julio Valdez
data...
r608
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Cross Spectra data array for Covariance Matrixes
ind = 0
for pairs in listComb:
pairsSel = numpy.array([coord[x],coord[y]])
indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
ind += 1
dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
dataCross = dataCross**2/K
Julio Valdez
data...
r608
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 for h in range(nHeights):
# print self.dataOut.heightList[h]
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Input
d = data[:,h]
#Covariance Matrix
D = numpy.diag(d**2/K)
ind = 0
for pairs in listComb:
#Coordinates in Covariance Matrix
x = pairs[0]
y = pairs[1]
#Channel Index
S12 = dataCross[ind,:,h]
D12 = numpy.diag(S12)
#Completing Covariance Matrix with Cross Spectras
D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
ind += 1
Dinv=numpy.linalg.inv(D)
L=numpy.linalg.cholesky(Dinv)
LT=L.T
dp = numpy.dot(LT,d)
#Initial values
data_spc = self.dataIn.data_spc[coord,:,h]
if (h>0)and(error1[3]<5):
p0 = self.dataOut.data_param[i,:,h-1]
else:
p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
try:
#Least Squares
minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
# minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
#Chi square error
error0 = numpy.sum(infodict['fvec']**2)/(2*N)
#Error with Jacobian
error1 = self.dataOut.library.errorFunction(minp,constants,LT)
except:
minp = p0*numpy.nan
error0 = numpy.nan
error1 = p0*numpy.nan
#Save
if self.dataOut.data_param == None:
self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
self.dataOut.data_param[i,:,h] = minp
Julio Valdez
Processing Modules added:...
r502 return
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 def __residFunction(self, p, dp, LT, constants):
Julio Valdez
Specular Meteor module modifications
r840
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 fm = self.dataOut.library.modelFunction(p, constants)
fmp=numpy.dot(LT,fm)
return dp-fmp
def __getSNR(self, z, noise):
Julio Valdez
Bug fixes in meteor module
r811
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 avg = numpy.average(z, axis=1)
SNR = (avg.T-noise)/noise
SNR = SNR.T
return SNR
Julio Valdez
-Functional HDF5 Format Writing and Reading Unit...
r804
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 def __chisq(p,chindex,hindex):
#similar to Resid but calculates CHI**2
[LT,d,fm]=setupLTdfm(p,chindex,hindex)
dp=numpy.dot(LT,d)
fmp=numpy.dot(LT,fm)
chisq=numpy.dot((dp-fmp).T,(dp-fmp))
return chisq
class WindProfiler(Operation):
__isConfig = False
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 __initime = None
__lastdatatime = None
__integrationtime = None
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 __buffer = None
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 __dataReady = False
__firstdata = None
n = None
def __init__(self):
Operation.__init__(self)
def __calculateCosDir(self, elev, azim):
zen = (90 - elev)*numpy.pi/180
azim = azim*numpy.pi/180
cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 signX = numpy.sign(numpy.cos(azim))
signY = numpy.sign(numpy.sin(azim))
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 cosDirX = numpy.copysign(cosDirX, signX)
cosDirY = numpy.copysign(cosDirY, signY)
return cosDirX, cosDirY
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 def __calculateAngles(self, theta_x, theta_y, azimuth):
dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
zenith_arr = numpy.arccos(dir_cosw)
azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
Julio Valdez
Processing Modules added:...
r502
#
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 if horOnly:
A = numpy.c_[dir_cosu,dir_cosv]
else:
A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
A = numpy.asmatrix(A)
A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
return A1
def __correctValues(self, heiRang, phi, velRadial, SNR):
listPhi = phi.tolist()
maxid = listPhi.index(max(listPhi))
minid = listPhi.index(min(listPhi))
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 rango = range(len(phi))
# rango = numpy.delete(rango,maxid)
heiRang1 = heiRang*math.cos(phi[maxid])
heiRangAux = heiRang*math.cos(phi[minid])
indOut = (heiRang1 < heiRangAux[0]).nonzero()
heiRang1 = numpy.delete(heiRang1,indOut)
velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
SNR1 = numpy.zeros([len(phi),len(heiRang1)])
for i in rango:
x = heiRang*math.cos(phi[i])
y1 = velRadial[i,:]
f1 = interpolate.interp1d(x,y1,kind = 'cubic')
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 x1 = heiRang1
y11 = f1(x1)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 y2 = SNR[i,:]
f2 = interpolate.interp1d(x,y2,kind = 'cubic')
y21 = f2(x1)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 velRadial1[i,:] = y11
SNR1[i,:] = y21
return heiRang1, velRadial1, SNR1
def __calculateVelUVW(self, A, velRadial):
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Operacion Matricial
# velUVW = numpy.zeros((velRadial.shape[1],3))
# for ind in range(velRadial.shape[1]):
# velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
# velUVW = velUVW.transpose()
velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
velUVW[:,:] = numpy.dot(A,velRadial)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842
return velUVW
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
Julio Valdez
Changes in Correlations Processing unit
r854
def techniqueDBS(self, kwargs):
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 """
Function that implements Doppler Beam Swinging (DBS) technique.
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
Direction correction (if necessary), Ranges and SNR
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 Output: Winds estimation (Zonal, Meridional and Vertical)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 Parameters affected: Winds, height range, SNR
"""
Julio Valdez
Changes in Correlations Processing unit
r854 velRadial0 = kwargs['velRadial']
heiRang = kwargs['heightList']
SNR0 = kwargs['SNR']
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 if kwargs.has_key('dirCosx') and kwargs.has_key('dirCosy'):
theta_x = numpy.array(kwargs['dirCosx'])
theta_y = numpy.array(kwargs['dirCosy'])
else:
elev = numpy.array(kwargs['elevation'])
azim = numpy.array(kwargs['azimuth'])
theta_x, theta_y = self.__calculateCosDir(elev, azim)
azimuth = kwargs['correctAzimuth']
if kwargs.has_key('horizontalOnly'):
horizontalOnly = kwargs['horizontalOnly']
else: horizontalOnly = False
if kwargs.has_key('correctFactor'):
correctFactor = kwargs['correctFactor']
else: correctFactor = 1
if kwargs.has_key('channelList'):
channelList = kwargs['channelList']
if len(channelList) == 2:
horizontalOnly = True
arrayChannel = numpy.array(channelList)
param = param[arrayChannel,:,:]
theta_x = theta_x[arrayChannel]
theta_y = theta_y[arrayChannel]
azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
#Calculo de Componentes de la velocidad con DBS
winds = self.__calculateVelUVW(A,velRadial1)
return winds, heiRang1, SNR1
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Changes in Correlations Processing unit
r854 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Changes in Correlations Processing unit
r854 nPairs = len(pairs_ccf)
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 posx = numpy.asarray(posx)
posy = numpy.asarray(posy)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Rotacion Inversa para alinear con el azimuth
if azimuth!= None:
azimuth = azimuth*math.pi/180
posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
else:
posx1 = posx
posy1 = posy
#Calculo de Distancias
Julio Valdez
Changes in Correlations Processing unit
r854 distx = numpy.zeros(nPairs)
disty = numpy.zeros(nPairs)
dist = numpy.zeros(nPairs)
ang = numpy.zeros(nPairs)
for i in range(nPairs):
distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
ang[i] = numpy.arctan2(disty[i],distx[i])
Julio Valdez
Changes in Correlations Processing unit
r854 return distx, disty, dist, ang
#Calculo de Matrices
# nPairs = len(pairs)
# ang1 = numpy.zeros((nPairs, 2, 1))
# dist1 = numpy.zeros((nPairs, 2, 1))
#
# for j in range(nPairs):
# dist1[j,0,0] = dist[pairs[j][0]]
# dist1[j,1,0] = dist[pairs[j][1]]
# ang1[j,0,0] = ang[pairs[j][0]]
# ang1[j,1,0] = ang[pairs[j][1]]
#
# return distx,disty, dist1,ang1
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842
def __calculateVelVer(self, phase, lagTRange, _lambda):
Ts = lagTRange[1] - lagTRange[0]
velW = -_lambda*phase/(4*math.pi*Ts)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 return velW
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
nPairs = tau1.shape[0]
Julio Valdez
Changes in Correlations Processing unit
r854 nHeights = tau1.shape[1]
vel = numpy.zeros((nPairs,3,nHeights))
dist1 = numpy.reshape(dist, (dist.size,1))
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 angCos = numpy.cos(ang)
angSin = numpy.sin(ang)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Changes in Correlations Processing unit
r854 vel0 = dist1*tau1/(2*tau2**2)
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
vel[:,1,:] = (vel0*angSin).sum(axis = 1)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 ind = numpy.where(numpy.isinf(vel))
vel[ind] = numpy.nan
return vel
Julio Valdez
Changes in Correlations Processing unit
r854 # def __getPairsAutoCorr(self, pairsList, nChannels):
#
# pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
#
# for l in range(len(pairsList)):
# firstChannel = pairsList[l][0]
# secondChannel = pairsList[l][1]
#
# #Obteniendo pares de Autocorrelacion
# if firstChannel == secondChannel:
# pairsAutoCorr[firstChannel] = int(l)
#
# pairsAutoCorr = pairsAutoCorr.astype(int)
#
# pairsCrossCorr = range(len(pairsList))
# pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
#
# return pairsAutoCorr, pairsCrossCorr
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842
Julio Valdez
Changes in Correlations Processing unit
r854 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
def techniqueSA(self, kwargs):
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 """
Function that implements Spaced Antenna (SA) technique.
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
Direction correction (if necessary), Ranges and SNR
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 Output: Winds estimation (Zonal, Meridional and Vertical)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 Parameters affected: Winds
"""
Julio Valdez
Changes in Correlations Processing unit
r854 position_x = kwargs['positionX']
position_y = kwargs['positionY']
azimuth = kwargs['azimuth']
if kwargs.has_key('correctFactor'):
correctFactor = kwargs['correctFactor']
else:
correctFactor = 1
groupList = kwargs['groupList']
pairs_ccf = groupList[1]
tau = kwargs['tau']
_lambda = kwargs['_lambda']
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Changes in Correlations Processing unit
r854 #Cross Correlation pairs obtained
# pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
# pairsArray = numpy.array(pairsList)[pairsCrossCorr]
# pairsSelArray = numpy.array(pairsSelected)
# pairs = []
#
# #Wind estimation pairs obtained
# for i in range(pairsSelArray.shape[0]/2):
# ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
# ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
# pairs.append((ind1,ind2))
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842
indtau = tau.shape[0]/2
tau1 = tau[:indtau,:]
tau2 = tau[indtau:-1,:]
Julio Valdez
Changes in Correlations Processing unit
r854 # tau1 = tau1[pairs,:]
# tau2 = tau2[pairs,:]
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 phase1 = tau[-1,:]
#---------------------------------------------------------------------
#Metodo Directo
Julio Valdez
Changes in Correlations Processing unit
r854 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
winds = stats.nanmean(winds, axis=0)
#---------------------------------------------------------------------
#Metodo General
# distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
# #Calculo Coeficientes de Funcion de Correlacion
# F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
# #Calculo de Velocidades
# winds = self.calculateVelUV(F,G,A,B,H)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #---------------------------------------------------------------------
winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
winds = correctFactor*winds
return winds
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 def __checkTime(self, currentTime, paramInterval, outputInterval):
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 dataTime = currentTime + paramInterval
deltaTime = dataTime - self.__initime
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 if deltaTime >= outputInterval or deltaTime < 0:
self.__dataReady = True
return
def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
'''
Function that implements winds estimation technique with detected meteors.
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 Input: Detected meteors, Minimum meteor quantity to wind estimation
Output: Winds estimation (Zonal and Meridional)
Parameters affected: Winds
'''
# print arrayMeteor.shape
#Settings
nInt = (heightMax - heightMin)/2
# print nInt
nInt = int(nInt)
# print nInt
winds = numpy.zeros((2,nInt))*numpy.nan
#Filter errors
error = numpy.where(arrayMeteor[:,-1] == 0)[0]
finalMeteor = arrayMeteor[error,:]
#Meteor Histogram
finalHeights = finalMeteor[:,2]
hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
nMeteorsPerI = hist[0]
heightPerI = hist[1]
#Sort of meteors
indSort = finalHeights.argsort()
finalMeteor2 = finalMeteor[indSort,:]
# Calculating winds
ind1 = 0
ind2 = 0
for i in range(nInt):
nMet = nMeteorsPerI[i]
ind1 = ind2
ind2 = ind1 + nMet
meteorAux = finalMeteor2[ind1:ind2,:]
if meteorAux.shape[0] >= meteorThresh:
vel = meteorAux[:, 6]
zen = meteorAux[:, 4]*numpy.pi/180
azim = meteorAux[:, 3]*numpy.pi/180
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 n = numpy.cos(zen)
# m = (1 - n**2)/(1 - numpy.tan(azim)**2)
# l = m*numpy.tan(azim)
l = numpy.sin(zen)*numpy.sin(azim)
m = numpy.sin(zen)*numpy.cos(azim)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 A = numpy.vstack((l, m)).transpose()
A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
windsAux = numpy.dot(A1, vel)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 winds[0,i] = windsAux[0]
winds[1,i] = windsAux[1]
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 return winds, heightPerI[:-1]
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 def techniqueNSM_SA(self, **kwargs):
metArray = kwargs['metArray']
heightList = kwargs['heightList']
timeList = kwargs['timeList']
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 rx_location = kwargs['rx_location']
groupList = kwargs['groupList']
azimuth = kwargs['azimuth']
dfactor = kwargs['dfactor']
k = kwargs['k']
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
d = dist*dfactor
#Phase calculation
metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
Julio Valdez
data...
r608
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 velEst = numpy.zeros((heightList.size,2))*numpy.nan
azimuth1 = azimuth1*numpy.pi/180
for i in range(heightList.size):
h = heightList[i]
indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
metHeight = metArray1[indH,:]
if metHeight.shape[0] >= 2:
velAux = numpy.asmatrix(metHeight[:,-2]).T #Radial Velocities
iazim = metHeight[:,1].astype(int)
azimAux = numpy.asmatrix(azimuth1[iazim]).T #Azimuths
A = numpy.hstack((numpy.cos(azimAux),numpy.sin(azimAux)))
A = numpy.asmatrix(A)
A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
velHor = numpy.dot(A1,velAux)
velEst[i,:] = numpy.squeeze(velHor)
return velEst
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 def __getPhaseSlope(self, metArray, heightList, timeList):
meteorList = []
#utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
#Putting back together the meteor matrix
utctime = metArray[:,0]
uniqueTime = numpy.unique(utctime)
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 phaseDerThresh = 0.5
ippSeconds = timeList[1] - timeList[0]
sec = numpy.where(timeList>1)[0][0]
nPairs = metArray.shape[1] - 6
nHeights = len(heightList)
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 for t in uniqueTime:
metArray1 = metArray[utctime==t,:]
# phaseDerThresh = numpy.pi/4 #reducir Phase thresh
tmet = metArray1[:,1].astype(int)
hmet = metArray1[:,2].astype(int)
metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
metPhase[:,:] = numpy.nan
metPhase[:,hmet,tmet] = metArray1[:,6:].T
#Delete short trails
metBool = ~numpy.isnan(metPhase[0,:,:])
heightVect = numpy.sum(metBool, axis = 1)
metBool[heightVect<sec,:] = False
metPhase[:,heightVect<sec,:] = numpy.nan
#Derivative
metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
metPhase[phDerAux] = numpy.nan
#--------------------------METEOR DETECTION -----------------------------------------
indMet = numpy.where(numpy.any(metBool,axis=1))[0]
for p in numpy.arange(nPairs):
phase = metPhase[p,:,:]
phDer = metDer[p,:,:]
for h in indMet:
height = heightList[h]
phase1 = phase[h,:] #82
phDer1 = phDer[h,:]
phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
indValid = numpy.where(~numpy.isnan(phase1))[0]
initMet = indValid[0]
endMet = 0
for i in range(len(indValid)-1):
#Time difference
inow = indValid[i]
inext = indValid[i+1]
idiff = inext - inow
#Phase difference
phDiff = numpy.abs(phase1[inext] - phase1[inow])
if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
sizeTrail = inow - initMet + 1
if sizeTrail>3*sec: #Too short meteors
x = numpy.arange(initMet,inow+1)*ippSeconds
y = phase1[initMet:inow+1]
ynnan = ~numpy.isnan(y)
x = x[ynnan]
y = y[ynnan]
slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
ylin = x*slope + intercept
rsq = r_value**2
if rsq > 0.5:
vel = slope#*height*1000/(k*d)
estAux = numpy.array([utctime,p,height, vel, rsq])
meteorList.append(estAux)
initMet = inext
metArray2 = numpy.array(meteorList)
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 return metArray2
def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 azimuth1 = numpy.zeros(len(pairslist))
dist = numpy.zeros(len(pairslist))
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 for i in range(len(rx_location)):
ch0 = pairslist[i][0]
ch1 = pairslist[i][1]
diffX = rx_location[ch0][0] - rx_location[ch1][0]
diffY = rx_location[ch0][1] - rx_location[ch1][1]
azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
dist[i] = numpy.sqrt(diffX**2 + diffY**2)
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 azimuth1 -= azimuth0
return azimuth1, dist
def techniqueNSM_DBS(self, **kwargs):
metArray = kwargs['metArray']
heightList = kwargs['heightList']
timeList = kwargs['timeList']
zenithList = kwargs['zenithList']
nChan = numpy.max(cmet) + 1
nHeights = len(heightList)
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 utctime = metArray[:,0]
cmet = metArray[:,1]
hmet = metArray1[:,3].astype(int)
h1met = heightList[hmet]*zenithList[cmet]
vmet = metArray1[:,5]
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 for i in range(nHeights - 1):
hmin = heightList[i]
hmax = heightList[i + 1]
vthisH = vmet[(h1met>=hmin) & (h1met<hmax)]
return data_output
def run(self, dataOut, technique, **kwargs):
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 param = dataOut.data_param
if dataOut.abscissaList != None:
absc = dataOut.abscissaList[:-1]
noise = dataOut.noise
heightList = dataOut.heightList
SNR = dataOut.data_SNR
if technique == 'DBS':
Julio Valdez
Changes in Correlations Processing unit
r854
kwargs['velRadial'] = param[:,1,:] #Radial velocity
kwargs['heightList'] = heightList
kwargs['SNR'] = SNR
dataOut.data_output, dataOut.heightList, dataOut.data_SNR = self.techniqueDBS(kwargs) #DBS Function
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 dataOut.utctimeInit = dataOut.utctime
dataOut.outputInterval = dataOut.paramInterval
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 elif technique == 'SA':
#Parameters
Julio Valdez
Changes in Correlations Processing unit
r854 # position_x = kwargs['positionX']
# position_y = kwargs['positionY']
# azimuth = kwargs['azimuth']
#
# if kwargs.has_key('crosspairsList'):
# pairs = kwargs['crosspairsList']
# else:
# pairs = None
#
# if kwargs.has_key('correctFactor'):
# correctFactor = kwargs['correctFactor']
# else:
# correctFactor = 1
# tau = dataOut.data_param
# _lambda = dataOut.C/dataOut.frequency
# pairsList = dataOut.groupList
# nChannels = dataOut.nChannels
kwargs['groupList'] = dataOut.groupList
kwargs['tau'] = dataOut.data_param
kwargs['_lambda'] = dataOut.C/dataOut.frequency
# dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
dataOut.data_output = self.techniqueSA(kwargs)
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 dataOut.utctimeInit = dataOut.utctime
dataOut.outputInterval = dataOut.timeInterval
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 elif technique == 'Meteors':
dataOut.flagNoData = True
self.__dataReady = False
if kwargs.has_key('nHours'):
nHours = kwargs['nHours']
else:
nHours = 1
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 if kwargs.has_key('meteorsPerBin'):
meteorThresh = kwargs['meteorsPerBin']
else:
meteorThresh = 6
if kwargs.has_key('hmin'):
hmin = kwargs['hmin']
else: hmin = 70
if kwargs.has_key('hmax'):
hmax = kwargs['hmax']
else: hmax = 110
dataOut.outputInterval = nHours*3600
if self.__isConfig == False:
# self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
#Get Initial LTC time
self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 self.__isConfig = True
if self.__buffer == None:
self.__buffer = dataOut.data_param
self.__firstdata = copy.copy(dataOut)
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 else:
self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
if self.__dataReady:
dataOut.utctimeInit = self.__initime
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 self.__initime += dataOut.outputInterval #to erase time offset
Julio Valdez
-Functional HDF5 file writer unit...
r543
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
dataOut.flagNoData = False
self.__buffer = None
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 elif technique == 'Meteors1':
dataOut.flagNoData = True
self.__dataReady = False
if kwargs.has_key('nMins'):
nMins = kwargs['nMins']
else: nMins = 20
if kwargs.has_key('rx_location'):
rx_location = kwargs['rx_location']
else: rx_location = [(0,1),(1,1),(1,0)]
if kwargs.has_key('azimuth'):
azimuth = kwargs['azimuth']
else: azimuth = 51
if kwargs.has_key('dfactor'):
dfactor = kwargs['dfactor']
if kwargs.has_key('mode'):
mode = kwargs['mode']
else: mode = 'SA'
#Borrar luego esto
if dataOut.groupList == None:
dataOut.groupList = [(0,1),(0,2),(1,2)]
groupList = dataOut.groupList
C = 3e8
freq = 50e6
lamb = C/freq
k = 2*numpy.pi/lamb
timeList = dataOut.abscissaList
heightList = dataOut.heightList
if self.__isConfig == False:
dataOut.outputInterval = nMins*60
# self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
#Get Initial LTC time
initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
minuteAux = initime.minute
minuteNew = int(numpy.floor(minuteAux/nMins)*nMins)
self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
self.__isConfig = True
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 if self.__buffer == None:
self.__buffer = dataOut.data_param
self.__firstdata = copy.copy(dataOut)
else:
self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
if self.__dataReady:
dataOut.utctimeInit = self.__initime
self.__initime += dataOut.outputInterval #to erase time offset
metArray = self.__buffer
if mode == 'SA':
dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
elif mode == 'DBS':
dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList)
dataOut.data_output = dataOut.data_output.T
dataOut.flagNoData = False
self.__buffer = None
return
class EWDriftsEstimation(Operation):
def __init__(self):
Operation.__init__(self)
def __correctValues(self, heiRang, phi, velRadial, SNR):
listPhi = phi.tolist()
maxid = listPhi.index(max(listPhi))
minid = listPhi.index(min(listPhi))
rango = range(len(phi))
# rango = numpy.delete(rango,maxid)
heiRang1 = heiRang*math.cos(phi[maxid])
heiRangAux = heiRang*math.cos(phi[minid])
indOut = (heiRang1 < heiRangAux[0]).nonzero()
heiRang1 = numpy.delete(heiRang1,indOut)
velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
SNR1 = numpy.zeros([len(phi),len(heiRang1)])
for i in rango:
x = heiRang*math.cos(phi[i])
y1 = velRadial[i,:]
f1 = interpolate.interp1d(x,y1,kind = 'cubic')
x1 = heiRang1
y11 = f1(x1)
y2 = SNR[i,:]
f2 = interpolate.interp1d(x,y2,kind = 'cubic')
y21 = f2(x1)
velRadial1[i,:] = y11
SNR1[i,:] = y21
return heiRang1, velRadial1, SNR1
def run(self, dataOut, zenith, zenithCorrection):
heiRang = dataOut.heightList
velRadial = dataOut.data_param[:,3,:]
SNR = dataOut.data_SNR
zenith = numpy.array(zenith)
zenith -= zenithCorrection
zenith *= numpy.pi/180
heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
alp = zenith[0]
bet = zenith[1]
w_w = velRadial1[0,:]
w_e = velRadial1[1,:]
w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
winds = numpy.vstack((u,w))
dataOut.heightList = heiRang1
dataOut.data_output = winds
dataOut.data_SNR = SNR1
dataOut.utctimeInit = dataOut.utctime
dataOut.outputInterval = dataOut.timeInterval
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513 return
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #--------------- Non Specular Meteor ----------------
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 class NonSpecularMeteorDetection(Operation):
def run(self, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False):
Julio Valdez
Non Specular Meteors module
r839 data_acf = self.dataOut.data_pre[0]
data_ccf = self.dataOut.data_pre[1]
lamb = self.dataOut.C/self.dataOut.frequency
tSamp = self.dataOut.ippSeconds*self.dataOut.nCohInt
paramInterval = self.dataOut.paramInterval
nChannels = data_acf.shape[0]
nLags = data_acf.shape[1]
nProfiles = data_acf.shape[2]
nHeights = self.dataOut.nHeights
nCohInt = self.dataOut.nCohInt
sec = numpy.round(nProfiles/self.dataOut.paramInterval)
heightList = self.dataOut.heightList
ippSeconds = self.dataOut.ippSeconds*self.dataOut.nCohInt*self.dataOut.nAvg
utctime = self.dataOut.utctime
self.dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
#------------------------ SNR --------------------------------------
power = data_acf[:,0,:,:].real
noise = numpy.zeros(nChannels)
SNR = numpy.zeros(power.shape)
for i in range(nChannels):
noise[i] = hildebrand_sekhon(power[i,:], nCohInt)
SNR[i] = (power[i]-noise[i])/noise[i]
SNRm = numpy.nanmean(SNR, axis = 0)
SNRdB = 10*numpy.log10(SNR)
if mode == 'SA':
nPairs = data_ccf.shape[0]
#---------------------- Coherence and Phase --------------------------
phase = numpy.zeros(data_ccf[:,0,:,:].shape)
# phase1 = numpy.copy(phase)
coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
for p in range(nPairs):
ch0 = self.dataOut.groupList[p][0]
ch1 = self.dataOut.groupList[p][1]
ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
# phase1[p,:,:] = numpy.angle(ccf) #median filter
coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
# coh1[p,:,:] = numpy.abs(ccf) #median filter
coh = numpy.nanmax(coh1, axis = 0)
# struc = numpy.ones((5,1))
# coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
#---------------------- Radial Velocity ----------------------------
phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
if allData:
boolMetFin = ~numpy.isnan(SNRm)
# coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
else:
#------------------------ Meteor mask ---------------------------------
# #SNR mask
# boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
#
# #Erase small objects
# boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
#
# auxEEJ = numpy.sum(boolMet1,axis=0)
# indOver = auxEEJ>nProfiles*0.8 #Use this later
# indEEJ = numpy.where(indOver)[0]
# indNEEJ = numpy.where(~indOver)[0]
#
# boolMetFin = boolMet1
#
# if indEEJ.size > 0:
# boolMet1[:,indEEJ] = False #Erase heights with EEJ
#
# boolMet2 = coh > cohThresh
# boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
#
# #Final Meteor mask
# boolMetFin = boolMet1|boolMet2
#Coherence mask
boolMet1 = coh > 0.75
struc = numpy.ones((30,1))
boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
#Derivative mask
derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
boolMet2 = derPhase < 0.2
# boolMet2 = ndimage.morphology.binary_opening(boolMet2)
# boolMet2 = ndimage.morphology.binary_closing(boolMet2, structure = numpy.ones((10,1)))
boolMet2 = ndimage.median_filter(boolMet2,size=5)
boolMet2 = numpy.vstack((boolMet2,numpy.full((1,nHeights), True, dtype=bool)))
# #Final mask
# boolMetFin = boolMet2
boolMetFin = boolMet1&boolMet2
# boolMetFin = ndimage.morphology.binary_dilation(boolMetFin)
#Creating data_param
coordMet = numpy.where(boolMetFin)
tmet = coordMet[0]
hmet = coordMet[1]
data_param = numpy.zeros((tmet.size, 6 + nPairs))
data_param[:,0] = utctime
data_param[:,1] = tmet
data_param[:,2] = hmet
data_param[:,3] = SNRm[tmet,hmet]
data_param[:,4] = velRad[tmet,hmet]
data_param[:,5] = coh[tmet,hmet]
data_param[:,6:] = phase[:,tmet,hmet].T
elif mode == 'DBS':
self.dataOut.groupList = numpy.arange(nChannels)
#Radial Velocities
# phase = numpy.angle(data_acf[:,1,:,:])
phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
velRad = phase*lamb/(4*numpy.pi*tSamp)
#Spectral width
acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2))
# velRad = ndimage.median_filter(velRad, size = (1,5,1))
if allData:
boolMetFin = ~numpy.isnan(SNRdB)
else:
#SNR
boolMet1 = (SNRdB>SNRthresh) #SNR mask
boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
#Radial velocity
boolMet2 = numpy.abs(velRad) < 30
boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
#Spectral Width
boolMet3 = spcWidth < 30
boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
# boolMetFin = self.__erase_small(boolMet1, 10,5)
boolMetFin = boolMet1&boolMet2&boolMet3
#Creating data_param
coordMet = numpy.where(boolMetFin)
cmet = coordMet[0]
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 tmet = coordMet[1]
hmet = coordMet[2]
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 data_param = numpy.zeros((tmet.size, 7))
data_param[:,0] = utctime
data_param[:,1] = cmet
data_param[:,2] = tmet
data_param[:,3] = hmet
data_param[:,4] = SNR[cmet,tmet,hmet].T
data_param[:,5] = velRad[cmet,tmet,hmet].T
data_param[:,6] = spcWidth[cmet,tmet,hmet].T
# self.dataOut.data_param = data_int
if len(data_param) == 0:
self.dataOut.flagNoData = True
else:
self.dataOut.data_param = data_param
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 def __erase_small(self, binArray, threshX, threshY):
labarray, numfeat = ndimage.measurements.label(binArray)
binArray1 = numpy.copy(binArray)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 for i in range(1,numfeat + 1):
auxBin = (labarray==i)
auxSize = auxBin.sum()
x,y = numpy.where(auxBin)
widthX = x.max() - x.min()
widthY = y.max() - y.min()
#width X: 3 seg -> 12.5*3
#width Y:
if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
binArray1[auxBin] = False
return binArray1
#--------------- Specular Meteor ----------------
Julio Valdez
Changes in Correlations Processing unit
r854 class SMDetection(Operation):
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 '''
Function DetectMeteors()
Project developed with paper:
HOLDSWORTH ET AL. 2004
Input:
self.dataOut.data_pre
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 centerReceiverIndex: From the channels, which is the center receiver
hei_ref: Height reference for the Beacon signal extraction
tauindex:
predefinedPhaseShifts: Predefined phase offset for the voltge signals
cohDetection: Whether to user Coherent detection or not
cohDet_timeStep: Coherent Detection calculation time step
cohDet_thresh: Coherent Detection phase threshold to correct phases
noise_timeStep: Noise calculation time step
noise_multiple: Noise multiple to define signal threshold
multDet_timeLimit: Multiple Detection Removal time limit in seconds
multDet_rangeLimit: Multiple Detection Removal range limit in km
phaseThresh: Maximum phase difference between receiver to be consider a meteor
SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
hmin: Minimum Height of the meteor to use it in the further wind estimations
hmax: Maximum Height of the meteor to use it in the further wind estimations
azimuth: Azimuth angle correction
Affected:
self.dataOut.data_param
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 Rejection Criteria (Errors):
0: No error; analysis OK
1: SNR < SNR threshold
2: angle of arrival (AOA) ambiguously determined
3: AOA estimate not feasible
4: Large difference in AOAs obtained from different antenna baselines
5: echo at start or end of time series
6: echo less than 5 examples long; too short for analysis
7: echo rise exceeds 0.3s
8: echo decay time less than twice rise time
9: large power level before echo
10: large power level after echo
11: poor fit to amplitude for estimation of decay time
12: poor fit to CCF phase variation for estimation of radial drift velocity
13: height unresolvable echo: not valid height within 70 to 110 km
14: height ambiguous echo: more then one possible height within 70 to 110 km
15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
16: oscilatory echo, indicating event most likely not an underdense echo
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 17: phase difference in meteor Reestimation
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 Data Storage:
Meteors for Wind Estimation (8):
Utc Time | Range Height
Azimuth Zenith errorCosDir
VelRad errorVelRad
Phase0 Phase1 Phase2 Phase3
TypeError
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 '''
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 def run(self, dataOut, hei_ref = None, tauindex = 0,
phaseOffsets = None,
cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
noise_timeStep = 4, noise_multiple = 4,
multDet_timeLimit = 1, multDet_rangeLimit = 3,
phaseThresh = 20, SNRThresh = 5,
hmin = 50, hmax=150, azimuth = 0,
channelPositions = None) :
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842
#Getting Pairslist
if channelPositions == None:
# channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
Julio Valdez
Changes in Correlations Processing unit
r854 meteorOps = SMOperations()
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
heiRang = dataOut.getHeiRange()
Julio Valdez
Changes in Correlations Processing unit
r854 #Get Beacon signal - No Beacon signal anymore
# newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
#
# if hei_ref != None:
# newheis = numpy.where(self.dataOut.heightList>hei_ref)
#
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842
#****************REMOVING HARDWARE PHASE DIFFERENCES***************
# see if the user put in pre defined phase shifts
Julio Valdez
Changes in Correlations Processing unit
r854 voltsPShift = dataOut.data_pre.copy()
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 # if predefinedPhaseShifts != None:
# hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
#
# # elif beaconPhaseShifts:
# # #get hardware phase shifts using beacon signal
# # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
# # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
#
# else:
# hardwarePhaseShifts = numpy.zeros(5)
#
# voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
# for i in range(self.dataOut.data_pre.shape[0]):
# voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Remove DC
voltsDC = numpy.mean(voltsPShift,1)
voltsDC = numpy.mean(voltsDC,1)
for i in range(voltsDC.shape[0]):
voltsPShift[i] = voltsPShift[i] - voltsDC[i]
#Don't considerate last heights, theyre used to calculate Hardware Phase Shift
Julio Valdez
Changes in Correlations Processing unit
r854 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
#Coherent Detection
if cohDetection:
#use coherent detection to get the net power
cohDet_thresh = cohDet_thresh*numpy.pi/180
Julio Valdez
Changes in Correlations Processing unit
r854 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Non-coherent detection!
powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
#********** END OF COH/NON-COH POWER CALCULATION**********************
#********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
#Get noise
Julio Valdez
Changes in Correlations Processing unit
r854 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
#Get signal threshold
signalThresh = noise_multiple*noise
#Meteor echoes detection
listMeteors = self.__findMeteors(powerNet, signalThresh)
#******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
#Parameters
Julio Valdez
Changes in Correlations Processing unit
r854 heiRange = dataOut.getHeiRange()
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 rangeInterval = heiRange[1] - heiRange[0]
rangeLimit = multDet_rangeLimit/rangeInterval
Julio Valdez
Changes in Correlations Processing unit
r854 timeLimit = multDet_timeLimit/dataOut.timeInterval
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Multiple detection removals
listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
#************ END OF REMOVE MULTIPLE DETECTIONS **********************
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
#Parameters
phaseThresh = phaseThresh*numpy.pi/180
thresh = [phaseThresh, noise_multiple, SNRThresh]
#Meteor reestimation (Errors N 1, 6, 12, 17)
Julio Valdez
Changes in Correlations Processing unit
r854 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist0, thresh, noise, dataOut.timeInterval, dataOut.frequency)
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
#Estimation of decay times (Errors N 7, 8, 11)
Julio Valdez
Changes in Correlations Processing unit
r854 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #******************* END OF METEOR REESTIMATION *******************
#********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
#Calculating Radial Velocity (Error N 15)
radialStdThresh = 10
Julio Valdez
Changes in Correlations Processing unit
r854 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842
if len(listMeteors4) > 0:
#Setting New Array
Julio Valdez
Changes in Correlations Processing unit
r854 date = dataOut.utctime
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Correcting phase offset
if phaseOffsets != None:
phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Second Pairslist
pairsList = []
pairx = (0,1)
pairy = (2,3)
pairsList.append(pairx)
pairsList.append(pairy)
jph = numpy.array([0,0,0,0])
h = (hmin,hmax)
arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
# #Calculate AOA (Error N 3, 4)
# #JONES ET AL. 1998
# error = arrayParameters[:,-1]
# AOAthresh = numpy.pi/8
# phases = -arrayParameters[:,9:13]
# arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
#
# #Calculate Heights (Error N 13 and 14)
# error = arrayParameters[:,-1]
# Ranges = arrayParameters[:,2]
# zenith = arrayParameters[:,5]
# arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
# error = arrayParameters[:,-1]
#********************* END OF PARAMETERS CALCULATION **************************
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #***************************+ PASS DATA TO NEXT STEP **********************
# arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
Julio Valdez
Changes in Correlations Processing unit
r854 dataOut.data_param = arrayParameters
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842
if arrayParameters == None:
Julio Valdez
Changes in Correlations Processing unit
r854 dataOut.flagNoData = True
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 else:
Julio Valdez
Changes in Correlations Processing unit
r854 dataOut.flagNoData = True
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842
return
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
minIndex = min(newheis[0])
maxIndex = max(newheis[0])
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 voltage = voltage0[:,:,minIndex:maxIndex+1]
nLength = voltage.shape[1]/n
nMin = 0
nMax = 0
phaseOffset = numpy.zeros((len(pairslist),n))
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 for i in range(n):
nMax += nLength
phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
phaseCCF = numpy.mean(phaseCCF, axis = 2)
phaseOffset[:,i] = phaseCCF.transpose()
nMin = nMax
# phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Remove Outliers
factor = 2
wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
dw = numpy.std(wt,axis = 1)
dw = dw.reshape((dw.size,1))
ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
phaseOffset[ind] = numpy.nan
phaseOffset = stats.nanmean(phaseOffset, axis=1)
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 return phaseOffset
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 def __shiftPhase(self, data, phaseShift):
#this will shift the phase of a complex number
dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
return dataShifted
def __estimatePhaseDifference(self, array, pairslist):
nChannel = array.shape[0]
nHeights = array.shape[2]
numPairs = len(pairslist)
# phaseCCF = numpy.zeros((nChannel, 5, nHeights))
phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Correct phases
derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 if indDer[0].shape[0] > 0:
for i in range(indDer[0].shape[0]):
signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 # for j in range(numSides):
# phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
# phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
#
#Linear
phaseInt = numpy.zeros((numPairs,1))
angAllCCF = phaseCCF[:,[0,1,3,4],0]
for j in range(numPairs):
fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
phaseInt[j] = fit[1]
#Phase Differences
phaseDiff = phaseInt - phaseCCF[:,2,:]
phaseArrival = phaseInt.reshape(phaseInt.size)
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Dealias
phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
# indAlias = numpy.where(phaseArrival > numpy.pi)
# phaseArrival[indAlias] -= 2*numpy.pi
# indAlias = numpy.where(phaseArrival < -numpy.pi)
# phaseArrival[indAlias] += 2*numpy.pi
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 return phaseDiff, phaseArrival
def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
#this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
#find the phase shifts of each channel over 1 second intervals
#only look at ranges below the beacon signal
numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
numBlocks = int(volts.shape[1]/numProfPerBlock)
numHeights = volts.shape[2]
nChannel = volts.shape[0]
voltsCohDet = volts.copy()
pairsarray = numpy.array(pairslist)
indSides = pairsarray[:,1]
# indSides = numpy.array(range(nChannel))
# indSides = numpy.delete(indSides, indCenter)
#
# listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
listBlocks = numpy.array_split(volts, numBlocks, 1)
startInd = 0
endInd = 0
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 for i in range(numBlocks):
startInd = endInd
endInd = endInd + listBlocks[i].shape[1]
arrayBlock = listBlocks[i]
# arrayBlockCenter = listCenter[i]
#Estimate the Phase Difference
phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
#Phase Difference RMS
arrayPhaseRMS = numpy.abs(phaseDiff)
phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
indPhase = numpy.where(phaseRMSaux==4)
#Shifting
if indPhase[0].shape[0] > 0:
for j in range(indSides.size):
arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
voltsCohDet[:,startInd:endInd,:] = arrayBlock
return voltsCohDet
def __calculateCCF(self, volts, pairslist ,laglist):
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 nHeights = volts.shape[2]
nPoints = volts.shape[1]
voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
for i in range(len(pairslist)):
volts1 = volts[pairslist[i][0]]
volts2 = volts[pairslist[i][1]]
for t in range(len(laglist)):
idxT = laglist[t]
if idxT >= 0:
vStacked = numpy.vstack((volts2[idxT:,:],
numpy.zeros((idxT, nHeights),dtype='complex')))
else:
vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
volts2[:(nPoints + idxT),:]))
voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 vStacked = None
return voltsCCF
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 def __getNoise(self, power, timeSegment, timeInterval):
numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
numBlocks = int(power.shape[0]/numProfPerBlock)
numHeights = power.shape[1]
listPower = numpy.array_split(power, numBlocks, 0)
noise = numpy.zeros((power.shape[0], power.shape[1]))
noise1 = numpy.zeros((power.shape[0], power.shape[1]))
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 startInd = 0
endInd = 0
for i in range(numBlocks): #split por canal
startInd = endInd
endInd = endInd + listPower[i].shape[0]
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 arrayBlock = listPower[i]
noiseAux = numpy.mean(arrayBlock, 0)
# noiseAux = numpy.median(noiseAux)
# noiseAux = numpy.mean(arrayBlock)
noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 noiseAux1 = numpy.mean(arrayBlock)
noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
return noise, noise1
def __findMeteors(self, power, thresh):
nProf = power.shape[0]
nHeights = power.shape[1]
listMeteors = []
for i in range(nHeights):
powerAux = power[:,i]
threshAux = thresh[:,i]
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 indUPthresh = numpy.where(powerAux > threshAux)[0]
indDNthresh = numpy.where(powerAux <= threshAux)[0]
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 j = 0
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 while (j < indUPthresh.size - 2):
if (indUPthresh[j + 2] == indUPthresh[j] + 2):
indDNAux = numpy.where(indDNthresh > indUPthresh[j])
indDNthresh = indDNthresh[indDNAux]
if (indDNthresh.size > 0):
indEnd = indDNthresh[0] - 1
indInit = indUPthresh[j]
meteor = powerAux[indInit:indEnd + 1]
indPeak = meteor.argmax() + indInit
FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
j = numpy.where(indUPthresh == indEnd)[0] + 1
else: j+=1
else: j+=1
return listMeteors
def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 arrayMeteors = numpy.asarray(listMeteors)
listMeteors1 = []
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 while arrayMeteors.shape[0] > 0:
FLAs = arrayMeteors[:,4]
maxFLA = FLAs.argmax()
listMeteors1.append(arrayMeteors[maxFLA,:])
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 MeteorInitTime = arrayMeteors[maxFLA,1]
MeteorEndTime = arrayMeteors[maxFLA,3]
MeteorHeight = arrayMeteors[maxFLA,0]
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Check neighborhood
maxHeightIndex = MeteorHeight + rangeLimit
minHeightIndex = MeteorHeight - rangeLimit
minTimeIndex = MeteorInitTime - timeLimit
maxTimeIndex = MeteorEndTime + timeLimit
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Check Heights
indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 return listMeteors1
def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
numHeights = volts.shape[2]
nChannel = volts.shape[0]
thresholdPhase = thresh[0]
thresholdNoise = thresh[1]
thresholdDB = float(thresh[2])
thresholdDB1 = 10**(thresholdDB/10)
pairsarray = numpy.array(pairslist)
indSides = pairsarray[:,1]
pairslist1 = list(pairslist)
pairslist1.append((0,1))
pairslist1.append((3,4))
listMeteors1 = []
listPowerSeries = []
listVoltageSeries = []
#volts has the war data
if frequency == 30e6:
timeLag = 45*10**-3
else:
timeLag = 15*10**-3
lag = numpy.ceil(timeLag/timeInterval)
for i in range(len(listMeteors)):
###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
meteorAux = numpy.zeros(16)
#Loading meteor Data (mHeight, mStart, mPeak, mEnd)
mHeight = listMeteors[i][0]
mStart = listMeteors[i][1]
mPeak = listMeteors[i][2]
mEnd = listMeteors[i][3]
#get the volt data between the start and end times of the meteor
meteorVolts = volts[:,mStart:mEnd+1,mHeight]
meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #3.6. Phase Difference estimation
phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #3.7. Phase difference removal & meteor start, peak and end times reestimated
#meteorVolts0.- all Channels, all Profiles
meteorVolts0 = volts[:,:,mHeight]
meteorThresh = noise[:,mHeight]*thresholdNoise
meteorNoise = noise[:,mHeight]
meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Times reestimation
mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
if mStart1.size > 0:
mStart1 = mStart1[-1] + 1
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 else:
mStart1 = mPeak
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
if mEndDecayTime1.size == 0:
mEndDecayTime1 = powerNet0.size
Julio Valdez
Processing Modules added:...
r502 else:
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
# mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #meteorVolts1.- all Channels, from start to end
meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
if meteorVolts2.shape[1] == 0:
meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
##################### END PARAMETERS REESTIMATION #########################
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
# if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
if meteorVolts2.shape[1] > 0:
#Phase Difference re-estimation
phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
# phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
Julio Valdez
-Functional HDF5 file writer unit...
r543
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Phase Difference RMS
phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
#Data from Meteor
mPeak1 = powerNet1.argmax() + mStart1
mPeakPower1 = powerNet1.max()
noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
#Vectorize
meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
meteorAux[7:11] = phaseDiffint[0:4]
Julio Valdez
Processing Modules added:...
r502
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Rejection Criterions
if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
meteorAux[-1] = 17
elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
meteorAux[-1] = 1
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 else:
meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
PowerSeries = 0
listMeteors1.append(meteorAux)
listPowerSeries.append(PowerSeries)
listVoltageSeries.append(meteorVolts1)
return listMeteors1, listPowerSeries, listVoltageSeries
def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
threshError = 10
#Depending if it is 30 or 50 MHz
if frequency == 30e6:
timeLag = 45*10**-3
else:
timeLag = 15*10**-3
lag = numpy.ceil(timeLag/timeInterval)
listMeteors1 = []
for i in range(len(listMeteors)):
meteorPower = listPower[i]
meteorAux = listMeteors[i]
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 if meteorAux[-1] == 0:
try:
indmax = meteorPower.argmax()
indlag = indmax + lag
y = meteorPower[indlag:]
x = numpy.arange(0, y.size)*timeLag
#first guess
a = y[0]
tau = timeLag
#exponential fit
popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
y1 = self.__exponential_function(x, *popt)
#error estimation
error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
decayTime = popt[1]
riseTime = indmax*timeInterval
meteorAux[11:13] = [decayTime, error]
#Table items 7, 8 and 11
if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
meteorAux[-1] = 7
elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
meteorAux[-1] = 8
if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
meteorAux[-1] = 11
except:
meteorAux[-1] = 11
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 listMeteors1.append(meteorAux)
return listMeteors1
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Exponential Function
def __exponential_function(self, x, a, tau):
y = a*numpy.exp(-x/tau)
return y
def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
pairslist1 = list(pairslist)
pairslist1.append((0,1))
pairslist1.append((3,4))
numPairs = len(pairslist1)
#Time Lag
timeLag = 45*10**-3
c = 3e8
lag = numpy.ceil(timeLag/timeInterval)
freq = 30e6
listMeteors1 = []
for i in range(len(listMeteors)):
meteorAux = listMeteors[i]
if meteorAux[-1] == 0:
mStart = listMeteors[i][1]
mPeak = listMeteors[i][2]
mLag = mPeak - mStart + lag
#get the volt data between the start and end times of the meteor
meteorVolts = listVolts[i]
meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
#Get CCF
allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
#Method 2
slopes = numpy.zeros(numPairs)
time = numpy.array([-2,-1,1,2])*timeInterval
angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
#Correct phases
derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 if indDer[0].shape[0] > 0:
for i in range(indDer[0].shape[0]):
signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
for j in range(numPairs):
fit = stats.linregress(time, angAllCCF[j,:])
slopes[j] = fit[0]
Julio Valdez
Non Specular Meteors module
r839
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Remove Outlier
# indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
# slopes = numpy.delete(slopes,indOut)
# indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
# slopes = numpy.delete(slopes,indOut)
radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
meteorAux[-2] = radialError
meteorAux[-3] = radialVelocity
#Setting Error
#Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
if numpy.abs(radialVelocity) > 200:
meteorAux[-1] = 15
#Number 12: Poor fit to CCF variation for estimation of radial drift velocity
elif radialError > radialStdThresh:
meteorAux[-1] = 12
listMeteors1.append(meteorAux)
return listMeteors1
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 def __setNewArrays(self, listMeteors, date, heiRang):
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #New arrays
arrayMeteors = numpy.array(listMeteors)
arrayParameters = numpy.zeros((len(listMeteors), 13))
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Date inclusion
# date = re.findall(r'\((.*?)\)', date)
# date = date[0].split(',')
# date = map(int, date)
#
# if len(date)<6:
# date.append(0)
#
# date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
# arrayDate = numpy.tile(date, (len(listMeteors), 1))
arrayDate = numpy.tile(date, (len(listMeteors)))
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Meteor array
# arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
# arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 #Parameters Array
arrayParameters[:,0] = arrayDate #Date
arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 return arrayParameters
Julio Valdez
Changes in Correlations Processing unit
r854 class CorrectSMPhases(Operation):
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842
def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
arrayParameters = dataOut.data_param
pairsList = []
pairx = (0,1)
pairy = (2,3)
pairsList.append(pairx)
pairsList.append(pairy)
jph = numpy.zeros(4)
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
# arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Changes in Correlations Processing unit
r854 meteorOps = SMOperations()
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 if channelPositions == None:
# channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
h = (hmin,hmax)
arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 dataOut.data_param = arrayParameters
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513 return
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842
Julio Valdez
Changes in Correlations Processing unit
r854 class SMPhaseCalibration(Operation):
Julio Valdez
data...
r608
__buffer = None
__initime = None
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
data...
r608 __dataReady = False
__isConfig = False
def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
dataTime = currentTime + paramInterval
deltaTime = dataTime - initTime
if deltaTime >= outputInterval or deltaTime < 0:
return True
return False
Julio Valdez
Specular Meteor module modifications
r840 def __getGammas(self, pairs, d, phases):
Julio Valdez
data...
r608 gammas = numpy.zeros(2)
Julio Valdez
Correction to Spaced Antenna libraries
r762
Julio Valdez
data...
r608 for i in range(len(pairs)):
pairi = pairs[i]
Julio Valdez
Specular Meteor module modifications
r840 phip3 = phases[:,pairi[1]]
d3 = d[pairi[1]]
phip2 = phases[:,pairi[0]]
d2 = d[pairi[0]]
Julio Valdez
data...
r608 #Calculating gamma
Julio Valdez
Specular Meteor module modifications
r840 # jdcos = alp1/(k*d1)
# jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0)))
jgamma = -phip2*d3/d2 - phip3
jgamma = numpy.angle(numpy.exp(1j*jgamma))
# jgamma[jgamma>numpy.pi] -= 2*numpy.pi
# jgamma[jgamma<-numpy.pi] += 2*numpy.pi
Julio Valdez
data...
r608 #Revised distribution
jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
#Histogram
nBins = 64.0
rmin = -0.5*numpy.pi
rmax = 0.5*numpy.pi
phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
meteorsY = phaseHisto[0]
phasesX = phaseHisto[1][:-1]
width = phasesX[1] - phasesX[0]
phasesX += width/2
Julio Valdez
Correction to Spaced Antenna libraries
r762
Julio Valdez
data...
r608 #Gaussian aproximation
bpeak = meteorsY.argmax()
peak = meteorsY.max()
jmin = bpeak - 5
jmax = bpeak + 5 + 1
if jmin<0:
jmin = 0
jmax = 6
elif jmax > meteorsY.size:
jmin = meteorsY.size - 6
jmax = meteorsY.size
x0 = numpy.array([peak,bpeak,50])
coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
#Gammas
gammas[i] = coeff[0][1]
Julio Valdez
Correction to Spaced Antenna libraries
r762
Julio Valdez
data...
r608 return gammas
def __residualFunction(self, coeffs, y, t):
return y - self.__gauss_function(t, coeffs)
def __gauss_function(self, t, coeffs):
return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
Julio Valdez
Specular Meteor module modifications
r840
Julio Valdez
data...
r608 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
Julio Valdez
Changes in Correlations Processing unit
r854 meteorOps = SMOperations()
Julio Valdez
data...
r608 nchan = 4
pairx = pairsList[0]
pairy = pairsList[1]
center_xangle = 0
center_yangle = 0
Julio Valdez
Correction to Spaced Antenna libraries
r762 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
Julio Valdez
data...
r608 ntimes = len(range_angle)
nstepsx = 20.0
nstepsy = 20.0
for iz in range(ntimes):
min_xangle = -range_angle[iz]/2 + center_xangle
max_xangle = range_angle[iz]/2 + center_xangle
min_yangle = -range_angle[iz]/2 + center_yangle
max_yangle = range_angle[iz]/2 + center_yangle
inc_x = (max_xangle-min_xangle)/nstepsx
inc_y = (max_yangle-min_yangle)/nstepsy
alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
penalty = numpy.zeros((nstepsx,nstepsy))
jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
jph = numpy.zeros(nchan)
# Iterations looking for the offset
for iy in range(int(nstepsy)):
for ix in range(int(nstepsx)):
jph[pairy[1]] = alpha_y[iy]
Julio Valdez
Specular Meteor module modifications
r840 jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
Julio Valdez
data...
r608
jph[pairx[1]] = alpha_x[ix]
Julio Valdez
Specular Meteor module modifications
r840 jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
Julio Valdez
data...
r608
jph_array[:,ix,iy] = jph
Julio Valdez
Specular Meteor module modifications
r840 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
Julio Valdez
data...
r608 error = meteorsArray1[:,-1]
ind1 = numpy.where(error==0)[0]
penalty[ix,iy] = ind1.size
i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
phOffset = jph_array[:,i,j]
center_xangle = phOffset[pairx[1]]
center_yangle = phOffset[pairy[1]]
phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
phOffset = phOffset*180/numpy.pi
return phOffset
Julio Valdez
Specular Meteor module modifications
r840 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
Julio Valdez
data...
r608
dataOut.flagNoData = True
Julio Valdez
Changes to meteor detection and phase correction because of relocation of antenna
r819 self.__dataReady = False
Julio Valdez
data...
r608 dataOut.outputInterval = nHours*3600
if self.__isConfig == False:
# self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
#Get Initial LTC time
self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
self.__isConfig = True
Julio Valdez
Correction to Spaced Antenna libraries
r762 if self.__buffer == None:
Julio Valdez
data...
r608 self.__buffer = dataOut.data_param.copy()
else:
Julio Valdez
Changes to meteor detection and phase correction because of relocation of antenna
r819 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
Julio Valdez
data...
r608
self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
if self.__dataReady:
dataOut.utctimeInit = self.__initime
self.__initime += dataOut.outputInterval #to erase time offset
freq = dataOut.frequency
c = dataOut.C #m/s
lamb = c/freq
k = 2*numpy.pi/lamb
azimuth = 0
h = (hmin, hmax)
Julio Valdez
Changes to meteor detection and phase correction because of relocation of antenna
r819 pairs = ((0,1),(2,3))
Julio Valdez
Specular Meteor module modifications
r840
if channelPositions == None:
# channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
Julio Valdez
Changes in Correlations Processing unit
r854 meteorOps = SMOperations()
Julio Valdez
Specular Meteor module modifications
r840 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
# distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
Julio Valdez
data...
r608
Julio Valdez
-Functional HDF5 Format Writing and Reading Unit...
r804 meteorsArray = self.__buffer
Julio Valdez
data...
r608 error = meteorsArray[:,-1]
boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
ind1 = numpy.where(boolError)[0]
meteorsArray = meteorsArray[ind1,:]
meteorsArray[:,-1] = 0
Julio Valdez
-Functional HDF5 Format Writing and Reading Unit...
r804 phases = meteorsArray[:,8:12]
Julio Valdez
data...
r608
#Calculate Gammas
Julio Valdez
Specular Meteor module modifications
r840 gammas = self.__getGammas(pairs, distances, phases)
Julio Valdez
data...
r608 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
#Calculate Phases
Julio Valdez
Changes to meteor detection and phase correction because of relocation of antenna
r819 phasesOff = self.__getPhases(azimuth, h, pairs, distances, gammas, meteorsArray)
Julio Valdez
data...
r608 phasesOff = phasesOff.reshape((1,phasesOff.size))
dataOut.data_output = -phasesOff
dataOut.flagNoData = False
self.__buffer = None
return
Julio Valdez
Changes in Correlations Processing unit
r854 class SMOperations():
Julio Valdez
data...
r608
def __init__(self):
return
Julio Valdez
Specular Meteor module modifications
r840 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
Julio Valdez
data...
r608
arrayParameters = arrayParameters0.copy()
hmin = h[0]
hmax = h[1]
#Calculate AOA (Error N 3, 4)
#JONES ET AL. 1998
AOAthresh = numpy.pi/8
error = arrayParameters[:,-1]
Julio Valdez
-Functional HDF5 Format Writing and Reading Unit...
r804 phases = -arrayParameters[:,8:12] + jph
Julio Valdez
Bug fixes in meteor module
r811 # phases = numpy.unwrap(phases)
Julio Valdez
Specular Meteor module modifications
r840 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
Julio Valdez
data...
r608
#Calculate Heights (Error N 13 and 14)
error = arrayParameters[:,-1]
Julio Valdez
-Functional HDF5 Format Writing and Reading Unit...
r804 Ranges = arrayParameters[:,1]
zenith = arrayParameters[:,4]
arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
Julio Valdez
data...
r608
#----------------------- Get Final data ------------------------------------
# error = arrayParameters[:,-1]
# ind1 = numpy.where(error==0)[0]
# arrayParameters = arrayParameters[ind1,:]
return arrayParameters
Julio Valdez
Specular Meteor module modifications
r840 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
Julio Valdez
data...
r608
arrayAOA = numpy.zeros((phases.shape[0],3))
Julio Valdez
Specular Meteor module modifications
r840 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
Julio Valdez
data...
r608
arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
arrayAOA[:,2] = cosDirError
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
data...
r608 azimuthAngle = arrayAOA[:,0]
zenithAngle = arrayAOA[:,1]
#Setting Error
Julio Valdez
Bug fixes in meteor module
r811 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
error[indError] = 0
Julio Valdez
data...
r608 #Number 3: AOA not fesible
indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
error[indInvalid] = 3
#Number 4: Large difference in AOAs obtained from different antenna baselines
indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
error[indInvalid] = 4
return arrayAOA, error
Julio Valdez
Specular Meteor module modifications
r840 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
Julio Valdez
First Spectral Fitting and EW Drifts operative module inside Signal Chain TRUNK
r513
Julio Valdez
data...
r608 #Initializing some variables
ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
ang_aux = ang_aux.reshape(1,ang_aux.size)
cosdir = numpy.zeros((arrayPhase.shape[0],2))
cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
for i in range(2):
Julio Valdez
Specular Meteor module modifications
r840 ph0 = arrayPhase[:,pairsList[i][0]]
ph1 = arrayPhase[:,pairsList[i][1]]
d0 = distances[pairsList[i][0]]
d1 = distances[pairsList[i][1]]
ph0_aux = ph0 + ph1
ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
# ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
# ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
Julio Valdez
data...
r608 #First Estimation
Julio Valdez
Specular Meteor module modifications
r840 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
Julio Valdez
data...
r608
#Most-Accurate Second Estimation
Julio Valdez
Specular Meteor module modifications
r840 phi1_aux = ph0 - ph1
Julio Valdez
data...
r608 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
#Direction Cosine 1
Julio Valdez
Specular Meteor module modifications
r840 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
Julio Valdez
data...
r608
#Searching the correct Direction Cosine
cosdir0_aux = cosdir0[:,i]
cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
#Minimum Distance
cosDiff = (cosdir1 - cosdir0_aux)**2
indcos = cosDiff.argmin(axis = 1)
#Saving Value obtained
cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
return cosdir0, cosdir
def __calculateAOA(self, cosdir, azimuth):
cosdirX = cosdir[:,0]
Julio Valdez
Modification due to new block reader option in Voltage reader
r835 cosdirY = cosdir[:,1]
Julio Valdez
data...
r608
zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
Julio Valdez
Specular Meteor module modifications
r840 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
Julio Valdez
data...
r608 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
return angles
def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
Ramb = 375 #Ramb = c/(2*PRF)
Re = 6371 #Earth Radius
heights = numpy.zeros(Ranges.shape)
R_aux = numpy.array([0,1,2])*Ramb
R_aux = R_aux.reshape(1,R_aux.size)
Ranges = Ranges.reshape(Ranges.size,1)
Ri = Ranges + R_aux
hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
#Check if there is a height between 70 and 110 km
h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
ind_h = numpy.where(h_bool == 1)[0]
hCorr = hi[ind_h, :]
ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
hCorr = hi[ind_hCorr]
heights[ind_h] = hCorr
#Setting Error
#Number 13: Height unresolvable echo: not valid height within 70 to 110 km
#Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
Julio Valdez
Bug fixes in meteor module
r811 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
error[indError] = 0
Julio Valdez
data...
r608 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
error[indInvalid2] = 14
indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
error[indInvalid1] = 13
Julio Valdez
Specular Meteor module modifications
r840 return heights, error
def getPhasePairs(self, channelPositions):
chanPos = numpy.array(channelPositions)
listOper = list(itertools.combinations(range(5),2))
distances = numpy.zeros(4)
axisX = []
axisY = []
distX = numpy.zeros(3)
distY = numpy.zeros(3)
ix = 0
iy = 0
pairX = numpy.zeros((2,2))
pairY = numpy.zeros((2,2))
for i in range(len(listOper)):
pairi = listOper[i]
posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
if posDif[0] == 0:
axisY.append(pairi)
distY[iy] = posDif[1]
iy += 1
elif posDif[1] == 0:
axisX.append(pairi)
distX[ix] = posDif[0]
ix += 1
for i in range(2):
if i==0:
dist0 = distX
axis0 = axisX
else:
dist0 = distY
axis0 = axisY
side = numpy.argsort(dist0)[:-1]
axis0 = numpy.array(axis0)[side,:]
chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
axis1 = numpy.unique(numpy.reshape(axis0,4))
side = axis1[axis1 != chanC]
diff1 = chanPos[chanC,i] - chanPos[side[0],i]
diff2 = chanPos[chanC,i] - chanPos[side[1],i]
if diff1<0:
chan2 = side[0]
d2 = numpy.abs(diff1)
chan1 = side[1]
d1 = numpy.abs(diff2)
else:
chan2 = side[1]
d2 = numpy.abs(diff2)
chan1 = side[0]
d1 = numpy.abs(diff1)
if i==0:
chanCX = chanC
chan1X = chan1
chan2X = chan2
distances[0:2] = numpy.array([d1,d2])
else:
chanCY = chanC
chan1Y = chan1
chan2Y = chan2
distances[2:4] = numpy.array([d1,d2])
# axisXsides = numpy.reshape(axisX[ix,:],4)
#
# channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
# channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
#
# ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
# ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
# channel25X = int(pairX[0,ind25X])
# channel20X = int(pairX[1,ind20X])
# ind25Y = numpy.where(pairY[0,:] != channelCentY)[0][0]
# ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
# channel25Y = int(pairY[0,ind25Y])
# channel20Y = int(pairY[1,ind20Y])
# pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
Julio Valdez
Parameters libraries reorganized, now each operation is a separated class
r842 return pairslist, distances
# def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
#
# arrayAOA = numpy.zeros((phases.shape[0],3))
# cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
#
# arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
# cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
# arrayAOA[:,2] = cosDirError
#
# azimuthAngle = arrayAOA[:,0]
# zenithAngle = arrayAOA[:,1]
#
# #Setting Error
# #Number 3: AOA not fesible
# indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
# error[indInvalid] = 3
# #Number 4: Large difference in AOAs obtained from different antenna baselines
# indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
# error[indInvalid] = 4
# return arrayAOA, error
#
# def __getDirectionCosines(self, arrayPhase, pairsList):
#
# #Initializing some variables
# ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
# ang_aux = ang_aux.reshape(1,ang_aux.size)
#
# cosdir = numpy.zeros((arrayPhase.shape[0],2))
# cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
#
#
# for i in range(2):
# #First Estimation
# phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
# #Dealias
# indcsi = numpy.where(phi0_aux > numpy.pi)
# phi0_aux[indcsi] -= 2*numpy.pi
# indcsi = numpy.where(phi0_aux < -numpy.pi)
# phi0_aux[indcsi] += 2*numpy.pi
# #Direction Cosine 0
# cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
#
# #Most-Accurate Second Estimation
# phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
# phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
# #Direction Cosine 1
# cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
#
# #Searching the correct Direction Cosine
# cosdir0_aux = cosdir0[:,i]
# cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
# #Minimum Distance
# cosDiff = (cosdir1 - cosdir0_aux)**2
# indcos = cosDiff.argmin(axis = 1)
# #Saving Value obtained
# cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
#
# return cosdir0, cosdir
#
# def __calculateAOA(self, cosdir, azimuth):
# cosdirX = cosdir[:,0]
# cosdirY = cosdir[:,1]
#
# zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
# azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
# angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
#
# return angles
#
# def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
#
# Ramb = 375 #Ramb = c/(2*PRF)
# Re = 6371 #Earth Radius
# heights = numpy.zeros(Ranges.shape)
#
# R_aux = numpy.array([0,1,2])*Ramb
# R_aux = R_aux.reshape(1,R_aux.size)
#
# Ranges = Ranges.reshape(Ranges.size,1)
#
# Ri = Ranges + R_aux
# hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
#
# #Check if there is a height between 70 and 110 km
# h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
# ind_h = numpy.where(h_bool == 1)[0]
#
# hCorr = hi[ind_h, :]
# ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
#
# hCorr = hi[ind_hCorr]
# heights[ind_h] = hCorr
#
# #Setting Error
# #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
# #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
#
# indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
# error[indInvalid2] = 14
# indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
# error[indInvalid1] = 13
#
# return heights, error