示例#1
0
    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]
示例#2
0
    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()]