Source code for species.core.box

"""
Module with the  ``Box`` classes and ``create_box`` function.
"""

from typing import List, Union

import numpy as np

from spectres import spectres

from species.phot.syn_phot import SyntheticPhotometry
from species.read.read_filter import ReadFilter
from species.util.spec_util import smooth_spectrum


[docs] class Box: """ Class for generic methods that can be applied on all `Box` object. """ def __init__(self): """ Returns ------- NoneType None """
[docs] def open_box(self): """ Method for inspecting the content of a `Box`. Returns ------- NoneType None """ print(f"Opening {type(self).__name__}...") for key, value in self.__dict__.items(): print(f"{key} = {value}")
[docs] class ColorMagBox(Box): """ Class for storing color-magnitude data in a :class:`~species.core.box.Box`. """ def __init__(self): """ Returns ------- NoneType None """ self.library = None self.iso_tag = None self.object_type = None self.filters_color = None self.filter_mag = None self.color = None self.magnitude = None self.names = None self.sptype = None self.mass = None self.radius = None
[docs] class ColorColorBox(Box): """ Class for storing color-color data in a :class:`~species.core.box.Box`. """ def __init__(self): """ Returns ------- NoneType None """ self.library = None self.iso_tag = None self.object_type = None self.filters = None self.color1 = None self.color2 = None self.names = None self.sptype = None self.mass = None self.radius = None
[docs] class CoolingBox(Box): """ Class for storing cooling curve data in a :class:`~species.core.box.Box`. """ def __init__(self): """ Returns ------- NoneType None """ self.model = None self.mass = None self.age = None self.teff = None self.log_lum = None self.logg = None self.radius = None self.filter_mag = None self.magnitude = None self.filters_color = None self.color = None
[docs] class IsochroneBox(Box): """ Class for storing isochrone data in a :class:`~species.core.box.Box`. """ def __init__(self): """ Returns ------- NoneType None """ self.model = None self.age = None self.mass = None self.teff = None self.log_lum = None self.logg = None self.radius = None self.filter_mag = None self.magnitude = None self.filters_color = None self.color = None
[docs] class PhotometryBox(Box): """ Class for storing photometric data in a :class:`~species.core.box.Box`. """ def __init__(self): """ Returns ------- NoneType None """ self.name = None self.sptype = None self.wavelength = None self.flux = None self.app_mag = None self.abs_mag = None self.filter_name = None
[docs] class ModelBox(Box): """ Class for storing a model spectrum in a :class:`~species.core.box.Box`. """ def __init__(self): """ Returns ------- NoneType None """ self.model = None self.type = None self.wavelength = None self.flux = None self.parameters = None self.quantity = None self.contribution = None self.bol_flux = None self.spec_res = None
[docs] def smooth_spectrum(self, spec_res: float) -> None: """ Method for smoothing the spectrum with a Gaussian kernel to the instrument resolution. The method is best applied on an input spectrum with a logarithmic wavelength sampling (i.e. constant spectral resolution). Alternatively, the wavelength sampling may be linear, but the smoothing is slower in that case. Parameters ---------- spec_res : float Spectral resolution that is used for the smoothing kernel. Returns ------- NoneType None """ self.flux = smooth_spectrum(self.wavelength, self.flux, spec_res)
[docs] def resample_spectrum(self, wavel_resample: np.ndarray) -> None: """ Method for resampling the spectrum with ``spectres`` to a new wavelength grid. Parameters ---------- wavel_resample : np.ndarray Wavelength points (um) to which the spectrum will be resampled. Returns ------- NoneType None """ self.flux = spectres( wavel_resample, self.wavelength, self.flux, spec_errs=None, fill=np.nan, verbose=True, ) self.wavelength = wavel_resample
[docs] def synthetic_photometry(self, filter_name: Union[str, List[str]]) -> PhotometryBox: """ Method for calculating synthetic photometry from the model spectrum that is stored in the ``ModelBox``. Parameters ---------- filter_name : str, list(str) Single filter name or a list of filter names for which synthetic photometry will be calculated. Returns ------- species.core.box.PhotometryBox Box with the synthetic photometry. """ if isinstance(filter_name, str): filter_name = [filter_name] list_wavel = [] list_flux = [] list_app_mag = [] list_abs_mag = [] for item in filter_name: synphot = SyntheticPhotometry(filter_name=item) syn_flux = synphot.spectrum_to_flux( wavelength=self.wavelength, flux=self.flux ) syn_mag = synphot.spectrum_to_magnitude( wavelength=self.wavelength, flux=self.flux ) list_flux.append(syn_flux) list_app_mag.append(syn_mag[0]) list_abs_mag.append(syn_mag[1]) filter_profile = ReadFilter(filter_name=item) list_wavel.append(filter_profile.mean_wavelength()) phot_box = create_box( boxtype="photometry", name=None, sptype=None, wavelength=list_wavel, flux=list_flux, app_mag=list_app_mag, abs_mag=list_abs_mag, filter_name=filter_name, ) return phot_box
[docs] class ObjectBox(Box): """ Class for storing object data in a :class:`~species.core.box.Box`. """ def __init__(self): """ Returns ------- NoneType None """ self.name = None self.filters = None self.mean_wavel = None self.magnitude = None self.flux = None self.spectrum = None self.parallax = None self.distance = None
[docs] class ResidualsBox(Box): """ Class for storing best-fit residuals in a :class:`~species.core.box.Box`. """ def __init__(self): """ Returns ------- NoneType None """ self.name = None self.photometry = None self.spectrum = None self.chi2_red = None
[docs] class SamplesBox(Box): """ Class for storing posterior samples in a :class:`~species.core.box.Box`. """ def __init__(self): """ Returns ------- NoneType None """ self.spectrum = None self.parameters = None self.samples = None self.ln_prob = None self.ln_evidence = None self.prob_sample = None self.median_sample = None self.attributes = None self.uniform_priors = None self.normal_priors = None
[docs] class SpectrumBox(Box): """ Class for storing spectral data in a :class:`~species.core.box.Box`. """ def __init__(self): """ Returns ------- NoneType None """ self.spectrum = None self.wavelength = None self.flux = None self.error = None self.name = None self.simbad = None self.sptype = None self.distance = None self.spec_res = None
[docs] class SynphotBox(Box): """ Class for storing synthetic photometry in a :class:`~species.core.box.Box`. """ def __init__(self): """ Returns ------- NoneType None """ self.name = None self.wavelength = None self.flux = None self.app_mag = None self.abs_mag = None
[docs] def create_box(boxtype, **kwargs): """ Function for creating a :class:`~species.core.box.Box`. Returns ------- species.core.box Box with the data and parameters. """ if boxtype == "colormag": box = ColorMagBox() box.library = kwargs["library"] box.object_type = kwargs["object_type"] box.filters_color = kwargs["filters_color"] box.filter_mag = kwargs["filter_mag"] box.color = kwargs["color"] box.magnitude = kwargs["magnitude"] if "names" in kwargs: box.names = kwargs["names"] if "sptype" in kwargs: box.sptype = kwargs["sptype"] if "mass" in kwargs: box.mass = kwargs["mass"] if "radius" in kwargs: box.radius = kwargs["radius"] if "iso_tag" in kwargs: box.iso_tag = kwargs["iso_tag"] if boxtype == "colorcolor": box = ColorColorBox() box.library = kwargs["library"] box.object_type = kwargs["object_type"] box.filters = kwargs["filters"] box.color1 = kwargs["color1"] box.color2 = kwargs["color2"] if "names" in kwargs: box.names = kwargs["names"] if "sptype" in kwargs: box.sptype = kwargs["sptype"] if "mass" in kwargs: box.mass = kwargs["mass"] if "radius" in kwargs: box.radius = kwargs["radius"] if "iso_tag" in kwargs: box.iso_tag = kwargs["iso_tag"] elif boxtype == "cooling": box = CoolingBox() box.model = kwargs["model"] box.mass = kwargs["mass"] if "age" in kwargs: box.age = kwargs["age"] else: box.age = kwargs["ages"] box.teff = kwargs["teff"] box.log_lum = kwargs["log_lum"] box.logg = kwargs["logg"] box.radius = kwargs["radius"] box.filter_mag = kwargs["filter_mag"] box.magnitude = kwargs["magnitude"] box.filters_color = kwargs["filters_color"] box.color = kwargs["color"] elif boxtype == "isochrone": box = IsochroneBox() box.model = kwargs["model"] box.age = kwargs["age"] if "mass" in kwargs: box.mass = kwargs["mass"] else: box.mass = kwargs["masses"] box.teff = kwargs["teff"] box.log_lum = kwargs["log_lum"] box.logg = kwargs["logg"] box.radius = kwargs["radius"] box.filter_mag = kwargs["filter_mag"] box.magnitude = kwargs["magnitude"] box.filters_color = kwargs["filters_color"] box.color = kwargs["color"] elif boxtype == "model": box = ModelBox() box.model = kwargs["model"] box.wavelength = kwargs["wavelength"] box.flux = kwargs["flux"] box.parameters = kwargs["parameters"] box.quantity = kwargs["quantity"] if "contribution" in kwargs: box.contribution = kwargs["contribution"] if "bol_flux" in kwargs: box.bol_flux = kwargs["bol_flux"] if "spec_res" in kwargs: box.spec_res = kwargs["spec_res"] elif boxtype == "object": box = ObjectBox() box.name = kwargs["name"] box.filters = kwargs["filters"] box.mean_wavel = kwargs["mean_wavel"] box.magnitude = kwargs["magnitude"] box.flux = kwargs["flux"] box.spectrum = kwargs["spectrum"] if "parallax" in kwargs: box.parallax = kwargs["parallax"] if "distance" in kwargs: box.distance = kwargs["distance"] elif boxtype == "photometry": box = PhotometryBox() if "name" in kwargs: box.name = kwargs["name"] if "sptype" in kwargs: box.sptype = kwargs["sptype"] if "wavelength" in kwargs: box.wavelength = kwargs["wavelength"] if "flux" in kwargs: box.flux = kwargs["flux"] if "app_mag" in kwargs: box.app_mag = kwargs["app_mag"] if "abs_mag" in kwargs: box.abs_mag = kwargs["abs_mag"] if "filter_name" in kwargs: box.filter_name = kwargs["filter_name"] elif boxtype == "residuals": box = ResidualsBox() box.name = kwargs["name"] box.photometry = kwargs["photometry"] box.spectrum = kwargs["spectrum"] if "chi2_red" in kwargs: box.chi2_red = kwargs["chi2_red"] elif boxtype == "samples": box = SamplesBox() box.spectrum = kwargs["spectrum"] box.parameters = kwargs["parameters"] box.samples = kwargs["samples"] box.ln_prob = kwargs["ln_prob"] box.ln_evidence = kwargs["ln_evidence"] box.prob_sample = kwargs["prob_sample"] box.median_sample = kwargs["median_sample"] box.attributes = kwargs["attributes"] if "uniform_priors" in kwargs: box.uniform_priors = kwargs["uniform_priors"] if "normal_priors" in kwargs: box.normal_priors = kwargs["normal_priors"] elif boxtype == "spectrum": box = SpectrumBox() box.spectrum = kwargs["spectrum"] box.wavelength = kwargs["wavelength"] box.flux = kwargs["flux"] if "error" in kwargs: box.error = kwargs["error"] if "name" in kwargs: box.name = kwargs["name"] if "simbad" in kwargs: box.simbad = kwargs["simbad"] if "sptype" in kwargs: box.sptype = kwargs["sptype"] if "distance" in kwargs: box.distance = kwargs["distance"] if "spec_res" in kwargs: box.spec_res = kwargs["spec_res"] elif boxtype == "synphot": box = SynphotBox() box.name = kwargs["name"] box.flux = kwargs["flux"] if "wavelength" in kwargs: box.wavelength = kwargs["wavelength"] if "app_mag" in kwargs: box.app_mag = kwargs["app_mag"] if "abs_mag" in kwargs: box.abs_mag = kwargs["abs_mag"] return box