{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "bd3a37b4",
   "metadata": {
    "collapsed": true,
    "jupyter": {
     "outputs_hidden": true
    }
   },
   "source": [
    "# Getting started\n",
    "\n",
    "The aim of this tutorial is to teach you how to use the sumo-experiments library. First, we'll explain the logic behind creating a simulation, then we'll create one from the pre-parameterized networks available from the library.\n",
    "\n",
    "## How to create a simulation\n",
    "\n",
    "The sumo-experiments library has been designed as a scientific framework, to enable SUMO simulations to be run quickly and reproducibly. It is made up of a set of classes that aims to create a simulation, called here experiment.\n",
    "\n",
    "A SUMO network must be made up of at least two elements: a set of infrastructures, and a set of vehicle flows. It can be completed by optional elements, such as the addition of detectors. To launch a simulation, you must first instantiate generators for each of these elements.\n",
    "\n",
    "Once these elements have been instantiated, you can create an experience, in which you add them as parameters. You then configure the experiment with the parameters of your choice, and you're ready to go. Once the experiment is complete, you can extract the results in CSV format, and even plot them. \n",
    "\n",
    "The diagram below summarizes the steps involved in creating an experiment."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8cac04be",
   "metadata": {},
   "source": [
    "<img src=\"../images/library_operation.png\" style=\"height:500px\" />"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e4eb6989",
   "metadata": {},
   "source": [
    "## Create your first experiment\n",
    "\n",
    "In this section, we'll make our first SUMO experiment. We'll use a pre-set network from the library to instanciate all the elements of the network. We'll be taking a closer look at pre-set networks in the following tutorials.\n",
    "\n",
    "The first step is to import the library into your environment. Be sure that sumo-experiments is already intalled with pip. \n",
    "\n",
    ">***Note :** Matplotlib 3.8.0 shows some issues to be imported. You can have this error when running the code below :*\n",
    ">```\n",
    "\"cannot import name 'docstring' from 'matplotlib'\"\n",
    ">```\n",
    "*If you are in this situation, please execute the following commands in your terminal.*\n",
    ">```\n",
    "sudo apt remove python3-matplotlib\n",
    "pip uninstall matplotlib\n",
    "pip install matplotlib\n",
    ">```\n",
    "\n",
    "> *reference : https://github.com/matplotlib/matplotlib/issues/26827*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "a7e1a8a8",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sumo_experiments as sumexp"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f5f1b4ce",
   "metadata": {},
   "source": [
    "Then, we instanciate a pre-set network from the preset_network package."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "c90fce46",
   "metadata": {},
   "outputs": [],
   "source": [
    "network = sumexp.preset_networks.OneCrossroadNetwork()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "552a7fb0",
   "metadata": {},
   "source": [
    "The OneCrossroadNetwork class contains functions that generates infrastructures, flows and some other features to build the configuration files of a SUMO simulation.\n",
    "\n",
    "These functions include the `generate_infrastructures` function, that returns a InfrastructureBuilder object that contains all of the physical elements of the network (nodes, edges, connections, etc), and the `generate_flows_all_directions` function, that returns a FlowBuilder object containing vehicle flows able to go to any direction at the intersection.\n",
    "\n",
    "The next step is to build the infrastructures. Here, for the unique intersection, we select a length of 200 meters for each edge, a duration of 60 seconds for every green phases, i.e. phases that do not contains any yellow light, and 3 seconds for every yellow phases. The maximum speed allowed on the network is 50 kilometers per hour. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "7ff4e52a",
   "metadata": {},
   "outputs": [],
   "source": [
    "infrastructures = network.generate_infrastructures(\n",
    "    lane_length = 200,\n",
    "    green_time = 60,\n",
    "    yellow_time = 3,\n",
    "    max_speed = 50\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1abdab89",
   "metadata": {},
   "source": [
    "Then, we create the flows that will drive on the network. The vehicles can go at any direction by the intersection, except turning around. Flow frequencies are defined at the network entry level, and at the route level. This means that if we select a frequency of $x$ vehicles per hour, each entry will produce $x$ vehicles per hour, and their routes will be distributed uniformly. This distribution of route over frequency can be parametrized with more complex functions, that we'll see in next tutorials. Here, we select a frequency of 360 vehicles per hour for each entry, that will stop after 600 simulation steps."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "e309b9bd",
   "metadata": {},
   "outputs": [],
   "source": [
    "flows = network.generate_flows_all_directions(\n",
    "    flow_frequency = 360,\n",
    "    stop_generation_time = 600\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "83017ca3",
   "metadata": {},
   "source": [
    "An experiment can now be created. Use the Experiment to create a new experiment, with the infreastructures and flows set previously."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "10a38e2c",
   "metadata": {},
   "outputs": [],
   "source": [
    "experiment = sumexp.Experiment(\n",
    "    name = 'first_tutorial',\n",
    "    infrastructures = infrastructures,\n",
    "    flows = flows\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c6c46b9c",
   "metadata": {},
   "source": [
    "The experiment is now configured, we can run it. Use the *run()* method of the Experiment object, with a simulation_duration paramater, expressed in simulation steps. The `run` method also has a `gui` parameter. If set to `True`, the experiment will be launched in graphical mode with SUMO GUI."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "7a8aa95f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Success.\n",
      "Success.\n"
     ]
    }
   ],
   "source": [
    "experiment.run(\n",
    "    simulation_duration = 600,\n",
    "    gui = True\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d12f38d0",
   "metadata": {},
   "source": [
    "As we said in the introduction, sumo-experiment has been created to produce easily reproducible simulations. The run function implements a parameter `seed` that is the seed that randomly send vehicle in the network, for each flow, with the binomial `distribution`. If you don't set the `seed`, simulation seed will be generated randomly. Then, you can reproduce to exact same traffic scenarios when you fix the seed to the same value. Try it starting multiple time the experiment without seed, and with a fixed seed. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "1a5e18cb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Success.\n",
      "Success.\n"
     ]
    }
   ],
   "source": [
    "experiment.run(gui=True, seed=42, simulation_duration=600)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "edb2438c",
   "metadata": {},
   "source": [
    "You can see that some files have been generated in the current folder. They are the configuration files for the simulation. They __are not__ deleted at the end of the experiment, but you can delete all of them with the `clean_files` method from the Experiment."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "1c229bf2",
   "metadata": {},
   "outputs": [],
   "source": [
    "experiment.clean_files()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b2b99555",
   "metadata": {},
   "source": [
    "**You now have the basis to run a simulation with the sumo-experiments framework. In the next tutorial, we'll see how to use the pre-set networks to quickly run simulations with common networks.**"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
