diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..a44e9b685f7c47f2118467fc55437d864bd22971 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.ipynb* +src/*.egg* +*.pyc +*__pycache__* +tmp/ diff --git a/README.rst b/README.rst new file mode 100644 index 0000000000000000000000000000000000000000..eeb564dba3fbf9e791c9d909dba4f5b770e5362d --- /dev/null +++ b/README.rst @@ -0,0 +1,37 @@ +########### +SCS ToolBox +########### + +Kernel +###### + +The SCS ToolBox is design to work in the exfel_anaconda3 environement. This can +be selected on the online cluster by: + +`module load exfel exfel_anaconda3` + +before launching the jupyter-notebook or on max-jhub by selecting the 'xfel' +kernel instead of the 'Python 3' anaconda environement maintained by DESY. + +Installation +############ + +As long as the ToolBox is not yet added to the exfel_anaconda3 environment it needs to be installed locally. + +Activate environment mentioned above and check installation of scs_toolbox: + +.. code:: bash + + pip show toolbox_scs + +If the toolbox has been installed in your home directory previously, everything is set up. Otherwise it needs to be installed (only once). In that case enter the following command in the directory where the *setup.py* script is located: + +.. code:: bash + + pip install --user . + +If you intend to develop code in the toolbox use the -e flag for installation. This creates a symbolic link to the source code you are working on. + +.. code:: bash + + pip install --user -e . \ No newline at end of file diff --git a/Readme.md b/Readme.md deleted file mode 100644 index 54e2b811f1247f195c3f49847fa0d93831d18e16..0000000000000000000000000000000000000000 --- a/Readme.md +++ /dev/null @@ -1,11 +0,0 @@ -# SCS ToolBox - -## Kernel - -The SCS ToolBox is design to work in the exfel_anaconda3 environement. This can -be selected on the online cluster by: - -`module load exfel exfel_anaconda3` - -before launching the jupyter-notebook or on max-jhub by selecting the 'xfel' -kernel instead of the 'Python 3' anaconda environement maintained by DESY. \ No newline at end of file diff --git a/VERSION b/VERSION new file mode 100644 index 0000000000000000000000000000000000000000..15f445be00fe4d3a72cea515c17ff34749fa34dd --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.1.2rc1 diff --git a/__init__.py b/__init__.py deleted file mode 100644 index ee34d75e82c0a49e2a417f4f11842be049b66376..0000000000000000000000000000000000000000 --- a/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -from ToolBox.Load import * -from ToolBox.xgm import * -from ToolBox.XAS import * -from ToolBox.knife_edge import * -from ToolBox.Laser_utils import * -from ToolBox.DSSC import DSSC -from ToolBox.azimuthal_integrator import * -from ToolBox.DSSC1module import * -from ToolBox.bunch_pattern import * -from ToolBox.FastCCD import * diff --git a/azimuthal_integrator.py b/azimuthal_integrator.py deleted file mode 100644 index b84df6c347c9445e713d53234562857f29098135..0000000000000000000000000000000000000000 --- a/azimuthal_integrator.py +++ /dev/null @@ -1,74 +0,0 @@ -import numpy as np - -class azimuthal_integrator(object): - def __init__(self, imageshape, center, polar_range, dr=2, aspect=204/236): - ''' - Create a reusable integrator for repeated azimuthal integration of similar - images. Calculates array indices for a given parameter set that allows - fast recalculation. - - Parameters - ========== - imageshape : tuple of ints - The shape of the images to be integrated over. - - center : tuple of ints - center coordinates in pixels - - polar_range : tuple of ints - start and stop polar angle (in degrees) to restrict integration to wedges - - dr : int, default 2 - radial width of the integration slices. Takes non-square DSSC pixels into account. - - aspect: float, default 204/236 for DSSC - aspect ratio of the pixel pitch - - Returns - ======= - ai : azimuthal_integrator instance - Instance can directly be called with image data: - > az_intensity = ai(image) - radial distances and the polar mask are accessible as attributes: - > ai.distance - > ai.polar_mask - ''' - self.shape = imageshape - cx, cy = center - print(f'azimuthal center: {center}') - sx, sy = imageshape - xcoord, ycoord = np.ogrid[:sx, :sy] - xcoord -= cx - ycoord -= cy - - # distance from center, hexagonal pixel shape taken into account - dist_array = np.hypot(xcoord * aspect, ycoord) - - # array of polar angles - if np.abs(polar_range[1]-polar_range[0]) > 180: - raise ValueError('Integration angle too wide, should be within 180 degrees') - - if np.abs(polar_range[1]-polar_range[0]) < 1e-6: - raise ValueError('Integration angle too narrow') - - tmin, tmax = np.deg2rad(np.sort(polar_range)) % np.pi - polar_array = np.arctan2(xcoord, ycoord) - polar_array = np.mod(polar_array, np.pi) - self.polar_mask = (polar_array > tmin) * (polar_array < tmax) - - self.maxdist = max(sx - cx, sy - cy) - - ix, iy = np.indices(dimensions=(sx, sy)) - self.index_array = np.ravel_multi_index((ix, iy), (sx, sy)) - - self.distance = np.array([]) - self.flat_indices = [] - for dist in range(dr, self.maxdist, dr): - ring_mask = self.polar_mask * (dist_array >= (dist - dr)) * (dist_array < dist) - self.flat_indices.append(self.index_array[ring_mask]) - self.distance = np.append(self.distance, dist) - - def __call__(self, image): - assert self.shape == image.shape, 'image shape does not match' - image_flat = image.flatten() - return np.array([np.nansum(image_flat[indices]) for indices in self.flat_indices]) diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..298ea9e213e8c4c11f0431077510d4e325733c65 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,19 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/doc/bunch_pattern_decoding.rst b/doc/bunch_pattern_decoding.rst new file mode 100644 index 0000000000000000000000000000000000000000..f1812e42e7e12c46cbed71f11b90e044ac292688 --- /dev/null +++ b/doc/bunch_pattern_decoding.rst @@ -0,0 +1,34 @@ +.. code:: ipython3 + + import toolbox_scs as tb + import toolbox_scs.misc as tbm + + proposalNB = 2511 + runNB = 176 + +**option 1** + +This method uses function we implemented. + +.. code:: ipython3 + + fields = ["bunchPatternTable"] + run = tb.load(fields, runNB, proposalNB) + bpt = run['bunchPatternTable'] + + bpt_dec = tbm.extractBunchPattern( + run['bunchPatternTable'],'scs_ppl') + + +**option 2** + +This method uses function from the euxfel_bunch_pattern package. + +.. code:: ipython3 + + + run = tb.load_run(proposalNB, runNB) + mnemonic = tb.mnemonics["bunchPatternTable"] + bpt = run.get_array(*mnemonic.values()) + + bpt_is_laser = tbm.is_ppl(bpt) diff --git a/doc/conf.py b/doc/conf.py new file mode 100644 index 0000000000000000000000000000000000000000..a48fe7ad33d49bcb617ca9252ebab5fee5dd3ebc --- /dev/null +++ b/doc/conf.py @@ -0,0 +1,185 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +sys.path.insert(0, os.path.abspath('..')) +import sphinx_rtd_theme + +# -- Project information ----------------------------------------------------- + +project = 'SCS Toolbox' +copyright = '2021, SCS' +author = 'SCS' + +# The short X.Y version +version = '' +# The full version, including alpha/beta/rc tags +release = '' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.mathjax', + 'sphinx.ext.viewcode', + 'sphinx.ext.coverage', + 'sphinx.ext.napoleon', + 'autoapi.extension', + 'sphinx_rtd_theme', +] +autoapi_dirs = ['../src/toolbox_scs'] +autoapi_ignore = ['*/deprecated/*'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = None + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +#html_theme = 'alabaster' +html_theme = 'sphinx_rtd_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'SCSToolboxdoc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'SCSToolbox.tex', 'SCS Toolbox Documentation', + 'SCS', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'scstoolbox', 'SCS Toolbox Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'SCSToolbox', 'SCS Toolbox Documentation', + author, 'SCSToolbox', 'One line description of project.', + 'Miscellaneous'), +] + + +# -- Options for Epub output ------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + + +# -- Extension configuration ------------------------------------------------- diff --git a/doc/dssc/DSSCBinner.rst b/doc/dssc/DSSCBinner.rst new file mode 100644 index 0000000000000000000000000000000000000000..de3bee56c589b1750fde17d420929a7bf931c57f --- /dev/null +++ b/doc/dssc/DSSCBinner.rst @@ -0,0 +1,157 @@ +Basic principle +=============== + +In a DSSC binner object we basically define maps, here called 'binners'. They define into which bucket a value along a certain dimension will be put into. + +map: coordinate array along specified dimension -> array of buckets + + +Example 1 +========= + +Bin static run +~~~~~~~~~~~~~~ + +.. code:: ipython3 + + import os + import logging + import importlib + + import numpy as np + import xarray as xr + import pandas as pd + + import extra_data as ed + import toolbox_scs as tb + import toolbox_scs.detectors as tbdet + import toolbox_scs.detectors.dssc_plot as dssc_plot + + #logging.basicConfig(level=logging.INFO) + +.. code:: ipython3 + + # run settings + proposal_nb = 2711 + run_nb = 97 + +.. code:: ipython3 + + # create a extra_data run object and collect detector information + run = tb.load_run(proposal_nb, run_nb) + dssc_info = tbdet.load_dssc_info(proposal_nb, run_nb) + +.. code:: ipython3 + + # create toolbox bin object + bin_obj = tbdet.DSSCBinner(proposal_nb, run_nb) + +.. code:: ipython3 + + # create array that will map the pulse dimension into + # buckets 'image' and 'dark' -> resulting dimension length = 2 + buckets_pulse = ['image', 'dark'] * 30 # put all 60 pulses into buckets image and dark + + + # create array that will map the trainId dimension into + # buckets [0] -> resulting dimension length = 1 + buckets_train = np.zeros(len(run.train_ids)).astype(int) # put all train Ids to the same bucket called 0. + +.. code:: ipython3 + + #create binners (xarray data arrays that basically act as a map) + fpt = dssc_info['frames_per_train'] + binnertrain = tbdet.create_dssc_bins("trainId",run.train_ids,buckets_train) + binnerpulse = tbdet.create_dssc_bins("pulse",np.linspace(0,fpt-1,fpt, dtype=int),buckets_pulse) + + +.. code:: ipython3 + + # add binners to bin object + bin_obj.add_binner('trainId', binnertrain) + bin_obj.add_binner('pulse', binnerpulse) + +.. code:: ipython3 + + # get a prediction of how the data will look like (minus module dimension) + bin_obj.get_info() + + +.. parsed-literal:: + + Frozen(SortedKeysDict({'trainId': 1, 'pulse': 2, 'x': 128, 'y': 512})) + + +.. code:: ipython3 + + # bin 2 modules in parallel + + mod_list = [0,15] + bin_obj.bin_data(chunksize=248, modules=mod_list, filepath='./') + +.. code:: ipython3 + + # Save metadata into file + fname = 'testfile.h5' + tbdet.save_xarray(fname, binnertrain, group='binner1', mode='a') + tbdet.save_xarray(fname, binnerpulse, group='binner2', mode='a') + +Example2 +======== + +bin pump-probe data +~~~~~~~~~~~~~~~~~~~ + +.. code:: ipython3 + + # run settings + proposal_nb = 2212 + run_nb = 235 + +.. code:: ipython3 + + # Collect information about run + run_obj = tb.load_run(proposal_nb, run_nb) + detector_info = tbdet.load_dssc_info(proposal_nb, run_nb) + +.. code:: ipython3 + + bin_obj = tbdet.DSSCBinner(proposal_nb, run_nb) + +.. code:: ipython3 + + # define buckets + buckets_trainId = (tb.get_array(run_obj, 'PP800_PhaseShifter', 0.03)).values + buckets_pulse = ['pumped', 'unpumped'] * 10 + + # create binner + binnerTrain = tbdet.create_dssc_bins("trainId", + detector_info['trainIds'], + buckets_trainId) + binnerPulse = tbdet.create_dssc_bins("pulse", + np.linspace(0,19,20, dtype=int), + buckets_pulse) + +.. code:: ipython3 + + bin_obj.add_binner('trainId', binnerTrain) + bin_obj.add_binner('pulse', binnerPulse) + + +.. code:: ipython3 + + # get a prediction of how the data will look like (minus module dimension) + bin_obj.get_info() + + +.. parsed-literal:: + + Frozen(SortedKeysDict({'trainId': 271, 'pulse': 2, 'x': 128, 'y': 512})) + + +.. code:: ipython3 + + # bin 2 modules using the joblib module to precess the two modules + # in parallel. + + bin_obj.bin_data(chunksize=248, modules=mod_list, filepath='./') diff --git a/doc/dssc/hist1D.png b/doc/dssc/hist1D.png new file mode 100644 index 0000000000000000000000000000000000000000..4f2eac68a52f1f163f9936c520bad15d4e85aabd Binary files /dev/null and b/doc/dssc/hist1D.png differ diff --git a/doc/dssc/plot1D.png b/doc/dssc/plot1D.png new file mode 100644 index 0000000000000000000000000000000000000000..d9c4f2f9109034ed81f6609a441564cb5e524d32 Binary files /dev/null and b/doc/dssc/plot1D.png differ diff --git a/doc/dssc/xgm_threshold.png b/doc/dssc/xgm_threshold.png new file mode 100644 index 0000000000000000000000000000000000000000..837a07164501b3ba6749fc61664a77d98eda14b6 Binary files /dev/null and b/doc/dssc/xgm_threshold.png differ diff --git a/doc/getting_started.rst b/doc/getting_started.rst new file mode 100644 index 0000000000000000000000000000000000000000..05e2d9f7874288941e35fb3568acd9dc3a8b0820 --- /dev/null +++ b/doc/getting_started.rst @@ -0,0 +1,24 @@ +``Getting started`` +~~~~~~~~~~~~~~~~~~~ + +Installation +------------ +The ToolBox may be installed in any environment. However, it depends on the extra_data and the euxfel_bunch_pattern package, which are no official third party python modules. Within environments where the latter are not present, they need to be installed by hand. + +Furthermore, as long as the ToolBox is not yet added to one of our custom environments, it needs to be installed locally. Activate your preferred environment and check installation of scs_toolbox by typing: + +.. code:: bash + + pip show toolbox_scs + +If the toolbox has been installed in your home directory previously, everything is set up. Otherwise it needs to be installed (only once). In that case enter following command from the the ToolBox top-level directory: + +.. code:: bash + + pip install --user . + +Alternatively, use the -e flag for installation to install the package in development mode. + +.. code:: bash + + pip install --user -e . diff --git a/doc/howtos.rst b/doc/howtos.rst new file mode 100644 index 0000000000000000000000000000000000000000..aac8797f2d698f250422a21568e4654377b821f7 --- /dev/null +++ b/doc/howtos.rst @@ -0,0 +1,27 @@ +``How to's`` +~~~~~~~~~~~~ + +top +--- + +* :doc:`load run and data <load>`. + +misc +---- + +* :doc:`bunch pattern decoding <bunch_pattern_decoding>`. + + +detectors (dssc) +---------------- + +Most of the functions within toolbox_scs.detectors can be accessed directly. This is useful during development, or when working in a non-standardized way, which is often neccessary during data evaluation. For frequent routines there is the possibility to use dssc objects that guarantee consistent data structure, and reduce the amount of recurring code within the notebook. + +* bin data using toolbox_scs.tbdet -> *to be documented*. +* :doc:`bin data using the DSSCBinner <dssc/DSSCBinner>`. +* post processing, data analysis -> *to be documented* + +routines +-------- + +* *to do* diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..d6594a2de1cf04ed8b0566315eb87d6af0850782 --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,48 @@ +Welcome to SCS Toolbox's documentation! +======================================= + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + :numbered: + :titlesonly: + :glob: + :hidden: + + getting_started.rst + howtos.rst + + +``Contribute`` +~~~~~~~~~~~~~~ + +For reasons of readability, contributions preferrably comply with the PEP8_ code structure guidelines. + +.. _PEP8: https://www.python.org/dev/peps/pep-0008/#a-foolish-consistency-is-the-hobgoblin-of-little-minds + +The associated code checker, called 'flake8', can be installed via PyPi. + + +Module index +============ + +*to to* (automatized doc generation) + +**toolbox_scs**: Top-level entry point + +**detectors**: detector specific routines + +**routines**: Automatized evaluations involving several instruments + +**misc**: Various sub-routines and helper functions + +**test**: Test environment + +**util**: Package related routines + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/doc/load.rst b/doc/load.rst new file mode 100644 index 0000000000000000000000000000000000000000..37265ead67f805e289f4d16c9ad480e17cb6fedc --- /dev/null +++ b/doc/load.rst @@ -0,0 +1,34 @@ +**Option 1**: + +.. code:: python3 + + import toolbox_scs as tb + + # optional, check available mnemonics + # print(tb.mnemonics) + # fields is a list of available mnemonics, representing the data + # to be loaded + + fields = ["FastADC4raw", "scannerX"] + proposalNr = 2565 + runNr = 19 + + run_data = tb.load(fields, runNr, proposalNr) + +run_data is an xarray dataArray. It has an attribute called 'run' containing the underlying extra_data dataCollection. + +**Option 2**: + +.. code:: python3 + + import toolbox_scs as tb + + # get entry for single data source defined in mnemonics + mnemonic = tb.mnemonics["scannerX"] + proposalNr = 2565 + runNr = 19 + + run = tb.load_run(proposalNr, runNr) + run_data = run.get_array(*mnemonic.values()) + +run is an extra_data dataCollection and run_data an xarray dataArray for a single data source. diff --git a/doc/make.bat b/doc/make.bat new file mode 100644 index 0000000000000000000000000000000000000000..27f573b87af11e2cbbd9f54eb1ee285a58550146 --- /dev/null +++ b/doc/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/notebook_examples/Knife edge scan and fluence calculation.ipynb b/notebook_examples/Knife edge scan and fluence calculation.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..158e436df86fa292b06ce883f3d3a55877e5e56b --- /dev/null +++ b/notebook_examples/Knife edge scan and fluence calculation.ipynb @@ -0,0 +1,7652 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Peak fluence calculation using knife-edge scans:\n", + "\n", + "\n", + "\n", + "For a Gaussian beam at the waist position, the intensity distribution is defined as:\n", + "\n", + "$I(x,y) = I_0 e^{\\left(-\\frac{2x^2}{w_{0,x}^2} -\\frac{2y^2}{w_{0,y}^2}\\right)}$\n", + "\n", + "with $I_0$ the peak intensity of the Gaussian beam, $w_{0,x}$ and $w_{0,y}$ the beam radii at $1/e^2$ in $x$ and $y$ axes, respectively.\n", + "\n", + "Let's consider a knife-edge \"corner\" at position $(x,y)$ that blocks the beam for $x^\\prime < x$ and $y^\\prime < y$. The detected power behind the knife-edge is given by:\n", + "\n", + "$P(x,y) = I_0 \\int_{x}^\\infty \\int_{y}^\\infty e^{\\left(-\\frac{2x^{\\prime 2}}{w_{0,x}^2} -\\frac{2y^{\\prime 2}}{w_{0,y}^2}\\right)} dx^\\prime dy^\\prime $\n", + "\n", + "Now let's consider a purely vertical knife-edge. The power in the $y$ axis is integrated from $-\\infty$ to $\\infty$, thus:\n", + "\n", + "$P(x) = I_0 \\sqrt\\frac{\\pi}{2}w_{0,y}\\int_x^\\infty e^{\\left(-\\frac{2x^{\\prime 2}}{w_{0,x}^2}\\right)}dx^\\prime$.\n", + "\n", + "Similarly, for a purely horizontal knife-edge:\n", + "\n", + "$P(y) = I_0 \\sqrt\\frac{\\pi}{2}w_{0,x}\\int_y^\\infty e^{\\left(-\\frac{2y^{\\prime 2}}{w_{0,y}^2}\\right)}dy^\\prime$\n", + "\n", + "By fitting the knife edge scans to these functions, we extract the waist in $x$ and $y$ axes.\n", + "\n", + "The total power of one pulse is then:\n", + "\n", + "$P_{TOT} = \\frac{I_0 \\pi w_{0,x} w_{0,y}}{2}$\n", + "\n", + "Hence, the peak fluence, defined as $F_0=I_0\\tau$ with $\\tau$ the pulse duration of the laser, is given as:\n", + "\n", + "$F_0 = \\frac{2 E_P}{\\pi w_{0,x} w_{0,y}}$\n", + "\n", + "where $E_P$ is the pulse energy.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "#Load ToolBox package\n", + "#!git clone https://git.xfel.eu/gitlab/SCS/ToolBox.git" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "#%cd ~/Notebooks\n", + "import numpy as np\n", + "%matplotlib notebook\n", + "import matplotlib.pyplot as plt\n", + "import matplotlib.cm as cm\n", + "import matplotlib.colors as colors\n", + "\n", + "import matplotlib as mpl\n", + "mpl.rcParams['font.size'] = 12.0\n", + "mpl.rcParams['savefig.dpi'] = 100\n", + "mpl.rcParams['figure.dpi'] = 100\n", + "\n", + "from extra_data import RunDirectory, by_index\n", + "import xarray as xr\n", + "import toolbox_scs as tb\n", + "import toolbox_scs.detectors as tbdet\n", + "from toolbox_scs.routines.knife_edge import knife_edge\n", + "\n", + "from scipy.stats import binned_statistic\n", + "from scipy.signal import find_peaks\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# X-ray beam profile and fluence" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Knife-edge measurement" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load runs with horizontal and vertical scans" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<xarray.Dataset>\n", + "Dimensions: (XGMbunchId: 1000, apdId: 400, bunchId: 1000, trainId: 613)\n", + "Coordinates:\n", + " * trainId (trainId) uint64 566589937 566589938 ... 566590549\n", + "Dimensions without coordinates: XGMbunchId, apdId, bunchId\n", + "Data variables:\n", + " sase1 (trainId, bunchId) uint64 320 324 328 332 336 ... 0 0 0 0\n", + " npulses_sase1 (trainId) int64 15 15 15 15 15 15 15 ... 15 15 15 15 15 15\n", + " sase3 (trainId, bunchId) uint64 322 338 354 370 386 ... 0 0 0 0\n", + " npulses_sase3 (trainId) int64 25 25 25 25 25 25 25 ... 25 25 25 25 25 25\n", + " MCP2apd (trainId, apdId) float64 1.898 54.88 ... 19.33 -32.31\n", + " scannerX (trainId) float64 18.5 18.5 18.5 18.5 ... 17.5 17.5 17.5\n", + " SCS_SA3 (trainId, XGMbunchId) float32 4954.09 2332.2 ... 1.0 1.0\n", + " SCS_photonFlux (trainId) float32 1.1874738 1.1874738 ... 1.1305579\n", + " SCS_XGM (trainId, XGMbunchId) float32 34.03499 4954.09 ... 1.0 1.0\n", + " XTD10_XGM (trainId, XGMbunchId) float32 1.2124572 3506.015 ... 1.0\n", + " XTD10_photonFlux (trainId) float32 2381.053 2381.053 ... 2322.0618\n", + "Attributes:\n", + " run: <extra_data.reader.DataCollection object at 0x2b87a3ec6b38>\n", + " runFolder: /gpfs/exfel/exp/SCS/201931/p900094/raw/r0687\n" + ] + } + ], + "source": [ + "proposal = 900094\n", + "fields = [\"MCP2apd\", \"scannerX\", \"SCS_SA3\", \"SCS_photonFlux\", \"SCS_XGM\", \"XTD10_XGM\", \"XTD10_photonFlux\"]\n", + "runNB = 687\n", + "runX = tb.load(fields, runNB, proposal)\n", + "\n", + "fields = [\"MCP2apd\", \"scannerY\", \"SCS_SA3\", \"SCS_photonFlux\", \"SCS_XGM\", \"XTD10_XGM\", \"XTD10_photonFlux\"]\n", + "runNB = 688\n", + "runY = tb.load(fields, runNB, proposal)\n", + "\n", + "print(runX)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Clean up and align XGM and MCP (TIM) data, normalize X-ray transmission using XGM" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "nrunX = tbdet.matchXgmTimPulseId(runX)\n", + "nrunY = tbdet.matchXgmTimPulseId(runY)\n", + "nrunX['Tr'] = -nrunX['MCP2apd'] / nrunX['SCS_SA3']\n", + "nrunY['Tr'] = -nrunY['MCP2apd'] / nrunY['SCS_SA3']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Fit scan to erfc function and plot" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fitting function: a*erfc(np.sqrt(2)*(x-x0)/w0) + b\n", + "w0 = (177.9 +/- 0.6) um\n", + "x0 = (17.953 +/- 0.000) mm\n", + "a = 6.956484e-01 +/- 5.093211e-04 \n", + "b = 3.562530e-03 +/- 7.279907e-04 \n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('<div/>');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n", + " 'ui-helper-clearfix\"/>');\n", + " var titletext = $(\n", + " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n", + " 'text-align: center; padding: 3px;\"/>');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('<div/>');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('<canvas/>');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('<canvas/>');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('<div/>');\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('<button/>');\n", + " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n", + " 'ui-button-icon-only');\n", + " button.attr('role', 'button');\n", + " button.attr('aria-disabled', 'false');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + "\n", + " var icon_img = $('<span/>');\n", + " icon_img.addClass('ui-button-icon-primary ui-icon');\n", + " icon_img.addClass(image);\n", + " icon_img.addClass('ui-corner-all');\n", + "\n", + " var tooltip_span = $('<span/>');\n", + " tooltip_span.addClass('ui-button-text');\n", + " tooltip_span.html(tooltip);\n", + "\n", + " button.append(icon_img);\n", + " button.append(tooltip_span);\n", + "\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " var fmt_picker_span = $('<span/>');\n", + "\n", + " var fmt_picker = $('<select/>');\n", + " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n", + " fmt_picker_span.append(fmt_picker);\n", + " nav_element.append(fmt_picker_span);\n", + " this.format_dropdown = fmt_picker[0];\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = $(\n", + " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n", + " fmt_picker.append(option);\n", + " }\n", + "\n", + " // Add hover states to the ui-buttons\n", + " $( \".ui-button\" ).hover(\n", + " function() { $(this).addClass(\"ui-state-hover\");},\n", + " function() { $(this).removeClass(\"ui-state-hover\");}\n", + " );\n", + "\n", + " var status_bar = $('<span class=\"mpl-message\"/>');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "}\n", + "\n", + "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n", + "}\n", + "\n", + "mpl.figure.prototype.send_message = function(type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "}\n", + "\n", + "mpl.figure.prototype.send_draw_message = function() {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n", + " }\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype.handle_resize = function(fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1]);\n", + " fig.send_message(\"refresh\", {});\n", + " };\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n", + " var x0 = msg['x0'] / mpl.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n", + " var x1 = msg['x1'] / mpl.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0, 0, fig.canvas.width / 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", + " // 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", + "\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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sbG0bduWJ554gszMzEoYfe2jvPn6/PPPqVu3Li4uLhw+fJikpCT69OnDbbfdRnR0dLnnXbBgAYZhEBsbW+Kxxx57jI8//riyXkKtoarmqixGjhyJYRikp6df58hrJ1U9X1OmTOHBBx8kKytLhbeKUOFVqpWrEahu3brRoEGDCsmPk5MThmFw33338dprr7Fw4ULc3d156KGH+Pvf/67/yF8jVTVfALGxsTRp0qTIYrdXXnml4CtE5eopb75OnjzJu+++W+T9vv/++yv0H7KjoyOGYZCamlrisZYtW/L6669XxvBrFVU1V6Vx+vRpHnzwQdq0aXOdo669VOV8HT9+nDvvvBNPT08AFd4qQoVXqVYqKlBZWVnceuut/Oc//6nQee3s7Ar+kcnOzi7YHxMTg2EYjBo16nqGXWupqvkC2L9/P926dWP48OGsXLmSqVOnct999/HWW2+Rk5NznSOvnZQ3X9nZ2fTp04dvvvmGgIAA5syZw4svvkjDhg05cOBAuec1/X6dPHmyxGNt2rShefPmlfUSag1VNVfFuXTpEp06daJ+/frEx8dX0uhrH1U5X19//TXNmzfn0qVLgApvVaHCq1QrFRWoOXPmYBgGy5Ytq9B5TRGonj17lnjsiSeeoF27dtcy3FpPVc3XmTNneOihh5g6dWqR/Rs3bsQwDNzd3a91yLWa8uarU6dOdOnSpci+06dPc++99/LZZ5+Ve16N8FY+VTVXxenTpw+GYeDr63s9w631VNV8xcTEUKdOHSIjIwv2qfBWDSq8SrVSUYF69913ufvuuyu88GzhwoUYhsHw4cNLPNaqVStatGhxLcOt9VTVfPn4+GAYBvv37y/x2F133UWPHj2uZbi1nrLmKyUlpSDHvTgfffQRjz76aLnn1Rzeyqeq5sqcsWPHYhgGkyZNut7h1nqqar7atGnD22+/zeHDhws20w1mUFAQR48ercyXUatR4VWqlYoIVHp6Orfccgvfffddhc+bnJyMYRh89dVXJR5r1KgR77333rUMt9ZTVfPl4OCAYRglylnl5+dz++23X/NK9NpOWfMVHR1dZvWLDz74gIceeqjc8yYkJJRbpcHOzu66x17bqKq5MuHq6ophGAwaNKgyhlvrqar5aty4cblNfO6+++7KfBm1GhVepVqpiECZFqBFRESU+nheXh5JSUklFqI1b96cu+66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\" width=\"700\">" + ], + "text/plain": [ + "<IPython.core.display.HTML object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fitting function: a*erfc(-np.sqrt(2)*(x-x0)/w0) + b\n", + "w0 = (114.6 +/- 0.5) um\n", + "x0 = (13.328 +/- 0.000) mm\n", + "a = 6.919488e-01 +/- 4.776092e-04 \n", + "b = 1.138866e-03 +/- 6.013901e-04 \n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('<div/>');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n", + " 'ui-helper-clearfix\"/>');\n", + " var titletext = $(\n", + " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n", + " 'text-align: center; padding: 3px;\"/>');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('<div/>');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('<canvas/>');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('<canvas/>');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('<div/>');\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('<button/>');\n", + " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n", + " 'ui-button-icon-only');\n", + " button.attr('role', 'button');\n", + " button.attr('aria-disabled', 'false');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + "\n", + " var icon_img = $('<span/>');\n", + " icon_img.addClass('ui-button-icon-primary ui-icon');\n", + " icon_img.addClass(image);\n", + " icon_img.addClass('ui-corner-all');\n", + "\n", + " var tooltip_span = $('<span/>');\n", + " tooltip_span.addClass('ui-button-text');\n", + " tooltip_span.html(tooltip);\n", + "\n", + " button.append(icon_img);\n", + " button.append(tooltip_span);\n", + "\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " var fmt_picker_span = $('<span/>');\n", + "\n", + " var fmt_picker = $('<select/>');\n", + " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n", + " fmt_picker_span.append(fmt_picker);\n", + " nav_element.append(fmt_picker_span);\n", + " this.format_dropdown = fmt_picker[0];\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = $(\n", + " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n", + " fmt_picker.append(option);\n", + " }\n", + "\n", + " // Add hover states to the ui-buttons\n", + " $( \".ui-button\" ).hover(\n", + " function() { $(this).addClass(\"ui-state-hover\");},\n", + " function() { $(this).removeClass(\"ui-state-hover\");}\n", + " );\n", + "\n", + " var status_bar = $('<span class=\"mpl-message\"/>');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "}\n", + "\n", + "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n", + "}\n", + "\n", + "mpl.figure.prototype.send_message = function(type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "}\n", + "\n", + "mpl.figure.prototype.send_draw_message = function() {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n", + " }\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype.handle_resize = function(fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1]);\n", + " fig.send_message(\"refresh\", {});\n", + " };\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n", + " var x0 = msg['x0'] / mpl.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n", + " var x1 = msg['x1'] / mpl.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0, 0, fig.canvas.width / 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", + " // 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", + "\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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Dg7O9v569OiBppnOoq1SpYrFJ80zZ86gaRqTJk3K9v5yE2vZ7o8//kDTNAYOHJip8qdOnaJYsWIWZ4XnJTJjv82bN7Nu3TomTpxInTp1MjUGcN68eWn2cnTu3BlnZ2fD90f13IPcs58l9P/t2rVrMyx78+ZNXFxceO6557K1L2tgTdtB/rrugfXsVxCvfbNnz6ZYsWIG0ZoVwauP97127ZrZb40aNaJWrVqG74UKFaJ3795m5SIiItA0jRUrVmShRfkPEbz5kMyKtsWLF2NnZ2cy/jE7nDhxwmws0aPa02Et2w0fPhxN0zh48GCm1+nYsSP29vZmbqTyElntIT99+jSOjo5MmzYt3XLSw2uZzNovNePGjTP7z2bEN998g6ZpXLx4MUv7shbWsp1OfrrugfXsV9CufXFxcbi4uDB8+HBDnvTw2gYRvPmQzFy4wsPDsbe35/3338/xxIB///3X7In9UR3LZi3bVatWLcu9ZV5eXmiaZjYhJi+R1ZsmQP369U0u2paQMbxpkxn7GTNnzhzs7OzMXBplRFBQEJqmceTIkSytZy2sYTtj8tN1D6xnv4J27fv+++957LHHOHr0KDExMcTExLBjxw40TeO7774jJiYm3YmhMob34SGCNx+S0YVr7969FC9enAYNGvDff//leH9RUVFomsbo0aMNeZ6enhZnK+vDAPLqbGVr2G7v3r1omoaPj0+W1mvXrh2Ojo5m497yEtm5adauXduiSDDm1q1b6XppMO7VeFTPPcg9++msXLmSwoUL065duyyfR4MGDULTNC5fvpyl9axFbtsuNfnpugfWsV9BvPZ16dLFMO45rRQZGZnmdqOjo9G0tL00GNvyo48+suiloUePHuKlARG8+ZL0LlzHjh2jTJky1KhRg7///jvd7Rw/fpzz588bvsfFxZn9YR48eECHDh3QNM0kmot+YTN+ZZOQkEC1atV47bXXstmy3Ce3bGdMv3790DSN06dPW/z9+vXrZnm//fYbRYsWpXXr1hk3woakZb/ExESLNtu3bx+FCxemc+fOJvmW7Ne8eXMqVKjA7du3DXl6z8X69esNeY/quQe5a79t27bh6OjIW2+9le6Nz9L5d+nSJR577DFq1qyZhdZYl9yyXUG47kHunns6BfHad+jQIVasWGGSQkND0TSNrl27smLFCm7dugWoKGzHjx83e6h8/vnnqVWrlsmQjmHDhmFnZ8exY8cMeYsXL0bTTP3w3rhxg9KlS9OhQ4dcaPWjhQjefMS0adPw9fWld+/eaJrGhx9+iK+vL76+vty6dYvbt29TuXJlChUqxNixY80i2Ri7JgLQNA03NzfD9y1btlC+fHkGDhxIUFAQEyZMoGHDhmiaRs+ePc3q4+7ubuiVCw0NpUGDBhQpUoRt27bltimyTG7bTicpKQkXF5d0XwO+9dZbtGzZ0hDRbcCAATg5OeHs7GxycctLZGS/2NhYw/iyiRMnEhISQp8+fXBycuLxxx83iwJkyX6HDh3CwcHBJNKao6MjzZo1M6vPo3TuQe7b79y5czg7O1OsWDGCgoLMzl/jYQpdu3alUaNGjBgxgrCwML777jvKlCmDvb09W7ZssZJFMk9u2y4/X/fAOv9dKLjXPkukNYZXz+/SpYtJ/po1a7Czs6NJkyaEhYXRr18/ChUqRI8ePUzKJSUl8frrr1OiRAlGjhxJUFAQNWrUoGTJkpw4ceKhtvtRRARvPsLV1TXNVyb62KH0Xquk/pOlvnCdPXsWd3d3nn76aRwdHXFycuKVV14hJCTEYmjd+Ph4PD09KV++PA4ODtStWzfPDprPbdvpbNiwAU1LP1DFlClTqFevHo8//jhFihShQoUKfPrppybRsPIaGdnv7t279O/fn5o1a1KqVCmKFi2Kq6sr3bt3JyYmxmx7adlvx44dNGjQAEdHR5544gn69Olj0uOr8yide5D79tP9m6aVvL29DWUXLlzIm2++yRNPPEGRIkUoW7Ysbdu2NenJzEvktu3y83UPrPffLajXPktkVfACrFixgtq1a+Pg4EClSpUs+oEG+Pvvv+nevTtlypTByckJNze3R8KPsTUQwSsIgiAIgiDka0TwCoIgCIIgCPkaEbyCIAiCIAhCvkYEryAIgiAIgpCvEcErCIIgCIIg5GtE8AqCIAiCIAj5GhG8giAIgiAIQr5GBK8gCIIgCIKQrxHBKwiCIAiCIORrRPAKgiAIgiAI+RoRvIIgCEKaeHt7o2mZu1XMmTMn3ZCquUXq0N9Lly616v4zwtnZ2VC3Pn362Lo6glAgEcErCIJgBTw8PChatChRUVFmvyUmJvLSSy/h6urKP//8Y4PapY0lwevn58eKFSvMytpa8Pbs2ZP58+dz/vx5q+4/I5YsWcL8+fNF8AqCDRHBKwiCYAViY2MpX748DRs25MGDBya/jRs3Dk3TWLt2rY1qlzaJiYnEx8eb5BUvXpwuXbqYlU1KSiI+Pt6sfbmNLnjnzJlj1f1mFRG8gmA7RPAKgiDkMvHx8dy/f58lS5agaRqhoaGG386fP0/x4sVp3769DWuYNdISvLZCBK8gCBkhglcQhFzn9u3b9O/fH1dXV+zt7XniiSdo2rQphw4dMim3d+9eWrRoQenSpXFycuKll15i8uTJht+PHDlCly5deOaZZ3BwcMDFxYVu3brx119/mWxHfw1/6tQpunTpgrOzM6VKlaJr1678+++/JmV1EbJixQpq1KiBvb091atXZ/369WbtuHTpEt26daNcuXKGcrNmzTIps2XLFjRNY9GiRQwdOpSKFStiZ2dHbGwsAC1btuSxxx7j2rVrALRu3ZrSpUtz5cqVDO2o13XBggX873//w8HBgZdffplt27aZlT18+DDNmzenZMmSFC9enCZNmrBnzx6TMvfu3WPEiBFUq1YNBwcHHn/8cRo2bEh4eLiZLY3rkDrp4jetIQ1BQUFUr14de3t7KlSowJdffmmwh46bmxs1atTg6NGjNG7cmGLFilGxYkX8/f0ztEt6glev/x9//MEnn3xCqVKlKFu2LMOGDePBgwdcuHCB1q1bU7JkSVxcXJgwYYLJ+vrxXLJkCSNGjKBixYqUKFGCdu3acevWLRISEujfvz9PPPEExYsXp2vXriQkJFispwheQbAdIngFQch1Pv74Y+zt7fn666+ZOXMm/v7+tGrVigULFhjKhIeHY29vj6urK97e3kyfPp1+/frRtGlTQ5kJEybQqFEjfHx8CAsLo3///hQrVox69eqZvEbXRU6dOnX48MMPCQ4O5osvvkDTNAYPHmxSN03TqFWrFhUqVMDX15fJkydTpUoVnJycTIT01atXqVSpEpUrV8bHx4fp06fTunVrNE1j0qRJhnK6QKpevTq1a9cmICCAMWPGGIT2uXPnKF68OB9//DErV65E0zRCQkIyZUdN03jxxRcpW7YsPj4++Pv74+rqSrFixUzGBkdHR1O8eHFDm8aOHWt4SNi7d6+h3HfffYednR09evRgxowZTJw4kU6dOjF27FgzW+rMnz8fBwcHGjVqxPz585k/fz67d+8GLAteff2mTZsybdo0vvrqKwoXLkzdunW5d++eoZyb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\" width=\"700\">" + ], + "text/plain": [ + "<IPython.core.display.HTML object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.00017787613670375985 0.00011464211799492675\n", + "X-FWHM [um]: 209.43314612133952\n", + "Y-FWHM [um]: 134.9807787296284\n" + ] + } + ], + "source": [ + "w0_x = knife_edge(nrunX, axisKey='scannerX', signalKey='Tr', plot=True)[0]*1e-3\n", + "w0_y = knife_edge(nrunY, axisKey='scannerY', signalKey='Tr', plot=True)[0]*1e-3\n", + "print(w0_x, w0_y)\n", + "\n", + "print('X-FWHM [um]:', w0_x * np.sqrt(2*np.log(2))*1e6)\n", + "print('Y-FWHM [um]:', w0_y * np.sqrt(2*np.log(2))*1e6)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Fluence calculation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load run of interest, clean up XGM data" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "proposal = 900094\n", + "fields = [\"SCS_SA3\", \"SCS_XGM\", \"SCS_photonFlux\", \"XTD10_XGM\", \"XTD10_photonFlux\"]\n", + "runNB = 647\n", + "run = tb.load(fields, runNB, proposal)\n", + "nrun = tbdet.matchXgmTimPulseId(run)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Calibrate XGM fast data using photon flux and plot" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8.341872\n", + "Pulse energy [J]: 4.498510461663136e-05\n", + "Fluence [mJ/cm^2]: 140.43875422560828\n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('<div/>');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n", + " 'ui-helper-clearfix\"/>');\n", + " var titletext = $(\n", + " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n", + " 'text-align: center; padding: 3px;\"/>');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('<div/>');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('<canvas/>');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('<canvas/>');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('<div/>');\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('<button/>');\n", + " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n", + " 'ui-button-icon-only');\n", + " button.attr('role', 'button');\n", + " button.attr('aria-disabled', 'false');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + "\n", + " var icon_img = $('<span/>');\n", + " icon_img.addClass('ui-button-icon-primary ui-icon');\n", + " icon_img.addClass(image);\n", + " icon_img.addClass('ui-corner-all');\n", + "\n", + " var tooltip_span = $('<span/>');\n", + " tooltip_span.addClass('ui-button-text');\n", + " tooltip_span.html(tooltip);\n", + "\n", + " button.append(icon_img);\n", + " button.append(tooltip_span);\n", + "\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " var fmt_picker_span = $('<span/>');\n", + "\n", + " var fmt_picker = $('<select/>');\n", + " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n", + " fmt_picker_span.append(fmt_picker);\n", + " nav_element.append(fmt_picker_span);\n", + " this.format_dropdown = fmt_picker[0];\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = $(\n", + " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n", + " fmt_picker.append(option);\n", + " }\n", + "\n", + " // Add hover states to the ui-buttons\n", + " $( \".ui-button\" ).hover(\n", + " function() { $(this).addClass(\"ui-state-hover\");},\n", + " function() { $(this).removeClass(\"ui-state-hover\");}\n", + " );\n", + "\n", + " var status_bar = $('<span class=\"mpl-message\"/>');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "}\n", + "\n", + "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n", + "}\n", + "\n", + "mpl.figure.prototype.send_message = function(type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "}\n", + "\n", + "mpl.figure.prototype.send_draw_message = function() {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n", + " }\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype.handle_resize = function(fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1]);\n", + " fig.send_message(\"refresh\", {});\n", + " };\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n", + " var x0 = msg['x0'] / mpl.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n", + " var x1 = msg['x1'] / mpl.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0, 0, fig.canvas.width / 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", + " // 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", + "\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4nOzdfVxUdf7///cMF8OAqSMoopIKXsaSpaVpmYqueJFaGdWKXZuJrlkbGJsZmkkf1i7J1pDKzdJq65ZdbLcu9LuGqJu2bW0prq4tIaSt5iq4CgrD8/dHy/k5zgUzODPn/T7neb/dzs2dw+G8zsxxO48mziBARERERKYi9D4AIiIiIgovBiARERGRyTAAiYiIiEyGAUhERERkMgxAIiIiIpNhABIRERGZDAOQiIiIyGQYgEREREQmwwAkIiIiMhkGIBEREZHJMACJiIiITIYBSERERGQyDEAiIiIik2EAEhEREZkMA5CIiIjIZBiARERERCbDACQiIiIyGQYgERERkckwAImIiIhMhgFIRETSKywsxJAhQ9CuXTt06dIFWVlZqKys1PuwiJTFACQiIullZmbiD3/4A3bv3o2//e1vGDt2LAYMGIDGxka9D41ISQxAItJFZWUlhBC47bbb9D4U6axZswZCCG256aab9D4k6fzrX/+CEAJ///vftXV79uxxed169uyp3wESSY4BSERB0xJ1vpZjx465bMsAdNcSgNOmTUNBQQHeeuutkM0SQqB///5ev/7FF19ACIHnnnsuZMfQFl999RWEEKiurtbWHTlyBAUFBSgoKECHDh0YgEQ+MACJKGhaoi41NVW7EJ+71NfXu2zLAHTXEoBr1qwJ+azWAvDhhx+GEAIHDhwI+bH4q6mpCWPHjsWkSZO8btOzZ08GIJEPDEAiCpqWqMvMzPR7WwagO5kCMD09HYMHDw75cfirubkZs2bNQt++fXH48GGv2zEAiXxjABJR0JxvAPoKn82bN0MIgYKCArevlZWV4ZprrkF8fDyio6PRp08fLFq0CCdPnvS6jy+++ALjxo1Du3bt0L59e1x77bU+7yotKyvDtGnT0KVLF0RHR6NHjx647rrrUF5e3ubj8cbf12Hbtm0YPXo02rVrh4SEBOTk5ODUqVMAgD/96U+44oorEBsbiy5duiAvL8/jDRO+ArDl5+yWLl0a8OsR7OMEfo6/OXPmoFevXq2+I8kAJPKNAUhEQaNHAP7+97+HxWKBw+HArbfeitzcXIwePRpCCIwYMQKnT59228ekSZNgt9sxadIkPPDAA8jIyND+03XLf6I+2zPPPAOLxYLY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2O12VFVVaes2btzodmGqqalBVFQU5s2bp61rbm7GyJEj0aNHDzQ1NYXuyZjYtm3b3C78+/btg81mQ3Z2traO51E9TU1NGDRoEPr376+t43lUy0033YSMjAyMGjXKLQAnTpyIpKQk1NbWautKS0shhMAnn3yirduxYweEEFixYoW2rr6+HqmpqRg+fHjon4TBMACJzuIrALt06YKsrCy39f369cPYsWO1x88//zyEENi9e7fLduvXr4cQgv+mGmaDBw/G4MGDtcc8j2q65pprkJiYqD3meVRHWVkZIiIi8M0337gFYG1tLSIjI5GXl+fyPadPn0a7du1w1113aevy8vIQERHhEooAUFhYCCEEDhw4ENonYjAMQKKzeAvAmpoaCCFQVFTk9j0zZ85Ep06dtMezZs1CXFwcmpubXbbbv38/hBAoLi4OybGTu+bmZnTv3h3jx48HwPOokv/+9784cuQI9u/fj6eeegoRERGYMWMGAJ5HlTQ1NeHiiy/GPffcAwBuAbh161YIIfDmm2+6fe9VV13l8i9v48aNw8CBA92227RpE4QQHn9OlLxjABKdxVsAtqxfu3at2/fk5eVBCIGGhgYAwOTJk5GSkuK23cmTJyGEQH5+fkiOndy9+uqrEELgpZdeAsDzqJJ77rkHQggIIWC1WnHDDTfgP//5DwCeR5WsXLkSHTp00G7OOTcA33rrLQghsGXLFrfvzcrKQteuXbXHaWlpyMjIcNtu9+7dEELghRdeCMEzMC4GINFZvAXgli1bvP5b6uLFiyGEwLFjxwAAGRkZHv8t1el0QgiBBQsWhOTYydWePXvQvn17DB8+XPs5L55HdezZswcbN27EK6+8gsmTJ+O6667Djz/+CIDnURU//fQTOnXqhCeeeEJbd24Arl27FkII7Nixw+37b7nlFnTo0EF7nJKSgokTJ7pt991330EIgaeffjrIz8DYGIBEZ+E7gMZw6NAhpKSkIDk5GT/88IO2nudRXb/85S9x+eWXo7m5medREXPmzEGfPn1cbs7iO4DyYAASnSVYPwMYGxvLnznSyfHjx3HJJZegU6dObj/4z/OorpKSEggh8I9//IPnUQH79u2D1WpFcXExKisrtWXYsGHo168fKisrcfToUf4MoI4YgERn8XUXcOfOnb3edXj2v5WuXLnS412H69at8/pvuhQc9fX1GDly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QgiP+z5by528VVVVLutfeeUVCCG0j4P7y1/+AovFgj//+c9us/292eOKK65Aamqqz20YgAbHADSJYAZgsP6hzAAkkpJZAvDsWGpqasIVV1yBbt264cSJEy7bewvAHj16eAzAcyOsJQA3b97s87j69u0LIQQaGhpc1n/00UcQQuDdd98FAIwcORJXX301KisrtWXFihXar4w9NyA9ycrKgsPh8LkNA9DgGICKO9+wYwAS0TnMGIDA/x9qjz/+uMt6h8OBBQsWuKw7ffo0IiIighqAN998M4QQ+O6771zWv/TSSxBCYNu2bQB+fufR24c7CyHQoUOHVl+DIUOGoF+/fj63YQAaHANQcQxAIgoyswYgAAwdOhSJiYkuz/2yyy7DpZde6rLdc889ByFEUANww4YNEELgoYce0tY5nU5cddVV6NSpk/bO4CeffIINGza4LPPnz4cQAk888QT+9Kc/ad/v6eNnPvzwQwghWv28QQagwTEAFccAJKIgM3MAvvXWW24fBfPCCy9ACIHrr78eq1atwpw5c9C7d28kJCQENQCbm5sxduxYWCwWzJ49G88//zx++ctfQgih3e0b6HPq06cPsrKyUFRUhBdeeAGzZ89GZGQkkpOT8eOPP/rcJwPQ4BiAimMAElGQmTkAnU4nUlNTkZqaqn1ostPpxIMPPqh9sHNmZib279/v9SaQtgYg8POHPy9YsABdu3ZFdHQ00tPT8dprr7X5OS1atAiXXHIJOnTogKioKFx44YXIyclpNf4ABqDhMQAVxwAkoiAz+u8CJv8wAA2OAag4BiARBRkDkAAGoOExABXHACSiIGMAEsAANDwGoOJkDsDWtmMAEkmJAUgAA9DwGICKUzkA6+qA2tqf/yQiaTAACWAAGh4DUHEqByARSYkBSAAD0PAYgIpjABJRkDEACWAAGh4DUHEMQCIKMgYgAQxAw2MAKk7lAHzySaCg4Oc/iUgaLRf+U6dO6X0opKNTp04xAI2MASgxPd6NC+dM3gVMJKWmpibs2bMHR44c0ftQSEdHjhzBnj17tN+Ici4GoOIYgBJjABKRTg4ePIiKigrU1NSgrq4Op06dQn19PReDL6dOnUJdXR1qampQUVGBgwcPev07wgBUHANQYgxAItJJc3Mzjh07hr1796KiooKLyZa9e/fi2LFjaG5u9vp3hAGoOAagxBiARKSz5uZmNDY26v7OFJfwLY2NjT7DrwUDUHEMQIkxAImISFIMQMUxACXGACQiIkkxABXHAJQYA5CIiCTFAFQcA1BiDEAiIpIUA1BxDECJMQCJiEhSDEDFMQAlZvQAnDIFuOKKn/8kIiKlMAAVxwCUmNEDMJB9ERGRVBiAimMASowBSEREkmIAKo4BKDEGIBERSYoBqDgGoMQYgEREJCkGoOIYgBIzegBOmQL0EcBgBiARkWoYgIpjAErM6AHY8jEwDgYgEZFqGICKYwBKjAFIRESSYgAqjgEoMQYgERFJigGoOAagxBiAREQkKQag4hiAEmMAEhGRpBiAimMASowBSEREkmIAKo4BKDEGIBERSYoBqDgGoMQYgEREJCkGoOIYgBJjABIRkaQYgIpjAErM6AH45JPA9QLIZgASEamGAag4BqDEjB6AgeyLiIikwgBUHANQYgxAIiKSFANQcQxAiTEAiYhIUgxAxTEAJWb0AKyrA0oF8GIQZxIRUVgwABXHAJSY0QMwkLuAGYBERFJhAJ7lsccegxACaWlpbl/btm0brrzyStjtdiQmJmL+/Pk4ceKE23YNDQ1YuHAhkpKSEBMTg6FDh+LTTz/1OM/fffrCAJQYAzDwmUREFBYMwP+prq5GbGws4uLi3ALwq6++QkxMDC699FKsWrUKixYtgs1mw4QJE9z2c/PNNyMyMhK5ubkoKSnB8OHDERkZifLy8jbvs7XjZgBKigEY+EwiIgoLBuD/3HTTTcjIyMCoUaPcAnDixIlISkpCbW2ttq60tBRCCHzyySfauh07dkAIgRUrVmjr6uvrkZqaiuHDh7dpn61hAEqMARj4TCIiCgsGIICysjJERETgm2++cQvA2tpaREZGIi8vz+V7Tp8+jXbt2uGuu+7S1uXl5SEiIsIl6gCgsLAQQggcOHAg4H22hgGoAxljTI+ZDEAiImWZPgCbmppw8cUX45577gEAtwDcunUrhBB488033b73qquuwuDBg7XH48aNw8CBA92227RpE4QQeP/99wPeZ2sYgDqQMcb0mMkAJCJSlukDcOXKlejQoQMOHz4MwD0A33rrLQghsGXLFrfvzcrKQteuXbXHaWlpyMjIcNtu9+7dEELghRdeCHif52poaEBtba22VFRUMADDTcYY02MmA5CISFmmDsCffvoJnTp1whNPPKGtOzcA165dCyEEduzY4fb9t9xyCzp06KA9TklJwcSJE922++677yCEwNNPPx3wPs9VUFAAIYTbwgAMIxljTI+ZDEAiImWZOgDnzJmDPn364PTp09o6vgNIrZIxxvSYyQAkIlKWaQNw3759sFqtKC4uRmVlpbYMGzYM/fr1Q2VlJY4ePcqfASR3MsaYHjMZgICbozkAACAASURBVEREyjJtAG7evNnjf0o9e1mwYAGOHz/u847dO++8U1uXm5vr8S7g5cuXu9wFHMg+W8MA1IGMMabHzL/+FVgigMcYgEREqjFtAB45cgQbNmxwW9LS0nDhhRdiw4YN+OabbwAAEyZMQFJSEurq6rTvf/HFFyGEwEcffaSt+/zzz90+B7ChoQF9+vTBsGHDXOb7u8/WMAB1IGOM6TUz2MdPRERhoXQANjQ04MyZM0Hdp6cPgv7yyy9hs9lcfmtHTEwMxo8f7/b9WVlZ2rt7JSUlGDFiBCIjI1FWVtbmffrCANSBrDGmx0wGIBGRkqQPwLKyMixevBjHjh3T1v3000+YMGECIiMjYbfb8eCDDwZtnqcABIDy8nKMGDECMTEx6Ny5M+bNm+fy7l2L+vp65ObmomvXrrDZbLj88svx8ccfe5zl7z59YQDqQNYY02MmA5CISEnSB+CUKVOQmprqsu62226DxWJB3759kZSUBKvV6vGGCjNgAOpA1hgL98wPPgDuFcADDEAiItVIH4A9evTAbbfdpj2ur6+H3W5HZmYmAKCurg69evXC6NGjQzFeegxAHcgYY3rM5F3ARETKkj4A7XY7HnroIe3xn//8Z1gsFrzxxhvaul//+tdISkoKxXjpMQB1IGOM6TGTAUhEpCzpA7BTp06YP3++9njx4sWwWq04dOiQti4/Px8xMTGhGC89BqAOZIwxPWYyAImIlCV9AA4dOhR9+/ZFQ0MDTp8+jb59++IXv/iFyzYzZszAhRdeGIrx0mMA6kDGGNNjJgOQiEhZ0gdgaWkpLBYLevTogZSUFFitVjz55JMu2/Tv3x8TJkwIxXjpMQB1IGOM6TGTAUhEpCzpA7C5uRkLFy5EfHw84uPjMW/ePDidTu3r27dvh8VicfnwZTNhAOpAxhjTYyYDkIhIWdIHYGtOnz6N48ePo7GxUY/xumMA6kDGGNNjJgOQiEhZygeg2TEAdSBjjOkxkwFIRKQsZQLwnXfeQVZWFtLT010+GHrPnj0oKipCTU1NKMdLiwGoAxljTI+ZDEAiImVJH4BOpxM33ngjrFYrrFYr4uLiYLVata//+OOPiIyMRGFhYSjGS48BqAMZY0yPmf37AzECSGIAEhGpRvoAfOKJJ2CxWJCTk4Pa2loUFBS4BCAAjBkzBldeeWUoxkuPAagDGWNMr5nBPn4iIgoL6QPwF7/4BYYOHao9XrJkiVsA3n333ejWrVsoxkuPAagDWWNMj5kMQCIiJUkfgDExMXjggQe0x54CMD8/HzabLRTjpccA1IGsMabHTAYgEZGSpA9Ah8OBWbNmaY89BeCvfvUrJCYmhmK89BiAOpA1xvSYyQAkIlKS9AGYkZGB5ORk1NfXA3APwKNHj8LhcGDatGmhGC89BqAOZI2xcM/MzQVGC2CyDs+TiIjOi/QB+O6778JisWDSpEmorq52CcD9+/fj6quvhtVqxf/7f/8vFOOlxwDUgYwxpsfMUHwMDAOQiCgspA9A4Oef8bNYLLBarbjgggtgtVrRuXNnWK1WWCwWPPLII6EaLT0GoA5kjDE9ZjIAiYiUpUQAAsCnn36KqVOnIjExEVFRUYiPj8ekSZPw8ccfh3Ks9BiAOpAxxvSYyQAkIlKWMgFInjEAdSBjjOkxkwFIRKQsBqDiGIA6kDHG9JjJACQiUpb0AfjNN9/gpZdeQm1trbbu1KlTmDNnDrp164aUlBSsWrUqFKOVwADUgYwxpsdMBiARkbKkD8Abb7wR3bp1Q3Nzs7buvvvug8ViwQUXXIDo6GhYrVZ8+umnoRgvPQagDmSMMT1mMgCJiJQlfQD26tUL2dnZ2uPGxkZ06NABw4YNQ319PX744QckJiZi8uTJoRgvPQagDmSMMT1mMgCJiJQlfQDGxcUhPz9fe7x9+3ZYLBasWbNGWzd79mz06NEjFOOlxwDUgYwxpsdMBiARkbKkD8AOHTrg/vvv1x4XFhbCarXi+++/19b99re/RUxMTCjGS48BqAMZY0yPmbNnA0MFkMEAJCJSjfQBOGjQIFxyySXa40svvRSpqaku29x6663o3r17KMZLjwGoAxljTK+Z4Tp+BiARUVBJH4BPPPEELBYLhg4dipEjR8JqtWLx4sUu21xyySUYPXp0KMZLjwGoA1ljTI+ZDEAiIiVJH4ANDQ248cYbtV/7NnnyZNTX12tf37VrFywWCx599NFQjJceA1AHssaYHjMZgERESpI+AFvU1tairq7Obf2RI0fw9ddf4/jx46EcLy0GoA5kjTE9ZjIAiYiUpEwAkmcMQB3IGmPhnjlkyM93APdmABIRqYYBqDgGoA5kjDE9ZvJjYIiIlCVdAPbu3btNS0pKSjDGK4cBqAMZY0yPmQxAIiJlSReAPXv2RK9evdq0mBEDUAcyxpgeMxmARETKki4AKTAMQB3IGGN6zGQAEhEpiwGoOAagDmSMMT1mMgCJiJTFAFQcA1AHMsaYHjP1CkBGIhHReZM+AJcuXerXwg+CZgCGjYwxpsdMBiARkbKkD0CLxeJzafkNIVarNRTjpccA1IGMMabHTAYgEZGypA/Azz77zOPy3nvvoaCgAA6HA1lZWfjss89CMV56DEAdyBhjesxkABIRKUv6AGzNvn370K5dO7zxxht6jNcdA1AHMsaYHjPXrQNmCWAuA5CISDXKByAA3HLLLbjkkkv0Gq8rBmAQqRxjes0M1/EzAImIgsoQAfjAAw/AbrfrNV5XDMAgUj3G9JjJACQiUpLyAdjQ0IC0tDQkJSXpMV53DMAgUj3G9JjJACQiUpL0AfjKK694XF566SU8+uijuOiii2C1WnHfffeFYrz0GIBBpHqMhXvmP/4BFAlgBQOQiEg10gdgy0e8nLuc/TEw2dnZaGhoCMV46TEAg0jlGNNjJu8CJiJSlvQB+Ic//MHjsnbtWnzwwQc4ePBgKMYqgwEYRCrHmB4zGYBERMqSPgDJNwZgEKkcY3rMZAASESmLAag4BmAQqRxjesxkABIRKUuZAHznnXcwdepUJCcno3379khOTsa0adOwYcOGUI6VHgMwiFSOMT1mMgCJiJQlfQA2NjYiKytLu/EjKioKXbt2RVRUlHYTSFZWFhobG0MxXnoMwCBSOcb0mMkAJCJSlvQB+Oijj8JisWDUqFHYunUrnE4nAMDpdKK8vBxXX301rFYrli1bFvC+d+3ahRtuuAG9e/eG3W5HfHw8Ro4ciffff99t24qKCmRmZiIuLg4OhwMzZ87E4cOH3bZzOp0oKipCr169YLPZkJ6ejvXr13uc7+8+fWEABpHKMabHTAYgEZGypA/A3r17Y+DAgV7f4Ttz5gwGDBiA3r17B7zvDz/8EJmZmViyZAlWr16NZ555BiNHjoQQAiUlJdp21dXVSEhIQGpqKp599lksX74cDocDgwYNwunTp132mZ+fDyEE7r77bqxevRqTJ0+GEAKvv/66y3aB7NMXBmAQqRxjesxkABIRKUv6AIyJicHChQt9bpOXl4eYmJigzGtqasKgQYPQv39/bV1OTg7sdjuqqqq0dRs3bnQLxZqaGkRFRWHevHnauubmZowcORI9evRAU1NTwPtsDQMwiFSOMT1mMgCJiJQlfQD27dsXc+fO9bnN3Llz0a9fv6DNvOaaa5CYmKg97tKlC7Kysty269evH8aOHas9fv755yGEwO7du122W79+PYQQKC8vD3ifrWEABpHKMabHTAYgEZGypA/AoqIiJCQkeP3A55qaGsTHx+N3v/tdm2f897//xZEjR7B//3489dRTiIiIwIwZM7T9CyFQVFTk9n0zZ85Ep06dtMezZs1CXFwcmpubXbbbv38/hBAoLi4OeJ+tYQAGkcoxpsfMgweBYgGsZAASEalG+gCsrKzE1KlTkZiYiMcffxzl5eXYt28fysvLUVhYiMTEREybNg2VlZWoqqpyWfx1zz33QAgBIQSsVituuOEG/Oc//wEAfPHFFxBCYO3atW7fl5eXByGE9mvoJk+ejJSUFLftTp48CSEE8vPzA97nuRoaGlBbW6stFRUVDMBgUTnG9JoZruNnABIRBZX0AdjyUS++fiewp/URERF+z9izZw82btyIV155BZMnT8Z1112HH3/8EQCwZcsWCCHw5ptvun3f4sWLIYTAsWPHAAAZGRkYOHCg23ZOpxNCCCxYsCDgfZ6roKBAi9WzFwZgEKgeY3rMlDkAGYpERF5JH4C33XYbbr/99jYtbfXLX/4Sl19+OZqbm/kOoJmoHmN6zGQAEhEpSfoA1ENJSQmEEPjHP/4R8M8AxsbG8mcAVaV6jIV7ZkkJkC2AuxiARESqYQB68Mwzz0AIgR07dgAAOnfu7PWO3YyMDO3xypUrPd4FvG7dOgghsGXLFm2dv/tsDQMwiFSOMT1myn4XMAOQiMgrUwfgv//9b7d1Z86cweDBg2G323HixAkAwJw5c2C323HgwAFtu02bNkEIgVWrVmnrqqurvX4OYPfu3V0+B9DffbaGARhEKseYHjMZgEREyjJ1AF577bXIyMjAkiVLUFpaimXLlmHAgAEQQuDJJ5/Utjtw4ADi4+ORmpqK4uJiFBYWwuFwID093e1n9Vp+hm/27NkoLS3VfhPIunXrXLYLZJ++MACDSOUY02MmA5CISFmmDsDXX38d48aNQ2JiIiIjI+FwODBu3Di89957btvu2rUL48ePR2xsLDp27Ijs7GztTuGzOZ1OFBYWomfPnoiOjkZaWhpee+01j/P93acvDMAgUjnG9JjJACQiUpapA9AIGIBBpHKM6TGTAUhEpCwGoOIYgEGkcozpMZMBSESkLOkC8LrrrnP5gOSysrKAfquH2TAAg0jlGNNjJgOQiEhZ0gWgxWLB0qVLtcdWq9XlMbliAAaRyjGmx0wGIBGRsqQLQIfDgQceeEB7fG4QkisGYBCpHGN6zGQAEhEpS7oAvPLKK9GtWze88cYbKCsrg8ViwR133IGysrJWFzNiAAaRyjGmx8wxY4DuAriIAUhEpBrpAvCTTz6B3W6H1WqF1WqFxWLR/ndrixkxAINI5RjTa2a4jp8BSEQUVNIFIAB8//33ePHFF7F06VJYLBaMGTMGS5YsaXUxIwZgEKkeY3rMZAASESlJygA8G38G0DcGYBCpHmN6zDRCADIUiciEpA/A77//HsePHw/Frg2BARhEqseYHjMZgERESpI+AM/W2NiIXbt2Yfv27di1axcaGxtDPVJ6DMAgUj3Gwj1zxgwgXQAjGIBERKpRIgCPHj2KWbNmITY21uWmj7i4ONx999346aefQjVaegzAIFI5xvSYaZSPgWEAEpEJSR+AR48eRd++fWGxWBAfH4/MzEzcfvvtmDBhAhISEmCxWNCvXz8cPXo0FOOlxwAMIpVjTI+ZDEAiImVJH4D33XcfLBYLFi5ciP/+978uXzt58iTy8/NhsVjwm9/8JhTjpccADCKVY0yPmQxAIiJlSR+AvXv3xpgxY3xuM2bMGPTu3TsU46XHAPST0WNMj5kMQCIiZUkfgDabDQ899JDPbR566CHYbLZQjJceA9BPRo8xPWYyAImIlCV9AHbp0gXZ2dk+t8nOzkaXLl1CMV56DEA/GT3G9JjJACQiUpb0AZiVlYXo6Ghs3LjR49c3bdqE6Oho3HjjjaEYLz0GoJ+MHmN6zGQAEhEpS/oA3LVrl/bxL9dccw1WrFiBtWvXYsWKFZg8eTKsVivatWuHXbt2hWK89BiAfjJ6jOkxkwFIRKQs6QMQAMrLy5GamgqLxQKLxQKr1ar97z59+mDr1q2hGi09BqCfjB5jesxkABIRKUuJAASA5uZmlJeXo7i4GI899hiKi4tRXl6O5ubmUI6VHgPQT0aPMT1mLlkCTBTA9QxAIiLVKBOA5BkD0E9GjzG9ZuoRYwxAIqLzxgBUHAPQT2aIMT1mMgCJiJTEAFQcA9BPZogxPWYyAImIlMQAVBwD0E9miDE9ZjIAiYiUxABUHAPQT2aIsXDP5F3ARETKYgAqjgHoJ6PHmB4zGYBERMpiACqOAegno8eYHjMZgEREypI+AK1WK2bMmBGKXRsCA9BPRo8xPWYyAImIlCV9AHbs2BEPPvhgKHZtCAxAPxk9xvSYyQAkIlKW9AE4fvx4TJgwIRS7NgQGoJ+MHmN6zGQAEhEpS/oA3L59O6Kjo/HKK6+EYvfKYwD6yegxpsdMBiARkbKkD8ClS5di/PjxsFqtuOyyy5CTk4MlS5Zg6dKlLsujjz4aivHSYwD6yegxpsdMBiARkbKkD0CLxeLXYrVaQzFeegxAPxk9xvSYyQAkIlKW9AH42Wef+b2YEQPQT0aPMT1mmikAGYlEZDDSByD5xgD0k9FjTI+ZmzcDDwpgkaQxxgAkIvKKAag4BqCfjB5jes2UOcYYgEREXikRgI2NjXjqqadw+eWX44ILLkBERIT2ta+++go5OTnYu3dvqMZLjQHoJzPEmB4zZY4xBiARkVfSB+CpU6dw1VVXwWq1okuXLujevbvLDR/Hjx9HTEwMFi1aFIrx0mMA+skMMabHTJljjAFIROSV9AH48MMPw2KxoKioCM3NzSgoKHC74zczMxOXXXZZKMZLjwHoJzPEWLhn8mcAGYBEpCzpA7Bv377IyMjQHi9ZssQtAHNyctClS5dQjJceA9BPRo8xPWbyLmAGIBEpS/oAtNlsWLhwofbYUwAuXLgQNpstFOOlxwD0k9FjTI+ZDEAGIBEpS/oATEhIwO2336499hSA06dPR48ePUIxXnoMQD8ZPcb0mMkAZAASkbKkD8BrrrkG8fHxOHbsGAD3ADxw4ADsdjtmzJgRivHSYwD6yegxpsdMBiADkIiUJX0AlpWVwWq1YvDgwdi6dSsefvhhWK1WnDx5Eps2bcLAgQMRFRWFv/71r6EYLz0GoJ+MHmN6zGQAMgCJSFnSByAA/P73v0dUVBSsVqvbEhUVhdLS0lCNlh4D0E9GjzE9ZjIAGYBEpCwlAhAAKioqcO+992LYsGHo27cvhgwZgrlz52LXrl2hHCs9BqCfjB5jesxkADIAiUhZygQgecYA9JPRY0yPmQxABiARKYsBqDgGoJ+MHmN6zGQAMgCJSFnKBOA777yDqVOnIjk5Ge3bt0dycjKmTp2KDRs2hHKs9BiAfjJ6jOkxkwHY9plERDqTPgAbGxuRlZUFq9UKi8WCqKgodO3aFVFRUbBYLLBarcjKykJjY2PA+965cyfmzZuHiy66CLGxsUhOTkZWVhb27t3rtm1FRQUyMzMRFxcHh8OBmTNn4vDhw27bOZ1OFBUVoVevXrDZbEhPT8f69es9zvd3n74wAP1k9BjTa6YRYowBSEQmJH0APvroo7BYLBg1ahS2bt0Kp9MJ4OfQKi8vx9VXXw2r1Yply5YFvO/p06eja9eumD9/PkpLS7Fs2TIkJiYiLi4O3377rbZddXU1EhISkJqaimeffRbLly+Hw+HAoEGDcPr0aZd95ufnQwiBu+++G6tXr8bkyZMhhMDrr7/usl0g+/SFAegnM8SYHjONEGMMQCIyIekDsHfv3hg4cKDXd/jOnDmDAQMGoHfv3gHve9u2bW6xtW/fPthsNmRnZ2vrcnJyYLfbUVVVpa3buHEjhBAoKSnR1tXU1CAqKgrz5s3T1jU3N2PkyJHo0aMHmpqaAt5naxiAfjJDjOkx0wgxxgAkIhOSPgBjYmJcfhewJ3l5eYiJiQnazMGDB2Pw4MHa4y5duiArK8ttu379+mHs2LHa4+effx5CCOzevdtlu/Xr10MIgfLy8oD32RoGoJ/MEGN6zDRCjDEAiciEpA/Avn37Yu7cuT63mTt3Lvr16xeUec3NzejevTvGjx8P4Od39YQQKCoqctt25syZ6NSpk/Z41qxZiIuLQ3Nzs8t2+/fvhxACxcXFAe+zNQxAP5khxsI9c8kSYKIArlc8xhiARGRC0gdgUVEREhIScPDgQY9fr6mpQXx8PH73u98FZd6rr74KIQReeuklAMAXX3wBIQTWrl3rtm1eXh6EEGhoaAAATJ48GSkpKW7bnTx5EkII5OfnB7zPczU0NKC2tlZbKioqGID+MHqM6TGTdwEzAIlIWdIFYFVVlctSWVmJqVOnIjExEY8//jjKy8uxb98+lJeXo7CwEImJiZg2bRoqKyvPe/aePXvQvn17DB8+XPt5vS1btkAIgTfffNNt+8WLF0MIgWPHjgEAMjIyMHDgQLftnE4nhBBYsGBBwPs8V0FBAYQQbgsDsBVGjzE9ZjIAGYBEpCzpArDlo13OXXytt1gsiIiIOK+5hw4dQkpKCpKTk/HDDz9o6/kOoEEYPcb0mMkAZAASkbKkC8DbbrsNt99+e5uWtjp+/DguueQSdOrUye0GjkB/BjA2NpY/Aygjo8eYHjMZgAxAIlKWdAEYbvX19Rg5ciRiY2Oxfft2j9t07tzZ6x27GRkZ2uOVK1d6vAt43bp1EEJgy5YtAe+zNQxAPxk9xvSYyQBkABKRskwdgE1NTZg6dSoiIyPx4Ycfet1uzpw5sNvtOHDggLZu06ZNEEJg1apV2rrq6mqvnwPYvXt3l88B9HefrWEA+snoMabHTAYgA5CIlGXqAFywYAGEEJgyZQpeffVVt6XFgQMHEB8fj9TUVBQXF6OwsBAOhwPp6eluP6vX8jN8s2fPRmlpqfabQNatW+eyXSD79IUB6Cejx5geMxmADEAiUpYSAVheXo5p06ahV69eiI6O9ngzSFtuAhk1apTHO2pblrPt2rUL48ePR2xsLDp27Ijs7Gz8+OOPbvt0Op0oLCxEz549ER0djbS0NLz22mse5/u7T18YgH4yeozpMZMByAAkImVJH4Br167V7vZNTU3FVVddhdGjR3tczMj0AShjGJllJgOQAUhEypI+APv27Yv4+Hjs2LEjFLtXHgNQwjAyy8wZM4B0AYxQPMYYgERkQtIHYExMjMtNFeSKAShhGJlpphFijAFIRCYkfQD2798fd999dyh2bQgMQEnDyCwzjRBjDEAiMiHpA/CJJ55AUlISjh49GordK48BKGkYmWWmEWKMAUhEJiR9AALA3LlzMWDAALz22mv49ttv3X5fcMtiRgxAScPILDONEGMMQCIyISUC8MUXX0THjh09fvzL+XwMjBEwACUNIzPMHDMG6C6AixSPMQYgEZmQ9AFYXFwMq9UKm82GsWPHYubMmUH/XcAqYwBKGEZmmcmPgWEAEpGypA/A3r17Izk52byB0woGoIRhZJaZDEAGIBEpS/oAtNvtuO+++0Kxa0NgAEoYRmaZyQBkABKRsqQPwPT0dNP+511/MAAlDCOzzGQAMgCJSFnSB+DLL78Mh8OB77//PhS7Vx4DUMIwMstMBmBozxMRUQhJH4BlZWW49tprkZCQgMceewwffPABysrKPC5mxACUMIzMMpMByAAkImVJH4AWiwVWqxUWi0X7394WM2IAShhGZpnJAGQAEpGypA/AgoICLFmyxK/FjBiAEoaRWWYyABmARKQs6QOQfGMAShhGZpnJAGQAEpGyGICKYwBKGEZmmVlSAmQL4C6DxhgDkIgMjAGoOAaghGFkpplGjjE9ZhIRhYn0AdjajR/8XcAMQCnDyCwzjRxjeswkIgoT6QNw1KhRGD16tNty6aWXol27drBYLLjkkkswevToUIyXHgNQ0jAyy0wjx5geM4mIwkT6APTl5MmTmD9/Pvr27YsjR46Ee7wUGICShpEZZh48CBQLYKVBY4wBSEQGpnQAtrjssstM++viGIAShpFZZvIuYAYgESnLEAF4//33o3PnznqN1xUDUMIwMstMBiADkIiUZYgAnDlzJux2u17jdcUAlDCMzDKTAcgAJCJlKR2ATqcTa9euRVRUFIYPHx7u8VJgAEoYRmaZyQBkABKRsqQPwN69e3tckpOTYbPZYLVaYbPZ8Nlnn4VivPQYgBKGkVlmMgAZgESkLOkDsGfPnujVq5fbkpKSgiFDhmDOnDnYtWtXKEYrgQEoYRiZZSYDUI7zRETUBtIHIPnGAJQwjMwykwEox3kiImoDBqDiGIAShpFZZjIA5ThPRERtwABUHANQwjAyy0wGoBzniYioDaQMwDvuuCPg5c477wzWeKUwACUMI7PMZADKcZ6IiNpAygC0WCx+L1arVfvTjBiAEoaRWWb+4x9AkQBWGDTG9JjZln0REbWBlAH4+eef+7W89tpr6NOnDwOQAShXGJlpppFjTI+ZbdkXEVEbSBmArTly5Ah+/etfw2azwWKxYOTIkdi+fXu4xkuFAShpGJllppFjTI+ZbdkXEVEbKBWAJ0+exNKlS9G+fXtYLBb84he/wPvvvx/qsVJjAEoaRmaZaeQY02NmW/ZFRNQGSgRgU1MTnn/+eXTt2hUWiwXJycl4+eWX4XQ6QzVSGQxAScPIDDPXrQNmCWCuQWNMj5lt2RcRURtIH4B//OMf0a9fP1itVjgcDhQVFaG+vj4Uo5TEAJQwjMwyk3cBy3GeiIjaQNoA3Lx5M4YOHQqr1YqYmBjk5eXh2LFjwRxhCAxACcPILDMZgHKcJyKiNpAyACdMmACr1YrIyEjccccd5o0bPzAAJQwjs8xkAMpxnoiI2kDKAGz5WJeUlBRMnDjRr2XSpEnBGq8UBqCEYWSWmQxANc4TEZEH0gZgoAs/B5ABKN0F1+gzGYBqnCciIg+kDMDvv/++TYsZMQAlvuAafSYDUI3zRETkgZQBSP5jAEp8wTX6TAagGueJiMgDBqDiGIASX3CNPpMBqMZ5IiLygAGoOAagxBdco89kAKpxnoiIPGAAKo4BKPEF1+gzhwz5Of56GzTG9JgZquMnIjoHA1BxDECJL7hmmGnkGNNjZqiOn4joHAxAxTEAJb7gmmGmkWNMj5mhOn4ionMwABXHAJT4gmuGmUaOMT1mhur4iYjOwQBUHANQ4guuGWYaDkq3HgAAIABJREFUOcb0mBmq4yciOoepA/DEiRN45JFHkJmZCYfDASEE1qxZ43HbiooKZGZmIi4uDg6HAzNnzsThw4fdtnM6nSgqKkKvXr1gs9mQnp6O9evXn9c+fWEASnzBNfrM2bOBoQLIMGiM6TEzVMdPRHQOUwdgZWUlhBC48MILMXr0aK8BWF1djYSEBKSmpuLZZ5/F8uXL4XA4MGjQIJw+fdpl2/z8fAghcPfdd2P16tWYPHkyhBB4/fXX27xPXwwbgEa44Bp9Jj8GRo3zRETkgakDsKGhAYcOHQIAfPHFF14DMCcnB3a7HVVVVdq6jRs3QgiBkpISbV1NTQ2ioqIwb948bV1zczNGjhyJHj16oKmpKeB9toYBKPEF1+gzGYBqnKdAZhKRaZg6AM/mKwC7dOmCrKwst/X9+vXD2LFjtcfPP/88hBDYvXu3y3br16+HEALl5eUB77M1DEDFL7gqz2QAqnGeAplJRKbBAPwfbwFYU1MDIQSKiorcvmfmzJno1KmT9njWrFmIi4tDc3Ozy3b79++HEALFxcUB77M1DEDFL7gqz2QAqnGeAplJRKbBAPwfbwHYsn7t2rVu35OXlwchBBoaGgAAkydPRkpKitt2J0+ehBAC+fn5Ae/zXA0NDaitrdWWiooKBqDKF1yVZzIA1ThPgcwkItNgAP6PtwDcsmULhBB488033b5n8eLFEELg2LFjAICMjAwMHDjQbTun0wkhBBYsWBDwPs9VUFAAIYTbwgBU9IKr8kwGoBrnKZCZRGQaDMD/4TuAkjHLBVflmQxANc5TIDOJyDQYgP8TrJ8BjI2N5c8ABoNZLrgqz2QAqnGeAplJRKbBAPwfX3cBd+7c2esduxkZGdrjlStXerwLeN26dRBCYMuWLQHvszUMQMUvuCrPZACqcZ4CmUlEpsEA/B9fAThnzhzY7XYcOHBAW7dp0yYIIbBq1SptXXV1tdfPAezevbvL5wD6u8/WMAAVv+CqPDM3FxgtgMlhfp7hes30mBmq4/d3JhGZhukD8LnnnsOyZcuQk5MDIQSuv/56LFu2DMuWLcPx48cBAAcOHEB8fDxSU1NRXFyMwsJCOBwOpKenu/2sXsvP8M2ePRulpaXabwJZt26dy3aB7NMXBqDiF1zVZ4br+M0yM1TH7+9MIjIN0wdgz549Pd5VK4RAZWWltt2uXbswfvx4xMbGomPHjsjOzsaPP/7otj+n04nCwkL07NkT0dHRSEtLw2uvveZxtr/79IUBqPgFV/WZ4Tp+s8wM1fH7O5OITMP0Aag6BqDiF1zVZ4br+M0yM1TH7+9MIjINBqDiGICKX3BVnxmu4zfLzFAdv78zicg0GICKYwAqfsFVeWb//kCMAJLC/DzD9ZrpMTNUx+/vTCIyDQag4hiAil9wVZ7Jj4FR4zwFMpOITIMBqDgGoOIXXJVnMgDVOE+BzCQi02AAKo4BqPgFV+WZDEA1zlMgM4nINBiAimMAKn7BVXkmA1CN8xTITCIyDQag4hiAil9wVZ7JAFTjPAUyk4hMgwGoOAag4hdclWcyANU4T4HM9Je/M4lIWgxAxTEAFb/gqjyTAajGedJzJhFJiwGoOAagxBc/o89kAKpxnvScSUTSYgAqjgEo8cXP6DMZgGqcJz1nEpG0GICKYwBKfPEz+swPPgDuFcADYX6e4XrN9JgZquPXayYRSYsBqDgGoMQXPzPMDNfxm2VmqI5fr5lEJC0GoOIYgBJf/MwwM1zHb5aZoTp+vWYSkbQYgIpjAEp88TPDzHAdv1lmhur49ZpJRNJiACqOASjxxc/oM//6V2CJAB4L8/MM12umx8xQHb9eM4lIWgxAxTEAJb74GX0m7wJW4zzpOZOIpMUAVBwDUOKLn9FnMgDVOE96ziQiaTEAFccAlPjiZ/SZDEA1zpOeM4lIWgxAxTEAJb74GX0mA1CN86TnTCKSFgNQcQxAiS9+Rp/JAFTjPMk+k4h0wQBUHANQ8YufyjMZgGqcJ9lnEpEuGICKYwAqfvFTeSYDUI3zJPtMItIFA1BxDEDFL34qz2QAqnGeZJ9JRLpgACqOAaj4xU/lmQxANc6T7DOJSBcMQMUpGYCyXog4M7DtGIBqnCfZZxKRLhiAimMAKn7xU3lmXR1QKoAXw/w8w/Wa6TEzVMdvhJlEFFQMQMUxAE1y8ZN1ZriO3ywzQ3X8RphJREHFAFQcA9AkFz9ZZ4br+M0yM1THb4SZRBRUDEDFMQBNcvGTdWa4jt8sM0N1/EaYSURBxQBUHAPQJBc/GWc++SRwvQCyw/w8w/Wa6TEzVMdvhJlEFFQMQMUxAE1y8ZNxJu8CVuM8GWUmEQUVA1BxDECTXPxknMkAVOM8GWUmEQUVA1BxDECTXPxknMkAVOM8mW0mEfmFAag4BqDEFyKjz2QAqnGezDaTiPzCAFQcA1DiC5HRZzIA1ThPZptJRH5hACqOASjxhcjoMxmAapwns80kIr8wABXHAJT4QmT0mQxANc6T2WYSkV8YgIpjAEp8ITL6TAagGufJbDOJyC8MQMUxACW+EBl9JgNQjfPEme7bEBEDUHUMQMUvRCrPnDIF6COAwWF+nuF6zfSYGarj50wQkSsGoOIYgIpfiFSfGa7jN8vMUB0/Z4KIXDEAFccAVPxCpPrMcB2/WWaG6vg5s237IjIwBqDiGIAmuRDJOjNcx2+WmaE6fs5s276IDIwBqDgGoEkuRLLODNfxm2VmqI6fM0M7k0hBDEDFSRWAMv8DmjODP5M3gahxnjgz9DOJFMQAVBwDkDN1m8mPgVHjPHFm6GcSKYgBqDgGIGfqNpMBqMZ54kw5ZhJJhgGoOAYgZ+o2kwGoxnniTDlmEkmGAaijhoYGLFy4EElJSYiJicHQoUPx6aefBrQPBiBn6jaTAajGeeJMtWYShQkDUEc333wzIiMjkZubi5KSEgwfPhyRkZEoLy/3ex8MQM7UbSYDUI3zxJlqzSQKEwagTnbs2AEhBFasWKGtq6+vR2pqKoYPH+73fhiAnKnbTAagGueJM405k+g8MQB1kpeXh4iICNTW1rqsLywshBACBw4c8Gs/DEDO1G0mA1CN88SZxpsZ7OMnU2IA6mTcuHEYOHCg2/pNmzZBCIH333/fr/0wADlTt5kMQDXOE2cab2a4jv/c7chQGIA6SUtLQ0ZGhtv63bt3QwiBF154weP3NTQ0oLa2Vlt27doFIQR27tyJ6urq0CzFwvsSzO04U62ZiYmoFgLVHcL8PMP1mukx0yh/NzjTGH8f9ZjZln1xadOyc+dOCCFQVVV13k3DAAxASkoKJk6c6Lb+u+++gxACTz/9tMfvKygogBCCCxcuXLhw4cLlvJedO3eed9MwAAMQrHcAjx49iq1bt6Kqqkr3f5uQaamoqIAQAhUVFbofi2wLXxu+Pnxt+PrwtZFn0eu1qaqqws6dO9HY2HjeTcMADECwfgaQPKutrYUQwu0mG+Jr0xq+Pt7xtfGNr493fG28M8JrwwAMQG5urse7gJcvXw4h/L8LmDwzwv+hQoWvjW98fbzja+MbXx/v+Np4Z4TXhgEYgM8//xxCuH4OYENDA/r06YNhw4bpeGTGYIT/Q4UKXxvf+Pp4x9fGN74+3vG18c4Irw0DMEBZWVmIjIxEXl4eSkpKMGLECERGRqKsrEzvQ1NeQ0MDCgoK0NDQoPehSIevjW98fbzja+MbXx/v+Np4Z4TXhgEYoPr6euTm5qJr166w2Wy4/PLL8fHHH+t9WERERER+YwASERERmQwDkIiIiMhkGIBEREREJsMApLDZuXMn5s2bh4suugixsbFITk5GVlYW9u7d67ZtRUUFMjMzERcXB4fDgZkzZ+Lw4cM6HLV+HnvsMQghkJaW5va1bdu24corr4TdbkdiYiLmz5+PEydO6HCU4fPll19iypQpcDgcsNvtSEtLw7PPPuuyjRlfFwDYt28fbrrpJnTv3h12ux39+/fH0qVLcfLkSZftjP76nDhxAo888ggyMzPhcDgghMCaNWs8buvvP2OcTieKiorQq1cv2Gw2pKenY/369SF+JsHnz2vjdDqxZs0aTJkyBT169EBsbCzS0tKwbNky1NfXe9zviy++iAEDBsBms6FPnz4oLi4Ow7MJrkD+3rQ4c+YMBg4c6PbJIC1U+HvDAKSwmT59Orp27Yr58/+/9u49qIryDwP4l9sBzkkQERTTTgGDFZMXatDM288SUwkz84JXIBMYU0plxCgxUezipbwmZBeV1DGlm2Np6XidrCknL2FWUqCR19QURS7P74/mrKx7Dpwjx0O4z2fmzNS777777uu653H33T0TkJeXh+zsbLRo0QImkwkHDx5U6pWUlKB58+YICwvDW2+9hdmzZyMgIADt27dHeXl5A+6B65SUlMBoNMJkMmkC4P79++Hj44OOHTti2bJlyMzMhLe3Nx5//PEG6u2t9+WXX8JgMKBTp06YP38+cnNzMXXqVKSnpyt19DguAFBcXIymTZvCbDZjzpw5WL58ORISEiAiiIuLU+rpYXyKioogIrjrrrvQs2dPm1/kjpxjMjIyICJ49tlnkZubi/79+0NEsGbNGhftlXPYMzb//PMPRASdO3fGrFmzkJubi8TERLi7u6Nnz56orq5W1X/77bchIhg0aBByc3MxatQoiAheffVVF+5Z/dl73NQ0b948mEwmmwGwMRw3DIDkMnv27NGcXI8ePQpvb2+MGDFCKUtNTYWvr6/qx663bt0KEcHy5ctd1t+GNHToUPTq1Qs9evTQBMC+ffsiJCRE9f6pvLw8iAi+/PJLV3f1lrtw4QJatGiBgQMHoqqqymY9vY2LheVF9IcOHVKVjx49GiKCc+fOAdDH+Fy9ehWlpaUAgO+++87mF7m955jjx4/Dy8sL48ePV8qqq6vRrVs3tG7dGpWVlbduZ5zMnrEpLy/Hnj17NOu+8sorEBFs3bpVKSsrK0NgYCD69++vqjtixAiYTCbluGsM7D1uLE6ePAl/f3/MnDnTagBsLMcNAyA1uKioKERFRSn/HxwcjMGDB2vqRURE4NFHH3Vl1xrEjh074OHhgQMHDmgC4IULF5T3UNZUXl6OO+64A88884yru3vLLVu2TPnNTQC4dOmSJgjqcVwspk6dChHB6dOnNeXu7u64dOmSLsenti9ye88xS5YsgYjg8OHDqnoffvghRAS7du1yer9dwZ6QU9OBAwcgIqrbu5s2bYKIYNOmTaq6e/fuhYhg1apVzuyyy9gzNomJiYiOjsaxY8esBsDGctwwAFKDqq6uxp133omYmBgA//7LSUTw2muvaeqOHDkSzZo1c3UXXaqyshLt2rVDcnIyAGgC4O7duyEiWLdunWbdrl27qoL07WLQoEHw8/PD1q1bERERARGByWRCSkqKMi9Jj+NisXnzZuV27/79+1FcXIy1a9fCz88Pzz//PAB9jo+tL3JHzjFjx46FyWTS3Pr89ddfNYGoMXE0AG7ZsgUioprDZpmjfPLkSVXd8vJyuLu7Y9KkSc7sssvUNTb79u2Du7s79u7dq9w6vjEANpbjhgGQGtSqVasgIlixYgWA63/5Vq5cqambnp4OEWnUb16vy+LFi+Hv769MRr8xAK5fvx4igp07d2rWHTx4MFq2bOmyvrpKu3btYDQaYTQaMWHCBGzYsAETJkyAiGDYsGEA9DkuNWVnZ8PX1xcionwyMzOV5XocH1tf5I6cY/r374/Q0FBNvcuXL0NEkJGRcUv6fqs5GgAfe+wx+Pn54e+//1bKxo8fDw8PD6v1g4KClL+bjU1tY1NdXY3o6GjEx8cDgM0A2FiOGwZAajCFhYXw8/PDww8/rMyJ2Llzp80rFS+//DJERHUSup2cOXMGzZo1w9y5c5WyGwPgypUrISLYt2+fZv1Ro0bB39/fJX11pdDQUIgIUlJSVOXJyckQERw9elSX41LTqlWr0KdPH+Tm5mLDhg1ISkqCm5sbFi1aBECfx42tL3JHzjG9evXCfffdp6lXVVUFEUFaWtot6fut5kgAtMwxXbp0qao8KSkJvr6+Vtdp06YNBgwY4IyuulxtY/Puu+/C19cXxcXFAGwHwMZy3DAAUoMoLS1FaGgo2rRpgxMnTijler4CmJKSgvDwcNWDMrwCCERGRkJENL+3vWPHDogIPvjgA12Oi8WaNWvg6+uLkpISVXlCQgKMRiPOnDmjy/HhFUDb7A2Aa9euhZubm9U5onq7Amh5GG369OlKGa8AEjno/Pnz6NChA5o1a6aZJKvXOYBHjx6Fu7s7Fi5ciKKiIuXTqVMnREREoKioCGfPntXlXK7evXtDRHDkyBFVeWFhIUQEb775pi7HxaJbt27o0qWLpnzjxo3Kk5t6HB9nzQE0Go3/+blcjrInAG7ZsgUGgwGxsbGoqKjQLNfbHMCXX34ZAQEBOHz4sHJ+3rVrF0QEL774IoqKipR/vDeW44YBkFzqypUr6NatG4xGI/bu3Wu1TlBQkM0n9Hr16nWru9ggtm/frpq/Ze2TlpaG8+fP1/o0Z1JSUgPtwa1jeZ/W119/rSr/+uuvISLIz8/X5bhYREREoFOnTprydevWQUSwefNmXY5PbSHH3nPM4sWLrT7NmZ+fb/OKamNQVwD85ptvYDKZ0KVLF5SVlVmt8/nnn1t9CnjPnj02r7A2BrbGZsyYMXWeo/fv3w+g8Rw3DIDkMpWVlYiLi4Onp6fmpFFTSkqKap4FAHz11VcQESxbtswVXXW506dPo6CgQPOJjIzEXXfdhYKCAhw4cAAA8PjjjyMkJAQXL15U1n/nnXeUL/vbzQ8//AARwfDhw1Xl8fHx8PT0VKYQ6G1cLGJjY2EwGDS/qPPkk0/C3d1dt+NTW8ix9xxTUlJi831ud95553/mfW6Oqm1sfvrpJwQGBiIyMrLWd/mVlZWhWbNmiI2NVZWPHDkSRqMRZ8+edXa3XcLW2Hz//fea8/Py5cshIkhISEBBQQHOnz8PoPEcNwyA5DJpaWkQETzxxBNYtWqV5mNRXFyMwMBAhIWFYeHChcjJyUFAQAAeeOCB23b+ny3WXgT9/fffw9vbW/WLDj4+PsqrdG5HSUlJEBEMGTIES5YsweDBgyEimDZtmlJHj+MCXH9vZHBwMGbOnIklS5agb9++EBGMHTtWqaeX8Vm0aBGys7ORmpoKEcFTTz2F7OxsZGdnK1/QjpxjLPMCx40bh7y8POUXHfLz8xti9+qlrrG5ePEi2rRpA3d3d7z66quac/SNd20s77t7+umnkZeXp7x8fPbs2Q20hzfPnuPmRrbmAAKN47hhACSX6dGjR62Xz2s6dOgQYmJiYDQa0bRpU4wYMQJ//fVXA/W84VgLgACwa9cudOnSBT4+PggKCsL48eNVV3ZuN9euXcOMGTNgNpvh5eWF8PBwLFiwQFNPb+NisW/fPvTt2xctW7aEl5cXIiIiMHv2bM3cLT2Mj9lstnmOKSoqUurZe46pqqpCTk4OzGYzDAYDIiMjsXr1ahfukfPUNTaWQGPrM2bMGE2bubm5aNu2LQwGA8LCwrBgwQLN3LfGwN7jpqbaAmBjOG4YAImIiIh0hgGQiIiISGcYAImIiIh0hgGQiIiISGcYAImIiIh0hgGQiIiISGcYAImIiIh0hgGQiIiISGcYAImIiIh0hgGQiIiISGcYAImIiIh0hgGQiIiISGcYAImoUbH8ALu1H6an/5733nsPIqJ8hg4deku2U1hYqNqO2Wy+Jdshul0wABKRU1kCWs2Pl5cXWrdujfj4ePz4449OaZ8BsHGwBMABAwYgKysL69evr3ebIoK2bduqyk6fPo2srCxkZWXB39+fAZCoDgyARORUloAWFhamfCFPnjwZjzzyCEQE3t7e2L17d73bZwBsHCwB8L333nNam9YCYE1ms5kBkKgODIBE5FSWgNanTx/NsszMTIgIevToUe/2GQAbBwZAov8mBkAicqraAuBff/0FEYHRaARQezjYvn07RARZWVlW278xAH700Ufo3r07goKC4O3tjZCQEDz66KP46KOPNG3v2LEDsbGxCAwMhMFgQHh4ODIzM3H58mWH9tXedmruy3fffYfHHnsMd9xxB/z8/PDkk0+iqKjIqdvYs2cPevfuDX9/f4hcP81XVFQgJycHoaGh8Pb2RlhYGHJycvDbb7+pxnTr1q0QEaSmplrt06+//go3NzfExMTUOUZ1BcCZM2dCRPDFF19oln366acQEcydO1dVzgBIVH8MgETkVPYEQJPJBMB5AXDp0qUQEYSEhGDcuHGYNm0aEhMTERkZiREjRqjWX7p0Kdzc3BAQEIDRo0djypQp6NmzJ0QEXbp0QXl5uV376Ug7ln3p168ffH190a9fP0yePBm9evVSbpdfuXLFKdvo3bs3vLy8EBMTg/T0dNVDF6NGjYKIIDQ0FJMmTcL48eMRFBSEJ554QjWm1dXVCAsLg7+/v9VQnJGRARGxaz5fXQFw4MCBEBGcOnVKs2zGjBkQEWzbtk1VzgBIVH8MgETkVLUFwOnTp0NE8L///Q+A8wJgVFQUDAYDTp48qWnnzJkzyn8fPnwYnp6eaN++vaocAObMmWP1apM1jrZj2RcRwdq1a1X1LaFszZo1TtvGu+++q+nzV199BRFBhw4dVKHuzz//RIsWLTRj+tprr0FE8P7776vaqaioQEhICIKDg3Ht2rU6RqruAHj33XejdevWVpfFxcVBRHDu3DlVOQMgUf0xABKRU1l7CGTKlCno1q0bRAQ+Pj7Yu3cvAOcGQJPJpAkKN5o4cSJEBDt37tQsq6qqQlBQEB588ME699HRdiz70r17d019y7JJkyY5ZRtRUVFW+5yQkAARwcaNGzXLcnJyNGN66tQpGAwGdO3aVVX3448/hoggPT3d6nZuVNuf8blz5yAiiIuLs7pu69atcffdd2vKGQCJ6o8BkIicqrbXwAwfPhwHDhxQ6jorAL7++usQEbRq1QpTpkzBpk2bcOHCBU2b0dHREBFkZmYq4bTmp1WrVsrt6do42o5lX1544QVNW7/88gtEBElJSU7ZRnJystU+d+zY0eat1h07dlidVzls2DCICAoLC5Wy2NhYiAh+/vnnOscJqP3PeNu2bRARzJgxQ7Ps1KlTEBEMHDhQs4wBkKj+GACJyKlquwV8I2cFwOrqaqxYsQIPPfQQ3NzcICLw9PTEgAEDcOzYMaVeeHi4Jpxa+9TF0XZs7Yut/anPNqZPn261z2FhYXB3d0d1dbVm2ZEjR6z2wdLm5MmTAQAnTpyAh4eHQ09x1/ZnPG/ePIgIPvnkE82yL774AiKCmTNnapYxABLVHwMgETmVIwHwgw8+gIggLy9Ps8xyq9Hep4Atzpw5g4KCAgwZMgQigvvvvx+VlZUA/r1VLCK4ePGiw/tVk6Pt3EwAdOY2gJu7AggA9957L4KCglBeXo5Zs2ZBRLB69Wq7+gTUHgBHjhwJEUFJSYlmmWW+6GeffaZZxgBIVH8MgETkVI4EQMtrPqzdAszKyrqpAFiT5SnbI0eOAABSU1MhItiyZYtd+2KLo+3cTAB05jaA63MACwoKNMssD5VYG9P58+dDRLBu3TqEhoYiICDA6hPLttQWACMjI+Hm5oaqqipVeVVVFSIjIyEiOH78uGY9BkCi+mMAJCKnciQAnjhxAm5ubrj33ntVoeLo0aNo2rSp3QFw+/btmlub165dQ4cOHSAi+P333wEABw8ehKenJ9q2bYs//vhD05+///4bP/zwQ539drSdmwmAztwGcP3dfh07dkRZWZlSXlpaipYtW9oMgGfPnoWPjw9atWoFEcHEiROttm+LrQBYVlYGDw8PiIjql2Gqq6vx0ksvQUQQEBBgtU0GQKL6YwAkIqdyJAACwPDhw5VbtZMmTcLIkSNhMpkwaNAguwOgv78/2rRpg8GDB2PKlClIS0vD/fffDxHB008/rVo/NzcXHh4e8PHxwVNPPYX09HSkpKQgJiYG3t7eNh+iuJEj7dxMAHTmNiwsYx0WFobJkyfjueeeQ3BwsPIewMTERKvrWV5VIyI4ePCgXeNjYSsA7tu3DyKC4OBgNGnSBAkJCUhNTUX79u1xzz33wM3NDR4eHkhKSsLVq1dV6zIAEtUfAyAROZWjAbCsrAwTJ05EixYt4O3tjXbt2iE/P9/hF0HHxcXBbDbDx8cHgYGBiI6OxrJly6y+q+7bb7/FsGHD0KpVK3h5eaF58+aIiopCRkaG6onXutjbzs0GQGdtw6KiogLZ2dm45557YDAYEBoaipycHCWMpaWlWV3P8g7Bzp072zUuNdkKgG+//TZE/n3PYHJyMvz8/ODn54dBgwahuLgY8fHxMJlMiI+PV61XWVkJEcEDDzxgc5sMgER1YwAkItK5vLw8iAiWLl1qdfkbb7wBEcGKFSscbttWAExOTta8YsYepaWlELn+MnFrGACJ6sYASESkE6WlpZq5ksePH4fZbIaHhweKi4s161y5cgVmsxkBAQEO/1YycD0AWj6Wn6aLjo6G0WjUPABSF8uVw4yMDFV5YWGhajsMgES1YwAkItKJtLQ0hIeHIzExEVOnTkV8fDyaNGli9UnsXbt2YdasWcovuMyZM+emtrl//37VC6zXr1+PyspK+Pr6olOnTna3M3v2bMTHx8PDwwMmkwlFRUWq5adPn1ZtZ8GCBTfVXyK9YAAkItKJzZs3o3fv3ggODoaXlxeaNGmCRx55BPn5+Zq6ltfwNG/eHC+88AIqKiqc1o9Dhw5BxPavlljTtGlTNGnSBDExMfj222+d1hcivWIAJCIiItIZBkAiIiIinWEAJCIiItIZBkAiIiIinWEAJCIiItIZBkAiIiIinWEAJCIiItIZBkAiIiIinWEAJCIiItIZBkAiIiIinWEAJCIiItIZBkAiIiIinWEAJCIiItIZBkAiIiIinWEAJCIiItIZBkAiIiIzr+BwAAAAJklEQVQinWEAJCIiItIZBkAiIiIinWEAJCIiItIZBkAiIiIinfk/QMpcEXCEQDkAAAAASUVORK5CYII=\" width=\"640\">" + ], + "text/plain": [ + "<IPython.core.display.HTML object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "print(nrun['SCS_photonFlux'].mean().values)\n", + "f_xgm = tbdet.calibrateXGMs(run)\n", + "\n", + "pulse_energy = nrun['SCS_SA3'].mean().values*f_xgm[1]*1e-6 #average energy in J\n", + "nrun['pulse_energy'] = nrun['SCS_SA3']*f_xgm[1]*1e-6\n", + "nrun['fluence'] = 2*nrun['pulse_energy']/(np.pi*w0_x*w0_y)\n", + "print('Pulse energy [J]:',pulse_energy)\n", + "F0 = 2*pulse_energy/(np.pi*w0_x*w0_y)\n", + "print('Fluence [mJ/cm^2]:', F0*1e-1)\n", + "\n", + "plt.figure()\n", + "plt.hist(nrun['pulse_energy'].values.flatten()*1e6, bins=50, rwidth=0.7, color='orange', label='Run 645')\n", + "plt.axvline(pulse_energy*1e6, color='r', lw=2, ls='--')\n", + "plt.xlabel('Pulse energy [$\\mu$J]', size=14)\n", + "plt.ylabel('Number of pulses', size=14)\n", + "#plt.xlim(0,50)\n", + "plt.legend()\n", + "ax = plt.gca()\n", + "plt.twiny()\n", + "plt.xlim(np.array(ax.get_xlim())*2e-6/(np.pi*w0_x*w0_y)*1e-1)\n", + "plt.xlabel('Fluence [mJ/cm$^2$]', labelpad=10, size=14)\n", + "plt.tight_layout()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Optical laser beam profile and fluence" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Knife-edge measurement (OL)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load runs" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "<xarray.Dataset>\n", + "Dimensions: (bunchId: 1000, fadc_samplesId: 100000, trainId: 767)\n", + "Coordinates:\n", + " * trainId (trainId) uint64 512717212 512717213 ... 512717978 512717979\n", + "Dimensions without coordinates: bunchId, fadc_samplesId\n", + "Data variables:\n", + " sase1 (trainId, bunchId) uint64 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0\n", + " npulses_sase1 (trainId) int64 0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0\n", + " sase3 (trainId, bunchId) uint64 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0\n", + " npulses_sase3 (trainId) int64 0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0\n", + " FastADC4raw (trainId, fadc_samplesId) uint16 33080 33093 ... 33048 33055\n", + " scannerX (trainId) float64 18.0 18.0 18.0 18.0 ... 19.5 19.5 19.5 19.5\n", + "Attributes:\n", + " run: <extra_data.reader.DataCollection object at 0x2b8825a20d68>\n", + " runFolder: /gpfs/exfel/exp/SCS/201931/p900094/raw/r0384\n" + ] + } + ], + "source": [ + "proposal = 900094\n", + "fields = [\"FastADC4raw\", \"scannerX\"]\n", + "runNB = 384\n", + "runX = tb.load(fields, runNB, proposal, validate=False, display=False)\n", + "print(runX)\n", + "\n", + "fields = [\"FastADC4raw\", \"scannerY\"]\n", + "runNB = 385\n", + "runY = tb.load(fields, runNB, proposal, validate=False, display=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Plot diode traces" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('<div/>');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n", + " 'ui-helper-clearfix\"/>');\n", + " var titletext = $(\n", + " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n", + " 'text-align: center; padding: 3px;\"/>');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('<div/>');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('<canvas/>');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('<canvas/>');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('<div/>');\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('<button/>');\n", + " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n", + " 'ui-button-icon-only');\n", + " button.attr('role', 'button');\n", + " button.attr('aria-disabled', 'false');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + "\n", + " var icon_img = $('<span/>');\n", + " icon_img.addClass('ui-button-icon-primary ui-icon');\n", + " icon_img.addClass(image);\n", + " icon_img.addClass('ui-corner-all');\n", + "\n", + " var tooltip_span = $('<span/>');\n", + " tooltip_span.addClass('ui-button-text');\n", + " tooltip_span.html(tooltip);\n", + "\n", + " button.append(icon_img);\n", + " button.append(tooltip_span);\n", + "\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " var fmt_picker_span = $('<span/>');\n", + "\n", + " var fmt_picker = $('<select/>');\n", + " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n", + " fmt_picker_span.append(fmt_picker);\n", + " nav_element.append(fmt_picker_span);\n", + " this.format_dropdown = fmt_picker[0];\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = $(\n", + " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n", + " fmt_picker.append(option);\n", + " }\n", + "\n", + " // Add hover states to the ui-buttons\n", + " $( \".ui-button\" ).hover(\n", + " function() { $(this).addClass(\"ui-state-hover\");},\n", + " function() { $(this).removeClass(\"ui-state-hover\");}\n", + " );\n", + "\n", + " var status_bar = $('<span class=\"mpl-message\"/>');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "}\n", + "\n", + "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n", + "}\n", + "\n", + "mpl.figure.prototype.send_message = function(type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "}\n", + "\n", + "mpl.figure.prototype.send_draw_message = function() {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n", + " }\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype.handle_resize = function(fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1]);\n", + " fig.send_message(\"refresh\", {});\n", + " };\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n", + " var x0 = msg['x0'] / mpl.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n", + " var x1 = msg['x1'] / mpl.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0, 0, fig.canvas.width / 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", + " // 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", + "\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 0x2b8826018a20>]" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "plt.figure()\n", + "plt.plot(runY['FastADC4raw'][0])\n", + "plt.plot(runX['FastADC4raw'][0]-20000)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Integrate peaks, plot intensity vs. knife-edge positions, fit with erfc function" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "scrolled": false + }, + "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", + " // 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", + "\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" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fitting function: a*erfc(np.sqrt(2)*(x-x0)/w0) + b\n", + "w0 = (133.0 +/- 0.1) um\n", + "x0 = (18.758 +/- 0.000) mm\n", + "a = 2.440091e+05 +/- 3.786296e+01 \n", + "b = 8.093633e+03 +/- 5.257618e+01 \n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('<div/>');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n", + " 'ui-helper-clearfix\"/>');\n", + " var titletext = $(\n", + " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n", + " 'text-align: center; padding: 3px;\"/>');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('<div/>');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('<canvas/>');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('<canvas/>');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('<div/>');\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('<button/>');\n", + " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n", + " 'ui-button-icon-only');\n", + " button.attr('role', 'button');\n", + " button.attr('aria-disabled', 'false');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + "\n", + " var icon_img = $('<span/>');\n", + " icon_img.addClass('ui-button-icon-primary ui-icon');\n", + " icon_img.addClass(image);\n", + " icon_img.addClass('ui-corner-all');\n", + "\n", + " var tooltip_span = $('<span/>');\n", + " tooltip_span.addClass('ui-button-text');\n", + " tooltip_span.html(tooltip);\n", + "\n", + " button.append(icon_img);\n", + " button.append(tooltip_span);\n", + "\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " var fmt_picker_span = $('<span/>');\n", + "\n", + " var fmt_picker = $('<select/>');\n", + " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n", + " fmt_picker_span.append(fmt_picker);\n", + " nav_element.append(fmt_picker_span);\n", + " this.format_dropdown = fmt_picker[0];\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = $(\n", + " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n", + " fmt_picker.append(option);\n", + " }\n", + "\n", + " // Add hover states to the ui-buttons\n", + " $( \".ui-button\" ).hover(\n", + " function() { $(this).addClass(\"ui-state-hover\");},\n", + " function() { $(this).removeClass(\"ui-state-hover\");}\n", + " );\n", + "\n", + " var status_bar = $('<span class=\"mpl-message\"/>');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "}\n", + "\n", + "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n", + "}\n", + "\n", + "mpl.figure.prototype.send_message = function(type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "}\n", + "\n", + "mpl.figure.prototype.send_draw_message = function() {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n", + " }\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype.handle_resize = function(fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1]);\n", + " fig.send_message(\"refresh\", {});\n", + " };\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n", + " var x0 = msg['x0'] / mpl.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n", + " var x1 = msg['x1'] / mpl.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0, 0, fig.canvas.width / 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", + " // 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", + "\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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X3+xZMkSwsLC+PPPP/P9jDNnzpCYmFiocrF+505pyB2JvpjLCbxRUVEYhsGePXs8dqwn583mutzAW9xzeN944w2XeeEX07x5c1q2bOlW//zzz3PDDTe41OUG3gtHcl955RUqVqzo1kazZs247bbbCvz8AgPvsb0QHsKn3ezYbQ42/7ebuZKDiJQaCrziQlMaCh94x44d67U5vLGxsZQvX56nn36azMzC31H+ww8/YBgGK1asoGzZss7lpCIiIrj33nsZPnw4tWvXdmkzNTWVsmXLkpBwfsvVZs2auW0IkcsT81Fzb1r78ccfC/w+lxN4J0yYgGEYfPvttx47tnfv3vmujBAREVHsqzR4si+evGnt6quvdrkxDcz54tWrV+fZZ591qS/2wHs2HcY9wq/9WmC3OYjuvJQzXxf9plARCVwKvOJCN60VPvBOmzYNwzD44YcfPN6HRx55hNatW3PmzJkivS93U4HHHnvMZRRw8uTJNGjQgOuuu47hw4e7vOf7778nNDTUpa5bt268/fbb+X6GJ+bw5s43ff/99wv8PgUFsiNHjrjVnT17lrvvvpvg4GCXG+KKcuxff/1FfHy8SxjbsmULhuG69m1GRgY33HADDzzwQIHfwdOK0pf8vktehV2WrHv37gX26ciRIxiGwXPPPedSn7sld3h4uEt9sQdegMktyBlahfnnlijb3rujGYRFpFRQ4BUXCryFD7xbt27FMAz+8Y9/MGfOHBYuXOixZclSUlKKtENe3vfljq5OnjzZWT979mwMw6Bs2bJu84HXr19PvXr1XOoGDhyIzWa7rL4X1u23386LL76Y72uF2QUxdy7ysGHDiImJYcSIEdx8880YhsF7773n0l5Rjs39878wpLVr146goCD69OlDVFQUDz30EEFBQZdcLgsgKSnJuXTdpUphfoYK25eLfZfCnF84v/HEpeZ0506nqFy5Ml26dGHixIm8+OKLhIWFYRgGbdq0yfemtWINvGMfhvAQ4vo8jd3m4IMuH5N1OK7ANkWk5FDgFRcKvIUPvAAjRoygdu3aWK1Wr01vKIrs7GwsFguVKlVy+TNcvHgxhmHw/PPPu72nqCO8njJu3DgqVaqU781QhdkFceHChbRo0YKaNWsSFBREaGgoLVq0YMmSJW7tFeXYi4XE9PR0evfuTa1atShfvjz33XcfX375ZaG+qyeX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DMPg008/veTnfPHFF1gsFh577DGio6Pp3r07VquVzp07e+FbXZniOCfLli2jbNmy/Otf/2LChAnY7XYee+wxDMNg6NChXvpml6+4fk7yeuqpp6hYsaJfXpSL63ycOHGCxo0bU61aNQYMGMD777/Pu+++y/9v7+6joirzOID/hsEBYXhL3hRwMs+K78NW+JIiGeXqali6ptEaUG2mJUibnlrcBeGcMjQyEUi2dE/kS5umi2db09Vejkcz11NWm2UpuZpKrOJbIQh89w/PvctlXgDhjszw/Zwz5+gzlzvP/c2dZ75z57l3Jk+ejHPnzumwZdfPVTWZNm0avL29MXfuXPz5z3/GkiVLEB4ejoCAAHz//fc6bNn1a2tNFi1aBBHBb37zG5SWlmL+/Pnw9vbGhAkT2vQ47jK+uqIenjq2dnQfaa4rj62uxMDbzVy5cgWnT58GABw4cMDhi+0Xv/gF4uPj0dTUpLZduHABZrMZycnJrT7O4MGDYbVaNUccsrOzYTAYcPjw4Y5vSCdyRU2OHTtm8+bc1NSEu+66Cz4+Ptf1qV1PrtpPFNu3b4fJZMLixYu75KDsqnrMnTsXwcHBOHbsWKf1XS+uqMnJkychInjmmWc07bt374aIoLCwsOMb0onaUpNTp07B29sbs2fP1rQXFRVBRFBRUdHq47jL+OqKenji2NoZ+4iiq4+trsTA2405e5OKiIjA5MmTbdojIyMxc+ZMp+v997//DRFBcXGxpv2HH36AiCA/P79D/daTXjVxRDn69fnnn1/X37uC3jWpr69HbGwsFi5ciLVr13b5QVmvetTU1MDX1xeLFi0CANTV1bnNtTb1qsnhw4chIli2bJnd9tLS0g71W0+OarJ582aICP7+979r2qurqyEiSElJcbpedx1f9aqHI+48tnZWTdxtbNUbA2835uxNaubMmTAajVi5ciUqKytx+PBhzJs3Dz179sTevXudrvfNN9+EiGD//v0290VHR2PatGmdtQmdTq+aOPKHP/wBIoJTp051sOf60bsmBQUFCA8Px4ULF9xiUNarHtu2bYOIoKysDNOnT4fRaITBYMAdd9yBTz/9VKet6Rx61aS+vh7R0dGIjIxERUUFTpw4gf379yMxMRH9+vVDTU2NTlvUcY5qsn79eogIdu/erWn/6aefICKIjY11ul53HV/1qocj7jy2dlZN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\" width=\"700\">" + ], + "text/plain": [ + "<IPython.core.display.HTML object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "fitting function: a*erfc(-np.sqrt(2)*(x-x0)/w0) + b\n", + "w0 = (314.9 +/- 0.6) um\n", + "x0 = (12.092 +/- 0.000) mm\n", + "a = 2.480674e+05 +/- 1.685863e+02 \n", + "b = -8.370131e+03 +/- 1.847908e+02 \n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('<div/>');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n", + " 'ui-helper-clearfix\"/>');\n", + " var titletext = $(\n", + " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n", + " 'text-align: center; padding: 3px;\"/>');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('<div/>');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('<canvas/>');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('<canvas/>');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('<div/>');\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('<button/>');\n", + " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n", + " 'ui-button-icon-only');\n", + " button.attr('role', 'button');\n", + " button.attr('aria-disabled', 'false');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + "\n", + " var icon_img = $('<span/>');\n", + " icon_img.addClass('ui-button-icon-primary ui-icon');\n", + " icon_img.addClass(image);\n", + " icon_img.addClass('ui-corner-all');\n", + "\n", + " var tooltip_span = $('<span/>');\n", + " tooltip_span.addClass('ui-button-text');\n", + " tooltip_span.html(tooltip);\n", + "\n", + " button.append(icon_img);\n", + " button.append(tooltip_span);\n", + "\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " var fmt_picker_span = $('<span/>');\n", + "\n", + " var fmt_picker = $('<select/>');\n", + " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n", + " fmt_picker_span.append(fmt_picker);\n", + " nav_element.append(fmt_picker_span);\n", + " this.format_dropdown = fmt_picker[0];\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = $(\n", + " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n", + " fmt_picker.append(option);\n", + " }\n", + "\n", + " // Add hover states to the ui-buttons\n", + " $( \".ui-button\" ).hover(\n", + " function() { $(this).addClass(\"ui-state-hover\");},\n", + " function() { $(this).removeClass(\"ui-state-hover\");}\n", + " );\n", + "\n", + " var status_bar = $('<span class=\"mpl-message\"/>');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "}\n", + "\n", + "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n", + "}\n", + "\n", + "mpl.figure.prototype.send_message = function(type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "}\n", + "\n", + "mpl.figure.prototype.send_draw_message = function() {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n", + " }\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype.handle_resize = function(fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1]);\n", + " fig.send_message(\"refresh\", {});\n", + " };\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n", + " var x0 = msg['x0'] / mpl.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n", + " var x1 = msg['x1'] / mpl.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0, 0, fig.canvas.width / 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", + " // 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", + "\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=\"700\">" + ], + "text/plain": [ + "<IPython.core.display.HTML object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "X-FWHM [um]: 156.5707204032264\n", + "Y-FWHM [um]: 370.80865951724894\n" + ] + } + ], + "source": [ + "runX['FastADC4peaks'] = tbdet.autoFindFastAdcPeaks(runX, channel=4, plot=True)\n", + "runY['FastADC4peaks'] = tbdet.autoFindFastAdcPeaks(runY, channel=4)\n", + "\n", + "w0_x = knife_edge(runX, axisKey='scannerX', plot=True)[0]*1e-3\n", + "w0_y = knife_edge(runY, axisKey='scannerY', plot=True)[0]*1e-3\n", + "\n", + "print('X-FWHM [um]:', w0_x * np.sqrt(2*np.log(2))*1e6)\n", + "print('Y-FWHM [um]:', w0_y * np.sqrt(2*np.log(2))*1e6)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Fluence calculation (OL)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### OL power measurement " + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "#measurement performed in Exp Hutch before in-coupling window\n", + "rel_powers = np.array([100, 75, 50, 25, 15, 12, 10, 8, 6, 4, 2, 1, 0.75, 0.5, 0.25, 0.1, 0])\n", + "powers = np.array([505, 384, 258, 130, 81, 67, 56.5, 45.8, 35.6, 24.1, 14.1, 9.3, 8.0, 6.5, 4.8, 4.1, 1.0])*1e-3 #in W\n", + "\n", + "rep_rate = 10\n", + "npulses = 336" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Fluence vs. laser power" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[150.29761905 114.28571429 76.78571429 38.69047619 24.10714286\n", + " 19.94047619 16.81547619 13.63095238 10.5952381 7.17261905\n", + " 4.19642857 2.76785714 2.38095238 1.93452381 1.42857143\n", + " 1.2202381 0.29761905]\n", + "[228.46899057 173.7269156 116.72277142 58.81379955 36.64552126\n", + " 30.31172746 25.56138211 20.720554 16.1059328 10.90317361\n", + " 6.37903518 4.20744874 3.61931074 2.94068998 2.17158645\n", + " 1.85489676 0.45241384]\n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('<div/>');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n", + " 'ui-helper-clearfix\"/>');\n", + " var titletext = $(\n", + " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n", + " 'text-align: center; padding: 3px;\"/>');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('<div/>');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('<canvas/>');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('<canvas/>');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('<div/>');\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('<button/>');\n", + " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n", + " 'ui-button-icon-only');\n", + " button.attr('role', 'button');\n", + " button.attr('aria-disabled', 'false');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + "\n", + " var icon_img = $('<span/>');\n", + " icon_img.addClass('ui-button-icon-primary ui-icon');\n", + " icon_img.addClass(image);\n", + " icon_img.addClass('ui-corner-all');\n", + "\n", + " var tooltip_span = $('<span/>');\n", + " tooltip_span.addClass('ui-button-text');\n", + " tooltip_span.html(tooltip);\n", + "\n", + " button.append(icon_img);\n", + " button.append(tooltip_span);\n", + "\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " var fmt_picker_span = $('<span/>');\n", + "\n", + " var fmt_picker = $('<select/>');\n", + " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n", + " fmt_picker_span.append(fmt_picker);\n", + " nav_element.append(fmt_picker_span);\n", + " this.format_dropdown = fmt_picker[0];\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = $(\n", + " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n", + " fmt_picker.append(option);\n", + " }\n", + "\n", + " // Add hover states to the ui-buttons\n", + " $( \".ui-button\" ).hover(\n", + " function() { $(this).addClass(\"ui-state-hover\");},\n", + " function() { $(this).removeClass(\"ui-state-hover\");}\n", + " );\n", + "\n", + " var status_bar = $('<span class=\"mpl-message\"/>');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "}\n", + "\n", + "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n", + "}\n", + "\n", + "mpl.figure.prototype.send_message = function(type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "}\n", + "\n", + "mpl.figure.prototype.send_draw_message = function() {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n", + " }\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype.handle_resize = function(fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1]);\n", + " fig.send_message(\"refresh\", {});\n", + " };\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n", + " var x0 = msg['x0'] / mpl.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n", + " var x1 = msg['x1'] / mpl.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0, 0, fig.canvas.width / 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", + " // 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", + "\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": { + "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", + " // 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", + "\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4nOzdeXhTZeI+/NOwlLZQKAhlL4sUlS+joOKow8iASBFZRBhFkUVQQEWYGX27J0ApiyI7AmVTkSoqUGWTqegAsgmIAmUTqVBo6Ub3LW1yv3/015SQLklPzpOc5P5c13N5kZ7kPL17bO6eLRKIiIiIyK1Ijp4AEREREYnFAkhERETkZlgAiYiIiNwMCyARERGRm2EBJCIiInIzLIBEREREboYFkIiIiMjNsAASERERuRkWQCIiIiI3wwJIRERE5GZYAImIiIjcDAsgERERkZthASQiIiJyMyyARERERG6GBZCIiIjIzbAAEhEREbkZFkAiIiIiN8MCSERERORmWACJiIiI3AwLIBEREZGbYQEkIiIicjMsgERERERuhgWQiIiIyM2wABIRERG5GRZAIiIiIjfDAkhERETkZlgAiYiIiNwMCyARERGRm2EBJCIiInIzLIBEREREboYFkIiIiMjNsAASERERuRkWQCIiIiI3wwJIRERE5GZYAImIiIjcDAsgERERkZthASQiIiJyMyyARERERG6GBZCIiIjIzbAAEhEREbkZFkAiIiIiN8MCSERERORmWACJiIiI3AwLIBEREZGbYQEkIiIicjMsgERERERuhgWQiIiIyM2wABIRERG5GRZAIiIiIjfDAkhERETkZlgAiYiIiNwMCyARERGRm2EBJCIiInIzLIBEREREboYFkIiIiMjNsAASERERuRkWQBkMBgOSkpKQnZ2NnJwcDg4ODg4ODhWM7OxsJCUlwWAwOLpKOAwLoAxJSUmQJImDg4ODg4NDhSMpKcnRVcJhWABlyM7ONm1A9v7rJCMjA7GxscjIyHD4X0quPJgzc3alwZyZsysNJXOu2IGTnZ3t6CrhMCyAMuTk5ECSJOTk5Nj9tfV6PeLi4qDX6+3+2lSJOYvBnMVgzmIwZzGUzFnJ92+1YAGUgQVQ/ZizGMxZDOYsBnMWgwVQWSyAMrAAqh9zFoM5i8GcxWDOYrAAKosFUAYWQPVjzmIwZzGYsxjMWQwWQGWxAMrAAqh+zFkM5iwGcxaDOYvBAqgsFkAZbNmAjEYjSktLUVRUZNXIzc3Frl27kJuba/VzOGwfzJk5u9Jw55xLS0thNBoF/OZnARSFBVBZLIAyWLMBGY1G3L59G5cuXcL58+etHgkJCTh58iQSEhJseh6HbYM5M2dXGu6e86VLl5CVlaV4EWQBFIMFUFksgDJYswElJyfj/PnzuHHjBnJzc1FYWGjVX7MFBQVITU1FQUGBw/+yduXBnJmzKw13zbmwsBC5ubm4ceMGzp8/j+TkZEV/97MAisECqCwWQBlq24DKyspw4cIFpKen2/zaBoMBWVlZbv0xNSIwZzGYsxjMGUhPT8eFCxdQVlam2DpYAMVgAVQWC6AMtW1ARUVFOH/+PAoLC21+bf4iF4M5i8GcxWDOQGFhIc6fP4+ioiLF1sECKAYLoLJYAGWwtgDW5RcRf5GLwZzFYM5iMGd5v3etxQIoBgugslgAZWABVD/mLAZzFoM5swC6EhZAZbEAysACqH7MWQzmLAZzZgF0JXq9HnE7drAAKoQFUAYWQPVjzmIwZzGYMwugq9h7NhnvvL8GFyJ7YMIHsdh71r5XdrMAsgDKwgKofsxZDOYsBnNmAXQFe8/cQHTYFOi1foDOF3sinkZA8C67lkAWQBZAWVgArTd+/HhIkgRJktCjRw+7ve6SJUtMrytJks233HG1nJ2Vq+TsrNtxBVfJWQ4WQJXLT8fxqH8AOl9A54udEc/g/4K/RKeQXQhaesBuq2EBZAGUhQUQ2LRpk9kb193j6NGjAMrfOO+55x5s3rwZO3fulLWuEydOmB67cOECNm/ejOeff154AczLy4NWq8WgQYPg5+cHSZKwadMmm1+nwty5c6stFidPnsSgQYPQpEkTNG7cGAMHDsTp06erfJ3Lly/jxRdfRLt27eDl5YXu3btj9uzZKCgoqPPc5FLL9lyb6rbjGzdu4Nlnn0WTJk1w//3349tvv7V47rZt29CyZUtkZ2dbfE3udlyhLjnL3Y7PnTuHUaNGoXPnzvDy8kKLFi3Qt29fiwysXQ4Afv75Z7z11lt44IEH4O3tjQ4dOmD06NG4dOlSrfNhAVSxxEPAou6AzhdF2hYICfsXAoJ3IiB4FwKCdyEwfI/dVsUCyAIoCwtgZSmbM2cONm/ebDEq3sjGjx+PgIAAu6zrzgJYQafTCS+AiYmJkCQJHTt2RL9+/WQVwKSkJHh7e8PHx8eiAJ46dQqNGjVCt27dsGjRIrz//vvo1KkTfH19cfHiRbNlr1+/jmbNmiEgIADz58/H2rVrMWHCBEiShGHDhtVpbvaglu25NtVtxwMGDMB9992Hjz76CK+88go8PT2RmJho+npRURE6d+6MtWvX1vj6dd2OK9QlZ7nb8e7duzFo0CDMmjULMTExWLp0Kfr27QtJksy+X2uXA4AXXngBrVu3xvTp07Fu3TpERUXB398fPj4+OHv2bI3zYQFUIUMZ8ON8YFYzQOeLK9r78EzIR6biFxC8i3sAFcACKAMLYM2l7E6uWACLi4uRkpICADhx4oSsAvjiiy+if//+eOqppywK4LPPPgs/Pz9kZGSYHktOTkbjxo0xcuRIs2Wjo6MhSRLOnTtn9vi4ceMgSRJu375dp/nJpZbtGQDy8/Or/VpV23FhYSE8PDxw4ED5m5PRaETnzp2xZs0a0zJRUVF46KGHav3+5RTAp556CuPGjbM5Z3tuxxXKysrw4IMPonv37nVa7vDhwygpKTF77PLly/D09MQrr7xS42uyAKpMTjKwaYjpkO/XkcNwX/DX5aXvjvJXfg5giv1WywLIAigHC6B9CmDnzp2r/KXer18//P3vf7dqXY4ogHeS88Z54MAB1KtXD2fOnKmyADZp0gSjR4+2eN6QIUPQsGFD5OXlmR4LDg6uMofg4GBoNJoay01hYSG6d++O7t27m316TWZmJlq3bo3HH3+8xo/XqvgZXLhwAaNHj0aTJk3QvHlzvPPOOygoKLDI+ZdffkFQUBCaNGkCHx8f9O/f33TKAAD89ttvkCQJ33zzjemxkydPQpIk9OrVy2zdQUFB6NOnj+nfN27cwMSJE9GqVSs0bNgQDzzwADZs2FDtnBMSEjBmzBg0a9YMDz30ULXfY1Xb8e3btyFJEs6cOWN6rFevXli8eLFpLj4+PqaCWBNHFMA72asAAsBzzz0Hf39/uy0HAL1790bv3r1rXIYFUEUuxwMLu5Qf8p3VCjNCQxAQvAuvbjiOL36+hkFL/oeuITsxaMn/7Fr+ABZAgAVQFkcWwL1nkzFoyQEEhu/BoCUH7H6JvLUqStn333+P9PR0s3HnHqvqCmBeXh48PDzw/vvvW3ytefPmePvtty3WJacA6vV6szmmpqbiypUrSE1NtZi/LW+idX3jLCsrw1/+8hdMmTIFAKosgA0bNsS4ceMsnjt69Giz8ywBYO/evabDvadPn8b169fxxRdfwNfXFzNnzqx1PseOHUO9evXwr3/9y/TYSy+9BC8vr1rPv6r4GfTs2RNDhw7FypUrMXbsWEiShLFjx5ptz+fOnYOPjw/atGmDqKgoLFiwAJ07d4anpyeOHTsGoPz/gWbNmuE///mPaR1LliyBRqOBRqMx/X9nMBjg6+uLd999FwBw69YttG/fHh06dMCcOXOwevVqDBs2DJIkYcmSJVXO+YEHHsDw4cPx0UcfYdWqVdV+j9Vtx127dsVLL72Eq1ev4rPPPoOHhwd++uknAMDLL7+MUaNG1Zjd3fNRYwHMz89Heno6rly5gsWLF6NevXp4+eWX67zc3YxGI9q1a4dnnnmmxuVYAFWgTA/8N9K01++i7i/oF7IO3cL2YMOhqzAYjAB4I2ilsQDKUNcCaDQaUVBSWuPIKypBcmoG8opKLL4Wd/qG+e7x//ffuNM3an3dqobRaKxzBjVdBOLp6Wlarro3zqNHj0KSJOzbt8/s8aSkJEiShJiYGIt1ySmAP/74Y40Xrdw57jyHqzZ1feNcuXIlmjZtirS0NABVF8CePXsiMDDQbO9bSUkJOnbsCEmS8PXXX5stHxUVBS8vL7PvJTw83Oo5hYaGQqPR4ODBg/jqq68gSRKWLl1a6/MqfgZ3n2v45ptvQpIkHDp0yFRMRowYgYYNG+KPP/4wLZecnIwmTZqY7fUdMmSI2Z69kSNHYuTIkahXrx727t0LoHxP4p17CidNmoQ2bdqY/QEClBfZpk2bmu3drJjzmDFjrMqmuu14//79pgsoJEkyle3Dhw/Dy8sLf/75p1Wvr+YCOGXKFNP3r9FoMGrUqCpPObB2ubtt3rwZkiRVuSf3TiyATu72n8C6Aaby90n4CwgM3o6Bi/+H88nm76UsgMpiAZShrgWwoKTU7ORWR4+CktI6Z1BRylatWoX4+Hiz8cMPP5iWq+6Nc926dZAkCbdu3TJ7fNeuXZAkybQ36M51ySmAt2/fNpvjvn37sGPHDuzbt89i/ra8gdTljTMjIwPNmzfHokWLTI9VVQBXr14NSZIwfvx4JCQk4OzZs3jxxRfRoEEDSJKEzZs3my2/efNmDBo0CDExMdi2bRtee+01eHh4YMWKFVbNq6SkBD179kTnzp3RsmVLPPXUU1b9kVDxM7i7zF+4cAGSJEGr1cJgMKCsrAze3t745z//afEaU6ZMMdu7t2DBAtSvX9906LpVq1ZYv349Hn74YYSFhQEAli1bBg8PD2RmZsJoNKJZs2Z44403LPboVmw/FXvm7pyzNYdngZpPZcjLy8OxY8dw/fp1AOV7Jh9++GFEREQAAD766CN0794dgYGBWL16dY0Z2ronOz09HU888QRefPFFiz3aIvZkA+U/5/j4eHzyyScYMmQInn/+eYv/r21Z7u7n+Pr61noaAsAC6NTOfwvM7wDofJGna4MpoVoEBO+C7ptzKNJb/lxZAJXFAigDC6D8cwDfeeedKs//mTdvnsU5a652DuDUqVNx7733mp3sXlUBBICwsDBT4ZMkCY888gjCw8MhSRJ27NhhWu7zzz+Hl5cXkpKSzJ4/YcIEeHt7W+wVq+37adSoEa5evWrVcyp+Bncvr9frodFoMGHCBBgMBqSkpECSJERGRlq8xtKlS80uYjl8+DAkSUJ8fDwuXrwISZJw6dIl/Otf/0Lfvn0BAKNGjTJllpqaWuue3e3bt1vMuaK01caWi5nWr1+Pdu3aIT8/H/Hx8fDx8cGOHTsQFxcHb29vsz+Q7p6P2vZkV2XgwIF49NFHa/3jobblUlJS0KVLF3To0AE3b96sdb0sgE5IXwTsfte01++0tjeeDNmIh6Pi8cPF1OqfxgKoKBZAGRx1CHjg4v+ZDvveeYn8M0sOOOwQcF0LYP/+/as8p+ef//wn7r33XqvXZe0bZ0lJCVJSUkzj5s2buHjxIm7evGn2eEpKSq17Gu5k6xvn5cuXodFosHz5ciQmJprGY489hsDAQCQmJiIzM9PsObdv38ahQ4dMFxuEhoaaLmCo0LdvXzzxxBMW69u+fbupSFmj4p6EVe3Rq051BbC0tLTOBbCkpASNGjVCZGQk1q1bh1atWpm+H09PTxQXF8Pf3x9Tp04FANNrjx071mKPbsVITa18w7H1DwdrC2BOTg78/f1Ne2dfe+01jB8/3vT1cePGYdKkSRbPq+ue7Pj4ePzlL3/BwIEDLfZoK70nuzpr166FJEkWtyqyZbns7Gw89NBDaN68udl2XhMWQCeT/juw+klT+Vsd/jK6BsfhtU0/Iz2vuMansgAqiwVQBkddBLL3bLLZpfFKXCJvLbkFsGXLlmYXegDl3/s999xjcYsTVzoH0Jp5zJgxo8bXePTRR9G+fXuzbSQwMBCPPfaYxbJbt26FJEmm8+Zq8ttvv6Fhw4aYOHEievXqhQ4dOlR58+K72eMQ8NSpU80OAQPA3//+d/Tr1w/jxo3DCy+8AABIT083nQ8mSRJiY2MBlF9U06RJE6vP6VOqAP7nP//BX//6V9MfV0FBQQgNDTV9PSQkBEFBQbLncydHnwN4t4oyf/z48TotV1RUhL59+8Lb2xtHjhyxer0sgE7kty+B6LaAzhe3de0xPnQuAsP34NOjf1q144EFUFksgDI4+irgoKXlVwEHLT3gkPIHyCuAFYfrKt7UK1R8LJZOp7N6Xc5+DmBBQQEuXLhgml96ejp27NhhMXr06IGOHTtix44dZrcVudsXX3wBSZLMzh8Eym+p0bBhQ4srdkeMGAGNRlPrITS9Xo9evXqhU6dOyM3NNSuDtantIpCDBw+aXQRy982Sb926BV9fX7OLQAAgPDwcXl5e6NChg9nFKPfffz8CAwMhSZLZIe8JEyagYcOGVd4wuOJim7vnbM8CeOnSJXh6epoVmvHjx+P55583/Xv48OGYMGGCxXOduQDevQ1XuHOPagW9Xo/evXvDy8vLdJsia5cDyov8sGHDUL9+fezevdum74EF0AmU5ANxb5r2+h2NfAx9gj9F0NKDuHwr1+qXYQFUFgugDLwPYO2fBFJxlWdVb5zff/89JElCkyZNMG3aNCxbtgxjxoxB8+bNIUkSnnvuObtfBHI3uTmvWLECUVFRmDZtGiRJwsiRIxEVFYWoqCizvWYVe/zuLrV3q+ocwAMHDmDAgAFYuHAh1q9fj8mTJ6NevXoICgpCaWmpxbL16tVDq1atMGfOHKxatQqDBw+GJEmYPHlyrd+PVquFh4eH2flpFYeDa3sjvvs2MKtWrTLdBmbMmDFV3gamXbt2iI6OxsKFC9GlSxez28BU+O6770x7RU+dOmV6vOJq0k6dOpktf+vWLQQEBMDb2xszZszA2rVrMX/+fIwePRp+fn5VztmeBfDZZ5+1uG3Pzp07odFoEBoaarrKes8ey4+1clQBtGY7rm4bHjFiBPr3749Zs2aZPrXjvvvugyRJ+PDDD21eDgBmzJgBSZIwdOjQKn+v1IQF0MFuJQAr+wA6Xxh0TbEkfAI6B3+LubsSUFxq/Wk1AAug0lgAZWABrP2zgCv2JFT1xrlkyRLUq1cPu3fvRteuXdGoUSMMHDgQZ8+eRdeuXdG+fXuzN/yNGzdCkiT88ssvFvNwVAEMCAiw6hCynAJ45coVPPPMM7jnnnvg6emJ++67D/Pnz7f4pIQKx48fx+DBg9G6dWs0aNAAgYGBiI6OtiiLdzt16hTq16+P6dOnmz1eVlaGRx99FG3btkVWVla1z6/4GZw/fx6jRo1CkyZN4Ofnh7fffrvaG0EPGjQIjRs3hre3N/7xj39UeagvNzcX9erVQ5MmTczOy/zss88gSRJeffVVi+ekpqbirbfeQocOHdCgQQO0bt0aAwYMMLut0J1ztlcB3L17Nxo3bozkZMv7cs6fPx9t27ZFmzZtsHDhwiqf76gCaM12XN02/Pnnn+Ppp5+Gv78/6tevDz8/Pzz99NNmN/C2ZbmK76Wm3ys1YQF0EKMROLkJxqhWgM4Xt7Qd8VLoQjw6Nx4HL6fV/vwqsAAqiwVQBhZA640fPx4dOnRAenq6qURMmjQJ3bp1s/o1li1bBkmScOXKFdNjRUVFSE9Px3vvveeQAkiVaiovrpJzVduxPcjdjiu4Ss5ysAA6QFEO8NVE0yHfHyP6onfwFrz+yQlk5lf9h6o1WACVxQIoAwug9caPH2/6671iD1efPn0wfPhwq19j7Nix8PHxMduTVXG+YMVgAXQcdymAd2/H9iB3O67gKjnLwQIo2M1fgKUPAjpf6HV+iA6bgvsjdiP2+DVZd5gAWACVxgIoAwug9RISEkwXVxw9ehRGoxGNGzc2uzKyOl9//TXefvtteHh44PXXXzf72vXr180u3LD1F4Wr5exI7lAA796O7UXudlzBVXKWgwVQEKMROPoRjLNbADpfJGm7YETIEjy3/BCupOXV/nwrsAAqiwVQBhbAuvvjjz8gSZafYlGVTp06oUWLFpg8ebLZjaHtwdVzFskdCqCzY84sgEIUZAKxL5kO+e6NGIC/hHyBBXsvoKTUftseC6CyVFEA8/LyoNVqMWjQINPnbdZ2nyq9Xo/7778fkiThgw8+sPi6wWDAwoUL0alTJ3h6eqJnz56me4lZiwVQ/ZizGMxZDObMAqi4a0dh/PABQOeLEm1zRIZNx1+j43HkinWfMmQLFkBlqaIAJiYmQpIkdOzYEf369bOqAH744Yfw8fGptgCGhIRAkiS8/vrriImJwZAhQyBJEj7//HOr58UCqH7MWQzmLAZzZgFUjMEAHFwE4yw/QOeLq5Hd8GzISrz52SlkFyiTAwugslRRAIuLi5GSUn6jY2vuVJ+amoqmTZtizpw5VRbAGzduoEGDBnjrrbdMjxmNRvTt2xft27e3+iPAWADVjzmLwZzFYM4sgIrISwU+GW465Ls9YjAeidyOL09cl32hR01YAJWligJ4J2sK4MSJE9GnTx9cvXq1ygK4atUqSJJk8dmSsbGxkCQJhw4dsmouLIDqx5zFYM5iMGcWQLv740cY3r8X0PmiUHsP3g17F8NXHEJiun3Px64KC6CyXK4AHj9+HBqNBkeOHDEdOr67AE6ePBk+Pj4Wf7lcuXIFkiRh+fLlVs2FBVD9mLMYzFkM5swCaDdlpcD+KBh1TQGdLy5E9sDA0DX4cN9F6MvEbF8sgMpyqQJoNBrRp08f0wfBV1cAhwwZgi5dulg8v6CgAJIkISQkpMp1FxcXIycnxzSSkpIgSRIyMjKg1+stRl5eHhISEpCfnw+DwWDTKCsrQ1ZWFsrKymx+LgdzdrbBnJmzqJGfn4+EhATk5eVV+XvZHqOgoABxcXEoKChQbB0OHRl/omzdM6ZDvlvCh+Mf83bjyO+pQuehZM4ZGRksgI6egK1qKoAbN26El5cXrl+/DqD6Ati/f3/cf//9Fs83GAyQJAkzZsyoct0Vt7m4e8TGxiIuLs5ifPPNNzh+/DiuXbuGrKwsDg4ODg6Fx7Vr13D8+HF88803Vf5e5qh5HP1Eh6I5bQGdL3K1/ng7NAwjP/gWn3/t+LnZc1Sc8sUCqCLVFcCcnBz4+/tDq9WaHnP0HkC9Xo+kpCQkJCQgKSkJ2dnZyM/PR0FBQa0jPz8fqampVi/PUbfBnJmzKw13zTk/Px/Z2dlmv2/VumfKYaMoH2V7gk17/X6LfBBB2o/x1YlrDpuTkjlzD6ALFcDIyEj4+fkhISEBiYmJSExMxKFDhyBJEsLCwpCYmIiSkvLPJJw8eTK8vb0VPwcQKD8snZWVhUuXLuH8+fNWj4SEBJw8eRIJCQk2PY/DtsGcmbMrDXfP+dKlS8jKylL0ylTABc8BzLyK0jVPmcrf+vAX8eKqH3E9s8Ch01IyZ54D6EIFcPwdn9FZ3Th9+jQAYOXKlVVeBbxlyxZIkoSDBw9aNRdbNiCj0YjS0lIUFRVZNXJzc7Fr1y7k5uZa/RwO2wdzZs6uNNw559LSUsWLXwWXKoBnt6F0bjtA54ssbRu8HjYby76/jFJBF3rUhAVQWS5TAE+dOoUdO3aYjbVr10KSJEyYMAE7duxAdnY2ACApKana+wC2a9fObvcBlMOlfsE4MeYsBnMWgzmL4RI56wtR9s07pr1+P0c+ghfmb8Wpa7cdPTMTFkBlqaYArlixAlFRUZg2bRokScLIkSMRFRWFqKgoU7G7W3XnAALAe++9B0mS8MYbb2DdunWmTwLZsmWL1XNiAVQ/5iwGcxaDOYuh+pzTLqFk+WOAzhcGbVOsCH8V735xEnnFpY6emRkWQGWppgAGBARUe2g3MTGxyufUVAANBgPmzZuHgIAANGzYED169MBnn31m05xYANWPOYvBnMVgzmKoOWfjL5+hdI4/oPNFmrY93tAtxLe/3nT0tKrEAqgs1RRAZ8QCqH7MWQzmLAZzFkOVORfnoeTLyaZDvociHsfrq3bhRlaho2dWLRZAZbEAysACqH7MWQzmLAZzFkN1OaecQcGHDwE6X5Rpm2JR+GR89MNFlBnEXDRTVyyAymIBlIEFUP2YsxjMWQzmLIZqcjYaUXosBqWz7gF0vkjWdsL0BSvxW1KWo2dmFRZAZbEAysACqH7MWQzmLAZzFkMVORdmIe/Tl0yHfOMjnsLsLw6goMS5LvSoCQugslgAZWABVD/mLAZzFoM5i+HsORuTTiBvwf2AzhclWj98MGs69p5xzgs9asICqCwWQBlYANWPOYvBnMVgzmI4bc4GAwp+XIJSnR+g88W1yK6IWPUxUrKLHD2zOmEBVBYLoAwsgOrHnMVgzmIwZzGcMuf8DGSuHWY65Lsr8hls2v8rDE5+oUdNWACVxQIoAwug+jFnMZizGMxZDGfLueTKAeTM7QLofFGkbYHF80Nw7oY6LvSoCQugslgAZWABVD/mLAZzFoM5i+E0ORvKkL5rNsp0zQCdL36PvA8rYuNQWGLdx5k6OxZAZbEAysACqH7MWQzmLAZzFsMZcjbmJCN52QDTId9vZg3HD2euOmw+SmABVBYLoAwsgOrHnMVgzmIwZzEcnXPWmT3Imd0R0PkiX9sSq5fPRWquOi/0qAkLoLJYAGVgAVQ/5iwGcxaDOYvhsJzL9Pjzi/dMe/0uaP8PX+/7QdUXetSEBVBZLIAysACqH3MWgzmLwZzFcETORemJuP7+E5WHfKNfwsWkVGHrdwQWQGWxAMrAAqh+zFkM5iwGcxZDdM7XD29Frq4NoPNFjrY1tn6yAkV617jQoyYsgMpiAZSBBVD9mLMYzFkM5iyGqJwNJUU4t36Kaa/fWd3DOHrypKLrdCYsgMpiAZSBBVD9mLMYzFkM5iyGiJwz/kzA1bm9TeVv74eTkJGdq9j6nBELoLJYAGVgAVQ/5iwGcxaDOYuhdM5n9qxDvq4VoPPFbW07fP/tZhiNrnmhR01YAJXFAigDC6D6MWcxmLMYzFkMpXIuzKNv4tAAACAASURBVM/FiWUvm/b6nYl6Alf/uGTXdagJC6CyWABlYAFUP+YsBnMWgzmLoUTOl88cR+LsHoDOFwZtUxxc+y8UlxTb7fXViAVQWSyAMrAAqh9zFoM5i8GcxbBnzoYyA/4X+wEKtfcAOl+k6QJw5uC3dpil+rEAKosFUAYWQPVjzmIwZzGYsxj2yjklNRU/LRhmOuR7bsEAZKXesNMs1Y8FUFksgDKwAKofcxaDOYvBnMWwR84/HYjHn7pAQOeLUm0znI7VwWhw/Xv72YIFUFksgDKwAKofcxaDOYvBnMWQk3N+kR5xayJQrG0O6HyROrsrbpz50f6TdAEsgMpiAZSBBVD9mLMYzFkM5ixGXXM++3siDs4ZaDrke2npUJTkZio0S/VjAVQWC6AMLIDqx5zFYM5iMGcxbM25zGDE1zu+xg1tF0DnixJdc1zd9SHghvf2swULoLJYAGVgAVQ/5iwGcxaDOYthS85JmXn47IMZKNU2Kz/kO/d+5P5xQsAs1Y8FUFksgDKwAKofcxaDOYvBnMWwNufvjv2Gn3R9TYd8r8WMgbHIfQuHrVgAlcUCKAMLoPoxZzGYsxjMWYzacs4t0mPVhg1I1XYEdL4o1rVE+sF1PORrIxZAZbEAysACqH7MWQzmLAZzFqOmnE9eTcWmqEkwaJsCOl+kL3wI+uRzDpil+rEAKosFUAYWQPVjzmIwZzGYsxhV5VxaZsC6XQdxPLKP6ZBv2pY3gJICB85U3VgAlcUCKAMLoPoxZzGYsxjMWYy7c76WUYC5ixcjU9sW0PmiaHZrFJz6wsGzVD8WQGWxAMrAAqh+zFkM5iwGcxajIueSkhJsP/EHNmlfNu31y1r8VyDjiqOn6BJYAJXl9AUwLy8PWq0WgwYNgp+fHyRJwqZNm8yWMRgM2LRpE4YOHYr27dvD29sbPXr0QFRUFIqKiqp83fXr1+O+++6Dp6cn7r33XixfvtzmubEAqh9zFoM5i8GcxdDr9Yj9Og6Rm3bidGQvU/nL3fFvoLTY0dNzGSyAynL6ApiYmAhJktCxY0f069evygKYl5cHSZLw17/+FXPnzkVMTAwmTpwIjUaDfv36wXjXlVdr1qyBJEl44YUXEBMTg1dffRWSJGHBggU2zY0FUP2YsxjMWQzmLMZPl2/h3cgI5Ghblx/yjWqPsoSdjp6Wy2EBVJbTF8Di4mKkpKQAAE6cOFFlASwpKcHhw4ctnjt79mxIkoT4+HjTY4WFhWjRogWGDBlituwrr7wCHx8f3L592+q5sQCqH3MWgzmLwZyVpS8z4MM9v+LTiJGmvX55q/4BZF139NRcEgugspy+AN6pugJYnTNnzkCSJLPDu7t374YkSdi9e7fZskeOHIEkSdi8ebPV82EBVD/mLAZzFoM5K+dqej6mLYnF+cj/M5W/wj0RQBmzVgoLoLJcugD+97//hSRJiI2NNT02d+5cSJKE1NRUs2VLSkqg0Wjw73//2+r5sACqH3MWgzmLwZztz2g0YuvP1xEcGYJ8bcvyGzvP64TDn0YxZ4WxACrLpQvg008/DV9fX2RlZZkee+utt1CvXr0ql2/ZsiVeeumlal+vuLgYOTk5ppGUlARJkpCRkQG9Xm/XUVBQgLi4OBQUFNj9tTmYM3N2zcGc7TvSsgswfdMBfB0xxLTXr2jdYBSkXmXOAoaS23NGRgYLoKMnYAtbCmB0dDQkScJHH31k9vhrr70GLy+vKp/ToUMHDB8+vNrX1Ol0kCTJYsTGxiIuLo6Dg4ODw0XG+598gxciV+FKZHdA5wuDrikSVk9E3I7tDp8bh/wRGxvLAujoCdjC2gL4xRdfwMPDA5MmTbL4GvcAcjBn5uyqgznLH/mFxYj69izCwmaiWNsC0PmiZGEgSq/8jzkLHtwDqCyXK4D//e9/0bBhQzz33HMoLS21+DrPAaQ7MWcxmLMYzFme31Pz8M+le7Ar4mnTId+yzaOA/Ayz5ZizGErmzHMAXawAHjt2DD4+PnjiiSdQWFhY5TK7du2q8irgw4cPQ5IkfPrpp1bPhwVQ/ZizGMxZDOZcN0ajEZ8d+xMvRKzAtciu5Yd8Z7UADq8A7rqPLMCcRWEBVJbLFMDz58+jRYsW6NGjR4338issLETz5s3x3HPPmT0+duxYeHt7IzMz0+r5sACqH3MWgzmLwZxtl5FXjEmbfsacsGko0foBOl+ULv4/IOlktc9hzmKwACpLFQVwxYoViIqKwrRp0yBJEkaOHImoqChERUUhOzsbubm56NChAzQaDRYsWIDNmzebjSNHjpi93qpVqyBJEkaNGoV169Zh3LhxkCQJ0dHRNs2LBVD9mLMYzFkM5mybA5fSMCBqG76PeMp0yNe4dRxQlF3j85izGCyAylJFAQwICKjy6ltJkpCYmGj6uLjqxvjx4y1eMyYmBt27d0fDhg3RtWtXLFmyxOIj42rDAqh+zFkM5iwGc7ZOkb4Ms79NwKiQRUjWdio/5DunJXBiQ5WHfO/GnMVgAVSWKgqgs2IBVD/mLAZzFoM51+7SrVwMXvwDPgibhDJt0/Lyt/xhIOWs1a/BnMVgAVQWC6AMLIDqx5zFYM5iMOfqGY1GfHw4EU+Gb8FPEY+bDvli+1SgOM+m12LOYrAAKosFUAYWQPVjzmIwZzGYc9XScosxYeNxjA2dhzRt+/Jz/ea2Bk7H1v7kKjBnMVgAlcUCKAMLoPoxZzGYsxjMudLes8kYtOQAuobuRmBIHFaFj6280OOjx4G0S3V+beYsBgugslgAZWABVD/mLAZzFoM5l9t7NhkBwbsQELwLjwd/jBORj1Qe8t35L0Bf9X1ircWcxWABVBYLoAwsgOrHnMVgzmIw53L/+OBHBATvwuTQWcjStgF0vsjR+mPu+/Ps8vrMWQwWQGWxAMrAAqh+zFkM5iwGcwa+PpmEbsE7sCH8n6a9fqcje+HJkI0IDN9jl3UwZzFYAJXFAigDC6D6MWcxmLMY7pxzfnEp/r31V/w9ZD3ORP7FVP7Who/BvcFx6BSyC0FLD9hlXe6cs0gsgMpiAZSBBVD9mLMYzFkMd835fHIO+i/6EW+HhiFX6w/ofJGpbYuJYVEICN6FTiHl5wPuPZtil/W5a86isQAqiwVQBhZA9WPOYjBnMdwtZ6PRiM+O/Yme4TsQGz688kKPjYPxw/FfELT0AALD9yBo6QG7lT/A/XJ2FBZAZbEAysACqH7MWQzmLIY75ZxTpMebW05hQMgaXIx8oPz2LrqmwA/RQFmpout2p5wdiQVQWSyAMrAAqh9zFoM5i+EuOf96PQt9F+zHu2HvolB7T3n5+6Ab8Mf/hKzfXXJ2NBZAZbEAysACqH7MWQzmLIar52w0GrHu4B94MOxr7IgIqjzk++kIIC9N2DxcPWdnwQKoLBZAGVgA1Y85i8GcxXDlnG/nl2DSxz/j2ZAVuBrZrXyv3yw/4NBiwGAQOhdXztmZsAAqiwVQBhZA9WPOYjBnMVw1558TM/HX6Hhow6ajRNu8vPwtfgC4dswh83HVnJ0NC6CyWABlYAFUP+YsBnMWw9VyNhiMWPnD73godCu+i+hfecg3dgxQkOmweblazs6KBVBZLIAysACqH3MWgzmL4Uo5p+UWY+z6Y3g+ZDGStF3K9/rNuQc4tgYwGh06N1fK2ZmxACqLBVAGFkD1Y85iMGcxXCXnQ5fT8cicfZgf9gZKtc3Ky9+yh4Cbpx09NQCuk7OzYwFUFgugDCyA6secxWDOYqg959IyAxbtu4iHQ7bgfxF/qzzk+9VrQJHzvFGrPWe1YAFUFgugDCyA6secxWDOYqg55+TsQoxefQQvhS5EqrZj+V6/KH/g1CcOP+R7NzXnrCYsgMpiAZSBBVD9mLMYzFkMtea8/8ItPDxrD5aGj4dB27R8r9/KPkDqeUdPrUpqzVltWACVxQIoAwug+jFnMZizGGrLuaTUgKidCegT/CmORfapPOT7zdtASYGjp1ctteWsViyAyrK5AGZmZsoaZWVlSnwfDsECqH7MWQzmLIaacr6eWYBhKw5hQmgUMrVtyw/5RrcFznzl6KnVSk05qxkLoLJsLoAeHh7QaDR1Hvv371fi+3AIFkD1Y85iMGcx1JLz7jPJeEi3C2vCx1Tu9VvTF8i44uipWUUtOasdC6Cy6lQAR44ciVmzZtk03nvvPRZAG/AXjBjMWQzmLIaz51ykL0P4jjN4MmQjTkf2qix/e/4/oLTY0dOzmrPn7CpYAJVVpwK4ZcsWm1eUkZEBDw8PFkAr8ReMGMxZDOYshjPnfCUtD4OWHMCUUC1ytK3LD/nO7wCc3+noqdnMmXN2JSyAyrK5AC5duhSXLl2yeUXFxcVYunQpbty4YfNznRULoPoxZzGYsxjOmvO2U0l4MPIbfBo+snKv37qngaxrjp5anThrzq6GBVBZvApYBhZA9WPOYjBnMZwt54KSUvzny1/xj5AYJET2rCx/8TqgzDnmWBfOlrOrYgFUFgugDCyA6secxWDOYjhTzueTc9B/0Y+YGRqMfG3L8kO+C7sAv8c7emqyOVPOrowFUFl1KoCnTp2yafz666+4evUqDAaDvefvUCyA6secxWDOYjhDzkajEVuOXcND4dvxVcRzlXv9Pn4OyE1x2LzsyRlydgcsgMqqUwGs661gmjRpgqlTp6KwsNDe34dDsACqH3MWgzmL4eicc4r0eHPLKQwK+Qi/R95XvtdvVjPgfwsBg+vcA9bRObsLFkBl1akAfvzxxzaNTZs2Yfny5Rg7diw0Gg2mTJli0/ry8vKg1WoxaNAg+Pn5QZIkbNq0qcplz58/j0GDBsHHxwd+fn4YO3Ys0tLSLJYzGAxYuHAhOnXqBE9PT/Ts2ROxsbE2zYsFUP2YsxjMWQxH5vxbUhb6LtiPsLCZKNa2KC9/i7oDiT8Jn4vSuD2LwQKoLOHnAL799tto2bKlTc9JTEyEJEno2LEj+vXrV20BTEpKwj333IOuXbti2bJliI6Ohp+fHx588EGUlJSYLRsSEgJJkvD6668jJiYGQ4YMgSRJ+Pzzz62eFwug+jFnMZizGI7I2Wg0Yv2hq3go7CvsjBhYecj3s9FAfoaweYjE7VkMFkBlyS6A/fr1w4wZM7B+/Xr8/PPPFod3f/75Z5w+fdr0723btqFz5842raO4uBgpKeXnjpw4caLaAjht2jR4eXnh2rXKWwvEx8dDkiSsXbvW9NiNGzfQoEEDvPXWW6bHjEYj+vbti/bt21v9cXUsgOrHnMVgzmKIzvl2fgkmfXwCQ0OW4Vpk1/K9frObA4dXAC52zveduD2LwQKoLLsUwBYtWpjOC6xfvz4CAwMxatQozJ49G8OGDUPHjh3tMVcANRfAVq1aYfTo0RaPBwYGYsCAAaZ/r1q1CpIkISEhwWy52NhYSJKEQ4cOWTUXFkD1Y85iMGcxROZ8IjETf42Ox5ywaSjR+pWXvyU9gaSTiq/b0bg9i8ECqCy7HQK+ceMGdu/ejfnz5+PFF19Ey5YtTaWwW7du9lpNtQXwxo0bkCQJCxcutHjO2LFj0bx5c9O/J0+eDB8fHxiNRrPlrly5AkmSsHz5cqvmwgKofsxZDOYshoicDQYjVv7wOx4O/RzfRzxVech366tAYZZi63Um3J7FYAFUlmLnABqNRixZsgQtWrSw2NMmR3UFsOLxTz/91OI57733HiRJQnFx+WdNDhkyBF26dLFYrqCgAJIkISQkpMp1FxcXIycnxzSSkpIgSRIyMjKg1+vtOgoKChAXF4eCggK7vzYHc2bOrjmUzjn5dh5ejjmKUSGLkKztVL7Xb05LlB1dC31JicO/f1fJmUP5nDMyMlgAlV7Byy+/jKCgILu9XnUF8ODBg5AkCVu3brV4TmRkJCRJQlZW+V+n/fv3x/3332+xnMFggCRJmDFjRpXr1ul0kCTJYsTGxiIuLo6Dg4PDZcfCT77BgxHf4IOwSSjTNgV0vsid1x0/xC53+Nw4OGwdFad8sQAqaPny5fD29rbb63EPIAdzVt9gzurNubCoGO/vPY9HQzbjp4jHTYd8DV+/Dn3+bYd/z66SM4fYnLkH0A4F8NVXX8WHH36I+Pj4Ku+39+abb+Lee++VuxoTe50D6O3tzXMAiTkLwpzFsHfOydmFGL36CMaGzkOatn35Id+5rYHTW+zy+mrF7VkMJXPmOYB2KICdO3eGRqMxXfDRpk0bBAUF4Z133sHo0aPRtGlT7N271x5zBVDzVcAtW7as9irg/v37m/69cuXKKq8C3rJlCyRJwsGDB62aCwug+jFnMZizGPbMef+FW3h41h6sDB9beaHHR08AaZfsMFN14/YsBgugsuxyCDg/Px/Hjh3D+vXrMWPGDAwYMACtWrWCh4cHPDw80KBBA3Tv3h3PP/88wsPDbf7EjTvVVACnTp0KLy8vXL9+3fTY999/D0mSsHr1atNjSUlJ1d4HsF27drwPoBthzmIwZzHskXNJqQFzdyXg8eCPcSLykcryt3MmoHeNj/GUi9uzGCyAylL0HMC0tDTs378fS5cuxeTJk/HYY4+hSZMm0Gg0Nr/WihUrEBUVhWnTpkGSJIwcORJRUVGIiopCdnY2AOD69eto0aIFunbtiuXLl2PevHnw8/NDz549Tef/Vag4L/CNN97AunXrTJ8EsmWL9Yc2WADVjzmLwZzFkJvz9cwCDFv5EyaFzkaWtk35Id957YBz2+08U3Xj9iwGC6CyhH8UHABcvXrV5ucEBARUeQWuJElITEw0LXfu3Dk888wz8Pb2RrNmzfDKK6/g1q1bFq9nMBgwb948BAQEoGHDhujRowc+++wzm+bEAqh+zFkM5iyGnJx3n0lGL91ObAj/Z+Vev7X9gEzbf1+7Om7PYrAAKsshBdBVsACqH3MWgzmLUZeci/RlCN9xBn8PWY8zkX+pLH/fhQGlJbW/gBvi9iwGC6CybC6APXv2xO7du21eUXZ2Nnr27Injx4/b/FxnxQKofsxZDOYshq05X0nLQ9DSg3g7NAy5Wv/yQ74LOgGXvlN4purG7VkMFkBl2VwAPTw86nQRR0ZGBjw8PLB//36bn+usWADVjzmLwZzFsCXnbaeS0CsyDrHhwyv3+m0IArJvCJipunF7FoMFUFl1KoCtWrVC586dbRoBAQHQaDQsgFbiLxgxmLMYzFkMa3IuKCnFf778FQNC1uBi5APle/10TYH9c4GyUoGzVS9uz2KwACrL5gI4YcIEWePChQtKfB8OwQKofsxZDOYsRm05X0jJwYBFP+LdsHdRqL2nvPx90A3440eh81Q7bs9isAAqixeByMACqH7MWQzmLEZ1ORuNRsQev4Ze4duwIyKo8pDvJ8OBvFQHzVa9uD2LwQKoLBZAGVgA1Y85i8Gcxagq59wiPd7acgrPhqzA1chu5Xv9ZvkBBz8EDAYHzla9uD2LwQKoLBZAGVgA1Y85i8Gcxbg759+SstB3wX5ow6ajRNu8vPx9+ABw7aiDZ6pu3J7FYAFUFgugDCyA6secxWDOYlTkXFJSgg2HrqJ32FZ8F9G/8pBv7EtAQaajp6l63J7FYAFUFgugDCyA6secxWDOYuj1emz5Kg6vbTqO50MWI0nbpXyv35x7gKOrAaPR0VN0CdyexWABVBYLoAwsgOrHnMVgzmIc/T0VD0V+g/lhb6BU26y8/C19ELj5i6On5lK4PYvBAqgs2QXw2LFj9piHKrEAqh9zFoM5K8tgMGLlD7/j0dBY/C/ib5WHfL+aCBS57xucUrg9i8ECqCzZBdDDwwPdunXDnDlz8Mcff9hjTqrBAqh+zFkM5qyctNxijF1/DC+FLkSqtmP5Xr8of+DkxzzkqxBuz2KwACpLdgHcsmULnn32WTRo0AAajQZPPPEEVq9ejcxM1z/RmAVQ/ZizGMxZGYd/T0efqO+wNHwCDNqmgM4XOfPvh/7Gb46emkvj9iwGC6Cy7HYOYHp6OlasWIHHH38cHh4e8PT0xPDhw/HVV1+hpKTEXqtxKiyA6secxWDO9lVaZsCH+y7isZBPcTTyMdMhX8P2adi5fStzVhi3ZzFYAJWlyEUgV65cwZw5c9C9e3doNBr4+fnh9ddfx6FDh5RYncOwAKofcxaDOdtPSnYRRq85gvGhUcjQtis/5BvdFvjtS+YsCHMWgwVQWYoUwJs3b2LRokV48MEH4eHhgebNm6NVq1bQaDR45JFHkJCQoMRqhWMBVD/mLAZzto/9F27hkVm7sCZ8TOWFHqv/BmRcAcCcRWHOYrAAKstuBTA3NxcbN27EgAEDUL9+fTRs2BDDhw/Htm3boNfrUVZWhq+++godO3ZEnz597LVah2IBVD/mLAZzlqek1IDo3efxZMhGnI7sVVn+dr8HlBablmPOYjBnMVgAlSW7AMbFxWH06NHw8vKCh4cH+vTpg5UrVyIjI6PK5WNiYtCgQQO5q3UKLIDqx5zFYM51dz2zAMNW/oQpoVrkaFuXH/Kd3wE4/63FssxZDOYsBgugsuxyG5iOHTsiLCwMFy9erHX548ePY8KECXJX6xRYANWPOYvBnOtmz5lk9NZ9i0/DR1bu9Vs3AMi6VuXyzFkM5iwGC6CyZBfAH3/80Q7TUCcWQPVjzmIwZ9sU6csQseMs/hESg4TInpXl779aoKz6DJmzGMxZDBZAZfGj4GRgAVQ/5iwGc7beH2l5CFp6EDNDg5GvbVl+yHdhF+ByfK3PZc5iMGcxWACVZZdDwBqNpsbh7e2NwMBATJkyBVeuXLHHvJ0CC6D6MWcxmLN1tv+ShIcjd+CriOcq9/ptGgLkJFv1fOYsBnMWgwVQWbILoE6nw0MPPYQGDRpg2LBh+Pe//41///vfGDp0KBo0aIDevXvj3XffxYgRI9CwYUP4+vri119/tcfcHY4FUP2YsxjMuWYFJaV498tfMSjkI/weeV/5Xr9ZzYAfFwCGMqtfhzmLwZzFYAFUluwCuHbtWrRv377KzwH+/fff0a5dO2zcuBEAcPnyZbRo0QLPPvus3NU6BRZA9WPOYjDn6l1MycWART8iLGwmirUtysvfou5Aou03zmfOYjBnMVgAlSW7AN57772YP39+tV+fN28eunXrZvp3eHg4mjVrJne1ToEFUP2YsxjM2ZLRaETs8WvoHf41dkYMrDzk+9koID+9Tq/JnMVgzmKwACpLdgFs1KgRPvjgg2q//v7776NRo0amf69btw5eXl5yV+sUWADVjzmLwZzN5Rbp8XbsLxgasgzXIruW7/Wb3Rw4vBwwGOr8usxZDOYsBgugsmQXwIcffhhdunTBrVu3LL6WkpKCzp074+GHHzY9Fhoais6dO8tdrVNgAVQ/5iwGc650Jikbf1+4H3PCpqFE61de/pb8H5B0QvZrM2cxmLMYLIDKsst9ABs1aoTGjRtj7NixmDVrFmbNmoWxY8eicePG8PT0NN0rsKioCG3atMFrr70md7VOgQVQ/ZizGMy5/JDvxp+u4tGwz/F9xFOVh3y/GAsUZtllHcxZDOYsBgugsuxyH8BffvkFQ4cOhbe3Nzw8PODh4QEvLy8MHToUp06dsscqnBILoPoxZzHcPeesghJM/uQERoUsQrK2U/levzktgeMxgNFot/W4e86iMGcxWACVZdcbQRsMBqSkpCAlJQUGGeexqAULoPoxZzHcOeeTf2biyeh9+CBsEsq0TcvL3/LeQPJvdl+XO+csEnMWgwVQWbIKYEFBAXr37o3Vq1fbaz6qwgKofsxZDHfM2WAwYtWPv6NP6BYcini88pDvtjeA4jxF1umOOTsCcxaDBVBZsvcA+vn5Yc2aNfaYi2yXL1/Giy++iHbt2sHLywvdu3fH7NmzUVBQYLbc4cOH8eSTT8LLywv+/v6YPn068vJs/4XMAqh+zFkMd8s5Pa8YY9cfwyuh85GmbV++129ua+D0FkXX6245OwpzFoMFUFmyC+CYMWPw/PPP22Musly/fh3NmjVDQEAA5s+fj7Vr12LChAmQJAnDhg0zLXf69Gk0atQIvXr1wurVqxEeHg5PT08EBQXZvE4WQPVjzmK4U86Hf0/HY1HfYWX4WBgqDvmu+iuQdlHxdbtTzo7EnMVgAVSW7AJ4/vx59OjRA2PHjsWhQ4dw48YNZGZmWgylRUdHQ5IknDt3zuzxcePGQZIk3L59GwAwePBgtGnTxuyHvm7dOkiShH379tm0ThZA9WPOYrhDzqVlBny47yKeCPkYJyIfqTzku3MmoC8UMgd3yNkZMGcxWACVJbsAVlz16+HhAY1GU+1QWnBwMCRJQnp6usXjGo0G+fn5yMnJQf369fHee++ZLVNSUoLGjRtj0qRJNq2TBVD9mLMYrp5zSnYRRq85gkmhs5GlbVO+129eO+DcdqHzcPWcnQVzFoMFUFmyC6BOpzPd+6+mobS9e/eaDveePn0a169fxxdffAFfX1/MnDkTAPDTTz9BkiRs3brV4vl/+9vf0Lt3b5vWyQKofsxZDFfO+YcLqegzezc2hP+zcq/f2qeAzKvC5+LKOTsT5iwGC6Cy7HobGEeLioqCl5cXJEkyjfDwcNPXv/rqK0iShIMHD1o8d/To0WjdunWNr19cXIycnBzTSEpKgiRJyMjIgF6vt+soKChAXFwcCgoK7P7aHMyZOdvheyoqxpxvz+LvIetxJvIvpvJXticY+qJ85uzCgzmrP+eMjAwWQHu9UHFxMY4cOYK4uDiLw7CibN68GYMGDUJMTAy2bduG1157DR4eHlixYgUA4NNPP4UkSTh+/LjFc1999VU0bdq0xtfX6XRm5bJixMbGIi4ujoODw03Ghi/i8PeonXg7NAy5Wn9A54viOW1w9BOdw+fGwcFR+4iNjWUBtMeLLFu2DH5+fqbz/fbv3w8ASE9PR4sWLbBhwwZ7rKZGn3/+Oby8vJCUlGT2+IQJE+Dt7Y2MjAzuAeRgzsxZ9th5OgmP6L5BbPhw014/bqI+rwAAIABJREFUw/pnoM9IdPjcXClnZx7MWf05cw+gHQrgxo0b4eHhgTFjxmDTpk3w8PAwFUCgvFgNHDhQ7mpq1bdvXzzxxBMWj2/fvh2SJCE+Pp7nAJIF5iyGK+RcpC9DZNxZDAhZg4uRD5Rf6KFrCuyPAspKHT09AK6RsxowZzGUzJnnANqhAPbo0QMjRowAAGRkZFgUwAULFqBt27ZyV1OrwMBAPPbYYxaPb926FZIkYe/evcjOzq7xKuDXXnvNpnWyAKofcxZD7Tn/kZaHwUsO4N2wd1Govae8/L1/L3DlB0dPzYzac1YL5iwGC6CyZBdAT09PrF27FkDVBTAmJgaenp5yV1Or5557Dg0bNsSlS5fMHh8xYgQ0Gg1u3rwJAAgKCkKbNm2Qm5trWmb9+vWmkmgLFkD1Y85iqC3nvWeTMWjJAQSG78Hj875Hr/Bt2BERVHmV7yfDgbxUR0/TgtpyVivmLAYLoLJkF0B/f39ER0cDqLoAzpw5EwEBAXJXU6sDBw6gXr16aNWqFebMmYNVq1Zh8ODBkCQJkydPNi136tQpeHp6mn0SSKNGjfDMM8/YvE4WQPVjzmKoKee9Z5MRELwLnYJ3ISB4F54NWYGrkd3K9/rN8gMOLgIMBkdPs0pqylnNmLMYLIDKkl0AJ06ciICAAGRlZVkUwHPnzsHHxwfTp0+XPVFrHD9+HIMHD0br1q3RoEEDBAYGIjo6GqWl5ufnHDp0CE888QQaNWqEli1b4q233jLbI2gtFkD1Y85iqCnnQUsO/L/ytxPasOko1jYHdL5IndUFuHbU0dOrkZpyVjPmLAYLoLJkF8CbN2+iffv2aNeuHaZOnQqNRoNx48bhlVdeQaNGjdC5c2eH3RZGaSyA6secxVBTzl1Dd6Nn8BfYGzHAdMj3vxH/wKPhXzp6arVSU85qxpzFYAFUll1uA5OamopJkybBz8/P9LFwvr6+mDhxIlJTne88GXthAVQ/5iyGGnIuLCnDu1/+iudDFiNJ2wXQ+aJE64dZYW+hU8hOBC094Ogp1koNObsC5iwGC6Cy7P5JIGlpabh16xYMTnqOjD2xAKofcxbD2XP+PTUXz3z4A+aFTUGpthmg80WithueC1mOTiHl5wLuPZvi6GnWytlzdhXMWQwWQGW51EfBicYCqH7MWQxnznn7L0l4MvIL/C/ib6ZDvsnrX8LIJXsRGL4HQUsPqKL8Ac6dsythzmKwACrLrgUwLy8P169fx7Vr1yyGK2IBVD/mLIYz5lykL0Pw17/hpdCFuKXtWH6Vb1Qr4OTHgNHo6OnViTPm7IqYsxgsgMqSXQCLiooQEhKCli1bmj4KrqrhilgA1Y85i+FsOV9Jy8PgxT9gafgEGLRNy8vfyj7ArQRHT00WZ8vZVTFnMVgAlWWX28BoNBqMHDkSS5Yswccff1zlcEUsgOrHnMVwppzjTt/AU5FbcDTyscobO8e9CZTkO3pqsjlTzq6MOYvBAqgs2QWwadOmeOONN+wxF9VhAVQ/5iyGM+RcpC9DyLYzGB8ahQxtO0DnC8PcNsBvlp8NrlbOkLM7YM5isAAqS3YBbNasGdasWWOPuagOC6D6MWcxHJ3z1fR8PLdkP9aEjzHt9TOufhJI/90h81GKo3N2F8xZDBZAZckugOPHj8eoUaPsMRfVYQFUP+YshiNz/vbXmxgY+QlOR/aqPOS7+11AXyR8Lkrj9iwGcxaDBVBZsgvglStX0Lt3b7z++us4efIk0tLSkJmZaTFcEQug+jFnMRyRc5G+DOE7zmBKqBY52tblh3zndQASvhE2B9G4PYvBnMVgAVSW7AJY8ckfHh4evArYjvgLRgzmLIbonBPT8zF86ff4NHxk5SHfmAHA7T+FrN9RuD2LwZzFYAFUluwCqNPpMGvWrFqHK2IBVD/mLIbInHf9lowh2o1IiOxZecj3v5FAmev/jLk9i8GcxWABVBY/CUQGFkD1Y85iiMi5uLQMkXFnMTM0GPnaloDOF2ULOgOX4xVbp7Ph9iwGcxaDBVBZdiuAxcXFOHLkCOLi4pCenm6vl3VqLIDqx5zFUDrnaxkFeGFZPL4Mf86018+w8VkgJ1mR9Tkrbs9iMGcxWACVZZcCuGzZMvj5+ZnO99u/fz8AID09HS1atMCGDRvssRqnwwKofsxZDCVz3ns2GSN1a/F75H3l5/rNagb8uAAwlNl9Xc6O27MYzFkMFkBlyS6AGzduhIeHB8aMGYNNmzbBw8PDVAABYPTo0Rg4cKDc1TglFkD1Y85iKJFzSakBurizCA37F4q0LcoP+b4fCCQests61IbbsxjMWQwWQGXJLoA9evTAiBEjAAAZGRkWBXDBggVo27at3NU4JRZA9WPOYtg75+uZBXhp2XfYGfFM5SHfzSOBfPc4/aQ63J7FYM5isAAqS3YB9PT0xNq1awFUXQBjYmLg6ekpdzVOiQVQ/ZizGPbM+btzKXhJtxJ/Rt5bXvxmNQd+WgYYDHaYqbpxexaDOYvBAqgs2QXQ398f0dHRAKougDNnzkRAQIDc1TglFkD1Y85i2CPnklID5nx7DnPC3kSJ1g/Q+aL0wx5A0gk7zlTduD2LwZzFYAFUluwCOHHiRAQEBCArK8uiAJ47dw4+Pj6YPn267Ik6IxZA9WPOYsjNOel2AcYu34P4iKcqD/l+PhYozLLvRFWO27MYzFkMFkBlyS6AN2/eRPv27dGuXTtMnToVGo0G48aNwyuvvIJGjRqhc+fOLntbGBZA9WPOYsjJOT7hFsbrluKmtlP5hR6z7wGOxwBGowIzVTduz2IwZzFYAJVll9vApKamYtKkSfDz8zN9LJyvry8mTpyI1NRUe6zCKbEAqh9zFqMuOevLDJi36yw+CJuEMm1TQOcL/ZJeQPJvCs5U3bg9i8GcxWABVJbdPwkkLS0Nt27dgsENTshmAVQ/5iyGrTnfzCrExOXf4lDE46ZDvmVfTQaK8xSeqbpxexaDOYvBAqgsfhScDCyA6secxbAl5x8upGLKrPeRpm1ffqHHHH/gl894yNcK3J7FYM5isAAqiwVQBhZA9WPOYliTs77MgAW7z2JF+Ksw/L9DviXL+wBpFwXOVN24PYvBnMVgAVQWC6AMLIDqx5zFqC3n5OxCvLEiDj9HPlJ5yPebdwB9oeCZqhu3ZzGYsxgsgMpiAZSBBVD9mLMYNeX8w8VUzJg1F7e1bcsv9IhqC5zd5oBZqh+3ZzGYsxgsgMpiAZSBBVD9mLMYVeVcWmbAot2/YUP4P017/YpX9QUyrzpwpurG7VkM5iwGC6CyWABlYAFUP+Ysxt05p2QX4e0VX+O3yAdN5a90dzBQWuLgmaobt2cxmLMYLIDKslsBLC4uxpEjRxAXF+eyN36+Gwug+jFnMe7M+cClNITM0iJX619+ocfcDsDFPY6eokvg9iwGcxaDBVBZdimAy5Ytg5+fHzQaDTQajemj4NLT09GiRQts2LDBHquxyqlTpzB06FD4+fnBy8sLPXr0wLJly8yWOXz4MJ588kl4eXnB398f06dPR16e7fcXYwFUP+Yshl6vx/Ydcfhw5y+IjRhu2utXtOZpIDvJ0dNzGdyexWDOYrAAKkt2Ady4cSM8PDwwZswYbNq0yeyzgAFg9OjRGDhwoNzVWGXfvn1o2LAhHnvsMSxevBgxMTEIDg7Ge++9Z1rm9OnTaNSoEXr16oXVq1cjPDwcnp6eCAoKsnl9LIDqx5zFuJGZh4lzV+Ni5APln+Ora4rS/84GykodPTWXwu1ZDOYsBgugsmQXwB49emDEiBEAgIyMDIsCuGDBArRt21buamqVk5MDf39/PP/88zV+CsngwYPRpk0bsx/6unXrIEkS9u3bZ/M6WQDVjTkr79ClNMyaFYxC7T3le/3mdQau/ODoabkkbs9iMGcxWACVJbsAenp6Yu3atQCqLoAxMTHw9PSUu5parV69GpIk4fz58wCA/Px8iyKYk5OD+vXrm+0RBICSkhI0btwYkyZNsmmdLIDqx5yVU2YwYvmeX7AjYrDpkG9+zBAgz3U/H9zRuD2LwZzFYAFUluwC6O/vj+joaABVF8CZM2ciICBA7mpq9cILL8DX1xfx8fEIDAyEJEnw8fHB1KlTUVRUBAD46aefIEkStm7davH8v/3tb+jdu7dN62QBVD/mrIzU3CKErNyMPyIDy2/qrPPDmdWToC8pdvTUXBq3ZzGYsxgsgMqSXQAnTpyIgIAAZGX9/+3de1xUZeI/8AdEuekgXjEvICj9lJWK3XS11F0rxS3LMuxiWlqttua622qAyAxq3jYVNVlEMlMTNStJMTQ1w0tppmzeJY0VvKCggohchPn8/vDLyWlAwZnzzJyZz/v1el778njmnGc+O3v24zlzzlw1K4BHjhyBt7c3xo0bZ/FE7yY0NBReXl7w8vLCuHHj8Pnnn2PcuHEQQuDFF18EAKxbtw5CCOzcudPs9REREfDz87vjPsrKylBUVKSM3NxcCCFQUFCAiooKq46SkhKkpqaipKTE6tvmYM5qjozj5zFryj9Rpm8GGHQomRmM0pM7mLOEwc8zc3akoWbOBQUFLICWbuDcuXNo164d2rZtizFjxsDV1RUjRozAsGHD4OHhgY4dO0p5LExgYCCEEBgzZozJ8tGjR0MIgaysLKxYsQJCCOzbt8/s9cOHD4ePj88d92EwGCCEMBspKSlITU3l4HDq8cX6VLyzIAXpk/spl3yz3++LTZ99YvO5cXBwcNw+UlJSWACtsZGLFy/i9ddfh6+vL1xcXODi4gKdToeRI0fi4kU53/cJCQmBEAIZGRkmyzMyMiCEwPLly3kGkIM5qzQuXClG7KKlyNUH3nqos6EZSjMWoKK8nDlLHMyZOTvS4BlAdVn9l0AuXbqEvLy8O96Jq4YnnngCQgicOHHCZPnx48chhMD8+fP5HUAyw5wt9/2pS1g4ZSwq9L6AQYfi2SHA2QMm6zBnOZizHMxZDjVz5ncArVAAMzMzkZKSYrJs8+bN6N27N7p374758+dbuos6iYqKghDC5AYUANi+fTuEEFi1ahUKCwvveBfwqFGj6rVPFkDtY873rqrKiOT0fdgR21u55Htt5StAqfn/HpizHMxZDuYsBwuguiwugE888QSeeeYZ5c+//PILPD090a5dO3Tv3h2urq7KY2LUdPDgQQgh8PLLL5ssf+mll+Dm5oZz584BAMLDw9GmTRtcu3ZNWefDDz+EEALp6en12icLoPYx53tTUFyG9xYlIU/fATDoUBHXAmV7lwJGY43rM2c5mLMczFkOFkB1WVwAW7Vqhffff1/5c1xcHBo3bqzc+DF06FA89NBDlu6mTkaNGgUhBIYOHYqEhARERERACIHo6GhlnQMHDsDd3d3kl0A8PDzQv3//eu+PBVD7mHP97Tt1CUumvIFKvQ9g0KHo/QeBvCN3fA1zloM5y8Gc5WABVJdVHgT90UcfKX/u3r07nn32WeXPycnJaNKkiaW7qZOKigrExcXB398fDRs2RKdOnRAfH2+23q5du9CrVy94eHigZcuWGDt2rMkZwbpiAdQ+5lx3VVVGLEvfg+9jeyiXfK+ufhMov37X1zJnOZizHMxZDhZAdVlcAAMCApTv1J0/fx4NGjRAYmKi8vfx8fF3fbyKVrEAah9zrpvL18sxJ+EDFOjb3vo5tymtUfpjyt1f+H+YsxzMWQ7mLAcLoLosLoDjx4+Hh4cHxo0bh+7du8PLywt5eXnK37/22mvSLgHLxgKofcz57n48nYeVU0coZ/2uzO0OY35WvbbBnOVgznIwZzlYANVlcQEsLi7Gyy+/jKZNmyIgIACffvqp8ndFRUVo3LgxIiMjLd2NXWIB1D7mXLuqKiM+Sd+Jg7FhSvm7/OnfgYrSem+LOcvBnOVgznKwAKrL6s8BvF1VVRUKCwsd9n8kLIDax5xrduV6OT5YNBeFer9bP+c25T7c+OmLe94ec5aDOcvBnOVgAVSXqgXQ0bEAah9zNnfg1Hmsm/KCctYvP/5RGK9kW7RN5iwHc5aDOcvBAqiuehfAM2fO3NNwRCyA2secf2U0GrE2/Rscje32a/n74l2g0vJsmLMczFkO5iwHC6C66l0AXVxc4OrqWu/hiFgAtY8533K1pBzJi2bgur7lrV/0mNoBJUfr92D0O2HOcjBnOZizHCyA6qp3AVy2bBk+/vjjeg9HxAKofcwZ+O+ps9g4dbBy1u/CgsdgLDpn1X0wZzmYsxzMWQ4WQHXxO4AWYAHUPmfO2Wg04vP0LfhZ3wUw6FBpaIq8DXFAVaXV9+XMOcvEnOVgznKwAKqLBdACLIDa56w5F14vx4oPDCjVN7/1ix5TO+L6yR2q7c9Zc5aNOcvBnOVgAVSXxQWwrt8JdEQsgNrnjDkfOnUG26YOVC755n7wFxiLL6m6T2fM2RaYsxzMWQ4WQHVZXAANBgPi4uJMRmxsLIYPH44mTZrgD3/4A+Li4qwxV7vDAqh9zpSz0WjEl5s24oy+E2DQ4abBF+c2zQKqqlTftzPlbEvMWQ7mLAcLoLpUvQR8/vx5dOjQASkpdf/NUC1hAdQ+Z8m5sKQcny6MRLne99bjXaZ1RvGp76Xt31lytjXmLAdzloMFUF2qfwdwxowZ6NKli9q7sQkWQO1zhpyP/pyN3VMfUy75Zic8C2PJFalzcIac7QFzloM5y8ECqC7VC+CCBQvg4eGh9m5sggVQ+xw5Z6PRiPRNn+O8PgAw6FBuaIaczQsAo1H6XBw5Z3vCnOVgznKwAKpL1QJ4+PBhBAUFITQ0VM3d2AwLoPY5as5FN8rw5cJ/4qa+6a1n+73XFdd+OWCz+ThqzvaGOcvBnOVgAVSXxQUwICAAHTt2NBu+vr5wdXVF48aNsW3bNmvM1e6wAGqfI+Z8PCsL+6f0Vi75ZiW+BGOpbQ9yjpizPWLOcjBnOVgA1WVxAXz11Vfx2muvmYyRI0finXfeQUJCAi5fvmyNedolFkDtc6ScjUYjtm5cg0v69oBBhxuGlsjelmSTS76/5Ug52zPmLAdzloMFUF18ELQFWAC1z1FyvlZyA+kL/oYqvc+tZ/u9F4qinMO2npbCUXK2d8xZDuYsBwuguu65AJaWlmLNmjWYOXMmkpOTcf78eWvOSxNYALXPEXI+efI4fpryR+WS79GkkTCWl9h6WiYcIWctYM5yMGc5WADVdU8F8OLFiwgKCoKrqytcXFzg4uICb29vbN261drzs2ssgNqn5ZyNRiO+/XI5rujvAww6FBv8cHrHcltPq0ZazllLmLMczFkOFkB13VMBfPvtt9GgQQP861//wqZNm7BgwQK0aNECgYGB1p6fXWMB1D6t5ny9pAQ75o9Szvr9Mv0PKDx70tbTqpVWc9Ya5iwHc5aDBVBd91QAg4ODMXLkSJNla9asgaurK06cOGGViWkBC6D2aTHnUyd+wvEpYUr5+2/yW6iqKLP1tO5IizlrEXOWgznLwQKornsqgB4eHli6dKnJsrNnz8LFxQUZGRlWmZgWsABqn5ZyNhqN2JOahGJ9a8CgQ6HhPpzcudbW06oTLeWsZcxZDuYsBwuguu6pALq4uGDVqlUmywoKCuDi4oLt27dbZWJawAKofVrJueT6NXwXP0w563diRi9cOXfa1tOqM63krHXMWQ7mLAcLoLruuQBOnz4dBw4cUMY333wDFxcXLF682GR59XBELIDap4Wcfzl2AL9M6QYYdKjS++CHpf9E1U37nW9NtJCzI2DOcjBnOVgA1XXPBdDV1dVs1LS8epkjYgHUPrvO2WjEvi8WokTfEjDoUGDogGO7Um09q3ti1zk7EOYsB3OWgwVQXfdUAD/++ON6D0fEAqh99ppzybUr2D/veeWS76EZf0JBXo6tp3XP7DVnR8Oc5WDOcrAAqou/BGIBFkDts8ec/3fke+RM6QIYdLipb4rvlkWjqrLS1tOyiD3m7IiYsxzMWQ4WQHWxAFqABVD77CpnoxGZn81Gmb45YNAhz9ARh7/bbOtZWYVd5ezAmLMczFkOFkB1sQBagAVQ++wl5xtFl3Fo7lPKJd8fZ/ZH/kXH+XlFe8nZ0TFnOZizHCyA6mIBtAALoPbZQ845P32LC3GdAIMO5XpffPtxHCorq2w2HzXYQ87OgDnLwZzlYAFUl0MXwPfeew9CCISEhJj93Z49e/DII4/A09MTrVu3xrhx41BcXFyv7bMAap9Nc66qwuG1U1Ch9wUMOuQaOuO/ex3zOZr8PMvBnOVgznKwAKrLYQtgbm4uvLy84O3tbVYAMzMz4eHhgYceegiJiYmIiYmBu7s7wsPD67UPFkDts1XOpVfzcGJOf+WS756Zg3Ap/6LUOcjEz7MczFkO5iwHC6C6HLYAvvDCC+jXrx/69u1rVgAHDhyINm3amPwXn5ycDCEEtmzZUud9sABqny1yPpe5BflxAYBBh1J9c3y9YpbDXfL9LX6e5WDOcjBnOVgA1eWQBTAjIwMNGjTAoUOHzApgUVER3NzcMHHiRJPXlJeXo3Hjxnj99dfrvB8WQO2TmnNVJY6vnoRKvQ9g0OG0oSsO7Nut/n7tAD/PcjBnOZizHCyA6nK4AlhZWYnQ0FCMHj0aAMwK4O7duyGEwNq1a81e++ijjyIsLKzO+2IB1D5ZOZdezsXpf/dVLvlun/U88goKVN2nPeHnWQ7mLAdzloMFUF0OVwAXLVoEHx8fXLp0CYB5AVy3bh2EENi5c6fZayMiIuDn51frtsvKylBUVKSM3NxcCCFQUFCAiooKq46SkhKkpqaipKTE6tvmkJvzuX2pKIxrBxh0KNa3woYV83CjtMzm793RcuZgzszZsYaaORcUFLAA2noC1lRQUIBmzZphzpw5yrLfFsAVK1ZACIF9+/aZvX748OHw8fGpdfsGgwFCCLORkpKC1NRUDg6kpqZiytIv0XPKRtwftR4f6V9Wzvod03fD4uTFNp8fBwcHh7OPlJQUFkBbT8CaxowZg06dOqG8vFxZxjOAHDJz3piZC//INDwSuQwHYsOU8vfFey8iJ++Szd+vo+TMwZyZs+MPngFUl8MUwKysLLi6umLhwoXIzs5WRo8ePRAcHIzs7GxcvnyZ3wEkE9bOeUB8Bv4abUCh3g8w6FCo98Nfo/UYEJ9hle1rFT/PcjBnOZizHGrmzO8AOlAB3LFjR42XZ28f48ePR2Fh4R3vAh41alSd98kCqH3WzNlYcQPLJz+vnPU7EBuGR6KWwT8yDcExX1lhttrFz7MczFkO5iwHC6C6HKYA5ufnY/369WYjJCQEHTp0wPr163Ho0CEAQHh4ONq0aYNr164pr//www8hhEB6enqd98kCqH3Wyrko9xhypv96yTcxZhiCIlPhH5mGgKg0hM/nGUB+ntXHnOVgznKwAKrLYQpgbWp6EPSBAwfg7u5u8ksgHh4e6N+/f722zQKofdbI+eetH+K6oRVg0CFf3w4joqcjICpNKX/+kWlIP3zBirPWHn6e5WDOcjBnOVgA1eWUBRAAdu3ahV69esHDwwMtW7bE2LFjTc4I1gULoPZZknPFjWs4nDBMOet3cEovHD1xAumHzyN8fgaCY75C+PwMpy9/AD/PsjBnOZizHCyA6nL4AqgmFkDtu9ecL2QdQM7UEMCgQ6XeB1sWjcf1G2UqzVL7+HmWgznLwZzlYAFUFwugBVgAta/eORuNyFwfj1J9c8Cgw0WDP3ZvXa/uJB0AP89yMGc5mLMcLIDqYgG0AAug9tUn5+Kiyzg4d/Cvd/lO74ezuWckzFL7+HmWgznLwZzlYAFUFwugBVgAta+uOZ84kIGzcZ0Bgw4Vel9kfDQZN2/elDRL7ePnWQ7mLAdzloMFUF0sgBZgAdS+u+VcWVmFnSumoFzvCxh0OG8IwtF92yTPUvv4eZaDOcvBnOVgAVQXC6AFWAC170455104h/0z+/96l+/7T6LwyiUbzFL7+HmWgznLwZzlYAFUFwugBVgAta+2nPd+uxEXDB0Bgw7l+mb4cd2/YayqstEstY+fZzmYsxzMWQ4WQHWxAFqABVD7fpvzjbIKbE6ciJv6poBBh9wpXZB79Hsbz1L7+HmWgznLwZzlYAFUFwugBVgAte/2nE+eOoUfp/ZRLvkeXjgU5dcLbT1Fh8DPsxzMWQ7mLAcLoLpYAC3AAqh9FRUVWL8+FZvWf4JL+vaAQYcbhpY4kZ4IGI22np7D4OdZDuYsB3OWgwVQXSyAFmAB1L4LBVexeupwVOl9bl3yfS8UV7N/svW0HA4/z3IwZzmYsxwsgOpiAbQAC6C2fZ/5Ew4auiuXfE8kj4SxvMTW03JI/DzLwZzlYM5ysACqiwXQAiyA2lR+swprP1mMK/r7AIMO1w2tcObb5baelkPj51kO5iwHc5aDBVBdLIAWYAHUnlMXLmP9zOHKWb+zsx7GppQk5qwyfp7lYM5yMGc5WADVxQJoARZA7TAajdi4YzcO6R9Uyt//Pvk7Km4UM2cJ+HmWgznLwZzlYAFUFwugBVgAtaGwpAIfJs5Bkb41YNDhWlxbXDmQCoA5y8Kc5WDOcjBnOVgA1cUCaAEWQPv3Q9Y5fDHleeWs3/l5fVB1JUf5e+YsB3OWgznLwZzlYAFUFwugBVgA7dfNyiosS92M47EhgEGHKoMP8r6YBFTeNFmPOcvBnOVgznIwZzlYANXFAmgBFkD7lFNwHQvnGFCibwkYdCiaGoAbx7fWuC5zloM5y8Gc5WDOcrAAqosF0AIsgPYnbX8WNuifVC75XlrUH7iWV+v6zFkO5iwHc5aDOcvBAqguFkALsADaj+Kym5i7fB1Oxd4PGHSoNDTF1c3TgarKO76OOcvBnOVgznIwZzlYANXFAmgBFkD78N8zVxA/fQLK9M1v3eU7vRNu/rK7Tq9lznIwZzmYsxzMWQ4WQHWxAFqABdC2qqqMWLo1E+mxjyuXfK8kDwZKLtd5G8xZDuaW3AiHAAAgAElEQVQsB3OWgznLwQKoLhZAC7AA2k5eUSkmL1qGnNggwKDDTUMz3MhYCBiN9doOc5aDOcvBnOVgznKwAKqLBdACLIC28fWR85gbNxYVel/AoEPx7K4wnj1wT9tiznIwZzmYsxzMWQ4WQHWxAFqABVB96YfPY0B8BoJjvkL/eRkYu2QLvpncW7nkW7xyGFBaeM/bZ85yMGc5mLMczFkOFkB1sQBagAVQXemHz8M/Mg0BkWnwj0zD0Kj3cUHvDxh0qIhrgYp9H9b7ku9vMWc5mLMczFkO5iwHC6C6WAAtwAKorgHxGQiITEPHyA2YN2kkKvU+gEGH7LguQN4Rq+yDOcvBnOVgznIwZzlYANXFAmgBFkB1dZ70FR6OXIk9k/+oXPJdGzMID8R8YbV9MGc5mLMczFkO5iwHC6C6WAAtwAKoDqPRiM9+zMWr0dORr28HGHS4rm+Jf0RHIiAqDeHzM6y2L2fOWSbmLAdzloM5y8ECqC4WQAuwAFpfQXEZxiz/Hokxw5Szfkdju+HPUUsQEHXru4Dphy9YbX/OmrNszFkO5iwHc5aDBVBdLIAWYAG0ri1HLuDJKZ/gQGyYUv6yl4/GoPitCI75CuHzM6xa/gDnzNkWmLMczFkO5iwHC6C6HKYA/vDDDxg7diy6du0KLy8vtG/fHhERETh58qTZuseOHcOAAQPg7e0NX19fvPLKK7h06VK998kCaB1FpRX416f/xV+jDSjU+936Ld/p7YCjqarv25lytiXmLAdzloM5y8ECqC6HKYBDhgyBn58fxo0bh+TkZEybNg2tW7eGt7c3Dh8+rKyXm5uLFi1aICgoCAsWLMD06dPh6+uLBx54AOXl5fXaJwug5facysefZqRjWczzylm/qiV/Bq5kS9m/s+Rsa8xZDuYsB3OWgwVQXQ5TAPfs2WNW4LKysuDu7o5hw4Ypy9566y14enrizJkzyrKtW7dCCIGkpKR67ZMF8N6VVlQibsMR/CkqGUdiuynlD1smA5Xy3rOj52wvmLMczFkO5iwHC6C6HKYA1iYsLAxhYWHKn1u1aoWIiAiz9YKDg/HYY4/Va9ssgPVT/asenSZtQudJmzAuOhrF+laAQQfjrI5A1tfS5+SIOdsj5iwHc5aDOcvBAqguhy6ARqMRbdu2Rf/+/QEAZ8+ehRACs2fPNlv3lVdeQbNmzeq1fRbAuqv+VQ//yDT8v8jPsCbm6V/P+n30F6DonE3m5Wg52yvmLAdzloM5y8ECqC6HLoArV66EEAJLly4FAOzfvx9CCKxYscJs3YkTJ0IIgbKyslq3V1ZWhqKiImXk5uZCCIGCggJUVFRYdZSUlCA1NRUlJSVW37YtRr85O+AfmYYnohJxMrbLre/66X2wcsZfUVFWarN5OVrO9jqYM3N2pMGctZ9zQUEBC6CtJ6CW48ePQ6fToWfPnqisrAQA7Ny5E0IIrF271mz92NhYCCFw9erVWrdpMBgghDAbKSkpSE1N5ahlzFmeCv/IDYic9A5K9c0Bgw55+g54MXo2gqI22nx+HBwcHBzONVJSUlgAbT0BNVy4cAGBgYFo3749zp379dIizwDKHeXl5Uj45iRCo9fhy8kDlEu+305+FGGRqxAQlYYB8d867L8wOZgzc3bMwZy1nzPPADpgASwsLMSDDz6IZs2a4ejRoyZ/x+8AylNUWoE3l+/Hk1ELkR3bGTDocFPfFDNjRiMgcoMqv+pxL7Ses1YwZzmYsxzMWQ41c+Z3AB2sAJaWlqJ3797w8vLCd999V+M6LVu2rPUu4H79+tVrfyyANTt6rgh9Z29H3KSxKNf73rrLd15XfP/tJoTPz1DtVz3uhZZz1hLmLAdzloM5y8ECqC6HKYCVlZV4+umn4ebmhk2bNtW63pgxY+Dp6YmcnBxl2bZt2yCEQGJiYr32yQL4q+pHvARFb8IDkWvw9eQ//3qX7+qXgRtXbD3FGmktZ61iznIwZzmYsxwsgOpymAI4fvx4CCEwaNAgrFy50mxUy8nJQfPmzREUFISFCxdixowZ8PX1Rbdu3e74/b+asADecvsjXp6Lmouz+o63fs5tSnNgbxJgNNp6irXSUs5axpzlYM5yMGc5WADV5TAFsG/fvjXeoVs9bnfkyBH0798fXl5eaNq0KYYNG4a8vLx675MF8JZ+c3YgIHIDZk96Ezf1TQGDDr/EdsbYOR/Zemp3paWctYw5y8Gc5WDOcrAAqsthCqAtsAACu3/Ox+8jVyFj8iPKJd8vJg9E18h1CI75ytbTuyut5Kx1zFkO5iwHc5aDBVBdLIAWcOYCaDQa8Z8dpzAsehYu6jsABh1u6FtgwqQJ8I/ciICoNITPz7D1NO/K3nN2FMxZDuYsB3OWgwVQXSyAFnDWAlhcdhN/W7EPC2JGoErvAxh0OB4bgsejF8M/Ms1uHvFSF/acsyNhznIwZzmYsxwsgOpiAbSAMxbAny8WY+i/12FvbHflkq/xy3HYknna7h7xUhf2mrOjYc5yMGc5mLMcLIDqYgG0gLMUwNsf8TIqeiou6++7dZfve/cBh9bZenoWsaecHRlzloM5y8Gc5WABVBcLoAWcoQBWP+KlU2QqlsS8qJz1uzz3j0DBKZvOzRrsJWdHx5zlYM5yMGc5WADVxQJoAWcogI/N/RaPRi1FZuyDSvlbGjMUg+K32XRe1mIvOTs65iwHc5aDOcvBAqguFkALOHoBzDh5CX+LnowifWvAoMNVfRu8ER0H/8g0TTzipS7sIWdnwJzlYM5yMGc5WADVxQJoAUctgDcrqzD/q//ik8nPKmf99sf+AT0jP1bu8tXCI17qggdyOZizHMxZDuYsBwugulgALeCIBTCvqBT/WLQWx2JDAIMOVQYfLIp5BZ2iUjX3iJe64IFcDuYsB3OWgznLwQKoLhZACzhCAay+wzc45is8Oms7ovVRKNG3BAw6lM3oCPy8DemHz2vyES91wQO5HMxZDuYsB3OWgwVQXSyAFtB6Aay+wzcgMg1dIj/DZ5OfVC75liT/BbhW/99H1hoeyOVgznIwZzmYsxwsgOpiAbSA1gvggPgMBESmITwqAadi77/1bD+9D5bN/BtQVanafu0JD+RyMGc5mLMczFkOFkB1sQBaQOsFsNOkNMRMGo8yfXPAoMM5fQCej5rjMHf41gUP5HIwZzmYsxzMWQ4WQHWxAFpAywUw46csfDX5ceWS79bJffFA5GqHusO3Lnggl4M5y8Gc5WDOcrAAqosF0AJaLIBGoxGpaV8iRx8EGHQo1/tiyqSx8I/c6HB3+NYFD+RyMGc5mLMczFkOFkB1sQBaQGsFsOLmTWxaHI0KvS9g0KHgvfuxc8dmh73Dty54IJeDOcvBnOVgznKwAKqLBdACWiqARQUXkDnz10u+pxKeh/HGVatsW8t4IJeDOcvBnOVgznKwAKqLBdAC9l4Aq5/x93LMHOTp/W8920/fHEc3zAeMRutNVsN4IJeDOcvBnOVgznKwAKqLBdAC9lwA0w+fR8fIDZg7aRQq9T6AQYefY/8f1m1ynjt864IHcjmYsxzMWQ7mLAcLoLpYAC1gzwXwpblfYM/kPyqXfNdNfgpdIz9zqjt864IHcjmYsxzMWQ7mLAcLoLpYAC1grwXw+pHNyNe3Aww6XNe3xD+j34V/5K07fJ3pGX91wQO5HMxZDuYsB3OWgwVQXSyAFrC7AlhZgQufvauc9TsW+zv8OWqJUv6c7Rl/dcEDuRzMWQ7mLAdzloMFUF0sgBawpwJYdfl/OD/3UaX8fRoXgeDIL5Rn+znjM/7qggdyOZizHMxZDuYsBwugulgALWAvBfDqgc9xPe4+wKBDkd4PS5Pica20AumHzzv1M/7qggdyOZizHMxZDuYsBwugulgALWDLAph++DyemrcNyydHKGf9/qsPQ1rGdzDyES91xgO5HMxZDuYsB3OWgwVQXSyAFrBVAUw/fB59oj7EodhQpfwtjnkJH+88afV5ODoeyOVgznIwZzmYsxwsgOpiAbSArQrgtBlxKNa3Agw6XNbfh1ejp/EGj3vEA7kczFkO5iwHc5aDBVBdLIAWkFUAq3/RIzRmPb6c8qxy1m9vbHd0j1zBR7xYgAdyOZizHMxZDuYsBwugulgALSCjAE7bcBj+kWl4PGoxTsZ2AQw6VOl9MD/mNQRGfslHvFiIB3I5mLMczFkO5iwHC6C6WAAtoHYBHDn/S/hHbsS7k/6FG/oWgEGHi/oOeDF6tsmjXfiIl3vHA7kczFkO5iwHc5aDBVBdTlsAy8rK8O6776JNmzbw8PBA9+7d8fXXX9drG2p9gNIPn8dDU7YgJPJTpE4OVy75fjv5UYRFroJ/ZBqCojfxES9WwAO5HMxZDuYsB3OWgwVQXU5bAF988UW4ublhwoQJSEpKQs+ePeHm5oZdu3bVeRtqfIDSD5+Hf2Qa/hL1AX6J7QwYdLipb4qZk/6KgMgNyiVfXu61Dh7I5WDOcjBnOZizHCyA6nLKArhv3z4IIfD+++8ry0pLSxEUFISePXvWeTtqfIAGxGcgZtJ4lOmbAQYdcvWBeDZqnlL8qgfP+FkHD+RyMGc5mLMczFkOFkB1OWUBnDhxIho0aGD2X/yMGTMghEBOTk6dtqPGBygoehPemzQGMOiweXI/dItcY1b+Zmw6ZrX9OTseyOVgznIwZzmYsxwsgOpyygL4+OOPo0uXLmbLt23bBiEENmzYUKftqPEBCo75CgGRG/BmtAH+kRtZ/lTGA7kczFkO5iwHc5aDBVBdTlkAQ0JC0K9fP7PlR48ehRACixcvrvF1ZWVlKCoqUkZubi6EECgoKEBFRYVVRlD0JrPSVz3e23jEavvhuDVKSkqQmpqKkpISm8/FkQdzZs6ONJiz9nMuKChgAbT1BGwhMDAQAwcONFt++vRpCCEQHx9f4+sMBgOEEGYjJSUFqampVhk9p2ys4czfRjyk32i1fXBwcHBwcDjzSElJYQG09QRswZ7PAG7MzL31bL/qBzz/33+m/TfX5v8ac8TBf8kzZ0cazJk5O9LgGUB1OWUBtOfvAAL4v59++xZBURsxIP5b3vGroooKfpdHBuYsB3OWgznLoWbO/A6gkxbACRMm1HgX8PTp021+F3A1HmDkYM5yMGc5mLMczFkOFkB1OWUB3Lt3r9lzAMvKytCpUyf06NGjztthAdQ+5iwHc5aDOcvBnOVgAVSXUxZAAIiIiICbmxsmTpyIpKQk9OrVC25ubsjIqPsvbLAAah9zloM5y8Gc5WDOcrAAqstpC2BpaSkmTJgAPz8/uLu74+GHH8bmzZvrtQ0WQO1jznIwZzmYsxzMWQ4WQHU5bQG0BhZA7WPOcjBnOZizHMxZDhZAdbEAWoAFUPuYsxzMWQ7mLAdzloMFUF0sgBZgAdQ+5iwHc5aDOcvBnOVgAVQXC6AFWAC1jznLwZzlYM5yMGc5WADVxQJoARZA7WPOcjBnOZizHMxZDhZAdbEAWoAFUPuYsxzMWQ7mLAdzloMFUF0sgBZgAdQ+5iwHc5aDOcvBnOVgAVQXC6AFWAC1jznLwZzlYM5yMGc5WADVxQJogcLCQgghkJubi6KiIquOgoICpKSkoKCgwOrb5mDOzNkxB3Nmzo401Mw5NzcXQggUFhbaukrYDAugBao/QBwcHBwcHBzaG7m5ubauEjbDAmiBqqoq5ObmorCwULV/nahxdpGDOTNnxxzMmTk70lAz58LCQuTm5qKqqsrWVcJmWADtVFERv58gA3OWgznLwZzlYM5yMGd1sQDaKX7w5WDOcjBnOZizHMxZDuasLhZAO8UPvhzMWQ7mLAdzloM5y8Gc1cUCaKfKyspgMBhQVlZm66k4NOYsB3OWgznLwZzlYM7qYgEkIiIicjIsgEREREROhgWQiIiIyMmwABIRERE5GRZAIiIiIifDAmhHysrK8O6776JNmzbw8PBA9+7d8fXXX9t6Wpr1ww8/YOzYsejatSu8vLzQvn17RERE4OTJk2brHjt2DAMGDIC3tzd8fX3xyiuv4NKlSzaYtWN47733IIRASEiI2d/t2bMHjzzyCDw9PdG6dWuMGzcOxcXFNpildh04cACDBg2Cr68vPD09ERISggULFpisw5wtk5WVhRdeeAFt27aFp6cn7r//fkyZMgUlJSUm6zHnuisuLoZer8eAAQPg6+sLIQSWLVtW47p1PSZXVVVh9uzZCAgIgLu7O7p164aUlBSV34ljYAG0Iy+++CLc3NwwYcIEJCUloWfPnnBzc8OuXbtsPTVNGjJkCPz8/DBu3DgkJydj2rRpaN26Nby9vXH48GFlvdzcXLRo0QJBQUFYsGABpk+fDl9fXzzwwAMoLy+34TvQptzcXHh5ecHb29usAGZmZsLDwwMPPfQQEhMTERMTA3d3d4SHh9tottqzZcsWNGrUCD169MC8efOwZMkSREZGYuLEico6zNkyOTk5aNq0Kfz9/TFz5kwkJSXhtddegxACTz/9tLIec66f7OxsCCHQoUMH/OlPf6q1ANbnmBwVFQUhBN58800sWbIETz75JIQQWL16taR3pV0sgHZi3759EELg/fffV5aVlpYiKCgIPXv2tOHMtGvPnj1mB4usrCy4u7tj2LBhyrK33noLnp6eOHPmjLJs69atEEIgKSlJ2nwdxQsvvIB+/fqhb9++ZgVw4MCBaNOmjcmDXZOTkyGEwJYtW2RPVXOKiorQunVrPPvss3f8DVPmbJnp06dDCIEjR46YLB8xYgSEELhy5QoA5lxfZWVluHDhAgBg//79tRbAuh6Tz549i4YNG2Ls2LHKMqPRiN69e6Ndu3aorKxU7804ABZAOzFx4kQ0aNDA7InnM2bMgBACOTk5NpqZ4wkLC0NYWJjy51atWiEiIsJsveDgYDz22GMyp6Z5GRkZaNCgAQ4dOmRWAIuKiuDm5mZypgoAysvL0bhxY7z++uuyp6s5iYmJEELg2LFjAIDr16+bFUHmbLnIyEgIIZCfn2+23NXVFdevX2fOFrpTAazrMTkhIQFCCBw9etRkvZSUFAghePXsLlgA7cTjjz+OLl26mC3ftm0bhBDYsGGDDWbleIxGI9q2bYv+/fsDuPUvSCEEZs+ebbbuK6+8gmbNmsmeomZVVlYiNDQUo0ePBgCzArh7924IIbB27Vqz1z766KMmpZxqNmTIEOh0OmzduhXBwcEQQsDb2xtjxoxBaWkpAOZsDenp6crl3szMTOTk5GDNmjXQ6XT4xz/+AYA5W6q2AlifY/Ibb7wBb29vGI1Gk/VOnToFIQQWLlyoytwdBQugnQgJCUG/fv3Mlh89ehRCCCxevNgGs3I8K1euhBACS5cuBfDrQWjFihVm606cOBFCCP4MUR0tWrQIPj4+yhe1f1sA161bByEEdu7cafbaiIgI+Pn5SZurVoWGhsLLywteXl4YN24cPv/8c4wbNw5CCLz44osAmLO1TJs2DZ6enhBCKCMmJkb5e+ZsmdoKYH2OyU8++SQCAwPN1ispKYEQAlFRUarM3VGwANqJwMBADBw40Gz56dOnIYRAfHy8DWblWI4fPw6dToeePXsq3w3ZuXNnrf+Kj42NhRACV69elT1VzSkoKECzZs0wZ84cZdlvC+CKFSsghMC+ffvMXj98+HD4+PhImauWBQYGQgiBMWPGmCwfPXo0hBDIyspizlaycuVKDBgwAEuWLMHnn3+OUaNGwcXFBR988AEAfp4tVVsBrM8xuV+/fjVeOauqqoIQAuPHj1dl7o6CBdBO8Aygui5cuIDAwEC0b98e586dU5bzDKB1jBkzBp06dTK56YZnAK0vJCQEQghkZGSYLM/IyIAQAsuXL2fOVrB69Wp4enoiNzfXZPlrr70GLy8vFBQUMGcL8Qyg7bEA2gl+B1A9hYWFePDBB9GsWTOzLwvzO4CWy8rKgqurKxYuXIjs7Gxl9OjRA8HBwcjOzsbly5f5nSkreOKJJyCEwIkTJ0yWHz9+HEIIzJ8/nzlbQe/evdGrVy+z5V988QWEENi6dStztpC1vgPo5eXF7wDeIxZAOzFhwoQa7wKufhwB7wK+N6Wlpejduze8vLzw3Xff1bhOy5Yta73jrKazsmRqx44dJt+TqmmMHz8ehYWFd7xrctSoUTZ6B9pR/cyz7du3myzfvn07hBBYtWoVc7aC4OBg9OjRw2z52rVrIYRAeno6c7bQne4CrusxedGiRTXeBbxq1apaz87Sr1gA7cTevXvNngNYVlaGTp061XggorurrKzE008/DTc3N2zatKnW9caMGQNPT0+Tkl195jUxMVHGVDUtPz8f69evNxshISHo0KED1q9fj0OHDgEAwsPD0aZNG1y7dk15/Ycffqj8nyrd2cGDByGEwMsvv2yy/KWXXoKbm5vy9QbmbJmnnnoKjRo1MvvVoMGDB8PV1ZU5W8GdCmBdj8m5ubm1Pgewbdu2fA7gXbAA2pGIiAjlX5RJSUno1asX3NzczL7vQ3Uzfvx4CCEwaNAgrFy50mxUy8nJQfPmzREUFISFCxdixowZ8PX1Rbdu3fj9PwvU9CDoAwcOwN3d3eSXEzw8PJTH8tDdjRo1CkIIDB06FAkJCYiIiIAQAtHR0co6zNky1c+zbNWqFaZOnYqEhAQMHDgQQgi88cYbynrMuf4++OADTJs2DW+99RaEEHjuuecwbdo0TJs2DYWFhQDqd0yu/l7gX//6VyQnJyu/BLJq1SpbvD1NYQG0I6WlpZgwYQL8/Pzg7u6Ohx9+GJs3b7b1tDSrb9++d7wsebsjR46gf//+8PLyQtOmTTFs2DDk5eXZaOaOoaYCCAC7du1Cr1694OHhgZYtW2Ls2LEmZ1DozioqKhAXFwd/f380bNgQnTp1qvEpAczZMvv27cPAgQPh5+eHhg0bIjg4GNOnT8fNmzdN1mPO9ePv71/rMTk7O1tZr67H5KqqKsyYMQP+/v5o1KgRQkJC8Mknn0h8R9rFAkhERETkZFgAiYiIiJwMCyARERGRk2EBJCIiInIyLIBEREREToYFkIiIiMjJsAASERERORkWQCIiIiInwwJIRERE5GRYAImINMpgMCi/ouDt7W217WZmZpr8QsO6deustm0isg8sgERkYtmyZRBCYP/+/baeCt1FdQFcuXIl1qxZY/J369evx/333w+dToennnoK586dM3v9oEGD8Oabb5otv3LlClauXIlJkyaxABI5KBZAIjLBAqgd1QXwt06fPo1GjRph+PDh+M9//oPg4GD079/fZJ3NmzfDx8cHly5dqnX7O3bsYAEkclAsgERkQksF8ObNmygvL7f1NFR1/fr1Wv+utgKYmJiIwMBAGI1GALeKnIuLC0pLSwHcyq1Lly6YO3fuHffNAkjkuFgAichEXQpgeXk5YmNjERYWBp1OBy8vLzz66KP45ptvzNZdvXo1wsLC0LhxYzRp0gS/+93vMH/+fJN1rl69ivHjx6Ndu3Zo1KgRgoKCMGvWLFRVVSnrZGdnQwiB999/H/Hx8QgMDISrqysyMzNrnacQAmPHjsUnn3yC4OBguLu7IywsDBkZGWbrHjx4EOHh4WjSpAm8vb3Rr18/fP/99yZzdHV1xYIFC5Rl+fn5cHFxQbNmzZSyBQBjxoxB69atTba/d+9eDBgwADqdDp6enujTpw92795tsk51oTt69CheeuklNG3aFA8++GCt76+2Ajhv3jyEhYUpf/7pp58ghMCVK1cAAPHx8QgODkZFRUWt2wZYAIkcGQsgEZmoSwHMz89HmzZt8M477yAxMRH//ve/cf/996Nhw4Ymhezrr7+GEAKPPfYYEhISkJCQgLfffhsRERHKOiUlJQgNDUXz5s0xadIkLF68GCNGjICLiwvGjx+vrFddALt27YrAwEDMmjUL8fHxOHPmTK3zFELgd7/7HVq0aIGpU6di9uzZ8Pf3h6enJw4fPqysd+TIEXh7e6NNmzaYNm0aZs2ahY4dO8Ld3R179+5V1gsNDcWQIUOUP69fvx6urq4QQuDIkSPK8pCQEDz//PPKn7dv345GjRqhZ8+emDt3LuLj4xEaGopGjRph3759ynrVha5r16545pln8J///AcJCQm1vr/aCuCuXbvg4uKClJQU/PLLLxg6dCg6deoEALh06RKaNm2KtLS0WrdbjQWQyHGxABKRiboUwMrKSrNLr1evXkXr1q0xatQoZdn48eOh0+lQWVlZ67amTZsGb29vZGVlmSyPiopCgwYNkJOTA+DXAqjT6e74vbXbVd/F+uOPPyrLzpw5Aw8PDzz77LPKssGDB6NRo0Y4ffq0suz8+fNo0qQJ+vTpoywbO3asyZm9d955B3369EGrVq2QmJgIALh8+TJcXFyUM4VGoxGdO3fGgAEDTM4S3rhxAx07dsQTTzyhLKsudC+99FKd3l9tBRAA/v73vyvvv1mzZsrZ2TfffBPh4eF12j4LIJHjYgEkIhP1/Q5gVVUVLl++jPz8fDz55JMmlywNBgMaNGiA9PT0Wl8fGhqK8PBw5Ofnm4xt27ZBCIFPPvkEwK8FcOTIkXV+L0II9OzZ02z5Cy+8AC8vL1RWVqKyshJeXl4YOnSo2XqjR4+Gq6srioqKAABr1qyBEAInTpwAADz88MOYPHkyhgwZgpdffhkA8OWXX0IIgYMHDwK4dWlZCIHly5ebvcc33ngD7u7uyqXu6kJX0yXqmtypAAK3yu6+fftQXFwM4NbjXdzd3XH8+HEUFhZi2LBhuO+++9C3b18cO3bM7PUsgESOiwWQiEzUtQB+/PHH6NatGxo2bGjyzLiOHTsq61y8eBFdunSBEAJt27bFyJEjzcqgp6enyet/O+bNmwfg1wI4derUOr8XIQRGjBhhtjw2NhZCCFy4cAEXLlyAEAKxsbFm682fP9/k8u65c+cghEBycjKuX78ONzc3bNmyBQsWLED79u0BABMmTIBOp1NK3dq1a5XA2IsAAAR5SURBVO/4/m7/bl51oas+63k3dyuAv9W7d2/lsvqwYcPQp08f7N+/H2+//TaCgoJw8+ZNk/VZAIkcFwsgEZmoSwFcuXIlhBAYPHgwVqxYgc2bN2Pr1q3o168f/P39TdYtLy/Hhg0b8NZbbyEgIMCslLm7u+OJJ57A1q1baxzV3/G7/SaQurJ2AQSAjh07Yvjw4di6dSsaNGiAa9euKWf5/ve//6FHjx4ml1hXr16tzLu291h9M0Z1ocvPz6/T+6tPAVyzZg1atGiBq1evorKyEg0bNsSOHTsA3Loc7e7ujl27dpm8hgWQyHGxABKRiboUwGeeecbkMSPVevXqZVYAb1dVVYXRo0dDCIGff/4ZANC1a9caL9P+1r0WQEsuAY8ZM8bkEjAAjBgxAgEBAdDr9fj973+vvC8fHx8sXrwYDRs2xIwZM5T1f/jhBwghkJSUdNf5qlUAS0pK0L59e+V7inl5eRBC4OTJk8o6fn5+Zg+TZgEkclwsgERkoi4F8LnnnkNgYKDJY1r27t0LFxcXkwJYUFBg9tqEhASTs2pxcXEQQmDz5s1m6169elW5LHmvBVAIgQMHDijLcnJy4OHhgcGDByvLBg8eDHd3d2RnZyvL8vLyoNPpTG4CAYDk5GQIIXD//ffjH//4h7J84MCBCA4OhhDC5ExaVVUVgoKC0LlzZ+W7eLe7/YYWtQqgXq9HaGiocjPOzZs34ebmhi+//BLArbu6GzRogG+//dbkdSyARI6LBZCITFQXwLfeegvTpk0zG9euXcNHH30EIQSefvppJCUlISoqCk2bNkVISIhJARw8eDD69OmDuLg4fPjhh4iNjVWebVddHktKShAWFgY3Nze88cYbSExMxJw5c/Dqq6/C29tbKUP3WgBregyMh4cHfvrpJ2W96sfAtG3bFtOnT8fs2bMRGBho9hgYADhx4oRSLD///HNl+cyZMyGEgLu7O8rKykxes2PHDnh4eKBDhw4wGAxYsmQJDAYD+vTpg6eeekpZT40CeObMGXh6epo9o3HIkCHo2LEjPvjgA/Tr1w/t27c3u7ObBZDIcbEAEpGJ6gJY28jNzYXRaMSMGTPg7+8Pd3d3PPTQQ0hLS8Orr75qUgA/++wz9O/fH61atUKjRo3QoUMHjB49GhcuXDDZZ3FxMaKjo9GpUyc0atQILVq0QK9evTBnzhzl+3H3WgCrHwTduXNnZa7V33273cGDBzFgwAA0btwYXl5e+POf/4zvvvuuxu22atUKQghcvHhRWbZ7924IIdC7d+8aX5OZmYnnnnsOzZs3h7u7O/z9/TF06FBs375dWUeNAhgREYHnnnvObPnFixcxaNAgNGnSBGFhYSaPyqnGAkjkuFgAichhVRdAR3V7Yazpcvu9qqysRH5+PlJTU1kAiRwUCyAROSxnKYBCCHh7e1ttu5mZmSZnfVkAiRwPCyAROSxHL4CnT59WHiVT02Xte1VcXGzymJrbL3UTkWNgASQih+XoBZCI6F6xABIRERE5GRZAIiIiIifz/wHwO7cyuaUIHgAAAABJRU5ErkJggg==\" width=\"640\">" + ], + "text/plain": [ + "<IPython.core.display.HTML object>" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1.49838084 1.33228895]\n" + ] + } + ], + "source": [ + "pulse_energies = powers/(rep_rate*npulses)\n", + "print(pulse_energies*1e6)\n", + "fluences = 2*pulse_energies*1e3/(np.pi*w0_x*w0_y*1e4)\n", + "print(fluences)\n", + "plt.figure()\n", + "plt.plot(rel_powers, fluences, 'o-', ms=4)\n", + "plt.grid()\n", + "plt.ylabel('Peak fluence [mJ/cm$^2$]')\n", + "plt.xlabel('Laser power [%]')\n", + "\n", + "e_fit = np.polyfit(rel_powers, pulse_energies*1e6, 1)\n", + "plt.figure()\n", + "plt.plot(rel_powers, pulse_energies*1e6, 'o-', \n", + " ms=4, label='E[$\\mu$J] = {:.3f} x power [%] + {:.3f}'.format(e_fit[0], e_fit[1]))\n", + "plt.grid()\n", + "plt.ylabel('Pulse energy [$\\mu$J]')\n", + "plt.xlabel('Laser power [%]')\n", + "plt.plot(rel_powers,rel_powers*e_fit[0]+ e_fit[1])\n", + "plt.legend()\n", + "print(e_fit)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "xfel", + "language": "python", + "name": "xfel" + }, + "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.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebook_examples/tim-normalization.ipynb b/notebook_examples/tim-normalization.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..ac515819fb858a659286812feff88f4e1876025e --- /dev/null +++ b/notebook_examples/tim-normalization.ipynb @@ -0,0 +1,485 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# How to\n", + "\n", + "This notebook has been created for the latest commit on DevelopmentRG.\n", + "\n", + "- git fetch origin\n", + "- git checkout DevelopmentRG\n", + "\n", + "some methods changed, so the processing scripts have to be adapted correspondingly (if you want to use the tim for the processing in some way).\n", + "\n", + "# changes since last version\n", + "\n", + "selection from the changelog that is relevant for you (changes since 1.1.1-rc2)\n", + "\n", + "* (DSSCBinner): \n", + " - constructor: kwargs 'tim_names' and 'dssc_coords_stride'\n", + " in constructor the latter described the relation between\n", + " xgm/tim pulses to the dssc frames. Can be an int or a list.\n", + " - load_xgm(), load_tim(): loading formatted xgm tim data\n", + " - create_pulsemask(), kwargs use_data='xgm'/'tim'. The\n", + " pulsemask is created from either the xgm or tim data.\n", + " - get_xgm_binned(), get_tim_binned(): returns the \n", + " binned xgm/tim data\n", + "\n", + "# comments\n", + "\n", + "The methods used in the code below use the automatic peak integration for the adcs. We have 4mcp's. 3 of them are downstream of the sample, one is in the FFT just under the sample and measures fluorecence from the sample. the automatic peak integratio has been set up for the 3 downstream mcps only. So this code here only works for these mcps. If you would like to use the 4th as well you have to look at the raw data (example at the end of the notebook) and do the peak integration by hand (older version of toolbox). The raw data is recorded all the time anyway. Mcp4 has been switched on after run 181." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import importlib\n", + "import logging\n", + "\n", + "import numpy as np\n", + "import xarray as xr\n", + "import pandas as pd\n", + "import extra_data as ed\n", + "import matplotlib.pyplot as plt\n", + "\n", + "import toolbox_scs as tb\n", + "import toolbox_scs.detectors as tbdet\n", + "import toolbox_scs.misc as tbm\n", + "import toolbox_scs.detectors.dssc_plot as dssc_plot" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "logging.basicConfig(level=logging.INFO)\n", + "log_root = logging.getLogger(__name__)\n", + "#%matplotlib inline\n", + "#xr.set_options(display_style='text')" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:extra_data.read_machinery:Found proposal dir '/gpfs/exfel/exp/SCS/202002/p002719' in 0.044 s\n" + ] + } + ], + "source": [ + "proposal_nb = 2719\n", + "run_nb = 194\n", + "\n", + "run_info = tbdet.load_dssc_info(proposal_nb, run_nb)\n", + "fpt = run_info['frames_per_train']\n", + "n_trains = run_info['number_of_trains']\n", + "trainIds = run_info['trainIds']" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9170" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "n_trains" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "buckets_train = ['chunk1']*3000 + ['chunk2']*3000 + ['chunk3']*3170\n", + "buckets_pulse = np.linspace(0,fpt-1,fpt, dtype=int)\n", + "\n", + "binner1 = tbdet.create_dssc_bins(\"trainId\",trainIds,buckets_train)\n", + "binner2 = tbdet.create_dssc_bins(\"pulse\",\n", + " np.linspace(0,fpt-1,fpt, dtype=int),\n", + " buckets_pulse)\n", + "\n", + "binners = {'trainId': binner1, 'pulse': binner2}" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:extra_data.read_machinery:Found proposal dir '/gpfs/exfel/exp/SCS/202002/p002719' in 0.0023 s\n", + "INFO:extra_data.read_machinery:Found proposal dir '/gpfs/exfel/exp/SCS/202002/p002719' in 0.0021 s\n" + ] + } + ], + "source": [ + "bin_obj = tbdet.DSSCBinner(proposal_nb, run_nb,\n", + " binners=binners,\n", + " dssc_coords_stride=2)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Frozen(SortedKeysDict({'trainId': 3, 'pulse': 52, 'x': 128, 'y': 512}))" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bin_obj.get_info()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:toolbox_scs.detectors.dssc_misc:loaded formatted tim data.\n", + "INFO:toolbox_scs.detectors.dssc:binned tim data according to dssc binners.\n" + ] + } + ], + "source": [ + "bin_obj.load_tim()\n", + "tim_binned = bin_obj.get_tim_binned()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:toolbox_scs.detectors.dssc_misc:loaded formatted xgm data.\n", + "INFO:toolbox_scs.detectors.dssc:binned xgm data according to dssc binners.\n" + ] + } + ], + "source": [ + "bin_obj.load_xgm()\n", + "xgm_binned = bin_obj.get_xgm_binned()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[<matplotlib.lines.Line2D at 0x2ad43da66390>]" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(xgm_binned['xgm'][0,:])\n", + "plt.plot(xgm_binned['xgm'][1,:])\n", + "plt.plot(xgm_binned['xgm'][2,:])" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[<matplotlib.lines.Line2D at 0x2ad43dca0898>]" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(tim_binned['tim'][0,:])\n", + "plt.plot(tim_binned['tim'][1,:])\n", + "plt.plot(tim_binned['tim'][2,:])" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[<matplotlib.lines.Line2D at 0x2ad43d942160>]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX0AAAD4CAYAAAAAczaOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nO2de5hcVZXof6uqqzuVRNN5oJJOEHQYvKKYQFS8yTADiIhKiKjxgcIo3PjAUZAJBIfPJIxIIDO8ZuSlcgcENeFhE8QZhIQZDXdAE5MAURFQgXR4JCSdMUmnu7pq3z/OOdWnqs4+j6rq7uqq9fu+fKk+deqcvc/eZ+21115rbTHGoCiKorQGqdEugKIoijJyqNBXFEVpIVToK4qitBAq9BVFUVoIFfqKoigtRNtoFyCMadOmmUMPPXS0i6EoijKm2Lhx405jzEFB3zW00D/00EPZsGHDaBdDURRlTCEiz9m+izTviMgtIvKKiDzpOzZFRB4Ukafd/ye7x0VErhORZ0TkcRE52vebs9zznxaRs2qtlKIoipKcODb9fwPeX3ZsCbDWGHM4sNb9G+AU4HD33yLgBnAGCWAp8G7gXcBSb6BQFEVRRo5IoW+M+Tmwq+zwacCt7udbgQW+47cZh0eBThE5GDgZeNAYs8sYsxt4kMqBRFEURRlmqvXeeb0x5kX380vA693PXcALvvO2ucdsxysQkUUiskFENuzYsaPK4imKoihB1OyyaZzkPXVL4GOMudkYM8cYM+eggwIXnxVFUZQqqdZ752UROdgY86JrvnnFPd4DzPSdN8M91gP8Tdnx/6zy3kod6N7Uw8oHnmJ7bx/TO7MsPvkIFswOnHwpitJEVKvprwE8D5yzgHt9x890vXiOBfa4ZqAHgPeJyGR3Afd97jFlFOje1MPF9zxBT28fBujp7ePie56ge1PPaBdNUZRhJo7L5g+B/waOEJFtInI2sAI4SUSeBt7r/g3wU+APwDPAd4AvARhjdgH/CPzK/Xepe0wZBVY+8BR9uXzJsb5cnpUPPDVKJVIUZaSINO8YYz5p+erEgHMNcK7lOrcAtyQqnTIsbO/tS3RcUZTmQXPvtCDTO7OJjiuK0jyo0G9BFp98BNlMuuRYNpNm8clHjFKJFEUZKRo6944yPHheOuq9oyithwr9FmXB7C4V8orSgqh5R1EUpYVQoa8oitJCqNBXFEVpIVToK4qitBAq9BVFUVoIFfqKoigthAp9RVGUFkKFvqIoSguhQl9RFKWFUKGvKIrSQqjQVxRFaSFU6CuKorQQKvQVRVFaCBX6iqIoLYQKfUVRlBZChb6iKEoLoUJfURSlhVChryiK0kKo0FcURWkhVOgriqK0ECr0FUVRWggV+oqiKC2ECn1FUZQWQoW+oihKC6FCX1EUpYVQoa8oitJCqNBXFEVpIVToK4qitBA1CX0ROV9EtorIkyLyQxEZJyKHichjIvKMiKwSkXb33A7372fc7w+tRwUURVGU+FQt9EWkC/gKMMcY8zYgDXwCuAK42hjzF8Bu4Gz3J2cDu93jV7vnKYqiKCNIreadNiArIm3AeOBF4ATgLvf7W4EF7ufT3L9xvz9RRKTG+yuKoigJqFroG2N6gH8CnscR9nuAjUCvMWbQPW0b0OV+7gJecH876J4/tfy6IrJIRDaIyIYdO3ZUWzxFURQlgFrMO5NxtPfDgOnABOD9tRbIGHOzMWaOMWbOQQcdVOvlFEVRFB+1mHfeC/zRGLPDGJMD7gHmAp2uuQdgBtDjfu4BZgK4308CXq3h/oqiKEpCahH6zwPHish41zZ/IvAb4GHgo+45ZwH3up/XuH/jfr/OGGNquL+iKIqSkFps+o/hLMj+GnjCvdbNwEXA10TkGRyb/ffcn3wPmOoe/xqwpIZyK4qiKFUgjaxsz5kzx2zYsGG0i6EoijKmEJGNxpg5Qd9pRK6iKEoLoUJfURSlhVChryiK0kKo0FcURWkhVOgriqK0ECr0FUVRWggV+oqiKC2ECn1FUZQWQoW+oihKC6FCX1EUpYVQoa8oitJCqNBXFEVpIVToK4qitBAq9BVFUVoIFfqKoigthAp9RVGUFkKFvqIoSguhQl9RFKWFUKGvKIrSQqjQVxRFaSFU6CuKorQQKvQVRVFaCBX6iqIoLUTbaBdAqY7uTT2sfOAptvf2Mb0zy+KTj2DB7K7RLpaiKA2OCv0xSPemHi6+5wn6cnkAenr7uPieJwBU8CuKEoqad8YgKx94qijwPfpyeVY+8NQolUhRlLGCCv0xyPbevkTHFUVRPFToj0Gmd2YTHVcURfFQoT8GWXzyEWQz6ZJj2UyaxScfMUolUhRlrKALuaNItR443jlJfqvePoqigAr9UaNWD5wFs7tiC2319lEUxUPNO6PESHrgqLePoigeNQl9EekUkbtE5Hci8lsReY+ITBGRB0Xkaff/ye65IiLXicgzIvK4iBxdnyqMTUbSA0e9fRRF8ahV078W+A9jzFuAdwC/BZYAa40xhwNr3b8BTgEOd/8tAm6o8d5jmpH0wFFvH0VRPKoW+iIyCTgO+B6AMWbAGNMLnAbc6p52K7DA/XwacJtxeBToFJGDqy75GGckPXDU20dRFI9aFnIPA3YA/1dE3gFsBL4KvN4Y86J7zkvA693PXcALvt9vc4+96DuGiCzCmQlwyCGH1FC8xqYaD5yxcC9lbKDeXK2LGGOq+6HIHOBRYK4x5jERuRb4H+DvjDGdvvN2G2Mmi8hPgBXGmPXu8bXARcaYDbZ7zJkzx2zYYP1aUZQqKPfmAmfmd/npb1fB3ySIyEZjzJyg72qx6W8DthljHnP/vgs4GnjZM9u4/7/ift8DzPT9foZ7TFGUEUS9uVqbqoW+MeYl4AUR8QzDJwK/AdYAZ7nHzgLudT+vAc50vXiOBfb4zECKoowQ6s3V2tQanPV3wB0i0g78AfgszkCyWkTOBp4DFrrn/hT4APAMsN89V1GUEWZ6Z5aeAAGv3lytQU1C3xizGQiyG50YcK4Bzq3lfoqi1M7ik48ItOmrN1droGkYFKXFUG+u1kaFvqK0IElyNynNhQp9ZVRRf3FFGVlU6LcQjSZgNfunoow8mmWzRfAEbE9vH4YhAdu9afRCJdRfXFFGHtX0G5h6auZhAna0tGr1F1eUkUc1/Qal3pp5IwpYzf6pKCOPCv0Gpd6mj0YUsJr9s5LuTT3MXbGOw5bcz9wV60bV/KY0Jyr0G5R6a+aNKGAXzO7i8tPfTldnFgG6OrMtnfSrEdddFDtjdYBWm36DUu9Q+UYNyFF/8SGGa92l0by2moGx7HmmQr9BGY5Q+VoF7GgIj1YSWMOx7jKWhVMj04iOEXFRod9g+IXcpGyGcZkUvftzoy7wRkN4tJrAGo5EaGNZODUKQYpHIzpGxEVt+g1EuU23ty/HgVyBqz8+i0eWnFCXl7RaO+Ro+NS3mh//cKy7jGXh1AjY1lk6x2cCzx8Lnmeq6TcQy+/bOqxaWS2a82gIj5G+52ibkoZj3UXTKNeGTfHoaEuRzaTHZKZSFfoNQvemHnbvzwV+19PbR/emnpoFUC1T/dEQHiN5z+E0JSUZTOq9sB20NpRJCfsHBjlsyf2jbjZsdGwKxp6+HFd/fNaYXG9Sod8gRJks6iGAatGcRyMH+0jeczg9Z0ZzXaJ89jApm2HfwGBRwUhantGeDY00YYrHWPU8U5t+gxAleOthy64lQGu0fOo72oa66OTxmWG753B5zlywesuor0ssmN3FI0tO4I8rPsiEjjZyeVNVebo39bD4zi0l9u3Fd24ZM/7p1dCI8S21opp+g2DTKPzUasuuVXMeLs0mSHsEKsp6IFeo+709bM9/UjbD3BXrEmu2noafNybw+9FaSK1lcFu2Ziu5Qml9cgXDsjVbx6TGG4dGjW+pBRX6DcLik49g8Z1bKl4qP7XashuxA9vMH+MyqRF1NbTZvvcNDNLbl9wUEmQu8jNaC6m1rJN4zyHu8WZhrJpxbKjQH0aSLuAtv2+rdTE3k5aap5SNaI+12dJtAnO4NOSgAXG/z/btL1ucgSesnPU2DyRpV90ft3b8z/usib/kwswqxve9BJNmwInfgKMWjnYRQ1GhP0xUs4DXaxH4ANgnAMNWnpEgqRAfTg25XKM7bMn9gefFKbNNo06L1HVdImm71jLbmzw+E6iUTLb4rDcj/uc9P7WeC3PfZfzggPPlnhfgvq84n22C//HVsPZS2LNt1AYJXcgdJqoJLAoTaLmCqWnxr1EDnWx17sxmRn0BrZaFb9sC4D8vfEddB9lq2tW/sJsk6G/pqUeSSUvJsUxaWHrqkckLPkbxP+8L21YzXgZKT8j1OUI9iMdXO4PCnhcAMzRIPL56eAtdhgr9hMSNaK1mwSxIUMT9bRSNGplpE47L5h856hk4a/HcGClvp5Fs1wWzu1j50XeU1GnlR+s7iCVlpDNd+p/rdNkZfNKebcHH117qDAp+wgaJYULNOwlIMpWuZsHMu8YFq7cEen3UYtoYlkCnOkxVo8wNoylQal34HokFwJEOmmukRc3RMFn6n/d2M40ZQYJ/0ozgH9sGA9vxYUKFfgKSBPBUu2DmXafei231XMDr3tTD5vtv5sLc9UPT2zj2TAuNJEjKaeSyQWsvzI5GMjn/875ycCErMt8tNfFkso7yE8SkGa5pJ+D4CKJCPwFJptK1aInV/jbMi6Ne7pqedvWg3M74lMWemVDox/E+aUTPo0agEd1wR4rRMFn6n/d9vfOYkmm3eu+U99lr3vp3vPOJpaUmnrBBYpgQYwkeaQTmzJljNmzYMNrFKDJ3xbrAqXRXZ5ZHlpwwCiUaonyqC47GV287svcM/tDxKVISdIbAst7Y14tT7pGqW9zyNrqAHe4yNsozaLT3sTwt+r6BwZLo52wmzW3vfI53PvsvJSbR7vzcuj9PEdlojJkT9J1q+glYfPIRLL5rS0lDxvWfH+4XZaSmuturtWdaiFPukZzGh7VTo7q9+olTxmr7YvemHpat2VoSjDWaz6Bepq3y53H8Ww7i4d/tSDzL9pclKGCtL5fnvN8cziNLnrT+biSep3rvJKV8YhRjolTN3qdJvRJsKRyiUjskxVsgvHJwIftNe+mXVUxV40zRR2oaH9VOtbi9jpSXSVQZq92H1/udTZj5n8FI1bUeHlJBz+P2R59P/HyiIrA9yvvsaLhSq9BPwMoHngrMPRLVQEkbtpoXMy2Bthbr8Wrx3BjXFOaxJHcO2wrTKBhhf/ZgOPW6xPb8OL7wtfjLJyGqnaodfEZyw/OoMobVMUxYRwk17/pRda33gLBgdheLTz6C6Z1Ztvf2FesRlzjCOo4QjquAlPfZ0ViXUPNOAqptoKS/izJneNPRnt4+0iLWpF4AeWOYu2Jd3cxJC2Z3seG5XfzwsRdYU5jH/bm/4pPvnsk3F7y9quvFmaJXO41PasYIa6fuTT2kLM86avAZSfNUlAunrY6ecLaZGaL6uHf9qIHTdg/vt9UmtqvWPBJXuMapf9SsurzP1tKnakE1/QRUq3Em/V2U8PE0KSBU4HskmcJHaWHdm3q4e2NP8b55Y7h7Y0/VGlucKXo10/hqtGtbe0zKZqwZM22Dj/9Zhpne6m0CiQoos9VRhFBhHdbH/dcP67u2AWHZmq1Vz4SqNY947RPXjSXqHQ967pmUMHl8JrDPhmVhHW6X25o1fRFJAxuAHmPMh0TkMOBHwFRgI/AZY8yAiHQAtwHHAK8CHzfG/KnW+48k1S7kJtVUw7S1oC0V4xClWcbVmIZDaw3zhS/X1q/++KxY96mmnLZ2ChKIYM+jE+RtZMMv5KD2xbsoF05bNlFbdldPiAf9Dpy8O0tPPbJ4/bC+axsQwtYJqk1s5z8etFB798ae2O9RJhX9jid1nbWZleqdmymIeph3vgr8Fnit+/cVwNXGmB+JyI3A2cAN7v+7jTF/ISKfcM/7eB3uXxfimAI2PLerYgOKOKpC0g5hEz7Hv+Ugbn/0+WQV8xE2RY0rJEfSBjkce/p6W08GtYWtnc5ftTnwWnljAssRd1HPTz3NPWGDaHkdJ2Uz/M8Be6I/T8ON24fDFBzPJBmXWhLbeeUO6kNh71BnNsOf+wfJ+wfBmMtiSQL5bHUrWPpUPalJ6IvIDOCDwGXA10REgBOAT7mn3AoswxH6p7mfAe4C/lVExDRAoEBcN7c7AjqLt5Ab1VBJOoTtBRuunbMgvjCvd9h/2GBby6yi05IREiiZrZW3dVA72YSVuOUvPz9MWAl2PaHenlY2vDp6/T5kC4cSDTdOH44aHMoHBAHGt6fZN1A5SMZNbBc2i04yAAswoaOtYuaRy8d7x5MwmhvW16rpXwNcCLzG/Xsq0GuMGXT/3gZ4T6oLeAHAGDMoInvc80ucvUVkEbAI4JBDDqmxeNF4W9qV29aCfMVt70atWm6U5ulh0zg9wgRKlJ0wbiesdzqHahYP43jL7D0waP3etl1g2Mzr/FWbA711g3aNsj1LL2jozRf/NNCWW29PqyjiCERP0YhrfrP1Xe8aG57bxR2PPl98lgYYGCyQSUtFIFPcxHZeOYMGmSTvpmeCmp9az4Vtq5kuO9lupnHl4ELu650X+zpxGM30GVULfRH5EPCKMWajiPxNvQpkjLkZuBmciNx6XNPWMZNsaRfWeZKOzmGRe9UkcQNHoNhslSmBjxwTrqUd/5aDSl5GCO6E9Qz7t2ny563azMoHnrJq63G8ZcJ2IAsirH0XzO7iPMuA29uXq9D2o15oW3+LsyjvUY9gvzgCMaw/Bg3a563azPL7tpbY+f08/LsdFYNnrmDozGaY0NFW98R2k7KZWDt7Cc470PbkXU6OfDefzgzZyYrMd5mSaccxatSH0UyfUYumPxeYLyIfAMbh2PSvBTpFpM3V9mcA3hJ8DzAT2CYibcAknAXdYeWM7/w3jzy7q/i3vxMn2dLOJnAFEo3Ol3Q/USJckyxi2YSJf+FnzhunVERNFgzcvbGHOW+cEtipPI+c8pfx6EMmWTW2KM+ZOJ05TOj09PYFupb5haftPtXMvKIGkq6QAbe8raJeaNu1umIqD92beipMVIvv2lJyb9vv/GUKM4H5sfVH2/uze3/OOlDY2mZPX47NS98XWZa4eHWNu5WjAW5/9Hke6bi9Ikf+eBngwswqYHni+4e9A0lMvvWkapdNY8zFxpgZxphDgU8A64wxZwAPAx91TzsLuNf9vMb9G/f7dcNtz7+k+4kSge/hdeIkW9oFuWQJcMaxh8RuOG9dwADzU+tZ3/4V/tDxKda3f4X5qfUl5/b09lW4T8Z1b5zQUTmWh7mx2TyC/t+zuxK5EnZv6mHW8p9x3qrNsdzvogRt+TbowtCMJcwlM+y6mZRUbAQSZ1od9r0t4Z4taKiWPP3gtFe5iSqXNyy/b6v1N5d0P8H5Ze2y98BgxbOwEVTHsPfH1t9GItCu3K05CQcTnCN/fN9LVd1/uIPxqmE4grMuAn4kIt8ENgHfc49/D/i+iDwD7MIZKIaVHz4WkMbUxRuB425p59fe/EFRD/9uR+BiXgWPr+bYe7/Osx072G0m8ho5QLs4dmdvCkkO1hQc26EwtLAXtNgYRhJbePemHqu2Z6jUYm2EuSn25fJcsHoL56/aXKL12NwAbRgc8wCEL/JGuRd6v08yrV4wu4t/+PETsRcc4zgHhOX4CSufrb1sx/3Khp9cwTgLqZkU+3PlQ2x0HaMCkry4kih3ybgDXtwZZDXeU8Uy1yGn1EgG41VDXYS+MeY/gf90P/8BeFfAOQeAj9XjfnEJs5F6nSbIXPKRY7pY+cBTJUIKhgS++K4d5Ubozz3/BhkAgamyt+K88TLAhW2rWTMwL3BBNkmnsU3bO929TP0vTypi8TCuqSTqRbM9r/KFvSiKCd9CBrY49tKkL1/3ph76AgS+LU4j6sW3Dd61RpgGKSBhTggG6IsQ+DahHDVoe0Ft/rrcvbGHjxzTVXNCs6Bo3jgR6l59xmVSge9I4hz5AdgGQlufHemspU2dhiGsA5S7Bto0kZ7ePhbfuQVkyOsjrkAOzT0fwHR5NdKlb+6KdZGdw9bnjal8eaJeEAOx0jgksaP7n1fQwl4YnsZp0zINMGv5zxBxNpqv10u0bM3WCnMTQFtKSq7tT5ERRNRziqMldoYsTgYNEFH3DHv+XSHPzztWvoYE9qC2vlyeh3+3I3Hq47Bo3v7BQuz+3OVT4oIGrDWFeZCDr7ffyRvYmXhHuO5NPdZ3uNoZYb1pXqH/+Go2TLyESQMvs91MY21hFiemNjNddvJq2+s4KH0ZsLBC45q7Yl1FR4jjCRL0YnkddXqHZS/N8muYqRji+XKHdY49FoGwpy9X1dTXG/iW37fVKkjj5B7xE6WxB+HXOMO0zFpS/9q0LpuQ9WvJcSJxo2zXcUxzy+YfyeI7twT2yyAFJGnbeNjy0pd7n3mTRU/J8gSrzcW4moV2W/njLtTa9l8IGrAeTP81J5z25ao90oLeXZvDR9hgNlxCvzlz77i7zk/OvUxKYEZqJ2emH2JGaicpgYPyr1h3oa/W5z7oZfbnno9iv2nnykFHm4ir+XrujW+++Kdc0j001bUJlpRI1QFAuYJh9/6cdWFq8clHxA1cLClj3AW8yeMzJS+tt6jdmc2UnBe0QJ4k/XH5Atz5qzZz6JL7Y5UxzoB6/FsOCv0+zkLngtldrPzYO6zX8KKOPYIWjqPwIsDLnQnKn1FvX65oJskbUxyYF8zuCs1llIRqFkD9/eDRcV/ltnc+F+g9s3np+7jm47NKnCM88255XqQ4uals8sMQrHSEDWazL/3ZsCz+NqemH7DrfIXp2re1X7mNO2iKGBSw4S26+l8Qv4boaViBdsJUht7COF5r9rLdTC25XlLyxhRDy7+54O1WLTiOH3iYa6Kfcm3EZp/PpKTENAZDGnv3ph729duDqGDIQ8qWxbN/cEjTnp9aX/Kc/QvkcYJrgoR21BMbn0kV2z3OYO0tRNuw5cbZPzDIYUvuL1ljCpsRls9uOtpSsWd4QTEf3kA/LhN+Hf9MY/HJRwTOSPYNDMZzfmBoIPYIew/95/j7wRvYwRueWAqHTg400/hn+zZzy4bndgU+D4AF6UccWbJnG/89bhrfGvhYRZmC3HHDTEEQ7vpaC825XeKyTuLpy0L3aVsjp+QfbnuEy9LfKRHa+007S3Ln8BMzj/e8aQq/fn5P4IKw11GGOuurHBj/Bsafcind+bmBC8kpIdBLJIq0CM9e/gHA6VBBUaRheNN52zZ0QVxTlgAtyDwClQttnQHbyYXVq2BM0ZTgmZj2DwyWLMatb/8KM1KVprRthWl8fPx3Iu3Ihy25P9HzSgmkUxKrDh4C/HFFeJBPWPAehC9E+vHMLEGDSN6YwPQL3rO2KT9x8Ndx9qU/Cyxn3C0N/X2xXJjD0HvoF7K2fsCkmXD+k5XHLffzY1sf/NuJv2SZ3FSiZBYMfD//XpYOfg6wm5bivmfVbP/Yetsl2nadDzgvLNtdwRimd2a5TO5hfF9AwIbrbWOLBXj4dzu4/PS3s/KBp1jT6+SezxtDVzbL4rx9IXnVL+1lD9N0/J2yPIo0SkPy2xyTuFIGBSbZtJKo7eRsePUqt9WXMz3I1Q5ngTwqoAuS2b4F52VOOjjHMWf5n+HcFesqnlVfLh+rbXp6g9MZexGw/gVQD3/K7GoxOMJ+6alH0msZmKrJY39h2+rgwCn3PfSw9QP2bEt0Pz+253HOwO2QKv1NSuDMtocQ4KaJ51YVnFjNeXFpTpv+id9w3KzCcN2wbC953hj+uOKDPLLkBGtgxnQJDyj23Ac9m6rfbdGzFXt+5d69Hv7dDuvCsafpeGsTM1KO+cIL7LLlbon6HZTOizx7eVQAmVfHONTiOx0X29rJSzKV81dtZtbyn7H4ri3WoJkktm9D8tlY0uhtqO2FT4uERsAGrYlE0ZnNxHpGu/fnWHzXlqKbcDmRg9/jq+Hqt/HsuDOKfa8rZFD3Y11Di+FrnzRIbHoqWAYI8Jm2h3jkAzutSpDt2dRapiiaU+gftdDZum/STECc/+eczf7swRQQthWmscx8nu783NAkV8VFFEtn2W6mhhYjbDchT8iWC56wl9ym6Sxtu4317V/hmY5PwdVvKy5QT3Y7VZiG5McrhxdbEDVQ+OsYRVzhVUvKsSsHF9JXtm9vn2lnxcDC4qJjULK181ZtZu6KdQDFiOdayxKEbTEPKAo5lnWWtGEtL3zemFCha4veDuND7ziYjxwTz76cyxuMIXn0seuIwZ4XSGGYkdrJysxN1tP976EQvH9zHx2xfO2TLnq/hF0GCLD7vkuYu2Idhy65nzdf/FMOdReBL+l+IjQpoMdwJGFrTvMO0J2fy8r+69h+oI/p47IcP3gQd+9935DwHYBsSLI1cLJanrdqM3878SNcxPVkKbUlet42ULmoFmc3IQ//4leYicE2bZ0iexEv4GvPC84LA3zwqP/F7Y8+H2r2KC+H5/ccFFtQPpVO0iHjbifnD9yJY1f2J+ra+NqTePKth/LOZ/8F9mzjJabxrVzloloQ3uB7+elvL9pPuzf1BLr0+e+dxEzlX8zzm5nOmvhLLjE30pY/4HzptuGv/rSbff2Hxb5+UPmCBIs/oCzpTCJqIbqcPX05zjj2EH742AvkjSEtUhw0AmNOHl8NP/4CmFIlqUOCZ1UFQ8l7aBjytffW0LabqawcXMi1MXztvUE5KPNuEFcMLOSa9uutCkLnwMv09JfuctfT21fh8BBkfv3FuOOtietqoSmFftAKfFDUZ18uHxrA5R39t73vYldqoKQTldvEDZV+yklsxV7gVVCYujegvCIH8QYqX7ogz6T9//4N7t57DWAPLQ+aqXhCzBZb4B8oxmXiTxTjrBOUL3ZF+b0Ljs966UtxAt2bPpR4ww4I3oc4TKiLwARLLvhy/B5eXlS317/OGbidttSB0h/k+pi+8Up6+6+LvHaQfd4LjgoyFU5ob6tqHQOSDxKTspmK7TVX/fIFVv3qhZKEceet2sxj997IP6Zvps0kM5v530PP+2xNYV6Jnd+WzC4oTcTDv9sRe01jw2tP4p7+P3B64T8q30Mgb3IxbSAAACAASURBVDGmlAv8IK+zJQdg5QOOiK6n4G9K804S17u8MbGm8WsK85g3cB1v6r+DeQPXBWqPeWOKWlR5qt04U0Z/mLrfb/jqj8/iTys+yBtO/xaD6XGl9bJUbFzfS8VnEDTdLZ+plGOzi/oHCs+lLI4vsbdOYDOnpUU43zWzeNfzfmMjyFxSS7ItcNrAb/sPY/f+XDEXfBiTx2eKnlzeNf3NZp2JsbNiLaX8TtlMmmXzjwxMxGdbRO3tyxWf8+KTj3DcamMyvTMb2+SUSUtgVG6uYAI9ns4t/GBothMTfz8VscdBBB0Pisu4/dHnEy3m9/T2cUHfmdZzUoFx3KWEmV+HI1lbU2r6cbWRKI+WOD7B5ZxifsG77v07uPdVZy3g8PexYOuPOS29C9Kw20xkWe5M63VCw9SPWsg312zlnMLtxRnHeDnAFCpz+WwvDAnnoOluVF2CYguCBoq40YOeRuUNsuWvvC03z4LZXUWtvbw9vtv+acpznMdZMJ4ckVI4ickmVzBkMykG88aqWIxvb+Ph3+0olqu8Hr1MDGxDkcpkfAZHqAd5H5XPksKcwL3n/JFjuhiMufeAf69Y2/4CfiZ2tMVK3exh9boB+k0aQYpJCqGyP6awm5+CjtfqXOB/aj2W2XSBFPNT60PftSjza72TtTWln34c/9con9+g742B3diFdtBvghgwbfx9blFoR7C92OXRoUH37KODiwbOrjrYy3/tuAPFp0MCqILMNJ48EgmerfhdZg+dmmXqH9dU1HNAOmj/8L+WBNzE8bX/04oPJtq8vFY8PdpLqV1ejyCBVs62wjTmDVwXy2e7e1OPNU1DUNmSSIBPH3sIc944JXYMSJLr2/zrB02Kr+W+ACRTXDy8fjwj9WpJLp2kcRlR97C9+0GxBH7C4kvmDTjmvTjxHX7C/PSbUujHeaGjHrQ1wAN7I4b9xnafIMpfFC8q1fayzU+t5+vtd/J6drLdTOWKXPXRvXGyFNrKfHVZoJaHbRCOuxAqwC9iBtxEDfh+oRmUHK2a2V0UXb5AMlsfebUwkT7G0SU7A23DBSMcWfiRs+7hiwANSgiWJLiuGlJC6L661RIoODNZfvX25fyfTYclmoFFXZNTr2PuT6fV9TnNT63nqsyNtEmlSSfsfY8TdJY0QCtM6DelTb/rhZ/wUOrcUP/yqClVl8X/FoLdHcOuGXafIMrfJ4Ozq8/XVgdrV2sK8/jXWT9m3rh7mNt/XYWJKsrX3iObSfPJd89MnKfFK+MFq7ckykeSZFejsIAbf06UqLQOQUFa3jpDWDxDNpPm08ceUvFsMilhQTr4Gc9PreeRjq+w/sDp/CT/Rean1lvrMVn2MW/gOnosayn/IxOHBL7rzghmyFvLl0eq3sE85QyHwAenHy/JncO2wjQKrqv1r96+nPN+czh7+nJ0dWb59LGHJHKlDbKXk+vjpXu+XlxQr2f5bTb86alXQ9d++kw7xjiz3l1mYonAr7fbZtPZ9H+15ibetvESsgH5V4CiFlcgFdhA3kLldjPVGgwCwULbugFDAFE+/kGEvWxB3klhuWjKtVf/BiM/2fJiVWaPvDEl9nhPsNZDRtie7f7sGxJF+vp33SpPx2tbUPt6+53FrItz3jilOFiMy6Q4Kf9zvtVW+YyPyf+ehW0/L7r5drnHbfZ7rz9cObiQlZmbKlwUO9P9Qxp+WV4pfx4piOeRMxwzmnqwpjCPB81fc/lpjqnQ2RZyKLOsl2MqLrZB9nXGsfFH9c32tDCQIM2GrZ8WjPBU2ycptKVIU6DHfeZAhZY/zgwwob0NOUCFebceNJ1556VlfxHo1vhqYSJZGaiw0fun0lE2/fLr9TGu5KU5JvV7zkw/VHLN8ntAPJu+jSQvaxxboYctT0s1xLlWNpNOdJ/TUuu5vKw9BtPj+KZ8gX/bO7RnT9jzSYvwzwvfYfXB/kPHpwh2ZBFY1ltyxMttZDM7DZKiLUCpCOqH5VP5X3csYkrARjsvcRCvZycSIKoKCGtO21oc1MJs+nFz2NSDTDo8N1E6JeQDytnVmaV3/0BVOaj82N4BY+A2X36cIJLGYQAsSK/nyvbv0W76S+4VZLLbb9o5QHtgW8fJExRGS5l3vBG8nCmyt0KAiziLRAXjROn6O7031Xy1MLFiobHfpHmNHKgwA5yafrSicUUg707bvKlbLQJ/ZeamkvuuzNxkdemLG5QFjhZl2ys3qBxR+/uGeUZ0ZjOhPv5B19952HyuzHypOPXfnz2YttP+hVvLBH5YFPGxb5rMxSEBedY0DkyrMFt5MxjbM06b4Gn+ZNk3ZMII6HcAnQEzAYDXmZ3WGWLBCP9197eZfenPOH/VZiZ0tGF7xLYZzVWZGwPNf0lMhOUMFgyTx2es1wgS+OD0Ib/Ar7YMVw4uDHQUEIEz0utCfxuxqVwg3fl5XDgw1L6DJmW9zngZYLKlrePkCaqWptP0e5a+OdAsYxttC0Z4U/8dodcs92IZLwcCR+dq7xFXe9/Yvoipqcr7vlqYyDEDN1ccT6Lpx8UbePzmh36TZnHu8yX7+4b1qjAt36aF/qN8gZ+PO74kU2dXZ5bd+/qL+7va6ttjpnHD7G4e/t2OULNHlAbs91DyvKjCNMmgvhA0Qyxva5umv63gnH9F+/fI0l/xfb9Js48snexlu5nGNXyCF2d+qJgQ0OtntsVir75LzSLuHPjfsZ4JRO+xG5alNq73TS0zkz92fCqwvsbAYf0/iPx9Ldhnj0NlCGwL1fTjc0UuOBBpNxMDz/c0pzBNojwwy6aJ2SggVg0lTjI0j8BpYNlxfwcKCso6QAcrQ4KyoljadluFvblD8lybub5YvyCB73++D8q5LG+7JfB527TQcws/KApsv0+/X9jYtO4ueZVvLnh75AJnyUJigBZ++6PPF3MTeY/5ysGFgWstEuDhEjRDvDZzPb/uWFSy+DuBynIOmLbiALFk4GwGTeWr2yF5psje4rUvlZs5/OX/KGraXj8L02DHywAXpFYV/47K25QW4Tf/eIo14hXggtSqWLmfbMTNHWXDFhVrO14v5qfWU4i4xy4zseIdTbonb1KaTuhvfO1JgS/ustyZ1qjUJIIX7GYAmzbRJgXrdW0d2i9Ek+CfuK0pzOPO/HEMmhTGOKas1YPHcfzHvhx5Hb+Qfqbj0/zRFc62gUdCnlvQ8/XvZOb/nd0kFb1AHpVdcXpnNoGZIHiucsHqLZznc5tdU5gX6gHi74f7yFb44os4g7ZX/4syqwPzzPzZjCsOPhteexIpiZ6hj5cBzhm4nQ8edXCwF4sFv4nUPpA60cIflF9wqOs1ZdNok5gZh+P3d+RPqDDxGOMcHw7mp9azsX0R12auD3Tf9Nhv2lk+eGaJvOrlNdCWhXsWlSTeqydNJ/QXn3wED6b/uiJlQpgWl1STCNKgbVay8oFgvAxwWdv3ioLU5iEUJERts5UCYrXFfiz9c9qkgIgz+Hw8vY7jut8VKvTKhbT3+zgxCEHPLej5Bj2XqzI30mupo1euMKKyK17z1qdDB/egwemazPXFAW9+an3geoDNzbJAyjXjOIFEYTNE77kdbBFkk2UfMBT674+4DqNLdvLFTQtCPdGCyu0RpuD4n19vX87qXWa7RtgMOM7v43rALR38HLfl31ui/PgXcWtZsyjH60NTU3utSqAxlMgfz5JwoTmXiekc9O3C5o5bD5rOpg9ecNbjJZtWl+O3owvJbPHzU+tZ2nZbUevdRwdZBkjH0L4gxI5nwbPBz0+t558yNwdGbgbZOG224ajfJQkyC6L8uUXZNf30mzTt5AOfT5y1CH+7FnDc46RzpiP4114auLlOnIA8GHpWMOT6u9tMpENyTKA/1GvLGEfIhfWRgnFd/izrMH81cF1xhhE3+tt/7bhtYAyhLoVB54M9Wn1+aj1XZW8pyatT/nz6aOeigUobfTaT5qT8fw2bt1G9PZmi+lDY+t7/G/cVplPdjl/ltNzOWQtmd3HB6i3Fv8sXStcWZvGx9M8jX5ggTSKok0ww/ZZBI/hFS+oV4J/G/tmMYwqVWkR52uP5qfV2z4Cy312VubHEdz9JkFkQ283UCuEbJ/EUOHZpmx4SR1tdU5gHg2WCas8LcM//sf7Ge75R9R4vA1yduZ4UQ204tWxQtQl3EUhjQgf8AilnoTbz3WKcCTgD4Xg5wLMdnypd/M1hjQAtx4ui9ffHsP7pxRvcmT+OPtNejDcIKrt3bAp7+afMzSV9yesHbfkDDJIibQrkSVWUOcsAyyfczbyDpzH3ues5mJ28yDQeeeOX+NYLx7Okv7oUDFGE7VFxIcniGMI2evEolyklyqcheBOHOnvyNKXQ7940lMo1KEDpTHkoUvDaslDGMVWAM4W8I39CrMElCk+IRmlc/sHhwrbVsQeXNimUBG3ZAojiYAysLcwqKWuKQqDmm3Twi7vwlsR+DbDbTADiBddFJNREBFIhs2cv11BQ3dMUWFOYxzH533NGeh1pChignTwd7uBSHmyYjjmYemwrTCsKzijlZ7wM8Jn0Q7FnCADtMlhUPsr7bBsF9tNesi+Fn0kDL3Pac5cV1zS62MmC5y7jV+aL3FmWKrmcaoPN4uxRERbU6L//isx3Q/t0uUxZ3nZLvOcbY8evJDSd0O/e1MP6H1/PxvZ/K5o2gnzngzAGDBKqScTVglMYlg5+jo2Fv+TazPVV+fyCo+WtLcyKpdH5tYik2nrRFj9IoPeIR5Sw3mUmcmJqc+DA6MnCHne2dUbbusAAJhtxZwtJ6+7VJyiz6EjSY6aVrMNAsOLnaaJZGUjUr7abSvPYxsJfhrpxJhH4Hp7yYdOiB01w4JqhcrOUdsmzgm/TnypECtw4kefl2Ab6qJl0OWGKRlCixvmp9bEEfh8dZOvsydN0C7mb77+Zy+SG4kJKkpeix0wLzZcPIR4iZXiLVBe2rbYuwMahnTxnpNdFCvxyLSJuOf1Ml1e5sC3Ye8QYyBspfg7CGFg+eKZV6Hpt0Sl7+Uz6IfYUxjNgSvUOZ+ANJqhOQYtwSeveibNIWrrYX32OmUA3vIjvvfaLO0sJCjb0GDDpiudqm7l6i4hJ+mjUMqCnfNj6QYpCYP1twigtJtSbzja4XJ25IXJxNolTRpgyYTPrGANfzX2Jo/tvLpEpF7attgp8YxhyNhk4uySZXj1oOqF/zsDt1q3VwvC/FGGr+WsLsyKFQbmb5gT6goWbcaJ1w67ned2E3SsoqtPmPx7GdjM1VGCnxYQOpHtNB2sK80KFrghMlAOkBCfQTAx7TUfxRRMJ1i4HTapEaPnd4sq9cdYWZkUKJj/+WA2/ieD7+fcWvb3iXs/vhhcUzR3kpudvv1rXU4yBH+aP5+9zi0Kjfsv7eDvJM1ja7r+2MAvA6om13UwrcSU2BqvJx8PvFVZedpvATYuJdMEO8urbx7iAqzmzrl93LApMrGfrHj1mWmKLgV/53PDak6znVUvTee8UlnWSSpDiy0uNIOKEv+82E3mNHKjYrMHz2ojjyRC4bZoZGmGDpno2r5yoskOpp4VfaIVFXtquFbTIFhcvpxDANZnrY5sGBk30Pf25UqLWN7YVpnGwvBrLmyqsbf1eHLZoaGNgH+MYTz+7zYSSfuR99ryIekJszcvbbina8aParGAcgWrzzIrycrLtFWFzMfQf9xSJsLYdMG38MP83fCL9cIUC5n1XzVpXwQjn5b5YUfa4nklxI9FtbV2O1z+cXP3J8vvYvHwKBs7LfanYR66xpCuPoqXy6fdfdggduT2xz99rOkhhIjvgtoKjvUa5MsZZoAxyCQvLxR2HnBHaMBUvqO1lKBisrqrVLLJ6eC/WbZnL+KvU1ljXiXs/74WwvWT+60H0Nb2p95rCvMiUFfNT661rM156hLCBqDxFgl/4L2+7pSJRX1iZ+8nQTi6xq7FHrS65cbAN5HkjpMr6aVz6CmnapRA4mMfpQ57pMGqhN4mLcVR9bO6fQYpe0CDxpwQbp/hpqTQMHW3BueBtY9sE+mNpHNPl1cipd8HYA6j8BAUwrSnM42u5L1RtR85IZccL2+zCJjDAvptVHLxFvDfJy7Ff7LjnpWRoJhN1vTjX9E+9o6I+Q3c5EyedQlg/Kk+R4Dc3nJFel+hZjZMcqZA62lyNPZNIkkCtarF5FaUD+mk5nsmnnHGSjx0LE4RnOqw24j6IqPqEJbKzbbBZbKtxZwxLVG7VQl9EZorIwyLyGxHZKiJfdY9PEZEHReRp9//J7nERketE5BkReVxEjq5XJUro253o9Lgv23YzNVZnsHXYcoJCyNcU5vH9/HurFrg2vAVYP9Vq8lF47qXDJVgcd8Pki9TlGAPj5UDxZbRGnmKKuXFskbdJHQagLH9NQrfLMAo+mzoEr30MV9v7qSWvTY9xN1EpI8prLInCFBVx32+SbyRkw3OJ9q8BXJW5scL0JQKfST/EVZkbnbbyonLvPbeugr8WTX8QuMAY81bgWOBcEXkrsARYa4w5HFjr/g1wCnC4+28RcEMN97Zj8Wk1ULGYGpd+k+bKwYVcObiQXIAA9RCwhl9XnmtKwvs9lg5+riZvn3K2m2mB+dcjyxfT1OBnv2nnz3TU5KIaxXYzlT+Y18ceGL1B2LgL5n7Tjz/nje1F9867KnMDnfLnug7I3sBfz8RfKYGPpX/O/NT6yJQAw8WAaeOO/AlVCU7PoSLputxW88bEu2B1yc6SvFLee7imMI/Fuc8XF+Lr0ebeIOO1ic2M66U9KSE/AP9+Ue2F8O5R7Q+NMS8aY37tfv4z8FugCzgNuNU97VZggfv5NOA24/Ao0CkiB1ddchsnfoMg7+aUONGs2wrTEjdiO3k+mv4vlrbdRltIZ0zyYnnaoX+q6U3rOtlbly3pPE+KemjGQew1HSVeDxsKh/MW6QmNg6gFYxwtbF7MtQJwtMbD+n/AV3NfAuz+1wASIjbaxDBRgiOvq8UzwwQlBKsFz4//qsyNkU4Htd43Z6Q4mBoDe804/j63iI2Fvwx9nkHlMAYO4LhPJhkIRYi9flT+O39eKf/eFGsK81g+eCZ57Pnwk+K5RFcVB9K3qz6FoE4LuSJyKPBz4G3A88aYTve4ALuNMZ0i8hNghTFmvfvdWuAiY4x1pbba3Dtm2aTA7uat/lezYFrL4mYc4uzsVQ0FA+sLRzIn9XSFx0OYXT8O/qATIFTD9xbRqgn28V/jF4UjEy0Q72Yi9+WPDY11KBgnIK/ei5th7Ve+wLe87RY+nX6oJMXDcN07yTnl5w95uu1jt5lg9XSLWmwPY79pZ0Ph8Ip2ruV9iPvbvBEEE+jFVytONPTO6t+BZfEdVIZ1IVdEJgJ3A+cZY/7H/51xRpREo4qILBKRDSKyYceO4F2woniZgwKP7zYTQqdW4eWqqiixse3sVSspgXmprdyZP64YdGRcrx7v+tVqfJ7pY2XmJv4pc3NoeQ3B0aVJ75dEo/PKd2b6odA2D4tPqIWwAbDco2Pp4Od40UyrWz+LZWJMcK9+k2Y3E5kse9lvxnFe7ov0Ma5CKHoLl7Ws6YyXAY6U5xgs6zG1PJu4v/V8+6em9tZV4BfcWWrVs+7slLqVpSahLyIZHIF/hzHmHvfwy57Zxv3/Ffd4DzDT9/MZ7rESjDE3G2PmGGPmHHRQsPCO4vKBj1VE2RUMdMjgiIfYe9F1o+kZmxI4MbWZtYVZgdp9rYKmQ/KRL0gtGn6thA5G7oJuWErnerPLTKwpxcdI4SkDrxYmIkiF95FNsHsmk1qYInvJ1OCp04isKcyrKmhygDScckXdylGL944A3wN+a4y5yvfVGuAs9/NZwL2+42e6XjzHAnuMMS9We/8w/qvjeO7MH1fycFMCEzhg/9Ew0WOmcV7ui5HnDZcd3GO67OQzIb7gI7HQV4971Luc3mxgMnsDvZxqJaj9XuPzGvIzXGsv1bLLTOSw/h9YNfrh3HlqJBeeRwKDE817TeZ69vki0CN/Z2DL0ZfXNRVDLQnX5gKfAZ4Qkc3usa8DK4DVInI28BzglfanwAeAZ4D9wGdruHco4mq25drlSHckz30uScbLcupV5kINkbaNwnCuq3jZMZPknS8nbvm8TJQMlkZQry3M4mNSe1bWejFF9oanOXBz6DRKeRuZtFDMXPsa6Y+vzAm8c/7n61qWpovIBWfT6iRRdcPJfjcX+WhqLgOmjQyDY1J78qeasG1IX08KrgdJ0gX1ahZFofQ3+007d+aP48TUZqbLq/SbFOMkeEOZehJVdtv3gybF13JfKOa5lyojbZUQ2ifA17cn/llLReR6m1aP5FTZGIrJo8ppBC1ISJ6ArlEoIHw19yXmDVzHffljK+yh9XBt9SPAOAYqfPojf1eFu2CQ++gZ6XVcObiQN/XfERhlXSsFQzHBnX8BP0z3s5UhTYFrMtcD8P38idbfN7Be2fD0DqTo3lSx9FkTTSf0Vz7wFAZnpXykOls+Ymeo4dJ+4tZvOITHSJEWw8rMTTzZ8VnOLMs/bly306TtHCXgUsKIRa6W44/erGekLjj1/n7+vXw9dzYDpIsDj/cvqReXP61B3NxBSjImmT+z/sfX11XwN53Q397rbACypjCPfXQM+/38aZTjdvp6DEatpD11SD4wMMovsOLiZcVsZLzgqnojAmemH+LazPWB6cerSSfh/2013411hvs9FIFL5WY2339z3a7ZdEJ/eme2+Pnu/F/VffpfTjUdutaAqCRmB6UUERjPAQaHwVOnnjjb9dX/urUIdqWSWpITxmW8DHDOwO11u17TCf3FJx+BQHHbuUZYzK0n1Wi3SikpGdqkvFHR9h07jERbTU9VJmislqYT+gtmd/EXr5vAssxtDbGIqoweUbZ7FazKWOFA9g11u1bTCf1Lup/gf+18gMkMr2uf0vioUFeagYKB8adcWrfr1RKc1ZD88LEX+FX7bfrCK4rSFIhQ14jcptP088aolq8oStNgpL5iuumEvir4iqI0E2LqG6/RdEL/1NT6KvaJUhRFic9Ien71FOqbXaDphP6Fbaubzk1TUZTGYqTWDPebdr6d+lRdr9l0Qr/RcpIriqJUg7fZzuqB92gahjD62iaNdhEURVFqxuCkk8kXDCsfeKpu1206oT+hPT3aRVAURakL3mY7Xk6xetB0Qt/Ucdd4RVGU0SIlcEXbTUBpTrGar1u3KzUIY3tvKEVRlCHGSZ75qfUsPvmIul2z6YR+Sv01FUVpEkTgosxqFszuqts1m07oa3SWoijNRL09EptO6OfIjHYRFEVR6odBXTbDSDM42kVQFEWpK+qyGUKqkXfGUBRFSUgBddkMJV/njHSKoiijSY42ddkM47k3LmzobfAURVGS0MEgX33dprpdr+mE/ps/exP7ZdxoF0NRFKUuiMBxz99Qt+s1ndAH+M3Rl1JQbV9RlCbhdaZ+bptNKfTfeehk3S5RUZSm4RWpX0795hP6j6+G7i+1RIyWrl00BtoMynBiDOx744l1u17zCf21l0IhF+vU4RCaIykAdDZTG/Vq/7HeDIMm1dwKRHYKZMK9Xxq5/iLw5t5H6na95hP6e7bFOm2/aee2/HsZNPV9ZWXMi4DWYaQGzVrkyXALoz46uCD3hXgjl4zBtOWZLJxyBZx6Xe3lT7fXWJjghxyriWPKtTg0n9CfNMP6lTHOv22FaSzJncPSwc/xzcxXoV6+/ZIOvb+VzIRYpxncOiS/Q+zrjyrZKTDn7EitzKORtTM/tYwtwzowZaeQPf1fufZbl8cr44dvdNqnTsRtvqoz506a6Qj7oxY6/z58Y+jp+02IUM9OgdO+7VwTcf5OIjckDXM+5/6eoQFo0sx4z74auWKh+YT+id+AVGX+HQP8wJzEYf0/YN7AdawpzCObSTPrg4vgwzcF/iYxx/ytc/+YQgtwzm3riHGiIHPORpbvQbyOU1ei5ijidNgIoWx9kcOm2Ol2OP07cNEf4UNXOS9qdkpoaQzwSzmKbYVpFILum8k611y2x/l3+neGXrgIwgeTRn5lEowQ2SnO8z5qofvTGFrwfV+BQ46tj+CXVGRpjYFd5jVsPPrK2G3nuwGc/+RQ/cD5bOlXPWYaV2a+RH8mYOc9b7Zw1ELnmst6nWf34Zviv+smD1t+AHteGPo7k3XkRVTd0u3OeXVixHuwiLxfRJ4SkWdEZEndb3DUQlhwfWnjZqcgp3+HCR++lq7OLAJ0dWa5/PS3OylLg36TBEk7L8KHrnKudep1QxrBpJn260raObdvd9jFnWucfrNzfQgeWFIZ9z6uFhI1FfWf713f1vkmzXQ6+vlPDglli5CQIOHun2IHaDqc9u3Kl/OiPzqC2oIgvHvZL5hx6bOklu1BikJdSjU8/zXPfzKW8BhMZ4O1y+wUOP0mp1xJBvaRYNJMYuvOXnv4OeZvo3+X63PWzD50lTOQzjm7OpPJpJmxpmkiMG78RN45//P2Pm8bOmya8SlXBPbPGR+9nGWXLKfjH573KQiWvuRR/q6HyQ9JO8/Pj/c8wxRFb4YRdP8qETOCc2QRSQO/B04CtgG/Aj5pjPlN0Plz5swxGzZsGLHyFbn6bUMjsp/sFGif4NjXJs1wGitOYzy+2tGS/I2eyQ51Jtv9Js10BJXtmmsvtZel/PvD3wdP/yy87FHljHsuhJctCdU8mzCCyu0nbh38z3dYDWMSfv10+5BQqLXf/uRrsOGW8PshjgJQzrLOiN+5eM937aXBZQ27X1Cfh/h91iPq3amFoGeYydr7m1e/OpdJRDYaY+YEfjfCQv89wDJjzMnu3xcDGGMuDzp/1IR+EuGX5Jq2Rh2O+1VLks43nC+P/x7D2RbZyc6xvt3V12FZgEnATyoDR5/pDrovOFqfyTvCeGAv5AeCf5fJwjs+NTRYZyfDYD/k9jnfZ6cMmR28etXjWT2+Gn78BaeM5dgG26QDTtTgG3W/8vIOdz9MQlB5bINctcpLBI0kBnmFngAABZNJREFU9D8KvN8Yc47792eAdxtjvuw7ZxGwCOCQQw455rnnnhux8pUw0h2p0TpuI9Hoz8Ym8MB5qeMOnPUYgOr1rJIOINUMOOV1Lx8AR0vxGQ5GWLEbU0Lfz6hp+oqShEaaqdWTpANIrQNOow/utTKC9WskoT82zDuKkpRmF1jKmCJM6LeNcFl+BRwuIocBPcAngE+NcBkUpf54vuCK0uCMqNA3xgyKyJeBB4A0cIsxZutIlkFRFKWVGWlNH2PMT4GfjvR9FUVRlMYOL1QURVHqjAp9RVGUFkKFvqIoSgsxoi6bSRGRHUAt0VnTgPrtMzZ6NEs9QOvSqDRLXZqlHlBbXd5ojDko6IuGFvq1IiIbbL6qY4lmqQdoXRqVZqlLs9QDhq8uat5RFEVpIVToK4qitBDNLvRvHu0C1IlmqQdoXRqVZqlLs9QDhqkuTW3TVxRFUUppdk1fURRF8aFCX1EUpYVoSqE/7PvwDgMi8icReUJENovIBvfYFBF5UESedv+f7B4XEbnOrd/jInL0KJf9FhF5RUSe9B1LXHYROcs9/2kROatB6rFMRHrcdtksIh/wfXexW4+nRORk3/FR738iMlNEHhaR34jIVhH5qnt8TLVLSD3GXLuIyDgR+aWIbHHrstw9fpiIPOaWa5WItLvHO9y/n3G/PzSqjrEwxjTVP5zsnc8CbwLagS3AW0e7XDHK/SdgWtmxK4El7uclwBXu5w8A/46zgeqxwGOjXPbjgKOBJ6stOzAF+IP7/2T38+QGqMcy4O8Dzn2r27c6gMPcPpdulP4HHAwc7X5+Dc7e1G8da+0SUo8x1y7us53ofs4Aj7nPejXwCff4jcAX3c9fAm50P38CWBVWx7jlaEZN/13AM8aYPxhjBoAfAaeNcpmq5TTgVvfzrcAC3/HbjMOjQKeIHDwaBQQwxvwc2FV2OGnZTwYeNMbsMsbsBh4E3j/8pR/CUg8bpwE/Msb0G2P+CDyD0/caov8ZY140xvza/fxn4LdAF2OsXULqYaNh28V9tnvdPzPuPwOcANzlHi9vE6+t7gJOFBHBXsdYNKPQ7wL8G5ZuI7yTNAoG+JmIbBRnn2CA1xtjXnQ/vwS83v08FuqYtOyNXKcvuyaPWzxzCGOoHq5ZYDaOZjlm26WsHjAG20VE0iKyGXgFZwB9Fug1xgwGlKtYZvf7PcBUaqxLMwr9sco8Y8zRwCnAuSJynP9L48zrxqR/7VguO3AD8GZgFvAi8M+jW5xkiMhE4G7gPGPM//i/G0vtElCPMdkuxpi8MWYWMANHO3/LSJehGYV+DzDT9/cM91hDY4zpcf9/BfgxTod42TPbuP+/4p4+FuqYtOwNWSdjzMvui1oAvsPQNLrh6yEiGRxBeYcx5h738Jhrl6B6jOV2ATDG9AIPA+/BMaV5G1r5y1Uss/v9JOBVaqxLMwr94j687ir4J4A1o1ymUERkgoi8xvsMvA94EqfcnrfEWcC97uc1wJmux8WxwB7flL1RSFr2B4D3ichkd6r+PvfYqFK2VvJhnHYBpx6fcD0sDgMOB35Jg/Q/1/b7PeC3xpirfF+NqXax1WMstouIHCQine7nLHASzhrFw8BH3dPK28Rrq48C69zZma2O8RjJ1euR+ofjifB7HHvZP4x2eWKU9004q/FbgK1emXHsd2uBp4GHgClmyAvg2279ngDmjHL5f4gzxc7h2BfPrqbswOdwFqWeAT7bIPX4vlvOx92X7WDf+f/g1uMp4JRG6n/APBzTzePAZvffB8Zau4TUY8y1C3AUsMkt85PAN9zjb8IR2s8AdwId7vFx7t/PuN+/KaqOcf5pGgZFUZQWohnNO4qiKIoFFfqKoigthAp9RVGUFkKFvqIoSguhQl9RFKWFUKGvKIrSQqjQVxRFaSH+P2Eyj5k+88FSAAAAAElFTkSuQmCC\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(bin_obj.xgm.sel(pulse=20)[0:3000], 'o')\n", + "plt.plot(bin_obj.xgm.sel(pulse=0)[0:3000], 'o')" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[<matplotlib.lines.Line2D at 0x2ad43d97c128>]" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(bin_obj.tim.sel(pulse=20)[0:3000], 'o')\n", + "plt.plot(bin_obj.tim.sel(pulse=0)[0:3000], 'o')" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[<matplotlib.lines.Line2D at 0x2ad43d90beb8>]" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(bin_obj.xgm.sel(pulse=2)[0:3000], bin_obj.tim.sel(pulse=2)[0:3000], '.')" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[<matplotlib.lines.Line2D at 0x2ad43d807c50>]" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(bin_obj.xgm.sel(pulse=2)[-3000::], bin_obj.tim.sel(pulse=2)[-3000::], '.')" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "# this is how the correlation should look like ideally (run from last week)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# how to access the raw mcp data" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:extra_data.read_machinery:Found proposal dir '/gpfs/exfel/exp/SCS/202002/p002719' in 0.0023 s\n" + ] + } + ], + "source": [ + "run_obj = ed.open_run(2719, 194)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mcp4 = run_obj.get_array(*tb.mnemonics['MCP4raw'].values())\n", + "# other mnemonics: MCP1raw, MCP2raw, MCP3raw" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.plot(mcp4[0,:])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "xfel", + "language": "python", + "name": "xfel" + }, + "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.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/scripts/format_data.py b/scripts/format_data.py new file mode 100644 index 0000000000000000000000000000000000000000..5fa68313b4e33215df4df224ba920298c9e2e13f --- /dev/null +++ b/scripts/format_data.py @@ -0,0 +1,50 @@ +import os +import logging +import argparse + +import numpy as np + +import toolbox_scs as tb +import toolbox_scs.detectors as tbdet + +logging.basicConfig(level=logging.INFO) +log_root = logging.getLogger(__name__) + +# ----------------------------------------------------------------------------- +# user input: +# ----------------------------------------------------------------------------- +run_type = 'static, delay, .....' +description = 'useful description or comment .....' +#add xgm data to formatted file if save_xgm_binned was set to True +metadata = ['binner1', 'binner2', 'xgm_binned'] # ['binner1', 'binner2'] +# ----------------------------------------------------------------------------- + + +def formatting(run_number, run_folder): + log_root.debug("Collect, combine and format files in run folder") + + run_formatted = tbdet.DSSCFormatter(run_folder) + run_formatted.combine_files() + + run_formatted.add_dataArray(metadata) + + attrs = {'run_type':run_type, + 'description':description, + 'run_number':run_number} + run_formatted.add_attributes(attrs) + + run_formatted.save_formatted_data(f'{run_folder}run_{run_number}_formatted.h5') + log_root.debug("Formatting finished successfully.") + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--run-number', metavar='S', + action='store', + help='run number') + parser.add_argument('--run-folder', metavar='S', + action='store', + help='the run folder containing fractional data') + args = parser.parse_args() + + formatting(str(args.run_number), str(args.run_folder)) diff --git a/scripts/format_data.sh b/scripts/format_data.sh new file mode 100755 index 0000000000000000000000000000000000000000..01e6659ece073ab8b8011d149c3f71af16e57334 --- /dev/null +++ b/scripts/format_data.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +RUN_NR=${1} +RUN_DIR="../processed_runs/r_${RUN_NR}/" + + +if [ -d $RUN_DIR ] + then + echo creating formatted .h5 file for run $RUN_NR in $RUN_DIR +# module load exfel +# module load exfel_anaconda3/1.1 + python format_data.py --run-number $RUN_NR --run-folder $RUN_DIR + #chgrp -R 60002711-part $RUN_DIR + chmod -R 777 $RUN_DIR + else + echo run folder $RUN_DIR does not exist + echo please provide a valid run number +fi \ No newline at end of file diff --git a/scripts/process_data_201007_23h.py b/scripts/process_data_201007_23h.py new file mode 100644 index 0000000000000000000000000000000000000000..6b9873c0d53c0cdd3a5ab3878df65b381e9b3901 --- /dev/null +++ b/scripts/process_data_201007_23h.py @@ -0,0 +1,168 @@ +import os +import logging +import argparse +import h5py + +import numpy as np +import extra_data as ed + +import toolbox_scs as tb +import toolbox_scs.detectors as tbdet + +logging.basicConfig(level=logging.INFO) +log_root = logging.getLogger(__name__) + + +# ----------------------------------------------------------------------------- +# user input: run-type specific +# ----------------------------------------------------------------------------- +proposal_nb = 2599 +output_filepath = "../processed_runs/" + +# these get set by the shell script now! (e.g. "--runtype static") +# runtype = 'energyscan' +# runtype = 'energyscan_pumped' +# runtype = 'static' +# runtype = 'static_IR' +# runtype = 'delayscan' +# runtype = 'timescan' + +# useful metadata to be added to h5 files +scriptname = os.path.basename(__file__) + +save_xgm_binned = True + +# optional prebinning methods for DSSC data +normevery = 2 # 2 if use intradark, 1 otherwise +xgm_mask = True # True: xgm_threshold will be used to drop corresponding DSSC frames accordingly to the xgm treshold +xgm_threshold = (1000, np.inf) # or you mean bad pulses here ? +filename_dark = None # 200 +xgm_normalization = False + +# ----------------------------------------------------------------------------- + + +def process(run_nb, runtype, modules=[]): + run_description = f'{runtype}; script {scriptname}' + print(run_description) + mod_list = modules + if len(mod_list)==0: + mod_list = [i for i in range(16)] + + path = f'{output_filepath}r_{run_nb}/' + log_root.info("create run objects") + run_info = tbdet.load_dssc_info(proposal_nb, run_nb) + fpt = run_info['frames_per_train'] + n_trains = run_info['number_of_trains'] + trainIds = run_info['trainIds'] + + # ------------------------------------------------------------------------- + # user input: run specific + # ------------------------------------------------------------------------- + run_obj = ed.open_run(proposal_nb, run_nb) + + if runtype == 'static': + buckets_train = np.zeros(n_trains) + pulsepattern = ['image', 'intradark'] + buckets_pulse = pulsepattern * (fpt // len(pulsepattern)) + + if runtype == 'energyscan': + buckets_train = tb.get_array(run_obj, 'nrj', 0.1).values + pulsepattern = ['image', 'intradark'] + buckets_pulse = pulsepattern * (fpt // len(pulsepattern)) + + if runtype == 'static_IR': + buckets_train = np.zeros(n_trains) + pulsepattern = ['unpumped', 'unpumped_intradark', 'pumped', 'pumped_intradark'] + buckets_pulse = pulsepattern * (fpt // len(pulsepattern)) + + if runtype == 'energyscan_pumped': + buckets_train = tb.get_array(run_obj, 'nrj', 0.1).values + pulsepattern = ['unpumped', 'unpumped_intradark', 'pumped', 'pumped_intradark'] + buckets_pulse = pulsepattern * (fpt // len(pulsepattern)) + + if runtype == 'delayscan': + buckets_train = tb.get_array(run_obj, 'PP800_DelayLine', 0.03).values + pulsepattern = ['unpumped', 'unpumped_intradark', 'pumped', 'pumped_intradark'] + buckets_pulse = pulsepattern * (fpt // len(pulsepattern)) + + if runtype == 'timescan': # 10s bins (tstamp is in ns) + bin_nsec = 10 * 1e9 + tstamp = run_obj.get_array('SCS_RR_UTC/TSYS/TIMESERVER', 'id.timestamp') + buckets_train = (bin_nsec * np.round(tstamp / bin_nsec) - tstamp.min()) / 1e9 + pulsepattern = ['unpumped', 'unpumped_intradark', 'pumped', 'pumped_intradark'] + buckets_pulse = pulsepattern * (fpt // len(pulsepattern)) + # ------------------------------------------------------------------------- + + # create binner + binner1 = tbdet.create_dssc_bins("trainId",trainIds,buckets_train) + binner2 = tbdet.create_dssc_bins("pulse", + np.linspace(0,fpt-1,fpt, dtype=int), + buckets_pulse) + binners = {'trainId': binner1, 'pulse': binner2} + bin_obj = tbdet.DSSCBinner(proposal_nb, run_nb, + binners=binners, + dssc_coords_stride=normevery) + + if xgm_mask: + bin_obj.create_pulsemask('xgm', xgm_threshold) + + dark=None + if filename_dark: + dark = tbdet.load_xarray(filename_dark) + dark = dark['data'] + + bin_params = {'modules':mod_list, + 'chunksize':248, + 'filepath':path, + 'xgm_normalization':xgm_normalization, + 'normevery':normevery, + 'dark_image':dark} + + log_root.info("start binning routine") + bin_obj.process_data(**bin_params) + + log_root.info("Add additional data to module files") + if save_xgm_binned: + bin_obj.load_xgm() + xgm_binned = bin_obj.get_xgm_binned() + + if not os.path.isdir(path): + os.mkdir(path) + for m in mod_list: + fname = f'run_{run_nb}_module{m}.h5' + if save_xgm_binned: + tbdet.save_xarray( + path+fname, xgm_binned, group='xgm_binned', mode='a') + tbdet.save_xarray(path+fname, binner1, group='binner1', mode='a') + tbdet.save_xarray(path+fname, binner2, group='binner2', mode='a') + metadata = {'run_number':run_nb, + 'module':m, + 'run_description':run_description} + tbdet.save_attributes_h5(path+fname, metadata) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--run-number', metavar='S', + action='store', + help='the run to be processed') + parser.add_argument('--module', metavar='S', + nargs='+', action='store', + help='modules to be processed') + parser.add_argument('--runtype', metavar='S', + nargs='+', action='store', + help=('type of run (static, static_IR, energyscan, energyscan_pumped)' + ', delayscan', 'timescan)')) + args = parser.parse_args() + + runtype = args.runtype[0] + if args.run_number: + if args.module is not None: + modules = [] + if len(args.module) == 1: + args.module = args.module[0].split(" ") + modules = list(map(int, args.module)) + process(str(args.run_number), runtype, modules) + else: + process(str(args.run_number), runtype) diff --git a/scripts/start_job_single.sh b/scripts/start_job_single.sh new file mode 100755 index 0000000000000000000000000000000000000000..68e97d6486ca5f90d19b986458523d8aac4c884c --- /dev/null +++ b/scripts/start_job_single.sh @@ -0,0 +1,13 @@ +#!/bin/bash +#SBATCH -N 1 +#SBATCH --partition=upex +#SBATCH --time=00:30:00 +#SBATCH --mail-type=END,FAIL +#SBATCH --output=../logs/%j-%x.out + +RUN=$1 +MODULES=$2 +RUNTYPE=$3 + +echo processing modules $MODULES of run $RUN +python process_data_201007_23h.py --run-number $RUN --module ${MODULES} --runtype $RUNTYPE diff --git a/scripts/start_processing_all.sh b/scripts/start_processing_all.sh new file mode 100755 index 0000000000000000000000000000000000000000..681315e8372a482598a079512a3795b78a4c94f9 --- /dev/null +++ b/scripts/start_processing_all.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +RUN=$1 +RUNTYPE=$2 + +if [ $RUN ] && [ $RUNTYPE ] + then + echo processing run $RUN +# module load exfel +# module load exfel_anaconda3/1.1 + sbatch ./start_job_single.sh $RUN '0 1 2 3' $RUNTYPE + sbatch ./start_job_single.sh $RUN '4 5 6 7' $RUNTYPE + sbatch ./start_job_single.sh $RUN '8 9 10 11' $RUNTYPE + sbatch ./start_job_single.sh $RUN '12 13 14 15' $RUNTYPE + else + echo please specify a run number and type + echo available runtypes: + echo energyscan, energyscan_pumped, static, static_IR, delayscan, timescan +fi \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000000000000000000000000000000000000..9076e9155e56da1c0d690e125316e83fbf8a7727 --- /dev/null +++ b/setup.py @@ -0,0 +1,28 @@ +from setuptools import setup, find_packages + +with open('README.rst') as f: + readme = f.read() + +with open('VERSION') as f: + _version = f.read() + _version = _version.strip("\n") + + +setup(name='toolbox_scs', + version=_version, + description="A collection of code for the SCS beamline", + long_description=readme, + author='SCS team', + author_email='scs@xfel.eu', + url="https://git.xfel.eu/gitlab/SCS/ToolBox.git", + keywords='XAS, xgm, DSSC, FCCD, PPL', + license="GPL", + package_dir={'': 'src'}, + packages=find_packages('src'), + package_data={}, + install_requires=[ + 'xarray>=0.13.0', 'numpy', 'matplotlib', + 'pandas', 'scipy', 'h5py', 'h5netcdf', + 'extra_data', 'euxfel_bunch_pattern>=0.6', + ], + ) diff --git a/src/toolbox_scs/__init__.py b/src/toolbox_scs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..fede7d9ce230df11adbd2ff392a0f828da41171b --- /dev/null +++ b/src/toolbox_scs/__init__.py @@ -0,0 +1,39 @@ +from .load import (load, concatenateRuns, get_array, + load_run, run_by_path) + +from .constants import mnemonics + +__all__ = ( + # functions + "load", + "concatenateRuns", + "get_array", + "load_run", + "run_by_path", + # Classes + # Variables + "mnemonics", +) + + +# ------------------------------------------------------------------------------ +# Clean namespace +# clean_ns is a collection of undesired items in the namespace +# ------------------------------------------------------------------------------ + +clean_ns = [ + # filenames + 'constants', + # folders + 'misc', + 'util', + 'detectors', + 'routines', + ] + +for name in dir(): + if name in clean_ns: + del globals()[name] + +del globals()['clean_ns'] +del globals()['name'] diff --git a/Load.py b/src/toolbox_scs/constants.py similarity index 74% rename from Load.py rename to src/toolbox_scs/constants.py index 3b001795afa82e6220dcd8c7b10e8a91c96d770e..d0e98b8a30f2e54e2aa021b07c3e6e2b4e5af0aa 100644 --- a/Load.py +++ b/src/toolbox_scs/constants.py @@ -1,17 +1,3 @@ -# -*- coding: utf-8 -*- -""" Toolbox for SCS. - - Various utilities function to quickly process data measured at the SCS instruments. - - Copyright (2019) SCS Team. -""" -import numpy as np -from extra_data import by_index, RunDirectory -from extra_data.read_machinery import find_proposal -import xarray as xr -import os -from ToolBox.bunch_pattern import extractBunchPattern - mnemonics = { # Machine "sase3": {'source':'SCS_RR_UTC/MDL/BUNCH_DECODER', @@ -196,7 +182,7 @@ mnemonics = { 'key':'actualPosition.value', 'dim':None}, "AFS_DelayLine": {'source':'SCS_ILH_LAS/MOTOR/LT3', - 'key':'AActualPosition.value', + 'key':'actualPosition.value', 'dim':None}, "AFS_HalfWP": {'source':'SCS_ILH_LAS/MOTOR/ROT_OPA_BWP1', 'key':'actualPosition.value', @@ -217,7 +203,7 @@ mnemonics = { 'key':'actualPosition.value', 'dim':None}, "PP800_DelayLine": {'source':'SCS_ILH_LAS/MOTOR/LT3', - 'key':'AActualPosition.value', + 'key':'actualPosition.value', 'dim':None}, "PP800_HalfWP": {'source':'SCS_ILH_LAS/MOTOR/ROT8WP1', 'key':'actualPosition.value', @@ -407,131 +393,3 @@ mnemonics = { 'key': 'data.adc', 'dim': ['gott_pId','pixelId']} } - -def load(fields, runNB, proposalNB, subFolder='raw', display=False, validate=False, - subset=by_index[:], rois={}, useBPTable=True): - """ Load a run and extract the data. Output is an xarray with aligned trainIds - - Inputs: - fields: list of mnemonic strings to load specific data such as "fastccd", "SCS_XGM", - or dictionnaries defining a custom mnemonic such as - {"extra": {'SCS_CDIFFT_MAG/SUPPLY/CURRENT', 'actual_current.value', None}} - runNB: (str, int) run number as integer - proposalNB: (str, int) of the proposal number e.g. 'p002252' or 2252 - subFolder: (str) sub-folder from which to load the data. Use 'raw' for raw - data or 'proc' for processed data. - display: (bool) whether to show the run.info or not - validate: (bool) whether to run extra-data-validate or not - subset: a subset of train that can be load with by_index[:5] for the - first 5 trains - rois: a dictionnary of mnemonics with a list of rois definition and the desired - names, for example {'fastccd':{'ref':{'roi':by_index[730:890, 535:720], - 'dim': ['ref_x', 'ref_y']}, 'sam':{'roi':by_index[1050:1210, 535:720], - 'dim': ['sam_x', 'sam_y']}}} - useBPTable: If True, uses the raw bunch pattern table to extract sase pulse - number and indices in the trains. If false, load the data from BUNCH_DECODER - middle layer device. - - Outputs: - res: an xarray DataSet with aligned trainIds - """ - - if isinstance(runNB, int): - runNB = 'r{:04d}'.format(runNB) - if isinstance(proposalNB,int): - proposalNB = 'p{:06d}'.format(proposalNB) - runFolder = os.path.join(find_proposal(proposalNB), subFolder, runNB) - run = RunDirectory(runFolder).select_trains(subset) - - if validate: - get_ipython().system('extra-data-validate ' + runFolder) - if display: - print('Loading data from {}'.format(runFolder)) - run.info() - - keys = [] - vals = [] - - # load pulse pattern info - if useBPTable: - bp_mnemo = mnemonics['bunchPatternTable'] - if bp_mnemo['source'] not in run.all_sources: - print('Source {} not found in run. Skipping!'.format( - mnemonics['bunchPatternTable']['source'])) - else: - bp_table = run.get_array(bp_mnemo['source'],bp_mnemo['key'], - extra_dims=bp_mnemo['dim']) - sase1, npulses_sase1, dummy = extractBunchPattern(bp_table, 'sase1') - sase3, npulses_sase3, dummy = extractBunchPattern(bp_table, 'sase3') - keys += ["sase1", "npulses_sase1", "sase3", "npulses_sase3"] - vals += [sase1, npulses_sase1, sase3, npulses_sase3] - else: - fields += ["sase1", "sase3", "npulses_sase3", "npulses_sase1"] - - for f in fields: - - if type(f) == dict: - # extracting mnemomic defined on the spot - if len(f.keys()) > 1: - print('Loading only one "on-the-spot" mnemonic at a time, skipping all others !') - k = list(f.keys())[0] - v = f[k] - else: - # extracting mnemomic from the table - if f in mnemonics: - v = mnemonics[f] - k = f - else: - print('Unknow mnemonic "{}". Skipping!'.format(f)) - continue - - if k in keys: - continue # already loaded, skip - - if display: - print('Loading {}'.format(k)) - - if v['source'] not in run.all_sources: - print('Source {} not found in run. Skipping!'.format(v['source'])) - continue - - if k not in rois: - # no ROIs selection, we read everything - vals.append(run.get_array(v['source'], v['key'], extra_dims=v['dim'])) - keys.append(k) - else: - # ROIs selection, for each ROI we select a region of the data and save it with new name and dimensions - for nk,nv in rois[k].items(): - vals.append(run.get_array(v['source'], v['key'], extra_dims=nv['dim'], roi=nv['roi'])) - keys.append(nk) - - aligned_vals = xr.align(*vals, join='inner') - result = dict(zip(keys, aligned_vals)) - result = xr.Dataset(result) - result.attrs['run'] = run - result.attrs['runFolder'] = runFolder - return result - -def concatenateRuns(runs): - """ Sorts and concatenate a list of runs with identical data variables along the - trainId dimension. - - Input: - runs: (list) the xarray Datasets to concatenate - Output: - a concatenated xarray Dataset - """ - firstTid = {i: int(run.trainId[0].values) for i,run in enumerate(runs)} - orderedDict = dict(sorted(firstTid.items(), key=lambda t: t[1])) - orderedRuns = [runs[i] for i in orderedDict] - keys = orderedRuns[0].keys() - for run in orderedRuns[1:]: - if run.keys() != keys: - print('data fields between different runs are not identical. Cannot combine runs.') - return - - result = xr.concat(orderedRuns, dim='trainId') - for k in orderedRuns[0].attrs.keys(): - result.attrs[k] = [run.attrs[k] for run in orderedRuns] - return result - diff --git a/src/toolbox_scs/detectors/LICENSE_BSD b/src/toolbox_scs/detectors/LICENSE_BSD new file mode 100644 index 0000000000000000000000000000000000000000..def0969d45225e36c946f538fa8717d907a6f35d --- /dev/null +++ b/src/toolbox_scs/detectors/LICENSE_BSD @@ -0,0 +1,30 @@ +BSD 3-Clause License + +Copyright (c) 2019, Michael Schneider +Copyright (c) 2020, SCS-team +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/src/toolbox_scs/detectors/__init__.py b/src/toolbox_scs/detectors/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..65809f4ac5edca64a17745c81a3b9396f020d5b8 --- /dev/null +++ b/src/toolbox_scs/detectors/__init__.py @@ -0,0 +1,71 @@ +from .xgm import ( + load_xgm, cleanXGMdata, matchXgmTimPulseId, calibrateXGMs, + autoFindFastAdcPeaks) +from .tim import ( + load_TIM,) +from .dssc_data import ( + save_xarray, load_xarray, get_data_formatted, save_attributes_h5) +from .dssc_misc import ( + load_dssc_info, create_dssc_bins, quickmask_DSSC_ASIC, + get_xgm_formatted, load_mask) +from .dssc_processing import ( + process_dssc_data) +from .dssc import ( + DSSCBinner, DSSCFormatter) +from .azimuthal_integrator import AzimuthalIntegrator, AzimuthalIntegratorDSSC + +__all__ = ( + # Functions + "load_xgm", + "cleanXGMdata", + "load_TIM", + "matchXgmTimPulseId", + "load_dssc_info", + "create_dssc_bins", + "calc_xgm_frame_indices", + "get_xgm_formatted", + "process_dssc_data", + "save_xarray", + "load_xarray", + "get_data_formatted", + "save_attributes_h5", + "quickmask_DSSC_ASIC", + "load_mask", + # Classes + "DSSCBinner", + "DSSCFormatter", + "AzimuthalIntegrator", + "AzimuthalIntegratorDSSC", + # Variables +) + + +# ----------------------------------------------------------------------------- +# Clean namespace +# -> certain filenames we dont need in the namespace. Especially not those +# that are marked as private by using an underscore (_<filename>.py). +# ----------------------------------------------------------------------------- + +clean_ns = [ + # filenames + 'DSSC_bkp', + 'DSSC1module', + 'dssc', + 'dssc_routines', + 'dssc_processing', + 'dssc_data', + 'dssc_misc', + 'dssc_plot', + 'azimuthal_integrator', + 'FastCCD', + 'tim', + 'xgm', + ] + + +for name in dir(): + if name in clean_ns: + del globals()[name] + +del globals()['clean_ns'] +del globals()['name'] diff --git a/src/toolbox_scs/detectors/azimuthal_integrator.py b/src/toolbox_scs/detectors/azimuthal_integrator.py new file mode 100644 index 0000000000000000000000000000000000000000..d6326dfc77a83c8f7daea565b6d3ef21b4d919e4 --- /dev/null +++ b/src/toolbox_scs/detectors/azimuthal_integrator.py @@ -0,0 +1,187 @@ +import logging +import numpy as np + +log = logging.getLogger(__name__) + + +class AzimuthalIntegrator(object): + def __init__(self, imageshape, center, polar_range, + aspect=204/236, **kwargs): + ''' + Create a reusable integrator for repeated azimuthal integration of + similar images. Calculates array indices for a given parameter set that + allows fast recalculation. + + Parameters + ========== + imageshape : tuple of ints + The shape of the images to be integrated over. + + center : tuple of ints + center coordinates in pixels + + polar_range : tuple of ints + start and stop polar angle (in degrees) to restrict integration to + wedges + + dr : int, optional + radial width of the integration slices. Takes non-square DSSC + pixels into account. + + nrings : int, optional + Number of integration rings. Can be given as an alternative to dr + + aspect: float, default 204/236 for DSSC + aspect ratio of the pixel pitch + + Returns + ======= + ai : azimuthal_integrator instance + Instance can directly be called with image data: + > az_intensity = ai(image) + radial distances and the polar mask are accessible as attributes: + > ai.distance + > ai.polar_mask + ''' + self.xcoord = None + self.ycoord = None + + self._calc_dist_array(imageshape, center, aspect) + self._calc_polar_mask(polar_range) + self._calc_indices(**kwargs) + + def _calc_dist_array(self, shape, center, aspect): + '''Calculate pixel coordinates for the given shape.''' + self.center = center + self.shape = shape + self.aspect = aspect + cx, cy = center + log.info(f'azimuthal center: {center}') + sx, sy = shape + xcoord, ycoord = np.ogrid[:sx, :sy] + self.xcoord = xcoord - cx + self.ycoord = ycoord - cy + # distance from center, hexagonal pixel shape taken into account + self.dist_array = np.hypot(self.xcoord * aspect, self.ycoord) + + def _calc_indices(self, **kwargs): + '''Calculates the list of indices for the flattened image array.''' + maxdist = self.dist_array.max() + mindist = self.dist_array.min() + dr = kwargs.get('dr', None) + nrings = kwargs.get('nrings', None) + if (dr is None) and (nrings is None): + raise AssertionError('Either <dr> or <nrings> needs to be given.') + if (dr is not None) and (nrings is not None): + log.warning('Both <dr> and <nrings> given. <dr> takes precedence.') + if (dr is None): + dr = maxdist / nrings + + idx = np.indices(dimensions=self.shape) + self.index_array = np.ravel_multi_index(idx, self.shape) + + self.distance = np.array([]) + self.flat_indices = [] + for dist in np.arange(mindist, maxdist + dr, dr): + ring_mask = (self.polar_mask + * (self.dist_array >= (dist - dr)) + * (self.dist_array < dist)) + self.flat_indices.append(self.index_array[ring_mask]) + self.distance = np.append(self.distance, dist) + + def _calc_polar_mask(self, polar_range): + self.polar_range = polar_range + prange = np.abs(polar_range[1] - polar_range[0]) + if prange > 180: + raise ValueError('Integration angle too wide, should be within 180' + ' degrees') + if prange < 1e-6: + raise ValueError('Integration angle too narrow') + + if prange == 180: + self.polar_mask = np.ones(self.shape, dtype=bool) + else: + tmin, tmax = np.deg2rad(np.sort(polar_range)) % np.pi + polar_array = np.arctan2(self.xcoord, self.ycoord) + polar_array = np.mod(polar_array, np.pi) + self.polar_mask = (polar_array > tmin) * (polar_array < tmax) + + def calc_q(self, distance, wavelength): + '''Calculate momentum transfer coordinate. + + Parameters + ========== + distance : float + Sample - detector distance in meter + wavelength : float + wavelength of scattered light in meter + + Returns + ======= + deltaq : np.ndarray + Momentum transfer coordinate in 1/m + ''' + res = 4 * np.pi \ + * np.sin(np.arctan(self.distance / distance) / 2) / wavelength + return res + + def __call__(self, image): + assert self.shape == image.shape, 'image shape does not match' + image_flat = np.ravel(image) + return np.array([np.nansum(image_flat[indices]) + for indices in self.flat_indices]) + + +class AzimuthalIntegratorDSSC(AzimuthalIntegrator): + def __init__(self, geom, polar_range, dxdy=(0, 0), **kwargs): + ''' + Create a reusable integrator for repeated azimuthal integration of + similar images. Calculates array indices for a given parameter set that + allows fast recalculation. Directly uses a + extra_geom.detectors.DSSC_1MGeometry instance for correct pixel + positions + + Parameters + ========== + geom : extra_geom.detectors.DSSC_1MGeometry + loaded geometry instance + + polar_range : tuple of ints + start and stop polar angle (in degrees) to restrict integration to + wedges + + dr : int, optional + radial width of the integration slices. Takes non-square DSSC + pixels into account. + + nrings : int, optional + Number of integration rings. Can be given as an alternative to dr + + dxdy : tuple of floats, default (0, 0) + global coordinate shift to adjust center outside of geom object + (meter) + + Returns + ======= + ai : azimuthal_integrator instance + Instance can directly be called with image data: + > az_intensity = ai(image) + radial distances and the polar mask are accessible as attributes: + > ai.distance + > ai.polar_mask + ''' + + self.xcoord = None + self.ycoord = None + + self._calc_dist_array(geom, dxdy) + self._calc_polar_mask(polar_range) + self._calc_indices(**kwargs) + + def _calc_dist_array(self, geom, dxdy): + self.dxdy = dxdy + pos = geom.get_pixel_positions() + self.shape = pos.shape[:-1] + self.xcoord = pos[..., 0] + dxdy[0] + self.ycoord = pos[..., 1] + dxdy[1] + self.dist_array = np.hypot(self.xcoord, self.ycoord) diff --git a/DSSC.py b/src/toolbox_scs/detectors/deprecated/dssc_bkp.py similarity index 97% rename from DSSC.py rename to src/toolbox_scs/detectors/deprecated/dssc_bkp.py index 6bda4b3ba85dc3354672b07eef49d3dbf77ea0e9..8cfa4fa04676caf18684e042a22c9942b58f8803 100644 --- a/DSSC.py +++ b/src/toolbox_scs/detectors/deprecated/dssc_bkp.py @@ -10,15 +10,16 @@ import psutil import extra_data as ed from extra_data.read_machinery import find_proposal from extra_geom import DSSC_1MGeometry -import ToolBox as tb import matplotlib.pyplot as plt from mpl_toolkits.axes_grid1 import ImageGrid import numpy as np import xarray as xr import h5py - from imageio import imread +from ..constants import mnemonics as _mnemonics +from .azimuthal_integrator import AzimuthalIntegrator + class DSSC: def __init__(self, proposal, distance=1): @@ -122,9 +123,9 @@ class DSSC: if type(vname) is dict: scan = self.run.get_array(vname['source'], vname['key']) elif type(vname) is str: - if vname not in tb.mnemonics: + if vname not in _mnemonics: raise ValueError(f'{vname} not found in the ToolBox mnemonics table') - scan = self.run.get_array(tb.mnemonics[vname]['source'], tb.mnemonics[vname]['key']) + scan = self.run.get_array(_mnemonics[vname]['source'], _mnemonics[vname]['key']) else: raise ValueError(f'vname should be a string or a dict. We got {type(vname)}') @@ -170,8 +171,9 @@ class DSSC: """ if self.xgm is None: - self.xgm = self.run.get_array(tb.mnemonics['SCS_SA3']['source'], - tb.mnemonics['SCS_SA3']['key'], roi=ed.by_index[:self.nbunches]) + self.xgm = self.run.get_array(_mnemonics['SCS_SA3']['source'], + _mnemonics['SCS_SA3']['key'], + roi=ed.by_index[:self.nbunches]) def plot_xgm_hist(self, nbins=100): """ Plots an histogram of the SCS XGM dedicated SAS3 data. @@ -188,7 +190,7 @@ class DSSC: plt.figure(figsize=(5,3)) plt.bar(bins_center, hist, align='center', width=width) - plt.xlabel(f"{tb.mnemonics['SCS_SA3']['source']}{tb.mnemonics['SCS_SA3']['key']}") + plt.xlabel(f"{_mnemonics['SCS_SA3']['source']}{_mnemonics['SCS_SA3']['key']}") plt.ylabel('density') plt.title(self.plot_title) @@ -515,7 +517,7 @@ class DSSC: if center is None: center = c_geom - ai = tb.azimuthal_integrator(im_pumped_mean.shape, center, angle_range, dr=dr) + ai = AzimuthalIntegrator(im_pumped_mean.shape, center, angle_range, dr=dr) norm = ai(~np.isnan(im_pumped_mean)) az_pump = [] diff --git a/DSSC1module.py b/src/toolbox_scs/detectors/deprecated/dssc_single_module.py similarity index 96% rename from DSSC1module.py rename to src/toolbox_scs/detectors/deprecated/dssc_single_module.py index eea4232590bfded8f7c13a1c9ac7b9baeebd0147..dddd9c644ac35beb4ada92da8b1492167d9668d2 100644 --- a/DSSC1module.py +++ b/src/toolbox_scs/detectors/deprecated/dssc_single_module.py @@ -7,7 +7,6 @@ import psutil import extra_data as ed from extra_data.read_machinery import find_proposal -import ToolBox as tb import matplotlib.pyplot as plt from mpl_toolkits.axes_grid1 import ImageGrid import matplotlib.patches as patches @@ -18,6 +17,9 @@ from glob import glob from imageio import imread +from ..constants import mnemonics as _mnemonics +from ..misc.laser_utils import positionToDelay + class DSSC1module: def __init__(self, module, proposal): @@ -90,23 +92,23 @@ class DSSC1module: print(f'Loading XGM data') - self.xgm = self.run.get_array(tb.mnemonics['SCS_SA3']['source'], - tb.mnemonics['SCS_SA3']['key'], + self.xgm = self.run.get_array(_mnemonics['SCS_SA3']['source'], + _mnemonics['SCS_SA3']['key'], roi=ed.by_index[:self.nbunches]) self.xgm = self.xgm.rename({'dim_0':'pulseId'}) self.xgm['pulseId'] = np.arange(0, 2*self.nbunches, 2) print(f'Loading mono nrj data') - self.nrj = self.run.get_array(tb.mnemonics['nrj']['source'], - tb.mnemonics['nrj']['key']) + self.nrj = self.run.get_array(_mnemonics['nrj']['source'], + _mnemonics['nrj']['key']) print(f'Loading delay line data') try: - self.delay_mm = self.run.get_array(tb.mnemonics['PP800_DelayLine']['source'], - tb.mnemonics['PP800_DelayLine']['key']) + self.delay_mm = self.run.get_array(_mnemonics['PP800_DelayLine']['source'], + _mnemonics['PP800_DelayLine']['key']) except: self.delay_mm = 0*self.nrj self.t0 = t0 - self.delay_ps = tb.positionToDelay(self.delay_mm, origin=self.t0, invert=True) + self.delay_ps = positionToDelay(self.delay_mm, origin=self.t0, invert=True) def collect_dssc_module_file(self): """ Collect the raw DSSC module h5 files. diff --git a/src/toolbox_scs/detectors/dssc.py b/src/toolbox_scs/detectors/dssc.py new file mode 100644 index 0000000000000000000000000000000000000000..48535abdb05ef8aa0e187182ae54425a55fe50cd --- /dev/null +++ b/src/toolbox_scs/detectors/dssc.py @@ -0,0 +1,422 @@ +""" + DSSC-detector class module + -------------------------- + + The dssc detector class. It represents a namespace for frequent evaluation + while implicitly applying/requiring certain structure/naming conventions to + its objects. + + comments: + - contributions should comply with pep8 code structure guidelines. + - Plot routines don't fit into objects since they are rather fluent. + They have been outsourced to dssc_plot.py. They can now be accessed + as tbdet member functions. +""" +import os +import logging +import joblib + +import numpy as np +import xarray as xr + +from ..load import load_run +from ..util.exceptions import ToolBoxValueError, ToolBoxFileError +from .dssc_data import ( + save_xarray, load_xarray, save_attributes_h5, + search_files, get_data_formatted) +from .dssc_misc import ( + load_dssc_info, get_xgm_formatted, get_tim_formatted) +from .dssc_processing import ( + process_dssc_data, create_empty_dataset) + +__all__ = ["DSSCBinner", "DSSCFormatter"] +log = logging.getLogger(__name__) + + +class DSSCBinner: + def __init__(self, proposal_nr, run_nr, + binners={}, + xgm_name='SCS_SA3', + tim_names=['MCP1apd', 'MCP2apd', 'MCP3apd'], + dssc_coords_stride=2, + ): + """ + A dssc binner object. Loads and bins the dssc data according to the + bins specified in 'binners'. The data can be reduced further through + masking using XGM or TIM data. + + Parameters + ---------- + proposal_nr: int, str + proposal number containing run folders + run_nr: int, str + run number + binners: dictionary + dictionary containing binners constructed using the + 'create_dssc_bins' tbdet-method. + xgm_name: str + a valid mnemonic key of the XGM data to be used to mask the dssc + frames. Since the xgm is used in several methods its name can be + set here globally. + tim_names: list of strings + a list of valid mnemonic keys for an mcp in the tim. Once the + corresponding data is loaded the different sources will be averaged. + dssc_coords_stride: int, list + defines which dssc frames should be normalized using data from the + xgm. The parameter may be an integer (stride parameter) or a list, + that assigns each pulse to its corresponding dssc frame number. + + Returns + ------- + DSSCbinner: object + + Example + ------- + 1.) quick -> generic bins, no xgm, + >>> import toolbox_scs.detectors as tbdet + >>> run235 = tbdet.DSSCBinner(proposal_nb=2212, run_nb=235) + 2.) detailed -> docs + """ + + # --------------------------------------------------------------------- + # object (run) properties + # --------------------------------------------------------------------- + self.proposal = proposal_nr + self.runnr = run_nr + self.info = load_dssc_info(proposal_nr, run_nr) + self.run = load_run(proposal_nr, run_nr) + self.binners = {} + for b in binners: + self.add_binner(b, binners[b]) + self.xgm_name = xgm_name + self.tim_names = tim_names + self.dssc_coords_stride = dssc_coords_stride + self.xgm = None + self.tim = None + self.pulsemask = None + + log.debug("Constructed DSSC object") + + def __del__(self): + pass + + def add_binner(self, name, binner): + """ + Add additional binner to internal dictionary + + Parameters + ---------- + name: str + name of binner to be created + binner: xarray.DataArray + An array that represents a map how the respective coordinate should + be binned. + + Raises + ------ + ToolBoxValueError: Exception + Raises exception in case the name does not correspond to a valid + binner name. To be generalized. + """ + if name in ['trainId', 'pulse', 'x', 'y']: + self.binners[name] = binner + else: + msg = "Invalid binner name" + log.info(msg+", no binner created") + raise ToolBoxValueError(msg, name) + + def load_xgm(self): + """ + load xgm data and construct coordinate array according to corresponding + dssc frame number. + """ + self.xgm = get_xgm_formatted(self.run, + self.xgm_name, + self.dssc_coords_stride) + + def load_tim(self): + """ + load tim data and construct coordinate array according to corresponding + dssc frame number. + """ + self.tim = get_tim_formatted(self.run, + self.tim_names, + self.dssc_coords_stride) + + def create_pulsemask(self, use_data='xgm', threshold=(0, np.inf)): + """ + creates a mask for dssc frames according to measured xgm intensity. + Once such a mask has been constructed, it will be used in the data + reduction process to drop out-of-bounds pulses. + """ + fpt = self.info['frames_per_train'] + n_trains = self.info['number_of_trains'] + trainIds = self.info['trainIds'] + data = np.ones([n_trains, fpt], dtype=bool) + self.pulsemask = xr.DataArray(data, + dims=['trainId', 'pulse'], + coords={'trainId': trainIds, + 'pulse': range(fpt)}) + + if use_data == 'xgm': + if self.xgm is None: + self.load_xgm() + valid = (self.xgm > threshold[0]) * \ + (self.xgm < threshold[1]) + if use_data == 'tim': + if self.tim is None: + self.load_tim() + valid = (self.tim > threshold[0]) * \ + (self.tim < threshold[1]) + + self.pulsemask = \ + (valid.combine_first(self.pulsemask).astype(bool))[:, 0:fpt] + log.info(f'created pulse mask used during processing') + + def get_info(self): + """ + Returns the expected shape of the binned dataset, in case binners have + been defined. + """ + if any(self.binners): + empty = create_empty_dataset(self.info, self.binners) + return(empty.dims) + else: + log.info("no binner defined yet.") + pass + + def _bin_metadata(self, data): + if self.pulsemask is not None: + data = data.where(self.pulsemask) + for b in self.binners: + if b in ['trainId', 'pulse']: + data[b+"_binned"] = self.binners[b] + data = data.groupby(b+"_binned").mean(b) + data = data.rename(name_dict={b+"_binned": b}) + log.debug('binned metadata data according to dssc binners.') + return data.transpose('trainId', 'pulse') + + def get_xgm_binned(self): + """ + Bin the xgm data according to the binners of the dssc data. The result + can eventually be merged into the final dataset by the DSSCFormatter. + + Returns + ------- + xgm_data: xarray.DataSet + xarray dataset containing the binned xgm data + """ + if self.xgm is not None: + xgm_data = self.xgm.to_dataset(name='xgm') + xgm_binned = self._bin_metadata(xgm_data) + log.info('binned xgm data according to dssc binners.') + return xgm_binned + else: + log.warning("no xgm data. Use load_xgm() to load the xgm data.") + pass + + def get_tim_binned(self): + """ + Bin the tim data according to the binners of the dssc data. The result + can eventually be merged into the final dataset by the DSSCFormatter. + + Returns + ------- + tim_data: xarray.DataSet + xarray dataset containing the binned tim data + """ + if self.tim is not None: + tim_data = self.tim.to_dataset(name='tim') + tim_binned = self._bin_metadata(tim_data) + log.info('binned tim data according to dssc binners.') + return tim_binned + else: + log.warning("no data. Use load_tim() to load the tim data.") + pass + + # ------------------------------------------------------------------------- + # Data processing + # ------------------------------------------------------------------------- + def process_data(self, modules=[], filepath='./', + chunksize=512, backend='loky', n_jobs=None, + dark_image=None, + xgm_normalization=False, normevery=1 + ): + """ + Load and bin dssc data according to self.bins. No data is returned by + this method. The condensed data is written to file by the worker + processes directly. + + Parameters + ---------- + modules: list of ints + a list containing the module numbers that should be processed. If + empty, all modules are processed. + filepath: str + the path where the files containing the reduced data should be + stored. + chunksize: int + The number of trains that should be read in one iterative step. + backend: str + joblib multiprocessing backend to be used. At the moment it can be + any of joblibs standard backends: 'loky' (default), + 'multiprocessing', 'threading'. Anything else than the default is + experimental and not appropriately implemented in the dbdet member + function 'bin_data'. + n_jobs: int + inversely proportional of the number of cpu's available for one + job. Tasks within one job can grab a maximum of n_CPU_tot/n_jobs of + cpu's. + Note that when using the default backend there is no need to adjust + this parameter with the current implementation. + dark_image: xarray.DataArray + DataArray with dimensions compatible with the loaded dssc data. If + given, it will be subtracted from the dssc data before the binning. + The dark image needs to be of dimension module, trainId, pulse, x + and y. + xgm_normalization: boolean + if true, the dssc data is normalized by the xgm data before the + binning. + normevery: int + integer indicating which out of normevery frame will be normalized. + """ + log.info("Bin data according to binners") + log.info(f'Process {chunksize} trains per chunk') + + mod_list = modules + if len(mod_list) == 0: + mod_list = [i for i in range(16)] + log.info(f'Process modules {mod_list}') + njobs = n_jobs + if njobs is None: + njobs = len(mod_list) + + module_jobs = [] + for m in mod_list: + dark = dark_image + if dark_image is not None: + dark = dark_image.sel(module=m) + module_jobs.append(dict( + proposal=self.proposal, + run_nr=self.runnr, + module=m, + chunksize=chunksize, + path=filepath, + info=self.info, + dssc_binners=self.binners, + pulsemask=self.pulsemask, + dark_image=dark, + xgm_normalization=xgm_normalization, + xgm_mnemonic=self.xgm_name, + normevery=normevery, + )) + + log.info(f'using parallelization backend {backend}') + joblib.Parallel(n_jobs=njobs, backend=backend)\ + (joblib.delayed(process_dssc_data)(**module_jobs[i]) + for i in range(len(mod_list))) + + log.info(f'Binning done') + + +class DSSCFormatter: + def __init__(self, filepath): + """ + Class that handles formatting related aspects, before handing the data + overt for analysis. + + Parameters + ---------- + filepath: str + location of processed files. + + Raises + ------ + ToolBoxFileError: Exception + Trows an error in case the the given path does not exist. + """ + self._filenames = [] + self._filename = '' + if os.path.exists(filepath): + try: + self._filenames = search_files(filepath) + except ToolBoxFileError: + log.info("path did not contain any files") + pass + else: + log.info("path did not exist") + + self.data = None + self.data_xarray = {} + self.attributes = {} + + def combine_files(self, filenames=[]): + """ + Read the files given in filenames, and store the data in the class + variable 'data'. If no filenames are given, it tries to read the files + stored in the class-internal variable '_filenames'. + + Parameters + ---------- + filenames: list + list of strings containing the names of the files to be combined. + """ + if any(filenames) is True: + self._filenames = filenames + if self._filenames is not None: + self.data = get_data_formatted(self._filenames) + else: + log.info("No matching data found.") + + def add_dataArray(self, groups=[]): + """ + Reads addional xarray-data from the first file given in the list of + filenames. This assumes that all the files in the folder contain the + same additional data. To be generalized. + + Parameters + ---------- + groups: list + list of strings with the names of the groups in the h5 file, + containing additional xarray data. + """ + if any(self._filenames) is True: + for group in groups: + self.data_xarray[group] = load_xarray(self._filenames[0], + group=group, + form='array') + else: + log.info("No files found in specified folder.") + + def add_attributes(self, attributes={}): + """ + Add additional information, such as run-type, as attributes to the + formatted .h5 file. + + Parameters + ---------- + attributes: dictionary + a dictionary, containing information or data of any kind, that + will be added to the formatted .h5 file as attributes. + """ + for key in attributes.keys(): + self.attributes[key] = attributes[key] + + def save_formatted_data(self, filename): + """ + Create a .h5 file containing the main dataset in the group called + 'data'. Additional groups will be created for the content of the + variable 'data_array'. Metadata about the file is added in the form of + attributes. + + Parameters + ---------- + filename: str + the name of the file to be created + """ + save_xarray(filename, self.data, group='data', mode='w') + + for arr in self.data_xarray.keys(): + save_xarray(filename, self.data_xarray[arr], group=arr, mode='a') + + save_attributes_h5(filename, self.attributes) diff --git a/src/toolbox_scs/detectors/dssc_data.py b/src/toolbox_scs/detectors/dssc_data.py new file mode 100644 index 0000000000000000000000000000000000000000..078117727a8daabe88c6be50c9f3f92725801adc --- /dev/null +++ b/src/toolbox_scs/detectors/dssc_data.py @@ -0,0 +1,203 @@ +import os +import logging + +import h5py +import xarray as xr + +from ..util.exceptions import ToolBoxFileError + +log = logging.getLogger(__name__) + + +def _to_netcdf(fname, data, group, mode): + f_exists = os.path.isfile(fname) + if (f_exists and mode == 'w'): + data.to_netcdf(fname, group=group, mode='w', engine='h5netcdf') + log.warning(f"File {fname} existed: overwritten") + log.info(f"Stored data in file {fname}") + elif f_exists and mode == 'a': + try: + data.to_netcdf(fname, group=group, mode='a', engine='h5netcdf') + log.info(f"Created group {group} in file {fname}") + except (ValueError, TypeError): + msg = f"Group {group} exists and has incompatible dimensions." + log.warning(f"Could not store data: {msg}") + raise ToolBoxFileError(msg, fname) + else: + data.to_netcdf(fname, group=group, mode='w', engine='h5netcdf') + log.info(f"Stored data in file {fname}") + + +def save_xarray(fname, data, group='data', mode='a'): + """ + Store xarray Dataset in the specified location + + Parameters + ---------- + data: xarray.DataSet + The data to be stored + fname: str, int + filename + overwrite: bool + overwrite existing data + + Raises + ------ + ToolBoxFileError: Exception + File existed, but overwrite was set to False. + """ + try: + _to_netcdf(fname, data, group, mode) + except ToolBoxFileError as err: + raise err + + +def save_attributes_h5(fname, data={}): + """ + Adding attributes to a hdf5 file. This function is intended to be used to + attach metadata to a processed run. + + Parameters + ---------- + fname: str + filename as string + data: dictionary + the data that should be added to the file in form of a dictionary. + """ + f = h5py.File(fname, mode='a') + for d in data.keys(): + f.attrs[d] = data[d] + f.close() + log.info(f"added attributes to file {fname}") + + +def load_xarray(fname, group='data', form='dataset'): + """ + Load stored xarray Dataset. + Comment: This function exists because of a problem with the standard + netcdf engine that is malfunctioning due to related software installed + in the exfel_anaconda3 environment. May be dropped at some point. + + Parameters + ---------- + fname: str + filename as string + group: str + the name of the xarray dataset (group in h5 file). + form: str + specify whether the data to be loaded is a 'dataset' or a 'array'. + """ + f_exists = os.path.isfile(fname) + if f_exists: + if form == 'dataset': + log.debug(f'open xarray dataset {fname}') + return xr.load_dataset(fname, group=group, engine='h5netcdf') + elif form == 'array': + log.debug(f'open xarray dataarray {fname}') + return xr.load_dataarray(fname, group=group, engine='h5netcdf') + else: + msg = "File does not exists." + raise ToolBoxFileError(msg, fname) + + +def _data_from_list(filenames): + """ + Helper function for data formatting routines. Loads the specified files + given by their names. This subroutine expects the name of the group to be + 'data'. + + Parameters + ---------- + filenames: list + list of valid xarray filenames + + Returns + ------- + data: list + a list containing the loaded data + + Raises + ------ + ToolBoxFileError + raises ToolBoxFileError in case file does not exist. + """ + data = [] + for name in filenames: + f_exists = os.path.isfile(name) + if f_exists: + data.append(load_xarray(name, group='data')) + else: + msg = "File does not exists." + raise ToolBoxFileError(msg, name) + return data + + +def get_data_formatted(filenames=[], data_list=[]): + """ + Combines the given data into one dataset. For any of extra_data's data + types, an xarray.Dataset is returned. The data is sorted along the 'module' + dimension. The array dimension have the order 'trainId', 'pulse', 'module', + 'x', 'y'. This order is required by the extra_geometry package. + + Parameters + ---------- + filenames: list of str + files to be combined as a list of names. Calls '_data_from_list' to + actually load the data. + data_list: list + list containing the already loaded data + + Returns + ------- + data: xarray.Dataset + A xarray.Dataset containing the combined data. + """ + if any(filenames) is True: + data = _data_from_list(filenames) + elif any(data_list) is True: + data = data_list + + mod_list = [] + for d in data: + if 'module' in d.attrs.keys(): + mod_list.append(d.attrs['module']) + + if type(data[0]).__module__ == 'xarray.core.dataset': + data = xr.concat(data, dim='module') + elif type(data[0]).__module__ == 'pandas.core.frame': + pass + elif type(data[0]).__module__ == 'dask.dataframe.core': + pass + + if mod_list is not None: + data = data.assign_coords(module=("module", mod_list)) + data = data.sortby("module") + data.attrs.clear() + return data.transpose('trainId', 'pulse', 'module', 'x', 'y') + + +def search_files(run_folder): + """ + Search folder for h5 files. + + Parameters + ---------- + run_folder: str + the path to a folder containing h5 files. + + Returns + ------- + a list of the filenames of all .h5 files in the given folder. + + Raises + ------ + ToolBoxFileError: Exception + raises ToolBoxFileError in case there are no .h5 files in the folder, + or the folder does not exist. + """ + try: + filenames = os.listdir(run_folder) + return [run_folder+name for name in filenames if ".h5" in name] + except: + msg = "No files in folder" + raise ToolBoxFileError(msg, run_folder) diff --git a/src/toolbox_scs/detectors/dssc_misc.py b/src/toolbox_scs/detectors/dssc_misc.py new file mode 100644 index 0000000000000000000000000000000000000000..9b7010b8db3740d253bd1abf1a50c0542d9d6cbd --- /dev/null +++ b/src/toolbox_scs/detectors/dssc_misc.py @@ -0,0 +1,237 @@ +""" + DSSC-related sub-routines. + + comment: contributions should comply with pep8 code structure guidelines. +""" +import logging + +import numpy as np +import xarray as xr +from imageio import imread + +import extra_data as ed + +from ..constants import mnemonics as _mnemonics +from ..misc.bunch_pattern_external import is_sase_3 + + +log = logging.getLogger(__name__) + + +def load_dssc_info(proposal, run_nr): + """ + Loads the first data file for DSSC module 0 (this is hardcoded) + and returns the detector_info dictionary + + Parameters + ---------- + proposal: str, int + number of proposal + run_nr: str, int + number of run + + Returns + ------- + info : dictionary + {'dims': tuple, 'frames_per_train': int, 'total_frames': int} + """ + module = ed.open_run(proposal, run_nr, include='*DSSC01*') + info = module.detector_info('SCS_DET_DSSC1M-1/DET/1CH0:xtdf') + info["number_of_trains"] = len(module.train_ids) + info["trainIds"] = module.train_ids + log.debug("Fetched information for DSSC module nr. 1.") + return info + + +def create_dssc_bins(name, coordinates, bins): + """ + Creates a single entry for the dssc binner dictionary. The produced xarray + data-array will later be used to perform grouping operations according to + the given bins. + + Parameters + ---------- + name: str + name of the coordinate to be binned. + coordinates: numpy.ndarray + the original coordinate values (1D) + bins: numpy.ndarray + the bins according to which the corresponding dimension should + be grouped. + + Returns + ------- + da: xarray.DataArray + A pre-formatted xarray.DataArray relating the specified dimension with + its bins. + + Examples + -------- + >>> import toolbox_scs as tb + >>> import toolbox_scs.detectors as tbdet + >>> run = tb.load_run(2212, 235, include='*DA*') + + 1.) binner along 'pulse' dimension. Group data into two bins. + >>> bins_pulse = ['pumped', 'unpumped'] * 10 + >>> binner_pulse = tbdet.create_dssc_bins("pulse", + np.linspace(0,19,20, dtype=int), + bins_pulse) + + 2.) binner along 'train' dimension. Group data into bins corresponding + to the positions of a delay stage for instance. + >>> bins_trainId = tb.get_array(run, 'PP800_PhaseShifter', 0.04) + >>> binner_train = tbdet.create_dssc_bins("trainId", + run.trainIds, + bins_trainId.values) + """ + if name in ['trainId', 'pulse', 'x', 'y']: + da = xr.DataArray(bins, + dims=[name], + coords={name: coordinates}) + log.debug(f'created dssc bin array for dimension {name}') + return da + log.debug(f'could not construct dssc bin array for dimension {name}') + raise ValueError(f'Invalid name {str(name)}: value should be ' + 'trainId, x, or y') + + +def _bunch_pattern_sase3(run_obj): + log.debug('load sase3 bunch pattern info') + bpt = run_obj.get_array(*_mnemonics["bunchPatternTable"].values()) + is_sase3 = is_sase_3(bpt.values[0]) + ind_sase3 = np.where(is_sase3 == 1)[0] + n_pulses = len(ind_sase3) + return is_sase3, ind_sase3, n_pulses + + +def get_xgm_formatted(run_obj, xgm_name, dssc_frame_coords): + """ + Load the xgm data and define coordinates along the pulse dimension. + + Parameters + ---------- + run_obj: extra_data.DataCollection + DataCollection object providing access to the xgm data to be loaded + xgm_name: str + valid mnemonic of a xgm source + dssc_frame_coords: int, list + defines which dssc frames should be normalized using data from the xgm. + + Returns + ------- + xgm: xarray.DataArray + xgm data with coordinate 'pulse'. + """ + log.debug('load raw xgm data') + xgm_raw = run_obj.get_array(*_mnemonics[xgm_name].values()) + + log.debug('create formatted xarray.dataArray') + _, ind_sase3, n_pulses = _bunch_pattern_sase3(run_obj) + coords = {'trainId': xgm_raw.trainId.values} + shape = (len(xgm_raw.trainId.values), n_pulses) + xgm_formatted = xr.DataArray(np.zeros(shape, dtype=np.float64), + coords=coords, + dims=['trainId', 'pulse']) + for i in range(len(xgm_formatted.trainId)): + xgm_formatted[i, :] = xgm_raw[i, 0:n_pulses].values + + if type(dssc_frame_coords) == int: + dssc_frame_coords = np.linspace(0, + (n_pulses-1)*dssc_frame_coords, + n_pulses, + dtype=np.uint64) + + xgm_formatted['pulse'] = dssc_frame_coords + log.info('loaded formatted xgm data.') + return xgm_formatted + + +def get_tim_formatted(run_obj, tim_names, dssc_frame_coords): + """ + Load the tim data and define coordinates along the pulse dimension. + + Parameters + ---------- + run_obj: extra_data.DataCollection + DataCollection object + tim_names: list of str + a list of valid mnemonics for tim data sources + dssc_frame_coords: int + defines which dssc frames should be normalized using data from the tim. + + Returns + ------- + xgm: xarray.DataArray + xgm data with coordinate 'pulse'. + """ + log.debug('load tim data') + data = [] + for name in tim_names: + data.append(run_obj.get_array(*_mnemonics[name].values())) + tim_raw = xr.zeros_like(data[0]) + for d in data: + tim_raw -= d + tim_raw /= len(data) + + log.debug('calculate pulse indices in raw data') + _, ind_sase3, n_pulses = _bunch_pattern_sase3(run_obj) + ind_pulse_tim = ((np.array(ind_sase3)-ind_sase3[0])/4).astype(np.int64) + + log.debug('create formatted xarray.dataArray') + coords = {'trainId': tim_raw.trainId.values} + shape = (len(tim_raw.trainId.values), n_pulses) + tim_formatted = xr.DataArray(np.zeros(shape, dtype=np.float64), + coords=coords, + dims=['trainId', 'pulse']) + for i in range(len(tim_formatted.trainId)): + tim_formatted[i, :] = np.take(tim_raw[i, :].values, ind_pulse_tim) + + if type(dssc_frame_coords) == int: + dssc_frame_coords = np.linspace(0, + (n_pulses-1)*dssc_frame_coords, + n_pulses, + dtype=np.uint64) + + tim_formatted['pulse'] = dssc_frame_coords + log.info('loaded formatted tim data.') + return tim_formatted + + +def quickmask_DSSC_ASIC(poslist): + ''' + Returns a mask for the given DSSC geometry with ASICs given in poslist + blanked. poslist is a list of (module, row, column) tuples. Each module + consists of 2 rows and 8 columns of individual ASICS. + + Copyright (c) 2019, Michael Schneider + Copyright (c) 2020, SCS-team + license: BSD 3-Clause License (see LICENSE_BSD for more info) + ''' + mask = np.ones([16, 128, 512], dtype=float) # need floats to use NaN + for (module, row, col) in poslist: + mask[module, 64 * row:64 * (row + 1), 64 * col:64 * (col + 1)] = \ + np.nan + return mask + + +def load_mask(fname, dssc_mask): + """ + Load a DSSC mask file. + + Copyright (c) 2019, Michael Schneider + Copyright (c) 2020, SCS-team + license: BSD 3-Clause License (see LICENSE_BSD for more info) + + Parameters + ---------- + fname: str + string of the filename of the mask file + + Returns + ------- + dssc_mask: + """ + mask = imread(fname) + mask = dssc_mask.astype(float)[..., 0] // 255 + mask[dssc_mask == 0] = np.nan + return mask diff --git a/src/toolbox_scs/detectors/dssc_plot.py b/src/toolbox_scs/detectors/dssc_plot.py new file mode 100644 index 0000000000000000000000000000000000000000..470a2f4df382dff6bf75d689e926e3c83fda7473 --- /dev/null +++ b/src/toolbox_scs/detectors/dssc_plot.py @@ -0,0 +1,80 @@ +""" DSSC visualization routines + +Plotting sub-routines frequently done in combination with dssc analysis. +The initial code is based on: https://github.com/dscran/dssc_process +/blob/master/example_image_process_pulsemask.ipynb + +Todo: For visualization of statistical information we could eventually +switch to seaborn: https://seaborn.pydata.org/ +""" + +from time import strftime + +import matplotlib.pyplot as plt +import numpy as np +import xarray as xr + + +def plot_xgm_threshold(xgm, + xgm_min = None, xgm_max = None, + run_nr = '', safe_fig = False): + + fig = plt.figure() + ax = fig.add_subplot(111) + + ax.plot(xgm.trainId, xgm, 'o', c='C0', ms=1) + if xgm_min: + ax.axhline(xgm_min, c='r') + if xgm_max: + ax.axhline(xgm_max, c='r') + + ax.set_xlabel('trainId') + ax.set_ylabel('xgm') + ax.set_title(f'run: {run_nr}') + + if safe_fig == True: + tstamp = strftime('%y%m%d_%H%M') + fig.savefig(f'images/run{run_nr}_scan_{tstamp}.png', dpi=200) + + +def plot_binner(binner, + yname = 'data', xname='data', + run_nr = ''): + + fig = plt.figure() + ax = fig.add_subplot(111) + + ax.plot(binner.values) + + ax.set_ylabel(yname) + ax.set_xlabel(xname) + ax.set_title(f'run: {run_nr}') + + +def plot_binner_hist(binner, + dname = 'data', run_nr = ''): + + counts = xr.DataArray(np.ones(len(binner.values)), + dims=[dname], + coords={dname: binner.values}, + name='counts') + + counts = counts.groupby(dname).sum() + + fig = plt.figure() + ax = fig.add_subplot(111) + + ax.plot(counts[dname], counts, 'o', ms=4) + + ax.set_xlabel(dname) + ax.set_ylabel('counts') + ax.set_title(f'run {run_nr}') + ax.grid(True) + + #if safe_fig == True: + # tstamp = strftime('%y%m%d_%H%M') + # fig.savefig(f'images/run{run_nr}_scan_{tstamp}.png', dpi=200) + + +def plot_hist_processed(hist_data): + pass diff --git a/src/toolbox_scs/detectors/dssc_processing.py b/src/toolbox_scs/detectors/dssc_processing.py new file mode 100644 index 0000000000000000000000000000000000000000..62c1e27087db6ff521d3f74c7cc7373dc39132b5 --- /dev/null +++ b/src/toolbox_scs/detectors/dssc_processing.py @@ -0,0 +1,275 @@ +""" + DSSC-related sub-routines. + + comment: contributions should comply with pep8 code structure guidelines. +""" +import logging +import os + +import numpy as np +import xarray as xr +import pandas as pd + +import extra_data as ed + +from ..constants import mnemonics as _mnemonics +from .dssc_data import save_xarray + +log = logging.getLogger(__name__) + + +def create_empty_dataset(run_info, binners={}): + """ + Create empty (zero-valued) DataSet for a single DSSC module + to iteratively add data to. + + Copyright (c) 2020, SCS-team + + Parameters + ---------- + + Returns + ------- + + """ + fpt = run_info['frames_per_train'] + len_x = run_info['dims'][0] + len_y = run_info['dims'][1] + defaults = {"trainId": run_info["trainIds"], + "pulse": np.linspace(0, fpt-1, fpt, dtype=int), + "x": np.linspace(1, len_x, len_x, dtype=int), + "y": np.linspace(1, len_y, len_y, dtype=int)} + + dims = [] + coords = {} + shape = [] + + for key in defaults: + dims.append(key) + df = pd.DataFrame({'data': defaults[key]}) + if key in binners: + df = pd.DataFrame({'data': binners[key].values}) + grouped = df.groupby(['data']) + groups = list(grouped.groups.keys()) + coords[key] = groups + shape.append(len(groups)) + + da_data = xr.DataArray(np.zeros(shape, dtype=np.float64), + coords=coords, + dims=dims) + ds = da_data.to_dataset(name="data") + ds['hist'] = xr.full_like(ds.data[:, :, 0, 0], fill_value=0) + + log.debug("Prepared empty dataset for single dssc module") + return ds + + +def load_chunk_data(sel, sourcename, maxframes=None): + """ + Load selected DSSC data. The flattened multi-index (trains+pulses) is + unraveled before returning the data. + + Copyright (c) 2019, Michael Schneider + Copyright (c) 2020, SCS-team + license: BSD 3-Clause License (see LICENSE_BSD for more info) + + Parameters + ---------- + sel: extra_data.DataCollection + a DataCollection or a subset of a DataCollection obtained by its + select_trains() method + sourcename: str + + Returns + ------- + xarray.DataArray + """ + + info = sel.detector_info(sourcename) + fpt = info['frames_per_train'] + data = sel.get_array(sourcename, 'image.data', + extra_dims=['_empty_', 'x', 'y'] + ).squeeze() + + tids = np.unique(data.trainId) + data = data.rename(dict(trainId='trainId_pulse')) + + midx = pd.MultiIndex.from_product([sorted(tids), range(fpt)], + names=('trainId', 'pulse')) + data = xr.DataArray(data, + dict(trainId_pulse=midx) + ).unstack('trainId_pulse') + data = data.transpose('trainId', 'pulse', 'x', 'y') + + log.debug(f"loaded and formatted chunk of dssc data") + return data.loc[{'pulse': np.s_[:maxframes]}] + + +def _load_chunk_xgm(sel, xgm_mnemonic, stride): + """ + Load selected xgm data. + + Copyright (c) 2020, SCS-team + + Parameters + ---------- + sel: extra_data.DataCollection + a DataCollection or a subset of a DataCollection obtained by its + select_trains() method + xgm_mnemonic: str + a valid mnemonic for an xgm source from the tb.mnemonic dictionary + stride: int + indicating which dssc frames should be normalized using the xgm data. + + Returns + ------- + xarray.DataArray + """ + d = sel.get_array(*_mnemonics[xgm_mnemonic].values()) + d = d.rename(new_name_or_name_dict={'XGMbunchId': 'pulse'}) + frame_coords = np.linspace(0, (d.shape[1]-1)*stride, d.shape[1], dtype=int) + d = d.assign_coords({'pulse': frame_coords}) + log.debug(f"loaded and formatted chunk of xgm data") + return d + + +def process_dssc_data(proposal, run_nr, module, chunksize, info, dssc_binners, + path='./', + pulsemask=None, + dark_image=None, + xgm_mnemonic='SCS_SA3', + xgm_normalization=False, + normevery=1 + ): + """ + Collects and reduces DSSC data for a single module. + + Copyright (c) 2020, SCS-team + + Parameters + ---------- + proposal : int + proposal number + run_nr : int + run number + module : int + DSSC module to process + chunksize : int + number of trains to load simultaneously + info: dictionary + dictionary containing keys 'dims', 'frames_per_train', 'total_frames', + 'trainIds', 'number_of_trains'. + dssc_binners: dictionary + a dictionary containing binner objects created by the tbdet member + function "create_binner()" + path : str + location in which the .h5 files, containing the binned data, should + be stored. + pulsemask : numpy.ndarray + array of booleans to be used to mask dssc data according to xgm data. + dark_image: xarray.DataArray + an xarray dataarray with matching coordinates with the loaded data. If + dark_image is not None it will be subtracted from each individual dssc + frame. + xgm_normalization: bool + true if the data should be divided by the corresponding xgm value. + xgm_mnemonic: str + Mnemonic of the xgm data to be used for normalization. + normevery: int + One out of normevery dssc frames will be normalized. + + Returns + ------- + module_data: xarray.Dataset + xarray datastructure containing data binned according to bins. + """ + # metadata definition + ntrains = info['number_of_trains'] + chunks = np.arange(ntrains, step=chunksize) + sourcename_dssc = f'SCS_DET_DSSC1M-1/DET/{module}CH0:xtdf' + + # open extra_data run objects + collection_DSSC = ed.open_run(proposal, run_nr, + include=f'*DSSC{module:02d}*') + collection_DA1 = ed.open_run(proposal, run_nr, include='*DA01*') + log.info(f"Processing dssc module {module}: start") + + # create empty dataset for dssc data to be filled iteratively + module_data = create_empty_dataset(info, dssc_binners) + + # load data chunk by chunk and merge result into prepared empty dataset + for chunk in chunks: + log.debug(f"Module {module}: " + f"load trains {chunk}:{chunk + chunksize}") + + sel = collection_DSSC.select_trains( + ed.by_index[chunk:chunk + chunksize]) + chunk_data = load_chunk_data(sel, sourcename_dssc) + chunk_hist = xr.full_like(chunk_data[:, :, 0, 0], fill_value=1) + + # --------------------------------------------------------------------- + # optional blocks -> ToDo: see merge request !87 + # --------------------------------------------------------------------- + # option 1: prefiltering -> xgm pulse masking + if pulsemask is not None: + log.debug(f'Module {module}: drop out-of-bounds frames') + # relatively slow. ToDo -> wrap using np.ufunc + chunk_data = chunk_data.where(pulsemask) + chunk_hist = chunk_hist.where(pulsemask) + + # option 2: subtraction of dark image/s + if dark_image is not None: + log.debug(f'Module {module}: subtract dark') + chunk_data.values = chunk_data.values - dark_image.values + # slower: using xarray directly + # chunk_data = chunk_data - dark_image + + # option 3: normalize dssc frames by their xgm values + if xgm_normalization: + log.debug(f'Module {module}: load and format xgm data') + sel_DA1 = collection_DA1.select_trains( + ed.by_index[chunk:chunk + chunksize]) + chunk_xgm = _load_chunk_xgm(sel_DA1, xgm_mnemonic, normevery) + + log.debug(f'Module {module}: normalize chunk_data using xgm') + # the following line uses numpys fast vectorized array operation + # there is overhead coming from rewriting the xarrayDataarray + chunk_data.values[:, 0::normevery, :, :] = \ + np.divide(chunk_data[:, 0::normevery, :, :], chunk_xgm) + # slow code using xarray directly + # chunk_data = chunk_data / chunk_xgm + # --------------------------------------------------------------------- + # end optional blocks: xarray operations from here on. + # --------------------------------------------------------------------- + + # data reduction -> apply binners + log.debug(f'Module {module}: apply binning to chunk_data') + chunk_data = chunk_data.to_dataset(name='data') + chunk_data['hist'] = chunk_hist + for b in dssc_binners: + chunk_data[b+"_binned"] = dssc_binners[b] + chunk_data = chunk_data.groupby(b+"_binned").sum(b) + chunk_data = chunk_data.rename(name_dict={b+"_binned": b}) + + # add chunk data to loaded data + log.debug(f'Module {module}: merge junk data') + for var in ['data', 'hist']: + module_data[var] = xr.concat([module_data[var], + chunk_data[var]], + dim='tmp').sum('tmp') + + log.debug(f"Module {module}: " + f"processed trains {chunk}:{chunk + chunksize}") + + log.debug(f'Module {module}: calculate mean') + module_data['data'] = module_data['data'] / module_data['hist'] + module_data = module_data.transpose('trainId', 'pulse', 'x', 'y') + module_data.attrs['module'] = module + + log.debug(f'saving module {module}') + if not os.path.isdir(path): + os.mkdir(path) + fname = f'run_{run_nr}_module{module}.h5' + save_xarray(path+fname, module_data, mode='a') + + log.info(f"processing module {module}: done") diff --git a/FastCCD.py b/src/toolbox_scs/detectors/fccd.py similarity index 95% rename from FastCCD.py rename to src/toolbox_scs/detectors/fccd.py index e919dc131aaaba49c0a8f80487e55cb22302b539..0396df5549d8d3c4c476d351fe8627a0d1c9d8d6 100644 --- a/FastCCD.py +++ b/src/toolbox_scs/detectors/fccd.py @@ -9,16 +9,19 @@ import psutil import extra_data as ed from extra_data.read_machinery import find_proposal -import ToolBox as tb import matplotlib.pyplot as plt from mpl_toolkits.axes_grid1 import ImageGrid import numpy as np import xarray as xr import h5py from glob import glob - from imageio import imread +import ToolBox as tb +from ..constants import mnemonics as _mnemonics +from .azimuthal_integrator import AzimuthalIntegrator +from ..misc.laser_utils import positionToDelay + class FastCCD: def __init__(self, proposal, distance=1, raw=False): @@ -106,8 +109,8 @@ class FastCCD: print(f'Loading XGM data') try: - self.xgm = self.run.get_array(tb.mnemonics['SCS_SA3']['source'], - tb.mnemonics['SCS_SA3']['key'], + self.xgm = self.run.get_array(_mnemonics['SCS_SA3']['source'], + _mnemonics['SCS_SA3']['key'], roi=ed.by_index[:self.nbunches]) self.xgm = self.xgm.squeeze() # remove the pulseId dimension since XGM should have only 1 value per train except: @@ -115,8 +118,8 @@ class FastCCD: print(f'Loading mono nrj data') try: - self.nrj = self.run.get_array(tb.mnemonics['nrj']['source'], - tb.mnemonics['nrj']['key']) + self.nrj = self.run.get_array(_mnemonics['nrj']['source'], + _mnemonics['nrj']['key']) except: self.nrj = xr.DataArray(np.zeros_like(self.run.train_ids),dims = 'trainId', coords = {"trainId":self.run.train_ids}) @@ -124,16 +127,16 @@ class FastCCD: print(f'Loading delay line data') try: - self.delay_mm = self.run.get_array(tb.mnemonics['PP800_DelayLine']['source'], - tb.mnemonics['PP800_DelayLine']['key']) + self.delay_mm = self.run.get_array(_mnemonics['PP800_DelayLine']['source'], + _mnemonics['PP800_DelayLine']['key']) except: self.delay_mm = xr.DataArray(np.zeros_like(self.run.train_ids),dims = 'trainId', coords = {"trainId":self.run.train_ids}) self.t0 = t0 - self.delay_ps = tb.positionToDelay(self.delay_mm, origin=self.t0, invert=True) + self.delay_ps = positionToDelay(self.delay_mm, origin=self.t0, invert=True) print(f'Loading Fast ADC5 data') try: - self.FastADC5 = self.run.get_array(tb.mnemonics['FastADC5raw']['source'], tb.mnemonics['FastADC5raw']['key']).max('dim_0') + self.FastADC5 = self.run.get_array(_mnemonics['FastADC5raw']['source'], _mnemonics['FastADC5raw']['key']).max('dim_0') self.FastADC5[self.FastADC5<35000] = 0 self.FastADC5[self.FastADC5>=35000] = 1 except: @@ -178,9 +181,9 @@ class FastCCD: if type(vname) is dict: self.scan = self.run.get_array(vname['source'], vname['key']) elif type(vname) is str: - if vname not in tb.mnemonics: + if vname not in _mnemonics: raise ValueError(f'{vname} not found in the ToolBox mnemonics table') - self.scan = self.run.get_array(tb.mnemonics[vname]['source'], tb.mnemonics[vname]['key']) + self.scan = self.run.get_array(_mnemonics[vname]['source'], _mnemonics[vname]['key']) else: raise ValueError(f'vname should be a string or a dict. We got {type(vname)}') @@ -235,7 +238,7 @@ class FastCCD: plt.figure(figsize=(5,3)) plt.bar(bins_center, hist, align='center', width=width) - plt.xlabel(f"{tb.mnemonics['SCS_SA3']['source']}{tb.mnemonics['SCS_SA3']['key']}") + plt.xlabel(f"{_mnemonics['SCS_SA3']['source']}{_mnemonics['SCS_SA3']['key']}") plt.ylabel('density') plt.title(self.plot_title) @@ -499,7 +502,7 @@ class FastCCD: im_pumped_mean = im_pumped_arranged.mean(axis=0) im_unpumped_mean = im_unpumped_arranged.mean(axis=0) - ai = tb.azimuthal_integrator(im_pumped_mean.shape, center, angle_range, dr=dr, aspect=1) + ai = AzimuthalIntegrator(im_pumped_mean.shape, center, angle_range, dr=dr, aspect=1) norm = ai(~np.isnan(im_pumped_mean)) az_pump = [] diff --git a/src/toolbox_scs/detectors/tim.py b/src/toolbox_scs/detectors/tim.py new file mode 100644 index 0000000000000000000000000000000000000000..b7ec77121174cc775fd36cbfee42dd3eaca18702 --- /dev/null +++ b/src/toolbox_scs/detectors/tim.py @@ -0,0 +1,54 @@ +""" Tim related sub-routines + + Copyright (2019) SCS Team. + contributions preferrably comply with pep8 code structure + guidelines. +""" + +import logging + +import xarray as xr + +from .xgm import matchXgmTimPulseId +from ..constants import mnemonics as _mnemonics + + + +log = logging.getLogger(__name__) + + +def load_TIM(run, apd='MCP2apd'): + """ + Load TIM traces and match them to SASE3 pulses. + + Parameters + ---------- + run: extra_data.DataCollection, extra_data.RunDirectory + + Returns + ------- + timdata : xarray.DataArray + xarray DataArray containing the tim data + + Example + ------- + >>> import toolbox_scs as tb + >>> import toolbox_scs.detectors as tbdet + >>> run = tb.run_by_proposal(2212, 235) + >>> data = tbdet.load_TIM(run) + """ + + fields = ["sase1", "sase3", "npulses_sase3", + "npulses_sase1", apd, "SCS_SA3", "nrj"] + timdata = xr.Dataset() + + for f in fields: + m = _mnemonics[f] + timdata[f] = run.get_array(m['source'], + m['key'], + extra_dims=m['dim']) + + timdata.attrs['run'] = run + timdata = matchXgmTimPulseId(timdata) + + return timdata.rename({'sa3_pId': 'pulse'})[apd] \ No newline at end of file diff --git a/xgm.py b/src/toolbox_scs/detectors/xgm.py similarity index 97% rename from xgm.py rename to src/toolbox_scs/detectors/xgm.py index f60f8b4cb117011ce7823ed0c9ca4fda5b82ab8c..cb77bded175c5295d970414477c320c17d080336 100644 --- a/xgm.py +++ b/src/toolbox_scs/detectors/xgm.py @@ -1,17 +1,59 @@ -# -*- coding: utf-8 -*- -""" Toolbox for SCS. - - Various utilities function to quickly process data measured at the SCS instruments. +""" XGM related sub-routines Copyright (2019) SCS Team. + + (contributions preferrably comply with pep8 code structure + guidelines.) """ -import matplotlib.pyplot as plt + +import logging + import numpy as np import xarray as xr +import matplotlib.pyplot as plt from scipy.signal import find_peaks -import ToolBox as tb +import extra_data as ed + +from ..constants import mnemonics as _mnemonics + + +log = logging.getLogger(__name__) + + +def load_xgm(run, xgm_mnemonic='SCS_SA3'): + """ + Loads XGM data from karabo_data.DataCollection + + Parameters + ---------- + run: karabo_data.DataCollection + + Returns + ------- + xgm : xarray.DataArray + xarray DataArray containing the xgm data + + Example + ------- + >>> import toolbox_scs as tb + >>> import toolbox_scs.detectors as tbdet + >>> run = tb.run_by_proposal(2212, 235) + >>> xgm_data = tbdet.load_xgm(run) + """ + nbunches = run.get_array(*_mnemonics['sase3'].values()) + nbunches = np.unique(nbunches) + if len(nbunches) == 1: + nbunches = nbunches[0] + else: + log.info('change of pulse pattern in sase3 during the run.') + nbunches = max(nbunches) + + log.info(f'maximum number of bunches per train in sase3: {nbunches}') + xgm = run.get_array(*_mnemonics[xgm_mnemonic].values(), + roi=ed.by_index[:nbunches]) + return xgm + -# XGM def cleanXGMdata(data, npulses=None, sase3First=True): ''' Cleans the XGM data arrays obtained from load() function. The XGM "TD" data arrays have arbitrary size of 1000 and default value 1.0 @@ -250,7 +292,7 @@ def calibrateXGMs(data, allPulses=False, plot=False, display=False): print(f'Using fast data averages (slowTrain) for {whichXgm}') slowTrainData.append(data[f'{whichXgm}_slowTrain']) else: - mnemo = tb.mnemonics[f'{whichXgm}_slowTrain'] + mnemo = _mnemonics[f'{whichXgm}_slowTrain'] if mnemo['key'] in data.attrs['run'].keys_for_source(mnemo['source']): if display: print(f'Using fast data averages (slowTrain) for {whichXgm}') @@ -1041,4 +1083,3 @@ def mergeFastAdcPeaks(data, channel, intstart, intstop, bkgstart, bkgstop, subset.attrs[k] = data.attrs[k] return subset - diff --git a/src/toolbox_scs/load.py b/src/toolbox_scs/load.py new file mode 100644 index 0000000000000000000000000000000000000000..c9735342fdd4649036eb3c18b7cb7cdb3eb4f616 --- /dev/null +++ b/src/toolbox_scs/load.py @@ -0,0 +1,297 @@ +# -*- coding: utf-8 -*- +""" + Toolbox for SCS. + + Various utilities function to quickly process data measured at the SCS + instruments. + + Copyright (2019) SCS Team. +""" + +import logging + +import numpy as np +import xarray as xr + +import extra_data as ed + +from .misc.bunch_pattern import extractBunchPattern +from .constants import mnemonics as _mnemonics_ld +from .util.exceptions import ToolBoxValueError, ToolBoxPathError +from .util.data_access import find_run_dir + +log = logging.getLogger(__name__) + + +def load(fields, runNB, proposalNB, + subFolder='raw', + display=False, + validate=False, + subset=ed.by_index[:], + rois={}, + useBPTable=True): + """ + Load a run and extract the data. Output is an xarray with aligned + trainIds + + Parameters + ---------- + + fields: list of strings, list of dictionaries + list of mnemonic strings to load specific data such as "fastccd", + "SCS_XGM", or dictionnaries defining a custom mnemonic such as + {"extra": + {'SCS_CDIFFT_MAG/SUPPLY/CURRENT', + 'actual_current.value', None}} + runNB: (str, int) + run number as integer + proposalNB: (str, int) + of the proposal number e.g. 'p002252' or 2252 + subFolder: (str) + sub-folder from which to load the data. Use 'raw' for raw data + or 'proc' for processed data. + display: (bool) + whether to show the run.info or not + validate: (bool) + whether to run extra-data-validate or not + subset: + a subset of train that can be load with by_index[:5] for the first 5 + trains + rois: dictionary + a dictionnary of mnemonics with a list of rois definition and + the desired names, for example: + {'fastccd': + {'ref': + {'roi': by_index[730:890, 535:720], + 'dim': ['ref_x', 'ref_y']}, + 'sam': + {'roi':by_index[1050:1210, 535:720], + 'dim': ['sam_x', 'sam_y']}}} + useBPTable: boolean + If True, uses the raw bunch pattern table to extract sase pulse number + and indices in the trains. If false, load the data from BUNCH_DECODER + middle layer device. + + Returns + ------- + res: xarray.DataArray + an xarray DataSet with aligned trainIds + """ + try: + runFolder = find_run_dir(proposalNB, runNB) + except ToolBoxPathError as err: + log.error(f"{err.message}") + raise + + run = ed.RunDirectory(runFolder).select_trains(subset) + + if validate: + # get_ipython().system('extra-data-validate ' + runFolder) + pass + if display: + print('Loading data from {}'.format(runFolder)) + run.info() + + keys = [] + vals = [] + + # load pulse pattern info + if useBPTable: + bp_mnemo = _mnemonics_ld['bunchPatternTable'] + if bp_mnemo['source'] not in run.all_sources: + print('Source {} not found in run. Skipping!'.format( + _mnemonics_ld['bunchPatternTable']['source'])) + else: + bp_table = run.get_array(bp_mnemo['source'], bp_mnemo['key'], + extra_dims=bp_mnemo['dim']) + sase1, npulses_sase1, dummy = extractBunchPattern( + bp_table, 'sase1') + sase3, npulses_sase3, dummy = extractBunchPattern( + bp_table, 'sase3') + keys += ["sase1", "npulses_sase1", "sase3", "npulses_sase3"] + vals += [sase1, npulses_sase1, sase3, npulses_sase3] + else: + fields += ["sase1", "sase3", "npulses_sase3", "npulses_sase1"] + + for f in fields: + + if type(f) == dict: + # extracting mnemomic defined on the spot + if len(f.keys()) > 1: + print('Loading only one "on-the-spot" mnemonic at a time, ' + 'skipping all others !') + k = list(f.keys())[0] + v = f[k] + else: + # extracting mnemomic from the table + if f in _mnemonics_ld: + v = _mnemonics_ld[f] + k = f + else: + print('Unknow mnemonic "{}". Skipping!'.format(f)) + continue + + if k in keys: + continue # already loaded, skip + + if display: + print('Loading {}'.format(k)) + + if v['source'] not in run.all_sources: + print('Source {} not found in run. Skipping!'.format(v['source'])) + continue + + if k not in rois: + # no ROIs selection, we read everything + vals.append(run.get_array(v['source'], v['key'], + extra_dims=v['dim'])) + keys.append(k) + else: + # ROIs selection, for each ROI we select a region of the data and + # save it with new name and dimensions + for nk, nv in rois[k].items(): + vals.append(run.get_array(v['source'], v['key'], + extra_dims=nv['dim'], + roi=nv['roi'])) + keys.append(nk) + + aligned_vals = xr.align(*vals, join='inner') + result = dict(zip(keys, aligned_vals)) + result = xr.Dataset(result) + result.attrs['run'] = run + result.attrs['runFolder'] = runFolder + return result + + +def load_run(proposal, run, **kwargs): + """ + Get run in given proposal + + Wraps the extra_data open_run routine, out of convenience for the toolbox + user. More information can be found in the karabo_data documentation. + + Parameters + ---------- + proposal: str, int + Proposal number + run: str, int + Run number + + **kwargs + -------- + data: str + default -> 'raw' + include: str + default -> '*' + + Returns + ------- + run : extra_data.DataCollection + DataCollection object containing information about the specified + run. Data can be loaded using built-in class methods. + """ + return ed.open_run(proposal, run, **kwargs) + + +def run_by_path(path): + """ + Return specified run + + Wraps the extra_data RunDirectory routine, to ease its use for the + scs-toolbox user. + + Parameters + ---------- + path: str + path to the run directory + + Returns + ------- + run : extra_data.DataCollection + DataCollection object containing information about the specified + run. Data can be loaded using built-in class methods. + """ + return ed.RunDirectory(path) + + +def concatenateRuns(runs): + """ Sorts and concatenate a list of runs with identical data variables + along the trainId dimension. + + Input: + runs: (list) the xarray Datasets to concatenate + Output: + a concatenated xarray Dataset + """ + firstTid = {i: int(run.trainId[0].values) for i, run in enumerate(runs)} + orderedDict = dict(sorted(firstTid.items(), key=lambda t: t[1])) + orderedRuns = [runs[i] for i in orderedDict] + keys = orderedRuns[0].keys() + for run in orderedRuns[1:]: + if run.keys() != keys: + print('data fields between different runs are not identical. ' + 'Cannot combine runs.') + return + + result = xr.concat(orderedRuns, dim='trainId') + for k in orderedRuns[0].attrs.keys(): + result.attrs[k] = [run.attrs[k] for run in orderedRuns] + return result + + +def get_array(run, mnemonic_key=None, stepsize=None): + """ + Loads the required 1D-data and rounds its values to integer multiples of + stepsize for consistent grouping (except for stepsize=None). + Returns a dummy array if mnemonic is set to None. + + Parameters + ---------- + run: karabo_data.DataCollection + path to the run directory + mnemonic_key: str + Identifier of a single item in the mnemonic collection. None creates a + dummy file to average over all trains in the run + stepsize : float + nominal stepsize of the array data - values will be rounded to integer + multiples of this value + + Returns + ------- + data : xarray.DataArray + xarray DataArray containing rounded array values using the trainId as + coordinate. + + Raises + ------ + ToolBoxValueError: Exception + Toolbox specific exception, indicating a non-valid mnemonic entry + + Example + ------- + >>> import toolbox_scs as tb + >>> run = tb.load_run(2212, 235) + >>> mnemonic = 'PP800_PhaseShifter' + >>> data_PhaseShifter = tb.get_array(run, mnemonic, 0.5) + """ + + try: + if mnemonic_key is None: + data = xr.DataArray( + np.ones(len(run.train_ids), dtype=np.int16), + dims=['trainId'], coords={'trainId': run.train_ids}) + elif mnemonic_key in _mnemonics_ld: + mnem = _mnemonics_ld[mnemonic_key] + data = run.get_array(*mnem.values()) + else: + raise ToolBoxValueError("Invalid mnemonic", mnemonic_key) + + if stepsize is not None: + data = stepsize * np.round(data / stepsize) + data.name = 'data' + log.debug(f"Got data for {mnemonic_key}") + except ToolBoxValueError as err: + log.error(f"{err.message}") + raise + + return data diff --git a/src/toolbox_scs/misc/__init__.py b/src/toolbox_scs/misc/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9afb2d95ac3461a7d9d2be909eda3a918b819bd0 --- /dev/null +++ b/src/toolbox_scs/misc/__init__.py @@ -0,0 +1,24 @@ +from .bunch_pattern import (extractBunchPattern, pulsePatternInfo, + repRate, sortBAMdata, + ) +from .bunch_pattern_external import is_sase_3, is_sase_1, is_ppl +from .laser_utils import positionToDelay, degToRelPower + + +__all__ = ( + # Functions + "extractBunchPattern", + "pulsePatternInfo", + "repRate", + "sortBAMdata", + "is_sase_3", + "is_sase_1", + "is_ppl", + "get_index_ppl", + "get_index_sase1", + "get_index_sase3", + "positionToDelay", + "degToRelPower", + # Classes + # Variables +) diff --git a/bunch_pattern.py b/src/toolbox_scs/misc/bunch_pattern.py similarity index 98% rename from bunch_pattern.py rename to src/toolbox_scs/misc/bunch_pattern.py index 0ff19613a89ff589d24c3a4050e4d75d84f6361c..2edf85437f0f4ea966e27c26d24049efbb2554ef 100644 --- a/bunch_pattern.py +++ b/src/toolbox_scs/misc/bunch_pattern.py @@ -6,13 +6,17 @@ Copyright (2019) SCS Team. """ +import os + import numpy as np import xarray as xr -import ToolBox as tb -import os from extra_data.read_machinery import find_proposal from extra_data import RunDirectory +# import and hide variable, such that it does not alter namespace. +from ..constants import mnemonics as _mnemonics_bp + + def extractBunchPattern(bp_table=None, key='sase3', runDir=None): ''' generate the bunch pattern and number of pulses of a source directly from the bunch pattern table and not using the MDL device BUNCH_DECODER. This is @@ -37,7 +41,7 @@ def extractBunchPattern(bp_table=None, key='sase3', runDir=None): if bp_table is None: if runDir is None: raise ValueError('bp_table and runDir cannot both be None') - bp_mnemo = tb.mnemonics['bunchPatternTable'] + bp_mnemo = _mnemonics_bp['bunchPatternTable'] if bp_mnemo['source'] not in runDir.all_sources: raise ValueError('Source {} not found in run'.format( bp_mnemo['source'])) @@ -188,7 +192,7 @@ def repRate(data=None, runNB=None, proposalNB=None, key='sase3'): proposalNB = 'p{:06d}'.format(proposalNB) runFolder = os.path.join(find_proposal(proposalNB), 'raw', runNB) runDir = RunDirectory(runFolder) - bp_mnemo = tb.mnemonics['bunchPatternTable'] + bp_mnemo = _mnemonics_bp['bunchPatternTable'] if bp_mnemo['source'] not in runDir.all_sources: raise ValueError('Source {} not found in run'.format( bp_mnemo['source'])) diff --git a/bunch_pattern_external.py b/src/toolbox_scs/misc/bunch_pattern_external.py similarity index 50% rename from bunch_pattern_external.py rename to src/toolbox_scs/misc/bunch_pattern_external.py index 6fae7007f6632395ef272696e96d257eec8bf561..0a5ca3ba4a2f9256704bff34f30fdd05424396ac 100644 --- a/bunch_pattern_external.py +++ b/src/toolbox_scs/misc/bunch_pattern_external.py @@ -7,13 +7,30 @@ information from the bunch pattern tables. To ease its use from within the toolbox some of its methods are wrapped. Like this they show up in the users namespace in a self-explanatory way. """ +import logging import euxfel_bunch_pattern as ebp PPL_SCS = ebp.LASER_SEED6 +log = logging.getLogger(__name__) -def is_sase_3(data): +def _convert_data(bpt_dec): + bpt_conv = bpt_dec + + if type(bpt_dec).__module__ == 'xarray.core.dataarray': + bpt_conv = bpt_dec.where(bpt_dec.values == True, other = 0) + elif type(bpt_dec).__module__ == 'numpy': + bpt_conv = bpt_dec.astype(int) + else: + dtype = type(bpt_dec).__module__ + log.warning(f"Could not convert data type {dtype}." + "Return raw euxfel_bp table.") + + return bpt_conv + + +def is_sase_3(bpt): """ Check for prescence of a SASE3 pulse. @@ -27,10 +44,11 @@ def is_sase_3(data): boolean : numpy array, xarray DataArray true if SASE3 pulse is present. """ - return ebp.is_sase(data, 3) + bpt_dec = ebp.is_sase(bpt, 3) + return _convert_data(bpt_dec) -def is_sase_1(data): +def is_sase_1(bpt): """ Check for prescence of a SASE1 pulse. @@ -44,16 +62,17 @@ def is_sase_1(data): boolean : numpy array, xarray DataArray true if SASE1 pulse is present. """ - return ebp.is_sase(data, 1) + bpt_dec = ebp.is_sase(bpt, 1) + return _convert_data(bpt_dec) -def is_ppl(data): +def is_ppl(bpt): """ Check for prescence of pp-laser pulse. Parameters ---------- - data : numpy array, xarray DataArray + bpt : numpy array, xarray DataArray The bunch pattern data. Returns @@ -61,55 +80,5 @@ def is_ppl(data): boolean : numpy array, xarray DataArray true if pp-laser pulse is present. """ - return ebp.is_laser(data, laser=PPL_SCS) - - -def get_index_ppl(data): - """ - Check array index where pp-laser pulse is present. - - Parameters - ---------- - data : numpy array - The bunch pattern data. - - Returns - ------- - boolean : numpy array - The indices of the pp-laser pulses in the given array. - """ - return ebp.indices_at_laser(data, laser=PPL_SCS) - - -def get_index_sase1(data): - """ - Search for array index where SASE1 pulse is present. - - Parameters - ---------- - data : numpy array - The bunch pattern data. - - Returns - ------- - boolean : numpy array - The indices of the SASE1 pulses in the given array. - """ - return ebp.indices_at_sase(data, 1) - - -def get_index_sase3(data): - """ - Search for array index where SASE3 pulse is present. - - Parameters - ---------- - data : numpy array - The bunch pattern data. - - Returns - ------- - boolean : numpy array - The indices of the SASE3 pulses in the given array. - """ - return ebp.indices_at_sase(data, 3) + bpt_dec = ebp.is_laser(bpt, laser=PPL_SCS) + return _convert_data(bpt_dec) diff --git a/Laser_utils.py b/src/toolbox_scs/misc/laser_utils.py similarity index 100% rename from Laser_utils.py rename to src/toolbox_scs/misc/laser_utils.py diff --git a/XAS.py b/src/toolbox_scs/routines/XAS.py similarity index 100% rename from XAS.py rename to src/toolbox_scs/routines/XAS.py diff --git a/src/toolbox_scs/routines/__init__.py b/src/toolbox_scs/routines/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/knife_edge.py b/src/toolbox_scs/routines/knife_edge.py similarity index 100% rename from knife_edge.py rename to src/toolbox_scs/routines/knife_edge.py diff --git a/src/toolbox_scs/test/README.rst b/src/toolbox_scs/test/README.rst new file mode 100644 index 0000000000000000000000000000000000000000..2afe1d9c4a5aef81b8cb255e730e3ffdfd500d1b --- /dev/null +++ b/src/toolbox_scs/test/README.rst @@ -0,0 +1,74 @@ +============ +Test modules +============ + +Comments +======== + +The code below is intended to be executed from the command line in the directory: +toolbox\_scs/test. + +The test suites directly import the toolbox\_scs/ package. The idea is that problems related to packaging come up immediately (changing folder structure, breaking relative dependencies between the subpackages ....). + +Requirements to run the code are: + +* loaded exfel_anaconda3 environment +* local installation of toolbox\_scs using pip (pip install --user .) + +*Comment*: During development, use the -e flag when installing via pip, such that changes become effective immediately. + +Usage +===== + +* **Help message** + +.. code:: bash + + python test_top_level --help + + +.. parsed-literal:: + + usage: test_top_level.py [-h] [--list-suites] [--run-suites S [S ...]] + + optional arguments: + -h, --help show this help message and exit + --list-suites list possible test suites + --run-suites S [S ...] + a list of valid test suites + +* **List available test suites** + +.. code:: bash + + python test_top_level --list-suites + + +.. parsed-literal:: + + + Possible test suites: + ------------------------- + packaging + load + ------------------------- + +* **Run selected test suites** + +.. code:: bash + + python3 test_top_level --run-suites packaging + + +.. parsed-literal:: + + test_constant (__main__.TestToolbox) ... INFO:extra_data.read_machinery:Found proposal dir '/gpfs/exfel/exp/SCS/201901/p002212' in 0.055 s + DEBUG:extra_data.run_files_map:Loaded cached files map from /gpfs/exfel/exp/SCS/201901/p002212/scratch/.karabo_data_maps/raw_r0235.json + DEBUG:extra_data.run_files_map:Loaded cached files map in 0.29 s + DEBUG:extra_data.reader:Opened run with 313 files in 0.22 s + ok + + ---------------------------------------------------------------------- + Ran 1 test in 0.616s + + OK \ No newline at end of file diff --git a/src/toolbox_scs/test/__init__.py b/src/toolbox_scs/test/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/src/toolbox_scs/test/__init__.py @@ -0,0 +1 @@ + diff --git a/src/toolbox_scs/test/test_all.sh b/src/toolbox_scs/test/test_all.sh new file mode 100644 index 0000000000000000000000000000000000000000..78a4eacf96f528c4a7d640a4bf1b691b3fca53d7 --- /dev/null +++ b/src/toolbox_scs/test/test_all.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +python test_top_level.py --run-suite packaging load +python test_misc.py --run-suite bunch-pattern-decoding +python test_utils.py --run-suite ed-extensions +python test_dssc_cls.py --run-suite no-processing \ No newline at end of file diff --git a/src/toolbox_scs/test/test_dssc_cls.py b/src/toolbox_scs/test/test_dssc_cls.py new file mode 100644 index 0000000000000000000000000000000000000000..9fc715a316d55c5d0bbff7ce6264d659ddc40205 --- /dev/null +++ b/src/toolbox_scs/test/test_dssc_cls.py @@ -0,0 +1,275 @@ +import unittest +import logging +import os +import argparse +import shutil +from time import strftime + +import numpy as np +import xarray as xr +import extra_data as ed + +import toolbox_scs as tb +import toolbox_scs.detectors as tbdet + +logging.basicConfig(level=logging.DEBUG) +log_root = logging.getLogger(__name__) + + +suites = {"no-processing": ( + "test_create", + "test_use_xgm_tim", + ), + "processing": ( + "test_processing_quick", + #"test_normalization_all", + ) + } + + +_temp_dirs = ['tmp'] + +def setup_tmp_dir(): + for d in _temp_dirs: + if not os.path.isdir(d): + os.mkdir(d) + +def cleanup_tmp_dir(): + for d in _temp_dirs: + shutil.rmtree(d, ignore_errors=True) + log_root.info(f'remove {d}') + + +class TestDSSC(unittest.TestCase): + @classmethod + def setUpClass(cls): + log_root.info("Start global setup") + setup_tmp_dir() + log_root.info("Finished global setup, start tests") + + @classmethod + def tearDownClass(cls): + log_root.info("Clean up test environment....") + cleanup_tmp_dir() + + def test_create(self): + proposal_nb = 2212 + run_nb = 235 + run = tb.load_run(proposal_nb, run_nb, include='*DA*') + run_info = tbdet.load_dssc_info(proposal_nb, run_nb) + bins_trainId = tb.get_array(run, + 'PP800_PhaseShifter', + 0.04) + bins_pulse = ['pumped', 'unpumped'] * 10 + + binner1 = tbdet.create_dssc_bins("trainId", + run_info['trainIds'], + bins_trainId.values) + binner2 = tbdet.create_dssc_bins("pulse", + np.linspace(0,19,20, dtype=int), + bins_pulse) + binners = {'trainId': binner1, 'pulse': binner2} + params = {'binners': binners} + + # normal + run235 = tbdet.DSSCBinner(proposal_nb, run_nb) + del(run235) + + run235 = tbdet.DSSCBinner(2212, 235, dssc_coords_stride=1) + run235.add_binner('trainId', binner1) + run235.add_binner('pulse', binner2) + xgm_threshold=(300.0, 8000.0) + run235.create_pulsemask('xgm', xgm_threshold) + self.assertIsNotNone(run235.get_xgm_binned()) + + self.assertEqual(run235.binners['trainId'].values[0], + np.float32(7585.52)) + + # expected fails + with self.assertRaises(FileNotFoundError) as cm: + run235 = tbdet.DSSCBinner(2212, 2354) + err_msg = "[Errno 2] No such file or directory: " \ + "'/gpfs/exfel/exp/SCS/201901/p002212/raw/r2354'" + self.assertEqual(str(cm.exception), err_msg) + + def test_use_xgm_tim(self): + proposal_nb = 2599 + run_nb = 103 + + run_info = tbdet.load_dssc_info(proposal_nb, run_nb) + fpt = run_info['frames_per_train'] + n_trains = run_info['number_of_trains'] + trainIds = run_info['trainIds'] + + buckets_train = ['chunk1']*n_trains + buckets_pulse = ['image_unpumped', 'dark', + 'image_pumped', 'dark'] + + binner1 = tbdet.create_dssc_bins("trainId",trainIds,buckets_train) + binner2 = tbdet.create_dssc_bins("pulse", + np.linspace(0,fpt-1,fpt, dtype=int), + buckets_pulse) + binners = {'trainId': binner1, 'pulse': binner2} + dssc_frame_coords = np.linspace(0,2,2, dtype=np.uint64) + bin_obj = tbdet.DSSCBinner(proposal_nb, run_nb, + binners=binners, + dssc_coords_stride=dssc_frame_coords) + bin_obj.load_xgm() + bin_obj.load_tim() + xgm_binned = bin_obj.get_xgm_binned() + tim_binned = bin_obj.get_tim_binned() + self.assertIsNotNone(xgm_binned) + self.assertIsNotNone(tim_binned) + + def test_processing_quick(self): + proposal_nb = 2530 + module_list=[2] + run_nb = 49 + + + run_info = tbdet.load_dssc_info(proposal_nb, run_nb) + fpt = run_info['frames_per_train'] + n_trains = run_info['number_of_trains'] + trainIds = run_info['trainIds'] + + buckets_train = np.zeros(n_trains) + buckets_pulse = ['image', 'dark'] * 99 + ['image_last'] + + binner1 = tbdet.create_dssc_bins("trainId", + trainIds, + buckets_train) + binner2 = tbdet.create_dssc_bins("pulse", + np.linspace(0,fpt-1,fpt, dtype=int), + buckets_pulse) + binners = {'trainId': binner1, 'pulse': binner2} + bin_obj = tbdet.DSSCBinner(proposal_nb, run_nb, binners=binners) + bin_obj.process_data( + modules=module_list, filepath='./tmp/', chunksize=248) + filename = f'./tmp/run_{run_nb}_module{module_list[0]}.h5' + self.assertTrue(os.path.isfile(filename)) + + run_formatted = tbdet.DSSCFormatter('./tmp/') + run_formatted.combine_files() + attrs = {'run_type':'useful description', + 'comment':'blabla', + 'run_number':run_nb} + run_formatted.add_attributes(attrs) + run_formatted.save_formatted_data( + f'./tmp/run_{run_nb}_formatted.h5') + data = tbdet.load_xarray(f'./tmp/run_{run_nb}_formatted.h5') + self.assertIsNotNone(data) + + def test_normalization_all(self): + proposal_nb = 2530 + module_list=[2] + + # dark + run_nb = 49 + run_info = tbdet.load_dssc_info(proposal_nb, run_nb) + fpt = run_info['frames_per_train'] + n_trains = run_info['number_of_trains'] + trainIds = run_info['trainIds'] + + buckets_train = np.zeros(n_trains) + + binner1 = tbdet.create_dssc_bins("trainId", + trainIds, + buckets_train) + binner2 = tbdet.create_dssc_bins("pulse", + np.linspace(0,fpt-1,fpt, dtype=int), + np.linspace(0,fpt-1,fpt, dtype=int)) + binners = {'trainId': binner1, 'pulse': binner2} + bin_obj = tbdet.DSSCBinner(proposal_nb, run_nb, binners=binners) + bin_obj.process_data( + modules=module_list, filepath='./tmp/', chunksize=248) + filename = f'./tmp/run_{run_nb}_module{module_list[0]}.h5' + self.assertTrue(os.path.isfile(filename)) + + run_formatted = tbdet.DSSCFormatter('./tmp/') + run_formatted.combine_files() + attrs = {'run_type':'useful description', + 'comment':'blabla', + 'run_number':run_nb} + run_formatted.add_attributes(attrs) + run_formatted.save_formatted_data( + f'./tmp/run_{run_nb}_formatted.h5') + + # main run + run_nb = 50 + run_info = tbdet.load_dssc_info(proposal_nb, run_nb) + fpt = run_info['frames_per_train'] + n_trains = run_info['number_of_trains'] + trainIds = run_info['trainIds'] + + buckets_train = np.zeros(n_trains) + buckets_pulse = ['image', 'dark'] * 99 + ['image_last'] + + binner1 = tbdet.create_dssc_bins("trainId", + trainIds, + buckets_train) + binner2 = tbdet.create_dssc_bins("pulse", + np.linspace(0,fpt-1,fpt, dtype=int), + buckets_pulse) + binners = {'trainId': binner1, 'pulse': binner2} + bin_obj = tbdet.DSSCBinner(proposal_nb, run_nb, binners=binners) + + dark = tbdet.load_xarray('./tmp/run_49_formatted.h5') + bin_params = {'modules':module_list, + 'chunksize':248, + 'filepath':'./tmp/', + 'xgm_normalization':True, + 'normevery':2, + 'dark_image':dark['data'] + } + + bin_obj.process_data(**bin_params) + filename = f'./tmp/run_{run_nb}_module{module_list[0]}.h5' + self.assertTrue(os.path.isfile(filename)) + + + +def list_suites(): + print("\nPossible test suites:\n" + "-" * 79) + for key in suites: + print(key) + print("-" * 79 + "\n") + + +def suite(*tests): + suite = unittest.TestSuite() + for test in tests: + suite.addTest(TestDSSC(test)) + return suite + + +def main(*cliargs): + try: + for test_suite in cliargs: + if test_suite in suites: + runner = unittest.TextTestRunner(verbosity=2) + runner.run(suite(*suites[test_suite])) + else: + log_root.warning( + "Unknown suite: '{}'".format(test_suite)) + pass + except Exception as err: + log_root.error("Unecpected error: {}".format(err), + exc_info=True) + pass + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--list-suites', + action='store_true', + help='list possible test suites') + parser.add_argument('--run-suites', metavar='S', + nargs='+', action='store', + help='a list of valid test suites') + args = parser.parse_args() + + if args.list_suites: + list_suites() + + if args.run_suites: + main(*args.run_suites) diff --git a/src/toolbox_scs/test/test_misc.py b/src/toolbox_scs/test/test_misc.py new file mode 100644 index 0000000000000000000000000000000000000000..8644aa633ec467d041a0ff800bf0a44e90756681 --- /dev/null +++ b/src/toolbox_scs/test/test_misc.py @@ -0,0 +1,115 @@ +import unittest +import logging +import os +import sys +import argparse + +import toolbox_scs as tb +import toolbox_scs.misc as tbm +from toolbox_scs.util.exceptions import ToolBoxPathError + +# ----------------------------------------------------------------------------- +# global test settings +# ----------------------------------------------------------------------------- +proposalNB = 2511 +runNB = 176 +# ----------------------------------------------------------------------------- + +suites = {"bunch-pattern-decoding": ( + "test_isppl", + "test_issase1", + "test_issase3", + "test_extractBunchPattern", + "test_pulsePatternInfo", + ) + } + +class TestDataAccess(unittest.TestCase): + @classmethod + def setUpClass(cls): + run = tb.load_run(proposalNB, runNB) + mnemonic = tb.mnemonics["bunchPatternTable"] + cls._bpt = run.get_array(*mnemonic.values()) + + @classmethod + def tearDownClass(cls): + pass + + def setUp(self): + pass + + def tearDown(self): + pass + + def test_isppl(self): + cls = self.__class__ + bpt_decoded = tbm.is_ppl(cls._bpt) + self.assertEqual(bpt_decoded.values[0][0],1) + + def test_issase1(self): + cls = self.__class__ + bpt_decoded = tbm.is_sase_3(cls._bpt) + self.assertEqual(bpt_decoded.values[0][0],0) + + def test_issase3(self): + cls = self.__class__ + bpt_decoded = tbm.is_sase_3(cls._bpt) + self.assertEqual(bpt_decoded.values[0][0],0) + + def test_extractBunchPattern(self): + cls = self.__class__ + bpt_decoded = tbm.extractBunchPattern(cls._bpt, + 'scs_ppl') + self.assertIsNotNone(bpt_decoded) + self.assertEqual(bpt_decoded[0].values[0,1],80) + + def test_pulsePatternInfo(self): + pass + + +def list_suites(): + print("\nPossible test suites:\n" + "-" * 79) + for key in suites: + print(key) + print("-" * 79 + "\n") + +def suite(*tests): + suite = unittest.TestSuite() + for test in tests: + suite.addTest(TestDataAccess(test)) + return suite + + +def start_tests(*cliargs): + logging.basicConfig(level=logging.DEBUG) + log_root = logging.getLogger(__name__) + try: + for test_suite in cliargs: + if test_suite in suites: + runner = unittest.TextTestRunner(verbosity=2) + runner.run(suite(*suites[test_suite])) + else: + log_root.warning( + "Unknown suite: '{}'".format(test_suite)) + pass + except Exception as err: + log_root.error("Unecpected error: {}".format(err), + exc_info=True) + pass + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--list-suites', + action='store_true', + help='list possible test suites') + parser.add_argument('--run-suites', metavar='S', + nargs='+', action='store', + help='a list of valid test suites') + args = parser.parse_args() + + if args.list_suites: + list_suites() + + if args.run_suites: + start_tests(*args.run_suites) diff --git a/src/toolbox_scs/test/test_top_level.py b/src/toolbox_scs/test/test_top_level.py new file mode 100644 index 0000000000000000000000000000000000000000..9fd549609fdcc29fcefbfa97571a1988c5ffa269 --- /dev/null +++ b/src/toolbox_scs/test/test_top_level.py @@ -0,0 +1,150 @@ +import unittest +import logging +import os +import sys +import argparse + + +import toolbox_scs as tb +from toolbox_scs.util.exceptions import * +import extra_data as ed + + +logging.basicConfig(level=logging.DEBUG) +log_root = logging.getLogger(__name__) + + +suites = {"packaging": ( + "test_constant", + ), + "load": ( + "test_load", + "test_openrun", + "test_openrunpath", + "test_loadbinnedarray", + ) + } + + +class TestToolbox(unittest.TestCase): + @classmethod + def setUpClass(cls): + log_root.info("Start global setup") + cls._mnentry = 'SCS_RR_UTC/MDL/BUNCH_DECODER' + cls._ed_run = ed.open_run(2212, 235) + log_root.info("Finished global setup, start tests") + + @classmethod + def tearDownClass(cls): + pass + + def setUp(self): + pass + + def tearDown(self): + pass + + def test_constant(self): + cls = self.__class__ + self.assertEqual(tb.mnemonics['sase3']['source'],cls._mnentry) + + def test_load(self): + fields = ["SCS_XGM"] + + # normal behavior + run_tb = None + proposalNB = 2511 + runNB = 176 + run_tb = tb.load(fields, runNB, proposalNB, + validate=False, display=False) + self.assertEqual(run_tb['npulses_sase3'].values[0], 42) + + # exception raised + run_tb = None + proposalNB = 2511 + runNB = 1766 + with self.assertRaises(ToolBoxPathError) as cm: + run_tb = tb.load(fields, runNB, proposalNB, + validate=False, display=False) + tb_exception = cm.exception + constr_path = f'/gpfs/exfel/exp/SCS/202001/p002511/raw/r{runNB}' + exp_msg = f"Invalid path: {constr_path}. " + \ + "The constructed path does not exist." + self.assertEqual(tb_exception.message, exp_msg) + + def test_openrun(self): + run = tb.load_run(2212, 235) + src = 'SCS_DET_DSSC1M-1/DET/0CH0:xtdf' + self.assertTrue(src in run.all_sources) + + def test_openrunpath(self): + run = tb.run_by_path( + "/gpfs/exfel/exp/SCS/201901/p002212/raw/r0235") + src = 'SCS_DET_DSSC1M-1/DET/0CH0:xtdf' + self.assertTrue(src in run.all_sources) + + def test_loadbinnedarray(self): + cls = self.__class__ + + # Normal use + mnemonic = 'PP800_PhaseShifter' + data = tb.get_array(cls._ed_run, mnemonic, 0.5) + self.assertTrue = (data) + + # unknown mnemonic + mnemonic = 'blabla' + with self.assertRaises(ToolBoxValueError) as cm: + scan_variable = tb.get_array(cls._ed_run, mnemonic, 0.5) + excp = cm.exception + self.assertEqual(excp.value, mnemonic) + + +def list_suites(): + print("\nPossible test suites:\n" + "-" * 79) + for key in suites: + print(key) + print("-" * 79 + "\n") + + +def suite(*tests): + suite = unittest.TestSuite() + for test in tests: + suite.addTest(TestToolbox(test)) + return suite + + +def main(*cliargs): + try: + for test_suite in cliargs: + if test_suite in suites: + runner = unittest.TextTestRunner(verbosity=2) + runner.run(suite(*suites[test_suite])) + else: + log_root.warning( + "Unknown suite: '{}'".format(test_suite)) + pass + except Exception as err: + log_root.error("Unecpected error: {}".format(err), + exc_info=True) + pass + + + + + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--list-suites', + action='store_true', + help='list possible test suites') + parser.add_argument('--run-suites', metavar='S', + nargs='+', action='store', + help='a list of valid test suites') + args = parser.parse_args() + + if args.list_suites: + list_suites() + + if args.run_suites: + main(*args.run_suites) diff --git a/src/toolbox_scs/test/test_utils.py b/src/toolbox_scs/test/test_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..90bd14c1bdb500d2487eaae80cd680abccbd4ab1 --- /dev/null +++ b/src/toolbox_scs/test/test_utils.py @@ -0,0 +1,114 @@ +import unittest +import logging +import os +import sys +import argparse + + +from toolbox_scs.util.data_access import ( + find_run_dir, + ) +from toolbox_scs.util.exceptions import ToolBoxPathError + +suites = {"ed-extensions": ( + "test_rundir1", + "test_rundir2", + "test_rundir3", + ) + } + + +def list_suites(): + print("""\nPossible test suites:\n-------------------------""") + for key in suites: + print(key) + print("-------------------------\n") + + +class TestDataAccess(unittest.TestCase): + @classmethod + def setUpClass(cls): + pass + + @classmethod + def tearDownClass(cls): + pass + + def setUp(self): + pass + + def tearDown(self): + pass + + def test_rundir1(self): + Proposal = 2212 + Run = 235 + Dir = find_run_dir(Proposal, Run) + self.assertEqual(Dir, + "/gpfs/exfel/exp/SCS/201901/p002212/raw/r0235") + + def test_rundir2(self): + Proposal = 23678 + Run = 235 + with self.assertRaises(Exception) as cm: + find_run_dir(Proposal, Run) + exp = cm.exception + self.assertEqual(str(exp), "Couldn't find proposal dir for 'p023678'") + + def test_rundir3(self): + Proposal = 2212 + Run = 800 + with self.assertRaises(ToolBoxPathError) as cm: + find_run_dir(Proposal, Run) + exp_msg = cm.exception.message + print(exp_msg) + path = f'/gpfs/exfel/exp/SCS/201901/p00{Proposal}/raw/r0{Run}' + err_msg = f"Invalid path: {path}. " \ + "The constructed path does not exist." + self.assertEqual(exp_msg, err_msg) + + +def suite(*tests): + suite = unittest.TestSuite() + for test in tests: + suite.addTest(TestDataAccess(test)) + return suite + + +def main(*cliargs): + logging.basicConfig(level=logging.DEBUG) + log_root = logging.getLogger(__name__) + try: + for test_suite in cliargs: + if test_suite in suites: + runner = unittest.TextTestRunner(verbosity=2) + runner.run(suite(*suites[test_suite])) + else: + log_root.warning( + "Unknown suite: '{}'".format(test_suite)) + pass + except Exception as err: + log_root.error("Unecpected error: {}".format(err), + exc_info=True) + pass + + + + + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--list-suites', + action='store_true', + help='list possible test suites') + parser.add_argument('--run-suites', metavar='S', + nargs='+', action='store', + help='a list of valid test suites') + args = parser.parse_args() + + if args.list_suites: + list_suites() + + if args.run_suites: + main(*args.run_suites) diff --git a/src/toolbox_scs/util/__init__.py b/src/toolbox_scs/util/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/toolbox_scs/util/data_access.py b/src/toolbox_scs/util/data_access.py new file mode 100644 index 0000000000000000000000000000000000000000..1fe637f63eb5866d3e29a7c5666f03ae5daaed2e --- /dev/null +++ b/src/toolbox_scs/util/data_access.py @@ -0,0 +1,65 @@ +''' +Extensions to the extra_data package. + +contributions should comply with pep8 code structure guidelines. +''' + +import os +import logging + +import extra_data as ed +from extra_data.read_machinery import find_proposal + +from ..util.exceptions import ToolBoxPathError + +log = logging.getLogger(__name__) + +def find_run_dir(proposal, run): + """ + Get run directory for given run. + + This method is an extension to 'find_proposal' in the extra_data + package and should eventually be transferred to the latter. + + Parameters + ---------- + proposal: str, int + Proposal number + run: str, int + Run number + + Returns + ------- + rdir : str + Run directory as a string + + Raises + ------ + ToolBoxPathError: Exception + Error raised if the constructed path does not exist. This may + happen when entering a non-valid run number, or the folder has + been renamed/removed. + + Comment + ------- + The rather unspecified Exeption raised, when entering a invalid proposal + number stems from the ed package -> to be fixed externally. + + """ + rdir = None + + try: + pdir = find_proposal(f'p{proposal:06d}') + rdir = os.path.join(pdir, f'raw/r{run:04d}') + if os.path.isdir(rdir) is False: + log.warning("Invalid directory: raise ToolBoxPathError.") + msg = 'The constructed path does not exist.' + raise ToolBoxPathError(msg, rdir) + + except ToolBoxPathError: + raise + except Exception as err: + log.error("Unexpected error:", exc_info=True) + raise + + return rdir \ No newline at end of file diff --git a/src/toolbox_scs/util/exceptions.py b/src/toolbox_scs/util/exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..52aa3c55cf567aee1a22ddf30e433a0cc9052915 --- /dev/null +++ b/src/toolbox_scs/util/exceptions.py @@ -0,0 +1,29 @@ +class ToolBoxError(Exception): + """ + Parent Toolbox exception. (to be defined) + """ + pass + + +class ToolBoxPathError(ToolBoxError): + def __init__(self, message = "", path = ""): + self.path = path + self.message = f'Invalid path: {path}. ' + message + + +class ToolBoxTypeError(ToolBoxError): + def __init__(self, msg = "", dtype = ''): + self.dtype = dtype + self.message = "Unknown data type:Â " + dtype + " \n" + msg + + +class ToolBoxValueError(ToolBoxError): + def __init__(self, msg = "", val = None): + self.value = val + self.message = msg + " unknown value: " + str(val) + + +class ToolBoxFileError(ToolBoxError): + def __init__(self, msg = "", val = ''): + self.value = val + self.message = f"file: {val}, {msg}" \ No newline at end of file diff --git a/src/toolbox_scs/util/pkg.py b/src/toolbox_scs/util/pkg.py new file mode 100644 index 0000000000000000000000000000000000000000..cefb1a65acf8e459d6c6ee2fcfa4c7c6b9053170 --- /dev/null +++ b/src/toolbox_scs/util/pkg.py @@ -0,0 +1,5 @@ +import os + +def get_version(): + release_tag = os.popen('git describe --tags').read() + return release_tag.strip("\n") \ No newline at end of file