{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n\n# Project Scenarios\n\nIn this example, we show how to use AequilibraE's scenario system to manage multiple model variants\nwithin a single project, using different example networks to demonstrate scenario isolation and management.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        ".. admonition:: References\n\n  * :doc:`../../aequilibrae_project`\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        ".. seealso::\n    Several functions, methods, classes and modules are used in this example:\n\n    * :func:`aequilibrae.project.project.Project.list_scenarios`\n    * :func:`aequilibrae.project.project.Project.use_scenario`\n    * :func:`aequilibrae.project.project.Project.create_empty_scenario`\n    * :func:`aequilibrae.project.project.Project.clone_scenario`\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Imports\nfrom uuid import uuid4\nfrom tempfile import gettempdir\nfrom pathlib import Path\n\nfrom aequilibrae.utils.create_example import create_example\nfrom aequilibrae import TrafficAssignment, TrafficClass"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# We create the example project inside our temp folder.\nfldr = Path(gettempdir()) / uuid4().hex\nproject = create_example(fldr, \"sioux_falls\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Working with scenarios\nLet's first see what scenarios exist in our project\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "project.list_scenarios()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The root scenario is always present and represents the base model.\nLet's examine the current scenario's network\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "print(f\"Current scenario network has {len(project.network.links.data)} links\")\nprint(f\"Current scenario network has {len(project.network.nodes.data)} nodes\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Creating new scenarios\nWe can create empty scenarios or clone existing ones\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Create an empty scenario to manually populate with a future/different network\nproject.create_empty_scenario(\"test_modifications\", \"Scenario for testing network modifications\")\n\n# Clone the root scenario to preserve the original network\nproject.clone_scenario(\"limited_capacity\", \"Testing different assignment parameters\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Let's see our updated scenario list\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "project.list_scenarios()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Switching between scenarios\nEach scenario operates independently with its own data\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Switch to the cloned scenario\nproject.use_scenario(\"limited_capacity\")\nprint(f\"This scenario has {len(project.network.links.data)} links\")\n\n# Modify the network\nwith project.db_connection as conn:\n    conn.execute(\"UPDATE links SET capacity_ab=capacity_ab/2, capacity_ba=capacity_ba/2 WHERE link_id > 20 AND link_id < 50\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Let's perform a traffic assignment in this scenario with lowered capacity\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Build the network graph\nproject.network.build_graphs(fields=[\"distance\", \"capacity_ab\", \"capacity_ba\"], modes=[\"c\"])\ngraph = project.network.graphs[\"c\"]\ngraph.set_graph(\"distance\")\ngraph.set_blocked_centroid_flows(False)\n\n# Get the demand matrix\nmat = project.matrices.get_matrix(\"demand_omx\")\nmat.computational_view()\n\n# Create traffic assignment with alternative parameters\nassigclass = TrafficClass(\"car\", graph, mat)\nassignment = TrafficAssignment(project)\nassignment.add_class(assigclass)\nassignment.set_vdf(\"BPR\")\n\nassignment.set_vdf_parameters({\"alpha\": 0.15, \"beta\": 4.0})\nassignment.set_capacity_field(\"capacity\")\nassignment.set_time_field(\"distance\")\nassignment.max_iter = 10\nassignment.set_algorithm(\"msa\")\n\nassignment.execute()\n\n# Save results specific to this scenario\nassignment.save_results(\"alternative_assignment\")\n\nprint(f\"Assignment completed. Total flow: {assigclass.results.total_link_loads.sum():.2f}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Switch to empty scenario for modifications\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "project.use_scenario(\"test_modifications\")\nprint(f\"Empty scenario has {len(project.network.links.data)} links\")\n\n# This scenario starts with an empty network, suitable for building from scratch\n# or testing specific network configurations"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Scenario isolation demonstration\nLet's switch back to root and show that scenarios are isolated\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "project.use_scenario(\"root\")\nprint(f\"Back to root scenario with {len(project.network.links.data)} links\")\n\n# Check results - only root scenario results should be visible\nroot_results = project.results.list()\nprint(f\"Root scenario has {len(root_results)} result tables\")\n\n# Switch to alternative scenario and check its results\nproject.use_scenario(\"limited_capacity\")\nalt_results = project.results.list()\nprint(f\"Alternative scenario has {len(alt_results)} result tables\")\n\n# Each scenario maintains its own results database\nalternative_assignment_exists = \"alternative_assignment\" in alt_results[\"table_name\"].values\nprint(f\"Alternative assignment result exists in this scenario: {alternative_assignment_exists}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Best practices for scenario management\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Always return to root when doing project-wide operations\nproject.use_scenario(\"root\")\n\n# List scenarios for reference\nfinal_scenarios = project.list_scenarios()\nprint(\"\\nFinal scenario summary:\")\nfor _, scenario in final_scenarios.iterrows():\n    project.use_scenario(scenario['scenario_name'])\n    link_count = len(project.network.links.data)\n    result_count = len(project.results.list())\n    print(f\"  {scenario['scenario_name']}: {link_count} links, {result_count} results\")\n    print(f\"    Description: {scenario['description']}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Clean up\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "project.use_scenario(\"root\")  # Always end on root scenario\nmat.close()\nproject.close()"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "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.15"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}