modelingrealm.py 5.03 KB
Newer Older
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
# coding=utf-8
"""Class to manage variable domains"""
from earthdiagnostics.frequency import Frequencies


class ModelingRealm(object):
    """
    Class to represent Modeling Relms for variables

    Parameters
    ----------
    domain_name: str

    Raises
    ------
    ValueError
        If the domain is not supported
    """

    def __init__(self, domain_name):
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        lower_name = domain_name.lower()
        if lower_name == 'seaice':
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        elif lower_name == 'landice':
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        elif lower_name == 'atmoschem':
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        elif lower_name == 'ocnbgchem':
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        elif lower_name in ['ocean', 'atmos', 'land', 'aerosol']:
            self.name = domain_name
        else:
            raise ValueError('Modelling realm {0} not recognized!'.format(domain_name))
        return other.__class__ == ModelingRealm and self.name == other.name
    def __hash__(self):
        return hash(self.name)

    def __ne__(self, other):
        return not (self == other)

    def __str__(self):
        return self.name

Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
    def __repr__(self):
        return str(self)

    def get_varfolder(self, var, ocean_timestep, atmos_timestep, grid=None, frequency=None):
        """Get variable folder name for <frequency>_<var_type> folder"""
        if grid:
            var = '{0}-{1}'.format(var, grid)

        if self in [ModelingRealms.ocean, ModelingRealms.seaIce, ModelingRealms.ocnBgchem]:
            timestep = ocean_timestep
        else:
            timestep = atmos_timestep
        is_base_frequency = frequency is not None and frequency.frequency.endswith('hr')
        if not is_base_frequency and timestep > 0:
            return '{0}_f{1}h'.format(var, timestep)
        return var

    def get_table_name(self, frequency, data_convention):
        Get table name for a domain-frequency pair

        Parameters
        ----------
        data_convention: str
        frequency: Frequency

        Returns
        -------
        str

Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        if self.name == 'seaIce':
            if data_convention.name in ('specs', 'preface'):
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
                prefix = 'OI'
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
                prefix = 'SI'
        elif self.name == 'landIce':
            prefix = 'LI'
        else:
            prefix = self.name[0].upper()

        if frequency == Frequencies.six_hourly:
            if (frequency in (Frequencies.monthly, Frequencies.climatology)) or data_convention.name not in ('specs',
                                                                                                             'preface'):
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
                table_name = prefix + str(frequency)
            else:
                table_name = frequency.frequency
    def get_table(self, frequency, data_convention):
        """
        Get table name for a domain-frequency pair

        Parameters
        ----------
        data_convention: str
        frequency: Frequency

        Returns
        -------
        str

        Parameters
        ----------
        frequency
        data_convention

        Returns
        -------
        CMORTable

        """
        table_name = self.get_table_name(frequency, data_convention)
        from earthdiagnostics.variable import CMORTable
        return CMORTable(table_name, frequency, 'December 2013', self)
class ModelingRealms(object):
    """Enumeration of supported modelling realms"""
    seaIce = ModelingRealm('seaice')
    ocean = ModelingRealm('ocean')
    landIce = ModelingRealm('landIce')
    atmos = ModelingRealm('atmos')
    land = ModelingRealm('land')
    aerosol = ModelingRealm('aerosol')
    atmosChem = ModelingRealm('atmosChem')
    ocnBgchem = ModelingRealm('ocnBgchem')
    @classmethod
    def parse(cls, modelling_realm):
        """
        Return the basin matching the given name.

        If the parameter modelling_realm is a ModelingRealm instance, directly returns the same
        instance. This behaviour is intended to facilitate the development of
        methods that can either accept a name or a ModelingRealm instance to
        characterize the modelling realm.

        Parameters
        ----------
        modelling_realm: ModelingRealm or str

        Returns
        -------
        ModelingRealm

        Raises
        ------
        ValueError
            If the modelling realm is not supported

        """
        if isinstance(modelling_realm, ModelingRealm):
            return modelling_realm
        if modelling_realm == '':
            return None
        for name in cls.__dict__.keys():
            if name.startswith('_'):
                continue
            # noinspection PyCallByClass
            value = cls.__getattribute__(cls, name)
            if isinstance(value, ModelingRealm):
                if modelling_realm.lower() in [value.name.lower()]:
                    return value
        raise ValueError('Modelling realm {0} not recognized!'.format(modelling_realm))