# Volcano Cooking

[![PyPI version](https://img.shields.io/pypi/v/volcano-cooking)](https://pypi.org/project/volcano-cooking/)
[![codecov](https://codecov.io/gh/engeir/volcano-cooking/branch/main/graph/badge.svg?token=8I5VE7LYA4)](https://codecov.io/gh/engeir/volcano-cooking)
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

> Let's make some volcanoes erupt!

[![asciicast](https://asciinema.org/a/6eOsLnlOikscbXYLJqclxytD3.svg)](https://asciinema.org/a/6eOsLnlOikscbXYLJqclxytD3)

__NOTE:__
The created dates *must* start before the model start. Running CESM2 from year 1850 with
the first eruption in 1850 will make it crash. Setting the first eruption to 1849,
however, will make it run. The same goes for the end, the model must stop prior to the
last event, otherwise it will crash. This project will make sure one event is placed
ahead of the `init` year, but the end will vary depending on number of events created
and their frequency.

## Install

The package is published on [PyPI] and installable via `pip`:

```bash
pip install volcano-cooking
```

<!-- FIXME: add reference to available classes -->
If you only plan on using the already present generator classes and only need the CLI
program, it is recommended to install this with [pipx][pipx-source]:

```bash
pipx install volcano-cooking
```

## Usage

### The basics

There are mainly two CLI programs coming with this project. The main program is
`volcano-cooking`, which will create a `.nc` and `.npz` file in the `data/output`
directory. With the `view-frc` program you can quickly view the content of the created
files in a plot. There is also a third program called `sfrc-sparse2lin` which converts
arrays of only non-zero events at arbitrary times to linearly spaced events where times
between the non-zero events are filled with zeros.

### `volcano-cooking`

Once installed, run from within this directory with:

```bash
volcano-cooking
```

All created files are saved to a `data/output` directory that will be created inside the
current directory from where the `volcano-cooking` command is run.

For more information, see

```bash
volcano-cooking --help
```

> [!TIP]
>
> It is also possible to run the CLI as a python module. Try: `python -m volcano_cooking
> --help`, `python -m volcano_cooking.view_forcing --help` or `python -m
> volcano_cooking.sparse_to_lin --help`.

#### Option 0 (default, using NCL-script)

##### TL;DR

```console
$ volcano-cooking -f 1 -s 100
Generating with 'GenerateFPP'...
$ volcano-cooking --run-ncl
 Copyright (C) 1995-2019 - All Rights Reserved
 University Corporation for Atmospheric Research
 NCAR Command Language Version 6.6.2
 The use of this software is governed by a License Agreement.
 See http://www.ncl.ucar.edu/ for more details.
(0)     in data/originals/createVolcEruptV3.ncl
...
  long_name :   SO2 elevated emissions from explosive volcanoes
  _FillValue :  9.96921e+36
(0)     saving stratvolc
(0)     File creation complete: data/cesm/VolcanEESMv3.11Enger_SO2_850-2016_Mscale_Zreduc_2deg_c20220502-140023.nc
Log file created at data/cesm/logs/20220502-140022.log
Fixing the attributes of the altitude_int coordinate...
$ volcano-cooking --package-last
Successfully placed all latest source files in the 'source-files' directory.
$ ls source-files
20220502-140022.log                     VolcanEESMv3.11Enger_SO2_850-2016_Mscale_Zreduc_2deg_c20220502-140023.nc
synthetic_volcanoes_20220502_135956.nc  synthetic_volcanoes_20220502_135956.npz
```

##### Dependencies

This option needs

- `volcano-cooking` installed
- A coordinate file (~ 10 kB)
- [`ncl`](https://www.ncl.ucar.edu/Download/) executable

##### Create source file for forcing

Run command `volcano-cooking` with the options you want. See `volcano-cooking --help`.

##### Create forcing file for CESM2

> Running the `volcano-cooking --run-ncl` script depends on having `ncl` installed. See
> installation instructions [here](https://www.ncl.ucar.edu/Download/).

After having run the `volcano-cooking` command, the forcing file for CESM2 can be
generated by running

```bash
volcano-cooking --run-ncl
```

If the needed coordinate files are missing, you will be asked if you want to download
them. If you want to use different files, or change the default resolution (default is 2
degrees), edit __.env__ (see [__./examples/.env.example__](./examples/.env.example))
accordingly. In this case, you also need to manually download whatever coordinate file
you want to use. See section [Setting up manually](#setting-up-manually).

##### Wrap up

The last created files, source files, logs and final output, can be nicely collected and
placed in a directory named `source-files` with command:

```sh
volcano-cooking --package-last
```

<details><summary><h5>Setting up manually</h5></summary><br>

To be able to create forcing files used by CESM2 from the newly created synthetic file,
we need a script from the [emissions][data_source_files] directory. These are scripts
that use the forcing file this project generates to make a new, full forcing file that
CESM2 accepts (examples of such files can be found [here][volc-frc-complete]). For
example, `createVolcEruptV3.ncl` can be found in the [emissions][data_source_files]
directory. This need a `common.ncl` file, found [here][common-ncl], in addition to other
standard `ncl` libraries. Make sure to edit `createVolcEruptV3.ncl` to read the created
file and that the first and last year cover those used in the created file. A working
version of `createVolcEruptV3.ncl` that uses input files generated by `volcano-cooking`
can be found in [data/originals](data/originals). To see what was changed from the
original, run `diff data/originals/createVolcEruptV3.ncl.original
src/volcano_cooking/createVolcEruptV3.ncl`.

Coordinate files are needed when running `createVolcEruptV3.ncl` or similar scripts, and
are located [here][coord-file]. For example `fv_1.9x2.5_L30.nc` which can be used with
two degrees resolution in the atmosphere model. The following commands will download
1 and 2 degree resolution coordinate files, respectively, to the `data/originals`
directory:

```bash
wget --no-check-certificate https://svn-ccsm-inputdata.cgd.ucar.edu/trunk/inputdata/atm/cam/coords/fv_0.9x1.25_L30.nc --directory-prefix data/originals
wget --no-check-certificate https://svn-ccsm-inputdata.cgd.ucar.edu/trunk/inputdata/atm/cam/coords/fv_1.9x2.5_L30.nc --directory-prefix data/originals
```

</details>

#### Option 1 (directly change forcing file)

##### TL;DR

```console
$ volcano-cooking -f 1 -s 100 -o
Generating with 'GenerateFPP'...
```

##### Dependencies

This option needs

- `volcano-cooking` installed
- A coordinate file (~ 10 kB)
- Original CESM2 forcing file (~ 2.2 GB)

##### Run library

Now the only thing we need to do is running `volcano-cooking` with the flag `-o`, and
choose the type of forcing we want (see `volcano-cooking --lst`):

```bash
volcano-cooking -f 1 -s 100 -o
```

<details><summary><h5>Get forcing and coordinate files manually</h5></summary><br>

> Manually downloading the files and placing them in the correct directory is *not*
> needed. Running the command as shown above will ask you if you want to download the
> files, and place them where they need to be.

This option relies on having a working forcing file and coordinate file at hand. We will
use the forcing file that CESM2 places in the `stratvolc` directory of the `cam` model.
Download from [this link][stratvolc-forcing] and place it in the `data/originals`
directory, or run command:

```bash
wget --no-check-certificate https://svn-ccsm-inputdata.cgd.ucar.edu/trunk/inputdata/atm/cam/chem/stratvolc/VolcanEESMv3.11_SO2_850-2016_Mscale_Zreduc_2deg_c191125.nc --directory-prefix data/originals
```

It's 2.2 GB file, so it will take some time.

We will also need a coordinate file, specifically `fv_1.9x2.5_L30.nc` which is found
[here][coord-file]. This file is small and quick to download. From the command line:

```bash
wget --no-check-certificate https://svn-ccsm-inputdata.cgd.ucar.edu/trunk/inputdata/atm/cam/coords/fv_0.9x1.25_L30.nc --directory-prefix data/originals
wget --no-check-certificate https://svn-ccsm-inputdata.cgd.ucar.edu/trunk/inputdata/atm/cam/coords/fv_1.9x2.5_L30.nc --directory-prefix data/originals
```

</details>

#### Examples

When running the command `volcano-cooking --run-ncl`, a few environment variables will
be used, which can be controlled by setting them in a `.env` file. See
[`.env.example`](./examples/.env.example) to see some default values. With this you can
for example easily change the grid resolution to be `1deg` rather than `2deg` (default).

The [__examples__](./examples/) directory also include an example on how to use the
`--file` option. Cloning this repository and running `volcano-cooking --file json.json`
from *inside* the __examples__ directory will result in some output files generated to a
new __data__ directory inside __examples__. If you further rename `.env.example` →
`.env` you may also run `volcano-cooking --run-ncl` and `volcano-cooking --package-last`
(this assumes you follow option 0, see below).

Finally, there is also a script [`custom_generator.py`](./examples/custom_generator.py)
which show how you might define your own generator classes and functions. Run as `python
custom_generator.py`.

### `view-frc`

After running the `volcano-cooking` command, files with names `synthetic_volcanoes_...`
are created with file type `.nc` and `.npz`. These can be viewed with

```bash
view-frc <file.nc>
```

An optional flag can be sent to the `view-frc` program that will save the plot:
`view-frc -s <file.nc>`.

For more information, see

```bash
view-frc --help
```

### `sfrc-sparse2lin`

This program is available as a convenience tool in the rare case when you have a forcing
file with only the events of eruptions. The program will re-write time array to be
linearly spaced and place the values from the forcing values into a new forcing array
that matches the new linearly spaced time axis.

It assumes the file sent to it has `yoes`(year, YYYY), `moes` (month, MM), `does`
(days, DD) and `tes` (emissions, Tg) fields if it is a `.npz` file. If a `.nc` file is
used, it must have a dataset with variables "Year_of_Emission", "Month_of_Emission",
"Day_of_Emission" and "Total_Emission".

## Extra

This assumes you are using the package from a python script, and not just the CLI.

### Compare created file with a similar used in a default CESM2 experiment

A similar file to those that are created is needed to be able to use some scripts in the
`helper_scripts` directory. By default, it assumes the file is named
`volcan-eesm_global_2015_so2-emissions-database_v1.0.nc` and that it is placed inside
the `data/originals` directory. You can find this file [here][volc-frc].

## Contributing

To contribute to the project, clone and install the full development version (uses
[poetry] for dependencies):

```bash
git clone https://github.com/engeir/volcano-cooking.git
cd volcano-cooking
poetry install
pre-commit install
```

<!-- Before committing new changes to a branch you may run the full test suite with: -->
<!---->
<!-- ```bash -->
<!-- nox -->
<!-- ``` -->
<!---->
<!-- You will need [Poetry], [nox] and [nox-poetry] installed for this. -->

[common-ncl]: http://svn.code.sf.net/p/codescripts/code/trunk/ncl/lib/common.ncl
[coord-file]: https://svn-ccsm-inputdata.cgd.ucar.edu/trunk/inputdata/atm/cam/coords/
[data_source_files]: https://svn.code.sf.net/p/codescripts/code/trunk/ncl/emission
[nox-poetry]: https://nox-poetry.readthedocs.io/
[nox]: https://nox.thea.codes/en/stable/
[pipx-source]: https://github.com/pypa/pipx
[poetry]: https://python-poetry.org
[pypi]: https://pypi.org/
[stratvolc-forcing]: https://svn-ccsm-inputdata.cgd.ucar.edu/trunk/inputdata/atm/cam/chem/stratvolc/VolcanEESMv3.11_SO2_850-2016_Mscale_Zreduc_2deg_c191125.nc
[volc-frc-complete]: https://svn-ccsm-inputdata.cgd.ucar.edu/trunk/inputdata/atm/cam/chem/stratvolc/
[volc-frc]: http://catalogue.ceda.ac.uk/uuid/bfbd5ec825fa422f9a858b14ae7b2a0d
