Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added tools for cache persistent status messages #177

Merged
merged 7 commits into from
Jul 25, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .buildlibrary
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ValidationKey: '6845650'
ValidationKey: '7042320'
AcceptedWarnings:
- 'Warning: package ''.*'' was built under R version'
- 'Warning: namespace ''.*'' is not available and has been replaced'
Expand Down
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ cff-version: 1.2.0
message: If you use this software, please cite it using the metadata from this file.
type: software
title: 'madrat: May All Data be Reproducible and Transparent (MADRaT) *'
version: 3.5.0
date-released: '2023-07-21'
version: 3.6.0
date-released: '2023-07-24'
abstract: Provides a framework which should improve reproducibility and transparency
in data processing. It provides functionality such as automatic meta data creation
and management, rudimentary quality management, data caching, work-flow management
Expand Down
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Type: Package
Package: madrat
Title: May All Data be Reproducible and Transparent (MADRaT) *
Version: 3.5.0
Date: 2023-07-21
Version: 3.6.0
Date: 2023-07-24
Authors@R: c(
person("Jan Philipp", "Dietrich", , "[email protected]", role = c("aut", "cre")),
person("Lavinia", "Baumstark", , "[email protected]", role = "aut"),
Expand Down
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export(getISOlist)
export(getLocation)
export(getMadratGraph)
export(getMadratInfo)
export(getMadratMessage)
export(getSources)
export(installedMadratUniverse)
export(localConfig)
Expand All @@ -24,8 +25,10 @@ export(madratAttach)
export(madratDetach)
export(metadataGFZ)
export(pucAggregate)
export(putMadratMessage)
export(readSource)
export(regionscode)
export(resetMadratMessages)
export(retrieveData)
export(setConfig)
export(toolAggregate)
Expand Down
1 change: 1 addition & 0 deletions R/cacheGet.R
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ cacheGet <- function(prefix, type, args = NULL, graph = NULL, ...) {
x[[elem]] <- .terraLoad(x[[elem]])
}
}
putMadratMessage(value = attr(x, "madratMessage"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would have expected that the message is also printed here, is there a reason why not?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, with this procedure you can store various types of information. For some you might want to have them reported at some point for others you might not. As it is unclear what should happen with this information I would not print it here.

attr(x, "id") <- fname
return(x)
}
3 changes: 3 additions & 0 deletions R/cachePut.R
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ cachePut <- function(x, prefix, type, args = NULL, graph = NULL, ...) {
}
}
}

attr(x, "madratMessage") <- getMadratMessage(fname = paste0(prefix, type))

# write to tempfile to avoid corrupt cache files in parallel running preprocessings
tempfileName <- paste0(fname, Sys.getenv("SLURM_JOB_ID", unset = ""))
saveRDS(x, file = tempfileName, compress = getConfig("cachecompression"))
Expand Down
31 changes: 31 additions & 0 deletions R/getMadratMessage.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#' Tool: getMadratMessage
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me think it is a function with the "tool" prefix, but it is not. So maybe delete the "Tool: " here?

Suggested change
#' Tool: getMadratMessage
#' getMadratMessage

#'
#' Read a madrat message from the madrat environment. The madrat environment
#' behaves similar like global options, except that 1) messages will also
#' be stored in cache files and restored when a cache file is being loaded and
#' 2) messages are always stored in lists with messages split by function calls
#' where the message was triggered.
#'
#' @param name The category in which the message should be stored
#' @param fname function name. If specified only messages belonging to the
#' functions history will be returned (this includes entries from the function
#' itself, but also entries from functions which were called by this function).
#' @author Jan Philipp Dietrich
#' @seealso \code{\link{getMadratMessage}}
#' @examples
#' putMadratMessage("test", "This is a toast", fname = "readTau")
#' getMadratMessage("test", fname = "calcTauTotal")
#' @export

getMadratMessage <- function(name = NULL, fname = NULL) {
x <- getOption("madratMessage")
if (!is.null(x) && !is.null(fname)) {
deps <- suppressWarnings(getDependencies(sub("^.*:::", "", fname),
pfuehrlich-pik marked this conversation as resolved.
Show resolved Hide resolved
packages = getConfig("packages"), self = TRUE)$func)
for (n in names(x)) {
x[[n]] <- x[[n]][sub("^.*:::", "", names(x[[n]])) %in% deps]
}
}
if (!is.null(name)) x <- x[[name]]
return(x)
}
39 changes: 39 additions & 0 deletions R/putMadratMessage.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#' Tool: putMadratMessage
#'
#' Store a madrat message in the madrat environment. The madrat environment
#' behaves similar like global options, except that 1) messages will also
#' be stored in cache files and restored when a cache file is being loaded and
#' 2) messages are always stored in lists with messages split by function calls
#' where the message was triggered.
#'
#' @param name The category in which the message should be stored
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What categories do you mean here? The example puts "test" here, but I'm still not sure how to use this. It is an arbitrary string chosen by the user?

