Source code for c3s_magic_wps.processes.wps_hyint

import logging
import os

from pywps import FORMATS, ComplexInput, ComplexOutput, Format, LiteralInput, LiteralOutput, Process
from pywps.app.Common import Metadata
from pywps.response.status import WPS_STATUS
from pywps.app.exceptions import ProcessError
from pywps.inout.literaltypes import AllowedValue
from pywps.validator.allowed_value import ALLOWEDVALUETYPE

from .utils import default_outputs, model_experiment_ensemble, outputs_from_plot_names, year_ranges, check_constraints

from .. import runner, util

LOGGER = logging.getLogger("PYWPS")


[docs]class HyInt(Process): def __init__(self): self.variables = ['pr'] self.frequency = 'day' inputs = [ *model_experiment_ensemble(model='ACCESS1-0', experiment='rcp85', ensemble='r1i1p1', min_occurs=2, max_occurs=100, required_variables=self.variables, required_frequency=self.frequency, exclude_historical=True), *year_ranges((1980, 2020)), LiteralInput( 'ref_model', 'Reference Model', abstract='Choose a reference model like ACCESS1-0.', data_type='string', allowed_values=['ACCESS1-0'], default='ACCESS1-0', min_occurs=1, max_occurs=1, ), LiteralInput( 'indices', 'Indices', abstract='Indices to be analysed and plotted.', data_type='string', allowed_values=[ "pa_norm", "hyint", "int_norm", "r95_norm", "wsl_norm", "dsl_norm", "int", "dsl", "wsl" ], default="hyint", min_occurs=1, max_occurs=9, ), LiteralInput( 'regions', 'Regions', abstract='Regions for timeseries and maps.', data_type='string', allowed_values=["GL", "GL60", "TR", "SA", "AF", "IN", "EU", "EA", "AU"], default="GL", min_occurs=1, max_occurs=5, ), LiteralInput( 'norm_year_start', 'Norm year start', abstract='First year of reference normalization period to be used for normalized indices. \ Must be inside of model data year range.', data_type='integer', default=1980, allowed_values=AllowedValue(allowed_type=ALLOWEDVALUETYPE.RANGE, minval=1850, maxval=2100) ), LiteralInput( 'norm_year_end', 'Norm year end', abstract='Last year of reference normalization period to be used for normalized indices. \ Must be inside of model data year range.', data_type='integer', default=1999, allowed_values=AllowedValue(allowed_type=ALLOWEDVALUETYPE.RANGE, minval=1850, maxval=2100) ), ] outputs = [ ComplexOutput('plot1', 'Plot1', abstract='Single panel lon/lat map per individual index, multi-year mean', as_reference=True, supported_formats=[Format('image/png')]), ComplexOutput('plot2', 'Plot2', abstract='3-panel lon/lat maps per individual index with comparison to reference dataset, \ multi-year mean', as_reference=True, supported_formats=[Format('image/png')]), ComplexOutput('plot3', 'Plot3', abstract='multipanel of indices of lon/lat maps with comparison to reference dataset, \ multi-year mean', as_reference=True, supported_formats=[Format('image/png')]), ComplexOutput('plot12', 'Plot12', abstract='multipanel of indices with timeseries over multiple regions', as_reference=True, supported_formats=[Format('image/png')]), ComplexOutput('plot13', 'Plot13', abstract='multipanel of indices with timeseries for multiple models', as_reference=True, supported_formats=[Format('image/png')]), ComplexOutput('plot14', 'Plot14', abstract='multipanel of indices with summary of trend coefficients over multiple regions', as_reference=True, supported_formats=[Format('image/png')]), ComplexOutput('plot15', 'Plot15', abstract='multipanel of indices with summary of trend coefficients for multiple models', as_reference=True, supported_formats=[Format('image/png')]), ComplexOutput('archive', 'Archive', abstract='The complete output of the ESMValTool processing as a zip archive.', as_reference=True, supported_formats=[Format('application/zip')]), *default_outputs(), ] super(HyInt, self).__init__( self._handler, identifier="hyint", title="HyInt - Hydroclimatic intensity and extremes", version=runner.VERSION, abstract="""HyInt hydroclimatic indices calculation and plotting. The estimated calculation time of this process is 30 minutes for the default values supplied. Selected models should be experiment (eg. "rcp85") and not historical. The historical data will be added automatically.""", metadata=[ Metadata('ESMValTool', 'http://www.esmvaltool.org/'), Metadata('Documentation', 'https://esmvaltool.readthedocs.io/en/v2.0a2/recipes/recipe_hyint.html', role=util.WPS_ROLE_DOC), ], inputs=inputs, outputs=outputs, status_supported=True, store_supported=True) def _handler(self, request, response): response.update_status("starting ...", 0) # build esgf search constraints constraints = dict( models=request.inputs['model'], experiments=request.inputs['experiment'], ensembles=request.inputs['ensemble'], reference=request.inputs['ref_model'][0].data, ) check_constraints(constraints) options = dict( indices=request.inputs['indices'][0].data, regions=request.inputs['regions'][0].data, norm_year_start=request.inputs['norm_year_start'][0].data, norm_year_end=request.inputs['norm_year_end'][0].data, ) if ((request.inputs['norm_year_start'][0].data < request.inputs['start_year'][0].data) or (request.inputs['norm_year_end'][0].data > request.inputs['end_year'][0].data)): raise ProcessError("Normalization year range not within model data range") # generate recipe response.update_status("generate recipe ...", 10) recipe_file, config_file = runner.generate_recipe( workdir=self.workdir, diag='hyint', constraints=constraints, options=options, start_year=request.inputs['start_year'][0].data, end_year=request.inputs['end_year'][0].data, output_format='png', ) # recipe output response.outputs['recipe'].output_format = FORMATS.TEXT response.outputs['recipe'].file = recipe_file # run diag response.update_status("running diagnostic (this could take a while)...", 20) result = runner.run(recipe_file, config_file) response.outputs['success'].data = result['success'] # log output response.outputs['log'].output_format = FORMATS.TEXT response.outputs['log'].file = result['logfile'] # debug log output response.outputs['debug_log'].output_format = FORMATS.TEXT response.outputs['debug_log'].file = result['debug_logfile'] if result['success']: try: self.get_outputs(constraints['models'], result, response) except Exception as e: response.update_status("exception occured: " + str(e), 85) else: LOGGER.exception('esmvaltool failed!') response.update_status("exception occured: " + result['exception'], 85) response.update_status("creating archive of diagnostic result ...", 90) response.outputs['archive'].output_format = Format('application/zip') response.outputs['archive'].file = runner.compress_output( os.path.join(self.workdir, 'output'), os.path.join(self.workdir, 'hyint_result.zip')) response.update_status("done.", 100) return response
[docs] def get_outputs(self, models, result, response): # result plot response.update_status("collecting output ...", 80) response.outputs['plot1'].output_format = Format('image/png') response.outputs['plot1'].file = runner.get_output(result['plot_dir'], path_filter=os.path.join('hyint', 'main'), name_filter="*_??_map", output_format="png") response.outputs['plot2'].output_format = Format('image/png') response.outputs['plot2'].file = runner.get_output(result['plot_dir'], path_filter=os.path.join('hyint', 'main'), name_filter="*comp_map", output_format="png") response.outputs['plot3'].output_format = Format('image/png') response.outputs['plot3'].file = runner.get_output(result['plot_dir'], path_filter=os.path.join('hyint', 'main'), name_filter="multiindex*_map", output_format="png") response.outputs['plot12'].output_format = Format('image/png') response.outputs['plot12'].file = runner.get_output(result['plot_dir'], path_filter=os.path.join('hyint', 'main'), name_filter="*multiregion_timeseries*", output_format="png") response.outputs['plot13'].output_format = Format('image/png') response.outputs['plot13'].file = runner.get_output(result['plot_dir'], path_filter=os.path.join('hyint', 'main'), name_filter="*_multimodel*_timeseries*", output_format="png") response.outputs['plot14'].output_format = Format('image/png') response.outputs['plot14'].file = runner.get_output(result['plot_dir'], path_filter=os.path.join('hyint', 'main'), name_filter="*multiregion_trend_summary*", output_format="png") response.outputs['plot15'].output_format = Format('image/png') response.outputs['plot15'].file = runner.get_output(result['plot_dir'], path_filter=os.path.join('hyint', 'main'), name_filter="*_multimodel*_trend_summary*", output_format="png") response.outputs['model'].output_format = FORMATS.NETCDF response.outputs['model'].file = runner.get_output(result['work_dir'], path_filter=os.path.join('hyint', 'main'), name_filter="hyint_{}*_ALL".format(models[0]), output_format="nc")