diff --git a/heat2urbanimpact_control.py b/heat2urbanimpact_control.py index dd36ed791bd136b26c76e440116ba480f9ce7358..c09892eb956226e651116f36c5176bb5daaa7cad 100644 --- a/heat2urbanimpact_control.py +++ b/heat2urbanimpact_control.py @@ -1 +1,209 @@ -#freva plugin development +# SPDX-FileCopyrightText: 2024 Deutsche Klimarechenzentrum +# +# SPDX-License-Identifier: EUPL-1.2 + +""" +heat2urbanimpact_test plugin API wrapper. +""" + +###################################################### +# import commonly used libraries. You can add/remove +# libraries as needed +###################################################### + +import json +from pathlib import Path + +# from evaluation_system.api.exceptions import PluginError +from typing import List, Optional + +from evaluation_system.api import plugin + +# from evaluation_system.api.parameters import ( +# Bool, +# CacheDirectory, +# Directory, +# Float, +# InputDirectory, +# Integer, +# ParameterDictionary, +# SelectField, +# SolrField, +# String, +# ) +from evaluation_system.api.parameters import ( + CacheDirectory, + Directory, + Integer, + ParameterDictionary, + SelectField, + String, +) + + +class heat2urbanimpact_test(plugin.PluginAbstract): + ###################################################### + # Define the details for the plugin + ###################################################### + + # Version of the heat2urbanimpact_test plugin (major, minor, patch) * Mandatory + __version__ = (0, 0, 0) + # Short Description of the heat2urbanimpact_test plugin * Mandatory + __short_description__: str = ( + "Heat period data from regional climate models for urban impact models" + ) + # Optional category this plugin belongs to + __category__: Optional[str] = "Support" + # Optional tags, that are the plugin can be described with and found by + __tags__: Optional[List[str]] = [ + "heat", + "regional climate model", + "urban climate model", + ] + # Optional author of the plugin + tool_developer: Optional[str] = "Bente Tiedje, Astrid Ziemann" + # Optional long description of the author of the plugin + __long_description__: Optional[ + str + ] = "This plugin processes the development of the atmospheric temperature stratification during a specified heat period from regional climate model data and tailors the data for the usage in urban impact models. For a selectable region of interest and period of time this plugin returns hourly temperature data at different layers/hights in a directly usable format (format specification). This plugin is based on the NUKLEUS ensemble of 3km horizontal grid." + + ###################################################### + # Define the parameters for the plugin * Mandatory + ###################################################### + + __parameters__ = ParameterDictionary( + SelectField( + name="experiment", + options={"GWL 2°C": "ssp370-gwl2k", "GWL 3°C": "ssp370-gwl3k"}, + help=("Please select the global warming level of interest."), + ), + String( + name="shape_file", + default="None", + help=( + "Please enter something. Doesn't work yet. Needs to be copied from climpact: Select a geo reference file defining your region of interest, if None is selected (default), the whole region, that is defined in the climate data will be taken. Note: You can either select a path on the HPC system, or a web url pointing to the file." + ), + ), + SelectField( + name="region", + options={ + "municipality 1": "mun1", + "municipality 2": "mun2", + "municipality 3": "mun3", + }, + help=( + "Please select something. Doesn't work yet. Needs to be copied from climpact: Select a pre defined German municipality of interest. This selection has only effect if you don't chose a shape file." + ), + ), + String( + name="split_by", + default="None", + help=( + "Please enter something. Doesn't work yet. Needs to be copied from climpact: If your selected geo reference file has multiple geometries and you whish to process each geometry separatly you can choose a split key that splits the geometries into different sub regions. The values for the split key will thereby used to distinguish the sub regions." + ), + ), + SelectField( + name="event", + options={ + "75th percentile": "75", + "95th percentile": "95", + "99th percentile": "99", + }, + default="95", + help=( + "Please select the exceptionality of the heat period by selecting percentiles of temperature probability distribution. Default is the 95th percentile." + ), + ), + Integer( + name="length_of_event", + default=3, + help=( + "Please enter the number of days of the heat period you would like to receive as output. An integer between 1 and 14 days would be plausible. Default is 3 days." + ), + ), + String( + name="months_of_event", + default="July", + help=( + "Please enter the month(s) when your heat event is supposed to happen for your studies. E.g. for single month 'June' or for multiple months 'May:August'. Default is 'July'." + ), + ), + SelectField( + name="impact_model", + options={"PALM4U": "PALM4U", "ENVI-met": "ENVI-met"}, + help=( + "The format of the output will be tailored for the selected impact model." + ), + ), + # Bool( + # name="checkbox", + # default=True, + # ), + # InputDirectory( + # name="inputdirectory", + # ), + # SolrField( + # name="solrfield", + # facet="facet", + # group=1, + # multiple=False, + # predefined_facets=None, + # editable=True, + # ), + Directory( + name="outputdir", + default="$USER_OUTPUT_DIR/$SYSTEM_DATETIME", + mandatory=True, + help=("The default output directory for the freva-wrk instance"), + ), + CacheDirectory( + name="cache", + default="$USER_CACHE_DIR", + mandatory=True, + ), + # SelectField( + # name="selectfield", + # options={"first": "1st", "second": "2nd"}, + # ), + # Integer( + # name="integer", + # default=1, + # ), + # Float( + # name="float", + # default=1.0, + # ), + # Directory( + # name="outputdir", + # ), + ) + + def run_tool(self, config_dict=None): + import os + + os.makedirs(config_dict["cache"], exist_ok=True) + os.makedirs(config_dict["outputdir"], exist_ok=True) + errorfile = Path(config_dict["cache"]) / "error.log" + json_file = Path(config_dict["cache"]) / "out.json" + with json_file.open("w") as json_f: + json.dump(config_dict, json_f, indent=4) + with errorfile.open("w") as error_f: + self.call( + f"python {Path(__file__).parent / '/src/heat2urbanimpact_test/scientific_code.py'} {json_file}", + stderr=error_f, + ) + + # self.call(f"python scientific_code.py {config_dict}") + # self.call(f"python template_plugin.py arg1 arg2 {config_dict}") + # self.call(f"template_runner.sh {config_dict}") + + # json_file = Path(config_dict["cache"]) / "out.json" + # with json_file.open("w") as json_f: + # json.dump(config_dict, json_f, indent=4) + # with errorfile.open("w") as error_f: + # self.call( + # f"{self.class_basedir}/main_runner.sh {json_file}", + # stderr=error_f, + # ) + return self.prepare_output(config_dict["outputdir"]) +