Source code for taurex.cache.ciaacache

"""
Contains caching class for Collisionally Induced Absorption files
"""
from taurex.core import Singleton
from taurex.log import Logger


[docs]class CIACache(Singleton): """ Implements a lazy load of collisionally induced absorpiton cross-sections Supports pickle files and HITRAN cia files. Functionally behaves the same as :class:`~taurex.cache.opacitycache.OpacityCache` except the keys are now cia pairs e.g: >>> CIACache()['H2-H2'] <taurex.cia.picklecia.PickleCIA at 0x107a60be0> Pickle ``.db`` and HITRAN ``.cia`` files are supported and automatically loaded. with priority given to ``.db`` files """
[docs] def init(self): self.cia_dict = {} self._cia_path = None self.log = Logger('CIACache')
[docs] def set_cia_path(self, cia_path): """ Sets the path to search for CIA files Parameters ---------- cia_path : str or :obj:`list` of str Either a single path or a list of paths that contain CIA files """ self._cia_path = cia_path
def __getitem__(self, key): """ For a CIA pair, load from the set path and return the relevant :class:`~taurex.cia.cia.CIA` object Parameter --------- key : str cia pair name Returns ------- :class:`~taurex.cia.picklecia.PickleCIA` or :class:`~taurex.cia.hitrancia.HitranCIA` Desire CIA object, format depends on what is found in the path set by :func:`set_cia_path` Raise ----- Exception If desired CIA pair could not be loaded """ if key in self.cia_dict: return self.cia_dict[key] else: # Try a load of the cia self.load_cia(pair_filter=[key]) # If we have it after a load then good job boys if key in self.cia_dict: return self.cia_dict[key] else: # Otherwise throw an error self.log.error('CIA for pair %s could not be loaded', key) self.log.error('It could not be found in the local dictionary ' ' %s', list(self.cia_dict.keys())) self.log.error('Or paths %s', self._cia_path) self.log.error('Try loading it manually/ putting it in a path') raise Exception('cia could notn be loaded')
[docs] def add_cia(self, cia, pair_filter=None): """ Adds a :class:`~taurex.cia.cia.CIA` object to the cache to then be used by Taurex 3 Parameters ---------- cia : :class:`~taurex.cia.cia.CIA` CIA object to add to the cache pair_filter : :obj:`list` of str , optional If provided, the cia object will only be included if its pairname is in the list. Mostly used by the :func:`__getitem__` for filtering """ self.log.info('Loading cia %s into model', cia.pairName) if cia.pairName in self.cia_dict: self.log.error('cia with name %s already in ' 'opactiy dictionary %s', cia.pairName, self.cia_dict.keys()) raise Exception('cia for molecule %s already exists') if pair_filter is not None: if cia.pairName in pair_filter: self.log.info('Loading cia %s into model', cia.pairName) self.cia_dict[cia.pairName] = cia self.cia_dict[cia.pairName] = cia
[docs] def load_cia_from_path(self, path, pair_filter=None): """ Searches path for CIA files, creates and loads them into the cache ``.db`` will be loaded as :class:`~taurex.cia.picklecia.PickleCIA` and ``.cia`` files will be loaded as :class:`~taurex.cia.hitrancia.HitranCIA` Parameters ---------- path : str Path to search for CIA files pair_filter : :obj:`list` of str , optional If provided, the cia will only be loaded if its pairname is in the list. Mostly used by the :func:`__getitem__` for filtering """ from glob import glob from pathlib import Path import os from taurex.cia import PickleCIA # Find .db files glob_path = os.path.join(path, '*.db') file_list = glob(glob_path) self.log.debug('Glob list: %s', glob_path) self.log.debug('File list FOR CIA %s', file_list) for files in file_list: pairname = Path(files).stem.split('_')[0] self.log.debug('pairname found %s', pairname) if pair_filter is not None: if pairname not in pair_filter: continue op = PickleCIA(files, pairname) self.add_cia(op) # Find .cia files glob_path = os.path.join(path, '*.cia') file_list = glob(glob_path) self.log.debug('File list %s', file_list) for files in file_list: from taurex.cia import HitranCIA pairname = Path(files).stem.split('_')[0] if pair_filter is not None: if pairname not in pair_filter: continue op = HitranCIA(files) self.add_cia(op)
[docs] def load_cia(self, cia_xsec=None, cia_path=None, pair_filter=None): """ Main function to use when loading CIA files. Handles both cross sections and paths. Handles lists of either so lists of :class:`~taurex.cia.cia.CIA` objects or lists of paths can be used to load multiple files/objects Parameters ---------- cia_xsec : :class:`~taurex.cia.cia.CIA` or :obj:`list` of :class:`~taurex.cia.cia.CIA` , optional Object(s) to include in cache cia_path : str or :obj:`list` of str, optional search path(s) to look for cias pair_filter : :obj:`list` of str , optional If provided, the cia will only be loaded if its pair name is in this list. Mostly used by the :func:`__getitem__` for filtering """ from taurex.cia import CIA if cia_path is None: cia_path = self._cia_path self.log.debug('CIA XSEC, CIA_PATH %s %s', cia_xsec, cia_path) if cia_xsec is not None: if isinstance(cia_xsec, (list,)): self.log.debug('cia passed is list') for xsec in cia_xsec: self.add_cia(xsec, pair_filter=pair_filter) elif isinstance(cia_xsec, CIA): self.add_cia(cia_xsec, pair_filter=pair_filter) else: self.log.error('Unknown type %s passed into cia, should be a list, single \ cia or None if reading a path', type(xsec)) raise Exception('Unknown type passed into cia') if cia_path is not None: if isinstance(cia_path, str): self.load_cia_from_path(cia_path, pair_filter=pair_filter) elif isinstance(cia_path, (list,)): for path in cia_path: self.load_cia_from_path(path, pair_filter=pair_filter)