Source code for earthdiagnostics.general.simplify_dimensions

# coding=utf-8
"""Convert i j files to lon lat when there is no interpolation required"""
import numpy as np
from earthdiagnostics.general.fix_file import FixFile
from earthdiagnostics.diagnostic import DiagnosticOption, DiagnosticDomainOption, \
    DiagnosticVariableListOption
from earthdiagnostics.utils import Utils, TempFile


[docs]class SimplifyDimensions(FixFile): """ Convert i j files to lon lat when there is no interpolation required i.e. lon is constant over i and lat is constat over j Parameters ---------- data_manager: DataManager startdate: str member: int chunk: init domain: ModellingRealm variable: str grid: str or None data_convention: str """ alias = 'simdim' "Diagnostic alias for the configuration file" def __init__(self, data_manager, startdate, member, chunk, domain, variable, grid, data_convention): FixFile.__init__(self, data_manager, startdate, member, chunk, domain, variable, grid) if data_convention in ('cmip6', 'primavera'): self.lon_name = 'longitude' self.lat_name = 'latitude' else: self.lon_name = 'lon' self.lat_name = 'lat' def __str__(self): return 'Simplify dimension Startdate: {0} Member: {1} Chunk: {2} ' \ 'Variable: {3}:{4} Grid: {5}'.format(self.startdate, self.member, self.chunk, self.domain, self.variable, self.grid) 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.domain == other.domain and self.variable == other.variable and self.grid == self.grid
[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: domain,variables,grid :type options: list[str] :return: """ options_available = (DiagnosticDomainOption(), DiagnosticVariableListOption(diags.data_manager.config.var_manager, 'variables'), DiagnosticOption('grid', '')) options = cls.process_options(options, options_available) job_list = list() variables = options['variables'] for var in variables: for startdate, member, chunk in diags.config.experiment.get_chunk_list(): job_list.append(SimplifyDimensions(diags.data_manager, startdate, member, chunk, options['domain'], var, options['grid'], diags.config.data_convention)) return job_list
[docs] def compute(self): """Run the diagnostic""" handler = Utils.open_cdf(self.variable_file.local_file) if 'i' not in handler.dimensions: raise Exception('Variable {0.domain}:{0.variable} does not have i,j dimensions'.format(self)) lat = handler.variables[self.lat_name] lat_values = lat[:, 0:1] # noinspection PyTypeChecker if np.any((lat[:] - lat_values) != 0): raise Exception('Latitude is not constant over i dimension for variable ' '{0.domain}:{0.variable}'.format(self)) lon = handler.variables[self.lon_name] lon_values = lon[0:1, :] # noinspection PyTypeChecker if np.any((lon[:] - lon) != 0): raise Exception('Longitude is not constant over j dimension for variable ' '{0.domain}:{0.variable}'.format(self)) temp = TempFile.get() new_file = Utils.open_cdf(temp, 'w') for dim in handler.dimensions.keys(): if dim in (self.lon_name, self.lat_name, 'i', 'j', 'vertices'): continue Utils.copy_dimension(handler, new_file, dim, new_names={'i': self.lon_name, 'j': self.lat_name}) new_file.createDimension(self.lon_name, handler.dimensions['i'].size) new_file.createDimension(self.lat_name, handler.dimensions['j'].size) new_file.createDimension('vertices', 2) for var in handler.variables.keys(): if var in (self.lon_name, self.lat_name, 'i', 'j', '{0}_vertices'.format(self.lon_name), '{0}_vertices'.format(self.lat_name)): continue Utils.copy_variable(handler, new_file, var, new_names={'i': self.lon_name, 'j': self.lat_name}) self._create_var(self.lon_name, lon_values, handler, new_file) self._create_var(self.lat_name, lat_values, handler, new_file) handler.close() new_file.close() self.simplified.set_local_file(temp)
@staticmethod def _create_var(var_name, var_values, source, destiny): old_var = source.variables[var_name] new_var = destiny.createVariable(var_name, old_var.dtype, dimensions=(var_name, )) new_var[:] = var_values Utils.copy_attributes(new_var, old_var) vertices_name = '{0}_vertices'.format(var_name) if vertices_name in source.variables: var_vertices = source.variables[vertices_name] if var_name == 'lon': vertices_values = var_vertices[0:1, :, 2:] else: vertices_values = var_vertices[:, 0:1, 1:3] new_lat_vertices = destiny.createVariable(vertices_name, var_vertices.dtype, dimensions=(var_name, 'vertices')) new_lat_vertices[:] = vertices_values Utils.copy_attributes(new_lat_vertices, var_vertices)