diff --git a/.RData b/.RData deleted file mode 100644 index 972ea6c7..00000000 Binary files a/.RData and /dev/null differ diff --git a/.Rbuildignore b/.Rbuildignore index 92d87b85..f72f4882 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -47,3 +47,4 @@ references.bib ^scripts$ .tgitconfig ^rakefile\.rb$ +_\.new\.png$ diff --git a/.gitignore b/.gitignore index dc02a93f..f7c60f19 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,5 @@ revdep/data.sqlite /Meta/ .tgitconfig tests/testthat/Rplots.pdf +# {shinytest2}: Ignore new debug snapshots for `$expect_values()` +*_.new.png diff --git a/DESCRIPTION b/DESCRIPTION index a16d2732..930b6e4b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,11 +1,13 @@ Type: Package Package: esqlabsR Title: esqLABS utilities package -Version: 3.0.0 +Version: 4.0.0 Authors@R: c(person("esqLABS GmbH", role = c("cph", "fnd")), - person("Pavel", "Balazki", role = c("cre", "aut"), email = "pavel.balazki@esqlabs.com"), - person("Johanna", "Eitel", role = "aut"), + person("Pavel", "Balazki", , "https://github.com/PavelBal", role = c("cre", "aut"), + email = "pavel.balazki@esqlabs.com"), + person("Johanna", "Eitel", , "https://github.com/hannaei", role = "aut"), + person("Sergei", "Vavilov", , "https://github.com/svavil", role = "aut"), person("Indrajeet", "Patil", , "patilindrajeet.science@gmail.com", role = "aut", comment = c(ORCID = "0000-0003-1995-6531", Twitter = "@patilindrajeets"))) Maintainer: Pavel Balazki @@ -15,31 +17,37 @@ License: GPL-2 URL: https://github.com/esqLABS/esqlabsR BugReports: https://github.com/esqLABS/esqlabsR/issues Depends: - ospsuite (>= 11.0) + R (>= 4.1), + ospsuite (>= 11.0), + ospsuite.parameteridentification Imports: colorspace, dplyr, ggplot2, - hash, ospsuite.utils (>= 1.3.0), purrr, - rClr, readxl, shiny, shinyjs, tidyr, tools, + tlf (>= 1.4.0), vctrs, - writexl + writexl, + stringr, + labeling Suggests: + clipr, knitr, rmarkdown, + shinytest2, testthat (>= 3.0.0), - vdiffr (>= 1.0.0) + vdiffr (>= 1.0.0), + withr VignetteBuilder: knitr Config/testthat/edition: 3 Encoding: UTF-8 Language: en-US Roxygen: list(markdown = TRUE) -RoxygenNote: 7.2.0 +RoxygenNote: 7.2.1 diff --git a/NAMESPACE b/NAMESPACE index 29589cfc..9e431a08 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,30 +1,27 @@ # Generated by roxygen2: do not edit by hand export("%||%") -export(DataConfiguration) -export(DataMapping) -export(DataMappingConfiguration) export(Distributions) export(GenderInt) export(GraphicsDevices) export(LLOQMode) -export(PlotConfiguration) -export(PlotTypes) export(ProjectConfiguration) export(ScenarioConfiguration) -export(XYData) -export(XYDataTypes) export(applyIndividualParameters) export(calculateMeanDataSet) -export(calculateRMSE) export(col2hsv) export(compareSimulationParameters) export(compareWithNA) export(createDefaultProjectConfiguration) +export(createEsqlabsExportConfiguration) +export(createEsqlabsPlotConfiguration) +export(createEsqlabsPlotGridConfiguration) export(enumPutList) export(escapeForRegex) export(esqLABS_colors) +export(esqlabsRSettingNames) export(executeInParallel) +export(exportParametersToXLS) export(exportSteadyStateToXLS) export(extendParameterStructure) export(extendPopulationByUserDefinedParams) @@ -32,25 +29,19 @@ export(extendPopulationFromXLS) export(foldChangeFunction) export(geomean) export(geosd) +export(getAllApplicationParameters) export(getEsqlabsRSetting) export(getIndexClosestToValue) -export(getQuantilesYData) -export(getSteadyState) +export(getMoleculeNameFromQuantity) export(hillFunction) export(initializeScenario) export(initializeSimulation) -export(isCharInString) export(isParametersEqual) export(isTableFormulasEqual) export(loadObservedData) export(pathFromClipboard) -export(plotBoxPlot) -export(plotMultiPanel) -export(plotPredictedVsObserved) -export(plotXYDataAggregated) export(readExcel) export(readIndividualCharacteristicsFromXLS) -export(readOSPSTimeValues) export(readParametersFromXLS) export(readPopulationCharacteristicsFromXLS) export(readScenarioConfigurationFromExcel) @@ -67,14 +58,14 @@ export(sourceAll) export(startFunctionVisualizer) export(startUnitConverter) export(stringToNum) +export(writeExcel) export(writeIndividualToXLS) import(colorspace) import(dplyr) import(ggplot2) -import(hash) import(ospsuite) +import(ospsuite.parameteridentification) import(ospsuite.utils) import(parallel) -import(rClr) import(readxl) importFrom(ospsuite.utils,"%||%") diff --git a/NEWS.md b/NEWS.md index 6ed7a315..c3fba4aa 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,24 +1,58 @@ -# esqlabsR 3.0.0 +# esqlabsR 4.0.0 + +MAJOR CHANGES + +- Three new functions to create configuration objects needed for data visualization workflows: + + * `createEsqlabsPlotConfiguration()` + * `createEsqlabsPlotGridConfiguration()` + * `createEsqlabsExportConfiguration()` + +- New function `getAllApplicationParameters()` that returns all parameters of +applications in a simulation +- New function `exportParametersToXLS()` to write parameter information into an +excel file that can be loaded in MoBi or R using the `readParametersFromXLS()` +function. +- New function `writeExcel()` that is a wrapper for creating a directory +(if not present) and writing to excel file using `writexl::write_xlsx()`. + +BREAKING CHANGES + +- The package requires R version >=4.1. +- The package gains new dependencies: + * [`{ospsuite.parameteridentification}`](https://github.com/Open-Systems-Pharmacology/OSPSuite.ParameterIdentification/) + * [`{tlf}`](https://www.open-systems-pharmacology.org/TLF-Library/). + +- Function `getSteadyState()` has been moved to package `{ospsuite.parameteridentification}`. + +- Function `loadObservedData()` requires a `ProjectConfiguration` instead of a +`ScenarioConfiguration`. + +- `DataMapping`, `DataMappingConfiguration`, `XYData`, `DataConfiguration` and +associated functions for creating standard figures are moved to `esqlabsRLegacy` +[package](https://esqlabs.github.io/esqlabsRLegacy/). + +# esqlabsR 3.0.0 NEW FUNCTIONS - To carry out and visualize sensitivity analysis: -* `sensitivityCalculation()` -* `sensitivitySpiderPlot()` -* `sensivitityTimeProfiles()` + * `sensitivityCalculation()` + * `sensitivitySpiderPlot()` + * `sensitivityTimeProfiles()` - Classes and functions for standard esqLABS simulation workflow: -* `ProjectConfiguration` -* `ScenarioConfiguration` -* `createDefaultProjectConfiguration()` -* `readScenarioConfigurationFromExcel()` -* `setApplications()` -* `initializeScenario()` -* `initializeScenario()` + * `ProjectConfiguration` + * `ScenarioConfiguration` + * `createDefaultProjectConfiguration()` + * `readScenarioConfigurationFromExcel()` + * `setApplications()` + * `initializeScenario()` + * `initializeScenario()` - Maintenance and bug fixes. diff --git a/R/DataConfiguration.R b/R/DataConfiguration.R deleted file mode 100644 index fac5955d..00000000 --- a/R/DataConfiguration.R +++ /dev/null @@ -1,64 +0,0 @@ -#' @title DataConfiguration -#' @docType class -#' @description An object storing configuration of for observed data import -#' @export -#' @format NULL -DataConfiguration <- R6::R6Class( - "DataConfiguration", - inherit = Printable, - cloneable = FALSE, - active = list(), - private = list(), - public = list( - #' @param dataFolder Path to the directory where the data file is located - #' @param dataFile Name of the data excel file - #' @param dataSheets Name of excel sheets to read - #' @param compoundPropertiesFile Name of the excel file with compound properties - #' @description - #' Initialize a new instance of the class - #' @return A new `DataConfiguration` object. - initialize = function(dataFolder, dataFile, compoundPropertiesFile, dataSheets) { - self$dataFolder <- dataFolder - self$dataFile <- dataFile - self$compoundPropertiesFile <- compoundPropertiesFile - self$dataSheets <- dataSheets - self$columnsToSplitBy <- esqlabsEnv$columnsToSplitDataBy - self$XValuesColumn <- esqlabsEnv$XValuesColumn - self$YValuesColumn <- esqlabsEnv$YValuesColumn - self$YErrorColumn <- esqlabsEnv$YErrorColumn - }, - - #' @field dataFolder Path to the directory where the data file is located - dataFolder = "", - #' @field dataFile Name of the data excel file - dataFile = "", - #' @field compoundPropertiesFile Name of the excel file with compound properties - compoundPropertiesFile = "Compound Properties.xlsx", - #' @field dataSheets Name of excel sheets to read - dataSheets = c(), - #' @field columnsToSplitBy Column names by which the data will be split into groups - columnsToSplitBy = "", - #' @field XValuesColumn Column index for x values in observed data files - XValuesColumn = 0, - #' @field YValuesColumn Column index for y values in observed data files - YValuesColumn = 0, - #' @field YErrorColumn Column index for y error values in observed data files - YErrorColumn = 0, - - #' @description - #' Print the object to the console - #' @param ... Rest arguments. - print = function(...) { - private$printClass() - private$printLine("Data file directory", self$dataFolder) - private$printLine("Data file", self$dataFile) - private$printLine("Sheets", self$dataSheets) - private$printLine("CompoundProperties file", self$compoundPropertiesFile) - private$printLine("Columns to split by", self$columnsToSplitBy) - private$printLine("X values column", self$XValuesColumn) - private$printLine("Y values column", self$YValuesColumn) - private$printLine("Y error column", self$YErrorColumn) - invisible(self) - } - ) -) diff --git a/R/DataMapping.R b/R/DataMapping.R deleted file mode 100644 index a9454670..00000000 --- a/R/DataMapping.R +++ /dev/null @@ -1,727 +0,0 @@ -#' @title DataMapping -#' @docType class -#' @description Mapping of model outputs to observed data -#' @export -#' @import ospsuite hash -#' @format NULL -DataMapping <- R6::R6Class( - "DataMapping", - inherit = Printable, - cloneable = FALSE, - active = list( - #' @field xySeries Named list with the `XYData` - #' that will be plotted. Names are the labels of the `xySeries` objects - xySeries = function(value) { - if (missing(value)) { - as.list(private$.xySeries) - } else { - stop(messages$errorPropertyReadOnly("xySeries")) - } - }, - - #' @field xySeriesCount number of `XYData` objects to be plotted - xySeriesCount = function(value) { - if (missing(value)) { - length(private$.xySeries) - } else { - stop(messages$errorPropertyReadOnly("xySeriesCount")) - } - }, - - #' @field xLim Limits of the x-axis. Numerical vector c(min, max) - xLim = function(value) { - if (missing(value)) { - if (is.null(private$.xLim)) { - if (length(self$xySeries) == 0) { - return(c(0, 0)) - } - xMax <- max(sapply(self$xySeries, function(x) { - toUnit( - quantityOrDimension = self$xDimension, - values = x$xMax, - targetUnit = self$xUnit, - sourceUnit = x$xUnit - ) - })) - xMin <- min(sapply(self$xySeries, function(x) { - toUnit( - quantityOrDimension = self$xDimension, - values = x$xMin, - targetUnit = self$xUnit, - sourceUnit = x$xUnit - ) - })) - # Extend limits by 10% - return(c(xMin, xMax) + abs(c(xMin, xMax)) * c(-0.1, 0.1)) - # My cat wrote this, I leave it here out of respect - # \code{runSimulationBatchesConcurrently}ß C.\JKFD. PO.#]}*#J#......................JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJöL - } else { - private$.xLim - } - } else { - validateIsNumeric(value, nullAllowed = TRUE) - if (!is.null(value)) { - validateLength(value, 2) - } - private$.xLim <- value - } - }, - - #' @field yLim Limits of the y-axis. Numerical vector c(min, max) - yLim = function(value) { - if (missing(value)) { - if (is.null(private$.yLim)) { - if (length(self$xySeries) == 0) { - return(c(0, 0)) - } - yMax <- max(sapply(self$xySeries, function(x) { - toUnit( - quantityOrDimension = self$yDimension, - values = x$yMax, - targetUnit = self$yUnit, - sourceUnit = x$yUnit, - molWeight = x$MW, - molWeightUnit = ospUnits$`Molecular weight`$`g/mol` - ) - })) - # If logarithmic scaling of the y axis is selected, the minimal value should be greater than zero - yMin <- min(sapply(self$xySeries, function(x) { - if (isCharInString("y", self$log)) { - toUnit( - quantityOrDimension = self$yDimension, - values = x$yMinPositive(), - targetUnit = self$yUnit, - sourceUnit = x$yUnit, - molWeight = x$MW, - molWeightUnit = ospUnits$`Molecular weight`$`g/mol` - ) - } else { - toUnit( - quantityOrDimension = self$yDimension, - values = x$yMin, - targetUnit = self$yUnit, - sourceUnit = x$yUnit, - molWeight = x$MW, - molWeightUnit = ospUnits$`Molecular weight`$`g/mol` - ) - } - })) - # Extend limits by 10% - return(c(yMin, yMax) + abs(c(yMin, yMax)) * c(-0.1, 0.1)) - } else { - private$.yLim - } - } else { - validateIsNumeric(value, nullAllowed = TRUE) - if (!is.null(value)) { - validateLength(value, 2) - } - private$.yLim <- value - } - }, - - #' @field xLab label of the x-axis. - xLab = function(value) { - if (missing(value)) { - private$.xLab - } else { - validateIsString(value) - private$.xLab <- value - } - }, - - #' @field yLab label of the y-axis. - yLab = function(value) { - if (missing(value)) { - private$.yLab - } else { - validateIsString(value) - private$.yLab <- value - } - }, - - #' @field xDimension Dimension of x values. See enum `ospDimensions` for the list of supported dimensions. - #' If no dimension is specified, the dimension of the first added `XYSeries` is used. - #' If no `XYSeries` are present, the dimension is `NULL` - #' When changing the dimension, the unit is automatically set to the base unit of the dimension. - xDimension = function(value) { - if (missing(value)) { - if (!is.null(private$.xDimension)) { - return(private$.xDimension) - } - if (self$xySeriesCount == 0) { - return(NULL) - } - return(self$xySeries[[1]]$xDimension) - } else { - validateDimension(value) - private$.xDimension <- value - self$xUnit <- getBaseUnit(value) - } - }, - - #' @field yDimension Dimension of y values. See enum `ospDimensions` for the list of supported dimensions. - #' If no dimension is specified, the dimension of the first added `XYSeries` is used. - #' If no `XYSeries` are present, the dimension is `NULL` - #' #' When changing the dimension, the unit is automatically set to the base unit of the dimension. - yDimension = function(value) { - if (missing(value)) { - if (!is.null(private$.yDimension)) { - return(private$.yDimension) - } - if (self$xySeriesCount == 0) { - return(NULL) - } - return(self$xySeries[[1]]$yDimension) - } else { - validateDimension(value) - private$.yDimension <- value - private$.yUnit <- getBaseUnit(value) - } - }, - - #' @field xUnit Unit of x values. - #' If no unit is specified, the default unit of the dimension is used. - #' If no dimension is specified, the unit is `NULL` - xUnit = function(value) { - if (missing(value)) { - if (!is.null(private$.xUnit)) { - return(private$.xUnit) - } - if (is.null(self$xDimension)) { - return(NULL) - } - return(getBaseUnit(self$xDimension)) - } else { - private$.xUnit <- value - } - }, - - #' @field yUnit Unit of y values. - #' If no unit is specified, the default unit of the dimension is used. - #' If no dimension is specified, the unit is `NULL` - yUnit = function(value) { - if (missing(value)) { - if (!is.null(private$.yUnit)) { - return(private$.yUnit) - } - if (is.null(self$yDimension)) { - return(NULL) - } - return(getBaseUnit(self$yDimension)) - } else { - private$.yUnit <- value - } - }, - - #' @field groupings A named list listing which data sets are grouped together. Grouped data sets will be plotted with the same color - #' and used together in the legend. - groupings = function(value) { - if (missing(value)) { - as.list(private$.groupings) - } else { - stop(messages$errorPropertyReadOnly("groupings", optionalMessage = "Data sets are assigned to groupings when adding via `addModelOutputs' - or 'addXYSeries'.")) - } - }, - - #' @field ungroupedSeries A list of `XYData` that do not belong to any group. - #' `NULL` if empty. - ungroupedSeries = function(value) { - if (missing(value)) { - private$.emptyGrouping - } else { - stop(messages$errorPropertyReadOnly("ungroupedSeries", optionalMessage = "Data sets are assigned to groupings when adding via `addModelOutputs' - or 'addXYSeries'.")) - } - }, - - #' @field plotType A string defining what kind of plot is generated when the `plot()` method of the object is called. - #' Supported plot types are listed in the enum `PlotTypes`. Default is "IndividualProfile" - plotType = function(value) { - if (missing(value)) { - private$.plotType - } else { - validateEnumValue(enum = PlotTypes, value = value) - private$.plotType <- value - } - }, - - #' @field populationQuantiles A numerical vector with three quantile values used if `plotType = "PopulationQuantiles"`. Default is - #' `c(0.05, 0.5, 0.95)` - populationQuantiles = function(value) { - if (missing(value)) { - private$.populationQuantiles - } else { - validateIsNumeric(value) - validateLength(value, 3) - private$.populationQuantiles <- value - } - } - ), - private = list( - .xySeries = NULL, - # Map linking each xySeries to a group. Used for removal of xySeries - .xySeriesGroupMap = NULL, - .xLim = NULL, - .yLim = NULL, - .xLab = NULL, - .yLab = NULL, - .xDimension = NULL, - .yDimension = NULL, - .xUnit = NULL, - .yUnit = NULL, - .groupings = NULL, - .emptyGrouping = NULL, - .plotType = "IndividualProfile", - .populationQuantiles = c(0.05, 0.5, 0.95), - .removeLabelFromGroup = function(label, group) { - # Empty grouping has to be treated separately. Empty group is identified by an NA - # because NULL cannot be added to a list. - # Have to unlist because removeFromList returns a list, but groupings are vectors of strings. - # However, if the list is empty, create an empty list... - if (is.na(group)) { - private$.emptyGrouping <- unlist(removeFromList(label, private$.emptyGrouping)) %||% list() - } else { - private$.groupings[[group]] <- unlist(removeFromList(label, private$.groupings[[group]])) - } - } - ), - public = list( - #' @description - #' Initialize a new instance of the class - #' @return A new `DataMapping` object. - initialize = function() { - private$.xySeries <- hash::hash() - private$.xySeriesGroupMap <- hash::hash() - private$.groupings <- hash::hash() - private$.emptyGrouping <- list() - }, - #' @description - #' Clean up upon object removal - finalize = function() { - hash::clear(private$.groupings) - hash::clear(private$.xySeries) - hash::clear(private$.xySeriesGroupMap) - }, - - #' @field log String defining which axis will be plotted in logarithmic scaling. - #' Possible values are "" (empty string, both axis in linear scaling, default), - #' "x", "y", "xy" (both axis are in logarithmic scaling). - log = "", - - #' @field title Title of the plot. If the value is an empty string, no title is added. Otherwise, the title appears on top of the plot. - title = "", - - #' @field addLegend Boolean defining if the legend should be added to the plot. If TRUE, - #' a legend will be added for each group and each XYSeries that is not in any group - addLegend = TRUE, - - #' @field legendPosition Position of the legend in the plot. Default value is "topright". See [legend()] for more information. - legendPosition = "topright", - - #' @description Add simulated results to the data mapping - #' @param paths A string or a list of strings representing the path(s) to the output(s) in the model. - #' @param simulationResults Simulated results as returned by `runSimulation` - #' @param labels A string or a list of strings that are used as a label (e.g. in the legend) for the output(s). - #' If `NULL` (default), the path of the output is used as a label. - #' @param groups A string or a list of strings assigning the outputs to a group. All outputs may be assigned to one group, or to - #' different groups, while each output can be assigned to not more than one group. If an entry within the list is NULL, the corresponding - #' output is not assigned to any group - #' @param removeNA If TRUE (default), NA values will be removed from the simulated results. NA values can be the result of observer not being calculated at a certain time point. - #' @description - #' Add new `ModelOutput` to be plotted. Line type is set to "l" (line) by default. - addModelOutputs = function(paths, labels, simulationResults, groups = NULL, removeNA = TRUE) { - # Paths are checked for correct type in ospsuite - validateIsString(labels) - validateIsSameLength(paths, labels) - outputValues <- getOutputValues( - simulationResults = simulationResults, - quantitiesOrPaths = paths, - stopIfNotFound = FALSE - ) - - for (idx in seq_along(paths)) { - yValues <- outputValues$data[[paths[[idx]]]] - # If NULL is returned, the output with the given path could not be found - if (all(is.na(yValues))) { - stop(messages$errorOutputPathNotFound(paths[[idx]])) - } - - xValues <- outputValues$data$Time - # Remove any NA values, is specified. - if (removeNA) { - naVals <- is.na(yValues) - yValues <- yValues[!naVals] - xValues <- xValues[!naVals] - } - # If no label is specified, use output path as label - label <- labels[[idx]] %||% paths[[idx]] - timeValues <- XYData$new(xValues, yValues, label = label) - - self$addXYData( - timeValues, - groups = groups[[idx]] - ) - xySeries <- self$xySeries[[label]] - xySeries$type <- "l" - xySeries$dataType <- XYDataTypes$Simulated - xySeries$yDimension <- outputValues$metaData[[paths[[idx]]]]$dimension - xySeries$yUnit <- outputValues$metaData[[paths[[idx]]]]$unit - # get molecular weight - entity <- getQuantity(path = paths[[idx]], container = simulationResults$simulation) - mw <- NULL - if (entity$quantityType == "Drug") { - mw <- getParameter(path = paste(entity$name, "Molecular weight", sep = "|"), container = simulationResults$simulation, stopIfNotFound = F) - } else if (entity$parentContainer$containerType == "Molecule") { - mw <- getParameter(path = paste(entity$parentContainer$name, "Molecular weight", sep = "|"), container = simulationResults$simulation, stopIfNotFound = F) - } - if (!is.null(mw)) { - xySeries$MW <- toDisplayUnit(quantity = mw, values = mw$value) - } - } - - invisible(self) - }, - - #' @description Add `XYData` object(s). - #' - #' @param xValsList A single array or a list of arrays of x-values. For time series, the values must be in minutes. - #' @param yValsList A single array or a list of arrays of y-values. - #' @param yErrorList A single array or a list of arrays of y-error values. If `NULL` (default), no errors are - #' assigned. If not `NULL`, the list must have the same number of entries (numerical arrays) as `yValsList`. If an entry of the list is `NULL`, the respective data set has no error. - #' @param labels A string or a list of strings that are used as unique label for the output(s). Must be of same length as `xValsList`. - #' @param groups A string or a list of strings assigning the data set to a group. If an entry within the list is `NULL`, the corresponding data set is not assigned to any group. If `NULL` (default), all data sets are not assigned to any group. If provided, `groups` must have the same length as `xValsList` - #' - #' @details - #' Add new series of x-y values to be plotted. If an `XYData` with the same label already exists, - #' it will be overwritten - #' @export - #' - #' @examples - #' dataMapping <- DataMapping$new() - #' xVals <- list(c(1, 2, 3, 4), c(1, 2, 3, 4), c(2, 3, 4, 5)) - #' yVals <- list(c(5, 6, 7, 8), c(5, 6, 7, 8), c(6, 7, 8, 9)) - #' yErr <- list(c(0.1, 0.1, 0.1, 0.2), NULL, c(0.2, 0.3, 0.1, 0.2)) - #' groups <- list("Group1", NULL, "Group1") - #' dataMapping$addXYSeries(xValsList = xVals, yValsList = yVals, - #' yErrorList = yErr, labels = list("my series1", "my series2", "my series3"), groups = groups) - addXYSeries = function(xValsList, yValsList, labels, yErrorList = NULL, groups = NULL) { - # Label is validated for string in Plotable - xValsList <- toList(xValsList) - yValsList <- toList(yValsList) - if (!is.null(yErrorList)) { - yErrorList <- toList(yErrorList) - } - if (!is.null(groups)) { - validateIsString(groups, nullAllowed = TRUE) - validateIsSameLength(xValsList, groups) - } - validateIsSameLength(xValsList, yValsList, labels) - - for (idx in seq_along(labels)) { - xyData <- XYData$new(xVals = xValsList[[idx]], yVals = yValsList[[idx]], yError = yErrorList[[idx]], label = labels[[idx]]) - group <- groups[[idx]] - self$addXYData(xyData, group) - } - invisible(self) - }, - - - #' @description Add `XYData` object(s). The objects are cloned at adding. - #' - #' @param XYData Object or a list of objects of the type `XYData` - #' @param groups A string or a list of strings assigning the data set to a group. If an entry within the list is `NULL`, the corresponding data set is not assigned to any group. If `NULL` (default), all data sets are not assigned to any group. If provided, `groups` must have the same length as `XYData` - #' output is not assigned to any group - #' @export - addXYData = function(XYData, groups = NULL) { - validateIsOfType(XYData, "XYData") - XYData <- toList(XYData) - if (!is.null(groups)) { - groups <- c(groups) - validateIsSameLength(XYData, groups) - } - for (idx in seq_along(XYData)) { - newGroupName <- groups[[idx]] - # NULL is converted to NA as NULL cannot be put into a list. - if (is.null(newGroupName)) { - newGroupName <- NA - } - label <- XYData[[idx]]$label - # clone the object and add it - timeValuesClone <- XYData[[idx]]$clone() - - private$.xySeries[[label]] <- timeValuesClone - # If an entry with the given label already exists in the DataMapping (i.e., it will be overwritten), - # check if the group has changed. In no, do nothing. If yes, remove the label - # from the old group and add to the new. - if (hash::has.key(key = label, hash = private$.xySeriesGroupMap)) { - if (compareWithNA(private$.xySeriesGroupMap[[label]], newGroupName)) { - next - } - private$.removeLabelFromGroup( - label = label, - group = private$.xySeriesGroupMap[[label]] - ) - } - # Now assign the entry to the new group - # If no group is specified, add the entry to the empty grouping - if (is.na(newGroupName)) { - private$.xySeriesGroupMap[[label]] <- newGroupName - private$.emptyGrouping <- append(private$.emptyGrouping, label) - next - } - # If a group with the given name already exists, put the entry into it - if (hash::has.key(key = newGroupName, hash = private$.groupings)) { - private$.groupings[[newGroupName]] <- append(private$.groupings[[newGroupName]], label) - private$.xySeriesGroupMap[[label]] <- newGroupName - next - } - # Create a new group and put the entry into - private$.groupings[[newGroupName]] <- label - private$.xySeriesGroupMap[[label]] <- newGroupName - } - }, - - #' @description Add `DataSet` object(s). - #' @details The objects are transformed to `XYData` before adding. - #' - #' @param dataSets Object or a list of objects of the type `DataSet` - #' @param groups A string or a list of strings assigning the data set to a group. If an entry within the list is `NULL`, the corresponding data set is not assigned to any group. If `NULL` (default), all data sets are not assigned to any group. If provided, `groups` must have the same length as `dataSets` - #' output is not assigned to any group - #' @export - addDataSets = function(dataSets, groups = NULL) { - validateIsOfType(dataSets, "DataSet") - dataSets <- toList(dataSets) - xyDataList <- vector("list", length = length(dataSets)) - for (idx in seq_along(dataSets)) { - dataSet <- dataSets[[idx]] - label <- dataSet$name - # Create a `XYData` object from `DataSet` - xyData <- XYData$new(xVals = dataSet$xValues, yVals = dataSet$yValues, yError = dataSet$yErrorValues, label = label) - xyData$dataType <- XYDataTypes$Observed - xyData$MW <- dataSet$molWeight - xyData$xDimension <- dataSet$xDimension - xyData$xUnit <- dataSet$xUnit - xyData$yDimension <- dataSet$yDimension - xyData$yUnit <- dataSet$yUnit - # In `DataSet`, yErrorUnit is `NULL` if no error is defined. In `XYData`, - # there is always a unit of the error (which is by default set to the base - # unit of the y dimension). - if (!is.null(dataSet$yErrorUnit)) { - xyData$yErrorUnit <- dataSet$yErrorUnit - } - # Set meta data - for (metaDataIdx in seq_along(dataSet$metaData)) { - xyData$setMetaData(names(dataSet$metaData)[[metaDataIdx]], dataSet$metaData[[metaDataIdx]]) - } - xyDataList[[idx]] <- xyData - } - self$addXYData(xyDataList, groups) - }, - - #' @param label label of the x-y values series to be removed - #' @description - #' Remove the observed data with given label from the DataMapping. - removeXYSeries = function(label) { - # If no entry with the given label exists, show a warning and do nothing. - if (!hash::has.key(key = label, hash = private$.xySeries)) { - warning(messages$warningLabelNotInDataMapping(label)) - return(invisible(self)) - } - hash::del(x = label, hash = private$.xySeries) - - private$.removeLabelFromGroup( - label = label, - group = private$.xySeriesGroupMap[[label]] - ) - hash::del(x = label, hash = private$.xySeriesGroupMap) - invisible(self) - }, - - #' @description Return group mapping of labels. - #' @details Returns a named list with keys being labels of xySeries and values group names. If value is `NA`, no group is defined for this label. - #' @return A named list with keys being labels of xySeries and values group names. - #' @export - getXYSeriesGroupMap = function() { - return(as.list(private$.xySeriesGroupMap)) - }, - - #' @description Set the X-factors of x-y values by labels. - #' @details If the data set with a label is not present in the mapping, the label is ignored. - #' - #' @param labels A list of labels of `XYData`. - #' @param xFactors Numeric values that will be multiplied by the x-values during plotting. - setXFactors = function(labels, xFactors) { - validateIsString(labels, nullAllowed = TRUE) - validateIsNumeric(xFactors, nullAllowed = TRUE) - validateIsSameLength(labels, xFactors) - - for (idx in seq_along(labels)) { - xySeries <- self$xySeries[[labels[[idx]]]] - xySeries$xFactor <- xFactors[[idx]] - } - - invisible(self) - }, - - #' @description Set the y-factors of x-y values by labels. - #' @details If the data set with a label is not present in the mapping, the label is ignored - #' - #' @param labels A list of label of `XYData` - #' @param yFactors Numeric values that will be multiplied by the y-values during plotting - setYFactors = function(labels, yFactors) { - validateIsString(labels, nullAllowed = TRUE) - validateIsNumeric(yFactors, nullAllowed = TRUE) - validateIsSameLength(labels, yFactors) - - for (idx in seq_along(labels)) { - xySeries <- self$xySeries[[labels[[idx]]]] - xySeries$yFactor <- yFactors[[idx]] - } - - invisible(self) - }, - - #' @description Set the X-offset of x-y values by labels. - #' @details If the data set with a label is not present in the mapping, the label is ignored - #' - #' @param labels A list of label of `XYData` - #' @param xOffsets Numeric values that will be added to the x-values during plotting - setXOffsets = function(labels, xOffsets) { - validateIsString(labels, nullAllowed = TRUE) - validateIsNumeric(xOffsets, nullAllowed = TRUE) - validateIsSameLength(labels, xOffsets) - - for (idx in seq_along(labels)) { - xySeries <- self$xySeries[[labels[[idx]]]] - xySeries$xOffset <- xOffsets[[idx]] - } - - invisible(self) - }, - - #' @description Set the Y-offset of x-y values by labels. - #' @details If the data set with a label is not present in the mapping, the label is ignored - #' - #' @param labels A list of label of `XYData` - #' @param yOffsets Numeric values that will be added to the y-values during plotting - setYOffsets = function(labels, yOffsets) { - validateIsString(labels, nullAllowed = TRUE) - validateIsNumeric(yOffsets, nullAllowed = TRUE) - validateIsSameLength(labels, yOffsets) - - for (idx in seq_along(labels)) { - xySeries <- self$xySeries[[labels[[idx]]]] - xySeries$yOffset <- yOffsets[[idx]] - } - - invisible(self) - }, - - #' @description Set the type(s) of the data to be plotted, e.g. line, points, etc. - #' @details If no data set for the provided label is present in the mapping, the corresponding value is ignored. - #' No check is performed whether a valid type is provided. - #' - #' @param labels A list of label of `XYData` - #' @param types Plot types as accepted by the base `plot` method - setTypes = function(labels, types) { - validateIsString(c(labels, types), nullAllowed = TRUE) - validateIsSameLength(labels, types) - - for (idx in seq_along(labels)) { - xySeries <- self$xySeries[[labels[[idx]]]] - xySeries$type <- types[[idx]] - } - - invisible(self) - }, - - #' @description Set the line type(s) property of the data to be plotted. Line types as accepted by the base `plot` lty argument. - #' @details If no data set for the provided label is present in the mapping, the corresponding value is ignored. - #' No check is performed whether a valid type is provided.Line types as accepted by the base `plot` lty argument. - #' Line types can be provided either as numeric or as character vectors (e.g. "dashed"). - #' - #' @param labels A list of label of `XYData` - #' @param linetypes Values that will be set as line type(s). - setLinetypes = function(labels, linetypes) { - validateIsString(labels, nullAllowed = TRUE) - validateIsSameLength(labels, linetypes) - - for (idx in seq_along(labels)) { - xySeries <- self$xySeries[[labels[[idx]]]] - xySeries$lty <- linetypes[[idx]] - } - - invisible(self) - }, - - #' @description Set the colors of the data to be plotted - #' @details If the data set with a label is not present in the mapping, the label is ignored - #' - #' @param labels A list of label of `XYData` - #' @param colors String names of colors of the data as accepted by the base `plot` method - #' If the value is `NULL`, the color is automatically selected when plotting the data. - setColors = function(labels, colors) { - validateIsString(c(labels), nullAllowed = TRUE) - # If the color is a single NULL, put it into a list - if (is.null(colors)) { - colors <- list(NULL) - } - validateIsSameLength(labels, colors) - - for (idx in seq_along(labels)) { - xySeries <- self$xySeries[[labels[[idx]]]] - xySeries$color <- colors[[idx]] - } - - invisible(self) - }, - - #' @description Apply settings stored in a `DataMappingConfiguration` - #' @details If the data set with a label is not present in the mapping, the label is ignored - #' Equivalent to calling `setXFactors`, `setYFactors`, `setXOffsets`, - #' `setYOffsets`, `setTypes`, and `setColors`. - #' - #' @param dataMappingConfiguration An object of type `DataMappingConfiguration` - setConfiguration = function(dataMappingConfiguration) { - self$setXFactors(names(dataMappingConfiguration$xFactors), dataMappingConfiguration$xFactors) - self$setYFactors(names(dataMappingConfiguration$yFactors), dataMappingConfiguration$yFactors) - self$setXOffsets(names(dataMappingConfiguration$xOffsets), dataMappingConfiguration$xOffsets) - self$setYOffsets(names(dataMappingConfiguration$yOffsets), dataMappingConfiguration$yOffsets) - self$setTypes(names(dataMappingConfiguration$lineTypes), dataMappingConfiguration$lineTypes) - self$setColors(names(dataMappingConfiguration$colors), dataMappingConfiguration$colors) - - invisible(self) - }, - - #' @description Plot the data stored in this `DataMapping`. - #' @param ... Any parameter that can be interpreted by the default [plot()] function - plot = function(...) { - # Get the function by its name - fun <- get(x = paste0("plot", self$plotType)) - fun(self, ...) - - invisible(self) - }, - - #' @description - #' Print the object to the console - #' @param ... Rest arguments. - print = function(...) { - private$printClass() - private$printLine("Plot type", self$plotType) - private$printLine("Population quantiles", self$populationQuantiles) - private$printLine("labels", hash::keys(private$.xySeries)) - private$printLine("X limits", self$xLim) - private$printLine("Y limits", self$yLim) - private$printLine("X label", self$xLab) - private$printLine("Y label", self$yLab) - private$printLine("X unit", self$xUnit) - private$printLine("Y unit", self$yUnit) - private$printLine("Title", self$title) - private$printLine("Log axes", self$log) - invisible(self) - } - ) -) diff --git a/R/DataMappingConfiguration.R b/R/DataMappingConfiguration.R deleted file mode 100644 index b8998068..00000000 --- a/R/DataMappingConfiguration.R +++ /dev/null @@ -1,175 +0,0 @@ -#' @title DataMappingConfiguration -#' @docType class -#' @description An object storing configuration of a data mapping -#' @export -#' @import hash -#' @format NULL -DataMappingConfiguration <- R6::R6Class( - "DataMappingConfiguration", - inherit = Printable, - cloneable = FALSE, - active = list( - #' @field xFactors A named list listing numerical values that x-values are - #' multiplied by. Keys are names of data sets, values are numerical - #' factors. - xFactors = function(value) { - if (missing(value)) { - as.list(private$.xFactors) - } else { - stop(messages$errorPropertyReadOnly("xFactors", optionalMessage = "Use function 'setXFactors' to set the values.")) - } - }, - #' @field yFactors A named list listing numerical values that y-values are multiplied by. Keys are names of data sets, - #' values are numerical factors. - yFactors = function(value) { - if (missing(value)) { - as.list(private$.yFactors) - } else { - stop(messages$errorPropertyReadOnly("yFactors", optionalMessage = "Use function 'setYFactors' to set the values.")) - } - }, - #' @field xOffsets A named list listing numerical values that will be added - #' to the x-values. Keys are names of data sets, values are numerical - #' values - xOffsets = function(value) { - if (missing(value)) { - as.list(private$.xOffsets) - } else { - stop(messages$errorPropertyReadOnly("xOffsets", optionalMessage = "Use function 'setXOffsets' to set the values.")) - } - }, - #' @field yOffsets A named list listing numerical values that will be added - #' to the y-values. Keys are names of data sets, values are numerical - #' values - yOffsets = function(value) { - if (missing(value)) { - as.list(private$.yOffsets) - } else { - stop(messages$errorPropertyReadOnly("yOffsets", optionalMessage = "Use function 'setYOffsets' to set the values.")) - } - }, - #' @field lineTypes A named list listing line types that will be used to - #' plot a certain data set. Keys are names of data sets, values are - #' numerical values recognized by the `lty` argument of the [plot()] - #' function - lineTypes = function(value) { - if (missing(value)) { - as.list(private$.lineTypes) - } else { - stop(messages$errorPropertyReadOnly("lineTypes", optionalMessage = "Use function 'setLineTypes' to set the values.")) - } - }, - #' @field colors A named list listing color values that will be used to plot - #' a certain data set. Keys are names of data sets, values are values - #' recognized by the `col` argument of the [plot()] function - colors = function(value) { - if (missing(value)) { - as.list(private$.colors) - } else { - stop(messages$errorPropertyReadOnly("colors", optionalMessage = "Use function 'setColors' to set the values.")) - } - } - ), - private = list( - .xFactors = NULL, - .yFactors = NULL, - .xOffsets = NULL, - .yOffsets = NULL, - .lineTypes = NULL, - .colors = NULL - ), - public = list( - #' @description - #' Initialize a new instance of the class - #' @return A new `DataMappingConfiguration` object. - initialize = function() { - private$.xFactors <- hash::hash() - private$.yFactors <- hash::hash() - private$.xOffsets <- hash::hash() - private$.yOffsets <- hash::hash() - private$.lineTypes <- hash::hash() - private$.colors <- hash::hash() - }, - #' @description - #' Clean up upon object removal - finalize = function() { - hash::clear(private$.xFactors) - hash::clear(private$.yFactors) - hash::clear(private$.xOffsets) - hash::clear(private$.yOffsets) - hash::clear(private$.lineTypes) - hash::clear(private$.colors) - }, - - #' @description Set the values of x-factors. An x-factor will be multiplied - #' by the x-values of the data set. - #' @param labels A string or a list of strings representing the names of the - #' data sets - #' @param xFactors A numerical value or a list of numerical values - #' representing the x-factors. Both lists must be of same length and store - #' the entries in the same order. - setXFactors = function(labels, xFactors) { - validateIsSameLength(labels, xFactors) - private$.xFactors[labels] <- xFactors - }, - #' @description Set the values of y-factors. A y-factor will be multiplied - #' by the y-values of the data set. - #' @param labels A string or a list of strings representing the names of the - #' data sets - #' @param yFactors A numerical value or a list of numerical values - #' representing the y-factors. Both lists must be of same length - #' and store the entries in the same order. - setYFactors = function(labels, yFactors) { - validateIsSameLength(labels, yFactors) - private$.yFactors[labels] <- yFactors - }, - #' @description Set the values of x-offsets. An x-offset will be added to - #' the the x-values of the data set. - #' @param labels A string or a list of strings representing the names of the - #' data sets - #' @param xOffsets A numerical value or a list of numerical values - #' representing the x-offsets. Both lists must be of same length and store - #' the entries in the same order. - setXOffsets = function(labels, xOffsets) { - validateIsSameLength(labels, xOffsets) - private$.xOffsets[labels] <- xOffsets - }, - #' @description Set the values of y-offsets. A y-offset will be added to the - #' the y-values of the data set. - #' @param labels A string or a list of strings representing the names of the - #' data sets - #' @param yOffsets A numerical value or a list of numerical values - #' representing the y-offsets. Both lists must be of same length and store - #' the entries in the same order. - setYOffsets = function(labels, yOffsets) { - validateIsSameLength(labels, yOffsets) - private$.yOffsets[labels] <- yOffsets - }, - #' @description Set the colors that will be used to plot a certain data set. - #' @param labels A string or a list of strings representing the names of the - #' data sets - #' @param colors Values representing a color recognized by the `col` - #' argument of the [plot()] function - setColors = function(labels, colors) { - validateIsSameLength(labels, colors) - private$.colors[labels] <- colors - }, - #' @description Set the line types that will be used to plot a certain data set. - #' @param labels A string or a list of strings representing the names of the - #' data sets - #' @param lineTypes Values recognized by the `col` argument of the [plot()] - #' function - setLineTypes = function(labels, lineTypes) { - validateIsSameLength(labels, lineTypes) - private$.lineTypes[labels] <- lineTypes - }, - - #' @description - #' Print the object to the console - #' @param ... Rest arguments. - print = function(...) { - private$printClass() - invisible(self) - } - ) -) diff --git a/R/PlotConfiguration.R b/R/PlotConfiguration.R deleted file mode 100644 index 16a8fe1e..00000000 --- a/R/PlotConfiguration.R +++ /dev/null @@ -1,63 +0,0 @@ -#' @title PlotConfiguration -#' @docType class -#' @description An object storing configuration of a plot -#' @export -#' @format NULL -PlotConfiguration <- R6::R6Class( - "PlotConfiguration", - inherit = Printable, - cloneable = FALSE, - active = list(), - private = list(), - public = list( - #' @description - #' Initialize a new instance of the class - #' @return A new `PlotConfiguration` object. - initialize = function() { - - }, - #' @field outputDevice Output target of the plot. If NULL (default), the figure is created in the default "plot" - #' output. Other values indicate output into a file. A list of supported outputs is provided in `GraphicsDevices`-enum. - outputDevice = NULL, - #' @field outputName A string used as the name of the .png file and as the title of the plot - outputName = "", - #' @field outputFolder Path to the directory where the outputs should be stored. - outputFolder = NULL, - #' @field width Width of the resulting plot in cm. If NULL (default), the width is automatically calculated - #' using the value esqlabsEnv$widthPerPlotMapping - width = NULL, - #' @field height Height of the resulting plot in cm. If `NULL` (default), the - #' height is automatically calculated - #' using the value esqlabsEnv$heightPerPlotMapping - height = NULL, - #' @field nrOfCols Number of column in a multi-panel plot. If `NULL` - #' (default), the number is calculated automatically to fit all panels - #' while trying to keep the number of columns and rows equal. If `nrOfCols` - #' is specified, the number of rows calculated to fit all the panels. - nrOfCols = NULL, - #' @field res Resolution of the .png output in dpi. Default is 600. - res = 600, - #' @field pointsize Size of the plotted text. Default is 8. - pointsize = 8, - #' @field addTitle Boolean flag if the title should be added. If TRUE, - #' `outputName` is added a title. - addTitle = TRUE, - - #' @description - #' Print the object to the console - #' @param ... Rest arguments. - print = function(...) { - private$printClass() - private$printLine("Output device", self$outputDevice) - private$printLine("Output name", self$outputName) - private$printLine("Output path", self$outputPath) - private$printLine("Width", self$width) - private$printLine("Height", self$height) - private$printLine("Number of columns", self$nrOfCols) - private$printLine("Resulution", self$res) - private$printLine("Point size", self$pointsize) - private$printLine("addTitle", self$addTitle) - invisible(self) - } - ) -) diff --git a/R/Plotable.R b/R/Plotable.R deleted file mode 100644 index a377fff5..00000000 --- a/R/Plotable.R +++ /dev/null @@ -1,69 +0,0 @@ -#' @title Plotable -#' @docType class -#' @description An object holding plotting information -#' @import ospsuite -#' @format NULL -Plotable <- R6::R6Class( - "Plotable", - inherit = Printable, - cloneable = FALSE, - active = list(), - private = list(), - public = list( - #' @description - #' Initialize a new instance of the class - #' @param label A string that is used as a label (e.g. in the legend) for the data set - #' @return A new `Plotable` object. - initialize = function(label) { - validateIsString(label) - - self$label <- label - }, - #' @field label A string that is used as a label (e.g. in the legend) for the data set - #' that will be plotted - label = NULL, - - #' @field color Color that will be used when plotting the output. Represented as a array - #' of three HSV values. - #' @seealso col2hsv - color = NULL, - - #' @field xFactor Numeric value the x-values will be multiplied by. - xFactor = 1, - - #' @field yFactor Numeric value the y-values will be multiplied by. - yFactor = 1, - - #' @field xOffset A value that is added to all x-values when plotting - xOffset = 0, - - #' @field yOffset A value that is added to all y-values when plotting - yOffset = 0, - - #' @field type "p" for points, "l" for line, or "pl" for both - type = "p", - - #' @field pch Either an integer specifying a symbol or a single character to be used as the default in plotting points. See `par` for more information. - pch = NULL, - - #' @field lty The line type. See `par` for more information. - lty = NULL, - - #' @description - #' Print the object to the console - #' @param ... Rest arguments. - print = function(...) { - private$printClass() - private$printLine("label", self$label) - private$printLine("x factor", self$xFactor) - private$printLine("y factor", self$yFactor) - private$printLine("x offset", self$xOffset) - private$printLine("y offset", self$yOffset) - private$printLine("Color", self$color) - private$printLine("Type", self$type) - private$printLine("pch", self$pch) - private$printLine("lty", self$lty) - invisible(self) - } - ) -) diff --git a/R/XYData.R b/R/XYData.R deleted file mode 100644 index ae692524..00000000 --- a/R/XYData.R +++ /dev/null @@ -1,357 +0,0 @@ -#' @title XYData -#' @docType class -#' @description A set of x and y value pairs -#' -#' @import ospsuite.utils -#' -#' @export -#' @format NULL -XYData <- R6::R6Class( - "XYData", - inherit = Plotable, - active = list( - #' @field xValues An array of x-values. For time series, the values must be - #' in minutes. - xValues = function(value) { - if (missing(value)) { - private$.xVals - } else { - validateIsNumeric(value) - validateIsSameLength(value, private$.yVals) - private$.xVals <- value - } - }, - - #' @field yValues An array of y-values. - yValues = function(value) { - if (missing(value)) { - private$.yVals - } else { - validateIsNumeric(value) - validateIsSameLength(value, private$.xVals) - private$.yVals <- value - } - }, - - #' @field yError An array of arithmetic error of the y-values. Only positive - #' values are allowed - yError = function(value) { - if (missing(value)) { - private$.yError - } else { - validateIsNumeric(value, nullAllowed = TRUE) - if (!is.null(value)) { - validateIsSameLength(private$.yVals, value) - # Replace all NAs with 0 - value[is.na(value)] <- 0 - # Check if all values are positive - if (!all(value >= 0)) { - stop(messages$errorValuesAreNotPositive(values = value)) - } - private$.yError <- value - } - } - }, - - #' @field xMax Maximal value of x values plus xOffset multiplied by the - #' scaling factor - xMax = function(value) { - if (missing(value)) { - max(private$.xVals + self$xOffset) * self$xFactor - } else { - stop(messages$errorPropertyReadOnly("xMax")) - } - }, - - #' @field xMin Minimal value of x values plus xOffset multiplied by the - #' scaling factor - xMin = function(value) { - if (missing(value)) { - min(private$.xVals + self$xOffset) * self$xFactor - } else { - stop(messages$errorPropertyReadOnly("xMin")) - } - }, - - #' @field yMax Maximal value (plus error, if specified) of y values plus - #' yOffset multiplied by the scaling factor - yMax = function(value) { - if (missing(value)) { - max((private$.yVals + self$yOffset) * self$yFactor + (self$yErrorProcessed(self$yUnit) %||% 0)) - } else { - stop(messages$errorPropertyReadOnly("yMax")) - } - }, - - #' @field yMin Minimal value (minus error, if specified) of y values plus - #' yOffset multiplied by the scaling factor - yMin = function(value) { - if (missing(value)) { - # As the error can be specified in another unit, it has to bo converted to the unit of y values first - min((private$.yVals + self$yOffset) * self$yFactor - (self$yErrorProcessed(self$yUnit) %||% 0)) - } else { - stop(messages$errorPropertyReadOnly("yMin")) - } - }, - - #' @field dataType Type of the data. See enum `XYDataTypes` for the list of - #' supported types. - dataType = function(value) { - if (missing(value)) { - private$.dataType - } else { - validateEnumValue(enum = XYDataTypes, value) - private$.dataType <- value - } - }, - - #' @field xDimension Dimension of x values. See enum `ospDimensions` for the - #' list of supported dimensions. - xDimension = function(value) { - if (missing(value)) { - private$.xDimension - } else { - validateDimension(value) - private$.xDimension <- value - private$.xUnit <- getBaseUnit(value) - } - }, - - #' @field xUnit Unit of x values - xUnit = function(value) { - if (missing(value)) { - private$.xUnit - } else { - validateUnit(value, self$xDimension) - private$.xUnit <- value - } - }, - - #' @field yDimension Dimension of y values. See enum `ospDimensions` for the - #' list of supported dimensions. - yDimension = function(value) { - if (missing(value)) { - private$.yDimension - } else { - validateDimension(value) - private$.yDimension <- value - private$.yUnit <- getBaseUnit(value) - private$.yErrorUnit <- getBaseUnit(value) - } - }, - - #' @field yUnit Unit of y values - yUnit = function(value) { - if (missing(value)) { - private$.yUnit - } else { - validateUnit(value, self$yDimension) - private$.yUnit <- value - } - }, - - #' @field yErrorUnit Unit of y error values - yErrorUnit = function(value) { - if (missing(value)) { - private$.yErrorUnit - } else { - # Dimensionless is always supported as it represents the geometric error. - if (value == "") { - private$.yErrorUnit <- value - } else { - validateUnit(value, self$yDimension) - private$.yErrorUnit <- value - } - } - }, - - #' @field MW Molecular weight in g/mol. Required for conversion between - #' molar and mass dimensions. Can be `NULL` (default) - MW = function(value) { - if (missing(value)) { - private$.MW - } else { - validateIsNumeric(value) - private$.MW <- value - } - } - ), - private = list( - .xVals = NULL, - .yVals = NULL, - .yError = NULL, - .dataType = NULL, - .xDimension = NULL, - .xUnit = NULL, - .yDimension = NULL, - .yUnit = NULL, - .yErrorUnit = NULL, - .MW = NULL, - .metaData = list() - ), - public = list( - #' @param xVals An array of numeric x values. - #' @param yVals An array of numeric y values, - #' @param yError An array of numeric values of the arithmetic error. Optional - #' @param label A string that is used as a label (e.g. in the legend) for the data set - #' @description Initialize a new instance of the class. xVals, yVals, and - #' yError (optional) must be of the same length - #' @return A new `XYData` object. - initialize = function(xVals, yVals, label, yError = NULL) { - validateIsNumeric(c(xVals, yVals)) - validateIsNumeric(yError, nullAllowed = TRUE) - validateIsSameLength(xVals, yVals) - - super$initialize(label) - private$.xVals <- xVals - private$.yVals <- yVals - if (!is.null(yError)) { - validateIsSameLength(yVals, yError) - # Replace all NAs with 0 - yError[is.na(yError)] <- 0 - self$yError <- yError - } - private$.dataType <- XYDataTypes$Unspecified - - self$xDimension <- ospDimensions$Time - self$yDimension <- ospDimensions$Dimensionless - }, - - #' @description Returns the minimal value (minus error, if specified) of the y series that is not negative or null - #' @return The minimal non-negative value of the y series minus error, if - #' specified, plus yOffset multiplied by the scaling factor If no such - #' value exists, returns Inf. - yMinPositive = function() { - effectiveVals <- private$.yVals + self$yOffset - (private$.yError %||% 0) - min(effectiveVals[effectiveVals > 0]) * self$yFactor - }, - - #' @description - #' x values with all conversions applied. - #' - #' @param unit Target unit. If `NULL` (default), no conversion between units - #' is applied. - #' - #' @return Raw xValues plus xOffset multiplied by xFactor and converted to a - #' specified unit. It is assumed that raw xValues are in `xUnit`. - xValuesProcessed = function(unit = NULL) { - # Add offset and multiply by the factor. The values are in the unit of XYData - valuesProcessed <- (private$.xVals + self$xOffset) * self$xFactor - - # If a unit is passed and is different from the current unit, convert to unit - if (!is.null(unit) && unit != private$.xUnit) { - return(toUnit( - quantityOrDimension = private$.xDimension, - values = valuesProcessed, - targetUnit = unit, - sourceUnit = private$.xUnit - )) - } - # Otherwise return without conversion to unit - return(valuesProcessed) - }, - - #' @description - #' y values with all conversions applied. - #' - #' @param unit Target unit. If `NULL` (default), no conversion between units - #' is applied. - #' - #' @return Raw yValues plus yOffset multiplied by yFactor and converted to a - #' specified unit. - #' It is assumed that raw yValues are in `yUnit`. - yValuesProcessed = function(unit = NULL) { - # Add offset and multiply by the factor. The values are in the unit of XYData - valuesProcessed <- (private$.yVals + self$yOffset) * self$yFactor - - # If a unit is passed and is different from the current unit, convert to unit - if (!is.null(unit) && unit != private$.yUnit) { - return(toUnit( - quantityOrDimension = private$.yDimension, - values = valuesProcessed, - targetUnit = unit, - sourceUnit = private$.yUnit, - molWeight = private$.MW, - molWeightUnit = ospUnits$`Molecular weight`$`g/mol` - )) - } - # Otherwise return without conversion to unit - return(valuesProcessed) - }, - - #' @description - #' y error values with all conversions applied. - #' - #' @param unit Target unit. If `NULL` (default), the no conversion between - #' units is applied. - #' - #' @return Raw yError multiplied by yFactor and converted to a specified - #' unit. It is assumed that raw yError are in `yUnit`. If no error is - #' specified, `NULL` is returned. - yErrorProcessed = function(unit = NULL) { - if (is.null(private$.yError)) { - return(NULL) - } - - # Add offset and multiply by the factor. The values are in the unit of XYData - valuesProcessed <- private$.yError * self$yFactor - - # If a unit is passed and is different from the current unit, convert to unit - if (!is.null(unit) && unit != private$.yErrorUnit) { - return(toUnit( - quantityOrDimension = private$.yDimension, - values = valuesProcessed, - targetUnit = unit, - sourceUnit = private$.yErrorUnit, - molWeight = private$.MW, - molWeightUnit = ospUnits$`Molecular weight`$`g/mol` - )) - } - # Otherwise return without conversion to unit - return(valuesProcessed) - }, - - #' @description - #' Meta data list of `XYData` object - #' @return - #' A named list holding the metadata of this `XYData` - getAllMetaData = function() { - return(private$.metaData) - }, - - #' @description - #' Adds a new entry to meta data list of `XYData` object or changes its - #' value if name is already present in meta data. If only `name` is provided - #' or if `value` is set to NULL, entry with corresponding name is deleted - #' from meta data. - #' - #' @param name Name of new meta data list entry - #' @param value Value of new meta data list entry - setMetaData = function(name, value = NULL) { - if (length(name) != 1) { - stop(messages$errorMultipleMetaDataEntries()) - } - - private$.metaData[[name]] <- value - }, - - #' @description Print the object to the console - #' @param ... Rest arguments. - print = function(...) { - super$print() - private$printLine("Data type", c(private$.dataType)) - # private$printLine("X values", c(private$.xVals)) - # private$printLine("Y values", c(private$.yVals)) - private$printLine("X dimension", c(private$.xDimension)) - private$printLine("X unit", c(private$.xUnit)) - private$printLine("Y dimension", c(private$.yDimension)) - private$printLine("Y unit", c(private$.yUnit)) - private$printLine("Y error unit", c(private$.yErrorUnit)) - invisible(self) - } - ) -) - -#' Possible entries for the `dataType` field of a `XYData` object -#' @export -XYDataTypes <- enum(list("Simulated", "Observed", "Unspecified")) diff --git a/R/enum.R b/R/enum.R index ffb23d69..42558cf6 100644 --- a/R/enum.R +++ b/R/enum.R @@ -15,6 +15,7 @@ #' myEnum <- enum(c(a = "b")) #' myEnum <- enumPut("c", "d", myEnum) #' myEnum <- enumPut(c("c", "d", "g"), list(12, 2, "a"), myEnum, overwrite = TRUE) +#' myEnum <- enumPutList("g", list(12, 2, "a"), myEnum, overwrite = TRUE) enumPutList <- function(key, values, enum, overwrite = FALSE) { if (length(key) > 1) { stop(messages$errorEnumPutListMultipleKeys()) diff --git a/R/error-checks.R b/R/error-checks.R index 6e307464..8b137891 100644 --- a/R/error-checks.R +++ b/R/error-checks.R @@ -1,24 +1 @@ -#' Check if the file exists. If not, stop with an error. -#' -#' @param filePath Path to the file -validateFileExists <- function(filePath) { - if (!file.exists(filePath)) { - stop(messages$errorFileNotFound(filePath)) - } -} -#' Check if the provided object is of a certain length. If not, stop with an -#' error. -#' -#' @param object Object which length will be checked -#' @param length Expected length -validateLength <- function(object, length) { - if (length(object) == length) { - return() - } - - # Name of the variable in the calling function - objectName <- deparse(substitute(object)) - - stop(messages$errorWrongLength(objectName, length)) -} diff --git a/R/esqlabs-env.R b/R/esqlabs-env.R index 2959f35a..40757db4 100644 --- a/R/esqlabs-env.R +++ b/R/esqlabs-env.R @@ -1,8 +1,3 @@ -.getPackageVersion <- function() { - version <- getNamespaceVersion("esqlabsR") - return(version) -} - # Environment that holds various global variables and settings for the esqlabsR, # It is not exported and should not be directly manipulated by other packages. esqlabsEnv <- new.env(parent = emptyenv()) @@ -11,7 +6,7 @@ esqlabsEnv <- new.env(parent = emptyenv()) esqlabsEnv$packageName <- "esqlabsR" # Version of the package -esqlabsEnv$packageVersion <- .getPackageVersion() +esqlabsEnv$packageVersion <- getNamespaceVersion("esqlabsR") # Default width of a plot of a single `PlotMapping` esqlabsEnv$widthPerPlotMapping <- 8 @@ -19,15 +14,9 @@ esqlabsEnv$widthPerPlotMapping <- 8 # Default height of a plot of a single `PlotMapping` esqlabsEnv$heightPerPlotMapping <- 8 -# Column names to split observed data by -esqlabsEnv$columnsToSplitDataBy <- c("Group Id", "Gender", "Patient Id", "Dose", "Route", "Molecule", "Organ", "Compartment") - -# Column index for x values in observed data files -esqlabsEnv$XValuesColumn <- 10 -# Column index for y values in observed data files -esqlabsEnv$YValuesColumn <- 11 -# Column index for y error values in observed data files -esqlabsEnv$YErrorColumn <- 12 +#' Names of the settings stored in esqlabsEnv Can be used with `getEsqlabsRSetting()` +#' @export +esqlabsRSettingNames <- enum(names(esqlabsEnv)) #' Get the value of a global esqlabsR setting. #' @@ -39,10 +28,10 @@ esqlabsEnv$YErrorColumn <- 12 #' #' @examples #' getEsqlabsRSetting("packageVersion") -#' getEsqlabsRSetting("widthPerPlotMapping") +#' getEsqlabsRSetting("packageName") getEsqlabsRSetting <- function(settingName) { if (!(any(names(esqlabsEnv) == settingName))) { - stop(messages$errorEsqlabsRSettingNotFound(settingName)) + stop(messages$errorPackageSettingNotFound(settingName, esqlabsEnv)) } obj <- esqlabsEnv[[settingName]] diff --git a/R/messages.R b/R/messages.R index 717a42e0..5fc84e1e 100644 --- a/R/messages.R +++ b/R/messages.R @@ -13,34 +13,10 @@ messages$errorEnumPutListMultipleKeys <- function() { paste0("Trying to put multiple keys, but only one key is allowed!") } -messages$errorFileNotFound <- function(filePath, optionalMessage = NULL) { - paste0("File '", filePath, "' could not be found!") -} - -messages$errorEsqlabsRSettingNotFound <- function(settingName) { - paste0("No global setting with the name '", settingName, "' exists. Available global settings are:\n", paste0(names(esqlabsEnv), collapse = ", ")) -} - messages$errorDistributionNotSupported <- function(string) { paste0("The distribution '", string, "' is not supported. Supported distributions are listed in `Distributions`.") } -messages$errorOutputPathNotFound <- function(string) { - paste0("The output with the path '", string, "' is not found.") -} - -messages$warningLabelNotInDataMapping <- function(string) { - paste0("No xy-series with label ", string, " exists in the DataMapping. Nothing to remove") -} - -messages$errorValuesAreNotPositive <- function(values, optionalMessage = NULL) { - paste("All values must be positive or 0, but they are not! Values are: ", paste(as.character(values), collapse = ", "), optionalMessage) -} - -messages$errorWrongLength <- function(object, length, optionalMessage = NULL) { - paste("Object `", object, "` must be of length ", length, " but it is not!") -} - messages$errorWrongPopulationName <- function(populationName) { paste0("Population name ", populationName, " is not specified in the population file!") } @@ -53,16 +29,12 @@ messages$warningValueWithinThresholdNotExisting <- function(value, threshold, op paste("value `", value, "` not found in the array within the absolute threshold of ", threshold, optionalMessage) } -messages$errorMultipleMetaDataEntries <- function(optionalMessage = NULL) { - paste("Can only set a single meta data entry at once", optionalMessage) -} - messages$errorInvalidMeanMethod <- function() { - paste("Invalid value for argument `method`, supported values are `arithmetic` or `geometric`") + "Invalid value for argument `method`, supported values are `arithmetic` or `geometric`" } messages$errorOutputMolWeightNeeded <- function() { - paste("`outputMolWeight` can not be `NULL` when data sets have different molWeights") + "`outputMolWeight` can not be `NULL` when data sets have different molWeights" } messages$wrongParametersStructure <- function(argumentName) { @@ -75,3 +47,19 @@ messages$wrongParametersStructure <- function(argumentName) { messages$valueShouldNotBeNegative <- function(parameterName, value) { paste0(parameterName, " must be a positive numerical value, but the value is ", value) } + +messages$nrOfColorsShouldBePositive <- function(nrOfColors) { + paste0("nrOfColors must be positive, value ", nrOfColors, " is not valid!") +} + +messages$wrongSimulationType <- function() { + "Wrong value for 'simulationType'! Accepted values are 'Individual and 'Population'" +} + +messages$noPKDataToWrite <- function() { + "`pkDataFilePath` argument is specified, but there is no PK parameters data to write to spreadsheets." +} + +messages$cannotGetMoleculeFromQuantity <- function(quantityPath, optionalMessage = NULL) { + paste0("Could not retrieve molecule name for the quantity with the path '", quantityPath, "'. ", optionalMessage) +} diff --git a/R/ProjectConfiguration.R b/R/project-configuration.R similarity index 91% rename from R/ProjectConfiguration.R rename to R/project-configuration.R index 8325b57d..59c82d98 100644 --- a/R/ProjectConfiguration.R +++ b/R/project-configuration.R @@ -47,6 +47,11 @@ ProjectConfiguration <- R6::R6Class( #' @field outputFolder Path to the folder where the results should be #' saved to; relative to the "Code" folder outputFolder = NULL, + #' @field outputDevice Output target of the plot. If `NULL` (default), the + #' figure is created in the default "plot" output. Other values indicate + #' output into a file. A list of supported outputs is provided in + #' `GraphicsDevices`-enum. + outputDevice = NULL, #' @description #' Print the object to the console @@ -65,6 +70,7 @@ ProjectConfiguration <- R6::R6Class( private$printLine("Experimental data file", self$dataFile) private$printLine("Data importer configuration", self$dataImporterConfigurationFile) private$printLine("Output folder", self$outputFolder) + private$printLine("Output device", self$outputDevice) invisible(self) } ) diff --git a/R/ScenarioConfiguration.R b/R/scenario-configuration.R similarity index 80% rename from R/ScenarioConfiguration.R rename to R/scenario-configuration.R index 0213d5a7..bdd7947e 100644 --- a/R/ScenarioConfiguration.R +++ b/R/scenario-configuration.R @@ -8,8 +8,8 @@ ScenarioConfiguration <- R6::R6Class( inherit = ospsuite.utils::Printable, cloneable = TRUE, active = list( - #' @field setTestParameters Boolean representing whether parameters defined in `TestParameters` are to be applied - #' to the simulation + #' @field setTestParameters Boolean representing whether parameters defined + #' in `TestParameters` are to be applied to the simulation setTestParameters = function(value) { if (missing(value)) { private$.setTestParameters @@ -18,7 +18,8 @@ ScenarioConfiguration <- R6::R6Class( private$.setTestParameters <- value } }, - #' @field simulateSteadyState Boolean representing whether the simulation will be brought to a steady-state first + #' @field simulateSteadyState Boolean representing whether the simulation + #' will be brought to a steady-state first simulateSteadyState = function(value) { if (missing(value)) { private$.simulateSteadyState @@ -27,7 +28,8 @@ ScenarioConfiguration <- R6::R6Class( private$.simulateSteadyState <- value } }, - #' @field simulationTime Boolean representing whether the simulation will be brought to a steady-state first + #' @field simulationTime Simulation time in minutes. If `NULL` (default), + #' simulation time as defined in the `Simulation` object will be used. simulationTime = function(value) { if (missing(value)) { private$.simulationTime @@ -39,7 +41,7 @@ ScenarioConfiguration <- R6::R6Class( private$.simulationTime <- value } }, - #' @field pointsPerMinute Resultion of the ouputs in points per minute + #' @field pointsPerMinute Resolution of the outputs in points per minute pointsPerMinute = function(value) { if (missing(value)) { private$.pointsPerMinute @@ -51,7 +53,7 @@ ScenarioConfiguration <- R6::R6Class( private$.pointsPerMinute <- value } }, - #' @field steadyStateTime Time in minutes to simulate if simulating steady-state. May be NULL + #' @field steadyStateTime Time in minutes to simulate if simulating steady-state. May be `NULL`. steadyStateTime = function(value) { if (missing(value)) { private$.steadyStateTime @@ -63,18 +65,23 @@ ScenarioConfiguration <- R6::R6Class( private$.steadyStateTime <- value } }, - #' @field paramSheets Names of the sheets from the parameters-excel file that will be applied to the simulation + #' @field paramSheets Names of the sheets from the parameters-excel file + #' that will be applied to the simulation paramSheets = function(value) { if (missing(value)) { private$.paramSheets } else { - stop("Field paramSheets is read-only! Use functions 'addParamSheet' and 'removeParamSheet' to add or remove -a parameter sheet from the list") + stop(paste0( + messages$errorPropertyReadOnly("paramSheets"), + ". Use functions 'addParamSheet' and 'removeParamSheet' to add or remove +a parameter sheet from the list" + )) } }, - #' @field simulationType Type of the simulation - "Individual" or "Population". If "Population", population characteristics - #' are created based on information stored in `populationParamsFile`. - #' Default is "Individual" + #' @field simulationType Type of the simulation - "Individual" or + #' "Population". If "Population", population characteristics are created + #' based on information stored in `populationParamsFile`. Default is + #' "Individual" simulationType = function(value) { if (missing(value)) { private$.simulationType @@ -82,7 +89,7 @@ a parameter sheet from the list") if (value %in% c("Individual", "Population")) { private$.simulationType <- value } else { - stop("Wrong value for 'simulationType'! Accepted values are 'Individual and 'Population'") + stop(messages$wrongSimulationType()) } } }, @@ -136,16 +143,18 @@ a parameter sheet from the list") #' @field applicationProtocol Name of the application protocol to be applied. Defined #' in the excel file "ApplicationParameters.xlsx" applicationProtocol = NULL, - #' @field outputDevice Output target of the plot. If `NULL` (default), the figure is created in the default "plot" - #' output. Other values indicate output into a file. A list of supported outputs is provided in `GraphicsDevices`-enum. - outputDevice = NULL, - #' @field individualId Id of the individual. If `NULL` (default), the individual as defined in the simulation file will be simulated. + #' @field individualId Id of the individual as specified in "IndividualParameters.xlsx". + #' If `NULL` (default), the individual as defined in the simulation file will be simulated. individualId = NULL, #' @description Add the names of sheets in the parameters excel-file #' that will be applied to the simulation #' @param sheetNames A name or a list of names of the excel sheet addParamSheets = function(sheetNames) { - private$.paramSheets <- enumPut(sheetNames, sheetNames, enum = private$.paramSheets, overwrite = TRUE) + private$.paramSheets <- enumPut(sheetNames, + sheetNames, + enum = private$.paramSheets, + overwrite = TRUE + ) }, #' @description Remove the names of sheets in the parameters excel-file #' from the list of sheets `paramSheets` @@ -171,7 +180,6 @@ a parameter sheet from the list") private$printLine("Application protocol", self$applicationProtocol) private$printLine("Simulation time", self$simulationTime) private$printLine("Points per minute", self$pointsPerMinute) - private$printLine("Output to PNG", self$outputToPNG) private$printLine("Simulate steady-state", self$simulateSteadyState) private$printLine("Steady-state time", self$steadyStateTime) private$printLine("Set test parameters", self$setTestParameters) diff --git a/R/sensitivityCalculation.R b/R/sensitivity-calculation.R similarity index 86% rename from R/sensitivityCalculation.R rename to R/sensitivity-calculation.R index b6fa7495..8466a314 100644 --- a/R/sensitivityCalculation.R +++ b/R/sensitivity-calculation.R @@ -104,16 +104,21 @@ sensitivityCalculation <- function(simulation, # Initialize `batchResultsIdMap` for the current parameter batchResultsIdMap[[parameterPath]] <- vector("list", length(variationRange)) names(batchResultsIdMap[[parameterPath]]) <- variationRange - - param <- getParameter(parameterPath, simulation) - - if (param$isConstant) { - constantParamPaths <- c(constantParamPaths, parameterPath) - } else { + # Check if the parameter is given by an explicit formula + isExplicitFormulaByPath <- ospsuite::isExplicitFormulaByPath( + path = parameterPath, + simulation = simulation + ) + if (isExplicitFormulaByPath) { formulaParamPaths <- c(formulaParamPaths, parameterPath) + } else { + constantParamPaths <- c(constantParamPaths, parameterPath) } - initialValues[[parameterPath]] <- param$value + initialValues[[parameterPath]] <- ospsuite::getQuantityValuesByPath( + quantityPaths = parameterPath, + simulation = simulation + ) } constantParamPaths <- unlist(constantParamPaths) @@ -166,7 +171,10 @@ sensitivityCalculation <- function(simulation, ) # `runSimulationBatches()` returns a list with one entry per simulation batch. - # + # First remove the names of the upper level of the list to get all result in + # one flat list in the next step but maintain the IDs of the runs + names(simulationBatchesResults) <- NULL + # Unlist so all results are in one list. The names of the results are the IDs # of the runs. Using `batchResultsIdMap`, results for a certain # parameter/scale factor combination can be filtered out. @@ -193,20 +201,25 @@ sensitivityCalculation <- function(simulation, pkData <- dplyr::filter(pkData, PKParameter %in% pkParameters) } - # Write each wide data frame in a list to a separate sheet in Excel + # Write each data frame in a list to a separate sheet in Excel if (!is.null(pkDataFilePath)) { - # Convert tidy data to wide format for each output path - pkData_wide_list <- purrr::map( - .x = pkData %>% split(.$OutputPath), - .f = ~ .convertToWide(.x) - ) - - # The output paths can be quite long and don't make for good sheet names, so - # use `OutputPathXXX` naming pattern for sheets instead. - names(pkData_wide_list) <- paste0("OutputPath", seq(1:length(unique(pkData$OutputPath)))) - - # Write to a spreadsheet with one sheet per output path. - writexl::write_xlsx(pkData_wide_list, pkDataFilePath) + # If there is no data to write to Excel sheet, inform the user and do nothing. + if (nrow(pkData) == 0L) { + warning(messages$noPKDataToWrite()) + } else { + # Convert tidy data to wide format for each output path + pkData_wide_list <- purrr::map( + .x = pkData %>% split(.$OutputPath), + .f = ~ .convertToWide(.x) + ) + + # The output paths can be quite long and don't make for good sheet names, so + # use `OutputPathXXX` naming pattern for sheets instead. + names(pkData_wide_list) <- paste0("OutputPath", seq(1:length(unique(pkData$OutputPath)))) + + # Write to a spreadsheet with one sheet per output path. + writeExcel(data = pkData_wide_list, path = pkDataFilePath) + } } # return `SensitivityCalculation` ------------------------ diff --git a/R/sensitivitySpiderPlot.R b/R/sensitivity-spider-plot.R similarity index 98% rename from R/sensitivitySpiderPlot.R rename to R/sensitivity-spider-plot.R index b5e973b0..1941ef29 100644 --- a/R/sensitivitySpiderPlot.R +++ b/R/sensitivity-spider-plot.R @@ -127,7 +127,7 @@ sensitivitySpiderPlot <- function(sensitivityCalculation, } # print plots without producing warnings - suppressWarnings(purrr::walk2(ls_plots, names(ls_plots), ~ printPlot(.x, .y))) + suppressWarnings(purrr::walk2(ls_plots, names(ls_plots), ~ .printPlot(.x, .y))) } #' @keywords internal diff --git a/R/sensivitityTimeProfiles.R b/R/sensivitity-time-profiles.R similarity index 97% rename from R/sensivitityTimeProfiles.R rename to R/sensivitity-time-profiles.R index 9d8afefe..e6934085 100644 --- a/R/sensivitityTimeProfiles.R +++ b/R/sensivitity-time-profiles.R @@ -115,7 +115,7 @@ sensitivityTimeProfiles <- function(sensitivityCalculation, } # print plots without producing warnings - suppressWarnings(purrr::walk2(ls_plots, names(ls_plots), ~ printPlot(.x, .y))) + suppressWarnings(purrr::walk2(ls_plots, names(ls_plots), ~ .printPlot(.x, .y))) } @@ -179,7 +179,7 @@ sensitivityTimeProfiles <- function(sensitivityCalculation, #' @keywords internal #' @noRd -printPlot <- function(plot, pathName) { +.printPlot <- function(plot, pathName) { print(paste0("Creating plot for path: ", pathName)) print(plot) } diff --git a/R/utilities-data-mapping.R b/R/utilities-data-mapping.R deleted file mode 100644 index 7801c92d..00000000 --- a/R/utilities-data-mapping.R +++ /dev/null @@ -1,561 +0,0 @@ -#' Plot multiple `PlotMapping` in one plot. -#' -#' @param dataMappingList A single or a list of `PlotMapping` objects -#' @param plotConfiguration An object of type `PlotConfiguration` -#' @param ... Any parameter that can be interpreted by the default [plot()] function -#' @export -plotMultiPanel <- function(dataMappingList, plotConfiguration, ...) { - dataMappingList <- toList(dataMappingList) - - nrOfCols <- plotConfiguration$nrOfCols - # If no number of columns provided, calculate the number needed from - # the amount of PlotMappings. Calculated in such way that the numbers of columns - # and rows are as close as possible - if (is.null(nrOfCols)) { - nrOfCols <- ceiling(sqrt(length(dataMappingList))) - } - # Nr of rows is calculated from the number of columns such that all PlotMappings - # can be plottet - nrOfRows <- ceiling(length(dataMappingList) / nrOfCols) - - # If no width and height are provided, automatically calculate based on the number of PlotMappings - width <- plotConfiguration$width %||% esqlabsEnv$widthPerPlotMapping * nrOfCols - height <- plotConfiguration$height %||% esqlabsEnv$heightPerPlotMapping * nrOfRows - - openOuptutDevice(plotConfiguration, width, height) - - split.screen(c(nrOfRows, nrOfCols)) - for (idx in seq_along(dataMappingList)) { - screen(idx) - dataMappingList[[idx]]$plot(cex = 1 - 0.1 * (nrOfRows - 1), ...) - - if (length(dataMappingList) > 1) { - figureAddLabel(letters[[idx]], offset = c(0, -0.1)) - } - } - - if (plotConfiguration$addTitle) { - title(plotConfiguration$outputName, outer = TRUE, line = -1, cex = 1.2) - } - - close.screen(all.screens = TRUE) - - closeOutputDevice(plotConfiguration) -} - -#' Plot XYData -#' -#' @description Draw XYData on top of an existing plot using the `points` method. -#' -#' @param xySeries An `XYData` object to be plotted -#' @param xUnit Target unit of x-axis. -#' @param yUnit Target unit of y-axis. -#' If `TRUE`, -#' @param ... Any parameter that can be interpreted by the default [plot()] function -#' @import ospsuite -#' @keywords internal -plotXYData <- function(xySeries, xUnit = NULL, yUnit = NULL, ...) { - validateIsOfType(xySeries, "XYData") - points(xySeries$xValuesProcessed(xUnit), - xySeries$yValuesProcessed(yUnit), - type = xySeries$type, - lty = xySeries$lty, - pch = xySeries$pch, - col = xySeries$color, - ... - ) - if (!is.null(xySeries$yError)) { - plotErrorBars(xySeries$xValuesProcessed(xUnit), - xySeries$yValuesProcessed(yUnit), - xySeries$yErrorProcessed(yUnit), - col = xySeries$color, - ... - ) - } -} - -#' Plot XYData quantiles -#' -#' @description Draw XYData on top of an existing plot using the `points` method. -#' -#' @param xySeries An `XYData` object to be plotted -#' @inheritParams getQuantilesYData -#' @param xUnit Target unit of x-axis. -#' @param yUnit Target unit of y-axis. -#' @param ... Any parameter that can be interpreted by the default [plot()] function -#' @import ospsuite -#' @export -plotXYDataAggregated <- function(xySeries, xUnit = NULL, yUnit = NULL, - quantiles = c(0.05, 0.5, 0.95), ...) { - validateIsOfType(xySeries, "XYData") - # Get the quantiles for data - lower/mid/upper - aggregatedData <- getQuantilesYData( - xValues = xySeries$xValuesProcessed(xUnit), - yValues = xySeries$yValuesProcessed(yUnit), - quantiles = quantiles - ) - - # Draw the shaded area - polygon(c(aggregatedData[[3]]$xValues, rev(aggregatedData[[1]]$xValues)), - c(aggregatedData[[3]]$yValues, rev(aggregatedData[[1]]$yValues)), - # Add 50% transparency for the color - col = paste0(xySeries$color, "80"), - border = 0 - ) - # Draw the middle quantile line - points(aggregatedData[[2]]$xValues, - aggregatedData[[2]]$yValues, - type = xySeries$type, - lty = xySeries$lty, - pch = xySeries$pch, - col = xySeries$color, - ... - ) -} - -#' Plot individual time-values profile -#' @description Create a 2D-plot of the x-y data sets stored in `dataMapping` -#' -#' @param dataMapping A `DataMapping` object with `XYData` -#' @param ... Any parameter that can be interpreted by the default [plot()] function -plotIndividualProfile <- function(dataMapping, ...) { - plotTimeValues(dataMapping, aggregated = FALSE, ...) -} - -#' Create a box-plot of data -#' -#' @param dataMapping A `DataMapping` object with `XYData` -#' @param ... Any parameter that can be interpreted by the default [boxplot()] function -#' @import ospsuite -#' @export -plotBoxPlot <- function(dataMapping, ...) { - validateIsOfType(dataMapping, "DataMapping") - legendEntries <- vector(mode = "character", length = length(dataMapping$xySeries)) - - allData <- vector(mode = "list", length = length(dataMapping$xySeries)) - for (i in seq_along(dataMapping$xySeries)) { - legendEntries[i] <- paste0(i, ": ", dataMapping$xySeries[[i]]$label) - allData[[i]] <- dataMapping$xySeries[[i]]$yValues - } - - boxplot(allData, - xlab = dataMapping$xLab, - ylab = dataMapping$yLab, - main = dataMapping$title - ) - - # Draw a legend, if specified - if (dataMapping$addLegend) { - .figureAddLegend( - x = dataMapping$legendPosition, - legend = legendEntries, - col = NULL, - pch = NULL, - lty = rep(0, length(legendEntries)), - ... - ) - } -} - -#' Plot individual time-values profile -#' @description Create a 2D-plot of the x-y data sets stored in `dataMapping`. -#' Population simulation results are plotted as quantiles -#' -#' @param dataMapping A `DataMapping` object with `XYData` -#' @param ... Any parameter that can be interpreted by the default [plot()] function -plotPopulationQuantiles <- function(dataMapping, ...) { - plotTimeValues(dataMapping, aggregated = TRUE, ...) -} - -#' Plot time-values profile -#' @description Create a 2D-plot of the x-y data sets stored in `dataMapping` -#' -#' @import ospsuite -#' @param dataMapping A `DataMapping` object with `XYData` -#' @param aggregated Boolean. If `FALSE`, simulation data containing multiple -#' individuals (population simulation) are plotted separately for each -#' individual. If `TRUE`, population simulation results are plotted as -#' mid-percentile and lower/upper percentile bands around. -#' @param ... Any parameter that can be interpreted by the default [plot()] function -#' @import hash -#' @keywords internal -plotTimeValues <- function(dataMapping, aggregated, ...) { - validateIsOfType(dataMapping, "DataMapping") - legendEntries <- c() - legendColors <- c() - legendLty <- c() - legendPch <- c() - - # Count the number of groups plus the number of data sets that are not assigned to any group. - # Based on this number, the colors and other graphics argument values will be defined - nrOfEntries <- length(dataMapping$groupings) + length(dataMapping$ungroupedSeries) - # Generate default values in case specific values for color etc are not set - colors <- esqLABS_colors(nrOfColors = nrOfEntries) - pchArr <- rep(0:24, times = (dataMapping$xySeriesCount %/% 26 + 1)) - ltyArr <- 1:nrOfEntries - graphicsParIdx <- 1 - - # If logarithmic scaling of y-axis has been selected and manually provided y-lim - # is non-positive, use the automatically calculated values - if (isCharInString("y", dataMapping$log) && !all(dataMapping$yLim > 0)) { - dataMapping$yLim <- NULL - } - - # Create an empty plot - # If axis labels have not been set by the user, generate defaults based - # on Dimension and unit - plot(NULL, NULL, - xlim = dataMapping$xLim, - ylim = dataMapping$yLim, - xlab = dataMapping$xLab %||% paste0(dataMapping$xDimension, " [", dataMapping$xUnit, "]"), - ylab = dataMapping$yLab %||% paste0(dataMapping$yDimension, " [", dataMapping$yUnit, "]"), - log = dataMapping$log, - main = dataMapping$title, - ... - ) - - # Add the current data set to the legend. - updateLegend <- function(legendConfiguration) { - legendEntries <<- c(legendEntries, legendConfiguration$legendEntry) - legendColors <<- c(legendColors, legendConfiguration$color) - legendPch <<- c(legendPch, legendConfiguration$pch) - legendLty <<- c(legendLty, legendConfiguration$lty) - } - - pchParIdx <- 0 - for (i in seq_along(dataMapping$groupings)) { - legendConfiguration <- list("legendEntry" = names(dataMapping$groupings)[[i]], "color" = NULL, "pch" = NA, "lty" = 0) - # Plot every entry within the group with the same graphical parameters except for pch - for (j in seq_along(dataMapping$groupings[[i]])) { - pchParIdx <- pchParIdx + 1 - xySeriesEntry <- dataMapping$xySeries[[dataMapping$groupings[[i]][[j]]]] - - # We have to track if any of the graphic parameters for the XYData - # were NULL, so these are reset to NULL after plotting the XYData - resetPch <- FALSE - resetLty <- FALSE - resetColor <- FALSE - - if (is.null(xySeriesEntry$lty)) { - xySeriesEntry$lty <- ltyArr[[graphicsParIdx]] - resetLty <- TRUE - } - if (is.null(xySeriesEntry$pch)) { - xySeriesEntry$pch <- pchArr[[pchParIdx]] - resetPch <- TRUE - } - if (is.null(xySeriesEntry$color)) { - xySeriesEntry$color <- colors[[graphicsParIdx]] - resetColor <- TRUE - } - - legendConfiguration$color <- xySeriesEntry$color - # If symbols are plotted for the data set, set its pch for the legend - if (.isPoint(xySeriesEntry$type)) { - legendConfiguration$pch <- xySeriesEntry$pch - } - # If line is plotted for the data set, set its lty for the legend - if (.isLine(xySeriesEntry$type)) { - legendConfiguration$lty <- xySeriesEntry$lty - } - - # If XYSeriesEntry is simulation data, choose whether to plot individual values - # or aggregated data - if (xySeriesEntry$dataType == XYDataTypes$Simulated && aggregated) { - plotXYDataAggregated( - xySeriesEntry, - dataMapping$xUnit, - dataMapping$yUnit, - quantiles = dataMapping$populationQuantiles, - ... - ) - } else { - plotXYData( - xySeriesEntry, - dataMapping$xUnit, - dataMapping$yUnit, - ... - ) - } - - # Reset the entry's graphics parameters - if (resetPch) { - xySeriesEntry$pch <- NULL - } - if (resetLty) { - xySeriesEntry$lty <- NULL - } - if (resetColor) { - xySeriesEntry$color <- NULL - } - } - updateLegend(legendConfiguration) - graphicsParIdx <- graphicsParIdx + 1 - } - # pchParIdx == 0 is when no grouping exists - if (pchParIdx == 0) { - pchParIdx <- 1 - } - # Process XYData that are in no grouping - for (xySeriesName in dataMapping$ungroupedSeries) { - xySeriesEntry <- dataMapping$xySeries[[xySeriesName]] - # We have to track if any of the graphic parameters for the XYData - # were NULL, so these are reset to NULL after plotting the XYData - resetPch <- FALSE - resetLty <- FALSE - resetColor <- FALSE - - if (is.null(xySeriesEntry$lty)) { - xySeriesEntry$lty <- ltyArr[[graphicsParIdx]] - resetLty <- TRUE - } - if (is.null(xySeriesEntry$pch)) { - xySeriesEntry$pch <- pchArr[[pchParIdx]] - resetPch <- TRUE - } - if (is.null(xySeriesEntry$color)) { - xySeriesEntry$color <- colors[[graphicsParIdx]] - resetColor <- TRUE - } - - legendConfiguration <- list("legendEntry" = xySeriesName, "color" = xySeriesEntry$color, "pch" = NA, "lty" = 0) - # If symbols are plotted for the data set, set its pch for the legend - if (.isPoint(xySeriesEntry$type)) { - legendConfiguration$pch <- xySeriesEntry$pch - } - # If line is plotted for the data set, set its lty for the legend - if (.isLine(xySeriesEntry$type)) { - legendConfiguration$lty <- xySeriesEntry$lty - } - - # If XYSeriesEntry is simulation data, choose whether to plot individual values - # or aggregated data - if (xySeriesEntry$dataType == XYDataTypes$Simulated && aggregated) { - plotXYDataAggregated( - xySeriesEntry, - dataMapping$xUnit, - dataMapping$yUnit, - quantiles = dataMapping$populationQuantiles, - ... - ) - } else { - plotXYData( - xySeriesEntry, - dataMapping$xUnit, - dataMapping$yUnit, - ... - ) - } - updateLegend(legendConfiguration) - - if (resetPch) { - xySeriesEntry$pch <- NULL - } - if (resetLty) { - xySeriesEntry$lty <- NULL - } - if (resetColor) { - xySeriesEntry$color <- NULL - } - - graphicsParIdx <- graphicsParIdx + 1 - pchParIdx <- graphicsParIdx - } - - # Draw a legend, if specified - if (dataMapping$addLegend && (length(legendEntries) > 0)) { - .figureAddLegend( - x = dataMapping$legendPosition, - legend = legendEntries, - col = legendColors, - pch = legendPch, - lty = legendLty, - ... - ) - } -} - -#' Plot a predicted-versus-observed goodness of fit plot -#' -#' @param dataMapping THe `DataMapping` object for which the goodness-of-fit -#' plot is to be drawn. For each group within the `dataMapping`, simulated -#' and observed values are compared. -#' @param foldDistance Numerical value for the fold-distance lines to be drawn. -#' Default is 2. -#' @param timeDiffThreshold Allowed difference between observed and simulated -#' time values in minutes. Default is 10. If for a certain observed point no -#' simulated time point exists within the defined threshold, the value is not -#' considered. -#' @param ... Any parameter that can be interpreted by the default [plot()] function -#' -#' @details Observed data points are drawn on the x, simulated values on the y axis. -#' @import ospsuite -#' @export -plotPredictedVsObserved <- function(dataMapping, foldDistance = 2, timeDiffThreshold = 10, ...) { - validateIsOfType(dataMapping, "DataMapping") - legendEntries <- c() - legendColors <- c() - legendPch <- c() - - # Count the number of groups plus the number of data sets that are not assigned to any group. - # Based on this number, the colors and other graphics argument values will be defined - nrOfEntries <- length(dataMapping$groupings) + length(dataMapping$ungroupedSeries) - # Generate default values in case specific values for color etc are not set - colors <- esqLABS_colors(nrOfColors = nrOfEntries) - pchArr <- 1:dataMapping$xySeriesCount - ltyArr <- 1:nrOfEntries - graphicsParIdx <- 1 - - # Convert timeDiffThreshold to xUnit of the dataMapping - if (!is.null(timeDiffThreshold)) { - timeDiffThreshold <- toUnit(quantityOrDimension = "Time", values = timeDiffThreshold, sourceUnit = "min", targetUnit = dataMapping$xUnit) - } - - # If logarithmic scaling of y-axis has been selected and manually provided y-lim - # is non-positive, use the automatically calculated values - if (isCharInString("y", dataMapping$log) && !all(dataMapping$yLim > 0)) { - dataMapping$yLim <- NULL - } - - # Create an empty plot - plot(NULL, NULL, - xlim = dataMapping$yLim + abs(dataMapping$yLim) * c(-0.1, 0.1), - ylim = dataMapping$yLim + abs(dataMapping$yLim) * c(-0.1, 0.1), - xlab = "Observed values", - ylab = "Simulated values", - log = if (isCharInString("y", dataMapping$log)) { - "xy" - } else { - "" - }, - main = dataMapping$title, - ... - ) - # Draw the identity line - points(dataMapping$yLim, dataMapping$yLim, type = "l") - # Plot the fold deviation lines. - for (f in foldDistance) { - points(dataMapping$yLim, dataMapping$yLim * 1 / f, type = "l", lty = 2) - points(dataMapping$yLim, dataMapping$yLim * f, type = "l", lty = 2) - } - - graphicsParIdx <- 1 - for (groupingIdx in seq_along(dataMapping$groupings)) { - grouping <- dataMapping$groupings[[groupingIdx]] - - # Combine all values for observed data - dataPointsX <- c() - dataPointsY <- c() - dataErrorY <- c() - simulatedResults <- list() - # First filter simulated results from observed data - for (dataName in grouping) { - xySeries <- dataMapping$xySeries[[dataName]] - if (xySeries$dataType == XYDataTypes$Simulated) { - simulatedResults <- append(simulatedResults, xySeries) - next - } - # Collapse all observed data - dataPointsX <- c(dataPointsX, xySeries$xValuesProcessed(dataMapping$xUnit)) - dataPointsY <- c(dataPointsY, xySeries$yValuesProcessed(dataMapping$yUnit)) - } - # Plot the simulated-observed pairs - for (simulatedResult in simulatedResults) { - # Apply scaling to simulated results - simulatedPointsX <- simulatedResult$xValuesProcessed(dataMapping$xUnit) - simulatedPointsY <- simulatedResult$yValuesProcessed(dataMapping$yUnit) - # Iterate through each observed data point and find the simulated value - # with the closest x-value. - for (i in seq_along(dataPointsX)) { - idx <- getIndexClosestToValue(dataPointsX[[i]], (simulatedPointsX), thresholdAbs = timeDiffThreshold) - # In case of population simulation, idx may have more than one entry - for (pointIdx in idx) { - points(dataPointsY[[i]], simulatedPointsY[[pointIdx]], - pch = pchArr[[graphicsParIdx]], - col = colors[[graphicsParIdx]] - ) - } - } - } - legendEntries <- c(legendEntries, names(dataMapping$groupings)[[groupingIdx]]) - legendColors <- c(legendColors, colors[[graphicsParIdx]]) - legendPch <- c(legendPch, pchArr[[graphicsParIdx]]) - graphicsParIdx <- graphicsParIdx + 1 - } - - # Draw a legend, if specified - if (dataMapping$addLegend) { - .figureAddLegend( - x = dataMapping$legendPosition, - legend = legendEntries, - col = legendColors, - pch = legendPch, - lty = NULL, - ... - ) - } -} - -#' Calculate the root mean square error for groupings in `dataMapping`s -#' -#' -#' @param dataMappingList A `DataMapping` or a list of `DataMapping` objects. -#' @param timeDiffThreshold Allowed difference between observed and simulated -#' time values in minutes. Default is 10. If for a certain observed point no -#' simulated time point exists within the defined threshold, the value is not -#' considered. -#' -#' @details The error is calculated for each group separately and added up. For -#' each group, the error is defined as the root of the sum of the squared -#' residuals between each simulated result and observed data. -#' -#' @return Total error for all groups across all provided data mappings. -#' @import ospsuite -#' @export -calculateRMSE <- function(dataMappingList, timeDiffThreshold = 10) { - dataMappingList <- toList(dataMappingList) - - error <- 0 - for (dataMapping in dataMappingList) { - # Convert timeDiffThreshold to xUnit of the dataMapping - if (!is.null(timeDiffThreshold)) { - timeDiffThreshold <- toUnit( - quantityOrDimension = "Time", - values = timeDiffThreshold, - sourceUnit = "min", - targetUnit = dataMapping$xUnit - ) - } - - for (grouping in dataMapping$groupings) { - dataPointsX <- c() - dataPointsY <- c() - simulatedResults <- list() - # First filter simulated results from observed data - for (dataName in grouping) { - xySeries <- dataMapping$xySeries[[dataName]] - if (xySeries$dataType == XYDataTypes$Simulated) { - simulatedResults <- append(simulatedResults, xySeries) - next - } - # Collapse all observed data - dataPointsX <- c(dataPointsX, xySeries$xValuesProcessed(dataMapping$xUnit)) - dataPointsY <- c(dataPointsY, xySeries$yValuesProcessed(dataMapping$yUnit)) - } - # Calculate the distance between each point of the observed data to each simulated result - for (simulatedResult in simulatedResults) { - # Apply scaling to simulated results - simulatedPointsX <- simulatedResult$xValuesProcessed(dataMapping$xUnit) - simulatedPointsY <- simulatedResult$yValuesProcessed(dataMapping$yUnit) - for (i in seq_along(dataPointsX)) { - idx <- getIndexClosestToValue(dataPointsX[[i]], (simulatedPointsX), timeDiffThreshold) - # In case of population simulation, idx may have more than one entry - for (pointIdx in idx) { - error <- error + (simulatedPointsY[[pointIdx]] - dataPointsY[[i]])^2 - } - } - } - } - } - return(sqrt(error)) -} diff --git a/R/utilities-data.R b/R/utilities-data.R index d5e10478..f4691807 100644 --- a/R/utilities-data.R +++ b/R/utilities-data.R @@ -1,104 +1,3 @@ -#' Read time-values data from excel file -#' -#' @param dataConfiguration An object of `DataConfiguration` -#' @details The methods reads time-values data from the properly defined excel -#' sheet and creates `XYData` objects according to the groupings. Each sheet -#' in `DataConfiguration$sheets` is split according to columns listed in -#' `DataConfiguration$columnsToSplitBy`. The output structure is a nested list -#' with levels corresponding to the groupings. -#' -#' @return A (nested) list of `XYData` objects -#' @import ospsuite -#' @export -readOSPSTimeValues <- function(dataConfiguration) { - validateIsString(c(dataConfiguration$dataFolder, dataConfiguration$dataFile, dataConfiguration$sheets)) - filePath <- file.path(dataConfiguration$dataFolder, dataConfiguration$dataFile) - validateFileExists(filePath) - - observedData <- list() - for (sheet in dataConfiguration$dataSheets) { - data <- readExcel(path = filePath, sheet = sheet) - allFactors <- list() - groupings <- c() - # Split the data by a column only if it contains non-NA values - for (columnName in dataConfiguration$columnsToSplitBy) { - if (length(data[[columnName]]) > 0 && all(!is.na(data[[columnName]]))) { - groupings <- c(groupings, columnName) - allFactors <- append(allFactors, list(data[[columnName]])) - } - } - data <- split(data, allFactors, drop = TRUE) - - # Create an XYData object for each group - for (groupIdx in seq_along(data)) { - group <- data[[groupIdx]] - groupName <- names(data)[[groupIdx]] - xVals <- group[[dataConfiguration$XValuesColumn]] - yVals <- group[[dataConfiguration$YValuesColumn]] - yErrorVals <- group[[dataConfiguration$YErrorColumn]] - - # Parse Dimensions and Units - xName <- colnames(group)[[dataConfiguration$XValuesColumn]] - yName <- colnames(group)[[dataConfiguration$YValuesColumn]] - yErrorName <- colnames(group)[[dataConfiguration$YErrorColumn]] - - - # Get name of the dimension before the unit - xDim <- strsplit(xName, "\\ ?\\[")[[1]][[1]] - # The unit is the second entry - xUnit <- strsplit(xName, "\\ ?\\[")[[1]][[2]] - # Remove the trailing ']' - xUnit <- gsub(pattern = "]", replacement = "", xUnit, fixed = TRUE) - - yDim <- strsplit(yName, "\\ ?\\[")[[1]][[1]] - yUnit <- strsplit(yName, "\\ ?\\[")[[1]][[2]] - yUnit <- gsub(pattern = "]", replacement = "", yUnit, fixed = TRUE) - - yErrorUnit <- strsplit(yErrorName, "\\ ?\\[")[[1]][[2]] - yErrorUnit <- gsub(pattern = "]", replacement = "", yErrorUnit, fixed = TRUE) - - timeValues <- XYData$new(stringToNum(xVals), stringToNum(yVals), label = paste(sheet, groupName, sep = "."), yError = stringToNum(yErrorVals)) - timeValues$xDimension <- xDim - timeValues$xUnit <- xUnit - timeValues$yDimension <- yDim - timeValues$yUnit <- yUnit - timeValues$yErrorUnit <- yErrorUnit - timeValues$dataType <- XYDataTypes$Observed - timeValues$setMetaData(name = "StudyId", value = group$`Study Id`[[1]]) - timeValues$setMetaData(name = "PatientId", value = group$`Study Id`[[1]]) - timeValues$setMetaData(name = "Organ", value = group$Organ[[1]]) - timeValues$setMetaData(name = "Compartment", value = group$Compartment[[1]]) - timeValues$setMetaData(name = "Species", value = group$Species[[1]]) - timeValues$setMetaData(name = "Gender", value = group$Gender[[1]]) - timeValues$setMetaData(name = "Molecule", value = group$Molecule[[1]]) - - # If a molecule is specified, retrieve its molecular weight - moleculeName <- timeValues$getAllMetaData()$Molecule - if (!is.null(moleculeName) && !is.na(moleculeName)) { - compoundProperties <- readExcel( - path = file.path(dataConfiguration$dataFolder, dataConfiguration$compoundPropertiesFile), sheet = timeValues$getAllMetaData()$Molecule - ) - mwIdx <- which(compoundProperties$`Parameter, [AdditionalParameter]` == "MW") - mw <- compoundProperties$`Value [1,1]`[[mwIdx]] - unit <- compoundProperties$`Unit [1,1]`[[mwIdx]] - timeValues$MW <- as.numeric(mw) - } - - timeValues$setMetaData(name = "GroupId", value = group$`Group Id`[[1]]) - - # Some ugly piece of code to create a tree-like structure. - # Don't even want to comment - levelString <- unlist(lapply(groupings, function(x) { - group[[x]][[1]] - }), use.names = FALSE) - levelString <- paste0("'", levelString, "'", collapse = "$") - evalString <- paste0("observedData[[sheet]]$", levelString, " <- timeValues") - eval(parse(text = evalString)) - } - } - return(observedData) -} - #' Convert string to numeric #' #' @param string A string or a list of strings to be converted to numeric values @@ -205,7 +104,6 @@ calculateMeanDataSet <- function(dataSets, method = "arithmetic", lloqMode = LLO switch(lloqMode, # nothing to do for LLOQ/2 "LLOQ/2" = { - return }, # set all data points with lloq that are smaller than it to value of lloq "LLOQ" = df[ind, "yValues"] <- df[ind, "lloq"], @@ -292,12 +190,12 @@ LLOQMode <- enum(list("LLOQ/2", "LLOQ", "ZERO", "ignore")) #' Load data from excel #' #' @description Loads data sets from excel. The excel file containing the data -#' must be located in the folder `scenarioConfiguration$projectConfiguration$dataFolder` -#' and be named `scenarioConfiguration$projectConfiguration$dataFile`. +#' must be located in the folder `projectConfiguration$dataFolder` +#' and be named `projectConfiguration$dataFile`. #' Importer configuration file must be located in the same folder and named -#' `scenarioConfiguration$projectConfiguration$dataImporterConfigurationFile`. +#' `projectConfiguration$dataImporterConfigurationFile`. #' -#' @param scenarioConfiguration Object of class `ScenarioConfiguration` containing +#' @param projectConfiguration Object of class `ProjectConfiguration` containing #' the necessary information. #' @param sheets String or a list of strings defining which sheets to load. #' If `NULL` (default), all sheets within the file are loaded. @@ -308,16 +206,15 @@ LLOQMode <- enum(list("LLOQ/2", "LLOQ", "ZERO", "ignore")) #' #' @examples #' \dontrun{ -#' # Create default project and scenario configurations +#' # Create default project configuration #' projectConfiguration <- createDefaultProjectConfiguration() -#' scenarioConfiguration <- ScenarioConfiguration$new(projectConfiguration) -#' dataSets <- loadObservedData(scenarioConfiguration) +#' dataSets <- loadObservedData(projectConfiguration) #' } -loadObservedData <- function(scenarioConfiguration, sheets = NULL) { +loadObservedData <- function(projectConfiguration, sheets = NULL) { importerConfiguration <- ospsuite::loadDataImporterConfiguration( configurationFilePath = file.path( - scenarioConfiguration$projectConfiguration$dataFolder, - scenarioConfiguration$projectConfiguration$dataImporterConfigurationFile + projectConfiguration$dataFolder, + projectConfiguration$dataImporterConfigurationFile ) ) validateIsString(sheets, nullAllowed = TRUE) @@ -331,8 +228,8 @@ loadObservedData <- function(scenarioConfiguration, sheets = NULL) { dataSets <- ospsuite::loadDataSetsFromExcel( xlsFilePath = file.path( - scenarioConfiguration$projectConfiguration$dataFolder, - scenarioConfiguration$projectConfiguration$dataFile + projectConfiguration$dataFolder, + projectConfiguration$dataFile ), importerConfigurationOrPath = importerConfiguration, importAllSheets = importAllSheets diff --git a/R/utilities-figures.R b/R/utilities-figures.R index b4496860..fc591c83 100644 --- a/R/utilities-figures.R +++ b/R/utilities-figures.R @@ -37,7 +37,7 @@ esqLABS_colors <- function(nrOfColors) { deltaV_r_g <- max(esqRed_hsv[3], esqGreen_hsv[3]) - min(esqRed_hsv[3], esqGreen_hsv[3]) if (nrOfColors < 0) { - stop("nrOfColors must be positive, value ", nrOfColors, " is not valid!") + stop(messages$nrOfColorsShouldBePositive(nrOfColors)) } if (nrOfColors == 0) { return(c()) @@ -97,51 +97,6 @@ esqLABS_colors <- function(nrOfColors) { return(palette) } -#' Add a label to a figure. Taken from -#' -#' @param label Label that is to be drawn -#' @param location Location of the label. Allowed entries are 'topleft', -#' 'topcenter', 'topright', 'bottomleft', 'bottomright', 'bottomcenter' -#' @param offset Coordinates of the offset of the label -#' @keywords internal -figureAddLabel <- function(label, location = "topleft", - offset = c(0, 0)) { - coords <- switch(location, - topleft = c(0.015, 0.98), - topcenter = c(0.5525, 0.98), - topright = c(0.985, 0.98), - bottomleft = c(0.015, 0.02), - bottomcenter = c(0.5525, 0.02), - bottomright = c(0.985, 0.02), - c(0.015, 0.98) - ) - - this.x <- grconvertX(coords[1] + offset[1], from = "nfc", to = "user") - this.y <- grconvertY(coords[2] + offset[2], from = "nfc", to = "user") - text(labels = label[1], x = this.x, y = this.y, xpd = T) -} - -#' Add legend to a plot -#' -#' @inheritParams graphics::legend -#' @param ... Additional arguments to be passed to `graphics::legend`. -#' @keywords internal -.figureAddLegend <- function(x, legend, col, pch, lty, ...) { - # Legend does not ignore ellipsis arguments that are not supported, so they - # must be removed from the arguments list - supportedArgs <- names(formals(graphics::legend)) - args <- list(...) - args <- args[which(names(args) %in% supportedArgs)] - args$x <- x - args$legend <- legend - args$col <- col - args$pch <- pch - args$lty <- lty - - # Using do.call use arguments combined from ellipsis - do.call(graphics::legend, args) -} - #' Returns the HSV values for a given R color name #' #' @param color vector of any of the three kinds of R color specifications, @@ -153,7 +108,7 @@ figureAddLabel <- function(label, location = "topleft", #' indicate hue, saturation and value and are named "h", "s", and "v" #' accordingly. #' @export -#' @import ospsuite +#' @import ospsuite ospsuite.utils #' #' @examples #' col2hsv("yellow") @@ -164,125 +119,105 @@ col2hsv <- function(color) { return(rgb2hsv(rgb)) } -#' A function to add error bars on the chart. -#' @description Taken from -#' @import ospsuite -#' -#' @param x Numerical array of x-values -#' @param y Numerical array of y-values -#' @param upper Numerical array of upper y-error values -#' @param lower Numerical array of lower y-error values. Optional. -#' If not specified, same values as for `upper` are used -#' @param length Numerical value specifying the width of the error bars. -#' Optional. Default is 0.1. -#' @param axis Dimension to which the error bars are added. If "y" (default), -#' vertical error bars are drawn. If "x", horizontal error bars are drawn -#' @param ... Graphical parameters (see [par()]) -#' -#' @keywords internal -plotErrorBars <- function(x, - y, - upper, - lower = upper, - length = par()$cin[[1]] / 2, - axis = "y", - ...) { - validateIsNumeric(c(x, y)) - validateIsSameLength(x, y, upper, lower) - if (axis == "y") { - arrows(x, y + upper, x, y - lower, angle = 90, code = 3, length = length, ...) - } - if (axis == "x") { - arrows(x + upper, y, x - lower, y, angle = 90, code = 3, length = length, ...) - } -} - -#' Possible entries for the `outputDevice` field of a `PlotConfiguration` object +#' Possible entries for the `outputDevice` field of a `ProjectConfiguration` object #' @export GraphicsDevices <- enum(list("PNG")) -#' Possible entries for the `plotType` field of a `DataMapping` object -#' -#' @details "IndividualProfile" - simulated results are plotted as time-values -#' series with points connected by lines, with each individual results potted -#' separately "PopulationQuantiles" - simulated results for a population are -#' aggregated as median, 95th an 5th percentiles, with median plotted as a -#' line an upper/lower percentiles plotted as shaded areas -#' "PredictedVsObserved" - predicted-versus-observed goodness of fit plot -#' @export -PlotTypes <- enum(list( - "IndividualProfile", - "PopulationQuantiles", - "PredictedVsObserved", - "BoxPlot" -)) -#' Open an output device. +#' @title Create an instance of `DefaultPlotConfiguration` R6 class +#' @rdname createEsqlabsPlotConfiguration #' -#' @param plotConfiguration An object of type `PlotConfiguration` -#' @param width Width of the output figure -#' @param height Height of the output figure +#' @description #' -#' @details If the output of the plot is directed to a file, open the -#' connection. A list of supported outputs is provided in -#' `GraphicsDevices`-enum. If the provided output defined in -#' PlotConfiguration$outputDevice is not supported or the value is `NULL`, -#' output is directed to the default plot frame. +#' An instance of `DefaultPlotConfiguration` R6 class is needed for creating +#' visualizations with the `{ospsuite}` package. #' -#' @keywords internal -openOuptutDevice <- function(plotConfiguration, width, height) { - if (is.null(plotConfiguration$outputDevice)) { - return() - } - if (plotConfiguration$outputDevice == GraphicsDevices$PNG) { - png( - filename = file.path( - plotConfiguration$outputFolder, - paste0(plotConfiguration$outputName, ".png") - ), - width = width, - height = height, - units = "cm", - res = plotConfiguration$res, - pointsize = plotConfiguration$pointsize - ) - } -} - -#' Close output device +#' The default attributes of the class are chosen to reflect the corporate +#' standards adopted by esqLABS GmbH. #' -#' @param plotConfiguration An object of type `PlotConfiguration` -#' @import ospsuite +#' @return An instance of `DefaultPlotConfiguration` R6 class. #' -#' @details If the output of the plot is directed to a file, close the device. -#' @keywords internal -closeOutputDevice <- function(plotConfiguration) { - if (is.null(plotConfiguration$outputDevice)) { - return() - } - if (enumHasKey(plotConfiguration$outputDevice, GraphicsDevices)) { - dev.off() - } +#' @examples +#' createEsqlabsPlotConfiguration() +#' +#' @family create-plotting-configurations +#' +#' @export +createEsqlabsPlotConfiguration <- function() { + defaultPlotConfiguration <- ospsuite::DefaultPlotConfiguration$new() + + defaultPlotConfiguration$titleSize <- 8 + defaultPlotConfiguration$xLabelSize <- 8 + defaultPlotConfiguration$yLabelSize <- 8 + defaultPlotConfiguration$xAxisLabelTicksSize <- 8 + defaultPlotConfiguration$yAxisLabelTicksSize <- 8 + defaultPlotConfiguration$legendTitleSize <- 6 + defaultPlotConfiguration$legendPosition <- tlf::LegendPositions$outsideTop + + return(defaultPlotConfiguration) } -#' Does the plot type contain points? +#' @title Create an instance of `PlotGridConfiguration` R6 class +#' @rdname createEsqlabsPlotGridConfiguration +#' +#' @description +#' +#' An instance of `PlotGridConfiguration` R6 class from `{tlf}` package is +#' needed for creating a grid of multiple visualizations created using the +#' `{ospsuite}` package. #' -#' @param type String value of argument `type` passed to function `plot()` +#' The default attributes of the class are chosen to reflect the corporate +#' standards adopted by esqLABS GmbH. #' -#' @return TRUE if `type` contains "p" or is "b", FALSE otherwise +#' @return An instance of `PlotGridConfiguration` R6 class. #' -#' @keywords internal -.isPoint <- function(type) { - isCharInString("p", type) || (type == "b") +#' @examples +#' createEsqlabsPlotGridConfiguration() +#' +#' @family create-plotting-configurations +#' +#' @export +createEsqlabsPlotGridConfiguration <- function() { + plotGridConfiguration <- tlf::PlotGridConfiguration$new() + + plotGridConfiguration$tagLevels <- "a" + + return(plotGridConfiguration) } -#' Does the plot type contain line? +#' @param projectConfiguration Object of class `ProjectConfiguration` +#' that contains information about the output paths. +#' +#' @title Create an instance of `ExportConfiguration` R6 class +#' @rdname createEsqlabsExportConfiguration +#' +#' @description #' -#' @param type String value of argument `type` passed to function `plot()` +#' An instance of `ExportConfiguration` R6 class from `{tlf}` package is needed +#' for saving the plots and plot grids created using the `{ospsuite}` package. #' -#' @return TRUE if `type` contains "l" or is "b", FALSE otherwise +#' The default attributes of the class are chosen to reflect the corporate +#' standards adopted by esqLABS GmbH. +#' +#' @return An instance of `ExportConfiguration` R6 class. +#' +#' @examples +#' myProjConfig <- ProjectConfiguration$new() +#' createEsqlabsExportConfiguration(myProjConfig) #' -#' @keywords internal -.isLine <- function(type) { - isCharInString("l", type) || (type == "b") +#' @family create-plotting-configurations +#' +#' @export +createEsqlabsExportConfiguration <- function(projectConfiguration) { + exportConfiguration <- tlf::ExportConfiguration$new() + + exportConfiguration$path <- projectConfiguration$outputFolder + exportConfiguration$dpi <- 300 + exportConfiguration$format <- projectConfiguration$outputDevice + + exportConfiguration$width <- 18 + exportConfiguration$height <- 18 + exportConfiguration$units <- "cm" + + return(exportConfiguration) } diff --git a/R/utilities-file.R b/R/utilities-file.R index 2e8d0ed5..e2068fa6 100644 --- a/R/utilities-file.R +++ b/R/utilities-file.R @@ -1,9 +1,9 @@ #' Source all .R files located in a specific folder #' #' @param folderPath Path to the folder where .R files are located -#' @param recursive If TRUE, the contents of the sub-folders are also sourced, +#' @param recursive If `TRUE`, the contents of the sub-folders are also sourced, #' otherwise only the files located directly in the directory are considered. -#' Default is FALSE. +#' Default is `FALSE`. #' @export sourceAll <- function(folderPath, recursive = FALSE) { filesPaths <- list.files(folderPath, recursive = recursive) @@ -18,15 +18,15 @@ sourceAll <- function(folderPath, recursive = FALSE) { invisible(lapply(file.path(folderPath, filesPaths), sourceFile)) } -#' pathFromClipboard +#' Convert Windows filepaths for R #' -#' Converts the windows-like path (using `\`) from the clipboard to the form +#' Converts the Windows-like path (using `\`) from the clipboard to the form #' readable by R (using` /`). #' -#' @param path Path that will be converted. If "clipboard" (default), path is +#' @param path Path that will be converted. If `"clipboard"` (default), path is #' queried from clipboard. #' -#' @return String representation of a file path with `/` as separator +#' @return String representation of a file path with `/` as separator. #' @export pathFromClipboard <- function(path = "clipboard") { y <- if (path == "clipboard") { @@ -45,7 +45,7 @@ pathFromClipboard <- function(path = "clipboard") { #' @param path Full path of an XLS/XLSX file #' @param sheet Name or number of the sheet. If `NULL` (default), the first sheet of the #' file is used. -#' @param ... Any other parameters that can be passed to readxl::read_excel +#' @param ... Any other parameters that can be passed to `readxl::read_excel` #' #' @return A tibble with the contents of the excel sheet #' @export @@ -57,3 +57,24 @@ readExcel <- function(path, sheet = NULL, ...) { ... )) } + +#' Write data to excel +#' +#' @details Uses `writexl::write_xlsx` to write data to excel. If the folder +#' does not exist, creates folder(s) recursively. +#' +#' @param data Data frame or named list of data frames that will be sheets in +#' the xlsx +#' @inheritParams writexl::write_xlsx +#' @export +writeExcel <- function(data, path, col_names = TRUE) { + # If the provided path to the output file targets a non-existent directory, + # try to create the directory + resultsDir <- dirname(path) + if (!file.exists(resultsDir)) { + dir.create(resultsDir, recursive = TRUE) + } + + # Write the data into an excel file. + writexl::write_xlsx(data, path = path, col_names = col_names) +} diff --git a/R/utilities-individual.R b/R/utilities-individual.R index 6566fd9b..801ededc 100644 --- a/R/utilities-individual.R +++ b/R/utilities-individual.R @@ -41,10 +41,15 @@ writeIndividualToXLS <- function(individualCharacteristics, outputXLSPath) { units[i] <- individual$distributedParameters$units[[i]] } - output <- data.frame(unlist(containerPaths, use.names = FALSE), unlist(paramNames, use.names = FALSE), unlist(as.numeric(values), use.names = FALSE), unlist(units, use.names = FALSE)) + output <- data.frame( + unlist(containerPaths, use.names = FALSE), + unlist(paramNames, use.names = FALSE), + unlist(as.numeric(values), use.names = FALSE), + unlist(units, use.names = FALSE) + ) colnames(output) <- columnNames - writexl::write_xlsx(output, path = outputXLSPath, col_names = TRUE) + writeExcel(data = output, path = outputXLSPath) } #' Read individual characteristics from file @@ -113,12 +118,11 @@ readIndividualCharacteristicsFromXLS <- function(XLSpath, #' For other species, all parameters returned by `createIndividual` are applied. #' #' @param individualCharacteristics `IndividualCharacteristics` describing an individual. Optional -#' @param simulation `Simulation` loaded form the PKML file +#' @param simulation `Simulation` loaded from the PKML file #' @import ospsuite #' @export #' #' @examples -#' #' #' \dontrun{ #' simulation <- loadSimulation(filePath = modelPath) #' humanIndividualCharacteristics <- createIndividualCharacteristics( diff --git a/R/utilities-parameters.R b/R/utilities-parameters.R index 269628bb..d571ffa4 100644 --- a/R/utilities-parameters.R +++ b/R/utilities-parameters.R @@ -39,6 +39,61 @@ readParametersFromXLS <- function(paramsXLSpath, sheets = NULL) { return(.parametersVectorToList(pathsValuesVector, pathsUnitsVector)) } +#' Export simulation parameters to excel +#' +#' @description Creates an excel file with information from the passed +#' parameters. The excel sheet will contain columns "Container Path", +#' "Parameter Name", "Value", and "Units". The resulting file can be loaded in +#' `MoBi` or in `R` with the function `readParametersFromXLS()`. +#' +#' @param parameters A single or a list of `Parameter` objects +#' @param paramsXLSpath Path to the excel file +#' @param sheet (Optional) name of the excel sheet + +#' @export +exportParametersToXLS <- function(parameters, paramsXLSpath, sheet = NULL) { + validateIsOfType(parameters, "Parameter") + validateIsCharacter(sheet, nullAllowed = TRUE) + if (!is.null(sheet)) { + validateIsOfLength(sheet, 1) + } + # Make sure parameters is a list even if only one parameter is passed + parameters <- c(parameters) + + parameterContainerPath <- + parameterUnits <- + parameterName <- vector("character", length(parameters)) + parameterValue <- vector("numeric", length(parameters)) + + for (paramIdx in seq_along(parameters)) { + param <- parameters[[paramIdx]] + parameterContainerPath[[paramIdx]] <- param$parentContainer$path + parameterName[[paramIdx]] <- param$name + parameterUnits[[paramIdx]] <- param$unit + parameterValue[[paramIdx]] <- param$value + } + + output <- data.frame( + unlist(parameterContainerPath, use.names = FALSE), + unlist(parameterName, use.names = FALSE), + unlist(parameterValue, use.names = FALSE), + unlist(parameterUnits, use.names = FALSE) + ) + + if (length(output) > 0) { + colnames(output) <- c("Container Path", "Parameter Name", "Value", "Units") + } + + # Write the results into an excel file. + # Wrap the output data frame into a list and name the list if sheet name + # has been provided + data <- list(output) + if (!is.null(sheet)) { + names(data) <- sheet + } + writeExcel(data = data, path = paramsXLSpath) +} + #' Extend parameters structure with new entries #' #' @param parameters A list containing vectors 'paths' with the full paths to the @@ -49,11 +104,11 @@ readParametersFromXLS <- function(paramsXLSpath, sheets = NULL) { #' units the values are in. Entries from this list will extend or overwrite #' the list `parameters` #' -#' @details This function adds new parameter entries from `newParameters` to +#' @details This function adds new parameter entries from `newParameters` to #' `parameters`. If an entry with the same path is already present in `parameters`, #' its value and unit will be overwritten with the values from `newParameters`. #' -#' @return Updated list of parameter patsh, values, and units +#' @return Updated list of parameter paths, values, and units #' @export extendParameterStructure <- function(parameters, newParameters) { if (!identical(names(parameters), c("paths", "values", "units"))) { @@ -73,7 +128,7 @@ extendParameterStructure <- function(parameters, newParameters) { return(parameters) } - # Convert the input parameter structure into hashes. + # Convert the input parameter structure into named vectors. pathsValuesVector <- parameters$values names(pathsValuesVector) <- parameters$paths pathsUnitsVector <- parameters$units @@ -109,7 +164,7 @@ extendParameterStructure <- function(parameters, newParameters) { return(returnVal) } -#' @title Check if two parameters are equal is respect to certain properties. +#' @title Check if two parameters are equal with respect to certain properties. #' #' @details #' The parameters are not equal if: @@ -123,8 +178,8 @@ extendParameterStructure <- function(parameters, newParameters) { #' OR checkFormulaValues is TRUE and the values differ (disregarding of overridden or not) #' Table formulas: If the number of points differ, OR any of the points differ, #' OR one of the parameter values is fixed (formula is overridden), -#' OR both parameter values are fixed and differ -#' #' +#' OR both parameter values are fixed and differ. +#' #' @param parameter1 First parameter to compare #' @param parameter2 Second parameter to compare #' @param checkFormulaValues If TRUE, values of explicit formulas are always @@ -223,13 +278,13 @@ isTableFormulasEqual <- function(formula1, formula2) { #' @param simulation Simulation used to retrieve parameter instances from given paths. #' #' @examples -#' \dontrun{ -#' #' simPath <- system.file("extdata", "simple.pkml", package = "ospsuite") #' sim <- loadSimulation(simPath) #' condition <- function(path) { -#' task <- ospsuite:::getContainerTask() -#' !rClr::clrCall(task, "IsExplicitFormulaByPath", simulation$ref, enc2utf8(path)) +#' ospsuite::isExplicitFormulaByPath( +#' path = path, +#' simulation = sim +#' ) #' } #' setParameterValuesByPathWithCondition( #' c("Organism|Liver|Volume", "Organism|Volume"), @@ -237,7 +292,6 @@ isTableFormulasEqual <- function(formula1, formula2) { #' sim, #' condition #' ) -#' } #' @import ospsuite #' @export setParameterValuesByPathWithCondition <- function(parameterPaths, diff --git a/R/utilities-project-configuration.R b/R/utilities-project-configuration.R index 36d32fb9..568ff42e 100644 --- a/R/utilities-project-configuration.R +++ b/R/utilities-project-configuration.R @@ -1,13 +1,15 @@ #' Create a default `ProjectConfiguration` #' -#' @details Create a `ProjectConfiguration` based on the "ProjectConfiguration.xlsx" +#' @inheritParams readExcel +#' +#' @details Create a `ProjectConfiguration` based on the `"ProjectConfiguration.xlsx"` #' located in the "Code" folder. #' #' @return Object of type `ProjectConfiguration` #' @export -createDefaultProjectConfiguration <- function() { +createDefaultProjectConfiguration <- function(path = file.path("ProjectConfiguration.xlsx")) { # Read data from excel - data <- readExcel(path = file.path("ProjectConfiguration.xlsx")) + data <- readExcel(path = path) # Create an empty project configuration object and population with data from # excel projectConfiguration <- ProjectConfiguration$new() diff --git a/R/utilities-quantity.R b/R/utilities-quantity.R new file mode 100644 index 00000000..1cb4f7fb --- /dev/null +++ b/R/utilities-quantity.R @@ -0,0 +1,44 @@ +#' Get the name of the molecule from a quantity +#' +#' @description Returns the name of the molecule to which the quantity object +#' is associated. The quantity could be the amount of the molecule in a container +#' ('Organism|VenousBlood|Plasma|Aciclovir'), a parameter of the molecule +#' ('Aciclivor|Lipophilicity' or 'Organism|VenousBlood|Plasma|Aciclovir|Concentration'), +#' or an observer ("Organism|PeripheralVenousBlood|Aciclovir|Plasma (Peripheral Venous Blood)"). +#' +#' If the quantity is not associated with a molecule (e.g. 'Organism|Weight'), +#' an error is thrown. +#' +#' @param quantity A `Quantity` object +#' +#' @return Name of the molecule the quantity is associated with. +#' @export +#' +#' @examples +#' simulation <- loadSimulation(system.file("extdata", "Aciclovir.pkml", package = "ospsuite")) +#' quantity <- getQuantity( +#' path = "Organism|PeripheralVenousBlood|Aciclovir|Plasma (Peripheral Venous Blood)", +#' container = simulation +#' ) +#' getMoleculeNameFromQuantity(quantity = quantity) +getMoleculeNameFromQuantity <- function(quantity) { + validateIsOfType(quantity, "Quantity") + + quantityType <- quantity$quantityType + + # If the passed quantitiy is a molecule, return its name + if (quantityType %in% c("Drug", "Molecule")) { + return(quantity$name) + } + + # Otherwise try to get its parent container + parentContainer <- quantity$parentContainer + parentContainerType <- parentContainer$containerType + + # If parent container is not a molecule, stop with an error + if (!(parentContainerType %in% c("Drug", "Molecule"))) { + stop(messages$cannotGetMoleculeFromQuantity(quantity$path)) + } + + return(parentContainer$name) +} diff --git a/R/utilities-scenario-configuration.R b/R/utilities-scenario-configuration.R index 6409e263..84e6c03c 100644 --- a/R/utilities-scenario-configuration.R +++ b/R/utilities-scenario-configuration.R @@ -65,7 +65,7 @@ readScenarioConfigurationFromExcel <- function(scenarioConfiguration) { return(scenarioConfiguration) } -#' Set applications +#' Set an application protocol in a `Simulation` #' #' @details Set the parameter values describing the application protocol #' defined in the scenario configuration. Either calling a function that is stored diff --git a/R/utilities-scenarios.R b/R/utilities-scenarios.R index f6e0c07f..1bf8e537 100644 --- a/R/utilities-scenarios.R +++ b/R/utilities-scenarios.R @@ -13,7 +13,7 @@ #' #' @return A named list, where the names are scenario names, and the values are #' lists with the initialized `Simulation` object with applied parameters, -#' `SimulatioResults` objec produced by running the simulation, and output values +#' `SimulatioResults` objects produced by running the simulation, and output values #' of the `SimulationResults`. #' @export runScenarios <- function(scenarioNames, scenarioConfiguration, customParams = NULL, @@ -80,14 +80,14 @@ runScenarios <- function(scenarioNames, scenarioConfiguration, customParams = NU #' Initialize a simulation based on scenario definition #' #' @description -#' Load simulation -#' Apply parameters from global XLS -#' Apply individual physiology -#' Apply individual model parameters -#' Apply test parameters (TestParameters.R) -#' Set simulation outputs (OutputPaths.R) -#' Set simulation time -#' initializeSimulation() +#' Load simulation. +#' Apply parameters from global XLS. +#' Apply individual physiology. +#' Apply individual model parameters. +#' Apply test parameters (TestParameters.R). +#' Set simulation outputs (OutputPaths.R). +#' Set simulation time. +#' initializeSimulation(). #' #' @param scenarioConfiguration A `ScenarioConfiguration` object #' @param customParams A list with three vectors named `paths`, `values`, `units` @@ -170,15 +170,18 @@ initializeScenario <- function(scenarioConfiguration, customParams = NULL) { # Set the outputs clearOutputs(simulation) addOutputs(quantitiesOrPaths = enumValues(OutputPaths), simulation = simulation) - # Set simulation time - setOutputInterval(simulation = simulation, startTime = 0, endTime = scenarioConfiguration$simulationTime, resolution = scenarioConfiguration$pointsPerMinute) + # Set simulation time if defined by the user. + if (!is.null(scenarioConfiguration$simulationTime)) { + setOutputInterval(simulation = simulation, startTime = 0, endTime = scenarioConfiguration$simulationTime, resolution = scenarioConfiguration$pointsPerMinute) + } initializeSimulation( simulation = simulation, individualCharacteristics = individualCharacteristics, additionalParams = params, simulateSteadyState = scenarioConfiguration$simulateSteadyState, - steadyStateTime = scenarioConfiguration$steadyStateTime + steadyStateTime = scenarioConfiguration$steadyStateTime, + simulationRunOptions = scenarioConfiguration$simulationRunOptions ) # Set administration protocols diff --git a/R/utilities-simulation.R b/R/utilities-simulation.R index f9f4473c..8eade384 100644 --- a/R/utilities-simulation.R +++ b/R/utilities-simulation.R @@ -17,7 +17,7 @@ #' of the simulation are applied as initial conditions for all molecules. #' Default is `FALSE`. #' @param steadyStateTime Simulation time (minutes) for the steady-state -#' simulation. Must be long enough for system to reach a steady-state 1000 by +#' simulation. Must be long enough for system to reach a steady-state. 1000 by #' default. #' @param ignoreIfFormula If `TRUE` (default), species and parameters with #' initial values defined by a formula are not included in the steady-state @@ -25,7 +25,9 @@ #' @param stopIfParameterNotFound Logical. If `TRUE` (default), an error is #' thrown if any of the `additionalParams` does not exist. If `FALSE`, #' non-existent parameters are ignored. -#' @import ospsuite +#' @param simulationRunOptions Optional instance of a `SimulationRunOptions` +#' used during the simulation run. +#' @import ospsuite ospsuite.parameteridentification #' @export #' #' @examples @@ -45,10 +47,12 @@ initializeSimulation <- function(simulation, simulateSteadyState = FALSE, steadyStateTime = 1000, ignoreIfFormula = TRUE, - stopIfParameterNotFound = TRUE) { + stopIfParameterNotFound = TRUE, + simulationRunOptions = NULL) { validateIsOfType(simulation, "Simulation", nullAllowed = FALSE) validateIsOfType(individualCharacteristics, "IndividualCharacteristics", nullAllowed = TRUE) validateIsLogical(simulateSteadyState) + validateIsNumeric(steadyStateTime) # Apply parameters of the individual if (!is.null(individualCharacteristics)) { @@ -61,17 +65,25 @@ initializeSimulation <- function(simulation, stop(messages$wrongParametersStructure("additionalParams")) } - ospsuite::setParameterValuesByPath( - parameterPaths = additionalParams$paths, - values = additionalParams$values, - simulation = simulation, - units = additionalParams$units, - stopIfNotFound = FALSE - ) + # Skip if the correct structure is supplied, but no parameters are defined + if (!isEmpty(additionalParams$paths)) { + ospsuite::setParameterValuesByPath( + parameterPaths = additionalParams$paths, + values = additionalParams$values, + simulation = simulation, + units = additionalParams$units, + stopIfNotFound = FALSE + ) + } } if (simulateSteadyState) { - initialValues <- getSteadyState(simulations = simulation, steadyStateTime = steadyStateTime, ignoreIfFormula = ignoreIfFormula)[[simulation$id]] + initialValues <- getSteadyState( + simulations = simulation, + steadyStateTime = steadyStateTime, + ignoreIfFormula = ignoreIfFormula, + simulationRunOptions = simulationRunOptions + )[[simulation$id]] ospsuite::setQuantityValuesByPath( quantityPaths = initialValues$paths, values = initialValues$values, @@ -142,3 +154,59 @@ compareSimulationParameters <- function(simulation1, simulation2) { return(list(In1NotIn2 = pathsIn1NotIn2, In2NotIn1 = pathsIn2NotIn1, Different = pathsDiff)) } + +#' Get parameters of applications in the simulation +#' +#' @param simulation A `Simulation` object +#' @param moleculeNames Names of the molecules which applications parameters +#' will be returned. If `NUll`(default), applications for all molecules are +#' returned. +#' +#' @details Every application event has a `ProtocolSchemaItem` container that +#' holds parameters describing the dose, start time, infusion time etc. This +#' function returns a list of all constant parameters located under the +#' `ProtocolSchemaItem` container of applications defined for the `moleculeNames`. +#' +#' @return A list of `Parameter` objects defining the applications in the +#' simulation. +#' @export +#' +#' @examples +#' simPath <- system.file("extdata", "Aciclovir.pkml", package = "ospsuite") +#' simulation <- loadSimulation(simPath) +#' applicationParams <- getAllApplicationParameters(simulation = simulation) +#' +#' applicationParams <- getAllApplicationParameters( +#' simulation = simulation, +#' moleculeNames = "Aciclovir" +#' ) +getAllApplicationParameters <- function(simulation, moleculeNames = NULL) { + validateIsOfType(simulation, "Simulation") + validateIsCharacter(moleculeNames, nullAllowed = TRUE) + + # If no molecules have been specified, get application parameters for all + # molecules in the simulation + moleculeNames <- moleculeNames %||% simulation$allFloatingMoleculeNames() + + # Returns an object of class `Application` for each administration event + applications <- unlist(lapply(moleculeNames, \(x)simulation$allApplicationsFor(x)), use.names = FALSE) + + # Gather all parameters in one list that will be the output of the function + allParams <- list() + + for (application in applications) { + # get parent container of the application + parentContainer <- application$startTime$parentContainer + containerPath <- parentContainer$path + # Get all non-formula parameters of ProtocolSchemaItem + params <- getAllParametersMatching("*", parentContainer) + + for (param in params) { + if (!param$isFormula) { + allParams <- c(allParams, param) + } + } + } + + return(allParams) +} diff --git a/R/utilities-steady-state.R b/R/utilities-steady-state.R index 0810f31e..6be5e519 100644 --- a/R/utilities-steady-state.R +++ b/R/utilities-steady-state.R @@ -1,150 +1,16 @@ -#' Get the steady-state values of species and state variable parameters. -#' -#' @details The steady-state is considered to be the last value of the -#' simulation with sufficiently long simulation time, i.e., where the rates of -#' the processes do not (significantly) change. -#' -#' @param steadyStateTime Simulation time (minutes). Must be long enough for -#' system to reach a steady-state. 1000 by default -#' @param quantitiesPaths List of quantity paths (molecules and/or parameters) -#' for which the steady-state is to be simulated. If `NULL` (default), all -#' molecules and state variable parameters are considered. The same list is -#' applied for all simulations. -#' @param simulations `Simulation` object or a list of `Simulation` objects -#' @param ignoreIfFormula If `TRUE` (default), species and parameters with -#' initial values defined by a formula are not included. -#' @param stopIfNotFound Boolean. If `TRUE` (default), an error is thrown when -#' results for certain species were not generated. This may happen when due to -#' numerical problems some values cannot be calculated, though the whole -#' simulation converges. Setting this argument to `FALSE` allows to ignore -#' such errors. Check the outputs for empty values when using this option. -#' @param lowerThreshold Numerical value (in µmol). Any steady-state values -#' below this value are considered as numerical noise and replaced by 0. If -#' `lowerThreshold` is `NULL`, no cut-off is applied. Default value is 1e-15. -#' -#' @return A named list, where the names are the IDs of the simulations and the -#' entries are lists containing `paths` and their `values` at the end of the -#' simulation. -#' @import ospsuite rClr hash -#' @export -getSteadyState <- function(quantitiesPaths = NULL, - simulations, - steadyStateTime, - ignoreIfFormula = TRUE, - stopIfNotFound = TRUE, - lowerThreshold = 1e-15) { - validateIsOfType(simulations, type = "Simulation") - validateIsString(object = quantitiesPaths, nullAllowed = TRUE) - simulations <- toList(simulations) - - if (steadyStateTime <= 0) { - stop(messages$steadyStateTimeNotPositive(steadyStateTime)) - } - - # First prepare all simulations by setting their outputs and time intervals - # Create hash maps for the output intervals, time points, and output selections of the simulations in their initial state. - oldOutputIntervals <- hash::hash() - oldTimePoints <- hash::hash() - oldOutputSelections <- hash::hash() - # If no quantities have been specified, the quantities paths may be different for each simulation and must be stored separately - quantitiesPathsMap <- hash::hash() - for (simulation in simulations) { - simId <- simulation$id - # Have to reset both the output intervals and the time points! - oldOutputIntervals[[simId]] <- simulation$outputSchema$intervals - oldTimePoints[[simId]] <- simulation$outputSchema$timePoints - oldOutputSelections[[simId]] <- simulation$outputSelections$allOutputs - # Set simulation time to the steady-state value. - ospsuite::setOutputInterval(simulation = simulation, startTime = 0, endTime = steadyStateTime, resolution = 1 / steadyStateTime) - # If no quantities are explicitly specified, simulate all outputs. - if (is.null(quantitiesPaths)) { - quantitiesPathsMap[[simId]] <- ospsuite::getAllStateVariablesPaths(simulation) - } else { - quantitiesPathsMap[[simId]] <- quantitiesPaths - } - ospsuite::addOutputs(quantitiesOrPaths = quantitiesPathsMap[[simId]], simulation = simulation) - } - - # Run simulations concurrently - simulationResults <- ospsuite::runSimulations(simulations = simulations) - # Container task is required for checking the "isFormula" property - task <- ospsuite:::getContainerTask() - - # Iterate through simulations and get their outputs - outputMap <- hash::hash() - for (simulation in simulations) { - simId <- simulation$id - # Have to distinguish between a list of simulation results for multiple simulations, - # or a single simulation results - simResults <- simulationResults[[simId]] %||% simulationResults - - allOutputs <- ospsuite::getOutputValues( - simResults, - quantitiesOrPaths = quantitiesPathsMap[[simId]], - stopIfNotFound = stopIfNotFound, - addMetaData = FALSE - ) - - - # Get the end values of all outputs - endValues <- lapply(quantitiesPathsMap[[simId]], function(path) { - # Check if the quantity is defined by an explicit formula - isFormulaExplicit <- rClr::clrCall(task, "IsExplicitFormulaByPath", simulation$ref, enc2utf8(path)) - - if (ignoreIfFormula && isFormulaExplicit) { - return(NULL) - } - value <- tail(allOutputs$data[path][[1]], 1) - # Skip if value is NA. This happens if stopIfNotFound = FALSE and some species are not calculated - if (is.na(value)) { - return(NULL) - } - # If the value is below the cut-off threshold, replace it by 0 - if (!is.null(lowerThreshold) && value < lowerThreshold) { - value <- 0 - } - return(value) - }) - - # Get the indices for which the outputs have been calculated - indices <- which(lengths(endValues) != 0) - - # reset the output intervals - simulation$outputSchema$clear() - for (outputInterval in oldOutputIntervals[[simId]]) { - ospsuite::addOutputInterval( - simulation = simulation, startTime = outputInterval$startTime$value, - endTime = outputInterval$endTime$value, - resolution = outputInterval$resolution$value - ) - } - if (length(oldTimePoints[[simId]]) > 0) { - simulation$outputSchema$addTimePoints(oldTimePoints[[simId]]) - } - # Reset output selections - ospsuite::clearOutputs(simulation) - for (outputSelection in oldOutputSelections[[simId]]) { - ospsuite::addOutputs(quantitiesOrPaths = outputSelection$path, simulation = simulation) - } - outputMap[[simId]] <- list(paths = quantitiesPathsMap[[simId]][indices], values = endValues[indices]) - } - return(outputMap) -} - #' Export steady-state to excel #' #' @details Simulates a given model to its steady-state and creates an #' Excel-file with the end values of molecules amounts in all containers and #' parameter values that have a right-hand-side (state variable parameters). -#' @param simulation `Simulation` object -#' @param quantitiesPaths List of quantity paths (molecules and/or parameters) -#' for which the steady-state is to be simulated. If `NULL` (default), all -#' molecules and state variable parameters are considered. #' @param resultsXLSPath Path to the xls-file where the results will be written #' to. If the file does not exist, a new file is created. If no path is #' provided, the file will be created in the same directory where the model -#' file is located. -#' @inheritParams getSteadyState +#' file is located. The name of the file will be `_SS`. +#' @param simulation A `Simulation` object that will be updated with the steady +#' state +#' @inheritParams ospsuite.parameteridentification::getSteadyState +#' @import ospsuite.utils ospsuite.parameteridentification #' @export exportSteadyStateToXLS <- function(simulation, quantitiesPaths = NULL, @@ -152,20 +18,14 @@ exportSteadyStateToXLS <- function(simulation, steadyStateTime = 1000, ignoreIfFormula = TRUE, stopIfNotFound = TRUE, - lowerThreshold = 1e-15) { - validateIsOfType(simulation, type = "Simulation") - # If no explicit path to the results-file is provided, store the results file in the same folder as the model file. + lowerThreshold = 1e-15, + simulationRunOptions = NULL) { + # If no explicit path to the results-file is provided, store the results file + # in the same folder as the model file. if (resultsXLSPath == "") { simulationPath <- tools::file_path_sans_ext(simulation$sourceFile) resultsXLSPath <- paste0(simulationPath, "_SS.xlsx") } - # If the provided path to the output file targets a non-existent directory, try to create the directory - else { - resultsDir <- dirname(resultsXLSPath) - if (!file.exists(resultsDir)) { - dir.create(resultsDir, recursive = TRUE) - } - } initialValues <- getSteadyState( simulations = simulation, @@ -173,7 +33,8 @@ exportSteadyStateToXLS <- function(simulation, steadyStateTime = steadyStateTime, ignoreIfFormula = ignoreIfFormula, stopIfNotFound = stopIfNotFound, - lowerThreshold = lowerThreshold + lowerThreshold = lowerThreshold, + simulationRunOptions = simulationRunOptions )[[simulation$id]] nrOfEntries <- length(initialValues$paths) @@ -227,8 +88,13 @@ exportSteadyStateToXLS <- function(simulation, } speciesInitVals <- data.frame( - unlist(moleculeContainerPath, use.names = FALSE), unlist(moleculeName, use.names = FALSE), unlist(moleculeIsPresent, use.names = FALSE), unlist(moleculeValue, use.names = FALSE), - unlist(moleculeUnits, use.names = FALSE), unlist(moleculeScaleDivisor, use.names = FALSE), unlist(moleculeNegValsAllowed, use.names = FALSE) + unlist(moleculeContainerPath, use.names = FALSE), + unlist(moleculeName, use.names = FALSE), + unlist(moleculeIsPresent, use.names = FALSE), + unlist(moleculeValue, use.names = FALSE), + unlist(moleculeUnits, use.names = FALSE), + unlist(moleculeScaleDivisor, use.names = FALSE), + unlist(moleculeNegValsAllowed, use.names = FALSE) ) if (length(speciesInitVals) > 0) { @@ -236,12 +102,17 @@ exportSteadyStateToXLS <- function(simulation, } parameterInitVals <- data.frame( - unlist(parameterContainerPath, use.names = FALSE), unlist(parameterName, use.names = FALSE), unlist(parameterValue, use.names = FALSE), unlist(parameterUnits, use.names = FALSE) + unlist(parameterContainerPath, use.names = FALSE), + unlist(parameterName, use.names = FALSE), + unlist(parameterValue, use.names = FALSE), + unlist(parameterUnits, use.names = FALSE) ) if (length(parameterInitVals) > 0) { colnames(parameterInitVals) <- c("Container Path", "Parameter Name", "Value", "Units") } + # Write the results into an excel file. - writexl::write_xlsx(list("Molecules" = speciesInitVals, "Parameters" = parameterInitVals), path = resultsXLSPath, col_names = TRUE) + data <- list("Molecules" = speciesInitVals, "Parameters" = parameterInitVals) + writeExcel(data = data, path = resultsXLSPath) } diff --git a/R/utilities.R b/R/utilities.R index c8f561e9..9239761d 100644 --- a/R/utilities.R +++ b/R/utilities.R @@ -76,41 +76,6 @@ geosd <- function(x, na.rm = FALSE) { exp(sd(log(x), na.rm = na.rm)) } -#' Calculate quantiles for given xy-vectors -#' -#' @param quantiles A numerical vector with quantile values. Default is -#' `c(0.05, 0.5, 0.95)` -#' @param xValues X values, by which y values are grouped -#' @param yValues Values for which the quantiles are calculated -#' -#' @return A list with `xValues` and aggregated `yValues` -#' @export -getQuantilesYData <- function(xValues, yValues, quantiles = c(0.05, 0.5, 0.95)) { - validateIsNumeric(c(xValues, yValues, quantiles)) - validateIsSameLength(xValues, yValues) - output <- list() - # Aggregate time values - for (quantile in quantiles) { - aggregatedData <- aggregate(yValues, by = list(xVals = xValues), FUN = quantile, quantile) - output[[as.character(quantile)]] <- list() - output[[as.character(quantile)]][["xValues"]] <- aggregatedData$xVals - output[[as.character(quantile)]][["yValues"]] <- aggregatedData[[2]] - } - - return(output) -} - -#' Get hash code of the .NET object -#' -#' @param netWrapper Any object from the ospsuite-R that inherits from DotNetWrapper -#' @import rClr -#' -#' @return Value of the .NET-method "GetHashCode" -getNetHashCode <- function(netWrapper) { - validateIsOfType(netWrapper, "DotNetWrapper") - rClr::clrGet(netWrapper$ref, "HashCode") -} - #' Remove an entry from a list #' @@ -138,14 +103,14 @@ removeFromList <- function(entry, listArg) { return(listArg) } -#' Compare values including NA +#' Compare values including `NA` #' -#' @param v1 Value or a list of values to compare. May include NA. -#' @param v2 Value or a list of values to compare. May include NA. +#' @param v1 Value or a list of values to compare. May include `NA`. +#' @param v2 Value or a list of values to compare. May include `NA`. #' @details From http://www.cookbook-r.com/Manipulating_data/Comparing_vectors_or_factors_with_NA/ #' -#' @return TRUE wherever elements are the same, including NA's, -# and FALSE everywhere else. +#' @return `TRUE` wherever elements are the same, including `NA`'s, +# and `FALSE` everywhere else. #' @export compareWithNA <- function(v1, v2) { same <- (v1 == v2) | (is.na(v1) & is.na(v2)) @@ -153,21 +118,6 @@ compareWithNA <- function(v1, v2) { return(same) } -#' Is a character part of string? -#' -#' @param char Character to find in the string -#' @param string String that should contain the character -#' -#' @return TRUE if the `character` is a substring if `string`, FALSE otherwise -#' @export -#' -#' @examples -#' isCharInString("a", "bsdalk") -isCharInString <- function(char, string) { - any(unlist(strsplit(string, ""), use.names = FALSE) == char) -} - - #' Escape a string for possible regular expression match #' #' @param string String to be escaped diff --git a/R/zzz.R b/R/zzz.R index 21239471..3f24db8b 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -1,4 +1,6 @@ +# nocov start .onLoad <- function(...) { options(warnPartialMatchDollar = TRUE) Sys.setenv("_R_CHECK_LENGTH_1_CONDITION_" = "true") } +# nocov end diff --git a/README.md b/README.md index 538ca88e..5ba89795 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# esqlabsR +# esqlabsR -Utilities functions for modeling and simulation workflows within *esqLABS*. +The **`{esqlabsR}`** R-package is designed to facilitate and standardize **modeling and simulation** (M&S) of PBPK and QSP models implemented in [Open Systems Pharmacology Software](https://www.open-systems-pharmacology.org/) (OSPS) and executed from R. The package provides functions to read and run scenarios, workflows, and simulations. Furthermore, it creates visualizations based on non-code input from Excel files. The package is based on R functions in the [`ospsuite` package](https://github.com/Open-Systems-Pharmacology/OSPSuite-R). @@ -11,39 +11,40 @@ Utilities functions for modeling and simulation workflows within *esqLABS*. ## Installation -The latest version of the package comes as a binary `*.zip` and can be downloaded from here (the `.zip` folder under `Artifacts` panel): - - -## Required packages - -- rClr >0.9.1 - - https://github.com/Open-Systems-Pharmacology/rClr/releases/ or esqLABS internal -- ospsuite-r > 10.0 - - https://github.com/Open-Systems-Pharmacology/OSPSuite-R or esqLABS internal -- R6 (CRAN) -- readr (CRAN) -- readxl (CRAN) -- writexl (CRAN) -- hash (CRAN) -- shiny (CRAN) -- shinyjs (CRAN) -- vctrs (CRAN) - -### For building from source and developing - -- Rtools (https://cran.r-project.org/bin/windows/Rtools/) - - After installation, add the folder to your $PATH: In start menu, type in "PATH", select "Change path environment for user", and add the path to Rtools folder. -- roxygen2 (CRAN) -- devtools (CRAN) -- rmarkdown (CRAN) -- testthat (CRAN) -- knitr (CRAN) -- styler (CRAN) +Install as a binary file from [an AppVeyor link](https://ci.appveyor.com/project/StephanSchaller/esqlabsr/build/artifacts). The `{esqlabsR}` package requires the following packages: + +* Available from CRAN: + * colorspace, + * dplyr, + * ggplot2, + * purrr, + * readxl, + * shiny, + * shinyjs, + * tidyr, + * tools, + * vctrs, + * writexl, + * stringr, + * labeling + + +* Available from github: + * [rClr](https://github.com/Open-Systems-Pharmacology/rClr/) > 0.9.2 + * [ospsuite.utils](https://github.com/Open-Systems-Pharmacology/OSPSuite.RUtils) + * [tlf](https://github.com/Open-Systems-Pharmacology/TLF-Library) + * [ospsuite](https://github.com/Open-Systems-Pharmacology/OSPSuite-R) > 11.0 + * [ospsuite.parameteridentification](https://github.com/Open-Systems-Pharmacology/OSPSuite.ParameterIdentification) + +### For projects created for version 3 + +To run code written for version 3 of `esqlabsR` package, additionally install the +[esqlabsRLegacy](https://github.com/esqLABS/esqlabsRLegacy) package. ## Contributing -- Follow the OSPS-R [coding standards](https://github.com/Open-Systems-Pharmacology/Suite/blob/develop/CODING_STANDARDS_R.md) -- Some additional useful information can be found [here](https://github.com/Open-Systems-Pharmacology/OSPSuite-R/wiki/Developer-How-To's) +- Follow the OSPS-R [coding standards](https://github.com/Open-Systems-Pharmacology/Suite/blob/develop/CODING_STANDARDS_R.md). +- Some additional useful information can be found [here](https://github.com/Open-Systems-Pharmacology/OSPSuite-R/wiki/Developer-How-To's). ## Code of Conduct diff --git a/_pkgdown.yml b/_pkgdown.yml index 76392fdb..5168f3a9 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -12,14 +12,6 @@ authors: reference: - - title: R6 Classes - desc: Important objects for modeling and simulation and plotting workflows. - contents: - - matches("^Data") - - XYData - - Plotable - - PlotConfiguration - - title: Sensitivity analysis #desc: contents: @@ -27,10 +19,10 @@ reference: - title: Project workflow contents: - - contains("Configuration") + - contains("Project") - contains("Scenario") - - title: Helper functions for data import, wrangling, and export + - title: Helpers for data import, wrangling, and export #desc: contents: - matches("^read") @@ -39,13 +31,13 @@ reference: - matches("^write") - matches("^export") - - title: Helper functions for modeling and simulation + - title: Helpers for modeling and simulation #desc: contents: - matches("^compare") - matches("^calculate") - contains("Simulation") - - contains("Function") + - ends_with("Function") - contains("Quantiles") - matches("^geo") - sampleRandomValue @@ -54,13 +46,14 @@ reference: - LLOQMode - loadObservedData - - title: Helper functions for plotting + - title: Helpers for plotting #desc: contents: - matches("^plot") - matches("^col") - contains("color") - GraphicsDevices + - has_concept("create-plotting-configurations") - title: Input validation #desc: @@ -77,7 +70,7 @@ reference: contents: - matches("^start") - - title: Miscllaneous + - title: Miscellaneous #desc: contents: - matches("^enum") @@ -86,4 +79,4 @@ reference: - pathFromClipboard - removeFromList - sourceAll - + - esqlabsRSettingNames diff --git a/appveyor.yml b/appveyor.yml index f87c58ae..014b8508 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,12 +12,14 @@ install: - git submodule update --init --recursive environment: - app_version: "3.0" + app_version: "4.0" USE_RTOOLS: true - R_VERSION: "4.1.0" + R_VERSION: "4.2.0" R_ARCH: x64 KEEP_VIGNETTES: true NOT_CRAN: true + # We use this variale to skip some tests that depend on PK-Sim using "skip_on_ci" + # CI: true version: "$(app_version).{build}" @@ -52,11 +54,15 @@ before_test: build_script: - travis-tool.sh install_deps - travis-tool.sh r_binary_install curl - - Rscript -e "install.packages('https://github.com/Open-Systems-Pharmacology/rClr/releases/download/v0.9.1/rClr_0.9.1.zip', repos = NULL, type = 'binary')" + - Rscript -e "install.packages('https://github.com/Open-Systems-Pharmacology/rClr/releases/download/v0.9.2/rClr_0.9.2.zip', repos = NULL, type = 'binary')" - Rscript -e "install.packages('https://ci.appveyor.com/api/projects/open-systems-pharmacology-ci/ospsuite-r/artifacts/ospsuite.zip', repos = NULL, type = 'binary')" - - Rscript -e "install.packages(c('covr', 'readr', 'tidyr', 'ggplot2', 'patchwork', 'vdiffr'), repos = 'http://cran.us.r-project.org')" + # hard dependencies (Imports) + - Rscript -e "install.packages(c('FME', 'readr', 'tidyr', 'ggplot2', 'patchwork'), repos = 'http://cran.us.r-project.org')" + # soft dependencies (Suggests) + - Rscript -e "install.packages(c('covr', 'clipr', 'shinytest2', 'vdiffr', 'withr'), repos = 'http://cran.us.r-project.org')" - Rscript -e "install.packages('https://ci.appveyor.com/api/projects/open-systems-pharmacology-ci/ospsuite-rutils/artifacts/ospsuite.utils.zip', repos = NULL, type = 'binary')" - Rscript -e "install.packages('https://ci.appveyor.com/api/projects/open-systems-pharmacology-ci/tlf-library/artifacts/tlf.zip', repos = NULL, type = 'binary')" + - Rscript -e "install.packages('https://ci.appveyor.com/api/projects/open-systems-pharmacology-ci/ospsuite-parameteridentification/artifacts/ospsuite.parameteridentification.zip', repos = NULL, type = 'binary')" test_script: - travis-tool.sh run_tests diff --git a/docs/404.html b/docs/404.html index d6d51746..278ea93d 100644 --- a/docs/404.html +++ b/docs/404.html @@ -6,11 +6,18 @@ Page not found (404) • esqlabsR + + + + + + - - + + + Contributor Covenant Code of Conduct • esqlabsRContributor Covenant Code of Conduct • esqlabsR @@ -10,7 +10,7 @@ esqlabsR - 3.0.0 + 4.0.0 + + + + + +
+ + + + +
+
+ + + +
+

