Ejemplo n.º 1
0
def define_omura2010_parameters(include_energetic=False):
    '''
    Ambient plasma parameters from Omura et al. (2010) to recreate plots
    '''
    # Parameters in SI units (Note: Added the hot bit here. Is it going to break anything?) nh = 7.2
    pcyc = 3.7  # Hz
    B0 = 2 * np.pi * mp * pcyc / qp

    if include_energetic == True:
        Th_para = (mp * (6e5)**2 / kB) / 11603.
        Th_perp = (mp * (8e5)**2 / kB) / 11603.
        Ah = Th_perp / Th_para - 1
        #apar_h   = np.sqrt(2.0 * qp * Th_para  / mp)

        name = np.array(['H', 'He', 'O', 'Hot H'])
        mass = np.array([1.0, 4.0, 16.0, 1.0]) * mp
        charge = np.array([1.0, 1.0, 1.0, 1.0]) * qp
        density = np.array([136.8, 17.0, 17.0, 7.2]) * 1e6
        ani = np.array([0.0, 0.0, 0.0, Ah])
        tpar = np.array([0.0, 0.0, 0.0, Th_para])
        tper = (ani + 1) * tpar
    else:
        name = np.array(['H', 'He', 'O'])
        mass = np.array([1.0, 4.0, 16.0]) * mp
        charge = np.array([1.0, 1.0, 1.0]) * qp
        density = np.array([144.0, 17.0, 17.0]) * 1e6
        ani = np.array([0.0, 0.0, 0.0])
        tpar = np.array([0.0, 0.0, 0.0])
        tper = (ani + 1) * tpar

    Species, PP = create_species_array(B0, name, mass, charge, density, tper,
                                       ani)
    return Species, PP
Ejemplo n.º 2
0
def plot_shoji2012_2D():
    # Shoji et al. (2012) recreation of 2D plot
    #   --- Varies with normalized frequency (to pcyc) and ion density (plasma freq. proxy)
    #   --- Need to get Bth first, then NL growth rate calculated with Bw = Bth
    #   --- BTH ALMOST VALIDATED. Min growth region looked a little off, and weird nan's at bottom left.
    #       -- NOPE, H band completely different (way lower in higher density lower frequency section). Error?
    Nw = 500
    B0 = 243e-9  # T
    pcyc = 23.2  # rad/s
    #ecyc = 4.27e4   # rad/s

    Nr = 500
    wpe_wce_max = 17  # Ratio max

    # Frequency axis
    pcyc_min = 0.375
    pcyc_max = 1.0
    w_axis = np.linspace(pcyc_min, pcyc_max, Nw)
    w = w_axis * pcyc

    # Density axis
    wpe_wce = np.linspace(0.0, wpe_wce_max, Nr)
    ne = wpe_wce**2 * B0**2 * e0 / me

    # Energetic plasma parameters
    Q = 0.5
    Vth_para = 0.00800 * c
    Vth_perp = 0.01068 * c

    # Other parameters
    L = 4.0
    #Bw_init  = 0.5e-9

    # Cold plasma parameters
    name = np.array(['H', 'He', 'O'])
    mass = np.array([1.0, 4.0, 16.0]) * mp
    charge = np.array([1.0, 1.0, 1.0]) * qp
    tpar = np.array([0.0, 0.0, 0.0])
    ani = np.array([0.0, 0.0, 0.0])
    tper = (ani + 1) * tpar

    BTH = np.zeros((Nr, Nw), dtype=float)
    for MM in range(Nr):
        nh = 0.0081 * ne[MM]
        density = np.array([0.8019, 0.0950, 0.0950]) * ne[MM]
        Species, PP = create_species_array(B0, name, mass, charge, density,
                                           tper, ani)

        BTH[MM] = get_threshold_value_UNIO(w, Species, PP, nh, Vth_para,
                                           Vth_perp, Q, L)

    fig, ax = plt.subplots()

    im1 = ax.pcolormesh(w_axis, wpe_wce, BTH, cmap='jet', vmin=0.0, vmax=0.1)
    fig.colorbar(im1)

    #NL = nonlinear_growth_rate(_w, _Species, _PP, _nh, _Q, _Vth_para, _Vth_perp, _Bw_init)
    return
