CLI Reference

FHOPS exposes a Typer-based CLI called fhops. Detailed command documentation will be autogenerated with sphinx-click in upcoming iterations. For now, the primary commands are:

  • fhops validate — validate operational scenario inputs.

  • fhops validate tactical-operational scenario.yaml — validate a Phase 6 aggregate planning contract and print period/product/block/option/facility/flow dimensions before model construction.

  • fhops solve-mip — build and solve the deterministic MIP.

  • fhops solve-mip-operational — run the shift-indexed operational MILP prototype (bundle + Pyomo builder + HiGHS wrapper).

  • fhops solve-heur — run the metaheuristic solver (simulated annealing v0.1).

  • fhops solve-heur --iters 5000 --seed 123 — adjust SA iteration budget/seed (additional tuning flags under review).

  • fhops evaluate — replay a schedule and compute KPIs.

  • fhops eval-playback — generate shift/day summaries from a schedule (deterministic playback).

  • fhops benchmark — compare solver runtimes and quality on a single scenario (legacy helper).

  • fhops bench suite — run the full benchmarking harness across sample or user-supplied scenarios.

  • fhops geo distances — derive block-to-block distance matrices from GeoJSON geometry.

  • fhops plan rolling — execute rolling-horizon solves (stub/SA/MIP hooks) with metadata-rich exports for per-iteration telemetry and locked assignments; see Rolling-Horizon Planning. Supports solver options such as --mip-solver-option Threads=64 (repeatable) or GRB_THREADS for Gurobi, plus --out-json, --out-assignments, and per-iteration JSONL/CSV exports. Feed the locked assignments into fhops eval-playback or fhops.planning.compute_rolling_kpis() for KPI deltas against a baseline.

  • fhops plan tactical-operational — solve the Phase 6 aggregate block × system × period MILP with continuous, semi-continuous, or whole-block harvest modes; supports cost, profit, and NPV objective profiles, optional road/silviculture/fleet-investment modules, and exports objective decomposition, harvest decisions, production, transport flows, purchases, inventory, road, silviculture, and fleet tables. See Tactical–Operational Scenario Contract.

  • fhops scenario overlay / fhops scenario diff / fhops scenario batch — apply sparse tactical scenario overlays, compare scenario assumptions field-by-field, and solve scenario batches with comparison reports.

  • fhops report tactical — write normalized CSV/Parquet/Markdown report tables from a tactical solve JSON summary.

  • fhops synth tactical — generate deterministic TOPM-shaped tactical scale scenarios for benchmarking.

  • fhops synth tactical-practitioner — generate the redistributable practitioner-scale tactical validation case (24 blocks, 8 periods, roads/silviculture/fleet modules).

  • fhops scenario benchmark — solve generated tactical scale cases and export runtime, build/solve timing, and Pyomo model-size telemetry.

  • fhops plan compile-tactical — compile tactical harvest commitments into a loadable operational YAML/CSV bundle using an existing operational scenario for machines, calendars, and rates.

Run fhops --help to inspect the full command tree.

