# coding=utf-8 """Time mean diagnostics""" import os from earthdiagnostics.diagnostic import Diagnostic, DiagnosticOption, DiagnosticDomainOption, \ DiagnosticFrequencyOption, DiagnosticVariableOption from earthdiagnostics.frequency import Frequencies from earthdiagnostics.utils import TempFile, Utils class TimeMean(Diagnostic): """ Base class for all time mean diagnostics :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 :param frequency: original frequency :type frequency: str :param grid: original data grid :type grid: str """ def __init__(self, data_manager, startdate, member, chunk, domain, variable, frequency, grid): Diagnostic.__init__(self, data_manager) self.startdate = startdate self.member = member self.chunk = chunk self.variable = variable self.domain = domain self.frequency = frequency self.grid = grid self._target_frequency = None def __str__(self): return 'Calculate {0._target_frequency} mean Startdate: {0.startdate} Member: {0.member} Chunk: {0.chunk} ' \ 'Variable: {0.domain}:{0.variable} Original frequency: {0.frequency} Grid: {0.grid}'.format(self) 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.variable == other.variable and self.frequency == other.frequency and \ self.grid == other.grid and self._target_frequency == other._target_frequency @classmethod def _process_options(cls, diags, options): options_available = (DiagnosticDomainOption(), DiagnosticVariableOption(diags.data_manager.config.var_manager), DiagnosticFrequencyOption(), DiagnosticOption('grid', '')) options = cls.process_options(options, options_available) return options @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: variable, domain, frequency=day, grid='' :type options: list[str] :return: """ options = cls._process_options(diags, options) job_list = list() for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append(cls(diags.data_manager, startdate, member, chunk, options['domain'], options['variable'], options['frequency'], options['grid'])) return job_list def request_data(self): """Request data required by the diagnostic""" self.variable_file = self.request_chunk(self.domain, self.variable, self.startdate, self.member, self.chunk, frequency=self.frequency, grid=self.grid) def declare_data_generated(self): """Declare data to be generated by the diagnostic""" self.daymean = self.declare_chunk(self.domain, self.variable, self.startdate, self.member, self.chunk, frequency=Frequencies.daily, grid=self.grid) def compute_mean(self, input_file, output_file): """ Compute the time mean Parameters ---------- input_file: str output_file: str """ raise NotImplementedError() def compute(self): """Run the diagnostic""" temp = TempFile.get() handler = Utils.open_cdf(self.variable_file.local_file) if 'region' in handler.variables: noregion = TempFile.get() Utils.nco.ncks(input=self.variable_file.local_file, output=noregion, options=('-O -C -x -v region',)) self.compute_mean(noregion, temp) os.remove(noregion) monmean_handler = Utils.open_cdf(temp) Utils.copy_variable(handler, monmean_handler, 'region') monmean_handler.close() else: self.compute_mean(self.variable_file.local_file, temp) self.daymean.set_local_file(temp) class DailyMean(TimeMean): """ Calculates daily mean for a given variable :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 :param frequency: original frequency :type frequency: str :param grid: original data grid :type grid: str """ alias = 'daymean' "Diagnostic alias for the configuration file" def __init__(self, data_manager, startdate, member, chunk, domain, variable, frequency, grid): TimeMean.__init__(self, data_manager, startdate, member, chunk, domain, variable, frequency, grid) self._target_frequency = 'daily' def compute_mean(self, input_file, output_file): """ Compute the time mean Parameters ---------- input_file: str output_file: str """ Utils.cdo.daymean(input=input_file, output=output_file) class MonthlyMean(TimeMean): """ Calculates monthly mean for a given variable :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 :param frequency: original frequency :type frequency: str :param grid: original data grid :type grid: str """ alias = 'monmean' "Diagnostic alias for the configuration file" def __init__(self, data_manager, startdate, member, chunk, domain, variable, frequency, grid): TimeMean.__init__(self, data_manager, startdate, member, chunk, domain, variable, frequency, grid) self._target_frequency = 'monthly' def compute_mean(self, input_file, output_file): """ Computes the time mean Parameters ---------- input_file: str output_file: str """ Utils.cdo.monmean(input=input_file, output=output_file) class YearlyMean(TimeMean): """ Calculates monthly mean for a given variable :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 :param frequency: original frequency :type frequency: str :param grid: original data grid :type grid: str """ alias = 'yearmean' "Diagnostic alias for the configuration file" def __init__(self, data_manager, startdate, member, chunk, domain, variable, frequency, grid): TimeMean.__init__(self, data_manager, startdate, member, chunk, domain, variable, frequency, grid) self._target_frequency = 'yearly' def compute_mean(self, input_file, output_file): """ Compute the time mean Parameters ---------- input_file: str output_file: str """ Utils.cdo.monmean(input=input_file, output=output_file)