Ejemplo n.º 3
0
def plot_convective_growth_rate_fraser():
    '''
    TODO: Check this with Fraser (1989) parameters
    '''
    f_max = 3.5
    f_vals = np.linspace(0.0, f_max, 5000)
    w_vals = 2 * np.pi * f_vals

    mp = 1.673e-27  # Proton mass (kg)
    qi = 1.602e-19  # Elementary charge (C)
    _B0 = 300e-9  # Background magnetic field in T
    #A_style    = [':', '-', '--']                 # Line style for each anisotropy
    Ah = 1.5  # Anisotropy values

    _name = np.array(
        ['Cold H', 'Cold He', 'Cold O', 'Warm H', 'Warm He',
         'Warm O'])  # Species label
    _mass = np.array([1.0, 4.0, 16.0, 1.0, 4.0, 16.0
                      ]) * mp  # Mass   in proton masses (kg)
    _charge = np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0
                        ]) * qi  # Change in elementary units (C)
    _density = np.array([196.0, 22.0, 2.0, 5.1, 0.05, 0.13
                         ]) * 1e6  # Density in cm3 (/m3)
    _tper = np.array([0.0, 0.0, 0.0, 30.0, 10.0, 10.0
                      ]) * 1e3  # Parallel temperature in keV (eV)
    _ani = np.array([0.0, 0.0, 0.0, Ah, 1.0, 1.0])  # Temperature anisotropy

    Species, PP = create_species_array(_B0, _name, _mass, _charge, _density,
                                       _tper, _ani)

    temporal_GR, convective_GR, V_group, k_cold = linear_growth_rates_chen(
        w_vals, Species)

    fig, ax = plt.subplots(figsize=(16, 10))
    ax.set_title('Convective Growth Rate :: Fraser (1989) Comparison')

    ax.plot(f_vals, convective_GR * 1e7)
    ax.set_ylim(0, None)
    ax.set_ylabel('$S$\n$(m^{-1})$', rotation=0, fontsize=14, labelpad=30)

    ax.set_xlabel('f (Hz)', fontsize=14)
    ax.set_xlim(0, f_max)

    sb0, sb1 = get_stop_bands(k_cold)
    for st, en in zip(sb0, sb1):
        ax.axvspan(f_vals[st], f_vals[en], color='k', alpha=0.5, lw=0)

    plt.show()
    return
Ejemplo n.º 4
0
def get_linear_dispersion_from_sim(k, zero_cold=True, Nk=1000):
    '''
    Extracted values units :: 
        Density    -- /m3       (Cold, warm densities)
        Anisotropy -- Number
        Tper       -- eV
    '''
    print('Calculating linear dispersion relations...')
    from multiapprox_dispersion_solver import get_dispersion_relation, create_species_array

    # Extract species parameters from run, create Species array (Could simplify T calculation when I'm less lazy)
    anisotropy = cf.Tperp / cf.Tpar - 1

    t_perp = cf.Tperp.copy() / 11603.
    if zero_cold == True:
        for ii in range(t_perp.shape[0]):
            if cf.temp_type[ii] == 0:
                t_perp[ii] = 0.0
                anisotropy[ii] = 0.0

    Species, PP = create_species_array(cf.B_eq, cf.species_lbl, cf.mass,
                                       cf.charge, cf.density, t_perp,
                                       anisotropy)

    # Convert from linear units to angular units for k range to solve over
    kmin = 2 * np.pi * k[0]
    kmax = 2 * np.pi * k[-1]
    k_vals = np.linspace(kmin, kmax, Nk)

    # Calculate dispersion relations (3 approximations)
    CPDR_solns, cold_CGR = get_dispersion_relation(Species,
                                                   k_vals,
                                                   approx='cold')
    WPDR_solns, warm_CGR = get_dispersion_relation(Species,
                                                   k_vals,
                                                   approx='warm')
    HPDR_solns, hot_CGR = get_dispersion_relation(Species,
                                                  k_vals,
                                                  approx='hot')

    # Convert to linear frequency
    CPDR_solns /= 2 * np.pi
    WPDR_solns /= 2 * np.pi
    HPDR_solns /= 2 * np.pi

    return k_vals, CPDR_solns, WPDR_solns, HPDR_solns
Ejemplo n.º 5
0
def just_random():
    name = np.array(['H'])
    mass = np.array([1.0]) * mp
    charge = np.array([1.0]) * qp
    density = np.array([200.0]) * 1e6
    ani = np.array([0.0])
    tper = np.array([0.0])
    B0 = 200e-9

    Species, PP = create_species_array(B0, name, mass, charge, density, tper,
                                       ani)

    w = 0.3 * PP['pcyc_rad']

    k = get_k_cold(w, Species)
    print(k)
    return