Baseline usage:

  • fhops solve-mip tests/fixtures/regression/regression.yaml --out /tmp/regression_mip.csv

  • fhops solve-mip examples/med42/scenario.yaml --driver gurobi --time-limit 600 --out tmp/med42_gurobi.csv — run the MIP with the Gurobi backend (requires installing fhops[gurobi] and configuring a licence).

  • fhops solve-mip-operational examples/tiny7/scenario.yaml --out tmp/tiny7_operational.csv --time-limit 60 — run the day×shift operational MILP benchmark and emit assignments/KPIs for the tiny7 scenario. Use --dump-bundle foo.json to capture the serialized bundle for debugging, or --bundle-json foo.json to replay the solver without reloading the scenario. Telemetry/logging hooks mirror the heuristics (--telemetry-log for JSONL records, --watch for a live snapshot even though the run is single-shot). --incumbent seed.csv accepts a heuristic schedule (machine_id, block_id, day, shift_id[, assigned, production]) as a warm start; the CLI expands those rows into the auxiliary Pyomo variables (transitions, activation binaries, landing inventories) before invoking the solver. Today the feature is operationally correct but only practically useful on the smallest scenarios—Gurobi still discards greedy/SA seeds on med42/large84 because they are far from its internal incumbents—so expect little to no runtime improvement unless you provide a near-feasible schedule.

  • fhops plan rolling examples/med42/scenario.yaml --master-days 42 --sub-days 21 --lock-days 7 --solver mip --mip-solver gurobi --mip-solver-option Threads=64 --mip-time-limit 600 --out-json tmp/med42_rolling.json --out-assignments tmp/med42_rolling_assignments.csv — run the rolling MILP planner with a Gurobi backend and archive both telemetry JSON and playback-ready assignments. Use --out-iterations-jsonl/--out-iterations-csv to capture per-iteration runtimes/objectives and pass the assignments into fhops eval-playback to compute KPI deltas quickly.

  • fhops solve-heur tests/fixtures/regression/regression.yaml --out /tmp/regression_sa.csv

  • fhops evaluate tests/fixtures/regression/regression.yaml --assignments tmp/regression_sa.csv --kpi-mode extended

  • fhops eval-playback tests/fixtures/regression/regression.yaml --assignments /tmp/regression_sa.csv --shift-out tmp/shift_summary.csv --day-out tmp/day_summary.csv

  • fhops eval-playback tests/fixtures/regression/regression.yaml --assignments tmp/regression_sa.csv --samples 10 --downtime-prob 0.1 --weather-prob 0.2 — run stochastic playback, capturing downtime and weather variability.

  • fhops eval-playback ... --landing-prob 0.3 --landing-mult-min 0.3 --landing-mult-max 0.7 --landing-duration 2 — simulate landing congestion shocks that temporarily reduce throughput.

  • fhops eval-playback ... --shift-parquet tmp/shift.parquet --day-parquet tmp/day.parquet --summary-md tmp/playback.md — export Parquet files and a Markdown summary alongside the CSV outputs. See Evaluation Workflows for a full end-to-end example.

  • fhops eval-playback ... --shift-out tmp/shift_summary.csv --day-out tmp/day_summary.csv — recommended when using shift calendars/blackouts so you can verify shift-level KPIs roll up to the day totals.

  • fhops bench suite --scenario examples/tiny7/scenario.yaml --out-dir tmp/benchmarks

  • fhops synth generate tmp/custom_bundle --tier medium --seed 777 --blocks 10:12 — create a synthetic scenario bundle using the medium preset with a custom block range; add --preview to inspect metadata without writing files.

  • fhops synth batch plans/synthetic.yaml --overwrite — process several bundles in one call using a YAML/TOML/JSON plan (each entry supports the same fields as generate), refreshing metadata automatically when writing to examples/synthetic.

Both solve-mip and solve-heur export schedules with the columns machine_id, block_id, day, and shift_id. The shift identifier matches the scenario’s shift calendar (or defaults to S1 when only day-level data is provided) so downstream tooling can analyse sub-daily assignments.

Heuristic configuration reference

