def load_CRRES_data(time_start, time_end, crres_path='G://DATA//CRRES//', nsec=None): ''' Since no moment data exists for CRRES, this loads only the cold electron density and magnetic field (with option to low-pass filter) and interpolates them to the same timebase (linear or cubic? Just do linear for now). If nsec is none, interpolates B to ne. Else, interpolates both to nsec. CRRES density cadence bounces between 8-9 seconds (terrible for FFT, alright for interp) den_dict params: ['VTCW', 'YRDOY', 'TIMESTRING', 'FCE_KHZ', 'FUHR_KHZ', 'FPE_KHZ', 'NE_CM3', 'ID', 'M'] TODO: Fix this. B_arr shape and nyq in mHz ''' # Load data times, B0, HM, dB, E0, HMe, dE, S, B, E = cfr.get_crres_fields(crres_path, time_start, time_end, pad=1800, E_ratio=5.0, rotation_method='vector', output_raw_B=True, interpolate_nan=None, B0_LP=1.0, Pc1_LP=5000, Pc1_HP=100, Pc5_LP=30, Pc5_HP=None, dEx_LP=None) den_times, den_dict = cfr.get_crres_density(crres_path, time_start, time_end, pad=600) edens = den_dict['NE_CM3'] # Interpolate B only if nsec is None: # Low-pass total field to avoid aliasing (Assume 8.5 second cadence) B_dt = 1.0 / 32.0 nyq = 1.0 / (2.0 * 8.5) for ii in range(3): B[:, ii] = ascr.clw_low_pass(B[:, ii].copy(), nyq, B_dt, filt_order=4) # Take magnitude and interpolate B_mag = np.sqrt(B[:, 0] ** 2 + B[:, 1] ** 2 + B[:, 2] ** 2) B_interp = np.interp(den_times.astype(np.int64), times.astype(np.int64), B_mag) return den_times, B_interp*1e-9, edens*1e6 else: # Define new time array ntime = np.arange(time_start, time_end, np.timedelta64(nsec, 's'), dtype='datetime64[us]') # Low-pass total field to avoid aliasing (Assume 8.5 second cadence) B_dt = 1.0 / 32.0 nyq = 1.0 / (2.0 * nsec) for ii in range(3): B[ii] = ascr.clw_low_pass(B[ii].copy(), nyq, B_dt, filt_order=4) # Take magnitude and interpolate B_mag = np.sqrt(B[0] ** 2 + B[1] ** 2 + B[2] ** 2) B_interp = np.interp(ntime.astype(np.int64), times.astype(np.int64), B_mag) # Also interpolate density ne_interp = np.interp(ntime.astype(np.int64), den_times.astype(np.int64), edens) return ntime, B_interp, ne_interp
def get_mag_data(time_start, time_end, probe, low_cut=None, high_cut=None): ''' Load and process data ''' ti, B0, HM_mags, pc1_mags, \ E0, HM_elec, pc1_elec, S, B, E = cfr.get_crres_fields(_crres_path, time_start, time_end, pad=600, output_raw_B=True, Pc5_LP=30.0, B0_LP=1.0, Pc5_HP=None, dEx_LP=None, interpolate_nan=True) dt = 1/32. # Bandpass selected component and return if low_cut is not None: dat = ascr.clw_high_pass(pc1_mags, low_cut*1000., dt, filt_order=4) if high_cut is not None: dat = ascr.clw_low_pass(pc1_mags, high_cut*1000., dt, filt_order=4) #pc1_res = 5.0 _xpow, _xtime, _xfreq = fscr.autopower_spectra(ti, pc1_mags[:, 0], time_start, time_end, dt, overlap=0.95, df=pc1_res, window_data=True) _ypow, _xtime, _xfreq = fscr.autopower_spectra(ti, pc1_mags[:, 1], time_start, time_end, dt, overlap=0.95, df=pc1_res, window_data=True) _zpow, _xtime, _xfreq = fscr.autopower_spectra(ti, pc1_mags[:, 2], time_start, time_end, dt, overlap=0.95, df=pc1_res, window_data=True) _pow = np.array([_xpow, _ypow, _zpow]) return ti, dat, HM_mags, dt, _xtime, _xfreq, _pow
def interpolate_B(new_time, b_time, b_array, dt, LP_filter=True): ''' To do: Add a LP filter. Or does interp already do that? ''' # Filter at Nyquist frequency to prevent aliasing if LP_filter == True: nyq = 1.0 / (2.0 * dt) for ii in range(3): b_array[:, ii] = ascr.clw_low_pass(b_array[:, ii].copy(), nyq, 1./64., filt_order=4) xp = b_time.astype(np.int64) yp = np.sqrt(b_array[:, 0] ** 2 + b_array[:, 1] ** 2 + b_array[:, 2] ** 2) xi = new_time.astype(np.int64) yi = np.interp(xi, xp, yp) return yi
def interpolate_B(new_time, b_time, b_array, dt, LP_filter=True): ''' Does second LP filter based on the Nyquist of the new sample rate Different to original filter, which is just to get rid of EMIC signal ''' # Filter at Nyquist frequency to prevent aliasing if LP_filter == True: nyq = 1.0 / (2.0 * dt) for ii in range(3): b_array[:, ii] = ascr.clw_low_pass(b_array[:, ii].copy(), nyq, 1./64., filt_order=4) xp = b_time.astype(np.int64) yp = np.sqrt(b_array[:, 0] ** 2 + b_array[:, 1] ** 2 + b_array[:, 2] ** 2) xi = new_time.astype(np.int64) yi = np.interp(xi, xp, yp) return yi
def load_and_interpolate_plasma_params(time_start, time_end, probe, nsec=None, rbsp_path='G://DATA//RBSP//', HM_filter_mhz=None, time_array=None, check_interp=False): ''' Same copy+paste as other versions, without the SPICE stuff ''' print('Loading and interpolating satellite data') # Ephemeris data # Load ephemeris data eph_params = ['L', 'CD_MLAT', 'CD_MLT'] eph_times, eph_dict = rfr.retrieve_RBSP_ephemeris_data(rbsp_path, probe, time_start, time_end, eph_params, padding=[60, 60]) # Cold (total?) electron plasma density den_times, edens, dens_err = rfr.retrieve_RBSP_electron_density_data( rbsp_path, time_start, time_end, probe, pad=30) # Magnetic magnitude mag_times, raw_mags = rfl.load_magnetic_field(rbsp_path, time_start, time_end, probe, return_raw=True, pad=3600) # Filter out EMIC waves (background plus HM) if HM_filter_mhz is not None: filt_mags = np.zeros(raw_mags.shape) for ii in range(3): filt_mags[:, ii] = ascr.clw_low_pass(raw_mags[:, ii], HM_filter_mhz, 1. / 64., filt_order=4) else: filt_mags = raw_mags # HOPE data itime, etime, pdict, perr = rfr.retrieve_RBSP_hope_moment_data(rbsp_path, time_start, time_end, padding=30, probe=probe) hope_dens = np.array( [pdict['Dens_p_30'], pdict['Dens_he_30'], pdict['Dens_o_30']]) hope_tperp = np.array( [pdict['Tperp_p_30'], pdict['Tperp_he_30'], pdict['Tperp_o_30']]) hope_tpar = np.array( [pdict['Tpar_p_30'], pdict['Tpar_he_30'], pdict['Tpar_o_30']]) hope_anis = np.array([ pdict['Tperp_Tpar_p_30'], pdict['Tperp_Tpar_he_30'], pdict['Tperp_Tpar_o_30'] ]) - 1. # Interpolation step if nsec is None: # This should let me set my own timebase by feeding in an array if time_array is None: time_array = den_times.copy() iedens = edens.copy() else: iedens = interpolate_ne(time_array, den_times, edens) else: time_array = np.arange(time_start, time_end, np.timedelta64(nsec, 's'), dtype='datetime64[us]') iedens = interpolate_ne(time_array, den_times, edens) ihope_dens, ihope_tpar, ihope_anis = HOPE_interpolate_to_time( time_array, itime, hope_dens, hope_tpar, hope_anis) ihope_dens, ihope_tperp, ihope_anis = HOPE_interpolate_to_time( time_array, itime, hope_dens, hope_tperp, hope_anis) Bi = interpolate_B(time_array, mag_times, filt_mags, nsec, LP_filter=False) iL = interpolate_ne(time_array, eph_times, eph_dict['L']) if check_interp: plt.ioff() # Cold dens + Magnetic field fig1, axes1 = plt.subplots(2) axes1[0].plot(den_times, edens, c='b') axes1[0].plot(time_array, iedens, c='r', lw=0.75) axes1[0].set_ylabel('$n_e$') B_total = np.sqrt(raw_mags[:, 0]**2 + raw_mags[:, 1]**2 + raw_mags[:, 2]**2) axes1[1].plot(mag_times, B_total, c='b') axes1[1].plot(time_array, Bi, c='r', lw=0.75) axes1[1].set_ylabel('B') for ax in axes1: ax.set_xlim(time_start, time_end) # HOPE parameters (dens, temp, anis) fig2, axes2 = plt.subplots(3) for xx, clr in zip(range(3), ['r', 'g', 'b']): axes2[0].plot(itime, hope_dens[xx], c=clr, ls='-') axes2[0].plot(time_array, ihope_dens[xx], c=clr, ls='--') axes2[0].set_ylabel('$n_i (cc)$') axes2[1].plot(itime, hope_tpar[xx], c=clr, ls='-') axes2[1].plot(time_array, ihope_tpar[xx], c=clr, ls='--') axes2[1].set_ylabel('$T_{\perp, i} (keV)$') axes2[2].plot(itime, hope_anis[xx], c=clr, ls='-') axes2[2].plot(time_array, ihope_anis[xx], c=clr, ls='--') axes2[2].set_ylabel('$A_i$') for ax in axes2: ax.set_xlim(time_start, time_end) plt.show() # Subtract energetic components from total electron density (assuming each is singly charged) cold_dens = iedens - ihope_dens.sum(axis=0) # Original DTs just for reference den_dt = (den_times[1] - den_times[0]) / np.timedelta64(1, 's') mag_dt = (mag_times[1] - mag_times[0]) / np.timedelta64(1, 's') hope_dt = (itime[1] - itime[0]) / np.timedelta64(1, 's') new_dt = (time_array[1] - time_array[0]) / np.timedelta64(1, 's') print('Original sample periods:') print(f'Cold Plasma Density: {den_dt} s') print(f'Magnetic field: {mag_dt} s ') print(f'HOPE Particle data: {hope_dt} s') print('') print(f'New sample period: {new_dt} s') return time_array, Bi * 1e-9, iedens * 1e6, cold_dens * 1e6, ihope_dens * 1e6, ihope_tpar, ihope_tperp, ihope_anis, iL
def load_and_interpolate_plasma_params(time_start, time_end, probe, pad, nsec=None, rbsp_path='G://DATA//RBSP//', HM_filter_mhz=None): ''' Outputs as SI units: B0 in T, densities in /m3, temperatures in eV (pseudo SI) nsec is cadence of interpolated array in seconds. If None, defaults to using den_times as interpolant. If HOPE or RBSPICE data does not exist, file retrieval returns NoneType - have to deal with that. ''' print('Loading and interpolating satellite data') # Cold (total?) electron plasma density den_times, edens, dens_err = rfr.retrieve_RBSP_electron_density_data( rbsp_path, time_start, time_end, probe, pad=pad) # Magnetic magnitude mag_times, raw_mags = rfl.load_magnetic_field(rbsp_path, time_start, time_end, probe, return_raw=True, pad=3600) # Filter out EMIC waves (background plus HM) if HM_filter_mhz is not None: filt_mags = np.zeros(raw_mags.shape) for ii in range(3): filt_mags[:, ii] = ascr.clw_low_pass(raw_mags[:, ii], HM_filter_mhz, 1. / 64., filt_order=4) else: filt_mags = raw_mags # HOPE data itime, etime, pdict, perr = rfr.retrieve_RBSP_hope_moment_data(rbsp_path, time_start, time_end, padding=pad, probe=probe) hope_dens = np.array( [pdict['Dens_p_30'], pdict['Dens_he_30'], pdict['Dens_o_30']]) hope_temp = np.array( [pdict['Tperp_p_30'], pdict['Tperp_he_30'], pdict['Tperp_o_30']]) hope_anis = np.array([ pdict['Tperp_Tpar_p_30'], pdict['Tperp_Tpar_he_30'], pdict['Tperp_Tpar_o_30'] ]) - 1 # SPICE data spice_dens = [] spice_temp = [] spice_anis = [] spice_times = [] for product, spec in zip(['TOFxEH', 'TOFxEHe', 'TOFxEO'], ['P', 'He', 'O']): spice_epoch, spice_dict = rfr.retrieve_RBSPICE_data(rbsp_path, time_start, time_end, product, padding=pad, probe=probe) # Collect all times (don't assume every file is good) spice_times.append(spice_epoch) if spice_dict is not None: this_dens = spice_dict['F{}DU_Density'.format(spec)] this_anis = spice_dict['F{}DU_PerpPressure'.format( spec)] / spice_dict['F{}DU_ParaPressure'.format(spec)] - 1 # Perp Temperature - Calculate as T = P/nk kB = 1.381e-23 q = 1.602e-19 t_perp_kelvin = 1e-9 * spice_dict['F{}DU_PerpPressure'.format( spec)] / (kB * 1e6 * spice_dict['F{}DU_Density'.format(spec)]) this_temp = kB * t_perp_kelvin / q # Convert from K to eV spice_dens.append(this_dens) spice_temp.append(this_temp) spice_anis.append(this_anis) else: spice_dens.append(None) spice_temp.append(None) spice_anis.append(None) # Interpolation step if nsec is None: time_array = den_times.copy() iedens = edens.copy() else: time_array = np.arange(time_start, time_end, np.timedelta64(nsec, 's'), dtype='datetime64[us]') iedens = interpolate_ne(time_array, den_times, edens) ihope_dens, ihope_temp, ihope_anis = HOPE_interpolate_to_time( time_array, itime, hope_dens, hope_temp, hope_anis) ispice_dens, ispice_temp, ispice_anis = SPICE_interpolate_to_time( time_array, spice_times, np.array(spice_dens), np.array(spice_temp), np.array(spice_anis)) Bi = interpolate_B(time_array, mag_times, filt_mags, nsec, LP_filter=False) # Subtract energetic components from total electron density (assuming each is singly charged) cold_dens = iedens - ihope_dens.sum(axis=0) - ispice_dens.sum(axis=0) return time_array, Bi * 1e-9, cold_dens * 1e6, ihope_dens * 1e6, ihope_temp, ihope_anis, ispice_dens * 1e6, ispice_temp, ispice_anis