Exemplo n.º 1
0
def load_data(sc='mms1', mode='srvy', level='l2', optdesc='efield',
              start_date=None, end_date=None, rename_vars=True,
              **kwargs):
    """
    Load EDI data.
    
    CDF variable names are renamed to something easier to remember and
    use. Original CDF variable names are kept as an attribute "cdf_name"
    in each individual variable.
    
    Parameters
    ----------
    sc : str
        Spacecraft ID: ('mms1', 'mms2', 'mms3', 'mms4')
    mode : str
        Instrument mode: ('slow', 'srvy', 'fast', 'brst').
    level : str
        Data quality level ('l1a', 'l2pre', 'l2')
    optdesc : str
        Optional descriptor. Options are: {'efield' | 'amb' | 'amb-pm2' |
        'amb-alt-cc', 'amb-alt-oc', 'amb-alt-oob', 'amb-perp-c',
        'amb-perp-ob'}
    start_date, end_date : `datetime.datetime`
        Start and end of the data interval.
    rename_vars : bool
        If true (default), rename the standard MMS variable names
        to something more memorable and easier to use.
    \*\*kwargs : dict
    	Any keyword accepted by *pymms.data.util.load_data*
    
    Returns
    -------
    dist : `xarray.Dataset`
        EDI data.
    """
    
    with warnings.catch_warnings(record=True) as w:
        # Cause all warnings to always be triggered.
        warnings.simplefilter("always")
        
        # Load the data
        data = util.load_data(sc=sc, instr='edi', mode=mode, level=level,
                              optdesc=optdesc, start_date=start_date, 
                              end_date=end_date, **kwargs)
        
        # Verify some things
        import pdb
        pdb.set_trace()
        if len(w) > 0:
            data = prune_time_overlap(data, start_date, end_date)
    
    # EDI generates empty efield files when in ambient mode. These files
    # have a version number of '0.0.0' and get read in as empty datasets,
    # which fail the concatenation in util.load_data. Remove the datasets
    # associated with empty files and concatenate the datasets with data
    if isinstance(data, list):
        # Remove empty datasets
        data = [ds 
                for ds in data
                if api.parse_file_name(ds.attrs['filename'])[-1] != '0.0.0']
        
        # Concatenate again
        data = xr.concat(data, dim='Epoch')
    
    # Rename data variables to something simpler
    if rename_vars:
        data = rename(data, sc, mode, level, optdesc)
    
    # Add data descriptors to attributes
    data.attrs['sc'] = sc
    data.attrs['instr'] = 'edi'
    data.attrs['mode'] = mode
    data.attrs['level'] = level
    data.attrs['optdesc'] = optdesc
    
    return data
Exemplo n.º 2
0
def load_data(sc='mms1',
              mode='srvy',
              level='l2',
              optdesc='efield',
              start_date=None,
              end_date=None,
              **kwargs):
    """
    Load EDI data.
    
    CDF variable names are renamed to something easier to remember and
    use. Original CDF variable names are kept as an attribute "cdf_name"
    in each individual variable.
    
    Parameters
    ----------
    sc : str
        Spacecraft ID: ('mms1', 'mms2', 'mms3', 'mms4')
    mode : str
        Instrument mode: ('slow', 'srvy', 'fast', 'brst').
    optdesc : str
        Optional descriptor. Options are: {'efield' | 'amb' | 'amb-pm2' |
        'amb-alt-cc', 'amb-alt-oc', 'amb-alt-oob', 'amb-perp-c',
        'amb-perp-ob'}
    \*\*kwargs : dict
    	Any keyword accepted by *pymms.data.util.load_data*
    
    Returns
    -------
    dist : `xarray.Dataset`
        EDI data.
    """

    # Load the data
    data = util.load_data(sc=sc,
                          instr='edi',
                          mode=mode,
                          level=level,
                          optdesc=optdesc,
                          start_date=start_date,
                          end_date=end_date,
                          **kwargs)

    # Rename data variables to something simpler
    if optdesc == 'efield':
        v_dsl_vname = '_'.join((sc, 'edi', 'vdrift', 'dsl', mode, level))
        v_gse_vname = '_'.join((sc, 'edi', 'vdrift', 'gse', mode, level))
        v_gsm_vname = '_'.join((sc, 'edi', 'vdrift', 'gsm', mode, level))
        e_dsl_vname = '_'.join((sc, 'edi', 'e', 'dsl', mode, level))
        e_gse_vname = '_'.join((sc, 'edi', 'e', 'gse', mode, level))
        e_gsm_vname = '_'.join((sc, 'edi', 'e', 'gsm', mode, level))
        v_labl_vname = 'v_labls'
        e_labl_vname = 'e_labls'

        names = {
            v_dsl_vname: 'V_DSL',
            v_gse_vname: 'V_GSE',
            v_gsm_vname: 'V_GSM',
            e_dsl_vname: 'E_DSL',
            e_gse_vname: 'E_GSE',
            e_gsm_vname: 'E_GSM',
            v_labl_vname: 'V_index',
            e_labl_vname: 'E_index'
        }

        names = {key: val for key, val in names.items() if key in data}
        data = data.rename(names)

    return data
