def plot_Mf(save=True, ED_I=False):
    """
    Function that generates the plot of the LISA and Taiji monopole
    response functions.

    It corresponds to left panel of figure 15 of A. Roper Pol, S. Mandal,
    A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves
    from helical MHD turbulent sources," submitted to JCAP,
    https://arxiv.org/abs/2107.05356.

    Arguments:
        save -- option to save the figure in "plots/LISA_Taiji_response.pdf"
                (default True)
        ED_I -- option to plot the response function of cross-correlating
                channels E and D of the LISA-Taiji network (default False)
    """

    plt.figure(figsize=(12, 10))
    plt.rc('font', size=30)
    plt.plot(fs, MAs, color='black', label=r'${\cal M}_{\rm AA} (f)$')
    plt.plot(fs,
             MAs_Tai,
             color='black',
             ls='-.',
             label=r'${\cal M}_{\rm CC} (f)$')
    plt.plot(fs, MTs, color='blue', label=r'${\cal M}_{\rm TT} (f)$')
    plt.plot(fs,
             MTs_Tai,
             color='blue',
             ls='-.',
             label=r'${\cal M}_{\rm SS} (f)$')
    aaux = ''
    if ED_I == True:
        gg = np.where(abs(M_ED_I) > 1e-48)
        plt.plot(fs[gg], abs(M_ED_I[gg]), color='purple', alpha=.5)
        plt.text(3e-3, 6e-3, r'$|{\cal M}^I_{\rm ED}|$', color='purple')
        aaux = 'ED'
    Rf = inte.R_f(fs)
    L = 3e6 * u.km
    Rf_Tai = inte.R_f(fs, L=L)
    plt.plot(fs, Rf, color='black', ls='dashed', lw=.7)
    plt.plot(fs, Rf_Tai, color='black', ls='dashed', lw=.7)
    plt.text(5e-2, 7e-2, r'$\tilde {\cal R}^{\rm A, C}(f)$', fontsize=34)
    plt.xscale('log')
    plt.yscale('log')
    plt.xlim(1e-3, 1)
    plt.ylim(1e-7, 1e0)
    plt.legend(fontsize=28, frameon=False, loc='center left')
    plt.xlabel(r'$f$ [Hz]')
    plt.ylabel(r'${\cal M} (f)$')
    plot_sets.axes_lines()
    plt.yticks(np.logspace(-7, 0, 8))

    ax = plt.gca()
    ax.tick_params(axis='x', pad=20)
    ax.tick_params(axis='y', pad=10)

    if save:
        plt.savefig('plots/LISA_Taiji_response' + aaux + '.pdf',
                    bbox_inches='tight')
def plot_noise_PSD(interf='LISA', save=True):
    """
    Function that generates the plot of LISA (Taiji) noise PSD of the channel
    A (C) and compares with the optical metrology system P_oms and
    mass acceleration P_acc PSD noises.

    Arguments:
        interf -- selects interferometer (default 'LISA',
                  also available 'Taiji')
        save -- option to save the figure in "plots/noise_PSD_interf.pdf"
                (default True)
    """

    plt.figure(figsize=(12, 8))
    if interf == 'LISA':
        #plt.plot(fs, PnX, color='blue')
        plt.plot(fs, PnA, color='red')
        plt.plot(fs, Pacc, color='blue', ls='-.', lw=.8)
        plt.plot(fs, Poms, color='blue', ls='-.', lw=.8)
        yPn = 1e-40
        yPoms = 1e-40
        yPacc = 6e-43
        A = 'A'

    if interf == 'Taiji':
        #plt.plot(fs, PnX_Tai, color='blue')
        plt.plot(fs, PnC, color='red')
        plt.plot(fs, Pacc_Tai, color='blue', ls='-.', lw=.8)
        plt.plot(fs, Poms_Tai, color='blue', ls='-.', lw=.8)
        yPn = 2e-41
        yPoms = 2e-41
        yPacc = 4e-43
        A = 'C'

    plt.xlabel('$f$ [Hz]')
    plt.ylabel('noise PSD $(f)$')
    plt.xscale('log')
    plt.yscale('log')
    plt.ylim(1e-43, 1e-30)
    plt.xlim(1e-5, 1e0)
    plt.text(1e-1, yPoms, r'$P_{\rm oms} (f)$', color='blue')
    plt.text(1e-1, yPacc, r'$P_{\rm acc} (f)$', color='blue')
    plt.text(1e-2, yPn, r'$P_n^{\rm %s} (f)$' % A, color='red')
    plt.text(1e-1,
             1e-32,
             interf,
             fontsize=24,
             bbox=dict(facecolor='none',
                       edgecolor='black',
                       boxstyle='round,pad=.5'))
    plot_sets.axes_lines()

    if save:
        plt.savefig('plots/noise_PSD_' + interf + '.pdf', bbox_inches='tight')
Пример #3
0
def plot_PM_beltrami(save=True):
    """
    Function that plots the analytical relations between the GW polarization P
    and the source helicity PM (for magnetic) for the Beltrami field model,
    compared to the empirical fit obtained in the numerical simulations.

    It produces figure 14 (appendix A) of A. Roper Pol, S. Mandal,
    A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves
    from helical MHD turbulent sources," https://arxiv.org/abs/2107.05356.

    Arguments:
        save -- option to save the figure in plots/PM_beltrami.pdf'
                (default True)
    """

    plt.figure(figsize=(12, 8))

    sigma = np.linspace(0, 1, 100)
    Sh_sig = .5 + 2 * sigma**2 / (1 + sigma**2)**2
    Pm_sig = 2 * sigma / (1 + sigma**2)
    Sh_sig = .5 * (1 + Pm_sig**2)
    Ph_sig = Pm_sig / Sh_sig

    plt.plot(sigma,
             Pm_sig,
             ls='dotted',
             color='red',
             label=r'${\cal P}_{\rm M}$')
    plt.plot(sigma,
             Sh_sig,
             ls='-.',
             color='blue',
             label=r'$\left(1 + {\cal P}_{\rm M}^2\right)/2$')
    plt.plot(sigma,
             Ph_sig,
             color='black',
             lw=.8,
             label=r'$2 {\cal P}_{\rm M}/\left(1 + {\cal P}_{\rm M}^2\right)$')

    plot_sets.axes_lines()
    plt.xlim(0, 1)
    plt.ylim(0, 1.1)
    plt.legend(fontsize=28, loc='lower right', frameon=False)
    plt.xlabel('$\sigma$')
    plt.ylabel(r'$\cal P$')
    ax = plt.gca()
    ax.tick_params(axis='x', pad=20)
    plt.yticks(np.linspace(0, 1, 5))

    if save: plt.savefig('plots/PM_beltrami.pdf', bbox_inches='tight')
def plot_EGW_vs_kt(runs, rr='ini2', save=True, show=True):

    """
    Function that generates the plot of the compensated GW spectrum as a
    function of k(t - tini) for the smallest wave numbers of the run.

    It corresponds to figure 3 of A. Roper Pol, S. Mandal, A. Brandenburg,
    T. Kahniashvili, and A. Kosowsky, "Numerical simulations of gravitational
    waves from early-universe turbulence," Phys. Rev. D 102, 083512 (2020),
    https://arxiv.org/abs/1903.08585.

    Arguments:
        runs -- dictionary that includes the run variables
        rr -- string that selects which run to plot (default 'ini2')
        save -- option to save the resulting figure as
                plots/EGW_vs_kt.pdf (default True)
        show -- option to show the resulting figure (default True)
    """

    run = runs.get(rr)
    k = run.spectra.get('k')[1:]
    EGW = np.array(run.spectra.get('EGW')[:,1:], dtype='float')
    t = run.spectra.get('t_EGW')

    plt.figure(figsize=(10,6))
    plt.xscale('log')
    plt.yscale('log')
    plt.xlim(1e-2, 40)
    plt.ylim(8e-8, 1e-5)
    plt.xlabel('$k (t - 1)$')
    plt.ylabel(r'$\left[k_* \Omega_{\rm GW} (k, t)/k\right]^{1/2}$')
    plot_sets.axes_lines()

    # plot for initial wave numbers
    plt.plot(k[0]*(t - 1), np.sqrt(EGW[:, 0]*run.kf),
             color='black', lw=.8, #label='$k = %.0f$'%k[0])
             label='$k = 100$')
    plt.plot(k[1]*(t - 1), np.sqrt(EGW[:, 1]*run.kf),
             color='red', ls='-.', lw=.8, #label='$k = %.0f$'%k[1])
             label='$k = 200$')
    plt.plot(k[2]*(t - 1), np.sqrt(EGW[:, 2]*run.kf),
             color='blue', ls='dashed', lw=.8, #label='$k = %.0f$'%k[2])
             label='$k = 300$')
    plt.plot(k[3]*(t - 1), np.sqrt(EGW[:, 3]*run.kf),
             color='green', ls='dotted', lw=.8, #label='$k = %.0f$'%k[3])
             label='$k = 400$')
    plt.legend(fontsize=22, loc='lower right', frameon=False)

    if save: plt.savefig('plots/EGW_vs_kt.pdf', bbox_inches='tight')
    if not show: plt.close()
def plot_Xi_sensitivity_comb(save=True):
    """
    Function that generates the plot of the GW energy density
    polarization sensitivity obtained by combining the cross-correlated
    channels of the LISA-Taiji network.

    Arguments:
        save -- option to save the figure in "plots/Xi_LISA_Taiji_comb.pdf"
                (default True)
    """

    plt.figure(figsize=(12, 8))
    #plt.rc('font', size=18)
    plt.plot(fs,
             XiSAC,
             color='black',
             lw=.8,
             label=r'$h_0^2\, \Xi_{\rm s}^{AC} (f)$')
    plt.plot(fs,
             XiSAD,
             color='blue',
             ls='dotted',
             label=r'$h_0^2\, \Xi_{\rm s}^{AD} (f)$')
    plt.plot(fs,
             XiSEC,
             color='red',
             ls='-.',
             label=r'$h_0^2\, \Xi_{\rm s}^{EC} (f)$')
    plt.plot(fs,
             XiSED,
             color='green',
             ls='--',
             lw=.6,
             label=r'$h_0^2\, \Xi_{\rm s}^{ED} (f)$')
    plt.plot(fs,
             XiS_comb,
             color='blue',
             label=r'$h_0^2\, \Xi_{\rm s}^{\rm comb} (f)$')

    plt.legend(fontsize=20, loc='lower right', frameon=False)
    plt.xlabel(r'$f$ [Hz]')
    plt.ylabel(r'$h_0^2\, \Xi_{\rm s} (f)$')
    plt.xscale('log')
    plt.yscale('log')
    plt.ylim(1e-12, 1e-4)
    plt.xlim(1e-4, 1e-1)
    plot_sets.axes_lines()

    if save: plt.savefig('plots/Xi_LISA_Taiji_comb.pdf', bbox_inches='tight')
def plot_Df(save=True):
    """
    Function that generates the plot of the LISA and Taiji dipole
    response functions.

    It corresponds to right panel of figure 15 of A. Roper Pol, S. Mandal,
    A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves
    from helical MHD turbulent sources," submitted to JCAP,
    https://arxiv.org/abs/2107.05356.

    Arguments:
        save -- option to save the figure in "plots/DEA_LISA_Taiji.pdf"
                (default True)
    """

    fig, ax0 = plt.subplots(figsize=(12, 10))
    # plt.rc('font', size=30)
    DAE_posneg(fs, DAEs)
    DAE_posneg(fs, DAEs_Tai, ls='-.')
    plt.xlim(1e-3, 1)
    plt.ylim(1e-7, 1)
    plt.xlabel(r'$f$ [Hz]')
    plt.ylabel(r'${\cal D}(f)$')
    plt.xscale('log')
    plt.yscale('log')
    plot_sets.axes_lines()
    plt.text(4.7e-2, 2e-2, r'${\cal D}_{AE}(f)$', fontsize=30)
    plt.text(1.3e-2, 7e-3, r'${\cal D}_{CD}(f)$', fontsize=30)
    #plt.text(2.1e-2, 3e-3, r'${\cal D}_{CD}(f)$', fontsize=20)

    line_pos, = ax0.plot([], [], color='blue', lw=.7, label=r'positive values')
    line_neg, = ax0.plot([], [], color='red', lw=.7, label=r'negative values')
    handles = [line_pos, line_neg]
    lgd = ax0.legend(handles=handles,
                     loc='lower left',
                     fontsize=34,
                     frameon=False)

    ax = plt.gca()
    ax.tick_params(axis='x', pad=20)
    ax.tick_params(axis='y', pad=10)

    plt.yticks(np.logspace(-7, 0, 8))

    if save: plt.savefig('plots/DEA_LISA_Taiji.pdf', bbox_inches='tight')
