Skip to content

Commit

Permalink
Merge pull request #1 from robinhasse/main
Browse files Browse the repository at this point in the history
Reporting of stock and flow variables.
  • Loading branch information
robinhasse authored Apr 16, 2024
2 parents aa181e8 + c2c38b1 commit dd3f279
Show file tree
Hide file tree
Showing 36 changed files with 1,340 additions and 3 deletions.
9 changes: 9 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
^.*\.Rproj$
^\.Rproj\.user$
^\.buildlibrary$
^\.pre-commit-config\.yaml$
^Makefile$
^workflow$
^codecov\.yml$
^\.github$
^.*CITATION.cff$
^.lintr$
^tests/.lintr$
8 changes: 8 additions & 0 deletions .buildlibrary
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
ValidationKey: '198290'
AutocreateReadme: yes
AcceptedWarnings:
- 'Warning: package ''.*'' was built under R version'
- 'Warning: namespace ''.*'' is not available and has been replaced'
AcceptedNotes: ~
allowLinterWarnings: no
enforceVersionUpdate: no
68 changes: 68 additions & 0 deletions .github/workflows/check.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: check

on:
push:
branches: [main, master]
pull_request:
branches: [main, master]

jobs:
check:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: r-lib/actions/setup-pandoc@v2

- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true
extra-repositories: "https://rse.pik-potsdam.de/r/packages"

- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: |
any::lucode2
any::covr
any::madrat
any::magclass
any::citation
any::gms
any::goxygen
any::GDPuc
# piam packages also available on CRAN (madrat, magclass, citation,
# gms, goxygen, GDPuc) will usually have an outdated binary version
# available; by using extra-packages we get the newest version

- uses: actions/setup-python@v5
with:
python-version: 3.9

- name: Install python dependencies if applicable
run: |
[ -f requirements.txt ] && python -m pip install --upgrade pip wheel || true
[ -f requirements.txt ] && pip install -r requirements.txt || true
- name: Verify validation key
shell: Rscript {0}
run: lucode2:::validkey(stopIfInvalid = TRUE)

- name: Verify that lucode2::buildLibrary was successful
if: github.event_name == 'pull_request'
shell: Rscript {0}
run: lucode2:::isVersionUpdated()

- name: Checks
shell: Rscript {0}
run: |
options(crayon.enabled = TRUE)
lucode2::check(runLinter = FALSE)
- name: Test coverage
shell: Rscript {0}
run: |
nonDummyTests <- setdiff(list.files("./tests/testthat/"), c("test-dummy.R", "_snaps"))
if(length(nonDummyTests) > 0) covr::codecov(quiet = FALSE)
env:
NOT_CRAN: "true"
2 changes: 2 additions & 0 deletions .lintr
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
linters: lucode2::lintrRules(modification = list(object_name_linter = NULL))
encoding: "UTF-8"
28 changes: 28 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# testthat snapshots are machine-generated regression tests that
# have to be preserved exactly as they are
exclude: '^tests/testthat/_snaps/.*$'
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: check-case-conflict
- id: check-json
- id: check-merge-conflict
- id: check-yaml
- id: fix-byte-order-marker
- id: check-added-large-files
args: ['--maxkb=100']
- id: mixed-line-ending

- repo: https://github.com/lorenzwalthert/precommit
rev: v0.4.0
hooks:
- id: parsable-R
- id: deps-in-desc
args: [--allow_private_imports]
- id: no-browser-statement
- id: no-debug-statement
- id: readme-rmd-rendered
- id: use-tidy-description
ci:
autoupdate_schedule: quarterly
16 changes: 16 additions & 0 deletions CITATION.cff
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
cff-version: 1.2.0
message: If you use this software, please cite it using the metadata from this file.
type: software
title: 'reportBrick: Reporting package for BRICK'
version: 0.1.0
date-released: '2024-04-16'
abstract: This package contains BRICK-specific routines to report model results. The
main functionality is to generate a mif-file from a given BRICK model run folder.
authors:
- family-names: Hasse
given-names: Robin
email: robin.hasse@pik-potsdam.de
orcid: 0000-0003-1818-3186
license: LGPL-3.0
repository-code: https://github.com/pik-piam/reportBrick

