Source code for nes.nes_formats.monarch_format
#!/usr/bin/env python
import numpy as np
import nes
from netCDF4 import Dataset
from mpi4py import MPI
# noinspection DuplicatedCode
[docs]
def to_netcdf_monarch(self, path, chunking=False, keep_open=False):
"""
Create the NetCDF using netcdf4-python methods.
Parameters
----------
self : nes.Nes
Source projection Nes Object.
path : str
Path to the output netCDF file.
chunking: bool
Indicates if you want to chunk the output netCDF.
keep_open : bool
Indicates if you want to keep open the NetCDH to fill the data by time-step
"""
self.to_dtype(np.float32)
# Open NetCDF
if self.info:
print("Rank {0:03d}: Creating {1}".format(self.rank, path))
if self.size > 1:
netcdf = Dataset(path, format="NETCDF4", mode='w', parallel=True, comm=self.comm, info=MPI.Info())
else:
netcdf = Dataset(path, format="NETCDF4", mode='w', parallel=False)
if self.info:
print("Rank {0:03d}: NetCDF ready to write".format(self.rank))
# Create dimensions
self._create_dimensions(netcdf)
# Create dimension variables
self._lev['data'] = np.array(self._lev['data'], dtype=np.float32)
self._lat['data'] = np.array(self._lat['data'], dtype=np.float32)
self._lat_bnds['data'] = np.array(self._lat_bnds['data'], dtype=np.float32)
self._lon['data'] = np.array(self._lon['data'], dtype=np.float32)
self._lon_bnds['data'] = np.array(self._lon_bnds['data'], dtype=np.float32)
if isinstance(self, nes.RotatedNes):
self._rlat['data'] = np.array(self._rlat['data'], dtype=np.float32)
self._rlon['data'] = np.array(self._rlon['data'], dtype=np.float32)
if isinstance(self, nes.LCCNes) or isinstance(self, nes.MercatorNes):
self._y['data'] = np.array(self._y['data'], dtype=np.float32)
self._x['data'] = np.array(self._x['data'], dtype=np.float32)
self._create_dimension_variables(netcdf)
if self.info:
print("Rank {0:03d}: Dimensions done".format(self.rank))
# Create cell measures
if 'cell_area' in self.cell_measures.keys():
self.cell_measures['cell_area']['data'] = np.array(self.cell_measures['cell_area']['data'], dtype=np.float32)
self._create_cell_measures(netcdf)
# Create variables
self._create_variables(netcdf, chunking=chunking)
# Create metadata
self._create_metadata(netcdf)
# Close NetCDF
if self.global_attrs is not None:
for att_name, att_value in self.global_attrs.items():
netcdf.setncattr(att_name, att_value)
netcdf.setncattr('Conventions', 'CF-1.7')
if keep_open:
self.netcdf = netcdf
else:
netcdf.close()
return None
[docs]
def to_monarch_units(self):
"""
Change the data values according to the MONARCH conventions
Parameters
----------
self : nes.Nes
Returns
-------
dict
Variable in the MONARCH units
"""
for var_name in self.variables.keys():
if isinstance(self.variables[var_name]['data'], np.ndarray):
if self.variables[var_name]['units'] == 'mol.s-1.m-2':
# Kmol to mol
self.variables[var_name]['data'] = np.array(self.variables[var_name]['data'] * 1000, dtype=np.float32)
elif self.variables[var_name]['units'] == 'kg.s-1.m-2':
# No unit change needed
self.variables[var_name]['data'] = np.array(self.variables[var_name]['data'], dtype=np.float32)
else:
raise TypeError("The unit '{0}' of specie {1} is not defined correctly. ".format(
self.variables[var_name]['units'], var_name) +
"Should be 'mol.s-1.m-2' or 'kg.s-1.m-2'")
self.variables[var_name]['dtype'] = np.float32
return self.variables