{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n\n# Run module\n\nIn this example we demonstrate how to use AequilibraE's run module using Sioux Falls example.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        ".. admonition:: References\n\n  * :doc:`../../run_module`\n  * `parameters_run`\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        ".. seealso::\n    Several functions, methods, classes and modules are used in this example:\n\n    * :attr:`aequilibrae.project.Project.run`\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Imports\nfrom uuid import uuid4\nfrom tempfile import gettempdir\nfrom os.path import join\n\nfrom aequilibrae.parameters import Parameters\nfrom aequilibrae.utils.create_example import create_example"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Let's create the Sioux Falls example in an arbitrary folder.\nfolder = join(gettempdir(), uuid4().hex)\n\nproject = create_example(folder)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "First, let's check the matrix information using ``matrix_summary()``. This method\nprovides us useful information such as the matrix total, minimum and maximum values\nin the array, and the number of non-empty pairs in the matrix.\n\nNotice that the matrix summary is presented for each matrix core.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "project.run.matrix_summary()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "If our matrices folder is empty, instead of a nested dictionary of data,\nAequilibraE run would return an empty dictionary.\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Let's create a graph for mode `car`.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "mode = \"c\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "network = project.network\nnetwork.build_graphs(modes=[mode])\ngraph = network.graphs[mode]\ngraph.set_graph(\"distance\")\ngraph.set_skimming(\"distance\")\ngraph.set_blocked_centroid_flows(False)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "With the method ``graph_summary()``, we can check the total number of links, nodes, and zones,\nas well as the compact number of links and nodes used for computation. If we had more than\none graph, its information would be displayed within the nested dictionary.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "project.run.graph_summary()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "If no graphs have been built, an empty dictionary will be returned.\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Let's add a ``create_delaunay`` function to our ``run/__init__.py`` file.\n\nThis function replicates the example in which we `create Delaunay lines <creating_delaunay_lines>`.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "func_string = \"\"\"\ndef create_delaunay(source: str, name: str, computational_view: str, result_name: str, overwrite: bool=False):\\n\n\\tfrom aequilibrae.utils.create_delaunay_network import DelaunayAnalysis\\n\n\\tproject = get_active_project()\\n\n\\tmatrix = project.matrices\\n\n\\tmat = matrix.get_matrix(name)\\n\n\\tmat.computational_view(computational_view)\\n\n\\tda = DelaunayAnalysis(project)\\n\n\\tda.create_network(source, overwrite)\\n\n\\tda.assign_matrix(mat, result_name)\\n\n\"\"\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "with open(join(folder, \"run\", \"__init__.py\"), \"a\") as file:\n    file.write(\"\\n\")\n    file.write(func_string)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Now we add new parameters to our model\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "p = Parameters(project)\np.parameters[\"run\"][\"create_delaunay\"] = {}\np.parameters[\"run\"][\"create_delaunay\"][\"source\"] = \"zones\"\np.parameters[\"run\"][\"create_delaunay\"][\"name\"] = \"demand_omx\"\np.parameters[\"run\"][\"create_delaunay\"][\"computational_view\"] = \"matrix\"\np.parameters[\"run\"][\"create_delaunay\"][\"result_name\"] = \"my_run_module_example\"\np.write_back()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "And we run the function\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "project.run.create_delaunay()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "<div class=\"alert alert-info\"><h4>Note</h4><p>To run the ``create_delaunay`` function we created above without argument\n   values, we must insert the values as a project parameter. Adding an unused\n   parameter to the ``parameters.yml`` file will raise an execution error.</p></div>\n\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Creating Delaunay lines also creates a ``results_database.sqlite`` that contains the\nresult of the all-or-nothing algorithim that generated the output. We can check\nthe existing results in the results_database using the ``results_summary`` method.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "project.run.results_summary()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Let's check what our Delaunay lines look like!\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import sqlite3\nimport pandas as pd\nimport geopandas as gpd"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Let's retrieve the results\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "res_path = join(project.project_base_path, \"results_database.sqlite\")\nconn = sqlite3.connect(res_path)\n\nresults = pd.read_sql(\"SELECT * FROM my_run_module_example\", conn).set_index(\"link_id\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "with project.db_connection as conn:\n    links = gpd.read_postgis(\n        \"SELECT link_id, st_asBinary(geometry) geometry FROM delaunay_network\", conn, geom_col=\"geometry\", crs=4326\n    )\nlinks.set_index(\"link_id\", inplace=True)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "df = links.join(results)\nmax_vol = df.matrix_tot.max()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "And finally plot the data\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "df.plot(linewidth=5 * df[\"matrix_tot\"] / max_vol, color=\"blue\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "project.close()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Pipeline image credits to\n[Data-pipeline icons created by Vectors Tank - Flaticon](https://www.flaticon.com/free-icons/data-pipeline)\n\n"
      ]
    }
  ],
  "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.10.18"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}