#' @param value The message that should be recorded as character. Alternatively,
#' if \code{name} is not set, it is also possible to provide a complete list
#' of the structure value[[name]][[fname]] where name and fname correspond
pfuehrlich-pik marked this conversation as resolved.
Show resolved Hide resolved
#' to the category name and function name entries.
#' @param fname function name the entry belongs to or the frame number from which
#' the function name should be derived from (e.g. -1 to recieve function name
#' from parent function).
#' @param add boolean deciding whether the value should be added to a existing
#' value (TRUE) or overwrite it (FALSE)
#' @author Jan Philipp Dietrich
#' @seealso \code{\link{putMadratMessage}}
#' @examples
#' putMadratMessage("test", "This is a toast", fname = "readTau")
#' getMadratMessage("test", fname = "calcTauTotal")
#' @export

putMadratMessage <- function(name, value, fname = -1, add = FALSE) {
if ((missing(name) || is.null(name)) && is.list(value) && !is.null(names(value))) {
for (n in names(value)) {
for (f in names(value[[n]])) {
putMadratMessage(name = n, value = value[[n]][[f]], fname = f, add = add)
}
}
} else {
if (is.numeric(fname)) fname <- as.character(sys.call(fname))[1]
madratMessage <- getOption("madratMessage")
madratMessage[[name]][[fname]] <- if (add) c(madratMessage[[name]][[fname]], value) else value
options(madratMessage = madratMessage) # nolint: undesirable_function_linter
}
}
40 changes: 40 additions & 0 deletions R/resetMadratMessages.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#' Tool: resetMadratMessages
#'
#' Delete stored madrat messages from the madrat environment. The madrat environment
#' behaves similar like global options, except that 1) messages will also
#' be stored in cache files and restored when a cache file is being loaded and
#' 2) messages are always stored in lists with messages split by function calls
#' where the message was triggered.
pfuehrlich-pik marked this conversation as resolved.
Show resolved Hide resolved
#'
#' @param name The category for which the messages should be reset (if not set
#' messages in all categories will be reset)
pfuehrlich-pik marked this conversation as resolved.
Show resolved Hide resolved
#' @param fname function name for which the entries should be reset (if not specified
#' messages for all function names will be reset)
#' @author Jan Philipp Dietrich
#' @seealso \code{\link{putMadratMessage}}, \code{\link{getMadratMessage}}
#' @examples
#' putMadratMessage("test", "This is a toast", fname = "readTau")
#' getMadratMessage("test", fname = "calcTauTotal")
#' resetMadratMessages("test")
#' @export

resetMadratMessages <- function(name, fname) {
if (missing(name)) name <- NULL
if (missing(fname)) fname <- NULL
pfuehrlich-pik marked this conversation as resolved.
Show resolved Hide resolved

madratMessage <- getOption("madratMessage")

if (is.null(name) && is.null(fname)) {
madratMessage <- NULL
} else if (is.null(fname)) {
madratMessage[[name]] <- NULL
} else if (is.null(name)) {
for (n in names(madratMessage)) {
madratMessage[[n]][[fname]] <- NULL
}
} else {
madratMessage[[name]][[fname]] <- NULL
}
if (length(madratMessage) == 0) madratMessage <- NULL
options(madratMessage = madratMessage) # nolint: undesirable_function_linter
}
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# May All Data be Reproducible and Transparent (MADRaT) *

R package **madrat**, version **3.5.0**
R package **madrat**, version **3.6.0**