See Heuristic Presets & Registry Guide for an end-to-end walkthrough. Common CLI patterns:

  • fhops solve-heur ... --operator swap --operator move — restrict the operator set (defaults to all registered operators).

  • fhops solve-heur ... --operator-weight swap=2 --operator-weight move=0.5 — adjust operator weights; zero disables an operator.

  • fhops bench suite ... --operator swap --operator-weight swap=2 — pass the same options when running aggregate benchmarks; the summary now records the operator configuration in operators_config.

  • fhops solve-heur ... --operator-preset swap-only — apply predefined operator weight profiles (available presets: balanced, move-only, swap-heavy, swap-only, diversify, explore, mobilisation, stabilise). Presets may be combined with explicit --operator and --operator-weight overrides.

  • explore enables the advanced neighbourhood operators with moderate weights for general diversification, mobilisation prioritises mobilisation shake moves for distance-constrained scenarios, and stabilise tones down advanced operators to focus on consolidation.

  • Tiny ladder defaults: fhops solve-heur examples/tiny7/scenario.yaml auto-enables small batched sampling (batch_size=4) and a mobilisation-shake boost after prolonged stalls; pass --batch-size/--max-workers to override.

  • fhops bench suite --operator-preset swap-heavy --operator-weight move=1 — use presets within benchmarking; final configurations are captured in the summary output.

  • fhops solve-heur --list-operator-presets (or fhops bench suite --list-operator-presets) — display all presets with their weights and descriptions.

  • fhops bench suite --compare-preset explore --compare-preset mobilisation — sweep multiple presets in one run; the benchmark summary adds a preset_label column and exports per-preset assignment CSVs for side-by-side analysis.

  • fhops bench suite --include-tabu — benchmark the Tabu prototype alongside SA (produces additional tabu rows in the summary output).

  • fhops bench suite --include-ils --include-tabu — emit solver comparison columns (best heuristic, gap/ratio metrics) so you can rank heuristics against each other and against MIP when included.

  • fhops solve-heur ... --batch-neighbours 4 --parallel-workers 4 — sample multiple neighbour candidates per iteration and score them with a small worker pool (opt-in; defaults keep sequential evaluation).

  • fhops solve-heur ... --parallel-multistart 8 — launch several SA runs in parallel, using the best result while logging per-run telemetry (requires --parallel-workers for true parallelism).

  • fhops solve-heur ... --telemetry-log fhops_runs.jsonl — append telemetry entries (objective, KPIs, operator stats, parallel configuration) to a JSONL file for later analysis.

  • fhops solve-heur ... --kpi-mode basic — print the concise KPI bundle (production/mobilisation only). Use extended to show utilisation, downtime, and weather metrics.

  • fhops solve-heur ... --show-operator-stats — print per-operator proposal/acceptance statistics at the end of a run (also available in the benchmark summaries).

  • fhops solve-ils ... --perturbation-strength 3 --stall-limit 10 --hybrid-use-mip — run the Iterated Local Search solver. The optional hybrid flag attempts a time-boxed MIP warm start when ILS stalls; --batch-neighbours/--parallel-workers reuse the SA batching infrastructure.

  • fhops solve-tabu ... — run the Tabu Search prototype (–tabu-tenure, –stall-limit, –batch-neighbours, –parallel-workers) and export telemetry consistent with SA runs.

  • fhops bench suite --include-ils — add ILS rows to the benchmark summary (CSV/JSON). Combine with --include-tabu for full solver comparisons.

  • python scripts/render_benchmark_plots.py tmp/benchmarks/summary.csv — turn benchmark summaries into comparison charts for documentation (see Benchmarking Harness).

  • fhops bench suite --include-ils --include-tabu --out-dir tmp/benchmarks_compare — generate the richer comparison columns (best heuristic solver, objective gaps, runtime ratios).

  • fhops solve-heur ... --profile explore — apply a named solver profile that bundles presets, batching, and optional multi-start settings (see fhops solve-heur --list-profiles).

  • fhops bench suite --profile mobilisation — reuse the same profile defaults across SA/ILS/Tabu when benchmarking; explicit CLI overrides still win.

The evaluation output should include mobilisation_cost=6.0 and sequencing_violation_count=0 if the regression baseline is satisfied.

Dataset command cheat sheet

fhops dataset estimate-productivity exposes every productivity preset that now carries detailed docstrings (see fhops.cli.dataset). Use the following guide to jump from the CLI role flag to the corresponding API surface:

CLI --machine-role

When to pick it

Key CLI options

Docstring to consult

forwarder

Cut-to-length or shortwood workflows needing payload/distance regressions.

--forwarder-model + payload/length inputs listed in the CLI help.

fhops.productivity.forwarder_bc.estimate_forwarder_productivity_bc()

grapple_skidder

Full-tree or salvage skidding (ADV6N7, Han 2018, ADV1N12 presets).

--grapple-skidder-model with extraction distance, payload, utilisation overrides as needed.

fhops.productivity.grapple_bc.estimate_grapple_skidder_productivity_adv6n7()

grapple_yarder / skyline_yarder

Cable-running or standing skyline studies (TR125/127, FNCY12, TN173, Hi-Skid).

--model plus the lateral/log-count options described in the skyline helper docstrings.

fhops.productivity.cable_logging

loader / loader_forwarder

Loader-forwarder or Barko/Hypro presets (ADV5N1, ADV2N26, TN261, Barko 450).

--loader-model with payload/utilisation/delay switches.

fhops.productivity.loader

helicopter_longline

Longline or direct-to-water transfer flights with payload/delay modelling.

--helicopter-model / --helicopter-preset plus distance/payload overrides.

fhops.productivity.estimate_helicopter_longline_productivity()

shovel_logger

Sessions & Boston serpentine shovel logging.

--shovel-* swing/payload options (defaults seeded by the preset).

fhops.cli.dataset._evaluate_shovel_logger_result()

Each function linked above now documents parameter units, accepted ranges, default templates, and the structure of the result dataclasses. Run sphinx-build -b html docs _build/html -W after adding new roles so these cross-references stay valid.