Workflow +

+

Plotting the simulation results is an important part of model +diagnostics and quality control. Simulated modeling scenarios can be +passed to plotting functions from the ospsuite package to +create uniformly-looking plots.

+

DataCombined is a class used to store matching observed +and simulated data. Initialize a new class instance and populate it with +data with the following code:

+
+dataCombined <- DataCombined$new()
+dataCombined$addDataSets(observedData, names = "Observed", groups = "Aciclovir")
+dataCombined$addSimulationResults(simulatedScenarios$TestScenario$results, names = "Simulated", groups = "Aciclovir")
+dataCombined$toDataFrame()
+#> # A tibble: 1,452 × 25
+#>    name     group    dataT…¹ xValues xUnit xDime…² yValues yUnit yDime…³ yErro…⁴
+#>    <chr>    <chr>    <chr>     <dbl> <chr> <chr>     <dbl> <chr> <chr>     <dbl>
+#>  1 Observed Aciclov… observ…   0.273 h     Time      2.37  mg/l  Concen…    0   
+#>  2 Observed Aciclov… observ…   0.485 h     Time      2.95  mg/l  Concen…    1.23
+#>  3 Observed Aciclov… observ…   0.758 h     Time      3.08  mg/l  Concen…    1.28
+#>  4 Observed Aciclov… observ…   1.15  h     Time      3.08  mg/l  Concen…    1.82
+#>  5 Observed Aciclov… observ…   1.61  h     Time      2.17  mg/l  Concen…    0   
+#>  6 Observed Aciclov… observ…   1.97  h     Time      1.93  mg/l  Concen…    0   
+#>  7 Observed Aciclov… observ…   3     h     Time      1.31  mg/l  Concen…    0   
+#>  8 Observed Aciclov… observ…   5.03  h     Time      0.732 mg/l  Concen…    0   
+#>  9 Observed Aciclov… observ…   7     h     Time      0.434 mg/l  Concen…    0   
+#> 10 Observed Aciclov… observ…  11.0   h     Time      0.164 mg/l  Concen…    0   
+#> # … with 1,442 more rows, 15 more variables: yErrorType <chr>,
+#> #   yErrorUnit <chr>, molWeight <dbl>, lloq <dbl>, Sheet <chr>,
+#> #   `Study Id` <chr>, `Subject Id` <chr>, Organ <chr>, Compartment <chr>,
+#> #   Species <chr>, Gender <chr>, Dose <chr>, Molecule <chr>, Route <chr>,
+#> #   IndividualId <int>, and abbreviated variable names ¹​dataType, ²​xDimension,
+#> #   ³​yDimension, ⁴​yErrorValues
+

