siasiesiv.py 6.3 KB
Newer Older
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
# coding=utf-8
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
"""Compute the sea ice extent , area and volume  in both hemispheres or a specified region"""
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
import netCDF4
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
import numpy as np
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
from bscearth.utils.log import Log
from earthdiagnostics.constants import Basins
from earthdiagnostics.diagnostic import Diagnostic, DiagnosticBasinOption, DiagnosticBoolOption
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
from earthdiagnostics.modelingrealm import ModelingRealms
from earthdiagnostics.utils import Utils, TempFile
# noinspection PyUnresolvedReferences


Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
    Compute the sea ice extent , area and volume  in both hemispheres or a specified region.

Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
    Parameters
    ----------
    data_manager: DataManager
    startdate: str
    member: int
    chunk: init
    domain: ModellingRealm
    variable: str
    basin: Basin
    mask: numpy.array
    omit_vol: bool
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
    """
    alias = 'siasiesiv'
    "Diagnostic alias for the configuration file"

    e1t = None
    e2t = None
    gphit = None

    def __init__(self, data_manager, startdate, member, chunk, basin, mask, var_manager, omit_vol):
        Diagnostic.__init__(self, data_manager)
        self.basin = basin
        self.startdate = startdate
        self.member = member
        self.chunk = chunk
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        self.generated = {}
        self.var_manager = var_manager
        self.omit_volume = omit_vol
        self.sic_varname = self.var_manager.get_variable('sic').short_name
        self.sit_varname = self.var_manager.get_variable('sit').short_name
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
    def __str__(self):
        return 'Siasiesiv Startdate: {0.startdate} Member: {0.member} Chunk: {0.chunk} ' \
               'Basin: {0.basin} Omit volume: {0.omit_volume}'.format(self)
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed

    def generate_jobs(cls, diags, options):
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        Create a job for each chunk to compute the diagnostic

        :param diags: Diagnostics manager class
        :type diags: Diags
        :param options: basin
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        :type options: list[str]
        options_available = (DiagnosticBasinOption('basin', Basins().Global),
                             DiagnosticBoolOption('omit_volume', False))
        options = cls.process_options(options, options_available)
        if options['basin'] is None:
            Log.error('Basin not recognized')
            return ()

        mask = np.asfortranarray(Utils.get_mask(options['basin']))
        for startdate, member, chunk in diags.config.experiment.get_chunk_list():
            job_list.append(Siasiesiv(diags.data_manager, startdate, member, chunk, options['basin'], mask,
                                      diags.config.var_manager, options['omit_volume']))
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        mesh_handler = Utils.open_cdf('mesh_hgr.nc')
        Siasiesiv.e1t = np.asfortranarray(mesh_handler.variables['e1t'][0, :])
        Siasiesiv.e2t = np.asfortranarray(mesh_handler.variables['e2t'][0, :])
        Siasiesiv.gphit = np.asfortranarray(mesh_handler.variables['gphit'][0, :])
        mesh_handler.close()

Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
    def request_data(self):
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        """Request data required by the diagnostic"""
        if not self.omit_volume:
            self.sit = self.request_chunk(ModelingRealms.seaIce, self.sit_varname,
                                          self.startdate, self.member, self.chunk)
        self.sic = self.request_chunk(ModelingRealms.seaIce, self.sic_varname,
                                      self.startdate, self.member, self.chunk)
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed

    def declare_data_generated(self):
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        """Declare data to be generated by the diagnostic"""
        if not self.omit_volume:
            self._declare_var('sivols')
            self._declare_var('sivoln')

Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        self._declare_var('siareas')
        self._declare_var('siextents')

        self._declare_var('siarean')
        self._declare_var('siextentn')

    def _declare_var(self, var_name):
        self.generated[var_name] = self.declare_chunk(ModelingRealms.seaIce, var_name, self.startdate, self.member,
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
                                                      self.chunk, region=self.basin.name)
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        """Run the diagnostic"""
        import earthdiagnostics.cdftoolspython as cdftoolspython
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        sic_handler = Utils.open_cdf(self.sic.local_file)
        Utils.convert_units(sic_handler.variables[self.sic_varname], '1.0')
        sic = np.asfortranarray(sic_handler.variables[self.sic_varname][:])
        timesteps = sic_handler.dimensions['time'].size
        if self.omit_volume:
            sit = sic
        else:
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
            sit_handler = Utils.open_cdf(self.sit.local_file)
            sit = np.asfortranarray(sit_handler.variables[self.sit_varname][:])
            sit_handler.close()

        result = np.empty((8, timesteps))
        for t in range(0, timesteps):
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
            result[:, t] = cdftoolspython.icediag.icediags(Siasiesiv.e1t, Siasiesiv.e2t, self.mask,
                                                           Siasiesiv.gphit, sit[t, :], sic[t, :])
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        self._extract_variable_and_rename(result[5, :], 'siareas', '10^9 m2')
        self._extract_variable_and_rename(result[7, :], 'siextents', '10^9 m2')

        self._extract_variable_and_rename(result[1, :], 'siarean', '10^9 m2')
        self._extract_variable_and_rename(result[3, :], 'siextentn', '10^9 m2')

        if not self.omit_volume:
            self._extract_variable_and_rename(result[4, :], 'sivols', '10^9 m3')
            self._extract_variable_and_rename(result[0, :], 'sivoln', '10^9 m3')

Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
    def _extract_variable_and_rename(self, values, cmor_name, units):
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        reference_handler = Utils.open_cdf(self.sic.local_file)
        os.remove(temp)
        handler = netCDF4.Dataset(temp, 'w')

        Utils.copy_variable(reference_handler, handler, 'time', add_dimensions=True)
        Utils.copy_variable(reference_handler, handler, 'time_bnds', add_dimensions=True, must_exist=False)
        Utils.copy_variable(reference_handler, handler, 'leadtime', add_dimensions=True, must_exist=False)
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        reference_handler.close()
        new_var = handler.createVariable(cmor_name, float, 'time', fill_value=1.0e20)
        new_var.units = units
        new_var.short_name = cmor_name
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        new_var.valid_min = 0.0
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        new_var.valid_max = np.max(values)
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
        self.generated[cmor_name].set_local_file(temp)