Source code for cortecs.opac.opac
"""
this file holds the class describing opacity data. hmm...maybe I want the loader in a different file?
author: @arjunsavel
"""
import numpy as np
from cortecs.opac.io import *
[docs]
class Opac(object):
"""
this class holds the opacity data and provides methods for evaluating the opacity at a given temperature and pressure.
Everything's already been loaded into memory, so this is just a wrapper for the data.
todo: use the different loaders
"""
method_dict = {
"chimera": loader_chimera,
"helios": loader_helios,
"platon": loader_platon,
"exotransmit": loader_exotransmit,
}
wl = None
T = None
P = None
def __init__(
self,
filename,
loader="chimera",
load_kwargs={},
):
"""
wraps around the loaders.
Parameters
----------
filename : str
name of file to load
loader : str
name of loader to use. default is chimera.
Returns
-------
nothing
"""
self.filename = filename
self.load_obj = self._get_loader(loader)
self.wl, self.T, self.P, self.cross_section = self.load_obj.load(
filename, **load_kwargs
)
self.n_wav, self.n_t, self.n_p = len(self.wl), len(self.T), len(self.P)
return
def _get_loader(self, loader_name):
"""
gets the loader object
Parameters
----------
loader_name : str
name of loader
Returns
-------
loader object
"""
if loader_name not in self.method_dict:
raise ValueError(
"loader name not found. valid loaders are: {}".format(
self.method_dict.keys()
)
)
return self.method_dict[loader_name]()
# todo: implement the copy and deepcopy methods.
[docs]
def copy(self):
# need a new opac object with all the same attributes. so let's make sure we don't load on input.
raise NotImplementedError
[docs]
class Opac_cia(Opac):
"""
this class holds the opacity data and provides methods for evaluating the opacity at a given temperature and pressure.
Everything's already been loaded into memory, so this is just a wrapper for the data.
"""
method_dict = {
"platon_cia": loader_platon_cia,
"exotransmit_cia": loader_exotransmit_cia,
}
def __init__(self, filename, loader="platon_cia", view="default"):
"""
wraps around the loaders.
NOTE: there's a mixed type for self.cross_section. can be a dataframe if there are a number of species.
Parameters
----------
filename : str
name of file to load
loader : str
name of loader to use. default is chimera.
view : str
if 'full_frame' is selected, the cross_section object also includes temperature and wavelength columns.
Returns
-------
nothing
"""
self.filename = filename
self.load_obj = self._get_loader(loader)
self.wl, self.T, self.cross_section = self.load_obj.load(self.filename)
# at least for the exotransmit case, we have...wl x temp.
if view == "full_frame":
self.cross_section["temp"] = self.T
self.cross_section["wav"] = self.wl
self.n_wav, self.n_t = len(self.wl), len(self.T)
return
[docs]
def join_cross_section(self, opac):
"""
joins another opacity's cross-section data to this one.
:param opac:
:return:
"""
def replace_zeros(species):
mask = self.cross_section[species] == 0.0
self.cross_section.loc[mask, species] = opac.cross_section.loc[
mask, species
]
# throw errors if the grids don't match.
if np.all(opac.T != self.T):
raise ValueError("temperatures do not match!")
if np.all(opac.wl != self.wl):
raise ValueError("wavelengths do not match!")
# add the entirely new columns
other_columns = opac.cross_section.columns
for column in other_columns:
if column not in self.cross_section.columns:
self.cross_section[column] = opac.cross_section[column]
# now fill in any temperatures where the cross-section is zero here.
for species in self.cross_section.columns:
if species in other_columns:
replace_zeros(species)
return