--- title: "Running MAAT in PEcAn" author: "Shawn Serbin" output: rmarkdown::html_vignette vignette: | %\VignetteIndexEntry{Running MAAT in PEcAn} %\VignetteEngine{knitr::rmarkdown} --- ```{r echo=FALSE} knitr::opts_chunk$set(message = FALSE, warnings = FALSE, cache = FALSE, fig.height= 3, fig.width = 8) ``` # Overview A simple example to show how to setup and run MAAT simulations within the PEcAn framework. Running the MAAT model within PEcAn provides access to additional tools such as the PEcAn met process functions that enable the creation of model-specific met driver files using various sources such as reanalysis products including CRU-NCEP and NARR, as well as site-level tower observations from AmerifluxLBL and FLUXNET. In addition, the PEcAn framework provides the ability to define custom plant functional types (PFTs) for MAAT simulation and conduct multi-ensemble simulations using observationally-constrained MAAT parameter distributions based on a hierarchical Bayesian meta-analysis approach linked to the BETYdb trait database (betydb.org). Presently the full MAAT process representation, functionality and tools are not yet fully enabled in the PEcAn framework but adding in more the MAAT functionality is planned in future updates to the PEcAn wrapper code. ## MAAT Installation and usage **MAAT model source:** https://github.com/walkeranthonyp/MAAT
Follow the instructions found here: https://github.com/walkeranthonyp/MAAT/blob/master/README.md
## Installing the R packages ```{r install, eval = FALSE} options(repos = c(getOption("repos"), PEcAn = "pecanproject.r-universe.dev")) install.packages("PEcAn.MAAT") ``` ```{r load-pkg} library(PEcAn.MAAT) ``` ## MAAT XML configuration ### E.g. Running without met drivers and using user-specified met conditions ```{cat maat_nomet} leaf 'f_vcmax_constant' 'f_jmax_constant' 'f_rd_constant' 'f_rs_ball1987' 'f_j_farquharwong1984' 400 30 0.21 1500 0 0 1 0 101325 1 ``` ### E.g. Running with met drivers ```{cat maat_met} leaf 'f_vcmax_constant' 'f_jmax_constant' 'f_rd_constant' 'f_rs_ball1987' 'f_j_farquharwong1984' ``` ## Full PEcAn XML configuration with MAAT options ### E.g. pecan.xml file with MAAT configuration options. In this example the MAAT model is configured for a temperate deciduous forest based on the temperate.deciduous PFT in the BETYdb database (https://www.betydb.org/pfts/2000000044). ```{cat pecan_xml} ~/scratch/maat_pecan_test_run/ PostgreSQL bety bety localhost bety FALSE temperate.deciduous 3000 FALSE 1.2 TRUE 10 assimilation_rate -3 -2 -1 0 1 2 3 assimilation_rate MAAT 2000000010 leaf 'f_vcmax_constant' 'f_jmax_constant' 'f_rd_constant' 'f_rs_ball1987' 'f_j_farquharwong1984' 'f_tcor_asc_Arrhenius' 'f_tcor_asc_Arrhenius' 'f_tcor_asc_Q10' 'f_tcor_asc_Arrhenius' 'f_tcor_des_modArrhenius' 'f_tcor_des_modArrhenius' 'f_tcor_des_cox2001' 1000000146 2005/01/01 2006/12/31 AmerifluxLBL MAAT pecan 2005/01/01 2006/12/31 localhost ``` ## Simple MAAT run in PEcAn In this example we will run ten MAAT model ensembles in serial based on parameter values derived from the temperate.deciduous PFT in the BETYdb database (https://www.betydb.org/pfts/2000000044) and the PEcAn meta analysis step This chunk is shown but is not currently executed at vignette build time, because running it requires a connection to the PEcAn database. ```{r run_maat, eval = FALSE} rundir <- tempfile("maat_pecan_test_run") dir.create(rundir) setwd(rundir) settings <- PEcAn.settings::read.settings(system.file("pecan.maat.xml", package="PEcAn.MAAT", mustWork = TRUE)) settings$outdir <- rundir settings <- PEcAn.settings::prepare.settings(settings, force=FALSE) PEcAn.logger::logger.info(paste0("Main output directory: ",settings$outdir)) # Write pecan.CHECKED.xml PEcAn.settings::write.settings(settings, outputfile = "pecan.CHECKED.xml") # start from scratch if no continue is passed in statusFile <- file.path(settings$outdir, "STATUS") if (length(which(commandArgs() == "--continue")) == 0 && file.exists(statusFile)) { file.remove(statusFile) } # Do conversions settings <- PEcAn.workflow::do_conversions(settings) # Query the trait database for data and priors if (PEcAn.utils::status.check("TRAIT") == 0){ PEcAn.utils::status.start("TRAIT") settings <- PEcAn.workflow::runModule.get.trait.data(settings) PEcAn.settings::write.settings(settings, outputfile='pecan.TRAIT.xml') PEcAn.utils::status.end() } else if (file.exists(file.path(settings$outdir, 'pecan.TRAIT.xml'))) { settings <- PEcAn.settings::read.settings(file.path(settings$outdir, 'pecan.TRAIT.xml')) } # Run the PEcAn meta.analysis if(!is.null(settings$meta.analysis)) { if (PEcAn.utils::status.check("META") == 0){ PEcAn.utils::status.start("META") PEcAn.MA::runModule.run.meta.analysis(settings) PEcAn.utils::status.end() } } # Write model specific configs if (PEcAn.utils::status.check("CONFIG") == 0){ PEcAn.utils::status.start("CONFIG") settings <- PEcAn.workflow::runModule.run.write.configs(settings) PEcAn.settings::write.settings(settings, outputfile='pecan.CONFIGS.xml') PEcAn.utils::status.end() } else if (file.exists(file.path(settings$outdir, 'pecan.CONFIGS.xml'))) { settings <- PEcAn.settings::read.settings(file.path(settings$outdir, 'pecan.CONFIGS.xml')) } # Start MAAT model runs if (PEcAn.utils::status.check("MODEL") == 0) { PEcAn.utils::status.start("MODEL") PEcAn.workflow::runModule_start_model_runs(settings,stop.on.error=FALSE) PEcAn.utils::status.end() } PEcAn.logger::logger.info("*** Wait for model runs to finish. Since this is a serial execution of MAAT, it will take a few minutes ***") # Get results of model runs if (PEcAn.utils::status.check("OUTPUT") == 0) { PEcAn.utils::status.start("OUTPUT") runModule.get.results(settings) PEcAn.utils::status.end() } # Run ensemble analysis on model output. if ('ensemble' %in% names(settings) & PEcAn.utils::status.check("ENSEMBLE") == 0) { PEcAn.utils::status.start("ENSEMBLE") runModule.run.ensemble.analysis(settings, TRUE) PEcAn.utils::status.end() } # Pecan workflow complete if (PEcAn.utils::status.check("FINISHED") == 0) { PEcAn.utils::status.start("FINISHED") PEcAn.remote::kill.tunnel(settings) db.query(paste("UPDATE workflows SET finished_at=NOW() WHERE id=", settings$workflow$id, "AND finished_at IS NULL"), params=settings$database$bety) # Send email if configured if (!is.null(settings$email) && !is.null(settings$email$to) && (settings$email$to != "")) { sendmail(settings$email$from, settings$email$to, paste0("Workflow has finished executing at ", base::date()), paste0("You can find the results on ", settings$email$url)) } PEcAn.utils::status.end() } db.print.connections() print("---------- PEcAn Workflow Complete ----------") print(" ") print(" ") print("---------- Simple ensemble plot ----------") # create a simple timeseries plot of the ensemble output # get output and calculate some stats ensemble_output <- list.files(path = settings$outdir, pattern = "ensemble.ts.NOENSEMBLEID.*Rdata") load(file.path(settings$outdir,ensemble_output)) timeseries_stats <- apply(ensemble.ts$assimilation_rate,2,quantile,probs=c(0.025,0.5,0.975)) # create timeseries X axis x_axis <- seq(as.Date(settings$run$start.date), as.Date(settings$run$end.date), length.out=dim(timeseries_stats)[2]) # create a new plot window dev.new(width=14, height=8, unit="in") # create plot plot(x_axis, PEcAn.utils::misc.convert(timeseries_stats[2,],"kg C m-2 s-1","umol C m-2 s-1"), type="l",cex=0.00001, col="white", xlab="Time", ylab="Assimilation_rate (umol/m2/s)") polygon(c(x_axis ,rev(x_axis)),c(PEcAn.utils::misc.convert(timeseries_stats[3,],"kg C m-2 s-1","umol C m-2 s-1"), rev(PEcAn.utils::misc.convert(timeseries_stats[1,],"kg C m-2 s-1","umol C m-2 s-1"))), col="#99CC99",border="#99CC99") lines(x_axis,PEcAn.utils::misc.convert(timeseries_stats[2,],"kg C m-2 s-1","umol C m-2 s-1"),lwd=1, lty=1, col="light grey") # close plot dev.off() ``` Example output MAAT assimilation rate from the five PEcAn model esemble simulations. The green shaded area represents the ensemble spread and the grey line shows the mean simulation. ![Example output MAAT assimilation rate from the five PEcAn model esemble simulations](graphics/example_assimilation_rate.png)