Exemplo n.º 1
0
def mms_pgs_mphigeo(mag_temp, pos_temp):
    """
    Generates the 'mphigeo' transformation matrix
    """
    pos_data = get_data(pos_temp)

    if pos_data is None:
        logging.error('Error with position data')
        return

    # the following is heisted from the IDL version
    # transformation to generate other_dim dim for mphigeo from thm_fac_matrix_make
    # All the conversions to polar and trig simplifies to this.
    # But the reason the conversion is why this is the conversion that is done, is lost on me.
    # The conversion swaps the x & y components of position, reflects over x=0,z=0 then projects into the xy plane
    pos_conv = np.stack(
        (-pos_data.y[:, 1], pos_data.y[:, 0], np.zeros(len(pos_data.times))))
    pos_conv = np.transpose(pos_conv, [1, 0])
    store_data(pos_temp, data={'x': pos_data.times, 'y': pos_conv})

    # transform into GSE because the particles are in GSE
    cotrans(name_in=pos_temp,
            name_out=pos_temp,
            coord_in='gei',
            coord_out='gse')

    # create orthonormal basis set
    z_basis = tnormalize(mag_temp, return_data=True)
    x_basis = tcrossp(z_basis, pos_temp, return_data=True)
    x_basis = tnormalize(x_basis, return_data=True)
    y_basis = tcrossp(z_basis, x_basis, return_data=True)

    return (x_basis, y_basis, z_basis)
Exemplo n.º 2
0
def mms_pgs_make_fac(times, mag_tvar_in, pos_tvar_in, fac_type='mphigeo'):
    """
    Generate the field aligned coordinate transformation matrix
    """

    if not data_exists(mag_tvar_in):
        logging.error('Magnetic field variable not found: "' + mag_tvar_in +
                      '"; skipping field-aligned outputs')
        return

    if not data_exists(pos_tvar_in):
        logging.error('Position variable not found: "' + pos_tvar_in +
                      '"; skipping field-aligned outputs')
        return

    valid_types = ['mphigeo', 'phigeo', 'xgse']

    if fac_type not in valid_types:
        logging.error(
            'Invalid FAC type; valid types: "mphigeo", "phigeo", "xgse"')
        return

    cotrans(name_in=pos_tvar_in,
            name_out=pos_tvar_in,
            coord_in='gse',
            coord_out='gei')

    mag_temp = mag_tvar_in + '_pgs_temp'
    pos_temp = pos_tvar_in + '_pgs_temp'

    # first, we need to interpolate the magnetic field and position
    # variables to the time stamps of the particle data (times)
    tinterpol(mag_tvar_in, times, newname=mag_temp)
    tinterpol(pos_tvar_in, times, newname=pos_temp)

    if fac_type == 'mphigeo':
        basis = mms_pgs_mphigeo(mag_temp, pos_temp)
    elif fac_type == 'phigeo':
        basis = mms_pgs_phigeo(mag_temp, pos_temp)
    elif fac_type == 'xgse':
        basis = mms_pgs_xgse(mag_temp, pos_temp)

    fac_output = np.zeros((len(times), 3, 3))
    fac_output[:, 0, :] = basis[0]
    fac_output[:, 1, :] = basis[1]
    fac_output[:, 2, :] = basis[2]

    return fac_output
Exemplo n.º 3
0
 def test_cotrans_igrf(self):
     """Test GSE->GSM and IGRF."""
     del_data()
     d = [[245.0, -102.0, 251.0], [775.0, 10.0, -10], [121.0, 545.0, -1.0],
          [304.65, -205.3, 856.1], [464.34, -561.55, -356.22]]
     t = [1577112800, 1577308800, 1577598800, 1577608800, 1577998800]
     name_out = "tname_out"
     cotrans(name_out=name_out,
             time_in=t,
             data_in=d,
             coord_in="gse",
             coord_out="gsm")
     in_len = len(t)
     dout = get_data(name_out)
     out_len = len(dout[0])
     gsm = dout[1][1]
     res = [775.0, 11.70325822, -7.93937951]
     self.assertTrue(out_len == in_len)
     self.assertTrue(abs(gsm[0] - res[0]) <= 1e-6)
     self.assertTrue(abs(gsm[1] - res[1]) <= 1e-6)
     self.assertTrue(abs(gsm[2] - res[2]) <= 1e-6)