def plot_sensitivity(save=True):
    """
    Function that generates the plot of LISA and Taiji strain sensitivities.

    Arguments:
        save -- option to save the figure in "plots/sensitivity_LISA_Taiji.pdf"
                (default True)
    """

    plt.figure(figsize=(12, 8))
    plt.rc('font', size=20)
    plt.plot(fs, np.sqrt(SnX), color='red', label='channel X')
    plt.plot(fs, np.sqrt(SnA), color='blue', label='TDI channel A')
    plt.plot(fs, np.sqrt(SnT), color='orange', label='TDI channel T', alpha=.6)

    plt.plot(fs, np.sqrt(SnX_Tai), color='red', ls='-.')
    plt.plot(fs, np.sqrt(SnC), color='blue', ls='-.')
    plt.plot(fs, np.sqrt(SnS), color='orange', ls='-.', alpha=.6)
    gg = np.where(abs(M_ED_I) > 1e-48)
    plt.plot(fs[gg],
             np.sqrt(Sn_ED_I[gg]),
             color='purple',
             alpha=.5,
             label='TDI channels ED')

    plt.legend(fontsize=20)
    plt.xlabel('$f$ [Hz]')
    plt.ylabel(r'Strain sensitivity $\left[{\rm Hz}^{-1/2}\right]$')
    plt.xscale('log')
    plt.yscale('log')
    plt.text(1e-1, 3e-19, 'LISA', fontsize=20)
    plt.text(1e-1, 8e-21, 'Taiji', fontsize=20)
    plt.ylim(1e-21, 1e-12)
    plt.xlim(1e-5, 1e0)
    plot_sets.axes_lines()
    ax = plt.gca()
    ytics = 10**np.array(np.linspace(-21, -12, 10))
    ax.set_yticks(ytics)

    if save:
        plt.savefig('plots/sensitivity_LISA_Taiji.pdf', bbox_inches='tight')
def plot_OmMK_OmGW_vs_t(runs, save=True, show=True):

    """
    Function that generates the plots of the total magnetic/kinetic energy
    density as a function of time ('OmM_vs_t.pdf') and the GW energy density
    as a function of time ('OmGW_vs_t.pdf').

    It corresponds to figure 5 of A. Roper Pol, S. Mandal, A. Brandenburg,
    T. Kahniashvili, and A. Kosowsky, "Numerical simulations of gravitational
    waves from early-universe turbulence," Phys. Rev. D 102, 083512 (2020),
    https://arxiv.org/abs/1903.08585.

    Arguments:
        runs -- dictionary that includes the run variables
        save -- option to save the resulting figure as
                plots/OmGW_vs_t.pdf (default True)
        show -- option to show the resulting figure (default True)
    """

    # chose the runs to be shown
    rrs = ['ini1', 'ini2', 'ini3', 'hel1', 'hel2', 'ac1']
    # chose the colors of each run
    col = ['black', 'red', 'blue', 'red', 'blue', 'black']
    # chose the line style for the plots
    ls = ['solid']*6
    ls[3] = 'dashed'
    ls[4] = 'dashed'
    ls[5] = 'dashed'

    plt.figure(1, figsize=(10,6))
    plt.figure(2, figsize=(10,6))

    j = 0
    for i in rrs:
        run = runs.get(i)
        k = run.spectra.get('k')[1:]
        GWs_stat_sp = run.spectra.get('GWs_stat_sp')
        t = run.ts.get('t')[1:]
        indst = np.argsort(t)
        t = t[indst]
        EEGW = run.ts.get('EEGW')[1:][indst]
        if run.turb == 'm': EEM = run.ts.get('EEM')[1:][indst]
        if run.turb == 'k': EEM = run.ts.get('EEK')[1:][indst]

        plt.figure(1)
        plt.plot(t, EEGW, color=col[j], lw=.8, ls=ls[j])
        # text with run name
        if i=='ini1': plt.text(1.02, 5e-8, i, color=col[j])
        if i=='ini2': plt.text(1.07, 5e-11, i, color=col[j])
        if i=='ini3': plt.text(1.2, 6e-9, i, color=col[j])
        if i=='hel1': plt.text(1.15, 2e-9, i, color=col[j])
        if i=='hel2': plt.text(1.12, 7e-10, i, color=col[j])
        if i=='ac1': plt.text(1.2, 1e-7, i, color=col[j])

        plt.figure(2)
        plt.plot(t, EEM, color=col[j], lw=.8, ls=ls[j])
        # text with run name
        if i=='ini1': plt.text(1.01, 8e-2, i, color=col[j])
        if i=='ini2': plt.text(1.12, 3e-3, i, color=col[j])
        if i=='ini3': plt.text(1.01, 9e-3, i, color=col[j])
        if i=='hel1': plt.text(1.15, 1.3e-2, i, color=col[j])
        if i=='hel2': plt.text(1.02, 1e-3, i, color=col[j])
        if i=='ac1': plt.text(1.17, 1.5e-3, i, color=col[j])

        j += 1

    plt.figure(1)
    plt.yscale('log')
    plt.xlabel('$t$')
    plt.xlim(1, 1.25)
    plt.ylim(2e-11, 2e-7)
    plt.ylabel(r'$\Omega_{\rm GW}$')
    plot_sets.axes_lines()

    if save: plt.savefig('plots/OmGW_vs_t.pdf', bbox_inches='tight')
    if not show: plt.close()

    plt.figure(2)
    plt.yscale('log')
    plt.xlim(1, 1.25)
    plt.ylim(5e-4, 2e-1)
    plt.xlabel('$t$')
    plt.ylabel(r'$\Omega_{\rm M, K}$')
    plot_sets.axes_lines()

    if save: plt.savefig('plots/OmM_vs_t.pdf', bbox_inches='tight')
    if not show: plt.close()
Пример #9
0
def plot_PGW_vs_PM(runs, save=True):
    """
    Function that generates the plot of the total GW polarization PGW as a
    function of the total fractional helicity of the sourcing magnetic PM or
    velocity PK field.

    It corresponds to figure 6 of A. Roper Pol, S. Mandal, A. Brandenburg,
    and T. Kahniashvili, "Polarization of gravitational waves from helical MHD
    turbulent sources," https://arxiv.org/abs/2107.05356.

    Arguments:
        runs -- dictionary that includes the run variables
        save -- option to save the figure in plots/PGW_vs_PM.pdf'
                (default True)
    """

    plt.figure(figsize=(12, 8))

    for i in runs:
        run = runs.get(i)
        k = run.spectra.get('k')
        EGW = run.spectra.get('EGW_stat_sp')
        HGW = run.spectra.get('helEGW_stat_sp')
        t = run.spectra.get('t_mag')
        indt = 0
        EM = run.spectra.get('mag')[indt, :]
        HM = run.spectra.get('helmag_comp')[indt, :]
        PM = np.trapz(HM, k) / np.trapz(EM, k)
        PGW = np.trapz(HGW, k[1:]) / np.trapz(EGW, k[1:])
        if 'i' in i: plt.plot(abs(PM), abs(PGW), 'o', color='blue')
        else: plt.plot(abs(PM), abs(PGW), 'x', color='red')
        col = assign_col(i)
        if col == 'black': sig = 0
        if col == 'green': sig = 0.1
        if col == 'darkgreen': sig = 0.3
        if col == 'orange': sig = 0.5
        if col == 'darkorange': sig = 0.7
        if col == 'red' or col == 'blue': sig = 1.
        if col == 'blue': col = 'red'
        eps = 2 * sig / (1 + sig**2)
        plt.vlines(eps,
                   0,
                   2 * eps / (1 + eps**2),
                   color=col,
                   ls='dashed',
                   lw=0.5)

    plot_sets.axes_lines()
    plt.xlim(0, 1.05)
    plt.ylim(0, 1.1)
    plt.xlabel(r'$|{\cal P}_{\rm M}|$')
    plt.ylabel(r'$|{\cal P}_{\rm GW}|$')
    xx = np.linspace(0, 1.1)
    plt.plot(xx, xx, lw=.5, ls='dashed', color='black')
    plt.plot(xx, 2 * xx / (1 + xx**2), lw=.5, ls='dashed', color='black')
    plt.text(.06, .75, r'${\cal P}_{\rm GW}=2 {\cal P}_{\rm M}' + \
                            r'/\bigl(1 + {\cal P}_{\rm M}^2\bigr)$',
             fontsize=24, bbox=dict(facecolor='white', edgecolor='black',
                                    boxstyle='round,pad=.2'))
    plt.text(.3, .2, r'${\cal P}_{\rm GW}={\cal P}_{\rm M} = 2' + \
                            r'\sigma_{\rm M}/\bigl(1 + \sigma_{\rm M}^2\bigr)$',
             fontsize=24, bbox=dict(facecolor='white', edgecolor='black',
                                    boxstyle='round,pad=.2'))
    #plt.legend(fontsize=14)
    line_ini, = plt.plot([], [], 'o', color='blue', label='initial')
    line_forc, = plt.plot([], [], 'x', color='red', label='forcing (short)')
    hdls = [
        line_ini,
        line_forc,
    ]
    plt.legend(handles=hdls, fontsize=24, loc='upper left', frameon=False)
    ax = plt.gca()
    ax.tick_params(axis='x', pad=20)
    ax.tick_params(axis='y', pad=10)

    if save: plt.savefig('plots/PGW_vs_PM.pdf', bbox_inches='tight')
Пример #10
0
def plot_PGW(runs, PPh='GW', type='ini', save=True):
    """
    Function that plots the GW polarization spectra, averaging over
    times after the GW energy and helicity have entered stationary oscillatory
    stages (this needs to be previously computed and stored in the run variable,
    see initialize_JCAP_2021.py).

    It corresponds to figure 5 of A. Roper Pol, S. Mandal, A. Brandenburg,
    and T. Kahniashvili, "Polarization of gravitational waves from helical MHD
    turbulent sources," https://arxiv.org/abs/2107.05356.

    Arguments:
        runs -- dictionary of variables run with spectral information
        type -- selects the types of runs to be plotted (default 'ini', other
                option is 'forc'), i.e., runs with an initial magnetic field
                ('ini') or runs in which the magnetic field is initially driven
                during the simulation ('forc')
        save -- option to save the figure in plots/PGW_'type'_sigma.pdf'
                (default True)
    """

    plt.rcParams.update({
        'xtick.labelsize': 'xx-large',
        'ytick.labelsize': 'xx-large',
        'axes.labelsize': 'xx-large'
    })

    if type == 'ini': RR = ['i_s01', 'i_s03', 'i_s05', 'i_s07', 'i_s1']
    elif type == 'forc':
        RR = ['f_s001', 'f_s001_neg', 'f_s03', 'f_s05', 'f_s07', 'f_s1_neg']
    elif type == 'kin':
        RR = ['K0', 'K01_c', 'K03', 'K05', 'K1']
    elif type == 'mag':
        RR = ['M0', 'M01_c', 'M03', 'M05', 'M1']
    if PPh == 'GW': PP = 'GW'
    if PPh == 'h': PP = 'h'

    fig, ax = plt.subplots(figsize=(12, 10))

    for i in RR:
        # select colors
        col = assign_col(i)
        run = runs.get(i)
        k = run.spectra.get('k')[1:]
        PGW = run.spectra.get('P' + PP + '_stat_sp')
        PGW_min = run.spectra.get('P' + PP + '_min_sp')
        PGW_max = run.spectra.get('P' + PP + '_max_sp')
        plt.plot(k, PGW, color=col, lw=2)
        plt.fill_between(k, PGW_min, PGW_max, alpha=0.3, color=col)
        for i in range(0, len(k)):
            plt.vlines(k[i],
                       PGW_min[i],
                       PGW_max[i],
                       color=col,
                       lw=0.6,
                       ls='dashed')

    plot_sets.axes_lines()
    plt.xscale('log')
    plt.xlabel('$k$')
    plt.ylabel(r'${\cal P}_{\rm %s} (k)$' % PP)

    sigs = []
    plt.xlim(120, 5e4)
    tp = 'forc'
    if type == 'forc':
        sigs = ['0.01', '-0.01', '0.3', '0.5', '0.7', '-1']
        cols = ['black', 'black', 'darkgreen', 'orange', 'darkorange', 'blue']
        plt.ylim(-1.15, 1.15)
        plt.yticks(np.linspace(-1, 1, 9))
        if PPh == 'GW':
            xxs = [7e2, 7e2, 7e2, 8e3, 2.5e3, 7e2]
            yys = [.2, -.25, .4, .55, .9, -.9, -.9]
            plt.text(3e4, -0.9, '(b)', fontsize=30)
        else:
            xxs = [5e2, 5e2, 5e2, 4e3, 3e3, 5e2]
            yys = [.25, -.25, .5, .5, .7, -.8]
            plt.text(3e4, -0.9, '(d)', fontsize=30)
    else:
        if type == 'ini':
            tp = 'ini'
            sigs = ['0.1', '0.3', '0.5', '0.7', '1']
            cols = ['green', 'darkgreen', 'orange', 'darkorange', 'red']
            if PPh == 'GW':
                xxs = [1e4, 1e4, 1e4, 1e4, 1e3]
                yys = [.3, .5, .75, 1.05, 1.05]
                plt.text(3e4, -0.35, '(a)', fontsize=30)
            else:
                xxs = [1.5e4, 1.5e4, 1.5e4, 1.5e4, 1e3]
                yys = [0.05, 0.35, 0.62, 1.05, 1.05]
                plt.text(3e4, -0.35, '(c)', fontsize=30)
        else:
            line_s0, line_s001, line_s01, line_s03, line_s05, line_s07, \
                    line_s1, line_s1_neg, = get_lines_sig(tp)
            hdls = [
                line_s1,
                line_s05,
                line_s03,
                line_s01,
                line_s0,
            ]
            plt.legend(handles=hdls,
                       fontsize=24,
                       loc='upper right',
                       frameon=False)
            plt.xlim(120, 3e4)
        plt.ylim(-.5, 1.2)

    for i in range(0, len(sigs)):
        plt.text(xxs[i],
                 yys[i],
                 r'$\sigma_{\rm M}^{\rm %s}=%s$' % (tp, sigs[i]),
                 fontsize=30,
                 color=cols[i])

    if save:
        plt.savefig('plots/P' + PPh + '_' + type + '_sigma.pdf',
                    bbox_inches='tight')
