{
  "$defs": {
    "RawDiversionChannel": {
      "additionalProperties": false,
      "description": "Intermediate type for the `diversion` sub-object.",
      "properties": {
        "downstream_id": {
          "description": "Identifier of the downstream hydro plant receiving diverted water.",
          "format": "int32",
          "type": "integer"
        },
        "max_flow_m3s": {
          "description": "Maximum diversion flow capacity [m³/s].",
          "format": "double",
          "type": "number"
        }
      },
      "required": [
        "downstream_id",
        "max_flow_m3s"
      ],
      "type": "object"
    },
    "RawEfficiency": {
      "description": "Tagged-union intermediate type for the `efficiency` sub-object.",
      "oneOf": [
        {
          "description": "Constant efficiency across all operating points.",
          "properties": {
            "type": {
              "const": "constant",
              "type": "string"
            },
            "value": {
              "description": "Turbine efficiency as a fraction in (0, 1].",
              "format": "double",
              "type": "number"
            }
          },
          "required": [
            "type",
            "value"
          ],
          "type": "object"
        }
      ]
    },
    "RawEvaporation": {
      "additionalProperties": false,
      "description": "Intermediate type for the `evaporation` sub-object.",
      "properties": {
        "coefficients_mm": {
          "description": "Monthly evaporation coefficients [mm/month], one per calendar month.\nIndex 0 = January, index 11 = December.",
          "items": {
            "format": "double",
            "type": "number"
          },
          "type": "array"
        },
        "reference_volumes_hm3": {
          "default": null,
          "description": "Monthly reservoir reference volumes [hm³] used as the linearization\nreference point for evaporation, one per calendar month.\nIndex 0 = January, index 11 = December.\nAbsent = no reference volume override; the calling algorithm uses its\nown default (e.g., mid-point of the storage range).",
          "items": {
            "format": "double",
            "type": "number"
          },
          "type": [
            "array",
            "null"
          ]
        }
      },
      "required": [
        "coefficients_mm"
      ],
      "type": "object"
    },
    "RawFillingConfig": {
      "additionalProperties": false,
      "description": "Intermediate type for the `filling` sub-object.",
      "properties": {
        "filling_min_rate_m3s": {
          "default": 0.0,
          "description": "Minimum accumulation rate applied during filling [m³/s].\nAbsent = passive filling (no minimum rate, defaults to 0.0 per spec).",
          "format": "double",
          "type": "number"
        },
        "start_stage_id": {
          "description": "Stage index at which filling begins (inclusive).",
          "format": "int32",
          "type": "integer"
        }
      },
      "required": [
        "start_stage_id"
      ],
      "type": "object"
    },
    "RawGeneration": {
      "description": "Tagged-union intermediate type for the `generation` sub-object.\n\nUses `#[serde(tag = \"model\")]` (internally-tagged) to dispatch on the\n`\"model\"` field value. Each variant carries only the fields relevant to\nthat model. The `productivity_mw_per_m3s` field is NOT accepted here —\nproductivity coefficients are read from `system/hydro_production_models.json`\nand are associated per `(hydro, stage)` outside this file.\nA `hydros.json` input that includes `productivity_mw_per_m3s` in its\n`generation` block will be rejected with a parse error.",
      "oneOf": [
        {
          "additionalProperties": false,
          "description": "Constant productivity: `power = productivity * turbined_m3s`.\n\nThe productivity coefficient is read from\n`system/hydro_production_models.json` per `(hydro, stage)`. It is not\naccepted in `hydros.json`; supplying `productivity_mw_per_m3s` here\nproduces a hard parse error.",
          "properties": {
            "max_generation_mw": {
              "description": "Maximum electrical generation [MW].",
              "format": "double",
              "type": "number"
            },
            "max_turbined_m3s": {
              "description": "Maximum turbined flow [m³/s].",
              "format": "double",
              "type": "number"
            },
            "min_generation_mw": {
              "description": "Minimum electrical generation [MW].",
              "format": "double",
              "type": "number"
            },
            "min_turbined_m3s": {
              "description": "Minimum turbined flow [m³/s].",
              "format": "double",
              "type": "number"
            },
            "model": {
              "const": "constant_productivity",
              "type": "string"
            }
          },
          "required": [
            "model",
            "min_turbined_m3s",
            "max_turbined_m3s",
            "min_generation_mw",
            "max_generation_mw"
          ],
          "type": "object"
        },
        {
          "additionalProperties": false,
          "description": "Head-dependent productivity linearized around an operating point.\n\nThe productivity coefficient is read from\n`system/hydro_production_models.json` per `(hydro, stage)`. It is not\naccepted in `hydros.json`; supplying `productivity_mw_per_m3s` here\nproduces a hard parse error.",
          "properties": {
            "max_generation_mw": {
              "description": "Maximum electrical generation [MW].",
              "format": "double",
              "type": "number"
            },
            "max_turbined_m3s": {
              "description": "Maximum turbined flow [m³/s].",
              "format": "double",
              "type": "number"
            },
            "min_generation_mw": {
              "description": "Minimum electrical generation [MW].",
              "format": "double",
              "type": "number"
            },
            "min_turbined_m3s": {
              "description": "Minimum turbined flow [m³/s].",
              "format": "double",
              "type": "number"
            },
            "model": {
              "const": "linearized_head",
              "type": "string"
            }
          },
          "required": [
            "model",
            "min_turbined_m3s",
            "max_turbined_m3s",
            "min_generation_mw",
            "max_generation_mw"
          ],
          "type": "object"
        },
        {
          "additionalProperties": false,
          "description": "Full production function with head-area-productivity tables (FPHA model).\n\nProductivity is derived from the FPHA tables in\n`system/hydro_production_models.json`. The `productivity_mw_per_m3s`\nfield is not accepted here or in any other `generation` variant.",
          "properties": {
            "max_generation_mw": {
              "description": "Maximum electrical generation [MW].",
              "format": "double",
              "type": "number"
            },
            "max_turbined_m3s": {
              "description": "Maximum turbined flow [m³/s].",
              "format": "double",
              "type": "number"
            },
            "min_generation_mw": {
              "description": "Minimum electrical generation [MW].",
              "format": "double",
              "type": "number"
            },
            "min_turbined_m3s": {
              "description": "Minimum turbined flow [m³/s].",
              "format": "double",
              "type": "number"
            },
            "model": {
              "const": "fpha",
              "type": "string"
            }
          },
          "required": [
            "model",
            "min_turbined_m3s",
            "max_turbined_m3s",
            "min_generation_mw",
            "max_generation_mw"
          ],
          "type": "object"
        }
      ]
    },
    "RawHydraulicLosses": {
      "description": "Tagged-union intermediate type for the `hydraulic_losses` sub-object.",
      "oneOf": [
        {
          "description": "Losses as a fraction of net head.",
          "properties": {
            "type": {
              "const": "factor",
              "type": "string"
            },
            "value": {
              "description": "Dimensionless loss factor.",
              "format": "double",
              "type": "number"
            }
          },
          "required": [
            "type",
            "value"
          ],
          "type": "object"
        },
        {
          "description": "Constant head loss independent of flow or head.",
          "properties": {
            "type": {
              "const": "constant",
              "type": "string"
            },
            "value_m": {
              "description": "Fixed head loss [m].",
              "format": "double",
              "type": "number"
            }
          },
          "required": [
            "type",
            "value_m"
          ],
          "type": "object"
        }
      ]
    },
    "RawHydro": {
      "additionalProperties": false,
      "description": "Intermediate type for a single hydro plant entry.",
      "properties": {
        "bus_id": {
          "description": "Bus to which this plant's generation is injected.",
          "format": "int32",
          "type": "integer"
        },
        "diversion": {
          "anyOf": [
            {
              "$ref": "#/$defs/RawDiversionChannel"
            },
            {
              "type": "null"
            }
          ],
          "description": "Diversion channel configuration. Absent or null = no diversion channel."
        },
        "downstream_id": {
          "description": "Downstream hydro plant in the cascade. `null` = no downstream.",
          "format": "int32",
          "type": [
            "integer",
            "null"
          ]
        },
        "efficiency": {
          "anyOf": [
            {
              "$ref": "#/$defs/RawEfficiency"
            },
            {
              "type": "null"
            }
          ],
          "description": "Turbine efficiency model. Absent or null = 100% efficiency."
        },
        "entry_stage_id": {
          "default": null,
          "description": "Stage index when the plant enters service. Absent or null = always exists.",
          "format": "int32",
          "type": [
            "integer",
            "null"
          ]
        },
        "evaporation": {
          "anyOf": [
            {
              "$ref": "#/$defs/RawEvaporation"
            },
            {
              "type": "null"
            }
          ],
          "description": "Monthly evaporation coefficients. Absent or null = no evaporation."
        },
        "exit_stage_id": {
          "default": null,
          "description": "Stage index when the plant is decommissioned. Absent or null = never.",
          "format": "int32",
          "type": [
            "integer",
            "null"
          ]
        },
        "filling": {
          "anyOf": [
            {
              "$ref": "#/$defs/RawFillingConfig"
            },
            {
              "type": "null"
            }
          ],
          "description": "Reservoir filling configuration. Absent or null = no filling operation."
        },
        "generation": {
          "$ref": "#/$defs/RawGeneration",
          "description": "Generation model configuration (tagged union on `model` field)."
        },
        "hydraulic_losses": {
          "anyOf": [
            {
              "$ref": "#/$defs/RawHydraulicLosses"
            },
            {
              "type": "null"
            }
          ],
          "description": "Hydraulic loss model. Absent or null = lossless penstock."
        },
        "id": {
          "description": "Hydro plant identifier. Must be unique within the file.",
          "format": "int32",
          "type": "integer"
        },
        "name": {
          "description": "Human-readable plant name.",
          "type": "string"
        },
        "outflow": {
          "$ref": "#/$defs/RawOutflow",
          "description": "Total outflow bounds."
        },
        "penalties": {
          "anyOf": [
            {
              "$ref": "#/$defs/RawHydroPenaltyOverrides"
            },
            {
              "type": "null"
            }
          ],
          "description": "Entity-level penalty overrides. Absent = all penalties use global defaults."
        },
        "reservoir": {
          "$ref": "#/$defs/RawReservoir",
          "description": "Reservoir storage bounds."
        },
        "specific_productivity_mw_per_m3s_per_m": {
          "default": null,
          "description": "Specific productivity `ρ_esp` \\[MW / ((m³/s) · m)\\].\n\n**Resolution cascade** (first source that supplies a non-`null` value wins):\n\n1. Per-`(hydro, stage)` row in `system/hydro_energy_productivity.parquet`\n   (loaded at study setup time by the solver).\n2. This field — a single value applied uniformly across all stages.\n\nAbsent or `null` means this fallback level is skipped.  If the cascade\nfinds no value for a hydro whose generation model requires one\n(`constant_productivity` or `linearized_head`), study setup fails with an\nexplicit error.",
          "format": "double",
          "type": [
            "number",
            "null"
          ]
        },
        "tailrace": {
          "anyOf": [
            {
              "$ref": "#/$defs/RawTailrace"
            },
            {
              "type": "null"
            }
          ],
          "description": "Tailrace elevation model. Absent or null = no tailrace."
        }
      },
      "required": [
        "id",
        "name",
        "bus_id",
        "reservoir",
        "outflow",
        "generation"
      ],
      "type": "object"
    },
    "RawHydroPenaltyOverrides": {
      "additionalProperties": false,
      "description": "Intermediate type for entity-level hydro penalty overrides.\n\nAll 11 fields are `Option<f64>`. Absent fields default to `None`,\nmeaning the global default for that penalty is used.\n\nJSON field names mirror `HydroPenalties` and `HydroPenaltyOverrides` field names.",
      "properties": {
        "diversion_cost": {
          "default": null,
          "format": "double",
          "type": [
            "number",
            "null"
          ]
        },
        "evaporation_violation_cost": {
          "default": null,
          "format": "double",
          "type": [
            "number",
            "null"
          ]
        },
        "filling_target_violation_cost": {
          "default": null,
          "format": "double",
          "type": [
            "number",
            "null"
          ]
        },
        "generation_violation_below_cost": {
          "default": null,
          "format": "double",
          "type": [
            "number",
            "null"
          ]
        },
        "inflow_nonnegativity_cost": {
          "default": null,
          "format": "double",
          "type": [
            "number",
            "null"
          ]
        },
        "outflow_violation_above_cost": {
          "default": null,
          "format": "double",
          "type": [
            "number",
            "null"
          ]
        },
        "outflow_violation_below_cost": {
          "default": null,
          "format": "double",
          "type": [
            "number",
            "null"
          ]
        },
        "spillage_cost": {
          "default": null,
          "format": "double",
          "type": [
            "number",
            "null"
          ]
        },
        "storage_violation_below_cost": {
          "default": null,
          "format": "double",
          "type": [
            "number",
            "null"
          ]
        },
        "turbined_cost": {
          "default": null,
          "format": "double",
          "type": [
            "number",
            "null"
          ]
        },
        "turbined_violation_below_cost": {
          "default": null,
          "format": "double",
          "type": [
            "number",
            "null"
          ]
        },
        "water_withdrawal_violation_cost": {
          "default": null,
          "format": "double",
          "type": [
            "number",
            "null"
          ]
        }
      },
      "type": "object"
    },
    "RawOutflow": {
      "additionalProperties": false,
      "description": "Intermediate type for the `outflow` sub-object.",
      "properties": {
        "max_outflow_m3s": {
          "description": "Maximum total outflow [m³/s]. `null` = no upper bound.",
          "format": "double",
          "type": [
            "number",
            "null"
          ]
        },
        "min_outflow_m3s": {
          "description": "Minimum total outflow [m³/s].",
          "format": "double",
          "type": "number"
        }
      },
      "required": [
        "min_outflow_m3s"
      ],
      "type": "object"
    },
    "RawReservoir": {
      "additionalProperties": false,
      "description": "Intermediate type for the `reservoir` sub-object.",
      "properties": {
        "max_storage_hm3": {
          "description": "Maximum operational storage [hm³].",
          "format": "double",
          "type": "number"
        },
        "min_storage_hm3": {
          "description": "Minimum operational storage (dead volume) [hm³].",
          "format": "double",
          "type": "number"
        }
      },
      "required": [
        "min_storage_hm3",
        "max_storage_hm3"
      ],
      "type": "object"
    },
    "RawTailrace": {
      "description": "Tagged-union intermediate type for the `tailrace` sub-object.\n\nUses `#[serde(tag = \"type\")]` internally-tagged on the `\"type\"` field.",
      "oneOf": [
        {
          "description": "Polynomial tailrace curve.",
          "properties": {
            "coefficients": {
              "description": "Polynomial coefficients in ascending power order.",
              "items": {
                "format": "double",
                "type": "number"
              },
              "type": "array"
            },
            "type": {
              "const": "polynomial",
              "type": "string"
            }
          },
          "required": [
            "type",
            "coefficients"
          ],
          "type": "object"
        },
        {
          "description": "Piecewise-linear tailrace curve.",
          "properties": {
            "points": {
              "description": "Breakpoints defining the piecewise-linear curve.",
              "items": {
                "$ref": "#/$defs/RawTailracePoint"
              },
              "type": "array"
            },
            "type": {
              "const": "piecewise",
              "type": "string"
            }
          },
          "required": [
            "type",
            "points"
          ],
          "type": "object"
        }
      ]
    },
    "RawTailracePoint": {
      "additionalProperties": false,
      "description": "Intermediate type for a single piecewise tailrace breakpoint.",
      "properties": {
        "height_m": {
          "description": "Downstream water level (tailrace height) at this outflow [m].",
          "format": "double",
          "type": "number"
        },
        "outflow_m3s": {
          "description": "Total outflow at this point [m³/s].",
          "format": "double",
          "type": "number"
        }
      },
      "required": [
        "outflow_m3s",
        "height_m"
      ],
      "type": "object"
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "additionalProperties": false,
  "description": "Top-level intermediate type for `hydros.json`.\n\nPrivate — only used during deserialization. Not re-exported.",
  "properties": {
    "$schema": {
      "description": "`$schema` field — informational, not validated.",
      "type": [
        "string",
        "null"
      ]
    },
    "hydros": {
      "description": "Array of hydro plant entries.",
      "items": {
        "$ref": "#/$defs/RawHydro"
      },
      "type": "array"
    }
  },
  "required": [
    "hydros"
  ],
  "title": "RawHydroFile",
  "type": "object"
}