Skip to content

Commit beb106c

Browse files
Merge pull request #376 from StoXProject/develop
Develop
2 parents 26b57b2 + 6288138 commit beb106c

29 files changed

+362
-401
lines changed

DESCRIPTION

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: RstoxFramework
2-
Version: 4.2.0-9002
3-
Date: 2025-09-03
2+
Version: 4.2.0-9003
3+
Date: 2025-10-05
44
Title: The Engine of StoX
55
Authors@R: c(
66
person(given = "Arne Johannes",
@@ -51,8 +51,8 @@ Imports:
5151
jsonvalidate (>= 1.3.0),
5252
methods (>= 3.6.0),
5353
ncdf4 (>= 1.18),
54-
RstoxBase (>= 2.2.0-9002),
55-
RstoxData (>= 2.2.0-9002),
54+
RstoxBase (>= 2.2.0-9004),
55+
RstoxData (>= 2.2.0-9003),
5656
scales (>= 1.1.0),
5757
semver (>= 0.2.0),
5858
sf (>= 0.9.0),

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,5 +135,6 @@ export(unlistToDataType)
135135
export(unzipProject)
136136
export(writeProjectDescription)
137137
export(writeStoxJsonSchema)
138+
export(writeStoxOutput)
138139
export(write_list_as_tables_NetCDFF4)
139140
import(data.table)

NEWS.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
# RstoxFramework v4.2.0-9003 (2025-09-08)
2+
* 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.
3+
* Added the option unlistSingleBootstrapData to runProjects(), runProject() and rumModel().
4+
* Refactored to use inherits() actively when checking class.
5+
* Added support for logical columns in process data tables (represented as boolean in the JSON schema).
6+
* Fixed bug where the type of output of plotting functions was not correctly recognised (change in getDefaultOutputFileType()).
7+
* Some refactoring of getFunctionArguments() and getProcessOutputTextFilePath().
8+
* Added support for specifying which columns to write in writeGPX (using the "layers" argument).
9+
10+
111
# RstoxFramework v4.2.0-9002 (2025-09-01)
212
* 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).
313
* Renamed UseDefaultTextSettings to UseDefaultLabelSettings in PlotReportBootstrap().

R/API.R

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ runModel <- function(
7272
replaceDataList = list(), replaceArgsList = list(), prependProcessList = list(),
7373
fileOutput = NULL,
7474
setUseProcessDataToTRUE = TRUE, purge.processData = FALSE,
75-
returnModelData = TRUE, returnBootstrapData = FALSE, selection = list(), BootstrapID = NA, unlistSingleTable = FALSE,
75+
returnModelData = TRUE, returnBootstrapData = FALSE, selection = list(), BootstrapID = NA, unlistSingleTable = FALSE, unlistSingleBootstrapData = TRUE,
7676
try = TRUE,
7777
close = FALSE,
7878
msg = TRUE,
@@ -129,7 +129,7 @@ runModel <- function(
129129
drop.datatype = drop.datatype,
130130
warn = FALSE,
131131
unlistDepth2 = unlistDepth2,
132-
returnBootstrapData = returnBootstrapData, selection = selection, BootstrapID = BootstrapID, unlistSingleTable = unlistSingleTable
132+
returnBootstrapData = returnBootstrapData, selection = selection, BootstrapID = BootstrapID, unlistSingleTable = unlistSingleTable, unlistSingleBootstrapData = unlistSingleBootstrapData
133133
)
134134
}
135135
}
@@ -174,7 +174,7 @@ runProject <- function(
174174
replaceDataList = list(), replaceArgsList = list(), prependProcessList = list(),
175175
fileOutput = NULL,
176176
setUseProcessDataToTRUE = TRUE, purge.processData = FALSE,
177-
returnModelData = TRUE, returnBootstrapData = FALSE, selection = list(), BootstrapID = NA, unlistSingleTable = FALSE,
177+
returnModelData = TRUE, returnBootstrapData = FALSE, selection = list(), BootstrapID = NA, unlistSingleTable = FALSE, unlistSingleBootstrapData = TRUE,
178178
try = TRUE,
179179
close = FALSE,
180180
unlist.models = TRUE,
@@ -272,7 +272,7 @@ runProject <- function(
272272
processes = processes,
273273
setUseProcessDataToTRUE = setUseProcessDataToTRUE,
274274
purge.processData = purge.processData,
275-
returnBootstrapData = returnBootstrapData, selection = selection, BootstrapID = BootstrapID, unlistSingleTable = unlistSingleTable,
275+
returnBootstrapData = returnBootstrapData, selection = selection, BootstrapID = BootstrapID, unlistSingleTable = unlistSingleTable, unlistSingleBootstrapData = unlistSingleBootstrapData,
276276
try = try,
277277
close = FALSE,
278278
msg = msg,
@@ -333,7 +333,7 @@ runProjects <- function(
333333
replaceDataList = list(), replaceArgsList = list(), prependProcessList = list(),
334334
fileOutput = NULL,
335335
setUseProcessDataToTRUE = TRUE, purge.processData = FALSE,
336-
returnModelData = TRUE, returnBootstrapData = FALSE, selection = list(), BootstrapID = NA, unlistSingleTable = FALSE,
336+
returnModelData = TRUE, returnBootstrapData = FALSE, selection = list(), BootstrapID = NA, unlistSingleTable = FALSE, unlistSingleBootstrapData = TRUE,
337337
try = TRUE,
338338
unlist.models = FALSE,
339339
close = FALSE,
@@ -352,7 +352,7 @@ runProjects <- function(
352352
fileOutput = fileOutput,
353353
setUseProcessDataToTRUE = setUseProcessDataToTRUE, purge.processData = purge.processData,
354354
returnModelData = returnModelData,
355-
returnBootstrapData = returnBootstrapData, selection = selection, BootstrapID = BootstrapID, unlistSingleTable = unlistSingleTable,
355+
returnBootstrapData = returnBootstrapData, selection = selection, BootstrapID = BootstrapID, unlistSingleTable = unlistSingleTable, unlistSingleBootstrapData = unlistSingleBootstrapData,
356356
try = try,
357357
unlist.models = unlist.models,
358358
close = close,
@@ -513,6 +513,9 @@ readModelData <- function(
513513
...
514514
) {
515515

516+
517+
#browser()
518+
516519
# List the files of the project:
517520
if(isProject(projectPath)) {
518521
outputFolders <- getProjectPaths(projectPath)$outputFolders
@@ -625,12 +628,6 @@ readStoxOutputFiles <- function(paths, emptyStringAsNA = FALSE, readCsvAsLines =
625628
}
626629
}
627630

628-
# 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:
629-
areRDataFiles <- tolower(tools::file_ext(paths)) == "rdata"
630-
# isTRUE is TRUE only for one TRUE:
631-
if(isTRUE(areRDataFiles)) {
632-
output <- output[[1]]
633-
}
634631
return(output)
635632
}
636633

@@ -709,11 +706,30 @@ readStoxOutputFile <- function(path, emptyStringAsNA = FALSE, readCsvAsLines = F
709706
}
710707
}
711708
else if(tolower(ext) == "nc") {
712-
# Do not unlist here, as it is rather done in readModelData() (using unlist = 0 here):
713-
output <- readBootstrapData(
714-
path,
715-
... # Used in readBootstrapData()
716-
)
709+
### # Do not unlist here, as it is rather done in readModelData() (using unlist = 0 here):
710+
### output <- readBootstrapData(
711+
### path,
712+
### ... # Used in readBootstrapData()
713+
### )
714+
lll <- list(...)
715+
if(isTRUE(lll$returnBootstrapData)) {
716+
# Do not unlist here, as it is rather done in readModelData() (using unlist = 0 here):
717+
#output <- readBootstrapData(
718+
# path,
719+
# ... # Used in readBootstrapData()
720+
#)
721+
722+
output <- do.call(readBootstrapData, c(list(path), lll[names(lll) != "returnBootstrapData"]))
723+
724+
# Add class BootstrapData to the output, as the datatype is currently not written to a textfile "outputClass.txt" like the Baseline and Report processes:
725+
class(output) <- "BootstrapData"
726+
}
727+
728+
else {
729+
output <- createStoXNetCDF4FileDataType(path)
730+
}
731+
732+
717733
}
718734
#else if(tolower(ext) %in% "png") {
719735
# output <- path
@@ -724,7 +740,9 @@ readStoxOutputFile <- function(path, emptyStringAsNA = FALSE, readCsvAsLines = F
724740
}
725741

726742
if(emptyStringAsNA && data.table::is.data.table(output)) {
727-
characterColumns <- names(output)[sapply(output, getRelevantClass) == "character"]
743+
###characterColumns <- names(output)[sapply(output, getRelevantClass) == "character"]
744+
characterColumns <- names(output)[sapply(output, inherits, "character")]
745+
728746
if(length(characterColumns)) {
729747
output[, (characterColumns) := lapply(.SD, function(x) replace(x, nchar(x) == 0, NA_character_)), .SDcols = characterColumns]
730748
}
@@ -759,13 +777,6 @@ subsetModelData <- function(modelData, subsetList = list()) {
759777
}
760778

761779

762-
#POSIXctToCharacter <- function(x, digits = 3) {
763-
# browser()
764-
# formatString <- paste0("%Y-%m-%dT%H:%M:%OS", digits, "Z")
765-
# print(formatString)
766-
# format(x, format = formatString)
767-
#}
768-
769780
readOutputRDataFile <- function(outputDataPath) {
770781
if(file.exists(outputDataPath)) {
771782
outputData <- tryCatch(

R/Definitions.R

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,6 @@ initiateRstoxFramework <- function(){
9898
"nc"
9999
)
100100

101-
default.output.file.type <- list(
102-
baseline = "text",
103-
analysis = "RData",
104-
report = "text"
105-
)
106-
107101
processProperties <- c(
108102
"processName",
109103
"functionName",
@@ -524,8 +518,10 @@ initiateRstoxFramework <- function(){
524518
atSingleTableProcessData <- setdiff(seq_along(processDataSchemas), atMultiTableProcessData)
525519
# Find column types of the process data tables:
526520
columnTypes <- lapply(processDataSchemas[atSingleTableProcessData], function(x) sapply(x$items[[1]]$properties, function(x) utils::head(x$type, if(onlyFirst) 1 else Inf)))
521+
# Translate from JSON schema to R primitive types ("string" to "character", "number" to "double", "boolean" to "logical"):
527522
columnTypes <- rapply(columnTypes, function(x) replace(x, x == "string", "character"), how = "replace")
528523
columnTypes <- rapply(columnTypes, function(x) replace(x, x == "number", "double"), how = "replace")
524+
columnTypes <- rapply(columnTypes, function(x) replace(x, x == "boolean", "logical"), how = "replace")
529525
return(columnTypes)
530526
}
531527
processDataColumnTypes <- getProcessDataColumnTypes(processDataSchemas)
@@ -643,7 +639,7 @@ initiateRstoxFramework <- function(){
643639
#"StoX_multipolygon_WKT",
644640
#"StoX_shapefile"
645641
"ggplot",
646-
#"BootstrapData",
642+
"BootstrapData",
647643
"StoXNetCDF4File",
648644
"Ruter"
649645
)
@@ -1311,15 +1307,18 @@ getDefaultOutputFileType <- function(processOutput) {
13111307
if(length(processOutput)) {
13121308
# Support for class specified in the output of function:
13131309
classes <- unique(c(class(processOutput), class(processOutput[[1]])))
1314-
classes2 <- class(processOutput[[1]][[1]])
1310+
if(is.list(processOutput[[1]]) && length(processOutput[[1]])) {
1311+
classes2 <- class(processOutput[[1]][[1]])
1312+
}
1313+
else {
1314+
classes2 <- NULL
1315+
}
1316+
13151317

13161318
#### Detect classes in the root or first list element:
13171319
if("StoXNetCDF4File" %in% classes) {
13181320
ext <- "nc"
13191321
}
1320-
#else if("BootstrapData" %in% classes) {
1321-
# ext <- "RData"
1322-
#}
13231322

13241323
# List of outputs:
13251324
else if("sf" %in% classes) {
@@ -1337,7 +1336,7 @@ getDefaultOutputFileType <- function(processOutput) {
13371336
else if("Ruter" %in% classes) {
13381337
# Set file extension:
13391338
ext <- "txt"
1340-
# This is the default, and is changed to the value specified by the user in the process later in reportFunctionOutputOne().
1339+
# This is the default, and is changed to the value specified by the user in the process later in writeStoxOutputOne().
13411340
}
13421341
else if("matrix" %in% classes || any(getRstoxFrameworkDefinitions("vectorClasses") %in% classes)) {
13431342
# Set file extension:
@@ -1346,13 +1345,19 @@ getDefaultOutputFileType <- function(processOutput) {
13461345
else if("ggplot" %in% classes) {
13471346
# Set file extension:
13481347
ext <- RstoxBase::getRstoxBaseDefinitions("defaultPlotOptions")$default_general_file_plot_arguments$Format # "png"
1349-
# This is the default, and is changed to the value specified by the user in the process later in reportFunctionOutputOne().
1348+
# This is the default, and is changed to the value specified by the user in the process later in writeStoxOutputOne().
13501349
}
13511350
#### Detect also classes in the recursive list element:
13521351
# List of lists of outputs:
13531352
else if("sf" %in% classes2) {
1354-
# Set file extension:
1355-
ext <- "geojson"
1353+
### # Set file extension:
1354+
### ext <- "geojson"
1355+
if(sf::st_geometry_type(processOutput[[1]][[1]])[1] == "POINT") {
1356+
ext <- "gpx"
1357+
}
1358+
else {
1359+
ext <- "geojson"
1360+
}
13561361
}
13571362
else if("data.table" %in% classes2) {
13581363
# Set file extension:
@@ -1361,7 +1366,7 @@ getDefaultOutputFileType <- function(processOutput) {
13611366
else if("Ruter" %in% classes2) {
13621367
# Set file extension:
13631368
ext <- "txt"
1364-
# This is the default, and is changed to the value specified by the user in the process later in reportFunctionOutputOne().
1369+
# This is the default, and is changed to the value specified by the user in the process later in writeStoxOutputOne().
13651370
}
13661371
else if("matrix" %in% classes2 || any(getRstoxFrameworkDefinitions("vectorClasses") %in% classes2)) {
13671372
# Set file extension:
@@ -1370,7 +1375,7 @@ getDefaultOutputFileType <- function(processOutput) {
13701375
else if("ggplot" %in% classes2) {
13711376
# Set file extension:
13721377
ext <- RstoxBase::getRstoxBaseDefinitions("defaultPlotOptions")$default_general_file_plot_arguments$Format # "png"
1373-
# This is the default, and is changed to the value specified by the user in the process later in reportFunctionOutputOne().
1378+
# This is the default, and is changed to the value specified by the user in the process later in writeStoxOutputOne().
13741379
}
13751380
else {
13761381
stop("Unknown process output: [[1]]: ", classes, ", [[1]][[1]]: ", classes2)

0 commit comments

Comments
 (0)