Пример #11
0
def plot_helicity_vs_t(runs, type='ini', save=True):
    """
    Function that generates the plot of the total magnetic or kinetic helicity
    as a function of time.

    It corresponds to figure 4 of A. Roper Pol, S. Mandal, A. Brandenburg,
    and T. Kahniashvili, "Polarization of gravitational waves from helical MHD
    turbulent sources," https://arxiv.org/abs/2107.05356.

    Arguments:
        runs -- dictionary that includes the run variables
        type -- selects the types of runs to be plotted (default 'ini', other
                option is 'forc'), i.e., runs with an initial magnetic field
                ('ini') or runs in which the magnetic field is initially driven
                during the simulation ('forc')
        save -- option to save the figure in plots/sigmaM_vs_t_'type'.pdf'
                (default True)
    """

    if type == 'ini': RR = ['i_s01', 'i_s03', 'i_s05', 'i_s07', 'i_s1']
    elif type == 'forc':
        RR = ['f_s001', 'f_s001_neg', 'f_s03', 'f_s05', 'f_s07', 'f_s1_neg']
    elif type == 'kin':
        RR = ['K0', 'K01_c', 'K03', 'K05', 'K1']
    elif type == 'mag':
        RR = ['M0', 'M01_c', 'M03', 'M05', 'M1']

    plt.figure(figsize=(12, 8))

    for i in RR:
        run = runs.get(i)
        col = assign_col(i)
        if run.turb == 'm': sp = 'mag'
        if run.turb == 'k': sp = 'kin'
        t = np.array(run.spectra.get('t_hel' + sp), dtype='float')[:, 0]
        t2 = run.spectra.get('t_' + sp)
        EM = np.array(run.spectra.get(sp), dtype='float')
        HkM = run.spectra.get('hel' + sp + '_comp')
        k = run.spectra.get('k')
        EMs_mean = np.trapz(EM, k, axis=1)
        HMs_mean = np.trapz(HkM, k, axis=1)
        EMs_mean = np.interp(t, t2, EMs_mean)
        eps = abs(HMs_mean) / EMs_mean
        plt.plot(t - 1, eps, '.', color=col)
        if col == 'black': sig = 0
        if col == 'green': sig = 0.1
        if col == 'darkgreen': sig = 0.3
        if col == 'orange': sig = 0.5
        if col == 'darkorange': sig = 0.7
        if col == 'red' or col == 'blue': sig = 1.
        eps = 2 * sig / (1 + sig**2)
        plt.hlines(eps, 1e-5, 5, color=col, ls='dashed', lw=0.5)

    if type == 'ini': tp = 'ini'
    else: tp = 'forc'
    #line_s0, line_s001, line_s01, line_s03, line_s05, line_s07, \
    #        line_s1, line_s1_neg, = get_lines_sig(tp)
    #hdls1 = [line_s001, line_s01, line_s03, line_s05, line_s07, line_s1,]
    #plt.legend(handles=hdls1, fontsize=24, loc='center left')
    MM = 'M'
    if type == 'kin': MM = 'K'
    sig_s = r'$\sigma_{\rm %s}^{\rm %s} = $' % (MM, tp)
    if type != 'forc':
        plt.text(2.5e-3, .12, sig_s + ' 0.1', color='green', fontsize=24)
        if type != 'ini':
            plt.text(2.5e-3, -.08, sig_s + ' 0', color='black', fontsize=24)
    else:
        plt.text(2.5e-3,
                 .04,
                 sig_s + ' $\pm 0.01$',
                 color='black',
                 fontsize=24)
    plt.text(2.5e-3, .47, sig_s + ' 0.3', color='darkgreen', fontsize=24)
    plt.text(2.5e-3, .72, sig_s + ' 0.5', color='orange', fontsize=24)
    if type == 'ini' or type == 'forc':
        plt.text(2.5e-3, .86, sig_s + ' 0.7', color='darkorange', fontsize=24)
    if type != 'forc':
        plt.text(2.5e-3, 1.04, sig_s + ' $1$', color='red', fontsize=24)
    else:
        plt.text(2.5e-3, 1.04, sig_s + ' $-1$', color='blue', fontsize=24)

    plot_sets.axes_lines()
    plt.xscale('log')
    plt.xlim(2e-3, 5e-1)
    plt.ylim(-.1, 1.13)
    if type == 'mag' or type == 'kin':
        plt.ylim(-.15, 1.13)
        plt.xlim(2e-3, 1.5e0)
    plt.xlabel('$\delta t=t-1$')
    plt.ylabel(r'$|{\cal P}_{\rm M}(t)|$')
    plt.yticks(np.linspace(0, 1, 5))

    if save:
        plt.savefig('plots/sigmaM_vs_t_' + type + '.pdf', bbox_inches='tight')
def plot_Xi_sensitivity(XiPLSa,
                        XiPLSb,
                        XiPLSa_Tai,
                        XiPLSb_Tai,
                        XiPLS_comb,
                        SNR=10,
                        T=4,
                        save=True):
    """
    Function that generates the plot of LISA and Taiji GW energy density
    polarization sensitivities and PLS.

    It corresponds to right panel of figure 16 of A. Roper Pol, S. Mandal,
    A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves
    from helical MHD turbulent sources," submitted to JCAP,
    https://arxiv.org/abs/2107.05356.

    Arguments:
        XiPLSa -- polarization PLS of the dipole response function of LISA
                  with beta_max = 2 for T = 1yr and SNR = 1
        XiPLSb -- polarization PLS of the dipole response function of LISA
                  with beta_max = 3 for T = 1yr and SNR = 1
        XiPLSa_Tai -- polarization PLS of the dipole response function of Taiji
                      with beta_max = 2 for T = 1yr and SNR = 1
        XiPLSb_Tai -- polarization PLS of the dipole response function of Taiji
                      with beta_max = 3 for T = 1yr and SNR = 1
        XiPLS_comb -- polarization PLS of the LISA-Taiji network
                      for T = 1yr and SNR = 1
        SNR -- signal-to-noise ratio (SNR) for the plotted PLS (default 10)
        T -- duration of the observations for the plotted PLS in
             years (default 4)
        save -- option to save the figure in "plots/Xi_LISA_Taiji.pdf"
                (default True)
    """

    fact = SNR / np.sqrt(T)
    fig, ax0 = plt.subplots(figsize=(12, 10))
    #plt.rc('font', size=18)
    plt.plot(fs, XiSAE, color='blue')
    plt.plot(fs, XiSCD, color='blue', ls='-.')

    gg = np.where(XiS_comb < 1e5)
    plt.plot(fs[gg], XiS_comb[gg], color='blue', lw=.6)

    plt.plot(fs, XiPLSa * fact, color='green')
    plt.plot(fs, XiPLSb * fact, color='green')
    plt.plot(fs, XiPLSa_Tai * fact, color='green', ls='-.')
    plt.plot(fs, XiPLSb_Tai * fact, color='green', ls='-.')

    plt.plot(fs, XiPLS_comb * fact, color='green', lw=.6)

    line_XiPLS, = ax0.plot([], [],
                           color='green',
                           label=r'$\Xi_{\rm PLS}^{\rm AE}$')
    line_XiPLS_Tai, = ax0.plot([], [],
                               color='green',
                               ls='-.',
                               label=r'$\Xi_{\rm PLS}^{\rm CD}$')
    line_XiPLS_comb, = ax0.plot([], [],
                                color='green',
                                lw=.8,
                                label=r'$\Xi_{\rm PLS}^{\rm comb}$')

    line_XiSA, = ax0.plot([], [],
                          color='blue',
                          label=r'$\Xi_{\rm s}^{\rm AE}$')
    line_XiSC, = ax0.plot([], [],
                          color='blue',
                          ls='-.',
                          label=r'$\Omega_{\rm s}^{\rm CD}$')
    line_XiS_comb, = ax0.plot([], [],
                              color='blue',
                              lw=.8,
                              label=r'$\Xi_{\rm s}^{\rm comb}$')

    handles = [line_XiSA, line_XiSC, line_XiS_comb]
    lgd1 = ax0.legend(handles=handles,
                      loc='lower right',
                      fontsize=28,
                      frameon=False)
    handles2 = [line_XiPLS, line_XiPLS_Tai, line_XiPLS_comb]
    lgd2 = ax0.legend(handles=handles2,
                      loc='lower left',
                      fontsize=28,
                      frameon=False)
    ax0.add_artist(lgd1)

    #plt.legend(fontsize=30, loc='lower right', frameon=False)
    plt.xlabel(r'$f$ [Hz]')
    plt.ylabel(r'$h_0^2\, \Xi_{\rm s} (f)$')
    plt.xscale('log')
    plt.yscale('log')
    plt.ylim(1e-14, 1e-2)
    plt.xlim(1e-5, 1e0)
    plot_sets.axes_lines()

    plt.text(1e-1, 8e-9, r'$\beta_{\rm max}=2$', color='green', fontsize=30)
    plt.text(9e-2, 6e-4, r'$\beta_{\rm max}=3$', color='green', fontsize=30)

    ax = plt.gca()
    ax.tick_params(axis='x', pad=20)
    ax.tick_params(axis='y', pad=10)
    plt.yticks(np.logspace(-14, -2, 7))
    plt.xticks(np.logspace(-5, 0, 6))

    if save: plt.savefig('plots/Xi_LISA_Taiji.pdf', bbox_inches='tight')
def plot_EGW_EM_vs_k(runs, rr='ini2', save=True, show=True):

    """
    Function that generates the plot of the magnetic spectrum
    EM (k) = Omega_M(k)/k at the initial time of turbulence generation
    and the GW spectrum EGW (k) = Omega_GW(k)/k, averaged over oscillations
    in time.

    It corresponds to figure 1 of A. Roper Pol, S. Mandal, A. Brandenburg,
    T. Kahniashvili, and A. Kosowsky, "Numerical simulations of gravitational
    waves from early-universe turbulence," Phys. Rev. D 102, 083512 (2020),
    https://arxiv.org/abs/1903.08585.

    Arguments:
        runs -- dictionary that includes the run variables
        rr -- string that selects which run to plot (default 'ini2')
        save -- option to save the resulting figure as
                plots/EGW_EM_vs_k_'name_run'.pdf' (default True)
        show -- option to show the resulting figure (default True)
    """

    plt.figure(figsize=(10,6))
    plt.xscale('log')
    plt.yscale('log')
    plt.xlim(120, 6e4)
    plt.ylim(1e-19, 1e-4)
    plt.xlabel('$k$')
    plt.ylabel(r'$\Omega_{\rm GW}(k)/k$ and $\Omega_{\rm M}(k)/k$',
               fontsize=20)

    run = runs.get(rr)
    # plot the averaged over times GW spectrum
    GWs_stat_sp = run.spectra.get('EGW_stat_sp')
    k = run.spectra.get('k')[1:]
    plt.plot(k, GWs_stat_sp, color='black')
    # plot magnetic spectrum at the initial time
    mag = run.spectra.get('mag')[0, 1:]
    plt.plot(k, mag, color='black')

    # plot k^4 line
    k0 = np.logspace(np.log10(150), np.log10(500), 5)
    plt.plot(k0, 1e-9*(k0/100)**4, color='black', ls='-.', lw=.7)
    plt.text(300, 8e-9, r'$\sim\!k^4$', fontsize=20)

    # plot k^(-5/3) line
    k0 = np.logspace(np.log10(2000), np.log10(8000), 5)
    plt.plot(k0, 1e-5*(k0/1000)**(-5/3), color='black', ls='-.', lw=.7)
    plt.text(5e3, 1.6e-6, r'$\sim\!k^{-5/3}$', fontsize=20)

    # plot k^(-11/3) line
    k0 = np.logspace(np.log10(3000), np.log10(30000), 5)
    plt.plot(k0, 1e-12*(k0/1000)**(-11/3), color='black', ls='-.', lw=.7)
    plt.text(1e4, 5e-16, r'$\sim\!k^{-11/3}$', fontsize=20)

    plt.text(1500, 1e-16, r'$\Omega_{\rm GW} (k)/k$', fontsize=20)
    plt.text(800, 5e-8, r'$\Omega_{\rm M} (k)/k$', fontsize=20)

    ax = plt.gca()
    ax.set_xticks([100, 1000, 10000])
    ytics = 10**np.array(np.linspace(-19, -5, 7))
    ytics2 = 10**np.array(np.linspace(-19, -5, 15))
    yticss = ['$10^{-19}$', '', '$10^{-17}$', '', '$10^{-15}$', '',
              '$10^{-13}$', '', '$10^{-11}$', '', '$10^{-9}$', '',
              '$10^{-7}$', '', '$10^{-5}$']
    ax.set_yticks(ytics2)
    ax.set_yticklabels(yticss)
    plot_sets.axes_lines()
    ax.tick_params(pad=10)

    if save: plt.savefig('plots/EGW_EM_vs_k_' + run.name_run + '.pdf',
                         bbox_inches='tight')
    if not show: plt.close()
