Fornax 2022 Models

Neutrino spectra from the 2D long-duraction models produced for 100 progenitors (1/3 form black holes).

Data take from the Princeton group webpage and converted to HDF5 format for use in SNEWPY.

[1]:
from snewpy.neutrino import Flavor
from snewpy.models.ccsn import Fornax_2022

from astropy import units as u

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
[2]:
mpl.rc('font', size=16)

Initialize Models

To start, see what progenitors are avaialble for the Fornax_2022 model. Use the param property to view all physics parameters and their possible values.

[3]:
Fornax_2022.param
[3]:
{'progenitor_mass': <Quantity [ 9.  ,  9.25,  9.5 ,  9.75, 10.  , 10.25, 10.5 , 10.75, 11.  ,
            11.25, 11.5 , 11.75, 12.  , 12.03, 12.07, 12.1 , 12.13, 12.15,
            12.18, 12.2 , 12.25, 12.33, 12.4 , 12.45, 12.5 , 12.54, 12.6 ,
            12.63, 12.7 , 12.72, 12.75, 12.8 , 12.85, 12.9 , 12.93, 12.97,
            13.  , 13.05, 13.11, 13.25, 13.27, 13.32, 13.4 , 13.45, 13.5 ,
            13.6 , 13.75, 13.82, 13.9 , 13.96, 14.01, 14.13, 14.25, 14.4 ,
            14.41, 14.43, 14.44, 14.7 , 14.87, 15.  , 15.01, 15.04, 15.05,
            15.38, 16.43, 16.65, 16.99, 17.  , 17.07, 17.1 , 17.4 , 17.48,
            17.5 , 17.51, 17.83, 18.04, 18.05, 18.09, 18.1 , 18.5 , 19.02,
            19.56, 19.83, 19.99, 20.08, 20.09, 20.18, 20.37, 21.  , 21.68,
            22.  , 22.3 , 22.82, 23.  , 23.04, 23.43, 24.  , 25.  , 26.  ,
            26.99] solMass>}

Initialize some progenitors and plot the luminosity of different neutrino flavors for two of them. Note that the Fornax_2022 set of models do not distinguish between \(\nu_x\) and \(\bar{\nu}_x\) so both have the same luminosity. If this is the first time you are using a progenitor model, snewpy will download the data files for you.

[4]:
models = {}
for m in Fornax_2022.param['progenitor_mass'][::19]:
    # Initialize every 20th progenitor.
    print(m)
    models[m] = Fornax_2022(progenitor_mass=m)

models
9.0 solMass
12.2 solMass
13.11 solMass
14.7 solMass
18.05 solMass
23.43 solMass
[4]:
{<Quantity 9. solMass>: Fornax_2022 Model
 Progenitor mass  : 9.0 solMass
 Black hole       : False
 PNS mass         : 1.35 solMass,
 <Quantity 12.2 solMass>: Fornax_2022 Model
 Progenitor mass  : 12.2 solMass
 Black hole       : True
 PNS mass         : 1.69 solMass,
 <Quantity 13.11 solMass>: Fornax_2022 Model
 Progenitor mass  : 13.11 solMass
 Black hole       : False
 PNS mass         : 1.78 solMass,
 <Quantity 14.7 solMass>: Fornax_2022 Model
 Progenitor mass  : 14.7 solMass
 Black hole       : True
 PNS mass         : 1.89 solMass,
 <Quantity 18.05 solMass>: Fornax_2022 Model
 Progenitor mass  : 18.05 solMass
 Black hole       : False
 PNS mass         : 1.84 solMass,
 <Quantity 23.43 solMass>: Fornax_2022 Model
 Progenitor mass  : 23.43 solMass
 Black hole       : False
 PNS mass         : 1.98 solMass}
[5]:
models[23.43*u.solMass].metadata
[5]:
{'Progenitor mass': <Quantity 23.43 solMass>,
 'Black hole': False,
 'PNS mass': <Quantity 1.98 solMass>}
[6]:
fig, axes = plt.subplots(3, 2, figsize=(12, 15), sharex=True, sharey=True, tight_layout=True)
axes = axes.flatten()

