Source code for vortex_cen.algo.prosnow
# -*- coding: utf-8 -*-
"""
prosnow.py
----------
Algo Components for the PROSNOW project
.. inheritance-diagram:: vortex_cen.algo.prosnow
:top-classes: vortex_cen.algo.components._CenParaBlindRun, vortex_cen.algo.components._CenTaylorRun,
vortex_cen.algo.components._CenTaylorVortexWorker, vortex_cen.algo.components._CenWorkerBlindRun
vortex.algo.components.AlgoComponent, vortex.algo.components.Parallel, vortex.algo.components.TaylorRun
:private-bases:
:parts: 1
.. autoclass:: PrepareForcingComponentForecast
:no-members:
:show-inheritance:
.. autoclass:: ExtractForcingWorker
:no-members:
:show-inheritance:
.. autoclass:: ExtractForcingWorkerEnsembleForecast
:no-members:
:show-inheritance:
.. autoclass:: ExtractForcingWorkerLTForecast
:no-members:
:show-inheritance:
.. autoclass:: Prosnow_Parallel
:no-members:
:show-inheritance:
"""
from bronx.syntax.externalcode import ExternalCodeImportChecker
from vortex_cen.algo.ensemble import PrepareForcingComponent, PrepareForcingWorker
from vortex_cen.algo.deterministic import Surfex_Parallel
echecker = ExternalCodeImportChecker('snowtools')
with echecker:
from snowtools.tools.change_forcing import forcinput_extract, forcinput_changedates
from snowtools.tools.change_prep import prep_tomodify
from snowtools.tools.update_namelist import update_namelist_var
[docs]
@echecker.disabled_if_unavailable
class PrepareForcingComponentForecast(PrepareForcingComponent):
"""
It adapts forcing files to a ski resort geometry (several members in parallel).
This class was implemented by C. Carmagnola in May 2019 (PROSNOW project).
"""
_footprint = dict(
info = 'AlgoComponent that runs several executions in parallel',
attr = dict(
kind = dict(
values = ['extractforcing_STforecast', 'extractforcing_LTforecast']
)
)
)
def _default_common_instructions(self, rh, opts):
ddict = super(PrepareForcingComponent, self)._default_common_instructions(rh, opts)
for attribute in self.footprint_attributes:
if attribute in ['datebegin', 'dateend']:
ddict[attribute] = getattr(self, attribute)[0][0]
else:
ddict[attribute] = getattr(self, attribute)
return ddict
def execute(self, rh, opts):
self._default_pre_execute(rh, opts)
common_i = self._default_common_instructions(rh, opts)
subdirs = self.get_subdirs(rh, opts)
self._add_instructions(common_i, dict(subdir=subdirs))
self._default_post_execute(rh, opts)
def get_subdirs(self, rh, opts):
avail_members = self.context.sequence.effective_inputs(role=self.role_ref_namebuilder())
subdirs = list()
for am in avail_members:
if am.rh.container.dirname not in subdirs:
subdirs.append(am.rh.container.dirname)
return subdirs
def role_ref_namebuilder(self):
return 'Forcing'
[docs]
@echecker.disabled_if_unavailable
class Prosnow_Parallel(Surfex_Parallel):
"""
It adds snow management specificities by ski resorts to standard SURFEX-Crocus algo components.
This class was implemented by C. Carmagnola in April 2019 (PROSNOW project).
"""
_footprint = dict(
info = 'AlgoComponent designed to run SURFEX experiments over large domains with MPI parallelization.',
attr = dict(
insert_data = dict(
values = ['prosnow_insert_data', ],
type = str,
)
)
)
def prosnow_modify_namelist(self):
new_nam = update_namelist_var("OPTIONS_unmodified.nam", "water.txt")
return new_nam
def prosnow_modify_prep(self):
dateend_str = self.dateend.strftime('%Y%m%d%H')
my_name_OBS = 'OBS_' + dateend_str + '.nc'
my_name_PREP = 'PREP_' + dateend_str + '.nc'
old_prep = prep_tomodify(my_name_PREP)
new_prep = old_prep.insert_snow_depth('SRU.txt', 'snow.txt', my_name_OBS, 'prep_fillup_50.nc',
'prep_fillup_5.nc', 'variables', my_name_PREP)
return new_prep
def execute(self, rh, opts):
# Insert water consumption in namelist (before running surfex)
self.prosnow_modify_namelist()
# Call execute of Surfex_Parallel
# Note that modify_namelist and modify_prep methods of the mother class
# still have to be called in the following instruction
super().execute(rh, opts)
# Insert snow height in prep (after running surfex)
self.prosnow_modify_prep()