Exemplo n.º 4
0
 def test_cotrans(self):
     """Test cotrans.py GEI->GEO with Themis data."""
     del_data()
     trange = ['2010-02-25/00:00:00', '2010-02-25/23:59:59']
     probe = 'a'
     name_in = "tha_pos"
     name_out = "tha_pos_new_geo"
     pyspedas.themis.state(probe=probe,
                           trange=trange,
                           time_clip=True,
                           varnames=[name_in])
     cotrans(name_in=name_in,
             name_out=name_out,
             coord_in="gei",
             coord_out="geo")
     din = get_data(name_in)
     in_len = len(din[0])
     dout = get_data(name_out)
     out_len = len(dout[0])
     cotrans(name_in=name_in, coord_in="gei", coord_out="geo")
     self.assertTrue(out_len == in_len)
Exemplo n.º 5
0
 def test_cotrans_geigsm(self):
     """Test daisy chain of multiple transofrmations, GEI->GSE->GSM."""
     del_data()
     d = [[245.0, -102.0, 251.0], [775.0, 10.0, -10], [121.0, 545.0, -1.0],
          [304.65, -205.3, 856.1], [464.34, -561.55, -356.22]]
     t = [1577112800, 1577308800, 1577598800, 1577608800, 1577998800]
     name_out = "tname_out"
     cotrans(name_out=name_out,
             time_in=t,
             data_in=d,
             coord_in="gei",
             coord_out="gsm")
     in_len = len(t)
     dout = get_data(name_out)
     out_len = len(dout[0])
     gsm = dout[1][1]
     res = [4.59847513e+01, 7.62303493e+02, 1.32679267e+02]
     self.assertTrue(out_len == in_len)
     self.assertTrue(abs(gsm[0] - res[0]) <= 1e-6)
     self.assertTrue(abs(gsm[1] - res[1]) <= 1e-6)
     self.assertTrue(abs(gsm[2] - res[2]) <= 1e-6)
Exemplo n.º 6
0
 def test_cotrans_j2000(self):
     """Test GEI->J2000 and J2000 params."""
     del_data()
     d = [[245.0, -102.0, 251.0], [775.0, 10.0, -10], [121.0, 545.0, -1.0],
          [304.65, -205.3, 856.1], [464.34, -561.55, -356.22]]
     t = [1577112800, 1577308800, 1577598800, 1577608800, 1577998800]
     name_out = "tname_out"
     cotrans(name_out=name_out,
             time_in=t,
             data_in=d,
             coord_in="gei",
             coord_out="j2000")
     in_len = len(t)
     dout = get_data(name_out)
     out_len = len(dout[0])
     j2000 = dout[1][1]
     res = [775.01595209, 6.59521058, -11.47942543]
     self.assertTrue(out_len == in_len)
     self.assertTrue(abs(j2000[0] - res[0]) <= 1e-6)
     self.assertTrue(abs(j2000[1] - res[1]) <= 1e-6)
     self.assertTrue(abs(j2000[2] - res[2]) <= 1e-6)