Пример #14
0
def plot_OmGW_vs_f(runs,
                   type='ini',
                   T=1e5 * u.MeV,
                   g=100,
                   SNR=10,
                   Td=4,
                   OmM=.1,
                   Xi=False,
                   save=True):
    """
    Function that generates the plot of the GW energy density frequency
    spectra at present time compared to the LISA, Taiji, BBO, and DECIGO
    sensitivities and power law sensitivities (PLS).

    It produces figure 11-13 of A. Roper Pol, S. Mandal, A. Brandenburg,
    and T. Kahniashvili, "Polarization of gravitational waves from helical MHD
    turbulent sources," https://arxiv.org/abs/2107.05356.

    Arguments:
        runs -- dictionary that includes the run variables
        type -- selects the types of runs to be plotted (default 'ini', other
                option is 'forc'), i.e., runs with an initial magnetic field
                ('ini') or runs in which the magnetic field is initially driven
                during the simulation ('forc')
        T -- temperature scale (in natural units) at the time of turbulence
             generation (default 100 GeV, i.e., electroweak scale)
        g -- number of relativistic degrees of freedom at the time of
             turbulence generation (default 100, i.e., electroweak scale)
        SNR -- signal-to-noise ratio (SNR) of the resulting PLS (default 10)
        Td -- duration of the mission (in years) of the resulting PLS
              (default 4)
        save -- option to save the resulting figure as
                plots/'OmGW'_'type'_detectors_'Om'.pdf (default True)
                where 'OmGW' = OmGW or XiGW (for Xi False and True,
                respectively), 'Om' = OmM005 or OmM01, and 'type' is 'ini'
                or 'forc'
    """

    # read LISA and Taiji sensitivities
    CWD = os.getcwd()
    os.chdir('..')
    if Xi:
        fs, LISA_Om, LISA_OmPLS, LISA_Xi, LISA_XiPLS = \
                inte.read_sens(SNR=SNR, T=Td, Xi=True)
        fs_Tai, Taiji_Om, Taiji_OmPLS, Taiji_Xi, Taiji_XiPLS = \
                inte.read_sens(SNR=SNR, T=Td, interf='Taiji', Xi=True)
        fs_comb, LISA_Taiji_Xi, LISA_Taiji_XiPLS = \
                inte.read_sens(SNR=SNR, T=Td, interf='comb')
        fs_comb = fs_comb * u.Hz
    else:
        fs, LISA_Om, LISA_OmPLS = inte.read_sens(SNR=SNR, T=Td)
        fs_Tai, Taiji_Om, Taiji_OmPLS = inte.read_sens(SNR=SNR,
                                                       T=Td,
                                                       interf='Taiji')
        dir = 'detector_sensitivity'
        f_DECIGO, DECIGO_OmPLS = inte.read_csv(dir, 'DECIGO_PLS_SNR10')
        ff_D = np.logspace(np.log10(f_DECIGO[0]), np.log10(f_DECIGO[-1]), 100)
        DECIGO_OmPLS = 10**np.interp(ff_D, f_DECIGO, np.log10(DECIGO_OmPLS))
        f_DECIGO = ff_D * u.Hz
        f_BBO, BBO_OmPLS = inte.read_detector_PLIS_Schmitz(det='BBO',
                                                           SNR=SNR,
                                                           T=Td)
        f_BBO = f_BBO * u.Hz
    fs = fs * u.Hz
    fs_Tai = fs_Tai * u.Hz
    os.chdir(CWD)

    # internal function to compute f, OmGW as present time observables
    def shift_Omega(run, T, g, ratio, Xi, sp='stat'):
        hel = ''
        if Xi: hel = 'hel'
        EGW = np.array(run.spectra.get(hel + 'EGW_' + sp + '_sp'),
                       dtype='float') * ratio**2
        k = run.spectra.get('k')[1:]
        OmGW = EGW * k
        f, OmGW = cosmoGW.shift_OmGW_today(k, OmGW, T, g)
        return f, OmGW

    plt.rcParams.update({
        'xtick.labelsize': 'xx-large',
        'ytick.labelsize': 'xx-large',
        'axes.labelsize': 'xx-large'
    })

    if type == 'ini': RR = ['i_s01', 'i_s03', 'i_s05', 'i_s07', 'i_s1']
    elif type == 'forc':
        RR = ['f_s001', 'f_s001_neg', 'f_s03', 'f_s05', 'f_s07', 'f_s1_neg']
    elif type == 'kin':
        RR = ['K0', 'K01_c', 'K03', 'K05', 'K1']
    elif type == 'mag':
        RR = ['M0', 'M01_c', 'M03', 'M05', 'M1']

    fig, ax = plt.subplots(figsize=(12, 10))

    for i in RR:
        # select colors
        col = assign_col(i)
        run = runs.get(i)

        ratio = OmM / run.Ommax
        f, OmGW = shift_Omega(run, T, g, ratio, Xi, sp='stat')
        _, OmGW_min = shift_Omega(run, T, g, ratio, Xi, sp='min')
        _, OmGW_max = shift_Omega(run, T, g, ratio, Xi, sp='max')

        plt.plot(f, abs(OmGW), color=col, lw=3)
        #if 'i_s1' not in i:
        #if type == 'ini' or type == 'forc':
        plt.fill_between(f, OmGW_min, OmGW_max, alpha=0.1, color=col)
        for i in range(0, len(f)):
            plt.vlines(f.value[i],
                       OmGW_min[i],
                       OmGW_max[i],
                       color=col,
                       lw=0.6,
                       ls='dashed')

    if type == 'ini': tp = 'ini'
    else: tp = 'forc'
    line_s0, line_s001, line_s01, line_s03, line_s05, line_s07, \
            line_s1, line_s1_neg, = get_lines_sig(tp)
    if type == 'ini':
        hdls = [
            line_s01,
            line_s03,
            line_s05,
            line_s07,
            line_s1,
        ]
    elif type == 'forc':
        hdls = [
            line_s001,
            line_s03,
            line_s05,
            line_s07,
            line_s1_neg,
        ]
    else:
        hdls = [
            line_s0,
            line_s01,
            line_s03,
            line_s05,
            line_s1,
        ]
    plt.legend(handles=hdls, fontsize=24, loc='upper right', framealpha=1)

    Om = '0.1'
    if OmM == .05: Om = '0.05'
    xb = 2e-3
    yb = 8e-11
    if Xi:
        xb = 1e-3
        yb = 1e-17
    MM = 'M'
    if type == 'kin': MM = 'K'
    plt.text(xb,
             yb,
             r'${\cal E}^{\rm max}_{\rm %s} = %s$' % (MM, Om),
             fontsize=30,
             bbox=dict(facecolor='white',
                       edgecolor='black',
                       boxstyle='round,pad=.5'))

    if type == 'ini':
        xB = 1.2e-2
        yB = 1e-16
        xD = 2e-3
        yD = 6e-16
        if OmM == 0.1: pan = '(a)'
        else: pan = '(c)'
    else:
        xB = 3e-2
        yB = 3e-17
        xD = 2.5e-2
        yD = 1e-15
        if OmM == 0.1: pan = '(b)'
        else: pan = '(d)'
        if type == 'kin': pan = '(a)'
        if type == 'mag': pan = '(b)'

    if Xi:
        plt.plot(fs, LISA_XiPLS, color='lime', ls='-.', lw=1)
        plt.text(1.1e-3, 5e-11, 'LISA', fontsize=30, color='lime')
        plt.plot(fs_Tai, Taiji_XiPLS, color='crimson', ls='-.', lw=1)
        plt.text(1e-2, 4e-11, 'Taiji', fontsize=30, color='crimson')
        plt.plot(fs_comb, LISA_Taiji_XiPLS, color='navy', ls='-.', lw=1)
        plt.text(1e-2, 2e-13, r'LISA--Taiji', fontsize=30, color='navy')
    else:
        plt.plot(fs, LISA_OmPLS, color='lime', ls='-.', lw=1)
        plt.text(7e-3, 4e-12, 'LISA', fontsize=30, color='lime')
        plt.plot(fs_Tai, Taiji_OmPLS, color='crimson', ls='-.', lw=1)
        plt.text(1.3e-2, 1e-13, 'Taiji', fontsize=30, color='crimson')
        plt.plot(f_BBO, BBO_OmPLS, color='navy', ls='-.', lw=1)
        plt.text(xB, yB, 'BBO', fontsize=30, color='navy')
        plt.plot(f_DECIGO, DECIGO_OmPLS, color='royalblue', ls='-.', lw=1)
        plt.text(xD, yD, 'DECIGO', fontsize=30, color='royalblue')

    plt.text(4e-4, 4e-18, pan, fontsize=30)

    plot_sets.axes_lines()
    plt.xscale('log')
    plt.yscale('log')
    plt.xlim(3e-4, 2e-1)
    plt.ylim(1e-18, 1e-8)
    plt.xlabel('$f$ [Hz]')
    if Xi: plt.ylabel(r'$h_0^2 |\Xi_{\rm GW} (f)|$')
    else: plt.ylabel(r'$h_0^2 \Omega_{\rm GW} (f)$')

    Om_save = 'OmM01'
    if OmM == 0.05: Om_save = 'OmM005'
    OmGW_s = 'OmGW'
    if Xi: OmGW_s = 'XiGW'
    if save:
        plt.savefig('plots/%s_%s_detectors_%s.pdf' % (OmGW_s, type, Om_save),
                    bbox_inches='tight')
Пример #15
0
def plot_efficiency(runs, save=True):
    """
    Function that generates the plot of the GW production efficiency for
    different runs as a function of time.

    It corresponds to figure 10 of A. Roper Pol, S. Mandal, A. Brandenburg,
    and T. Kahniashvili, "Polarization of gravitational waves from helical MHD
    turbulent sources," https://arxiv.org/abs/2107.05356.

    Arguments:
        runs -- dictionary that includes the run variables
        save -- option to save the figure in plots/OmGW_efficiency_vs_t.pdf'
                (default True)
    """

    plt.figure(figsize=(12, 8))

    RR = [
        'i_s01', 'i_s03', 'i_s05', 'i_s07', 'i_s1', 'f_s001', 'f_s001_neg',
        'f_s03', 'f_s05', 'f_s07', 'f_s1_neg', 'M0', 'M01_c', 'M03', 'M05',
        'M1', 'ini1', 'ini2', 'ini3', 'hel1', 'hel2', 'hel3', 'hel4', 'noh1',
        'noh2', 'ac1', 'ac2', 'ac3'
    ]

    for i in RR:
        # select colors
        col = assign_col(i)
        run = runs.get(i)

        t = run.ts.get('t')
        EGW = run.ts.get('EEGW')
        if run.turb == 'm':
            Om = run.OmMmax
            kf = run.kfM
        if run.turb == 'k':
            Om = run.OmKmax
            kf = run.kfK
        if abs(kf - 510.9) < 10 or 'M' in i: kf = 708
        if abs(kf - 5999) < 100: kf = 7000
        lww = 1.
        ls = 'solid'
        if 'M' in i: lww = .6
        if 'ac' in i or 'hel' in i:
            lww = .8
            ls = 'dotted'
        if 'ini' in i or 'noh' in i:
            lww = .8
            ls = 'dotted'
        plt.plot(t - 1, np.sqrt(EGW) / Om * kf, color=col, ls=ls, lw=lww)


    line_s0, line_s001, line_s01, line_s03, line_s05, line_s07, \
            line_s1, line_s1_neg, = get_lines_sig('')
    hdls1 = [
        line_s001,
        line_s01,
        line_s03,
        line_s05,
        line_s07,
        line_s1,
    ]
    plt.text(.2, np.sqrt(.4), 'initial')
    plt.text(.08, 3.1, 'forcing (short)')
    plt.text(.007, 6, 'forcing (short, $k_*\sim 60$)')
    plt.text(1.2, np.sqrt(30), 'forcing (long)')
    plt.text(2e-1, 10, 'acoustic')
    plt.legend(handles=hdls1, fontsize=24, framealpha=1)

    plot_sets.axes_lines()
    plt.xlim(6e-3, 4)
    plt.ylim(1e-1, 2e1)
    plt.xlabel('$\delta t=t-1$')
    plt.ylabel(
        r'$k_*\, \Omega_{\rm GW}^{1/2} (t)/{\cal E}_{\rm M,K}^{\rm max}$')
    plt.yscale('log')
    plt.xscale('log')

    if save: plt.savefig('plots/OmGW_efficiency_vs_t.pdf', bbox_inches='tight')
