Skip to main content

Hydrological model extension package extracted from dmg

Project description

dmot

Hydrological model extension package extracted from dmg, now extended with a modular reservoir dispatch scheduling kernel.

Package Structure

dmotpy/
├── models/                    # Hydrological rainfall-runoff models (HBV, GR4J, …)
│   ├── core/                  # 38+ step-function model implementations
│   ├── flux/                  # Flux calculation components
│   ├── unithydro/             # Unit hydrograph routing
│   └── special/               # Full class-based model wrappers
├── neural_networks/           # Calibration & parameterization networks
├── trainers/                  # Training loops (CalTrainer, FasterTrainer)
└── dispatch/                  # *** NEW: Reservoir dispatch scheduling kernel ***
    ├── domain/                # Layer 3: Domain objects
    ├── kernel/                # Layer 5: Physics kernel & simulator
    ├── plugins/               # Layer 4 & 6: Operation modules & plugin registry
    ├── services/              # Layer 2: Service orchestration
    ├── evaluator.py           # Evaluation engine
    └── mcp/                   # Layer 1: FastMCP tool interface

Dispatch Kernel — 6-Layer Architecture

The dispatch module implements a single-reservoir, modular, service-oriented scheduling kernel designed for:

  • Rule-based dispatch with structured operation modules
  • Unified simulation with un-bypassable physics core
  • Plugin-based objectives, constraints, and strategies
  • FastMCP tool exposure for agent integration
  • Future extension to CBR, multi-objective optimization, and game-theoretic planning

Layer 1: Interface (FastMCP)

Exposes high-level capabilities as MCP tools:

Tool Description
get_snapshot Current state, spec, available modules
list_operation_modules Available module types with descriptions
create_program Create a dispatch program
simulate_program Run a simulation against a forecast
evaluate_program Simulate and evaluate against objectives
compare_programs Compare multiple programs side-by-side
explain_program Human-readable program explanation

Does not expose: direct state mutation, kernel bypass, constraint override.

Layer 2: Services

Service Responsibility
SnapshotService State and spec queries
ProgramService Dispatch program CRUD
SimulationService Run simulations, simulate-and-evaluate
EvaluationService Evaluate results, compare programs
ExplanationService Generate human-readable explanations

Layer 3: Domain Objects

Object Purpose
ReservoirSpec Static reservoir geometry, curves, gates, limits
ReservoirState Dynamic state: level, storage, inflow, outflow
ForecastBundle Single-value or ensemble forecast scenarios
DispatchProgram Structured scheduling via operation modules
ModuleInstance A concrete module with params & switch conditions
ConstraintSet Collection of hard/soft constraint rules
ObjectiveSet Weighted multi-criteria evaluation objectives
SimulationResult Full trajectory with water balance diagnostics
EvaluationResult Multi-level scoring output

Layer 4: Operation Modules

6 built-in module types:

Module Type Description
constant_release Fixed flow release regardless of state
inflow_driven Release = f(inflow) with ratio + offset
storage_driven Release based on level deviation from target
combined_driven Multi-factor conditional logic (flood/drought/normal)
level_tracking PID-like target water level tracking
external_constraint Follow a pre-computed release schedule

New module types can be added by implementing ModuleHandler and registering with ModuleRegistry.

Layer 5: Physics Kernel

The un-bypassable core:

  • Water balance: S(t+1) = S(t) + (I - O) × Δt
  • Level-capacity interpolation (forward & inverse)
  • Release clamping to physical limits (min/max/outlet capacity)
  • Level change rate limiting
  • Constraint checking (level max/min, release max/min, change rate)

No strategy, agent, or optimizer can directly mutate state — all transitions must go through the physics kernel.

Layer 6: Plugins

Pre-registered plugin slots for future extension:

Slot Status Future Use
ModuleHandler ✅ Built-in Custom operation modules
ConstraintPlugin ✅ Built-in Custom constraint types
ObjectivePlugin ✅ Built-in Custom evaluation criteria
SolverPlugin 🔲 Reserved Multi-objective optimization
CaseRetrievalPlugin 🔲 Reserved CBR knowledge reuse
PlannerPlugin 🔲 Reserved Game-theoretic / LLM planning

Quick Start

Define a reservoir

from dmotpy.dispatch.domain.reservoir_spec import ReservoirSpec

