{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib nbagg\n",
    "import time\n",
    "start_time = time.time()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Variance of SAXS data\n",
    "\n",
    "There has been a long discussion about the validity (or not) of pixel splitting regarding the propagation of errors [#520](https://github.com/silx-kit/pyFAI/issues/520) [#882](https://github.com/silx-kit/pyFAI/issues/882) [#883](https://github.com/silx-kit/pyFAI/issues/883).\n",
    "So we will develop a mathematical model for a SAXS experiment and validate it in the case of a SAXS approximation (i.e. no solid-angle correction, no polarisation effect, and of course small angled $\\theta = sin(\\theta) = tan(\\theta)$)\n",
    "\n",
    "## System under study\n",
    "\n",
    "Let's do a numerical experiment, simulating the following experiment:\n",
    "\n",
    "* Detector: 1024x1024 square pixels of 100µm each, assumed to be poissonian. \n",
    "* Geometry: The detector is placed at 1m from the sample, the beam center is in the corner of the detector\n",
    "* Intensity: the maximum signal on the detector is 10 000 photons per pixel, each pixel having a minimum count of a hundreed.\n",
    "* Wavelength: 1 Angstrom\n",
    "* During the first part of the studdy, the solid-angle correction will be discarded, same for solid angle corrections.\n",
    "* Pixel splitting is disables, for this we use one of the folloging rebinning engines:\n",
    "  - numpy: the slowest available in pyFAI\n",
    "  - histogram: implemented in cython\n",
    "  - nosplit_csr: using a look-up table\n",
    "  - nosplit_csr_ocl_gpu: which offloads the calculation on the GPU.\n",
    "  \n",
    "  We will check they all provide the same numerical result\n",
    "  \n",
    "Now we define some constants for the studdy. The dictionary *kwarg* contains the parameters used for azimuthal integration. This ensures the number of bins for the regrouping or correction like $\\Omega$ and polarization are always the same."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "pix = 100e-6\n",
    "shape = (1024, 1024)\n",
    "npt = 1000\n",
    "nimg = 1000\n",
    "wl = 1e-10\n",
    "I0 = 1e4\n",
    "Rg = 1.\n",
    "kwarg = {\"npt\":npt, \n",
    "         \"correctSolidAngle\":False, \n",
    "         \"polarization_factor\":None,\n",
    "         \"safe\":False}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.16.0-beta0\n",
      "Detector Detector\t Spline= None\t PixelSize= 1.000e-04, 1.000e-04 m\n"
     ]
    }
   ],
   "source": [
    "import numpy\n",
    "from scipy.stats import chi2 as chi2_dist\n",
    "from matplotlib.pyplot import subplots\n",
    "from matplotlib.colors import LogNorm\n",
    "import pyFAI\n",
    "print(pyFAI.version)\n",
    "from pyFAI.detectors import Detector\n",
    "from pyFAI.azimuthalIntegrator import AzimuthalIntegrator\n",
    "from pyFAI.gui import jupyter\n",
    "detector = Detector(pix, pix)\n",
    "detector.shape = detector.max_shape = shape\n",
    "print(detector)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We define in *ai_init* the geometry, the detector and the wavelength. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Detector Detector\t Spline= None\t PixelSize= 1.000e-04, 1.000e-04 m\n",
      "Wavelength= 1.000000e-10m\n",
      "SampleDetDist= 1.000000e+00m\tPONI= 0.000000e+00, 0.000000e+00m\trot1=0.000000  rot2= 0.000000  rot3= 0.000000 rad\n",
      "DirectBeamDist= 1000.000mm\tCenter: x=0.000, y=0.000 pix\tTilt=0.000 deg  tiltPlanRotation= 0.000 deg\n",
      "Solid angle: maxi= 9.999999925000007e-09 mini= 9.693768051738431e-09, ratio= 0.9693768124441685\n"
     ]
    }
   ],
   "source": [
    "ai_init = {\"dist\":1.0, \n",
    "           \"poni1\":0.0, \n",
    "           \"poni2\":0.0, \n",
    "           \"rot1\":0.0,\n",
    "           \"rot2\":0.0,\n",
    "           \"rot3\":0.0,\n",
    "           \"detector\":detector, \n",
    "           \"wavelength\":wl}\n",
    "ai = AzimuthalIntegrator(**ai_init)\n",
    "print(ai)          \n",
    "\n",
    "#Solid consideration:\n",
    "Ω  = ai.solidAngleArray(detector.shape, absolute=True)\n",
    "\n",
    "print(\"Solid angle: maxi= {} mini= {}, ratio= {}\".format(Ω.max(), Ω.min(), Ω.min()/Ω.max()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "/* Put everything inside the global mpl namespace */\n",
       "window.mpl = {};\n",
       "\n",
       "\n",
       "mpl.get_websocket_type = function() {\n",
       "    if (typeof(WebSocket) !== 'undefined') {\n",
       "        return WebSocket;\n",
       "    } else if (typeof(MozWebSocket) !== 'undefined') {\n",
       "        return MozWebSocket;\n",
       "    } else {\n",
       "        alert('Your browser does not have WebSocket support.' +\n",
       "              'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
       "              'Firefox 4 and 5 are also supported but you ' +\n",
       "              'have to enable WebSockets in about:config.');\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
       "    this.id = figure_id;\n",
       "\n",
       "    this.ws = websocket;\n",
       "\n",
       "    this.supports_binary = (this.ws.binaryType != undefined);\n",
       "\n",
       "    if (!this.supports_binary) {\n",
       "        var warnings = document.getElementById(\"mpl-warnings\");\n",
       "        if (warnings) {\n",
       "            warnings.style.display = 'block';\n",
       "            warnings.textContent = (\n",
       "                \"This browser does not support binary websocket messages. \" +\n",
       "                    \"Performance may be slow.\");\n",
       "        }\n",
       "    }\n",
       "\n",
       "    this.imageObj = new Image();\n",
       "\n",
       "    this.context = undefined;\n",
       "    this.message = undefined;\n",
       "    this.canvas = undefined;\n",
       "    this.rubberband_canvas = undefined;\n",
       "    this.rubberband_context = undefined;\n",
       "    this.format_dropdown = undefined;\n",
       "\n",
       "    this.image_mode = 'full';\n",
       "\n",
       "    this.root = $('<div/>');\n",
       "    this._root_extra_style(this.root)\n",
       "    this.root.attr('style', 'display: inline-block');\n",
       "\n",
       "    $(parent_element).append(this.root);\n",
       "\n",
       "    this._init_header(this);\n",
       "    this._init_canvas(this);\n",
       "    this._init_toolbar(this);\n",
       "\n",
       "    var fig = this;\n",
       "\n",
       "    this.waiting = false;\n",
       "\n",
       "    this.ws.onopen =  function () {\n",
       "            fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
       "            fig.send_message(\"send_image_mode\", {});\n",
       "            if (mpl.ratio != 1) {\n",
       "                fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
       "            }\n",
       "            fig.send_message(\"refresh\", {});\n",
       "        }\n",
       "\n",
       "    this.imageObj.onload = function() {\n",
       "            if (fig.image_mode == 'full') {\n",
       "                // Full images could contain transparency (where diff images\n",
       "                // almost always do), so we need to clear the canvas so that\n",
       "                // there is no ghosting.\n",
       "                fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
       "            }\n",
       "            fig.context.drawImage(fig.imageObj, 0, 0);\n",
       "        };\n",
       "\n",
       "    this.imageObj.onunload = function() {\n",
       "        fig.ws.close();\n",
       "    }\n",
       "\n",
       "    this.ws.onmessage = this._make_on_message_function(this);\n",
       "\n",
       "    this.ondownload = ondownload;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_header = function() {\n",
       "    var titlebar = $(\n",
       "        '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
       "        'ui-helper-clearfix\"/>');\n",
       "    var titletext = $(\n",
       "        '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
       "        'text-align: center; padding: 3px;\"/>');\n",
       "    titlebar.append(titletext)\n",
       "    this.root.append(titlebar);\n",
       "    this.header = titletext[0];\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_canvas = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var canvas_div = $('<div/>');\n",
       "\n",
       "    canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
       "\n",
       "    function canvas_keyboard_event(event) {\n",
       "        return fig.key_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    canvas_div.keydown('key_press', canvas_keyboard_event);\n",
       "    canvas_div.keyup('key_release', canvas_keyboard_event);\n",
       "    this.canvas_div = canvas_div\n",
       "    this._canvas_extra_style(canvas_div)\n",
       "    this.root.append(canvas_div);\n",
       "\n",
       "    var canvas = $('<canvas/>');\n",
       "    canvas.addClass('mpl-canvas');\n",
       "    canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
       "\n",
       "    this.canvas = canvas[0];\n",
       "    this.context = canvas[0].getContext(\"2d\");\n",
       "\n",
       "    var backingStore = this.context.backingStorePixelRatio ||\n",
       "\tthis.context.webkitBackingStorePixelRatio ||\n",
       "\tthis.context.mozBackingStorePixelRatio ||\n",
       "\tthis.context.msBackingStorePixelRatio ||\n",
       "\tthis.context.oBackingStorePixelRatio ||\n",
       "\tthis.context.backingStorePixelRatio || 1;\n",
       "\n",
       "    mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
       "\n",
       "    var rubberband = $('<canvas/>');\n",
       "    rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
       "\n",
       "    var pass_mouse_events = true;\n",
       "\n",
       "    canvas_div.resizable({\n",
       "        start: function(event, ui) {\n",
       "            pass_mouse_events = false;\n",
       "        },\n",
       "        resize: function(event, ui) {\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "        stop: function(event, ui) {\n",
       "            pass_mouse_events = true;\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "    });\n",
       "\n",
       "    function mouse_event_fn(event) {\n",
       "        if (pass_mouse_events)\n",
       "            return fig.mouse_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    rubberband.mousedown('button_press', mouse_event_fn);\n",
       "    rubberband.mouseup('button_release', mouse_event_fn);\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband.mousemove('motion_notify', mouse_event_fn);\n",
       "\n",
       "    rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
       "    rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
       "\n",
       "    canvas_div.on(\"wheel\", function (event) {\n",
       "        event = event.originalEvent;\n",
       "        event['data'] = 'scroll'\n",
       "        if (event.deltaY < 0) {\n",
       "            event.step = 1;\n",
       "        } else {\n",
       "            event.step = -1;\n",
       "        }\n",
       "        mouse_event_fn(event);\n",
       "    });\n",
       "\n",
       "    canvas_div.append(canvas);\n",
       "    canvas_div.append(rubberband);\n",
       "\n",
       "    this.rubberband = rubberband;\n",
       "    this.rubberband_canvas = rubberband[0];\n",
       "    this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
       "    this.rubberband_context.strokeStyle = \"#000000\";\n",
       "\n",
       "    this._resize_canvas = function(width, height) {\n",
       "        // Keep the size of the canvas, canvas container, and rubber band\n",
       "        // canvas in synch.\n",
       "        canvas_div.css('width', width)\n",
       "        canvas_div.css('height', height)\n",
       "\n",
       "        canvas.attr('width', width * mpl.ratio);\n",
       "        canvas.attr('height', height * mpl.ratio);\n",
       "        canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
       "\n",
       "        rubberband.attr('width', width);\n",
       "        rubberband.attr('height', height);\n",
       "    }\n",
       "\n",
       "    // Set the figure to an initial 600x600px, this will subsequently be updated\n",
       "    // upon first draw.\n",
       "    this._resize_canvas(600, 600);\n",
       "\n",
       "    // Disable right mouse context menu.\n",
       "    $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
       "        return false;\n",
       "    });\n",
       "\n",
       "    function set_focus () {\n",
       "        canvas.focus();\n",
       "        canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    window.setTimeout(set_focus, 100);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items) {\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) {\n",
       "            // put a spacer in here.\n",
       "            continue;\n",
       "        }\n",
       "        var button = $('<button/>');\n",
       "        button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
       "                        'ui-button-icon-only');\n",
       "        button.attr('role', 'button');\n",
       "        button.attr('aria-disabled', 'false');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "\n",
       "        var icon_img = $('<span/>');\n",
       "        icon_img.addClass('ui-button-icon-primary ui-icon');\n",
       "        icon_img.addClass(image);\n",
       "        icon_img.addClass('ui-corner-all');\n",
       "\n",
       "        var tooltip_span = $('<span/>');\n",
       "        tooltip_span.addClass('ui-button-text');\n",
       "        tooltip_span.html(tooltip);\n",
       "\n",
       "        button.append(icon_img);\n",
       "        button.append(tooltip_span);\n",
       "\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    var fmt_picker_span = $('<span/>');\n",
       "\n",
       "    var fmt_picker = $('<select/>');\n",
       "    fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
       "    fmt_picker_span.append(fmt_picker);\n",
       "    nav_element.append(fmt_picker_span);\n",
       "    this.format_dropdown = fmt_picker[0];\n",
       "\n",
       "    for (var ind in mpl.extensions) {\n",
       "        var fmt = mpl.extensions[ind];\n",
       "        var option = $(\n",
       "            '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
       "        fmt_picker.append(option)\n",
       "    }\n",
       "\n",
       "    // Add hover states to the ui-buttons\n",
       "    $( \".ui-button\" ).hover(\n",
       "        function() { $(this).addClass(\"ui-state-hover\");},\n",
       "        function() { $(this).removeClass(\"ui-state-hover\");}\n",
       "    );\n",
       "\n",
       "    var status_bar = $('<span class=\"mpl-message\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
       "    // which will in turn request a refresh of the image.\n",
       "    this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_message = function(type, properties) {\n",
       "    properties['type'] = type;\n",
       "    properties['figure_id'] = this.id;\n",
       "    this.ws.send(JSON.stringify(properties));\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_draw_message = function() {\n",
       "    if (!this.waiting) {\n",
       "        this.waiting = true;\n",
       "        this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
       "    }\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    var format_dropdown = fig.format_dropdown;\n",
       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
       "    fig.ondownload(fig, format);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
       "    var size = msg['size'];\n",
       "    if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
       "        fig._resize_canvas(size[0], size[1]);\n",
       "        fig.send_message(\"refresh\", {});\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
       "    var x0 = msg['x0'] / mpl.ratio;\n",
       "    var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
       "    var x1 = msg['x1'] / mpl.ratio;\n",
       "    var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
       "    x0 = Math.floor(x0) + 0.5;\n",
       "    y0 = Math.floor(y0) + 0.5;\n",
       "    x1 = Math.floor(x1) + 0.5;\n",
       "    y1 = Math.floor(y1) + 0.5;\n",
       "    var min_x = Math.min(x0, x1);\n",
       "    var min_y = Math.min(y0, y1);\n",
       "    var width = Math.abs(x1 - x0);\n",
       "    var height = Math.abs(y1 - y0);\n",
       "\n",
       "    fig.rubberband_context.clearRect(\n",
       "        0, 0, fig.canvas.width, fig.canvas.height);\n",
       "\n",
       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
       "    // Updates the figure title.\n",
       "    fig.header.textContent = msg['label'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
       "    var cursor = msg['cursor'];\n",
       "    switch(cursor)\n",
       "    {\n",
       "    case 0:\n",
       "        cursor = 'pointer';\n",
       "        break;\n",
       "    case 1:\n",
       "        cursor = 'default';\n",
       "        break;\n",
       "    case 2:\n",
       "        cursor = 'crosshair';\n",
       "        break;\n",
       "    case 3:\n",
       "        cursor = 'move';\n",
       "        break;\n",
       "    }\n",
       "    fig.rubberband_canvas.style.cursor = cursor;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
       "    fig.message.textContent = msg['message'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
       "    // Request the server to send over a new figure.\n",
       "    fig.send_draw_message();\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
       "    fig.image_mode = msg['mode'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Called whenever the canvas gets updated.\n",
       "    this.send_message(\"ack\", {});\n",
       "}\n",
       "\n",
       "// A function to construct a web socket function for onmessage handling.\n",
       "// Called in the figure constructor.\n",
       "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
       "    return function socket_on_message(evt) {\n",
       "        if (evt.data instanceof Blob) {\n",
       "            /* FIXME: We get \"Resource interpreted as Image but\n",
       "             * transferred with MIME type text/plain:\" errors on\n",
       "             * Chrome.  But how to set the MIME type?  It doesn't seem\n",
       "             * to be part of the websocket stream */\n",
       "            evt.data.type = \"image/png\";\n",
       "\n",
       "            /* Free the memory for the previous frames */\n",
       "            if (fig.imageObj.src) {\n",
       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
       "                    fig.imageObj.src);\n",
       "            }\n",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data);\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "        else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
       "            fig.imageObj.src = evt.data;\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        var msg = JSON.parse(evt.data);\n",
       "        var msg_type = msg['type'];\n",
       "\n",
       "        // Call the  \"handle_{type}\" callback, which takes\n",
       "        // the figure and JSON message as its only arguments.\n",
       "        try {\n",
       "            var callback = fig[\"handle_\" + msg_type];\n",
       "        } catch (e) {\n",
       "            console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        if (callback) {\n",
       "            try {\n",
       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
       "                callback(fig, msg);\n",
       "            } catch (e) {\n",
       "                console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
       "            }\n",
       "        }\n",
       "    };\n",
       "}\n",
       "\n",
       "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
       "mpl.findpos = function(e) {\n",
       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
       "    var targ;\n",
       "    if (!e)\n",
       "        e = window.event;\n",
       "    if (e.target)\n",
       "        targ = e.target;\n",
       "    else if (e.srcElement)\n",
       "        targ = e.srcElement;\n",
       "    if (targ.nodeType == 3) // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "\n",
       "    // jQuery normalizes the pageX and pageY\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    // offset() returns the position of the element relative to the document\n",
       "    var x = e.pageX - $(targ).offset().left;\n",
       "    var y = e.pageY - $(targ).offset().top;\n",
       "\n",
       "    return {\"x\": x, \"y\": y};\n",
       "};\n",
       "\n",
       "/*\n",
       " * return a copy of an object with only non-object keys\n",
       " * we need this to avoid circular references\n",
       " * http://stackoverflow.com/a/24161582/3208463\n",
       " */\n",
       "function simpleKeys (original) {\n",
       "  return Object.keys(original).reduce(function (obj, key) {\n",
       "    if (typeof original[key] !== 'object')\n",
       "        obj[key] = original[key]\n",
       "    return obj;\n",
       "  }, {});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.mouse_event = function(event, name) {\n",
       "    var canvas_pos = mpl.findpos(event)\n",
       "\n",
       "    if (name === 'button_press')\n",
       "    {\n",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * mpl.ratio;\n",
       "    var y = canvas_pos.y * mpl.ratio;\n",
       "\n",
       "    this.send_message(name, {x: x, y: y, button: event.button,\n",
       "                             step: event.step,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "\n",
       "    /* This prevents the web browser from automatically changing to\n",
       "     * the text insertion cursor when the button is pressed.  We want\n",
       "     * to control all of the cursor setting manually through the\n",
       "     * 'cursor' event from matplotlib */\n",
       "    event.preventDefault();\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    // Handle any extra behaviour associated with a key event\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.key_event = function(event, name) {\n",
       "\n",
       "    // Prevent repeat events\n",
       "    if (name == 'key_press')\n",
       "    {\n",
       "        if (event.which === this._key)\n",
       "            return;\n",
       "        else\n",
       "            this._key = event.which;\n",
       "    }\n",
       "    if (name == 'key_release')\n",
       "        this._key = null;\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which != 17)\n",
       "        value += \"ctrl+\";\n",
       "    if (event.altKey && event.which != 18)\n",
       "        value += \"alt+\";\n",
       "    if (event.shiftKey && event.which != 16)\n",
       "        value += \"shift+\";\n",
       "\n",
       "    value += 'k';\n",
       "    value += event.which.toString();\n",
       "\n",
       "    this._key_event_extra(event, name);\n",
       "\n",
       "    this.send_message(name, {key: value,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
       "    if (name == 'download') {\n",
       "        this.handle_save(this, null);\n",
       "    } else {\n",
       "        this.send_message(\"toolbar_button\", {name: name});\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
       "    this.message.textContent = tooltip;\n",
       "};\n",
       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
       "\n",
       "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
       "\n",
       "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
       "    // object with the appropriate methods. Currently this is a non binary\n",
       "    // socket, so there is still some room for performance tuning.\n",
       "    var ws = {};\n",
       "\n",
       "    ws.close = function() {\n",
       "        comm.close()\n",
       "    };\n",
       "    ws.send = function(m) {\n",
       "        //console.log('sending', m);\n",
       "        comm.send(m);\n",
       "    };\n",
       "    // Register the callback with on_msg.\n",
       "    comm.on_msg(function(msg) {\n",
       "        //console.log('receiving', msg['content']['data'], msg);\n",
       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
       "        ws.onmessage(msg['content']['data'])\n",
       "    });\n",
       "    return ws;\n",
       "}\n",
       "\n",
       "mpl.mpl_figure_comm = function(comm, msg) {\n",
       "    // This is the function which gets called when the mpl process\n",
       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
       "\n",
       "    var id = msg.content.data.id;\n",
       "    // Get hold of the div created by the display call when the Comm\n",
       "    // socket was opened in Python.\n",
       "    var element = $(\"#\" + id);\n",
       "    var ws_proxy = comm_websocket_adapter(comm)\n",
       "\n",
       "    function ondownload(figure, format) {\n",
       "        window.open(figure.imageObj.src);\n",
       "    }\n",
       "\n",
       "    var fig = new mpl.figure(id, ws_proxy,\n",
       "                           ondownload,\n",
       "                           element.get(0));\n",
       "\n",
       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
       "    // web socket which is closed, not our websocket->open comm proxy.\n",
       "    ws_proxy.onopen();\n",
       "\n",
       "    fig.parent_element = element.get(0);\n",
       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
       "    if (!fig.cell_info) {\n",
       "        console.error(\"Failed to find cell for figure\", id, fig);\n",
       "        return;\n",
       "    }\n",
       "\n",
       "    var output_index = fig.cell_info[2]\n",
       "    var cell = fig.cell_info[0];\n",
       "\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
       "    var width = fig.canvas.width/mpl.ratio\n",
       "    fig.root.unbind('remove')\n",
       "\n",
       "    // Update the output cell to use the data from the current canvas.\n",
       "    fig.push_to_output();\n",
       "    var dataURL = fig.canvas.toDataURL();\n",
       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
       "    // the notebook keyboard shortcuts fail.\n",
       "    IPython.keyboard_manager.enable()\n",
       "    $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
       "    fig.close_ws(fig, msg);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.close_ws = function(fig, msg){\n",
       "    fig.send_message('closing', msg);\n",
       "    // fig.ws.close()\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
       "    // Turn the data on the canvas into data in the output cell.\n",
       "    var width = this.canvas.width/mpl.ratio\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Tell IPython that the notebook contents must change.\n",
       "    IPython.notebook.set_dirty(true);\n",
       "    this.send_message(\"ack\", {});\n",
       "    var fig = this;\n",
       "    // Wait a second, then push the new image to the DOM so\n",
       "    // that it is saved nicely (might be nice to debounce this).\n",
       "    setTimeout(function () { fig.push_to_output() }, 1000);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items){\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) { continue; };\n",
       "\n",
       "        var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    // Add the status bar.\n",
       "    var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "\n",
       "    // Add the close button to the window.\n",
       "    var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
       "    var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
       "    button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
       "    button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
       "    buttongrp.append(button);\n",
       "    var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
       "    titlebar.prepend(buttongrp);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(el){\n",
       "    var fig = this\n",
       "    el.on(\"remove\", function(){\n",
       "\tfig.close_ws(fig, {});\n",
       "    });\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(el){\n",
       "    // this is important to make the div 'focusable\n",
       "    el.attr('tabindex', 0)\n",
       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
       "    // off when our div gets focus\n",
       "\n",
       "    // location in version 3\n",
       "    if (IPython.notebook.keyboard_manager) {\n",
       "        IPython.notebook.keyboard_manager.register_events(el);\n",
       "    }\n",
       "    else {\n",
       "        // location in version 2\n",
       "        IPython.keyboard_manager.register_events(el);\n",
       "    }\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager)\n",
       "        manager = IPython.keyboard_manager;\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which == 13) {\n",
       "        this.canvas_div.blur();\n",
       "        event.shiftKey = false;\n",
       "        // Send a \"J\" for go to next cell\n",
       "        event.which = 74;\n",
       "        event.keyCode = 74;\n",
       "        manager.command_mode();\n",
       "        manager.handle_keydown(event);\n",
       "    }\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.find_output_cell = function(html_output) {\n",
       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
       "    // IPython event is triggered only after the cells have been serialised, which for\n",
       "    // our purposes (turning an active figure into a static one), is too late.\n",
       "    var cells = IPython.notebook.get_cells();\n",
       "    var ncells = cells.length;\n",
       "    for (var i=0; i<ncells; i++) {\n",
       "        var cell = cells[i];\n",
       "        if (cell.cell_type === 'code'){\n",
       "            for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
       "                var data = cell.output_area.outputs[j];\n",
       "                if (data.data) {\n",
       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
       "                    data = data.data;\n",
       "                }\n",
       "                if (data['text/html'] == html_output) {\n",
       "                    return [cell, data, j];\n",
       "                }\n",
       "            }\n",
       "        }\n",
       "    }\n",
       "}\n",
       "\n",
       "// Register the function which deals with the matplotlib target/channel.\n",
       "// The kernel may be null if the page has been refreshed.\n",
       "if (IPython.notebook.kernel != null) {\n",
       "    IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
       "}\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAj0AAAGtCAYAAAD9H8XfAAAgAElEQVR4nO3deXRU9d3H8Rv2ZLJDEhAkpFCIPMoihi0oUNmeLgLSQisCatGyeKx9Ci5BCaUGWlcqVmpwAWopBpECxYUHRMAHEBArENzLopKCBoiQhWyf548ebh0y4SYhMJDv+3XOPce5987kl/Grn8+ZuTNxBAAAYIAT7AUAAABcCJQeAABgAqUHAACYQOkBAAAmUHoAAIAJlB4AAGACpQcAAJhA6QEAACZQegAAgAmUHgAAYAKlBwAAmEDpAQAAJlB6AACACZQeAABgAqUHAACYQOkBAAAmUHoAAIAJlB4AAGACpQcAAJhA6QEAACZQegAAgAmUHgAAYAKlBwAAmEDpAQAAJlB6AACACZQeAABgAqUHAACYQOkBAAAmUHoAAIAJlB4AAGACpQe4xH3yyScaP368OnbsqJCQEI0aNSrgeY7juFuTJk10+eWXa/jw4Vq5cmWVfk5iYqLuvffeaq8tPT1dx44dq9b9LpTt27crPT29wv709HQlJCRc+AUBOK8oPcAl7m9/+5tat26tUaNGKTEx8ayl55577tGWLVu0ceNG/eUvf9GoUaMUEhKiW2+91fPn7Ny5UwcPHqzW2l577TU5jqN9+/ZV634Xyrx58+Q4Ff83+Pnnn+vdd98NwooAnE+UHuASV1ZW5v5z3759z1p65s2bV2H/c889J8dxtGDBglpfWzBKz6lTp/yek7OprPQAqJv4rx2oQ2pSeiSpR48e6tGjx1kf+8y3t07/rIULFyopKUkRERH60Y9+pH/961+SpPXr1/u9peY4jhITE937f/bZZ7rxxhsVFRUln8+n4cOH64svvvD7mTt37lT37t3VuHFjXXXVVXrzzTcrXcfTTz+tpKQk1atXT1999ZX27NmjH//4x7rssssUFhamTp06adGiRe79XnjhhQrr69u3r6TAb2+99957+t73vqfQ0FDFxMRozJgx+uqrr9zj+/btk+M4evnll3XbbbcpIiJCl19+uWbNmnXW5xXAhUPpAeqQmpaeBx54QA0aNFBxcXGljx2obLRq1UqpqalasWKFXnzxRTVt2lQ/+clPJEl5eXl64okn5DiOXnnlFW3ZskU7d+6UJB05ckQtWrRQSkqKli1bpuXLl+uqq65S165dVV5eLkk6efKk4uPjlZKSor/97W9auHCh2rVrp6ioqArraN68ubp166Zly5Zp1apVKigo0BtvvKHf/OY3+vvf/64333xTv/3tb9WwYUP99a9/dddwzz33yHEcbdmyRVu2bFF2drakiqXnyJEjioqKUu/evfW3v/1NCxYsUEJCglJTU91zTpeexMRETZkyRWvWrNGvfvUrOY6j1atXV/4vDcAFQ+kB6pCalp4//elPchzHfZUmkEClJzo6WsePH3f3zZ49Ww0bNnTfXqrs7a20tDTFxcX53Xffvn1q0KCBVq1aJUmaO3euGjdurMOHD7vnrF69Wo7jVFhHaGiojhw5Uunay8vLVVJSojvuuEMDBgxw91f29taZpefee+9VTEyMTpw44e7bsGGDHMfR66+/7q7fcZwK10d16NBBP//5zytdG4ALh9ID1CE1LT2nw7+6pWfw4MF+56xYsUKO4ygnJ0dS5aWnZ8+euvnmm1VSUuK3tW/fXjNmzJAkjR07Vn369PG7X1lZmRo2bFhhHafflvq2/Px83XfffWrTpo0aNGgQ8C22qpae/v3762c/+1mF85o3b66ZM2dK+k/pOf1K0mnDhw+v8DwBCA5KD1CHnMvbWw0bNqz221tn/qwzS05lpaddu3YVrqc5vZ1+VWTw4MEaPnx4hXU0b968wjpGjhxZ4bxJkyYpIiJCjz32mNauXavt27frtttu8yszVS09ycnJuvvuuyuc17lzZ02YMEHSf0rPa6+95nfOqFGjApYyABcepQeoQ2paerp3766ePXue9bFrs/R0795dN954o7Zv315hO31udV7pCfQ7t2jRQg888IDfvltuuaVGpad///666aabKpwX6JUeSg9w8aL0AHXIuXxkfeHChWd97JqUnnXr1slxHH3wwQd+5913333q0KGDTp06VenPq841PYF+5+joaLeQSP++MLpZs2Z+Zeb0715YWOh33zNLz3333aeYmBidPHnS3bdx48aA1/RQeoCLF6UHuMTl5+dr6dKlWrp0qTp27KjU1FT3dn5+vnvemV9OuHjxYvfLCW+77TbPn1OT0vPFF18oJCREd999t7Zu3apdu3ZJ+venoVq2bKlrr71WS5Ys0VtvvaXFixfr1ltv1fr16yVV/PTWokWL1LZtW0VGRur+++8/6zokacSIEYqLi9Nf/vIXrVixQr1791abNm38ysz//d//yXEc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GAIAACzkHaXHg4UhAADAQt5RejxYGAIAACzkHaXHg4UhAADAQt5RejxYGAIAACzkHaXHg4UhAADAQt5RejxYGAIAACzkHaXHg4UhAADAQt5RejxYGAIAACzkHaXHg4UhAADAQt5RejxYGAIAACzkHaXHg4UhAADAQt5RejxYGAIAACzkHaXHg4UhAADAQt5RejxYGAIAACzkHaXHg4UhAADAQt5RejxYGAIAACzkHaXHg4UhAADAQt5RejxYGAIAACzkHaXHg4UhAADAQt5RejxYGAIAACzkHaXHg4UhAADAQt5RejxYGAIAACzkHaXHg4UhAADAQt5RejxYGAIAACzkHaXHg4UhAADAQt4FpfQUFxdr4sSJio6OVmxsrKZOnary8vKA5+7YsUOpqamKiIhQUlKSFi5c6B776KOPNGzYMCUkJCgqKkqpqanavHmz3/0dx1FoaKh8Pp98Pp/69+9frbVaGAIAACzkXVBKz/Tp05WSkqLDhw/rwIEDat++vZ588skK5x07dkzx8fGaP3++SktLtXXrVkVGRmrTpk2SpHfeeUfPPPOMjhw5otLSUmVmZio6Olq5ubnuYziOo927d9d4rRaGAAAAC3kXlNLTqlUrrVixwr2dmZmpLl26VDhv9erVSkpK8tt3yy23aNy4cZU+dkxMjDZs2ODepvQAAODNQt5d8NJz9OhROY6j/fv3u/u2bdumhg0bVniLa9WqVWrTpo3fvrFjx6pr164BH3vXrl1q0KCBcnJy3H2O46h58+aKi4vT4MGD9f7771drvRaGAAAAC3l3wUvPwYMH5TiOjh075u77+OOP5TiOCgsL/c7Nzc1VbGys5s2bp+LiYr399tuKiIhQ27ZtKzzu0aNH1bFjR02fPt1v//r161VUVKQTJ05o5syZio+P19dff13p+mbMmKGQkBB3cxyu9QYA1H2UnvPg9Cs9Bw4ccPdt37494Cs9krR582alpqYqNjZWffr00V133aXu3bv7nXP8+HGlpKTojjvuqPSC6NPat2+vpUuXVnm9FoYAAAALeRe0a3pWrlzp3p4/f37Aa3oCGTlypKZOnerePn78uHr06KFbb73Vs/BIUnJysrKysqq8VgtDAACAhbwLSul58MEH1aNHDx05ckQHDx5UcnJywE9vSdLOnTtVVFSkgoICZWZmKj4+Xl9++aUkKS8vTz179tSYMWNUVlZW4b579uzRu+++q5KSEhUUFGjWrFmKjY3V4cOHq7xWC0MAAICFvAva9/RMmDBBUVFRiomJ0ZQpU9xXaYYMGaKMjAz33HHjxikyMlI+n08DBw7Unj173GMLFiyQ4zgKCwtzv4fH5/PpxRdflCS9+eabSk5Ols/nU2xsrAYMGKAdO3ZUa60WhgAAAAt5x1W6HiwMAQAAFvKO0uPBwhAAAGAh7yg9HiwMAQAAFvKO0uPBwhAAAGAh7yg9HiwMAQAAFvKO0uPBwhAAAGAh7yg9HiwMAQAAFvKO0uPBwhAAAGAh7yg9HiwMAQAAFvKO0uPBwhAAAGAh7yg9HiwMAQAAFvKO0uPBwhAAAGAh7yg9HiwMAQAAFvKO0uPBwhAAAGAh7yg9HiwMAQAAFvKO0uPBwhAAAGAh7yg9HiwMAQAAFvKO0uPBwhAAAGAh7yg9HiwMAQAAFvKO0uPBwhAAAGAh7yg9HiwMAQAAFvKO0uPBwhAAAGAh7yg9HiwMAQAAFvKO0uPBwhAAAGAh7yg9HiwMAQAAFvKO0uPBwhAAAGAh7yg9HiwMAQAAFvKO0uPBwhAAAGAh7yg9HiwMAQAAFvKO0uPBwhAAAGAh7yg9HiwMAQAAFvKO0uPBwhAAAGAh7yg9HiwMAQAAFvIuKKWnuLhYEydOVHR0tGJjYzV16lSVl5cHPHfHjh1KTU1VRESEkpKStHDhQr/jX3zxhQYPHqywsDAlJibqxRdf9DuenZ2tXr16KTQ0VMnJyVqzZk211mphCAAAsJB3QSk906dPV0pKig4fPqwDBw6offv2evLJJyucd+zYMcXHx2v+/PkqLS3V1q1bFRkZqU2bNrnnXHfddZo4caIKCgq0fv16hYeH67333pP073LVtm1bZWRkqKioSEuWLFFERIRycnKqvFYLQwAAgIW8C0rpadWqlVasWOHezszMVJcuXSqct3r1aiUlJfntu+WWWzRu3DhJ0qeffqoGDRooNzfXPX7TTTfp7rvvliStXbtWzZo1U2lpqXu8d+/emjNnTpXXamEIAACwkHcXvPQcPXpUjuNo//797r5t27apYcOGFd7iWrVqldq0aeO3b+zYseratask6ZVXXqlw/OGHH9aAAQMkSY8//rj69evnd3zSpEkaP358lddrYQgAALCQdxe89Bw8eFCO4+jYsWPuvo8//liO46iwsNDv3NzcXMXGxmrevHkqLi7W22+/rYiICLVt21aStGjRInXu3NnvPpmZmerRo4ckaebMmRo6dKjf8bS0NI0aNarS9c2YMUMhISHu5jiO3+1z3Wr78dh4jnme6+7Gc8zzfKGfh7ouaK/0HDhwwN23ffv2gK/0SNLmzZuVmpqq2NhY9enTR3fddZe6d+8u6d+v9Jz59tcjjzzi90pP//79/Y5Pnjy5Wq/01LaQkLrfpION5/jC4Hk+/3iOLwyeZzuCdk3PypUr3dvz588PeE1PICNHjtTUqVMlBb6mZ/To0X7X9MTFxamsrMw9npqaWq1remob/3GdfzzHFwbP8/nHc3xh8DzbEZTS8+CDD6pHjx46cuSIDh48qOTk5ICf3pKknTt3qqioSAUFBcrMzFR8fLy+/PJL9/i1116rSZMmqaCgQBs2bAj46a3Zs2erqKhIWVlZioiI0KFDhy7I7xkI/3GdfzzHFwbP8/nHc3xh8DzbEbTv6ZkwYYKioqIUExOjKVOmuG9tDRkyRBkZGe6548aNU2RkpHw+nwYOHKg9e/b4PdYXX3yhQYMGKTQ0VK1bt67wPT179uxRz5491aRJE3Xo0KHa39NT22bMmBHUn28Bz/GFwfN8/vEcXxg8z3bU/auWAAAAROkBAABGUHoAAIAJlB4AAGACpecCqc4fWUX1FRUVafz48WrTpo3Cw8OVnJysF154IdjLqrOOHDmipk2bqlu3bsFeSp21bNkyXXnllQoLC1OrVq20ePHiYC+pzjl48KB+9KMfKSYmRs2aNdPo0aN1/PjxYC8L5xGl5wKp6h9ZRc2cPHlSDz74oD799FOVl5dry5Ytio6O1rp164K9tDpp9OjRuu666yg958m6devUsmVLbdiwQaWlpfrqq6/0ySefBHtZdc6PfvQjjRgxQidPntSxY8fUv39/TZ48OdjLwnlE6blAqvpHVlF7hg8frt/85jfBXkad88Ybb+jaa6/V888/T+k5T1JTU/XMM88Eexl13lVXXaWXXnrJvf3UU0+pb9++wVsQzjtKzwVQnT+yitpRWFioli1b6uWXXw72UuqU/Px8dejQQXv27NELL7xA6TkPSktL1bBhQ/3+979X+/bt1aJFC918881+3zyP2vH8889rxIgR+uabb/T111+rb9+++v3vfx/sZeE8ovRcANX5I6s4d+Xl5Ro9erT69evn9ydIcO6mTp2q++67T5IoPefJl19+Kcdx1KVLF33++ec6fvy4hg4dqpEjRwZ7aXXORx99pF69eqlevXoKCQnR9ddfr6KiomAvC+cRpecCqO4fWUXNlZeX6xe/+IWuueYaLkisZf/4xz/03e9+VwUFBZIoPefLsWPH5DiOnn32WXffjh075PP5+P9FLSorK1NiYqLS0tJUUFCgb775RhMmTNAPf/jDYC8N5xGl5wI5lz+yiqopLy/XxIkT1bVrVx09ejTYy6lznnjiCYWFhSkhIUEJCQmKjIxUgwYNlJCQwFsvtezyyy/Xc889597esWOHwsLCKD216KuvvpLjOMrJyXH37dq1S/Xq1VNpaWkQV4bzidJzgVTnj6yiZiZNmqROnTrp66+/DvZS6qT8/Hzl5OS425w5c9S5c2fl5OQQxrXsN7/5jbp27aqcnBydOHFCN954I29vnQdt27bV9OnTderUKeXn57v/D0HdRem5QM72R1Zx7vbv3y/HcdS4cWP5fD53+8UvfhHspdVZvL11/pSUlOiXv/yl3/fH8Gpa7du9e7cGDBigmJgYxcTEaNCgQdq7d2+wl4XziNIDAABMoPQAAAATKD0AAMAESg8AADCB0gMAAEyg9AAAABMoPQAAwARKDwAAMIHSAwAATKD0AMAlpri4WL1791ZUVJSWLl0a7OUAlwxKDwBcYsrLy3Xo0CGlp6dTeoBqoPQAhnXs2FGvvfZasJdxSfrzn/+sMWPGBHUNgUrP4MGD9frrrwdpRcDFjdID1KIPP/xQP/zhD9W0aVNFRESoQ4cO+t3vfnfOj5uYmKhVq1Z57rPgYvi9S0tLlZiYqA8//DCo6whUejZs2KAuXboEaUXAxY3SA9Sitm3bKj09XQUFBSotLdWePXuUlZV1zo9b26WnrKxMZWVl57yuYLgYfu/ly5erR48e5/w4lcnNzVWPHj0qbH//+9/9zgtUesrLy9WmTRtt2bLlvK0PuFRReoBa8tVXX8lxHB06dCjg8UOHDulnP/uZmjdvrqioKH3ve99zjz388MNq166dwsPD1a5dOz3//PPusZ/+9KcKCQlRkyZN5PP59Mtf/jLgvpycHI0aNUrx8fFq2bKl7r//fpWUlLiPk5iYqFmzZqlbt25q0qSJPvnkkwoFIjExUQ8//LCuueYahYeHa8CAATp8+LAk6f3331dKSorCw8M1ePBg3XnnnRoxYkTA3/Wxxx7ToEGD/PY988wz6t27t3v7bOut7LkK9HtL0scff6wBAwYoOjpa7dq10zPPPHPW3zuQP/zhD2rRooWioqJ0zz33qHPnzpWWq5///Oe6//77/fb99a9/VY8ePTRt2jRddtllioqK0lNPPeUeX7p0qa655hrdd999io+PV3x8vFasWKHXX39dnTp1ks/n0x133BHw51Wmsmt6brvtNqWlpVXrsQALKD1ALSkvL1dycrIGDBigl156Sfv373ePlZaW6uqrr9btt9+u48ePq7i4WG+++aZ7fOnSpTp48KDKysr02muvqXHjxtq1a5d73OuVnrKyMqWkpOjee+9VQUGB/vWvfyklJUWPP/643/nJycn65JNPVFJSouLi4oClp1OnTtq/f7/y8/PVt29f/epXv1JxcbHatGmjhx56SMXFxdq4caMiIyMrLT05OTlq1KiRcnJy3H19+vTRvHnzPNfr9Vyduebi4mJ997vfVVpamoqKirRjxw41bdpUr776aqW/95l+//vf66qrrtI///lPFRUV6cc//rHq16+vAwcOBPz9UlJStHDhQr999957r3w+n7KyslRSUqKsrCxFRUW5x9PS0uTz+fTyyy+rtLRU999/v1q0aKHbb79deXl5+vDDD1WvXj199tlnAX/mmX7yk58oKSlJV111laZOnep37NFHH9X3v//9Kj0OYAmlB6hFOTk5+p//+R917NhR9erV0xVXXKE1a9Zoy5YtioyMVFFRUZUe5/rrr/d7lcCr9LzzzjuKi4tTeXm5ezwrK0spKSl+58+dO7fSxzh9e/78+e7tP/7xj+rbt682bNig2NhYlZaWusdGjx5daemRpEGDBrml65///KcaN26s3Nxcz/V6PVdnrnnTpk2KiYnxKzP33nuvfvrTn1b6e3/bsWPHFB4ern/84x/uvmXLlik6OrrS+7Rr107Lly/32zd48GDdc8897u29e/f6lZ7//u//9ju+ZMkStWrVym/doaGh+uijjyr9uVWVmZmpXr16nfPjAHUNpQc4T3Jzc/XrX/9aPp9PL730kv7rv/6r0nMXLVqkLl26KDo6WlFRUWrYsKFmzJjhHvcqPS+99JLq16+vqKgod4uIiFDr1q39zl+5cmWljxHo9gsvvKBu3brpr3/9q6688kq/+953331nLT1//vOfdfXVV0uSfvvb32rYsGHusbOt1+u5OnONS5YsqbC2efPm6dprr6309/62l19+WcnJyX77nnnmGV133XWV3ifQKz0JCQnatGmT3+/47bfzWrRoobffftu9/cADD2j8+PHu7c8++0yNGzf2e0uypnilBwiM0gOcR998840cx9HWrVsVGRmpU6dOVThn//79atCggd588033lZTrr79e6enp7jlJSUkVSs+3923ZskUtW7Y861qqcjF0ZaVnw4YNatq0abVe6Tl58qR8Pp/27t2rDh066OWXX3aPnW29Z3uupIrPxelXer5dFs58pedsFz7PmzevQsG5/vrrdeedd1Z6nzOv6cnJyVG9evV04sQJvzVMnjxZknT48GHVq1dPJ0+edI//4Ac/0NNPP+3eXrZsmbp161bpz6wOrukBAqP0ALXk6NGjmjZtmj744AOVlpYqPz9fM2bMUGxsrE6ePKmrr75aEyZM0PHjx1VSUuJep5Kdna0GDRpo9+7dKisr07Jly9SoUSO/0tOzZ0/NmTPH7+d9e19paamuueYaTZ8+XSdOnFBZWZk+++wzrV271j3/XEpPcXGxWrdurdmzZ6u4uFhvv/32Wa/pOe3mm2/WoEGDFB0d7fd21dnWW1ZWVulzFei5KC4uVrt27fTAAw/o1KlT2rlzp5o1a6bVq1dX+nt/21tvvaWwsDBlZ2frxIkTeuCBB1S/fn2/t/nO9Morr6hnz57u7ddee63Cq0UDBw50H+P111+vcLxFixbaunWre/uBBx7Qz3/+80p/ZnUkJSVp8+bNtfJYQF1C6QFqycmTJ3XLLbcoKSlJPp9PTZs21cCBA/XOO+9Ikr788kuNHDlScXFxio6O1oABA9z7Pvjgg4qNjVVsbKxuv/123XDDDX6lZ+XKlUpMTFRUVJR+9atfBdyXk5OjMWPG6LLLLlNkZKQ6deqkF154wX2Mcyk9kvTee++pW7du8vl8GjRokO644w7ddNNNZ31O3njjDTmOo9tvv73CsbOt92zPVaDn4oMPPtD111+vqKgotW3b1u8VlKp8xP2uu+5SZGSkWrduraeeeko+n8/99xZISUmJWrdu7X5Pz+zZsys8F82aNdP27dsDHv/Xv/6l+vXrq6CgwN33gx/84KzXHlXVpk2b1Llz53N+HKAuovQAqJGRI0fq3nvvDfYyat2+fftUr1495efnn/W8RYsWBf0bmQMZMmQI37INVILSA6BKNmzYoM8//1ylpaVavXq1GjVqdNZXQy5Vq1evVvv27YO9DADnAaUHQJU899xzatGihcLCwtShQwc999xzwV7SefHoo4/qxz/+cbCXAeA8oPQAAAATKD0AAMAESg8AADCB0gMAAEyg9AAAABP+H6N+Q7veSoj6AAAAAElFTkSuQmCC\" width=\"573\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "(0.9, 1.1)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Validation of the flatness of a flat image integrated\n",
    "flat = numpy.ones(detector.shape)\n",
    "res_flat = ai.integrate1d(flat, **kwarg)\n",
    "crv = jupyter.plot1d(res_flat)\n",
    "crv.axes.set_ylim(0.9,1.1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "timeit for method= numpy max error: 0.0\n",
      "42.5 ms ± 2.77 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n",
      "timeit for method= histogram max error: 0.0\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:pyFAI.ext.splitBBoxCSR:Pixel splitting desactivated !\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "22.9 ms ± 1.01 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n",
      "timeit for method= nosplit_csr max error: 0.0\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:pyFAI.ext.splitBBoxCSR:Pixel splitting desactivated !\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.37 ms ± 31.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n",
      "timeit for method= nosplit_csr_ocl_gpu max error: 1.1920929e-07\n",
      "1.52 ms ± 192 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n"
     ]
    }
   ],
   "source": [
    "#Equivalence of different rebinning engines:\n",
    "\n",
    "for method in \"numpy\", \"histogram\", \"nosplit_csr\", \"nosplit_csr_ocl_gpu\":\n",
    "    ai.reset()\n",
    "    res_flat = ai.integrate1d(flat, method=method, **kwarg)\n",
    "    print(\"timeit for method=\", method, \"max error:\", abs(res_flat.intensity-1).max())\n",
    "    % timeit res_flat = ai.integrate1d(flat, method=method, **kwarg)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# so we chose the nosplit_csr_ocl_gpu, other methods may be faster depending on the computer\n",
    "kwarg[\"method\"] = \"nosplit_csr_ocl_gpu\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "/* Put everything inside the global mpl namespace */\n",
       "window.mpl = {};\n",
       "\n",
       "\n",
       "mpl.get_websocket_type = function() {\n",
       "    if (typeof(WebSocket) !== 'undefined') {\n",
       "        return WebSocket;\n",
       "    } else if (typeof(MozWebSocket) !== 'undefined') {\n",
       "        return MozWebSocket;\n",
       "    } else {\n",
       "        alert('Your browser does not have WebSocket support.' +\n",
       "              'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
       "              'Firefox 4 and 5 are also supported but you ' +\n",
       "              'have to enable WebSockets in about:config.');\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
       "    this.id = figure_id;\n",
       "\n",
       "    this.ws = websocket;\n",
       "\n",
       "    this.supports_binary = (this.ws.binaryType != undefined);\n",
       "\n",
       "    if (!this.supports_binary) {\n",
       "        var warnings = document.getElementById(\"mpl-warnings\");\n",
       "        if (warnings) {\n",
       "            warnings.style.display = 'block';\n",
       "            warnings.textContent = (\n",
       "                \"This browser does not support binary websocket messages. \" +\n",
       "                    \"Performance may be slow.\");\n",
       "        }\n",
       "    }\n",
       "\n",
       "    this.imageObj = new Image();\n",
       "\n",
       "    this.context = undefined;\n",
       "    this.message = undefined;\n",
       "    this.canvas = undefined;\n",
       "    this.rubberband_canvas = undefined;\n",
       "    this.rubberband_context = undefined;\n",
       "    this.format_dropdown = undefined;\n",
       "\n",
       "    this.image_mode = 'full';\n",
       "\n",
       "    this.root = $('<div/>');\n",
       "    this._root_extra_style(this.root)\n",
       "    this.root.attr('style', 'display: inline-block');\n",
       "\n",
       "    $(parent_element).append(this.root);\n",
       "\n",
       "    this._init_header(this);\n",
       "    this._init_canvas(this);\n",
       "    this._init_toolbar(this);\n",
       "\n",
       "    var fig = this;\n",
       "\n",
       "    this.waiting = false;\n",
       "\n",
       "    this.ws.onopen =  function () {\n",
       "            fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
       "            fig.send_message(\"send_image_mode\", {});\n",
       "            if (mpl.ratio != 1) {\n",
       "                fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
       "            }\n",
       "            fig.send_message(\"refresh\", {});\n",
       "        }\n",
       "\n",
       "    this.imageObj.onload = function() {\n",
       "            if (fig.image_mode == 'full') {\n",
       "                // Full images could contain transparency (where diff images\n",
       "                // almost always do), so we need to clear the canvas so that\n",
       "                // there is no ghosting.\n",
       "                fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
       "            }\n",
       "            fig.context.drawImage(fig.imageObj, 0, 0);\n",
       "        };\n",
       "\n",
       "    this.imageObj.onunload = function() {\n",
       "        fig.ws.close();\n",
       "    }\n",
       "\n",
       "    this.ws.onmessage = this._make_on_message_function(this);\n",
       "\n",
       "    this.ondownload = ondownload;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_header = function() {\n",
       "    var titlebar = $(\n",
       "        '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
       "        'ui-helper-clearfix\"/>');\n",
       "    var titletext = $(\n",
       "        '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
       "        'text-align: center; padding: 3px;\"/>');\n",
       "    titlebar.append(titletext)\n",
       "    this.root.append(titlebar);\n",
       "    this.header = titletext[0];\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_canvas = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var canvas_div = $('<div/>');\n",
       "\n",
       "    canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
       "\n",
       "    function canvas_keyboard_event(event) {\n",
       "        return fig.key_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    canvas_div.keydown('key_press', canvas_keyboard_event);\n",
       "    canvas_div.keyup('key_release', canvas_keyboard_event);\n",
       "    this.canvas_div = canvas_div\n",
       "    this._canvas_extra_style(canvas_div)\n",
       "    this.root.append(canvas_div);\n",
       "\n",
       "    var canvas = $('<canvas/>');\n",
       "    canvas.addClass('mpl-canvas');\n",
       "    canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
       "\n",
       "    this.canvas = canvas[0];\n",
       "    this.context = canvas[0].getContext(\"2d\");\n",
       "\n",
       "    var backingStore = this.context.backingStorePixelRatio ||\n",
       "\tthis.context.webkitBackingStorePixelRatio ||\n",
       "\tthis.context.mozBackingStorePixelRatio ||\n",
       "\tthis.context.msBackingStorePixelRatio ||\n",
       "\tthis.context.oBackingStorePixelRatio ||\n",
       "\tthis.context.backingStorePixelRatio || 1;\n",
       "\n",
       "    mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
       "\n",
       "    var rubberband = $('<canvas/>');\n",
       "    rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
       "\n",
       "    var pass_mouse_events = true;\n",
       "\n",
       "    canvas_div.resizable({\n",
       "        start: function(event, ui) {\n",
       "            pass_mouse_events = false;\n",
       "        },\n",
       "        resize: function(event, ui) {\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "        stop: function(event, ui) {\n",
       "            pass_mouse_events = true;\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "    });\n",
       "\n",
       "    function mouse_event_fn(event) {\n",
       "        if (pass_mouse_events)\n",
       "            return fig.mouse_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    rubberband.mousedown('button_press', mouse_event_fn);\n",
       "    rubberband.mouseup('button_release', mouse_event_fn);\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband.mousemove('motion_notify', mouse_event_fn);\n",
       "\n",
       "    rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
       "    rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
       "\n",
       "    canvas_div.on(\"wheel\", function (event) {\n",
       "        event = event.originalEvent;\n",
       "        event['data'] = 'scroll'\n",
       "        if (event.deltaY < 0) {\n",
       "            event.step = 1;\n",
       "        } else {\n",
       "            event.step = -1;\n",
       "        }\n",
       "        mouse_event_fn(event);\n",
       "    });\n",
       "\n",
       "    canvas_div.append(canvas);\n",
       "    canvas_div.append(rubberband);\n",
       "\n",
       "    this.rubberband = rubberband;\n",
       "    this.rubberband_canvas = rubberband[0];\n",
       "    this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
       "    this.rubberband_context.strokeStyle = \"#000000\";\n",
       "\n",
       "    this._resize_canvas = function(width, height) {\n",
       "        // Keep the size of the canvas, canvas container, and rubber band\n",
       "        // canvas in synch.\n",
       "        canvas_div.css('width', width)\n",
       "        canvas_div.css('height', height)\n",
       "\n",
       "        canvas.attr('width', width * mpl.ratio);\n",
       "        canvas.attr('height', height * mpl.ratio);\n",
       "        canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
       "\n",
       "        rubberband.attr('width', width);\n",
       "        rubberband.attr('height', height);\n",
       "    }\n",
       "\n",
       "    // Set the figure to an initial 600x600px, this will subsequently be updated\n",
       "    // upon first draw.\n",
       "    this._resize_canvas(600, 600);\n",
       "\n",
       "    // Disable right mouse context menu.\n",
       "    $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
       "        return false;\n",
       "    });\n",
       "\n",
       "    function set_focus () {\n",
       "        canvas.focus();\n",
       "        canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    window.setTimeout(set_focus, 100);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items) {\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) {\n",
       "            // put a spacer in here.\n",
       "            continue;\n",
       "        }\n",
       "        var button = $('<button/>');\n",
       "        button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
       "                        'ui-button-icon-only');\n",
       "        button.attr('role', 'button');\n",
       "        button.attr('aria-disabled', 'false');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "\n",
       "        var icon_img = $('<span/>');\n",
       "        icon_img.addClass('ui-button-icon-primary ui-icon');\n",
       "        icon_img.addClass(image);\n",
       "        icon_img.addClass('ui-corner-all');\n",
       "\n",
       "        var tooltip_span = $('<span/>');\n",
       "        tooltip_span.addClass('ui-button-text');\n",
       "        tooltip_span.html(tooltip);\n",
       "\n",
       "        button.append(icon_img);\n",
       "        button.append(tooltip_span);\n",
       "\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    var fmt_picker_span = $('<span/>');\n",
       "\n",
       "    var fmt_picker = $('<select/>');\n",
       "    fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
       "    fmt_picker_span.append(fmt_picker);\n",
       "    nav_element.append(fmt_picker_span);\n",
       "    this.format_dropdown = fmt_picker[0];\n",
       "\n",
       "    for (var ind in mpl.extensions) {\n",
       "        var fmt = mpl.extensions[ind];\n",
       "        var option = $(\n",
       "            '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
       "        fmt_picker.append(option)\n",
       "    }\n",
       "\n",
       "    // Add hover states to the ui-buttons\n",
       "    $( \".ui-button\" ).hover(\n",
       "        function() { $(this).addClass(\"ui-state-hover\");},\n",
       "        function() { $(this).removeClass(\"ui-state-hover\");}\n",
       "    );\n",
       "\n",
       "    var status_bar = $('<span class=\"mpl-message\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
       "    // which will in turn request a refresh of the image.\n",
       "    this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_message = function(type, properties) {\n",
       "    properties['type'] = type;\n",
       "    properties['figure_id'] = this.id;\n",
       "    this.ws.send(JSON.stringify(properties));\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_draw_message = function() {\n",
       "    if (!this.waiting) {\n",
       "        this.waiting = true;\n",
       "        this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
       "    }\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    var format_dropdown = fig.format_dropdown;\n",
       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
       "    fig.ondownload(fig, format);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
       "    var size = msg['size'];\n",
       "    if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
       "        fig._resize_canvas(size[0], size[1]);\n",
       "        fig.send_message(\"refresh\", {});\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
       "    var x0 = msg['x0'] / mpl.ratio;\n",
       "    var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
       "    var x1 = msg['x1'] / mpl.ratio;\n",
       "    var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
       "    x0 = Math.floor(x0) + 0.5;\n",
       "    y0 = Math.floor(y0) + 0.5;\n",
       "    x1 = Math.floor(x1) + 0.5;\n",
       "    y1 = Math.floor(y1) + 0.5;\n",
       "    var min_x = Math.min(x0, x1);\n",
       "    var min_y = Math.min(y0, y1);\n",
       "    var width = Math.abs(x1 - x0);\n",
       "    var height = Math.abs(y1 - y0);\n",
       "\n",
       "    fig.rubberband_context.clearRect(\n",
       "        0, 0, fig.canvas.width, fig.canvas.height);\n",
       "\n",
       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
       "    // Updates the figure title.\n",
       "    fig.header.textContent = msg['label'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
       "    var cursor = msg['cursor'];\n",
       "    switch(cursor)\n",
       "    {\n",
       "    case 0:\n",
       "        cursor = 'pointer';\n",
       "        break;\n",
       "    case 1:\n",
       "        cursor = 'default';\n",
       "        break;\n",
       "    case 2:\n",
       "        cursor = 'crosshair';\n",
       "        break;\n",
       "    case 3:\n",
       "        cursor = 'move';\n",
       "        break;\n",
       "    }\n",
       "    fig.rubberband_canvas.style.cursor = cursor;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
       "    fig.message.textContent = msg['message'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
       "    // Request the server to send over a new figure.\n",
       "    fig.send_draw_message();\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
       "    fig.image_mode = msg['mode'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Called whenever the canvas gets updated.\n",
       "    this.send_message(\"ack\", {});\n",
       "}\n",
       "\n",
       "// A function to construct a web socket function for onmessage handling.\n",
       "// Called in the figure constructor.\n",
       "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
       "    return function socket_on_message(evt) {\n",
       "        if (evt.data instanceof Blob) {\n",
       "            /* FIXME: We get \"Resource interpreted as Image but\n",
       "             * transferred with MIME type text/plain:\" errors on\n",
       "             * Chrome.  But how to set the MIME type?  It doesn't seem\n",
       "             * to be part of the websocket stream */\n",
       "            evt.data.type = \"image/png\";\n",
       "\n",
       "            /* Free the memory for the previous frames */\n",
       "            if (fig.imageObj.src) {\n",
       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
       "                    fig.imageObj.src);\n",
       "            }\n",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data);\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "        else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
       "            fig.imageObj.src = evt.data;\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        var msg = JSON.parse(evt.data);\n",
       "        var msg_type = msg['type'];\n",
       "\n",
       "        // Call the  \"handle_{type}\" callback, which takes\n",
       "        // the figure and JSON message as its only arguments.\n",
       "        try {\n",
       "            var callback = fig[\"handle_\" + msg_type];\n",
       "        } catch (e) {\n",
       "            console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        if (callback) {\n",
       "            try {\n",
       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
       "                callback(fig, msg);\n",
       "            } catch (e) {\n",
       "                console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
       "            }\n",
       "        }\n",
       "    };\n",
       "}\n",
       "\n",
       "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
       "mpl.findpos = function(e) {\n",
       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
       "    var targ;\n",
       "    if (!e)\n",
       "        e = window.event;\n",
       "    if (e.target)\n",
       "        targ = e.target;\n",
       "    else if (e.srcElement)\n",
       "        targ = e.srcElement;\n",
       "    if (targ.nodeType == 3) // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "\n",
       "    // jQuery normalizes the pageX and pageY\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    // offset() returns the position of the element relative to the document\n",
       "    var x = e.pageX - $(targ).offset().left;\n",
       "    var y = e.pageY - $(targ).offset().top;\n",
       "\n",
       "    return {\"x\": x, \"y\": y};\n",
       "};\n",
       "\n",
       "/*\n",
       " * return a copy of an object with only non-object keys\n",
       " * we need this to avoid circular references\n",
       " * http://stackoverflow.com/a/24161582/3208463\n",
       " */\n",
       "function simpleKeys (original) {\n",
       "  return Object.keys(original).reduce(function (obj, key) {\n",
       "    if (typeof original[key] !== 'object')\n",
       "        obj[key] = original[key]\n",
       "    return obj;\n",
       "  }, {});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.mouse_event = function(event, name) {\n",
       "    var canvas_pos = mpl.findpos(event)\n",
       "\n",
       "    if (name === 'button_press')\n",
       "    {\n",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * mpl.ratio;\n",
       "    var y = canvas_pos.y * mpl.ratio;\n",
       "\n",
       "    this.send_message(name, {x: x, y: y, button: event.button,\n",
       "                             step: event.step,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "\n",
       "    /* This prevents the web browser from automatically changing to\n",
       "     * the text insertion cursor when the button is pressed.  We want\n",
       "     * to control all of the cursor setting manually through the\n",
       "     * 'cursor' event from matplotlib */\n",
       "    event.preventDefault();\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    // Handle any extra behaviour associated with a key event\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.key_event = function(event, name) {\n",
       "\n",
       "    // Prevent repeat events\n",
       "    if (name == 'key_press')\n",
       "    {\n",
       "        if (event.which === this._key)\n",
       "            return;\n",
       "        else\n",
       "            this._key = event.which;\n",
       "    }\n",
       "    if (name == 'key_release')\n",
       "        this._key = null;\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which != 17)\n",
       "        value += \"ctrl+\";\n",
       "    if (event.altKey && event.which != 18)\n",
       "        value += \"alt+\";\n",
       "    if (event.shiftKey && event.which != 16)\n",
       "        value += \"shift+\";\n",
       "\n",
       "    value += 'k';\n",
       "    value += event.which.toString();\n",
       "\n",
       "    this._key_event_extra(event, name);\n",
       "\n",
       "    this.send_message(name, {key: value,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
       "    if (name == 'download') {\n",
       "        this.handle_save(this, null);\n",
       "    } else {\n",
       "        this.send_message(\"toolbar_button\", {name: name});\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
       "    this.message.textContent = tooltip;\n",
       "};\n",
       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
       "\n",
       "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
       "\n",
       "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
       "    // object with the appropriate methods. Currently this is a non binary\n",
       "    // socket, so there is still some room for performance tuning.\n",
       "    var ws = {};\n",
       "\n",
       "    ws.close = function() {\n",
       "        comm.close()\n",
       "    };\n",
       "    ws.send = function(m) {\n",
       "        //console.log('sending', m);\n",
       "        comm.send(m);\n",
       "    };\n",
       "    // Register the callback with on_msg.\n",
       "    comm.on_msg(function(msg) {\n",
       "        //console.log('receiving', msg['content']['data'], msg);\n",
       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
       "        ws.onmessage(msg['content']['data'])\n",
       "    });\n",
       "    return ws;\n",
       "}\n",
       "\n",
       "mpl.mpl_figure_comm = function(comm, msg) {\n",
       "    // This is the function which gets called when the mpl process\n",
       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
       "\n",
       "    var id = msg.content.data.id;\n",
       "    // Get hold of the div created by the display call when the Comm\n",
       "    // socket was opened in Python.\n",
       "    var element = $(\"#\" + id);\n",
       "    var ws_proxy = comm_websocket_adapter(comm)\n",
       "\n",
       "    function ondownload(figure, format) {\n",
       "        window.open(figure.imageObj.src);\n",
       "    }\n",
       "\n",
       "    var fig = new mpl.figure(id, ws_proxy,\n",
       "                           ondownload,\n",
       "                           element.get(0));\n",
       "\n",
       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
       "    // web socket which is closed, not our websocket->open comm proxy.\n",
       "    ws_proxy.onopen();\n",
       "\n",
       "    fig.parent_element = element.get(0);\n",
       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
       "    if (!fig.cell_info) {\n",
       "        console.error(\"Failed to find cell for figure\", id, fig);\n",
       "        return;\n",
       "    }\n",
       "\n",
       "    var output_index = fig.cell_info[2]\n",
       "    var cell = fig.cell_info[0];\n",
       "\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
       "    var width = fig.canvas.width/mpl.ratio\n",
       "    fig.root.unbind('remove')\n",
       "\n",
       "    // Update the output cell to use the data from the current canvas.\n",
       "    fig.push_to_output();\n",
       "    var dataURL = fig.canvas.toDataURL();\n",
       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
       "    // the notebook keyboard shortcuts fail.\n",
       "    IPython.keyboard_manager.enable()\n",
       "    $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
       "    fig.close_ws(fig, msg);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.close_ws = function(fig, msg){\n",
       "    fig.send_message('closing', msg);\n",
       "    // fig.ws.close()\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
       "    // Turn the data on the canvas into data in the output cell.\n",
       "    var width = this.canvas.width/mpl.ratio\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Tell IPython that the notebook contents must change.\n",
       "    IPython.notebook.set_dirty(true);\n",
       "    this.send_message(\"ack\", {});\n",
       "    var fig = this;\n",
       "    // Wait a second, then push the new image to the DOM so\n",
       "    // that it is saved nicely (might be nice to debounce this).\n",
       "    setTimeout(function () { fig.push_to_output() }, 1000);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items){\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) { continue; };\n",
       "\n",
       "        var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    // Add the status bar.\n",
       "    var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "\n",
       "    // Add the close button to the window.\n",
       "    var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
       "    var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
       "    button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
       "    button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
       "    buttongrp.append(button);\n",
       "    var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
       "    titlebar.prepend(buttongrp);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(el){\n",
       "    var fig = this\n",
       "    el.on(\"remove\", function(){\n",
       "\tfig.close_ws(fig, {});\n",
       "    });\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(el){\n",
       "    // this is important to make the div 'focusable\n",
       "    el.attr('tabindex', 0)\n",
       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
       "    // off when our div gets focus\n",
       "\n",
       "    // location in version 3\n",
       "    if (IPython.notebook.keyboard_manager) {\n",
       "        IPython.notebook.keyboard_manager.register_events(el);\n",
       "    }\n",
       "    else {\n",
       "        // location in version 2\n",
       "        IPython.keyboard_manager.register_events(el);\n",
       "    }\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager)\n",
       "        manager = IPython.keyboard_manager;\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which == 13) {\n",
       "        this.canvas_div.blur();\n",
       "        event.shiftKey = false;\n",
       "        // Send a \"J\" for go to next cell\n",
       "        event.which = 74;\n",
       "        event.keyCode = 74;\n",
       "        manager.command_mode();\n",
       "        manager.handle_keydown(event);\n",
       "    }\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.find_output_cell = function(html_output) {\n",
       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
       "    // IPython event is triggered only after the cells have been serialised, which for\n",
       "    // our purposes (turning an active figure into a static one), is too late.\n",
       "    var cells = IPython.notebook.get_cells();\n",
       "    var ncells = cells.length;\n",
       "    for (var i=0; i<ncells; i++) {\n",
       "        var cell = cells[i];\n",
       "        if (cell.cell_type === 'code'){\n",
       "            for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
       "                var data = cell.output_area.outputs[j];\n",
       "                if (data.data) {\n",
       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
       "                    data = data.data;\n",
       "                }\n",
       "                if (data['text/html'] == html_output) {\n",
       "                    return [cell, data, j];\n",
       "                }\n",
       "            }\n",
       "        }\n",
       "    }\n",
       "}\n",
       "\n",
       "// Register the function which deals with the matplotlib target/channel.\n",
       "// The kernel may be null if the page has been refreshed.\n",
       "if (IPython.notebook.kernel != null) {\n",
       "    IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
       "}\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAj0AAAGtCAYAAAD9H8XfAAAgAElEQVR4nO3deXhU9dn/8QFFnxpkE3faAZFVUGxAFFuDdaG2ah9L7VMf7aVVW0WeXxcrTiBA2FywgBZcENQoroBAgQECyL6vsoUlEEnCEhIgCdkmme3z+yM6EiEcApmcmfm+X9d1rquZJHPuTG+9P57t6xAAAIABHHYXAAAAUBcIPQAAwAiEHgAAYARCDwAgIgSDQXm9Xja2c96CweAZe4zQAwCwnc/nU3p6unbu3MnGds7brl27lJeXV234IfQAAGx34MABZWRkqLy83PajBWzRuVVUVKigoCAUfE6H0AMAsFUgENDOnTtVUlJidymIAd8Fn9Md7SH0AABs5fV6tXPnTlVUVNhdCmJARUWFdu7cKa/Xe8r3CD0AAFt9F3pON6SAmjpTPxF6AAC2ipXQ07FjR82bNy8s752cnKzevXuH5b1rc3+//OUv9e6774aholM5HA5t3779lNcJPQCAiBUtoWf37t26//77ddlll+nSSy9Vu3bt9Oqrr9bJvmsSQlJSUhQfH19n+7MLoQcAEHWiJfS0bt1aycnJKisrk9/v144dOzRlypQ62Teh51SEHgBA1ImG0HP06FE5HA4dPny42p9xOp2aPXu2pO+Dx4ABA9SsWTNdddVVmjJlipYtW6aOHTuqUaNGevrpp0N3GJ0uqJz8fj8MIc8//7x+/OMfq2HDhurUqZPcbrckadu2bbr44otVv359xcXFKS4uTrm5uQoGgxo9erTatGmjJk2a6N5779U333wTer+tW7eqW7duatiwoXr16qW+fftWG3qOHTumBx98UE2aNFGTJk10yy236OjRo5KkhIQEjRs3LvSzY8aM0bXXXqvLL79cL7/88il/029+8xv95S9/UaNGjdSyZcvQ3yFJ8+bN009/+lM1atRIV199tf7xj3/I5/OFvk/oAQBEnWgIPcFgUO3bt9fdd9+tyZMnKzMz85Sf+WHoufDCCzV27Fj5fD5NmDBBjRs3Vu/evXX8+HEdPHhQV1xxhWbOnBn6+ZqEno8//lh5eXny+/16//33Q+GmuvcaO3asunTpooyMDPl8Pg0bNkxdunRRIBCQ1+tVy5YtNWzYMFVUVGjx4sWKi4urNvQkJibq/vvvV2lpqfx+vzZu3Kji4mJJVUPPggUL1KxZM23atEnl5eV6/vnndeGFF1b5mxo0aKApU6bI7/frrbfe0uWXXx4KNkuXLtWWLVsUCAS0e/dutWrVSm+++WaoDkIPACDqnG5I9XhlkTonp4Z96/HKorOuMycnR88//7w6duyo+vXrq0OHDlqwYEHo+z8MPS1atAh9r7S0VA6HQwsXLgy99vDDDys5OTn08zUJPT/UunXr0FGS071Xhw4dqhxFCQQCatiwodLS0rRs2TI1a9ZMfr8/9P0//OEP1e5v8ODB6tGjh7Zt23bK904OPX/605/0t7/9rcpn0KBBgyp/0+23317l+w6HQ/v37z/tfocPH67f/e53oa8JPQCAqBMtoedkx48f1z//+U/FxcXp+PHjkk5/eutkPxzSjz/+uP75z39W+/NnCj2jRo1Shw4d1KhRIzVu3FgXXHCBPvzww2rf60c/+pEuvfRSNW7cOLT913/9l+bPn6/PP/9cnTp1qvLzLper2tBTXFysfv366frrr9fVV1+tfv36hf6/Ozn09OrVS6NGjaryu1ddddUZg9zJn9HatWt155136vLLL1ejRo30ox/9SD179qz28/wOoQcAELGi4fTW6RQVFcnhcGjjxo2Szi/0TJ06VR06dAh9z+/365JLLjltQFi+fLmaNGmizZs3KxAISKo80pOSkiJJ+uijj07Zd7t27aocZTrZ6Y70PPLII2d1IfPevXvVunVrvffee5LOfKSnrKzslCM9Zwo91113nV555RWVlpZKqjzSk5CQcNqfPRmhBwAQsaIh9OTn5yspKUm7du2S3+9XaWmphgwZombNmoWWzzif0JOenq4LL7xQq1evVkVFhZKSknTBBRecNiDMmTNHzZs314EDB+Tz+TRu3DhdcMEFodCTmpqqq6++Wh6PJ7SvN954Q7feeqvS09MlSYWFhZo6dap8Pp+8Xq9+8pOfaMSIEfJ6vVq6dKkaNmxYbeiZPXu29uzZo0AgoNzcXLVr1y6075NDT2pqqi677DJ9/fXXqqio0AsvvHDKNT1nCj2XX365xo8fL6nyAm2n00noAQBEt2gIPSUlJXriiSfUqlUrxcXF6bLLLtM999yjdevWhX7mfEKPJI0cOVLNmzfXFVdcoVGjRlV7eisQCOjpp59Wo0aNdOWVVyopKUnx8fGh4OH1evXggw+qadOmaty4sXJzcxUIBDR27Fi1b99el156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ptzcXGVlZalt27YR+wDFaFRSUqJBgwZp3759CgaDWrNmjZo0aaJFixbZXVrMevTRR3XHHXcQesJg0aJFuvbaa7Vs2TL5/X4dPXpUe/futbusmPPAAw+od+/eKikpUUFBge6880717dvX7rIQRoSeOtKiRQvNnDkz9PWECRNqbakMnN5DDz2koUOH2l1GTJo/f75+/vOf64MPPiD0hMHtt9+ud9991+4yYl7nzp01efLk0Ndvvvlm6KG3iE2Enjrw3aKomZmZodfWr19fa4ui4lQej0fXXnutvvzyS7tLiTmlpaVq166dduzYoZSUFEJPLfP7/WrQoIFGjhyptm3b6uqrr9Zjjz2m48eP211azPnggw/Uu3dvFRUV6dixY0pISNDIkSPtLgthROipA9nZ2XI4HCooKAi9lp6eLofDIY/HY2NlsSkYDOrRRx9Vz549FQgE7C4n5vTr10+JiYmSROgJg0OHDsnhcKhLly46cOCACgsL9Zvf/Ea///3v7S4t5uzZs0e33Xab6tevr3r16umuu+5SeXm53WUhjAg9deC7Iz1ZWVmh1zZs2MCRnjAIBoN65pln1LVrVy5IDIMtW7aoTZs2Kisrk0ToCYeCggI5HA699957odc2btyouLg4/n1RiwKBgJxOpwYMGKCysjIVFRXp2Wef1f333293aQgjQk8dadGihWbNmhX6euLEiVzTU8uCwaD69Omjm2++Wfn5+XaXE5Nef/11XXLJJbryyit15ZVXqlGjRrrwwgt15ZVXcvqlFv34xz/W+++/H/p648aNuuSSSwg9tejo0aNyOBzKyckJvbZt2zbVr19ffr/fxsoQToSeOjJo0CB1795deXl5ys7OVvv27bl7q5Y999xzuvHGG3Xs2DG7S4lZpaWlysnJCW1vvPGGbrrpJuXk5DCQa9HQoUN18803KycnR8XFxfrtb3/L6a0waN26tQYPHqyKigqVlpaG/h2C2EXoqSNer1fPPvusGjdurKZNm+qFF15gSNSizMxMORwOXXzxxYqLiwttzzzzjN2lxTROb4WHz+fT3/72tyrPj+FIWu3bvn277r77bjVt2lRNmzbVvffeq507d9pdFsKI0AMAAIxA6AEAAEYg9AAAACMQegAAgBEIPQAAwAiEHgAAYARCDwAAMAKhBwAAGIHQAwAAjEDoARCTvF6vevToocaNG2vq1Kl2lwMgAhB6AMSkYDCow4cPKzk5mdADQBKhB0AYffzxx/rjH/9oaw2nCz29evVSamqqTRUBsAuhB0BY+P1+OZ1O7d6929Y6Thd6li1bpi5duthUEQC7EHoAhMWMGTPUvXv3sO7j+PHj6t69+ymb2+0O/czpQk8wGFTLli21Zs2asNYHILIQegCcta1bt6pbt25q2LChevXqpb59+6p3796n/dmnnnpK/fv3r/La559/ru7duyspKUnXXHONGjdurDfffDP0/alTp6pr165KTEzUFVdcoSuuuEIzZ85UamqqbrzxRsXFxekvf/lLjWqu7pqeJ598UgMGDKjRewGIboQeAGfF6/WqZcuWGjZsmCoqKrR48WLFxcVVG3q6deumjz76qMprLpdLcXFxmjJlinw+n6ZMmaLGjRuHvj9gwADFxcXpyy+/lN/vV//+/XX11Vfrz3/+s06cOKHdu3erfv36ysjIOKuaH374YbVq1UqdO3dWv379qnxv1KhR+tWvflXDTwFANCP0ADgry5YtU7NmzeT3+0Ov/eEPf6g29Fx//fWaMWNGldd69eqlF198MfT1zp07q4Se++67r8r3v/jiC7Vo0UJerzf02o9+9CPt2bPnvP+eCRMm6Lbbbjvv9wEQPQg9AM7K559/rk6dOlV5zeVy1ehIz5VXXqkVK1aEvp48ebJ69OgR+vrqq6/WypUrQ18PHDhQTz/9dOjrjIwMXXzxxfL5fOf1t0gc6QFMROgBcFZOd6TnkUceOetrenJyclS/fn0VFxeHXnO5XOrbt68kKTc3V/Xr11dJSUno+7/+9a/19ttvh76eNm2a4uPja+Xv4ZoewDyEHgBnxev16ic/+YlGjBghr9erpUuXqmHDhtWGnunTp+vWW28NfT1v3jy1b9++ys/cc889mjhxoiQpNTX1lO9fffXVWrt2bejrgQMH6qmnnqqVv6dVq1ZavXp1rbwXgOhA6AFw1r7++mvFx8crLi5O99577xnv3vL5fPrJT34Sek7PK6+8ov/93/+t8jPNmzfXhg0bTvv9I0eO6IILLlBZWVnotV//+tcaN27cef8dK1as0E033XTe7wMguhB6AJyz5OTkakOPJE2aNMn2JzKfzi9/+UvNmzfP7jIA1DFCD4BzZhV6ACCSEHoAnDNCD4BoQugBAABGIPQAAAAjEHoAAIARCD0AAMAIhB4AAGCE/w9o3n2km2Zi4gAAAABJRU5ErkJggg==\" width=\"573\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7f3b85e3c9b0>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Generation of a \"SAXS-like\" curve with the shape of a lorentzian curve\n",
    "\n",
    "q = numpy.linspace(0, res_flat.radial.max(), npt)\n",
    "I = I0/(1+q**2)\n",
    "fig, ax = subplots()\n",
    "ax.semilogy(q, I, label=\"Simulated signal\")\n",
    "ax.set_xlabel(\"q ($nm^{-1}$)\")\n",
    "ax.set_ylabel(\"I (count)\")\n",
    "fig.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "/* Put everything inside the global mpl namespace */\n",
       "window.mpl = {};\n",
       "\n",
       "\n",
       "mpl.get_websocket_type = function() {\n",
       "    if (typeof(WebSocket) !== 'undefined') {\n",
       "        return WebSocket;\n",
       "    } else if (typeof(MozWebSocket) !== 'undefined') {\n",
       "        return MozWebSocket;\n",
       "    } else {\n",
       "        alert('Your browser does not have WebSocket support.' +\n",
       "              'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
       "              'Firefox 4 and 5 are also supported but you ' +\n",
       "              'have to enable WebSockets in about:config.');\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
       "    this.id = figure_id;\n",
       "\n",
       "    this.ws = websocket;\n",
       "\n",
       "    this.supports_binary = (this.ws.binaryType != undefined);\n",
       "\n",
       "    if (!this.supports_binary) {\n",
       "        var warnings = document.getElementById(\"mpl-warnings\");\n",
       "        if (warnings) {\n",
       "            warnings.style.display = 'block';\n",
       "            warnings.textContent = (\n",
       "                \"This browser does not support binary websocket messages. \" +\n",
       "                    \"Performance may be slow.\");\n",
       "        }\n",
       "    }\n",
       "\n",
       "    this.imageObj = new Image();\n",
       "\n",
       "    this.context = undefined;\n",
       "    this.message = undefined;\n",
       "    this.canvas = undefined;\n",
       "    this.rubberband_canvas = undefined;\n",
       "    this.rubberband_context = undefined;\n",
       "    this.format_dropdown = undefined;\n",
       "\n",
       "    this.image_mode = 'full';\n",
       "\n",
       "    this.root = $('<div/>');\n",
       "    this._root_extra_style(this.root)\n",
       "    this.root.attr('style', 'display: inline-block');\n",
       "\n",
       "    $(parent_element).append(this.root);\n",
       "\n",
       "    this._init_header(this);\n",
       "    this._init_canvas(this);\n",
       "    this._init_toolbar(this);\n",
       "\n",
       "    var fig = this;\n",
       "\n",
       "    this.waiting = false;\n",
       "\n",
       "    this.ws.onopen =  function () {\n",
       "            fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
       "            fig.send_message(\"send_image_mode\", {});\n",
       "            if (mpl.ratio != 1) {\n",
       "                fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
       "            }\n",
       "            fig.send_message(\"refresh\", {});\n",
       "        }\n",
       "\n",
       "    this.imageObj.onload = function() {\n",
       "            if (fig.image_mode == 'full') {\n",
       "                // Full images could contain transparency (where diff images\n",
       "                // almost always do), so we need to clear the canvas so that\n",
       "                // there is no ghosting.\n",
       "                fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
       "            }\n",
       "            fig.context.drawImage(fig.imageObj, 0, 0);\n",
       "        };\n",
       "\n",
       "    this.imageObj.onunload = function() {\n",
       "        fig.ws.close();\n",
       "    }\n",
       "\n",
       "    this.ws.onmessage = this._make_on_message_function(this);\n",
       "\n",
       "    this.ondownload = ondownload;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_header = function() {\n",
       "    var titlebar = $(\n",
       "        '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
       "        'ui-helper-clearfix\"/>');\n",
       "    var titletext = $(\n",
       "        '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
       "        'text-align: center; padding: 3px;\"/>');\n",
       "    titlebar.append(titletext)\n",
       "    this.root.append(titlebar);\n",
       "    this.header = titletext[0];\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_canvas = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var canvas_div = $('<div/>');\n",
       "\n",
       "    canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
       "\n",
       "    function canvas_keyboard_event(event) {\n",
       "        return fig.key_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    canvas_div.keydown('key_press', canvas_keyboard_event);\n",
       "    canvas_div.keyup('key_release', canvas_keyboard_event);\n",
       "    this.canvas_div = canvas_div\n",
       "    this._canvas_extra_style(canvas_div)\n",
       "    this.root.append(canvas_div);\n",
       "\n",
       "    var canvas = $('<canvas/>');\n",
       "    canvas.addClass('mpl-canvas');\n",
       "    canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
       "\n",
       "    this.canvas = canvas[0];\n",
       "    this.context = canvas[0].getContext(\"2d\");\n",
       "\n",
       "    var backingStore = this.context.backingStorePixelRatio ||\n",
       "\tthis.context.webkitBackingStorePixelRatio ||\n",
       "\tthis.context.mozBackingStorePixelRatio ||\n",
       "\tthis.context.msBackingStorePixelRatio ||\n",
       "\tthis.context.oBackingStorePixelRatio ||\n",
       "\tthis.context.backingStorePixelRatio || 1;\n",
       "\n",
       "    mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
       "\n",
       "    var rubberband = $('<canvas/>');\n",
       "    rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
       "\n",
       "    var pass_mouse_events = true;\n",
       "\n",
       "    canvas_div.resizable({\n",
       "        start: function(event, ui) {\n",
       "            pass_mouse_events = false;\n",
       "        },\n",
       "        resize: function(event, ui) {\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "        stop: function(event, ui) {\n",
       "            pass_mouse_events = true;\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "    });\n",
       "\n",
       "    function mouse_event_fn(event) {\n",
       "        if (pass_mouse_events)\n",
       "            return fig.mouse_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    rubberband.mousedown('button_press', mouse_event_fn);\n",
       "    rubberband.mouseup('button_release', mouse_event_fn);\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband.mousemove('motion_notify', mouse_event_fn);\n",
       "\n",
       "    rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
       "    rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
       "\n",
       "    canvas_div.on(\"wheel\", function (event) {\n",
       "        event = event.originalEvent;\n",
       "        event['data'] = 'scroll'\n",
       "        if (event.deltaY < 0) {\n",
       "            event.step = 1;\n",
       "        } else {\n",
       "            event.step = -1;\n",
       "        }\n",
       "        mouse_event_fn(event);\n",
       "    });\n",
       "\n",
       "    canvas_div.append(canvas);\n",
       "    canvas_div.append(rubberband);\n",
       "\n",
       "    this.rubberband = rubberband;\n",
       "    this.rubberband_canvas = rubberband[0];\n",
       "    this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
       "    this.rubberband_context.strokeStyle = \"#000000\";\n",
       "\n",
       "    this._resize_canvas = function(width, height) {\n",
       "        // Keep the size of the canvas, canvas container, and rubber band\n",
       "        // canvas in synch.\n",
       "        canvas_div.css('width', width)\n",
       "        canvas_div.css('height', height)\n",
       "\n",
       "        canvas.attr('width', width * mpl.ratio);\n",
       "        canvas.attr('height', height * mpl.ratio);\n",
       "        canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
       "\n",
       "        rubberband.attr('width', width);\n",
       "        rubberband.attr('height', height);\n",
       "    }\n",
       "\n",
       "    // Set the figure to an initial 600x600px, this will subsequently be updated\n",
       "    // upon first draw.\n",
       "    this._resize_canvas(600, 600);\n",
       "\n",
       "    // Disable right mouse context menu.\n",
       "    $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
       "        return false;\n",
       "    });\n",
       "\n",
       "    function set_focus () {\n",
       "        canvas.focus();\n",
       "        canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    window.setTimeout(set_focus, 100);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items) {\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) {\n",
       "            // put a spacer in here.\n",
       "            continue;\n",
       "        }\n",
       "        var button = $('<button/>');\n",
       "        button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
       "                        'ui-button-icon-only');\n",
       "        button.attr('role', 'button');\n",
       "        button.attr('aria-disabled', 'false');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "\n",
       "        var icon_img = $('<span/>');\n",
       "        icon_img.addClass('ui-button-icon-primary ui-icon');\n",
       "        icon_img.addClass(image);\n",
       "        icon_img.addClass('ui-corner-all');\n",
       "\n",
       "        var tooltip_span = $('<span/>');\n",
       "        tooltip_span.addClass('ui-button-text');\n",
       "        tooltip_span.html(tooltip);\n",
       "\n",
       "        button.append(icon_img);\n",
       "        button.append(tooltip_span);\n",
       "\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    var fmt_picker_span = $('<span/>');\n",
       "\n",
       "    var fmt_picker = $('<select/>');\n",
       "    fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
       "    fmt_picker_span.append(fmt_picker);\n",
       "    nav_element.append(fmt_picker_span);\n",
       "    this.format_dropdown = fmt_picker[0];\n",
       "\n",
       "    for (var ind in mpl.extensions) {\n",
       "        var fmt = mpl.extensions[ind];\n",
       "        var option = $(\n",
       "            '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
       "        fmt_picker.append(option)\n",
       "    }\n",
       "\n",
       "    // Add hover states to the ui-buttons\n",
       "    $( \".ui-button\" ).hover(\n",
       "        function() { $(this).addClass(\"ui-state-hover\");},\n",
       "        function() { $(this).removeClass(\"ui-state-hover\");}\n",
       "    );\n",
       "\n",
       "    var status_bar = $('<span class=\"mpl-message\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
       "    // which will in turn request a refresh of the image.\n",
       "    this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_message = function(type, properties) {\n",
       "    properties['type'] = type;\n",
       "    properties['figure_id'] = this.id;\n",
       "    this.ws.send(JSON.stringify(properties));\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_draw_message = function() {\n",
       "    if (!this.waiting) {\n",
       "        this.waiting = true;\n",
       "        this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
       "    }\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    var format_dropdown = fig.format_dropdown;\n",
       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
       "    fig.ondownload(fig, format);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
       "    var size = msg['size'];\n",
       "    if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
       "        fig._resize_canvas(size[0], size[1]);\n",
       "        fig.send_message(\"refresh\", {});\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
       "    var x0 = msg['x0'] / mpl.ratio;\n",
       "    var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
       "    var x1 = msg['x1'] / mpl.ratio;\n",
       "    var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
       "    x0 = Math.floor(x0) + 0.5;\n",
       "    y0 = Math.floor(y0) + 0.5;\n",
       "    x1 = Math.floor(x1) + 0.5;\n",
       "    y1 = Math.floor(y1) + 0.5;\n",
       "    var min_x = Math.min(x0, x1);\n",
       "    var min_y = Math.min(y0, y1);\n",
       "    var width = Math.abs(x1 - x0);\n",
       "    var height = Math.abs(y1 - y0);\n",
       "\n",
       "    fig.rubberband_context.clearRect(\n",
       "        0, 0, fig.canvas.width, fig.canvas.height);\n",
       "\n",
       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
       "    // Updates the figure title.\n",
       "    fig.header.textContent = msg['label'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
       "    var cursor = msg['cursor'];\n",
       "    switch(cursor)\n",
       "    {\n",
       "    case 0:\n",
       "        cursor = 'pointer';\n",
       "        break;\n",
       "    case 1:\n",
       "        cursor = 'default';\n",
       "        break;\n",
       "    case 2:\n",
       "        cursor = 'crosshair';\n",
       "        break;\n",
       "    case 3:\n",
       "        cursor = 'move';\n",
       "        break;\n",
       "    }\n",
       "    fig.rubberband_canvas.style.cursor = cursor;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
       "    fig.message.textContent = msg['message'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
       "    // Request the server to send over a new figure.\n",
       "    fig.send_draw_message();\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
       "    fig.image_mode = msg['mode'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Called whenever the canvas gets updated.\n",
       "    this.send_message(\"ack\", {});\n",
       "}\n",
       "\n",
       "// A function to construct a web socket function for onmessage handling.\n",
       "// Called in the figure constructor.\n",
       "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
       "    return function socket_on_message(evt) {\n",
       "        if (evt.data instanceof Blob) {\n",
       "            /* FIXME: We get \"Resource interpreted as Image but\n",
       "             * transferred with MIME type text/plain:\" errors on\n",
       "             * Chrome.  But how to set the MIME type?  It doesn't seem\n",
       "             * to be part of the websocket stream */\n",
       "            evt.data.type = \"image/png\";\n",
       "\n",
       "            /* Free the memory for the previous frames */\n",
       "            if (fig.imageObj.src) {\n",
       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
       "                    fig.imageObj.src);\n",
       "            }\n",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data);\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "        else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
       "            fig.imageObj.src = evt.data;\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        var msg = JSON.parse(evt.data);\n",
       "        var msg_type = msg['type'];\n",
       "\n",
       "        // Call the  \"handle_{type}\" callback, which takes\n",
       "        // the figure and JSON message as its only arguments.\n",
       "        try {\n",
       "            var callback = fig[\"handle_\" + msg_type];\n",
       "        } catch (e) {\n",
       "            console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        if (callback) {\n",
       "            try {\n",
       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
       "                callback(fig, msg);\n",
       "            } catch (e) {\n",
       "                console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
       "            }\n",
       "        }\n",
       "    };\n",
       "}\n",
       "\n",
       "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
       "mpl.findpos = function(e) {\n",
       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
       "    var targ;\n",
       "    if (!e)\n",
       "        e = window.event;\n",
       "    if (e.target)\n",
       "        targ = e.target;\n",
       "    else if (e.srcElement)\n",
       "        targ = e.srcElement;\n",
       "    if (targ.nodeType == 3) // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "\n",
       "    // jQuery normalizes the pageX and pageY\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    // offset() returns the position of the element relative to the document\n",
       "    var x = e.pageX - $(targ).offset().left;\n",
       "    var y = e.pageY - $(targ).offset().top;\n",
       "\n",
       "    return {\"x\": x, \"y\": y};\n",
       "};\n",
       "\n",
       "/*\n",
       " * return a copy of an object with only non-object keys\n",
       " * we need this to avoid circular references\n",
       " * http://stackoverflow.com/a/24161582/3208463\n",
       " */\n",
       "function simpleKeys (original) {\n",
       "  return Object.keys(original).reduce(function (obj, key) {\n",
       "    if (typeof original[key] !== 'object')\n",
       "        obj[key] = original[key]\n",
       "    return obj;\n",
       "  }, {});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.mouse_event = function(event, name) {\n",
       "    var canvas_pos = mpl.findpos(event)\n",
       "\n",
       "    if (name === 'button_press')\n",
       "    {\n",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * mpl.ratio;\n",
       "    var y = canvas_pos.y * mpl.ratio;\n",
       "\n",
       "    this.send_message(name, {x: x, y: y, button: event.button,\n",
       "                             step: event.step,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "\n",
       "    /* This prevents the web browser from automatically changing to\n",
       "     * the text insertion cursor when the button is pressed.  We want\n",
       "     * to control all of the cursor setting manually through the\n",
       "     * 'cursor' event from matplotlib */\n",
       "    event.preventDefault();\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    // Handle any extra behaviour associated with a key event\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.key_event = function(event, name) {\n",
       "\n",
       "    // Prevent repeat events\n",
       "    if (name == 'key_press')\n",
       "    {\n",
       "        if (event.which === this._key)\n",
       "            return;\n",
       "        else\n",
       "            this._key = event.which;\n",
       "    }\n",
       "    if (name == 'key_release')\n",
       "        this._key = null;\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which != 17)\n",
       "        value += \"ctrl+\";\n",
       "    if (event.altKey && event.which != 18)\n",
       "        value += \"alt+\";\n",
       "    if (event.shiftKey && event.which != 16)\n",
       "        value += \"shift+\";\n",
       "\n",
       "    value += 'k';\n",
       "    value += event.which.toString();\n",
       "\n",
       "    this._key_event_extra(event, name);\n",
       "\n",
       "    this.send_message(name, {key: value,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
       "    if (name == 'download') {\n",
       "        this.handle_save(this, null);\n",
       "    } else {\n",
       "        this.send_message(\"toolbar_button\", {name: name});\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
       "    this.message.textContent = tooltip;\n",
       "};\n",
       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
       "\n",
       "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
       "\n",
       "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
       "    // object with the appropriate methods. Currently this is a non binary\n",
       "    // socket, so there is still some room for performance tuning.\n",
       "    var ws = {};\n",
       "\n",
       "    ws.close = function() {\n",
       "        comm.close()\n",
       "    };\n",
       "    ws.send = function(m) {\n",
       "        //console.log('sending', m);\n",
       "        comm.send(m);\n",
       "    };\n",
       "    // Register the callback with on_msg.\n",
       "    comm.on_msg(function(msg) {\n",
       "        //console.log('receiving', msg['content']['data'], msg);\n",
       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
       "        ws.onmessage(msg['content']['data'])\n",
       "    });\n",
       "    return ws;\n",
       "}\n",
       "\n",
       "mpl.mpl_figure_comm = function(comm, msg) {\n",
       "    // This is the function which gets called when the mpl process\n",
       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
       "\n",
       "    var id = msg.content.data.id;\n",
       "    // Get hold of the div created by the display call when the Comm\n",
       "    // socket was opened in Python.\n",
       "    var element = $(\"#\" + id);\n",
       "    var ws_proxy = comm_websocket_adapter(comm)\n",
       "\n",
       "    function ondownload(figure, format) {\n",
       "        window.open(figure.imageObj.src);\n",
       "    }\n",
       "\n",
       "    var fig = new mpl.figure(id, ws_proxy,\n",
       "                           ondownload,\n",
       "                           element.get(0));\n",
       "\n",
       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
       "    // web socket which is closed, not our websocket->open comm proxy.\n",
       "    ws_proxy.onopen();\n",
       "\n",
       "    fig.parent_element = element.get(0);\n",
       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
       "    if (!fig.cell_info) {\n",
       "        console.error(\"Failed to find cell for figure\", id, fig);\n",
       "        return;\n",
       "    }\n",
       "\n",
       "    var output_index = fig.cell_info[2]\n",
       "    var cell = fig.cell_info[0];\n",
       "\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
       "    var width = fig.canvas.width/mpl.ratio\n",
       "    fig.root.unbind('remove')\n",
       "\n",
       "    // Update the output cell to use the data from the current canvas.\n",
       "    fig.push_to_output();\n",
       "    var dataURL = fig.canvas.toDataURL();\n",
       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
       "    // the notebook keyboard shortcuts fail.\n",
       "    IPython.keyboard_manager.enable()\n",
       "    $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
       "    fig.close_ws(fig, msg);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.close_ws = function(fig, msg){\n",
       "    fig.send_message('closing', msg);\n",
       "    // fig.ws.close()\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
       "    // Turn the data on the canvas into data in the output cell.\n",
       "    var width = this.canvas.width/mpl.ratio\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Tell IPython that the notebook contents must change.\n",
       "    IPython.notebook.set_dirty(true);\n",
       "    this.send_message(\"ack\", {});\n",
       "    var fig = this;\n",
       "    // Wait a second, then push the new image to the DOM so\n",
       "    // that it is saved nicely (might be nice to debounce this).\n",
       "    setTimeout(function () { fig.push_to_output() }, 1000);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items){\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) { continue; };\n",
       "\n",
       "        var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    // Add the status bar.\n",
       "    var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "\n",
       "    // Add the close button to the window.\n",
       "    var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
       "    var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
       "    button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
       "    button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
       "    buttongrp.append(button);\n",
       "    var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
       "    titlebar.prepend(buttongrp);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(el){\n",
       "    var fig = this\n",
       "    el.on(\"remove\", function(){\n",
       "\tfig.close_ws(fig, {});\n",
       "    });\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(el){\n",
       "    // this is important to make the div 'focusable\n",
       "    el.attr('tabindex', 0)\n",
       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
       "    // off when our div gets focus\n",
       "\n",
       "    // location in version 3\n",
       "    if (IPython.notebook.keyboard_manager) {\n",
       "        IPython.notebook.keyboard_manager.register_events(el);\n",
       "    }\n",
       "    else {\n",
       "        // location in version 2\n",
       "        IPython.keyboard_manager.register_events(el);\n",
       "    }\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager)\n",
       "        manager = IPython.keyboard_manager;\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which == 13) {\n",
       "        this.canvas_div.blur();\n",
       "        event.shiftKey = false;\n",
       "        // Send a \"J\" for go to next cell\n",
       "        event.which = 74;\n",
       "        event.keyCode = 74;\n",
       "        manager.command_mode();\n",
       "        manager.handle_keydown(event);\n",
       "    }\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.find_output_cell = function(html_output) {\n",
       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
       "    // IPython event is triggered only after the cells have been serialised, which for\n",
       "    // our purposes (turning an active figure into a static one), is too late.\n",
       "    var cells = IPython.notebook.get_cells();\n",
       "    var ncells = cells.length;\n",
       "    for (var i=0; i<ncells; i++) {\n",
       "        var cell = cells[i];\n",
       "        if (cell.cell_type === 'code'){\n",
       "            for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
       "                var data = cell.output_area.outputs[j];\n",
       "                if (data.data) {\n",
       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
       "                    data = data.data;\n",
       "                }\n",
       "                if (data['text/html'] == html_output) {\n",
       "                    return [cell, data, j];\n",
       "                }\n",
       "            }\n",
       "        }\n",
       "    }\n",
       "}\n",
       "\n",
       "// Register the function which deals with the matplotlib target/channel.\n",
       "// The kernel may be null if the page has been refreshed.\n",
       "if (IPython.notebook.kernel != null) {\n",
       "    IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
       "}\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,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B9ITTzzR+NqSJUvosssuIyKibdu20YABA2jXrl2Nr8+fP58WL17s/ffMkZ/97Gc0depUuueeexroKfszPvzwwzRs2DA6dOhQ4+vnnXce3XXXXX5/85Y5//zz6fvf/36/H0/p34H3v//99OMf/7jx19/73vdo+vTp0X8Pbrnllhb02P55Y/lvIvUAPQnm1VdfJSEEPfvss40f+8UvfkHHHXdcVCOu5uzfv59OOeUU+slPfkKPP/44HXvssXT48OHG19etW0fjx48nIqL169fTmDFjWv7+FStW0IwZM7z+njmyb98+mjhxIj355JN07733NtBT9mdcvXo1XXDBBS1fX7hwIV199dV+fuMMOXToEB133HF0xx130IQJE+jkk0+mK664gnbt2pXUvwP33HMPzZkzh/bs2UOvvPIKTZ8+ne64447ovwft6LH988bw3wQC9CSZ7du3kxCCXnvttcaPPfPMMySEoP3791f4O3OT3t5e6urqogsuuIAOHz5Mjz32GA0ZMqTl52zcuJE6OzuJiGjt2rU0efLklq+vWbOGpkyZ4u33zJUbbriBbrzxRiKiFvSU/RlvvfVWmj17dsvXlyxZQvPmzfPwu+bJCy+8QEIIOuOMM+j555+n119/nWbPnk1z585N6t+Bp59+ms4991w65phjSEpJF110ER04cCD670E7emz/vDH8N4EAPUmmr+l57rnnGj/2y1/+Msqmp7e3l6655hr64Ac/2Fje7PtffM1/1gceeKDlf/GNHTu25Z+zcuXK2vwv3L786le/olNPPZV6enqIiPo1PUV/xtWrV9OFF17Y8vVFixbV6n/VvvbaaySEoB/+8IeNH9u8eTOdcMIJyfw7cPjwYRo9ejQtWbKEenp6aM+ePXTttdfSxz72sei/B3lNj+mfN4b/JhCgJ9mMHDmyZYHvBz/4QXQ7Pb29vbRgwQI688wz6dVXX238eN9sv7u7u/FjS5cuLZztd3V11WaXoS/f/va3afDgwdTZ2UmdnZ309re/nQYMGECdnZ20efPmwj/jww8/TMOHD28ZBZx//vm1219497vfTXfffXfjrzdv3kyDBw+mvXv3JvHvwMsvv0xCiJZl2+7ubjrmmGOi/x7k7fSY/nlj+W8i9QA9ieamm26iKVOm0EsvvUTbt2+nSZMmRXV6i+jIvP3000+nV155pd/XrrzySpo9ezbt2bOHtm7dSp2dnS0InDp1Ki1cuJB6enpo06ZNtTi10p59+/bRzp07G5+77rqLJk+eTDt37qTe3t7CP2PfSZXbb7+dDhw4QOvWraMTTzyRXnzxxYr/VHpZvnw5nXnmmbRz5076/e9/Tx//+Mdp7ty5RJTGvwNEROPGjaObb76Z3njjDdq3b1/jvwuiOL8Hb775Ju3fv5+WLl1Kl19+Oe3fv5/eeOMNIrL788by30TqAXoSzcGDB+naa6+lIUOG0NChQ+n666+ParT17LPPkhCC3va2t9EJJ5zQ+FxzzTVEdOS+jrlz51JHRwd1dnZm3tcxc+ZMGjRoEI0aNaoW95OUpXm8RVT+Z3zyySfpnHPOoeOPP54mTpxYyztJ3nzzTbruuuta7qjp+1/yqfw7sHXrVpoxYwYNHTqUhg4dSjNnzqRf//rXRBTn9+CWW24hIUTLZ/o+ngzpAAABDElEQVT06URk/+eN4b+J1AP0IAiCIAiSRIAeBEEQBEGSCNCDIAiCIEgSAXoQBEEQBEkiQA+CIAiCIEkE6EEQBEEQJIkAPQiCIAiCJBGgB0EQBEGQJAL0IAiCIAiSRIAeBEEQBEGSCNCDIAiCIEgSAXoQBEEQBEkiQA+CIAiCIEkE6EEQBEEQJIkAPQiCIAiCJBGgB0EQBEGQJAL0IAiCIAiSRIAeBEEQBEGSCNCDIAiCIEgSAXoQBEEQBEkiQA+CIAiCIEkE6EEQBEEQJIkAPQiCIAiCJBGgB0EQBEGQJAL0IAiCIAiSRIAeBEEQBEGSCNCDIAiCIEgSAXoQBEEQBEkiQA+CIAiCIEnk/wdSBowILehLJwAAAABJRU5ErkJggg==\" width=\"573\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7f3b85e66e10>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#Reconstruction of diffusion image:\n",
    "\n",
    "img_theo = ai.calcfrom1d(q, I, dim1_unit=\"q_nm^-1\", \n",
    "                         correctSolidAngle=False, \n",
    "                         polarization_factor=None)\n",
    "fig, ax = subplots()\n",
    "ax.imshow(img_theo, norm=LogNorm())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "/* Put everything inside the global mpl namespace */\n",
       "window.mpl = {};\n",
       "\n",
       "\n",
       "mpl.get_websocket_type = function() {\n",
       "    if (typeof(WebSocket) !== 'undefined') {\n",
       "        return WebSocket;\n",
       "    } else if (typeof(MozWebSocket) !== 'undefined') {\n",
       "        return MozWebSocket;\n",
       "    } else {\n",
       "        alert('Your browser does not have WebSocket support.' +\n",
       "              'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
       "              'Firefox 4 and 5 are also supported but you ' +\n",
       "              'have to enable WebSockets in about:config.');\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
       "    this.id = figure_id;\n",
       "\n",
       "    this.ws = websocket;\n",
       "\n",
       "    this.supports_binary = (this.ws.binaryType != undefined);\n",
       "\n",
       "    if (!this.supports_binary) {\n",
       "        var warnings = document.getElementById(\"mpl-warnings\");\n",
       "        if (warnings) {\n",
       "            warnings.style.display = 'block';\n",
       "            warnings.textContent = (\n",
       "                \"This browser does not support binary websocket messages. \" +\n",
       "                    \"Performance may be slow.\");\n",
       "        }\n",
       "    }\n",
       "\n",
       "    this.imageObj = new Image();\n",
       "\n",
       "    this.context = undefined;\n",
       "    this.message = undefined;\n",
       "    this.canvas = undefined;\n",
       "    this.rubberband_canvas = undefined;\n",
       "    this.rubberband_context = undefined;\n",
       "    this.format_dropdown = undefined;\n",
       "\n",
       "    this.image_mode = 'full';\n",
       "\n",
       "    this.root = $('<div/>');\n",
       "    this._root_extra_style(this.root)\n",
       "    this.root.attr('style', 'display: inline-block');\n",
       "\n",
       "    $(parent_element).append(this.root);\n",
       "\n",
       "    this._init_header(this);\n",
       "    this._init_canvas(this);\n",
       "    this._init_toolbar(this);\n",
       "\n",
       "    var fig = this;\n",
       "\n",
       "    this.waiting = false;\n",
       "\n",
       "    this.ws.onopen =  function () {\n",
       "            fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
       "            fig.send_message(\"send_image_mode\", {});\n",
       "            if (mpl.ratio != 1) {\n",
       "                fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
       "            }\n",
       "            fig.send_message(\"refresh\", {});\n",
       "        }\n",
       "\n",
       "    this.imageObj.onload = function() {\n",
       "            if (fig.image_mode == 'full') {\n",
       "                // Full images could contain transparency (where diff images\n",
       "                // almost always do), so we need to clear the canvas so that\n",
       "                // there is no ghosting.\n",
       "                fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
       "            }\n",
       "            fig.context.drawImage(fig.imageObj, 0, 0);\n",
       "        };\n",
       "\n",
       "    this.imageObj.onunload = function() {\n",
       "        fig.ws.close();\n",
       "    }\n",
       "\n",
       "    this.ws.onmessage = this._make_on_message_function(this);\n",
       "\n",
       "    this.ondownload = ondownload;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_header = function() {\n",
       "    var titlebar = $(\n",
       "        '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
       "        'ui-helper-clearfix\"/>');\n",
       "    var titletext = $(\n",
       "        '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
       "        'text-align: center; padding: 3px;\"/>');\n",
       "    titlebar.append(titletext)\n",
       "    this.root.append(titlebar);\n",
       "    this.header = titletext[0];\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_canvas = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var canvas_div = $('<div/>');\n",
       "\n",
       "    canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
       "\n",
       "    function canvas_keyboard_event(event) {\n",
       "        return fig.key_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    canvas_div.keydown('key_press', canvas_keyboard_event);\n",
       "    canvas_div.keyup('key_release', canvas_keyboard_event);\n",
       "    this.canvas_div = canvas_div\n",
       "    this._canvas_extra_style(canvas_div)\n",
       "    this.root.append(canvas_div);\n",
       "\n",
       "    var canvas = $('<canvas/>');\n",
       "    canvas.addClass('mpl-canvas');\n",
       "    canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
       "\n",
       "    this.canvas = canvas[0];\n",
       "    this.context = canvas[0].getContext(\"2d\");\n",
       "\n",
       "    var backingStore = this.context.backingStorePixelRatio ||\n",
       "\tthis.context.webkitBackingStorePixelRatio ||\n",
       "\tthis.context.mozBackingStorePixelRatio ||\n",
       "\tthis.context.msBackingStorePixelRatio ||\n",
       "\tthis.context.oBackingStorePixelRatio ||\n",
       "\tthis.context.backingStorePixelRatio || 1;\n",
       "\n",
       "    mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
       "\n",
       "    var rubberband = $('<canvas/>');\n",
       "    rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
       "\n",
       "    var pass_mouse_events = true;\n",
       "\n",
       "    canvas_div.resizable({\n",
       "        start: function(event, ui) {\n",
       "            pass_mouse_events = false;\n",
       "        },\n",
       "        resize: function(event, ui) {\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "        stop: function(event, ui) {\n",
       "            pass_mouse_events = true;\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "    });\n",
       "\n",
       "    function mouse_event_fn(event) {\n",
       "        if (pass_mouse_events)\n",
       "            return fig.mouse_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    rubberband.mousedown('button_press', mouse_event_fn);\n",
       "    rubberband.mouseup('button_release', mouse_event_fn);\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband.mousemove('motion_notify', mouse_event_fn);\n",
       "\n",
       "    rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
       "    rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
       "\n",
       "    canvas_div.on(\"wheel\", function (event) {\n",
       "        event = event.originalEvent;\n",
       "        event['data'] = 'scroll'\n",
       "        if (event.deltaY < 0) {\n",
       "            event.step = 1;\n",
       "        } else {\n",
       "            event.step = -1;\n",
       "        }\n",
       "        mouse_event_fn(event);\n",
       "    });\n",
       "\n",
       "    canvas_div.append(canvas);\n",
       "    canvas_div.append(rubberband);\n",
       "\n",
       "    this.rubberband = rubberband;\n",
       "    this.rubberband_canvas = rubberband[0];\n",
       "    this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
       "    this.rubberband_context.strokeStyle = \"#000000\";\n",
       "\n",
       "    this._resize_canvas = function(width, height) {\n",
       "        // Keep the size of the canvas, canvas container, and rubber band\n",
       "        // canvas in synch.\n",
       "        canvas_div.css('width', width)\n",
       "        canvas_div.css('height', height)\n",
       "\n",
       "        canvas.attr('width', width * mpl.ratio);\n",
       "        canvas.attr('height', height * mpl.ratio);\n",
       "        canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
       "\n",
       "        rubberband.attr('width', width);\n",
       "        rubberband.attr('height', height);\n",
       "    }\n",
       "\n",
       "    // Set the figure to an initial 600x600px, this will subsequently be updated\n",
       "    // upon first draw.\n",
       "    this._resize_canvas(600, 600);\n",
       "\n",
       "    // Disable right mouse context menu.\n",
       "    $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
       "        return false;\n",
       "    });\n",
       "\n",
       "    function set_focus () {\n",
       "        canvas.focus();\n",
       "        canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    window.setTimeout(set_focus, 100);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items) {\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) {\n",
       "            // put a spacer in here.\n",
       "            continue;\n",
       "        }\n",
       "        var button = $('<button/>');\n",
       "        button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
       "                        'ui-button-icon-only');\n",
       "        button.attr('role', 'button');\n",
       "        button.attr('aria-disabled', 'false');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "\n",
       "        var icon_img = $('<span/>');\n",
       "        icon_img.addClass('ui-button-icon-primary ui-icon');\n",
       "        icon_img.addClass(image);\n",
       "        icon_img.addClass('ui-corner-all');\n",
       "\n",
       "        var tooltip_span = $('<span/>');\n",
       "        tooltip_span.addClass('ui-button-text');\n",
       "        tooltip_span.html(tooltip);\n",
       "\n",
       "        button.append(icon_img);\n",
       "        button.append(tooltip_span);\n",
       "\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    var fmt_picker_span = $('<span/>');\n",
       "\n",
       "    var fmt_picker = $('<select/>');\n",
       "    fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
       "    fmt_picker_span.append(fmt_picker);\n",
       "    nav_element.append(fmt_picker_span);\n",
       "    this.format_dropdown = fmt_picker[0];\n",
       "\n",
       "    for (var ind in mpl.extensions) {\n",
       "        var fmt = mpl.extensions[ind];\n",
       "        var option = $(\n",
       "            '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
       "        fmt_picker.append(option)\n",
       "    }\n",
       "\n",
       "    // Add hover states to the ui-buttons\n",
       "    $( \".ui-button\" ).hover(\n",
       "        function() { $(this).addClass(\"ui-state-hover\");},\n",
       "        function() { $(this).removeClass(\"ui-state-hover\");}\n",
       "    );\n",
       "\n",
       "    var status_bar = $('<span class=\"mpl-message\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
       "    // which will in turn request a refresh of the image.\n",
       "    this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_message = function(type, properties) {\n",
       "    properties['type'] = type;\n",
       "    properties['figure_id'] = this.id;\n",
       "    this.ws.send(JSON.stringify(properties));\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_draw_message = function() {\n",
       "    if (!this.waiting) {\n",
       "        this.waiting = true;\n",
       "        this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
       "    }\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    var format_dropdown = fig.format_dropdown;\n",
       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
       "    fig.ondownload(fig, format);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
       "    var size = msg['size'];\n",
       "    if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
       "        fig._resize_canvas(size[0], size[1]);\n",
       "        fig.send_message(\"refresh\", {});\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
       "    var x0 = msg['x0'] / mpl.ratio;\n",
       "    var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
       "    var x1 = msg['x1'] / mpl.ratio;\n",
       "    var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
       "    x0 = Math.floor(x0) + 0.5;\n",
       "    y0 = Math.floor(y0) + 0.5;\n",
       "    x1 = Math.floor(x1) + 0.5;\n",
       "    y1 = Math.floor(y1) + 0.5;\n",
       "    var min_x = Math.min(x0, x1);\n",
       "    var min_y = Math.min(y0, y1);\n",
       "    var width = Math.abs(x1 - x0);\n",
       "    var height = Math.abs(y1 - y0);\n",
       "\n",
       "    fig.rubberband_context.clearRect(\n",
       "        0, 0, fig.canvas.width, fig.canvas.height);\n",
       "\n",
       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
       "    // Updates the figure title.\n",
       "    fig.header.textContent = msg['label'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
       "    var cursor = msg['cursor'];\n",
       "    switch(cursor)\n",
       "    {\n",
       "    case 0:\n",
       "        cursor = 'pointer';\n",
       "        break;\n",
       "    case 1:\n",
       "        cursor = 'default';\n",
       "        break;\n",
       "    case 2:\n",
       "        cursor = 'crosshair';\n",
       "        break;\n",
       "    case 3:\n",
       "        cursor = 'move';\n",
       "        break;\n",
       "    }\n",
       "    fig.rubberband_canvas.style.cursor = cursor;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
       "    fig.message.textContent = msg['message'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
       "    // Request the server to send over a new figure.\n",
       "    fig.send_draw_message();\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
       "    fig.image_mode = msg['mode'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Called whenever the canvas gets updated.\n",
       "    this.send_message(\"ack\", {});\n",
       "}\n",
       "\n",
       "// A function to construct a web socket function for onmessage handling.\n",
       "// Called in the figure constructor.\n",
       "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
       "    return function socket_on_message(evt) {\n",
       "        if (evt.data instanceof Blob) {\n",
       "            /* FIXME: We get \"Resource interpreted as Image but\n",
       "             * transferred with MIME type text/plain:\" errors on\n",
       "             * Chrome.  But how to set the MIME type?  It doesn't seem\n",
       "             * to be part of the websocket stream */\n",
       "            evt.data.type = \"image/png\";\n",
       "\n",
       "            /* Free the memory for the previous frames */\n",
       "            if (fig.imageObj.src) {\n",
       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
       "                    fig.imageObj.src);\n",
       "            }\n",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data);\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "        else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
       "            fig.imageObj.src = evt.data;\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        var msg = JSON.parse(evt.data);\n",
       "        var msg_type = msg['type'];\n",
       "\n",
       "        // Call the  \"handle_{type}\" callback, which takes\n",
       "        // the figure and JSON message as its only arguments.\n",
       "        try {\n",
       "            var callback = fig[\"handle_\" + msg_type];\n",
       "        } catch (e) {\n",
       "            console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        if (callback) {\n",
       "            try {\n",
       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
       "                callback(fig, msg);\n",
       "            } catch (e) {\n",
       "                console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
       "            }\n",
       "        }\n",
       "    };\n",
       "}\n",
       "\n",
       "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
       "mpl.findpos = function(e) {\n",
       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
       "    var targ;\n",
       "    if (!e)\n",
       "        e = window.event;\n",
       "    if (e.target)\n",
       "        targ = e.target;\n",
       "    else if (e.srcElement)\n",
       "        targ = e.srcElement;\n",
       "    if (targ.nodeType == 3) // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "\n",
       "    // jQuery normalizes the pageX and pageY\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    // offset() returns the position of the element relative to the document\n",
       "    var x = e.pageX - $(targ).offset().left;\n",
       "    var y = e.pageY - $(targ).offset().top;\n",
       "\n",
       "    return {\"x\": x, \"y\": y};\n",
       "};\n",
       "\n",
       "/*\n",
       " * return a copy of an object with only non-object keys\n",
       " * we need this to avoid circular references\n",
       " * http://stackoverflow.com/a/24161582/3208463\n",
       " */\n",
       "function simpleKeys (original) {\n",
       "  return Object.keys(original).reduce(function (obj, key) {\n",
       "    if (typeof original[key] !== 'object')\n",
       "        obj[key] = original[key]\n",
       "    return obj;\n",
       "  }, {});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.mouse_event = function(event, name) {\n",
       "    var canvas_pos = mpl.findpos(event)\n",
       "\n",
       "    if (name === 'button_press')\n",
       "    {\n",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * mpl.ratio;\n",
       "    var y = canvas_pos.y * mpl.ratio;\n",
       "\n",
       "    this.send_message(name, {x: x, y: y, button: event.button,\n",
       "                             step: event.step,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "\n",
       "    /* This prevents the web browser from automatically changing to\n",
       "     * the text insertion cursor when the button is pressed.  We want\n",
       "     * to control all of the cursor setting manually through the\n",
       "     * 'cursor' event from matplotlib */\n",
       "    event.preventDefault();\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    // Handle any extra behaviour associated with a key event\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.key_event = function(event, name) {\n",
       "\n",
       "    // Prevent repeat events\n",
       "    if (name == 'key_press')\n",
       "    {\n",
       "        if (event.which === this._key)\n",
       "            return;\n",
       "        else\n",
       "            this._key = event.which;\n",
       "    }\n",
       "    if (name == 'key_release')\n",
       "        this._key = null;\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which != 17)\n",
       "        value += \"ctrl+\";\n",
       "    if (event.altKey && event.which != 18)\n",
       "        value += \"alt+\";\n",
       "    if (event.shiftKey && event.which != 16)\n",
       "        value += \"shift+\";\n",
       "\n",
       "    value += 'k';\n",
       "    value += event.which.toString();\n",
       "\n",
       "    this._key_event_extra(event, name);\n",
       "\n",
       "    this.send_message(name, {key: value,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
       "    if (name == 'download') {\n",
       "        this.handle_save(this, null);\n",
       "    } else {\n",
       "        this.send_message(\"toolbar_button\", {name: name});\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
       "    this.message.textContent = tooltip;\n",
       "};\n",
       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
       "\n",
       "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
       "\n",
       "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
       "    // object with the appropriate methods. Currently this is a non binary\n",
       "    // socket, so there is still some room for performance tuning.\n",
       "    var ws = {};\n",
       "\n",
       "    ws.close = function() {\n",
       "        comm.close()\n",
       "    };\n",
       "    ws.send = function(m) {\n",
       "        //console.log('sending', m);\n",
       "        comm.send(m);\n",
       "    };\n",
       "    // Register the callback with on_msg.\n",
       "    comm.on_msg(function(msg) {\n",
       "        //console.log('receiving', msg['content']['data'], msg);\n",
       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
       "        ws.onmessage(msg['content']['data'])\n",
       "    });\n",
       "    return ws;\n",
       "}\n",
       "\n",
       "mpl.mpl_figure_comm = function(comm, msg) {\n",
       "    // This is the function which gets called when the mpl process\n",
       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
       "\n",
       "    var id = msg.content.data.id;\n",
       "    // Get hold of the div created by the display call when the Comm\n",
       "    // socket was opened in Python.\n",
       "    var element = $(\"#\" + id);\n",
       "    var ws_proxy = comm_websocket_adapter(comm)\n",
       "\n",
       "    function ondownload(figure, format) {\n",
       "        window.open(figure.imageObj.src);\n",
       "    }\n",
       "\n",
       "    var fig = new mpl.figure(id, ws_proxy,\n",
       "                           ondownload,\n",
       "                           element.get(0));\n",
       "\n",
       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
       "    // web socket which is closed, not our websocket->open comm proxy.\n",
       "    ws_proxy.onopen();\n",
       "\n",
       "    fig.parent_element = element.get(0);\n",
       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
       "    if (!fig.cell_info) {\n",
       "        console.error(\"Failed to find cell for figure\", id, fig);\n",
       "        return;\n",
       "    }\n",
       "\n",
       "    var output_index = fig.cell_info[2]\n",
       "    var cell = fig.cell_info[0];\n",
       "\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
       "    var width = fig.canvas.width/mpl.ratio\n",
       "    fig.root.unbind('remove')\n",
       "\n",
       "    // Update the output cell to use the data from the current canvas.\n",
       "    fig.push_to_output();\n",
       "    var dataURL = fig.canvas.toDataURL();\n",
       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
       "    // the notebook keyboard shortcuts fail.\n",
       "    IPython.keyboard_manager.enable()\n",
       "    $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
       "    fig.close_ws(fig, msg);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.close_ws = function(fig, msg){\n",
       "    fig.send_message('closing', msg);\n",
       "    // fig.ws.close()\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
       "    // Turn the data on the canvas into data in the output cell.\n",
       "    var width = this.canvas.width/mpl.ratio\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Tell IPython that the notebook contents must change.\n",
       "    IPython.notebook.set_dirty(true);\n",
       "    this.send_message(\"ack\", {});\n",
       "    var fig = this;\n",
       "    // Wait a second, then push the new image to the DOM so\n",
       "    // that it is saved nicely (might be nice to debounce this).\n",
       "    setTimeout(function () { fig.push_to_output() }, 1000);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items){\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) { continue; };\n",
       "\n",
       "        var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    // Add the status bar.\n",
       "    var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "\n",
       "    // Add the close button to the window.\n",
       "    var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
       "    var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
       "    button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
       "    button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
       "    buttongrp.append(button);\n",
       "    var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
       "    titlebar.prepend(buttongrp);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(el){\n",
       "    var fig = this\n",
       "    el.on(\"remove\", function(){\n",
       "\tfig.close_ws(fig, {});\n",
       "    });\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(el){\n",
       "    // this is important to make the div 'focusable\n",
       "    el.attr('tabindex', 0)\n",
       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
       "    // off when our div gets focus\n",
       "\n",
       "    // location in version 3\n",
       "    if (IPython.notebook.keyboard_manager) {\n",
       "        IPython.notebook.keyboard_manager.register_events(el);\n",
       "    }\n",
       "    else {\n",
       "        // location in version 2\n",
       "        IPython.keyboard_manager.register_events(el);\n",
       "    }\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager)\n",
       "        manager = IPython.keyboard_manager;\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which == 13) {\n",
       "        this.canvas_div.blur();\n",
       "        event.shiftKey = false;\n",
       "        // Send a \"J\" for go to next cell\n",
       "        event.which = 74;\n",
       "        event.keyCode = 74;\n",
       "        manager.command_mode();\n",
       "        manager.handle_keydown(event);\n",
       "    }\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.find_output_cell = function(html_output) {\n",
       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
       "    // IPython event is triggered only after the cells have been serialised, which for\n",
       "    // our purposes (turning an active figure into a static one), is too late.\n",
       "    var cells = IPython.notebook.get_cells();\n",
       "    var ncells = cells.length;\n",
       "    for (var i=0; i<ncells; i++) {\n",
       "        var cell = cells[i];\n",
       "        if (cell.cell_type === 'code'){\n",
       "            for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
       "                var data = cell.output_area.outputs[j];\n",
       "                if (data.data) {\n",
       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
       "                    data = data.data;\n",
       "                }\n",
       "                if (data['text/html'] == html_output) {\n",
       "                    return [cell, data, j];\n",
       "                }\n",
       "            }\n",
       "        }\n",
       "    }\n",
       "}\n",
       "\n",
       "// Register the function which deals with the matplotlib target/channel.\n",
       "// The kernel may be null if the page has been refreshed.\n",
       "if (IPython.notebook.kernel != null) {\n",
       "    IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
       "}\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,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ITg4GKNHj8aECRMwZsyYBr/75z//GS+99FK99z755BMMHz4cU6dORY8ePRASEoJFixZpn69duxY333wzpkyZgi5duqBLly7YuHEjNm/ejBtuuAFBQUF4/vnnm1RzY+f0PPvss3j55ZebtC4i8m8MPUR0SWw2G/r06YNp06bBarXiu+++Q1BQUKOhZ9iwYXj//ffrvTd58mQEBQVhzZo1sNvtWLNmDUJCQrTPX375ZQQFBWHdunVwOBx46aWX0L17d/zlL39BeXk5jhw5gpYtWyIrK+uSan7sscfQt29fXH/99Zg0aVK9z+bMmYNf//rXTfwViMifMfQQ0SXZsWMHOnToAIfDob33xBNPNBp6rrnmGmzYsKHee6NHj8Z//vMf7XV6enq90HPffffV+/zTTz9FeHg4bDab9t6VV16Jo0ePNvvvWbZsGW677bZmr4eI/AdDDxFdkk8++QRDhgyp997kyZObtKena9eu2LVrl/Z69erVuP3227XX3bt3xw8//KC9fuWVV/Dcc89pr7OystC2bVvY7fZm/S0A9/QQScTQQ0SXpKE9PU8++eQln9OTl5eHli1borKyUntv8uTJmDBhAgAgPz8fLVu2RFVVlfb5/fffjyVLlmiv169fj4iICLf8PTynh0gehh4iuiQ2mw29evXCjBkzYLPZsH37dgQHBzcaej777DPceuut2uuvv/4aAwcOrPede+65B8uXLwcAbN68+YLPu3fvjoSEBO31K6+8gj//+c9u+Xv69u2LuLg4t6yLiPwDQw8RXbLU1FREREQgKCgIo0aNuujVW3a7Hb169dLu0zNz5kz8/ve/r/edTp06ITk5ucHPz549i1atWqGmpkZ77/7778fChQub/Xfs2rULN954Y7PXQ0T+haGHiC6bqqqNhh4A+OCDDwy/I3ND7r33Xnz99ddGl0FEXsbQQ0SXTS/0EBH5EoYeIrpsDD1E5E8YeoiIiEgEhh4iIiISgaGHiIiIRGDoISIiIhEYeoiIiEiE/wdbrnd5NRM42AAAAABJRU5ErkJggg==\" width=\"573\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7f3b85195cf8>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fig, ax = subplots()\n",
    "ax.semilogy(q, I, label=\"Simulated signal\")\n",
    "ax.set_xlabel(\"q ($nm^{-1}$)\")\n",
    "ax.set_ylabel(\"I (count)\")\n",
    "res = ai.integrate1d(img_theo, **kwarg)\n",
    "ax.plot(*res, label=\"Integrated image\")\n",
    "\n",
    "#Display the error: commented as it makes the graph less readable\n",
    "#I_bins = I0/(1+res.radial**2)\n",
    "#ax.plot(res.radial, abs(res.intensity-I_bins), label=\"error\")\n",
    "fig.legend()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Construction of a synthetic dataset\n",
    "\n",
    "We construct now a synthetic dataset of thousand images of this reference image with a statistical distribution which is common for photon-counting detectors (like Pilatus or Eiger): The Poisson distribution. The signal is between 100 and 10000, so every pixel should see photons and there is should be no \"rare-events\" bias (which sometimes occures in SAXS).\n",
    "\n",
    "### Poisson distribution:\n",
    "The Poisson distribution has the peculiarity of having its variance equal to the signal, hence the standard deviation equals to the square root of the signal. \n",
    "\n",
    "\n",
    "**Nota:** the generation of the images is slow and takes about 1Gbyte of memory !\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1000.0 MBytes (1000, 1024, 1024)\n",
      "CPU times: user 1min 21s, sys: 1.6 s, total: 1min 22s\n",
      "Wall time: 1min 22s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "\n",
    "if \"dataset\" not in dir():\n",
    "    dataset = numpy.random.poisson(img_theo, (nimg,) + img_theo.shape)\n",
    "# else avoid wasting time\n",
    "print(dataset.size/(1<<20), \"MBytes\", dataset.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Validation of the Poisson distribution.\n",
    "\n",
    "We have now thousand images of one magapixel. It is interesting to validate if the distribution actually follows the Poisson distribution. For this we will check if the *signal* and its *variance* follow a $\\chi^2$ distribution. \n",
    "\n",
    "For every pair of images I and J we calculate the numerical value of $\\chi ^2$:\n",
    "\n",
    "$$\n",
    "\\chi^2 = \\frac{1}{nbpixel-1}\\sum_{pix}\\frac{(I_{pix} - J_{pix})^2}{\\sigma(I_{pix})^2 + \\sigma(J_{pix})^2)}\n",
    "$$\n",
    "\n",
    "The distibution is obtained by calculating the histogram of $\\chi^2$ values for every pair of images, here almost half a milion. \n",
    "\n",
    "The calculation of the $\\chi^2$ value is likely to be critical in time, so we will shortly investigate 3 implementation: *numpy* (fail-safe but not that fast), *numexp* and *numba*\n",
    "Do not worry if any of the two later method fail: they are faster but provide the same numerical result as numpy."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Number of paires of images:  499500\n"
     ]
    }
   ],
   "source": [
    "print(\"Number of paires of images: \", nimg*(nimg-1)//2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.9995950907530075\n",
      "6.95 ms ± 8.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
     ]
    }
   ],
   "source": [
    "#Numpy implementation of Chi^2 measurement for a pair of images. Fail-safe implementation\n",
    "\n",
    "def chi2_images_np(I, J):\n",
    "    \"\"\"Calculate the Chi2 value for a pair of images with poissonnian noise \n",
    "    Numpy implementation\"\"\"\n",
    "    return ((I-J)**2/(I+J)).sum()/(I.size - 1)\n",
    "\n",
    "img0 = dataset[0]\n",
    "img1 = dataset[1]\n",
    "print(chi2_images_np(img0, img1))\n",
    "%timeit chi2_images_np(img0, img1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.9995950907530075\n",
      "1.71 ms ± 47.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n"
     ]
    }
   ],
   "source": [
    "#Numexp implementation of Chi^2 measurement for a pair of images. \n",
    "from numexpr import NumExpr\n",
    "expr = NumExpr(\"((I-J)**2/(I+J))\", signature=[(\"I\", numpy.float64),(\"J\", numpy.float64)])\n",
    "\n",
    "def chi2_images_ne(I, J):\n",
    "    \"\"\"Calculate the Chi2 value for a pair of images with poissonnian noise\n",
    "    NumExpr implementation\"\"\"\n",
    "    return expr(I, J).sum()/(I.size-1)\n",
    "\n",
    "img0 = dataset[0]\n",
    "img1 = dataset[1]\n",
    "print(chi2_images_ne(img0, img1))\n",
    "%timeit chi2_images_ne(img0, img1)\n",
    "\n",
    "#May fail if numexpr is not installed, but gives the same numerical value, just faster"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.9995950907527901\n",
      "1.4 ms ± 1.13 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n"
     ]
    }
   ],
   "source": [
    "#Numba implementation of Chi^2 measurement for a pair of images. \n",
    "from numba import jit\n",
    "\n",
    "@jit\n",
    "def chi2_images_nu(img1, img2):\n",
    "    \"\"\"Calculate the Chi2 value for a pair of images with poissonnian noise\n",
    "    Numba implementation\"\"\"\n",
    "    I = img1.ravel()\n",
    "    J = img2.ravel()\n",
    "    l = len(I)\n",
    "    assert len(J) == l\n",
    "    #version optimized for JIT\n",
    "    s = 0.0\n",
    "    for i in range(len(I)):\n",
    "        a = float(I[i])\n",
    "        b = float(J[i])\n",
    "        s+= (a-b)**2/(a+b)\n",
    "    return s/(l-1)\n",
    "\n",
    "img0 = dataset[0]\n",
    "img1 = dataset[1]\n",
    "print(chi2_images_nu(img0, img1))\n",
    "%timeit chi2_images_nu(img0, img1)\n",
    "\n",
    "#May fail if numba is not installed. \n",
    "# The numerical value, may differ due to reduction algorithm used, should be the fastest."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Select the prefered algorithm for calculating the numerical value of chi^2 for a pair of images.\n",
    "chi2_images = chi2_images_ne"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 1h 4min 19s, sys: 44.8 s, total: 1h 5min 4s\n",
      "Wall time: 15min 14s\n"
     ]
    }
   ],
   "source": [
    "%%time \n",
    "\n",
    "#Calculate the numerical value for chi2 for every pair of images. This takes a while\n",
    "\n",
    "c2i = []\n",
    "for i in range(nimg):\n",
    "    img1 = dataset[i]\n",
    "    for j in range(i):\n",
    "        c2i.append(chi2_images(img1, dataset[j]))\n",
    "c2i = numpy.array(c2i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "/* Put everything inside the global mpl namespace */\n",
       "window.mpl = {};\n",
       "\n",
       "\n",
       "mpl.get_websocket_type = function() {\n",
       "    if (typeof(WebSocket) !== 'undefined') {\n",
       "        return WebSocket;\n",
       "    } else if (typeof(MozWebSocket) !== 'undefined') {\n",
       "        return MozWebSocket;\n",
       "    } else {\n",
       "        alert('Your browser does not have WebSocket support.' +\n",
       "              'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
       "              'Firefox 4 and 5 are also supported but you ' +\n",
       "              'have to enable WebSockets in about:config.');\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
       "    this.id = figure_id;\n",
       "\n",
       "    this.ws = websocket;\n",
       "\n",
       "    this.supports_binary = (this.ws.binaryType != undefined);\n",
       "\n",
       "    if (!this.supports_binary) {\n",
       "        var warnings = document.getElementById(\"mpl-warnings\");\n",
       "        if (warnings) {\n",
       "            warnings.style.display = 'block';\n",
       "            warnings.textContent = (\n",
       "                \"This browser does not support binary websocket messages. \" +\n",
       "                    \"Performance may be slow.\");\n",
       "        }\n",
       "    }\n",
       "\n",
       "    this.imageObj = new Image();\n",
       "\n",
       "    this.context = undefined;\n",
       "    this.message = undefined;\n",
       "    this.canvas = undefined;\n",
       "    this.rubberband_canvas = undefined;\n",
       "    this.rubberband_context = undefined;\n",
       "    this.format_dropdown = undefined;\n",
       "\n",
       "    this.image_mode = 'full';\n",
       "\n",
       "    this.root = $('<div/>');\n",
       "    this._root_extra_style(this.root)\n",
       "    this.root.attr('style', 'display: inline-block');\n",
       "\n",
       "    $(parent_element).append(this.root);\n",
       "\n",
       "    this._init_header(this);\n",
       "    this._init_canvas(this);\n",
       "    this._init_toolbar(this);\n",
       "\n",
       "    var fig = this;\n",
       "\n",
       "    this.waiting = false;\n",
       "\n",
       "    this.ws.onopen =  function () {\n",
       "            fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
       "            fig.send_message(\"send_image_mode\", {});\n",
       "            if (mpl.ratio != 1) {\n",
       "                fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
       "            }\n",
       "            fig.send_message(\"refresh\", {});\n",
       "        }\n",
       "\n",
       "    this.imageObj.onload = function() {\n",
       "            if (fig.image_mode == 'full') {\n",
       "                // Full images could contain transparency (where diff images\n",
       "                // almost always do), so we need to clear the canvas so that\n",
       "                // there is no ghosting.\n",
       "                fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
       "            }\n",
       "            fig.context.drawImage(fig.imageObj, 0, 0);\n",
       "        };\n",
       "\n",
       "    this.imageObj.onunload = function() {\n",
       "        fig.ws.close();\n",
       "    }\n",
       "\n",
       "    this.ws.onmessage = this._make_on_message_function(this);\n",
       "\n",
       "    this.ondownload = ondownload;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_header = function() {\n",
       "    var titlebar = $(\n",
       "        '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
       "        'ui-helper-clearfix\"/>');\n",
       "    var titletext = $(\n",
       "        '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
       "        'text-align: center; padding: 3px;\"/>');\n",
       "    titlebar.append(titletext)\n",
       "    this.root.append(titlebar);\n",
       "    this.header = titletext[0];\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_canvas = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var canvas_div = $('<div/>');\n",
       "\n",
       "    canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
       "\n",
       "    function canvas_keyboard_event(event) {\n",
       "        return fig.key_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    canvas_div.keydown('key_press', canvas_keyboard_event);\n",
       "    canvas_div.keyup('key_release', canvas_keyboard_event);\n",
       "    this.canvas_div = canvas_div\n",
       "    this._canvas_extra_style(canvas_div)\n",
       "    this.root.append(canvas_div);\n",
       "\n",
       "    var canvas = $('<canvas/>');\n",
       "    canvas.addClass('mpl-canvas');\n",
       "    canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
       "\n",
       "    this.canvas = canvas[0];\n",
       "    this.context = canvas[0].getContext(\"2d\");\n",
       "\n",
       "    var backingStore = this.context.backingStorePixelRatio ||\n",
       "\tthis.context.webkitBackingStorePixelRatio ||\n",
       "\tthis.context.mozBackingStorePixelRatio ||\n",
       "\tthis.context.msBackingStorePixelRatio ||\n",
       "\tthis.context.oBackingStorePixelRatio ||\n",
       "\tthis.context.backingStorePixelRatio || 1;\n",
       "\n",
       "    mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
       "\n",
       "    var rubberband = $('<canvas/>');\n",
       "    rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
       "\n",
       "    var pass_mouse_events = true;\n",
       "\n",
       "    canvas_div.resizable({\n",
       "        start: function(event, ui) {\n",
       "            pass_mouse_events = false;\n",
       "        },\n",
       "        resize: function(event, ui) {\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "        stop: function(event, ui) {\n",
       "            pass_mouse_events = true;\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "    });\n",
       "\n",
       "    function mouse_event_fn(event) {\n",
       "        if (pass_mouse_events)\n",
       "            return fig.mouse_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    rubberband.mousedown('button_press', mouse_event_fn);\n",
       "    rubberband.mouseup('button_release', mouse_event_fn);\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband.mousemove('motion_notify', mouse_event_fn);\n",
       "\n",
       "    rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
       "    rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
       "\n",
       "    canvas_div.on(\"wheel\", function (event) {\n",
       "        event = event.originalEvent;\n",
       "        event['data'] = 'scroll'\n",
       "        if (event.deltaY < 0) {\n",
       "            event.step = 1;\n",
       "        } else {\n",
       "            event.step = -1;\n",
       "        }\n",
       "        mouse_event_fn(event);\n",
       "    });\n",
       "\n",
       "    canvas_div.append(canvas);\n",
       "    canvas_div.append(rubberband);\n",
       "\n",
       "    this.rubberband = rubberband;\n",
       "    this.rubberband_canvas = rubberband[0];\n",
       "    this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
       "    this.rubberband_context.strokeStyle = \"#000000\";\n",
       "\n",
       "    this._resize_canvas = function(width, height) {\n",
       "        // Keep the size of the canvas, canvas container, and rubber band\n",
       "        // canvas in synch.\n",
       "        canvas_div.css('width', width)\n",
       "        canvas_div.css('height', height)\n",
       "\n",
       "        canvas.attr('width', width * mpl.ratio);\n",
       "        canvas.attr('height', height * mpl.ratio);\n",
       "        canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
       "\n",
       "        rubberband.attr('width', width);\n",
       "        rubberband.attr('height', height);\n",
       "    }\n",
       "\n",
       "    // Set the figure to an initial 600x600px, this will subsequently be updated\n",
       "    // upon first draw.\n",
       "    this._resize_canvas(600, 600);\n",
       "\n",
       "    // Disable right mouse context menu.\n",
       "    $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
       "        return false;\n",
       "    });\n",
       "\n",
       "    function set_focus () {\n",
       "        canvas.focus();\n",
       "        canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    window.setTimeout(set_focus, 100);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items) {\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) {\n",
       "            // put a spacer in here.\n",
       "            continue;\n",
       "        }\n",
       "        var button = $('<button/>');\n",
       "        button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
       "                        'ui-button-icon-only');\n",
       "        button.attr('role', 'button');\n",
       "        button.attr('aria-disabled', 'false');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "\n",
       "        var icon_img = $('<span/>');\n",
       "        icon_img.addClass('ui-button-icon-primary ui-icon');\n",
       "        icon_img.addClass(image);\n",
       "        icon_img.addClass('ui-corner-all');\n",
       "\n",
       "        var tooltip_span = $('<span/>');\n",
       "        tooltip_span.addClass('ui-button-text');\n",
       "        tooltip_span.html(tooltip);\n",
       "\n",
       "        button.append(icon_img);\n",
       "        button.append(tooltip_span);\n",
       "\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    var fmt_picker_span = $('<span/>');\n",
       "\n",
       "    var fmt_picker = $('<select/>');\n",
       "    fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
       "    fmt_picker_span.append(fmt_picker);\n",
       "    nav_element.append(fmt_picker_span);\n",
       "    this.format_dropdown = fmt_picker[0];\n",
       "\n",
       "    for (var ind in mpl.extensions) {\n",
       "        var fmt = mpl.extensions[ind];\n",
       "        var option = $(\n",
       "            '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
       "        fmt_picker.append(option)\n",
       "    }\n",
       "\n",
       "    // Add hover states to the ui-buttons\n",
       "    $( \".ui-button\" ).hover(\n",
       "        function() { $(this).addClass(\"ui-state-hover\");},\n",
       "        function() { $(this).removeClass(\"ui-state-hover\");}\n",
       "    );\n",
       "\n",
       "    var status_bar = $('<span class=\"mpl-message\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
       "    // which will in turn request a refresh of the image.\n",
       "    this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_message = function(type, properties) {\n",
       "    properties['type'] = type;\n",
       "    properties['figure_id'] = this.id;\n",
       "    this.ws.send(JSON.stringify(properties));\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_draw_message = function() {\n",
       "    if (!this.waiting) {\n",
       "        this.waiting = true;\n",
       "        this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
       "    }\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    var format_dropdown = fig.format_dropdown;\n",
       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
       "    fig.ondownload(fig, format);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
       "    var size = msg['size'];\n",
       "    if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
       "        fig._resize_canvas(size[0], size[1]);\n",
       "        fig.send_message(\"refresh\", {});\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
       "    var x0 = msg['x0'] / mpl.ratio;\n",
       "    var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
       "    var x1 = msg['x1'] / mpl.ratio;\n",
       "    var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
       "    x0 = Math.floor(x0) + 0.5;\n",
       "    y0 = Math.floor(y0) + 0.5;\n",
       "    x1 = Math.floor(x1) + 0.5;\n",
       "    y1 = Math.floor(y1) + 0.5;\n",
       "    var min_x = Math.min(x0, x1);\n",
       "    var min_y = Math.min(y0, y1);\n",
       "    var width = Math.abs(x1 - x0);\n",
       "    var height = Math.abs(y1 - y0);\n",
       "\n",
       "    fig.rubberband_context.clearRect(\n",
       "        0, 0, fig.canvas.width, fig.canvas.height);\n",
       "\n",
       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
       "    // Updates the figure title.\n",
       "    fig.header.textContent = msg['label'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
       "    var cursor = msg['cursor'];\n",
       "    switch(cursor)\n",
       "    {\n",
       "    case 0:\n",
       "        cursor = 'pointer';\n",
       "        break;\n",
       "    case 1:\n",
       "        cursor = 'default';\n",
       "        break;\n",
       "    case 2:\n",
       "        cursor = 'crosshair';\n",
       "        break;\n",
       "    case 3:\n",
       "        cursor = 'move';\n",
       "        break;\n",
       "    }\n",
       "    fig.rubberband_canvas.style.cursor = cursor;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
       "    fig.message.textContent = msg['message'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
       "    // Request the server to send over a new figure.\n",
       "    fig.send_draw_message();\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
       "    fig.image_mode = msg['mode'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Called whenever the canvas gets updated.\n",
       "    this.send_message(\"ack\", {});\n",
       "}\n",
       "\n",
       "// A function to construct a web socket function for onmessage handling.\n",
       "// Called in the figure constructor.\n",
       "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
       "    return function socket_on_message(evt) {\n",
       "        if (evt.data instanceof Blob) {\n",
       "            /* FIXME: We get \"Resource interpreted as Image but\n",
       "             * transferred with MIME type text/plain:\" errors on\n",
       "             * Chrome.  But how to set the MIME type?  It doesn't seem\n",
       "             * to be part of the websocket stream */\n",
       "            evt.data.type = \"image/png\";\n",
       "\n",
       "            /* Free the memory for the previous frames */\n",
       "            if (fig.imageObj.src) {\n",
       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
       "                    fig.imageObj.src);\n",
       "            }\n",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data);\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "        else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
       "            fig.imageObj.src = evt.data;\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        var msg = JSON.parse(evt.data);\n",
       "        var msg_type = msg['type'];\n",
       "\n",
       "        // Call the  \"handle_{type}\" callback, which takes\n",
       "        // the figure and JSON message as its only arguments.\n",
       "        try {\n",
       "            var callback = fig[\"handle_\" + msg_type];\n",
       "        } catch (e) {\n",
       "            console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        if (callback) {\n",
       "            try {\n",
       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
       "                callback(fig, msg);\n",
       "            } catch (e) {\n",
       "                console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
       "            }\n",
       "        }\n",
       "    };\n",
       "}\n",
       "\n",
       "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
       "mpl.findpos = function(e) {\n",
       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
       "    var targ;\n",
       "    if (!e)\n",
       "        e = window.event;\n",
       "    if (e.target)\n",
       "        targ = e.target;\n",
       "    else if (e.srcElement)\n",
       "        targ = e.srcElement;\n",
       "    if (targ.nodeType == 3) // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "\n",
       "    // jQuery normalizes the pageX and pageY\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    // offset() returns the position of the element relative to the document\n",
       "    var x = e.pageX - $(targ).offset().left;\n",
       "    var y = e.pageY - $(targ).offset().top;\n",
       "\n",
       "    return {\"x\": x, \"y\": y};\n",
       "};\n",
       "\n",
       "/*\n",
       " * return a copy of an object with only non-object keys\n",
       " * we need this to avoid circular references\n",
       " * http://stackoverflow.com/a/24161582/3208463\n",
       " */\n",
       "function simpleKeys (original) {\n",
       "  return Object.keys(original).reduce(function (obj, key) {\n",
       "    if (typeof original[key] !== 'object')\n",
       "        obj[key] = original[key]\n",
       "    return obj;\n",
       "  }, {});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.mouse_event = function(event, name) {\n",
       "    var canvas_pos = mpl.findpos(event)\n",
       "\n",
       "    if (name === 'button_press')\n",
       "    {\n",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * mpl.ratio;\n",
       "    var y = canvas_pos.y * mpl.ratio;\n",
       "\n",
       "    this.send_message(name, {x: x, y: y, button: event.button,\n",
       "                             step: event.step,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "\n",
       "    /* This prevents the web browser from automatically changing to\n",
       "     * the text insertion cursor when the button is pressed.  We want\n",
       "     * to control all of the cursor setting manually through the\n",
       "     * 'cursor' event from matplotlib */\n",
       "    event.preventDefault();\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    // Handle any extra behaviour associated with a key event\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.key_event = function(event, name) {\n",
       "\n",
       "    // Prevent repeat events\n",
       "    if (name == 'key_press')\n",
       "    {\n",
       "        if (event.which === this._key)\n",
       "            return;\n",
       "        else\n",
       "            this._key = event.which;\n",
       "    }\n",
       "    if (name == 'key_release')\n",
       "        this._key = null;\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which != 17)\n",
       "        value += \"ctrl+\";\n",
       "    if (event.altKey && event.which != 18)\n",
       "        value += \"alt+\";\n",
       "    if (event.shiftKey && event.which != 16)\n",
       "        value += \"shift+\";\n",
       "\n",
       "    value += 'k';\n",
       "    value += event.which.toString();\n",
       "\n",
       "    this._key_event_extra(event, name);\n",
       "\n",
       "    this.send_message(name, {key: value,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
       "    if (name == 'download') {\n",
       "        this.handle_save(this, null);\n",
       "    } else {\n",
       "        this.send_message(\"toolbar_button\", {name: name});\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
       "    this.message.textContent = tooltip;\n",
       "};\n",
       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
       "\n",
       "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
       "\n",
       "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
       "    // object with the appropriate methods. Currently this is a non binary\n",
       "    // socket, so there is still some room for performance tuning.\n",
       "    var ws = {};\n",
       "\n",
       "    ws.close = function() {\n",
       "        comm.close()\n",
       "    };\n",
       "    ws.send = function(m) {\n",
       "        //console.log('sending', m);\n",
       "        comm.send(m);\n",
       "    };\n",
       "    // Register the callback with on_msg.\n",
       "    comm.on_msg(function(msg) {\n",
       "        //console.log('receiving', msg['content']['data'], msg);\n",
       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
       "        ws.onmessage(msg['content']['data'])\n",
       "    });\n",
       "    return ws;\n",
       "}\n",
       "\n",
       "mpl.mpl_figure_comm = function(comm, msg) {\n",
       "    // This is the function which gets called when the mpl process\n",
       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
       "\n",
       "    var id = msg.content.data.id;\n",
       "    // Get hold of the div created by the display call when the Comm\n",
       "    // socket was opened in Python.\n",
       "    var element = $(\"#\" + id);\n",
       "    var ws_proxy = comm_websocket_adapter(comm)\n",
       "\n",
       "    function ondownload(figure, format) {\n",
       "        window.open(figure.imageObj.src);\n",
       "    }\n",
       "\n",
       "    var fig = new mpl.figure(id, ws_proxy,\n",
       "                           ondownload,\n",
       "                           element.get(0));\n",
       "\n",
       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
       "    // web socket which is closed, not our websocket->open comm proxy.\n",
       "    ws_proxy.onopen();\n",
       "\n",
       "    fig.parent_element = element.get(0);\n",
       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
       "    if (!fig.cell_info) {\n",
       "        console.error(\"Failed to find cell for figure\", id, fig);\n",
       "        return;\n",
       "    }\n",
       "\n",
       "    var output_index = fig.cell_info[2]\n",
       "    var cell = fig.cell_info[0];\n",
       "\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
       "    var width = fig.canvas.width/mpl.ratio\n",
       "    fig.root.unbind('remove')\n",
       "\n",
       "    // Update the output cell to use the data from the current canvas.\n",
       "    fig.push_to_output();\n",
       "    var dataURL = fig.canvas.toDataURL();\n",
       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
       "    // the notebook keyboard shortcuts fail.\n",
       "    IPython.keyboard_manager.enable()\n",
       "    $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
       "    fig.close_ws(fig, msg);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.close_ws = function(fig, msg){\n",
       "    fig.send_message('closing', msg);\n",
       "    // fig.ws.close()\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
       "    // Turn the data on the canvas into data in the output cell.\n",
       "    var width = this.canvas.width/mpl.ratio\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Tell IPython that the notebook contents must change.\n",
       "    IPython.notebook.set_dirty(true);\n",
       "    this.send_message(\"ack\", {});\n",
       "    var fig = this;\n",
       "    // Wait a second, then push the new image to the DOM so\n",
       "    // that it is saved nicely (might be nice to debounce this).\n",
       "    setTimeout(function () { fig.push_to_output() }, 1000);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items){\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) { continue; };\n",
       "\n",
       "        var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    // Add the status bar.\n",
       "    var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "\n",
       "    // Add the close button to the window.\n",
       "    var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
       "    var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
       "    button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
       "    button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
       "    buttongrp.append(button);\n",
       "    var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
       "    titlebar.prepend(buttongrp);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(el){\n",
       "    var fig = this\n",
       "    el.on(\"remove\", function(){\n",
       "\tfig.close_ws(fig, {});\n",
       "    });\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(el){\n",
       "    // this is important to make the div 'focusable\n",
       "    el.attr('tabindex', 0)\n",
       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
       "    // off when our div gets focus\n",
       "\n",
       "    // location in version 3\n",
       "    if (IPython.notebook.keyboard_manager) {\n",
       "        IPython.notebook.keyboard_manager.register_events(el);\n",
       "    }\n",
       "    else {\n",
       "        // location in version 2\n",
       "        IPython.keyboard_manager.register_events(el);\n",
       "    }\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager)\n",
       "        manager = IPython.keyboard_manager;\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which == 13) {\n",
       "        this.canvas_div.blur();\n",
       "        event.shiftKey = false;\n",
       "        // Send a \"J\" for go to next cell\n",
       "        event.which = 74;\n",
       "        event.keyCode = 74;\n",
       "        manager.command_mode();\n",
       "        manager.handle_keydown(event);\n",
       "    }\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.find_output_cell = function(html_output) {\n",
       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
       "    // IPython event is triggered only after the cells have been serialised, which for\n",
       "    // our purposes (turning an active figure into a static one), is too late.\n",
       "    var cells = IPython.notebook.get_cells();\n",
       "    var ncells = cells.length;\n",
       "    for (var i=0; i<ncells; i++) {\n",
       "        var cell = cells[i];\n",
       "        if (cell.cell_type === 'code'){\n",
       "            for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
       "                var data = cell.output_area.outputs[j];\n",
       "                if (data.data) {\n",
       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
       "                    data = data.data;\n",
       "                }\n",
       "                if (data['text/html'] == html_output) {\n",
       "                    return [cell, data, j];\n",
       "                }\n",
       "            }\n",
       "        }\n",
       "    }\n",
       "}\n",
       "\n",
       "// Register the function which deals with the matplotlib target/channel.\n",
       "// The kernel may be null if the page has been refreshed.\n",
       "if (IPython.notebook.kernel != null) {\n",
       "    IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
       "}\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,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jhwJb29vNGzYEHv37pX3v337NkaOHImgoCBUr14dr7/+uuJtn4EDB6JmzZrw8vJC69atFb+7f/9+tG7dGl5eXggICEB0dDSAopv5q6++infffRcAsHPnTvj7++Ojjz5CUFAQ2rdvLx+vffv28PHxQaNGjbB8+XL5900mE4YPHw5fX1/Ur18f8+fPLzEwHDlyBK1atYKnpye6deuGmJgYOfQUPL/NmzejefPm8PT0RPXq1fHee+8BAGrWrAmNRgOtVgutVos1a9bI524TGRmJ999/H+3bt4enpyfat2+Ps2fPyts1Gg1+/fVX+ef84cue41++fBn9+vWDv78/9Ho9xo8fj9zcXMXrOH/+fNSqVQv+/v744IMPiisNCj2sT8DZ8VAEhJSWXshAI2EdbhurI8sYgKbCaucIPXl50jevizrgxu9l/rxdKfQ89dRT+PPPP3Hr1i00bdoUISEhWLduHaxWK+Lj4xEaGirv369fP7z88sv4+++/cfv2bfTq1QujR4+Wt3/++ef4+++/YbFYkJSUhKCgIGRnZwMAIiIikJycjNzcXJhMJnz33XcA7As9jz32GEaNGoWsrCxkZWXh0qVL8PX1xZo1a2C1WnHgwAH4+fnh4MGDAACDwYCnn34af/31F65du4YOHToUG3osFgvq1q2L8ePHIzs7Gzt27IBWqy029NSoUQNLly4FANy9exf79u0r9nkUFXoCAgLw008/wWw246233kJYWJi8vaTQY8/xO3bsiJdffhn37t3D6dOnERISgvnz58v7VqpUCe+88w7MZjMOHTqEKlWq4Oeffy6yNij0kBLxUASElJZeyMB/4xIBUYe0hK5MA0+hQLBjohR6dk8r8+ftSqHns88+k38eN24c2rZtK/987NgxVKpUCVarFVeuXEGlSpVw+/ZteftPP/2EwMDAIo9ttVpRtWpVHD16FADQoUMHjBw5EhcuXFDsZ0/ocXNzw507D74s9sMPP8QLL7ygOM6oUaMwbtw4AEC9evWwbt06eduWLVuKDT27d++Gn58frFar/NjAgQOLDRt16tRBUlISrl27pvo8igo9+UPivXv3ULlyZZw4cQLAo4We8+fPQ6PRKM5rwYIFiIiIkPetVKkSTCaTvL1Vq1ZYvHhxodcEoNBDoUcFD0VASGnphQxsTugMiDoMi/vAuULP1VNS6Pm4dZl/QrMr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\" width=\"573\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7f395c1c42e8>"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fig, ax = subplots()\n",
    "h,b,_ = ax.hist(c2i, 100, label=\"measured distibution\")\n",
    "ax.plot()\n",
    "size = numpy.prod(shape)\n",
    "y_sim = chi2_dist.pdf(b*(size-1), size)\n",
    "y_sim *= h.sum()/y_sim.sum()\n",
    "ax.plot(b, y_sim, label=r\"$\\chi^2$ distribution\")\n",
    "ax.set_title(\"Is the set of images Poissonian?\")\n",
    "ax.legend()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This validates the fact that our set of image is actually a Poissonian distribution around the target image displayed in figure 3.\n",
    "\n",
    "# Integration of images in the SAXS appoximation:\n",
    "\n",
    "We can now integrate all images and check wheather all pairs of curves (with their associated error) fit or not the $\\chi^2$ distribution. \n",
    "\n",
    "It is important to remind that we stay in SAXS approximation, i.e. no solid angle correction or other position-dependent normalization. The pixel splitting is also disabled. So the azimuthal integration is simply:\n",
    "\n",
    "$$\n",
    "I_{bin} = \\frac{1}{count(pix\\in bin)} \\sum_{pix \\in bin} I_{pix}\n",
    "$$\n",
    "\n",
    "The number of bins in the curve being much smaller than the number of pixel in the input image, this calculation is less time-critical. So we simply define the same kind of $\\chi^2$ function using numpy."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "def chi2_curves(res1, res2):\n",
    "    \"\"\"Calculate the Chi2 value for a pair of integrated data\"\"\"\n",
    "    I = res1.intensity\n",
    "    J = res2.intensity\n",
    "    l = len(I)\n",
    "    assert len(J) == l\n",
    "    sigma_I = res1.sigma\n",
    "    sigma_J = res2.sigma\n",
    "    return ((I-J)**2/(sigma_I**2+sigma_J**2)).sum()/(l-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 3.49 s, sys: 141 ms, total: 3.63 s\n",
      "Wall time: 3.61 s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "#Perform the azimuthal integration of every single image\n",
    "\n",
    "integrated = []\n",
    "for i in range(nimg):\n",
    "    data = dataset[i, :, :]\n",
    "    integrated.append(ai.integrate1d(data, variance=data, **kwarg))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10.3 µs ± 24 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n"
     ]
    }
   ],
   "source": [
    "#Check if chi^2 calculation is time-critical:\n",
    "%timeit chi2_curves(integrated[0], integrated[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "c2 = []\n",
    "for i in range(nimg):\n",
    "    res1 = integrated[i]\n",
    "    for j in range(i):\n",
    "        c2.append(chi2_curves(res1, integrated[j]))\n",
    "c2 = numpy.array(c2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "/* Put everything inside the global mpl namespace */\n",
       "window.mpl = {};\n",
       "\n",
       "\n",
       "mpl.get_websocket_type = function() {\n",
       "    if (typeof(WebSocket) !== 'undefined') {\n",
       "        return WebSocket;\n",
       "    } else if (typeof(MozWebSocket) !== 'undefined') {\n",
       "        return MozWebSocket;\n",
       "    } else {\n",
       "        alert('Your browser does not have WebSocket support.' +\n",
       "              'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
       "              'Firefox 4 and 5 are also supported but you ' +\n",
       "              'have to enable WebSockets in about:config.');\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
       "    this.id = figure_id;\n",
       "\n",
       "    this.ws = websocket;\n",
       "\n",
       "    this.supports_binary = (this.ws.binaryType != undefined);\n",
       "\n",
       "    if (!this.supports_binary) {\n",
       "        var warnings = document.getElementById(\"mpl-warnings\");\n",
       "        if (warnings) {\n",
       "            warnings.style.display = 'block';\n",
       "            warnings.textContent = (\n",
       "                \"This browser does not support binary websocket messages. \" +\n",
       "                    \"Performance may be slow.\");\n",
       "        }\n",
       "    }\n",
       "\n",
       "    this.imageObj = new Image();\n",
       "\n",
       "    this.context = undefined;\n",
       "    this.message = undefined;\n",
       "    this.canvas = undefined;\n",
       "    this.rubberband_canvas = undefined;\n",
       "    this.rubberband_context = undefined;\n",
       "    this.format_dropdown = undefined;\n",
       "\n",
       "    this.image_mode = 'full';\n",
       "\n",
       "    this.root = $('<div/>');\n",
       "    this._root_extra_style(this.root)\n",
       "    this.root.attr('style', 'display: inline-block');\n",
       "\n",
       "    $(parent_element).append(this.root);\n",
       "\n",
       "    this._init_header(this);\n",
       "    this._init_canvas(this);\n",
       "    this._init_toolbar(this);\n",
       "\n",
       "    var fig = this;\n",
       "\n",
       "    this.waiting = false;\n",
       "\n",
       "    this.ws.onopen =  function () {\n",
       "            fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
       "            fig.send_message(\"send_image_mode\", {});\n",
       "            if (mpl.ratio != 1) {\n",
       "                fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
       "            }\n",
       "            fig.send_message(\"refresh\", {});\n",
       "        }\n",
       "\n",
       "    this.imageObj.onload = function() {\n",
       "            if (fig.image_mode == 'full') {\n",
       "                // Full images could contain transparency (where diff images\n",
       "                // almost always do), so we need to clear the canvas so that\n",
       "                // there is no ghosting.\n",
       "                fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
       "            }\n",
       "            fig.context.drawImage(fig.imageObj, 0, 0);\n",
       "        };\n",
       "\n",
       "    this.imageObj.onunload = function() {\n",
       "        fig.ws.close();\n",
       "    }\n",
       "\n",
       "    this.ws.onmessage = this._make_on_message_function(this);\n",
       "\n",
       "    this.ondownload = ondownload;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_header = function() {\n",
       "    var titlebar = $(\n",
       "        '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
       "        'ui-helper-clearfix\"/>');\n",
       "    var titletext = $(\n",
       "        '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
       "        'text-align: center; padding: 3px;\"/>');\n",
       "    titlebar.append(titletext)\n",
       "    this.root.append(titlebar);\n",
       "    this.header = titletext[0];\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_canvas = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var canvas_div = $('<div/>');\n",
       "\n",
       "    canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
       "\n",
       "    function canvas_keyboard_event(event) {\n",
       "        return fig.key_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    canvas_div.keydown('key_press', canvas_keyboard_event);\n",
       "    canvas_div.keyup('key_release', canvas_keyboard_event);\n",
       "    this.canvas_div = canvas_div\n",
       "    this._canvas_extra_style(canvas_div)\n",
       "    this.root.append(canvas_div);\n",
       "\n",
       "    var canvas = $('<canvas/>');\n",
       "    canvas.addClass('mpl-canvas');\n",
       "    canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
       "\n",
       "    this.canvas = canvas[0];\n",
       "    this.context = canvas[0].getContext(\"2d\");\n",
       "\n",
       "    var backingStore = this.context.backingStorePixelRatio ||\n",
       "\tthis.context.webkitBackingStorePixelRatio ||\n",
       "\tthis.context.mozBackingStorePixelRatio ||\n",
       "\tthis.context.msBackingStorePixelRatio ||\n",
       "\tthis.context.oBackingStorePixelRatio ||\n",
       "\tthis.context.backingStorePixelRatio || 1;\n",
       "\n",
       "    mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
       "\n",
       "    var rubberband = $('<canvas/>');\n",
       "    rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
       "\n",
       "    var pass_mouse_events = true;\n",
       "\n",
       "    canvas_div.resizable({\n",
       "        start: function(event, ui) {\n",
       "            pass_mouse_events = false;\n",
       "        },\n",
       "        resize: function(event, ui) {\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "        stop: function(event, ui) {\n",
       "            pass_mouse_events = true;\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "    });\n",
       "\n",
       "    function mouse_event_fn(event) {\n",
       "        if (pass_mouse_events)\n",
       "            return fig.mouse_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    rubberband.mousedown('button_press', mouse_event_fn);\n",
       "    rubberband.mouseup('button_release', mouse_event_fn);\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband.mousemove('motion_notify', mouse_event_fn);\n",
       "\n",
       "    rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
       "    rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
       "\n",
       "    canvas_div.on(\"wheel\", function (event) {\n",
       "        event = event.originalEvent;\n",
       "        event['data'] = 'scroll'\n",
       "        if (event.deltaY < 0) {\n",
       "            event.step = 1;\n",
       "        } else {\n",
       "            event.step = -1;\n",
       "        }\n",
       "        mouse_event_fn(event);\n",
       "    });\n",
       "\n",
       "    canvas_div.append(canvas);\n",
       "    canvas_div.append(rubberband);\n",
       "\n",
       "    this.rubberband = rubberband;\n",
       "    this.rubberband_canvas = rubberband[0];\n",
       "    this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
       "    this.rubberband_context.strokeStyle = \"#000000\";\n",
       "\n",
       "    this._resize_canvas = function(width, height) {\n",
       "        // Keep the size of the canvas, canvas container, and rubber band\n",
       "        // canvas in synch.\n",
       "        canvas_div.css('width', width)\n",
       "        canvas_div.css('height', height)\n",
       "\n",
       "        canvas.attr('width', width * mpl.ratio);\n",
       "        canvas.attr('height', height * mpl.ratio);\n",
       "        canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
       "\n",
       "        rubberband.attr('width', width);\n",
       "        rubberband.attr('height', height);\n",
       "    }\n",
       "\n",
       "    // Set the figure to an initial 600x600px, this will subsequently be updated\n",
       "    // upon first draw.\n",
       "    this._resize_canvas(600, 600);\n",
       "\n",
       "    // Disable right mouse context menu.\n",
       "    $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
       "        return false;\n",
       "    });\n",
       "\n",
       "    function set_focus () {\n",
       "        canvas.focus();\n",
       "        canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    window.setTimeout(set_focus, 100);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items) {\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) {\n",
       "            // put a spacer in here.\n",
       "            continue;\n",
       "        }\n",
       "        var button = $('<button/>');\n",
       "        button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
       "                        'ui-button-icon-only');\n",
       "        button.attr('role', 'button');\n",
       "        button.attr('aria-disabled', 'false');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "\n",
       "        var icon_img = $('<span/>');\n",
       "        icon_img.addClass('ui-button-icon-primary ui-icon');\n",
       "        icon_img.addClass(image);\n",
       "        icon_img.addClass('ui-corner-all');\n",
       "\n",
       "        var tooltip_span = $('<span/>');\n",
       "        tooltip_span.addClass('ui-button-text');\n",
       "        tooltip_span.html(tooltip);\n",
       "\n",
       "        button.append(icon_img);\n",
       "        button.append(tooltip_span);\n",
       "\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    var fmt_picker_span = $('<span/>');\n",
       "\n",
       "    var fmt_picker = $('<select/>');\n",
       "    fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
       "    fmt_picker_span.append(fmt_picker);\n",
       "    nav_element.append(fmt_picker_span);\n",
       "    this.format_dropdown = fmt_picker[0];\n",
       "\n",
       "    for (var ind in mpl.extensions) {\n",
       "        var fmt = mpl.extensions[ind];\n",
       "        var option = $(\n",
       "            '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
       "        fmt_picker.append(option)\n",
       "    }\n",
       "\n",
       "    // Add hover states to the ui-buttons\n",
       "    $( \".ui-button\" ).hover(\n",
       "        function() { $(this).addClass(\"ui-state-hover\");},\n",
       "        function() { $(this).removeClass(\"ui-state-hover\");}\n",
       "    );\n",
       "\n",
       "    var status_bar = $('<span class=\"mpl-message\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
       "    // which will in turn request a refresh of the image.\n",
       "    this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_message = function(type, properties) {\n",
       "    properties['type'] = type;\n",
       "    properties['figure_id'] = this.id;\n",
       "    this.ws.send(JSON.stringify(properties));\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_draw_message = function() {\n",
       "    if (!this.waiting) {\n",
       "        this.waiting = true;\n",
       "        this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
       "    }\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    var format_dropdown = fig.format_dropdown;\n",
       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
       "    fig.ondownload(fig, format);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
       "    var size = msg['size'];\n",
       "    if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
       "        fig._resize_canvas(size[0], size[1]);\n",
       "        fig.send_message(\"refresh\", {});\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
       "    var x0 = msg['x0'] / mpl.ratio;\n",
       "    var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
       "    var x1 = msg['x1'] / mpl.ratio;\n",
       "    var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
       "    x0 = Math.floor(x0) + 0.5;\n",
       "    y0 = Math.floor(y0) + 0.5;\n",
       "    x1 = Math.floor(x1) + 0.5;\n",
       "    y1 = Math.floor(y1) + 0.5;\n",
       "    var min_x = Math.min(x0, x1);\n",
       "    var min_y = Math.min(y0, y1);\n",
       "    var width = Math.abs(x1 - x0);\n",
       "    var height = Math.abs(y1 - y0);\n",
       "\n",
       "    fig.rubberband_context.clearRect(\n",
       "        0, 0, fig.canvas.width, fig.canvas.height);\n",
       "\n",
       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
       "    // Updates the figure title.\n",
       "    fig.header.textContent = msg['label'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
       "    var cursor = msg['cursor'];\n",
       "    switch(cursor)\n",
       "    {\n",
       "    case 0:\n",
       "        cursor = 'pointer';\n",
       "        break;\n",
       "    case 1:\n",
       "        cursor = 'default';\n",
       "        break;\n",
       "    case 2:\n",
       "        cursor = 'crosshair';\n",
       "        break;\n",
       "    case 3:\n",
       "        cursor = 'move';\n",
       "        break;\n",
       "    }\n",
       "    fig.rubberband_canvas.style.cursor = cursor;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
       "    fig.message.textContent = msg['message'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
       "    // Request the server to send over a new figure.\n",
       "    fig.send_draw_message();\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
       "    fig.image_mode = msg['mode'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Called whenever the canvas gets updated.\n",
       "    this.send_message(\"ack\", {});\n",
       "}\n",
       "\n",
       "// A function to construct a web socket function for onmessage handling.\n",
       "// Called in the figure constructor.\n",
       "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
       "    return function socket_on_message(evt) {\n",
       "        if (evt.data instanceof Blob) {\n",
       "            /* FIXME: We get \"Resource interpreted as Image but\n",
       "             * transferred with MIME type text/plain:\" errors on\n",
       "             * Chrome.  But how to set the MIME type?  It doesn't seem\n",
       "             * to be part of the websocket stream */\n",
       "            evt.data.type = \"image/png\";\n",
       "\n",
       "            /* Free the memory for the previous frames */\n",
       "            if (fig.imageObj.src) {\n",
       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
       "                    fig.imageObj.src);\n",
       "            }\n",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data);\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "        else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
       "            fig.imageObj.src = evt.data;\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        var msg = JSON.parse(evt.data);\n",
       "        var msg_type = msg['type'];\n",
       "\n",
       "        // Call the  \"handle_{type}\" callback, which takes\n",
       "        // the figure and JSON message as its only arguments.\n",
       "        try {\n",
       "            var callback = fig[\"handle_\" + msg_type];\n",
       "        } catch (e) {\n",
       "            console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        if (callback) {\n",
       "            try {\n",
       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
       "                callback(fig, msg);\n",
       "            } catch (e) {\n",
       "                console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
       "            }\n",
       "        }\n",
       "    };\n",
       "}\n",
       "\n",
       "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
       "mpl.findpos = function(e) {\n",
       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
       "    var targ;\n",
       "    if (!e)\n",
       "        e = window.event;\n",
       "    if (e.target)\n",
       "        targ = e.target;\n",
       "    else if (e.srcElement)\n",
       "        targ = e.srcElement;\n",
       "    if (targ.nodeType == 3) // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "\n",
       "    // jQuery normalizes the pageX and pageY\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    // offset() returns the position of the element relative to the document\n",
       "    var x = e.pageX - $(targ).offset().left;\n",
       "    var y = e.pageY - $(targ).offset().top;\n",
       "\n",
       "    return {\"x\": x, \"y\": y};\n",
       "};\n",
       "\n",
       "/*\n",
       " * return a copy of an object with only non-object keys\n",
       " * we need this to avoid circular references\n",
       " * http://stackoverflow.com/a/24161582/3208463\n",
       " */\n",
       "function simpleKeys (original) {\n",
       "  return Object.keys(original).reduce(function (obj, key) {\n",
       "    if (typeof original[key] !== 'object')\n",
       "        obj[key] = original[key]\n",
       "    return obj;\n",
       "  }, {});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.mouse_event = function(event, name) {\n",
       "    var canvas_pos = mpl.findpos(event)\n",
       "\n",
       "    if (name === 'button_press')\n",
       "    {\n",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * mpl.ratio;\n",
       "    var y = canvas_pos.y * mpl.ratio;\n",
       "\n",
       "    this.send_message(name, {x: x, y: y, button: event.button,\n",
       "                             step: event.step,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "\n",
       "    /* This prevents the web browser from automatically changing to\n",
       "     * the text insertion cursor when the button is pressed.  We want\n",
       "     * to control all of the cursor setting manually through the\n",
       "     * 'cursor' event from matplotlib */\n",
       "    event.preventDefault();\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    // Handle any extra behaviour associated with a key event\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.key_event = function(event, name) {\n",
       "\n",
       "    // Prevent repeat events\n",
       "    if (name == 'key_press')\n",
       "    {\n",
       "        if (event.which === this._key)\n",
       "            return;\n",
       "        else\n",
       "            this._key = event.which;\n",
       "    }\n",
       "    if (name == 'key_release')\n",
       "        this._key = null;\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which != 17)\n",
       "        value += \"ctrl+\";\n",
       "    if (event.altKey && event.which != 18)\n",
       "        value += \"alt+\";\n",
       "    if (event.shiftKey && event.which != 16)\n",
       "        value += \"shift+\";\n",
       "\n",
       "    value += 'k';\n",
       "    value += event.which.toString();\n",
       "\n",
       "    this._key_event_extra(event, name);\n",
       "\n",
       "    this.send_message(name, {key: value,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
       "    if (name == 'download') {\n",
       "        this.handle_save(this, null);\n",
       "    } else {\n",
       "        this.send_message(\"toolbar_button\", {name: name});\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
       "    this.message.textContent = tooltip;\n",
       "};\n",
       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
       "\n",
       "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
       "\n",
       "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
       "    // object with the appropriate methods. Currently this is a non binary\n",
       "    // socket, so there is still some room for performance tuning.\n",
       "    var ws = {};\n",
       "\n",
       "    ws.close = function() {\n",
       "        comm.close()\n",
       "    };\n",
       "    ws.send = function(m) {\n",
       "        //console.log('sending', m);\n",
       "        comm.send(m);\n",
       "    };\n",
       "    // Register the callback with on_msg.\n",
       "    comm.on_msg(function(msg) {\n",
       "        //console.log('receiving', msg['content']['data'], msg);\n",
       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
       "        ws.onmessage(msg['content']['data'])\n",
       "    });\n",
       "    return ws;\n",
       "}\n",
       "\n",
       "mpl.mpl_figure_comm = function(comm, msg) {\n",
       "    // This is the function which gets called when the mpl process\n",
       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
       "\n",
       "    var id = msg.content.data.id;\n",
       "    // Get hold of the div created by the display call when the Comm\n",
       "    // socket was opened in Python.\n",
       "    var element = $(\"#\" + id);\n",
       "    var ws_proxy = comm_websocket_adapter(comm)\n",
       "\n",
       "    function ondownload(figure, format) {\n",
       "        window.open(figure.imageObj.src);\n",
       "    }\n",
       "\n",
       "    var fig = new mpl.figure(id, ws_proxy,\n",
       "                           ondownload,\n",
       "                           element.get(0));\n",
       "\n",
       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
       "    // web socket which is closed, not our websocket->open comm proxy.\n",
       "    ws_proxy.onopen();\n",
       "\n",
       "    fig.parent_element = element.get(0);\n",
       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
       "    if (!fig.cell_info) {\n",
       "        console.error(\"Failed to find cell for figure\", id, fig);\n",
       "        return;\n",
       "    }\n",
       "\n",
       "    var output_index = fig.cell_info[2]\n",
       "    var cell = fig.cell_info[0];\n",
       "\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
       "    var width = fig.canvas.width/mpl.ratio\n",
       "    fig.root.unbind('remove')\n",
       "\n",
       "    // Update the output cell to use the data from the current canvas.\n",
       "    fig.push_to_output();\n",
       "    var dataURL = fig.canvas.toDataURL();\n",
       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
       "    // the notebook keyboard shortcuts fail.\n",
       "    IPython.keyboard_manager.enable()\n",
       "    $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
       "    fig.close_ws(fig, msg);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.close_ws = function(fig, msg){\n",
       "    fig.send_message('closing', msg);\n",
       "    // fig.ws.close()\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
       "    // Turn the data on the canvas into data in the output cell.\n",
       "    var width = this.canvas.width/mpl.ratio\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Tell IPython that the notebook contents must change.\n",
       "    IPython.notebook.set_dirty(true);\n",
       "    this.send_message(\"ack\", {});\n",
       "    var fig = this;\n",
       "    // Wait a second, then push the new image to the DOM so\n",
       "    // that it is saved nicely (might be nice to debounce this).\n",
       "    setTimeout(function () { fig.push_to_output() }, 1000);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items){\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) { continue; };\n",
       "\n",
       "        var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    // Add the status bar.\n",
       "    var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "\n",
       "    // Add the close button to the window.\n",
       "    var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
       "    var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
       "    button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
       "    button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
       "    buttongrp.append(button);\n",
       "    var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
       "    titlebar.prepend(buttongrp);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(el){\n",
       "    var fig = this\n",
       "    el.on(\"remove\", function(){\n",
       "\tfig.close_ws(fig, {});\n",
       "    });\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(el){\n",
       "    // this is important to make the div 'focusable\n",
       "    el.attr('tabindex', 0)\n",
       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
       "    // off when our div gets focus\n",
       "\n",
       "    // location in version 3\n",
       "    if (IPython.notebook.keyboard_manager) {\n",
       "        IPython.notebook.keyboard_manager.register_events(el);\n",
       "    }\n",
       "    else {\n",
       "        // location in version 2\n",
       "        IPython.keyboard_manager.register_events(el);\n",
       "    }\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager)\n",
       "        manager = IPython.keyboard_manager;\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which == 13) {\n",
       "        this.canvas_div.blur();\n",
       "        event.shiftKey = false;\n",
       "        // Send a \"J\" for go to next cell\n",
       "        event.which = 74;\n",
       "        event.keyCode = 74;\n",
       "        manager.command_mode();\n",
       "        manager.handle_keydown(event);\n",
       "    }\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.find_output_cell = function(html_output) {\n",
       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
       "    // IPython event is triggered only after the cells have been serialised, which for\n",
       "    // our purposes (turning an active figure into a static one), is too late.\n",
       "    var cells = IPython.notebook.get_cells();\n",
       "    var ncells = cells.length;\n",
       "    for (var i=0; i<ncells; i++) {\n",
       "        var cell = cells[i];\n",
       "        if (cell.cell_type === 'code'){\n",
       "            for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
       "                var data = cell.output_area.outputs[j];\n",
       "                if (data.data) {\n",
       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
       "                    data = data.data;\n",
       "                }\n",
       "                if (data['text/html'] == html_output) {\n",
       "                    return [cell, data, j];\n",
       "                }\n",
       "            }\n",
       "        }\n",
       "    }\n",
       "}\n",
       "\n",
       "// Register the function which deals with the matplotlib target/channel.\n",
       "// The kernel may be null if the page has been refreshed.\n",
       "if (IPython.notebook.kernel != null) {\n",
       "    IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
       "}\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,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TZoEu92OdevWISYmBvXq1Qv0YYcFvVIoKChAbGys29fy8/ORkJDg70MLS1x6Asub822z2dChQwf06dPHz0dF/sSlpxy8uYjpmTNnYDAYXCV86tQpJCcnY9CgQYE+7JDl7UVjv/nmGyQlJSEuLg73338/Xn31Vdx3332BPOSw4ekzPZf+HubNm8dnesqJS09geXq+S0pK8Pjjj6NLly4oKSkJwJGRv3DpKSdPL2K6efNmREZGun0tLy8PiYmJ/j7EsHI9F43t0aMH3njjDX8dWljz9DU9O3fudH3NZDLxNT3lxKUnsDw53yUlJejatSs6deoEm80WoCMjf+HSU06eXsT03LlzqFKlCnJycuBwOHDmzBl069YNXbt2VXDUocubi8Zu27YNNpsNRUVFyMnJQY0aNXD06NEAH3Fou3DhAoqLi2EymdCtWzcUFxdf9f9wn3vuOSQnJ+PcuXPYtWsXEhIS+O4tL3lzvu12O4qLi/Hss89i8ODBKC4u5kdgeMnT822325GcnIyHH374ii9doNDDpaecrnUR08ceewwjRoxwfe+aNWvQunVrxMbGonr16ujevTtL2EvenO++ffvCYDAgKioKjz76KHbv3q3qsEOW1WpFRESEWx588EEAl5/vwsJC9OjRA9HR0UhISODn9JSDN+e7b9++l30v353oHU/P9+rVqxEREYHIyEhERUW5cunvg0ILlx4iIiISgUsPERERicClh4iIiETg0kNEREQicOkhIiIiEbj0EBERkQhceoiIiEgELj1EREQkApceIiIiEoFLDxEREYnApYeIiIhE4NJDREREInDpISIiIhG49BAREZEIXHqIiIhIBC49REREJAKXHiIiIhKBSw8RERGJwKWHiIiIRODSQ0RERCJw6SEiIiIRuPQQERGRCFx6iIiISAQuPURERCQClx4iIiISgUsPERERicClh4iIiETg0kNEREQicOkhIiIiEf4/FBFjgF8YtEUAAAAASUVORK5CYII=\" width=\"573\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7f395c01e080>"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fig, ax = subplots()\n",
    "h,b,_ = ax.hist(c2, 100, label=\"Measured distibution\")\n",
    "y_sim = chi2_dist.pdf(b*(nimg-1), nimg)\n",
    "y_sim *= h.sum()/y_sim.sum()\n",
    "ax.plot(b, y_sim, label=r\"Chi^2 distribution\")\n",
    "ax.set_title(\"Integrated curves in SAXS approximation\")\n",
    "ax.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.889452976157626 1.1200681344576493\n",
      "Expected outliers:  2497.5 got 2522 below and  2653 above\n"
     ]
    }
   ],
   "source": [
    "low_lim, up_lim = chi2_dist.ppf([0.005, 0.995], nimg) / (nimg - 1)\n",
    "print(low_lim, up_lim)\n",
    "print(\"Expected outliers: \", nimg*(nimg-1)*0.005/2, \"got\", \n",
    "(c2<low_lim).sum(),\"below and \",(c2>up_lim).sum(), \"above\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Integration of images with solid angle correction/polarization correction\n",
    "\n",
    "PyFAI applies by default solid-angle correction which is needed for powder diffraction. \n",
    "On synchrotron sources, the beam is highly polarized and one would like to correct for this effect as well. How does it influence the error propagation ? \n",
    "\n",
    "If we enable the solid angle normalisation (noted $\\Omega$) and the polarisation correction (noted $P$), this leads us to:\n",
    "\n",
    "$$\n",
    "I_{bin} = \\frac{1}{count(pix\\in bin)} \\sum_{pix \\in bin} \\frac{I_{pix}}{\\Omega_{pix} P_{pix}}\n",
    "$$\n",
    "\n",
    "Flatfield correction and any other normalization like pixel efficiency related to sensor thickness should be accounted in the same way.\n",
    "\n",
    "**Nota:** The pixel splitting remains disabled. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:pyFAI.ext.splitBBoxCSR:Pixel splitting desactivated !\n"
     ]
    },
    {
     "data": {
      "application/javascript": [
       "/* Put everything inside the global mpl namespace */\n",
       "window.mpl = {};\n",
       "\n",
       "\n",
       "mpl.get_websocket_type = function() {\n",
       "    if (typeof(WebSocket) !== 'undefined') {\n",
       "        return WebSocket;\n",
       "    } else if (typeof(MozWebSocket) !== 'undefined') {\n",
       "        return MozWebSocket;\n",
       "    } else {\n",
       "        alert('Your browser does not have WebSocket support.' +\n",
       "              'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
       "              'Firefox 4 and 5 are also supported but you ' +\n",
       "              'have to enable WebSockets in about:config.');\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
       "    this.id = figure_id;\n",
       "\n",
       "    this.ws = websocket;\n",
       "\n",
       "    this.supports_binary = (this.ws.binaryType != undefined);\n",
       "\n",
       "    if (!this.supports_binary) {\n",
       "        var warnings = document.getElementById(\"mpl-warnings\");\n",
       "        if (warnings) {\n",
       "            warnings.style.display = 'block';\n",
       "            warnings.textContent = (\n",
       "                \"This browser does not support binary websocket messages. \" +\n",
       "                    \"Performance may be slow.\");\n",
       "        }\n",
       "    }\n",
       "\n",
       "    this.imageObj = new Image();\n",
       "\n",
       "    this.context = undefined;\n",
       "    this.message = undefined;\n",
       "    this.canvas = undefined;\n",
       "    this.rubberband_canvas = undefined;\n",
       "    this.rubberband_context = undefined;\n",
       "    this.format_dropdown = undefined;\n",
       "\n",
       "    this.image_mode = 'full';\n",
       "\n",
       "    this.root = $('<div/>');\n",
       "    this._root_extra_style(this.root)\n",
       "    this.root.attr('style', 'display: inline-block');\n",
       "\n",
       "    $(parent_element).append(this.root);\n",
       "\n",
       "    this._init_header(this);\n",
       "    this._init_canvas(this);\n",
       "    this._init_toolbar(this);\n",
       "\n",
       "    var fig = this;\n",
       "\n",
       "    this.waiting = false;\n",
       "\n",
       "    this.ws.onopen =  function () {\n",
       "            fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
       "            fig.send_message(\"send_image_mode\", {});\n",
       "            if (mpl.ratio != 1) {\n",
       "                fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
       "            }\n",
       "            fig.send_message(\"refresh\", {});\n",
       "        }\n",
       "\n",
       "    this.imageObj.onload = function() {\n",
       "            if (fig.image_mode == 'full') {\n",
       "                // Full images could contain transparency (where diff images\n",
       "                // almost always do), so we need to clear the canvas so that\n",
       "                // there is no ghosting.\n",
       "                fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
       "            }\n",
       "            fig.context.drawImage(fig.imageObj, 0, 0);\n",
       "        };\n",
       "\n",
       "    this.imageObj.onunload = function() {\n",
       "        fig.ws.close();\n",
       "    }\n",
       "\n",
       "    this.ws.onmessage = this._make_on_message_function(this);\n",
       "\n",
       "    this.ondownload = ondownload;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_header = function() {\n",
       "    var titlebar = $(\n",
       "        '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
       "        'ui-helper-clearfix\"/>');\n",
       "    var titletext = $(\n",
       "        '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
       "        'text-align: center; padding: 3px;\"/>');\n",
       "    titlebar.append(titletext)\n",
       "    this.root.append(titlebar);\n",
       "    this.header = titletext[0];\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_canvas = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var canvas_div = $('<div/>');\n",
       "\n",
       "    canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
       "\n",
       "    function canvas_keyboard_event(event) {\n",
       "        return fig.key_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    canvas_div.keydown('key_press', canvas_keyboard_event);\n",
       "    canvas_div.keyup('key_release', canvas_keyboard_event);\n",
       "    this.canvas_div = canvas_div\n",
       "    this._canvas_extra_style(canvas_div)\n",
       "    this.root.append(canvas_div);\n",
       "\n",
       "    var canvas = $('<canvas/>');\n",
       "    canvas.addClass('mpl-canvas');\n",
       "    canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
       "\n",
       "    this.canvas = canvas[0];\n",
       "    this.context = canvas[0].getContext(\"2d\");\n",
       "\n",
       "    var backingStore = this.context.backingStorePixelRatio ||\n",
       "\tthis.context.webkitBackingStorePixelRatio ||\n",
       "\tthis.context.mozBackingStorePixelRatio ||\n",
       "\tthis.context.msBackingStorePixelRatio ||\n",
       "\tthis.context.oBackingStorePixelRatio ||\n",
       "\tthis.context.backingStorePixelRatio || 1;\n",
       "\n",
       "    mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
       "\n",
       "    var rubberband = $('<canvas/>');\n",
       "    rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
       "\n",
       "    var pass_mouse_events = true;\n",
       "\n",
       "    canvas_div.resizable({\n",
       "        start: function(event, ui) {\n",
       "            pass_mouse_events = false;\n",
       "        },\n",
       "        resize: function(event, ui) {\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "        stop: function(event, ui) {\n",
       "            pass_mouse_events = true;\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "    });\n",
       "\n",
       "    function mouse_event_fn(event) {\n",
       "        if (pass_mouse_events)\n",
       "            return fig.mouse_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    rubberband.mousedown('button_press', mouse_event_fn);\n",
       "    rubberband.mouseup('button_release', mouse_event_fn);\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband.mousemove('motion_notify', mouse_event_fn);\n",
       "\n",
       "    rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
       "    rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
       "\n",
       "    canvas_div.on(\"wheel\", function (event) {\n",
       "        event = event.originalEvent;\n",
       "        event['data'] = 'scroll'\n",
       "        if (event.deltaY < 0) {\n",
       "            event.step = 1;\n",
       "        } else {\n",
       "            event.step = -1;\n",
       "        }\n",
       "        mouse_event_fn(event);\n",
       "    });\n",
       "\n",
       "    canvas_div.append(canvas);\n",
       "    canvas_div.append(rubberband);\n",
       "\n",
       "    this.rubberband = rubberband;\n",
       "    this.rubberband_canvas = rubberband[0];\n",
       "    this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
       "    this.rubberband_context.strokeStyle = \"#000000\";\n",
       "\n",
       "    this._resize_canvas = function(width, height) {\n",
       "        // Keep the size of the canvas, canvas container, and rubber band\n",
       "        // canvas in synch.\n",
       "        canvas_div.css('width', width)\n",
       "        canvas_div.css('height', height)\n",
       "\n",
       "        canvas.attr('width', width * mpl.ratio);\n",
       "        canvas.attr('height', height * mpl.ratio);\n",
       "        canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
       "\n",
       "        rubberband.attr('width', width);\n",
       "        rubberband.attr('height', height);\n",
       "    }\n",
       "\n",
       "    // Set the figure to an initial 600x600px, this will subsequently be updated\n",
       "    // upon first draw.\n",
       "    this._resize_canvas(600, 600);\n",
       "\n",
       "    // Disable right mouse context menu.\n",
       "    $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
       "        return false;\n",
       "    });\n",
       "\n",
       "    function set_focus () {\n",
       "        canvas.focus();\n",
       "        canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    window.setTimeout(set_focus, 100);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items) {\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) {\n",
       "            // put a spacer in here.\n",
       "            continue;\n",
       "        }\n",
       "        var button = $('<button/>');\n",
       "        button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
       "                        'ui-button-icon-only');\n",
       "        button.attr('role', 'button');\n",
       "        button.attr('aria-disabled', 'false');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "\n",
       "        var icon_img = $('<span/>');\n",
       "        icon_img.addClass('ui-button-icon-primary ui-icon');\n",
       "        icon_img.addClass(image);\n",
       "        icon_img.addClass('ui-corner-all');\n",
       "\n",
       "        var tooltip_span = $('<span/>');\n",
       "        tooltip_span.addClass('ui-button-text');\n",
       "        tooltip_span.html(tooltip);\n",
       "\n",
       "        button.append(icon_img);\n",
       "        button.append(tooltip_span);\n",
       "\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    var fmt_picker_span = $('<span/>');\n",
       "\n",
       "    var fmt_picker = $('<select/>');\n",
       "    fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
       "    fmt_picker_span.append(fmt_picker);\n",
       "    nav_element.append(fmt_picker_span);\n",
       "    this.format_dropdown = fmt_picker[0];\n",
       "\n",
       "    for (var ind in mpl.extensions) {\n",
       "        var fmt = mpl.extensions[ind];\n",
       "        var option = $(\n",
       "            '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
       "        fmt_picker.append(option)\n",
       "    }\n",
       "\n",
       "    // Add hover states to the ui-buttons\n",
       "    $( \".ui-button\" ).hover(\n",
       "        function() { $(this).addClass(\"ui-state-hover\");},\n",
       "        function() { $(this).removeClass(\"ui-state-hover\");}\n",
       "    );\n",
       "\n",
       "    var status_bar = $('<span class=\"mpl-message\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
       "    // which will in turn request a refresh of the image.\n",
       "    this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_message = function(type, properties) {\n",
       "    properties['type'] = type;\n",
       "    properties['figure_id'] = this.id;\n",
       "    this.ws.send(JSON.stringify(properties));\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_draw_message = function() {\n",
       "    if (!this.waiting) {\n",
       "        this.waiting = true;\n",
       "        this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
       "    }\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    var format_dropdown = fig.format_dropdown;\n",
       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
       "    fig.ondownload(fig, format);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
       "    var size = msg['size'];\n",
       "    if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
       "        fig._resize_canvas(size[0], size[1]);\n",
       "        fig.send_message(\"refresh\", {});\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
       "    var x0 = msg['x0'] / mpl.ratio;\n",
       "    var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
       "    var x1 = msg['x1'] / mpl.ratio;\n",
       "    var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
       "    x0 = Math.floor(x0) + 0.5;\n",
       "    y0 = Math.floor(y0) + 0.5;\n",
       "    x1 = Math.floor(x1) + 0.5;\n",
       "    y1 = Math.floor(y1) + 0.5;\n",
       "    var min_x = Math.min(x0, x1);\n",
       "    var min_y = Math.min(y0, y1);\n",
       "    var width = Math.abs(x1 - x0);\n",
       "    var height = Math.abs(y1 - y0);\n",
       "\n",
       "    fig.rubberband_context.clearRect(\n",
       "        0, 0, fig.canvas.width, fig.canvas.height);\n",
       "\n",
       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
       "    // Updates the figure title.\n",
       "    fig.header.textContent = msg['label'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
       "    var cursor = msg['cursor'];\n",
       "    switch(cursor)\n",
       "    {\n",
       "    case 0:\n",
       "        cursor = 'pointer';\n",
       "        break;\n",
       "    case 1:\n",
       "        cursor = 'default';\n",
       "        break;\n",
       "    case 2:\n",
       "        cursor = 'crosshair';\n",
       "        break;\n",
       "    case 3:\n",
       "        cursor = 'move';\n",
       "        break;\n",
       "    }\n",
       "    fig.rubberband_canvas.style.cursor = cursor;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
       "    fig.message.textContent = msg['message'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
       "    // Request the server to send over a new figure.\n",
       "    fig.send_draw_message();\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
       "    fig.image_mode = msg['mode'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Called whenever the canvas gets updated.\n",
       "    this.send_message(\"ack\", {});\n",
       "}\n",
       "\n",
       "// A function to construct a web socket function for onmessage handling.\n",
       "// Called in the figure constructor.\n",
       "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
       "    return function socket_on_message(evt) {\n",
       "        if (evt.data instanceof Blob) {\n",
       "            /* FIXME: We get \"Resource interpreted as Image but\n",
       "             * transferred with MIME type text/plain:\" errors on\n",
       "             * Chrome.  But how to set the MIME type?  It doesn't seem\n",
       "             * to be part of the websocket stream */\n",
       "            evt.data.type = \"image/png\";\n",
       "\n",
       "            /* Free the memory for the previous frames */\n",
       "            if (fig.imageObj.src) {\n",
       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
       "                    fig.imageObj.src);\n",
       "            }\n",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data);\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "        else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
       "            fig.imageObj.src = evt.data;\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        var msg = JSON.parse(evt.data);\n",
       "        var msg_type = msg['type'];\n",
       "\n",
       "        // Call the  \"handle_{type}\" callback, which takes\n",
       "        // the figure and JSON message as its only arguments.\n",
       "        try {\n",
       "            var callback = fig[\"handle_\" + msg_type];\n",
       "        } catch (e) {\n",
       "            console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        if (callback) {\n",
       "            try {\n",
       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
       "                callback(fig, msg);\n",
       "            } catch (e) {\n",
       "                console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
       "            }\n",
       "        }\n",
       "    };\n",
       "}\n",
       "\n",
       "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
       "mpl.findpos = function(e) {\n",
       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
       "    var targ;\n",
       "    if (!e)\n",
       "        e = window.event;\n",
       "    if (e.target)\n",
       "        targ = e.target;\n",
       "    else if (e.srcElement)\n",
       "        targ = e.srcElement;\n",
       "    if (targ.nodeType == 3) // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "\n",
       "    // jQuery normalizes the pageX and pageY\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    // offset() returns the position of the element relative to the document\n",
       "    var x = e.pageX - $(targ).offset().left;\n",
       "    var y = e.pageY - $(targ).offset().top;\n",
       "\n",
       "    return {\"x\": x, \"y\": y};\n",
       "};\n",
       "\n",
       "/*\n",
       " * return a copy of an object with only non-object keys\n",
       " * we need this to avoid circular references\n",
       " * http://stackoverflow.com/a/24161582/3208463\n",
       " */\n",
       "function simpleKeys (original) {\n",
       "  return Object.keys(original).reduce(function (obj, key) {\n",
       "    if (typeof original[key] !== 'object')\n",
       "        obj[key] = original[key]\n",
       "    return obj;\n",
       "  }, {});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.mouse_event = function(event, name) {\n",
       "    var canvas_pos = mpl.findpos(event)\n",
       "\n",
       "    if (name === 'button_press')\n",
       "    {\n",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * mpl.ratio;\n",
       "    var y = canvas_pos.y * mpl.ratio;\n",
       "\n",
       "    this.send_message(name, {x: x, y: y, button: event.button,\n",
       "                             step: event.step,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "\n",
       "    /* This prevents the web browser from automatically changing to\n",
       "     * the text insertion cursor when the button is pressed.  We want\n",
       "     * to control all of the cursor setting manually through the\n",
       "     * 'cursor' event from matplotlib */\n",
       "    event.preventDefault();\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    // Handle any extra behaviour associated with a key event\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.key_event = function(event, name) {\n",
       "\n",
       "    // Prevent repeat events\n",
       "    if (name == 'key_press')\n",
       "    {\n",
       "        if (event.which === this._key)\n",
       "            return;\n",
       "        else\n",
       "            this._key = event.which;\n",
       "    }\n",
       "    if (name == 'key_release')\n",
       "        this._key = null;\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which != 17)\n",
       "        value += \"ctrl+\";\n",
       "    if (event.altKey && event.which != 18)\n",
       "        value += \"alt+\";\n",
       "    if (event.shiftKey && event.which != 16)\n",
       "        value += \"shift+\";\n",
       "\n",
       "    value += 'k';\n",
       "    value += event.which.toString();\n",
       "\n",
       "    this._key_event_extra(event, name);\n",
       "\n",
       "    this.send_message(name, {key: value,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
       "    if (name == 'download') {\n",
       "        this.handle_save(this, null);\n",
       "    } else {\n",
       "        this.send_message(\"toolbar_button\", {name: name});\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
       "    this.message.textContent = tooltip;\n",
       "};\n",
       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
       "\n",
       "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
       "\n",
       "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
       "    // object with the appropriate methods. Currently this is a non binary\n",
       "    // socket, so there is still some room for performance tuning.\n",
       "    var ws = {};\n",
       "\n",
       "    ws.close = function() {\n",
       "        comm.close()\n",
       "    };\n",
       "    ws.send = function(m) {\n",
       "        //console.log('sending', m);\n",
       "        comm.send(m);\n",
       "    };\n",
       "    // Register the callback with on_msg.\n",
       "    comm.on_msg(function(msg) {\n",
       "        //console.log('receiving', msg['content']['data'], msg);\n",
       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
       "        ws.onmessage(msg['content']['data'])\n",
       "    });\n",
       "    return ws;\n",
       "}\n",
       "\n",
       "mpl.mpl_figure_comm = function(comm, msg) {\n",
       "    // This is the function which gets called when the mpl process\n",
       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
       "\n",
       "    var id = msg.content.data.id;\n",
       "    // Get hold of the div created by the display call when the Comm\n",
       "    // socket was opened in Python.\n",
       "    var element = $(\"#\" + id);\n",
       "    var ws_proxy = comm_websocket_adapter(comm)\n",
       "\n",
       "    function ondownload(figure, format) {\n",
       "        window.open(figure.imageObj.src);\n",
       "    }\n",
       "\n",
       "    var fig = new mpl.figure(id, ws_proxy,\n",
       "                           ondownload,\n",
       "                           element.get(0));\n",
       "\n",
       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
       "    // web socket which is closed, not our websocket->open comm proxy.\n",
       "    ws_proxy.onopen();\n",
       "\n",
       "    fig.parent_element = element.get(0);\n",
       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
       "    if (!fig.cell_info) {\n",
       "        console.error(\"Failed to find cell for figure\", id, fig);\n",
       "        return;\n",
       "    }\n",
       "\n",
       "    var output_index = fig.cell_info[2]\n",
       "    var cell = fig.cell_info[0];\n",
       "\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
       "    var width = fig.canvas.width/mpl.ratio\n",
       "    fig.root.unbind('remove')\n",
       "\n",
       "    // Update the output cell to use the data from the current canvas.\n",
       "    fig.push_to_output();\n",
       "    var dataURL = fig.canvas.toDataURL();\n",
       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
       "    // the notebook keyboard shortcuts fail.\n",
       "    IPython.keyboard_manager.enable()\n",
       "    $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
       "    fig.close_ws(fig, msg);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.close_ws = function(fig, msg){\n",
       "    fig.send_message('closing', msg);\n",
       "    // fig.ws.close()\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
       "    // Turn the data on the canvas into data in the output cell.\n",
       "    var width = this.canvas.width/mpl.ratio\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Tell IPython that the notebook contents must change.\n",
       "    IPython.notebook.set_dirty(true);\n",
       "    this.send_message(\"ack\", {});\n",
       "    var fig = this;\n",
       "    // Wait a second, then push the new image to the DOM so\n",
       "    // that it is saved nicely (might be nice to debounce this).\n",
       "    setTimeout(function () { fig.push_to_output() }, 1000);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items){\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) { continue; };\n",
       "\n",
       "        var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    // Add the status bar.\n",
       "    var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "\n",
       "    // Add the close button to the window.\n",
       "    var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
       "    var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
       "    button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
       "    button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
       "    buttongrp.append(button);\n",
       "    var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
       "    titlebar.prepend(buttongrp);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(el){\n",
       "    var fig = this\n",
       "    el.on(\"remove\", function(){\n",
       "\tfig.close_ws(fig, {});\n",
       "    });\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(el){\n",
       "    // this is important to make the div 'focusable\n",
       "    el.attr('tabindex', 0)\n",
       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
       "    // off when our div gets focus\n",
       "\n",
       "    // location in version 3\n",
       "    if (IPython.notebook.keyboard_manager) {\n",
       "        IPython.notebook.keyboard_manager.register_events(el);\n",
       "    }\n",
       "    else {\n",
       "        // location in version 2\n",
       "        IPython.keyboard_manager.register_events(el);\n",
       "    }\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager)\n",
       "        manager = IPython.keyboard_manager;\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which == 13) {\n",
       "        this.canvas_div.blur();\n",
       "        event.shiftKey = false;\n",
       "        // Send a \"J\" for go to next cell\n",
       "        event.which = 74;\n",
       "        event.keyCode = 74;\n",
       "        manager.command_mode();\n",
       "        manager.handle_keydown(event);\n",
       "    }\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.find_output_cell = function(html_output) {\n",
       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
       "    // IPython event is triggered only after the cells have been serialised, which for\n",
       "    // our purposes (turning an active figure into a static one), is too late.\n",
       "    var cells = IPython.notebook.get_cells();\n",
       "    var ncells = cells.length;\n",
       "    for (var i=0; i<ncells; i++) {\n",
       "        var cell = cells[i];\n",
       "        if (cell.cell_type === 'code'){\n",
       "            for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
       "                var data = cell.output_area.outputs[j];\n",
       "                if (data.data) {\n",
       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
       "                    data = data.data;\n",
       "                }\n",
       "                if (data['text/html'] == html_output) {\n",
       "                    return [cell, data, j];\n",
       "                }\n",
       "            }\n",
       "        }\n",
       "    }\n",
       "}\n",
       "\n",
       "// Register the function which deals with the matplotlib target/channel.\n",
       "// The kernel may be null if the page has been refreshed.\n",
       "if (IPython.notebook.kernel != null) {\n",
       "    IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
       "}\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,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\" width=\"573\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "kwarg = {\"npt\":npt, \n",
    "         \"method\": \"nosplit_csr\", \n",
    "         \"correctSolidAngle\":True, \n",
    "         \"polarization_factor\":0.95,\n",
    "         \"safe\":False}\n",
    "\n",
    "#As we use \"safe\"=False, we need to reset the integrator manually:\n",
    "ai.reset()\n",
    "\n",
    "def plot_distribution(ai, kwargs, nbins=100, integrate=None):\n",
    "    ai.reset()\n",
    "    results = []\n",
    "    c2 = []\n",
    "    if integrate is None:\n",
    "        integrate = ai._integrate1d_legacy\n",
    "    for i in range(nimg):\n",
    "        data = dataset[i, :, :]\n",
    "        r = integrate(data, variance=data, **kwarg)\n",
    "        results.append(r)    \n",
    "        for j in range(i):\n",
    "            c2.append(chi2_curves(r, results[j]))\n",
    "    c2 = numpy.array(c2)\n",
    "    fig, ax = subplots()\n",
    "    h,b,_ = ax.hist(c2, nbins, label=\"Measured distibution\")\n",
    "    y_sim = chi2_dist.pdf(b*(nimg-1), nimg)\n",
    "    y_sim *= h.sum()/y_sim.sum()\n",
    "    ax.plot(b, y_sim, label=r\"Chi^2 distribution\")\n",
    "    ax.set_title(\"Integrated curves\")\n",
    "    ax.legend()\n",
    "    return fig, ax\n",
    "\n",
    "f,a = plot_distribution(ai, kwarg)\n",
    "f.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The normalisation of the raw signal distorts the distribution of error, even at a level of a few percent correction ! (Thanks Daniel Franke for the demonstration)\n",
    "\n",
    "# Introducing the next generation azimuthal integrator ... pyFAI 0.16\n",
    "\n",
    "As any normalization introduces some distortion into the error propagation, the error propagation should properly account for this. Alessandro Mirone suggested to treat normalization within azimuthal integration like this :\n",
    "\n",
    "$$\n",
    "I_{bin} = \\frac{\\sum_{pix \\in bin} I_{pix}}{\\sum_{pix \\in bin} \\Omega_{pix}P_{pix}}\n",
    "$$\n",
    "\n",
    "This is under investigation since begining 2017 https://github.com/silx-kit/pyFAI/issues/520 and is now available as part of pyFAI_0.16 as the ```_integrate1d_ng``` method of any ```AzimuthalIntegrator``` object. This procedure has for now lower performances than the legacy version and we hope to get the performances back for version 0.17 and make it the default behaviour.\n",
    "\n",
    "**Nota:**\n",
    "This is a major issue as almost any commercial detector comes with flatfield correction already applied on raw images; making impossible to properly propagate the error (I am especially thinking at photon counting detectors manufactured by Dectris!). The detector should then provide the actual raw-signal and the flatfield normalization to allow proper signal and error propagation.\n",
    "\n",
    "This is a demonstration of how one can build an AzimuthalIntegrator-like class with proper error propagaton:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pyFAI.containers import Integrate1dResult\n",
    "from pyFAI.azimuthalIntegrator import AzimuthalIntegrator\n",
    "from copy import copy\n",
    "\n",
    "class AzimuthalIntegratorNextGen(AzimuthalIntegrator):\n",
    "    def integrate1d_ng(self, data, variance, **kwargs):\n",
    "        \"\"\"Demonstrator for the new azimuthal integrator taking care of the normalization, \n",
    "        here implemented only on the solid-angle correction\"\"\"\n",
    "        kwargs = kwargs.copy()\n",
    "        if kwargs[\"correctSolidAngle\"]:\n",
    "            norm = self.solidAngleArray(self.detector.shape).copy()\n",
    "        else:\n",
    "            norm = numpy.ones(data.shape)\n",
    "        kwargs[\"correctSolidAngle\"] = False\n",
    "        polf = kwargs.get(\"polarization_factor\")\n",
    "        if polf:\n",
    "            norm *= self.polarization(self.detector.shape, factor=polf)\n",
    "        kwargs[\"polarization_factor\"] = None\n",
    "        flat = kwargs.get(\"flat\")\n",
    "        if flat is not None:\n",
    "            norm *= flat\n",
    "        kwargs[\"flat\"] = None\n",
    "        denom = self.integrate1d(norm, **kwargs)\n",
    "        signal = self.integrate1d(data, **kwargs)\n",
    "        sigma2 = self.integrate1d(variance, **kwargs)\n",
    "        result = Integrate1dResult(denom.radial, \n",
    "                                   signal.sum/denom.sum, \n",
    "                                   numpy.sqrt(sigma2.sum)/denom.sum)\n",
    "        result._set_method_called(\"integrate1d_ng\")\n",
    "        result._set_compute_engine(denom.compute_engine)\n",
    "        result._set_unit(signal.unit)\n",
    "        result._set_sum(signal.sum)\n",
    "        result._set_count(signal.count)\n",
    "        return result\n",
    "    \n",
    "\n",
    "ai2 = AzimuthalIntegratorNextGen(**ai_init)\n",
    "kwarg = {\"npt\":npt, \n",
    "         \"method\": \"nosplit_csr_ocl_gpu\", \n",
    "         \"correctSolidAngle\":True, \n",
    "         \"polarization_factor\":0.95,\n",
    "         \"safe\":False}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "/* Put everything inside the global mpl namespace */\n",
       "window.mpl = {};\n",
       "\n",
       "\n",
       "mpl.get_websocket_type = function() {\n",
       "    if (typeof(WebSocket) !== 'undefined') {\n",
       "        return WebSocket;\n",
       "    } else if (typeof(MozWebSocket) !== 'undefined') {\n",
       "        return MozWebSocket;\n",
       "    } else {\n",
       "        alert('Your browser does not have WebSocket support.' +\n",
       "              'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
       "              'Firefox 4 and 5 are also supported but you ' +\n",
       "              'have to enable WebSockets in about:config.');\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
       "    this.id = figure_id;\n",
       "\n",
       "    this.ws = websocket;\n",
       "\n",
       "    this.supports_binary = (this.ws.binaryType != undefined);\n",
       "\n",
       "    if (!this.supports_binary) {\n",
       "        var warnings = document.getElementById(\"mpl-warnings\");\n",
       "        if (warnings) {\n",
       "            warnings.style.display = 'block';\n",
       "            warnings.textContent = (\n",
       "                \"This browser does not support binary websocket messages. \" +\n",
       "                    \"Performance may be slow.\");\n",
       "        }\n",
       "    }\n",
       "\n",
       "    this.imageObj = new Image();\n",
       "\n",
       "    this.context = undefined;\n",
       "    this.message = undefined;\n",
       "    this.canvas = undefined;\n",
       "    this.rubberband_canvas = undefined;\n",
       "    this.rubberband_context = undefined;\n",
       "    this.format_dropdown = undefined;\n",
       "\n",
       "    this.image_mode = 'full';\n",
       "\n",
       "    this.root = $('<div/>');\n",
       "    this._root_extra_style(this.root)\n",
       "    this.root.attr('style', 'display: inline-block');\n",
       "\n",
       "    $(parent_element).append(this.root);\n",
       "\n",
       "    this._init_header(this);\n",
       "    this._init_canvas(this);\n",
       "    this._init_toolbar(this);\n",
       "\n",
       "    var fig = this;\n",
       "\n",
       "    this.waiting = false;\n",
       "\n",
       "    this.ws.onopen =  function () {\n",
       "            fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
       "            fig.send_message(\"send_image_mode\", {});\n",
       "            if (mpl.ratio != 1) {\n",
       "                fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
       "            }\n",
       "            fig.send_message(\"refresh\", {});\n",
       "        }\n",
       "\n",
       "    this.imageObj.onload = function() {\n",
       "            if (fig.image_mode == 'full') {\n",
       "                // Full images could contain transparency (where diff images\n",
       "                // almost always do), so we need to clear the canvas so that\n",
       "                // there is no ghosting.\n",
       "                fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
       "            }\n",
       "            fig.context.drawImage(fig.imageObj, 0, 0);\n",
       "        };\n",
       "\n",
       "    this.imageObj.onunload = function() {\n",
       "        fig.ws.close();\n",
       "    }\n",
       "\n",
       "    this.ws.onmessage = this._make_on_message_function(this);\n",
       "\n",
       "    this.ondownload = ondownload;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_header = function() {\n",
       "    var titlebar = $(\n",
       "        '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
       "        'ui-helper-clearfix\"/>');\n",
       "    var titletext = $(\n",
       "        '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
       "        'text-align: center; padding: 3px;\"/>');\n",
       "    titlebar.append(titletext)\n",
       "    this.root.append(titlebar);\n",
       "    this.header = titletext[0];\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_canvas = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var canvas_div = $('<div/>');\n",
       "\n",
       "    canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
       "\n",
       "    function canvas_keyboard_event(event) {\n",
       "        return fig.key_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    canvas_div.keydown('key_press', canvas_keyboard_event);\n",
       "    canvas_div.keyup('key_release', canvas_keyboard_event);\n",
       "    this.canvas_div = canvas_div\n",
       "    this._canvas_extra_style(canvas_div)\n",
       "    this.root.append(canvas_div);\n",
       "\n",
       "    var canvas = $('<canvas/>');\n",
       "    canvas.addClass('mpl-canvas');\n",
       "    canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
       "\n",
       "    this.canvas = canvas[0];\n",
       "    this.context = canvas[0].getContext(\"2d\");\n",
       "\n",
       "    var backingStore = this.context.backingStorePixelRatio ||\n",
       "\tthis.context.webkitBackingStorePixelRatio ||\n",
       "\tthis.context.mozBackingStorePixelRatio ||\n",
       "\tthis.context.msBackingStorePixelRatio ||\n",
       "\tthis.context.oBackingStorePixelRatio ||\n",
       "\tthis.context.backingStorePixelRatio || 1;\n",
       "\n",
       "    mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
       "\n",
       "    var rubberband = $('<canvas/>');\n",
       "    rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
       "\n",
       "    var pass_mouse_events = true;\n",
       "\n",
       "    canvas_div.resizable({\n",
       "        start: function(event, ui) {\n",
       "            pass_mouse_events = false;\n",
       "        },\n",
       "        resize: function(event, ui) {\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "        stop: function(event, ui) {\n",
       "            pass_mouse_events = true;\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "    });\n",
       "\n",
       "    function mouse_event_fn(event) {\n",
       "        if (pass_mouse_events)\n",
       "            return fig.mouse_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    rubberband.mousedown('button_press', mouse_event_fn);\n",
       "    rubberband.mouseup('button_release', mouse_event_fn);\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband.mousemove('motion_notify', mouse_event_fn);\n",
       "\n",
       "    rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
       "    rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
       "\n",
       "    canvas_div.on(\"wheel\", function (event) {\n",
       "        event = event.originalEvent;\n",
       "        event['data'] = 'scroll'\n",
       "        if (event.deltaY < 0) {\n",
       "            event.step = 1;\n",
       "        } else {\n",
       "            event.step = -1;\n",
       "        }\n",
       "        mouse_event_fn(event);\n",
       "    });\n",
       "\n",
       "    canvas_div.append(canvas);\n",
       "    canvas_div.append(rubberband);\n",
       "\n",
       "    this.rubberband = rubberband;\n",
       "    this.rubberband_canvas = rubberband[0];\n",
       "    this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
       "    this.rubberband_context.strokeStyle = \"#000000\";\n",
       "\n",
       "    this._resize_canvas = function(width, height) {\n",
       "        // Keep the size of the canvas, canvas container, and rubber band\n",
       "        // canvas in synch.\n",
       "        canvas_div.css('width', width)\n",
       "        canvas_div.css('height', height)\n",
       "\n",
       "        canvas.attr('width', width * mpl.ratio);\n",
       "        canvas.attr('height', height * mpl.ratio);\n",
       "        canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
       "\n",
       "        rubberband.attr('width', width);\n",
       "        rubberband.attr('height', height);\n",
       "    }\n",
       "\n",
       "    // Set the figure to an initial 600x600px, this will subsequently be updated\n",
       "    // upon first draw.\n",
       "    this._resize_canvas(600, 600);\n",
       "\n",
       "    // Disable right mouse context menu.\n",
       "    $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
       "        return false;\n",
       "    });\n",
       "\n",
       "    function set_focus () {\n",
       "        canvas.focus();\n",
       "        canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    window.setTimeout(set_focus, 100);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items) {\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) {\n",
       "            // put a spacer in here.\n",
       "            continue;\n",
       "        }\n",
       "        var button = $('<button/>');\n",
       "        button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
       "                        'ui-button-icon-only');\n",
       "        button.attr('role', 'button');\n",
       "        button.attr('aria-disabled', 'false');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "\n",
       "        var icon_img = $('<span/>');\n",
       "        icon_img.addClass('ui-button-icon-primary ui-icon');\n",
       "        icon_img.addClass(image);\n",
       "        icon_img.addClass('ui-corner-all');\n",
       "\n",
       "        var tooltip_span = $('<span/>');\n",
       "        tooltip_span.addClass('ui-button-text');\n",
       "        tooltip_span.html(tooltip);\n",
       "\n",
       "        button.append(icon_img);\n",
       "        button.append(tooltip_span);\n",
       "\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    var fmt_picker_span = $('<span/>');\n",
       "\n",
       "    var fmt_picker = $('<select/>');\n",
       "    fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
       "    fmt_picker_span.append(fmt_picker);\n",
       "    nav_element.append(fmt_picker_span);\n",
       "    this.format_dropdown = fmt_picker[0];\n",
       "\n",
       "    for (var ind in mpl.extensions) {\n",
       "        var fmt = mpl.extensions[ind];\n",
       "        var option = $(\n",
       "            '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
       "        fmt_picker.append(option)\n",
       "    }\n",
       "\n",
       "    // Add hover states to the ui-buttons\n",
       "    $( \".ui-button\" ).hover(\n",
       "        function() { $(this).addClass(\"ui-state-hover\");},\n",
       "        function() { $(this).removeClass(\"ui-state-hover\");}\n",
       "    );\n",
       "\n",
       "    var status_bar = $('<span class=\"mpl-message\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
       "    // which will in turn request a refresh of the image.\n",
       "    this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_message = function(type, properties) {\n",
       "    properties['type'] = type;\n",
       "    properties['figure_id'] = this.id;\n",
       "    this.ws.send(JSON.stringify(properties));\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_draw_message = function() {\n",
       "    if (!this.waiting) {\n",
       "        this.waiting = true;\n",
       "        this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
       "    }\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    var format_dropdown = fig.format_dropdown;\n",
       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
       "    fig.ondownload(fig, format);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
       "    var size = msg['size'];\n",
       "    if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
       "        fig._resize_canvas(size[0], size[1]);\n",
       "        fig.send_message(\"refresh\", {});\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
       "    var x0 = msg['x0'] / mpl.ratio;\n",
       "    var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
       "    var x1 = msg['x1'] / mpl.ratio;\n",
       "    var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
       "    x0 = Math.floor(x0) + 0.5;\n",
       "    y0 = Math.floor(y0) + 0.5;\n",
       "    x1 = Math.floor(x1) + 0.5;\n",
       "    y1 = Math.floor(y1) + 0.5;\n",
       "    var min_x = Math.min(x0, x1);\n",
       "    var min_y = Math.min(y0, y1);\n",
       "    var width = Math.abs(x1 - x0);\n",
       "    var height = Math.abs(y1 - y0);\n",
       "\n",
       "    fig.rubberband_context.clearRect(\n",
       "        0, 0, fig.canvas.width, fig.canvas.height);\n",
       "\n",
       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
       "    // Updates the figure title.\n",
       "    fig.header.textContent = msg['label'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
       "    var cursor = msg['cursor'];\n",
       "    switch(cursor)\n",
       "    {\n",
       "    case 0:\n",
       "        cursor = 'pointer';\n",
       "        break;\n",
       "    case 1:\n",
       "        cursor = 'default';\n",
       "        break;\n",
       "    case 2:\n",
       "        cursor = 'crosshair';\n",
       "        break;\n",
       "    case 3:\n",
       "        cursor = 'move';\n",
       "        break;\n",
       "    }\n",
       "    fig.rubberband_canvas.style.cursor = cursor;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
       "    fig.message.textContent = msg['message'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
       "    // Request the server to send over a new figure.\n",
       "    fig.send_draw_message();\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
       "    fig.image_mode = msg['mode'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Called whenever the canvas gets updated.\n",
       "    this.send_message(\"ack\", {});\n",
       "}\n",
       "\n",
       "// A function to construct a web socket function for onmessage handling.\n",
       "// Called in the figure constructor.\n",
       "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
       "    return function socket_on_message(evt) {\n",
       "        if (evt.data instanceof Blob) {\n",
       "            /* FIXME: We get \"Resource interpreted as Image but\n",
       "             * transferred with MIME type text/plain:\" errors on\n",
       "             * Chrome.  But how to set the MIME type?  It doesn't seem\n",
       "             * to be part of the websocket stream */\n",
       "            evt.data.type = \"image/png\";\n",
       "\n",
       "            /* Free the memory for the previous frames */\n",
       "            if (fig.imageObj.src) {\n",
       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
       "                    fig.imageObj.src);\n",
       "            }\n",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data);\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "        else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
       "            fig.imageObj.src = evt.data;\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        var msg = JSON.parse(evt.data);\n",
       "        var msg_type = msg['type'];\n",
       "\n",
       "        // Call the  \"handle_{type}\" callback, which takes\n",
       "        // the figure and JSON message as its only arguments.\n",
       "        try {\n",
       "            var callback = fig[\"handle_\" + msg_type];\n",
       "        } catch (e) {\n",
       "            console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        if (callback) {\n",
       "            try {\n",
       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
       "                callback(fig, msg);\n",
       "            } catch (e) {\n",
       "                console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
       "            }\n",
       "        }\n",
       "    };\n",
       "}\n",
       "\n",
       "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
       "mpl.findpos = function(e) {\n",
       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
       "    var targ;\n",
       "    if (!e)\n",
       "        e = window.event;\n",
       "    if (e.target)\n",
       "        targ = e.target;\n",
       "    else if (e.srcElement)\n",
       "        targ = e.srcElement;\n",
       "    if (targ.nodeType == 3) // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "\n",
       "    // jQuery normalizes the pageX and pageY\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    // offset() returns the position of the element relative to the document\n",
       "    var x = e.pageX - $(targ).offset().left;\n",
       "    var y = e.pageY - $(targ).offset().top;\n",
       "\n",
       "    return {\"x\": x, \"y\": y};\n",
       "};\n",
       "\n",
       "/*\n",
       " * return a copy of an object with only non-object keys\n",
       " * we need this to avoid circular references\n",
       " * http://stackoverflow.com/a/24161582/3208463\n",
       " */\n",
       "function simpleKeys (original) {\n",
       "  return Object.keys(original).reduce(function (obj, key) {\n",
       "    if (typeof original[key] !== 'object')\n",
       "        obj[key] = original[key]\n",
       "    return obj;\n",
       "  }, {});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.mouse_event = function(event, name) {\n",
       "    var canvas_pos = mpl.findpos(event)\n",
       "\n",
       "    if (name === 'button_press')\n",
       "    {\n",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * mpl.ratio;\n",
       "    var y = canvas_pos.y * mpl.ratio;\n",
       "\n",
       "    this.send_message(name, {x: x, y: y, button: event.button,\n",
       "                             step: event.step,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "\n",
       "    /* This prevents the web browser from automatically changing to\n",
       "     * the text insertion cursor when the button is pressed.  We want\n",
       "     * to control all of the cursor setting manually through the\n",
       "     * 'cursor' event from matplotlib */\n",
       "    event.preventDefault();\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    // Handle any extra behaviour associated with a key event\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.key_event = function(event, name) {\n",
       "\n",
       "    // Prevent repeat events\n",
       "    if (name == 'key_press')\n",
       "    {\n",
       "        if (event.which === this._key)\n",
       "            return;\n",
       "        else\n",
       "            this._key = event.which;\n",
       "    }\n",
       "    if (name == 'key_release')\n",
       "        this._key = null;\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which != 17)\n",
       "        value += \"ctrl+\";\n",
       "    if (event.altKey && event.which != 18)\n",
       "        value += \"alt+\";\n",
       "    if (event.shiftKey && event.which != 16)\n",
       "        value += \"shift+\";\n",
       "\n",
       "    value += 'k';\n",
       "    value += event.which.toString();\n",
       "\n",
       "    this._key_event_extra(event, name);\n",
       "\n",
       "    this.send_message(name, {key: value,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
       "    if (name == 'download') {\n",
       "        this.handle_save(this, null);\n",
       "    } else {\n",
       "        this.send_message(\"toolbar_button\", {name: name});\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
       "    this.message.textContent = tooltip;\n",
       "};\n",
       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
       "\n",
       "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
       "\n",
       "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
       "    // object with the appropriate methods. Currently this is a non binary\n",
       "    // socket, so there is still some room for performance tuning.\n",
       "    var ws = {};\n",
       "\n",
       "    ws.close = function() {\n",
       "        comm.close()\n",
       "    };\n",
       "    ws.send = function(m) {\n",
       "        //console.log('sending', m);\n",
       "        comm.send(m);\n",
       "    };\n",
       "    // Register the callback with on_msg.\n",
       "    comm.on_msg(function(msg) {\n",
       "        //console.log('receiving', msg['content']['data'], msg);\n",
       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
       "        ws.onmessage(msg['content']['data'])\n",
       "    });\n",
       "    return ws;\n",
       "}\n",
       "\n",
       "mpl.mpl_figure_comm = function(comm, msg) {\n",
       "    // This is the function which gets called when the mpl process\n",
       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
       "\n",
       "    var id = msg.content.data.id;\n",
       "    // Get hold of the div created by the display call when the Comm\n",
       "    // socket was opened in Python.\n",
       "    var element = $(\"#\" + id);\n",
       "    var ws_proxy = comm_websocket_adapter(comm)\n",
       "\n",
       "    function ondownload(figure, format) {\n",
       "        window.open(figure.imageObj.src);\n",
       "    }\n",
       "\n",
       "    var fig = new mpl.figure(id, ws_proxy,\n",
       "                           ondownload,\n",
       "                           element.get(0));\n",
       "\n",
       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
       "    // web socket which is closed, not our websocket->open comm proxy.\n",
       "    ws_proxy.onopen();\n",
       "\n",
       "    fig.parent_element = element.get(0);\n",
       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
       "    if (!fig.cell_info) {\n",
       "        console.error(\"Failed to find cell for figure\", id, fig);\n",
       "        return;\n",
       "    }\n",
       "\n",
       "    var output_index = fig.cell_info[2]\n",
       "    var cell = fig.cell_info[0];\n",
       "\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
       "    var width = fig.canvas.width/mpl.ratio\n",
       "    fig.root.unbind('remove')\n",
       "\n",
       "    // Update the output cell to use the data from the current canvas.\n",
       "    fig.push_to_output();\n",
       "    var dataURL = fig.canvas.toDataURL();\n",
       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
       "    // the notebook keyboard shortcuts fail.\n",
       "    IPython.keyboard_manager.enable()\n",
       "    $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
       "    fig.close_ws(fig, msg);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.close_ws = function(fig, msg){\n",
       "    fig.send_message('closing', msg);\n",
       "    // fig.ws.close()\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
       "    // Turn the data on the canvas into data in the output cell.\n",
       "    var width = this.canvas.width/mpl.ratio\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Tell IPython that the notebook contents must change.\n",
       "    IPython.notebook.set_dirty(true);\n",
       "    this.send_message(\"ack\", {});\n",
       "    var fig = this;\n",
       "    // Wait a second, then push the new image to the DOM so\n",
       "    // that it is saved nicely (might be nice to debounce this).\n",
       "    setTimeout(function () { fig.push_to_output() }, 1000);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items){\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) { continue; };\n",
       "\n",
       "        var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    // Add the status bar.\n",
       "    var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "\n",
       "    // Add the close button to the window.\n",
       "    var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
       "    var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
       "    button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
       "    button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
       "    buttongrp.append(button);\n",
       "    var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
       "    titlebar.prepend(buttongrp);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(el){\n",
       "    var fig = this\n",
       "    el.on(\"remove\", function(){\n",
       "\tfig.close_ws(fig, {});\n",
       "    });\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(el){\n",
       "    // this is important to make the div 'focusable\n",
       "    el.attr('tabindex', 0)\n",
       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
       "    // off when our div gets focus\n",
       "\n",
       "    // location in version 3\n",
       "    if (IPython.notebook.keyboard_manager) {\n",
       "        IPython.notebook.keyboard_manager.register_events(el);\n",
       "    }\n",
       "    else {\n",
       "        // location in version 2\n",
       "        IPython.keyboard_manager.register_events(el);\n",
       "    }\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager)\n",
       "        manager = IPython.keyboard_manager;\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which == 13) {\n",
       "        this.canvas_div.blur();\n",
       "        event.shiftKey = false;\n",
       "        // Send a \"J\" for go to next cell\n",
       "        event.which = 74;\n",
       "        event.keyCode = 74;\n",
       "        manager.command_mode();\n",
       "        manager.handle_keydown(event);\n",
       "    }\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.find_output_cell = function(html_output) {\n",
       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
       "    // IPython event is triggered only after the cells have been serialised, which for\n",
       "    // our purposes (turning an active figure into a static one), is too late.\n",
       "    var cells = IPython.notebook.get_cells();\n",
       "    var ncells = cells.length;\n",
       "    for (var i=0; i<ncells; i++) {\n",
       "        var cell = cells[i];\n",
       "        if (cell.cell_type === 'code'){\n",
       "            for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
       "                var data = cell.output_area.outputs[j];\n",
       "                if (data.data) {\n",
       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
       "                    data = data.data;\n",
       "                }\n",
       "                if (data['text/html'] == html_output) {\n",
       "                    return [cell, data, j];\n",
       "                }\n",
       "            }\n",
       "        }\n",
       "    }\n",
       "}\n",
       "\n",
       "// Register the function which deals with the matplotlib target/channel.\n",
       "// The kernel may be null if the page has been refreshed.\n",
       "if (IPython.notebook.kernel != null) {\n",
       "    IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
       "}\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,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\" width=\"573\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:pyFAI.ext.splitBBoxCSR:Pixel splitting desactivated !\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7f3b5601d0f0>"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#The new implementation provides almost the same result as the former one:\n",
    "ai.reset()\n",
    "fig, ax = subplots()\n",
    "data = dataset[0]\n",
    "res_ng = ai._integrate1d_ng(data, variance=data, **kwarg)\n",
    "jupyter.plot1d(res_ng, ax=ax, label=\"next_generation\")\n",
    "ax.set_yscale(\"log\")\n",
    "jupyter.plot1d(ai._integrate1d_legacy(data, variance=data, **kwarg), ax=ax, label=\"legacy\")\n",
    "#jupyter.plot1d(ai._integrate1d_ng(data, variance=data, **kwarg), ax=ax, label=\"next2\")\n",
    "ax.legend()\n",
    "\n",
    "# If you zoom in enough, you will see the difference !"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:pyFAI.ext.splitBBoxCSR:Pixel splitting desactivated !\n"
     ]
    },
    {
     "data": {
      "application/javascript": [
       "/* Put everything inside the global mpl namespace */\n",
       "window.mpl = {};\n",
       "\n",
       "\n",
       "mpl.get_websocket_type = function() {\n",
       "    if (typeof(WebSocket) !== 'undefined') {\n",
       "        return WebSocket;\n",
       "    } else if (typeof(MozWebSocket) !== 'undefined') {\n",
       "        return MozWebSocket;\n",
       "    } else {\n",
       "        alert('Your browser does not have WebSocket support.' +\n",
       "              'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
       "              'Firefox 4 and 5 are also supported but you ' +\n",
       "              'have to enable WebSockets in about:config.');\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
       "    this.id = figure_id;\n",
       "\n",
       "    this.ws = websocket;\n",
       "\n",
       "    this.supports_binary = (this.ws.binaryType != undefined);\n",
       "\n",
       "    if (!this.supports_binary) {\n",
       "        var warnings = document.getElementById(\"mpl-warnings\");\n",
       "        if (warnings) {\n",
       "            warnings.style.display = 'block';\n",
       "            warnings.textContent = (\n",
       "                \"This browser does not support binary websocket messages. \" +\n",
       "                    \"Performance may be slow.\");\n",
       "        }\n",
       "    }\n",
       "\n",
       "    this.imageObj = new Image();\n",
       "\n",
       "    this.context = undefined;\n",
       "    this.message = undefined;\n",
       "    this.canvas = undefined;\n",
       "    this.rubberband_canvas = undefined;\n",
       "    this.rubberband_context = undefined;\n",
       "    this.format_dropdown = undefined;\n",
       "\n",
       "    this.image_mode = 'full';\n",
       "\n",
       "    this.root = $('<div/>');\n",
       "    this._root_extra_style(this.root)\n",
       "    this.root.attr('style', 'display: inline-block');\n",
       "\n",
       "    $(parent_element).append(this.root);\n",
       "\n",
       "    this._init_header(this);\n",
       "    this._init_canvas(this);\n",
       "    this._init_toolbar(this);\n",
       "\n",
       "    var fig = this;\n",
       "\n",
       "    this.waiting = false;\n",
       "\n",
       "    this.ws.onopen =  function () {\n",
       "            fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
       "            fig.send_message(\"send_image_mode\", {});\n",
       "            if (mpl.ratio != 1) {\n",
       "                fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
       "            }\n",
       "            fig.send_message(\"refresh\", {});\n",
       "        }\n",
       "\n",
       "    this.imageObj.onload = function() {\n",
       "            if (fig.image_mode == 'full') {\n",
       "                // Full images could contain transparency (where diff images\n",
       "                // almost always do), so we need to clear the canvas so that\n",
       "                // there is no ghosting.\n",
       "                fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
       "            }\n",
       "            fig.context.drawImage(fig.imageObj, 0, 0);\n",
       "        };\n",
       "\n",
       "    this.imageObj.onunload = function() {\n",
       "        fig.ws.close();\n",
       "    }\n",
       "\n",
       "    this.ws.onmessage = this._make_on_message_function(this);\n",
       "\n",
       "    this.ondownload = ondownload;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_header = function() {\n",
       "    var titlebar = $(\n",
       "        '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
       "        'ui-helper-clearfix\"/>');\n",
       "    var titletext = $(\n",
       "        '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
       "        'text-align: center; padding: 3px;\"/>');\n",
       "    titlebar.append(titletext)\n",
       "    this.root.append(titlebar);\n",
       "    this.header = titletext[0];\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_canvas = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var canvas_div = $('<div/>');\n",
       "\n",
       "    canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
       "\n",
       "    function canvas_keyboard_event(event) {\n",
       "        return fig.key_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    canvas_div.keydown('key_press', canvas_keyboard_event);\n",
       "    canvas_div.keyup('key_release', canvas_keyboard_event);\n",
       "    this.canvas_div = canvas_div\n",
       "    this._canvas_extra_style(canvas_div)\n",
       "    this.root.append(canvas_div);\n",
       "\n",
       "    var canvas = $('<canvas/>');\n",
       "    canvas.addClass('mpl-canvas');\n",
       "    canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
       "\n",
       "    this.canvas = canvas[0];\n",
       "    this.context = canvas[0].getContext(\"2d\");\n",
       "\n",
       "    var backingStore = this.context.backingStorePixelRatio ||\n",
       "\tthis.context.webkitBackingStorePixelRatio ||\n",
       "\tthis.context.mozBackingStorePixelRatio ||\n",
       "\tthis.context.msBackingStorePixelRatio ||\n",
       "\tthis.context.oBackingStorePixelRatio ||\n",
       "\tthis.context.backingStorePixelRatio || 1;\n",
       "\n",
       "    mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
       "\n",
       "    var rubberband = $('<canvas/>');\n",
       "    rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
       "\n",
       "    var pass_mouse_events = true;\n",
       "\n",
       "    canvas_div.resizable({\n",
       "        start: function(event, ui) {\n",
       "            pass_mouse_events = false;\n",
       "        },\n",
       "        resize: function(event, ui) {\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "        stop: function(event, ui) {\n",
       "            pass_mouse_events = true;\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "    });\n",
       "\n",
       "    function mouse_event_fn(event) {\n",
       "        if (pass_mouse_events)\n",
       "            return fig.mouse_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    rubberband.mousedown('button_press', mouse_event_fn);\n",
       "    rubberband.mouseup('button_release', mouse_event_fn);\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband.mousemove('motion_notify', mouse_event_fn);\n",
       "\n",
       "    rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
       "    rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
       "\n",
       "    canvas_div.on(\"wheel\", function (event) {\n",
       "        event = event.originalEvent;\n",
       "        event['data'] = 'scroll'\n",
       "        if (event.deltaY < 0) {\n",
       "            event.step = 1;\n",
       "        } else {\n",
       "            event.step = -1;\n",
       "        }\n",
       "        mouse_event_fn(event);\n",
       "    });\n",
       "\n",
       "    canvas_div.append(canvas);\n",
       "    canvas_div.append(rubberband);\n",
       "\n",
       "    this.rubberband = rubberband;\n",
       "    this.rubberband_canvas = rubberband[0];\n",
       "    this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
       "    this.rubberband_context.strokeStyle = \"#000000\";\n",
       "\n",
       "    this._resize_canvas = function(width, height) {\n",
       "        // Keep the size of the canvas, canvas container, and rubber band\n",
       "        // canvas in synch.\n",
       "        canvas_div.css('width', width)\n",
       "        canvas_div.css('height', height)\n",
       "\n",
       "        canvas.attr('width', width * mpl.ratio);\n",
       "        canvas.attr('height', height * mpl.ratio);\n",
       "        canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
       "\n",
       "        rubberband.attr('width', width);\n",
       "        rubberband.attr('height', height);\n",
       "    }\n",
       "\n",
       "    // Set the figure to an initial 600x600px, this will subsequently be updated\n",
       "    // upon first draw.\n",
       "    this._resize_canvas(600, 600);\n",
       "\n",
       "    // Disable right mouse context menu.\n",
       "    $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
       "        return false;\n",
       "    });\n",
       "\n",
       "    function set_focus () {\n",
       "        canvas.focus();\n",
       "        canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    window.setTimeout(set_focus, 100);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items) {\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) {\n",
       "            // put a spacer in here.\n",
       "            continue;\n",
       "        }\n",
       "        var button = $('<button/>');\n",
       "        button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
       "                        'ui-button-icon-only');\n",
       "        button.attr('role', 'button');\n",
       "        button.attr('aria-disabled', 'false');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "\n",
       "        var icon_img = $('<span/>');\n",
       "        icon_img.addClass('ui-button-icon-primary ui-icon');\n",
       "        icon_img.addClass(image);\n",
       "        icon_img.addClass('ui-corner-all');\n",
       "\n",
       "        var tooltip_span = $('<span/>');\n",
       "        tooltip_span.addClass('ui-button-text');\n",
       "        tooltip_span.html(tooltip);\n",
       "\n",
       "        button.append(icon_img);\n",
       "        button.append(tooltip_span);\n",
       "\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    var fmt_picker_span = $('<span/>');\n",
       "\n",
       "    var fmt_picker = $('<select/>');\n",
       "    fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
       "    fmt_picker_span.append(fmt_picker);\n",
       "    nav_element.append(fmt_picker_span);\n",
       "    this.format_dropdown = fmt_picker[0];\n",
       "\n",
       "    for (var ind in mpl.extensions) {\n",
       "        var fmt = mpl.extensions[ind];\n",
       "        var option = $(\n",
       "            '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
       "        fmt_picker.append(option)\n",
       "    }\n",
       "\n",
       "    // Add hover states to the ui-buttons\n",
       "    $( \".ui-button\" ).hover(\n",
       "        function() { $(this).addClass(\"ui-state-hover\");},\n",
       "        function() { $(this).removeClass(\"ui-state-hover\");}\n",
       "    );\n",
       "\n",
       "    var status_bar = $('<span class=\"mpl-message\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
       "    // which will in turn request a refresh of the image.\n",
       "    this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_message = function(type, properties) {\n",
       "    properties['type'] = type;\n",
       "    properties['figure_id'] = this.id;\n",
       "    this.ws.send(JSON.stringify(properties));\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_draw_message = function() {\n",
       "    if (!this.waiting) {\n",
       "        this.waiting = true;\n",
       "        this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
       "    }\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    var format_dropdown = fig.format_dropdown;\n",
       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
       "    fig.ondownload(fig, format);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
       "    var size = msg['size'];\n",
       "    if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
       "        fig._resize_canvas(size[0], size[1]);\n",
       "        fig.send_message(\"refresh\", {});\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
       "    var x0 = msg['x0'] / mpl.ratio;\n",
       "    var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
       "    var x1 = msg['x1'] / mpl.ratio;\n",
       "    var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
       "    x0 = Math.floor(x0) + 0.5;\n",
       "    y0 = Math.floor(y0) + 0.5;\n",
       "    x1 = Math.floor(x1) + 0.5;\n",
       "    y1 = Math.floor(y1) + 0.5;\n",
       "    var min_x = Math.min(x0, x1);\n",
       "    var min_y = Math.min(y0, y1);\n",
       "    var width = Math.abs(x1 - x0);\n",
       "    var height = Math.abs(y1 - y0);\n",
       "\n",
       "    fig.rubberband_context.clearRect(\n",
       "        0, 0, fig.canvas.width, fig.canvas.height);\n",
       "\n",
       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
       "    // Updates the figure title.\n",
       "    fig.header.textContent = msg['label'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
       "    var cursor = msg['cursor'];\n",
       "    switch(cursor)\n",
       "    {\n",
       "    case 0:\n",
       "        cursor = 'pointer';\n",
       "        break;\n",
       "    case 1:\n",
       "        cursor = 'default';\n",
       "        break;\n",
       "    case 2:\n",
       "        cursor = 'crosshair';\n",
       "        break;\n",
       "    case 3:\n",
       "        cursor = 'move';\n",
       "        break;\n",
       "    }\n",
       "    fig.rubberband_canvas.style.cursor = cursor;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
       "    fig.message.textContent = msg['message'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
       "    // Request the server to send over a new figure.\n",
       "    fig.send_draw_message();\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
       "    fig.image_mode = msg['mode'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Called whenever the canvas gets updated.\n",
       "    this.send_message(\"ack\", {});\n",
       "}\n",
       "\n",
       "// A function to construct a web socket function for onmessage handling.\n",
       "// Called in the figure constructor.\n",
       "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
       "    return function socket_on_message(evt) {\n",
       "        if (evt.data instanceof Blob) {\n",
       "            /* FIXME: We get \"Resource interpreted as Image but\n",
       "             * transferred with MIME type text/plain:\" errors on\n",
       "             * Chrome.  But how to set the MIME type?  It doesn't seem\n",
       "             * to be part of the websocket stream */\n",
       "            evt.data.type = \"image/png\";\n",
       "\n",
       "            /* Free the memory for the previous frames */\n",
       "            if (fig.imageObj.src) {\n",
       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
       "                    fig.imageObj.src);\n",
       "            }\n",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data);\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "        else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
       "            fig.imageObj.src = evt.data;\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        var msg = JSON.parse(evt.data);\n",
       "        var msg_type = msg['type'];\n",
       "\n",
       "        // Call the  \"handle_{type}\" callback, which takes\n",
       "        // the figure and JSON message as its only arguments.\n",
       "        try {\n",
       "            var callback = fig[\"handle_\" + msg_type];\n",
       "        } catch (e) {\n",
       "            console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        if (callback) {\n",
       "            try {\n",
       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
       "                callback(fig, msg);\n",
       "            } catch (e) {\n",
       "                console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
       "            }\n",
       "        }\n",
       "    };\n",
       "}\n",
       "\n",
       "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
       "mpl.findpos = function(e) {\n",
       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
       "    var targ;\n",
       "    if (!e)\n",
       "        e = window.event;\n",
       "    if (e.target)\n",
       "        targ = e.target;\n",
       "    else if (e.srcElement)\n",
       "        targ = e.srcElement;\n",
       "    if (targ.nodeType == 3) // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "\n",
       "    // jQuery normalizes the pageX and pageY\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    // offset() returns the position of the element relative to the document\n",
       "    var x = e.pageX - $(targ).offset().left;\n",
       "    var y = e.pageY - $(targ).offset().top;\n",
       "\n",
       "    return {\"x\": x, \"y\": y};\n",
       "};\n",
       "\n",
       "/*\n",
       " * return a copy of an object with only non-object keys\n",
       " * we need this to avoid circular references\n",
       " * http://stackoverflow.com/a/24161582/3208463\n",
       " */\n",
       "function simpleKeys (original) {\n",
       "  return Object.keys(original).reduce(function (obj, key) {\n",
       "    if (typeof original[key] !== 'object')\n",
       "        obj[key] = original[key]\n",
       "    return obj;\n",
       "  }, {});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.mouse_event = function(event, name) {\n",
       "    var canvas_pos = mpl.findpos(event)\n",
       "\n",
       "    if (name === 'button_press')\n",
       "    {\n",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * mpl.ratio;\n",
       "    var y = canvas_pos.y * mpl.ratio;\n",
       "\n",
       "    this.send_message(name, {x: x, y: y, button: event.button,\n",
       "                             step: event.step,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "\n",
       "    /* This prevents the web browser from automatically changing to\n",
       "     * the text insertion cursor when the button is pressed.  We want\n",
       "     * to control all of the cursor setting manually through the\n",
       "     * 'cursor' event from matplotlib */\n",
       "    event.preventDefault();\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    // Handle any extra behaviour associated with a key event\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.key_event = function(event, name) {\n",
       "\n",
       "    // Prevent repeat events\n",
       "    if (name == 'key_press')\n",
       "    {\n",
       "        if (event.which === this._key)\n",
       "            return;\n",
       "        else\n",
       "            this._key = event.which;\n",
       "    }\n",
       "    if (name == 'key_release')\n",
       "        this._key = null;\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which != 17)\n",
       "        value += \"ctrl+\";\n",
       "    if (event.altKey && event.which != 18)\n",
       "        value += \"alt+\";\n",
       "    if (event.shiftKey && event.which != 16)\n",
       "        value += \"shift+\";\n",
       "\n",
       "    value += 'k';\n",
       "    value += event.which.toString();\n",
       "\n",
       "    this._key_event_extra(event, name);\n",
       "\n",
       "    this.send_message(name, {key: value,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
       "    if (name == 'download') {\n",
       "        this.handle_save(this, null);\n",
       "    } else {\n",
       "        this.send_message(\"toolbar_button\", {name: name});\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
       "    this.message.textContent = tooltip;\n",
       "};\n",
       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
       "\n",
       "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
       "\n",
       "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
       "    // object with the appropriate methods. Currently this is a non binary\n",
       "    // socket, so there is still some room for performance tuning.\n",
       "    var ws = {};\n",
       "\n",
       "    ws.close = function() {\n",
       "        comm.close()\n",
       "    };\n",
       "    ws.send = function(m) {\n",
       "        //console.log('sending', m);\n",
       "        comm.send(m);\n",
       "    };\n",
       "    // Register the callback with on_msg.\n",
       "    comm.on_msg(function(msg) {\n",
       "        //console.log('receiving', msg['content']['data'], msg);\n",
       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
       "        ws.onmessage(msg['content']['data'])\n",
       "    });\n",
       "    return ws;\n",
       "}\n",
       "\n",
       "mpl.mpl_figure_comm = function(comm, msg) {\n",
       "    // This is the function which gets called when the mpl process\n",
       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
       "\n",
       "    var id = msg.content.data.id;\n",
       "    // Get hold of the div created by the display call when the Comm\n",
       "    // socket was opened in Python.\n",
       "    var element = $(\"#\" + id);\n",
       "    var ws_proxy = comm_websocket_adapter(comm)\n",
       "\n",
       "    function ondownload(figure, format) {\n",
       "        window.open(figure.imageObj.src);\n",
       "    }\n",
       "\n",
       "    var fig = new mpl.figure(id, ws_proxy,\n",
       "                           ondownload,\n",
       "                           element.get(0));\n",
       "\n",
       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
       "    // web socket which is closed, not our websocket->open comm proxy.\n",
       "    ws_proxy.onopen();\n",
       "\n",
       "    fig.parent_element = element.get(0);\n",
       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
       "    if (!fig.cell_info) {\n",
       "        console.error(\"Failed to find cell for figure\", id, fig);\n",
       "        return;\n",
       "    }\n",
       "\n",
       "    var output_index = fig.cell_info[2]\n",
       "    var cell = fig.cell_info[0];\n",
       "\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
       "    var width = fig.canvas.width/mpl.ratio\n",
       "    fig.root.unbind('remove')\n",
       "\n",
       "    // Update the output cell to use the data from the current canvas.\n",
       "    fig.push_to_output();\n",
       "    var dataURL = fig.canvas.toDataURL();\n",
       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
       "    // the notebook keyboard shortcuts fail.\n",
       "    IPython.keyboard_manager.enable()\n",
       "    $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
       "    fig.close_ws(fig, msg);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.close_ws = function(fig, msg){\n",
       "    fig.send_message('closing', msg);\n",
       "    // fig.ws.close()\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
       "    // Turn the data on the canvas into data in the output cell.\n",
       "    var width = this.canvas.width/mpl.ratio\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Tell IPython that the notebook contents must change.\n",
       "    IPython.notebook.set_dirty(true);\n",
       "    this.send_message(\"ack\", {});\n",
       "    var fig = this;\n",
       "    // Wait a second, then push the new image to the DOM so\n",
       "    // that it is saved nicely (might be nice to debounce this).\n",
       "    setTimeout(function () { fig.push_to_output() }, 1000);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items){\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) { continue; };\n",
       "\n",
       "        var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    // Add the status bar.\n",
       "    var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "\n",
       "    // Add the close button to the window.\n",
       "    var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
       "    var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
       "    button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
       "    button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
       "    buttongrp.append(button);\n",
       "    var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
       "    titlebar.prepend(buttongrp);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(el){\n",
       "    var fig = this\n",
       "    el.on(\"remove\", function(){\n",
       "\tfig.close_ws(fig, {});\n",
       "    });\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(el){\n",
       "    // this is important to make the div 'focusable\n",
       "    el.attr('tabindex', 0)\n",
       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
       "    // off when our div gets focus\n",
       "\n",
       "    // location in version 3\n",
       "    if (IPython.notebook.keyboard_manager) {\n",
       "        IPython.notebook.keyboard_manager.register_events(el);\n",
       "    }\n",
       "    else {\n",
       "        // location in version 2\n",
       "        IPython.keyboard_manager.register_events(el);\n",
       "    }\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager)\n",
       "        manager = IPython.keyboard_manager;\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which == 13) {\n",
       "        this.canvas_div.blur();\n",
       "        event.shiftKey = false;\n",
       "        // Send a \"J\" for go to next cell\n",
       "        event.which = 74;\n",
       "        event.keyCode = 74;\n",
       "        manager.command_mode();\n",
       "        manager.handle_keydown(event);\n",
       "    }\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.find_output_cell = function(html_output) {\n",
       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
       "    // IPython event is triggered only after the cells have been serialised, which for\n",
       "    // our purposes (turning an active figure into a static one), is too late.\n",
       "    var cells = IPython.notebook.get_cells();\n",
       "    var ncells = cells.length;\n",
       "    for (var i=0; i<ncells; i++) {\n",
       "        var cell = cells[i];\n",
       "        if (cell.cell_type === 'code'){\n",
       "            for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
       "                var data = cell.output_area.outputs[j];\n",
       "                if (data.data) {\n",
       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
       "                    data = data.data;\n",
       "                }\n",
       "                if (data['text/html'] == html_output) {\n",
       "                    return [cell, data, j];\n",
       "                }\n",
       "            }\n",
       "        }\n",
       "    }\n",
       "}\n",
       "\n",
       "// Register the function which deals with the matplotlib target/channel.\n",
       "// The kernel may be null if the page has been refreshed.\n",
       "if (IPython.notebook.kernel != null) {\n",
       "    IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
       "}\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,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dv/992u9a8nr9Z61KZw4cYIGDRrw0UcfBV7LycnhzjvvjMTmxZ1Q632qoUOHauj5mWqy3t/r0qWLzh7HMA09tVDTh5iOHTuWzMxMfD4fe/fupWPHjsyfPz+SmxzTarLeS5cupXXr1kGvDRkyhC5dukRkW+NNqKawadMm6tevT2VlZeC1BQsW0K5du0hsXtzR0BNZNR16Dh48SMOGDdm4cWMdbpXUJQ09tVDTh5hu2LCBjh07Ur9+fRISEhgyZEhQk5Czq8l6HzlyhNTUVKZPn47f7+edd94hOTmZtm3bRnqz40KoprB27VpSUlKCXisuLiYtLa2uNy0uaeiJrJqst8/no3fv3gwZMqSOt0rqkoaeWqjJQ0yPHj2Ky+UKNOHDhw+TkZHBww8/HOnNjlk1fWjse++9R3p6Oqmpqfz617/mT3/6EzfccEMkNzluhHum59T/DwsXLtSZnlrS0BNZ4a53eXk5d9xxB/369aO8vDwCWyZ1RUNPLYX7ENONGzfSsGHDoNeKiopo1apVXW9iXPk5D4295557eOyxx+pq0+JauNf0bNmyJfBabm6urumpJQ09kRXOepeXl9O/f3/69u2Lz+eL0JZJXdHQU0vhPsT0+PHjNG7cmMLCQioqKjh69CgDBgygf//+BrY6dtXkobGbNm3C5/NRWlpKYWEhzZs3Z//+/RHe4th28uRJysrKyM3NZcCAAZSVlZ3xX7j33XcfGRkZHD9+nK1bt5KWlqZvb9VQTdbb7/dTVlbGvffey6hRoygrK9MtMGoo3PX2+/1kZGRw8803n/bSBYk9Gnpq6WwPMb3tttsYP3584GfXrFlDt27dSElJoWnTptx1111qwjVUk/UeOnQoLpeLxMREbr31VrZt22Zqs2OW1+slISEhKDfddBPw0/UuKSnhnnvuISkpibS0NN2npxZqst5Dhw79yc/q24k1E+56r169moSEBBo2bEhiYmIgp/7/kNiioUdERESsoKFHRERErKChR0RERKygoUdERESsoKFHRERErKChR0RERKygoUdERESsoKFHRERErKChR0RERKygoUdERESsoKFHRERErKChR0RERKygoUdERESsoKFHRERErKChR0RERKygoUdERESsoKFHRERErKChR0RERKygoUdERESsoKFHRERErKChR0RERKygoUdERESsoKFHRERErKChR0RERKygoUdERESsoKFHRERErKChR0RERKygoUdERESsoKFHRERErPD/AYvAAN8qNDgKAAAAAElFTkSuQmCC\" width=\"573\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#Validation of the error propagation without pixel splitting but with normalization:\n",
    "f,a = plot_distribution(ai, kwarg, integrate = ai._integrate1d_ng)\n",
    "f.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Azimuthal integration with pixel splitting\n",
    "\n",
    "Pixels splitting is implemented in pyFAI in calculating the fraction of area every pixel spends in any bin. This is noted $c^{pix}_{bin}$. The calculation of those coeficient is done with some simple geometry but it is rather tedious, this is why two implementation exists: a simple one which assues pixels boundary are paralle to the radial and azimuthal axes called ```BBox``` for bounding box and a more precise one calculating the intersection of polygons (called ```splitpixel```. The calculation of those coefficient is what lasts during the initialization of the integrator as this piece of code is not (yet) parallelized. The total number of (complete) pixel in a bin is then simply the sum of all those coeficients: $\\sum_{pix \\in bin} c^{pix}_{bin}$.\n",
    "\n",
    "The azimuthal integration used to be implemented as (pyFAI <=0.15):\n",
    "\n",
    "$$\n",
    "I_{bin} = \\frac{ \\sum_{pix \\in bin} c^{pix}_{bin} \\frac{I_{pix}}{\\Omega_{pix} P_{pix}}}{\\sum_{pix \\in bin}c^{pix}_{bin}}\n",
    "$$\n",
    "\n",
    "With the associated error propagation (this is what is implemented in pyFAI, there is an error in it!):\n",
    "\n",
    "$$\n",
    "\\sigma_{bin} = \\frac{\\sqrt{\\sum_{pix \\in bin} c^{pix}_{bin} \\sigma^2_{pix}}}{\\sum_{pix \\in bin}c^{pix}_{bin}}\n",
    "$$\n",
    "\n",
    "We have now tools to validate the error propagation for every single rebinning engine. Let's see if pixel splitting induces some error, with coarse or fine pixel splitting:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "/* Put everything inside the global mpl namespace */\n",
       "window.mpl = {};\n",
       "\n",
       "\n",
       "mpl.get_websocket_type = function() {\n",
       "    if (typeof(WebSocket) !== 'undefined') {\n",
       "        return WebSocket;\n",
       "    } else if (typeof(MozWebSocket) !== 'undefined') {\n",
       "        return MozWebSocket;\n",
       "    } else {\n",
       "        alert('Your browser does not have WebSocket support.' +\n",
       "              'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
       "              'Firefox 4 and 5 are also supported but you ' +\n",
       "              'have to enable WebSockets in about:config.');\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
       "    this.id = figure_id;\n",
       "\n",
       "    this.ws = websocket;\n",
       "\n",
       "    this.supports_binary = (this.ws.binaryType != undefined);\n",
       "\n",
       "    if (!this.supports_binary) {\n",
       "        var warnings = document.getElementById(\"mpl-warnings\");\n",
       "        if (warnings) {\n",
       "            warnings.style.display = 'block';\n",
       "            warnings.textContent = (\n",
       "                \"This browser does not support binary websocket messages. \" +\n",
       "                    \"Performance may be slow.\");\n",
       "        }\n",
       "    }\n",
       "\n",
       "    this.imageObj = new Image();\n",
       "\n",
       "    this.context = undefined;\n",
       "    this.message = undefined;\n",
       "    this.canvas = undefined;\n",
       "    this.rubberband_canvas = undefined;\n",
       "    this.rubberband_context = undefined;\n",
       "    this.format_dropdown = undefined;\n",
       "\n",
       "    this.image_mode = 'full';\n",
       "\n",
       "    this.root = $('<div/>');\n",
       "    this._root_extra_style(this.root)\n",
       "    this.root.attr('style', 'display: inline-block');\n",
       "\n",
       "    $(parent_element).append(this.root);\n",
       "\n",
       "    this._init_header(this);\n",
       "    this._init_canvas(this);\n",
       "    this._init_toolbar(this);\n",
       "\n",
       "    var fig = this;\n",
       "\n",
       "    this.waiting = false;\n",
       "\n",
       "    this.ws.onopen =  function () {\n",
       "            fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
       "            fig.send_message(\"send_image_mode\", {});\n",
       "            if (mpl.ratio != 1) {\n",
       "                fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
       "            }\n",
       "            fig.send_message(\"refresh\", {});\n",
       "        }\n",
       "\n",
       "    this.imageObj.onload = function() {\n",
       "            if (fig.image_mode == 'full') {\n",
       "                // Full images could contain transparency (where diff images\n",
       "                // almost always do), so we need to clear the canvas so that\n",
       "                // there is no ghosting.\n",
       "                fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
       "            }\n",
       "            fig.context.drawImage(fig.imageObj, 0, 0);\n",
       "        };\n",
       "\n",
       "    this.imageObj.onunload = function() {\n",
       "        fig.ws.close();\n",
       "    }\n",
       "\n",
       "    this.ws.onmessage = this._make_on_message_function(this);\n",
       "\n",
       "    this.ondownload = ondownload;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_header = function() {\n",
       "    var titlebar = $(\n",
       "        '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
       "        'ui-helper-clearfix\"/>');\n",
       "    var titletext = $(\n",
       "        '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
       "        'text-align: center; padding: 3px;\"/>');\n",
       "    titlebar.append(titletext)\n",
       "    this.root.append(titlebar);\n",
       "    this.header = titletext[0];\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_canvas = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var canvas_div = $('<div/>');\n",
       "\n",
       "    canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
       "\n",
       "    function canvas_keyboard_event(event) {\n",
       "        return fig.key_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    canvas_div.keydown('key_press', canvas_keyboard_event);\n",
       "    canvas_div.keyup('key_release', canvas_keyboard_event);\n",
       "    this.canvas_div = canvas_div\n",
       "    this._canvas_extra_style(canvas_div)\n",
       "    this.root.append(canvas_div);\n",
       "\n",
       "    var canvas = $('<canvas/>');\n",
       "    canvas.addClass('mpl-canvas');\n",
       "    canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
       "\n",
       "    this.canvas = canvas[0];\n",
       "    this.context = canvas[0].getContext(\"2d\");\n",
       "\n",
       "    var backingStore = this.context.backingStorePixelRatio ||\n",
       "\tthis.context.webkitBackingStorePixelRatio ||\n",
       "\tthis.context.mozBackingStorePixelRatio ||\n",
       "\tthis.context.msBackingStorePixelRatio ||\n",
       "\tthis.context.oBackingStorePixelRatio ||\n",
       "\tthis.context.backingStorePixelRatio || 1;\n",
       "\n",
       "    mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
       "\n",
       "    var rubberband = $('<canvas/>');\n",
       "    rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
       "\n",
       "    var pass_mouse_events = true;\n",
       "\n",
       "    canvas_div.resizable({\n",
       "        start: function(event, ui) {\n",
       "            pass_mouse_events = false;\n",
       "        },\n",
       "        resize: function(event, ui) {\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "        stop: function(event, ui) {\n",
       "            pass_mouse_events = true;\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "    });\n",
       "\n",
       "    function mouse_event_fn(event) {\n",
       "        if (pass_mouse_events)\n",
       "            return fig.mouse_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    rubberband.mousedown('button_press', mouse_event_fn);\n",
       "    rubberband.mouseup('button_release', mouse_event_fn);\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband.mousemove('motion_notify', mouse_event_fn);\n",
       "\n",
       "    rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
       "    rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
       "\n",
       "    canvas_div.on(\"wheel\", function (event) {\n",
       "        event = event.originalEvent;\n",
       "        event['data'] = 'scroll'\n",
       "        if (event.deltaY < 0) {\n",
       "            event.step = 1;\n",
       "        } else {\n",
       "            event.step = -1;\n",
       "        }\n",
       "        mouse_event_fn(event);\n",
       "    });\n",
       "\n",
       "    canvas_div.append(canvas);\n",
       "    canvas_div.append(rubberband);\n",
       "\n",
       "    this.rubberband = rubberband;\n",
       "    this.rubberband_canvas = rubberband[0];\n",
       "    this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
       "    this.rubberband_context.strokeStyle = \"#000000\";\n",
       "\n",
       "    this._resize_canvas = function(width, height) {\n",
       "        // Keep the size of the canvas, canvas container, and rubber band\n",
       "        // canvas in synch.\n",
       "        canvas_div.css('width', width)\n",
       "        canvas_div.css('height', height)\n",
       "\n",
       "        canvas.attr('width', width * mpl.ratio);\n",
       "        canvas.attr('height', height * mpl.ratio);\n",
       "        canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
       "\n",
       "        rubberband.attr('width', width);\n",
       "        rubberband.attr('height', height);\n",
       "    }\n",
       "\n",
       "    // Set the figure to an initial 600x600px, this will subsequently be updated\n",
       "    // upon first draw.\n",
       "    this._resize_canvas(600, 600);\n",
       "\n",
       "    // Disable right mouse context menu.\n",
       "    $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
       "        return false;\n",
       "    });\n",
       "\n",
       "    function set_focus () {\n",
       "        canvas.focus();\n",
       "        canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    window.setTimeout(set_focus, 100);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items) {\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) {\n",
       "            // put a spacer in here.\n",
       "            continue;\n",
       "        }\n",
       "        var button = $('<button/>');\n",
       "        button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
       "                        'ui-button-icon-only');\n",
       "        button.attr('role', 'button');\n",
       "        button.attr('aria-disabled', 'false');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "\n",
       "        var icon_img = $('<span/>');\n",
       "        icon_img.addClass('ui-button-icon-primary ui-icon');\n",
       "        icon_img.addClass(image);\n",
       "        icon_img.addClass('ui-corner-all');\n",
       "\n",
       "        var tooltip_span = $('<span/>');\n",
       "        tooltip_span.addClass('ui-button-text');\n",
       "        tooltip_span.html(tooltip);\n",
       "\n",
       "        button.append(icon_img);\n",
       "        button.append(tooltip_span);\n",
       "\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    var fmt_picker_span = $('<span/>');\n",
       "\n",
       "    var fmt_picker = $('<select/>');\n",
       "    fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
       "    fmt_picker_span.append(fmt_picker);\n",
       "    nav_element.append(fmt_picker_span);\n",
       "    this.format_dropdown = fmt_picker[0];\n",
       "\n",
       "    for (var ind in mpl.extensions) {\n",
       "        var fmt = mpl.extensions[ind];\n",
       "        var option = $(\n",
       "            '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
       "        fmt_picker.append(option)\n",
       "    }\n",
       "\n",
       "    // Add hover states to the ui-buttons\n",
       "    $( \".ui-button\" ).hover(\n",
       "        function() { $(this).addClass(\"ui-state-hover\");},\n",
       "        function() { $(this).removeClass(\"ui-state-hover\");}\n",
       "    );\n",
       "\n",
       "    var status_bar = $('<span class=\"mpl-message\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
       "    // which will in turn request a refresh of the image.\n",
       "    this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_message = function(type, properties) {\n",
       "    properties['type'] = type;\n",
       "    properties['figure_id'] = this.id;\n",
       "    this.ws.send(JSON.stringify(properties));\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_draw_message = function() {\n",
       "    if (!this.waiting) {\n",
       "        this.waiting = true;\n",
       "        this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
       "    }\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    var format_dropdown = fig.format_dropdown;\n",
       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
       "    fig.ondownload(fig, format);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
       "    var size = msg['size'];\n",
       "    if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
       "        fig._resize_canvas(size[0], size[1]);\n",
       "        fig.send_message(\"refresh\", {});\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
       "    var x0 = msg['x0'] / mpl.ratio;\n",
       "    var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
       "    var x1 = msg['x1'] / mpl.ratio;\n",
       "    var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
       "    x0 = Math.floor(x0) + 0.5;\n",
       "    y0 = Math.floor(y0) + 0.5;\n",
       "    x1 = Math.floor(x1) + 0.5;\n",
       "    y1 = Math.floor(y1) + 0.5;\n",
       "    var min_x = Math.min(x0, x1);\n",
       "    var min_y = Math.min(y0, y1);\n",
       "    var width = Math.abs(x1 - x0);\n",
       "    var height = Math.abs(y1 - y0);\n",
       "\n",
       "    fig.rubberband_context.clearRect(\n",
       "        0, 0, fig.canvas.width, fig.canvas.height);\n",
       "\n",
       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
       "    // Updates the figure title.\n",
       "    fig.header.textContent = msg['label'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
       "    var cursor = msg['cursor'];\n",
       "    switch(cursor)\n",
       "    {\n",
       "    case 0:\n",
       "        cursor = 'pointer';\n",
       "        break;\n",
       "    case 1:\n",
       "        cursor = 'default';\n",
       "        break;\n",
       "    case 2:\n",
       "        cursor = 'crosshair';\n",
       "        break;\n",
       "    case 3:\n",
       "        cursor = 'move';\n",
       "        break;\n",
       "    }\n",
       "    fig.rubberband_canvas.style.cursor = cursor;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
       "    fig.message.textContent = msg['message'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
       "    // Request the server to send over a new figure.\n",
       "    fig.send_draw_message();\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
       "    fig.image_mode = msg['mode'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Called whenever the canvas gets updated.\n",
       "    this.send_message(\"ack\", {});\n",
       "}\n",
       "\n",
       "// A function to construct a web socket function for onmessage handling.\n",
       "// Called in the figure constructor.\n",
       "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
       "    return function socket_on_message(evt) {\n",
       "        if (evt.data instanceof Blob) {\n",
       "            /* FIXME: We get \"Resource interpreted as Image but\n",
       "             * transferred with MIME type text/plain:\" errors on\n",
       "             * Chrome.  But how to set the MIME type?  It doesn't seem\n",
       "             * to be part of the websocket stream */\n",
       "            evt.data.type = \"image/png\";\n",
       "\n",
       "            /* Free the memory for the previous frames */\n",
       "            if (fig.imageObj.src) {\n",
       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
       "                    fig.imageObj.src);\n",
       "            }\n",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data);\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "        else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
       "            fig.imageObj.src = evt.data;\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        var msg = JSON.parse(evt.data);\n",
       "        var msg_type = msg['type'];\n",
       "\n",
       "        // Call the  \"handle_{type}\" callback, which takes\n",
       "        // the figure and JSON message as its only arguments.\n",
       "        try {\n",
       "            var callback = fig[\"handle_\" + msg_type];\n",
       "        } catch (e) {\n",
       "            console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        if (callback) {\n",
       "            try {\n",
       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
       "                callback(fig, msg);\n",
       "            } catch (e) {\n",
       "                console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
       "            }\n",
       "        }\n",
       "    };\n",
       "}\n",
       "\n",
       "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
       "mpl.findpos = function(e) {\n",
       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
       "    var targ;\n",
       "    if (!e)\n",
       "        e = window.event;\n",
       "    if (e.target)\n",
       "        targ = e.target;\n",
       "    else if (e.srcElement)\n",
       "        targ = e.srcElement;\n",
       "    if (targ.nodeType == 3) // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "\n",
       "    // jQuery normalizes the pageX and pageY\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    // offset() returns the position of the element relative to the document\n",
       "    var x = e.pageX - $(targ).offset().left;\n",
       "    var y = e.pageY - $(targ).offset().top;\n",
       "\n",
       "    return {\"x\": x, \"y\": y};\n",
       "};\n",
       "\n",
       "/*\n",
       " * return a copy of an object with only non-object keys\n",
       " * we need this to avoid circular references\n",
       " * http://stackoverflow.com/a/24161582/3208463\n",
       " */\n",
       "function simpleKeys (original) {\n",
       "  return Object.keys(original).reduce(function (obj, key) {\n",
       "    if (typeof original[key] !== 'object')\n",
       "        obj[key] = original[key]\n",
       "    return obj;\n",
       "  }, {});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.mouse_event = function(event, name) {\n",
       "    var canvas_pos = mpl.findpos(event)\n",
       "\n",
       "    if (name === 'button_press')\n",
       "    {\n",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * mpl.ratio;\n",
       "    var y = canvas_pos.y * mpl.ratio;\n",
       "\n",
       "    this.send_message(name, {x: x, y: y, button: event.button,\n",
       "                             step: event.step,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "\n",
       "    /* This prevents the web browser from automatically changing to\n",
       "     * the text insertion cursor when the button is pressed.  We want\n",
       "     * to control all of the cursor setting manually through the\n",
       "     * 'cursor' event from matplotlib */\n",
       "    event.preventDefault();\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    // Handle any extra behaviour associated with a key event\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.key_event = function(event, name) {\n",
       "\n",
       "    // Prevent repeat events\n",
       "    if (name == 'key_press')\n",
       "    {\n",
       "        if (event.which === this._key)\n",
       "            return;\n",
       "        else\n",
       "            this._key = event.which;\n",
       "    }\n",
       "    if (name == 'key_release')\n",
       "        this._key = null;\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which != 17)\n",
       "        value += \"ctrl+\";\n",
       "    if (event.altKey && event.which != 18)\n",
       "        value += \"alt+\";\n",
       "    if (event.shiftKey && event.which != 16)\n",
       "        value += \"shift+\";\n",
       "\n",
       "    value += 'k';\n",
       "    value += event.which.toString();\n",
       "\n",
       "    this._key_event_extra(event, name);\n",
       "\n",
       "    this.send_message(name, {key: value,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
       "    if (name == 'download') {\n",
       "        this.handle_save(this, null);\n",
       "    } else {\n",
       "        this.send_message(\"toolbar_button\", {name: name});\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
       "    this.message.textContent = tooltip;\n",
       "};\n",
       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
       "\n",
       "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
       "\n",
       "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
       "    // object with the appropriate methods. Currently this is a non binary\n",
       "    // socket, so there is still some room for performance tuning.\n",
       "    var ws = {};\n",
       "\n",
       "    ws.close = function() {\n",
       "        comm.close()\n",
       "    };\n",
       "    ws.send = function(m) {\n",
       "        //console.log('sending', m);\n",
       "        comm.send(m);\n",
       "    };\n",
       "    // Register the callback with on_msg.\n",
       "    comm.on_msg(function(msg) {\n",
       "        //console.log('receiving', msg['content']['data'], msg);\n",
       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
       "        ws.onmessage(msg['content']['data'])\n",
       "    });\n",
       "    return ws;\n",
       "}\n",
       "\n",
       "mpl.mpl_figure_comm = function(comm, msg) {\n",
       "    // This is the function which gets called when the mpl process\n",
       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
       "\n",
       "    var id = msg.content.data.id;\n",
       "    // Get hold of the div created by the display call when the Comm\n",
       "    // socket was opened in Python.\n",
       "    var element = $(\"#\" + id);\n",
       "    var ws_proxy = comm_websocket_adapter(comm)\n",
       "\n",
       "    function ondownload(figure, format) {\n",
       "        window.open(figure.imageObj.src);\n",
       "    }\n",
       "\n",
       "    var fig = new mpl.figure(id, ws_proxy,\n",
       "                           ondownload,\n",
       "                           element.get(0));\n",
       "\n",
       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
       "    // web socket which is closed, not our websocket->open comm proxy.\n",
       "    ws_proxy.onopen();\n",
       "\n",
       "    fig.parent_element = element.get(0);\n",
       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
       "    if (!fig.cell_info) {\n",
       "        console.error(\"Failed to find cell for figure\", id, fig);\n",
       "        return;\n",
       "    }\n",
       "\n",
       "    var output_index = fig.cell_info[2]\n",
       "    var cell = fig.cell_info[0];\n",
       "\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
       "    var width = fig.canvas.width/mpl.ratio\n",
       "    fig.root.unbind('remove')\n",
       "\n",
       "    // Update the output cell to use the data from the current canvas.\n",
       "    fig.push_to_output();\n",
       "    var dataURL = fig.canvas.toDataURL();\n",
       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
       "    // the notebook keyboard shortcuts fail.\n",
       "    IPython.keyboard_manager.enable()\n",
       "    $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
       "    fig.close_ws(fig, msg);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.close_ws = function(fig, msg){\n",
       "    fig.send_message('closing', msg);\n",
       "    // fig.ws.close()\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
       "    // Turn the data on the canvas into data in the output cell.\n",
       "    var width = this.canvas.width/mpl.ratio\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Tell IPython that the notebook contents must change.\n",
       "    IPython.notebook.set_dirty(true);\n",
       "    this.send_message(\"ack\", {});\n",
       "    var fig = this;\n",
       "    // Wait a second, then push the new image to the DOM so\n",
       "    // that it is saved nicely (might be nice to debounce this).\n",
       "    setTimeout(function () { fig.push_to_output() }, 1000);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items){\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) { continue; };\n",
       "\n",
       "        var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    // Add the status bar.\n",
       "    var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "\n",
       "    // Add the close button to the window.\n",
       "    var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
       "    var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
       "    button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
       "    button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
       "    buttongrp.append(button);\n",
       "    var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
       "    titlebar.prepend(buttongrp);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(el){\n",
       "    var fig = this\n",
       "    el.on(\"remove\", function(){\n",
       "\tfig.close_ws(fig, {});\n",
       "    });\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(el){\n",
       "    // this is important to make the div 'focusable\n",
       "    el.attr('tabindex', 0)\n",
       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
       "    // off when our div gets focus\n",
       "\n",
       "    // location in version 3\n",
       "    if (IPython.notebook.keyboard_manager) {\n",
       "        IPython.notebook.keyboard_manager.register_events(el);\n",
       "    }\n",
       "    else {\n",
       "        // location in version 2\n",
       "        IPython.keyboard_manager.register_events(el);\n",
       "    }\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager)\n",
       "        manager = IPython.keyboard_manager;\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which == 13) {\n",
       "        this.canvas_div.blur();\n",
       "        event.shiftKey = false;\n",
       "        // Send a \"J\" for go to next cell\n",
       "        event.which = 74;\n",
       "        event.keyCode = 74;\n",
       "        manager.command_mode();\n",
       "        manager.handle_keydown(event);\n",
       "    }\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.find_output_cell = function(html_output) {\n",
       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
       "    // IPython event is triggered only after the cells have been serialised, which for\n",
       "    // our purposes (turning an active figure into a static one), is too late.\n",
       "    var cells = IPython.notebook.get_cells();\n",
       "    var ncells = cells.length;\n",
       "    for (var i=0; i<ncells; i++) {\n",
       "        var cell = cells[i];\n",
       "        if (cell.cell_type === 'code'){\n",
       "            for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
       "                var data = cell.output_area.outputs[j];\n",
       "                if (data.data) {\n",
       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
       "                    data = data.data;\n",
       "                }\n",
       "                if (data['text/html'] == html_output) {\n",
       "                    return [cell, data, j];\n",
       "                }\n",
       "            }\n",
       "        }\n",
       "    }\n",
       "}\n",
       "\n",
       "// Register the function which deals with the matplotlib target/channel.\n",
       "// The kernel may be null if the page has been refreshed.\n",
       "if (IPython.notebook.kernel != null) {\n",
       "    IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
       "}\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,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\" width=\"573\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#With coarse pixel-splitting, new integrator:\n",
    "kwarg[\"method\"] = \"csr\"\n",
    "f,a = plot_distribution(ai, kwarg, integrate = ai._integrate1d_ng)\n",
    "f.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "/* Put everything inside the global mpl namespace */\n",
       "window.mpl = {};\n",
       "\n",
       "\n",
       "mpl.get_websocket_type = function() {\n",
       "    if (typeof(WebSocket) !== 'undefined') {\n",
       "        return WebSocket;\n",
       "    } else if (typeof(MozWebSocket) !== 'undefined') {\n",
       "        return MozWebSocket;\n",
       "    } else {\n",
       "        alert('Your browser does not have WebSocket support.' +\n",
       "              'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
       "              'Firefox 4 and 5 are also supported but you ' +\n",
       "              'have to enable WebSockets in about:config.');\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
       "    this.id = figure_id;\n",
       "\n",
       "    this.ws = websocket;\n",
       "\n",
       "    this.supports_binary = (this.ws.binaryType != undefined);\n",
       "\n",
       "    if (!this.supports_binary) {\n",
       "        var warnings = document.getElementById(\"mpl-warnings\");\n",
       "        if (warnings) {\n",
       "            warnings.style.display = 'block';\n",
       "            warnings.textContent = (\n",
       "                \"This browser does not support binary websocket messages. \" +\n",
       "                    \"Performance may be slow.\");\n",
       "        }\n",
       "    }\n",
       "\n",
       "    this.imageObj = new Image();\n",
       "\n",
       "    this.context = undefined;\n",
       "    this.message = undefined;\n",
       "    this.canvas = undefined;\n",
       "    this.rubberband_canvas = undefined;\n",
       "    this.rubberband_context = undefined;\n",
       "    this.format_dropdown = undefined;\n",
       "\n",
       "    this.image_mode = 'full';\n",
       "\n",
       "    this.root = $('<div/>');\n",
       "    this._root_extra_style(this.root)\n",
       "    this.root.attr('style', 'display: inline-block');\n",
       "\n",
       "    $(parent_element).append(this.root);\n",
       "\n",
       "    this._init_header(this);\n",
       "    this._init_canvas(this);\n",
       "    this._init_toolbar(this);\n",
       "\n",
       "    var fig = this;\n",
       "\n",
       "    this.waiting = false;\n",
       "\n",
       "    this.ws.onopen =  function () {\n",
       "            fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
       "            fig.send_message(\"send_image_mode\", {});\n",
       "            if (mpl.ratio != 1) {\n",
       "                fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
       "            }\n",
       "            fig.send_message(\"refresh\", {});\n",
       "        }\n",
       "\n",
       "    this.imageObj.onload = function() {\n",
       "            if (fig.image_mode == 'full') {\n",
       "                // Full images could contain transparency (where diff images\n",
       "                // almost always do), so we need to clear the canvas so that\n",
       "                // there is no ghosting.\n",
       "                fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
       "            }\n",
       "            fig.context.drawImage(fig.imageObj, 0, 0);\n",
       "        };\n",
       "\n",
       "    this.imageObj.onunload = function() {\n",
       "        fig.ws.close();\n",
       "    }\n",
       "\n",
       "    this.ws.onmessage = this._make_on_message_function(this);\n",
       "\n",
       "    this.ondownload = ondownload;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_header = function() {\n",
       "    var titlebar = $(\n",
       "        '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
       "        'ui-helper-clearfix\"/>');\n",
       "    var titletext = $(\n",
       "        '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
       "        'text-align: center; padding: 3px;\"/>');\n",
       "    titlebar.append(titletext)\n",
       "    this.root.append(titlebar);\n",
       "    this.header = titletext[0];\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_canvas = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var canvas_div = $('<div/>');\n",
       "\n",
       "    canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
       "\n",
       "    function canvas_keyboard_event(event) {\n",
       "        return fig.key_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    canvas_div.keydown('key_press', canvas_keyboard_event);\n",
       "    canvas_div.keyup('key_release', canvas_keyboard_event);\n",
       "    this.canvas_div = canvas_div\n",
       "    this._canvas_extra_style(canvas_div)\n",
       "    this.root.append(canvas_div);\n",
       "\n",
       "    var canvas = $('<canvas/>');\n",
       "    canvas.addClass('mpl-canvas');\n",
       "    canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
       "\n",
       "    this.canvas = canvas[0];\n",
       "    this.context = canvas[0].getContext(\"2d\");\n",
       "\n",
       "    var backingStore = this.context.backingStorePixelRatio ||\n",
       "\tthis.context.webkitBackingStorePixelRatio ||\n",
       "\tthis.context.mozBackingStorePixelRatio ||\n",
       "\tthis.context.msBackingStorePixelRatio ||\n",
       "\tthis.context.oBackingStorePixelRatio ||\n",
       "\tthis.context.backingStorePixelRatio || 1;\n",
       "\n",
       "    mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
       "\n",
       "    var rubberband = $('<canvas/>');\n",
       "    rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
       "\n",
       "    var pass_mouse_events = true;\n",
       "\n",
       "    canvas_div.resizable({\n",
       "        start: function(event, ui) {\n",
       "            pass_mouse_events = false;\n",
       "        },\n",
       "        resize: function(event, ui) {\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "        stop: function(event, ui) {\n",
       "            pass_mouse_events = true;\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "    });\n",
       "\n",
       "    function mouse_event_fn(event) {\n",
       "        if (pass_mouse_events)\n",
       "            return fig.mouse_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    rubberband.mousedown('button_press', mouse_event_fn);\n",
       "    rubberband.mouseup('button_release', mouse_event_fn);\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband.mousemove('motion_notify', mouse_event_fn);\n",
       "\n",
       "    rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
       "    rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
       "\n",
       "    canvas_div.on(\"wheel\", function (event) {\n",
       "        event = event.originalEvent;\n",
       "        event['data'] = 'scroll'\n",
       "        if (event.deltaY < 0) {\n",
       "            event.step = 1;\n",
       "        } else {\n",
       "            event.step = -1;\n",
       "        }\n",
       "        mouse_event_fn(event);\n",
       "    });\n",
       "\n",
       "    canvas_div.append(canvas);\n",
       "    canvas_div.append(rubberband);\n",
       "\n",
       "    this.rubberband = rubberband;\n",
       "    this.rubberband_canvas = rubberband[0];\n",
       "    this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
       "    this.rubberband_context.strokeStyle = \"#000000\";\n",
       "\n",
       "    this._resize_canvas = function(width, height) {\n",
       "        // Keep the size of the canvas, canvas container, and rubber band\n",
       "        // canvas in synch.\n",
       "        canvas_div.css('width', width)\n",
       "        canvas_div.css('height', height)\n",
       "\n",
       "        canvas.attr('width', width * mpl.ratio);\n",
       "        canvas.attr('height', height * mpl.ratio);\n",
       "        canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
       "\n",
       "        rubberband.attr('width', width);\n",
       "        rubberband.attr('height', height);\n",
       "    }\n",
       "\n",
       "    // Set the figure to an initial 600x600px, this will subsequently be updated\n",
       "    // upon first draw.\n",
       "    this._resize_canvas(600, 600);\n",
       "\n",
       "    // Disable right mouse context menu.\n",
       "    $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
       "        return false;\n",
       "    });\n",
       "\n",
       "    function set_focus () {\n",
       "        canvas.focus();\n",
       "        canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    window.setTimeout(set_focus, 100);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items) {\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) {\n",
       "            // put a spacer in here.\n",
       "            continue;\n",
       "        }\n",
       "        var button = $('<button/>');\n",
       "        button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
       "                        'ui-button-icon-only');\n",
       "        button.attr('role', 'button');\n",
       "        button.attr('aria-disabled', 'false');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "\n",
       "        var icon_img = $('<span/>');\n",
       "        icon_img.addClass('ui-button-icon-primary ui-icon');\n",
       "        icon_img.addClass(image);\n",
       "        icon_img.addClass('ui-corner-all');\n",
       "\n",
       "        var tooltip_span = $('<span/>');\n",
       "        tooltip_span.addClass('ui-button-text');\n",
       "        tooltip_span.html(tooltip);\n",
       "\n",
       "        button.append(icon_img);\n",
       "        button.append(tooltip_span);\n",
       "\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    var fmt_picker_span = $('<span/>');\n",
       "\n",
       "    var fmt_picker = $('<select/>');\n",
       "    fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
       "    fmt_picker_span.append(fmt_picker);\n",
       "    nav_element.append(fmt_picker_span);\n",
       "    this.format_dropdown = fmt_picker[0];\n",
       "\n",
       "    for (var ind in mpl.extensions) {\n",
       "        var fmt = mpl.extensions[ind];\n",
       "        var option = $(\n",
       "            '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
       "        fmt_picker.append(option)\n",
       "    }\n",
       "\n",
       "    // Add hover states to the ui-buttons\n",
       "    $( \".ui-button\" ).hover(\n",
       "        function() { $(this).addClass(\"ui-state-hover\");},\n",
       "        function() { $(this).removeClass(\"ui-state-hover\");}\n",
       "    );\n",
       "\n",
       "    var status_bar = $('<span class=\"mpl-message\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
       "    // which will in turn request a refresh of the image.\n",
       "    this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_message = function(type, properties) {\n",
       "    properties['type'] = type;\n",
       "    properties['figure_id'] = this.id;\n",
       "    this.ws.send(JSON.stringify(properties));\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_draw_message = function() {\n",
       "    if (!this.waiting) {\n",
       "        this.waiting = true;\n",
       "        this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
       "    }\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    var format_dropdown = fig.format_dropdown;\n",
       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
       "    fig.ondownload(fig, format);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
       "    var size = msg['size'];\n",
       "    if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
       "        fig._resize_canvas(size[0], size[1]);\n",
       "        fig.send_message(\"refresh\", {});\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
       "    var x0 = msg['x0'] / mpl.ratio;\n",
       "    var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
       "    var x1 = msg['x1'] / mpl.ratio;\n",
       "    var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
       "    x0 = Math.floor(x0) + 0.5;\n",
       "    y0 = Math.floor(y0) + 0.5;\n",
       "    x1 = Math.floor(x1) + 0.5;\n",
       "    y1 = Math.floor(y1) + 0.5;\n",
       "    var min_x = Math.min(x0, x1);\n",
       "    var min_y = Math.min(y0, y1);\n",
       "    var width = Math.abs(x1 - x0);\n",
       "    var height = Math.abs(y1 - y0);\n",
       "\n",
       "    fig.rubberband_context.clearRect(\n",
       "        0, 0, fig.canvas.width, fig.canvas.height);\n",
       "\n",
       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
       "    // Updates the figure title.\n",
       "    fig.header.textContent = msg['label'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
       "    var cursor = msg['cursor'];\n",
       "    switch(cursor)\n",
       "    {\n",
       "    case 0:\n",
       "        cursor = 'pointer';\n",
       "        break;\n",
       "    case 1:\n",
       "        cursor = 'default';\n",
       "        break;\n",
       "    case 2:\n",
       "        cursor = 'crosshair';\n",
       "        break;\n",
       "    case 3:\n",
       "        cursor = 'move';\n",
       "        break;\n",
       "    }\n",
       "    fig.rubberband_canvas.style.cursor = cursor;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
       "    fig.message.textContent = msg['message'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
       "    // Request the server to send over a new figure.\n",
       "    fig.send_draw_message();\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
       "    fig.image_mode = msg['mode'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Called whenever the canvas gets updated.\n",
       "    this.send_message(\"ack\", {});\n",
       "}\n",
       "\n",
       "// A function to construct a web socket function for onmessage handling.\n",
       "// Called in the figure constructor.\n",
       "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
       "    return function socket_on_message(evt) {\n",
       "        if (evt.data instanceof Blob) {\n",
       "            /* FIXME: We get \"Resource interpreted as Image but\n",
       "             * transferred with MIME type text/plain:\" errors on\n",
       "             * Chrome.  But how to set the MIME type?  It doesn't seem\n",
       "             * to be part of the websocket stream */\n",
       "            evt.data.type = \"image/png\";\n",
       "\n",
       "            /* Free the memory for the previous frames */\n",
       "            if (fig.imageObj.src) {\n",
       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
       "                    fig.imageObj.src);\n",
       "            }\n",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data);\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "        else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
       "            fig.imageObj.src = evt.data;\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        var msg = JSON.parse(evt.data);\n",
       "        var msg_type = msg['type'];\n",
       "\n",
       "        // Call the  \"handle_{type}\" callback, which takes\n",
       "        // the figure and JSON message as its only arguments.\n",
       "        try {\n",
       "            var callback = fig[\"handle_\" + msg_type];\n",
       "        } catch (e) {\n",
       "            console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        if (callback) {\n",
       "            try {\n",
       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
       "                callback(fig, msg);\n",
       "            } catch (e) {\n",
       "                console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
       "            }\n",
       "        }\n",
       "    };\n",
       "}\n",
       "\n",
       "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
       "mpl.findpos = function(e) {\n",
       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
       "    var targ;\n",
       "    if (!e)\n",
       "        e = window.event;\n",
       "    if (e.target)\n",
       "        targ = e.target;\n",
       "    else if (e.srcElement)\n",
       "        targ = e.srcElement;\n",
       "    if (targ.nodeType == 3) // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "\n",
       "    // jQuery normalizes the pageX and pageY\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    // offset() returns the position of the element relative to the document\n",
       "    var x = e.pageX - $(targ).offset().left;\n",
       "    var y = e.pageY - $(targ).offset().top;\n",
       "\n",
       "    return {\"x\": x, \"y\": y};\n",
       "};\n",
       "\n",
       "/*\n",
       " * return a copy of an object with only non-object keys\n",
       " * we need this to avoid circular references\n",
       " * http://stackoverflow.com/a/24161582/3208463\n",
       " */\n",
       "function simpleKeys (original) {\n",
       "  return Object.keys(original).reduce(function (obj, key) {\n",
       "    if (typeof original[key] !== 'object')\n",
       "        obj[key] = original[key]\n",
       "    return obj;\n",
       "  }, {});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.mouse_event = function(event, name) {\n",
       "    var canvas_pos = mpl.findpos(event)\n",
       "\n",
       "    if (name === 'button_press')\n",
       "    {\n",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * mpl.ratio;\n",
       "    var y = canvas_pos.y * mpl.ratio;\n",
       "\n",
       "    this.send_message(name, {x: x, y: y, button: event.button,\n",
       "                             step: event.step,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "\n",
       "    /* This prevents the web browser from automatically changing to\n",
       "     * the text insertion cursor when the button is pressed.  We want\n",
       "     * to control all of the cursor setting manually through the\n",
       "     * 'cursor' event from matplotlib */\n",
       "    event.preventDefault();\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    // Handle any extra behaviour associated with a key event\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.key_event = function(event, name) {\n",
       "\n",
       "    // Prevent repeat events\n",
       "    if (name == 'key_press')\n",
       "    {\n",
       "        if (event.which === this._key)\n",
       "            return;\n",
       "        else\n",
       "            this._key = event.which;\n",
       "    }\n",
       "    if (name == 'key_release')\n",
       "        this._key = null;\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which != 17)\n",
       "        value += \"ctrl+\";\n",
       "    if (event.altKey && event.which != 18)\n",
       "        value += \"alt+\";\n",
       "    if (event.shiftKey && event.which != 16)\n",
       "        value += \"shift+\";\n",
       "\n",
       "    value += 'k';\n",
       "    value += event.which.toString();\n",
       "\n",
       "    this._key_event_extra(event, name);\n",
       "\n",
       "    this.send_message(name, {key: value,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
       "    if (name == 'download') {\n",
       "        this.handle_save(this, null);\n",
       "    } else {\n",
       "        this.send_message(\"toolbar_button\", {name: name});\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
       "    this.message.textContent = tooltip;\n",
       "};\n",
       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
       "\n",
       "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
       "\n",
       "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
       "    // object with the appropriate methods. Currently this is a non binary\n",
       "    // socket, so there is still some room for performance tuning.\n",
       "    var ws = {};\n",
       "\n",
       "    ws.close = function() {\n",
       "        comm.close()\n",
       "    };\n",
       "    ws.send = function(m) {\n",
       "        //console.log('sending', m);\n",
       "        comm.send(m);\n",
       "    };\n",
       "    // Register the callback with on_msg.\n",
       "    comm.on_msg(function(msg) {\n",
       "        //console.log('receiving', msg['content']['data'], msg);\n",
       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
       "        ws.onmessage(msg['content']['data'])\n",
       "    });\n",
       "    return ws;\n",
       "}\n",
       "\n",
       "mpl.mpl_figure_comm = function(comm, msg) {\n",
       "    // This is the function which gets called when the mpl process\n",
       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
       "\n",
       "    var id = msg.content.data.id;\n",
       "    // Get hold of the div created by the display call when the Comm\n",
       "    // socket was opened in Python.\n",
       "    var element = $(\"#\" + id);\n",
       "    var ws_proxy = comm_websocket_adapter(comm)\n",
       "\n",
       "    function ondownload(figure, format) {\n",
       "        window.open(figure.imageObj.src);\n",
       "    }\n",
       "\n",
       "    var fig = new mpl.figure(id, ws_proxy,\n",
       "                           ondownload,\n",
       "                           element.get(0));\n",
       "\n",
       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
       "    // web socket which is closed, not our websocket->open comm proxy.\n",
       "    ws_proxy.onopen();\n",
       "\n",
       "    fig.parent_element = element.get(0);\n",
       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
       "    if (!fig.cell_info) {\n",
       "        console.error(\"Failed to find cell for figure\", id, fig);\n",
       "        return;\n",
       "    }\n",
       "\n",
       "    var output_index = fig.cell_info[2]\n",
       "    var cell = fig.cell_info[0];\n",
       "\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
       "    var width = fig.canvas.width/mpl.ratio\n",
       "    fig.root.unbind('remove')\n",
       "\n",
       "    // Update the output cell to use the data from the current canvas.\n",
       "    fig.push_to_output();\n",
       "    var dataURL = fig.canvas.toDataURL();\n",
       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
       "    // the notebook keyboard shortcuts fail.\n",
       "    IPython.keyboard_manager.enable()\n",
       "    $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
       "    fig.close_ws(fig, msg);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.close_ws = function(fig, msg){\n",
       "    fig.send_message('closing', msg);\n",
       "    // fig.ws.close()\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
       "    // Turn the data on the canvas into data in the output cell.\n",
       "    var width = this.canvas.width/mpl.ratio\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Tell IPython that the notebook contents must change.\n",
       "    IPython.notebook.set_dirty(true);\n",
       "    this.send_message(\"ack\", {});\n",
       "    var fig = this;\n",
       "    // Wait a second, then push the new image to the DOM so\n",
       "    // that it is saved nicely (might be nice to debounce this).\n",
       "    setTimeout(function () { fig.push_to_output() }, 1000);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items){\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) { continue; };\n",
       "\n",
       "        var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    // Add the status bar.\n",
       "    var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "\n",
       "    // Add the close button to the window.\n",
       "    var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
       "    var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
       "    button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
       "    button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
       "    buttongrp.append(button);\n",
       "    var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
       "    titlebar.prepend(buttongrp);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(el){\n",
       "    var fig = this\n",
       "    el.on(\"remove\", function(){\n",
       "\tfig.close_ws(fig, {});\n",
       "    });\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(el){\n",
       "    // this is important to make the div 'focusable\n",
       "    el.attr('tabindex', 0)\n",
       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
       "    // off when our div gets focus\n",
       "\n",
       "    // location in version 3\n",
       "    if (IPython.notebook.keyboard_manager) {\n",
       "        IPython.notebook.keyboard_manager.register_events(el);\n",
       "    }\n",
       "    else {\n",
       "        // location in version 2\n",
       "        IPython.keyboard_manager.register_events(el);\n",
       "    }\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager)\n",
       "        manager = IPython.keyboard_manager;\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which == 13) {\n",
       "        this.canvas_div.blur();\n",
       "        event.shiftKey = false;\n",
       "        // Send a \"J\" for go to next cell\n",
       "        event.which = 74;\n",
       "        event.keyCode = 74;\n",
       "        manager.command_mode();\n",
       "        manager.handle_keydown(event);\n",
       "    }\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.find_output_cell = function(html_output) {\n",
       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
       "    // IPython event is triggered only after the cells have been serialised, which for\n",
       "    // our purposes (turning an active figure into a static one), is too late.\n",
       "    var cells = IPython.notebook.get_cells();\n",
       "    var ncells = cells.length;\n",
       "    for (var i=0; i<ncells; i++) {\n",
       "        var cell = cells[i];\n",
       "        if (cell.cell_type === 'code'){\n",
       "            for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
       "                var data = cell.output_area.outputs[j];\n",
       "                if (data.data) {\n",
       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
       "                    data = data.data;\n",
       "                }\n",
       "                if (data['text/html'] == html_output) {\n",
       "                    return [cell, data, j];\n",
       "                }\n",
       "            }\n",
       "        }\n",
       "    }\n",
       "}\n",
       "\n",
       "// Register the function which deals with the matplotlib target/channel.\n",
       "// The kernel may be null if the page has been refreshed.\n",
       "if (IPython.notebook.kernel != null) {\n",
       "    IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
       "}\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,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\" width=\"573\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#With fine pixel-splitting, new integrator:\n",
    "kwarg[\"method\"] = \"fullsplit_csr\"\n",
    "f,a = plot_distribution(ai, kwarg, integrate = ai._integrate1d_ng)\n",
    "f.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Any kind of pixel splitting causes a change in the distribution of signal. This error has been spotted by Daniel Franke from Hamburg. If the azimuthal integration should be performed like:\n",
    "\n",
    "$$\n",
    "I_{bin} = \\frac{\\sum_{pix \\in bin} c^{pix}_{bin}I_{pix}}{\\sum_{pix \\in bin} c^{pix}_{bin}\\Omega_{pix}P_{pix}}\n",
    "$$\n",
    "\n",
    "the associated variance propagation should look like this: \n",
    "\n",
    "$$\n",
    "\\sigma_{bin} = \\frac{\\sqrt{\\sum_{pix \\in bin} (c^{pix}_{bin})^2 \\sigma^2_{pix}}}\n",
    "                     {\\sum_{pix \\in bin}c^{pix}_{bin}\\Omega_{pix}P_{pix}}\n",
    "$$\n",
    "\n",
    "And the square of the coefficient has been missing until v0.16 of pyFAI. Updated rebinning engines contain a ```coef_power``` optional argument which allows the user to change the power applied on the coefficient, like CSR-integrators:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "/* Put everything inside the global mpl namespace */\n",
       "window.mpl = {};\n",
       "\n",
       "\n",
       "mpl.get_websocket_type = function() {\n",
       "    if (typeof(WebSocket) !== 'undefined') {\n",
       "        return WebSocket;\n",
       "    } else if (typeof(MozWebSocket) !== 'undefined') {\n",
       "        return MozWebSocket;\n",
       "    } else {\n",
       "        alert('Your browser does not have WebSocket support.' +\n",
       "              'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
       "              'Firefox 4 and 5 are also supported but you ' +\n",
       "              'have to enable WebSockets in about:config.');\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
       "    this.id = figure_id;\n",
       "\n",
       "    this.ws = websocket;\n",
       "\n",
       "    this.supports_binary = (this.ws.binaryType != undefined);\n",
       "\n",
       "    if (!this.supports_binary) {\n",
       "        var warnings = document.getElementById(\"mpl-warnings\");\n",
       "        if (warnings) {\n",
       "            warnings.style.display = 'block';\n",
       "            warnings.textContent = (\n",
       "                \"This browser does not support binary websocket messages. \" +\n",
       "                    \"Performance may be slow.\");\n",
       "        }\n",
       "    }\n",
       "\n",
       "    this.imageObj = new Image();\n",
       "\n",
       "    this.context = undefined;\n",
       "    this.message = undefined;\n",
       "    this.canvas = undefined;\n",
       "    this.rubberband_canvas = undefined;\n",
       "    this.rubberband_context = undefined;\n",
       "    this.format_dropdown = undefined;\n",
       "\n",
       "    this.image_mode = 'full';\n",
       "\n",
       "    this.root = $('<div/>');\n",
       "    this._root_extra_style(this.root)\n",
       "    this.root.attr('style', 'display: inline-block');\n",
       "\n",
       "    $(parent_element).append(this.root);\n",
       "\n",
       "    this._init_header(this);\n",
       "    this._init_canvas(this);\n",
       "    this._init_toolbar(this);\n",
       "\n",
       "    var fig = this;\n",
       "\n",
       "    this.waiting = false;\n",
       "\n",
       "    this.ws.onopen =  function () {\n",
       "            fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
       "            fig.send_message(\"send_image_mode\", {});\n",
       "            if (mpl.ratio != 1) {\n",
       "                fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
       "            }\n",
       "            fig.send_message(\"refresh\", {});\n",
       "        }\n",
       "\n",
       "    this.imageObj.onload = function() {\n",
       "            if (fig.image_mode == 'full') {\n",
       "                // Full images could contain transparency (where diff images\n",
       "                // almost always do), so we need to clear the canvas so that\n",
       "                // there is no ghosting.\n",
       "                fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
       "            }\n",
       "            fig.context.drawImage(fig.imageObj, 0, 0);\n",
       "        };\n",
       "\n",
       "    this.imageObj.onunload = function() {\n",
       "        fig.ws.close();\n",
       "    }\n",
       "\n",
       "    this.ws.onmessage = this._make_on_message_function(this);\n",
       "\n",
       "    this.ondownload = ondownload;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_header = function() {\n",
       "    var titlebar = $(\n",
       "        '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
       "        'ui-helper-clearfix\"/>');\n",
       "    var titletext = $(\n",
       "        '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
       "        'text-align: center; padding: 3px;\"/>');\n",
       "    titlebar.append(titletext)\n",
       "    this.root.append(titlebar);\n",
       "    this.header = titletext[0];\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_canvas = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var canvas_div = $('<div/>');\n",
       "\n",
       "    canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
       "\n",
       "    function canvas_keyboard_event(event) {\n",
       "        return fig.key_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    canvas_div.keydown('key_press', canvas_keyboard_event);\n",
       "    canvas_div.keyup('key_release', canvas_keyboard_event);\n",
       "    this.canvas_div = canvas_div\n",
       "    this._canvas_extra_style(canvas_div)\n",
       "    this.root.append(canvas_div);\n",
       "\n",
       "    var canvas = $('<canvas/>');\n",
       "    canvas.addClass('mpl-canvas');\n",
       "    canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
       "\n",
       "    this.canvas = canvas[0];\n",
       "    this.context = canvas[0].getContext(\"2d\");\n",
       "\n",
       "    var backingStore = this.context.backingStorePixelRatio ||\n",
       "\tthis.context.webkitBackingStorePixelRatio ||\n",
       "\tthis.context.mozBackingStorePixelRatio ||\n",
       "\tthis.context.msBackingStorePixelRatio ||\n",
       "\tthis.context.oBackingStorePixelRatio ||\n",
       "\tthis.context.backingStorePixelRatio || 1;\n",
       "\n",
       "    mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
       "\n",
       "    var rubberband = $('<canvas/>');\n",
       "    rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
       "\n",
       "    var pass_mouse_events = true;\n",
       "\n",
       "    canvas_div.resizable({\n",
       "        start: function(event, ui) {\n",
       "            pass_mouse_events = false;\n",
       "        },\n",
       "        resize: function(event, ui) {\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "        stop: function(event, ui) {\n",
       "            pass_mouse_events = true;\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "    });\n",
       "\n",
       "    function mouse_event_fn(event) {\n",
       "        if (pass_mouse_events)\n",
       "            return fig.mouse_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    rubberband.mousedown('button_press', mouse_event_fn);\n",
       "    rubberband.mouseup('button_release', mouse_event_fn);\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband.mousemove('motion_notify', mouse_event_fn);\n",
       "\n",
       "    rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
       "    rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
       "\n",
       "    canvas_div.on(\"wheel\", function (event) {\n",
       "        event = event.originalEvent;\n",
       "        event['data'] = 'scroll'\n",
       "        if (event.deltaY < 0) {\n",
       "            event.step = 1;\n",
       "        } else {\n",
       "            event.step = -1;\n",
       "        }\n",
       "        mouse_event_fn(event);\n",
       "    });\n",
       "\n",
       "    canvas_div.append(canvas);\n",
       "    canvas_div.append(rubberband);\n",
       "\n",
       "    this.rubberband = rubberband;\n",
       "    this.rubberband_canvas = rubberband[0];\n",
       "    this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
       "    this.rubberband_context.strokeStyle = \"#000000\";\n",
       "\n",
       "    this._resize_canvas = function(width, height) {\n",
       "        // Keep the size of the canvas, canvas container, and rubber band\n",
       "        // canvas in synch.\n",
       "        canvas_div.css('width', width)\n",
       "        canvas_div.css('height', height)\n",
       "\n",
       "        canvas.attr('width', width * mpl.ratio);\n",
       "        canvas.attr('height', height * mpl.ratio);\n",
       "        canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
       "\n",
       "        rubberband.attr('width', width);\n",
       "        rubberband.attr('height', height);\n",
       "    }\n",
       "\n",
       "    // Set the figure to an initial 600x600px, this will subsequently be updated\n",
       "    // upon first draw.\n",
       "    this._resize_canvas(600, 600);\n",
       "\n",
       "    // Disable right mouse context menu.\n",
       "    $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
       "        return false;\n",
       "    });\n",
       "\n",
       "    function set_focus () {\n",
       "        canvas.focus();\n",
       "        canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    window.setTimeout(set_focus, 100);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items) {\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) {\n",
       "            // put a spacer in here.\n",
       "            continue;\n",
       "        }\n",
       "        var button = $('<button/>');\n",
       "        button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
       "                        'ui-button-icon-only');\n",
       "        button.attr('role', 'button');\n",
       "        button.attr('aria-disabled', 'false');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "\n",
       "        var icon_img = $('<span/>');\n",
       "        icon_img.addClass('ui-button-icon-primary ui-icon');\n",
       "        icon_img.addClass(image);\n",
       "        icon_img.addClass('ui-corner-all');\n",
       "\n",
       "        var tooltip_span = $('<span/>');\n",
       "        tooltip_span.addClass('ui-button-text');\n",
       "        tooltip_span.html(tooltip);\n",
       "\n",
       "        button.append(icon_img);\n",
       "        button.append(tooltip_span);\n",
       "\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    var fmt_picker_span = $('<span/>');\n",
       "\n",
       "    var fmt_picker = $('<select/>');\n",
       "    fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
       "    fmt_picker_span.append(fmt_picker);\n",
       "    nav_element.append(fmt_picker_span);\n",
       "    this.format_dropdown = fmt_picker[0];\n",
       "\n",
       "    for (var ind in mpl.extensions) {\n",
       "        var fmt = mpl.extensions[ind];\n",
       "        var option = $(\n",
       "            '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
       "        fmt_picker.append(option)\n",
       "    }\n",
       "\n",
       "    // Add hover states to the ui-buttons\n",
       "    $( \".ui-button\" ).hover(\n",
       "        function() { $(this).addClass(\"ui-state-hover\");},\n",
       "        function() { $(this).removeClass(\"ui-state-hover\");}\n",
       "    );\n",
       "\n",
       "    var status_bar = $('<span class=\"mpl-message\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
       "    // which will in turn request a refresh of the image.\n",
       "    this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_message = function(type, properties) {\n",
       "    properties['type'] = type;\n",
       "    properties['figure_id'] = this.id;\n",
       "    this.ws.send(JSON.stringify(properties));\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_draw_message = function() {\n",
       "    if (!this.waiting) {\n",
       "        this.waiting = true;\n",
       "        this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
       "    }\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    var format_dropdown = fig.format_dropdown;\n",
       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
       "    fig.ondownload(fig, format);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
       "    var size = msg['size'];\n",
       "    if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
       "        fig._resize_canvas(size[0], size[1]);\n",
       "        fig.send_message(\"refresh\", {});\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
       "    var x0 = msg['x0'] / mpl.ratio;\n",
       "    var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
       "    var x1 = msg['x1'] / mpl.ratio;\n",
       "    var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
       "    x0 = Math.floor(x0) + 0.5;\n",
       "    y0 = Math.floor(y0) + 0.5;\n",
       "    x1 = Math.floor(x1) + 0.5;\n",
       "    y1 = Math.floor(y1) + 0.5;\n",
       "    var min_x = Math.min(x0, x1);\n",
       "    var min_y = Math.min(y0, y1);\n",
       "    var width = Math.abs(x1 - x0);\n",
       "    var height = Math.abs(y1 - y0);\n",
       "\n",
       "    fig.rubberband_context.clearRect(\n",
       "        0, 0, fig.canvas.width, fig.canvas.height);\n",
       "\n",
       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
       "    // Updates the figure title.\n",
       "    fig.header.textContent = msg['label'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
       "    var cursor = msg['cursor'];\n",
       "    switch(cursor)\n",
       "    {\n",
       "    case 0:\n",
       "        cursor = 'pointer';\n",
       "        break;\n",
       "    case 1:\n",
       "        cursor = 'default';\n",
       "        break;\n",
       "    case 2:\n",
       "        cursor = 'crosshair';\n",
       "        break;\n",
       "    case 3:\n",
       "        cursor = 'move';\n",
       "        break;\n",
       "    }\n",
       "    fig.rubberband_canvas.style.cursor = cursor;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
       "    fig.message.textContent = msg['message'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
       "    // Request the server to send over a new figure.\n",
       "    fig.send_draw_message();\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
       "    fig.image_mode = msg['mode'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Called whenever the canvas gets updated.\n",
       "    this.send_message(\"ack\", {});\n",
       "}\n",
       "\n",
       "// A function to construct a web socket function for onmessage handling.\n",
       "// Called in the figure constructor.\n",
       "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
       "    return function socket_on_message(evt) {\n",
       "        if (evt.data instanceof Blob) {\n",
       "            /* FIXME: We get \"Resource interpreted as Image but\n",
       "             * transferred with MIME type text/plain:\" errors on\n",
       "             * Chrome.  But how to set the MIME type?  It doesn't seem\n",
       "             * to be part of the websocket stream */\n",
       "            evt.data.type = \"image/png\";\n",
       "\n",
       "            /* Free the memory for the previous frames */\n",
       "            if (fig.imageObj.src) {\n",
       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
       "                    fig.imageObj.src);\n",
       "            }\n",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data);\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "        else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
       "            fig.imageObj.src = evt.data;\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        var msg = JSON.parse(evt.data);\n",
       "        var msg_type = msg['type'];\n",
       "\n",
       "        // Call the  \"handle_{type}\" callback, which takes\n",
       "        // the figure and JSON message as its only arguments.\n",
       "        try {\n",
       "            var callback = fig[\"handle_\" + msg_type];\n",
       "        } catch (e) {\n",
       "            console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        if (callback) {\n",
       "            try {\n",
       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
       "                callback(fig, msg);\n",
       "            } catch (e) {\n",
       "                console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
       "            }\n",
       "        }\n",
       "    };\n",
       "}\n",
       "\n",
       "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
       "mpl.findpos = function(e) {\n",
       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
       "    var targ;\n",
       "    if (!e)\n",
       "        e = window.event;\n",
       "    if (e.target)\n",
       "        targ = e.target;\n",
       "    else if (e.srcElement)\n",
       "        targ = e.srcElement;\n",
       "    if (targ.nodeType == 3) // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "\n",
       "    // jQuery normalizes the pageX and pageY\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    // offset() returns the position of the element relative to the document\n",
       "    var x = e.pageX - $(targ).offset().left;\n",
       "    var y = e.pageY - $(targ).offset().top;\n",
       "\n",
       "    return {\"x\": x, \"y\": y};\n",
       "};\n",
       "\n",
       "/*\n",
       " * return a copy of an object with only non-object keys\n",
       " * we need this to avoid circular references\n",
       " * http://stackoverflow.com/a/24161582/3208463\n",
       " */\n",
       "function simpleKeys (original) {\n",
       "  return Object.keys(original).reduce(function (obj, key) {\n",
       "    if (typeof original[key] !== 'object')\n",
       "        obj[key] = original[key]\n",
       "    return obj;\n",
       "  }, {});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.mouse_event = function(event, name) {\n",
       "    var canvas_pos = mpl.findpos(event)\n",
       "\n",
       "    if (name === 'button_press')\n",
       "    {\n",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * mpl.ratio;\n",
       "    var y = canvas_pos.y * mpl.ratio;\n",
       "\n",
       "    this.send_message(name, {x: x, y: y, button: event.button,\n",
       "                             step: event.step,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "\n",
       "    /* This prevents the web browser from automatically changing to\n",
       "     * the text insertion cursor when the button is pressed.  We want\n",
       "     * to control all of the cursor setting manually through the\n",
       "     * 'cursor' event from matplotlib */\n",
       "    event.preventDefault();\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    // Handle any extra behaviour associated with a key event\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.key_event = function(event, name) {\n",
       "\n",
       "    // Prevent repeat events\n",
       "    if (name == 'key_press')\n",
       "    {\n",
       "        if (event.which === this._key)\n",
       "            return;\n",
       "        else\n",
       "            this._key = event.which;\n",
       "    }\n",
       "    if (name == 'key_release')\n",
       "        this._key = null;\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which != 17)\n",
       "        value += \"ctrl+\";\n",
       "    if (event.altKey && event.which != 18)\n",
       "        value += \"alt+\";\n",
       "    if (event.shiftKey && event.which != 16)\n",
       "        value += \"shift+\";\n",
       "\n",
       "    value += 'k';\n",
       "    value += event.which.toString();\n",
       "\n",
       "    this._key_event_extra(event, name);\n",
       "\n",
       "    this.send_message(name, {key: value,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
       "    if (name == 'download') {\n",
       "        this.handle_save(this, null);\n",
       "    } else {\n",
       "        this.send_message(\"toolbar_button\", {name: name});\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
       "    this.message.textContent = tooltip;\n",
       "};\n",
       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
       "\n",
       "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
       "\n",
       "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
       "    // object with the appropriate methods. Currently this is a non binary\n",
       "    // socket, so there is still some room for performance tuning.\n",
       "    var ws = {};\n",
       "\n",
       "    ws.close = function() {\n",
       "        comm.close()\n",
       "    };\n",
       "    ws.send = function(m) {\n",
       "        //console.log('sending', m);\n",
       "        comm.send(m);\n",
       "    };\n",
       "    // Register the callback with on_msg.\n",
       "    comm.on_msg(function(msg) {\n",
       "        //console.log('receiving', msg['content']['data'], msg);\n",
       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
       "        ws.onmessage(msg['content']['data'])\n",
       "    });\n",
       "    return ws;\n",
       "}\n",
       "\n",
       "mpl.mpl_figure_comm = function(comm, msg) {\n",
       "    // This is the function which gets called when the mpl process\n",
       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
       "\n",
       "    var id = msg.content.data.id;\n",
       "    // Get hold of the div created by the display call when the Comm\n",
       "    // socket was opened in Python.\n",
       "    var element = $(\"#\" + id);\n",
       "    var ws_proxy = comm_websocket_adapter(comm)\n",
       "\n",
       "    function ondownload(figure, format) {\n",
       "        window.open(figure.imageObj.src);\n",
       "    }\n",
       "\n",
       "    var fig = new mpl.figure(id, ws_proxy,\n",
       "                           ondownload,\n",
       "                           element.get(0));\n",
       "\n",
       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
       "    // web socket which is closed, not our websocket->open comm proxy.\n",
       "    ws_proxy.onopen();\n",
       "\n",
       "    fig.parent_element = element.get(0);\n",
       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
       "    if (!fig.cell_info) {\n",
       "        console.error(\"Failed to find cell for figure\", id, fig);\n",
       "        return;\n",
       "    }\n",
       "\n",
       "    var output_index = fig.cell_info[2]\n",
       "    var cell = fig.cell_info[0];\n",
       "\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
       "    var width = fig.canvas.width/mpl.ratio\n",
       "    fig.root.unbind('remove')\n",
       "\n",
       "    // Update the output cell to use the data from the current canvas.\n",
       "    fig.push_to_output();\n",
       "    var dataURL = fig.canvas.toDataURL();\n",
       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
       "    // the notebook keyboard shortcuts fail.\n",
       "    IPython.keyboard_manager.enable()\n",
       "    $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
       "    fig.close_ws(fig, msg);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.close_ws = function(fig, msg){\n",
       "    fig.send_message('closing', msg);\n",
       "    // fig.ws.close()\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
       "    // Turn the data on the canvas into data in the output cell.\n",
       "    var width = this.canvas.width/mpl.ratio\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Tell IPython that the notebook contents must change.\n",
       "    IPython.notebook.set_dirty(true);\n",
       "    this.send_message(\"ack\", {});\n",
       "    var fig = this;\n",
       "    // Wait a second, then push the new image to the DOM so\n",
       "    // that it is saved nicely (might be nice to debounce this).\n",
       "    setTimeout(function () { fig.push_to_output() }, 1000);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items){\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) { continue; };\n",
       "\n",
       "        var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    // Add the status bar.\n",
       "    var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "\n",
       "    // Add the close button to the window.\n",
       "    var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
       "    var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
       "    button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
       "    button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
       "    buttongrp.append(button);\n",
       "    var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
       "    titlebar.prepend(buttongrp);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(el){\n",
       "    var fig = this\n",
       "    el.on(\"remove\", function(){\n",
       "\tfig.close_ws(fig, {});\n",
       "    });\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(el){\n",
       "    // this is important to make the div 'focusable\n",
       "    el.attr('tabindex', 0)\n",
       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
       "    // off when our div gets focus\n",
       "\n",
       "    // location in version 3\n",
       "    if (IPython.notebook.keyboard_manager) {\n",
       "        IPython.notebook.keyboard_manager.register_events(el);\n",
       "    }\n",
       "    else {\n",
       "        // location in version 2\n",
       "        IPython.keyboard_manager.register_events(el);\n",
       "    }\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager)\n",
       "        manager = IPython.keyboard_manager;\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which == 13) {\n",
       "        this.canvas_div.blur();\n",
       "        event.shiftKey = false;\n",
       "        // Send a \"J\" for go to next cell\n",
       "        event.which = 74;\n",
       "        event.keyCode = 74;\n",
       "        manager.command_mode();\n",
       "        manager.handle_keydown(event);\n",
       "    }\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.find_output_cell = function(html_output) {\n",
       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
       "    // IPython event is triggered only after the cells have been serialised, which for\n",
       "    // our purposes (turning an active figure into a static one), is too late.\n",
       "    var cells = IPython.notebook.get_cells();\n",
       "    var ncells = cells.length;\n",
       "    for (var i=0; i<ncells; i++) {\n",
       "        var cell = cells[i];\n",
       "        if (cell.cell_type === 'code'){\n",
       "            for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
       "                var data = cell.output_area.outputs[j];\n",
       "                if (data.data) {\n",
       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
       "                    data = data.data;\n",
       "                }\n",
       "                if (data['text/html'] == html_output) {\n",
       "                    return [cell, data, j];\n",
       "                }\n",
       "            }\n",
       "        }\n",
       "    }\n",
       "}\n",
       "\n",
       "// Register the function which deals with the matplotlib target/channel.\n",
       "// The kernel may be null if the page has been refreshed.\n",
       "if (IPython.notebook.kernel != null) {\n",
       "    IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
       "}\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,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\" width=\"573\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "HistoBBox1d.integrate(self, weights, dummy=None, delta_dummy=None, dark=None, flat=None, solidAngle=None, polarization=None, double normalization_factor=1.0, int coef_power=1)\n",
      "\n",
      "        Actually perform the integration which in this case looks more like a matrix-vector product\n",
      "\n",
      "        :param weights: input image\n",
      "        :type weights: ndarray\n",
      "        :param dummy: value for dead pixels (optional)\n",
      "        :type dummy: float\n",
      "        :param delta_dummy: precision for dead-pixel value in dynamic masking\n",
      "        :type delta_dummy: float\n",
      "        :param dark: array with the dark-current value to be subtracted (if any)\n",
      "        :type dark: ndarray\n",
      "        :param flat: array with the dark-current value to be divided by (if any)\n",
      "        :type flat: ndarray\n",
      "        :param solidAngle: array with the solid angle of each pixel to be divided by (if any)\n",
      "        :type solidAngle: ndarray\n",
      "        :param polarization: array with the polarization correction values to be divided by (if any)\n",
      "        :type polarization: ndarray\n",
      "        :param normalization_factor: divide the valid result by this value\n",
      "        :param coef_power: set to 2 for variance propagation, leave to 1 for mean calculation\n",
      "        :return: positions, pattern, weighted_histogram and unweighted_histogram\n",
      "        :rtype: 4-tuple of ndarrays\n",
      "\n",
      "        \n"
     ]
    }
   ],
   "source": [
    "ai.reset()\n",
    "kwarg[\"method\"] = \"csr\"\n",
    "img = dataset[0]\n",
    "fig,ax = subplots()\n",
    "ref = ai.integrate1d(img, variance=img, **kwarg)\n",
    "jupyter.plot1d(ref, ax=ax)\n",
    "csr = ai.engines[\"csr_integrator\"].engine\n",
    "print(csr.integrate.__doc__)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With those modification available, we are now able to estimate the error propagated from one curve and compare it with the \"usual\" result from pyFAI:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.9594304350043318\n"
     ]
    },
    {
     "data": {
      "application/javascript": [
       "/* Put everything inside the global mpl namespace */\n",
       "window.mpl = {};\n",
       "\n",
       "\n",
       "mpl.get_websocket_type = function() {\n",
       "    if (typeof(WebSocket) !== 'undefined') {\n",
       "        return WebSocket;\n",
       "    } else if (typeof(MozWebSocket) !== 'undefined') {\n",
       "        return MozWebSocket;\n",
       "    } else {\n",
       "        alert('Your browser does not have WebSocket support.' +\n",
       "              'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
       "              'Firefox 4 and 5 are also supported but you ' +\n",
       "              'have to enable WebSockets in about:config.');\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
       "    this.id = figure_id;\n",
       "\n",
       "    this.ws = websocket;\n",
       "\n",
       "    this.supports_binary = (this.ws.binaryType != undefined);\n",
       "\n",
       "    if (!this.supports_binary) {\n",
       "        var warnings = document.getElementById(\"mpl-warnings\");\n",
       "        if (warnings) {\n",
       "            warnings.style.display = 'block';\n",
       "            warnings.textContent = (\n",
       "                \"This browser does not support binary websocket messages. \" +\n",
       "                    \"Performance may be slow.\");\n",
       "        }\n",
       "    }\n",
       "\n",
       "    this.imageObj = new Image();\n",
       "\n",
       "    this.context = undefined;\n",
       "    this.message = undefined;\n",
       "    this.canvas = undefined;\n",
       "    this.rubberband_canvas = undefined;\n",
       "    this.rubberband_context = undefined;\n",
       "    this.format_dropdown = undefined;\n",
       "\n",
       "    this.image_mode = 'full';\n",
       "\n",
       "    this.root = $('<div/>');\n",
       "    this._root_extra_style(this.root)\n",
       "    this.root.attr('style', 'display: inline-block');\n",
       "\n",
       "    $(parent_element).append(this.root);\n",
       "\n",
       "    this._init_header(this);\n",
       "    this._init_canvas(this);\n",
       "    this._init_toolbar(this);\n",
       "\n",
       "    var fig = this;\n",
       "\n",
       "    this.waiting = false;\n",
       "\n",
       "    this.ws.onopen =  function () {\n",
       "            fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
       "            fig.send_message(\"send_image_mode\", {});\n",
       "            if (mpl.ratio != 1) {\n",
       "                fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
       "            }\n",
       "            fig.send_message(\"refresh\", {});\n",
       "        }\n",
       "\n",
       "    this.imageObj.onload = function() {\n",
       "            if (fig.image_mode == 'full') {\n",
       "                // Full images could contain transparency (where diff images\n",
       "                // almost always do), so we need to clear the canvas so that\n",
       "                // there is no ghosting.\n",
       "                fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
       "            }\n",
       "            fig.context.drawImage(fig.imageObj, 0, 0);\n",
       "        };\n",
       "\n",
       "    this.imageObj.onunload = function() {\n",
       "        fig.ws.close();\n",
       "    }\n",
       "\n",
       "    this.ws.onmessage = this._make_on_message_function(this);\n",
       "\n",
       "    this.ondownload = ondownload;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_header = function() {\n",
       "    var titlebar = $(\n",
       "        '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
       "        'ui-helper-clearfix\"/>');\n",
       "    var titletext = $(\n",
       "        '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
       "        'text-align: center; padding: 3px;\"/>');\n",
       "    titlebar.append(titletext)\n",
       "    this.root.append(titlebar);\n",
       "    this.header = titletext[0];\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_canvas = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var canvas_div = $('<div/>');\n",
       "\n",
       "    canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
       "\n",
       "    function canvas_keyboard_event(event) {\n",
       "        return fig.key_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    canvas_div.keydown('key_press', canvas_keyboard_event);\n",
       "    canvas_div.keyup('key_release', canvas_keyboard_event);\n",
       "    this.canvas_div = canvas_div\n",
       "    this._canvas_extra_style(canvas_div)\n",
       "    this.root.append(canvas_div);\n",
       "\n",
       "    var canvas = $('<canvas/>');\n",
       "    canvas.addClass('mpl-canvas');\n",
       "    canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
       "\n",
       "    this.canvas = canvas[0];\n",
       "    this.context = canvas[0].getContext(\"2d\");\n",
       "\n",
       "    var backingStore = this.context.backingStorePixelRatio ||\n",
       "\tthis.context.webkitBackingStorePixelRatio ||\n",
       "\tthis.context.mozBackingStorePixelRatio ||\n",
       "\tthis.context.msBackingStorePixelRatio ||\n",
       "\tthis.context.oBackingStorePixelRatio ||\n",
       "\tthis.context.backingStorePixelRatio || 1;\n",
       "\n",
       "    mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
       "\n",
       "    var rubberband = $('<canvas/>');\n",
       "    rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
       "\n",
       "    var pass_mouse_events = true;\n",
       "\n",
       "    canvas_div.resizable({\n",
       "        start: function(event, ui) {\n",
       "            pass_mouse_events = false;\n",
       "        },\n",
       "        resize: function(event, ui) {\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "        stop: function(event, ui) {\n",
       "            pass_mouse_events = true;\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "    });\n",
       "\n",
       "    function mouse_event_fn(event) {\n",
       "        if (pass_mouse_events)\n",
       "            return fig.mouse_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    rubberband.mousedown('button_press', mouse_event_fn);\n",
       "    rubberband.mouseup('button_release', mouse_event_fn);\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband.mousemove('motion_notify', mouse_event_fn);\n",
       "\n",
       "    rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
       "    rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
       "\n",
       "    canvas_div.on(\"wheel\", function (event) {\n",
       "        event = event.originalEvent;\n",
       "        event['data'] = 'scroll'\n",
       "        if (event.deltaY < 0) {\n",
       "            event.step = 1;\n",
       "        } else {\n",
       "            event.step = -1;\n",
       "        }\n",
       "        mouse_event_fn(event);\n",
       "    });\n",
       "\n",
       "    canvas_div.append(canvas);\n",
       "    canvas_div.append(rubberband);\n",
       "\n",
       "    this.rubberband = rubberband;\n",
       "    this.rubberband_canvas = rubberband[0];\n",
       "    this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
       "    this.rubberband_context.strokeStyle = \"#000000\";\n",
       "\n",
       "    this._resize_canvas = function(width, height) {\n",
       "        // Keep the size of the canvas, canvas container, and rubber band\n",
       "        // canvas in synch.\n",
       "        canvas_div.css('width', width)\n",
       "        canvas_div.css('height', height)\n",
       "\n",
       "        canvas.attr('width', width * mpl.ratio);\n",
       "        canvas.attr('height', height * mpl.ratio);\n",
       "        canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
       "\n",
       "        rubberband.attr('width', width);\n",
       "        rubberband.attr('height', height);\n",
       "    }\n",
       "\n",
       "    // Set the figure to an initial 600x600px, this will subsequently be updated\n",
       "    // upon first draw.\n",
       "    this._resize_canvas(600, 600);\n",
       "\n",
       "    // Disable right mouse context menu.\n",
       "    $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
       "        return false;\n",
       "    });\n",
       "\n",
       "    function set_focus () {\n",
       "        canvas.focus();\n",
       "        canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    window.setTimeout(set_focus, 100);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items) {\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) {\n",
       "            // put a spacer in here.\n",
       "            continue;\n",
       "        }\n",
       "        var button = $('<button/>');\n",
       "        button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
       "                        'ui-button-icon-only');\n",
       "        button.attr('role', 'button');\n",
       "        button.attr('aria-disabled', 'false');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "\n",
       "        var icon_img = $('<span/>');\n",
       "        icon_img.addClass('ui-button-icon-primary ui-icon');\n",
       "        icon_img.addClass(image);\n",
       "        icon_img.addClass('ui-corner-all');\n",
       "\n",
       "        var tooltip_span = $('<span/>');\n",
       "        tooltip_span.addClass('ui-button-text');\n",
       "        tooltip_span.html(tooltip);\n",
       "\n",
       "        button.append(icon_img);\n",
       "        button.append(tooltip_span);\n",
       "\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    var fmt_picker_span = $('<span/>');\n",
       "\n",
       "    var fmt_picker = $('<select/>');\n",
       "    fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
       "    fmt_picker_span.append(fmt_picker);\n",
       "    nav_element.append(fmt_picker_span);\n",
       "    this.format_dropdown = fmt_picker[0];\n",
       "\n",
       "    for (var ind in mpl.extensions) {\n",
       "        var fmt = mpl.extensions[ind];\n",
       "        var option = $(\n",
       "            '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
       "        fmt_picker.append(option)\n",
       "    }\n",
       "\n",
       "    // Add hover states to the ui-buttons\n",
       "    $( \".ui-button\" ).hover(\n",
       "        function() { $(this).addClass(\"ui-state-hover\");},\n",
       "        function() { $(this).removeClass(\"ui-state-hover\");}\n",
       "    );\n",
       "\n",
       "    var status_bar = $('<span class=\"mpl-message\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
       "    // which will in turn request a refresh of the image.\n",
       "    this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_message = function(type, properties) {\n",
       "    properties['type'] = type;\n",
       "    properties['figure_id'] = this.id;\n",
       "    this.ws.send(JSON.stringify(properties));\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_draw_message = function() {\n",
       "    if (!this.waiting) {\n",
       "        this.waiting = true;\n",
       "        this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
       "    }\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    var format_dropdown = fig.format_dropdown;\n",
       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
       "    fig.ondownload(fig, format);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
       "    var size = msg['size'];\n",
       "    if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
       "        fig._resize_canvas(size[0], size[1]);\n",
       "        fig.send_message(\"refresh\", {});\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
       "    var x0 = msg['x0'] / mpl.ratio;\n",
       "    var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
       "    var x1 = msg['x1'] / mpl.ratio;\n",
       "    var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
       "    x0 = Math.floor(x0) + 0.5;\n",
       "    y0 = Math.floor(y0) + 0.5;\n",
       "    x1 = Math.floor(x1) + 0.5;\n",
       "    y1 = Math.floor(y1) + 0.5;\n",
       "    var min_x = Math.min(x0, x1);\n",
       "    var min_y = Math.min(y0, y1);\n",
       "    var width = Math.abs(x1 - x0);\n",
       "    var height = Math.abs(y1 - y0);\n",
       "\n",
       "    fig.rubberband_context.clearRect(\n",
       "        0, 0, fig.canvas.width, fig.canvas.height);\n",
       "\n",
       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
       "    // Updates the figure title.\n",
       "    fig.header.textContent = msg['label'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
       "    var cursor = msg['cursor'];\n",
       "    switch(cursor)\n",
       "    {\n",
       "    case 0:\n",
       "        cursor = 'pointer';\n",
       "        break;\n",
       "    case 1:\n",
       "        cursor = 'default';\n",
       "        break;\n",
       "    case 2:\n",
       "        cursor = 'crosshair';\n",
       "        break;\n",
       "    case 3:\n",
       "        cursor = 'move';\n",
       "        break;\n",
       "    }\n",
       "    fig.rubberband_canvas.style.cursor = cursor;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
       "    fig.message.textContent = msg['message'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
       "    // Request the server to send over a new figure.\n",
       "    fig.send_draw_message();\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
       "    fig.image_mode = msg['mode'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Called whenever the canvas gets updated.\n",
       "    this.send_message(\"ack\", {});\n",
       "}\n",
       "\n",
       "// A function to construct a web socket function for onmessage handling.\n",
       "// Called in the figure constructor.\n",
       "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
       "    return function socket_on_message(evt) {\n",
       "        if (evt.data instanceof Blob) {\n",
       "            /* FIXME: We get \"Resource interpreted as Image but\n",
       "             * transferred with MIME type text/plain:\" errors on\n",
       "             * Chrome.  But how to set the MIME type?  It doesn't seem\n",
       "             * to be part of the websocket stream */\n",
       "            evt.data.type = \"image/png\";\n",
       "\n",
       "            /* Free the memory for the previous frames */\n",
       "            if (fig.imageObj.src) {\n",
       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
       "                    fig.imageObj.src);\n",
       "            }\n",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data);\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "        else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
       "            fig.imageObj.src = evt.data;\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        var msg = JSON.parse(evt.data);\n",
       "        var msg_type = msg['type'];\n",
       "\n",
       "        // Call the  \"handle_{type}\" callback, which takes\n",
       "        // the figure and JSON message as its only arguments.\n",
       "        try {\n",
       "            var callback = fig[\"handle_\" + msg_type];\n",
       "        } catch (e) {\n",
       "            console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        if (callback) {\n",
       "            try {\n",
       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
       "                callback(fig, msg);\n",
       "            } catch (e) {\n",
       "                console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
       "            }\n",
       "        }\n",
       "    };\n",
       "}\n",
       "\n",
       "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
       "mpl.findpos = function(e) {\n",
       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
       "    var targ;\n",
       "    if (!e)\n",
       "        e = window.event;\n",
       "    if (e.target)\n",
       "        targ = e.target;\n",
       "    else if (e.srcElement)\n",
       "        targ = e.srcElement;\n",
       "    if (targ.nodeType == 3) // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "\n",
       "    // jQuery normalizes the pageX and pageY\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    // offset() returns the position of the element relative to the document\n",
       "    var x = e.pageX - $(targ).offset().left;\n",
       "    var y = e.pageY - $(targ).offset().top;\n",
       "\n",
       "    return {\"x\": x, \"y\": y};\n",
       "};\n",
       "\n",
       "/*\n",
       " * return a copy of an object with only non-object keys\n",
       " * we need this to avoid circular references\n",
       " * http://stackoverflow.com/a/24161582/3208463\n",
       " */\n",
       "function simpleKeys (original) {\n",
       "  return Object.keys(original).reduce(function (obj, key) {\n",
       "    if (typeof original[key] !== 'object')\n",
       "        obj[key] = original[key]\n",
       "    return obj;\n",
       "  }, {});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.mouse_event = function(event, name) {\n",
       "    var canvas_pos = mpl.findpos(event)\n",
       "\n",
       "    if (name === 'button_press')\n",
       "    {\n",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * mpl.ratio;\n",
       "    var y = canvas_pos.y * mpl.ratio;\n",
       "\n",
       "    this.send_message(name, {x: x, y: y, button: event.button,\n",
       "                             step: event.step,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "\n",
       "    /* This prevents the web browser from automatically changing to\n",
       "     * the text insertion cursor when the button is pressed.  We want\n",
       "     * to control all of the cursor setting manually through the\n",
       "     * 'cursor' event from matplotlib */\n",
       "    event.preventDefault();\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    // Handle any extra behaviour associated with a key event\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.key_event = function(event, name) {\n",
       "\n",
       "    // Prevent repeat events\n",
       "    if (name == 'key_press')\n",
       "    {\n",
       "        if (event.which === this._key)\n",
       "            return;\n",
       "        else\n",
       "            this._key = event.which;\n",
       "    }\n",
       "    if (name == 'key_release')\n",
       "        this._key = null;\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which != 17)\n",
       "        value += \"ctrl+\";\n",
       "    if (event.altKey && event.which != 18)\n",
       "        value += \"alt+\";\n",
       "    if (event.shiftKey && event.which != 16)\n",
       "        value += \"shift+\";\n",
       "\n",
       "    value += 'k';\n",
       "    value += event.which.toString();\n",
       "\n",
       "    this._key_event_extra(event, name);\n",
       "\n",
       "    this.send_message(name, {key: value,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
       "    if (name == 'download') {\n",
       "        this.handle_save(this, null);\n",
       "    } else {\n",
       "        this.send_message(\"toolbar_button\", {name: name});\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
       "    this.message.textContent = tooltip;\n",
       "};\n",
       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
       "\n",
       "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
       "\n",
       "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
       "    // object with the appropriate methods. Currently this is a non binary\n",
       "    // socket, so there is still some room for performance tuning.\n",
       "    var ws = {};\n",
       "\n",
       "    ws.close = function() {\n",
       "        comm.close()\n",
       "    };\n",
       "    ws.send = function(m) {\n",
       "        //console.log('sending', m);\n",
       "        comm.send(m);\n",
       "    };\n",
       "    // Register the callback with on_msg.\n",
       "    comm.on_msg(function(msg) {\n",
       "        //console.log('receiving', msg['content']['data'], msg);\n",
       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
       "        ws.onmessage(msg['content']['data'])\n",
       "    });\n",
       "    return ws;\n",
       "}\n",
       "\n",
       "mpl.mpl_figure_comm = function(comm, msg) {\n",
       "    // This is the function which gets called when the mpl process\n",
       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
       "\n",
       "    var id = msg.content.data.id;\n",
       "    // Get hold of the div created by the display call when the Comm\n",
       "    // socket was opened in Python.\n",
       "    var element = $(\"#\" + id);\n",
       "    var ws_proxy = comm_websocket_adapter(comm)\n",
       "\n",
       "    function ondownload(figure, format) {\n",
       "        window.open(figure.imageObj.src);\n",
       "    }\n",
       "\n",
       "    var fig = new mpl.figure(id, ws_proxy,\n",
       "                           ondownload,\n",
       "                           element.get(0));\n",
       "\n",
       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
       "    // web socket which is closed, not our websocket->open comm proxy.\n",
       "    ws_proxy.onopen();\n",
       "\n",
       "    fig.parent_element = element.get(0);\n",
       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
       "    if (!fig.cell_info) {\n",
       "        console.error(\"Failed to find cell for figure\", id, fig);\n",
       "        return;\n",
       "    }\n",
       "\n",
       "    var output_index = fig.cell_info[2]\n",
       "    var cell = fig.cell_info[0];\n",
       "\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
       "    var width = fig.canvas.width/mpl.ratio\n",
       "    fig.root.unbind('remove')\n",
       "\n",
       "    // Update the output cell to use the data from the current canvas.\n",
       "    fig.push_to_output();\n",
       "    var dataURL = fig.canvas.toDataURL();\n",
       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
       "    // the notebook keyboard shortcuts fail.\n",
       "    IPython.keyboard_manager.enable()\n",
       "    $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
       "    fig.close_ws(fig, msg);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.close_ws = function(fig, msg){\n",
       "    fig.send_message('closing', msg);\n",
       "    // fig.ws.close()\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
       "    // Turn the data on the canvas into data in the output cell.\n",
       "    var width = this.canvas.width/mpl.ratio\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Tell IPython that the notebook contents must change.\n",
       "    IPython.notebook.set_dirty(true);\n",
       "    this.send_message(\"ack\", {});\n",
       "    var fig = this;\n",
       "    // Wait a second, then push the new image to the DOM so\n",
       "    // that it is saved nicely (might be nice to debounce this).\n",
       "    setTimeout(function () { fig.push_to_output() }, 1000);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items){\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) { continue; };\n",
       "\n",
       "        var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    // Add the status bar.\n",
       "    var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "\n",
       "    // Add the close button to the window.\n",
       "    var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
       "    var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
       "    button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
       "    button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
       "    buttongrp.append(button);\n",
       "    var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
       "    titlebar.prepend(buttongrp);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(el){\n",
       "    var fig = this\n",
       "    el.on(\"remove\", function(){\n",
       "\tfig.close_ws(fig, {});\n",
       "    });\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(el){\n",
       "    // this is important to make the div 'focusable\n",
       "    el.attr('tabindex', 0)\n",
       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
       "    // off when our div gets focus\n",
       "\n",
       "    // location in version 3\n",
       "    if (IPython.notebook.keyboard_manager) {\n",
       "        IPython.notebook.keyboard_manager.register_events(el);\n",
       "    }\n",
       "    else {\n",
       "        // location in version 2\n",
       "        IPython.keyboard_manager.register_events(el);\n",
       "    }\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager)\n",
       "        manager = IPython.keyboard_manager;\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which == 13) {\n",
       "        this.canvas_div.blur();\n",
       "        event.shiftKey = false;\n",
       "        // Send a \"J\" for go to next cell\n",
       "        event.which = 74;\n",
       "        event.keyCode = 74;\n",
       "        manager.command_mode();\n",
       "        manager.handle_keydown(event);\n",
       "    }\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.find_output_cell = function(html_output) {\n",
       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
       "    // IPython event is triggered only after the cells have been serialised, which for\n",
       "    // our purposes (turning an active figure into a static one), is too late.\n",
       "    var cells = IPython.notebook.get_cells();\n",
       "    var ncells = cells.length;\n",
       "    for (var i=0; i<ncells; i++) {\n",
       "        var cell = cells[i];\n",
       "        if (cell.cell_type === 'code'){\n",
       "            for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
       "                var data = cell.output_area.outputs[j];\n",
       "                if (data.data) {\n",
       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
       "                    data = data.data;\n",
       "                }\n",
       "                if (data['text/html'] == html_output) {\n",
       "                    return [cell, data, j];\n",
       "                }\n",
       "            }\n",
       "        }\n",
       "    }\n",
       "}\n",
       "\n",
       "// Register the function which deals with the matplotlib target/channel.\n",
       "// The kernel may be null if the page has been refreshed.\n",
       "if (IPython.notebook.kernel != null) {\n",
       "    IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
       "}\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAj0AAAGtCAYAAAD9H8XfAAAgAElEQVR4nOzdZ3iUdfq38bAoqxAmIGBUkICCZRdXXVRsNPWRXQugruCCyOq6Kuh/14YJKXMn9CYdBaQI0qtAQOkQQaRDQifSSwohvSfzfV6MjEbAYPglmcmcn+OYF5kJV4bx0vv0zhQfAQAAeAGf8r4DAAAAZYHoAQAAXoHoAQAAXoHoAQBcEYfDoby8PC5c3PbicDh+c4eJHgDAb3I4HEpISND+/fu1b98+Llzc9rJ//34lJCRcNn6IHgDAb7oQPMnJycrNzS33/5vnwuVSl9zcXCUnJ7vC51KIHgDAZTkcDlfwAJ7gQvhc6mwP0QMAuKy8vDzt27dPubm55X1XgCuSm5urffv2KS8v76LbiB4AwGVdiJ5LHUAAd/RbO0v0AAAuy9OjZ9q0aWrevHl53w2UIaIHAFAinh498D5EDwCgRIgeeBqiBwBQIp4UPYMHD1a9evXk6+urhg0baubMmZo8ebKaNm3q+p7du3frwQcflK+vr9q0aaP33ntPL730kiTp6NGj8vHx0eTJk9WgQQP5+voqKChIp06d0hNPPCFfX1+1atVK8fHxrnkffvihbr31Vvn6+qpJkyaKjIws8783iiJ6AAAl4inRc+DAAV1//fU6cOCAJOnMmTPau3dvkejJy8tTgwYN1KdPH+Xl5SkqKko2m+2i6OnSpYsyMjIUExOjKlWq6LHHHtOePXuUnZ2tJ554Qh988IHr53711VdKSEhQQUGBJk6cqGrVqhWJIpQ9ogcAUCKXOoA82n+17rG+LfXLo/1XX/H9jI2N1XXXXacFCxYoKyvLdf0vo2f9+vW64YYbVFBQ4Lq9c+fOF0XP4cOHXbc/+OCDCgkJcX09ZswYtWzZ8rL34/bbb+dsTzkjegAAJeIp0SNJs2bNUosWLVS9enU988wz2r9/f5HomTlzppo0aVLkzwQFBV0UPenp6a7bW7ZsqVGjRrm+/vWvy4YMGaK7775bNptNfn5+qly5sr788svfdb9hFtEDACgRT/n11i9lZGSoe/fuevzxxy8601OrVq1iz/RcafRERUWpRo0a2rFjhwoLCyU5z/RMnjy5tP+K+A1EDwCgRDwleg4cOKCVK1cqOztb+fn56tGjh1q2bHnRc3rq16+v/v37Ky8vTxs2bLjkc3quNHqWLl2q2rVr6+TJk8rPz9eoUaNUuXJloqecET0AgBLxlOjZvXu3HnroIfn6+srPz0+tW7e+6NdbkrRz5041bdpU1apV09NPP6233npLnTp1kvT7o6ewsFBvvvmmbDab/P39FRISoqZNmxI95YzoAQCUiKdET0l16NBBgYGB5X03YBDRAwAokYoWPevXr9fJkydVUFCgpUuXqkqVKtq8eXN53y0YRPQAAEqkokXPxIkTdfPNN6tq1aq68847NXHixPK+SzCM6AEAlEhFix5UfEQPAKBEiB54GqIHAFAiRA88DdEDACgRogeehugBAJQI0QNPQ/QAAEqE6IGnIXoAACVC9MDTED0AgBIhen72448/6u6771Z+fv5vfl9UVJQCAgLK5D5ZluX67LDipKen67bbblNCQkIp36vS1b9/fwUFBV32dqIHAFAi3hg9lwuJTp06ady4ceVwjy7vl/c1Pj5enTp1Ut26dVW9enXdf//9ioyMLPL9ERERev/99y+aM3HiRNdnkJW3mJgYPf3006pVq9ZFn4UmOePtxhtvVFxc3CX/PNEDACgRb4ue/Pz8S0ZPfHy8qlevrpSUlHK6Z5f2y/v6448/avDgwTp58qQKCwu1ePFiVatWTQcOHHB9/9GjR1WjRg1lZ2cXmdO+fXvNnDnT+P0r7qzYpRw4cEATJkzQkiVLLhk9ktS1a1f179//kn+e6AEAlIgnRc/gwYNVr149+fr6qmHDhpo5c6YKCwsVFBSkOnXqqG7dupo0aZJ8fHwUExMjyXnwfPPNN/XCCy/I19dXo0aN0rXXXqvKlSurWrVqqlWrliTpq6++0iOPPFLk502dOlW33367fH19Va9ePQ0dOlSStHbtWtefk6Tjx4+rdevWql69upo1a6awsLAin/zu4+Ojzz//XHfffbeqV6+ul19+WZmZma7bX3nlFd18882qXr26HnroIW3atMl1W3G/3rr//vs1ZcqUItfddtttWrFihevrnJwc1ahRQ8nJya5Pmp8yZYoaNmwoPz8/vfPOO3I4HK7v//LLL3XnnXfKz89PrVq10t69e123tWzZUp988olat26tqlWrauXKleratav+85//6IUXXlC1atXUpEkT7d27V6NHj9Ytt9yiOnXqaOzYsRfd90t96v0vH/tHH330kn9nogcAUCKXPIAMbSL1v7X0L0ObXPH9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\" width=\"573\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "norm = ai.solidAngleArray(detector.shape) * ai.polarization(detector.shape, factor=0.95)\n",
    "print(norm.min())\n",
    "denom = csr.integrate(norm)\n",
    "signal1 = csr.integrate(img)\n",
    "signal2 = csr.integrate(img, coef_power=2)\n",
    "\n",
    "fig,ax = subplots()\n",
    "#ax.plot(ref.radial, ref.intensity, label=\"ref\")\n",
    "#ax.plot(denom1[0], signal1[2]/denom1[2], label=\"signal/norm\")\n",
    "ax.plot(ref.radial, ref.sigma, label=\"sigma\")\n",
    "ax.plot(denom[0], numpy.sqrt(signal2[2])/denom[2], label=\"sqrt(signal2)/norm1)\")\n",
    "\n",
    "fig.legend()\n",
    "fig.canvas.draw()\n",
    "#ax.plot(denom2[0], denom2[2])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It turns out pyFAI was slightly overestimating the error, but not by much which explains why this bug remained undiscovered for years.\n",
    "\n",
    "We have now all the tools to build a new integrator and evaluate if it behaves as expected: (from a statistical point of view)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "/* Put everything inside the global mpl namespace */\n",
       "window.mpl = {};\n",
       "\n",
       "\n",
       "mpl.get_websocket_type = function() {\n",
       "    if (typeof(WebSocket) !== 'undefined') {\n",
       "        return WebSocket;\n",
       "    } else if (typeof(MozWebSocket) !== 'undefined') {\n",
       "        return MozWebSocket;\n",
       "    } else {\n",
       "        alert('Your browser does not have WebSocket support.' +\n",
       "              'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
       "              'Firefox 4 and 5 are also supported but you ' +\n",
       "              'have to enable WebSockets in about:config.');\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
       "    this.id = figure_id;\n",
       "\n",
       "    this.ws = websocket;\n",
       "\n",
       "    this.supports_binary = (this.ws.binaryType != undefined);\n",
       "\n",
       "    if (!this.supports_binary) {\n",
       "        var warnings = document.getElementById(\"mpl-warnings\");\n",
       "        if (warnings) {\n",
       "            warnings.style.display = 'block';\n",
       "            warnings.textContent = (\n",
       "                \"This browser does not support binary websocket messages. \" +\n",
       "                    \"Performance may be slow.\");\n",
       "        }\n",
       "    }\n",
       "\n",
       "    this.imageObj = new Image();\n",
       "\n",
       "    this.context = undefined;\n",
       "    this.message = undefined;\n",
       "    this.canvas = undefined;\n",
       "    this.rubberband_canvas = undefined;\n",
       "    this.rubberband_context = undefined;\n",
       "    this.format_dropdown = undefined;\n",
       "\n",
       "    this.image_mode = 'full';\n",
       "\n",
       "    this.root = $('<div/>');\n",
       "    this._root_extra_style(this.root)\n",
       "    this.root.attr('style', 'display: inline-block');\n",
       "\n",
       "    $(parent_element).append(this.root);\n",
       "\n",
       "    this._init_header(this);\n",
       "    this._init_canvas(this);\n",
       "    this._init_toolbar(this);\n",
       "\n",
       "    var fig = this;\n",
       "\n",
       "    this.waiting = false;\n",
       "\n",
       "    this.ws.onopen =  function () {\n",
       "            fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
       "            fig.send_message(\"send_image_mode\", {});\n",
       "            if (mpl.ratio != 1) {\n",
       "                fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
       "            }\n",
       "            fig.send_message(\"refresh\", {});\n",
       "        }\n",
       "\n",
       "    this.imageObj.onload = function() {\n",
       "            if (fig.image_mode == 'full') {\n",
       "                // Full images could contain transparency (where diff images\n",
       "                // almost always do), so we need to clear the canvas so that\n",
       "                // there is no ghosting.\n",
       "                fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
       "            }\n",
       "            fig.context.drawImage(fig.imageObj, 0, 0);\n",
       "        };\n",
       "\n",
       "    this.imageObj.onunload = function() {\n",
       "        fig.ws.close();\n",
       "    }\n",
       "\n",
       "    this.ws.onmessage = this._make_on_message_function(this);\n",
       "\n",
       "    this.ondownload = ondownload;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_header = function() {\n",
       "    var titlebar = $(\n",
       "        '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
       "        'ui-helper-clearfix\"/>');\n",
       "    var titletext = $(\n",
       "        '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
       "        'text-align: center; padding: 3px;\"/>');\n",
       "    titlebar.append(titletext)\n",
       "    this.root.append(titlebar);\n",
       "    this.header = titletext[0];\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_canvas = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var canvas_div = $('<div/>');\n",
       "\n",
       "    canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
       "\n",
       "    function canvas_keyboard_event(event) {\n",
       "        return fig.key_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    canvas_div.keydown('key_press', canvas_keyboard_event);\n",
       "    canvas_div.keyup('key_release', canvas_keyboard_event);\n",
       "    this.canvas_div = canvas_div\n",
       "    this._canvas_extra_style(canvas_div)\n",
       "    this.root.append(canvas_div);\n",
       "\n",
       "    var canvas = $('<canvas/>');\n",
       "    canvas.addClass('mpl-canvas');\n",
       "    canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
       "\n",
       "    this.canvas = canvas[0];\n",
       "    this.context = canvas[0].getContext(\"2d\");\n",
       "\n",
       "    var backingStore = this.context.backingStorePixelRatio ||\n",
       "\tthis.context.webkitBackingStorePixelRatio ||\n",
       "\tthis.context.mozBackingStorePixelRatio ||\n",
       "\tthis.context.msBackingStorePixelRatio ||\n",
       "\tthis.context.oBackingStorePixelRatio ||\n",
       "\tthis.context.backingStorePixelRatio || 1;\n",
       "\n",
       "    mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
       "\n",
       "    var rubberband = $('<canvas/>');\n",
       "    rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
       "\n",
       "    var pass_mouse_events = true;\n",
       "\n",
       "    canvas_div.resizable({\n",
       "        start: function(event, ui) {\n",
       "            pass_mouse_events = false;\n",
       "        },\n",
       "        resize: function(event, ui) {\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "        stop: function(event, ui) {\n",
       "            pass_mouse_events = true;\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "    });\n",
       "\n",
       "    function mouse_event_fn(event) {\n",
       "        if (pass_mouse_events)\n",
       "            return fig.mouse_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    rubberband.mousedown('button_press', mouse_event_fn);\n",
       "    rubberband.mouseup('button_release', mouse_event_fn);\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband.mousemove('motion_notify', mouse_event_fn);\n",
       "\n",
       "    rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
       "    rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
       "\n",
       "    canvas_div.on(\"wheel\", function (event) {\n",
       "        event = event.originalEvent;\n",
       "        event['data'] = 'scroll'\n",
       "        if (event.deltaY < 0) {\n",
       "            event.step = 1;\n",
       "        } else {\n",
       "            event.step = -1;\n",
       "        }\n",
       "        mouse_event_fn(event);\n",
       "    });\n",
       "\n",
       "    canvas_div.append(canvas);\n",
       "    canvas_div.append(rubberband);\n",
       "\n",
       "    this.rubberband = rubberband;\n",
       "    this.rubberband_canvas = rubberband[0];\n",
       "    this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
       "    this.rubberband_context.strokeStyle = \"#000000\";\n",
       "\n",
       "    this._resize_canvas = function(width, height) {\n",
       "        // Keep the size of the canvas, canvas container, and rubber band\n",
       "        // canvas in synch.\n",
       "        canvas_div.css('width', width)\n",
       "        canvas_div.css('height', height)\n",
       "\n",
       "        canvas.attr('width', width * mpl.ratio);\n",
       "        canvas.attr('height', height * mpl.ratio);\n",
       "        canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
       "\n",
       "        rubberband.attr('width', width);\n",
       "        rubberband.attr('height', height);\n",
       "    }\n",
       "\n",
       "    // Set the figure to an initial 600x600px, this will subsequently be updated\n",
       "    // upon first draw.\n",
       "    this._resize_canvas(600, 600);\n",
       "\n",
       "    // Disable right mouse context menu.\n",
       "    $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
       "        return false;\n",
       "    });\n",
       "\n",
       "    function set_focus () {\n",
       "        canvas.focus();\n",
       "        canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    window.setTimeout(set_focus, 100);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items) {\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) {\n",
       "            // put a spacer in here.\n",
       "            continue;\n",
       "        }\n",
       "        var button = $('<button/>');\n",
       "        button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
       "                        'ui-button-icon-only');\n",
       "        button.attr('role', 'button');\n",
       "        button.attr('aria-disabled', 'false');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "\n",
       "        var icon_img = $('<span/>');\n",
       "        icon_img.addClass('ui-button-icon-primary ui-icon');\n",
       "        icon_img.addClass(image);\n",
       "        icon_img.addClass('ui-corner-all');\n",
       "\n",
       "        var tooltip_span = $('<span/>');\n",
       "        tooltip_span.addClass('ui-button-text');\n",
       "        tooltip_span.html(tooltip);\n",
       "\n",
       "        button.append(icon_img);\n",
       "        button.append(tooltip_span);\n",
       "\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    var fmt_picker_span = $('<span/>');\n",
       "\n",
       "    var fmt_picker = $('<select/>');\n",
       "    fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
       "    fmt_picker_span.append(fmt_picker);\n",
       "    nav_element.append(fmt_picker_span);\n",
       "    this.format_dropdown = fmt_picker[0];\n",
       "\n",
       "    for (var ind in mpl.extensions) {\n",
       "        var fmt = mpl.extensions[ind];\n",
       "        var option = $(\n",
       "            '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
       "        fmt_picker.append(option)\n",
       "    }\n",
       "\n",
       "    // Add hover states to the ui-buttons\n",
       "    $( \".ui-button\" ).hover(\n",
       "        function() { $(this).addClass(\"ui-state-hover\");},\n",
       "        function() { $(this).removeClass(\"ui-state-hover\");}\n",
       "    );\n",
       "\n",
       "    var status_bar = $('<span class=\"mpl-message\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
       "    // which will in turn request a refresh of the image.\n",
       "    this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_message = function(type, properties) {\n",
       "    properties['type'] = type;\n",
       "    properties['figure_id'] = this.id;\n",
       "    this.ws.send(JSON.stringify(properties));\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_draw_message = function() {\n",
       "    if (!this.waiting) {\n",
       "        this.waiting = true;\n",
       "        this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
       "    }\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    var format_dropdown = fig.format_dropdown;\n",
       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
       "    fig.ondownload(fig, format);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
       "    var size = msg['size'];\n",
       "    if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
       "        fig._resize_canvas(size[0], size[1]);\n",
       "        fig.send_message(\"refresh\", {});\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
       "    var x0 = msg['x0'] / mpl.ratio;\n",
       "    var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
       "    var x1 = msg['x1'] / mpl.ratio;\n",
       "    var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
       "    x0 = Math.floor(x0) + 0.5;\n",
       "    y0 = Math.floor(y0) + 0.5;\n",
       "    x1 = Math.floor(x1) + 0.5;\n",
       "    y1 = Math.floor(y1) + 0.5;\n",
       "    var min_x = Math.min(x0, x1);\n",
       "    var min_y = Math.min(y0, y1);\n",
       "    var width = Math.abs(x1 - x0);\n",
       "    var height = Math.abs(y1 - y0);\n",
       "\n",
       "    fig.rubberband_context.clearRect(\n",
       "        0, 0, fig.canvas.width, fig.canvas.height);\n",
       "\n",
       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
       "    // Updates the figure title.\n",
       "    fig.header.textContent = msg['label'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
       "    var cursor = msg['cursor'];\n",
       "    switch(cursor)\n",
       "    {\n",
       "    case 0:\n",
       "        cursor = 'pointer';\n",
       "        break;\n",
       "    case 1:\n",
       "        cursor = 'default';\n",
       "        break;\n",
       "    case 2:\n",
       "        cursor = 'crosshair';\n",
       "        break;\n",
       "    case 3:\n",
       "        cursor = 'move';\n",
       "        break;\n",
       "    }\n",
       "    fig.rubberband_canvas.style.cursor = cursor;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
       "    fig.message.textContent = msg['message'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
       "    // Request the server to send over a new figure.\n",
       "    fig.send_draw_message();\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
       "    fig.image_mode = msg['mode'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Called whenever the canvas gets updated.\n",
       "    this.send_message(\"ack\", {});\n",
       "}\n",
       "\n",
       "// A function to construct a web socket function for onmessage handling.\n",
       "// Called in the figure constructor.\n",
       "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
       "    return function socket_on_message(evt) {\n",
       "        if (evt.data instanceof Blob) {\n",
       "            /* FIXME: We get \"Resource interpreted as Image but\n",
       "             * transferred with MIME type text/plain:\" errors on\n",
       "             * Chrome.  But how to set the MIME type?  It doesn't seem\n",
       "             * to be part of the websocket stream */\n",
       "            evt.data.type = \"image/png\";\n",
       "\n",
       "            /* Free the memory for the previous frames */\n",
       "            if (fig.imageObj.src) {\n",
       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
       "                    fig.imageObj.src);\n",
       "            }\n",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data);\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "        else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
       "            fig.imageObj.src = evt.data;\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        var msg = JSON.parse(evt.data);\n",
       "        var msg_type = msg['type'];\n",
       "\n",
       "        // Call the  \"handle_{type}\" callback, which takes\n",
       "        // the figure and JSON message as its only arguments.\n",
       "        try {\n",
       "            var callback = fig[\"handle_\" + msg_type];\n",
       "        } catch (e) {\n",
       "            console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        if (callback) {\n",
       "            try {\n",
       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
       "                callback(fig, msg);\n",
       "            } catch (e) {\n",
       "                console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
       "            }\n",
       "        }\n",
       "    };\n",
       "}\n",
       "\n",
       "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
       "mpl.findpos = function(e) {\n",
       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
       "    var targ;\n",
       "    if (!e)\n",
       "        e = window.event;\n",
       "    if (e.target)\n",
       "        targ = e.target;\n",
       "    else if (e.srcElement)\n",
       "        targ = e.srcElement;\n",
       "    if (targ.nodeType == 3) // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "\n",
       "    // jQuery normalizes the pageX and pageY\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    // offset() returns the position of the element relative to the document\n",
       "    var x = e.pageX - $(targ).offset().left;\n",
       "    var y = e.pageY - $(targ).offset().top;\n",
       "\n",
       "    return {\"x\": x, \"y\": y};\n",
       "};\n",
       "\n",
       "/*\n",
       " * return a copy of an object with only non-object keys\n",
       " * we need this to avoid circular references\n",
       " * http://stackoverflow.com/a/24161582/3208463\n",
       " */\n",
       "function simpleKeys (original) {\n",
       "  return Object.keys(original).reduce(function (obj, key) {\n",
       "    if (typeof original[key] !== 'object')\n",
       "        obj[key] = original[key]\n",
       "    return obj;\n",
       "  }, {});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.mouse_event = function(event, name) {\n",
       "    var canvas_pos = mpl.findpos(event)\n",
       "\n",
       "    if (name === 'button_press')\n",
       "    {\n",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * mpl.ratio;\n",
       "    var y = canvas_pos.y * mpl.ratio;\n",
       "\n",
       "    this.send_message(name, {x: x, y: y, button: event.button,\n",
       "                             step: event.step,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "\n",
       "    /* This prevents the web browser from automatically changing to\n",
       "     * the text insertion cursor when the button is pressed.  We want\n",
       "     * to control all of the cursor setting manually through the\n",
       "     * 'cursor' event from matplotlib */\n",
       "    event.preventDefault();\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    // Handle any extra behaviour associated with a key event\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.key_event = function(event, name) {\n",
       "\n",
       "    // Prevent repeat events\n",
       "    if (name == 'key_press')\n",
       "    {\n",
       "        if (event.which === this._key)\n",
       "            return;\n",
       "        else\n",
       "            this._key = event.which;\n",
       "    }\n",
       "    if (name == 'key_release')\n",
       "        this._key = null;\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which != 17)\n",
       "        value += \"ctrl+\";\n",
       "    if (event.altKey && event.which != 18)\n",
       "        value += \"alt+\";\n",
       "    if (event.shiftKey && event.which != 16)\n",
       "        value += \"shift+\";\n",
       "\n",
       "    value += 'k';\n",
       "    value += event.which.toString();\n",
       "\n",
       "    this._key_event_extra(event, name);\n",
       "\n",
       "    this.send_message(name, {key: value,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
       "    if (name == 'download') {\n",
       "        this.handle_save(this, null);\n",
       "    } else {\n",
       "        this.send_message(\"toolbar_button\", {name: name});\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
       "    this.message.textContent = tooltip;\n",
       "};\n",
       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
       "\n",
       "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
       "\n",
       "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
       "    // object with the appropriate methods. Currently this is a non binary\n",
       "    // socket, so there is still some room for performance tuning.\n",
       "    var ws = {};\n",
       "\n",
       "    ws.close = function() {\n",
       "        comm.close()\n",
       "    };\n",
       "    ws.send = function(m) {\n",
       "        //console.log('sending', m);\n",
       "        comm.send(m);\n",
       "    };\n",
       "    // Register the callback with on_msg.\n",
       "    comm.on_msg(function(msg) {\n",
       "        //console.log('receiving', msg['content']['data'], msg);\n",
       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
       "        ws.onmessage(msg['content']['data'])\n",
       "    });\n",
       "    return ws;\n",
       "}\n",
       "\n",
       "mpl.mpl_figure_comm = function(comm, msg) {\n",
       "    // This is the function which gets called when the mpl process\n",
       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
       "\n",
       "    var id = msg.content.data.id;\n",
       "    // Get hold of the div created by the display call when the Comm\n",
       "    // socket was opened in Python.\n",
       "    var element = $(\"#\" + id);\n",
       "    var ws_proxy = comm_websocket_adapter(comm)\n",
       "\n",
       "    function ondownload(figure, format) {\n",
       "        window.open(figure.imageObj.src);\n",
       "    }\n",
       "\n",
       "    var fig = new mpl.figure(id, ws_proxy,\n",
       "                           ondownload,\n",
       "                           element.get(0));\n",
       "\n",
       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
       "    // web socket which is closed, not our websocket->open comm proxy.\n",
       "    ws_proxy.onopen();\n",
       "\n",
       "    fig.parent_element = element.get(0);\n",
       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
       "    if (!fig.cell_info) {\n",
       "        console.error(\"Failed to find cell for figure\", id, fig);\n",
       "        return;\n",
       "    }\n",
       "\n",
       "    var output_index = fig.cell_info[2]\n",
       "    var cell = fig.cell_info[0];\n",
       "\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
       "    var width = fig.canvas.width/mpl.ratio\n",
       "    fig.root.unbind('remove')\n",
       "\n",
       "    // Update the output cell to use the data from the current canvas.\n",
       "    fig.push_to_output();\n",
       "    var dataURL = fig.canvas.toDataURL();\n",
       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
       "    // the notebook keyboard shortcuts fail.\n",
       "    IPython.keyboard_manager.enable()\n",
       "    $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
       "    fig.close_ws(fig, msg);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.close_ws = function(fig, msg){\n",
       "    fig.send_message('closing', msg);\n",
       "    // fig.ws.close()\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
       "    // Turn the data on the canvas into data in the output cell.\n",
       "    var width = this.canvas.width/mpl.ratio\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Tell IPython that the notebook contents must change.\n",
       "    IPython.notebook.set_dirty(true);\n",
       "    this.send_message(\"ack\", {});\n",
       "    var fig = this;\n",
       "    // Wait a second, then push the new image to the DOM so\n",
       "    // that it is saved nicely (might be nice to debounce this).\n",
       "    setTimeout(function () { fig.push_to_output() }, 1000);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items){\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) { continue; };\n",
       "\n",
       "        var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    // Add the status bar.\n",
       "    var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "\n",
       "    // Add the close button to the window.\n",
       "    var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
       "    var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
       "    button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
       "    button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
       "    buttongrp.append(button);\n",
       "    var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
       "    titlebar.prepend(buttongrp);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(el){\n",
       "    var fig = this\n",
       "    el.on(\"remove\", function(){\n",
       "\tfig.close_ws(fig, {});\n",
       "    });\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(el){\n",
       "    // this is important to make the div 'focusable\n",
       "    el.attr('tabindex', 0)\n",
       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
       "    // off when our div gets focus\n",
       "\n",
       "    // location in version 3\n",
       "    if (IPython.notebook.keyboard_manager) {\n",
       "        IPython.notebook.keyboard_manager.register_events(el);\n",
       "    }\n",
       "    else {\n",
       "        // location in version 2\n",
       "        IPython.keyboard_manager.register_events(el);\n",
       "    }\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager)\n",
       "        manager = IPython.keyboard_manager;\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which == 13) {\n",
       "        this.canvas_div.blur();\n",
       "        event.shiftKey = false;\n",
       "        // Send a \"J\" for go to next cell\n",
       "        event.which = 74;\n",
       "        event.keyCode = 74;\n",
       "        manager.command_mode();\n",
       "        manager.handle_keydown(event);\n",
       "    }\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.find_output_cell = function(html_output) {\n",
       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
       "    // IPython event is triggered only after the cells have been serialised, which for\n",
       "    // our purposes (turning an active figure into a static one), is too late.\n",
       "    var cells = IPython.notebook.get_cells();\n",
       "    var ncells = cells.length;\n",
       "    for (var i=0; i<ncells; i++) {\n",
       "        var cell = cells[i];\n",
       "        if (cell.cell_type === 'code'){\n",
       "            for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
       "                var data = cell.output_area.outputs[j];\n",
       "                if (data.data) {\n",
       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
       "                    data = data.data;\n",
       "                }\n",
       "                if (data['text/html'] == html_output) {\n",
       "                    return [cell, data, j];\n",
       "                }\n",
       "            }\n",
       "        }\n",
       "    }\n",
       "}\n",
       "\n",
       "// Register the function which deals with the matplotlib target/channel.\n",
       "// The kernel may be null if the page has been refreshed.\n",
       "if (IPython.notebook.kernel != null) {\n",
       "    IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
       "}\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAj0AAAGtCAYAAAD9H8XfAAAgAElEQVR4nOzdd3gU1d4H8EUgJiS7tASQthQliCCSgBSlCRekSLlcRUFpckVAAVHvpg+EJh0FAQEpBoGXDomIoYTiFRUJgoCAonJpFoKEkt20/b5/DFkypExCkj27e76f5znP87JndzOZ+b3393VyZsYAIiIiIgkYRG8AERERkTMw9BAREZEUGHqIiIhICgw9REREJAWGHiIiIpICQw8RERFJgaGHiIiIpMDQQ0RERFJg6CEiIiIpMPQQERGRFBh6iIiISAoMPURERCQFhh4iIiKSAkMPERERSYGhh4iIiKTA0ENERERSYOghIiIiKTD0EBERkRQYeoiIiEgKDD1EREQkBYYeIiIikgJDDxEREUmBoYeIiIikwNBDREREUmDoISIiIikw9BAREZEUGHqIiIhICgw9REREJAWGHiIiIpICQw8RERFJgaGHyIUoioKqVasW+nNLly7Fli1bSmCLisfMmTORkJBQbN93v/uJiOTG0EPkQu63mbds2RKDBw8u/g0qJlWrVoWiKMX2fQw9RHQ/GHqIXIg7hZ6UlJQCv9eTQk9hfm8ici0MPUQu5N5mnpCQAIPBgP3796NPnz4oV64c6tevj+XLlzve0759exgMBs1YsWKFY37BggUIDAyEl5cX6tevj6VLl2p+ZmZmJkJCQlC5cmWYTCa8/vrrWLRoEQwGA6xWq2Y7du3ahR49eqBcuXIYPXo0AGD69Olo1qwZ/Pz88NBDD6F///64cuWK4/vNZnOO7cv6U1dGRgYmTJiAOnXqwMvLC4899hi2bdum2T6bzYbXX38dJpMJ/v7+CAsLQ2RkZIFCz759+9CuXTuUK1cO5cuXR6dOnfDjjz/muq8BwGq15th/ZrMZ//nPfzBhwgRUr14dRqMRS5cuxYMPPojk5GTN57/88ksYDAYcPXq0wPt///79aN26Nfz8/GAymRAcHIydO3fq/m5EVHgMPUQuJK/Q88gjj2DKlCmIj4/Hyy+/jFKlSuHEiRMAgJMnT+Kxxx5D9+7dcejQIRw6dAh//vknAGDSpEnw8vKCoijYtWsXIiIi8MADD2Dr1q2OnzFjxgyULl0a0dHR2LlzJwYPHoyaNWvmGnpq1qwJRVGwZ88efP311wCAsWPH4pNPPkFCQgI2btyIVq1aoVGjRsjMzAQAJCYmolKlSnj11Vcd25cVFl599VUYjUbMmTMH8fHxGDlyJEqXLo0jR444tm/cuHHw8fHBvHnz8Nlnn6Fbt26oUaOGbuhJSEhAmTJl0K1bN2zatAmfffYZ/vOf/zgCV2FCT7Vq1dClSxfExsZi69atSEpKQtmyZfHJJ59oPj9mzBg0aNDA8W+9/Z+cnAyTyYTBgwdj165d+PzzzzF16lSsXbs239+NiO4PQw+RC8kr9EycONHxmtVqRfny5TFp0iTHa7n9eev69evw8fHB1KlTNa+/+uqrCA4OBqCeaalatSrGjRunec+TTz6Za+h555138t3+jIwMXLx4EQaDAV9++aXj9dz+vHXmzBkYDAasWbNG83qnTp3Qr18/AMDVq1fh7e2NWbNmOeZTU1Px0EMP6YaeVq1aoWXLlrDb7bnOFyb01KhRA6mpqZr3duvWDT179nT82263o3r16oiIiABQsP1/+PBhGAwG3LhxI9/fhYiKB0MPkQvJK/QcOnRI875mzZphxIgRjn/nFnp27twJg8GAs2fPIj093TFWr16NMmXKICMjA7/88gsMBgN2796t+eykSZNyDT25XYF14MABdOjQARUqVMjzT2y5hZ7FixejbNmyuHXrlmb7pkyZgjp16mh+7k8//aT57Kuvvppv6Ll16xZKlSqFhQsX5vmewoSe3NZLrVy5El5eXvj7778d+8FgMOCHH34AULD9f+3aNfj5+eG5555DbGxsjj+XEVHxYughciF5hZ6sdShZ7g05uYWe1atX51hLk31cuHABhw4dgsFgwLFjxzSfXbx4ca6h59SpU5r3/frrr/D19cWzzz6LzZs346uvvsLXX38Ng8GARYsWOd6XW+iZPHlynttWunRpAMDatWthMBhyhIGQkJB8Q8+FCxdgMBjyvYy/sGt67nX9+nV4eXk53vvGG2+gUaNGjvmC7H8A+O9//4vOnTujbNmyKFu2LPr27YtLly7lud1EdP8YeohcSHGGnh07dsBgMGDnzp04fPhwjpGamlroMz33bsdHH32EsmXLaq5o+u233woUehYuXAgvLy98++23uW5f9p97P2d6HnjggXzP9EybNg0VK1bUvHb58uVcQ4/FYsn1O3r16oVu3bohMzMTDz30ECZMmOCYK8j+v3ebN27ciJo1a6JXr155bjcR3T+GHiIXcr+hp23btujfv7/mPdeuXYOPjw9WrlyZ58/La01PixYtChR65s2bB29vb6SlpTlee++993KEnlq1auUIDj/++CMMBgP27duX5/YVdU1Pq1at8lzTExMTA4PBgN9//93x2sqVKwsVej799FOULVsWmzdvzrF/CrL/czN+/Hg88sgjhfoMERUMQw+RC7nf0PPvf/8b1atXd5xVuHr1KgBg6tSp8PX1haIoiI+Px2effYaZM2di+PDhjs9mXb01adIkfPHFFxg8eDBq1KgBg8HgOBuR13YcO3YMDzzwAAYNGoTdu3dj6tSpCAwMzBF6/vGPf6Bx48ZISEjA4cOHHQt3X3vtNfj7+2PWrFnYs2cPtm3bhujoaISEhDg+++abb+a4eqt69eq6oWfv3r0oU6YMevTogS1btuDzzz9HWFiYY13SX3/9BR8fH3Tr1g1ffPEFFixYgCZNmhQq9Ny8eRM+Pj546KGH8Pjjj+eY19v/cXFx6NevH2JiYrBv3z6sXLkSVapU0azXIqLiw9BD5ELuN/T8+uuv6Ny5M0wmU46mvXz5cjz++OPw8vJC5cqV0bZtW6xatcoxn5mZCYvFgkqVKsFoNGLo0KGYNm0aHnzwQd3tyPr+OnXqwMfHBx07dsTp06dzhJ7ExES0atUK5cqV0yyIzszMxIwZM9CgQQN4eXmhatWqjkvDs1itVrz22mswGo2oXLkyLBZLge/Ts2fPHrRp0wbe3t6oUKECOnfujNOnTzvmP/vsMzz66KPw9vZGu3btcOzYsUKFHgDo168fDAYDJk+enOt8fvv/9OnT+Oc//4kaNWrAy8sLtWvXxltvvYXbt2/r/m5EVHgMPUSUQ9++ffHkk0+K3gwiomLF0EMkue+//x5RUVH4/PPPsWPHDowYMQIGg0FzNoiIyBMw9BBJ7qeffkL79u1RoUIFlC1bFoGBgZo/TREReQqGHiIiIpICQw8RERFJgaGHiIiIpMDQQ0RERFJg6CEiIiIpMPToMBgMKFWqFAcHBwcHh0cPg8HzI4Hn/4ZFVKpUKdGbQEREVOJk6HcMPTpkKAIiIiIZ+h1Djw4ZioCIiEiGfsfQo0OGIiAiIpKh3zH06JChCIjo/tjtdqSlpXFwuMXIzMzMt55l6HcMPTpkKAIiKryUlBScOXMGp06d4uBwm3HhwgWkp6fnWtMy9DuGHh0yFAERFY7dbseZM2dw6dIlpKamCv8veA4OvZGamopbt27h3LlzOHv2LOx2e466lqHfMfTokKEIiKhw0tLScOrUKaSmporeFKJCsdlsOHXqFNLS0nLMydDvGHp0yFAERFQ4WaEnt8ZB5Mryq10Z+h1Djw4ZioCICoehh9wVQw/lS4YiIKLC8ZTQk5CQgMqVK+c5v3r1arRt2zbXuU2bNmHq1KmwWq3Fvl0rVqxAcHCw49++vr44depUsX1/9u9TFAX9+vUrtu++9/tdDUMP5UuGIiCiwnGn0JOQkIBOnTrBZDKhYsWKCA4OxocffuiYyy/05GXNmjUoX748goKC0LNnzxxXA61cuRItWrSAyWRCtWrVMHz4cFy/fr3A339v6Ckog8GAH374oVCfKWroMZvNiI2Nve/POxtDD+VLhiIgosJxl9CzdetWGI1GfPjhh0hKSoLdbkdiYiJ69uwJ4P5CT2xsLKpVq4Zvv/0Wt2/fRteuXTFgwADNPWAWLlyIhIQEWK1WJCUloVu3bnjllVcK/DNKKvTkdqk2Q89dMvQ7hh4dMhQB0X27fhH4fi1w7VfRW+JU7hB67HY7zGYz3nvvvTzfkxV6Fi5ciOrVq6Ny5cqYOHGiY/7e8JGQkIB69erhxIkTjtdSU1Pxr3/9C6+//nqeP2fbtm2oW7dunvPnz5/HM888A6PRiJYtWyIiIkLzc7OHmcOHD+PJJ5+E0WiEv78/BgwYAABo3bo1DAYDfHx84Ovri9mzZ+PXX3+FwWDAxx9/jLp168JsNuf4PkVR0KtXLwwePBhGoxGBgYHYuXOn42e3b98e8+fPz7HPAODFF19EqVKl4O3tDV9fX4wdOzbH96empuLdd99FzZo1ERAQgFdeeQV///235ndbtGgRHn30URiNRjz//PO4fft2nvuqqBh6KF8yFAFRoWRmAGd2Ap/2ByZUABQToJQH1rwI/LwHyOX+H57GHULP6dOnYTAYcO7cuTzfk5CQgNKlS2P8+PGw2WxITEyEl5cXvv/+ewD3f8blXuPHj3ecXcpNmzZt8O9//xtWqxXff/89qlWrlmfoadWqFSZPnozMzExYrVZ8+eWXub4PgCP09OvXD9evX0dKSkqO9ymKgtKlS2PFihVIT0/H2rVrUa5cOVy5cgVA/qEHyP1Mz73f37RpU1y4cAHJycl47rnn8MILL2je26lTJ/z111+4evUqGjZsiPfff7+Ae7bwGHooXzIUAVGBXTgMzGl8J+iYgJkNgG1vALMC7742v7n6Pg+Wa+OY0xiYVqvkx5zGBdrGL7/8EgaDId+FxlmhJ/t7WrRogRUrVgAontCzY8cOmEwmHD9+PNf58+fPw2AwICkpyfFaSEhInqGnXbt2GDFiBC5evJjju/IKPff+yeveUPL4449r5lu1aoVFixYBKHroqV+/PjZu3OiY+/HHH1GqVCnHPjcYDNi1a5dj/t1338XgwYNz/G7FhaGH8iVDERAVyPULwIyH1WCzqjdwajuQced/ODPSgB82AR8/q85Prwf8/T+x21uC3CH0/PjjjwU603Pvmp7sTb6ooWfPnj2oVKkSdu/ened7Dh06BD8/P81rixYtyjP0/Pzzzxg4cCACAgLQqFEjfPzxx7m+D7gbem7cuKH5/ntDz71nofr374+IiAgARQ893t7e+O677xxzVqtVc1zu3eaSuJosO4YeypcMRUCkK/U2sLitGmji3s7/vZ+9q75vcVv1cx7IHf68lbWmZ/r06Xm+pyRDz549e1CxYkXN+pjcZJ3puXbtmuO10NDQPENPFrvdjj179qBMmTL46aefAKj/e51b6Ll586bms3pnelq3bu0409OjRw/NPlyzZo1mn9WtW7fIZ3oYepynxEOPzWbD8OHDUadOHfj5+aFhw4aOU6cAkJycjP79+8PPzw/VqlXDrFmzNJ+/ePEiunbtinLlysFsNmP16tWa+ZMnT6J169bw8fFBw4YNER8fr5k/ePAgmjRpAh8fHwQHByMxMbFQ2y9DERDly24HNgxVg8yKHnfP7uQlIw1Y2VN9/4ahHrnGxx1CD6BevWUymbB48WJHqDh27Bh69eoFoORCT0JCAipUqIC4uLgCvb9169YYMWIErFYrjh8/joceeijP0LNq1Sr88ccfAIAjR46gbNmy+OWXXwAA1apVw9atWx2fK2joKV26NFatWoX09HT83//9H8qVK4fLly8DACIiIvDkk0/ixo0buHjxIlq0aKHZZ61atcK8efPy/P6oqCg0a9YMFy9eRHJyMvr06YPnn38+1/dmbQ9DT8kp8dBz69YtREZG4ueff4bdbsehQ4dQoUIF7NmzBwAwaNAg9OrVC8nJyTh+/DgCAgKwfft2x+fbtWuHkSNHIiUlBQkJCfDz88PRo0cBqAevfv36mDJlCmw2G9atWwej0ehYgJaUlISKFSti1apVsNlsmD17NmrUqFGom2nJUARE+TowSw0wc5sAt5P03w+o75vbRP3cwTklu30CuEvoAe7ep8doNKJixYpo3rw5Fi9e7JgridDToUMHPPDAA/D19dWMvPz666/o0KED/Pz8dK/eevnll1GlShX4+vri4YcfxrJlyxzvW7JkCR566CGUL18ec+fOLXDoyX71VoMGDbBjxw7He5OSkvDss8/Cz88PTZs2xdy5czX7bPv27TCbzShfvjzeeuutHN9vs9kwfvx4VK9eHf7+/hg4cKBm/RJDj3MJ+fNW3759MXHiRNy+fRteXl44duyYYy4sLAx9+vQBoP7ttkyZMpoCGTBgAMaNGwcA2L17N/z9/ZGRkeGYb9OmjSN1L1u2DM2aNXPM2e121KxZU/NfAnpkKAKiPJ1LUK/MmlId+P1k4T77+wlg8kPq53/Ke02HO3Kn0EOUHUOPk1mtVtSoUQMbN25EYmIiSpcurbmp1fr16/Hwww8DADZv3ow6depoPj9jxgx07twZADBnzhx06NBBMz9q1CgMHz4cADBmzBgMGTJEM9+9e3dMnjy5wNsrQxEQ5cpuv7uO54dN9/cdJzarn/+wFZDt/8/dHUMPuSuGHiey2+0YOHAgOnTogMzMTBw4cADly5fXvCc+Ph5Vq1YFAHzyySdo2rSpZn7JkiVo2bIlACA6Ohq9e/fWzIeFhaF///4AgGHDhjluFpVlwIABsFgseW7jhAkTUKpUKccwGLjWmyR1+nM1sHzU4f7X5djtd6/oOrG5eLdPIIYeclcMPU5it9sxYsQING/e3PEMlqwzPfZs/4O6YcMGzZmee+/iOXPmTM2Zno4dO2rmR48erTnTM3ToUM18jx49eKaHSI/dDnzUXg0rZ74o2nf9sl/9ngUtPeZsD0MPuSuGHiew2+0YOXIkmjVrprksMWtNT/abVoWHh+e7pmfgwIGaNT0BAQGaP4899dRTmjU9QUFBmu2oVasW1/QQ6Tmz885ZnvbFc/XV8u53/ky2Uf+9boChh9wVQ48TjBo1Co8//jiuXr2aY+6VV15B7969cePGDfzwww+oWrWq5uqttm3bYtSoUUhJScH+/ftzvXpr2rRpsNlsWL9+PYxGo+NSw6yrt2JiYpCamoq5c+fy6i0iPXa7+ictxaT+ias4/HLgzt2aW6iPsXBzDD3krhh6Sthvv/0Gg8GABx98UHPp4ogRIwCo9+l54YUX4Ofnh6pVq+Z6n54uXbrAx8cHtWvXznGfnhMnTqBVq1bw9vZGYGBgjvv0HDhwAI0bN4a3tzeCgoJw5MiRQm2/DEVApHE2/s7NBdsBdjvMlrgc476s6KF+7/ENxbu9AjD0kLti6KF8yVAERA52O7DkmTtnedR7leQWeu4rBP365d1nc7n52R6GHnJXDD2ULxmKgMjhp913HyFxZy1PsYUe4O6dmo+tL6FfwDkYeshdMfRQvmQoAiKHNS+poeTk3cX+xRp6fj2ofv+yf5TAxjsPQ4/rKOwdjLM/IHTKlCl4+eWX7+vnjhgxAmFhYQDyftxFUWT//uLE0EP5kqEIiACoj46YWBmYXlfzfK1iDT12O/B+MzX4XP25BH4J58ircRRkXxV1FEb79u1hMBiQkJCgeT06OhoGgwGKohRxT4hXlNBTXD+jqKGnpB89kR1DD+VLhiIgAgB8s0QNI5+9o3m52Bvz/hnqz9kdXYK/TMlyp9ATGBiIwYMHO16z2+2oV68eGjZs6HKhJz09vdCfYegpHIYeypcMRUAEAFjaSQ0jF77TvFzsjfnv/6nP45rdyG1vVuhOoWfixImoVKmSoyHv27cPLVq0QL9+/TSh5/Dhw2jbti0qVKiABg0aYM2aNZq5Nm3aoEKFCggICMDgwYNx48YNx/zMmTNRs2ZN+Pn5oW7duli7di2A3Jt59gdsDh48GMOHD0ffvn3h5+eHpUuXwm63Y/bs2XjkkUdQoUIFdOnSxfEUdUB9SnyLFi3g5+eHrl27YvTo0fkGhqxblfj7+2Pq1Kma0JN9++x2O9555x1UqVIFRqMRgYGBSEhIQGxsLMqWLYvSpUvD19fX8bDRwYMH4+233wZwN/QsXboUtWvXRuXKlTF+/HjHcyFze3Br1nYU5PsBYMeOHWjatClMJhOaN2+OL7/80jE3ePBgvPbaa+jXrx/8/PzQqFEjfPPNN7nuD4YeypcMRUCEqz+rgeeD4Bw3IyyRRr3yOfXnnUtwyq9X3Nwp9MyfPx/PP/88li9fDgAYNGgQFi5cqAk9ly9fRsWKFbFx40ZkZGTgu+++Q6VKlRy3+EhMTMSXX36JtLQ0XLp0CS1atMA776hnBE+fPg0fHx+cPn3a8V0nT6oPpy1I6ClXrhx27doFu92OlJQUfPDBB3jiiSdw7tw5pKenIzo6Gk888QQyMzORlpaGOnXqIDo6Gqmpqdi7dy98fX3zDD3x8fGoWLEiDh8+DJvNhjfffBOlS5fONfTs3LkTNWvWdNzn7ZdffsG5c+fy/D1yCz29evVCcnIyfvvtNzzyyCN4//33AeQfegry/WfPnoW3tze2bduG9PR0rFq1CiaTCX/88YfjvUajEfv370dGRgYsFovmYdvZMfRQvmQoAiLsmayGkP0znNOov1+r/rxNrzn/dy0G7hZ6duzYgbZt2+LGjRuoXLky/v77b03omT59Ov71r39pPjtq1Ci8++67uX5vTEwMmjdvDkC9c763tzc2b96MlJQUzfsKEnrunX/00UcRF3f398zMzISfnx9OnjyJ/fv3o1KlSo4zKADw4osv5hl6hg4dijFjxjj+fevWLZQpUybXsLF37174+/tj9+7dOY5rQUNPYmKiY37x4sWO50QWNfRMmjQJPXv21My3bNkSixcvdrx34MCBjrmTJ0+idOnSmv2UhaGH8iVDEZDk7HZgbhM1hFz7zTmNOvUWMKU6MLkaYLuRc97FuVvoycjIQI0aNRASEoIXX3wRADShZ+TIkXjwwQdRvnx5x/D19XVc2XTmzBn07NkT1apVg9FohK+vL+rUqeP4OevWrUO7du1gNBrRvXt3/PjjjwAKFnrGjx+vmffx8YHRaNRsi7e3N7744gusXbsWjRs31rzfYrHkGXq6du2a44a3VatWzTNsLFiwAC1atED58uXRv39/XLp0Kc/fI7fQk/2pA59//jlq1qwJoOih5/XXX8cbb7yhme/fvz8iIyNzvDf79uS2xoihh/IlQxGQ5H77Sg08y7sBKJnGnasto9SfmxjjxF+2eLhb6AGAkJAQlCpVCl98oT5ANnvomTZtmuZMwb2eeeYZvPHGG46HRcfExMBsNud4361btzBq1Cg8/fTTANS1Pt26dXPMX758OUfoyd6sASAwMBC7du3KdTtyO9Pz0ksvFcuZnuyuXbuGPn36OELfxIkTC32m56OPPnKc6dmwYQMeffRRx1xGRgbKlSvn2A697y/ImR6GnoJh6NEhQxGQ5LaPUcPHdysBODH0ZN2heXm33OddmDuGnqtXr2L37t2OBzRnDz0XLlxAQEAAtmzZgrS0NKSlpeHw4cM4duwYAKBFixYIDQ2F3W7HL7/8gqCgIEfoOX36NHbt2gWr1Yr09HS8++67aN++PQD1odAmkwlnz57F7du3MXz4cN3QM2/ePLRq1Qpnz54FAFy/fh0bNmxAeno60tLSULt2bUyePBlpaWnYt28f/Pz88gw9O3fudKxNstlsGDt2bJ5rer799lt89dVXSE1NhdVqxUsvveS46m3x4sVo3ry5JmzlFnr69OmD5ORknD9/HoGBgY6HX589exZlypRxfH94eLhmO/S+/8yZM/D29kZsbCzS09OxevVqGI1G/P7777nuR4aevDH06JChCEhiaVYkR1WDLaoyGlvWO7dRZ2be/bNa0i+5v8dFuWPoude9V29999136NSpEypXroxKlSqhffv2+PrrrwEABw8exKOPPgpfX1+0aNEC06ZNc4SeY8eO4cknn4Sfnx/Kly+Pjh07Ov68BQBjx45FhQoVUKtWLXz66ae6oSczMxMffPABGjZsCKPRiJo1a+Lll192BIKjR48iODgYvr6+6NKli+7VW7NmzUL16tXh7++PKVOm5Plnpd27d+Pxxx+Hn58fKlasiF69euHKlSsA1IdXt2vXDhUqVEDVqlVzbPu9V29VqlQJY8eO1VyCP336dPj7+6NKlSqYNWuWZjv0vh8AYmNj0aRJExiNRgQHB2P//v2OOYaegmPo0SFDEZDETmwBFBNiI7qIadQJ09TQs3eq837nYsA7MpO7YuihfMlQBCSx9UMAxYRXQyeKCT1Zl8ovbOO837kYMPSQu2LooXzJUAQkqYx0YFotWKMqI9CyySl/msk1BC140nHlmLtg6CF3xdBD+ZKhCEhSdxYS745o79TAkyP07FLU0PP1YhF74b4w9JC7YuihfMlQBCSp+EhAMSE8bKzY0PO/b9TQs6qXmP1wHxh6yF0x9FC+ZCgCktSdPyu1tqwUG3oyM4AZ9dUnvFuvi9kXhcTQQ+6KoYfyJUMRkISu/aaeXfmwtdMDT47QA9y9UeEPm5y/L+5DVuNITU0VvSlEhWKz2Rh6KG8yFAFJ6JslasjYpbhG6DkVq27PxuFO3xX3w26348yZM7h06RJSU1MdN/Tj4HDVkZqailu3buHcuXM4e/Ys7Pc8WBiQo98x9OiQoQhIQjH/VEPGb1+5RuhJvQVEBwDTagEZ7vEno5SUFJw5cwanTp3i4HCbceHCBc1NE7OTod8x9OiQoQhILg0tG2GLqoxrUdVRz7JNSOjJNQStfl4NYr8cELuDCsFutwv/L3gOjoKOrEeQ5EWGfsfQo0OGIiC5DAudCCgmbIl4VnjY0YSew8vV0PN5qNgdRCQpGfodQ48OGYqA5LI6vC+gmPBmaJjwsKMJPcmX1dAzrymQy3oDIipZMvQ7hh4dMhQBScRux/kULAoAACAASURBVKWoOsiIKo/HLeuEhx1N6AGAjzqowefP0+L2EZGkZOh3DD06ZCgCksiV44BiwjeRLYQHnVxDz74Zaug5OEfcPiKSlAz9jqFHhwxFQBLZPxNQTJgW9prwoJNr6Ll8TA09y7uJ20dEkpKh3zH06JChCEgiK3oAignPhnwoPOjkGnoyM4Hp9dS7M6feErefiCQkQ79j6NEhQxGQJNKswKQquBZVHXUs24UHnVxDDwBsGKqe7flpl5j9RCQpGfodQ48OGYqAJPHrQUAx4fOITsJDTr6h57uVauj5IlzMfiKSlAz9zimhZ/78+QgODoaXlxf69evneP38+fPw9fXVjFKlSuHNN9+8u4EGA3x8fBzzHTt21Hz3wYMH0aRJE/j4+CA4OBiJiYma+c2bN6N+/frw8fFBhw4d8MsvvxRq22UoApLE3qmAYkJU2JvCQ06+oefar2roWfS0kN1EJCsZ+p1TQs+mTZuwZcsWjB49WhN67nXt2jU8+OCDOHjw4N0NNBjwww8/5Pr+pKQkVKxYEatWrYLNZsPs2bNRo0YNWK1WAMDp06fh5+eHL774AikpKRg3bhyCg4MLte0yFAFJYnk3QDHhHyGLhIecfEMPAMx7XA0+t646fz8RSUqGfufUP28pipJv6FmwYAEeeeQRzWv5hZ5ly5ahWbNmjn/b7XbUrFkTW7duBQBERESgb9++jvkbN27gwQcfxPfff1/gbZahCMizmS1xaGDZDFtUJVyNqgGzJVZ4yNENPdveVEPPic3O32FEkpKh37lU6AkODsbUqVM1rxkMBlSrVg0BAQHo2rUrjh075pgbM2YMhgwZonl/9+7dMXnyZABAr169MGHCBM18o0aNsHr16gJvswxFQJ7NbInDi6HTAcWEuIjOwgNOgULPD5vU0LN9jPN3GJGkZOh3LhN6jh07htKlS+PSpUua1xMSEmCz2XDz5k1ER0ejSpUquHpVPeU9bNgwjB07VvP+AQMGwGKxAACeeeYZzJ07VzPfpk0bLFq0KM9tnDBhAkqVKuUYBgPXepN7M1vi8H74IEAxITxsrPCAU6DQc+uvu4+kICKnYOgpZvmFnnHjxqF79+6639GgQQNs2LABgHqmZ+jQoZr5Hj16aM70TJw4UTP/2GOP8UwPScVsicM3kS0AxYRnQj4SHnAKFHoAYNFTavC59ptzdxiRpGTody4RetLS0uDv7+8IM/lp2LAh1q9fD0Bd0xMUFOSYs9vtqFWrlmZNzz//+U/H/M2bN+Ht7c01PSSVQMsmpEZVxJ9RteCK63nyDD07w9TQc2SVc3cYkaRk6HdOCT3p6emwWq0IDw9H3759YbVakZqa6pjftGkT/P39Na8BwIkTJ3DkyBGkp6cjJSUFU6dORaVKlfDHH38AuHv1VkxMDFJTUzF37txcr97atWsXrFYrxo8fz6u3SDoDQ6cBignbI7oIDzeFCj1nd6mhZ8PQ3OeJqFjJ0O+cEnoURYHBYNCM9u3bO+Z79uyZY20OAOzduxcNGzaEr68vKlWqhM6dO+O7777TvOfAgQNo3LgxvL29ERQUhCNHjmjmN23ahHr16sHb2xvt27fnfXpIOgvCXwYUE0LD3hIebgoVglJvqY+jmF5PfTwFEZUoGfodV+nqkKEIyLN9FxkMKCZ0CFkqPMwU+szPnXsL4Urut60gouIjQ79j6NEhQxGQB7PdRFpURfweVRuuup4n39CT8J4aer5aIG4fEklChn7H0KNDhiIgD3ZnXcyWiGeFB5n7Cj3nD6mhZ/Xz4vYhkSRk6HcMPTpkKALyYPFRgGLCf8LeFh5k7iv0pKcCk6oC02pxXQ9RCZOh3zH06JChCMiDLevidut5NKEHAFb04LoeIieQod8x9OiQoQjIQ6XbgOgAl33eVoFDz94pauj5ZomY/UgkCRn6HUOPDhmKgDzU/74FFBPiIzoKDzFFCj0/71VDz/ohuf+eRFQsZOh3DD06ZCgC8lD/nQ8oJkwLe014iClS6LHdBCZUBGYFAna7mH1JJAEZ+h1Djw4ZioA81LqBgGLCv0JmCQ8xRQo9APBRB/VsT1Lhbi5KRAUnQ79j6NEhQxGQB7LbgZmPABMroYFls/AQU+TQk/UcrqOfOn9fEklChn7H0KNDhiIgD3TtVzUkLHG/9Ty5hp5Tservs3W003clkSxk6HcMPTpkKALyLGZLHMaEhgCKCcvC+wsPMMUSgm5dVUPPB0Gidy+Rx5Kh3zH06JChCMizmC1xWBXeD1BMGBkaITywFNuZn/kt1OBz8w+xO5jIQ8nQ7xh6dMhQBORZzJY4nIhsAigmPGn5RHhgKbbQs32MGnpObhW7g4k8lAz9jqFHhwxFQJ6lkWUDMqLK40JUPeFhpVhDz/fr1NCzwyJ2BxN5KBn6HUOPDhmKgDzLgNBpgGLCVjd7yKhu6Pn7vBp6FrcVu4OJPJQM/Y6hR4cMRUCeZXbYMEAxITLsTeFhpVhDDwDMbgRMqABYk8XtYCIPJUO/Y+jRIUMRkGfZF/E0oJjQPWS+8LBS7KFn46vq2Z6fdonbwUQeSoZ+x9CjQ4YiIA+SmYnkqKq4HRWAepZtwsNKsYeeb5epoWd3tLh9TOShZOh3DD06ZCgC8iC/nwQUE/4b0Up4UCmR0PPHKTX0LO8ubh8TeSgZ+h1Djw4ZioA8yOHlgGLCB+GDhAeVEgk9mZnAtFrA5GpARrq4/UzkgWTodww9OmQoAvIgm18HFBOGhE4SHlRKJPQAQMw/1bM9l46K2cdEHkqGfsfQo0OGIiAPMr85oJjQ1LJWeFApsdCT8J4aer7+SMw+JvJQMvQ7hh4dMhQBeQjrdUAx4dfIR4SHlBINPT/vUUPPxlfF7GciDyVDv2Po0SFDEZCHOJfgcTclzDX0WJMBpTwwt4mIvUzksWTodww9OmQoAvIQB2YBigkTw0YLDyklGnoA4MNWfPgoUTGTod8x9OiQoQjIQ6wdACgm9A2ZIzyklHjo2famGnpOxTp/PxN5KBn6HUOPDhmKgDzErEBgYiU0sGwWHlJKPAQlxqihJz5S9F4n8hgy9DuGHh0yFAG5N7MlDk9aPgEUE45HPi48kDgl9Px5Rg09Hz8revcTeQwZ+p1TQs/8+fMRHBwMLy8v9OvXTzPXvn17eHl5wdfX1zFsNptj/uLFi+jatSvKlSsHs9mM1atXaz5/8uRJtG7dGj4+PmjYsCHi4+M18wcPHkSTJk3g4+OD4OBgJCYmFmrbZSgCcm9mSxxeC1UAxYSY8L7CA4lTQk9mJjCtNjCpCpCRJvoQEHkEGfqdU0LPpk2bsGXLFowePTrX0DN//vw8P9uuXTuMHDkSKSkpSEhIgJ+fH44eVW9KlpaWhvr162PKlCmw2WxYt24djEYjrly5AgBISkpCxYoVsWrVKthsNsyePRs1atSA1Wot8LbLUATk3syWOCwMHwgoJrwT9o7wQOKU0AMAMf3Usz0XvxN7AIg8hAz9zql/3lIUpVCh5+eff0aZMmWQlJTkeG3AgAEYN24cAGD37t3w9/dHRkaGY75NmzaYN28eAGDZsmVo1qyZY85ut6NmzZrYunVrgbdZhiIg92a2xOG/EerVTJ1DFgsPJE4LPfumq6Hn0CKxB4DIQ8jQ71wi9FSuXBmVKlVCcHAwNm3a5JjbvHkz6tSpo3n/jBkz0LlzZwDAnDlz0KFDB838qFGjMHz4cADAmDFjMGTIEM189+7dMXny5AJvswxFQO6trmU7bkRVxc2oKqhr2S48kDgt9JxLUEPPhqEidz+Rx5Ch3wkPPYcOHUJycjLS0tKwfft2+Pr6Yt++fQCATz75BE2bNtW8f8mSJWjZsiUAIDo6Gr1799bMh4WFoX///gCAYcOGYezYsZr5AQMGwGKx5LmNEyZMQKlSpRzDYOBab3JtnUIWA4oJX3nYk9V1Q4/tBjChAjCnsdgDQOQhGHqKWW6h516vvfYaRo8eDUA901O3bl3N/MyZMzVnejp27KiZHz16tOZMz9Ch2v8K7NGjB8/0kEd5O+xdQDFhUfhA4WHEqaEHABa2Uc/23Lgi7gAQeQgZ+p3LhZ7XX38do0aNApD7mp6BAwdq1vQEBAQgMzPTMf/UU09p1vQEBQU55ux2O2rVqsU1PeRRPglXnzo+IjRKeBhxeujZPlYNPSe3iTsARB5Chn7nlNCTnp4Oq9WK8PBw9O3bF1arFampqfj777+xY8cOpKSkICMjAzt27ICvry927drl+Gzbtm0xatQopKSkYP/+/blevTVt2jTYbDasX78eRqMRly9fBnD36q2YmBikpqZi7ty5vHqLPM6xyKaAYkJLyyrhYcTpoefop2ro+SJc3AEg8hAy9DunhB5FUWAwGDSjffv2+PPPP9GiRQsYjUaYTCY88cQTWLt2reazFy9eRJcuXeDj44PatWvnuE/PiRMn0KpVK3h7eyMwMDDHfXoOHDiAxo0bw9vbG0FBQThy5Eihtl2GIiA3lmZFWlRF/B5VG2ZLrPAw4vTQ89dPauhZ9g9xx4DIQ8jQ77hKV4cMRUBu7H/fAooJX0R0FB5EhIQeux14z8ybFBIVAxn6HUOPDhmKgNzYoUWAYsL0sOHCg4iQ0AMAMeqaJlw6KuYYEHkIGfodQ48OGYqA3NjG4YBiwoDQacKDiLDQs3eqGnq+XSrmGBB5CBn6HUOPDhmKgNzYB0GAYkITyzrhQURY6Dkbr4aeza+LOQZEHkKGfsfQo0OGIiA3Zb0OKCb8EvmI8BAiNPTcTlJDz/zmYo4DkYeQod8x9OiQoQjIvWQ1/v6hMwDFhG0RXYWHEKGhBwDef0INPil/O/+AEHkIGfodQ48OGYqA3EtW458c9jqgmDApbKTwECI89NxZ24Sf9zj/gBB5CBn6HUOPDhmKgNxLVuPfHtEFUEx4IWSm8BAiPPTcuYoN+2Y4/4AQeQgZ+h1Djw4ZioDcS1bj/zXyEWRGlcdjlvXCQ4jw0HPhsBp6Pn3B+QeEyEPI0O8YenTIUATkXsyWODSxrAMUE36KbCg8gLjCQLoNiPYHptdTb1hIRIUmQ79j6NEhQxGQezFb4jAgdBqgmLA5opvwwOEKAwCwpKN6tufar0KPD5G7kqHfMfTokKEIyL2YLXF4L+w1QDFhYtho4YHDFQYA4LN31dBzfIPYA0TkpmTodww9OmQoAnIvZkscPovoDCgm9AuZJTxwuMIAABz7PzX0fB4i9gARuSkZ+h1Djw4ZioDci9kSh/9F1kdGVHk8atkoPHC4wgAAXP1ZDT1LO4s9QERuSoZ+x9CjQ4YiIPfyhGUNoJhwOrKR8LDhKgPAnSeu1wGiA4D0VLEHicgNydDvGHp0yFAE5F5eCZ0CKCZsiOgpPGy4ynCI6aee7bl4RNwBInJTMvQ7hh4dMhQBuZcZYerdhyPD3hQeNlxlOCSoV7XhmyXiDhCRm5Kh3zH06JChCMi97Ix4BlBM6BMyV3jYcJXhcHbXnSeujxB3gIjclAz9jqFHhwxFQO7lUlQdpEdVQAPLZuFhw1WGQ9YT1z8IFneAiNyUDP2OoUeHDEVAbuTG74BiwqnIxsKDhisNjfeb8YnrRPdBhn7H0KNDhiIgN3JmJ6CYsC68l/Cg4UpDw/HE9b1ijhGRm5Kh3zH06JChCMiNJLwHKCaEh40VHjRcaWhkPXF9/0wxx4jITcnQ7xh6dMhQBORGPu0PKCb0CpknPGi40tD437dq6FnzkphjROSmZOh3DD06ZCgCcm3Zm/vvUbWRFlWRi5jzGQ0sm4GJlYCZj/CJ60SFIEO/Y+jRIUMRkGvLaubNLTGAYsKJyCbCg4WrDyxup57tuX5R9OEjchsy9DuGHh0yFAG5tqxGPjQ0GlBMWMtFzPqhJ/YtNfSc3Cb68BG5DRn6HUOPDhmKgFxbViOfEzaUi5gLGnqOfqqGnvhI0YePyG3I0O8YenTIUATk2rIaeXxEBy5iLmjo+fO0GnpW9BB9+Ijchgz9jqFHhwxFQK4tq5FfiTJzEXNBQ09mJjClBjClOpCZIfoQErkFGfodQ48OGYqAXJvZEofmltWAYsJJLmIuWOgBgJU91bM9f5wSewCJ3IQM/c4poWf+/PkIDg6Gl5cX+vXr53j9jz/+wIABA1CjRg0YjUY0a9YMcXHae26YzWZ4e3vD19cXvr6+qFevnmb+5MmTaN26NXx8fNCwYUPEx8dr5g8ePIgmTZrAx8cHwcHBSExMLNS2y1AE5NrMljgMCZ3EOzEXNvTsUtTQkxgj8vARuQ0Z+p1TQs+mTZuwZcsWjB49WhN6zp07h5kzZ+LChQvIzMzE9u3b4evri9OnTzveYzabERsbm+v3pqWloX79+pgyZQpsNhvWrVsHo9GIK1euAACSkpJQsWJFrFq1CjabDbNnz0aNGjVgtVoLvO0yFAG5NrMlDrPDhnERc2FDz6ntauiJHSf2ABK5CRn6nVP/vKUoiib05KZZs2ZYtWqV49/5hZ7du3fD398fGRl3/2bfpk0bzJs3DwCwbNkyNGvWzDFnt9tRs2ZNbN26tcDbLEMRkGszW+IQH9ERUEzozUXMBQ89yZfU0LO4rdgDSOQmZOh3LhV6/vjjD3h7e+Pw4cOO18xmM6pUqYLKlSvj6aefxr59+xxzc+bMQYcOHTTfMWrUKAwfPhwAMGbMGAwZMkQz3717d0yePLnA2yxDEZBrM1vicDmqDtKjKnARc2FCDwDMClTvzpyWIu4AErkJGfqdy4Qem82Gjh07YtCgQZrXDx48iNu3b8NqtWLZsmXw9fXFmTNnAADR0dHo3bu35v1hYWHo378/AGDYsGEYO3asZn7AgAGwWCx5buOECRNQqlQpxzAYuNabxAq2qPecORXZWHiYcJfhsHaAerbnf9+IO4BEboKhp5jlFXpSU1PRs2dP9OjRA6mpqfl+R5cuXTBzpvr05Dlz5qBjx46a+dGjR2vO9AwdOlQz36NHD57pIbcy+M4i5v8Lf054mHCX4XBglhp6Di0UdwCJ3IQM/U546ElNTUWvXr3QtWtX2Gw23e949tlnMWPGDADqmp6AgABkZmY65p966inNmp6goCDHnN1uR61atbimh9zKrDuLmCPCxggPE+4yHM4lqKFn46uiDh+R25Ch3zkl9KSnp8NqtSI8PBx9+/aF1WpFamoq0tLS0Lt3b3Tq1CnXK6rOnz+PAwcOON67cuVK+Pj44OTJkwDuXr01bdo02Gw2rF+/HkajEZcvXwZw9+qtmJgYpKamYu7cubx6i9zOF3cWMfcJmSs8TLjLcLBeB5TywLym4g4gkZuQod85JfQoigKDwaAZ7du3x759+2AwGDT34fH19cWUKVMAqPfgadq0KXx9fVGhQgW0bt06x314Tpw4gVatWsHb2xuBgYE55g8cOIDGjRvD29sbQUFBOHLkSKG2XYYiINd2iYuY7z/0AMD8FurZnttJYg4gkZuQod9xla4OGYqAXNjNP+8sYn5MeJBw17Eh4s6dmc/G6+9vIonJ0O8YenTIUATkWrI37MGhkwHFhPXhPYWHB3cd4WFj1dCTME30oSVyaTL0O4YeHTIUAbmW7A17ZtirgGJCZNibwsODu44eIR+ooScm/xujEslOhn7H0KNDhiIg15K9Ye+MeAZQTOgbMkd4eHDXUd+yFYgOAN6rA9jtog8vkcuSod8x9OiQoQjItWRv2Bej6iIjqjwCLZuEhwd3HljaWT3bk3RO9OElclky9DuGHh0yFAG5lqxGHXTnTsw/chFz0UPPDosaeo5vEH14iVyWDP2OoUeHDEVAriWrUWctYt4QwUXMRQ49xzeooWdH3o+gIZKdDP2OoUeHDEVAriWrUXMRczGGnqRzauhZ2ln04SVyWTL0O4YeHTIUAbmWrEbNRczFGHrsdnUhc3QAkJ7/8/2IZCVDv2Po0SFDEZBryWrUl6LqcBFzcYUeQL1kXTEBlxLFHmAiFyVDv2Po0SFDEZBrMVvuLmLmnZiLMfQkTFNDz7dLxR5gIhclQ79j6NEhQxGQazFbeCfmEgk9Z+PV0LP5dbEHmMhFydDvGHp0yFAE5FrMljjMChvGRczFHXpuJ6mhZ34LsQeYyEXJ0O8YenTIUATkWsyWOHwR0RFQTOgTMld4YPCE4TCvKaCUB6zXxR1gIhclQ79j6NEhQxGQazFb1EXM6VEV0MCyWXhg8IThsFG9DQDOJYg6vEQuS4Z+x9CjQ4YiINcSzEXMJRd6Di1UQ8/+meIOMJGLkqHfMfTokKEIyLUMDp0EKCb8X/hzwsOCpwyH/32jhp41L4k7wEQuSoZ+x9CjQ4YiINeStYg5ImyM8LDgKcMhzQpMrAzMeJhPXCe6hwz9jqFHhwxFQK6Fi5hLMPQAwEft1bM9f58XcXiJXJYM/Y6hR4cMRUCu5TIXMZfoWBH+LzX0/LBJ9KEmciky9DuGHh0yFAG5kJt/3FnE3Fh4OPDUMSY0RA09n4eKPtpELkWGfsfQo0OGIiAXcuYLLmIu4dE25GM+cZ0oFzL0O4YeHTIUAYmVvSFnLWIODxsrPBx47ogFpte988R1m+jDT+QyZOh3DD06ZCgCEit7Q46/s4i5d8g8FwgHnjvw6Qvq2Z4L34k+/EQuQ4Z+x9CjQ4YiILGyN+MrUWYuYnZG6Nk3Qw09Xy8WffiJXIYM/Y6hR4cMRUBiZTXiFpYYQDHhRGQT4aHA0wd+3quGno2vij78RC5Dhn7H0KNDhiIgsbIa8auhEwHFhE/DewsPBZ4+YL2uPnh03uOiDz+Ry5Ch3zH06JChCEisrEb8fvggQDEhJOwt4aHA0wcAYEFL9WzPzT/FFgCRi5Ch3zH06JChCEisrEacENEWUEzoHrJAeCjw9AEA2DpaDT2nd4gtACIXIUO/c0romT9/PoKDg+Hl5YV+/fpp5pKTk9G/f3/4+fmhWrVqmDVrlmb+4sWL6Nq1K8qVKwez2YzVq1dr5k+ePInWrVvDx8cHDRs2RHx8vGb+4MGDaNKkCXx8fBAcHIzExMRCbbsMRUBiqY04FklR1WGLqoz6lq3CQ4GnDwDAdyvU0LM7WujxJ3IVMvQ7p4SeTZs2YcuWLRg9enSO0DNo0CD06tULycnJOH78OAICArB9+3bHfLt27TBy5EikpKQgISEBfn5+OHr0KAAgLS0N9evXx5QpU2Cz2bBu3ToYjUZcuXIFAJCUlISKFSti1apVsNlsmD17NmrUqAGr1VrgbZehCEgssyUOT4UsBxQTEiODhAcCGQYA4PcTauhZ+ZzYAiByETL0O6f+eUtRFE3ouX37Nry8vHDs2DHHa2FhYejTpw8A4Oeff0aZMmWQlJTkmB8wYADGjRsHANi9ezf8/f2RkZHhmG/Tpg3mzZsHAFi2bBmaNWvmmLPb7ahZsya2bt1a4G2WoQhILLMlDqNCIwDFhBXh/xIeCGQYAIDMDGBKdWBKDfX/JpKcDP1OaOhJTExE6dKlkZmZ6Xht/fr1ePjhhwEAmzdvRp06dTTfMWPGDHTurN4+fs6cOejQoYNmftSoURg+fDgAYMyYMRgyZIhmvnv37pg8eXKBt1mGIiCxzJY4LAofACgmvBX6H+GBQIbhsLKnerbn95PiCoDIRcjQ74SGngMHDqB8+fKa98THx6Nq1aoAgE8++QRNmzbVzC9ZsgQtW7YEAERHR6N3796a+bCwMPTv3x8AMGzYMIwdO1YzP2DAAFgsljy3ccKECShVqpRjGAxc600ly2yJw1cRrQDFhGdCPhIeCGQYDrvV2wTgu5XiCoDIRTD0FLO8zvTY7XbHaxs2bNCc6albt67mO2bOnKk509OxY0fN/OjRozVneoYOHaqZ79GjB8/0kEupY9mOG1FVcTOqCupatgsPBDIMhx8/U0PPtjfEFQCRi5Ch37nEmp7jx487XgsPD893Tc/AgQM1a3oCAgI0fx576qmnNGt6goKCHHN2ux21atXimh5yKc+EfAQoJhyKbCk8DMgyHG7+oYaeBS3FFQCRi5Ch3zkl9KSnp8NqtSI8PBx9+/aF1WpFamoqAOCVV15B7969cePGDfzwww+oWrWq5uqttm3bYtSoUUhJScH+/ftzvXpr2rRpsNlsWL9+PYxGIy5fvgzg7tVbMTExSE1Nxdy5c3n1FrmccaEWQDFhcfhLwsOAjOO3yIfVuzNbr4suBSKhZOh3Tgk9iqLAYDBoRvv27QGo9+l54YUX4Ofnh6pVq+Z6n54uXbrAx8cHtWvXznGfnhMnTqBVq1bw9vZGYGBgjvv0HDhwAI0bN4a3tzeCgoJw5MiRQm27DEVAYi0Pfx5QTBgdGi48AMg4NkV0V8/2/LRLdCkQCSVDv+MqXR0yFAGJdSQyCFBMeDrkY+EBQMYRHjZWDT17p4guBSKhZOh3DD06ZCgCEigjDdaoyrgWVR1mS6zwACDjeDbkQzX0rOoluhqIhJKh3zH06JChCMi5sjfcbiELAMWE/RFPCW/+so66lu3qDQqnVOdNCklqMvQ7hh4dMhQBOVf2hmsJGw8oJnwQPkh485d5YFVv9WzP5WP6B5DIQ8nQ7xh6dMhQBORc2Zvtp+Fqsx0eOkF445d5YO9UNfR8s0R0eRAJI0O/Y+jRIUMRkHNlb7Y/RD4OKCY8aflEeOOXeeCn3Wro2ThcdHkQCSNDv2Po0SFDEZBzZTXaQMsmpEdVwJUos/CmL/uA9bp6r565TUSXB5EwMvQ7hh4dMhQBOVdWo+0XMgtQTPg8opPwpi/7AAAsbKOe7blxRWyBEAkiQ79j6NEhQxGQc2U12slhrwOKCVPDRghv+rIPAEDsODX0nCz4Y2qIPIkM/Y6hR4cMRUDOldVo4yI6A4oJL4TMFN70ZR8AgO/XqqFnZ5jYAiESRIZ+x9CjQ4YiIOfKarQXo+oiI6o8HrVsFN70ZR8AgKRzauhZ2klsgRAJIkO/Y+jRIUMRkHOZLXFobokBFBNORTYW3vA57oQeux2YRuz0yQAAIABJREFUUR+YWBlIK/hDiYk8hQz9jqFHhwxFQM5ltsTh36EKoJjwaXgf4Q2fI+7uwVk7QD3b89tXwuqDSBQZ+h1Djw4ZioCcy2yJw4fhLwOKCe+EvSO84XNkCz1fvq+GnoNzxRUIkSAy9DuGHh0yFAE5l9kSh68iWgGKCZ1DFgtv+BzZQs/5r9XQs+YlcQVCJIgM/Y6hR4cMRUDOVdeyHTejquBGVFXUtWwX3vA57o4Gls2wRVUCptdV1/gQSUSGfsfQo0OGIiDn6hKyEFBM+DKitfAmz5FzfBvZXD3b8+cZ0aVC5FQy9DuGHh0yFAE513/C3gYUE+aHvyK8wXPkHAvurLfCdytElwqRU8nQ7xh6dMhQBORca+48Wf3V0InCGzxHzjE4dLIaejb9W3SpEDmVDP2OoUeHDEVAznUq8jFAMSHY8qnwBs+RczS2rAcmVADmNBZdKkROJUO/Y+jRIUMRUMnK3lAbWTYgM6o8LkTVE97cOfIeWPS0erbn7/Oiy4fIaWTodww9OmQoAipZ2Zvpi6HTAcWE2Iguwhs7Rz6hZ4dFDT3frxNdPkROI0O/Y+jRIUMRUMnK3kzfC3sNUEyIDhslvLFz5BN6Tm5TQ8/2MaLLh8hpZOh3DD06ZCgCKlnZm+nOiGcAxYS+IXOEN3aOfELPzT/V0DO/uejyIXIaGfodQ48OGYqAStbdZhqLP6JqIy2qIhpYNgtv7Bz5hB5ADTyKSQ1ARBKQod8x9OiQoQioZGU10qdDPgYUE45GNhPe1DkKEHq2vamGnpPbxBYQkZPI0O8YenTIUARUsrIa6bhQdXHs0vD+wps6RwFCz/fr1NDzeYjYAiJyEhn6HUOPDhmKgEpWViONCe8LKCaMCI0S3tQ5ChB6/v6fGnoWtxVbQEROIkO/Y+jRIUMRUMnKaqRZNyVsbokR3tQ5ChB6AGDOY+qNCq3J4gqIyElk6HcuEXp8fX01o3Tp0njuuecc82azGd7e3o75evXqaT5/8uRJtG7dGj4+PmjYsCHi4+M18wcPHkSTJk3g4+OD4OBgJCYmFnjbZCgCKllmSxyaWP4PmVHlcT6yvvCGzlGI0LPp3+rZnrO7xBUQkZPI0O9cIvRkl5GRgerVqyMmJsbxmtlsRmxsbK7vT0tLQ/369TFlyhTYbDasW7cORqMRV65cAQAkJSWhYsWKWLVqFWw2G2bPno0aNWrAarUWaHtkKAIqWWZLHAaFTgEUEzZFdBfe0DkKEXoOL1dDz64J4gqIyElk6HcuF3ri4uJgMpmQkpLieC2/0LN79274+/sjIyPD8VqbNm0wb948AMCyZcvQrFkzx5zdbkfNmjWxdevWAm2PDEVAJctsicP74YMAxYSwsHHCGzpHIULPn2fU0PNxV3EFROQkMvQ7lws9/fr1w2uvvaZ5zWw2o0qVKqhcuTKefvpp7Nu3zzE3Z84cdOjQQfP+UaNGYfjw4QCAMWPGYMiQIZr57t27Y/LkyQXaHhmKgEqW2RKH/0a0AhQTuoQsFN7QOQoReux2YHo9INofSEvJ+yATeQAZ+p1LhZ6//voLXl5e+PrrrzWvHzx4ELdv34bVasWyZcvg6+uLM2fOAACio6PRu3dvzfvDwsLQv39/AMCwYcMwduxYzfyAAQNgsVhy3YYJEyagVKlSjmEwuNQuIjdU37IVt6MCkBxVFXUs24U3dI7CjdiIf6hne37eK7qUiEoUQ4+TzZs3D40aNdJ9X5cuXTBz5kwA6pmejh07auZHjx6tOdMzdOhQzXyPHj14poecpkfIB4Biwr6Ip4U3cI7Cj9Cwt7iuh6QgQ79zqdDTtGlTR5jJz7PPPosZM2YAUNf0BAQEIDMz0zH/1FNPadb0BAUFOebsdjtq1arFNT3kNErYG4BiwqywYcIbOEfhR/uQpWroWfKM6FIiKlEy9DuXCT1HjhxBmTJl8Pvvv2teP3/+PA4cOIDU1FSkpaVh5cqV8PHxwcmTJwHcvXpr2rRpsNlsWL9+PYxGIy5fvgzg7tVbMTExSE1Nxdy5c3n1FjlVbEQXQDHhxdDpwhs4x/2MWGD2o3fu13NddDkRlRgZ+p3LhJ433ngjx9ocQL0HT9OmTeHr64sKFSqgdevWOe7Dc+LECbRq1Qre3t4IDAzMMX/gwAE0btwY3t7eCAoKwpEjRwq8XTIUAZUgux2Xo+ogPaoCGlo2ukAD57ifgc0j1LM9p3eIriiiEiNDv3OZ0OOqZCgCKl7Zm2UbywpAMeFYZFPhjZujCKHn6Bo+h4s8ngz9jqFHhwxFQMUre7N8MzQUUExYHv688MbNUYTQc/2CGnoWthFdXkQlRoZ+x9CjQ4YioOKVvVmuCu8HKCaMDg0X3rg5ihB6AOD9Zmrwufmn2AIjKiEy9DuGHh0yFAEVr+zN8kRkE0AxoaVllfDGzVHE0BM7Tg09P2wSW2BEJUSGfsfQo0OGIqDildUosx4yeiGqnvCmzVEMoefEZjX0bB+bfwEQuSkZ+h1Djw4ZioCKV1ajHBY6EVBM2BDRU3jT5iiG0HPrLzX0vN8s/wIgclMy9DuGHh0yFAEVr6xGuST8RUAx4e2wd4U3bY5iCD2AupBZMakLm4k8jAz9jqFHhwxFQMUrq1Eej3wcUEx4KmSF8KbNUUyh53P1ajwc/VRcgRGVEBn6HUOPDhmKgIqX2aKu58ngeh6PG0NDo9XQs3mE6DIjKnYy9DuGHh0yFAEVr+zNket5PGs8ZlmP9KgKwKyGgN0uutSIipUM/Y6hR4cMRUDFy2yJw0fhLwGKCe+EvSO8UXMU7zgSGaSe7fnztOhSIypWMvQ7hh4dMhQBFS+zJQ7HIpveWc+zXHiT5ijeMSdsqBp6vlogutSIipUM/Y6hR4cMRUDFS7ueJ1Z4k+Yo3tE7ZJ4aej7pI7rUiIqVDP2OoUeHDEVAxStrPc/GiB7CGzRH8Y+6lu3Ae3WA6AAg9bbociMqNjL0O4YeHTIUARXNvU1xMdfzePzAhmHq2Z4zX4guP6JiI0O/Y+jRIUMRUNHc2xC/j3yC63k8fODoGjX0fPau6PIjKjYy9DuGHh0yFAEVTfZm2Niynut5JBi48TsfSUEeR4Z+x9CjQ4YioKLJ3gyHhE7ieh4JBgBg0dNq8Ek6J7YAiYqJDP2OoUeHDEVARZO9GXI9jxwDALBbfaAsvlkitgCJiokM/Y6hR4cMRUBFk70ZZq3neTrkY+GNmaOEQ89v/1VDz6cviC1AomIiQ79j6NEhQxFQ0WQ1wiaWdciIKo+LUXXB9TyeP+pbtiI5qipuRwUA6TbRZUhUZDL0O4YeHTIUARVNVhN8PTQSUExYG95LeEPmcM7YEdFJPdvz817RZUhUZDL0O4YeHTIUARVNVgNcE94bUEwYGRohvBlzOGdYwsaroWdnmOgyJCoyGfodQ48OGYqAikZtgLG4EFUPGVHl8bhlnfBmzOGc0cqySg09C1qKLkOiIpOh3zH06JChCKhozJY4PBPyEaCYkBgZJLwRczh3nI5spAafa7+JLkWiIpGh3zH06JChCKhozJY4KGFvAIoJ88KHCG/CHM4dC8JfVkPPoUWiS5GoSGTodww9OmQoAioasyUOeyLaAYoJ/wyZLbwJczh3OJ66vqKH6FIkKhIZ+h1Djw4ZioCK5hHLFtyOCkByVFXUs2wT3oQ5nDvqWLYDMxsAEyoCt5NElyPRfZOh3zH06JChCKhw7m16L4ZOBxQTPo/oJLwBc4gZiB2nnu05ukZ0eRLdNxn6HUOPDhmKgArn3oa3MHwgoJgQGvaW8ObLISj0/LRLDT1rB4guT6L7JkO/Ex56Bg8ejLJly8LX19cxzpw545hPTk5G//794efnh2rVqmHWrFmaz1+8eBFdu3ZFuXLlYDabsXr1as38yZMn0bp1a/j4+KBhw4aIj48v1PbJUARUOPc2vBORTQDFhKdClgtvvhyCQk96KjC1JjC5GpCWIrpEie6LDP3OJULP22+/nef8oEGD0KtXLyQnJ+P48eMICAjA9u3bHfPt2rXDyJEjkZKSgoSEBPj5+eHo0aMAgLS0NNSvXx9TpkyBzWbDunXrYDQaceXKlQJvnwxFQIWTvdkFWz4FFNP/t3fvYVHV+R/A8bF1dYGDeMOybSCv5JXMS+EFy9TVEsld7acpXdxM0LJNO3M9RymztC3TfmuhrWZZincgdiMrtdLMshJt07TUNftpiUEJ4wi8f3+MjAwaZyhnvjPzfb+e5/2HDNjpPN9z3h+HM+fgkKOD8OJlBA49ALDmHve7PV8WiF2gRL+SDH0X1EPPmTNn0KhRI3z++eeer1mtVowaNQoAcPDgQVxxxRU4derCxYPjxo3D9OnTAQCbN29GixYtUFFR4Xn9pptuwoIFC3zePhkWAdVPzbJ7yGIGdAXLbaOFFy8jeOgpWuseejZmiF2gRL+SDH0XFENPbGwsYmNj0aVLFyxefOFeF7t370bDhg1RWVnp+VpOTg7atWsHAFi/fj3i4+O9/r558+Zh8ODBAIBnnnkGKSkpXq9nZGRg0qRJPm+fDIuA6qdm2a21Dwd0BfdaZgsvXkZsOqs5OKvF4getDVBZYbyQiIKMDH0nfOj55JNP8P3336OiogLbtm1DXFwcVqxYAQDYtm0bYmJivL6/sLAQcXFxAIAVK1age/fuXq9nZ2ejTx/3LeGzsrKQmprq9brVasXYsWN/cXtmzZqFBg0aeBIRIXwXUZCpLrl4NRcntT/irBaLRHWt8NJlxGeLvZ/73Z7DH4hepkT1xqFHgCeeeAIjRrhv8lX9Tk9VVZXn9TVr1ni905OQkOD18/Pnz/d6p2fQoEFer2dmZvKdHvpNqguu+qZ0H9j7Ci9bJjhitU7nA0gpZMnQd0E39Dz55JMYPnw4gAvX9OzZs8fzus1mq/OanvHjx3td09OyZUuvX48lJyfzmh76TaoLrvrxA7OsmcLLlgmO9FJfcQ89C7oBNf6xRhQKZOg74UPP6tWrUVpaiqqqKmzfvh2tW7fG0qVLPa9PmDABqampKC0tRVFREeLi4rw+vdW/f39kZGSgrKwMW7duveSnt+bOnQun04mcnBxER0fj+PHjPm+fDIuA6qe64PY7Es9/VH2Z8LJlgie7Hde7B5/jn4leqkT1IkPfCR96+vfvj5iYGERFRSExMRELFy70er2kpARjxoxBVFQU4uLiLnmfniFDhqBJkya45pprLrpPz969e9G3b180btwYHTt25H166DczqfkYYF4K6Ar2OboKL1kmuJJlzXAPPW/aRS9VonqRoe+EDz3BToZFQPVjUvPxmHUKn6rOXDLuX3HFAH+/Dqjxq3WiYCdD33HoMSDDIqD6Man52OnoBegKhpsXCS9ZJviCZSPOf4pru+jlSuQzGfqOQ48BGRYB1a12oSWpr6FCi8ExLQEmNU94wTLBF3y8zD305D0sevkS+UyGvuPQY0CGRUB1q11oM6wzeBdmps7gzClgdnPgqQSgwiV6CRP5RIa+49BjQIZFQHWrXWhv2gcBuoLxlrnCy5UJzgAAVo5xv9tz4C2xC5jIRzL0HYceAzIsAqpbzTLrqK5DmdYCJVoc2qkbhZcrE5wBAOxZ4x561t0vdgET+UiGvuPQY0CGRUB1q1lmkyyzAF3BRvsw4cXKBHc6qWtxRmuJn7RWgKtM9DImMiRD33HoMSDDIqC61Syy1bbbAV1BpsUmvFSZ4M9G+zD3uz1714texkSGZOg7Dj0GZFgEVLfqAktQc/G9djXOarHorOYIL1Qm+HOvZbZ76Hl9nOhlTGRIhr7j0GNAhkVAdasusHGWuYCu4F17f+FlyoRG2qkbcVq7EshqAZSdFr2UieokQ99x6DEgwyKgulUXWI7tNkBX8JDFLLxMmdDJq7Y097s9O7NFL2WiOsnQdxx6DMiwCKhuJjUfHdT1KNXiUKa1wHXqGuFFyoRORpgXuoeexcl88joFNRn6jkOPARkWAdXNpOZjskUDdAW59iHCS5QJvWBxP/fgc+wT0cuZ6BfJ0HccegzIsAiobiY1HwX2WwBdwX2W2cILlAm94KMl7qFn0zTRy5noF8nQdxx6DMiwCMhb7cLqqq6GU2uG09qVvCEh86uC8h+Bx1sDc64CnD+JXuJElyRD33HoMSDDIiBvtQur+llbK22jhJcnE7qpvhD+Uesjopc40SXJ0HccegzIsAjIW+2yes9+I6ArGGOeL7w4mdBNmvkZQFfwqSNJ9BInuiQZ+o5DjwEZFgF5q1lUN6ivoFKLwXEtHvFqrvDiZEI5efjScZ372p7vikQvc6KLyNB3HHoMyLAIyFvNosqyZgC6ghds/xMEpcmEemZZM91DzxszRC9zoovI0HccegzIsAjIW82S+szRA9AV/Mn8vPDCZEI/3dRVcGrNgSf+CJw9I3qpE3mRoe849BiQYRGQt+qCGmx+AdAVHHAkwqTmCS9MJjyyzj7c/W7PrpdEL3UiLzL0HYceAzIsAvJWXU7LbH8GdAVZ1inCi5IJnww3L3IPPc8lAZWVopc7kYcMfcehx4AMi4C8mdR8JKprUaLFwak1Rzd1lfCiZMIrWO7++Dr+ky96uRN5yNB3HHoMyLAIyJtJzXffS0VXsNY+QnhBMuEXHCh0Dz0vDRW93Ik8ZOg7Dj0GZFgE5M2k5mGPoxugKxhlflZ4QTLhmDzsdyR61hhRMJCh7zj0GJBhEZC3283PAbqCfY6u4AXMjL9SfafvN+yDRS95IgBy9B2HHgMyLALyttp2O6ArsFgfFl6MTPimvboB/6ddg0otBjh1SPSyJ5Ki7zj0GJBhEciuZhF1VVehTGuBn7RWuE5dI7wYmfDOk9b73df25PN5XCSeDH3HoceADItAdjVLqPqOuStsdwgvRCb801VdhZ+1lsBjccDPP4g+FEhyMvSd8KHH6XRi0qRJiI+PR1RUFDp16oRly5Z5Xh84cCAaNWqEyMhIT5xOp+f1Y8eOYejQofjDH/4Ak8mEV1991evv37dvH2688UY0adIEnTp1QmFhYb22T4ZFILsLJZSHrxydAF3BUPM/hBciI0eW2MZe9KgTIhFk6DvhQ8/PP/8Mh8OBgwcPoqqqCjt27EDTpk3x9ttvA3APPYsWLfrFnx8wYACmTJmCsrIyvPvuu4iKisKnn34KAHC5XGjbti3mzJkDp9OJVatWITo6Gt99953P2yfDIpBdddGkWx4DdAW7HDcIL0JGnvRUV+JnrSXKtebora6ASeXQQ2LI0HfCh55LSUtLw+zZswHUPfQcPHgQV1xxBU6dOuX52rhx4zB9+nQAwObNm9GiRQtUVFR4Xr/pppuwYMECn7dFhkUgO3f55GGX4wZAV3CfZbbwImTkykLbREBX8KotDSaVQw+JIUPfBd3QU15ejjZt2mDt2rUA3ENP8+bN0axZM/Ts2RPr1q3zfO/69esRHx/v9fPz5s3D4MHuj4A+88wzSElJ8Xo9IyMDkyZN8nl7ZFgEsjOp+RhrmQfoCr5wdEa8miu8BBm50lVdjdPalXBpsRhgXir6kCBJydB3QTX0VFVVYfz48UhJSUHl+WfS7NixAyUlJXC5XMjNzUVkZCS2bNkCAFixYgW6d+/u9XdkZ2ejT58+AICsrCykpqZ6vW61WjF27Nhf3IZZs2ahQYMGnkREBNUuosvgUqWzzX4ToCuYarEKL0BGzsw9/0muDfZhog8RkhSHngCqqqrC5MmTccMNN+DHH3/8xe+7//77kZmZCcD9Tk9CQoLX6/Pnz/d6p2fQoEFer2dmZvKdHsnVLpuR5gWAruCQowMS+C4PIygd1XU4UX3fnu+KRB8mJCEZ+i4ohp6qqipMmTIFSUlJKC4urvN7H3jgAWRkZAC49DU948eP97qmp2XLlp53jQAgOTmZ1/RIrnbZFNoHAbqCGdYZwouPkTs260Pu+/asHCP6MCEJydB3QTH0ZGRkoFu3bvjhB+/7VJw+fRoFBQUoKytDRUUFCgoKEBkZibfeesvzPf3790dGRgbKysqwdevWS356a+7cuXA6ncjJyUF0dDSOHz/u87bJsAhkU7Nkhpj/AegKjmkJaKduFF56jNxpp27EEUdb9+DzzXuiDxWSjAx9J3zoOXz4MCIiIvD73//e6148kydPxsmTJ9GrVy9ER0dDURT06NEDr7/+utfPHzt2DEOGDEGTJk1wzTXXXHSfnr1796Jv375o3LgxOnbsyPv0kFfJbLIPBXQFDus04YXHMCY1HxkWu3voeb43cO6s6MOFJCJD3wkfeoKdDItANtXlcov5BVRoMTipXY0O6nrhZccw7uRhqz0Z0BU8Zf0rTCo/wk6BIUPfcegxIMMikE3tYpllzQyComOYCxlgXgqn1hzlWnP0M78k+pAhScjQdxx6DMiwCGRjUvNxjyUL0BV85eiEtryWhwnCPG29F9AVvGPvD1RViT5sSAIy9B2HHgMyLIJwV7tM2qkbccjRAdAVpFseF15uDHOptFc34KCjo/v6nn0bRR9GJAEZ+o5DjwEZFkG4q10mWdYpnn9Biy42hqkrd1qecg89T3cEyktEH0oU5mToOw49BmRYBOGuZokkqa+hRGsNlxaLm80vCi81hjHKOvtwQFewzj7c8zUif5Ch7zj0GJBhEYS7mgXyqi0N0BW8ZBsjvMwYxpd0U1fhmJYA6AoetjwKk8qhh/xDhr7j0GNAhkUQ7qrLY6R5ASq0GJzSrkJXdZXwMmMYX3OH+e84pzXFz1pLpJiXiD6kKEzJ0HccegzIsAjCnUnNRyd1refiZT5uggnFzLfeB+gKihzdgHNO0YcVhSEZ+o5DjwEZFkG4M6n5WGG7A9AVvGkfBJOaJ7zAGKa+SVBz8YG9r/vC5gJV9GFFYUiGvuPQY0CGRRBuapdFuuUxQFdwUrsa16srhZcXw/za9FJfwQ9aG/fgU7RO9KFGYUaGvuPQY0CGRRBuapZED/U1nNT+COgK7rFkCS8thvmtmWiZgwotBk6tOUabn4ZJ5YXNdHnI0HccegzIsAjCzYWCyMO/7LcAuoKVtlHCy4phLlcs1ocBXcFp7UoMMmeLPuQoTMjQdxx6DMiwCMJNdTE8bn0A0BV87WiPRHWt8KJimMuZ/7XdBegKjjjaAj+dEH3YURiQoe849BiQYRGEuksVwmSLBugKzmgtMdy8SHhBMczlTryaiw32Ye7re14cCDh/En0oUoiToe849BiQYRGEutplkGpegHKtOSq1GNxrmS28nBjGX2mvbsD285/o+tjR03P/KaJfQ4a+49BjQIZFEOpqlkCyeRlOalcDugLdOlV4KTGMv9NFzcEuxw2ArmCfoyt6qitFH5IUomToOw49BmRYBKGu+uTfXX0d+x2JgK7gn7a/CC8jhglUOqlrsdWeDOiK+8nsp4+KPiwpBMnQdxx6DMiwCEKdSc1Hb3WFZ+DZbB+IBDVXeBExTCDTXt2AgvOfVjymJeBW82Kv14mMyNB3HHoMyLAIQk3tk/0A81IcdbT1DDwd1PXCC4hhRORadRPW2G/zXMT/oMXseY3IiAx9x6HHgAyLINTUPMkPNf/Dc/PBDfZhaKtuFF48DCMy8Wou5lrvR4UWA+gKVtjuQHt1g+jDlkKADH3HoceADIsg1FSf3NMtj+FHrTWgK1huG414/kqLYTwZa5nn+QfBZ44eGGhe4vU6UW0y9B2HHgMyLIJgV/tk3k7diGzbne77k+gKFtjSwYeIMszFuUF9BR86egO6AqfWHE9b70V7dQNMKoceupgMfcehx4AMiyDY1TyJDzAvxWeOHoCuoFi7CvfxPjwMU2euVTdhrvV+lGktPJ/uGmuZJ/qwpiAkQ99x6DEgwyIIdibV/e5OlnUKSrU4QFfwoaM3+qgvCy8UhgmVJJv/iXfs/T3vkP7bfjP+ZH7e8zqRDH3HoceADIsg2HifrPMwyTILXzvaA7oClxaLZ2138yPpDPOrkocpFjuOaQme4edN+yAMrzH8VIfkI0PfcegxIMMiCDbVJ+c7LU/hffuNnpPzZvtA3Gx+MQiKg2FCO+3VDbBYH/Yafrbb+2Kaxeq55QPJR4a+49BjQIZFEFRcZZhpfQRfODp7TsZfOq7DXZYnhBcFw4Rb2qkbYbY+jMOOdp7jrVi7CkttY4FjHwOVlaLPCBRAMvQdhx4DMiwCkUyq+0LLcZa5eMWWhlPaVZ6T727H9ZhmseJadZPwcmCYcE68motxlrnIsw/BWS3Wcwx+p5mwwnYHJljmXHTTTwo/MvQdhx4DMiyCQKo+YfZSX8FUixWrbCO9Bh2XFotN9qEYZX5WeBEwjIy5Xl2J2dZM7HD08dzg0P2R92bY6eiFRbYJmGCZA5w5Jfp0QpeZDH0nxdDjcrkwZcoUNG3aFM2aNcPMmTNRVVXl08/KsAj8yaTmo6u6Cn8xz4fDOg2rbbd7LkqueTLdbB+IR6wz0U1dJfykzzCMOz3U1/A3y6N4wz4YP2htvI7b6md8FdpTsMCWDuxZ4/6VWNlp0acd+pVk6Dsphh5N09CrVy+cOHECR44cQYcOHbBw4UKfflaGRfCbVFYApf8HfLcHOPg2/mZ5FM9Y70GO7TbscPTBcS3+ohMldAVfODpjuW00Mix2dFFzhJ/cGYYxSh5uNr8Is/VhrLMPx35Hotc7QTVzSrsKnzu6o9A+CC/bRuMp61+BT1YAXxYARz8CTh0Cyord5w8KGjL0nRRDz9VXX41NmzZ5/pydnY0ePXr49LOXbRGcO+s+2OvMTu8c+bBWdlzI4e3n8wHwzfvAN+8BX28Dvt4KHHoXOPgOcPBt4Ku3gAOFwP5/u084X+QB+zYCRWuBz3OAT18DPnkZ+Ggp8OELwAeLgK3zgXfmAIUaUPAosDETWHMPsHIssGwEsLgf8GxXYO41qPyFk151zmlNsd+RiE32oXjKOgn3WLLQXX09CE7gDMP81nRQ1+N283N41PoIFtvG4V/2W/AfR2cPN65bAAAHHElEQVSUa83rPC/UTKkWh2+1eGBRL+DFFPc5ZuUYICcdWD8ZyH0IKFCBQgfw9uPAlnnAe88C258HPnzRfe76eDmw+xXgs9fd57WitcDeDcC+TcB/8t3nvv3/Bva/CRx4y31e/Gqz+xx58B33OfPQFvf58+tt7vPpN++dP7e+7z7PHv7gwnnXcy6udY6ufQ6/KEYdUM8UH748/XQeh54wUFxcjIiICBw+fGFxfPTRR/jd737n06+4LtsiKDnu80kgVFKixeG/2rX41JGEQnsKXrOl4jnbRMy0PoI7LU+hn/klPgCUYaRMHnqor+FP5udxjyULVut0/N16L5bZ/oxc+xC8b78RRY5uOOxoh2LtKpzTmgo/n4VkCtTL00/ncegJA0ePHkVERAROn77we+YDBw4gIiIC5eXlF33/rFmz0KBBA08iIiK8/uzPBPK/JWO4f7lvQzXcv9y/gdoP4S7s/w+r3+k5cuSI52u7du3y+Z2eQGrQIPynbJG4f/2H+9a/uH/9i/tXHmE/9ADua3pyc3M9f16yZInP1/QEEg88/+L+9R/uW//i/vUv7l95SDH0OBwO9OnTBydPnsTRo0fRqVMnnz+9FUg88PyL+9d/uG/9i/vXv7h/5SHF0ONyufDAAw8gJiYGsbGxmDFjRtD9agtwX09E/sP96z/ct/7F/etf3L/ykGLoISIiIuLQQ0RERFLg0ENERERS4NBDREREUuDQE0D1efBpUVERUlJSEBMTg7i4OEydOhUulyvAWxxa6rN/P/74YyQnJyM6OhoJCQl4+eWXA7y1oWXRokXo2bMnGjVqhNGjR9f5vSUlJRg7diyioqLQunVrPP300wHaytBUn31rt9vRpUsXNGzYEI888kiAtjC0+bp/T5w4gXHjxqFNmzaIjo5GUlIS8vPzA7ilFAgcegKoPg8+7dq1K6ZNmwaXy4Vvv/0WnTt3xvz58wO8xaHF1/17+vRptGrVCkuWLEFFRQU+/PBDKIqC9957T8BWh4Z169Zhw4YNyMzMNCzmiRMnYuTIkSgpKcGePXvQsmVLr/tkkbf67Nvly5ejoKAAaWlpHHp85Ov+PXToEObPn4///ve/qKysRG5uLiIjI/Hll18GcGvJ3zj0BFB9HnwaHR2NnTt3ev48Y8YMpKen+3sTQ5qv+/eNN95AQkKC19fuvvtu7l8f6LpeZ3GcOXMGjRo1wueff+75mtVqxahRowKxeSHNaN/WlJ6ezqGnnuqzf6slJSXxXeAww6EnQOr74NPZs2cjIyMDTqcTR48eRWJiIlavXh3ITQ4p9dm/eXl5iI+P9/raxIkTkZSUFJBtDWVGxbF79240bNgQlZWVnq/l5OSgXbt2gdi8kMahx7/qO/ScOHECjRs3xq5du/y4VRRoHHoCpL4PPt25cycSExPRsGFDREREYOLEiV5FQt7qs39PnTqFZs2aYfHixXC5XHj//fcRHR2Ntm3bBnqzQ45RcWzbtg0xMTFeXyssLERcXJy/Ny3kcejxr/rsX6fTiUGDBmHixIl+3ioKNA49AVKfB58WFxdDURRPKX///fdITU3F1KlTA73ZIaO+D5bdvn07kpOT0axZM/Tr1w8PPvggevfuHchNDkm+vtNTc5+vWbOG7/T4gEOPf/m6f8+ePYvbbrsNI0aMwNmzZwOwZRRIHHoCyNcHn+7atQuNGzf2+lpubi5MJpO/NzGk/ZYHy44ZMwYzZ87016aFDV+v6dmzZ4/nazabjdf0+IBDj3/5sn/Pnj2LkSNHYujQoXA6nQHaMgokDj0B5OuDT0tLS9G0aVNkZ2ejoqICxcXFSEtLw8iRIwVsdeioz4Nld+/eDafTibKyMmRnZ6NVq1b49ttvA7zFoePcuXMoLy+HzWZDWloaysvLf/FfwRMmTEBqaipKS0tRVFSEuLg4fnqrDvXZty6XC+Xl5bjrrrswffp0lJeX81YWBnzdvy6XC6mpqbjlllsueckBhQcOPQFU14NPhw0bhjlz5ni+d+vWrejbty9iYmLQokULjB49mqVsoD77Nz09HYqiIDIyErfeeiv27t0rarNDgq7riIiI8MrAgQMBXLxvS0pKMGbMGERFRSEuLo736TFQn32bnp5+0ffyU4d183X/btmyBREREWjcuDEiIyM9qbn/KfRx6CEiIiIpcOghIiIiKXDoISIiIilw6CEiIiIpcOghIiIiKXDoISIiIilw6CEiIiIpcOghIiIiKXDoISIiIilw6CEiIiIpcOghIiIiKXDoISIiIilw6CEiIiIpcOghIiIiKXDoISIiIilw6CEiIiIpcOghIiIiKXDoISIiIilw6CEiIiIpcOghIiIiKXDoISIiIilw6CEiIiIpcOghIiIiKXDoISIiIilw6CEiIiIpcOghIiIiKXDoISIiIilw6CEiIiIpcOghIiIiKfw/DDj5s4Q8sJ4AAAAASUVORK5CYII=\" width=\"573\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#Experimental 1D integrator ... \n",
    "from pyFAI.containers import Integrate1dResult\n",
    "from pyFAI.azimuthalIntegrator import AzimuthalIntegrator\n",
    "from copy import copy\n",
    "\n",
    "def integrate1d_experimental(self, data, variance, **kwargs):\n",
    "    \"\"\"Experimental azimuthal integrator\"\"\"\n",
    "    if \"csr_integrator\" not in self.engines:\n",
    "        self.integrate1d(data, **kwargs)\n",
    "    csr = self.engines[\"csr_integrator\"].engine\n",
    "    \n",
    "    if kwargs[\"correctSolidAngle\"]:\n",
    "        norm = self.solidAngleArray(self.detector.shape).copy()\n",
    "    else:\n",
    "        norm = numpy.ones(data.shape)\n",
    "    polf = kwargs.get(\"polarization_factor\")\n",
    "    if polf:\n",
    "        norm *= self.polarization(self.detector.shape, factor=polf)\n",
    "    flat = kwargs.get(\"flat\")\n",
    "    if flat is not None:\n",
    "        norm *= flat\n",
    "    denom1 = csr.integrate(norm)\n",
    "    signal = csr.integrate(data)\n",
    "    sigma2 = csr.integrate(variance, coef_power=2)\n",
    "    result = Integrate1dResult(denom1[0], \n",
    "                               signal[2]/denom1[2], \n",
    "                               numpy.sqrt(sigma2[2])/denom1[2])\n",
    "    result._set_method_called(\"integrate1d_exp\")\n",
    "    result._set_compute_engine(\"experimental\")\n",
    "    return result\n",
    "\n",
    "#I would usually not recommand monkey-patching, but it is convieniant here for demonstration purpose\n",
    "ai.__class__.integrate1d_experimental = integrate1d_experimental\n",
    "\n",
    "\n",
    "f,a = plot_distribution(ai, kwarg, integrate=ai.integrate1d_experimental)\n",
    "f.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The integrated curves are now following the $\\chi^2$ distribution, which means that the errors provided are in accordance with the data.\n",
    "\n",
    "# Conclusion\n",
    "\n",
    "PyFAI's historical version (version <=0.16) has been providing proper error propagation ONLY in the case where any normalization (solid angle, flatfield, polarization, ...) and pixel splitting was DISABLED. \n",
    "This is not the most common use-case for pyFAI I have to confess. We demonstrate in this notebook how to fix the two bugs. For implementing this in pyFAI, many thousands of line of code needs to be changed and all associated test, which was not be possible before the release of pyFAI v0.16. But for scientific honesty I prefer warning the users of the implication and offer them the tools to validate the code.\n",
    "\n",
    "Moreover the fact the normalization has to be performed as part of the integration is a major issue as almost any commercial detector comes with flatfield correction already applied.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total execution time:  1153.526174068451\n"
     ]
    }
   ],
   "source": [
    "print(\"Total execution time: \", time.time()-start_time)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
