# -*- coding: utf-8 -*-
"""
Module that contains various functions dedicated to the \
conversion of |pypago| outputs into NetCDF files` \
to :file:`.nc` files
"""
from netCDF4 import Dataset
import numpy as np
import pypago.misc
import pypago.pyio
import pypago.disp
from netcdftime import utime
[docs]def gridsec_tonc(finname, varname, section_names=None, units='days since 1900-01-01 00:00:00', calendar='gregorian'):
"""
Conversion of tracer and velocities along the
sections into |netcdf|. There will
be one file per section, in which the
variables will be saved. The absolute path of
the output files will be the same
as for the input file name, except that
the :file:`.pygo` will be replaced by
:file:`_sec_{SECTIONNAME}.nc`
:param str finname: output of the
:py:func:`pypago.loaddata.loaddata` function (must contain
a dictionary with the `MODEL_sections` and `MODEL_time` keys)
:param list section_names: Default is None.
If set, the list of the sections' names from which to extract the data
:param list varname: Default is None. If None, all the variables (`vect`,
`vecs` and `vecv` are extracted. If set, the list of the variables
names to extract
"""
modelsec = pypago.pyio.load(finname)
print(r'Conversion of the %s file into netcdf' % finname)
print(r'==============================================')
if section_names is None:
print(r'Processing of ALL the sections')
for secint in modelsec:
_write_gridsec_netcdf(finname, secint, varname, units, calendar)
print('section %s: done' % secint.name)
else:
# Conversion of section_names into list
if not(isinstance(section_names, 'list')):
section_names = [section_names]
print(r'Processing of the section list %s'
% section_names)
for secnames in section_names:
indice_sec = pypago.misc.findsecnum(modelsec, secnames)
secint = modelsec[indice_sec]
_write_gridsec_netcdf(finname, secint, varname, units, calendar)
print('section %s: done' % secint.name)
print('\n')
[docs]def gridvol_tonc(finname, varname, domain_names=None, units='days since 1900-01-01 00:00:00', calendar='gregorian'):
"""
Conversion of tracer fields within a domain into |netcdf|.
There will be one file per domain, in which the variables will be saved.
The absolute path of the output files will be the same
as for the input file name, except that the :file:`.pygo`
will be replaced by
:file:`_dom_{DOMAINNAME}.nc`
:param str finname: output of the
:py:func:`pypago.loaddata.loaddata` function (must contain
a dictionary with the `MODEL_areas` and `MODEL_time` keys)
:param list domain_names: Default is None. If set, the list of the domains'
names from which to extract the data
:param list varname: Default is None. If None, all the variables
(`temperature`, `salinity`) are extracted.
If set, the list of the variables names to extract
"""
modeldom = pypago.pyio.load(finname)
#modeldom = data['MODEL_areas']
#modeltime = data['MODEL_time']
print(r'Conversion of the %s file into netcdf' % finname)
print(r'==============================================')
if domain_names is None:
print(r'Processing of ALL the domains')
for domint in modeldom:
_write_gridvol_netcdf(finname, domint, varname, units, calendar)
print('domain %s: done' % domint.name)
else:
# Conversion of domain_names into list
if not(isinstance(domain_names, 'list')):
domain_names = [domain_names]
print(r'Processing of the domain list %s'
% domain_names)
for domnames in domain_names:
indice_dom = pypago.misc.finddomnum(modeldom, domnames)
domint = modeldom[indice_dom]
_write_gridvol_netcdf(finname, domint, varname, units, calendar)
print('domain %s: done' % domint.name)
print('\n')
[docs]def secind_tonc(finname, section_names=None):
"""
Conversion of section indices (issued from
:py:func:`pypago.pypago.indices_MODEL` function) in |netcdf|.
:param str finname: output of the
:py:func:`pypago.pypago.indices_MODEL` function
:param str section: Default is None. If set, the section to extract
"""
data = pypago.pyio.load(finname)
sectionind = data['MODEL_indices']
modeltime = data['MODEL_time']
print(r'Conversion of the %s file into netcdf' %
finname)
print(r'==========================================')
if section_names is None:
print(r'Processing of ALL the sections')
for secint in sectionind:
_write_secind_netcdf(finname, modeltime, secint)
print('section %s: done' % secint.name)
else:
print(r'Processing of the section list %s'
% section_names)
for secnames in section_names:
indice_section = pypago.misc.findsecnum(sectionind, secnames)
secint = sectionind[indice_section]
_write_secind_netcdf(finname, modeltime, secint)
print('section %s: done' % secint.name)
print('\n')
[docs]def sections_tonc(finname, section_names=None):
"""
Extraction of sections' endpoints into |netcdf| files
:param str finname: filename containing the list of sections' endpoints
(output of the :py:mod:`pypago.guis.gui_sections_edition`)
:param list section_names: Default is None. If set, the list of sections'
names from which to extract the endpoints
Convert all sections of :file:`sections_NA_Nico.pygo` to individual
|netcdf| files:
>>> _sections_tonc('sections_NA_Nico.pygo')
Convert only ``ar7`` section
>>> _sections_tonc('sections_NA_Nico.pygo', section_names=['ar7'])
What append if missing file ?
>>> _sections_tonc('badfile')
What append if missing section name in the file ?
>>> _sections_tonc('sections_NA_Nico.pygo', section_names=['badsection'])
"""
try:
pagosections = pypago.pyio.load(finname)
except IOError:
message = r'filename {0} not found'.format(finname)
error = Errors(message)
raise error
print(r'Conversion of the %s file into netcdf' % finname)
print(r'==============================================')
if section_names is None:
print(r'Processing of ALL the sections')
for secint in pagosections:
_write_sections_netcdf(finname, secint)
print('section %s: done' % secint.name)
else:
print(r'Processing of the section list %s'
% section_names)
for secnames in section_names:
try:
indice_sec = pypago.misc.findsecnum(pagosections, secnames)
except ValueError:
message = r'Can not produce NetCDF file'
error = Errors(message)
raise error
secint = pagosections[indice_sec]
_write_sections_netcdf(finname, secint)
print('section %s: done' % secint.name)
print('\n')
[docs]def _volind_tonc(finname, domain_names=None):
"""
Conversion of volume indices (issued from
:py:func:`pypago.pypago.volumes_MODEL` function) in |netcdf|.
:param str finname: output of
the :py:func:`pypago.pypago.volumes_MODEL` function
:param str domain: Default is None. If set, the domain to extract
"""
data = pypago.pyio.load(finname)
volumeind = data['MODEL_volumes']
modeltime = data['MODEL_time']
print(r'Conversion of the %s file into netcdf'
% finname)
print(r'==========================================')
if domain_names is None:
print(r'Processing of ALL the domains')
for domint in volumeind:
_write_volind_netcdf(finname, modeltime, domint)
print('domain %s: done' % domint.name)
else:
print(r'Processing of the domain list %s'
% domain_names)
for domnames in domain_names:
indice_dom = pypago.misc.finddomnum(volumeind, domnames)
domint = volumeind[indice_dom]
_write_volind_netcdf(finname, modeltime, domint)
print('\n')
[docs]def _write_gridsec_netcdf(finname, secint, varname, units, calendar):
"""
Function that handles the writing of individual |netcdf| section files
(called by :py:func:`pypago.tonc.gridsec_tonc` function)
:param str finname: output of the
:py:func:`pypago.pypago.sections_MODEL` function
:param float modeltime: time vector contained on the file
:param pypago.sections.GridSection secint: |pypago| object that contains the
index elements
:param str varname: variable name to save in the file ('vecv', 'vect' or
'vecv'. If None, all are saved)
"""
timename = dictvname['time_varname']
name = secint.name
nz, nl = secint.areavect.shape
nlvect = len(secint.lvect)
foutname = finname.replace('.pygo', '_sec_'+name+'.nc')
fout = Dataset(foutname, 'w')
fout.createDimension('z', nz)
fout.createDimension('l', nl)
fout.createDimension('lvect', nlvect)
fout.createDimension(timename, None)
# If time exists in the section attribute:
if hasattr(secint, timename):
# create time variable
fout.createVariable(timename, 'f', (timename, ))
# recover time variable
modeltime = secint.time
# if the variable is not made of numbers: conversion into
# numerical time
if not(isinstance(modeltime[0], (int, long, float))):
cdftime = utime(units, calendar)
modeltime = cdftime.date2num(modeltime)
fout.variables[timename].calendar = calendar
fout.variables[timename].units = units
fout.variables[timename][:] = modeltime
fout.createVariable('areavect', 'f', ('z', 'l'))
fout.variables['areavect'][:] = secint.areavect
fout.createVariable('depthvect', 'f', ('z', 'l'))
fout.variables['depthvect'][:] = secint.depthvect
fout.createVariable('veci', 'i', ('l', ))
fout.variables['veci'][:] = secint.veci
fout.createVariable('vecj', 'i', ('l', ))
fout.variables['vecj'][:] = secint.vecj
fout.createVariable('orient', 'i', ('l', ))
fout.variables['orient'][:] = secint.orient
facesout = np.empty(secint.faces.shape)
facesout[secint.faces == 'N'] = 1
facesout[secint.faces == 'W'] = 2
fout.createVariable('faces', 'i', ('l', ))
fout.variables['faces'][:] = facesout
fout.variables['faces'].description = '1 for N, 2 for W'
if not(isinstance(varname, list)):
varname = [varname]
for var in varname:
fout.createVariable(var, 'f', (timename, 'z', 'l',))
fout.variables[var][:] = secint.__dict__[var]
fout.close()
[docs]def _write_gridvol_netcdf(finname, domint, varname, units, calendar):
"""
Function that handles the writing of individual |netcdf| volume files
(called by :py:func:`pypago.tonc.gridvol_tonc` function)
:param str finname: output of the
:py:func:`pypago.pypago.sections_MODEL` function
:param float modeltime: time vector contained on the file
:param pypago.areas.Areas domint: |pypago| object that contains the
index elements
:param str varname: variable to save in the file ('salinity' or
'temperature'). If None, both are saved
"""
timename = dictvname['time_varname']
nz, npoints = domint.volume.shape
foutname = finname.replace('.pygo', '_dom_' + domint.name + '.nc')
fout = Dataset(foutname, 'w')
fout.createDimension(timename, None)
fout.createDimension('z', nz)
fout.createDimension('points', npoints)
# If time exists in the section attribute:
if hasattr(domint, timename):
# create time variable
fout.createVariable(timename, 'f', (timename, ))
# recover time variable
modeltime = domint.time
# if the variable is not made of numbers: conversion into
# numerical time
if not(isinstance(modeltime[0], (int, long, float))):
cdftime = utime(units, calendar)
modeltime = cdftime.date2num(modeltime)
fout.variables[timename].calendar = calendar
fout.variables[timename].units = units
fout.variables[timename][:] = modeltime
fout.createVariable('indi', 'i', ('points',))
fout.createVariable('indj', 'i', ('points', ))
fout.createVariable('volume', 'f', ('z', 'points', ))
fout.createVariable('surface', 'f', ('points', ))
fout.variables['indi'][:] = domint.i
fout.variables['indj'][:] = domint.j
fout.variables['volume'][:] = domint.volume
fout.variables['surface'][:] = domint.surface
# If the domain has been defined from sections,
# creation of section dimension and variables
if domint.secnames is not None:
nsec = len(domint.secnames)
fout.createDimension('section', nsec)
fout.createVariable('sectionsign', 'i', ('section', ))
fout.variables['sectionsign'][:] = domint.signs
fout.variables['sectionsign'].sections = ','.join(domint.secnames)
# barrier.n --- modified 2015-08-13
# this variable is not written in the file, since its
# dimensions are (lat, lon). To keep it, we must add
# these two dimensions in the file
# fout.variables['mask'][:] = domint.mask
# fout.createVariable('mask', 'i', ('points', ))
if not(isinstance(varname, list)):
varname = [varname]
for var in varname:
if(domint.__dict__[var].ndim == 3):
fout.createVariable(var, 'f', (timename, 'z', 'points'))
fout.variables[var][:] = domint.__dict__[var]
elif(domint.__dict__[var].ndim == 2):
fout.createVariable(var, 'f', (timename, 'points'))
fout.variables[var][:] = domint.__dict__[var]
else:
print('Not implemented !')
fout.close()
[docs]def _write_secind_netcdf(finname, modeltime, secint):
"""
Function that handles the writing of individual |netcdf| index files
(called by :py:func:`pypago.tonc.secind_tonc` function)
:param str finname: output of the
:py:func:`pypago.pypago.indices_MODEL` function
:param float modeltime: time vector contained on the file
:param pypago.sections.GridSection secint: |pypago| object that contains the
volume elements
"""
name = secint.name
nl = secint.bpmt_vec.shape[1]
foutname = finname.replace('.pygo', '_sec_' + name + '.nc')
fout = Dataset(foutname, 'w')
fout.createDimension('time', None)
fout.createDimension('l', nl)
fout.createVariable('time', 'f', ('time', ))
fout.variables['time'] = modeltime
fout.createVariable('lindex', 'i', ('l',))
fout.variables['lindex'] = np.arange(0, nl)
# barrier.n -- modified 2015-08-07
# instead of using exceptions, we check for
# the variable type and the variable dimension
for key, val in zip(secint.__dict__.keys(),
secint.__dict__.values()):
if isinstance(val, np.ndarray):
if val.ndim == 2: # for the _vec variables
fout.createVariable(key, 'f', ('time', 'l'))
fout.variables[key][:] = val
else:
fout.createVariable(key, 'f', ('time', ))
fout.variables[key][:] = val
[docs]def _write_sections_netcdf(finname, secint):
"""
Function that handles the writing of individual section endpoints files
(called by :py:func:`pypago.tonc.sections_tonc` function)
:param str finname: output of the
:py:mod:`pypago.guis.ihm_editions_sections` module
:param pypago.sections.Section secint: |pypago| object that contains the
section element
"""
name = secint.name
lon = secint.lon
lat = secint.lat
dire = secint.dir
dire = np.array(dire)
dirout = np.empty(dire.shape)
dirout[dire == 'NE'] = 1
dirout[dire == 'NW'] = 2
dirout[dire == 'SE'] = 3
dirout[dire == 'SW'] = 4
npoint = len(lon)
nseg = len(dirout)
foutname = finname.replace('.pygo', '_'+name+'.nc')
fout = Dataset(foutname, 'w')
fout.createDimension('npoint', npoint)
fout.createDimension('nseg', nseg)
fout.createVariable('lon', 'f', ('npoint', ))
fout.createVariable('lat', 'f', ('npoint', ))
fout.createVariable('dir', 'i', ('nseg', ))
fout.variables['lon'][:] = lon
fout.variables['lat'][:] = lat
fout.variables['dir'][:] = dirout
fout.variables['dir'].description = '1 for NE, 2 for NW, 3 \
for SE and 4 for SW'
fout.close()
[docs]def _write_volind_netcdf(finname, modeltime, domint):
"""
Function that handles the writing of individual |netcdf| volume files
(called by :py:func:`pypago.tonc.volind_tonc` function)
:param str finname: output of the
:py:func:`pypago.pypago.volumes_MODEL` function
:param float modeltime: time vector contained on the file
:param pypago.areas.Areas domint: |pypago| object that contains
the volume index elements
"""
name = domint.name
foutname = finname.replace('.pygo', '_dom_'+name+'.nc')
fout = Dataset(foutname, 'w')
fout.createDimension('time', None)
fout.createVariable('time', 'f', ('time', ))
fout.variables['time'] = modeltime
# barrier.n -- modified 2015-08-07
# instead of using exceptions, we check for
# the variable type and the variable dimension
for key, val in zip(domint.__dict__.keys(),
domint.__dict__.values()):
if isinstance(val, np.ndarray):
fout.createVariable(key, 'f', ('time',))
fout.variables[key][:] = val
fout.close()