for i, (key, model) in enumerate(models.items()):
    ax = axes[i]
    for flavor in Flavor:
        ax.plot(model.time, model.luminosity[flavor]/1e51,  # Report luminosity in units foe/s
                label=flavor.to_tex(),
                color='C0' if flavor.is_electron else 'C1',
                ls='-' if flavor.is_neutrino else ':',
                lw=2)

    modtitle = rf"{model.metadata['Progenitor mass'].value} $M_\odot$"
    if model.metadata['Black hole']:
        modtitle += ' (BH)'

    ax.set(xlim=(-0.05, 1.5),
           xlabel=r'$t-t_{\rm bounce}$ [s]',
           title=modtitle)
    ax.grid()
    ax.legend(loc='upper right', ncol=2, fontsize=18)

axes[0].set(ylabel=r'luminosity [foe s$^{-1}$]');
# axes[5].set_axis_off();
../../_images/nb_ccsn_Fornax_2022_8_0.png

Spectra of All Flavors vs. Time for the 19.02 \(M_\odot\) Model

Use Default Linear Interpolation in Flux Retrieval

[7]:
model = models[23.43*u.solMass]

times = np.arange(-0.2, 3.8, 0.2) * u.s
E = np.arange(0, 101, 1) * u.MeV

fig, axes = plt.subplots(5,4, figsize=(15,12), sharex=True, sharey=True, tight_layout=True)

linestyles = ['-', '--', '-.', ':']

spectra = model.get_initial_spectra(times, E)

for i, ax in enumerate(axes.flatten()):
    for line, flavor in zip(linestyles, Flavor):
        ax.plot(E, spectra[flavor][i], lw=3, ls=line, label=flavor.to_tex())
    ax.set(xlim=(0,100))
    ax.set_title('$t$ = {:g}'.format(times[i]), fontsize=16)
    ax.legend(loc='upper right', ncol=2, fontsize=12)

fig.text(0.5, 0., 'energy [MeV]', ha='center')
fig.text(0., 0.5, f'flux [{spectra[Flavor.NU_E].unit}]', va='center', rotation='vertical');
../../_images/nb_ccsn_Fornax_2022_10_0.png

Use Nearest-Bin “Interpolation” in Flux Retrieval

[8]:
times = np.arange(-0.2, 3.8, 0.2) * u.s
E = np.arange(0, 101, 1) * u.MeV

fig, axes = plt.subplots(5,4, figsize=(15,12), sharex=True, sharey=True, tight_layout=True)

linestyles = ['-', '--', '-.', ':']

spectra = model.get_initial_spectra(times, E, interpolation='nearest')

for i, ax in enumerate(axes.flatten()):
    for line, flavor in zip(linestyles, Flavor):
        ax.plot(E, spectra[flavor][i], lw=3, ls=line, label=flavor.to_tex())
    ax.set(xlim=(0,100))
    ax.set_title('$t$ = {:g}'.format(times[i]), fontsize=16)
    ax.legend(loc='upper right', ncol=2, fontsize=12)

fig.text(0.5, 0., 'energy [MeV]', ha='center')
fig.text(0., 0.5, f'flux [{spectra[Flavor.NU_E].unit}]', va='center', rotation='vertical');
../../_images/nb_ccsn_Fornax_2022_12_0.png

Progenitor Mass Dependence

Luminosity vs. Time for a Selected List of Progenitor Masses

Plot \(L_{\nu_e}(t)\) for a selection of progenitor masses to observe the dependence of the emission on mass.

[9]:
fig, axes = plt.subplots(3,1, figsize=(10,13), sharex=True, sharey=True,
                         gridspec_kw = {'hspace':0.02})

colors0 = mpl.cm.viridis(np.linspace(0.1,0.9, len(models)))
colors1 = mpl.cm.inferno(np.linspace(0.1,0.9, len(models)))
colors2 = mpl.cm.cividis(np.linspace(0.1,0.9, len(models)))

linestyles = ['-', '--', '-.', ':']

