Commit 45b94e8b authored by sloosvel's avatar sloosvel Committed by Javier Vegas-Regidor
Browse files

Add IPO, AMV and IOD indices

parent abac2882
......@@ -269,6 +269,7 @@ class DataFile(Publisher):
self._rename_coordinate_variables()
self._correct_metadata()
self._prepare_region()
self.add_basin_history()
self.add_diagnostic_history()
Utils.convert2netcdf4(self.local_file)
......@@ -508,7 +509,6 @@ class DataFile(Publisher):
if not self.diagnostic:
return
from earthdiagnostics.earthdiags import EarthDiags
history_line = (
f"Diagnostic {self.diagnostic} calculated with EarthDiagnostics "
f"version {EarthDiags.version}"
......@@ -524,6 +524,19 @@ class DataFile(Publisher):
)
self._add_history_line(history_line)
def add_basin_history(self):
"""Add basin history line to local file"""
if not os.path.isfile('basins.nc'):
return
basins = iris.load_cube('basins.nc')
history_line = (
"Using Basins masks file "
f"version {basins.attributes['version']} with "
f"grid {basins.attributes['grid']}. "
"Original file can be found in /esarchive/autosubmit/conf_files."
)
self._add_history_line(history_line)
def _add_history_line(self, history_line):
utc_datetime = "UTC " + datetime.utcnow().isoformat()
history_line = "{0}: {1};".format(utc_datetime, history_line)
......
# coding=utf-8
"""Compute the indices for oceanic basins"""
from bscearth.utils.log import Log
import iris
import iris.analysis
from earthdiagnostics.diagnostic import Diagnostic
from earthdiagnostics.modelingrealm import ModelingRealms
from earthdiagnostics.utils import Utils, TempFile
class Indices(Diagnostic):
"""
Compute the MOC for oceanic basins
:created: March 2012
: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
"""
alias = 'indices'
"Diagnostic alias for the configuration file"
def __init__(self, data_manager, startdate, member, chunk):
Diagnostic.__init__(self, data_manager)
self.startdate = startdate
self.member = member
self.chunk = chunk
self.results = {}
self.region_metadata = {}
self.generated = {}
def __str__(self):
return 'Indices Startdate: {0.startdate} Member: {0.member} ' \
'Chunk: {0.chunk}'.format(self)
def __hash__(self):
return hash(str(self))
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
)
@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:
"""
job_list = list()
for sdate, mem, chunk in diags.config.experiment.get_chunk_list():
job_list.append(
Indices(diags.data_manager, sdate, mem, chunk))
return job_list
def request_data(self):
"""Request data required by the diagnostic"""
self.variable_file = self.request_chunk(
ModelingRealms.ocean, 'tosmean',
self.startdate, self.member, self.chunk)
def declare_data_generated(self):
"""Declare data to be generated by the diagnostic"""
self._declare_var('amv')
self._declare_var('ipo')
self._declare_var('iod')
def _declare_var(self, var_name):
self.generated[var_name] = self.declare_chunk(
ModelingRealms.ocean, var_name,
self.startdate, self.member, self.chunk)
def compute(self):
"""Run the diagnostic"""
tosmean = iris.load_cube(self.variable_file.local_file)
data_regions = tosmean.coord('region').points
amv_regions = ['AMV_North_Atlantic', 'AMV_trend']
ipo_regions = ['Pacific_TPI1', 'Pacific_TPI2', 'Pacific_TPI3']
iod_regions = ['Indian_dipole_east', 'Indian_dipole_west']
check_amv = set(amv_regions).issubset(set(data_regions))
if check_amv:
data = {}
for region in amv_regions:
data[region] = tosmean.extract(iris.Constraint(region=region))
self.compute_amv(data)
else:
Log.info('Input data does not contain the basins required to '
'compute the AMV index. Skipping AMV computations.')
check_ipo = set(ipo_regions).issubset(set(data_regions))
if check_ipo:
data = {}
for region in ipo_regions:
data[region] = tosmean.extract(iris.Constraint(region=region))
self.compute_ipo(data)
else:
Log.info('Input data does not contain the basins required to '
'compute the IPO index. Skipping IPO computations.')
check_iod = set(iod_regions).issubset(set(data_regions))
if check_iod:
data = {}
for region in iod_regions:
data[region] = tosmean.extract(iris.Constraint(region=region))
self.compute_iod(data)
else:
Log.info('Input data does not contain the basins required to '
'compute the IOD index. Skipping IOD computations.')
self.save()
def compute_amv(self, data):
self.results['amv'] = (data['AMV_North_Atlantic'].data -
data['AMV_trend'].data)
self.region_metadata['amv'] = (
'AMV_North_Atlantic Box (lat: [0, 60], lon:[-80, 0]), '
'AMV_trend Box (lat: [-60, 60], lon: [-180, 180])')
def compute_ipo(self, data):
self.results['ipo'] = data['Pacific_TPI2'].data - 0.5*(
data['Pacific_TPI1'].data + data['Pacific_TPI3'].data
)
self.region_metadata['ipo'] = (
'Pacific_TPI1 Box ( (lat: [25, 45], lon:[140, 180]), '
'(lat: [25, 45], lon:[-180, -145]) ) '
'Pacific_TPI2 Box ( (lat: [-10, 10], lon:[170, 180]), '
'(lat: [-10, 10], lon:[-180, -90]) ) '
'Pacific_TPI3 Box ( (lat: [-50, -15], lon:[150, 180]), '
'(lat: [-50, -15], lon:[-180, -160]) )'
)
def compute_iod(self, data):
self.results['iod'] = (data['Indian_dipole_west'].data -
data['Indian_dipole_east'].data)
self.region_metadata['iod'] = (
'Indian_dipole_west Box (lat: [-10, 10], lon:[50,70]) '
'Indian_dipole_east Box (lat: [-10, 0], lon:[90, 110])'
)
def save(self):
for var in self.results.keys():
res = self.results[var]
temp = TempFile.get()
handler_source = Utils.open_cdf(self.variable_file.local_file)
handler_temp = Utils.open_cdf(temp, 'w')
Utils.copy_variable(
handler_source, handler_temp, 'time', True, True)
var_res = handler_temp.createVariable(
'{0}'.format(var), float, ('time',))
var_res[...] = res[...]
var_res.units = 'degC'
var_res.comment = '{var} index computed at {region}'.format(
var=var,
region=self.region_metadata[var]
)
handler_temp.close()
self.generated[var].set_local_file(temp, diagnostic=self)
......@@ -388,6 +388,7 @@ class WorkManager(object):
from .ocean.verticalmean import VerticalMean
from .ocean.verticalmeanmeters import VerticalMeanMeters
from .ocean.verticalgradient import VerticalGradient
from .ocean.indices import Indices
from .ocean.interpolate import Interpolate
from .ocean.interpolatecdo import InterpolateCDO
from .ocean.moc import Moc
......@@ -411,6 +412,7 @@ class WorkManager(object):
Diagnostic.register(Siasiesiv)
Diagnostic.register(VerticalMean)
Diagnostic.register(VerticalMeanMeters)
Diagnostic.register(Indices)
Diagnostic.register(Interpolate)
Diagnostic.register(InterpolateCDO)
Diagnostic.register(Moc)
......
mixdiags @ 19997970
Subproject commit 199979700e38d3918a82bd2052855d46375e48ab
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment