WITH_DIMENSION_EXTENSION <- "OSPSuite.Core.Domain.WithDimensionExtensions"
WITH_DISPLAY_UNIT_EXTENSION <- "OSPSuite.Core.Domain.WithDisplayUnitExtensions"
QUANTITY_EXTENSIONS <- "OSPSuite.Core.Domain.QuantityExtensions"
#' @title Quantity
#' @docType class
#' @description A quantity of the model (with unit, value) such as a Parameter or an Amount
#' @format NULL
Quantity <- R6::R6Class(
"Quantity",
cloneable = FALSE,
inherit = Entity,
active = list(
#' @field value The value of the quantity in unit
value = function(value) {
private$.wrapProperty("Value", value)
},
#' @field unit The base unit in which the quantity value is defined (Read-Only)
unit = function(value) {
private$.unit <- private$.wrapExtensionMethodCached(WITH_DIMENSION_EXTENSION, "BaseUnitName", "unit", private$.unit, value)
return(private$.unit)
},
#' @field displayUnit The unit in which the quantity value is usually displayed (Read-Only)
displayUnit = function(value) {
private$.wrapExtensionMethod(WITH_DISPLAY_UNIT_EXTENSION, "DisplayUnitName", "displayUnit", value)
},
#' @field dimension The dimension in which the quantity is defined (Read-Only)
dimension = function(value) {
private$.dimension <- private$.wrapExtensionMethodCached(WITH_DIMENSION_EXTENSION, "DimensionName", "dimension", private$.dimension, value)
return(private$.dimension)
},
#' @field allUnits the list of all supported units (Read-Only)
allUnits = function(value) {
# Optimized implementation to avoid constant marshalling with .NET. We saved the array of units once the first time it is accessed
private$.allUnits <- private$.wrapExtensionMethodCached(WITH_DIMENSION_EXTENSION, "AllUnitNames", "allUnits", private$.allUnits, value)
return(private$.allUnits)
},
#' @field quantityType The type of the quantity (Read-Only)
quantityType = function(value) {
private$.wrapReadOnlyProperty("QuantityTypeAsString", value)
},
#' @field formula An instance of a `Formula` object used by this quantity (Read-Only)
formula = function(value) {
private$.readOnlyProperty("formula", value, private$.formula)
},
#' @field isTable Returns `TRUE` if the formula used by this quantity is a table formula otherwise `FALSE`
isTable = function(value) {
private$.readOnlyProperty("isTable", value, self$formula$isTable)
},
#' @field isConstant Returns `TRUE` if the formula used by this quantity is a constant formula otherwise `FALSE`
isConstant = function(value) {
private$.readOnlyProperty("isConstant", value, self$formula$isConstant)
},
#' @field isFormula Returns `TRUE` if the formula used by this quantity is an explicit formula (e.g an equation) otherwise `FALSE`
isFormula = function(value) {
private$.readOnlyProperty("isFormula", value, self$formula$isExplicit)
},
#' @field isDistributed Returns `TRUE` if the quantity represents a quantity with an underlying distribution otherwise `FALSE`
isDistributed = function(value) {
private$.readOnlyProperty("isDistributed", value, self$formula$isDistributed)
},
#' @field formulaString Returns the equation of the formula for a quantity using an explicit formula (e.g. `isFormula == TRUE`) or `NULL` for a quantity that does not use an explicit formula.
formulaString = function(value) {
private$.readOnlyProperty("formulaString", value, self$formula$formulaString)
},
#' @field isFixedValue Returns `TRUE` if the formula was overridden by a constant value, otherwise `FALSE`
isFixedValue = function(value) {
private$.wrapProperty("IsFixedValue", value)
}
),
private = list(
.formula = NULL,
.allUnits = NULL,
.unit = NULL,
.dimension = NULL,
.printQuantity = function(valueCaption = "Value") {
private$.printClass()
private$.printLine("Path", self$path)
self$printQuantityValue(valueCaption)
self$formula$printFormula()
if (!self$isConstant && !self$isDistributed) {
private$.printLine("Value overrides formula", self$isFixedValue)
}
invisible(self)
}
),
public = list(
#' @description
#' Initialize a new instance of the class
#' @param netObject A `NetObject` object with the pointer to the .NET `Quantity`
#' @return A new `Quantity` object.
initialize = function(netObject) {
super$initialize(netObject)
# Cannot use property Formula directly from the quantity because of new override in Distributed Parameter
formula <- private$.wrapExtensionMethod(QUANTITY_EXTENSIONS, "GetFormula")
private$.formula <- Formula$new(formula)
if (self$isTable) {
private$.formula <- TableFormula$new(formula)
}
},
#' @description
#' Print the object to the console
#' @param ... Rest arguments.
print = function(...) {
private$.printQuantity()
private$.printLine("Quantity Type", self$quantityType)
},
#' @description
#' Print the name of the quantity and its value
printValue = function() {
self$printQuantityValue(self$name)
},
#' @description
#' Print the value (in scientific notation with 2 digits when needed) and unit of the quantity
#' @param caption Text to prepend to the value
printQuantityValue = function(caption) {
scientific <- FALSE
if (!is.nan(self$value) & (self$value >= 10000 | self$value < 0.01)) {
scientific <- TRUE
}
QuantityValue <- formatNumerics(self$value, scientific = scientific)
if (self$unit != "") {
QuantityValue <- paste0(QuantityValue, " [", self$unit, "]")
}
private$.printLine(caption, QuantityValue)
},
#' @description
#' Convert value from unit to the base unit and sets the value in base unit.
#' @param value Value to set. If unit is null, we assume that the value is in base unit
#' @param unit Optional unit in which the value is given.
setValue = function(value, unit = NULL) {
validateIsNumeric(value)
validateIsString(unit, nullAllowed = TRUE)
if (!is.null(unit)) {
unit <- .encodeUnit(unit)
.validateHasUnit(self, unit)
value <- rSharp::callStatic(WITH_DIMENSION_EXTENSION, "ConvertToBaseUnit", self, value, unit)
}
self$value <- value
},
#' @description
#' Returns `TRUE` if the quantity supports the given unit otherwise `FALSE`.
#' For the list of supported units, use `allUnits`
#' @param unit Unit to check
hasUnit = function(unit) {
validateIsString(unit)
any(self$allUnits == unit)
},
#' @description
#' Ensures that the quantity uses the value computed by its formula. It is a shortcut for `self$isFixedValue <- false`.
reset = function() {
self$isFixedValue <- FALSE
}
)
)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.