The simulation results are stored in a list returned by the +runScenarios() function. Plotting and visualization is +performed by storing these results along with matching observed data in +a DataCombined object and passing it to plotting functions. +Observed data in the form of Data Set objects is added to a +DataCombined object via the addDataSets +method, simulated data can be added by using +addSimulationResults. Observed and simulated data can be +linked by setting the groups argument in both methods. Data +of the same group will then be plotted together when calling plotting +functions on the DataCombined object.

+

Plotting functions in the ospsuite package are +wrappers around tlf plotting functions that provide +default plot configuration options. All of them accept instances of +DataCombined class as the data source.

+

Time profile plots visualize the pharmacokinetics of the drug in +question and help assess if the observed data (represented by points and +error bars) match the simulated data (represented by lines).

+
+plotIndividualTimeProfile(dataCombined)
+#> Warning: Removed 8 rows containing missing values (geom_segment).
+#> Removed 8 rows containing missing values (geom_segment).
+

+

Observed versus simulated plots show if simulated time points and +observed time points follow a linear trend.

+
+plotObservedVsSimulated(dataCombined)
+

+

Residual plots show if there is a systematic bias in how the +simulation represents values either in high-concentration or +low-concentration regions, or, alternatively, in early or late time +periods.

+
+plotResidualsVsSimulated(dataCombined)
+

