{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "3. Running a simulation with PCSE/LINTUL3\n",
    "=========================================\n",
    "\n",
    "The LINTUL model (Light INTerception and UtiLisation) is a simple generic crop model, which simulates dry\n",
    "matter production as the result of light interception and utilization with a constant light use efficiency.\n",
    "In PCSE the LINTUL family of models has been implemented including the LINTUL3 model which is used for\n",
    "simulation of crop production under water-limited and nitrogen-limited conditions.\n",
    "\n",
    "For the third example, we will use LINTUL3 for simulating spring-wheat in the Netherlands under water-limited\n",
    "and nitrogen-limited conditions. We will again assume that data files are in the directory\n",
    "`D:\\\\userdata\\\\pcse_examples` and all the parameter files needed can be\n",
    "found by unpacking this zip file :download:`quickstart_part3.zip`.\n",
    "\n",
    "First we will import the necessary modules and define the data directory. We also assume that you have the\n",
    "`matplotlib`_, `pandas`_ and `PyYAML`_ packages installed on your system.::\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import os\n",
    "import pcse\n",
    "import matplotlib.pyplot as plt\n",
    "import pandas as pd\n",
    "import yaml\n",
    "data_dir = r'D:\\userdata\\sources\\pcse\\pcse\\doc'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Input requirements\n",
    "----------------------\n",
    "For running the PCSE/LINTUL3 (and PCSE models in general), you need three types of inputs:\n",
    "1. Model parameters that parameterize the different model components. These parameters usually\n",
    "   consist of a set of crop parameters (or multiple sets in case of crop rotations), a set of soil parameters\n",
    "   and a set of site parameters. The latter provide ancillary parameters that are specific for a location.\n",
    "2. Driving variables represented by weather data which can be derived from various sources.\n",
    "3. Agromanagement actions which specify the farm activities that will take place on the field that is simulated\n",
    "   by PCSE. For defining the agromanagement we will use the new `AgroManager` which replaces the `timerdata`\n",
    "   definition that was used previously.\n",
    "\n",
    "Reading model parameters\n",
    "------------------------\n",
    "Model parameters can be easily read from the input files using the `PCSEFileReader`. However, PCSE models expect a single set of parameters and therefore they need to be combined using the\n",
    "`ParameterProvider`::\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from pcse.fileinput import PCSEFileReader\n",
    "from pcse.base_classes import ParameterProvider\n",
    "crop = PCSEFileReader(os.path.join(data_dir, \"lintul3_springwheat.crop\"))\n",
    "soil = PCSEFileReader(os.path.join(data_dir, \"lintul3_springwheat.soil\"))\n",
    "site = PCSEFileReader(os.path.join(data_dir, \"lintul3_springwheat.site\"))\n",
    "parameterprovider = ParameterProvider(soildata=soil, cropdata=crop, sitedata=site)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Reading weather data\n",
    "--------------------\n",
    "For reading weather data we will use the ExcelWeatherDataProvider. This WeatherDataProvider uses nearly the same\n",
    "file format as is used for the CABO weather files but stores its data in an MicroSoft Excel file which makes the\n",
    "weather files easier to create and update:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from pcse.fileinput import ExcelWeatherDataProvider\n",
    "weatherdataprovider = ExcelWeatherDataProvider(os.path.join(data_dir, \"nl1.xlsx\"))\n",
    "print(weatherdataprovider)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Defining agromanagement\n",
    "---------------------------\n",
    "Defining agromanagement needs a bit more explanation because agromanagement is a relatively\n",
    "complex piece of PCSE. The agromanagement definition for PCSE is written in a format called `YAML` and\n",
    "for the current example looks like this:\n",
    "\n",
    "    Version: 1.0\n",
    "    AgroManagement:\n",
    "    - 2006-01-01:\n",
    "        CropCalendar:\n",
    "            crop_id: spring-wheat\n",
    "            crop_start_date: 2006-03-31\n",
    "            crop_start_type: emergence\n",
    "            crop_end_date: 2006-08-20\n",
    "            crop_end_type: earliest\n",
    "            max_duration: 300\n",
    "        TimedEvents:\n",
    "        -   event_signal: apply_n\n",
    "            name:  Nitrogen application table\n",
    "            comment: All nitrogen amounts in g N m-2\n",
    "            events_table:\n",
    "            - 2006-04-10: {amount: 10, recovery: 0.7}\n",
    "            - 2006-05-05: {amount:  5, recovery: 0.7}\n",
    "        StateEvents: null\n",
    "\n",
    "The agromanagement definition starts with `Version:` indicating the version number of the agromanagement file\n",
    "while the actual definition starts after the label `AgroManagement:`. Next a date must be provide which sets the\n",
    "start date of the campaign (and the start date of the simulation). Each campaign is defined by zero or one\n",
    "CropCalendars and zero or more TimedEvents and/or StateEvents. The CropCalendar defines the crop type, date of sowing,\n",
    "date of harvesting, etc. while the Timed/StateEvents define actions that are either connected to a date or\n",
    "to a model state.\n",
    "\n",
    "In the current example, the campaign starts on 2006-01-01, there is a crop calendar for spring-wheat starting on\n",
    "2006-03-31 with a harvest date of 2006-08-20 or earlier if the crop reaches maturity before this date.\n",
    "Next there are timed events defined for applying N fertilizer at 2006-04-10 and 2006-05-05. The current example\n",
    "has no state events. For a thorough description of all possibilities see the section on AgroManagement in the\n",
    "Reference Guide.\n",
    "\n",
    "Loading the agromanagement definition must by done with the YAMLAgroManagementReader::\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from pcse.fileinput import YAMLAgroManagementReader\n",
    "agromanagement = YAMLAgroManagementReader(os.path.join(data_dir, \"lintul3_springwheat.amgt\"))\n",
    "print(agromanagement)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Starting and running the LINTUL3 model\n",
    "--------------------------------------\n",
    "We have now all parameters, weather data and agromanagement information available to start the LINTUL3 model:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from pcse.models import LINTUL3\n",
    "lintul3 = LINTUL3(parameterprovider, weatherdataprovider, agromanagement)\n",
    "lintul3.run_till_terminate()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Getting and visualizing results\n",
    "--------------------------------------\n",
    "Next, we can easily get the output from the model using the get_output() method and turn it into a pandas DataFrame:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "output = lintul3.get_output()\n",
    "df = pd.DataFrame(output).set_index(\"day\")\n",
    "df.tail()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, we can visualize the results from the pandas DataFrame with a few commands:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "fig, axes = plt.subplots(nrows=9, ncols=2, figsize=(16,40))\n",
    "for key, axis in zip(df.columns, axes.flatten()):\n",
    "    df[key].plot(ax=axis, title=key)\n",
    "fig.autofmt_xdate()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
