Skip to content

Instantly share code, notes, and snippets.

@kif
Created September 14, 2021 10:35
Show Gist options
  • Save kif/560de4c8feca6b1123bd6fd844875be9 to your computer and use it in GitHub Desktop.
Save kif/560de4c8feca6b1123bd6fd844875be9 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib nbagg\n",
"import numpy\n",
"from matplotlib.pyplot import subplots"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'/usr/bin/python3'"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import sys\n",
"sys.executable"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"import pyFAI, pyFAI.azimuthalIntegrator\n",
"from pyFAI.gui import jupyter\n",
"import hdf5plugin"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"import h5py\n",
"import numpy\n",
"import fabio"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"/* global mpl */\n",
"window.mpl = {};\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(\n",
" '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",
"\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 = document.createElement('div');\n",
" this.root.setAttribute('style', 'display: inline-block');\n",
" this._root_extra_style(this.root);\n",
"\n",
" parent_element.appendChild(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 (fig.ratio !== 1) {\n",
" fig.send_message('set_dpi_ratio', { dpi_ratio: fig.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 = document.createElement('div');\n",
" titlebar.classList =\n",
" 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
" var titletext = document.createElement('div');\n",
" titletext.classList = 'ui-dialog-title';\n",
" titletext.setAttribute(\n",
" 'style',\n",
" 'width: 100%; text-align: center; padding: 3px;'\n",
" );\n",
" titlebar.appendChild(titletext);\n",
" this.root.appendChild(titlebar);\n",
" this.header = titletext;\n",
"};\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
"\n",
"mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
"\n",
"mpl.figure.prototype._init_canvas = function () {\n",
" var fig = this;\n",
"\n",
" var canvas_div = (this.canvas_div = document.createElement('div'));\n",
" canvas_div.setAttribute(\n",
" 'style',\n",
" 'border: 1px solid #ddd;' +\n",
" 'box-sizing: content-box;' +\n",
" 'clear: both;' +\n",
" 'min-height: 1px;' +\n",
" 'min-width: 1px;' +\n",
" 'outline: 0;' +\n",
" 'overflow: hidden;' +\n",
" 'position: relative;' +\n",
" 'resize: both;'\n",
" );\n",
"\n",
" function on_keyboard_event_closure(name) {\n",
" return function (event) {\n",
" return fig.key_event(event, name);\n",
" };\n",
" }\n",
"\n",
" canvas_div.addEventListener(\n",
" 'keydown',\n",
" on_keyboard_event_closure('key_press')\n",
" );\n",
" canvas_div.addEventListener(\n",
" 'keyup',\n",
" on_keyboard_event_closure('key_release')\n",
" );\n",
"\n",
" this._canvas_extra_style(canvas_div);\n",
" this.root.appendChild(canvas_div);\n",
"\n",
" var canvas = (this.canvas = document.createElement('canvas'));\n",
" canvas.classList.add('mpl-canvas');\n",
" canvas.setAttribute('style', 'box-sizing: content-box;');\n",
"\n",
" this.context = canvas.getContext('2d');\n",
"\n",
" var backingStore =\n",
" this.context.backingStorePixelRatio ||\n",
" this.context.webkitBackingStorePixelRatio ||\n",
" this.context.mozBackingStorePixelRatio ||\n",
" this.context.msBackingStorePixelRatio ||\n",
" this.context.oBackingStorePixelRatio ||\n",
" this.context.backingStorePixelRatio ||\n",
" 1;\n",
"\n",
" this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
" 'canvas'\n",
" ));\n",
" rubberband_canvas.setAttribute(\n",
" 'style',\n",
" 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
" );\n",
"\n",
" // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
" if (this.ResizeObserver === undefined) {\n",
" if (window.ResizeObserver !== undefined) {\n",
" this.ResizeObserver = window.ResizeObserver;\n",
" } else {\n",
" var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
" this.ResizeObserver = obs.ResizeObserver;\n",
" }\n",
" }\n",
"\n",
" this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
" var nentries = entries.length;\n",
" for (var i = 0; i < nentries; i++) {\n",
" var entry = entries[i];\n",
" var width, height;\n",
" if (entry.contentBoxSize) {\n",
" if (entry.contentBoxSize instanceof Array) {\n",
" // Chrome 84 implements new version of spec.\n",
" width = entry.contentBoxSize[0].inlineSize;\n",
" height = entry.contentBoxSize[0].blockSize;\n",
" } else {\n",
" // Firefox implements old version of spec.\n",
" width = entry.contentBoxSize.inlineSize;\n",
" height = entry.contentBoxSize.blockSize;\n",
" }\n",
" } else {\n",
" // Chrome <84 implements even older version of spec.\n",
" width = entry.contentRect.width;\n",
" height = entry.contentRect.height;\n",
" }\n",
"\n",
" // Keep the size of the canvas and rubber band canvas in sync with\n",
" // the canvas container.\n",
" if (entry.devicePixelContentBoxSize) {\n",
" // Chrome 84 implements new version of spec.\n",
" canvas.setAttribute(\n",
" 'width',\n",
" entry.devicePixelContentBoxSize[0].inlineSize\n",
" );\n",
" canvas.setAttribute(\n",
" 'height',\n",
" entry.devicePixelContentBoxSize[0].blockSize\n",
" );\n",
" } else {\n",
" canvas.setAttribute('width', width * fig.ratio);\n",
" canvas.setAttribute('height', height * fig.ratio);\n",
" }\n",
" canvas.setAttribute(\n",
" 'style',\n",
" 'width: ' + width + 'px; height: ' + height + 'px;'\n",
" );\n",
"\n",
" rubberband_canvas.setAttribute('width', width);\n",
" rubberband_canvas.setAttribute('height', height);\n",
"\n",
" // And update the size in Python. We ignore the initial 0/0 size\n",
" // that occurs as the element is placed into the DOM, which should\n",
" // otherwise not happen due to the minimum size styling.\n",
" if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
" fig.request_resize(width, height);\n",
" }\n",
" }\n",
" });\n",
" this.resizeObserverInstance.observe(canvas_div);\n",
"\n",
" function on_mouse_event_closure(name) {\n",
" return function (event) {\n",
" return fig.mouse_event(event, name);\n",
" };\n",
" }\n",
"\n",
" rubberband_canvas.addEventListener(\n",
" 'mousedown',\n",
" on_mouse_event_closure('button_press')\n",
" );\n",
" rubberband_canvas.addEventListener(\n",
" 'mouseup',\n",
" on_mouse_event_closure('button_release')\n",
" );\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband_canvas.addEventListener(\n",
" 'mousemove',\n",
" on_mouse_event_closure('motion_notify')\n",
" );\n",
"\n",
" rubberband_canvas.addEventListener(\n",
" 'mouseenter',\n",
" on_mouse_event_closure('figure_enter')\n",
" );\n",
" rubberband_canvas.addEventListener(\n",
" 'mouseleave',\n",
" on_mouse_event_closure('figure_leave')\n",
" );\n",
"\n",
" canvas_div.addEventListener('wheel', function (event) {\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" on_mouse_event_closure('scroll')(event);\n",
" });\n",
"\n",
" canvas_div.appendChild(canvas);\n",
" canvas_div.appendChild(rubberband_canvas);\n",
"\n",
" this.rubberband_context = rubberband_canvas.getContext('2d');\n",
" this.rubberband_context.strokeStyle = '#000000';\n",
"\n",
" this._resize_canvas = function (width, height, forward) {\n",
" if (forward) {\n",
" canvas_div.style.width = width + 'px';\n",
" canvas_div.style.height = height + 'px';\n",
" }\n",
" };\n",
"\n",
" // Disable right mouse context menu.\n",
" this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
" event.preventDefault();\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 toolbar = document.createElement('div');\n",
" toolbar.classList = 'mpl-toolbar';\n",
" this.root.appendChild(toolbar);\n",
"\n",
" function on_click_closure(name) {\n",
" return function (_event) {\n",
" return fig.toolbar_button_onclick(name);\n",
" };\n",
" }\n",
"\n",
" function on_mouseover_closure(tooltip) {\n",
" return function (event) {\n",
" if (!event.currentTarget.disabled) {\n",
" return fig.toolbar_button_onmouseover(tooltip);\n",
" }\n",
" };\n",
" }\n",
"\n",
" fig.buttons = {};\n",
" var buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'mpl-button-group';\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",
" /* Instead of a spacer, we start a new button group. */\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
" buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'mpl-button-group';\n",
" continue;\n",
" }\n",
"\n",
" var button = (fig.buttons[name] = document.createElement('button'));\n",
" button.classList = 'mpl-widget';\n",
" button.setAttribute('role', 'button');\n",
" button.setAttribute('aria-disabled', 'false');\n",
" button.addEventListener('click', on_click_closure(method_name));\n",
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
"\n",
" var icon_img = document.createElement('img');\n",
" icon_img.src = '_images/' + image + '.png';\n",
" icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
" icon_img.alt = tooltip;\n",
" button.appendChild(icon_img);\n",
"\n",
" buttonGroup.appendChild(button);\n",
" }\n",
"\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
"\n",
" var fmt_picker = document.createElement('select');\n",
" fmt_picker.classList = 'mpl-widget';\n",
" toolbar.appendChild(fmt_picker);\n",
" this.format_dropdown = fmt_picker;\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = document.createElement('option');\n",
" option.selected = fmt === mpl.default_extension;\n",
" option.innerHTML = fmt;\n",
" fmt_picker.appendChild(option);\n",
" }\n",
"\n",
" var status_bar = document.createElement('span');\n",
" status_bar.classList = 'mpl-message';\n",
" toolbar.appendChild(status_bar);\n",
" this.message = status_bar;\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",
"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",
"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], msg['forward']);\n",
" fig.send_message('refresh', {});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
" var x0 = msg['x0'] / fig.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
" var x1 = msg['x1'] / fig.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / fig.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,\n",
" 0,\n",
" fig.canvas.width / fig.ratio,\n",
" fig.canvas.height / fig.ratio\n",
" );\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",
" 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.handle_history_buttons = function (fig, msg) {\n",
" for (var key in msg) {\n",
" if (!(key in fig.buttons)) {\n",
" continue;\n",
" }\n",
" fig.buttons[key].disabled = !msg[key];\n",
" fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
" if (msg['mode'] === 'PAN') {\n",
" fig.buttons['Pan'].classList.add('active');\n",
" fig.buttons['Zoom'].classList.remove('active');\n",
" } else if (msg['mode'] === 'ZOOM') {\n",
" fig.buttons['Pan'].classList.remove('active');\n",
" fig.buttons['Zoom'].classList.add('active');\n",
" } else {\n",
" fig.buttons['Pan'].classList.remove('active');\n",
" fig.buttons['Zoom'].classList.remove('active');\n",
" }\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",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data\n",
" );\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" } else if (\n",
" typeof evt.data === 'string' &&\n",
" evt.data.slice(0, 21) === 'data:image/png;base64'\n",
" ) {\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(\n",
" \"No handler for the '\" + msg_type + \"' message type: \",\n",
" msg\n",
" );\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(\n",
" \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
" e,\n",
" e.stack,\n",
" msg\n",
" );\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",
" }\n",
" if (e.target) {\n",
" targ = e.target;\n",
" } else if (e.srcElement) {\n",
" targ = e.srcElement;\n",
" }\n",
" if (targ.nodeType === 3) {\n",
" // defeat Safari bug\n",
" targ = targ.parentNode;\n",
" }\n",
"\n",
" // pageX,Y are the mouse positions relative to the document\n",
" var boundingRect = targ.getBoundingClientRect();\n",
" var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
" var y = e.pageY - (boundingRect.top + document.body.scrollTop);\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",
" }\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",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * this.ratio;\n",
" var y = canvas_pos.y * this.ratio;\n",
"\n",
" this.send_message(name, {\n",
" x: x,\n",
" y: y,\n",
" button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event),\n",
" });\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",
" // Prevent repeat events\n",
" if (name === 'key_press') {\n",
" if (event.which === this._key) {\n",
" return;\n",
" } else {\n",
" this._key = event.which;\n",
" }\n",
" }\n",
" if (name === 'key_release') {\n",
" this._key = null;\n",
" }\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which !== 17) {\n",
" value += 'ctrl+';\n",
" }\n",
" if (event.altKey && event.which !== 18) {\n",
" value += 'alt+';\n",
" }\n",
" if (event.shiftKey && event.which !== 16) {\n",
" value += 'shift+';\n",
" }\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, 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",
"\n",
"///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
"// prettier-ignore\n",
"var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\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\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"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\";/* global mpl */\n",
"\n",
"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 = document.getElementById(id);\n",
" var ws_proxy = comm_websocket_adapter(comm);\n",
"\n",
" function ondownload(figure, _format) {\n",
" window.open(figure.canvas.toDataURL());\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy, ondownload, element);\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;\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",
" fig.cell_info[0].output_area.element.on(\n",
" 'cleared',\n",
" { fig: fig },\n",
" fig._remove_fig_handler\n",
" );\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function (fig, msg) {\n",
" var width = fig.canvas.width / fig.ratio;\n",
" fig.cell_info[0].output_area.element.off(\n",
" 'cleared',\n",
" fig._remove_fig_handler\n",
" );\n",
" fig.resizeObserverInstance.unobserve(fig.canvas_div);\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.innerHTML =\n",
" '<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 / this.ratio;\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] =\n",
" '<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 () {\n",
" fig.push_to_output();\n",
" }, 1000);\n",
"};\n",
"\n",
"mpl.figure.prototype._init_toolbar = function () {\n",
" var fig = this;\n",
"\n",
" var toolbar = document.createElement('div');\n",
" toolbar.classList = 'btn-toolbar';\n",
" this.root.appendChild(toolbar);\n",
"\n",
" function on_click_closure(name) {\n",
" return function (_event) {\n",
" return fig.toolbar_button_onclick(name);\n",
" };\n",
" }\n",
"\n",
" function on_mouseover_closure(tooltip) {\n",
" return function (event) {\n",
" if (!event.currentTarget.disabled) {\n",
" return fig.toolbar_button_onmouseover(tooltip);\n",
" }\n",
" };\n",
" }\n",
"\n",
" fig.buttons = {};\n",
" var buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'btn-group';\n",
" var button;\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",
" /* Instead of a spacer, we start a new button group. */\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
" buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'btn-group';\n",
" continue;\n",
" }\n",
"\n",
" button = fig.buttons[name] = document.createElement('button');\n",
" button.classList = 'btn btn-default';\n",
" button.href = '#';\n",
" button.title = name;\n",
" button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
" button.addEventListener('click', on_click_closure(method_name));\n",
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
" buttonGroup.appendChild(button);\n",
" }\n",
"\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = document.createElement('span');\n",
" status_bar.classList = 'mpl-message pull-right';\n",
" toolbar.appendChild(status_bar);\n",
" this.message = status_bar;\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = document.createElement('div');\n",
" buttongrp.classList = 'btn-group inline pull-right';\n",
" button = document.createElement('button');\n",
" button.classList = 'btn btn-mini btn-primary';\n",
" button.href = '#';\n",
" button.title = 'Stop Interaction';\n",
" button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
" button.addEventListener('click', function (_evt) {\n",
" fig.handle_close(fig, {});\n",
" });\n",
" button.addEventListener(\n",
" 'mouseover',\n",
" on_mouseover_closure('Stop Interaction')\n",
" );\n",
" buttongrp.appendChild(button);\n",
" var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
" titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
"};\n",
"\n",
"mpl.figure.prototype._remove_fig_handler = function (event) {\n",
" var fig = event.data.fig;\n",
" if (event.target !== this) {\n",
" // Ignore bubbled events from children.\n",
" return;\n",
" }\n",
" fig.close_ws(fig, {});\n",
"};\n",
"\n",
"mpl.figure.prototype._root_extra_style = function (el) {\n",
" el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
"};\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function (el) {\n",
" // this is important to make the div 'focusable\n",
" el.setAttribute('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",
" } else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\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",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which === 13) {\n",
" this.canvas_div.blur();\n",
" // select the cell after this one\n",
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
" IPython.notebook.select(index + 1);\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
" fig.ondownload(fig, null);\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(\n",
" 'matplotlib',\n",
" mpl.mpl_figure_comm\n",
" );\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=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x7ffb6c094ac0>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"filename = \"lys1_7_data_000002.h5\" \n",
"h = h5py.File(filename, \"r\")\n",
"ds = h[\"/entry/data/data\"]\n",
"frame = ds[4]\n",
"mask = (ds[4] > 30000).astype(\"int8\")\n",
"fig,ax = subplots()\n",
"ax.imshow(mask)\n",
"#hist(frame.ravel(), 100)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"250538\n"
]
}
],
"source": [
"det = pyFAI.detector_factory(\"Eiger4M\")\n",
"det.mask = mask\n",
"print(mask.sum())"
]
},
{
"cell_type": "code",
"execution_count": 7,
"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",
"/* global mpl */\n",
"window.mpl = {};\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(\n",
" '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",
"\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 = document.createElement('div');\n",
" this.root.setAttribute('style', 'display: inline-block');\n",
" this._root_extra_style(this.root);\n",
"\n",
" parent_element.appendChild(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 (fig.ratio !== 1) {\n",
" fig.send_message('set_dpi_ratio', { dpi_ratio: fig.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 = document.createElement('div');\n",
" titlebar.classList =\n",
" 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
" var titletext = document.createElement('div');\n",
" titletext.classList = 'ui-dialog-title';\n",
" titletext.setAttribute(\n",
" 'style',\n",
" 'width: 100%; text-align: center; padding: 3px;'\n",
" );\n",
" titlebar.appendChild(titletext);\n",
" this.root.appendChild(titlebar);\n",
" this.header = titletext;\n",
"};\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
"\n",
"mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
"\n",
"mpl.figure.prototype._init_canvas = function () {\n",
" var fig = this;\n",
"\n",
" var canvas_div = (this.canvas_div = document.createElement('div'));\n",
" canvas_div.setAttribute(\n",
" 'style',\n",
" 'border: 1px solid #ddd;' +\n",
" 'box-sizing: content-box;' +\n",
" 'clear: both;' +\n",
" 'min-height: 1px;' +\n",
" 'min-width: 1px;' +\n",
" 'outline: 0;' +\n",
" 'overflow: hidden;' +\n",
" 'position: relative;' +\n",
" 'resize: both;'\n",
" );\n",
"\n",
" function on_keyboard_event_closure(name) {\n",
" return function (event) {\n",
" return fig.key_event(event, name);\n",
" };\n",
" }\n",
"\n",
" canvas_div.addEventListener(\n",
" 'keydown',\n",
" on_keyboard_event_closure('key_press')\n",
" );\n",
" canvas_div.addEventListener(\n",
" 'keyup',\n",
" on_keyboard_event_closure('key_release')\n",
" );\n",
"\n",
" this._canvas_extra_style(canvas_div);\n",
" this.root.appendChild(canvas_div);\n",
"\n",
" var canvas = (this.canvas = document.createElement('canvas'));\n",
" canvas.classList.add('mpl-canvas');\n",
" canvas.setAttribute('style', 'box-sizing: content-box;');\n",
"\n",
" this.context = canvas.getContext('2d');\n",
"\n",
" var backingStore =\n",
" this.context.backingStorePixelRatio ||\n",
" this.context.webkitBackingStorePixelRatio ||\n",
" this.context.mozBackingStorePixelRatio ||\n",
" this.context.msBackingStorePixelRatio ||\n",
" this.context.oBackingStorePixelRatio ||\n",
" this.context.backingStorePixelRatio ||\n",
" 1;\n",
"\n",
" this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
" 'canvas'\n",
" ));\n",
" rubberband_canvas.setAttribute(\n",
" 'style',\n",
" 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
" );\n",
"\n",
" // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
" if (this.ResizeObserver === undefined) {\n",
" if (window.ResizeObserver !== undefined) {\n",
" this.ResizeObserver = window.ResizeObserver;\n",
" } else {\n",
" var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
" this.ResizeObserver = obs.ResizeObserver;\n",
" }\n",
" }\n",
"\n",
" this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
" var nentries = entries.length;\n",
" for (var i = 0; i < nentries; i++) {\n",
" var entry = entries[i];\n",
" var width, height;\n",
" if (entry.contentBoxSize) {\n",
" if (entry.contentBoxSize instanceof Array) {\n",
" // Chrome 84 implements new version of spec.\n",
" width = entry.contentBoxSize[0].inlineSize;\n",
" height = entry.contentBoxSize[0].blockSize;\n",
" } else {\n",
" // Firefox implements old version of spec.\n",
" width = entry.contentBoxSize.inlineSize;\n",
" height = entry.contentBoxSize.blockSize;\n",
" }\n",
" } else {\n",
" // Chrome <84 implements even older version of spec.\n",
" width = entry.contentRect.width;\n",
" height = entry.contentRect.height;\n",
" }\n",
"\n",
" // Keep the size of the canvas and rubber band canvas in sync with\n",
" // the canvas container.\n",
" if (entry.devicePixelContentBoxSize) {\n",
" // Chrome 84 implements new version of spec.\n",
" canvas.setAttribute(\n",
" 'width',\n",
" entry.devicePixelContentBoxSize[0].inlineSize\n",
" );\n",
" canvas.setAttribute(\n",
" 'height',\n",
" entry.devicePixelContentBoxSize[0].blockSize\n",
" );\n",
" } else {\n",
" canvas.setAttribute('width', width * fig.ratio);\n",
" canvas.setAttribute('height', height * fig.ratio);\n",
" }\n",
" canvas.setAttribute(\n",
" 'style',\n",
" 'width: ' + width + 'px; height: ' + height + 'px;'\n",
" );\n",
"\n",
" rubberband_canvas.setAttribute('width', width);\n",
" rubberband_canvas.setAttribute('height', height);\n",
"\n",
" // And update the size in Python. We ignore the initial 0/0 size\n",
" // that occurs as the element is placed into the DOM, which should\n",
" // otherwise not happen due to the minimum size styling.\n",
" if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
" fig.request_resize(width, height);\n",
" }\n",
" }\n",
" });\n",
" this.resizeObserverInstance.observe(canvas_div);\n",
"\n",
" function on_mouse_event_closure(name) {\n",
" return function (event) {\n",
" return fig.mouse_event(event, name);\n",
" };\n",
" }\n",
"\n",
" rubberband_canvas.addEventListener(\n",
" 'mousedown',\n",
" on_mouse_event_closure('button_press')\n",
" );\n",
" rubberband_canvas.addEventListener(\n",
" 'mouseup',\n",
" on_mouse_event_closure('button_release')\n",
" );\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband_canvas.addEventListener(\n",
" 'mousemove',\n",
" on_mouse_event_closure('motion_notify')\n",
" );\n",
"\n",
" rubberband_canvas.addEventListener(\n",
" 'mouseenter',\n",
" on_mouse_event_closure('figure_enter')\n",
" );\n",
" rubberband_canvas.addEventListener(\n",
" 'mouseleave',\n",
" on_mouse_event_closure('figure_leave')\n",
" );\n",
"\n",
" canvas_div.addEventListener('wheel', function (event) {\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" on_mouse_event_closure('scroll')(event);\n",
" });\n",
"\n",
" canvas_div.appendChild(canvas);\n",
" canvas_div.appendChild(rubberband_canvas);\n",
"\n",
" this.rubberband_context = rubberband_canvas.getContext('2d');\n",
" this.rubberband_context.strokeStyle = '#000000';\n",
"\n",
" this._resize_canvas = function (width, height, forward) {\n",
" if (forward) {\n",
" canvas_div.style.width = width + 'px';\n",
" canvas_div.style.height = height + 'px';\n",
" }\n",
" };\n",
"\n",
" // Disable right mouse context menu.\n",
" this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
" event.preventDefault();\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 toolbar = document.createElement('div');\n",
" toolbar.classList = 'mpl-toolbar';\n",
" this.root.appendChild(toolbar);\n",
"\n",
" function on_click_closure(name) {\n",
" return function (_event) {\n",
" return fig.toolbar_button_onclick(name);\n",
" };\n",
" }\n",
"\n",
" function on_mouseover_closure(tooltip) {\n",
" return function (event) {\n",
" if (!event.currentTarget.disabled) {\n",
" return fig.toolbar_button_onmouseover(tooltip);\n",
" }\n",
" };\n",
" }\n",
"\n",
" fig.buttons = {};\n",
" var buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'mpl-button-group';\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",
" /* Instead of a spacer, we start a new button group. */\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
" buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'mpl-button-group';\n",
" continue;\n",
" }\n",
"\n",
" var button = (fig.buttons[name] = document.createElement('button'));\n",
" button.classList = 'mpl-widget';\n",
" button.setAttribute('role', 'button');\n",
" button.setAttribute('aria-disabled', 'false');\n",
" button.addEventListener('click', on_click_closure(method_name));\n",
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
"\n",
" var icon_img = document.createElement('img');\n",
" icon_img.src = '_images/' + image + '.png';\n",
" icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
" icon_img.alt = tooltip;\n",
" button.appendChild(icon_img);\n",
"\n",
" buttonGroup.appendChild(button);\n",
" }\n",
"\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
"\n",
" var fmt_picker = document.createElement('select');\n",
" fmt_picker.classList = 'mpl-widget';\n",
" toolbar.appendChild(fmt_picker);\n",
" this.format_dropdown = fmt_picker;\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = document.createElement('option');\n",
" option.selected = fmt === mpl.default_extension;\n",
" option.innerHTML = fmt;\n",
" fmt_picker.appendChild(option);\n",
" }\n",
"\n",
" var status_bar = document.createElement('span');\n",
" status_bar.classList = 'mpl-message';\n",
" toolbar.appendChild(status_bar);\n",
" this.message = status_bar;\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",
"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",
"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], msg['forward']);\n",
" fig.send_message('refresh', {});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
" var x0 = msg['x0'] / fig.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
" var x1 = msg['x1'] / fig.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / fig.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,\n",
" 0,\n",
" fig.canvas.width / fig.ratio,\n",
" fig.canvas.height / fig.ratio\n",
" );\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",
" 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.handle_history_buttons = function (fig, msg) {\n",
" for (var key in msg) {\n",
" if (!(key in fig.buttons)) {\n",
" continue;\n",
" }\n",
" fig.buttons[key].disabled = !msg[key];\n",
" fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
" if (msg['mode'] === 'PAN') {\n",
" fig.buttons['Pan'].classList.add('active');\n",
" fig.buttons['Zoom'].classList.remove('active');\n",
" } else if (msg['mode'] === 'ZOOM') {\n",
" fig.buttons['Pan'].classList.remove('active');\n",
" fig.buttons['Zoom'].classList.add('active');\n",
" } else {\n",
" fig.buttons['Pan'].classList.remove('active');\n",
" fig.buttons['Zoom'].classList.remove('active');\n",
" }\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",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data\n",
" );\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" } else if (\n",
" typeof evt.data === 'string' &&\n",
" evt.data.slice(0, 21) === 'data:image/png;base64'\n",
" ) {\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(\n",
" \"No handler for the '\" + msg_type + \"' message type: \",\n",
" msg\n",
" );\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(\n",
" \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
" e,\n",
" e.stack,\n",
" msg\n",
" );\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",
" }\n",
" if (e.target) {\n",
" targ = e.target;\n",
" } else if (e.srcElement) {\n",
" targ = e.srcElement;\n",
" }\n",
" if (targ.nodeType === 3) {\n",
" // defeat Safari bug\n",
" targ = targ.parentNode;\n",
" }\n",
"\n",
" // pageX,Y are the mouse positions relative to the document\n",
" var boundingRect = targ.getBoundingClientRect();\n",
" var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
" var y = e.pageY - (boundingRect.top + document.body.scrollTop);\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",
" }\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",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * this.ratio;\n",
" var y = canvas_pos.y * this.ratio;\n",
"\n",
" this.send_message(name, {\n",
" x: x,\n",
" y: y,\n",
" button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event),\n",
" });\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",
" // Prevent repeat events\n",
" if (name === 'key_press') {\n",
" if (event.which === this._key) {\n",
" return;\n",
" } else {\n",
" this._key = event.which;\n",
" }\n",
" }\n",
" if (name === 'key_release') {\n",
" this._key = null;\n",
" }\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which !== 17) {\n",
" value += 'ctrl+';\n",
" }\n",
" if (event.altKey && event.which !== 18) {\n",
" value += 'alt+';\n",
" }\n",
" if (event.shiftKey && event.which !== 16) {\n",
" value += 'shift+';\n",
" }\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, 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",
"\n",
"///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
"// prettier-ignore\n",
"var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\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\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"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\";/* global mpl */\n",
"\n",
"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 = document.getElementById(id);\n",
" var ws_proxy = comm_websocket_adapter(comm);\n",
"\n",
" function ondownload(figure, _format) {\n",
" window.open(figure.canvas.toDataURL());\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy, ondownload, element);\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;\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",
" fig.cell_info[0].output_area.element.on(\n",
" 'cleared',\n",
" { fig: fig },\n",
" fig._remove_fig_handler\n",
" );\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function (fig, msg) {\n",
" var width = fig.canvas.width / fig.ratio;\n",
" fig.cell_info[0].output_area.element.off(\n",
" 'cleared',\n",
" fig._remove_fig_handler\n",
" );\n",
" fig.resizeObserverInstance.unobserve(fig.canvas_div);\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.innerHTML =\n",
" '<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 / this.ratio;\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] =\n",
" '<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 () {\n",
" fig.push_to_output();\n",
" }, 1000);\n",
"};\n",
"\n",
"mpl.figure.prototype._init_toolbar = function () {\n",
" var fig = this;\n",
"\n",
" var toolbar = document.createElement('div');\n",
" toolbar.classList = 'btn-toolbar';\n",
" this.root.appendChild(toolbar);\n",
"\n",
" function on_click_closure(name) {\n",
" return function (_event) {\n",
" return fig.toolbar_button_onclick(name);\n",
" };\n",
" }\n",
"\n",
" function on_mouseover_closure(tooltip) {\n",
" return function (event) {\n",
" if (!event.currentTarget.disabled) {\n",
" return fig.toolbar_button_onmouseover(tooltip);\n",
" }\n",
" };\n",
" }\n",
"\n",
" fig.buttons = {};\n",
" var buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'btn-group';\n",
" var button;\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",
" /* Instead of a spacer, we start a new button group. */\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
" buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'btn-group';\n",
" continue;\n",
" }\n",
"\n",
" button = fig.buttons[name] = document.createElement('button');\n",
" button.classList = 'btn btn-default';\n",
" button.href = '#';\n",
" button.title = name;\n",
" button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
" button.addEventListener('click', on_click_closure(method_name));\n",
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
" buttonGroup.appendChild(button);\n",
" }\n",
"\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = document.createElement('span');\n",
" status_bar.classList = 'mpl-message pull-right';\n",
" toolbar.appendChild(status_bar);\n",
" this.message = status_bar;\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = document.createElement('div');\n",
" buttongrp.classList = 'btn-group inline pull-right';\n",
" button = document.createElement('button');\n",
" button.classList = 'btn btn-mini btn-primary';\n",
" button.href = '#';\n",
" button.title = 'Stop Interaction';\n",
" button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
" button.addEventListener('click', function (_evt) {\n",
" fig.handle_close(fig, {});\n",
" });\n",
" button.addEventListener(\n",
" 'mouseover',\n",
" on_mouseover_closure('Stop Interaction')\n",
" );\n",
" buttongrp.appendChild(button);\n",
" var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
" titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
"};\n",
"\n",
"mpl.figure.prototype._remove_fig_handler = function (event) {\n",
" var fig = event.data.fig;\n",
" if (event.target !== this) {\n",
" // Ignore bubbled events from children.\n",
" return;\n",
" }\n",
" fig.close_ws(fig, {});\n",
"};\n",
"\n",
"mpl.figure.prototype._root_extra_style = function (el) {\n",
" el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
"};\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function (el) {\n",
" // this is important to make the div 'focusable\n",
" el.setAttribute('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",
" } else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\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",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which === 13) {\n",
" this.canvas_div.blur();\n",
" // select the cell after this one\n",
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
" IPython.notebook.select(index + 1);\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
" fig.ondownload(fig, null);\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(\n",
" 'matplotlib',\n",
" mpl.mpl_figure_comm\n",
" );\n",
"}\n"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4nOzdeXgUVb4+8AQU0XhxnIXxjvc3hbJLq+wKKoj7Nji4b4iKjuKGjOMUe9gRWVQEAoSEDqvsW2WBAGFNgEDYQiAsWQiQQCB7yNr9/v6o7kqadCfdXR0qXf1+nqee5053ddUJc5573jlV53v8QEREREQ+xU/rBhARERHRzcUASERERORjGACJiIiIfAwDIBEREZGPYQAkIiIi8jEMgEREREQ+hgGQiIiIyMcwABIRERH5GAZAIiIiIh/DAEhERETkYxgAiYiIiHwMAyARERGRj2EAJCIiIvIxDIBEREREPoYBkIiIiMjHMAASERER+RgGQCIiIiIfwwBIRERE5GMYAImIiIh8DAMgERERkY9hACQiIiLyMQyARERERD6GAZCIiIjIxzAAEhEREfkYBkAiIiIiH8MASERERORjGACJiIiIfAwDIBEREZGPYQAkIiIi8jEMgEREREQ+hgGQiIiIyMcwABIRERH5GAZAIiIiIh/DAEhERETkYxgAiYiIiHwMAyARERGRj2EAJCKXFBQU4IcffsCzzz6LP//5z/Dz80NgYKDdc3v37g0/Pz/4+fnB398fd955J1q2bIk33ngDq1atgslkcuqeAwYMgCAIbrV37969CAwMRG5urlu/18LEiROxbt26Gp/HxMTAz88PMTExN79RRKQrDIBE5JLU1FTcdddd6NWrFz799NM6A+D999+PuLg4xMXFYevWrQgODsbLL78MPz8/PPHEE8jLy6vznmfPnkVCQoJb7Z06dSr8/PyQmprq1u+1EBAQgAEDBtT4PD8/H3FxccjPz7/5jSIiXWEAJCKXmM1mmM1mAEB2dnadAbBDhw52vwsNDYWfnx/eeuut+moqAO0DYGVlJUpLS136jaMASETkKQyAROQ2NQEQAF566SX4+/sjLS2t1vvYewTs5+eHr776CosWLUK7du1w++2346GHHsKmTZuUcwIDA5VH0NWP6o9Qf//9dzz66KO44447EBAQgOeee87ubOP8+fPRunVrNGnSBO3bt8fSpUtrtCs1NRV+fn6YMmUKxo8fjxYtWqBx48aIjIxESUkJ/v3vf+Phhx9Gs2bNcPfdd+PRRx/F+vXra/xdNx69e/cG4PgR8IYNG/Doo4/i9ttvx5133olnnnkGsbGxNudY/y0SExPxzjvvoFmzZmjevDk+/vhjp2ZhiUhfGACJyG1qA+DcuXPh5+eHxYsX13ofRwGwRYsW6N69O1auXImIiAg8+eSTuOWWW3Du3DkAQEZGBr755hv4+flh7dq1yqNo6yPUiRMnwt/fH5988gkkScLatWvRo0cPBAQE4MSJE8q95s2bBz8/P7z++uuQJAlLly5FmzZtIAiC3QB47733ok+fPli9ejW2bNmC1NRU5OXl4aOPPsLixYuxfft2REVF4T//+Q8aNWqEsLAw5RpxcXG4/fbb8dJLLynttbbFXgBcunQp/Pz88Nxzz2H9+vVYsWIFunTpgiZNmmD37t3KedYA2LZtW4wePRrR0dGYMWMGbrvtNnz88ce1/vsTkf4wABKR29QGwMjISGXGrDaOAuBf//pXFBQUKJ9lZWWhUaNGmDx5svKZo0fA58+fxy233IJvvvnG5vPCwkLcc889yqNpk8mEe+65B4888ojNeenp6bj11lvtBsCWLVuivLy81r+psrISFRUVGDhwIDp16mTznaNHwDcGQJPJhL/97W948MEHbRbUFBYWonnz5ujZs6fymTUA/vTTTzbX/PLLL9G0aVPlsT4R+QYGQCJym9oAGBERoSoAvvPOOzXOveeee/DFF18o/9lRAAwODoafnx/i4+NRUVFhc7z99tto3rw5ACApKQl+fn6YPn16jXs9+eSTdgPgkCFD7P4dK1euRM+ePREQEGDziLdp06Y25zkbAK1tuzHUAcCgQYPQqFEjFBcXA6gKgKdOnbI5zzoLm5WVZbfNRKRPDIBE5Da1ATAoKEjVI+CvvvqqxrmCINiEJ0cBcMKECXbft7MejRo1AgDs3r0bfn5+WLJkSY17vf3223YDoL1AtmbNGvj5+eHNN9/EunXrEBcXh/j4eHzyySfw87P9f8XOBkBr2+z9+40fPx5+fn64cOECgKoAmJ2dbXPewoULvW6VNBGpxwBIRG5TGwBffPFF+Pv7Iz09vdb71EcAtM58rV69GvHx8XYPoPYZwN69e9sNgFOnTq1xbr9+/XDffffVeNT6/vvvux0A3ZkBZAAkIoABkIhU8EQZmPfee6/O+6gJgDNnzoSfnx+SkpJszktNTcUtt9xS5+Nnd94BtBcAX3vtNbRt29bms8zMTNx55501AuAf//hHu+Vx7L0DeO+996Jjx442wbKoqAjNmzfHY489pnzGAEhE1TEAEpHLIiIisGrVKiXEvfnmm1i1ahVWrVqlzDgBNQtBb9++HQsWLMArr7yilDepvojDETUB0BqaPv/8c8TGxiI+Pl6556RJk3DLLbfg888/x7p167Bjxw6sWLEC33//PUaPHq1co/oq4PDwcGUV8N///nfcd999ynm1BUDrv9WgQYOwbds2GI1GtGzZEq1bt64RAHv37o3mzZtj48aNiI+PV97bq20V8EsvvYQNGzZg5cqV6Natm8NVwAyARAQwABKRGwRBcPjuXPUgUX0rOD8/PwQEBOD+++/3yFZwzgZAABg2bBj+9re/oVGjRjUC1Pr169GnTx80a9YMt912GwRBwBtvvIGtW7faXGP+/Plo1aoVmjRpgjZt2iA0NBSvvvqqzQre2gIgAPz4449o0aIFbrvtNrRv3x7BwcFKMKvuyJEjeOyxx3DHHXc4VQdw/fr1eOSRR9C0aVMEBATg6aefxt69e23OYQAkouoYAImI3JCbm4u//OUv+Oyzz7RuChGRyxgAiYjqkJmZia+//hpr1qzBjh07EBYWho4dO6Jp06ZITEzUunlERC5jACQiqkNOTg5eeeUV/PWvf8Wtt96Ku+66C88//zz27dunddOIiNzCAEhERETkYxgAiYiIiHwMAyARERGRj2EAJCIiIvIxDIBEREREPoYBUAWTyYSMjAzk5eUhPz+fBw8ePHjw4OEFR15eHjIyMpwuRq9HDIAqZGRkONwNgQcPHjx48ODRsI+MjAyto4RmGABVyMvLUzqQ1v9rhgcPHjx48ODh3GGdwMnLy9M6SmiGAVCF/Px8+Pn5IT8/X+umEBERkZM4fjMAqsIORERE5H04fjMAqsIORERE5H04fjMAqsIORERE5H04fjMAqsIORERE5H04fjMAqsIORERE5H04fjMAqsIORERE5H04fussAM6ePRstWrTAbbfdhs6dO2PXrl0Oz42JibFbFPLkyZNO348diIiIyPtw/NZRAPz9999x6623Ijg4GElJSRg8eDACAgKQnp5u93xrAExOTkZmZqZyVFZWOn1PdiAiIiLvw/FbRwGwe/fu+OKLL2w+a9euHYYOHWr3fGsAzM3Ndfue7EBERETeh+O3TgJgWVkZGjdujLVr19p8/u2336JXr152f2MNgC1atMA999yDp556Ctu3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\" width=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ai = pyFAI.azimuthalIntegrator.AzimuthalIntegrator(detector=det)\n",
"ai.setFit2D(100,1160,1250)\n",
"ax = jupyter.plot1d(ai._integrate1d_ng(ds[4], 100, unit=\"r_mm\",correctSolidAngle=False, method=(\"no\", \"csr\", \"opencl\")))\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"IntegrationMethod(1d int, no split, CSR, cython) IntegrationMethod(1d int, no split, CSR, OpenCL, Portable Computing Language / Tesla V100-SXM2-32GB)\n"
]
},
{
"data": {
"text/plain": [
"<ErrorbarContainer object of 3 artists>"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"c,m=list(ai.engines.keys())[:2]\n",
"print(c,m)\n",
"img = ds[4]\n",
"sc = ai.engines[m].engine\n",
"csr = ai.engines[c].engine\n",
"res = sc.sigma_clip(img, variance=img, cutoff=0, cycle=3)\n",
"ax.errorbar(res[0]*1000, res[1], res[2])"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(0, 2)"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"m.target"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"import pyFAI.opencl.peak_finder\n",
"unit = pyFAI.units.to_unit(\"r_mm\")\n",
"pf = pyFAI.opencl.peak_finder.OCL_PeakFinder(csr.lut, \n",
" radius=ai.array_from_unit(unit=unit, scale=False),\n",
" image_size=img.size,\n",
" checksum=csr.lut_checksum,\n",
" empty=0,\n",
" unit=unit,\n",
" mask=mask,\n",
" bin_centers=csr.bin_centers,\n",
" platformid=m.target[0],\n",
" deviceid=m.target[1])"
]
},
{
"cell_type": "code",
"execution_count": 85,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"230566"
]
},
"execution_count": 85,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pf.set_profiling(True)\n",
"pol = ai.polarization(factor=0.95)\n",
"res = pf(img, error_model=\"azimuthal\", cutoff_pick=1.4, cutoff_clip=0, cycle=5, polarization=pol)\n",
"len(res[0])"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Profiling info for OpenCL: OCL_PeakFinder\n",
" copy raw H->D image : 0.984ms\n",
" cast u16_to_float : 0.062ms\n",
" memset_ng : 0.016ms\n",
" corrections : 0.141ms\n",
" csr_sigma_clip4 : 19.203ms\n",
" memset counter : 0.016ms\n",
" peak_search : 0.203ms\n",
" copy D->H counter : 0.016ms\n",
" copy D->D + cast uint16 intenity : 0.031ms\n",
" copy D->H peak_position : 0.047ms\n",
" copy D->H peak_intensty : 0.031ms\n",
" copy D->H background_avg : 0.016ms\n",
" copy D->H background_std : 0.016ms\n",
" copy raw H->D image : 0.984ms\n",
" cast u16_to_float : 0.062ms\n",
" memset_ng : 0.016ms\n",
" corrections : 0.141ms\n",
" csr_sigma_clip4 : 19.203ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.203ms\n",
" copy D->H counter : 0.031ms\n",
" copy D->D + cast uint16 intenity : 0.016ms\n",
" copy D->H peak_position : 0.062ms\n",
" copy D->H peak_intensty : 0.047ms\n",
" copy D->H background_avg : 0.016ms\n",
" copy D->H background_std : 0.031ms\n",
" copy raw H->D image : 0.984ms\n",
" cast u16_to_float : 0.062ms\n",
" memset_ng : 0.016ms\n",
" corrections : 0.125ms\n",
" csr_sigma_clip4 : 19.188ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.203ms\n",
" copy D->H counter : 0.031ms\n",
" copy D->D + cast uint16 intenity : 0.031ms\n",
" copy D->H peak_position : 0.062ms\n",
" copy D->H peak_intensty : 0.047ms\n",
" copy D->H background_avg : 0.016ms\n",
" copy D->H background_std : 0.016ms\n",
" copy raw H->D image : 0.781ms\n",
" cast u16_to_float : 0.062ms\n",
" memset_ng : 0.000ms\n",
" corrections : 0.141ms\n",
" csr_sigma_clip4 : 19.219ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.188ms\n",
" copy D->H counter : 0.031ms\n",
" copy D->D + cast uint16 intenity : 0.031ms\n",
" copy D->H peak_position : 0.062ms\n",
" copy D->H peak_intensty : 0.047ms\n",
" copy D->H background_avg : 0.016ms\n",
" copy D->H background_std : 0.031ms\n",
" copy raw H->D image : 0.969ms\n",
" cast u16_to_float : 0.062ms\n",
" memset_ng : 0.031ms\n",
" corrections : 0.125ms\n",
" csr_sigma_clip4 : 19.219ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.219ms\n",
" copy D->H counter : 0.000ms\n",
" copy D->D + cast uint16 intenity : 0.000ms\n",
" copy D->H peak_position : 0.000ms\n",
" copy D->H peak_intensty : 0.031ms\n",
" copy D->H background_avg : 0.000ms\n",
" copy D->H background_std : 0.031ms\n",
" copy raw H->D image : 1.000ms\n",
" cast u16_to_float : 0.094ms\n",
" memset_ng : 0.031ms\n",
" corrections : 0.125ms\n",
" csr_sigma_clip4 : 30.406ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.219ms\n",
" copy D->H counter : 0.000ms\n",
" copy D->D + cast uint16 intenity : 0.000ms\n",
" copy D->H peak_position : 0.031ms\n",
" copy D->H peak_intensty : 0.031ms\n",
" copy D->H background_avg : 0.031ms\n",
" copy D->H background_std : 0.031ms\n",
" copy raw H->D image : 1.000ms\n",
" cast u16_to_float : 0.062ms\n",
" memset_ng : 0.000ms\n",
" corrections : 0.125ms\n",
" csr_sigma_clip4 : 19.219ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.188ms\n",
" copy D->H counter : 0.031ms\n",
" copy D->D + cast uint16 intenity : 0.031ms\n",
" copy D->H peak_position : 0.062ms\n",
" copy D->H peak_intensty : 0.031ms\n",
" copy D->H background_avg : 0.031ms\n",
" copy D->H background_std : 0.031ms\n",
" copy raw H->D image : 1.000ms\n",
" cast u16_to_float : 0.062ms\n",
" memset_ng : 0.000ms\n",
" corrections : 0.125ms\n",
" csr_sigma_clip4 : 8.000ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.219ms\n",
" copy D->H counter : 0.031ms\n",
" copy D->D + cast uint16 intenity : 0.031ms\n",
" copy D->H peak_position : 0.062ms\n",
" copy D->H peak_intensty : 0.062ms\n",
" copy D->H background_avg : 0.000ms\n",
" copy D->H background_std : 0.000ms\n",
" copy raw H->D image : 1.000ms\n",
" cast u16_to_float : 0.062ms\n",
" memset_ng : 0.000ms\n",
" corrections : 0.125ms\n",
" csr_sigma_clip4 : 2.438ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.219ms\n",
" copy D->H counter : 0.031ms\n",
" copy D->D + cast uint16 intenity : 0.031ms\n",
" copy D->H peak_position : 0.094ms\n",
" copy D->H peak_intensty : 0.062ms\n",
" copy D->H background_avg : 0.031ms\n",
" copy D->H background_std : 0.031ms\n",
" copy raw H->D image : 1.000ms\n",
" cast u16_to_float : 0.094ms\n",
" memset_ng : 0.031ms\n",
" corrections : 0.156ms\n",
" csr_sigma_clip4 : 2.406ms\n",
" memset counter : 0.031ms\n",
" peak_search : 0.188ms\n",
" copy D->H counter : 0.031ms\n",
" copy D->D + cast uint16 intenity : 0.031ms\n",
" copy D->H peak_position : 0.062ms\n",
" copy D->H peak_intensty : 0.031ms\n",
" copy D->H background_avg : 0.031ms\n",
" copy D->H background_std : 0.000ms\n",
" copy raw H->D image : 1.031ms\n",
" cast u16_to_float : 0.062ms\n",
" memset_ng : 0.000ms\n",
" corrections : 0.125ms\n",
" csr_sigma_clip4 : 8.031ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.219ms\n",
" copy D->H counter : 0.000ms\n",
" copy D->D + cast uint16 intenity : 0.000ms\n",
" copy D->H peak_position : 0.062ms\n",
" copy D->H peak_intensty : 0.031ms\n",
" copy D->H background_avg : 0.031ms\n",
" copy D->H background_std : 0.031ms\n",
" copy raw H->D image : 1.000ms\n",
" cast u16_to_float : 0.062ms\n",
" memset_ng : 0.000ms\n",
" corrections : 0.125ms\n",
" csr_sigma_clip4 : 24.812ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.188ms\n",
" copy D->H counter : 0.031ms\n",
" copy D->D + cast uint16 intenity : 0.031ms\n",
" copy D->H peak_position : 0.062ms\n",
" copy D->H peak_intensty : 0.031ms\n",
" copy D->H background_avg : 0.031ms\n",
" copy D->H background_std : 0.031ms\n",
" copy raw H->D image : 1.000ms\n",
" cast u16_to_float : 0.062ms\n",
" memset_ng : 0.031ms\n",
" corrections : 0.156ms\n",
" csr_sigma_clip4 : 24.812ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.188ms\n",
" copy D->H counter : 0.000ms\n",
" copy D->D + cast uint16 intenity : 0.031ms\n",
" copy D->H peak_position : 0.062ms\n",
" copy D->H peak_intensty : 0.031ms\n",
" copy D->H background_avg : 0.031ms\n",
" copy D->H background_std : 0.000ms\n",
" copy raw H->D image : 0.969ms\n",
" cast u16_to_float : 0.062ms\n",
" memset_ng : 0.000ms\n",
" corrections : 0.125ms\n",
" csr_sigma_clip4 : 2.438ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.219ms\n",
" copy D->H counter : 0.000ms\n",
" copy D->D + cast uint16 intenity : 0.031ms\n",
" copy D->H peak_position : 0.062ms\n",
" copy D->H peak_intensty : 0.031ms\n",
" copy D->H background_avg : 0.031ms\n",
" copy D->H background_std : 0.031ms\n",
" copy raw H->D image : 1.000ms\n",
" cast u16_to_float : 0.062ms\n",
" memset_ng : 0.031ms\n",
" corrections : 0.156ms\n",
" csr_sigma_clip4 : 3.688ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.219ms\n",
" copy D->H counter : 0.031ms\n",
" copy D->D + cast uint16 intenity : 0.031ms\n",
" copy D->H peak_position : 0.062ms\n",
" copy D->H peak_intensty : 0.062ms\n",
" copy D->H background_avg : 0.000ms\n",
" copy D->H background_std : 0.031ms\n",
" copy raw H->D image : 0.938ms\n",
" cast u16_to_float : 0.062ms\n",
" copy raw H->D image : 1.000ms\n",
" cast u16_to_float : 0.094ms\n",
" copy H->D polarization : 1.469ms\n",
" memset_ng : 0.031ms\n",
" corrections : 0.188ms\n",
" csr_sigma_clip4 : 3.281ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.188ms\n",
" copy D->H counter : 0.031ms\n",
" copy D->D + cast uint16 intenity : 0.031ms\n",
" copy D->H peak_position : 0.094ms\n",
" copy D->H peak_intensty : 0.062ms\n",
" copy D->H background_avg : 0.031ms\n",
" copy D->H background_std : 0.031ms\n",
" copy raw H->D image : 1.000ms\n",
" cast u16_to_float : 0.062ms\n",
" memset_ng : 0.031ms\n",
" corrections : 0.156ms\n",
" csr_sigma_clip4 : 3.688ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.219ms\n",
" copy D->H counter : 0.031ms\n",
" copy D->D + cast uint16 intenity : 0.000ms\n",
" copy D->H peak_position : 0.062ms\n",
" copy D->H peak_intensty : 0.031ms\n",
" copy D->H background_avg : 0.031ms\n",
" copy D->H background_std : 0.031ms\n",
" copy raw H->D image : 0.812ms\n",
" cast u16_to_float : 0.062ms\n",
" memset_ng : 0.062ms\n",
" corrections : 0.188ms\n",
" csr_sigma_clip4 : 3.688ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.188ms\n",
" copy D->H counter : 0.000ms\n",
" copy D->D + cast uint16 intenity : 0.000ms\n",
" copy D->H peak_position : 0.000ms\n",
" copy D->H peak_intensty : 0.062ms\n",
" copy D->H background_avg : 0.000ms\n",
" copy D->H background_std : 0.000ms\n",
" copy raw H->D image : 0.938ms\n",
" cast u16_to_float : 0.062ms\n",
" copy H->D polarization : 1.438ms\n",
" memset_ng : 0.000ms\n",
" corrections : 0.188ms\n",
" csr_sigma_clip4 : 3.250ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.188ms\n",
" copy D->H counter : 0.062ms\n",
" copy D->D + cast uint16 intenity : 0.000ms\n",
" copy D->H peak_position : 0.125ms\n",
" copy D->H peak_intensty : 0.062ms\n",
" copy D->H background_avg : 0.000ms\n",
" copy D->H background_std : 0.000ms\n",
" copy raw H->D image : 1.000ms\n",
" cast u16_to_float : 0.062ms\n",
" memset_ng : 0.000ms\n",
" corrections : 0.188ms\n",
" csr_sigma_clip4 : 3.312ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.188ms\n",
" copy D->H counter : 0.000ms\n",
" copy D->D + cast uint16 intenity : 0.062ms\n",
" copy D->H peak_position : 0.125ms\n",
" copy D->H peak_intensty : 0.062ms\n",
" copy D->H background_avg : 0.000ms\n",
" copy D->H background_std : 0.000ms\n",
" copy raw H->D image : 1.062ms\n",
" cast u16_to_float : 0.062ms\n",
" memset_ng : 0.000ms\n",
" corrections : 0.188ms\n",
" csr_sigma_clip4 : 2.438ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.188ms\n",
" copy D->H counter : 0.000ms\n",
" copy D->D + cast uint16 intenity : 0.062ms\n",
" copy D->H peak_position : 0.062ms\n",
" copy D->H peak_intensty : 0.062ms\n",
" copy D->H background_avg : 0.000ms\n",
" copy D->H background_std : 0.000ms\n",
" copy raw H->D image : 1.000ms\n",
" cast u16_to_float : 0.125ms\n",
" memset_ng : 0.062ms\n",
" corrections : 0.125ms\n",
" csr_sigma_clip4 : 2.438ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.188ms\n",
" copy D->H counter : 0.062ms\n",
" copy D->D + cast uint16 intenity : 0.000ms\n",
" copy D->H peak_position : 0.000ms\n",
" copy D->H peak_intensty : 0.062ms\n",
" copy D->H background_avg : 0.000ms\n",
" copy D->H background_std : 0.000ms\n",
" copy raw H->D image : 1.000ms\n",
" cast u16_to_float : 0.125ms\n",
" memset_ng : 0.000ms\n",
" corrections : 0.188ms\n",
" csr_sigma_clip4 : 3.250ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.188ms\n",
" copy D->H counter : 0.000ms\n",
" copy D->D + cast uint16 intenity : 0.062ms\n",
" copy D->H peak_position : 0.125ms\n",
" copy D->H peak_intensty : 0.062ms\n",
" copy D->H background_avg : 0.000ms\n",
" copy D->H background_std : 0.000ms\n",
" copy raw H->D image : 0.938ms\n",
" cast u16_to_float : 0.125ms\n",
" memset_ng : 0.000ms\n",
" corrections : 0.188ms\n",
" csr_sigma_clip4 : 22.688ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.188ms\n",
" copy D->H counter : 0.062ms\n",
" copy D->D + cast uint16 intenity : 0.062ms\n",
" copy D->H peak_position : 0.188ms\n",
" copy D->H peak_intensty : 0.125ms\n",
" copy D->H background_avg : 0.000ms\n",
" copy D->H background_std : 0.000ms\n",
" copy raw H->D image : 1.188ms\n",
" cast u16_to_float : 0.062ms\n",
" memset_ng : 0.000ms\n",
" corrections : 0.188ms\n",
" csr_sigma_clip4 : 35.688ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.188ms\n",
" copy D->H counter : 0.062ms\n",
" copy D->D + cast uint16 intenity : 0.000ms\n",
" copy D->H peak_position : 0.125ms\n",
" copy D->H peak_intensty : 0.062ms\n",
" copy D->H background_avg : 0.000ms\n",
" copy D->H background_std : 0.000ms\n",
" copy raw H->D image : 1.125ms\n",
" cast u16_to_float : 0.062ms\n",
" memset_ng : 0.000ms\n",
" corrections : 0.188ms\n",
" csr_sigma_clip4 : 9.750ms\n",
" memset counter : 0.000ms\n",
" peak_search : 0.188ms\n",
" copy D->H counter : 0.062ms\n",
" copy D->D + cast uint16 intenity : 0.062ms\n",
" copy D->H peak_position : 0.125ms\n",
" copy D->H peak_intensty : 0.062ms\n",
" copy D->H background_avg : 0.062ms\n",
" copy D->H background_std : 0.000ms\n",
"________________________________________________________________________________\n",
" Total OpenCL execution time : 362.359ms\n"
]
}
],
"source": [
"print(\"\\n\".join(pf.log_profile()))\n",
"pf.set_profiling(False)"
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"/* global mpl */\n",
"window.mpl = {};\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(\n",
" '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",
"\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 = document.createElement('div');\n",
" this.root.setAttribute('style', 'display: inline-block');\n",
" this._root_extra_style(this.root);\n",
"\n",
" parent_element.appendChild(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 (fig.ratio !== 1) {\n",
" fig.send_message('set_dpi_ratio', { dpi_ratio: fig.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 = document.createElement('div');\n",
" titlebar.classList =\n",
" 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
" var titletext = document.createElement('div');\n",
" titletext.classList = 'ui-dialog-title';\n",
" titletext.setAttribute(\n",
" 'style',\n",
" 'width: 100%; text-align: center; padding: 3px;'\n",
" );\n",
" titlebar.appendChild(titletext);\n",
" this.root.appendChild(titlebar);\n",
" this.header = titletext;\n",
"};\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
"\n",
"mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
"\n",
"mpl.figure.prototype._init_canvas = function () {\n",
" var fig = this;\n",
"\n",
" var canvas_div = (this.canvas_div = document.createElement('div'));\n",
" canvas_div.setAttribute(\n",
" 'style',\n",
" 'border: 1px solid #ddd;' +\n",
" 'box-sizing: content-box;' +\n",
" 'clear: both;' +\n",
" 'min-height: 1px;' +\n",
" 'min-width: 1px;' +\n",
" 'outline: 0;' +\n",
" 'overflow: hidden;' +\n",
" 'position: relative;' +\n",
" 'resize: both;'\n",
" );\n",
"\n",
" function on_keyboard_event_closure(name) {\n",
" return function (event) {\n",
" return fig.key_event(event, name);\n",
" };\n",
" }\n",
"\n",
" canvas_div.addEventListener(\n",
" 'keydown',\n",
" on_keyboard_event_closure('key_press')\n",
" );\n",
" canvas_div.addEventListener(\n",
" 'keyup',\n",
" on_keyboard_event_closure('key_release')\n",
" );\n",
"\n",
" this._canvas_extra_style(canvas_div);\n",
" this.root.appendChild(canvas_div);\n",
"\n",
" var canvas = (this.canvas = document.createElement('canvas'));\n",
" canvas.classList.add('mpl-canvas');\n",
" canvas.setAttribute('style', 'box-sizing: content-box;');\n",
"\n",
" this.context = canvas.getContext('2d');\n",
"\n",
" var backingStore =\n",
" this.context.backingStorePixelRatio ||\n",
" this.context.webkitBackingStorePixelRatio ||\n",
" this.context.mozBackingStorePixelRatio ||\n",
" this.context.msBackingStorePixelRatio ||\n",
" this.context.oBackingStorePixelRatio ||\n",
" this.context.backingStorePixelRatio ||\n",
" 1;\n",
"\n",
" this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
" 'canvas'\n",
" ));\n",
" rubberband_canvas.setAttribute(\n",
" 'style',\n",
" 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
" );\n",
"\n",
" // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
" if (this.ResizeObserver === undefined) {\n",
" if (window.ResizeObserver !== undefined) {\n",
" this.ResizeObserver = window.ResizeObserver;\n",
" } else {\n",
" var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
" this.ResizeObserver = obs.ResizeObserver;\n",
" }\n",
" }\n",
"\n",
" this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
" var nentries = entries.length;\n",
" for (var i = 0; i < nentries; i++) {\n",
" var entry = entries[i];\n",
" var width, height;\n",
" if (entry.contentBoxSize) {\n",
" if (entry.contentBoxSize instanceof Array) {\n",
" // Chrome 84 implements new version of spec.\n",
" width = entry.contentBoxSize[0].inlineSize;\n",
" height = entry.contentBoxSize[0].blockSize;\n",
" } else {\n",
" // Firefox implements old version of spec.\n",
" width = entry.contentBoxSize.inlineSize;\n",
" height = entry.contentBoxSize.blockSize;\n",
" }\n",
" } else {\n",
" // Chrome <84 implements even older version of spec.\n",
" width = entry.contentRect.width;\n",
" height = entry.contentRect.height;\n",
" }\n",
"\n",
" // Keep the size of the canvas and rubber band canvas in sync with\n",
" // the canvas container.\n",
" if (entry.devicePixelContentBoxSize) {\n",
" // Chrome 84 implements new version of spec.\n",
" canvas.setAttribute(\n",
" 'width',\n",
" entry.devicePixelContentBoxSize[0].inlineSize\n",
" );\n",
" canvas.setAttribute(\n",
" 'height',\n",
" entry.devicePixelContentBoxSize[0].blockSize\n",
" );\n",
" } else {\n",
" canvas.setAttribute('width', width * fig.ratio);\n",
" canvas.setAttribute('height', height * fig.ratio);\n",
" }\n",
" canvas.setAttribute(\n",
" 'style',\n",
" 'width: ' + width + 'px; height: ' + height + 'px;'\n",
" );\n",
"\n",
" rubberband_canvas.setAttribute('width', width);\n",
" rubberband_canvas.setAttribute('height', height);\n",
"\n",
" // And update the size in Python. We ignore the initial 0/0 size\n",
" // that occurs as the element is placed into the DOM, which should\n",
" // otherwise not happen due to the minimum size styling.\n",
" if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
" fig.request_resize(width, height);\n",
" }\n",
" }\n",
" });\n",
" this.resizeObserverInstance.observe(canvas_div);\n",
"\n",
" function on_mouse_event_closure(name) {\n",
" return function (event) {\n",
" return fig.mouse_event(event, name);\n",
" };\n",
" }\n",
"\n",
" rubberband_canvas.addEventListener(\n",
" 'mousedown',\n",
" on_mouse_event_closure('button_press')\n",
" );\n",
" rubberband_canvas.addEventListener(\n",
" 'mouseup',\n",
" on_mouse_event_closure('button_release')\n",
" );\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband_canvas.addEventListener(\n",
" 'mousemove',\n",
" on_mouse_event_closure('motion_notify')\n",
" );\n",
"\n",
" rubberband_canvas.addEventListener(\n",
" 'mouseenter',\n",
" on_mouse_event_closure('figure_enter')\n",
" );\n",
" rubberband_canvas.addEventListener(\n",
" 'mouseleave',\n",
" on_mouse_event_closure('figure_leave')\n",
" );\n",
"\n",
" canvas_div.addEventListener('wheel', function (event) {\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" on_mouse_event_closure('scroll')(event);\n",
" });\n",
"\n",
" canvas_div.appendChild(canvas);\n",
" canvas_div.appendChild(rubberband_canvas);\n",
"\n",
" this.rubberband_context = rubberband_canvas.getContext('2d');\n",
" this.rubberband_context.strokeStyle = '#000000';\n",
"\n",
" this._resize_canvas = function (width, height, forward) {\n",
" if (forward) {\n",
" canvas_div.style.width = width + 'px';\n",
" canvas_div.style.height = height + 'px';\n",
" }\n",
" };\n",
"\n",
" // Disable right mouse context menu.\n",
" this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
" event.preventDefault();\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 toolbar = document.createElement('div');\n",
" toolbar.classList = 'mpl-toolbar';\n",
" this.root.appendChild(toolbar);\n",
"\n",
" function on_click_closure(name) {\n",
" return function (_event) {\n",
" return fig.toolbar_button_onclick(name);\n",
" };\n",
" }\n",
"\n",
" function on_mouseover_closure(tooltip) {\n",
" return function (event) {\n",
" if (!event.currentTarget.disabled) {\n",
" return fig.toolbar_button_onmouseover(tooltip);\n",
" }\n",
" };\n",
" }\n",
"\n",
" fig.buttons = {};\n",
" var buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'mpl-button-group';\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",
" /* Instead of a spacer, we start a new button group. */\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
" buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'mpl-button-group';\n",
" continue;\n",
" }\n",
"\n",
" var button = (fig.buttons[name] = document.createElement('button'));\n",
" button.classList = 'mpl-widget';\n",
" button.setAttribute('role', 'button');\n",
" button.setAttribute('aria-disabled', 'false');\n",
" button.addEventListener('click', on_click_closure(method_name));\n",
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
"\n",
" var icon_img = document.createElement('img');\n",
" icon_img.src = '_images/' + image + '.png';\n",
" icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
" icon_img.alt = tooltip;\n",
" button.appendChild(icon_img);\n",
"\n",
" buttonGroup.appendChild(button);\n",
" }\n",
"\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
"\n",
" var fmt_picker = document.createElement('select');\n",
" fmt_picker.classList = 'mpl-widget';\n",
" toolbar.appendChild(fmt_picker);\n",
" this.format_dropdown = fmt_picker;\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = document.createElement('option');\n",
" option.selected = fmt === mpl.default_extension;\n",
" option.innerHTML = fmt;\n",
" fmt_picker.appendChild(option);\n",
" }\n",
"\n",
" var status_bar = document.createElement('span');\n",
" status_bar.classList = 'mpl-message';\n",
" toolbar.appendChild(status_bar);\n",
" this.message = status_bar;\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",
"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",
"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], msg['forward']);\n",
" fig.send_message('refresh', {});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
" var x0 = msg['x0'] / fig.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
" var x1 = msg['x1'] / fig.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / fig.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,\n",
" 0,\n",
" fig.canvas.width / fig.ratio,\n",
" fig.canvas.height / fig.ratio\n",
" );\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",
" 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.handle_history_buttons = function (fig, msg) {\n",
" for (var key in msg) {\n",
" if (!(key in fig.buttons)) {\n",
" continue;\n",
" }\n",
" fig.buttons[key].disabled = !msg[key];\n",
" fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
" if (msg['mode'] === 'PAN') {\n",
" fig.buttons['Pan'].classList.add('active');\n",
" fig.buttons['Zoom'].classList.remove('active');\n",
" } else if (msg['mode'] === 'ZOOM') {\n",
" fig.buttons['Pan'].classList.remove('active');\n",
" fig.buttons['Zoom'].classList.add('active');\n",
" } else {\n",
" fig.buttons['Pan'].classList.remove('active');\n",
" fig.buttons['Zoom'].classList.remove('active');\n",
" }\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",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data\n",
" );\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" } else if (\n",
" typeof evt.data === 'string' &&\n",
" evt.data.slice(0, 21) === 'data:image/png;base64'\n",
" ) {\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(\n",
" \"No handler for the '\" + msg_type + \"' message type: \",\n",
" msg\n",
" );\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(\n",
" \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
" e,\n",
" e.stack,\n",
" msg\n",
" );\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",
" }\n",
" if (e.target) {\n",
" targ = e.target;\n",
" } else if (e.srcElement) {\n",
" targ = e.srcElement;\n",
" }\n",
" if (targ.nodeType === 3) {\n",
" // defeat Safari bug\n",
" targ = targ.parentNode;\n",
" }\n",
"\n",
" // pageX,Y are the mouse positions relative to the document\n",
" var boundingRect = targ.getBoundingClientRect();\n",
" var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
" var y = e.pageY - (boundingRect.top + document.body.scrollTop);\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",
" }\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",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * this.ratio;\n",
" var y = canvas_pos.y * this.ratio;\n",
"\n",
" this.send_message(name, {\n",
" x: x,\n",
" y: y,\n",
" button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event),\n",
" });\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",
" // Prevent repeat events\n",
" if (name === 'key_press') {\n",
" if (event.which === this._key) {\n",
" return;\n",
" } else {\n",
" this._key = event.which;\n",
" }\n",
" }\n",
" if (name === 'key_release') {\n",
" this._key = null;\n",
" }\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which !== 17) {\n",
" value += 'ctrl+';\n",
" }\n",
" if (event.altKey && event.which !== 18) {\n",
" value += 'alt+';\n",
" }\n",
" if (event.shiftKey && event.which !== 16) {\n",
" value += 'shift+';\n",
" }\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, 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",
"\n",
"///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
"// prettier-ignore\n",
"var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\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\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"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\";/* global mpl */\n",
"\n",
"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 = document.getElementById(id);\n",
" var ws_proxy = comm_websocket_adapter(comm);\n",
"\n",
" function ondownload(figure, _format) {\n",
" window.open(figure.canvas.toDataURL());\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy, ondownload, element);\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;\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",
" fig.cell_info[0].output_area.element.on(\n",
" 'cleared',\n",
" { fig: fig },\n",
" fig._remove_fig_handler\n",
" );\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function (fig, msg) {\n",
" var width = fig.canvas.width / fig.ratio;\n",
" fig.cell_info[0].output_area.element.off(\n",
" 'cleared',\n",
" fig._remove_fig_handler\n",
" );\n",
" fig.resizeObserverInstance.unobserve(fig.canvas_div);\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.innerHTML =\n",
" '<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 / this.ratio;\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] =\n",
" '<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 () {\n",
" fig.push_to_output();\n",
" }, 1000);\n",
"};\n",
"\n",
"mpl.figure.prototype._init_toolbar = function () {\n",
" var fig = this;\n",
"\n",
" var toolbar = document.createElement('div');\n",
" toolbar.classList = 'btn-toolbar';\n",
" this.root.appendChild(toolbar);\n",
"\n",
" function on_click_closure(name) {\n",
" return function (_event) {\n",
" return fig.toolbar_button_onclick(name);\n",
" };\n",
" }\n",
"\n",
" function on_mouseover_closure(tooltip) {\n",
" return function (event) {\n",
" if (!event.currentTarget.disabled) {\n",
" return fig.toolbar_button_onmouseover(tooltip);\n",
" }\n",
" };\n",
" }\n",
"\n",
" fig.buttons = {};\n",
" var buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'btn-group';\n",
" var button;\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",
" /* Instead of a spacer, we start a new button group. */\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
" buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'btn-group';\n",
" continue;\n",
" }\n",
"\n",
" button = fig.buttons[name] = document.createElement('button');\n",
" button.classList = 'btn btn-default';\n",
" button.href = '#';\n",
" button.title = name;\n",
" button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
" button.addEventListener('click', on_click_closure(method_name));\n",
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
" buttonGroup.appendChild(button);\n",
" }\n",
"\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = document.createElement('span');\n",
" status_bar.classList = 'mpl-message pull-right';\n",
" toolbar.appendChild(status_bar);\n",
" this.message = status_bar;\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = document.createElement('div');\n",
" buttongrp.classList = 'btn-group inline pull-right';\n",
" button = document.createElement('button');\n",
" button.classList = 'btn btn-mini btn-primary';\n",
" button.href = '#';\n",
" button.title = 'Stop Interaction';\n",
" button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
" button.addEventListener('click', function (_evt) {\n",
" fig.handle_close(fig, {});\n",
" });\n",
" button.addEventListener(\n",
" 'mouseover',\n",
" on_mouseover_closure('Stop Interaction')\n",
" );\n",
" buttongrp.appendChild(button);\n",
" var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
" titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
"};\n",
"\n",
"mpl.figure.prototype._remove_fig_handler = function (event) {\n",
" var fig = event.data.fig;\n",
" if (event.target !== this) {\n",
" // Ignore bubbled events from children.\n",
" return;\n",
" }\n",
" fig.close_ws(fig, {});\n",
"};\n",
"\n",
"mpl.figure.prototype._root_extra_style = function (el) {\n",
" el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
"};\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function (el) {\n",
" // this is important to make the div 'focusable\n",
" el.setAttribute('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",
" } else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\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",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which === 13) {\n",
" this.canvas_div.blur();\n",
" // select the cell after this one\n",
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
" IPython.notebook.select(index + 1);\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
" fig.ondownload(fig, null);\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(\n",
" 'matplotlib',\n",
" mpl.mpl_figure_comm\n",
" );\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=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<AxesSubplot:>"
]
},
"execution_count": 72,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"rec = numpy.zeros(ai.detector.shape)\n",
"recl = rec.ravel()\n",
"recl[res.index] = res.intensity\n",
"from matplotlib.colors import LogNorm \n",
"#fig,ax = subplots()\n",
"jupyter.display(rec)\n",
"#ax.imshow(rec+1, norm=LogNorm(vmin=0, vmax=1+recl.max()))"
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {},
"outputs": [],
"source": [
"npt = [len(pf(img, error_model=\"azimuthal\", cutoff_pick=5, cutoff_clip=5, cycle=10, polarization=pol)[0]) for img in ds]"
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"/* global mpl */\n",
"window.mpl = {};\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(\n",
" '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",
"\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 = document.createElement('div');\n",
" this.root.setAttribute('style', 'display: inline-block');\n",
" this._root_extra_style(this.root);\n",
"\n",
" parent_element.appendChild(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 (fig.ratio !== 1) {\n",
" fig.send_message('set_dpi_ratio', { dpi_ratio: fig.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 = document.createElement('div');\n",
" titlebar.classList =\n",
" 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
" var titletext = document.createElement('div');\n",
" titletext.classList = 'ui-dialog-title';\n",
" titletext.setAttribute(\n",
" 'style',\n",
" 'width: 100%; text-align: center; padding: 3px;'\n",
" );\n",
" titlebar.appendChild(titletext);\n",
" this.root.appendChild(titlebar);\n",
" this.header = titletext;\n",
"};\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
"\n",
"mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
"\n",
"mpl.figure.prototype._init_canvas = function () {\n",
" var fig = this;\n",
"\n",
" var canvas_div = (this.canvas_div = document.createElement('div'));\n",
" canvas_div.setAttribute(\n",
" 'style',\n",
" 'border: 1px solid #ddd;' +\n",
" 'box-sizing: content-box;' +\n",
" 'clear: both;' +\n",
" 'min-height: 1px;' +\n",
" 'min-width: 1px;' +\n",
" 'outline: 0;' +\n",
" 'overflow: hidden;' +\n",
" 'position: relative;' +\n",
" 'resize: both;'\n",
" );\n",
"\n",
" function on_keyboard_event_closure(name) {\n",
" return function (event) {\n",
" return fig.key_event(event, name);\n",
" };\n",
" }\n",
"\n",
" canvas_div.addEventListener(\n",
" 'keydown',\n",
" on_keyboard_event_closure('key_press')\n",
" );\n",
" canvas_div.addEventListener(\n",
" 'keyup',\n",
" on_keyboard_event_closure('key_release')\n",
" );\n",
"\n",
" this._canvas_extra_style(canvas_div);\n",
" this.root.appendChild(canvas_div);\n",
"\n",
" var canvas = (this.canvas = document.createElement('canvas'));\n",
" canvas.classList.add('mpl-canvas');\n",
" canvas.setAttribute('style', 'box-sizing: content-box;');\n",
"\n",
" this.context = canvas.getContext('2d');\n",
"\n",
" var backingStore =\n",
" this.context.backingStorePixelRatio ||\n",
" this.context.webkitBackingStorePixelRatio ||\n",
" this.context.mozBackingStorePixelRatio ||\n",
" this.context.msBackingStorePixelRatio ||\n",
" this.context.oBackingStorePixelRatio ||\n",
" this.context.backingStorePixelRatio ||\n",
" 1;\n",
"\n",
" this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
" 'canvas'\n",
" ));\n",
" rubberband_canvas.setAttribute(\n",
" 'style',\n",
" 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
" );\n",
"\n",
" // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
" if (this.ResizeObserver === undefined) {\n",
" if (window.ResizeObserver !== undefined) {\n",
" this.ResizeObserver = window.ResizeObserver;\n",
" } else {\n",
" var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
" this.ResizeObserver = obs.ResizeObserver;\n",
" }\n",
" }\n",
"\n",
" this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
" var nentries = entries.length;\n",
" for (var i = 0; i < nentries; i++) {\n",
" var entry = entries[i];\n",
" var width, height;\n",
" if (entry.contentBoxSize) {\n",
" if (entry.contentBoxSize instanceof Array) {\n",
" // Chrome 84 implements new version of spec.\n",
" width = entry.contentBoxSize[0].inlineSize;\n",
" height = entry.contentBoxSize[0].blockSize;\n",
" } else {\n",
" // Firefox implements old version of spec.\n",
" width = entry.contentBoxSize.inlineSize;\n",
" height = entry.contentBoxSize.blockSize;\n",
" }\n",
" } else {\n",
" // Chrome <84 implements even older version of spec.\n",
" width = entry.contentRect.width;\n",
" height = entry.contentRect.height;\n",
" }\n",
"\n",
" // Keep the size of the canvas and rubber band canvas in sync with\n",
" // the canvas container.\n",
" if (entry.devicePixelContentBoxSize) {\n",
" // Chrome 84 implements new version of spec.\n",
" canvas.setAttribute(\n",
" 'width',\n",
" entry.devicePixelContentBoxSize[0].inlineSize\n",
" );\n",
" canvas.setAttribute(\n",
" 'height',\n",
" entry.devicePixelContentBoxSize[0].blockSize\n",
" );\n",
" } else {\n",
" canvas.setAttribute('width', width * fig.ratio);\n",
" canvas.setAttribute('height', height * fig.ratio);\n",
" }\n",
" canvas.setAttribute(\n",
" 'style',\n",
" 'width: ' + width + 'px; height: ' + height + 'px;'\n",
" );\n",
"\n",
" rubberband_canvas.setAttribute('width', width);\n",
" rubberband_canvas.setAttribute('height', height);\n",
"\n",
" // And update the size in Python. We ignore the initial 0/0 size\n",
" // that occurs as the element is placed into the DOM, which should\n",
" // otherwise not happen due to the minimum size styling.\n",
" if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
" fig.request_resize(width, height);\n",
" }\n",
" }\n",
" });\n",
" this.resizeObserverInstance.observe(canvas_div);\n",
"\n",
" function on_mouse_event_closure(name) {\n",
" return function (event) {\n",
" return fig.mouse_event(event, name);\n",
" };\n",
" }\n",
"\n",
" rubberband_canvas.addEventListener(\n",
" 'mousedown',\n",
" on_mouse_event_closure('button_press')\n",
" );\n",
" rubberband_canvas.addEventListener(\n",
" 'mouseup',\n",
" on_mouse_event_closure('button_release')\n",
" );\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband_canvas.addEventListener(\n",
" 'mousemove',\n",
" on_mouse_event_closure('motion_notify')\n",
" );\n",
"\n",
" rubberband_canvas.addEventListener(\n",
" 'mouseenter',\n",
" on_mouse_event_closure('figure_enter')\n",
" );\n",
" rubberband_canvas.addEventListener(\n",
" 'mouseleave',\n",
" on_mouse_event_closure('figure_leave')\n",
" );\n",
"\n",
" canvas_div.addEventListener('wheel', function (event) {\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" on_mouse_event_closure('scroll')(event);\n",
" });\n",
"\n",
" canvas_div.appendChild(canvas);\n",
" canvas_div.appendChild(rubberband_canvas);\n",
"\n",
" this.rubberband_context = rubberband_canvas.getContext('2d');\n",
" this.rubberband_context.strokeStyle = '#000000';\n",
"\n",
" this._resize_canvas = function (width, height, forward) {\n",
" if (forward) {\n",
" canvas_div.style.width = width + 'px';\n",
" canvas_div.style.height = height + 'px';\n",
" }\n",
" };\n",
"\n",
" // Disable right mouse context menu.\n",
" this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
" event.preventDefault();\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 toolbar = document.createElement('div');\n",
" toolbar.classList = 'mpl-toolbar';\n",
" this.root.appendChild(toolbar);\n",
"\n",
" function on_click_closure(name) {\n",
" return function (_event) {\n",
" return fig.toolbar_button_onclick(name);\n",
" };\n",
" }\n",
"\n",
" function on_mouseover_closure(tooltip) {\n",
" return function (event) {\n",
" if (!event.currentTarget.disabled) {\n",
" return fig.toolbar_button_onmouseover(tooltip);\n",
" }\n",
" };\n",
" }\n",
"\n",
" fig.buttons = {};\n",
" var buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'mpl-button-group';\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",
" /* Instead of a spacer, we start a new button group. */\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
" buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'mpl-button-group';\n",
" continue;\n",
" }\n",
"\n",
" var button = (fig.buttons[name] = document.createElement('button'));\n",
" button.classList = 'mpl-widget';\n",
" button.setAttribute('role', 'button');\n",
" button.setAttribute('aria-disabled', 'false');\n",
" button.addEventListener('click', on_click_closure(method_name));\n",
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
"\n",
" var icon_img = document.createElement('img');\n",
" icon_img.src = '_images/' + image + '.png';\n",
" icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
" icon_img.alt = tooltip;\n",
" button.appendChild(icon_img);\n",
"\n",
" buttonGroup.appendChild(button);\n",
" }\n",
"\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
"\n",
" var fmt_picker = document.createElement('select');\n",
" fmt_picker.classList = 'mpl-widget';\n",
" toolbar.appendChild(fmt_picker);\n",
" this.format_dropdown = fmt_picker;\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = document.createElement('option');\n",
" option.selected = fmt === mpl.default_extension;\n",
" option.innerHTML = fmt;\n",
" fmt_picker.appendChild(option);\n",
" }\n",
"\n",
" var status_bar = document.createElement('span');\n",
" status_bar.classList = 'mpl-message';\n",
" toolbar.appendChild(status_bar);\n",
" this.message = status_bar;\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",
"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",
"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], msg['forward']);\n",
" fig.send_message('refresh', {});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
" var x0 = msg['x0'] / fig.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
" var x1 = msg['x1'] / fig.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / fig.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,\n",
" 0,\n",
" fig.canvas.width / fig.ratio,\n",
" fig.canvas.height / fig.ratio\n",
" );\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",
" 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.handle_history_buttons = function (fig, msg) {\n",
" for (var key in msg) {\n",
" if (!(key in fig.buttons)) {\n",
" continue;\n",
" }\n",
" fig.buttons[key].disabled = !msg[key];\n",
" fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
" if (msg['mode'] === 'PAN') {\n",
" fig.buttons['Pan'].classList.add('active');\n",
" fig.buttons['Zoom'].classList.remove('active');\n",
" } else if (msg['mode'] === 'ZOOM') {\n",
" fig.buttons['Pan'].classList.remove('active');\n",
" fig.buttons['Zoom'].classList.add('active');\n",
" } else {\n",
" fig.buttons['Pan'].classList.remove('active');\n",
" fig.buttons['Zoom'].classList.remove('active');\n",
" }\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",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data\n",
" );\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" } else if (\n",
" typeof evt.data === 'string' &&\n",
" evt.data.slice(0, 21) === 'data:image/png;base64'\n",
" ) {\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(\n",
" \"No handler for the '\" + msg_type + \"' message type: \",\n",
" msg\n",
" );\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(\n",
" \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
" e,\n",
" e.stack,\n",
" msg\n",
" );\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",
" }\n",
" if (e.target) {\n",
" targ = e.target;\n",
" } else if (e.srcElement) {\n",
" targ = e.srcElement;\n",
" }\n",
" if (targ.nodeType === 3) {\n",
" // defeat Safari bug\n",
" targ = targ.parentNode;\n",
" }\n",
"\n",
" // pageX,Y are the mouse positions relative to the document\n",
" var boundingRect = targ.getBoundingClientRect();\n",
" var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
" var y = e.pageY - (boundingRect.top + document.body.scrollTop);\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",
" }\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",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * this.ratio;\n",
" var y = canvas_pos.y * this.ratio;\n",
"\n",
" this.send_message(name, {\n",
" x: x,\n",
" y: y,\n",
" button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event),\n",
" });\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",
" // Prevent repeat events\n",
" if (name === 'key_press') {\n",
" if (event.which === this._key) {\n",
" return;\n",
" } else {\n",
" this._key = event.which;\n",
" }\n",
" }\n",
" if (name === 'key_release') {\n",
" this._key = null;\n",
" }\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which !== 17) {\n",
" value += 'ctrl+';\n",
" }\n",
" if (event.altKey && event.which !== 18) {\n",
" value += 'alt+';\n",
" }\n",
" if (event.shiftKey && event.which !== 16) {\n",
" value += 'shift+';\n",
" }\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, 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",
"\n",
"///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
"// prettier-ignore\n",
"var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\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\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"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\";/* global mpl */\n",
"\n",
"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 = document.getElementById(id);\n",
" var ws_proxy = comm_websocket_adapter(comm);\n",
"\n",
" function ondownload(figure, _format) {\n",
" window.open(figure.canvas.toDataURL());\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy, ondownload, element);\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;\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",
" fig.cell_info[0].output_area.element.on(\n",
" 'cleared',\n",
" { fig: fig },\n",
" fig._remove_fig_handler\n",
" );\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function (fig, msg) {\n",
" var width = fig.canvas.width / fig.ratio;\n",
" fig.cell_info[0].output_area.element.off(\n",
" 'cleared',\n",
" fig._remove_fig_handler\n",
" );\n",
" fig.resizeObserverInstance.unobserve(fig.canvas_div);\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.innerHTML =\n",
" '<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 / this.ratio;\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] =\n",
" '<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 () {\n",
" fig.push_to_output();\n",
" }, 1000);\n",
"};\n",
"\n",
"mpl.figure.prototype._init_toolbar = function () {\n",
" var fig = this;\n",
"\n",
" var toolbar = document.createElement('div');\n",
" toolbar.classList = 'btn-toolbar';\n",
" this.root.appendChild(toolbar);\n",
"\n",
" function on_click_closure(name) {\n",
" return function (_event) {\n",
" return fig.toolbar_button_onclick(name);\n",
" };\n",
" }\n",
"\n",
" function on_mouseover_closure(tooltip) {\n",
" return function (event) {\n",
" if (!event.currentTarget.disabled) {\n",
" return fig.toolbar_button_onmouseover(tooltip);\n",
" }\n",
" };\n",
" }\n",
"\n",
" fig.buttons = {};\n",
" var buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'btn-group';\n",
" var button;\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",
" /* Instead of a spacer, we start a new button group. */\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
" buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'btn-group';\n",
" continue;\n",
" }\n",
"\n",
" button = fig.buttons[name] = document.createElement('button');\n",
" button.classList = 'btn btn-default';\n",
" button.href = '#';\n",
" button.title = name;\n",
" button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
" button.addEventListener('click', on_click_closure(method_name));\n",
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
" buttonGroup.appendChild(button);\n",
" }\n",
"\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = document.createElement('span');\n",
" status_bar.classList = 'mpl-message pull-right';\n",
" toolbar.appendChild(status_bar);\n",
" this.message = status_bar;\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = document.createElement('div');\n",
" buttongrp.classList = 'btn-group inline pull-right';\n",
" button = document.createElement('button');\n",
" button.classList = 'btn btn-mini btn-primary';\n",
" button.href = '#';\n",
" button.title = 'Stop Interaction';\n",
" button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
" button.addEventListener('click', function (_evt) {\n",
" fig.handle_close(fig, {});\n",
" });\n",
" button.addEventListener(\n",
" 'mouseover',\n",
" on_mouseover_closure('Stop Interaction')\n",
" );\n",
" buttongrp.appendChild(button);\n",
" var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
" titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
"};\n",
"\n",
"mpl.figure.prototype._remove_fig_handler = function (event) {\n",
" var fig = event.data.fig;\n",
" if (event.target !== this) {\n",
" // Ignore bubbled events from children.\n",
" return;\n",
" }\n",
" fig.close_ws(fig, {});\n",
"};\n",
"\n",
"mpl.figure.prototype._root_extra_style = function (el) {\n",
" el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
"};\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function (el) {\n",
" // this is important to make the div 'focusable\n",
" el.setAttribute('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",
" } else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\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",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which === 13) {\n",
" this.canvas_div.blur();\n",
" // select the cell after this one\n",
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
" IPython.notebook.select(index + 1);\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
" fig.ondownload(fig, null);\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(\n",
" 'matplotlib',\n",
" mpl.mpl_figure_comm\n",
" );\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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qqrSf9YW5ta5c2csWbLE5Wdz585Fnz59ALSNOd6suLgYPj4+WLZsmfRza+ghkMbm43wIJCQkRD8mLy+PD4HcQRgAm+Evf/kLfHx8cODAAZdyDdeuXdOPCQoKgo+PD7Zu3YqkpCSMHDnyjn7U/2ZTp07FoUOHkJmZicTEREybNg3t2rXDnj17AMg9t/rcfAkYkH9+7733Hg4cOICMjAzExsbC398f3t7eOHfuHAD55xcfH4977rkHc+bMQWpqKtavX49OnTph3bp1+jGyz7GmpgYPPPAAVFWt857sc3v99dfRs2dPvQzM1q1b8cMf/hDvv/++fozMcwwLC8Pu3buRkZGBPXv2wM/PD8888wyuX78OQL65lZWV4dixYzh27BgsFgs+++wzHDt2DFlZWQDcm8/EiRPRq1cvREZGwmq14vnnn2cZmDsIA2Az1Fek1WKxYNWqVfoxzuKY3bp1g5eXF/r3768/JXyne/PNN6EoCjp06ID7778fgwYN0sMfIPfc6nNrAJR9fs46XO3bt0ePHj3w8ssvIzk5WX9f9vkBwM6dO+Hr6wsvLy889thjLk8BA/LPMTw8HBaLRX9S9mayz+3WQskPPfQQpk+fjsrKSv0YmecYEhKChx56CB06dEC3bt3wzjvvoKSkRH9ftrnt37+/3v3u9ddfB+DefCoqKhAQEKAXbvf390d2drYJs6H6MAASEREReRgGQCIiIiIPwwBIRERE5GEYAImIiIg8DAMgERERkYdhACQiIiLyMAyARERERB6GAZCIiIjIwzAAEhEREXkYBkAiIiIiD8MASERERORhGACJiIiIPAwDIBEREZGHYQAkIiIi8jAMgEREREQehgGQiIiIyMMwABIRERF5GAZAIiIiIg/DAEhERETkYRgAiYiIiDwMAyARERGRh2EAJCIiIvIwDIBEREREHoYBkIiIiMjDMAASEREReRgGQCIiIiIPwwBIRERE5GEYAImIiIg8DAMgERERkYdhACQiIiLyMAyARERERB6GAZCIiIjIw/x/sIWcpevu5F4AAAAASUVORK5CYII=\" width=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x7ffa8c3b6a90>]"
]
},
"execution_count": 78,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"fig,ax = subplots()\n",
"ax.plot(npt)"
]
},
{
"cell_type": "code",
"execution_count": 87,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"/* global mpl */\n",
"window.mpl = {};\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(\n",
" '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",
"\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 = document.createElement('div');\n",
" this.root.setAttribute('style', 'display: inline-block');\n",
" this._root_extra_style(this.root);\n",
"\n",
" parent_element.appendChild(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 (fig.ratio !== 1) {\n",
" fig.send_message('set_dpi_ratio', { dpi_ratio: fig.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 = document.createElement('div');\n",
" titlebar.classList =\n",
" 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
" var titletext = document.createElement('div');\n",
" titletext.classList = 'ui-dialog-title';\n",
" titletext.setAttribute(\n",
" 'style',\n",
" 'width: 100%; text-align: center; padding: 3px;'\n",
" );\n",
" titlebar.appendChild(titletext);\n",
" this.root.appendChild(titlebar);\n",
" this.header = titletext;\n",
"};\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
"\n",
"mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
"\n",
"mpl.figure.prototype._init_canvas = function () {\n",
" var fig = this;\n",
"\n",
" var canvas_div = (this.canvas_div = document.createElement('div'));\n",
" canvas_div.setAttribute(\n",
" 'style',\n",
" 'border: 1px solid #ddd;' +\n",
" 'box-sizing: content-box;' +\n",
" 'clear: both;' +\n",
" 'min-height: 1px;' +\n",
" 'min-width: 1px;' +\n",
" 'outline: 0;' +\n",
" 'overflow: hidden;' +\n",
" 'position: relative;' +\n",
" 'resize: both;'\n",
" );\n",
"\n",
" function on_keyboard_event_closure(name) {\n",
" return function (event) {\n",
" return fig.key_event(event, name);\n",
" };\n",
" }\n",
"\n",
" canvas_div.addEventListener(\n",
" 'keydown',\n",
" on_keyboard_event_closure('key_press')\n",
" );\n",
" canvas_div.addEventListener(\n",
" 'keyup',\n",
" on_keyboard_event_closure('key_release')\n",
" );\n",
"\n",
" this._canvas_extra_style(canvas_div);\n",
" this.root.appendChild(canvas_div);\n",
"\n",
" var canvas = (this.canvas = document.createElement('canvas'));\n",
" canvas.classList.add('mpl-canvas');\n",
" canvas.setAttribute('style', 'box-sizing: content-box;');\n",
"\n",
" this.context = canvas.getContext('2d');\n",
"\n",
" var backingStore =\n",
" this.context.backingStorePixelRatio ||\n",
" this.context.webkitBackingStorePixelRatio ||\n",
" this.context.mozBackingStorePixelRatio ||\n",
" this.context.msBackingStorePixelRatio ||\n",
" this.context.oBackingStorePixelRatio ||\n",
" this.context.backingStorePixelRatio ||\n",
" 1;\n",
"\n",
" this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
" 'canvas'\n",
" ));\n",
" rubberband_canvas.setAttribute(\n",
" 'style',\n",
" 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
" );\n",
"\n",
" // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
" if (this.ResizeObserver === undefined) {\n",
" if (window.ResizeObserver !== undefined) {\n",
" this.ResizeObserver = window.ResizeObserver;\n",
" } else {\n",
" var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
" this.ResizeObserver = obs.ResizeObserver;\n",
" }\n",
" }\n",
"\n",
" this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
" var nentries = entries.length;\n",
" for (var i = 0; i < nentries; i++) {\n",
" var entry = entries[i];\n",
" var width, height;\n",
" if (entry.contentBoxSize) {\n",
" if (entry.contentBoxSize instanceof Array) {\n",
" // Chrome 84 implements new version of spec.\n",
" width = entry.contentBoxSize[0].inlineSize;\n",
" height = entry.contentBoxSize[0].blockSize;\n",
" } else {\n",
" // Firefox implements old version of spec.\n",
" width = entry.contentBoxSize.inlineSize;\n",
" height = entry.contentBoxSize.blockSize;\n",
" }\n",
" } else {\n",
" // Chrome <84 implements even older version of spec.\n",
" width = entry.contentRect.width;\n",
" height = entry.contentRect.height;\n",
" }\n",
"\n",
" // Keep the size of the canvas and rubber band canvas in sync with\n",
" // the canvas container.\n",
" if (entry.devicePixelContentBoxSize) {\n",
" // Chrome 84 implements new version of spec.\n",
" canvas.setAttribute(\n",
" 'width',\n",
" entry.devicePixelContentBoxSize[0].inlineSize\n",
" );\n",
" canvas.setAttribute(\n",
" 'height',\n",
" entry.devicePixelContentBoxSize[0].blockSize\n",
" );\n",
" } else {\n",
" canvas.setAttribute('width', width * fig.ratio);\n",
" canvas.setAttribute('height', height * fig.ratio);\n",
" }\n",
" canvas.setAttribute(\n",
" 'style',\n",
" 'width: ' + width + 'px; height: ' + height + 'px;'\n",
" );\n",
"\n",
" rubberband_canvas.setAttribute('width', width);\n",
" rubberband_canvas.setAttribute('height', height);\n",
"\n",
" // And update the size in Python. We ignore the initial 0/0 size\n",
" // that occurs as the element is placed into the DOM, which should\n",
" // otherwise not happen due to the minimum size styling.\n",
" if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
" fig.request_resize(width, height);\n",
" }\n",
" }\n",
" });\n",
" this.resizeObserverInstance.observe(canvas_div);\n",
"\n",
" function on_mouse_event_closure(name) {\n",
" return function (event) {\n",
" return fig.mouse_event(event, name);\n",
" };\n",
" }\n",
"\n",
" rubberband_canvas.addEventListener(\n",
" 'mousedown',\n",
" on_mouse_event_closure('button_press')\n",
" );\n",
" rubberband_canvas.addEventListener(\n",
" 'mouseup',\n",
" on_mouse_event_closure('button_release')\n",
" );\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband_canvas.addEventListener(\n",
" 'mousemove',\n",
" on_mouse_event_closure('motion_notify')\n",
" );\n",
"\n",
" rubberband_canvas.addEventListener(\n",
" 'mouseenter',\n",
" on_mouse_event_closure('figure_enter')\n",
" );\n",
" rubberband_canvas.addEventListener(\n",
" 'mouseleave',\n",
" on_mouse_event_closure('figure_leave')\n",
" );\n",
"\n",
" canvas_div.addEventListener('wheel', function (event) {\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" on_mouse_event_closure('scroll')(event);\n",
" });\n",
"\n",
" canvas_div.appendChild(canvas);\n",
" canvas_div.appendChild(rubberband_canvas);\n",
"\n",
" this.rubberband_context = rubberband_canvas.getContext('2d');\n",
" this.rubberband_context.strokeStyle = '#000000';\n",
"\n",
" this._resize_canvas = function (width, height, forward) {\n",
" if (forward) {\n",
" canvas_div.style.width = width + 'px';\n",
" canvas_div.style.height = height + 'px';\n",
" }\n",
" };\n",
"\n",
" // Disable right mouse context menu.\n",
" this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
" event.preventDefault();\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 toolbar = document.createElement('div');\n",
" toolbar.classList = 'mpl-toolbar';\n",
" this.root.appendChild(toolbar);\n",
"\n",
" function on_click_closure(name) {\n",
" return function (_event) {\n",
" return fig.toolbar_button_onclick(name);\n",
" };\n",
" }\n",
"\n",
" function on_mouseover_closure(tooltip) {\n",
" return function (event) {\n",
" if (!event.currentTarget.disabled) {\n",
" return fig.toolbar_button_onmouseover(tooltip);\n",
" }\n",
" };\n",
" }\n",
"\n",
" fig.buttons = {};\n",
" var buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'mpl-button-group';\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",
" /* Instead of a spacer, we start a new button group. */\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
" buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'mpl-button-group';\n",
" continue;\n",
" }\n",
"\n",
" var button = (fig.buttons[name] = document.createElement('button'));\n",
" button.classList = 'mpl-widget';\n",
" button.setAttribute('role', 'button');\n",
" button.setAttribute('aria-disabled', 'false');\n",
" button.addEventListener('click', on_click_closure(method_name));\n",
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
"\n",
" var icon_img = document.createElement('img');\n",
" icon_img.src = '_images/' + image + '.png';\n",
" icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
" icon_img.alt = tooltip;\n",
" button.appendChild(icon_img);\n",
"\n",
" buttonGroup.appendChild(button);\n",
" }\n",
"\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
"\n",
" var fmt_picker = document.createElement('select');\n",
" fmt_picker.classList = 'mpl-widget';\n",
" toolbar.appendChild(fmt_picker);\n",
" this.format_dropdown = fmt_picker;\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = document.createElement('option');\n",
" option.selected = fmt === mpl.default_extension;\n",
" option.innerHTML = fmt;\n",
" fmt_picker.appendChild(option);\n",
" }\n",
"\n",
" var status_bar = document.createElement('span');\n",
" status_bar.classList = 'mpl-message';\n",
" toolbar.appendChild(status_bar);\n",
" this.message = status_bar;\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",
"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",
"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], msg['forward']);\n",
" fig.send_message('refresh', {});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
" var x0 = msg['x0'] / fig.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
" var x1 = msg['x1'] / fig.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / fig.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,\n",
" 0,\n",
" fig.canvas.width / fig.ratio,\n",
" fig.canvas.height / fig.ratio\n",
" );\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",
" 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.handle_history_buttons = function (fig, msg) {\n",
" for (var key in msg) {\n",
" if (!(key in fig.buttons)) {\n",
" continue;\n",
" }\n",
" fig.buttons[key].disabled = !msg[key];\n",
" fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
" if (msg['mode'] === 'PAN') {\n",
" fig.buttons['Pan'].classList.add('active');\n",
" fig.buttons['Zoom'].classList.remove('active');\n",
" } else if (msg['mode'] === 'ZOOM') {\n",
" fig.buttons['Pan'].classList.remove('active');\n",
" fig.buttons['Zoom'].classList.add('active');\n",
" } else {\n",
" fig.buttons['Pan'].classList.remove('active');\n",
" fig.buttons['Zoom'].classList.remove('active');\n",
" }\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",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data\n",
" );\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" } else if (\n",
" typeof evt.data === 'string' &&\n",
" evt.data.slice(0, 21) === 'data:image/png;base64'\n",
" ) {\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(\n",
" \"No handler for the '\" + msg_type + \"' message type: \",\n",
" msg\n",
" );\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(\n",
" \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
" e,\n",
" e.stack,\n",
" msg\n",
" );\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",
" }\n",
" if (e.target) {\n",
" targ = e.target;\n",
" } else if (e.srcElement) {\n",
" targ = e.srcElement;\n",
" }\n",
" if (targ.nodeType === 3) {\n",
" // defeat Safari bug\n",
" targ = targ.parentNode;\n",
" }\n",
"\n",
" // pageX,Y are the mouse positions relative to the document\n",
" var boundingRect = targ.getBoundingClientRect();\n",
" var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
" var y = e.pageY - (boundingRect.top + document.body.scrollTop);\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",
" }\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",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * this.ratio;\n",
" var y = canvas_pos.y * this.ratio;\n",
"\n",
" this.send_message(name, {\n",
" x: x,\n",
" y: y,\n",
" button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event),\n",
" });\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",
" // Prevent repeat events\n",
" if (name === 'key_press') {\n",
" if (event.which === this._key) {\n",
" return;\n",
" } else {\n",
" this._key = event.which;\n",
" }\n",
" }\n",
" if (name === 'key_release') {\n",
" this._key = null;\n",
" }\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which !== 17) {\n",
" value += 'ctrl+';\n",
" }\n",
" if (event.altKey && event.which !== 18) {\n",
" value += 'alt+';\n",
" }\n",
" if (event.shiftKey && event.which !== 16) {\n",
" value += 'shift+';\n",
" }\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, 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",
"\n",
"///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
"// prettier-ignore\n",
"var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\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\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"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\";/* global mpl */\n",
"\n",
"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 = document.getElementById(id);\n",
" var ws_proxy = comm_websocket_adapter(comm);\n",
"\n",
" function ondownload(figure, _format) {\n",
" window.open(figure.canvas.toDataURL());\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy, ondownload, element);\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;\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",
" fig.cell_info[0].output_area.element.on(\n",
" 'cleared',\n",
" { fig: fig },\n",
" fig._remove_fig_handler\n",
" );\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function (fig, msg) {\n",
" var width = fig.canvas.width / fig.ratio;\n",
" fig.cell_info[0].output_area.element.off(\n",
" 'cleared',\n",
" fig._remove_fig_handler\n",
" );\n",
" fig.resizeObserverInstance.unobserve(fig.canvas_div);\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.innerHTML =\n",
" '<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 / this.ratio;\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] =\n",
" '<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 () {\n",
" fig.push_to_output();\n",
" }, 1000);\n",
"};\n",
"\n",
"mpl.figure.prototype._init_toolbar = function () {\n",
" var fig = this;\n",
"\n",
" var toolbar = document.createElement('div');\n",
" toolbar.classList = 'btn-toolbar';\n",
" this.root.appendChild(toolbar);\n",
"\n",
" function on_click_closure(name) {\n",
" return function (_event) {\n",
" return fig.toolbar_button_onclick(name);\n",
" };\n",
" }\n",
"\n",
" function on_mouseover_closure(tooltip) {\n",
" return function (event) {\n",
" if (!event.currentTarget.disabled) {\n",
" return fig.toolbar_button_onmouseover(tooltip);\n",
" }\n",
" };\n",
" }\n",
"\n",
" fig.buttons = {};\n",
" var buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'btn-group';\n",
" var button;\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",
" /* Instead of a spacer, we start a new button group. */\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
" buttonGroup = document.createElement('div');\n",
" buttonGroup.classList = 'btn-group';\n",
" continue;\n",
" }\n",
"\n",
" button = fig.buttons[name] = document.createElement('button');\n",
" button.classList = 'btn btn-default';\n",
" button.href = '#';\n",
" button.title = name;\n",
" button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
" button.addEventListener('click', on_click_closure(method_name));\n",
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
" buttonGroup.appendChild(button);\n",
" }\n",
"\n",
" if (buttonGroup.hasChildNodes()) {\n",
" toolbar.appendChild(buttonGroup);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = document.createElement('span');\n",
" status_bar.classList = 'mpl-message pull-right';\n",
" toolbar.appendChild(status_bar);\n",
" this.message = status_bar;\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = document.createElement('div');\n",
" buttongrp.classList = 'btn-group inline pull-right';\n",
" button = document.createElement('button');\n",
" button.classList = 'btn btn-mini btn-primary';\n",
" button.href = '#';\n",
" button.title = 'Stop Interaction';\n",
" button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
" button.addEventListener('click', function (_evt) {\n",
" fig.handle_close(fig, {});\n",
" });\n",
" button.addEventListener(\n",
" 'mouseover',\n",
" on_mouseover_closure('Stop Interaction')\n",
" );\n",
" buttongrp.appendChild(button);\n",
" var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
" titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
"};\n",
"\n",
"mpl.figure.prototype._remove_fig_handler = function (event) {\n",
" var fig = event.data.fig;\n",
" if (event.target !== this) {\n",
" // Ignore bubbled events from children.\n",
" return;\n",
" }\n",
" fig.close_ws(fig, {});\n",
"};\n",
"\n",
"mpl.figure.prototype._root_extra_style = function (el) {\n",
" el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
"};\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function (el) {\n",
" // this is important to make the div 'focusable\n",
" el.setAttribute('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",
" } else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\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",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which === 13) {\n",
" this.canvas_div.blur();\n",
" // select the cell after this one\n",
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
" IPython.notebook.select(index + 1);\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
" fig.ondownload(fig, null);\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(\n",
" 'matplotlib',\n",
" mpl.mpl_figure_comm\n",
" );\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=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x7ffa8c5b6d90>]"
]
},
"execution_count": 87,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"fig, ax = subplots()\n",
"ax.plot(res.index)"
]
},
{
"cell_type": "code",
"execution_count": 90,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"dtype('int32')"
]
},
"execution_count": 90,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"c = res.index.copy()\n",
"#%timeit numpy.sort(c)\n",
"c.dtype"
]
},
{
"cell_type": "code",
"execution_count": 89,
"metadata": {},
"outputs": [],
"source": [
"import pyopencl.algorithm\n",
"pyopencl.algorithm.RadixSort(pf.ctx, \"ary\", numpy.int32 )"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"import pyopencl\n",
"frame4 = numpy.zeros(img.shape+(4,), dtype=\"float32\")\n",
"pyopencl.enqueue_copy(pf.queue, frame4, pf.cl_mem[\"output4\"]).wait()"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[[0. , 0. , 0.01904849, 0.500816 ],\n",
" [0. , 0. , 0.02056885, 0.54078865],\n",
" [0. , 0. , 0.02208862, 0.580746 ],\n",
" ...,\n",
" [0. , 0. , 0.06121008, 1.001204 ],\n",
" [0. , 0. , 0.06098632, 1.0011909 ],\n",
" [0. , 0. , 0.06076241, 1.0011777 ]],\n",
"\n",
" [[0. , 0. , 0.02068714, 0.5438987 ],\n",
" [0. , 0. , 0.02220808, 0.5838867 ],\n",
" [0. , 0. , 0.02372844, 0.62385935],\n",
" ...,\n",
" [0. , 0. , 0.06151802, 1.001222 ],\n",
" [0. , 0. , 0.06129411, 1.0012089 ],\n",
" [0. , 0. , 0.06107015, 1.0011958 ]],\n",
"\n",
" [[0. , 0. , 0.02232492, 0.5869585 ],\n",
" [0. , 0. , 0.02384673, 0.6269694 ],\n",
" [0. , 0. , 0.02536767, 0.6669574 ],\n",
" ...,\n",
" [0. , 0. , 0.06176973, 1.0012385 ],\n",
" [0. , 0. , 0.0616019 , 1.001227 ],\n",
" [0. , 0. , 0.06137774, 1.0012138 ]],\n",
"\n",
" ...,\n",
"\n",
" [[0. , 0. , 0.06242415, 1.0008723 ],\n",
" [0. , 0. , 0.06240233, 1.000855 ],\n",
" [0. , 0. , 0.06238053, 1.0008377 ],\n",
" ...,\n",
" [0. , 0. , 0.07338466, 1.0012863 ],\n",
" [0. , 0. , 0.07335578, 1.0012822 ],\n",
" [0. , 0. , 0.07332689, 1.0012782 ]],\n",
"\n",
" [[0. , 0. , 0.06244136, 1.0008858 ],\n",
" [0. , 0. , 0.06241955, 1.0008686 ],\n",
" [0. , 0. , 0.06239776, 1.0008514 ],\n",
" ...,\n",
" [0. , 0. , 0.07335556, 1.0012822 ],\n",
" [0. , 0. , 0.07332669, 1.0012782 ],\n",
" [0. , 0. , 0.07329781, 1.0012741 ]],\n",
"\n",
" [[0. , 0. , 0.06245858, 1.0008996 ],\n",
" [0. , 0. , 0.06243678, 1.0008823 ],\n",
" [0. , 0. , 0.062415 , 1.000865 ],\n",
" ...,\n",
" [0. , 0. , 0.07332644, 1.001278 ],\n",
" [0. , 0. , 0.07329759, 1.001274 ],\n",
" [0. , 0. , 0.07326873, 1.0012699 ]]], dtype=float32)"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"frame4"
]
},
{
"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 / mpl.ratio, fig.canvas.height / mpl.ratio);\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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Tk4OXn75ZQCwHqG3Y8cOa5vKykoYhmH1bH/1q18hJyfHsXzB4sWL0bFjR2178nY+/fRTGIaBrVu3AgDOnj2LFi1aYO3atdY2dXV1uOSSS/D73/8eQMPN85JLLkFdXZ21zZo1a9CqVStrna8nnngC1113nWNf06ZNw8CBA9N9SkQCakcT1I5wUDsuDmgANeT8+fP49re/jfXr1ztenzlzJvLy8hI6quRwi7j5oPuqqirHdmPHjsX9998PAFi5ciVycnJS2srJycFrr70GALjvvvswduxYx/tVVVUwDANHjx6N+zQyzqFDh2AYBqqrqwEA7733HgzDwJkzZxzb5ebmYv78+QCAefPmITc31/H+mTNnYBgGNm3aBAAYMmQIZs6c6dhm/fr1+M53voO///3v6TodIgG1wwm1IxzUjosDGkANqaurg2EY2L59u+P1hQsXolevXgkdVXK4RXz79u0wDMPR0wSAqVOnYuTIkQAarlXPnj1T2urZsycWLVoEABgxYgSmTp3qeN+89hUVFXGfRka5cOECxowZg8GDB1uvrV69Gi1btkzZdsSIEXjooYcANFzDESNGpGzTsmVLvPHGGwAaruHChQsd75vfyalTp+I8DaIItcMJtUMdasfFAw2ghngJyXPPPYdrr702oaNKDi8RdwvGlClTUFRUBMD7htejRw8sXrwYgFO8TD755BMYhoHKysq4TyOj/PSnP0XXrl0dg7S9RLywsBDTpk0D4LwR2mnRogXWrFkDwHkjNHn//fdhGAZOnz4d52kQRagdTqgd6lA7Lh5oADWEZRwnLOOoUVpais6dO6ecA8s4Fz/UDifUDjWoHRcXNICaMmDAAEyfPt3xWu/evTmQG00DuZcsWWK9dv78eeFA7p07d1rb7NixI2Ug9/e+9z3HMgXl5eXaDuS+cOECHn74YXTs2BEHDx5Med8cyP2b3/zGeu3UqVPCgdz2DMnatWtTBnL37t3b0XZJSQkHcmcJ1I4mqB1yUDsuTmgANcVcymHlypWoqanB7Nmzcfnll+P48eNJH1pG+PLLL7Fr1y7s2rULhmFg+fLl2LVrl7WURXl5OXJycrB+/XpUV1djwoQJwqUccnNzUVlZicrKStxwww2OpRzOnj2Ldu3aYcKECaiursb69evRtm1bbZdymD59OnJycrBlyxacPn3air/+9a/WNiUlJejcuTM2btyIqqoqDB8+XLiUQ0FBAaqqqrBx40Z07txZuJTDI488gpqaGqxcuZJLOWQR1A5qhyrUjosTGkCNWbFiBbp27YqWLVuiX79+1pT85sDmzZthGEZKTJ48GUDTYq7t27dHq1atkJeXZ81YM/nss88wceJEtGnTBm3atMHEiROFi7kOGTIErVq1Qvv27fHMM89o2YMHILxehmFg1apV1jZ/+9vfUFpaiiuuuAKXXXYZiouLceLECUc7tbW1GD16NC677DJcccUVKC0tdSx3ATQs5nrTTTehZcuW6NatGxdzzTKoHdQOFagdFyc0gIQQQgghzQwaQEIIIYSQZgYNICGEEEJIM4MGkBBCCCGkmUEDSAghhBDSzKABJIQQQghpZtAAEkIIIYQ0M2gACSGEEEKaGTSAhBBCCCHNDBrALGDFihXo1q0bWrVqhX79+mHbtm1JHxIhJMuhbhBCokADmDDmczlfffVV1NTUYNasWbj88sut51ISQogb6gYhJCo0gAkzYMAAlJSUOF677rrr8NRTTyV0RISQbIe6QQiJCg1ggpw/fx7f/va3sX79esfrM2fORF5eXsr29fX1OHfunBWff/45jhw5grNnzzpeZzAyFWfPnsXJkyfxzTffZOpn0+xR1Q2A2sHIvqB2JA8NYILU1dXBMAxs377d8frChQvRq1evlO3LyspgGAaDkXVx8uTJTP1smj2qugFQOxjZG9SO5KABTBBTyCsqKhyvP/fcc7j22mtTtnf34k+cOAHDMJB/9XQUXPcYhvf5GYbnPolhfZ/C8BueaPi3OxrfH3bTUxjW7ykM7T8H+QOeRv6ApzG0/xwM6z8HQ2/+OfJvebohBs51hvn6LU9bn7Nvl3erLQbNc8bgeRgyZH5D5KXG4PwyDB4aHD8a1hgFz+BHBc9gUKFXLLDi1hGuGJmBsO3Pfixex2uez48KnrHOMfB65DeE6HoOGTIfeYPnpX4Pg+ZZ35Hjex3g+k79vv/Gv5chNz4KwzBw9uzZTP1smj2qugF4a8cfdv4P7Nr3D1bsqWkK++te4be9bBuitvzaZKQ/ZL4f1e/W/VrFB/+D2pEwNIAJEqaUY+fcuXMwDAMF1z2GkX3nYuRN8zGiXxlG3jiv4d/uuGk+RvywDCNufgYjBixA4a2/QMGPnkXhrb9o+PctC1Aw6FkU/KgxBj/nDPP1Qc8Ktxs+pDHyFjpj6EIMG7YIw4anxtCCxQ1R6B35I2xRVI78onLk3SaIUUuQN2oJhvy4MUYrxI8jRoh9mcebN2qJ8HzMczXP3e8aDS1suI6iazxs2CIMH7ow9XvJW2h9Z47v2P39+vwtDL355zAMA+fOnUvXz4S4iKobQJN27Nr3Dzh8oj0On2iPYyebwnzNL/y2l23D3Y5fe4zMR5jvSjZ27fsHakfC0AAmzIABAzB9+nTHa71795YazG2K+PA+P8PIm+Y3hMj83TjP2/zdsqDp34MCjJ/bHGTK+MVh+MKataghu88AQ6hkBlWNoMgE+hh9+3b5tzxNEU+AKLoBpBrAOM2fStD46RFxGkFzWxrA5KEBTBhzOYeVK1eipqYGs2fPxuWXX47jx48HftYygLlPNpg/UdbvxnkY0a/MMn9Wlm+Qy/ypZP2CjJ+P+VMxfULjZzd9YU1XsUdEMXoqbQYdnztD6GMG024EA7KB+QPnUsQTIIpuAE4DqHITDzIFNH4Xd6h+j8wAZjc0gFnAihUr0LVrV7Rs2RL9+vXD1q1bpT7nMICK5i+w5Btz1i9Sti/I9HkZqjgNXpzmUMUQ+phB6ayghxH0KwsLTaDgb4UGMDnC6gbQpB17av5B+uZN88eI0wjSACYPDaDGOErAMubPa7xfUNbPtl0o4+dj/jyzfTKmz89ohc3YxRmyxyBzbm4zKMoKhjGCUbKBNIDa4jaAmSj50vhdXBHVBNIAJg8NoMZ4GkC3+fOb7BFHyXfoQu9xfgHGT5Tt88yIuV+TMVsBJm3wmF/GGpFMoWgbn2vhmRWM2Qj6mUCOAdQT0SQQVfOnYgb9zEHSRoaRjBGkAUweGkCNERpAu/kTzfSNMt4vhnJvoPGTNX0Khs/XtI2NOcKYQxUzGJcRLBAbQdVsIA2gnsgawKjmT9UsMPQNVRNIA5g8NIAak2IAG5eBSTF/QZM9QmT9YjF+fmXeHweYIVXDF8LM/eh/iiNOcyhlCFXNoKIRlMoGepjA/AE0gDoiYwDTaf6SNiuM9ITK3wANYPLQAGqMexmYjJg/xayfkvGTzfYFGb4wxu72GCKMWYxqBhWNoEpZWKYkTAOoJ0EG0OuGzqwfQyZk/h5oAJOHBlBjLAN4wxMN5s++xp9omZc4Sr4qxs9t/mSMXxjTJ2v0Qhg46VBoWzZD6GsG02EEQ2QDOQlET/wMoJdxY9aPoRJBfxc0gMlDA6gxpogP6/uUp/lTnewRR8nXK+unbPwUTV+gIZMwbYPuWKocgfsKMIXKZlBkjv0ml7iMYOA6gm4j6GMCaQD1xMsAim7eNH+MKOH1d0ADmDw0gBpjGcB+T0Uzf4ol30waP2nTJ2nAHObtztS49S71ELXjaRAljle6TOxnBAXXPGo2UFQSzruVBlBH/B4FF9X8seTLcIfo72FPDQ1g0tAAaoxlAPvPCWf+ZMb7hc36xWX8ZE2fwPCJjJ7DvN2dGgPvUQtRG54GUWQKAwxhKDOYTiM4bJHTAA6aRxHXEK9HUOqzRgAAIABJREFUwcVp/pI2HYzsCvffBg1g8tAAaowp4kNv/rl4wkcGzJ901i+i8fM1fR6GT2T2HAZu/PNW3HKvR0xwhcd29rY8DaKHIfQ1gxkygmFLwjSAehL2UXA0f4woYf8boQFMHhpAjTFFPP+Wp6OZv4DxfrFm/cIYvyDT5zZ8brPnNnluU9cYA/5X+BC26TaHblPoZwhlzaDICMrMpPYxgUIj6GECaQD1RPVJIBzvx4gzOAkkO6AB1Bh7BjDQ/MnM9JUc7+c1w9dh9tJh/GRNn4/ZExq4ialx8yT/EH1GyhwKTKHQEPqZwbBGMGo2UDAuMG8wDaCORDGAops5zR9DNWgAk4cGUGNSxgBmyvzJZv3cRiTA+HkZHXd51276UjJ8fmZPZO7ua4of3r8sVNjbuPk+D5PoZQrthtBlBu2ZQZERNv8tMoJSZeGQJWH738iQvPkUcQ2xG0CaP0YSwRJw8tAAaox7DGDosm9c5k8i6xfK+EmaPl+z5zZ5kxui/wON8RNn9HvQP9zbW+080NR2ikGcJDaE7gyhpxl0ZwXDGkH7v13mXXqCSGM2kAZQT1SeBUzzx0hH0AAmDw2gxtjHAPo+4UPV/MmO9wuT9fMr9QrKvJ7lXQ/TZzd8drNnN3mWkft/muKmKa6YGhDu7afY2nObRLsxVDGEbjMoygqqGsE4s4EFi2kANUXVALpv3jR+jKhBA5g8NIAa4zCAYc2fe6avx3g/e1bId4avStYvKOOnYvrsGT6b4bMbvRRz91BT3DitMUpSo+/0pkh5f1pTWO25TKLdGNpNocMQ2svGEkbQnhVMMYI+YwSFBl2UwZU0gYPzyyjiGuKeBUzzFz5qI0bSx59U0AAmDw2gxlgGcODcyOYv1pJvuo3fRFeWz8/w2cye3eD1nb4MfX/aELkPL2+IUlvMCAj7to2fN9tzmEW3MbSbwge9zaBXVlDVCCpnAxVN4OChNIA6IjsG0H3Tbs7mL6rRozmkAcw2aAA1JsUA+j3hI13mTzLrJxznJ2H8/Mq7btPnZfhMs2eZvEYTd8PM5bhhVkP0md0Yj7jiUVe432/8nNnODTMbwjKJLmPoMIVT1c2gIysYwQh6jg0UZHb9TCANoJ7IlICbs/lLwuw1N0NIA5g8NIAa4zCAfs/29RnzF3qmr0fWTzTWLxbj58r2pZg+H8NnmjLL6DUau+sfa4zHG+IHP3PFEx7h2s78vNmewyzObjKGblMoZQYVjWDkbKBfSVhgAmkA9UTVADYH85e0uWtuhpAGMHloADUmxQAmbP6kSr4i8ydh/DyzfQ+5TF9pU3bPy+w5zN2TDdH7qcaY44zrfu4M9/u95zR91mzLbhJNYyg0hBJm0J4V9DSCXpNFgoxgDCaQBlBPggygyPxdjAYwaQPXnM0gDWDy0ABqjGMSiMj82Q2gxGzfwJm+CuZPNuuXMsbPy/gJsn0pps/M8D0qMHsuk+cwdk83xbVzG2OeRDRua31eZBSfcppCtyH0NYPurKCkEQyTDQw7LvBHw2gAdcTPAF7s5i8uw/VJzNHcjCANYPLQAGpMigH0Mn+ix7vFbf4ksn4p5V7X5I4g42eVeM3yrpfpsxu+OalG79q5y3Ht/IboVbYcvZ5Zjl4LGqLnLxrj2WX+8YumbXstaGzjmYb2rp3fZBDtxtDLEHqawem2rKCrPBxoBOPOBnqYwEGFz1DENcTLAF7M5i+bzF6mjGHS15wGMLuhAdQYywAOeNp3xm8k8ycz01dk/lTLvQHGz57ts5d3RabPbvjMbJ7d6JkGr8dzy9BjYWMsaoprFsuF/TNWO881hGkSey1wmkKhIfQwg7kzbEawpKk8HJQRFM0YTpcJpAHUE5EBvBjNn46GLx2GMOnvgQYwO6EB1BiHAZQ1fwUhzF/Ukq9X1q+x3GtN7vAwfsJsn1neFZk+m+FLMXt2g1e+DNcsaYirzfhlYyyVCHPbxs9es6SxzXKbQbQZwxRDaMsQ9p7jygw+JjCCP/UxgvbJIjLZwJhM4KDCBRRxDXEbwIvN/F1spi8uM5j090IDmF3QAGqMeyFo1eVe0mr+PMb6pZR7bbN6fY2fK9vnKO/aTd8CD8NXbjN6jQav+/PL0H3Z8+i+vCG6/e/GeEEhGj/TffnzDW0tex7dn7cZxCVNhvCaxTYzaGYIn7GZQTMzaJaJf2YbLzi7qTzsMILuySL3L/PMBvqWhGXGBQpM4K0jaAB1RMYAJm0QMmH+ohqw0590iCUybQaT/o5oALMDGkCNsc8CDrXWXxrMn7Dk65H1cyznYp/R+9NlKcZPlO0zx/K5TZ/D8NnN3nKXwfvHhuj6YmP8v0ud8U8+Yd/uxaY2uv2j0xxaxvD5VENoZgh7PrusKTM4T5AVtJeHTSNoHyNoThYRjQ/0ywYKSsKqJvDWkTSAOuJ+EsjFYP7SbfriMnvpNoa6GEEawOShAdQYU8Tzbp3rO+NXyvy5l3pRMX8BJV9h1s9e7rUbP3OMn5fxs2X7ev5iuafpM7N7luFzG71/WoquKxrjV0vR5aVfNsTLjfH/BcTLtnjpl+j6q4Z2uq5wGUS7KbQZwquXCszgc01m0J4VtJeHTSOYMkZwmkdZ2J0NFJSEg8YF+plAGkA9sT8JxG3+dDOA6TJ+SRi+OA1htptAGsDkoQHUGIcB9Bj357XWXzrMn2fJ1yfrZy/3WpM7HnWWei3jN79xXJ+Z7TPLu3bTt1xg+kzDZxo9u8F7ZUlDvNoY/6cxVpYHh7mt+dlXljgNomkM7abQbQhFZrCxTGxlBd1G0D1GUFQWNrOBjWMDpUrCIUwgS8B64jaAOpq/uI1f0uYuaTNIA9j8oAHUGMsADprnXfr1m/HrtchzFPPnnuXrmuFrjfUTlXtljJ85rq+8cTzfUmemz53hcxi+V2wmb2U5urxWji6rGuOfF6PrvzTG64vkonH7Lv/cGKsa2zTNodsU2g2hywx2X95UJr5miTMrGGgEPcrC5thAr5KwNUs4gglkBlBPvAxg0qYuTvOXbuP355gjE2Ywm0wgDWDy0ACGoKysYfFbe7Rr1856/8KFCygrK0OHDh1w6aWXIj8/H3v37nW0cebMGUyaNAlt27ZF27ZtMWnSJHz++edKx5FiABUnffg+4SNO82cv+Xpk/Rzl3sbJHdfOa5rJ6zZ+VrbPnukTmT634ftnm8n7dUN0+9eF6La6Ibq/0RhrnvOPN5q27bZ6YUMb/7qwoc1Gc+gwhW5D+HKjGbRnBu1ZQbsRXOgsDVtjBJ8SlIXNbKB7bKC9JByjCby1iAZQhWzTjj014mVgsjniMH7ZYPjSYQp1ygbSACYPDWAIysrKcP311+P06dNWfPrpp9b75eXlaNOmDdatW4fq6mqMHz8eHTp0wBdffGFtc9ttt6FPnz6oqKhARUUF+vTpg+LiYqXjcBtAv9Kvr/nzmPQRaP4Ekz18x/uZ5s8c6+fO+s1pmtzhGONnGr9fOo2fle3zMn0Cw2eZvEYjd3VjXLP2WWf85hfBYdvebMduEE1j2PXXLkNoZghNM/jSL5vKxGZW0FYeTjGCzzRNFvHLBqaUhIPGBYYwgcwAqpFt2uG1DmA2RhxZv2w3fHEZQh2ygTSAyUMDGIKysjL07dtX+N6FCxfQvn17lJeXW6/V19cjJycHL7/8MgCgpqYGhmFgx44d1jaVlZUwDAMHDhyQPg67AQxc7Flxxm9U8+dV8vXK+jnKvQtcxq8x45dS5jWNn1nedZu+xuyeafgcZq/RxPV4syF6/tsC9HqrIa5d94wV160vSwn7+73eWoCe/9YQPd5MNYdXuwyhI0NomsFXxVlBhxF0ZwR/ISgLm9lA+9hAn5JwHCaQBlCNbNMO0TIw2RiZMn5hTNlfPukYOdJlBrPZBNIAJg8NYAjKysrQunVrdOjQAd26dcP48eNx5MgRAMCRI0dgGAaqqqocnxk7dizuv/9+AMDKlSuRk5OT0m5OTg5ee+01z/3W19fj3LlzVpw8ebLBAA6eF1j6FU76CFruJUbz5yj5PiLI+s1zjvO7ZrFtjJ874/erpc5s38qGcXyW6VvtNH2m4bMbPdPc9X67DD/49/m4/j/m4fr/mIc+imF+7gf/Ph+9324yiKYxtEyhyxBa2cHXFzVkBl8TZAW9jGC5c3ygvSxsZgPNJWNyZzhLwnGbQJaA1cg27XAvA5ONEcX8xWn64jB66TCFuhpBGsDkoQEMwbvvvou33noLe/bswYYNG5Cfn4927drhL3/5C7Zv3w7DMFBXV+f4zNSpUzFy5EgAwMKFC9GzZ8+Udnv27IlFixZ57lc0fsgwDAwZMl+u9Ksy41fV/Nln+orG+9lKvo6xfq6sn2NW7zIf42fP9r2emumzmz7T8NnNXp//mIfcd+Yi95256PufT6Pvfz6NG//r51b0+21wmNuanzfbs5tD0xSKDKHdDFplYjMr6DaC9tLw842zht1l4bmusYGiknBEE+h+YggNoBrZph3ZbgDTmfXLRtMX1RBGMYKZNoE0gMlDAxgDX331Fdq1a4dly5ZZIn7q1CnHNlOmTEFRURGABhHv1atXSjs9evTA4sWLPffj1Ysfkjdfar0/6Rm/shM+ZMxf4yxfe8nXnOFrjfUzs37ucu8/2kq9XsZvtbfpu259quGzG71+v/05+r87B/3fnYObf/eUFQN+/6R0mJ8x27GbQ9MUmobQzBJeu+4Z9Py3BUpG0CoNv9g0a/jqpYJs4DyPkrDHuEBlE+jKAg687RcU8QgkrR32dQCzKdKZ9dPJ9IU1g+nKBtIAXlzQAMZEYWEhSkpK0lrGcWOO4/EygCmlX69xf37m7/aQ5q9EYP7cJV/7WD9RufefbGP8XrUZv1+nGj+zvGtm+kzTJzJ8dpM38P8+gYH/9wnc6oof/ffPAsP9GbMttzEUGcIf/Pt8KzOYkhV8o7E8bBpBszRsjhG0l4Xd2cDGsYH2krBjlnDjUjGqJtDrsXE0gNFJUjuy0QAmYfyiGrIzdZ1CRbYawUyYQBrA5KEBjIH6+np06tQJCxYssAZyL1myxHr//PnzwoHcO3futLbZsWNH6IHcQ/Lmy5d+JSZ9xGH+zOf4poz3ayz5mku7mGP9UrJ+v1raNLljpUfGz5bts5u+3HfmCg2f2+yZRm7IhscxZMPjyNv4GIa+9yiGvvcohm96BMM3PYLCTbMdYb4+fNMjGPreo8jb+Jj1eZE5tBtCkRk0y8TCrOAbtoygOUbQXRZ+IXVsoLAk/DPXUjExmcCBo2gAo5C0dmSbAUyH+Yvb+IU1e+k2hrqZQBrA5KEBDMFjjz2GLVu24OjRo9ixYweKi4vRpk0bHD9+HEDDUg45OTlYv349qqurMWHCBOFSDrm5uaisrERlZSVuuOGG0Es5DMmbr1b6VZjx63i8m9eED4H5c0z2sI33Syn5usf62Wf2/p8lDZM7zDF+LuNnz/bZy7tu02c3fKZZM03eiM2zULRlJkZtnYHR20oxZtvDGPeH6Rj3h+m4/f0SzzC3GbPtYYzeVopRW2dgxOZZlkk0jaHdEHqZQXdW0G4E7aXhLv+82DFr2J0NNJeMsUrCMZhAxxNDzGcH2yaF0ACqkW3akU0GMG7zF5fxy4Thi9MQxmkE02kCaQCThwYwBObaXC1atEDHjh1xxx13YN++fdb75mKu7du3R6tWrZCXl4fq6mpHG5999hkmTpyINm3aoE2bNpg4cWLoxVwH55fFX/p1TfpwP97NMdvXNeYv0PzZ1/VbLhjrZ8/6/XoRur+x0FHqtWf8TOPnzva5TV/exscswzdq6wzL6N3+fgnu3D4Nd1c8hPEVUzG+YiomVE6xYuKOBx1hf8/c/u6Kh3Dn9mm4c/s03P5+iWUKi7bMROGm2Rj63qO+ZlBkBO0ZQWuMoLss7M4GukvC7nGBASbQa2JIigm0ZYhpANXINu3IFgMYxvyFyfplyvSdq+ssjGw2gpk2gTSAyUMDqDGWARxaFq30m0bzZ67vZy3xYhvvJyz5mlm/f1lsZf3MyR09/61hYofI+NmzfXbTV7hpNoq2zMTobaUY94fpDrNnGrz7d/4ED+x8AA9+MBlT/ngfpvzxPkz7cBKmfTgJ0z+c6Ajz9WkfTsKUP96HBz+YjAc/mIwHdj6A+3f+xDKJ4yumOgyhmSG0m8EgI2iWhnu8mVoWtrKB5tjAFa6ScFQTOElsAt2TQm4ZTQOoI9lkAOM0f5kyfl4GL2rEbQaz2QTSACYPDaDGeBnA0KVf2XF/9z3vWOfPMdvXZf6undtg/uyTPczxfo6JHgFZv2vXPYMf/Pt8a2KHn/EbvukRFG2ZiTHbHrYyfKbhM82eafKmfzgRD380ATOq7sXsqnvw+O678OTuO/Dk7jsw50+3Y86fbsfcPeOsMF97cvcdeHz3XXh0192YXXUPZlTdi4c/moDpH060jKHdEN5d8ZBVOh61dQYKN812lIlv9TCC1//HPGuyiKMsbGYDXxOUhO3jAm2TQ66d720CU5aIcT82zmM84C3FNIA6ki0GMBvMX5yG78u6LtIRlyEMawTjHBdIA6gnNIAa4zaAKdm/kKVfz3F/tmf7qpo/x2QP+3g/s+T7mjjrZ5Z77TN6RcbPzPaN2jrDyvSNr5hqZfge/GAypn04yTJ7j+66G0/uvgNz94zDgupiLNo7CuX7irB030gsqynECzUFeHH/MGG8UFOAF2oKsKymEEv3jcSivaPwbPVozN8zFnP+dDse330XZlfd4zCED+x8IMUMjt5WKswK2o1g3/982lEWtmcDu61uXEjaVhK2jwvsvtw2OSTIBLrXCXQ9O9hrUggzgHqS7QYwDvMX1fipGr2/nuqqHCrGMKoRTHc2kAZQP2gANSbFAKpO/PAr/d7dWPr1MX/WEz7MpV6CzJ97sodteRdzhq8o62fO6jXH+ImM3+htpbj9/RLcXfGQlemzm77ZVffgyd13YP6esXi2ejSW7huJF2oKsGJ/Pl46kIeVHw/Cqo8H4vWDt2D1wZux5lB/vHmoH9481A/rDt+IdYdvtP795qF+WHOoP1YfvBmvH7wFqz4eiFcODMaK/fl4cf8wLKspxKK9o7CgutgyhDOq7k0xg2aZeMy2h1G0ZabDCJql4f7vzkkpC5vZQGFJ2BwXaDeBS10mUFQOFi0WLTCB7vGANIB6kg0GMCnzF8b4qRi9+lPdfUPFFIYxg+nOBsZVDqYBTB4aQI2xG0DPiR+CBZ99l3wJGvf3E5f5KxWs8/e0j/mzj/d7tWmWr1XydY31M8u99skdZqlXZPzM8q7b9C3aOwrLagqxYn8+Vn48CK8fvAVrDvXHusM34u3DuXjnSB/89sj1+O2R6/G7I73xuyO98d9HrxWG+f7vjvTGb49cj3eO9ME7R/rg7cO5ePNQP6w+eDNWfTwQLx3Iw4v7h2HpvpF4tno05vzpdjy6627MqLoX0z6chAc/mOxpBO1jBO1lYVE20FESNscFNk4OccwQbjSBwjGBjYtFW4+Na5wZ3P8B70khg+5cigFjnqWIa0jSBjAO8xd31k/F9AWZvLDhZwjjNILZYAJpAJOHBlBjTBH/0bAyuYkfEqVf0bg/4aSPkqbHu6WYv7KmMX+e5s+c7PFrp/lzl3xN8zfQNcbPLPWKjN+ju+7G3D3jLNNnZvhWH7wZ6w7faJk90+S9d7QXNh/rgW3Hrsb2Y91RebwrKo93xQfHu1jx0fHvO/5debwrth/rjm3HrsbmYz3w3tFeljk0TeHbh3Ox5lB/vH7wFrxyYDBe3D8M5fuKsKC6GE/uvsPKCrqNoFkaztv4mKMsbM8GmmMDlUzgL8Um0Fos+pGmZwcLl4cRjAccMJYGUEeSNIBJmL8w2b6opu/vp652RFRD6JcZzCYTSAOoDzSAGmM3gJ7ZvzClX79JH/a1/mzP9u39lGCpF/uYP7f5s032sJd8r7ct5GyO9bOXe0dsnoUx2x7GndunWcbPLPM+vvsuzN8zFuX7ivDi/mEpps9u+LYdu9oyebtqO2NPbSfsP9EBB0+0x+HG8BIu8/2DJ9pj/4kO2FvbEXtqO+Gj499H5fGuDlNoGkLTDJqZwWU1hVZWcHbVPQ4jaI4RHLV1BoZvegRDNjyekg00xwba1w20xgWak0NcJtAaE7g4dZ3AHzzZ9Oxg+8xg0aQQczzgrXcvxc3jaAB1JCkDmM3mT2T8VAxe1AhjBtNhBDNlAmkAk4cGUGMsA1jwTLjsn2DWb0rp12PSh325F+vZvvM9zN+Lz4vNn228n315F3vW79b/+4SV9TPLveMrpuL+nT+xMn5247difz5WfTwQaw71x9uHc/HbI9dbpm/7se744HgXy+yZJs9+E5JZRPbPAlE0Re+wzRSahtBuBt850gfrDt+I1w/e4jCCZkZw2oeT8MDOBzChcopVFh6xeVbKJJH+786xTKB7XGAYE2g9O/gx70kholLwzf+TBlBHsskApsv8hTV+UQzfN6d7SEUUQxhkBHUxgTSAyUMDqDGmiA8qfCbSxA+vWb8pT/rwm/Qxz/Z4t3LXUi8r5MyfV8nXzPrZy73TP5yI2VX3YO6ecQ7j9+ahfla2z8z0uU2f3eyZNxD7zcFvdp+oDGOK659tImk3hKYZ3H6sOzYf64H/PnqtlRVcffBmywguqC7G47vvwsMfTcCUP96H+3f+BOMrplrZQPvYQHtJ2BwXKDSB9nKwOTHEvU5g47ODe88RTAqZ5vOkkHufxw9vpwHUkSQMoEr2LxPmL4rxkzV6qqFiBsMYwagmMM6ZwTSAyUMDqDEOAxgm+yda8Fmy9Gsf92fN+DUf77ZUYP5etY35kzR/eRsfQ9GWmdZYv4k7HrSyfk/uvgPPVo/GCzUFWPnxIKw51D/F+H10/PvYW9vRyvSZNxbzBmHeBOziH7ZsY4qwyBCaQrj/RAfsqu1sZQVNI7ju8I1Y9fFArNifj/J9RZi7ZxxmV92Tkg0cva3UURJ2jwtMMYH2MYHudQKfb3psXM9nlzmWh3GMB3QvEu0qBf/wjuco4hqSaQOYtPlTNX6ZNH0qZtDPCMaRDQxrAmkA9YQGUGNSDGDI7J858SNl1q9X6dcc9+ea9HHNYtfj3f6pcZ2/V50TPrzMn32839D3HsWorTOskq851s/M+i3dNxIvHcjD6oM34+3DuZbx236sOz46/n3sP9HBuvG4TZ8p+nGLu12k7YbQFNZPbFnBPbWdLCNolobfPNQPKz8ehBdqCvBs9WgrG2gfGzhm28Mo3DTbMS7QywSmTAwxTWDjE0O8Zga7xwP6lYL730UDqCPZYACTMn9+Y/ySNn2yZjAOI5i0CaQBTB4aQI1pMoALpLN/shM/PEu/PuP+rBm//+h6wsdrTUu9yJg/c7yfOdHjwQ8mW2P9FlQXW1m/dYdvtMb4mRk/0/h9crK9daMQmb5MibbdDJ6p6+TICtqNoDlG0F4WLt9XhDl/uh0zqu61SsJ3VzyEcX+Ybo0LtE8OMU1g77cbJ4bYZgd3+efFTYtFr2h6drBlAhvHA0qXgifRAOpMJg1g3OP+wpi/oKxftho/VSOokwmkAUweGkCNcRhA1eyf18QP94LPHqVfc9xfrwWucX+NM367vPTLhtKva5Fn+2zfIPM3cceDePCDyZhRdS/m/Ol2a6yfPeu3+VgPfHC8C/bWdnQYvzN1nSzBDxJ1UdbOTxzd4wXNG4hMZtCeFTSN4MET7bGrtjO2HbvaKgub2cBlNYWYv2esVRI2xwX6mUBzYojdBHb9deMTQ15tfHawYFJIz2cbxwO61ge0l4LdC0T3v5sGUEcyZQDjLv3Kmj+Vkq8Oxi+KEcwGE0gDmJ3QAGqMKeK3jlgQW/ZPuOCzV+nXvtizfdyfOeN3ZePj3VY3rfMXZP7MyR7meL8ZVfdaJd9XDgzGm4f6WVm/7ce6Y1dtZ2tih1nqtZsyL1E3zZg9K/eJS6wOn/AO+w1OlG302q/dCJr7NkvDe2s74oPjXayy8NuHc7Hq44F4cf8wqyQ8/cOJeGDnA9bkkKItMx1PD7FPDOn9tnOdQMsECiaFWOMBf5FaCk6ZFWybENL/HhpAHUnSAGba/GXS+KmMH457f3GbQJl1AqNkAWkAk4cGUGMsAzhyQeTsX8rEj8YFnx1P+7DP+nWXfu3j/mwzfq1n+zYu8mw+2s2c8OFn/mZX3YP5e8ZiWU0hVn080Cr5vne0lyPrd1rSfJnGy559M42ee02/PbWdsKu2s2eY2+yt7ehYP9BuCM3jkTGC9rKwPRv4zpE+WH3wZqzYn49Fe0fhyd13pJhAdybQvkSMY7HoNxqfHSyYFOIYD+hRCrYvEG1OCOlHA6glmTCAstk/Xc1f2PX+0mEKvYygV0k4rAmMMwtIA5g8NIAa4zCAacj+3TitsfRrZv/ss379Sr+CGb89/y3V/A10lX1N82dO9jDH+636eKCj5PvR8e/jYKPZMsu99jF+bnH866muKSbrYOPyLKbRM5/0YT7hw3zKh1e4nxjy0fHvY1dtZ8sQ2mcem1lJ0bH9/dTV+OuprlZZ2J4N3H6su2UC1xzqb40LfHL3HXj4owmWCXSXg+3rBF7/H/Nw7bpnUpeHcY0HdJeCU2YFe0wI6TeeBlBH0m0Ao5R+02n+opot2Zm5KhGXGdTNBNIAJg8NoMYIM4AKM3+lsn/uiR+CWb8ppV/BpA/z8W43/pfT/A1971HHmD+7+Xtx/zC8fvAWvHOkjzXRwyz5msbqXF3nQONnmiq76TMXabY/zs3+KDf3M37NMF8TPUrONIXup4sctplVkRH0ygbuP9EBHxzvgveO9rLGBb5yYLBlAu2ZQJEJ7PfbpsfG2WcGe44HNEvB7lnBTzizgOaEkP4/WYab7l1IEdeQJAxgnKXfTJq/uA2fqiEMawRFJeF0mUAaQD2hAdSYFAOosu6fbPZPMPGj5y+Wi2f92ku/rnF/5rN9+787x7HO36gP0hkMAAAgAElEQVStMyzzZy/7vlBT4DB/2491Tyn5ek3AqD/VXWj8dtV2xgfHu6QsyGw+nePNQ/2w5lB/rD54M1YfvBmvH7xFGOb7aw71x5uH+mHd4Rutp47Y1yGsPN4VHx3/vqcR9MsG/tk2QSTIBNonhhRumm0tFm0+Ni5lZrBZCm58Uoi1NIw5K9i9QLR9bUDzMXGNWcAb/xcNoI6k0wCmO/uXKfOnYvzczw2WDRUzGFc2MMgEykwKiSMLSAOYPDSAGpMyCSRN2T/Hs36f8Sn9vpJa+jXH/bknfQzZ8DiKtszE7e+XYELlFGvCh4z5M0u+okzaubrOOP1JB8v4uZ/Raxqptw/nWobv9YO3YNXHA7Hy40F45cBgvHJgMF46kIcV+/OxYn8+Xtw/zArztZcO5OGVA4Ox8uNBWPXxQMsYrjnU33r28H8fvdbKDJpZQdMIfnKyPc7UdUL9qe7CbKBpAj9pPI+Pjn8fm4/1sEzgSwfysGjvKGtiiLlEzJhtD2P4pkesSSH2mcHmeECvUrA1K1g0IcT2mDh7FvDGiTSAOpJpA5gu8+de6sXP/EU1T3EYvrCGMKqBFZlAv4kh6cwCmiaQBjB5aAA1xpEB9Jv8YX/mb9Tsn2jixwrnrF936Tf3nblW6dc0f4WbZmPcH6ZjfMVUa52/uXvGWRM+3j6cq2T+7Fm/w7aMn2n87E/dsJs+0+y9uH8YltUUYum+kSjfV4RFe0fh2erRwli0dxTK9xVh6b6RWFZTiBdqCrBif75lCE0zaH8snWkEzYzgwcYxgqJsoN0EmuMCTRNoGtg1h/pjxf58PFs92loiZuKOB3Hn9mkYtXUG8jY+JhwPKCwF22cFv+CxNqBrLKCZBex7Hw2gjqTLAKZ74kfS5s/PvLkfIRkUYcygqhHMVhNIA5gd0ABqjNAA+kz+ED71w77uX5Ts36tNs35FS77YS7/2Gb/37/wJpn84EXP+dDuW7huJlR8PsiZ8uM2f1yzfL+u64M+NWb/9JzpgT20nfHC8i2Mm7brDN2L1wZutTN+K/fl4oaYAS/eNxKK9o7Cguhhz94zDnD/djid334HHd9+FR3fdjdlV96TEo7vuxuO778KTu+/A3D3jMH/PWDxbPRrl+4qwrKYQL+4fhlcODLYyg28e6ueYxGKWhs3H1H1ysj3O1XUWmlpz1rJpAu3l4NUHb8aL+4dZ6wRO+eN9mFA5JWVmsH08oLAUbM4KlsgCuscC5t5PA6gjmTSA6S79xmH+whg/L2NnN1VeoWII02ECRUvEpKsUTAOYvdAAaozXMjBSS7/4ZP/6/nRZU/bvSUH275eCZ/26Jn64l3wxS7/ucX/TPpyEx3ffhfJ9RXjlwGCsO3wjfnekN7Yduxp7ajs5zJ9ovJ9Z8jWzfma51yyX2o3fKwcG48X9wyzTN3/PWMz50+14fPddmFF1Lx7+aAKmfTgJU/54H6b88T48+MFkPPjBZDyw8wErzNem/PE+TPtwEqZ/OBEzqu7Fo7vutgyhaQZfqCnASwfyrKygmRE0J7R8cLyLlQ2sPdkwqcVdEvYzge8c6YPXD96CZTWFmLtnXMrMYK9SsGNWsPmUEHNCiEIW8MaSZcidTAOoI0kawKDsX9hxf+kwf0GmT8bshTGEKkYw7MSQsCYwriwgDWDy0ABqjGUAi3wMoMzkD/dTP0oFM39F2T/7s35t2T/zUW/2Wb9m6XfE5lmOcX+zq+7Bs9WjsWJ/vrXI8+ZjPbCrtrNv2dcc72eaInfW7+3DuVap1278nq0ejTl/uh2P7robM6rutQzfAzsfwP07f4IJlVMwvmIq7q54CHdun4Y7t0/D7e+XWHHn9mm4u+IhjK+YigmVUzBxx4O4f+dP8OAHkzHtw0l4+KMJmF11D57cfQfm7xmLRXtHYVlNIV46kIdVHw/E6oM3W+sZmtlAc2ygWRJ2rx1oN4Hm7ODK412t81z58SAs3TfSMSnk7oqHMHpbKfI2PoYf/ffPHKXgH/z7fOdTQswJIe5lYSSygLkP0ADqSDoMYJLZvziNUZDxi8v0yZjBOLOB6TKBYbOANIDJQwOoMSkGUKL8K5z8YX/mr/2pH14zf5d7LPtim/jhV/odXzEVD+x8wBr390JNAVYfvNla5Pmj49/H4RP+5u9MXSdrlqz5PF131s8s9bqN3/QPJ1qmb+KOB60Flcdsexijts5A0ZaZKNw0G8M3PYLhmx7B0PcetWL4pkdQuGk2RmyehaItMzF6WynG/WE67q54CBMqpzjM4Iyqe/H47rswf89YKyNolobXHOqPd470wXtHe1ljA4NMoH128N7ajth27Gr87khvrDt8I145MBiL9o7Co7vu9iwFuyeEBGUBuz9vywKWidcFvOFBGkAdScoAxpn9E5V+oxoit/mTNX6iySkyEYcRjMME+o0HTFcWcC8NYOLQAGqMaBkYz/LvnY0G0Cv7Z5v8YT71I2XdP/fYP3v2z/asX3Pih3vWr1n6vX/nTzDtw0l4cvcd1rg/szT6wfEuOGhb5y/I/JkTPcyS6JuH+llZvxdqCrBo7yjM3TPOMn4PfjDZWjbl9vdLMHpbKUZsnmUZvbyNj2HIhsetx6uJwnw/b+NjyNv4GIa+9ygKN83GqK0zLDM4cceDeGDnA5YRfHL3HVhQXYyl+0Zixf58rPx4kPVMY3OyizkuUGQC7RNDzFnOu2o7W6Z3zaH+1njAGVX3WqVg96zglAkhHlnA/7+9d4+K8jrb/+ebVk1sjf0mb35RpBCNZwkmGBWNYlQO4QWlGIny4ilWBAJ4TowRUaIgRqHW1prXvNbW32s0B01rm0PjAUUFNQqGs3hAVHS1K7XadKWmK/X6/jGzN/vZs5+ZZ4YZZh69r7X2ahcMwzCazcfrvq/7VvYC5mi3g4RmFyPkpwSAZpSnAdBb7p+3+v4cuWF6g5M9BX2uAqEeCLpbEjYCge3hAhIA+l4EgCaWUwB0Vv7VG/0i7PzlWz9k90/u/RPWvancP5b6lUu/WxoieN/f8aaeqL/S3eHQ5NstgUr4YyXf7efCueuXVx2PJWcnI/NMMuZ8MV0zLy/m8DyMO7SQAx+bncfWqQ37bCmGfvq68gz7bCmGfbYU4bbHMyhkMBhVMl8z3Hr2qZnIOJ2CRZVJyKlKQEFNLHcDdzQO1/Q9iivu/nytu6YnkF3abFj0BakfcPu5cE0pWEwFy4EQu7EwogsoJ4JtcwHZdhBxR/Cg1AK6xE0oXwCgN9w/b8CfI/DzBvS5CoJthUBPhUJcdQEJAP1PBIAmll0K2MXyrxj+4OVfKfyh2fqxXsf9+1/H7h8LfrDUb+aZZCz7MlFT+pX7/ljoQ4Y/1vMnwx8r+W6qH4vC2hjkVCXw8SizTs5CcvkcDn7M6WPQFy6MSwn7+A08/cfWE/ax9sifG/LJMg6FIgwyV1BcccdmHS49Owmrq+NQVBfJIfD982EcAkUn8KtrAXYO6DfXg3kopP5Kd74ybs+Fp7GlIYKPhpl9aib/udmAaF0XUC8RLG0HYWGQga/a+kTnEgCaUf4AgJ50//wF/vSSs0bmGRoBQU9DoDddQGdlYAJA34sA0MSSAdBh+ddo+EMu/7Kdv+LWD3Hun5T81XP/xODHosokFNTEYmvDKF4CPXU5yGHf39ctQXzGH+v5U8FfQU0sln2ZiOyKqZjzxXSNC8YcPwZ+MvTJsOfKefqPrTAYLoFgVMl87n7OOjkLGadTsOTsZF4S3tIQoYRA5obebOlhd3mLo2+qmnvwUvDOxqHYWDceOVUJmkCIYRdQngv4M2lHsBQGGZhGAGhGeRIAPVH+bQ/3z1348wTwtRUInYGgJyCwvV1AAkDfiwBQoSNHjiA+Ph7du3eHxWLBRx99pPn83bt3sXLlSnTv3h0PPvggxowZg5qaGs1jbt68iWnTpuHhhx/Gww8/jGnTpuFvf/ub5jFVVVWIiIjAgw8+iICAAOTl5eHu3buGX6dDAHSl/DtXKv+qBj8Lo1/ErR/i3L/+ex27fyz4kVs1EZvqx2LX+SH4+OIglDb1Qk1zAB+FIpd+71zviT/bSp4i/O27GMLhb2PdeKyujsPSs5OQeSZZ435FlczH8wcXaQBoyCfL7KDv6T++gcF/WI7Bf1iO0H05CN2Xg5Dfr9Ac9vHQfTkY/IflyucI+1i77zjiwGKMO7SQu4GsB3JRZRJyqyYqIfB4U09UNgfyfsjbLYF2oRC5FCymguVAiGEXUNwOwnYEOwiDDEwnABRltrujvQDQ0+5fe8Bfe4CfKyDoCgS2pRTcXi4gAaDvRQCo0CeffILly5djz549yku8sLAQXbp0wZ49e1BdXY0pU6age/fu+Pvf/84f88ILLyAkJARlZWUoKytDSEgI4uPj+edv376Nxx9/HFOnTkV1dTX27NmDLl26YMOGDYZfpyYF7Gb619HsP2X4g41++Z91CP6tNfzx5O7V6PNB68o3R71/iyqTUFgbwwc+y6lfVen3Zot1HiCb81fa1IsHH0TnT4Y/FoBgrh8DHxW0MdgbJAGfkaOCQfb/xRDM8wcX2QVhGASK5eA9F57G55f6ofxyMKqae/D3Rg6FiKNhWCqYvS/OXEDVXEC+HYSFQX5lPxKGl4FtYZABrxAAijLb3eEPANgW96+94c9b4GcUBFUQ6Cwd7EkX0JNhEAJA34sA0InkS/zu3bvo1q0bCgsL+cfu3LmDrl274u233wYA1NXVwWKx4MSJE/wx5eXlsFgsaGhoAAD86le/QteuXXHnzh3+mLVr1yIgIMDwv+RdBkBp+HObyr+/Fnb+2rZ+qOb+icAju3+s3Fl/pbtu6peVfuuvdMeZyz/G8aae+PTiALx/Pgzbz4Ur4W9KWSriSrPsXD+5bMucPhX0yU6fM2dQ/DoZBEUgZiXhxGPpGgjMq47nEMjSwSVNvTWhELkfUEwFXxBWxX10IZSPhRE3hIjDocXtIAN/l6vZEawMg+iUgQdkEgDqyQx3R1sB0BvlX2+7f/4Of85AsD0gsD3KwASAvhcBoBPJl/jFixdhsVhQUVGhedzEiRMxY8YMAMC2bdvQtWtXu+fq2rUrfv3rXwMApk+fjokTJ2o+X1FRAYvFgkuXLhl6bSIAutX/p1r99pot/Wsr/z65VlH+dTL6RZz7Z8T9Y4nX2y2BTku/LOywo3E4tjREoLA2Bsu+TNSFP3ELhgx+KhdPVdYd8skyfuQwiOq5Qmx9kOLzDPlkGYZ9tpSXhGUIXHJ2MlZXx2Fj3XhsOzdSUx4X+wHFUrAYCJFdQNYLuOzLRO4Cvng8DTGH59m5gA7DIA7KwAOXFqN/FgGgnsxwd7QHAHqr/NtW988o/Hmyl89TgRGjEOgPLqBeGZgA0PciAHQi+RI/fvw4LBYLWlpaNI9LTU1FdHQ0ACA/Px99+vSxe64+ffqgoKAAABAVFYXU1FTN51taWmCxWFBWVqZ8LXfu3MHt27f5uXr1qhoAFf1/8u5fTf+fbfizXvmXp3+l8q8q/CFv/WCjUDJOp/ChzyLcMPdPFfxgI19qmgNw6nIQSpp6876/rQ2jsL42GjlVCciumMrLvjL8iSVfsdSrV75loKca+yKPgxGhUO+5ZZiUIZC5oxmnU7D07CQU1MRiU/1YbD8XjvfPh/EZgawUrBoNI7uArBdwa8MoTSKYzQWMOLDYbkewOBial4G3rtOUgVVp4P7ZBIB6MsPd4WsAdAY8nnD/vA1/rn6NO9/HGQQ6Sge3twtotAxMAOh7EQA6kd4lfv36dc3j5syZg5iYGADWS7xv3752z9W7d2+sXbsWgPUSnzt3rubz165dg8ViQXl5ufK1rFy5EhaLxe6IAOjq+Bc2/Pmp+Tqr31wo/8rhj7jSLEwpS8XsUzORXTEVq6vjdJO/KvfvxrXufOTL8aaemr6/jXXjkVcdrwk6TCjNNAx/DPxk6JPn+4nDn9n/V80KdASC7PuoIDDm8DxNQGbZl4korI3BloYIZSnYiAvIEsFsT/DSs5OQdnoaUk7MRuKxdGUYhK2H0y0Di2lgYTVcv/kEgHoyw93RFgD0ZfnXE6XftsKfo8e64voZ/Z6uQqArsNzeLiABoH+IANCJ/KmMY8QBdLv/b6F2+LO4+o2Vf4N/td4u/SuWf/XCH2zrR1FdJHY0Dudz/8Tkr+z+icEPlvplpd/N9WN431/a6WmYcfJlnnJl5U0Z/lTOnOj0MegTBzqzVXCRhxZoVsOJW0PEkTIiCA7+w3L+/QY5gMDnDy5CXGmWZkA2C4WIpWAxFXxDcgHlXkCWCN5z4Wlsrh+DvOp4vh1ELwyiTAOLZWCd1XD9FhAA6skMd4e3AdAT5V935v61tfTrKvi5UvrV+z7uuoGeLAUbnQtIAHhviADQifQaudetW8c/9u233yobuU+ePMkfc+LECbtG7h/96Ef49ttv+WMKCwvdauQOf+FNt+f/ORr/ohz+LJV/+3ygLv/GHJ5nF/7YXD9Gk3A16v6JfW1bG0ahqC6Sl34Z1ESVzOelTbHnT4Y/0fVTjWoR9/zGHJ6H2CPZdifm8DxElcznUCiHTRgIym6gDIHhQjo44WgGUk7M5v2ABTWx2Fw/hqeCD17qa9gFrGruwcfkbDs3EoW1MdwpZWXg5w8uUs4EVKaBVUOhV9mc4oUEgHoyw93hSwD0ZvnXkaPlCfhzpT/PyFxBV9xAI06gp1xAT5WBVc4wAaDvRQCo0Ndff43KykpUVlbCYrGguLgYlZWVaG5uBmC9bLt27Yq9e/eiuroaycnJylEOoaGhKC8vR3l5OZ566inNKIdbt27h8ccfR3JyMqqrq7F37148/PDDbo1ycAkAXez/04x/EYc/K9K/Yvl3QmkmL/8uqHgJBTWxfOfvwUt9+dYP1co3sfdPDH6w1O/q6jhN6Zf1/bF0qzP4Ezd3iODHgG9CaSYSjmYg8Vg6Eo+l48XjafwkHktHwtEMTCjNRFxpFodBBoKstKqCQNkJHPLJMv4aWD8gKwXnVCXYuYClTb24C/jna93toPlmSw/NdpBPLw6wC4PolYFD9+VgwEfqodB642D65RSj7yICQFFmuzv8CQA9Vf515v55A/6cQZ9RGDTqBrpTCvZ2GdjVNDABoO9FAKhQSUmJsl9m5syZAFqHuXbr1g2dOnVCREQEqqurNc/x17/+FSkpKejSpQu6dOmClJQU5TDX0aNHo1OnTujWrRtWrVrl1jBXDQDqBED05v/x/j8GgAb7/1j5Vx7+LKd/xfIvW/vGBj+z8IccamDJX5X7x4IfmWeSMePky0g8lo5xhxbyvj/VbD8V/LHyKwO/uNIsJBzNwIvH05BUNhdTylIxpSwVyeVz7M6UslQklc3lQDihNBOxR7I5CIrpY0dOIBuZoyoFL6pMwurqOO4CstS06AJ+3RKked/E7SBiGXhLQwTyquP5e6ZKA7Oh0H0+sJaBn9gpDIV+W9sH2LugdRwMAaBWZrs7PAmA3uj/8zTIuAuA4uc9AX6OQNBTEKjnAnoqDNLWMjABoO9FAGhiyQDoVgBEb/6fXv+fsPtXb/izKv27qX4sT7U6Cn+Ic/9OXQ7S9P7J7t+UslTEHsnWlH4ZABqBv6iS+dzxY+CXXD4HKSdmY8bJlx2elBOzNTCYcDSDO4Js+PQIBxAopoNZKXjcoYV8NIzKBWQbQlgi+KtrAYbKwNvPhfOZgOKoHLlkzodC642D2bgBvdZbWwN6rylCv9xi9FlMAGhGtRUAfV3+dTf564/wp3pNRiDQG72A7VkGJgD0vQgATSzDAOhuAITN//vFej7/T9z+oTf+RVz9ll0xFXnV8Tz966z8e7PFGv5gc/8+vTiAJ39Z71/mmWTMOjlL4/6Jg57F0i9zJ8U5fCL8JRzN4I6fHvilnJjNj+rzyeVzkFQ2l7uBMYfnIfLQAkQcWKxxAsVgCHtdDEzFtXnMBWS9gHIi+MzlH+uGQcQysOieFtVFYsnZyZqh0GLZ3HAfoBQEIQA0p8wKgN5y//wB/hxBoKdcwLaWgQkA7y0RAJpYbgGgpwIgOts/VP1/hbUx2H4uHPsuhtilf+Xyrxz+YHP/tjREaJK/yeVzNO6fOKRZdtpU8BdXmoXEY+nc9dNz91RH5RKmnJiNKWWpePF4GodAuRysem0qF5D1AmZXTEVu1URsrBuvmQtYfjlYtwx8u6U1DcwA+v3zYdhUP5avhnO3D1AVBOmzhADQjPI3APRW/58eABpx/9oCf6qghivgqPreRiDQqAvorTSwoz5A+e9HPQGgz0UAaGLpAiDr/5vsfAPIU/MkAMyVAiA/1w+A9N+7UjP/T7X9Y8nZybz/j5UwG69YL4DbLdq9v99cD1aWf7efC+dz/1gZ88XjaXzsixj8YL1scumXwWnkoQWIPZKNxGPpdq6fXNZlPX7iYWEQ5hrK8KiCQOayyaVg2QUUewFZ+XzZl4lYXxuNrQ2jNCNhqpqtTunNlh66fYDiUGhHfYDyPEC7tXAOgiAEgOaUGQDQXQfL1fKvI7CSX58r4OcMCj0FgY7g2VMuoDf6AAkAfS8CQBOLA2CsDgC2NQHsJACiWv8WeWgBEo+lawCG9f99enGApv9Plf4VZ/+J5d/1tdGatWZslMlzn7+q7P0TZ/0N+2wpd9diDs/jZV8Z/hi8yUlfcQQMC4swGFT1DbLniSvNQlTJfD5yhb1OsRSscgGjSuZjSlkqD4OwMvCOxuHYdzGEr4dTpYEdjYMpqIl1OA9QFQRRDoS2AWCfN4vR+1UCQDPKnwHQ3f4/b7t/RmDNqAPoynM6KwW3RxmYAPDeFAGgiWUHgIkOAFBvBdx8CQDFBHCx4wHQA3+XazcAWlxvJs7/Y9s/xN2/MgB+dS2Ap3/Z5g+x/Lvk7GRe/o05PI/32Kl6/1gwRXTWokrmY0Jppl3Zl7l+Lx5P42EOcbRLxIHF/LCRMSw8IpaRGQQymEw8lo7YI9kap5K5gHIvIBujw1zUxGPpmh5Kth5OnAnI1ujp9QHKW0HYPEBHQRDlQGhFEvjJtdYkcO/XCADNKE8DoLMEsCsDoL1R/nXkxDly/4w4duLnjZZrxa/1tAvoDADdAWlvBEEIAH0vAkATywgAqnYAiyNg7BLANgDspQeAO/UTwGwAtBgAYevf2Py/quYemu0f8viXRts+29KmXvjoQijf/CHutE0qm6tb/lX1/o3ev8Su9Kty/hKOZih799iqOPZ8I/70mtNewpQTs5FUNhcTSjOVLqDYCyjPBXz+4CJMKM3UpKhZGtiVPsDGK9008wDlIIg8EFqTBGZBEDEJ/AttEpgA0LzyNgD6WwDElfKvK+6fDH96rpz8PeWv85YL6E4fYHsFQQgAfS8CQBNLCYAuzgA0MgKGJYCDftOaANbbAMISwKoB0CwAopr/d+d6T97/d+byj+36/3KrJmrSv87Kv2Lvn+z+yU6dCH/PH1zEXcV+e1bxcSjBv7WOv3nyvTcRui9HA5Z6ECi6gGJaWUwED1KUgdmOYHGOYmFtjG4f4O0W7VaQr1uClEEQNhCauagJRzM0PYrKJLDeKBhbErj3UgJAM6otAOjPCWBP9P8Z7f1TwZ/8vPLP3VYIbM8+QE8EQQgA/VsEgCaWHgCyBLAMgHozAAe+agVAIyNg2Ao4NgJGTgDHlWbx/jUxAcwGQLOypQyA31wP5ts/2BDj98+Haca/sASr6Fyx9K+q/CuWVGMOz7Nz/9j4loSjGYg9ks3hL+T3K6wJ2LffQq911rRrv1yrMxq8aQOCthei74d5GPLJMt73yGYJisES5gKykrI4FkZ+vWIZmPUBJpXNVY6D2XcxhO8GvnDFcRBEHAjtLAnMIFp3FMwv7UfBEACaU/4EgM7cK3egRXS93On/M+r+qeDvzzrAc0MCQWf9e94sAxMAkgACQFPLGQA6HALtygxAxQ7gvh/mORwBwwIM62ujsaNxOHetGh0MgBbXv8kBEDb+JeXEbD7+Rez/E9O/YvmXJX/jSrPw4vE07tCJfXoTSjMx7tBCjPjTawjdl2P9OTcUYdCSYgx5uQgjktZj5KT1GPZfGxCaaX2PgrauQ+/338TQT1/njh0Ll8guoOguqsrAYh8g61lk42CYkypuBWFBEAaAX10L4O8lGwitSgJvrh/DnVQGgFEl85WjYJ58z5oEdjYL8MnXCQDNKDMAYFugxd0AiNHyr9zzJ8PfNdv7Ir9n1652U0KgERfQlTKwL4MgBIDmEQGgieUKALIh0EYA8Mm1NgDUmwG4e7VyBzDrXWOlS9UIGL0NILdbApUDoLc2jEJhbYymd00cX6LX/zf009cR7qD8K7p/LFAy5JNl6PluPnoWb8BT84oxasJbiApbiReCFuCF7pmI6bcUY8cVYMjL1gRs0LZCDPr9Coz402t2LqBeGZiVreXB0KpxMKogCFsLJw6EFpPA4kYQBoAHL/XVHQWjB4CaWYAyABZtIAA0ufwdAPWgxZMJ4Lb0/6ncv6+uBeDGte4a8LtwpfU06UCgMwfQnTKwvwCgo1mABIC+FwGgiSUCoLM1cIa2gBgZAm2bAagHgKodwGyNWfnlYF0AvNnSugFELwHM1r9Flcy3C4A46v9j7pxc/mW9f1El8zHCVvoN+p916P9GMUZMXo+YfksR80gqon8wA9EPTUNM19mI6fYKnh+/FqFZxdaZeLvWYOinr/P5ffJ8QfZ9VGlg1TgYVlZm7+WMky9zAGQDofdceNoOAOVy+lfXrAGRyuZADoBbG0Y5nQWoOwxaBkDbMGgCQHPqfgLAtgRAjJR/RffvmgL8VBB4w0UXsK19gN5MAhMAmlcEgCaWIQB0tAYu2wAA/lIAQGEItAyA8hBoBoAb68Z7BADF8SWuAKA4+0925tjA5nGHFiL8T6+hzwd5CP7Fegx+pQjjn1uNmP+Yi6iO/4XIB5Ks53tTEP3wy4jp+xqGJ29A31XFCP7tWoR9/AZPQLMwiNgHyGYCGgVA0UBFF4IAACAASURBVE0Vx+mIAHjwUl/dlXAqANx3MYQDYHbFVIfDoHW3gRAA3jMyCwB6YgZgWwIgrjhyovunB4AXrmhdQAJAujt8KQJAE6tdAVDaAsIAUG8LiCMA1NsB7GgGIANAvREw7gJgXGkWxh1aiGGfLUWvXWvQa721TB4TshzRD7+MyO9NQeT/mWw9DyQh6sEUxHR7BaMmvoUBy6xl4Kf/6BgAWRDE0wDIZgGqdgLrAeDq6jj3AVCxDo4A0JzyVwDUC4C0NwA6K/+2BQCbCAAJAP1EBIAmFgGgZwHwyd2r0XOD9T2KfiqnFQAfSLIDwOd+8hb6v1GMoF/7DgD1HEACQJIzEQASABIAkggATSx/KwGregDNVALu+2Eegn+5HqFZxRgXkW8tAT+Y0gqB35ti7QMcuAzDUjagz5vFCN5RgCGfLONJYBkAWQ8glYBJ/iR/BUB/6AF0pQQsPpcRAJSDIASAdHf4UgSAJpY7IRCHKWAjIZB3810OgbAUsDsAuLVhVLuEQJ77/FWE7stB0LZC9FtRjOFTNyD6qRzEPJaG6IdfRvQPZyLm//4ULwQtQMQLhXhqfjGe+PkGPLl7NYZ9ttRQCEQcuqyXAvZmCESVAo45PM95CphCIPecCAC9FwJxBIHtFQJxlgImACQBBICmlj+PgWEDjOUxMHpzAG+3OB4Ds/TsJM0YGNUcQHkNHNuqobcFJKlsLh/REnFgMYZ++jqe3L0awb9cj4GvFiN8ygaMG70GMYPeQEy/pYh6diVGx6/D4AzrHLyg36xF6L4cPgYm4WiGZtagOAaGrZgTt5fI0Ko3BmZBxUseGwPD5gAaHQOjnANIY2BML38HwNstrs0B9KcxMPIMQAZ+Ivwx90/8HkYcR08BIM0BJAEEgKZWuw2C3uKZQdClTb00ACi6VvIgaHETyPraaL7CLOXEbMSVZiHiwGKMMDAIWtwDrIIzVgZmGzHCPn4DT+zMR/Av16NfTjFCM4vx7MwiDJ2+Ac+kFmHgq8Xota4IQdsL0X/vSu7+sT3DKshkLqORQdDsNYuDoBdVJjkdBC1e3KpB0HsuPM0HQYubQEQAlDeB0CDoe1f3GgCyv/vtOQhadeRB0PJ7pLcNxAgAqsrUBICktogA0MRydRewkVVwfBewYhWcuAtYtQpu9P4lfBUc22Dh7iq4g5f6KlfBzTj5suFVcOJWDb0ysOgCsm0gYR+/gV671liDL79Yj17rivDkuiL0LN6AoP9+C0/8bz4G/i4XQz99na9tY+6fqszM+v8iDizm5V/VKjgWqGHPyUBaXgUn7wK+2aJeBXfhSjfNWj1Hq+DYLmBaBXd/yJ8A0GgQxCyr4BgEye+BM/gzWv5tLwCkVXD3vggATSxXAXDo9A1aAMy0AuCgJVYA7L9cAMB1NgDctEEJgH0+sALg4D8s1wBg7JFsJJXNxexTM5FdMRUFNbHYdm4k9l0MQUlTb9Q0W3vTvroWYJdcvXGtO+qvdMeZyz9GSVNv7LnwNLafC8fGuvHIrZqI7IqpmHVyFhKPpeP5g4t4OdVIH6BYBla5gGwfsFimDfn9CvT5IA89d63hzueAj1Yqy8uy+yevgdPr/xskBUDY88Yeydb0Uq6vjcbWhlGaQA0DwNstgZqL+3ZLIG7YAFAsp2+sG89X6iWXz0HC0QzN6wr72Aql/fasagXAHQUI2iYA4MYN6LWeANDsutcB0JNBEGdgpoJAV0vMniz/yu+hpwHQGUQTAJpHBIAmlhIAE+0BcHiyAICztAD41HwJAFcVo3e+FQB7FlsBMPhX6xG0dR2Cthfiif/NR69da9DngzwM/F0ud9vCbQAYc3geksrmalaYbW0YhY8uhOLgpb6obA7kAPjN9WBN79qfr3VHo20UTGlTL+y7GIIdjcOxuX4MVlfHYUHFSw5Hwaj6AOUyMAtpMEhjO4FFCGRu3Yg/vYZhny3F0E9f5yf8T6/xHj0Z/kSwZO7ihNJMh+VfeQ2cnADOOJ2CnKoEFNVFYtu5kXj/fBg+v9QP5ZeDOUx/3RJkB4DXrnZD45VuKG3qhU8vDsDOxqEoqovUrNQTnVT2PuoC4NtvIfgXAgCuLUKf1UXo/RoBoBnVFgBUQaC/AKA3giBG4EzPqdODJXfgz10AFN1QTwRqCADvHREAmlh2APgTewAMn2IPgGE/LcIzc4sw+JUiKwAuLsbApcXo/0YrAD65rgg9i2wAuNkeAHu//yYGfLQSoftyOAA+9/mriCqZjxePp2nGl2yuH4M9F57G55f64czlH6PpqnoW4FfXAnDhijoJzPYBM/eKBTfEPkBVWVV2AeNKs+x6AUUITDyWjgmlmYg5PA+RhxZg3KGFeP7gIn7GHVrInyfhaIYS/tjzie6fOP5F9TrljSqqPcBGh0DfbOmBa7ZyeklTb3x8cRC2nwtHYW2MZpyO2EvJnNRBv1+Bvh/mWWcivpuP4N+uRdD/rGsFwJ9tQK+3bAD4ZjEBoEnlbQCUIVBOhvoLALbVBdSDQNXzqn5GR8/rrfKvJxPABIDmFgGgieUSAP6XDgDOkwBwZbG1ub/QCoBP/NwGgP/9FoJ+XYjg/78AvWyzABkAhn38BgfAyEMLkHgsHSknZiPt9DQs+zIRm+rH4v3zYU5HwdxusSaBVUEQ1gfIEqwJRzM0ZWAGgaKzJruAYi+gHrQllc3lbmDC0QzElWYhrjQLsUeyEVeahQmlmRz8WM+f6nkSj6UjrjQLUSXzNZClcirZa2fl35jD85T9f6oAiJgAdjQDcNu5kXwI9KyTs5BUNhexR7Ixev8S/tpYkKbPB1YAfGJnPoJ+s9Za/t/yFoI3bbAC4Loi9C6wAeCrBIBmlKcB0N+HQbvTB2jUBZSf01FQRAWN3nL/fBEAIQA0lwgATSwOgC/oAOBkCQCnbcCzM20AmFqEwRlWAAxZVIyBr1kBsF+uAIAbiqwA+EsbAErbQPrvXWm3DUScBSiPgmHhhcYr3XSDINeudkP9le48CML6ADfVj0VedbyyDBxuwAVkcMVKwXoQmFw+RwOCzBVkwPfi8TQklc3l4Cf2/IlOIoM/Bqkq909M/4rjXyaUZiLlxGxknE7Bsi8Tsb42GtvOjeT9f0YCIGIC2NEIGHkI9MDf5bbOAGQAaNsCErxpA3oW22YAFhShb14x+iwhADSj/BkAGcR4qnfNnTKwqy6gM+hzBGnOnscV908GaF8mgAkA/V8EgCaWLgA62gYys3UbyOAM2zaQRdYkcP83XBgGbZsFKCeBIw4stksCF9TEYvu5cGUQ5JvrwZqLh6VXxT5AcSOIGGIQS5gsDaznAoqlYEcQyEBOhEHxJJfPsQM/lfMnl35VvX+y+8d6FV88nmY3/2/7uXC8fz6Ml38d9f/JARCWAF72ZaIyASyOgHFlCHTfVcXos5gA0IwyAwB6ugzcFhfQFQjU+x5Gv87d0q8nyr+eTAA7GgJNAOgfIgA0sdwCQHkdnCuzAHVGweglgcUtFlsaIngQxFEf4M2W1o0gIsCwMrCcBhYhS+UChu7L0ZSCmcsmQiAr5cpQZ+QwUGTjZJjzx15XuE7pV+z9E92/uNIsTfq3sDaGj39h5V9HO4BZ/1/9le4obeqFjy8Owo7G4VhfG60JgIgldDEB7MoImL4rCQDNKn8DQG/3AbalF1AGMVdhzh3wM1L6bS/3zxsBkGtXu6GGANDnIgA0sWQAdHkYtIFRMI6SwM6CIKyMmVOVYNcHqLcRRCwDs3EwH10I5WlgcS2cHAYRR8KoYEsFgTGH5/EVbnqlXRX0ieAnJohV8CevfWNQ6sj9y66YityqiZr0r7Pyr6P+v4KaWE35PK40S9P/pwyAOEkA98slADSrfA2Abe0D9HQZ2AhkeRsCPQV/svvnrfIvAaD5RQBoYjkCQIezAG1BEM0oGAdJYEdBkP57W4MgYopV7gOUN4KwEqbcB/iv673w1bUAXgZmaeBd54dowiDMBXzxeJqmF1CvFCxDICtXs1Rv7JFsPtJF7PNTnaSyudzxY0ERlhpmrpoIf6IjKZZ+xeSvuEYv7fQ0Hv5g2z/Y+jeW/r12tZtd+Vws/4oDoNkGEHkHsKr/TzcAIiSAWQCk34pi9F1EAGhGtRUA3UkCt+dGEE+6gI7KwZ4CQT348wQAtlf5lwDQfCIAVOjIkSOIj49H9+7dYbFY8NFHH2k+P3PmTFgsFs0ZPny45jF37txBVlYWHn30UXTu3BkTJkzA1atXNY9pbm5GfHw8OnfujEcffRTZ2dn49ttvDb9OJQC6mQR2GATZqB8EEXcCy32A4jzA1dVxmnmAjsrA4lo4MQwiu4BsNRybZyeWMxlg6UEgC4aM3r+Eu4FRJfO5I8jSvizxy07C0QxMKM3kyWBxXIw8O5DBn+o1yO+XPD9RdP/E8Ide+lev/Mvm/4m9k3L/n2oHMO//kwIgvVj/X57NLV5IACjKbHeHJwHQX/oAveECOoNAd0HQEfj5g/vnrQAIAaB/iABQoU8++QTLly/Hnj17dC/xF154ATdu3ODnr3/9q+Yx6enp6NGjB/bv34+KigqMHTsWgwcPxnfffQcA+O677xASEoKxY8eioqIC+/fvR0BAALKysgy/Tg0ATtABQL0ksBwEWSgAoBwE+Zl9EETcCKI3EJrNA1SVgcU08O2WQDsXUAyDqFzA3KqJvKQ5pSwVMYfnIeLAYrvtIDKAiT2BQz99nbuBDATHHVqogUHViSqZj8hDC7jjx76v6PrJZWh55Zv4XrG5f+y9Env/ZPePOae3W7TbP8T0r6Py75SyVEwozdTAqrL/b4diB3DRhtb+v1W2vysLCABFme3u8CcA9HQZ2NMuoJ4rJ3+9IxhUPdYV188I/LXF/Wuv8i8BoH+IANCJ9C7xhIQE3a+5desWOnTogN27d/OPtbS04IEHHsBnn30GwPqL4oEHHkBLSwt/zK5du9CpUyfD/0GwS3xETJ49ALoaBFmgDYK40wcozwN0VAYuaeqNquYeyq0g/75hnQmo5wJuaYhAYW0Mlp6dxPcDJx5Lt5u55wwCRTeQgeBzn7+KiAOLNYOf5cOgb/T+JRz8ZNfPEfzJY3NY8GPOF9N58ndj3Xi73j/R/ZPDH2L5VwzPOCr/Oh0ArVoBt9YKgP1ybQA4nwBQT2a4O3wJgN4cB+PMBfQEBBoBQWfHFdfPCGx6yv3zdvm3mQDQL0QA6ER6l3jXrl3x2GOPoU+fPpgzZw7+/Oc/888fPHgQFosFN2/e1HxdaGgocnNzAQArVqxAaGio5vM3b96ExWLBoUOHDL02FQC6GwTRWwnnqA9QVQYW++tUZWCWBv78Uj+cuhykOxT6zvWedi4ggxo2F3B1dRwWVSbxUjDbbSvDjQoCGZSpQHDYZ0sR/qfXMMJ2nvv8VX7Yx0Tok10/1ffRg7/YI9l8ZE52xVTkVCXwvb8s+VvS1BtnLv8Y9Ve6K90/MfxR1dyDb/9g6V9n5V/d+X9O+v8GLCtGv3kEgHoyw93hbQD0VhnYXUdLzwV0FQKNQJuR53P3+7WH+0cAeO+LANCJVJf47t278cc//hHV1dXYt28fBg8ejEGDBuHOnTsAgJ07d6Jjx452zxUVFYW5c+cCAFJTUxEVFWX3mI4dO+Ldd99VvpY7d+7g9u3b/Fy9etUhACp3ArvRB+hsHmCfD1rHwYilzaiS+XwrCBtqvLFuPB8KLYZBHLmAbDB0SVNvPhdwa8MoTSlY3G+rB4Gqsmzovhw7EGQw6OiwxzG4VIGfnPYVk9Jy31/mmWQs+zJRE/xg6/PKLwejqrmHbu+fKvzBhj/nVccju2Kqcv2b0/EvqgHQtvl//Zfb/rGQTQCoJzPcHW0BQF+UgT3lAhopBRuBMj0w88RjPQl/ngx/eKL8SwDoHyIAdCLVJS7r+vXr6NChA/bs2QNA/xKPjIxEWloaAOslHh0dbfeYDh06YNeuXcrvs3LlSrsGciUAOguCOOoDZGXgFcI8wHW2PsBNG1rnATooA8vJVnko9LZzIw25gGIimM0FPHipLx8Ls6UhAutro3kqePapmboQKDpwzA0cJMCaDIMiuMmHfZ5Bnwx+suvHeg5l+BN7JJeenYTV1XHYVD+WBz8YJLO5f9eu2g9+Ft0/cfcvC3+Iw5/1tn/o7v8Vyr/y/L/+b9hS41kEgHoyw93hawBsjzBIW0rBRgHN1TJwW5/TEfy19T3ytvtHAOg/IgB0IiOXOAD07t0bhYWFALxXxnHkAI6OX+dyHyAvA6frzAN0swwsDoUWQSfzTDIPgxh1AdlcwEadUvDm+jEorI3Bsi8TlRDIAhriKja9lLB8GNzJR/XYQQJAysAovh/PH1ykeU/YyJfV1XG8708s/bLghzz3z5n7t7VhFFZXx9mFP+S0tDL9q1P+5fP/VtgA8LViDMgkANSTGe6O9gBAf3AB2wqBrkKbp44z+HPU9+eN3j9n7p/R8i8BoH+IANCJjFziX331FTp16oTf/va3AFobud977z3+mOvXrysbua9fv84fs3v3brdDIIYAUJ4HaANAXgaW5wGutJWBHayFc5QGVs0EXFSZhIKaWD4SRuUCigGHf9+wbgdhpeAzl3/MR5yI/YAFNbF2EJhwNAORhxbYpXRVjp6qhGv0qMBP3j7C4I/1RTLnb8nZycirjkdRXSTv+2OjcuTSr5yUZslfufdvZ+NQbKwbz90/R+GPkN+vQL89q9TbPzYryr+28S8Dltnc4lcIAPVkhrujrQDYHmVgI72AbS0F+xsE6n1/T8Jfe7h/BID+LQJAhb7++mtUVlaisrISFosFxcXFqKysRHNzM77++mssXrwYZWVlaGpqQklJCUaMGIEePXrg73//O3+O9PR0BAYG4sCBA6ioqMC4ceOUoxzGjx+PiooKHDhwAIGBgW6NchgRrQVA3gfoZB7gszNtfYCKvcCOysBiGlh0AfvvXWkXBmGr4WQXUOwFFBPBqrmArBTcdLU1FcxgZ9f5IRwCC2tjeDl4zhfTedkz5vA8PH9wkSa1y0BQLvWqyrvyGfyH5Zq+QT3wYz9/xIHFmlT0rJOzdOGP9f2x1K+j0u/Nlh7cHS2/HKzr/jEYHndood3sP3n4My//vu28/DtocTEGphMAijLb3eEPAOhrF1APAn0Bgo7Kxt6GP3fcP1fLv+LfEQJA34sAUKGSkhJlv8zMmTPxzTffIDo6Go899hg6dOiAoKAgzJw5E1euXNE8xz//+U9kZWXhkUcewUMPPYT4+Hi7xzQ3NyMuLg4PPfQQHnnkEWRlZfFmcCNyCICqeYAGx8Eoy8CFQhlYHAothEHE3cCOXMAFFS/xRLAYdGCwo1cKZqXOquYemlAIg0BWDs6pSsCCipeQdnoaZpx8mZc/2dw+5oLJ2zoc9f05OmKARDVOhgFwyonZmPPFdGSeSeY9fxvrxuvCnyr1K5d+5bl/OxqHK3v/9Nw/Fv7oxdw/afizKv3Lyr8hi4oxMI0AUJTZ7o72AkB/cQE9CYGegkFnz68Cv7bCnzfcPwJA84kA0MSSAdAjZeB52jJwv1xhKPRbwlBoRRhEdAHl3jfRBWShh6K6SOxoHI59F0M020FuXOuOmy097MYXfN0SpIHA8svBSghcXxuN3KqJWHJ2MjJOp2D2qZkchOJKszQgyEa7iHP8ZDdQdeTRMWxsDHP8WK+f6PqlnZ6GBRUv8bSv2PMnwp848uVmSw87N/TrliB8da01+FHa1Esz909O/qrcPzb6xeHsPzb8WZH+HbTE9o+FuQSAZpQnAdBXYRCVC+gtCDQCgkaB0OjzqF6Dt+CvPdw/AkD/EwGgiaUBwLh16jLwT9woAy9UDIXWC4Ow1XAGXUBx5l1u1URsrh/DV52VNvVCVXMPNNlKwap+wK9bgnjZU4RA1hO4o3E4HxGzujoOy75M5G7grJOzkFw+h4NgVMl8u6HO4pw/NutPPuxzzOkToW/coYWIPZLNf9YZJ1/mrt+Ss5ORWzURhbUx2Fw/hsMf64UU4a/J5oTK8MdSv6rS77ZzI1FYG6NZk5d4LN2Q+8dXv4nhD2H4c5/VrcOfWfn3qfnFCJmTT5e4CeULAPQHF9AIBHoKBNty2gJ/bSn9tpf7RwDoHyIANLGcAqArZWBhKDQrA9uFQVQzAd9Zh6DfrNWMhBF7AVWJ4JQTs3n6tbA2RjMWpvxyMHe/vroWYNcP+O8b1vmARiBwY914FNbGcDcw80wy5nwxXQOCE0ozEXskW7PWjQGho8Mex6AvqmQ+4kqzkHgsnYPf7FMzkXE6hbt+q6vjUFQXiS0NEdh+Lhy7zg9xCH9y6OPOdeu+X7n0KwY/cqoSkHkmGbNOzkJS2VxN8ld2/1jvX893862r37ZJq9/Y7t8Ca/ijX05r+CNkUbH1Hws/JQA0o/wRAF3pBfQ1BHoDBPW+jwr83IU/d0q/7rh/BIDmEAGgiaVJAdsA0FkZmA2F1pSBnQ2FztGGQfhqOBddQDYXkKVg2fBjuRTMUsF6/YAqCDx1OYiXQvdceBo7G4di+7lwbGmIQFFdJApqYpFTlcBBMO30NMw+NRMzTr6M5PI5SCqbi4SjGRwI5Z2/4mF7guNKs5BwNAMvHk/DlLJUpJyYjVknZ2HOF9M14JdXHY/1tdF8xt+OxuF4/3wY/3nLLwfznj9H8He7JZDv+61q7qEp/W5piODBDzYUm63HM+T+yaNfmPunCn/Yyr+hmcV4ajYBoBnlaQB0twzsCRfQkxDoDgi2BQgdPR/7vt6EP0+Uft0p/xIA+ocIAE0sOwB0pwwsDYVWhkEkF7DnBsEF3GLvAsqJYOYCsh3BicfSkVw+h5eC86rjsal+LB9+zPoB2WiYmy09dCGQ9QTWNAfgzOUf43hTTx6IYG7gtnMjsbl+DAfB3KqJWHp2EhZUvISM0ykcBmednIWUE7ORXD4HU8pSMaUsFUllc+3OlLJUJJfPQcqJ2Zhx8mUN9GVXTMWSs5M5+BXWxvCgB3P99lx4mpe8T10OQlVzDzRe6cZdT0fwx/r+2DxElvplpV8x+BF7JJvDnzj3z1X3r8+bgvtnC388Na8Yg18pQugsAkAzylcA6AkX0FP9gK5AoAiCRmCwLcco+LkCu+6Wfr3R+8dOFQGgz0UAaGLZlYCdlYEVQ6Hl3cC6LuAK11zAPh/k2W0HkQMhrBTMZgNuaYjA++fD+GiYyuZATShEBYEsGNJ01TonsLI5kJeEGSDtOj/EDgQLa2OQVx2PnKoELD07CYsqk5BdMZUD4ZwvpmPOF9Mx+9RMzWEfTzs9DRmnU5B5JhkLKl7i0JdbNREFNbHc8WPgx4IeDHBZybemOYC7narAhwx/9Ve6876/fRdDsP1cOE/9stIvSz2rgh+DpLl/Dnv/JPdPDH+EZhVb/7EwkwDQjPIGAPrCBXRWCnYFAt0BQU/BoPyczsDPU/DnK/ePANA/RABoYtmlgA2UgfV2AytdwIWKkTCOXEBbIljcDqJXCpYHIi89OwmFtTHY2jBK45CxUIgjCBTXobGSsOgGfnxxkB0IbmmIwKb6sRwGV1fHIbdqInKqErDsy0QsPTsJS85OxqLKJM1ZcnYylpydjKVnJ3Hgy6uO59C3sW48NteP0YAfK/d+fqkfSpt62ZV8b1zrrpnzpwd/jbZtH+LIl41145FbNVEzAFtV+lVu/dgpJX83tyZ/Ne6fNPqFuX/PzC1C6AwCQDPKlwDoDRewLf2AztxAPRBUwaARKNT7GtXzOwI/M8NfEwGgX4gA0MRSAqBeGdhAGISvhkuTNoM4cAE1iWBhO4heIERMBbM9wbNOzuL9gOtro3koxBUI/Nf1XrwkLLqBpy4HcRBkjuD758N4j+C2cyOxtWEUNteP4UC4vjYahbUxKKiJVZ7C2hisr41GUV0kNtaNx6b6sdjSEIFt50Zi+7lw7Ggczku9Mvgx108s+X5zPdgp/NVf6a6Bv52NQ7GpfizyquN5359q5h8r/dqNfZHm/mnWvtmSv87cv2dSizB4GgGgGeUtAPSUC+jpfkBXYclVEHQGhEaBz5Pg5wr8EQDenyIANLE4AEYJIRARAA2EQYYnK8IgbCSMygWUE8HydhBxR7CwIk5VCo4qmc9Ts6wfMKcqAUV1kboQyIIhX7cE2c0JlN1A1hsogmBJU29ePt1z4Wm8fz6MO4MMCBkUbm0YhS0NEXaHfU4Evp2NQzXQ9+nFATh4qa8G/FivH4PZ2y2BSpD95nqwsuzL3Mxd54dgc/0YHvpgI1/YeBtV6ldc+aYJfohbP6S5f6z3T+X+PZ1m+8dCCgGgGeVrAPRUKdgbEGgEBI3AoKtH7/uIr+VegT8CQP8QAaCJpRoDY9gFVIVBVC6gg0SwZi7gL+3HwuiVgkUIjDk8zy4UwiBw+7lwDQRWNgdq0sG3WwKVEMjcQAZQF65YIYqVhssvB6O0qReHwY8vDtIAIYPCXeeHYGfjULvDPvf++TDsufA0ProQio8vDtJA3/Gmnjh1OQiVzYHc8ZNdTNWF/c31YM2ol5rmAN7zJ8Pfosokvu2EjXwR+/7E1C8r/SqHPktbP9jcP2fuX9jsIjyTTABoRnkTANu7FOwtCDQKgu5CobPnchf8fAF/BIDmFAGgiaUBwP8U4M9RGMTZZhDBBZQTwXZzAcXtIHIgxEEpWOwHjDiwmIdC2Ko4PSewpKk3zlz+MS+f/tlBSfjfN1pXpskgyFxBBoPHm3pyIDx4qS8+v9QPn14cgI8vDlKeTy8OwKcXB+DzS/1w8FJflDT1xvGmnii/HIxTl4O421d/pbth8GOvlQ15brpq7WU83tSTO5Y7G4c6hL/IQwv4MGux70+T+tUr/Yo7f/OluX+K3r9n5tj+sTCVANCM8lcAbGsp2BsQKIOgURh058jfx1PA2hb484b7RwDoHyIANLH0UsDOwiBtcQHttoOoAiGsFKyTCpb7AVkoRNyXyzaFMAhkwRA2J5ANi2ZgpVcSdFAtUQAAIABJREFUlkGQwVWjAgZPXQ7CqctBHArZKW3qxV09dsovB2uAr7I5EFXNPbjbd8EGqc7ATy75XrOBKpvzJ8NfQU0sH/fC9hwnHM3QhD7Evr9Bjkq/emNf5K0fOu7fszOLEDZlDV3iJpS3AdDbpWBfQKAKBD0BhG2FPk/BnyfdP9WfPQGg/4kA0MRSAqCbLqDYC6g7F1CxI5gHQlSl4O3afsC+H2r7AY1AYE5VAtbXRmNrwyg+IoYNTxb7AkU3UA8ExRIrgy3mDDIgZFBY1dyDn8rmQH7Yx2qaA1DTHMBdvgtXWn/p3bD90mJQqndZi64fK/k2XumGM5d/rBljs6NxODbVj+XOnzP4k0e+6KZ+xdKvOPaF7fyVtn4w9y/sp9Z/JDw7owhhLxEAmlG+AkBPloLdhUBPgKAjGHT3eOp1+Br+jLh/BID+IQJAE8suBPKfnncBn5mr2BEsB0L0SsH/Yz8gmm0JESFwhJAMZhAo9gQu+zIRhbUx2NIQgZ2NQzXJWrEkzMDrdksgLwvrXayi88aA8IYAheJFdUEAPPmX2zXh+4pOpKPL+s71nvi6JUgDosz1E8Meey48jW3nRvJRL2LZ1xn8sW0fmr6/HQUI+rVO6XedtvTLgh9s529oZrE1+CG4f0Onb8CQJAJAM6o9ALA9SsFGINCIG9gWAHMHDL3xvfT6Ef0B/ggA/VMEgCYWu8RHRubZOX9uu4CquYC2HcF2Y2GkUrC4Jzj4V+p+QDEUooLA5w8u0vQEzj41E5lnkrH07CQU1MRiU/1YTThEdAMv6ICgniOoAjPxwnS0vkn8xWLkuRlwyuDXdNXqPDLXj5V8d50fgq0No7C+Nho5VQnIrpiq6flLOJqByEMLOPyxxK+46o3Dn9j3946U+nVW+l1oc/8yBPdvltX9G5ZCAGhW+RIA2wMC9eYEessNbO/jrATtafhrS9+fCv4IAP1DBIAmVisArmp1/5y4gLrr4aTtILpjYaRAiDgbkKeCHfQDyhA4+A/LdSGQjYiZdXIWMk6nYFFlEu8L3NowCrvOD+FuYElTb5y6HMQ3a8ggKPYItsdFL17MzGlkF6vYh1jZHGg3sJqVfAtqYrH07CRknknG7FMzkXJitibwITt/YuLXLvSh1/f3ljDzT1H6lce+sNLv0GnWvytDJhMAmlHtBYD+AoHOSsJmAUFXwM9d+PN26ZcA0H9EAGhiiQAYEWvf/+eKC2ioFMwCIWIp2JYK7rPaVgoWB0T/0nUIFNPBbETMlLJUzDj5MtJOT+Ml4YKaWGyuH4MdjcP5ijU9EGQ9giIMis6gJy59+VIWy8usx49dhmxItTigmgU9tjaMQlFdJC/5ZpxOwayTs5BcPofP+Rt3aKFh+FOFPuz6/pyVfoXgx5BZ1tLvsBQCQDOrPQGwraVgT0OgUTfQn2DQKPgZdf3aC/4IAP1bBIAmlh0AuuoCqraDqMbCKErBYipYsybO1g+ogUAxFCJAYO/31eVgBoFsWPSE0kwklc1FyonZmH1qpp0byHoD2Tw+EQTF4cvMFWS/QMRyrrP+IEfJP/niFaFPDJrUNAdoVtQx8Hv/fBjv9SuoicWyLxM1Jd8pZalIPJaO2CPZfMizqudPF/7k0Ic48kVe9yamfuXSr+T+DU/egGcnEQCaUf4AgG1xAdsCgbIbaMQR9AUMGk0be8r1a0/4IwD0DxEAmlgaAHyhsE0uoMNAiF4p2Fk/oBgKkZPBCidQhkA2LFoMh8hu4NKzk7C6Og4b68Zja8MoJQgeb+qpWcHWJPzyuSH9MtH7ZeHocmUXpxwiYXMHK5sDUX45mM8ZFMFv+7lwbKofi8LaGORUJXDXTyz5srBHxIHFfMizOOrFMPyx0Afb9iH1/Q143Vb6Xdia+mWlXx78EOBv+NQNeDZxNV3iJlR7A6A/QKAzN9AVEPQGDLo6YsYR+LUn/Lla+iUA9B8RAJpY7BJ/brwAgO66gKoVcQZSwcp+QD0I/G+1E8ggkI2IYcOi2cYQ1hcYc3geEo5m2LmBCypewrIvEzUgyErDbC2bDINsULOY7m128gtIdRGKlx0bJ8NmC7KNI2y4NOvx23V+CLadG4nN9WNQWBvDy72ZZ5Ix54vpGtdPLvmGC0Oe2aiX/nsdw58m8VukDX30Xanu+3NW+h2evAHhUzZg6E8IAM0oXwBge0OgK26gERA0WhlwNn3AleqCp8CvveGPANAcIgA0sTgAjl1pBUCjLqCjsTCT1YEQngqWB0RL/YD9coVQCBsSbRAC2ZzAEGltnFgSjjy0AHGlWbw3UA8EWWl4+7lw7Do/BB9dCNXAoLinl61sY/P92Gw/Nt9PPI1XtEOk2ZxAcauI6PSxNXPvnw/Djsbh2Nowijt+uVUTseTsZA34sV6/hKMZiDk8j7t+cr9f6L4czZw/p87fz1vhTxn6EPv+xIHPQupXdP/Cp2zAiKT1GJpAAGhGmQEAvQmBbQVBd6HQHeBT9fh5C/zaC/4IAP1DBIAmFrvERz2/EmNiCjkEuuQCGigF666JE/sBXxX6AVe2Dol+cp2wKcQgBA74aCWHQLkkLLuBbFzMjJMvY84X0zUgmFcdj/W10dhUP5a7gu+fD+MwyNa6iSvdSpp6860fbNuHfMQNIeL6OHGFHNstvLNxKHf7iuoiUVATi5yqBCw5O5n3+c06OYuXe1mvH0v5iiVfEf4G/i7XKfxx508n8ctDHzp9fzz1qyj9hr9k/cfCsIkEgGaUrwDQ3yDQKAgahUFPHvn764Gft+HPk31/BID+JQJAE0sDgFFr9V1A2RE0UAq2mw0olILDfiqUgrO08wENQyDrCbSlg/mcwN2r+e5g1hcoloRFN3DcoYWIPZJtB4LMEcyumIolZycjpyoBq6vjOAxuaYjAtnMjsbNxKHadH4I9F57WQKG471fvsMftuxiCfRdD8NGFULx/Pgw7G4di+7lwbG0YpYG+3KqJWHp2EhZUvMQdPxn84kqzNL1+qpIv6/fr+2EeX+/W8918+1EvovMnwp+c+JXn/an6/uTS70vWfySMfHE9hse/SZe4CeVLAPQUBLqSDnYHBB3BoDeAUPU99PqPnYGfv8MfAaB/iADQxBIB8PnItWoX0MVAiCoVrIHAmYp+QCkU4hIEshExv7VuDOkpQCDrC5TdQLE3UAWCrDQ86+Qs7goyGGTOYEFNLNbXRmNj3Xhsrh+DrQ2jsO3cSGw/F44djcOxs3EoB0T57Gwcih2Nw7GjcTi2nRuJrQ2jsKUhApvqx6KoLhKFtTFYXR1nB31pp6dh9qmZvNTrDPxUJV/e7/eesN5th23Is1H4ExK/LPShmffnpO9vRJL178fISesxPI4A0IzyNQB6EwK9AYJyGEwFa84g0cjjxe/hDvQ5Az9vln0JAM0nAkATyw4AowQIFF1AD5eCxX5ATSjEKASynkBxTuC2QgT9Zq1dQrjPB3lKN1AuCzMQjDk8DxNKM5F4LB1JZXO5KyjCYOaZZCyoeIkDYW7VRA6FhbUxWF8bjaK6SBTVRWJj3XjNYR9fXxuNwtoYFNTEctjLqUrA0rOTsKgyCdkVU+2gL+XEbEwpS+U9fqzUqwd+suunKvkG/3atdb3bO+uUaV/e8yfBH0/8qkIfOn1/w6dq4e+5xLfIATSp/AEA/RkCncGgDISugqHqa/WAr73Brz3gjwDQP0QAaGLJAMggsM2lYAcDou3mAwqhEA6BtmSwHgSydLBmWDTbHby9tSQsu4GsN9AZCD5/cBGiSuZrXEEGgyknZvMy8ZwvpiPt9DQOhdkVU7Gg4iUsqkzCkrOTseTsZCw9O8nuLDk7GYsqk7CoMgkLKl7isJdxOoUD36yTs7jTx6CPuX0xh+fxZK8MfmK5V8/105R8t9l2+74tDHmW4W+NA/iThz3rzPsT+/5Gvrie/z0hADSn/AUAvQ2BRkDQEzBoBA6NQJ4rwGcU/PwR/ggA/UMEgCaWHgBqXEC9QIijUrA0INptCNRzAm0jYviwaHF38DtSSVhyA+WysAoEZVeQwSBzBmUgZFA46+QszD41k8MhA0TxsI/P+WI6Bz0GeyknZnPgSyqby50+Bn3M7VOBH3P8xHKv2OvHXT9FyTdoi3W3rzjk2RD8qZw/Cf6G/ZcAf7a+v5GT1vO/K1QCNqf8CQA9CYHuuoGugKA7QOhJ4Gsr+PkD/BEA+ocIAE0sDoBjWgHQk6Vgp/2AbEi0sClEA4FSOZiPiGFzAt8SdgfLfYHbCpVuoFgWlkFQ7BEUXUHRGYw8tAAxh+chrjSLA6EIhUllczGlLBVTylKRXD5HedjnRdBjDh8Dvtgj2YgqmY9xhxbaQZ8Y7hBLvTL4sXKv6Prplnx/Lqx3s835U6V9lfAnbvpgiV9F358Mf88lvoXwWAJAM8osAOgIAr3lBroKgu15jL5+V8GvveGPANA/RABoYrFLfHRErgYAnQZCnJWCVf2AziDwpwYg8A0JAtnuYKkvUOUGanoDdUCQlYbDPm51BUUYFJ1BBoTjDi3kUBh7JBuxR7I5HE4ozUTC0QzNYR+PK83ioBdzeB6iSuYj8tACPH9wkQb4RKdPLvM+/cfWHr9Bcp8fK/eyXj/R9VOVfFnYo9B+yLMm7auAP824FyehD9Ehfu4nBIBmlb8BoDcg0BMg6A9A6Mrr1Pt5/Q3+CAD9QwSAChUUFODZZ5/FD3/4Qzz22GNISEhAQ0OD5jF37txBVlYWHn30UXTu3BkTJkzA1atXNY9pbm5GfHw8OnfujEcffRTZ2dn49ttvNY85fPgwwsLC0KlTJ/Ts2RNbtmwx/Do1ADh+rWMX0Egq2EE/IA+FiPuCXYXA11s3hrDdwWJfoKYkzNxAsTdQLgsLIMh6BFlYRHQFZRiUgVB0CUfvX4KIA4sRcWAxnj+4SHnY59njZdgTXT4GfGKJl7l9Ib9fgYG/y0X/vYLjJ4IfK/eyXj8d109T8s237fbNFYY8C6Ne5LJvW+Bv1EQCQFFmuTcA/wRAZxDoyZKwuyDYHkDozuvxNPh5G/4IAP1DBIAKxcTEYPv27aipqcHZs2cRFxeHoKAg/OMf/+CPSU9PR48ePbB//35UVFRg7NixGDx4ML777jsAwHfffYeQkBCMHTsWFRUV2L9/PwICApCVlcWf49KlS+jcuTPmz5+Puro6vPPOO+jQoQM+/PBDQ69TBMCx4wqUEKgMhDjqB5S3hDhLBjuCQGFOIB8W/bqwO1juC5RLwmJvoFgW1gHB3u9bB0nLrqAIgzIQilAogqErR3T3GPA5gj7R7WPhDl7qZeDHQh5CuTdoi8L1s5V8Nf1+bLcv2/ChA3+asq8j+BNCHyL8jZr4FsJfIABkMsu9AfgvAPrCDWwrDLoDh576Xu6Cn6/hjwDQP0QAaEB/+ctfYLFYcOTIEQDArVu30KFDB+zevZs/pqWlBQ888AA+++wzAMAnn3yCBx54AC0tLfwxu3btQqdOnfhf+Ndeew39+/fXfK+0tDSEh4cbel0yAI4dV+CwFKxMBRvpB1TsC24LBLLdwTwcolMSfuLnQm8gSwq/I4yM2VHAQbCnBIKiKzjwd7kY9PsVDoGQQaF4GNCpjvg49vXs+RjwqaBPdvtU4Mf7/MRyr+j6sZSvUPLl/X5i2MO23s1V+NNL/MrwN2rCWxgRk0eXuI789d4A/B8AvQWB7QmC3jrOXr+3wM+T8EcA6B8iADSg8+fPw2KxoLq6GgBw8OBBWCwW3Lx5U/O40NBQ5ObmAgBWrFiB0NBQzedv3rwJi8WCQ4cOAQBGjx6NefPmaR6zd+9efP/738e//vUvu9dx584d3L59m5+rV69aAXC0AICOSsEGBkQ7DYUYhUB5TqAAgZqEMCsJ5wklYdEN/JlUFpZBcHtrjyALi8iuYJ8P8rgzqAJCBoUMDOUjgp18RNBjsMeAj5V3++1ZpQt9Pd/Nb+3x+40O+P3SgetnK/mK/X4s6TtosbDeTRzy7AL8aUIfEvwRADqWv9wbgP7dUVnrvwDYFgj0BAj6Ewwaea3Ofl5/gj8CQP8QAaAT3b17FxMmTMCoUaP4x3bu3ImOHTvaPTYqKgpz584FAKSmpiIqKsruMR07dsS7774LAOjTpw/y8/M1nz9+/DgsFguuX79u97UrV66ExWKxOxGjVnAAdAqBBvoBvQGBfHfwPKsjZdcXmGPvBvLeQFtZWAmCQmlYdAXtYFABhP32rNJAIQNDBoeOziDhDPxdLnf3lMCngj7R7dteqOnxU4GfptdPDHqIrt8yKewxvxihWTrwN8NF+Eu0h7/R8eswIpoAUCV/ujcA/bvD3wHQGQS2Fwj6AgiNvqa2gp8v4I8A0D9EAOhEr7zyCoKDgzWN2noXeWRkJNLS0gBYL/Lo6Gi7x3To0AG7du0CYL3ICwoKNJ8/duwYLBYLbty4Yfe1ev+Kjxi5AuOez9dCoFwKdrEf0B0IFNPBdhtDUq0QKIZDxJIwHxVjC4j0WV2kKQvzkIgjEJRdQREG31UDIYNCBoYMDhkgqg77fN8P8/jXyLDHgM/O6WPQJ7t9rMdPD/ykcq/S9VOUfAdntCZ97TZ8tBH+CAD15U/3BuDYAbxwxfeQ52sIdAcGPQWG7nw/oz+PP4IfAaD/iADQgbKyshAYGIhLly5pPu7LUo4o1scTMXIFxkXkY+xYfRfQYT+ggVCIIQicql4bN+Rlnb5A5gYu0bqBbGagXVlYBYLi6Ji3BRj8H8kZZGViCQgZFPaS4VA8EtjJRwN6gsPHgW+H4PQx6BPcPh7u+IUT8MvXd/3YfD9NyVcY88J2+9oNebYFPhzBn1z6ZfA3Oo4AUCV/vzeA1ruDAeC9AIFGQLA9YNBbx+jrNgJ+voY/AkD/EAGgQnfv3kVmZiYCAgLQ2Nho93nWzP3ee+/xj12/fl3ZzC2WZHbv3m3XzD1gwADNc6enp7scAmEAOO55xxDosB/QExAozQnkEDhDgECpJKzrBsplYQaCcmlYDIv8Yr0aBt+xAeGvJSDcUWAFNAEM2en5rvPDH/+/Ctj7jQB82ySnT4Q+5vb9vLXHTwQ/3ucngp+q14+5fllW10+v308Ff7ppXyfwNzpuHfUACjLLvQFoQyBmAUBfgaCvgNDV1+cp8GsP+CMA9A8RACqUkZGBrl274vDhw7hx4wY/33zzDX9Meno6AgMDceDAAVRUVGDcuHHKcQ7jx49HRUUFDhw4gMDAQOU4h4ULF6Kurg7btm1zawwMB0AGgUb7AfWGRLsBgfKcQA0EqvoCxXmBWVJvoCsg+JY1NWznCoowuOUtNRBuswEaA0MbHHJAdHLYY/nXirD3jgB8Yl+fAvqe+Jkt1bte2+PnEPxek3r9su2HOzsNe7QR/qgErJVZ7g3APgV8v0KgOyDoDTBsy/c3+nP6C/gRAPqPCAAVUjVLWywWbN++nT/mn//8J7KysvDII4/goYceQnx8PK5cuaJ5nubmZsTFxeGhhx7CI488gqysLNy5c0fzmMOHD+OZZ55Bx44d8cQTT7g1CDpiRE4rAEqlYL1+QIehEFcgMFGCQNvGEFU4xK4krHAD7ZLCr9uDIC8Ns7CIWB4u2qCGQVvPoB0Q/rcAhgwOGSA6Ou8IRwQ90eETge8Xaujjbh9L9Yo9firwk8q9Yq8fc/2UJV9Vv5+BOX+O4G903DqMiCIAZDLLvQHoA6CZINDTIOgJGGyv48rPZOQ9am/4IwD0DxEAmljsEh8TnoNxo9foQqCyH1AOhbQVAqW1capwiKYkrHIDM+zLwnog2C9XCIuIrqAIg8wZ/JkEhKJD+MtWMORwyM7bOkd4DPu64M0S7KmAr1hw+hj0SW4fC3fogR8v94oJXweun1zyFeGP9/u5CX+j/5McQLNKNQfwXoZAV0HQH2HQ1dfvr+BHAOg/IgA0sewAUIRAJ/2A3oLA5xLf0kKgTknYkRuoKQtLICiWhnlq2OYKsuSwCIOsTMyBkPUNClDIDodD0TV0dITH8+fZaA98zOVj5V3u9OVLbl+uFW77v6Et9dqBn1zutfX6aVw/ueSrF/ZwMOTZGfxRCMS8EkMg4i9ls0KgKyDoDgz6AgrdfY3+Dn4EgP4jAkATiwPg8OUYP2qNnQvorB9QmQz2FAQ6CofouIEsKewUBF9VgKDoCr6pcAZFIFRAYc/iDa1uoQiIqiM8hn1dzyIB9tYLwOcI+vIUbt8y5+CnLPfKrp+Tfj9nSV8j8EclYPNKTgGrINDXgODPIOhJMPTE93flZ/YH+CMA9A8RAJpYHACHLcf451a7BYFyKES5Ls7AnECH4RBHo2JkN1AoCzsEQRYWkcrDGhhkziALj6yRHEIGhSIYMjg0ctYJkLdOeC4GeyLwrbbu6eVOnwB9dmVeW7hDF/ykcq/K9TPc79cG+Bv9n+swMnIVXeImlLMxMGaHQFdB0JMw2F7H1Z/PX8CPANB/RABoYmkAcKQVAFUQaBcKaQ8I1OsL1HMDbUlhpyAohkUWSq6gDINCmZgD4apWKOQuIQPDfAHcCiRQXCuBXYEEefmtz8V7+STg65ejcPqWtiZ6By2Wwh1Z+uAnl3uVvX4q18+D8BfxQiEBoEllFADNDoHugKA/w6A7P4u/gR8BoP+IANDE0pSAR67mLqDHINBAOdiVkrBDN1AqCzsEQRYWEV1BBQwOXKoDhDmtUKgBQxscckB0cthj+66yPcdKNexxl2+ZvdOngT7R7bOFOzSlXj3w0+v1M1ry1Qt7OIG/iBcK8dx4AkAzSgWA9zIEuguCvobCtrxeX7/fBID+LwJAE+vWrVuwWCx4bsgSjBm+HGOGLbf+b3gOIkbYzsgV/IwenYvREa1n1PMrNee5sSvx3PhVGBnJTh5GROVhRLR0YqT/H5OH8BfetJ5Y6xkeZzvxrf87bMJqDJu4GkMTVmPoT1bj2cTVeHbSGgyZbDtJtvPSGoRNWYNnpubjmeR8PJ2Sj8HT8jF4ej5CZ+QjdGY+nno5H0/NzkfInHwMSi3AoLQCDEwrwMD0Agx4pQADMgvQP6sA/bML0G9eAfrNL0C/BQXou9B2FhWgz2LpLGk9vV91fsTHi8/Td5HtLLR+z37zbWee9fX0z7K9xgzr6x2UVoBBcwsQMicfIT+1/lyhs6w/Z+gM68/9dEo+nv6vfDwzNR9hU9Yg7CXr+8Tfs8lrMOTFNXh20hoM/Yn1PR42cTWGTVit+TNg/5/9OYXHWv/c2J+j/Oc6Ilr6OxCVx/9+PDd+FYaPfh0WiwW3bt3y9X8OJBfE7o6jJ/8DlbX/n+ZU1bUevY+b+dR4+NR74Hjy9fj6/TV6yk79B90dPhYBoInF9nnSoePrI+68Jfm/Ll686PO/M3ToWCx0d/hSBIAm1r///W/U1dXx/4jEZe909A8DZ3rP2v6+3bp1C1evXsW///1vX//nQHJBf/vb32CxWHDlyhWf/70y06G7w3PvGd0dvhcBoMl1+7a1l+f2beqjMCp6z9wTvW/3jujP0j3R++a66D3zXxEAmlz0H5frovfMPdH7du+I/izdE71vroveM/8VAaDJRf9xuS56z9wTvW/3jujP0j3R++a66D3zXxEAmlx37tzBypUr7ZbFk/RF75l7ovft3hH9Wbonet9cF71n/isCQBKJRCKRSKT7TASAJBKJRCKRSPeZCABJJBKJRCKR7jMRAJJIJBKJRCLdZyIAJJFIJBKJRLrPRABoYm3evBlPPPEEOnXqhLCwMJSWlvr6JbWbjhw5gvj4eHTv3h0WiwUfffSR5vN3797FypUr0b17dzz44IMYM2YMampqNI+5efMmpk2bhocffhgPP/wwpk2bhr/97W+ax1RVVSEiIgIPPvggAgICkJeXh7t373r95/OGCgoK8Oyzz+KHP/whHnvsMSQkJKChoUHzmDt37iArKwuPPvooOnfujAkTJtitampubkZ8fDw6d+6MRx99FNnZ2fj22281jzl8+DDCwsLQqVMn9OzZE1u2bPH6z0cyLro76O5wRXR33JsiADSpdu/ejQ4dOuCdd95BXV0d5s+fjx/84Adobm729UtrF33yySdYvnw59uzZo7zECwsL0aVLF+zZswfV1dWYMmUKunfvjr///e/8MS+88AJCQkJQVlaGsrIyhISEID4+nn/+9u3bePzxxzF16lRUV1djz5496NKlCzZs2NBuP6cnFRMTg+3bt6OmpgZnz55FXFwcgoKC8I9//IM/Jj09HT169MD+/ftRUVGBsWPHYvDgwfjuu+8AAN999x1CQkIwduxYVFRUYP/+/QgICEBWVhZ/jkuXLqFz586YP38+6urq8M4776BDhw748MMP2/1nJtmL7g66O1wV3R33pggATaphw4YhPT1d87H+/fvj9ddf99Er8p3kS/zu3bvo1q0bCgsL+cfu3LmDrl274u233wYAvkP5xIkT/DHl5eWwWCz8X7a/+tWv0LVrV838qrVr1yIgIMC0/5IX9Ze//AUWiwVHjhwBANy6dQsdOnTA7t27+WNaWlrwwAMP4LPPPgNg/eX5wAMPoKWlhT9m165d6NSpEx/0+tprr6F///6a75WWlobw8HBv/0gkA6K7o1V0d7gnujvuDREAmlDffvstvve972Hv3r2aj8+bNw8RERE+elW+k3yJX7x4ERaLBRUVFZrHTZw4ETNmzAAAbNu2DV27drV7rq5du+LXv/41AGD69OmYOHGi5vMVFRWwWCy4dOmSp3+Mdtf58+dhsVhQXV0NADh48CAsFgtu3rypeVxoaChyc3MBACtWrEBoaKjm8zdv3oTFYsGhQ4cAAKNHj8a8efM0j9m7dy++//3v41//+pe3fhySAdHdoRXdHe6J7o57QwSAJlRLSwssFguOHz+u+Xh+fj769u3ro1flO8mX+PHjx2GxWDT/0gSA1NRUREdHA7C+V3369LF7rj59+qCgoAAAEBUVhdTUVM3n2XtfVlbm6R+jXXX37l1MmDABo0aN4h/lpQV4AAAERUlEQVTbuXMnOnbsaPfYqKgozJ07F4D1PYyKirJ7TMeOHfHuu+8CsL6H+fn5ms+zP5Pr16978scguSi6O7Siu8N10d1x74gA0ITSu0jWrFmDfv36+ehV+U56l7h8YcyZMwcxMTEA9H/h9e7dG2vXrgWgvbyYrl27BovFgvLyck//GO2qV155BcHBwZombb1LPDIyEmlpaQC0vwhFdejQAbt27QKg/UXIdOzYMVgsFty4ccOTPwbJRdHdoRXdHa6L7o57RwSAJhSVcbSiMo5rysrKQmBgoN3PQGWce190d2hFd4drorvj3hIBoEk1bNgwZGRkaD42YMAAauRGayP3unXr+Me+/fZbZSP3yZMn+WNOnDhh18j9ox/9SDOmoLCw0LSN3Hfv3kVmZiYCAgLQ2Nho93nWyP3ee+/xj12/fl3ZyC06JLt377Zr5B4wYIDmudPT06mR209Ed0er6O4wJro77k0RAJpUbJTDtm3bUFdXhwULFuAHP/gBLl++7OuX1i76+uuvUVlZicrKSlgsFhQXF6OyspKPsigsLETXrl2xd+9eVFdXIzk5WTnKITQ0FOXl5SgvL8dTTz2lGeVw69YtPP7440hOTkZ1dTX27t2Lhx9+2LSjHDIyMtC1a1ccPnwYN27c4Oebb77hj0lPT0dgYCAOHDiAiooKjBs3TjnKYfz48aioqMCBAwcQGBioHOWwcOFC1NXVYdu2bTTKwY9EdwfdHa6K7o57UwSAJtbmzZsRHByMjh07IiwsjEfy7weVlJTAYrHYnZkzZwJoHebarVs3dOrUCRERETyxxvTXv/4VKSkp6NKlC7p06YKUlBTlMNfRo0ejU6dO6NatG1atWmXKf8EDUL5fFosF27dv54/55z//iaysLDzyyCN46KGHEB8fjytXrmiep7m5GXFxcXjooYfwyCOPICsrSzPuArAOc33mmWfQsWNHPPHEEzTM1c9EdwfdHa6I7o57UwSAJBKJRCKRSPeZCABJJBKJRCKR7jMRAJJIJBKJRCLdZyIAJJFIJBKJRLrPRABIIpFIJBKJdJ+JAJBEIpFIJBLpPhMBIIlEIpFIJNJ9JgJAEolEIpFIpPtMBIAkEolEIpFI95kIAEkkEolEIpHuMxEAkkgkEolEIt1nIgAkkUgkEolEus9EAEgikUgkEol0n4kAkEQikUgkEuk+EwEgiUQikUgk0n0mAkASiUQikUik+0wEgCQSiUQikUj3mQgASSQSiUQike4zEQCSSCQSiUQi3WciACSRSCQSiUS6z0QASCKRSCQSiXSfiQCQRCKRSCQS6T4TASCJRCKRSCTSfSYCQBKJRCKRSKT7TASAJBKJRCKRSPeZCABJJBKJRCKR7jMRAJJIJBKJRCLdZyIAJJFIJBKJRLrPRABIIpFIJBKJdJ+JAJBEIpFIJBLpPhMBIIlEIpFIJNJ9JgJAEolEIpFIpPtM/w9T9Oda1Kef/QAAAABJRU5ErkJggg==\" width=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x7fede8469dd8>"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"fig,ax = subplots(2,2)\n",
"ax[0,0].imshow(numpy.arcsinh(frame4[...,0]))\n",
"ax[0,1].imshow(numpy.arcsinh(frame4[...,1]))\n",
"ax[1,0].imshow(frame4[...,2])\n",
"ax[1,1].imshow(frame4[...,3])"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 18.1 s, sys: 557 ms, total: 18.7 s\n",
"Wall time: 15.5 s\n"
]
}
],
"source": [
"%time cnt = [len(pf(img, error_model=\"poisson\", cutoff=5, cycle=5)) for img in ds]"
]
},
{
"cell_type": "code",
"execution_count": 20,
"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 / mpl.ratio, fig.canvas.height / mpl.ratio);\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=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x7fede8292cf8>]"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"fig,ax = subplots()\n",
"ax.plot(cnt)"
]
},
{
"cell_type": "code",
"execution_count": 21,
"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 / mpl.ratio, fig.canvas.height / mpl.ratio);\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4nO3dfXRU5YHH8RtC3ohK5W0NYJJWyIsCkdSNrw1arPgSrGvtuh5f4ilVE19IurZrbM6adSVocUW3h+ALpVpba8SSiHIivm0MNomKh0HRVKurYIxaK0hAt4kIv/3Dk6lDAt7c597JPDPfzznPHw53nnvvM5Ph653M4AgAAAAJxRnpAwAAAEB0EYAAAAAJhgAEAABIMAQgAABAgiEAAQAAEgwBCAAAkGAIQAAAgARDAAIAACQYAhAAACDBEIAAAAAJhgAEAABIMAQgAABAgiEAAQAAEgwBCAAAkGAIQAAAgARDAAIAACQYAhAAACDBEIAAAAAJhgAEAABIMAQgAABAgiEAAQAAEgwBCAAAkGAIQAAAgARDAAIAACQYAhAAACDBEIAAAAAJhgAEAABIMAQgAABAgiEAAQAAEgwBCAAAkGAIQAAAgARDAAIAACQYAhAAACDBEIAAAAAJhgAEAABIMAQgAABAgiEAgRh17733ynEcbdiwYcg/P+uss5STkxNxW05OjsrLy4e1n/b2dtXV1emTTz7xeKSJp7GxUUceeaTS09PlOI5CodCw7j/w2L7zzjvh2+bMmaM5c+ZEbPfOO+/ozDPP1KGHHirHcVRVVSVJ2rhxo0pLS3XIIYfIcRzdfvvtEfebPXu2Fi5c6Pp4vDxvANiNAARilJcA3Lhxo956661h7efWW28dFCPYv48++kgpKSmaP3++nn32WXV2duqzzz4b1hxDBeBrr72m1157LWK7c845R+PHj1dzc7M6Ozu1ZcsWSdLRRx+t6dOnq6WlRZ2dnfrggw/C93n77bflOI7a2tpcH4+X5w0AuxGAQIzyEoBejHQAfv7559q9e/eI7NuLP/7xj3IcRw899JDnOYYKwKFMmzZNZ5xxxqDbR48ercrKyiHvs2TJEk2aNEl79uzxfHwA4h8BCMQoP94C3rNnj2666Sbl5eUpPT1dY8eO1cyZM3XHHXdIkurq6uQ4zqDR2toavv8vfvEL5efnKzU1VRMnTtTFF1+s7u7uiP3u3btX9fX1ys7OVlpamr797W/rySefHPS2ZmtrqxzH0f33369//dd/1eTJk5WUlKQ//elP+uijj1RZWanCwkJlZmZq4sSJOuWUU7R+/fqIfb3zzjtyHEdLlizRLbfcopycHKWnp2vOnDl644039Pnnn+u6665TVlaWDjnkEJ1zzjn6y1/+4mrN16xZo+OOO04ZGRk66KCDdOqpp6qjoyP85+Xl5YPWat+3bffV2dmpE044QWlpacrKylJNTY3uueeeA74FPLBO+46B58S+46uOPfZYXXHFFeH/3rhxo8466yxNnDhRqampysrK0plnnhnxGA71FvCrr76q733ve8rIyNCECRN05ZVXau3atRHPj4HjPuqoo9TR0aHjjz9e6enpysnJ0a9//WtJ0tq1azV79mxlZGRoxowZevzxxyP28+abb+rSSy/VtGnTlJGRocmTJ6usrEyvvPLKAdcVgBkCEIhRA3/ZP//889q9e/egceaZZ35tAN58881KTk5WXV2dnnnmGa1bt0533HGH/uM//kOS1N3drWuuuUaO46ipqUmdnZ3q7OxUb2+vJOnyyy+X4zi6+uqrtW7dOt11112aOHGiDj/8cP31r38N7+f666+X4zi6/PLLtW7dOq1YsULZ2dnKysoaMgCnTJmi8847T48++qjWrl2rbdu26fXXX1dlZaUaGxv17LPPau3atVqwYIFGjRoVERwDAZiTk6P58+dr7dq1+t3vfqd/+Id/UF5eni6++GL96Ec/0uOPP6677rpLBx10kObPn/+16/3AAw/IcRyddtppeuSRR/TQQw/p29/+tlJTU/Xcc89Jkt566y01NDTIcRwtXrxYnZ2dg962/arXXntNY8aM0ZFHHqkHH3xQa9as0bx585SdnX3AAOzt7VVnZ6cOO+wwnXjiieHH5cMPP1RnZ6ccx9F5550Xvn1Ad3e3kpKS9OSTT0qSPv30U40fP17HHHOMVq1apba2Nj300EOqqKhQV1fXfp8377//vsaPH6/s7Gzdd999amlp0cUXX6zc3NwhA3D8+PHKz8/XypUr9cQTT6isrEyO4+jGG2/UzJkz9eCDD6qlpUXHHXec0tLS1NPTE75/W1ubrr32Wv3hD39QW1ubmpubdc455ygjI0Ovv/761z5uALwhAIEYtb+rPV8dXxeAZWVlOvroow+4n/29BfynP/1JjuPoyiuvjLj9hRdekOM4+vnPfy5J2r59u9LS0nT++edHbDcQKkMFYGlp6dee/xdffKHdu3dr7ty5+qd/+qfw7QMBWFRUFPE25x133CHHcXT22WdHzFNdXS3HccJRO5Q9e/Zo8uTJmjlzZsScu3bt0qRJk3TCCScMOoeHH374a8/h/PPPV0ZGhj788MOI8yooKHD1IZCcnBydddZZg+Z1HEdXXXXVoNvvuOMOHXrooeG31F966SU5jqNHHnnkgMe57/PmZz/7mZKSkgbF7bx584YMQMdx9NJLL4Vv27Ztm5KTk5WRkRERe5s2bZLjOPrlL3+532P54osv9Pnnn2v69On6yU9+csDjBuAdAQjEqIEAvP/++7Vhw4ZB46STTvraAPzP//xPJSUlqbKyUuvWrRsygvYXgMuXL5fjOHrxxRcH3aewsFDHHnusJKmlpUWO42j16tWDtsvNzR0yAP/7v/97yHO+8847NXv2bKWlpUWEbkFBQXibgQC8/vrrI+77xBNPyHEc3X333RG333333XIcR5s3bx5yn5LU1dUVflt5X5WVlRo1alT4gx7DCcBJkyaprKxs0O0Db737HYDf+c53dOmll4b/e8eOHTr00EOVn5+vO++8c79XK/d93pSUlGjmzJmDtrvvvvuGDMCsrKxB22ZlZen444+PuK2/v1+O4+jaa68N37Z7927V19ersLBQKSkpEY/76aefPuTxAjBHAAIxyo/fAdy9e7duu+02zZ49W0lJSRo9erS++93vRsy5vwC86aab5DjOoN/3k6S5c+dq2rRpkqTf/va3chxHf/zjHwdtd+yxxw4ZgKtWrRq07W233SbHcVRRUaG1a9fq+eef14YNG3T66adHnOdAAN56660R999fmH3dOkrSc889J8dx9Nvf/nbQnw2sw3vvvXfA/QwlOTlZP/7xjwfdfuedd/oegB988IFGjRqlxx57LOL2V155Reeff374q2SysrJ0ww036PPPP4/Yz1efN0cccYROPfXUQft9/PHH9/s7gPtye+zXXHONRo0apeuvv17r1q3TCy+8oA0bNqioqOhrf78SgHcEIBCj/P4ewE8++UQPP/ywpk+frnHjxoWvaHm9AnjcccdJOvAVwJycnCEDcKh4mj17tk4++eRBt5944omBB2A8XAFcvny5Dj74YPX19Q15LHv37tWmTZvCb4nffPPNEftxcwVwYC39DMBDDz004qrlgClTphCAQIAIQCBGBfVF0AO/KzfwduAvf/lLOY4T8aEASXr99dflOM6gLxR+8cUX5TiOamtrJX35+15paWn653/+54jt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b036o7m5WY7jKDk5OTwcx1FSUpKSk5P19NNPs84+yM7O1oIFCyJuW758uSZPniyJtyb9MnXqVC1btizitptuuin8P+Ossz94C3jkEIAxpqSkRJWVlRG3FRYW8iEQA3v37tVVV12lyZMn689//vOgPx/4cMJDDz0Uvu3999/nwwnDtHPnTm3evDliHHPMMbrooou0efNm1tknF1xwwaAPgVRXV4evCg78Ev0vfvGL8J/39/fz4YRhGjdunJYvXx5x2+LFi8NvPbLO/tjfh0AOtK4DHwJ54YUXwts8//zzfAhkmAjAGDPwNTArV65UV1eXqqurlZmZqS1btoz0oVmrsrJSY8eO1bPPPqsPPvggPP7v//4vvE1FRYWmTp2qp59+Whs3btR3v/tdvp7EB199C1hinf3w4osvavTo0aqvr9ebb76pBx54QGPGjNHvfve78Da33HKLxo4dq6amJm3evFkXXHABX08yTOXl5ZoyZUr4a2Campo0YcIE/du//Vt4G9bZm127dikUCikUCslxHC1dulShUCj8dWdu1vX000/XrFmz1NnZqc7OTs2cOZOvgRkmAjAGNTQ0KCcnR6mpqSouLg5/XQm8cRxnyHHvvfeGt/nb3/6mq6++OvzFumVlZXr33XdH7qDjxL4ByDr747HHHtOMGTOUlpamgoKCiE8BS3//It3DDjtMaWlpKi0tDX/qHe7s3LlTVVVVys7OVnp6ur71rW+ptrZW/f394W1YZ29aW1uHfE0uLy+X5G5dt23bpgsvvFAHH3ywDj74YF144YV8EfQwEYAAAAAJhgAEAABIMAQgAABAgiEAAQAAEgwBCAAAkGAIQAAAgARDAAIAACQYAhAAACDBEIAAAAAJhgAEAABIMAQgAABAgiEAAQAAEgwBCAAAkGAIQAAAgARDAAIAACQYAhAAACDBEIAAAAAJhgAEAABIMAQgAABAgiEAAQAAEgwBCAAAkGAIQAAAgARDAAIAACQYAhAAACDBEIAAAAAJhgAEAABIMAQgAABAgiEAAQAAEgwBCAAAkGAIQAAAgARDAAIAACQYAhAAACDB/D/1jKDOOAaVygAAAABJRU5ErkJggg==\" width=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig,ax = subplots()\n",
"ax.hist(((frame4[...,0]-frame4[...,2])/frame4[...,3]).ravel(), 100, range=(0,100))\n",
"ax.set_title(\"Histogram of diff/sigma\")\n",
"ax.set_yscale('log', nonposy='clip')"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [],
"source": [
"def display(img, cutoff=5):\n",
" fig, ax = subplots()\n",
" img = img.copy()\n",
" img[numpy.where(mask)] = 0\n",
" ax.imshow(img, vmin=0, vmax=100, origin=\"lower\")\n",
" pts = pf(img, error_model=\"poisson\", cutoff=cutoff, cycle=5)\n",
" x = pts%img.shape[-1]\n",
" y = pts//img.shape[-1]\n",
" ax.scatter(x,y,marker=\".\")\n",
" return \n",
" "
]
},
{
"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 / mpl.ratio, fig.canvas.height / mpl.ratio);\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=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"display(img)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%time cnt = [len(pf(img, error_model=\"poisson\", cutoff=5, cycle=5)) for img in ds]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fig,ax = subplots()\n",
"ax.plot(cnt)"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"6.67 ms ± 5.99 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n",
"3.68 ms ± 400 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)\n",
"2.09 ms ± 115 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)\n",
"1.24 ms ± 54.3 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n"
]
}
],
"source": [
"shape = (1024, 1024)\n",
"data = numpy.random.random(shape)\n",
"res1 = []\n",
"for i in (2, 4, 8, 16):\n",
" o = %timeit -o data.reshape(1024 // i, i, 1024 // i, i).sum(axis=(1,3))\n",
" res1.append(o)"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[<TimeitResult : 6.67 ms ± 5.99 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)>,\n",
" <TimeitResult : 3.68 ms ± 400 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)>,\n",
" <TimeitResult : 2.09 ms ± 115 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)>,\n",
" <TimeitResult : 1.24 ms ± 54.3 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)>]"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"res"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [],
"source": [
"def ex4_2(data, i):\n",
" \"\"\"Generate a 2D array of [1..9999] then operate a 2x2 binning\n",
" \"\"\"\n",
" binned = numpy.zeros([j//i for j in data.shape], dtype=data.dtype)\n",
" #for j in range(i):\n",
" # for k in range(i):\n",
" for j, k in itertools.product(range(i), range(i)):\n",
" binned += data[j::i, k::i]\n",
" return binned\n"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1.45 ms ± 334 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n",
"1.52 ms ± 10.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n",
"2.11 ms ± 505 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)\n",
"3.53 ms ± 1.92 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
]
}
],
"source": [
"res2 = []\n",
"for i in (2, 4, 8, 16):\n",
" o = %timeit -o ex4_2(data, i)\n",
" res2.append(o)"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[(0, 0),\n",
" (0, 1),\n",
" (0, 2),\n",
" (0, 3),\n",
" (1, 0),\n",
" (1, 1),\n",
" (1, 2),\n",
" (1, 3),\n",
" (2, 0),\n",
" (2, 1),\n",
" (2, 2),\n",
" (2, 3),\n",
" (3, 0),\n",
" (3, 1),\n",
" (3, 2),\n",
" (3, 3)]"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import itertools\n",
"[i for i in itertools.product(range(4), range(4))]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"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.9.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment