Source code for earthdiagnostics.ocean.gyres

# coding=utf-8
"""Compute the intensity of the subtropical and subpolar gyres"""
import numpy as np
from bscearth.utils.log import Log

from earthdiagnostics.constants import Models
from earthdiagnostics.diagnostic import Diagnostic
from earthdiagnostics.modelingrealm import ModelingRealms
from earthdiagnostics.utils import Utils, TempFile


[docs]class Gyres(Diagnostic): """ Compute the intensity of the subtropical and subpolar gyres :original author: Virginie Guemas <virginie.guemas@bsc.es> :contributor: Javier Vegas-Regidor<javier.vegas@bsc.es> :created: October 2013 :last modified: June 2016 :param data_manager: data management object :type data_manager: DataManager :param startdate: startdate :type startdate: str :param member: member number :type member: int :param chunk: chunk's number :type chunk: int :param model_version: model version :type model_version: str """ alias = 'gyres' "Diagnostic alias for the configuration file" def __init__(self, data_manager, startdate, member, chunk, model_version): Diagnostic.__init__(self, data_manager) self.startdate = startdate self.member = member self.chunk = chunk self.model_version = model_version self.var_vsftbarot = None def __eq__(self, other): if self._different_type(other): return False return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ self.model_version == other.model_version def __str__(self): return 'Gyres Startdate: {0.startdate} Member: {0.member} Chunk: {0.chunk} ' \ 'Model version: {0.model_version}'.format(self)
[docs] @classmethod 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: None :type options: list[str] :return: """ if len(options) > 1: raise Exception('The gyres diagnostic has no options') job_list = list() model_version = diags.config.experiment.model_version for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append(Gyres(diags.data_manager, startdate, member, chunk, model_version)) return job_list
[docs] def request_data(self): """Request data required by the diagnostic""" self.vsftbarot = self.request_chunk(ModelingRealms.ocean, 'vsftbarot', self.startdate, self.member, self.chunk)
[docs] def declare_data_generated(self): """Declare data to be generated by the diagnostic""" self.gyre = self.declare_chunk(ModelingRealms.ocean, 'gyre', self.startdate, self.member, self.chunk)
# noinspection PyPep8Naming
[docs] def compute(self): """Run the diagnostic""" if self.model_version in [Models.ECEARTH_2_3_O1L42, Models.ECEARTH_3_0_O1L46, Models.NEMO_3_2_O1L42, Models.NEMO_3_3_O1L46, Models.NEMOVAR_O1L42]: subpol_n_atl = [230, 275, 215, 245] subpol_n_pac = [70, 145, 195, 235] subtrop_n_pac = [45, 175, 165, 220] subtrop_n_atl = [195, 275, 175, 225] subtrop_s_pac = [70, 205, 120, 145] subtrop_s_atl = [235, 300, 120, 145] subtrop_ind = [320, 30, 110, 180] acc = [1, 361, 1, 65] elif self.model_version in [Models.ECEARTH_3_0_O25L46, Models.ECEARTH_3_0_O25L75, Models.GLORYS2_V1_O25L75, Models.ECEARTH_3_2_O1L75, Models.ECEARTH_3_2_O25L75]: raise Exception("Option gyres not available yet for {0}".format(self.model_version)) else: raise Exception("Input grid {0} not recognized".format(self.model_version)) output = TempFile.get() vsftbarot_file = self.vsftbarot.local_file handler_original = Utils.open_cdf(vsftbarot_file) self.var_vsftbarot = handler_original.variables['vsftbarot'] handler = Utils.open_cdf(output, 'w') handler.createDimension('time', handler_original.variables['time'].shape[0]) handler.createDimension('region', 8) Utils.copy_variable(handler_original, handler, 'time') var_region = handler.createVariable('region', str, 'region') var_gyre = handler.createVariable('gyre', 'f', ('time', 'region'), fill_value=0.0) var_gyre.valid_max = 2e8 var_gyre.valid_min = 0.0 var_gyre.short_name = 'gyre' var_gyre.long_name = 'gyre' var_gyre.units = 'm^3/s' var_region[0] = 'subpolNAtl' var_gyre[:, 0] = self._gyre(subpol_n_atl, True) Log.debug('subpolNAtl: {0}', var_gyre[:, 0]) var_region[1] = 'subpolNPac' var_gyre[:, 1] = self._gyre(subpol_n_pac, True) Log.debug('subpolNPac: {0}', var_gyre[:, 1]) var_region[2] = 'subtropNPac' var_gyre[:, 2] = self._gyre(subtrop_n_pac) Log.debug('subtropNPac: {0}', var_gyre[:, 2]) var_region[3] = 'subtropSPac' var_gyre[:, 3] = self._gyre(subtrop_s_pac) Log.debug('subtropSPac: {0}', var_gyre[:, 3]) var_region[4] = 'subtropNAtl' var_gyre[:, 4] = self._gyre(subtrop_n_atl) Log.debug('subtropNAtl: {0}', var_gyre[:, 4]) var_region[5] = 'subtropSAtl' var_gyre[:, 5] = self._gyre(subtrop_s_atl) Log.debug('subtropSAtl: {0}', var_gyre[:, 5]) var_region[6] = 'subtropInd' var_gyre[:, 6] = self._gyre(subtrop_ind) Log.debug('subtropInd: {0}', var_gyre[:, 6]) var_region[7] = 'ACC' var_gyre[:, 7] = self._gyre(acc) Log.debug('ACC: {0}', var_gyre[:, 7]) handler.close() handler_original.close() self.gyre.set_local_file(output) Log.info('Finished gyres for startdate {0}, member {1}, chunk {2}', self.startdate, self.member, self.chunk)
def _gyre(self, site, invert=False): if invert: return np.min(self._extract_section(site), (1, 2)) * -1 else: return np.max(self._extract_section(site), (1, 2)) def _extract_section(self, site): if site[2] <= site[3]: if site[0] <= site[1]: return self.var_vsftbarot[:, site[2] - 1:site[3] - 1, site[0] - 1:site[1] - 1] else: return np.concatenate((self.var_vsftbarot[:, site[2] - 1:site[3] - 1, site[0] - 1:], self.var_vsftbarot[:, site[2] - 1:site[3] - 1, :site[1] - 1]), axis=2) else: if site[0] <= site[1]: return np.concatenate((self.var_vsftbarot[:, site[2] - 1:, site[0] - 1: site[1] - 1], self.var_vsftbarot[:, :site[3] - 1, site[0] - 1: site[1] - 1]), axis=1) else: temp = np.concatenate((self.var_vsftbarot[:, site[2] - 1:, :], self.var_vsftbarot[:, :site[3] - 1, :]), axis=1) return np.concatenate((temp[:, :, site[0] - 1:], temp[:, :, :site[1] - 1]), axis=2)