Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 4 additions & 4 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: RstoxFramework
Version: 4.2.0-9002
Date: 2025-09-03
Version: 4.2.0-9003
Date: 2025-10-05
Title: The Engine of StoX
Authors@R: c(
person(given = "Arne Johannes",
Expand Down Expand Up @@ -51,8 +51,8 @@ Imports:
jsonvalidate (>= 1.3.0),
methods (>= 3.6.0),
ncdf4 (>= 1.18),
RstoxBase (>= 2.2.0-9002),
RstoxData (>= 2.2.0-9002),
RstoxBase (>= 2.2.0-9004),
RstoxData (>= 2.2.0-9003),
scales (>= 1.1.0),
semver (>= 0.2.0),
sf (>= 0.9.0),
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -135,5 +135,6 @@ export(unlistToDataType)
export(unzipProject)
export(writeProjectDescription)
export(writeStoxJsonSchema)
export(writeStoxOutput)
export(write_list_as_tables_NetCDFF4)
import(data.table)
10 changes: 10 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# RstoxFramework v4.2.0-9003 (2025-09-08)
* Added the exported function writeStoxOutput() which can be used to write output from a StoX function run in R and get the same files as a StoX project would.
* Added the option unlistSingleBootstrapData to runProjects(), runProject() and rumModel().
* Refactored to use inherits() actively when checking class.
* Added support for logical columns in process data tables (represented as boolean in the JSON schema).
* Fixed bug where the type of output of plotting functions was not correctly recognised (change in getDefaultOutputFileType()).
* Some refactoring of getFunctionArguments() and getProcessOutputTextFilePath().
* Added support for specifying which columns to write in writeGPX (using the "layers" argument).


# RstoxFramework v4.2.0-9002 (2025-09-01)
* Changed how help pages are generated, from generating the html on the fly using getObjectHelpAsHtml() to instead fetching html from the new RstoxDefinition object named "objectHelp", which is compiled from htmls generated by RstoxBuild for the individual Rstox packages. This saves significant time when moving between processes in the StoX GUI (roughly half the time compared to StoX 4.1.4).
* Renamed UseDefaultTextSettings to UseDefaultLabelSettings in PlotReportBootstrap().
Expand Down
61 changes: 36 additions & 25 deletions R/API.R
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ runModel <- function(
replaceDataList = list(), replaceArgsList = list(), prependProcessList = list(),
fileOutput = NULL,
setUseProcessDataToTRUE = TRUE, purge.processData = FALSE,
returnModelData = TRUE, returnBootstrapData = FALSE, selection = list(), BootstrapID = NA, unlistSingleTable = FALSE,
returnModelData = TRUE, returnBootstrapData = FALSE, selection = list(), BootstrapID = NA, unlistSingleTable = FALSE, unlistSingleBootstrapData = TRUE,
try = TRUE,
close = FALSE,
msg = TRUE,
Expand Down Expand Up @@ -129,7 +129,7 @@ runModel <- function(
drop.datatype = drop.datatype,
warn = FALSE,
unlistDepth2 = unlistDepth2,
returnBootstrapData = returnBootstrapData, selection = selection, BootstrapID = BootstrapID, unlistSingleTable = unlistSingleTable
returnBootstrapData = returnBootstrapData, selection = selection, BootstrapID = BootstrapID, unlistSingleTable = unlistSingleTable, unlistSingleBootstrapData = unlistSingleBootstrapData
)
}
}
Expand Down Expand Up @@ -174,7 +174,7 @@ runProject <- function(
replaceDataList = list(), replaceArgsList = list(), prependProcessList = list(),
fileOutput = NULL,
setUseProcessDataToTRUE = TRUE, purge.processData = FALSE,
returnModelData = TRUE, returnBootstrapData = FALSE, selection = list(), BootstrapID = NA, unlistSingleTable = FALSE,
returnModelData = TRUE, returnBootstrapData = FALSE, selection = list(), BootstrapID = NA, unlistSingleTable = FALSE, unlistSingleBootstrapData = TRUE,
try = TRUE,
close = FALSE,
unlist.models = TRUE,
Expand Down Expand Up @@ -272,7 +272,7 @@ runProject <- function(
processes = processes,
setUseProcessDataToTRUE = setUseProcessDataToTRUE,
purge.processData = purge.processData,
returnBootstrapData = returnBootstrapData, selection = selection, BootstrapID = BootstrapID, unlistSingleTable = unlistSingleTable,
returnBootstrapData = returnBootstrapData, selection = selection, BootstrapID = BootstrapID, unlistSingleTable = unlistSingleTable, unlistSingleBootstrapData = unlistSingleBootstrapData,
try = try,
close = FALSE,
msg = msg,
Expand Down Expand Up @@ -333,7 +333,7 @@ runProjects <- function(
replaceDataList = list(), replaceArgsList = list(), prependProcessList = list(),
fileOutput = NULL,
setUseProcessDataToTRUE = TRUE, purge.processData = FALSE,
returnModelData = TRUE, returnBootstrapData = FALSE, selection = list(), BootstrapID = NA, unlistSingleTable = FALSE,
returnModelData = TRUE, returnBootstrapData = FALSE, selection = list(), BootstrapID = NA, unlistSingleTable = FALSE, unlistSingleBootstrapData = TRUE,
try = TRUE,
unlist.models = FALSE,
close = FALSE,
Expand All @@ -352,7 +352,7 @@ runProjects <- function(
fileOutput = fileOutput,
setUseProcessDataToTRUE = setUseProcessDataToTRUE, purge.processData = purge.processData,
returnModelData = returnModelData,
returnBootstrapData = returnBootstrapData, selection = selection, BootstrapID = BootstrapID, unlistSingleTable = unlistSingleTable,
returnBootstrapData = returnBootstrapData, selection = selection, BootstrapID = BootstrapID, unlistSingleTable = unlistSingleTable, unlistSingleBootstrapData = unlistSingleBootstrapData,
try = try,
unlist.models = unlist.models,
close = close,
Expand Down Expand Up @@ -513,6 +513,9 @@ readModelData <- function(
...
) {


#browser()

# List the files of the project:
if(isProject(projectPath)) {
outputFolders <- getProjectPaths(projectPath)$outputFolders
Expand Down Expand Up @@ -625,12 +628,6 @@ readStoxOutputFiles <- function(paths, emptyStringAsNA = FALSE, readCsvAsLines =
}
}

# Unlist the top level of an RData file, as an RData file is a joint file of several outputs, and we do not want the extra BootstrapData level on top of this list:
areRDataFiles <- tolower(tools::file_ext(paths)) == "rdata"
# isTRUE is TRUE only for one TRUE:
if(isTRUE(areRDataFiles)) {
output <- output[[1]]
}
return(output)
}

Expand Down Expand Up @@ -709,11 +706,30 @@ readStoxOutputFile <- function(path, emptyStringAsNA = FALSE, readCsvAsLines = F
}
}
else if(tolower(ext) == "nc") {
# Do not unlist here, as it is rather done in readModelData() (using unlist = 0 here):
output <- readBootstrapData(
path,
... # Used in readBootstrapData()
)
### # Do not unlist here, as it is rather done in readModelData() (using unlist = 0 here):
### output <- readBootstrapData(
### path,
### ... # Used in readBootstrapData()
### )
lll <- list(...)
if(isTRUE(lll$returnBootstrapData)) {
# Do not unlist here, as it is rather done in readModelData() (using unlist = 0 here):
#output <- readBootstrapData(
# path,
# ... # Used in readBootstrapData()
#)

output <- do.call(readBootstrapData, c(list(path), lll[names(lll) != "returnBootstrapData"]))

# Add class BootstrapData to the output, as the datatype is currently not written to a textfile "outputClass.txt" like the Baseline and Report processes:
class(output) <- "BootstrapData"
}

else {
output <- createStoXNetCDF4FileDataType(path)
}


}
#else if(tolower(ext) %in% "png") {
# output <- path
Expand All @@ -724,7 +740,9 @@ readStoxOutputFile <- function(path, emptyStringAsNA = FALSE, readCsvAsLines = F
}

if(emptyStringAsNA && data.table::is.data.table(output)) {
characterColumns <- names(output)[sapply(output, getRelevantClass) == "character"]
###characterColumns <- names(output)[sapply(output, getRelevantClass) == "character"]
characterColumns <- names(output)[sapply(output, inherits, "character")]

if(length(characterColumns)) {
output[, (characterColumns) := lapply(.SD, function(x) replace(x, nchar(x) == 0, NA_character_)), .SDcols = characterColumns]
}
Expand Down Expand Up @@ -759,13 +777,6 @@ subsetModelData <- function(modelData, subsetList = list()) {
}


#POSIXctToCharacter <- function(x, digits = 3) {
# browser()
# formatString <- paste0("%Y-%m-%dT%H:%M:%OS", digits, "Z")
# print(formatString)
# format(x, format = formatString)
#}

readOutputRDataFile <- function(outputDataPath) {
if(file.exists(outputDataPath)) {
outputData <- tryCatch(
Expand Down
39 changes: 22 additions & 17 deletions R/Definitions.R
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,6 @@ initiateRstoxFramework <- function(){
"nc"
)

default.output.file.type <- list(
baseline = "text",
analysis = "RData",
report = "text"
)

processProperties <- c(
"processName",
"functionName",
Expand Down Expand Up @@ -524,8 +518,10 @@ initiateRstoxFramework <- function(){
atSingleTableProcessData <- setdiff(seq_along(processDataSchemas), atMultiTableProcessData)
# Find column types of the process data tables:
columnTypes <- lapply(processDataSchemas[atSingleTableProcessData], function(x) sapply(x$items[[1]]$properties, function(x) utils::head(x$type, if(onlyFirst) 1 else Inf)))
# Translate from JSON schema to R primitive types ("string" to "character", "number" to "double", "boolean" to "logical"):
columnTypes <- rapply(columnTypes, function(x) replace(x, x == "string", "character"), how = "replace")
columnTypes <- rapply(columnTypes, function(x) replace(x, x == "number", "double"), how = "replace")
columnTypes <- rapply(columnTypes, function(x) replace(x, x == "boolean", "logical"), how = "replace")
return(columnTypes)
}
processDataColumnTypes <- getProcessDataColumnTypes(processDataSchemas)
Expand Down Expand Up @@ -643,7 +639,7 @@ initiateRstoxFramework <- function(){
#"StoX_multipolygon_WKT",
#"StoX_shapefile"
"ggplot",
#"BootstrapData",
"BootstrapData",
"StoXNetCDF4File",
"Ruter"
)
Expand Down Expand Up @@ -1311,15 +1307,18 @@ getDefaultOutputFileType <- function(processOutput) {
if(length(processOutput)) {
# Support for class specified in the output of function:
classes <- unique(c(class(processOutput), class(processOutput[[1]])))
classes2 <- class(processOutput[[1]][[1]])
if(is.list(processOutput[[1]]) && length(processOutput[[1]])) {
classes2 <- class(processOutput[[1]][[1]])
}
else {
classes2 <- NULL
}


#### Detect classes in the root or first list element:
if("StoXNetCDF4File" %in% classes) {
ext <- "nc"
}
#else if("BootstrapData" %in% classes) {
# ext <- "RData"
#}

# List of outputs:
else if("sf" %in% classes) {
Expand All @@ -1337,7 +1336,7 @@ getDefaultOutputFileType <- function(processOutput) {
else if("Ruter" %in% classes) {
# Set file extension:
ext <- "txt"
# This is the default, and is changed to the value specified by the user in the process later in reportFunctionOutputOne().
# This is the default, and is changed to the value specified by the user in the process later in writeStoxOutputOne().
}
else if("matrix" %in% classes || any(getRstoxFrameworkDefinitions("vectorClasses") %in% classes)) {
# Set file extension:
Expand All @@ -1346,13 +1345,19 @@ getDefaultOutputFileType <- function(processOutput) {
else if("ggplot" %in% classes) {
# Set file extension:
ext <- RstoxBase::getRstoxBaseDefinitions("defaultPlotOptions")$default_general_file_plot_arguments$Format # "png"
# This is the default, and is changed to the value specified by the user in the process later in reportFunctionOutputOne().
# This is the default, and is changed to the value specified by the user in the process later in writeStoxOutputOne().
}
#### Detect also classes in the recursive list element:
# List of lists of outputs:
else if("sf" %in% classes2) {
# Set file extension:
ext <- "geojson"
### # Set file extension:
### ext <- "geojson"
if(sf::st_geometry_type(processOutput[[1]][[1]])[1] == "POINT") {
ext <- "gpx"
}
else {
ext <- "geojson"
}
}
else if("data.table" %in% classes2) {
# Set file extension:
Expand All @@ -1361,7 +1366,7 @@ getDefaultOutputFileType <- function(processOutput) {
else if("Ruter" %in% classes2) {
# Set file extension:
ext <- "txt"
# This is the default, and is changed to the value specified by the user in the process later in reportFunctionOutputOne().
# This is the default, and is changed to the value specified by the user in the process later in writeStoxOutputOne().
}
else if("matrix" %in% classes2 || any(getRstoxFrameworkDefinitions("vectorClasses") %in% classes2)) {
# Set file extension:
Expand All @@ -1370,7 +1375,7 @@ getDefaultOutputFileType <- function(processOutput) {
else if("ggplot" %in% classes2) {
# Set file extension:
ext <- RstoxBase::getRstoxBaseDefinitions("defaultPlotOptions")$default_general_file_plot_arguments$Format # "png"
# This is the default, and is changed to the value specified by the user in the process later in reportFunctionOutputOne().
# This is the default, and is changed to the value specified by the user in the process later in writeStoxOutputOne().
}
else {
stop("Unknown process output: [[1]]: ", classes, ", [[1]][[1]]: ", classes2)
Expand Down
Loading
Loading