Ejemplo n.º 6
0
def calculate_all_NL_amplitudes():
    # Import cutoff-derived composition information
    cutoff_filename = 'D://Google Drive//Uni//PhD 2017//Josh PhD Share Folder//Thesis//Data_Plots//20130725_RBSP-A//pearl_times.txt'
    cutoff_dict = epd.read_cutoff_file(cutoff_filename)

    #plot_amplitudes_from_data(_time_start, _time_end, probe=_probe, pad=600)
    time_start = _time_start
    time_end = _time_end
    probe = 'a'
    pad = 0

    plot_start = time_start - np.timedelta64(int(pad), 's')
    plot_end = time_end + np.timedelta64(int(pad), 's')

    time, mag, edens, cold_dens, hope_dens, hope_tpar, hope_tperp, hope_anis, L_vals =\
                                       load_and_interpolate_plasma_params(
                                       plot_start, plot_end, probe, nsec=None,
                                       rbsp_path='E://DATA//RBSP//', HM_filter_mhz=50.0,
                                       time_array=None, check_interp=False)

    mag_time, pc1_mags, HM_mags, imf_time, IA, IF, IP, stime, sfreq, spower = \
            load_EMIC_IMFs_and_dynspec(plot_start, plot_end)

    # Specify color values for time
    time0 = time[0].astype(np.int64)
    time1 = time[-1].astype(np.int64)
    norm = mpl.colors.LogNorm(vmin=time0, vmax=time1, clip=False)
    mapper = cm.ScalarMappable(norm=norm, cmap=cm.jet)

    lpad = 20
    fig, axes = plt.subplots(nrows=4,
                             ncols=2,
                             figsize=(8.27, 11.69),
                             gridspec_kw={
                                 'width_ratios': [1, 0.01],
                                 'height_ratios': [1, 1, 0.5, 2]
                             })

    # Spectra/IP
    im0 = axes[0, 0].pcolormesh(stime,
                                sfreq,
                                spower.sum(axis=0).T,
                                cmap='jet',
                                norm=colors.LogNorm(vmin=1e-4, vmax=1e1))
    axes[0, 0].set_ylim(0, fmax)
    axes[0, 0].set_ylabel('$f$\n(Hz)', rotation=0, labelpad=lpad, fontsize=12)
    fig.colorbar(im0, cax=axes[0, 1],
                 extend='both').set_label(r'$\frac{nT^2}{Hz}$',
                                          fontsize=16,
                                          rotation=0,
                                          labelpad=5)

    axes[0, 0].plot(imf_time, IF[0][:, 0], c='k', lw=0.75)
    axes[0, 0].plot(imf_time, IF[1][:, 0], c='k', lw=0.75, alpha=0.8)
    #axes[0, 0].plot(imf_time, IF[2][:, 0], c='k', lw=0.75, alpha=0.6)
    #axes[0, 0].axvline(this_time, color='white', ls='-' , alpha=0.7)
    axes[0, 0].set_xlim(plot_start, plot_end)
    axes[0, 0].set_xticklabels([])

    axes[0, 0].axhline(_band_start, color='white', ls='--')
    axes[0, 0].axhline(_band_end, color='white', ls='--')

    # mag_time, pc1_mags, IA, IF, IP, stime, sfreq, spower
    # Timeseries for comparison
    axes[1, 0].plot(mag_time, pc1_mags[:, 0], c='b', label='$\delta B_\\nu$')
    axes[1, 0].plot(mag_time,
                    pc1_mags[:, 1],
                    c='r',
                    label='$\delta B_\phi$',
                    alpha=0.5)
    #axes[1, 0].plot(mag_time, pc1_mags[:, 2], c='k', label='$\delta B_\mu$', alpha=0.25)
    axes[1, 0].set_ylabel('nT', rotation=0, labelpad=lpad)
    axes[1, 0].set_xlim(plot_start, plot_end)
    axes[1, 0].set_xlabel('Time [UT]')
    axes[1, 0].set_xlim(plot_start, plot_end)

    # CALCULATE PLASMA PARAMETERS AND AMPLITUDES FOR ALL TIMES
    # Plot all on same graph, use colorbar to discern time
    # Maybe do for cutoff times/packet times
    for ii in range(0, time.shape[0], 4):
        this_time = time[ii]
        clr = mapper.to_rgba(time[ii].astype(np.int64))
        print('Doing time:', this_time)

        # Get oxygen concentration from cutoffs
        cutoff = np.interp(this_time.astype(np.int64),
                           cutoff_dict['CUTOFF_TIME'].astype(np.int64),
                           cutoff_dict['CUTOFF_NORM'])
        o_frac = epd.calculate_o_from_he_and_cutoff(cutoff, he_frac)
        h_frac = 1. - he_frac - o_frac

        # Cold plasma params, SI units
        B0 = mag[ii]
        name = np.array(['H', 'He', 'O'])
        mass = np.array([1.0, 4.0, 16.0]) * PMASS
        charge = np.array([1.0, 1.0, 1.0]) * PCHARGE
        density = np.array([h_frac, he_frac, o_frac]) * edens[ii]
        ani = np.array([0.0, 0.0, 0.0])
        tpar = np.array([0.0, 0.0, 0.0])
        tper = (ani + 1) * tpar
        Species, PP = create_species_array(B0, name, mass, charge, density,
                                           tper, ani)

        # Frequencies to evaluate, calculate wavenumber (cold approximation)
        f_min = 0.07 * PP['pcyc_rad'] / (2 * np.pi)
        f_max = 0.24 * PP['pcyc_rad'] / (2 * np.pi)
        Nf = 10000
        f_vals = np.linspace(f_min, f_max, Nf)
        w_vals = 2 * np.pi * f_vals
        k_vals = nls.get_k_cold(w_vals, Species)

        # Define hot proton parameters (velocities normalized c)
        # Remember: temperatures originally in eV
        nh = hope_dens[0][ii]
        wph2 = nh * PCHARGE**2 / (PMASS * EPS0)
        Vth_para = np.sqrt(KB * hope_tpar[0][ii] *
                           (PCHARGE / KB) / PMASS) / SPLIGHT
        Vth_perp = np.sqrt(KB * hope_tperp[0][ii] *
                           (PCHARGE / KB) / PMASS) / SPLIGHT
        Q = 0.5

        # Curvature parameters (this has the most wiggle room)
        L = 4.7  #L_vals[ii]
        a = 4.5 / (L * RE)**2
        a = a * (SPLIGHT**2 / PP['pcyc_rad']**2)

        Vg, Vp, Vr = nls.get_velocities(w_vals, Species, PP, normalize=True)
        s0, s1, s2 = nls.get_inhomogeneity_terms(w_vals,
                                                 Species,
                                                 PP,
                                                 Vth_perp,
                                                 normalize_vel=True)

        # Normalize input parameters
        wph = np.sqrt(wph2) / PP['pcyc_rad']
        w = w_vals / PP['pcyc_rad']

        # DO THE ACTUAL CALCULATION (All hands off from here, using existing code/proforma)
        tau = 1.00
        B_th = nls.get_threshold_amplitude(w, wph, Q, s2, a, Vp, Vr, Vth_para,
                                           Vth_perp)
        B_opt = nls.get_optimum_amplitude(w, wph, Q, tau, s0, s1, Vg, Vr,
                                          Vth_para, Vth_perp)
        T_tr = nls.get_nonlinear_trapping_period(k_vals, Vth_perp * SPLIGHT,
                                                 B_opt * PP['B0'])
        T_N = tau * T_tr * PP['pcyc_rad']

        # Filter zeros and infs:
        B_th[B_th == np.inf] = np.nan
        B_th[B_th == 0] = np.nan

        B_opt[B_opt == np.inf] = np.nan
        B_opt[B_opt == 0] = np.nan

        T_N[T_N == np.inf] = np.nan
        T_N[T_N == 0] = np.nan

        ################
        ### PLOTTING ###
        ################
        # Bth, Bopt, Inst. Amplitudes
        axes[3, 0].plot(f_vals,
                        B_th * B0 * 1e9,
                        c=clr,
                        ls='--',
                        label=r'$B_{th}$')
        axes[3, 0].plot(f_vals,
                        B_opt * B0 * 1e9,
                        c=clr,
                        ls='-',
                        label=r'$B_{opt}$')

    axes[3, 0].set_ylabel('$B$ [nT]', rotation=0, labelpad=20, fontsize=16)
    axes[3, 0].set_xlabel('$f$ [Hz]', fontsize=16)
    axes[3, 0].set_ylim(0, 17)
    axes[3, 0].set_xlim(f_vals[0], f_vals[-1])
    axes[3, 0].tick_params(top=True, right=True)
    add_custom_legend(axes[3, 0], [r'$B_{th}$', r'$B_{opt}$'], ['--', '-'],
                      [1.0, 1.0], ['k', 'k'])

    label_every = 15
    cbar = fig.colorbar(mapper,
                        cax=axes[3, 1],
                        label='Time',
                        orientation='vertical',
                        ticks=time[::label_every].astype(np.int64))
    for label in cbar.ax.get_yminorticklabels():
        label.set_visible(False)

    cbar.ax.set_yticklabels(time[::label_every].astype('datetime64[m]'))

    axes[1, 1].set_visible(False)
    axes[2, 0].set_visible(False)
    axes[2, 1].set_visible(False)
    axes[0, 0].xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S'))
    axes[1, 0].xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S'))

    fig.tight_layout()
    fig.subplots_adjust(wspace=0.05, hspace=0)
    fig.align_ylabels()

    plt.show()
    return
