{
  "$defs": {
    "ARSource": {
      "additionalProperties": false,
      "description": "Autoregressive process: coefficients per base step, mean and stationary standard deviation.",
      "properties": {
        "kind": {
          "const": "ar",
          "description": "`ar`",
          "title": "Kind",
          "type": "string"
        },
        "coef": {
          "description": "Coefficients φ₁…φₚ, per base step `dt`; they must give a stationary process.",
          "items": {
            "type": "number"
          },
          "minItems": 1,
          "title": "Coef",
          "type": "array"
        },
        "mean": {
          "default": 0.0,
          "description": "Mean, in the signal's unit.",
          "title": "Mean",
          "type": "number"
        },
        "std": {
          "description": "Stationary standard deviation, in the signal's unit.",
          "minimum": 0,
          "title": "Std",
          "type": "number"
        }
      },
      "required": [
        "kind",
        "coef",
        "std"
      ],
      "title": "ARSource",
      "type": "object"
    },
    "BurnIn": {
      "additionalProperties": false,
      "description": "Start by running with noise for a while and discarding it.",
      "properties": {
        "burn_in": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "pattern": "^-?\\s*[0-9.]",
              "type": "string"
            }
          ],
          "description": "How long to run before t = 0.",
          "title": "Burn In"
        }
      },
      "required": [
        "burn_in"
      ],
      "title": "BurnIn",
      "type": "object"
    },
    "ConstantSource": {
      "additionalProperties": false,
      "description": "A constant value.",
      "properties": {
        "kind": {
          "const": "constant",
          "description": "`constant`",
          "title": "Kind",
          "type": "string"
        },
        "value": {
          "description": "The value, in the signal's unit.",
          "title": "Value",
          "type": "number"
        }
      },
      "required": [
        "kind",
        "value"
      ],
      "title": "ConstantSource",
      "type": "object"
    },
    "CustomOp": {
      "additionalProperties": true,
      "description": "A core operator used directly; every other key is an operator parameter.",
      "properties": {
        "id": {
          "description": "Name of the operator; its output signal has the same name.",
          "title": "Id",
          "type": "string"
        },
        "op": {
          "description": "Operator, for example `sum`, `product`, `first_order` or `schedule` (see the operator reference).",
          "title": "Op",
          "type": "string"
        },
        "inputs": {
          "additionalProperties": {
            "type": "string"
          },
          "description": "Input port → signal name.",
          "title": "Inputs",
          "type": "object"
        },
        "unit": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Unit of the output signal.",
          "title": "Unit"
        },
        "period": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "pattern": "^-?\\s*[0-9.]",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Update period, a multiple of `dt` (default: every step).",
          "title": "Period"
        }
      },
      "required": [
        "id",
        "op"
      ],
      "title": "CustomOp",
      "type": "object"
    },
    "Degradation": {
      "additionalProperties": true,
      "description": "A slow degradation from the domain library on one unit; every other key is a parameter.",
      "properties": {
        "target": {
          "description": "A unit id.",
          "title": "Target",
          "type": "string"
        },
        "kind": {
          "description": "A degradation of the domain library, for example `fouling`.",
          "title": "Kind",
          "type": "string"
        }
      },
      "required": [
        "target",
        "kind"
      ],
      "title": "Degradation",
      "type": "object"
    },
    "Exogenous": {
      "additionalProperties": false,
      "description": "Drive a signal (usually a template port such as TIC-101.feed_temp) from a source, or from\nan existing signal with `from`.",
      "properties": {
        "target": {
          "description": "A template port such as `TIC-101.feed_temp`, or the name of a new signal.",
          "title": "Target",
          "type": "string"
        },
        "source": {
          "anyOf": [
            {
              "discriminator": {
                "mapping": {
                  "ar": "#/$defs/ARSource",
                  "constant": "#/$defs/ConstantSource",
                  "ou": "#/$defs/OUSource"
                },
                "propertyName": "kind"
              },
              "oneOf": [
                {
                  "$ref": "#/$defs/OUSource"
                },
                {
                  "$ref": "#/$defs/ARSource"
                },
                {
                  "$ref": "#/$defs/ConstantSource"
                }
              ]
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "A source that creates the signal: `ou`, `ar` or `constant`.",
          "title": "Source"
        },
        "from": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "An existing signal that feeds the port instead of a source, for example another unit's output.",
          "title": "From"
        },
        "unit": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Unit of the signal, for the signal table.",
          "title": "Unit"
        },
        "measured": {
          "anyOf": [
            {
              "$ref": "#/$defs/Measurement"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Also measure the signal with an instrument."
        }
      },
      "required": [
        "target"
      ],
      "title": "Exogenous",
      "type": "object"
    },
    "FamilySpec": {
      "additionalProperties": false,
      "description": "How many plants to draw from the config's distributions, and histories per plant.",
      "properties": {
        "plants": {
          "default": 1,
          "description": "Number of plants to draw.",
          "minimum": 1,
          "title": "Plants",
          "type": "integer"
        },
        "histories": {
          "default": 1,
          "description": "Histories per plant (the same plant, different noise).",
          "minimum": 1,
          "title": "Histories",
          "type": "integer"
        }
      },
      "title": "FamilySpec",
      "type": "object"
    },
    "Intervention": {
      "additionalProperties": false,
      "description": "A planned change (target + value) or a fault (target unit + fault name).",
      "properties": {
        "at": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "pattern": "^-?\\s*[0-9.]",
              "type": "string"
            }
          ],
          "description": "When the change starts.",
          "title": "At"
        },
        "target": {
          "description": "A setpoint, mode, manual output, port or parameter path; for a fault, a unit id.",
          "title": "Target",
          "type": "string"
        },
        "value": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "The value for `set`, the amount for `shift`, the factor for `scale`; a mode may be `MAN`, `AUTO` or `CAS`.",
          "title": "Value"
        },
        "action": {
          "default": "set",
          "description": "How `value` applies.",
          "enum": [
            "set",
            "shift",
            "scale"
          ],
          "title": "Action",
          "type": "string"
        },
        "fault": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "A fault of the domain library, instead of a planned change.",
          "title": "Fault"
        },
        "magnitude": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Size of the fault, in the fault's own terms (see the fault's description).",
          "title": "Magnitude"
        },
        "profile": {
          "anyOf": [
            {
              "enum": [
                "step",
                "ramp"
              ],
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "`step`, or `ramp` over `over` (default: step; a fault's own default for faults).",
          "title": "Profile"
        },
        "over": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "pattern": "^-?\\s*[0-9.]",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Duration of a ramp.",
          "title": "Over"
        },
        "id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Id of the event in the event log (default: its position).",
          "title": "Id"
        },
        "lanes": {
          "anyOf": [
            {
              "items": {
                "type": "integer"
              },
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "The lanes it applies to (default: all).",
          "title": "Lanes"
        }
      },
      "required": [
        "at",
        "target"
      ],
      "title": "Intervention",
      "type": "object"
    },
    "Measurement": {
      "additionalProperties": false,
      "description": "Measure an exogenous signal with a sensor preset over a span.",
      "properties": {
        "tag": {
          "description": "Tag of the measured signal, for example `TT-205`.",
          "title": "Tag",
          "type": "string"
        },
        "sensor": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Sensor preset of the domain library (default: the library's first preset).",
          "title": "Sensor"
        },
        "span": {
          "description": "Measurement span `[low, high]`; noise and quantization are percentages of it.",
          "maxItems": 2,
          "minItems": 2,
          "prefixItems": [
            {
              "type": "number"
            },
            {
              "type": "number"
            }
          ],
          "title": "Span",
          "type": "array"
        },
        "installed": {
          "default": true,
          "description": "Whether the sensor is installed at the start (a removed sensor reads NaN).",
          "title": "Installed",
          "type": "boolean"
        }
      },
      "required": [
        "tag",
        "span"
      ],
      "title": "Measurement",
      "type": "object"
    },
    "OUSource": {
      "additionalProperties": false,
      "description": "Ornstein–Uhlenbeck process: mean, stationary standard deviation and correlation time.",
      "properties": {
        "kind": {
          "const": "ou",
          "description": "`ou`",
          "title": "Kind",
          "type": "string"
        },
        "mean": {
          "default": 0.0,
          "description": "Long-run mean, in the signal's unit.",
          "title": "Mean",
          "type": "number"
        },
        "std": {
          "description": "Stationary standard deviation, in the signal's unit (the same whatever `dt`).",
          "minimum": 0,
          "title": "Std",
          "type": "number"
        },
        "tau": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "pattern": "^-?\\s*[0-9.]",
              "type": "string"
            }
          ],
          "description": "Correlation time.",
          "title": "Tau"
        }
      },
      "required": [
        "kind",
        "std",
        "tau"
      ],
      "title": "OUSource",
      "type": "object"
    },
    "Output": {
      "additionalProperties": false,
      "description": "What is recorded.",
      "properties": {
        "every": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "pattern": "^-?\\s*[0-9.]",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Recording interval, a multiple of `dt` (default: every step).",
          "title": "Every"
        },
        "start": {
          "anyOf": [
            {
              "format": "date-time",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Calendar time of t = 0; the index becomes timestamps instead of elapsed time.",
          "title": "Start"
        }
      },
      "title": "Output",
      "type": "object"
    },
    "Plan": {
      "additionalProperties": false,
      "description": "A historical plan: the starting regime, the production changes and the maintenance.",
      "properties": {
        "start": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "The regime at the start of the run; the plant settles in it.",
          "title": "Start"
        },
        "production": {
          "description": "Production transitions between regimes (or a generator; see Self-running plans).",
          "items": {
            "$ref": "#/$defs/Transition"
          },
          "title": "Production",
          "type": "array"
        },
        "maintenance": {
          "description": "Maintenance tasks (entries may be recurring generators).",
          "items": {
            "$ref": "#/$defs/Task"
          },
          "title": "Maintenance",
          "type": "array"
        }
      },
      "title": "Plan",
      "type": "object"
    },
    "Task": {
      "additionalProperties": false,
      "description": "A maintenance task from the domain library, on one unit or several.",
      "properties": {
        "at": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "pattern": "^-?\\s*[0-9.]",
              "type": "string"
            }
          ],
          "description": "When the task starts.",
          "title": "At"
        },
        "task": {
          "description": "A maintenance task of the domain library, for example `clean` or `calibrate`.",
          "title": "Task",
          "type": "string"
        },
        "target": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "items": {
                "type": "string"
              },
              "type": "array"
            }
          ],
          "description": "A unit id, or several.",
          "title": "Target"
        },
        "duration": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "pattern": "^-?\\s*[0-9.]",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "How long the task takes, for tasks that need one (for example `stop`).",
          "title": "Duration"
        },
        "id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Id of the task in the event log.",
          "title": "Id"
        }
      },
      "required": [
        "at",
        "task",
        "target"
      ],
      "title": "Task",
      "type": "object"
    },
    "Transition": {
      "additionalProperties": false,
      "description": "Move to a regime at `at`, ramping its numeric values over `over` (modes switch at once).",
      "properties": {
        "at": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "pattern": "^-?\\s*[0-9.]",
              "type": "string"
            }
          ],
          "description": "When the transition starts.",
          "title": "At"
        },
        "to": {
          "description": "The regime to move to.",
          "title": "To",
          "type": "string"
        },
        "over": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "pattern": "^-?\\s*[0-9.]",
              "type": "string"
            }
          ],
          "default": 0.0,
          "description": "Duration of the ramp (0: a step).",
          "title": "Over"
        },
        "id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Id of the transition in the event log.",
          "title": "Id"
        }
      },
      "required": [
        "at",
        "to"
      ],
      "title": "Transition",
      "type": "object"
    },
    "UnitSpec": {
      "additionalProperties": true,
      "description": "A template instance; every other key is a template parameter.",
      "properties": {
        "id": {
          "description": "Unit id, for example `TIC-101`; its ISA tags derive from it (`TT-101`, `TV-101`).",
          "title": "Id",
          "type": "string"
        },
        "template": {
          "description": "Template of the domain library, for example `temperature_loop`.",
          "title": "Template",
          "type": "string"
        },
        "period": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "pattern": "^-?\\s*[0-9.]",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Update period of every operator of the unit, a multiple of `dt` (default: every step).",
          "title": "Period"
        }
      },
      "required": [
        "id",
        "template"
      ],
      "title": "UnitSpec",
      "type": "object"
    }
  },
  "additionalProperties": false,
  "description": "A plant and its timeline.",
  "properties": {
    "seed": {
      "default": 0,
      "description": "Seed of every random stream.",
      "title": "Seed",
      "type": "integer"
    },
    "duration": {
      "anyOf": [
        {
          "type": "number"
        },
        {
          "pattern": "^-?\\s*[0-9.]",
          "type": "string"
        }
      ],
      "description": "Length of the run, a whole multiple of `dt`.",
      "title": "Duration"
    },
    "dt": {
      "anyOf": [
        {
          "type": "number"
        },
        {
          "pattern": "^-?\\s*[0-9.]",
          "type": "string"
        }
      ],
      "default": 1.0,
      "description": "Base step; parameters are given in physical units and discretized exactly.",
      "title": "Dt"
    },
    "lanes": {
      "default": 1,
      "description": "Number of lanes run side by side as one batch.",
      "minimum": 1,
      "title": "Lanes",
      "type": "integer"
    },
    "noise_keys": {
      "anyOf": [
        {
          "items": {
            "type": "integer"
          },
          "type": "array"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "One noise key per lane; lanes with the same key share their noise (twin runs).",
      "title": "Noise Keys"
    },
    "init": {
      "anyOf": [
        {
          "enum": [
            "steady",
            "none"
          ],
          "type": "string"
        },
        {
          "$ref": "#/$defs/BurnIn"
        }
      ],
      "default": "steady",
      "description": "`steady` (settle noise-free first), `none`, or `{burn_in: <duration>}`.",
      "title": "Init"
    },
    "library": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Domain library, optionally pinned to a major version: `process` or `process@1`.",
      "title": "Library"
    },
    "units": {
      "description": "Template instances.",
      "items": {
        "$ref": "#/$defs/UnitSpec"
      },
      "title": "Units",
      "type": "array"
    },
    "exogenous": {
      "description": "Sources and wiring of template ports and new signals.",
      "items": {
        "$ref": "#/$defs/Exogenous"
      },
      "title": "Exogenous",
      "type": "array"
    },
    "interventions": {
      "description": "Planned changes and faults at given times.",
      "items": {
        "$ref": "#/$defs/Intervention"
      },
      "title": "Interventions",
      "type": "array"
    },
    "custom": {
      "description": "Core operators used directly.",
      "items": {
        "$ref": "#/$defs/CustomOp"
      },
      "title": "Custom",
      "type": "array"
    },
    "regimes": {
      "additionalProperties": {
        "additionalProperties": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "string"
            }
          ]
        },
        "type": "object"
      },
      "description": "Named sets of values (setpoints, parameters, modes) for the plan.",
      "title": "Regimes",
      "type": "object"
    },
    "plan": {
      "$ref": "#/$defs/Plan",
      "description": "The starting regime, production transitions and maintenance."
    },
    "degradation": {
      "description": "Slow degradations of units.",
      "items": {
        "$ref": "#/$defs/Degradation"
      },
      "title": "Degradation",
      "type": "array"
    },
    "family": {
      "anyOf": [
        {
          "$ref": "#/$defs/FamilySpec"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Plants and histories drawn by `homeostat.family()`."
    },
    "output": {
      "$ref": "#/$defs/Output"
    }
  },
  "required": [
    "duration"
  ],
  "title": "Scenario",
  "type": "object"
}
