Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
247 changes: 247 additions & 0 deletions doc/source/nb/pisn/Wright_2017.ipynb

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions python/snewpy/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def _wrapper(self, *arg, **kwargs):
init(self, *arg, **kwargs)
check(self)
return _wrapper

class SupernovaModel(ABC, LocalFileLoader):
"""Base class defining an interface to a supernova model."""

Expand Down Expand Up @@ -132,10 +132,10 @@ def get_initial_spectra(self, t, E):
A container with the information about the initial neutrino spectra
"""
spectra_dict = self._get_initial_spectra_dict(t, E, flavors=ThreeFlavor)
initial_spectra = flux.Container['1/(MeV*s)'].from_dict(spectra_dict,
time=t,
energy=E,
flavor_scheme=ThreeFlavor)
initial_spectra = flux.Spectrum.from_dict(spectra_dict,
time=t,
energy=E,
flavor_scheme=ThreeFlavor)
return initial_spectra

def get_transformed_spectra(self, t, E, flavor_xform):
Expand All @@ -155,8 +155,8 @@ def get_transformed_spectra(self, t, E, flavor_xform):
flux.Container
A container with the information of the transformed neutrino spectra
"""
initialspectra = self.get_initial_spectra(t, E)
transformed_spectra = flavor_xform.apply_to(initialspectra)
initial_spectra = self.get_initial_spectra(t, E)
transformed_spectra = flavor_xform.apply_to(initial_spectra)
return transformed_spectra

def get_flux (self, t, E, distance, flavor_xform=NoTransformation()):
Expand Down Expand Up @@ -249,7 +249,7 @@ def _get_initial_spectra_dict(self, t, E, flavors=ThreeFlavor):
#Reshape the Energy array to shape [1,len(E)]
E = np.expand_dims(E, axis=0)

initialspectra = {}
initial_spectra = {}

# Estimate L(t), <E_nu(t)> and alpha(t). Express all energies in erg.
E = E.to_value('erg')
Expand Down Expand Up @@ -283,6 +283,6 @@ def _get_initial_spectra_dict(self, t, E, flavors=ThreeFlavor):

#remove unnecessary dimensions, if E or t was scalar:
result = np.squeeze(result)
initialspectra[flavor] = result
initial_spectra[flavor] = result

return initialspectra
return initial_spectra
11 changes: 11 additions & 0 deletions python/snewpy/models/model_files.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ config:
- &snewpy "https://github.com/SNEWS2/snewpy/raw/v{snewpy_version}/models/{model}/{filename}"
- &ccsn_repository "https://github.com/SNEWS2/snewpy-models-ccsn/raw/v0.3/models/{model}/{filename}"
- &presn_repository "https://github.com/SNEWS2/snewpy-models-presn/raw/v0.2/models/{model}/{filename}"
- &pisn_typeIa_repository "https://github.com/SNEWS2/snewpy-models-pisn_typeIa/raw/v0.1/models/{model}/{filename}"

models:
ccsn:
Expand Down Expand Up @@ -73,3 +74,13 @@ models:

Yoshida_2016:
repository: *presn_repository

pisn:
Wright_2017:
repository: *pisn_typeIa_repository

typeIa:
TypeIa:
repository: *pisn_typeIa_repository


36 changes: 36 additions & 0 deletions python/snewpy/models/pisn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
"""
The submodule ``snewpy.models.pisn`` contains models of pair-instability supernova neutrino fluxes,
"""
import logging
import os

from astropy import units as u

from snewpy.models import pisn_loaders as loaders
from .base import SupernovaModel

from snewpy.models.registry_model import RegistryModel, Parameter
from snewpy.models.registry_model import all_models

@RegistryModel(
progenitor_mass = [150, 250] * u.Msun,
eos = ['SFHo', 'Helm']
)
class Wright_2017(loaders.Wright_2017):
"""PISN model described in the paper `Neutrino signal from pair-instability supernovae' by Wright et al.,
Phys. Rev. D96 (2017) 103008 <https://journals.aps.org/prd/abstract/10.1103/PhysRevD.96.103008>`_
"""
def _metadata_from_filename(self, filename:str):
metadata = {
'Progenitor mass': float(filename.split('_')[1].strip('Msun')) * u.Msun,
'EOS': filename.split('_')[2].strip('EOS=')
}
return metadata