Ejemplo n.º 7
0
            cutoff = np.interp(parameter_time.astype(np.int64),
                               cutoff_dict['CUTOFF_TIME'].astype(np.int64),
                               cutoff_dict['CUTOFF_NORM'])
            o_frac = epd.calculate_o_from_he_and_cutoff(cutoff, he_frac)
            h_frac = 1. - he_frac - o_frac

            # Cold plasma params, SI units
            B0 = mag[time_idx]
            name = np.array(['H', 'He', 'O'])
            mass = np.array([1.0, 4.0, 16.0]) * PMASS
            charge = np.array([1.0, 1.0, 1.0]) * PCHARGE
            density = np.array([h_frac, he_frac, o_frac]) * edens[time_idx]
            ani = np.array([0.0, 0.0, 0.0])
            tpar = np.array([0.0, 0.0, 0.0])
            tper = (ani + 1) * tpar
            Species, PP = create_species_array(B0, name, mass, charge, density,
                                               tper, ani)

            # Frequencies to evaluate, calculate wavenumber (cold approximation)
            f_min = 0.07 * PP['pcyc_rad'] / (2 * np.pi)
            f_max = 0.24 * PP['pcyc_rad'] / (2 * np.pi)
            Nf = 10000
            f_vals = np.linspace(f_min, f_max, Nf)
            w_vals = 2 * np.pi * f_vals
            k_vals = nls.get_k_cold(w_vals, Species)

            # Define hot proton parameters (velocities normalized c) : vth = sqrt(kT/m)?
            # Remember: temperatures originally in eV
            nh = hope_dens[0][time_idx]
            wph2 = nh * PCHARGE**2 / (PMASS * EPS0)
            Vth_para = np.sqrt(KB * hope_tpar[0][time_idx] *
                               (PCHARGE / KB) / PMASS) / SPLIGHT