Exemplo n.º 3
0
def load_data(sc='mms1',
              mode='srvy',
              level='l2',
              start_date=None,
              end_date=None,
              rename_vars=True,
              **kwargs):
    """
    Load SCM data.
    
    CDF variable names are renamed to something easier to remember and
    use. Original CDF variable names are kept as an attribute "cdf_name"
    in each individual variable.
    
    Parameters
    ----------
    sc : str
        Spacecraft ID: ('mms1', 'mms2', 'mms3', 'mms4')
    mode : str
        Instrument mode: ('slow', 'srvy', 'fast', 'brst').
    level : str
        Data quality level ('l1a', 'l2pre', 'l2')
    start_date, end_date : `datetime.datetime`
        Start and end of the data interval.
    rename_vars : bool
        If true (default), rename the standard MMS variable names
        to something more memorable and easier to use.
    \*\*kwargs : dict
        Any keyword accepted by *pymms.data.util.load_data*
    
    Returns
    -------
    data : `xarray.Dataset`
        SCM data.
    """
    if mode == 'srvy':
        optcesc = 'scsrvy'
    elif mode == 'slow':
        optdesc = 'scs'
    elif mode == 'fast':
        optdesc = 'scf'
    elif mode == 'brst':
        optdesc = 'scb'
    else:
        raise ValueError('SCM data rate mode {0} invalid. Try {1}'.format(
            mode, ('slow', 'fast', 'srvy', 'brst')))

    # Load the data
    #   - R is concatenated along Epoch, but depends on Epoch_state
    data = util.load_data(sc=sc,
                          instr='scm',
                          mode=mode,
                          level=level,
                          optdesc=optdesc,
                          start_date=start_date,
                          end_date=end_date,
                          **kwargs)

    # Rename data variables to something simpler
    if rename_vars:
        data = rename(data, sc, mode, level, optdesc)

    return data
