{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://calvagone.github.io/campsis.doc/schema/1.0/campsis.schema.json",
  "$comment": "Campsis JSON Schema v1.0 © 2025 [Nicolas Luyckx / Calvagone]. Licensed under CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). You are free to share and adapt this schema with attribution.",
  "title": "Campsis JSON Schema",
  "$ref": "#/$defs/dataset",
  "$defs": {
    "dataset": {
      "type": "array",
      "items": {
        "oneOf": [
          {
            "$ref": "#/$defs/arm"
          },
          {
            "$ref": "#/$defs/dataset_config"
          }
        ]
      }
    },
    "arm": {
      "type": "object",
      "properties": {
        "type": {
          "const": "arm"
        },
        "list": {
          "type": "array",
          "items": {
            "oneOf": [
              {
                "$ref": "#/$defs/arm_attributes"
              },
              {
                "$ref": "#/$defs/bolus"
              },
              {
                "$ref": "#/$defs/infusion"
              },
              {
                "$ref": "#/$defs/observations"
              },
              {
                "$ref": "#/$defs/covariate"
              },
              {
                "$ref": "#/$defs/dose_adaptation"
              },
              {
                "$ref": "#/$defs/bootstrap"
              }
            ]
          }
        }
      },
      "required": [
        "list"
      ],
      "additionalProperties": false
    },
    "arm_attributes": {
      "type": "object",
      "properties": {
        "type": {
          "const": "arm_attributes"
        },
        "subjects": {
          "type": "integer",
          "description": "Number of subjects in the arm",
          "minimum": 0
        },
        "label": {
          "type": "string",
          "description": "Arm label"
        }
      },
      "required": [
        "subjects",
        "label"
      ],
      "additionalProperties": false
    },
    "bolus": {
      "type": "object",
      "properties": {
        "type": {
          "const": "bolus"
        },
        "time": {
          "type": "number",
          "description": "Time at which the bolus is given"
        },
        "amount": {
          "type": "number",
          "description": "Dose amount"
        },
        "compartment": {
          "type": "array",
          "description": "Compartment where the dose is given. The dose can be given into multiple compartments at once.",
          "items": {
            "type": "string"
          }
        },
        "ii": {
          "type": "number",
          "description": "Inter-dose interval"
        },
        "addl": {
          "type": "integer",
          "description": "Number of additional doses"
        },
        "time_unit": {
          "$ref": "#/$defs/time_unit",
          "description": "Time unit of 'time' field. Default unit is 'hour'"
        },
        "ii_unit": {
          "$ref": "#/$defs/time_unit",
          "description": "Time unit of 'ii' field. Default unit is 'hour'"
        },
        "rep": {
          "$ref": "#/$defs/cyclic_schedule",
          "description": "Repeat this bolus wrapper using a cyclic schedule."
        }
      },
      "required": [
        "time",
        "amount",
        "compartment"
      ],
      "additionalProperties": false
    },
    "infusion": {
      "type": "object",
      "properties": {
        "type": {
          "const": "infusion"
        },
        "time": {
          "type": "number"
        },
        "amount": {
          "type": "number"
        },
        "compartment": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "ii": {
          "type": "number"
        },
        "addl": {
          "type": "integer"
        },
        "duration": {
          "type": "number"
        },
        "time_unit": {
          "$ref": "#/$defs/time_unit",
          "description": "Time unit of 'time' field. Default unit is 'hour'"
        },
        "ii_unit": {
          "$ref": "#/$defs/time_unit",
          "description": "Time unit of 'ii' field. Default unit is 'hour'"
        },
        "duration_unit": {
          "$ref": "#/$defs/time_unit",
          "description": "Time unit of 'duration' field. Default unit is 'hour'"
        },
        "rep": {
          "$ref": "#/$defs/cyclic_schedule",
          "description": "Repeat this infusion wrapper using a cyclic schedule."
        }
      },
      "required": [
        "time",
        "amount",
        "compartment"
      ],
      "additionalProperties": false
    },
    "observations": {
      "type": "object",
      "properties": {
        "type": {
          "const": "observations"
        },
        "times": {
          "oneOf": [
            {
              "type": "array",
              "items": {
                "type": "number"
              }
            },
            {
              "$ref": "#/$defs/time_sequence"
            }
          ]
        },
        "unit": {
          "$ref": "#/$defs/time_unit",
          "description": "Time unit of 'times' field. Default unit is 'hour'"
        },
        "rep": {
          "oneOf": [
            {
              "type": "array",
              "items": {
                "type": "number"
              }
            },
            {
              "$ref": "#/$defs/dosing_schedule"
            }
          ]
        }
      },
      "required": [
        "times"
      ],
      "additionalProperties": false
    },
    "time_sequence": {
      "type": "object",
      "properties": {
        "type": {
          "const": "time_sequence"
        },
        "start": {
          "type": "number",
          "description": "Start time"
        },
        "end": {
          "type": "number",
          "description": "End time (this time may not be included in the final sequence depending on the chosen step)"
        },
        "by": {
          "type": "number",
          "description": "Step between two consecutive times"
        }
      },
      "required": [
        "start",
        "end"
      ]
    },
    "dosing_schedule": {
      "type": "object",
      "properties": {
        "type": {
          "const": "dosing_schedule"
        }
      },
      "required": []
    },
    "cyclic_schedule": {
      "type": "object",
      "properties": {
        "type": {
          "const": "cyclic_schedule"
        },
        "duration": {
          "type": "number",
          "description": "Duration of the cyclic period."
        },
        "duration_unit": {
          "$ref": "#/$defs/time_unit",
          "description": "Time unit of 'duration' field."
        },
        "repetitions": {
          "type": "integer",
          "description": "Number of additional cyclic periods"
        }
      },
      "required": [
        "duration",
        "repetitions"
      ]
    },
    "dataset_config": {
      "type": "object",
      "properties": {
        "type": {
          "const": "dataset_config"
        },
        "export_tsld": {
          "type": "boolean",
          "description": "Export variable TSLD (time since last dose) in the dataset for rxode2 / mrgsolve"
        },
        "export_tdos": {
          "type": "boolean",
          "description": "Export variable TDOS (time of current dose) in the dataset for rxode2 / mrgsolve"
        },
        "time_unit_export": {
          "$ref": "#/$defs/time_unit",
          "description": "TIME column unit in exported dataset."
        }
      },
      "required": [
        "export_tsld",
        "export_tdos",
        "time_unit_export"
      ]
    },
    "distribution": {
      "title": "Base distribution",
      "type": "object",
      "properties": {},
      "additionalProperties": true
    },
    "constant_distribution": {
      "title": "Constant distribution",
      "allOf": [
        {
          "$ref": "#/$defs/distribution"
        }
      ],
      "type": "object",
      "properties": {
        "type": {
          "const": "constant_distribution"
        },
        "value": {
          "type": "number",
          "description": "Constant value"
        }
      },
      "required": [
        "value"
      ],
      "additionalProperties": false
    },
    "fixed_distribution": {
      "title": "Fixed distribution",
      "allOf": [
        {
          "$ref": "#/$defs/distribution"
        }
      ],
      "type": "object",
      "properties": {
        "type": {
          "const": "fixed_distribution"
        },
        "values": {
          "type": "array",
          "description": "Array of constant values (1 per individual)",
          "items": {
            "type": "number"
          }
        }
      },
      "required": [
        "values"
      ],
      "additionalProperties": false
    },
    "uniform_distribution": {
      "title": "Uniform distribution",
      "allOf": [
        {
          "$ref": "#/$defs/distribution"
        }
      ],
      "type": "object",
      "properties": {
        "type": {
          "const": "uniform_distribution"
        },
        "min": {
          "type": "number",
          "description": "Lower limit of the uniform distribution"
        },
        "max": {
          "type": "number",
          "description": "Upper limit of the uniform distribution"
        }
      },
      "required": [
        "min",
        "max"
      ],
      "additionalProperties": false
    },
    "normal_distribution": {
      "title": "Normal distribution",
      "allOf": [
        {
          "$ref": "#/$defs/distribution"
        }
      ],
      "type": "object",
      "properties": {
        "type": {
          "const": "normal_distribution"
        },
        "mean": {
          "type": "number",
          "description": "Mean value of the normal distribution"
        },
        "sd": {
          "type": "number",
          "description": "Standard deviation of the normal distribution"
        }
      },
      "required": [
        "mean",
        "sd"
      ],
      "additionalProperties": false
    },
    "lognormal_distribution": {
      "title": "Lognormal distribution",
      "allOf": [
        {
          "$ref": "#/$defs/distribution"
        }
      ],
      "type": "object",
      "properties": {
        "type": {
          "const": "lognormal_distribution"
        },
        "meanlog": {
          "type": "number",
          "description": "Mean value of the lognormal distribution in the log domain"
        },
        "sdlog": {
          "type": "number",
          "description": "Standard deviation of the lognormal distribution in the log domain"
        }
      },
      "required": [
        "meanlog",
        "sdlog"
      ],
      "additionalProperties": false
    },
    "discrete_distribution_item": {
      "type": "object",
      "properties": {
        "type": {
          "const": "discrete_distribution_item"
        },
        "value": {
          "type": "number",
          "description": "Discrete value in model (usually an integer)"
        },
        "probability": {
          "type": "number",
          "description": "Probability of generating this item (number must be between 0 and 1)"
        },
        "label": {
          "type": "string",
          "description": "Optional label representing this discrete item"
        }
      },
      "required": [
        "value",
        "probability"
      ]
    },
    "discrete_distribution": {
      "title": "Discrete distribution",
      "allOf": [
        {
          "$ref": "#/$defs/distribution"
        }
      ],
      "type": "object",
      "properties": {
        "type": {
          "const": "discrete_distribution"
        },
        "items": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/discrete_distribution_item"
          }
        }
      },
      "required": [
        "items"
      ],
      "additionalProperties": false
    },
    "covariate": {
      "title": "Model covariate",
      "type": "object",
      "properties": {
        "type": {
          "const": "covariate"
        },
        "name": {
          "type": "string",
          "description": "Name of the covariate"
        },
        "distribution": {
          "oneOf": [
            {
              "$ref": "#/$defs/constant_distribution"
            },
            {
              "$ref": "#/$defs/fixed_distribution"
            },
            {
              "$ref": "#/$defs/uniform_distribution"
            },
            {
              "$ref": "#/$defs/normal_distribution"
            },
            {
              "$ref": "#/$defs/lognormal_distribution"
            },
            {
              "$ref": "#/$defs/discrete_distribution"
            }
          ],
          "discriminator": {
            "propertyName": "type"
          }
        }
      },
      "required": [
        "name",
        "distribution"
      ]
    },
    "dose_adaptation": {
      "title": "Static dose adaptation based on a formula",
      "type": "object",
      "properties": {
        "type": {
          "const": "dose_adaptation"
        },
        "formula": {
          "type": "string",
          "description": "Any formula to adapt the dose amount. E.g. 'AMT*WT' for kg-based doses, where AMT is the original amount given in the bolus/infusion."
        },
        "compartments": {
          "type": "array",
          "description": "List of compartments where the previous formula applies. By default, the formula is applied to all compartments.",
          "items": {
            "type": "string"
          }
        }
      },
      "required": [
        "formula"
      ]
    },
    "time_unit": {
      "type": "string",
      "enum": [
        "second",
        "minute",
        "hour",
        "day",
        "week",
        "month",
        "year"
      ]
    },
    "bootstrap": {
      "title": "Bootstrap layer.",
      "type": "object",
      "properties": {
        "type": {
          "const": "bootstrap"
        },
        "data": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/bootstrap_row"
          },
          "description": "Bootstrap data in the form of a list of dictionaries."
        },
        "replacement": {
          "type": "boolean",
          "description": "Values can be reused or not when already drawn."
        },
        "random": {
          "type": "boolean",
          "description": "Randomly draw the bootstrap rows (1 row = 1 individual)."
        }
      },
      "required": [
        "data",
        "replacement",
        "random"
      ]
    },
    "bootstrap_row": {
      "type": "object",
      "properties": {
        "type": {
          "const": "bootstrap_row"
        },
        "BS_ID": {
          "type": "integer"
        }
      },
      "description": "Each bootstrap row contains the covariates of a specific individual. BS_ID is a non-mandatory identifier for this row. Other properties are the covariates to bootstrap for this individual.",
      "required": [
      ],
      "additionalProperties": true
    }
  }
}