Ejemplo n.º 8
0
def plot_velocities_and_energies_single(time_start, time_end, probe='a'):
    # Import cutoff-derived composition information
    cutoff_dict = epd.read_cutoff_file(cutoff_filename)
        
    # Load particle and field information
    time, mag, edens = load_CRRES_data(time_start, time_end, nsec=None,
                                        crres_path='E://DATA//CRRES//')

    mag_time, pc1_mags, HM_mags, imf_time, IA, IF, IP, stime, sfreq, spower = \
            load_EMIC_IMFs_and_dynspec(time_start, time_end)
    spower = spower.sum(axis=0)

    cutoff  = np.interp(time.astype(np.int64),
                        cutoff_dict['CUTOFF_TIME'].astype(np.int64),
                        cutoff_dict['CUTOFF_NORM'])
    o_fracs = epd.calculate_o_from_he_and_cutoff(cutoff, he_frac)        
    
    # Get velocity/energy data for time
    plt.ioff()
    for ii in range(time.shape[0]):
        
        # Define time, time index
        this_time   = time[ii]
        maxpwr_tidx = np.where(abs(stime - this_time) == np.min(abs(stime - this_time)))[0][0]
        
        # Find max freq and index
        fst, fen     = ascr.boundary_idx64(sfreq, _band_start, _band_end)
        maxpwr_fidx  = spower[maxpwr_tidx, fst:fen].argmax()
        maxpwr_fidx += fst
        maxpwr_freq  = sfreq[maxpwr_fidx]
        
        #date_string = this_time.astype(object).strftime('%Y%m%d')
        save_string = this_time.astype(object).strftime('%Y%m%d_%H%M%S')
    
        #clr = mapper.to_rgba(time[ii].astype(np.int64))
        print('Doing time:', this_time)
        
        fig, axes = plt.subplots(nrows=4, ncols=2, figsize=(8.0, 0.5*11.00),
                                 gridspec_kw={'width_ratios':[1, 0.01],
                                              'height_ratios':[1, 2, 2, 2]
                                              })
        
        # Spectra/IP
        im0 = axes[0, 0].pcolormesh(stime, sfreq, spower.T, cmap='jet',
                             norm=colors.LogNorm(vmin=1e-4, vmax=1e1))
        axes[0, 0].set_ylim(0, _band_end)
        axes[0, 0].set_ylabel('$f$ [Hz]', rotation=90)
        fig.colorbar(im0, cax=axes[0, 1], extend='both').set_label(
                    r'$\frac{nT^2}{Hz}$', fontsize=16, rotation=0, labelpad=15)
        
        axes[0, 0].axvline(this_time, color='white', ls='-' , alpha=0.7)
        axes[0, 0].set_xlim(time_start, time_end)
        axes[0, 0].set_xticklabels([])
        
        axes[0, 0].axvline(this_time,   color='white', ls='-', alpha=0.75)
        axes[0, 0].axhline(maxpwr_freq, color='white', ls='-', alpha=0.75)
        axes[0, 0].set_title(f'Velocities and Energies :: {this_time}')

        h_frac = 1. - he_frac - o_fracs[ii]
        
        # Cold plasma params, SI units
        B0      = mag[ii]
        name    = np.array(['H'   , 'He'   , 'O'    ])
        mass    = np.array([1.0   , 4.0    , 16.0   ]) * PMASS
        charge  = np.array([1.0   , 1.0    , 1.0    ]) * PCHARGE
        density = np.array([h_frac, he_frac, o_fracs[ii] ]) * edens[ii]
        ani     = np.array([0.0   , 0.0    , 0.0    ])
        tpar    = np.array([0.0   , 0.0    , 0.0    ])
        tper    = (ani + 1) * tpar
        Species, PP = create_species_array(B0, name, mass, charge, density, tper, ani)
        
        # Frequencies to evaluate, calculate wavenumber (cold approximation)
        f_min  = _band_start
        f_max  = _band_end
        Nf     = 10000
        f_vals = np.linspace(f_min, f_max, Nf)
        w_vals = 2*np.pi*f_vals
        k_vals = nls.get_k_cold(w_vals, Species)
        wv_len = 1e-3 * 2*np.pi / k_vals
        
        fidx = np.where(abs(f_vals - maxpwr_freq) == np.min(abs(f_vals - maxpwr_freq)))[0][0] 
        freq = f_vals[fidx]
        
        axes[1, 0].plot(f_vals, wv_len, c='k')
        axes[1, 0].set_ylabel('$\lambda_{EMIC}$ [km]')
        axes[1, 0].set_ylim(0, 2000)
        
        # Velocities
        Vg, Vp, Vr = nls.get_velocities(w_vals, Species, PP)
    
        axes[2, 0].semilogy(f_vals, Vg*1e-3, c='k', label='$V_g$') 
        axes[2, 0].semilogy(f_vals, Vp*1e-3, c='r', label='$V_p$')
        axes[2, 0].semilogy(f_vals,-Vr*1e-3, c='b', label='$-V_R$')
        axes[2, 0].set_ylim(10, 4500)
        axes[2, 0].set_ylabel('Velocities [km/s]')
        axes[2, 0].legend(bbox_to_anchor=(1.0, 0), loc=3, borderaxespad=0.)
        
        # Energies
        ELAND, ECYCL = nls.get_energies(w_vals, k_vals, PP['pcyc_rad'], PMASS)
        axes[3, 0].semilogy(f_vals, ELAND*1e-3, c='r', label='$E_0$')
        axes[3, 0].semilogy(f_vals, ECYCL*1e-3, c='b', label='$E_1$')
        axes[3, 0].set_ylim(1e-1, 1e3)
        axes[3, 0].set_ylabel('$E_R$ [keV]')
        axes[3, 0].set_xlabel('Freq [Hz]', rotation=0)
        axes[3, 0].legend(bbox_to_anchor=(1.0, 0), loc=3, borderaxespad=0.)
        
        # Work out what the energy is at maxpwr_freq
        num_landau    = ELAND[fidx]*1e-3
        num_cyclotron = ECYCL[fidx]*1e-3
        
        axes[3, 0].text(0.8, 0.9, f'$E_0(f) =$ {num_landau:.1f} keV', horizontalalignment='left',
                        verticalalignment='center', transform=axes[3, 0].transAxes)
        axes[3, 0].text(0.8, 0.8, f'$E_1(f) =$ {num_cyclotron:.1f} keV', horizontalalignment='left',
                        verticalalignment='center', transform=axes[3, 0].transAxes)
        
        axes[0, 0].set_xticklabels([])
        axes[1, 0].set_yticks(np.array([0, 500, 1000, 1500]))
        for ax in axes[1:, 0]:
            ax.set_xlim(_band_start, _band_end)
            ax.axvline(freq, color='k', alpha=0.5, ls='--')
            if ax != axes[-1, 0]:
                ax.set_xticklabels([])
        
        axes[1, 1].set_visible(False)
        axes[2, 1].set_visible(False)
        axes[3, 1].set_visible(False)
        
        #fig.tight_layout(rect=[0, 0, 0.95, 1])
        fig.tight_layout()
        fig.subplots_adjust(wspace=0.05, hspace=0)
        fig.align_ylabels()
        
        if save_plot == True:
            print('Saving plot...')
            fig.savefig(_plot_path + 'VELENG_FROMDATA_' + save_string + '.png', dpi=dpi)
            plt.close('all')
        else:
            plt.show()
    return