[![CRAN status](https://www.r-pkg.org/badges/version/madrat)](https://cran.r-project.org/package=madrat) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.1115490.svg)](https://doi.org/10.5281/zenodo.1115490) [![R build status](https://github.com/pik-piam/madrat/workflows/check/badge.svg)](https://github.com/pik-piam/madrat/actions) [![codecov](https://codecov.io/gh/pik-piam/madrat/branch/master/graph/badge.svg)](https://app.codecov.io/gh/pik-piam/madrat) [![r-universe](https://pik-piam.r-universe.dev/badges/madrat)](https://pik-piam.r-universe.dev/builds)

Expand Down Expand Up @@ -55,7 +55,7 @@ In case of questions / problems please contact Jan Philipp Dietrich <dietrich@pi

To cite package **madrat** in publications use:

Dietrich J, Baumstark L, Wirth S, Giannousakis A, Rodrigues R, Bodirsky B, Leip D, Kreidenweis U, Klein D, Führlich P (2023). _madrat: May All Data be Reproducible and Transparent (MADRaT)_. doi: 10.5281/zenodo.1115490 (URL: https://doi.org/10.5281/zenodo.1115490), R package version 3.5.0, <URL: https://github.com/pik-piam/madrat>.
Dietrich J, Baumstark L, Wirth S, Giannousakis A, Rodrigues R, Bodirsky B, Leip D, Kreidenweis U, Klein D, Führlich P (2023). _madrat: May All Data be Reproducible and Transparent (MADRaT)_. doi: 10.5281/zenodo.1115490 (URL: https://doi.org/10.5281/zenodo.1115490), R package version 3.6.0, <URL: https://github.com/pik-piam/madrat>.

A BibTeX entry for LaTeX users is

Expand All @@ -64,7 +64,7 @@ A BibTeX entry for LaTeX users is
title = {madrat: May All Data be Reproducible and Transparent (MADRaT)},
author = {Jan Philipp Dietrich and Lavinia Baumstark and Stephen Wirth and Anastasis Giannousakis and Renato Rodrigues and Benjamin Leon Bodirsky and Debbora Leip and Ulrich Kreidenweis and David Klein and Pascal Führlich},
year = {2023},
note = {R package version 3.5.0},
note = {R package version 3.6.0},
doi = {10.5281/zenodo.1115490},
url = {https://github.com/pik-piam/madrat},
}
Expand Down
32 changes: 32 additions & 0 deletions man/getMadratMessage.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions man/putMadratMessage.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions man/resetMadratMessages.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/visualizeDependencies.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 57 additions & 0 deletions tests/testthat/test-getputMadratMessage.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
test_that("getMadratMessage and putMadratMessage work", {
localConfig(globalenv = FALSE, .verbose = FALSE)
expect_silent(resetMadratMessages())
expect_silent(putMadratMessage("test", "This is a test", fname = "example"))
expect_silent(putMadratMessage("test", "This is a toast", fname = "readTau"))
expect_identical(getOption("madratMessage"), list(test = list(example = "This is a test",
readTau = "This is a toast")))
expect_identical(getMadratMessage("test", fname = "calcTauTotal"), list(readTau = "This is a toast"))
expect_silent(resetMadratMessages())
expect_null(getMadratMessage())
test <- function() {
putMadratMessage("level", "level 1")
.tmp <- function() {
putMadratMessage("level", "level 2")
putMadratMessage("level", "level 1 again", fname = -2, add = TRUE)
}
.tmp()
}
test()
expect_identical(getMadratMessage(), list(level = list(test = c("level 1", "level 1 again"), .tmp = "level 2")))
expect_silent(resetMadratMessages(fname = ".tmp"))
expect_identical(getMadratMessage(), list(level = list(test = c("level 1", "level 1 again"))))
expect_silent(resetMadratMessages("level"))
expect_null(getMadratMessage())
})

test_that("get/putMadratMessage work in combination with caching", {
localConfig(globalenv = TRUE, .verbose = FALSE)
resetMadratMessages()

calcMessage1 <- function() {
putMadratMessage("example", "message 1")
return(list(x = as.magpie(1), description = "-", unit = "-"))
}
calcMessage2 <- function() {
putMadratMessage("example", "message 2")
return(list(x = as.magpie(2), description = "-", unit = "-"))
}
calcMessage3 <- function() {
x <- calcOutput("Message1", aggregate = FALSE)
putMadratMessage("example", "message 3")
return(list(x = as.magpie(3), description = "-", unit = "-"))
}
globalassign("calcMessage1", "calcMessage2", "calcMessage3")

tmp <- calcOutput("Message2", aggregate = FALSE)
expect_identical(getMadratMessage(), list(example = list(calcMessage2 = "message 2")))
tmp <- calcOutput("Message3", aggregate = FALSE)
expect_identical(getMadratMessage(), list(example = list(calcMessage2 = "message 2", calcMessage1 = "message 1",
calcMessage3 = "message 3")))
options(madratMessage = NULL)
expect_null(getMadratMessage())
tmp <- calcOutput("Message3", aggregate = FALSE)
expect_identical(getMadratMessage(), list(example = list(calcMessage1 = "message 1",
calcMessage3 = "message 3")))
resetMadratMessages()
})
Loading