diff --git a/doc/source/nb/AnalyticFluence.ipynb b/doc/source/nb/AnalyticFluence.ipynb index 6705162ea..671629c84 100644 --- a/doc/source/nb/AnalyticFluence.ipynb +++ b/doc/source/nb/AnalyticFluence.ipynb @@ -27,7 +27,7 @@ "\n", "from snewpy import snowglobes, model_path\n", "from snewpy.flavor import ThreeFlavor\n", - "from snewpy.models.ccsn import Analytic3Species\n", + "from snewpy.models.base import Analytic3Species\n", "\n", "mpl.rc('font', size=14)\n", "\n", diff --git a/doc/source/nb/README.md b/doc/source/nb/README.md index 4e02b194c..8e7f06384 100644 --- a/doc/source/nb/README.md +++ b/doc/source/nb/README.md @@ -8,7 +8,7 @@ These directories contain notebooks demonstrating how to use the core-collapse a ## AnalyticFluence -This notebook demonstrates how to use the `Analytic3Species` class from `snewpy.models` to create an analytic supernova model by specifying the luminosity, mean energy and mean squared energy for three neutrino flavors. +This notebook demonstrates how to use the `Analytic3Species` class from `snewpy.models.base` to create an analytic supernova model by specifying the luminosity, mean energy and mean squared energy for three neutrino flavors. ## FlavorTransformation @@ -16,7 +16,7 @@ This notebook demonstrates the flavor transformations available in `snewpy.flavo ## SNOwGLoBES_models -This notebook demonstrates how to use the `SNOwGLoBES` class in `snewpy.models`, which can be used with the `Type_Ia` and `PISN` model files that are available for download through SNEWPY. +This notebook demonstrates how to use the `SNOwGLoBES` class in `snewpy.models.base`, which can be used with the `Type_Ia` and `PISN` model files that are available for download through SNEWPY. ## SNOwGLoBES_usage @@ -25,4 +25,4 @@ This notebook demonstrates how to use SNEWPY’s `snewpy.snowglobes` module to i ## `dev` Directory This directory contains notebooks which may be under development or illustrate usage of internal/undocumented APIs. -They are not recommended for general users. \ No newline at end of file +They are not recommended for general users. diff --git a/doc/source/nb/SNOwGLoBES_models.ipynb b/doc/source/nb/SNOwGLoBES_models.ipynb index 7842a8bd2..c60c71cf7 100644 --- a/doc/source/nb/SNOwGLoBES_models.ipynb +++ b/doc/source/nb/SNOwGLoBES_models.ipynb @@ -19,7 +19,7 @@ "metadata": {}, "outputs": [], "source": [ - "from snewpy.models.ccsn import SNOwGLoBES\n", + "from snewpy.models.base import SNOwGLoBES\n", "\n", "import matplotlib as mpl\n", "import matplotlib.pyplot as plt\n", diff --git a/python/snewpy/models/base.py b/python/snewpy/models/base.py index c8b153008..34f90d3f3 100644 --- a/python/snewpy/models/base.py +++ b/python/snewpy/models/base.py @@ -204,6 +204,86 @@ def get_value(x): return x.value return x + +class SNOwGLoBES: + """A model that does not inherit from SupernovaModel (yet) and imports a group of SNOwGLoBES files.""" + + def __init__(self, tarfilename): + """ + Parameters + ---------- + tarfilename: str + Absolute or relative path to tar archive with SNOwGLoBES files. + """ + self.tfname = tarfilename + tf = tarfile.open(self.tfname) + + # For now just pull out the "NoOsc" files. + datafiles = sorted([f.name for f in tf if '.dat' in f.name]) + noosc = [df for df in datafiles if 'NoOsc' in df] + noosc.sort(key=len) + + # Loop through the noosc files and pull out the number fluxes. + self.time = [] + self.energy = None + self.flux = {} + self.fmin = 1e99 + self.fmax = -1e99 + + for nooscfile in noosc: + 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 ['NuE', 'NuMu', 'NuTau', 'aNuE', 'aNuMu', 'aNuTau']: + if flavor in self.flux: + self.flux[flavor].append(data[flavor].data.tolist()) + else: + self.flux[flavor] = [data[flavor].data.tolist()] + + # We now have a table with rows=times and columns=energies. Transpose + # so that rows=energy and cols=time. + for k, v in self.flux.items(): + self.flux[k] = np.transpose(self.flux[k]) + self.fmin = np.minimum(self.fmin, np.min(self.flux[k])) + self.fmax = np.maximum(self.fmax, np.max(self.flux[k])) + + def get_fluence(self, t): + """Return the fluence at a given time t. + + Parameters + ---------- + t : float + Time in seconds. + + Returns + ------- + fluence : dict + A dictionary giving fluence at time t, keyed by flavor. + """ + # Get index of closest element in the array + idx = np.abs(np.asarray(self.time) - t).argmin() + + fluence = {} + for k, fl in self.flux.items(): + fluence[k] = fl[:,idx] + + return fluence + + class PinchedModel(SupernovaModel): """Subclass that contains spectra/luminosity pinches""" def __init__(self, simtab, metadata): @@ -286,3 +366,27 @@ def _get_initial_spectra_dict(self, t, E, flavors=ThreeFlavor): initialspectra[flavor] = result return initialspectra + + +class Analytic3Species(PinchedModel): + """An analytical model calculating spectra given total luminosity, + average energy, and rms or pinch, for each species. + """ + + param = "There are no input files available for this class. Use `doc/scripts/Analytic.py` in the SNEWPY GitHub repo to create a custom input file." + + def get_param_combinations(cls): + print(cls.param) + return [] + + def __init__(self, filename): + """ + Parameters + ---------- + filename : str + Absolute or relative path to file with model data. + """ + + simtab = Table.read(filename,format='ascii') + self.filename = filename + super().__init__(simtab, metadata={}) diff --git a/python/snewpy/models/ccsn.py b/python/snewpy/models/ccsn.py index 0bf0ad9aa..07e81b229 100644 --- a/python/snewpy/models/ccsn.py +++ b/python/snewpy/models/ccsn.py @@ -35,7 +35,6 @@ class method to get a list of all valid combinations and filter it: from astropy.table import Table from snewpy.models import ccsn_loaders as loaders -from .base import PinchedModel from snewpy.models.registry_model import RegistryModel, Parameter from snewpy.models.registry_model import all_models @@ -392,103 +391,3 @@ def __init__(self, *, Bfield:str, direction:str, rotation:int=None, grav:str=Non filename = f'{Bfield}_b12_3d_{rotation}deg_snewpy_{direction}.dat' return super().__init__(filename=filename, metadata=self.metadata) -class SNOwGLoBES: - """A model that does not inherit from SupernovaModel (yet) and imports a group of SNOwGLoBES files.""" - - def __init__(self, tarfilename): - """ - Parameters - ---------- - tarfilename: str - Absolute or relative path to tar archive with SNOwGLoBES files. - """ - self.tfname = tarfilename - tf = tarfile.open(self.tfname) - - # For now just pull out the "NoOsc" files. - datafiles = sorted([f.name for f in tf if '.dat' in f.name]) - noosc = [df for df in datafiles if 'NoOsc' in df] - noosc.sort(key=len) - - # Loop through the noosc files and pull out the number fluxes. - self.time = [] - self.energy = None - self.flux = {} - self.fmin = 1e99 - self.fmax = -1e99 - - for nooscfile in noosc: - 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 ['NuE', 'NuMu', 'NuTau', 'aNuE', 'aNuMu', 'aNuTau']: - if flavor in self.flux: - self.flux[flavor].append(data[flavor].data.tolist()) - else: - self.flux[flavor] = [data[flavor].data.tolist()] - - # We now have a table with rows=times and columns=energies. Transpose - # so that rows=energy and cols=time. - for k, v in self.flux.items(): - self.flux[k] = np.transpose(self.flux[k]) - self.fmin = np.minimum(self.fmin, np.min(self.flux[k])) - self.fmax = np.maximum(self.fmax, np.max(self.flux[k])) - - def get_fluence(self, t): - """Return the fluence at a given time t. - - Parameters - ---------- - t : float - Time in seconds. - - Returns - ------- - fluence : dict - A dictionary giving fluence at time t, keyed by flavor. - """ - # Get index of closest element in the array - idx = np.abs(np.asarray(self.time) - t).argmin() - - fluence = {} - for k, fl in self.flux.items(): - fluence[k] = fl[:,idx] - - return fluence - -class Analytic3Species(PinchedModel): - """An analytical model calculating spectra given total luminosity, - average energy, and rms or pinch, for each species. - """ - - param = "There are no input files available for this class. Use `doc/scripts/Analytic.py` in the SNEWPY GitHub repo to create a custom input file." - - def get_param_combinations(cls): - print(cls.param) - return [] - - def __init__(self, filename): - """ - Parameters - ---------- - filename : str - Absolute or relative path to file with model data. - """ - - simtab = Table.read(filename,format='ascii') - self.filename = filename - super().__init__(simtab, metadata={}) diff --git a/python/snewpy/models/model_files.yml b/python/snewpy/models/model_files.yml index 3e9b9840d..601251437 100644 --- a/python/snewpy/models/model_files.yml +++ b/python/snewpy/models/model_files.yml @@ -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: @@ -73,3 +74,10 @@ models: Yoshida_2016: repository: *presn_repository + + pisn_typeIa: + TypeIa: + repository: *pisn_typeIa_repository + + Wright_2017: + repository: *pisn_typeIa_repository diff --git a/python/snewpy/scripts/Analytic.py b/python/snewpy/scripts/Analytic.py index d681207f7..fe020f0a5 100644 --- a/python/snewpy/scripts/Analytic.py +++ b/python/snewpy/scripts/Analytic.py @@ -1,5 +1,5 @@ """This model stub allows one to generate simple analytic models and then -read them into the Analytic3Species model found in model.py which is part of SNEWPY. +read them into the Analytic3Species model found in models.base.py which is part of SNEWPY. """ from astropy.table import Table