From 8f16b740fb77b08ea53ea02d71aa74d0c9ef112b Mon Sep 17 00:00:00 2001 From: Pierre Chelle <45343665+pchelle@users.noreply.github.com> Date: Wed, 14 Aug 2024 04:55:26 -0400 Subject: [PATCH 1/4] Fixes #1266 update news (#1267) --- NEWS.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index b88caeb2..90e697c9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,9 @@ ## New features +> [!NOTE] +> Users can now check out [Reporting Engine Test Reports](https://github.com/Open-Systems-Pharmacology/RE-Test-Reports) and access a bunch of template workflows including their R code, models, data and corresponding reports. + - Demography task received significant updates: - The [article for demography](../articles/demography.html) has been updated with more comprehensive examples using more representative virtual populations and illustrating the effects of population workflows and settings (#1095, #1102) - Categorical parameters, such as Gender, are now accounted for demography range plots and displayed as boxplots (#1088) @@ -11,10 +14,11 @@ - Mass balance plots can leverage user-defined settings from json files as illustrated in the [mass balance article](../articles/mass-balance.html) (#1118) - Normalized mass balance plots now use time-dependent cumulative drug mass for normalization (#1039, #1118) - Qualification DDI plots received the following improvements - - Delta symbol (δ) from Guest *et al.* formula is indicated in table caption (1069) + - Delta symbol (δ) from Guest *et al.* formula is indicated in table caption (#1069) - Guest criterion (δ) can be tuned through the configuration plan (#789) - DDI plot format is quadratic by default (#1051) - Formatting to word reports can translate additional `html` tags (#382) +- Goodness of Fit task leverages `groupID` from `Output` objects to group multiple outputs in same time profile and residual plots (#1188).
`groupID` is also leveraged in the plots of residuals across the simulations (#1251). ## Minor improvements and bug fixes @@ -23,6 +27,7 @@ - Number of bins in demography and PK parameter range plots is consistent with input (#1128) - Link/bookmark targets in word reports are better placed (#1084) - Qualification time profiles work when no observed data is contained (#1082) +- Qualification PKRatio uses *ml/min/kg* as default clearance - *CL* - unit (#1242) - Static images in qualification reports are better handled (#955, #1071) - Figure captions are displayed below the figure in the reports (#1053) - Word report is updated if it already existed (#1055) From ca1991228e6e59ae1ba7f5b6df714fea842a93f8 Mon Sep 17 00:00:00 2001 From: Pierre Chelle <45343665+pchelle@users.noreply.github.com> Date: Tue, 3 Sep 2024 10:28:50 -0400 Subject: [PATCH 2/4] Fixes #1262 convert simulation endTime in qualification workflows (#1270) --- R/utilities-qualification.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/R/utilities-qualification.R b/R/utilities-qualification.R index b6cb9cb8..72d30b1f 100644 --- a/R/utilities-qualification.R +++ b/R/utilities-qualification.R @@ -52,6 +52,8 @@ loadQualificationWorkflow <- function(workflowFolder, configurationPlanFile) { minimumSimulationEndTime <- NULL if (any(!is.na(outputsDataframeSubset$endTime))) { minimumSimulationEndTime <- max(outputsDataframeSubset$endTime, na.rm = TRUE) + # Convert minimumSimulationEndTime from base unit to simulation set default unit + minimumSimulationEndTime <- ospsuite::toUnit("Time", minimumSimulationEndTime, "h") } # simulationSetName defined as project-simulation uniquely identifies the simulation From acb77e6accb7b293e0d4b2971aa77541494e0f62 Mon Sep 17 00:00:00 2001 From: Pierre Chelle <45343665+pchelle@users.noreply.github.com> Date: Wed, 4 Sep 2024 06:48:32 -0400 Subject: [PATCH 3/4] Fixes #1271 remove blanks before anchors in titles (#1272) * Fixes #1271 remove blanks before anchors in titles * Remove spaces from test TOC --- R/captions.R | 21 ++++++---- R/configuration-plan.R | 2 +- R/error-checks.R | 18 ++++---- R/gof-plot-task.R | 10 +++-- R/messages.R | 30 +++++++------- R/plot-task.R | 7 ++-- R/population-plot-task.R | 2 +- R/qualification-ddi.R | 8 +++- R/simulation-set.R | 8 ++-- R/utilities-goodness-of-fit.R | 2 +- R/utilities-mass-balance.R | 2 +- R/utilities-pop-pk-parameters.R | 53 ++++++++++++------------ R/utilities-simulation-set.R | 6 +-- man/CalculatePKParametersTask.Rd | 2 +- man/GofPlotTask.Rd | 6 ++- man/GofTaskSettings.Rd | 2 +- man/MeanModelWorkflow.Rd | 2 +- man/PlotTask.Rd | 2 +- man/PopulationPlotTask.Rd | 2 +- man/PopulationSensitivityAnalysisTask.Rd | 2 +- man/PopulationSimulationSet.Rd | 2 +- man/PopulationWorkflow.Rd | 2 +- man/QualificationTask.Rd | 2 +- man/QualificationWorkflow.Rd | 2 +- man/SensitivityAnalysisTask.Rd | 2 +- man/SimulationTask.Rd | 2 +- man/getOutputGroups.Rd | 2 +- man/reEnv.Rd | 2 +- man/reSettingsNames.Rd | 2 +- tests/testthat/test-ddi-report.R | 16 +++---- 30 files changed, 117 insertions(+), 104 deletions(-) diff --git a/R/captions.R b/R/captions.R index 56aee790..98d8d1ce 100644 --- a/R/captions.R +++ b/R/captions.R @@ -36,18 +36,18 @@ captions <- list( ), demography = list( parameterSection = function(sectionId, parameterName) { - paste("##", parameterName, "distributions", anchor(sectionId)) + paste("## ", parameterName, " distributions", anchor(sectionId), sep = "") }, xParameterSection = function(sectionId, parameterName) { - paste("## ", parameterName, "-dependence ", anchor(sectionId), sep = "") + paste("## ", parameterName, "-dependence", anchor(sectionId), sep = "") }, yParameterSection = function(sectionId, parameterName) { - paste("###", parameterName, anchor(sectionId)) + paste("### ", parameterName, anchor(sectionId), sep = "") }, populationSection = function(sectionId, simulationSetName, descriptor, level = 4) { tagLevel <- paste0(rep("#", level), collapse = "") sectionTitle <- paste(tagLevel, "For", reportSimulationSet(simulationSetName, descriptor)) - return(paste(sectionTitle, anchor(sectionId))) + return(paste(sectionTitle, anchor(sectionId), sep = "")) }, histogramLegend = function(data, observed = FALSE) { if (observed) { @@ -163,10 +163,10 @@ captions <- list( paste0("PK parameters for ", reportSimulationSet(simulationSetName, descriptor)) }, outputSection = function(pathName, pathID) { - paste("## PK Parameters of", pathName, anchor(pathID)) + paste("## PK Parameters of ", pathName, anchor(pathID), sep = "") }, parameterSection = function(parameterName, parameterID) { - paste("###", parameterName, anchor(parameterID)) + paste("### ", parameterName, anchor(parameterID), sep = "") }, boxplot = function(parameterName, pathName, simulationSetName, descriptor, plotScale = "linear") { paste( @@ -324,19 +324,22 @@ getTimeRangeCaption <- function(timeRangeName, reference, simulationSetName) { if (isIncluded(timeRangeName, ApplicationRanges$total)) { return(paste( "### For total simulation time range", - anchor(paste0(reference, "-", removeForbiddenLetters(simulationSetName), "-", "total")) + anchor(paste0(reference, "-", removeForbiddenLetters(simulationSetName), "-", "total")), + sep = "" )) } if (isIncluded(timeRangeName, ApplicationRanges$firstApplication)) { return(paste( "### For first application range", - anchor(paste0(reference, "-", removeForbiddenLetters(simulationSetName), "-", "first")) + anchor(paste0(reference, "-", removeForbiddenLetters(simulationSetName), "-", "first")), + sep = "" )) } if (isIncluded(timeRangeName, ApplicationRanges$lastApplication)) { return(paste( "### For last application range", - anchor(paste0(reference, "-", removeForbiddenLetters(simulationSetName), "-", "last")) + anchor(paste0(reference, "-", removeForbiddenLetters(simulationSetName), "-", "last")), + sep = "" )) } } diff --git a/R/configuration-plan.R b/R/configuration-plan.R index 0e0c3004..63f09542 100644 --- a/R/configuration-plan.R +++ b/R/configuration-plan.R @@ -70,7 +70,7 @@ ConfigurationPlan <- R6::R6Class( # Issue #1084: new reference title get anchor at the end of title addTextChunk( fileName = self$getSectionMarkdown(id), - text = paste(self$getSectionTitle(id), anchor(sectionReference)) + text = paste(self$getSectionTitle(id), anchor(sectionReference), sep = "") ) # Add section content sectionContent <- private$.sections$content[selectedId] diff --git a/R/error-checks.R b/R/error-checks.R index 6fbb3a18..012c0d0d 100644 --- a/R/error-checks.R +++ b/R/error-checks.R @@ -669,25 +669,25 @@ checkSamePopulationIds <- function(setIds, #' @keywords internal checkMetaDataIsConsistent <- function(metaData) { groupId <- unique(metaData$group) - if(!isOfLength(unique(metaData$unit), 1)){ + if (!isOfLength(unique(metaData$unit), 1)) { warning( messages$inconsistentMetaData( - values = metaData$unit, - id = groupId, + values = metaData$unit, + id = groupId, dataType = "units" - ), + ), call. = FALSE - ) + ) } - if(!isOfLength(unique(metaData$residualScale), 1)){ + if (!isOfLength(unique(metaData$residualScale), 1)) { warning( messages$inconsistentMetaData( - values = metaData$residualScale, - id = groupId, + values = metaData$residualScale, + id = groupId, dataType = "residualScale" ), call. = FALSE ) } return() -} \ No newline at end of file +} diff --git a/R/gof-plot-task.R b/R/gof-plot-task.R index 586bb449..6ea4a1dc 100644 --- a/R/gof-plot-task.R +++ b/R/gof-plot-task.R @@ -15,8 +15,9 @@ GofPlotTask <- R6::R6Class( addTextChunk( fileName = self$fileName, text = paste( - "##", self$title, "for", simulationSetName, - anchor(paste0(self$reference, "-", removeForbiddenLetters(simulationSetName))) + "## ", self$title, " for ", simulationSetName, + anchor(paste0(self$reference, "-", removeForbiddenLetters(simulationSetName))), + sep = "" ) ) for (result in taskResults) { @@ -76,7 +77,8 @@ GofPlotTask <- R6::R6Class( fileName = self$fileName, text = paste( "## Residuals across all simulations", - anchor(paste0(self$reference, "-residuals-across-all-simulations")) + anchor(paste0(self$reference, "-residuals-across-all-simulations")), + sep = "" ) ) for (result in taskResults) { @@ -136,7 +138,7 @@ GofPlotTask <- R6::R6Class( resetReport(self$fileName) addTextChunk( fileName = self$fileName, - text = paste("#", self$title, anchor(self$reference)) + text = paste("# ", self$title, anchor(self$reference), sep = "") ) if (!is.null(self$outputFolder)) { dir.create(file.path(self$workflowFolder, self$outputFolder), showWarnings = FALSE) diff --git a/R/messages.R b/R/messages.R index 74e3ab94..ae259216 100644 --- a/R/messages.R +++ b/R/messages.R @@ -255,46 +255,46 @@ messages <- list( warningNAFoundInPKAnalysisFile = function(filePath) { paste0(highlight("NaN"), " found in PK analysis file '", highlight(filePath), "'.") }, - warningPKAnalysesMissingIds = function(ids, setName){ + warningPKAnalysesMissingIds = function(ids, setName) { paste0( - "Missing ", highlight("IndividualIds"), " in PKAnalysis file for simulation set '", + "Missing ", highlight("IndividualIds"), " in PKAnalysis file for simulation set '", highlight(setName), "': ", paste0("'", highlight(ids), "'", collapse = ", ") ) }, - warningPKAnalysesMissingIds = function(ids, setName){ + warningPKAnalysesMissingIds = function(ids, setName) { paste0( - "Missing ", highlight("IndividualIds"), " in PKAnalysis file for simulation set '", + "Missing ", highlight("IndividualIds"), " in PKAnalysis file for simulation set '", highlight(setName), "': ", paste0("'", highlight(ids), "'", collapse = ", ") ) }, - warningMissingFromReferenceSet = function(path, simulationSetName, pkParameters = NULL){ - if(is.null(pkParameters)){ + warningMissingFromReferenceSet = function(path, simulationSetName, pkParameters = NULL) { + if (is.null(pkParameters)) { return( paste0( - "Output path '", highlight(path), - "' was NOT defined for reference simulation set '", highlight(simulationSetName), + "Output path '", highlight(path), + "' was NOT defined for reference simulation set '", highlight(simulationSetName), "'. Ouptut path and its PK Parameters were added to the list of figures to export." ) ) } return( paste0( - "The following PK Parameters '", - paste(highlight(pkParameters), collapse = "', '"), - "' were NOT defined for the Ouptut path '", highlight(path), - "' in the reference simulation set '", highlight(simulationSetName), + "The following PK Parameters '", + paste(highlight(pkParameters), collapse = "', '"), + "' were NOT defined for the Ouptut path '", highlight(path), + "' in the reference simulation set '", highlight(simulationSetName), "'. The PK Parameters were added to the list of figures to export." ) ) }, - inconsistentMetaData = function(values, id, dataType = "units"){ + inconsistentMetaData = function(values, id, dataType = "units") { paste0( - "Inconsistent ", highlight(dataType), + "Inconsistent ", highlight(dataType), " found within Group ID '", highlight(id), "': '", paste0(highlight(unique(values)), collapse = "', '"), "'." - ) + ) }, #----- Info messages ---- runStarting = function(runName, subRun = NULL) { diff --git a/R/plot-task.R b/R/plot-task.R index f58b5d63..8979bc8c 100644 --- a/R/plot-task.R +++ b/R/plot-task.R @@ -50,8 +50,9 @@ PlotTask <- R6::R6Class( addTextChunk( fileName = self$fileName, text = paste( - "##", self$title, "for", simulationSetName, - anchor(paste0(self$reference, "-", removeForbiddenLetters(simulationSetName))) + "## ", self$title, " for ", simulationSetName, + anchor(paste0(self$reference, "-", removeForbiddenLetters(simulationSetName))), + sep = "" ) ) for (result in taskResults) { @@ -113,7 +114,7 @@ PlotTask <- R6::R6Class( resetReport(self$fileName) addTextChunk( fileName = self$fileName, - text = paste("#", self$title, anchor(self$reference)) + text = paste("# ", self$title, anchor(self$reference), sep = "") ) if (!is.null(self$outputFolder)) { dir.create(file.path(self$workflowFolder, self$outputFolder), showWarnings = FALSE) diff --git a/R/population-plot-task.R b/R/population-plot-task.R index 5f83a6c2..ff73e434 100644 --- a/R/population-plot-task.R +++ b/R/population-plot-task.R @@ -38,7 +38,7 @@ PopulationPlotTask <- R6::R6Class( resetReport(self$fileName) addTextChunk( fileName = self$fileName, - text = paste("#", self$title, anchor(self$reference)) + text = paste("# ", self$title, anchor(self$reference), sep = "") ) for (result in taskResults) { # Get both absolute and relative paths for figures and tables diff --git a/R/qualification-ddi.R b/R/qualification-ddi.R index 42317797..7faf5425 100644 --- a/R/qualification-ddi.R +++ b/R/qualification-ddi.R @@ -545,8 +545,10 @@ plotQualificationDDIs <- function(configurationPlan, settings) { # Subheading result includes anchor tag to be referenced in TOC textChunk = paste( paste0(rep("#", sectionLevel + 1), collapse = ""), + " ", subplotTypeName, - anchor(paste0(sectionID, "-ddi-subunit-", length(ddiResults) + 1)) + anchor(paste0(sectionID, "-ddi-subunit-", length(ddiResults) + 1)), + sep = "" ), includeTextChunk = TRUE ) @@ -562,8 +564,10 @@ plotQualificationDDIs <- function(configurationPlan, settings) { # Subheading result includes anchor tag to be referenced in TOC textChunk = paste( paste0(rep("#", sectionLevel + 2), collapse = ""), + " ", subplotTypeLevel, - anchor(paste0(sectionID, "-ddi-subunit-", length(ddiResults) + 1)) + anchor(paste0(sectionID, "-ddi-subunit-", length(ddiResults) + 1)), + sep = "" ), includeTextChunk = TRUE ) diff --git a/R/simulation-set.R b/R/simulation-set.R index 331d177f..cf0c1d45 100644 --- a/R/simulation-set.R +++ b/R/simulation-set.R @@ -57,7 +57,7 @@ SimulationSet <- R6::R6Class( validateIsString(simulationFile) validateIsFileExtension(simulationFile, "pkml") validateIsUnitFromDimension(timeUnit, "Time") - + # For optional input, usually null is allowed # but not here as it would mean that nothing would be reported validateIsIncluded(c(applicationRanges), ApplicationRanges) @@ -66,14 +66,14 @@ SimulationSet <- R6::R6Class( validateIsFileExtension(massBalanceFile, "json") self$massBalanceSettings <- jsonlite::fromJSON(massBalanceFile, simplifyVector = FALSE)[["MassBalancePlots"]] } - + # Before loading the simulation, check if the file exists validateFileExists(simulationFile) simulation <- ospsuite::loadSimulation(simulationFile, addToCache = FALSE) validateVector(minimumSimulationEndTime, type = "numeric", valueRange = c(0, Inf), nullAllowed = TRUE) # Following checks require simulation info endTime <- max( - minimumSimulationEndTime, + minimumSimulationEndTime, ospsuite::toUnit( quantityOrDimension = "Time", values = simulation$outputSchema$endTime, @@ -81,7 +81,7 @@ SimulationSet <- R6::R6Class( ) ) validateVectorRange(timeOffset, type = "numeric", valueRange = c(0, endTime)) - + # Test and validate outputs and their paths validateOutputObject(c(outputs), simulation, nullAllowed = TRUE) validateDataSource(dataSource, c(outputs), nullAllowed = TRUE) diff --git a/R/utilities-goodness-of-fit.R b/R/utilities-goodness-of-fit.R index 137e327f..9308d51e 100644 --- a/R/utilities-goodness-of-fit.R +++ b/R/utilities-goodness-of-fit.R @@ -1154,7 +1154,7 @@ getResidualsPlotResultsInGroup <- function(data, metaData, outputId, structureSe plotConfiguration = qqPlotConfiguration ) goodnessOfFitCaptions[[resultId$resQQPlot]] <- getGoodnessOfFitCaptions(structureSet, "resQQPlot", residualScale, settings) - + return(list( plots = goodnessOfFitPlots, captions = goodnessOfFitCaptions diff --git a/R/utilities-mass-balance.R b/R/utilities-mass-balance.R index 3d0af33d..7a8daeea 100644 --- a/R/utilities-mass-balance.R +++ b/R/utilities-mass-balance.R @@ -37,7 +37,7 @@ plotMeanMassBalance <- function(structureSet, settings = NULL) { sectionId <- defaultFileNames$resultID(length(massBalanceResults) + 1, "mass_balance") massBalanceResults[[sectionId]] <- saveTaskResults( id = sectionId, - textChunk = paste("###", plotSettings$Name, anchor(sectionId)), + textChunk = paste("### ", plotSettings$Name, anchor(sectionId), sep = ""), includeTextChunk = TRUE ) } diff --git a/R/utilities-pop-pk-parameters.R b/R/utilities-pop-pk-parameters.R index 6d3b1f8d..ae772d95 100644 --- a/R/utilities-pop-pk-parameters.R +++ b/R/utilities-pop-pk-parameters.R @@ -22,7 +22,7 @@ plotPopulationPKParameters <- function(structureSets, validateIsOfType(c(structureSets), "SimulationStructure") validateIsString(c(xParameters), nullAllowed = TRUE) validateIsOfType(c(yParameters), "Output", nullAllowed = TRUE) - + # Use union of outputs from all the structure sets yParameters <- yParameters %||% getOutputsForPKPlot(structureSets) # Get first simulation, in case mol weight is needed @@ -159,16 +159,16 @@ plotPopulationPKParameters <- function(structureSets, } # Report tables summarizing the distributions - # Caution: since simulationSetName is a factor, + # Caution: since simulationSetName is a factor, # Unused levels need to be removed first to prevent errors in tlf::getPKParameterMeasure - allSetNames <-levels(pkParameterData$simulationSetName) + allSetNames <- levels(pkParameterData$simulationSetName) usedSetNames <- unique(as.character(pkParameterData$simulationSetName)) pkParameterTable <- getPKParameterMeasure( - data = pkParameterData %>% + data = pkParameterData %>% mutate(simulationSetName = factor( - simulationSetName, + simulationSetName, levels = intersect(allSetNames, usedSetNames) - )), + )), dataMapping = pkParametersMapping ) # A different table needs to be created here @@ -304,7 +304,7 @@ plotPopulationPKParameters <- function(structureSets, # Regular range plots not associated to workflow type for (simulationSetName in simulationSetNames) { vpcData <- pkParameterData[pkParameterData$simulationSetName %in% simulationSetName, ] - if(nrow(vpcData) == 0){ + if (nrow(vpcData) == 0) { logDebug(paste( "No data found for simulation set", simulationSetName, @@ -803,61 +803,62 @@ getPopulationPKAnalysesFromOutput <- function(data, metaData, output, pkParamete } #' @title getOutputsForPKPlot -#' @description +#' @description #' Get the list of outputs and their PK parameters for population PK parameter plot #' @param structureSets List of `SimulationStructure` objects #' @return list of `Output` objects #' @keywords internal #' @import dplyr -getOutputsForPKPlot <- function(structureSets){ +getOutputsForPKPlot <- function(structureSets) { # Use the first simulation set as reference for PK parameters to plot # Clone R6 objects to prevent potential issues in other workflow steps outputsToPlot <- lapply( - structureSets[[1]]$simulationSet$outputs, - function(output){ + structureSets[[1]]$simulationSet$outputs, + function(output) { output$clone() - }) + } + ) for (structureSet in structureSets) { outputsToAdd <- structureSet$simulationSet$outputs - for(output in outputsToAdd){ + for (output in outputsToAdd) { # Check if output path is included in the initial outputs to plot outputIndex <- head(which(sapply( - outputsToPlot, + outputsToPlot, function(outputToPlot) { isIncluded(outputToPlot$path, output$path) } - )), 1) - if(isEmpty(outputIndex)){ + )), 1) + if (isEmpty(outputIndex)) { warning( messages$warningMissingFromReferenceSet( - path = output$path, + path = output$path, simulationSetName = structureSets[[1]]$simulationSet$simulationSetName - ), + ), call. = FALSE - ) + ) outputsToPlot <- c(outputsToPlot, output$clone()) next } # If output path is included, check if PK parameters are the same pkParametersToPlot <- sapply( outputsToPlot[[outputIndex]]$pkParameters, - function(pkParameter){ + function(pkParameter) { pkParameter$pkParameter - } - ) + } + ) pkParametersToAdd <- sapply( output$pkParameters, - function(pkParameter){ + function(pkParameter) { pkParameter$pkParameter } ) - if(isIncluded(pkParametersToAdd, pkParametersToPlot)){ + if (isIncluded(pkParametersToAdd, pkParametersToPlot)) { next } indicesToAdd <- which(!(pkParametersToAdd %in% pkParametersToPlot)) warning( messages$warningMissingFromReferenceSet( - path = output$path, + path = output$path, simulationSetName = structureSets[[1]]$simulationSet$simulationSetName, pkParameters = pkParametersToAdd[indicesToAdd] ), @@ -870,4 +871,4 @@ getOutputsForPKPlot <- function(structureSets){ } } return(outputsToPlot) -} \ No newline at end of file +} diff --git a/R/utilities-simulation-set.R b/R/utilities-simulation-set.R index c590a1fc..639d3b31 100644 --- a/R/utilities-simulation-set.R +++ b/R/utilities-simulation-set.R @@ -122,7 +122,7 @@ loadSimulationWithUpdatedPaths <- function(simulationSet, loadFromCache = FALSE, paths <- getOutputPathsInSimulationSet(simulationSet) ospsuite::addOutputs(quantitiesOrPaths = paths, simulation = simulation) } - + # Add timeOffset time point to output schema simulation$outputSchema$addTimePoints( timePoints = ospsuite::toBaseUnit( @@ -131,7 +131,7 @@ loadSimulationWithUpdatedPaths <- function(simulationSet, loadFromCache = FALSE, unit = simulationSet$timeUnit ) ) - + # Update simulation end time if minimum is longer than current simulation end time endTime <- max( simulation$outputSchema$endTime, @@ -144,7 +144,7 @@ loadSimulationWithUpdatedPaths <- function(simulationSet, loadFromCache = FALSE, if (endTime <= simulation$outputSchema$endTime) { return(simulation) } - # Get interval that includes current endTime, + # Get interval that includes current endTime, # if mutliple intervals include endTime, update the last one endTimes <- sapply( simulation$outputSchema$intervals, diff --git a/man/CalculatePKParametersTask.Rd b/man/CalculatePKParametersTask.Rd index 4e9d409a..9b5a06a2 100644 --- a/man/CalculatePKParametersTask.Rd +++ b/man/CalculatePKParametersTask.Rd @@ -8,7 +8,7 @@ R6 class for defining how pk parameters are calculated and save } \keyword{internal} \section{Super classes}{ -\code{\link[ospsuite.reportingengine:Task]{ospsuite.reportingengine::Task}} -> \code{\link[ospsuite.reportingengine:SimulationTask]{ospsuite.reportingengine::SimulationTask}} -> \code{CalculatePKParametersTask} +\code{ospsuite.reportingengine::Task} -> \code{ospsuite.reportingengine::SimulationTask} -> \code{CalculatePKParametersTask} } \section{Public fields}{ \if{html}{\out{
}} diff --git a/man/GofPlotTask.Rd b/man/GofPlotTask.Rd index be247a99..5e57992c 100644 --- a/man/GofPlotTask.Rd +++ b/man/GofPlotTask.Rd @@ -32,7 +32,7 @@ Other workflow tasks: } \concept{workflow tasks} \section{Super classes}{ -\code{\link[ospsuite.reportingengine:Task]{ospsuite.reportingengine::Task}} -> \code{\link[ospsuite.reportingengine:PlotTask]{ospsuite.reportingengine::PlotTask}} -> \code{GofPlotTask} +\code{ospsuite.reportingengine::Task} -> \code{ospsuite.reportingengine::PlotTask} -> \code{GofPlotTask} } \section{Methods}{ \subsection{Public methods}{ @@ -118,7 +118,7 @@ Run task and save its output results \subsection{Method \code{getResidualsResults()}}{ Get plot results for residuals across all simulations \subsection{Usage}{ -\if{html}{\out{
}}\preformatted{GofPlotTask$getResidualsResults(structureSets, data, settings)}\if{html}{\out{
}} +\if{html}{\out{
}}\preformatted{GofPlotTask$getResidualsResults(structureSets, data, metaData, settings)}\if{html}{\out{
}} } \subsection{Arguments}{ @@ -128,6 +128,8 @@ Get plot results for residuals across all simulations \item{\code{data}}{data.frame} +\item{\code{metaData}}{A data.frame containing relevant information about the residuals} + \item{\code{settings}}{List of settings such as `PlotConfiguration` R6 class objects for each goodness of fit plot} } \if{html}{\out{
}} diff --git a/man/GofTaskSettings.Rd b/man/GofTaskSettings.Rd index b372f00d..a0388ce7 100644 --- a/man/GofTaskSettings.Rd +++ b/man/GofTaskSettings.Rd @@ -39,7 +39,7 @@ workflow$plotTimeProfilesAndResiduals$settings$getStatistics() } \keyword{internal} \section{Super class}{ -\code{\link[ospsuite.reportingengine:TaskSettings]{ospsuite.reportingengine::TaskSettings}} -> \code{GofTaskSettings} +\code{ospsuite.reportingengine::TaskSettings} -> \code{GofTaskSettings} } \section{Public fields}{ \if{html}{\out{
}} diff --git a/man/MeanModelWorkflow.Rd b/man/MeanModelWorkflow.Rd index 341fb0fa..4c6a11f7 100644 --- a/man/MeanModelWorkflow.Rd +++ b/man/MeanModelWorkflow.Rd @@ -13,7 +13,7 @@ Other workflows: } \concept{workflows} \section{Super class}{ -\code{\link[ospsuite.reportingengine:Workflow]{ospsuite.reportingengine::Workflow}} -> \code{MeanModelWorkflow} +\code{ospsuite.reportingengine::Workflow} -> \code{MeanModelWorkflow} } \section{Public fields}{ \if{html}{\out{
}} diff --git a/man/PlotTask.Rd b/man/PlotTask.Rd index 42ed480d..9b2d86bf 100644 --- a/man/PlotTask.Rd +++ b/man/PlotTask.Rd @@ -32,7 +32,7 @@ Other workflow tasks: } \concept{workflow tasks} \section{Super class}{ -\code{\link[ospsuite.reportingengine:Task]{ospsuite.reportingengine::Task}} -> \code{PlotTask} +\code{ospsuite.reportingengine::Task} -> \code{PlotTask} } \section{Public fields}{ \if{html}{\out{
}} diff --git a/man/PopulationPlotTask.Rd b/man/PopulationPlotTask.Rd index 7e6fc2d0..357d6ac2 100644 --- a/man/PopulationPlotTask.Rd +++ b/man/PopulationPlotTask.Rd @@ -32,7 +32,7 @@ Other workflow tasks: } \concept{workflow tasks} \section{Super classes}{ -\code{\link[ospsuite.reportingengine:Task]{ospsuite.reportingengine::Task}} -> \code{\link[ospsuite.reportingengine:PlotTask]{ospsuite.reportingengine::PlotTask}} -> \code{PopulationPlotTask} +\code{ospsuite.reportingengine::Task} -> \code{ospsuite.reportingengine::PlotTask} -> \code{PopulationPlotTask} } \section{Public fields}{ \if{html}{\out{
}} diff --git a/man/PopulationSensitivityAnalysisTask.Rd b/man/PopulationSensitivityAnalysisTask.Rd index c20a58ac..f277871f 100644 --- a/man/PopulationSensitivityAnalysisTask.Rd +++ b/man/PopulationSensitivityAnalysisTask.Rd @@ -32,7 +32,7 @@ Other workflow tasks: } \concept{workflow tasks} \section{Super classes}{ -\code{\link[ospsuite.reportingengine:Task]{ospsuite.reportingengine::Task}} -> \code{\link[ospsuite.reportingengine:SensitivityAnalysisTask]{ospsuite.reportingengine::SensitivityAnalysisTask}} -> \code{PopulationSensitivityAnalysisTask} +\code{ospsuite.reportingengine::Task} -> \code{ospsuite.reportingengine::SensitivityAnalysisTask} -> \code{PopulationSensitivityAnalysisTask} } \section{Public fields}{ \if{html}{\out{
}} diff --git a/man/PopulationSimulationSet.Rd b/man/PopulationSimulationSet.Rd index 69127fd4..cd398618 100644 --- a/man/PopulationSimulationSet.Rd +++ b/man/PopulationSimulationSet.Rd @@ -7,7 +7,7 @@ R6 class representing Reporting Engine Population Model Set } \section{Super class}{ -\code{\link[ospsuite.reportingengine:SimulationSet]{ospsuite.reportingengine::SimulationSet}} -> \code{PopulationSimulationSet} +\code{ospsuite.reportingengine::SimulationSet} -> \code{PopulationSimulationSet} } \section{Public fields}{ \if{html}{\out{
}} diff --git a/man/PopulationWorkflow.Rd b/man/PopulationWorkflow.Rd index 76fc9850..02b9d278 100644 --- a/man/PopulationWorkflow.Rd +++ b/man/PopulationWorkflow.Rd @@ -13,7 +13,7 @@ Other workflows: } \concept{workflows} \section{Super class}{ -\code{\link[ospsuite.reportingengine:Workflow]{ospsuite.reportingengine::Workflow}} -> \code{PopulationWorkflow} +\code{ospsuite.reportingengine::Workflow} -> \code{PopulationWorkflow} } \section{Public fields}{ \if{html}{\out{
}} diff --git a/man/QualificationTask.Rd b/man/QualificationTask.Rd index 71b8df58..bf1a7e22 100644 --- a/man/QualificationTask.Rd +++ b/man/QualificationTask.Rd @@ -32,7 +32,7 @@ Other workflow tasks: } \concept{workflow tasks} \section{Super classes}{ -\code{\link[ospsuite.reportingengine:Task]{ospsuite.reportingengine::Task}} -> \code{\link[ospsuite.reportingengine:PlotTask]{ospsuite.reportingengine::PlotTask}} -> \code{QualificationTask} +\code{ospsuite.reportingengine::Task} -> \code{ospsuite.reportingengine::PlotTask} -> \code{QualificationTask} } \section{Methods}{ \subsection{Public methods}{ diff --git a/man/QualificationWorkflow.Rd b/man/QualificationWorkflow.Rd index 95d5de8d..476cd45c 100644 --- a/man/QualificationWorkflow.Rd +++ b/man/QualificationWorkflow.Rd @@ -13,7 +13,7 @@ Other workflows: } \concept{workflows} \section{Super class}{ -\code{\link[ospsuite.reportingengine:Workflow]{ospsuite.reportingengine::Workflow}} -> \code{QualificationWorkflow} +\code{ospsuite.reportingengine::Workflow} -> \code{QualificationWorkflow} } \section{Public fields}{ \if{html}{\out{
}} diff --git a/man/SensitivityAnalysisTask.Rd b/man/SensitivityAnalysisTask.Rd index 0519313c..4d9c8e74 100644 --- a/man/SensitivityAnalysisTask.Rd +++ b/man/SensitivityAnalysisTask.Rd @@ -32,7 +32,7 @@ Other workflow tasks: } \concept{workflow tasks} \section{Super class}{ -\code{\link[ospsuite.reportingengine:Task]{ospsuite.reportingengine::Task}} -> \code{SensitivityAnalysisTask} +\code{ospsuite.reportingengine::Task} -> \code{SensitivityAnalysisTask} } \section{Public fields}{ \if{html}{\out{
}} diff --git a/man/SimulationTask.Rd b/man/SimulationTask.Rd index 49160e85..9ffd3656 100644 --- a/man/SimulationTask.Rd +++ b/man/SimulationTask.Rd @@ -8,7 +8,7 @@ R6 class for SimulationTask settings } \keyword{internal} \section{Super class}{ -\code{\link[ospsuite.reportingengine:Task]{ospsuite.reportingengine::Task}} -> \code{SimulationTask} +\code{ospsuite.reportingengine::Task} -> \code{SimulationTask} } \section{Public fields}{ \if{html}{\out{
}} diff --git a/man/getOutputGroups.Rd b/man/getOutputGroups.Rd index 6a2bcf89..bb2eb7f9 100644 --- a/man/getOutputGroups.Rd +++ b/man/getOutputGroups.Rd @@ -13,6 +13,6 @@ getOutputGroups(metaDataFrame) List of data.frames data.frame with variables `path`, `dimension`, `unit`, `group`, `color`, `fill` } \description{ -Group paths with same group IDs and Units +Group paths with same group IDs and check their units and residuals are consistent } \keyword{internal} diff --git a/man/reEnv.Rd b/man/reEnv.Rd index ae833acf..5c3bf10d 100644 --- a/man/reEnv.Rd +++ b/man/reEnv.Rd @@ -5,7 +5,7 @@ \alias{reEnv} \title{reEnv} \format{ -An object of class \code{environment} of length 38. +An object of class \code{environment} of length 39. } \usage{ reEnv diff --git a/man/reSettingsNames.Rd b/man/reSettingsNames.Rd index f4471fc4..6fe86817 100644 --- a/man/reSettingsNames.Rd +++ b/man/reSettingsNames.Rd @@ -5,7 +5,7 @@ \alias{reSettingsNames} \title{reSettingsNames} \format{ -An object of class \code{list} of length 38. +An object of class \code{list} of length 39. } \usage{ reSettingsNames diff --git a/tests/testthat/test-ddi-report.R b/tests/testthat/test-ddi-report.R index a47f87aa..8bc70d60 100644 --- a/tests/testthat/test-ddi-report.R +++ b/tests/testthat/test-ddi-report.R @@ -57,14 +57,14 @@ test_that("Subunits are alphabetically ordered", { test_that("Subunits are included in TOC", { tocSubunits <- c( - "\\* \\[1.1 Mechanism \\]", - "\\* \\[1.1.1 M1 \\]", - "\\* \\[1.2 Perpetrator \\]", - "\\* \\[1.2.1 P1 \\]", - "\\* \\[1.2.2 P2 \\]", - "\\* \\[1.3 Victim \\]", - "\\* \\[1.3.1 V1 \\]", - "\\* \\[1.3.2 V2 \\]" + "\\* \\[1.1 Mechanism\\]", + "\\* \\[1.1.1 M1\\]", + "\\* \\[1.2 Perpetrator\\]", + "\\* \\[1.2.1 P1\\]", + "\\* \\[1.2.2 P2\\]", + "\\* \\[1.3 Victim\\]", + "\\* \\[1.3.1 V1\\]", + "\\* \\[1.3.2 V2\\]" ) for (subunit in tocSubunits) { subunitLine <- grep(pattern = subunit, x = reportContent) From 252a1667c9e5c8ee8ce6d30702646d25f1ab6f45 Mon Sep 17 00:00:00 2001 From: Pierre Chelle <45343665+pchelle@users.noreply.github.com> Date: Wed, 4 Sep 2024 07:22:47 -0400 Subject: [PATCH 4/4] Fixes #1046 use 2 template dictionaries with and without LLOQ (#1273) --- inst/extdata/WorkflowInput.xlsx | Bin 54558 -> 55746 bytes inst/extdata/tpDictionary.csv | 2 +- inst/extdata/tpDictionaryLoq.csv | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/inst/extdata/WorkflowInput.xlsx b/inst/extdata/WorkflowInput.xlsx index 828c4dc3df2ec1607621efbda09fdceecee3d44f..70aeeb1d1d9237669edf7627f0557312c2701ea0 100644 GIT binary patch delta 24601 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

5*SVY=4k>Ph8d0G0xVK5Sl^in_eA2`( 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 diff --git a/inst/extdata/tpDictionary.csv b/inst/extdata/tpDictionary.csv index 670ef4a9..73bdc775 100644 --- a/inst/extdata/tpDictionary.csv +++ b/inst/extdata/tpDictionary.csv @@ -7,5 +7,5 @@ tad,timeprofile,TAD,h,,, age,covariate,AGE,year(s),Age,Organism|Age, wght,covariate,WGHT,kg,Body weight,Organism|Weight, hght,covariate,HGHT,cm,Height,Organism|Height, -bmi,covariate,BMI,kg/m2,BMI,Organism|BMI, +bmi,covariate,BMI,kg/m²,BMI,Organism|BMI, gender,covariate,SEX,,SEX,Gender,Make sure male="MALE" and female="FEMALE" \ No newline at end of file diff --git a/inst/extdata/tpDictionaryLoq.csv b/inst/extdata/tpDictionaryLoq.csv index 235b24a0..133d268d 100644 --- a/inst/extdata/tpDictionaryLoq.csv +++ b/inst/extdata/tpDictionaryLoq.csv @@ -7,6 +7,6 @@ tad,timeprofile,TAD,h,,, age,covariate,AGE,year(s),Age,Organism|Age, wght,covariate,WGHT,kg,Body weight,Organism|Weight, hght,covariate,HGHT,cm,Height,Organism|Height, -bmi,covariate,BMI,kg/m2,BMI,Organism|BMI, +bmi,covariate,BMI,kg/m²,BMI,Organism|BMI, gender,covariate,SEX,,SEX,Gender,Make sure male="MALE" and female="FEMALE" lloq,timeprofile,LOQ,,,,units are defined in corresponding output definitions \ No newline at end of file