Exemplo n.º 7
0
def mms_cotrans_lmn(name_in,
                    name_out,
                    gsm=False,
                    gse=False,
                    probe=None,
                    data_rate='srvy'):
    '''
    Tranforms MMS vector fields from GSM coordinates to LMN (boundary-normal) coordinates
    using the Shue et al., 1998 magnetopause model

    Input
    ------
        name_in: str
            Name of the input tplot variable

        name_out: str
            Name of the output tplot variable

    Parameters
    -----------
        gsm: bool
            Flag to indicate the input data are in GSM coordinates

        gse: bool
            Flag to indicate the input data are in GSE coordinates; note: the input data 
            will be transformed to GSM prior to transforming to LMN

        probe: str
            Spacecraft probe #; if not specified, the routine attempts to extract from the 
            input variable name

        data_rate: str
            Data rate of the input data; default is 'srvy'

    Returns
    --------
        Name of the variable containing the data in LMN coordinates.

    '''

    data_in = get_data(name_in)
    metadata_in = get_data(name_in, metadata=True)

    if data_in is None:
        logging.error('Error reading tplot variable: ' + name_in)
        return None

    data_in_coord = cotrans_get_coord(name_in).lower()

    if data_in_coord != 'gse' and data_in_coord != 'gsm' and not gse and not gsm:
        logging.error(
            'Please specify the coordinate system of the input data.')
        return

    # we'll need the probe if it's not specified via keyword
    if probe is None:
        sc_id = name_in.split('_')[0]

        if sc_id != '':
            probe = sc_id[-1]

        if probe not in ['1', '2', '3', '4']:
            logging.error(
                'Error, probe not found; please specify the probe via the "probe" keyword.'
            )
            return

    # load the spacecraft position data
    mec_vars = mec(trange=[min(data_in.times),
                           max(data_in.times)],
                   probe=probe,
                   data_rate=data_rate)

    # interpolate the position data to the input data
    tinterp_vars = tinterpol('mms' + probe + '_mec_r_gsm',
                             name_in,
                             newname='mms' + probe + '_mec_r_gsm_interp')

    pos_data = get_data('mms' + probe + '_mec_r_gsm_interp')

    # we'll need the input data in GSM coordinates
    if data_in_coord != 'gsm':
        cotrans_out = cotrans(name_in, name_in + '_gsm', coord_out='gsm')
        data_in = get_data(name_in + '_gsm')

    swdata = solarwind_load([min(data_in.times), max(data_in.times)])

    logging.info(
        'Transforming GSM -> LMN; this may take several minutes, depending on the size of the input.'
    )
    Blmn = gsm2lmn(data_in.times, pos_data.y, data_in.y, swdata=swdata)

    saved = store_data(name_out,
                       data={
                           'x': data_in.times,
                           'y': Blmn
                       },
                       attr_dict=metadata_in)

    if saved:
        options(name_out, 'legend_names', ['L', 'M', 'N'])
        return name_out
    else:
        logging.error('Problem creating tplot variable.')
Exemplo n.º 8
0
def dsi2j2000(name_in=None,
              name_out=None,
              no_orb=False,
              J20002DSI=False,
              noload=False):
    """
    This function transform a time series data between the DSI and J2000 coordinate systems

    Parameters:

        name_in : str
            input tplot variable to be transformed

        name_out : str
            Name of the tplot variable in which the transformed data is stored

        J20002DSI : bool
            Set to transform data from J2000 to DSI. If not set, it transforms data from DSI to J2000.

    Returns:
        None

    """
    if (name_in is None) or (name_in not in tplot_names(quiet=True)):
        print('Input of Tplot name is undifiend')
        return

    if name_out is None:
        print('Tplot name for output is undifiend')
        name_out = 'result_of_dsi2j2000'

    # prepare for transformed Tplot Variable
    reload = not noload
    dl_in = get_data(name_in, metadata=True)
    get_data_array = get_data(name_in)
    time_array = get_data_array[0]
    time_length = time_array.shape[0]
    dat = get_data_array[1]

    # Get the SGI axis by interpolating the attitude data
    dsiz_j2000 = erg_interpolate_att(name_in, noload=noload)['sgiz_j2000']

    # Sun direction in J2000
    sundir = np.array([[1., 0., 0.]]*time_length)

    if no_orb:
        store_data('sundir_gse', data={'x': time_array, 'y': sundir})

    else:  # Calculate the sun directions from the instantaneous satellite locations
        if reload:
            tr = get_timespan(name_in)
            orb(trange=time_string([tr[0] - 60., tr[1] + 60.]))
            tinterpol('erg_orb_l2_pos_gse', time_array)
            scpos = get_data('erg_orb_l2_pos_gse-itrp')[1]
            sunpos = np.array([[1.496e+08, 0., 0.]]*time_length)
            sundir = sunpos - scpos
            store_data('sundir_gse', data={'x': time_array, 'y': sundir})
            tnormalize('sundir_gse', newname='sundir_gse')

    # Derive DSI-X and DSI-Y axis vectors in J2000.
    # The elementary vectors below are the definition of DSI. The detailed relationship
    # between the spin phase, sun pulse timing, sun direction, and the actual subsolar point
    # on the spining s/c body should be incorporated into the calculation below.
    if reload:
        cotrans(name_in='sundir_gse', name_out='sundir_j2000',
                coord_in='gse', coord_out='j2000')
    sun_j2000 = get_data('sundir_j2000')
    dsiy = tcrossp(dsiz_j2000['y'], sun_j2000[1], return_data=True)
    dsix = tcrossp(dsiy, dsiz_j2000['y'], return_data=True)
    dsix_j2000 = {'x': time_array, 'y': dsix}
    dsiy_j2000 = {'x': time_array, 'y': dsiy}

    if not J20002DSI:
        print('DSI --> J2000')
        mat = cart_trans_matrix_make(
            dsix_j2000['y'], dsiy_j2000['y'], dsiz_j2000['y'])
        j2000x_in_dsi = np.dot(mat, np.array([1., 0., 0.]))
        j2000y_in_dsi = np.dot(mat, np.array([0., 1., 0.]))
        j2000z_in_dsi = np.dot(mat, np.array([0., 0., 1.]))
        mat = cart_trans_matrix_make(
            j2000x_in_dsi, j2000y_in_dsi, j2000z_in_dsi)
        dat_new = np.einsum("ijk,ik->ij", mat, dat)
    else:
        print('J2000 --> DSI')
        mat = cart_trans_matrix_make(
            dsix_j2000['y'], dsiy_j2000['y'], dsiz_j2000['y'])
        dat_new = np.einsum("ijk,ik->ij", mat, dat)

    store_data(name_out, data={'x': time_array, 'y': dat_new}, attr_dict=dl_in)
    options(name_out, 'ytitle', '\n'.join(name_out.split('_')))
