def AlphaOfK(self,Kt,lati,mlti,imod,parmod): # lati and mlti are the footpoint of the FL at iono exname = ['zeroB','T96_01','T01_01','T04_s'] # The name should be the same than inname = ['DIP_08','IGRF_GSW_08'] # in routine rhand_08. !!Check capital letters!! dsmax=.1 err=0.0000001 Lmax = 1000 pi=np.pi rlim=15. r0=1. iopt=1 # dummy variable in TRACE #ps=0. # force ps = 0 #tsygFort.geopack1.sps=np.sin(ps) #tsygFort.geopack1.cps=np.cos(ps) DIR=1. rr=1.0001 xi=-rr*np.cos(lati)*np.cos(mlti) yi=-rr*np.cos(lati)*np.sin(mlti) zi=rr*np.sin(lati) # Mapping from North to South Hemisphere xf,yf,zf,xx,yy,zz,npf=tsygFort.trace_08(xi,yi,zi,DIR,dsmax,err,rlim,r0,\ iopt,parmod,exname[imod],'DIP_08',Lmax) Bmag = np.zeros(npf) ds = np.zeros(npf) for i in range(npf): bx,by,bz,Bmag[i] = self.Tsy_w_dip(imod,parmod,xx[i],yy[i],zz[i]) ds[i] = np.sqrt((xx[i+1]-xx[i])**2+(yy[i+1]-yy[i])**2+(zz[i+1]-zz[i])**2) idx_eq = Bmag.argmin() Beq = Bmag[idx_eq] #if np.abs(zz[idx_eq])>0.1: # print ("Warning: Min B out of equator at z=%6.2f, Bmin=%6.2f" %(zz[idx_eq],Beq)) #ipdb.set_trace() Alpha = pi/180*np.array([20,25,30,35,40,45,50,55,60,70,80]) _sinA = np.sin(Alpha) Bm = Beq/(_sinA**2) K = np.zeros(len(Alpha)) for i in range(len(Alpha)): # look for Bm index idx_m1 = (np.abs(Bmag[0:idx_eq]-Bm[i])).argmin() idx_m2 = (np.abs(Bmag[idx_eq:-1]-Bm[i])).argmin() + idx_eq ### Do integration K ### I = np.sqrt(np.abs(Bm[i] - Bmag[idx_m1:idx_m2+1])) #K[i] = np.dot(I,ds[idx_m1:idx_m2+1]) S = np.cumsum(ds) K[i] = np.trapz(I,S[idx_m1:idx_m2+1]) #ipdb.set_trace() f = interp1d(K, Alpha, kind='cubic',fill_value="extrapolate") alpha = f(Kt) #ipdb.set_trace() return alpha,Beq
def mapping(self,imod,parmod,xeq,yeq,zeq,lati,mlti,switch): #----------------------------------------------------------------------------- # Routine mapping field line from equator to earth surface and vice versa # input: imod,parmod # if switch=1, xeq,yeq,zeq # if switch=-1, lati,mlti # output: # if switch=1, lati,mlti # if switch=-1, xeq,yeq,zeq,iout exname = ['zeroB','T96_01','T01_01','T04_s'] # The name should be the same than inname = ['DIP_08','IGRF_GSW_08'] # in routine rhand_08. !!Check capital letters!! dsmax=1.33 err=0.00001 Lmax = 1000 pi=np.pi rlim=15. r0=1. iopt=1 # dummy variable in TRACE ps=0. # force ps = 0 tsygFort.geopack1.sps=np.sin(ps) tsygFort.geopack1.cps=np.cos(ps) if (switch ==1): # mapping from equator to earth surface DIR=-1. xf,yf,zf,xx,yy,zz,npf = tsygFort.trace_08(xeq,yeq,zeq,DIR,dsmax,err,rlim,r0,\ iopt,parmod,exname[imod],'DIP_08',Lmax) rf=np.sqrt(xf*xf+yf*yf+zf*zf) lati=np.arcsin(zf/rf) # latitude in radian at ionosphere mlti=np.arctan2(yf,xf)+pi # local time in radian at ionosphere return lati,mlti else : # mapping from Earth surface to equator DIR=1. rr=1.0001 xi=-rr*np.cos(lati)*np.cos(mlti) yi=-rr*np.cos(lati)*np.sin(mlti) zi=rr*np.sin(lati) xf,yf,zf,xx,yy,zz,npf,iout=tsygFort.trace1_08(xi,yi,zi,DIR,dsmax,err,rlim,r0,\ iopt,parmod,exname[imod],'DIP_08',Lmax) xeq=xf yeq=yf zeq=zf return xf,yf,zf,iout
def KofAlpha(self,Alpha,lati,mlti,imod,parmod): # lati and mlti are the footpoint of the FL at iono and Alpha is PA at magnetic equator exname = ['zeroB','T96_01','T01_01','T04_s'] # The name should be the same than inname = ['DIP_08','IGRF_GSW_08'] # in routine rhand_08. !!Check capital letters!! dsmax=.1 err=0.0000001 Lmax = 1000 pi=np.pi rlim=15. r0=1. iopt=1 # dummy variable in TRACE #ps=0. # force ps = 0 #tsygFort.geopack1.sps=np.sin(ps) #tsygFort.geopack1.cps=np.cos(ps) DIR=1. rr=1.0001 xi=-rr*np.cos(lati)*np.cos(mlti) yi=-rr*np.cos(lati)*np.sin(mlti) zi=rr*np.sin(lati) # Mapping from North to South Hemisphere xf,yf,zf,xx,yy,zz,npf=tsygFort.trace_08(xi,yi,zi,DIR,dsmax,err,rlim,r0,\ iopt,parmod,exname[imod],'DIP_08',Lmax) Bmag = np.zeros(npf) ds = np.zeros(npf) for i in range(npf): bx,by,bz,Bmag[i] = self.Tsy_w_dip(imod,parmod,xx[i],yy[i],zz[i]) ds[i] = np.sqrt((xx[i+1]-xx[i])**2+(yy[i+1]-yy[i])**2+(zz[i+1]-zz[i])**2) idx_eq = Bmag.argmin() Beq = Bmag[idx_eq] _sinA = np.sin(Alpha) Bm = Beq/(_sinA**2) idx_m1 = (np.abs(Bmag[0:idx_eq]-Bm)).argmin() idx_m2 = (np.abs(Bmag[idx_eq:-1]-Bm)).argmin() + idx_eq ### Do integration K ### I = np.sqrt(np.abs(Bm - Bmag[idx_m1:idx_m2+1])) #K = np.dot(I,ds[idx_m1:idx_m2+1]) S = np.cumsum(ds) K = np.trapz(I,S[idx_m1:idx_m2+1]) #ipdb.set_trace() return K
def trace(self, lat=None, lon=None, rho=None, coords=None, datetime=None, vswgse=None, pdyn=None, dst=None, byimf=None, bzimf=None, lmax=5000, rmax=60., rmin=1., dsmax=0.01, err=0.000001): """See tsygTrace for a description of each parameter Any unspecified parameter default to the one stored in the object Unspecified lmax, rmax, rmin, dsmax, err has a set default value Parameters ---------- lat : Optional[ ] latitude [degrees] lon : Optional[ ] longitude [degrees] rho : Optional[ ] distance from center of the Earth [km] coords : Optional[str] coordinates used for start point ['geo'] datetime : Optional[datetime] a python datetime object vswgse : Optional[list, float] solar wind velocity in GSE coordinates [m/s, m/s, m/s] pdyn : Optional[float] solar wind dynamic pressure [nPa] dst : Optional[flaot] Dst index [nT] byimf : Optional[float] IMF By [nT] bzimf : Optional[float] IMF Bz [nT] lmax : Optional[int] maximum number of points to trace rmax : Optional[float] upper trace boundary in Re rmin : Optional[float] lower trace boundary in Re dsmax : Optional[float] maximum tracing step size err : Optional[float] tracing step tolerance Written by Sebastien 2012-10 """ from numpy import radians, degrees, zeros # Store existing values of class attributes in case something is wrong # and we need to revert back to them if lat: _lat = self.lat if lon: _lon = self.lon if rho: _rho = self.rho if coords: _coords = self.coords if vswgse: _vswgse = self.vswgse if not datetime is None: _datetime = self.datetime # Pass position if new if lat: self.lat = lat lat = self.lat if lon: self.lon = lon lon = self.lon if rho: self.rho = rho rho = self.rho if not datetime is None: self.datetime = datetime datetime = self.datetime # Set necessary parameters if new if coords: self.coords = coords coords = self.coords if not datetime is None: self.datetime = datetime datetime = self.datetime if vswgse: self.vswgse = vswgse vswgse = self.vswgse if pdyn: self.pdyn = pdyn pdyn = self.pdyn if dst: self.dst = dst dst = self.dst if byimf: self.byimf = byimf byimf = self.byimf if bzimf: self.bzimf = bzimf bzimf = self.bzimf # Test that everything is in order, if not revert to existing values iTest = self.__test_valid__() if not iTest: if lat: self.lat = _lat if lon: _self.lon = lon if rho: self.rho = _rho if coords: self.coords = _coords if vswgse: self.vswgse = _vswgse if not datetime is None: self.datetime = _datetime # Declare the same Re as used in Tsyganenko models [km] Re = 6371.2 # Initialize trace array self.l = zeros(len(lat)) self.xTrace = zeros((len(lat), 2 * lmax)) self.yTrace = self.xTrace.copy() self.zTrace = self.xTrace.copy() self.xGsw = self.l.copy() self.yGsw = self.l.copy() self.zGsw = self.l.copy() self.latNH = self.l.copy() self.lonNH = self.l.copy() self.rhoNH = self.l.copy() self.latSH = self.l.copy() self.lonSH = self.l.copy() self.rhoSH = self.l.copy() # And now iterate through the desired points for ip in xrange(len(lat)): # This has to be called first tsygFort.recalc_08(datetime[ip].year, datetime[ip].timetuple().tm_yday, datetime[ip].hour, datetime[ip].minute, datetime[ip].second, vswgse[0], vswgse[1], vswgse[2]) # Convert lat,lon to geographic cartesian and then gsw r, theta, phi, xgeo, ygeo, zgeo = tsygFort.sphcar_08( rho[ip] / Re, radians(90. - lat[ip]), radians(lon[ip]), 0., 0., 0., 1) if coords.lower() == 'geo': xgeo, ygeo, zgeo, xgsw, ygsw, zgsw = tsygFort.geogsw_08( xgeo, ygeo, zgeo, 0., 0., 0., 1) self.xGsw[ip] = xgsw self.yGsw[ip] = ygsw self.zGsw[ip] = zgsw # Trace field line inmod = 'IGRF_GSW_08' exmod = 'T96_01' parmod = [pdyn, dst, byimf, bzimf, 0, 0, 0, 0, 0, 0] # First towards southern hemisphere maptoL = [-1, 1] for mapto in maptoL: xfgsw, yfgsw, zfgsw, xarr, yarr, zarr, l = tsygFort.trace_08( xgsw, ygsw, zgsw, mapto, dsmax, err, rmax, rmin, 0, parmod, exmod, inmod, lmax) # Convert back to spherical geographic coords xfgeo, yfgeo, zfgeo, xfgsw, yfgsw, zfgsw = tsygFort.geogsw_08( 0., 0., 0., xfgsw, yfgsw, zfgsw, -1) geoR, geoColat, geoLon, xgeo, ygeo, zgeo = tsygFort.sphcar_08( 0., 0., 0., xfgeo, yfgeo, zfgeo, -1) # Get coordinates of traced point if mapto == 1: self.latSH[ip] = 90. - degrees(geoColat) self.lonSH[ip] = degrees(geoLon) self.rhoSH[ip] = geoR * Re elif mapto == -1: self.latNH[ip] = 90. - degrees(geoColat) self.lonNH[ip] = degrees(geoLon) self.rhoNH[ip] = geoR * Re # Store trace if mapto == -1: self.xTrace[ip, 0:l] = xarr[l - 1::-1] self.yTrace[ip, 0:l] = yarr[l - 1::-1] self.zTrace[ip, 0:l] = zarr[l - 1::-1] elif mapto == 1: ind = int(self.l[ip]) self.xTrace[ip, ind:ind + l] = xarr[0:l] self.yTrace[ip, ind:ind + l] = yarr[0:l] self.zTrace[ip, ind:ind + l] = zarr[0:l] self.l[ip] += l # Resize trace output to more minimum possible length ind = int(self.l.max()) self.xTrace = self.xTrace[:, 0:ind] self.yTrace = self.yTrace[:, 0:ind] self.zTrace = self.zTrace[:, 0:ind]
def trace(self, lat=None, lon=None, rho=None, coords=None, datetime=None, vswgse=None, pdyn=None, dst=None, byimf=None, bzimf=None, lmax=5000, rmax=60., rmin=1., dsmax=0.01, err=0.000001): """ | See tsygTrace for a description of each parameter | Any unspecified parameter default to the one stored in the object | Unspecified lmax, rmax, rmin, dsmax, err has a set default value | | Written by Sebastien 2012-10 """ from numpy import radians, degrees, zeros # Store existing values of class attributes in case something is wrong # and we need to revert back to them if lat: _lat = self.lat if lon: _lon = self.lon if rho: _rho = self.rho if coords: _coords = self.coords if vswgse: _vswgse = self.vswgse if not datetime==None: _datetime = self.datetime # Pass position if new if lat: self.lat = lat lat = self.lat if lon: self.lon = lon lon = self.lon if rho: self.rho = rho rho = self.rho if not datetime==None: self.datetime = datetime datetime = self.datetime # Set necessary parameters if new if coords: self.coords = coords coords = self.coords if not datetime==None: self.datetime = datetime datetime = self.datetime if vswgse: self.vswgse = vswgse vswgse = self.vswgse if pdyn: self.pdyn = pdyn pdyn = self.pdyn if dst: self.dst = dst dst = self.dst if byimf: self.byimf = byimf byimf = self.byimf if bzimf: self.bzimf = bzimf bzimf = self.bzimf # Test that everything is in order, if not revert to existing values iTest = self.__test_valid__() if not iTest: if lat: self.lat = _lat if lon: _self.lon = lon if rho: self.rho = _rho if coords: self.coords = _coords if vswgse: self.vswgse = _vswgse if not datetime==None: self.datetime = _datetime # Declare the same Re as used in Tsyganenko models [km] Re = 6371.2 # Initialize trace array self.l = zeros(len(lat)) self.xTrace = zeros((len(lat),2*lmax)) self.yTrace = self.xTrace.copy() self.zTrace = self.xTrace.copy() self.xGsw = self.l.copy() self.yGsw = self.l.copy() self.zGsw = self.l.copy() self.latNH = self.l.copy() self.lonNH = self.l.copy() self.rhoNH = self.l.copy() self.latSH = self.l.copy() self.lonSH = self.l.copy() self.rhoSH = self.l.copy() # And now iterate through the desired points for ip in xrange(len(lat)): # This has to be called first tsygFort.recalc_08(datetime[ip].year,datetime[ip].timetuple().tm_yday, datetime[ip].hour,datetime[ip].minute,datetime[ip].second, vswgse[0],vswgse[1],vswgse[2]) # Convert lat,lon to geographic cartesian and then gsw r, theta, phi, xgeo, ygeo, zgeo = tsygFort.sphcar_08( rho[ip]/Re, radians(90.-lat[ip]), radians(lon[ip]), 0., 0., 0., 1) if coords.lower() == 'geo': xgeo, ygeo, zgeo, xgsw, ygsw, zgsw = tsygFort.geogsw_08( xgeo, ygeo, zgeo, 0. ,0. ,0. , 1) self.xGsw[ip] = xgsw self.yGsw[ip] = ygsw self.zGsw[ip] = zgsw # Trace field line inmod = 'IGRF_GSW_08' exmod = 'T96_01' parmod = [pdyn, dst, byimf, bzimf, 0, 0, 0, 0, 0, 0] # First towards southern hemisphere maptoL = [-1, 1] for mapto in maptoL: xfgsw, yfgsw, zfgsw, xarr, yarr, zarr, l = tsygFort.trace_08( xgsw, ygsw, zgsw, mapto, dsmax, err, rmax, rmin, 0, parmod, exmod, inmod, lmax ) # Convert back to spherical geographic coords xfgeo, yfgeo, zfgeo, xfgsw, yfgsw, zfgsw = tsygFort.geogsw_08( 0. ,0. ,0. , xfgsw, yfgsw, zfgsw, -1) geoR, geoColat, geoLon, xgeo, ygeo, zgeo = tsygFort.sphcar_08( 0., 0., 0., xfgeo, yfgeo, zfgeo, -1) # Get coordinates of traced point if mapto == 1: self.latSH[ip] = 90. - degrees(geoColat) self.lonSH[ip] = degrees(geoLon) self.rhoSH[ip] = geoR*Re elif mapto == -1: self.latNH[ip] = 90. - degrees(geoColat) self.lonNH[ip] = degrees(geoLon) self.rhoNH[ip] = geoR*Re # Store trace if mapto == -1: self.xTrace[ip,0:l] = xarr[l-1::-1] self.yTrace[ip,0:l] = yarr[l-1::-1] self.zTrace[ip,0:l] = zarr[l-1::-1] elif mapto == 1: self.xTrace[ip,self.l[ip]:self.l[ip]+l] = xarr[0:l] self.yTrace[ip,self.l[ip]:self.l[ip]+l] = yarr[0:l] self.zTrace[ip,self.l[ip]:self.l[ip]+l] = zarr[0:l] self.l[ip] += l # Resize trace output to more minimum possible length self.xTrace = self.xTrace[:,0:self.l.max()] self.yTrace = self.yTrace[:,0:self.l.max()] self.zTrace = self.zTrace[:,0:self.l.max()]