+
+plotResidualsVsTime(dataCombined)
+

+

The plots returned by plotting functions are ggplot +objects. They can be modified further and saved to files with +ggplot2 functions:

+
+plotObject <- plotIndividualTimeProfile(dataCombined)
+ggplot2::ggsave(filename = "../Results/aciclovir_time_profile.png", plotObject, width = 8, height = 4)
+#> Warning: Removed 8 rows containing missing values (geom_segment).
+#> Removed 8 rows containing missing values (geom_segment).
+
+
+

Troubleshooting +

+
    +
  • At any time, you can check the groups assigned to the datasets in +the DataCombined object by examining the output of +dataCombined$toDataFrame().
  • +
+

More detailed information on function signatures can be found in:

+ +
+
+
+ + + +
+ + + +
+
+ + + + + + + diff --git a/docs/articles/example-visualization_files/figure-html/plot-obs-vs-pred-1.png b/docs/articles/example-visualization_files/figure-html/plot-obs-vs-pred-1.png new file mode 100644 index 00000000..f126efa6 Binary files /dev/null and b/docs/articles/example-visualization_files/figure-html/plot-obs-vs-pred-1.png differ diff --git a/docs/articles/example-visualization_files/figure-html/plot-time-profile-1.png b/docs/articles/example-visualization_files/figure-html/plot-time-profile-1.png new file mode 100644 index 00000000..ce516c5b Binary files /dev/null and b/docs/articles/example-visualization_files/figure-html/plot-time-profile-1.png differ diff --git a/docs/articles/example-visualization_files/figure-html/residuals-vs-simulated-1.png b/docs/articles/example-visualization_files/figure-html/residuals-vs-simulated-1.png new file mode 100644 index 00000000..c6e7c701 Binary files /dev/null and b/docs/articles/example-visualization_files/figure-html/residuals-vs-simulated-1.png differ diff --git a/docs/articles/example-visualization_files/figure-html/residuals-vs-time-1.png b/docs/articles/example-visualization_files/figure-html/residuals-vs-time-1.png new file mode 100644 index 00000000..039b4677 Binary files /dev/null and b/docs/articles/example-visualization_files/figure-html/residuals-vs-time-1.png differ diff --git a/docs/articles/example-workflow.html b/docs/articles/example-workflow.html index d223dde5..c6a8ac76 100644 --- a/docs/articles/example-workflow.html +++ b/docs/articles/example-workflow.html @@ -6,13 +6,20 @@ -Exemplary workflow • esqlabsR +Running simulations • esqlabsR + + + + + + - - + + - + + Articles • esqlabsRArticles • esqlabsR @@ -10,7 +10,7 @@ esqlabsR - 3.0.0 + 4.0.0 - - - - - -
- - - - -
-
- - - -
-

