From 257713bcaaef7d0161b5efaa34dd514fcd192a94 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 30 Sep 2024 15:41:31 +0200 Subject: [PATCH 01/11] add documentation using mkdocs --- docs/assets/ecoextreml_logo.png | Bin 0 -> 87342 bytes docs/contributing_guide.md | 1 + docs/getting_started.md | 1 + docs/index.md | 7 +++++ docs/requirements.txt | 4 +++ docs/run_model.md | 1 + mkdocs.yml | 51 ++++++++++++++++++++++++++++++++ 7 files changed, 65 insertions(+) create mode 100644 docs/assets/ecoextreml_logo.png create mode 100644 docs/contributing_guide.md create mode 100644 docs/getting_started.md create mode 100644 docs/index.md create mode 100644 docs/requirements.txt create mode 100644 docs/run_model.md create mode 100644 mkdocs.yml diff --git a/docs/assets/ecoextreml_logo.png b/docs/assets/ecoextreml_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..dd892c52e75a4014526e892e94d073374f36babf GIT binary patch literal 87342 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

1NW!-|l0$0aE6jS*mx4lvZkv8(Rdvew-54#y9g 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 z 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 Awg3PC literal 0 HcmV?d00001 diff --git a/docs/contributing_guide.md b/docs/contributing_guide.md new file mode 100644 index 00000000..a6b802c4 --- /dev/null +++ b/docs/contributing_guide.md @@ -0,0 +1 @@ +{% include-markdown "../CONTRIBUTING.md" start="# Contributing guidelines" heading-offset=2%} \ No newline at end of file diff --git a/docs/getting_started.md b/docs/getting_started.md new file mode 100644 index 00000000..a9c45e7c --- /dev/null +++ b/docs/getting_started.md @@ -0,0 +1 @@ +# Installation requirements \ No newline at end of file diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..d14a2278 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,7 @@ +# STEMMUS_SCOPE + +Integrated code of SCOPE and STEMMUS. + +SCOPE is a radiative transfer and energy balance model, and STEMMUS model is a two-phase mass and heat transfer model. For more information about the coupling between these two models, please check [this reference](https://gmd.copernicus.org/articles/14/1379/2021/). +![img](https://raw.githubusercontent.com/EcoExtreML/STEMMUS_SCOPE/main/docs/assets/imgs/coupling_scheme.png) +(by Zeng & Su, 2021) \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000..6253c1f1 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,4 @@ +mkdocs +mkdocs-material +mkdocs-gen-files +mkdocs-include-markdown-plugin \ No newline at end of file diff --git a/docs/run_model.md b/docs/run_model.md new file mode 100644 index 00000000..48c992e1 --- /dev/null +++ b/docs/run_model.md @@ -0,0 +1 @@ +# How to run the model \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 00000000..e7d7db80 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,51 @@ +site_name: STEMMUS_SCOPE documentation +repo_url: https://github.com/EcoExtreML/STEMMUS_SCOPE +repo_name: STEMMUS_SCOPE + +nav: + - Introduction: index.md + - Getting started: getting_started.md + - Run the model: run_model.md + - Contributing guide: contributing_guide.md + +theme: + name: material + custom_dir: docs/assets + logo: assets/ecoextreml_logo.png + features: + - navigation.instant + - navigation.tabs + - navigation.tabs.sticky + icon: + repo: fontawesome/brands/github-alt + + palette: + # Palette toggle for light mode + - scheme: default + toggle: + icon: material/weather-sunny + name: Switch to dark mode + primary: light green + accent: green + + # Palette toggle for dark mode + - scheme: slate + toggle: + icon: material/weather-night + name: Switch to light mode + primary: blue grey + accent: teal + +plugins: +- include-markdown +- search + +markdown_extensions: + - pymdownx.highlight: + anchor_linenums: true + - pymdownx.superfences + - pymdownx.details + - admonition + +extra: + generator: false From 6e4d831916480f218cdb3c0610ddd5b41ff3daba Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 30 Sep 2024 15:42:10 +0200 Subject: [PATCH 02/11] add a github workflow to build the docs --- .github/workflows/doc_deploy.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/doc_deploy.yml diff --git a/.github/workflows/doc_deploy.yml b/.github/workflows/doc_deploy.yml new file mode 100644 index 00000000..b9c4034c --- /dev/null +++ b/.github/workflows/doc_deploy.yml @@ -0,0 +1,27 @@ +# Deploy documentation when push to main + +name: Deploy docs + +on: + push: + branches: [ "main" ] + +jobs: + build: + name: Deploy docs + runs-on: ubuntu-latest + steps: + - name: Checkout main + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Python 3.11 + uses: actions/setup-python@v2 + with: + python-version: "3.11" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install -r docs/requirements.txt + - name: Deploy docs + run: mkdocs gh-deploy --force From 38eb832f78aafb0627bd6be9571549fdb14a5aa7 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Tue, 1 Oct 2024 14:46:36 +0200 Subject: [PATCH 03/11] polish documentation --- README.md | 33 ++----- docs/STEMMUS_SCOPE_on_CRIB.md | 141 +++++++++++++++--------------- docs/STEMMUS_SCOPE_on_Snellius.md | 94 ++++++++++---------- docs/getting_started.md | 54 +++++++++++- docs/run_model.md | 4 +- mkdocs.yml | 2 +- 6 files changed, 180 insertions(+), 148 deletions(-) diff --git a/README.md b/README.md index 49a4faa0..789fbf4e 100644 --- a/README.md +++ b/README.md @@ -3,38 +3,14 @@ Integrated code of SCOPE and STEMMUS. SCOPE is a radiative transfer and energy balance model, and STEMMUS model is a two-phase mass and heat transfer model. For more information about the coupling between these two models, please check [this reference](https://gmd.copernicus.org/articles/14/1379/2021/). Before running the model, you need to prepare input data and a configuration file. This can be done using the python package -[PyStemmusScope](https://pystemmusscope.readthedocs.io). +[PyStemmusScope](https://pystemmusscope.readthedocs.io). ![img](https://raw.githubusercontent.com/EcoExtreML/STEMMUS_SCOPE/main/docs/assets/imgs/coupling_scheme.png) (by Zeng & Su, 2021) -## Running STEMMUS_SCOPE - -```mermaid -flowchart LR - subgraph Platform - direction RL - b[Snellius] - c[CRIB] - d[Your own machine] - end - A(Data) - Platform --> A - B(Config file) - A --> B - C{{Run model}} - B --> C - click b "https://github.com/EcoExtreML/STEMMUS_SCOPE/tree/main/docs/STEMMUS_SCOPE_on_Snellius.md" "Run STEMMUS_SCOPE on Snellius" _blank - click c "https://github.com/EcoExtreML/STEMMUS_SCOPE/tree/main/docs/STEMMUS_SCOPE_on_CRIB.md" "Run STEMMUS_SCOPE on CRIB" _blank - click d "https://github.com/EcoExtreML/STEMMUS_SCOPE/tree/main/docs/STEMMUS_SCOPE_on_local_device.md" "Run STEMMUS_SCOPE on your own machine" _blank -``` -About how to run `STEMMUS_SCOPE` on Snellius, check [./docs/STEMMUS_SCOPE_on_Snellius.md](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/docs/STEMMUS_SCOPE_on_Snellius.md). - -If you want to run `STEMMUS_SCOPE` on CRIB, check [./docs/STEMMUS_SCOPE_on_CRIB.md](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/docs/STEMMUS_SCOPE_on_CRIB.md). - -If you want to run `STEMMUS_SCOPE` on your own machine, check [./docs/STEMMUS_SCOPE_on_local_device.md](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/docs/STEMMUS_SCOPE_on_local_device.md). - -`STEMMUS_SCOPE` scope also has a Basic Model Interface (BMI) mode implemented. The full BMI is implemented in Python in [PyStemmusScope](https://github.com/EcoExtreML/STEMMUS_SCOPE_Processing/). For more information, check [./docs/STEMMUS_SCOPE_BMI.md](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/docs/STEMMUS_SCOPE_BMI.md). +## Documentation + +The documentation of the STEMMUS_SCOPE model can be found [here](https://ecoextreml.github.io/STEMMUS_SCOPE/). ## Contributing @@ -42,5 +18,6 @@ If you want to contribute to the development of `STEMMUS_SCOPE`, have a look at the [contribution guidelines](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/CONTRIBUTING.md). ## How to cite us + [![RSD](https://img.shields.io/badge/rsd-ecoextreml-00a3e3.svg)](https://research-software-directory.org/projects/ecoextreml) diff --git a/docs/STEMMUS_SCOPE_on_CRIB.md b/docs/STEMMUS_SCOPE_on_CRIB.md index b35d0668..60cc231c 100644 --- a/docs/STEMMUS_SCOPE_on_CRIB.md +++ b/docs/STEMMUS_SCOPE_on_CRIB.md @@ -4,72 +4,74 @@ ### Dataflow of STEMMUS_SCOPE on CRIB: -1. Data required by the model are in a folder named "input" under project - directory on CRIB. This folder includes: - - - Plumber2_data: the forcing/driving data provided by PLUMBER2. - - SoilProperty: the soil texture data and soil hydraulic parameters. - - Below the directory explanations are from [SCOPE - documentation](https://scope-model.readthedocs.io/en/latest/directories.html): - - - directional: the observer’s zenith and azimuth angles.(only used for - multi-angle simulations (if the option ‘directional’ is switched on in - parameters). - - fluspect_parameters: absorption spectra of different leaf components are - provided, according to PROSPECT 3.1, as well as Fluspect input: standard - spectra for PSI and PSII. - - leafangles: example leaf inclination distribution data are provided. - - radiationdata: RTMo.m calculates spectra based on MODTRAN5 outputs (T-18 - system).Note that in the input data (files as well as the spreadsheet), - the broadband input radiation may be provided. SCOPE linearly scales the - input spectra of the optical and the thermal domain in such a way that - the spectrally integrated input shortwave and long-wave radiation matches - with the measured values. - - soil_spectra: the soil spectrum is provided. Note that it is also possible - to simulate a soil reflectance spectrum with the BSM model. In that case, - the values for the BSM model parameters are taken from the input data, and - the archived spectra in this folder are not used. - - input_data.xlsx: the input to SCOPE model is provided. It - provides parameter inputs for PROSPECT, leaf_biochemical, fluorescence, - soil, canopy, aerodynamic, angles, photosynthetic temperature dependence - functional parameters, etc. - - input_soilLayThick.csv (optional): A file to change the discretization of - the soil layers of the STEMMUS model. An example of this file is in - [example_data folder](../example_data). This file (if needed) should be copied into the - `InputPath` folder. If this file is used, it will override the default settings of - the soil layers. The file has three columns: 1) layer number, 2) layer thickness, - and 3) maximum root depth. The user is free to change the values of the three columns. - Also, the number of rows determines the number of the soil layers and the total - thickness of the soil column (sum of soil layer thickness). - -2. Config file: it is a text file that sets the paths **required** by the - model. For example, see [config_file_crib.txt](../config_file_crib.txt) in this - repository. This file includes: - - - SoilPropertyPath: a path to soil texture data and soil hydraulic - parameters. - - InputPath: this is the working/running directory of the model and should - include the data of `directional`, `fluspect_parameters`, `leafangles`, - `radiationdata`, `soil_spectra`, and `input_data.xlsx`. - - OutputPath: this is the base path to store outputs of the model. When the - model runs, it creates `sitename_timestamped` directories under this - path. - - ForcingPath: a path to the forcing/driving data. I.e. the Plumber2 dataset. - - Location: Location where the model should be run. Currently, - the model runs at the site scale. For example, if we put `FI-Hyy` here, the model - runs at the `FI-Hyy` site. - - StartTime: The start time of the model, in the ISO 8601 format. For example: - `2001-01-01T00:00`. Note that the time can only be defined in half hour increments. - If you want the start time to be the first available data point of the forcing data, - you can set StartTime to `NA`. - - EndTime: The end time of the model. Formatted the same way as the StartTime. - For example: `2001-12-31T23:30`. If you want the end time to be the last available - data point of the forcing data, you can set EndTime to `NA`. - - To edit the config file, open the file with a text editor and change the - paths. The variable names e.g. `SoilPropertyPath` should not be changed. - Also, note a `/` is required at the end of each line. +Data required by the model are in a folder named "input" under project directory +on CRIB. This folder includes: + +- Plumber2_data: the forcing/driving data provided by PLUMBER2. +- SoilProperty: the soil texture data and soil hydraulic parameters. + +Below the directory explanations are from [SCOPE +documentation](https://scope-model.readthedocs.io/en/latest/directories.html): + +- directional: the observer’s zenith and azimuth angles.(only used for + multi-angle simulations (if the option ‘directional’ is switched on in + parameters). +- fluspect_parameters: absorption spectra of different leaf components are + provided, according to PROSPECT 3.1, as well as Fluspect input: standard + spectra for PSI and PSII. +- leafangles: example leaf inclination distribution data are provided. +- radiationdata: RTMo.m calculates spectra based on MODTRAN5 outputs (T-18 + system).Note that in the input data (files as well as the spreadsheet), + the broadband input radiation may be provided. SCOPE linearly scales the + input spectra of the optical and the thermal domain in such a way that + the spectrally integrated input shortwave and long-wave radiation matches + with the measured values. +- soil_spectra: the soil spectrum is provided. Note that it is also possible + to simulate a soil reflectance spectrum with the BSM model. In that case, + the values for the BSM model parameters are taken from the input data, and + the archived spectra in this folder are not used. +- input_data.xlsx: the input to SCOPE model is provided. It + provides parameter inputs for PROSPECT, leaf_biochemical, fluorescence, + soil, canopy, aerodynamic, angles, photosynthetic temperature dependence + functional parameters, etc. +- input_soilLayThick.csv (optional): A file to change the discretization of + the soil layers of the STEMMUS model. An example of this file is in + [example_data folder](../example_data). This file (if needed) should be copied into the + `InputPath` folder. If this file is used, it will override the default settings of + the soil layers. The file has three columns: 1) layer number, 2) layer thickness, + and 3) maximum root depth. The user is free to change the values of the three columns. + Also, the number of rows determines the number of the soil layers and the total + thickness of the soil column (sum of soil layer thickness). + +### Configuration file: + +Config file: it is a text file that sets the paths **required** by the + model. For example, see [config_file_crib.txt](../config_file_crib.txt) in this + repository. This file includes: + + - SoilPropertyPath: a path to soil texture data and soil hydraulic + parameters. + - InputPath: this is the working/running directory of the model and should + include the data of `directional`, `fluspect_parameters`, `leafangles`, + `radiationdata`, `soil_spectra`, and `input_data.xlsx`. + - OutputPath: this is the base path to store outputs of the model. When the + model runs, it creates `sitename_timestamped` directories under this + path. + - ForcingPath: a path to the forcing/driving data. I.e. the Plumber2 dataset. + - Location: Location where the model should be run. Currently, + the model runs at the site scale. For example, if we put `FI-Hyy` here, the model + runs at the `FI-Hyy` site. + - StartTime: The start time of the model, in the ISO 8601 format. For example: + `2001-01-01T00:00`. Note that the time can only be defined in half hour increments. + If you want the start time to be the first available data point of the forcing data, + you can set StartTime to `NA`. + - EndTime: The end time of the model. Formatted the same way as the StartTime. + For example: `2001-12-31T23:30`. If you want the end time to be the last available + data point of the forcing data, you can set EndTime to `NA`. + + To edit the config file, open the file with a text editor and change the + paths. The variable names e.g. `SoilPropertyPath` should not be changed. + Also, note a `/` is required at the end of each line. As explained above, the "InputPath" directory of the model is considered as the working/running directory and should include some data required by the @@ -89,12 +91,9 @@ working/running directory. The `.dat` files are stored in the "InputPath" directory. In addition, the model reads the site information i.e. the location and vegetation parameters. -1. The model reads the soil parameters from "SoilPropertyPath" using - `soilpropertyread.m`. -2. Some constants are loaded using `Constant.m`. -3. The model runs step by step until the whole simulation period is completed +2. The model runs step by step until the whole simulation period is completed i.e till the last time step of the forcing data. -4. The results are saved as binary files temporarily. Then, the binary files are +3. The results are saved as binary files temporarily. Then, the binary files are converted to `.csv` files and stored in a `sitename_timestamped` output directory under "OutputPath". diff --git a/docs/STEMMUS_SCOPE_on_Snellius.md b/docs/STEMMUS_SCOPE_on_Snellius.md index 19525286..69e1b0ec 100644 --- a/docs/STEMMUS_SCOPE_on_Snellius.md +++ b/docs/STEMMUS_SCOPE_on_Snellius.md @@ -5,52 +5,54 @@ Dutch National supercomputer hosted at SURF. ### Dataflow of STEMMUS_SCOPE on Snellius: -1. Data required by the model are in a folder named "data" in the project - directory `einf2480` on Snellius. This directory includes: - - - forcing/plumber2_data: the forcing/driving data provided by PLUMBER2. - - model_parameters/soil_property: the soil texture data and soil hydraulic parameters. - - model_parameters/vegetation_property: - - directional - - fluspect_parameters - - leafangles - - radiationdata - - soil_spectra - - input_data.xlsx - - input_soilThick.csv (optional) - - For the explanation of the directories see - [Dataflow of STEMMUS_SCOPE on CRIB](./STEMMUS_SCOPE_on_CRIB.md#dataflow-of-stemmus_scope-on-crib). - -2. Config file: it is a text file that sets the paths **required** by the model. - For example, see [config_file_snellius.txt](../config_file_snellius.txt) in - this repository. This file includes: - - - SoilPropertyPath: a path to soil texture data and soil hydraulic - parameters. - - InputPath: this is the working/running directory of the model and should - include the data of `directional`, `fluspect_parameters`, `leafangles`, - `radiationdata`, `soil_spectra`, and `input_data.xlsx`. - - OutputPath: this is the base path to store outputs of the model. When the - model runs, it creates `sitename_timestamped` directories under this - path. - - ForcingPath: a path to the forcing/driving data. I.e. the Plumber2 dataset. - - Location: Location where the model should be run. Currently, - the model runs at the site scale. For example, if we put `FI-Hyy` here, the model - runs at the `FI-Hyy` site. - - StartTime: The start time of the model, in the ISO 8601 format. For example: - `2001-01-01T00:00`. Note that the time can only be defined in half hour increments. - If you want the start time to be the first available data point of the forcing data, - you can set StartTime to `NA`. - - EndTime: The end time of the model. Formatted the same way as the StartTime. - For example: `2001-12-31T23:30`. If you want the end time to be the last available - data point of the forcing data, you can set EndTime to `NA`. - - To edit the config file, open the file with a text editor and change the - paths. The `InputPath` and `OutputPath` are user-defined directories, make - sure they exist and you have right permissions. The variable name e.g. - `SoilPropertyPath` should not be changed. Also, note a `/` is required at - the end of each line. +Data required by the model are in a folder named "data" in the project + directory `einf2480` on Snellius. This directory includes: + +- forcing/plumber2_data: the forcing/driving data provided by PLUMBER2. +- model_parameters/soil_property: the soil texture data and soil hydraulic parameters. +- model_parameters/vegetation_property: + - directional + - fluspect_parameters + - leafangles + - radiationdata + - soil_spectra + - input_data.xlsx + - input_soilThick.csv (optional) + +For the explanation of the directories see +[Dataflow of STEMMUS_SCOPE on CRIB](./STEMMUS_SCOPE_on_CRIB.md#dataflow-of-stemmus_scope-on-crib). + +### Configuration file: + +Config file: it is a text file that sets the paths **required** by the model. + For example, see [config_file_snellius.txt](../config_file_snellius.txt) in + this repository. This file includes: + + - SoilPropertyPath: a path to soil texture data and soil hydraulic + parameters. + - InputPath: this is the working/running directory of the model and should + include the data of `directional`, `fluspect_parameters`, `leafangles`, + `radiationdata`, `soil_spectra`, and `input_data.xlsx`. + - OutputPath: this is the base path to store outputs of the model. When the + model runs, it creates `sitename_timestamped` directories under this + path. + - ForcingPath: a path to the forcing/driving data. I.e. the Plumber2 dataset. + - Location: Location where the model should be run. Currently, + the model runs at the site scale. For example, if we put `FI-Hyy` here, the model + runs at the `FI-Hyy` site. + - StartTime: The start time of the model, in the ISO 8601 format. For example: + `2001-01-01T00:00`. Note that the time can only be defined in half hour increments. + If you want the start time to be the first available data point of the forcing data, + you can set StartTime to `NA`. + - EndTime: The end time of the model. Formatted the same way as the StartTime. + For example: `2001-12-31T23:30`. If you want the end time to be the last available + data point of the forcing data, you can set EndTime to `NA`. + + To edit the config file, open the file with a text editor and change the + paths. The `InputPath` and `OutputPath` are user-defined directories, make + sure they exist and you have right permissions. The variable name e.g. + `SoilPropertyPath` should not be changed. Also, note a `/` is required at + the end of each line. As explained above, the "InputPath" directory of the model is considered as the working/running directory and should include some data required by the diff --git a/docs/getting_started.md b/docs/getting_started.md index a9c45e7c..f7e362b2 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -1 +1,53 @@ -# Installation requirements \ No newline at end of file +# Requiremnets: + +## Data + +To run the STEMMUS-SCOPE model, you need to have input data either from in-situ +measurements or from remote sensing. Before running the model, you need to +prepare input data and a configuration file. This can be done using the python +package [PyStemmusScope](https://pystemmusscope.readthedocs.io). + +### Data on CRIB + +[CRIB](https://crib.utwente.nl/) is the ITC Geospatial Computing Platform. + +{% include-markdown "./STEMMUS_SCOPE_on_CRIB.md" start="### Dataflow of STEMMUS_SCOPE on CRIB:" end="### Configuration file:" heading-offset=2%} + +### Data on Snellius + +[Snellius](https://servicedesk.surfsara.nl/wiki/display/WIKI/Snellius) is the +Dutch National supercomputer hosted at SURF. + +{% include-markdown "./STEMMUS_SCOPE_on_Snellius.md" start="### Dataflow of STEMMUS_SCOPE on Snellius:" end="### Configuration file:" heading-offset=2%} + +### Example dataset on Zenodo + +A pre-processed example dataset can be found on Zenodo +[here](https://zenodo.org/records/10566827). + +## Configuration file + +The configuration file is a text file that sets the paths required by the model. +For example, see +[config_file_template.txt](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/config_file_template.txt). + +### Configuration file on CRIB + +{% include-markdown "./STEMMUS_SCOPE_on_CRIB.md" start="### Configuration file:" end="### Workflow of STEMMUS_SCOPE on CRIB:" heading-offset=2%} + +### Configuration file on Snellius + +{% include-markdown "./STEMMUS_SCOPE_on_Snellius.md" start="### Configuration file:" end="### Workflow of STEMMUS_SCOPE on Snellius:" heading-offset=2%} + +### Example configuration file + +An example configuration file can be found [here]((https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/config_file_template.txt)). + +## Software + +To run the STEMMUS-SCOPE model, you need **one** of the following: + +- [MATLAB](https://nl.mathworks.com/products/matlab.html) +- [MATLAB Runtime](https://nl.mathworks.com/products/compiler/matlab-runtime.html) on a Unix-like system +- [Octave](https://octave.org/) +- [Docker](https://www.docker.com/) \ No newline at end of file diff --git a/docs/run_model.md b/docs/run_model.md index 48c992e1..40105e94 100644 --- a/docs/run_model.md +++ b/docs/run_model.md @@ -1 +1,3 @@ -# How to run the model \ No newline at end of file +# + +To run the diff --git a/mkdocs.yml b/mkdocs.yml index e7d7db80..4ea44fb7 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -5,7 +5,7 @@ repo_name: STEMMUS_SCOPE nav: - Introduction: index.md - Getting started: getting_started.md - - Run the model: run_model.md + - Running the model: run_model.md - Contributing guide: contributing_guide.md theme: From a5fd802e8eed328b819721f30c08e68762bcf2bb Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 7 Oct 2024 13:47:53 +0200 Subject: [PATCH 04/11] move Octave_instructions to docs folder --- Octave_instructions.md => docs/Octave_instructions.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Octave_instructions.md => docs/Octave_instructions.md (100%) diff --git a/Octave_instructions.md b/docs/Octave_instructions.md similarity index 100% rename from Octave_instructions.md rename to docs/Octave_instructions.md From be6a72e30ad87ef5a4d56b514dcc33f8ce932d0f Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 7 Oct 2024 16:17:38 +0200 Subject: [PATCH 05/11] delete STEMMUS_SCOPE_on_local_device.md --- docs/STEMMUS_SCOPE_on_local_device.md | 31 --------------------------- 1 file changed, 31 deletions(-) delete mode 100644 docs/STEMMUS_SCOPE_on_local_device.md diff --git a/docs/STEMMUS_SCOPE_on_local_device.md b/docs/STEMMUS_SCOPE_on_local_device.md deleted file mode 100644 index 8c314bad..00000000 --- a/docs/STEMMUS_SCOPE_on_local_device.md +++ /dev/null @@ -1,31 +0,0 @@ -## STEMMUS_SCOPE on local device - -You can run STEMMUS_SCOPE locally. Follow the steps below and use `config_file_crib.txt` to configure the paths correctly. - -### How to run STEMMUS_SCOPE on local device: - -1. Download the source code from this repository or get it using `git clone` in - a terminal: - - ` git clone https://github.com/EcoExtreML/STEMMUS_SCOPE.git ` - - All the codes can be found in the folder `src` whereas the executable file in - the folder `exe`. - -2. Check `config_file_crib.txt` and change the paths if needed, specifically - "InputPath" and "OutputPath". -3. Follow the instructions below: - -#### Run using MATLAB Compiler that does not require a license - -If you want to run the model as a standalone application, you need MATLAB -Runtime version `2023a`. To download and install the MATLAB Runtime, follow -this -[instruction](https://nl.mathworks.com/products/compiler/matlab-runtime.html). -The "STEMMUS_SCOPE" executable file is in `STEMMUS_SCOPE/exe` directory -in this repository. You can run the model by passing the path of the config -file in a terminal: - -```bash -exe/STEMMUS_SCOPE config_file_crib.txt -``` \ No newline at end of file From 6bde8712a2dcad49b8c2a6433da780610d10d039 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 7 Oct 2024 16:18:49 +0200 Subject: [PATCH 06/11] add documentation for Running the model, polish existing documentation, add docker instructions --- docs/Octave_instructions.md | 55 +------ docs/STEMMUS_SCOPE_on_CRIB.md | 50 ------ docs/STEMMUS_SCOPE_on_Snellius.md | 88 ---------- docs/getting_started.md | 91 ++++++++--- docs/run_model.md | 257 +++++++++++++++++++++++++++++- mkdocs.yml | 2 + 6 files changed, 330 insertions(+), 213 deletions(-) diff --git a/docs/Octave_instructions.md b/docs/Octave_instructions.md index a951db9a..2d0c14b3 100644 --- a/docs/Octave_instructions.md +++ b/docs/Octave_instructions.md @@ -10,17 +10,6 @@ - [Mount extra directory](#mount-extra-directory) - [Linux from source](#linux-from-source) -The downloads can be found here -https://octave.org/download - -TODO: installation of octave on linux -After installation, launch octave and install the following Octave package: -`pkg install -forge statistics` - -For off-line installation, first, download the package [io](https://octave.sourceforge.io/io/index.html) and [statistics](https://octave.sourceforge.io/statistics/index.html). Then, launch octave and run: - -`pkg install io-2.6.4.tar.gz` -`pkg install statistics-1.4.3.tar.gz` ## VS Code setup Add Octave to path, e.g. for (64-bit) Windows add the following folders: @@ -35,23 +24,18 @@ The debugger configurations are included in `/.vscode/launch.json` `Octave Hacking` by Andrew Janke https://marketplace.visualstudio.com/items?itemName=apjanke.octave-hacking This adds syntax highlighting and formatting. -## Running STEMMUS-SCOPE in Octave -It is possible to run STEMMUS-SCOPE from the command line with the following setup: -`octave.bat --no-gui --interactive --silent --eval "STEMMUS_SCOPE_exe('path_to_config_file')"` - -On a Unix system, use `octave` instead of `octave.bat`. ## Developing STEMMUS-SCOPE in Octave -Open the `run_Octave.m` file, either in VS Code or the Octave GUI. +Open the `debug_Octave.m` file, either in VS Code or the Octave GUI. ### Octave GUI -Set the workspace to the `STEMMUS_SCOPE/src` folder, and open the `run_Octave.m` file. +Set the workspace to the `STEMMUS_SCOPE/src` folder, and open the `debug_Octave.m` file. Here you can set the config file that should be used, and then run the file. ### VS Code While having the `STEMMUS_SCOPE` folder as the workspace, open the debugger and select `Octave: Debug STEMMUS-SCOPE`. Start the debugger to run (and debug) the model. -In the `run_Octave.m` file you can set the config file that should be used. +In the `debug_Octave.m` file you can set the config file that should be used. ## VS Code + Dev container @@ -78,36 +62,3 @@ After editing file you can restart the editor to get the extra directory inside See [dev container docs](https://code.visualstudio.com/remote/advancedcontainers/add-local-file-mount) for more info. To mount Windows directory inside the dev container you have to start the container in WSL2 (aka run Docker service inside WSL2) and use unix paths like `/mnt/c/...`. - -## Linux from source - -Octave on many Linux distributions is too old so we need to compile it ourselves. -See [https://wiki.octave.org/Building](https://wiki.octave.org/Building). - -

-Here are build instructions for Ubuntu 22.04 - -```shell -sudo apt update -# install minimal deps, see https://wiki.octave.org/Octave_for_Debian_systems#The_right_way for all dependencies -sudo apt install -yq wget build-essential gfortran liblapack-dev libblas-dev libpcre3-dev libreadline-dev libnetcdf-dev -wget https://mirror.serverion.com/gnu/octave/octave-7.2.0.tar.gz # or download from local mirror at https://ftpmirror.gnu.org/octave -tar -zxf octave-7.2.0.tar.gz -cd octave-7.2.0 -./configure --prefix=/opt/octave -make -j 6 -sudo make install -``` - -Add `/opt/octave/bin` to PATH environment variable. - -```shell -export PATH=$PATH:/opt/octave/bin -``` - -Install Octave dependencies with - -```shell -octave --eval 'pkg install -forge statistics' -``` -
\ No newline at end of file diff --git a/docs/STEMMUS_SCOPE_on_CRIB.md b/docs/STEMMUS_SCOPE_on_CRIB.md index 60cc231c..b75eb29c 100644 --- a/docs/STEMMUS_SCOPE_on_CRIB.md +++ b/docs/STEMMUS_SCOPE_on_CRIB.md @@ -82,53 +82,3 @@ different working/running directory and set the "InputPath" to it. Then, you should copy the required data i.e. `directional`, `fluspect_parameters`, `leafangles`, `radiationdata`, `soil_spectra`, and `input_data.xlsx` to the working/running directory. - -### Workflow of STEMMUS_SCOPE on CRIB: - -1. The model reads the forcing file associated with the specified location, - e.g., `FI-Hyy_1996-2014_FLUXNET2015_Met.nc` from "ForcingPath" and - extracts forcing variables in `.dat` format using `filesread.m`. - The `.dat` files are stored in the "InputPath" directory. In - addition, the model reads the site information i.e. the location and - vegetation parameters. -2. The model runs step by step until the whole simulation period is completed - i.e till the last time step of the forcing data. -3. The results are saved as binary files temporarily. Then, the binary files are - converted to `.csv` files and stored in a `sitename_timestamped` output - directory under "OutputPath". - -### How to run STEMMUS_SCOPE on CRIB: - -1. Log in CRIB with your username and password and select a proper compute unit. -2. Download the source code from this repository or get it using `git clone` in - a terminal: - - ` git clone https://github.com/EcoExtreML/STEMMUS_SCOPE.git ` - - All the codes can be found in the folder `src` whereas the executable file in - the folder `exe`. - -3. Check `config_file_crib.txt` and change the paths if needed, specifically - "InputPath" and "OutputPath". -4. Follow the instructions below: - -#### Run using MATLAB that requires a license - -If you want to use MATLAB desktop, - -1. click on the `Remote Desktop` in the -Launcher. Click on the `Applications`. You will find the 'MATLAB' software under -the `Research`. -2. After clicking on 'MATLAB', it asks for your account information that is -connected to a MATLAB license. -3. Open the file `filesread.m` and set the -variable `CFG` to the path of the config file e.g. `CFG = -'/data/shared/EcoExtreML/STEMMUS_SCOPEv1.0.0/STEMMUS_SCOPE/config_file_crib.txt';`. -4. Then, run the main script `STEMMUS_SCOPE.m`. - -As an alternative, you can run the -main script using MATLAB command line in a terminal: - -```bash -matlab -nodisplay -nosplash -nodesktop -r "run('STEMMUS_SCOPE.m');exit;" -``` diff --git a/docs/STEMMUS_SCOPE_on_Snellius.md b/docs/STEMMUS_SCOPE_on_Snellius.md index 69e1b0ec..5d245d34 100644 --- a/docs/STEMMUS_SCOPE_on_Snellius.md +++ b/docs/STEMMUS_SCOPE_on_Snellius.md @@ -66,91 +66,3 @@ input_data.xlsx` to the working/running directory. For example: ` cp -r /projects/0/einf2480/model_parameters/vegetation_property/* /scratch-shared/EcoExtreML/STEMMUS_SCOPE/input/ ` - -### Workflow of STEMMUS_SCOPE on Snellius: - -This is the same as the workflow of STEMMUS_SCOPE on crib, see section -[Workflow of STEMMUS_SCOPE on CRIB](./STEMMUS_SCOPE_on_CRIB.md#workflow-of-stemmus_scope-on-crib). - -### How to run STEMMUS_SCOPE on Snellius: - -1. Log in to Snellius. -2. Download the source code from this repository or get it using `git clone` in - a terminal: - - ` git clone https://github.com/EcoExtreML/STEMMUS_SCOPE.git ` - - All the codes can be found in the folder `src` whereas the executable file in - the folder `exe`. - -3. Check `config_file_snellius.txt` and change the paths if needed, - specifically "InputPath" and "OutputPath". -4. Follow one of the instructions below: - -#### Run using MATLAB that requires a license - -In order to use MATLAB, you need to send a request to add you to the user pool -on Snellius. Then, open the file -[config_file_snellius.txt](../config_file_snellius.txt) and set the paths. Then, -run the main script `STEMMUS_SCOPE_exe.m` using MATLAB command line in a terminal on -a **compute node**: - -```bash -module load 2021 -module load MATLAB/2021a-upd3 -matlab -nodisplay -nosplash -nodesktop -r "STEMMUS_SCOPE_exe('config_file_snellius.txt');exit;" -``` - -> To run the codes above on a compute node, you can create a bash script as: - -```bash -#!/bin/bash -# SLURM settings -#SBATCH -J stemmus_scope -#SBATCH -t 01:00:00 -#SBATCH -N 1 -#SBATCH --ntasks=1 -#SBATCH --cpus-per-task=32 -#SBATCH -p thin -#SBATCH --output=./slurm_%j.out -#SBATCH --error=./slurm_%j.out - -module load 2021 -module load MATLAB/2021a-upd3 -matlab -nodisplay -nosplash -nodesktop -r "STEMMUS_SCOPE_exe('config_file_snellius.txt');exit;" -``` - -#### Run using MATLAB Compiler that does not require a license - -If you want to run the model as a standalone application, you need MATLAB -Runtime version `2023a`. This is available on Snellius. You can run the -model by passing the path of the config file in a terminal on a **compute -node**: - -```bash -module load 2021 -module load MCR/R2021a.3 -./STEMMUS_SCOPE/exe/STEMMUS_SCOPE config_file_snellius.txt -``` - -The bash script `run_stemmus_scope_snellius.sh` in this repository, runs the -model at 170 sites (default) on a **compute node**. The scripts loops over -forcing files in the "ForcingPath", creates `sitename_timestamped` working -directories under "InputPath" directory and copies required data to those -working dirs. To change the number of sites, open the script and on the last -line change the parameter `{1..170}`. For example `env_parallel -n1 -j32 ---joblog $log_file loop_func ::: {1..170}` will run the model at 32 sites -simultaneously. For testing purposes, the time of the bash script is set to -`00:10:00`. Note that the model run can take long for some of the sites. As the -maxium time wall is 5 days on a partition thin, time can be set to`5-00:00:00` -for a complete run of the model. - - You can run the script in a terminal: - -```shell -cd STEMMUS_SCOPE -mkdir -p slurm -sbatch run_stemmus_scope_snellius.sh -``` - -This creates a log file per each forcing file in the folder `slurm`. diff --git a/docs/getting_started.md b/docs/getting_started.md index f7e362b2..1f614a5c 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -1,11 +1,48 @@ # Requiremnets: +## Infrastructure (computig resources) + +To run the STEMMUS-SCOPE model, you can use one of the following computing resources: + +- [CRIB](https://crib.utwente.nl/) is the ITC Geospatial Computing Platform. +- [Snellius](https://servicedesk.surfsara.nl/wiki/display/WIKI/Snellius) is the +Dutch National supercomputer hosted at SURF. + +Otherwise, you can run the model on your local device if you have the correct +set of software and data. + +## Software + +To run the STEMMUS-SCOPE model, you need **one** of the following: + +- [MATLAB](https://nl.mathworks.com/products/matlab.html) +- [MATLAB Runtime](https://nl.mathworks.com/products/compiler/matlab-runtime.html) on a Unix-like system +- [Octave](https://octave.org/) +- [Docker](https://www.docker.com/) + +## Model source code + +Download the [latest version of the +model](https://github.com/EcoExtreML/STEMMUS_SCOPE/releases) from the repository +https://github.com/EcoExtreML/STEMMUS_SCOPE or get it using `git clone` in a +terminal: + + ` git clone https://github.com/EcoExtreML/STEMMUS_SCOPE.git ` + +All the codes can be found in the folder `src`. + ## Data To run the STEMMUS-SCOPE model, you need to have input data either from in-situ measurements or from remote sensing. Before running the model, you need to -prepare input data and a configuration file. This can be done using the python -package [PyStemmusScope](https://pystemmusscope.readthedocs.io). +prepare input data and a configuration file for **one site/location**. This can be done using +[setup()](https://pystemmusscope.readthedocs.io/en/v0.2.0/reference/#PyStemmusScope.stemmus_scope.StemmusScope.setup) function +in the python package [PyStemmusScope](https://pystemmusscope.readthedocs.io). + +### Example dataset on Zenodo + +A pre-processed example dataset for one site can be found on Zenodo +[here](https://zenodo.org/records/10566827). ### Data on CRIB @@ -20,16 +57,39 @@ Dutch National supercomputer hosted at SURF. {% include-markdown "./STEMMUS_SCOPE_on_Snellius.md" start="### Dataflow of STEMMUS_SCOPE on Snellius:" end="### Configuration file:" heading-offset=2%} -### Example dataset on Zenodo - -A pre-processed example dataset can be found on Zenodo -[here](https://zenodo.org/records/10566827). - ## Configuration file The configuration file is a text file that sets the paths required by the model. -For example, see -[config_file_template.txt](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/config_file_template.txt). +The configuration file should contain the following information: + +```text +WorkDir=/path_to_working_directory/ +SoilPropertyPath=/path_to_soil_property_data/ +ForcingPath=/path_to_forcing_data/ +Location=AU-DaS +directional=/path_to_directional_data/ +fluspect_parameters=/path_to_fluspect_parameters_data/ +leafangles=/path_to_leafangles_data/ +radiationdata=/path_to_radiation_data/ +soil_spectrum=/path_to_soil_spectra_data/ +InitialConditionPath=/path_to_soil_initial_condition_data/ +input_data=/path_to_input_data.xlsx_file/ +StartTime=2001-01-01T00:00 +EndTime=2001-01-02T00:00 +InputPath=/path_to_model_input_folder/ +OutputPath=/path_to_model_output_folder/ +``` + +### Example configuration file + +An example configuration file can be found [here](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/config_file_template.txt). + +> NOTE: If +[setup()](https://pystemmusscope.readthedocs.io/en/v0.2.0/reference/#PyStemmusScope.stemmus_scope.StemmusScope.setup) + function in the python package +[PyStemmusScope](https://pystemmusscope.readthedocs.io) is used to prepare data, +the model configuration file including `InputPath` and `OutputPath` and the data +of **one site/location** will be generated automatically. ### Configuration file on CRIB @@ -38,16 +98,3 @@ For example, see ### Configuration file on Snellius {% include-markdown "./STEMMUS_SCOPE_on_Snellius.md" start="### Configuration file:" end="### Workflow of STEMMUS_SCOPE on Snellius:" heading-offset=2%} - -### Example configuration file - -An example configuration file can be found [here]((https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/config_file_template.txt)). - -## Software - -To run the STEMMUS-SCOPE model, you need **one** of the following: - -- [MATLAB](https://nl.mathworks.com/products/matlab.html) -- [MATLAB Runtime](https://nl.mathworks.com/products/compiler/matlab-runtime.html) on a Unix-like system -- [Octave](https://octave.org/) -- [Docker](https://www.docker.com/) \ No newline at end of file diff --git a/docs/run_model.md b/docs/run_model.md index 40105e94..a6c074aa 100644 --- a/docs/run_model.md +++ b/docs/run_model.md @@ -1,3 +1,258 @@ # -To run the +> NOTE: The instructions below is meant for users who want to run the model. If +you want to develop the model, see the documentation on `Contributing guide`. + +## Workflow of STEMMUS_SCOPE + +1. The model reads the forcing file associated with the specified location, + e.g., `FI-Hyy_1996-2014_FLUXNET2015_Met.nc` from "ForcingPath" and extracts + forcing variables in `.dat` format. The `.dat` files are stored in the + `InputPath` directory. In addition, the model reads the site information i.e. + the location and vegetation parameters. +2. The model runs step by step until the whole simulation period is completed + i.e till the last time step of the forcing data. +3. The results are saved as binary files temporarily. Then, the binary files are + converted to `.csv` files and stored in a `sitename_timestamped` output + directory under `OutputPath`. + +## Run the model with MATLAB + +=== "Local device" + If you have [MATLAB](https://nl.mathworks.com/products/matlab.html) installed on + your device, you can run the model by passing config file path to the + variable `CFG` in the main script `STEMMUS_SCOPE.m`. + + As an alternative, you can run the main script using MATLAB command line in a + terminal: + + ```bash + cd src/ + matlab -nodisplay -nosplash -nodesktop -r "run('STEMMUS_SCOPE.m');exit;" + ``` +=== "CRIB" + To open MATLAB desktop on CRIB, click on the `Remote Desktop` in the + Launcher. Click on the `Applications`. You will find the 'MATLAB' software + under the `Research`. After clicking on 'MATLAB', it asks for your account + information that is connected to a MATLAB license. Then, you can run the + model by passing config file path to the variable `CFG` in the main script + `STEMMUS_SCOPE.m` + +=== "Snellius" + In order to use MATLAB, you need to send a request to add you to the user pool + on Snellius. Then, pass config file path to the variable `CFG` in the main script + `STEMMUS_SCOPE.m`. To run the main script `STEMMUS_SCOPE.m` using MATLAB command line in a terminal on + a **compute node**: + + ```bash + module load 2023 + module load MATLAB/2023a-upd4 + cd src/ + matlab -nodisplay -nosplash -nodesktop -r "run('STEMMUS_SCOPE.m');exit;" + ``` + + To submit a job to a compute node, see instructions [here](https://servicedesk.surf.nl/wiki/display/WIKI/Example+job+scripts). + +## Run the model with MATLAB Runtime + +=== "Local device" + If you want to run the model as a standalone application, you need [MATLAB + Runtime](https://nl.mathworks.com/products/compiler/matlab-runtime.html) + version `2023a`. You don't need a license for MATLAB Runtime. Note that the + version of the MATLAB Runtime is tied to the version of MATLAB. The + executable file works on the operating system on which the file is created. + The file `STEMMUS_SCOPE` under `exe` directory is an executable file of + STEMMUS_SCOPE that is created using MATLAB version `2023a` in a **Linux + system**. + + Make sure `LD_LIBRARY_PATH` is set correctly, in a terminal: + + ```bash + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/MATLAB/MATLAB_Runtime/v2023a/runtime/glnxa64:/usr/local/MATLAB/MATLAB_Runtime/v2023a/bin/glnxa64:/usr/local/MATLAB/MATLAB_Runtime/v2023a/sys/os/glnxa64:/usr/local/MATLAB/MATLAB_Runtime/v2023a/sys/opengl/lib/glnxa64 + ``` + + Change `/usr/local/MATLAB/MATLAB_Runtime/v2023a` to the path where MATLAB Runtime is installed. + + Then, you can run the model in a terminal: + + ```bash + ./STEMMUS_SCOPE/exe/STEMMUS_SCOPE config_file_template.txt + ``` + +=== "CRIB" + On CRIB, [MATLAB + Runtime](https://nl.mathworks.com/products/compiler/matlab-runtime.html) is + not available. Contact the system administrator for more information. + +=== "Snellius" + [MATLAB + Runtime](https://nl.mathworks.com/products/compiler/matlab-runtime.html) is available on Snellius. You can run the + model by passing the path of the config file in a terminal on a **compute + node**: + + ```bash + module load 2023 + module load MATLAB/2023a-upd4 + ./STEMMUS_SCOPE/exe/STEMMUS_SCOPE config_file_snellius.txt + ``` + + Note that you don't need to set `LD_LIBRARY_PATH` on Snellius. To submit a job to a compute node, see instructions [here](https://servicedesk.surf.nl/wiki/display/WIKI/Example+job+scripts). + +=== BMI interface + You can run the model using the [BMI](https://bmi.readthedocs.io/en/stable/) + interface. The BMI interface is available in the script + `STEMMUS_SCOPE_exe.m`. For that, you need [MATLAB + Runtime](https://nl.mathworks.com/products/compiler/matlab-runtime.html) + version `2023a`. You don't need a license for MATLAB Runtime. Note that the + version of the MATLAB Runtime is tied to the version of MATLAB. The + executable file works on the operating system on which the file is created. + The file `STEMMUS_SCOPE` under `exe` directory is an executable file of + STEMMUS_SCOPE that is created using MATLAB version `2023a` in a **Linux + system**. + + Make sure `LD_LIBRARY_PATH` is set correctly, in a terminal: + + ```bash + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/MATLAB/MATLAB_Runtime/v2023a/runtime/glnxa64:/usr/local/MATLAB/MATLAB_Runtime/v2023a/bin/glnxa64:/usr/local/MATLAB/MATLAB_Runtime/v2023a/sys/os/glnxa64:/usr/local/MATLAB/MATLAB_Runtime/v2023a/sys/opengl/lib/glnxa64 + ``` + + Change `/usr/local/MATLAB/MATLAB_Runtime/v2023a` to the path where MATLAB Runtime is installed. + + To enter the BMI mode: + + ```bash + ./STEMMUS_SCOPE/exe/STEMMUS_SCOPE "" bmi + ``` + + Now, BMI asks you to select one of the steps "initialize", "update" or "finalize". + To initialize the model using a config file, type: + + ```bash + initialize "path/to/config_file_template.txt" + ``` + + Change `path/to/config_file_template.txt` to the actual path of the config file. + +## Run the model with Octave + +=== "Local device" + If you want to run the model for a small time period or tests purpose, you + can use [Octave](https://octave.org/). Allmost all funcationalities of + STEMMUS_SCOPE are compatible with Octave, but the execution time is longer + than MATLAB. After Octave installation, launch octave and install the following Octave packages: + + ```bash + pkg install "https://downloads.sourceforge.net/project/octave/Octave%20Forge%20Packages/Individual%20Package%20Releases/io-2.6.4.tar.gz" + pkg install "https://downloads.sourceforge.net/project/octave/Octave%20Forge%20Packages/Individual%20Package%20Releases/statistics-1.4.3.tar.gz" + ``` + + Then, pass config file path to the variable `CFG` in the main script + `STEMMUS_SCOPE.m`. Run the model in a terminal: + + ```bash + cd src/ + octave.bat --no-gui --interactive --silent --eval "STEMMUS_SCOPE" + ``` + + On a Unix system, use `octave` instead of `octave.bat`. + +
+ Octave from source + + Note that Octave on many Linux distributions might be too old so we need to compile it ourselves. + See [https://wiki.octave.org/Building](https://wiki.octave.org/Building). Here are build instructions for Ubuntu 22.04: + + ```shell + sudo apt update + # install minimal deps, see https://wiki.octave.org/Octave_for_Debian_systems#The_right_way for all dependencies + sudo apt install -yq wget build-essential gfortran liblapack-dev libblas-dev libpcre3-dev libreadline-dev libnetcdf-dev + wget https://mirror.serverion.com/gnu/octave/octave-7.2.0.tar.gz # or download from local mirror at https://ftpmirror.gnu.org/octave + tar -zxf octave-7.2.0.tar.gz + cd octave-7.2.0 + ./configure --prefix=/opt/octave + make -j 6 + sudo make install + ``` + + Add `/opt/octave/bin` to PATH environment variable. + + ```shell + export PATH=$PATH:/opt/octave/bin + ``` + + Launch Octave and install Octave dependencies with: + + ```bash + pkg install "https://downloads.sourceforge.net/project/octave/Octave%20Forge%20Packages/Individual%20Package%20Releases/io-2.6.4.tar.gz" + pkg install "https://downloads.sourceforge.net/project/octave/Octave%20Forge%20Packages/Individual%20Package%20Releases/statistics-1.4.3.tar.gz" + ``` +
+ +=== "CRIB" + On CRIB, you can use [Octave](https://octave.org/). Allmost all + funcationalities of STEMMUS_SCOPE are compatible with Octave, but the + execution time is longer than MATLAB. After Octave installation, launch + octave and install the following Octave packages: + + ```bash + pkg install "https://downloads.sourceforge.net/project/octave/Octave%20Forge%20Packages/Individual%20Package%20Releases/io-2.6.4.tar.gz" + pkg install "https://downloads.sourceforge.net/project/octave/Octave%20Forge%20Packages/Individual%20Package%20Releases/statistics-1.4.3.tar.gz" + ``` + + Then, pass config file path to the variable `CFG` in the main script + `STEMMUS_SCOPE.m`. Run the model in a terminal: + + ```bash + octave.bat --no-gui --interactive --silent --eval "STEMMUS_SCOPE" + ``` + +=== "Snellius" + Since Octave is very slow, it is not recommended to run the model on + Snellius using Octave. Use MATLAB Runtime instead. + +## Run the model with Docker + +=== "Local device" + If you have [Docker](https://www.docker.com/) installed on your device, you + can run the model using the docker image `ecoextreml/stemmus_scope` and + [BMI](https://bmi.readthedocs.io/en/stable/) interface. The docker image is available + on + [EcoExtreML](https://github.com/EcoExtreML/STEMMUS_SCOPE/pkgs/container/stemmus_scope). + You can pull the `latest` image using the following command: + + ```bash + docker pull ghcr.io/ecoextreml/stemmus_scope:latest + ``` + + Then, mount the directories and run the model in a terminal: + + ```bash + docker run -u $(id -u):$(id -g) -v /path_to_input_folder:/path_to_input_folder -v /path_to_output_folder:/path_to_output_folder -it ghcr.io/ecoextreml/stemmus_scope:latest + ``` + + With `-it` option, you can enter the docker interactive mode. + Now, BMI asks you to select one of the steps "initialize", "update" or "finalize". + To initialize the model using a config file, type: + + ```bash + initialize "path/to/config_file_template.txt" + ``` + + Make sure that the input and output directories are mounted correctly + and `config_file_template.txt` is available in the input directory. + Also, remove the container after running the model: + + ```bash + docker rm container_id + ``` + +=== "CRIB" + If [Docker](https://www.docker.com/) is installed on CRIB, follow the same + instructions as for the `Local device`. + +=== "Snellius" + [Docker](https://www.docker.com/) option is not available on Snellius. You + need to use + [Apptainer](https://apptainer.org/docs/user/main/introduction.html), see + instructions + [here](https://servicedesk.surf.nl/wiki/pages/viewpage.action?pageId=30660251). diff --git a/mkdocs.yml b/mkdocs.yml index 4ea44fb7..263f0dc6 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -46,6 +46,8 @@ markdown_extensions: - pymdownx.superfences - pymdownx.details - admonition + - pymdownx.tabbed: + alternate_style: true extra: generator: false From bb6b5a1c838d36b8f8e6a1f2510515516318737b Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Wed, 9 Oct 2024 17:57:42 +0200 Subject: [PATCH 07/11] polish documentation --- CONTRIBUTING.md | 222 +++++++++++++++++++++++------- docs/Octave_instructions.md | 63 +++++++-- docs/STEMMUS_SCOPE_on_CRIB.md | 75 +++++----- docs/STEMMUS_SCOPE_on_Snellius.md | 69 +++++----- docs/contributing_guide.md | 6 + docs/getting_started.md | 70 +++++----- docs/run_model.md | 71 +++------- run_model_on_snellius/README.md | 22 +++ 8 files changed, 382 insertions(+), 216 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0ca2d975..8d12f105 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,7 @@ read and follow our contributing guidelines. ## Contributing via GitHub -If you want to work with the `STEMMUS_SCOPE` repository for the first time, or on a new computer, +If you want to work with the `STEMMUS_SCOPE` repository for the first time, or on a new computer, you need to configure a few things following steps 1 through 5 below.
@@ -28,7 +28,7 @@ SSH](https://docs.github.com/en/authentication/connecting-to-github-with-ssh) #### 2.1. Checking for existing SSH keys -Open a terminal and run the command below: +Open a terminal and run the command below: ```bash ls -la ~/.ssh @@ -70,7 +70,7 @@ Then, run the command below: ssh-add ~/.ssh/id_ed25519 ``` -This asks for your "passphrase" that was provided in the previous step. +This asks for your "passphrase" that was provided in the previous step. #### 2.4. Adding a new SSH key to your GitHub account @@ -124,7 +124,7 @@ Git](https://swcarpentry.github.io/git-novice/02-setup/index.html). Open a terminal and run the command below: ```bash -cd +cd ``` Now you are in your `HOME` directory. Run the command below: @@ -144,65 +144,191 @@ To know about the most common Git commands, follow the guides [here](https://hackmd.io/B4v6KwsBRzG-akLDF8e5pg).
-## Development of the MATLAB source of STEMMUS_SCOPE model +## Adding changes to the model source code + +To setup the required software and configurations, see the documentation on +`Getting started`. + +It would be ideal to introduce changes incrementally over time. This way, you +can track the changes and understand the impact of each change. Here are the +steps to follow: + +- Submit [an issue](https://github.com/EcoExtreML/STEMMUS_SCOPE/issues) to the + repository. This issue should describe the problem or the feature you want to + introduce. +- Create a new branch from the `main` branch. This branch should have a + descriptive name that relates to the issue you are working on. +- Make the changes in the new branch, for example, you can add new features, fix + bugs, or improve the documentation. Follow [MATLAB Guidelines 2.0, Richard + Johnson](http://cnl.sogang.ac.kr/cnlab/lectures/programming/matlab/Richard_Johnson-MatlabStyle2_book.pdf) + when introducing new changes to the codes. +- Commit the changes to the new branch. Write a descriptive commit message that + explains the changes you are introducing. +- Push the changes to the repository. +- Create a **draft** [pull + request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests) + to the `main` branch. This pull request should reference the issue you are + working on. +- When you are done with the changes, run [the tests](#testing-new-changes) and + [MISS_HIT commands](#miss_hit-checks), make sure they pass. +- Make the pull request ready for review. Ask for a review from the repository + maintainers. +- The maintainers will review the changes and provide feedback. You may need to + make additional changes based on the feedback. +- When the changes are approved, the maintainers will merge the pull request. + +## Reviewing a pull request + +When you are reviewing a pull request, you should follow the steps below: -To contribute to the STEMMUS_SCOPE model, you need access to the model source code that is stored in the repository [STEMMUS_SCOPE](https://github.com/EcoExtreML/STEMMUS_SCOPE). You also need a MATLAB license. MATLAB `2021a` is installed on -[Snellius]((https://servicedesk.surfsara.nl/wiki/display/WIKI/Snellius)) and [CRIB](https://crib.utwente.nl/), see [this instruction](https://pystemmusscope.readthedocs.io/en/latest/contributing_link.html#development-of-stemmus-scope-model). +- Check the changes introduced in the pull request. Make sure the changes are + consistent with the issue description. Also, check for example variable names, + function names, documentation, global variables, ..., to see if the changes + are consistent with the [MATLAB Style Guidelines + 2.0](http://cnl.sogang.ac.kr/cnlab/lectures/programming/matlab/Richard_Johnson-MatlabStyle2_book.pdf). +- Run [the tests](#testing-new-changes) and [MISS_HIT commands](#miss_hit-checks) to make sure they pass. +- Provide feedback on the changes. You can ask questions, suggest improvements, + or point out issues. +- When you are satisfied with the changes, approve the pull request. Ask a + maintainer to [re-generate the executable + file](#creating-an-executable-file-of-stemmus_scope) and merge the pull + request. +- If the changes are related to BMI, you have to ask the maintainer to make a + new release of the model. This way a new docker image will be created and the + model will be available for the users. +- If the changes are related to the documentation, make sure that documentation + page can be built successfully, see [Building the documentation + locally](#building-the-documentation-locally). + +## Merging a pull request + +When you are merging a pull request, you should follow the steps below: + +- Make sure the pull request is approved by at least one reviewer. +- Make sure all the items in the pull requests list are checked. + +## Creating an executable file of STEMMUS_SCOPE + +See the disumentation on [executable +file](https://github.com/EcoExtreML/STEMMUS_SCOPE/tree/main/run_model_on_snellius/exe). + +## MISS_HIT Checks + +When you submit a pull request, the code is also [checked](https://github.com/EcoExtreML/STEMMUS_SCOPE/actions/workflows/lint.yml) by the [MISS_HIT](misshit.org/) linter and style checker. +The status of `MISS_HIT` checks is shown below the pull request. The checks should be successful (green) before merging the pull request. To work with `MISS_HIT`, follow the instructions below: -## Create an executable file of STEMMUS_SCOPE +- Installing MISS_HIT: To install MISS_HIT, follow their [installation instructions](https://github.com/florianschanda/miss_hit#installation-via-pip). + +- Running MISS_HIT: To run the style checker or linter, navigate to the `src/` folder in STEMMUS_SCOPE, and run the following commands: -See the [exe readme](./exe/README.md). + ```bash + mh_style + mh_lint + mh_metric + ``` + + Follow the errors and information in the output to fix any issues. -## Follow MATLAB style guidelines +- Configuring MISS_HIT: `MISS_HIT` is configured in [`miss_hit.cfg`](./miss_hit.cfg). This file contains +the configuration for the linter and style checker. Please do not change this +file unless you are familiar with the configuration options. -When you are introducing new changes to the codes, please follow the style introduced in [MATLAB Guidelines 2.0, Richard Johnson](http://cnl.sogang.ac.kr/cnlab/lectures/programming/matlab/Richard_Johnson-MatlabStyle2_book.pdf). +## Testing new changes -When you submit a pull request, the code is also [checked](https://github.com/EcoExtreML/STEMMUS_SCOPE/actions/workflows/lint.yml) by the [MISS_HIT](misshit.org/) linter and style checker. -The status of `MISS_HIT` checks is shown below the pull request. The checks should be successful (green) before merging the pull request. -MISS_HIT is configured in [`miss_hit.cfg`](./miss_hit.cfg). +To test the new changes, we can only check if the new changes do not break the +model. To do this, follow the steps below: -### Installing MISS_HIT -It is best practice to install packages in environments. See the dropdown menu for instructions. -However, you can also continue below to install MISS_HIT without these steps. +- Run the notebook `compare_git_branch_results.ipynb` in the `test` folder. This + notebook will compare the results of the model between the `main` branch and + the new branch with the changes. If the results are similar, the changes do + not break the model. +- [Create the executable file](#creating-an-executable-file-of-stemmus_scope) of + the model and run the model with the new changes. Check if the model runs + without any errors. +- [Run the model with Octave](#octave-compatibility) to check if the new changes + are compatible with Octave. + +## Building the documentation locally + +Documentation is created using several markdown files and the [`mkdocs` +tool](https://www.mkdocs.org/). The markdown files are located in the `docs` +folder. The configuration file for `mkdocs` is `mkdocs.yml` located in the root +directory. To build the documentation locally, follow the steps below: + +- Install the required dependencies as: + + ```bash + cd STEMMUS_SCOPE + pip install -r docs/requirements.txt + ``` -
Python environment / conda instructions +- Build the documentation as: -You need to have a valid python installation on your system. + ```bash + mkdocs build + ``` -Create an enviroment with `venv` or conda: +- Preview the documentation as: -### **Venv** -```bash -python3 -m venv misshit # python on windows. -``` -Activate this environment -```bash -source misshit/bin/activate -``` + ```bash + mkdocs serve + ``` -Or on Windows: -```pwsh -./misshit/Scripts/Activate.ps1 -``` +Click on the link provided in the terminal to view the documentation in your +browser. -### **conda** -```bash -conda env create --name misshit -conda activate misshit -``` +## Making a release -
+When you are ready to make a release of the model, follow the steps below: -Install miss hit (optionally in the conda or venv environment) with: -```bash -pip install miss-hit -``` +- Make sure all new changes are added to changes log in the [`CHANGELOG.md` + file](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/CHANGELOG.md). +- Create a new release in the repository. The release should have a version number + following the [semantic versioning](https://semver.org/) guidelines. +- Add a description of the changes in the release notes. -To run the style checker or linter, navigate to the STEMMUS_SCOPE repository, and run the following commands: +## GitHub actions workflow -``` -mh_style -mh_lint -``` +GitHub actions workflows are located in the folder `.github/workflows`: + +- `lint.yml`: This workflow checks the code style and lints the code using + `MISS_HIT`. +- `doc_deploy.yml`: This workflow builds the documentation and deploys it to + GitHub pages. +- `publish-container`: This workflow builds the docker image and publishes it to + the repository once a new release is made. The docker image will avialable in + the + [packages](https://github.com/EcoExtreML/STEMMUS_SCOPE/pkgs/container/stemmus_scope) + in the repository. + +## Docker image + +The +[Dockerfile](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/Dockerfile) +is located in the root directory. This file is used to build the docker image of the model by Github action `publish-container`, see [GitHub actions workflow](#github-actions-workflow). To build and run the docker image locally, follow the steps below: + +- Install [Docker](https://www.docker.com/). +- Build the docker image as: + + ```bash + cd STEMMUS_SCOPE + docker build -t stemmus_scope . + ``` + +- Run the docker image with the BMI interface as: + + ```bash + docker run -u $(id -u):$(id -g) -v /path_to_input_folder:/path_to_input_folder -v /path_to_output_folder:/path_to_output_folder -it stemmus_scope + ``` + + With `-it` option, you can enter the docker interactive mode. + Now, BMI asks you to select one of the steps "initialize", "update" or "finalize". + To initialize the model using a config file, type: + + ```bash + initialize "path/to/config_file_template.txt" + ``` + +## Octave compatibility -For more information on installing and using MISS_HIT, look at [MISS_HIT's readme](https://github.com/florianschanda/miss_hit#installation-via-pip). \ No newline at end of file +See the documentation on [Octave compatibility](./docs/Octave_instructions.md). \ No newline at end of file diff --git a/docs/Octave_instructions.md b/docs/Octave_instructions.md index 2d0c14b3..6947b725 100644 --- a/docs/Octave_instructions.md +++ b/docs/Octave_instructions.md @@ -1,15 +1,56 @@ -# Using STEMMUS-SCOPE with GNU Octave - -- [Using STEMMUS-SCOPE with GNU Octave](#using-stemmus-scope-with-gnu-octave) - - [VS Code setup](#vs-code-setup) - - [Running STEMMUS-SCOPE in Octave](#running-stemmus-scope-in-octave) - - [Developing STEMMUS-SCOPE in Octave](#developing-stemmus-scope-in-octave) - - [Octave GUI](#octave-gui) - - [VS Code](#vs-code) - - [VS Code + Dev container](#vs-code--dev-container) - - [Mount extra directory](#mount-extra-directory) - - [Linux from source](#linux-from-source) +# Running STEMMUS-SCOPE in Octave +If you want to run the model for a small time period or tests purpose, you +can use [Octave](https://octave.org/). Allmost all funcationalities of +STEMMUS_SCOPE are compatible with Octave, but the execution time is longer +than MATLAB. After Octave installation, launch octave and install the following Octave packages: + +```bash +pkg install "https://downloads.sourceforge.net/project/octave/Octave%20Forge%20Packages/Individual%20Package%20Releases/io-2.6.4.tar.gz" +pkg install "https://downloads.sourceforge.net/project/octave/Octave%20Forge%20Packages/Individual%20Package%20Releases/statistics-1.4.3.tar.gz" +``` + +Then, pass config file path to the variable `CFG` in the main script +`STEMMUS_SCOPE.m`. Run the model in a terminal: + +```bash +cd src/ +octave.bat --no-gui --interactive --silent --eval "STEMMUS_SCOPE" +``` + +On a Unix system, use `octave` instead of `octave.bat`. + +
+Octave from source + +Note that Octave on many Linux distributions might be too old so we need to compile it ourselves. +See [https://wiki.octave.org/Building](https://wiki.octave.org/Building). Here are build instructions for Ubuntu 22.04: + +```shell +sudo apt update +# install minimal deps, see https://wiki.octave.org/Octave_for_Debian_systems#The_right_way for all dependencies +sudo apt install -yq wget build-essential gfortran liblapack-dev libblas-dev libpcre3-dev libreadline-dev libnetcdf-dev +wget https://mirror.serverion.com/gnu/octave/octave-7.2.0.tar.gz # or download from local mirror at https://ftpmirror.gnu.org/octave +tar -zxf octave-7.2.0.tar.gz +cd octave-7.2.0 +./configure --prefix=/opt/octave +make -j 6 +sudo make install +``` + +Add `/opt/octave/bin` to PATH environment variable. + +```shell +export PATH=$PATH:/opt/octave/bin +``` + +Launch Octave and install Octave dependencies with: + +```bash +pkg install "https://downloads.sourceforge.net/project/octave/Octave%20Forge%20Packages/Individual%20Package%20Releases/io-2.6.4.tar.gz" +pkg install "https://downloads.sourceforge.net/project/octave/Octave%20Forge%20Packages/Individual%20Package%20Releases/statistics-1.4.3.tar.gz" +``` +
## VS Code setup Add Octave to path, e.g. for (64-bit) Windows add the following folders: diff --git a/docs/STEMMUS_SCOPE_on_CRIB.md b/docs/STEMMUS_SCOPE_on_CRIB.md index b75eb29c..eb3d5c43 100644 --- a/docs/STEMMUS_SCOPE_on_CRIB.md +++ b/docs/STEMMUS_SCOPE_on_CRIB.md @@ -2,15 +2,20 @@ [CRIB](https://crib.utwente.nl/) is the ITC Geospatial Computing Platform. -### Dataflow of STEMMUS_SCOPE on CRIB: +### Dataflow of STEMMUS_SCOPE on CRIB -Data required by the model are in a folder named "input" under project directory -on CRIB. This folder includes: +To run the STEMMUS-SCOPE model, you need to have input data either from in-situ +measurements or from remote sensing. Plumber2 site data are avialable under +project directory on CRIB. This folder includes: - Plumber2_data: the forcing/driving data provided by PLUMBER2. - SoilProperty: the soil texture data and soil hydraulic parameters. -Below the directory explanations are from [SCOPE +In addition to site data, the remote sensing data are available on CRIB in +`global_data` folder. + +Data required by the model are in a folder named "input". Below the directory +explanations are from [SCOPE documentation](https://scope-model.readthedocs.io/en/latest/directories.html): - directional: the observer’s zenith and azimuth angles.(only used for @@ -34,44 +39,48 @@ documentation](https://scope-model.readthedocs.io/en/latest/directories.html): provides parameter inputs for PROSPECT, leaf_biochemical, fluorescence, soil, canopy, aerodynamic, angles, photosynthetic temperature dependence functional parameters, etc. -- input_soilLayThick.csv (optional): A file to change the discretization of - the soil layers of the STEMMUS model. An example of this file is in - [example_data folder](../example_data). This file (if needed) should be copied into the +- input_soilLayThick.csv (optional): A file to change the discretization of the + soil layers of the STEMMUS model. An example of this file is in [example_data + folder](https://github.com/EcoExtreML/STEMMUS_SCOPE/tree/main/example_data). + This file (if needed) should be copied into the `InputPath` folder. If this file is used, it will override the default settings of the soil layers. The file has three columns: 1) layer number, 2) layer thickness, and 3) maximum root depth. The user is free to change the values of the three columns. Also, the number of rows determines the number of the soil layers and the total thickness of the soil column (sum of soil layer thickness). -### Configuration file: +### Configuration file -Config file: it is a text file that sets the paths **required** by the - model. For example, see [config_file_crib.txt](../config_file_crib.txt) in this - repository. This file includes: +Config file: it is a text file that sets the paths **required** by the model. +For example, see +[config_file_crib.txt](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/config_file_crib.txt) +or +[config_file_crib_global.txt](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/config_file_crib_global.txt) +in this repository. This file includes: - - SoilPropertyPath: a path to soil texture data and soil hydraulic - parameters. - - InputPath: this is the working/running directory of the model and should - include the data of `directional`, `fluspect_parameters`, `leafangles`, - `radiationdata`, `soil_spectra`, and `input_data.xlsx`. - - OutputPath: this is the base path to store outputs of the model. When the - model runs, it creates `sitename_timestamped` directories under this - path. - - ForcingPath: a path to the forcing/driving data. I.e. the Plumber2 dataset. - - Location: Location where the model should be run. Currently, - the model runs at the site scale. For example, if we put `FI-Hyy` here, the model - runs at the `FI-Hyy` site. - - StartTime: The start time of the model, in the ISO 8601 format. For example: - `2001-01-01T00:00`. Note that the time can only be defined in half hour increments. - If you want the start time to be the first available data point of the forcing data, - you can set StartTime to `NA`. - - EndTime: The end time of the model. Formatted the same way as the StartTime. - For example: `2001-12-31T23:30`. If you want the end time to be the last available - data point of the forcing data, you can set EndTime to `NA`. +- SoilPropertyPath: a path to soil texture data and soil hydraulic + parameters. +- InputPath: this is the working/running directory of the model and should + include the data of `directional`, `fluspect_parameters`, `leafangles`, + `radiationdata`, `soil_spectra`, and `input_data.xlsx`. +- OutputPath: this is the base path to store outputs of the model. When the +model runs, it creates `sitename_timestamped` directories under this +path. +- ForcingPath: a path to the forcing/driving data. I.e. the Plumber2 dataset. +- Location: Location where the model should be run. Currently, +the model runs at the site scale. For example, if we put `FI-Hyy` here, the model +runs at the `FI-Hyy` site. +- StartTime: The start time of the model, in the ISO 8601 format. For example: +`2001-01-01T00:00`. Note that the time can only be defined in half hour increments. +If you want the start time to be the first available data point of the forcing data, +you can set StartTime to `NA`. +- EndTime: The end time of the model. Formatted the same way as the StartTime. +For example: `2001-12-31T23:30`. If you want the end time to be the last available +data point of the forcing data, you can set EndTime to `NA`. - To edit the config file, open the file with a text editor and change the - paths. The variable names e.g. `SoilPropertyPath` should not be changed. - Also, note a `/` is required at the end of each line. +To edit the config file, open the file with a text editor and change the +paths. The variable names e.g. `SoilPropertyPath` should not be changed. +Also, note a `/` is required at the end of each line. As explained above, the "InputPath" directory of the model is considered as the working/running directory and should include some data required by the diff --git a/docs/STEMMUS_SCOPE_on_Snellius.md b/docs/STEMMUS_SCOPE_on_Snellius.md index 5d245d34..295e3074 100644 --- a/docs/STEMMUS_SCOPE_on_Snellius.md +++ b/docs/STEMMUS_SCOPE_on_Snellius.md @@ -3,10 +3,12 @@ [Snellius](https://servicedesk.surfsara.nl/wiki/display/WIKI/Snellius) is the Dutch National supercomputer hosted at SURF. -### Dataflow of STEMMUS_SCOPE on Snellius: +### Dataflow of STEMMUS_SCOPE on Snellius -Data required by the model are in a folder named "data" in the project - directory `einf2480` on Snellius. This directory includes: +To run the STEMMUS-SCOPE model, you need to have input data either from in-situ +measurements or from remote sensing. Data required by the model are in a folder +named "data" in the project directory `einf2480` on Snellius. This directory +includes: - forcing/plumber2_data: the forcing/driving data provided by PLUMBER2. - model_parameters/soil_property: the soil texture data and soil hydraulic parameters. @@ -19,40 +21,43 @@ Data required by the model are in a folder named "data" in the project - input_data.xlsx - input_soilThick.csv (optional) -For the explanation of the directories see -[Dataflow of STEMMUS_SCOPE on CRIB](./STEMMUS_SCOPE_on_CRIB.md#dataflow-of-stemmus_scope-on-crib). +In addition to site data, the remote sensing data are available on Snellius in +`global_data` folder. -### Configuration file: +### Configuration file Config file: it is a text file that sets the paths **required** by the model. - For example, see [config_file_snellius.txt](../config_file_snellius.txt) in - this repository. This file includes: +For example, see +[config_file_snellius.txt](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/run_model_on_snellius/config_file_snellius.txt) +or +[config_file_snellius_global.txt](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/run_model_on_snellius/config_file_snellius_global.txt) +in this repository. This file includes: - - SoilPropertyPath: a path to soil texture data and soil hydraulic - parameters. - - InputPath: this is the working/running directory of the model and should - include the data of `directional`, `fluspect_parameters`, `leafangles`, - `radiationdata`, `soil_spectra`, and `input_data.xlsx`. - - OutputPath: this is the base path to store outputs of the model. When the - model runs, it creates `sitename_timestamped` directories under this - path. - - ForcingPath: a path to the forcing/driving data. I.e. the Plumber2 dataset. - - Location: Location where the model should be run. Currently, - the model runs at the site scale. For example, if we put `FI-Hyy` here, the model - runs at the `FI-Hyy` site. - - StartTime: The start time of the model, in the ISO 8601 format. For example: - `2001-01-01T00:00`. Note that the time can only be defined in half hour increments. - If you want the start time to be the first available data point of the forcing data, - you can set StartTime to `NA`. - - EndTime: The end time of the model. Formatted the same way as the StartTime. - For example: `2001-12-31T23:30`. If you want the end time to be the last available - data point of the forcing data, you can set EndTime to `NA`. +- SoilPropertyPath: a path to soil texture data and soil hydraulic + parameters. +- InputPath: this is the working/running directory of the model and should + include the data of `directional`, `fluspect_parameters`, `leafangles`, + `radiationdata`, `soil_spectra`, and `input_data.xlsx`. +- OutputPath: this is the base path to store outputs of the model. When the +model runs, it creates `sitename_timestamped` directories under this +path. +- ForcingPath: a path to the forcing/driving data. I.e. the Plumber2 dataset. +- Location: Location where the model should be run. Currently, +the model runs at the site scale. For example, if we put `FI-Hyy` here, the model +runs at the `FI-Hyy` site. +- StartTime: The start time of the model, in the ISO 8601 format. For example: +`2001-01-01T00:00`. Note that the time can only be defined in half hour increments. +If you want the start time to be the first available data point of the forcing data, +you can set StartTime to `NA`. +- EndTime: The end time of the model. Formatted the same way as the StartTime. +For example: `2001-12-31T23:30`. If you want the end time to be the last available +data point of the forcing data, you can set EndTime to `NA`. - To edit the config file, open the file with a text editor and change the - paths. The `InputPath` and `OutputPath` are user-defined directories, make - sure they exist and you have right permissions. The variable name e.g. - `SoilPropertyPath` should not be changed. Also, note a `/` is required at - the end of each line. +To edit the config file, open the file with a text editor and change the +paths. The `InputPath` and `OutputPath` are user-defined directories, make +sure they exist and you have right permissions. The variable name e.g. +`SoilPropertyPath` should not be changed. Also, note a `/` is required at +the end of each line. As explained above, the "InputPath" directory of the model is considered as the working/running directory and should include some data required by the diff --git a/docs/contributing_guide.md b/docs/contributing_guide.md index a6b802c4..7b734730 100644 --- a/docs/contributing_guide.md +++ b/docs/contributing_guide.md @@ -1 +1,7 @@ +# + +> NOTE: The instructions below are meant for users who want to add changes to +the model source code. If you want to run the model, see the documentation on +`Running the model`. + {% include-markdown "../CONTRIBUTING.md" start="# Contributing guidelines" heading-offset=2%} \ No newline at end of file diff --git a/docs/getting_started.md b/docs/getting_started.md index 1f614a5c..ac14bd09 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -1,6 +1,6 @@ -# Requiremnets: +# Requiremnets -## Infrastructure (computig resources) +## Computig resource To run the STEMMUS-SCOPE model, you can use one of the following computing resources: @@ -22,40 +22,37 @@ To run the STEMMUS-SCOPE model, you need **one** of the following: ## Model source code -Download the [latest version of the +The source code of STEMMUS_SCOPE can be found in the GitHub repository +[https://github.com/EcoExtreML/STEMMUS_SCOPE](https://github.com/EcoExtreML/STEMMUS_SCOPE) +under the folder `src`. Download the [latest version of the model](https://github.com/EcoExtreML/STEMMUS_SCOPE/releases) from the repository -https://github.com/EcoExtreML/STEMMUS_SCOPE or get it using `git clone` in a -terminal: +or get it using `git clone` in a terminal: - ` git clone https://github.com/EcoExtreML/STEMMUS_SCOPE.git ` +` git clone https://github.com/EcoExtreML/STEMMUS_SCOPE.git ` -All the codes can be found in the folder `src`. ## Data To run the STEMMUS-SCOPE model, you need to have input data either from in-situ measurements or from remote sensing. Before running the model, you need to prepare input data and a configuration file for **one site/location**. This can be done using -[setup()](https://pystemmusscope.readthedocs.io/en/v0.2.0/reference/#PyStemmusScope.stemmus_scope.StemmusScope.setup) function -in the python package [PyStemmusScope](https://pystemmusscope.readthedocs.io). +[setup()](https://pystemmusscope.readthedocs.io/en/latest/reference/#PyStemmusScope.stemmus_scope.StemmusScope.setup) function +in the python package [PyStemmusScope](https://pystemmusscope.readthedocs.io/en/latest/). See example datasets below: -### Example dataset on Zenodo +=== "Example dataset on Zenodo" + A pre-processed example dataset for one site can be found on Zenodo + [here](https://zenodo.org/records/10566827). -A pre-processed example dataset for one site can be found on Zenodo -[here](https://zenodo.org/records/10566827). +=== "Data on CRIB" + [CRIB](https://crib.utwente.nl/) is the ITC Geospatial Computing Platform. -### Data on CRIB + {% include-markdown "./STEMMUS_SCOPE_on_CRIB.md" start="### Dataflow of STEMMUS_SCOPE on CRIB" end="### Configuration file" heading-offset=2%} -[CRIB](https://crib.utwente.nl/) is the ITC Geospatial Computing Platform. +=== "Data on Snellius" + [Snellius](https://servicedesk.surfsara.nl/wiki/display/WIKI/Snellius) is the + Dutch National supercomputer hosted at SURF. -{% include-markdown "./STEMMUS_SCOPE_on_CRIB.md" start="### Dataflow of STEMMUS_SCOPE on CRIB:" end="### Configuration file:" heading-offset=2%} - -### Data on Snellius - -[Snellius](https://servicedesk.surfsara.nl/wiki/display/WIKI/Snellius) is the -Dutch National supercomputer hosted at SURF. - -{% include-markdown "./STEMMUS_SCOPE_on_Snellius.md" start="### Dataflow of STEMMUS_SCOPE on Snellius:" end="### Configuration file:" heading-offset=2%} + {% include-markdown "./STEMMUS_SCOPE_on_Snellius.md" start="### Dataflow of STEMMUS_SCOPE on Snellius" end="### Configuration file" heading-offset=2%} ## Configuration file @@ -80,21 +77,20 @@ InputPath=/path_to_model_input_folder/ OutputPath=/path_to_model_output_folder/ ``` -### Example configuration file - -An example configuration file can be found [here](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/config_file_template.txt). - -> NOTE: If -[setup()](https://pystemmusscope.readthedocs.io/en/v0.2.0/reference/#PyStemmusScope.stemmus_scope.StemmusScope.setup) - function in the python package -[PyStemmusScope](https://pystemmusscope.readthedocs.io) is used to prepare data, -the model configuration file including `InputPath` and `OutputPath` and the data -of **one site/location** will be generated automatically. - -### Configuration file on CRIB +See example configuration files below: -{% include-markdown "./STEMMUS_SCOPE_on_CRIB.md" start="### Configuration file:" end="### Workflow of STEMMUS_SCOPE on CRIB:" heading-offset=2%} +=== "Example configuration file" + An example configuration file can be found + [here](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/config_file_template.txt). If + [setup()](https://pystemmusscope.readthedocs.io/en/latest/reference/#PyStemmusScope.stemmus_scope.StemmusScope.setup) + function in the python package + [PyStemmusScope](https://pystemmusscope.readthedocs.io/en/latest/) is used + to prepare data, the model configuration file including `InputPath` and + `OutputPath` and the data of **one site/location** will be generated + automatically. -### Configuration file on Snellius +=== "Example configuration file on CRIB" + {% include-markdown "./STEMMUS_SCOPE_on_CRIB.md" start="### Configuration file" heading-offset=2%} -{% include-markdown "./STEMMUS_SCOPE_on_Snellius.md" start="### Configuration file:" end="### Workflow of STEMMUS_SCOPE on Snellius:" heading-offset=2%} +=== "Example configuration file on Snellius" + {% include-markdown "./STEMMUS_SCOPE_on_Snellius.md" start="### Configuration file" heading-offset=2%} diff --git a/docs/run_model.md b/docs/run_model.md index a6c074aa..05ab07e5 100644 --- a/docs/run_model.md +++ b/docs/run_model.md @@ -1,11 +1,12 @@ # -> NOTE: The instructions below is meant for users who want to run the model. If -you want to develop the model, see the documentation on `Contributing guide`. +> NOTE: The instructions below are meant for users who want to run the model. If +you want to add changes to the model, see the documentation on `Contributing +guide`. ## Workflow of STEMMUS_SCOPE -1. The model reads the forcing file associated with the specified location, +1. The model reads the forcing file associated with the specified site/location, e.g., `FI-Hyy_1996-2014_FLUXNET2015_Met.nc` from "ForcingPath" and extracts forcing variables in `.dat` format. The `.dat` files are stored in the `InputPath` directory. In addition, the model reads the site information i.e. @@ -16,6 +17,7 @@ you want to develop the model, see the documentation on `Contributing guide`. converted to `.csv` files and stored in a `sitename_timestamped` output directory under `OutputPath`. + ## Run the model with MATLAB === "Local device" @@ -98,7 +100,7 @@ you want to develop the model, see the documentation on `Contributing guide`. Note that you don't need to set `LD_LIBRARY_PATH` on Snellius. To submit a job to a compute node, see instructions [here](https://servicedesk.surf.nl/wiki/display/WIKI/Example+job+scripts). -=== BMI interface +=== "BMI interface" You can run the model using the [BMI](https://bmi.readthedocs.io/en/stable/) interface. The BMI interface is available in the script `STEMMUS_SCOPE_exe.m`. For that, you need [MATLAB @@ -136,57 +138,7 @@ you want to develop the model, see the documentation on `Contributing guide`. ## Run the model with Octave === "Local device" - If you want to run the model for a small time period or tests purpose, you - can use [Octave](https://octave.org/). Allmost all funcationalities of - STEMMUS_SCOPE are compatible with Octave, but the execution time is longer - than MATLAB. After Octave installation, launch octave and install the following Octave packages: - - ```bash - pkg install "https://downloads.sourceforge.net/project/octave/Octave%20Forge%20Packages/Individual%20Package%20Releases/io-2.6.4.tar.gz" - pkg install "https://downloads.sourceforge.net/project/octave/Octave%20Forge%20Packages/Individual%20Package%20Releases/statistics-1.4.3.tar.gz" - ``` - - Then, pass config file path to the variable `CFG` in the main script - `STEMMUS_SCOPE.m`. Run the model in a terminal: - - ```bash - cd src/ - octave.bat --no-gui --interactive --silent --eval "STEMMUS_SCOPE" - ``` - - On a Unix system, use `octave` instead of `octave.bat`. - -
- Octave from source - - Note that Octave on many Linux distributions might be too old so we need to compile it ourselves. - See [https://wiki.octave.org/Building](https://wiki.octave.org/Building). Here are build instructions for Ubuntu 22.04: - - ```shell - sudo apt update - # install minimal deps, see https://wiki.octave.org/Octave_for_Debian_systems#The_right_way for all dependencies - sudo apt install -yq wget build-essential gfortran liblapack-dev libblas-dev libpcre3-dev libreadline-dev libnetcdf-dev - wget https://mirror.serverion.com/gnu/octave/octave-7.2.0.tar.gz # or download from local mirror at https://ftpmirror.gnu.org/octave - tar -zxf octave-7.2.0.tar.gz - cd octave-7.2.0 - ./configure --prefix=/opt/octave - make -j 6 - sudo make install - ``` - - Add `/opt/octave/bin` to PATH environment variable. - - ```shell - export PATH=$PATH:/opt/octave/bin - ``` - - Launch Octave and install Octave dependencies with: - - ```bash - pkg install "https://downloads.sourceforge.net/project/octave/Octave%20Forge%20Packages/Individual%20Package%20Releases/io-2.6.4.tar.gz" - pkg install "https://downloads.sourceforge.net/project/octave/Octave%20Forge%20Packages/Individual%20Package%20Releases/statistics-1.4.3.tar.gz" - ``` -
+ {% include-markdown "./Octave_instructions.md" start="# Running STEMMUS-SCOPE in Octave" end="## VS Code setup" heading-offset=2%} === "CRIB" On CRIB, you can use [Octave](https://octave.org/). Allmost all @@ -256,3 +208,12 @@ you want to develop the model, see the documentation on `Contributing guide`. [Apptainer](https://apptainer.org/docs/user/main/introduction.html), see instructions [here](https://servicedesk.surf.nl/wiki/pages/viewpage.action?pageId=30660251). + +## Example workflow of running the model + +1. Download the [latest version of the + model](https://github.com/EcoExtreML/STEMMUS_SCOPE/releases). +2. Download the example dataset from Zenodo + [here](https://zenodo.org/records/10566827) that includes the configuration + file. +3. Choose one of the options above to run the model. diff --git a/run_model_on_snellius/README.md b/run_model_on_snellius/README.md index 92cc0bd6..bd12273b 100644 --- a/run_model_on_snellius/README.md +++ b/run_model_on_snellius/README.md @@ -7,3 +7,25 @@ This folder contains files that are needed for running `STEMMUS_SCOPE` on Snelli - `config_file_snellius.txt` is the model config file Before submitting the job via `sbatch run_stemmus_scope_snellius.sh`, make sure that conda environment `pystemmusscope` is created, see the [environment file](https://github.com/EcoExtreML/STEMMUS_SCOPE_Processing/blob/main/environment.yml). Also, set the `WorkDir` and `NumberOfTimeSteps` in the model config file e.g. `config_file_snellius.txt`. + +The bash script `run_stemmus_scope_snellius.sh` in this repository, runs the +model at 170 sites (default) on a **compute node**. The scripts loops over +forcing files in the "ForcingPath", creates `sitename_timestamped` working +directories under "InputPath" directory and copies required data to those +working dirs. To change the number of sites, open the script and on the last +line change the parameter `{1..170}`. For example `env_parallel -n1 -j32 +--joblog $log_file loop_func ::: {1..170}` will run the model at 32 sites +simultaneously. For testing purposes, the time of the bash script is set to +`00:10:00`. Note that the model run can take long for some of the sites. As the +maxium time wall is 5 days on a partition thin, time can be set to`5-00:00:00` +for a complete run of the model. + +You can run the script in a terminal: + +```shell +cd STEMMUS_SCOPE +mkdir -p slurm +sbatch run_stemmus_scope_snellius.sh +``` + +This creates a log file per each forcing file in the folder `slurm`. From d0e3779055ade1d4fc467cd9c5c2092161bead9d Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Thu, 10 Oct 2024 14:27:49 +0200 Subject: [PATCH 08/11] polich contributing docs --- CONTRIBUTING.md => docs/CONTRIBUTING.md | 34 +++++++++++++++++-------- docs/Octave_instructions.md | 5 +++- docs/STEMMUS_SCOPE_BMI.md | 3 ++- docs/contributing_guide.md | 7 ----- mkdocs.yml | 4 ++- run_model_on_snellius/exe/README.md | 6 ++--- 6 files changed, 35 insertions(+), 24 deletions(-) rename CONTRIBUTING.md => docs/CONTRIBUTING.md (89%) delete mode 100644 docs/contributing_guide.md diff --git a/CONTRIBUTING.md b/docs/CONTRIBUTING.md similarity index 89% rename from CONTRIBUTING.md rename to docs/CONTRIBUTING.md index 8d12f105..3a58e701 100644 --- a/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -1,4 +1,8 @@ -# Contributing guidelines +# + +> NOTE: The instructions below are meant for users who want to add changes to +the model source code. If you want to run the model, see the documentation on +`Running the model`. This repository includes the MATLAB source code of the STEMMUS-SCOPE model. We welcome any kind of contributions to our software, from simple comments or questions to a full @@ -214,12 +218,18 @@ file](https://github.com/EcoExtreML/STEMMUS_SCOPE/tree/main/run_model_on_snelliu ## MISS_HIT Checks -When you submit a pull request, the code is also [checked](https://github.com/EcoExtreML/STEMMUS_SCOPE/actions/workflows/lint.yml) by the [MISS_HIT](misshit.org/) linter and style checker. -The status of `MISS_HIT` checks is shown below the pull request. The checks should be successful (green) before merging the pull request. To work with `MISS_HIT`, follow the instructions below: +When you submit a pull request, the code is also +[checked](https://github.com/EcoExtreML/STEMMUS_SCOPE/actions/workflows/lint.yml) +by the [MISS_HIT](https://misshit.org/) linter and style checker. The status of +`MISS_HIT` checks is shown below the pull request. The checks should be +successful (green) before merging the pull request. To work with `MISS_HIT`, +follow the instructions below: -- Installing MISS_HIT: To install MISS_HIT, follow their [installation instructions](https://github.com/florianschanda/miss_hit#installation-via-pip). +- Installing MISS_HIT: To install MISS_HIT, follow their [installation + instructions](https://github.com/florianschanda/miss_hit#installation-via-pip). -- Running MISS_HIT: To run the style checker or linter, navigate to the `src/` folder in STEMMUS_SCOPE, and run the following commands: +- Running MISS_HIT: To run the style checker or linter, navigate to the `src/` + folder in STEMMUS_SCOPE, and run the following commands: ```bash mh_style @@ -229,9 +239,10 @@ The status of `MISS_HIT` checks is shown below the pull request. The checks shou Follow the errors and information in the output to fix any issues. -- Configuring MISS_HIT: `MISS_HIT` is configured in [`miss_hit.cfg`](./miss_hit.cfg). This file contains -the configuration for the linter and style checker. Please do not change this -file unless you are familiar with the configuration options. +- Configuring MISS_HIT: `MISS_HIT` is configured in +[`miss_hit.cfg`](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/miss_hit.cfg). +This file contains the configuration for the linter and style checker. Please do +not change this file unless you are familiar with the configuration options. ## Testing new changes @@ -305,7 +316,10 @@ GitHub actions workflows are located in the folder `.github/workflows`: The [Dockerfile](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/Dockerfile) -is located in the root directory. This file is used to build the docker image of the model by Github action `publish-container`, see [GitHub actions workflow](#github-actions-workflow). To build and run the docker image locally, follow the steps below: +is located in the root directory. This file is used to build the docker image of +the model by Github action `publish-container`, see [GitHub actions +workflow](#github-actions-workflow). To build and run the docker image locally, +follow the steps below: - Install [Docker](https://www.docker.com/). - Build the docker image as: @@ -331,4 +345,4 @@ is located in the root directory. This file is used to build the docker image of ## Octave compatibility -See the documentation on [Octave compatibility](./docs/Octave_instructions.md). \ No newline at end of file +See the documentation on [Octave compatibility](./Octave_instructions.md). diff --git a/docs/Octave_instructions.md b/docs/Octave_instructions.md index 6947b725..27d3fc0c 100644 --- a/docs/Octave_instructions.md +++ b/docs/Octave_instructions.md @@ -90,7 +90,10 @@ It will then start a Docker container with your code, Octave and the VS Code Oct By default a Dev container only has the current VS code folder mounted inside the container. -To add additional directories like directory with model input files to the container you will need to edit the [.devcontainer/devcontainer.json](.devcontainer/devcontainer.json) and add +To add additional directories like directory with model input files to the +container you will need to edit the +[.devcontainer/devcontainer.json](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/.devcontainer/devcontainer.json) +and add ```json "mounts": [ diff --git a/docs/STEMMUS_SCOPE_BMI.md b/docs/STEMMUS_SCOPE_BMI.md index 614e486b..362018be 100644 --- a/docs/STEMMUS_SCOPE_BMI.md +++ b/docs/STEMMUS_SCOPE_BMI.md @@ -13,7 +13,8 @@ When starting the executable, a run-mode can be specified. The following command ./STEMMUS_SCOPE "/home/path/to/config/file.txt" full ``` -(Where `./STEMMUS_SCOPE` is the path to the executable. For more info see [documentation](../run_model_on_snellius/exe/README.md)) +(Where `./STEMMUS_SCOPE` is the path to the executable. For more info see +[documentation](https://github.com/EcoExtreML/STEMMUS_SCOPE/tree/main/run_model_on_snellius/exe)) To start BMI mode, pass anything (e.g. an empty string "") as config file, and use `bmi` to start the model in BMI-mode: diff --git a/docs/contributing_guide.md b/docs/contributing_guide.md deleted file mode 100644 index 7b734730..00000000 --- a/docs/contributing_guide.md +++ /dev/null @@ -1,7 +0,0 @@ -# - -> NOTE: The instructions below are meant for users who want to add changes to -the model source code. If you want to run the model, see the documentation on -`Running the model`. - -{% include-markdown "../CONTRIBUTING.md" start="# Contributing guidelines" heading-offset=2%} \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 263f0dc6..88e7f838 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -6,7 +6,7 @@ nav: - Introduction: index.md - Getting started: getting_started.md - Running the model: run_model.md - - Contributing guide: contributing_guide.md + - Contributing guide: CONTRIBUTING.md theme: name: material @@ -39,6 +39,7 @@ theme: plugins: - include-markdown - search +- autorefs markdown_extensions: - pymdownx.highlight: @@ -48,6 +49,7 @@ markdown_extensions: - admonition - pymdownx.tabbed: alternate_style: true + - attr_list extra: generator: false diff --git a/run_model_on_snellius/exe/README.md b/run_model_on_snellius/exe/README.md index 4d558c63..eb40f7f7 100644 --- a/run_model_on_snellius/exe/README.md +++ b/run_model_on_snellius/exe/README.md @@ -1,14 +1,12 @@ # Create an executable file of STEMMUS_SCOPE If you want to run the STEMMUS_SCOPE model, you need to run it using MATLAB or -[MATLAB Runtime](https://nl.mathworks.com/products/compiler/matlab-runtime.html). You don't need a license for MATLAB Runtime. +[MATLAB Runtime](https://nl.mathworks.com/products/compiler/matlab-runtime.html). You don't need a license for MATLAB Runtime. The file `STEMMUS_SCOPE` under `exe` directory is an executable file of STEMMUS_SCOPE that is created using MATLAB version `2023a` in a Linux system. Note that the version of the MATLAB Runtime is tied to the version of MATLAB. -For more information, see [How to run STEMMUS_SCOPE on -CRIB](../README.md#how-to-run-stemmus_scope-on-crib) or [How to run -STEMMUS_SCOPE on Snellius](../README.md#how-to-run-stemmus_scope-on-snellius). +For more information, see documentation. To re-create an executable file of `STEMMUS_SCOPE`, you need a license for [MATLAB compiler](https://nl.mathworks.com/products/compiler.html). In order to use MATLAB on Snellius, you need to send a request to add you to the From 271d836aac23201ed47d5d2d08c71f1ca1ef72f3 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 11 Oct 2024 10:50:50 +0200 Subject: [PATCH 09/11] polish docs --- docs/CONTRIBUTING.md | 20 +++++++++++--------- docs/run_model.md | 4 ++-- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 3a58e701..41cd1fcc 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -2,7 +2,7 @@ > NOTE: The instructions below are meant for users who want to add changes to the model source code. If you want to run the model, see the documentation on -`Running the model`. +["**Running the model**"](./run_model.md). This repository includes the MATLAB source code of the STEMMUS-SCOPE model. We welcome any kind of contributions to our software, from simple comments or questions to a full @@ -151,7 +151,7 @@ To know about the most common Git commands, follow the guides ## Adding changes to the model source code To setup the required software and configurations, see the documentation on -`Getting started`. +["**Getting started**"](./getting_started.md). It would be ideal to introduce changes incrementally over time. This way, you can track the changes and understand the impact of each change. Here are the @@ -209,7 +209,7 @@ When you are reviewing a pull request, you should follow the steps below: When you are merging a pull request, you should follow the steps below: - Make sure the pull request is approved by at least one reviewer. -- Make sure all the items in the pull requests list are checked. +- Make sure all the items in the pull request's list are checked. ## Creating an executable file of STEMMUS_SCOPE @@ -292,20 +292,22 @@ browser. When you are ready to make a release of the model, follow the steps below: -- Make sure all new changes are added to changes log in the [`CHANGELOG.md` - file](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/CHANGELOG.md). +- Make sure all new changes are added to changes log in the file + ["CHANGELOG.md"](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/CHANGELOG.md). - Create a new release in the repository. The release should have a version number following the [semantic versioning](https://semver.org/) guidelines. - Add a description of the changes in the release notes. ## GitHub actions workflow -GitHub actions workflows are located in the folder `.github/workflows`: +[GitHub +actions](https://docs.github.com/en/actions/about-github-actions/understanding-github-actions) +workflows are located in the folder `.github/workflows`: - `lint.yml`: This workflow checks the code style and lints the code using `MISS_HIT`. - `doc_deploy.yml`: This workflow builds the documentation and deploys it to - GitHub pages. + GitHub pages. It will create a gh-pages branch in the repository. - `publish-container`: This workflow builds the docker image and publishes it to the repository once a new release is made. The docker image will avialable in the @@ -322,7 +324,7 @@ workflow](#github-actions-workflow). To build and run the docker image locally, follow the steps below: - Install [Docker](https://www.docker.com/). -- Build the docker image as: +- Build the docker image **locally** as: ```bash cd STEMMUS_SCOPE @@ -345,4 +347,4 @@ follow the steps below: ## Octave compatibility -See the documentation on [Octave compatibility](./Octave_instructions.md). +See the documentation on [Octave](./Octave_instructions.md). diff --git a/docs/run_model.md b/docs/run_model.md index 05ab07e5..b713cae5 100644 --- a/docs/run_model.md +++ b/docs/run_model.md @@ -1,8 +1,8 @@ # > NOTE: The instructions below are meant for users who want to run the model. If -you want to add changes to the model, see the documentation on `Contributing -guide`. +you want to add changes to the model, see the documentation on ["**Contributing +guide**"](./CONTRIBUTING.md). ## Workflow of STEMMUS_SCOPE From 0aae7a725aa379ee72c3cba3f00747768fca80f4 Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Fri, 11 Oct 2024 11:01:06 +0200 Subject: [PATCH 10/11] fix links in pull request template --- pull_request_template.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pull_request_template.md b/pull_request_template.md index be1b31af..de2db406 100644 --- a/pull_request_template.md +++ b/pull_request_template.md @@ -6,8 +6,10 @@ Please add a description of the changes proposed in the pull request. - [ ] @mentions of the person or team responsible for reviewing proposed changes. - [ ] This pull request has a descriptive title. - [ ] Code is written according to the [guidelines](http://cnl.sogang.ac.kr/cnlab/lectures/programming/matlab/Richard_Johnson-MatlabStyle2_book.pdf). -- [ ] The checks by [MISS_HIT style checker and linter](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/CONTRIBUTING.md#follow-matlab-style-guidelines), below the pull request, are successful (green). +- [ ] The checks by [MISS_HIT style checker and + linter](./docs/CONTRIBUTING.md#miss_hit-checks), below the pull request, are + successful (green). - [ ] Documentation is available. - [ ] Add changes to the [changelog file](CHANGELOG.md) under section `Unreleased`. -- [ ] Model runs successfully. +- [ ] Model runs successfully, see [tests](./docs/CONTRIBUTING.md#testing-new-changes). - [ ] Ask a meinatainer to re-generate exe file if matlab codes are changed. About how to create an exe file, see [exe readme](https://github.com/EcoExtreML/STEMMUS_SCOPE/blob/main/run_model_on_snellius/exe/README.md). From 2acb92293bb202bc06adf8472b3471da87d7d9ff Mon Sep 17 00:00:00 2001 From: SarahAlidoost Date: Mon, 14 Oct 2024 16:28:21 +0200 Subject: [PATCH 11/11] add changes to changelog file --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4b2edb2..20606166 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Unreleased +**Added:** + +- Documentation using mkdocs and a github action workflow to publish the + documentation in [#264](https://github.com/EcoExtreML/STEMMUS_SCOPE/pull/264) + **Changed:**
@@ -50,7 +55,7 @@ as well as various bugfixes. - Defining the indices of the first four layers discussed in [#237](https://github.com/EcoExtreML/STEMMUS_SCOPE/issues/237) and fixed in [#238](https://github.com/EcoExtreML/STEMMUS_SCOPE/pull/238) - + # [1.5.0](https://github.com/EcoExtreML/STEMMUS_SCOPE/releases/tag/1.5.0) - 3 Jan 2024