def plot_MAC(save=True, log=False):
    """
    Function that generates the plot of the helical (V Stokes parameter)
    monopole responses of the cross-correlated channels of the LISA-Taiji
    network.

    It corresponds to figure 18 of A. Roper Pol, S. Mandal,
    A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves
    from helical MHD turbulent sources," submitted to JCAP,
    https://arxiv.org/abs/2107.05356.

    Arguments:
        save -- option to save the figure in
                "plots/Mcross_LISA_Taiji.pdf" (default True)
        log -- option to plot loglog with absolute values of the response
               functions (default False)
    """

    plt.figure(figsize=(12, 8))
    #plt.rc('font', size=20)
    lg = ''
    if log:
        MAC = abs(M_AC)
        MAD = abs(M_AD)
        MEC = abs(M_ED)
        MED = abs(M_ED)
        MED_I = abs(M_ED_I)
        plt.xscale('log')
        plt.yscale('log')
        lg = '_log'
    else:
        MAC = M_AC
        MAD = M_AD
        MEC = M_EC
        MED = M_ED
        MED_I = M_ED_I
    plt.plot(fs, MAC, color='black', label=r'${\cal M}^V_{\rm AC}$')
    plt.plot(fs,
             MAD,
             color='blue',
             ls='dotted',
             label=r'${\cal M}^V_{\rm AD}$')
    plt.plot(fs, MEC, color='red', ls='-.', label=r'${\cal M}^V_{\rm EC}$')
    plt.plot(fs, MED, color='green', ls='--', label=r'${\cal M}^V_{\rm ED}$')
    gg = np.where(abs(MED_I) > 1e-48)
    plt.plot(fs[gg],
             MED_I[gg],
             color='purple',
             alpha=.8,
             label=r'${\cal M}^I_{\rm ED}$')
    plt.legend(fontsize=18, frameon=False)
    plt.xlabel('$f$ [Hz]')
    plt.ylabel(r'${\cal M} (f)$')
    plt.xscale('log')
    if log:
        plt.xlim(1e-4, 4e-2)
        plt.ylim(1e-4, 2e-1)
    else:
        plt.xlim(3e-5, 4e-2)
        plt.ylim(-0.08, 0.08)
        plt.yticks(np.linspace(-.075, .075, 7))
    plot_sets.axes_lines()

    if save:
        plt.savefig('plots/Mcross_LISA_Taiji' + lg + '.pdf',
                    bbox_inches='tight')
def plot_Xi_sensitivity_dipole(XiPLSa,
                               XiPLSb,
                               XiPLSc,
                               XiPLSd,
                               XiPLSe,
                               XiPLSf,
                               XiPLSg,
                               XiPLS0,
                               XiPLS_comb,
                               interf='LISA',
                               SNR=10,
                               T=4,
                               save=True):
    """
    Function that generates the plot of the GW energy density
    polarization PLS for different values of beta_max.

    It corresponds to figure 17 of A. Roper Pol, S. Mandal,
    A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves
    from helical MHD turbulent sources," submitted to JCAP,
    https://arxiv.org/abs/2107.05356.

    Arguments:
        XiPLSa -- polarization PLS of the dipole response function of LISA
                  with beta_max = 2 for T = 1yr and SNR = 1
        XiPLSb -- polarization PLS of the dipole response function of LISA
                  with beta_max = 3 for T = 1yr and SNR = 1
        XiPLSc -- polarization PLS of the dipole response function of LISA
                  with beta_max = 3.7 for T = 1yr and SNR = 1
        XiPLSd -- polarization PLS of the dipole response function of LISA
                  with beta_max = 3.95 for T = 1yr and SNR = 1
        XiPLSe -- polarization PLS of the dipole response function of LISA
                  with beta_max = 3.999 for T = 1yr and SNR = 1
        XiPLSf -- polarization PLS of the dipole response function of LISA
                  with beta_max = 3.999999 for T = 1yr and SNR = 1
        XiPLSg -- polarization PLS of the dipole response function of LISA
                  with beta values in (-20, 0)U(5, 20) for T = 1yr and SNR = 1
        XiPLS0 -- polarization PLS of the dipole response function of LISA
                  omitting 1/(1 - beta/4) term for T = 1yr and SNR = 1
        XiPLS_comb -- polarization PLS of the LISA-Taiji network
                      for T = 1yr and SNR = 1
        interf -- selects interferometer (default 'LISA',
                  also available 'Taiji')
        SNR -- signal-to-noise ratio (SNR) for the plotted PLS (default 10)
        T -- duration of the observations for the plotted PLS in
             years (default 4)
        save -- option to save the figure in "plots/Xi_PLS_interf.pdf"
                (default True)
    """

    import pandas as pd
    fact = SNR / np.sqrt(T)
    plt.figure(figsize=(12, 10))
    if interf == 'LISA':
        AE = 'AE'
        ybeta_a = 1.3e-8
        ybeta_b = 1.5e-7
        ybeta_c = 3e-8
        ybeta_d = 1e-7
        ybeta_e = 1e-8
        ybeta_f = 3e-8
    if interf == 'Taiji':
        AE = 'CD'
        ybeta_a = 3e-9
        ybeta_b = 3.5e-8
        ybeta_c = 8e-9
        ybeta_d = 3e-8
        ybeta_e = 2.5e-9
        ybeta_f = 6e-9
    # plot PLS using dipole for different beta_max
    plt.plot(fs,
             XiPLSa * fact,
             color='blue',
             lw=1,
             label=r'$\Xi_{\rm PLS}^{\rm %s}$' % AE)
    plt.plot(fs, XiPLSb * fact, color='blue', lw=.8, ls='-.')
    plt.plot(fs, XiPLSc * fact, color='blue', lw=.8, ls='-.')
    plt.plot(fs, XiPLSd * fact, color='blue', lw=.8, ls='-.')
    plt.plot(fs, XiPLSe * fact, color='blue', lw=.8, ls='-.')
    plt.plot(fs, XiPLSf * fact, color='blue', lw=.8, ls='-.')
    # plot PLS using dipole ignoring 1/abs(1 - beta/4) term
    plt.plot(fs,
             XiPLS0 * fact,
             color='red',
             lw=.8,
             label=r'$\Xi_{\rm PLS}^{0, {\rm %s}}$' % AE)
    # plot PLS using LISA-Taiji combined network
    plt.plot(fs,
             XiPLS_comb * fact,
             color='green',
             lw=.8,
             label=r'$\Xi_{\rm PLS}^{\rm comb}$')

    # text with values of beta_max
    plt.text(2.5e-2,
             ybeta_a / 4,
             r'$\beta_{\rm max}=2$',
             color='blue',
             fontsize=22,
             bbox=dict(facecolor='white',
                       edgecolor='none',
                       boxstyle='round,pad=.2'))
    plt.text(3.2e-2,
             ybeta_b / 4,
             r'$\beta_{\rm max}=3$',
             color='blue',
             fontsize=22,
             bbox=dict(facecolor='white',
                       edgecolor='none',
                       boxstyle='round,pad=.2'))
    plt.text(5.3e-3,
             ybeta_c,
             r'$\beta_{\rm max}=3.7$',
             color='blue',
             fontsize=22,
             bbox=dict(facecolor='white',
                       edgecolor='none',
                       boxstyle='round,pad=.2'))
    plt.text(5.5e-3,
             ybeta_d * 3,
             r'$\beta_{\rm max}=3.95$',
             color='blue',
             fontsize=22,
             bbox=dict(facecolor='white',
                       edgecolor='none',
                       boxstyle='round,pad=.2'))
    plt.text(8e-4,
             ybeta_e,
             r'$\beta_{\rm max}=3.999$',
             color='blue',
             fontsize=22)
    plt.text(2e-4,
             ybeta_f * 5,
             r'$\beta_{\rm max}=3.999999$',
             fontsize=22,
             color='blue')

    plt.hlines(Xiflat * fact, 1e-3, 7e-2, color='blue', lw=.7)
    plt.hlines(Xiflat_Tai * fact, 1e-3, 7e-2, color='blue', ls='-.', lw=.7)
    plt.hlines(Xiflat_comb * fact, 1.e-3, 7e-2, color='green', lw=.8)
    plt.text(3e-2,
             1.5e-10,
             r'$\Xi_{\rm flat}^{\rm AE}$',
             fontsize=28,
             color='blue')
    plt.text(3e-2,
             1.7e-11,
             r'$\Xi_{\rm flat}^{\rm CD}$',
             fontsize=28,
             color='blue')
    plt.text(3e-2,
             8e-13,
             r'$\Xi_{\rm flat}^{\rm comb}$',
             fontsize=28,
             color='green')

    # read reference Xi PLS from Ellis et al 2019
    if interf == 'Taiji':
        dir = '../detector_sensitivity/'
        df = pd.read_csv(dir + 'XiPLS_Ellisetal19.csv')
        f = np.array(df['f'])
        ff = np.logspace(np.log10(f[0]), np.log10(f[-1]), 50)
        XiGW_PLS_LISA = np.array(df['Xi'])
        XiGW_PLS_LISA = np.interp(ff, f, XiGW_PLS_LISA)
        plt.plot(ff, XiGW_PLS_LISA, '.', color='blue', alpha=.4)
        plt.text(1.15e-2, 1.5e-10, r'$\sim\!f^5$', fontsize=22, color='blue')
        gg = np.where(XiPLSg > Xiflat_Tai * 1.01)
        hh = np.where(fs.value[gg] > 4e-3)
        plt.plot(fs[gg][hh], XiPLSg[gg][hh] * fact, color='blue', lw=.5)

    plt.legend(fontsize=28, loc='lower left', frameon=False)
    plt.xlabel(r'$f$ [Hz]')
    plt.ylabel(r'$h_0^2\, \Xi_{\rm PLS} (f)$')
    plt.xscale('log')
    plt.yscale('log')
    plt.ylim(1e-13, 1e-6)
    plt.xlim(1e-4, 1e-1)
    plot_sets.axes_lines()

    ax = plt.gca()
    ax.tick_params(axis='x', pad=20)
    ax.tick_params(axis='y', pad=10)
    plt.yticks(np.logspace(-13, -6, 8))

    if save:
        plt.savefig('plots/Xi_PLS_' + interf + '.pdf', bbox_inches='tight')
def plot_OmGW_hc_vs_f_ini(runs, T=1e5*u.MeV, g=100, SNR=10, Td=4,
                             save=True, show=True):

    """
    Function that generates the plot of the GW energy density spectrum
    of initial runs (ini1, ini2, and ini3), compared to the LISA sensitivity
    and power law sensitivity (PLS).

    It corresponds to figure 4 of A. Roper Pol, S. Mandal, A. Brandenburg,
    T. Kahniashvili, and A. Kosowsky, "Numerical simulations of gravitational
    waves from early-universe turbulence," Phys. Rev. D 102, 083512 (2020),
    https://arxiv.org/abs/1903.08585.

    Arguments:
        runs -- dictionary that includes the run variables
        T -- temperature scale (in natural units) at the time of turbulence
             generation (default 100 GeV, i.e., electroweak scale)
        g -- number of relativistic degrees of freedom at the time of
             turbulence generation (default 100, i.e., electroweak scale)
        SNR -- signal-to-noise ratio (SNR) of the resulting PLS (default 10)
        Td -- duration of the mission (in years) of the resulting PLS
             (default 4)
        save -- option to save the resulting figure as
                plots/OmGW_vs_f_ini.pdf (default True)
        show -- option to show the resulting figure (default True)
    """

    # read LISA and Taiji sensitivities
    CWD = os.getcwd()
    os.chdir('..')
    #f_LISA, f_LISA_Taiji, LISA_sensitivity, LISA_OmPLS, LISA_XiPLS, \
    #       Taiji_OmPLS, Taiji_XiPLS, LISA_Taiji_XiPLS = inte.read_sens()
    fs, LISA_Om, LISA_OmPLS = inte.read_sens(SNR=SNR, T=Td)
    fs = fs*u.Hz
    os.chdir(CWD)

    # chose the runs to be shown
    rrs = ['ini1', 'ini2', 'ini3']
    # chose the colors of each run
    col = ['black', 'red', 'blue']

    plt.figure(1, figsize=(12,5))
    plt.figure(2, figsize=(12,5))

    j = 0
    for i in rrs:
        run = runs.get(i)
        k = run.spectra.get('k')[1:]
        EGW_stat = run.spectra.get('EGW_stat_sp')
        f, OmGW_stat = cosmoGW.shift_OmGW_today(k, EGW_stat*k, T, g)
        OmGW_stat = np.array(OmGW_stat, dtype='float')
        hc_stat = cosmoGW.hc_OmGW(f, OmGW_stat)
        plt.figure(1)
        plt.plot(f, OmGW_stat, color=col[j], lw=.8)
        if i == 'ini1': plt.text(5e-2, 1.5e-15, i, color=col[j])
        if i == 'ini2': plt.text(3e-2, 2e-17, i, color=col[j])
        if i == 'ini3': plt.text(3e-3, 4e-17, i, color=col[j])
        plt.figure(2)
        plt.plot(f, hc_stat, color=col[j], lw=.8)
        if i == 'ini1': plt.text(5e-2, 1.5e-24, i, color=col[j])
        if i == 'ini2': plt.text(1e-2, 3e-24, i, color=col[j])
        if i == 'ini3': plt.text(4e-3, 1e-24, i, color=col[j])
        j += 1

    plt.figure(1)
    plt.xscale('log')
    plt.yscale('log')
    plt.xlim(1e-4, 1e-1)
    plt.ylim(1e-19, 1e-9)
    plt.xlabel('$f$ [Hz]')
    plt.ylabel(r'$h_0^2 \Omega_{\rm GW} (f)$')
    #plt.plot(f_LISA, LISA_OmPLS, color='lime', ls='dashdot')
    #plt.plot(f_LISA, LISA_sensitivity, color='lime')
    plt.plot(fs, LISA_OmPLS, color='lime', ls='dashdot')
    plt.plot(fs, LISA_Om, color='lime')

    # plot f^(-8/3) line
    fs0 = np.logspace(-2.1, -1.5, 5)
    plt.plot(fs0, 3e-15*(fs0/2e-2)**(-8/3), color='black',
             ls='dashdot', lw=.7)
    plt.text(1e-2, 5e-16, '$\sim\!f^{-8/3}$')

    # plot f line
    fs0 = np.logspace(-3.45, -2.8, 5)
    plt.plot(fs0, 2e-13*(fs0/1e-3)**(1), color='black',
             ls='dashdot', lw=.7)
    plt.text(4e-4, 3e-13, '$\sim\!f$')

    ax = plt.gca()
    ytics2 = 10**np.array(np.linspace(-19, -9, 11))
    yticss = ['', '$10^{-18}$', '', '$10^{-16}$', '', '$10^{-14}$', '',
              '$10^{-12}$', '', '$10^{-10}$', '']
    ax.set_yticks(ytics2)
    ax.set_yticklabels(yticss)
    plot_sets.axes_lines()

    if save: plt.savefig('plots/OmGW_vs_f_ini.pdf', bbox_inches='tight')
    if not show: plt.close()

    plt.figure(2)
    plt.xscale('log')
    plt.yscale('log')
    plt.xlim(1e-4, 1e-1)
    plt.ylim(1e-25, 1e-20)
    plt.xlabel('$f$ [Hz]')
    plt.ylabel(r'$h_{\rm c}(f)$')

    LISA_hc_PLS = cosmoGW.hc_OmGW(fs, LISA_OmPLS)
    LISA_hc = cosmoGW.hc_OmGW(fs, LISA_Om)
    plt.plot(fs, LISA_hc_PLS, color='lime', ls='dashdot')
    plt.plot(fs, LISA_hc, color='lime')

    # plot f^(-1/2) line
    fs0 = np.logspace(-3.4, -2.6, 5)
    plt.plot(fs0, 8e-22*(fs0/1e-3)**(-1/2), color='black',
             ls='dashdot', lw=.7)
    plt.text(8e-4, 1.5e-21, '$\sim\!f^{-1/2}$')

    # plot f^(-7/3) line
    fs0 = np.logspace(-2, -1.4, 5)
    plt.plot(fs0, 1e-23*(fs0/2e-2)**(-7/3), color='black',
             ls='dashdot', lw=.7)
    plt.text(2e-2, 2e-23, '$\sim\!f^{-7/3}$')

    ax = plt.gca()
    ytics2 = 10**np.array(np.linspace(-25, -20, 6))
    ax.set_yticks(ytics2)
    plot_sets.axes_lines()

    if save: plt.savefig('plots/hc_vs_f_ini.pdf', bbox_inches='tight')
    if not show: plt.close()
