Newer
Older
"""Compute the sea ice extent , area and volume in both hemispheres or a specified region"""
Javier Vegas-Regidor
committed
import six
Javier Vegas-Regidor
committed
import iris
import iris.analysis
import iris.coords
Javier Vegas-Regidor
committed
import iris.util
from earthdiagnostics.constants import Basins
from earthdiagnostics.diagnostic import Diagnostic, \
DiagnosticBasinListOption, DiagnosticBoolOption
from earthdiagnostics.modelingrealm import ModelingRealms
from earthdiagnostics.utils import Utils, TempFile
Javier Vegas-Regidor
committed
import diagonals.siasie as siasie
from diagonals.mesh_helpers.nemo import Nemo
# noinspection PyUnresolvedReferences
Javier Vegas-Regidor
committed
class Siasiesiv(Diagnostic):
Compute the sea ice extent , area and volume in both hemispheres or a
specified region.
Parameters
----------
data_manager: DataManager
startdate: str
member: int
chunk: init
domain: ModellingRealm
variable: str
Javier Vegas-Regidor
committed
basin: list of Basin
alias = 'siasiesiv'
"Diagnostic alias for the configuration file"
def __init__(self, data_manager, startdate, member, chunk, masks,
var_manager, data_convention, omit_vol):
Javier Vegas-Regidor
committed
Diagnostic.__init__(self, data_manager)
self.startdate = startdate
self.member = member
self.chunk = chunk
Javier Vegas-Regidor
committed
self.masks = masks
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
committed
Javier Vegas-Regidor
committed
self.results = {}
for var in ('siarean', 'siareas', 'siextentn', 'siextents'):
Javier Vegas-Regidor
committed
self.results[var] = {}
return 'Siasiesiv Startdate: {0.startdate} Member: {0.member} Chunk: {0.chunk} ' \
Javier Vegas-Regidor
committed
'Basins: {1} Omit volume: {0.omit_volume}'.format(self,
','.join(str(basin) for basin in self.masks.keys()))
def generate_jobs(cls, diags, options):
Create a job for each chunk to compute the diagnostic
:param diags: Diagnostics manager class
:type diags: Diags
:param options: basin
options_available = (DiagnosticBasinListOption('basins',
[Basins().Global]),
DiagnosticBoolOption('omit_volume', True))
options = cls.process_options(options, options_available)
basins = options['basins']
if not basins:
Javier Vegas-Regidor
committed
Log.error('Basins not recognized')
return ()
Javier Vegas-Regidor
committed
masks = {}
basins.sort()
for basin in basins:
Javier Vegas-Regidor
committed
masks[basin] = Utils.get_mask(basin)
Javier Vegas-Regidor
committed
job_list = list()
for startdate, member, chunk in diags.config.experiment.get_chunk_list():
job_list.append(Siasiesiv(diags.data_manager, startdate, member,
chunk, masks, diags.config.var_manager,
diags.config.data_convention,
Javier Vegas-Regidor
committed
Javier Vegas-Regidor
committed
return job_list
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)
if not self.omit_volume:
self._declare_var('sivols')
self._declare_var('sivoln')
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, self.chunk)
Javier Vegas-Regidor
committed
def compute(self):
self._fix_coordinates_attribute(
self.sic.local_file, self.sic_varname
)
Javier Vegas-Regidor
committed
sic = iris.load_cube(self.sic.local_file)
if sic.units.origin == '%' and sic.data.max() < 2:
Javier Vegas-Regidor
committed
sic.units = '1.0'
sic_slices = []
for sic_data in sic.slices_over('time'):
sic_data.data = np.ma.filled(sic_data.data, 0.0).astype(np.float32)
sic_slices.append(sic_data)
mesh = Nemo('mesh_hgr.nc', 'mask_regions.nc')
areacello = mesh.get_areacello(cell_point='T')
results = siasie.compute(gphit, areacello, sic_slices, self.masks)
self.results['siextentn'] = results[0]
self.results['siextents'] = results[1]
self.results['siarean'] = results[2]
self.results['siareas'] = results[3]
Javier Vegas-Regidor
committed
self.save()
def _fix_coordinates_attribute(self, filepath, var_name):
add_coordinates = {
'time', 'leadtime', 'time_centered',
self.data_convention.lon_name, self.data_convention.lat_name
}
handler = Utils.open_cdf(filepath)
coordinates = handler.variables[var_name].coordinates.split()
handler.variables[var_name].coordinates = \
' '.join(set(coordinates) | add_coordinates)
handler.close()
Javier Vegas-Regidor
committed
def save(self):
for var in self.results.keys():
res = self.results[var]
temp = TempFile.get()
handler_source = Utils.open_cdf(self.sic.local_file)
handler_temp = Utils.open_cdf(temp, 'w')
Utils.copy_variable(handler_source, handler_temp, 'time', True, True)
handler_temp.createDimension('region', len(self.masks))
handler_temp.createDimension('region_length', 50)
var_region = handler_temp.createVariable('region', 'S1', ('region', 'region_length'))
var_res = handler_temp.createVariable('{0}'.format(var), float,
('time', 'region',))
var_res.units = 'm^2'
for i, basin in enumerate(self.masks):
var_region[i, ...] = netCDF4.stringtoarr(str(basin), 50)
var_res[..., i] = res[i, ...]
handler_temp.close()
self.generated[var].set_local_file(temp, diagnostic=self)