Exemplo n.º 4
0
def load_data(sc='mms1',
              mode='brst',
              level='l3',
              optdesc='8khz',
              start_date=None,
              end_date=None,
              rename_vars=True,
              coords='gse',
              product='b',
              **kwargs):
    """
    Load EDI data.
    
    CDF variable names are renamed to something easier to remember and
    use. Original CDF variable names are kept as an attribute "cdf_name"
    in each individual variable.
    
    Parameters
    ----------
    sc : str
        Spacecraft ID: ('mms1', 'mms2', 'mms3', 'mms4')
    mode : str
        Instrument mode: ('fast', 'brst'). If 'srvy' is given, it is
        automatically changed to 'fast'.
    level : str
        Data quality level ('l1a', 'l2pre', 'l2')
    optdesc : str
        Optional descriptor. Options are: ('8khz',)
    start_date, end_date : `datetime.datetime`
        Start and end of the data interval.
    coords : str, list
        Data coordinate system ('gse', 'gsm')
    product : str
        Data product to be loaded ('b', 'r')
    rename_vars : bool
        If true (default), rename the standard MMS variable names
        to something more memorable and easier to use.
    \*\*kwargs : dict
        Any keyword accepted by *pymms.data.util.load_data*
    
    Returns
    -------
    dist : `xarray.Dataset`
        FSM data.
    """
    if isinstance(coords, str):
        coords = [coords]

    # Select either magnetic field or position data
    if product in ('b', 'b-field'):
        product = 'b'
    elif product in ('r', 'ephemeris', 'state'):
        product = 'r'
    else:
        raise ValueError(
            'Invalid data product {0}. Choose from (b, r)'.format(product))
    if product == 'b':
        coords += ['mag']
    varformat = '_' + product + '_(' + '|'.join(coords) + ')_'

    # Load the data
    #   - R is concatenated along Epoch, but depends on Epoch_state
    data = util.load_data(sc=sc,
                          instr='fsm',
                          mode=mode,
                          level=level,
                          optdesc=optdesc,
                          start_date=start_date,
                          end_date=end_date,
                          team_site=True,
                          varformat=varformat,
                          **kwargs)

    # The FSM CDFs do not have a DEPEND_0 attribute for the time delta
    # variable. Coordinates have to be assigned and its index reset
    if isinstance(data, list):
        t_delta_vname = '_'.join((sc, 'fsm', 'epoch', 'delta', mode, level))
        for idx, ds in enumerate(data):
            data[idx] = (ds.assign_coords({
                t_delta_vname: ds['Epoch']
            }).reset_coords(t_delta_vname))

        # Concatenate the dat
        data = xr.concat(data, dim='Epoch')

    # Rename data variables to something simpler
    if rename_vars:
        data = rename(data, sc, mode, level, optdesc, product=product)

    # Add attributes about the data request
    data.attrs['sc'] = sc
    data.attrs['instr'] = 'fsm'
    data.attrs['mode'] = mode
    data.attrs['level'] = level
    data.attrs['optdesc'] = optdesc

    return data
Exemplo n.º 5
0
def load_data(sc='mms1',
              mode='fast',
              level='l2',
              optdesc='dce',
              start_date=None,
              end_date=None,
              rename_vars=True,
              **kwargs):
    """
    Load EDP data.
    
    Parameters
    ----------
    sc : str
        Spacecraft ID: ('mms1', 'mms2', 'mms3', 'mms4')
    mode : str
        Instrument mode: ('slow', 'srvy', 'fast', 'brst').
    level : str
        Data quality level ('l1a', 'l2pre', 'l2')
    optdesc : str
        Optional descriptor ('dce', 'scpot', 'hmfe')
    start_date, end_date : `datetime.datetime`
        Start and end of the data interval.
    rename_vars : bool
        If true (default), rename the standard MMS variable names
        to something more memorable and easier to use.
    \*\*kwargs : dict
        Any keyword accepted by *pymms.data.util.load_data*
    
    Returns
    -------
    data : `xarray.Dataset`
        EDP data.
    """

    # Check the inputs
    check_spacecraft(sc)
    mode = check_mode(mode)

    # Load the data
    t_vname = '_'.join((sc, 'edp', 'epoch', mode, level))
    data = util.load_data(sc=sc,
                          instr='edp',
                          mode=mode,
                          level=level,
                          optdesc=optdesc,
                          start_date=start_date,
                          end_date=end_date,
                          record_dim=t_vname,
                          **kwargs)

    # Trim time interval
    data = data.sel({t_vname: slice(start_date, end_date)})

    # Rename variables
    if rename_vars:
        data = rename(data, sc, mode, level, optdesc)

    # Add data descriptors to attributes
    data.attrs['sc'] = sc
    data.attrs['instr'] = 'fpi'
    data.attrs['mode'] = mode
    data.attrs['level'] = level
    data.attrs['optdesc'] = optdesc

    return data
