@@ -881,8 +881,7 class FullSpectralAnalysis(Operation): | |||||
881 |
|
881 | |||
882 | velocityX=[] |
|
882 | velocityX=[] | |
883 | velocityY=[] |
|
883 | velocityY=[] | |
884 | velocityV=[] |
|
884 | velocityV=[] | |
885 | PhaseLine=[] # unused afterwards |
|
|||
886 |
|
885 | |||
887 | dbSNR = 10*numpy.log10(dataOut.data_SNR) |
|
886 | dbSNR = 10*numpy.log10(dataOut.data_SNR) | |
888 | dbSNR = numpy.average(dbSNR,0) |
|
887 | dbSNR = numpy.average(dbSNR,0) | |
@@ -892,12 +891,8 class FullSpectralAnalysis(Operation): | |||||
892 | for Height in range(nHeights): |
|
891 | for Height in range(nHeights): | |
893 |
|
892 | |||
894 | if Height >= range_min and Height < range_max: |
|
893 | if Height >= range_min and Height < range_max: | |
895 | # [Vzon,Vmer,Vver, GaussCenter, PhaseSlope, FitGaussCSPC] = self.WindEstimation(spc, cspc, pairsList, ChanDist, Height, noise, dataOut.spc_range, dbSNR[Height], SNRlimit) |
|
894 | # error_code unused, yet maybe useful for future analysis. | |
896 |
|
895 | [Vzon,Vmer,Vver, error_code] = self.WindEstimation(spc[:,:,Height], cspc[:,:,Height], pairsList, ChanDist, Height, noise, dataOut.spc_range, dbSNR[Height], SNRlimit) | ||
897 | # error_code unused, yet maybe useful for future analysis. |
|
|||
898 | # Test |
|
|||
899 | [Vzon,Vmer,Vver, error_code] = self.TestWindEstimation(spc[:,:,Height], cspc[:,:,Height], pairsList, ChanDist, Height, noise, dataOut.spc_range, dbSNR[Height], SNRlimit) |
|
|||
900 |
|
||||
901 | else: |
|
896 | else: | |
902 | Vzon,Vmer,Vver = 0., 0., numpy.NaN |
|
897 | Vzon,Vmer,Vver = 0., 0., numpy.NaN | |
903 |
|
898 | |||
@@ -934,8 +929,6 class FullSpectralAnalysis(Operation): | |||||
934 | def gaus(self,xSamples,Amp,Mu,Sigma): |
|
929 | def gaus(self,xSamples,Amp,Mu,Sigma): | |
935 | return ( Amp / ((2*numpy.pi)**0.5 * Sigma) ) * numpy.exp( -( xSamples - Mu )**2 / ( 2 * (Sigma**2) )) |
|
930 | return ( Amp / ((2*numpy.pi)**0.5 * Sigma) ) * numpy.exp( -( xSamples - Mu )**2 / ( 2 * (Sigma**2) )) | |
936 |
|
931 | |||
937 |
|
||||
938 |
|
||||
939 | def Moments(self, ySamples, xSamples): |
|
932 | def Moments(self, ySamples, xSamples): | |
940 | '''*** |
|
933 | '''*** | |
941 | Variables corresponding to moments of distribution. |
|
934 | Variables corresponding to moments of distribution. | |
@@ -950,251 +943,6 class FullSpectralAnalysis(Operation): | |||||
950 | Desv = Sigma2**0.5 # Desv. Estandar, Ancho espectral |
|
943 | Desv = Sigma2**0.5 # Desv. Estandar, Ancho espectral | |
951 |
|
944 | |||
952 | return numpy.array([Pot, Vr, Desv]) |
|
945 | return numpy.array([Pot, Vr, Desv]) | |
953 |
|
||||
954 | def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, AbbsisaRange, dbSNR, SNRlimit): |
|
|||
955 |
|
||||
956 |
|
||||
957 |
|
||||
958 | ySamples=numpy.ones([spc.shape[0],spc.shape[1]]) |
|
|||
959 | phase=numpy.ones([spc.shape[0],spc.shape[1]]) |
|
|||
960 | CSPCSamples=numpy.ones([spc.shape[0],spc.shape[1]],dtype=numpy.complex_) |
|
|||
961 | coherence=numpy.ones([spc.shape[0],spc.shape[1]]) |
|
|||
962 | PhaseSlope=numpy.zeros(spc.shape[0]) |
|
|||
963 | PhaseInter=numpy.ones(spc.shape[0]) |
|
|||
964 | xFrec=AbbsisaRange[0][0:spc.shape[1]] |
|
|||
965 | xVel =AbbsisaRange[2][0:spc.shape[1]] |
|
|||
966 | Vv=numpy.empty(spc.shape[2])*0 |
|
|||
967 | SPCav = numpy.average(spc, axis=0)-numpy.average(noise) #spc[0]-noise[0]# |
|
|||
968 |
|
||||
969 | SPCmoments = self.Moments(SPCav[:,Height], xVel ) |
|
|||
970 | CSPCmoments = [] |
|
|||
971 | cspcNoise = numpy.empty(3) |
|
|||
972 |
|
||||
973 | '''Getting Eij and Nij''' |
|
|||
974 |
|
||||
975 | Xi01=ChanDist[0][0] |
|
|||
976 | Eta01=ChanDist[0][1] |
|
|||
977 |
|
||||
978 | Xi02=ChanDist[1][0] |
|
|||
979 | Eta02=ChanDist[1][1] |
|
|||
980 |
|
||||
981 | Xi12=ChanDist[2][0] |
|
|||
982 | Eta12=ChanDist[2][1] |
|
|||
983 |
|
||||
984 | z = spc.copy() |
|
|||
985 | z = numpy.where(numpy.isfinite(z), z, numpy.NAN) |
|
|||
986 |
|
||||
987 | for i in range(spc.shape[0]): |
|
|||
988 |
|
||||
989 | '''****** Line of Data SPC ******''' |
|
|||
990 | zline=z[i,:,Height].copy() - noise[i] # Se resta ruido |
|
|||
991 |
|
||||
992 | '''****** SPC is normalized ******''' |
|
|||
993 | SmoothSPC =self.moving_average(zline.copy(),N=1) # Se suaviza el ruido |
|
|||
994 | FactNorm = SmoothSPC/numpy.nansum(SmoothSPC) # SPC Normalizado y suavizado |
|
|||
995 |
|
||||
996 | xSamples = xFrec # Se toma el rango de frecuncias |
|
|||
997 | ySamples[i] = FactNorm # Se toman los valores de SPC normalizado |
|
|||
998 |
|
||||
999 | for i in range(spc.shape[0]): |
|
|||
1000 |
|
||||
1001 | '''****** Line of Data CSPC ******''' |
|
|||
1002 | cspcLine = ( cspc[i,:,Height].copy())# - noise[i] ) # no! Se resta el ruido |
|
|||
1003 | SmoothCSPC =self.moving_average(cspcLine,N=1) # Se suaviza el ruido |
|
|||
1004 | cspcNorm = SmoothCSPC/numpy.nansum(SmoothCSPC) # CSPC normalizado y suavizado |
|
|||
1005 |
|
||||
1006 | '''****** CSPC is normalized with respect to Briggs and Vincent ******''' |
|
|||
1007 | chan_index0 = pairsList[i][0] |
|
|||
1008 | chan_index1 = pairsList[i][1] |
|
|||
1009 |
|
||||
1010 | CSPCFactor= numpy.abs(numpy.nansum(ySamples[chan_index0]))**2 * numpy.abs(numpy.nansum(ySamples[chan_index1]))**2 |
|
|||
1011 | CSPCNorm = cspcNorm / numpy.sqrt(CSPCFactor) |
|
|||
1012 |
|
||||
1013 | CSPCSamples[i] = CSPCNorm |
|
|||
1014 |
|
||||
1015 | coherence[i] = numpy.abs(CSPCSamples[i]) / numpy.sqrt(CSPCFactor) |
|
|||
1016 |
|
||||
1017 | #coherence[i]= self.moving_average(coherence[i],N=1) |
|
|||
1018 |
|
||||
1019 | phase[i] = self.moving_average( numpy.arctan2(CSPCSamples[i].imag, CSPCSamples[i].real),N=1)#*180/numpy.pi |
|
|||
1020 |
|
||||
1021 | CSPCmoments = numpy.vstack([self.Moments(numpy.abs(CSPCSamples[0]), xSamples), |
|
|||
1022 | self.Moments(numpy.abs(CSPCSamples[1]), xSamples), |
|
|||
1023 | self.Moments(numpy.abs(CSPCSamples[2]), xSamples)]) |
|
|||
1024 |
|
||||
1025 |
|
||||
1026 | popt=[1e-10,0,1e-10] |
|
|||
1027 | popt01, popt02, popt12 = [1e-10,1e-10,1e-10], [1e-10,1e-10,1e-10] ,[1e-10,1e-10,1e-10] |
|
|||
1028 | FitGauss01, FitGauss02, FitGauss12 = numpy.empty(len(xSamples))*0, numpy.empty(len(xSamples))*0, numpy.empty(len(xSamples))*0 |
|
|||
1029 |
|
||||
1030 | CSPCMask01 = numpy.abs(CSPCSamples[0]) |
|
|||
1031 | CSPCMask02 = numpy.abs(CSPCSamples[1]) |
|
|||
1032 | CSPCMask12 = numpy.abs(CSPCSamples[2]) |
|
|||
1033 |
|
||||
1034 | mask01 = ~numpy.isnan(CSPCMask01) |
|
|||
1035 | mask02 = ~numpy.isnan(CSPCMask02) |
|
|||
1036 | mask12 = ~numpy.isnan(CSPCMask12) |
|
|||
1037 |
|
||||
1038 | #mask = ~numpy.isnan(CSPCMask01) |
|
|||
1039 | CSPCMask01 = CSPCMask01[mask01] |
|
|||
1040 | CSPCMask02 = CSPCMask02[mask02] |
|
|||
1041 | CSPCMask12 = CSPCMask12[mask12] |
|
|||
1042 | #CSPCMask01 = numpy.ma.masked_invalid(CSPCMask01) |
|
|||
1043 |
|
||||
1044 |
|
||||
1045 |
|
||||
1046 | '''***Fit Gauss CSPC01***''' |
|
|||
1047 | if dbSNR > SNRlimit and numpy.abs(SPCmoments[1])<3 : |
|
|||
1048 | try: |
|
|||
1049 | popt01,pcov = curve_fit(self.gaus,xSamples[mask01],numpy.abs(CSPCMask01),p0=CSPCmoments[0]) |
|
|||
1050 | popt02,pcov = curve_fit(self.gaus,xSamples[mask02],numpy.abs(CSPCMask02),p0=CSPCmoments[1]) |
|
|||
1051 | popt12,pcov = curve_fit(self.gaus,xSamples[mask12],numpy.abs(CSPCMask12),p0=CSPCmoments[2]) |
|
|||
1052 | FitGauss01 = self.gaus(xSamples,*popt01) |
|
|||
1053 | FitGauss02 = self.gaus(xSamples,*popt02) |
|
|||
1054 | FitGauss12 = self.gaus(xSamples,*popt12) |
|
|||
1055 | except: |
|
|||
1056 | FitGauss01=numpy.ones(len(xSamples))*numpy.mean(numpy.abs(CSPCSamples[0])) |
|
|||
1057 | FitGauss02=numpy.ones(len(xSamples))*numpy.mean(numpy.abs(CSPCSamples[1])) |
|
|||
1058 | FitGauss12=numpy.ones(len(xSamples))*numpy.mean(numpy.abs(CSPCSamples[2])) |
|
|||
1059 |
|
||||
1060 |
|
||||
1061 | CSPCopt = numpy.vstack([popt01,popt02,popt12]) |
|
|||
1062 |
|
||||
1063 | '''****** Getting fij width ******''' |
|
|||
1064 |
|
||||
1065 | yMean = numpy.average(ySamples, axis=0) # ySamples[0] |
|
|||
1066 |
|
||||
1067 | '''******* Getting fitting Gaussian *******''' |
|
|||
1068 | meanGauss = sum(xSamples*yMean) / len(xSamples) # Mu, velocidad radial (frecuencia) |
|
|||
1069 | sigma2 = sum(yMean*(xSamples-meanGauss)**2) / len(xSamples) # Varianza, Ancho espectral (frecuencia) |
|
|||
1070 |
|
||||
1071 | yMoments = self.Moments(yMean, xSamples) |
|
|||
1072 |
|
||||
1073 | if dbSNR > SNRlimit and numpy.abs(SPCmoments[1])<3: # and abs(meanGauss/sigma2) > 0.00001: |
|
|||
1074 | try: |
|
|||
1075 | popt,pcov = curve_fit(self.gaus,xSamples,yMean,p0=yMoments) |
|
|||
1076 | FitGauss=self.gaus(xSamples,*popt) |
|
|||
1077 |
|
||||
1078 | except :#RuntimeError: |
|
|||
1079 | FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean) |
|
|||
1080 |
|
||||
1081 |
|
||||
1082 | else: |
|
|||
1083 | FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean) |
|
|||
1084 |
|
||||
1085 |
|
||||
1086 |
|
||||
1087 | '''****** Getting Fij ******''' |
|
|||
1088 | Fijcspc = CSPCopt[:,2]/2*3 |
|
|||
1089 |
|
||||
1090 |
|
||||
1091 | GaussCenter = popt[1] #xFrec[GCpos] |
|
|||
1092 | #Punto en Eje X de la Gaussiana donde se encuentra el centro |
|
|||
1093 | ClosestCenter = xSamples[numpy.abs(xSamples-GaussCenter).argmin()] |
|
|||
1094 | PointGauCenter = numpy.where(xSamples==ClosestCenter)[0][0] |
|
|||
1095 |
|
||||
1096 | #Punto e^-1 hubicado en la Gaussiana |
|
|||
1097 | PeMinus1 = numpy.max(FitGauss)* numpy.exp(-1) |
|
|||
1098 | FijClosest = FitGauss[numpy.abs(FitGauss-PeMinus1).argmin()] # El punto mas cercano a "Peminus1" dentro de "FitGauss" |
|
|||
1099 | PointFij = numpy.where(FitGauss==FijClosest)[0][0] |
|
|||
1100 |
|
||||
1101 | if xSamples[PointFij] > xSamples[PointGauCenter]: |
|
|||
1102 | Fij = xSamples[PointFij] - xSamples[PointGauCenter] |
|
|||
1103 |
|
||||
1104 | else: |
|
|||
1105 | Fij = xSamples[PointGauCenter] - xSamples[PointFij] |
|
|||
1106 |
|
||||
1107 |
|
||||
1108 | '''****** Taking frequency ranges from SPCs ******''' |
|
|||
1109 |
|
||||
1110 |
|
||||
1111 | #GaussCenter = popt[1] #Primer momento 01 |
|
|||
1112 | GauWidth = popt[2] *3/2 #Ancho de banda de Gau01 |
|
|||
1113 | Range = numpy.empty(2) |
|
|||
1114 | Range[0] = GaussCenter - GauWidth |
|
|||
1115 | Range[1] = GaussCenter + GauWidth |
|
|||
1116 | #Punto en Eje X de la Gaussiana donde se encuentra ancho de banda (min:max) |
|
|||
1117 | ClosRangeMin = xSamples[numpy.abs(xSamples-Range[0]).argmin()] |
|
|||
1118 | ClosRangeMax = xSamples[numpy.abs(xSamples-Range[1]).argmin()] |
|
|||
1119 |
|
||||
1120 | PointRangeMin = numpy.where(xSamples==ClosRangeMin)[0][0] |
|
|||
1121 | PointRangeMax = numpy.where(xSamples==ClosRangeMax)[0][0] |
|
|||
1122 |
|
||||
1123 | Range=numpy.array([ PointRangeMin, PointRangeMax ]) |
|
|||
1124 |
|
||||
1125 | FrecRange = xFrec[ Range[0] : Range[1] ] |
|
|||
1126 | VelRange = xVel[ Range[0] : Range[1] ] |
|
|||
1127 |
|
||||
1128 |
|
||||
1129 | '''****** Getting SCPC Slope ******''' |
|
|||
1130 |
|
||||
1131 | for i in range(spc.shape[0]): |
|
|||
1132 |
|
||||
1133 | if len(FrecRange)>5 and len(FrecRange)<spc.shape[1]*0.3: |
|
|||
1134 | PhaseRange=self.moving_average(phase[i,Range[0]:Range[1]],N=3) |
|
|||
1135 |
|
||||
1136 | '''***********************VelRange******************''' |
|
|||
1137 |
|
||||
1138 | mask = ~numpy.isnan(FrecRange) & ~numpy.isnan(PhaseRange) |
|
|||
1139 |
|
||||
1140 | if len(FrecRange) == len(PhaseRange): |
|
|||
1141 | try: |
|
|||
1142 | slope, intercept, r_value, p_value, std_err = stats.linregress(FrecRange[mask], PhaseRange[mask]) |
|
|||
1143 | PhaseSlope[i]=slope |
|
|||
1144 | PhaseInter[i]=intercept |
|
|||
1145 | except: |
|
|||
1146 | PhaseSlope[i]=0 |
|
|||
1147 | PhaseInter[i]=0 |
|
|||
1148 | else: |
|
|||
1149 | PhaseSlope[i]=0 |
|
|||
1150 | PhaseInter[i]=0 |
|
|||
1151 | else: |
|
|||
1152 | PhaseSlope[i]=0 |
|
|||
1153 | PhaseInter[i]=0 |
|
|||
1154 |
|
||||
1155 |
|
||||
1156 | '''Getting constant C''' |
|
|||
1157 | cC=(Fij*numpy.pi)**2 |
|
|||
1158 |
|
||||
1159 | '''****** Getting constants F and G ******''' |
|
|||
1160 | MijEijNij=numpy.array([[Xi02,Eta02], [Xi12,Eta12]]) |
|
|||
1161 | MijResult0=(-PhaseSlope[1]*cC) / (2*numpy.pi) |
|
|||
1162 | MijResult1=(-PhaseSlope[2]*cC) / (2*numpy.pi) |
|
|||
1163 | MijResults=numpy.array([MijResult0,MijResult1]) |
|
|||
1164 | (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults) |
|
|||
1165 |
|
||||
1166 | '''****** Getting constants A, B and H ******''' |
|
|||
1167 | W01=numpy.nanmax( FitGauss01 ) #numpy.abs(CSPCSamples[0])) |
|
|||
1168 | W02=numpy.nanmax( FitGauss02 ) #numpy.abs(CSPCSamples[1])) |
|
|||
1169 | W12=numpy.nanmax( FitGauss12 ) #numpy.abs(CSPCSamples[2])) |
|
|||
1170 |
|
||||
1171 | WijResult0=((cF*Xi01+cG*Eta01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi/cC)) |
|
|||
1172 | WijResult1=((cF*Xi02+cG*Eta02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi/cC)) |
|
|||
1173 | WijResult2=((cF*Xi12+cG*Eta12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi/cC)) |
|
|||
1174 |
|
||||
1175 | WijResults=numpy.array([WijResult0, WijResult1, WijResult2]) |
|
|||
1176 |
|
||||
1177 | WijEijNij=numpy.array([ [Xi01**2, Eta01**2, 2*Xi01*Eta01] , [Xi02**2, Eta02**2, 2*Xi02*Eta02] , [Xi12**2, Eta12**2, 2*Xi12*Eta12] ]) |
|
|||
1178 | (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults) |
|
|||
1179 |
|
||||
1180 | VxVy=numpy.array([[cA,cH],[cH,cB]]) |
|
|||
1181 | VxVyResults=numpy.array([-cF,-cG]) |
|
|||
1182 | (Vx,Vy) = numpy.linalg.solve(VxVy, VxVyResults) |
|
|||
1183 |
|
||||
1184 | Vzon = Vy |
|
|||
1185 | Vmer = Vx |
|
|||
1186 | Vmag=numpy.sqrt(Vzon**2+Vmer**2) |
|
|||
1187 | Vang=numpy.arctan2(Vmer,Vzon) |
|
|||
1188 | if numpy.abs( popt[1] ) < 3.5 and len(FrecRange)>4: |
|
|||
1189 | Vver=popt[1] |
|
|||
1190 | else: |
|
|||
1191 | Vver=numpy.NaN |
|
|||
1192 | FitGaussCSPC = numpy.array([FitGauss01,FitGauss02,FitGauss12]) |
|
|||
1193 |
|
||||
1194 |
|
||||
1195 | return Vzon, Vmer, Vver, GaussCenter, PhaseSlope, FitGaussCSPC |
|
|||
1196 |
|
||||
1197 |
|
||||
1198 |
|
946 | |||
1199 | def StopWindEstimation(self, error_code): |
|
947 | def StopWindEstimation(self, error_code): | |
1200 | ''' |
|
948 | ''' | |
@@ -1231,9 +979,7 class FullSpectralAnalysis(Operation): | |||||
1231 |
|
979 | |||
1232 | return antialiased |
|
980 | return antialiased | |
1233 |
|
981 | |||
1234 |
|
982 | def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, AbbsisaRange, dbSNR, SNRlimit): | ||
1235 |
|
||||
1236 | def TestWindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, AbbsisaRange, dbSNR, SNRlimit): |
|
|||
1237 | """ |
|
983 | """ | |
1238 | Function that Calculates Zonal, Meridional and Vertical wind velocities. |
|
984 | Function that Calculates Zonal, Meridional and Vertical wind velocities. | |
1239 | Initial Version by E. Bocanegra updated by J. Zibell until Nov. 2019. |
|
985 | Initial Version by E. Bocanegra updated by J. Zibell until Nov. 2019. | |
@@ -1552,7 +1298,6 class FullSpectralAnalysis(Operation): | |||||
1552 | return Vzon, Vmer, Vver, error_code |
|
1298 | return Vzon, Vmer, Vver, error_code | |
1553 |
|
1299 | |||
1554 |
|
1300 | |||
1555 |
|
||||
1556 | class SpectralMoments(Operation): |
|
1301 | class SpectralMoments(Operation): | |
1557 |
|
1302 | |||
1558 | ''' |
|
1303 | ''' |
General Comments 0
You need to be logged in to leave comments.
Login now