for i, model in enumerate(models.values()):
    ax = axes[0]
    flavor = Flavor.NU_E
    ax.plot(model.time, model.luminosity[flavor], lw=2, color=colors0[i], ls=linestyles[i%4],
            label='${0.value:g}$ {0.unit:latex}{1}'.format(model.progenitor_mass, ' (BH)' if 'bh' in model.progenitor else ''))
    ax.set(xscale='log',
           xlim=(1e-3, 4),
           yscale='log',
           ylim=(0.4e52, 9e53),
           ylabel=r'$L_{\nu_e}(t)$ [erg s$^{-1}$]')
    ax.grid(ls=':', which='both')
    ax.legend(ncol=3, fontsize=12, title=r'$\nu_e$');

    ax = axes[1]
    flavor = Flavor.NU_E_BAR
    ax.plot(model.time, model.luminosity[flavor], lw=2, color=colors1[i], ls=linestyles[i%4],
        label='${0.value:g}$ {0.unit:latex}{1}'.format(model.progenitor_mass, ' (BH)' if 'bh' in model.progenitor else ''))
    ax.set(ylabel=r'$L_{\bar{\nu}_e}(t)$ [erg s$^{-1}$]')
    ax.grid(ls=':', which='both')
    ax.legend(ncol=3, fontsize=12, title=r'$\bar{\nu}_e$');

    ax = axes[2]
    flavor = Flavor.NU_X
    ax.plot(model.time, model.luminosity[flavor], lw=2, color=colors2[i], ls=linestyles[i%4],
        label='${0.value:g}$ {0.unit:latex}{1}'.format(model.progenitor_mass, ' (BH)' if 'bh' in model.progenitor else ''))
    ax.set(xlabel='time [s]',
           ylabel=r'$L_{\nu_X}(t)$ [erg s$^{-1}$]')
    ax.grid(ls=':', which='both')
    ax.legend(ncol=3, fontsize=12, title=r'$\nu_X$');
../../_images/nb_ccsn_Fornax_2022_14_0.png

Progenitor Dependence of Spectra at 70 ms

Use Default Linear Interpolation in Flux Retrieval

[10]:
t = 70*u.ms
E = np.arange(0, 101, 1) * u.MeV

fig, axes = plt.subplots(2,3, figsize=(12,6), sharex=True, sharey=True, tight_layout=True)

linestyles = ['-', '--', '-.', ':']

for model, ax in zip(models.values(), axes.flatten()):
    spectra = model.get_initial_spectra(t, E)
    for line, flavor in zip(linestyles, Flavor):
        ax.plot(E, spectra[flavor][0], lw=3, ls=line, label=flavor.to_tex())
    ax.set(xlim=(0,100))
    ax.set_title('${0.value:g}$ {0.unit:latex}{1}'.format(model.progenitor_mass, ' (BH)' if 'bh' in model.progenitor else ''))
    ax.legend(loc='upper right', ncol=2, fontsize=12)
    ax.grid(ls=':')

fig.text(0.5, 0., 'energy [MeV]', ha='center')
fig.text(0., 0.5, f'flux [{spectra[Flavor.NU_E].unit}]', va='center', rotation='vertical');
../../_images/nb_ccsn_Fornax_2022_16_0.png

Use Nearest-Bin “Interpolation” in Flux Retrieval

[11]:
t = 70*u.ms
E = np.arange(0, 101, 1) * u.MeV

fig, axes = plt.subplots(2,3, figsize=(12,6), sharex=True, sharey=True, tight_layout=True)

linestyles = ['-', '--', '-.', ':']

for model, ax in zip(models.values(), axes.flatten()):
    spectra = model.get_initial_spectra(t, E, interpolation='nearest')
    for line, flavor in zip(linestyles, Flavor):
        ax.plot(E, spectra[flavor][0], lw=3, ls=line, label=flavor.to_tex())
    ax.set(xlim=(0,100))
    ax.set_title('${0.value:g}$ {0.unit:latex}{1}'.format(model.progenitor_mass, ' (BH)' if 'bh' in model.progenitor else ''))
    ax.legend(loc='upper right', ncol=2, fontsize=12)
    ax.grid(ls=':')

fig.text(0.5, 0., 'energy [MeV]', ha='center')
fig.text(0., 0.5, f'flux [{spectra[Flavor.NU_E].unit}]', va='center', rotation='vertical');
../../_images/nb_ccsn_Fornax_2022_18_0.png