Exemplo n.º 6
0
def load_data(sc='mms1',
              instr='fgm',
              mode='srvy',
              level='l2',
              start_date=None,
              end_date=None,
              rename_vars=True,
              coords='gse',
              product='b-field',
              **kwargs):
    """
    Load FGM data.
    
    Notes
    -----
    Ephemeris data and magnetic field data are stored in the same file
    but have different DEPEND_0 variables. When concatenating along
    Epoch (the B-field DEPEND_0), a new Epoch dimension is added to the
    ephemeris data. Particularly for survey data, the array dimensions
    are too large to hold in memory and xarray/python crashes. For now,
    load ephemeris and b-field data separately. See the *product*
    keyword.
    
    Parameters
    ----------
    sc : str
        Spacecraft ID: ('mms1', 'mms2', 'mms3', 'mms4')
    instr : str
        Instrument ID: ('afg', 'dfg', 'fgm')
    mode : str
        Instrument mode: ('fast', 'brst'). If 'srvy' is given, it is
        automatically changed to 'fast'.
    level : str
        Data quality level ('l1a', 'l2pre', 'l2')
    start_date, end_date : `datetime.datetime`
        Start and end of the data interval.
    product : str
        Data product to be loaded ('b', 'b-field', 'ephemeris', 'state')
    coords : str, list
        Data coordinate system ('gse', 'gsm', 'dmpa', 'bcs')
    rename_vars : bool
        If true (default), rename the standard MMS variable names
        to something more memorable and easier to use.
    \*\*kwargs : dict
        Keywords for `pymms.data.util.load_data`
    
    Returns
    -------
    dist : `metaarray.metaarray`
        Particle distribution function.
    """

    # Check the inputs
    check_spacecraft(sc)
    mode = check_mode(mode, level=level)
    check_level(level, instr=instr)
    if isinstance(coords, str):
        coords = [coords]

    # Select either magnetic field or position data
    if product in ('b', 'b-field'):
        product = 'b'
    elif product in ('r', 'ephemeris', 'state'):
        product = 'r'
    else:
        raise ValueError(
            'Invalid data product {0}. Choose from (b, r)'.format(product))
    varformat = '_' + product + '_(' + '|'.join(coords) + ')_'

    # Load the data
    #   - R is concatenated along Epoch, but depends on Epoch_state
    data = util.load_data(sc=sc,
                          instr=instr,
                          mode=mode,
                          level=level,
                          start_date=start_date,
                          end_date=end_date,
                          varformat=varformat,
                          **kwargs)

    if rename_vars:
        data = rename(data, sc, instr, mode, level, product=product)

    # Add data descriptors to attributes
    data.attrs['sc'] = sc
    data.attrs['instr'] = instr
    data.attrs['mode'] = mode
    data.attrs['level'] = level

    return data
