{ "cells": [ { "cell_type": "markdown", "id": "9a81a49a", "metadata": {}, "source": [ "# Harvest System Mix Explorer\n", "\n", "Analyse machine-role allocation and system mixes for the synthetic medium scenario." ] }, { "cell_type": "code", "execution_count": 1, "id": "858c7745", "metadata": { "execution": { "iopub.execute_input": "2026-10-05T12:57:10.087190Z", "iopub.status.busy": "2026-10-05T12:57:10.087073Z", "iopub.status.idle": "2026-10-05T12:57:10.577453Z", "shell.execute_reply": "2026-10-05T12:57:10.576683Z" } }, "outputs": [], "source": [ "import sys\n", "from pathlib import Path\n", "\n", "PROJECT_ROOT = Path.cwd().resolve()\n", "while PROJECT_ROOT != PROJECT_ROOT.parent and not (PROJECT_ROOT / \"pyproject.toml\").exists():\n", " PROJECT_ROOT = PROJECT_ROOT.parent\n", "if not (PROJECT_ROOT / \"pyproject.toml\").exists():\n", " raise RuntimeError(\n", " \"Notebook must be executed within a FHOPS checkout (pyproject.toml not found).\"\n", " )\n", "if str(PROJECT_ROOT) not in sys.path:\n", " sys.path.insert(0, str(PROJECT_ROOT))\n", "\n", "\n", "import pandas as pd\n", "import yaml\n", "\n", "from fhops.scenario.io import load_scenario\n", "from fhops.scenario.synthetic import SyntheticDatasetConfig, generate_random_dataset\n", "\n", "SCENARIO = PROJECT_ROOT / \"examples/synthetic/medium/scenario.yaml\"\n", "ASSIGNMENTS = PROJECT_ROOT / \"docs/examples/analytics/data/synthetic_medium_sa_assignments.csv\"" ] }, { "cell_type": "markdown", "id": "7e51062d", "metadata": {}, "source": [ "## System Mix Metadata" ] }, { "cell_type": "code", "execution_count": 2, "id": "95f81bca", "metadata": { "execution": { "iopub.execute_input": "2026-10-05T12:57:10.579551Z", "iopub.status.busy": "2026-10-05T12:57:10.579309Z", "iopub.status.idle": "2026-10-05T12:57:10.597738Z", "shell.execute_reply": "2026-10-05T12:57:10.597113Z" } }, "outputs": [ { "data": { "text/plain": [ "{'ground_fb_skid': 0.15873015873015875,\n", " 'ctl': 0.15873015873015875,\n", " 'steep_tethered': 0.11904761904761904,\n", " 'cable_running': 0.11904761904761904,\n", " 'cable_running_fncy12': 0.03968253968253969,\n", " 'cable_highlead_tn147': 0.023809523809523808,\n", " 'cable_running_tr122_extended': 0.015873015873015872,\n", " 'cable_running_tr122_shelterwood': 0.015873015873015872,\n", " 'cable_running_tr122_clearcut': 0.015873015873015872,\n", " 'cable_micro_ecologger': 0.03968253968253969,\n", " 'cable_micro_gabriel': 0.03968253968253969,\n", " 'cable_micro_christie': 0.03968253968253969,\n", " 'cable_micro_teletransporteur': 0.03968253968253969,\n", " 'cable_micro_timbermaster': 0.03968253968253969,\n", " 'cable_micro_hi_skid': 0.03968253968253969,\n", " 'cable_running_sr54': 0.015873015873015872,\n", " 'cable_running_tr75_bunched': 0.015873015873015872,\n", " 'cable_running_tr75_handfelled': 0.015873015873015872,\n", " 'cable_standing_tr125_strip': 0.015873015873015872,\n", " 'cable_partial_tr127_block1': 0.015873015873015872,\n", " 'cable_partial_tr127_block5': 0.015873015873015872}" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "metadata = yaml.safe_load((PROJECT_ROOT / \"examples/synthetic/metadata.yaml\").read_text())\n", "medium_meta = metadata[\"medium\"]\n", "medium_meta.get(\"system_mix\", {})" ] }, { "cell_type": "markdown", "id": "a4cd5879", "metadata": {}, "source": [ "## Machine Roles in Scenario" ] }, { "cell_type": "code", "execution_count": 3, "id": "5a009dc3", "metadata": { "execution": { "iopub.execute_input": "2026-10-05T12:57:10.599116Z", "iopub.status.busy": "2026-10-05T12:57:10.598997Z", "iopub.status.idle": "2026-10-05T12:57:10.698550Z", "shell.execute_reply": "2026-10-05T12:57:10.698061Z" } }, "outputs": [ { "data": { "text/plain": [ "role\n", "harvester 2\n", "forwarder 2\n", "Name: count, dtype: int64" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "scenario = load_scenario(SCENARIO)\n", "roles = pd.Series([machine.role or \"unassigned\" for machine in scenario.machines], name=\"role\")\n", "roles.value_counts()" ] }, { "cell_type": "markdown", "id": "f3badfd0", "metadata": {}, "source": [ "## Generate Custom Mix" ] }, { "cell_type": "code", "execution_count": 4, "id": "653747c1", "metadata": { "execution": { "iopub.execute_input": "2026-10-05T12:57:10.700513Z", "iopub.status.busy": "2026-10-05T12:57:10.700264Z", "iopub.status.idle": "2026-10-05T12:57:10.707393Z", "shell.execute_reply": "2026-10-05T12:57:10.706717Z" } }, "outputs": [ { "data": { "text/plain": [ "role\n", "harvester 3\n", "forwarder 3\n", "Name: count, dtype: int64" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "custom_config = SyntheticDatasetConfig(\n", " name=\"synthetic-mix-demo\",\n", " tier=\"large\",\n", " num_blocks=12,\n", " num_days=16,\n", " num_machines=6,\n", " system_mix={\"ground_fb_skid\": 0.5, \"ctl\": 0.3, \"steep_tethered\": 0.2},\n", ")\n", "bundle = generate_random_dataset(custom_config, seed=404)\n", "custom_roles = bundle.machines[\"role\"].fillna(\"unassigned\")\n", "custom_roles.value_counts()" ] }, { "cell_type": "markdown", "id": "05c8313f", "metadata": {}, "source": [ "## Role Comparison" ] }, { "cell_type": "code", "execution_count": 5, "id": "f25034bc", "metadata": { "execution": { "iopub.execute_input": "2026-10-05T12:57:10.709601Z", "iopub.status.busy": "2026-10-05T12:57:10.709475Z", "iopub.status.idle": "2026-10-05T12:57:10.715885Z", "shell.execute_reply": "2026-10-05T12:57:10.715098Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
scenario_rolescustom_mix_roles
role
harvester23
forwarder23
\n", "
" ], "text/plain": [ " scenario_roles custom_mix_roles\n", "role \n", "harvester 2 3\n", "forwarder 2 3" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "comparison_df = pd.DataFrame(\n", " {\"scenario_roles\": roles.value_counts(), \"custom_mix_roles\": custom_roles.value_counts()}\n", ").fillna(0)\n", "comparison_df" ] } ], "metadata": { "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.16" } }, "nbformat": 4, "nbformat_minor": 5 }