def plot_OmGW_hc_vs_f_driven(runs, T=1e5*u.MeV, g=100, SNR=10, Td=4,
                             save=True, show=True):

    """
    Function that generates the plot of the GW energy density spectrum
    of some of the initially driven runs (ac1, hel1, hel2, hel3, and noh1),
    compared to the LISA sensitivity and power law sensitivity (PLS).

    It corresponds to figure 6 of A. Roper Pol, S. Mandal, A. Brandenburg,
    T. Kahniashvili, and A. Kosowsky, "Numerical simulations of gravitational
    waves from early-universe turbulence," Phys. Rev. D 102, 083512 (2020),
    https://arxiv.org/abs/1903.08585.

    Arguments:
        runs -- dictionary that includes the run variables
        T -- temperature scale (in natural units) at the time of turbulence
             generation (default 100 GeV, i.e., electroweak scale)
        g -- number of relativistic degrees of freedom at the time of
             turbulence generation (default 100, i.e., electroweak scale)
        SNR -- signal-to-noise ratio (SNR) of the resulting PLS (default 10)
        Td -- duration of the mission (in years) of the resulting PLS
             (default 4)
        save -- option to save the resulting figure as
                plots/OmGW_vs_f_driven.pdf (default True)
        show -- option to show the resulting figure (default True)
    """

    # read LISA and Taiji sensitivities
    CWD = os.getcwd()
    os.chdir('..')
    #f_LISA, f_LISA_Taiji, LISA_sensitivity, LISA_OmPLS, LISA_XiPLS, \
    #        Taiji_OmPLS, Taiji_XiPLS, LISA_Taiji_XiPLS = inte.read_sens()
    fs, LISA_Om, LISA_OmPLS = inte.read_sens(SNR=SNR, T=Td)
    fs = fs*u.Hz
    os.chdir(CWD)

    # chose the runs to be shown
    rrs = ['ac1', 'hel1', 'hel2', 'hel3', 'noh1']
    # chose the colors of each run
    col = ['black', 'red', 'blue', 'blue', 'blue']
    # chose the line style for the plots
    ls = ['solid', 'solid', 'solid', 'dotted', 'dashed']

    plt.figure(1, figsize=(12,5))
    plt.figure(2, figsize=(12,5))

    j = 0
    for i in rrs:
        run = runs.get(i)
        k = run.spectra.get('k')[1:]
        EGW_stat = run.spectra.get('EGW_stat_sp')
        f, OmGW_stat = cosmoGW.shift_OmGW_today(k, EGW_stat*k, T, g)
        OmGW_stat = np.array(OmGW_stat, dtype='float')
        hc_stat = cosmoGW.hc_OmGW(f, OmGW_stat)

        plt.figure(1)
        # omit largest frequencies where there is not enough numerical accuracy
        if i == 'hel3':
            OmGW_stat = OmGW_stat[np.where(f.value<3e-2)]
            hc_stat = hc_stat[np.where(f.value<3e-2)]
            f = f[np.where(f.value<3e-2)]
        if i=='hel3' or i=='hel2' or i=='noh1' or i=='hel1':
            plt.plot(f, OmGW_stat, color=col[j],
                     ls=ls[j], lw=.8, label=i)
        else:
            plt.plot(f, OmGW_stat, color=col[j], ls=ls[j], lw=.8)
            plt.text(5e-2, 2e-19, i, fontsize=20, color='black')

        plt.figure(2)
        if i=='hel3' or i=='hel2' or i=='noh1'or i=='hel1':
            plt.plot(f, hc_stat, color=col[j], ls=ls[j], lw=.8, label=i)
        else:
            plt.plot(f, hc_stat, color=col[j], ls=ls[j], lw=.8)
            plt.text(3e-3, 5e-22, i, color=col[j])
        j += 1

    plt.figure(1)
    plt.xscale('log')
    plt.yscale('log')
    plt.xlim(1e-4, 1e-1)
    plt.ylim(1e-26, 1e-9)
    plt.xlabel('$f$ [Hz]')
    plt.ylabel(r'$h_0^2 \Omega_{\rm GW} (f)$')
    plt.legend(loc='lower left', frameon=False, fontsize=20)
    plt.plot(fs, LISA_OmPLS, color='lime', ls='dashdot')
    plt.plot(fs, LISA_Om, color='lime')

    # plot f^(-5) line
    fk0 = np.logspace(-2.2, -1.6, 5)
    plt.plot(fk0, 1e-14*(fk0/1e-2)**(-5), color='black',
             ls='dashdot', lw=.7)
    plt.text(1.3e-2, 1e-14, '$\sim\!f^{-5}$')

    # plot f line
    fk0 = np.logspace(-3.3, -2.8, 5)
    plt.plot(fk0, 2e-16*(fk0/1e-3)**(1), color='black',
             ls='dashdot', lw=.7)
    plt.text(6e-4, 1e-17, '$\sim\!f$')

    ax = plt.gca()
    ytics2 = 10**np.array(np.linspace(-25, -9, 16))
    yticss = ['$10^{-25}$', '', '$10^{-23}$', '',  '$10^{-21}$', '',
              '$10^{-19}$','', '$10^{-17}$', '','$10^{-15}$','',
              '$10^{-13}$', '','$10^{-11}$','']
    ax.set_yticks(ytics2)
    ax.set_yticklabels(yticss)
    plot_sets.axes_lines()

    if save: plt.savefig('plots/OmGW_vs_f_driven.pdf', bbox_inches='tight')
    if not show: plt.close()

    plt.figure(2)
    plt.xscale('log')
    plt.yscale('log')
    plt.xlim(1e-4, 1e-1)
    plt.ylim(1e-28, 1e-20)
    plt.xlabel('$f$ [Hz]')
    plt.ylabel(r'$h_{\rm c}(f)$')
    plt.legend(loc='lower left', frameon=False, fontsize=20)

    LISA_hc_PLS = cosmoGW.hc_OmGW(fs, LISA_OmPLS)
    LISA_hc = cosmoGW.hc_OmGW(fs, LISA_Om)
    plt.plot(fs, LISA_hc_PLS, color='lime', ls='dashdot')
    plt.plot(fs, LISA_hc, color='lime')

    # plot f^(-7/2) line
    fk0 = np.logspace(-2.2, -1.6, 5)
    plt.plot(fk0, 1e-23*(fk0/1e-2)**(-7/2), color='black',
             ls='dashdot', lw=.7)
    plt.text(1.3e-2, 1e-23, '$\sim\!f^{-7/2}$')

    # plot f^(-1/2) line
    fk0 = np.logspace(-3.3, -2.8, 5)
    plt.plot(fk0, 2e-23*(fk0/1e-3)**(-1/2), color='black',
             ls='dashdot', lw=.7)
    plt.text(6e-4, 3e-24, '$\sim\!f^{-1/2}$')

    ax = plt.gca()
    ytics2 = 10**np.array(np.linspace(-28, -20, 9))
    ytics2 = 10**np.array(np.linspace(-28, -20, 9))
    yticss = ['', '$10^{-27}$', '',  '$10^{-25}$', '',
              '$10^{-23}$', '', '$10^{-21}$', '']
    ax.set_yticks(ytics2)
    ax.set_yticklabels(yticss)
    plot_sets.axes_lines()

    if save: plt.savefig('plots/hc_vs_f_driven.pdf', bbox_inches='tight')
    if not show: plt.close()
def plot_EGW_vs_k_initial_ts(runs, rr='ini2', save=True, show=True):

    """
    Function that generates the plot of the amplitudes of the GW energy
    density at the first time step, to show the evolution from k^2 to k^0
    slopes.

    It corresponds to a plot generated for a presentation, related to the
    work A. Roper Pol, S. Mandal, A. Brandenburg, T. Kahniashvili,
    and A. Kosowsky, "Numerical simulations of gravitational waves from
    early-universe turbulence," Phys. Rev. D 102, 083512 (2020),
    https://arxiv.org/abs/1903.08585.

    Arguments:
        runs -- dictionary that includes the run variables
        rr -- string that selects which run to plot (default 'ini2')
        save -- option to save the resulting figure as
                plots/EGW_vs_k_initial_ts.pdf (default True)
        show -- option to show the resulting figure (default True)
    """

    run = runs.get(rr)
    EGW = run.spectra.get('EGW')[:, 1:]
    k = run.spectra.get('k')[1:]
    t = run.spectra.get('t_GWs')
    max_sp_EGW = run.spectra.get('EGW_max_sp')

    plt.figure(figsize=(10,6))
    plt.xscale('log')
    plt.yscale('log')
    plt.xlabel('$k$')
    plt.ylabel(r'$\Omega_{\rm GW} (k)/k$')
    # initial time step GW spectrum
    plt.plot(k, EGW[0, :], color='black', lw=.7, ls='dashed')
    # local maximum amplitudes of oscillations at next time step
    kmax, EGWmax = sp.local_max(k, EGW[1, :])
    plt.plot(kmax, EGWmax, color='black', lw=.7, ls='dashed')
    plt.plot(k[:10], EGW[1, :10], color='black', lw=.7, ls='dashed')
    # maximum over all times of the GW energy density (amplitude of the
    # oscillations)
    plt.plot(k, max_sp_EGW, color='black', lw=1.5)
    # 6th time step
    kmax, EGWmax = sp.local_max(k, EGW[5, :])
    plt.plot(kmax, EGWmax, color='black', lw=.7, ls='dashed')
    plt.plot(k[:4], EGW[5, :4], color='black', lw=.7, ls='dashed')

    # line k^(2.5)
    k0s = np.linspace(250, 1000)
    plt.plot(k0s, 3e-19*(k0s/100)**2.5, color='black',
             ls='dashdot', lw=.7)
    plt.text(500, 5e-18, '$k^{2.5}$', fontsize=20)

    # line k^(1/2)
    k0s = np.linspace(200, 800)
    plt.plot(k0s, 7e-14*(k0s/100)**0.5, color='black',
             ls='dashdot', lw=.7)
    plt.text(500, 3e-13, '$k^{0.5}$', fontsize=20)

    # line k^(-11/3)
    k0s = np.linspace(3000, 10000)
    plt.text(5000, 1e-14, '$k^{-11/3}$', fontsize=20)
    plt.plot(k0s, 1e-14*(k0s/4e3)**(-11/3), color='black',
             ls='dashdot', lw=.7)

    plt.text(3000, 1e-17, r'$t-1=4 \times 10^{-5}$', fontsize=14)
    plt.text(250, 2e-15, '$t-1=10^{-3}$', fontsize=14)
    plt.text(130, 8e-15, r'$5 \times 10^{-3}$', fontsize=14)

    plt.ylim(1e-19, 2e-12)
    yticks = np.logspace(-19, -12, 8)
    ax = plt.gca()
    ax.set_yticks(yticks)
    plot_sets.axes_lines()
    ax.tick_params(axis='x', pad=12)

    if save: plt.savefig('plots/EGW_vs_k_initial_ts.pdf',
                         bbox_inches='tight')
    if not show: plt.close()