Exemplo n.º 7
0
def plot_photocurrent():

    # Download the data
    scpot = edp.load_scpot(sc=sc,
                           mode=mode,
                           start_date=orbit_t0,
                           end_date=orbit_t1)
    dis_moms = fpi.load_moms(sc=sc,
                             mode=mode,
                             optdesc='dis-moms',
                             start_date=orbit_t0,
                             end_date=orbit_t1)
    des_moms = fpi.load_moms(sc=sc,
                             mode=mode,
                             optdesc='des-moms',
                             start_date=orbit_t0,
                             end_date=orbit_t1)
    aspoc = mms_util.load_data(sc=sc,
                               instr='aspoc',
                               mode='srvy',
                               level='l2',
                               start_date=orbit_t0,
                               end_date=orbit_t1)

    # Bin data into FPI time stamps
    t_bins = np.append(
        dis_moms['time'].data - dis_moms['Epoch_minus_var'].data,
        dis_moms['time'].data[-1] + dis_moms['Epoch_plus_var'].data)
    Vsc, edges, binnum = binned_statistic(scpot['time'].astype('i8'),
                                          scpot['Vsc'],
                                          statistic='mean',
                                          bins=t_bins.astype('i8'))

    asp1, edges, binnum = binned_statistic(aspoc['Epoch'].astype('i8'),
                                           aspoc[sc + '_asp1_ionc'],
                                           statistic='mean',
                                           bins=t_bins.astype('i8'))

    idx = 0
    data_bin = []
    asp2 = np.empty_like(asp1)
    asp_on = np.zeros(asp1.shape, dtype='?')
    ref_idx = binnum[0]

    for aspoc_idx, bin_idx in enumerate(binnum):
        if (bin_idx == 0) | (bin_idx == len(aspoc[sc + '_asp1_ionc'])):
            continue
        elif ref_idx == 0:
            ref_idx = bin_idx

        if bin_idx == ref_idx:
            data_bin.append(aspoc_idx)
        else:
            asp2[idx] = aspoc[sc + '_asp2_ionc'][data_bin].mean()
            asp_on[idx] = aspoc[sc + '_aspoc_status'][data_bin, 3].max() > 0
            idx += 1
            ref_idx = bin_idx
            data_bin = [aspoc_idx]

    Vsc = xr.DataArray(Vsc, dims='time', coords={'time': dis_moms['time']})
    asp = xr.Dataset(
        {
            'asp1': (['time'], asp1),
            'asp2': (['time'], asp2),
            'asp': (['time'], asp1 + asp2)
        },
        coords={'time': dis_moms['time']})

    # Electron current
    Ie = electron_current(des_moms['density'], des_moms['t'], Vsc)

    # Flag the data
    flag = xr.DataArray(asp_on.astype('int'),
                        dims='time',
                        coords={'time': dis_moms['time']})
    flag += (((Ie < 1e-11) & (Vsc > 8) & (Vsc < 11)) * 2**1)
    flag += (((Vsc > 14.75) & (Ie > 7.9e-12) & (Ie < 2e-11)) * 2**2)
    flag += (((Vsc > 12.6) & (Vsc <= 14.75) & (Ie > 9.2e-12) & (Ie < 2e-11)) *
             2**2)

    #
    # Fit the data
    #

    # Ie = Iph0 exp(-Vsc/Vph0)
    # y = a exp(b * x)
    # log(y) = log(a) + b*x
    b, a = np.polyfit(Vsc[flag == 0],
                      np.log(Ie[flag == 0]),
                      1,
                      w=np.sqrt(Ie[flag == 0]))
    Ie_fit = np.exp(a) * np.exp(b * Vsc[flag == 0])
    str_fit = ('Ie = {0:0.3e} exp(-Vsc/{1:0.3e})'.format(
        np.exp(a), 1 / np.exp(b)))

    # Fit density to the spacecraft potential
    c, b, a = np.polyfit(Vsc[flag == 0], des_moms['density'][flag == 0], 2)
    Ne_fit2 = c * Vsc[flag == 0]**2 + b * Vsc[flag == 0] + a
    str_Ne_fit2 = ('Ne = {0:0.3e}Vsc^2 + {1:0.3e}Vsc^1 + {2:0.3e})'.format(
        c, b, a))

    e, d, c, b, a = np.polyfit(Vsc[flag == 0], des_moms['density'][flag == 0],
                               4)
    Ne_fit4 = e * Vsc[flag == 0]**4 + d * Vsc[flag == 0]**3 + c * Vsc[
        flag == 0]**2 + b * Vsc[flag == 0] + a
    str_Ne_fit4 = (
        'Ne = {0:0.3e}Vsc^4 + {1:0.3e}Vsc^3 + {2:0.3e}Vsc^2 + {3:0.3e}Vsc + {4:0.3e})'
        .format(e, d, c, b, a))

    # Fit density to the inverse of the spacecraft potential
    c, b, a = np.polyfit(1 / Vsc[flag == 0], des_moms['density'][flag == 0], 2)
    invV_fit2 = c / Vsc[flag == 0]**2 + b / Vsc[flag == 0] + a
    str_invV_fit2 = ('Ne = {0:0.3e}/Vsc^2 + {1:0.3e}/Vsc + {2:0.3e})'.format(
        c, b, a))

    e, d, c, b, a = np.polyfit(1 / Vsc[flag == 0],
                               des_moms['density'][flag == 0], 4)
    invV_fit4 = e / Vsc[flag == 0]**4 + d / Vsc[flag == 0]**3 + c / Vsc[
        flag == 0]**2 + b / Vsc[flag == 0] + a
    str_invV_fit4 = (
        'Ne = {0:0.3e}/Vsc^4 + {1:0.3e}/Vsc^3 + {2:0.3e}/Vsc^2 + {3:0.3e}/Vsc + {4:0.3e})'
        .format(e, d, c, b, a))

    #
    # Plot: Time Series
    #

    # Plot current-related data
    fig1, axes1 = plt.subplots(nrows=8,
                               ncols=1,
                               sharex=True,
                               figsize=(5, 6.5),
                               squeeze=False)
    plt.subplots_adjust(left=0.17, right=0.85, bottom=0.14, top=0.95)

    # Ion energy spectrogram
    nt = dis_moms['omnispectr'].shape[0]
    nE = dis_moms['omnispectr'].shape[1]
    x0 = mdates.date2num(dis_moms['time'])[:, np.newaxis].repeat(nE, axis=1)
    x1 = dis_moms['energy']

    y = np.where(dis_moms['omnispectr'] == 0, 1, dis_moms['omnispectr'])
    y = np.log(y[0:-1, 0:-1])

    ax = axes1[0, 0]
    im = ax.pcolorfast(x0, x1, y, cmap='nipy_spectral')
    ax.images.append(im)
    ax.set_title(sc.upper())
    ax.set_yscale('log')
    ax.set_ylabel('E (ion)\n(eV)')
    util.format_axes(ax, xaxis='off')
    cb = util.add_colorbar(ax, im)
    cb.set_label('$log_{10}$DEF\nkeV/($cm^{2}$ s sr keV)')

    # Electron energy spectrogram
    nt = des_moms['omnispectr'].shape[0]
    nE = des_moms['omnispectr'].shape[1]
    x0 = mdates.date2num(des_moms['time'])[:, np.newaxis].repeat(nE, axis=1)
    x1 = des_moms['energy']

    y = np.where(des_moms['omnispectr'] == 0, 1, des_moms['omnispectr'])
    y = np.log(y[0:-1, 0:-1])

    ax = axes1[1, 0]
    im = ax.pcolorfast(x0, x1, y, cmap='nipy_spectral')
    ax.images.append(im)
    ax.set_yscale('log')
    ax.set_ylabel('E (e-)\n(eV)')
    util.format_axes(ax, xaxis='off')
    cb = util.add_colorbar(ax, im)
    cb.set_label('$log_{10}$DEF\nkeV/($cm^{2}$ s sr keV)')

    # Density
    ax = axes1[2, 0]
    l1 = dis_moms['density'].plot(ax=ax, label='$N_{i}$')
    l2 = des_moms['density'].plot(ax=ax, label='$N_{e}$')
    ax.set_title('')
    ax.set_ylabel('N\n($cm^{3}$)')
    ax.set_yscale('log')
    util.format_axes(ax, xaxis='off')
    util.add_legend(ax, [l1[0], l2[0]])

    # Temperature
    ax = axes1[3, 0]
    l1 = dis_moms['t'].plot(ax=ax, label='$T_{i}$')
    l2 = des_moms['t'].plot(ax=ax, label='$T_{e}$')
    util.format_axes(ax, xaxis='off')
    util.add_legend(ax, [l1[0], l2[0]])
    ax.set_title('')
    ax.set_ylabel('T\n(eV)')
    ax.set_yscale('log')

    # Spacecraft potential
    ax = axes1[4, 0]
    Vsc[~asp_on].plot(ax=ax)
    Vsc[asp_on].plot(ax=ax, color='red')
    util.format_axes(ax, xaxis='off')
    ax.set_title('')
    ax.set_ylabel('$V_{S/C}$\n(V)')

    # Electron current
    ax = axes1[5, 0]
    Ie.plot(ax=ax)
    ax.set_title('')
    ax.set_ylabel('$I_{e}$\n($\mu A$)')
    ax.set_yscale('log')
    ax.set_ylim([1e-12, 1e-10])
    util.format_axes(ax, xaxis='off')

    # Aspoc Status
    ax = axes1[6, 0]
    l1 = asp['asp1'].plot(ax=ax, label='$ASP_{1}$')
    l2 = asp['asp2'].plot(ax=ax, label='$ASP_{2}$')
    l3 = asp['asp'].plot(ax=ax, label='$ASP_{tot}$')
    util.format_axes(ax, xaxis='off')
    util.add_legend(ax, [l1[0], l2[0], l3[0]])
    ax.set_title('')
    ax.set_xlabel('')
    ax.set_ylabel('$I_{ASPOC}$\n($\mu A$)')

    # Flag
    ax = axes1[7, 0]
    flag.plot(ax=ax)
    util.format_axes(ax)
    ax.set_title('')
    ax.set_xlabel('')
    ax.set_ylabel('Flag')

    #
    # Plot: Photocurrent Fit
    #

    # Plot the data
    fig2, axes = plt.subplots(nrows=3,
                              ncols=1,
                              figsize=[5, 5.5],
                              squeeze=False)
    plt.subplots_adjust(left=0.15, right=0.95, top=0.94)

    # I_ph = I_ph0 exp(Vsc/Vph0)
    ax = axes[0, 0]
    ax.scatter(Vsc[flag == 0], Ie[flag == 0], marker='o')
    ax.scatter(Vsc[np.bitwise_and(flag, 2**0) > 0],
               Ie[np.bitwise_and(flag, 2**0) > 0],
               marker='o',
               color='red')
    ax.scatter(Vsc[np.bitwise_and(flag, 2**1) > 0],
               Ie[np.bitwise_and(flag, 2**1) > 0],
               marker='o',
               color='purple')
    ax.scatter(Vsc[np.bitwise_and(flag, 2**2) > 0],
               Ie[np.bitwise_and(flag, 2**2) > 0],
               marker='o',
               color='green')
    ax.plot(Vsc[flag == 0], Ie_fit, color='black')
    ax.set_title(
        'Photocurrent Parameters $I_{e} = -I_{ph0} \exp(V_{S/C}/V_{ph0})$')
    ax.set_xlabel('$V_{S/C}$ (V)')
    ax.set_ylabel('$I_{e}$\n($\mu A$)')
    ax.set_yscale('log')
    ax.set_ylim([
        10**np.floor(np.log10(Ie.min().values)),
        10**np.ceil(np.log10(Ie.max().values))
    ])
    ax.text(0.9 * ax.get_xlim()[1],
            0.7 * ax.get_ylim()[1],
            str_fit,
            horizontalalignment='right',
            verticalalignment='bottom',
            color='black')

    # Ne = \Sum a_i * V^i
    ax = axes[1, 0]
    ax.scatter(Vsc[flag == 0], des_moms['density'][flag == 0], marker='o')
    ax.scatter(Vsc[np.bitwise_and(flag, 2**0) > 0],
               des_moms['density'][np.bitwise_and(flag, 2**0) > 0],
               marker='o',
               color='red')
    ax.scatter(Vsc[np.bitwise_and(flag, 2**1) > 0],
               des_moms['density'][np.bitwise_and(flag, 2**1) > 0],
               marker='o',
               color='purple')
    ax.scatter(Vsc[np.bitwise_and(flag, 2**2) > 0],
               des_moms['density'][np.bitwise_and(flag, 2**2) > 0],
               marker='o',
               color='green')
    ax.plot(Vsc[flag == 0], Ne_fit2, color='black')
    ax.plot(Vsc[flag == 0], Ne_fit4, color='grey')
    ax.set_title('')
    ax.set_xlabel('$V_{S/C}$ (V)')
    ax.set_ylabel('$N_{e}$\n($cm^{-3}$)')
    ax.text(0.98 * ax.get_xlim()[1],
            0.85 * ax.get_ylim()[1],
            str_Ne_fit2,
            horizontalalignment='right',
            verticalalignment='bottom',
            color='black')
    ax.text(0.98 * ax.get_xlim()[1],
            0.75 * ax.get_ylim()[1],
            str_Ne_fit4,
            horizontalalignment='right',
            verticalalignment='bottom',
            color='grey')

    # Ne = \Sum a_i * V^-i
    ax = axes[2, 0]
    ax.scatter(1 / Vsc[flag == 0], des_moms['density'][flag == 0], marker='o')
    ax.scatter(1 / Vsc[np.bitwise_and(flag, 2**0) > 0],
               des_moms['density'][np.bitwise_and(flag, 2**0) > 0],
               marker='o',
               color='red')
    ax.scatter(1 / Vsc[np.bitwise_and(flag, 2**1) > 0],
               des_moms['density'][np.bitwise_and(flag, 2**1) > 0],
               marker='o',
               color='purple')
    ax.scatter(1 / Vsc[np.bitwise_and(flag, 2**2) > 0],
               des_moms['density'][np.bitwise_and(flag, 2**2) > 0],
               marker='o',
               color='green')
    ax.plot(Vsc[flag == 0], invV_fit2, color='black')
    ax.plot(Vsc[flag == 0], invV_fit4, color='grey')
    ax.set_title('')
    ax.set_xlabel('1/$V_{S/C}$ ($V^{-1}$)')
    ax.set_ylabel('$N_{e}$\n($cm^{-3}$)')
    ax.text(0.98 * ax.get_xlim()[1],
            0.85 * ax.get_ylim()[1],
            str_invV_fit2,
            horizontalalignment='right',
            verticalalignment='bottom',
            color='black')
    ax.text(0.98 * ax.get_xlim()[1],
            0.75 * ax.get_ylim()[1],
            str_invV_fit4,
            horizontalalignment='right',
            verticalalignment='bottom',
            color='grey')

    return [fig1, fig2], ax