def plot_HM_and_energy(time_start, time_end, probe):
    '''
    For a specific frequency, calculate what the first order cyclotron resonance
    energy is and plot this as a timeseries. Secondary plots for the Pc1 spectra
    and HM/|B| spectra
    
    Do for all frequencies and select specific frequency at end (or option to
    show as a pcolormesh)
    '''
    # Import cutoff-derived composition information
    cutoff_filename = 'D://Google Drive//Uni//PhD 2017//Josh PhD Share Folder//Thesis//Data_Plots//20130725_RBSP-A//pearl_times.txt'
    cutoff_dict = epd.read_cutoff_file(cutoff_filename)

    time, mag, edens, cold_dens, hope_dens, hope_tpar, hope_tperp, hope_anis, L_vals =\
                                       load_and_interpolate_plasma_params(
                                       time_start, time_end, probe, nsec=None,
                                       rbsp_path='E://DATA//RBSP//', HM_filter_mhz=50.0,
                                       time_array=None, check_interp=False)

    mag_time, pc1_mags, HM_mags, imf_time, IA, IF, IP, stime, sfreq, spower = \
            load_EMIC_IMFs_and_dynspec(time_start, time_end)

    # Frequencies to evaluate, calculate wavenumber (cold approximation)
    f_min = _band_start
    f_max = _band_end
    Nf = 10000
    f_vals = np.linspace(f_min, f_max, Nf)
    w_vals = 2 * np.pi * f_vals

    all_CR = np.zeros((time.shape[0], Nf), dtype=np.float64)
    all_LR = np.zeros((time.shape[0], Nf), dtype=np.float64)
    all_VP = np.zeros((time.shape[0], Nf), dtype=np.float64)
    all_VG = np.zeros((time.shape[0], Nf), dtype=np.float64)
    all_VR = np.zeros((time.shape[0], Nf), dtype=np.float64)

    # Collect info for each time
    for ii in range(time.shape[0]):
        this_time = time[ii]
        print('Doing time:', this_time)

        # Get oxygen concentration from cutoffs
        cutoff = np.interp(this_time.astype(np.int64),
                           cutoff_dict['CUTOFF_TIME'].astype(np.int64),
                           cutoff_dict['CUTOFF_NORM'])
        o_frac = epd.calculate_o_from_he_and_cutoff(cutoff, he_frac)
        h_frac = 1. - he_frac - o_frac

        # Cold plasma params, SI units
        B0 = mag[ii]
        name = np.array(['H', 'He', 'O'])
        mass = np.array([1.0, 4.0, 16.0]) * PMASS
        charge = np.array([1.0, 1.0, 1.0]) * PCHARGE
        density = np.array([h_frac, he_frac, o_frac]) * edens[ii]
        ani = np.array([0.0, 0.0, 0.0])
        tpar = np.array([0.0, 0.0, 0.0])
        tper = (ani + 1) * tpar
        Species, PP = create_species_array(B0, name, mass, charge, density,
                                           tper, ani)

        # Velocities and Energies
        k_vals = nls.get_k_cold(w_vals, Species)
        all_VG[ii], all_VP[ii], all_VR[ii] = nls.get_velocities(
            w_vals, Species, PP)
        all_LR[ii], all_CR[ii] = nls.get_energies(w_vals, k_vals,
                                                  PP['pcyc_rad'], PMASS)

    fig, axes = plt.subplots(nrows=5,
                             ncols=2,
                             figsize=(8.0, 1.0 * 11.00),
                             gridspec_kw={'width_ratios': [1, 0.01]})

    # To plot: Spectra, velocities (Vg, Vr) and energies (cyclotron, landau resonances)
    # HM/|B| overlay
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        axes[0, 0].set_title(f'Velocities and Energies :: {this_time}')

        # Spectra
        im0 = axes[0, 0].pcolormesh(stime,
                                    sfreq,
                                    spower.sum(axis=0).T,
                                    cmap='jet',
                                    norm=colors.LogNorm(vmin=1e-4, vmax=1e1))
        axes[0, 0].set_ylim(0, fmax)
        axes[0, 0].set_ylabel('$f$ [Hz]', rotation=90)
        fig.colorbar(im0, cax=axes[0, 1],
                     extend='both').set_label(r'$\frac{nT^2}{Hz}$',
                                              fontsize=14,
                                              rotation=0,
                                              labelpad=15)

        # E_RES_CYCLOTRON
        im1 = axes[1, 0].pcolormesh(time,
                                    f_vals,
                                    all_CR.T * 1e-3,
                                    cmap='jet',
                                    norm=colors.Normalize())
        axes[1, 0].set_ylabel('$f$ [Hz]', rotation=90)
        fig.colorbar(im1, cax=axes[1, 1],
                     extend='both').set_label('$E_R$ Cyclotron\n[keV]',
                                              fontsize=14,
                                              rotation=0,
                                              labelpad=15)

        # E_RES_LANDAU
        im2 = axes[2, 0].pcolormesh(time,
                                    f_vals,
                                    all_LR.T * 1e-3,
                                    cmap='jet',
                                    norm=colors.Normalize())
        axes[2, 0].set_ylabel('$f$ [Hz]', rotation=90)
        fig.colorbar(im2, cax=axes[2, 1],
                     extend='both').set_label('$E_R$ Landau\n[keV]',
                                              fontsize=14,
                                              rotation=0,
                                              labelpad=15)

        # VR
        im3 = axes[3, 0].pcolormesh(time,
                                    f_vals,
                                    all_VR.T * 1e-3,
                                    cmap='jet',
                                    norm=colors.Normalize())
        axes[3, 0].set_ylabel('$f$ [Hz]', rotation=90)
        fig.colorbar(im3, cax=axes[3, 1],
                     extend='both').set_label('$V_R$\n[$km/s$]',
                                              fontsize=14,
                                              rotation=0,
                                              labelpad=15)

        # VG
        im4 = axes[4, 0].pcolormesh(time,
                                    f_vals,
                                    all_VG.T * 1e-3,
                                    cmap='jet',
                                    norm=colors.Normalize())
        axes[4, 0].set_ylabel('$f$ [Hz]', rotation=90)
        fig.colorbar(im4, cax=axes[4, 1],
                     extend='both').set_label('$V_G$\n[$km/s$]',
                                              fontsize=14,
                                              rotation=0,
                                              labelpad=15)

        for ax in axes[:, 0]:
            ax.set_xlim(time_start, time_end)
            ax.set_ylim(_band_start, _band_end)

            ax2 = ax.twinx()
            ax2.plot(mag_time, HM_mags[:, 2], c='k', lw=0.75)

    fig.tight_layout()
    fig.subplots_adjust(wspace=0.05, hspace=0)
    fig.align_ylabels()

    if save_plot == True:
        save_string = time_start.astype(object).strftime('%Y%m%d_%H%M')

        print('Saving plot...')
        fig.savefig(_plot_path + 'VELENG_FROMDATA_PCOLOR_' + save_string +
                    '.png')
        plt.close('all')
    else:
        plt.show()
    return