R/task.R

#' @title Task
#' @description  R6 class for Task settings
#' @field active logical indicating if `Task` is performed in a workflow.
#' @field outputFolder List of output files/folders to save the task output
#' @field workflowFolder folder where workflow is run and saved
#' @field settings list of settings for task such as plot configurations
#' @field message message or title of the task
#' @export
#' @import ospsuite.utils
#' @family workflow tasks
Task <- R6::R6Class(
  "Task",
  public = list(
    active = NULL,
    outputFolder = NULL,
    workflowFolder = NULL,
    settings = NULL,
    message = NULL,

    #' @description
    #' Create a `Task` object
    #' @param outputFolder task output folder to save results
    #' @param inputFolder task input folder where input files are stored
    #' @param inputs expected input files required by task
    #' @param outputs expected output files generated by task
    #' @param workflowFolder folder where workflow is run and saved
    #' @param settings specific settings for task (e.g. plot configurations)
    #' @param active logical indicating if `Task` is performed in a workflow.
    #' Default value is `FALSE`
    #' @param message message of the `Task`.
    #' @return A new `Task` object
    initialize = function(outputFolder = NULL,
                          inputFolder = NULL,
                          inputs = NULL,
                          outputs = NULL,
                          workflowFolder = getwd(),
                          settings = NULL,
                          active = FALSE,
                          message = NULL) {
      validateIsOfType(active, "logical")
      validateIsString(c(outputFolder, inputFolder, inputs, outputs), nullAllowed = TRUE)

      self$active <- active
      self$outputFolder <- outputFolder
      self$workflowFolder <- workflowFolder
      self$settings <- settings
      self$message <- message

      private$.inputFolder <- inputFolder
      private$.inputs <- inputs
      private$.outputs <- outputs
    },

    #' @description
    #' Activate `Task`
    activate = function() {
      self$active <- TRUE
    },
    #' @description
    #' Inactivate `Task`
    inactivate = function() {
      self$active <- FALSE
    },
    #' @description
    #' Check if `Task` inputs exist
    #' @return logical indicating if input is valid
    validateInput = function() {
      isValid <- TRUE
      for (inputToCheck in private$.inputs) {
        if (!file.exists(inputToCheck)) {
          isValid <- FALSE
          logErrorThenStop(messages$errorTaskInputDoesNotExist(inputToCheck))
        }
      }
      return(isValid)
    },
    #' @description
    #' Check if a task input from a specific `SimulationStructure` is valid
    #' @param structureSet `SimulationStructure` object
    #' @return logical indicating if input is valid
    validateStructureSetInput = function(structureSet) {
      validateIsOfType(structureSet, "SimulationStructure")
      # Get only the input from the structure set
      structureSetInputs <- c(
        structureSet$simulationResultFileNames,
        structureSet$pkAnalysisResultsFileNames,
        structureSet$sensitivityAnalysisResultsFileNames
      )
      inputsToCheck <- intersect(structureSetInputs, private$.inputs)
      # If no required input
      if (isEmpty(inputsToCheck)) {
        return(TRUE)
      }
      tryCatch(
        {
          validateFileExists(inputsToCheck, nullAllowed = TRUE)
        },
        error = function(e) {
          missingInputs <- inputsToCheck[!file.exists(inputsToCheck)]
          logErrorThenStop(message = messages$errorTaskInputDoesNotExist(missingInputs), self$workflowFolder)
        }
      )
      # If no error is caught, return isValid = TRUE
      return(TRUE)
    },

    #' @description
    #' Print `Task` features
    #' @return Text of task features
    print = function() {
      taskActiveMessage <- " NOT"
      if (self$active) {
        taskActiveMessage <- ""
      }

      info <- c(
        sprintf("Task: %s", self$message %||% ""),
        sprintf("Task is%s active", taskActiveMessage),
        sprintf("Workflow folder: %s", self$workflowFolder %||% ""),
        sprintf("Expected input folder: %s", private$.inputFolder %||% "none"),
        sprintf("Expected input files: %s", ifNotNull(
          private$.inputs,
          paste0(private$.inputs, collapse = ", "),
          "none"
        )),
        sprintf("Expected output folder: %s", self$outputFolder %||% "none"),
        sprintf("Expected output files: %s", ifNotNull(
          private$.outputs,
          paste0(private$.outputs, collapse = ", "),
          "none"
        ))
      )
      invisible(self)
      return(info)
    },

    #' @description
    #' Get the relative path to a file to be output by this task
    #' @param fileName name (with extension) of the file to be output
    #' @return Output file's relative path
    getRelativePath = function(fileName) {
      return(file.path(self$outputFolder, fileName))
    },

    #' @description
    #' Get the absolute path to a file to be output by this task
    #' @param fileName name (with extension) of the file to be output
    #' @return Output file's absolute path
    getAbsolutePath = function(fileName) {
      return(file.path(self$workflowFolder, self$outputFolder, fileName))
    },

    #' @description
    #' Get `Task` required input files
    #' @return Required file names
    getInputs = function() {
      return(private$.inputs)
    }
  ),
  private = list(
    .inputFolder = NULL,
    .inputs = NULL,
    .outputs = NULL
  )
)
Open-Systems-Pharmacology/OSPSuite.ReportingEngine documentation built on May 1, 2024, 12:27 p.m.