Exemplo n.º 9
0
    def test_all_cotrans(self):
        """Test all cotrans pairs.

        Apply transformation, then inverse transformation and compare.
        """
        cotrans()
        all_cotrans = ['gei', 'geo', 'j2000', 'gsm', 'mag', 'gse', 'sm']
        d = [[245.0, -102.0, 251.0], [775.0, 10.0, -10], [121.0, 545.0, -1.0],
             [304.65, -205.3, 856.1], [464.34, -561.55, -356.22]]
        dd1 = d[1]
        t = [1577112800, 1577308800, 1577598800, 1577608800, 1577998800]
        in_len = len(t)
        name1 = "name1"
        name2 = "name2"
        count = 0
        # Test non-existent system.
        cotrans(name_out=name1,
                time_in=t,
                data_in=d,
                coord_in="coord_in",
                coord_out="coord_out")
        # Test empty data.
        cotrans(name_out=name1,
                time_in=t,
                data_in=[],
                coord_in="gei",
                coord_out="geo")
        cotrans(time_in=t, data_in=d, coord_in="gse", coord_out="gsm")
        # Test all combinations.
        for coord_in in all_cotrans:
            for coord_out in all_cotrans:
                count += 1
                del_data()
                cotrans(name_out=name1,
                        time_in=t,
                        data_in=d,
                        coord_in=coord_in,
                        coord_out=coord_out)
                dout = get_data(name1)
                out_len1 = len(dout[0])
                self.assertTrue(out_len1 == in_len)
                # Now perform inverse transformation.
                cotrans(name_in=name1,
                        name_out=name2,
                        coord_in=coord_out,
                        coord_out=coord_in)
                dout2 = get_data(name2)
                out_len2 = len(dout2[0])
                dd2 = dout2[1][1]
                print(count, "--- in:", coord_in, "out:", coord_out)
                # print(dout[1][1])
                # print(dd2)
                self.assertTrue(out_len2 == in_len)
                self.assertTrue(abs(dd1[0] - dd2[0]) <= 1e-6)
                self.assertTrue(abs(dd1[1] - dd2[1]) <= 1e-6)
                self.assertTrue(abs(dd1[2] - dd2[2]) <= 1e-6)