Exemplo n.º 8
0
def load_sunpulse(sc='mms1',
                  start_date=None, end_date=None, rename_vars=True):
    """
    Load Digital Sun Sensor data.
    
    CDF variable names are renamed to something easier to remember and
    use. Original CDF variable names are kept as an attribute "cdf_name"
    in each individual variable.
    
    Parameters
    ----------
    sc : str
        Spacecraft ID: ('mms1', 'mms2', 'mms3', 'mms4')
    start_date, end_date : `datetime.datetime`
        Start and end of the data interval.
    rename_vars : bool
        If true (default), rename the standard MMS variable names
        to something more memorable and easier to use.
    
    Returns
    -------
    dist : `xarray.Dataset`
        EDI data.
    """
    instr = 'fields'
    mode = 'hk'
    level = 'l1b'
    optdesc = '101'
    
    sunsps_vname = '_'.join((sc, '101', 'sunssps'))
    sunper_vname = '_'.join((sc, '101', 'iifsunper'))
    sunpulse_vname = '_'.join((sc, '101', 'sunpulse'))
    sunpulse_uniq_vname = '_'.join((sc, '101', 'sunpulse', 'uniq'))
    
    # Load the data
    data = util.load_data(sc=sc, instr=instr, mode=mode, level=level,
                          optdesc=optdesc, start_date=start_date, 
                          end_date=end_date, team_site=True, data_type='hk',
                          variables=[sunsps_vname, sunper_vname,
                                     sunpulse_vname, sunpulse_uniq_vname])
    
    # Convert the sun pulse period to a timedelta64
    data[sunper_vname] = data[sunper_vname].astype('timedelta64[us]')
    
    # Select only the unique sun pulse times
    #  - Spin period is 20 sec
    #  - HK is reported once every 10 sec
    attrs = data.attrs
    pulse, idx = np.unique(data[sunpulse_vname], return_index=True, axis=0)
    data = data.isel(Epoch=idx)
    
    # Rename data variables to something simpler
    if rename_vars:
        data = rename(data, sc, optdesc)
    
    # Add data descriptors to attributes
    data.attrs['sc'] = sc
    data.attrs['instr'] = instr
    data.attrs['mode'] = mode
    data.attrs['level'] = level
    data.attrs['optdesc'] = optdesc
    
    return data