def startvalfunc(Ne_init, loc, locsp, time, inputs, ambinfo=[0]): """ This is a method to determine the start values for the fitter. Inputs Ne_init - A nloc x nt numpy array of the initial estimate of electron density. Basically the zeroth lag of the ACF. loc - A nloc x 3 numpy array of cartisian coordinates. time - A nt x 2 numpy array of times in seconds exinputs - A list of extra inputs allowed for by the fitter class. It only has one element and its the name of the ionocontainer file holding the rest of the start parameters. Outputs xarray - This is a numpy array of starting values for the fitter parameters.""" if isinstance(inputs, str): if os.path.splitext(inputs)[-1] == '.h5': ionoin = IonoContainer.readh5(inputs) elif os.path.splitext(inputs)[-1] == '.mat': ionoin = IonoContainer.readmat(inputs) elif os.path.splitext(inputs)[-1] == '': ionoin = makeionocombined(inputs) elif isinstance(inputs, list): ionoin = makeionocombined(inputs) else: ionoin = inputs numel = sp.prod(ionoin.Param_List.shape[-2:]) + 1 xarray = sp.zeros((loc.shape[0], len(time), numel)) for ilocn, iloc in enumerate(loc): #for iamb in ambinfo: newlocsp = locsp[ilocn] #newlocsp[0] += iamb (datast, vel) = ionoin.getclosestsphere(newlocsp, time)[:2] datast[:, -1, 0] = Ne_init[ilocn, :] # get the ion densities ionoden = datast[:, :-1, 0] # find the right normalization for the ion species ionodensum = sp.repeat(sp.sum(ionoden, axis=-1)[:, sp.newaxis], ionoden.shape[-1], axis=-1) # renormalized to the right level ionoden = sp.repeat(Ne_init[ilocn, :, sp.newaxis], ionoden.shape[-1], axis=-1) * ionoden / ionodensum datast[:, :-1, 0] = ionoden xarray[ilocn, :, :-1] = sp.reshape( datast, (len(time), numel - 1)) #/float(len(ambinfo)) locmag = sp.sqrt(sp.sum(iloc * iloc)) ilocmat = sp.repeat(iloc[sp.newaxis, :], len(time), axis=0) xarray[ilocn, :, -1] = sp.sum(vel * ilocmat) / locmag #/float(len(ambinfo)) return xarray
def __init__(self,ionoin,configfile,timein=None,mattype='matrix'): """ This will create the RadarSpaceTimeOperator object. Inputs ionoin - The input ionocontainer. This can be either an string that is a ionocontainer file, a list of ionocontainer objects or a list a strings to ionocontainer files. config - The ini file that used to set up the simulation. timein - A Ntx2 numpy array of times. RSTOPinv - The inverse operator object. invmat - The inverse matrix to the original operator. """ mattype=mattype.lower() accepttypes=['matrix','sim','real'] if not mattype in accepttypes: raise ValueError('Matrix type can only be {0}'.format(', '.join(accepttypes))) d2r = np.pi/180.0 (sensdict,simparams) = readconfigfile(configfile) # determine if the input ionocontainer is a string, a list of strings or a list of ionocontainers. ionoin=makeionocombined(ionoin) #Input location self.Cart_Coords_In = ionoin.Cart_Coords self.Sphere_Coords_In = ionoin.Sphere_Coords # Set the input times if timein is None: self.Time_In = ionoin.Time_Vector else: self.Time_In = timein #Create an array of output location based off of the inputs rng_vec2 = simparams['Rangegatesfinal'] nrgout = len(rng_vec2) angles = simparams['angles'] nang =len(angles) ang_data = np.array([[iout[0],iout[1]] for iout in angles]) rng_all = np.repeat(rng_vec2,(nang),axis=0) ang_all = np.tile(ang_data,(nrgout,1)) self.Sphere_Coords_Out = np.column_stack((rng_all,ang_all)) (R_vec,Az_vec,El_vec) = (self.Sphere_Coords_Out[:,0],self.Sphere_Coords_Out[:,1], self.Sphere_Coords_Out[:,2]) xvecmult = np.sin(Az_vec*d2r)*np.cos(El_vec*d2r) yvecmult = np.cos(Az_vec*d2r)*np.cos(El_vec*d2r) zvecmult = np.sin(El_vec*d2r) X_vec = R_vec*xvecmult Y_vec = R_vec*yvecmult Z_vec = R_vec*zvecmult self.Cart_Coords_Out = np.column_stack((X_vec,Y_vec,Z_vec)) self.Time_Out = np.column_stack((simparams['Timevec'],simparams['Timevec']+simparams['Tint']))+self.Time_In[0,0] self.simparams=simparams self.sensdict=sensdict self.lagmat = self.simparams['amb_dict']['WttMatrix'] self.mattype=mattype # create the matrix (self.RSTMat,self.overlaps,self.blocklocs) = makematPA(ionoin.Sphere_Coords,ionoin.Cart_Coords,ionoin.Time_Vector,configfile,ionoin.Velocity,mattype)
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*np.arange(np) outdata = np.zeros((nlout,ntout,np),dtype=acf.dtype) assert np.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=np.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=np.dot(ambmat,tempdata) outdata[:,it_out] = np.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 phantest(inputfile,outdir,configfile,timevec): ne_red=1e-10 nemin,nemax=[0.*ne_red,3e11*ne_red] xlim = [-200.,360.] xticks = [-150.,0.,150.,300.] defmap = 'viridis'# color map fs=18# fontsize fscb=12 figsize = (10,7) ylim = [100.,500.] # iono1=makesimpledata(inputfile,timevec= None,begx=0.,begz=300.,vx=500.) iono1=makeionocombined(os.path.split(inputfile)[0]) iono2=iono1.deepcopy() iono2.Param_List[:,1:]=0. # sum1=sp.sum(iono1.Param_List,axis=1) # iono1.Param_List[:,:,:]=0. # iono1.Param_List[:,0]=sum1 RSTO1 = RadarSpaceTimeOperator(iono1,configfile,timevec,mattype='matrix') RSTO2 = RadarSpaceTimeOperator(iono2,configfile,timevec,mattype='sim') iono1new=RSTO1.mult_iono(iono1) iono2new=RSTO2.mult_iono(iono2) rngrdr =iono1new.Sphere_Coords[:,0].astype('float32') sign1 = sp.sign(iono1new.Sphere_Coords[:,1]) el = iono1new.Sphere_Coords[:,2].astype('float32') elvec,elinv = sp.unique(el,return_inverse=True) nbeams = len(elvec) nrg = len(rngrdr)/nbeams Rngrdrmat = sp.reshape(rngrdr,(nrg,nbeams)) Signmat = sp.reshape(sign1,(nrg,nbeams)) Elmat = sp.reshape(el,(nrg,nbeams)) Xmat = Rngrdrmat*Signmat*sp.cos(Elmat*sp.pi/180.) Zmat = Rngrdrmat*sp.sin(Elmat*sp.pi/180.) Ne1 = iono1new.Param_List[:,:,0].reshape(nrg,nbeams,1).real*ne_red Nemat1 = Ne1[:,:,0] Ne2 = iono2new.Param_List[:,:,0].reshape(nrg,nbeams,1).real*ne_red Nemat2 = Ne2[:,:,0] fig ,axmat= plt.subplots(nrows=1,ncols=2,facecolor='w',figsize=figsize,sharey=True) avec=axmat.flatten() plt.sca(avec[0]) avec[0].set_xlabel('X Plane in km',fontsize=fs) avec[0].set_ylabel('Alt in km',fontsize=fs) pc1 = avec[0].pcolor(Xmat,Zmat,Nemat1,cmap = defmap,vmin=nemin,vmax=nemax) plt.tick_params(labelsize=16) plt.xticks(xticks) avec[0].set_xlim(xlim) avec[0].set_ylim(ylim) avec[0].set_title('Operator No motion',fontsize=fs) tick_locator = ticker.MaxNLocator(nbins=5) cb1 = plt.colorbar(pc1, ax=avec[0]) cb1.ax.xaxis.set_label_position('top') cb1.ax.set_xlabel('') cb1.locator = tick_locator cb1.update_ticks() plt.sca(avec[1]) avec[1].set_xlabel('X Plane in km',fontsize=fs) avec[1].set_ylabel('Alt in km',fontsize=fs) pc1 = avec[1].pcolor(Xmat,Zmat,Nemat2,cmap = defmap,vmin=nemin,vmax=nemax) plt.tick_params(labelsize=fs) plt.xticks(xticks) avec[1].set_xlim(xlim) avec[1].set_ylim(ylim) avec[1].set_title('Operator for Motion',fontsize=fs) tick_locator = ticker.MaxNLocator(nbins=5) cb2 = plt.colorbar(pc1, ax=avec[1]) cb2.ax.xaxis.set_label_position('top') cb2.ax.set_xlabel('') cb2.locator = tick_locator cb2.update_ticks() plt.tight_layout() return fig,avec,Nemat1,Nemat2
def parametersweep(basedir,configfile,acfdir='ACF',invtype='tik'): """ This function will run the inversion numerious times with different constraint parameters. This will create a directory called cost and place. Input basedir - The directory that holds all of the data for the simulator. configfile - The ini file for the simulation. acfdir - The directory within basedir that hold the acfs to be inverted. invtype - The inversion method that will be tested. Can be tik, tikd, and tv. """ alpha_sweep=sp.logspace(-3.5,sp.log10(7),25) costdir = os.path.join(basedir,'Cost') ionoinfname=os.path.join(basedir,acfdir,'00lags.h5') ionoin=IonoContainer.readh5(ionoinfname) dirio = ('Spectrums','Mat','ACFMat') inputdir = os.path.join(basedir,dirio[0]) dirlist = glob.glob(os.path.join(inputdir,'*.h5')) (listorder,timevector,filenumbering,timebeg,time_s) = IonoContainer.gettimes(dirlist) Ionolist = [dirlist[ikey] for ikey in listorder] RSTO = RadarSpaceTimeOperator(Ionolist,configfile,timevector,mattype='Sim') npts=RSTO.simparams['numpoints'] ionospec=makeionocombined(dirlist) if npts==ionospec.Param_List.shape[-1]: tau,acfin=spect2acf(ionospec.Param_Names,ionospec.Param_List) nloc,ntimes=acfin.shape[:2] ambmat=RSTO.simparams['amb_dict']['WttMatrix'] np=ambmat.shape[0] acfin_amb=sp.zeros((nloc,ntimes,np),dtype=acfin.dtype) # get the original acf ambmat=RSTO.simparams['amb_dict']['WttMatrix'] np=ambmat.shape[0] for iloc,locarr in enumerate(acfin): for itime,acfarr in enumerate(locarr): acfin_amb[iloc,itime]=sp.dot(ambmat,acfarr) acfin_amb=acfin_amb[:,0] else: acfin_amb=ionospec.Param_List[:,0] if not os.path.isdir(costdir): os.mkdir(costdir) # pickle file stuff pname=os.path.join(costdir,'cost{0}-{1}.pickle'.format(acfdir,invtype)) alpha_list=[] errorlist=[] errorlaglist=[] datadiflist=[] constlist=[] if 'perryplane' in basedir.lower() or 'SimpData': rbounds=[-500,500] else: rbounds=[0,500] alpha_list_new=alpha_sweep.tolist() for i in alpha_list: if i in alpha_list_new: alpha_list_new.remove(i) for i in alpha_list_new: ionoout,datadif,constdif=invertRSTO(RSTO,ionoin,alpha_list=i,invtype=invtype,rbounds=rbounds,Nlin=1) datadiflist.append(datadif) constlist.append(constdif) acfout=ionoout.Param_List[:,0] alpha_list.append(i) outdata=sp.power(sp.absolute(acfout-acfin_amb),2) aveerror=sp.sqrt(sp.nanmean(outdata,axis=0)) errorlaglist.append(aveerror) errorlist.append(sp.nansum(aveerror)) pickleFile = open(pname, 'wb') pickle.dump([alpha_list,errorlist,datadiflist,constlist,errorlaglist],pickleFile) pickleFile.close() mkalphalist(pname) alphaarr=sp.array(alpha_list) errorarr=sp.array(errorlist) errorlagarr=sp.array(errorlaglist) datadif=sp.array(datadiflist) constdif=sp.array(constlist) fig,axlist,axmain=plotalphaerror(alphaarr,errorarr,errorlagarr) fig.savefig(os.path.join(costdir,'cost{0}-{1}.png'.format(acfdir,invtype))) fig,axlist=plotLcurve(alphaarr,datadif,constdif) fig.savefig(os.path.join(costdir,'lcurve{0}-{1}.png'.format(acfdir,invtype)))
def plotgradlines(inputlist,fitiono,alt,times,paramlist=['Ne','Te','Ti']): """ Plots the values along a specific alittude. """ inputiono = makeionocombined(inputlist) Iono1 = GeoData(readIono,[inputiono]) fitiono = IonoContainer.readh5(fitiono) fitGeo = GeoData(readIono,[fitiono]) paramlist = ['Ne','Te','Ti'] (x,y,z) = inputiono.Cart_Coords.transpose() r = sp.sqrt(x**2+y**2)*sp.sign(y) incoords = sp.column_stack((r,z,sp.ones_like(z))) ru,zu =[ sp.unique(r),sp.unique(z)] Rmat,Zmat = sp.meshgrid(ru,zu) zinput = sp.argmin(sp.absolute(zu-alt)) (xf,yf,zf) = fitiono.Cart_Coords.transpose() rf = sp.sqrt(xf**2+yf**2)*sp.sign(yf) outcoords = sp.column_stack((rf,zf,sp.ones_like(zf))) rfu,zfu =[ sp.unique(rf),sp.unique(zf)] Rfmat,Zfmat = sp.meshgrid(rfu,zfu) zoutput = sp.argmin(sp.absolute(zfu-alt)) fitGeo.interpolate(incoords,Iono1.coordnames,method='linear',fill_value=sp.nan,twodinterp = True,oldcoords=outcoords) uz = sp.unique(z) ur = sp.unique(r) (rmat,zmat) = sp.meshgrid(ur,uz) inputdata = {} for iparm in paramlist: if iparm =='Nepow': iparm='Ne' curdata = Iono1.data[iparm][:,times[0]] inputdata[iparm] = sp.reshape(curdata,Rmat.shape)[zinput] outputdata = {} for iparm in paramlist: curdata = fitGeo.data[iparm][:, times[1]] outputdata[iparm] = sp.reshape(curdata,Rmat.shape)[zinput] fig, axvec = plt.subplots(len(paramlist),1,sharey=False,figsize=(12,5*len(paramlist))) for ipn,iparam in enumerate(paramlist): ax = axvec[ipn] ax2 = ax.twinx() p1, = ax.plot(ru,inputdata[iparam],'b-',label='In',linewidth=3) p2, = ax.plot(ru,outputdata[iparam],'b--',label='Out',linewidth=3) ax.set_title(iparam) ax.set_xlabel('X Plane in km') gi = sp.gradient(inputdata[iparam])/sp.gradient(ru) go = sp.gradient(outputdata[iparam])/sp.gradient(ru) p3, = ax2.plot(ru,gi,'g-',label='Grad In',linewidth=3) p4, = ax2.plot(ru,go,'g--',label='Grad Out',linewidth=3) ax.yaxis.label.set_color(p1.get_color()) ax2.yaxis.label.set_color(p3.get_color()) lines = [p1,p2,p3,p4] ax.legend(lines,[l.get_label() for l in lines]) plt.tight_layout() return(fig)
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 * np.arange(np) outdata = np.zeros((nlout, ntout, np), dtype=acf.dtype) assert np.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 = np.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 = np.dot(ambmat, tempdata) outdata[:, it_out] = np.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 __init__(self, ionoin, configfile, timein=None, mattype='matrix'): """ This will create the RadarSpaceTimeOperator object. Inputs ionoin - The input ionocontainer. This can be either an string that is a ionocontainer file, a list of ionocontainer objects or a list a strings to ionocontainer files. config - The ini file that used to set up the simulation. timein - A Ntx2 numpy array of times. RSTOPinv - The inverse operator object. invmat - The inverse matrix to the original operator. """ mattype = mattype.lower() accepttypes = ['matrix', 'sim', 'real'] if not mattype in accepttypes: raise ValueError('Matrix type can only be {0}'.format( ', '.join(accepttypes))) d2r = np.pi / 180.0 (sensdict, simparams) = readconfigfile(configfile) # determine if the input ionocontainer is a string, a list of strings or a list of ionocontainers. ionoin = makeionocombined(ionoin) #Input location self.Cart_Coords_In = ionoin.Cart_Coords self.Sphere_Coords_In = ionoin.Sphere_Coords # Set the input times if timein is None: self.Time_In = ionoin.Time_Vector else: self.Time_In = timein #Create an array of output location based off of the inputs rng_vec2 = simparams['Rangegatesfinal'] nrgout = len(rng_vec2) angles = simparams['angles'] nang = len(angles) ang_data = np.array([[iout[0], iout[1]] for iout in angles]) rng_all = np.repeat(rng_vec2, (nang), axis=0) ang_all = np.tile(ang_data, (nrgout, 1)) self.Sphere_Coords_Out = np.column_stack((rng_all, ang_all)) (R_vec, Az_vec, El_vec) = (self.Sphere_Coords_Out[:, 0], self.Sphere_Coords_Out[:, 1], self.Sphere_Coords_Out[:, 2]) xvecmult = np.sin(Az_vec * d2r) * np.cos(El_vec * d2r) yvecmult = np.cos(Az_vec * d2r) * np.cos(El_vec * d2r) zvecmult = np.sin(El_vec * d2r) X_vec = R_vec * xvecmult Y_vec = R_vec * yvecmult Z_vec = R_vec * zvecmult self.Cart_Coords_Out = np.column_stack((X_vec, Y_vec, Z_vec)) self.Time_Out = np.column_stack( (simparams['Timevec'], simparams['Timevec'] + simparams['Tint'])) + self.Time_In[0, 0] self.simparams = simparams self.sensdict = sensdict self.lagmat = self.simparams['amb_dict']['WttMatrix'] self.mattype = mattype # create the matrix (self.RSTMat, self.overlaps, self.blocklocs) = makematPA(ionoin.Sphere_Coords, ionoin.Cart_Coords, ionoin.Time_Vector, configfile, ionoin.Velocity, mattype)