Introduction -

-

The package provides a set of functions designed to streamline -processes that frequently occur in Modeling and simulation (M&S) -workflows projects.

-
-
-
- - - -
- - - -
-
- - - - - - - diff --git a/docs/articles/sensitivity-analysis.html b/docs/articles/sensitivity-analysis.html new file mode 100644 index 00000000..b8decb27 --- /dev/null +++ b/docs/articles/sensitivity-analysis.html @@ -0,0 +1,207 @@ + + + + + + + + +Sensitivity analysis • esqlabsR + + + + + + + + + + + + + + + + + Skip to contents + + +
+ + + + +
+
+ + + +
+

Workflow +

+

Sensitivity analysis quantifies how the pharmacokinetics of the drug +changes with a variation in simulation parameters. This is important to +track if the values of simulation parameters are uncertain.

+

In the aciclovir simulation example, the lipophilicity of aciclovir +was assumed to be -0.100 in log units. In the sensitivity analysis, we +want to quantify how much the pharmacokinetic parameters change if the +lipophilicity of aciclovir is varied by certain factors.

+

The sensitivityCalculation() function in the +esqlabsR package does that by re-running the simulation +with a set of updated parameter values. By default, the parameter will +be multiplied by 0.1, 0.2, 0.3, …, 1, 2, 3, … and 10, and for each value +a simulation will be run. These factors can be customized by the +variationRange argument. The function returns a list with +output paths, parameter paths, a SimulationResults object, +and a data frame with computed pharmacokinetic parameters for each of +the input parameter values.