def __init__(self, progenitor_mass:u.Quantity, eos:str):
filename=f"PISN_{progenitor_mass.to_value('Msun'):.0f}Msun_EOS={eos}_NeutrinoFlux.tar.bz2"
super().__init__(filename, self.metadata)



124 changes: 124 additions & 0 deletions python/snewpy/models/pisn_loaders.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# -*- coding: utf-8 -*-
"""
The submodule ``snewpy.models.pisn_loaders`` contains classes to load pair-instability supernova
models from files stored on disk.
"""
import logging
import os
import numpy as np
import pandas as pd
import tarfile

from astropy import units as u
from astropy.table import Table

from scipy import interpolate

from snewpy.models.base import SupernovaModel
from snewpy.flavor import ThreeFlavor
from snewpy.flux import Spectrum
from snewpy import _model_downloader


class Wright_2017(SupernovaModel):
"""PISN model described in the paper `Neutrino signal from pair-instability supernovae' by Wright et al.,
Phys. Rev. D96 (2017) 103008 <https://journals.aps.org/prd/abstract/10.1103/PhysRevD.96.103008>`
"""

def __init__(self, filename, metadata={}):
"""
Parameters
----------
tarfilename: str
Absolute or relative path to tar archive
"""
# Open the requested filename using the model downloader.
datafile = self.request_file(filename)

tf = tarfile.open(datafile)

# Find the "NoOsc" files.
datafiles = sorted([f.name for f in tf if '.dat' in f.name])
nooscfiles = [df for df in datafiles if 'NoOsc' in df]
nooscfiles.sort(key=len)

# Loop through the NoOsc files and pull out the number fluxes.
self.time = []
self.energy = None
self.initial_spectra = {}
self.interpolation = {}

self._flavorkeys = {ThreeFlavor.NU_E: 'NuE',
ThreeFlavor.NU_E_BAR: 'aNuE',
ThreeFlavor.NU_MU: 'NuMu',
ThreeFlavor.NU_MU_BAR: 'aNuMu',
ThreeFlavor.NU_TAU: 'NuTau',
ThreeFlavor.NU_TAU_BAR: 'aNuTau'}

for nooscfile in nooscfiles:
with tf.extractfile(nooscfile) as f:
logging.debug('Reading {}'.format(nooscfile))
meta = f.readline()
metatext = meta.decode('utf-8')
t = float(metatext.split('TBinMid=')[-1].split('sec')[0])
dt = float(metatext.split('tBinWidth=')[-1].split('s')[0])
dE = float(metatext.split('eBinWidth=')[-1].split('MeV')[0])

data = Table.read(f, format='ascii.commented_header', header_start=-1)
data.meta['t'] = t
data.meta['dt'] = dt
data.meta['dE'] = dE

self.time.append(t)

if self.energy is None:
self.energy = (data['E(GeV)'].data*1000).tolist()

for flavor in ThreeFlavor:
key = self._flavorkeys[flavor]
# convert from flux back to initial spectra: number per /s/erg
spectrum = data[key].data.tolist() * (4*np.pi*(10*u.kpc)**2) /dt/dE
if flavor in self.initial_spectra:
self.initial_spectra[flavor].append(spectrum)
else:
self.initial_spectra[flavor] = [spectrum]

for flavor in ThreeFlavor:
self.interpolation[flavor] = interpolate.RegularGridInterpolator((self.time, self.energy), self.initial_spectra[flavor], method='cubic')

self.time *= u.s
self.energy *= u.MeV

self.filename = os.path.basename(filename)

def _get_initial_spectra_dict(self, t, E, flavors=ThreeFlavor):
"""Get neutrino spectra/luminosity curves after oscillation.

Parameters
----------
t : astropy.Quantity
Time to evaluate initial spectra.
E : astropy.Quantity or ndarray of astropy.Quantity
Energies to evaluate the initial spectra.
flavors: iterable of snewpy.neutrino.Flavor
Return spectra for these flavors only (default: all)

Returns
-------
spectra : dict
Dictionary of model spectra, keyed by neutrino flavor.
"""
#convert input arguments to 1D arrays
t = u.Quantity(t, ndmin=1)
E = u.Quantity(E, ndmin=1)

initial_spectra = {}
for flavor in ThreeFlavor:
initial_spectra[flavor] = self.interpolation[flavor]((t, E)) / (u.MeV * u.s)

return initial_spectra