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
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
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
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
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
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
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
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