+
+simulation <- simulatedScenarios$TestScenario$simulation
+OutputPaths <- enum(list(
+  Aciclovir_PVB = "Organism|PeripheralVenousBlood|Aciclovir|Plasma (Peripheral Venous Blood)"
+))
+analysis <- sensitivityCalculation(simulation, OutputPaths, parameterPaths = "Aciclovir|Lipophilicity")
+head(analysis$pkData)
+#> # A tibble: 6 × 9
+#>   OutputPath       Param…¹ Param…² Param…³ PKPar…⁴ PKPar…⁵ Unit  Perce…⁶ Sensi…⁷
+#>   <chr>            <chr>     <dbl>   <dbl> <chr>     <dbl> <chr>   <dbl>   <dbl>
+#> 1 Organism|Periph… Aciclo…     0.1   -0.01 AUC_inf   3896. µmol…  -0.522 5.83e-4
+#> 2 Organism|Periph… Aciclo…     0.2   -0.02 AUC_inf   3898. µmol…  -0.461 1.16e-3
+#> 3 Organism|Periph… Aciclo…     0.3   -0.03 AUC_inf   3900. µmol…  -0.401 1.73e-3
+#> 4 Organism|Periph… Aciclo…     0.4   -0.04 AUC_inf   3903. µmol…  -0.342 2.29e-3
+#> 5 Organism|Periph… Aciclo…     0.5   -0.05 AUC_inf   3905. µmol…  -0.283 2.84e-3
+#> 6 Organism|Periph… Aciclo…     0.6   -0.06 AUC_inf   3907. µmol…  -0.225 3.38e-3
+#> # … with abbreviated variable names ¹​ParameterPath, ²​ParameterFactor,
+#> #   ³​ParameterValue, ⁴​PKParameter, ⁵​PKParameterValue, ⁶​PercentChangePK,
+#> #   ⁷​SensitivityPKParameter
+

In the aciclovir example case, the default value of lipophilicity was +-0.100 log units, corresponding to the area under curve (AUC) of 3915.87 +µmol×min/L. Changing the lipophilicity to -0.01 log units leads to a +decrease of AUC to 3895.43 µmol×min/L (a change of -0.52%), while +changing the lipophilicity to -1.00 log units leads to an increase of +AUC to 4015.73 µmol×min/L (a change of 2.55%).

+

The results of the sensitivity analysis can be plotted with two +functions:

+
    +
  • the sensitivitySpiderPlot() function shows a separate +plot for each of the pharmacokinetic parameters under investigation. By +default, the sensitivityCalculation() function computes the +changes in area under curve (AUC_inf), maximum +concentration (C_max) and time when the maximum +concentration is reached (t_max).
  • +
+
+sensitivitySpiderPlot(analysis)
+#> [1] "Creating plot for path: Organism|PeripheralVenousBlood|Aciclovir|Plasma (Peripheral Venous Blood)"
+

+ +
+sensitivityTimeProfiles(analysis)
+#> [1] "Creating plot for path: Organism|PeripheralVenousBlood|Aciclovir|Plasma (Peripheral Venous Blood)"
+

+
+
+

Troubleshooting +

+
    +
  • The SensitivityPKParameter column in the output of +analysis$pkData will be NA in the rows +corresponding to the initial parameter values.
  • +
+

More detailed information on function signatures can be found in:

+ +
+
+
+ + + +
+ + + +
+
+ + + + + + + diff --git a/docs/articles/sensitivity-analysis_files/figure-html/spider-plot-1.png b/docs/articles/sensitivity-analysis_files/figure-html/spider-plot-1.png new file mode 100644 index 00000000..1ed87dd0 Binary files /dev/null and b/docs/articles/sensitivity-analysis_files/figure-html/spider-plot-1.png differ diff --git a/docs/articles/sensitivity-analysis_files/figure-html/time-profile-1.png b/docs/articles/sensitivity-analysis_files/figure-html/time-profile-1.png new file mode 100644 index 00000000..8983c8fb Binary files /dev/null and b/docs/articles/sensitivity-analysis_files/figure-html/time-profile-1.png differ diff --git a/docs/articles/helper-methods.html b/docs/articles/shiny-apps.html similarity index 50% rename from docs/articles/helper-methods.html rename to docs/articles/shiny-apps.html index 5f458d87..b60cb7e6 100644 --- a/docs/articles/helper-methods.html +++ b/docs/articles/shiny-apps.html @@ -6,13 +6,20 @@ -Helper methods • esqlabsR +Using the esqlabsR Shiny apps • esqlabsR + + + + + + - - + + - + + + + + + + + +Standard workflow • esqlabsR + + + + + + + + + + + + + + + + + Skip to contents + + +
+ + + + +
+
+ + + +
+

Defining scenarios +

+

Within the esqlabsR framework, the simulations are run +by defining and executing multiple scenarios. A scenario is +defined by the simulation file containing the model structure, +parametrization of the model, application protocol, and (optionally) the +physiology of the simulated individual or population. To simplify +scenarios set up, all these information are stored in excel files with +defined structure.

+

Information about location of scenario definition files, simulation +files, output folders etc. is stored in excel file +ProjectConfiguration.xlsx located in the folder +Code. Usually it is not required to edit the contents of +this file.

+

The first step in the workflow is to create a +ProjectConfiguration from this file that will be used by +the scripts to know where to find the required data (for all following +examples, we assume that the current working directory is the +Code folder):

+
+projectConfiguration <- createDefaultProjectConfiguration()
+print(projectConfiguration)
+#> ProjectConfiguration: 
+#>    Model folder: ../Models 
+#>    Parameters folder: ../Parameters 
+#>    Parameters file name: ModelParameters.xlsx 
+#>    Individual parameters file name: IndividualParameters.xlsx 
+#>    Individual physiology file name: IndividualPhysiology.xlsx 
+#>    Population parameters file name: PopulationParameters.xlsx 
+#>    Scenario definitions file name: Scenarios.xlsx 
+#>    Scenario applications definitions file name: ApplicationParameters.xlsx 
+#>    Experimental data folder: ../Data 
+#>    Experimental data file: TestProject_TimeValuesData.xlsx 
+#>    Data importer configuration: esqlabs_dataImporter_configuration.xml 
+#>    Output folder: ../Results 
+#>    Output device:
+

Next, we will define a scenario that we want to simulate in +the excel file Parameters/Scenarios.xlsx (or other as set +in projectConfiguration$scenarioDefinitionFile). The +package includes an +example scenario that models the administration of a single dose of +250 mg aciclovir intravenously to an individual with a 90 ml/min +estimated glomerular filtration rate. To define a scenario, create a new +row in the Scenarios.xlsx file with the following +content:

+
    +
  • Scenario_name: unique name of the scenario. The +name must be a valid +R variables name.

  • +
  • IndividualId: Name (ID) of an individual. This +name refers to the name of the individual as used in excel files +IndividualPhysiology.xlsx for definition of the biometric +properties of the simulated individual and +IndividualParameters.xlsx for definition of +individual-specific model parameters. IndividualId may +be empty. In this case, standard individual as defined in the +pkml simulation without any individual-specific model +parameters will be simulated. To create an individual with specific +biometric characteristics, define an entry with the same individual id +in the file IndividualPhysiology.xlsx. The same individual +can be used in multiple scenarios. Note that though it is technically +possible to apply a species different from the one in the original +simulation, the correctness of the results is not guaranteed as there +exist some structural differences between the species.

  • +
  • ModelParameterSheets: A list of sheet names from +the ModelParameter.xlsx file, separated by a +,. Each sheet must have the columns +Container Path, Parameter Name, +Value, and Units. Parameter values from +specified sheets will be applied to the model in the order of their +definition. E.g., if we define Global, Aciclovir, then +parameters from the Aciclovir sheet will be applied after +the Global parameters. +ModelParameterSheets may be empty or specify as many +sheets as required. Note that the specified sheets must be present in +the ModelParameter.xlsx file. The purpose of this approach +is to have global parameters that can be applied to most +scenarios, and separate set of parameters for e.g. different disease +states (parameter sheets Healthy and +CKD), or separate parametrization of different +compounds (sheet Aciclovir).
    +We can further refine the parametrization of the scenario by specifying +the individual parameters in the IndividualParameters.xlsx +file. Create a sheet with the name as the IndividualId +specified for the respective scenario and populate it the same structure +as the ModelParameters.xlsx file. This way we can define +e.g. individual-specific clearance values or, as in our case, the +glomerular filtration rate. Individual specific parameters are applied +after the parameters defined in the ModelParameterSheets. We +can use an individual in multiple scenarios. If an individual is +specified in the scenario definition, but no sheet with this name exists +in the IndividualParameters.xlsx file, this step is simply +ignored.

  • +
  • ApplicationProtocol: name of the application +protocol that will be applied. Applications are defined as a set of +parameters that will be applied to the model in the file +ApplicationParameters.xlsx. For each application, create a +sheet with the name as specified in the +ApplicationProtocol entry and populate it with the same +structure as the ModelParameter.xlsx file… Configuring +application protocols this way requires that the loaded simulation +includes all possible applications that can be turned on and off by +setting parameters, e.g. the Dose or +Start time parameters. As it might be cumbersome to +manually create entries for all administration parameters, we can use +the getAllApplicationParameters() function to get a list of +all (constant) parameters located in the Applications +container. In the following example, we will extract application +parameters for the molecule Aciclovir from the example +simulation:

  • +
+
+sim <- loadSimulation(system.file("extdata", "Aciclovir.pkml", package = "ospsuite"))
+applicationParams <- getAllApplicationParameters(sim)
+print(applicationParams)
+#> [[1]]
+#> Parameter: 
+#>    Path: Applications|IV 250mg 10min|Application_1|ProtocolSchemaItem|Start time 
+#>    Value: 0.00 [min] 
+#>    isConstant: TRUE 
+#>    isStateVariable: FALSE 
+#> 
+#> [[2]]
+#> Parameter: 
+#>    Path: Applications|IV 250mg 10min|Application_1|ProtocolSchemaItem|Dose 
+#>    Value: 0.00 [kg] 
+#>    isConstant: TRUE 
+#>    isStateVariable: FALSE 
+#> 
+#> [[3]]
+#> Parameter: 
+#>    Path: Applications|IV 250mg 10min|Application_1|ProtocolSchemaItem|DosePerBodySurfaceArea 
+#>    Value: 0.00 [kg/dm²] 
+#>    isConstant: TRUE 
+#>    isStateVariable: FALSE 
+#> 
+#> [[4]]
+#> Parameter: 
+#>    Path: Applications|IV 250mg 10min|Application_1|ProtocolSchemaItem|DosePerBodyWeight 
+#>    Value: 0.00 [kg/kg] 
+#>    isConstant: TRUE 
+#>    isStateVariable: FALSE 
+#> 
+#> [[5]]
+#> Parameter: 
+#>    Path: Applications|IV 250mg 10min|Application_1|ProtocolSchemaItem|Infusion time 
+#>    Value: 10.00 [min] 
+#>    isConstant: TRUE 
+#>    isStateVariable: FALSE
+

and export the parameters to an excel file using the +exportParametersToXLS() function:

+
+exportParametersToXLS(parameters = applicationParams, paramsXLSpath = "../Applications.xlsx")
+

The created excel file will have the same structure as all +Parameter-files and can be directly loaded in MoBi or R using the +readParametersFromXLS() function.

+
    +
  • SimulationTime: Time of the simulation. The output +intervel of the simulation will be set to the range [0 - +SimulationTime] with the resolution of 1 point per +minute.

  • +
  • SimulationTimeUnit: Unit for +SimulationTime. For supported units, see +ospsuite::ospUnits.

  • +
  • SteadyState: If TRUE, the model +will be simulated for a “sufficiently long” time (1000 minutes by +default). The steady-state time can be specified in the +ScenarioConfiguration (see Section Running scenarios).

  • +
  • ModelFile: Name of the pkml file +with the simulation. Must be located in the folder defined in +ProjectConfiguration$modelFolder.

  • +
+
+
+

Running scenarios +

+

To translate all the information we have defined in the excel files +in a structure that can be understood by R, we must create +a

+

Scenarios are then executed by creating a +ScenarioConfiguration object and calling a +runScenarios() function with a specific scenario name +(TestScenario in this case):

+
+scenarioConfiguration <- ScenarioConfiguration$new(projectConfiguration)
+OutputPaths <- enum(list(
+  Aciclovir_PVB = "Organism|PeripheralVenousBlood|Aciclovir|Plasma (Peripheral Venous Blood)"
+))
+simulatedScenarios <- runScenarios(
+  scenarioNames = c("TestScenario"),
+  scenarioConfiguration = scenarioConfiguration,
+  customParams = NULL, saveSimulationsToPKML = FALSE
+)
+

The runScenarios() function relies on an +OutputPaths variable being defined in the current +environment. The variable is expected to contain path(s) to outputs +generated by the model. In our case this is the simulated concentration +of Aciclovir in the peripheral venous blood plasma.

+

The runScenarios() function returns a named list of +lists with Simulation objects, +SimulationResults objects, and vectors of output +values.

+
+print(simulatedScenarios$TestScenario$results)
+#> SimulationResults: 
+#>    Number of individuals: 1
+
+print(head(simulatedScenarios$TestScenario$outputValues$data))
+#>   IndividualId Time
+#> 1            0    0
+#> 2            0    1
+#> 3            0    2
+#> 4            0    3
+#> 5            0    4
+#> 6            0    5
+#>   Organism|PeripheralVenousBlood|Aciclovir|Plasma (Peripheral Venous Blood)
+#> 1                                                                  0.000000
+#> 2                                                                  2.713168
+#> 3                                                                  7.830613
+#> 4                                                                 13.109206
+#> 5                                                                 18.258501
+#> 6                                                                 23.242720
+
+
+

Troubleshooting +

+
    +
  • The runScenarios() function will fail if the +OutputPaths variable is missing in the current environment. +Make sure to have this variable set up immediately before calling the +runScenarios() function.
  • +
+

More detailed information on function signatures can be found in:

+ +
+
+
+ + + +
+ + + +
+
+ + + + + + + diff --git a/docs/authors.html b/docs/authors.html index 67f221be..58e15084 100644 --- a/docs/authors.html +++ b/docs/authors.html @@ -1,5 +1,5 @@ -Authors and Citation • esqlabsRAuthors and Citation • esqlabsR @@ -10,7 +10,7 @@ esqlabsR - 3.0.0 + 4.0.0 - - - - - -
-
-
- -
-

An object storing configuration of for observed data import

-
- - -
-

Super class

-

ospsuite.utils::Printable -> DataConfiguration

-
-
-

Public fields

-

dataFolder
-

Path to the directory where the data file is located

- - -
dataFile
-

Name of the data excel file

- - -
compoundPropertiesFile
-

Name of the excel file with compound properties

- - -
dataSheets
-

Name of excel sheets to read

- - -
columnsToSplitBy
-

Column names by which the data will be split into groups

- - -
XValuesColumn
-

Column index for x values in observed data files

- - -
YValuesColumn
-

Column index for y values in observed data files

- - -
YErrorColumn
-

Column index for y error values in observed data files

- - -

-
-
-

Methods

- -

