ipynb: rtapp: add another example of workload generation

This notebook provides some more example of workloads generation
using the wlgen::RTA "profile" based API.

Signed-off-by: Patrick Bellasi <patrick.bellasi@arm.com>
diff --git a/ipynb/wlgen/rtapp_examples.ipynb b/ipynb/wlgen/rtapp_examples.ipynb
new file mode 100644
index 0000000..ac321aa
--- /dev/null
+++ b/ipynb/wlgen/rtapp_examples.ipynb
@@ -0,0 +1,632 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "import logging\n",
+    "reload(logging)\n",
+    "logging.basicConfig(\n",
+    "    format='%(asctime)-9s %(levelname)-8s: %(message)s',\n",
+    "    datefmt='%I:%M:%S')\n",
+    "\n",
+    "# Enable logging at INFO level\n",
+    "logging.getLogger().setLevel(logging.INFO)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Populating the interactive namespace from numpy and matplotlib\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Generate plots inline\n",
+    "%pylab inline\n",
+    "\n",
+    "import json\n",
+    "import os\n",
+    "\n",
+    "# Support to access the remote target\n",
+    "import devlib\n",
+    "from env import TestEnv\n",
+    "\n",
+    "# Support to configure and run RTApp based workloads\n",
+    "from wlgen import RTA"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Test environment setup"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "03:34:27  INFO    :         Target - Using base path: /home/derkling/Code/schedtest\n",
+      "03:34:27  INFO    :         Target - Loading custom (inline) target configuration\n",
+      "03:34:27  INFO    :         Target - Connecing host target with: {'username': 'derkling', 'password': ''}\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "sudo password:········\n"
+     ]
+    },
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "03:34:31  INFO    :         Target - Initializing target workdir [/tmp]\n",
+      "03:34:31  INFO    : Target topology: [[0, 1, 2, 3, 4, 5, 6, 7]]\n",
+      "03:34:31  WARNING :         Target - Unable to identify cluster frequencies\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Let's use the local host as a target\n",
+    "te = TestEnv(\n",
+    "    target_conf={\n",
+    "        \"platform\": 'host',\n",
+    "        \"username\": 'put_here_your_username'\n",
+    "    })"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Create a new RTA workload generator object"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The wlgen::RTA class is a workload generator which exposes an API to configure\n",
+    "RTApp based workload as well as to execute them on a target."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "03:34:31  INFO    : Setup new workload example\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Create a new RTApp workload generator\n",
+    "rtapp = RTA(\n",
+    "    \n",
+    "    target=te.target, # Target execution on the local machine\n",
+    "    \n",
+    "    name='example', # This is the name of the JSON configuration file reporting\n",
+    "                    # the generated RTApp configuration\n",
+    "    \n",
+    "    calibration={0: 10, 1: 11, 2: 12, 3: 13} # These are a set of fake\n",
+    "                                             # calibration values\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Workload Generation Examples"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Single periodic task"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "An RTApp workload is defined by specifying a **kind**, which represents the way\n",
+    "we want to defined the behavior of each task.<br>\n",
+    "The most common kind is **profile**, which allows to define each task using one\n",
+    "of the predefined **profile** supported by the RTA base class.<br>\n",
+    "<br>\n",
+    "The following example shows how to generate a \"periodic\" task<br>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {
+    "code_folding": [],
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "03:34:31  INFO    : Workload duration defined by longest task\n",
+      "03:34:31  INFO    : Default policy: SCHED_OTHER\n",
+      "03:34:31  INFO    : ------------------------\n",
+      "03:34:31  INFO    : task [task_per20], sched: {'policy': 'FIFO'}\n",
+      "03:34:31  INFO    :  | calibration CPU: 0\n",
+      "03:34:31  INFO    :  | loops count: 1\n",
+      "03:34:31  INFO    :  + phase_000001: duration 5.000000 [s] (50 loops)\n",
+      "03:34:31  INFO    :  |  period   100000 [us], duty_cycle  20 %\n",
+      "03:34:31  INFO    :  |  run_time  20000 [us], sleep_time  80000 [us]\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Configure this RTApp instance to:\n",
+    "rtapp.conf(\n",
+    "    \n",
+    "    # 1. generate a \"profile based\" set of tasks\n",
+    "    kind='profile',\n",
+    "    \n",
+    "    # 2. define the \"profile\" of each task\n",
+    "    params={\n",
+    "        \n",
+    "        # 3. PERIODIC task\n",
+    "        # \n",
+    "        # This class defines a task which load is periodic with a configured\n",
+    "        # period and duty-cycle.\n",
+    "        # \n",
+    "        # This class is a specialization of the 'pulse' class since a periodic\n",
+    "        # load is generated as a sequence of pulse loads.\n",
+    "        # \n",
+    "        # Args:\n",
+    "        #     cuty_cycle_pct  (int, [0-100]): the pulses load [%]\n",
+    "        #                                     default: 50[%]\n",
+    "        #     duration_s  (float): the duration in [s] of the entire workload\n",
+    "        #                          default: 1.0[s]\n",
+    "        #     period_ms   (float): the period used to define the load in [ms]\n",
+    "        #                          default: 100.0[ms]\n",
+    "        #     delay_s     (float): the delay in [s] before ramp start\n",
+    "        #                          default: 0[s]\n",
+    "        #     sched       (dict):  the scheduler configuration for this task\n",
+    "        'task_per20': RTA.periodic(\n",
+    "            period_ms=100,         # period\n",
+    "            duty_cycle_pct=20,     # duty cycle\n",
+    "            duration_s=5,          # duration\n",
+    "            cpus=None,             # run on all CPUS\n",
+    "            sched={\n",
+    "                \"policy\": \"FIFO\",  # Run this task as a SCHED_FIFO task\n",
+    "            },\n",
+    "            delay_s=0              # start at the start of RTApp\n",
+    "        ),\n",
+    "        \n",
+    "    },\n",
+    "    \n",
+    "    # 4. use this folder for task logfiles\n",
+    "    run_dir='/tmp'\n",
+    "    \n",
+    ");"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The output of the previous cell reports the main properties of the generated\n",
+    "tasks. Thus for example we see that the first task is configure to be:\n",
+    "1. named **task_per20**\n",
+    "2. will be executed as a **SCHED_FIFO** task\n",
+    "3. generating a load which is **calibrated** with respect to the **CPU 0**\n",
+    "3. with one single \"phase\" which defines a peripodic load for the **duration** of **5[s]**\n",
+    "4. that periodic load consistes of **50 cycles**\n",
+    "5. each cycle has a **period** of **100[ms]** and a **duty-cycle** of **20%**\n",
+    "6. which means that the task, for every cycle, will **run** for **20[ms]** and then sleep for **20[ms]** \n",
+    "\n",
+    "All these properties are translated into a JSON configuration file for RTApp.<br>\n",
+    "Let see what it looks like the generated configuration file:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "    \"tasks\": {\n",
+      "        \"task_per20\": {\n",
+      "            \"policy\": \"SCHED_FIFO\", \n",
+      "            \"phases\": {\n",
+      "                \"p000001\": {\n",
+      "                    \"run\": 20000, \n",
+      "                    \"timer\": {\n",
+      "                        \"ref\": \"task_per20\", \n",
+      "                        \"period\": 100000\n",
+      "                    }, \n",
+      "                    \"loop\": 50\n",
+      "                }\n",
+      "            }, \n",
+      "            \"loop\": 1\n",
+      "        }\n",
+      "    }, \n",
+      "    \"global\": {\n",
+      "        \"duration\": -1, \n",
+      "        \"logdir\": \"/tmp\", \n",
+      "        \"default_policy\": \"SCHED_OTHER\", \n",
+      "        \"calibration\": 10\n",
+      "    }\n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Dump the configured JSON file for that task\n",
+    "with open(\"./example_00.json\") as fh:\n",
+    "    rtapp_config = json.load(fh)\n",
+    "print json.dumps(rtapp_config, indent=4)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Workload mix"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Using the wlgen::RTA workload generator we can easily create multiple tasks, each one with different \"profiles\", which are executed once the rtapp application is started in the target.<br>\n",
+    "<br>\n",
+    "In the following example we configure a workload mix composed by a RAMP task, a STEP task and a PULSE task:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {
+    "code_folding": [],
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "03:34:31  INFO    : Workload duration defined by longest task\n",
+      "03:34:31  INFO    : Default policy: SCHED_OTHER\n",
+      "03:34:31  INFO    : ------------------------\n",
+      "03:34:31  INFO    : task [task_pls5-80], sched: using default policy\n",
+      "03:34:31  INFO    :  | start delay: 0.500000 [s]\n",
+      "03:34:31  INFO    :  | calibration CPU: 0\n",
+      "03:34:31  INFO    :  | loops count: 1\n",
+      "03:34:31  INFO    :  + phase_000001: duration 1.000000 [s] (10 loops)\n",
+      "03:34:31  INFO    :  |  period   100000 [us], duty_cycle  65 %\n",
+      "03:34:31  INFO    :  |  run_time  65000 [us], sleep_time  35000 [us]\n",
+      "03:34:31  INFO    :  + phase_000002: duration 1.000000 [s] (10 loops)\n",
+      "03:34:31  INFO    :  |  period   100000 [us], duty_cycle   5 %\n",
+      "03:34:31  INFO    :  |  run_time   5000 [us], sleep_time  95000 [us]\n",
+      "03:34:31  INFO    : ------------------------\n",
+      "03:34:31  INFO    : task [task_rmp20_5-60], sched: using default policy\n",
+      "03:34:31  INFO    :  | calibration CPU: 0\n",
+      "03:34:31  INFO    :  | loops count: 1\n",
+      "03:34:31  INFO    :  | CPUs affinity: 0\n",
+      "03:34:31  INFO    :  + phase_000001: duration 1.000000 [s] (10 loops)\n",
+      "03:34:31  INFO    :  |  period   100000 [us], duty_cycle   5 %\n",
+      "03:34:31  INFO    :  |  run_time   5000 [us], sleep_time  95000 [us]\n",
+      "03:34:31  INFO    :  + phase_000002: duration 1.000000 [s] (10 loops)\n",
+      "03:34:31  INFO    :  |  period   100000 [us], duty_cycle  25 %\n",
+      "03:34:31  INFO    :  |  run_time  25000 [us], sleep_time  75000 [us]\n",
+      "03:34:31  INFO    :  + phase_000003: duration 1.000000 [s] (10 loops)\n",
+      "03:34:31  INFO    :  |  period   100000 [us], duty_cycle  45 %\n",
+      "03:34:31  INFO    :  |  run_time  45000 [us], sleep_time  55000 [us]\n",
+      "03:34:31  INFO    :  + phase_000004: duration 1.000000 [s] (10 loops)\n",
+      "03:34:31  INFO    :  |  period   100000 [us], duty_cycle  65 %\n",
+      "03:34:31  INFO    :  |  run_time  65000 [us], sleep_time  35000 [us]\n",
+      "03:34:31  INFO    : ------------------------\n",
+      "03:34:31  INFO    : task [task_stp10-50], sched: using default policy\n",
+      "03:34:31  INFO    :  | start delay: 0.500000 [s]\n",
+      "03:34:31  INFO    :  | calibration CPU: 0\n",
+      "03:34:31  INFO    :  | loops count: 1\n",
+      "03:34:31  INFO    :  + phase_000001: sleep 1.000000 [s]\n",
+      "03:34:31  INFO    :  + phase_000002: duration 1.000000 [s] (10 loops)\n",
+      "03:34:31  INFO    :  |  period   100000 [us], duty_cycle  50 %\n",
+      "03:34:31  INFO    :  |  run_time  50000 [us], sleep_time  50000 [us]\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Configure this RTApp instance to:\n",
+    "rtapp.conf(\n",
+    "    # 1. generate a \"profile based\" set of tasks\n",
+    "    kind='profile',\n",
+    "    \n",
+    "    # 2. define the \"profile\" of each task\n",
+    "    params={\n",
+    "        \n",
+    "        # 3. RAMP task\n",
+    "        #\n",
+    "        # This class defines a task which load is a ramp with a configured number\n",
+    "        # of steps according to the input parameters.\n",
+    "        # \n",
+    "        # Args:\n",
+    "        #     start_pct (int, [0-100]): the initial load [%], (default 0[%])\n",
+    "        #     end_pct   (int, [0-100]): the final load [%], (default 100[%])\n",
+    "        #     delta_pct (int, [0-100]): the load increase/decrease [%],\n",
+    "        #                               default: 10[%]\n",
+    "        #                               increase if start_prc < end_prc\n",
+    "        #                               decrease  if start_prc > end_prc\n",
+    "        #     time_s    (float): the duration in [s] of each load step\n",
+    "        #                        default: 1.0[s]\n",
+    "        #     period_ms (float): the period used to define the load in [ms]\n",
+    "        #                        default: 100.0[ms]\n",
+    "        #     delay_s   (float): the delay in [s] before ramp start\n",
+    "        #                        default: 0[s]\n",
+    "        #     loops     (int):   number of time to repeat the ramp, with the\n",
+    "        #                        specified delay in between\n",
+    "        #                        default: 0\n",
+    "        #     sched     (dict): the scheduler configuration for this task\n",
+    "        #     cpus      (list): the list of CPUs on which task can run\n",
+    "        'task_rmp20_5-60': RTA.ramp(\n",
+    "            period_ms=100,         # period\n",
+    "            start_pct=5,           # intial load\n",
+    "            end_pct=65,            # end load\n",
+    "            delta_pct=20,          # load % increase...\n",
+    "            time_s=1,              # ... every 1[s]\n",
+    "            cpus=\"0\"               # run just on first CPU\n",
+    "        ),\n",
+    "        \n",
+    "        # 4. STEP task\n",
+    "        # \n",
+    "        # This class defines a task which load is a step with a configured\n",
+    "        # initial and final load.\n",
+    "        # \n",
+    "        # Args:\n",
+    "        # start_pct (int, [0-100]): the initial load [%]\n",
+    "        #                               default 0[%])\n",
+    "        # end_pct   (int, [0-100]): the final load [%]\n",
+    "        #                               default 100[%]\n",
+    "        # time_s    (float): the duration in [s] of the start and end load\n",
+    "        #                        default: 1.0[s]\n",
+    "        # period_ms (float): the period used to define the load in [ms]\n",
+    "        #                        default 100.0[ms]\n",
+    "        # delay_s   (float): the delay in [s] before ramp start\n",
+    "        #                        default 0[s]\n",
+    "        # loops     (int):   number of time to repeat the ramp, with the\n",
+    "        #                        specified delay in between\n",
+    "        #                        default: 0\n",
+    "        # sched     (dict): the scheduler configuration for this task\n",
+    "        # cpus      (list): the list of CPUs on which task can run\n",
+    "        'task_stp10-50': RTA.step(\n",
+    "            period_ms=100,         # period\n",
+    "            start_pct=0,           # intial load\n",
+    "            end_pct=50,            # end load\n",
+    "            time_s=1,              # ... every 1[s]\n",
+    "            delay_s=0.5            # start .5[s] after the start of RTApp\n",
+    "        ),\n",
+    "        \n",
+    "        # 5. PULSE task\n",
+    "        #\n",
+    "        # This class defines a task which load is a pulse with a configured\n",
+    "        # initial and final load.\n",
+    "        # \n",
+    "        # The main difference with the 'step' class is that a pulse workload is\n",
+    "        # by definition a 'step down', i.e. the workload switch from an finial\n",
+    "        # load to a final one which is always lower than the initial one.\n",
+    "        # Moreover, a pulse load does not generate a sleep phase in case of 0[%]\n",
+    "        # load, i.e. the task ends as soon as the non null initial load has\n",
+    "        # completed.\n",
+    "        # \n",
+    "        # Args:\n",
+    "        #     start_pct (int, [0-100]): the initial load [%]\n",
+    "        #                               default: 0[%]\n",
+    "        #     end_pct   (int, [0-100]): the final load [%]\n",
+    "        #                               default: 100[%]\n",
+    "        #               NOTE: must be lower than start_pct value\n",
+    "        #     time_s    (float): the duration in [s] of the start and end load\n",
+    "        #                        default: 1.0[s]\n",
+    "        #                        NOTE: if end_pct is 0, the task end after the\n",
+    "        #                        start_pct period completed\n",
+    "        #     period_ms (float): the period used to define the load in [ms]\n",
+    "        #                        default: 100.0[ms]\n",
+    "        #     delay_s   (float): the delay in [s] before ramp start\n",
+    "        #                        default: 0[s]\n",
+    "        #     loops     (int):   number of time to repeat the ramp, with the\n",
+    "        #                        specified delay in between\n",
+    "        #                        default: 0\n",
+    "        #     sched     (dict):  the scheduler configuration for this task\n",
+    "        #     cpus      (list):  the list of CPUs on which task can run\n",
+    "        'task_pls5-80': RTA.pulse(\n",
+    "            period_ms=100,         # period\n",
+    "            start_pct=65,          # intial load\n",
+    "            end_pct=5,             # end load\n",
+    "            time_s=1,              # ... every 1[s]\n",
+    "            delay_s=0.5            # start .5[s] after the start of RTApp\n",
+    "        ),\n",
+    "        \n",
+    "        \n",
+    "    },\n",
+    "    \n",
+    "    # 6. use this folder for task logfiles\n",
+    "    run_dir='/tmp'\n",
+    "    \n",
+    ");"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "    \"tasks\": {\n",
+      "        \"task_rmp20_5-60\": {\n",
+      "            \"policy\": \"SCHED_OTHER\", \n",
+      "            \"phases\": {\n",
+      "                \"p000004\": {\n",
+      "                    \"run\": 65000, \n",
+      "                    \"timer\": {\n",
+      "                        \"ref\": \"task_rmp20_5-60\", \n",
+      "                        \"period\": 100000\n",
+      "                    }, \n",
+      "                    \"loop\": 10\n",
+      "                }, \n",
+      "                \"p000003\": {\n",
+      "                    \"run\": 45000, \n",
+      "                    \"timer\": {\n",
+      "                        \"ref\": \"task_rmp20_5-60\", \n",
+      "                        \"period\": 100000\n",
+      "                    }, \n",
+      "                    \"loop\": 10\n",
+      "                }, \n",
+      "                \"p000002\": {\n",
+      "                    \"run\": 25000, \n",
+      "                    \"timer\": {\n",
+      "                        \"ref\": \"task_rmp20_5-60\", \n",
+      "                        \"period\": 100000\n",
+      "                    }, \n",
+      "                    \"loop\": 10\n",
+      "                }, \n",
+      "                \"p000001\": {\n",
+      "                    \"run\": 5000, \n",
+      "                    \"timer\": {\n",
+      "                        \"ref\": \"task_rmp20_5-60\", \n",
+      "                        \"period\": 100000\n",
+      "                    }, \n",
+      "                    \"loop\": 10\n",
+      "                }\n",
+      "            }, \n",
+      "            \"cpus\": [\n",
+      "                0\n",
+      "            ], \n",
+      "            \"loop\": 1\n",
+      "        }, \n",
+      "        \"task_pls5-80\": {\n",
+      "            \"policy\": \"SCHED_OTHER\", \n",
+      "            \"phases\": {\n",
+      "                \"p000002\": {\n",
+      "                    \"run\": 5000, \n",
+      "                    \"timer\": {\n",
+      "                        \"ref\": \"task_pls5-80\", \n",
+      "                        \"period\": 100000\n",
+      "                    }, \n",
+      "                    \"loop\": 10\n",
+      "                }, \n",
+      "                \"p000001\": {\n",
+      "                    \"run\": 65000, \n",
+      "                    \"timer\": {\n",
+      "                        \"ref\": \"task_pls5-80\", \n",
+      "                        \"period\": 100000\n",
+      "                    }, \n",
+      "                    \"loop\": 10\n",
+      "                }, \n",
+      "                \"p000000\": {\n",
+      "                    \"sleep\": 500000\n",
+      "                }\n",
+      "            }, \n",
+      "            \"loop\": 1\n",
+      "        }, \n",
+      "        \"task_stp10-50\": {\n",
+      "            \"policy\": \"SCHED_OTHER\", \n",
+      "            \"phases\": {\n",
+      "                \"p000002\": {\n",
+      "                    \"run\": 50000, \n",
+      "                    \"timer\": {\n",
+      "                        \"ref\": \"task_stp10-50\", \n",
+      "                        \"period\": 100000\n",
+      "                    }, \n",
+      "                    \"loop\": 10\n",
+      "                }, \n",
+      "                \"p000001\": {\n",
+      "                    \"sleep\": 1000000, \n",
+      "                    \"loop\": 1\n",
+      "                }, \n",
+      "                \"p000000\": {\n",
+      "                    \"sleep\": 500000\n",
+      "                }\n",
+      "            }, \n",
+      "            \"loop\": 1\n",
+      "        }\n",
+      "    }, \n",
+      "    \"global\": {\n",
+      "        \"duration\": -1, \n",
+      "        \"logdir\": \"/tmp\", \n",
+      "        \"default_policy\": \"SCHED_OTHER\", \n",
+      "        \"calibration\": 10\n",
+      "    }\n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Dump the configured JSON file for that task\n",
+    "with open(\"./example_00.json\") as fh:\n",
+    "    rtapp_config = json.load(fh)\n",
+    "print json.dumps(rtapp_config, indent=4)"
+   ]
+  }
+ ],
+ "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.9"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 0
+}