13 changes: 10 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
Type: Package
Package: reportBrick
Title: Reporting package for BRICK
Version: 0.0.1
Date: 2024-03-18
Version: 0.1.0
Date: 2024-04-16
Authors@R:
person("Robin", "Hasse", , "robin.hasse@pik-potsdam.de",
role = c("aut", "cre"),
comment = c(ORCID = "0000-0003-1818-3186"))
Description: This package contains BRICK-specific routines to report model results. The main functionality is to generate a mif-file from a given BRICK model run folder.
License: LGPL-3
URL: https://github.com/pik-piam/reportBrick
Imports:
dplyr,
gamstransfer (>= 3.0.1),
madrat,
magclass,
yaml
Suggests:
covr,
testthat
Encoding: UTF-8
RoxygenNote: 7.2.1
RoxygenNote: 7.3.1
46 changes: 46 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
.PHONY: help build check test lint lint-all format format-all install docs
.DEFAULT_GOAL = help

# extracts the help text and formats it nicely
HELP_PARSING = 'm <- readLines("Makefile");\
m <- grep("\#\#", m, value=TRUE);\
command <- sub("^([^ ]*) *\#\#(.*)", "\\1", m);\
help <- sub("^([^ ]*) *\#\#(.*)", "\\2", m);\
cat(sprintf("%-8s%s", command, help), sep="\n")'

help: ## Show this help.
@Rscript -e $(HELP_PARSING)

build: ## Build the package using lucode2::buildLibrary(). You can pass the
## updateType with 'make build u=3'
Rscript -e 'lucode2::buildLibrary(updateType = "$(u)")'

check: ## Build documentation and vignettes, run testthat tests,
## and check if code etiquette is followed using lucode2::check().
Rscript -e 'lucode2::check()'

test: ## Run testthat tests
Rscript -e 'devtools::test(show_report = TRUE)'

lint: ## Check if code etiquette is followed using lucode2::lint().
## Only checks files you changed.
Rscript -e 'lucode2::lint()'

lint-all: ## Check if code etiquette is followed using lucode2::lint().
## Checks all files.
Rscript -e 'lucode2::lint(".")'

format: ## Apply auto-formatting to changed files and lint afterwards.
Rscript -e 'lucode2::autoFormat()'

format-all: ## Apply auto-formatting to all files and lint afterwards.
Rscript -e 'lucode2::autoFormat(files=list.files("./R", full.names = TRUE, pattern = "\\.R"))'

install: ## Install the package locally via devtools::install() after
## generating NAMESPACE and docs (see docs target).
Rscript -e 'roxygen2::roxygenize(); devtools::install(upgrade = "never")'

docs: ## Generate the package documentation (man/*.Rd files) and
## NAMESPACE via roxygen2::roxygenize(), view the generated
## documentation with `?package::function`.
Rscript -e 'roxygen2::roxygenize()'
22 changes: 22 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by roxygen2: do not edit by hand