def plot_OmGW_vs_OmMK(runs, save=True, show=True):

    """
    Function that generates the plot of the total (saturated) GW energy
    density integrated over wave numbers as a function of the
    magnetic/kinetic energy density.

    It corresponds to figure 7 of A. Roper Pol, S. Mandal, A. Brandenburg,
    T. Kahniashvili, and A. Kosowsky, "Numerical simulations of gravitational
    waves from early-universe turbulence," Phys. Rev. D 102, 083512 (2020),
    https://arxiv.org/abs/1903.08585.

    Arguments:
        runs -- dictionary that includes the run variables
        save -- option to save the resulting figure as
                plots/OmGW_vs_OmMK.pdf (default True)
        show -- option to show the resulting figure (default True)
    """

    # chose the runs to be shown
    rrs = [s for s in runs]
    # chose the colors of each run
    col = ['darkorange', 'darkorange', 'lime', 'red', 'red', 'red',
           'lime', 'red', 'red', 'blue', 'blue', 'blue']

    plt.figure(figsize=(8,5))
    plt.xscale('log')
    plt.yscale('log')
    plt.xlabel(r'$\Omega_{\rm M,K}^{\rm max}$')
    plt.ylabel(r'$\Omega_{\rm GW}^{\rm sat}$')
    plt.xlim(1e-3, 2e-1)
    plt.ylim(7e-12, 1e-7)

    j = 0
    for i in runs:
        run = runs.get(i)
        if 'noh' in i:
            plt.scatter(run.Ommax, run.OmGWsat,
                        edgecolors='red', facecolors='none')
        else:
            plt.plot(run.Ommax, run.OmGWsat, 'o', color=col[j])
        j += 1

    OmMs = np.logspace(-2.2, -.8)
    plt.plot(OmMs, 1.7e-6*OmMs**2, color='darkorange')
    OmMs = np.logspace(-2.5, -1.5)
    plt.plot(OmMs, 9e-6*OmMs**2, color='red')
    OmMs = np.logspace(-2.5, -1.7)
    plt.plot(OmMs, 1.5e-5*OmMs**2, color='red', ls='dashed', lw=.7)
    OmMs = np.logspace(-2.8, -1.8)
    plt.plot(OmMs, 3.5e-4*OmMs**2, color='blue')

    plot_sets.axes_lines()
    plt.yticks([1e-11, 1e-10, 1e-9, 1e-8, 1e-7])
    plt.text(1.5e-2, 2e-10, 'ini', color='darkorange')
    plt.text(1.5e-2, 2e-10/2, '$i$=M', color='darkorange')
    plt.text(2e-2, 2e-8, 'hel', color='red')
    plt.text(2e-2, 2e-8/2, '$i$=M', color='red')
    plt.text(2e-3, 1e-8, 'ac', color='blue')
    plt.text(2e-3, 1e-8/2, '$i$=K', color='blue')
    plt.text(7e-3, 4e-9, '(ini3)', color='lime')
    plt.text(5e-3, 1.7e-11, '(hel4)', color='lime')
    plt.text(3.5e-3, 7e-10, '(noh)', color='red')

    if save: plt.savefig('plots/OmGW_vs_OmMK.pdf', bbox_inches='tight')
    if not show: plt.close()
def plot_Omega_sensitivity(OmPLS,
                           OmPLS_Tai,
                           OmPLS_comb,
                           SNR=10,
                           T=4,
                           save=True):
    """
    Function that generates the plot of LISA and Taiji GW energy density
    sensitivities and PLS.

    It corresponds to left panel of figure 16 of A. Roper Pol, S. Mandal,
    A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves
    from helical MHD turbulent sources," submitted to JCAP,
    https://arxiv.org/abs/2107.05356.

    Arguments:
        OmPLS -- power law sensitivity (PLS) of LISA for T = 1yr and SNR = 1
        OmPLS_Tai -- power law sensitivity (PLS) of Taiji for T = 1yr
                     and SNR = 1
        OmPLS_comb -- power law sensitivity (PLS) of the LISA-Taiji network
                      for T = 1yr and SNR = 1
        SNR -- signal-to-noise ratio (SNR) for the plotted PLS (default 10)
        T -- duration of the observations for the plotted PLS in
             years (default 4)
        save -- option to save the figure in "plots/Omega_LISA_Taiji.pdf"
                (default True)
    """

    import pandas as pd

    fact = SNR / np.sqrt(T)
    fig, ax0 = plt.subplots(figsize=(12, 10))
    line_OmPLS, = ax0.plot([], [],
                           color='green',
                           label=r'$\Omega_{\rm PLS}^{\rm A}$')
    line_OmPLS_Tai, = ax0.plot([], [],
                               color='green',
                               ls='-.',
                               label=r'$\Omega_{\rm PLS}^{\rm C}$')
    line_OmPLS_comb, = ax0.plot([], [],
                                color='green',
                                lw=.8,
                                label=r'$\Omega_{\rm PLS}^{\rm comb}$')

    line_OmSA, = ax0.plot([], [],
                          color='blue',
                          label=r'$\Omega_{\rm s}^{\rm A}$')
    line_OmSC, = ax0.plot([], [],
                          color='blue',
                          ls='-.',
                          label=r'$\Omega_{\rm s}^{\rm C}$')
    line_OmS_comb, = ax0.plot([], [],
                              color='blue',
                              lw=.8,
                              label=r'$\Omega_{\rm s}^{\rm comb}$')

    line_OmST, = ax0.plot([], [],
                          color='orange',
                          alpha=.5,
                          label=r'$\Omega_{\rm s}^{\rm T}$')
    line_OmSS, = ax0.plot([], [],
                          color='orange',
                          ls='-.',
                          alpha=.5,
                          label=r'$\Omega_{\rm s}^{\rm S}$')
    line_OmS_ED_I, = ax0.plot([], [],
                              color='purple',
                              alpha=.5,
                              label=r'$\Omega_{\rm s}^{\rm ED}$')

    handles = [line_OmSA, line_OmSC, line_OmS_comb]
    lgd1 = ax0.legend(handles=handles,
                      loc='lower right',
                      fontsize=28,
                      frameon=False)
    handles2 = [line_OmST, line_OmSS, line_OmS_ED_I]
    lgd2 = ax0.legend(handles=handles2,
                      loc='upper left',
                      fontsize=28,
                      frameon=False)
    handles3 = [line_OmPLS, line_OmPLS_Tai, line_OmPLS_comb]
    lgd3 = ax0.legend(handles=handles3,
                      loc='lower left',
                      fontsize=28,
                      frameon=False)
    ax0.add_artist(lgd1)
    ax0.add_artist(lgd2)

    # plt.rc('font', size=30)
    plt.plot(fs, OmSA, color='blue')
    plt.plot(fs, OmST, color='orange', alpha=.5)
    plt.plot(fs, OmPLS * fact, color='green')
    plt.plot(fs, OmSC, '-.', color='blue')
    plt.plot(fs, OmSS, '-.', color='orange', alpha=.5)
    plt.plot(fs, OmPLS_Tai * fact, '-.', color='green')
    gg = np.where(abs(M_ED_I) > 1e-48)
    plt.plot(fs[gg], OmS_ED_I[gg], color='purple', alpha=.5)
    plt.plot(fs, OmS_comb, color='blue', lw=.8)
    plt.plot(fs, OmPLS_comb * fact, color='green', lw=.8)

    # Add reference PLS from Caprini et al 2019
    dir = '../detector_sensitivity/'
    df = pd.read_csv(dir + 'OmegaPLS_Caprinietal19.csv')
    f = np.array(df['f'])
    ff = np.logspace(np.log10(f[0]), np.log10(f[-1]), 70)
    OmGW_PLS_LISA = np.array(df['Omega'])
    OmGW_PLS_LISA = np.interp(ff, f, OmGW_PLS_LISA)
    plt.plot(ff, OmGW_PLS_LISA, '.', color='green', alpha=.4)

    plot_sets.axes_lines()
    plt.ylim(1e-14, 1e-2)
    plt.yticks(np.logspace(-14, -2, 8))
    plt.xlim(1e-5, 1e0)
    plt.xlabel('$f$ [Hz]')
    plt.ylabel(r'$h_0^2\,\Omega_{\rm s} (f)$')
    plt.xscale('log')
    plt.yscale('log')
    ax = plt.gca()
    ax.tick_params(axis='x', pad=20)
    ax.tick_params(axis='y', pad=10)
    plt.yticks(np.logspace(-14, -2, 7))
    plt.xticks(np.logspace(-5, 0, 6))

    if save: plt.savefig('plots/Omega_LISA_Taiji.pdf', bbox_inches='tight')
def plot_efficiency(runs, save=True, show=True, sqrt=False):

    """
    Function that generates the plot of the total GW energy density
    compensated by EM^2/kf^2 (efficiency).

    It corresponds to the runs presented in A. Roper Pol, S. Mandal,
    A. Brandenburg, T. Kahniashvili, and A. Kosowsky, "Numerical simulations of gravitational waves from
    early-universe turbulence," Phys. Rev. D 102, 083512 (2020),
    https://arxiv.org/abs/1903.08585.

    This plot is analogous to figure 10 of A. Roper Pol, S. Mandal,
    A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves
    from helical MHD turbulent sources", https://arxiv.org/abs/2107.05356.

    Arguments:
        runs -- dictionary that includes the run variables
        save -- option to save the resulting figure as plots/efficiency.pdf
                or plots/efficiency_sqrt.pdf (if sqrt = True) (default True)
        show -- option to show the resulting figure (default True)
        sqrt -- option to plot the efficiency defined as the square root of
                the compensated GW energy density (default False)
    """

    exp = 1
    if sqrt: exp = 1/2
    plt.figure(1, figsize=(12,8))
    plt.xscale('log')
    plt.yscale('log')
    plt.xlim(6e-3, 1)
    plt.ylim(1e-1**exp, 2e2**exp)
    plt.xlabel('$\delta t = t - 1$')
    plt.ylabel(r'$q^2 (t) = k_*^2\, \Omega_{\rm GW}$' + \
               r'$(t)/({\cal E}_{\rm M, K}^{\rm max})^2$')
    if sqrt:
        plt.ylabel(r'$q (t) = k_* \left[\Omega_{\rm GW} (t)\right]^{1/2}$' + \
                   r'$/{\cal E}_{\rm M, K}^{\rm max}$')
    for i in runs:
        # chose colors
        if 'ini' in i: col = 'green'
        elif 'hel4' in i: col = 'red'
        elif 'noh' in i: col = 'black'
        elif 'ac' in i: col = 'blue'
        else: col = 'orange'
        run = runs.get(i)
        t = run.ts.get('t')
        EGW = run.ts.get('EEGW')
        plt.plot(t-1, (EGW/run.Ommax**2*run.kf**2)**exp,
                 color=col)

    plot_sets.axes_lines()
    plt.text(3e-1, 70**exp, 'acoustic', color='blue')
    plt.text(3e-1, 1.5**exp, 'initial', color='green')
    plt.text(1.3e-1, 2.8**exp, r'helical 1--3', color='orange')
    plt.text(3e-1, 15**exp, 'helical 4', color='red')
    plt.text(4e-1, 8.6**exp, 'non-helical', color='black')

    if save:
        if sqrt: plt.savefig('plots/efficiency_sqrt.pdf',
                         bbox_inches='tight')
        else: plt.savefig('plots/efficiency.pdf',
                         bbox_inches='tight')
    if not show: plt.close()