spec = ReservoirSpec(
    name="MyReservoir",
    dead_level=100.0, normal_level=120.0,
    flood_limit_level=130.0, check_flood_level=135.0, crest_level=140.0,
    total_capacity=3500.0, flood_control_capacity=1300.0, dead_capacity=100.0,
    level_capacity={100.0: 100, 120.0: 1200, 130.0: 2200, 140.0: 3500},
    max_release=3000.0, min_release=10.0,
)

Create a dispatch program

from dmotpy.dispatch.domain.dispatch_program import DispatchProgram, ModuleInstance

program = DispatchProgram(
    name="flood_response",
    modules=[
        ModuleInstance(
            module_type="constant_release", name="normal",
            params={"release": 50.0},
            switch_in_conditions={"level_below": 128.0},
        ),
        ModuleInstance(
            module_type="inflow_driven", name="flood",
            params={"ratio": 1.2, "min_release": 100.0},
            switch_in_conditions={"level_above": 128.0},
        ),
    ],
)

Run simulation

from datetime import datetime
from dmotpy.dispatch.domain.reservoir_state import ReservoirState
from dmotpy.dispatch.domain.forecast import ForecastBundle
from dmotpy.dispatch.kernel.simulator import DispatchSimulator

state = ReservoirState(
    timestamp=datetime(2024, 7, 1),
    level=118.0, storage=900.0, inflow=100.0, outflow=50.0,
)
forecast = ForecastBundle.from_deterministic([50]*6 + [800, 1200, 1000, 700, 400, 200] + [50]*12)

sim = DispatchSimulator(spec)
result = sim.simulate(state, forecast, program)
print(result.summary())

Evaluate

from dmotpy.dispatch.domain.objectives import ObjectiveSet, ObjectiveWeight, ObjectiveType, ObjectiveDirection
from dmotpy.dispatch.evaluator import Evaluator

obj = ObjectiveSet()
obj.add(ObjectiveWeight(name="flood", objective_type=ObjectiveType.FLOOD_CONTROL,
                        direction=ObjectiveDirection.MAXIMIZE, weight=0.7))
obj.add(ObjectiveWeight(name="eco", objective_type=ObjectiveType.ECOLOGY,
                        direction=ObjectiveDirection.MAXIMIZE, weight=0.3))

evaluator = Evaluator(spec, obj)
eval_result = evaluator.evaluate(result, program)
print(eval_result.summary())

Use via MCP (for agents)

from dmotpy.dispatch.mcp import DispatchMCPServer

server = DispatchMCPServer(spec, initial_state)
server.get_snapshot()                          # Get state + spec
server.create_program("p1", "constant_release", {"release": 80.0})
server.simulate_program("p1", [60.0]*24)       # Simulate 24 steps
server.compare_programs(["p1", "p2"], [60.0]*24)  # Compare
server.explain_program("p1")                   # Explain

Running Tests

pip install pytest
pytest tests/dispatch/ -v

Dependencies

Package Purpose
numpy Numerical computation
scipy Scientific computing
torch Differentiable models
pydantic Domain object validation (v2)
fastmcp MCP tool interface (optional)
pytest Testing

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dmotpy-0.1.0.tar.gz (129.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dmotpy-0.1.0-py3-none-any.whl (193.4 kB view details)

Uploaded Python 3

File details

Details for the file dmotpy-0.1.0.tar.gz.

File metadata

  • Download URL: dmotpy-0.1.0.tar.gz
  • Upload date:
  • Size: 129.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.11 {"installer":{"name":"uv","version":"0.9.11"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for dmotpy-0.1.0.tar.gz
Algorithm Hash digest
SHA256 03989c81b5034ab458a1b6f32dc6c9f80915a34a909415fc719ee155c8b1ab82
MD5 ca8f6d5436fc29e21dffb7fe8486eda3
BLAKE2b-256 80279869dc8d5185b3339cfa3dd6e5e0c013f62b05d77b3f4038b38fbf37e442

See more details on using hashes here.

File details

Details for the file dmotpy-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: dmotpy-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 193.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.11 {"installer":{"name":"uv","version":"0.9.11"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for dmotpy-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d49a337abc2da32e7e0ffc7015a8debee57bc4e2fce95ad3ede2d4a85f200522
MD5 637376b81418a622415e9c86c071d349
BLAKE2b-256 46a11a36bf28f7ba1d5e33b4fb571529acab7be3e6f09ac4e2e61210c7cba5d9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page