export(convGDX2MIF)
importFrom(dplyr,"%>%")
importFrom(dplyr,all_of)
importFrom(dplyr,rename)
importFrom(dplyr,select)
importFrom(gamstransfer,Container)
importFrom(madrat,toolGetMapping)
importFrom(magclass,"getSets<-")
importFrom(magclass,add_dimension)
importFrom(magclass,as.magpie)
importFrom(magclass,collapseDim)
importFrom(magclass,dimSums)
importFrom(magclass,getItems)
importFrom(magclass,getSets)
importFrom(magclass,mbind)
importFrom(magclass,mselect)
importFrom(magclass,setNames)
importFrom(magclass,write.report)
importFrom(utils,tail)
importFrom(yaml,read_yaml)
63 changes: 63 additions & 0 deletions R/convGDX2MIF.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#' Read in GDX from BRICK and write *.mif reporting
#'
#' Read in all information from GDX file that was generated with BRICK and
#' create the *.mif reporting
#'
#' @param gdx file path to a BRICK gdx
#' @param tmpl character, BRICK reporting template. There has to be a brickSets
#' mapping named with the same suffix: \code{brickSets_<tmpl>.yaml}
#' @param file name of the mif file which will be written, if no name is
#' provided a magpie object containing all the reporting information is
#' returned
#' @param scenario scenario name that is used in the *.mif reporting
#' @param t numeric vector of reporting periods (years)
#'
#' @author Robin Hasse
#'
#' @importFrom magclass mbind add_dimension write.report getSets<-
#' @export

convGDX2MIF <- function(gdx, tmpl = NULL, file = NULL, scenario = "default", t = NULL) {

# PREPARE --------------------------------------------------------------------

# common time steps
if (is.null(t)) {
t <- as.numeric(as.character(readGdxSymbol(gdx, "ttot", asMagpie = FALSE)[[1]]))
}

# central object containing all output data
output <- NULL



# REPORT VARIABLES -----------------------------------------------------------

## Stock ====
message("running reportBuildingStock ...")
output <- mbind(output, reportBuildingStock(gdx, tmpl)[, t, ])

## Construction ====
message("running reportConstruction ...")
output <- mbind(output, reportConstruction(gdx, tmpl)[, t, ])

## Demolition ====
message("running reportDemolition ...")
output <- mbind(output, reportDemolition(gdx, tmpl)[, t, ])


# FINISH ---------------------------------------------------------------------

# Add dimension names "scenario.model.variable"
getSets(output)[3] <- "variable"
output <- add_dimension(output, dim = 3.1, add = "model", nm = "BRICK")
output <- add_dimension(output, dim = 3.1, add = "scenario", nm = scenario)

# either write the *.mif or return the magpie object
if (!is.null(file)) {
write.report(output, file = file, ndigit = 7)
} else {
return(output)
}

}
62 changes: 62 additions & 0 deletions R/readGdxSymbol.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#' Read symbol from gams container
#'
#' @param gdx character, file path to GDX file
#' @param symbol character, name of gams object
#' @param field character, field to read (only relevant for variables)
#' @param asMagpie boolean, return Magpie object
#' @returns MagPIE object with data of symbol
#'
#' @author Robin Hasse
#'
#' @importFrom gamstransfer Container
#' @importFrom dplyr select rename %>% all_of
#' @importFrom magclass as.magpie
#'
readGdxSymbol <- function(gdx, symbol, field = "level", asMagpie = TRUE) {

allFields <- c("level", "marginal", "lower", "upper", "scale")

if (!file.exists(gdx)) {
stop("This file does not exist: ", gdx)
}

if (!is.character(symbol) || length(symbol) != 1) {
stop("symbol has to be a character object of length 1.")
}

if (length(field) != 1 || !field %in% allFields) {
stop("'field' has to be one out of ",
paste(allFields, collapse = ", "),
"; not: ", field)
}

m <- Container$new(gdx)
obj <- m$getSymbols(symbol)[[1]]

data <- obj$records

# remove columns
data <- switch(class(obj)[1],
Variable = {
data %>%
select(-all_of(setdiff(allFields, field))) %>%
rename(value = field)
},
Set = {
data %>%
select(-"element_text")
},
data
)

# convert to MagPIE object
if (isTRUE(asMagpie)) {
out <- data %>%
as.magpie(spatial = "reg", temporal = "ttot", datacol = "value")
} else {
out <- data
}


return(out)
}
Loading

0 comments on commit dd3f279

Please sign in to comment.