def mult_iono(self, ionoin_list): """ This will apply the forward model to the contents of an ionocontainer object. It is assuming that this is an ionocontainer holding the spectra. """ ntout = self.Time_Out.shape[0] nlout = self.Cart_Coords_Out.shape[0] blist_in, blist_out = self.blocklocs amb_dict = self.simparams['amb_dict'] ambmat = amb_dict['WttMatrix'] overlaps = self.overlaps t_s = self.sensdict['t_s'] if isinstance(ionoin_list, list) or isinstance(ionoin_list, str): Iono_in = makeionocombined(ionoin_list) else: Iono_in = ionoin_list ionocart = Iono_in.Cart_Coords if self.simparams['numpoints'] == Iono_in.Param_List.shape[-1]: tau, acf = spect2acf(Iono_in.Param_Names, Iono_in.Param_List) np = ambmat.shape[0] else: acf = Iono_in.Param_List np = acf.shape[-1] np_in = acf.shape[-1] tau_out = t_s * sp.arange(np) outdata = sp.zeros((nlout, ntout, np), dtype=acf.dtype) assert sp.allclose( ionocart, self.Cart_Coords_In), "Spatial Coordinates need to be the same" for it_out in range(ntout): overlists = overlaps[it_out] irows = blist_out[it_out] curintimes = [i[0] for i in overlists] curintratio = [i[1] for i in overlists] if self.mattype.lower() == 'sim': curintimes = [curintimes[0]] curintratio = [1.] cur_outmat = self.RSTMat[irows[0]:irows[1], :] icols = blist_in[it_out] cur_mat = cur_outmat[:, icols[0]:icols[1]] for i_it, it_in in enumerate(curintimes): tempdata = sp.zeros((np_in, nlout), dtype=acf.dtype) for iparam in range(np_in): tempdata[iparam] = cur_mat.dot(acf[:, it_in, iparam]) if self.simparams['numpoints'] == Iono_in.Param_List.shape[-1]: tempdata = sp.dot(ambmat, tempdata) outdata[:, it_out] = sp.transpose( tempdata) * curintratio[i_it] + outdata[:, it_out] outiono = IonoContainer(self.Sphere_Coords_Out, outdata, times=self.Time_Out, sensor_loc=Iono_in.Sensor_loc, ver=1, coordvecs=['r', 'theta', 'phi'], paramnames=tau_out) return outiono
def lagdict2ionocont(DataLags,NoiseLags,sensdict,simparams,time_vec): """This function will take the data and noise lags and create an instance of the Ionocontanier class. This function will also apply the summation rule to the lags. Inputs DataLags - A dictionary """ # Pull in Location Data angles = simparams['angles'] ang_data = sp.array([[iout[0],iout[1]] for iout in angles]) rng_vec = simparams['Rangegates'] # pull in other data pulsewidth = len(simparams['Pulse'])*sensdict['t_s'] txpower = sensdict['Pt'] if sensdict['Name'].lower() in ['risr','pfisr','risr-n']: Ksysvec = sensdict['Ksys'] else: beamlistlist = sp.array(simparams['outangles']).astype(int) inplist = sp.array([i[0] for i in beamlistlist]) Ksysvec = sensdict['Ksys'][inplist] ang_data_temp = ang_data.copy() ang_data = sp.array([ang_data_temp[i].mean(axis=0) for i in beamlistlist ]) sumrule = simparams['SUMRULE'] rng_vec2 = simparams['Rangegatesfinal'] minrg = -sumrule[0].min() maxrg = len(rng_vec)-sumrule[1].max() Nrng2 = len(rng_vec2) # Copy the lags lagsData= DataLags['ACF'].copy() # Set up the constants for the lags so they are now # in terms of density fluxtuations. angtile = sp.tile(ang_data,(Nrng2,1)) rng_rep = sp.repeat(rng_vec2,ang_data.shape[0],axis=0) coordlist=sp.zeros((len(rng_rep),3)) [coordlist[:,0],coordlist[:,1:]] = [rng_rep,angtile] (Nt,Nbeams,Nrng,Nlags) = lagsData.shape rng3d = sp.tile(rng_vec[sp.newaxis,sp.newaxis,:,sp.newaxis],(Nt,Nbeams,1,Nlags)) *1e3 ksys3d = sp.tile(Ksysvec[sp.newaxis,:,sp.newaxis,sp.newaxis],(Nt,1,Nrng,Nlags)) radar2acfmult = rng3d*rng3d/(pulsewidth*txpower*ksys3d) pulses = sp.tile(DataLags['Pulses'][:,:,sp.newaxis,sp.newaxis],(1,1,Nrng,Nlags)) time_vec = time_vec[:Nt] # Divid lags by number of pulses lagsData = lagsData/pulses # Set up the noise lags and divid out the noise. lagsNoise=NoiseLags['ACF'].copy() lagsNoise = sp.mean(lagsNoise,axis=2) pulsesnoise = sp.tile(NoiseLags['Pulses'][:,:,sp.newaxis],(1,1,Nlags)) lagsNoise = lagsNoise/pulsesnoise lagsNoise = sp.tile(lagsNoise[:,:,sp.newaxis,:],(1,1,Nrng,1)) # subtract out noise lags lagsData = lagsData-lagsNoise # Calculate a variance using equation 2 from Hysell's 2008 paper. Done use full covariance matrix because assuming nearly diagonal. # multiply the data and the sigma by inverse of the scaling from the radar lagsData = lagsData*radar2acfmult lagsNoise = lagsNoise*radar2acfmult # Apply summation rule # lags transposed from (time,beams,range,lag)to (range,lag,time,beams) lagsData = sp.transpose(lagsData,axes=(2,3,0,1)) lagsNoise = sp.transpose(lagsNoise,axes=(2,3,0,1)) lagsDatasum = sp.zeros((Nrng2,Nlags,Nt,Nbeams),dtype=lagsData.dtype) lagsNoisesum = sp.zeros((Nrng2,Nlags,Nt,Nbeams),dtype=lagsNoise.dtype) for irngnew,irng in enumerate(sp.arange(minrg,maxrg)): for ilag in range(Nlags): lagsDatasum[irngnew,ilag] = lagsData[irng+sumrule[0,ilag]:irng+sumrule[1,ilag]+1,ilag].sum(axis=0) lagsNoisesum[irngnew,ilag] = lagsNoise[irng+sumrule[0,ilag]:irng+sumrule[1,ilag]+1,ilag].sum(axis=0) # Put everything in a parameter list Paramdata = sp.zeros((Nbeams*Nrng2,Nt,Nlags),dtype=lagsData.dtype) # Put everything in a parameter list # transpose from (range,lag,time,beams) to (beams,range,time,lag) lagsDatasum = sp.transpose(lagsDatasum,axes=(3,0,2,1)) lagsNoisesum = sp.transpose(lagsNoisesum,axes=(3,0,2,1)) # Get the covariance matrix pulses_s=sp.transpose(pulses,axes=(1,2,0,3))[:,:Nrng2] Cttout=makeCovmat(lagsDatasum,lagsNoisesum,pulses_s,Nlags) # R=sp.transpose(lagsDatasum/sp.sqrt(2.*pulses_s),axes=(3,0,1,2)) # Rw=sp.transpose(lagsNoisesum/sp.sqrt(2.*pulses_s),axes=(3,0,1,2)) # l=sp.arange(Nlags) # T1,T2=sp.meshgrid(l,l) # R0=R[sp.zeros_like(T1)] # Rw0=Rw[sp.zeros_like(T1)] # Td=sp.absolute(T1-T2) # Tl = T1>T2 # R12 =R[Td] # R12[Tl]=sp.conjugate(R12[Tl]) # Rw12 =Rw[Td] # Rw12[Tl]=sp.conjugate(Rw12[Tl]) # Ctt=R0*R12+R[T1]*sp.conjugate(R[T2])+Rw0*Rw12+Rw[T1]*sp.conjugate(Rw[T2]) # Cttout = sp.transpose(Ctt,(2,3,4,0,1)) Paramdatasig = sp.zeros((Nbeams*Nrng2,Nt,Nlags,Nlags),dtype=Cttout.dtype) curloc = 0 for irng in range(Nrng2): for ibeam in range(Nbeams): Paramdata[curloc] = lagsDatasum[ibeam,irng].copy() Paramdatasig[curloc] = Cttout[ibeam,irng].copy() curloc+=1 ionodata = IonoContainer(coordlist,Paramdata,times = time_vec,ver =1, paramnames=sp.arange(Nlags)*sensdict['t_s']) ionosigs = IonoContainer(coordlist,Paramdatasig,times = time_vec,ver =1, paramnames=sp.arange(Nlags*Nlags).reshape(Nlags,Nlags)*sensdict['t_s']) return (ionodata,ionosigs)