diff --git a/VERSION b/VERSION index bdb0fbcd421ce3d3d1524d61cf1a1c6e819dac3c..880f38c61c92bd49d96147f974c440f2ffbc641b 100644 --- a/VERSION +++ b/VERSION @@ -1,2 +1,2 @@ -3.0.0b51 +3.0.0b52 diff --git a/diags.conf b/diags.conf index 256eb0fc5a59d0d78b6791ab1404c932919078f7..2e9c7c56e40f8903b20cc893f5c5b6085035af3e 100644 --- a/diags.conf +++ b/diags.conf @@ -15,11 +15,11 @@ CON_FILES = /esnas/autosubmit/con_files/ # Diagnostics to run, space separated. You must provide for each one the name and the parameters (comma separated) or # an alias defined in the ALIAS section (see more below). If you are using the diagnostics just to CMORize, leave it # empty -DIAGS = vgrad,thetao +DIAGS = module,atmos,uas,vas,sfcwind monmean,sfcwind,atmos,6hr # DIAGS = OHC # Frequency of the data you want to use by default. Some diagnostics do not use this value: i.e. monmean always stores # its results at monthly frequency (obvious) and has a parameter to specify input's frequency. -FREQUENCY = mon +FREQUENCY = 6hr # Path to CDFTOOLS binaries CDFTOOLS_PATH = ~jvegas/CDFTOOLS/bin # If true, copies the mesh files regardless of presence in scratch dir @@ -85,10 +85,10 @@ OCEAN_TIMESTEP = 6 # if 2, fc00 # CHUNK_SIZE is the size of each data file, given in months # CHUNKS is the number of chunks. You can specify less chunks than present on the experiment -EXPID = t01d -STARTDATES = 19900101 -MEMBERS = 0 -MEMBER_DIGITS = 1 +EXPID = a04f +STARTDATES = 20150201 +MEMBERS = fc00 +MEMBER_DIGITS = 2 CHUNK_SIZE = 1 CHUNKS = 1 # CHUNKS = 1 diff --git a/doc/source/codedoc/general.rst b/doc/source/codedoc/general.rst index f0898e42bb5b54c33e877444e4052e4dfb6a4c48..215b700a42fca267dd66a98f2db0e6710db8a987 100644 --- a/doc/source/codedoc/general.rst +++ b/doc/source/codedoc/general.rst @@ -13,6 +13,12 @@ earthdiagnostics.general.dailymean :show-inheritance: :members: +earthdiagnostics.general.module +------------------------------- +.. automodule:: earthdiagnostics.general.module + :show-inheritance: + :members: + earthdiagnostics.general.monthlymean ------------------------------------ .. automodule:: earthdiagnostics.general.monthlymean diff --git a/doc/source/conf.py b/doc/source/conf.py index 32893e405ba525e8255d0e990dc900e0f59d33fb..8a5867886b11f3a172628fc5a7ec5eac3663e375 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -64,7 +64,7 @@ copyright = u'2016, BSC-CNS Earth Sciences Department' # The short X.Y version. version = '3.0b' # The full version, including alpha/beta/rc tags. -release = '3.0.0b51' +release = '3.0.0b52' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/source/diagnostic_list.rst b/doc/source/diagnostic_list.rst index 88861569d0926cac799dc5ac5f2017029b7cb71e..39901f01e1c017f13c96f615015a32b62833c41a 100644 --- a/doc/source/diagnostic_list.rst +++ b/doc/source/diagnostic_list.rst @@ -67,6 +67,29 @@ Options: 4. Grid = '': Variable grid. Only required in case that you want to use interpolated data. +module +~~~~~~ +Calculates the module for two given variables and stores the result in a third. +See :class:`~earthdiagnostics.general.module.Module` + +Options: +******** + +1. Domain: + Variables domain + +2. Variable U: + Variable U name + +3. Variable V: + Variable V name + +4. Variable Module: + Variable module name + +5. Grid = '': + Variable grids. Only required in case that you want to use interpolated data. + monmean ~~~~~~~ Calculates the monthly mean for a given variable. See :class:`~earthdiagnostics.general.monthlymean.MonthlyMean` diff --git a/earthdiagnostics/EarthDiagnostics.pdf b/earthdiagnostics/EarthDiagnostics.pdf index e789ce78e75869dcee7feb4ad83e61aebfc453f5..02f26274a6e001dc73d8740bf4025b9b1053b30e 100644 Binary files a/earthdiagnostics/EarthDiagnostics.pdf and b/earthdiagnostics/EarthDiagnostics.pdf differ diff --git a/earthdiagnostics/config.py b/earthdiagnostics/config.py index 7b339b61080c4b489b6533aa1be9cee06d697605..3119171d48a09cb2e8a75c0eb637858d744fd165 100644 --- a/earthdiagnostics/config.py +++ b/earthdiagnostics/config.py @@ -218,7 +218,23 @@ class ExperimentConfig(object): self.member_digits = parser.get_int_option('EXPERIMENT', 'MEMBER_DIGITS', 1) self.member_prefix = parser.get_option('EXPERIMENT', 'MEMBER_PREFIX', 'fc') self.member_count_start = parser.get_int_option('EXPERIMENT', 'MEMBER_COUNT_START', 0) - self.members = [int(mem) if mem.startswith(self.member_prefix) else int(mem) for mem in self.members] + + members = [] + for mem in self.members: + if '-' in mem: + start, end = mem.split('-') + if start.startswith(self.member_prefix): + start = start[len(self.member_prefix):] + if end.startswith(self.member_prefix): + end = end[len(self.member_prefix):] + for member in range(int(start), int(end) +1): + members.append(member) + else: + if mem.startswith(self.member_prefix): + mem = mem[len(self.member_prefix):] + members.append(int(mem)) + self.members = members + self.startdates = parser.get_option('EXPERIMENT', 'STARTDATES').split() self.chunk_size = parser.get_int_option('EXPERIMENT', 'CHUNK_SIZE') self.num_chunks = parser.get_int_option('EXPERIMENT', 'CHUNKS') @@ -251,7 +267,7 @@ class ExperimentConfig(object): member_list = list() for startdate in self.startdates: for member in self.members: - member_list.append((startdate, member)) + member_list.append((startdate, member)) return member_list def get_year_chunks(self, startdate, year): diff --git a/earthdiagnostics/earthdiags.py b/earthdiagnostics/earthdiags.py index 44fa9974496c4e38981eb8b112f5c02a905c2e6b..da6fe4538c34b3c294a6280b7a1bfdc4512a6023 100755 --- a/earthdiagnostics/earthdiags.py +++ b/earthdiagnostics/earthdiags.py @@ -254,6 +254,7 @@ class EarthDiags(object): Diagnostic.register(Scale) Diagnostic.register(Attribute) Diagnostic.register(SelectLevels) + Diagnostic.register(Module) @staticmethod def _register_ocean_diagnostics(): diff --git a/earthdiagnostics/general/__init__.py b/earthdiagnostics/general/__init__.py index 2920230a23576364f5a0b6d12559a6c8f6966e56..be95992ffc1fbffea51f3fdd8c202cf45b43a2f0 100644 --- a/earthdiagnostics/general/__init__.py +++ b/earthdiagnostics/general/__init__.py @@ -9,3 +9,4 @@ from earthdiagnostics.general.attribute import Attribute from earthdiagnostics.general.relinkall import RelinkAll from earthdiagnostics.general.simplify_dimensions import SimplifyDimensions from earthdiagnostics.general.select_levels import SelectLevels +from earthdiagnostics.general.module import Module diff --git a/earthdiagnostics/general/module.py b/earthdiagnostics/general/module.py new file mode 100644 index 0000000000000000000000000000000000000000..8d08020c1dff3620243324d7ec2a57e4bbfc1742 --- /dev/null +++ b/earthdiagnostics/general/module.py @@ -0,0 +1,110 @@ +# coding=utf-8 +from earthdiagnostics.diagnostic import * +from earthdiagnostics.utils import Utils +from earthdiagnostics.modelingrealm import ModelingRealm +import numpy as np +import math + + +class Module(Diagnostic): + """ + Scales a variable by the given value also adding at offset + Can be useful to correct units or other known errors + (think of a tas file declaring K as units but with the data stored as Celsius) + + :original author: Javier Vegas-Regidor + + :created: July 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 variable: variable's name + :type variable: str + :param domain: variable's domain + :type domain: ModelingRealm + """ + + alias = 'module' + "Diagnostic alias for the configuration file" + + def __init__(self, data_manager, startdate, member, chunk, domain, componentu, componentv, module, grid): + Diagnostic.__init__(self, data_manager) + self.startdate = startdate + self.member = member + self.chunk = chunk + self.domain = domain + self.componentu = componentu + self.componentv = componentv + self.module = module + self.grid = grid + + self.original_values = None + + def __str__(self): + return 'Calculate module Startdate: {0} Member: {1} Chunk: {2} ' \ + 'Variables: {3}:{4},{5},{6} ' \ + 'Grid: {7}'.format(self.startdate, self.member, self.chunk, self.domain, self.componentu, + self.componentv, self.module, self.grid) + + def __eq__(self, other): + return self.startdate == other.startdate and self.member == other.member and self.chunk == other.chunk and \ + self.domain == other.domain and self.componentu == other.componentu and \ + self.componentv == other.componentv and self.module == other.module and self.grid == other.grid + + @classmethod + def generate_jobs(cls, diags, options): + """ + Creates a job for each chunk to compute the diagnostic + + :param diags: Diagnostics manager class + :type diags: Diags + :param options: variable, domain, grid + :type options: list[str] + :return: + """ + options_available = (DiagnosticDomainOption('domain'), + DiagnosticVariableOption('componentu'), + DiagnosticVariableOption('componentv'), + DiagnosticVariableOption('module'), + DiagnosticOption('grid', '')) + options = cls.process_options(options, options_available) + job_list = list() + for startdate, member, chunk in diags.config.experiment.get_chunk_list(): + job_list.append(Module(diags.data_manager, startdate, member, chunk, + options['domain'], options['componentu'], options['componentv'], options['module'], + options['grid'])) + return job_list + + def compute(self): + """ + Runs the diagnostic + """ + component_u_file = self.data_manager.get_file(self.domain, self.componentu, self.startdate, self.member, + self.chunk, grid=self.grid) + + component_v_file = self.data_manager.get_file(self.domain, self.componentv, self.startdate, self.member, + self.chunk, grid=self.grid) + + component_u = Utils.openCdf(component_u_file) + component_v = Utils.openCdf(component_v_file) + variable_u = component_u.variables[self.componentu] + variable_v = component_v.variables[self.componentv] + + variable_u[:] = np.sqrt(variable_u[:] ** 2 + variable_v[:] ** 2) + + if 'table' in variable_u.ncattrs(): + del variable_u.table + if 'code' in variable_u.ncattrs(): + del variable_u.code + + component_u.close() + component_v.close() + + self.send_file(component_u_file, self.domain, self.module, self.startdate, self.member, self.chunk, + grid=self.grid, rename_var=self.componentu)