{ "cells": [ { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2017-10-19T12:41:48.007238Z", "start_time": "2017-10-19T14:41:47.980725+02:00" }, "hideCode": false, "hidePrompt": false }, "source": [ "# Soil Tutorial" ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2017-07-02T16:44:14.120953Z", "start_time": "2017-07-02T18:44:14.117152+02:00" }, "hideCode": false, "hidePrompt": false }, "source": [ "## Introduction" ] }, { "cell_type": "markdown", "metadata": { "cell_style": "center", "collapsed": true, "hideCode": false, "hidePrompt": false }, "source": [ "This notebook is an introduction to the soil agent-based social network simulation framework.\n", "It will focus on a specific use case: studying the propagation of disinformation through TV and social networks.\n", "\n", "\n", "The steps we will follow are:\n", "\n", "* Cover some basics about simulations in Soil (environments, agents, etc.)\n", "* Simulate a basic scenario with a single agent\n", "* Add more complexity to our scenario\n", "* Running the simulation using different configurations\n", "* Analysing the results of each simulation\n", "\n", "The simulations in this tutorial will be kept simple, for the sake of clarity.\n", "However, they provide all the building blocks necessary to model, run and analyse more complex scenarios." ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2017-07-03T13:38:48.052876Z", "start_time": "2017-07-03T15:38:48.044762+02:00" }, "hideCode": false, "hidePrompt": false }, "source": [ "But before that, let's import the soil module and networkx." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2017-11-03T10:58:13.451481Z", "start_time": "2017-11-03T11:58:12.643469+01:00" }, "hideCode": false, "hidePrompt": false }, "outputs": [], "source": [ "from soil import *\n", "import networkx as nx\n", "\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2017-07-03T13:41:19.788717Z", "start_time": "2017-07-03T15:41:19.785448+02:00" }, "hideCode": false, "hidePrompt": false }, "source": [ "## Basic concepts" ] }, { "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": false }, "source": [ "There are two main elements in a soil simulation:\n", " \n", "* The **environment** or model. It assigns agents to nodes in the network, and stores the environment parameters (shared state for all agents).\n", " - `soil.NetworkEnvironment` models also contain a network topology (accessible through through `self.G`). A simulation may use an existing NetworkX topology, or generate one on the fly. The `NetworkEnvironment` class is parameterized, which makes it easy to initialize environments with a variety of network topologies. **In this tutorial, we will manually add a network to each environment**.\n", "* One or more **agents**. Agents are programmed with their individual behaviors, and they can communicate with the environment and with other agents. There are several types of agents, depending on their behavior and their capabilities. Some examples of built-in types of agents are:\n", " - Network agents, which are linked to a node in the topology. They have additional methods to access their neighbors.\n", " - FSM (Finite state machine) agents. Their behavior is defined in terms of states, and an agent will move from one state to another.\n", " - Evented agents, an actor-based model of agents, which can communicate with one another through message passing.\n", " - For convenience, a general `soil.Agent` class is provided, which inherits from Network, FSM and Evented at the same time.\n", "\n", "Soil provides several abstractions over events to make developing agents easier.\n", "This means you can use events (timeouts, delays) in soil, but for the most part we will assume your models will be step-based o.\n" ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2017-07-02T15:55:12.933978Z", "start_time": "2017-07-02T17:55:12.930860+02:00" }, "hideCode": false, "hidePrompt": false }, "source": [ "## Modeling behaviour" ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2017-07-03T13:49:31.269687Z", "start_time": "2017-07-03T15:49:31.257850+02:00" }, "hideCode": false, "hidePrompt": false }, "source": [ "Our first step will be to model how every person in the social network reacts to hearing a piece of disinformation (news).\n", "We will follow a very simple model based on a finite state machine.\n", "\n", "A person may be in one of two states: **neutral** (the default state) and **infected**.\n", "A neutral person may hear about a piece of disinformation either on the TV (with probability **prob_tv_spread**) or through their friends.\n", "Once a person has heard the news, they will spread it to their friends (with a probability **prob_neighbor_spread**).\n", "Some users do not have a TV, so they will only be infected by their friends.\n", "\n", "The spreading probabilities will change over time due to different factors.\n", "We will represent this variance using an additional agent which will not be a part of the social network." ] }, { "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": false }, "source": [ "### Modelling Agents\n", "\n", "The following sections will cover the basics of developing agents in SOIL.\n", "\n", "For more advanced patterns, please check the **examples** folder in the repository." ] }, { "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": false }, "source": [ "#### Basic agents" ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2017-07-03T14:03:07.171127Z", "start_time": "2017-07-03T16:03:07.165779+02:00" }, "hideCode": false, "hidePrompt": false }, "source": [ "The most basic agent in Soil is ``soil.BaseAgent``.\n", "These agents implement their behavior by overriding the `step` method, which will be run in every simulation step.\n", "Only one agent will be running at any given time, and it will be doing so until the `step` function returns.\n", "\n", "Agents can access their environment through their ``self.model`` attribute.\n", "This is most commonly used to get access to the environment parameters and methods.\n", "Here is a simple example of an agent:\n", "\n", "\n", "```python\n", "class ExampleAgent(BaseAgent):\n", " def init(self):\n", " self.is_infected = False\n", " self.steps_neutral = 0\n", " \n", " def step(self):\n", " # Implement agent logic\n", " if self.is_infected:\n", " ... # Do something, like infecting other agents\n", " return self.die(\"No need to do anything else\") # Stop forever\n", " else:\n", " ... # Do something\n", " self.steps_neutral += 1\n", " if self.steps_neutral > self.model.max_steps_neutral:\n", " self.is_infected = True\n", "```\n", "\n", "\n", "\n", "Any kind of agent behavior can be implemented with this `step` function.\n", "However, it has two main drawbacks: 1) complex behaviors can get difficult both write and understand; 2) these behaviors are not composable." ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2017-07-03T14:03:07.171127Z", "start_time": "2017-07-03T16:03:07.165779+02:00" }, "hideCode": false, "hidePrompt": false }, "source": [ "#### FSM agents\n", "\n", "One way to solve both issues is to model agents as **[Finite-state Machines](https://en.wikipedia.org/wiki/Finite-state_machine)** (FSM, for short).\n", "FSM define a series of possible states for the agent, and changes between these states.\n", "These states can be modelled and extended independently.\n", "\n", "This is modelled in Soil through the `soil.FSM` class.\n", "Agents that inherit from ``soil.FSM`` do not need to specify a ``step`` method.\n", "Instead, we describe each finite state with a function.\n", "To change to another state, a function may return the new state, or the ``id`` of a state.\n", "If no state is returned, the state remains unchanged.\n", "\n", "The current state of the agent can be checked with ``agent.state_id``.\n", "That state id can be used to look for other agents in that specific state.\n", "\n", "Our previous example could be expressed like this:\n", "\n", "```python\n", "class FSMExample(FSM):\n", "\n", " def init(self):\n", " self.steps_neutral = 0\n", " \n", " @state(default=True)\n", " def neutral(self):\n", " ... # Do something\n", " self.steps_neutral += 1\n", " if self.steps_neutral > self.model.max_steps_neutral:\n", " return self.infected # Change state\n", "\n", " @state\n", " def infected(self):\n", " ... # Do something\n", " return self.die(\"No need to do anything else\")\n", "```" ] }, { "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": false }, "source": [ "#### Generator-based agents\n", "\n", "Another design pattern that can be very useful in some cases is to model each step (or a specific state) using generators (the `yield` keyword).\n", "\n", "\n", "\n", "```python\n", "class GenExample(BaseAgent):\n", " def step(self):\n", " for i in range(self.model.max_steps_neutral):\n", " ... # Do something\n", " yield # Signal the scheduler that this step is done for now\n", " ... # Do something\n", " return self.die(\"No need to do anything else\") \n", "```" ] }, { "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": false }, "source": [ "#### Telling the scheduler when to wake up an agent\n", "\n", "By default, every agent will be called in every simulation step, and the time elapsed between two steps is controlled by the `interval` attribute in the environment.\n", "\n", "But agents may signal the scheduler when they expect to be called again.\n", "This is especially useful when an agent is going to be dormant for a long time.\n", "To do so, an agent can return (or `yield`) from a `step` or a `state` a value of type `soil.When` (absolute time), `soil.Delta` (relative time) or `soil.Cond`, telling the scheduler when the agent will be ready to run again.\n", "If it returns nothing (i.e., `None`), the agent will be ready to run at the next simulation step." ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2017-07-02T12:22:53.931963Z", "start_time": "2017-07-02T14:22:53.928340+02:00" }, "hideCode": false, "hidePrompt": false }, "source": [ "### Environment agents" ] }, { "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": false }, "source": [ "Environment agents allow us to control the state of the environment.\n", "In this case, we will use an environment agent to simulate a very viral event.\n", "\n", "When the event happens, the agent will modify the probability of spreading the rumor." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2017-11-03T10:58:17.653736Z", "start_time": "2017-11-03T11:58:17.612944+01:00" }, "hideCode": false, "hidePrompt": false }, "outputs": [], "source": [ "import logging\n", "\n", "class EventGenerator(BaseAgent):\n", " level = logging.INFO\n", " \n", " def step(self):\n", " # Do nothing until the time of the event\n", " yield When(self.model.event_time)\n", " self.info(\"TV event happened\")\n", " self.model.prob_tv_spread = 0.5\n", " self.model.prob_neighbor_spread *= 2\n", " self.model.prob_neighbor_spread = min(self.model.prob_neighbor_spread, 1)\n", " yield\n", " self.model.prob_tv_spread = 0\n", "\n", " while self.alive:\n", " self.model.prob_neighbor_spread = self.model.prob_neighbor_spread * self.model.neighbor_factor\n", " if self.model.prob_neighbor_spread < 0.01:\n", " return self.die(\"neighbors can no longer spread the rumour\")\n", " yield" ] }, { "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": false }, "source": [ "### Environment (Model)\n", "\n", "Let's define a environment model to test our event generator agent.\n", "This environment will have a single agent (the event generator).\n", "We will also tell the environment to save the value of `prob_tv_spread` after every step:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "hideCode": false, "hidePrompt": false }, "outputs": [], "source": [ "class NewsEnvSimple(NetworkEnvironment):\n", " \n", " # Here we set the default parameters for our model\n", " # We will be able to override them on a per-simulation basis\n", " prob_tv_spread = 0.1\n", " prob_neighbor_spread = 0.1\n", " event_time = 10\n", " tv_factor = 0.5\n", " neighbor_factor = 0.9\n", "\n", " \n", " def init(self):\n", " self.add_model_reporter(\"prob_tv_spread\")\n", " self.add_agent(EventGenerator)" ] }, { "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": false }, "source": [ "Once the environment has been defined, we can quickly run our simulation through the `run` method on NewsEnv:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "hideCode": false, "hidePrompt": false }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "ff6ebca13a384769a2a783fcb1808d91", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, description='NewsEnvSimple', max=1, style=ProgressStyle(description_width=…" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, max=1), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\n" ] }, { "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", " \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", " \n", "
stepagent_countprob_tv_spread
time
0010.1
10110.1
11210.5
12310.0
13410.0
14510.0
\n", "
" ], "text/plain": [ " step agent_count prob_tv_spread\n", "time \n", "0 0 1 0.1\n", "10 1 1 0.1\n", "11 2 1 0.5\n", "12 3 1 0.0\n", "13 4 1 0.0\n", "14 5 1 0.0" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "it = NewsEnvSimple.run(iterations=1, max_time=14)\n", "\n", "it[0].model_df()" ] }, { "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": false }, "source": [ "As we can see, the event occurred right after `t=10`, so by `t=11` the value of `prob_tv_spread` was already set to `1.0`.\n", "\n", "You may notice nothing happened between `t=0` and `t=1`.\n", "That is because there aren't any other agents in the simulation, and our event generator explicitly waited until `t=10`." ] }, { "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": false }, "source": [ "### Network agents" ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2017-07-03T14:03:07.171127Z", "start_time": "2017-07-03T16:03:07.165779+02:00" }, "hideCode": false, "hidePrompt": false }, "source": [ "In our disinformation scenario, we will model our agents as a FSM with two states: ``neutral`` (default) and ``infected``.\n", "\n", "Here's the code:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "ExecuteTime": { "end_time": "2017-11-03T10:58:16.051690Z", "start_time": "2017-11-03T11:58:16.006044+01:00" }, "hideCode": false, "hidePrompt": false }, "outputs": [], "source": [ "class NewsSpread(Agent):\n", " has_tv = False\n", " infected_by_friends = False\n", " \n", " @state(default=True)\n", " def neutral(self):\n", " if self.infected_by_friends:\n", " return self.infected\n", " if self.has_tv:\n", " if self.prob(self.model.prob_tv_spread):\n", " return self.infected\n", " \n", " @state\n", " def infected(self):\n", " for neighbor in self.iter_neighbors(state_id=self.neutral.id):\n", " if self.prob(self.model.prob_neighbor_spread):\n", " neighbor.infected_by_friends = True" ] }, { "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": false }, "source": [ "We can check that our states are well defined:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "hideCode": false, "hidePrompt": false }, "outputs": [ { "data": { "text/plain": [ "['dead', 'neutral', 'infected']" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "NewsSpread.states()" ] }, { "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": false }, "source": [ "### Environment (Model)" ] }, { "cell_type": "markdown", "metadata": { "cell_style": "split", "hideCode": false, "hidePrompt": false }, "source": [ "Let's modify our simple simulation.\n", "We will add a network of agents of type NewsSpread.\n", "\n", "Only one agent (0) will have a TV (in blue)." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "cell_style": "split", "hideCode": false, "hidePrompt": false }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def generate_simple():\n", " G = nx.Graph()\n", " G.add_edge(0, 1)\n", " G.add_edge(0, 2)\n", " G.add_edge(2, 3)\n", " G.add_node(4)\n", " return G\n", "\n", "G = generate_simple()\n", "pos = nx.spring_layout(G)\n", "nx.draw_networkx(G, pos, node_color='red')\n", "nx.draw_networkx(G, pos, nodelist=[0], node_color='blue')" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "hideCode": false, "hidePrompt": false }, "outputs": [], "source": [ "class NewsEnvNetwork(Environment):\n", " \n", " prob_tv_spread = 0\n", " prob_neighbor_spread = 0.1\n", " event_time = 10\n", " tv_factor = 0.5\n", " neighbor_factor = 0.9\n", "\n", " \n", " def init(self):\n", " self.add_agent(EventGenerator)\n", " self.G = generate_simple()\n", " self.populate_network(NewsSpread)\n", " self.agent(node_id=0).has_tv = True\n", " self.add_model_reporter('prob_tv_spread')\n", " self.add_model_reporter('prob_neighbor_spread')" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "hideCode": false, "hidePrompt": false }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "d848b48f031e4c798d7ea246d4c17260", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, description='NewsEnvNetwork', max=1, style=ProgressStyle(description_width…" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, max=1), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\n" ] }, { "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", " \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", " \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", " \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", " \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", " \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", " \n", " \n", " \n", " \n", " \n", " \n", "
stepagent_countprob_tv_spreadprob_neighbor_spread
time
0060.00.100000
1160.00.100000
2260.00.100000
3360.00.100000
4460.00.100000
5560.00.100000
6660.00.100000
7760.00.100000
8860.00.100000
9960.00.100000
101060.00.100000
111160.50.200000
121260.00.180000
131360.00.162000
141460.00.145800
151560.00.131220
161660.00.118098
171760.00.106288
181860.00.095659
191960.00.086093
202060.00.077484
\n", "
" ], "text/plain": [ " step agent_count prob_tv_spread prob_neighbor_spread\n", "time \n", "0 0 6 0.0 0.100000\n", "1 1 6 0.0 0.100000\n", "2 2 6 0.0 0.100000\n", "3 3 6 0.0 0.100000\n", "4 4 6 0.0 0.100000\n", "5 5 6 0.0 0.100000\n", "6 6 6 0.0 0.100000\n", "7 7 6 0.0 0.100000\n", "8 8 6 0.0 0.100000\n", "9 9 6 0.0 0.100000\n", "10 10 6 0.0 0.100000\n", "11 11 6 0.5 0.200000\n", "12 12 6 0.0 0.180000\n", "13 13 6 0.0 0.162000\n", "14 14 6 0.0 0.145800\n", "15 15 6 0.0 0.131220\n", "16 16 6 0.0 0.118098\n", "17 17 6 0.0 0.106288\n", "18 18 6 0.0 0.095659\n", "19 19 6 0.0 0.086093\n", "20 20 6 0.0 0.077484" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "it = NewsEnvNetwork.run(max_time=20)\n", "it[0].model_df()" ] }, { "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": false }, "source": [ "In this case, notice that the inclusion of other agents (which run every step) means that the simulation did not skip to `t=10`.\n", "\n", "Now, let's look at the state of our agents in every step:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "hideCode": false, "hidePrompt": false }, "outputs": [ { "data": { "image/png": "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IxX0KLp168b48ePp3r07xcXFXHnllbss79ChA3fddRfHHHMMffv2ZcCAAZx2mnetVV5eHnPmzKFXr168/fbb3HrrrdF2AcDo0aMZO3Ys/fr1Y9u2bWRmZjJixAhee+01RowYEfNz69atY+jQofTr14/zzz+fP/3pT+FlOTk59O/fn7FjxzJx4sSon3/wwQcpKiqiT58+9OjRg0cffRSA3/zmN/z2t7+lf//+u8yGufLKK9m6dSvdu3fn1ltvZcCAJj2Jqd5KQj1z57yiLhI0cy41PYnCwkJXfS7z8uXL6d69e0ra41u9ejUjRowIn0xsTIYOHRo+ydrcpeK7dObD7zN/TQkAb91wNAf/JP5rEkTiZWbznHNR/5Grhy6SIMVllbTJzQo91zi6BE8nRavp0qVLwnvnV199Ne+///4u740bN46LL7641s8OGjSIH3/8cZf3nnzySXr37r3buu+++26D2ikNs7G0goN/sifzvizW1EVJCRX0AIwfP77en/3oo48S2BJJlqrtO9hcXsmB7fKY92VxeDxdJEgachFJgE3bKnEODtzbGzffWKqTohI8FXSRBPDHzPdtk8MeLTI0hi4poYIukgD+VaIFednk52YroEtSQgVdJAH8k6D5udnk52Wrhy4poYKeYHXJQ6+rr7/+mrPPPrvebRg9enT4KtamIpnHuy78HnlBXjYFeVma5SIpoYJeD4nKQ6+rfffdN2UFORk56k0pm93Pb8nPDQ25KKBLUiB9py2+dhN8uzix29ynN5x0V42rBJWHDt6VnYMGDeKdd96hpKSEiRMnctRRR7F9+3Zuuukm3n33XX788Ueuvvpqrrjiil2uYi0rK2P06NEsWbKEbt268fXXXzN+/PjwVaI333wzM2bMoGXLlrz88su0b98e8JIW77rrLjZv3sy9997LiBEjKC8v58orr6SoqIgWLVpw7733cswxxzB58mReeOEFtm7dyvbt23nvvfd2+zt88803jBw5ks2bN1NVVcUjjzzCUUcdxZ577slll12223HwIwtmz57NOeecw9ChQ7nhhhvYunUr7dq1Y/LkyXTo0IEJEybw2GOPUVFRwcEHH8yTTz5Jbm4uX3zxBeeeey5bt24Nxy2kg5KySnKyMmiZnRkq6OqhS/DUQ49ixYoVXHXVVSxfvpy99tprtzz0IUOGcOONN/L222+zYMEC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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "analysis.plot(it[0])" ] }, { "cell_type": "markdown", "metadata": { "deletable": false, "editable": false, "hideCode": false, "hidePrompt": false, "run_control": { "frozen": true } }, "source": [ "## Running in more scenarios\n", "\n", "In real life, you probably want to run several simulations, varying some of the parameters so that you can compare and answer your research questions.\n", "\n", "For instance:\n", " \n", "* Does the outcome depend on the structure of our network? We will use different generation algorithms to compare them (Barabasi-Albert and Erdos-Renyi)\n", "* How does neighbor spreading probability affect my simulation? We will try probability values in the range of [0, 0.4], in intervals of 0.1." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "hideCode": false, "hidePrompt": false }, "outputs": [], "source": [ "class NewsEnvComplete(Environment):\n", " prob_tv = 0.05\n", " prob_tv_spread = 0\n", " prob_neighbor_spread = 0\n", " event_time = 10\n", " tv_factor = 0\n", " neighbor_factor = 0.5\n", " generator = \"erdos_renyi_graph\"\n", " n = 100\n", "\n", " def init(self):\n", " self.add_agent(EventGenerator)\n", " if not self.G:\n", " opts = {\"n\": self.n}\n", " if self.generator == \"erdos_renyi_graph\":\n", " opts[\"p\"] = 0.5\n", " elif self.generator == \"barabasi_albert_graph\":\n", " opts[\"m\"] = 4\n", " self.create_network(generator=self.generator, **opts)\n", "\n", " self.populate_network([NewsSpread,\n", " NewsSpread.w(has_tv=True)],\n", " [1-self.prob_tv, self.prob_tv])\n", " self.add_model_reporter('prob_tv_spread')\n", " self.add_model_reporter('prob_neighbor_spread')\n", " self.add_agent_reporter('state_id')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This time, we set `dump=True` because we want to store our results to a database, so that we can later analyze them.\n", "\n", "But since we do not care about existing results in the database, we will also set`overwrite=True`." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "hideCode": false, "hidePrompt": false }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "[INFO ][19:22:00] Output directory: /mnt/data/home/j/git/lab.gsi/soil/soil/docs/tutorial/soil_output\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "6e72f871a2d242129f0b848caf6b5bdf", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, description='newspread', max=10, style=ProgressStyle(description_width='in…" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\r", "n = 100\n", "\r", "generator = erdos_renyi_graph\n", "\r", "prob_neighbor_spread = 0\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, max=5), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\r", "n = 100\n", "\r", "generator = erdos_renyi_graph\n", "\r", "prob_neighbor_spread = 0.25\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, max=5), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\r", "n = 100\n", "\r", "generator = erdos_renyi_graph\n", "\r", "prob_neighbor_spread = 0.5\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, max=5), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\r", "n = 100\n", "\r", "generator = erdos_renyi_graph\n", "\r", "prob_neighbor_spread = 0.75\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, max=5), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\r", "n = 100\n", "\r", "generator = erdos_renyi_graph\n", "\r", "prob_neighbor_spread = 1.0\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, max=5), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\r", "n = 100\n", "\r", "generator = barabasi_albert_graph\n", "\r", "prob_neighbor_spread = 0\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, max=5), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\r", "n = 100\n", "\r", "generator = barabasi_albert_graph\n", "\r", "prob_neighbor_spread = 0.25\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, max=5), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\r", "n = 100\n", "\r", "generator = barabasi_albert_graph\n", "\r", "prob_neighbor_spread = 0.5\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, max=5), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\r", "n = 100\n", "\r", "generator = barabasi_albert_graph\n", "\r", "prob_neighbor_spread = 0.75\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, max=5), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\r", "n = 100\n", "\r", "generator = barabasi_albert_graph\n", "\r", "prob_neighbor_spread = 1.0\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, max=5), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "N = 100\n", "probabilities = [0, 0.25, 0.5, 0.75, 1.0]\n", "generators = [\"erdos_renyi_graph\", \"barabasi_albert_graph\"]\n", "\n", "\n", "it = NewsEnvComplete.run(name=f\"newspread\",\n", " iterations=5, max_time=30, dump=True, overwrite=True,\n", " matrix=dict(n=[N], generator=generators, prob_neighbor_spread=probabilities))" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "hideCode": false, "hidePrompt": false }, "outputs": [], "source": [ "DEFAULT_ITERATIONS = 5\n", "assert len(it) == len(probabilities) * len(generators) * DEFAULT_ITERATIONS" ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2017-07-03T11:05:18.043194Z", "start_time": "2017-07-03T13:05:18.034699+02:00" }, "cell_style": "center", "hideCode": false, "hidePrompt": false }, "source": [ "The results are conveniently stored in sqlite (history of agent and environment state) and the configuration is saved in a YAML file.\n", "\n", "You can also export the results to GEXF format (dynamic network) and CSV using .`run(dump=['gexf', 'csv'])` or the command line flags `--graph --csv`." ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "ExecuteTime": { "end_time": "2017-11-01T14:05:56.404540Z", "start_time": "2017-11-01T15:05:56.122876+01:00" }, "cell_style": "split", "hideCode": false, "hidePrompt": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[01;34msoil_output\u001b[00m\n", "└── \u001b[01;34mnewspread\u001b[00m\n", " ├── newspread_1681989837.124865.dumped.yml\n", " ├── newspread_1681990513.1584163.dumped.yml\n", " ├── newspread_1681990524.5204282.dumped.yml\n", " ├── newspread_1681990796.858183.dumped.yml\n", " ├── newspread_1682002299.544348.dumped.yml\n", " ├── newspread_1682003721.597205.dumped.yml\n", " ├── newspread_1682003784.1948986.dumped.yml\n", " ├── newspread_1682003812.4626257.dumped.yml\n", " ├── newspread_1682004020.182087.dumped.yml\n", " ├── newspread_1682004044.6837814.dumped.yml\n", " ├── newspread_1682004398.267355.dumped.yml\n", " ├── newspread_1682004564.1052232.dumped.yml\n", " ├── newspread_1682351953.9104202.dumped.yml\n", " ├── newspread_1682352039.0612123.dumped.yml\n", " ├── newspread_1682352713.2328467.dumped.yml\n", " ├── newspread_1682354145.0394537.dumped.yml\n", " ├── newspread_1682354210.681379.dumped.yml\n", " ├── newspread_1682354306.4574156.dumped.yml\n", " ├── newspread_1682354380.1758456.dumped.yml\n", " ├── newspread_1682354406.758729.dumped.yml\n", " ├── newspread_1682354533.7559075.dumped.yml\n", " ├── newspread_1682356920.2487948.dumped.yml\n", " └── newspread.sqlite\n", "\n", "1 directory, 23 files\n", "21M\tsoil_output/newspread\n" ] } ], "source": [ "!tree soil_output\n", "!du -xh soil_output/*" ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2017-07-02T10:40:14.384177Z", "start_time": "2017-07-02T12:40:14.381885+02:00" }, "hideCode": false, "hidePrompt": false }, "source": [ "### Analysing the results" ] }, { "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": false }, "source": [ "#### Loading data" ] }, { "cell_type": "markdown", "metadata": { "hideCode": false, "hidePrompt": false }, "source": [ "Once the simulations are over, we can use soil to analyse the results.\n", "\n", "There are two main ways: directly using the iterations returned by the `run` method, or loading up data from the results database.\n", "This is particularly useful to store data between sessions, and to accumulate results over multiple runs.\n", "\n", "The mainThe main method to load data from the database is `read_sql`, which can be used in two ways:\n", "\n", "* `analysis.read_sql()` to load all the results from a sqlite database . e.g. `read_sql('my_simulation/file.db.sqlite')`\n", "* `analysis.read_sql(name=)` will look for the default path for a simulation named ``" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The result in both cases is a named tuple with four dataframes:\n", "\n", "* `configuration`, which contains configuration parameters per simulation\n", "* `parameters`, which shows the parameters used **in every iteration** of every simulation\n", "* `env`, with the data collected from the model in each iteration (as specified in `model_reporters`)\n", "* `agents`, like `env`, but for `agent_reporters`" ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2017-07-03T14:44:30.978223Z", "start_time": "2017-07-03T16:44:30.971952+02:00" }, "hideCode": false, "hidePrompt": false }, "source": [ "Let's see it in action by loading the stored results into a pandas dataframe:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "ExecuteTime": { "end_time": "2017-10-19T15:57:44.101253Z", "start_time": "2017-10-19T17:57:44.039710+02:00" }, "hideCode": false, "hidePrompt": false }, "outputs": [], "source": [ "res = analysis.read_sql(name=\"newspread\", include_agents=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Plotting data\n", "\n", "Once we have loaded the results from the file, we can use them just like any other dataframe.\n", "\n", "Here is an example of plotting the ratio of infected users in each of our simulations:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "image/png": "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z+HDh3nooYc4dOgQ7dq1s2uWzJw5kx07drB//35KS0tZt26d/RiDwcDOnTt57LHHuPzyy/n999/ZvXs3kyZN4qWXXrL77d27l40bN7J161YWLFjA2bNn8fDwYM2aNezatYtNmzbx2GOPIaXk22+/pWPHjiQnJ7N//36uu+66esX//PPPs3PnTvbu3ctPP/3E3r17a/gUFxczaNAgDhw4wFVXXWVP+vfffz+LFi0iKSmJV155hYceOr+EQ2pqKr/99htffPEFDz74ILNnz2bPnj1VkjlcmG76tGnTiIuL45///CdNLbWiKnRFk5G1+ygaocGzowflZUZ0uvPjzvdlfo/FXMIYHmnBCC8SnFXUbl7O7d5B9arIq9O5c2dGjBgBwF133cXrr7/O448/zqZNm3jppZcoKSkhJyeHqKgobrrpJsCqh15BamoqEydOJC0tDYPBQEREhN02btw4PD098fT0ZNSoUWzfvp2xY8fy9NNP8/PPP6PRaDhz5gzp6elER0fz2GOP8eSTT3LjjTfWSJy18emnn/LOO+9gMplIS0vj4MGDxMTEVPHRaDT2mO+66y5uvfVWioqK+O2337j99vO/esrLzz+cv/322xslH1ydFStW0KlTJwoLC7ntttv46KOPuOeee+o+sIGoCl3RZBQcPgeAf4B1VRl9h452WxC5WIRr15JU1B9RbWFXIQRlZWU89NBDrF69mn379nHfffdRVlZm96msXz5r1ixmzpzJvn37ePvtt6v4OWp7xYoVZGZmkpSUxJ49e2jfvj1lZWX07t2bXbt2ER0dzTPPPMOCBQvqjP3EiRO88sor/Pjjj+zdu5exY8dWOb+za7ZYLPj7+7Nnzx7736FDhxxeozPqq5tesc/X15c77riD7du316v9hqISuqLJMJ8ro9RShHux9aeorlNXu61D4HBuiPgbOSdOtVR4lzSnTp1i61brxK6PP/6Yyy+/3J4Ug4ODKSoqYvXq1bUen5+fb09WH3zwQRXb2rVrKSsrIzs7m82bNzN48GDy8/MJDQ1Fr9ezadMmu/762bNn8fLy4q677mLOnDm1jhapTEFBAd7e3vj5+ZGens769esd+lksFvs1VFxju3btiIiIsGu7SylJTk52eLyvry+FhYUObfXRTTeZTGRlZQFgNBpZt25dk40uqkAldEWTcSIvmYx2ZzGdSQFA16WX3WZy88dD682pX+v+B6xwPX369GHx4sX07duX3NxcZsyYgb+/P/fddx/9+/dnzJgx9iXqHDFv3jxuv/12Bg4cSHBwcBVbTEwMo0aNYujQocydO5eOHTty5513snPnTqKjo/nwww+JjIwEYN++fQwZMoS4uDjmz5/PM888U2fssbGxDBgwgMjISO644w5711F1vL292b59O/3792fjxo08++yzgLUb5L333iM2NpaoqCjWrl3r8PibbrqJNWvWEBcXxy+//FLF5kw3PS4uDrB25YwZM4aYmBji4uLo1KkT9913X53X1xiUHrqiSSgrKmLxXydx+aR76Ll7Axmf/kbvLRvRBlmrmM1Pv0FPSyzHPfdz5XMzWjja5kXpoSvqi9JDV1wUpO87QoBbezpE9MLk2RPh6YkmsIPd7tXJusKMKVfNFlUoXIUa5aJoEop2nePaTlMJ7BRBTkYG+vbtqzws6zAkBk7nIU0eLRil4mInPj6+yigUgI8++ojo6OgWiujiRiV0RZMg08sptkjCQ/zJOLoLnad7FXtYXCTbP1hKvkGNRVfUTm2zLxWOUQld0SS4l3lQ5m0dNWFKz8Cze9UHZ3q9nl1pX+GhcWuJ8BSKNolK6AqXU3gmE0+ND8YOIC0WTMUSXXBgDT9vcylY6h4/rFAo6odK6AqXk7X7GHqgXe8OWNJPIS0CfWj7Gn79wm7B3zO8+QNUKNooapSLwuWcKzrB5nOrCBnYC2PKHwDowmrOojNqdHjofDEaDM0dokLRJlEJXeFyzp08ginIgns7H0xnrdOjdZ261fAzUY5Ooyd9/+FmjlDREJYtW8bMmTNbOow6cSR3C/Dtt9/Sp08fevbsyYsvvujQ5z//+Q/9+vUjJiaGhIQE+4xWAK1Wa9c1v/nmm5sk9saiErrCpVgsFrzPeNGts1UoyUQQALqY0TV99Vb1xbPb9jdfgIp6Yzab63ZyASaTazV9HC1KYTabefjhh1m/fj0HDx7kk08+cbiAxoABA+wqjuPHj+eJJ56w2zw9Pe36L4mJiS6N2VWoPnSFSylIOUc/r6EU+pYCYMq0rtCiCw2t4asJCoBiKEy/dLtc/r393/yR84dL24wMjOTJIU869Vm+fDmvv/46BoOB+Ph43nzzTbRaLT4+PjzwwAP88MMPLF68mKNHj/LCCy/g7+9PbGws7u7W4acpKSnce++9ZGVlERISwtKlS+nSpQufffYZ8+fPR6vV4ufnx88//+zw/MuWLeOLL76gqKgIs9nMN998w6xZs9i/fz9Go5F58+Yxbtw4li1bRmJiIiUlJRw7doxbbrmFl156iffff5+9e/fy3//+F4AlS5Zw8OBBXn31VXx8fCgqKqpyvu3bt9OzZ0+6d+8OwKRJk1i7di39+vWr4jdq1Cj766FDh7J8+fILeu9bGlWhK1xKdvIJAPwircqKxuQf0Xrp0bi71/D16duNw/k7yC3Ia84QL3kOHTrEqlWr2LJlC3v27EGr1bJixQrAqiEeHx9PcnIyPXr04LnnnmPLli38+uuvVSraWbNmMWXKFPbu3cudd97JI49YZZAXLFjAhg0bSE5OrrOK3bVrF6tXr+ann37i+eefZ/To0Wzfvp1NmzYxZ84ciouLAdizZw+rVq1i3759rFq1itOnTzNhwgS++uorjEarkufSpUu59957az3XheiXV/Dee+9x/fXX27fLysoYNGgQQ4cO5csvv3R6bEtRrwpdCHEd8BqgBd6VUr5Yzd4F+ADwt/k8JaX8xrWhKloDpSey0ct2tI+zrk5kXdjC4tC3+/C+LPvsFTr41qzeLxXqqqSbgh9//JGkpCS7+FZpaSmhtl9QWq2W2267DbBO6hk5ciQhISGAVQ/9yJEjAGzdupUvvvgCgLvvvtveNTFixAimTp3KhAkTuPXWW53Gcc011xAYaB3O+t1335GYmGhfj7SsrIxTp6xKnAkJCfj5+QHQr18/Tp48SefOnRk9ejTr1q2jb9++GI1Gl84eXb58OTt37uSnn36y7zt58iSdOnXi+PHjjB49mujoaHr06OGyc7qCOhO6EEILLAauAVKBHUKIRCll5Q6oZ4BPpZT/E0L0A74BujVBvIqLnWwzxaIAvbd1Sr8prwSdn+Pp/UEd2+NmEXgUZTdnhJc8UkqmTJnCCy+8UMPm4eHRqAUe3nrrLbZt28bXX3/NwIEDSUpKIigoyKFvZe1xKSWff/45ffr0qeKzbds2ezcPWL9wKvrcp0+fzr/+9S8iIyOZNm2a07jqq18O8MMPP/D888/z008/VTl3hX/37t0ZOXIku3fvvugSen26XIYAf0opj0spDcBKYFw1Hwm0s732A866LkRFa8FiseBu8MDke74iNxUZ0QW0q/WYhPB76Rryl2aITlFBQkICq1evtq9An5OTU2U0RwXx8fH89NNPZGdnYzQa7RriYB1JsnLlSsAqR1ux0tCxY8eIj49nwYIFhISEVEmizhgzZgyLFi2yL9G2e/fuOo+Jj4/n9OnTfPzxx0yePNmp7+DBgzl69CgnTpzAYDCwcuVKhyNVdu/ezQMPPEBiYqL9VwtAbm6uXVMmKyuLLVu21Oh/vxioT5dLJ6DyXUkF4qv5zAO+E0LMAryBqx01JIS4H7gfoEuXLhcaq+IiJz/jHF+depNrEqxD26TRgKlEogupOUu0gjJLOXqtb3OFqMDabbFw4UKuvfZaLBYLer2exYsX07Vr1yp+YWFhzJs3j2HDhuHv72/X+QZYtGgR06ZN4+WXX7Y/FAWYM2cOR48eRUpJQkICsbGx9Ypp7ty5PProo8TExGCxWIiIiKiynmltTJgwgT179hAQEODUT6fT8cYbbzBmzBjMZjP33nsvUVFRADz77LMMGjSIm2++mTlz5lBUVGRfoq5Lly4kJiZy6NAhHnjgATQaDRaLhaeeeuqiTOhIKZ3+AeOx9ptXbN8NvFHN5+/AY7bXw4CDgMZZuwMHDpSKtsWhXzfLVyaMleknjkkppTScPCIP9omUOf+eXesxvz38vvzjsa+bK8SLgoMHD7Z0CG2GsWPHyh9++KGlw2gyHH1WgJ2ylrxany6XM0DnStvhtn2V+Svwqe0LYivgAQSjuKQo3ZHJgOAEgsKtv75MBdbhiLqBY2s9xmgpw1PrhaGktFliVLQN8vLy6N27N56eniQkJLR0OBcN9ely2QH0EkJEYE3kk4A7qvmcAhKAZUKIvlgTeqYrA1Vc/Lil6+jg2x2tzvqxMmWkA47HoFdg0Ak0QkvKziP0vrJ+P88VrYcNGzbw5JNVR/JERESwZs2aRrXr7+9vH3GjOE+dCV1KaRJCzAQ2YB2S+L6U8oAQYgHW0j8ReAxYIoSYjfUB6VTbTwPFJYLZZMLb7Eth4PkJHabd3wKga1f7IhbF3rAnayNeh2NVQm+DjBkzhjFjxrR0GJcM9RqHLq1jyr+ptu/ZSq8PAo5XalVcEmTvP4FO44ZHl/MjWkypKSAkug6daz3Or5cnScd3EJWlAf7S5HEqFG0ZNVNU4RLyDqQC4N///OglY1Y2Ok8Q7rVX6J26tcdb5w+pNYfNKRSKC0NpuShcQkFGOiajJ5H9zivdmXLy0fnonR7XMXYIN3b25kTBrqYOUaFo87S6hG4sK6MsrwjM1broBWi8rJdjKTVB9dnmGtB41tNeYrI+CaiMVqDx0NZqF1qBqLAX11SPEzqBcNdahxeV1FSxq9OuFwg3LdIikaWO7BqEm6Z2u5sGodcgzRJZ5sDurkHoNEizBVlWc6q+3W6yIMtr2g+nb0fXzo1+uvNzzkz5ZeiDvGv4VsY7KJA0cwka4dxPoVDUTatL6Hu++xr5QyEdvapOuS0wZLP+zLsAjAq7g1CPqv22OeVpfH/2QwCu7TiVAPeqK+ikl55k8znrzLcbwu/DV191MsyZ4qP8mmHVrri588N46nyq2E8WHeD3TOtEiNu6zkZXba3MPwt2k5T9HQATI2rqd/yRt43k3M3ohRu3dptdw74v9xcO5v2Gp9aHm7s8XMO+O/tHjhTsxFcfyA3h99Ww78j6luOFyQS6deCaTlNq2H/LSOR08SFCPbowKqzmrLufz31GWulxOnr15Ir2t9Wwm9NKCL+mf5V9phKBZ1THGr7VKTWV4K71rNNP0bIsW7aMnTt38sYbb7R0KE4ZPny4Qwndb7/9lr/97W+YzWamT5/OU089VcNn2bJlzJkzxz7Nf+bMmUyfPr3JY3YVoqUGowwaNEju3Lnzgo/LSDlO5m9H0ZZV7f636CSGDtbK2C1Th6ZcVLW7SQyhNnuGDo2hmt3dgiHEWrm6n9MhTFXtZk8LxiCbPU2HMFeze1kwBtrsZ/SIam+ryduCKcAMEjzO1OyGMPmaMflZwAIeZx3Y25kxtbOACTzO1bQb/cyYfS0II7inO7AHmDF7WxAGgXtGze9xQ6AJi5dEUyZwy3JgDzJh8ZRoSgVu2Q7soWZ6XjkMr3ZWESWLwcDhmFiCH5lFyEMP1fCvzM5HPsZd60H0q87FnNoKhw4dom/fvi0dRp2YzeYqui5NldBNJhM6XdPWlmazmd69e/P9998THh7O4MGD+eSTT2rM9rzYvrQcfVaEEElSykGO/FtdhR7arTuh3bq3dBiKOjBlWKch6NvXXEu0OmWWcvzca5cHaMuc+9e/KD/kWj10976RdHj6aac+Sg/dsR56a0eNclE0CaYDVtlRncit0zfVcJZdWd9TXFBUp6+i8Sg9dOd66J9//jkxMTGMHz++3uJiFwutrkJXtA5Mp/8EQNc+rE5fnVc6J9OOcyZ5J72vGNnEkV1c1FVJNwVKD712brrpJiZPnoy7uztvv/02U6ZMYePGjY1ut7lQCV3RJJjOWqsfXbe6+4oD27lTktuZ3D274RJL6C2BVHroteqhV451+vTpVdYUbQ2oLhdFk2DKSEdoJNqwbnX6+gT1Y3TYHZSeVGoRzYHSQ69dDz0tLc3+OjExsVU8vK6MqtAVTYIxKxedt0Bo6q4Z/KN6QZpElja8MlTUH6WHXrse+uuvv05iYiI6nY7AwECWLVtWr/gvFlrdsEVF6+DkX65GlpfRbf2vdfoaSko5N38bKYWHuPLNGc0QXcvSWoYttgZuvPFGZs+e3WYldC902KLqclE0CaZyN3R9BtfL183Lk1JzCXpN7ZovCkVllB66Y1SXi6JJMGVk4H3F5fX2LzOX4KZmi7Y5lB5686ISusLlmHPOYSkuRl+eUu9j9ufsxGgpZCCTmi4wRbOj9NCbF5XQFS7HlHIIAJ1t/HJ9MBsOk28sa6qQFIpLAtWHrnA5plO2SUXh3ep9TJCnD53aRZNrm0yiUCguHJXQFS7HlJoCgK5Lz3of4+0by9DQmzi5OamJolIo2j4qoStcjimt/rNE7XhbR7gUHD/XFCEpFJcEKqErXI7R6InGXYc2sEO9j/HqbJ1ybcpT/ehNTUpKCv3796/bsQHMmzfPrsfSGKZPn15FDKy+jBw5kor5LT4+PnV4O2fz5s0OddUB/vjjD4YNG4a7u7vT6z1x4gTx8fH07NmTiRMnYjAYGhVTXaiHogqXYzJ4oOtY+8LQjggb1A9OFoDx0pstuub/ai6/13NgKNEjwzEazKxblFzDHjksjL7DwygtMvDt2/ur2G557LImixWaR7/83XffbdL268JkMrF582Z8fHwYPnx4DXtgYCCvv/46X375pdN2nnzySWbPns2kSZN48MEHee+995gxo+kmz6kKXeFyTOfOogut/wgXgA6xfTFZjGopumbCZDJx55130rdvX8aPH09JSQlglb8dPHgw/fv35/7777drq4wcOZJHH32UQYMG8dprr/HVV18RHx/PgAEDuPrqq0lPT7e3nZyczLBhw+jVqxdLliwBoKioiISEBC677DKio6NZu3YtYJXrHTt2LLGxsfTv359Vq1bZz+dsJvmMGTMYNGgQUVFRPPfcc7X6zZ49m6ioKBISEsjMtGr0Hzt2jOuuu46BAwdyxRVX8McfVj36qVOn8uCDDxIfH8+ECRN46623ePXVV4mLi+OXX36p0m5oaCiDBw9Gr699zVwpJRs3bmT8+PEATJkypc4vgEYjpWyRv4EDB0pF2+TooEiZOuGKCz5u6V0PyXcmP9gEEV1cHDx4sEXPf+LECQnIX3/9VUop5bRp0+TLL78spZQyOzvb7nfXXXfJxMREKaWUV111lZwxY4bdlpOTIy0Wi5RSyiVLlsi///3vUkopn3vuORkTEyNLSkpkZmamDA8Pl2fOnJFGo1Hm5+dLKaXMzMyUPXr0kBaLRa5evVpOnz7d3m5eXp79fDt27Kj1GiriNJlM8qqrrpLJyck1jgPk8uXLpZRSzp8/Xz788MNSSilHjx4tjxw5IqWU8vfff5ejRo2SUko5ZcoUOXbsWGkymezXUvG+1IYzn4rrrODUqVMyKirKaXvVcfRZAXbKWvKqqtAVLkVaLJiKJfpg52JJjjAW/YkoPd4EUSmq07lzZ0aMGAHAXXfdxa+/WjV3Nm3aRHx8PNHR0WzcuJEDBw7Yj5k4caL9dWpqKmPGjCE6OpqXX365it+4cePw9PQkODiYUaNGsX37dqSUPP3008TExHD11Vdz5swZ0tPTiY6O5vvvv+fJJ5/kl19+seue18Wnn37KZZddxoABAzhw4IDD/naNRmOPueIai4qK+O2337j99tuJi4vjgQceqKKwePvttzdKPrilUX3oCpdiPncSaRHo2tf/gWgFYV6d0LjVvWSdovEIIWpsl5WV8dBDD7Fz5046d+7MvHnzKCs7/5C6sn75rFmz+Pvf/87NN9/M5s2bmTdvntO2V6xYQWZmJklJSej1erp160ZZWRm9e/dm165dfPPNNzzzzDMkJCTw7LPPOo39xIkTvPLKK+zYsYOAgACmTp1aJU5n12yxWPD392fPnj0OfSpfY2MJCgoiLy/P/syhNg12V6IqdIVLMZ2wVkq6sAv/4Pr7DaJfyDUYm3gkgAJOnTrF1q1bAfj444+5/PLL7UkxODiYoqIiVq9eXevx+fn59uT0wQcfVLGtXbuWsrIysrOz2bx5M4MHDyY/P5/Q0FD0ej2bNm2y66+fPXsWLy8v7rrrLubMmcOuXTUfEFenoKAAb29v/Pz8SE9PZ/369Q79LBaL/RoqrrFdu3ZERETYtd2llCQn13zoDODr60thYWGd8dSGEIJRo0bZY/jggw8YN25cg9urDyqhK1yK6fQxAHThF76Qt1GY0Gn0nEs+5OqwFNXo06cPixcvpm/fvuTm5jJjxgz8/f2577776N+/P2PGjLEvUeeIefPmcfvttzNw4ECCg4Or2GJiYhg1ahRDhw5l7ty5dOzYkTvvvJOdO3cSHR3Nhx9+SGRkJAD79u1jyJAhxMXFMX/+fJ555pk6Y4+NjWXAgAFERkZyxx132LuOquPt7c327dvp378/GzdutFf+K1as4L333iM2NpaoqCj7A9rq3HTTTaxZs8bhQ9Fz584RHh7Of/7zHxYuXEh4eDgFBQUA3HDDDZw9exaAf//73/znP/+hZ8+eZGdn89e//rXO62sMSg9d4VLyPvgfaS+8To+vPsWt14Wt8bjx0Vfp7TGIs51PM+ThO5oowpZH6aEr6ovSQ1e0KCbr6Dd0Xfs4d3SA1t86W7T4XL4rQ1IoLhnUQ1GFSzGeOobW3w+Nm9sFH+vTLwp2gaG49rG9ikuL+Ph4ysvLq+z76KOPiI6+sF9/lwr1SuhCiOuA1wAt8K6U8kUHPhOAeYAEkqWUbfc3s6JWTAd/QacrbtCxXYdH8umXf8Pdu6OLo1K0VrZt29bSIbQq6kzoQggtsBi4BkgFdgghEqWUByv59AL+AYyQUuYKIUKbKmDFxY0prwSdX8OWkgsOD8VoyMPfXODiqBSKS4P6VOhDgD+llMcBhBArgXFA5ZH89wGLpZS5AFLKDFcHqmgdmAqNuHe+sGn/lenlE4MbLfOgXqFo7dQnoXcCTlfaTgXiq/n0BhBCbMHaLTNPSvlt9YaEEPcD9wN06dKlIfEqLmKkoRxTKehDghrcRge/OLQa1YeuUDQEV41y0QG9gJHAZGCJEMK/upOU8h0p5SAp5aCQC1ieTNE6MJ0+ArJhs0QrKDeX4an1cmFUCsWlQ30S+hmgshZquG1fZVKBRCmlUUp5AjiCNcErLiFMedYxi7rIoQ1uw2ApxUPrjaGk1FVhKVzEsmXLmDlzZkuHUSeO5G4Bvv32W/r06UPPnj158cUa4zoAqzpjXFwccXFx9O7dG39/f7tNq9XabTfffHNThN5o6tPlsgPoJYSIwJrIJwHVR7B8ibUyXyqECMbaBaNUli4xTHlFAOh6xjW4DbPGhEZoSNmaTO+Ehn8xtBY2LXuHjJOu/acS2rU7o6be3+h2zGZzswhVuVpf3dGiFGazmYcffpjvv/+e8PBwBg8ezM0330y/fv2q+L366qv214sWLWL37t32bU9Pz1o1YC4W6qzQpZQmYCawATgEfCqlPCCEWCCEqPia2gBkCyEOApuAOVLK7KYKWnFxYjphnbKva0QfurFdOyzSwrkj6rl6U7J8+XL7lPsHHngAs9kMWFf5eeyxx4iNjWXr1q0sXbqU3r17M2TIELZs2WI/PiUlhdGjRxMTE0NCQgKnbIt7f/bZZ/Tv35/Y2FiuvPLKWs+/bNkybr75ZkaPHk1CQgLFxcXce++9DBkyhAEDBtin4y9btoxbb72V6667jl69evHEE08A8P777/Poo4/a21uyZAmzZ8+2X0N1tm/fTs+ePenevTtubm5MmjSp1in/FXzyySdMnjy5Hu/mRURturpN/af00Nse6Y+Olwcj+0iLobzBbWx4a6X8vwk3ys+ff82FkV1ctLQe+sGDB+WNN94oDQaDlFLKGTNmyA8++EBKadUQX7VqlZRSyrNnz8rOnTvLjIwMWV5eLocPH27XFL/xxhvlsmXLpJRSvvfee3LcuHFSSin79+8vU1NTpZRS5ubm1hrD0qVLZadOney65v/4xz/kRx99ZD+uV69esqioSC5dulRGRETIvLw8WVpaKrt06SJPnTolCwsLZffu3e3XMGzYMLl3714ppZTe3t41zvfZZ5/Jv/71r/btDz/80H4tjkhJSZEdOnSwa6NLKaVWq5UDBw6U8fHxcs2aNbUe60ouVA9dzRRVuAxTZjY6TxD6C58lWkG3qPbs2yjRpSqdn6bixx9/JCkpyS6+VVpaSmiodeqIVqvltttuA6yTekaOHEnFAIaJEydy5MgRALZu3coXX3wBwN13322vnEeMGMHUqVOZMGECt956q9M4rrnmGgIDAwH47rvvSExMtK/PWVZWZq/6ExIS7Drp/fr14+TJk3Tu3JnRo0ezbt06+vbti9FodOns0ZUrVzJ+/PgqXU4nT56kU6dOHD9+nNGjRxMdHU2PHj1cdk5XoBK6wmWYcgrQ+TZuyGF4/1guC7waaUyr21nRIKSUTJkyhRdeeKGGzcPDo1H95m+99Rbbtm3j66+/ZuDAgSQlJREU5LgLrrL2uJSSzz//nD59qmoAbdu2DXd3d/u2VqvFZDIB1oWk//WvfxEZGcm0adOcxtWpUydOnz4/+roubfKVK1eyePHiGm0AdO/enZEjR7J79+6LLqErcS6FyzDll6Hzb9yQQy//AMJ9IvFw7+2iqBTVSUhIYPXq1WRkWJ9T5OTk2PXJKxMfH89PP/1EdnY2RqPRriEO1pEkK1euBKxytFdccQVgXa8zPj6eBQsWEBISUiWJOmPMmDEsWrTIvoZp5YeRtREfH8/p06f5+OOP6+zrHjx4MEePHuXEiRMYDAZWrlxZ60iVP/74g9zcXIYNG2bfl5uba9eUycrKYsuWLTUeqF4MqApd4TJMRSY8e/s3up0yUwlumobJByjqpl+/fixcuJBrr70Wi8WCXq9n8eLFdO3atYpfWFgY8+bNY9iwYfj7+xMXF2e3LVq0iGnTpvHyyy8TEhLC0qVLAZgzZw5Hjx5FSklCQgKxsbH1imnu3Lk8+uijxMTEYLFYiIiIYN26dXUeN2HCBPbs2UNAgPMlD3U6HW+88QZjxozBbDZz7733EhUVBcCzzz7LoEGD7Al+5cqVTJo0qcrKS4cOHeKBBx5Ao9FgsVh46qmnLsqErvTQFS7BUl7O4dg4QqZPJvhx50uI1cXOR1bgrvUk+lXnfbCtFaWH7jpuvPFGZs+eTUJCQkuH0iQoPXRFi2DKzARAF9G/0W2VW8rx1LlubUdF2yMvL4/evXvj6enZZpN5Q1BdLgqXYF9L1N+z0W2VYsIsTRTlFuAT0K7R7Slajg0bNvDkk09W2RcREcGaNWsa1a6/v799xI3iPCqhK1yC6Y/fAdB5Nr4L76wuleTTiVx/MJR+I2pf11Jx8TNmzBjGjBnT0mFcMqguF4VLMJ1NBUAf0fgHRR2DjADkJW9qdFsKxaWEqtAVLsGYkY7QSDTtGy+L7N8+gisye1OWkuqCyBSKSwdVoStcgikrF523QGga/5Hy6xFFR6+emIpV/7lCcSGohK5wCabcQnTt3Ot2rAddh12GWZrRyYZLCCgUlyIqoStcgokgdL0HuqQtNy9PyszF6NXkoiYhJSWF/v0bP7zUEfPmzbPrsTSG6dOnc/DgwbodqzFy5Egq5rc4Ul28EDZv3uxQihesUgWPPPIIPXv2JCYmhl27dtXwKSwstOunx8XFERwcbFeIXLZsGSEhIXbbu+++26hYK2h1feiFP/5I/nuvQFl+VYPOAzrYxHkyD0F5UVW7mxeEWmeGkb4fjNUWUHD3hZBI6+tze8FUXtXu6Q9BtjU7zu4Gi6mq3SsQAm26DmeSQFqq2r1DIKAbIMGR8JRPB/DvbG33rINpz+06QrtOYDZAWnJNu19n8O0AplI4t7+mPaCbNQZDEWQcqmkP7A5eQVBeAJmHa9qDe4GHP5TmQvafNczGtEJ8RtU9Hjhx1xwCfHtyRa8HnPqVmUpxv0RWLsp4e2+NfV4xwfgM64jFYCZr6YEadu+B7fEe1B5zsZHs5VXvZ+gDMU0WK7hev9wRrkpwDcVkMrF582Z8fHwcLpixfv16jh49ytGjR9m2bRszZsxg27ZtVXx8fX2r6KcPHDiwimDZxIkTeeONN1wad6tL6Oa8fAxnssBYUtWgLYFS20IBBdlgLKtq15VBsc2enwMmQ1W73gBFNnteLpiNVe1uJiiwiRbl5oHFXNXuboZ821ThnDyoPgPXQ0KeBSSQU+3LCMADyDWCxQK5Duz5GvAqB7MZ8hzYC3TgWQImI+Q7sBeeBY9C6xeVI3vRWXDPt37RFTiwF6eCWw4YSqCwpt2tczjeTvSvAUxmE955X2DIA+pI6PnGfLRCLRbdVJhMJu6880527dpFVFQUH374IV5eXixYsICvvvqK0tJShg8fzttvv40QgpEjRxIXF8evv/7K5MmT6d27NwsXLsRgMBAUFMSKFSto3749AMnJyQwbNoysrCyeeOIJ7rvvPoqKihg3bhy5ubkYjUYWLlzIuHHjKC4uZsKECaSmpmI2m5k7dy4TJ05k5MiRvPLKKwwa5HBCJDNmzGDHjh2UlpYyfvx45s+f79Bv9uzZfPfdd3To0IGVK1cSEhLCsWPHePjhh8nMzMTLy4slS5YQGRnJ1KlT8fDwYPfu3XTq1InffvsNrVbL8uXLWbRokV2vBmDt2rXcc889CCEYOnQoeXl5pKWlERYW5jCOI0eOkJGRUaWNJqE2Xd2m/lN66Jcef+b+KZ/7srf85vvu0mQ2OvV9f8YT8pUJY+WxHTuaKbrmo6X10E+cOCEB+euvv0oppZw2bZp8+eWXpZTSrk8upZR33XWXTExMlFJKedVVV8kZM2bYbTk5OdJisUgppVyyZIn8+9//LqWU8rnnnpMxMTGypKREZmZmyvDwcHnmzBlpNBplfn6+lFLKzMxM2aNHD2mxWOTq1avl9OnT7e3m5eXZz7fDyb2viNNkMsmrrrpKJicn1zgOkMuXL5dSSjl//ny7/vno0aPlkSNHpJRS/v7773LUqFFSSimnTJkix44da9dAf+655+zvS3XGjh0rf/nlF/v26NGjncY7f/58+dhjj9m3ly5dKjt06CCjo6PlbbfdJk+dOuXwuAvVQ1d96IpmY3/Wfk4bNbhp4Gjmr059e0VadbJPJC5vjtAuOTp37syIESMAuOuuu/j1V+v92LRpE/Hx8URHR7Nx40YOHDjf3TNx4kT769TUVMaMGUN0dDQvv/xyFb9x48bh6elJcHAwo0aNYvv27Ugpefrpp4mJieHqq6/mzJkzpKenEx0dzffff8+TTz7JL7/8Ytc9r4tPP/2Uyy67jAEDBnDgwAGH/e0ajcYec8U1FhUV8dtvv3H77bfbV2tKSzsv1Xz77bc3ybJ7K1eurKIIedNNN5GSksLevXu55pprmDJlikvOoxK6otnIS/uIK3yszx6On9vo1LffXyZyTcd7cM8Mb47QLjkqKwlWbJeVlfHQQw+xevVq9u3bx3333UdZ2fmuy8r65bNmzWLmzJns27ePt99+u4qfo7ZXrFhBZmYmSUlJ7Nmzh/bt21NWVkbv3r3ZtWsX0dHRPPPMMyxYsKDO2E+cOMErr7zCjz/+yN69exk7dmyV8zu7ZovFgr+/P3v27LH/HTp0/hlE5Wt0xoXoqycnJ2MymRg48PyggaCgILvO+/Tp00lKSqrXeetCJXRFs+FefgR3nQ9Hy/WcKna+Zmhgl25ohBse+o7NFN2lxalTp9i6dSsAH3/8MZdffrk9KQYHB1NUVMTq1atrPT4/P9+ewD744IMqtrVr11JWVkZ2djabN29m8ODB5OfnExoail6vZ9OmTXb99bNnz+Ll5cVdd93FnDlzHI4WqU5BQQHe3t74+fmRnp7O+vXrHfpZLBb7NVRcY7t27YiIiLBru0spSU52MMgA60PNwsJCh7abb76ZDz/8ECklv//+O35+frX2nztam7Tyr4LExESXqW+2uoeiitZJubEYf1FMjlssW42+WPKKebCOYwoMOYR6dsJoMKB3U2PSXUmfPn1YvHgx9957L/369WPGjBl4eXlx33330b9/fzp06GBfos4R8+bN4/bbbycgIIDRo0dz4sQJuy0mJoZRo0aRlZXF3Llz6dixI3feeSc33XQT0dHRDBo0iMhI64iyffv2MWfOHDQaDXq9nv/97391xh4bG8uAAQOIjIys0nVUHW9vb7Zv387ChQsJDQ1l1apVgHVBjhkzZrBw4UKMRiOTJk1yqNt+0003MX78eNauXVvjoegNN9zAN998Q8+ePfHy8rLrwQPExcVVGd3y6aef8s0331Rp+/XXXycxMRGdTkdgYCDLli2r87rrg9JDVzQLyae/Iuvoo5hC7iW5TM+aw5/y8+Qt6LW1T0baOPO/9PYZSO5l+URPuLEZo21alB66or4oPXTFRcnJzJ8A6Nk+gWhPmB+Wyx/nnItvuXUNBiBtp1pfVKGoDyqhK5qF08WZHCt3IyJ4CD1Dh6MVkJKx2ekx0ffcwMmig+TkOO9vV7Rd4uPjq8y2jIuLY9++fS0d1kWL6kNXNAub80oIcL+C+zUaugcP5bBFUFDg+GFUBX7tA9mT9jV6aXbqp2i7VJ99qXCOqtAVTU6psZjjuUfpH2zVD9FqdOTjj9ZQtzxukKYMqffCWFr3sDSF4lJHJXRFk3Pg7Ncs7FhIlNf5H4QazwgCNCWUGYucHAkdw65ibMQj7Fv1VVOHqVC0elRCVzQ5pzN/xU0DvUMvt+8LDr6Gr/P1HMlxrqjn1sO6YEbe7jNNGqNC0RZQCV3R5BQXHaDQoqGT/3nJ1v6dbmJToZ6DucedHhtzz82YLEb0xsYvPq2wouRz60dj5XNbApXQFU2OuzGNIhGMptJqRh28O9DFy4+TdWi6eAX4kW/IxtctsKnDVNQTk8lUt1Mjeffdd+nXr/Hr0zaUCvnc2hJ6Zfncd955hxkzZjRzhI5Ro1wUTUpBaQb+mnJyvHpW2S+E4I5AI/qyuheCzjcW0MU7gpL8Yrz86qe10ZqoPMuwgqioKIYMGYLBYGDFihU17HFxcQwYMIDi4mI+/fTTKrZp06bVeU4ln9u88rnNharQFU3KHzkHWF+gp33I1TVsOs+eBGjKKCzLctpGtkcpO7O+ZefXdSd/Rf04fPgwDz30EIcOHaJdu3a8+eabAMycOZMdO3awf/9+SktLWbdunf0Yg8HAzp07eeyxx7j88sv5/fff2b17N5MmTeKll16y++3du5eNGzeydetWFixYwNmzZ/Hw8GDNmjXs2rWLTZs28dhjjyGl5Ntvv6Vjx44kJyezf/9+rrvuunrF//zzz7Nz50727t3LTz/9xN69NRcJKS4uZtCgQRw4cICrrrrKnvTvv/9+Fi1aRFJSEq+88goPPfSQ/ZjU1FR+++03vvjiCx588EFmz57Nnj17auiYnzlzhs6dO9u3w8PDOXOm5Z/z1KtCF0JcB7wGaIF3pZQv1uJ3G7AaGCylVPP6FRzKO8X3BXqeCb+phi00YAiWst85dHYDQ7rfWWsbXRN6s+mDb9HtKIQ72o4EQAXOKmo3Nzendm9v73pV5NWpLp/7+uuv8/jjj7Np0yZeeuklSkpKyMnJISoqiptust676vK5EydOJC0tDYPBQEREhN1WIZ/r6elpl88dO3YsTz/9ND///DMajaaKfO5jjz3Gk08+yY033ljvBSA+/fRT3nnnHUwmE2lpaRw8eJCYmKorNVWXz7311luryOdWUF5+fnWyppLPbS7qrNCFEFpgMXA90A+YLISo0bklhPAF/gaomQAKOymZW+ju055Aj5p94JEdrdXY6awtTtuISbiKQG0gblkGp36K+qPkc5tPPrc5qU+XyxDgTynlcSmlAVgJjHPg90/g34CaAaKwE2X8mdsDHH8kwvz6UGDWUlrsfDSDzt2dASHXER58fVOEeEmi5HObTz63OalPQu8EnK60nWrbZ0cIcRnQWUr5tbOGhBD3CyF2CiF2ZmZmXnCwitZFdtEpArRG3L0ja/XZpx3M+oK6pXELjAX4uQWRn5buyhAvWSrkc/v27Utubi4zZszA39/fLp87ZsyYesnnDhw4kODg4Cq2CvncoUOHVpHP3blzJ9HR0Xz44YdV5HOHDBlCXFwc8+fP55lnnqkz9sryuXfccUed8rn9+/dn48aNPPvss4BVPve9994jNjaWqKgo1q5d6/D4m266iTVr1hAXF8cvv/xSxXbDDTfQvXt3evbsyX333Wd/BtHS1CmfK4QYD1wnpZxu274biJdSzrRta4CNwFQpZYoQYjPweF196Eo+t+3zy5G3MaS+hEeXfzCi53SHPkv2LuH13a+zZfIW2rm1q7WtjbP/S2/3gZwKPMLwJ/7aVCE3C0o+V1FfmkI+9wzQudJ2uG1fBb5Af2CzECIFGAokCiEcjzdSXDKcy/kdgL4da+8q6RfQnaHeJvaf/c5pW0FDrMMey04Vuy5AhaKNUZ9RLjuAXkKICKyJfBJwR4VRSpkP2H9z1bdCV7R9yksOk2t2I9Cr9odFkQG9mBRo4Ez6t9BtfK1+/W67llO7NuNG7VW8ou0RHx9fZRQKwEcffUR0dHQLRXRxU2dCl1KahBAzgQ1Yhy2+L6U8IIRYAOyUUiY2dZCK1sm6PB0DAoc69Qny6UKuWU958R9O/fRubmxJ30BReTqXM9WFUSouZpR87oVRr3HoUspvgG+q7Xu2Ft+RjQ9L0drJKs3iQGEuYyNH1+lbpmuPl+lcnX46UimTReSdTcW/Y7grwlQo2hRqpqiiSdh/ZgMDvUz0C+hZp6+ndyR+WhPphcec+oV16UrfgBEcXvG5q8JUKNoUKqErmoT0jG+4M9BA74Bedfp2DBoOwB9pPzj16zT8OqIDrqAkRTj1UyguVVRCVzQJptI/ybV44OsRXKdv//Bx/L8zXhwstTj1633DaEpNRXgK9WBUoXCESugKl2OxWPCVORj0Hevl7+vuT3vf7hzIOlCnb54hm3buSkq3MSg99PrRWD30kpISxo4dS2RkJFFRUTz11FN227JlywgJCbEvfP3uu+82KtYKlHyuwuWczt2Dt8aCxTeq3sdcFRiAKPoZi8VSRTe9OsWmfMK8upK69yjhMXV35yhcj8lkQqdr2tThqgTXUCr00H18fBg+fHgNe2U99G3btjFjxgyHI3Ief/xxRo0ahcFgICEhgfXr13P99dZ5GRMnTuSNN95wadwqoStczpH0H9EAXUOuqvcxEV6+tDMVcyZvP50DY2r1M4b4YSo1cmTd9jaT0JN23VFjX/vQGwgPvwuzuZQ9yTVnxoaF3UrHsPEYDDns2z+zim3gZR/XeU6lh970euheXl6MGjUKsKpmXnbZZaSm1r0wemNQXS4Kl7O/VMeCNB/6hl1b72M6h1j/sRw553zGaI9xg/ji5KucOanmrTUGpYfevHroeXl5fPXVVyQkJNj3ff7558TExDB+/Pgqyo2NQVXoCpdzIPsAHfwi8dDXf3Whvh2uZcuf/yAn13mi7n5ZJB5GA/rMfY0N86LBWUWt1Xo6tbu5BdarIq+O0kNvPj10k8nE5MmTeeSRR+jevTtgFf6aPHky7u7uvP3220yZMoWNGzc2+lyqQle4FLPFRKRxKyP8L+zBpbe7P7kWT8xlzseiA/RqF0OfjpMbGqICpYfenHro999/P7169eLRRx+17wsKCsLd3R2wPgBOSkqq13nrQiV0hUs5nvU7AzzLiPD2u+Bjy926UmAopi4FUJ1XF8J8enNs09aGhnnJo/TQm0cP/ZlnniE/P5///ve/VfanpaXZXycmJrpMfVMldIVL+fPcjwB0Cx15wcd6hk3lzQwtqUXOHxyJIOvH9vQG1Y/eUJQeetPpocfFxQHWqv3555/n4MGDXHbZZVWGJ77++utERUURGxvL66+/zrJly+q87vpQpx56U6H00NsmH//yFwLK93H1yAPodR4XdOyh7ENMWDeBl698mesian84lrrnAKzM4c+CvYx88+HGhtzsKD10RX1pCj10haLeiPKT5OJ7wckcoId/D2aFGsg+875Tv/C4KAqMuXjr/BsYpULRNlGjXBQuw2g2UmwqwdO7xhri9cJN64av3gNZ9medvuml59AIU4POo2g9KD30C0MldIXLSClI4bV0N/41YlqD27C4dSbA8AcmswGdtva1Rk/yJ9lZB+m0bSA94+MbfD7FxY3SQ78wVJeLwmXsz9oPQP+QhldP/u3icNdI/szY4tSvd78gAE6sXd7gcykUbQ2V0BUuozDtAx4IMdG1XdcGt9G9vXWq9PEM55Ms+v7lDm4Ivx+v3O4NPpdC0dZQCV3hMvTlxwl080IjGv6x6hV6BXtL3UgpynHqFxDeGbM04+HWocHnUijaGiqhK1xCubGYQE0xwiOibmcn6LRuJGvj2ZKfV6dvQXkO/m5BGA2GRp1ToWgrqISucAmHzv2ATkCQ/8BGtxUVFMXp3EMYTKVO/cpEEe5aTw6u/rbR51TUzbJly5g5c2bdji2MI7lbgG+//ZY+ffrQs2dPXnzxxWaOqnlQCV3hEk5m/gxAr7CrG91WtKeZ58Ly+eOc8350t+4hAKTvSW/0ORU1MZvNzXIek8m1w08dLUphNpt5+OGHWb9+PQcPHuSTTz5p0AIaFztq2KLCJZwszkWUeTAqoPEVes/QqziZsYSTGT8REz62Vr+Ye25g17MfklWe1+hzthRzj6ayv8j5L5ELpb+PJ//sFe7UZ/ny5bz++usYDAbi4+N588030Wq1+Pj48MADD/DDDz+wePFijh49ygsvvIC/vz+xsbF2QamUlBTuvfdesrKyCAkJYenSpXTp0oXPPvuM+fPno9Vq8fPz4+eff3Z4/mXLlvHFF19QVFSE2Wzmm2++YdasWezfvx+j0ci8efMYN24cy5YtIzExkZKSEo4dO8Ytt9zCSy+9xPvvv8/evXvtGilLlizh4MGDvPrqq/j4+FBUVFTlfNu3b6dnz552tcNJkyaxdu1a+vVr2JyJi5VWl9DTitI4mbUFaa56w4TGHa2ndYV5c+kJpKWkmt0TrWd3m/0Y0lJVnU1ovdF6dAPAVHIUpKGa3RetRxeb/TDIqlWF0Pmhdbf+IzIVHwIs1ewBaN07IqXEXFKzMtDog9C4dUBKM+aSPxzYQ9C4hSItRsylR2ra3dqj0QcjLeWYS2tOzNG4haHRByLNJZjLTtS0u4ej0fkhzUWYy046sHdBo/PFYirAUl5Tu/nnrHME+17hdLWh+tI9OJ4/LIL8wpoa15VpF+zPwXPfo5NqgtGFcOjQIVatWsWWLVvQ6/U89NBDrFixgnvuuYfi4mLi4+P5v//7P9LS0rjjjjtISkrCz8+PUaNGMWDAAMCqtjhlyhSmTJnC+++/zyOPPMKXX37JggUL2LBhA506dSIvL89pHLt27WLv3r0EBgby9NNPM3r0aN5//33y8vIYMmQIV19t/bW3Z88edu/ejbu7O3369GHWrFlMmDCB559/npdffhm9Xs/SpUt5++23az2XI/3ytjjGvdUl9G9TvqXw5L+I8qyaMNONghfOeQIwK6SMHh5V7acMGv6Tbp2O/nj7UsLdqmrYHCnT8Gam1f7/OpQSoq9q31eq5b0sa3WyoGMJ7apJJu8s1rI8x2r/d6cS3KvltS1FOj7LdUMgebVzzYpsY4GOxHw3PITkxfCa9vX5ejYU6PHTWpjfsaZU6JpcPT8V6QnVWXg6rKZ9ZY4bvxfr6Oxm5rH25TXsH2S5sbtURy93Mw+H1rS/k+nOwTIt/T1MTA+p+RDSWO5OXPeba+xvCBqNhjwRiIchpc4l6YJ0BsrdOpN5+AghfXq75PzNSV2VdFPw448/kpSUZBffKi0tJTQ0FACtVsttt90GWCf1jBw5kpAQa9fWxIkTOXLEWkxs3bqVL774AoC7776bJ554AoARI0YwdepUJkyYwK233uo0jmuuuYbAQKvM8nfffUdiYqJ9PdKysjJOnToFQEJCAn5+VvXOfv36cfLkSTp37szo0aNZt24dffv2xWg0qtmjtMKEfl236zjp41ujQu+ucef92Nor9L4aT96Pq71CH6D15n0nFfpQrS8jnFToV+n8GO2kQr9WF8D1Tir0m/VB/MVJhX67PoSJTir0u3u1Z4qTCn16rzDud1KhP9zbeYX+997OK/RnIrsT0951MzYDg6/DPXsFW48vZUTPmkuwVRAxdBwdM6LZv+gbRr3R+hJ6SyClZMqUKbzwwgs1bB4eHo1a4OGtt95i27ZtfP311wwcOJCkpCSCgoIc+lbWHpdS8vnnn9OnT58qPtu2bbN384D1C6eiz3369On861//IjIykmnTnM9OvhD98tZMq0voYT5hhPmMr8OrdtnPi8M+pA770Drsjp/in+fyOuz1X+uzpRjV73Ge/nod+tN7GNGzdr8BM6fzx5NfE+LWFaPBgN6tdrkAhZWEhATGjRvH7NmzCQ0NJScnh8LCQrp2rTohLD4+nr/97W9kZ2fTrl07PvvsM2JjYwHrSJKVK1dy9913s2LFCvtKQ8eOHSM+Pp74+HjWr1/P6dOna03olRkzZgyLFi1i0aJFCCHYvXu3vXunNuLj4zl9+rS968YZgwcP5ujRo5w4cYJOnTqxcuVKPv74wld6uthRo1wUFyWe+naEh9/Jd6d/IaMko1Y/vZsbmaZT+LsF8/u/lzZjhK2Xfv36sXDhQq699lpiYmK45pprqiy4UEFYWBjz5s1j2LBhjBgxooqM66JFi1i6dCkxMTF89NFHvPbaawDMmTOH6Oho+vfvz/Dhw+1fAHUxd+5cjEYjMTExREVFMXfu3HodN2HCBEaMGEFAQIBTP51OxxtvvMGYMWPo27cvEyZMICoqql7naE0oPXTFRcvJ/JM8//11XNV5FHfGv1mrX/off1LyfgrpJWcY+saUZoywYSg9dNdx4403Mnv27CqLL7cllB66os3Q1a8rVwX44FXwA0ZT7WtGto/syemSUwR5tOfPHQeaMUJFS5GXl0fv3r3x9PRss8m8IaiErrio6RA2kXZaMz8fecOpnyY+jK9T32LLu/9rpsgU9WHDhg3ExcVV+bvlllsa3a6/vz9Hjhyxrw2qsFKvhC6EuE4IcVgI8acQ4ikH9r8LIQ4KIfYKIX4UQjRcbk+hqMSVvWdSYNZyLm2VU7/L774en/ISSjKPYqzHCvAtTUt1dTY3Y8aMYc+ePVX+1qxZ09JhtQoa8hmpM6ELIbTAYuB6oB8wWQhRfXrVbmCQlDIGWA28dMGRKBQO0Os8MPoMpYPI4c+MrU59I7r356puM9i64K1miq5heHh4kJ2dfckkdcWFI6UkOzsbD48LW8qxPsMWhwB/SimPAwghVgLjAPtgainlpkr+vwN3XVAUCoUTLu/7D77eOo4/jq+hZ+iwWv0GP/E0Ga8k4VkUXKvPxUB4eDipqalkZma2dCiKixgPDw/Cwy9s4ll9EnonoPJMklTA2QySvwLrHRmEEPcD9wN06dKlniEqLnU6+vflkOeNbE/5jb8OKsOjlgWo27UPZk/xcbr59mP/6vX0H399M0daP/R6PRERjZMZVigc4dKHokKIu4BBwMuO7FLKd6SUg6SUgyqmEysU9WFin4kYjXl8f/QDp37+V3ZBIMjZmNI8gSkUFxH1SehngM6VtsNt+6oghLga+H/AzVLKmmIgCkUjGNJhCLM7WCg6U/t4dICYSWNJL00lzDuCwuy85glOobhIqE9C3wH0EkJECCHcgElAYmUHIcQA4G2sybz2aX0KRQMRQuDmP5JQTRF7U7926pvhb2BX1vd8/Z93mik6heLioM6ELqU0ATOBDcAh4FMp5QEhxAIhRIW83suAD/CZEGKPECKxluYUigZzVb9/YLDA3mOLnPol/GMSmfkHKT74QzNFplBcHNRLnEtK+Q3wTbV9z1Z63fhlahSKOgjy7ky2rjuBxqPklaTh7xXm0M/d04Mufr7o3WJJfv8TYu+d3MyRKhQtg5opqmhV9O/+MO4a+PHwYqd+sdP+Rj//ERQmFTZTZApFy6MSuqJVEdflL3xSGsNHJ/c7nZjT9coRpJWcpKNXBOmHjzVjhApFy6ESuqLVMbb3PRzLP8bOczuc+hmCS3DTenDgja+aKTKFomVRCV3R6rgu4jruDrZw6I8nnfoN+8dfyTfkEKLroqbZKy4JVEJXtDo8dZ6Et+tJe8sp0gpqLsdXgd7NjVRzOiWmPH546/NmjFChaBlUQle0Si7rPRudgF8PvejUr/+s6/nt3BekbvqomSJTKFoOldAVrZLI9iM5Z/FHW7AFk9lQq1+nnp0Jw4BR603a7t3NGKFC0fyohK5otYR0GI+f1sQvR53L5fa+egLXd3mQw+/+1EyRKRQtg0roilbLVZF/Y1OxP2tTnVfelz0wnZzyDNp7dKe0sKiZolMomh+V0BWtFnedF926zeDHMzv57PBKp77ZIhVffQA7n1reTNEpFM2PSuiKVs20qGmM6RSHOWUuvx/7sFa/0a8+ysnCP4jwjWLDY+82Y4QKRfOhErqiVaPVaHl6+ItoNToyTvyTE9k7a/WNnX8b6aWplOSfZONS52uUKhStEZXQFa2eQK9OxMS8jQbJ9l1TKCzLcujnExxIwJQBpObu5uC6pRz7+cdmjlShaFpUQle0Cfq0v5J2XR4jUFPG2t/GYbaYHPp1vyySy2+7hRCfPhSuPkf2iVPNHKlC0XSohK5oM1zZewYFvtdSXJbBO8lv1Oo34I6/EhbWlSDPzhz9z0aMhtrHsSsUrQmV0BVtilsGLSbV93be3Pse36V8V6vflS/+nWOFewn37sGW2W83Y4QKRdOhErqiTaHRaJg7fB5DQvrx58FHnC5XN+K/95NafJwePrF898yy5gtSoWgiVEJXtDnctG4sHLGAML2FY4f+zrl8xwJeejc3ej5yFbmGLDTZuWz7ckMzR6pQuBaV0BVtkjC/PnSPfAUPYWLTjomUG4sd+gX36oYY25kDmRtJ+vA/nN23q5kjVShch0roijZLbOeb0bS/l1BNAZ/9dgsWi8WhX/TVgxk86ircPcM49b+tFGVmN3OkCoVrUAld0aYZE/3/yHQfjFv5cVYeqn2G6PCHH6d3SCTh7WLYM++LZoxQoXAdKqEr2jy3D1vONt01vLBzEQu3/IOswhSHflf89ylOFB6km28kOx5ZTvKq9c0bqELRSFRCV7R5tBodC6/8D1OjpkL2GrZuu4avdj/lcPLRoBfv5GjBHoI9wvBLcmflA89TUljY/EErFA1AtNRai4MGDZI7d9auu6FQNAUHzn5P8sEnaK8pIMPiQ/++LxLd6foafvvXbSH9670k53yDl8FA/8EjuPzpZ1sgYoWiKkKIJCnlIEc2VaErLimiOl7DpNFJlAVOxpsSzv0xk3e3/JUiQ1Wd9P43jiDhfzPoO2A4eq0HYblD+X3WB/zx9aYWilyhqBtVoSsuWbKLT7M+aQbvnEpB5xbKnIEzGRPxFzSaqnVO/tmzJC/8gq4+UVgwk1J8kPiFU/AK8GuhyBWXMs4qdJXQFZc8+7P288/fF3CVZjd+bn4Miv4PfdpfWcNv19IvkHvKae8ZTp4hi9SIcq6bNakFIlZcyqiErlDUgclsZN2eOehy1+EmJJkyAC//YcRFTCMi6DK7n9FgYPMzH6IrKmNX9rf4G8ro0X44XtF9GHDf7ejd3FrwKhSXAiqhKxT1JC3/MJv3z0Vbsp8gbTmf5ujJdOtHQsehDAvpQWzncWg1OtJTzvLDwv+HKTeLUT0fRyM0FBnzySw7izFEy5BHbscnsF1LX46iDaISukLRAP7M2MrW9L1sPPM7bsXbmBBQTqFFQ5G+O51Cr2dw93vwcQ/k0LqNpG3YRzsRTIhHR7QaHUlZP5KVt5vwbh3pf/cMOsXGtPTlKNoIKqErFI0ku/g024+9R3b2RgLMZ/HQSAwW+LB0AJ39uhPlqaGDhzftSsLJTywj9eQBSkqPEe4fx6DgMRQa8yg2FlJqLqLM0w3Rw4eYMYPp0KN7S1+aopXR6IQuhLgOeA3QAu9KKV+sZncHPgQGAtnARCllirM2VUJXtFbKjcVsT1lOSvoP/FoaSEp+Ctd7nCDay2z3KTBrySeA8t8G0CsjGo+O6bh7WXDTeKARGpKyv6e8xEKnnKvo6Nuf/NCdGLR5mLQWLEJLrjyHKCnGMzMSd7qg6XQMoTUihQazEOSRgSgqwSurH250QhN+FKExI4UGk4B8MhD5pfjkxqCjPdouhwGJFBqMAgrIgLxS2uXHoZVBaLtYFSml0GLATKHIhJxy/AovQyPaoQ3/EwCLzV4k0pFZJgKKByG0nmg7HrfbyzFRItIxZ5oJKokHnQ5tWIrdXoaRUpGOOV0SXDYM6SbRtj913i4NlGnSMZ3TEFw+FOluRht62mrX6CixlGHQnMN81p0g4xDwNKAJPlPJXopBnMN81psg00DwKkMTlGa3F1tKMGnSMZ9uR6BlAPgUowlIt9uLLEWYRQaW04EEyFjwLUDjn2mz6ym05GMRWVhOhRJAf/DLRdMuu6qdTDjZET9NXwjIQuOTZ7dnF5XRPvY6rv3L5AZ9/pwldF09DtYCi4FrgFRghxAiUUp5sJLbX4FcKWVPIcQk4N/AxAZFq1Bc5Ljrvbmi1wNc0esB7rbtKy7P40T2Ns7m7Cav6A8MpacoMZawvNdeCrtt4dHQMrq5nxcH6wQUZOgxfl8CCETUb2h806h4pBoGFJz2JiRjPN18ojgWvRqT53nRME8g77gvYVkxhHv35mjccix6q6KkG+AFZB/2Izw/jvae3Tg84F3QmO12byBzXwBdiwYR4BHC0YFL7G27AT7AuV1B9Cgdipe3G8cGvnf++gFf4Oy2EHobR6DzLePEwKVV7O2A1F/b09d8BRa/TE4O/KCK3Q84uSmM/mIkZQHHOD3wo5r277oQ4zWK4qB9pA5cXsUOcCqtFzFeIylsv4OzsR/XsKee6U+M10jyO/7Cuf4/1bCfSRlEjPdV5IZ/T0ZkTXvasU7E+F1JdpdEsnrVtGcc6UlM4BVkdv2MnO417dl/xBITcgXpER+R1+W83e94KEd/tDQ4oTujzgpdCDEMmCelHGPb/geAlPKFSj4bbD5bhRA64BwQIp003tAKfe7RVH7480SN/d5e3vi280VaJOkZ6TXsPt4++Pj6YDFbyMjMqGH39fXF29sbs8lMZlZmDbtfOz88vTwxGo1kZ9dU4/P388fD0wNDuYGc3Jwa9gD/ANw93CkvKyc3L7eGPTAgEDd3N8pKy8jLz6thDwoKQq/XU1pSSn5Bfg17SHAIWp2W4uJiCh1MVQ8NCUWj1VBUWERRcVENe/vQ9giNoLCgkOKSmlKzHTp0AKAgv4CS0pIqNiE0tG8fCkB+Xj6lZaVV7FqNlpDQEAByc/MoLy+rYtdpdQSHBAOQk5ODodqScHqdnqDgIACys7IxmoxV7G5ubgQGBgKQlZmFyVx1Sr+7uwcBAf4AZGZkYraYq9g9PTzx87eOKU9Pz0DKqqqMXp5etPOzPuA8d+4c1anrs+fp5YWHpxaLxUx+7vl7JxEgtXj5eOHhoaOsoIji0lJAgAApJUgt7lodei1YpIVSk7GSHZAaPLR6dFqJWVooc2TX6dFpLZgtFspMphp2T50erdaCyWyh3FzNbtHgpdej0Vowmi0Y7HaJlMJqd3NDozFjNJsxmM017N5ubgiNGYPJjNFyAXaLBqTAx90NhJlykwmTxVLVjsDHrXa7QIO3mx6EmTKjCbO0IBEIm12DBi+bvdRoxCJlVbuwXv95O0iw27VCi6deC8JCicGIPeEJibRo0QkNHna7AYlAIhjeMYz/DuxX47NSHxpVoWMtJk5X2k4F4mvzkVKahBD5QBBQZfl1IcT9wP0AXbp0qVfwCkVrRys0uOu9sZgtwPkvQ2H7j06jw13vjc7Pg1JjzWLCu1IxUe6gmPCuVEwYHBQTPpWKCYODYsKnUjFhdFBM+FQqJkwOiol2wcH2YsLkoJhoFxJiLybMDooJv9BQezFhrlxMaG329u0BB8WE1lpM+FUqJiyViwmttZjwsxUTlurFhNZaTPjZiglz9WJCay0m/GzFhKl6MaG1FhN+tmLCWL2Y0IKbuwd+tmLCUKmY8G3XNCOg6lOhjweuk1JOt23fDcRLKWdW8tlv80m1bR+z+WQ5ahNUH7pCoVA0hMZquZwBOlfaDrftc+hj63Lxw/pwVKFQKBTNRH0S+g6glxAiQgjhBkwCEqv5JAJTbK/HAxud9Z8rFAqFwvXU2Ydu6xOfCWzA2qv1vpTygBBiAbBTSpkIvAd8JIT4E8jBmvQVCoVC0YzU56EoUspvgG+q7Xu20usy4HbXhqZQKBSKC0HpoSsUCkUbQSV0hUKhaCOohK5QKBRtBJXQFQqFoo3QYmqLQohM4GQDDw+m2izUVoy6louPtnIdoK7lYqUx19JVShniyNBiCb0xCCF21jZTqrWhruXio61cB6hruVhpqmtRXS4KhULRRlAJXaFQKNoIrTWhv9PSAbgQdS0XH23lOkBdy8VKk1xLq+xDVygUCkVNWmuFrlAoFIpqqISuUCgUbYRWl9CFENcJIQ4LIf4UQjzV0vE0BiFEihBinxBijxCiVa32IYR4XwiRYVvcpGJfoBDieyHEUdv/A1oyxvpQy3XME0Kcsd2XPUKIG1oyxvoihOgshNgkhDgohDgghPibbX+rui9OrqPV3RchhIcQYrsQItl2LfNt+yOEENtseWyVTZq88edrTX3otgWrj1BpwWpgcrUFq1sNQogUYJCzlZ0uVoQQVwJFwIdSyv62fS8BOVLKF21ftgFSyidbMs66qOU65gFFUspXWjK2C0UIEQaESSl3CSF8gSTgL8BUWtF9cXIdE2hl90UIIQBvKWWREEIP/Ar8Dfg78IWUcqUQ4i0gWUr5v8aer7VV6EOAP6WUx6WUBmAlMK6FY7okkVL+jFX7vjLjgIrl3T/A+o/woqaW62iVSCnTpJS7bK8LgUNY1/ttVffFyXW0OqSVioVU9bY/CYwGVtv2u+yetLaE7mjB6lZ5o21I4DshRJJtAe3WTnspZZrt9TmgfUsG00hmCiH22rpkLuouCkcIIboBA4BttOL7Uu06oBXeFyGEVgixB8gAvgeOAXlSyooVpV2Wx1pbQm9rXC6lvAy4HnjY9vO/TWBbgrD19OdV5X9ADyAOSAP+r0WjuUCEED7A58CjUsqCyrbWdF8cXEervC9SSrOUMg7resxDgMimOldrS+j1WbC61SClPGP7fwawBuvNbs2k2/o/K/pBM1o4ngYhpUy3/SO0AEtoRffF1k/7ObBCSvmFbXeruy+OrqM13xcAKWUesAkYBvgLISpWjHNZHmttCb0+C1a3CoQQ3rYHPgghvIFrgf3Oj7roqbxY+BRgbQvG0mAqkp+NW2gl98X2AO494JCU8j+VTK3qvtR2Ha3xvgghQoQQ/rbXnlgHdBzCmtjH29xcdk9a1SgXANtQpf9yfsHq51s2ooYhhOiOtSoH69quH7emaxFCfAKMxCoDmg48B3wJfAp0wSqNPEFKeVE/cKzlOkZi/VkvgRTggUp90BctQojLgV+AfYDFtvtprP3Prea+OLmOybSy+yKEiMH60FOLtYD+VEq5wPbvfyUQCOwG7pJSljf6fK0toSsUCoXCMa2ty0WhUCgUtaASukKhULQRVEJXKBSKNoJK6AqFQtFGUAldoVAo2ggqoSsuaYQQjwohvFo6DoXCFahhi4pLmtaseKlQVEdV6IpLBtvs3K9t2tT7hRDPAR2BTUKITTafa4UQW4UQu4QQn9n0RCq0618SVv367UKIni15LQqFI1RCV1xKXAeclVLG2rTP/wucBUZJKUcJIYKBZ4CrbaJpO7HqVleQL6WMBt6wHatQXFSohK64lNgHXCOE+LcQ4gopZX41+1CgH7DFJnc6Behayf5Jpf8Pa+pgFYoLRVe3i0LRNpBSHhFCXAbcACwUQvxYzUUA30spJ9fWRC2vFYqLAlWhKy4ZhBAdgRIp5XLgZeAyoBDwtbn8Doyo6B+39bn3rtTExEr/39o8USsU9UdV6IpLiWjgZSGEBTACM7B2nXwrhDhr60efCnwihHC3HfMM1nVsAQKEEHuBcqzKfwrFRYUatqhQ1AM1vFHRGlBdLgqFQtFGUBW6QqFQtBFUha5QKBRtBJXQFQqFoo2gErpCoVC0EVRCVygUijaCSugKhULRRvj/lXQcN8HtWCYAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "for (g, group) in res.env.dropna().groupby(\"params_id\"):\n", " params = res.parameters.query(f'params_id == \"{g}\"').iloc[0]\n", " title = f\"{params.generator.rstrip('_graph')} {params.prob_neighbor_spread}\"\n", " prob = group.groupby(by=[\"step\"]).prob_neighbor_spread.mean()\n", " line = \"-\"\n", " if \"barabasi\" in params.generator:\n", " line = \"--\"\n", " prob.rename(title).fillna(0).plot(linestyle=line)\n", "plt.title(\"Mean probability for each configuration\")\n", "plt.legend();" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "hideCode": false, "hidePrompt": false }, "outputs": [ { "data": { "image/png": "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jx6jxYDJoieiqZZWaLYaufNJLcXXXeykYN1JHHuzyEgvxHG6CFnsJGhIc/z6RiOMOtzFTswtgzCEWzFG+GiOO0T75WBs7EtgY98Kr+FKxumRu61NPvzww1rt/3w4nU5WrFiBn59fhQ49JCSEN954g//7v/+rsp8nn3ySRx55hFGjRvHnP/+Zjz76iClTptSS1cqh1yindu3DZjai9/HD4nvmt7JXu6XpVR5uKciEPd/B7kWQslJLH/SNgOumgn8juPmlctWlW5J9qpDTh/MoKXQSn6TNS6yYs5fMNBu+QWYaxQXQ4ZoooloHedtN/s+13sU0ZyOEoN8fz+iFlBzKxZVXgmNXJpkrU3GeLsTSPpTAgc1AJ8j9IQWdnxFjhBVrfBiGCCvmltq5DKE+NHqgyyV/LAv+vfmcYy27RXh/UXz35rZzytv2jqRdn0iKbHaWvFd+pH3bY13Pe06n08mYMWPYvHkzHTp04NNPP8VqtTJ9+nQWLVpEUVERffr04b333tM+s379SEhI4LfffmP06NG0bt2aGTNmYLfbCQ0NZc6cOTRqpOnObNu2jd69e5ORkcETTzzB5MmTsdlsDBs2jOzsbBwOBzNmzGDYsGEUFBQwYsQI0tLScLlcPP3004wcObLcSLsipkyZwoYNGygqKuLOO+/kueeeq7DeI488wrJly2jcuDFz584lPDycgwcPcv/995Oeno7VauWDDz6gbdu2jB8/HovFwpYtW4iOjmb16tXo9Xo+//xz3nzzTa699lpvvxEREURERPD9999X+hlLKfnll1/44gtNq3DcuHFMmzZNOfQrhfx9B8nzsRBQRgO9bLglzCesitYNlJxUMPpoqycP/wqLHtIyT3reA+2GaCGVs9I796w5wd51Jzl9OA97sTay9gs203lADEIIksa1w8fPhF+w+ZzTSenZxd3TZeHW0zjSi3Dn2XHlleDKtWOM8SPkztYAZH6+C3ehU9ucIdiihUdCNIVMnUlP1LO90fk0vP8me/fu5aOPPqJv375MnDiRt99+m8cff5wHHniAZ57REtjuuusuvvvuO4YMGQKA3W6ndHV3dnY2a9euRQjBhx9+yMsvv8y///1vALZv387atWspKCigS5cu3HrrrURERLBgwQICAgLIyMigV69eDB06lCVLlhAVFeV1jLm5udWy//nnnyckJASXy0VSUhLb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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "for (g, group) in res.agents.dropna().groupby(\"params_id\"):\n", " params = res.parameters.query(f'params_id == \"{g}\"').iloc[0]\n", " title = f\"{params.generator.rstrip('_graph')} {params.prob_neighbor_spread}\"\n", " counts = group.groupby(by=[\"step\", \"state_id\"]).value_counts().unstack()\n", " line = \"-\"\n", " if \"barabasi\" in params.generator:\n", " line = \"--\"\n", " (counts.infected/counts.sum(axis=1)).rename(title).fillna(0).plot(linestyle=line)\n", "plt.legend()\n", "plt.xlim([9, None]);\n", "plt.title(\"Ratio of infected users\");" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Data format" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Parameters\n", "\n", "The `parameters` dataframe has three keys:\n", "\n", "* The identifier of the simulation. This will be shared by all iterations launched in the same run\n", "* The identifier of the parameters used in the simulation. This will be shared by all iterations that have the exact same set of parameters.\n", "* The identifier of the iteration. Each row should have a different iteration identifier\n", "\n", "There will be a column per each parameter passed to the environment. In this case, that's three: **generator**, **n** and **prob_neighbor_spread**." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "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", " \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", " \n", " \n", " \n", " \n", " \n", "
keygeneratornprob_neighbor_spread
iteration_idparams_idsimulation_id
039063f8newspread_1682356920.2487948erdos_renyi_graph1001.0
8f26adbnewspread_1682356920.2487948barabasi_albert_graph1000.5
92fdcb9newspread_1682356920.2487948erdos_renyi_graph1000.25
cb3dbcanewspread_1682356920.2487948erdos_renyi_graph1000.5
d1fe9c1newspread_1682356920.2487948barabasi_albert_graph1001.0
\n", "
" ], "text/plain": [ "key generator \\\n", "iteration_id params_id simulation_id \n", "0 39063f8 newspread_1682356920.2487948 erdos_renyi_graph \n", " 8f26adb newspread_1682356920.2487948 barabasi_albert_graph \n", " 92fdcb9 newspread_1682356920.2487948 erdos_renyi_graph \n", " cb3dbca newspread_1682356920.2487948 erdos_renyi_graph \n", " d1fe9c1 newspread_1682356920.2487948 barabasi_albert_graph \n", "\n", "key n prob_neighbor_spread \n", "iteration_id params_id simulation_id \n", "0 39063f8 newspread_1682356920.2487948 100 1.0 \n", " 8f26adb newspread_1682356920.2487948 100 0.5 \n", " 92fdcb9 newspread_1682356920.2487948 100 0.25 \n", " cb3dbca newspread_1682356920.2487948 100 0.5 \n", " d1fe9c1 newspread_1682356920.2487948 100 1.0 " ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "res.parameters.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Configuration\n", "\n", "This dataset is indexed by the identifier of the simulation, and there will be a column per each attribute of the simulation.\n", "For instance, there is one for the number of processes used, another one for the path where the results were stored, etc." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "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", " \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", " \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", "
indexversionsource_filenamedescriptiongroupbackupoverwritedry_rundump...num_processesexportersmodel_reportersagent_reporterstablesoutdirexporter_paramslevelskip_testdebug
simulation_id
newspread_1682356920.248794802NonenewspreadNoneFalseTrueFalseTrue...1[<class 'soil.exporters.default'>]{}{}{}/mnt/data/home/j/git/lab.gsi/soil/soil/docs/tu...{}20FalseFalse
\n", "

1 rows × 29 columns

\n", "
" ], "text/plain": [ " index version source_file name \\\n", "simulation_id \n", "newspread_1682356920.2487948 0 2 None newspread \n", "\n", " description group backup overwrite dry_run dump \\\n", "simulation_id \n", "newspread_1682356920.2487948 None False True False True \n", "\n", " ... num_processes \\\n", "simulation_id ... \n", "newspread_1682356920.2487948 ... 1 \n", "\n", " exporters \\\n", "simulation_id \n", "newspread_1682356920.2487948 [] \n", "\n", " model_reporters agent_reporters tables \\\n", "simulation_id \n", "newspread_1682356920.2487948 {} {} {} \n", "\n", " outdir \\\n", "simulation_id \n", "newspread_1682356920.2487948 /mnt/data/home/j/git/lab.gsi/soil/soil/docs/tu... \n", "\n", " exporter_params level skip_test debug \n", "simulation_id \n", "newspread_1682356920.2487948 {} 20 False False \n", "\n", "[1 rows x 29 columns]" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "res.config.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Model reporters\n", "\n", "The `env` dataframe includes the data collected from the model.\n", "The keys in this case are the same as `parameters`, and an additional one: **step**." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "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", " \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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
agent_counttimeprob_tv_spreadprob_neighbor_spread
simulation_idparams_iditeration_idstep
newspread_1682356920.2487948ff1d24a0010100.00.0
110110.00.0
210120.00.0
310130.00.0
410140.00.0
\n", "
" ], "text/plain": [ " agent_count time \\\n", "simulation_id params_id iteration_id step \n", "newspread_1682356920.2487948 ff1d24a 0 0 101 0 \n", " 1 101 1 \n", " 2 101 2 \n", " 3 101 3 \n", " 4 101 4 \n", "\n", " prob_tv_spread \\\n", "simulation_id params_id iteration_id step \n", "newspread_1682356920.2487948 ff1d24a 0 0 0.0 \n", " 1 0.0 \n", " 2 0.0 \n", " 3 0.0 \n", " 4 0.0 \n", "\n", " prob_neighbor_spread \n", "simulation_id params_id iteration_id step \n", "newspread_1682356920.2487948 ff1d24a 0 0 0.0 \n", " 1 0.0 \n", " 2 0.0 \n", " 3 0.0 \n", " 4 0.0 " ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "res.env.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Agent reporters\n", "\n", "This dataframe reflects the data collected for all the agents in the simulation, in every step where data collection was invoked.\n", "\n", "The key in this dataframe is similar to the one in the `parameters` dataframe, but there will be two more keys: the `step` and the `agent_id`.\n", "There will be a column per each agent reporter added to the model. In our case, there is only one: `state_id`." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
state_id
simulation_idparams_iditeration_idstepagent_id
newspread_1682356920.2487948ff1d24a000None
1neutral
2neutral
3neutral
4neutral
\n", "
" ], "text/plain": [ " state_id\n", "simulation_id params_id iteration_id step agent_id \n", "newspread_1682356920.2487948 ff1d24a 0 0 0 None\n", " 1 neutral\n", " 2 neutral\n", " 3 neutral\n", " 4 neutral" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "res.agents.head()" ] } ], "metadata": { "hide_code_all_hidden": false, "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.8.10" }, "toc": { "colors": { "hover_highlight": "#DAA520", "navigate_num": "#000000", "navigate_text": "#333333", "running_highlight": "#FF0000", "selected_highlight": "#FFD700", "sidebar_border": "#EEEEEE", "wrapper_background": "#FFFFFF" }, "moveMenuLeft": true, "nav_menu": { "height": "31px", "width": "252px" }, "navigate_menu": true, "number_sections": true, "sideBar": true, "threshold": 4, "toc_cell": false, "toc_position": { "height": "867px", "left": "0px", "right": "1670px", "top": "106px", "width": "250px" }, "toc_section_display": "block", "toc_window_display": false, "widenNotebook": false }, "vscode": { "interpreter": { "hash": "3581132406f7320837865a422f37590c78ed7dabfbcb5bc7771b9d116b13a5cf" } } }, "nbformat": 4, "nbformat_minor": 2 }