Пример #24
0
def plot_EM_EGW(run, save=True):
    """
    Function that plots the magnetic energy and helicity spectra at the time
    of maximum magnetic energy density.
    It also plots the GW energy density and helicity spectra, averaging over
    times after the GW energy has entered a stationary oscillatory stage (this
    needs to be previously computed and stored in the run variable, see
    initialize_JCAP_2021.py).

    It corresponds to figures 1-3 of A. Roper Pol, S. Mandal, A. Brandenburg,
    and T. Kahniashvili, "Polarization of gravitational waves from helical MHD
    turbulent sources," https://arxiv.org/abs/2107.05356.

    Arguments:
        run -- variable run with spectral information
        save -- option to save the figure in plots/'name_run'EM_EGW.pdf'
                (default True)
    """

    # auxiliary functions used in plot_EM_EGW
    def init_Ay2_Ax(N, Ay, Ax):
        return N, N * [Ay], N * [Ax]

    # chose indices to show power law fits and text with k^(a/b) for magnetic
    # spectrum EM(k)
    def indices_EM(nm, Ax, Ay):
        if 'i' in nm:
            inds_show = [0, 1, 4, 5, 6, 7, 8, 9, 10]
            inds_show_txt = [0, 6]
            Ay[0] *= 8
            Ay[6] *= 2
            if '3' in nm or '5' in nm:
                inds_show_txt = [0, 7]
                Ay[7] *= .5
                if '5' in nm: Ay[0] *= 2
            if nm == 'i_s1':
                inds_show_txt = [1, 7]
                Ay[1] *= 20
                Ax[1] *= .7
                Ay[7] *= .5
        else:
            if '001' in nm:
                inds_show = [0, 1, 4, 6, 8, 9, 10, 11]
                inds_show_txt = [1, 4, 6, 10]
                Ay[1] *= 6
                Ax[1] *= .7
                Ay[4] *= 25
                Ay[6] *= 2
                Ay[10] *= 1 / 6000
            else:
                inds_show = [0, 1, 5, 6, 7, 8, 9, 10, 11]
                inds_show_txt = [0, 5, 7, 10, 11]
                Ay[0] *= 5
                Ay[5] *= 3.5
                Ay[7] *= 1 / 10
                Ay[10] *= 6e-5
                Ay[11] *= 1e-6
                Ax[11] *= .9
                if '5' in nm:
                    inds_show_txt = [1, 5, 7, 10, 11]
                    Ay[1] *= 10
                    Ax[1] *= .8
                    Ay[10] *= 1 / 8
                    Ay[11] *= 1 / 5
                if '7' in nm:
                    inds_show_txt = [0, 5, 7, 9, 10]
                    Ay[5] *= .5
                    Ay[7] *= 3e-1
                    Ay[9] *= 1e-4
                    Ay[10] *= 3e-2
                if '1' in nm:
                    inds_show_txt = [0, 5, 7, 9, 10]
                    Ay[0] *= 2
                    Ax[0] *= .9
                    Ay[5] *= .3
                    Ay[7] *= 1e-1
                    Ay[9] *= 4e-5
                    Ay[10] *= 1e-2
                    Ax[10] *= 1.1
        return inds_show, inds_show_txt, Ax, Ay

    # chose indices to show power law fits and text with k^(a/b) for magnetic
    # helicity spectrum HM(k)
    def indices_HM(nm, Ax, Ay):
        inds_show = []
        inds_show_txt = []
        if 'i' in nm:
            inds_show = [1, 4, 5, 6, 7, 8]
            inds_show_txt = [1]
            Ay[1] *= 80
            #Ay[2] *= 100; Ax[2] *= .8
            if '3' in nm or '5' in nm:
                inds_show = [0, 1, 4, 5, 6, 7, 8]
                inds_show_txt = [0, 1]
                if '3' in nm: Ay[0] *= 8
                if '5' in nm: Ay[0] *= 5
        else:
            if '001' not in nm:
                inds_show = [0, 4, 5, 6, 7, 8]
                inds_show_txt = [0, 4, 6, 8]
                Ay[0] *= 8
                Ax[4] *= .7
                Ay[6] *= 3e-4
                Ay[8] *= 4e-7
                Ax[8] *= .7
                if '5' in nm:
                    Ax[6] *= .7
                    Ay[6] *= 15
                    Ax[8] *= .7
                    Ay[8] *= 2
                if '7' in nm:
                    Ay[4] *= .5
                    Ax[6] *= .7
                    Ay[6] *= 7
                    Ax[8] *= .9
                if '1' in nm:
                    Ax[6] *= .7
                    Ay[6] *= 3
                    Ay[8] *= 2e-1
                    Ax[8] *= .8
        return inds_show, inds_show_txt, Ax, Ay

    # chose indices to show power law fits and text with k^(a/b) for GW
    # spectrum EGW(k)
    def indices_EGW(nm, Ax, Ay):
        if 'i' in nm:
            inds_show = [0, 2, 4, 6, 7, 8, 9, 10]
            inds_show_txt = [0, 2, 4, 9]
            Ay[4] *= .6
            Ay[9] *= 3e-4
            if '5' in nm:
                inds_show_txt = [0, 2, 4, 7]
                Ay[7] *= 8e-3
            if nm == 'i_s1':
                Ay[2] *= 1.8
                Ay[4] *= 4
                Ay2_HGW[3] *= 2.5
        else:
            if '001' in nm:
                inds_show = [0, 2, 3, 5, 6, 7, 8, 9]
                inds_show_txt = [0, 2, 7]
                Ay[2] *= .5
                Ay[7] *= 5e-5
            else:
                inds_show = [0, 1, 2, 3, 6, 7, 8, 9, 10, 11]
                inds_show_txt = [0, 2, 8]
                Ay[2] *= .5
                Ay[8] *= 2e-6
                if '5' in nm:
                    inds_show_txt = [0, 2, 7, 10]
                    Ay[2] *= 1.5
                    Ay[7] *= 1e-5
                    Ay[10] *= 3e-10
                if '7' in nm or '1' in nm:
                    inds_show_txt = [0, 2, 7, 9]
                    Ay[2] *= 2
                    Ay[7] *= 3e-6
                    Ay[9] *= 3e-9
        return inds_show, inds_show_txt, Ax, Ay

    # chose indices to show power law fits and text with k^(a/b) for GW
    # helicity spectrum HGW(k)
    def indices_HGW(nm, Ax, Ay):
        inds_show = []
        inds_show_txt = []
        if 'i' in nm:
            inds_show = [3, 5, 6, 7, 8]
            inds_show_txt = [3]
            if '3' in nm or '5' in nm:
                inds_show = [1, 2, 3, 5, 6, 7, 8]
                if '3' in nm:
                    inds_show_txt = [1, 2, 3]
                    Ay[1] *= .3
                    Ay[2] *= 1.5
                    Ay[3] *= 3.5
                if '5' in nm:
                    inds_show_txt = [2, 3]
                    Ax[2] *= .9
                    Ay[3] *= 1.5
                if nm == 'i_s1': Ay[3] *= 2.5
        else:
            if '001' not in nm:
                inds_show = [2, 5, 6, 7, 8, 9]
                inds_show_txt = [2, 6]
                Ay[6] *= 1e-6
                Ax[6] *= .8
                if '5' in nm:
                    inds_show_txt = [2, 5]
                    Ay[2] *= 2
                    Ay[5] *= 1.3e-4
                    Ax[5] *= .7
                if '7' in nm or '1' in nm:
                    Ay[2] *= 1.3
                    Ay[6] *= .35
                    Ax[6] *= .9
        return inds_show, inds_show_txt, Ax, Ay

    plt.rcParams.update({
        'xtick.labelsize': 'xx-large',
        'ytick.labelsize': 'xx-large',
        'axes.labelsize': 'xx-large'
    })

    name = run.name_run
    k = run.spectra.get('k')[1:]
    t = run.spectra.get('t_helmag')
    # read magnetic spectra
    if run.turb == 'k':
        EM = np.array(run.spectra.get('kin')[:, 1:], dtype='float')
        HkM = np.array(run.spectra.get('helkin_comp')[:, 1:], dtype='float')
    if run.turb == 'm':
        EM = np.array(run.spectra.get('mag')[:, 1:], dtype='float')
        HkM = np.array(run.spectra.get('helmag_comp')[:, 1:], dtype='float')
    # read GW spectra
    min_GWs = np.array(run.spectra.get('EGW_min_sp'), dtype='float')
    max_GWs = np.array(run.spectra.get('EGW_max_sp'), dtype='float')
    mean_GWs = np.array(run.spectra.get('EGW_stat_sp'), dtype='float')
    min_pos_HGWs = abs(
        np.array(run.spectra.get('helEGW_pos_min_sp'), dtype='float'))
    min_neg_HGWs = abs(
        np.array(run.spectra.get('helEGW_neg_min_sp'), dtype='float'))
    max_pos_HGWs = abs(
        np.array(run.spectra.get('helEGW_pos_max_sp'), dtype='float'))
    max_neg_HGWs = abs(
        np.array(run.spectra.get('helEGW_neg_max_sp'), dtype='float'))
    mean_HGWs = np.array(run.spectra.get('helEGW_stat_sp'), dtype='float')

    # get time that corresponds to maximum of magnetic energy density tini
    dtk = t[1] - t[0]
    indt = np.where(abs(t - run.tini) <= dtk / 2)[0][0]

    fig, ax = plt.subplots(figsize=(12, 10))
    plt.xscale('log')
    plt.yscale('log')
    #plt.text(3e4, 4e-23, '$k$', fontsize=30)
    plt.xlabel('$k$')
    TT = 'M'
    if run.turb == 'k': TT = 'K'
    plt.title(r'$E_{\rm %s, GW} (k)$ and $H_{\rm %s, GW} (k)$' % (TT, TT),
              fontsize=30,
              pad=15)

    # specific options for the plots
    N_EM, Ay2_EM, Ax_EM = init_Ay2_Ax(12, 2., 1.)
    N_HM, Ay2_HM, Ax_HM = init_Ay2_Ax(10, .04, 1.)
    N_EGW, Ay2_EGW, Ax_EGW = init_Ay2_Ax(12, 2.5, 1.)
    N_HGW, Ay2_HGW, Ax_HGW = init_Ay2_Ax(10, .08, .8)
    Ay_HGW = .2
    Ay_HM = .2
    if 'i' in name:
        xleg = 1.5e4
        yleg = 5e-13
    else:
        xleg = 8e2
        yleg = 5e-20

    if '001' in name: yks_H = False
    else: yks_H = True
    # choose indices for which to show the power law fits and the power law
    # text above the fit for each of the runs
    inds_show_EM, inds_show_txt_EM, Ax_EM, Ay2_EM = \
            indices_EM(name, Ax_EM, Ay2_EM)
    inds_show_HM, inds_show_txt_HM, Ax_HM, Ay2_HM = \
            indices_HM(name, Ax_HM, Ay2_HM)
    inds_show_EGW, inds_show_txt_EGW, Ax_EGW, Ay2_EGW = \
            indices_EGW(name, Ax_EGW, Ay2_EGW)
    inds_show_HGW, inds_show_txt_HGW, Ax_HGW, Ay2_HGW = \
            indices_HGW(name, Ax_HGW, Ay2_HGW)

    if 'i' in name: str_typ = 'ini'
    else: str_typ = 'forc'
    if name == 'M0': sig_val = '0'
    if '01' in name and 'i' in name: sig_val = '0.1'
    if '01' in name and 'M' in name: sig_val = '0.1'
    if '01' in name and 'K' in name: sig_val = '0.1'
    if '3' in name: sig_val = '0.3'
    if '5' in name: sig_val = '0.5'
    if '7' in name: sig_val = '0.7'
    if name == 'i_s1': sig_val = '1'
    if name == 'M1' or name == 'K1': sig_val = '1'
    if '001' in name and 'f' in name:
        if 'neg' in name: sig_val = '-0.01'
        else: sig_val = '0.01'
    if name == 'f_s1_neg': sig_val = '-1'
    str_leg = r'$\sigma^{\rm %s}_{\rm M}=%s$' % (str_typ, sig_val)

    plot_st(k,
            EM[indt, :],
            yks=True,
            N=N_EM,
            inds_show=inds_show_EM,
            inds_show_txt=inds_show_txt_EM,
            Ay=4,
            Ay2=Ay2_EM,
            Ax=Ax_EM)

    plot_st(k,
            HkM[indt, :],
            hel=True,
            yks=yks_H,
            N=N_HM,
            inds_show=inds_show_HM,
            inds_show_txt=inds_show_txt_HM,
            Ay=Ay_HM,
            Ay2=Ay2_HM,
            Ax=Ax_HM)

    plot_st(k,
            mean_GWs,
            fb=True,
            yv=True,
            min_sp=min_GWs,
            max_sp=max_GWs,
            yks=True,
            N=N_EGW,
            inds_show=inds_show_EGW,
            Ax=Ax_EGW,
            inds_show_txt=inds_show_txt_EGW,
            Ay=4,
            Ay2=Ay2_EGW)

    plot_st(k,
            mean_HGWs,
            hel=True,
            fb=True,
            yv=True,
            min_sp_neg=min_neg_HGWs,
            max_sp_neg=max_neg_HGWs,
            min_sp_pos=min_pos_HGWs,
            max_sp_pos=max_pos_HGWs,
            yks=yks_H,
            N=N_HGW,
            inds_show=inds_show_HGW,
            inds_show_txt=inds_show_txt_HGW,
            Ay=Ay_HGW,
            Ay2=Ay2_HGW,
            Ax=Ax_HGW)

    handles = []
    line_mag, = ax.plot([], [],
                        '-',
                        color='black',
                        label=r'$E_{\rm %s}(k)$' % TT)
    line_helpos, = ax.plot([], [],
                           '.',
                           label=r'$+\frac{1}{2} k H_{\rm %s}(k)$' % TT,
                           color='red')
    line_helneg, = ax.plot([], [],
                           '.',
                           label=r'$-\frac{1}{2} k H_{\rm %s}(k)$' % TT,
                           color='blue')
    line_GW, = ax.plot([], [], color='black', label=r'$E_{\rm GW}(k)$')
    line_HGWpos, = ax.plot([], [],
                           '.',
                           label=r'$+H_{\rm GW} (k)$',
                           color='red')
    line_HGWneg, = ax.plot([], [],
                           '.',
                           label=r'$-H_{\rm GW}(k)$',
                           color='blue')
    handles = [line_mag, line_helpos, line_helneg]
    lgd1 = ax.legend(handles=handles,
                     loc='upper right',
                     fontsize=23,
                     frameon=False)
    handles2 = [line_GW, line_HGWpos, line_HGWneg]
    lgd2 = plt.legend(handles=handles2,
                      loc='lower left',
                      fontsize=23,
                      frameon=False)
    ax = plt.gca()
    ax.add_artist(lgd1)

    plt.yticks(
        [1e-21, 1e-19, 1e-17, 1e-15, 1e-13, 1e-11, 1e-9, 1e-7, 1e-5, 1e-3])
    plot_sets.axes_lines()
    plt.tick_params(axis='y', direction='out', length=10)

    plt.text(xleg,
             yleg,
             str_leg,
             fontsize=30,
             bbox=dict(facecolor='white',
                       edgecolor='black',
                       boxstyle='round,pad=.5'))

    plt.xlim(100, 8e4)
    plt.ylim(1e-21, 1e-3)
    if save:
        plt.savefig('plots/' + run.name_run + 'EM_EGW.pdf',
                    bbox_inches='tight')