---
title: "Running ED from R"
author: "Alexey Shiklomanov"
output_format: rmarkdown::html_vignette
vignette: |
  %\VignetteIndexEntry{Running ED from R}
  %\VignetteEngine{knitr::rmarkdown}
---

# Introduction

The `PEcAn.ED2` package features a number of utilities to facilitate running the ED model from inside R, including
working with input files,
running the ED executable,
and processing the outputs.
This tutorial describes these utilites and provides examples of common use cases.

# Basic ED run

## Installing the R package

The `PEcAn.ED2` package and its PEcAn dependencies can be installed from GitHub as follows (all CRAN package dependencies should be installed automatically):

```{r install, eval = FALSE}
devtools::install_github("pecanproject/pecan", ref = "develop", subdir = "base/logger")
devtools::install_github("pecanproject/pecan", ref = "develop", subdir = "base/utils")
devtools::install_github("pecanproject/pecan", ref = "develop", subdir = "base/settings")
devtools::install_github("pecanproject/pecan", ref = "develop", subdir = "modules/data.atmosphere")
devtools::install_github("pecanproject/pecan", ref = "develop", subdir = "models/ed")
```

```{r library}
library(PEcAn.ED2)
```

## Installing the ED2 model

The source code for the ED2 model is available [on GitHub](https://github.com/edmodel/ed2).

Alternatively, if you have [Singularity](https://singularity.lbl.gov) container software installed, you can use a pre-built Singularity container available on [Singularity Hub](https://www.singularity-hub.org/collections/642):

```
singularity pull --name ed2.simg shub://ashiklom/ED2
```

## ED inputs

### EDI

ED requires a global land use database to determine its land-sea mask, as well as a vegetation "thermal sums" database.
These can be customized to some extent, but this package provides a version of the most common inputs.
These inputs, stored in an "EDI" directory, can be downloaded via the `download_edi` function:

```{r get_edi}
rundir <- file.path(tempdir(), "ed_run_data")
dir.create(rundir, showWarnings = FALSE)

edi_dir <- file.path(rundir, "EDI")
if (!file.exists(edi_dir)) {
  download_edi(edi_dir)
} else {
  message("EDI directory already exists. Skipping download.")
}
```

### Meteorological data

To do the ED run described here, we'll need some meteorological data.
ED meteorological data are typically stored in HDF5 format and are described by a plain text header file (typically called `ED_MET_DRIVER_HEADER`).

To download the meteorological data, we'll use the `PEcAn.data.atmosphere` package.
Here, we grab the data for the first week of July 2005 and Harvard Forest, for which we'll be running the simulation.

```{r, download_met}
start_date <- "2006-07-01"
end_date <- "2006-07-08"
latitude <- 42.53
longitude <- -72.19

raw_met <- PEcAn.data.atmosphere::download.CRUNCEP(
  outfolder = file.path(rundir, "raw_met"),
  start_date = start_date,
  end_date = start_date,
  lat.in = latitude,
  lon.in = longitude
)
```

Next, we convert this raw data to the ED-specific format.

```{r, met2model}
ed_met <- met2model.ED2(
  in.path = dirname(raw_met$file),
  in.prefix = "CRUNCEP",
  outfolder = file.path(rundir, "ed_met"),
  start_date = start_date,
  end_date = start_date,
  lat = latitude,
  lon = longitude,
  overwrite = TRUE
)
```

If you already have ED-specific meteorology available, `PEcAn.ED2` provides utilities to interact with that file directly:

```{r met_driver, eval = FALSE}
met_driver_raw <- "/path/to/ED_MET_DRIVER_HEADER"
met_driver_obj <- read_ed_metheader(met_driver_raw, check = FALSE)
met_driver_obj[[1]]$path_prefix <- "/path/to/new/location"
met_driver_obj[[1]]$xmin <- -90
met_driver_obj[[1]]$ymin <- 43

met_driver_path <- file.path(rundir, "ED_MET_DRIVER_HEADER")
write_ed_metheader(met_driver_obj, met_driver_path)
```

### Vegetation inputs

A common way to initialize ED is through three interrelated vegetation initial condition files:

* `css` -- Cohort file, which describes all plant cohorts located within a patch, including its PFT, DBH, and stand density
* `pss` -- Patch file, which describes each patch within a site (single, plot-scale runs will often have only one patch)
* `site` -- Site file, which describes each site (single, plot-scale runs will often have only one site)

The package ships with simple functional examples of these objects (`example_css/pss/site`) and functions for quickly creating custom objects based on these examples (`create_css/pss/site`).
Below, we create a `css` file with a single PFT with a specific DBH, but stick to the unmodified example `pss` and `site` files.

```{r, veg_inputs}
css <- create_css(list(pft = 11, dbh = 18.00))
pss <- example_pss
site <- example_site
veg_input <- create_ed_veg(css, pss, site, latitude, longitude, check = TRUE)

veg_prefix <- file.path(rundir, "veg_input", "test_veg")
write_ed_veg(veg_input, veg_prefix)
```

As with meteorology, `PEcAn.ED2` also provides utilities for working with existing vegetation inputs.

```{r veg_input, eval = FALSE}
veg_prefix <- "/path/to/site/files/prefix"
latitude <- 43.3724
longitude <- -89.9071
veg_input <- read_ed_veg(veg_prefix, latitude = latitude, longitude = longitude)
```

### ED configuration file

Now that all inputs are taken care of, the final step is to create the ED configuration file (typically called `ED2IN`).

First, read a `ED2IN` template file:

```{r read_ed2in}
ed2in_raw <- read_ed2in(system.file("ED2IN.rgit", package = "PEcAn.ED2"))
```

Then, set up the `ED2IN` with the required components.

```{r modify_ed2in}
ed2in <- modify_ed2in(
  ed2in_raw,
  veg_prefix = veg_prefix,
  latitude = latitude,
  longitude = longitude,
  met_driver = ed_met$file,
  EDI_path = file.path(rundir, "EDI"),
  start_date = start_date,
  end_date = end_date,
  run_dir = file.path(rundir, "run"),
  output_dir = file.path(rundir, "out"),
  runtype = "INITIAL",
  pecan_defaults = TRUE,
  EXPNME = "ED test run"
)
```

It is also a good idea to check the `ED2IN` file for internal consistency.

```{r check_ed2in}
check_ed2in(ed2in)
```

Assuming the `ed2in` object is valid, you then write it to a file to a desired directory.
This doesn't have to be the run directory (nor does the file have to be named `ED2IN`), but it's a good idea to keep the `ED2IN` file close to the run outputs, as it provides useful metadata for the run.

```{r write_ed2in}
ed2in_path <- file.path(rundir, "ED2IN")
write_ed2in(ed2in, ed2in_path)
```

### Running ED

Assuming all of the inputs are correct, running ED is as simple as calling the `run_ed_singularity` function, which requires paths to the Singularity image and ED2IN file.

```{r start_ed_run, eval = FALSE}
img_path <- "~/Projects/ED2/ed2.simg"
run_ed_singularity(img_path, ed2in_path)
```