Inherited methods


    -

    Method new()

    -

    Initialize a new instance of the class

    -

    Usage

    -

    DataConfiguration$new(dataFolder, dataFile, compoundPropertiesFile, dataSheets)

    -
    - -
    -

    Arguments

    -

    dataFolder
    -

    Path to the directory where the data file is located

    - - -
    dataFile
    -

    Name of the data excel file

    - - -
    compoundPropertiesFile
    -

    Name of the excel file with compound properties

    - - -
    dataSheets
    -

    Name of excel sheets to read

    - - -

    -
    -
    -

    Returns

    -

    A new DataConfiguration object.

    -
    - -


    -

    Method print()

    -

    Print the object to the console

    -

    Usage

    -

    DataConfiguration$print(...)

    -
    - -
    -

    Arguments

    -

    ...
    -

    Rest arguments.

    - - -

    -
    - -
    - -
    - -
    - - -
    - - - -
    - - - - - - - diff --git a/docs/reference/DataMapping.html b/docs/reference/DataMapping.html deleted file mode 100644 index d44cb741..00000000 --- a/docs/reference/DataMapping.html +++ /dev/null @@ -1,661 +0,0 @@ - -DataMapping — DataMapping • esqlabsR - Skip to contents - - -
    -
    -
    - -
    -

    Mapping of model outputs to observed data

    -
    - - -
    -

    Super class

    -

    ospsuite.utils::Printable -> DataMapping

    -
    -
    -

    Public fields

    -

    log
    -

    String defining which axis will be plotted in logarithmic scaling. -Possible values are "" (empty string, both axis in linear scaling, default), -"x", "y", "xy" (both axis are in logarithmic scaling).

    - - -
    title
    -

    Title of the plot. If the value is an empty string, no title is added. Otherwise, the title appears on top of the plot.

    - - -
    addLegend
    -

    Boolean defining if the legend should be added to the plot. If TRUE, -a legend will be added for each group and each XYSeries that is not in any group

    - - -
    legendPosition
    -

    Position of the legend in the plot. Default value is "topright". See legend() for more information.

    - - -

    -
    -
    -

    Active bindings

    -

    xySeries
    -

    Named list with the XYData -that will be plotted. Names are the labels of the xySeries objects

    - - -
    xySeriesCount
    -

    number of XYData objects to be plotted

    - - -
    xLim
    -

    Limits of the x-axis. Numerical vector c(min, max)

    - - -
    yLim
    -

    Limits of the y-axis. Numerical vector c(min, max)

    - - -
    xLab
    -

    label of the x-axis.

    - - -
    yLab
    -

    label of the y-axis.

    - - -
    xDimension
    -

    Dimension of x values. See enum ospDimensions for the list of supported dimensions. -If no dimension is specified, the dimension of the first added XYSeries is used. -If no XYSeries are present, the dimension is NULL -When changing the dimension, the unit is automatically set to the base unit of the dimension.

    - - -
    yDimension
    -

    Dimension of y values. See enum ospDimensions for the list of supported dimensions. -If no dimension is specified, the dimension of the first added XYSeries is used. -If no XYSeries are present, the dimension is NULL -#' When changing the dimension, the unit is automatically set to the base unit of the dimension.

    - - -
    xUnit
    -

    Unit of x values. -If no unit is specified, the default unit of the dimension is used. -If no dimension is specified, the unit is NULL

    - - -
    yUnit
    -

    Unit of y values. -If no unit is specified, the default unit of the dimension is used. -If no dimension is specified, the unit is NULL

    - - -
    groupings
    -

    A named list listing which data sets are grouped together. Grouped data sets will be plotted with the same color -and used together in the legend.

    - - -
    ungroupedSeries
    -

    A list of XYData that do not belong to any group. -NULL if empty.

    - - -
    plotType
    -

    A string defining what kind of plot is generated when the plot() method of the object is called. -Supported plot types are listed in the enum PlotTypes. Default is "IndividualProfile"

    - - -
    populationQuantiles
    -

    A numerical vector with three quantile values used if plotType = "PopulationQuantiles". Default is -c(0.05, 0.5, 0.95)

    - - -

    -
    -
    -

    Methods

    - -

    Inherited methods


      -

      Method new()

      -

      Initialize a new instance of the class

      -

      Usage

      -

      -
      - -
      -

      Returns

      -

      A new DataMapping object.

      -
      - -


      -

      Method finalize()

      -

      Clean up upon object removal

      -

      Usage

      -

      DataMapping$finalize()

      -
      - - -


      -

      Method addModelOutputs()

      -

      Add simulated results to the data mapping

      - -

      Add new ModelOutput to be plotted. Line type is set to "l" (line) by default.

      -

      Usage

      -

      DataMapping$addModelOutputs(
      -  paths,
      -  labels,
      -  simulationResults,
      -  groups = NULL,
      -  removeNA = TRUE
      -)

      -
      - -
      -

      Arguments

      -

      paths
      -

      A string or a list of strings representing the path(s) to the output(s) in the model.

      - - -
      labels
      -

      A string or a list of strings that are used as a label (e.g. in the legend) for the output(s). -If NULL (default), the path of the output is used as a label.

      - - -
      simulationResults
      -

      Simulated results as returned by runSimulation

      - - -
      groups
      -

      A string or a list of strings assigning the outputs to a group. All outputs may be assigned to one group, or to -different groups, while each output can be assigned to not more than one group. If an entry within the list is NULL, the corresponding -output is not assigned to any group

      - - -
      removeNA
      -

      If TRUE (default), NA values will be removed from the simulated results. NA values can be the result of observer not being calculated at a certain time point.

      - - -

      -
      - -


      -

      Method addXYSeries()

      -

      Add XYData object(s).

      -

      Usage

      -

      DataMapping$addXYSeries(
      -  xValsList,
      -  yValsList,
      -  labels,
      -  yErrorList = NULL,
      -  groups = NULL
      -)

      -
      - -
      -

      Arguments

      -

      xValsList
      -

      A single array or a list of arrays of x-values. For time series, the values must be in minutes.

      - - -
      yValsList
      -

      A single array or a list of arrays of y-values.

      - - -
      labels
      -

      A string or a list of strings that are used as unique label for the output(s). Must be of same length as xValsList.

      - - -
      yErrorList
      -

      A single array or a list of arrays of y-error values. If NULL (default), no errors are -assigned. If not NULL, the list must have the same number of entries (numerical arrays) as yValsList. If an entry of the list is NULL, the respective data set has no error.

      - - -
      groups
      -

      A string or a list of strings assigning the data set to a group. If an entry within the list is NULL, the corresponding data set is not assigned to any group. If NULL (default), all data sets are not assigned to any group. If provided, groups must have the same length as xValsList

      - - -

      -
      -
      -

      Details

      -

      Add new series of x-y values to be plotted. If an XYData with the same label already exists, -it will be overwritten

      -
      - -
      -

      Examples

      -

      dataMapping <- DataMapping$new()
      -xVals <- list(c(1, 2, 3, 4), c(1, 2, 3, 4), c(2, 3, 4, 5))
      -yVals <- list(c(5, 6, 7, 8), c(5, 6, 7, 8), c(6, 7, 8, 9))
      -yErr <- list(c(0.1, 0.1, 0.1, 0.2), NULL, c(0.2, 0.3, 0.1, 0.2))
      -groups <- list("Group1", NULL, "Group1")
      -dataMapping$addXYSeries(xValsList = xVals, yValsList = yVals,
      -yErrorList = yErr, labels = list("my series1", "my series2", "my series3"), groups = groups)

      -
      - - -


      -

      Method addXYData()

      -

      Add XYData object(s). The objects are cloned at adding.

      -

      Usage

      -

      DataMapping$addXYData(XYData, groups = NULL)

      -
      - -
      -

      Arguments

      -

      XYData
      -

      Object or a list of objects of the type XYData

      - - -
      groups
      -

      A string or a list of strings assigning the data set to a group. If an entry within the list is NULL, the corresponding data set is not assigned to any group. If NULL (default), all data sets are not assigned to any group. If provided, groups must have the same length as XYData -output is not assigned to any group

      - - -

      -
      - -


      -

      Method addDataSets()

      -

      Add DataSet object(s).

      -

      Usage

      -

      DataMapping$addDataSets(dataSets, groups = NULL)

      -
      - -
      -

      Arguments

      -

      dataSets
      -

      Object or a list of objects of the type DataSet

      - - -
      groups
      -

      A string or a list of strings assigning the data set to a group. If an entry within the list is NULL, the corresponding data set is not assigned to any group. If NULL (default), all data sets are not assigned to any group. If provided, groups must have the same length as dataSets -output is not assigned to any group

      - - -

      -
      -
      -

      Details

      -

      The objects are transformed to XYData before adding.

      -
      - - -


      -

      Method removeXYSeries()

      -

      Remove the observed data with given label from the DataMapping.

      -

      Usage

      -

      DataMapping$removeXYSeries(label)

      -
      - -
      -

      Arguments

      -

      label
      -

      label of the x-y values series to be removed

      - - -

      -
      - -


      -

      Method getXYSeriesGroupMap()

      -

      Return group mapping of labels.

      -

      Usage

      -

      DataMapping$getXYSeriesGroupMap()

      -
      - -
      -

      Details

      -

      Returns a named list with keys being labels of xySeries and values group names. If value is NA, no group is defined for this label.

      -
      - -
      -

      Returns

      -

      A named list with keys being labels of xySeries and values group names.

      -
      - -


      -

      Method setXFactors()

      -

      Set the X-factors of x-y values by labels.

      -

      Usage

      -

      DataMapping$setXFactors(labels, xFactors)

      -
      - -
      -

      Arguments

      -

      labels
      -

      A list of labels of XYData.

      - - -
      xFactors
      -

      Numeric values that will be multiplied by the x-values during plotting.

      - - -

      -
      -
      -

      Details

      -

      If the data set with a label is not present in the mapping, the label is ignored.

      -
      - - -


      -

      Method setYFactors()

      -

      Set the y-factors of x-y values by labels.

      -

      Usage

      -

      DataMapping$setYFactors(labels, yFactors)

      -
      - -
      -

      Arguments

      -

      labels
      -

      A list of label of XYData

      - - -
      yFactors
      -

      Numeric values that will be multiplied by the y-values during plotting

      - - -

      -
      -
      -

      Details

      -

      If the data set with a label is not present in the mapping, the label is ignored

      -
      - - -


      -

      Method setXOffsets()

      -

      Set the X-offset of x-y values by labels.

      -

      Usage

      -

      DataMapping$setXOffsets(labels, xOffsets)

      -
      - -
      -

      Arguments

      -

      labels
      -

      A list of label of XYData

      - - -
      xOffsets
      -

      Numeric values that will be added to the x-values during plotting

      - - -

      -
      -
      -

      Details

      -

      If the data set with a label is not present in the mapping, the label is ignored

      -
      - - -


      -

      Method setYOffsets()

      -

      Set the Y-offset of x-y values by labels.

      -

      Usage

      -

      DataMapping$setYOffsets(labels, yOffsets)

      -
      - -
      -

      Arguments

      -

      labels
      -

      A list of label of XYData

      - - -
      yOffsets
      -

      Numeric values that will be added to the y-values during plotting

      - - -

      -
      -
      -

      Details

      -

      If the data set with a label is not present in the mapping, the label is ignored

      -
      - - -


      -

      Method setTypes()

      -

      Set the type(s) of the data to be plotted, e.g. line, points, etc.

      -

      Usage

      -

      DataMapping$setTypes(labels, types)

      -
      - -
      -

      Arguments

      -

      labels
      -

      A list of label of XYData

      - - -
      types
      -

      Plot types as accepted by the base plot method

      - - -

      -
      -
      -

      Details

      -

      If no data set for the provided label is present in the mapping, the corresponding value is ignored. -No check is performed whether a valid type is provided.

      -
      - - -


      -

      Method setLinetypes()

      -

      Set the line type(s) property of the data to be plotted. Line types as accepted by the base plot lty argument.

      -

      Usage

      -

      DataMapping$setLinetypes(labels, linetypes)

      -
      - -
      -

      Arguments

      -

      labels
      -

      A list of label of XYData

      - - -
      linetypes
      -

      Values that will be set as line type(s).

      - - -

      -
      -
      -

      Details

      -

      If no data set for the provided label is present in the mapping, the corresponding value is ignored. -No check is performed whether a valid type is provided.Line types as accepted by the base plot lty argument. -Line types can be provided either as numeric or as character vectors (e.g. "dashed").

      -
      - - -


      -

      Method setColors()

      -

      Set the colors of the data to be plotted

      -

      Usage

      -

      DataMapping$setColors(labels, colors)

      -
      - -
      -

      Arguments

      -

      labels
      -

      A list of label of XYData

      - - -
      colors
      -

      String names of colors of the data as accepted by the base plot method -If the value is NULL, the color is automatically selected when plotting the data.

      - - -

      -
      -
      -

      Details

      -

      If the data set with a label is not present in the mapping, the label is ignored

      -
      - - -


      -

      Method setConfiguration()

      -

      Apply settings stored in a DataMappingConfiguration

      -

      Usage

      -

      DataMapping$setConfiguration(dataMappingConfiguration)

      -
      - -
      -

      Arguments

      -

      dataMappingConfiguration
      -

      An object of type DataMappingConfiguration

      - - -

      -
      -
      -

      Details

      -

      If the data set with a label is not present in the mapping, the label is ignored -Equivalent to calling setXFactors, setYFactors, setXOffsets, -setYOffsets, setTypes, and setColors.

      -
      - - -


      -

      Method plot()

      -

      Plot the data stored in this DataMapping.

      -

      Usage

      -

      DataMapping$plot(...)

      -
      - -
      -

      Arguments

      -

      ...
      -

      Any parameter that can be interpreted by the default plot() function

      - - -

      -
      - -


      -

      Method print()

      -

      Print the object to the console

      -

      Usage

      -

      DataMapping$print(...)

      -
      - -
      -

      Arguments

      -

      ...
      -

      Rest arguments.

      - - -

      -
      - -
      - -
      - -
      -

      Examples

      -
      
      -## ------------------------------------------------
      -## Method `DataMapping$addXYSeries`
      -## ------------------------------------------------
      -
      -dataMapping <- DataMapping$new()
      -xVals <- list(c(1, 2, 3, 4), c(1, 2, 3, 4), c(2, 3, 4, 5))
      -yVals <- list(c(5, 6, 7, 8), c(5, 6, 7, 8), c(6, 7, 8, 9))
      -yErr <- list(c(0.1, 0.1, 0.1, 0.2), NULL, c(0.2, 0.3, 0.1, 0.2))
      -groups <- list("Group1", NULL, "Group1")
      -dataMapping$addXYSeries(xValsList = xVals, yValsList = yVals,
      -yErrorList = yErr, labels = list("my series1", "my series2", "my series3"), groups = groups)
      -
      -
      -
      - - -
      - - - -
      - - - - - - - diff --git a/docs/reference/DataMappingConfiguration.html b/docs/reference/DataMappingConfiguration.html deleted file mode 100644 index 1e037dab..00000000 --- a/docs/reference/DataMappingConfiguration.html +++ /dev/null @@ -1,321 +0,0 @@ - -DataMappingConfiguration — DataMappingConfiguration • esqlabsR - Skip to contents - - -
      -
      -
      - -
      -

      An object storing configuration of a data mapping

      -
      - - -
      -

      Super class

      -

      ospsuite.utils::Printable -> DataMappingConfiguration

      -
      -
      -

      Active bindings

      -

      xFactors
      -

      A named list listing numerical values that x-values are -multiplied by. Keys are names of data sets, values are numerical -factors.

      - - -
      yFactors
      -

      A named list listing numerical values that y-values are multiplied by. Keys are names of data sets, -values are numerical factors.

      - - -
      xOffsets
      -

      A named list listing numerical values that will be added -to the x-values. Keys are names of data sets, values are numerical -values

      - - -
      yOffsets
      -

      A named list listing numerical values that will be added -to the y-values. Keys are names of data sets, values are numerical -values

      - - -
      lineTypes
      -

      A named list listing line types that will be used to -plot a certain data set. Keys are names of data sets, values are -numerical values recognized by the lty argument of the plot() -function

      - - -
      colors
      -

      A named list listing color values that will be used to plot -a certain data set. Keys are names of data sets, values are values -recognized by the col argument of the plot() function

      - - -

      -
      -
      -

      Methods

      - -

      Inherited methods


        -

        Method new()

        -

        Initialize a new instance of the class

        -

        Usage

        -

        -
        - -
        -

        Returns

        -

        A new DataMappingConfiguration object.

        -
        - -


        -

        Method finalize()

        -

        Clean up upon object removal

        -

        Usage

        -

        DataMappingConfiguration$finalize()

        -
        - - -


        -

        Method setXFactors()

        -

        Set the values of x-factors. An x-factor will be multiplied -by the x-values of the data set.

        -

        Usage

        -

        DataMappingConfiguration$setXFactors(labels, xFactors)

        -
        - -
        -

        Arguments

        -

        labels
        -

        A string or a list of strings representing the names of the -data sets

        - - -
        xFactors
        -

        A numerical value or a list of numerical values -representing the x-factors. Both lists must be of same length and store -the entries in the same order.

        - - -

        -
        - -


        -

        Method setYFactors()

        -

        Set the values of y-factors. A y-factor will be multiplied -by the y-values of the data set.

        -

        Usage

        -

        DataMappingConfiguration$setYFactors(labels, yFactors)

        -
        - -
        -

        Arguments

        -

        labels
        -

        A string or a list of strings representing the names of the -data sets

        - - -
        yFactors
        -

        A numerical value or a list of numerical values -representing the y-factors. Both lists must be of same length -and store the entries in the same order.

        - - -

        -
        - -


        -

        Method setXOffsets()

        -

        Set the values of x-offsets. An x-offset will be added to -the the x-values of the data set.

        -

        Usage

        -

        DataMappingConfiguration$setXOffsets(labels, xOffsets)

        -
        - -
        -

        Arguments

        -

        labels
        -

        A string or a list of strings representing the names of the -data sets

        - - -
        xOffsets
        -

        A numerical value or a list of numerical values -representing the x-offsets. Both lists must be of same length and store -the entries in the same order.

        - - -

        -
        - -


        -

        Method setYOffsets()

        -

        Set the values of y-offsets. A y-offset will be added to the -the y-values of the data set.

        -

        Usage

        -

        DataMappingConfiguration$setYOffsets(labels, yOffsets)

        -
        - -
        -

        Arguments

        -

        labels
        -

        A string or a list of strings representing the names of the -data sets

        - - -
        yOffsets
        -

        A numerical value or a list of numerical values -representing the y-offsets. Both lists must be of same length and store -the entries in the same order.

        - - -

        -
        - -


        -

        Method setColors()

        -

        Set the colors that will be used to plot a certain data set.

        -

        Usage

        -

        DataMappingConfiguration$setColors(labels, colors)

        -
        - -
        -

        Arguments

        -

        labels
        -

        A string or a list of strings representing the names of the -data sets

        - - -
        colors
        -

        Values representing a color recognized by the col -argument of the plot() function

        - - -

        -
        - -


        -

        Method setLineTypes()

        -

        Set the line types that will be used to plot a certain data set.

        -

        Usage

        -

        DataMappingConfiguration$setLineTypes(labels, lineTypes)

        -
        - -
        -

        Arguments

        -

        labels
        -

        A string or a list of strings representing the names of the -data sets

        - - -
        lineTypes
        -

        Values recognized by the col argument of the plot() -function

        - - -

        -
        - -


        -

        Method print()

        -

        Print the object to the console

        -

        Usage

        -

        DataMappingConfiguration$print(...)

        -
        - -
        -

        Arguments

        -

        ...
        -

        Rest arguments.

        - - -

        -
        - -
        - -
        - -
        - - -
        - - - -
        - - - - - - - diff --git a/docs/reference/Distributions.html b/docs/reference/Distributions.html index add2b3fa..e26ce27e 100644 --- a/docs/reference/Distributions.html +++ b/docs/reference/Distributions.html @@ -1,5 +1,5 @@ -Supported distributions for sampling — Distributions • esqlabsRSupported distributions for sampling — Distributions • esqlabsR @@ -10,7 +10,7 @@ esqlabsR - 3.0.0 + 4.0.0 - - - - - -
        -
        -
        - -
        -

        An object storing configuration of a plot

        -
        - - -
        -

        Super class

        -

        ospsuite.utils::Printable -> PlotConfiguration

        -
        -
        -

        Public fields

        -

        outputDevice
        -

        Output target of the plot. If NULL (default), the figure is created in the default "plot" -output. Other values indicate output into a file. A list of supported outputs is provided in GraphicsDevices-enum.

        - - -
        outputName
        -

        A string used as the name of the .png file and as the title of the plot

        - - -
        outputFolder
        -

        Path to the directory where the outputs should be stored.

        - - -
        width
        -

        Width of the resulting plot in cm. If NULL (default), the width is automatically calculated -using the value esqlabsEnv$widthPerPlotMapping

        - - -
        height
        -

        Height of the resulting plot in cm. If NULL (default), the -height is automatically calculated -using the value esqlabsEnv$heightPerPlotMapping

        - - -
        nrOfCols
        -

        Number of column in a multi-panel plot. If NULL -(default), the number is calculated automatically to fit all panels -while trying to keep the number of columns and rows equal. If nrOfCols -is specified, the number of rows calculated to fit all the panels.

        - - -
        res
        -

        Resolution of the .png output in dpi. Default is 600.

        - - -
        pointsize
        -

        Size of the plotted text. Default is 8.

        - - -
        addTitle
        -

        Boolean flag if the title should be added. If TRUE, -outputName is added a title.

        - - -

        -
        -
        -

        Methods

        - -

        Inherited methods


          -

          Method new()

          -

          Initialize a new instance of the class

          -

          Usage

          -

          -
          - -
          -

          Returns

          -

          A new PlotConfiguration object.

          -
          - -


          -

          Method print()

          -

          Print the object to the console

          -

          Usage

          -

          PlotConfiguration$print(...)

          -
          - -
          -

          Arguments

          -

          ...
          -

          Rest arguments.

          - - -

          -
          - -
          - -
          - -
          - - -
          - - - -
          - - - - - - - diff --git a/docs/reference/PlotTypes.html b/docs/reference/PlotTypes.html deleted file mode 100644 index 9ae5cba2..00000000 --- a/docs/reference/PlotTypes.html +++ /dev/null @@ -1,100 +0,0 @@ - -Possible entries for the plotType field of a DataMapping object — PlotTypes • esqlabsR - Skip to contents - - -
          -
          -
          - -
          -

          Possible entries for the plotType field of a DataMapping object

          -
          - -
          -

          Usage

          -
          PlotTypes
          -
          - -
          -

          Format

          -

          An object of class list of length 4.

          -
          -
          -

          Details

          -

          "IndividualProfile" - simulated results are plotted as time-values -series with points connected by lines, with each individual results potted -separately "PopulationQuantiles" - simulated results for a population are -aggregated as median, 95th an 5th percentiles, with median plotted as a -line an upper/lower percentiles plotted as shaded areas -"PredictedVsObserved" - predicted-versus-observed goodness of fit plot

          -
          - -
          - - -
          - - - -
          - - - - - - - diff --git a/docs/reference/Plotable.html b/docs/reference/Plotable.html deleted file mode 100644 index 51916d57..00000000 --- a/docs/reference/Plotable.html +++ /dev/null @@ -1,180 +0,0 @@ - -Plotable — Plotable • esqlabsR - Skip to contents - - -
          -
          -
          - -
          -

          An object holding plotting information

          -
          - - -
          -

          See also

          -

          col2hsv

          -
          -
          -

          Super class

          -

          ospsuite.utils::Printable -> Plotable

          -
          -
          -

          Public fields

          -

          label
          -

          A string that is used as a label (e.g. in the legend) for the data set -that will be plotted

          - - -
          color
          -

          Color that will be used when plotting the output. Represented as a array -of three HSV values.

          - - -
          xFactor
          -

          Numeric value the x-values will be multiplied by.

          - - -
          yFactor
          -

          Numeric value the y-values will be multiplied by.

          - - -
          xOffset
          -

          A value that is added to all x-values when plotting

          - - -
          yOffset
          -

          A value that is added to all y-values when plotting

          - - -
          type
          -

          "p" for points, "l" for line, or "pl" for both

          - - -
          pch
          -

          Either an integer specifying a symbol or a single character to be used as the default in plotting points. See par for more information.

          - - -
          lty
          -

          The line type. See par for more information.

          - - -

          -
          -
          -

          Methods

          - -
          -

          Public methods

          - -

          Inherited methods


            -

            Method new()

            -

            Initialize a new instance of the class

            -

            Usage

            -

            Plotable$new(label)

            -
            - -
            -

            Arguments

            -

            label
            -

            A string that is used as a label (e.g. in the legend) for the data set

            - - -

            -
            -
            -

            Returns

            -

            A new Plotable object.

            -
            - -


            -

            Method print()

            -

            Print the object to the console

            -

            Usage

            -

            Plotable$print(...)

            -
            - -
            -

            Arguments

            -

            ...
            -

            Rest arguments.

            - - -

            -
            - -
            - -
            - -
            - - -
            - - - -
            - - - - - - - diff --git a/docs/reference/ProjectConfiguration.html b/docs/reference/ProjectConfiguration.html index 92e124ea..0c750060 100644 --- a/docs/reference/ProjectConfiguration.html +++ b/docs/reference/ProjectConfiguration.html @@ -1,5 +1,5 @@ -ProjectConfiguration — ProjectConfiguration • esqlabsRProjectConfiguration — ProjectConfiguration • esqlabsR @@ -10,7 +10,7 @@ esqlabsR - 3.0.0 + 4.0.0 - - - - - -
            -
            -
            - -
            -

            A set of x and y value pairs

            -
            - - -
            -

            Super classes

            -

            ospsuite.utils::Printable -> esqlabsR::Plotable -> XYData

            -
            -
            -

            Active bindings

            -

            xValues
            -

            An array of x-values. For time series, the values must be -in minutes.

            - - -
            yValues
            -

            An array of y-values.

            - - -
            yError
            -

            An array of arithmetic error of the y-values. Only positive -values are allowed

            - - -
            xMax
            -

            Maximal value of x values plus xOffset multiplied by the -scaling factor

            - - -
            xMin
            -

            Minimal value of x values plus xOffset multiplied by the -scaling factor

            - - -
            yMax
            -

            Maximal value (plus error, if specified) of y values plus -yOffset multiplied by the scaling factor

            - - -
            yMin
            -

            Minimal value (minus error, if specified) of y values plus -yOffset multiplied by the scaling factor

            - - -
            dataType
            -

            Type of the data. See enum XYDataTypes for the list of -supported types.

            - - -
            xDimension
            -

            Dimension of x values. See enum ospDimensions for the -list of supported dimensions.

            - - -
            xUnit
            -

            Unit of x values

            - - -
            yDimension
            -

            Dimension of y values. See enum ospDimensions for the -list of supported dimensions.

            - - -
            yUnit
            -

            Unit of y values

            - - -
            yErrorUnit
            -

            Unit of y error values

            - - -
            MW
            -

            Molecular weight in g/mol. Required for conversion between -molar and mass dimensions. Can be NULL (default)

            - - -

            -
            -
            -

            Methods

            - -

            Inherited methods


              -

              Method new()

              -

              Initialize a new instance of the class. xVals, yVals, and -yError (optional) must be of the same length

              -

              Usage

              -

              XYData$new(xVals, yVals, label, yError = NULL)

              -
              - -
              -

              Arguments

              -

              xVals
              -

              An array of numeric x values.

              - - -
              yVals
              -

              An array of numeric y values,

              - - -
              label
              -

              A string that is used as a label (e.g. in the legend) for the data set

              - - -
              yError
              -

              An array of numeric values of the arithmetic error. Optional

              - - -

              -
              -
              -

              Returns

              -

              A new XYData object.

              -
              - -


              -

              Method yMinPositive()

              -

              Returns the minimal value (minus error, if specified) of the y series that is not negative or null

              -

              Usage

              -

              XYData$yMinPositive()

              -
              - -
              -

              Returns

              -

              The minimal non-negative value of the y series minus error, if -specified, plus yOffset multiplied by the scaling factor If no such -value exists, returns Inf.

              -
              - -


              -

              Method xValuesProcessed()

              -

              x values with all conversions applied.

              -

              Usage

              -

              XYData$xValuesProcessed(unit = NULL)

              -
              - -
              -

              Arguments

              -

              unit
              -

              Target unit. If NULL (default), no conversion between units -is applied.

              - - -

              -
              -
              -

              Returns

              -

              Raw xValues plus xOffset multiplied by xFactor and converted to a -specified unit. It is assumed that raw xValues are in xUnit.

              -
              - -


              -

              Method yValuesProcessed()

              -

              y values with all conversions applied.

              -

              Usage

              -

              XYData$yValuesProcessed(unit = NULL)

              -
              - -
              -

              Arguments

              -

              unit
              -

              Target unit. If NULL (default), no conversion between units -is applied.

              - - -

              -
              -
              -

              Returns

              -

              Raw yValues plus yOffset multiplied by yFactor and converted to a -specified unit. -It is assumed that raw yValues are in yUnit.

              -
              - -


              -

              Method yErrorProcessed()

              -

              y error values with all conversions applied.

              -

              Usage

              -

              XYData$yErrorProcessed(unit = NULL)

              -
              - -
              -

              Arguments

              -

              unit
              -

              Target unit. If NULL (default), the no conversion between -units is applied.

              - - -

              -
              -
              -

              Returns

              -

              Raw yError multiplied by yFactor and converted to a specified -unit. It is assumed that raw yError are in yUnit. If no error is -specified, NULL is returned.

              -
              - -


              -

              Method getAllMetaData()

              -

              Meta data list of XYData object

              -

              Usage

              -

              XYData$getAllMetaData()

              -
              - -
              -

              Returns

              -

              A named list holding the metadata of this XYData

              -
              - -


              -

              Method setMetaData()

              -

              Adds a new entry to meta data list of XYData object or changes its -value if name is already present in meta data. If only name is provided -or if value is set to NULL, entry with corresponding name is deleted -from meta data.

              -

              Usage

              -

              XYData$setMetaData(name, value = NULL)

              -
              - -
              -

              Arguments

              -

              name
              -

              Name of new meta data list entry

              - - -
              value
              -

              Value of new meta data list entry

              - - -

              -
              - -


              -

              Method print()

              -

              Print the object to the console

              -

              Usage

              -

              XYData$print(...)

              -
              - -
              -

              Arguments

              -

              ...
              -

              Rest arguments.

              - - -

              -
              - -


              -

              Method clone()

              -

              The objects of this class are cloneable with this method.

              -

              Usage

              -

              XYData$clone(deep = FALSE)

              -
              - -
              -

              Arguments

              -

              deep
              -

              Whether to make a deep clone.

              - - -

              -
              - -
              - -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/XYDataTypes.html b/docs/reference/XYDataTypes.html deleted file mode 100644 index 6a1578ee..00000000 --- a/docs/reference/XYDataTypes.html +++ /dev/null @@ -1,91 +0,0 @@ - -Possible entries for the dataType field of a XYData object — XYDataTypes • esqlabsR - Skip to contents - - -
              -
              -
              - -
              -

              Possible entries for the dataType field of a XYData object

              -
              - -
              -

              Usage

              -
              XYDataTypes
              -
              - -
              -

              Format

              -

              An object of class list of length 3.

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/applyIndividualParameters.html b/docs/reference/applyIndividualParameters.html index c24aa7c7..ae4aaf6a 100644 --- a/docs/reference/applyIndividualParameters.html +++ b/docs/reference/applyIndividualParameters.html @@ -3,11 +3,11 @@ For human species, only parameters that do not override formulas are applied. For other species, all parameters returned by createIndividual are applied.">Apply an individual to the simulation. For human species, only parameters that do not override formulas are applied. -For other species, all parameters returned by createIndividual are applied. — applyIndividualParameters • esqlabsR @@ -18,7 +18,7 @@ esqlabsR - 3.0.0 + 4.0.0 - - - - - -
              -
              -
              - -
              -

              Calculate the root mean square error for groupings in dataMappings

              -
              - -
              -

              Usage

              -
              calculateRMSE(dataMappingList, timeDiffThreshold = 10)
              -
              - -
              -

              Arguments

              -
              dataMappingList
              -

              A DataMapping or a list of DataMapping objects.

              -
              timeDiffThreshold
              -

              Allowed difference between observed and simulated -time values in minutes. Default is 10. If for a certain observed point no -simulated time point exists within the defined threshold, the value is not -considered.

              -
              -
              -

              Value

              -

              Total error for all groups across all provided data mappings.

              -
              -
              -

              Details

              -

              The error is calculated for each group separately and added up. For -each group, the error is defined as the root of the sum of the squared -residuals between each simulated result and observed data.

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/closeOutputDevice.html b/docs/reference/closeOutputDevice.html deleted file mode 100644 index b4d42385..00000000 --- a/docs/reference/closeOutputDevice.html +++ /dev/null @@ -1,96 +0,0 @@ - -Close output device — closeOutputDevice • esqlabsR - Skip to contents - - -
              -
              -
              - -
              -

              Close output device

              -
              - -
              -

              Usage

              -
              closeOutputDevice(plotConfiguration)
              -
              - -
              -

              Arguments

              -
              plotConfiguration
              -

              An object of type PlotConfiguration

              -
              -
              -

              Details

              -

              If the output of the plot is directed to a file, close the device.

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/col2hsv.html b/docs/reference/col2hsv.html index 7ec9d347..8029d2ab 100644 --- a/docs/reference/col2hsv.html +++ b/docs/reference/col2hsv.html @@ -1,5 +1,5 @@ -Returns the HSV values for a given R color name — col2hsv • esqlabsRReturns the HSV values for a given R color name — col2hsv • esqlabsR @@ -10,7 +10,7 @@ esqlabsR - 3.0.0 + 4.0.0
              + + + + + +
              +
              +
              + +
              +

              An instance of ExportConfiguration R6 class from {tlf} package is needed +for saving the plots and plot grids created using the {ospsuite} package.

              +

              The default attributes of the class are chosen to reflect the corporate +standards adopted by esqLABS GmbH.

              +
              + +
              +

              Usage

              +
              createEsqlabsExportConfiguration(projectConfiguration)
              +
              + +
              +

              Arguments

              +
              projectConfiguration
              +

              Object of class ProjectConfiguration +that contains information about the output paths.

              + +
              +
              +

              Value

              + + +

              An instance of ExportConfiguration R6 class.

              +
              +
              +

              See also

              +

              Other create-plotting-configurations: +createEsqlabsPlotConfiguration(), +createEsqlabsPlotGridConfiguration()

              +
              + +
              +

              Examples

              +
              myProjConfig <- ProjectConfiguration$new()
              +createEsqlabsExportConfiguration(myProjConfig)
              +#> Format: 
              +#> Width: 18 cm
              +#> Height: 18 cm
              +#> Resolution: 300 dots per inch
              +
              +
              +
              +
              + + +
              + + + +
              + + + + + + + diff --git a/docs/reference/createEsqlabsPlotConfiguration.html b/docs/reference/createEsqlabsPlotConfiguration.html new file mode 100644 index 00000000..30a28ef4 --- /dev/null +++ b/docs/reference/createEsqlabsPlotConfiguration.html @@ -0,0 +1,235 @@ + +Create an instance of DefaultPlotConfiguration R6 class — createEsqlabsPlotConfiguration • esqlabsR + Skip to contents + + +
              +
              +
              + +
              +

              An instance of DefaultPlotConfiguration R6 class is needed for creating +visualizations with the {ospsuite} package.

              +

              The default attributes of the class are chosen to reflect the corporate +standards adopted by esqLABS GmbH.

              +
              + +
              +

              Usage

              +
              createEsqlabsPlotConfiguration()
              +
              + +
              +

              Value

              + + +

              An instance of DefaultPlotConfiguration R6 class.

              +
              +
              +

              See also

              +

              Other create-plotting-configurations: +createEsqlabsExportConfiguration(), +createEsqlabsPlotGridConfiguration()

              +
              + +
              +

              Examples

              +
              createEsqlabsPlotConfiguration()
              +#> <DefaultPlotConfiguration>
              +#>   Public:
              +#>     caption: NULL
              +#>     captionAlign: right
              +#>     captionAngle: 0
              +#>     captionColor: black
              +#>     captionFontFace: plain
              +#>     captionFontFamily: 
              +#>     captionSize: 8
              +#>     clone: function (deep = FALSE) 
              +#>     errorbarsAlpha: 0.75
              +#>     errorbarsCapSize: 5
              +#>     errorbarsLinetype: solid
              +#>     errorbarsSize: 1
              +#>     legendKeysAlign: left
              +#>     legendKeysAngle: 0
              +#>     legendKeysColor: black
              +#>     legendKeysFontFace: plain
              +#>     legendKeysFontFamily: 
              +#>     legendKeysSize: 10
              +#>     legendPosition: outsideTop
              +#>     legendTitle: NULL
              +#>     legendTitleAlign: left
              +#>     legendTitleAngle: 0
              +#>     legendTitleColor: black
              +#>     legendTitleFontFace: plain
              +#>     legendTitleFontFamily: 
              +#>     legendTitleSize: 6
              +#>     linesAlpha: 0.75
              +#>     linesColor: NULL
              +#>     linesLinetype: NULL
              +#>     linesSize: 1
              +#>     plotBackgroundColor: black
              +#>     plotBackgroundFill: white
              +#>     plotBackgroundLinetype: blank
              +#>     plotBackgroundSize: 0.5
              +#>     plotPanelBackgroundColor: black
              +#>     plotPanelBackgroundFill: white
              +#>     plotPanelBackgroundLinetype: solid
              +#>     plotPanelBackgroundSize: 0.5
              +#>     pointsAlpha: 0.75
              +#>     pointsColor: #5050FFFF #CE3D32FF #749B58FF #F0E685FF #466983FF #BA633 ...
              +#>     pointsShape: circle square triangle triangleDown cross plus asterisk  ...
              +#>     pointsSize: 3
              +#>     ribbonsAlpha: 0.5
              +#>     ribbonsFill: #5050FFFF #CE3D32FF #749B58FF #F0E685FF #466983FF #BA633 ...
              +#>     ribbonsLinetype: solid longdash dotted dashed twodash dotdash blank
              +#>     ribbonsSize: 1
              +#>     subtitle: NULL
              +#>     subtitleAlign: left
              +#>     subtitleAngle: 0
              +#>     subtitleColor: black
              +#>     subtitleFontFace: plain
              +#>     subtitleFontFamily: 
              +#>     subtitleSize: 10
              +#>     title: NULL
              +#>     titleAlign: left
              +#>     titleAngle: 0
              +#>     titleColor: black
              +#>     titleFontFace: plain
              +#>     titleFontFamily: 
              +#>     titleSize: 8
              +#>     watermark: NULL
              +#>     watermarkAlign: center
              +#>     watermarkAngle: 30
              +#>     watermarkColor: grey40
              +#>     watermarkFontFace: plain
              +#>     watermarkFontFamily: 
              +#>     watermarkSize: 20
              +#>     xAxisColor: black
              +#>     xAxisExpand: FALSE
              +#>     xAxisLabelTicksAlign: center
              +#>     xAxisLabelTicksAngle: 0
              +#>     xAxisLabelTicksColor: black
              +#>     xAxisLabelTicksFontFace: plain
              +#>     xAxisLabelTicksFontFamily: 
              +#>     xAxisLabelTicksSize: 8
              +#>     xAxisLimits: NULL
              +#>     xAxisLinetype: solid
              +#>     xAxisScale: NULL
              +#>     xAxisSize: 0.5
              +#>     xAxisTicks: NULL
              +#>     xAxisTicksLabels: identity
              +#>     xGridColor: grey
              +#>     xGridLinetype: blank
              +#>     xGridSize: 0.25
              +#>     xLabel: NULL
              +#>     xLabelAlign: center
              +#>     xLabelAngle: 0
              +#>     xLabelColor: black
              +#>     xLabelFontFace: plain
              +#>     xLabelFontFamily: 
              +#>     xLabelSize: 8
              +#>     xUnit: NULL
              +#>     yAxisColor: black
              +#>     yAxisExpand: FALSE
              +#>     yAxisLabelTicksAlign: center
              +#>     yAxisLabelTicksAngle: 90
              +#>     yAxisLabelTicksColor: black
              +#>     yAxisLabelTicksFontFace: plain
              +#>     yAxisLabelTicksFontFamily: 
              +#>     yAxisLabelTicksSize: 8
              +#>     yAxisLimits: NULL
              +#>     yAxisLinetype: solid
              +#>     yAxisScale: NULL
              +#>     yAxisSize: 0.5
              +#>     yAxisTicks: NULL
              +#>     yAxisTicksLabels: identity
              +#>     yGridColor: grey
              +#>     yGridLinetype: blank
              +#>     yGridSize: 0.25
              +#>     yLabel: NULL
              +#>     yLabelAlign: center
              +#>     yLabelAngle: 90
              +#>     yLabelColor: black
              +#>     yLabelFontFace: plain
              +#>     yLabelFontFamily: 
              +#>     yLabelSize: 8
              +#>     yUnit: NULL
              +
              +
              +
              +
              + + +
              + + + +
              + + + + + + + diff --git a/docs/reference/createEsqlabsPlotGridConfiguration.html b/docs/reference/createEsqlabsPlotGridConfiguration.html new file mode 100644 index 00000000..01530714 --- /dev/null +++ b/docs/reference/createEsqlabsPlotGridConfiguration.html @@ -0,0 +1,134 @@ + +Create an instance of PlotGridConfiguration R6 class — createEsqlabsPlotGridConfiguration • esqlabsR + Skip to contents + + +
              +
              +
              + +
              +

              An instance of PlotGridConfiguration R6 class from {tlf} package is +needed for creating a grid of multiple visualizations created using the +{ospsuite} package.

              +

              The default attributes of the class are chosen to reflect the corporate +standards adopted by esqLABS GmbH.

              +
              + +
              +

              Usage

              +
              createEsqlabsPlotGridConfiguration()
              +
              + +
              +

              Value

              + + +

              An instance of PlotGridConfiguration R6 class.

              +
              +
              +

              See also

              +

              Other create-plotting-configurations: +createEsqlabsExportConfiguration(), +createEsqlabsPlotConfiguration()

              +
              + +
              +

              Examples

              +
              createEsqlabsPlotGridConfiguration()
              +#> PlotGridConfiguration: 
              +#>    Plot grid annotations: 
              +#>    	Title: 
              +#>    	Subtitle: 
              +#>    	Caption: 
              +#>    Plot grid arrangement: 
              +#>    	Number of plots included: 0 
              +#>    	Number of columns in the grid: 
              +#>    	Number of rows in the grid: 
              +#>    	Arranged in row-major order: 
              +#>    Individual plot tags: 
              +#>    	Tag level format: a 
              +#>    	Tag level prefix: 
              +#>    	Tag level suffix: 
              +#>    	Tag level separator: 
              +
              +
              +
              +
              + + +
              + + + +
              + + + + + + + diff --git a/docs/reference/dot-figureAddLegend.html b/docs/reference/dot-figureAddLegend.html deleted file mode 100644 index 4c9a4132..00000000 --- a/docs/reference/dot-figureAddLegend.html +++ /dev/null @@ -1,104 +0,0 @@ - -Add legend to a plot — .figureAddLegend • esqlabsR - Skip to contents - - -
              -
              -
              - -
              -

              Add legend to a plot

              -
              - -
              -

              Usage

              -
              .figureAddLegend(x, legend, col, pch, lty, ...)
              -
              - -
              -

              Arguments

              -
              legend
              -

              a character or expression vector - of length \(\ge 1\) to appear in the legend. Other - objects will be coerced by as.graphicsAnnot.

              -
              col
              -

              the color of points or lines appearing in the legend.

              -
              pch
              -

              the plotting symbols appearing in the legend, as - numeric vector or a vector of 1-character strings (see - points). Unlike points, this can all be - specified as a single multi-character string. Must be - specified for symbol drawing.

              -
              ...
              -

              Additional arguments to be passed to graphics::legend.

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/dot-isLine.html b/docs/reference/dot-isLine.html deleted file mode 100644 index 6842bf13..00000000 --- a/docs/reference/dot-isLine.html +++ /dev/null @@ -1,96 +0,0 @@ - -Does the plot type contain line? — .isLine • esqlabsR - Skip to contents - - -
              -
              -
              - -
              -

              Does the plot type contain line?

              -
              - -
              -

              Usage

              -
              .isLine(type)
              -
              - -
              -

              Arguments

              -
              type
              -

              String value of argument type passed to function plot()

              -
              -
              -

              Value

              -

              TRUE if type contains "l" or is "b", FALSE otherwise

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/dot-isPoint.html b/docs/reference/dot-isPoint.html deleted file mode 100644 index d74b2e15..00000000 --- a/docs/reference/dot-isPoint.html +++ /dev/null @@ -1,96 +0,0 @@ - -Does the plot type contain points? — .isPoint • esqlabsR - Skip to contents - - -
              -
              -
              - -
              -

              Does the plot type contain points?

              -
              - -
              -

              Usage

              -
              .isPoint(type)
              -
              - -
              -

              Arguments

              -
              type
              -

              String value of argument type passed to function plot()

              -
              -
              -

              Value

              -

              TRUE if type contains "p" or is "b", FALSE otherwise

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/dot-setApplicationFromExcel.html b/docs/reference/dot-setApplicationFromExcel.html index 03dc18bc..2ef5fefb 100644 --- a/docs/reference/dot-setApplicationFromExcel.html +++ b/docs/reference/dot-setApplicationFromExcel.html @@ -1,5 +1,5 @@ -Set application protocol from excel — .setApplicationFromExcel • esqlabsRSet application protocol from excel — .setApplicationFromExcel • esqlabsR @@ -10,7 +10,7 @@ esqlabsR - 3.0.0 + 4.0.0 + + + + + +
              +
              +
              + +
              +

              Creates an excel file with information from the passed +parameters. The excel sheet will contain columns "Container Path", +"Parameter Name", "Value", and "Units". The resulting file can be loaded in +MoBi or in R with the function readParametersFromXLS().

              +
              + +
              +

              Usage

              +
              exportParametersToXLS(parameters, paramsXLSpath, sheet = NULL)
              +
              + +
              +

              Arguments

              +
              parameters
              +

              A single or a list of Parameter objects

              + + +
              paramsXLSpath
              +

              Path to the excel file

              + + +
              sheet
              +

              (Optional) name of the excel sheet

              + +
              + +
              + + +
              + + + +
              + + + + + + + diff --git a/docs/reference/exportSteadyStateToXLS.html b/docs/reference/exportSteadyStateToXLS.html index e31c26c7..45ecefae 100644 --- a/docs/reference/exportSteadyStateToXLS.html +++ b/docs/reference/exportSteadyStateToXLS.html @@ -1,5 +1,5 @@ -Export steady-state to excel — exportSteadyStateToXLS • esqlabsRExport steady-state to excel — exportSteadyStateToXLS • esqlabsR @@ -10,7 +10,7 @@ esqlabsR - 3.0.0 + 4.0.0 - - - - - -
              -
              -
              - - - -
              -

              Usage

              -
              figureAddLabel(label, location = "topleft", offset = c(0, 0))
              -
              - -
              -

              Arguments

              -
              label
              -

              Label that is to be drawn

              -
              location
              -

              Location of the label. Allowed entries are 'topleft', -'topcenter', 'topright', 'bottomleft', 'bottomright', 'bottomcenter'

              -
              offset
              -

              Coordinates of the offset of the label

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/figures/logo.png b/docs/reference/figures/logo.png new file mode 100644 index 00000000..71238cc0 Binary files /dev/null and b/docs/reference/figures/logo.png differ diff --git a/docs/reference/foldChangeFunction.html b/docs/reference/foldChangeFunction.html index 597d47a4..e8d9af76 100644 --- a/docs/reference/foldChangeFunction.html +++ b/docs/reference/foldChangeFunction.html @@ -1,5 +1,5 @@ -Function returning the fold difference between x and x_0 — foldChangeFunction • esqlabsRFunction returning the fold difference between x and x_0 — foldChangeFunction • esqlabsR @@ -10,7 +10,7 @@ esqlabsR - 3.0.0 + 4.0.0 + + + + + +
              +
              +
              + +
              +

              Returns the name of the molecule to which the quantity object +is associated. The quantity could be the amount of the molecule in a container +('Organism|VenousBlood|Plasma|Aciclovir'), a parameter of the molecule +('Aciclivor|Lipophilicity' or 'Organism|VenousBlood|Plasma|Aciclovir|Concentration'), +or an observer ("Organism|PeripheralVenousBlood|Aciclovir|Plasma (Peripheral Venous Blood)").

              +

              If the quantity is not associated with a molecule (e.g. 'Organism|Weight'), +an error is thrown.

              +
              + +
              +

              Usage

              +
              getMoleculeNameFromQuantity(quantity)
              +
              + +
              +

              Arguments

              +
              quantity
              +

              A Quantity object

              + +
              +
              +

              Value

              + + +

              Name of the molecule the quantity is associated with.

              +
              + +
              +

              Examples

              +
              simulation <- loadSimulation(system.file("extdata", "Aciclovir.pkml", package = "ospsuite"))
              +quantity <- getQuantity(
              +  path = "Organism|PeripheralVenousBlood|Aciclovir|Plasma (Peripheral Venous Blood)",
              +  container = simulation
              +)
              +getMoleculeNameFromQuantity(quantity = quantity)
              +#> [1] "Aciclovir"
              +
              +
              +
              + + +
              + + + +
              + + + + + + + diff --git a/docs/reference/getNetHashCode.html b/docs/reference/getNetHashCode.html deleted file mode 100644 index 18a54dd0..00000000 --- a/docs/reference/getNetHashCode.html +++ /dev/null @@ -1,96 +0,0 @@ - -Get hash code of the .NET object — getNetHashCode • esqlabsR - Skip to contents - - -
              -
              -
              - -
              -

              Get hash code of the .NET object

              -
              - -
              -

              Usage

              -
              getNetHashCode(netWrapper)
              -
              - -
              -

              Arguments

              -
              netWrapper
              -

              Any object from the ospsuite-R that inherits from DotNetWrapper

              -
              -
              -

              Value

              -

              Value of the .NET-method "GetHashCode"

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/getSteadyState.html b/docs/reference/getSteadyState.html deleted file mode 100644 index f2c98ce4..00000000 --- a/docs/reference/getSteadyState.html +++ /dev/null @@ -1,132 +0,0 @@ - -Get the steady-state values of species and state variable parameters. — getSteadyState • esqlabsR - Skip to contents - - -
              -
              -
              - -
              -

              Get the steady-state values of species and state variable parameters.

              -
              - -
              -

              Usage

              -
              getSteadyState(
              -  quantitiesPaths = NULL,
              -  simulations,
              -  steadyStateTime,
              -  ignoreIfFormula = TRUE,
              -  stopIfNotFound = TRUE,
              -  lowerThreshold = 1e-15
              -)
              -
              - -
              -

              Arguments

              -
              quantitiesPaths
              -

              List of quantity paths (molecules and/or parameters) -for which the steady-state is to be simulated. If NULL (default), all -molecules and state variable parameters are considered. The same list is -applied for all simulations.

              -
              simulations
              -

              Simulation object or a list of Simulation objects

              -
              steadyStateTime
              -

              Simulation time (minutes). Must be long enough for -system to reach a steady-state. 1000 by default

              -
              ignoreIfFormula
              -

              If TRUE (default), species and parameters with -initial values defined by a formula are not included.

              -
              stopIfNotFound
              -

              Boolean. If TRUE (default), an error is thrown when -results for certain species were not generated. This may happen when due to -numerical problems some values cannot be calculated, though the whole -simulation converges. Setting this argument to FALSE allows to ignore -such errors. Check the outputs for empty values when using this option.

              -
              lowerThreshold
              -

              Numerical value (in µmol). Any steady-state values -below this value are considered as numerical noise and replaced by 0. If -lowerThreshold is NULL, no cut-off is applied. Default value is 1e-15.

              -
              -
              -

              Value

              -

              A named list, where the names are the IDs of the simulations and the -entries are lists containing paths and their values at the end of the -simulation.

              -
              -
              -

              Details

              -

              The steady-state is considered to be the last value of the -simulation with sufficiently long simulation time, i.e., where the rates of -the processes do not (significantly) change.

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/hillFunction.html b/docs/reference/hillFunction.html index 0a35bed6..fb24040c 100644 --- a/docs/reference/hillFunction.html +++ b/docs/reference/hillFunction.html @@ -1,9 +1,9 @@ Hill equation, transforming a value of an effector (e.g. concentration) to a -saturable function value. — hillFunction • esqlabsR @@ -14,7 +14,7 @@ esqlabsR - 3.0.0 + 4.0.0
              - - - - - -
              -
              -
              - -
              -

              Is a character part of string?

              -
              - -
              -

              Usage

              -
              isCharInString(char, string)
              -
              - -
              -

              Arguments

              -
              char
              -

              Character to find in the string

              -
              string
              -

              String that should contain the character

              -
              -
              -

              Value

              -

              TRUE if the character is a substring if string, FALSE otherwise

              -
              - -
              -

              Examples

              -
              isCharInString("a", "bsdalk")
              -#> [1] TRUE
              -
              -
              -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/isParametersEqual.html b/docs/reference/isParametersEqual.html index 5dac35e6..67ffaa30 100644 --- a/docs/reference/isParametersEqual.html +++ b/docs/reference/isParametersEqual.html @@ -1,5 +1,5 @@ -Check if two parameters are equal is respect to certain properties. — isParametersEqual • esqlabsRCheck if two parameters are equal with respect to certain properties. — isParametersEqual • esqlabsR @@ -10,7 +10,7 @@ esqlabsR - 3.0.0 + 4.0.0 - - - - - -
              -
              -
              - -
              -

              Open an output device.

              -
              - -
              -

              Usage

              -
              openOuptutDevice(plotConfiguration, width, height)
              -
              - -
              -

              Arguments

              -
              plotConfiguration
              -

              An object of type PlotConfiguration

              -
              width
              -

              Width of the output figure

              -
              height
              -

              Height of the output figure

              -
              -
              -

              Details

              -

              If the output of the plot is directed to a file, open the -connection. A list of supported outputs is provided in -GraphicsDevices-enum. If the provided output defined in -PlotConfiguration$outputDevice is not supported or the value is NULL, -output is directed to the default plot frame.

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/pathFromClipboard.html b/docs/reference/pathFromClipboard.html index 578dc293..7b5dd209 100644 --- a/docs/reference/pathFromClipboard.html +++ b/docs/reference/pathFromClipboard.html @@ -1,7 +1,7 @@ -pathFromClipboard — pathFromClipboard • esqlabsRConvert Windows filepaths for R — pathFromClipboard • esqlabsR @@ -12,7 +12,7 @@ esqlabsR - 3.0.0 + 4.0.0 - - - - - -
              -
              -
              - -
              -

              Create a box-plot of data

              -
              - -
              -

              Usage

              -
              plotBoxPlot(dataMapping, ...)
              -
              - -
              -

              Arguments

              -
              dataMapping
              -

              A DataMapping object with XYData

              -
              ...
              -

              Any parameter that can be interpreted by the default boxplot() function

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/plotErrorBars.html b/docs/reference/plotErrorBars.html deleted file mode 100644 index 57d9fdb0..00000000 --- a/docs/reference/plotErrorBars.html +++ /dev/null @@ -1,115 +0,0 @@ - -A function to add error bars on the chart. — plotErrorBars • esqlabsR - Skip to contents - - -
              -
              -
              - - - -
              -

              Usage

              -
              plotErrorBars(
              -  x,
              -  y,
              -  upper,
              -  lower = upper,
              -  length = par()$cin[[1]]/2,
              -  axis = "y",
              -  ...
              -)
              -
              - -
              -

              Arguments

              -
              x
              -

              Numerical array of x-values

              -
              y
              -

              Numerical array of y-values

              -
              upper
              -

              Numerical array of upper y-error values

              -
              lower
              -

              Numerical array of lower y-error values. Optional. -If not specified, same values as for upper are used

              -
              length
              -

              Numerical value specifying the width of the error bars. -Optional. Default is 0.1.

              -
              axis
              -

              Dimension to which the error bars are added. If "y" (default), -vertical error bars are drawn. If "x", horizontal error bars are drawn

              -
              ...
              -

              Graphical parameters (see par())

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/plotIndividualProfile.html b/docs/reference/plotIndividualProfile.html deleted file mode 100644 index ead79b50..00000000 --- a/docs/reference/plotIndividualProfile.html +++ /dev/null @@ -1,94 +0,0 @@ - -Plot individual time-values profile — plotIndividualProfile • esqlabsR - Skip to contents - - -
              -
              -
              - -
              -

              Create a 2D-plot of the x-y data sets stored in dataMapping

              -
              - -
              -

              Usage

              -
              plotIndividualProfile(dataMapping, ...)
              -
              - -
              -

              Arguments

              -
              dataMapping
              -

              A DataMapping object with XYData

              -
              ...
              -

              Any parameter that can be interpreted by the default plot() function

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/plotMultiPanel.html b/docs/reference/plotMultiPanel.html deleted file mode 100644 index 7d9358a6..00000000 --- a/docs/reference/plotMultiPanel.html +++ /dev/null @@ -1,96 +0,0 @@ - -Plot multiple PlotMapping in one plot. — plotMultiPanel • esqlabsR - Skip to contents - - -
              -
              -
              - -
              -

              Plot multiple PlotMapping in one plot.

              -
              - -
              -

              Usage

              -
              plotMultiPanel(dataMappingList, plotConfiguration, ...)
              -
              - -
              -

              Arguments

              -
              dataMappingList
              -

              A single or a list of PlotMapping objects

              -
              plotConfiguration
              -

              An object of type PlotConfiguration

              -
              ...
              -

              Any parameter that can be interpreted by the default plot() function

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/plotPopulationQuantiles.html b/docs/reference/plotPopulationQuantiles.html deleted file mode 100644 index 70d5c839..00000000 --- a/docs/reference/plotPopulationQuantiles.html +++ /dev/null @@ -1,97 +0,0 @@ - -Plot individual time-values profile — plotPopulationQuantiles • esqlabsR - Skip to contents - - -
              -
              -
              - -
              -

              Create a 2D-plot of the x-y data sets stored in dataMapping. -Population simulation results are plotted as quantiles

              -
              - -
              -

              Usage

              -
              plotPopulationQuantiles(dataMapping, ...)
              -
              - -
              -

              Arguments

              -
              dataMapping
              -

              A DataMapping object with XYData

              -
              ...
              -

              Any parameter that can be interpreted by the default plot() function

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/plotPredictedVsObserved.html b/docs/reference/plotPredictedVsObserved.html deleted file mode 100644 index aaac18d9..00000000 --- a/docs/reference/plotPredictedVsObserved.html +++ /dev/null @@ -1,113 +0,0 @@ - -Plot a predicted-versus-observed goodness of fit plot — plotPredictedVsObserved • esqlabsR - Skip to contents - - -
              -
              -
              - -
              -

              Plot a predicted-versus-observed goodness of fit plot

              -
              - -
              -

              Usage

              -
              plotPredictedVsObserved(
              -  dataMapping,
              -  foldDistance = 2,
              -  timeDiffThreshold = 10,
              -  ...
              -)
              -
              - -
              -

              Arguments

              -
              dataMapping
              -

              THe DataMapping object for which the goodness-of-fit -plot is to be drawn. For each group within the dataMapping, simulated -and observed values are compared.

              -
              foldDistance
              -

              Numerical value for the fold-distance lines to be drawn. -Default is 2.

              -
              timeDiffThreshold
              -

              Allowed difference between observed and simulated -time values in minutes. Default is 10. If for a certain observed point no -simulated time point exists within the defined threshold, the value is not -considered.

              -
              ...
              -

              Any parameter that can be interpreted by the default plot() function

              -
              -
              -

              Details

              -

              Observed data points are drawn on the x, simulated values on the y axis.

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/plotTimeValues.html b/docs/reference/plotTimeValues.html deleted file mode 100644 index 0d4e6288..00000000 --- a/docs/reference/plotTimeValues.html +++ /dev/null @@ -1,99 +0,0 @@ - -Plot time-values profile — plotTimeValues • esqlabsR - Skip to contents - - -
              -
              -
              - -
              -

              Create a 2D-plot of the x-y data sets stored in dataMapping

              -
              - -
              -

              Usage

              -
              plotTimeValues(dataMapping, aggregated, ...)
              -
              - -
              -

              Arguments

              -
              dataMapping
              -

              A DataMapping object with XYData

              -
              aggregated
              -

              Boolean. If FALSE, simulation data containing multiple -individuals (population simulation) are plotted separately for each -individual. If TRUE, population simulation results are plotted as -mid-percentile and lower/upper percentile bands around.

              -
              ...
              -

              Any parameter that can be interpreted by the default plot() function

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/plotXYData.html b/docs/reference/plotXYData.html deleted file mode 100644 index ec5f733a..00000000 --- a/docs/reference/plotXYData.html +++ /dev/null @@ -1,99 +0,0 @@ - -Plot XYData — plotXYData • esqlabsR - Skip to contents - - -
              -
              -
              - -
              -

              Draw XYData on top of an existing plot using the points method.

              -
              - -
              -

              Usage

              -
              plotXYData(xySeries, xUnit = NULL, yUnit = NULL, ...)
              -
              - -
              -

              Arguments

              -
              xySeries
              -

              An XYData object to be plotted

              -
              xUnit
              -

              Target unit of x-axis.

              -
              yUnit
              -

              Target unit of y-axis. -If TRUE,

              -
              ...
              -

              Any parameter that can be interpreted by the default plot() function

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/readExcel.html b/docs/reference/readExcel.html index 6bf15cc6..e8052b42 100644 --- a/docs/reference/readExcel.html +++ b/docs/reference/readExcel.html @@ -1,5 +1,5 @@ -Read XLSX files using readxl::read_excel with suppressed warnings — readExcel • esqlabsRRead XLSX files using readxl::read_excel with suppressed warnings — readExcel • esqlabsR @@ -10,7 +10,7 @@ esqlabsR - 3.0.0 + 4.0.0 - - - - - -
              -
              -
              - -
              -

              Read time-values data from excel file

              -
              - -
              -

              Usage

              -
              readOSPSTimeValues(dataConfiguration)
              -
              - -
              -

              Arguments

              -
              dataConfiguration
              -

              An object of DataConfiguration

              -
              -
              -

              Value

              -

              A (nested) list of XYData objects

              -
              -
              -

              Details

              -

              The methods reads time-values data from the properly defined excel -sheet and creates XYData objects according to the groupings. Each sheet -in DataConfiguration$sheets is split according to columns listed in -DataConfiguration$columnsToSplitBy. The output structure is a nested list -with levels corresponding to the groupings.

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/readParametersFromXLS.html b/docs/reference/readParametersFromXLS.html index c4d6d218..6ab7855b 100644 --- a/docs/reference/readParametersFromXLS.html +++ b/docs/reference/readParametersFromXLS.html @@ -3,11 +3,11 @@ Each excel sheet must consist of columns 'Container Path', 'Parameter Name', 'Value', and 'Units'">Read parameter values from a structured Excel file. Each excel sheet must consist of columns 'Container Path', 'Parameter Name', -'Value', and 'Units' — readParametersFromXLS • esqlabsR @@ -18,7 +18,7 @@ esqlabsR - 3.0.0 + 4.0.0 - - - - - -
              -
              -
              - -
              -

              Check if the file exists. If not, stop with an error.

              -
              - -
              -

              Usage

              -
              validateFileExists(filePath)
              -
              - -
              -

              Arguments

              -
              filePath
              -

              Path to the file

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/validateLength.html b/docs/reference/validateLength.html deleted file mode 100644 index bb6eabfd..00000000 --- a/docs/reference/validateLength.html +++ /dev/null @@ -1,100 +0,0 @@ - -Check if the provided object is of a certain length. If not, stop with an -error. — validateLength • esqlabsR - Skip to contents - - -
              -
              -
              - -
              -

              Check if the provided object is of a certain length. If not, stop with an -error.

              -
              - -
              -

              Usage

              -
              validateLength(object, length)
              -
              - -
              -

              Arguments

              -
              object
              -

              Object which length will be checked

              -
              length
              -

              Expected length

              -
              - -
              - - -
              - - - -
              - - - - - - - diff --git a/docs/reference/writeExcel.html b/docs/reference/writeExcel.html new file mode 100644 index 00000000..990948c7 --- /dev/null +++ b/docs/reference/writeExcel.html @@ -0,0 +1,109 @@ + +Write data to excel — writeExcel • esqlabsR + Skip to contents + + +
              +
              +
              + +
              +

              Write data to excel

              +
              + +
              +

              Usage

              +
              writeExcel(data, path, col_names = TRUE)
              +
              + +
              +

              Arguments

              +
              data
              +

              Data frame or named list of data frames that will be sheets in +the xlsx

              + + +
              path
              +

              a file name to write to

              + + +
              col_names
              +

              write column names at the top of the file?

              + +
              +
              +

              Details

              +

              Uses writexl::write_xlsx to write data to excel. If the folder +does not exist, creates folder(s) recursively.

              +
              + +
              + + +
              + + + +
              + + + + + + + diff --git a/docs/reference/writeIndividualToXLS.html b/docs/reference/writeIndividualToXLS.html index 4654a8e8..4e3f108d 100644 --- a/docs/reference/writeIndividualToXLS.html +++ b/docs/reference/writeIndividualToXLS.html @@ -1,5 +1,5 @@ -Create a parameter set describing an individual and write it to the Excel file — writeIndividualToXLS • esqlabsRCreate a parameter set describing an individual and write it to the Excel file — writeIndividualToXLS • esqlabsR @@ -10,7 +10,7 @@ esqlabsR - 3.0.0 + 4.0.0