From 35d75cd2edd538b71d7c794cdfa61ea13d8e75bc Mon Sep 17 00:00:00 2001 From: Lucian Smith Date: Wed, 30 Sep 2026 17:28:13 -0700 Subject: [PATCH 1/5] Update several specsheets. This is a good test of what happens when we run existing tests when a specsheet is updated. --- .../LoopVariable/v1.0.0/description.md | 4 +- .../WorkingAlgorithm/v1.0.0/description.md | 6 +-- .../WorkingAlgorithm/v1.0.0/schema.json | 2 +- .../v1.0.0/AbstractSimulation.png | Bin 20871 -> 17927 bytes .../AbstractSimulation/v1.0.0/description.md | 2 +- .../v1.0.0/outputs.json | 7 --- .../BoundedODESimulation/v1.0.0/outputs.json | 5 -- .../v1.0.0/outputs.json | 5 -- .../tasks/Calculation/v1.0.0/outputs.json | 4 -- .../tasks/CreateDataBlock/v1.0.0/outputs.json | 4 -- .../tasks/CsvImport/v1.0.0/outputs.json | 7 --- .../tasks/DataImport/v1.0.0/outputs.json | 4 -- .../DrawFromDistribution/v1.0.0/outputs.json | 7 --- .../ExplicitODESimulation/v1.0.0/outputs.json | 5 -- .../v1.0.0/outputs.json | 5 -- .../v1.0.0/FluxBalanceAnalysis.png | Bin 14925 -> 15039 bytes .../FluxBalanceAnalysis/v1.0.0/description.md | 10 ++-- .../FluxBalanceAnalysis/v1.0.0/outputs.json | 5 -- .../FluxBalanceAnalysis/v1.0.0/schema.json | 14 ++--- .../validation/FluxBalanceAnalysis-0006.md | 10 ---- .../validation/FluxBalanceAnalysis-0007.md | 10 ---- .../tasks/JacobianFull/v1.0.0/outputs.json | 7 --- .../tasks/JacobianReduced/v1.0.0/outputs.json | 7 --- specsheets/tasks/Loop/v1.0.0/Loop.png | Bin 10651 -> 7935 bytes specsheets/tasks/Loop/v1.0.0/description.md | 12 ++--- specsheets/tasks/Loop/v1.0.0/outputs.json | 31 ++++++----- specsheets/tasks/Loop/v1.0.0/schema.json | 10 +++- .../tasks/ModelChange/v1.0.0/outputs.json | 7 --- .../ModelElementList/v1.0.0/outputs.json | 7 --- .../tasks/ModelImport/v1.0.0/outputs.json | 7 --- .../tasks/NumericRange/v1.0.0/outputs.json | 7 --- .../OneStepODESimulation/v1.0.0/outputs.json | 5 -- .../v1.0.0/OneStepStochasticSimulation.png | Bin 13449 -> 14911 bytes .../v1.0.0/outputs.json | 5 -- .../tasks/ParameterRange/v1.0.0/outputs.json | 7 --- .../ParameterScan/v1.0.0/ParameterScan.png | Bin 8766 -> 15171 bytes .../tasks/ParameterScan/v1.0.0/description.md | 11 ++-- .../tasks/ParameterScan/v1.0.0/outputs.json | 48 ++++++++++++++---- specsheets/tasks/Range/v1.0.0/outputs.json | 7 --- .../tasks/RelabelData/v1.0.0/outputs.json | 4 -- specsheets/tasks/Repeat/v1.0.0/Repeat.png | Bin 25928 -> 17741 bytes specsheets/tasks/Repeat/v1.0.0/description.md | 14 ++--- specsheets/tasks/Repeat/v1.0.0/schema.json | 4 -- .../Repeat/v1.0.0/validation/Repeat-0005.md | 10 ---- specsheets/tasks/Scatter/v1.0.0/Scatter.png | Bin 3324 -> 11258 bytes .../tasks/Scatter/v1.0.0/description.md | 10 ++-- specsheets/tasks/Scatter/v1.0.0/outputs.json | 9 ---- specsheets/tasks/Scatter/v1.0.0/schema.json | 10 +++- specsheets/tasks/Span/v1.0.0/outputs.json | 12 +---- .../tasks/SteadyState/v1.0.0/SteadyState.png | Bin 16617 -> 16780 bytes .../tasks/SteadyState/v1.0.0/description.md | 10 ++-- .../tasks/SteadyState/v1.0.0/outputs.json | 5 -- .../tasks/SteadyState/v1.0.0/schema.json | 14 ++--- .../v1.0.0/validation/SteadyState-0005.md | 10 ---- .../v1.0.0/validation/SteadyState-0006.md | 10 ---- .../tasks/StringFormation/v1.0.0/outputs.json | 5 -- 56 files changed, 124 insertions(+), 297 deletions(-) delete mode 100644 specsheets/tasks/FluxBalanceAnalysis/v1.0.0/validation/FluxBalanceAnalysis-0006.md delete mode 100644 specsheets/tasks/FluxBalanceAnalysis/v1.0.0/validation/FluxBalanceAnalysis-0007.md delete mode 100644 specsheets/tasks/Repeat/v1.0.0/validation/Repeat-0005.md delete mode 100644 specsheets/tasks/SteadyState/v1.0.0/validation/SteadyState-0005.md delete mode 100644 specsheets/tasks/SteadyState/v1.0.0/validation/SteadyState-0006.md diff --git a/specsheets/auxiliary/LoopVariable/v1.0.0/description.md b/specsheets/auxiliary/LoopVariable/v1.0.0/description.md index 69a4377..701852b 100644 --- a/specsheets/auxiliary/LoopVariable/v1.0.0/description.md +++ b/specsheets/auxiliary/LoopVariable/v1.0.0/description.md @@ -1,8 +1,6 @@ # LoopVariable -![LoopVariable UML diagram](../../../tasks/Loop/v1.0.0/Loop.png) - -*(`LoopVariable` has no standalone diagram of its own - the image above is `Loop`'s diagram, reused here because `LoopVariable` is drawn fully within it as a linked box, right next to `Loop`. Look for the `LoopVariable` box.)* +![LoopVariable UML diagram](./LoopVariable.png) **Category:** auxiliary **Version:** v1 diff --git a/specsheets/auxiliary/WorkingAlgorithm/v1.0.0/description.md b/specsheets/auxiliary/WorkingAlgorithm/v1.0.0/description.md index 11d4979..05a8391 100644 --- a/specsheets/auxiliary/WorkingAlgorithm/v1.0.0/description.md +++ b/specsheets/auxiliary/WorkingAlgorithm/v1.0.0/description.md @@ -1,8 +1,6 @@ # WorkingAlgorithm -![WorkingAlgorithm UML diagram](../../../tasks/AbstractSimulation/v1.0.0/AbstractSimulation.png) - -*(`WorkingAlgorithm` has no standalone diagram of its own - the image above is `AbstractSimulation`'s diagram, reused here because `WorkingAlgorithm` is drawn fully within it as a linked box, right next to `AbstractSimulation`. Look for the `workingAlgorithm` box.)* +![WorkingAlgorithm UML diagram](./WorkingAlgorithm.png) **Category:** auxiliary **Version:** v1 @@ -10,7 +8,7 @@ ## What it does -An algorithm used internally by a simulation task, attached via `AbstractSimulation`'s `workingAlgorithms` list. Beyond the fields it inherits from `SEDBase`, it carries a required `algorithm`. +An algorithm used internally by a task, attached via a `workingAlgorithms` list: the one `AbstractSimulation` defines (and so every ODE/stochastic simulation task has), or the one `SteadyState` and `FluxBalanceAnalysis` each declare directly. Beyond the fields it inherits from `SEDBase`, it carries a required `algorithm`. _(No description yet - placeholder. It's not yet clear from the diagram alone how `algorithm` relates to the task's own `_type` discriminator and `taskParameters`, or how multiple `workingAlgorithms` entries on one task are meant to be distinguished/used - needs updating once that's settled.)_ diff --git a/specsheets/auxiliary/WorkingAlgorithm/v1.0.0/schema.json b/specsheets/auxiliary/WorkingAlgorithm/v1.0.0/schema.json index 5822a1d..c742094 100644 --- a/specsheets/auxiliary/WorkingAlgorithm/v1.0.0/schema.json +++ b/specsheets/auxiliary/WorkingAlgorithm/v1.0.0/schema.json @@ -4,7 +4,7 @@ "title": "SED2 WorkingAlgorithm", "$defs": { "WorkingAlgorithm": { - "description": "An algorithm used internally by a simulation task, referenced via AbstractSimulation's workingAlgorithms list. Inherits from SEDBase.", + "description": "An algorithm used internally by a task, listed in a workingAlgorithms list (AbstractSimulation, SteadyState, FluxBalanceAnalysis). Inherits from SEDBase.", "type": "object", "allOf": [ { diff --git a/specsheets/tasks/AbstractSimulation/v1.0.0/AbstractSimulation.png b/specsheets/tasks/AbstractSimulation/v1.0.0/AbstractSimulation.png index 23c51865ec7c1eb92fedf9adeb18836435b08251..1079d195bdf282f7b655421bb8520b39f770b0d3 100644 GIT binary patch literal 17927 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 Qc)6w|rv@vPd4c%90D{DaRR910 literal 20871 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 Q1dAJNZ5*vjtb7yx1#`i-YybcN diff --git a/specsheets/tasks/AbstractSimulation/v1.0.0/description.md b/specsheets/tasks/AbstractSimulation/v1.0.0/description.md index 508ad4a..c0088ac 100644 --- a/specsheets/tasks/AbstractSimulation/v1.0.0/description.md +++ b/specsheets/tasks/AbstractSimulation/v1.0.0/description.md @@ -8,7 +8,7 @@ ## What it does -`AbstractSimulation` is a schema-only mixin (composed via `allOf`, not instantiated directly, no `_type` or diagram box of its own beyond the one shown here) contributing the fields shared by every ODE or stochastic simulation task, by way of `AbstractODESimulation` and `AbstractStochasticSimulation`. It replaces the earlier `SimulationCommon`, and (unlike `SimulationCommon`) is no longer used by `SteadyState` or `FluxBalanceAnalysis`, which now declare their own fields directly. +`AbstractSimulation` is a schema-only mixin (composed via `allOf`, not instantiated directly, no `_type` or diagram box of its own beyond the one shown here) contributing the fields shared by every ODE or stochastic simulation task, by way of `AbstractODESimulation` and `AbstractStochasticSimulation`. It replaces the earlier `SimulationCommon`, and (unlike `SimulationCommon`) is no longer used by `SteadyState` or `FluxBalanceAnalysis`, which now declare their own fields directly (including their own `workingAlgorithms` lists). Beyond the fields it inherits from `AbstractTask`, it contributes `model`, `independentVariable`, `independentVariableInit`, `outputVariables`, and `workingAlgorithms` - a list of `WorkingAlgorithm` entries describing the algorithm(s) used internally by the simulation. diff --git a/specsheets/tasks/AggregationCalculation/v1.0.0/outputs.json b/specsheets/tasks/AggregationCalculation/v1.0.0/outputs.json index 4e5fabb..204132d 100644 --- a/specsheets/tasks/AggregationCalculation/v1.0.0/outputs.json +++ b/specsheets/tasks/AggregationCalculation/v1.0.0/outputs.json @@ -1,19 +1,12 @@ { "outputs": { "[id]": { - "valid": true, "type": "annotatedData", "dimensions": { "source": "static", "expr": "shapeOf(input) - dim(appliedDimensions or outermost)", "note": "shape is input's shape with the dimension(s) named in appliedDimensions removed (or the outermost dimension, if appliedDimensions is unset); dimension count/sizes are therefore only as knowable as input's own shape is" } - }, - "[id].model": { - "valid": false - }, - "[id].strings": { - "valid": false } } } diff --git a/specsheets/tasks/BoundedODESimulation/v1.0.0/outputs.json b/specsheets/tasks/BoundedODESimulation/v1.0.0/outputs.json index a62ad2f..ae89839 100644 --- a/specsheets/tasks/BoundedODESimulation/v1.0.0/outputs.json +++ b/specsheets/tasks/BoundedODESimulation/v1.0.0/outputs.json @@ -1,7 +1,6 @@ { "outputs": { "[id]": { - "valid": true, "type": "annotatedData", "dimensions": [ { @@ -24,11 +23,7 @@ ] }, "[id].model": { - "valid": true, "type": "model" - }, - "[id].strings": { - "valid": false } } } diff --git a/specsheets/tasks/BoundedStochasticSimulation/v1.0.0/outputs.json b/specsheets/tasks/BoundedStochasticSimulation/v1.0.0/outputs.json index a62ad2f..ae89839 100644 --- a/specsheets/tasks/BoundedStochasticSimulation/v1.0.0/outputs.json +++ b/specsheets/tasks/BoundedStochasticSimulation/v1.0.0/outputs.json @@ -1,7 +1,6 @@ { "outputs": { "[id]": { - "valid": true, "type": "annotatedData", "dimensions": [ { @@ -24,11 +23,7 @@ ] }, "[id].model": { - "valid": true, "type": "model" - }, - "[id].strings": { - "valid": false } } } diff --git a/specsheets/tasks/Calculation/v1.0.0/outputs.json b/specsheets/tasks/Calculation/v1.0.0/outputs.json index f2d04e9..29c695b 100644 --- a/specsheets/tasks/Calculation/v1.0.0/outputs.json +++ b/specsheets/tasks/Calculation/v1.0.0/outputs.json @@ -1,15 +1,11 @@ { "outputs": { "[id]": { - "valid": true, "type": "annotatedData", "dimensions": { "source": "runtime", "note": "shape matches the evaluated math expression: scalar if every operand is scalar, otherwise broadcasts across the shape of any AnnotatedData operand(s); not derivable without evaluating math against the operands' actual values" } - }, - "[id].model": { - "valid": false } } } diff --git a/specsheets/tasks/CreateDataBlock/v1.0.0/outputs.json b/specsheets/tasks/CreateDataBlock/v1.0.0/outputs.json index a6777b5..f932295 100644 --- a/specsheets/tasks/CreateDataBlock/v1.0.0/outputs.json +++ b/specsheets/tasks/CreateDataBlock/v1.0.0/outputs.json @@ -1,7 +1,6 @@ { "outputs": { "[id]": { - "valid": true, "type": "annotatedData", "dimensions": [ { @@ -16,9 +15,6 @@ "note": "base case: one entry per key in the data dictionary. If a value in data is itself multi-dimensional (a list or AnnotatedData), that entry's own dimensions carry through instead - how mixed-dimension entries combine into one overall shape is an open design question (see core-spec.md Section 10), so this formula covers only the uniform-scalar-values case" } ] - }, - "[id].model": { - "valid": false } } } diff --git a/specsheets/tasks/CsvImport/v1.0.0/outputs.json b/specsheets/tasks/CsvImport/v1.0.0/outputs.json index c770299..6e6db57 100644 --- a/specsheets/tasks/CsvImport/v1.0.0/outputs.json +++ b/specsheets/tasks/CsvImport/v1.0.0/outputs.json @@ -1,7 +1,6 @@ { "outputs": { "[id]": { - "valid": true, "type": "annotatedData", "dimensions": [ { @@ -28,12 +27,6 @@ } } ] - }, - "[id].model": { - "valid": false - }, - "[id].strings": { - "valid": false } } } diff --git a/specsheets/tasks/DataImport/v1.0.0/outputs.json b/specsheets/tasks/DataImport/v1.0.0/outputs.json index 0372af2..f0f0d26 100644 --- a/specsheets/tasks/DataImport/v1.0.0/outputs.json +++ b/specsheets/tasks/DataImport/v1.0.0/outputs.json @@ -1,7 +1,6 @@ { "outputs": { "[id]": { - "valid": true, "type": "annotatedData", "dimensions": { "source": "input-file", @@ -9,9 +8,6 @@ "extract": "shape", "note": "shape is whatever the imported file itself has; depends on format and the file at location - extraction is format-specific (format names how to parse it)" } - }, - "[id].model": { - "valid": false } } } diff --git a/specsheets/tasks/DrawFromDistribution/v1.0.0/outputs.json b/specsheets/tasks/DrawFromDistribution/v1.0.0/outputs.json index 7c7498b..8215458 100644 --- a/specsheets/tasks/DrawFromDistribution/v1.0.0/outputs.json +++ b/specsheets/tasks/DrawFromDistribution/v1.0.0/outputs.json @@ -1,16 +1,9 @@ { "outputs": { "[id]": { - "valid": true, "type": "annotatedData", "dimensions": [], "note": "currently always a single scalar value (0-D), indexed historically as [id][0]; the type is multidimensional AnnotatedData to leave room for future correlated multi-value draws (shape of that future case is not yet designed - see core-spec.md Section 10)" - }, - "[id].model": { - "valid": false - }, - "[id].strings": { - "valid": false } } } diff --git a/specsheets/tasks/ExplicitODESimulation/v1.0.0/outputs.json b/specsheets/tasks/ExplicitODESimulation/v1.0.0/outputs.json index 581851e..f7f3b24 100644 --- a/specsheets/tasks/ExplicitODESimulation/v1.0.0/outputs.json +++ b/specsheets/tasks/ExplicitODESimulation/v1.0.0/outputs.json @@ -1,7 +1,6 @@ { "outputs": { "[id]": { - "valid": true, "type": "annotatedData", "dimensions": [ { @@ -24,11 +23,7 @@ ] }, "[id].model": { - "valid": true, "type": "model" - }, - "[id].strings": { - "valid": false } } } diff --git a/specsheets/tasks/ExplicitStochasticSimulation/v1.0.0/outputs.json b/specsheets/tasks/ExplicitStochasticSimulation/v1.0.0/outputs.json index 253d20c..fb495cf 100644 --- a/specsheets/tasks/ExplicitStochasticSimulation/v1.0.0/outputs.json +++ b/specsheets/tasks/ExplicitStochasticSimulation/v1.0.0/outputs.json @@ -1,7 +1,6 @@ { "outputs": { "[id]": { - "valid": true, "type": "annotatedData", "dimensions": [ { @@ -24,11 +23,7 @@ ] }, "[id].model": { - "valid": true, "type": "model" - }, - "[id].strings": { - "valid": false } } } diff --git a/specsheets/tasks/FluxBalanceAnalysis/v1.0.0/FluxBalanceAnalysis.png b/specsheets/tasks/FluxBalanceAnalysis/v1.0.0/FluxBalanceAnalysis.png index 58001ae6cdbebd81ce2e0e9df9c167310dbe41b5..9e987773d249d3ebf67f939a2c72d4782de07d55 100644 GIT binary patch literal 15039 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 QG^SosRn|h4C|O|t3rA3plK=n! literal 14925 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 diff --git a/specsheets/tasks/Loop/v1.0.0/description.md b/specsheets/tasks/Loop/v1.0.0/description.md index 3dbb5cf..46aaa26 100644 --- a/specsheets/tasks/Loop/v1.0.0/description.md +++ b/specsheets/tasks/Loop/v1.0.0/description.md @@ -9,7 +9,7 @@ ## What it does -A `Repeat` whose iterations are chained: each depends on the output of the previous one. This is expressed with `loopVariables` - named `LoopVariable` entries whose value equals `initialValue` on the first iteration and thereafter equals `subsequentValues` (an output of one of the loop's `subTasks`). A subTask references a loop variable as `#tasks:[loop_id]:loopVariables:[loopvar_id]`. +A `Repeat` whose iterations are chained: each depends on the output of the previous one, with one iteration per element of its required `range` (a `Range`/`NumericRange`/`ParameterRange`), taken in order; a `Loop` always runs all of them and cannot end early. The chaining is expressed with `loopVariables` - named `LoopVariable` entries whose value equals `initialValue` on the first iteration and thereafter equals `subsequentValues` (an output of one of the loop's `subTasks`). A subTask references a loop variable as `#tasks:[loop_id]:loopVariables:[loopvar_id]`. ## Attributes @@ -21,7 +21,7 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an | `subTasks` | object (values: AbstractTask) | yes | | | `outputVariableMap` | object (values: SIdRef) or SIdRef | no | | | `aggregateOutputVariables` | object (values: AggregationCalculation) | no | | -| `range` | RangeInline | no | | +| `range` | RangeInline | yes | | | `loopVariables` | object (values: LoopVariable) | yes | | ### Attribute details @@ -34,7 +34,7 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an **`aggregateOutputVariables`** (object (values: AggregationCalculation), optional) - _(no description yet - placeholder, needs to be filled in)_ -**`range`** (RangeInline, optional) - _(no description yet - placeholder, needs to be filled in)_ +**`range`** (RangeInline, required) - _(no description yet - placeholder, needs to be filled in)_ **`loopVariables`** (object (values: LoopVariable), required) - _(no description yet - placeholder, needs to be filled in)_ @@ -44,7 +44,7 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an `[id]`: an `AnnotatedData` whose first column is the range values and whose subsequent columns follow `outputVariableMap`. `[id].aggregates`: an `AnnotatedData` following `aggregateOutputVariables`, when defined. - `[id]`: **Valid** - - Dimensions: 2D (or more): first dimension = one row per iteration; remaining dimension(s) = one column per entry of `outputVariableMap`. Unlike `Scatter`, the row count isn't known in advance from a `range` - it's however many iterations the loop actually runs. _(Exact termination condition for a Loop's iteration count - placeholder, needs to be filled in from the spec.)_ + - Dimensions: 2D (or more): first dimension = one row per value in `range`; remaining dimension(s) = one column per entry of `outputVariableMap` (or just the range-values column alone, if `outputVariableMap` is empty). As with `Scatter`, the row count is known in advance from `range`. A column whose subTask output is itself multi-dimensional would add further dimensions - not pinned down further here. - `[id].model`: **Invalid** - `[id].strings`: **Invalid** @@ -53,7 +53,7 @@ Additional possible outputs beyond the three standard ones: - `[id].aggregates`: An `AnnotatedData` following `aggregateOutputVariables`, when that attribute is defined. - Dimensions: 1D: one entry per `aggregateOutputVariables` mapping, each collapsing the iteration dimension of `[id]` down to a single value (per `Repeat`, the applied dimension defaults to the Repeat's own iterations) - unless the underlying subTask output was itself multi-dimensional, in which case that dimensionality carries through per entry. -- `[id].range`: Within the loop, the current value of `range`, when `range` is defined (see `Repeat`). +- `[id].range`: Within the loop, the current value of `range`. Always valid, since `range` is required. - Dimensions: Scalar (0-D) per iteration. -- `[id].index`: Within the loop, the current index into `range`, when `range` is defined. +- `[id].index`: Within the loop, the current index into `range`. Always valid. - Dimensions: Scalar (0-D) per iteration. diff --git a/specsheets/tasks/Loop/v1.0.0/outputs.json b/specsheets/tasks/Loop/v1.0.0/outputs.json index d7f34a4..95aee2f 100644 --- a/specsheets/tasks/Loop/v1.0.0/outputs.json +++ b/specsheets/tasks/Loop/v1.0.0/outputs.json @@ -1,18 +1,25 @@ { "outputs": { "[id]": { - "valid": true, "type": "annotatedData", - "dimensions": { - "source": "runtime", - "note": "2D or more: first dimension = one row per iteration (iteration count is not knowable ahead of the loop actually running - Loop's exact termination condition is an open design question, see core-spec.md Section 10); remaining dimension(s) = one column per entry of outputVariableMap" - } - }, - "[id].model": { - "valid": false - }, - "[id].strings": { - "valid": false + "dimensions": [ + { + "size": { + "source": "static", + "expr": "len(range)" + }, + "labels": null, + "note": "one row per value in range; len(range) dispatches on range's actual Range/NumericRange/ParameterRange type" + }, + { + "size": { + "source": "static", + "expr": "len(outputVariableMap)" + }, + "labels": null, + "note": "one column per entry of outputVariableMap, or just the range-values column alone if outputVariableMap is empty; a column whose subTask output is itself multi-dimensional would add further dimensions beyond this, not captured here" + } + ] }, "[id].aggregates": { "valid": "provided(aggregateOutputVariables)", @@ -29,13 +36,11 @@ ] }, "[id].range": { - "valid": "provided(range)", "type": "annotatedData", "dimensions": [], "note": "the current value of range, within the loop" }, "[id].index": { - "valid": "provided(range)", "type": "annotatedData", "dimensions": [], "note": "the current index into range, within the loop" diff --git a/specsheets/tasks/Loop/v1.0.0/schema.json b/specsheets/tasks/Loop/v1.0.0/schema.json index 2d4e9a8..cac92e1 100644 --- a/specsheets/tasks/Loop/v1.0.0/schema.json +++ b/specsheets/tasks/Loop/v1.0.0/schema.json @@ -25,16 +25,22 @@ "$ref": "../../../auxiliary/LoopVariable/v1.0.0/schema.json#/$defs/LoopVariable" }, "x-rule-id": "Loop-0003" + }, + "range": { + "$ref": "../../../tasks/Range/v1.0.0/inline.schema.json#/$defs/RangeInline", + "x-rule-id": "Loop-0007" } }, "required": [ "_type", "subTasks", - "loopVariables" + "loopVariables", + "range" ], "x-required-rule-ids": { "subTasks": "Loop-0001", - "loopVariables": "Loop-0002" + "loopVariables": "Loop-0002", + "range": "Loop-0006" }, "unevaluatedProperties": false } diff --git a/specsheets/tasks/ModelChange/v1.0.0/outputs.json b/specsheets/tasks/ModelChange/v1.0.0/outputs.json index 5b3b00f..6440bd5 100644 --- a/specsheets/tasks/ModelChange/v1.0.0/outputs.json +++ b/specsheets/tasks/ModelChange/v1.0.0/outputs.json @@ -1,14 +1,7 @@ { "outputs": { - "[id]": { - "valid": false - }, "[id].model": { - "valid": true, "type": "model" - }, - "[id].strings": { - "valid": false } } } diff --git a/specsheets/tasks/ModelElementList/v1.0.0/outputs.json b/specsheets/tasks/ModelElementList/v1.0.0/outputs.json index 1c33e4f..6a4fe36 100644 --- a/specsheets/tasks/ModelElementList/v1.0.0/outputs.json +++ b/specsheets/tasks/ModelElementList/v1.0.0/outputs.json @@ -1,13 +1,6 @@ { "outputs": { - "[id]": { - "valid": false - }, - "[id].model": { - "valid": false - }, "[id].strings": { - "valid": true, "type": "stringList", "dimensions": [ { diff --git a/specsheets/tasks/ModelImport/v1.0.0/outputs.json b/specsheets/tasks/ModelImport/v1.0.0/outputs.json index 5b3b00f..6440bd5 100644 --- a/specsheets/tasks/ModelImport/v1.0.0/outputs.json +++ b/specsheets/tasks/ModelImport/v1.0.0/outputs.json @@ -1,14 +1,7 @@ { "outputs": { - "[id]": { - "valid": false - }, "[id].model": { - "valid": true, "type": "model" - }, - "[id].strings": { - "valid": false } } } diff --git a/specsheets/tasks/NumericRange/v1.0.0/outputs.json b/specsheets/tasks/NumericRange/v1.0.0/outputs.json index e313e17..4eecff0 100644 --- a/specsheets/tasks/NumericRange/v1.0.0/outputs.json +++ b/specsheets/tasks/NumericRange/v1.0.0/outputs.json @@ -1,7 +1,6 @@ { "outputs": { "[id]": { - "valid": true, "type": "annotatedData", "dimensions": [ { @@ -12,12 +11,6 @@ "labels": null } ] - }, - "[id].model": { - "valid": false - }, - "[id].strings": { - "valid": false } } } diff --git a/specsheets/tasks/OneStepODESimulation/v1.0.0/outputs.json b/specsheets/tasks/OneStepODESimulation/v1.0.0/outputs.json index 300a0b9..70693f4 100644 --- a/specsheets/tasks/OneStepODESimulation/v1.0.0/outputs.json +++ b/specsheets/tasks/OneStepODESimulation/v1.0.0/outputs.json @@ -1,7 +1,6 @@ { "outputs": { "[id]": { - "valid": true, "type": "annotatedData", "dimensions": [ { @@ -18,11 +17,7 @@ ] }, "[id].model": { - "valid": true, "type": "model" - }, - "[id].strings": { - "valid": false } } } diff --git a/specsheets/tasks/OneStepStochasticSimulation/v1.0.0/OneStepStochasticSimulation.png b/specsheets/tasks/OneStepStochasticSimulation/v1.0.0/OneStepStochasticSimulation.png index fd9d7ab8595f472aabbb168e3ec781465ee4d117..4e3eccb04482c0cb45e91afe762c90f6b0e4e794 100644 GIT binary patch literal 14911 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 literal 8766 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 R;CCTZdfLXYGR;TN{uk+0Zan}1 diff --git a/specsheets/tasks/ParameterScan/v1.0.0/description.md b/specsheets/tasks/ParameterScan/v1.0.0/description.md index 8e02f0c..e74b984 100644 --- a/specsheets/tasks/ParameterScan/v1.0.0/description.md +++ b/specsheets/tasks/ParameterScan/v1.0.0/description.md @@ -9,7 +9,7 @@ ## What it does -Runs simulations/analyses over several systematically-varied versions of a model: a `Repeat` subclass that adds a `model` child (the model to scan) and one or more `ParameterRange` children (`parameterRanges`) - each scanned element adds a dimension to the output. Each `ParameterRange` must target a distinct `modelElement`, which must be an id within the child `model`. One of the `subTasks` must reference the scan's `model` child (`#tasks:[scanid]:model`) as its own input; the model is initialized with every combination of values across all the ranges. Mechanically it's otherwise identical to `Scatter`, and could in principle be reproduced with nested `Scatter`s plus careful `ModelChange` tasks. +Runs simulations/analyses over several systematically-varied versions of a model: a `Repeat` subclass that adds a `model` child (the model to scan) and one or more `ParameterRange` children (`parameterRanges`) - each scanned element adds a dimension to the output. Each `ParameterRange` must target a distinct `modelElement` (ParameterScan-0007), which must be an id within the child `model`; the `modelElement` also serves as the entry's name in `[id].ranges` and `[id].indexes`. One of the `subTasks` must reference the scan's `model` child (`#tasks:[scanid]:model`) as its own input; the model is initialized with every combination of values across all the ranges. Mechanically it's otherwise identical to `Scatter`, and could in principle be reproduced with nested `Scatter`s plus careful `ModelChange` tasks. Within the loop, the current value and index of each range are available as `[id].ranges` and `[id].indexes` (see Outputs below). ## Attributes @@ -36,7 +36,7 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an **`model`** (SIdRef, required) - _(no description yet - placeholder, needs to be filled in)_ -**`parameterRanges`** (array of ParameterRangeInline, required) - _(no description yet - placeholder, needs to be filled in)_ +**`parameterRanges`** (array of ParameterRangeInline, required) - The ranges to scan; at least one. The `modelElement` of each entry must be distinct within the scan (ParameterScan-0007), and labels that entry in `[id].ranges` and `[id].indexes`. ## Outputs @@ -44,7 +44,7 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an `[id]`: an `AnnotatedData` with one dimension per entry of `parameterRanges`, plus one further dimension sized by the number of entries in `outputVariableMap`. `[id].aggregates`: an `AnnotatedData` following `aggregateOutputVariables`, when defined. - `[id]`: **Valid** - - Dimensions: N-D: one dimension per entry in `parameterRanges` (each sized by that range's own number of steps), plus one further dimension sized by the number of entries in `outputVariableMap` - dimensionality grows with the number of ranges scanned. + - Dimensions: N-D: one dimension per entry in `parameterRanges` (each sized by that range's own number of steps, and each labeled with that range's `modelElement`), plus one further dimension sized by the number of entries in `outputVariableMap` - dimensionality grows with the number of ranges scanned. - `[id].model`: **Invalid** - `[id].strings`: **Invalid** @@ -52,3 +52,8 @@ Additional possible outputs beyond the three standard ones: - `[id].aggregates`: An `AnnotatedData` following `aggregateOutputVariables`, when that attribute is defined. - Dimensions: 1D: one entry per `aggregateOutputVariables` mapping. Each entry's aggregation collapses *all* of `[id]`'s scanned-range dimensions together (per `Repeat`, the applied dimension defaults to 'the Repeat' itself - here, the whole combined scan) down to a single value - unless the underlying subTask output was itself multi-dimensional, in which case that dimensionality carries through per entry. + +- `[id].ranges`: Within the loop only, the current value of each of the scan's `parameterRanges`. + - Dimensions: 1D `AnnotatedData`: one entry per `ParameterRange` child, in order, labeled with that child's `modelElement`. For example, with children whose `modelElement`s are `calc`, `phos`, and `ant`, it holds the current values of `calc`, `phos`, and `ant`, in that order, labeled accordingly. +- `[id].indexes`: Within the loop only, the current index into each of the scan's `parameterRanges`. + - Dimensions: 1D `AnnotatedData`: one entry per `ParameterRange` child, in order, labeled with that child's `modelElement` - the current index of `calc`, `phos`, and `ant`, in that order, in the example above. diff --git a/specsheets/tasks/ParameterScan/v1.0.0/outputs.json b/specsheets/tasks/ParameterScan/v1.0.0/outputs.json index e0c28c1..1aa0b90 100644 --- a/specsheets/tasks/ParameterScan/v1.0.0/outputs.json +++ b/specsheets/tasks/ParameterScan/v1.0.0/outputs.json @@ -1,7 +1,6 @@ { "outputs": { "[id]": { - "valid": true, "type": "annotatedData", "dimensions": [ { @@ -11,8 +10,11 @@ "source": "static", "expr": "len(self)" }, - "labels": null, - "note": "one dimension per entry of parameterRanges, each sized by that entry's own length; len(self) dispatches on the entry's actual Range/NumericRange/ParameterRange type - see core-spec.md Section 8" + "labels": { + "source": "static", + "expr": "modelElement" + }, + "note": "one dimension per entry of parameterRanges, each sized by that entry's own length; len(self) dispatches on the entry's actual Range/NumericRange/ParameterRange type - see core-spec.md Section 8; each dimension is labeled with (identified by) that entry's modelElement, in parameterRanges order" } }, { @@ -24,12 +26,6 @@ } ] }, - "[id].model": { - "valid": false - }, - "[id].strings": { - "valid": false - }, "[id].aggregates": { "valid": "provided(aggregateOutputVariables)", "type": "annotatedData", @@ -42,6 +38,40 @@ "labels": null } ] + }, + "[id].ranges": { + "type": "annotatedData", + "dimensions": [ + { + "size": { + "source": "static", + "expr": "len(parameterRanges)" + }, + "labels": { + "source": "static", + "expr": "parameterRanges.modelElement" + }, + "note": "one entry per ParameterRange child, in order, labeled with that child's modelElement (parameterRanges.modelElement is the modelElement of each entry, in order)" + } + ], + "note": "the current value of each entry of parameterRanges, within the loop only" + }, + "[id].indexes": { + "type": "annotatedData", + "dimensions": [ + { + "size": { + "source": "static", + "expr": "len(parameterRanges)" + }, + "labels": { + "source": "static", + "expr": "parameterRanges.modelElement" + }, + "note": "one entry per ParameterRange child, in order, labeled with that child's modelElement (parameterRanges.modelElement is the modelElement of each entry, in order)" + } + ], + "note": "the current index into each entry of parameterRanges, within the loop only" } } } diff --git a/specsheets/tasks/Range/v1.0.0/outputs.json b/specsheets/tasks/Range/v1.0.0/outputs.json index 3246fa3..dad7d33 100644 --- a/specsheets/tasks/Range/v1.0.0/outputs.json +++ b/specsheets/tasks/Range/v1.0.0/outputs.json @@ -1,7 +1,6 @@ { "outputs": { "[id]": { - "valid": true, "type": "annotatedData", "dimensions": [ { @@ -12,12 +11,6 @@ "labels": null } ] - }, - "[id].model": { - "valid": false - }, - "[id].strings": { - "valid": false } } } diff --git a/specsheets/tasks/RelabelData/v1.0.0/outputs.json b/specsheets/tasks/RelabelData/v1.0.0/outputs.json index 7b8f657..150a7fb 100644 --- a/specsheets/tasks/RelabelData/v1.0.0/outputs.json +++ b/specsheets/tasks/RelabelData/v1.0.0/outputs.json @@ -1,16 +1,12 @@ { "outputs": { "[id]": { - "valid": true, "type": "annotatedData", "dimensions": { "source": "static", "expr": "shapeOf(input)", "note": "same dimensions as the referenced input AnnotatedData - this task only replaces the topmost dimension's labels (from labels), not the shape" } - }, - "[id].model": { - "valid": false } } } diff --git a/specsheets/tasks/Repeat/v1.0.0/Repeat.png b/specsheets/tasks/Repeat/v1.0.0/Repeat.png index 1eead833dc831d58e08b628d88ac2951b4e40b7f..7021cf137b8ac58dfd5b42a421aa4632cf6d0cc1 100644 GIT binary patch literal 17741 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 diff --git a/specsheets/tasks/Repeat/v1.0.0/description.md b/specsheets/tasks/Repeat/v1.0.0/description.md index d8d9e88..3fc493f 100644 --- a/specsheets/tasks/Repeat/v1.0.0/description.md +++ b/specsheets/tasks/Repeat/v1.0.0/description.md @@ -10,11 +10,11 @@ Like SED-ML Level 1's RepeatedTask, SED2 needs to repeat a group of tasks multiple times. `Repeat` is the set of fields shared by all three concrete subclasses (`Scatter`, `Loop`, `ParameterScan`), composed via `allOf` rather than instantiated on its own - the prose spec calls this abstract concept simply "Repeat". -The repeat's `subTasks` are true children (not references) of the parent, and may depend on each other, on outputs of tasks outside the repeat, or on the repeat's own `range`/`index` (the current iteration's range value and position, available as `[id].range`/`[id].index` - see Outputs below). `outputVariableMap` defines the columns of the repeat's own `[id]` output: the first column is always the range values, and each further named entry maps an output column name to a value produced by a subTask; if empty, `[id]` contains only the range values. `aggregateOutputVariables` defines the columns of `[id].aggregates` - used to efficiently collect running summary statistics (e.g. mean/stdev) across a very large number of repeats without keeping every individual run's output; entries here may not define their own `appliedDimensions` (the applied dimension is always 'the Repeat' itself), and each `input` must reference a subTask's output. +The repeat's `subTasks` are true children (not references) of the parent, and may depend on each other, on outputs of tasks outside the repeat, or on the repeat's own per-iteration outputs (the current iteration's range value and position: `[id].range`/`[id].index` for `Scatter` and `Loop`, `[id].ranges`/`[id].indexes` for `ParameterScan` - see those classes). `outputVariableMap` (optional) defines the columns of the repeat's own `[id]` output: each named entry maps an output column name to a value produced by a subTask. `Scatter` and `Loop` additionally make the first column the range values, so for them `[id]` contains only the range values if `outputVariableMap` is omitted; see each subclass for its exact `[id]` shape. `aggregateOutputVariables` defines the columns of `[id].aggregates` - used to efficiently collect running summary statistics (e.g. mean/stdev) across a very large number of repeats without keeping every individual run's output; entries here may not define their own `appliedDimensions` (the applied dimension is always 'the Repeat' itself), and each `input` must reference a subTask's output. A `Repeat`-derived task must define at least one of `outputVariableMap` or `aggregateOutputVariables`. -`range` (a `Range`/`NumericRange`/`ParameterRange`) is shared here rather than being redefined separately on each subclass - `Loop` and `Scatter` both use it directly; `ParameterScan` does not (it uses `parameterRanges` instead). +`Repeat` itself has no `range`: `Loop` and `Scatter` each define their own required `range` child (a `Range`/`NumericRange`/`ParameterRange`), and `ParameterScan` uses `parameterRanges` instead. ## Attributes @@ -23,9 +23,8 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an | Attribute | Type | Required | Notes | |---|---|---|---| | `subTasks` | object (values: AbstractTask) | no | | -| `outputVariableMap` | object (values: SIdRef) or SIdRef | no | | +| `outputVariableMap` | object (values: SIdRef) or SIdRef | no | Optional, but at least one of this or `aggregateOutputVariables` must be provided (Repeat-0006). | | `aggregateOutputVariables` | object (values: AggregationCalculation) | no | | -| `range` | RangeInline | no | Used by `Loop`/`Scatter`; not used by `ParameterScan` (see `parameterRanges` there instead). | ### Attribute details @@ -35,14 +34,9 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an **`aggregateOutputVariables`** (object (values: AggregationCalculation), optional) - _(no description yet - placeholder, needs to be filled in)_ -**`range`** (RangeInline, optional) - _(no description yet - placeholder, needs to be filled in)_ - ## Outputs -Not applicable on its own - see `Scatter`, `Loop`, and `ParameterScan` for their concrete output shapes (`[id]` per `outputVariableMap`, `[id].aggregates` per `aggregateOutputVariables`). - -- `[id].range`: Within the loop, the current value of `range`. _(No description yet - placeholder, needs to be filled in: exact reference form and availability when `range` is unset.)_ -- `[id].index`: Within the loop, the current index into `range`. _(No description yet - placeholder, needs to be filled in.)_ +Not applicable on its own - see `Scatter`, `Loop`, and `ParameterScan` for their concrete output shapes (`[id]` per `outputVariableMap`, `[id].aggregates` per `aggregateOutputVariables`). The per-iteration range outputs (`[id].range`/`[id].index` on `Scatter` and `Loop`, `[id].ranges`/`[id].indexes` on `ParameterScan`) belong to those subclasses, not to `Repeat`. Shared mixin for the three `Repeat` subclasses - not instantiated on its own; see `Scatter`, `Loop`, `ParameterScan`. diff --git a/specsheets/tasks/Repeat/v1.0.0/schema.json b/specsheets/tasks/Repeat/v1.0.0/schema.json index 64c4a57..91c6a06 100644 --- a/specsheets/tasks/Repeat/v1.0.0/schema.json +++ b/specsheets/tasks/Repeat/v1.0.0/schema.json @@ -51,10 +51,6 @@ "$ref": "../../../tasks/AggregationCalculation/v1.0.0/schema.json#/$defs/AggregationCalculation" }, "x-rule-id": "Repeat-0004" - }, - "range": { - "$ref": "../../../tasks/Range/v1.0.0/inline.schema.json#/$defs/RangeInline", - "x-rule-id": "Repeat-0005" } }, "anyOf": [ diff --git a/specsheets/tasks/Repeat/v1.0.0/validation/Repeat-0005.md b/specsheets/tasks/Repeat/v1.0.0/validation/Repeat-0005.md deleted file mode 100644 index b78d18f..0000000 --- a/specsheets/tasks/Repeat/v1.0.0/validation/Repeat-0005.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -id: Repeat-0005 -rule: The range attribute of a Repeat, if present, must be a RangeInline object. -message: "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not a RangeInline object." -severity: error -status: active -check: schema ---- - -`range` is optional; when present, it must be a `Range`/`NumericRange`/`ParameterRange` object in its embedded `RangeInline` form. diff --git a/specsheets/tasks/Scatter/v1.0.0/Scatter.png b/specsheets/tasks/Scatter/v1.0.0/Scatter.png index da5c874598fa371de3fc8c7e99d470b94368f69c..cbb43fed1af8e0064007bd4ddc7344a1c496f634 100644 GIT binary patch literal 11258 zcmaiaWk6KX_buHm-3-#*4FW^Aq)MlN)Bw^Q(lT^+7?g<8jW9HlqBKJzjYH47{QmF5 z>-Xi%+&g#9xhMA8Ywx|{^>x(<@o4c-P*4ap)WOeDP*A0S@85B-fVRx@MjZu(r&j~4 zXykACw-CQW*Z5{=b=Yf(7Q)c1-vK7Zhur z$H`8{PL_`2T$bZL=$qsU>8?dS$nVH{{Q1X7G!Y~>i8y~zd|uSK(7xKaV0qA7^lkp@ zJYEbzzaRmt2|3qu`$WXh3s@-Z)whUI!$!^TNREo?>Uu(&Skj;g$xQ;M0{U~48o$in z?^C-MubDzm6RqfRt2%9{g?hk8vp9H*@edMEkt9hQkl#K=%%MLrA4a2EAPAL_OW}C) zfSl1Z76X3vw+8v$*t0#}_$(&+UpKNvz+~bF=^{xOJz)MF9K3vF*b}M#xF_roDJ>Hv zrw~XiDTg*3Ql$Rhzi+TWlw%3JGP#ZM-r@7N^vIpTSdUKD`+Gka*iBbx^eRhf>hIRH zx=?$87(oji0p6x{=28+avz)kYf4*ma)SIc&!BB4j2Q9GN23} z$rdw#4E*FM9T-SvmA0T%>)tG!S z@yI&YFEgQ1Rj%`9GTn0ugfV6GE0Si zD_pi>en;j~@2FYKYF{;U3wZ;Uc%Jxr{Dlh->=uZ9tcO1)Er{p)^ z-Cw9buF@^s54_xGJ8gcmxPe8?$Xm=5xXaS)IG(rmR|WHNjC>18nLS+d=3+^bq^{6%sbLS0x!LP)t_yEX&Anm@ zUVU@P#L>?eck3%t`PJt8+3fXln{T>5k7*sjD@e9gXlq=K!b79OsQEXSIrGlI%YnAd zn*sE^_DZd6qE)>b!N>Ck^xJ;ac2MzNJ6F&q5{FV}EDD=gGt459lCOd$LGWk2xa&M` zykV&lCgQ05IH7W==f^~$j0NIo*B3;rQ%q1hu*`(2C!NBYB7E)HITGjT=(Fu-@?Kcq>;7_~{YN6z=xGExc3Ym9tEOSjgDitTwUBLe9PdIB8~fwg1~$IB zPe)?;X?gW3tx1~CW4e;!Ixgg;09?`H9(7d#=j5gl*-=07W7 z1EQkSh7+*r=D>bn{huE(s8EOUtuW<^JFo<@$jODc!2}65!LxN1x8rx$=S*kv@)WX8 z)UnV*a_NJbum2`7g1+RCM-zQ_iI^g+fucOu- zcjQ_WaSB=M-b^*qShm1wg0*?SU{Xby*XAGtf7@{n9>10nPF?KLDQ6u<|PH zhEfRk^96xZjedQ;Q%rUDIQnzXgWBeYF54doYQK;yWb^_iHNS`iTx!?+2>S)eillw_ zgU_e61Teq-<-{VQZ>fJ4fp(15?F!6us>yZX=q!y*i_u0Tf3x>mDF*NFSr^3e1bBIB zT&;4|6=@2x?5JZ&-F`Vqeo!-b+}}s2bfQ+( zwELf1aA9%i%`hRO>@UEICgko;`rUzJ+{?MR4IrR90B!3?3HPO48CU8dTaXjDkf*+5 zy3lw2#nB+0htEz?P@R^Zo*zCHKY^+YOAzA7H`^Q%9|RoJEhO#}_Li@c@-if&f+>UG zi8yWA8)bi{{!(}Kd&7%F~{+xSH zI4b0h33>I7K4_=V5B@Ujs-I~Iz>1ALaku@@>rtz=)6JpLYXEo~5K#xK-QB@V54Wqx zHiL52R=`Tyor**Laq>*T7=VQ|sMal%o(MwLxi7aJeXK5mtcKpYT`fJDiOC9I^Ad>C z5-`K1e}Dg245zUzQ<$2s(@MDW_Qg)go%EoewZ8o30&=9_Hu3~eGSij0$}FDB(!aEQ zJI~epXPJu1F0j3J*SdStm0Ne)^Kk|dPp$!?quUz4}kFVP3GRIB&5x~Atw_gptd@q~S zYk09(9uVEgcw@wn!h^xhhI{9wiSze|%la@1o4z#Vr`JiazrVgH%Xibzg8dH7kqVR@oYS zF)GlV;Y~mWA5K?Gq2e}DAJ|_-J~YRf{z#x$_6R+v+tWK(>1=O#@0rv>pxJS~oqv|w z)d9fr$TM&R8m9T_#t#d?n*vyW0N@tTxA@e$g3|=O7lUHz9kc5B&LowV&bo-#ml0}G zhYa%2yHhm@!10}SMs1B|w};&ySgjwQ(%=(m5$~?{gW&a086l_$0c+*|t&PuxQSh3j zCad?kV^H#%HIO9gH@*JJT54vURbWGX%Iug`0KhKwY0snCWdLXY|J$-VgHtFR7w5Q4 zW@}!|+}|IEW$PF~(B=*4WZu>UJ92scTw_o)tm zvfh4!^5E+;_wBLVqm4uXq9SRwl`v$;LX{5P^%!L!V%g7%S#@5!K++%!Yv+2=a#Aqq zFr6GUM7DT{*~6Is#uBnuncZgD88|E@E@AUo3QytIrLo%S&v&=w`p`=rzw>d4Q4`;A z3gb#m3ezfW8pLk-`&a~G;Q3~r;xC2pIs3&^++S{Zy_?OxllpHxy4PdrmOR34UoAA) zC+5-6Bw4lKC7%I4bD`d+ao9n3FVKfWkCT`FU1Q5&)$<7<&@-OA2YQK(w-WNh7Q|*x&lwZa$g6cNz~HNWMoWp&uBz zkCJ!yKh!~WY{h>wxkrF;{P#Ckl^hg|2kjz!Z8_inH+O2J^o*C@7kM{2s1%MkkE_{{EKUqdFQV43Y@B z@j*HObH_~6gum|NA|PmTUw&Eh4RCG4LSTNYuHZ%$hN zSUT$GB*OQ_0oyc-%Y{{3w~>urjYUHv!CRT86}V${hHrY+3~&5F?_%OO8yE3VT~lt= z;BV^n`z1rtRN?#`CrV!`NbsLEbhwVp`{EG1_P(5uInGFqaV~q<(+f-csXah)kX$&w z*r%%|9j{fqdTOo4`F*e)`M$~t*xDtD)!t!}lIY~WCo>D>rFv)wl-mFOcJ03p5H)W1*#j*M z2$y#gxz+%HU8j-GekOyCO+>QW%$h;Lynhlsc1Y9nz&+>Uy1 z52_CuO4Nc()iA;phFqkHlNg$q9kqD&#Wr@M6&R^I`d@qk3EsGzj3MWmuo-g6da7 zZvQr)De!QgE8v$llHUjH6mkshg>6dikoJg7${LCjpoydR*;$xE9BjxE&iS~fYSdI|cG2pz@Yq`FV_+pE{^|bR7i|LYk>tgpx>*!r_ zOwv+Rd;zK0FO~72%f?AerNMtmZJV_7a{#m0*q$ilp?gim^&DIy_EvaP=J3N{Xmc?8 zQ3jXc(mi5T02EKss7SiA+rKGU{EmPIv{0q@J_1|SDGYhLI=aGmK`0Nfva^u41|t8p z;?J7Qrn?@IAF?&l_~yPV2S1of16g^)Fpd9y)miRe@MKH0f817vj)+i0PcL&Nv%!pqE!rSp|EYcp6z> zJPB(7&P8jLPCk|%hiDSL2+yX^72tOUhy`B?{vaw=QZ39}ZufgPy5L&hxosJGy>-%R z#LS|S5)iv!8C3hK!8$@RNO_A4hyUr?`Uia==I8P;avu}ZVLw^j zEG#5q3O)vPv3Di!m}}jd!@P# zk0+)`DQ=-+4)0k~EqHcsO|j+~I4OsKnXBUw%fHY@vIyQ|1M_7^>$y{_OYZsf!PZzP z^8+w}G}MN&d4S=~t1i@8IJl4vH91zW5AMwp@0{SH)0?+;B^W*WYJhk;+>n{jedDD( z1hNX1J!`LG!>G>X=RVotJ)wCEaLA);Al5k!-Ow(QmAcD+h8f|T_?|ZAozsA3&nm&F z0mrD_U!jCyFZSl+rPlKg2UjZYK))MPLBnj>ag~*$EH(iKlBX6xLgUZUU^3m7IO6L@Wws^c`fSS^h}1}+tPJW*D+d7V^JJnXG02##>;OOS1JFUyqB(f~Twf~e za?Vt%@)_-|DO;~%t|+_C>F0J}p)3H{age5oxES~Zgj=7QC|l-B6r%$^4MjJ_g5cGwoP1N|tM zhDniKJBRr=N75yC*=I&acv)vOT`BN9R72!UG5~sEZGtzk7@nCRz)C@U3S=5WXT`#$ z`t#m)gw<6}s>yG6dL9orFSUHRl1~eZIO_>2DLB3B@O#NaUoHDHtwi>UZ|X436QnkH zR@N@%y$wSW(uw<+TKH!EY4@wwUaD$HKP92sV9|f($S!it0*&w2Dn}VFkTNV#8y1WM z?Qm+_Gsi)63>k$DuKdfa%{6VJ7-7v3|B)t9+lUr|9VZ^t6?+d-Gk8S_drY zj&gO=fz{uf&R|^@gHOs*Fx1w}PTCFkXW5h|F%IvzMP4b+%hVD!HPtQoYr<(v&YlV` z{ZwC*$PFr~yeaKG>@H>1E!pE38lq?E?;=s+!cELN-UGqW@J`LiE6AAcvl9Q%ntw08 zIu3t&N=`cvxo2baOz|M&wuJe-z$l5F1f0`Xt$%8OduCA;cq(J`rY1v4+AxmPb2?8m zSxNT>*z}-jIi6O*h+?IFvM-Bdy>$eN`q@ z__WMLM(z|mCgfi13P2dDJ8}J@={3~I3`Yhr^sUu{QhDmSFElcX{yO5qAxk};j1BG& zgwg#<-|UCUgvcT{Mr45V`qikYIP9U-Jl$!NhE!mMAt2Uo>~>9JB!i1}=8&`4DAGK= z@;eD&U*f}kcyOAOdLXy5g1sP1L#7M=Amt;5YvGI*qo&<48eL0lDT(|#jftxdL^FsT z1?2Sy*N-r$*$9x^sAMml@=VDt1y#?}38dyld(($K#-=U0h9G6YIA8G+){qZCH_0<< zN+{XRSq7G51c*yZ*=34ge3l(%^4@MP3MYvL$lS$$LhAZ(|In$*cy+pY_f07ra`jHC z9|DlOxfl37oy<5!Sa_$TL_ls*=IvqXCV88>(&3N*#Ec9t<{jP#AZ29huzUZ!6`B?L zyV>KIUAMr0_RD5`L0AzFXoy_+S(- zU=?Not_MN}kS7P3)C8+hpdJo7Wd#$ja8)N4oMT#`9aLS*%4z&5!${bOw<7m}e~463 zA+CUy;~74x0f!!oV}UaKZV+dlJyIvo_63ho5nLw;h1c`mq6)<&7sijv0hy(gWxg`a z>!Dq9{PwRz15Ai#PrDIvcRI9w5S~yVPAK$8XyFT3J$T~hg+6qK9Wy54cfr8URlY|T z*U)h4-FujgqCU!Ne&>?G$ppakmGL+?)VHe^bxPN1-g7{HbEw&XD|!SVq5&C)aRo2s z%(D+>iZ$GHux3k?K3u7!M83n}ilg3xAAe<)pXc722;k)}NyTg@kF=lTQ1d2&vXyy&A*^#JMHR}}1-*ZA)b;P>uY*-;poGr1)qR1$XIQjq`mepyUbPMP?V%Q+S zMhg1Y=lxZf>FVc5n9UX{ACPMPq;6RSF(p-oH>se-QJe5h9($nLJY$B)@;Jkh7PX>Z zwff@e#fsP?>qHgVtKLUUc3=owy?ptyr8TDKF;32Ndx}Px@DKNdVVu)%HKe)5Llvw1 z`wo5aS2C$CH5N9zsW3G@C0Q_$YigwSO!fn)Mgfl_%b}td&64_?SPcGaUFNhkDycdx zc2>KsXqXpY-S8zSp8o3gTpd44_-vC(YQot&bGzI`-Awtnxr1<5cdMo$MgzZ33U}mM za{~ph+_VG_wEUUvx`A~7dzZsbNFh)fgiPh#?EYVIkFA#>^HlYco1gHlL{;y|0eraDm*^)oQ_WhG}eA_`tg4WTYSpW@Z&xvrhq86_bPotybKKfQ$Cn@ z6wBmzds=NLuL{aHSatSJOam`=S<0fQnWLdM45ajD`E3s;*)2He6inBsh$mpvTER26 zaWFRtSQ(oUW(Su#!iC}|5KcjulXu_G1gkpGI>RXqwk@U;%En%|qVe*MFnWC$Yh}NO zE4ngK`%gu1wy}S}QFm?g=9Dq2F!O(?5=H0*Y!n&qXr2c8F@cA%&wWN(!aD>vC{0J=AF5J+>U5c%|@W|%0Io@{ty+X_SEf)kWbK5&`^U& zm)6zonn(=#hqk9zrRikNxCNf1vh2IJR?PA;!BkYqhkaA+e(j5l%W@VZj0_?6)K)6e zX_Iv2It1VCsg^98!q;Ern+8A?Z&6GlC0*+h}I2(|iTkMhpz67`}VWpo&>;2S&P zoFlxAz&7%n|AES&?maC(r!EOCXEyAaL*lNoUn0wT3})7+;uI*-TYb~yx}5#ZZViwU zE<#m_>&Jum4pkWCq5H(Dgh@#9I?k)`7-1D6SE6o^i$ZXkr&n)C^djZev{(IX=oJ|Y zGfstc5Vtn2T_6dwr2hdrO|JG2QL!UjY(rI#Q+#_$H0PdgG|qhjxGZ3jIRmOdMf zLJ#(`OkJMZn0;vWmI6fWS1AmWmsmrNRogBh=x+`Nt%HdKyan3G153h5 z)g{3wUS%)TVnIb+p29DtetKPuzqy9g(4%&pv%u(%8^ek>}E^ zF&7D8QDUSX?fMXoeW1k;Rx(Ac6xXz2u977g3Nph}GiDSP$LA8KQS$y{-X^Gu1Ds9T z*=IY1;5!^`r#GuT2;1a8jB)2>`ZRZ&Q2^xLzM;}t+BP|}*Gq6dPIgsLp%eP>M zusgD();ElJ&CVU+O=pR+>U`|bP@6978-Ih#3otxHd=7-EHv#?U+#+KIDTOFP$3e9S zm#hg+!rewhBFFu{h!&3y#_tdBISyZaz^5IWJvw z^5#o_-vvK#3V~9xa(XsZuUBD4Qj{PvJzftZgarprjG{YUEIj;dBZULvV!ZeCs06l0 zfHFOxFl>&SP%t6hQ(lNR{DwFs{R{4FR&NZqF}xx8&Rao4?Vs`w+u8AARH%~)-bRUc zVuTW<`Noi*KK$-JoLrpOvc`;8wbKei`WJER7D>%(p!*KBnAIIA)QDd0pQ{_WBrm|a zDyS!=Px%^IA<~~QFLFO{UdW+Qa2@BK$HhO$KiTjdSLAl$b`&2c>hsvGp)Ijhfi?0# zT;f5g)MRkQD*aC=XW5iSBqQnFiP)?$3AtBGJjYbf^H*uV*_3HrB%YLwBf~f4j&)|j zjh%HXN7>fFDO~hzFEMC@GMu?EId;$cd>9#XWBhwRvIFb&bDJ&;Yv^0Q@#bk?gZT%! zyY!QQ7fa}v#s2ouPcB=hG6v5|JUgAeP0TU#ic_5*@@xA$_#nQC6XUA z5;sE6lY3po4S4|I)xYQK>nGGa*&TS){1y2~zo=!dMHXO*UYbxzR0M2=7;g)Ke1faO zVx`>8g7Ulq;%CLlWyzFw>KxVJ>PC5~aTuooECZ~{&|#?|Z2}BsSMmFh8!xkP8=2@570dkUix$%=wXt_ys19PYp3lIZ1EB~d|fWOw%cZE#ipqc1+_Ns*y(`UY? zWWI^o?FNs%j%ArJk75_dk{HrZ!;^GYz1c&{?igL`AqsI8HG~}kG6EBN*o+PmrAbcc@80ohIBWug7yTIcX_+|#ZJJL`X^qoJl!+Rsu z@pn_X^Mn^TA2HA=8Wh z`=ri#7Yf}Bq%C$T`=K%;50KAd<7(YA`KDIQ)#iV#cJ%rISU<#Mo@T(H>N(%raG1l4 zQ8=GnG^h47A@=m0jPaNwe170{!!WTKuWIyneSR1T%VW}LCCC$Q7%;=$@M872uv{#% zU?pXp{%L7Np`=}{q@id-vk;wF3*j2g&%+3VV95UdLaptQ1dQo->;ltxmUq z(OWTp)ms|G+NCcuvq}}e#z>}m6iZ1Kl4`aq`i+(FLje&k8w4n!OC>)R)VTh~R%Z-6 zu^A))+x>`%PsuwVSRyCHF^&%qVt4CGDosY;d4TN=)6h%5bnYg~odU|~pe8~FS6#9$ zy#HLm&G%zMO6@Rp`x8=e3vH-1@HW1&_|!CD_Co~7NB<)SnD*4$HB%hr_JRG^WjI^2 zxKB+9W`DPm<1o-+#S}-g1n`$@%!wN~plWdW9V?9SSAE-x&?;7Y4Y)xX846+djJ2sC zf1n{ws>LKoL3)v*3fk3H+rAMdNq>sn7j$v{UvXSPpK;n=L#z2 z`PEc>tMULk3tRa_xJ08O@-KAVyC}`L&kLV|`(kwpSMpITP#swdv4cMa4A$4Ty?g8J zvCQs@)m_x*X|IY`ozB(y&9x-;Oy;MW7dUt$3p7KmRtNep9*hzCo=m5lppgtASk7LT#m z5V-CQXa6N!SU`3=hRpIq(e*X1fG8|!$ZMl;Cq}K~B%CTVH-P^=)$f2(KhDkefzPP{ zM|WeJ%S!WVIT=8a;-~c=y&#Kmevh`FU%MfP9~R%P5#R=^?oNLe0}3DQ{24!gB8v56 z+lMhNe{IEt`P(>dxBj-ga@%&A|3J4BqijjdID*ogiEimHk|9*4)j_9B6Is1*Glq}+ zr_?)kOsx?Kq~!U!mK&A}|Ev=tPS1R8f7p!M%qi-Mn;OGk+CRLsd%TLLwYZ)Np46#|p4Xq?))y>mQ`=785CgK7D*`j0ojj64{%r-Qx0M zep-+z&pGmI=ZOkuzwNEocB^=4u}WR2W5=nb*+$HT{-DR@h^+3pk&1f~)!QJO6oDKV z8x2r5X(}DooXKS8WvxwWsmiQ{Zh}lj&XIMc1WfH;m1z2?$Xiz(1`VO;+dud(l_&%V zhLhgGE>HUOEIFTyG!R%_^hxEe3Z*^nC8Z!vuQf&#nO66$mC+3xDCj2&uE#b1!hfYq zgN{A)r1hpW$^UNq573S)(I~}V{VdqZ1IEZIhJxXaP#K@y)O-;qT}j@TO)$6LOlU&VcAq7c4irv!XN86?xAVB65gcu`MiKu2+l@EtmWdApf98+bEV zQdRM+K~xZ+bnmTjcM=snU;D}srJs_)YkRWzm{P!!{$b_2+n=SI%Y$X0&au=HaJ~d& zx%+plfx4?ZQ1d?mk7o1~GAH}r5&OL(W_qiWCyJYB4pgbl0Vxikj8QW$mJcxp6e?`G?rbvSbMn3D zv0mIcY*diHf13R~Ixn+u%+I&Sf0RXebX^aAd$ahQxAkmmRBH(+l_bI_xSl@^W~k|S z)Zo;JY}CB`rkSDuRR3(Cqs0o{!PUi*R(Aq00t?d4G*Q1YS~PYsle4UysT?KB0D(f#bzSMPig`5kz>!{B(;xX zH6S^uafe629j)R%RibEnYD1I7_iA1Y5Z~S1FU37}1o;YMko4?HrWG3rIsHMkZuhF$ zJ<|>-+f$Iz0~N@N(VtE5E1)a;3gcQaYPrBBb2}hI3vnNaBR%RTRvw;>SL1Ku!bb|L;ej9D0mzAu=v( qMEI0t41h#7X^sWZu^H_kQOEj436oQDegT?Z6b%(!aGjEM?{wuVc%Yp=k`F$dWbLcgi+VXbkczOU9sImQ-V3vsH)~WMnIT*_W|J zra^WQ5hi12WH*-k+UWlZ_wv?Y4E@-iMh3Vqp87?;V*|_!r zeSsLbv{Ab{|1|szGr^4A$V61woY&Vy`V#}xJlp^w$;84Z9M2AKw|=6`j*wiK$N6rc z(wWTY^??gV_X8>eC#S-G;(0{&rKJ#=os?vZU$HE-fBzqvN z0%^&Xb8g-F@;KE|9`Q&~F@f{ld&{DLf-&p$wI_l~3VQq4+jg5^UFK^pcNlD2_E#^+r47PbkXr4;_{aend zao}&)4ryiOS6RxQ`etTk#G|3Y>w*FTZVCG_Jm==-V?gKM@to73`5zhnbuypfT&x$t za&)W}vipQKe=n9;^i0Dejswt!HjT#n)Gq&yO_nB(k+)YhQ{k5<_ntbov ziZ@D1O1hw?rgnI=)gOFSE*hl0KhsY3&<6_XkpUeN%VmizKUmQ1$&g>@?}!1pFQq&X z5vYwzPF`4(L)EuUatkYjdX1JET?<&9nIC>RTRDS$f8UNCceiY-rjEu{7j47n#qDywAzL6kK zPRi5MeG16j(vli%h*>S;1T5}Y*ku6!eV5|OqpK;~VIXR1YMS@X;*I|_@m`NmdNc6$ z%0V=j<*|zM3!OkM=I33;%AJU~E$Y{$s($T)kiGT6hKCD_HDhSXlc&_)Od^cmV0FwH zmy--UV=;O4l?veUYI7%1OS~p|@T|=b2fmV>IT{i>P0V!e$wD9>yxDOa>+9{GzTWwh%BR@FSpk&ps z(rkVDt@poXX%+MC$Ixgr;=sVbX_lHGQ&C$-2gM$V95SdlU*|Iw?_VK9#W1%+_N}a~ z2ToU`R6QoDJ<;~|_RoV^^?W^uMB>n`_x65cvdZ=i{*n`tf4UGn|JkG|w0QHaEKG`zL_T$25PQ3~Hc6rbWK1Gmi#dv&b6FZHtaj~S$x?FX`QT6$oxu(&FkF7? z_v;JaZyF5_a0f;ZC>Wcr_lp=i1|m%?cWMgw7y9NL92_(&FH;rOJ#sW2Eq(?&6M)xQoHPEIR6_5VvwR;IVy8Hh{6rag767zT6!7owzcWPTE4#qfZmCu@Q4W} z0V~fk!~_O|4|gZASL2@@ZIWc&%*{C#dh9dscuRomROK_2bT`pWz;Uz_fRg1F%ZhGY z)`jM2i_4>B*-8}kmr_>LboLe{+`^=dVMLww-Fhm>Og!hN|?H(u*{ zdV2m^S?L)P-`QU-tJtR-E#pk$Mm{q({LVLsQSZ(=SgZRPRLP3HMvG=TP(>U86G!7)9RctP7x3aZqutZP&u9Bu1h zn)p~_WI2CaP$ke~=n7^+868u)oR9`}yQ09nB@Go&szi{VNwNvN|zL)}@il4@UO$Z-JWS6hLvR*y-LE zZr{@{->DDo?aR3qj2qbyQwb6kQSL%1urt-# z9^c+W`oV%FgGTHmg{%>Hb9`LfY;ZPZx;X@M&+*f+L0Z&EoA$A8WUr3IInAJyLWruj zuzbu&qKI1US_Ip8mAln6=tJ{B8IJ&ml@0Nbke9{)?Q)4vPA=;0z0udihxrP3EGT}o zIFOGTnJBgqN260liou;Z9qJY6=Er_pkkBS`KgVSD!sH>b8a_!ey_0-Qst}U$Es2c{ zXfeK~f(Av;ej}5~qWOFu#i%d;u(8=m6mn4)Ivf?VP+($GhaJuVa7es)u3A~wRt@@D zP(mdhGkBTZ-|f@6i{j!Db?s9ozFf8rW{F3F!BRe(48eXUuIKqVk(Am*Th}isVno<) zc##po7%Z_p+NRny8S}~CE5w&C&y%aPd~fx8hlQ)JYkmgHfGAWOU~usS$%P|eSz$NTRilC+5% Y`Q@C;Jbixx_^V+sGqN-+*LMm32O@}mfdBvi diff --git a/specsheets/tasks/Scatter/v1.0.0/description.md b/specsheets/tasks/Scatter/v1.0.0/description.md index c2cde82..2492e2c 100644 --- a/specsheets/tasks/Scatter/v1.0.0/description.md +++ b/specsheets/tasks/Scatter/v1.0.0/description.md @@ -9,7 +9,7 @@ ## What it does -A `Repeat` whose iterations are guaranteed fully independent of one another - no subTask output from one iteration feeds into another - so a conforming interpreter may execute the iterations in parallel if it chooses. `range` (a `Range`/`NumericRange`/`ParameterRange`) defines one iteration per element. +A `Repeat` whose iterations are guaranteed fully independent of one another - no subTask output from one iteration feeds into another - so a conforming interpreter may execute the iterations in parallel if it chooses. `range` (a required `Range`/`NumericRange`/`ParameterRange` child) defines one iteration per element. ## Attributes @@ -21,7 +21,7 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an | `subTasks` | object (values: AbstractTask) | yes | | | `outputVariableMap` | object (values: SIdRef) or SIdRef | no | | | `aggregateOutputVariables` | object (values: AggregationCalculation) | no | | -| `range` | RangeInline | no | | +| `range` | RangeInline | yes | | ### Attribute details @@ -33,7 +33,7 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an **`aggregateOutputVariables`** (object (values: AggregationCalculation), optional) - _(no description yet - placeholder, needs to be filled in)_ -**`range`** (RangeInline, optional) - _(no description yet - placeholder, needs to be filled in)_ +**`range`** (RangeInline, required) - _(no description yet - placeholder, needs to be filled in)_ ## Outputs @@ -50,7 +50,7 @@ Additional possible outputs beyond the three standard ones: - `[id].aggregates`: An `AnnotatedData` following `aggregateOutputVariables`, when that attribute is defined. - Dimensions: 1D: one entry per `aggregateOutputVariables` mapping. Each entry's aggregation function collapses the `range` dimension of `[id]` (per `Repeat`, the applied dimension defaults to 'the Repeat' itself, i.e. this one) down to a single value - unless the underlying subTask output was itself multi-dimensional, in which case that dimensionality carries through per entry. -- `[id].range`: Within each iteration, the current value of `range` (see `Repeat`). +- `[id].range`: Within each iteration, the current value of `range`. Always valid, since `range` is required. - Dimensions: Scalar (0-D) per iteration. -- `[id].index`: Within each iteration, the current index into `range`. +- `[id].index`: Within each iteration, the current index into `range`. Always valid. - Dimensions: Scalar (0-D) per iteration. diff --git a/specsheets/tasks/Scatter/v1.0.0/outputs.json b/specsheets/tasks/Scatter/v1.0.0/outputs.json index c3efb9e..6f73d87 100644 --- a/specsheets/tasks/Scatter/v1.0.0/outputs.json +++ b/specsheets/tasks/Scatter/v1.0.0/outputs.json @@ -1,7 +1,6 @@ { "outputs": { "[id]": { - "valid": true, "type": "annotatedData", "dimensions": [ { @@ -22,12 +21,6 @@ } ] }, - "[id].model": { - "valid": false - }, - "[id].strings": { - "valid": false - }, "[id].aggregates": { "valid": "provided(aggregateOutputVariables)", "type": "annotatedData", @@ -43,13 +36,11 @@ ] }, "[id].range": { - "valid": "provided(range)", "type": "annotatedData", "dimensions": [], "note": "the current value of range, within each iteration" }, "[id].index": { - "valid": "provided(range)", "type": "annotatedData", "dimensions": [], "note": "the current index into range, within each iteration" diff --git a/specsheets/tasks/Scatter/v1.0.0/schema.json b/specsheets/tasks/Scatter/v1.0.0/schema.json index ef38356..b4b3175 100644 --- a/specsheets/tasks/Scatter/v1.0.0/schema.json +++ b/specsheets/tasks/Scatter/v1.0.0/schema.json @@ -15,14 +15,20 @@ "_type": { "const": "scatter", "x-rule-id": "Scatter-0003" + }, + "range": { + "$ref": "../../../tasks/Range/v1.0.0/inline.schema.json#/$defs/RangeInline", + "x-rule-id": "Scatter-0005" } }, "required": [ "_type", - "subTasks" + "subTasks", + "range" ], "x-required-rule-ids": { - "subTasks": "Scatter-0001" + "subTasks": "Scatter-0001", + "range": "Scatter-0004" }, "unevaluatedProperties": false } diff --git a/specsheets/tasks/Span/v1.0.0/outputs.json b/specsheets/tasks/Span/v1.0.0/outputs.json index 058a3b6..e5af762 100644 --- a/specsheets/tasks/Span/v1.0.0/outputs.json +++ b/specsheets/tasks/Span/v1.0.0/outputs.json @@ -1,13 +1,3 @@ { - "outputs": { - "[id]": { - "valid": false - }, - "[id].model": { - "valid": false - }, - "[id].strings": { - "valid": false - } - } + "outputs": {} } diff --git a/specsheets/tasks/SteadyState/v1.0.0/SteadyState.png b/specsheets/tasks/SteadyState/v1.0.0/SteadyState.png index 95dcaa25f7fac403ef791b5773a3613eb769a05d..dbe56d2d768ef553d58002d25da1e37aea5a7987 100644 GIT binary patch literal 16780 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 c`Yia!Vc|k literal 16617 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 diff --git a/specsheets/tasks/SteadyState/v1.0.0/description.md b/specsheets/tasks/SteadyState/v1.0.0/description.md index 32faacf..43a8539 100644 --- a/specsheets/tasks/SteadyState/v1.0.0/description.md +++ b/specsheets/tasks/SteadyState/v1.0.0/description.md @@ -11,7 +11,7 @@ Computes the steady state of a model: where dX/dt = 0 for every varying element X of the model, with respect to the independent variable (usually time). `independentVariable` follows the same rules as the simulation tasks (either the model's own variable, or an implicit URN such as `urn:sedml:symbol:time`). -This is an implementation of KISAO:0000407 (steady-state root-finding method). +This is an implementation of KISAO:0000407 (steady-state root-finding method). The algorithm(s) it uses internally may be listed in the optional `workingAlgorithms` (see `WorkingAlgorithm`). ## Attributes @@ -23,7 +23,7 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an | `model` | SIdRef | yes | | | `independentVariable` | StringOrRef | no | | | `outputVariables` | ListOfStringsOrRef | yes | | -| `outputModel` | BooleanOrRef | no | | +| `workingAlgorithms` | array of WorkingAlgorithm | no | | ### Attribute details @@ -35,16 +35,14 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an **`outputVariables`** (ListOfStringsOrRef, required) - _(no description yet - placeholder, needs to be filled in)_ -**`outputModel`** (BooleanOrRef, optional) - _(no description yet - placeholder, needs to be filled in)_ +**`workingAlgorithms`** (array of WorkingAlgorithm, optional) - _(no description yet - placeholder, needs to be filled in)_ ## Outputs -The steady-state values of `outputVariables`, accessible as `[id]`. If `outputModel` is `true`, the resulting model state is also available as `[id].model`. +The steady-state values of `outputVariables`, accessible as `[id]`. The resulting model state is always also available as `[id].model`. - `[id]`: **Valid** - Dimensions: 1D: one value per entry of `outputVariables`, at steady state. - `[id].model`: **Valid** - `[id].strings`: **Invalid** - -`[id].model` is only produced when `outputModel` is `true`. diff --git a/specsheets/tasks/SteadyState/v1.0.0/outputs.json b/specsheets/tasks/SteadyState/v1.0.0/outputs.json index 4f46b01..7ec8171 100644 --- a/specsheets/tasks/SteadyState/v1.0.0/outputs.json +++ b/specsheets/tasks/SteadyState/v1.0.0/outputs.json @@ -1,7 +1,6 @@ { "outputs": { "[id]": { - "valid": true, "type": "annotatedData", "dimensions": [ { @@ -17,11 +16,7 @@ ] }, "[id].model": { - "valid": "outputModel == true", "type": "model" - }, - "[id].strings": { - "valid": false } } } diff --git a/specsheets/tasks/SteadyState/v1.0.0/schema.json b/specsheets/tasks/SteadyState/v1.0.0/schema.json index 8ba2e3e..4f60d0c 100644 --- a/specsheets/tasks/SteadyState/v1.0.0/schema.json +++ b/specsheets/tasks/SteadyState/v1.0.0/schema.json @@ -4,7 +4,7 @@ "title": "SED2 SteadyState", "$defs": { "SteadyState": { - "description": "Compute the steady state of a model. kisaoID must be KISAO:0000407 or a child.", + "description": "Compute the steady state of a model.", "type": "object", "allOf": [ { @@ -27,12 +27,12 @@ "outputVariables": { "$ref": "../../../core/Types/v1.0.0/schema.json#/$defs/ListOfStringsOrRef" }, - "outputModel": { - "$ref": "../../../core/Types/v1.0.0/schema.json#/$defs/BooleanOrRef", - "x-rule-id": [ - "SteadyState-0005", - "SteadyState-0006" - ] + "workingAlgorithms": { + "type": "array", + "items": { + "$ref": "../../../auxiliary/WorkingAlgorithm/v1.0.0/schema.json#/$defs/WorkingAlgorithm" + }, + "x-rule-id": "SteadyState-0007" } }, "required": [ diff --git a/specsheets/tasks/SteadyState/v1.0.0/validation/SteadyState-0005.md b/specsheets/tasks/SteadyState/v1.0.0/validation/SteadyState-0005.md deleted file mode 100644 index 6f739ef..0000000 --- a/specsheets/tasks/SteadyState/v1.0.0/validation/SteadyState-0005.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -id: SteadyState-0005 -rule: When the value of outputModel of a SteadyState is provided directly, it must be a boolean. -message: "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not a boolean." -severity: error -status: active -check: schema ---- - -`outputModel` is `BooleanOrRef`: the value, when not a reference, must be a boolean. diff --git a/specsheets/tasks/SteadyState/v1.0.0/validation/SteadyState-0006.md b/specsheets/tasks/SteadyState/v1.0.0/validation/SteadyState-0006.md deleted file mode 100644 index 4e45ab3..0000000 --- a/specsheets/tasks/SteadyState/v1.0.0/validation/SteadyState-0006.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -id: SteadyState-0006 -rule: When the value of outputModel of a SteadyState is a reference, it must be a reference to a boolean. -message: "Attribute '{attr}' of {class} '{id}' is the reference '{value}', which resolves to '{resolved-value}', not a boolean." -severity: error -status: active -check: ref-type ---- - -`outputModel` is `BooleanOrRef`: when the value is a reference, it must resolve to a boolean. diff --git a/specsheets/tasks/StringFormation/v1.0.0/outputs.json b/specsheets/tasks/StringFormation/v1.0.0/outputs.json index 82ab3d2..6089362 100644 --- a/specsheets/tasks/StringFormation/v1.0.0/outputs.json +++ b/specsheets/tasks/StringFormation/v1.0.0/outputs.json @@ -1,18 +1,13 @@ { "outputs": { "[id]": { - "valid": true, "type": "annotatedData", "dimensions": { "source": "runtime", "note": "scalar when no element of concatenate is itself a list; otherwise N-D matching the shape of the list element(s) within concatenate (1D for one list element, higher-D when several list elements are combined pairwise, all sharing the same length/shape per dimension) - not derivable without evaluating concatenate's actual element values" } }, - "[id].model": { - "valid": false - }, "[id].strings": { - "valid": true, "type": "stringList", "dimensions": { "source": "runtime", From 498a8cffc6a91d3de97ddbe94768703f603c4f75 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 1 Oct 2026 00:28:55 +0000 Subject: [PATCH 2/5] Regenerate generated directories and SPECIFICATION.md from spec --- SPECIFICATION.md | 1046 +++++++++-------- .../cpp/include/libsed2/GeneratedModel.hpp | 125 +- generated/cpp/include/libsed2/RulesData.hpp | 5 - .../sedml/libsed2/AggregationCalculation.java | 2 +- .../sedml/libsed2/BoundedODESimulation.java | 2 +- .../libsed2/BoundedStochasticSimulation.java | 2 +- .../java/org/sedml/libsed2/Calculation.java | 2 +- .../org/sedml/libsed2/CreateDataBlock.java | 2 +- .../java/org/sedml/libsed2/CsvImport.java | 2 +- .../java/org/sedml/libsed2/DataImport.java | 2 +- .../sedml/libsed2/DrawFromDistribution.java | 2 +- .../sedml/libsed2/ExplicitODESimulation.java | 2 +- .../libsed2/ExplicitStochasticSimulation.java | 2 +- .../sedml/libsed2/FluxBalanceAnalysis.java | 23 +- .../java/org/sedml/libsed2/JacobianFull.java | 2 +- .../org/sedml/libsed2/JacobianReduced.java | 2 +- .../src/main/java/org/sedml/libsed2/Loop.java | 6 +- .../java/org/sedml/libsed2/ModelChange.java | 2 +- .../org/sedml/libsed2/ModelElementList.java | 2 +- .../java/org/sedml/libsed2/ModelImport.java | 2 +- .../java/org/sedml/libsed2/NumericRange.java | 2 +- .../sedml/libsed2/OneStepODESimulation.java | 2 +- .../libsed2/OneStepStochasticSimulation.java | 2 +- .../org/sedml/libsed2/ParameterRange.java | 2 +- .../java/org/sedml/libsed2/ParameterScan.java | 22 +- .../main/java/org/sedml/libsed2/Range.java | 2 +- .../java/org/sedml/libsed2/RelabelData.java | 2 +- .../java/org/sedml/libsed2/RulesData.java | 5 - .../main/java/org/sedml/libsed2/Scatter.java | 6 +- .../src/main/java/org/sedml/libsed2/Span.java | 2 +- .../java/org/sedml/libsed2/SteadyState.java | 23 +- .../org/sedml/libsed2/StringFormation.java | 2 +- generated/python/src/libsed2/model.py | 165 ++- generated/python/src/libsed2/rules_data.py | 5 - generated/rules-v1.0.0.json | 40 - 35 files changed, 759 insertions(+), 758 deletions(-) diff --git a/SPECIFICATION.md b/SPECIFICATION.md index cd08bb0..dfb6f0a 100644 --- a/SPECIFICATION.md +++ b/SPECIFICATION.md @@ -81,10 +81,15 @@ title: SED2 Specification ## Core Specification +*Source: [core-spec.md](core-spec.md)* + This document describes the overall shape and design of a SED2 document. It is deliberately short: the detailed, per-class rules (attributes, types, outputs, UML diagram) now live in individual **Specification Sheets** under `specsheets/`, one per Task, Output, and supporting class, each versioned (`v1.0.0/`, and later `v1.0.1/`, etc.) so the spec can evolve without breaking documents or tools written against an earlier version. ### 1. What a SED2 document is +*Source: [core-spec.md, line 5](core-spec.md#L5)* + + A SED2 document contains two main sections for describing a simulation experiment: **Tasks** and **Outputs**. Tasks define *how to do things*; Outputs define *how to report the results*. The document also holds predefined **constants** (centrally located so they can be referenced and changed in one place) and **styles** (presentation settings used by plots - still a placeholder, see below). Full attribute list and UML: [`specsheets/core/SEDDocument/v1.0.0/`](specsheets/core/SEDDocument/v1.0.0/description.md) @@ -101,12 +106,18 @@ Full attribute list and UML: [`specsheets/core/SEDDocument/v1.0.0/`](specsheets/ ### 2. Every element (`SEDBase`) +*Source: [core-spec.md, line 21](core-spec.md#L21)* + + Every element in a SED2 document may optionally carry `name`, `description`, `notes` (markdown), and `annotations` (qualifier/value pairs). Most elements also have an implicit `id`, which is not a child field but the dictionary key under which the element appears in its parent collection. Full detail: [`specsheets/core/SEDBase/v1.0.0/`](specsheets/core/SEDBase/v1.0.0/description.md) ### 3. The DAG design: inputs, outputs, and the chronological rule +*Source: [core-spec.md, line 27](core-spec.md#L27)* + + Every SED2 element defines its inputs and outputs, so a document can be understood as a **Directed Acyclic Graph (DAG)**: Tasks and Outputs are nodes, and references between them (`#tasks:...`, `#constants:...`, etc.) are the edges. **Chronological organization.** No Task nor Output may depend on input from a later Task. A conforming reader can therefore always execute a document correctly by walking `tasks` and then `outputs` in file order - while a more sophisticated interpreter may instead distribute independent Tasks across parallel workers by following the DAG's connected components. When a Repeat (`Scatter`/`Loop`/`ParameterScan`) defines child `subTasks`, those children follow the same internal ordering rule. @@ -115,6 +126,9 @@ Every SED2 element defines its inputs and outputs, so a document can be understo ### 4. Types and references +*Source: [core-spec.md, line 35](core-spec.md#L35)* + + Every value in a SED2 document is either a literal or a **reference** (an `SIdRef`) to a value elsewhere in the document - anywhere a `double` is expected, a string like `"#tasks:sim1.model['S1']"` may appear instead, and must be resolved to a double at execution time. The references point to task outputs. Each task defines what the shape of its output or outputs are. The three basic types of output references are: @@ -128,11 +142,17 @@ A full primitive/reference type catalogue: [`specsheets/core/Types/v1.0.0/`](spe ### 5. Tasks +*Source: [core-spec.md, line 48](core-spec.md#L48)* + + Every Task derives from `AbstractTask`, which itself derives from `SEDBase`: an implicit id plus a `_type` discriminator naming the concrete task class. Every concrete Task subclass must define what its output(s) are - see [`specsheets/core/SEDBase`](specsheets/core/SEDBase/v1.0.0/description.md) and each task's own Data Sheet under [`specsheets/tasks/`](specsheets/tasks/) for the details. ### 6. Outputs +*Source: [core-spec.md, line 53](core-spec.md#L53)* + + Every Output derives from `AbstractOutput`, which itself derives from `SEDBase`. An `AbstractOutput` may **never** be used as input to anything else in the document - it is always the final stage of processing; anything that needs to be reused belongs in a Task instead. SED2 dictates only what data an output must contain, not the concrete form it takes (an in-memory object, a web page, exported files). There are two basic families, documented under [`specsheets/outputs/`](specsheets/outputs/): @@ -142,6 +162,9 @@ There are two basic families, documented under [`specsheets/outputs/`](specsheet ### 7. Namespaces +*Source: [core-spec.md, line 62](core-spec.md#L62)* + + SED2 allows third parties to extend a document with their own attributes and classes under a **namespace**, written `namespace@identifier` (e.g. `saurolab@thisFactor` as an extra attribute, or `saurolab@thisAnalysis` as a whole new type). This applies at two levels: - **Attribute-level**: an extra `namespace@key` field alongside an element's normal attributes. @@ -153,6 +176,9 @@ A namespace also carries its own version, independent of the document's own `ver ### 8. Data Sheet folder layout and versioning +*Source: [core-spec.md, line 73](core-spec.md#L73)* + + ``` specsheets/ core/ - document-level & base-class infrastructure (not a Task or Output itself) @@ -220,10 +246,16 @@ Any future changes to a class creates a sibling `v#.#.#/` folder alongside `v1.0 ### 9. Validating a document against these schemas +*Source: [core-spec.md, line 140](core-spec.md#L140)* + + To validate a whole SED2 document, `$ref` the appropriate `specsheets/core/SEDDocument/v1.0.0/schema.json` (which itself only needs `AbstractTask`/`AbstractOutput`, which in turn enumerate the concrete task/output classes) with a schema registry that can resolve relative file `$ref`s - e.g. Python's `referencing`/`jsonschema` packages, pointed at the `specsheets/` root. To validate or compose against just one class (e.g. embedding `ExplicitODESimulation`'s schema inside a larger tool-specific document), `$ref` that class's own `specsheets/tasks/ExplicitODESimulation/v1.0.0/schema.json` directly - its external refs resolve the same way. ### 10. Known gaps and inconsistencies (flagged, not fixed here) +*Source: [core-spec.md, line 144](core-spec.md#L144)* + + Per the project's own working rule, this split is descriptive - it surfaces inconsistencies for you to resolve rather than silently deciding them: - **`Style` is unspecified.** Both the prose (`"[To be filled in; should be a straight copy of SED-ML's Style class.]"`) and the schema (a permissive `{"type": "object"}` placeholder) mark this as incomplete. @@ -239,6 +271,9 @@ Per the project's own working rule, this split is descriptive - it surfaces inco ### 11. Multi-target consistency reminder +*Source: [core-spec.md, line 159](core-spec.md#L159)* + + Per this project's own working rules: any future design change to the SED2 class model, cross-reference/math syntax, or validation rules must be reflected in **all three** generated libraries (C++, Java, Python) in the same change - this document split does not touch code generation, but any content change that follows from resolving Section 10's open items will. --- @@ -249,6 +284,8 @@ Per this project's own working rules: any future design change to the SED2 class #### SEDBase +*Source: [specsheets/core/SEDBase/v1.0.0/description.md](specsheets/core/SEDBase/v1.0.0/description.md)* + ![SEDBase UML diagram](specsheets/core/SEDBase/v1.0.0/SEDBase.png) **Category:** core @@ -275,29 +312,29 @@ Every element inherits `SEDBase`, but whether `[id]`, `[id].model`, or `[id].str ##### Validation Rules -**`SEDBase-0000`** (error) - The element fails a JSON Schema constraint attributable to SEDBase that does not match any other numbered rule. +**`SEDBase-0000`** (error) - The element fails a JSON Schema constraint attributable to SEDBase that does not match any other numbered rule. ([source](specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0000.md)) > Catch-all rule for schema-pass failures attributable to SEDBase (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`SEDBase-0001`** (error) - The name attribute of a SEDBase-derived element, if present, must be a string. +**`SEDBase-0001`** (error) - The name attribute of a SEDBase-derived element, if present, must be a string. ([source](specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0001.md)) > `name` is an unrestricted string in SEDBaseFields. -**`SEDBase-0002`** (error) - The description attribute of a SEDBase-derived element, if present, must be a string. +**`SEDBase-0002`** (error) - The description attribute of a SEDBase-derived element, if present, must be a string. ([source](specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0002.md)) > `description` is an unrestricted string in SEDBaseFields. -**`SEDBase-0003`** (error) - The notes attribute of a SEDBase-derived element, if present, must be a markdown-formatted string. +**`SEDBase-0003`** (error) - The notes attribute of a SEDBase-derived element, if present, must be a markdown-formatted string. ([source](specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0003.md)) > `notes` is a `MarkdownString` in SEDBaseFields - a CommonMark-formatted string. -**`SEDBase-0004`** (error) - The annotations attribute of a SEDBase-derived element, if present, must be an array of Annotation objects. +**`SEDBase-0004`** (error) - The annotations attribute of a SEDBase-derived element, if present, must be an array of Annotation objects. ([source](specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0004.md)) > `annotations` is an array of `Annotation` objects in SEDBaseFields, each with a required `qualifier` (a `Qualifier` string, e.g. 'bqbiol:hasPart') and a required `value` (`AnyValueOrRef`). -**`SEDBase-0005`** (error) - The first segment of a reference must name one of SEDDocument's ID-keyed collections: tasks, constants, outputs, or styles. +**`SEDBase-0005`** (error) - The first segment of a reference must name one of SEDDocument's ID-keyed collections: tasks, constants, outputs, or styles. ([source](specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0005.md)) > Applies to every reference anywhere in the document: a whole attribute value, > an element of an array or object value, or a REFERENCE token embedded in a @@ -308,7 +345,7 @@ Every element inherits `SEDBase`, but whether `[id]`, `[id].model`, or `[id].str > Listing #outputs as a legal root keeps this rule purely syntactic; > SEDBase-0007 is the rule that rejects actually using it. -**`SEDBase-0006`** (error) - Every colon-delimited segment of a reference must resolve to an existing element. +**`SEDBase-0006`** (error) - Every colon-delimited segment of a reference must resolve to an existing element. ([source](specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0006.md)) > Walks the containment tree one colon segment at a time: #tasks:loop1 must name > a key of SEDDocument.tasks; #tasks:loop1:subTasks:sim1 must name a key of @@ -326,13 +363,13 @@ Every element inherits `SEDBase`, but whether `[id]`, `[id].model`, or `[id].str > reference-path prefix, which is exactly what {subvalue} already means for > the other reference rules below (SEDBase-0008 through -0011).) -**`SEDBase-0007`** (error) - A reference must not target an AbstractOutput, or anything contained in one. +**`SEDBase-0007`** (error) - A reference must not target an AbstractOutput, or anything contained in one. ([source](specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0007.md)) > Enforces core-spec.md Section 6: an AbstractOutput is always a final stage > and is never an input to anything else. This includes an output referencing > another output. -**`SEDBase-0008`** (error) - A dot-accessor in a reference must be one the target declares valid. +**`SEDBase-0008`** (error) - A dot-accessor in a reference must be one the target declares valid. ([source](specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0008.md)) > For a task target, the accessor must appear in that task class's outputs.json, > and its "valid" field must be true, or be an expression that evaluates to true @@ -346,7 +383,7 @@ Every element inherits `SEDBase`, but whether `[id]`, `[id].model`, or `[id].str > "[id]" entry: referencing a ModelImport as '#tasks:m1' with no .model fires this > rule, with {subvalue} empty. -**`SEDBase-0009`** (error) - A reference must not apply more bracket indices than its target has dimensions. +**`SEDBase-0009`** (error) - A reference must not apply more bracket indices than its target has dimensions. ([source](specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0009.md)) > Only fires when the target's dimension count is static in outputs.json (a > fixed "dimensions" array, or one whose count is computable from the target's @@ -354,28 +391,28 @@ Every element inherits `SEDBase`, but whether `[id]`, `[id].model`, or `[id].str > this rule. {count} is the number of indices used; {expected-count} is the > number of dimensions available. -**`SEDBase-0010`** (error) - A label index in a reference must name one of the labels of the dimension it indexes. +**`SEDBase-0010`** (error) - A label index in a reference must name one of the labels of the dimension it indexes. ([source](specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0010.md)) > Only fires when that dimension's labels are "static" in outputs.json and all > the fields they are computed from are literals. For example, with > outputVariables ["S1","S2"], '#tasks:sim1['S3']' fires this rule; with > outputVariables given as a reference, it cannot fire. -**`SEDBase-0011`** (error) - An integer or range index in a reference must fall within the size of the dimension it indexes. +**`SEDBase-0011`** (error) - An integer or range index in a reference must fall within the size of the dimension it indexes. ([source](specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0011.md)) > Only fires when that dimension's size is "static" and computable. Negative > indices count from the end (Python-style), so for size n the legal integer > indices are -n..n-1. For a range [a:b], both ends must be within -n..n, and > the range must select at least one element. -**`SEDBase-0012`** (error) - A bracket index into a constant must match the structure of that constant's literal value. +**`SEDBase-0012`** (error) - A bracket index into a constant must match the structure of that constant's literal value. ([source](specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0012.md)) > Constants have no outputs.json; their shape is simply their literal JSON value. > An integer index requires an array of sufficient length, a label index requires > an object with that key, and any index into a scalar fires this rule. A > constant whose value is itself a reference is followed first. -**`SEDBase-0013`** (error) - A reference to a Repeat's subTasks, its .range/.index outputs, or one of its loop variables is only legal when the element holding the reference is that Repeat itself, or lies within that Repeat's own subTasks (at any depth, including through a nested Repeat). +**`SEDBase-0013`** (error) - A reference to a Repeat's subTasks, its .range/.index outputs, or one of its loop variables is only legal when the element holding the reference is that Repeat itself, or lies within that Repeat's own subTasks (at any depth, including through a nested Repeat). ([source](specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0013.md)) > Consolidates three rules that were drafted separately (AbstractTask-0004, > Repeat-0007, Loop-0006) into one, moved to SEDBase rather than AbstractTask @@ -393,7 +430,7 @@ Every element inherits `SEDBase`, but whether `[id]`, `[id].model`, or `[id].str > SEDBase-0008 like any other task reference. The only way a subTask's > per-iteration result leaves its Repeat is through one of those two exports. -**`SEDBase-0014`** (warning) - An integer or range index into a dimension whose size is sourced as runtime and documents a min should warn when the index requires more entries than min guarantees. +**`SEDBase-0014`** (warning) - An integer or range index into a dimension whose size is sourced as runtime and documents a min should warn when the index requires more entries than min guarantees. ([source](specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0014.md)) > Only fires when the target dimension's outputs.json size entry has > `source: "runtime"` and carries a `min`. A bare index `n` needs `min > n`; @@ -403,7 +440,7 @@ Every element inherits `SEDBase`, but whether `[id]`, `[id].model`, or `[id].str > guarantee, not the true count. Distinct from SEDBase-0011, which fires as > an error against a dimension whose size is statically known for certain. -**`SEDBase-0015`** (error) - A reference required to resolve to a scalar value must apply enough non-range indices to reduce its target's shape to zero remaining dimensions. +**`SEDBase-0015`** (error) - A reference required to resolve to a scalar value must apply enough non-range indices to reduce its target's shape to zero remaining dimensions. ([source](specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0015.md)) > This is the rule that actually backs every "must be a reference to a > number/string/..." field-level rule (see check: ref-type under Validation) @@ -416,7 +453,7 @@ Every element inherits `SEDBase`, but whether `[id]`, `[id].model`, or `[id].str > own type is then checked as usual by the field's own ref-type rule, not > by this one - this rule only covers the "still shaped" failure mode. -**`SEDBase-0016`** (error) - A reference required to resolve to a model must resolve to a model. +**`SEDBase-0016`** (error) - A reference required to resolve to a model must resolve to a model. ([source](specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0016.md)) > Applies to every field whose schema property carries `"x-ref-target": "model"` > (the `model` attribute of the simulation, FluxBalanceAnalysis, Jacobian, @@ -432,7 +469,7 @@ Every element inherits `SEDBase`, but whether `[id]`, `[id].model`, or `[id].str > reference did resolve to, such as "a number", "an array", "an object", or > "a annotatedData value". -**`SEDBase-0017`** (error) - A reference required to resolve to AnnotatedData must resolve to AnnotatedData. +**`SEDBase-0017`** (error) - A reference required to resolve to AnnotatedData must resolve to AnnotatedData. ([source](specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0017.md)) > Applies to every field whose schema property carries > `"x-ref-target": "annotatedData"` (AbstractCurve's `x`; Curve's `y`, `xErrorUpper`, @@ -452,6 +489,8 @@ Every element inherits `SEDBase`, but whether `[id]`, `[id].model`, or `[id].str #### SEDDocument +*Source: [specsheets/core/SEDDocument/v1.0.0/description.md](specsheets/core/SEDDocument/v1.0.0/description.md)* + ![SEDDocument UML diagram](specsheets/core/SEDDocument/v1.0.0/SEDDocument.png) **Category:** core @@ -507,41 +546,41 @@ The document is the root container, not an addressable element - it is never ref ##### Validation Rules -**`SEDDocument-0000`** (error) - The element fails a JSON Schema constraint attributable to SEDDocument that does not match any other numbered rule. +**`SEDDocument-0000`** (error) - The element fails a JSON Schema constraint attributable to SEDDocument that does not match any other numbered rule. ([source](specsheets/core/SEDDocument/v1.0.0/validation/SEDDocument-0000.md)) > Catch-all rule for schema-pass failures attributable to SEDDocument (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`SEDDocument-0001`** (error) - The version attribute of a SEDDocument is required. +**`SEDDocument-0001`** (error) - The version attribute of a SEDDocument is required. ([source](specsheets/core/SEDDocument/v1.0.0/validation/SEDDocument-0001.md)) > `version` is required. -**`SEDDocument-0002`** (error) - The version attribute of a SEDDocument must be a string. +**`SEDDocument-0002`** (error) - The version attribute of a SEDDocument must be a string. ([source](specsheets/core/SEDDocument/v1.0.0/validation/SEDDocument-0002.md)) > `version` is `string`: it must be a string. -**`SEDDocument-0003`** (error) - The version attribute of a SEDDocument must match the format v#.#.# (major.minor.patch). +**`SEDDocument-0003`** (error) - The version attribute of a SEDDocument must match the format v#.#.# (major.minor.patch). ([source](specsheets/core/SEDDocument/v1.0.0/validation/SEDDocument-0003.md)) > `version` must match the pattern `v#.#.#` (e.g. `v1.0.0`). -**`SEDDocument-0005`** (error) - The constants attribute of a SEDDocument must be an object whose values are AnyValueOrRef. +**`SEDDocument-0005`** (error) - The constants attribute of a SEDDocument must be an object whose values are AnyValueOrRef. ([source](specsheets/core/SEDDocument/v1.0.0/validation/SEDDocument-0005.md)) > `constants` is `object (values: AnyValueOrRef)`: it must be an object whose values are AnyValueOrRef. -**`SEDDocument-0006`** (error) - The tasks attribute of a SEDDocument must be an object whose values are AbstractTask. +**`SEDDocument-0006`** (error) - The tasks attribute of a SEDDocument must be an object whose values are AbstractTask. ([source](specsheets/core/SEDDocument/v1.0.0/validation/SEDDocument-0006.md)) > `tasks` is `object (values: AbstractTask)`: it must be an object whose values are AbstractTask. -**`SEDDocument-0007`** (error) - The outputs attribute of a SEDDocument must be an object whose values are AbstractOutput. +**`SEDDocument-0007`** (error) - The outputs attribute of a SEDDocument must be an object whose values are AbstractOutput. ([source](specsheets/core/SEDDocument/v1.0.0/validation/SEDDocument-0007.md)) > `outputs` is `object (values: AbstractOutput)`: it must be an object whose values are AbstractOutput. -**`SEDDocument-0008`** (error) - The styles attribute of a SEDDocument must be an object whose values are Style. +**`SEDDocument-0008`** (error) - The styles attribute of a SEDDocument must be an object whose values are Style. ([source](specsheets/core/SEDDocument/v1.0.0/validation/SEDDocument-0008.md)) > `styles` is `object (values: Style)`: it must be an object whose values are Style. -**`SEDDocument-0009`** (error) - For every namespace prefix used anywhere in the document, SEDDocument must declare a @version attribute. +**`SEDDocument-0009`** (error) - For every namespace prefix used anywhere in the document, SEDDocument must declare a @version attribute. ([source](specsheets/core/SEDDocument/v1.0.0/validation/SEDDocument-0009.md)) > Applies to registered and unregistered prefixes alike: 'used' means any > attribute key or _type value of the form prefix@identifier, anywhere in the @@ -550,17 +589,17 @@ The document is the root container, not an addressable element - it is never ref > prefix (see Design.md's Namespaces section); for an unregistered prefix, > SEDDocument-0014 checks it by hand instead. -**`SEDDocument-0010`** (warning) - A @version attribute should not be declared for a namespace the document never uses. +**`SEDDocument-0010`** (warning) - A @version attribute should not be declared for a namespace the document never uses. ([source](specsheets/core/SEDDocument/v1.0.0/validation/SEDDocument-0010.md)) > Harmless but likely a leftover. -**`SEDDocument-0011`** (warning) - The version of a SEDDocument should not be newer than the newest document version this library knows. +**`SEDDocument-0011`** (warning) - The version of a SEDDocument should not be newer than the newest document version this library knows. ([source](specsheets/core/SEDDocument/v1.0.0/validation/SEDDocument-0011.md)) > Version resolution picks the newest directory not greater than the > document's version, so a v1.3.0 document silently validates against v1.2.x > rules. This makes that visible. -**`SEDDocument-0012`** (error) - No JSON object in a SED2 document may contain the same key more than once. +**`SEDDocument-0012`** (error) - No JSON object in a SED2 document may contain the same key more than once. ([source](specsheets/core/SEDDocument/v1.0.0/validation/SEDDocument-0012.md)) > JSON parsers silently keep one copy of a duplicated key (usually the last), > so a document with two tasks named sim1 would lose one without any error. @@ -580,14 +619,14 @@ The document is the root container, not an addressable element - it is never ref > languages. Because of this, no fixture should chain this rule onto > another rule's filename the way Testing otherwise allows - see Testing. -**`SEDDocument-0013`** (error) - A constant may only reference constants that appear before it in the constants dictionary. +**`SEDDocument-0013`** (error) - A constant may only reference constants that appear before it in the constants dictionary. ([source](specsheets/core/SEDDocument/v1.0.0/validation/SEDDocument-0013.md)) > constants is described as coming before tasks, so a constant referencing a > task would break file-order execution. Constants may only reference earlier > constants, the same chronological principle AbstractTask-0003 applies to > tasks. -**`SEDDocument-0014`** (error) - An unregistered namespace's @version attribute must match the format v#.#.# (major.minor.patch). +**`SEDDocument-0014`** (error) - An unregistered namespace's @version attribute must match the format v#.#.# (major.minor.patch). ([source](specsheets/core/SEDDocument/v1.0.0/validation/SEDDocument-0014.md)) > For a registered namespace this is already enforced as a generated schema > pattern (see Design.md's Namespaces section) - the same mechanism as @@ -599,6 +638,8 @@ The document is the root container, not an addressable element - it is never ref #### Style +*Source: [specsheets/core/Style/v1.0.0/description.md](specsheets/core/Style/v1.0.0/description.md)* + *(No UML diagram exists yet for `Style` in the source spec - see [`DIAGRAM-PENDING.md`](specsheets/core/Style/v1.0.0/DIAGRAM-PENDING.md).)* **Category:** core @@ -633,7 +674,7 @@ _This class defines no additional attributes beyond `SEDBaseFields`._ ##### Validation Rules -**`Style-0000`** (error) - The element fails a JSON Schema constraint attributable to Style that does not match any other numbered rule. +**`Style-0000`** (error) - The element fails a JSON Schema constraint attributable to Style that does not match any other numbered rule. ([source](specsheets/core/Style/v1.0.0/validation/Style-0000.md)) > Catch-all rule for schema-pass failures attributable to Style (or a > more specific descendant whose own class's failure location can't be @@ -641,6 +682,8 @@ _This class defines no additional attributes beyond `SEDBaseFields`._ #### Types +*Source: [specsheets/core/Types/v1.0.0/description.md](specsheets/core/Types/v1.0.0/description.md)* + *(This page bundles the shared primitive and reference-helper types; it has no single UML class box of its own - see `core/SEDBase` for the base class every element derives from.)* **Category:** core @@ -750,7 +793,7 @@ Not applicable - `Types` bundles primitive/reference-helper definitions; it is n ##### Validation Rules -**`Types-0001`** (error) - A math expression must be a well-formed expression under the SED2 infix grammar. +**`Types-0001`** (error) - A math expression must be a well-formed expression under the SED2 infix grammar. ([source](specsheets/core/Types/v1.0.0/validation/Types-0001.md)) > The grammar is the one in Design.md's Math section (math.g4). {parse-message} > is the parser's own error text. When the math attribute is itself a @@ -764,19 +807,19 @@ Not applicable - `Types` bundles primitive/reference-helper definitions; it is n > four rules per class or attaching Calculation-specific numbering to a > generic grammar concern. -**`Types-0002`** (error) - Every function called in a math expression must be defined in the predefined-functions registry. +**`Types-0002`** (error) - Every function called in a math expression must be defined in the predefined-functions registry. ([source](specsheets/core/Types/v1.0.0/validation/Types-0002.md)) > The registry is schema/predefined-functions.json: the SBML L3 Core MathML > subset, the 12 distrib functions, and SED2's own additions (currently sum). > A namespace cannot add functions today; if that is wanted, the registry needs > a namespace extension point. -**`Types-0003`** (error) - Every function called in a math expression must be given a number of arguments its registry entry allows. +**`Types-0003`** (error) - Every function called in a math expression must be given a number of arguments its registry entry allows. ([source](specsheets/core/Types/v1.0.0/validation/Types-0003.md)) > Arity comes from the function's registry entry, including the distrib > functions' alternative argument counts (e.g. normal takes 2 or 4). -**`Types-0004`** (error) - Every bare identifier in a math expression must be a predefined constant. +**`Types-0004`** (error) - Every bare identifier in a math expression must be a predefined constant. ([source](specsheets/core/Types/v1.0.0/validation/Types-0004.md)) > SED2 math has no free variables: anything that is not a number, a predefined > constant (pi, exponentiale, true, false, notanumber, infinity), or a function @@ -789,6 +832,8 @@ Not applicable - `Types` bundles primitive/reference-helper definitions; it is n #### AbstractODESimulation +*Source: [specsheets/tasks/AbstractODESimulation/v1.0.0/description.md](specsheets/tasks/AbstractODESimulation/v1.0.0/description.md)* + ![AbstractODESimulation UML diagram](specsheets/tasks/AbstractODESimulation/v1.0.0/AbstractODESimulation.png) **Category:** tasks @@ -869,158 +914,160 @@ There is no output rule for `AbstractODESimulation` itself - see `ExplicitODESim ##### Validation Rules -**`AbstractODESimulation-0000`** (error) - The element fails a JSON Schema constraint attributable to AbstractODESimulation that does not match any other numbered rule. +**`AbstractODESimulation-0000`** (error) - The element fails a JSON Schema constraint attributable to AbstractODESimulation that does not match any other numbered rule. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0000.md)) > Catch-all rule for schema-pass failures attributable to AbstractODESimulation (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`AbstractODESimulation-0001`** (error) - When the value of relativeTolerance of an AbstractODESimulation is provided directly, it must be a number. +**`AbstractODESimulation-0001`** (error) - When the value of relativeTolerance of an AbstractODESimulation is provided directly, it must be a number. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0001.md)) > `relativeTolerance` is `NumberOrRef`: the value, when not a reference, must be a number. -**`AbstractODESimulation-0002`** (error) - When the value of relativeTolerance of an AbstractODESimulation is a reference, it must be a reference to a number. +**`AbstractODESimulation-0002`** (error) - When the value of relativeTolerance of an AbstractODESimulation is a reference, it must be a reference to a number. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0002.md)) > `relativeTolerance` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`AbstractODESimulation-0003`** (error) - When the value of absoluteTolerance of an AbstractODESimulation is provided directly, it must be a number. +**`AbstractODESimulation-0003`** (error) - When the value of absoluteTolerance of an AbstractODESimulation is provided directly, it must be a number. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0003.md)) > `absoluteTolerance` is `NumberOrRef`: the value, when not a reference, must be a number. -**`AbstractODESimulation-0004`** (error) - When the value of absoluteTolerance of an AbstractODESimulation is a reference, it must be a reference to a number. +**`AbstractODESimulation-0004`** (error) - When the value of absoluteTolerance of an AbstractODESimulation is a reference, it must be a reference to a number. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0004.md)) > `absoluteTolerance` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`AbstractODESimulation-0005`** (error) - When the value of absoluteToleranceVector of an AbstractODESimulation is provided directly, it must be an array of numbers. +**`AbstractODESimulation-0005`** (error) - When the value of absoluteToleranceVector of an AbstractODESimulation is provided directly, it must be an array of numbers. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0005.md)) > `absoluteToleranceVector` is `ListOfNumbersOrRef`: the value, when not a reference, must be an array of numbers. -**`AbstractODESimulation-0006`** (error) - When the value of absoluteToleranceVector of an AbstractODESimulation is a reference, it must be a reference to an array of numbers. +**`AbstractODESimulation-0006`** (error) - When the value of absoluteToleranceVector of an AbstractODESimulation is a reference, it must be a reference to an array of numbers. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0006.md)) > `absoluteToleranceVector` is `ListOfNumbersOrRef`: when the value is a reference, it must resolve to an array of numbers. -**`AbstractODESimulation-0007`** (error) - When the value of absoluteToleranceAdjustmentFactor of an AbstractODESimulation is provided directly, it must be a number. +**`AbstractODESimulation-0007`** (error) - When the value of absoluteToleranceAdjustmentFactor of an AbstractODESimulation is provided directly, it must be a number. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0007.md)) > `absoluteToleranceAdjustmentFactor` is `NumberOrRef`: the value, when not a reference, must be a number. -**`AbstractODESimulation-0008`** (error) - When the value of absoluteToleranceAdjustmentFactor of an AbstractODESimulation is a reference, it must be a reference to a number. +**`AbstractODESimulation-0008`** (error) - When the value of absoluteToleranceAdjustmentFactor of an AbstractODESimulation is a reference, it must be a reference to a number. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0008.md)) > `absoluteToleranceAdjustmentFactor` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`AbstractODESimulation-0009`** (error) - When the value of toleranceForRootFinder of an AbstractODESimulation is provided directly, it must be a number. +**`AbstractODESimulation-0009`** (error) - When the value of toleranceForRootFinder of an AbstractODESimulation is provided directly, it must be a number. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0009.md)) > `toleranceForRootFinder` is `NumberOrRef`: the value, when not a reference, must be a number. -**`AbstractODESimulation-0010`** (error) - When the value of toleranceForRootFinder of an AbstractODESimulation is a reference, it must be a reference to a number. +**`AbstractODESimulation-0010`** (error) - When the value of toleranceForRootFinder of an AbstractODESimulation is a reference, it must be a reference to a number. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0010.md)) > `toleranceForRootFinder` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`AbstractODESimulation-0011`** (error) - When the value of initialStepSize of an AbstractODESimulation is provided directly, it must be a number. +**`AbstractODESimulation-0011`** (error) - When the value of initialStepSize of an AbstractODESimulation is provided directly, it must be a number. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0011.md)) > `initialStepSize` is `NumberOrRef`: the value, when not a reference, must be a number. -**`AbstractODESimulation-0012`** (error) - When the value of initialStepSize of an AbstractODESimulation is a reference, it must be a reference to a number. +**`AbstractODESimulation-0012`** (error) - When the value of initialStepSize of an AbstractODESimulation is a reference, it must be a reference to a number. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0012.md)) > `initialStepSize` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`AbstractODESimulation-0013`** (error) - When the value of maxNumberOfSteps of an AbstractODESimulation is provided directly, it must be a number. +**`AbstractODESimulation-0013`** (error) - When the value of maxNumberOfSteps of an AbstractODESimulation is provided directly, it must be a number. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0013.md)) > `maxNumberOfSteps` is `NumberOrRef`: the value, when not a reference, must be a number. -**`AbstractODESimulation-0014`** (error) - When the value of maxNumberOfSteps of an AbstractODESimulation is a reference, it must be a reference to a number. +**`AbstractODESimulation-0014`** (error) - When the value of maxNumberOfSteps of an AbstractODESimulation is a reference, it must be a reference to a number. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0014.md)) > `maxNumberOfSteps` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`AbstractODESimulation-0015`** (error) - When the value of maxInternalSteps of an AbstractODESimulation is provided directly, it must be an integer. +**`AbstractODESimulation-0015`** (error) - When the value of maxInternalSteps of an AbstractODESimulation is provided directly, it must be an integer. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0015.md)) > `maxInternalSteps` is `IntegerOrRef`: the value, when not a reference, must be an integer. -**`AbstractODESimulation-0016`** (error) - When the value of maxInternalSteps of an AbstractODESimulation is a reference, it must be a reference to an integer. +**`AbstractODESimulation-0016`** (error) - When the value of maxInternalSteps of an AbstractODESimulation is a reference, it must be a reference to an integer. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0016.md)) > `maxInternalSteps` is `IntegerOrRef`: when the value is a reference, it must resolve to an integer. -**`AbstractODESimulation-0017`** (error) - When the value of maxInternalStepSize of an AbstractODESimulation is provided directly, it must be a number. +**`AbstractODESimulation-0017`** (error) - When the value of maxInternalStepSize of an AbstractODESimulation is provided directly, it must be a number. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0017.md)) > `maxInternalStepSize` is `NumberOrRef`: the value, when not a reference, must be a number. -**`AbstractODESimulation-0018`** (error) - When the value of maxInternalStepSize of an AbstractODESimulation is a reference, it must be a reference to a number. +**`AbstractODESimulation-0018`** (error) - When the value of maxInternalStepSize of an AbstractODESimulation is a reference, it must be a reference to a number. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0018.md)) > `maxInternalStepSize` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`AbstractODESimulation-0019`** (error) - When the value of minInternalStepSize of an AbstractODESimulation is provided directly, it must be a number. +**`AbstractODESimulation-0019`** (error) - When the value of minInternalStepSize of an AbstractODESimulation is provided directly, it must be a number. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0019.md)) > `minInternalStepSize` is `NumberOrRef`: the value, when not a reference, must be a number. -**`AbstractODESimulation-0020`** (error) - When the value of minInternalStepSize of an AbstractODESimulation is a reference, it must be a reference to a number. +**`AbstractODESimulation-0020`** (error) - When the value of minInternalStepSize of an AbstractODESimulation is a reference, it must be a reference to a number. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0020.md)) > `minInternalStepSize` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`AbstractODESimulation-0021`** (error) - When the value of forcePhysicalCorrectness of an AbstractODESimulation is provided directly, it must be a boolean. +**`AbstractODESimulation-0021`** (error) - When the value of forcePhysicalCorrectness of an AbstractODESimulation is provided directly, it must be a boolean. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0021.md)) > `forcePhysicalCorrectness` is `BooleanOrRef`: the value, when not a reference, must be a boolean. -**`AbstractODESimulation-0022`** (error) - When the value of forcePhysicalCorrectness of an AbstractODESimulation is a reference, it must be a reference to a boolean. +**`AbstractODESimulation-0022`** (error) - When the value of forcePhysicalCorrectness of an AbstractODESimulation is a reference, it must be a reference to a boolean. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0022.md)) > `forcePhysicalCorrectness` is `BooleanOrRef`: when the value is a reference, it must resolve to a boolean. -**`AbstractODESimulation-0023`** (error) - When the value of integrateReducedModel of an AbstractODESimulation is provided directly, it must be a boolean. +**`AbstractODESimulation-0023`** (error) - When the value of integrateReducedModel of an AbstractODESimulation is provided directly, it must be a boolean. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0023.md)) > `integrateReducedModel` is `BooleanOrRef`: the value, when not a reference, must be a boolean. -**`AbstractODESimulation-0024`** (error) - When the value of integrateReducedModel of an AbstractODESimulation is a reference, it must be a reference to a boolean. +**`AbstractODESimulation-0024`** (error) - When the value of integrateReducedModel of an AbstractODESimulation is a reference, it must be a reference to a boolean. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0024.md)) > `integrateReducedModel` is `BooleanOrRef`: when the value is a reference, it must resolve to a boolean. -**`AbstractODESimulation-0025`** (error) - When the value of useReducedModel of an AbstractODESimulation is provided directly, it must be a boolean. +**`AbstractODESimulation-0025`** (error) - When the value of useReducedModel of an AbstractODESimulation is provided directly, it must be a boolean. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0025.md)) > `useReducedModel` is `BooleanOrRef`: the value, when not a reference, must be a boolean. -**`AbstractODESimulation-0026`** (error) - When the value of useReducedModel of an AbstractODESimulation is a reference, it must be a reference to a boolean. +**`AbstractODESimulation-0026`** (error) - When the value of useReducedModel of an AbstractODESimulation is a reference, it must be a reference to a boolean. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0026.md)) > `useReducedModel` is `BooleanOrRef`: when the value is a reference, it must resolve to a boolean. -**`AbstractODESimulation-0027`** (error) - When the value of useStiffSolver of an AbstractODESimulation is provided directly, it must be a boolean. +**`AbstractODESimulation-0027`** (error) - When the value of useStiffSolver of an AbstractODESimulation is provided directly, it must be a boolean. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0027.md)) > `useStiffSolver` is `BooleanOrRef`: the value, when not a reference, must be a boolean. -**`AbstractODESimulation-0028`** (error) - When the value of useStiffSolver of an AbstractODESimulation is a reference, it must be a reference to a boolean. +**`AbstractODESimulation-0028`** (error) - When the value of useStiffSolver of an AbstractODESimulation is a reference, it must be a reference to a boolean. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0028.md)) > `useStiffSolver` is `BooleanOrRef`: when the value is a reference, it must resolve to a boolean. -**`AbstractODESimulation-0029`** (error) - When the value of maxBDForder of an AbstractODESimulation is provided directly, it must be a positive integer. +**`AbstractODESimulation-0029`** (error) - When the value of maxBDForder of an AbstractODESimulation is provided directly, it must be a positive integer. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0029.md)) > `maxBDForder` is `PositiveIntegerOrRef`: the value, when not a reference, must be a positive integer. -**`AbstractODESimulation-0030`** (error) - When the value of maxBDForder of an AbstractODESimulation is a reference, it must be a reference to a positive integer. +**`AbstractODESimulation-0030`** (error) - When the value of maxBDForder of an AbstractODESimulation is a reference, it must be a reference to a positive integer. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0030.md)) > `maxBDForder` is `PositiveIntegerOrRef`: when the value is a reference, it must resolve to a positive integer. -**`AbstractODESimulation-0031`** (error) - When the value of maxAdamsOrder of an AbstractODESimulation is provided directly, it must be a positive integer. +**`AbstractODESimulation-0031`** (error) - When the value of maxAdamsOrder of an AbstractODESimulation is provided directly, it must be a positive integer. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0031.md)) > `maxAdamsOrder` is `PositiveIntegerOrRef`: the value, when not a reference, must be a positive integer. -**`AbstractODESimulation-0032`** (error) - When the value of maxAdamsOrder of an AbstractODESimulation is a reference, it must be a reference to a positive integer. +**`AbstractODESimulation-0032`** (error) - When the value of maxAdamsOrder of an AbstractODESimulation is a reference, it must be a reference to a positive integer. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0032.md)) > `maxAdamsOrder` is `PositiveIntegerOrRef`: when the value is a reference, it must resolve to a positive integer. -**`AbstractODESimulation-0033`** (error) - When the value of variableStepSize of an AbstractODESimulation is provided directly, it must be a boolean. +**`AbstractODESimulation-0033`** (error) - When the value of variableStepSize of an AbstractODESimulation is provided directly, it must be a boolean. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0033.md)) > `variableStepSize` is `BooleanOrRef`: the value, when not a reference, must be a boolean. -**`AbstractODESimulation-0034`** (error) - When the value of variableStepSize of an AbstractODESimulation is a reference, it must be a reference to a boolean. +**`AbstractODESimulation-0034`** (error) - When the value of variableStepSize of an AbstractODESimulation is a reference, it must be a reference to a boolean. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0034.md)) > `variableStepSize` is `BooleanOrRef`: when the value is a reference, it must resolve to a boolean. -**`AbstractODESimulation-0035`** (error) - When the value of maxOutputRows of an AbstractODESimulation is provided directly, it must be a positive integer. +**`AbstractODESimulation-0035`** (error) - When the value of maxOutputRows of an AbstractODESimulation is provided directly, it must be a positive integer. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0035.md)) > `maxOutputRows` is `PositiveIntegerOrRef`: the value, when not a reference, must be a positive integer. -**`AbstractODESimulation-0036`** (error) - When the value of maxOutputRows of an AbstractODESimulation is a reference, it must be a reference to a positive integer. +**`AbstractODESimulation-0036`** (error) - When the value of maxOutputRows of an AbstractODESimulation is a reference, it must be a reference to a positive integer. ([source](specsheets/tasks/AbstractODESimulation/v1.0.0/validation/AbstractODESimulation-0036.md)) > `maxOutputRows` is `PositiveIntegerOrRef`: when the value is a reference, it must resolve to a positive integer. #### AbstractSimulation +*Source: [specsheets/tasks/AbstractSimulation/v1.0.0/description.md](specsheets/tasks/AbstractSimulation/v1.0.0/description.md)* + ![AbstractSimulation UML diagram](specsheets/tasks/AbstractSimulation/v1.0.0/AbstractSimulation.png) **Category:** tasks @@ -1029,7 +1076,7 @@ There is no output rule for `AbstractODESimulation` itself - see `ExplicitODESim ##### What it does -`AbstractSimulation` is a schema-only mixin (composed via `allOf`, not instantiated directly, no `_type` or diagram box of its own beyond the one shown here) contributing the fields shared by every ODE or stochastic simulation task, by way of `AbstractODESimulation` and `AbstractStochasticSimulation`. It replaces the earlier `SimulationCommon`, and (unlike `SimulationCommon`) is no longer used by `SteadyState` or `FluxBalanceAnalysis`, which now declare their own fields directly. +`AbstractSimulation` is a schema-only mixin (composed via `allOf`, not instantiated directly, no `_type` or diagram box of its own beyond the one shown here) contributing the fields shared by every ODE or stochastic simulation task, by way of `AbstractODESimulation` and `AbstractStochasticSimulation`. It replaces the earlier `SimulationCommon`, and (unlike `SimulationCommon`) is no longer used by `SteadyState` or `FluxBalanceAnalysis`, which now declare their own fields directly (including their own `workingAlgorithms` lists). Beyond the fields it inherits from `AbstractTask`, it contributes `model`, `independentVariable`, `independentVariableInit`, `outputVariables`, and `workingAlgorithms` - a list of `WorkingAlgorithm` entries describing the algorithm(s) used internally by the simulation. @@ -1066,46 +1113,48 @@ There is no single output rule for `AbstractSimulation` itself - see each concre ##### Validation Rules -**`AbstractSimulation-0000`** (error) - The element fails a JSON Schema constraint attributable to AbstractSimulation that does not match any other numbered rule. +**`AbstractSimulation-0000`** (error) - The element fails a JSON Schema constraint attributable to AbstractSimulation that does not match any other numbered rule. ([source](specsheets/tasks/AbstractSimulation/v1.0.0/validation/AbstractSimulation-0000.md)) > Catch-all rule for schema-pass failures attributable to AbstractSimulation (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`AbstractSimulation-0001`** (error) - The model attribute of an AbstractSimulation, if present, must be a reference (a string starting with '#'). +**`AbstractSimulation-0001`** (error) - The model attribute of an AbstractSimulation, if present, must be a reference (a string starting with '#'). ([source](specsheets/tasks/AbstractSimulation/v1.0.0/validation/AbstractSimulation-0001.md)) > `model` is defined as `SIdRef` in AbstractSimulation - always a reference, never a literal value. -**`AbstractSimulation-0002`** (error) - When the value of independentVariable of an AbstractSimulation is provided directly, it must be a string. +**`AbstractSimulation-0002`** (error) - When the value of independentVariable of an AbstractSimulation is provided directly, it must be a string. ([source](specsheets/tasks/AbstractSimulation/v1.0.0/validation/AbstractSimulation-0002.md)) > `independentVariable` is `StringOrRef` in AbstractSimulation: the value, when not a reference, must be a string. -**`AbstractSimulation-0003`** (error) - When the value of independentVariable of an AbstractSimulation is a reference, it must be a reference to a string. +**`AbstractSimulation-0003`** (error) - When the value of independentVariable of an AbstractSimulation is a reference, it must be a reference to a string. ([source](specsheets/tasks/AbstractSimulation/v1.0.0/validation/AbstractSimulation-0003.md)) > `independentVariable` is `StringOrRef` in AbstractSimulation: when the value is a reference, it must resolve to a string. -**`AbstractSimulation-0004`** (error) - When the value of independentVariableInit of an AbstractSimulation is provided directly, it must be a number. +**`AbstractSimulation-0004`** (error) - When the value of independentVariableInit of an AbstractSimulation is provided directly, it must be a number. ([source](specsheets/tasks/AbstractSimulation/v1.0.0/validation/AbstractSimulation-0004.md)) > `independentVariableInit` is `NumberOrRef` in AbstractSimulation: the value, when not a reference, must be a number. -**`AbstractSimulation-0005`** (error) - When the value of independentVariableInit of an AbstractSimulation is a reference, it must be a reference to a number. +**`AbstractSimulation-0005`** (error) - When the value of independentVariableInit of an AbstractSimulation is a reference, it must be a reference to a number. ([source](specsheets/tasks/AbstractSimulation/v1.0.0/validation/AbstractSimulation-0005.md)) > `independentVariableInit` is `NumberOrRef` in AbstractSimulation: when the value is a reference, it must resolve to a number. -**`AbstractSimulation-0006`** (error) - When the value of outputVariables of an AbstractSimulation is provided directly, it must be an array of strings. +**`AbstractSimulation-0006`** (error) - When the value of outputVariables of an AbstractSimulation is provided directly, it must be an array of strings. ([source](specsheets/tasks/AbstractSimulation/v1.0.0/validation/AbstractSimulation-0006.md)) > `outputVariables` is `ListOfStringsOrRef` in AbstractSimulation: the value, when not a reference, must be an array of strings. -**`AbstractSimulation-0007`** (error) - When the value of outputVariables of an AbstractSimulation is a reference, it must be a reference to an array of strings. +**`AbstractSimulation-0007`** (error) - When the value of outputVariables of an AbstractSimulation is a reference, it must be a reference to an array of strings. ([source](specsheets/tasks/AbstractSimulation/v1.0.0/validation/AbstractSimulation-0007.md)) > `outputVariables` is `ListOfStringsOrRef` in AbstractSimulation: when the value is a reference, it must resolve to an array of strings. -**`AbstractSimulation-0008`** (error) - The workingAlgorithms attribute of an AbstractSimulation, if present, must be an array of WorkingAlgorithm objects. +**`AbstractSimulation-0008`** (error) - The workingAlgorithms attribute of an AbstractSimulation, if present, must be an array of WorkingAlgorithm objects. ([source](specsheets/tasks/AbstractSimulation/v1.0.0/validation/AbstractSimulation-0008.md)) > `workingAlgorithms` is optional; when present, each entry must be a `WorkingAlgorithm` object. #### AbstractStochasticSimulation +*Source: [specsheets/tasks/AbstractStochasticSimulation/v1.0.0/description.md](specsheets/tasks/AbstractStochasticSimulation/v1.0.0/description.md)* + ![AbstractStochasticSimulation UML diagram](specsheets/tasks/AbstractStochasticSimulation/v1.0.0/AbstractStochasticSimulation.png) **Category:** tasks @@ -1156,78 +1205,80 @@ There is no output rule for `AbstractStochasticSimulation` itself - see `Explici ##### Validation Rules -**`AbstractStochasticSimulation-0000`** (error) - The element fails a JSON Schema constraint attributable to AbstractStochasticSimulation that does not match any other numbered rule. +**`AbstractStochasticSimulation-0000`** (error) - The element fails a JSON Schema constraint attributable to AbstractStochasticSimulation that does not match any other numbered rule. ([source](specsheets/tasks/AbstractStochasticSimulation/v1.0.0/validation/AbstractStochasticSimulation-0000.md)) > Catch-all rule for schema-pass failures attributable to AbstractStochasticSimulation (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`AbstractStochasticSimulation-0001`** (error) - When the value of seed of an AbstractStochasticSimulation is provided directly, it must be a number. +**`AbstractStochasticSimulation-0001`** (error) - When the value of seed of an AbstractStochasticSimulation is provided directly, it must be a number. ([source](specsheets/tasks/AbstractStochasticSimulation/v1.0.0/validation/AbstractStochasticSimulation-0001.md)) > `seed` is `NumberOrRef`: the value, when not a reference, must be a number. -**`AbstractStochasticSimulation-0002`** (error) - When the value of seed of an AbstractStochasticSimulation is a reference, it must be a reference to a number. +**`AbstractStochasticSimulation-0002`** (error) - When the value of seed of an AbstractStochasticSimulation is a reference, it must be a reference to a number. ([source](specsheets/tasks/AbstractStochasticSimulation/v1.0.0/validation/AbstractStochasticSimulation-0002.md)) > `seed` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`AbstractStochasticSimulation-0003`** (error) - When the value of timeDependentRelativeTolerance of an AbstractStochasticSimulation is provided directly, it must be a number. +**`AbstractStochasticSimulation-0003`** (error) - When the value of timeDependentRelativeTolerance of an AbstractStochasticSimulation is provided directly, it must be a number. ([source](specsheets/tasks/AbstractStochasticSimulation/v1.0.0/validation/AbstractStochasticSimulation-0003.md)) > `timeDependentRelativeTolerance` is `NumberOrRef`: the value, when not a reference, must be a number. -**`AbstractStochasticSimulation-0004`** (error) - When the value of timeDependentRelativeTolerance of an AbstractStochasticSimulation is a reference, it must be a reference to a number. +**`AbstractStochasticSimulation-0004`** (error) - When the value of timeDependentRelativeTolerance of an AbstractStochasticSimulation is a reference, it must be a reference to a number. ([source](specsheets/tasks/AbstractStochasticSimulation/v1.0.0/validation/AbstractStochasticSimulation-0004.md)) > `timeDependentRelativeTolerance` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`AbstractStochasticSimulation-0005`** (error) - When the value of variableStepSize of an AbstractStochasticSimulation is provided directly, it must be a boolean. +**`AbstractStochasticSimulation-0005`** (error) - When the value of variableStepSize of an AbstractStochasticSimulation is provided directly, it must be a boolean. ([source](specsheets/tasks/AbstractStochasticSimulation/v1.0.0/validation/AbstractStochasticSimulation-0005.md)) > `variableStepSize` is `BooleanOrRef`: the value, when not a reference, must be a boolean. -**`AbstractStochasticSimulation-0006`** (error) - When the value of variableStepSize of an AbstractStochasticSimulation is a reference, it must be a reference to a boolean. +**`AbstractStochasticSimulation-0006`** (error) - When the value of variableStepSize of an AbstractStochasticSimulation is a reference, it must be a reference to a boolean. ([source](specsheets/tasks/AbstractStochasticSimulation/v1.0.0/validation/AbstractStochasticSimulation-0006.md)) > `variableStepSize` is `BooleanOrRef`: when the value is a reference, it must resolve to a boolean. -**`AbstractStochasticSimulation-0007`** (error) - When the value of minimumTimeStep of an AbstractStochasticSimulation is provided directly, it must be a number. +**`AbstractStochasticSimulation-0007`** (error) - When the value of minimumTimeStep of an AbstractStochasticSimulation is provided directly, it must be a number. ([source](specsheets/tasks/AbstractStochasticSimulation/v1.0.0/validation/AbstractStochasticSimulation-0007.md)) > `minimumTimeStep` is `NumberOrRef`: the value, when not a reference, must be a number. -**`AbstractStochasticSimulation-0008`** (error) - When the value of minimumTimeStep of an AbstractStochasticSimulation is a reference, it must be a reference to a number. +**`AbstractStochasticSimulation-0008`** (error) - When the value of minimumTimeStep of an AbstractStochasticSimulation is a reference, it must be a reference to a number. ([source](specsheets/tasks/AbstractStochasticSimulation/v1.0.0/validation/AbstractStochasticSimulation-0008.md)) > `minimumTimeStep` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`AbstractStochasticSimulation-0009`** (error) - When the value of maximumTimeStep of an AbstractStochasticSimulation is provided directly, it must be a number. +**`AbstractStochasticSimulation-0009`** (error) - When the value of maximumTimeStep of an AbstractStochasticSimulation is provided directly, it must be a number. ([source](specsheets/tasks/AbstractStochasticSimulation/v1.0.0/validation/AbstractStochasticSimulation-0009.md)) > `maximumTimeStep` is `NumberOrRef`: the value, when not a reference, must be a number. -**`AbstractStochasticSimulation-0010`** (error) - When the value of maximumTimeStep of an AbstractStochasticSimulation is a reference, it must be a reference to a number. +**`AbstractStochasticSimulation-0010`** (error) - When the value of maximumTimeStep of an AbstractStochasticSimulation is a reference, it must be a reference to a number. ([source](specsheets/tasks/AbstractStochasticSimulation/v1.0.0/validation/AbstractStochasticSimulation-0010.md)) > `maximumTimeStep` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`AbstractStochasticSimulation-0011`** (error) - When the value of nonNegative of an AbstractStochasticSimulation is provided directly, it must be a boolean. +**`AbstractStochasticSimulation-0011`** (error) - When the value of nonNegative of an AbstractStochasticSimulation is provided directly, it must be a boolean. ([source](specsheets/tasks/AbstractStochasticSimulation/v1.0.0/validation/AbstractStochasticSimulation-0011.md)) > `nonNegative` is `BooleanOrRef`: the value, when not a reference, must be a boolean. -**`AbstractStochasticSimulation-0012`** (error) - When the value of nonNegative of an AbstractStochasticSimulation is a reference, it must be a reference to a boolean. +**`AbstractStochasticSimulation-0012`** (error) - When the value of nonNegative of an AbstractStochasticSimulation is a reference, it must be a reference to a boolean. ([source](specsheets/tasks/AbstractStochasticSimulation/v1.0.0/validation/AbstractStochasticSimulation-0012.md)) > `nonNegative` is `BooleanOrRef`: when the value is a reference, it must resolve to a boolean. -**`AbstractStochasticSimulation-0013`** (error) - When the value of maxOutputRows of an AbstractStochasticSimulation is provided directly, it must be a positive integer. +**`AbstractStochasticSimulation-0013`** (error) - When the value of maxOutputRows of an AbstractStochasticSimulation is provided directly, it must be a positive integer. ([source](specsheets/tasks/AbstractStochasticSimulation/v1.0.0/validation/AbstractStochasticSimulation-0013.md)) > `maxOutputRows` is `PositiveIntegerOrRef`: the value, when not a reference, must be a positive integer. -**`AbstractStochasticSimulation-0014`** (error) - When the value of maxOutputRows of an AbstractStochasticSimulation is a reference, it must be a reference to a positive integer. +**`AbstractStochasticSimulation-0014`** (error) - When the value of maxOutputRows of an AbstractStochasticSimulation is a reference, it must be a reference to a positive integer. ([source](specsheets/tasks/AbstractStochasticSimulation/v1.0.0/validation/AbstractStochasticSimulation-0014.md)) > `maxOutputRows` is `PositiveIntegerOrRef`: when the value is a reference, it must resolve to a positive integer. -**`AbstractStochasticSimulation-0015`** (error) - When the value of maxNumSteps of an AbstractStochasticSimulation is provided directly, it must be a positive integer. +**`AbstractStochasticSimulation-0015`** (error) - When the value of maxNumSteps of an AbstractStochasticSimulation is provided directly, it must be a positive integer. ([source](specsheets/tasks/AbstractStochasticSimulation/v1.0.0/validation/AbstractStochasticSimulation-0015.md)) > `maxNumSteps` is `PositiveIntegerOrRef`: the value, when not a reference, must be a positive integer. -**`AbstractStochasticSimulation-0016`** (error) - When the value of maxNumSteps of an AbstractStochasticSimulation is a reference, it must be a reference to a positive integer. +**`AbstractStochasticSimulation-0016`** (error) - When the value of maxNumSteps of an AbstractStochasticSimulation is a reference, it must be a reference to a positive integer. ([source](specsheets/tasks/AbstractStochasticSimulation/v1.0.0/validation/AbstractStochasticSimulation-0016.md)) > `maxNumSteps` is `PositiveIntegerOrRef`: when the value is a reference, it must resolve to a positive integer. #### AbstractTask +*Source: [specsheets/tasks/AbstractTask/v1.0.0/description.md](specsheets/tasks/AbstractTask/v1.0.0/description.md)* + ![AbstractTask UML diagram](specsheets/tasks/AbstractTask/v1.0.0/AbstractTask.png) **Category:** tasks @@ -1256,17 +1307,17 @@ There is no single output rule for `AbstractTask` itself - see each concrete sub ##### Validation Rules -**`AbstractTask-0000`** (error) - The element fails a JSON Schema constraint attributable to AbstractTask that does not match any other numbered rule. +**`AbstractTask-0000`** (error) - The element fails a JSON Schema constraint attributable to AbstractTask that does not match any other numbered rule. ([source](specsheets/tasks/AbstractTask/v1.0.0/validation/AbstractTask-0000.md)) > Catch-all rule for schema-pass failures attributable to AbstractTask (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`AbstractTask-0001`** (error) - The taskParameters attribute of an AbstractTask must be an array of TaskParameter objects. +**`AbstractTask-0001`** (error) - The taskParameters attribute of an AbstractTask must be an array of TaskParameter objects. ([source](specsheets/tasks/AbstractTask/v1.0.0/validation/AbstractTask-0001.md)) > `taskParameters` is `array of TaskParameter` in AbstractTaskCommon: it must be an array of TaskParameter objects. -**`AbstractTask-0002`** (error) - A value that must resolve to a concrete AbstractTask subtype must declare a _type attribute. +**`AbstractTask-0002`** (error) - A value that must resolve to a concrete AbstractTask subtype must declare a _type attribute. ([source](specsheets/tasks/AbstractTask/v1.0.0/validation/AbstractTask-0002.md)) > A narrower case of AbstractTask-0000's catch-all: fires specifically when > the generated oneOf fails because _type is missing entirely, rather than @@ -1274,7 +1325,7 @@ There is no single output rule for `AbstractTask` itself - see each concrete sub > a sibling of x-generated-oneOf; see core-spec.md Section 8 and Design.md's > Classes section. -**`AbstractTask-0003`** (error) - A task may only reference constants, tasks that appear earlier in the same tasks dictionary, or (for a subTask) the elements listed in this rule's explanation. +**`AbstractTask-0003`** (error) - A task may only reference constants, tasks that appear earlier in the same tasks dictionary, or (for a subTask) the elements listed in this rule's explanation. ([source](specsheets/tasks/AbstractTask/v1.0.0/validation/AbstractTask-0003.md)) > The chronological rule (core-spec.md Section 3), made checkable. For a task > at the top level of SEDDocument.tasks, a reference may target: @@ -1292,6 +1343,8 @@ There is no single output rule for `AbstractTask` itself - see each concrete sub #### AggregationCalculation +*Source: [specsheets/tasks/AggregationCalculation/v1.0.0/description.md](specsheets/tasks/AggregationCalculation/v1.0.0/description.md)* + ![AggregationCalculation UML diagram](specsheets/tasks/AggregationCalculation/v1.0.0/AggregationCalculation.png) **Category:** tasks @@ -1342,30 +1395,32 @@ The aggregated value, accessible as `[id]`. ##### Validation Rules -**`AggregationCalculation-0000`** (error) - The element fails a JSON Schema constraint attributable to AggregationCalculation that does not match any other numbered rule. +**`AggregationCalculation-0000`** (error) - The element fails a JSON Schema constraint attributable to AggregationCalculation that does not match any other numbered rule. ([source](specsheets/tasks/AggregationCalculation/v1.0.0/validation/AggregationCalculation-0000.md)) > Catch-all rule for schema-pass failures attributable to AggregationCalculation (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`AggregationCalculation-0001`** (error) - The input attribute of an AggregationCalculation is required. +**`AggregationCalculation-0001`** (error) - The input attribute of an AggregationCalculation is required. ([source](specsheets/tasks/AggregationCalculation/v1.0.0/validation/AggregationCalculation-0001.md)) > `input` is required. -**`AggregationCalculation-0002`** (error) - When the value of appliedDimensions of an AggregationCalculation is provided directly, it must be an array of strings. +**`AggregationCalculation-0002`** (error) - When the value of appliedDimensions of an AggregationCalculation is provided directly, it must be an array of strings. ([source](specsheets/tasks/AggregationCalculation/v1.0.0/validation/AggregationCalculation-0002.md)) > `appliedDimensions` is `ListOfStringsOrRef`: the value, when not a reference, must be an array of strings. -**`AggregationCalculation-0003`** (error) - When the value of appliedDimensions of an AggregationCalculation is a reference, it must be a reference to an array of strings. +**`AggregationCalculation-0003`** (error) - When the value of appliedDimensions of an AggregationCalculation is a reference, it must be a reference to an array of strings. ([source](specsheets/tasks/AggregationCalculation/v1.0.0/validation/AggregationCalculation-0003.md)) > `appliedDimensions` is `ListOfStringsOrRef`: when the value is a reference, it must resolve to an array of strings. -**`AggregationCalculation-0004`** (error) - The _type attribute of an AggregationCalculation must be "aggregationCalculation". +**`AggregationCalculation-0004`** (error) - The _type attribute of an AggregationCalculation must be "aggregationCalculation". ([source](specsheets/tasks/AggregationCalculation/v1.0.0/validation/AggregationCalculation-0004.md)) > `_type` is the discriminator field. For `AggregationCalculation` it must always equal `"aggregationCalculation"`. #### BoundedODESimulation +*Source: [specsheets/tasks/BoundedODESimulation/v1.0.0/description.md](specsheets/tasks/BoundedODESimulation/v1.0.0/description.md)* + ![BoundedODESimulation UML diagram](specsheets/tasks/BoundedODESimulation/v1.0.0/BoundedODESimulation.png) **Category:** tasks @@ -1477,38 +1532,40 @@ A 2D matrix of numbers, accessible as `[id]`, with the same column layout as `Ex ##### Validation Rules -**`BoundedODESimulation-0000`** (error) - The element fails a JSON Schema constraint attributable to BoundedODESimulation that does not match any other numbered rule. +**`BoundedODESimulation-0000`** (error) - The element fails a JSON Schema constraint attributable to BoundedODESimulation that does not match any other numbered rule. ([source](specsheets/tasks/BoundedODESimulation/v1.0.0/validation/BoundedODESimulation-0000.md)) > Catch-all rule for schema-pass failures attributable to BoundedODESimulation (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`BoundedODESimulation-0001`** (error) - The model attribute of a BoundedODESimulation is required. +**`BoundedODESimulation-0001`** (error) - The model attribute of a BoundedODESimulation is required. ([source](specsheets/tasks/BoundedODESimulation/v1.0.0/validation/BoundedODESimulation-0001.md)) > `model` is required. -**`BoundedODESimulation-0002`** (error) - The independentVariable attribute of a BoundedODESimulation is required. +**`BoundedODESimulation-0002`** (error) - The independentVariable attribute of a BoundedODESimulation is required. ([source](specsheets/tasks/BoundedODESimulation/v1.0.0/validation/BoundedODESimulation-0002.md)) > `independentVariable` is required. -**`BoundedODESimulation-0003`** (error) - The outputVariables attribute of a BoundedODESimulation is required. +**`BoundedODESimulation-0003`** (error) - The outputVariables attribute of a BoundedODESimulation is required. ([source](specsheets/tasks/BoundedODESimulation/v1.0.0/validation/BoundedODESimulation-0003.md)) > `outputVariables` is required. -**`BoundedODESimulation-0004`** (error) - The independentVariableSpan attribute of a BoundedODESimulation is required. +**`BoundedODESimulation-0004`** (error) - The independentVariableSpan attribute of a BoundedODESimulation is required. ([source](specsheets/tasks/BoundedODESimulation/v1.0.0/validation/BoundedODESimulation-0004.md)) > `independentVariableSpan` is required. -**`BoundedODESimulation-0005`** (error) - The independentVariableSpan attribute of a BoundedODESimulation must be a SpanInline object. +**`BoundedODESimulation-0005`** (error) - The independentVariableSpan attribute of a BoundedODESimulation must be a SpanInline object. ([source](specsheets/tasks/BoundedODESimulation/v1.0.0/validation/BoundedODESimulation-0005.md)) > `independentVariableSpan` is `SpanInline`: it must be a SpanInline object. -**`BoundedODESimulation-0006`** (error) - The _type attribute of a BoundedODESimulation must be "boundedODESimulation". +**`BoundedODESimulation-0006`** (error) - The _type attribute of a BoundedODESimulation must be "boundedODESimulation". ([source](specsheets/tasks/BoundedODESimulation/v1.0.0/validation/BoundedODESimulation-0006.md)) > `_type` is the discriminator field. For `BoundedODESimulation` it must always equal `"boundedODESimulation"`. #### BoundedStochasticSimulation +*Source: [specsheets/tasks/BoundedStochasticSimulation/v1.0.0/description.md](specsheets/tasks/BoundedStochasticSimulation/v1.0.0/description.md)* + ![BoundedStochasticSimulation UML diagram](specsheets/tasks/BoundedStochasticSimulation/v1.0.0/BoundedStochasticSimulation.png) **Category:** tasks @@ -1588,38 +1645,40 @@ A 2D matrix of numbers, accessible as `[id]`, with solver-chosen row spacing. Th ##### Validation Rules -**`BoundedStochasticSimulation-0000`** (error) - The element fails a JSON Schema constraint attributable to BoundedStochasticSimulation that does not match any other numbered rule. +**`BoundedStochasticSimulation-0000`** (error) - The element fails a JSON Schema constraint attributable to BoundedStochasticSimulation that does not match any other numbered rule. ([source](specsheets/tasks/BoundedStochasticSimulation/v1.0.0/validation/BoundedStochasticSimulation-0000.md)) > Catch-all rule for schema-pass failures attributable to BoundedStochasticSimulation (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`BoundedStochasticSimulation-0001`** (error) - The model attribute of a BoundedStochasticSimulation is required. +**`BoundedStochasticSimulation-0001`** (error) - The model attribute of a BoundedStochasticSimulation is required. ([source](specsheets/tasks/BoundedStochasticSimulation/v1.0.0/validation/BoundedStochasticSimulation-0001.md)) > `model` is required. -**`BoundedStochasticSimulation-0002`** (error) - The independentVariable attribute of a BoundedStochasticSimulation is required. +**`BoundedStochasticSimulation-0002`** (error) - The independentVariable attribute of a BoundedStochasticSimulation is required. ([source](specsheets/tasks/BoundedStochasticSimulation/v1.0.0/validation/BoundedStochasticSimulation-0002.md)) > `independentVariable` is required. -**`BoundedStochasticSimulation-0003`** (error) - The outputVariables attribute of a BoundedStochasticSimulation is required. +**`BoundedStochasticSimulation-0003`** (error) - The outputVariables attribute of a BoundedStochasticSimulation is required. ([source](specsheets/tasks/BoundedStochasticSimulation/v1.0.0/validation/BoundedStochasticSimulation-0003.md)) > `outputVariables` is required. -**`BoundedStochasticSimulation-0004`** (error) - The independentVariableSpan attribute of a BoundedStochasticSimulation is required. +**`BoundedStochasticSimulation-0004`** (error) - The independentVariableSpan attribute of a BoundedStochasticSimulation is required. ([source](specsheets/tasks/BoundedStochasticSimulation/v1.0.0/validation/BoundedStochasticSimulation-0004.md)) > `independentVariableSpan` is required. -**`BoundedStochasticSimulation-0005`** (error) - The independentVariableSpan attribute of a BoundedStochasticSimulation must be a SpanInline object. +**`BoundedStochasticSimulation-0005`** (error) - The independentVariableSpan attribute of a BoundedStochasticSimulation must be a SpanInline object. ([source](specsheets/tasks/BoundedStochasticSimulation/v1.0.0/validation/BoundedStochasticSimulation-0005.md)) > `independentVariableSpan` is `SpanInline`: it must be a SpanInline object. -**`BoundedStochasticSimulation-0006`** (error) - The _type attribute of a BoundedStochasticSimulation must be "boundedStochasticSimulation". +**`BoundedStochasticSimulation-0006`** (error) - The _type attribute of a BoundedStochasticSimulation must be "boundedStochasticSimulation". ([source](specsheets/tasks/BoundedStochasticSimulation/v1.0.0/validation/BoundedStochasticSimulation-0006.md)) > `_type` is the discriminator field. For `BoundedStochasticSimulation` it must always equal `"boundedStochasticSimulation"`. #### Calculation +*Source: [specsheets/tasks/Calculation/v1.0.0/description.md](specsheets/tasks/Calculation/v1.0.0/description.md)* + ![Calculation UML diagram](specsheets/tasks/Calculation/v1.0.0/Calculation.png) **Category:** tasks @@ -1660,30 +1719,32 @@ The result of evaluating `math`, accessible as `[id]`. ##### Validation Rules -**`Calculation-0000`** (error) - The element fails a JSON Schema constraint attributable to Calculation that does not match any other numbered rule. +**`Calculation-0000`** (error) - The element fails a JSON Schema constraint attributable to Calculation that does not match any other numbered rule. ([source](specsheets/tasks/Calculation/v1.0.0/validation/Calculation-0000.md)) > Catch-all rule for schema-pass failures attributable to Calculation (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`Calculation-0001`** (error) - The math attribute of a Calculation is required. +**`Calculation-0001`** (error) - The math attribute of a Calculation is required. ([source](specsheets/tasks/Calculation/v1.0.0/validation/Calculation-0001.md)) > `math` is required. -**`Calculation-0002`** (error) - When the value of math of a Calculation is provided directly, it must be a string. +**`Calculation-0002`** (error) - When the value of math of a Calculation is provided directly, it must be a string. ([source](specsheets/tasks/Calculation/v1.0.0/validation/Calculation-0002.md)) > `math` is `StringOrRef`: the value, when not a reference, must be a string. -**`Calculation-0003`** (error) - When the value of math of a Calculation is a reference, it must be a reference to a string. +**`Calculation-0003`** (error) - When the value of math of a Calculation is a reference, it must be a reference to a string. ([source](specsheets/tasks/Calculation/v1.0.0/validation/Calculation-0003.md)) > `math` is `StringOrRef`: when the value is a reference, it must resolve to a string. -**`Calculation-0004`** (error) - The _type attribute of a Calculation must be "calculation". +**`Calculation-0004`** (error) - The _type attribute of a Calculation must be "calculation". ([source](specsheets/tasks/Calculation/v1.0.0/validation/Calculation-0004.md)) > `_type` is the discriminator field. For `Calculation` it must always equal `"calculation"`. #### CreateDataBlock +*Source: [specsheets/tasks/CreateDataBlock/v1.0.0/description.md](specsheets/tasks/CreateDataBlock/v1.0.0/description.md)* + ![CreateDataBlock UML diagram](specsheets/tasks/CreateDataBlock/v1.0.0/CreateDataBlock.png) **Category:** tasks @@ -1722,30 +1783,32 @@ A new `AnnotatedData` object whose labels are the `data` dictionary's keys and w ##### Validation Rules -**`CreateDataBlock-0000`** (error) - The element fails a JSON Schema constraint attributable to CreateDataBlock that does not match any other numbered rule. +**`CreateDataBlock-0000`** (error) - The element fails a JSON Schema constraint attributable to CreateDataBlock that does not match any other numbered rule. ([source](specsheets/tasks/CreateDataBlock/v1.0.0/validation/CreateDataBlock-0000.md)) > Catch-all rule for schema-pass failures attributable to CreateDataBlock (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`CreateDataBlock-0001`** (error) - The data attribute of a CreateDataBlock is required. +**`CreateDataBlock-0001`** (error) - The data attribute of a CreateDataBlock is required. ([source](specsheets/tasks/CreateDataBlock/v1.0.0/validation/CreateDataBlock-0001.md)) > `data` is required. -**`CreateDataBlock-0002`** (error) - When the value of data of a CreateDataBlock is provided directly, it must be an object whose values are AnyValueOrRef. +**`CreateDataBlock-0002`** (error) - When the value of data of a CreateDataBlock is provided directly, it must be an object whose values are AnyValueOrRef. ([source](specsheets/tasks/CreateDataBlock/v1.0.0/validation/CreateDataBlock-0002.md)) > `data` is `object (values: AnyValueOrRef) or SIdRef`: the value, when not a reference, must be an object whose values are AnyValueOrRef. -**`CreateDataBlock-0003`** (error) - When the value of data of a CreateDataBlock is a reference, it must be a reference to an object whose values are AnyValueOrRef. +**`CreateDataBlock-0003`** (error) - When the value of data of a CreateDataBlock is a reference, it must be a reference to an object whose values are AnyValueOrRef. ([source](specsheets/tasks/CreateDataBlock/v1.0.0/validation/CreateDataBlock-0003.md)) > `data` is `object (values: AnyValueOrRef) or SIdRef`: when the value is a reference, it must resolve to an object whose values are AnyValueOrRef. -**`CreateDataBlock-0004`** (error) - The _type attribute of a CreateDataBlock must be "createDataBlock". +**`CreateDataBlock-0004`** (error) - The _type attribute of a CreateDataBlock must be "createDataBlock". ([source](specsheets/tasks/CreateDataBlock/v1.0.0/validation/CreateDataBlock-0004.md)) > `_type` is the discriminator field. For `CreateDataBlock` it must always equal `"createDataBlock"`. #### CsvImport +*Source: [specsheets/tasks/CsvImport/v1.0.0/description.md](specsheets/tasks/CsvImport/v1.0.0/description.md)* + ![CsvImport UML diagram](specsheets/tasks/CsvImport/v1.0.0/CsvImport.png) **Category:** tasks @@ -1809,86 +1872,88 @@ The imported numeric `AnnotatedData`, accessible as `[id]`. ##### Validation Rules -**`CsvImport-0000`** (error) - The element fails a JSON Schema constraint attributable to CsvImport that does not match any other numbered rule. +**`CsvImport-0000`** (error) - The element fails a JSON Schema constraint attributable to CsvImport that does not match any other numbered rule. ([source](specsheets/tasks/CsvImport/v1.0.0/validation/CsvImport-0000.md)) > Catch-all rule for schema-pass failures attributable to CsvImport (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`CsvImport-0001`** (error) - The location attribute of a CsvImport is required. +**`CsvImport-0001`** (error) - The location attribute of a CsvImport is required. ([source](specsheets/tasks/CsvImport/v1.0.0/validation/CsvImport-0001.md)) > `location` is required. -**`CsvImport-0002`** (error) - When the value of location of a CsvImport is provided directly, it must be a URI string. +**`CsvImport-0002`** (error) - When the value of location of a CsvImport is provided directly, it must be a URI string. ([source](specsheets/tasks/CsvImport/v1.0.0/validation/CsvImport-0002.md)) > `location` is `URIOrRef`: the value, when not a reference, must be a URI string. -**`CsvImport-0003`** (error) - When the value of location of a CsvImport is a reference, it must be a reference to a URI string. +**`CsvImport-0003`** (error) - When the value of location of a CsvImport is a reference, it must be a reference to a URI string. ([source](specsheets/tasks/CsvImport/v1.0.0/validation/CsvImport-0003.md)) > `location` is `URIOrRef`: when the value is a reference, it must resolve to a URI string. -**`CsvImport-0004`** (error) - When the value of organization of a CsvImport is provided directly, it must be a string. +**`CsvImport-0004`** (error) - When the value of organization of a CsvImport is provided directly, it must be a string. ([source](specsheets/tasks/CsvImport/v1.0.0/validation/CsvImport-0004.md)) > `organization` is `StringOrRef`: the value, when not a reference, must be a string. -**`CsvImport-0005`** (error) - When the value of organization of a CsvImport is a reference, it must be a reference to a string. +**`CsvImport-0005`** (error) - When the value of organization of a CsvImport is a reference, it must be a reference to a string. ([source](specsheets/tasks/CsvImport/v1.0.0/validation/CsvImport-0005.md)) > `organization` is `StringOrRef`: when the value is a reference, it must resolve to a string. -**`CsvImport-0006`** (error) - When the value of separator of a CsvImport is provided directly, it must be a string. +**`CsvImport-0006`** (error) - When the value of separator of a CsvImport is provided directly, it must be a string. ([source](specsheets/tasks/CsvImport/v1.0.0/validation/CsvImport-0006.md)) > `separator` is `StringOrRef`: the value, when not a reference, must be a string. -**`CsvImport-0007`** (error) - When the value of separator of a CsvImport is a reference, it must be a reference to a string. +**`CsvImport-0007`** (error) - When the value of separator of a CsvImport is a reference, it must be a reference to a string. ([source](specsheets/tasks/CsvImport/v1.0.0/validation/CsvImport-0007.md)) > `separator` is `StringOrRef`: when the value is a reference, it must resolve to a string. -**`CsvImport-0008`** (error) - When the value of headers of a CsvImport is provided directly, it must be a boolean. +**`CsvImport-0008`** (error) - When the value of headers of a CsvImport is provided directly, it must be a boolean. ([source](specsheets/tasks/CsvImport/v1.0.0/validation/CsvImport-0008.md)) > `headers` is `BooleanOrRef`: the value, when not a reference, must be a boolean. -**`CsvImport-0009`** (error) - When the value of headers of a CsvImport is a reference, it must be a reference to a boolean. +**`CsvImport-0009`** (error) - When the value of headers of a CsvImport is a reference, it must be a reference to a boolean. ([source](specsheets/tasks/CsvImport/v1.0.0/validation/CsvImport-0009.md)) > `headers` is `BooleanOrRef`: when the value is a reference, it must resolve to a boolean. -**`CsvImport-0010`** (error) - When the value of columnNames of a CsvImport is provided directly, it must be an array of strings. +**`CsvImport-0010`** (error) - When the value of columnNames of a CsvImport is provided directly, it must be an array of strings. ([source](specsheets/tasks/CsvImport/v1.0.0/validation/CsvImport-0010.md)) > `columnNames` is `ListOfStringsOrRef`: the value, when not a reference, must be an array of strings. -**`CsvImport-0011`** (error) - When the value of columnNames of a CsvImport is a reference, it must be a reference to an array of strings. +**`CsvImport-0011`** (error) - When the value of columnNames of a CsvImport is a reference, it must be a reference to an array of strings. ([source](specsheets/tasks/CsvImport/v1.0.0/validation/CsvImport-0011.md)) > `columnNames` is `ListOfStringsOrRef`: when the value is a reference, it must resolve to an array of strings. -**`CsvImport-0012`** (error) - When the value of ncols of a CsvImport is provided directly, it must be a positive integer. +**`CsvImport-0012`** (error) - When the value of ncols of a CsvImport is provided directly, it must be a positive integer. ([source](specsheets/tasks/CsvImport/v1.0.0/validation/CsvImport-0012.md)) > `ncols` is `PositiveIntegerOrRef`: the value, when not a reference, must be a positive integer. -**`CsvImport-0013`** (error) - When the value of ncols of a CsvImport is a reference, it must be a reference to a positive integer. +**`CsvImport-0013`** (error) - When the value of ncols of a CsvImport is a reference, it must be a reference to a positive integer. ([source](specsheets/tasks/CsvImport/v1.0.0/validation/CsvImport-0013.md)) > `ncols` is `PositiveIntegerOrRef`: when the value is a reference, it must resolve to a positive integer. -**`CsvImport-0014`** (error) - When the value of nrows of a CsvImport is provided directly, it must be a positive integer. +**`CsvImport-0014`** (error) - When the value of nrows of a CsvImport is provided directly, it must be a positive integer. ([source](specsheets/tasks/CsvImport/v1.0.0/validation/CsvImport-0014.md)) > `nrows` is `PositiveIntegerOrRef`: the value, when not a reference, must be a positive integer. -**`CsvImport-0015`** (error) - When the value of nrows of a CsvImport is a reference, it must be a reference to a positive integer. +**`CsvImport-0015`** (error) - When the value of nrows of a CsvImport is a reference, it must be a reference to a positive integer. ([source](specsheets/tasks/CsvImport/v1.0.0/validation/CsvImport-0015.md)) > `nrows` is `PositiveIntegerOrRef`: when the value is a reference, it must resolve to a positive integer. -**`CsvImport-0016`** (error) - When the value of units of a CsvImport is provided directly, it must be an array of strings. +**`CsvImport-0016`** (error) - When the value of units of a CsvImport is provided directly, it must be an array of strings. ([source](specsheets/tasks/CsvImport/v1.0.0/validation/CsvImport-0016.md)) > `units` is `ListOfStringsOrRef`: the value, when not a reference, must be an array of strings. -**`CsvImport-0017`** (error) - When the value of units of a CsvImport is a reference, it must be a reference to an array of strings. +**`CsvImport-0017`** (error) - When the value of units of a CsvImport is a reference, it must be a reference to an array of strings. ([source](specsheets/tasks/CsvImport/v1.0.0/validation/CsvImport-0017.md)) > `units` is `ListOfStringsOrRef`: when the value is a reference, it must resolve to an array of strings. -**`CsvImport-0018`** (error) - The _type attribute of a CsvImport must be "csvImport". +**`CsvImport-0018`** (error) - The _type attribute of a CsvImport must be "csvImport". ([source](specsheets/tasks/CsvImport/v1.0.0/validation/CsvImport-0018.md)) > `_type` is the discriminator field. For `CsvImport` it must always equal `"csvImport"`. #### DataImport +*Source: [specsheets/tasks/DataImport/v1.0.0/description.md](specsheets/tasks/DataImport/v1.0.0/description.md)* + ![DataImport UML diagram](specsheets/tasks/DataImport/v1.0.0/DataImport.png) **Category:** tasks @@ -1932,42 +1997,44 @@ The imported `AnnotatedData`, accessible as `[id]` (e.g. `#tasks:data1`). ##### Validation Rules -**`DataImport-0000`** (error) - The element fails a JSON Schema constraint attributable to DataImport that does not match any other numbered rule. +**`DataImport-0000`** (error) - The element fails a JSON Schema constraint attributable to DataImport that does not match any other numbered rule. ([source](specsheets/tasks/DataImport/v1.0.0/validation/DataImport-0000.md)) > Catch-all rule for schema-pass failures attributable to DataImport (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`DataImport-0001`** (error) - The location attribute of a DataImport is required. +**`DataImport-0001`** (error) - The location attribute of a DataImport is required. ([source](specsheets/tasks/DataImport/v1.0.0/validation/DataImport-0001.md)) > `location` is required. -**`DataImport-0002`** (error) - When the value of location of a DataImport is provided directly, it must be a URI string. +**`DataImport-0002`** (error) - When the value of location of a DataImport is provided directly, it must be a URI string. ([source](specsheets/tasks/DataImport/v1.0.0/validation/DataImport-0002.md)) > `location` is `URIOrRef`: the value, when not a reference, must be a URI string. -**`DataImport-0003`** (error) - When the value of location of a DataImport is a reference, it must be a reference to a URI string. +**`DataImport-0003`** (error) - When the value of location of a DataImport is a reference, it must be a reference to a URI string. ([source](specsheets/tasks/DataImport/v1.0.0/validation/DataImport-0003.md)) > `location` is `URIOrRef`: when the value is a reference, it must resolve to a URI string. -**`DataImport-0004`** (error) - The format attribute of a DataImport is required. +**`DataImport-0004`** (error) - The format attribute of a DataImport is required. ([source](specsheets/tasks/DataImport/v1.0.0/validation/DataImport-0004.md)) > `format` is required. -**`DataImport-0005`** (error) - When the value of format of a DataImport is provided directly, it must be a URI string. +**`DataImport-0005`** (error) - When the value of format of a DataImport is provided directly, it must be a URI string. ([source](specsheets/tasks/DataImport/v1.0.0/validation/DataImport-0005.md)) > `format` is `URIOrRef`: the value, when not a reference, must be a URI string. -**`DataImport-0006`** (error) - When the value of format of a DataImport is a reference, it must be a reference to a URI string. +**`DataImport-0006`** (error) - When the value of format of a DataImport is a reference, it must be a reference to a URI string. ([source](specsheets/tasks/DataImport/v1.0.0/validation/DataImport-0006.md)) > `format` is `URIOrRef`: when the value is a reference, it must resolve to a URI string. -**`DataImport-0007`** (error) - The _type attribute of a DataImport must be "dataImport". +**`DataImport-0007`** (error) - The _type attribute of a DataImport must be "dataImport". ([source](specsheets/tasks/DataImport/v1.0.0/validation/DataImport-0007.md)) > `_type` is the discriminator field. For `DataImport` it must always equal `"dataImport"`. #### DrawFromDistribution +*Source: [specsheets/tasks/DrawFromDistribution/v1.0.0/description.md](specsheets/tasks/DrawFromDistribution/v1.0.0/description.md)* + ![DrawFromDistribution UML diagram](specsheets/tasks/DrawFromDistribution/v1.0.0/DrawFromDistribution.png) **Category:** tasks @@ -2020,50 +2087,52 @@ Typically a single number, indexed as `[id][0]`; the type is multidimensional `A ##### Validation Rules -**`DrawFromDistribution-0000`** (error) - The element fails a JSON Schema constraint attributable to DrawFromDistribution that does not match any other numbered rule. +**`DrawFromDistribution-0000`** (error) - The element fails a JSON Schema constraint attributable to DrawFromDistribution that does not match any other numbered rule. ([source](specsheets/tasks/DrawFromDistribution/v1.0.0/validation/DrawFromDistribution-0000.md)) > Catch-all rule for schema-pass failures attributable to DrawFromDistribution (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`DrawFromDistribution-0001`** (error) - The arguments attribute of a DrawFromDistribution is required. +**`DrawFromDistribution-0001`** (error) - The arguments attribute of a DrawFromDistribution is required. ([source](specsheets/tasks/DrawFromDistribution/v1.0.0/validation/DrawFromDistribution-0001.md)) > `arguments` is required. -**`DrawFromDistribution-0002`** (error) - When the value of arguments of a DrawFromDistribution is provided directly, it must be an array of values. +**`DrawFromDistribution-0002`** (error) - When the value of arguments of a DrawFromDistribution is provided directly, it must be an array of values. ([source](specsheets/tasks/DrawFromDistribution/v1.0.0/validation/DrawFromDistribution-0002.md)) > `arguments` is `ListOfAnyOrRef`: the value, when not a reference, must be an array of values. -**`DrawFromDistribution-0003`** (error) - When the value of arguments of a DrawFromDistribution is a reference, it must be a reference to an array of values. +**`DrawFromDistribution-0003`** (error) - When the value of arguments of a DrawFromDistribution is a reference, it must be a reference to an array of values. ([source](specsheets/tasks/DrawFromDistribution/v1.0.0/validation/DrawFromDistribution-0003.md)) > `arguments` is `ListOfAnyOrRef`: when the value is a reference, it must resolve to an array of values. -**`DrawFromDistribution-0004`** (error) - When the value of outputPersistent of a DrawFromDistribution is provided directly, it must be a boolean. +**`DrawFromDistribution-0004`** (error) - When the value of outputPersistent of a DrawFromDistribution is provided directly, it must be a boolean. ([source](specsheets/tasks/DrawFromDistribution/v1.0.0/validation/DrawFromDistribution-0004.md)) > `outputPersistent` is `BooleanOrRef`: the value, when not a reference, must be a boolean. -**`DrawFromDistribution-0005`** (error) - When the value of outputPersistent of a DrawFromDistribution is a reference, it must be a reference to a boolean. +**`DrawFromDistribution-0005`** (error) - When the value of outputPersistent of a DrawFromDistribution is a reference, it must be a reference to a boolean. ([source](specsheets/tasks/DrawFromDistribution/v1.0.0/validation/DrawFromDistribution-0005.md)) > `outputPersistent` is `BooleanOrRef`: when the value is a reference, it must resolve to a boolean. -**`DrawFromDistribution-0006`** (error) - The _type attribute of a DrawFromDistribution must be "drawFromDistribution". +**`DrawFromDistribution-0006`** (error) - The _type attribute of a DrawFromDistribution must be "drawFromDistribution". ([source](specsheets/tasks/DrawFromDistribution/v1.0.0/validation/DrawFromDistribution-0006.md)) > `_type` is the discriminator field. For `DrawFromDistribution` it must always equal `"drawFromDistribution"`. -**`DrawFromDistribution-0007`** (error) - The distribution attribute of a DrawFromDistribution is required. +**`DrawFromDistribution-0007`** (error) - The distribution attribute of a DrawFromDistribution is required. ([source](specsheets/tasks/DrawFromDistribution/v1.0.0/validation/DrawFromDistribution-0007.md)) > `distribution` is required. -**`DrawFromDistribution-0008`** (error) - When the value of distribution of a DrawFromDistribution is provided directly, it must be one of the SBML distrib package's definitionURL values. +**`DrawFromDistribution-0008`** (error) - When the value of distribution of a DrawFromDistribution is provided directly, it must be one of the SBML distrib package's definitionURL values. ([source](specsheets/tasks/DrawFromDistribution/v1.0.0/validation/DrawFromDistribution-0008.md)) > `distribution` is `DistributionURI | SIdRef`: the value, when not a reference, must be one of the 12 `http://www.sbml.org/sbml/symbols/distrib/*` URIs listed in `core/Types`'s `DistributionURI` (kept in sync with `schema/predefined-functions.json`'s `distrib` registry). -**`DrawFromDistribution-0009`** (error) - When the value of distribution of a DrawFromDistribution is a reference, it must be a reference to one of the SBML distrib package's definitionURL values. +**`DrawFromDistribution-0009`** (error) - When the value of distribution of a DrawFromDistribution is a reference, it must be a reference to one of the SBML distrib package's definitionURL values. ([source](specsheets/tasks/DrawFromDistribution/v1.0.0/validation/DrawFromDistribution-0009.md)) > `distribution` is `DistributionURI | SIdRef`: when the value is a reference, it must resolve to one of the 12 allowed distribution URIs. #### ExplicitODESimulation +*Source: [specsheets/tasks/ExplicitODESimulation/v1.0.0/description.md](specsheets/tasks/ExplicitODESimulation/v1.0.0/description.md)* + ![ExplicitODESimulation UML diagram](specsheets/tasks/ExplicitODESimulation/v1.0.0/ExplicitODESimulation.png) **Category:** tasks @@ -2175,38 +2244,40 @@ A 2D matrix of numbers, accessible as `[id]`: the first column is `independentVa ##### Validation Rules -**`ExplicitODESimulation-0000`** (error) - The element fails a JSON Schema constraint attributable to ExplicitODESimulation that does not match any other numbered rule. +**`ExplicitODESimulation-0000`** (error) - The element fails a JSON Schema constraint attributable to ExplicitODESimulation that does not match any other numbered rule. ([source](specsheets/tasks/ExplicitODESimulation/v1.0.0/validation/ExplicitODESimulation-0000.md)) > Catch-all rule for schema-pass failures attributable to ExplicitODESimulation (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`ExplicitODESimulation-0001`** (error) - The model attribute of an ExplicitODESimulation is required. +**`ExplicitODESimulation-0001`** (error) - The model attribute of an ExplicitODESimulation is required. ([source](specsheets/tasks/ExplicitODESimulation/v1.0.0/validation/ExplicitODESimulation-0001.md)) > `model` is required. -**`ExplicitODESimulation-0002`** (error) - The independentVariable attribute of an ExplicitODESimulation is required. +**`ExplicitODESimulation-0002`** (error) - The independentVariable attribute of an ExplicitODESimulation is required. ([source](specsheets/tasks/ExplicitODESimulation/v1.0.0/validation/ExplicitODESimulation-0002.md)) > `independentVariable` is required. -**`ExplicitODESimulation-0003`** (error) - The outputVariables attribute of an ExplicitODESimulation is required. +**`ExplicitODESimulation-0003`** (error) - The outputVariables attribute of an ExplicitODESimulation is required. ([source](specsheets/tasks/ExplicitODESimulation/v1.0.0/validation/ExplicitODESimulation-0003.md)) > `outputVariables` is required. -**`ExplicitODESimulation-0004`** (error) - The independentVariableRange attribute of an ExplicitODESimulation is required. +**`ExplicitODESimulation-0004`** (error) - The independentVariableRange attribute of an ExplicitODESimulation is required. ([source](specsheets/tasks/ExplicitODESimulation/v1.0.0/validation/ExplicitODESimulation-0004.md)) > `independentVariableRange` is required. -**`ExplicitODESimulation-0005`** (error) - The independentVariableRange attribute of an ExplicitODESimulation must be a NumericRangeInline object. +**`ExplicitODESimulation-0005`** (error) - The independentVariableRange attribute of an ExplicitODESimulation must be a NumericRangeInline object. ([source](specsheets/tasks/ExplicitODESimulation/v1.0.0/validation/ExplicitODESimulation-0005.md)) > `independentVariableRange` is `NumericRangeInline`: it must be a NumericRangeInline object. -**`ExplicitODESimulation-0006`** (error) - The _type attribute of an ExplicitODESimulation must be "explicitODESimulation". +**`ExplicitODESimulation-0006`** (error) - The _type attribute of an ExplicitODESimulation must be "explicitODESimulation". ([source](specsheets/tasks/ExplicitODESimulation/v1.0.0/validation/ExplicitODESimulation-0006.md)) > `_type` is the discriminator field. For `ExplicitODESimulation` it must always equal `"explicitODESimulation"`. #### ExplicitStochasticSimulation +*Source: [specsheets/tasks/ExplicitStochasticSimulation/v1.0.0/description.md](specsheets/tasks/ExplicitStochasticSimulation/v1.0.0/description.md)* + ![ExplicitStochasticSimulation UML diagram](specsheets/tasks/ExplicitStochasticSimulation/v1.0.0/ExplicitStochasticSimulation.png) **Category:** tasks @@ -2288,38 +2359,40 @@ A 2D matrix of numbers, accessible as `[id]`: the first column is `independentVa ##### Validation Rules -**`ExplicitStochasticSimulation-0000`** (error) - The element fails a JSON Schema constraint attributable to ExplicitStochasticSimulation that does not match any other numbered rule. +**`ExplicitStochasticSimulation-0000`** (error) - The element fails a JSON Schema constraint attributable to ExplicitStochasticSimulation that does not match any other numbered rule. ([source](specsheets/tasks/ExplicitStochasticSimulation/v1.0.0/validation/ExplicitStochasticSimulation-0000.md)) > Catch-all rule for schema-pass failures attributable to ExplicitStochasticSimulation (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`ExplicitStochasticSimulation-0001`** (error) - The model attribute of an ExplicitStochasticSimulation is required. +**`ExplicitStochasticSimulation-0001`** (error) - The model attribute of an ExplicitStochasticSimulation is required. ([source](specsheets/tasks/ExplicitStochasticSimulation/v1.0.0/validation/ExplicitStochasticSimulation-0001.md)) > `model` is required. -**`ExplicitStochasticSimulation-0002`** (error) - The independentVariable attribute of an ExplicitStochasticSimulation is required. +**`ExplicitStochasticSimulation-0002`** (error) - The independentVariable attribute of an ExplicitStochasticSimulation is required. ([source](specsheets/tasks/ExplicitStochasticSimulation/v1.0.0/validation/ExplicitStochasticSimulation-0002.md)) > `independentVariable` is required. -**`ExplicitStochasticSimulation-0003`** (error) - The outputVariables attribute of an ExplicitStochasticSimulation is required. +**`ExplicitStochasticSimulation-0003`** (error) - The outputVariables attribute of an ExplicitStochasticSimulation is required. ([source](specsheets/tasks/ExplicitStochasticSimulation/v1.0.0/validation/ExplicitStochasticSimulation-0003.md)) > `outputVariables` is required. -**`ExplicitStochasticSimulation-0004`** (error) - The independentVariableRange attribute of an ExplicitStochasticSimulation is required. +**`ExplicitStochasticSimulation-0004`** (error) - The independentVariableRange attribute of an ExplicitStochasticSimulation is required. ([source](specsheets/tasks/ExplicitStochasticSimulation/v1.0.0/validation/ExplicitStochasticSimulation-0004.md)) > `independentVariableRange` is required. -**`ExplicitStochasticSimulation-0005`** (error) - The independentVariableRange attribute of an ExplicitStochasticSimulation must be a NumericRangeInline object. +**`ExplicitStochasticSimulation-0005`** (error) - The independentVariableRange attribute of an ExplicitStochasticSimulation must be a NumericRangeInline object. ([source](specsheets/tasks/ExplicitStochasticSimulation/v1.0.0/validation/ExplicitStochasticSimulation-0005.md)) > `independentVariableRange` is `NumericRangeInline`: it must be a NumericRangeInline object. -**`ExplicitStochasticSimulation-0006`** (error) - The _type attribute of an ExplicitStochasticSimulation must be "explicitStochasticSimulation". +**`ExplicitStochasticSimulation-0006`** (error) - The _type attribute of an ExplicitStochasticSimulation must be "explicitStochasticSimulation". ([source](specsheets/tasks/ExplicitStochasticSimulation/v1.0.0/validation/ExplicitStochasticSimulation-0006.md)) > `_type` is the discriminator field. For `ExplicitStochasticSimulation` it must always equal `"explicitStochasticSimulation"`. #### FluxBalanceAnalysis +*Source: [specsheets/tasks/FluxBalanceAnalysis/v1.0.0/description.md](specsheets/tasks/FluxBalanceAnalysis/v1.0.0/description.md)* + ![FluxBalanceAnalysis UML diagram](specsheets/tasks/FluxBalanceAnalysis/v1.0.0/FluxBalanceAnalysis.png) **Category:** tasks @@ -2331,7 +2404,7 @@ A 2D matrix of numbers, accessible as `[id]`: the first column is `independentVa Uses an objective function and reaction rate bounds (both defined within the model itself) to determine the set of reaction rates that maximizes the objective function. Unlike the other simulation tasks, FBA has no independent variable. -This is an implementation of KISAO:0000437 (FBA). +This is an implementation of KISAO:0000437 (FBA). The algorithm(s) it uses internally may be listed in the optional `workingAlgorithms` (see `WorkingAlgorithm`). ##### Attributes @@ -2342,7 +2415,7 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an | `taskParameters` | array of TaskParameter | no | | | `model` | SIdRef | yes | | | `outputVariables` | ListOfStringsOrRef | yes | | -| `outputModel` | BooleanOrRef | no | | +| `workingAlgorithms` | array of WorkingAlgorithm | no | | ###### Attribute details @@ -2352,62 +2425,54 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an **`outputVariables`** (ListOfStringsOrRef, required) - _(no description yet - placeholder, needs to be filled in)_ -**`outputModel`** (BooleanOrRef, optional) - _(no description yet - placeholder, needs to be filled in)_ +**`workingAlgorithms`** (array of WorkingAlgorithm, optional) - _(no description yet - placeholder, needs to be filled in)_ ##### Outputs -A dictionary of model variables (usually fluxes) to their final values, accessible via `outputVariables` as `[id]` - analogous to a `SteadyState` result. If `outputModel` is `true`, the resulting model state is also available as `[id].model`. +A dictionary of model variables (usually fluxes) to their final values, accessible via `outputVariables` as `[id]` - analogous to a `SteadyState` result. The resulting model state is always also available as `[id].model`. - `[id]`: **Valid** - Dimensions: 1D: one value per entry of `outputVariables` (typically reaction fluxes) - length depends on how many variables are named there. - `[id].model`: **Valid** - `[id].strings`: **Invalid** -`[id].model` is only produced when `outputModel` is `true`. - ##### Validation Rules -**`FluxBalanceAnalysis-0000`** (error) - The element fails a JSON Schema constraint attributable to FluxBalanceAnalysis that does not match any other numbered rule. +**`FluxBalanceAnalysis-0000`** (error) - The element fails a JSON Schema constraint attributable to FluxBalanceAnalysis that does not match any other numbered rule. ([source](specsheets/tasks/FluxBalanceAnalysis/v1.0.0/validation/FluxBalanceAnalysis-0000.md)) > Catch-all rule for schema-pass failures attributable to FluxBalanceAnalysis (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`FluxBalanceAnalysis-0001`** (error) - The model attribute of a FluxBalanceAnalysis is required. +**`FluxBalanceAnalysis-0001`** (error) - The model attribute of a FluxBalanceAnalysis is required. ([source](specsheets/tasks/FluxBalanceAnalysis/v1.0.0/validation/FluxBalanceAnalysis-0001.md)) > `model` is required. -**`FluxBalanceAnalysis-0002`** (error) - The model attribute of a FluxBalanceAnalysis, if present, must be a reference (a string starting with '#'). +**`FluxBalanceAnalysis-0002`** (error) - The model attribute of a FluxBalanceAnalysis, if present, must be a reference (a string starting with '#'). ([source](specsheets/tasks/FluxBalanceAnalysis/v1.0.0/validation/FluxBalanceAnalysis-0002.md)) > `model` is `SIdRef` - always a reference, never a literal value. -**`FluxBalanceAnalysis-0003`** (error) - The outputVariables attribute of a FluxBalanceAnalysis is required. +**`FluxBalanceAnalysis-0003`** (error) - The outputVariables attribute of a FluxBalanceAnalysis is required. ([source](specsheets/tasks/FluxBalanceAnalysis/v1.0.0/validation/FluxBalanceAnalysis-0003.md)) > `outputVariables` is required. -**`FluxBalanceAnalysis-0004`** (error) - When the value of outputVariables of a FluxBalanceAnalysis is provided directly, it must be an array of strings. +**`FluxBalanceAnalysis-0004`** (error) - When the value of outputVariables of a FluxBalanceAnalysis is provided directly, it must be an array of strings. ([source](specsheets/tasks/FluxBalanceAnalysis/v1.0.0/validation/FluxBalanceAnalysis-0004.md)) > `outputVariables` is `ListOfStringsOrRef`: the value, when not a reference, must be an array of strings. -**`FluxBalanceAnalysis-0005`** (error) - When the value of outputVariables of a FluxBalanceAnalysis is a reference, it must be a reference to an array of strings. +**`FluxBalanceAnalysis-0005`** (error) - When the value of outputVariables of a FluxBalanceAnalysis is a reference, it must be a reference to an array of strings. ([source](specsheets/tasks/FluxBalanceAnalysis/v1.0.0/validation/FluxBalanceAnalysis-0005.md)) > `outputVariables` is `ListOfStringsOrRef`: when the value is a reference, it must resolve to an array of strings. -**`FluxBalanceAnalysis-0006`** (error) - When the value of outputModel of a FluxBalanceAnalysis is provided directly, it must be a boolean. - -> `outputModel` is `BooleanOrRef`: the value, when not a reference, must be a boolean. - -**`FluxBalanceAnalysis-0007`** (error) - When the value of outputModel of a FluxBalanceAnalysis is a reference, it must be a reference to a boolean. - -> `outputModel` is `BooleanOrRef`: when the value is a reference, it must resolve to a boolean. - -**`FluxBalanceAnalysis-0008`** (error) - The _type attribute of a FluxBalanceAnalysis must be "fluxBalanceAnalysis". +**`FluxBalanceAnalysis-0008`** (error) - The _type attribute of a FluxBalanceAnalysis must be "fluxBalanceAnalysis". ([source](specsheets/tasks/FluxBalanceAnalysis/v1.0.0/validation/FluxBalanceAnalysis-0008.md)) > `_type` is the discriminator field. For `FluxBalanceAnalysis` it must always equal `"fluxBalanceAnalysis"`. #### JacobianFull +*Source: [specsheets/tasks/JacobianFull/v1.0.0/description.md](specsheets/tasks/JacobianFull/v1.0.0/description.md)* + ![JacobianFull UML diagram](specsheets/tasks/JacobianFull/v1.0.0/JacobianFull.png) **Category:** tasks @@ -2448,26 +2513,28 @@ The full Jacobian as a list of lists, accessible as `[id]`, with axis labels giv ##### Validation Rules -**`JacobianFull-0000`** (error) - The element fails a JSON Schema constraint attributable to JacobianFull that does not match any other numbered rule. +**`JacobianFull-0000`** (error) - The element fails a JSON Schema constraint attributable to JacobianFull that does not match any other numbered rule. ([source](specsheets/tasks/JacobianFull/v1.0.0/validation/JacobianFull-0000.md)) > Catch-all rule for schema-pass failures attributable to JacobianFull (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`JacobianFull-0001`** (error) - The model attribute of a JacobianFull is required. +**`JacobianFull-0001`** (error) - The model attribute of a JacobianFull is required. ([source](specsheets/tasks/JacobianFull/v1.0.0/validation/JacobianFull-0001.md)) > `model` is required. -**`JacobianFull-0002`** (error) - The model attribute of a JacobianFull, if present, must be a reference (a string starting with '#'). +**`JacobianFull-0002`** (error) - The model attribute of a JacobianFull, if present, must be a reference (a string starting with '#'). ([source](specsheets/tasks/JacobianFull/v1.0.0/validation/JacobianFull-0002.md)) > `model` is `SIdRef` - always a reference, never a literal value. -**`JacobianFull-0003`** (error) - The _type attribute of a JacobianFull must be "jacobianFull". +**`JacobianFull-0003`** (error) - The _type attribute of a JacobianFull must be "jacobianFull". ([source](specsheets/tasks/JacobianFull/v1.0.0/validation/JacobianFull-0003.md)) > `_type` is the discriminator field. For `JacobianFull` it must always equal `"jacobianFull"`. #### JacobianReduced +*Source: [specsheets/tasks/JacobianReduced/v1.0.0/description.md](specsheets/tasks/JacobianReduced/v1.0.0/description.md)* + ![JacobianReduced UML diagram](specsheets/tasks/JacobianReduced/v1.0.0/JacobianReduced.png) **Category:** tasks @@ -2508,26 +2575,28 @@ The reduced Jacobian as a list of lists, accessible as `[id]`, with axis labels ##### Validation Rules -**`JacobianReduced-0000`** (error) - The element fails a JSON Schema constraint attributable to JacobianReduced that does not match any other numbered rule. +**`JacobianReduced-0000`** (error) - The element fails a JSON Schema constraint attributable to JacobianReduced that does not match any other numbered rule. ([source](specsheets/tasks/JacobianReduced/v1.0.0/validation/JacobianReduced-0000.md)) > Catch-all rule for schema-pass failures attributable to JacobianReduced (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`JacobianReduced-0001`** (error) - The model attribute of a JacobianReduced is required. +**`JacobianReduced-0001`** (error) - The model attribute of a JacobianReduced is required. ([source](specsheets/tasks/JacobianReduced/v1.0.0/validation/JacobianReduced-0001.md)) > `model` is required. -**`JacobianReduced-0002`** (error) - The model attribute of a JacobianReduced, if present, must be a reference (a string starting with '#'). +**`JacobianReduced-0002`** (error) - The model attribute of a JacobianReduced, if present, must be a reference (a string starting with '#'). ([source](specsheets/tasks/JacobianReduced/v1.0.0/validation/JacobianReduced-0002.md)) > `model` is `SIdRef` - always a reference, never a literal value. -**`JacobianReduced-0003`** (error) - The _type attribute of a JacobianReduced must be "jacobianReduced". +**`JacobianReduced-0003`** (error) - The _type attribute of a JacobianReduced must be "jacobianReduced". ([source](specsheets/tasks/JacobianReduced/v1.0.0/validation/JacobianReduced-0003.md)) > `_type` is the discriminator field. For `JacobianReduced` it must always equal `"jacobianReduced"`. #### Loop +*Source: [specsheets/tasks/Loop/v1.0.0/description.md](specsheets/tasks/Loop/v1.0.0/description.md)* + ![Loop UML diagram](specsheets/tasks/Loop/v1.0.0/Loop.png) **Category:** tasks @@ -2537,7 +2606,7 @@ The reduced Jacobian as a list of lists, accessible as `[id]`, with axis labels ##### What it does -A `Repeat` whose iterations are chained: each depends on the output of the previous one. This is expressed with `loopVariables` - named `LoopVariable` entries whose value equals `initialValue` on the first iteration and thereafter equals `subsequentValues` (an output of one of the loop's `subTasks`). A subTask references a loop variable as `#tasks:[loop_id]:loopVariables:[loopvar_id]`. +A `Repeat` whose iterations are chained: each depends on the output of the previous one, with one iteration per element of its required `range` (a `Range`/`NumericRange`/`ParameterRange`), taken in order; a `Loop` always runs all of them and cannot end early. The chaining is expressed with `loopVariables` - named `LoopVariable` entries whose value equals `initialValue` on the first iteration and thereafter equals `subsequentValues` (an output of one of the loop's `subTasks`). A subTask references a loop variable as `#tasks:[loop_id]:loopVariables:[loopvar_id]`. ##### Attributes @@ -2549,7 +2618,7 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an | `subTasks` | object (values: AbstractTask) | yes | | | `outputVariableMap` | object (values: SIdRef) or SIdRef | no | | | `aggregateOutputVariables` | object (values: AggregationCalculation) | no | | -| `range` | RangeInline | no | | +| `range` | RangeInline | yes | | | `loopVariables` | object (values: LoopVariable) | yes | | ###### Attribute details @@ -2562,7 +2631,7 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an **`aggregateOutputVariables`** (object (values: AggregationCalculation), optional) - _(no description yet - placeholder, needs to be filled in)_ -**`range`** (RangeInline, optional) - _(no description yet - placeholder, needs to be filled in)_ +**`range`** (RangeInline, required) - _(no description yet - placeholder, needs to be filled in)_ **`loopVariables`** (object (values: LoopVariable), required) - _(no description yet - placeholder, needs to be filled in)_ @@ -2572,7 +2641,7 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an `[id]`: an `AnnotatedData` whose first column is the range values and whose subsequent columns follow `outputVariableMap`. `[id].aggregates`: an `AnnotatedData` following `aggregateOutputVariables`, when defined. - `[id]`: **Valid** - - Dimensions: 2D (or more): first dimension = one row per iteration; remaining dimension(s) = one column per entry of `outputVariableMap`. Unlike `Scatter`, the row count isn't known in advance from a `range` - it's however many iterations the loop actually runs. _(Exact termination condition for a Loop's iteration count - placeholder, needs to be filled in from the spec.)_ + - Dimensions: 2D (or more): first dimension = one row per value in `range`; remaining dimension(s) = one column per entry of `outputVariableMap` (or just the range-values column alone, if `outputVariableMap` is empty). As with `Scatter`, the row count is known in advance from `range`. A column whose subTask output is itself multi-dimensional would add further dimensions - not pinned down further here. - `[id].model`: **Invalid** - `[id].strings`: **Invalid** @@ -2581,37 +2650,39 @@ Additional possible outputs beyond the three standard ones: - `[id].aggregates`: An `AnnotatedData` following `aggregateOutputVariables`, when that attribute is defined. - Dimensions: 1D: one entry per `aggregateOutputVariables` mapping, each collapsing the iteration dimension of `[id]` down to a single value (per `Repeat`, the applied dimension defaults to the Repeat's own iterations) - unless the underlying subTask output was itself multi-dimensional, in which case that dimensionality carries through per entry. -- `[id].range`: Within the loop, the current value of `range`, when `range` is defined (see `Repeat`). +- `[id].range`: Within the loop, the current value of `range`. Always valid, since `range` is required. - Dimensions: Scalar (0-D) per iteration. -- `[id].index`: Within the loop, the current index into `range`, when `range` is defined. +- `[id].index`: Within the loop, the current index into `range`. Always valid. - Dimensions: Scalar (0-D) per iteration. ##### Validation Rules -**`Loop-0000`** (error) - The element fails a JSON Schema constraint attributable to Loop that does not match any other numbered rule. +**`Loop-0000`** (error) - The element fails a JSON Schema constraint attributable to Loop that does not match any other numbered rule. ([source](specsheets/tasks/Loop/v1.0.0/validation/Loop-0000.md)) > Catch-all rule for schema-pass failures attributable to Loop (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`Loop-0001`** (error) - The subTasks attribute of a Loop is required. +**`Loop-0001`** (error) - The subTasks attribute of a Loop is required. ([source](specsheets/tasks/Loop/v1.0.0/validation/Loop-0001.md)) > `subTasks` is required. -**`Loop-0002`** (error) - The loopVariables attribute of a Loop is required. +**`Loop-0002`** (error) - The loopVariables attribute of a Loop is required. ([source](specsheets/tasks/Loop/v1.0.0/validation/Loop-0002.md)) > `loopVariables` is required. -**`Loop-0003`** (error) - The loopVariables attribute of a Loop must be an object whose values are LoopVariable. +**`Loop-0003`** (error) - The loopVariables attribute of a Loop must be an object whose values are LoopVariable. ([source](specsheets/tasks/Loop/v1.0.0/validation/Loop-0003.md)) > `loopVariables` is `object (values: LoopVariable)`: it must be an object whose values are LoopVariable. -**`Loop-0005`** (error) - The _type attribute of a Loop must be "loop". +**`Loop-0005`** (error) - The _type attribute of a Loop must be "loop". ([source](specsheets/tasks/Loop/v1.0.0/validation/Loop-0005.md)) > `_type` is the discriminator field. For `Loop` it must always equal `"loop"`. #### ModelChange +*Source: [specsheets/tasks/ModelChange/v1.0.0/description.md](specsheets/tasks/ModelChange/v1.0.0/description.md)* + ![ModelChange UML diagram](specsheets/tasks/ModelChange/v1.0.0/ModelChange.png) **Category:** tasks @@ -2667,58 +2738,60 @@ The modified model, accessible as `[id].model`. ##### Validation Rules -**`ModelChange-0000`** (error) - The element fails a JSON Schema constraint attributable to ModelChange that does not match any other numbered rule. +**`ModelChange-0000`** (error) - The element fails a JSON Schema constraint attributable to ModelChange that does not match any other numbered rule. ([source](specsheets/tasks/ModelChange/v1.0.0/validation/ModelChange-0000.md)) > Catch-all rule for schema-pass failures attributable to ModelChange (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`ModelChange-0001`** (error) - The inputModel attribute of a ModelChange is required. +**`ModelChange-0001`** (error) - The inputModel attribute of a ModelChange is required. ([source](specsheets/tasks/ModelChange/v1.0.0/validation/ModelChange-0001.md)) > `inputModel` is required. -**`ModelChange-0002`** (error) - The inputModel attribute of a ModelChange, if present, must be a reference (a string starting with '#'). +**`ModelChange-0002`** (error) - The inputModel attribute of a ModelChange, if present, must be a reference (a string starting with '#'). ([source](specsheets/tasks/ModelChange/v1.0.0/validation/ModelChange-0002.md)) > `inputModel` is `SIdRef` - always a reference, never a literal value. -**`ModelChange-0003`** (error) - When the value of setValues of a ModelChange is provided directly, it must be an object whose values are AnyValueOrRef. +**`ModelChange-0003`** (error) - When the value of setValues of a ModelChange is provided directly, it must be an object whose values are AnyValueOrRef. ([source](specsheets/tasks/ModelChange/v1.0.0/validation/ModelChange-0003.md)) > `setValues` is `object (values: AnyValueOrRef) or SIdRef`: the value, when not a reference, must be an object whose values are AnyValueOrRef. -**`ModelChange-0004`** (error) - When the value of setValues of a ModelChange is a reference, it must be a reference to an object whose values are AnyValueOrRef. +**`ModelChange-0004`** (error) - When the value of setValues of a ModelChange is a reference, it must be a reference to an object whose values are AnyValueOrRef. ([source](specsheets/tasks/ModelChange/v1.0.0/validation/ModelChange-0004.md)) > `setValues` is `object (values: AnyValueOrRef) or SIdRef`: when the value is a reference, it must resolve to an object whose values are AnyValueOrRef. -**`ModelChange-0005`** (error) - When the value of removeElements of a ModelChange is provided directly, it must be an array of strings. +**`ModelChange-0005`** (error) - When the value of removeElements of a ModelChange is provided directly, it must be an array of strings. ([source](specsheets/tasks/ModelChange/v1.0.0/validation/ModelChange-0005.md)) > `removeElements` is `ListOfStringsOrRef`: the value, when not a reference, must be an array of strings. -**`ModelChange-0006`** (error) - When the value of removeElements of a ModelChange is a reference, it must be a reference to an array of strings. +**`ModelChange-0006`** (error) - When the value of removeElements of a ModelChange is a reference, it must be a reference to an array of strings. ([source](specsheets/tasks/ModelChange/v1.0.0/validation/ModelChange-0006.md)) > `removeElements` is `ListOfStringsOrRef`: when the value is a reference, it must resolve to an array of strings. -**`ModelChange-0007`** (error) - When the value of addElements of a ModelChange is provided directly, it must be an array of strings. +**`ModelChange-0007`** (error) - When the value of addElements of a ModelChange is provided directly, it must be an array of strings. ([source](specsheets/tasks/ModelChange/v1.0.0/validation/ModelChange-0007.md)) > `addElements` is `ListOfStringsOrRef`: the value, when not a reference, must be an array of strings. -**`ModelChange-0008`** (error) - When the value of addElements of a ModelChange is a reference, it must be a reference to an array of strings. +**`ModelChange-0008`** (error) - When the value of addElements of a ModelChange is a reference, it must be a reference to an array of strings. ([source](specsheets/tasks/ModelChange/v1.0.0/validation/ModelChange-0008.md)) > `addElements` is `ListOfStringsOrRef`: when the value is a reference, it must resolve to an array of strings. -**`ModelChange-0009`** (error) - When the value of replaceElements of a ModelChange is provided directly, it must be an object whose values are StringOrRef. +**`ModelChange-0009`** (error) - When the value of replaceElements of a ModelChange is provided directly, it must be an object whose values are StringOrRef. ([source](specsheets/tasks/ModelChange/v1.0.0/validation/ModelChange-0009.md)) > `replaceElements` is `object (values: StringOrRef) or SIdRef`: the value, when not a reference, must be an object whose values are StringOrRef. -**`ModelChange-0010`** (error) - When the value of replaceElements of a ModelChange is a reference, it must be a reference to an object whose values are StringOrRef. +**`ModelChange-0010`** (error) - When the value of replaceElements of a ModelChange is a reference, it must be a reference to an object whose values are StringOrRef. ([source](specsheets/tasks/ModelChange/v1.0.0/validation/ModelChange-0010.md)) > `replaceElements` is `object (values: StringOrRef) or SIdRef`: when the value is a reference, it must resolve to an object whose values are StringOrRef. -**`ModelChange-0011`** (error) - The _type attribute of a ModelChange must be "modelChange". +**`ModelChange-0011`** (error) - The _type attribute of a ModelChange must be "modelChange". ([source](specsheets/tasks/ModelChange/v1.0.0/validation/ModelChange-0011.md)) > `_type` is the discriminator field. For `ModelChange` it must always equal `"modelChange"`. #### ModelElementList +*Source: [specsheets/tasks/ModelElementList/v1.0.0/description.md](specsheets/tasks/ModelElementList/v1.0.0/description.md)* + ![ModelElementList UML diagram](specsheets/tasks/ModelElementList/v1.0.0/ModelElementList.png) **Category:** tasks @@ -2771,58 +2844,60 @@ Corrected here to `[id].strings`, per the general `AbstractTask` addressing conv ##### Validation Rules -**`ModelElementList-0000`** (error) - The element fails a JSON Schema constraint attributable to ModelElementList that does not match any other numbered rule. +**`ModelElementList-0000`** (error) - The element fails a JSON Schema constraint attributable to ModelElementList that does not match any other numbered rule. ([source](specsheets/tasks/ModelElementList/v1.0.0/validation/ModelElementList-0000.md)) > Catch-all rule for schema-pass failures attributable to ModelElementList (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`ModelElementList-0001`** (error) - The model attribute of a ModelElementList is required. +**`ModelElementList-0001`** (error) - The model attribute of a ModelElementList is required. ([source](specsheets/tasks/ModelElementList/v1.0.0/validation/ModelElementList-0001.md)) > `model` is required. -**`ModelElementList-0002`** (error) - The model attribute of a ModelElementList, if present, must be a reference (a string starting with '#'). +**`ModelElementList-0002`** (error) - The model attribute of a ModelElementList, if present, must be a reference (a string starting with '#'). ([source](specsheets/tasks/ModelElementList/v1.0.0/validation/ModelElementList-0002.md)) > `model` is `SIdRef` - always a reference, never a literal value. -**`ModelElementList-0003`** (error) - When the value of includeElements of a ModelElementList is provided directly, it must be an array of strings. +**`ModelElementList-0003`** (error) - When the value of includeElements of a ModelElementList is provided directly, it must be an array of strings. ([source](specsheets/tasks/ModelElementList/v1.0.0/validation/ModelElementList-0003.md)) > `includeElements` is `ListOfStringsOrRef`: the value, when not a reference, must be an array of strings. -**`ModelElementList-0004`** (error) - When the value of includeElements of a ModelElementList is a reference, it must be a reference to an array of strings. +**`ModelElementList-0004`** (error) - When the value of includeElements of a ModelElementList is a reference, it must be a reference to an array of strings. ([source](specsheets/tasks/ModelElementList/v1.0.0/validation/ModelElementList-0004.md)) > `includeElements` is `ListOfStringsOrRef`: when the value is a reference, it must resolve to an array of strings. -**`ModelElementList-0005`** (error) - When the value of includeTypes of a ModelElementList is provided directly, it must be an array of strings. +**`ModelElementList-0005`** (error) - When the value of includeTypes of a ModelElementList is provided directly, it must be an array of strings. ([source](specsheets/tasks/ModelElementList/v1.0.0/validation/ModelElementList-0005.md)) > `includeTypes` is `ListOfStringsOrRef`: the value, when not a reference, must be an array of strings. -**`ModelElementList-0006`** (error) - When the value of includeTypes of a ModelElementList is a reference, it must be a reference to an array of strings. +**`ModelElementList-0006`** (error) - When the value of includeTypes of a ModelElementList is a reference, it must be a reference to an array of strings. ([source](specsheets/tasks/ModelElementList/v1.0.0/validation/ModelElementList-0006.md)) > `includeTypes` is `ListOfStringsOrRef`: when the value is a reference, it must resolve to an array of strings. -**`ModelElementList-0007`** (error) - When the value of excludeElements of a ModelElementList is provided directly, it must be an array of strings. +**`ModelElementList-0007`** (error) - When the value of excludeElements of a ModelElementList is provided directly, it must be an array of strings. ([source](specsheets/tasks/ModelElementList/v1.0.0/validation/ModelElementList-0007.md)) > `excludeElements` is `ListOfStringsOrRef`: the value, when not a reference, must be an array of strings. -**`ModelElementList-0008`** (error) - When the value of excludeElements of a ModelElementList is a reference, it must be a reference to an array of strings. +**`ModelElementList-0008`** (error) - When the value of excludeElements of a ModelElementList is a reference, it must be a reference to an array of strings. ([source](specsheets/tasks/ModelElementList/v1.0.0/validation/ModelElementList-0008.md)) > `excludeElements` is `ListOfStringsOrRef`: when the value is a reference, it must resolve to an array of strings. -**`ModelElementList-0009`** (error) - When the value of excludeTypes of a ModelElementList is provided directly, it must be an array of strings. +**`ModelElementList-0009`** (error) - When the value of excludeTypes of a ModelElementList is provided directly, it must be an array of strings. ([source](specsheets/tasks/ModelElementList/v1.0.0/validation/ModelElementList-0009.md)) > `excludeTypes` is `ListOfStringsOrRef`: the value, when not a reference, must be an array of strings. -**`ModelElementList-0010`** (error) - When the value of excludeTypes of a ModelElementList is a reference, it must be a reference to an array of strings. +**`ModelElementList-0010`** (error) - When the value of excludeTypes of a ModelElementList is a reference, it must be a reference to an array of strings. ([source](specsheets/tasks/ModelElementList/v1.0.0/validation/ModelElementList-0010.md)) > `excludeTypes` is `ListOfStringsOrRef`: when the value is a reference, it must resolve to an array of strings. -**`ModelElementList-0011`** (error) - The _type attribute of a ModelElementList must be "modelElementList". +**`ModelElementList-0011`** (error) - The _type attribute of a ModelElementList must be "modelElementList". ([source](specsheets/tasks/ModelElementList/v1.0.0/validation/ModelElementList-0011.md)) > `_type` is the discriminator field. For `ModelElementList` it must always equal `"modelElementList"`. #### ModelImport +*Source: [specsheets/tasks/ModelImport/v1.0.0/description.md](specsheets/tasks/ModelImport/v1.0.0/description.md)* + ![ModelImport UML diagram](specsheets/tasks/ModelImport/v1.0.0/ModelImport.png) **Category:** tasks @@ -2867,42 +2942,44 @@ The bare id (`#tasks:model1`) has no meaning and must not be used. ##### Validation Rules -**`ModelImport-0000`** (error) - The element fails a JSON Schema constraint attributable to ModelImport that does not match any other numbered rule. +**`ModelImport-0000`** (error) - The element fails a JSON Schema constraint attributable to ModelImport that does not match any other numbered rule. ([source](specsheets/tasks/ModelImport/v1.0.0/validation/ModelImport-0000.md)) > Catch-all rule for schema-pass failures attributable to ModelImport (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`ModelImport-0001`** (error) - The location attribute of a ModelImport is required. +**`ModelImport-0001`** (error) - The location attribute of a ModelImport is required. ([source](specsheets/tasks/ModelImport/v1.0.0/validation/ModelImport-0001.md)) > `location` is required. -**`ModelImport-0002`** (error) - When the value of location of a ModelImport is provided directly, it must be a URI string. +**`ModelImport-0002`** (error) - When the value of location of a ModelImport is provided directly, it must be a URI string. ([source](specsheets/tasks/ModelImport/v1.0.0/validation/ModelImport-0002.md)) > `location` is `URIOrRef`: the value, when not a reference, must be a URI string. -**`ModelImport-0003`** (error) - When the value of location of a ModelImport is a reference, it must be a reference to a URI string. +**`ModelImport-0003`** (error) - When the value of location of a ModelImport is a reference, it must be a reference to a URI string. ([source](specsheets/tasks/ModelImport/v1.0.0/validation/ModelImport-0003.md)) > `location` is `URIOrRef`: when the value is a reference, it must resolve to a URI string. -**`ModelImport-0004`** (error) - The language attribute of a ModelImport is required. +**`ModelImport-0004`** (error) - The language attribute of a ModelImport is required. ([source](specsheets/tasks/ModelImport/v1.0.0/validation/ModelImport-0004.md)) > `language` is required. -**`ModelImport-0005`** (error) - When the value of language of a ModelImport is provided directly, it must be a URN string. +**`ModelImport-0005`** (error) - When the value of language of a ModelImport is provided directly, it must be a URN string. ([source](specsheets/tasks/ModelImport/v1.0.0/validation/ModelImport-0005.md)) > `language` is `URNOrRef`: the value, when not a reference, must be a URN string. -**`ModelImport-0006`** (error) - When the value of language of a ModelImport is a reference, it must be a reference to a URN string. +**`ModelImport-0006`** (error) - When the value of language of a ModelImport is a reference, it must be a reference to a URN string. ([source](specsheets/tasks/ModelImport/v1.0.0/validation/ModelImport-0006.md)) > `language` is `URNOrRef`: when the value is a reference, it must resolve to a URN string. -**`ModelImport-0007`** (error) - The _type attribute of a ModelImport must be "modelImport". +**`ModelImport-0007`** (error) - The _type attribute of a ModelImport must be "modelImport". ([source](specsheets/tasks/ModelImport/v1.0.0/validation/ModelImport-0007.md)) > `_type` is the discriminator field. For `ModelImport` it must always equal `"modelImport"`. #### NumericRange +*Source: [specsheets/tasks/NumericRange/v1.0.0/description.md](specsheets/tasks/NumericRange/v1.0.0/description.md)* + ![NumericRange UML diagram](specsheets/tasks/Range/v1.0.0/Range.png) *(`NumericRange` has no standalone diagram of its own - the image above is `Range`'s diagram; `NumericRange` inherits directly from `Range` and adds nothing that would need separate illustration.)* @@ -2970,66 +3047,68 @@ Only valid when `NumericRange` is used directly as a `tasks` dictionary entry. A ##### Validation Rules -**`NumericRange-0000`** (error) - The element fails a JSON Schema constraint attributable to NumericRange that does not match any other numbered rule. +**`NumericRange-0000`** (error) - The element fails a JSON Schema constraint attributable to NumericRange that does not match any other numbered rule. ([source](specsheets/tasks/NumericRange/v1.0.0/validation/NumericRange-0000.md)) > Catch-all rule for schema-pass failures attributable to NumericRange (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`NumericRange-0001`** (error) - When the value of start of a NumericRange is provided directly, it must be a number. +**`NumericRange-0001`** (error) - When the value of start of a NumericRange is provided directly, it must be a number. ([source](specsheets/tasks/NumericRange/v1.0.0/validation/NumericRange-0001.md)) > `start` is `NumberOrRef`: the value, when not a reference, must be a number. -**`NumericRange-0002`** (error) - When the value of start of a NumericRange is a reference, it must be a reference to a number. +**`NumericRange-0002`** (error) - When the value of start of a NumericRange is a reference, it must be a reference to a number. ([source](specsheets/tasks/NumericRange/v1.0.0/validation/NumericRange-0002.md)) > `start` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`NumericRange-0003`** (error) - When the value of end of a NumericRange is provided directly, it must be a number. +**`NumericRange-0003`** (error) - When the value of end of a NumericRange is provided directly, it must be a number. ([source](specsheets/tasks/NumericRange/v1.0.0/validation/NumericRange-0003.md)) > `end` is `NumberOrRef`: the value, when not a reference, must be a number. -**`NumericRange-0004`** (error) - When the value of end of a NumericRange is a reference, it must be a reference to a number. +**`NumericRange-0004`** (error) - When the value of end of a NumericRange is a reference, it must be a reference to a number. ([source](specsheets/tasks/NumericRange/v1.0.0/validation/NumericRange-0004.md)) > `end` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`NumericRange-0005`** (error) - When the value of interval of a NumericRange is provided directly, it must be a positive number (> 0). +**`NumericRange-0005`** (error) - When the value of interval of a NumericRange is provided directly, it must be a positive number (> 0). ([source](specsheets/tasks/NumericRange/v1.0.0/validation/NumericRange-0005.md)) > `interval` is `PositiveDoubleOrRef`: the value, when not a reference, must be a positive number (> 0). -**`NumericRange-0006`** (error) - When the value of interval of a NumericRange is a reference, it must be a reference to a positive number (> 0). +**`NumericRange-0006`** (error) - When the value of interval of a NumericRange is a reference, it must be a reference to a positive number (> 0). ([source](specsheets/tasks/NumericRange/v1.0.0/validation/NumericRange-0006.md)) > `interval` is `PositiveDoubleOrRef`: when the value is a reference, it must resolve to a positive number (> 0). -**`NumericRange-0007`** (error) - When the value of numberOfSteps of a NumericRange is provided directly, it must be a positive integer. +**`NumericRange-0007`** (error) - When the value of numberOfSteps of a NumericRange is provided directly, it must be a positive integer. ([source](specsheets/tasks/NumericRange/v1.0.0/validation/NumericRange-0007.md)) > `numberOfSteps` is `PositiveIntegerOrRef`: the value, when not a reference, must be a positive integer. -**`NumericRange-0008`** (error) - When the value of numberOfSteps of a NumericRange is a reference, it must be a reference to a positive integer. +**`NumericRange-0008`** (error) - When the value of numberOfSteps of a NumericRange is a reference, it must be a reference to a positive integer. ([source](specsheets/tasks/NumericRange/v1.0.0/validation/NumericRange-0008.md)) > `numberOfSteps` is `PositiveIntegerOrRef`: when the value is a reference, it must resolve to a positive integer. -**`NumericRange-0009`** (error) - When the value of scale of a NumericRange is provided directly, it must be one of 'linear', 'log10'. +**`NumericRange-0009`** (error) - When the value of scale of a NumericRange is provided directly, it must be one of 'linear', 'log10'. ([source](specsheets/tasks/NumericRange/v1.0.0/validation/NumericRange-0009.md)) > `ScaleType` is defined in `core/Types` with the allowed values 'linear', 'log10' (see `core/Types/v1.0.0/schema.json`). -**`NumericRange-0010`** (error) - When the value of scale of a NumericRange is a reference, it must be a reference to a valid ScaleType value. +**`NumericRange-0010`** (error) - When the value of scale of a NumericRange is a reference, it must be a reference to a valid ScaleType value. ([source](specsheets/tasks/NumericRange/v1.0.0/validation/NumericRange-0010.md)) > `scale` is `ScaleTypeOrRef`: when the value is a reference, it must resolve to a valid ScaleType value. -**`NumericRange-0011`** (error) - When the value of values of a NumericRange is provided directly, it must be an array of NumberOrRef objects. +**`NumericRange-0011`** (error) - When the value of values of a NumericRange is provided directly, it must be an array of NumberOrRef objects. ([source](specsheets/tasks/NumericRange/v1.0.0/validation/NumericRange-0011.md)) > `values` is `array of NumberOrRef or SIdRef`: the value, when not a reference, must be an array of NumberOrRef objects. -**`NumericRange-0012`** (error) - When the value of values of a NumericRange is a reference, it must be a reference to an array of NumberOrRef objects. +**`NumericRange-0012`** (error) - When the value of values of a NumericRange is a reference, it must be a reference to an array of NumberOrRef objects. ([source](specsheets/tasks/NumericRange/v1.0.0/validation/NumericRange-0012.md)) > `values` is `array of NumberOrRef or SIdRef`: when the value is a reference, it must resolve to an array of NumberOrRef objects. -**`NumericRange-0013`** (error) - The _type attribute of a NumericRange must be "numericRange". +**`NumericRange-0013`** (error) - The _type attribute of a NumericRange must be "numericRange". ([source](specsheets/tasks/NumericRange/v1.0.0/validation/NumericRange-0013.md)) > `_type` is the discriminator field. For `NumericRange` it must always equal `"numericRange"`. #### OneStepODESimulation +*Source: [specsheets/tasks/OneStepODESimulation/v1.0.0/description.md](specsheets/tasks/OneStepODESimulation/v1.0.0/description.md)* + ![OneStepODESimulation UML diagram](specsheets/tasks/OneStepODESimulation/v1.0.0/OneStepODESimulation.png) **Category:** tasks @@ -3143,42 +3222,44 @@ The final values of `outputVariables` after stepping by `independentStep`, acces ##### Validation Rules -**`OneStepODESimulation-0000`** (error) - The element fails a JSON Schema constraint attributable to OneStepODESimulation that does not match any other numbered rule. +**`OneStepODESimulation-0000`** (error) - The element fails a JSON Schema constraint attributable to OneStepODESimulation that does not match any other numbered rule. ([source](specsheets/tasks/OneStepODESimulation/v1.0.0/validation/OneStepODESimulation-0000.md)) > Catch-all rule for schema-pass failures attributable to OneStepODESimulation (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`OneStepODESimulation-0001`** (error) - The model attribute of an OneStepODESimulation is required. +**`OneStepODESimulation-0001`** (error) - The model attribute of an OneStepODESimulation is required. ([source](specsheets/tasks/OneStepODESimulation/v1.0.0/validation/OneStepODESimulation-0001.md)) > `model` is required. -**`OneStepODESimulation-0002`** (error) - The independentVariable attribute of an OneStepODESimulation is required. +**`OneStepODESimulation-0002`** (error) - The independentVariable attribute of an OneStepODESimulation is required. ([source](specsheets/tasks/OneStepODESimulation/v1.0.0/validation/OneStepODESimulation-0002.md)) > `independentVariable` is required. -**`OneStepODESimulation-0003`** (error) - The outputVariables attribute of an OneStepODESimulation is required. +**`OneStepODESimulation-0003`** (error) - The outputVariables attribute of an OneStepODESimulation is required. ([source](specsheets/tasks/OneStepODESimulation/v1.0.0/validation/OneStepODESimulation-0003.md)) > `outputVariables` is required. -**`OneStepODESimulation-0004`** (error) - The independentStep attribute of an OneStepODESimulation is required. +**`OneStepODESimulation-0004`** (error) - The independentStep attribute of an OneStepODESimulation is required. ([source](specsheets/tasks/OneStepODESimulation/v1.0.0/validation/OneStepODESimulation-0004.md)) > `independentStep` is required. -**`OneStepODESimulation-0005`** (error) - When the value of independentStep of an OneStepODESimulation is provided directly, it must be a number. +**`OneStepODESimulation-0005`** (error) - When the value of independentStep of an OneStepODESimulation is provided directly, it must be a number. ([source](specsheets/tasks/OneStepODESimulation/v1.0.0/validation/OneStepODESimulation-0005.md)) > `independentStep` is `NumberOrRef`: the value, when not a reference, must be a number. -**`OneStepODESimulation-0006`** (error) - When the value of independentStep of an OneStepODESimulation is a reference, it must be a reference to a number. +**`OneStepODESimulation-0006`** (error) - When the value of independentStep of an OneStepODESimulation is a reference, it must be a reference to a number. ([source](specsheets/tasks/OneStepODESimulation/v1.0.0/validation/OneStepODESimulation-0006.md)) > `independentStep` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`OneStepODESimulation-0007`** (error) - The _type attribute of an OneStepODESimulation must be "oneStepODE". +**`OneStepODESimulation-0007`** (error) - The _type attribute of an OneStepODESimulation must be "oneStepODE". ([source](specsheets/tasks/OneStepODESimulation/v1.0.0/validation/OneStepODESimulation-0007.md)) > `_type` is the discriminator field. For `OneStepODESimulation` it must always equal `"oneStepODE"`. #### OneStepStochasticSimulation +*Source: [specsheets/tasks/OneStepStochasticSimulation/v1.0.0/description.md](specsheets/tasks/OneStepStochasticSimulation/v1.0.0/description.md)* + ![OneStepStochasticSimulation UML diagram](specsheets/tasks/OneStepStochasticSimulation/v1.0.0/OneStepStochasticSimulation.png) **Category:** tasks @@ -3263,38 +3344,40 @@ Additional possible outputs beyond the three standard ones: ##### Validation Rules -**`OneStepStochasticSimulation-0000`** (error) - The element fails a JSON Schema constraint attributable to OneStepStochasticSimulation that does not match any other numbered rule. +**`OneStepStochasticSimulation-0000`** (error) - The element fails a JSON Schema constraint attributable to OneStepStochasticSimulation that does not match any other numbered rule. ([source](specsheets/tasks/OneStepStochasticSimulation/v1.0.0/validation/OneStepStochasticSimulation-0000.md)) > Catch-all rule for schema-pass failures attributable to OneStepStochasticSimulation (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`OneStepStochasticSimulation-0001`** (error) - The model attribute of an OneStepStochasticSimulation is required. +**`OneStepStochasticSimulation-0001`** (error) - The model attribute of an OneStepStochasticSimulation is required. ([source](specsheets/tasks/OneStepStochasticSimulation/v1.0.0/validation/OneStepStochasticSimulation-0001.md)) > `model` is required. -**`OneStepStochasticSimulation-0002`** (error) - The independentVariable attribute of an OneStepStochasticSimulation is required. +**`OneStepStochasticSimulation-0002`** (error) - The independentVariable attribute of an OneStepStochasticSimulation is required. ([source](specsheets/tasks/OneStepStochasticSimulation/v1.0.0/validation/OneStepStochasticSimulation-0002.md)) > `independentVariable` is required. -**`OneStepStochasticSimulation-0003`** (error) - The outputVariables attribute of an OneStepStochasticSimulation is required. +**`OneStepStochasticSimulation-0003`** (error) - The outputVariables attribute of an OneStepStochasticSimulation is required. ([source](specsheets/tasks/OneStepStochasticSimulation/v1.0.0/validation/OneStepStochasticSimulation-0003.md)) > `outputVariables` is required. -**`OneStepStochasticSimulation-0004`** (error) - When the value of independentStep of an OneStepStochasticSimulation is provided directly, it must be a number. +**`OneStepStochasticSimulation-0004`** (error) - When the value of independentStep of an OneStepStochasticSimulation is provided directly, it must be a number. ([source](specsheets/tasks/OneStepStochasticSimulation/v1.0.0/validation/OneStepStochasticSimulation-0004.md)) > `independentStep` is `NumberOrRef`: the value, when not a reference, must be a number. -**`OneStepStochasticSimulation-0005`** (error) - When the value of independentStep of an OneStepStochasticSimulation is a reference, it must be a reference to a number. +**`OneStepStochasticSimulation-0005`** (error) - When the value of independentStep of an OneStepStochasticSimulation is a reference, it must be a reference to a number. ([source](specsheets/tasks/OneStepStochasticSimulation/v1.0.0/validation/OneStepStochasticSimulation-0005.md)) > `independentStep` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`OneStepStochasticSimulation-0006`** (error) - The _type attribute of an OneStepStochasticSimulation must be "oneStepStochastic". +**`OneStepStochasticSimulation-0006`** (error) - The _type attribute of an OneStepStochasticSimulation must be "oneStepStochastic". ([source](specsheets/tasks/OneStepStochasticSimulation/v1.0.0/validation/OneStepStochasticSimulation-0006.md)) > `_type` is the discriminator field. For `OneStepStochasticSimulation` it must always equal `"oneStepStochastic"`. #### ParameterRange +*Source: [specsheets/tasks/ParameterRange/v1.0.0/description.md](specsheets/tasks/ParameterRange/v1.0.0/description.md)* + ![ParameterRange UML diagram](specsheets/tasks/Range/v1.0.0/Range.png) *(`ParameterRange` has no standalone diagram of its own - the image above is `Range`'s diagram; `ParameterRange` inherits from `Range` (via `NumericRange`) and adds nothing that would need separate illustration.)* @@ -3357,30 +3440,32 @@ Only valid when `ParameterRange` is used directly as a `tasks` dictionary entry. ##### Validation Rules -**`ParameterRange-0000`** (error) - The element fails a JSON Schema constraint attributable to ParameterRange that does not match any other numbered rule. +**`ParameterRange-0000`** (error) - The element fails a JSON Schema constraint attributable to ParameterRange that does not match any other numbered rule. ([source](specsheets/tasks/ParameterRange/v1.0.0/validation/ParameterRange-0000.md)) > Catch-all rule for schema-pass failures attributable to ParameterRange (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`ParameterRange-0001`** (error) - The modelElement attribute of a ParameterRange is required. +**`ParameterRange-0001`** (error) - The modelElement attribute of a ParameterRange is required. ([source](specsheets/tasks/ParameterRange/v1.0.0/validation/ParameterRange-0001.md)) > `modelElement` is required. -**`ParameterRange-0002`** (error) - When the value of modelElement of a ParameterRange is provided directly, it must be a string. +**`ParameterRange-0002`** (error) - When the value of modelElement of a ParameterRange is provided directly, it must be a string. ([source](specsheets/tasks/ParameterRange/v1.0.0/validation/ParameterRange-0002.md)) > `modelElement` is `StringOrRef`: the value, when not a reference, must be a string. -**`ParameterRange-0003`** (error) - When the value of modelElement of a ParameterRange is a reference, it must be a reference to a string. +**`ParameterRange-0003`** (error) - When the value of modelElement of a ParameterRange is a reference, it must be a reference to a string. ([source](specsheets/tasks/ParameterRange/v1.0.0/validation/ParameterRange-0003.md)) > `modelElement` is `StringOrRef`: when the value is a reference, it must resolve to a string. -**`ParameterRange-0016`** (error) - The _type attribute of a ParameterRange must be "parameterRange". +**`ParameterRange-0016`** (error) - The _type attribute of a ParameterRange must be "parameterRange". ([source](specsheets/tasks/ParameterRange/v1.0.0/validation/ParameterRange-0016.md)) > `_type` is the discriminator field. For `ParameterRange` it must always equal `"parameterRange"`. #### ParameterScan +*Source: [specsheets/tasks/ParameterScan/v1.0.0/description.md](specsheets/tasks/ParameterScan/v1.0.0/description.md)* + ![ParameterScan UML diagram](specsheets/tasks/ParameterScan/v1.0.0/ParameterScan.png) **Category:** tasks @@ -3390,7 +3475,7 @@ Only valid when `ParameterRange` is used directly as a `tasks` dictionary entry. ##### What it does -Runs simulations/analyses over several systematically-varied versions of a model: a `Repeat` subclass that adds a `model` child (the model to scan) and one or more `ParameterRange` children (`parameterRanges`) - each scanned element adds a dimension to the output. Each `ParameterRange` must target a distinct `modelElement`, which must be an id within the child `model`. One of the `subTasks` must reference the scan's `model` child (`#tasks:[scanid]:model`) as its own input; the model is initialized with every combination of values across all the ranges. Mechanically it's otherwise identical to `Scatter`, and could in principle be reproduced with nested `Scatter`s plus careful `ModelChange` tasks. +Runs simulations/analyses over several systematically-varied versions of a model: a `Repeat` subclass that adds a `model` child (the model to scan) and one or more `ParameterRange` children (`parameterRanges`) - each scanned element adds a dimension to the output. Each `ParameterRange` must target a distinct `modelElement` (ParameterScan-0007), which must be an id within the child `model`; the `modelElement` also serves as the entry's name in `[id].ranges` and `[id].indexes`. One of the `subTasks` must reference the scan's `model` child (`#tasks:[scanid]:model`) as its own input; the model is initialized with every combination of values across all the ranges. Mechanically it's otherwise identical to `Scatter`, and could in principle be reproduced with nested `Scatter`s plus careful `ModelChange` tasks. Within the loop, the current value and index of each range are available as `[id].ranges` and `[id].indexes` (see Outputs below). ##### Attributes @@ -3417,7 +3502,7 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an **`model`** (SIdRef, required) - _(no description yet - placeholder, needs to be filled in)_ -**`parameterRanges`** (array of ParameterRangeInline, required) - _(no description yet - placeholder, needs to be filled in)_ +**`parameterRanges`** (array of ParameterRangeInline, required) - The ranges to scan; at least one. The `modelElement` of each entry must be distinct within the scan (ParameterScan-0007), and labels that entry in `[id].ranges` and `[id].indexes`. ##### Outputs @@ -3425,7 +3510,7 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an `[id]`: an `AnnotatedData` with one dimension per entry of `parameterRanges`, plus one further dimension sized by the number of entries in `outputVariableMap`. `[id].aggregates`: an `AnnotatedData` following `aggregateOutputVariables`, when defined. - `[id]`: **Valid** - - Dimensions: N-D: one dimension per entry in `parameterRanges` (each sized by that range's own number of steps), plus one further dimension sized by the number of entries in `outputVariableMap` - dimensionality grows with the number of ranges scanned. + - Dimensions: N-D: one dimension per entry in `parameterRanges` (each sized by that range's own number of steps, and each labeled with that range's `modelElement`), plus one further dimension sized by the number of entries in `outputVariableMap` - dimensionality grows with the number of ranges scanned. - `[id].model`: **Invalid** - `[id].strings`: **Invalid** @@ -3434,40 +3519,47 @@ Additional possible outputs beyond the three standard ones: - `[id].aggregates`: An `AnnotatedData` following `aggregateOutputVariables`, when that attribute is defined. - Dimensions: 1D: one entry per `aggregateOutputVariables` mapping. Each entry's aggregation collapses *all* of `[id]`'s scanned-range dimensions together (per `Repeat`, the applied dimension defaults to 'the Repeat' itself - here, the whole combined scan) down to a single value - unless the underlying subTask output was itself multi-dimensional, in which case that dimensionality carries through per entry. +- `[id].ranges`: Within the loop only, the current value of each of the scan's `parameterRanges`. + - Dimensions: 1D `AnnotatedData`: one entry per `ParameterRange` child, in order, labeled with that child's `modelElement`. For example, with children whose `modelElement`s are `calc`, `phos`, and `ant`, it holds the current values of `calc`, `phos`, and `ant`, in that order, labeled accordingly. +- `[id].indexes`: Within the loop only, the current index into each of the scan's `parameterRanges`. + - Dimensions: 1D `AnnotatedData`: one entry per `ParameterRange` child, in order, labeled with that child's `modelElement` - the current index of `calc`, `phos`, and `ant`, in that order, in the example above. + ##### Validation Rules -**`ParameterScan-0000`** (error) - The element fails a JSON Schema constraint attributable to ParameterScan that does not match any other numbered rule. +**`ParameterScan-0000`** (error) - The element fails a JSON Schema constraint attributable to ParameterScan that does not match any other numbered rule. ([source](specsheets/tasks/ParameterScan/v1.0.0/validation/ParameterScan-0000.md)) > Catch-all rule for schema-pass failures attributable to ParameterScan (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`ParameterScan-0001`** (error) - The model attribute of a ParameterScan is required. +**`ParameterScan-0001`** (error) - The model attribute of a ParameterScan is required. ([source](specsheets/tasks/ParameterScan/v1.0.0/validation/ParameterScan-0001.md)) > `model` is required. -**`ParameterScan-0002`** (error) - The model attribute of a ParameterScan, if present, must be a reference (a string starting with '#'). +**`ParameterScan-0002`** (error) - The model attribute of a ParameterScan, if present, must be a reference (a string starting with '#'). ([source](specsheets/tasks/ParameterScan/v1.0.0/validation/ParameterScan-0002.md)) > `model` is `SIdRef` - always a reference, never a literal value. -**`ParameterScan-0003`** (error) - The parameterRanges attribute of a ParameterScan is required. +**`ParameterScan-0003`** (error) - The parameterRanges attribute of a ParameterScan is required. ([source](specsheets/tasks/ParameterScan/v1.0.0/validation/ParameterScan-0003.md)) > `parameterRanges` is required. -**`ParameterScan-0004`** (error) - The parameterRanges attribute of a ParameterScan must be an array of ParameterRangeInline objects. +**`ParameterScan-0004`** (error) - The parameterRanges attribute of a ParameterScan must be an array of ParameterRangeInline objects. ([source](specsheets/tasks/ParameterScan/v1.0.0/validation/ParameterScan-0004.md)) > `parameterRanges` is `array of ParameterRangeInline`: it must be an array of ParameterRangeInline objects. -**`ParameterScan-0005`** (error) - The subTasks attribute of a ParameterScan is required. +**`ParameterScan-0005`** (error) - The subTasks attribute of a ParameterScan is required. ([source](specsheets/tasks/ParameterScan/v1.0.0/validation/ParameterScan-0005.md)) > `subTasks` is required. -**`ParameterScan-0006`** (error) - The _type attribute of a ParameterScan must be "parameterScan". +**`ParameterScan-0006`** (error) - The _type attribute of a ParameterScan must be "parameterScan". ([source](specsheets/tasks/ParameterScan/v1.0.0/validation/ParameterScan-0006.md)) > `_type` is the discriminator field. For `ParameterScan` it must always equal `"parameterScan"`. #### Range +*Source: [specsheets/tasks/Range/v1.0.0/description.md](specsheets/tasks/Range/v1.0.0/description.md)* + ![Range UML diagram](specsheets/tasks/Range/v1.0.0/Range.png) **Category:** tasks @@ -3512,25 +3604,25 @@ Only valid when `Range` is used directly as a `tasks` dictionary entry. As an em ##### Validation Rules -**`Range-0000`** (error) - The element fails a JSON Schema constraint attributable to Range that does not match any other numbered rule. +**`Range-0000`** (error) - The element fails a JSON Schema constraint attributable to Range that does not match any other numbered rule. ([source](specsheets/tasks/Range/v1.0.0/validation/Range-0000.md)) > Catch-all rule for schema-pass failures attributable to Range (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`Range-0001`** (error) - When the value of values of a Range is provided directly, it must be an array of AnyValueOrRef objects. +**`Range-0001`** (error) - When the value of values of a Range is provided directly, it must be an array of AnyValueOrRef objects. ([source](specsheets/tasks/Range/v1.0.0/validation/Range-0001.md)) > `values` is `array of AnyValueOrRef or SIdRef`: the value, when not a reference, must be an array of AnyValueOrRef objects. -**`Range-0002`** (error) - When the value of values of a Range is a reference, it must be a reference to an array of AnyValueOrRef objects. +**`Range-0002`** (error) - When the value of values of a Range is a reference, it must be a reference to an array of AnyValueOrRef objects. ([source](specsheets/tasks/Range/v1.0.0/validation/Range-0002.md)) > `values` is `array of AnyValueOrRef or SIdRef`: when the value is a reference, it must resolve to an array of AnyValueOrRef objects. -**`Range-0003`** (error) - The _type attribute of a Range must be "range". +**`Range-0003`** (error) - The _type attribute of a Range must be "range". ([source](specsheets/tasks/Range/v1.0.0/validation/Range-0003.md)) > `_type` is the discriminator field. For `Range` it must always equal `"range"`. -**`Range-0004`** (error) - A value that must resolve to a concrete Range subtype must declare a _type attribute. +**`Range-0004`** (error) - A value that must resolve to a concrete Range subtype must declare a _type attribute. ([source](specsheets/tasks/Range/v1.0.0/validation/Range-0004.md)) > A narrower case of Range-0000's catch-all: fires specifically when > RangeInline's generated oneOf fails because _type is missing entirely, @@ -3540,6 +3632,8 @@ Only valid when `Range` is used directly as a `tasks` dictionary entry. As an em #### RelabelData +*Source: [specsheets/tasks/RelabelData/v1.0.0/description.md](specsheets/tasks/RelabelData/v1.0.0/description.md)* + ![RelabelData UML diagram](specsheets/tasks/RelabelData/v1.0.0/RelabelData.png) **Category:** tasks @@ -3581,38 +3675,40 @@ The relabeled `AnnotatedData`, accessible as `[id]`. ##### Validation Rules -**`RelabelData-0000`** (error) - The element fails a JSON Schema constraint attributable to RelabelData that does not match any other numbered rule. +**`RelabelData-0000`** (error) - The element fails a JSON Schema constraint attributable to RelabelData that does not match any other numbered rule. ([source](specsheets/tasks/RelabelData/v1.0.0/validation/RelabelData-0000.md)) > Catch-all rule for schema-pass failures attributable to RelabelData (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`RelabelData-0001`** (error) - The input attribute of a RelabelData is required. +**`RelabelData-0001`** (error) - The input attribute of a RelabelData is required. ([source](specsheets/tasks/RelabelData/v1.0.0/validation/RelabelData-0001.md)) > `input` is required. -**`RelabelData-0002`** (error) - The input attribute of a RelabelData, if present, must be a reference (a string starting with '#'). +**`RelabelData-0002`** (error) - The input attribute of a RelabelData, if present, must be a reference (a string starting with '#'). ([source](specsheets/tasks/RelabelData/v1.0.0/validation/RelabelData-0002.md)) > `input` is `SIdRef` - always a reference, never a literal value. -**`RelabelData-0003`** (error) - The labels attribute of a RelabelData is required. +**`RelabelData-0003`** (error) - The labels attribute of a RelabelData is required. ([source](specsheets/tasks/RelabelData/v1.0.0/validation/RelabelData-0003.md)) > `labels` is required. -**`RelabelData-0004`** (error) - When the value of labels of a RelabelData is provided directly, it must be an array of strings. +**`RelabelData-0004`** (error) - When the value of labels of a RelabelData is provided directly, it must be an array of strings. ([source](specsheets/tasks/RelabelData/v1.0.0/validation/RelabelData-0004.md)) > `labels` is `ListOfStringsOrRef`: the value, when not a reference, must be an array of strings. -**`RelabelData-0005`** (error) - When the value of labels of a RelabelData is a reference, it must be a reference to an array of strings. +**`RelabelData-0005`** (error) - When the value of labels of a RelabelData is a reference, it must be a reference to an array of strings. ([source](specsheets/tasks/RelabelData/v1.0.0/validation/RelabelData-0005.md)) > `labels` is `ListOfStringsOrRef`: when the value is a reference, it must resolve to an array of strings. -**`RelabelData-0006`** (error) - The _type attribute of a RelabelData must be "relabelData". +**`RelabelData-0006`** (error) - The _type attribute of a RelabelData must be "relabelData". ([source](specsheets/tasks/RelabelData/v1.0.0/validation/RelabelData-0006.md)) > `_type` is the discriminator field. For `RelabelData` it must always equal `"relabelData"`. #### Repeat +*Source: [specsheets/tasks/Repeat/v1.0.0/description.md](specsheets/tasks/Repeat/v1.0.0/description.md)* + ![Repeat UML diagram](specsheets/tasks/Repeat/v1.0.0/Repeat.png) **Category:** tasks @@ -3623,11 +3719,11 @@ The relabeled `AnnotatedData`, accessible as `[id]`. Like SED-ML Level 1's RepeatedTask, SED2 needs to repeat a group of tasks multiple times. `Repeat` is the set of fields shared by all three concrete subclasses (`Scatter`, `Loop`, `ParameterScan`), composed via `allOf` rather than instantiated on its own - the prose spec calls this abstract concept simply "Repeat". -The repeat's `subTasks` are true children (not references) of the parent, and may depend on each other, on outputs of tasks outside the repeat, or on the repeat's own `range`/`index` (the current iteration's range value and position, available as `[id].range`/`[id].index` - see Outputs below). `outputVariableMap` defines the columns of the repeat's own `[id]` output: the first column is always the range values, and each further named entry maps an output column name to a value produced by a subTask; if empty, `[id]` contains only the range values. `aggregateOutputVariables` defines the columns of `[id].aggregates` - used to efficiently collect running summary statistics (e.g. mean/stdev) across a very large number of repeats without keeping every individual run's output; entries here may not define their own `appliedDimensions` (the applied dimension is always 'the Repeat' itself), and each `input` must reference a subTask's output. +The repeat's `subTasks` are true children (not references) of the parent, and may depend on each other, on outputs of tasks outside the repeat, or on the repeat's own per-iteration outputs (the current iteration's range value and position: `[id].range`/`[id].index` for `Scatter` and `Loop`, `[id].ranges`/`[id].indexes` for `ParameterScan` - see those classes). `outputVariableMap` (optional) defines the columns of the repeat's own `[id]` output: each named entry maps an output column name to a value produced by a subTask. `Scatter` and `Loop` additionally make the first column the range values, so for them `[id]` contains only the range values if `outputVariableMap` is omitted; see each subclass for its exact `[id]` shape. `aggregateOutputVariables` defines the columns of `[id].aggregates` - used to efficiently collect running summary statistics (e.g. mean/stdev) across a very large number of repeats without keeping every individual run's output; entries here may not define their own `appliedDimensions` (the applied dimension is always 'the Repeat' itself), and each `input` must reference a subTask's output. A `Repeat`-derived task must define at least one of `outputVariableMap` or `aggregateOutputVariables`. -`range` (a `Range`/`NumericRange`/`ParameterRange`) is shared here rather than being redefined separately on each subclass - `Loop` and `Scatter` both use it directly; `ParameterScan` does not (it uses `parameterRanges` instead). +`Repeat` itself has no `range`: `Loop` and `Scatter` each define their own required `range` child (a `Range`/`NumericRange`/`ParameterRange`), and `ParameterScan` uses `parameterRanges` instead. ##### Attributes @@ -3636,9 +3732,8 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an | Attribute | Type | Required | Notes | |---|---|---|---| | `subTasks` | object (values: AbstractTask) | no | | -| `outputVariableMap` | object (values: SIdRef) or SIdRef | no | | +| `outputVariableMap` | object (values: SIdRef) or SIdRef | no | Optional, but at least one of this or `aggregateOutputVariables` must be provided (Repeat-0006). | | `aggregateOutputVariables` | object (values: AggregationCalculation) | no | | -| `range` | RangeInline | no | Used by `Loop`/`Scatter`; not used by `ParameterScan` (see `parameterRanges` there instead). | ###### Attribute details @@ -3648,66 +3743,57 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an **`aggregateOutputVariables`** (object (values: AggregationCalculation), optional) - _(no description yet - placeholder, needs to be filled in)_ -**`range`** (RangeInline, optional) - _(no description yet - placeholder, needs to be filled in)_ - ##### Outputs -Not applicable on its own - see `Scatter`, `Loop`, and `ParameterScan` for their concrete output shapes (`[id]` per `outputVariableMap`, `[id].aggregates` per `aggregateOutputVariables`). - -- `[id].range`: Within the loop, the current value of `range`. _(No description yet - placeholder, needs to be filled in: exact reference form and availability when `range` is unset.)_ -- `[id].index`: Within the loop, the current index into `range`. _(No description yet - placeholder, needs to be filled in.)_ +Not applicable on its own - see `Scatter`, `Loop`, and `ParameterScan` for their concrete output shapes (`[id]` per `outputVariableMap`, `[id].aggregates` per `aggregateOutputVariables`). The per-iteration range outputs (`[id].range`/`[id].index` on `Scatter` and `Loop`, `[id].ranges`/`[id].indexes` on `ParameterScan`) belong to those subclasses, not to `Repeat`. Shared mixin for the three `Repeat` subclasses - not instantiated on its own; see `Scatter`, `Loop`, `ParameterScan`. ##### Validation Rules -**`Repeat-0000`** (error) - The element fails a JSON Schema constraint attributable to Repeat that does not match any other numbered rule. +**`Repeat-0000`** (error) - The element fails a JSON Schema constraint attributable to Repeat that does not match any other numbered rule. ([source](specsheets/tasks/Repeat/v1.0.0/validation/Repeat-0000.md)) > Catch-all rule for schema-pass failures attributable to Repeat (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`Repeat-0001`** (error) - The subTasks attribute of a Repeat must be an object whose values are AbstractTask. +**`Repeat-0001`** (error) - The subTasks attribute of a Repeat must be an object whose values are AbstractTask. ([source](specsheets/tasks/Repeat/v1.0.0/validation/Repeat-0001.md)) > `subTasks` is `object (values: AbstractTask)` in Repeat: it must be an object whose values are AbstractTask. -**`Repeat-0002`** (error) - When the value of outputVariableMap of a Repeat is provided directly, it must be an object whose values are SIdRef. +**`Repeat-0002`** (error) - When the value of outputVariableMap of a Repeat is provided directly, it must be an object whose values are SIdRef. ([source](specsheets/tasks/Repeat/v1.0.0/validation/Repeat-0002.md)) > `outputVariableMap` is `object (values: SIdRef) or SIdRef` in Repeat: the value, when not a reference, must be an object whose values are SIdRef. -**`Repeat-0003`** (error) - When the value of outputVariableMap of a Repeat is a reference, it must be a reference to an object whose values are SIdRef. +**`Repeat-0003`** (error) - When the value of outputVariableMap of a Repeat is a reference, it must be a reference to an object whose values are SIdRef. ([source](specsheets/tasks/Repeat/v1.0.0/validation/Repeat-0003.md)) > `outputVariableMap` is `object (values: SIdRef) or SIdRef` in Repeat: when the value is a reference, it must resolve to an object whose values are SIdRef. -**`Repeat-0004`** (error) - The aggregateOutputVariables attribute of a Repeat must be an object whose values are AggregationCalculation. +**`Repeat-0004`** (error) - The aggregateOutputVariables attribute of a Repeat must be an object whose values are AggregationCalculation. ([source](specsheets/tasks/Repeat/v1.0.0/validation/Repeat-0004.md)) > `aggregateOutputVariables` is `object (values: AggregationCalculation)` in Repeat: it must be an object whose values are AggregationCalculation. -**`Repeat-0005`** (error) - The range attribute of a Repeat, if present, must be a RangeInline object. - -> `range` is optional; when present, it must be a `Range`/`NumericRange`/`ParameterRange` object in its embedded `RangeInline` form. - -**`Repeat-0006`** (error) - A Repeat must provide at least one of outputVariableMap or aggregateOutputVariables. +**`Repeat-0006`** (error) - A Repeat must provide at least one of outputVariableMap or aggregateOutputVariables. ([source](specsheets/tasks/Repeat/v1.0.0/validation/Repeat-0006.md)) > Repeat's schema expresses this as an `anyOf` of two single-field `required` > alternatives rather than a flat `required` list, since either field alone > satisfies it. See core-spec.md Section 8 for the `x-anyof-required-rule-id` > keyword that wires this rule to that `anyOf`. -**`Repeat-0008`** (error) - Every value in a Repeat's outputVariableMap must reference one of that Repeat's own subTasks, or an output of one. +**`Repeat-0008`** (error) - Every value in a Repeat's outputVariableMap must reference one of that Repeat's own subTasks, or an output of one. ([source](specsheets/tasks/Repeat/v1.0.0/validation/Repeat-0008.md)) > outputVariableMap defines the columns of the Repeat's [id] output, each > collected from a subTask per iteration. The reference may carry accessors and > indices into the subTask's output (e.g. '#tasks:loop1:subTasks:sim1['S1']'), > checked as usual by SEDBase-0008 through SEDBase-0011. -**`Repeat-0009`** (error) - The input of every entry in a Repeat's aggregateOutputVariables must reference one of that Repeat's own subTasks, or an output of one. +**`Repeat-0009`** (error) - The input of every entry in a Repeat's aggregateOutputVariables must reference one of that Repeat's own subTasks, or an output of one. ([source](specsheets/tasks/Repeat/v1.0.0/validation/Repeat-0009.md)) > Same as Repeat-0008, for the AggregationCalculation entries that define > [id].aggregates. -**`Repeat-0010`** (error) - An entry in a Repeat's aggregateOutputVariables must not define appliedDimensions. +**`Repeat-0010`** (error) - An entry in a Repeat's aggregateOutputVariables must not define appliedDimensions. ([source](specsheets/tasks/Repeat/v1.0.0/validation/Repeat-0010.md)) > Stated in Repeat's description.md. Could instead be expressed in the schema > (a dedicated AggregationCalculation variant without appliedDimensions) and @@ -3716,6 +3802,8 @@ Shared mixin for the three `Repeat` subclasses - not instantiated on its own; se #### Scatter +*Source: [specsheets/tasks/Scatter/v1.0.0/description.md](specsheets/tasks/Scatter/v1.0.0/description.md)* + ![Scatter UML diagram](specsheets/tasks/Scatter/v1.0.0/Scatter.png) **Category:** tasks @@ -3725,7 +3813,7 @@ Shared mixin for the three `Repeat` subclasses - not instantiated on its own; se ##### What it does -A `Repeat` whose iterations are guaranteed fully independent of one another - no subTask output from one iteration feeds into another - so a conforming interpreter may execute the iterations in parallel if it chooses. `range` (a `Range`/`NumericRange`/`ParameterRange`) defines one iteration per element. +A `Repeat` whose iterations are guaranteed fully independent of one another - no subTask output from one iteration feeds into another - so a conforming interpreter may execute the iterations in parallel if it chooses. `range` (a required `Range`/`NumericRange`/`ParameterRange` child) defines one iteration per element. ##### Attributes @@ -3737,7 +3825,7 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an | `subTasks` | object (values: AbstractTask) | yes | | | `outputVariableMap` | object (values: SIdRef) or SIdRef | no | | | `aggregateOutputVariables` | object (values: AggregationCalculation) | no | | -| `range` | RangeInline | no | | +| `range` | RangeInline | yes | | ###### Attribute details @@ -3749,7 +3837,7 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an **`aggregateOutputVariables`** (object (values: AggregationCalculation), optional) - _(no description yet - placeholder, needs to be filled in)_ -**`range`** (RangeInline, optional) - _(no description yet - placeholder, needs to be filled in)_ +**`range`** (RangeInline, required) - _(no description yet - placeholder, needs to be filled in)_ ##### Outputs @@ -3766,29 +3854,31 @@ Additional possible outputs beyond the three standard ones: - `[id].aggregates`: An `AnnotatedData` following `aggregateOutputVariables`, when that attribute is defined. - Dimensions: 1D: one entry per `aggregateOutputVariables` mapping. Each entry's aggregation function collapses the `range` dimension of `[id]` (per `Repeat`, the applied dimension defaults to 'the Repeat' itself, i.e. this one) down to a single value - unless the underlying subTask output was itself multi-dimensional, in which case that dimensionality carries through per entry. -- `[id].range`: Within each iteration, the current value of `range` (see `Repeat`). +- `[id].range`: Within each iteration, the current value of `range`. Always valid, since `range` is required. - Dimensions: Scalar (0-D) per iteration. -- `[id].index`: Within each iteration, the current index into `range`. +- `[id].index`: Within each iteration, the current index into `range`. Always valid. - Dimensions: Scalar (0-D) per iteration. ##### Validation Rules -**`Scatter-0000`** (error) - The element fails a JSON Schema constraint attributable to Scatter that does not match any other numbered rule. +**`Scatter-0000`** (error) - The element fails a JSON Schema constraint attributable to Scatter that does not match any other numbered rule. ([source](specsheets/tasks/Scatter/v1.0.0/validation/Scatter-0000.md)) > Catch-all rule for schema-pass failures attributable to Scatter (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`Scatter-0001`** (error) - The subTasks attribute of a Scatter is required. +**`Scatter-0001`** (error) - The subTasks attribute of a Scatter is required. ([source](specsheets/tasks/Scatter/v1.0.0/validation/Scatter-0001.md)) > `subTasks` is required. -**`Scatter-0003`** (error) - The _type attribute of a Scatter must be "scatter". +**`Scatter-0003`** (error) - The _type attribute of a Scatter must be "scatter". ([source](specsheets/tasks/Scatter/v1.0.0/validation/Scatter-0003.md)) > `_type` is the discriminator field. For `Scatter` it must always equal `"scatter"`. #### Span +*Source: [specsheets/tasks/Span/v1.0.0/description.md](specsheets/tasks/Span/v1.0.0/description.md)* + ![Span UML diagram](specsheets/tasks/Span/v1.0.0/Span.png) **Category:** tasks @@ -3832,42 +3922,44 @@ Not independently referenceable - a `Span` only exists as a named child of the t ##### Validation Rules -**`Span-0000`** (error) - The element fails a JSON Schema constraint attributable to Span that does not match any other numbered rule. +**`Span-0000`** (error) - The element fails a JSON Schema constraint attributable to Span that does not match any other numbered rule. ([source](specsheets/tasks/Span/v1.0.0/validation/Span-0000.md)) > Catch-all rule for schema-pass failures attributable to Span (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`Span-0001`** (error) - The start attribute of a Span is required. +**`Span-0001`** (error) - The start attribute of a Span is required. ([source](specsheets/tasks/Span/v1.0.0/validation/Span-0001.md)) > `start` is required. -**`Span-0002`** (error) - When the value of start of a Span is provided directly, it must be a number. +**`Span-0002`** (error) - When the value of start of a Span is provided directly, it must be a number. ([source](specsheets/tasks/Span/v1.0.0/validation/Span-0002.md)) > `start` is `NumberOrRef`: the value, when not a reference, must be a number. -**`Span-0003`** (error) - When the value of start of a Span is a reference, it must be a reference to a number. +**`Span-0003`** (error) - When the value of start of a Span is a reference, it must be a reference to a number. ([source](specsheets/tasks/Span/v1.0.0/validation/Span-0003.md)) > `start` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`Span-0004`** (error) - The end attribute of a Span is required. +**`Span-0004`** (error) - The end attribute of a Span is required. ([source](specsheets/tasks/Span/v1.0.0/validation/Span-0004.md)) > `end` is required. -**`Span-0005`** (error) - When the value of end of a Span is provided directly, it must be a number. +**`Span-0005`** (error) - When the value of end of a Span is provided directly, it must be a number. ([source](specsheets/tasks/Span/v1.0.0/validation/Span-0005.md)) > `end` is `NumberOrRef`: the value, when not a reference, must be a number. -**`Span-0006`** (error) - When the value of end of a Span is a reference, it must be a reference to a number. +**`Span-0006`** (error) - When the value of end of a Span is a reference, it must be a reference to a number. ([source](specsheets/tasks/Span/v1.0.0/validation/Span-0006.md)) > `end` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`Span-0007`** (error) - The _type attribute of a Span must be "span". +**`Span-0007`** (error) - The _type attribute of a Span must be "span". ([source](specsheets/tasks/Span/v1.0.0/validation/Span-0007.md)) > `_type` is the discriminator field. For `Span` it must always equal `"span"`. #### SteadyState +*Source: [specsheets/tasks/SteadyState/v1.0.0/description.md](specsheets/tasks/SteadyState/v1.0.0/description.md)* + ![SteadyState UML diagram](specsheets/tasks/SteadyState/v1.0.0/SteadyState.png) **Category:** tasks @@ -3879,7 +3971,7 @@ Not independently referenceable - a `Span` only exists as a named child of the t Computes the steady state of a model: where dX/dt = 0 for every varying element X of the model, with respect to the independent variable (usually time). `independentVariable` follows the same rules as the simulation tasks (either the model's own variable, or an implicit URN such as `urn:sedml:symbol:time`). -This is an implementation of KISAO:0000407 (steady-state root-finding method). +This is an implementation of KISAO:0000407 (steady-state root-finding method). The algorithm(s) it uses internally may be listed in the optional `workingAlgorithms` (see `WorkingAlgorithm`). ##### Attributes @@ -3891,7 +3983,7 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an | `model` | SIdRef | yes | | | `independentVariable` | StringOrRef | no | | | `outputVariables` | ListOfStringsOrRef | yes | | -| `outputModel` | BooleanOrRef | no | | +| `workingAlgorithms` | array of WorkingAlgorithm | no | | ###### Attribute details @@ -3903,54 +3995,46 @@ All classes additionally inherit the optional `name`, `description`, `notes`, an **`outputVariables`** (ListOfStringsOrRef, required) - _(no description yet - placeholder, needs to be filled in)_ -**`outputModel`** (BooleanOrRef, optional) - _(no description yet - placeholder, needs to be filled in)_ +**`workingAlgorithms`** (array of WorkingAlgorithm, optional) - _(no description yet - placeholder, needs to be filled in)_ ##### Outputs -The steady-state values of `outputVariables`, accessible as `[id]`. If `outputModel` is `true`, the resulting model state is also available as `[id].model`. +The steady-state values of `outputVariables`, accessible as `[id]`. The resulting model state is always also available as `[id].model`. - `[id]`: **Valid** - Dimensions: 1D: one value per entry of `outputVariables`, at steady state. - `[id].model`: **Valid** - `[id].strings`: **Invalid** -`[id].model` is only produced when `outputModel` is `true`. - ##### Validation Rules -**`SteadyState-0000`** (error) - The element fails a JSON Schema constraint attributable to SteadyState that does not match any other numbered rule. +**`SteadyState-0000`** (error) - The element fails a JSON Schema constraint attributable to SteadyState that does not match any other numbered rule. ([source](specsheets/tasks/SteadyState/v1.0.0/validation/SteadyState-0000.md)) > Catch-all rule for schema-pass failures attributable to SteadyState (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`SteadyState-0001`** (error) - The model attribute of a SteadyState is required. +**`SteadyState-0001`** (error) - The model attribute of a SteadyState is required. ([source](specsheets/tasks/SteadyState/v1.0.0/validation/SteadyState-0001.md)) > `model` is required. -**`SteadyState-0002`** (error) - The outputVariables attribute of a SteadyState is required. +**`SteadyState-0002`** (error) - The outputVariables attribute of a SteadyState is required. ([source](specsheets/tasks/SteadyState/v1.0.0/validation/SteadyState-0002.md)) > `outputVariables` is required. -**`SteadyState-0003`** (error) - The _type attribute of a SteadyState must be "steadyState". +**`SteadyState-0003`** (error) - The _type attribute of a SteadyState must be "steadyState". ([source](specsheets/tasks/SteadyState/v1.0.0/validation/SteadyState-0003.md)) > `_type` is the discriminator field. For `SteadyState` it must always equal `"steadyState"`. -**`SteadyState-0004`** (error) - The independentVariable attribute of a SteadyState, if present, must be a string. +**`SteadyState-0004`** (error) - The independentVariable attribute of a SteadyState, if present, must be a string. ([source](specsheets/tasks/SteadyState/v1.0.0/validation/SteadyState-0004.md)) > `independentVariable` is `StringOrRef`, which resolves to a plain string type; when present, it must be a string. -**`SteadyState-0005`** (error) - When the value of outputModel of a SteadyState is provided directly, it must be a boolean. - -> `outputModel` is `BooleanOrRef`: the value, when not a reference, must be a boolean. - -**`SteadyState-0006`** (error) - When the value of outputModel of a SteadyState is a reference, it must be a reference to a boolean. - -> `outputModel` is `BooleanOrRef`: when the value is a reference, it must resolve to a boolean. - #### StringFormation +*Source: [specsheets/tasks/StringFormation/v1.0.0/description.md](specsheets/tasks/StringFormation/v1.0.0/description.md)* + ![StringFormation UML diagram](specsheets/tasks/StringFormation/v1.0.0/StringFormation.png) **Category:** tasks @@ -3992,25 +4076,25 @@ Open question: the spec text accesses both the single-string and list-of-strings ##### Validation Rules -**`StringFormation-0000`** (error) - The element fails a JSON Schema constraint attributable to StringFormation that does not match any other numbered rule. +**`StringFormation-0000`** (error) - The element fails a JSON Schema constraint attributable to StringFormation that does not match any other numbered rule. ([source](specsheets/tasks/StringFormation/v1.0.0/validation/StringFormation-0000.md)) > Catch-all rule for schema-pass failures attributable to StringFormation (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`StringFormation-0001`** (error) - The concatenate attribute of a StringFormation is required. +**`StringFormation-0001`** (error) - The concatenate attribute of a StringFormation is required. ([source](specsheets/tasks/StringFormation/v1.0.0/validation/StringFormation-0001.md)) > `concatenate` is required. -**`StringFormation-0002`** (error) - When the value of concatenate of a StringFormation is provided directly, it must be an array of values. +**`StringFormation-0002`** (error) - When the value of concatenate of a StringFormation is provided directly, it must be an array of values. ([source](specsheets/tasks/StringFormation/v1.0.0/validation/StringFormation-0002.md)) > `concatenate` is `ListOfAnyOrRef`: the value, when not a reference, must be an array of values. -**`StringFormation-0003`** (error) - When the value of concatenate of a StringFormation is a reference, it must be a reference to an array of values. +**`StringFormation-0003`** (error) - When the value of concatenate of a StringFormation is a reference, it must be a reference to an array of values. ([source](specsheets/tasks/StringFormation/v1.0.0/validation/StringFormation-0003.md)) > `concatenate` is `ListOfAnyOrRef`: when the value is a reference, it must resolve to an array of values. -**`StringFormation-0004`** (error) - The _type attribute of a StringFormation must be "stringFormation". +**`StringFormation-0004`** (error) - The _type attribute of a StringFormation must be "stringFormation". ([source](specsheets/tasks/StringFormation/v1.0.0/validation/StringFormation-0004.md)) > `_type` is the discriminator field. For `StringFormation` it must always equal `"stringFormation"`. @@ -4020,6 +4104,8 @@ Open question: the spec text accesses both the single-string and list-of-strings #### AbstractOutput +*Source: [specsheets/outputs/AbstractOutput/v1.0.0/description.md](specsheets/outputs/AbstractOutput/v1.0.0/description.md)* + ![AbstractOutput UML diagram](specsheets/outputs/AbstractOutput/v1.0.0/AbstractOutput.png) **Category:** outputs @@ -4054,17 +4140,17 @@ By design, nothing - an `AbstractOutput` is always a terminal node and is never ##### Validation Rules -**`AbstractOutput-0000`** (error) - The element fails a JSON Schema constraint attributable to AbstractOutput that does not match any other numbered rule. +**`AbstractOutput-0000`** (error) - The element fails a JSON Schema constraint attributable to AbstractOutput that does not match any other numbered rule. ([source](specsheets/outputs/AbstractOutput/v1.0.0/validation/AbstractOutput-0000.md)) > Catch-all rule for schema-pass failures attributable to AbstractOutput (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`AbstractOutput-0001`** (error) - The outputParameters attribute of an AbstractOutput must be an array of OutputParameter objects. +**`AbstractOutput-0001`** (error) - The outputParameters attribute of an AbstractOutput must be an array of OutputParameter objects. ([source](specsheets/outputs/AbstractOutput/v1.0.0/validation/AbstractOutput-0001.md)) > `outputParameters` is `array of OutputParameter` in AbstractOutputCommon: it must be an array of OutputParameter objects. -**`AbstractOutput-0002`** (error) - A value that must resolve to a concrete AbstractOutput subtype must declare a _type attribute. +**`AbstractOutput-0002`** (error) - A value that must resolve to a concrete AbstractOutput subtype must declare a _type attribute. ([source](specsheets/outputs/AbstractOutput/v1.0.0/validation/AbstractOutput-0002.md)) > A narrower case of AbstractOutput-0000's catch-all: fires specifically when > the generated oneOf fails because _type is missing entirely, rather than @@ -4074,6 +4160,8 @@ By design, nothing - an `AbstractOutput` is always a terminal node and is never #### Plot +*Source: [specsheets/outputs/Plot/v1.0.0/description.md](specsheets/outputs/Plot/v1.0.0/description.md)* + ![Plot UML diagram](specsheets/outputs/Plot/v1.0.0/Plot.png) **Category:** outputs @@ -4117,46 +4205,48 @@ Shared mixin for `Plot2D`/`Plot3D` - not instantiated on its own. Every concrete ##### Validation Rules -**`Plot-0000`** (error) - The element fails a JSON Schema constraint attributable to Plot that does not match any other numbered rule. +**`Plot-0000`** (error) - The element fails a JSON Schema constraint attributable to Plot that does not match any other numbered rule. ([source](specsheets/outputs/Plot/v1.0.0/validation/Plot-0000.md)) > Catch-all rule for schema-pass failures attributable to Plot (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`Plot-0001`** (error) - When the value of legend of a Plot is provided directly, it must be a boolean. +**`Plot-0001`** (error) - When the value of legend of a Plot is provided directly, it must be a boolean. ([source](specsheets/outputs/Plot/v1.0.0/validation/Plot-0001.md)) > `legend` is `BooleanOrRef` in Plot: the value, when not a reference, must be a boolean. -**`Plot-0002`** (error) - When the value of legend of a Plot is a reference, it must be a reference to a boolean. +**`Plot-0002`** (error) - When the value of legend of a Plot is a reference, it must be a reference to a boolean. ([source](specsheets/outputs/Plot/v1.0.0/validation/Plot-0002.md)) > `legend` is `BooleanOrRef` in Plot: when the value is a reference, it must resolve to a boolean. -**`Plot-0003`** (error) - When the value of height of a Plot is provided directly, it must be a number. +**`Plot-0003`** (error) - When the value of height of a Plot is provided directly, it must be a number. ([source](specsheets/outputs/Plot/v1.0.0/validation/Plot-0003.md)) > `height` is `NumberOrRef` in Plot: the value, when not a reference, must be a number. -**`Plot-0004`** (error) - When the value of height of a Plot is a reference, it must be a reference to a number. +**`Plot-0004`** (error) - When the value of height of a Plot is a reference, it must be a reference to a number. ([source](specsheets/outputs/Plot/v1.0.0/validation/Plot-0004.md)) > `height` is `NumberOrRef` in Plot: when the value is a reference, it must resolve to a number. -**`Plot-0005`** (error) - When the value of width of a Plot is provided directly, it must be a number. +**`Plot-0005`** (error) - When the value of width of a Plot is provided directly, it must be a number. ([source](specsheets/outputs/Plot/v1.0.0/validation/Plot-0005.md)) > `width` is `NumberOrRef` in Plot: the value, when not a reference, must be a number. -**`Plot-0006`** (error) - When the value of width of a Plot is a reference, it must be a reference to a number. +**`Plot-0006`** (error) - When the value of width of a Plot is a reference, it must be a reference to a number. ([source](specsheets/outputs/Plot/v1.0.0/validation/Plot-0006.md)) > `width` is `NumberOrRef` in Plot: when the value is a reference, it must resolve to a number. -**`Plot-0007`** (error) - The xAxis attribute of a Plot must be an Axis object. +**`Plot-0007`** (error) - The xAxis attribute of a Plot must be an Axis object. ([source](specsheets/outputs/Plot/v1.0.0/validation/Plot-0007.md)) > `xAxis` is `Axis` in Plot: it must be an Axis object. -**`Plot-0008`** (error) - When the value of yAxis of a Plot is a reference, it must be a reference to a valid one of `"right"`, `"left"` value. +**`Plot-0008`** (error) - When the value of yAxis of a Plot is a reference, it must be a reference to a valid one of `"right"`, `"left"` value. ([source](specsheets/outputs/Plot/v1.0.0/validation/Plot-0008.md)) > `yAxis` is `one of `"right"`, `"left"` or SIdRef` in Plot: when the value is a reference, it must resolve to a valid one of `"right"`, `"left"` value. #### Plot2D +*Source: [specsheets/outputs/Plot2D/v1.0.0/description.md](specsheets/outputs/Plot2D/v1.0.0/description.md)* + ![Plot2D UML diagram](specsheets/outputs/Plot2D/v1.0.0/Plot2D.png) **Category:** outputs @@ -4216,30 +4306,32 @@ Terminal node - see `AbstractOutput`. ##### Validation Rules -**`Plot2D-0000`** (error) - The element fails a JSON Schema constraint attributable to Plot2D that does not match any other numbered rule. +**`Plot2D-0000`** (error) - The element fails a JSON Schema constraint attributable to Plot2D that does not match any other numbered rule. ([source](specsheets/outputs/Plot2D/v1.0.0/validation/Plot2D-0000.md)) > Catch-all rule for schema-pass failures attributable to Plot2D (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`Plot2D-0001`** (error) - The curves attribute of a Plot2D is required. +**`Plot2D-0001`** (error) - The curves attribute of a Plot2D is required. ([source](specsheets/outputs/Plot2D/v1.0.0/validation/Plot2D-0001.md)) > `curves` is required. -**`Plot2D-0002`** (error) - The curves attribute of a Plot2D must be an object whose values are Curve. +**`Plot2D-0002`** (error) - The curves attribute of a Plot2D must be an object whose values are Curve. ([source](specsheets/outputs/Plot2D/v1.0.0/validation/Plot2D-0002.md)) > `curves` is `object (values: Curve)`: it must be an object whose values are Curve. -**`Plot2D-0003`** (error) - The rightYAxis attribute of a Plot2D must be an Axis object. +**`Plot2D-0003`** (error) - The rightYAxis attribute of a Plot2D must be an Axis object. ([source](specsheets/outputs/Plot2D/v1.0.0/validation/Plot2D-0003.md)) > `rightYAxis` is `Axis`: it must be an Axis object. -**`Plot2D-0004`** (error) - The _type attribute of a Plot2D must be "plot2D". +**`Plot2D-0004`** (error) - The _type attribute of a Plot2D must be "plot2D". ([source](specsheets/outputs/Plot2D/v1.0.0/validation/Plot2D-0004.md)) > `_type` is the discriminator field. For `Plot2D` it must always equal `"plot2D"`. #### Plot3D +*Source: [specsheets/outputs/Plot3D/v1.0.0/description.md](specsheets/outputs/Plot3D/v1.0.0/description.md)* + ![Plot3D UML diagram](specsheets/outputs/Plot3D/v1.0.0/Plot3D.png) **Category:** outputs @@ -4299,30 +4391,32 @@ Terminal node - see `AbstractOutput`. ##### Validation Rules -**`Plot3D-0000`** (error) - The element fails a JSON Schema constraint attributable to Plot3D that does not match any other numbered rule. +**`Plot3D-0000`** (error) - The element fails a JSON Schema constraint attributable to Plot3D that does not match any other numbered rule. ([source](specsheets/outputs/Plot3D/v1.0.0/validation/Plot3D-0000.md)) > Catch-all rule for schema-pass failures attributable to Plot3D (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`Plot3D-0001`** (error) - The surfaces attribute of a Plot3D is required. +**`Plot3D-0001`** (error) - The surfaces attribute of a Plot3D is required. ([source](specsheets/outputs/Plot3D/v1.0.0/validation/Plot3D-0001.md)) > `surfaces` is required. -**`Plot3D-0002`** (error) - The surfaces attribute of a Plot3D must be an object whose values are Surface. +**`Plot3D-0002`** (error) - The surfaces attribute of a Plot3D must be an object whose values are Surface. ([source](specsheets/outputs/Plot3D/v1.0.0/validation/Plot3D-0002.md)) > `surfaces` is `object (values: Surface)`: it must be an object whose values are Surface. -**`Plot3D-0003`** (error) - The zAxis attribute of a Plot3D must be an Axis object. +**`Plot3D-0003`** (error) - The zAxis attribute of a Plot3D must be an Axis object. ([source](specsheets/outputs/Plot3D/v1.0.0/validation/Plot3D-0003.md)) > `zAxis` is `Axis`: it must be an Axis object. -**`Plot3D-0004`** (error) - The _type attribute of a Plot3D must be "plot3D". +**`Plot3D-0004`** (error) - The _type attribute of a Plot3D must be "plot3D". ([source](specsheets/outputs/Plot3D/v1.0.0/validation/Plot3D-0004.md)) > `_type` is the discriminator field. For `Plot3D` it must always equal `"plot3D"`. #### Report +*Source: [specsheets/outputs/Report/v1.0.0/description.md](specsheets/outputs/Report/v1.0.0/description.md)* + ![Report UML diagram](specsheets/outputs/Report/v1.0.0/Report.png) **Category:** outputs @@ -4366,26 +4460,28 @@ Terminal node - see `AbstractOutput`. ##### Validation Rules -**`Report-0000`** (error) - The element fails a JSON Schema constraint attributable to Report that does not match any other numbered rule. +**`Report-0000`** (error) - The element fails a JSON Schema constraint attributable to Report that does not match any other numbered rule. ([source](specsheets/outputs/Report/v1.0.0/validation/Report-0000.md)) > Catch-all rule for schema-pass failures attributable to Report (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`Report-0001`** (error) - The data attribute of a Report is required. +**`Report-0001`** (error) - The data attribute of a Report is required. ([source](specsheets/outputs/Report/v1.0.0/validation/Report-0001.md)) > `data` is required. -**`Report-0002`** (error) - The data attribute of a Report, if present, must be a reference (a string starting with '#'). +**`Report-0002`** (error) - The data attribute of a Report, if present, must be a reference (a string starting with '#'). ([source](specsheets/outputs/Report/v1.0.0/validation/Report-0002.md)) > `data` is `SIdRef` - always a reference, never a literal value. -**`Report-0003`** (error) - The _type attribute of a Report must be "report". +**`Report-0003`** (error) - The _type attribute of a Report must be "report". ([source](specsheets/outputs/Report/v1.0.0/validation/Report-0003.md)) > `_type` is the discriminator field. For `Report` it must always equal `"report"`. #### Surface +*Source: [specsheets/outputs/Surface/v1.0.0/description.md](specsheets/outputs/Surface/v1.0.0/description.md)* + ![Surface UML diagram](specsheets/outputs/Surface/v1.0.0/Surface.png) **Category:** outputs @@ -4438,57 +4534,57 @@ Not independently referenceable - only exists as a named child within a `Plot3D` ##### Validation Rules -**`Surface-0000`** (error) - The element fails a JSON Schema constraint attributable to Surface that does not match any other numbered rule. +**`Surface-0000`** (error) - The element fails a JSON Schema constraint attributable to Surface that does not match any other numbered rule. ([source](specsheets/outputs/Surface/v1.0.0/validation/Surface-0000.md)) > Catch-all rule for schema-pass failures attributable to Surface (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`Surface-0001`** (error) - The surfaceType attribute of a Surface is required. +**`Surface-0001`** (error) - The surfaceType attribute of a Surface is required. ([source](specsheets/outputs/Surface/v1.0.0/validation/Surface-0001.md)) > `surfaceType` is required. -**`Surface-0002`** (error) - When the value of surfaceType of a Surface is provided directly, it must be one of 'parametricCurve', 'surfaceMesh', 'surfaceContour', 'contour', 'heatMap', 'stackedCurves', 'bar'. +**`Surface-0002`** (error) - When the value of surfaceType of a Surface is provided directly, it must be one of 'parametricCurve', 'surfaceMesh', 'surfaceContour', 'contour', 'heatMap', 'stackedCurves', 'bar'. ([source](specsheets/outputs/Surface/v1.0.0/validation/Surface-0002.md)) > `SurfaceType` is defined in `core/Types` with the allowed values 'parametricCurve', 'surfaceMesh', 'surfaceContour', 'contour', 'heatMap', 'stackedCurves', 'bar' (see `core/Types/v1.0.0/schema.json`). -**`Surface-0003`** (error) - When the value of surfaceType of a Surface is a reference, it must be a reference to a valid SurfaceType value. +**`Surface-0003`** (error) - When the value of surfaceType of a Surface is a reference, it must be a reference to a valid SurfaceType value. ([source](specsheets/outputs/Surface/v1.0.0/validation/Surface-0003.md)) > `surfaceType` is `SurfaceType or SIdRef`: when the value is a reference, it must resolve to a valid SurfaceType value. -**`Surface-0004`** (error) - The x attribute of a Surface is required. +**`Surface-0004`** (error) - The x attribute of a Surface is required. ([source](specsheets/outputs/Surface/v1.0.0/validation/Surface-0004.md)) > `x` is required. -**`Surface-0005`** (error) - The x attribute of a Surface, if present, must be a reference (a string starting with '#'). +**`Surface-0005`** (error) - The x attribute of a Surface, if present, must be a reference (a string starting with '#'). ([source](specsheets/outputs/Surface/v1.0.0/validation/Surface-0005.md)) > `x` is `SIdRef` - always a reference, never a literal value. -**`Surface-0006`** (error) - The y attribute of a Surface is required. +**`Surface-0006`** (error) - The y attribute of a Surface is required. ([source](specsheets/outputs/Surface/v1.0.0/validation/Surface-0006.md)) > `y` is required. -**`Surface-0007`** (error) - The y attribute of a Surface, if present, must be a reference (a string starting with '#'). +**`Surface-0007`** (error) - The y attribute of a Surface, if present, must be a reference (a string starting with '#'). ([source](specsheets/outputs/Surface/v1.0.0/validation/Surface-0007.md)) > `y` is `SIdRef` - always a reference, never a literal value. -**`Surface-0008`** (error) - The z attribute of a Surface is required. +**`Surface-0008`** (error) - The z attribute of a Surface is required. ([source](specsheets/outputs/Surface/v1.0.0/validation/Surface-0008.md)) > `z` is required. -**`Surface-0009`** (error) - The z attribute of a Surface, if present, must be a reference (a string starting with '#'). +**`Surface-0009`** (error) - The z attribute of a Surface, if present, must be a reference (a string starting with '#'). ([source](specsheets/outputs/Surface/v1.0.0/validation/Surface-0009.md)) > `z` is `SIdRef` - always a reference, never a literal value. -**`Surface-0010`** (error) - The style attribute of a Surface, if present, must be a reference (a string starting with '#'). +**`Surface-0010`** (error) - The style attribute of a Surface, if present, must be a reference (a string starting with '#'). ([source](specsheets/outputs/Surface/v1.0.0/validation/Surface-0010.md)) > `style` is `SIdRef` - always a reference, never a literal value. -**`Surface-0011`** (error) - When the value of order of a Surface is provided directly, it must be a non-negative integer. +**`Surface-0011`** (error) - When the value of order of a Surface is provided directly, it must be a non-negative integer. ([source](specsheets/outputs/Surface/v1.0.0/validation/Surface-0011.md)) > `order` is `NonNegativeIntegerOrRef`: the value, when not a reference, must be a non-negative integer. -**`Surface-0012`** (error) - When the value of order of a Surface is a reference, it must be a reference to a non-negative integer. +**`Surface-0012`** (error) - When the value of order of a Surface is a reference, it must be a reference to a non-negative integer. ([source](specsheets/outputs/Surface/v1.0.0/validation/Surface-0012.md)) > `order` is `NonNegativeIntegerOrRef`: when the value is a reference, it must resolve to a non-negative integer. @@ -4498,6 +4594,8 @@ Not independently referenceable - only exists as a named child within a `Plot3D` #### AbstractCurve +*Source: [specsheets/auxiliary/AbstractCurve/v1.0.0/description.md](specsheets/auxiliary/AbstractCurve/v1.0.0/description.md)* + ![AbstractCurve UML diagram](specsheets/auxiliary/AbstractCurve/v1.0.0/AbstractCurve.png) **Category:** auxiliary @@ -4544,41 +4642,41 @@ Not independently referenceable - `AbstractCurve` is never used directly; only i ##### Validation Rules -**`AbstractCurve-0000`** (error) - The element fails a JSON Schema constraint attributable to AbstractCurve that does not match any other numbered rule. +**`AbstractCurve-0000`** (error) - The element fails a JSON Schema constraint attributable to AbstractCurve that does not match any other numbered rule. ([source](specsheets/auxiliary/AbstractCurve/v1.0.0/validation/AbstractCurve-0000.md)) > Catch-all rule for schema-pass failures attributable to AbstractCurve (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`AbstractCurve-0001`** (error) - The x attribute of an AbstractCurve is required. +**`AbstractCurve-0001`** (error) - The x attribute of an AbstractCurve is required. ([source](specsheets/auxiliary/AbstractCurve/v1.0.0/validation/AbstractCurve-0001.md)) > `x` is required. -**`AbstractCurve-0002`** (error) - The x attribute of an AbstractCurve, if present, must be a reference (a string starting with '#'). +**`AbstractCurve-0002`** (error) - The x attribute of an AbstractCurve, if present, must be a reference (a string starting with '#'). ([source](specsheets/auxiliary/AbstractCurve/v1.0.0/validation/AbstractCurve-0002.md)) > `x` is `SIdRef` in AbstractCurveCommon - always a reference, never a literal value. -**`AbstractCurve-0003`** (error) - When the value of order of an AbstractCurve is provided directly, it must be a non-negative integer. +**`AbstractCurve-0003`** (error) - When the value of order of an AbstractCurve is provided directly, it must be a non-negative integer. ([source](specsheets/auxiliary/AbstractCurve/v1.0.0/validation/AbstractCurve-0003.md)) > `order` is `NonNegativeIntegerOrRef` in AbstractCurveCommon: the value, when not a reference, must be a non-negative integer. -**`AbstractCurve-0004`** (error) - When the value of order of an AbstractCurve is a reference, it must be a reference to a non-negative integer. +**`AbstractCurve-0004`** (error) - When the value of order of an AbstractCurve is a reference, it must be a reference to a non-negative integer. ([source](specsheets/auxiliary/AbstractCurve/v1.0.0/validation/AbstractCurve-0004.md)) > `order` is `NonNegativeIntegerOrRef` in AbstractCurveCommon: when the value is a reference, it must resolve to a non-negative integer. -**`AbstractCurve-0005`** (error) - The style attribute of an AbstractCurve, if present, must be a reference (a string starting with '#'). +**`AbstractCurve-0005`** (error) - The style attribute of an AbstractCurve, if present, must be a reference (a string starting with '#'). ([source](specsheets/auxiliary/AbstractCurve/v1.0.0/validation/AbstractCurve-0005.md)) > `style` is `SIdRef` in AbstractCurveCommon - always a reference, never a literal value. -**`AbstractCurve-0006`** (error) - When the value of yAxis of an AbstractCurve is provided directly, it must be one of 'right' or 'left'. +**`AbstractCurve-0006`** (error) - When the value of yAxis of an AbstractCurve is provided directly, it must be one of 'right' or 'left'. ([source](specsheets/auxiliary/AbstractCurve/v1.0.0/validation/AbstractCurve-0006.md)) > `yAxis` is `one of "right", "left" or SIdRef` in AbstractCurveCommon: the value, when not a reference, must be one of 'right' or 'left'. -**`AbstractCurve-0007`** (error) - When the value of yAxis of an AbstractCurve is a reference, it must be a reference to one of 'right' or 'left'. +**`AbstractCurve-0007`** (error) - When the value of yAxis of an AbstractCurve is a reference, it must be a reference to one of 'right' or 'left'. ([source](specsheets/auxiliary/AbstractCurve/v1.0.0/validation/AbstractCurve-0007.md)) > `yAxis` is `one of "right", "left" or SIdRef` in AbstractCurveCommon: when the value is a reference, it must resolve to one of 'right' or 'left'. -**`AbstractCurve-0008`** (error) - A value that must resolve to a concrete AbstractCurve subtype must declare a _type attribute. +**`AbstractCurve-0008`** (error) - A value that must resolve to a concrete AbstractCurve subtype must declare a _type attribute. ([source](specsheets/auxiliary/AbstractCurve/v1.0.0/validation/AbstractCurve-0008.md)) > A narrower case of AbstractCurve-0000's catch-all: fires specifically when > the generated oneOf fails because _type is missing entirely, rather than @@ -4588,6 +4686,8 @@ Not independently referenceable - `AbstractCurve` is never used directly; only i #### Annotation +*Source: [specsheets/auxiliary/Annotation/v1.0.0/description.md](specsheets/auxiliary/Annotation/v1.0.0/description.md)* + ![Annotation UML diagram](specsheets/core/SEDBase/v1.0.0/SEDBase.png) *(`Annotation` has no standalone diagram of its own - the image above is `SEDBase`'s diagram, reused here because `Annotation` is drawn fully within it as a linked box, right next to `SEDBase`. Look for the `Annotation` box.)* @@ -4630,26 +4730,28 @@ Not independently referenceable - only exists as an entry in its parent element' ##### Validation Rules -**`Annotation-0000`** (error) - The element fails a JSON Schema constraint attributable to Annotation that does not match any other numbered rule. +**`Annotation-0000`** (error) - The element fails a JSON Schema constraint attributable to Annotation that does not match any other numbered rule. ([source](specsheets/auxiliary/Annotation/v1.0.0/validation/Annotation-0000.md)) > Catch-all rule for schema-pass failures attributable to Annotation (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`Annotation-0001`** (error) - The qualifier attribute of an Annotation is required. +**`Annotation-0001`** (error) - The qualifier attribute of an Annotation is required. ([source](specsheets/auxiliary/Annotation/v1.0.0/validation/Annotation-0001.md)) > `qualifier` is required. -**`Annotation-0002`** (error) - The qualifier attribute of an Annotation must be a Qualifier string (a 'namespace:term' pair). +**`Annotation-0002`** (error) - The qualifier attribute of an Annotation must be a Qualifier string (a 'namespace:term' pair). ([source](specsheets/auxiliary/Annotation/v1.0.0/validation/Annotation-0002.md)) > `qualifier` is `Qualifier`: it must be a Qualifier string (a 'namespace:term' pair). -**`Annotation-0003`** (error) - The value attribute of an Annotation is required. +**`Annotation-0003`** (error) - The value attribute of an Annotation is required. ([source](specsheets/auxiliary/Annotation/v1.0.0/validation/Annotation-0003.md)) > `value` is required. #### Axis +*Source: [specsheets/auxiliary/Axis/v1.0.0/description.md](specsheets/auxiliary/Axis/v1.0.0/description.md)* + ![Axis UML diagram](specsheets/outputs/Plot/v1.0.0/Plot.png) *(`Axis` has no standalone diagram of its own - the image above is `Plot`'s diagram, reused here because `Axis` is drawn fully within it as a linked box, right next to `Plot`. Look for the `Axis` box.)* @@ -4704,58 +4806,60 @@ Not independently referenceable - only exists as a named child of a `Plot`-deriv ##### Validation Rules -**`Axis-0000`** (error) - The element fails a JSON Schema constraint attributable to Axis that does not match any other numbered rule. +**`Axis-0000`** (error) - The element fails a JSON Schema constraint attributable to Axis that does not match any other numbered rule. ([source](specsheets/auxiliary/Axis/v1.0.0/validation/Axis-0000.md)) > Catch-all rule for schema-pass failures attributable to Axis (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`Axis-0001`** (error) - When the value of scale of an Axis is provided directly, it must be one of 'linear', 'log10'. +**`Axis-0001`** (error) - When the value of scale of an Axis is provided directly, it must be one of 'linear', 'log10'. ([source](specsheets/auxiliary/Axis/v1.0.0/validation/Axis-0001.md)) > `ScaleType` is defined in `core/Types` with the allowed values 'linear', 'log10' (see `core/Types/v1.0.0/schema.json`). -**`Axis-0002`** (error) - When the value of scale of an Axis is a reference, it must be a reference to a valid ScaleType value. +**`Axis-0002`** (error) - When the value of scale of an Axis is a reference, it must be a reference to a valid ScaleType value. ([source](specsheets/auxiliary/Axis/v1.0.0/validation/Axis-0002.md)) > `scale` is `ScaleTypeOrRef`: when the value is a reference, it must resolve to a valid ScaleType value. -**`Axis-0003`** (error) - When the value of min of an Axis is provided directly, it must be a number. +**`Axis-0003`** (error) - When the value of min of an Axis is provided directly, it must be a number. ([source](specsheets/auxiliary/Axis/v1.0.0/validation/Axis-0003.md)) > `min` is `NumberOrRef`: the value, when not a reference, must be a number. -**`Axis-0004`** (error) - When the value of min of an Axis is a reference, it must be a reference to a number. +**`Axis-0004`** (error) - When the value of min of an Axis is a reference, it must be a reference to a number. ([source](specsheets/auxiliary/Axis/v1.0.0/validation/Axis-0004.md)) > `min` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`Axis-0005`** (error) - When the value of max of an Axis is provided directly, it must be a number. +**`Axis-0005`** (error) - When the value of max of an Axis is provided directly, it must be a number. ([source](specsheets/auxiliary/Axis/v1.0.0/validation/Axis-0005.md)) > `max` is `NumberOrRef`: the value, when not a reference, must be a number. -**`Axis-0006`** (error) - When the value of max of an Axis is a reference, it must be a reference to a number. +**`Axis-0006`** (error) - When the value of max of an Axis is a reference, it must be a reference to a number. ([source](specsheets/auxiliary/Axis/v1.0.0/validation/Axis-0006.md)) > `max` is `NumberOrRef`: when the value is a reference, it must resolve to a number. -**`Axis-0007`** (error) - When the value of grid of an Axis is provided directly, it must be a boolean. +**`Axis-0007`** (error) - When the value of grid of an Axis is provided directly, it must be a boolean. ([source](specsheets/auxiliary/Axis/v1.0.0/validation/Axis-0007.md)) > `grid` is `BooleanOrRef`: the value, when not a reference, must be a boolean. -**`Axis-0008`** (error) - When the value of grid of an Axis is a reference, it must be a reference to a boolean. +**`Axis-0008`** (error) - When the value of grid of an Axis is a reference, it must be a reference to a boolean. ([source](specsheets/auxiliary/Axis/v1.0.0/validation/Axis-0008.md)) > `grid` is `BooleanOrRef`: when the value is a reference, it must resolve to a boolean. -**`Axis-0009`** (error) - The style attribute of an Axis, if present, must be a reference (a string starting with '#'). +**`Axis-0009`** (error) - The style attribute of an Axis, if present, must be a reference (a string starting with '#'). ([source](specsheets/auxiliary/Axis/v1.0.0/validation/Axis-0009.md)) > `style` is `SIdRef` - always a reference, never a literal value. -**`Axis-0010`** (error) - When the value of reverse of an Axis is provided directly, it must be a boolean. +**`Axis-0010`** (error) - When the value of reverse of an Axis is provided directly, it must be a boolean. ([source](specsheets/auxiliary/Axis/v1.0.0/validation/Axis-0010.md)) > `reverse` is `BooleanOrRef`: the value, when not a reference, must be a boolean. -**`Axis-0011`** (error) - When the value of reverse of an Axis is a reference, it must be a reference to a boolean. +**`Axis-0011`** (error) - When the value of reverse of an Axis is a reference, it must be a reference to a boolean. ([source](specsheets/auxiliary/Axis/v1.0.0/validation/Axis-0011.md)) > `reverse` is `BooleanOrRef`: when the value is a reference, it must resolve to a boolean. #### Curve +*Source: [specsheets/auxiliary/Curve/v1.0.0/description.md](specsheets/auxiliary/Curve/v1.0.0/description.md)* + ![Curve UML diagram](specsheets/auxiliary/AbstractCurve/v1.0.0/AbstractCurve.png) *(`Curve` has no standalone diagram of its own - the image above is `AbstractCurve`'s diagram, which already draws `Curve` directly as `AbstractCurve`'s one concrete subclass.)* @@ -4833,65 +4937,65 @@ Not independently referenceable - only exists as a named child within a `Plot2D` ##### Validation Rules -**`Curve-0000`** (error) - The element fails a JSON Schema constraint attributable to Curve that does not match any other numbered rule. +**`Curve-0000`** (error) - The element fails a JSON Schema constraint attributable to Curve that does not match any other numbered rule. ([source](specsheets/auxiliary/Curve/v1.0.0/validation/Curve-0000.md)) > Catch-all rule for schema-pass failures attributable to Curve (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`Curve-0001`** (error) - The curveType attribute of a Curve is required. +**`Curve-0001`** (error) - The curveType attribute of a Curve is required. ([source](specsheets/auxiliary/Curve/v1.0.0/validation/Curve-0001.md)) > `curveType` is required. -**`Curve-0002`** (error) - When the value of curveType of a Curve is provided directly, it must be one of 'points', 'bar', 'barStacked', 'horizontalBar', 'horizontalBarStacked', 'shadedArea'. +**`Curve-0002`** (error) - When the value of curveType of a Curve is provided directly, it must be one of 'points', 'bar', 'barStacked', 'horizontalBar', 'horizontalBarStacked', 'shadedArea'. ([source](specsheets/auxiliary/Curve/v1.0.0/validation/Curve-0002.md)) > `CurveType` is defined in `core/Types` with the allowed values 'points', 'bar', 'barStacked', 'horizontalBar', 'horizontalBarStacked', 'shadedArea' (see `core/Types/v1.0.0/schema.json`). -**`Curve-0003`** (error) - When the value of curveType of a Curve is a reference, it must be a reference to a valid CurveType value. +**`Curve-0003`** (error) - When the value of curveType of a Curve is a reference, it must be a reference to a valid CurveType value. ([source](specsheets/auxiliary/Curve/v1.0.0/validation/Curve-0003.md)) > `curveType` is `CurveType or SIdRef`: when the value is a reference, it must resolve to a valid CurveType value. -**`Curve-0004`** (error) - The y attribute of a Curve is required. +**`Curve-0004`** (error) - The y attribute of a Curve is required. ([source](specsheets/auxiliary/Curve/v1.0.0/validation/Curve-0004.md)) > `y` is required. -**`Curve-0005`** (error) - The y attribute of a Curve, if present, must be a reference (a string starting with '#'). +**`Curve-0005`** (error) - The y attribute of a Curve, if present, must be a reference (a string starting with '#'). ([source](specsheets/auxiliary/Curve/v1.0.0/validation/Curve-0005.md)) > `y` is `SIdRef` - always a reference, never a literal value. -**`Curve-0006`** (error) - The xErrorUpper attribute of a Curve, if present, must be a reference (a string starting with '#'). +**`Curve-0006`** (error) - The xErrorUpper attribute of a Curve, if present, must be a reference (a string starting with '#'). ([source](specsheets/auxiliary/Curve/v1.0.0/validation/Curve-0006.md)) > `xErrorUpper` is `SIdRef` - always a reference, never a literal value. -**`Curve-0007`** (error) - The xErrorLower attribute of a Curve, if present, must be a reference (a string starting with '#'). +**`Curve-0007`** (error) - The xErrorLower attribute of a Curve, if present, must be a reference (a string starting with '#'). ([source](specsheets/auxiliary/Curve/v1.0.0/validation/Curve-0007.md)) > `xErrorLower` is `SIdRef` - always a reference, never a literal value. -**`Curve-0008`** (error) - The yErrorUpper attribute of a Curve, if present, must be a reference (a string starting with '#'). +**`Curve-0008`** (error) - The yErrorUpper attribute of a Curve, if present, must be a reference (a string starting with '#'). ([source](specsheets/auxiliary/Curve/v1.0.0/validation/Curve-0008.md)) > `yErrorUpper` is `SIdRef` - always a reference, never a literal value. -**`Curve-0009`** (error) - The yErrorLower attribute of a Curve, if present, must be a reference (a string starting with '#'). +**`Curve-0009`** (error) - The yErrorLower attribute of a Curve, if present, must be a reference (a string starting with '#'). ([source](specsheets/auxiliary/Curve/v1.0.0/validation/Curve-0009.md)) > `yErrorLower` is `SIdRef` - always a reference, never a literal value. -**`Curve-0010`** (error) - The yFrom attribute of a Curve, if present, must be a reference (a string starting with '#'). +**`Curve-0010`** (error) - The yFrom attribute of a Curve, if present, must be a reference (a string starting with '#'). ([source](specsheets/auxiliary/Curve/v1.0.0/validation/Curve-0010.md)) > `yFrom` is `SIdRef` - always a reference, never a literal value. -**`Curve-0011`** (error) - The yTo attribute of a Curve, if present, must be a reference (a string starting with '#'). +**`Curve-0011`** (error) - The yTo attribute of a Curve, if present, must be a reference (a string starting with '#'). ([source](specsheets/auxiliary/Curve/v1.0.0/validation/Curve-0011.md)) > `yTo` is `SIdRef` - always a reference, never a literal value. -**`Curve-0012`** (error) - The _type attribute of a Curve must be "curve". +**`Curve-0012`** (error) - The _type attribute of a Curve must be "curve". ([source](specsheets/auxiliary/Curve/v1.0.0/validation/Curve-0012.md)) > `_type` is the discriminator field. For `Curve` it must always equal `"curve"`. #### LoopVariable -![LoopVariable UML diagram](specsheets/tasks/Loop/v1.0.0/Loop.png) +*Source: [specsheets/auxiliary/LoopVariable/v1.0.0/description.md](specsheets/auxiliary/LoopVariable/v1.0.0/description.md)* -*(`LoopVariable` has no standalone diagram of its own - the image above is `Loop`'s diagram, reused here because `LoopVariable` is drawn fully within it as a linked box, right next to `Loop`. Look for the `LoopVariable` box.)* +![LoopVariable UML diagram](specsheets/auxiliary/LoopVariable/v1.0.0/LoopVariable.png) **Category:** auxiliary **Version:** v1 @@ -4934,25 +5038,25 @@ Not independently referenceable outside its parent `Loop`. ##### Validation Rules -**`LoopVariable-0000`** (error) - The element fails a JSON Schema constraint attributable to LoopVariable that does not match any other numbered rule. +**`LoopVariable-0000`** (error) - The element fails a JSON Schema constraint attributable to LoopVariable that does not match any other numbered rule. ([source](specsheets/auxiliary/LoopVariable/v1.0.0/validation/LoopVariable-0000.md)) > Catch-all rule for schema-pass failures attributable to LoopVariable (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`LoopVariable-0001`** (error) - The initialValue attribute of a LoopVariable is required. +**`LoopVariable-0001`** (error) - The initialValue attribute of a LoopVariable is required. ([source](specsheets/auxiliary/LoopVariable/v1.0.0/validation/LoopVariable-0001.md)) > `initialValue` is required. -**`LoopVariable-0002`** (error) - The subsequentValues attribute of a LoopVariable is required. +**`LoopVariable-0002`** (error) - The subsequentValues attribute of a LoopVariable is required. ([source](specsheets/auxiliary/LoopVariable/v1.0.0/validation/LoopVariable-0002.md)) > `subsequentValues` is required. -**`LoopVariable-0003`** (error) - The subsequentValues attribute of a LoopVariable, if present, must be a reference (a string starting with '#'). +**`LoopVariable-0003`** (error) - The subsequentValues attribute of a LoopVariable, if present, must be a reference (a string starting with '#'). ([source](specsheets/auxiliary/LoopVariable/v1.0.0/validation/LoopVariable-0003.md)) > `subsequentValues` is `SIdRef` - always a reference, never a literal value. -**`LoopVariable-0004`** (error) - The subsequentValues of a LoopVariable must reference one of its enclosing Loop's own subTasks, or an output of one. +**`LoopVariable-0004`** (error) - The subsequentValues of a LoopVariable must reference one of its enclosing Loop's own subTasks, or an output of one. ([source](specsheets/auxiliary/LoopVariable/v1.0.0/validation/LoopVariable-0004.md)) > subsequentValues is the value this loop variable takes on after each > iteration, produced by one of the loop's own subTasks. This is the one place @@ -4961,6 +5065,8 @@ Not independently referenceable outside its parent `Loop`. #### OutputParameter +*Source: [specsheets/auxiliary/OutputParameter/v1.0.0/description.md](specsheets/auxiliary/OutputParameter/v1.0.0/description.md)* + ![OutputParameter UML diagram](specsheets/outputs/AbstractOutput/v1.0.0/AbstractOutput.png) *(`OutputParameter` has no standalone diagram of its own - the image above is `AbstractOutput`'s diagram, reused here because `OutputParameter` is drawn fully within it as a linked box, right next to `AbstractOutput`. Look for the `OutputParameter` box.)* @@ -5000,18 +5106,20 @@ Not independently referenceable - only exists as an entry in its parent output's ##### Validation Rules -**`OutputParameter-0000`** (error) - The element fails a JSON Schema constraint attributable to OutputParameter that does not match any other numbered rule. +**`OutputParameter-0000`** (error) - The element fails a JSON Schema constraint attributable to OutputParameter that does not match any other numbered rule. ([source](specsheets/auxiliary/OutputParameter/v1.0.0/validation/OutputParameter-0000.md)) > Catch-all rule for schema-pass failures attributable to OutputParameter (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`OutputParameter-0001`** (error) - The value attribute of an OutputParameter is required. +**`OutputParameter-0001`** (error) - The value attribute of an OutputParameter is required. ([source](specsheets/auxiliary/OutputParameter/v1.0.0/validation/OutputParameter-0001.md)) > `value` is required. Its type is `AnyValueOrRef` - any JSON value or a reference is accepted, so no separate type rule applies beyond presence. #### TaskParameter +*Source: [specsheets/auxiliary/TaskParameter/v1.0.0/description.md](specsheets/auxiliary/TaskParameter/v1.0.0/description.md)* + ![TaskParameter UML diagram](specsheets/tasks/AbstractTask/v1.0.0/AbstractTask.png) *(`TaskParameter` has no standalone diagram of its own - the image above is `AbstractTask`'s diagram, reused here because `TaskParameter` is drawn fully within it as a linked box, right next to `AbstractTask`. Look for the `TaskParameter` box.)* @@ -5051,21 +5159,21 @@ Not independently referenceable - only exists as an entry in its parent task's ` ##### Validation Rules -**`TaskParameter-0000`** (error) - The element fails a JSON Schema constraint attributable to TaskParameter that does not match any other numbered rule. +**`TaskParameter-0000`** (error) - The element fails a JSON Schema constraint attributable to TaskParameter that does not match any other numbered rule. ([source](specsheets/auxiliary/TaskParameter/v1.0.0/validation/TaskParameter-0000.md)) > Catch-all rule for schema-pass failures attributable to TaskParameter (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`TaskParameter-0001`** (error) - The value attribute of a TaskParameter is required. +**`TaskParameter-0001`** (error) - The value attribute of a TaskParameter is required. ([source](specsheets/auxiliary/TaskParameter/v1.0.0/validation/TaskParameter-0001.md)) > `value` is required. Its type is `AnyValueOrRef` - any JSON value or a reference is accepted, so no separate type rule applies beyond presence. #### WorkingAlgorithm -![WorkingAlgorithm UML diagram](specsheets/tasks/AbstractSimulation/v1.0.0/AbstractSimulation.png) +*Source: [specsheets/auxiliary/WorkingAlgorithm/v1.0.0/description.md](specsheets/auxiliary/WorkingAlgorithm/v1.0.0/description.md)* -*(`WorkingAlgorithm` has no standalone diagram of its own - the image above is `AbstractSimulation`'s diagram, reused here because `WorkingAlgorithm` is drawn fully within it as a linked box, right next to `AbstractSimulation`. Look for the `workingAlgorithm` box.)* +![WorkingAlgorithm UML diagram](specsheets/auxiliary/WorkingAlgorithm/v1.0.0/WorkingAlgorithm.png) **Category:** auxiliary **Version:** v1 @@ -5073,7 +5181,7 @@ Not independently referenceable - only exists as an entry in its parent task's ` ##### What it does -An algorithm used internally by a simulation task, attached via `AbstractSimulation`'s `workingAlgorithms` list. Beyond the fields it inherits from `SEDBase`, it carries a required `algorithm`. +An algorithm used internally by a task, attached via a `workingAlgorithms` list: the one `AbstractSimulation` defines (and so every ODE/stochastic simulation task has), or the one `SteadyState` and `FluxBalanceAnalysis` each declare directly. Beyond the fields it inherits from `SEDBase`, it carries a required `algorithm`. _(No description yet - placeholder. It's not yet clear from the diagram alone how `algorithm` relates to the task's own `_type` discriminator and `taskParameters`, or how multiple `workingAlgorithms` entries on one task are meant to be distinguished/used - needs updating once that's settled.)_ @@ -5104,13 +5212,13 @@ Not independently referenceable - only exists as an entry in its parent task's ` ##### Validation Rules -**`WorkingAlgorithm-0000`** (error) - The element fails a JSON Schema constraint attributable to WorkingAlgorithm that does not match any other numbered rule. +**`WorkingAlgorithm-0000`** (error) - The element fails a JSON Schema constraint attributable to WorkingAlgorithm that does not match any other numbered rule. ([source](specsheets/auxiliary/WorkingAlgorithm/v1.0.0/validation/WorkingAlgorithm-0000.md)) > Catch-all rule for schema-pass failures attributable to WorkingAlgorithm (or a > more specific descendant whose own class's failure location can't be > resolved to any other numbered rule). See Design.md, Schema-Pass Errors. -**`WorkingAlgorithm-0001`** (error) - The algorithm attribute of a WorkingAlgorithm is required. +**`WorkingAlgorithm-0001`** (error) - The algorithm attribute of a WorkingAlgorithm is required. ([source](specsheets/auxiliary/WorkingAlgorithm/v1.0.0/validation/WorkingAlgorithm-0001.md)) > `algorithm` is required. Its type is `StringOrRef` - a string value or a reference to one. diff --git a/generated/cpp/include/libsed2/GeneratedModel.hpp b/generated/cpp/include/libsed2/GeneratedModel.hpp index 76d98a5..903a67c 100644 --- a/generated/cpp/include/libsed2/GeneratedModel.hpp +++ b/generated/cpp/include/libsed2/GeneratedModel.hpp @@ -208,7 +208,7 @@ class AggregationCalculation : public SedBase { std::string class_name() const override { return "AggregationCalculation"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":{\"source\":\"static\",\"expr\":\"shapeOf(input) - dim(appliedDimensions or outermost)\"}},\"[id].model\":{\"valid\":false},\"[id].strings\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":{\"source\":\"static\",\"expr\":\"shapeOf(input) - dim(appliedDimensions or outermost)\"}}}}"); return &j; } std::optional get_type_value() const override { return std::string("aggregationCalculation"); } @@ -329,7 +329,7 @@ class BoundedODESimulation : public SedBase { std::string class_name() const override { return "BoundedODESimulation"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"runtime\"},\"labels\":null},{\"size\":{\"source\":\"static\",\"expr\":\"1 + len(outputVariables)\"},\"labels\":{\"source\":\"static\",\"expr\":\"[independentVariable] + outputVariables\"}}]},\"[id].model\":{\"valid\":true,\"type\":\"model\"},\"[id].strings\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"runtime\"},\"labels\":null},{\"size\":{\"source\":\"static\",\"expr\":\"1 + len(outputVariables)\"},\"labels\":{\"source\":\"static\",\"expr\":\"[independentVariable] + outputVariables\"}}]},\"[id].model\":{\"type\":\"model\"}}}"); return &j; } std::optional get_type_value() const override { return std::string("boundedODESimulation"); } @@ -644,7 +644,7 @@ class BoundedStochasticSimulation : public SedBase { std::string class_name() const override { return "BoundedStochasticSimulation"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"runtime\"},\"labels\":null},{\"size\":{\"source\":\"static\",\"expr\":\"1 + len(outputVariables)\"},\"labels\":{\"source\":\"static\",\"expr\":\"[independentVariable] + outputVariables\"}}]},\"[id].model\":{\"valid\":true,\"type\":\"model\"},\"[id].strings\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"runtime\"},\"labels\":null},{\"size\":{\"source\":\"static\",\"expr\":\"1 + len(outputVariables)\"},\"labels\":{\"source\":\"static\",\"expr\":\"[independentVariable] + outputVariables\"}}]},\"[id].model\":{\"type\":\"model\"}}}"); return &j; } std::optional get_type_value() const override { return std::string("boundedStochasticSimulation"); } @@ -856,7 +856,7 @@ class Calculation : public SedBase { std::string class_name() const override { return "Calculation"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":{\"source\":\"runtime\"}},\"[id].model\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":{\"source\":\"runtime\"}}}}"); return &j; } std::optional get_type_value() const override { return std::string("calculation"); } @@ -948,7 +948,7 @@ class CreateDataBlock : public SedBase { std::string class_name() const override { return "CreateDataBlock"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(data)\"},\"labels\":{\"source\":\"static\",\"expr\":\"keys(data)\"}}]},\"[id].model\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(data)\"},\"labels\":{\"source\":\"static\",\"expr\":\"keys(data)\"}}]}}}"); return &j; } std::optional get_type_value() const override { return std::string("createDataBlock"); } @@ -1047,7 +1047,7 @@ class CsvImport : public SedBase { std::string class_name() const override { return "CsvImport"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"input-file\",\"from\":\"location\",\"extract\":\"rowCount\"},\"labels\":null},{\"size\":{\"source\":\"input-file\",\"from\":\"location\",\"extract\":\"columnCount\"},\"labels\":{\"source\":\"input-file\",\"from\":\"location\",\"extract\":\"columnHeaders\"}}]},\"[id].model\":{\"valid\":false},\"[id].strings\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"input-file\",\"from\":\"location\",\"extract\":\"rowCount\"},\"labels\":null},{\"size\":{\"source\":\"input-file\",\"from\":\"location\",\"extract\":\"columnCount\"},\"labels\":{\"source\":\"input-file\",\"from\":\"location\",\"extract\":\"columnHeaders\"}}]}}}"); return &j; } std::optional get_type_value() const override { return std::string("csvImport"); } @@ -1203,7 +1203,7 @@ class DataImport : public SedBase { std::string class_name() const override { return "DataImport"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":{\"source\":\"input-file\",\"from\":\"location\",\"extract\":\"shape\"}},\"[id].model\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":{\"source\":\"input-file\",\"from\":\"location\",\"extract\":\"shape\"}}}}"); return &j; } std::optional get_type_value() const override { return std::string("dataImport"); } @@ -1306,7 +1306,7 @@ class DrawFromDistribution : public SedBase { std::string class_name() const override { return "DrawFromDistribution"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":[]},\"[id].model\":{\"valid\":false},\"[id].strings\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":[]}}}"); return &j; } std::optional get_type_value() const override { return std::string("drawFromDistribution"); } @@ -1439,7 +1439,7 @@ class ExplicitODESimulation : public SedBase { std::string class_name() const override { return "ExplicitODESimulation"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(independentVariableRange)\"},\"labels\":null},{\"size\":{\"source\":\"static\",\"expr\":\"1 + len(outputVariables)\"},\"labels\":{\"source\":\"static\",\"expr\":\"[independentVariable] + outputVariables\"}}]},\"[id].model\":{\"valid\":true,\"type\":\"model\"},\"[id].strings\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(independentVariableRange)\"},\"labels\":null},{\"size\":{\"source\":\"static\",\"expr\":\"1 + len(outputVariables)\"},\"labels\":{\"source\":\"static\",\"expr\":\"[independentVariable] + outputVariables\"}}]},\"[id].model\":{\"type\":\"model\"}}}"); return &j; } std::optional get_type_value() const override { return std::string("explicitODESimulation"); } @@ -1754,7 +1754,7 @@ class ExplicitStochasticSimulation : public SedBase { std::string class_name() const override { return "ExplicitStochasticSimulation"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"independentVariableRange.numberOfSteps\"},\"labels\":null},{\"size\":{\"source\":\"static\",\"expr\":\"1 + len(outputVariables)\"},\"labels\":{\"source\":\"static\",\"expr\":\"[independentVariable] + outputVariables\"}}]},\"[id].model\":{\"valid\":true,\"type\":\"model\"},\"[id].strings\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"independentVariableRange.numberOfSteps\"},\"labels\":null},{\"size\":{\"source\":\"static\",\"expr\":\"1 + len(outputVariables)\"},\"labels\":{\"source\":\"static\",\"expr\":\"[independentVariable] + outputVariables\"}}]},\"[id].model\":{\"type\":\"model\"}}}"); return &j; } std::optional get_type_value() const override { return std::string("explicitStochasticSimulation"); } @@ -1948,8 +1948,8 @@ class FluxBalanceAnalysis : public SedBase { static const std::vector specs = { FieldSpec{"model", "SIdRef", true, std::string("FluxBalanceAnalysis-0002"), std::string("FluxBalanceAnalysis-0001"), "FluxBalanceAnalysis-0000", std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::string("model")}, FieldSpec{"outputVariables", "ArrayOrRef", true, std::string("FluxBalanceAnalysis-0004"), std::string("FluxBalanceAnalysis-0003"), "FluxBalanceAnalysis-0000", std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt, false, std::nullopt, std::nullopt, std::string("FluxBalanceAnalysis-0005"), std::string("string"), std::nullopt}, - FieldSpec{"outputModel", "BooleanOrRef", false, std::string("FluxBalanceAnalysis-0006"), std::nullopt, "FluxBalanceAnalysis-0000", std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt, false, std::nullopt, std::nullopt, std::string("FluxBalanceAnalysis-0007"), std::nullopt, std::nullopt}, FieldSpec{"notes", "any", false, std::string("SEDBase-0003"), std::nullopt, "SEDBase-0000", std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, + FieldSpec{"workingAlgorithms", "array", false, std::string("FluxBalanceAnalysis-0009"), std::nullopt, "FluxBalanceAnalysis-0000", std::nullopt, std::nullopt, std::nullopt, std::string("WorkingAlgorithm"), std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, FieldSpec{"taskParameters", "array", false, std::string("AbstractTask-0001"), std::nullopt, "AbstractTask-0000", std::nullopt, std::nullopt, std::nullopt, std::string("TaskParameter"), std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, FieldSpec{"annotations", "array", false, std::string("SEDBase-0004"), std::nullopt, "SEDBase-0000", std::nullopt, std::nullopt, std::nullopt, std::string("Annotation"), std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt} }; @@ -1968,7 +1968,7 @@ class FluxBalanceAnalysis : public SedBase { std::string class_name() const override { return "FluxBalanceAnalysis"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(outputVariables)\"},\"labels\":{\"source\":\"static\",\"expr\":\"outputVariables\"}}]},\"[id].model\":{\"valid\":\"outputModel == true\",\"type\":\"model\"},\"[id].strings\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(outputVariables)\"},\"labels\":{\"source\":\"static\",\"expr\":\"outputVariables\"}}]},\"[id].model\":{\"type\":\"model\"}}}"); return &j; } std::optional get_type_value() const override { return std::string("fluxBalanceAnalysis"); } @@ -1987,19 +1987,16 @@ class FluxBalanceAnalysis : public SedBase { bool is_set_outputVariables() const { return values_.count("outputVariables") > 0; } void unset_outputVariables() { values_.erase("outputVariables"); or_ref_is_ref_.erase("outputVariables"); } - bool get_outputModel_value() const { return get_or_ref_value_node("outputModel").as(); } - std::string get_outputModel_ref() const { return get_or_ref_ref_node("outputModel").as(); } - void set_outputModel_value(bool value) { set_or_ref_value_node("outputModel", Json(value)); } - void set_outputModel_ref(const std::string& ref) { set_or_ref_ref_node("outputModel", ref); } - bool is_outputModel_ref() const { return is_or_ref_ref("outputModel"); } - bool is_set_outputModel() const { return values_.count("outputModel") > 0; } - void unset_outputModel() { values_.erase("outputModel"); or_ref_is_ref_.erase("outputModel"); } - Json get_notes() const { auto it = values_.find("notes"); if (it == values_.end()) throw ApiError(std::string("notes") + " is not set"); return it->second; } void set_notes(const Json& value) { values_["notes"] = value; } bool is_set_notes() const { return values_.count("notes") > 0; } void unset_notes() { values_.erase("notes"); } + std::vector get_workingAlgorithms() const { return workingAlgorithms_.items(); } + void add_workingAlgorithms(std::unique_ptr obj) { SedBase* raw = obj.get(); workingAlgorithms_.add(std::move(obj)); raw->attach(this, get_document()); } + void insert_workingAlgorithms(size_t index, std::unique_ptr obj) { SedBase* raw = obj.get(); workingAlgorithms_.insert(index, std::move(obj)); raw->attach(this, get_document()); } + void remove_workingAlgorithms(size_t index) { workingAlgorithms_.remove(index); } + std::vector get_taskParameters() const { return taskParameters_.items(); } void add_taskParameters(std::unique_ptr obj) { SedBase* raw = obj.get(); taskParameters_.add(std::move(obj)); raw->attach(this, get_document()); } void insert_taskParameters(size_t index, std::unique_ptr obj) { SedBase* raw = obj.get(); taskParameters_.insert(index, std::move(obj)); raw->attach(this, get_document()); } @@ -2012,6 +2009,7 @@ class FluxBalanceAnalysis : public SedBase { std::vector children() override { std::vector kids; + for (auto* item : workingAlgorithms_.items()) kids.push_back(item); for (auto* item : taskParameters_.items()) kids.push_back(item); for (auto* item : annotations_.items()) kids.push_back(item); return kids; @@ -2019,12 +2017,14 @@ class FluxBalanceAnalysis : public SedBase { std::vector children_with_locations() override { std::vector out; + { size_t idx = 0; for (auto* item : workingAlgorithms_.items()) { out.push_back(ChildLoc{item, "/workingAlgorithms/" + std::to_string(idx)}); idx++; } } { size_t idx = 0; for (auto* item : taskParameters_.items()) { out.push_back(ChildLoc{item, "/taskParameters/" + std::to_string(idx)}); idx++; } } { size_t idx = 0; for (auto* item : annotations_.items()) { out.push_back(ChildLoc{item, "/annotations/" + std::to_string(idx)}); idx++; } } return out; } ListCollection& get_list_collection(const std::string& field_name) override { + if (field_name == "workingAlgorithms") return workingAlgorithms_; if (field_name == "taskParameters") return taskParameters_; if (field_name == "annotations") return annotations_; return SedBase::get_list_collection(field_name); @@ -2037,8 +2037,8 @@ class FluxBalanceAnalysis : public SedBase { d["_type"] = values_.count("_type") ? values_.at("_type") : Json("fluxBalanceAnalysis"); if (values_.count("model")) d["model"] = values_.at("model"); if (values_.count("outputVariables")) d["outputVariables"] = values_.at("outputVariables"); - if (values_.count("outputModel")) d["outputModel"] = values_.at("outputModel"); if (values_.count("notes")) d["notes"] = values_.at("notes"); + if (workingAlgorithms_.size() > 0) { Json arr = Json::array(); for (auto* item : workingAlgorithms_.items()) arr.push_back(item->to_json_value()); d["workingAlgorithms"] = arr; } if (taskParameters_.size() > 0) { Json arr = Json::array(); for (auto* item : taskParameters_.items()) arr.push_back(item->to_json_value()); d["taskParameters"] = arr; } if (annotations_.size() > 0) { Json arr = Json::array(); for (auto* item : annotations_.items()) arr.push_back(item->to_json_value()); d["annotations"] = arr; } for (const auto& kv : ns_attrs_) d[kv.first] = kv.second; @@ -2046,6 +2046,7 @@ class FluxBalanceAnalysis : public SedBase { } private: + ListCollection workingAlgorithms_; ListCollection taskParameters_; ListCollection annotations_; }; @@ -2075,7 +2076,7 @@ class JacobianFull : public SedBase { std::string class_name() const override { return "JacobianFull"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"floatingSpeciesIds\"},\"labels\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"floatingSpeciesIds\"}},{\"size\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"floatingSpeciesIds\"},\"labels\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"floatingSpeciesIds\"}}]},\"[id].model\":{\"valid\":false},\"[id].strings\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"floatingSpeciesIds\"},\"labels\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"floatingSpeciesIds\"}},{\"size\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"floatingSpeciesIds\"},\"labels\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"floatingSpeciesIds\"}}]}}}"); return &j; } std::optional get_type_value() const override { return std::string("jacobianFull"); } @@ -2164,7 +2165,7 @@ class JacobianReduced : public SedBase { std::string class_name() const override { return "JacobianReduced"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"reducedFloatingSpeciesIds\"},\"labels\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"reducedFloatingSpeciesIds\"}},{\"size\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"reducedFloatingSpeciesIds\"},\"labels\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"reducedFloatingSpeciesIds\"}}]},\"[id].model\":{\"valid\":false},\"[id].strings\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"reducedFloatingSpeciesIds\"},\"labels\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"reducedFloatingSpeciesIds\"}},{\"size\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"reducedFloatingSpeciesIds\"},\"labels\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"reducedFloatingSpeciesIds\"}}]}}}"); return &j; } std::optional get_type_value() const override { return std::string("jacobianReduced"); } @@ -2240,12 +2241,12 @@ class Loop : public SedBase { FieldSpec{"aggregateOutputVariables", "dict", false, std::string("Repeat-0004"), std::nullopt, "Repeat-0000", std::nullopt, std::nullopt, std::nullopt, std::string("AggregationCalculation"), std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, FieldSpec{"taskParameters", "array", false, std::string("AbstractTask-0001"), std::nullopt, "AbstractTask-0000", std::nullopt, std::nullopt, std::nullopt, std::string("TaskParameter"), std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, FieldSpec{"annotations", "array", false, std::string("SEDBase-0004"), std::nullopt, "SEDBase-0000", std::nullopt, std::nullopt, std::nullopt, std::string("Annotation"), std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, - FieldSpec{"range", "ref-discriminator", false, std::string("Repeat-0005"), std::nullopt, "Repeat-0000", std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::string("RangeInline"), false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt} + FieldSpec{"range", "ref-discriminator", true, std::string("Loop-0007"), std::string("Loop-0006"), "Loop-0000", std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::string("RangeInline"), false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt} }; return specs; } const std::set& required_names() const override { - static const std::set names = {"loopVariables"}; + static const std::set names = {"loopVariables", "range"}; return names; } std::optional type_const() const override { return std::string("loop"); } @@ -2264,7 +2265,7 @@ class Loop : public SedBase { std::vector id_collection_names() const override { return {"loopVariables", "subTasks", "aggregateOutputVariables"}; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":{\"source\":\"runtime\"}},\"[id].model\":{\"valid\":false},\"[id].strings\":{\"valid\":false},\"[id].aggregates\":{\"valid\":\"provided(aggregateOutputVariables)\",\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(aggregateOutputVariables)\"},\"labels\":null}]},\"[id].range\":{\"valid\":\"provided(range)\",\"type\":\"annotatedData\",\"dimensions\":[]},\"[id].index\":{\"valid\":\"provided(range)\",\"type\":\"annotatedData\",\"dimensions\":[]}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(range)\"},\"labels\":null},{\"size\":{\"source\":\"static\",\"expr\":\"len(outputVariableMap)\"},\"labels\":null}]},\"[id].aggregates\":{\"valid\":\"provided(aggregateOutputVariables)\",\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(aggregateOutputVariables)\"},\"labels\":null}]},\"[id].range\":{\"type\":\"annotatedData\",\"dimensions\":[]},\"[id].index\":{\"type\":\"annotatedData\",\"dimensions\":[]}}}"); return &j; } std::optional get_type_value() const override { return std::string("loop"); } @@ -2414,7 +2415,7 @@ class ModelChange : public SedBase { std::string class_name() const override { return "ModelChange"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":false},\"[id].model\":{\"valid\":true,\"type\":\"model\"},\"[id].strings\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id].model\":{\"type\":\"model\"}}}"); return &j; } std::optional get_type_value() const override { return std::string("modelChange"); } @@ -2543,7 +2544,7 @@ class ModelElementList : public SedBase { std::string class_name() const override { return "ModelElementList"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":false},\"[id].model\":{\"valid\":false},\"[id].strings\":{\"valid\":true,\"type\":\"stringList\",\"dimensions\":[{\"size\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"matchedElementIds\"},\"labels\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"matchedElementIds\"}}]}}}"); + "{\"outputs\":{\"[id].strings\":{\"type\":\"stringList\",\"dimensions\":[{\"size\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"matchedElementIds\"},\"labels\":{\"source\":\"input-file\",\"from\":\"model\",\"extract\":\"matchedElementIds\"}}]}}}"); return &j; } std::optional get_type_value() const override { return std::string("modelElementList"); } @@ -2669,7 +2670,7 @@ class ModelImport : public SedBase { std::string class_name() const override { return "ModelImport"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":false},\"[id].model\":{\"valid\":true,\"type\":\"model\"},\"[id].strings\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id].model\":{\"type\":\"model\"}}}"); return &j; } std::optional get_type_value() const override { return std::string("modelImport"); } @@ -2772,7 +2773,7 @@ class NumericRange : public SedBase { std::string class_name() const override { return "NumericRange"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(values) if provided(values) else numberOfSteps + 1\"},\"labels\":null}]},\"[id].model\":{\"valid\":false},\"[id].strings\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(values) if provided(values) else numberOfSteps + 1\"},\"labels\":null}]}}}"); return &j; } std::optional get_type_value() const override { return std::string("numericRange"); } @@ -2932,7 +2933,7 @@ class OneStepODESimulation : public SedBase { std::string class_name() const override { return "OneStepODESimulation"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(outputVariables)\"},\"labels\":{\"source\":\"static\",\"expr\":\"outputVariables\"}}]},\"[id].model\":{\"valid\":true,\"type\":\"model\"},\"[id].strings\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(outputVariables)\"},\"labels\":{\"source\":\"static\",\"expr\":\"outputVariables\"}}]},\"[id].model\":{\"type\":\"model\"}}}"); return &j; } std::optional get_type_value() const override { return std::string("oneStepODE"); } @@ -3238,7 +3239,7 @@ class OneStepStochasticSimulation : public SedBase { std::string class_name() const override { return "OneStepStochasticSimulation"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(outputVariables)\"},\"labels\":{\"source\":\"static\",\"expr\":\"outputVariables\"}}]},\"[id].model\":{\"valid\":true,\"type\":\"model\"},\"[id].strings\":{\"valid\":false},\"[id].independentStep\":{\"valid\":\"!provided(independentStep)\",\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"1\"},\"labels\":null}]}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(outputVariables)\"},\"labels\":{\"source\":\"static\",\"expr\":\"outputVariables\"}}]},\"[id].model\":{\"type\":\"model\"},\"[id].independentStep\":{\"valid\":\"!provided(independentStep)\",\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"1\"},\"labels\":null}]}}}"); return &j; } std::optional get_type_value() const override { return std::string("oneStepStochastic"); } @@ -3452,7 +3453,7 @@ class ParameterRange : public SedBase { std::string class_name() const override { return "ParameterRange"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(values) if provided(values) else numberOfSteps + 1\"},\"labels\":null}]},\"[id].model\":{\"valid\":false},\"[id].strings\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(values) if provided(values) else numberOfSteps + 1\"},\"labels\":null}]}}}"); return &j; } std::optional get_type_value() const override { return std::string("parameterRange"); } @@ -3585,8 +3586,7 @@ class ParameterScan : public SedBase { FieldSpec{"subTasks", "dict", false, std::string("Repeat-0001"), std::nullopt, "Repeat-0000", std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::string("AbstractTask"), false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, FieldSpec{"aggregateOutputVariables", "dict", false, std::string("Repeat-0004"), std::nullopt, "Repeat-0000", std::nullopt, std::nullopt, std::nullopt, std::string("AggregationCalculation"), std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, FieldSpec{"taskParameters", "array", false, std::string("AbstractTask-0001"), std::nullopt, "AbstractTask-0000", std::nullopt, std::nullopt, std::nullopt, std::string("TaskParameter"), std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, - FieldSpec{"annotations", "array", false, std::string("SEDBase-0004"), std::nullopt, "SEDBase-0000", std::nullopt, std::nullopt, std::nullopt, std::string("Annotation"), std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, - FieldSpec{"range", "ref-discriminator", false, std::string("Repeat-0005"), std::nullopt, "Repeat-0000", std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::string("RangeInline"), false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt} + FieldSpec{"annotations", "array", false, std::string("SEDBase-0004"), std::nullopt, "SEDBase-0000", std::nullopt, std::nullopt, std::nullopt, std::string("Annotation"), std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt} }; return specs; } @@ -3609,7 +3609,7 @@ class ParameterScan : public SedBase { std::vector id_collection_names() const override { return {"subTasks", "aggregateOutputVariables"}; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":[{\"repeat\":{\"over\":\"parameterRanges\",\"size\":{\"source\":\"static\",\"expr\":\"len(self)\"},\"labels\":null}},{\"size\":{\"source\":\"static\",\"expr\":\"len(outputVariableMap)\"},\"labels\":null}]},\"[id].model\":{\"valid\":false},\"[id].strings\":{\"valid\":false},\"[id].aggregates\":{\"valid\":\"provided(aggregateOutputVariables)\",\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(aggregateOutputVariables)\"},\"labels\":null}]}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":[{\"repeat\":{\"over\":\"parameterRanges\",\"size\":{\"source\":\"static\",\"expr\":\"len(self)\"},\"labels\":{\"source\":\"static\",\"expr\":\"modelElement\"}}},{\"size\":{\"source\":\"static\",\"expr\":\"len(outputVariableMap)\"},\"labels\":null}]},\"[id].aggregates\":{\"valid\":\"provided(aggregateOutputVariables)\",\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(aggregateOutputVariables)\"},\"labels\":null}]},\"[id].ranges\":{\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(parameterRanges)\"},\"labels\":{\"source\":\"static\",\"expr\":\"parameterRanges.modelElement\"}}]},\"[id].indexes\":{\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(parameterRanges)\"},\"labels\":{\"source\":\"static\",\"expr\":\"parameterRanges.modelElement\"}}]}}}"); return &j; } std::optional get_type_value() const override { return std::string("parameterScan"); } @@ -3662,11 +3662,6 @@ class ParameterScan : public SedBase { void insert_annotations(size_t index, std::unique_ptr obj) { SedBase* raw = obj.get(); annotations_.insert(index, std::move(obj)); raw->attach(this, get_document()); } void remove_annotations(size_t index) { annotations_.remove(index); } - SedBase* get_range() const { if (!range_) throw ApiError(std::string("range") + " is not set"); return range_.get(); } - void set_range(std::unique_ptr obj) { SedBase* raw = obj.get(); range_ = std::move(obj); raw->attach(this, get_document()); } - bool is_set_range() const { return range_ != nullptr; } - void unset_range() { range_.reset(); } - std::vector children() override { std::vector kids; for (const auto& i : subTasks_.ids()) kids.push_back(subTasks_.get(i)); @@ -3674,7 +3669,6 @@ class ParameterScan : public SedBase { for (auto* item : parameterRanges_.items()) kids.push_back(item); for (auto* item : taskParameters_.items()) kids.push_back(item); for (auto* item : annotations_.items()) kids.push_back(item); - if (range_) kids.push_back(range_.get()); return kids; } @@ -3685,7 +3679,6 @@ class ParameterScan : public SedBase { { size_t idx = 0; for (auto* item : parameterRanges_.items()) { out.push_back(ChildLoc{item, "/parameterRanges/" + std::to_string(idx)}); idx++; } } { size_t idx = 0; for (auto* item : taskParameters_.items()) { out.push_back(ChildLoc{item, "/taskParameters/" + std::to_string(idx)}); idx++; } } { size_t idx = 0; for (auto* item : annotations_.items()) { out.push_back(ChildLoc{item, "/annotations/" + std::to_string(idx)}); idx++; } } - if (range_) out.push_back(ChildLoc{range_.get(), "/range"}); return out; } @@ -3702,11 +3695,6 @@ class ParameterScan : public SedBase { return SedBase::get_list_collection(field_name); } - void set_child_field(const std::string& field_name, std::unique_ptr child) override { - if (field_name == "range") { range_ = std::move(child); return; } - SedBase::set_child_field(field_name, std::move(child)); - } - Json own_json_value() const override { Json d = Json::object(); if (name_node_) d["name"] = *name_node_; @@ -3720,7 +3708,6 @@ class ParameterScan : public SedBase { if (parameterRanges_.size() > 0) { Json arr = Json::array(); for (auto* item : parameterRanges_.items()) arr.push_back(item->to_json_value()); d["parameterRanges"] = arr; } if (taskParameters_.size() > 0) { Json arr = Json::array(); for (auto* item : taskParameters_.items()) arr.push_back(item->to_json_value()); d["taskParameters"] = arr; } if (annotations_.size() > 0) { Json arr = Json::array(); for (auto* item : annotations_.items()) arr.push_back(item->to_json_value()); d["annotations"] = arr; } - if (range_) d["range"] = range_->to_json_value(); for (const auto& kv : ns_attrs_) d[kv.first] = kv.second; return d; } @@ -3731,7 +3718,6 @@ class ParameterScan : public SedBase { IdKeyedCollection aggregateOutputVariables_; ListCollection taskParameters_; ListCollection annotations_; - std::unique_ptr range_; }; /// Generated from test-specsheets/tasks/Range/. @@ -3755,7 +3741,7 @@ class Range : public SedBase { std::string class_name() const override { return "Range"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(values)\"},\"labels\":null}]},\"[id].model\":{\"valid\":false},\"[id].strings\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(values)\"},\"labels\":null}]}}}"); return &j; } std::optional get_type_value() const override { return std::string("range"); } @@ -3848,7 +3834,7 @@ class RelabelData : public SedBase { std::string class_name() const override { return "RelabelData"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":{\"source\":\"static\",\"expr\":\"shapeOf(input)\"}},\"[id].model\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":{\"source\":\"static\",\"expr\":\"shapeOf(input)\"}}}}"); return &j; } std::optional get_type_value() const override { return std::string("relabelData"); } @@ -3932,10 +3918,14 @@ class Scatter : public SedBase { FieldSpec{"aggregateOutputVariables", "dict", false, std::string("Repeat-0004"), std::nullopt, "Repeat-0000", std::nullopt, std::nullopt, std::nullopt, std::string("AggregationCalculation"), std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, FieldSpec{"taskParameters", "array", false, std::string("AbstractTask-0001"), std::nullopt, "AbstractTask-0000", std::nullopt, std::nullopt, std::nullopt, std::string("TaskParameter"), std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, FieldSpec{"annotations", "array", false, std::string("SEDBase-0004"), std::nullopt, "SEDBase-0000", std::nullopt, std::nullopt, std::nullopt, std::string("Annotation"), std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, - FieldSpec{"range", "ref-discriminator", false, std::string("Repeat-0005"), std::nullopt, "Repeat-0000", std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::string("RangeInline"), false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt} + FieldSpec{"range", "ref-discriminator", true, std::string("Scatter-0005"), std::string("Scatter-0004"), "Scatter-0000", std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::string("RangeInline"), false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt} }; return specs; } + const std::set& required_names() const override { + static const std::set names = {"range"}; + return names; + } std::optional type_const() const override { return std::string("scatter"); } std::optional type_rule_id() const override { return std::string("Scatter-0003"); } std::string own_catchall() const override { return "Scatter-0000"; } @@ -3951,7 +3941,7 @@ class Scatter : public SedBase { std::vector id_collection_names() const override { return {"subTasks", "aggregateOutputVariables"}; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(range)\"},\"labels\":null},{\"size\":{\"source\":\"static\",\"expr\":\"len(outputVariableMap)\"},\"labels\":null}]},\"[id].model\":{\"valid\":false},\"[id].strings\":{\"valid\":false},\"[id].aggregates\":{\"valid\":\"provided(aggregateOutputVariables)\",\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(aggregateOutputVariables)\"},\"labels\":null}]},\"[id].range\":{\"valid\":\"provided(range)\",\"type\":\"annotatedData\",\"dimensions\":[]},\"[id].index\":{\"valid\":\"provided(range)\",\"type\":\"annotatedData\",\"dimensions\":[]}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(range)\"},\"labels\":null},{\"size\":{\"source\":\"static\",\"expr\":\"len(outputVariableMap)\"},\"labels\":null}]},\"[id].aggregates\":{\"valid\":\"provided(aggregateOutputVariables)\",\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(aggregateOutputVariables)\"},\"labels\":null}]},\"[id].range\":{\"type\":\"annotatedData\",\"dimensions\":[]},\"[id].index\":{\"type\":\"annotatedData\",\"dimensions\":[]}}}"); return &j; } std::optional get_type_value() const override { return std::string("scatter"); } @@ -4085,7 +4075,7 @@ class Span : public SedBase { std::string class_name() const override { return "Span"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":false},\"[id].model\":{\"valid\":false},\"[id].strings\":{\"valid\":false}}}"); + "{\"outputs\":{}}"); return &j; } std::optional get_type_value() const override { return std::string("span"); } @@ -4159,8 +4149,8 @@ class SteadyState : public SedBase { FieldSpec{"model", "SIdRef", true, std::nullopt, std::string("SteadyState-0001"), "SteadyState-0000", std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::string("model")}, FieldSpec{"independentVariable", "StringOrRef", false, std::string("SteadyState-0004"), std::nullopt, "SteadyState-0000", std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, FieldSpec{"outputVariables", "ArrayOrRef", true, std::nullopt, std::string("SteadyState-0002"), "SteadyState-0000", std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::string("string"), std::nullopt}, - FieldSpec{"outputModel", "BooleanOrRef", false, std::string("SteadyState-0005"), std::nullopt, "SteadyState-0000", std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt, false, std::nullopt, std::nullopt, std::string("SteadyState-0006"), std::nullopt, std::nullopt}, FieldSpec{"notes", "any", false, std::string("SEDBase-0003"), std::nullopt, "SEDBase-0000", std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, + FieldSpec{"workingAlgorithms", "array", false, std::string("SteadyState-0007"), std::nullopt, "SteadyState-0000", std::nullopt, std::nullopt, std::nullopt, std::string("WorkingAlgorithm"), std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, FieldSpec{"taskParameters", "array", false, std::string("AbstractTask-0001"), std::nullopt, "AbstractTask-0000", std::nullopt, std::nullopt, std::nullopt, std::string("TaskParameter"), std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt}, FieldSpec{"annotations", "array", false, std::string("SEDBase-0004"), std::nullopt, "SEDBase-0000", std::nullopt, std::nullopt, std::nullopt, std::string("Annotation"), std::nullopt, false, std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt} }; @@ -4179,7 +4169,7 @@ class SteadyState : public SedBase { std::string class_name() const override { return "SteadyState"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(outputVariables)\"},\"labels\":{\"source\":\"static\",\"expr\":\"outputVariables\"}}]},\"[id].model\":{\"valid\":\"outputModel == true\",\"type\":\"model\"},\"[id].strings\":{\"valid\":false}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":[{\"size\":{\"source\":\"static\",\"expr\":\"len(outputVariables)\"},\"labels\":{\"source\":\"static\",\"expr\":\"outputVariables\"}}]},\"[id].model\":{\"type\":\"model\"}}}"); return &j; } std::optional get_type_value() const override { return std::string("steadyState"); } @@ -4206,19 +4196,16 @@ class SteadyState : public SedBase { bool is_set_outputVariables() const { return values_.count("outputVariables") > 0; } void unset_outputVariables() { values_.erase("outputVariables"); or_ref_is_ref_.erase("outputVariables"); } - bool get_outputModel_value() const { return get_or_ref_value_node("outputModel").as(); } - std::string get_outputModel_ref() const { return get_or_ref_ref_node("outputModel").as(); } - void set_outputModel_value(bool value) { set_or_ref_value_node("outputModel", Json(value)); } - void set_outputModel_ref(const std::string& ref) { set_or_ref_ref_node("outputModel", ref); } - bool is_outputModel_ref() const { return is_or_ref_ref("outputModel"); } - bool is_set_outputModel() const { return values_.count("outputModel") > 0; } - void unset_outputModel() { values_.erase("outputModel"); or_ref_is_ref_.erase("outputModel"); } - Json get_notes() const { auto it = values_.find("notes"); if (it == values_.end()) throw ApiError(std::string("notes") + " is not set"); return it->second; } void set_notes(const Json& value) { values_["notes"] = value; } bool is_set_notes() const { return values_.count("notes") > 0; } void unset_notes() { values_.erase("notes"); } + std::vector get_workingAlgorithms() const { return workingAlgorithms_.items(); } + void add_workingAlgorithms(std::unique_ptr obj) { SedBase* raw = obj.get(); workingAlgorithms_.add(std::move(obj)); raw->attach(this, get_document()); } + void insert_workingAlgorithms(size_t index, std::unique_ptr obj) { SedBase* raw = obj.get(); workingAlgorithms_.insert(index, std::move(obj)); raw->attach(this, get_document()); } + void remove_workingAlgorithms(size_t index) { workingAlgorithms_.remove(index); } + std::vector get_taskParameters() const { return taskParameters_.items(); } void add_taskParameters(std::unique_ptr obj) { SedBase* raw = obj.get(); taskParameters_.add(std::move(obj)); raw->attach(this, get_document()); } void insert_taskParameters(size_t index, std::unique_ptr obj) { SedBase* raw = obj.get(); taskParameters_.insert(index, std::move(obj)); raw->attach(this, get_document()); } @@ -4231,6 +4218,7 @@ class SteadyState : public SedBase { std::vector children() override { std::vector kids; + for (auto* item : workingAlgorithms_.items()) kids.push_back(item); for (auto* item : taskParameters_.items()) kids.push_back(item); for (auto* item : annotations_.items()) kids.push_back(item); return kids; @@ -4238,12 +4226,14 @@ class SteadyState : public SedBase { std::vector children_with_locations() override { std::vector out; + { size_t idx = 0; for (auto* item : workingAlgorithms_.items()) { out.push_back(ChildLoc{item, "/workingAlgorithms/" + std::to_string(idx)}); idx++; } } { size_t idx = 0; for (auto* item : taskParameters_.items()) { out.push_back(ChildLoc{item, "/taskParameters/" + std::to_string(idx)}); idx++; } } { size_t idx = 0; for (auto* item : annotations_.items()) { out.push_back(ChildLoc{item, "/annotations/" + std::to_string(idx)}); idx++; } } return out; } ListCollection& get_list_collection(const std::string& field_name) override { + if (field_name == "workingAlgorithms") return workingAlgorithms_; if (field_name == "taskParameters") return taskParameters_; if (field_name == "annotations") return annotations_; return SedBase::get_list_collection(field_name); @@ -4257,8 +4247,8 @@ class SteadyState : public SedBase { if (values_.count("model")) d["model"] = values_.at("model"); if (values_.count("independentVariable")) d["independentVariable"] = values_.at("independentVariable"); if (values_.count("outputVariables")) d["outputVariables"] = values_.at("outputVariables"); - if (values_.count("outputModel")) d["outputModel"] = values_.at("outputModel"); if (values_.count("notes")) d["notes"] = values_.at("notes"); + if (workingAlgorithms_.size() > 0) { Json arr = Json::array(); for (auto* item : workingAlgorithms_.items()) arr.push_back(item->to_json_value()); d["workingAlgorithms"] = arr; } if (taskParameters_.size() > 0) { Json arr = Json::array(); for (auto* item : taskParameters_.items()) arr.push_back(item->to_json_value()); d["taskParameters"] = arr; } if (annotations_.size() > 0) { Json arr = Json::array(); for (auto* item : annotations_.items()) arr.push_back(item->to_json_value()); d["annotations"] = arr; } for (const auto& kv : ns_attrs_) d[kv.first] = kv.second; @@ -4266,6 +4256,7 @@ class SteadyState : public SedBase { } private: + ListCollection workingAlgorithms_; ListCollection taskParameters_; ListCollection annotations_; }; @@ -4295,7 +4286,7 @@ class StringFormation : public SedBase { std::string class_name() const override { return "StringFormation"; } const Json* outputs_json() const override { static const Json j = Json::parse( - "{\"outputs\":{\"[id]\":{\"valid\":true,\"type\":\"annotatedData\",\"dimensions\":{\"source\":\"runtime\"}},\"[id].model\":{\"valid\":false},\"[id].strings\":{\"valid\":true,\"type\":\"stringList\",\"dimensions\":{\"source\":\"runtime\"}}}}"); + "{\"outputs\":{\"[id]\":{\"type\":\"annotatedData\",\"dimensions\":{\"source\":\"runtime\"}},\"[id].strings\":{\"type\":\"stringList\",\"dimensions\":{\"source\":\"runtime\"}}}}"); return &j; } std::optional get_type_value() const override { return std::string("stringFormation"); } diff --git a/generated/cpp/include/libsed2/RulesData.hpp b/generated/cpp/include/libsed2/RulesData.hpp index 1ec61d4..7bed217 100644 --- a/generated/cpp/include/libsed2/RulesData.hpp +++ b/generated/cpp/include/libsed2/RulesData.hpp @@ -204,8 +204,6 @@ inline void register_rules() { RuleCatalog::catalog()["FluxBalanceAnalysis-0003"] = RuleCatalog::Entry{"The outputVariables attribute of a FluxBalanceAnalysis is required.", "Required attribute '{attr}' is missing from {class} '{id}'.", "error"}; RuleCatalog::catalog()["FluxBalanceAnalysis-0004"] = RuleCatalog::Entry{"When the value of outputVariables of a FluxBalanceAnalysis is provided directly, it must be an array of strings.", "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not an array of strings.", "error"}; RuleCatalog::catalog()["FluxBalanceAnalysis-0005"] = RuleCatalog::Entry{"When the value of outputVariables of a FluxBalanceAnalysis is a reference, it must be a reference to an array of strings.", "Attribute '{attr}' of {class} '{id}' is the reference '{value}', which resolves to '{resolved-value}', not an array of strings.", "error"}; - RuleCatalog::catalog()["FluxBalanceAnalysis-0006"] = RuleCatalog::Entry{"When the value of outputModel of a FluxBalanceAnalysis is provided directly, it must be a boolean.", "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not a boolean.", "error"}; - RuleCatalog::catalog()["FluxBalanceAnalysis-0007"] = RuleCatalog::Entry{"When the value of outputModel of a FluxBalanceAnalysis is a reference, it must be a reference to a boolean.", "Attribute '{attr}' of {class} '{id}' is the reference '{value}', which resolves to '{resolved-value}', not a boolean.", "error"}; RuleCatalog::catalog()["FluxBalanceAnalysis-0008"] = RuleCatalog::Entry{"The _type attribute of a FluxBalanceAnalysis must be \"fluxBalanceAnalysis\".", "Attribute '{attr}' of {class} '{id}' has value '{value}', which does not match the required value '{allowed}'.", "error"}; RuleCatalog::catalog()["JacobianFull-0000"] = RuleCatalog::Entry{"The element fails a JSON Schema constraint attributable to JacobianFull that does not match any other numbered rule.", "{schema-message} (at {location})", "error"}; RuleCatalog::catalog()["JacobianFull-0001"] = RuleCatalog::Entry{"The model attribute of a JacobianFull is required.", "Required attribute '{attr}' is missing from {class} '{id}'.", "error"}; @@ -336,7 +334,6 @@ inline void register_rules() { RuleCatalog::catalog()["Repeat-0002"] = RuleCatalog::Entry{"When the value of outputVariableMap of a Repeat is provided directly, it must be an object whose values are SIdRef.", "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not an object whose values are SIdRef.", "error"}; RuleCatalog::catalog()["Repeat-0003"] = RuleCatalog::Entry{"When the value of outputVariableMap of a Repeat is a reference, it must be a reference to an object whose values are SIdRef.", "Attribute '{attr}' of {class} '{id}' is the reference '{value}', which resolves to '{resolved-value}', not an object whose values are SIdRef.", "error"}; RuleCatalog::catalog()["Repeat-0004"] = RuleCatalog::Entry{"The aggregateOutputVariables attribute of a Repeat must be an object whose values are AggregationCalculation.", "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not an object whose values are AggregationCalculation.", "error"}; - RuleCatalog::catalog()["Repeat-0005"] = RuleCatalog::Entry{"The range attribute of a Repeat, if present, must be a RangeInline object.", "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not a RangeInline object.", "error"}; RuleCatalog::catalog()["Repeat-0006"] = RuleCatalog::Entry{"A Repeat must provide at least one of outputVariableMap or aggregateOutputVariables.", "{class} '{id}' must provide at least one of 'outputVariableMap' or 'aggregateOutputVariables'.", "error"}; RuleCatalog::catalog()["Repeat-0008"] = RuleCatalog::Entry{"Every value in a Repeat's outputVariableMap must reference one of that Repeat's own subTasks, or an output of one.", "Entry '{attr}' of the outputVariableMap of {class} '{id}' references '{value}', which is not one of its own subTasks.", "error"}; RuleCatalog::catalog()["Repeat-0009"] = RuleCatalog::Entry{"The input of every entry in a Repeat's aggregateOutputVariables must reference one of that Repeat's own subTasks, or an output of one.", "Entry '{attr}' of the aggregateOutputVariables of {class} '{id}' has input '{value}', which is not one of its own subTasks.", "error"}; @@ -393,8 +390,6 @@ inline void register_rules() { RuleCatalog::catalog()["SteadyState-0002"] = RuleCatalog::Entry{"The outputVariables attribute of a SteadyState is required.", "Required attribute '{attr}' is missing from {class} '{id}'.", "error"}; RuleCatalog::catalog()["SteadyState-0003"] = RuleCatalog::Entry{"The _type attribute of a SteadyState must be \"steadyState\".", "Attribute '{attr}' of {class} '{id}' has value '{value}', which does not match the required value '{allowed}'.", "error"}; RuleCatalog::catalog()["SteadyState-0004"] = RuleCatalog::Entry{"The independentVariable attribute of a SteadyState, if present, must be a string.", "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not a string.", "error"}; - RuleCatalog::catalog()["SteadyState-0005"] = RuleCatalog::Entry{"When the value of outputModel of a SteadyState is provided directly, it must be a boolean.", "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not a boolean.", "error"}; - RuleCatalog::catalog()["SteadyState-0006"] = RuleCatalog::Entry{"When the value of outputModel of a SteadyState is a reference, it must be a reference to a boolean.", "Attribute '{attr}' of {class} '{id}' is the reference '{value}', which resolves to '{resolved-value}', not a boolean.", "error"}; RuleCatalog::catalog()["StringFormation-0000"] = RuleCatalog::Entry{"The element fails a JSON Schema constraint attributable to StringFormation that does not match any other numbered rule.", "{schema-message} (at {location})", "error"}; RuleCatalog::catalog()["StringFormation-0001"] = RuleCatalog::Entry{"The concatenate attribute of a StringFormation is required.", "Required attribute '{attr}' is missing from {class} '{id}'.", "error"}; RuleCatalog::catalog()["StringFormation-0002"] = RuleCatalog::Entry{"When the value of concatenate of a StringFormation is provided directly, it must be an array of values.", "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not an array of values.", "error"}; diff --git a/generated/java/src/main/java/org/sedml/libsed2/AggregationCalculation.java b/generated/java/src/main/java/org/sedml/libsed2/AggregationCalculation.java index 2303891..d8b1769 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/AggregationCalculation.java +++ b/generated/java/src/main/java/org/sedml/libsed2/AggregationCalculation.java @@ -38,7 +38,7 @@ public final class AggregationCalculation extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "aggregationCalculation"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": {\"source\": \"static\", \"expr\": \"shapeOf(input) - dim(appliedDimensions or outermost)\", \"note\": \"shape is input's shape with the dimension(s) named in appliedDimensions removed (or the outermost dimension, if appliedDimensions is unset); dimension count/sizes are therefore only as knowable as input's own shape is\"}}, \"[id].model\": {\"valid\": false}, \"[id].strings\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": {\"source\": \"static\", \"expr\": \"shapeOf(input) - dim(appliedDimensions or outermost)\", \"note\": \"shape is input's shape with the dimension(s) named in appliedDimensions removed (or the outermost dimension, if appliedDimensions is unset); dimension count/sizes are therefore only as knowable as input's own shape is\"}}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public JsonNode getInput() { if (!values.containsKey("input")) throw new ApiError("input" + " is not set"); return values.get("input"); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/BoundedODESimulation.java b/generated/java/src/main/java/org/sedml/libsed2/BoundedODESimulation.java index 25c72f2..799388d 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/BoundedODESimulation.java +++ b/generated/java/src/main/java/org/sedml/libsed2/BoundedODESimulation.java @@ -62,7 +62,7 @@ public final class BoundedODESimulation extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "boundedODESimulation"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"runtime\", \"note\": \"row count is chosen by the solver/simulator at run time under variable step size, not fixed by independentVariableSpan (only its start/end bound the range)\"}, \"labels\": null}, {\"size\": {\"source\": \"static\", \"expr\": \"1 + len(outputVariables)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"[independentVariable] + outputVariables\"}}]}, \"[id].model\": {\"valid\": true, \"type\": \"model\"}, \"[id].strings\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"runtime\", \"note\": \"row count is chosen by the solver/simulator at run time under variable step size, not fixed by independentVariableSpan (only its start/end bound the range)\"}, \"labels\": null}, {\"size\": {\"source\": \"static\", \"expr\": \"1 + len(outputVariables)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"[independentVariable] + outputVariables\"}}]}, \"[id].model\": {\"type\": \"model\"}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public double getRelativeToleranceValue() { return getOrRefValueNode("relativeTolerance").asDouble(); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/BoundedStochasticSimulation.java b/generated/java/src/main/java/org/sedml/libsed2/BoundedStochasticSimulation.java index 9aa57ab..39b3284 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/BoundedStochasticSimulation.java +++ b/generated/java/src/main/java/org/sedml/libsed2/BoundedStochasticSimulation.java @@ -52,7 +52,7 @@ public final class BoundedStochasticSimulation extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "boundedStochasticSimulation"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"runtime\", \"note\": \"row count is chosen by the solver/simulator at run time under variable step size, not fixed by independentVariableSpan (only its start/end bound the range)\"}, \"labels\": null}, {\"size\": {\"source\": \"static\", \"expr\": \"1 + len(outputVariables)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"[independentVariable] + outputVariables\"}}]}, \"[id].model\": {\"valid\": true, \"type\": \"model\"}, \"[id].strings\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"runtime\", \"note\": \"row count is chosen by the solver/simulator at run time under variable step size, not fixed by independentVariableSpan (only its start/end bound the range)\"}, \"labels\": null}, {\"size\": {\"source\": \"static\", \"expr\": \"1 + len(outputVariables)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"[independentVariable] + outputVariables\"}}]}, \"[id].model\": {\"type\": \"model\"}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public double getSeedValue() { return getOrRefValueNode("seed").asDouble(); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/Calculation.java b/generated/java/src/main/java/org/sedml/libsed2/Calculation.java index 8c741d6..d7ee6bc 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/Calculation.java +++ b/generated/java/src/main/java/org/sedml/libsed2/Calculation.java @@ -37,7 +37,7 @@ public final class Calculation extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "calculation"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": {\"source\": \"runtime\", \"note\": \"shape matches the evaluated math expression: scalar if every operand is scalar, otherwise broadcasts across the shape of any AnnotatedData operand(s); not derivable without evaluating math against the operands' actual values\"}}, \"[id].model\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": {\"source\": \"runtime\", \"note\": \"shape matches the evaluated math expression: scalar if every operand is scalar, otherwise broadcasts across the shape of any AnnotatedData operand(s); not derivable without evaluating math against the operands' actual values\"}}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public String getMathValue() { return getOrRefValueNode("math").asText(); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/CreateDataBlock.java b/generated/java/src/main/java/org/sedml/libsed2/CreateDataBlock.java index 478e0a3..fc29a4b 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/CreateDataBlock.java +++ b/generated/java/src/main/java/org/sedml/libsed2/CreateDataBlock.java @@ -37,7 +37,7 @@ public final class CreateDataBlock extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "createDataBlock"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(data)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"keys(data)\"}, \"note\": \"base case: one entry per key in the data dictionary. If a value in data is itself multi-dimensional (a list or AnnotatedData), that entry's own dimensions carry through instead - how mixed-dimension entries combine into one overall shape is an open design question (see core-spec.md Section 10), so this formula covers only the uniform-scalar-values case\"}]}, \"[id].model\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(data)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"keys(data)\"}, \"note\": \"base case: one entry per key in the data dictionary. If a value in data is itself multi-dimensional (a list or AnnotatedData), that entry's own dimensions carry through instead - how mixed-dimension entries combine into one overall shape is an open design question (see core-spec.md Section 10), so this formula covers only the uniform-scalar-values case\"}]}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public JsonNode getDataValue() { return getOrRefValueNode("data"); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/CsvImport.java b/generated/java/src/main/java/org/sedml/libsed2/CsvImport.java index ab7603f..66dfdb3 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/CsvImport.java +++ b/generated/java/src/main/java/org/sedml/libsed2/CsvImport.java @@ -44,7 +44,7 @@ public final class CsvImport extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "csvImport"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"input-file\", \"from\": \"location\", \"extract\": \"rowCount\", \"note\": \"row count, read from the CSV file at location\"}, \"labels\": null}, {\"size\": {\"source\": \"input-file\", \"from\": \"location\", \"extract\": \"columnCount\", \"note\": \"column count, read from the CSV file at location together with organization/headers/ncols\"}, \"labels\": {\"source\": \"input-file\", \"from\": \"location\", \"extract\": \"columnHeaders\", \"note\": \"column labels, read from the CSV header row when headers is true, else from columnNames\"}}]}, \"[id].model\": {\"valid\": false}, \"[id].strings\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"input-file\", \"from\": \"location\", \"extract\": \"rowCount\", \"note\": \"row count, read from the CSV file at location\"}, \"labels\": null}, {\"size\": {\"source\": \"input-file\", \"from\": \"location\", \"extract\": \"columnCount\", \"note\": \"column count, read from the CSV file at location together with organization/headers/ncols\"}, \"labels\": {\"source\": \"input-file\", \"from\": \"location\", \"extract\": \"columnHeaders\", \"note\": \"column labels, read from the CSV header row when headers is true, else from columnNames\"}}]}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public String getLocationValue() { return getOrRefValueNode("location").asText(); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/DataImport.java b/generated/java/src/main/java/org/sedml/libsed2/DataImport.java index f529397..6249621 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/DataImport.java +++ b/generated/java/src/main/java/org/sedml/libsed2/DataImport.java @@ -38,7 +38,7 @@ public final class DataImport extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "dataImport"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": {\"source\": \"input-file\", \"from\": \"location\", \"extract\": \"shape\", \"note\": \"shape is whatever the imported file itself has; depends on format and the file at location - extraction is format-specific (format names how to parse it)\"}}, \"[id].model\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": {\"source\": \"input-file\", \"from\": \"location\", \"extract\": \"shape\", \"note\": \"shape is whatever the imported file itself has; depends on format and the file at location - extraction is format-specific (format names how to parse it)\"}}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public String getLocationValue() { return getOrRefValueNode("location").asText(); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/DrawFromDistribution.java b/generated/java/src/main/java/org/sedml/libsed2/DrawFromDistribution.java index e42b6f1..7f75c1f 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/DrawFromDistribution.java +++ b/generated/java/src/main/java/org/sedml/libsed2/DrawFromDistribution.java @@ -39,7 +39,7 @@ public final class DrawFromDistribution extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "drawFromDistribution"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": [], \"note\": \"currently always a single scalar value (0-D), indexed historically as [id][0]; the type is multidimensional AnnotatedData to leave room for future correlated multi-value draws (shape of that future case is not yet designed - see core-spec.md Section 10)\"}, \"[id].model\": {\"valid\": false}, \"[id].strings\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": [], \"note\": \"currently always a single scalar value (0-D), indexed historically as [id][0]; the type is multidimensional AnnotatedData to leave room for future correlated multi-value draws (shape of that future case is not yet designed - see core-spec.md Section 10)\"}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public String getDistributionValue() { return getOrRefValueNode("distribution").asText(); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/ExplicitODESimulation.java b/generated/java/src/main/java/org/sedml/libsed2/ExplicitODESimulation.java index 9bdaf60..fbd0bb6 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/ExplicitODESimulation.java +++ b/generated/java/src/main/java/org/sedml/libsed2/ExplicitODESimulation.java @@ -62,7 +62,7 @@ public final class ExplicitODESimulation extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "explicitODESimulation"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(independentVariableRange)\"}, \"labels\": null}, {\"size\": {\"source\": \"static\", \"expr\": \"1 + len(outputVariables)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"[independentVariable] + outputVariables\"}}]}, \"[id].model\": {\"valid\": true, \"type\": \"model\"}, \"[id].strings\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(independentVariableRange)\"}, \"labels\": null}, {\"size\": {\"source\": \"static\", \"expr\": \"1 + len(outputVariables)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"[independentVariable] + outputVariables\"}}]}, \"[id].model\": {\"type\": \"model\"}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public double getRelativeToleranceValue() { return getOrRefValueNode("relativeTolerance").asDouble(); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/ExplicitStochasticSimulation.java b/generated/java/src/main/java/org/sedml/libsed2/ExplicitStochasticSimulation.java index 647a6ad..dbc013e 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/ExplicitStochasticSimulation.java +++ b/generated/java/src/main/java/org/sedml/libsed2/ExplicitStochasticSimulation.java @@ -52,7 +52,7 @@ public final class ExplicitStochasticSimulation extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "explicitStochasticSimulation"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"independentVariableRange.numberOfSteps\"}, \"labels\": null}, {\"size\": {\"source\": \"static\", \"expr\": \"1 + len(outputVariables)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"[independentVariable] + outputVariables\"}}]}, \"[id].model\": {\"valid\": true, \"type\": \"model\"}, \"[id].strings\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"independentVariableRange.numberOfSteps\"}, \"labels\": null}, {\"size\": {\"source\": \"static\", \"expr\": \"1 + len(outputVariables)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"[independentVariable] + outputVariables\"}}]}, \"[id].model\": {\"type\": \"model\"}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public double getSeedValue() { return getOrRefValueNode("seed").asDouble(); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/FluxBalanceAnalysis.java b/generated/java/src/main/java/org/sedml/libsed2/FluxBalanceAnalysis.java index b832128..1626199 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/FluxBalanceAnalysis.java +++ b/generated/java/src/main/java/org/sedml/libsed2/FluxBalanceAnalysis.java @@ -21,12 +21,13 @@ public final class FluxBalanceAnalysis extends SedBase { private static final List FIELD_SPECS = List.of( new FieldSpec("model", "SIdRef", true, "FluxBalanceAnalysis-0002", "FluxBalanceAnalysis-0001", "FluxBalanceAnalysis-0000", null, null, null, null, null, false, null, null, null, null, "model"), new FieldSpec("outputVariables", "ArrayOrRef", true, "FluxBalanceAnalysis-0004", "FluxBalanceAnalysis-0003", "FluxBalanceAnalysis-0000", null, null, null, null, null, false, null, null, "FluxBalanceAnalysis-0005", "string", null), - new FieldSpec("outputModel", "BooleanOrRef", false, "FluxBalanceAnalysis-0006", null, "FluxBalanceAnalysis-0000", null, null, null, null, null, false, null, null, "FluxBalanceAnalysis-0007", null, null), new FieldSpec("notes", "any", false, "SEDBase-0003", null, "SEDBase-0000", null, null, null, null, null, false, null, null, null, null, null), + new FieldSpec("workingAlgorithms", "array", false, "FluxBalanceAnalysis-0009", null, "FluxBalanceAnalysis-0000", null, null, null, "WorkingAlgorithm", null, false, null, null, null, null, null), new FieldSpec("taskParameters", "array", false, "AbstractTask-0001", null, "AbstractTask-0000", null, null, null, "TaskParameter", null, false, null, null, null, null, null), new FieldSpec("annotations", "array", false, "SEDBase-0004", null, "SEDBase-0000", null, null, null, "Annotation", null, false, null, null, null, null, null) ); private static final Set REQUIRED_NAMES = Set.of("model", "outputVariables"); + private final ListCollection workingAlgorithms = new ListCollection<>(); private final ListCollection taskParameters = new ListCollection<>(); private final ListCollection annotations = new ListCollection<>(); @@ -39,7 +40,7 @@ public final class FluxBalanceAnalysis extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "fluxBalanceAnalysis"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(outputVariables)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"outputVariables\"}}]}, \"[id].model\": {\"valid\": \"outputModel == true\", \"type\": \"model\"}, \"[id].strings\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(outputVariables)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"outputVariables\"}}]}, \"[id].model\": {\"type\": \"model\"}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public String getModel() { if (!values.containsKey("model")) throw new ApiError("model" + " is not set"); return values.get("model").asText(); } @@ -55,19 +56,16 @@ public final class FluxBalanceAnalysis extends SedBase { public boolean isSetOutputVariables() { return values.containsKey("outputVariables"); } public void unsetOutputVariables() { values.remove("outputVariables"); orRefIsRef.remove("outputVariables"); } - public boolean getOutputModelValue() { return getOrRefValueNode("outputModel").asBoolean(); } - public String getOutputModelRef() { return getOrRefRefNode("outputModel").asText(); } - public void setOutputModelValue(boolean value) { setOrRefValueNode("outputModel", BooleanNode.valueOf(value)); } - public void setOutputModelRef(String ref) { setOrRefRefNode("outputModel", ref); } - public boolean isOutputModelRef() { return isOrRefRef("outputModel"); } - public boolean isSetOutputModel() { return values.containsKey("outputModel"); } - public void unsetOutputModel() { values.remove("outputModel"); orRefIsRef.remove("outputModel"); } - public JsonNode getNotes() { if (!values.containsKey("notes")) throw new ApiError("notes" + " is not set"); return values.get("notes"); } public void setNotes(JsonNode value) { values.put("notes", value); } public boolean isSetNotes() { return values.containsKey("notes"); } public void unsetNotes() { values.remove("notes"); } + public List getWorkingAlgorithms() { return workingAlgorithms.items(); } + public void addWorkingAlgorithms(SedBase obj) { workingAlgorithms.add(obj); obj.attach(this, getDocument()); } + public void insertWorkingAlgorithms(int index, SedBase obj) { workingAlgorithms.insert(index, obj); obj.attach(this, getDocument()); } + public void removeWorkingAlgorithms(int index) { workingAlgorithms.remove(index); } + public List getTaskParameters() { return taskParameters.items(); } public void addTaskParameters(SedBase obj) { taskParameters.add(obj); obj.attach(this, getDocument()); } public void insertTaskParameters(int index, SedBase obj) { taskParameters.insert(index, obj); obj.attach(this, getDocument()); } @@ -81,6 +79,7 @@ public final class FluxBalanceAnalysis extends SedBase { @Override public List children() { List kids = new ArrayList<>(); + kids.addAll(workingAlgorithms.items()); kids.addAll(taskParameters.items()); kids.addAll(annotations.items()); return kids; @@ -89,6 +88,7 @@ public List children() { @Override public List childrenWithLocations() { List out = new ArrayList<>(); + { int idx = 0; for (SedBase item : workingAlgorithms.items()) { out.add(new ChildLoc(item, "/workingAlgorithms/" + idx)); idx++; } } { int idx = 0; for (SedBase item : taskParameters.items()) { out.add(new ChildLoc(item, "/taskParameters/" + idx)); idx++; } } { int idx = 0; for (SedBase item : annotations.items()) { out.add(new ChildLoc(item, "/annotations/" + idx)); idx++; } } return out; @@ -97,6 +97,7 @@ public List childrenWithLocations() { @Override protected ListCollection getListCollection(String fieldName) { switch (fieldName) { + case "workingAlgorithms": return workingAlgorithms; case "taskParameters": return taskParameters; case "annotations": return annotations; default: return super.getListCollection(fieldName); @@ -111,8 +112,8 @@ public ObjectNode ownJsonValue() { d.set("_type", values.containsKey("_type") ? values.get("_type") : TextNode.valueOf("fluxBalanceAnalysis")); if (values.containsKey("model")) d.set("model", values.get("model")); if (values.containsKey("outputVariables")) d.set("outputVariables", values.get("outputVariables")); - if (values.containsKey("outputModel")) d.set("outputModel", values.get("outputModel")); if (values.containsKey("notes")) d.set("notes", values.get("notes")); + if (workingAlgorithms.size() > 0) { ArrayNode arr = d.putArray("workingAlgorithms"); for (SedBase item : workingAlgorithms.items()) arr.add(item.toJsonValue()); } if (taskParameters.size() > 0) { ArrayNode arr = d.putArray("taskParameters"); for (SedBase item : taskParameters.items()) arr.add(item.toJsonValue()); } if (annotations.size() > 0) { ArrayNode arr = d.putArray("annotations"); for (SedBase item : annotations.items()) arr.add(item.toJsonValue()); } for (Map.Entry e : nsAttrs.entrySet()) d.set(e.getKey(), e.getValue()); diff --git a/generated/java/src/main/java/org/sedml/libsed2/JacobianFull.java b/generated/java/src/main/java/org/sedml/libsed2/JacobianFull.java index 85c4849..f6eb345 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/JacobianFull.java +++ b/generated/java/src/main/java/org/sedml/libsed2/JacobianFull.java @@ -37,7 +37,7 @@ public final class JacobianFull extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "jacobianFull"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"floatingSpeciesIds\", \"note\": \"row count = number of species in the referenced model\"}, \"labels\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"floatingSpeciesIds\", \"note\": \"row labels = the model's ordered species list\"}}, {\"size\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"floatingSpeciesIds\", \"note\": \"column count = number of species in the referenced model\"}, \"labels\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"floatingSpeciesIds\", \"note\": \"column labels = the model's ordered species list\"}}]}, \"[id].model\": {\"valid\": false}, \"[id].strings\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"floatingSpeciesIds\", \"note\": \"row count = number of species in the referenced model\"}, \"labels\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"floatingSpeciesIds\", \"note\": \"row labels = the model's ordered species list\"}}, {\"size\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"floatingSpeciesIds\", \"note\": \"column count = number of species in the referenced model\"}, \"labels\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"floatingSpeciesIds\", \"note\": \"column labels = the model's ordered species list\"}}]}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public String getModel() { if (!values.containsKey("model")) throw new ApiError("model" + " is not set"); return values.get("model").asText(); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/JacobianReduced.java b/generated/java/src/main/java/org/sedml/libsed2/JacobianReduced.java index e6da2f6..855d243 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/JacobianReduced.java +++ b/generated/java/src/main/java/org/sedml/libsed2/JacobianReduced.java @@ -37,7 +37,7 @@ public final class JacobianReduced extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "jacobianReduced"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"reducedFloatingSpeciesIds\", \"note\": \"row count = number of species in the referenced model's reduced species set\"}, \"labels\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"reducedFloatingSpeciesIds\", \"note\": \"row labels = the model's ordered, reduced species list\"}}, {\"size\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"reducedFloatingSpeciesIds\", \"note\": \"column count = number of species in the referenced model's reduced species set\"}, \"labels\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"reducedFloatingSpeciesIds\", \"note\": \"column labels = the model's ordered, reduced species list\"}}]}, \"[id].model\": {\"valid\": false}, \"[id].strings\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"reducedFloatingSpeciesIds\", \"note\": \"row count = number of species in the referenced model's reduced species set\"}, \"labels\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"reducedFloatingSpeciesIds\", \"note\": \"row labels = the model's ordered, reduced species list\"}}, {\"size\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"reducedFloatingSpeciesIds\", \"note\": \"column count = number of species in the referenced model's reduced species set\"}, \"labels\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"reducedFloatingSpeciesIds\", \"note\": \"column labels = the model's ordered, reduced species list\"}}]}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public String getModel() { if (!values.containsKey("model")) throw new ApiError("model" + " is not set"); return values.get("model").asText(); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/Loop.java b/generated/java/src/main/java/org/sedml/libsed2/Loop.java index e8d8418..785c08f 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/Loop.java +++ b/generated/java/src/main/java/org/sedml/libsed2/Loop.java @@ -26,9 +26,9 @@ public final class Loop extends SedBase { new FieldSpec("aggregateOutputVariables", "dict", false, "Repeat-0004", null, "Repeat-0000", null, null, null, "AggregationCalculation", null, false, null, null, null, null, null), new FieldSpec("taskParameters", "array", false, "AbstractTask-0001", null, "AbstractTask-0000", null, null, null, "TaskParameter", null, false, null, null, null, null, null), new FieldSpec("annotations", "array", false, "SEDBase-0004", null, "SEDBase-0000", null, null, null, "Annotation", null, false, null, null, null, null, null), - new FieldSpec("range", "ref-discriminator", false, "Repeat-0005", null, "Repeat-0000", null, null, null, null, "RangeInline", false, null, null, null, null, null) + new FieldSpec("range", "ref-discriminator", true, "Loop-0007", "Loop-0006", "Loop-0000", null, null, null, null, "RangeInline", false, null, null, null, null, null) ); - private static final Set REQUIRED_NAMES = Set.of("loopVariables"); + private static final Set REQUIRED_NAMES = Set.of("loopVariables", "range"); private final IdKeyedCollection loopVariables = new IdKeyedCollection<>(); private final IdKeyedCollection subTasks = new IdKeyedCollection<>(); private final IdKeyedCollection aggregateOutputVariables = new IdKeyedCollection<>(); @@ -45,7 +45,7 @@ public final class Loop extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "loop"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": {\"source\": \"runtime\", \"note\": \"2D or more: first dimension = one row per iteration (iteration count is not knowable ahead of the loop actually running - Loop's exact termination condition is an open design question, see core-spec.md Section 10); remaining dimension(s) = one column per entry of outputVariableMap\"}}, \"[id].model\": {\"valid\": false}, \"[id].strings\": {\"valid\": false}, \"[id].aggregates\": {\"valid\": \"provided(aggregateOutputVariables)\", \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(aggregateOutputVariables)\"}, \"labels\": null, \"note\": \"each entry collapses the iteration dimension of [id] to a single value (per Repeat, the applied dimension defaults to this Loop's own iterations), unless the underlying subTask output was itself multi-dimensional, in which case that dimensionality carries through per entry\"}]}, \"[id].range\": {\"valid\": \"provided(range)\", \"type\": \"annotatedData\", \"dimensions\": [], \"note\": \"the current value of range, within the loop\"}, \"[id].index\": {\"valid\": \"provided(range)\", \"type\": \"annotatedData\", \"dimensions\": [], \"note\": \"the current index into range, within the loop\"}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(range)\"}, \"labels\": null, \"note\": \"one row per value in range; len(range) dispatches on range's actual Range/NumericRange/ParameterRange type\"}, {\"size\": {\"source\": \"static\", \"expr\": \"len(outputVariableMap)\"}, \"labels\": null, \"note\": \"one column per entry of outputVariableMap, or just the range-values column alone if outputVariableMap is empty; a column whose subTask output is itself multi-dimensional would add further dimensions beyond this, not captured here\"}]}, \"[id].aggregates\": {\"valid\": \"provided(aggregateOutputVariables)\", \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(aggregateOutputVariables)\"}, \"labels\": null, \"note\": \"each entry collapses the iteration dimension of [id] to a single value (per Repeat, the applied dimension defaults to this Loop's own iterations), unless the underlying subTask output was itself multi-dimensional, in which case that dimensionality carries through per entry\"}]}, \"[id].range\": {\"type\": \"annotatedData\", \"dimensions\": [], \"note\": \"the current value of range, within the loop\"}, \"[id].index\": {\"type\": \"annotatedData\", \"dimensions\": [], \"note\": \"the current index into range, within the loop\"}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public JsonNode getOutputVariableMapValue() { return getOrRefValueNode("outputVariableMap"); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/ModelChange.java b/generated/java/src/main/java/org/sedml/libsed2/ModelChange.java index d37debd..8b29b8f 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/ModelChange.java +++ b/generated/java/src/main/java/org/sedml/libsed2/ModelChange.java @@ -41,7 +41,7 @@ public final class ModelChange extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "modelChange"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": false}, \"[id].model\": {\"valid\": true, \"type\": \"model\"}, \"[id].strings\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id].model\": {\"type\": \"model\"}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public String getInputModel() { if (!values.containsKey("inputModel")) throw new ApiError("inputModel" + " is not set"); return values.get("inputModel").asText(); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/ModelElementList.java b/generated/java/src/main/java/org/sedml/libsed2/ModelElementList.java index 198abb2..9f78091 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/ModelElementList.java +++ b/generated/java/src/main/java/org/sedml/libsed2/ModelElementList.java @@ -41,7 +41,7 @@ public final class ModelElementList extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "modelElementList"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": false}, \"[id].model\": {\"valid\": false}, \"[id].strings\": {\"valid\": true, \"type\": \"stringList\", \"dimensions\": [{\"size\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"matchedElementIds\", \"note\": \"length = number of elements in the referenced model matched after includeElements/includeTypes/excludeElements/excludeTypes filtering\"}, \"labels\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"matchedElementIds\", \"note\": \"the matched element ids themselves\"}}]}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id].strings\": {\"type\": \"stringList\", \"dimensions\": [{\"size\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"matchedElementIds\", \"note\": \"length = number of elements in the referenced model matched after includeElements/includeTypes/excludeElements/excludeTypes filtering\"}, \"labels\": {\"source\": \"input-file\", \"from\": \"model\", \"extract\": \"matchedElementIds\", \"note\": \"the matched element ids themselves\"}}]}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public String getModel() { if (!values.containsKey("model")) throw new ApiError("model" + " is not set"); return values.get("model").asText(); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/ModelImport.java b/generated/java/src/main/java/org/sedml/libsed2/ModelImport.java index d7c2f0a..5a95803 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/ModelImport.java +++ b/generated/java/src/main/java/org/sedml/libsed2/ModelImport.java @@ -38,7 +38,7 @@ public final class ModelImport extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "modelImport"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": false}, \"[id].model\": {\"valid\": true, \"type\": \"model\"}, \"[id].strings\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id].model\": {\"type\": \"model\"}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public String getLocationValue() { return getOrRefValueNode("location").asText(); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/NumericRange.java b/generated/java/src/main/java/org/sedml/libsed2/NumericRange.java index 2091c25..37c7f4d 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/NumericRange.java +++ b/generated/java/src/main/java/org/sedml/libsed2/NumericRange.java @@ -43,7 +43,7 @@ public final class NumericRange extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "numericRange"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(values) if provided(values) else numberOfSteps + 1\"}, \"labels\": null}]}, \"[id].model\": {\"valid\": false}, \"[id].strings\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(values) if provided(values) else numberOfSteps + 1\"}, \"labels\": null}]}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public double getStartValue() { return getOrRefValueNode("start").asDouble(); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/OneStepODESimulation.java b/generated/java/src/main/java/org/sedml/libsed2/OneStepODESimulation.java index 0605f6d..3e099a0 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/OneStepODESimulation.java +++ b/generated/java/src/main/java/org/sedml/libsed2/OneStepODESimulation.java @@ -61,7 +61,7 @@ public final class OneStepODESimulation extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "oneStepODE"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(outputVariables)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"outputVariables\"}, \"note\": \"a single point, not a series\"}]}, \"[id].model\": {\"valid\": true, \"type\": \"model\"}, \"[id].strings\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(outputVariables)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"outputVariables\"}, \"note\": \"a single point, not a series\"}]}, \"[id].model\": {\"type\": \"model\"}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public double getIndependentStepValue() { return getOrRefValueNode("independentStep").asDouble(); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/OneStepStochasticSimulation.java b/generated/java/src/main/java/org/sedml/libsed2/OneStepStochasticSimulation.java index 25b3a5f..9b5efd2 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/OneStepStochasticSimulation.java +++ b/generated/java/src/main/java/org/sedml/libsed2/OneStepStochasticSimulation.java @@ -51,7 +51,7 @@ public final class OneStepStochasticSimulation extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "oneStepStochastic"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(outputVariables)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"outputVariables\"}, \"note\": \"a single point, not a series\"}]}, \"[id].model\": {\"valid\": true, \"type\": \"model\"}, \"[id].strings\": {\"valid\": false}, \"[id].independentStep\": {\"valid\": \"!provided(independentStep)\", \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"1\"}, \"labels\": null}], \"note\": \"the actual elapsed step; present only when independentStep was NOT given as input\"}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(outputVariables)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"outputVariables\"}, \"note\": \"a single point, not a series\"}]}, \"[id].model\": {\"type\": \"model\"}, \"[id].independentStep\": {\"valid\": \"!provided(independentStep)\", \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"1\"}, \"labels\": null}], \"note\": \"the actual elapsed step; present only when independentStep was NOT given as input\"}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public double getIndependentStepValue() { return getOrRefValueNode("independentStep").asDouble(); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/ParameterRange.java b/generated/java/src/main/java/org/sedml/libsed2/ParameterRange.java index 8939718..a3279e6 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/ParameterRange.java +++ b/generated/java/src/main/java/org/sedml/libsed2/ParameterRange.java @@ -44,7 +44,7 @@ public final class ParameterRange extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "parameterRange"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(values) if provided(values) else numberOfSteps + 1\", \"note\": \"same derivation as NumericRange, inherited via NumericRangeCommon\"}, \"labels\": null}]}, \"[id].model\": {\"valid\": false}, \"[id].strings\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(values) if provided(values) else numberOfSteps + 1\", \"note\": \"same derivation as NumericRange, inherited via NumericRangeCommon\"}, \"labels\": null}]}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public String getModelElementValue() { return getOrRefValueNode("modelElement").asText(); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/ParameterScan.java b/generated/java/src/main/java/org/sedml/libsed2/ParameterScan.java index 2799918..0d3e0b1 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/ParameterScan.java +++ b/generated/java/src/main/java/org/sedml/libsed2/ParameterScan.java @@ -26,8 +26,7 @@ public final class ParameterScan extends SedBase { new FieldSpec("subTasks", "dict", false, "Repeat-0001", null, "Repeat-0000", null, null, null, null, "AbstractTask", false, null, null, null, null, null), new FieldSpec("aggregateOutputVariables", "dict", false, "Repeat-0004", null, "Repeat-0000", null, null, null, "AggregationCalculation", null, false, null, null, null, null, null), new FieldSpec("taskParameters", "array", false, "AbstractTask-0001", null, "AbstractTask-0000", null, null, null, "TaskParameter", null, false, null, null, null, null, null), - new FieldSpec("annotations", "array", false, "SEDBase-0004", null, "SEDBase-0000", null, null, null, "Annotation", null, false, null, null, null, null, null), - new FieldSpec("range", "ref-discriminator", false, "Repeat-0005", null, "Repeat-0000", null, null, null, null, "RangeInline", false, null, null, null, null, null) + new FieldSpec("annotations", "array", false, "SEDBase-0004", null, "SEDBase-0000", null, null, null, "Annotation", null, false, null, null, null, null, null) ); private static final Set REQUIRED_NAMES = Set.of("model", "parameterRanges"); private final ListCollection parameterRanges = new ListCollection<>(); @@ -35,7 +34,6 @@ public final class ParameterScan extends SedBase { private final IdKeyedCollection aggregateOutputVariables = new IdKeyedCollection<>(); private final ListCollection taskParameters = new ListCollection<>(); private final ListCollection annotations = new ListCollection<>(); - private SedBase range; @Override public List fieldSpecs() { return FIELD_SPECS; } @Override public Set requiredNames() { return REQUIRED_NAMES; } @@ -46,7 +44,7 @@ public final class ParameterScan extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "parameterScan"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": [{\"repeat\": {\"over\": \"parameterRanges\", \"size\": {\"source\": \"static\", \"expr\": \"len(self)\"}, \"labels\": null, \"note\": \"one dimension per entry of parameterRanges, each sized by that entry's own length; len(self) dispatches on the entry's actual Range/NumericRange/ParameterRange type - see core-spec.md Section 8\"}}, {\"size\": {\"source\": \"static\", \"expr\": \"len(outputVariableMap)\"}, \"labels\": null}]}, \"[id].model\": {\"valid\": false}, \"[id].strings\": {\"valid\": false}, \"[id].aggregates\": {\"valid\": \"provided(aggregateOutputVariables)\", \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(aggregateOutputVariables)\"}, \"labels\": null}]}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": [{\"repeat\": {\"over\": \"parameterRanges\", \"size\": {\"source\": \"static\", \"expr\": \"len(self)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"modelElement\"}, \"note\": \"one dimension per entry of parameterRanges, each sized by that entry's own length; len(self) dispatches on the entry's actual Range/NumericRange/ParameterRange type - see core-spec.md Section 8; each dimension is labeled with (identified by) that entry's modelElement, in parameterRanges order\"}}, {\"size\": {\"source\": \"static\", \"expr\": \"len(outputVariableMap)\"}, \"labels\": null}]}, \"[id].aggregates\": {\"valid\": \"provided(aggregateOutputVariables)\", \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(aggregateOutputVariables)\"}, \"labels\": null}]}, \"[id].ranges\": {\"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(parameterRanges)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"parameterRanges.modelElement\"}, \"note\": \"one entry per ParameterRange child, in order, labeled with that child's modelElement (parameterRanges.modelElement is the modelElement of each entry, in order)\"}], \"note\": \"the current value of each entry of parameterRanges, within the loop only\"}, \"[id].indexes\": {\"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(parameterRanges)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"parameterRanges.modelElement\"}, \"note\": \"one entry per ParameterRange child, in order, labeled with that child's modelElement (parameterRanges.modelElement is the modelElement of each entry, in order)\"}], \"note\": \"the current index into each entry of parameterRanges, within the loop only\"}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public String getModel() { if (!values.containsKey("model")) throw new ApiError("model" + " is not set"); return values.get("model").asText(); } @@ -96,11 +94,6 @@ public final class ParameterScan extends SedBase { public void insertAnnotations(int index, SedBase obj) { annotations.insert(index, obj); obj.attach(this, getDocument()); } public void removeAnnotations(int index) { annotations.remove(index); } - public SedBase getRange() { if (range == null) throw new ApiError("range" + " is not set"); return range; } - public void setRange(SedBase obj) { range = obj; obj.attach(this, getDocument()); } - public boolean isSetRange() { return range != null; } - public void unsetRange() { range = null; } - @Override public List children() { List kids = new ArrayList<>(); @@ -109,7 +102,6 @@ public List children() { kids.addAll(parameterRanges.items()); kids.addAll(taskParameters.items()); kids.addAll(annotations.items()); - if (range != null) kids.add(range); return kids; } @@ -121,7 +113,6 @@ public List childrenWithLocations() { { int idx = 0; for (SedBase item : parameterRanges.items()) { out.add(new ChildLoc(item, "/parameterRanges/" + idx)); idx++; } } { int idx = 0; for (SedBase item : taskParameters.items()) { out.add(new ChildLoc(item, "/taskParameters/" + idx)); idx++; } } { int idx = 0; for (SedBase item : annotations.items()) { out.add(new ChildLoc(item, "/annotations/" + idx)); idx++; } } - if (range != null) out.add(new ChildLoc(range, "/range")); return out; } @@ -156,14 +147,6 @@ protected ListCollection getListCollection(String fieldName) { } } - @Override - protected void setChildField(String fieldName, SedBase child) { - switch (fieldName) { - case "range": range = child; return; - default: super.setChildField(fieldName, child); - } - } - @Override public ObjectNode ownJsonValue() { ObjectNode d = JsonNodeFactory.instance.objectNode(); @@ -178,7 +161,6 @@ public ObjectNode ownJsonValue() { if (parameterRanges.size() > 0) { ArrayNode arr = d.putArray("parameterRanges"); for (SedBase item : parameterRanges.items()) arr.add(item.toJsonValue()); } if (taskParameters.size() > 0) { ArrayNode arr = d.putArray("taskParameters"); for (SedBase item : taskParameters.items()) arr.add(item.toJsonValue()); } if (annotations.size() > 0) { ArrayNode arr = d.putArray("annotations"); for (SedBase item : annotations.items()) arr.add(item.toJsonValue()); } - if (range != null) d.set("range", range.toJsonValue()); for (Map.Entry e : nsAttrs.entrySet()) d.set(e.getKey(), e.getValue()); return d; } diff --git a/generated/java/src/main/java/org/sedml/libsed2/Range.java b/generated/java/src/main/java/org/sedml/libsed2/Range.java index 3794d95..a2bee85 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/Range.java +++ b/generated/java/src/main/java/org/sedml/libsed2/Range.java @@ -37,7 +37,7 @@ public final class Range extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "range"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(values)\"}, \"labels\": null}]}, \"[id].model\": {\"valid\": false}, \"[id].strings\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(values)\"}, \"labels\": null}]}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public JsonNode getValuesValue() { return getOrRefValueNode("values"); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/RelabelData.java b/generated/java/src/main/java/org/sedml/libsed2/RelabelData.java index b3c1c93..eb3a4c6 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/RelabelData.java +++ b/generated/java/src/main/java/org/sedml/libsed2/RelabelData.java @@ -38,7 +38,7 @@ public final class RelabelData extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "relabelData"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": {\"source\": \"static\", \"expr\": \"shapeOf(input)\", \"note\": \"same dimensions as the referenced input AnnotatedData - this task only replaces the topmost dimension's labels (from labels), not the shape\"}}, \"[id].model\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": {\"source\": \"static\", \"expr\": \"shapeOf(input)\", \"note\": \"same dimensions as the referenced input AnnotatedData - this task only replaces the topmost dimension's labels (from labels), not the shape\"}}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public String getInput() { if (!values.containsKey("input")) throw new ApiError("input" + " is not set"); return values.get("input").asText(); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/RulesData.java b/generated/java/src/main/java/org/sedml/libsed2/RulesData.java index 42a14a6..eab241a 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/RulesData.java +++ b/generated/java/src/main/java/org/sedml/libsed2/RulesData.java @@ -200,8 +200,6 @@ public static void register() { RuleCatalog.CATALOG.put("FluxBalanceAnalysis-0003", new RuleCatalog.Entry("The outputVariables attribute of a FluxBalanceAnalysis is required.", "Required attribute '{attr}' is missing from {class} '{id}'.", "error")); RuleCatalog.CATALOG.put("FluxBalanceAnalysis-0004", new RuleCatalog.Entry("When the value of outputVariables of a FluxBalanceAnalysis is provided directly, it must be an array of strings.", "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not an array of strings.", "error")); RuleCatalog.CATALOG.put("FluxBalanceAnalysis-0005", new RuleCatalog.Entry("When the value of outputVariables of a FluxBalanceAnalysis is a reference, it must be a reference to an array of strings.", "Attribute '{attr}' of {class} '{id}' is the reference '{value}', which resolves to '{resolved-value}', not an array of strings.", "error")); - RuleCatalog.CATALOG.put("FluxBalanceAnalysis-0006", new RuleCatalog.Entry("When the value of outputModel of a FluxBalanceAnalysis is provided directly, it must be a boolean.", "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not a boolean.", "error")); - RuleCatalog.CATALOG.put("FluxBalanceAnalysis-0007", new RuleCatalog.Entry("When the value of outputModel of a FluxBalanceAnalysis is a reference, it must be a reference to a boolean.", "Attribute '{attr}' of {class} '{id}' is the reference '{value}', which resolves to '{resolved-value}', not a boolean.", "error")); RuleCatalog.CATALOG.put("FluxBalanceAnalysis-0008", new RuleCatalog.Entry("The _type attribute of a FluxBalanceAnalysis must be \"fluxBalanceAnalysis\".", "Attribute '{attr}' of {class} '{id}' has value '{value}', which does not match the required value '{allowed}'.", "error")); RuleCatalog.CATALOG.put("JacobianFull-0000", new RuleCatalog.Entry("The element fails a JSON Schema constraint attributable to JacobianFull that does not match any other numbered rule.", "{schema-message} (at {location})", "error")); RuleCatalog.CATALOG.put("JacobianFull-0001", new RuleCatalog.Entry("The model attribute of a JacobianFull is required.", "Required attribute '{attr}' is missing from {class} '{id}'.", "error")); @@ -332,7 +330,6 @@ public static void register() { RuleCatalog.CATALOG.put("Repeat-0002", new RuleCatalog.Entry("When the value of outputVariableMap of a Repeat is provided directly, it must be an object whose values are SIdRef.", "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not an object whose values are SIdRef.", "error")); RuleCatalog.CATALOG.put("Repeat-0003", new RuleCatalog.Entry("When the value of outputVariableMap of a Repeat is a reference, it must be a reference to an object whose values are SIdRef.", "Attribute '{attr}' of {class} '{id}' is the reference '{value}', which resolves to '{resolved-value}', not an object whose values are SIdRef.", "error")); RuleCatalog.CATALOG.put("Repeat-0004", new RuleCatalog.Entry("The aggregateOutputVariables attribute of a Repeat must be an object whose values are AggregationCalculation.", "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not an object whose values are AggregationCalculation.", "error")); - RuleCatalog.CATALOG.put("Repeat-0005", new RuleCatalog.Entry("The range attribute of a Repeat, if present, must be a RangeInline object.", "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not a RangeInline object.", "error")); RuleCatalog.CATALOG.put("Repeat-0006", new RuleCatalog.Entry("A Repeat must provide at least one of outputVariableMap or aggregateOutputVariables.", "{class} '{id}' must provide at least one of 'outputVariableMap' or 'aggregateOutputVariables'.", "error")); RuleCatalog.CATALOG.put("Repeat-0008", new RuleCatalog.Entry("Every value in a Repeat's outputVariableMap must reference one of that Repeat's own subTasks, or an output of one.", "Entry '{attr}' of the outputVariableMap of {class} '{id}' references '{value}', which is not one of its own subTasks.", "error")); RuleCatalog.CATALOG.put("Repeat-0009", new RuleCatalog.Entry("The input of every entry in a Repeat's aggregateOutputVariables must reference one of that Repeat's own subTasks, or an output of one.", "Entry '{attr}' of the aggregateOutputVariables of {class} '{id}' has input '{value}', which is not one of its own subTasks.", "error")); @@ -389,8 +386,6 @@ public static void register() { RuleCatalog.CATALOG.put("SteadyState-0002", new RuleCatalog.Entry("The outputVariables attribute of a SteadyState is required.", "Required attribute '{attr}' is missing from {class} '{id}'.", "error")); RuleCatalog.CATALOG.put("SteadyState-0003", new RuleCatalog.Entry("The _type attribute of a SteadyState must be \"steadyState\".", "Attribute '{attr}' of {class} '{id}' has value '{value}', which does not match the required value '{allowed}'.", "error")); RuleCatalog.CATALOG.put("SteadyState-0004", new RuleCatalog.Entry("The independentVariable attribute of a SteadyState, if present, must be a string.", "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not a string.", "error")); - RuleCatalog.CATALOG.put("SteadyState-0005", new RuleCatalog.Entry("When the value of outputModel of a SteadyState is provided directly, it must be a boolean.", "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not a boolean.", "error")); - RuleCatalog.CATALOG.put("SteadyState-0006", new RuleCatalog.Entry("When the value of outputModel of a SteadyState is a reference, it must be a reference to a boolean.", "Attribute '{attr}' of {class} '{id}' is the reference '{value}', which resolves to '{resolved-value}', not a boolean.", "error")); RuleCatalog.CATALOG.put("StringFormation-0000", new RuleCatalog.Entry("The element fails a JSON Schema constraint attributable to StringFormation that does not match any other numbered rule.", "{schema-message} (at {location})", "error")); RuleCatalog.CATALOG.put("StringFormation-0001", new RuleCatalog.Entry("The concatenate attribute of a StringFormation is required.", "Required attribute '{attr}' is missing from {class} '{id}'.", "error")); RuleCatalog.CATALOG.put("StringFormation-0002", new RuleCatalog.Entry("When the value of concatenate of a StringFormation is provided directly, it must be an array of values.", "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not an array of values.", "error")); diff --git a/generated/java/src/main/java/org/sedml/libsed2/Scatter.java b/generated/java/src/main/java/org/sedml/libsed2/Scatter.java index 06401fa..f8112cb 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/Scatter.java +++ b/generated/java/src/main/java/org/sedml/libsed2/Scatter.java @@ -25,9 +25,9 @@ public final class Scatter extends SedBase { new FieldSpec("aggregateOutputVariables", "dict", false, "Repeat-0004", null, "Repeat-0000", null, null, null, "AggregationCalculation", null, false, null, null, null, null, null), new FieldSpec("taskParameters", "array", false, "AbstractTask-0001", null, "AbstractTask-0000", null, null, null, "TaskParameter", null, false, null, null, null, null, null), new FieldSpec("annotations", "array", false, "SEDBase-0004", null, "SEDBase-0000", null, null, null, "Annotation", null, false, null, null, null, null, null), - new FieldSpec("range", "ref-discriminator", false, "Repeat-0005", null, "Repeat-0000", null, null, null, null, "RangeInline", false, null, null, null, null, null) + new FieldSpec("range", "ref-discriminator", true, "Scatter-0005", "Scatter-0004", "Scatter-0000", null, null, null, null, "RangeInline", false, null, null, null, null, null) ); - private static final Set REQUIRED_NAMES = Set.of(); + private static final Set REQUIRED_NAMES = Set.of("range"); private final IdKeyedCollection subTasks = new IdKeyedCollection<>(); private final IdKeyedCollection aggregateOutputVariables = new IdKeyedCollection<>(); private final ListCollection taskParameters = new ListCollection<>(); @@ -43,7 +43,7 @@ public final class Scatter extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "scatter"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(range)\"}, \"labels\": null, \"note\": \"one row per value in range; len(range) dispatches on range's actual Range/NumericRange/ParameterRange type\"}, {\"size\": {\"source\": \"static\", \"expr\": \"len(outputVariableMap)\"}, \"labels\": null, \"note\": \"one column per entry of outputVariableMap, or just the range-values column alone if outputVariableMap is empty; a column whose subTask output is itself multi-dimensional would add further dimensions beyond this, not captured here\"}]}, \"[id].model\": {\"valid\": false}, \"[id].strings\": {\"valid\": false}, \"[id].aggregates\": {\"valid\": \"provided(aggregateOutputVariables)\", \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(aggregateOutputVariables)\"}, \"labels\": null, \"note\": \"each entry collapses the range dimension of [id] to a single value (per Repeat, the applied dimension defaults to this Scatter's own range), unless the underlying subTask output was itself multi-dimensional, in which case that dimensionality carries through per entry\"}]}, \"[id].range\": {\"valid\": \"provided(range)\", \"type\": \"annotatedData\", \"dimensions\": [], \"note\": \"the current value of range, within each iteration\"}, \"[id].index\": {\"valid\": \"provided(range)\", \"type\": \"annotatedData\", \"dimensions\": [], \"note\": \"the current index into range, within each iteration\"}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(range)\"}, \"labels\": null, \"note\": \"one row per value in range; len(range) dispatches on range's actual Range/NumericRange/ParameterRange type\"}, {\"size\": {\"source\": \"static\", \"expr\": \"len(outputVariableMap)\"}, \"labels\": null, \"note\": \"one column per entry of outputVariableMap, or just the range-values column alone if outputVariableMap is empty; a column whose subTask output is itself multi-dimensional would add further dimensions beyond this, not captured here\"}]}, \"[id].aggregates\": {\"valid\": \"provided(aggregateOutputVariables)\", \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(aggregateOutputVariables)\"}, \"labels\": null, \"note\": \"each entry collapses the range dimension of [id] to a single value (per Repeat, the applied dimension defaults to this Scatter's own range), unless the underlying subTask output was itself multi-dimensional, in which case that dimensionality carries through per entry\"}]}, \"[id].range\": {\"type\": \"annotatedData\", \"dimensions\": [], \"note\": \"the current value of range, within each iteration\"}, \"[id].index\": {\"type\": \"annotatedData\", \"dimensions\": [], \"note\": \"the current index into range, within each iteration\"}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public JsonNode getOutputVariableMapValue() { return getOrRefValueNode("outputVariableMap"); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/Span.java b/generated/java/src/main/java/org/sedml/libsed2/Span.java index f9f6f5b..5fe98bc 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/Span.java +++ b/generated/java/src/main/java/org/sedml/libsed2/Span.java @@ -36,7 +36,7 @@ public final class Span extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "span"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": false}, \"[id].model\": {\"valid\": false}, \"[id].strings\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public double getStartValue() { return getOrRefValueNode("start").asDouble(); } diff --git a/generated/java/src/main/java/org/sedml/libsed2/SteadyState.java b/generated/java/src/main/java/org/sedml/libsed2/SteadyState.java index 7f2e14d..1c6b44e 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/SteadyState.java +++ b/generated/java/src/main/java/org/sedml/libsed2/SteadyState.java @@ -22,12 +22,13 @@ public final class SteadyState extends SedBase { new FieldSpec("model", "SIdRef", true, null, "SteadyState-0001", "SteadyState-0000", null, null, null, null, null, false, null, null, null, null, "model"), new FieldSpec("independentVariable", "StringOrRef", false, "SteadyState-0004", null, "SteadyState-0000", null, null, null, null, null, false, null, null, null, null, null), new FieldSpec("outputVariables", "ArrayOrRef", true, null, "SteadyState-0002", "SteadyState-0000", null, null, null, null, null, false, null, null, null, "string", null), - new FieldSpec("outputModel", "BooleanOrRef", false, "SteadyState-0005", null, "SteadyState-0000", null, null, null, null, null, false, null, null, "SteadyState-0006", null, null), new FieldSpec("notes", "any", false, "SEDBase-0003", null, "SEDBase-0000", null, null, null, null, null, false, null, null, null, null, null), + new FieldSpec("workingAlgorithms", "array", false, "SteadyState-0007", null, "SteadyState-0000", null, null, null, "WorkingAlgorithm", null, false, null, null, null, null, null), new FieldSpec("taskParameters", "array", false, "AbstractTask-0001", null, "AbstractTask-0000", null, null, null, "TaskParameter", null, false, null, null, null, null, null), new FieldSpec("annotations", "array", false, "SEDBase-0004", null, "SEDBase-0000", null, null, null, "Annotation", null, false, null, null, null, null, null) ); private static final Set REQUIRED_NAMES = Set.of("model", "outputVariables"); + private final ListCollection workingAlgorithms = new ListCollection<>(); private final ListCollection taskParameters = new ListCollection<>(); private final ListCollection annotations = new ListCollection<>(); @@ -40,7 +41,7 @@ public final class SteadyState extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "steadyState"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(outputVariables)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"outputVariables\"}}]}, \"[id].model\": {\"valid\": \"outputModel == true\", \"type\": \"model\"}, \"[id].strings\": {\"valid\": false}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": [{\"size\": {\"source\": \"static\", \"expr\": \"len(outputVariables)\"}, \"labels\": {\"source\": \"static\", \"expr\": \"outputVariables\"}}]}, \"[id].model\": {\"type\": \"model\"}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public String getModel() { if (!values.containsKey("model")) throw new ApiError("model" + " is not set"); return values.get("model").asText(); } @@ -64,19 +65,16 @@ public final class SteadyState extends SedBase { public boolean isSetOutputVariables() { return values.containsKey("outputVariables"); } public void unsetOutputVariables() { values.remove("outputVariables"); orRefIsRef.remove("outputVariables"); } - public boolean getOutputModelValue() { return getOrRefValueNode("outputModel").asBoolean(); } - public String getOutputModelRef() { return getOrRefRefNode("outputModel").asText(); } - public void setOutputModelValue(boolean value) { setOrRefValueNode("outputModel", BooleanNode.valueOf(value)); } - public void setOutputModelRef(String ref) { setOrRefRefNode("outputModel", ref); } - public boolean isOutputModelRef() { return isOrRefRef("outputModel"); } - public boolean isSetOutputModel() { return values.containsKey("outputModel"); } - public void unsetOutputModel() { values.remove("outputModel"); orRefIsRef.remove("outputModel"); } - public JsonNode getNotes() { if (!values.containsKey("notes")) throw new ApiError("notes" + " is not set"); return values.get("notes"); } public void setNotes(JsonNode value) { values.put("notes", value); } public boolean isSetNotes() { return values.containsKey("notes"); } public void unsetNotes() { values.remove("notes"); } + public List getWorkingAlgorithms() { return workingAlgorithms.items(); } + public void addWorkingAlgorithms(SedBase obj) { workingAlgorithms.add(obj); obj.attach(this, getDocument()); } + public void insertWorkingAlgorithms(int index, SedBase obj) { workingAlgorithms.insert(index, obj); obj.attach(this, getDocument()); } + public void removeWorkingAlgorithms(int index) { workingAlgorithms.remove(index); } + public List getTaskParameters() { return taskParameters.items(); } public void addTaskParameters(SedBase obj) { taskParameters.add(obj); obj.attach(this, getDocument()); } public void insertTaskParameters(int index, SedBase obj) { taskParameters.insert(index, obj); obj.attach(this, getDocument()); } @@ -90,6 +88,7 @@ public final class SteadyState extends SedBase { @Override public List children() { List kids = new ArrayList<>(); + kids.addAll(workingAlgorithms.items()); kids.addAll(taskParameters.items()); kids.addAll(annotations.items()); return kids; @@ -98,6 +97,7 @@ public List children() { @Override public List childrenWithLocations() { List out = new ArrayList<>(); + { int idx = 0; for (SedBase item : workingAlgorithms.items()) { out.add(new ChildLoc(item, "/workingAlgorithms/" + idx)); idx++; } } { int idx = 0; for (SedBase item : taskParameters.items()) { out.add(new ChildLoc(item, "/taskParameters/" + idx)); idx++; } } { int idx = 0; for (SedBase item : annotations.items()) { out.add(new ChildLoc(item, "/annotations/" + idx)); idx++; } } return out; @@ -106,6 +106,7 @@ public List childrenWithLocations() { @Override protected ListCollection getListCollection(String fieldName) { switch (fieldName) { + case "workingAlgorithms": return workingAlgorithms; case "taskParameters": return taskParameters; case "annotations": return annotations; default: return super.getListCollection(fieldName); @@ -121,8 +122,8 @@ public ObjectNode ownJsonValue() { if (values.containsKey("model")) d.set("model", values.get("model")); if (values.containsKey("independentVariable")) d.set("independentVariable", values.get("independentVariable")); if (values.containsKey("outputVariables")) d.set("outputVariables", values.get("outputVariables")); - if (values.containsKey("outputModel")) d.set("outputModel", values.get("outputModel")); if (values.containsKey("notes")) d.set("notes", values.get("notes")); + if (workingAlgorithms.size() > 0) { ArrayNode arr = d.putArray("workingAlgorithms"); for (SedBase item : workingAlgorithms.items()) arr.add(item.toJsonValue()); } if (taskParameters.size() > 0) { ArrayNode arr = d.putArray("taskParameters"); for (SedBase item : taskParameters.items()) arr.add(item.toJsonValue()); } if (annotations.size() > 0) { ArrayNode arr = d.putArray("annotations"); for (SedBase item : annotations.items()) arr.add(item.toJsonValue()); } for (Map.Entry e : nsAttrs.entrySet()) d.set(e.getKey(), e.getValue()); diff --git a/generated/java/src/main/java/org/sedml/libsed2/StringFormation.java b/generated/java/src/main/java/org/sedml/libsed2/StringFormation.java index 0fd34bb..bc92984 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/StringFormation.java +++ b/generated/java/src/main/java/org/sedml/libsed2/StringFormation.java @@ -37,7 +37,7 @@ public final class StringFormation extends SedBase { @Override public String descRuleId() { return "SEDBase-0002"; } @Override public String baseCatchall() { return "SEDBase-0000"; } public String getType() { return "stringFormation"; } - private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"valid\": true, \"type\": \"annotatedData\", \"dimensions\": {\"source\": \"runtime\", \"note\": \"scalar when no element of concatenate is itself a list; otherwise N-D matching the shape of the list element(s) within concatenate (1D for one list element, higher-D when several list elements are combined pairwise, all sharing the same length/shape per dimension) - not derivable without evaluating concatenate's actual element values\"}}, \"[id].model\": {\"valid\": false}, \"[id].strings\": {\"valid\": true, \"type\": \"stringList\", \"dimensions\": {\"source\": \"runtime\", \"note\": \"same as [id]'s dimensions above; not derivable without evaluating concatenate\"}}}}"); + private static final JsonNode OUTPUTS_JSON = OutputsShape.parseJson("{\"outputs\": {\"[id]\": {\"type\": \"annotatedData\", \"dimensions\": {\"source\": \"runtime\", \"note\": \"scalar when no element of concatenate is itself a list; otherwise N-D matching the shape of the list element(s) within concatenate (1D for one list element, higher-D when several list elements are combined pairwise, all sharing the same length/shape per dimension) - not derivable without evaluating concatenate's actual element values\"}}, \"[id].strings\": {\"type\": \"stringList\", \"dimensions\": {\"source\": \"runtime\", \"note\": \"same as [id]'s dimensions above; not derivable without evaluating concatenate\"}}}}"); @Override public JsonNode outputsJson() { return OUTPUTS_JSON; } public JsonNode getConcatenateValue() { return getOrRefValueNode("concatenate"); } diff --git a/generated/python/src/libsed2/model.py b/generated/python/src/libsed2/model.py index e846338..c5196b6 100644 --- a/generated/python/src/libsed2/model.py +++ b/generated/python/src/libsed2/model.py @@ -353,7 +353,7 @@ class AggregationCalculation(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': {'source': 'static', 'expr': 'shapeOf(input) - dim(appliedDimensions or outermost)', 'note': "shape is input's shape with the dimension(s) named in appliedDimensions removed (or the outermost dimension, if appliedDimensions is unset); dimension count/sizes are therefore only as knowable as input's own shape is"}}, '[id].model': {'valid': False}, '[id].strings': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': {'source': 'static', 'expr': 'shapeOf(input) - dim(appliedDimensions or outermost)', 'note': "shape is input's shape with the dimension(s) named in appliedDimensions removed (or the outermost dimension, if appliedDimensions is unset); dimension count/sizes are therefore only as knowable as input's own shape is"}}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -484,7 +484,7 @@ class BoundedODESimulation(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'runtime', 'note': 'row count is chosen by the solver/simulator at run time under variable step size, not fixed by independentVariableSpan (only its start/end bound the range)'}, 'labels': None}, {'size': {'source': 'static', 'expr': '1 + len(outputVariables)'}, 'labels': {'source': 'static', 'expr': '[independentVariable] + outputVariables'}}]}, '[id].model': {'valid': True, 'type': 'model'}, '[id].strings': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': [{'size': {'source': 'runtime', 'note': 'row count is chosen by the solver/simulator at run time under variable step size, not fixed by independentVariableSpan (only its start/end bound the range)'}, 'labels': None}, {'size': {'source': 'static', 'expr': '1 + len(outputVariables)'}, 'labels': {'source': 'static', 'expr': '[independentVariable] + outputVariables'}}]}, '[id].model': {'type': 'model'}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -1089,7 +1089,7 @@ class BoundedStochasticSimulation(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'runtime', 'note': 'row count is chosen by the solver/simulator at run time under variable step size, not fixed by independentVariableSpan (only its start/end bound the range)'}, 'labels': None}, {'size': {'source': 'static', 'expr': '1 + len(outputVariables)'}, 'labels': {'source': 'static', 'expr': '[independentVariable] + outputVariables'}}]}, '[id].model': {'valid': True, 'type': 'model'}, '[id].strings': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': [{'size': {'source': 'runtime', 'note': 'row count is chosen by the solver/simulator at run time under variable step size, not fixed by independentVariableSpan (only its start/end bound the range)'}, 'labels': None}, {'size': {'source': 'static', 'expr': '1 + len(outputVariables)'}, 'labels': {'source': 'static', 'expr': '[independentVariable] + outputVariables'}}]}, '[id].model': {'type': 'model'}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -1474,7 +1474,7 @@ class Calculation(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': {'source': 'runtime', 'note': "shape matches the evaluated math expression: scalar if every operand is scalar, otherwise broadcasts across the shape of any AnnotatedData operand(s); not derivable without evaluating math against the operands' actual values"}}, '[id].model': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': {'source': 'runtime', 'note': "shape matches the evaluated math expression: scalar if every operand is scalar, otherwise broadcasts across the shape of any AnnotatedData operand(s); not derivable without evaluating math against the operands' actual values"}}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -1591,7 +1591,7 @@ class CreateDataBlock(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(data)'}, 'labels': {'source': 'static', 'expr': 'keys(data)'}, 'note': "base case: one entry per key in the data dictionary. If a value in data is itself multi-dimensional (a list or AnnotatedData), that entry's own dimensions carry through instead - how mixed-dimension entries combine into one overall shape is an open design question (see core-spec.md Section 10), so this formula covers only the uniform-scalar-values case"}]}, '[id].model': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(data)'}, 'labels': {'source': 'static', 'expr': 'keys(data)'}, 'note': "base case: one entry per key in the data dictionary. If a value in data is itself multi-dimensional (a list or AnnotatedData), that entry's own dimensions carry through instead - how mixed-dimension entries combine into one overall shape is an open design question (see core-spec.md Section 10), so this formula covers only the uniform-scalar-values case"}]}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -1708,7 +1708,7 @@ class CsvImport(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'input-file', 'from': 'location', 'extract': 'rowCount', 'note': 'row count, read from the CSV file at location'}, 'labels': None}, {'size': {'source': 'input-file', 'from': 'location', 'extract': 'columnCount', 'note': 'column count, read from the CSV file at location together with organization/headers/ncols'}, 'labels': {'source': 'input-file', 'from': 'location', 'extract': 'columnHeaders', 'note': 'column labels, read from the CSV header row when headers is true, else from columnNames'}}]}, '[id].model': {'valid': False}, '[id].strings': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': [{'size': {'source': 'input-file', 'from': 'location', 'extract': 'rowCount', 'note': 'row count, read from the CSV file at location'}, 'labels': None}, {'size': {'source': 'input-file', 'from': 'location', 'extract': 'columnCount', 'note': 'column count, read from the CSV file at location together with organization/headers/ncols'}, 'labels': {'source': 'input-file', 'from': 'location', 'extract': 'columnHeaders', 'note': 'column labels, read from the CSV header row when headers is true, else from columnNames'}}]}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -1979,7 +1979,7 @@ class DataImport(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': {'source': 'input-file', 'from': 'location', 'extract': 'shape', 'note': 'shape is whatever the imported file itself has; depends on format and the file at location - extraction is format-specific (format names how to parse it)'}}, '[id].model': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': {'source': 'input-file', 'from': 'location', 'extract': 'shape', 'note': 'shape is whatever the imported file itself has; depends on format and the file at location - extraction is format-specific (format names how to parse it)'}}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -2118,7 +2118,7 @@ class DrawFromDistribution(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': [], 'note': 'currently always a single scalar value (0-D), indexed historically as [id][0]; the type is multidimensional AnnotatedData to leave room for future correlated multi-value draws (shape of that future case is not yet designed - see core-spec.md Section 10)'}, '[id].model': {'valid': False}, '[id].strings': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': [], 'note': 'currently always a single scalar value (0-D), indexed historically as [id][0]; the type is multidimensional AnnotatedData to leave room for future correlated multi-value draws (shape of that future case is not yet designed - see core-spec.md Section 10)'}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -2279,7 +2279,7 @@ class ExplicitODESimulation(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(independentVariableRange)'}, 'labels': None}, {'size': {'source': 'static', 'expr': '1 + len(outputVariables)'}, 'labels': {'source': 'static', 'expr': '[independentVariable] + outputVariables'}}]}, '[id].model': {'valid': True, 'type': 'model'}, '[id].strings': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(independentVariableRange)'}, 'labels': None}, {'size': {'source': 'static', 'expr': '1 + len(outputVariables)'}, 'labels': {'source': 'static', 'expr': '[independentVariable] + outputVariables'}}]}, '[id].model': {'type': 'model'}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -2884,7 +2884,7 @@ class ExplicitStochasticSimulation(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'independentVariableRange.numberOfSteps'}, 'labels': None}, {'size': {'source': 'static', 'expr': '1 + len(outputVariables)'}, 'labels': {'source': 'static', 'expr': '[independentVariable] + outputVariables'}}]}, '[id].model': {'valid': True, 'type': 'model'}, '[id].strings': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'independentVariableRange.numberOfSteps'}, 'labels': None}, {'size': {'source': 'static', 'expr': '1 + len(outputVariables)'}, 'labels': {'source': 'static', 'expr': '[independentVariable] + outputVariables'}}]}, '[id].model': {'type': 'model'}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -3261,7 +3261,7 @@ def to_json_value(self): class FluxBalanceAnalysis(SedBase): """Generated from test-specsheets/tasks/FluxBalanceAnalysis/.""" - _FIELDS = [FieldSpec('model', 'SIdRef', True, 'FluxBalanceAnalysis-0002', 'FluxBalanceAnalysis-0001', 'FluxBalanceAnalysis-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target='model'), FieldSpec('outputVariables', 'ArrayOrRef', True, 'FluxBalanceAnalysis-0004', 'FluxBalanceAnalysis-0003', 'FluxBalanceAnalysis-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id='FluxBalanceAnalysis-0005', item_kind='string', ref_target=None), FieldSpec('outputModel', 'BooleanOrRef', False, 'FluxBalanceAnalysis-0006', None, 'FluxBalanceAnalysis-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id='FluxBalanceAnalysis-0007', item_kind=None, ref_target=None), FieldSpec('notes', 'any', False, 'SEDBase-0003', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('taskParameters', 'array', False, 'AbstractTask-0001', None, 'AbstractTask-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='TaskParameter', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('annotations', 'array', False, 'SEDBase-0004', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='Annotation', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None)] + _FIELDS = [FieldSpec('model', 'SIdRef', True, 'FluxBalanceAnalysis-0002', 'FluxBalanceAnalysis-0001', 'FluxBalanceAnalysis-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target='model'), FieldSpec('outputVariables', 'ArrayOrRef', True, 'FluxBalanceAnalysis-0004', 'FluxBalanceAnalysis-0003', 'FluxBalanceAnalysis-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id='FluxBalanceAnalysis-0005', item_kind='string', ref_target=None), FieldSpec('notes', 'any', False, 'SEDBase-0003', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('workingAlgorithms', 'array', False, 'FluxBalanceAnalysis-0009', None, 'FluxBalanceAnalysis-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='WorkingAlgorithm', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('taskParameters', 'array', False, 'AbstractTask-0001', None, 'AbstractTask-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='TaskParameter', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('annotations', 'array', False, 'SEDBase-0004', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='Annotation', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None)] _REQUIRED_NAMES = {'model', 'outputVariables'} _TYPE_CONST = 'fluxBalanceAnalysis' _TYPE_RULE_ID = 'FluxBalanceAnalysis-0008' @@ -3269,12 +3269,13 @@ class FluxBalanceAnalysis(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(outputVariables)'}, 'labels': {'source': 'static', 'expr': 'outputVariables'}}]}, '[id].model': {'valid': 'outputModel == true', 'type': 'model'}, '[id].strings': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(outputVariables)'}, 'labels': {'source': 'static', 'expr': 'outputVariables'}}]}, '[id].model': {'type': 'model'}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} def __init__(self): super().__init__() + self._working_algorithms = ListCollection() self._task_parameters = ListCollection() self._annotations = ListCollection() @@ -3315,27 +3316,6 @@ def is_set_output_variables(self): def unset_output_variables(self): self._values.pop('outputVariables', None); self._orref_is_ref.pop('outputVariables', None) - def get_output_model_value(self): - return self._get_orref_value('outputModel') - - def get_output_model_ref(self): - return self._get_orref_ref('outputModel') - - def set_output_model_value(self, value): - self._set_orref_value('outputModel', value) - - def set_output_model_ref(self, ref): - self._set_orref_ref('outputModel', ref) - - def is_output_model_ref(self): - return self._is_orref_ref('outputModel') - - def is_set_output_model(self): - return 'outputModel' in self._values - - def unset_output_model(self): - self._values.pop('outputModel', None); self._orref_is_ref.pop('outputModel', None) - def get_notes(self): if 'notes' not in self._values: raise ApiError('notes is not set') return self._values['notes'] @@ -3349,6 +3329,18 @@ def is_set_notes(self): def unset_notes(self): self._values.pop('notes', None) + def get_working_algorithms(self): + return self._working_algorithms.items() + + def add_working_algorithms(self, obj): + self._working_algorithms.add(obj); obj._attach(self, self.get_document()) + + def insert_working_algorithms(self, index, obj): + self._working_algorithms.insert(index, obj); obj._attach(self, self.get_document()) + + def remove_working_algorithms(self, index): + self._working_algorithms.remove(index) + def get_task_parameters(self): return self._task_parameters.items() @@ -3375,6 +3367,7 @@ def remove_annotations(self, index): def _children(self): kids = [] + kids.extend(self._working_algorithms.items()) kids.extend(self._task_parameters.items()) kids.extend(self._annotations.items()) return kids @@ -3384,6 +3377,8 @@ def _get_id_collection(self, field_name): def _children_with_locations(self): out = [] + for idx, item in enumerate(self._working_algorithms.items()): + out.append((item, '/workingAlgorithms/%d' % idx)) for idx, item in enumerate(self._task_parameters.items()): out.append((item, '/taskParameters/%d' % idx)) for idx, item in enumerate(self._annotations.items()): @@ -3400,8 +3395,8 @@ def _own_json_value(self): d['_type'] = self._values.get('_type', 'fluxBalanceAnalysis') if 'model' in self._values: d['model'] = self._values['model'] if 'outputVariables' in self._values: d['outputVariables'] = self._values['outputVariables'] - if 'outputModel' in self._values: d['outputModel'] = self._values['outputModel'] if 'notes' in self._values: d['notes'] = self._values['notes'] + if len(self._working_algorithms): d['workingAlgorithms'] = [it.to_json_value() for it in self._working_algorithms.items()] if len(self._task_parameters): d['taskParameters'] = [it.to_json_value() for it in self._task_parameters.items()] if len(self._annotations): d['annotations'] = [it.to_json_value() for it in self._annotations.items()] for (pfx, key), value in self._ns_attrs.items(): @@ -3422,7 +3417,7 @@ class JacobianFull(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'input-file', 'from': 'model', 'extract': 'floatingSpeciesIds', 'note': 'row count = number of species in the referenced model'}, 'labels': {'source': 'input-file', 'from': 'model', 'extract': 'floatingSpeciesIds', 'note': "row labels = the model's ordered species list"}}, {'size': {'source': 'input-file', 'from': 'model', 'extract': 'floatingSpeciesIds', 'note': 'column count = number of species in the referenced model'}, 'labels': {'source': 'input-file', 'from': 'model', 'extract': 'floatingSpeciesIds', 'note': "column labels = the model's ordered species list"}}]}, '[id].model': {'valid': False}, '[id].strings': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': [{'size': {'source': 'input-file', 'from': 'model', 'extract': 'floatingSpeciesIds', 'note': 'row count = number of species in the referenced model'}, 'labels': {'source': 'input-file', 'from': 'model', 'extract': 'floatingSpeciesIds', 'note': "row labels = the model's ordered species list"}}, {'size': {'source': 'input-file', 'from': 'model', 'extract': 'floatingSpeciesIds', 'note': 'column count = number of species in the referenced model'}, 'labels': {'source': 'input-file', 'from': 'model', 'extract': 'floatingSpeciesIds', 'note': "column labels = the model's ordered species list"}}]}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -3531,7 +3526,7 @@ class JacobianReduced(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'input-file', 'from': 'model', 'extract': 'reducedFloatingSpeciesIds', 'note': "row count = number of species in the referenced model's reduced species set"}, 'labels': {'source': 'input-file', 'from': 'model', 'extract': 'reducedFloatingSpeciesIds', 'note': "row labels = the model's ordered, reduced species list"}}, {'size': {'source': 'input-file', 'from': 'model', 'extract': 'reducedFloatingSpeciesIds', 'note': "column count = number of species in the referenced model's reduced species set"}, 'labels': {'source': 'input-file', 'from': 'model', 'extract': 'reducedFloatingSpeciesIds', 'note': "column labels = the model's ordered, reduced species list"}}]}, '[id].model': {'valid': False}, '[id].strings': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': [{'size': {'source': 'input-file', 'from': 'model', 'extract': 'reducedFloatingSpeciesIds', 'note': "row count = number of species in the referenced model's reduced species set"}, 'labels': {'source': 'input-file', 'from': 'model', 'extract': 'reducedFloatingSpeciesIds', 'note': "row labels = the model's ordered, reduced species list"}}, {'size': {'source': 'input-file', 'from': 'model', 'extract': 'reducedFloatingSpeciesIds', 'note': "column count = number of species in the referenced model's reduced species set"}, 'labels': {'source': 'input-file', 'from': 'model', 'extract': 'reducedFloatingSpeciesIds', 'note': "column labels = the model's ordered, reduced species list"}}]}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -3632,15 +3627,15 @@ def to_json_value(self): class Loop(SedBase): """Generated from test-specsheets/tasks/Loop/.""" - _FIELDS = [FieldSpec('outputVariableMap', 'DictOrRef', False, 'Repeat-0002', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id='Repeat-0003', item_kind='ref', ref_target=None), FieldSpec('notes', 'any', False, 'SEDBase-0003', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('loopVariables', 'dict', True, 'Loop-0003', 'Loop-0002', 'Loop-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='LoopVariable', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('subTasks', 'dict', False, 'Repeat-0001', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator='AbstractTask', is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('aggregateOutputVariables', 'dict', False, 'Repeat-0004', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='AggregationCalculation', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('taskParameters', 'array', False, 'AbstractTask-0001', None, 'AbstractTask-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='TaskParameter', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('annotations', 'array', False, 'SEDBase-0004', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='Annotation', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('range', 'ref-discriminator', False, 'Repeat-0005', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator='RangeInline', is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None)] - _REQUIRED_NAMES = {'loopVariables'} + _FIELDS = [FieldSpec('outputVariableMap', 'DictOrRef', False, 'Repeat-0002', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id='Repeat-0003', item_kind='ref', ref_target=None), FieldSpec('notes', 'any', False, 'SEDBase-0003', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('loopVariables', 'dict', True, 'Loop-0003', 'Loop-0002', 'Loop-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='LoopVariable', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('subTasks', 'dict', False, 'Repeat-0001', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator='AbstractTask', is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('aggregateOutputVariables', 'dict', False, 'Repeat-0004', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='AggregationCalculation', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('taskParameters', 'array', False, 'AbstractTask-0001', None, 'AbstractTask-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='TaskParameter', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('annotations', 'array', False, 'SEDBase-0004', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='Annotation', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('range', 'ref-discriminator', True, 'Loop-0007', 'Loop-0006', 'Loop-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator='RangeInline', is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None)] + _REQUIRED_NAMES = {'loopVariables', 'range'} _TYPE_CONST = 'loop' _TYPE_RULE_ID = 'Loop-0005' _OWN_CATCHALL = 'Loop-0000' _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': {'source': 'runtime', 'note': "2D or more: first dimension = one row per iteration (iteration count is not knowable ahead of the loop actually running - Loop's exact termination condition is an open design question, see core-spec.md Section 10); remaining dimension(s) = one column per entry of outputVariableMap"}}, '[id].model': {'valid': False}, '[id].strings': {'valid': False}, '[id].aggregates': {'valid': 'provided(aggregateOutputVariables)', 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(aggregateOutputVariables)'}, 'labels': None, 'note': "each entry collapses the iteration dimension of [id] to a single value (per Repeat, the applied dimension defaults to this Loop's own iterations), unless the underlying subTask output was itself multi-dimensional, in which case that dimensionality carries through per entry"}]}, '[id].range': {'valid': 'provided(range)', 'type': 'annotatedData', 'dimensions': [], 'note': 'the current value of range, within the loop'}, '[id].index': {'valid': 'provided(range)', 'type': 'annotatedData', 'dimensions': [], 'note': 'the current index into range, within the loop'}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(range)'}, 'labels': None, 'note': "one row per value in range; len(range) dispatches on range's actual Range/NumericRange/ParameterRange type"}, {'size': {'source': 'static', 'expr': 'len(outputVariableMap)'}, 'labels': None, 'note': 'one column per entry of outputVariableMap, or just the range-values column alone if outputVariableMap is empty; a column whose subTask output is itself multi-dimensional would add further dimensions beyond this, not captured here'}]}, '[id].aggregates': {'valid': 'provided(aggregateOutputVariables)', 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(aggregateOutputVariables)'}, 'labels': None, 'note': "each entry collapses the iteration dimension of [id] to a single value (per Repeat, the applied dimension defaults to this Loop's own iterations), unless the underlying subTask output was itself multi-dimensional, in which case that dimensionality carries through per entry"}]}, '[id].range': {'type': 'annotatedData', 'dimensions': [], 'note': 'the current value of range, within the loop'}, '[id].index': {'type': 'annotatedData', 'dimensions': [], 'note': 'the current index into range, within the loop'}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -3846,7 +3841,7 @@ class ModelChange(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': False}, '[id].model': {'valid': True, 'type': 'model'}, '[id].strings': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id].model': {'type': 'model'}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -4043,7 +4038,7 @@ class ModelElementList(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': False}, '[id].model': {'valid': False}, '[id].strings': {'valid': True, 'type': 'stringList', 'dimensions': [{'size': {'source': 'input-file', 'from': 'model', 'extract': 'matchedElementIds', 'note': 'length = number of elements in the referenced model matched after includeElements/includeTypes/excludeElements/excludeTypes filtering'}, 'labels': {'source': 'input-file', 'from': 'model', 'extract': 'matchedElementIds', 'note': 'the matched element ids themselves'}}]}}} + _OUTPUTS_JSON = {'outputs': {'[id].strings': {'type': 'stringList', 'dimensions': [{'size': {'source': 'input-file', 'from': 'model', 'extract': 'matchedElementIds', 'note': 'length = number of elements in the referenced model matched after includeElements/includeTypes/excludeElements/excludeTypes filtering'}, 'labels': {'source': 'input-file', 'from': 'model', 'extract': 'matchedElementIds', 'note': 'the matched element ids themselves'}}]}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -4240,7 +4235,7 @@ class ModelImport(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': False}, '[id].model': {'valid': True, 'type': 'model'}, '[id].strings': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id].model': {'type': 'model'}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -4379,7 +4374,7 @@ class NumericRange(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(values) if provided(values) else numberOfSteps + 1'}, 'labels': None}]}, '[id].model': {'valid': False}, '[id].strings': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(values) if provided(values) else numberOfSteps + 1'}, 'labels': None}]}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -4628,7 +4623,7 @@ class OneStepODESimulation(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(outputVariables)'}, 'labels': {'source': 'static', 'expr': 'outputVariables'}, 'note': 'a single point, not a series'}]}, '[id].model': {'valid': True, 'type': 'model'}, '[id].strings': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(outputVariables)'}, 'labels': {'source': 'static', 'expr': 'outputVariables'}, 'note': 'a single point, not a series'}]}, '[id].model': {'type': 'model'}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -5238,7 +5233,7 @@ class OneStepStochasticSimulation(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(outputVariables)'}, 'labels': {'source': 'static', 'expr': 'outputVariables'}, 'note': 'a single point, not a series'}]}, '[id].model': {'valid': True, 'type': 'model'}, '[id].strings': {'valid': False}, '[id].independentStep': {'valid': '!provided(independentStep)', 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': '1'}, 'labels': None}], 'note': 'the actual elapsed step; present only when independentStep was NOT given as input'}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(outputVariables)'}, 'labels': {'source': 'static', 'expr': 'outputVariables'}, 'note': 'a single point, not a series'}]}, '[id].model': {'type': 'model'}, '[id].independentStep': {'valid': '!provided(independentStep)', 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': '1'}, 'labels': None}], 'note': 'the actual elapsed step; present only when independentStep was NOT given as input'}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -5628,7 +5623,7 @@ class ParameterRange(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(values) if provided(values) else numberOfSteps + 1', 'note': 'same derivation as NumericRange, inherited via NumericRangeCommon'}, 'labels': None}]}, '[id].model': {'valid': False}, '[id].strings': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(values) if provided(values) else numberOfSteps + 1', 'note': 'same derivation as NumericRange, inherited via NumericRangeCommon'}, 'labels': None}]}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -5891,7 +5886,7 @@ def to_json_value(self): class ParameterScan(SedBase): """Generated from test-specsheets/tasks/ParameterScan/.""" - _FIELDS = [FieldSpec('model', 'SIdRef', True, 'ParameterScan-0002', 'ParameterScan-0001', 'ParameterScan-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target='model'), FieldSpec('outputVariableMap', 'DictOrRef', False, 'Repeat-0002', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id='Repeat-0003', item_kind='ref', ref_target=None), FieldSpec('notes', 'any', False, 'SEDBase-0003', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('parameterRanges', 'array', True, 'ParameterScan-0004', 'ParameterScan-0003', 'ParameterScan-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='ParameterRange', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('subTasks', 'dict', False, 'Repeat-0001', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator='AbstractTask', is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('aggregateOutputVariables', 'dict', False, 'Repeat-0004', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='AggregationCalculation', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('taskParameters', 'array', False, 'AbstractTask-0001', None, 'AbstractTask-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='TaskParameter', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('annotations', 'array', False, 'SEDBase-0004', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='Annotation', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('range', 'ref-discriminator', False, 'Repeat-0005', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator='RangeInline', is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None)] + _FIELDS = [FieldSpec('model', 'SIdRef', True, 'ParameterScan-0002', 'ParameterScan-0001', 'ParameterScan-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target='model'), FieldSpec('outputVariableMap', 'DictOrRef', False, 'Repeat-0002', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id='Repeat-0003', item_kind='ref', ref_target=None), FieldSpec('notes', 'any', False, 'SEDBase-0003', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('parameterRanges', 'array', True, 'ParameterScan-0004', 'ParameterScan-0003', 'ParameterScan-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='ParameterRange', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('subTasks', 'dict', False, 'Repeat-0001', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator='AbstractTask', is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('aggregateOutputVariables', 'dict', False, 'Repeat-0004', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='AggregationCalculation', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('taskParameters', 'array', False, 'AbstractTask-0001', None, 'AbstractTask-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='TaskParameter', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('annotations', 'array', False, 'SEDBase-0004', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='Annotation', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None)] _REQUIRED_NAMES = {'model', 'parameterRanges'} _TYPE_CONST = 'parameterScan' _TYPE_RULE_ID = 'ParameterScan-0006' @@ -5899,7 +5894,7 @@ class ParameterScan(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': [{'repeat': {'over': 'parameterRanges', 'size': {'source': 'static', 'expr': 'len(self)'}, 'labels': None, 'note': "one dimension per entry of parameterRanges, each sized by that entry's own length; len(self) dispatches on the entry's actual Range/NumericRange/ParameterRange type - see core-spec.md Section 8"}}, {'size': {'source': 'static', 'expr': 'len(outputVariableMap)'}, 'labels': None}]}, '[id].model': {'valid': False}, '[id].strings': {'valid': False}, '[id].aggregates': {'valid': 'provided(aggregateOutputVariables)', 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(aggregateOutputVariables)'}, 'labels': None}]}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': [{'repeat': {'over': 'parameterRanges', 'size': {'source': 'static', 'expr': 'len(self)'}, 'labels': {'source': 'static', 'expr': 'modelElement'}, 'note': "one dimension per entry of parameterRanges, each sized by that entry's own length; len(self) dispatches on the entry's actual Range/NumericRange/ParameterRange type - see core-spec.md Section 8; each dimension is labeled with (identified by) that entry's modelElement, in parameterRanges order"}}, {'size': {'source': 'static', 'expr': 'len(outputVariableMap)'}, 'labels': None}]}, '[id].aggregates': {'valid': 'provided(aggregateOutputVariables)', 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(aggregateOutputVariables)'}, 'labels': None}]}, '[id].ranges': {'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(parameterRanges)'}, 'labels': {'source': 'static', 'expr': 'parameterRanges.modelElement'}, 'note': "one entry per ParameterRange child, in order, labeled with that child's modelElement (parameterRanges.modelElement is the modelElement of each entry, in order)"}], 'note': 'the current value of each entry of parameterRanges, within the loop only'}, '[id].indexes': {'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(parameterRanges)'}, 'labels': {'source': 'static', 'expr': 'parameterRanges.modelElement'}, 'note': "one entry per ParameterRange child, in order, labeled with that child's modelElement (parameterRanges.modelElement is the modelElement of each entry, in order)"}], 'note': 'the current index into each entry of parameterRanges, within the loop only'}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -5910,7 +5905,6 @@ def __init__(self): self._aggregate_output_variables = IdKeyedCollection(lambda tv, _cls=AggregationCalculation: (_cls, False)) self._task_parameters = ListCollection() self._annotations = ListCollection() - self._range = None def get_type(self): return 'parameterScan' @@ -6034,19 +6028,6 @@ def insert_annotations(self, index, obj): def remove_annotations(self, index): self._annotations.remove(index) - def get_range(self): - if self._range is None: raise ApiError('range is not set') - return self._range - - def set_range(self, obj): - self._range = obj; obj._attach(self, self.get_document()) - - def is_set_range(self): - return self._range is not None - - def unset_range(self): - self._range = None - def _children(self): kids = [] kids.extend(self._parameter_ranges.items()) @@ -6054,7 +6035,6 @@ def _children(self): kids.extend(self._aggregate_output_variables.get(i) for i in self._aggregate_output_variables.ids()) kids.extend(self._task_parameters.items()) kids.extend(self._annotations.items()) - if self._range is not None: kids.append(self._range) return kids def _get_id_collection(self, field_name): @@ -6074,7 +6054,6 @@ def _children_with_locations(self): out.append((item, '/taskParameters/%d' % idx)) for idx, item in enumerate(self._annotations.items()): out.append((item, '/annotations/%d' % idx)) - if self._range is not None: out.append((self._range, '/range')) return out def _id_collection_names(self): @@ -6093,7 +6072,6 @@ def _own_json_value(self): if len(self._aggregate_output_variables): d['aggregateOutputVariables'] = {i: self._aggregate_output_variables.get(i).to_json_value() for i in self._aggregate_output_variables.ids()} if len(self._task_parameters): d['taskParameters'] = [it.to_json_value() for it in self._task_parameters.items()] if len(self._annotations): d['annotations'] = [it.to_json_value() for it in self._annotations.items()] - if self._range is not None: d['range'] = self._range.to_json_value() for (pfx, key), value in self._ns_attrs.items(): d[f'{pfx}@{key}'] = value return d @@ -6112,7 +6090,7 @@ class Range(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(values)'}, 'labels': None}]}, '[id].model': {'valid': False}, '[id].strings': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(values)'}, 'labels': None}]}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -6229,7 +6207,7 @@ class RelabelData(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': {'source': 'static', 'expr': 'shapeOf(input)', 'note': "same dimensions as the referenced input AnnotatedData - this task only replaces the topmost dimension's labels (from labels), not the shape"}}, '[id].model': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': {'source': 'static', 'expr': 'shapeOf(input)', 'note': "same dimensions as the referenced input AnnotatedData - this task only replaces the topmost dimension's labels (from labels), not the shape"}}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -6352,15 +6330,15 @@ def to_json_value(self): class Scatter(SedBase): """Generated from test-specsheets/tasks/Scatter/.""" - _FIELDS = [FieldSpec('outputVariableMap', 'DictOrRef', False, 'Repeat-0002', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id='Repeat-0003', item_kind='ref', ref_target=None), FieldSpec('notes', 'any', False, 'SEDBase-0003', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('subTasks', 'dict', False, 'Repeat-0001', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator='AbstractTask', is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('aggregateOutputVariables', 'dict', False, 'Repeat-0004', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='AggregationCalculation', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('taskParameters', 'array', False, 'AbstractTask-0001', None, 'AbstractTask-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='TaskParameter', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('annotations', 'array', False, 'SEDBase-0004', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='Annotation', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('range', 'ref-discriminator', False, 'Repeat-0005', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator='RangeInline', is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None)] - _REQUIRED_NAMES = {} + _FIELDS = [FieldSpec('outputVariableMap', 'DictOrRef', False, 'Repeat-0002', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id='Repeat-0003', item_kind='ref', ref_target=None), FieldSpec('notes', 'any', False, 'SEDBase-0003', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('subTasks', 'dict', False, 'Repeat-0001', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator='AbstractTask', is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('aggregateOutputVariables', 'dict', False, 'Repeat-0004', None, 'Repeat-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='AggregationCalculation', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('taskParameters', 'array', False, 'AbstractTask-0001', None, 'AbstractTask-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='TaskParameter', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('annotations', 'array', False, 'SEDBase-0004', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='Annotation', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('range', 'ref-discriminator', True, 'Scatter-0005', 'Scatter-0004', 'Scatter-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator='RangeInline', is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None)] + _REQUIRED_NAMES = {'range'} _TYPE_CONST = 'scatter' _TYPE_RULE_ID = 'Scatter-0003' _OWN_CATCHALL = 'Scatter-0000' _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(range)'}, 'labels': None, 'note': "one row per value in range; len(range) dispatches on range's actual Range/NumericRange/ParameterRange type"}, {'size': {'source': 'static', 'expr': 'len(outputVariableMap)'}, 'labels': None, 'note': 'one column per entry of outputVariableMap, or just the range-values column alone if outputVariableMap is empty; a column whose subTask output is itself multi-dimensional would add further dimensions beyond this, not captured here'}]}, '[id].model': {'valid': False}, '[id].strings': {'valid': False}, '[id].aggregates': {'valid': 'provided(aggregateOutputVariables)', 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(aggregateOutputVariables)'}, 'labels': None, 'note': "each entry collapses the range dimension of [id] to a single value (per Repeat, the applied dimension defaults to this Scatter's own range), unless the underlying subTask output was itself multi-dimensional, in which case that dimensionality carries through per entry"}]}, '[id].range': {'valid': 'provided(range)', 'type': 'annotatedData', 'dimensions': [], 'note': 'the current value of range, within each iteration'}, '[id].index': {'valid': 'provided(range)', 'type': 'annotatedData', 'dimensions': [], 'note': 'the current index into range, within each iteration'}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(range)'}, 'labels': None, 'note': "one row per value in range; len(range) dispatches on range's actual Range/NumericRange/ParameterRange type"}, {'size': {'source': 'static', 'expr': 'len(outputVariableMap)'}, 'labels': None, 'note': 'one column per entry of outputVariableMap, or just the range-values column alone if outputVariableMap is empty; a column whose subTask output is itself multi-dimensional would add further dimensions beyond this, not captured here'}]}, '[id].aggregates': {'valid': 'provided(aggregateOutputVariables)', 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(aggregateOutputVariables)'}, 'labels': None, 'note': "each entry collapses the range dimension of [id] to a single value (per Repeat, the applied dimension defaults to this Scatter's own range), unless the underlying subTask output was itself multi-dimensional, in which case that dimensionality carries through per entry"}]}, '[id].range': {'type': 'annotatedData', 'dimensions': [], 'note': 'the current value of range, within each iteration'}, '[id].index': {'type': 'annotatedData', 'dimensions': [], 'note': 'the current index into range, within each iteration'}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -6542,7 +6520,7 @@ class Span(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': False}, '[id].model': {'valid': False}, '[id].strings': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} @@ -6656,7 +6634,7 @@ def to_json_value(self): class SteadyState(SedBase): """Generated from test-specsheets/tasks/SteadyState/.""" - _FIELDS = [FieldSpec('model', 'SIdRef', True, None, 'SteadyState-0001', 'SteadyState-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target='model'), FieldSpec('independentVariable', 'StringOrRef', False, 'SteadyState-0004', None, 'SteadyState-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('outputVariables', 'ArrayOrRef', True, None, 'SteadyState-0002', 'SteadyState-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind='string', ref_target=None), FieldSpec('outputModel', 'BooleanOrRef', False, 'SteadyState-0005', None, 'SteadyState-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id='SteadyState-0006', item_kind=None, ref_target=None), FieldSpec('notes', 'any', False, 'SEDBase-0003', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('taskParameters', 'array', False, 'AbstractTask-0001', None, 'AbstractTask-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='TaskParameter', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('annotations', 'array', False, 'SEDBase-0004', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='Annotation', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None)] + _FIELDS = [FieldSpec('model', 'SIdRef', True, None, 'SteadyState-0001', 'SteadyState-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target='model'), FieldSpec('independentVariable', 'StringOrRef', False, 'SteadyState-0004', None, 'SteadyState-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('outputVariables', 'ArrayOrRef', True, None, 'SteadyState-0002', 'SteadyState-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind='string', ref_target=None), FieldSpec('notes', 'any', False, 'SEDBase-0003', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class=None, item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('workingAlgorithms', 'array', False, 'SteadyState-0007', None, 'SteadyState-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='WorkingAlgorithm', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('taskParameters', 'array', False, 'AbstractTask-0001', None, 'AbstractTask-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='TaskParameter', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None), FieldSpec('annotations', 'array', False, 'SEDBase-0004', None, 'SEDBase-0000', minimum=None, exclusive_minimum=None, pattern=None, item_class='Annotation', item_discriminator=None, is_math=False, min_length=None, enum=None, ref_type_rule_id=None, item_kind=None, ref_target=None)] _REQUIRED_NAMES = {'model', 'outputVariables'} _TYPE_CONST = 'steadyState' _TYPE_RULE_ID = 'SteadyState-0003' @@ -6664,12 +6642,13 @@ class SteadyState(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(outputVariables)'}, 'labels': {'source': 'static', 'expr': 'outputVariables'}}]}, '[id].model': {'valid': 'outputModel == true', 'type': 'model'}, '[id].strings': {'valid': False}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': [{'size': {'source': 'static', 'expr': 'len(outputVariables)'}, 'labels': {'source': 'static', 'expr': 'outputVariables'}}]}, '[id].model': {'type': 'model'}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} def __init__(self): super().__init__() + self._working_algorithms = ListCollection() self._task_parameters = ListCollection() self._annotations = ListCollection() @@ -6731,27 +6710,6 @@ def is_set_output_variables(self): def unset_output_variables(self): self._values.pop('outputVariables', None); self._orref_is_ref.pop('outputVariables', None) - def get_output_model_value(self): - return self._get_orref_value('outputModel') - - def get_output_model_ref(self): - return self._get_orref_ref('outputModel') - - def set_output_model_value(self, value): - self._set_orref_value('outputModel', value) - - def set_output_model_ref(self, ref): - self._set_orref_ref('outputModel', ref) - - def is_output_model_ref(self): - return self._is_orref_ref('outputModel') - - def is_set_output_model(self): - return 'outputModel' in self._values - - def unset_output_model(self): - self._values.pop('outputModel', None); self._orref_is_ref.pop('outputModel', None) - def get_notes(self): if 'notes' not in self._values: raise ApiError('notes is not set') return self._values['notes'] @@ -6765,6 +6723,18 @@ def is_set_notes(self): def unset_notes(self): self._values.pop('notes', None) + def get_working_algorithms(self): + return self._working_algorithms.items() + + def add_working_algorithms(self, obj): + self._working_algorithms.add(obj); obj._attach(self, self.get_document()) + + def insert_working_algorithms(self, index, obj): + self._working_algorithms.insert(index, obj); obj._attach(self, self.get_document()) + + def remove_working_algorithms(self, index): + self._working_algorithms.remove(index) + def get_task_parameters(self): return self._task_parameters.items() @@ -6791,6 +6761,7 @@ def remove_annotations(self, index): def _children(self): kids = [] + kids.extend(self._working_algorithms.items()) kids.extend(self._task_parameters.items()) kids.extend(self._annotations.items()) return kids @@ -6800,6 +6771,8 @@ def _get_id_collection(self, field_name): def _children_with_locations(self): out = [] + for idx, item in enumerate(self._working_algorithms.items()): + out.append((item, '/workingAlgorithms/%d' % idx)) for idx, item in enumerate(self._task_parameters.items()): out.append((item, '/taskParameters/%d' % idx)) for idx, item in enumerate(self._annotations.items()): @@ -6817,8 +6790,8 @@ def _own_json_value(self): if 'model' in self._values: d['model'] = self._values['model'] if 'independentVariable' in self._values: d['independentVariable'] = self._values['independentVariable'] if 'outputVariables' in self._values: d['outputVariables'] = self._values['outputVariables'] - if 'outputModel' in self._values: d['outputModel'] = self._values['outputModel'] if 'notes' in self._values: d['notes'] = self._values['notes'] + if len(self._working_algorithms): d['workingAlgorithms'] = [it.to_json_value() for it in self._working_algorithms.items()] if len(self._task_parameters): d['taskParameters'] = [it.to_json_value() for it in self._task_parameters.items()] if len(self._annotations): d['annotations'] = [it.to_json_value() for it in self._annotations.items()] for (pfx, key), value in self._ns_attrs.items(): @@ -6839,7 +6812,7 @@ class StringFormation(SedBase): _NAME_RULE_ID = 'SEDBase-0001' _DESC_RULE_ID = 'SEDBase-0002' _BASE_CATCHALL = 'SEDBase-0000' - _OUTPUTS_JSON = {'outputs': {'[id]': {'valid': True, 'type': 'annotatedData', 'dimensions': {'source': 'runtime', 'note': "scalar when no element of concatenate is itself a list; otherwise N-D matching the shape of the list element(s) within concatenate (1D for one list element, higher-D when several list elements are combined pairwise, all sharing the same length/shape per dimension) - not derivable without evaluating concatenate's actual element values"}}, '[id].model': {'valid': False}, '[id].strings': {'valid': True, 'type': 'stringList', 'dimensions': {'source': 'runtime', 'note': "same as [id]'s dimensions above; not derivable without evaluating concatenate"}}}} + _OUTPUTS_JSON = {'outputs': {'[id]': {'type': 'annotatedData', 'dimensions': {'source': 'runtime', 'note': "scalar when no element of concatenate is itself a list; otherwise N-D matching the shape of the list element(s) within concatenate (1D for one list element, higher-D when several list elements are combined pairwise, all sharing the same length/shape per dimension) - not derivable without evaluating concatenate's actual element values"}}, '[id].strings': {'type': 'stringList', 'dimensions': {'source': 'runtime', 'note': "same as [id]'s dimensions above; not derivable without evaluating concatenate"}}}} _NAMESPACE_FIELDS = {} _NAMESPACE_CATCHALL = {} diff --git a/generated/python/src/libsed2/rules_data.py b/generated/python/src/libsed2/rules_data.py index 8ec50f6..6b18b7d 100644 --- a/generated/python/src/libsed2/rules_data.py +++ b/generated/python/src/libsed2/rules_data.py @@ -196,8 +196,6 @@ 'FluxBalanceAnalysis-0003': ('The outputVariables attribute of a FluxBalanceAnalysis is required.', "Required attribute '{attr}' is missing from {class} '{id}'.", 'error'), 'FluxBalanceAnalysis-0004': ('When the value of outputVariables of a FluxBalanceAnalysis is provided directly, it must be an array of strings.', "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not an array of strings.", 'error'), 'FluxBalanceAnalysis-0005': ('When the value of outputVariables of a FluxBalanceAnalysis is a reference, it must be a reference to an array of strings.', "Attribute '{attr}' of {class} '{id}' is the reference '{value}', which resolves to '{resolved-value}', not an array of strings.", 'error'), - 'FluxBalanceAnalysis-0006': ('When the value of outputModel of a FluxBalanceAnalysis is provided directly, it must be a boolean.', "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not a boolean.", 'error'), - 'FluxBalanceAnalysis-0007': ('When the value of outputModel of a FluxBalanceAnalysis is a reference, it must be a reference to a boolean.', "Attribute '{attr}' of {class} '{id}' is the reference '{value}', which resolves to '{resolved-value}', not a boolean.", 'error'), 'FluxBalanceAnalysis-0008': ('The _type attribute of a FluxBalanceAnalysis must be "fluxBalanceAnalysis".', "Attribute '{attr}' of {class} '{id}' has value '{value}', which does not match the required value '{allowed}'.", 'error'), 'JacobianFull-0000': ('The element fails a JSON Schema constraint attributable to JacobianFull that does not match any other numbered rule.', '{schema-message} (at {location})', 'error'), 'JacobianFull-0001': ('The model attribute of a JacobianFull is required.', "Required attribute '{attr}' is missing from {class} '{id}'.", 'error'), @@ -328,7 +326,6 @@ 'Repeat-0002': ('When the value of outputVariableMap of a Repeat is provided directly, it must be an object whose values are SIdRef.', "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not an object whose values are SIdRef.", 'error'), 'Repeat-0003': ('When the value of outputVariableMap of a Repeat is a reference, it must be a reference to an object whose values are SIdRef.', "Attribute '{attr}' of {class} '{id}' is the reference '{value}', which resolves to '{resolved-value}', not an object whose values are SIdRef.", 'error'), 'Repeat-0004': ('The aggregateOutputVariables attribute of a Repeat must be an object whose values are AggregationCalculation.', "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not an object whose values are AggregationCalculation.", 'error'), - 'Repeat-0005': ('The range attribute of a Repeat, if present, must be a RangeInline object.', "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not a RangeInline object.", 'error'), 'Repeat-0006': ('A Repeat must provide at least one of outputVariableMap or aggregateOutputVariables.', "{class} '{id}' must provide at least one of 'outputVariableMap' or 'aggregateOutputVariables'.", 'error'), 'Repeat-0008': ("Every value in a Repeat's outputVariableMap must reference one of that Repeat's own subTasks, or an output of one.", "Entry '{attr}' of the outputVariableMap of {class} '{id}' references '{value}', which is not one of its own subTasks.", 'error'), 'Repeat-0009': ("The input of every entry in a Repeat's aggregateOutputVariables must reference one of that Repeat's own subTasks, or an output of one.", "Entry '{attr}' of the aggregateOutputVariables of {class} '{id}' has input '{value}', which is not one of its own subTasks.", 'error'), @@ -385,8 +382,6 @@ 'SteadyState-0002': ('The outputVariables attribute of a SteadyState is required.', "Required attribute '{attr}' is missing from {class} '{id}'.", 'error'), 'SteadyState-0003': ('The _type attribute of a SteadyState must be "steadyState".', "Attribute '{attr}' of {class} '{id}' has value '{value}', which does not match the required value '{allowed}'.", 'error'), 'SteadyState-0004': ('The independentVariable attribute of a SteadyState, if present, must be a string.', "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not a string.", 'error'), - 'SteadyState-0005': ('When the value of outputModel of a SteadyState is provided directly, it must be a boolean.', "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not a boolean.", 'error'), - 'SteadyState-0006': ('When the value of outputModel of a SteadyState is a reference, it must be a reference to a boolean.', "Attribute '{attr}' of {class} '{id}' is the reference '{value}', which resolves to '{resolved-value}', not a boolean.", 'error'), 'StringFormation-0000': ('The element fails a JSON Schema constraint attributable to StringFormation that does not match any other numbered rule.', '{schema-message} (at {location})', 'error'), 'StringFormation-0001': ('The concatenate attribute of a StringFormation is required.', "Required attribute '{attr}' is missing from {class} '{id}'.", 'error'), 'StringFormation-0002': ('When the value of concatenate of a StringFormation is provided directly, it must be an array of values.', "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not an array of values.", 'error'), diff --git a/generated/rules-v1.0.0.json b/generated/rules-v1.0.0.json index dbd393d..06d4d07 100644 --- a/generated/rules-v1.0.0.json +++ b/generated/rules-v1.0.0.json @@ -1551,22 +1551,6 @@ "status": "active", "check": "ref-type" }, - "FluxBalanceAnalysis-0006": { - "class": "FluxBalanceAnalysis", - "rule": "When the value of outputModel of a FluxBalanceAnalysis is provided directly, it must be a boolean.", - "message": "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not a boolean.", - "severity": "error", - "status": "active", - "check": "schema" - }, - "FluxBalanceAnalysis-0007": { - "class": "FluxBalanceAnalysis", - "rule": "When the value of outputModel of a FluxBalanceAnalysis is a reference, it must be a reference to a boolean.", - "message": "Attribute '{attr}' of {class} '{id}' is the reference '{value}', which resolves to '{resolved-value}', not a boolean.", - "severity": "error", - "status": "active", - "check": "ref-type" - }, "FluxBalanceAnalysis-0008": { "class": "FluxBalanceAnalysis", "rule": "The _type attribute of a FluxBalanceAnalysis must be \"fluxBalanceAnalysis\".", @@ -2607,14 +2591,6 @@ "status": "active", "check": "schema" }, - "Repeat-0005": { - "class": "Repeat", - "rule": "The range attribute of a Repeat, if present, must be a RangeInline object.", - "message": "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not a RangeInline object.", - "severity": "error", - "status": "active", - "check": "schema" - }, "Repeat-0006": { "class": "Repeat", "rule": "A Repeat must provide at least one of outputVariableMap or aggregateOutputVariables.", @@ -3063,22 +3039,6 @@ "status": "active", "check": "schema" }, - "SteadyState-0005": { - "class": "SteadyState", - "rule": "When the value of outputModel of a SteadyState is provided directly, it must be a boolean.", - "message": "Attribute '{attr}' of {class} '{id}' has value '{value}', which is not a boolean.", - "severity": "error", - "status": "active", - "check": "schema" - }, - "SteadyState-0006": { - "class": "SteadyState", - "rule": "When the value of outputModel of a SteadyState is a reference, it must be a reference to a boolean.", - "message": "Attribute '{attr}' of {class} '{id}' is the reference '{value}', which resolves to '{resolved-value}', not a boolean.", - "severity": "error", - "status": "active", - "check": "ref-type" - }, "StringFormation-0000": { "class": "StringFormation", "rule": "The element fails a JSON Schema constraint attributable to StringFormation that does not match any other numbered rule.", From f44d4e699fc7bacd7db442401d14482d035f5e2c Mon Sep 17 00:00:00 2001 From: Lucian Smith Date: Thu, 1 Oct 2026 11:14:42 -0700 Subject: [PATCH 3/5] Update generator to reflect new meaning of outputs.json Now we don't have a 'valid' flag normally; if it's listed, it's valid. If there are requirements, it's listed. --- core-spec.md | 4 ++-- generator/emit_java.py | 18 +++++++++++------- generator/emit_python.py | 19 +++++++++++-------- schema/outputs-meta.schema.json | 15 ++++++--------- .../SEDBase/v1.0.0/validation/SEDBase-0008.md | 7 ++++--- templates/cpp/runtime/OutputsShape.hpp | 11 +++++++---- 6 files changed, 41 insertions(+), 33 deletions(-) diff --git a/core-spec.md b/core-spec.md index 147fe4c..a42a08c 100644 --- a/core-spec.md +++ b/core-spec.md @@ -102,7 +102,7 @@ Each `//v1.0.0/` folder normally contains exactly: Every `schema.json`'s `required` array carries a sibling `x-required-rule-ids` object mapping each required field's name to the numbered validation rule that documents its presence requirement, and any property whose own constraint - a `_type` discriminator `const`, or a type/shape check beyond bare presence - has a matching numbered rule carries a sibling `x-rule-id` alongside that constraint (as a sibling of `$ref` where the property is declared that way); `x-rule-id` is a single rule-ID string, or an array of them when more than one rule governs the same property (most commonly an `OrRef` field's separate direct-value and reference-form rules, e.g. `AbstractODESimulation.forcePhysicalCorrectness`). A bare `SIdRef` property that must resolve to a particular kind of thing also carries `"x-ref-target": "model"` (SEDBase-0016) or `"x-ref-target": "annotatedData"` (SEDBase-0017). All of these are inert to any JSON Schema validator (unknown keywords are ignored) and exist purely as generator-only metadata - see Design.md's Validation section - so the generator can wire each hand-written `validate()` check straight to the schema location it corresponds to rather than re-deriving that mapping itself. Not every numbered rule has a schema-visible home this way: most are semantic (cross-reference resolution, math well-formedness, tolerance interactions, and the like) with no single JSON Schema keyword to attach to; only presence, discriminator, and simple type/shape constraints get one. A class whose own requiredness is disjunctive rather than a flat list - so far, only `Repeat`, whose subclasses need at least one of `outputVariableMap` or `aggregateOutputVariables` rather than a fixed set - expresses that as an `anyOf` of single-field `required` objects at the class's own top level (sibling to `properties`), with a sibling `x-anyof-required-rule-id` naming the one rule documenting the whole disjunction, rather than forcing it into `x-required-rule-ids`'s per-field mapping. A `oneOf` discriminator built via `x-generated-oneOf` (see Design.md's Classes section) can similarly carry a sibling `x-missing-type-rule-id`, naming a rule for the narrower case where `_type` is absent from the instance entirely, rather than present but unrecognized - a more specific error than the discriminator's own catch-all, for whichever discriminators want to distinguish it (e.g. `AbstractTask-0002`). -**Task output shapes (`outputs.json`).** Every concrete `tasks/` class (one with its own `_type`) additionally carries an `outputs.json`, machine-describing what each output suffix (`[id]`, `[id].model`, `[id].strings`, and any class-specific suffix like `Loop`'s `[id].aggregates`/`[id].range`/`[id].index`) resolves to - replacing the free-text "Valid"/"Invalid"/"Dimensions:" bullets that used to be the only record of this. Each suffix entry has a `valid` flag (`true`/`false`, or a boolean expression string over the task's own fields, e.g. `"outputModel == true"`, `"provided(range)"`), a `type` (`annotatedData`/`model`/`stringList`) when valid, and for `annotatedData` a `dimensions` list. Every place a size, a label set, or a whole shape needs stating, it's tagged with where that knowledge actually comes from - `"static"` (an `expr` computed from the task's own fields: `len(outputVariables)`, `independentVariableRange.numberOfSteps`, `keys(data)`, `[independentVariable] + outputVariables` as an array-literal-plus-concatenation, `shapeOf(input)` to inherit another reference's whole shape, optionally minus a dropped dimension via `- dim(...)`), `"input-file"` (knowable only by reading whatever external resource a field like `model` or `location` points to - `JacobianFull`'s species count, `CsvImport`'s column headers - tagged with `from`/`extract`/`note` rather than a formula, since the actual parsing is format-specific generator work, not something this file does itself), or `"runtime"` (genuinely not derivable without executing the simulation, e.g. `BoundedODESimulation`'s solver-chosen row count under variable step size, or `Loop`'s iteration count - always paired with a `note` explaining why). A `"runtime"` size may also carry an optional `min`, a guaranteed lower bound when one is actually known (e.g. "at least 2 rows"); an index or range that requires more entries than `min` guarantees is flagged by `SEDBase-0014` as a warning rather than an error, since it may still be valid once the simulation actually runs. `dimensions` itself is either a fixed array of per-dimension entries - an ordinary entry, or a `repeat` entry that expands to one dimension per entry of a named array-valued attribute (e.g. `ParameterScan`'s one dimension per entry of `parameterRanges`) - when the shape is decomposable dimension-by-dimension, or a single sourced object describing the whole shape's derivation, for the genuinely non-decomposable cases (`shapeOf(x)` whole-shape inheritance, or a `"runtime"`/`"input-file"` source where the dimension count itself isn't knowable ahead of time). `schema/outputs-meta.schema.json` validates every class's `outputs.json` envelope (the object shapes above); it does not parse `expr`/`note` string contents, which stay documentation for whoever implements the generator's shape-inference step. Abstract/mixin classes (`AbstractSimulation` and friends, `Repeat`) carry no `outputs.json` of their own, the same reasoning as why they carry no `_type` - nothing is ever instantiated as one directly, so "what does referencing this task's output produce" has no meaning until a concrete leaf class answers it, flatly, the same way those classes already flatten every other inherited constraint into their own `schema.json`. +**Task output shapes (`outputs.json`).** Every concrete `tasks/` class (one with its own `_type`) additionally carries an `outputs.json`, machine-describing what each output suffix (`[id]`, `[id].model`, `[id].strings`, and any class-specific suffix like `Loop`'s `[id].aggregates`/`[id].range`/`[id].index`) resolves to - replacing the free-text "Valid"/"Invalid"/"Dimensions:" bullets that used to be the only record of this. A suffix that is listed is valid, and a suffix that is not listed is not valid (a class with no valid suffixes, such as `Span`, lists none). A listed entry may carry an optional `valid` field meaning "valid if": a boolean expression string over the task's own fields, e.g. `"outputModel == true"`, `"provided(range)"`; with no `valid` field the entry is always valid. Each entry has a `type` (`annotatedData`/`model`/`stringList`), and for `annotatedData` a `dimensions` list. Every place a size, a label set, or a whole shape needs stating, it's tagged with where that knowledge actually comes from - `"static"` (an `expr` computed from the task's own fields: `len(outputVariables)`, `independentVariableRange.numberOfSteps`, `keys(data)`, `[independentVariable] + outputVariables` as an array-literal-plus-concatenation, `shapeOf(input)` to inherit another reference's whole shape, optionally minus a dropped dimension via `- dim(...)`), `"input-file"` (knowable only by reading whatever external resource a field like `model` or `location` points to - `JacobianFull`'s species count, `CsvImport`'s column headers - tagged with `from`/`extract`/`note` rather than a formula, since the actual parsing is format-specific generator work, not something this file does itself), or `"runtime"` (genuinely not derivable without executing the simulation, e.g. `BoundedODESimulation`'s solver-chosen row count under variable step size, or `Loop`'s iteration count - always paired with a `note` explaining why). A `"runtime"` size may also carry an optional `min`, a guaranteed lower bound when one is actually known (e.g. "at least 2 rows"); an index or range that requires more entries than `min` guarantees is flagged by `SEDBase-0014` as a warning rather than an error, since it may still be valid once the simulation actually runs. `dimensions` itself is either a fixed array of per-dimension entries - an ordinary entry, or a `repeat` entry that expands to one dimension per entry of a named array-valued attribute (e.g. `ParameterScan`'s one dimension per entry of `parameterRanges`) - when the shape is decomposable dimension-by-dimension, or a single sourced object describing the whole shape's derivation, for the genuinely non-decomposable cases (`shapeOf(x)` whole-shape inheritance, or a `"runtime"`/`"input-file"` source where the dimension count itself isn't knowable ahead of time). `schema/outputs-meta.schema.json` validates every class's `outputs.json` envelope (the object shapes above); it does not parse `expr`/`note` string contents, which stay documentation for whoever implements the generator's shape-inference step. Abstract/mixin classes (`AbstractSimulation` and friends, `Repeat`) carry no `outputs.json` of their own, the same reasoning as why they carry no `_type` - nothing is ever instantiated as one directly, so "what does referencing this task's output produce" has no meaning until a concrete leaf class answers it, flatly, the same way those classes already flatten every other inherited constraint into their own `schema.json`. **The `expr`/`valid` notation.** Both fields reuse one small expression language, evaluated against the task's own attribute values at generate/validate time - never against runtime data, and not the SED2 math grammar `Types-0001` through `Types-0004` validate (see this section's `x-rule-id` paragraph above and `Design.md`'s Math section for that separate grammar): `outputs.json` describes shape, `math` describes computation. A bare identifier names one of the task's own attributes and evaluates to its value (`outputVariables`); a dotted path reaches into a nested attribute the same way (`independentVariableRange.numberOfSteps`). `[x]` is an array literal (`[independentVariable]`); JSON numbers and `true`/`false` are literals too. Five functions: `len(x)` - the length of an array-valued `x`; or, when `x` is a Range-family value (a `RangeInline`/`NumericRangeInline`/`ParameterRangeInline`-typed field, or the reserved identifier `self` inside a `repeat` entry - see below), the number of points it resolves to, dispatched on `x`'s own discriminated type: `len(x.values) if provided(x.values) else x.numberOfSteps + 1` for `NumericRange`/`ParameterRange`, or just `len(x.values)` for a bare `Range` (which has no `numberOfSteps` alternative); `keys(x)` - the keys of an object-valued `x`, as an array; `shapeOf(x)` - the whole `dimensions` shape of a referenced AnnotatedData value; `dim(x)` - the dimension(s) named by `x` (a single name or a list of names) within a shape, meaningful only as the right operand of `-`; `provided(x)` - `true` iff attribute `x` was given a value in the document. Operators, at ordinary precedence: `!x` (boolean negation); `x == y` (equality); `x + y` (numeric addition when both operands are numbers, array concatenation when both are arrays - `1 + len(outputVariables)` vs. `[independentVariable] + outputVariables`); `shapeOf(x) - dim(y)` (a shape with the named dimension(s) removed - the only place `-` appears); `x or y` (`x`'s value when `provided(x)` holds, else the literal `y` - used for a field with a documented default, e.g. `dim(appliedDimensions or outermost)`, where `outermost` is a sentinel meaning the shape's own first dimension); and a conditional `x if provided(y) else z` for a value with two different derivations depending on whether an alternate field was given instead (e.g. `NumericRange`'s `len(values) if provided(values) else numberOfSteps + 1`). This is the only formal definition of the notation - `schema/outputs-meta.schema.json` does not parse it, as noted above - so a generator's shape-inference step implements it by hand. Inside a `dimensions` array's `repeat` entry (see above), this same notation applies to that entry's own `size`/`labels`, with two scoping additions: a bare identifier there resolves against the current array entry's own fields, not the task's top-level attributes; and the reserved identifier `self` refers to the current entry as a whole (for taking its `len()`, per above) rather than one of its fields. `ParameterScan`'s `repeat` over `parameterRanges` uses `size: len(self)`, letting each entry's own type (`Range`/`NumericRange`/`ParameterRange`) determine its own length the same way `Scatter`'s `len(range)` and `ExplicitODESimulation`'s `len(independentVariableRange)` do for their own named Range-family fields. @@ -119,7 +119,7 @@ tasks/Range/v1.0.0/ tasks/NumericRange/v1.0.0/ task `Range` and `NumericRange` carry an extra `common.schema.json` that `ParameterRange` and `Span` don't need: `Range` is both directly instantiable and the parent of `NumericRange`, and `NumericRange` is in turn both directly instantiable and the parent of `ParameterRange` - so each contributes a `RangeCommon`/`NumericRangeCommon` mixin (composed via `allOf`) carrying the fields its subclass inherits, alongside its own `schema.json` for the standalone-task form. `ParameterRange` and `Span` are leaves - nothing subclasses them - so they need no such split. Each mixin composes the next one up in turn (`NumericRangeCommon` composes `RangeCommon`, which composes `AbstractTaskCommon`), so a concrete class's own `allOf` names only its one most specific ancestor mixin - `ParameterRange` lists just `NumericRangeCommon`, not `RangeCommon` and `NumericRangeCommon` side by side - mirroring the UML chain directly rather than flattening every ancestor into each leaf; see `Design.md`'s Classes section for why. -Each `description.md` in these four folders explains all of that folder's schema files. Everything else in the document - including every cross-reference into these four classes from other Data Sheets' `schema.json` files - still resolves correctly; this was verified by validating real SED2 example documents against the split schemas after the merge. All four live under `tasks/` rather than `auxiliary/`, so each also carries the ordinary `outputs.json` every concrete `tasks/` class does - `Range`, `NumericRange`, and `ParameterRange` describe their `[id]` output for when they're used as a standalone `tasks` entry, and `Span`'s marks every suffix invalid, matching its own `description.md` (`Span` can never be a standalone `tasks` entry, only ever an embedded child, so it has no output of its own). +Each `description.md` in these four folders explains all of that folder's schema files. Everything else in the document - including every cross-reference into these four classes from other Data Sheets' `schema.json` files - still resolves correctly; this was verified by validating real SED2 example documents against the split schemas after the merge. All four live under `tasks/` rather than `auxiliary/`, so each also carries the ordinary `outputs.json` every concrete `tasks/` class does - `Range`, `NumericRange`, and `ParameterRange` describe their `[id]` output for when they're used as a standalone `tasks` entry, and `Span`'s lists no suffixes at all (so every suffix is invalid), matching its own `description.md` (`Span` can never be a standalone `tasks` entry, only ever an embedded child, so it has no output of its own). **Exception - the two `*Common` mixins.** `AbstractTaskCommon` and `AbstractOutputCommon` are schema-only mixins (composed via `allOf`) rather than modeled classes with their own UML box: they contribute the fields every concrete Task (or Output) picks up beyond `SEDBase` - `taskParameters`/`outputParameters` - but have no `_type` of their own and are never instantiated directly. Rather than give them placeholder folders, each is merged into its family's base-class folder as a second schema file: diff --git a/generator/emit_java.py b/generator/emit_java.py index 60bf08b..0011758 100644 --- a/generator/emit_java.py +++ b/generator/emit_java.py @@ -2342,13 +2342,16 @@ def _fmt_entry(name: str, spec: tuple) -> str: return result; } - /** entry["valid"] is true/false, or a boolean expr string over the - * task's own fields. Returns TRUE/FALSE, or null when a string expr - * couldn't be evaluated statically ("the rule does not fire"). */ + /** A suffix entry that is listed in outputs.json is valid; one that isn't + * listed is not (resolveOutput handles that). An entry's optional "valid" + * field is a boolean expr string over the task's own fields meaning + * "valid if"; no "valid" field means always valid. Returns TRUE/FALSE, or + * null when the expr couldn't be evaluated statically ("the rule does not + * fire"). */ static Boolean evalValid(JsonNode entry, Scope scope, Function> shapeOf) { JsonNode valid = entry.get("valid"); - if (valid != null && valid.isBoolean()) return valid.booleanValue(); - if (valid != null && valid.isTextual()) { + if (valid == null) return Boolean.TRUE; + if (valid.isTextual()) { try { return truthy(eval(parseExpr(valid.textValue()), scope, shapeOf)); } catch (NotStatic e) { @@ -2360,8 +2363,9 @@ def _fmt_entry(name: str, spec: tuple) -> str: /** The result of resolveOutput: see that method. */ public static final class Resolution { - /** TRUE (suffix exists and its "valid" evaluated true), FALSE (absent - * or evaluates false), or null (couldn't be determined statically). */ + /** TRUE (suffix is listed and has no "valid" field, or its "valid" + * ("valid if") expr evaluated true), FALSE (not listed, or the expr + * evaluates false), or null (couldn't be determined statically). */ public final Boolean ok; public final JsonNode entry; // the raw outputEntry, or null when the suffix key is absent public final List dimsBefore; // null unless ok == TRUE and the entry has resolvable "dimensions" diff --git a/generator/emit_python.py b/generator/emit_python.py index 42308bc..279f798 100644 --- a/generator/emit_python.py +++ b/generator/emit_python.py @@ -2411,13 +2411,15 @@ def _apply_index_chain(dims, index_accessors): def eval_valid(entry, scope, shape_of): - """entry["valid"] is True/False, or a boolean expr string over the - task's own fields. Returns True/False, or None when a string expr - couldn't be evaluated statically (SEDBase-0008: "the rule does not - fire" in that case).""" + """A suffix entry that is listed in outputs.json is valid; one that + isn't listed is not (resolve_output handles that). An entry's optional + "valid" field is a boolean expr string over the task's own fields + meaning "valid if". No "valid" field: always valid. Returns True/False, + or None when the expr couldn't be evaluated statically (SEDBase-0008: + "the rule does not fire" in that case).""" valid = entry.get("valid") - if valid is True or valid is False: - return valid + if valid is None: + return True if isinstance(valid, str): try: return bool(eval_expr(parse_expr(valid), scope, shape_of)) @@ -2433,8 +2435,9 @@ def resolve_output(outputs_json, fields, accessors, shape_of): `fields` is the referenced task's own _own_json_value() dict; `accessors` is a ParsedReference's own .accessors list. Returns (accessor_ok, entry, dims_before, dims_after, dot_name, index_accessors): - - accessor_ok: True (the suffix exists and its "valid" evaluated - true), False (suffix absent or "valid" is/evaluates false), or None + - accessor_ok: True (the suffix is listed and has no "valid" field, + or its "valid" ("valid if") expr evaluated true), False (suffix + not listed, or its "valid" expr evaluated false), or None (couldn't be determined statically - every caller treats this the same as False for "don't fire a positive claim" but ALSO suppresses every rule that would need to know for sure, per the "only fires diff --git a/schema/outputs-meta.schema.json b/schema/outputs-meta.schema.json index 7e4b90f..d94ad2d 100644 --- a/schema/outputs-meta.schema.json +++ b/schema/outputs-meta.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://sed-ml.org/schemas/meta/outputs-meta.schema.json", "title": "SED2 outputs.json meta-schema", - "description": "Validates the ENVELOPE shape of a per-class outputs.json file (specsheets/tasks//v1.0.0/outputs.json) - not the internal syntax of its 'expr'/'note' strings, which is documented in prose (see Design.md's Task Output Shapes section) rather than formally parsed here.", + "description": "Validates the ENVELOPE shape of a per-class outputs.json file (specsheets/tasks//v1.0.0/outputs.json) - every listed suffix is valid (optionally only 'valid' if a condition holds), every unlisted suffix is invalid - not the internal syntax of its 'expr'/'note' strings, which is documented in prose (see Design.md's Task Output Shapes section) rather than formally parsed here.", "$defs": { "sourced": { "description": "How a size, label set, or whole dimensions list is known.", @@ -87,17 +87,15 @@ "type": "object", "properties": { "valid": { - "description": "true, false, or a boolean expression string conditioning validity on the task's own fields (e.g. \"outputModel == true\", \"provided(range)\").", - "anyOf": [ { "type": "boolean" }, { "type": "string", "minLength": 1 } ] + "description": "Optional 'valid if' condition: a boolean expression string over the task's own fields (e.g. \"outputModel == true\", \"provided(range)\"). A suffix that is listed with no 'valid' field is always valid; a suffix that is not listed at all is never valid.", + "type": "string", + "minLength": 1 }, "type": { "enum": ["annotatedData", "model", "stringList"] }, "dimensions": { "$ref": "#/$defs/dimensions" }, "note": { "type": "string" } }, - "required": ["valid"], - "if": { "properties": { "valid": { "const": false } } }, - "then": {}, - "else": { "required": ["type"] }, + "required": ["type"], "additionalProperties": false } }, @@ -106,8 +104,7 @@ "outputs": { "type": "object", "propertyNames": { "pattern": "^\\[id\\]" }, - "additionalProperties": { "$ref": "#/$defs/outputEntry" }, - "minProperties": 1 + "additionalProperties": { "$ref": "#/$defs/outputEntry" } } }, "required": ["outputs"], diff --git a/specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0008.md b/specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0008.md index c873ca4..b5278dd 100644 --- a/specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0008.md +++ b/specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0008.md @@ -7,9 +7,10 @@ status: active check: handwritten --- -For a task target, the accessor must appear in that task class's outputs.json, -and its "valid" field must be true, or be an expression that evaluates to true -against the target's own fields. When the expression cannot be evaluated +For a task target, the accessor must be listed in that task class's outputs.json +(a suffix that is not listed is not valid), and, if the entry has a "valid" +field, that field's expression must evaluate to true against the target's own +fields. An entry with no "valid" field is always valid. When the expression cannot be evaluated statically (it depends on a reference that resolves only at run time), the rule does not fire. diff --git a/templates/cpp/runtime/OutputsShape.hpp b/templates/cpp/runtime/OutputsShape.hpp index a544c2a..bd52c87 100644 --- a/templates/cpp/runtime/OutputsShape.hpp +++ b/templates/cpp/runtime/OutputsShape.hpp @@ -615,12 +615,15 @@ inline OptDims apply_index_chain(const OptDims& dims, const std::vector eval_valid(const Json& entry, const Scope& scope, const ShapeOf& shape_of) { const Json* valid = member(entry, "valid"); - if (valid && valid->is_bool()) return valid->as(); - if (valid && valid->is_string()) { + if (!valid) return true; + if (valid->is_string()) { try { return val_truthy(eval_expr(*parse_expr(valid->as()), scope, shape_of)); } catch (const NotStatic&) { From 17a9d703482c740b854880cb962a9f40971c2ba2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 1 Oct 2026 18:17:07 +0000 Subject: [PATCH 4/5] Regenerate generated directories and SPECIFICATION.md from spec --- SPECIFICATION.md | 11 ++++++----- .../cpp/include/libsed2/OutputsShape.hpp | 11 +++++++---- .../java/org/sedml/libsed2/OutputsShape.java | 18 +++++++++++------- generated/python/src/libsed2/outputs_shape.py | 19 +++++++++++-------- .../cpp/include/sed2test/OutputsShape.hpp | 11 +++++++---- .../main/java/org/sed2test/OutputsShape.java | 18 +++++++++++------- .../python/src/libsed2test/outputs_shape.py | 19 +++++++++++-------- 7 files changed, 64 insertions(+), 43 deletions(-) diff --git a/SPECIFICATION.md b/SPECIFICATION.md index dfb6f0a..50f8d7c 100644 --- a/SPECIFICATION.md +++ b/SPECIFICATION.md @@ -209,7 +209,7 @@ Each `//v1.0.0/` folder normally contains exactly: Every `schema.json`'s `required` array carries a sibling `x-required-rule-ids` object mapping each required field's name to the numbered validation rule that documents its presence requirement, and any property whose own constraint - a `_type` discriminator `const`, or a type/shape check beyond bare presence - has a matching numbered rule carries a sibling `x-rule-id` alongside that constraint (as a sibling of `$ref` where the property is declared that way); `x-rule-id` is a single rule-ID string, or an array of them when more than one rule governs the same property (most commonly an `OrRef` field's separate direct-value and reference-form rules, e.g. `AbstractODESimulation.forcePhysicalCorrectness`). A bare `SIdRef` property that must resolve to a particular kind of thing also carries `"x-ref-target": "model"` (SEDBase-0016) or `"x-ref-target": "annotatedData"` (SEDBase-0017). All of these are inert to any JSON Schema validator (unknown keywords are ignored) and exist purely as generator-only metadata - see Design.md's Validation section - so the generator can wire each hand-written `validate()` check straight to the schema location it corresponds to rather than re-deriving that mapping itself. Not every numbered rule has a schema-visible home this way: most are semantic (cross-reference resolution, math well-formedness, tolerance interactions, and the like) with no single JSON Schema keyword to attach to; only presence, discriminator, and simple type/shape constraints get one. A class whose own requiredness is disjunctive rather than a flat list - so far, only `Repeat`, whose subclasses need at least one of `outputVariableMap` or `aggregateOutputVariables` rather than a fixed set - expresses that as an `anyOf` of single-field `required` objects at the class's own top level (sibling to `properties`), with a sibling `x-anyof-required-rule-id` naming the one rule documenting the whole disjunction, rather than forcing it into `x-required-rule-ids`'s per-field mapping. A `oneOf` discriminator built via `x-generated-oneOf` (see Design.md's Classes section) can similarly carry a sibling `x-missing-type-rule-id`, naming a rule for the narrower case where `_type` is absent from the instance entirely, rather than present but unrecognized - a more specific error than the discriminator's own catch-all, for whichever discriminators want to distinguish it (e.g. `AbstractTask-0002`). -**Task output shapes (`outputs.json`).** Every concrete `tasks/` class (one with its own `_type`) additionally carries an `outputs.json`, machine-describing what each output suffix (`[id]`, `[id].model`, `[id].strings`, and any class-specific suffix like `Loop`'s `[id].aggregates`/`[id].range`/`[id].index`) resolves to - replacing the free-text "Valid"/"Invalid"/"Dimensions:" bullets that used to be the only record of this. Each suffix entry has a `valid` flag (`true`/`false`, or a boolean expression string over the task's own fields, e.g. `"outputModel == true"`, `"provided(range)"`), a `type` (`annotatedData`/`model`/`stringList`) when valid, and for `annotatedData` a `dimensions` list. Every place a size, a label set, or a whole shape needs stating, it's tagged with where that knowledge actually comes from - `"static"` (an `expr` computed from the task's own fields: `len(outputVariables)`, `independentVariableRange.numberOfSteps`, `keys(data)`, `[independentVariable] + outputVariables` as an array-literal-plus-concatenation, `shapeOf(input)` to inherit another reference's whole shape, optionally minus a dropped dimension via `- dim(...)`), `"input-file"` (knowable only by reading whatever external resource a field like `model` or `location` points to - `JacobianFull`'s species count, `CsvImport`'s column headers - tagged with `from`/`extract`/`note` rather than a formula, since the actual parsing is format-specific generator work, not something this file does itself), or `"runtime"` (genuinely not derivable without executing the simulation, e.g. `BoundedODESimulation`'s solver-chosen row count under variable step size, or `Loop`'s iteration count - always paired with a `note` explaining why). A `"runtime"` size may also carry an optional `min`, a guaranteed lower bound when one is actually known (e.g. "at least 2 rows"); an index or range that requires more entries than `min` guarantees is flagged by `SEDBase-0014` as a warning rather than an error, since it may still be valid once the simulation actually runs. `dimensions` itself is either a fixed array of per-dimension entries - an ordinary entry, or a `repeat` entry that expands to one dimension per entry of a named array-valued attribute (e.g. `ParameterScan`'s one dimension per entry of `parameterRanges`) - when the shape is decomposable dimension-by-dimension, or a single sourced object describing the whole shape's derivation, for the genuinely non-decomposable cases (`shapeOf(x)` whole-shape inheritance, or a `"runtime"`/`"input-file"` source where the dimension count itself isn't knowable ahead of time). `schema/outputs-meta.schema.json` validates every class's `outputs.json` envelope (the object shapes above); it does not parse `expr`/`note` string contents, which stay documentation for whoever implements the generator's shape-inference step. Abstract/mixin classes (`AbstractSimulation` and friends, `Repeat`) carry no `outputs.json` of their own, the same reasoning as why they carry no `_type` - nothing is ever instantiated as one directly, so "what does referencing this task's output produce" has no meaning until a concrete leaf class answers it, flatly, the same way those classes already flatten every other inherited constraint into their own `schema.json`. +**Task output shapes (`outputs.json`).** Every concrete `tasks/` class (one with its own `_type`) additionally carries an `outputs.json`, machine-describing what each output suffix (`[id]`, `[id].model`, `[id].strings`, and any class-specific suffix like `Loop`'s `[id].aggregates`/`[id].range`/`[id].index`) resolves to - replacing the free-text "Valid"/"Invalid"/"Dimensions:" bullets that used to be the only record of this. A suffix that is listed is valid, and a suffix that is not listed is not valid (a class with no valid suffixes, such as `Span`, lists none). A listed entry may carry an optional `valid` field meaning "valid if": a boolean expression string over the task's own fields, e.g. `"outputModel == true"`, `"provided(range)"`; with no `valid` field the entry is always valid. Each entry has a `type` (`annotatedData`/`model`/`stringList`), and for `annotatedData` a `dimensions` list. Every place a size, a label set, or a whole shape needs stating, it's tagged with where that knowledge actually comes from - `"static"` (an `expr` computed from the task's own fields: `len(outputVariables)`, `independentVariableRange.numberOfSteps`, `keys(data)`, `[independentVariable] + outputVariables` as an array-literal-plus-concatenation, `shapeOf(input)` to inherit another reference's whole shape, optionally minus a dropped dimension via `- dim(...)`), `"input-file"` (knowable only by reading whatever external resource a field like `model` or `location` points to - `JacobianFull`'s species count, `CsvImport`'s column headers - tagged with `from`/`extract`/`note` rather than a formula, since the actual parsing is format-specific generator work, not something this file does itself), or `"runtime"` (genuinely not derivable without executing the simulation, e.g. `BoundedODESimulation`'s solver-chosen row count under variable step size, or `Loop`'s iteration count - always paired with a `note` explaining why). A `"runtime"` size may also carry an optional `min`, a guaranteed lower bound when one is actually known (e.g. "at least 2 rows"); an index or range that requires more entries than `min` guarantees is flagged by `SEDBase-0014` as a warning rather than an error, since it may still be valid once the simulation actually runs. `dimensions` itself is either a fixed array of per-dimension entries - an ordinary entry, or a `repeat` entry that expands to one dimension per entry of a named array-valued attribute (e.g. `ParameterScan`'s one dimension per entry of `parameterRanges`) - when the shape is decomposable dimension-by-dimension, or a single sourced object describing the whole shape's derivation, for the genuinely non-decomposable cases (`shapeOf(x)` whole-shape inheritance, or a `"runtime"`/`"input-file"` source where the dimension count itself isn't knowable ahead of time). `schema/outputs-meta.schema.json` validates every class's `outputs.json` envelope (the object shapes above); it does not parse `expr`/`note` string contents, which stay documentation for whoever implements the generator's shape-inference step. Abstract/mixin classes (`AbstractSimulation` and friends, `Repeat`) carry no `outputs.json` of their own, the same reasoning as why they carry no `_type` - nothing is ever instantiated as one directly, so "what does referencing this task's output produce" has no meaning until a concrete leaf class answers it, flatly, the same way those classes already flatten every other inherited constraint into their own `schema.json`. **The `expr`/`valid` notation.** Both fields reuse one small expression language, evaluated against the task's own attribute values at generate/validate time - never against runtime data, and not the SED2 math grammar `Types-0001` through `Types-0004` validate (see this section's `x-rule-id` paragraph above and `Design.md`'s Math section for that separate grammar): `outputs.json` describes shape, `math` describes computation. A bare identifier names one of the task's own attributes and evaluates to its value (`outputVariables`); a dotted path reaches into a nested attribute the same way (`independentVariableRange.numberOfSteps`). `[x]` is an array literal (`[independentVariable]`); JSON numbers and `true`/`false` are literals too. Five functions: `len(x)` - the length of an array-valued `x`; or, when `x` is a Range-family value (a `RangeInline`/`NumericRangeInline`/`ParameterRangeInline`-typed field, or the reserved identifier `self` inside a `repeat` entry - see below), the number of points it resolves to, dispatched on `x`'s own discriminated type: `len(x.values) if provided(x.values) else x.numberOfSteps + 1` for `NumericRange`/`ParameterRange`, or just `len(x.values)` for a bare `Range` (which has no `numberOfSteps` alternative); `keys(x)` - the keys of an object-valued `x`, as an array; `shapeOf(x)` - the whole `dimensions` shape of a referenced AnnotatedData value; `dim(x)` - the dimension(s) named by `x` (a single name or a list of names) within a shape, meaningful only as the right operand of `-`; `provided(x)` - `true` iff attribute `x` was given a value in the document. Operators, at ordinary precedence: `!x` (boolean negation); `x == y` (equality); `x + y` (numeric addition when both operands are numbers, array concatenation when both are arrays - `1 + len(outputVariables)` vs. `[independentVariable] + outputVariables`); `shapeOf(x) - dim(y)` (a shape with the named dimension(s) removed - the only place `-` appears); `x or y` (`x`'s value when `provided(x)` holds, else the literal `y` - used for a field with a documented default, e.g. `dim(appliedDimensions or outermost)`, where `outermost` is a sentinel meaning the shape's own first dimension); and a conditional `x if provided(y) else z` for a value with two different derivations depending on whether an alternate field was given instead (e.g. `NumericRange`'s `len(values) if provided(values) else numberOfSteps + 1`). This is the only formal definition of the notation - `schema/outputs-meta.schema.json` does not parse it, as noted above - so a generator's shape-inference step implements it by hand. Inside a `dimensions` array's `repeat` entry (see above), this same notation applies to that entry's own `size`/`labels`, with two scoping additions: a bare identifier there resolves against the current array entry's own fields, not the task's top-level attributes; and the reserved identifier `self` refers to the current entry as a whole (for taking its `len()`, per above) rather than one of its fields. `ParameterScan`'s `repeat` over `parameterRanges` uses `size: len(self)`, letting each entry's own type (`Range`/`NumericRange`/`ParameterRange`) determine its own length the same way `Scatter`'s `len(range)` and `ExplicitODESimulation`'s `len(independentVariableRange)` do for their own named Range-family fields. @@ -226,7 +226,7 @@ tasks/Range/v1.0.0/ tasks/NumericRange/v1.0.0/ task `Range` and `NumericRange` carry an extra `common.schema.json` that `ParameterRange` and `Span` don't need: `Range` is both directly instantiable and the parent of `NumericRange`, and `NumericRange` is in turn both directly instantiable and the parent of `ParameterRange` - so each contributes a `RangeCommon`/`NumericRangeCommon` mixin (composed via `allOf`) carrying the fields its subclass inherits, alongside its own `schema.json` for the standalone-task form. `ParameterRange` and `Span` are leaves - nothing subclasses them - so they need no such split. Each mixin composes the next one up in turn (`NumericRangeCommon` composes `RangeCommon`, which composes `AbstractTaskCommon`), so a concrete class's own `allOf` names only its one most specific ancestor mixin - `ParameterRange` lists just `NumericRangeCommon`, not `RangeCommon` and `NumericRangeCommon` side by side - mirroring the UML chain directly rather than flattening every ancestor into each leaf; see `Design.md`'s Classes section for why. -Each `description.md` in these four folders explains all of that folder's schema files. Everything else in the document - including every cross-reference into these four classes from other Data Sheets' `schema.json` files - still resolves correctly; this was verified by validating real SED2 example documents against the split schemas after the merge. All four live under `tasks/` rather than `auxiliary/`, so each also carries the ordinary `outputs.json` every concrete `tasks/` class does - `Range`, `NumericRange`, and `ParameterRange` describe their `[id]` output for when they're used as a standalone `tasks` entry, and `Span`'s marks every suffix invalid, matching its own `description.md` (`Span` can never be a standalone `tasks` entry, only ever an embedded child, so it has no output of its own). +Each `description.md` in these four folders explains all of that folder's schema files. Everything else in the document - including every cross-reference into these four classes from other Data Sheets' `schema.json` files - still resolves correctly; this was verified by validating real SED2 example documents against the split schemas after the merge. All four live under `tasks/` rather than `auxiliary/`, so each also carries the ordinary `outputs.json` every concrete `tasks/` class does - `Range`, `NumericRange`, and `ParameterRange` describe their `[id]` output for when they're used as a standalone `tasks` entry, and `Span`'s lists no suffixes at all (so every suffix is invalid), matching its own `description.md` (`Span` can never be a standalone `tasks` entry, only ever an embedded child, so it has no output of its own). **Exception - the two `*Common` mixins.** `AbstractTaskCommon` and `AbstractOutputCommon` are schema-only mixins (composed via `allOf`) rather than modeled classes with their own UML box: they contribute the fields every concrete Task (or Output) picks up beyond `SEDBase` - `taskParameters`/`outputParameters` - but have no `_type` of their own and are never instantiated directly. Rather than give them placeholder folders, each is merged into its family's base-class folder as a second schema file: @@ -371,9 +371,10 @@ Every element inherits `SEDBase`, but whether `[id]`, `[id].model`, or `[id].str **`SEDBase-0008`** (error) - A dot-accessor in a reference must be one the target declares valid. ([source](specsheets/core/SEDBase/v1.0.0/validation/SEDBase-0008.md)) -> For a task target, the accessor must appear in that task class's outputs.json, -> and its "valid" field must be true, or be an expression that evaluates to true -> against the target's own fields. When the expression cannot be evaluated +> For a task target, the accessor must be listed in that task class's outputs.json +> (a suffix that is not listed is not valid), and, if the entry has a "valid" +> field, that field's expression must evaluate to true against the target's own +> fields. An entry with no "valid" field is always valid. When the expression cannot be evaluated > statically (it depends on a reference that resolves only at run time), the > rule does not fire. > diff --git a/generated/cpp/include/libsed2/OutputsShape.hpp b/generated/cpp/include/libsed2/OutputsShape.hpp index 5756523..816fe5c 100644 --- a/generated/cpp/include/libsed2/OutputsShape.hpp +++ b/generated/cpp/include/libsed2/OutputsShape.hpp @@ -615,12 +615,15 @@ inline OptDims apply_index_chain(const OptDims& dims, const std::vector eval_valid(const Json& entry, const Scope& scope, const ShapeOf& shape_of) { const Json* valid = member(entry, "valid"); - if (valid && valid->is_bool()) return valid->as(); - if (valid && valid->is_string()) { + if (!valid) return true; + if (valid->is_string()) { try { return val_truthy(eval_expr(*parse_expr(valid->as()), scope, shape_of)); } catch (const NotStatic&) { diff --git a/generated/java/src/main/java/org/sedml/libsed2/OutputsShape.java b/generated/java/src/main/java/org/sedml/libsed2/OutputsShape.java index 85bccb9..a65bd83 100644 --- a/generated/java/src/main/java/org/sedml/libsed2/OutputsShape.java +++ b/generated/java/src/main/java/org/sedml/libsed2/OutputsShape.java @@ -704,13 +704,16 @@ static List applyIndexChain(List dims, List indexAccessors) return result; } - /** entry["valid"] is true/false, or a boolean expr string over the - * task's own fields. Returns TRUE/FALSE, or null when a string expr - * couldn't be evaluated statically ("the rule does not fire"). */ + /** A suffix entry that is listed in outputs.json is valid; one that isn't + * listed is not (resolveOutput handles that). An entry's optional "valid" + * field is a boolean expr string over the task's own fields meaning + * "valid if"; no "valid" field means always valid. Returns TRUE/FALSE, or + * null when the expr couldn't be evaluated statically ("the rule does not + * fire"). */ static Boolean evalValid(JsonNode entry, Scope scope, Function> shapeOf) { JsonNode valid = entry.get("valid"); - if (valid != null && valid.isBoolean()) return valid.booleanValue(); - if (valid != null && valid.isTextual()) { + if (valid == null) return Boolean.TRUE; + if (valid.isTextual()) { try { return truthy(eval(parseExpr(valid.textValue()), scope, shapeOf)); } catch (NotStatic e) { @@ -722,8 +725,9 @@ static Boolean evalValid(JsonNode entry, Scope scope, Function /** The result of resolveOutput: see that method. */ public static final class Resolution { - /** TRUE (suffix exists and its "valid" evaluated true), FALSE (absent - * or evaluates false), or null (couldn't be determined statically). */ + /** TRUE (suffix is listed and has no "valid" field, or its "valid" + * ("valid if") expr evaluated true), FALSE (not listed, or the expr + * evaluates false), or null (couldn't be determined statically). */ public final Boolean ok; public final JsonNode entry; // the raw outputEntry, or null when the suffix key is absent public final List dimsBefore; // null unless ok == TRUE and the entry has resolvable "dimensions" diff --git a/generated/python/src/libsed2/outputs_shape.py b/generated/python/src/libsed2/outputs_shape.py index db4c30a..f8766e0 100644 --- a/generated/python/src/libsed2/outputs_shape.py +++ b/generated/python/src/libsed2/outputs_shape.py @@ -530,13 +530,15 @@ def _apply_index_chain(dims, index_accessors): def eval_valid(entry, scope, shape_of): - """entry["valid"] is True/False, or a boolean expr string over the - task's own fields. Returns True/False, or None when a string expr - couldn't be evaluated statically (SEDBase-0008: "the rule does not - fire" in that case).""" + """A suffix entry that is listed in outputs.json is valid; one that + isn't listed is not (resolve_output handles that). An entry's optional + "valid" field is a boolean expr string over the task's own fields + meaning "valid if". No "valid" field: always valid. Returns True/False, + or None when the expr couldn't be evaluated statically (SEDBase-0008: + "the rule does not fire" in that case).""" valid = entry.get("valid") - if valid is True or valid is False: - return valid + if valid is None: + return True if isinstance(valid, str): try: return bool(eval_expr(parse_expr(valid), scope, shape_of)) @@ -552,8 +554,9 @@ def resolve_output(outputs_json, fields, accessors, shape_of): `fields` is the referenced task's own _own_json_value() dict; `accessors` is a ParsedReference's own .accessors list. Returns (accessor_ok, entry, dims_before, dims_after, dot_name, index_accessors): - - accessor_ok: True (the suffix exists and its "valid" evaluated - true), False (suffix absent or "valid" is/evaluates false), or None + - accessor_ok: True (the suffix is listed and has no "valid" field, + or its "valid" ("valid if") expr evaluated true), False (suffix + not listed, or its "valid" expr evaluated false), or None (couldn't be determined statically - every caller treats this the same as False for "don't fire a positive claim" but ALSO suppresses every rule that would need to know for sure, per the "only fires diff --git a/test-specsheets/generated/cpp/include/sed2test/OutputsShape.hpp b/test-specsheets/generated/cpp/include/sed2test/OutputsShape.hpp index a544c2a..bd52c87 100644 --- a/test-specsheets/generated/cpp/include/sed2test/OutputsShape.hpp +++ b/test-specsheets/generated/cpp/include/sed2test/OutputsShape.hpp @@ -615,12 +615,15 @@ inline OptDims apply_index_chain(const OptDims& dims, const std::vector eval_valid(const Json& entry, const Scope& scope, const ShapeOf& shape_of) { const Json* valid = member(entry, "valid"); - if (valid && valid->is_bool()) return valid->as(); - if (valid && valid->is_string()) { + if (!valid) return true; + if (valid->is_string()) { try { return val_truthy(eval_expr(*parse_expr(valid->as()), scope, shape_of)); } catch (const NotStatic&) { diff --git a/test-specsheets/generated/java/src/main/java/org/sed2test/OutputsShape.java b/test-specsheets/generated/java/src/main/java/org/sed2test/OutputsShape.java index c0558b5..103daa9 100644 --- a/test-specsheets/generated/java/src/main/java/org/sed2test/OutputsShape.java +++ b/test-specsheets/generated/java/src/main/java/org/sed2test/OutputsShape.java @@ -704,13 +704,16 @@ static List applyIndexChain(List dims, List indexAccessors) return result; } - /** entry["valid"] is true/false, or a boolean expr string over the - * task's own fields. Returns TRUE/FALSE, or null when a string expr - * couldn't be evaluated statically ("the rule does not fire"). */ + /** A suffix entry that is listed in outputs.json is valid; one that isn't + * listed is not (resolveOutput handles that). An entry's optional "valid" + * field is a boolean expr string over the task's own fields meaning + * "valid if"; no "valid" field means always valid. Returns TRUE/FALSE, or + * null when the expr couldn't be evaluated statically ("the rule does not + * fire"). */ static Boolean evalValid(JsonNode entry, Scope scope, Function> shapeOf) { JsonNode valid = entry.get("valid"); - if (valid != null && valid.isBoolean()) return valid.booleanValue(); - if (valid != null && valid.isTextual()) { + if (valid == null) return Boolean.TRUE; + if (valid.isTextual()) { try { return truthy(eval(parseExpr(valid.textValue()), scope, shapeOf)); } catch (NotStatic e) { @@ -722,8 +725,9 @@ static Boolean evalValid(JsonNode entry, Scope scope, Function /** The result of resolveOutput: see that method. */ public static final class Resolution { - /** TRUE (suffix exists and its "valid" evaluated true), FALSE (absent - * or evaluates false), or null (couldn't be determined statically). */ + /** TRUE (suffix is listed and has no "valid" field, or its "valid" + * ("valid if") expr evaluated true), FALSE (not listed, or the expr + * evaluates false), or null (couldn't be determined statically). */ public final Boolean ok; public final JsonNode entry; // the raw outputEntry, or null when the suffix key is absent public final List dimsBefore; // null unless ok == TRUE and the entry has resolvable "dimensions" diff --git a/test-specsheets/generated/python/src/libsed2test/outputs_shape.py b/test-specsheets/generated/python/src/libsed2test/outputs_shape.py index db4c30a..f8766e0 100644 --- a/test-specsheets/generated/python/src/libsed2test/outputs_shape.py +++ b/test-specsheets/generated/python/src/libsed2test/outputs_shape.py @@ -530,13 +530,15 @@ def _apply_index_chain(dims, index_accessors): def eval_valid(entry, scope, shape_of): - """entry["valid"] is True/False, or a boolean expr string over the - task's own fields. Returns True/False, or None when a string expr - couldn't be evaluated statically (SEDBase-0008: "the rule does not - fire" in that case).""" + """A suffix entry that is listed in outputs.json is valid; one that + isn't listed is not (resolve_output handles that). An entry's optional + "valid" field is a boolean expr string over the task's own fields + meaning "valid if". No "valid" field: always valid. Returns True/False, + or None when the expr couldn't be evaluated statically (SEDBase-0008: + "the rule does not fire" in that case).""" valid = entry.get("valid") - if valid is True or valid is False: - return valid + if valid is None: + return True if isinstance(valid, str): try: return bool(eval_expr(parse_expr(valid), scope, shape_of)) @@ -552,8 +554,9 @@ def resolve_output(outputs_json, fields, accessors, shape_of): `fields` is the referenced task's own _own_json_value() dict; `accessors` is a ParsedReference's own .accessors list. Returns (accessor_ok, entry, dims_before, dims_after, dot_name, index_accessors): - - accessor_ok: True (the suffix exists and its "valid" evaluated - true), False (suffix absent or "valid" is/evaluates false), or None + - accessor_ok: True (the suffix is listed and has no "valid" field, + or its "valid" ("valid if") expr evaluated true), False (suffix + not listed, or its "valid" expr evaluated false), or None (couldn't be determined statically - every caller treats this the same as False for "don't fire a positive claim" but ALSO suppresses every rule that would need to know for sure, per the "only fires From 7e69936bb86cb9ca9e2c091175761b1f1ca91523 Mon Sep 17 00:00:00 2001 From: Lucian Smith Date: Thu, 1 Oct 2026 12:35:00 -0700 Subject: [PATCH 5/5] Fix handwritten tests to match new spec. --- ...ble-0004-fail-01-constant-target.sed2.json | 8 +++ ...4-fail-01-scalar-constant-target.sed2.json | 8 +++ ...eat-0008-fail-01-constant-target.sed2.json | 8 +++ ...peat-0008-pass-00-subtask-target.sed2.json | 8 +++ ...peat-0009-fail-01-constant-input.sed2.json | 8 +++ ...06-fail-01-missing-loop-variable.sed2.json | 8 +++ ...ase-0006-fail-01-missing-subtask.sed2.json | 8 +++ ...eep-reference-from-inside-repeat.sed2.json | 8 +++ ...il-01-conditional-accessor-false.sed2.json | 52 +++++++++----- ...al-accessor-depends-on-reference.sed2.json | 72 ------------------- ...ass-00-conditional-accessor-true.sed2.json | 58 ++++++++++----- ...00-runtime-dimension-never-fires.sed2.json | 20 ++---- ...pass-00-runtime-size-never-fires.sed2.json | 28 ++++---- ...-nested-subtask-uses-outer-index.sed2.json | 8 +++ 14 files changed, 163 insertions(+), 139 deletions(-) delete mode 100644 fixtures/handwritten/SEDBase-0008-pass-00-conditional-accessor-depends-on-reference.sed2.json diff --git a/fixtures/handwritten/LoopVariable-0004-fail-01-constant-target.sed2.json b/fixtures/handwritten/LoopVariable-0004-fail-01-constant-target.sed2.json index 4337ebd..f275140 100644 --- a/fixtures/handwritten/LoopVariable-0004-fail-01-constant-target.sed2.json +++ b/fixtures/handwritten/LoopVariable-0004-fail-01-constant-target.sed2.json @@ -31,6 +31,14 @@ }, "outputVariableMap": { "col": "#tasks:loop1:subTasks:sub1.model" + }, + "range": { + "_type": "numericRange", + "values": [ + 1, + 2, + 3 + ] } } } diff --git a/fixtures/handwritten/LoopVariable-0004-fail-01-scalar-constant-target.sed2.json b/fixtures/handwritten/LoopVariable-0004-fail-01-scalar-constant-target.sed2.json index c36f384..2ebe3c6 100644 --- a/fixtures/handwritten/LoopVariable-0004-fail-01-scalar-constant-target.sed2.json +++ b/fixtures/handwritten/LoopVariable-0004-fail-01-scalar-constant-target.sed2.json @@ -31,6 +31,14 @@ }, "outputVariableMap": { "col": "#tasks:loop1:subTasks:sub1.model" + }, + "range": { + "_type": "numericRange", + "values": [ + 1, + 2, + 3 + ] } } } diff --git a/fixtures/handwritten/Repeat-0008-fail-01-constant-target.sed2.json b/fixtures/handwritten/Repeat-0008-fail-01-constant-target.sed2.json index ff3f614..0054c00 100644 --- a/fixtures/handwritten/Repeat-0008-fail-01-constant-target.sed2.json +++ b/fixtures/handwritten/Repeat-0008-fail-01-constant-target.sed2.json @@ -31,6 +31,14 @@ }, "outputVariableMap": { "col": "#constants:myNumberArray" + }, + "range": { + "_type": "numericRange", + "values": [ + 1, + 2, + 3 + ] } } } diff --git a/fixtures/handwritten/Repeat-0008-pass-00-subtask-target.sed2.json b/fixtures/handwritten/Repeat-0008-pass-00-subtask-target.sed2.json index f91a3c7..0626665 100644 --- a/fixtures/handwritten/Repeat-0008-pass-00-subtask-target.sed2.json +++ b/fixtures/handwritten/Repeat-0008-pass-00-subtask-target.sed2.json @@ -31,6 +31,14 @@ }, "outputVariableMap": { "col": "#tasks:loop1:subTasks:sub1.model" + }, + "range": { + "_type": "numericRange", + "values": [ + 1, + 2, + 3 + ] } } } diff --git a/fixtures/handwritten/Repeat-0009-fail-01-constant-input.sed2.json b/fixtures/handwritten/Repeat-0009-fail-01-constant-input.sed2.json index d0cd4ba..c502985 100644 --- a/fixtures/handwritten/Repeat-0009-fail-01-constant-input.sed2.json +++ b/fixtures/handwritten/Repeat-0009-fail-01-constant-input.sed2.json @@ -37,6 +37,14 @@ "_type": "aggregationCalculation", "input": "#constants:mynumber" } + }, + "range": { + "_type": "numericRange", + "values": [ + 1, + 2, + 3 + ] } } } diff --git a/fixtures/handwritten/SEDBase-0006-fail-01-missing-loop-variable.sed2.json b/fixtures/handwritten/SEDBase-0006-fail-01-missing-loop-variable.sed2.json index 5716b91..750f4ed 100644 --- a/fixtures/handwritten/SEDBase-0006-fail-01-missing-loop-variable.sed2.json +++ b/fixtures/handwritten/SEDBase-0006-fail-01-missing-loop-variable.sed2.json @@ -55,6 +55,14 @@ "location": "model.xml", "language": "urn:sedml:language:sbml" } + }, + "range": { + "_type": "numericRange", + "values": [ + 1, + 2, + 3 + ] } }, "r1": { diff --git a/fixtures/handwritten/SEDBase-0006-fail-01-missing-subtask.sed2.json b/fixtures/handwritten/SEDBase-0006-fail-01-missing-subtask.sed2.json index 3a82b6e..eae4b45 100644 --- a/fixtures/handwritten/SEDBase-0006-fail-01-missing-subtask.sed2.json +++ b/fixtures/handwritten/SEDBase-0006-fail-01-missing-subtask.sed2.json @@ -55,6 +55,14 @@ "location": "model.xml", "language": "urn:sedml:language:sbml" } + }, + "range": { + "_type": "numericRange", + "values": [ + 1, + 2, + 3 + ] } }, "r1": { diff --git a/fixtures/handwritten/SEDBase-0006-pass-00-deep-reference-from-inside-repeat.sed2.json b/fixtures/handwritten/SEDBase-0006-pass-00-deep-reference-from-inside-repeat.sed2.json index 3c8b7e9..a7d84bd 100644 --- a/fixtures/handwritten/SEDBase-0006-pass-00-deep-reference-from-inside-repeat.sed2.json +++ b/fixtures/handwritten/SEDBase-0006-pass-00-deep-reference-from-inside-repeat.sed2.json @@ -73,6 +73,14 @@ ] } } + }, + "range": { + "_type": "numericRange", + "values": [ + 1, + 2, + 3 + ] } } } diff --git a/fixtures/handwritten/SEDBase-0008-fail-01-conditional-accessor-false.sed2.json b/fixtures/handwritten/SEDBase-0008-fail-01-conditional-accessor-false.sed2.json index f12d48b..b0ac684 100644 --- a/fixtures/handwritten/SEDBase-0008-fail-01-conditional-accessor-false.sed2.json +++ b/fixtures/handwritten/SEDBase-0008-fail-01-conditional-accessor-false.sed2.json @@ -41,31 +41,47 @@ ] } }, - "ss1": { - "_type": "steadyState", - "model": "#tasks:m1.model", - "outputVariables": [ - "S1" - ], - "outputModel": false - }, - "s2": { - "_type": "explicitODESimulation", - "model": "#tasks:ss1.model", - "independentVariable": "time", - "outputVariables": [ - "S1", - "S2" - ], - "independentVariableRange": { + "loop1": { + "_type": "loop", + "loopVariables": { + "lv1": { + "initialValue": 0, + "subsequentValues": "#tasks:loop1:subTasks:s1" + } + }, + "subTasks": { + "s1": { + "_type": "explicitODESimulation", + "model": "#tasks:m1.model", + "independentVariable": "time", + "outputVariables": [ + "S1", + "S2" + ], + "independentVariableRange": { + "_type": "numericRange", + "values": [ + 0, + 1, + 2, + 3 + ] + } + } + }, + "range": { "_type": "numericRange", "values": [ - 0, 1, 2, 3 ] } + }, + "r1": { + "_type": "relabelData", + "input": "#tasks:loop1.aggregates", + "labels": "#constants:k_strings" } } } diff --git a/fixtures/handwritten/SEDBase-0008-pass-00-conditional-accessor-depends-on-reference.sed2.json b/fixtures/handwritten/SEDBase-0008-pass-00-conditional-accessor-depends-on-reference.sed2.json deleted file mode 100644 index c6c89c8..0000000 --- a/fixtures/handwritten/SEDBase-0008-pass-00-conditional-accessor-depends-on-reference.sed2.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "version": "v1.0.0", - "constants": { - "k_num": 1.5, - "k_strings": [ - "a", - "b" - ], - "k_array": [ - 10, - 20, - 30 - ], - "k_obj": { - "a": 1, - "b": 2 - }, - "k_str": "hello", - "k_bool": false - }, - "tasks": { - "m1": { - "_type": "modelImport", - "location": "model.xml", - "language": "urn:sedml:language:sbml" - }, - "sim1": { - "_type": "explicitODESimulation", - "model": "#tasks:m1.model", - "independentVariable": "time", - "outputVariables": [ - "S1", - "S2" - ], - "independentVariableRange": { - "_type": "numericRange", - "values": [ - 0, - 1, - 2, - 3 - ] - } - }, - "ss1": { - "_type": "steadyState", - "model": "#tasks:m1.model", - "outputVariables": [ - "S1" - ], - "outputModel": "#constants:k_bool" - }, - "s2": { - "_type": "explicitODESimulation", - "model": "#tasks:ss1.model", - "independentVariable": "time", - "outputVariables": [ - "S1", - "S2" - ], - "independentVariableRange": { - "_type": "numericRange", - "values": [ - 0, - 1, - 2, - 3 - ] - } - } - } -} diff --git a/fixtures/handwritten/SEDBase-0008-pass-00-conditional-accessor-true.sed2.json b/fixtures/handwritten/SEDBase-0008-pass-00-conditional-accessor-true.sed2.json index 8f9c822..0e3c333 100644 --- a/fixtures/handwritten/SEDBase-0008-pass-00-conditional-accessor-true.sed2.json +++ b/fixtures/handwritten/SEDBase-0008-pass-00-conditional-accessor-true.sed2.json @@ -41,31 +41,53 @@ ] } }, - "ss1": { - "_type": "steadyState", - "model": "#tasks:m1.model", - "outputVariables": [ - "S1" - ], - "outputModel": true - }, - "s2": { - "_type": "explicitODESimulation", - "model": "#tasks:ss1.model", - "independentVariable": "time", - "outputVariables": [ - "S1", - "S2" - ], - "independentVariableRange": { + "loop1": { + "_type": "loop", + "loopVariables": { + "lv1": { + "initialValue": 0, + "subsequentValues": "#tasks:loop1:subTasks:s1" + } + }, + "subTasks": { + "s1": { + "_type": "explicitODESimulation", + "model": "#tasks:m1.model", + "independentVariable": "time", + "outputVariables": [ + "S1", + "S2" + ], + "independentVariableRange": { + "_type": "numericRange", + "values": [ + 0, + 1, + 2, + 3 + ] + } + } + }, + "range": { "_type": "numericRange", "values": [ - 0, 1, 2, 3 ] + }, + "aggregateOutputVariables": { + "a1": { + "_type": "aggregationCalculation", + "input": "#tasks:loop1:subTasks:s1" + } } + }, + "r1": { + "_type": "relabelData", + "input": "#tasks:loop1.aggregates", + "labels": "#constants:k_strings" } } } diff --git a/fixtures/handwritten/SEDBase-0009-pass-00-runtime-dimension-never-fires.sed2.json b/fixtures/handwritten/SEDBase-0009-pass-00-runtime-dimension-never-fires.sed2.json index bf15a16..5ae18bb 100644 --- a/fixtures/handwritten/SEDBase-0009-pass-00-runtime-dimension-never-fires.sed2.json +++ b/fixtures/handwritten/SEDBase-0009-pass-00-runtime-dimension-never-fires.sed2.json @@ -41,25 +41,13 @@ ] } }, - "loop1": { - "_type": "loop", - "loopVariables": { - "lv1": { - "initialValue": 0, - "subsequentValues": "#tasks:loop1:subTasks:s1.model" - } - }, - "subTasks": { - "s1": { - "_type": "modelImport", - "location": "model.xml", - "language": "urn:sedml:language:sbml" - } - } + "calc1": { + "_type": "calculation", + "math": "1 + 1" }, "r1": { "_type": "relabelData", - "input": "#tasks:loop1[0][1][2]", + "input": "#tasks:calc1[0][1][2]", "labels": "#constants:k_strings" } } diff --git a/fixtures/handwritten/SEDBase-0011-pass-00-runtime-size-never-fires.sed2.json b/fixtures/handwritten/SEDBase-0011-pass-00-runtime-size-never-fires.sed2.json index 61f4456..ee19e67 100644 --- a/fixtures/handwritten/SEDBase-0011-pass-00-runtime-size-never-fires.sed2.json +++ b/fixtures/handwritten/SEDBase-0011-pass-00-runtime-size-never-fires.sed2.json @@ -41,25 +41,23 @@ ] } }, - "loop1": { - "_type": "loop", - "loopVariables": { - "lv1": { - "initialValue": 0, - "subsequentValues": "#tasks:loop1:subTasks:s1.model" - } - }, - "subTasks": { - "s1": { - "_type": "modelImport", - "location": "model.xml", - "language": "urn:sedml:language:sbml" - } + "b1": { + "_type": "boundedODESimulation", + "model": "#tasks:m1.model", + "independentVariable": "time", + "outputVariables": [ + "S1", + "S2" + ], + "independentVariableSpan": { + "_type": "span", + "start": 0, + "end": 10 } }, "r1": { "_type": "relabelData", - "input": "#tasks:loop1[1000]", + "input": "#tasks:b1[1000]", "labels": "#constants:k_strings" } } diff --git a/fixtures/handwritten/SEDBase-0013-pass-00-nested-subtask-uses-outer-index.sed2.json b/fixtures/handwritten/SEDBase-0013-pass-00-nested-subtask-uses-outer-index.sed2.json index af6e664..f986a9f 100644 --- a/fixtures/handwritten/SEDBase-0013-pass-00-nested-subtask-uses-outer-index.sed2.json +++ b/fixtures/handwritten/SEDBase-0013-pass-00-nested-subtask-uses-outer-index.sed2.json @@ -100,6 +100,14 @@ "input": "#tasks:loop1.index", "labels": "#constants:k_strings" } + }, + "range": { + "_type": "numericRange", + "values": [ + 1, + 2, + 3 + ] } } },