From fd1557e2d3e552afd1213f7e31a15e02f88d3f39 Mon Sep 17 00:00:00 2001 From: Igor Andriyash Date: Wed, 13 Sep 2023 13:38:21 +0200 Subject: [PATCH 01/12] adding some formulas in a readable way (#13) * Create main.md * Update main.md * Update main.md * Update main.md --- somedocs/main.md | 83 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 somedocs/main.md diff --git a/somedocs/main.md b/somedocs/main.md new file mode 100644 index 0000000..ef9698b --- /dev/null +++ b/somedocs/main.md @@ -0,0 +1,83 @@ +## Basic model + +For optical propagation we need to describe evolution of electromagnetic field from the state defined at some time and space region to the state that it has after some time and in a different space region. This computation follows from the Maxwell equations for electric and magnetic fields: + +$$ \nabla \times \mathbf{E} = - \partial_t \mathbf{B} $$ + +$$ \nabla \times \mathbf{B} = \frac{1}{c^2} \partial_t \mathbf{E} + \mu_0 \mathbf{J}$$ + +In most cases that concern laser pulse propagation, it is enough to describe electric components of the field, for which we can find the equation by combinng the above ones: + +$$ \nabla \times \nabla \times \mathbf{E} = \nabla (\nabla \mathbf{E}) - \nabla^2 \mathbf{E} = - \partial_t \left( \frac{1}{c^2} +\partial_t \mathbf{E} + \mu_0 \mathbf{J}\right) = - \frac{1}{c^2} \partial_t^2 \mathbf{E} - \mu_0 \partial_t\mathbf{J}$$ + +The term $\nabla (\nabla \mathbf{E})$ here describes contributions of charge density perturbations (plasma waves) which +we may neglect, and for the acccount of fast media resopnse we can use: + +$$ \nabla^2 \mathbf{E} = \frac{1}{c^2} \partial_t^2 \mathbf{E} + \mu_0 \partial_t\mathbf{J} $$ + +In the following we will always consider a scalar version of this equation meaning the component along the laser field polarisation. + +#### Vacuum case + +In a case when field propagates in vacuum, there is no current $J = 0$ and equation simplifies to + +$$ \nabla^2 E = \frac{1}{c^2} \partial_t^2 E $$ + +### Plasma dispersion + +Simplest plasma response can be described with help of non-relativistic motion equation: + +$$ \mu_0 \partial_t J = -e \mu_0 n_{pe} \partial_t v = \omega_{pe}^2 / c^2 E $$ + +where $\omega_{pe} = \sqrt{\frac{e^2 n_{pe} }{\epsilon_0 m_e}}$ is a plasma frequency. + +The resulting field equation is: + +$$ \nabla^2 E = \frac{1}{c^2} \partial_t^2 E + \frac{ \omega_{pe}^2 }{ c^2 } E $$ + +and its spatio-temporal Fourier transform leads to the basic dispersion relation + +$$ \omega^2 = k^2 c^2 + \omega_{pe}^2 $$ + +### Field representation + +#### Temporal representation + +We assumed the field propagation along z-axis is and the temporal representation. The later means that the full field $E(t,x,y,z)$ is considered at a fixed $z=z_0$, and is measured on a finite $(x,y)$-plane over a time interval $t\in[t_{min},t_{max}]$, so the input as $E_0 = E(t,x,y,z=z_0)$. + +The field equation can be written as following: + +$$ \partial_z^2 E = \frac{1}{c^2} \partial_t^2 E - \nabla_{\perp}^2 E + \mu_0 \partial_t J $$ + +#### Geometries + +Two main geometries are usually considered +- cartesian $(x, y, t)$, where transverse Laplace operator is $\nabla_\perp^2 = \partial_x^2 + \partial_y^2$ +- cylindrical $(r, \theta, t)$, where $\nabla_{\perp}^2 = r^{-1} \partial_r (r \partial_r) + r^{-2} \partial_\theta^2$. + +#### Enelope + +If one considers the field around its central frequency $\omega_0$ as: + +$$ E(t) = \mathrm{Re}[\hat{E}(t) \exp(- i \omega_0 t) ], $$ + +in many practical cases the complex function $\hat{E}(t)$ can be assumed to be much slower than the actual $E(t)$. This presentation called envelope is often preferrable for analysis, and is also used in `Lasy` + +## Propagation + +Propagation calculations in `axiprop` are realized with spectral transformations in time and transverse spatial domains. + +### Non-paraxial propagator + +#### 3D + +#### RZ + +### Fresnel propagator + +For a mode $k=2\pi / \lambda$ + +$$ E(x, y, k, z) = \cfrac{ \exp\left(i k z \left(1 + \frac{x^2+y^2}{2 z^2}\right) \right) }{i \lambda z} \int \int_{-\infty}^{\infty} +dx' dy' \left[E(x', y', k, z=0) \exp\left(\frac{i k}{2 z} \left(x'^2+y'^2\right) \right) \right] \exp\left(-\frac{i k}{z} +\left(xx'+yy'\right)\right) $$ From 98ad94e6f32a6289c366f01b3ad9757a2ed70acc Mon Sep 17 00:00:00 2001 From: Igor Andriyash Date: Wed, 13 Sep 2023 13:39:36 +0200 Subject: [PATCH 02/12] renamed the doc folder --- {somedocs => docs}/main.md | 0 {somedocs => docs}/propagatorDHT.ipynb | 0 {somedocs => docs}/propagatorDHT.slides.html | 0 {somedocs => docs}/slides_axibeam.ipynb | 0 {somedocs => docs}/slides_axibeam.slides.html | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename {somedocs => docs}/main.md (100%) rename {somedocs => docs}/propagatorDHT.ipynb (100%) rename {somedocs => docs}/propagatorDHT.slides.html (100%) rename {somedocs => docs}/slides_axibeam.ipynb (100%) rename {somedocs => docs}/slides_axibeam.slides.html (100%) diff --git a/somedocs/main.md b/docs/main.md similarity index 100% rename from somedocs/main.md rename to docs/main.md diff --git a/somedocs/propagatorDHT.ipynb b/docs/propagatorDHT.ipynb similarity index 100% rename from somedocs/propagatorDHT.ipynb rename to docs/propagatorDHT.ipynb diff --git a/somedocs/propagatorDHT.slides.html b/docs/propagatorDHT.slides.html similarity index 100% rename from somedocs/propagatorDHT.slides.html rename to docs/propagatorDHT.slides.html diff --git a/somedocs/slides_axibeam.ipynb b/docs/slides_axibeam.ipynb similarity index 100% rename from somedocs/slides_axibeam.ipynb rename to docs/slides_axibeam.ipynb diff --git a/somedocs/slides_axibeam.slides.html b/docs/slides_axibeam.slides.html similarity index 100% rename from somedocs/slides_axibeam.slides.html rename to docs/slides_axibeam.slides.html From 890c3527e98f01b8e5cdf2f0bb7d34c7a7f88b68 Mon Sep 17 00:00:00 2001 From: Igor Andriyash Date: Fri, 15 Sep 2023 16:08:03 +0200 Subject: [PATCH 03/12] cleaned up the old docs and removed output graphics in examples revised README, removed old code and graphics --- README.md | 90 +- docs/{main.md => main_equations.md} | 3 + docs/propagatorDHT.ipynb | 747 - docs/propagatorDHT.slides.html | 15135 --------------- docs/slides_axibeam.ipynb | 10882 ----------- docs/slides_axibeam.slides.html | 25380 -------------------------- examples/example.ipynb | 72 +- examples/example_figure.png | Bin 55126 -> 0 bytes examples/test2d.ipynb | 57 +- 9 files changed, 58 insertions(+), 52308 deletions(-) rename docs/{main.md => main_equations.md} (99%) delete mode 100644 docs/propagatorDHT.ipynb delete mode 100644 docs/propagatorDHT.slides.html delete mode 100644 docs/slides_axibeam.ipynb delete mode 100644 docs/slides_axibeam.slides.html delete mode 100644 examples/example_figure.png diff --git a/README.md b/README.md index 9e6394a..520af98 100644 --- a/README.md +++ b/README.md @@ -1,91 +1,63 @@ # Axiprop A simple tool to compute optical propagation, based on the discrete Hankel and -Fourier transforms +Fourier transforms. -### Contents +## Contents This library contains methods and convenience tools to model propagation of the 3D optical -field. Computations can be done using a number of backends: -- [NumPy](https://numpy.org) (**CPU**) optionally enhanced via [mkl_fft](https://github.com/IntelPython/mkl_fft) or -[pyfftw](https://github.com/pyFFTW/pyFFTW) -- [CuPy](https://cupy.dev) for **GPU** calculations via Nvidia CUDA API -- [ArrayFire](https://arrayfire.com) for **GPU** calculations via CUDA or OpenCL APIs -- [PyOpenCL](https://documen.tician.de/pyopencl) for **GPU** calculations via OpenCL API +field. -Currently methods include: +### Basic propagation methods include: - `PropagatorSymmetric`: cylindical axisymmetric propagator with the symmetric DHT proposed in [[M. Guizar-Sicairos, J.C. Gutiérrez-Vega, JOSAA 21, 53 (2004)](https://doi.org/10.1364/JOSAA.21.000053)] - `PropagatorResampling`: cylindical axisymmetric propagator with a more generic DHT which allows for arbitrary sampling of radial axis [[K. Oubrerie, I.A. Andriyash et al, J. Opt. 24, 045503 (2022)](https://doi.org/10.1088/2040-8986/ac57d2)] +- `PropagatorResamplingFresnel`: cylindical axisymmetric propagator based on the Fresnel approximation as given by `Eq. (4-17)` of [JW Goodman _Introduction to Fourier Optics_] and is suited for translations between far and near fields. - `PropagatorFFT2`: fully 3D FFT-based propagator +- `PropagatorFFT2Fresnel`: ully 3D FFT-based propagator based on the Fresnel approximation -### Usage - -Consider a laser, -```python -k0 = 2 * np.pi / 0.8e-6 # 800 nm wavelength -tau = 35e-15/ (2*np.log(2))**0.5 # 35 fs FWHM duration -R_las = 10e-3 # 10 mm radius - -def fu_laser(kz, r): - """ - Gaussian spot with the Gaussian temporal profile - """ - profile_r = np.exp( -(r/R_las)**2 ) - profile_kz = np.exp( -( (kz-k0) * c * tau / 2 )**2 ) - return profile_r * profile_kz -``` +### Propagation with plasma models: +- `Simulation` class includes a few algorithms (`'Euler'` `'Ralston'`, `'MP'`, `'RK4'`), method to provide adjustive steps, diagnostics +- Plasma models: `PlasmaSimple` (linear current, $n_{pe}(z)$ ), `PlasmaSimpleNonuniform` (linear current, $n_{pe}(z, r)$), `PlasmaRelativistic` (non-linear current, $n_{pe}(z, r)$), `PlasmaIonization` (non-linear current and ionization, $n_{g}(z, r)$) -and some focusing optics, -```python -f_N = 40 # f-number f/40 -f0 = 2 * R_las * f_N # focal length -``` +### Convenience tools include: +- Container classes to create and handle time-frequency transformations for the **carrier-frequency-resolved** and **enveloped** fields. +- Methods to convert fields between temporal and spatial representations -Define the propagator, -```python -prop = PropagatorSymmetric((Rmax, Nr), (k0, L_kz, Nkz), Nr_end) -``` -and setup the laser reflected from the focusing mirror -```python -A0 = laser_from_fu( fu_laser, prop.kz, prop.r ) -A0 = A0 * mirror_parabolic( f0, prop.kz, prop.r ) -``` +Computations can be done using a number of backends: +- [NumPy](https://numpy.org) (**CPU**) optionally enhanced via [mkl_fft](https://github.com/IntelPython/mkl_fft) or +[pyfftw](https://github.com/pyFFTW/pyFFTW) +- [CuPy](https://cupy.dev) for **GPU** calculations via Nvidia CUDA to be discontinuedI +- [PyOpenCL](https://documen.tician.de/pyopencl) for **GPU** calculations/OpenCL +- [ArrayFire](https://arrayfire.com) for **GPU** calculations via CUDA/OpenCL (to be discontinued) -Use `AXIPROP` to compute the field after propagation of `dz` distance -(e.g. `dz=f0` for field at focus): -```python -A0 = prop.step(A0, f0) -``` -or evaluate it at `Nsteps` along some `Distance` around the focus, -```python -dz = Distance / Nsteps -zsteps = Nsteps * [dz,] -zsteps[0] = f0 - Distance/2 -A_multi = prop.steps(A0, zsteps) -``` +## Documentation -Plot the results using your favorite tools +Documentation is organized in a few sections: -![example_image](https://github.com/hightower8083/axiprop/blob/main/examples/example_figure.png) + - [Equations of field propagation](./docs/main.md) -For more info checkout the example notebooks for [radial](https://github.com/hightower8083/axiprop/blob/main/examples/example.ipynb) and [cartesian](https://github.com/hightower8083/axiprop/blob/main/examples/test2d.ipynb) cases, and also look for methods documentation. -### Installation +## Installation +### From PyPI +Major versions are released at [PyPI](https://pypi.org) and can be installed with `pip`: +```bash +pip install axiprop +``` -Install `axiprop` by cloning the source +### From source +You can build and install `axiprop` by cloning the source ```bash git clone https://github.com/hightower8083/axiprop.git cd axiprop python setup.py install ``` -or directly via PiPy +or directly from Github with `pip`: ```bash pip install git+https://github.com/hightower8083/axiprop.git ``` -#### Additional requirements - +### Additional dependencies Note that, while base backend `NP` requires only NumPy and SciPy, other backends have specific dependencies: - `NP_MKL`: [mkl_fft](https://github.com/IntelPython/mkl_fft) diff --git a/docs/main.md b/docs/main_equations.md similarity index 99% rename from docs/main.md rename to docs/main_equations.md index ef9698b..d32edbc 100644 --- a/docs/main.md +++ b/docs/main_equations.md @@ -81,3 +81,6 @@ For a mode $k=2\pi / \lambda$ $$ E(x, y, k, z) = \cfrac{ \exp\left(i k z \left(1 + \frac{x^2+y^2}{2 z^2}\right) \right) }{i \lambda z} \int \int_{-\infty}^{\infty} dx' dy' \left[E(x', y', k, z=0) \exp\left(\frac{i k}{2 z} \left(x'^2+y'^2\right) \right) \right] \exp\left(-\frac{i k}{z} \left(xx'+yy'\right)\right) $$ + + +# [Return](./../README.md) diff --git a/docs/propagatorDHT.ipynb b/docs/propagatorDHT.ipynb deleted file mode 100644 index acbc3eb..0000000 --- a/docs/propagatorDHT.ipynb +++ /dev/null @@ -1,747 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "e8ddfa3e", - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "# Optical propagation with DHT\n", - "\n", - "_Igor A Andriyash_\n", - "\n", - "**Laboratoire d’Optique Appliquée**\n", - "\n", - "https://github.com/hightower8083/axiprop" - ] - }, - { - "cell_type": "markdown", - "id": "beb8fab7", - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "## Basics" - ] - }, - { - "cell_type": "markdown", - "id": "11d76d6e", - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "source": [ - "#### Wave equation for $A(x, y, z, t )$\n", - "\n", - "$$ \\frac{1}{c} \\; \\partial_t^2 A \\; - \\; \\nabla^2 A \\; = \\; 0$$" - ] - }, - { - "cell_type": "raw", - "id": "7fbe3355", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "source": [ - "### Decompose to a series of monochromatic waves\n", - "\n", - "$$ A(x, y, z, t) = Re \\left\\{ \\int_{-\\infty}^{\\infty}d\\omega \\; \\hat{A}(x, y, z, \\omega ) \\; e^{-\\mathrm{i} \\omega t} \\right\\} \\; = \\text{or actually}= \\; Re \\left\\{\\sum_{\\omega\\in \\{\\omega\\} } \\hat{A}_\\omega(x, y, z ) \\; e^{-\\mathrm{i} \\omega t} \\right\\} $$" - ] - }, - { - "cell_type": "markdown", - "id": "ae6a63dc", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "#### Decompose to a series of monochromatic waves\n", - "\n", - "$$ A(x, y, z, t) = \\; Re \\left\\{\\sum_{\\omega\\in \\{\\omega\\} } \\hat{A}_\\omega(x, y, z ) \\; e^{-\\mathrm{i} \\omega t} \\right\\} $$" - ] - }, - { - "cell_type": "markdown", - "id": "b4d6b13d", - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "source": [ - "\n", - "#### If $\\{\\omega\\}$ corresponds to the orthogonal modes $e^{-\\mathrm{i} \\omega t}$, we get independent equations for $\\hat{A}_\\omega(x, y, z )$\n", - "\n", - "$$ -k^2 \\; \\hat{A}_\\omega \\; - \\; \\nabla^2 \\hat{A}_\\omega \\; = \\; 0$$\n", - "where $k=\\omega/c$" - ] - }, - { - "cell_type": "markdown", - "id": "d40f605d", - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "source": [ - "#### Assume cylindric coordinates and decompose to azimuthal modes \n", - "\n", - "$$ \\hat{A}_\\omega(x, y, z ) = \\hat{A}_\\omega(r, \\theta, z ) = \\sum_{m\\in \\{m\\} } \\hat{A}_{\\omega,m}(r, z ) e^{-\\mathrm{i} m \\theta} $$" - ] - }, - { - "cell_type": "markdown", - "id": "f631d9ca", - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "source": [ - "\n", - "#### For integer $m$ we get equations $\\hat{A}_{\\omega,m}(r, z )$\n", - "\n", - "$$ \\; \\partial_z^2 \\hat{A}_{\\omega,m} + \\cfrac{1}{r} \\partial_r r \\partial_r\\hat{A}_{\\omega,m} - \\cfrac{m^2}{r^2} \\hat{A}_{\\omega,m} \\; = \\; -k^2 \\; \\hat{A}_{\\omega,m}$$" - ] - }, - { - "cell_type": "markdown", - "id": "07bb2d12", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "#### Decompose to Bessel functions\n", - "\n", - "$$ \\hat{A}_{\\omega,m}(r, z ) = \\sum_{k_r\\in \\{k_r^{(m)}\\}} \\hat{A}_{\\omega,m, k_r^{(m)}}(z) \\, J_m\\!\\! \\left(k_r^{(m)} r\\right) $$" - ] - }, - { - "cell_type": "markdown", - "id": "2b1b50f1", - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "source": [ - "\n", - "#### Assuming $J_m \\left(k_r^{(m)} r\\right)$ are orthogonal on the base $\\{k_r^{(m)}\\}$ and some interval $r\\in [0, R]$, we get equations for $\\hat{A}_{\\omega,m, k_r^{(m)}}(z)$\n", - "\n", - "$$ \\; \\partial_z^2 \\hat{A}_{\\omega,m, k_r^{(m)}} = \\; -( k^2 - k_r^2) \\; \\hat{A}_{\\omega,m, k_r^{(m)}} $$" - ] - }, - { - "cell_type": "markdown", - "id": "593eba7e", - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "source": [ - "#### For the initial value problem with a known $\\hat{A}_0 = \\hat{A}_{\\omega,m, k_r^{(m)}}(z=z_0)$ we get known the propagator solution:\n", - "\n", - "$$ \\hat{A}_{\\omega,m, k_r^{(m)}}(z) = \\hat{A}_0 \\, \\exp\\left(-\\mathrm{i}\\, (z-z_0)\\, \\sqrt{k^2 - k_r^2}\\right) $$" - ] - }, - { - "cell_type": "markdown", - "id": "4e878d77", - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "## Orthogonality of the transverse base functions" - ] - }, - { - "cell_type": "markdown", - "id": "dfacc702", - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "source": [ - "#### Want to use the decomposition (or backward DHT)\n", - "$$ \\hat{A}_{\\omega,m}(r, z ) = \\sum_{k_r\\in \\{k_r^{(m)}\\}} \\hat{A}_{\\omega,m, k_r^{(m)}}(z) \\, J_m\\!\\! \\left(k_r^{(m)} r\\right) $$\n", - "and see when it is legit.\n", - "\n", - "Consider integral of a decomposed function:\n", - "$$ \\int_0^R\\, r\\, dr\\, J_m\\!\\! \\left(k_r' r\\right) \\, \\hat{A}_{\\omega,m}(r, z) = \\sum_{k_r\\in \\{k_r\\}} \\hat{A}_{\\omega,m, k_r}(z) \\, \\int_0^R\\, r\\, dr\\, J_m\\!\\! \\left(k_r' r\\right) \\, J_m\\!\\! \\left(k_r r\\right)\n", - "$$\n", - "\n", - "For $\\alpha$ being roots of $J_m$, $ \\int_0^1\\, \\rho \\,d\\rho \\, J_m(\\alpha \\rho) J_m(\\alpha' \\rho) = \\cfrac{\\delta_{\\alpha, \\alpha'}}{2} [J_{m+1}(\\alpha)]^2$\n", - "so for $k_r = \\alpha/R$ this leads to\n", - "$$ \\int_0^R\\, r\\, dr\\, J_m\\!\\! \\left(k_r' r\\right) \\, \\hat{A}_{\\omega,m}(r, z) = \\cfrac{R^2}{2} \\, \\hat{A}_{\\omega,m, k_r'}(z) \\; \\; \\left[J_{m+1}(k_r' R)\\right]^2$$\n" - ] - }, - { - "cell_type": "markdown", - "id": "ddf59a5e", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "#### We find the forward transform:\n", - "$$ \\hat{A}_{\\omega,m, k_r}(z) = \\cfrac{2}{[R\\, J_{m+1}(k_r R)]^2} \\int_0^R\\, r\\, dr\\, J_m\\!\\! \\left(k_r r\\right) \\, \\hat{A}_{\\omega,m}(r, z)$$\n", - "\n", - "Corresponds to the (bounded) Hankel transform with normalization.\n", - "\n", - "#### We can use backward DHT matrix:\n", - "$$ M_{ij} = J_m\\!\\! \\left(\\alpha_j \\rho_i) \\right) $$\n", - "or a one with normalization (simillar to FBPIC)\n", - "$$ M_{ij} = \\cfrac{2 J_m\\!\\! \\left(\\alpha_j \\rho_i \\right) }{[\\, J_{m+1}(\\alpha_j)]^2} $$" - ] - }, - { - "cell_type": "markdown", - "id": "b580ab61", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "## Tuning DHT \n", - "\n", - "For a custom $r = R \\alpha/\\alpha_{N+1}$ a symmetric transform with $\\det(M)\\simeq 1$ can be developed (Guizar-Sicairos, Gutiérrez-Vega):\n", - "$$ M_{ij} = \\cfrac{2\\, J_m(\\alpha_i \\alpha_j / \\alpha_{N+1})} { \\alpha_{N+1} |J_{m+1}(\\alpha_i)| \\;| J_{m+1}(\\alpha_j)|}$$\n", - "\n", - "#### Ideally we should be free in choice of $r$-grid\n", - "Will consider an axis $r_j = R \\, (d + j) \\,/\\, N_r$, for $j = 0, 1, ..., N_r-1$, with a _tuning_ coefficient $d\\in[0,1]$\n", - "(One metrics of transform consistensy is $\\det(M)$ -- closer to 1 is better)" - ] - }, - { - "cell_type": "markdown", - "id": "61a6c01a", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "Lets test differential property of m=0 DHT:\n", - "\n", - "$$ d_r A = iDHT^{(1)}[\\, -\\alpha^{(0)} DHT^{(0)}[A] \\, ] $$\n", - "\n", - "Consider a signal sampled with $N_r = 512$:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "3e8a358c", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "outputs": [], - "source": [ - "%matplotlib inline\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import scipy.constants as scc\n", - "import scipy.special as scf\n", - "\n", - "d_ax = np.r_[0:1:64j][:-1]\n", - "m = 0" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "c40a6a44", - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA04AAAFiCAYAAADBUYjlAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAABJ0AAASdAHeZh94AACQHklEQVR4nO2dd5hc5Xn27zMzu7NltmibpFUXQhJWpUqYIlOEwSGmGccYF4r92RCDHfsDJ3GMwSXGiR2bJJAv2AYpli3HNJMCxCAQGGG6CRIgoYYk1LZrZ2d3p57vj5n3zHt2Z3ZOec+Z1er+XRcX2qnvzpyZfe9zP8/9aLqu6yCEEEIIIYQQUpRAuRdACCGEEEIIIeMdCidCCCGEEEIIKQGFEyGEEEIIIYSUgMKJEEIIIYQQQkpA4UQIIYQQQgghJaBwIoQQQgghhJASUDgRQgghhBBCSAkonAghhBBCCCGkBBROhBBCCCGEEFKCULkXcKzQ19eHZ599FjNmzEA4HC73cgghhBBCCDmmicfj2LdvH1atWoXGxsaSt6dw8olnn30Wl156abmXQQghhBBCCJH47W9/i0suuaTk7SicfGLGjBkAsm/MvHnzyrwaQgghhBBCjm127NiBSy+91Ninl4LCySdEed68efOwaNGiMq+GEEIIIYQQAsByGw3DIQghhBBCCCGkBBROhBBCCCGEEFICCidCCCGEEEIIKQGFEyGEEEIIIYSUgMKJEEIIIYQQQkowoYVTNBrFrbfeigsuuACtra3QNA2333675ft3dHTgmmuuQUtLC2pqanD66adjw4YN3i2YEEIIIYQQMi6Z0MKpu7sb9957L+LxuO3hs/F4HOeddx42bNiAu+66C48++igmT56MCy+8EM8++6w3CyaEEEIIIYSMSyb0HKdZs2aht7cXmqahq6sLP/vZzyzf9+c//zm2bNmCF154AaeffjoA4JxzzsGyZctw66234qWXXvJq2YQQQgghhJBxxoR2nDRNg6Zpju77yCOPYMGCBYZoAoBQKIRPfepTePnll7F//35VyySEEHIUoes6emIJ6Lpe7qUQQgjxkQntOLlhy5YtOOuss0ZdvnTpUgDAW2+9hWnTphW8b0dHBzo7O02X7dixQ/0iCSHkGCKT0aFpcHxCTBX/8OS7+Kend+DL5x2Pv1g9v6xr0XUdug4EAuV9TQgh5FiAwqkI3d3daGpqGnW5uKy7u7vofe+55x7ccccdnq2NEEKONeKpNC67+wUcPDKE686Yg8+fPRdVFUHf1zGUSOO+53cDAO57fjdu+NBxZVnHcDKNe5/bhfs27cb0SdV4+IYzUBma0EUkhBBSdiicxmCss5pjXXfjjTfiyiuvNF22Y8cO2wEVhBBCsry2pxdvH+wHAPzoyXfRP5zEN/7kA76v4+mtHYgl0gCAaDyFjds6cOHiqb6v4++e2Ib7NmUFXN9gEn/c24sVc5t9XwchhBxLUDgVobm5uaCr1NPTAwAF3ShBW1sb2traPFsbIYQca7x9oN/082t7esuyjkff2D/i5wNlEU6v7TX//m8d6KdwIoQQj6GvX4QlS5Zg8+bNoy4Xly1evNjvJRFCyDHLlv1HTD9v7xjwPZxhKJHGxm3Z/lVRdLBhaweGk2lf16HrOnZ2DJgu23LgSJFbE0IIUQWFUxEuu+wybN261RQ7nkqlsG7dOqxYsQLt7e1lXB0hhBxbbBnhOEWHU+iMxn1dw77eQSTSGQDAmfNaAACJVAb7+4Z8Xceh/mEMxFOmy97a31/k1oQQQlQx4YXT448/jgcffBD/+Z//CQB4++238eCDD+LBBx/E4OAgAOD6669HKBTCnj17jPtdd911WLRoEa688kr86le/wlNPPYWPf/zj2LZtG37wgx+U5XchhJBjkcFECjs7sw7LsukNxuXbR7guXrO/Ny+QVkplcfLlfrD9cP73Xpp7PXZ0DvjufBFCyLHGhO9xuuGGG0yC6IEHHsADDzwAANi9ezdmz56NdDqNdDptKvsIh8PYsGEDbr31Vtx0000YHBzE8uXL8fjjj2PVqlW+/x6EEFJOnt56GJqm4ZwF/vdvvnMwCvH1fMnyafjf97NlaTs6BnBGzvnxA9lZOnV2vs/1gM+OkywYL1k+DW++fwTpjI6th6JYPqPR17UAwDNbOwAA5yxkby8hZGIz4R2n9957LzfnYvR/s2fPBgCsWbPG9LNg8uTJWLt2Lbq7uzE0NIQ//OEPOP/88/3/JQghpIxs3NaB69a8iuvWvILN7/vfS/OW1L9z/gmTUVuZjf/e3hH1dR1COAUDGpZOb4AYneR3qd6OnHCqqwrhXEmsjOwD84M39vXh2jWv4No1r+D57V2+Pz8hhPjJhBdOhBBCnKPrOr79n2/n/g3815sHfF/D3u5sWXVlKIAZTdWYN7kOQF5A+IVwlqbUV6GqIojJ9VUAyiGcsoLx+LYIZjXVoCKYVXD7egd9XQcA/Of/5o+H7/zX274HdhBCiJ9QOBFCCCnKph3d2NUVM35+9t1O39fQOZANgWirC0PTNMxrjQDwXziJXqZpjdUAgPbc/33vccr93vPaIggENLREwgDge1gGYD4eth2O4sVdPb6vgRBC/ILCiRBCSFH+e/NB089bD0Xxvs/OhhAEbXVZgTCruQYA0DWQQDzlXyCCcJymTcoKJiGgDhzxTzgNJlLoG0wCAGY11wLIvy5+C6c93bFR4vW/N/vvSBJCiF9QOBFCCCnKezm3qTKY/3Ox4Z0OX9fQkRMErTmBIBwWAOiJJXxZQzKdwaH+YQBAe2NV7v9Z4XSwbxjpjD8lat0D+d+3JVIJIP+6+C2c5ONAHB/vdflfLkgIIX5B4UQIIaQoe3uyG+ELF0/BpJoKAOawBj/IO05ZwdKcEwwA0BX1Rzgd7h+G0EbTGrOOl3CeUhndN9HSNZB/HiEgW3Ovi9/C6a3cbK2WSCVWL5oMANjTExvrLoQQclRD4UQIIaQg8VTaKEOb3VyDmU1ZwXDwyLCvazgylC1NK+Q4dcX8EQtyH5NwnKbl/g8A+/v8cVpkx6nZEE7Z//cMJpDMDej1A1G6OKOpBrNz5ZP7e4eQSPm3BkII8RMKJ0IIIQXZ1zNkzE+a2VybD0PwMUVOdlHywkl2nPwRTnIf03Sjx6nGuOx9nwIiZMepudZcqqfrZmHlNeI1aW+sxqymbL9VRvc/ZZAQQvyCwokQQkhB9kplV7OaazC1Id/T41fstCyc2go4Tt0+9TiZBVyVaT1ANqjCD+TfV7wO8jr8KtfLZHTDeWxvqMLM5ryI3NPNcj1CyMSEwokQQkhB9nTny89mNdcYJWpDybSR7OY1HQUcp5rKIKoqsn++ugf8EQq9ud83GNBQXxUCANRXV0DLDcHtG/RHOAnHqbYyiOrcIOBWSTh1RP0po+yOJYySvPbGaiPpEMj3xRFCyESDwokQQkhBhHCqqQyiNRI24rcB/8qxzI5TVrhpmobm2qxY8MvpEcKosboCWk4tBQMaGqqzgRm9vgmn7PO0SGKpHI7TgT6556sak+uqUBnKbilkwU0IIRMJCidCCCEFESVXM5tqoGma0eMEmDfOXiILATlNTwiHLr8cp1jWcWrMJQsKJtVk19TrkwMnHDbR3wSYSxfLIZymNVYjENCM8BCW6hFCJioUToQQQgqyJ1dyJTbE5RBOolSvqbYSFdIsqZaccPDLcRKOkhBKAiGk/C7Vk8VSVUXQKB/s8Ek47R/hOAHALEM40XEihExMKJwIIYQU5HCu+V/MK2qurTQGnR7wKZI8P8MpbLpcuE9+9TiJnq7GEcLJcJxifjlOWYHWHDG/Hm31/s5yOtCXff/DoYAx30scJ2JQMCGETDQonAghhIxiOJlGLJEGkHc3AgENU3MBEb71OOWEUesI4STW1BNLIJPxPuEv7ziZS/X8dJzSGR09uedpjZgFXGvu9fArHEI4jtMaq42eL9F3Fh1OcZYTIWRCQuFECCFkFHLsdZPUT9NuRJL7I5x6Y4VL5ITjksroxoBcr9B13XCc5NcCAJp87HHqiSWMuVojHaemnJDyK+3woDTDaeQagOxaCSFkokHhRAghZBQ9Uu+QHEQgHKeDPpXqCVEk0usE8hDc7pi35WmDiTQS6ayDMqpUL/faDCXTGE6mPV2H/Hs2j3Cc6quyr4/XIlIgSjWnNlQZl7XU+veeEEJIOaBwIoQQMopim3QhovxwFDIZHdHhYsJJTpLzdi1y1HixUj3Ae7enKzp6+K1AvD79w0nPhxPrum44gbLLJLtxdJwIIRMRCidCCCGj6B6QS/Xym3ThsMRTGQwlvHVYBhIpiPalkcJJLt3zeoaSLIiKhUMA3osF+fccWTIoXp9kWseQx87XQDyFVO6NaZJ+/2aW6hFCJjgUToQQQkYhb3zlDbGfguWIJFhGCqcGyekRrpRXWHecvH09+ofHeD2kn70u15OFpHw8NEsC26+YeEII8RMKJ0IIIaMQ4RAVQQ114ZBxuSwcPBdOkgCoHyEUxNwiAOgfSnm6Djn4YVJtccfJ64AI+fcUPU0CP4WT/L7LwrGhugLBQDZhr4c9ToSQCQiFEyGEkFGI+UhNtZVG3DRgLlXzenZRv0k4hUzX1VaGkNujm5wYL+grIhQAfx048XtWBDVUVZj/fJuEk8cCrpiQDAQ0Q1izVI8QMhGhcCKEEDIKsfGVy6+A8ggFYHRpWiCgoS7nuvR77bBIArGx2uw4+Vqql/s966sqTGIW8NlxihUvXRTHC0v1CCETEQonQggho+gSwikysjTNP6EgC4CRwgnIu1D9w16X6mV/z0g4hMqQ+c9mVUUQ1RXB3O08duByv+fIssXsZXlHzt9SvRFzrXxMXSSEEL+hcCKEEDIK0aMyMr2t0ceenpLCySfHSQjEkWV6AiEmPXfgDMcpNOo6f3ucZAfO/JqIeHIKJ0LIRITCiRBCyCjEANyRpXqVoQAiubAIv8IhAhqM55QxhJPnqXrZx580wl0RCDHp9Rwn8XsWcpzqpLAIrx04ISTrq0IIBc3bCDEEV/TIEULIRGL0XyJCCCHjgs5oHL96aS/CFQGsmt+KE6bW+/K8w8k0YrkZTSNL9YCs8zIQT5l6XbxACKf66tE9PdnLc6V6HqfqRQ3BUvhPprjc61h04TjVFXCcggENdVUhRIdT3vd8CSFZO/rYEDO/+odTSKQyo0obveLtA/14bnsn4skMrl45c9SAYEIIUQGFEyGEjFP+9rF38Mgf9wMAfvLUu3j+6+f6siHsjhUftApknZf3e4d8KNXLCqJCZXqAf45TNOfg1IULr0O4PVGPnR6jx6mq8DoaqisQHU75MMdJlC4WEE4Rc3jI5PoqT9cCZE8wXHbPJsRTGQDA3p5B/Ojjyzx/XkLIsQdL9QghZByi6zqefbfT+Hk4mcHLu3t8ee4eKRGtuYBwEr0+fqXIFRVO1f70OA3Es4IlUsDpAWDMufJcOA0VL9UD8q+TX+EQIxP1gHypHgB0+VSu9+KubkM0AcBz2zuh67ovz00IObagcCKEkHHI9o6BUQ32r77X68tz9w0VT00D8r0+foVDlHKcYok0UulMwduowHCcigmnKu9L9eKptCEOCoVDAD4Kp1jxni/5ePF6HYLX9pg/F53ROHZ1xXx5bkLIsQWFEyGEjENe3NVt/Fs4Gq/t9Uc4yT1DhUSLKN/zLUWuqOOUFxBeuT2ZjG44TnUFAiqAvBM1EE955nTIv9/4cZxGCyf5PfG690wghJP8/sifH0IIUQWFEyGEjEPExq8lUokrT5kBAHhr/xEMJ9OeP7fcM1QoEEGU6kWHU0h66PRYdZwA7/qcBhL5zX9dkd4icXlGBwYT3rw/cjlisR4ncbmXwimeShu/Y6FSPT/eE5nBRApvH+wHAPzZqTMMUf/iLn/KWgkhxxYUToQQMs7QdR0v5TZ+K+Y249TZkwAAqYyON98/4vnzl9qky06DVxHcuq7nU/WKCQVJUHnlbgxITk+xHic5Kl24U6rpNzlORUr1arwXTvL73Vig/838nngvnP533xGkM1mX75TZTVgxpwkAHSdCiDdQOBFCyDijbzBpJNstm96Ak2ZNMq57Y5/35XrCKQgGNNRUBkddLw+C9SogYjCRRiq3IS7uOEllYR65G3KJXKkep+ztvVmHFcdJvE6JVMYzZ1IuzyzkONWFQxDJ8V7PkwKAN/b1Gf8+edYkLJvRCCDb5+RXjxUh5NiBwokQQsYZ+3oHjX/PbKrB5PoqY3P+fu+Q588v3Jv6qlDB+UlyAECfR5tTWQiVStUDvHM3BuL5xy00hBcYKZy8cpzk8snyvR4mx6l6tOMUCGjG6+SH4yQ+K401FWitC2PGpJr8dT2Dxe5GCCGOoHAihJBxxr6evDiantsITmusBgAc6PNBOA2PHcogC4UBj4SCFafHJBR8cZzG7nEaeXuVyKWIxXucZAfO+9LFou+LmK/lg3ASn4f2huznY0ZTtXHd+70UToQQtVA4EULIOEN2nGY0ZYVTe0447e8b9vz5+0v1FvlcIlest8i0Do96nKwIOH96nMYO7PBrHVHJgSv2egiH0I9wCEM45T4fZsfJ+5MMhJBjCwonQggZZ4gSo/qqkLEJbW+sAuCX45Qr1SuyQffDYYlJG/9iMeC1lSEEjH4ar0r1xlePUyigobpidN8ZYBZOMa+EkwUHThw3XseR67qO/bnS1Wm5z0djTYXxOuyj40QIUQyFEyGEjDP25TaDwm0C8mfUjwwlPXMTBKUcJ3mD7pVwkn/H2iLCKRDQjM27V2VhshAq2uMU9qFUTyqfLNR3BphfJ6/WYamEssofx6l/OIVYLhpdfD40TcP0Sdl/s8eJEKIaCidCCBlnvJ/b8MllR6LHCQAOeuw6GZv0IsKppjKIYM7qkcMTVCILp2KCBchv3r3u6dG0rMNVCLmU0LNSvZx7U0ysAP46ThVBDeFQ4S2E6D3zusdJdl/bpc+HOOGwz4cgFULIsQWFEyGEjCMyGd1IzpMb3eWN4X6vhdPQ2KV6mpZPTvPMcRq2JpzEdV7PT4pUhhAIFHZ65Nh2r0sXi4k3wB8BJxy4uqrizlfecfLWGS0mnITj9H7vIHRd93QNhJBjCwonQggZR3RE40ikMwAKl+oBwAEPAyISqQyGcjOAijlOQN758KPHqVipnnydVw6LECBjOT3y9V6lDIp1WBGR8u1VI97vsV4PIbgH4imkcseyF8jCSXZkhVM7nMygcyDu2fMTQo49KJwIIWQcYUrUk0r1JteFjSAELwMirMwLAvLBAF6FIYiNf2UogMoiJWGA98JJ/H7Fkv0EhgPnUeliLJFznMKFgyEAIBwKIGSUUHrtOI0hnCTB7WU/nkiYDAU0tNaFjcvlEw5M1iOEqITCiRBCxhGms+iT8mfRQ8EAptR7n6wn96UUK9UD8kl3XodDFEvUE0RyQsKrDXrecSouIuXrvXPgsi7gWO6bpmm+OXBjOV/mQbzeCSfxOZjSUGX03AH5Uj35NoQQogIKJ0IIGUd0RvOlRW3SWXQgX673vqeOU+lBq4D3pXpigz6WUADyPT9CWKhG/H5jCQXAv9ej1DqMni+PU/XGEpJ+zPkCRs9wEsjuUxdL9QghCqFwIoSQcUTXQAJANrWsYUSp3OSc49QV9W4zKDtOI59fxhAKXpWmWRQKnjssFnp65Ou9cr5iFoWk12EZ1nqc8sfNEQ+T9UT/kvhcCCbVVBplrRROhBCVUDgRQsg4QjhOLZHwqNSyptpKAEB3LOHZ89vvcRofDksskfIkQa3fgsMir8OLnq9MRsdgbl5RydejKv96eEGpqPqR13kZSd6TO8nQnPtcCIIBDc2RrOvU6eFJBkLIsQeFEyGEjCPEGfKWSHjUdUI4HRlKIulRWpnckzLW5jgipch5IVgM4VTC6REOTEaHkQaodh2lwxCy12dfKy9K5GQRZNWB82Iduq5b7HHyvlQvnkojmltL0wjhBOQ/P8LBJYQQFVA4EULIOEKcIW+tGy2cmiP5DWLvoDcbQrPjVHrwbCqjYzipXsRZCUMA8uEQgPrytGQ6Y/xupUMqhNOTRjqjVkjK/VulXo86D0v1Yok0hEa2WqrnVThEbyx/nBYSTuLzw1I9QohKKJwIIWQckXecRm8G5Q1ij0fleqK0KhTQUF1RPPpaLl3zojzNaiiDLCRUB0TIfVM1FsMhAPWiZcA006r4eyJf74Vwkt/nsUoXI5Uho8fIqx6n7lheEI0s1QPynx+W6hFCVELhRAgh44RMRjf6lwqW6tV4L5zkErmRPVYy5uQ0D9wNoySslFCQhZPadYi+IgCorbS+jkHF/UXy72U9LEN92aLczzaW4xQI5GPRvQqpkI//go5TJO84eVFKSgg5NpnQwmlgYABf+cpX0N7ejqqqKixfvhy//vWvS95vzZo10DSt4H+HDh3yYeWEkGOR3sGEUeZVqFSvKeKfcBIx38Xw0mFJpTNGv1IkbC2UwYt1yAKolONUIwkrL50vO6V6GcUlg1aF08h1eIF8/DcXcGfF5yeZ1j1N9iOEHFuM/c13lHP55ZfjlVdewZ133on58+fjV7/6Fa666ipkMhl88pOfLHn/+++/HwsXLjRd1tzc7NVyCSHHOHIj+1jhEIB3wikfez22wyILGtWlejHZ6RknjlPNGGWLgFloqnacBhw4TgAwmEyXvL0dzKV6FtL9jng3T6p7QHacRn9W5M9P10AcjTWjxRUhhNhlwgqnxx57DE8++aQhlgDgnHPOwZ49e3DLLbfgz/7szxAMjv2HcPHixTjllFP8WC4hhJj6MQo5TpOkzV+3R2lhQiyUdDakjbPqSHJZKJTcoHsYDiE7RzUlBJx8vXLHKWHdcZJTCAeGU4qFk/y+jO0E+lWqF9CAxgKx+fLnpzOawLw2T5ZBCDnGmLCleo888ggikQiuvPJK0+XXXnstDhw4gJdeeqlMKyOEkMLICWCFHKeKYMAYSut5j5Mt4aTYcbJRmuZlOMRQUirVK1G6GPHQ+RqIW3fgvCxdtFOq5/UgXtELOKmmEoHA6F48+fPTyWQ9QogiJqxw2rJlC0444QSEQuYv96VLlxrXl+Liiy9GMBhEU1MTLr/8ckv3AYCOjg689dZbpv927Nhh/5cghBxTlHKcgHyCmNelejUlwhDMqXrebdDtpep55ziVCoeQhZXq4bN2wiG8FU7WUvXkdXjnOGU/K4WCIQDz56eLyXqEEEVM2FK97u5uzJ07d9TlTU1NxvXFmDJlCr7xjW9g5cqVqK+vx+bNm3HnnXdi5cqV2LRpE5YtWzbmc99zzz2444473P0ChJBjDuE4VQYDptQ6mabaSuzqipnimFVifX6Sd6V6tlLkJMESVbxJH5J6nKpLpurlr5d7o1Qg+oQCGsaMiM+uw0vnK/t4mlZaSBpzrTwu1SsmnBqrKxAMaEhndM5yIoQoY8IKJwBjRumOdd2FF16ICy+80Pj57LPPxp/8yZ9gyZIluO222/Doo4+O+bw33njjqBLBHTt24NJLL7W2cELIMUmnNMOp2HdUk9eOU8JaqV4woKG2MohYIu3p3KJIiZKwYG7e1FAyrd5xknuLSpTqmRwnj16P2sqxI+IBbwWtMVvLwjqMHievwiFyx3+hRD0gG4neXFuJjmics5wIIcqYsMKpubm5oKvU09MDIO88WWX27Nk488wz8eKLL5a8bVtbG9ra2IlKCLFH32C2FGpSkbPoQH6j6H2pXuk/DzXhEGIJ9YLFNPDVwjpqwyFPhNOgHcfJhzjyUi4g4G2v1ZDF4BAg3wM1kEhB1/WSQssupRwncV1HNI7eQW8+K4SQY48J2+O0ZMkSvPPOO0ilzH84Nm/eDCCbmGcXXdcRCEzYl4wQUmb6chu8xpri/SNio9g7mFQ+pyeRyiCZzj5mqcGz2dvkyrE8Kk0DSocQZNeRXatXc5yCAQ3h0Njf/aFgwLiN8gG4CWsR8cCIVD2PHLhSCYNAXlzpuvrSxVQ6Y8xmKhRFLhAplL2DnONECFHDhFUBl112GQYGBvDQQw+ZLl+7di3a29uxYsUKW4+3e/dubNq0CStXrlS5TEIIMRCbwYYC8coCsVFMZ3T0lzHNLnub4Kj7qcA0eNai4+TNOrIb/pqKoCXHxKsIbpGqZyVa3NuBwLnXo4T7NnIdqt+XvqEk9Nw5g+YSjhMAOk6EEGVM2FK9iy66CKtXr8YNN9yA/v5+zJs3D+vXr8cTTzyBdevWGTOcrr/+eqxduxY7d+7ErFmzAADnn38+zj77bCxdutQIh/i7v/s7aJqG73znO+X8tQghE5i8cBprM5gXVT2xhNLBnnZL5ISoUe9sZDfoFUENlSWcHkAWTmqdjcHc45Uq08uvI4iemHqHxU6pXjgUgKZlnZ4hj9ZhRcyaeq3iKagsXu+ThNBY7qy4ro+OEyFEERNWOAHAww8/jG984xu47bbb0NPTg4ULF2L9+vX4xCc+YdwmnU4jnU5D1/MlL0uWLMG///u/44c//CGGhobQ1taGc889F9/85jcxf/78cvwqhJAJjq7rlhyneikGul9x47284bfTT6O6NG3IcDas/YnyKvp6MGm9pwfIi031sejWhZOmaaitDGEgnlIu4IzhyDYdJ9UBEeJzAoz9WRGlen2DCWQyesF5T4QQYocJLZwikQjuuusu3HXXXUVvs2bNGqxZs8Z02Y9//GOPV0YIIWYGE2mjv2iss+jyRlHeQKpAFh5W+lhEyZZXYQhWSsIAyXFSLuCyj1cqAlwg1qs8jtziUGJBdWUwJ5y86nGyXj4JqBeSVoWT+BxldKB/OKnUnSWEHJtM2B4nQgg5mpA3g41jbAa9FE525ifJt1HeW5S0VyIX8ajXKj/Typ6AU166GLceDgF4J+BE6aIVx0kO9VA9X8uqcJIT9xgQQQhRAYUTIYSMA+Q+jLE2g/J1/YqF06CNuUVAvpROuXCS5hZZodajXqu8gLO3DvVOj72SwRqP1iEez05gB6D++Ogfyj9evYVSPYABEYQQNVA4EULIOKBvKL+xaxijVK/e01I9ucfJSh9LzulJpJVGowunxKrjJErHhpMZteswBJzVdagvXUylM0ikMrl1WBVO6h0nXdfzPU42ouoB9YLWbqkeAPR6NPeMEHJsQeFECCHjgH6Lm8GqiqCRNKfacbIfR56/zVBS3SbdTggBYO6F8mIdllP1KtX3Wg1Kv4/Vni+j90yhcEqkM0jlRKndVD2vhFNNZRAVweLbGLPjxFI9Qoh7KJwIIWQcIJfqlWpiF8JKeY9Twl6PU41H5Vh2SsKyt8sLCpUui1iHZacn58QMKnSc5Ehxyw5c7nZDKgVc3J6Aq6oIIJhLsfMqVW+sEwwAMEnqcepjqR4hRAEUToQQMg6wGg4B5DeMXg3ADWjZeUCliEglWyrdDTuDVgFz6p3K2UV21xHJCayEVF6nag121pGPRVf3WsRs9r9pmuZZTLxwWuVo/kLUV4UM8cYeJ0KICiicCCFkHNCX2wyGAlrJDbJnjlM8H0KgaaVn3siOkFrHyZ5gMQURKHJZ0hkd8Zz4sex8yaWLigSc/LpaXYdwprwoWwSsRdUD3s3Xsuo4aZpmnIToibFUjxDiHgonQggpwPqX9+KD39+A2//jLeUCpRCiVK+xpqKkaKnPRT17FUdudV6QV30sgzbmBQHmEjZVpXpyIp11pyd/uwFFAm7IQY9TrQcx8ab+N7uDiT0q1RsrUU8gAiL8KNU7MpjEbY9uwQe/vwH//spez5+PEOI/FE6EEDKCdw9HcdujW3DgyDDWvPAePnHvi0il1ZReFaPfxmbQ6x4nJ06PqujrRCpjDAKusTp41oNSvUEnvUXy66FItDgp1ROli/FUBmlFKYOOSgaN1EVvSvVKOU5AfpaT16V6iVQGH//XP+Df/rAHB44M45u/fQs7OqKePichxH8onAghRELXdfzVw5uNzTsAvHOwHy/s7Pb0eUUcean+JkDqcRpSuyEVceRWHSeTw6Kon2bIVBJmcR0elOrJQsHq4Fkver4GHZTqyetVJWjNr4dFxynXg6TacerPPV59del1iKCVPo9T9Tbt6MK2w3mhlEhn8NcPb4Guq4vHJ4SUHwonQgiReOdgFK/t6QUAfPyU6ajMxR3/5/8e8PR5rfZtyLfpH056M7fIiWBR5bAk7ZfIyY6QF71F1RX2Bs+OvL8bHDlOlep7rWQBZtWBE0IyqrBkMJXOGGWhVj4rk2pEj5O3jpP4fgiHAvj4KdMBAC+/14N3Dw94+ryEEH+hcCKEEIlntnUY//7SOcfjQwtaAQBPvHUI8ZS6ZvuR5Hucxo4iB/LlfLqudlMqNqSWnQ0PhELMZuz1yNup6nGSe4usOk5evB7yHCfr86TUO1/y+2K1x0ncTmU8e7/kXlkTTnnHySv3ZziZxu/ePgwAOO+ENtzwoXnGdRul7xNCyNEPhRMhhEg8u60TADC3tRYzm2vwp8vaAQDR4RSe397l2fPacZzkPiiVQ3CF6IhYFApyupqq6GtTqZ7lOU7qe62cOD2m10PVOhyEMpiFpKrXQ3ICrQpJD0Iq5L6+UnHkANCQc5wS6QyGk970KT73bqdx0uFPl7ZjTkstZjXXADCfiCGEHP1QOBFCSI4jQ0m8tjdbpveh+W0AgHMWtkGE3P1xb58nz5tKZxAdtl5+JN9GZUCE2OBa7S2qCAZQmZv3pGqDbp4XVD7HyVFvkUnAeRBSYTUsw4NSPZMTaHEdcjiEKrdHPlFg5bPSWJ13cL1Kx/zjvj4AQDCgYVXOof7Q/Oz/X32vF1HF89YIIeWDwokQQnJs2tFlpJCdszC78YmEQ5jTUgsA2HLgiCfPK5cfifjksWjwyHEasBlHLt9WVRz5kIM0u4pgABXBrLr1QrCUs9dKlAxWVQQQCJSerQWY16sspCInaMOhAEJBa1sHIeAyOoyZWG6RxU+Dzc+KCGBRzZb92e+F41prjd/5QwuzJ15SGR2bdngbLEMI8Q8KJ0IIyfFG7sxxKKDh1NlNxuWL2xsAAG8d6PfkeY/YPIsulyipOoueSmeMza3VkjBAchVU9TjJjpMNASfcmCEvStMclcipFSxW1zDytqpeD/G+2HlPvJjzZfezIp+IOOJBsp6u63g7970gvicAYOWcZgRzQld8rxBCjn4onAghJMfm97NnjudPrkOVVI60qL0eANAZjaMjOqz8eeXhnJYcpxr1winmIH4byIssdc6G/dI0QOqnKaPj5InzlSuRs7qGkbdV1Xsmfh+n61AVEGG7x8nkOKkXTof74+jOJfZ9IPc9AWTdx3mtEQB5R4oQcvRD4UQIIcieORaleEumNZiuWySdSfbCdTKfRS+dqmcq1VPUPyE7RnZcBdUBAIMO1yHK5JT19DgUcOK2qkMqbAkWeY5TsnwCLuLBfC35eLcyx8mrfkCBLIrk7wkAWJz7Htm8/wjnOREyQaBwIoQQAHu6B42AhsXTRwqn/Jnktz0XTqXPotdUBI3AClXDRQcdlsiJjbQypydp3+mRb6tKsIgSt+qKoOXeIiD/2ilznHKvR7XDUr1BxSWUtkoGPZjzJY73YECzJGgbPC7Vk0+kyI4TACyZlv35yFAS7/cOKX9uQoj/UDgRQgjMwQ+LR2yAJtVWYlpjNQDgLQ8CImThZKVULxDQjLP5quY4DZjm9Nh3FdQ5Ttl1BLRsEIFVxIZelWCJOXB6APXOlzGU2MY6ZEGhOizDXhmn+pAK0StVVxWCppUWtHXhkNFr5IXj9PbB7PfBzKaaUSc9lkgnYFiuR8jEgMKJEEKQLacBsmeyT5haP+r6eW3ZfoXdXYPKn7tv0J7jBGQ3hIA6x8lpqZ4hWFQJJ0OwWNsY59chHCe186SsziwavY7yleoFAxqqKhTHxNscjgyYjyNVx4c43q0mP2qahvqq7G29SNXb3RUDAByf+36QOWFqPYRZuZnCiZAJAYUTIYQgX4J3fFvEFAwhEAMt93bHlPcrCOFUWxlEhcWo50iV2hhwWTjZiSPPz+pRnSJXXsFiCIUK66+FfHtlAs5BqR6QD+1Q7jjZeF/kdEZVx2nUQWR+Y022b/DIkLpBvEC2L3JvT/ZEyszc94NMTWUIx+UCIrxK5CSE+AuFEyGEANjVmTtzPLmu4PUzm7Ibo1gibaRoqUKUEFl1m4D8xjGqynEyxW/b6S3KrkNZaZrDEjnV6xCCxbbjFFbrfMUclOoB+ZJB5bHodtzIsPqSQTFMtq7K+jrqc58rOb1SBR3ROIaT2Qj/WU2jhRMALJiS/T7Z0TGg9LkJIeWBwokQcswzlEhjf1+2eXtubtjtSGY15y/f0x1T+vxHciVEDTWlE/UEkVwUsxc9TnbO5guBk0hnkEy7H3LqZG6RvA5Vzle+NK28zpcQglaHAQvyjpMqB86+4+TFHCcnQ5obc8JJdY/Tnu582a78/SBzfFtWOO3vG1LWB0gIKR8UToSQY573JCE0t7WYcMqfUZY3TCoQG7pGG45TvsdJzWbQaQy46qGvTh0n5aEMUq+VrXVUqHO+dF03UvWcvh4q3pNMRndUMhgOBYweH1UCTvQ41VmY4SRo8Ew45b83CpXqAfneSADY2UnXiZCjHQonQsgxjyjTA4C5LaObvIF8qR6gXjiJHic7pXp1HvY42ZlbZIq+VrA5NtLsbIg3IN9blEhnkFLgfA05FCyG46RgflIinUE6o+ce12aPk8KSwSHpd7HjOGmaJs35UpuqF7FRqieSKvsUx5GL/iZNA6ZPqi54m+Mn579Pth+mcCLkaIfCiRByzLO7K7+hmd1S+MxxVUUQk+vDAPIbJlX0CcfJQhS5IKI4VW9AKsWyN7dIipxWsDkW85NqbIi3ketQIVpicWeOk8p0v0Hp9bTtOFWoi4k39b/ZFLSiZFBVmZro6auzsQ5xQqJ/OIlMRl2wiziB0t5QjXCo8Pszu7nWiEPfQceJkKMee9+AAM4991zHT6ZpGjZs2OD4/oQQ4gXCcWqrC49ZAjSruRaH++NKe5x0XXcWDpE74x5LpJHO6MbmzCnCLbJTpgeYhYWK8jRDsNgMZZB7gAbjadTbKOUqxJDjdL+c85XKOl8hiymJhXA6DBjIC8khBSJy0OGML0BtWEYilUE8lXUT7fQ4ic+VrmeFV4ONExRjsSd3AmVWkTI9AKgMBTCruQa7OmN0nAiZANgWThs3bnT8ZHZmchBCiF/sys1imVMkGEIwq6kGL+/uUeo4DSczSOQ2g3Y2dCMb7+2IrkKIEij7wkkecureVXBbIge4LxmUe4tsC4VKs/NV70I4DUm/h904ciMsQ4ELaE5ctLcOY0CygmNDLku1U6onfzaODCWVCae9uRMoYwknIDviYFdnjD1OhEwAbAunZ555xot1EEJIWdB1HbtyG5q5rYX7mwRig9Q1kEAsnrItMgohN6w3VltP1ZPjmFUIJyP22uHAV0BRj5MRv+3c+XLrbgwnMxCjuuwKFtn5Gkq4c75ibpweI57d/Xsiv55Ojw8VpXpyWaqdcIhGKa2ybyiBmRhb6FghOpxEb65nakaRKHLBvLYI/uetw9jTHcNwMl1wThwh5OjA9l/9VatWebEOQggpCz2xBPpzG7JiUeSCqQ35BvBD/cPGcEs39A3lZ8vYC4fI31ZFn1PMYYqcLB7dCpZ0RjdKsezGb6tM93M600r1OuT7O309BpNp6LruquJDFj22jw+jx8m98xWN508yOCnVA9Ql6x06Mmz8e1pj4WAIgfieyOjAvp7BorPiCCHjH4ZDEEKOaXZ3lY4iF0xtqDL+LW+c3HBESvpyEg4BAANx95vBmIP5OIA5gW/Q5eZYdqzsO07qnC+5V6ucJYNDSeeCRdxe12EMaXW8DhevR63KUj2T42Q/VQ9Ql6x3UPr8T6mvGuOWwGzphIz8fUMIOfqgcCKEHNPIUeSlepymSmeWDyoSTn3SGXAn4RAADMfMDTGHPU5mx0mdYLHvsKgLqXDT06OyZNBdqZ46AScPFbYraEVpnxLHSTrOy+04HTwyZPy7vYTjNJfCiZAJg/sC/Rwvv/wyHnroIbz77rvo7++Hro+O/GSqHiFkvCGCIUIBrWSvgnxm+WDf0Bi3tI7sONkq1ZMdJ4Wlem426DHXgsV9Lw2gtkTObrqfynW4E5LmdTS7WMegKY7cpuOUE1oq+t/kcAg7jpM3wil/4qQtN6agGI01lZhUU4HewaRp2DYh5OhDiXC66aabcM899xhiSdM0k3ASPzNVjxAy3hDBEDObalBRIgGtujKIxpoK9A0mcbBfUame7DjZKdUbEQ7hFqeOUzgUQEDL9m+43RzL9xdziKxSrdBhMc1PstnIbw6HUPd6jB/ny+Y6wkI4pZHJ6LZmhI0k6jBVr6oiiHAogHgqo7zHqSVSWXSGk8zsllr07u0zOdyEkKMP16V6v/jFL3D33XdjxowZuPfee3HBBRcAAP7nf/4Hd999N84880zouo5bbrkFTz/9tOsFE0KISkTpTKn+JoEIiFDV4yTCIYIBzdZQT5XhEJmMbmyu7QonTdMkV0Gd02PXcapVKBRMvVYu5lq5D6lw0WslDyZWJOA0DaiqsLdtqB0Rz+4GU49T2F5aoehz6htMlLilNQ7kPv9TGsbubxKIMmA6ToQc3bgWTj/72c8QCoXwzDPP4HOf+xymTp0KAFi9ejVuuOEGPPfcc/je976HH//4x6iuHrsOmBBC/CSd0bGnOzuTqVR/k0AERKjqcZKH39px5WsqghA3j7p0nOQNrd1SPSDvsrgPh3AuFEwhFeMgzU7FOkSpXkDLOnu21lEhO19qHKfaypDtyhFTD5zL41SEoAQDmm0BJ8r11DlO2VJdOWlzLOY0Z79fDvfHlUSzE0LKg2vhtHnzZnzwgx/EnDlzAOSH3Mqlen/1V3+FuXPn4nvf+57bpyOEEGXs7x1CIp1NHJvTYi1aXJxhPnRETY+TSPmyO4cpENAQybkb0WF3m0F5I+dkNpWq5LRBF7HXAWkz7b5k0EVpWqU6wSLWUeNSsLjdqIvX066Yza4jfx+3JaUiHCIStv96iBlpqlP1plp1nFoZEEHIRMC1cBoaGsK0adOMn8PhbJNkf3+/6XYnnXQSXnjhBbdPRwghytjZNWD822qpXntuo9Q7mHS9MQbMjpNdRJ+H21I9eWNtN44cyG+oVQkF+THtrUNVyaDUa+Ui3c+tkBRx5HbXMPI+Qy5L5PICzvl7Ij+OU8RxbicYQlCv0HEaiKcMEWe1VG92c/77heV6hBy9uBZOU6ZMQVdXl/Hz5MmTAQDvvvuu6XadnZ0YHlZT2kIIISrYLTVqlxp+K5gyYgiuW1wJp5zIcXsmX27+d7Y5zkVOu3V6kvI6jk4BFwxoqMyV1akrkXPg9MgCTtF8LSfvSUSh8xV1OGsMyPc4qRBOstts2XGSI8kZEEHIUYtr4TR//nzs3LnT+HnlypXQdR0/+MEPjHK9559/Hhs3bsS8efPcPh0hhChjV85xioRDaK0bO1JYIG+UDioo1xOlQ3aG3woMx8l174hbxyl7H9eCxVSq51zAqepxqgwGSiYt+rGOageCRWXKoCHgbAZ2ACPj6l0epy4cJ3FiQkWpntzfaLXHqTYcQlvuO2Y3HSdCjlpcC6eLLroIu3btwuuvvw4AOP/883H88cfjkUcewbRp03DyySfjvPPOQyaTwRe+8AXXCyaEEFWIXoM5LbWWeybk0hwVyXriDHijA8dJJOtFXZbquUmRy95HOE4KQxlsxoADeYGhKkXOSYkckA9mcB0OkXTeW6R2rpUqx8llqZ4bxyn3+RpKphFPuVuH/LmXZ7uVQrhO7HEi5OjF9Rynq6++Gq2traitzX4hhEIhPProo/jYxz6Gt99+G4cOHUIgEMANN9yAL37xi64XTAiZ2CRSGTy99TDefP8IZjbV4PwPTEZLxJobZBcxU8VqfxMA46wxAHQNxF09fyajo3/YeameiC93Gw4xYAqHcCBYcjOX3KamGYKlIuho3k+t4lI9JyVyQH52kRA+ThFCw4lwqggGUBkMIJHOKItFd+Q4qSzVyx3nkSr7nxXZ0T0ylERbnbP3FgA6pc+9VacayAqnl3b34D0PhVNnNI4N7xzG3p5BLJ3eiHMXthmlo4QQ97gWTq2trbj66qtNly1cuBBbtmzBtm3b0NPTg+OPPx4tLS1un4oQMsF552A//s8vXsW+nnwJ3KQntuKeq0/G6cc1K32uwUTKKLmxGkUOZM92V1UEMJzMoDPqTjhFh1MQAaQNNZW27+9Fj5Mbx8ntnJ5BFxt0QGWJnEvHSfR8uXRYhlyEMgDZWU6JwYyCgcDOHadaU6meGsfJTTgEAPQPJdFWZ90pGon43NdWBm19XsT3TO9gEn2DCTQ6+MyPxQs7unDDL1839XHNaq7BvZ8+BQum1Cl9LkKOVTw9DbFgwQKcfvrpFE2EkJK88l4PPvYvL5hEE5DdZHzmvpfwx729Sp/vva5B499zW61FkQPZkQviLLNb4SSG3wLlTdWTN9bOQhmE46Sqp8eZUBCleqpS5JyISCBfZuja+Uo6FyyAupLBmAsHzpSqpyiO3M6gaIEsUtz2OYnPvR23CRgREKHYdXptTy8+c9/Lo8Iv9nQP4op/eQGv7elR+nyEHKvQvyWElJ093TH8n397FbFEGpoG/N8L5mPLHR/GD69choqghmRax/994H8x7HJDLLNLjiK34TgBQGuudLDTZamevIFz0uMUMeYnpZHO6CVuXRxTqZ6LfppEOoNkbi6WE4SAszs7SVBrOD1uHZacgHPQZwVIzpfLUr1BF6V6QL5Mzv1cK+HA2X9fKkPZkkEAGHCxjkQqg3gqe2w56XGST0y4TdYbb8JpOJnGLQ/8L1IZHZXBAH505TJsuePD+Orq+QCyn+//82+vYV/PYIlHIoSUwnWpnmDTpk14+umnceDAAcTjhTcTmqbh5z//uaqnJIRMABKpDG5Y9zp6cyLiB5cvxcdPnQEA+NjJ03G4fxh//z/bsLMzhv/37E585fz5Sp5XjgS2U6oHQJnjJG/gGhyk6sklS7FECvUOej+AvNCoqggg5CJFDsi6Gw3Vzs7JuXec1Do9Th2nvGAp3/wk+X5u1pFIZZBMZ0W5856vXMmgC0fSNGvMQamefGLCteM04Ew4zWyugaYBuq5WON39zA7syj3e1y6YjytOng4AuPm849FaF8ZfPbwZ3bEEbvjla3jkxjMcJUUSQrK4Fk5DQ0O48sor8fjjjwOAEUFeCAonQshI7trwLt4+mB2Y/fmz5hiiSfCFs+fisc0H8daBfty/6T18/qy5jje0MmKjMbk+bPvx1JXquXOcZOEUHXYhnIxSLIdCwTTkNOWo7DB7X7fryPda6bpuOSlx1Dri7gRcjYJSvUxGN0oOnTg9gPR6uBAs8u9Q4/BzV1sZQt9g0lXaoZwcOW4cJ5uhNeFQENMaq/F+75Ay4RQdTmLNC+8BAJZMa8Dnzppruv6q02bi3cNR3L/pPWzZ349/enqH4UQRQuzjevdx22234bHHHkNdXR0+/elPY+HChairYxMiIaQ0r+3pxb9szM6B+8DUetzy4YWjbhMKBnDTufPwxXXZpudfv7IP1585x/VzC+E0t8V6f5OgNZJtLO8dTCKRyjhOrXLrOEXC+fu46XMSZ/OdClI5zMGNuyHW4TyUIbv+dEZHPJVBlcNSO9epegpKBoelyGznjlPO+XJRMiiLHaevhxFX7+L1iMbzn5U6BycI5HCIPhfCaTiZNkScXccJyLrbKoXT+pf3Guu5+bzjESyQRvmXFy3EH3Z2Y+uhKO5+ZgfOXdiG5TMalTw/IccaroXTb37zG0QiEbz22msccEsIscxgIoWv/eYNZPTsoNEf/9nyogJk9QemYG5LLXZ1xXDf87tx7QdnO4qrFui6jl2d2R6nOTaiyAXyhqk7Frc8BHMkRwbVhEMAwEDc+WbQrXAyBwC4cDeSagQLkHVKnAqnmIu5RYCakApT0mEZS/VMwSGOhbX70kX5xICTVL1gQENdVQjR4RT6XQgn2WV2Kpx+v70L73XFXLmiQPYEwf2b3gMAzGuL4LyFbQVvFw4F8Q8fX45L7n4eybSOr/77G/jvm89yfIKCkGMZ14Wuhw8fxtlnnz0uRdPAwAC+8pWvoL29HVVVVVi+fDl+/etfW7pvR0cHrrnmGrS0tKCmpgann346NmzY4PGKCTl2+N5/v4P3urPNyv/3w/PHjMsNBjRce8ZsAMD+viG8tNtdQlR3LGGcpbUbDAGYN0xuyvWE41RdEUQ4ZH8TI5csuRmCKzbpKgSLm3KsWFxNaRrgLhrddQx47n7JtO44LEMukStnqZ4KASdKL904TnKAiZNSPSA/y6lPOmFhF6cznASinzKWSLsu9f3Dzm5jpMK1Z4x9MukD7fX4i1yJ3q6uGL7/+DuunpuQYxXXwmnKlCnIZJynKHnJ5ZdfjrVr1+Jb3/oWHn/8cZx66qm46qqr8Ktf/WrM+8XjcZx33nnYsGED7rrrLjz66KOYPHkyLrzwQjz77LM+rZ6QicuGdw7jly/tBQCcNrsJ1585t8Q9gIuXtqMimN0YPPLH9109/y4pGMLO8FuBKuEkmtSd9gTVVykSTgm3jpPZ6XHKkJGq5y6OXH4suyRSGaRyCYVuhRPg3GWRy+tcl+q5EbMuo+qz93M/18rU4+TAcQLynzM3PU4mxylifxbUbIXJeg/nvgcrgwFcvKS95O2/cPZxOHnWJADAv/1hD57Z1uHq+Qk5FnEtnK644gq88soriEajKtajjMceewxPPvkk7rnnHnzhC1/AOeecg5/+9KdYvXo1brnlFqTTxb/Af/7zn2PLli34zW9+g6uvvhqrV6/Ggw8+iPnz5+PWW2/18bcgZOLRNRDH1x96E0B2HsuPPr6sYF3+SCbVVuKcBdlSlMc3H3IVTb7bFEXuoMdJlXDKbeAaHfQ3ASNL9dyfzXd6Jl8WXE4dJ13XDZfIqVAwDVt1uEmXRYZzp0cWcM7WIa+/nKl6gwrWkY/Nd9PjJJXqOXWcqrOznNz0OLkt1ZurSDgNJlJ4YsshAMB5J7RZ6pEMBjT8+OPLjc/JrQ++iW6XIxUIOdZw3eN0xx134He/+x2uvvpq3HfffeNm2O0jjzyCSCSCK6+80nT5tddei09+8pN46aWX8MEPfrDofcXwXkEoFMKnPvUp/PVf/zX279+PadOmebp+L+gfTo7abGowb1gLlVuPvGhkTfbo6ws9hjbygjHvU2gbbfd5Rz1nkbW5fQy7r0/Bx3BR516KTEZHLJHCQDyFWDyFI0Mp9MYS6B0U/yXzP8eSxuX9Qyk01FRgakMVpk+qxmmzm3Dm8S04rjXieL2ZjI6vP/gmugaypTLfvnQRZjTVWL7/ZSdOw+/ePoxoPIWN2zpw4eKpjtYhHKeKoIbpk+z3JzXX5odpqijVc+o4yULHTTiE23lB8rwjp2Vhw8kMRCir016aahVOT0JdbxHgXCyY0uyczrXKvY6pjO44xEQueZRDQOxQoyAcwtzj5Ozzotpxao5UjnHLwkxrrEYooCGV0bG727lwenZbp3GsXnai9f3IzOYa3P7RRbjlwTfRGY3jLx/ejHs/fbLj73Rd17HtcBTPb+/C2wf68fbBfnRG4xhKpjGcTCMcCqKuKoSG6go0RyrRHAmjNRJGc20lWurCaImE0RypzF4WqURlMIBgQLO8Hl3XoeuADiCj68iIn/Xsz+JyPQPo0JERl+vZn4l3FNo/FaK+OuSoVL1cuBZON998M+bPn49HHnkE8+bNw8knn4wZM2YgEBj9Be1nHPmWLVtwwgknIBQy/4pLly41ri8mnLZs2YKzzjpr1OXivm+99daYwqmjowOdnZ2my3bs2GFr/V7w/ce2Yv3Le8u9DOIAu4JWvi7lYjBqZzSOzmgcb75/BI9tzp7dnNlUg6tOm4krT5mOFptxvD9+6l1s2JotD/mTpVNx6XJ7JyDOWdiG6ooghpJp/O7tw86FU+5M78ymGkdzi6oqgqivCqF/OOVqCO4Rl6V6cmx31MWm1H2qnjmO3NEaEupK0wBgyGGSnNlxcjdPCnDuOA0qeD1MgjaRQmXI/kZ/MO6+VM/ocXITDpELPwkGNFRVOCuWEa7MERdznMTnfVJNhaN5SKFgADOba7CrM2aaJWcXUWZXVRHA2fNbbd33YydPx9NbO/D4lkN48u3DuGvDdtvz8Tqiw1j/0j7855sHsKNjoOjthpJpDCXT6IjGsd1GZWAwoCGoaUY1ghA9QihlRZKtJZNxyrrrV+DM48eH6WIF18JpzZo1xoatv78fzzzzTNHb+imcuru7MXfu6L6JpqYm4/qx7ituZ/e+AHDPPffgjjvusLNcQsak0Hi0UReNMUNtLEIBDY01lZhUU4FJtdn/N9VWoq6qAn2DCRw8Moyth6LGmda9PYP4wRNb8Q9PbsOfLmvH/zl7LhZOqS/5PPdv2o1/ejp7AmFOSy3+9tIlts9yVlUEcdbxLfjd24fx9NYOpNIZR8LHSNRzUKYnaK0LZ4WTAsfJaaleIKAhEg5hIJ5y7Djpum6IFqelemaHxdnm2BSG4DANT02pnuw4KQipUOB8OS5dDJvfl0br5q7pfsbjuXS+ssN0M44Ehzi+I+GQY3dEnKDoG0o6TrQzZjg5KNMTzGmuxa7OGN5z6Djpuo5ntmVPzp5xXIvt9EhN0/D9y5fg7YP92NM9iJ88tR1NtZX4zOmzS953Z+cAfvb7XXjotf1IjAg+aa6txAlT6zGzuQY1FUFUVQSN+PYjQ0l0DcTRHUugKxoveaInndGRhg64myFNiHJcC6f7779fxTo8YawvxVJfmG7ue+ONN44qEdyxYwcuvfTSMe/nNZcsb8ei9vwG18rGe+QlI28ycuBxoa37qPuMur70hn/0Y+glrnf/GIXXYe95Cwsem2u3+b6MfPxgIIC6cAi14RBqw0HUV2UFUlNNJRprK1BnYSOi6zp2dAxg47ZO/ObVfdjeMYBkWsfDr+/Hw6/vx4cWtOILZx+HlXObRj3WcDKNH/1uG376+90AspuXn3/2FEdziwBg9Qcm43dvH0bfYBKv7unFyrnNtu6fSmewtyeb5uckGELQWhfGzs6Yyx6nbMmiU8cJgCGcosPOzqIPJzPGmdsah6VY4VAAAQ3I6C56euR5QQpK9crbW+TegRtUUKqnIixDdpycz9cyl3I21NgXTtFhd+IeyA+ZTmd0xBJpR4+lRDjl+pze6x5EOqNb6vGUeetAv7GODy2w5zYJGmsqcd81p+KyuzehfziF2x59C/t7h/DVC+aPKpvKZHQ8v6ML617cgyffOWz6e3PC1Hr86bKp+JMlUzGzqcayGB1Opg0R1TUQR/dAAt2xBJLpbDhLJqMjldGRzoWPBbRs+Z6mAQEt9zMgXaYhoJl/1oz7ZS837idu5+iVI1awcxr3uDbnf4fLgWvh9NnPflbFOpTT3Nxc0Bnq6cnGGBdylFTcFwDa2trQ1lZ4nkI5WTm32fYmkxAg+0fm+Ml1OH5yHT531hy8uqcX92/ajSe2HEJGBzZu68TGbZ2Y21qLDy+agkXt9agMBrD1UBS/eXUf3u8dApA9I7n2utMwt9W503PeCZONTfqTbx+2fUzv6RlEMp39Wj/OlXDKJmo5LdUbTqYxnMxuChpr7JdQCeqqQjjU7zwcQkXMs6ZpqK0MIRpPOe7pUeGwqBAscomf014rFSmDKkoGaxU4X8JxqgwGHA96jowID3Fy0kQ4FE5mOAnkExR9gwl3wslmmbLMcW3Z779EKoN9PYOmpD0rbJTS8D60wPle47jWCH75uZX4zH0voXcwiX99bhce23IQHz95BhZOrUc8lcaW/f34rzcPGN/hgvNPmIwvrpqLU2aPvR8qRlVFENMaqzGt0dkMPELKhWvhNF5ZsmQJ1q9fj1QqZepz2rx5MwBg8eLFY95X3E7Gyn0JmehomoZTZzfh1NlNeK8rhp89vwsPvPo+4qkMdnXG8C8bdxa839LpDbjrEycaZ1ud0lRbiZNnTcIr7/Xi2Xc78U2b999+OJ8Aevzk4rOjSiE2Tk4dJ3kIZ70bxym3kXQqnOSGfaelWEB2cx+NpxyHQ5jT28o3x0llmh2gpnTRcY+TwpRBp25k9r7uBa0o1XMjnOSS2CNDSUyfZO/+uq4bJ0rcOE7Ht+VPHG3vGHAgnLJlevPaIrbCdQqxZHoDHrzhg/jyr/+ILfv7sa9nCD968t2Ctw2HArhkebY8e16b8+9OQo5mXMeRj1cuu+wyDAwM4KGHHjJdvnbtWrS3t2PFihVj3nfr1q146aWXjMtSqRTWrVuHFStWoL299LwEQo4FZrfU4ruXLsGmvzwXf3nRQiyeVj8qyOL4tgi+c8kiPHzDB12LJsGqXDP0jo4BvN87aOu+2w/nG5nlDYxdxMZpMJF2lBYmRyI3uizVA5zPcTKXyDnfHIvyOseCRUEYgigZBJyn+6kWLE5L5GSnx0lPEGAWwo5DO0TiosO+s+w68vcdcPi+uI3MB8wnKJwERPQPp5BIZV1id8IpLzrelU7kWKFvMIHX9/YCAM5xWKY3kuNaI3jkxjPw7UsWYd6I78SAlj3p9e1LFuHlb5yPv/vYMoomckzj2nG67rrrLN2usrISLS0tOOmkk/Anf/InCIedf+lY4aKLLsLq1atxww03oL+/H/PmzcP69evxxBNPYN26dQgGs1/k119/PdauXYudO3di1qxZALK/0913340rr7wSd955J9ra2nDPPfdg27ZteOqppzxdNyFHIy2RML646jh8cdVxiA4nsa9nCPFUGjObatDsoqSlGKvmt+GHv8ueFX3u3S58csVMy/d9N5cANbWhynGsMWDeOHUNxG335ciRyE7DIYD8GXjnjpMcN+38T4IxM8jhOlQIFk3TUFOZ7flyXpqmYuCrLFicCrjsOpyW6WXXoSKkQjhOzo8NU+qiy5LSiIvPrJjjBDiLJO8acDfDSdBQU4G2ujA6ovExE+kK8dz2LqMn8RwXZXojqQgG8JnTZ+Mzp89G10Ac+3oGEQ4FMaOp2tX3JCETDSWpekA+MGFk8/zIyzVNQ2trK+677z585CMfcfv0Y/Lwww/jG9/4Bm677Tb09PRg4cKFWL9+PT7xiU8Yt0mn00in06Z1h8NhbNiwAbfeeituuukmDA4OYvny5Xj88cexatUqT9dMyNFOXVUFPtDu7R/aRe31aIlUomsggY3bOmwJJ1Gq56ZMDxg9BHdWsz03rU864+02HAKA43AIFUIhe9/gqMdzug63Ai4rnMrXa2WOAXeXqud0DYCaEjmxDqczrbL3lXucnL0e4vh24zjJvVVOhuCaht9GqhyvAwDmT65DRzRu23HamBvnUFsZdNxfVIqWSNj2qAlCjhWUpOq98soruOeeezBjxgxcccUVmD17NnRdx969e/HQQw9h7969uOGGG9De3o6NGzdiw4YNuOKKK/Dyyy9jyZIlKn6PgkQiEdx111246667it5mzZo1hviTmTx5MtauXevZ2gghzgkENJx9fCse/uN+vLCz2/Jwz1Q6Ywy/ne+iTA8wN4c76XMyOU7VbsIhsptBp3HkMQXhEEBedDkNQzDFkStwWdw6LAEtW/rnBDFraDiZwZDD0kUlwkmJgMs5Tm5EtRyL7tBxEqWo9W56nKrNPU52MQknF44TABw/OYLnd3RhR8eA5WS9TEbHxndzMeTzWhyHdRBCnOP6U3fiiSfi/vvvx6233oqdO3fiH/7hH3DzzTfjy1/+Mn70ox9hx44d+PrXv477778fF198MZ588kn87d/+LeLxOH70ox+p+B0IIccgq3L1/QPxlFHzX4o9PYPG7JHjJ7sUTrLj5CBZr28wYfxbheMUS6SRdjAR0hQO4arHSThOCkIZXPTTiA2+e6fH+bwgeR1OhYIQLK7ct7B74STeFzfHxshUPbskUhnEc71F7sR9EKGcQOlz0OOkVDjl+oTiqYzlPs039x9BTyz7vXHOwvGX3EvIsYBr4fStb30Ls2bNwp133mlKrxOEQiF8//vfx+zZs/Gtb30LAHDLLbdg+vTp2Lhxo9unJ4Qco5w5r8UIong2dxa2FKoS9YBsup84SezGcdI0d0lh8n2dbEpNPU5uUvUq3DlOg7kY8MpQwNFQY0HecXLXa+XG6QHy5XrO51qlTY/jhMpgwHAynJfqKXCcKt05TiZX1MVnRdM0o5/QkeOUO0ESCmiuAl0AYL504mbbIWvleuYYcjXBEIQQe7gWTr///e9x4oknlrzdiSeeiOeffx4AEAwGsWTJEhw+fNjt0xNCjlGaI2EsndYAAHh2mzXhtGV/P4CsWJnvUjgFA5oRfOFGODVUVyBgcwCmjHwG3kmyntlxchMA4K7HSaTguemlAfJ9PY6dL0XCSbwebkvk3Lwn2bCM3PviMM1OvB5uHCdZdDlZx4CiYxTIJ+sdGUqUuOVoxOe8JRJ29ZkFgAVT8t8/bx3ot3SfZ3Lfcwun1GFqA+cfEVIOXAunoaEhHDx4sOTtDh48iOHhYePnuro6VFQwqYUQ4hwRS/72wX509A+XuDWwef8RAMDcllpXJT8CN7OcRKmQmzI9wHwG3kmf00Bug+5mwCmQ70tyPMdJKpFzQ43h9Dh1nNw7LABQLUoGXfY4uen3AvIuomMnMCdahKPohGBAM5wzJ85XvxR84qbHCcj3ObnpcXJbpgdkexPFeIYtue+lsegaiOPN9/sAsEyPkHLiWjgtWrQIv//977Fp06ait9m0aROee+45LFq0yLhs3759aGlpcfv0hJBjmFVSucpz27vGvK2u68YGZUnOqXJLS24D5aTHSWzc3Jb8yFHBA3H7m0EhdNwMOAXyG/REOoNkro/M1joMweLWcXLpsMTVOE5uBZwyB85F2qGu64bwc+M4yfd3MsdJPiHgNhpbnKhw0+PUEnEe5iKzOPc9tNmCcHru3U6I8N8PzWeZHiHlwrVw+vKXv4x0Oo0Pf/jD+OpXv4qXXnoJhw4dwqFDh/DSSy/ha1/7Gi688ELouo6vfOUrAIBoNIrXX38dp512mtunJ4Qcwyyb3mhshOT6/0IcPDKM7lxj9WJFwsmV45QTTvVuHSdFpXpu+psA9zODVKTIyfd3nGaXFEJSzevhVMCp6C0C8kLSieM0nMwYm3W36zAGJDsQcAOKkh8BoLEmK3rc9DipcJwAYMm0egBARzRe0jEXZXp1VSGcNGuSkucnhNjHda3K1VdfjW3btuF73/tewehvXdehaRr+5m/+BldddRWAbNnel770JXz0ox91+/SEkGOYUDCAM49vwX+/eRC/3941ZqyvfFZ36fRGJc8vNlCd0TgyGd1W30O/cJxq3J29lsMhnAzBNQaLuhYK5plBdksQVQmFWrdpdrn7uUn2A/IlduWMIweAmgrR8+VAVJtma7kVtOJ9cdfj5CYcAsg7TkdsOk7pjI7ugXyPkwrkEzib9x/BefWFZ0Ol0hk8lwvAOfv4VlS4CE8hhLhDyafv29/+Nl588UV8+tOfxpw5c1BZWYnKykrMmTMHn/3sZ/Hiiy/ijjvuMG4/f/58/P3f/z3OOussFU9PCDmGEX1OR4aS+N9cD0AhRJmepmUH6KpACKdURrd9BlvEkTdUu9sIyoLHSY+TsUFXVIolP6YdlJXI5Tbo8VTGUTy7stej0rnDkkhlkMqtXVXpoiMXUI6IdyloI0YJpf3XQ3ZS61wKfCGcovEUUjZKSntiCYjDqU2R4zRSOBXjf9/vM75fmKZHSHlx3x2d49RTTy04SJYQQrxklVTvv3FrB06aWbiMRcx6mttS6zqZSzByltOkWmvuUUYSWpNcOk7yGXgnpXqeOE4OXIUhxSVyQFa02O2JUdVrVe1iEK8stlyX6rlYh8lxUiRoXZfqKXKcAKB/OIUmi59Z8wynws6QXepzARG7u2J4fW9f0dtteCdfhryKwomQskK/lxByVDO5vgqLc70Cj285VPA2w8k0XnkvK5xWzm1W9tytUsmOnT6n/uGkcfbabaleRNpYR13MyFHb4+RmHWocluw6nPdaqXo9hhJp6Lo950uOUldVIjfo4NgwCTiXgtbNgORoLlVPTudzipjjBJiHUJdCDoBR1eMEACvmNAEAXtndg3hq9Guj6zqeyH2vLZvegDZFoo0Q4gwKJ0LIUc9Fi6cCALZ3DJiG3Ape29OLRCpblnPGPHVpnibHyYZw6pX6K9ym6gUCmuEWlbNUz204xJCi+G0360hndMRzx4mqdaQyOhI2UwblJL5qVY6Tg16rmKlUT03popNSPXFcR8IhaJq7+Umy42SnvNbsOKkTTuL7aCiZxh8LuE7bDkexqysGALhoyVRlz0sIcYbtb+Rzzz0XmqZh7dq1mD59Os4991zL99U0DRs2bLD7lIQQMiYXLZ6Cv/+fbQCAxzYfwpdHDLfdtCMbVa5pwOkqHSfHwil/pntSrft5dpFwCAPxlKM4clWlenL5o90gAl3Xjfu4d3rkYav21mEukXNbqpdfx1AijXDI+uPJgkVZiZyD8kmVr4c4Phz1OCk6RoERjtM4EE4fPC7/ffTCjq5Rjvhjm/Mu+kcWUzgRUm5sfwtt3LgRmqZhcHDQ+Nkqbs8UEUJIIea2RrBwSh22HoriP988gJvPm2f6vhHCaVF7veU+JCvUV4VQGQogkcrYmuUklwi5LdUDcn0f/fZT9XRdNzayrge+Vjh3euKpjFG6qNJxsptoJ6/bfbqf+fVorHG2DlWvh5ivZSeRzSzgFMWz50oX7ewHhONU57K/CQAaqvOft34Hwqm6IuhazMo0R8I4YWo93jnYj+d3dOGrFywwrtN1Hf/15gEAwOJp9ZjZbOMgIoR4gu1voWeeeQYAMHPmTNPPhBBSTi5ZPg1bn9iKHR0D+MOubnzwuGwJzL6eQbyZS6w64zi1Q7c1TUNrJIz9fUP2HKdYfsPmNhwCyJ+JtxsOkUjn09sirlP15HAIu06PeocFcOI4qStNq3ZRMjhoCmVQO1+rodq6cJLL+9ynLmZ/D1EOWWWjV0mVKwqYS/XsDMGVZzipPgl85rxmvHOwH2/s68OBviG0N1YDADbt6MauzmyZ3keXtSt9TkKIM2x/C61atWrMnwkhpBz82akz8OOn3kUilcHaF94zhNP6l/caQzwvPXGa8udtrXMgnORSvRr3pXriTLxd4WRyFBSm2dkNAFCZIieHKdgd+qo2zc5cqmdvHQp7i8LmddiZryULYLcCbqQDZ0c4iePabaIe4KbHKTugVmWZnuCS5dPw09/vRkYHfv3yXsN1WvPCbgBAVUUAHz9lhvLnJYTYx5NwiP379+PnP/857rzzTqxbtw49PT1ePA0hhBg01Vbi0uXZs7JPvn0Y7xzsRyKVwW9e3QcAOHnWJJwwVc38Jhl5CK5VxJnugJaNJHaLEE52S/ViCjfG4VAAYv6vK6HgNqSiQu61Kp9gMQtJF71WSgWtzeNDLhl0mWZn6oGzeZyK49putHwhKkMB4zWx5TjlPt+tiobfyiye1oBlMxoBAL9+ZR+S6Qy27D+CDVuzMeSXnThNSUkvIcQ9tr+R33rrLaxduxYnnngirrrqqlHX33vvvfjyl7+MRCJ/RrWurg5r167FJZdc4m61hBAyBtedOQcPvvY+Mjpw0/o/oiVSia6B7HfR1StmevKchnCy0ePUawy/rUAg4L7sx2mqnmlOj8sNuqZpqK0MIRpPORAKCgWLKY7cRcmgSwEnl+rZFZKmNDuXgsWV82X0vwVdH6duwkOiw+pK9YBskuVgIm3LcRLfI144TgDwqRUz8b/7+tARjeOz972Mw/3D0PVsBPu1Z8zx5DkJIfax7Tg99NBD+NGPfoRwePSXx4svvogbb7wR8Xgc1dXVOPHEE9HY2Ij+/n5cddVV2L17t5JFE0JIIRZOqcdN5x4PANjRMYAXd2Xd7gWT6/ARj6J8xRnonlgCSYux0+JMt4r+JgCIhLNn4l05Ti6FApAXC0436IC6ga+Ag94iaR3VFW5L06SeL5vrGFLYW2RynOweHyKqXkEYgnkd9l4PkRapIhwCAOpz5XpHhqzNcYqn8iLLK+H0p8vaMX9yBADwws5u7Mz1Nn3lvOMxf0RKKCGkfNgWTs8//zxqampw8cUXj7ruzjvvRCaTwcKFC7F9+3a8+uqr6OzsxDXXXIPh4WHcfffdShZNCCHFuOnceVj9gcnGzzOaqvFv159mq6fCDvJGqnvA2kZMOE6NCvqbgHzvx0A8hXTG+rDVAYU9TvJj2C2Riyl0nKpCQYjefVchFUrnWjkTtKGAhkobKXil1+Gs58utmAXMbpEdAZdMZzCczIx6DDeIz51Vx6lL+lx7JZyqKoL4t+tWYPqkauOyCxdNwY3nzPPk+QghzrD9LbRr1y6cdNJJqKw0nymNx+N44oknoGkafvCDH2Dq1OzZ3UAggH/8x3/Eww8/jKefflrNqgkhpAihYAD3fvpk7OyM4d3DUZw+t1lpBPlIRs5ymtJQVfI+qh2n+ipzGZTVvimVzf+ANGzV1fwkd+sIBDRUVwQxmEi7SrNzGwNerSAWvboy6DrBrcaF8yWcITWOk7wO68eHLLJUCScREGG1x8k0w8mDHifBlIYq/MeXzsSLu7oxf3Idjmut5RgXQsYZtk9ldXR0YMaM0ekur7/+OhKJBKqrq/HhD3/YdF0kEsEpp5yCXbt2OV8pIYRYRNM0zGuL4CNLpnoqmoARwmlg2NJ9+gzHSVWpXn5DaafPaUDxptQQTmUMZcg+hjPnyxyLrjCUwWZp2qCiYcCj1mHT+RpK5tahxI109nrISZEqUvUAoDE3y8mq4+TV8NtCNNVW4iNLpmJeW4SiiZBxiG3hlEgkEI1GR13+xhtvAACWL18+yo0CgClTpmBoaMj+CgkhZBwjn4G2mqzXazhOakv1AHt9TirT7IC8YHEVyqBALIhN+lAZU+SqQnI4hLPXQ3VvkdOQChXrcBoOIQunekXCqSH3uesbh8KJEDK+sS2cpk6dinfeeWfU5c8//zw0TcNpp51W8H7RaBTNzc32V0gIIeOYkaV6pRhOpo3SLVVumOwW2ZnlpNpxEoLFttMTV1ciB+RFj911CIFTVRFwnSIXCGiuHTgVYtZNmp1K56vWNJjY+uthPkbVnGgQpXqJVAbDFsoo5c91c4Sx4IQcy9gWTh/84Aexc+dOPPDAA8Zlhw4dwn/8x38AwKgyPcHmzZuNvidCCJkoVFUEjbQvK8JJ7qtQFQ4hp41Fh61HLIv+kWBAQzjkfqyfSKKznaqX27xWBDVUKliHEAu2Qxly61YhFACpdNFmj5N4X2pcJvsB2flamsP5WobjpEDAVVXk53zZCYcQiXqAulI9eQiulT4nUYLbWFOBcMibkBlCyNGB7b9QN910EwDgU5/6FK6++mp87Wtfw4oVKxCLxTB37lysXr161H22bt2K9957DyeeeKL7FRNCyDjDziwnkagHqAuHkAeDOinVq1EQQgDIjpNNZyO3ZrflcQKnTs+QFMqgAqfx7MKRVCFYxHwtwHmvlYpSPdM6HJbqqU7VA6z1OXk5/JYQcnRhWzitXLkSd955J1KpFNavX4+f/OQn2LdvH2pra7FmzRoEAqMf8t577wWAgqKKEEKOdsSGyorjJAunxmpFPU4uwyFUbUirXZamqQghAOR0P2dOjzLHqUIIFmdx5CoEi/w4IuzB8jpUO3Bh+++LLJxUzXGSHSf581gMQzixv4mQYx5H30K33HILLrjgAjz44IPo6OjAzJkz8elPfxozZ84sePuamhp8+ctfxgUXXOBqsYQQMh4xHCcLwkme9dSs6Ay203AIQygoEixig51IZZBMZ1BhcQaRyjCE7OPkSvVsCgXh9KhynIRQsBtHPmS8HmqFpB3HKZnOIJHKKF1H9jiLY8CG4yQfz6qEU5PUW9gTsyCcBiicCCFZHH8LLVu2DMuWLbN02+9+97tOn4YQQsY99oRT/jYtihrNZUfATjhE3lFQ62wAWTHUUG1VOKkbtCqvw67jlHe+ylsyqP59ET1f1tehchiw8ThiHXZ6nHLHc0BTV8opl9x1lyiv1XWdpXqEEAP3XbiEEHKMI4RTLJEuWZbVlXOcApq6OU7BgGZssm0JJ8WOkyx87PT1xBQ7TvlwCGeletUKQhnkx3Hea6VYSNpweuT3T7nzZeP1kMtJVc01ktMsOwfGdpwG4ikMJ7POGx0nQgiFEyGEuEQ+E91V4gx2dyx7fVNtJYIuI69lRECEnEJWinwvjapSLGfDVlWGEAB5Z2IomUY6o1u+nyipU+042ZnjlEhlkEhnN+rKHKew/YHA8vun6vUQvXR2er7EiQA5AMUtFcGAMUOtlOPEGU6EEBkKJ0IIcYmdWU6d0ewZ7hbFZT+iz8lOj1P+bL7akjDAXplcfm6RegFnp79I5cBX+XHsCBbZ6VHWa1VhX8DJ75/aHie7x2j2RICqABOB6C8sdaKDwokQIkPhRAghLpFFUCnhJBwn1YM0xcbSSameqrP55h4n+5v0GkU9LHKJm73yNNW9VvbnWsmBFspKKMP2wyFMjpMiASfEvRPHSdUMJ4HoL+wuUarXaepJpHAi5FiHwokQQlzSJjtOJc5gizPcqjdhdTYdJ13X846Tok3pyHAIqwhxoy7dT1qHRbGg67oxqFa14zSYSEHXrZUMxkxOj+o4cvvvCaDO+apzIO4HDHHvjePUXSJVj44TIUSGwokQQlzSVFsJ0bde0nHKneFurlVcqmdzUxpPZZBM66b7ukUWPk4S3JSVpjkQcMPJDIS2UT0AN6NnX28reBHKkB+Aa8eNlFP11KxDHGfxVD7qvBQiVU91qV5LLiCiq2Rpbfb6YEBTNrCaEHL0QuFECCEuCQUDaM5txDr6i2/EBhMpYyOvulTPcJwsCicv5uPIcdFWwyESqQxSuQAH1fHbgPVSPXNpmnoHzmq5nrwOZWEZuceJpzKWwzIGPViH7GxaFXFRjxwn4fhG4ykMj+HECeHUrDjMhRBydELhRAghCmirqwIAHI4OF72N3E+heiZMJCxS9SwKJ0lgeeI4WVyHuSRMfTiEVcfJk1CGSvtC0uw4qZ2fBFgXkqY5ToreF/k4s3ucehUOAYxdrneoP/t5bqtnmR4hhMKJEEKUMLUhK5wO9hUXTnKCl/JwCKnHKWPBVZA3rqo2paYSOYv9NOYNuqo48vHiONmfa2V2nNSGQ9hZh/y+1ChKXZRdIyslpcl0xujLEicGVCEPnx4rkvzgkezneWpDtdLnJ4QcnVA4EUKIAqY25oTTkaGit+mSHCfl4RCS+LHibsgbV1XhEOFQAKKayWoogxchBKZ5UpbX4V0ow8jHH3MdHoZDANaj0UUpXSigoTKoZqsgix8rjpNczqc6Va/Z4uy1Qznh1J47MUIIObahcCKEEAWIM9L9w6mi/RvdPjhOgLWz+aYeJ0Vn8zVNywcRlLEkrNqJ8+WBYKl2IpxMg2fVO192S/VqKoPQNDW9PfIxamVQs3wcq+5xMg+tLlyq1z+cND4nUxvpOBFCKJwIIUQJ7Y35M9LFXCe5l8KrOHLA2tl8eeOq8my+EAuWS9M8ECymnh4HvVaq5zgBwFDSasng+HC+hPhX9VoA5pJQ++JeteMkl+oVFk5y2e1UOk6EEFA4EUKIEuQeiANF+pxEQldtZRBVioa9CmxvSj0IhwDyLonVkjCTYFG0Djndz7rToz4cQu7ZsloyKARnQMuWPqpAFj9W0+wMx0lRfxPgRNx7V6pXGw4Zx0mxEQIHpBMg7XScCCGgcCKEECXIZ6SLOU6iX2KyB2ev7W5Kox7EkQPSsFUHpXqqHJZAQDM2xU7CIZSFZYTtl8iJddRUhpSVyLmJRVdVPgmMSNUro7gXTM4l5R3uL3yiQ3acptTTcSKEUDgRQogSppiEU+GNmDiDPc2Ds9dy4310uHT/iNiUhgKaMmcDyG/SrYcyqJ8XBOQDIuyWpsn3dUukUhaz9hwnpa+F7DjZDKlQuY5sv1T231bEfb90HKvucQLyLvH+vmInOrKXa5r5800IOXahcCKEEAWEQ0Ej4rhYJLko4fOiX8LUeG+jfyRSpc7ZAPJlYU7mBanspxHldtaFk/p11JjS/ez1OKkULNUmx8ni+5LryVIVUAFkw0OEc2S7x6lKbRw5kC+/K+YQH8idAGmNhFGhKFmQEHJ0w28CQghRhDiDfaDARiyeShuxx170S9juH/FosKhwa6z3OKkv1QPyLotlwZK7XXVFEMGAGiFZEQygMufmWU4Z9CCUwRTPblNIqur3EoiQBzvHKOBNqZ4IdOmIxpFMZ0ZdLwQVE/UIIQIKJ0IIUYQxBLdAqd4h6bJ2D4ZpyuVYVs7mix4n5cLJpmARzlRQccmgke5nMY7c6OlR/HqI19d2KINCwVIVsh+WIYSN6jQ7Y1CzDcdJ09S+HgJxAkPXzZ9PgXCOOcOJECKgcCKEEEUYpT99Q9B13XSdnLTnheMUDGhGipuds/mqe0dqbTgKQN7ZqKlQNy8IcOI4Zdehqr9JIDb8dgcCq0oYBLJhGfl12HPgvBKSlgJMJFdU5bEhmDpGX6Ku64ZzzP4mQoiAwokQQhQxfVJWEMUS6VFDNQ9IDehTG73ZiImz+ZbCITxynGSHZaR4LMSQB7HXgJMeJ/UpcoA9oQDk11ur2GExes8sOHDpjJ5fh3LHKdurFLUhnFS7XgI5pOXAiICIjmgcw8ls+d7MphpPnp8QcvRB4UQIIYqY21pr/Pu97pjpOrkB3YtSPcDeJj0fDqG26V6It4xurUxOjt9WSa1d4ZTwqudLzLWyJ5xU9xbZcZzktaoWLUaPkyVxn72N6hlOArl3aWRf4q7O/Od3TkstCCEEoHAihBBlzGmJGP/e3WkWTvtzpXqTaiqUb4oFInnMUo+TZ+EQ9kIqvIjfBvKlbnZT9VQ7X07j2VU7XzU2hKQ5mr18DpxXrqi8FlGqOtJxkk98zJU+14SQY5sJK5wGBgbwla98Be3t7aiqqsLy5cvx61//2tJ916xZA03TCv536NAhj1dOCDlamT6p2khk29VV2HHyor9JIDaB/ZYa75Om+6giIgkPKwEAecdJsWCxOwDX456ecsaRy49nxfnyYqaVwE44RP9Q9jb11eqjyAXTjL5Ec4/T7tzntyKoYdokpuoRQrJ4cxpnHHD55ZfjlVdewZ133on58+fjV7/6Fa666ipkMhl88pOftPQY999/PxYuXGi6rLm52YvlEkImABXBAGY21WB3VwzvjRROxgwn7zZhDbkNZv/Q2GVQyXTG6N/wKlUPsOay5EMZFDsskuOUyegIlIgYN1L1POotsiKcUukMEqmM6X6qMEoGLbwnUQ9jwA0hmUgjndHHjH4/kjuOGzwUTlMbqrD1UNSY2SQQpXozm2qUxdMTQo5+JqRweuyxx/Dkk08aYgkAzjnnHOzZswe33HIL/uzP/gzBYOk/josXL8Ypp5zi9XIJIROIOS212N0VM85YA9lm+709gwDyARJeIDaYR0oIJ3kTr3xjbHeelEflWLJjM5xKlxQiXgm4iI25VnJwg2rHSTiLVt4TWVypfl9khzOWSKF+jB47P4TT9EnZ4Ie93TGTwN7dNQDAXH5LCCETslTvkUceQSQSwZVXXmm6/Nprr8WBAwfw0ksvlWllhJCJzuzmbCP5e7mNGADs7Rk0ghIWTKnz7Lll4TRWop3JUVBeqic7TuUTTrJzVMpl0XXd+3AICymDcmS56l4rO/HsAz70OAFjl+tlMjr6h70XTvNzn8dYIo33e7PltPKJDjnwhRBCJqRw2rJlC0444QSEQuYv/KVLlxrXW+Hiiy9GMBhEU1MTLr/8csv36+jowFtvvWX6b8eOHfZ+CULIUcmc3EYrnsrgYH+2/GfrwX7j+oUeCifRC5LO6GM6HF6WYtkNhxjwKKSiWnKYhkq4PUPJNISm8apELpXRkUhnxryt3I+l2nGy01vklyM5VohJNJ4y3hMvhdMJ0ufxnUPZz+n+3iEk09knZ6IeIURmQpbqdXd3Y+7cuaMub2pqMq4fiylTpuAb3/gGVq5cifr6emzevBl33nknVq5ciU2bNmHZsmVj3v+ee+7BHXfc4fwXIIQctcyVNlo7OgYwrbEa7xyKAgA0DZg/2XvHCci6TsU2vf1SFLTqTWmdDeGUzuiGE6fa+TI5TiUCEQZMQkG102N2vsKh4o8vJ96pFnBGDHgi63yNNVDW9Hoofl/k0rz+MSLJ5T49L8Mh5kvCaevBKD68aAp2dg4YlwkHmRBCgKPAcdq4cWPRhLuR/73xxhvG/cb6o1BqAvmFF16I7373u7j44otx9tln48///M/x+9//Hpqm4bbbbiu55htvvBFbtmwx/ffb3/7W6q9MCDmK+cDUeuPfr+3pBZB3nGY11SgvfZKRRdBYARFyD5Rq4VRro1RvwENno0Z6vFLJeqYSOdUx4DZeD7NwUizgcuvQ9dKR5F6+LyZxP2jtGB2rD8ot9VUVRt/h1pzjJD63mgacMNW7Ex2EkKOPce84LViwAD/96U8t3XbmzJkAssl3hVylnp4eAHnnyQ6zZ8/GmWeeiRdffLHkbdva2tDW1mb7OQghRz+Taisxf3IE7x4ewMu7s99DW3OO08Ip9WPd1TUjHadieCmcaiqD0LTsBr2U4+TlBt1Oj5NfPT2lnC9P5yeNCO0Y6/HFOoIBDeGQ2vOr4+EYHcnCKfV4v3cI23Kf05d3Z/cKCybXobGm0tPnJoQcXYx74TR16lR87nOfs3WfJUuWYP369UilUqY+p82bNwPIpuU5Qdd1BALj3qQjhJSZ0+Y04d3DA/jj3j70xhJGo/lCj89eW92UelkGpWkaaitDGIinSgqnmIclYXbS/WQHxsuer1KOU1S6vs5DARcdTmHyGBremGlVGSxZoWGXegfHqNfC6YSpdXjqncPY3R1D32ACb+zrAwCsmGP/JCshZGIzIVXAZZddhoGBATz00EOmy9euXYv29nasWLHC9mPu3r0bmzZtwsqVK1UtkxAyQVkxJzvvLZ7K4GfP7zIu9zIYArB/Nl/T1G/QAetDX+VwgHKltwHmdapPs5MGApdyvsZJ2qEQcHUelMjVS7+XZcepxnvHCci6pD/7/W4jxGPFXM5tJISYGfeOkxMuuugirF69GjfccAP6+/sxb948rF+/Hk888QTWrVtnmuF0/fXXY+3atdi5cydmzZoFADj//PNx9tlnY+nSpUY4xN/93d9B0zR85zvfKdevRQg5SjhNOlN99zM7AQDVFUGcPrfF0+c1Nd5b2JTWhUMlB8M6oTYnPuyU6qkWcHXh/GsRLeV8JTwsGZR7rUq+Hvn3zKvBs9nnsSYkaxWLSAAIBQOIhLOO5FjhEH6W6p0xrxlVFQEMJzP452fyCbinzqbjRAgxMyGFEwA8/PDD+MY3voHbbrsNPT09WLhwIdavX49PfOITptul02mk02nTfI0lS5bg3//93/HDH/4QQ0NDaGtrw7nnnotvfvObmD9/vt+/CiHkKGNyfZXR5yT4+CnTPT9zXlcVMvqLrAgnr9YjNumlHBYvS/XkTb8dx8lT56uUcJIdOMUhFVZjwAHvhgELGqorMBBPWXKcggHN5Np5QWNNJT528nSse3GvcdnCKXVorQt7+ryEkKOPCSucIpEI7rrrLtx1111j3m7NmjVYs2aN6bIf//jHHq6MEHIscOcVS3H5PS8AyJbEXXvGHM+fMxDQUBcOoX/Y2qbUqzP5YpNeMlXPQ6EQCgZQXRHEUDJtcnIKrkMSeKo36XI6Xqk0O+GMRTxwAu2U6nk1lFhQX12B/X1D1sR9dYXyPqtCXHfGHEM4aVr280sIISOZkD1OhBBSbk6aOQnrP78Si6fV42ur52O2T4M0hYtkpfHeK+EkRJCtMATFjhMgDX0tFQ4h9zh5NADXyjq8GgY88jGtllB6JZwaqrOPW05xP5K5rRF8dfV8LJ5Wj19/fiWWz2j05XkJIUcXE9ZxIoSQcnP6cc34r5vO8vU5G6orsA9D5XWcchvu0iVh3pXIAdm+qc5ovOQ6BnI9TpXBACoVx2+HQwEEAxrSGd260+OBiLQj4PI9Th45TlWlxb24zsvhtyO5+bzjcfN5x/v2fISQow86ToQQMoEQYmjsTWnKdFvViA13qblFYgMfDgVQEVT/58i64yR6etT30mTj2bOPa3XwrBdOT/Y11kzPU451ANaOUeGK1nsgIgkhxCkUToQQMoEotSnVdT2/KfWhx0kO3hmJ2KB7UaYHSCEVFp0vrxyWfFiGNcHixeuhaZql10PX886Y18Kpf6j4OvqHvRX3hBDiBAonQgiZQIgyqP4im+PhZMaYU+N1qV4yrSOeyhS9ndjAl1uwiF4r1QEVglqLAs7LHifTOsZ4PYaSaWR08+1VI467oWQaiSLHh989ToQQYgUKJ0IImUCUcpz8mI8jJ9ON1dfjdUmYcL5K9ThFh4UD5806hIMULZnu5/HrYUE4yddFPChdBMwx+IWOU13XKZwIIeMSCidCCJlAiPK7RCqD4eTonhp5oyoPzFVJRHpcK5t0r4RCnVXHaViUyHnzeojHLRlSIRwnj0oXhYAby/mKydHsHjtOQGHhFEukkc7ZXhROhJDxBIUTIYRMICbVVBr/7oklRl3fP+y941Rncdiqn6VpY/Va5YWTx47TGK9FJqMb6X7lLNWLDnsvrOtLCKde6biVj2dCCCk3FE6EEDKBaI6MLZyODHovnOQNtyzURuJl/Lb8uOnM2L1WQix4J5yE41T8tRhMpiG0ndelemOVT8qBDV6Fh5Q6Prql41Y+ngkhpNxQOBFCyASiuTa/0ewaiI+63o8eJ7lXaKzkNK/T2+rCpZ0vXdc9L9UTkdrFAjsAc/mc16V60TGEk6mU06OeL/m46y/gOHVLx21TLYUTIWT8QOFECCETiOZI2Ph3QcfJD+FUNfbGWBD1KRwCKF6eNpRMI5Xrp/G6VC+RyiCeKjzLaUAKjvCsVK+ydI9Tvw+leqV6nEyOU2141PWEEFIuKJwIIWQCIZ+h7x4YLZz6pI2qV0JBLvEqVqqXSGWMKGrvStOkkIoiYkF2ovzo6SnmfMmXezbXKve4Q8l8+MJI+k2Ok/fCqW+wkOPEUj1CyPiEwokQQiYQ9VUhVAQ1AOYz9wJRBjWppgKhoDd/AurCIWjZJRR1nOQ+G6/nOAHFo8DlviOvHSdgrNcj70TJgk8l8utRTEgKoRsMaKZYeZVUhgLGa9JdoJy0J5a9LBwKoMajNRBCiBMonAghZAKhaZrhOokNqIzoe2qJeFcCFQhoRn9Rsb4eP0oGZcFSXCh47zjVhUs7Tn6U6llxAkVPWn1VCJpQvx7Qmjv+ugq4okLwt0TCnq6BEELsQuFECCETDNEXUqhUT2xUvRROQH6TXsxh8UM4mRyWIj1OfpTIWYln92MdpXqL5Mu9KtMTiOOvs4DjJI5bBkMQQsYbFE6EEDLBEH0hY5Xqed07ItybYs6G3GvVUOPVIF4rwkku1fN2AO7I55OR1+eV42RFOIn3yyv3TSCOv0LJjyLUhMKJEDLeoHAihJAJhthwdhcs1fPLccqV6hWJI/fbcSrm9MjrK6fjJJcSetXzVSqUAcg7hF69JwJx/HVFCzlO/oh7QgixC4UTIYRMMESpXs+IUr3hZNpwNlrrPBZOOceiVEkYADR6tEkPhwJGUIYVx8mzga8WeovE+sKhACpD3vxptuY45XqcPJrhJBDCqX84ZaQrAtm5WsIpbabjRAgZZ1A4EULIBEOcqY8l0hhO5tPaOqWz+y1el+pVj12q50fstaZphutUrNdKOEABDZ6lyFlyvowhvN4JlsYaC8JpyJ9SvZY6KTZfckZjiTTiOSHV7LErSgghdqFwIoSQCYZ8pl7uc5L7Sbwu1WuwGA4RDgVQVeFd5HRjTaXp+UYiHKdI2LsUuWAgL+CKCacjQ9n3ycsSueqKoOHAjZdwCADoiuaPUdklZY8TIWS8QeFECCETDPMQ3Lj07/ym1PMep5xjEUukkUpnRl3fN+i9UJAfv7hwEk6Pt+sQTlLRsIxcz5EQel6gadqYr8dwMu/21HvofAEjhJN0jHbF/HNFCSHELhROhBAywZBLnIo5Tp6n6lWPXZ52xKcQAlGeVjQMwYcSOfnxi6XqGcLJ49djrJh4+X3yPhwif/zJkeRmx4mleoSQ8QWFEyGETDDkTamcWuZnqZ7cI1PIZRHCqdGjKHJBKcfJr/ht4WgVL9XLCUmfXo++odFR9f0+BGUIijlOcr8TwyEIIeMNCidCCJlgTK6vMv59oG/Y+LeIIq8LhzztKwLMG+9CouVILgbcc8dJCIXB0UIBkEv1/HKcxhZOjdXeioWxhKQpsMNjIVkbDqE6dwzKPU77e4cAAJoGtNXTcSKEjC8onAghZIJRVRE04sb39Q4al4sz+y0eR5ED5h6ZQrOc+n0KIWjI9Qz1D6eQzuijrhelc16vo95wnEYLlmQ6Y8SRl7Pn64gp6dBbIQnkk/Vkl+n9nHCaXFeFcMhbcU8IIXahcCKEkAnIjEnVAID3CwknH5ru5ZKzQqV6foVDyD1DY/X1lNNxMs208rhUT7weRwr0fPVLa/PacQKkIbhSqZ4Q+jOaqj1/fkIIsQuFEyGETECmT6oBAOzrGTIuO9yf3aB6PfwWGNHjNEKwJNMZxBLZ+VJel6bJQqRvxDoyGd1wgLwXTvm5Vrpudr7k4Aq/er6i8RQyIxw4+X3yWtACQGtOOB08ki8nFY7TjNzxSwgh4wkKJ0IImYCIM/aH+oeRSmeQSGWwtyd7Nn92c63nzz9Wj5N5g+6tYDEJpxF9Tv3DSQjtMMnDGHAAaKrNriOZ1o2yPMERKajBa8Ei3hddH+1+ye+T1/HsADCnJXsc7usZRCqdQTyVxqH+rIiaPomOEyFk/OF9ETMhhBDfEY5TOqPj4JFhxFMZo8dHbFi9pLYyiMpgAIl0Bj0jBIu8QfcrRW7k8wJAT8y/YauyMOuNJU3CxFyq5084BJBN1pNf/97c61FVEUBVhffnVcVxmEzrhtMkzLjpTXScCCHjDzpOhBAyAZFLnfb1DGJX54Dx89zWiOfPr2maMStKTk0DzCVz3och5IVIOYWTPDdLDkMARpTq+RQOAYx+PcTMr5ZIGJqmeboOwHwc7uoaMAWZ0HEihIxH6DgRQsgERN54vt87hF7J9Tmu1XvHCciKhYNHhkcJhSM+Cidzqd44cZxGOHDl6HECRgsnEdLQ7PGML8Fc6Tjc1RlDTWV+S8IeJ0LIeITCiRBCJiDtjdXQtGzp077eQXTkgiEm1VR4Xg4mEKlp3QMjeotMwsnH0rQyCqfm2rwYGfl6CAdO07zvLZLf+9HCKbuuVh9SF4HsgNu6qhCiwyns6ooZblswoGFqQ1WJexNCiP+wVI8QQiYglaEApuQG4e7rGcSurmypnh9legIhFuS4aSDfSwN477BUBAOIhLPnCPuGzIJF7r3y3HGqlXqJRvZ8DeYHEwcD3pbIya9372ARx6nWH8dJ0zTjeNzVOYB9uT6nqQ1VCAW5PSGEjD/4zUQIIROUeW3ZTekr7/ViZ2cMgD/BEAIxL6p7IGGK4O6IZjfowYCGJh/cr2JDX3sG8mEIcpmYF0TCIVTmxEB3rHBYhh9OYHNtJUT7Umd/PgY8k9ENB67ZJ8cJAObmjsednTG8srsHQP64JYSQ8QaFEyGETFDOXdgGANjfN2Rsiuf61N8E5Ev1EumMabiqEE4tkUoEPHZYAEk4jSzVyzk9fog3TdMM16k3VrhUz2v3DQBCwQCac+6aeB+ArHgTqYstPvU4AXnh1BmNG1Hk5+WOW0IIGW9QOBFCyARl9Qcmj7psybQG357flCQnleuJDXtbnT99LEKQjByAK8Rkk08OS1OuBK5npHDKCTo/hs4CQGvudZeFk1xO6afjtGT66OPx/ALHLSGEjAconAghZIIyfVKN0ecEAKfOnoQz57X49vyyc9ElBSJ05JyFtjp/nA1DOI3oLRLOj9fDbwViCO5I4eRnqR4ATK7Pvu4d0Xypnvz+tProOK2a34qTZjYaP89oqsbUBkaRE0LGJxROhBAygbl6xUzj37d/dJEv83kExRynTuE41fuzQRfCaGRvkfi52eNgCEExx0m8NpN8KNUD8oL1cH8xx8k/4aRpGu746GLj50+cOnOMWxNCSHlhHDkhhExgPn/2XAwl01g6vRGL2v0r0wPMzoXYmCfTGUOw+FWqNznnuvUNJjGcTKOqIghAcpz8Ek41ox2nwUTK6P+aXO/P6yFe9+6BONIZHcGAZhK2LT6W6gHZcr1/ufokbDlwBNefOcfX5yaEEDtQOBFCyASmqiKIWy9cWJbnlgWJKAXrlPpq/HKc5HLFw/3DmNVci+FkGrFEGoD/jlP/cArJdAYVwQAOHcmXy03xSzjlXveMnhVPbfVVhpgNaP6VDMpctGQqLloy1ffnJYQQO7BUjxBCiCdUBANGf5FwnORAAt8cJ2mYqhAqsuvjm+Mkz3LKPf8hKRJ8ik9DX+XeMvF+iPenqbbS81lShBBytELhRAghxDNEQER3znHqkISCX+EQspMjhIosnPx2nIB8FPph6fXwrVRPeh4RECEcQT+jyAkh5GiDwokQQohnCFFS0HEqU6keYBZOsqDxkiZJoInhu4eO5F+PcjhOIiBCvD9+RpETQsjRBoUTIYQQz5jWmI2W3tMzCCAvnDTNP3ejvjqEqorsnzshVOTeIr/CEFolwXIw9/xCyEXCIUTC/rQdy+voyAmnvd3Z94dR4IQQUhwKJ0IIIZ5xXFsEQDYU4shQEp250rCmmkpUBP35E6RpmuE6CaGypycGIBuGMH1SjS/rmD6pGiINXghJIeAm++S+AUA4FDR6zzqiw+iNJYxwiHm594sQQshoKJwIIYR4xnGt+Y34zs4BozSs1af+JoHoHxI9Tnskh6Uy5M+fwqqKoCHg9nbHTOvxq0xPMLkuLyR3dg4Yl89rpXAihJBiUDgRQgjxDNnB2NExgHcO9gMA5rbW+rqOqTlhIhyevTnHZ1azP26TYGZT9vmE4yQcML+CIQSzW7LreOdgFDs68sLpODpOhBBSFAonQgghnjGruQahXLz1izu7jd6epdMbfV2HiCTviA4jk9ENx8lv4SSeb2/3INIZ3ej58muGk0C8/vv7hvDy7h4AQGUwgBmT2ONECCHFoHAihBDiGRXBgCEWHv7jfuPypdMbfF2HECbJtI7d3TEcGUoCAGY2+et8zWrOPl93LIE93TGkM3p2fT6X6smvv3hf5rTUIuRT3xkhhByN8BuSEEKIpxQKHFg8rTzCCQBe2Nlt/LtcpXoA8Idd+XX4Xaq3dFrjqMuOa/NXRBJCyNHGhBRO0WgUt956Ky644AK0trZC0zTcfvvtth6jo6MD11xzDVpaWlBTU4PTTz8dGzZs8GbBhBAygRkpnOa21qK+qsLXNSycWm/8+5HX3zf+LQsZP5CF2sOv5x24hVPqfF1HQ00FZo8QjQyGIISQsZmQwqm7uxv33nsv4vE4Lr30Utv3j8fjOO+887BhwwbcddddePTRRzF58mRceOGFePbZZ9UvmBBCJjAnzphk+nmZz/1NADC7ucaI/H59b59xue89TlJp4Gt7egEA7Q1Vvgs4AFgy4n04ceakwjckhBACYIIKp1mzZqG3txfPPvssvv/979u+/89//nNs2bIFv/nNb3D11Vdj9erVePDBBzF//nzceuutHqyYEEImLued0IZrPjjb+HnFnCbf16BpGlbObTZd1lRbiTqfna+GmgpjhpJg5dxmaGLAk4+snJt/H647Yw4+tKDV9zUQQsjRhD9jyn3G7R+gRx55BAsWLMDpp59uXBYKhfCpT30Kf/3Xf439+/dj2rRpbpdJCCHHBJqm4faPLsLqD0zGzs4BXHHy9LKsY+XcZjz6xgHj5w/NL49Q+ND8VvxWWsfK45rHuLV3XHnyDKQzOua1RvDBeS1lWQMhhBxNTEjh5JYtW7bgrLPOGnX50qVLAQBvvfXWmMKpo6MDnZ2dpst27NihdpGEEHKUcca8FpxRxg36SMfp/354QVnW8X8/vMAknE6fWx7hVBkK4DOnzy7LcxNCyNEIhVMBuru70dQ0upREXNbd3T3qOpl77rkHd9xxhydrI4QQ4ozZzTVYMq0Bm/cfwTc+cgLaG8szs2j6pBr85UULcefjW7FsRiOmc3YSIYQcFYx74bRx40acc845lm77xz/+EcuXL1fyvGOV+5UqBbzxxhtx5ZVXmi7bsWOHo6AKQgghatA0DeuuX4F9vYO+x6GP5IurjsOZ81owY1JNWfqbCCGE2GfcC6cFCxbgpz/9qaXbzpw5U8lzNjc3F3SVenqy09ULuVEybW1taGtrU7IWQggh6mioqUBDTXlFk6Dc4o0QQog9xr1wmjp1Kj73uc/5+pxLlizB5s2bR10uLlu8eLGv6yGEEEIIIYSUlwkZR+6Wyy67DFu3bsVLL71kXJZKpbBu3TqsWLEC7e3tZVwdIYQQQgghxG/GvePklMcffxyxWAzRaBQA8Pbbb+PBBx8EAHzkIx9BTU122OD111+PtWvXYufOnZg1axYA4LrrrsPdd9+NK6+8EnfeeSfa2tpwzz33YNu2bXjqqafK8wsRQgghhBBCysaEFU433HAD9uzZY/z8wAMP4IEHHgAA7N69G7NnzwYApNNppNNp6Lpu3DYcDmPDhg249dZbcdNNN2FwcBDLly/H448/jlWrVvn6exBCCCGEEELKz4QVTu+9956l261ZswZr1qwZdfnkyZOxdu1atYsihBBCCCGEHJWwx4kQQgghhBBCSkDhRAghhBBCCCEloHAihBBCCCGEkBJQOBFCCCGEEEJICSZsOMR4Ix6PAwB27NhR5pUQQgghhBBCxL5c7NNLQeHkE/v27QMAXHrppeVdCCGEEEIIIcRg3759OOmkk0reTtPlAUbEM/r6+vDss89ixowZCIfDZVvHjh07cOmll+K3v/0t5s2bV7Z1kPEHjw0yFjw+SDF4bJCx4PFBijEejo14PI59+/Zh1apVaGxsLHl7Ok4+0djYiEsuuaTcyzCYN28eFi1aVO5lkHEIjw0yFjw+SDF4bJCx4PFBilHuY8OK0yRgOAQhhBBCCCGElIDCiRBCCCGEEEJKQOFECCGEEEIIISWgcDrGaG1txbe+9S20traWeylknMFjg4wFjw9SDB4bZCx4fJBiHI3HBlP1CCGEEEIIIaQEdJwIIYQQQgghpAQUToQQQgghhBBSAgonQgghhBBCCCkBhRMhhBBCCCGElIDCaYIwMDCAr3zlK2hvb0dVVRWWL1+OX//615bu29HRgWuuuQYtLS2oqanB6aefjg0bNni8YuIXTo+Nhx9+GFdddRXmzZuH6upqzJ49G1dffTW2b9/uw6qJX7j57pD5m7/5G2iahsWLF3uwSlIO3B4bjz76KFatWoX6+nrU1tZi0aJFuPfeez1cMfETN8fHM888g9WrV6OtrQ2RSARLly7FP/7jPyKdTnu8auIH0WgUt956Ky644AK0trZC0zTcfvvtlu8/rvelOpkQrF69Wm9sbNT/3//7f/rTTz+tf+5zn9MB6L/85S/HvN/w8LC+ePFiffr06fq6dev03/3ud/oll1yih0IhfePGjT6tnniJ02PjtNNO0z/60Y/q9913n75x40b9F7/4hX7CCSfokUhE37Jli0+rJ17j9PiQ+eMf/6iHw2F98uTJ+qJFizxcLfETN8fG97//fT0QCOg33nij/vjjj+tPPfWU/s///M/6P/3TP/mwcuIHTo+PJ598Ug8EAvqHPvQh/be//a3+5JNP6jfddJMOQL/55pt9Wj3xkt27d+sNDQ362WefbRwX3/rWtyzdd7zvSymcJgD//d//rQPQf/WrX5kuX716td7e3q6nUqmi97377rt1APoLL7xgXJZMJvUPfOAD+mmnnebZmok/uDk2Dh8+POqy/fv36xUVFfr111+vfK3Ef9wcH4JkMqkvX75cv/nmm/VVq1ZROE0Q3Bwbr776qh4IBPQf/OAHXi+TlAk3x8fVV1+th8NhfWBgwHT5BRdcoNfX13uyXuIvmUxGz2Qyuq7remdnpy3hNN73pSzVmwA88sgjiEQiuPLKK02XX3vttThw4ABeeumlMe+7YMECnH766cZloVAIn/rUp/Dyyy9j//79nq2beI+bY6OtrW3UZe3t7Zg+fTr27dunfK3Ef9wcH4I777wTPT09+N73vufVMkkZcHNs/PM//zPC4TBuuukmr5dJyoSb46OiogKVlZWorq42Xd7Y2IiqqipP1kv8RdM0aJrm6L7jfV9K4TQB2LJlC0444QSEQiHT5UuXLjWuH+u+4naF7vvWW28pXCnxGzfHRiF27dqFPXv2YNGiRcrWSMqH2+Pj7bffxne/+138y7/8CyKRiGfrJP7j5th47rnncMIJJ+Chhx7CggULEAwGMX36dPzlX/4lEomEp+sm/uDm+PjiF7+IRCKBm2++GQcOHEBfXx9+8Ytf4JFHHsGtt97q6brJ+Ge870spnCYA3d3daGpqGnW5uKy7u9uT+5Lxj8r3N5VK4frrr0ckEsFf/MVfKFsjKR9ujo9MJoPrrrsOl19+OT7ykY94tkZSHtwcG/v378f27dtx88034+abb8ZTTz2Fa665Bj/84Q9x7bXXerZm4h9ujo8VK1bg6aefxiOPPIJp06Zh0qRJuPbaa/G9730PX/va1zxbMzk6GO/70lDpm5CjgbEs0VJ2qZv7kvGPivdX13Vcf/31+P3vf4+HHnoIM2bMULU8UmacHh//8A//gO3bt+M//uM/vFgWGQc4PTYymQyi0SjWr1+PT3ziEwCAc845B7FYDD/5yU9wxx13YN68ecrXS/zF6fHx2muv4bLLLsOKFSvwr//6r6itrcXTTz+Nv/mbv8Hw8DC++c1verFcchQxnvelFE4TgObm5oIKvKenBwAKKncV9yXjHxXvr67r+NznPod169Zh7dq1uOSSS5Svk5QHp8fH3r17cdttt+HOO+9EZWUl+vr6AGRdyUwmg76+PoTD4VE9DOTowe3flUOHDuHDH/6w6fKLLroIP/nJT/D6669TOB3luDk+/vzP/xyTJ0/GI488gmAwCCArrAOBAG6//XZcffXVmDt3rjcLJ+Oe8b4vZaneBGDJkiV45513kEqlTJdv3rwZAMacq7JkyRLjdnbvS8Y/bo4NIC+a7r//fvzsZz/Dpz71Kc/WSvzH6fGxa9cuDA0N4ctf/jImTZpk/Ldp0ya88847mDRpEv7qr/7K8/UT73Dz3VGoPwHIfp8AQCDArcfRjpvj44033sDJJ59siCbBqaeeikwmg3feeUf9gslRw3jfl/LbawJw2WWXYWBgAA899JDp8rVr16K9vR0rVqwY875bt241JeCkUimsW7cOK1asQHt7u2frJt7j5tjQdR2f//zncf/99+Nf//Vf2ZswAXF6fCxfvhzPPPPMqP+WLVuG2bNn45lnnsGXvvQlP34F4hFuvjuuuOIKAMDjjz9uuvyxxx5DIBDAqaeeqn7BxFfcHB/t7e149dVXRw27/cMf/gAAmD59uvoFk6OGcb8vLWsYOlHG6tWr9UmTJun33nuv/vTTT+uf//zndQD6unXrjNtcd911ejAY1N977z3jsuHhYX3RokX6jBkz9F/+8pf6k08+qV922WXjZtAYcY/TY+NLX/qSDkC/7rrr9D/84Q+m/15//fVy/CrEA5weH4XgHKeJhdNjI5FI6CeddJLe0NCg33XXXfqTTz6pf/3rX9eDwaD+pS99qRy/CvEAp8fHP/7jP+oA9Isuukj/7W9/q//ud7/Tv/71r+uhUEg///zzy/GrEA947LHH9AceeEC/7777dAD6lVdeqT/wwAP6Aw88oMdiMV3Xj859KYXTBCEajeo333yzPmXKFL2yslJfunSpvn79etNtPvvZz+oA9N27d5suP3TokP6Zz3xGb2pq0quqqvSVK1fqTz75pI+rJ17i9NiYNWuWDqDgf7NmzfL3lyCe4ea7YyQUThMLN8dGd3e3/oUvfEGfPHmyXlFRoc+fP1//+7//ez2dTvv4GxAvcXN8PPTQQ/qZZ56pt7S06LW1tfqiRYv073znO6OG4pKjl7H2EOJ4OBr3pZqu54qOCSGEEEIIIYQUhD1OhBBCCCGEEFICCidCCCGEEEIIKQGFEyGEEEIIIYSUgMKJEEIIIYQQQkpA4UQIIYQQQgghJaBwIoQQQgghhJASUDgRQgghhBBCSAkonAghhBBCCCGkBBROhBBCCCGEEFICCidCCCGEEEIIKQGFEyGEEEIIIYSUgMKJEEIIscjQ0BBuv/12zJs3D1VVVQiHw1i2bBnWrVtX7qURQgjxGE3Xdb3ciyCEEELGO1u3bsXFF1+MnTt34pRTTsHxxx+Pd999F6+99hoA4Je//CU++clPlnmVhBBCvILCiRBCCCnBwYMHsXTpUgwPD+M3v/kNLrroIuO6b37zm/jud7+L4447Djt27CjjKgkhhHgJhRMhhBBSgo997GN46KGH8POf/xzXXXed6brBwUE0NjYimUzi4MGDmDJlSplWSQghxEsonAghhJAx2LlzJ+bNm4dFixZhy5YtBW8zbdo0HDhwANu3b8e8efN8XiEhhBA/YDgEIYQQMgYPP/wwAOCKK64oeL2u6+jp6QEAuk2EEDKBoXAihBBCxuCpp54CAJx11lkFr3/llVcwPDyMBQsWIBKJ+Lk0QgghPkLhRAghhIzBq6++CgBobm4ueP1DDz0EAPjoRz/q25oIIYT4D4UTIYQQUoRdu3YZZXh79uwZdf3OnTtx9913IxwO48Ybb/R7eYQQQnyEwokQQggpgnCbAOCHP/whhoeHjZ/37NmDK664ArFYDN/+9rcxe/bsMqyQEEKIX4TKvQBCCCFkvCKE0w033ICf/exnmD9/Ps444wz09PTg2WefRTwex1/8xV/g1ltvLfNKCSGEeA3jyAkhhJAinHvuuXjmmWfw4osvIhqN4pvf/CbefPNNhEIhrFixAl/96ldx4YUXlnuZhBBCfIDCiRBCCCmAruuYNGkSYrEYotEoqqqqyr0kQgghZYQ9ToQQQkgBtm/fjiNHjmDRokUUTYQQQiicCCGEkEKI/qZTTjmlzCshhBAyHqBwIoQQQgoghNPJJ59c5pUQQggZD7DHiRBCCCGEEEJKQMeJEEIIIYQQQkpA4UQIIYQQQgghJaBwIoQQQgghhJASUDgRQgghhBBCSAkonAghhBBCCCGkBBROhBBCCCGEEFICCidCCCGEEEIIKQGFEyGEEEIIIYSUgMKJEEIIIYQQQkpA4UQIIYQQQgghJaBwIoQQQgghhJASUDgRQgghhBBCSAn+P95SdnyjGoQFAAAAAElFTkSuQmCC\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "Nr = 512\n", - "\n", - "rho0 = 0.5\n", - "Lrho = 0.2\n", - "n_ord = 4\n", - "freq = 20\n", - "rho = np.linspace(0, 1, Nr, endpoint=False)\n", - "dr = rho[[0,1]].ptp()\n", - "\n", - "fu_test = np.exp(-((rho-rho0)/Lrho)**n_ord) * np.cos(2*np.pi * freq * rho)\n", - "df_analyt = -2*np.pi * freq * np.exp(-((rho-rho0)/Lrho)**n_ord) * np.sin(2*np.pi * freq * rho) \\\n", - " - np.exp(-((rho-rho0)/Lrho)**n_ord) * np.cos(2*np.pi * freq * rho) \\\n", - " * n_ord * ((rho-rho0)/Lrho)**(n_ord-1) / Lrho\n", - "\n", - "plt.figure(dpi=120, figsize=(8,3))\n", - "\n", - "plt.plot(rho, fu_test)\n", - "plt.xlabel(r'$\\rho$',size=13)\n", - "plt.ylabel('Signal',size=13);" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "b27c6492", - "metadata": {}, - "outputs": [], - "source": [ - "alpha = scf.jn_zeros(0, Nr)\n", - "k_fft = 2 * np.pi * np.fft.fftfreq(Nr, dr)\n", - "\n", - "err_fdtd_val = []\n", - "err_fft_val = []\n", - "err_dht_val = []\n", - "\n", - "for d in d_ax: \n", - " rho = np.linspace(0, 1, Nr, endpoint=False)\n", - " dr = rho[[0,1]].ptp()\n", - " rho += d * dr\n", - "\n", - " fu_test = np.exp(-((rho-rho0)/Lrho)**n_ord) * np.cos(2*np.pi * freq * rho)\n", - " df_analyt = -2*np.pi * freq * np.exp(-((rho-rho0)/Lrho)**n_ord) * np.sin(2*np.pi * freq * rho) \\\n", - " - np.exp(-((rho-rho0)/Lrho)**n_ord) * np.cos(2*np.pi * freq * rho) \\\n", - " * n_ord * ((rho-rho0)/Lrho)**(n_ord-1) / Lrho\n", - " \n", - " iDHT = scf.jn(0, alpha[None,:] * rho[:, None])\n", - " DHT = np.linalg.inv(iDHT)\n", - " iDHT = scf.jn(1, alpha[None,:] * rho[:, None])\n", - " \n", - " df_dht = iDHT.dot(- alpha * DHT.dot(fu_test))\n", - "\n", - " err_dht_val.append(np.abs(df_analyt - df_dht).mean()/np.abs(df_analyt).mean())\n", - "\n", - "df_fdtd = np.gradient(fu_test, dr)\n", - "df_fft = np.real(np.fft.ifft(1j * k_fft * np.fft.fft(fu_test)))\n", - "\n", - "err_fdtd_val = np.abs(df_analyt - df_fdtd).mean()/np.abs(df_analyt).mean() * np.ones_like(d_ax)\n", - "err_fft_val = np.abs(df_analyt - df_fft).mean()/np.abs(df_analyt).mean() * np.ones_like(d_ax)" - ] - }, - { - "cell_type": "markdown", - "id": "604a3566", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "### Errors for derivatives computed via FD, FFT and DHT" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "b5a23697", - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "outputs": [ - { - "data": { - "image/png": "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aGio7rnnnlq5yJ6py5zce++9qlevnu6//34tXLhQixYtcthuGIaaN2+uWbNmmdktAAAAgFpi/vz56tixo0NZUFCQ/f833HCDXn31VUkXV2jcv3+/PvnkE9144426/fbbFRMTIw8Pj2qNubJMX1NyxIgRGjBggD744AN9/vnnSkxMVGZmppo2baqbb75Zzz77rJo2bWp2twAAAABqgfDwcPXo0eOS2/39/XXttdfanw8aNEgPPvigZsyYoZkzZ+qZZ57RSy+9VB2hVplp0wh/q0GDBvrb3/6mjRs36ty5cyooKNCxY8f07rvvkmgBAAAAqLAZM2YoLCxM77zzjvLy8lwdTrlUemTrgQce0J/+9CcNGjTIzHgAAAAA/I+Zq/Zq38lMV4chSeoUVF/P3hpW6dfbbDYVFRU5lJX3Js633nqrZs+erV27dqlPnz6VjqG6VDrZmjt3roqKiki2AAAAACfbdzJT21PSXB2GKX47RbBEYWFhuRKuVq1aSZJOnjxpelzOYPo1W5J0++23695779WwYcOc0XyN5+vr6/D8woULeuWVV/S3v/3NRREBAACgNusUVN/VIdhVNZaPPvpIoaGhDmXlHdkyDKNKfVc3pyRby5Ytk5+f31WbbGVnZ9v/f+rUKbVs2VIjRoxwYUQAAACozaoyba+mCQ0NvewCGZdz9OhRSY6rF9ZkTlkgA79atGiRrrvuOrVu3drVoQAAAAC1lmEYWrVqlXx8fCqdrFW3KzbZysrK0tSpUzV48GA1btxYFotFM2bMKLNudna2HnvsMQUFBcnb21tdunTRJ598YkocH3/8se655x5T2gIAAACuVjNnztS+ffv06KOPytvb29XhlItTphHWBKmpqXr//ffVuXNnRUdHa+7cuZesO2LECO3cuVOzZ89W+/bttXjxYo0ePVrFxcUaM2ZMpWNITEzU/v37NXLkyEq3AQAAAFxN0tPT9f3330uScnJy7Dc13rJli/70pz9p5syZLo6w/KqUbP3000/68ssvFRYWphYtWpgVkylatWql8+fPy2Kx6Ny5c5dMttasWaN169bZEyxJGjBggI4ePaonnnhCd955p6xWqyRp4MCB2rp1a5ntTJkyRS+++KJD2UcffaRhw4bJ39//srGeOXNGZ8+edSg7ePBgeXYTAAAAuKJs3bpV1113nSwWi3x8fNS8eXP16tVL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9PR0TZ48WZJ05513avr06Vq2bJnuu+8+F0cHAACA2uilHS/px7QfK/Xaw+mHlW9znFmWb8vXA189oDb+bSrcXseAjnqy15OViuVyfHx81KhRI508edKhvGnTppd8Tb9+/UyPw0ymJVuS1KdPH23evFljx47VunXr9PXXXztsNwxDgYGBmjZtmpndlikrK0vPPfecdu/erYSEBJ07d07PPvusZsyYUapudna2nnnmGX366adKS0tTx44d9dRTT2nUqFEV7tcwjDLL9u7dW5ndAAAAAPRj2o/a9csuU9tMy09T2i9pprZZVWWdS3/99dfy8/MrVV6Zc/XqZmqyJUldu3ZVYmKiPv74Yy1ZskQJCQk6e/as/Pz8FBUVpeeff17NmjUzu9tSUlNT9f7776tz586Kjo7W3LlzL1l3xIgR2rlzp2bPnq327dtr8eLFGj16tIqLizVmzJgK9duhQwf5+vrqX//6lx544AF99tlnOnjwoHJycqq6SwAAALhKdQzoWOnXHk4/rLT80klVgFdApUe2nCEnJ0epqamKiIhwKO/cubMaNWpUqr63t7dT4jCT6cmWJFmtVo0bN67a17H/rVatWun8+fP2tfkvlWytWbNG69atsydYkjRgwAAdPXpUTzzxhO68805ZrVZJ0sCBA7V169Yy25kyZYpefPFFeXp6atmyZXr44Yc1ffp0DRo0SIMGDbrsdWpnzpzR2bNnHcoOHjxYmd0GAADAFagq0/ZKrtn67VRCL6uX3h/8vjoEdDAjPFOsXr1aNpvNfu+sK0Glk60ePXro+uuv16xZs+Tv729iSOawWCzlqrds2TL5+vpq5MiRDuXjx4/XmDFjtH37dl1//fWSpPXr15erzW7dutmTMpvNprZt2+qvf/3rJevPmTNHM2fOLFfbAAAAQEV0COigRUMXaV7iPB3KOKS2fm01MWJijUq0jh07pscff1x+fn7685//7OpwTFPpZCs+Pl4JCQl66KGH5O/vr0aNGqlbt27q2rWr/d/27dubGatTJCUlKTQ0VO7ujm9FZGSkfXtJslWRNtu1a6eCggLNmjVLTZo00U033XTJ+pMnTy6V7B08eFDR0dEV6hcAAAAoS4eADnq538uuDkPSxXPlkhUFz5w5oy1btmj+/PmyWq1atmxZtd942JkqnWz99NNP+u677+zzJ9PT0/X111/r66+/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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure(dpi=120, figsize=(8,3))\n", - "\n", - "plt.plot(d_ax, err_fdtd_val, label='FD')\n", - "plt.plot(d_ax, err_fft_val, label='FFT')\n", - "plt.semilogy(d_ax, err_dht_val,'.-', label='DHT')\n", - "plt.legend()\n", - "\n", - "plt.xlabel(r'd',size=13)\n", - "plt.ylabel(r'$\\langle | Numeric - Formula |\\rangle$',size=13);" - ] - }, - { - "cell_type": "markdown", - "id": "0fd7b6bc", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "### Distribution of error" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "e06b6e16", - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(0.0, 1.049871341765873)" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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qKmpOeu+r732miHJWLFiRd2y6upqIyYmxujXr1+D1Qz3c+a8OXjw4GnL8vPzDR8fH+P22293ea1oGpw5Z06orq42EhISjAcffNAYNmwYwec84Mx5k5GRYZjNZuMvf/lLQ5eJJsaZ8+aGG24w/Pz8jNLS0lOWjxgxwmjRokWD1IumwWazGTabzTAMwzh06FC9go8nXROf10PdvvrqKwUFBWn8+PGnLL/11lu1b98+rV69+lf3jY6O1sCBA+uWWa1WTZgwQWvWrFF+fn6D1Q33cua8CQ8PP21ZZGSk2rdvrz179ri8VjQNzpwzJ0ydOlVHjhzRCy+80FBloolx5rz55z//KT8/Pz3wwAMNXSaaGGfOGx8fH/n6+iogIOCU5SEhIfL392+QetE0mEwmmUwmh/b1pGvi8zr45ObmqmfPnrJaracsj4+Pr1v/a/ue2O5M+27cuNGFlaIpcea8OZPt27dr165dio2NdVmNaFqcPWd++uknPf/885oxY4aCgoIarE40Lc6cN0uWLFHPnj01e/ZsRUdHy2KxqH379nr00UdVVVXVoHXDvZw5b+655x5VVVXpwQcf1L59+1RUVKQPP/xQX331lR5++OEGrRuey5Ouic/r4FNYWKiWLVuetvzEssLCwgbZF57NlT/7mpoa3X777QoKCtLkyZNdViOaFmfOGZvNpttuu01XX321Ro0a1WA1oulx5rzJz8/X1q1b9eCDD+rBBx/UggULdMstt+hvf/ubbr311garGe7nzHnTv39/LVy4UF999ZXatWun0NBQ3XrrrXrhhRf0xz/+scFqhmfzpGti629v4t1+rVvvt7r8nNkXns0VP3vDMHT77bdr6dKlmj17tjp06OCq8tAEOXrO/P3vf9fWrVv19ddfN0RZaOIcPW9sNptKSkr0ySef6Nprr5UkpaamqqysTC+//LLS0tIUFRXl8nrRNDh63mRmZuqqq65S//799frrryswMFALFy7Uk08+qYqKCj311FMNUS68gKdcE5/XwadVq1ZnTKFHjhyRpDOmV1fsC8/mip+9YRi64447NHPmTL3//vu68sorXV4nmg5Hz5ndu3fr6aef1tSpU+Xr66uioiJJ9p5Cm82moqIi+fn5nTYeH97B2X+jDhw4oEsuueSU5SNHjtTLL7+srKwsgo+Xcua8ue+++xQREaGvvvpKFotFkj0wm81mTZkyRTfccIO6du3aMIXDY3nSNfF5PdStV69e2rRpk2pqak5ZvmHDBkn61edk9OrVq267+u4Lz+bMeSP9N/S8++67euuttzRhwoQGqxVNg6PnzPbt23Xs2DE99NBDCg0NrXstX75cmzZtUmhoqB577LEGrx/u4czvmjONt5fsv38kyWw+r//592rOnDc5OTlKTEysCz0nJCcny2azadOmTa4vGB7Pk66Jz+vffFdddZVKS0s1e/bsU5a///77ioyMVP/+/X91382bN58yO0pNTY1mzpyp/v37KzIyssHqhns5c94YhqE777xT7777rl5//XXG2p8nHD1nEhIStGjRotNevXv3VufOnbVo0SLdf//9jfEtwA2c+V0zduxYSdK8efNOWf7tt9/KbDYrOTnZ9QWjSXDmvImMjFRGRsZpDytduXKlJKl9+/auLxgez6Ouid06mXYTMHz4cCM0NNR44403jIULFxp33nmnIcmYOXNm3Ta33XabYbFYjJ07d9Ytq6ioMGJjY40OHToYH330kTF//nzjqquuapIPa4LrOXre3H///YYk47bbbjNWrlx5yisrK8sd3woaiaPnzJnwHJ/zh6PnTVVVldG3b18jODjY+Mc//mHMnz/feOSRRwyLxWLcf//97vhW0IgcPW9eeeUVQ5IxcuRIY86cOcYPP/xgPPLII4bVajUuvvhid3wraETffvut8cUXXxjvvPOOIckYP3688cUXXxhffPGFUVZWZhiG518Tn/fBp6SkxHjwwQeNNm3aGL6+vkZ8fLzxySefnLLNzTffbEgyduzYccryAwcOGDfddJPRsmVLw9/f3xgwYIAxf/78Rqwe7uLoedOpUydD0hlfnTp1atxvAo3Kmd81/4vgc/5w5rwpLCw07r77biMiIsLw8fExunfvbvz1r381amtrG/E7gDs4c97Mnj3bGDx4sBEWFmYEBgYasbGxxnPPPXfaQ03hfX7tGuXEeeLp18Qmwzg+4BcAAAAAvNR5fY8PAAAAgPMDwQcAAACA1yP4AAAAAPB6BB8AAAAAXo/gAwAAAMDrEXwAAAAAeD2CDwAAAACvR/ABAAAA4PUIPgAAAAC8HsEHAAAAgNcj+AAAAADwegQfAMB549ixY5oyZYqioqLk7+8vPz8/9e7dWzNnznR3aQCABmYyDMNwdxEAADS0zZs367LLLtO2bduUlJSkbt26acuWLcrMzJQkffTRR7r++uvdXCUAoKEQfAAAXm///v2Kj49XRUWFPv/8c40cObJu3VNPPaXnn39eF1xwgfLy8txYJQCgIRF8AABeb9y4cZo9e7befvtt3XbbbaesKy8vV0hIiKqrq7V//361adPGTVUCABoSwQcA4NW2bdumqKgoxcbGKjc394zbtGvXTvv27dPWrVsVFRXVyBUCABoDkxsAALzal19+KUkaO3bsGdcbhqEjR45IEr09AODFCD4AAK+2YMECSdKQIUPOuH7t2rWqqKhQdHS0goKCGrM0AEAjIvgAALxaRkaGJKlVq1ZnXD979mxJ0hVXXNFoNQEAGh/BBwDgtbZv3143jG3Xrl2nrd+2bZtee+01+fn5aeLEiY1dHgCgERF8AABe60RvjyT97W9/U0VFRd3Xu3bt0tixY1VWVqZnn31WnTt3dkOFAIDGYnV3AQAANJQTwefee+/VW2+9pe7du+vCCy/UkSNHlJ6ersrKSk2ePFkPP/ywmysFADQ0prMGAHitiy66SIsWLdKqVatUUlKip556SuvXr5fValX//v31hz/8QZdeeqm7ywQANAKCDwDAKxmGodDQUJWVlamkpET+/v7uLgkA4Ebc4wMA8Epbt25VcXGxYmNjCT0AAIIPAMA7nbi/Jykpyc2VAACaAoIPAMArnQg+iYmJbq4EANAUcI8PAAAAAK9Hjw8AAAAAr0fwAQAAAOD1CD4AAAAAvB7BBwAAAIDXI/gAAAAA8HoEHwAAAABej+ADAAAAwOsRfAAAAAB4PYIPAAAAAK9H8AEAAADg9Qg+AAAAALwewQcAAACA1/v//h+Ig0Wjc/EAAAAASUVORK5CYII=\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure(dpi=120, figsize=(8,3))\n", - "\n", - "plt.fill_between(rho, np.abs(df_dht - df_analyt), -np.abs(df_dht - df_analyt), alpha=0.4, color='k')\n", - "plt.plot(rho, df_dht - df_analyt, c='r')\n", - "plt.xlabel(r'$\\rho$',size=13)\n", - "plt.ylabel(r'$DHT - Formula$',size=13);\n", - "plt.xlim(0,)" - ] - }, - { - "cell_type": "markdown", - "id": "b72c679c", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "### Or a non-periodic signal" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "6bb85277", - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA04AAAFiCAYAAADBUYjlAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAABJ0AAASdAHeZh94AABa4klEQVR4nO3deXhU5fk+8PvMTPZ93xdCSAJZSNgCyCIgCGIVVFTEHftroW7Vit/WutcWWzfaQlvqAhVFyyZWQYWwKCBhC5AEAiSBJCSEbGRPJpmZ8/tjFhIJ2WY5s9yf68plODNnzjN6JHPnfd/nFURRFEFERERERETXJZO6ACIiIiIiImvH4ERERERERNQHBiciIiIiIqI+MDgRERERERH1gcGJiIiIiIioDwxOREREREREfWBwIiIiIiIi6gODExERERERUR8YnIiIiIiIiPqgkLoAR1FfX4+9e/ciKioKLi4uUpdDREREROTQlEolysrKMHXqVPj6+vb5fAYnC9m7dy/mzZsndRlERERERNTFF198gdtvv73P5zE4WUhUVBQA7X+Y+Ph4iashIiIiInJshYWFmDdvnuFzel8YnCxEPz0vPj4eycnJEldDREREREQA+r2Mhs0hiIiIiIiI+sDgRERERERE1AcGJyIiIiIioj4wOBEREREREfWBwYmIiIiIiKgPdh2cmpqasGzZMsyaNQtBQUEQBAGvvPJKv8+vqqrCww8/jMDAQLi7u2PChAnIysoyX8FERERERGSV7Do41dbWYvXq1VAqlQPefFapVGLGjBnIysrCihUrsHXrVoSEhGD27NnYu3eveQomIiIiIiKrZNf7OMXExODKlSsQBAE1NTV4//33+33uBx98gLy8PBw4cAATJkwAAEybNg0jR47EsmXLkJ2dba6yiYiIiIjIytj1iJMgCBAEYVDnbtmyBYmJiYbQBAAKhQL3338/Dh06hPLyclOVaTEltS04XlaPqsZ2aDSi1OUQEREREdkMux5xMkZeXh4mT558zfG0tDQAQH5+PiIiIno8t6qqCtXV1d2OFRYWmr7IAfokuxSrvy8GAAR6OmNuahj+39ShiPB1k7gyIiIiIiLrxuB0HbW1tfD397/muP5YbW3tdc9dtWoVXn31VbPVNljl9W2G72uaO7D2xxJ8fqQMz8xMwM8nxw16dI6IiIiIyN4xOPWityDR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Vqst+A7InIy5PzZt2iROmjRJDAwMFD08PMTk5GTx9ddfv2ZTXLJdvX2G0N8Ptvi5VBBF3aRjIiIiIiIi6hHXOBEREREREfWBwYmIiIiIiKgPDE5ERERERER9YHAiIiIiIiLqA4MTERERERFRHxiciIiIiIiI+sDgRERERERE1AcGJyIiIiIioj4wOBEREREREfWBwYmIiIiIiKgPDE5ERERERER9YHAiIiLqp7a2NrzyyiuIj4+Hq6srXFxcMHLkSKxbt07q0oiIyMwEURRFqYsgIiKydgUFBbj11ltRVFSEMWPGYNiwYTh79iyOHj0KAPjkk09w3333SVwlERGZC4MTERFRHy5duoS0tDS0t7fjv//9L+bMmWN47MUXX8Qf/vAHDB06FIWFhRJWSURE5sTgRERE1Ie77roLmzZtwgcffIBHH32022Otra3w9fVFZ2cnLl26hNDQUImqJCIic2JwIiIi6kVRURHi4+ORnJyMvLy8Hp8TERGBiooKnDt3DvHx8RaukIiILIHNIYiIiHqxefNmAMCdd97Z4+OiKKKurg4AONpERGTHGJyIiIh6sXPnTgDA5MmTe3z88OHDaG9vR2JiIjw9PS1ZGhERWRCDExERUS+OHDkCAAgICOjx8U2bNgEAbrvtNovVRERElsfgREREdB3FxcWGaXglJSXXPF5UVISVK1fCxcUFS5cutXR5RERkQQxORERE16EfbQKAt956C+3t7YY/l5SU4M4770RLSwtee+01xMbGSlAhERFZikLqAoiIiKyVPjgtWbIE77//PhISEnDDDTegrq4Oe/fuhVKpxK9//WssW7ZM4kqJiMjc2I6ciIjoOqZPn47du3fj4MGDaGpqwosvvoiTJ09CoVAgMzMTzzzzDGbPni11mUREZAEMTkRERD0QRRF+fn5oaWlBU1MTXF1dpS6JiIgkxDVOREREPTh37hwaGhqQnJzM0ERERAxOREREPdGvbxozZozElRARkTVgcCIiIuqBPjiNHj1a4kqIiMgacI0TERERERFRHzjiRERERERE1AcGJyIiIiIioj4wOBEREREREfWBwYmIiIiIiKgPDE5ERERERER9YHAiIiIiIiLqA4MTERERERFRHxiciIiIiIiI+sDgRERERERE1AcGJyIiIiIioj4wOBEREREREfWBwYmIiIiIiKgP/x/5xQ5k/G3lOAAAAABJRU5ErkJggg==\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "Nr = 512\n", - "\n", - "rho0 = 0\n", - "Lrho = 0.4\n", - "n_ord = 4\n", - "freq = 4\n", - "rho = np.linspace(0, 1, Nr, endpoint=False)\n", - "\n", - "fu_test = np.exp(-((rho-rho0)/Lrho)**n_ord) * np.cos(2*np.pi * freq * rho)\n", - "df_analyt = -2*np.pi * freq * np.exp(-((rho-rho0)/Lrho)**n_ord) * np.sin(2*np.pi * freq * rho) \\\n", - " - np.exp(-((rho-rho0)/Lrho)**n_ord) * np.cos(2*np.pi * freq * rho) \\\n", - " * n_ord * ((rho-rho0)/Lrho)**(n_ord-1) / Lrho\n", - "\n", - "plt.figure(dpi=120, figsize=(8,3))\n", - "\n", - "plt.plot(rho, fu_test)\n", - "plt.xlabel(r'$\\rho$',size=13)\n", - "plt.ylabel('Signal',size=13);" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "8c185524", - "metadata": {}, - "outputs": [], - "source": [ - "alpha = scf.jn_zeros(0, Nr)\n", - "k_fft = 2 * np.pi * np.fft.fftfreq(Nr, dr)\n", - "\n", - "err_fdtd_val = []\n", - "err_fft_val = []\n", - "err_dht_val = []\n", - "\n", - "for d in d_ax: \n", - " rho = np.linspace(0, 1, Nr, endpoint=False)\n", - " dr = rho[[0,1]].ptp()\n", - " rho += d * dr\n", - "\n", - " fu_test = np.exp(-((rho-rho0)/Lrho)**n_ord) * np.cos(2*np.pi * freq * rho)\n", - " df_analyt = -2*np.pi * freq * np.exp(-((rho-rho0)/Lrho)**n_ord) * np.sin(2*np.pi * freq * rho) \\\n", - " - np.exp(-((rho-rho0)/Lrho)**n_ord) * np.cos(2*np.pi * freq * rho) \\\n", - " * n_ord * ((rho-rho0)/Lrho)**(n_ord-1) / Lrho\n", - " \n", - " iDHT = scf.jn(0, alpha[None,:] * rho[:, None])\n", - " DHT = np.linalg.inv(iDHT)\n", - " iDHT = scf.jn(1, alpha[None,:] * rho[:, None])\n", - " \n", - " df_dht = iDHT.dot(- alpha * DHT.dot(fu_test))\n", - "\n", - " err_dht_val.append(np.abs(df_analyt - df_dht).mean()/np.abs(df_analyt).mean())\n", - "\n", - "df_fdtd = np.gradient(fu_test, dr)\n", - "df_fft = np.real(np.fft.ifft(1j * k_fft * np.fft.fft(fu_test)))\n", - "\n", - "err_fdtd_val = np.abs(df_analyt - df_fdtd).mean()/np.abs(df_analyt).mean() * np.ones_like(d_ax)\n", - "err_fft_val = np.abs(df_analyt - df_fft).mean()/np.abs(df_analyt).mean() * np.ones_like(d_ax)" - ] - }, - { - "cell_type": "markdown", - "id": "93b934ed", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "### Errors for derivatives computed via FD, FFT and DHT" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "5c3879aa", - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "outputs": [ - { - "data": { - "image/png": "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6is8/fTTGD16NHbs2AFzc/NmjbkxJE22ACAyMhKhoaH4/PPP8d133yE1NRUlJSVwc3PDsGHDsGzZMri5uUndLRERERERtRABAQHo27dvrdsdHBzw6KOPan9+6qmnMHfuXCxfvhwrVqzAkiVLsGrVquYItUkkm0b4Z23btsUrr7yCI0eOIC8vD1VVVbhy5Qr++9//MtEiIiIiIqJGWb58Ofz9/bFu3TpUVFQYO5wHavTI1syZM/HMM8/gqaeekjIeIiIiIiL6ixV7zuH8jRJjh6Hl526HZcP9G72/Wq2GSqXSKTMzq19qMnz4cKxcuRJnzpzBE0880egYmkOjk62oqCioVComW0REREREBnb+RglOZRUYOwzJ/HmK4H3V1dX1Srg6deoEALhx44bkcUlN8mu2AGD06NGYMmUKRowYYYjmiYiIiIgeKn7udsYOQUdT49myZQt8fX11yuo7siWKYpP6bk4GSbbi4uJgb2/PZIuIiIiISAJNmbJninx9fetcIKMuOTk5AHRXLzRVBlkgg4iIiIiISGqiKGLPnj2wsbFpdLLWnJhsERERERFRi7BixQqcP38eL7/8MqysrIwdzgMZZBohERERERFRYxUVFeGXX34BAJSVlWlvanzs2DE888wzWLFihZEjrJ8mJVsXL17EDz/8AH9/f3h6ekoVExERERERPcSOHz+Oxx57DIIgwMbGBh4eHnjkkUewZMkSDBkyxNjh1VuTkq2TJ08iPDwcAGBraws/Pz/4+9+7eK+kpATV1dUwNzdvepRERERERNTiTZ06FVOnTq2zTnZ2drPE0hwanWx99NFHSE5ORnJyMn7//XeUlJTgl19+0Q73xcXFwdbWFv7+/ujbty/69OmDvn37IjAwkAkYERERERG1eo1OtubPn6/9d2VlJc6ePatNvpKSkpCamoqKigptWVRUFADA3NwcQUFBOH36dJODJyIiIiIiMlWSLJBhaWmJkJAQhISEaMs0Gg3S09O1yVdycjJSUlJQXFyMxMREKbolIiIiIiIyWQZbjVAmk8Hf3x/+/v547rnntOVZWVlITk42VLcm4/PPP8d7772HW7duoUOHDvjuu+/QtWtXY4dFRERERETNpNmXfu/cuTM6d+7c3N02qz179mDNmjXYvXs3fH19cenSJTg6Oho7LCIiIiIiaka8z5YBvP322/j444/h5+cH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qqdQKLB27VqsXbvWsAEREREREdFDQ/JkS6lU4uTJk8jPz4eTkxOCgoLQrl07qbshIiIiIiIyaZImW1FRUXj11Ve110gBwJQpU/D5559L2Q0REREREZHJk2zp9++++w4zZ87E3bt3MWbMGLzyyis1LujbtGkTIiMjcfHiRam6JSIiIiIiMkmSJVurVq2CTCbDDz/8gK+//hoffPBBjTqDBw/Grl278PXXX0vVLRERERERkUmSLNlKSUnB448/jtDQ0FrreHl5oXv37jh48KBU3RIREREREZkkyZItURTh5ub2wHqenp71XiWQiIiIiIiopZIs2eratSvS09MfWM/FxQV5eXlSdUtERERERGSSJEu2wsPDce7cOfzwww911svNzZWqSyIiIiIiIpMlWbL10ksvwcbGBs8++yxOnjypt05+fj5OnTqFzp07S9UtERERERGRSZIs2XJ3d8eXX36JsrIyDBgwAOPGjQMAqNVqAMClS5fwzDPP4O7du/j73/8uVbdEREREREQmSbJkCwBGjhyJAwcOwMvLCzExMQCArVu3wsrKCt27d8eRI0fg6emJhQsXStktERERERGRyZE02QKAJ554Aunp6YiKisKwYcPg7u4OAHB2dsakSZNw/PhxODo6St0tERERERGRSTEzRKPm5uaYPn06pk+fbojmiYiIiIiITJ7kI1tEREREREQk8chWWloadu7ciRs3bsDV1RVBQUHo3bs3unTpImU3REREREREJk+yZGv37t0YM2YM1Go1RFEEAAiCAACwt7dHr1690Lt3b+2jR48eUnVNRERERERkciRLtpYuXQqVSoXRo0dj2LBhKCoqwtmzZ5GUlIT09HQcOXIER44cgSAIEAQBKpVKqq6JiIiIiIhMjmTJVmZmJnr27Kld8v3PqqqqkJaWhqSkJCQlJSElJUWqbomIiIiIiEySZMmWi4sL/Pz89G6zsLDQTh8kIiIiIiJ6GEi2GuHw4cPx22+/SdUcERERERFRiyZZsvXGG2/g1q1b2LRpk1RNEhERERERtViSTSNs37494uPjERERgatXr2LRokVo06aNVM0TERERERG1KJKNbKnVanz33XcQBAFvv/02XF1dERkZiVWrVuHQoUMoLCyUqisiIiIiIiKTJ1mytWjRIvzrX/9CXl4eRFFEWVkZ4uPj8eabb2LIkCFwdnZG165d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XhABiFu3btXWmT59uiiXy8Xs7GxtWUVFhejv7y926NBB3LZtm3jgwAExIiKCNzVupRp7nLz44osiAHH69OniyZMndR5JSUnGeCpkII09RvThfbZar8YeJ1VVVWLv3r1Fe3t7ce3ateKBAwfERYsWiXK5XHzxxReN8VTIQBp7jPz73/8WAYhDhw4V4+Pjxf3794uLFi0SzczMxKeeesoYT4UMaO/evWJMTIz4+eefiwDEsWPHijExMWJMTIxYVlYmiqLpnb8y2XpIlZaWivPmzRPd3NxECwsLMSgoSNyxY4dOnSlTpogAxKysLJ3yW7duiZMnTxYdHR1FKysr8dFHHxUPHDjQjNFTc2nscdKpUycRgN5Hp06dmvdJkEE15bPkr5hstV5NOU7y8/PFWbNmie3atRPNzc3F7t27i//6179EtVrdjM+ADK0px0hsbKz4xBNPiM7OzqKNjY3o7+8vvv322zVudEwtX13nF/ePC1M7fxVE8X8Tn4mIiIiIiEgyvGaLiIiIiIjIAJhsERERERERGQCTLSIiIiIiIgNgskVERERERGQATLaIiIiIiIgMgMkWERERERGRATDZIiIiIiIiMgAmW0RERERERAbAZIuIiIiIiMgAmGwRERE1o+zsbAiCAC8vL2OHQkREBsZki4iIiIiIyACYbBERERERERkAky0iIiIiIiIDYLJFRERkAMnJyRg+fDgcHBygUCjw6KOPIiYmxthhERFRMzIzdgBEREStzeHDhxEeHo7Kykr4+/sjKCgI2dnZeOaZZ/Dyyy8bOzwiImomTLaIiIgkdPfuXTz33HOorKzEO++8g8WLF2u3xcTEYPz48UaMjoiImhOnERIREUno22+/xc2bN+Hv748333xTZ9vYsWMxatQo4wRGRETNjskWERGRhI4ePQoAmDBhAgRBqLF90qRJzR0SEREZCZMtIiIiCV2/fh0Aar1pMW9mTET08GCyRUREZAD6RrWIiOjhwmSLiIhIQh4eHgCA7OxsvdtrKyciotaHyRYREZGEnnzySQDAV199BVEUa2zftm1bc4dERERGwmSLiIhIQmPGjIGbmxtSU1OxatUqnW07d+7Ezp07jRQZERE1N0HU97UbERERNdqBAwcwfPhwVFZWIiAgAIGBgcjJycGJEycwb948/Pvf/0anTp04pZCIqJXjyBYREZHEwsLCcPz4cYSHh+PKlSvYtWsXqqursX37dixYsMDY4RERUTPhyBYREREREZEBcGSLiIiIiIjIAJhsERERERERGQCTLSIiIiIiIgNgskVERERERGQATLaIiIiIiIgMgMkWERERERGRATDZIiIiIiIiMgAmW0RERERERAbAZIuIiIiIiMgAmGwREREREREZAJMtIiIiIiIiA2CyRUREREREZABMtoiIiIiIiAyAyRYREREREZEB/H+GySwTuP3peAAAAABJRU5ErkJggg==\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure(dpi=120, figsize=(8,3))\n", - "\n", - "plt.plot(d_ax, err_fdtd_val, label='FD')\n", - "plt.plot(d_ax, err_fft_val, label='FFT')\n", - "plt.semilogy(d_ax, err_dht_val,'.-', label='DHT')\n", - "plt.legend()\n", - "\n", - "plt.xlabel(r'd',size=13)\n", - "plt.ylabel(r'$\\langle | Numeric - Formula |\\rangle$',size=13);" - ] - }, - { - "cell_type": "markdown", - "id": "793661c3", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "### Distribution of error" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "2f81293a", - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(0.0, 1.049871341765873)" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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OtSkpqaaP//5z2blypVmwoQJRpJZsGDBaY+rra01/fr1M926dTPz58837777rrn22mtNbGysWb16dRtVj0ix2m4GDRpkrrnmGjN37lyzevVq89JLL5m+ffua5ORks2nTpjaqHpFgtc2cyOfzGY/HY7KysozX6w1jtYgWwbSb3/3ud8btdpuJEyeapUuXmhUrVphnnnnGPP30021QOSLJartZvny5cbvd5tJLLzVLliwxy5cvN3fccYeRZIqLi9uoekTCzp07TceOHc2QIUP87WXatGmtOtZOfeJ2HXzeeustI8m8/PLLzbYPHTrUZGdnm4aGhlMeO3PmTCPJ/POf//Rvq6+vN3l5eWbQoEFhqxmRF0y7+eKLL07atmfPHhMXF2duueWWkNeK6BBMm2lSX19vCgsLTXFxsbnkkksIPu1AMO1m7dq1xu12m9///vfhLhNRJph2M2bMGOPxeMyRI0eabR82bJhJSUkJS72IDo2NjaaxsdEYY8yXX34ZUPCxU5+4XU91W7x4sZKTkzV69Ohm22+++Wbt3btXa9asOe2xubm5uuiii/zbYmNjNXbsWP3rX//Snj17wlY3IiuYdpOZmXnStuzsbHXr1k27d+8Oea2IDsG0mSYzZszQwYMH9cgjj4SrTESZYNrNM888I4/HozvuuCPcZSLKBNNu4uLiFB8fr8TExGbbU1NTlZCQEJZ6ER1cLpdcLpelY+3UJ27XwWfTpk3q27evYmNjm23Pz8/3P3+6Y5v2a+nYTz75JISVIpoE025asmPHDu3atUterzdkNSK6BNtmNm/erIcfflizZs1ScnJy2OpEdAmm3bz//vvq27evFi1apNzcXMXExKhbt276zW9+o2PHjoW1bkRWMO3mV7/6lY4dO6bi4mLt3btXhw8f1ksvvaTFixdr8uTJYa0b9mWnPnG7Dj4HDhxQp06dTtretO3AgQNhORb2FsrffUNDg2655RYlJyfr7rvvDlmNiC7BtJnGxkaNHz9e119/vUaOHBm2GhF9gmk3e/bs0bZt21RcXKzi4mKtWLFC48aN06OPPqqbb745bDUj8oJpN4MHD9bKlSu1ePFide3aVWlpabr55pv1yCOP6Ne//nXYaoa92alPHHvmXZztdMN6ZxryC+ZY2FsofvfGGN1yyy364IMPtGjRInXv3j1U5SEKWW0zjz/+uLZt26a/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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure(dpi=120, figsize=(8,3))\n", - "\n", - "plt.fill_between(rho, np.abs(df_dht - df_analyt), -np.abs(df_dht - df_analyt), alpha=0.4, color='k')\n", - "plt.plot(rho, df_dht - df_analyt, c='r')\n", - "plt.xlabel(r'$\\rho$',size=13)\n", - "plt.ylabel(r'$DHT - Formula$',size=13);\n", - "plt.xlim(0,)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "c56a4ce9", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "outputs": [], - "source": [ - "series_vals_iDHT = []\n", - "\n", - "Nr_series = [64, 128, 256]\n", - "\n", - "for Nr in Nr_series:\n", - " vals_iDHT = []\n", - " alpha = scf.jn_zeros(m, Nr)\n", - " for d in d_ax: \n", - " rho = np.linspace(0, 1, Nr, endpoint=False)\n", - " dr = rho[[0,1]].ptp()\n", - " rho += d * dr\n", - " iDHT = scf.jn(m, alpha[None,:] * rho[:, None])\n", - " vals_iDHT.append(np.linalg.det(iDHT))\n", - " series_vals_iDHT.append(vals_iDHT)\n", - "\n", - "d_max = d_ax[series_vals_iDHT[0]==max(series_vals_iDHT[0])]" - ] - }, - { - "cell_type": "markdown", - "id": "705b972f", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "source": [ - "### Determinant " - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "2b0a6d0f", - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABDwAAADtCAYAAABTR2V6AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAxOAAAMTgF/d4wjAAB0rUlEQVR4nO3deXxU1d3H8c9MZrJvJCEhe9gCsm8CClUE2ypWxKKWukAqClQotXko7dOntqWbO1pbESootFEUoW641KrFlX2TRSBAVkjIQvZ9Mvf5Y5IJYQ04yWT5vvW+7jpzf3NEzpnfnHOuyTAMAxERERERERGRTsTs7gBERERERERERFxNCQ8RERERERER6XSU8BARERERERGRTkcJDxERERERERHpdJTwEBEREREREZFORwkPEREREREREel0lPAQERERERERkU7H4u4AOgsvLy+6d+/u7jBERETcJj8/n5qaGneH0SWo3SEiIl1ZS9scSni4SPfu3cnOznZ3GCIiIm4TExPj7hC6DLU7RESkK2tpm0NDWkRERERERESk01HCQ0REREREREQ6HQ1pka7DMCBzM5w6BiG9IG4smEzujkpERERERERagRIe0jUUZ8I/vw/FGeBhhfo6CI6He/4FwXHujk5ERERERERcTENapPMzDEey41Qa1NdCbYVjfSoNUqY5zouIiIiIiEinoh4e0qnY7QY5pdVkn6qk2manuq4e39ytXF2Ujodha36xYcM4lU710S/w6TPePQGLiIjIJbHbDersdmz1BnX1durqDertjm2b3aDe3nSscd9Wb1BvnHasYd8wDOrtUG8Y2O2O83bDwDDAbhjYG9ZGs20wAKPhBxPHfvMfT871W0rjKFoTpqZtkwkTYDY5ts0mx4VmE5gb1o7jJjzMjmMmkwmPhn0Ps9l53MPsWCxmc8O6Yd+jcduMxWzC6mHG4mHCanasG7fNZg3zFZHORwkP6ZAMw+BofjmHcss5ml/OkTzH+lh+BVV19c2uvc3jc0ZYzPidox6vrDfx2xff4h1zORGBXgyICmRoTDDDYoMZHBOEr6f+FxEREWlUV2+nqq6e6tp6x7rO8eNCdV3Tfo2tnprGtc3uWOpO2244XtuwX9u41Nupqz97u67eoK7hmK0hKSGuZ2lIjlg9zHh6mLF6mLFamvY9LU3HPS1Ni5dz8cCr2TEPvK0N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u3j66ac5fPgwN954I8nJyS2+d3Z2NsuXL2fs2LGtWAIi0l7dMKgHKbPGYLWYuW/1dl7akuHukESkEygqKmLWrFnExsY6j6Wnp3PFFVcwd+5cfve737kvOBERkU7ILQmPvLw8du7cyd133w3AtGnTSEtLIz09vdl169at49ZbbyUiIgKTycTcuXNZs2YNAO+99x6jRo2if//+ADzwwAPOc9u3b8fLy4sJEyYAjgTHG2+8QV1dXYvuPXv2bJ566im8vLxasRREpD0b3TOEf/34amK6+fB/r+/j4fe+xm7v3JMAisjZFixYQEJCAiaTiX379jU719Leqo26devGypUr6devX7PjAQEBVFdXk5CQ4OrwRUREujS3JDyysrKIiorCYnHMmWoymZyPUjtdZmYm8fHxzv2EhATnNec6d/z4cex2+1nnAgICCAgIICcn56L3fu655xg4cCBjxoxpnQ8vIh1Gr+7+/OvHVzMiLpjlnxzjJ2t2UV1X7+6wRKQN3XbbbXz++efN2hWNztdjNDc3lwkTJjRbHnzwwXO+f3x8PFu3buXFF1/k7bffPuvHHxEREbl8bntKi8lkarZ/vsennX7dmdec+R4tff/znUtLS+P555/niy++uEDkDkuWLGHJkiXO/dPnDxGRziPU34uX7x9L8trdvLM3h9zSap6fMYoQP093hyYibeCaa6455/HGHqMffPAB4OgxOn/+fNLT00lISGDjxo0tev/GNonJZCI8PJyysjKXxC0iIiJu6uERGxtLdna2cwJSwzDIysoiLi6u2XVxcXHNfunIyMhwXnPmufT0dKKjozGbzWedKysro6ysjMjIyAvee9OmTZw4cYIrrriChIQENm/ezKxZs3j++efP+gzJyclkZ2c7F39/fxeVjoi0N95WD/72wxHMuaYXOzKKuHXpFxzJ05cSka6spb1VzzR37lwOHjzI3LlzOXr0KBs3bmTWrFncd999eHt7M3jw4HO+bsmSJcTExDgX/dAiIiJycW5JeISHhzN8+HBSUlIAWL9+PQkJCWeNXZ02bRqvv/46J0+exDAMli1bxvTp0wG44YYb2LZtGwcPHgRg6dKlznMjR46kurra+evK8uXLmTp1Klar9YL3vvPOO8nNzSU9PZ309HTGjh3LypUruf/++9ugVESkPTObTfzv5Cv4w9RBZBdVceuzX/LxwZPu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HVZLyrOuro5///vfLF++nF27dhEbG8u8efPaKsQOoyVluXPnTg4ePMjx48c5ceIEkyZNYv78+W0VYqej+qfzUJvD9dT2cC21P1xPbRDXU1vEPS63blLCw41iY2PJzs52TrhiGAZZWVnExcU1uy4uLo709HTnfkZGxlnXdHUtLUuAsrIybrjhBqZMmUJycnJbh9rutbQsP//8c37/+9+TkJDA9OnT2bt3LwMHDnRHyO1aS8szPj6e6667jujoaEwmE3fddRdbt251R8jtVkvLctWqVVx33XUEBwdjNpuZOXMm//3vf90Rcoen+qfzUJvD9dT2cC21P1xPbRDXU1vEPb5J3aSEhxuFh4czfPhwUlJSAFi/fj0JCQkkJCQ0u27atGm8/vrrnDx5EsMwWLZsGdOnT3dDxO1XS8uyvLycG264ge9+97s89NBDboi0/WtpWX711Vekp6eTnp7OK6+8wuDBg9m/f78bIm7fWlqed9xxB9u2baO0tBSA999/n6FDh7Z1uO1aS8uyV69efPTRR9TV1QHw9ttvM2jQoLYOt1NQ/dN5qM3hemp7uJbaH66nNojrqS3iHt+obmrpJCLSOg4ePGiMHTvW6Nu3rzFy5Ehj3759hmEYxqxZs4w333zTed3f//53o3fv3kbPnj2NWbNmOWf8lSYtKcs//vGPhsViMYYOHepc/vjHP7oz7HappX8uG2nSsAtraXmuXr3aGDBggDFkyBDjxhtvNLKystwVcrvVkrKsrq427rvvPqNfv37G4MGDje985zsXnUSwK3rggQeM6Ohow8PDw4iIiDB69+5tGIbqn85MbQ7XU9vDtdT+cD21QVxPbRHXau32iMkwNDhTRERERERERDoXDWkRERERERERkU5HCQ8RERERERER6XSU8BARERERERGRTkcJDxERERERERHpdJTwEBEREREREZFORwkPEel0fve73531PHQRERERV1ObQ6R9U8JDRERERERERDodJTxEREREREREpNNRwkNEOrTq6mrmzJlDUFAQ3bp148c//jE1NTXuDktEREQ6GbU5RDoeJTxEpENbtGgR69evZ9WqVWzevBk/Pz+effZZd4clIiIinYzaHCIdj8kwDMPdQYiIXI6KigpCQkJ46qmneOCBB5zHR40aRUFBAenp6e4LTkRERDoNtTlEOib18BCRDuvIkSPU1tYybty4ZsfHjx/vpohERESkM1KbQ6RjUsJDRDo8k8nk7hBERESkC1CbQ6RjUcJDRDqsPn364OnpyRdffNHs+JdffummiERERKQzUptDpGOyuDsAEZHL5efnx9y5c/ntb39LVFQU/fv3Z+XKlRw8eJCQkBB3hyciIiKdhNocIh2TJi0VkQ6tqqqKBx98kFdeeQWAH/zgB4SGhrJmzRpNICYiIiIuozaHSMejhIeIiIiIiIiIdDqaw0NEREREREREOh0lPERERERERESk01HCQ0REREREREQ6HSU8RERERERERKTTUcJDRERERERERDodJTxEREREREREpNNRwkNEREREREREOh0lPERERERERESk01HCQ0REREREREQ6HSU8RERERERERKTT+X/T5zIn0n9xAwAAAABJRU5ErkJggg==\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig, (ax1, ax2) = plt.subplots(1,2, dpi=80, figsize=(16,3))\n", - "\n", - "ax1.plot(d_ax, series_vals_iDHT[0])\n", - "ax1.plot(d_max, max(series_vals_iDHT[0]), 'o')\n", - "\n", - "for vals_iDHT in series_vals_iDHT:\n", - " ax2.semilogy(d_ax[:-1], vals_iDHT[:-1])\n", - "plt.legend(Nr_series)\n", - "\n", - "ax1.set_xlabel('d',size=13)\n", - "ax1.set_ylabel(r'$\\det(M)$',size=13);\n", - "\n", - "ax2.set_xlabel('d',size=13)\n", - "ax2.set_ylabel(r'$\\det(M)$',size=13);\n", - "# print(f'd = {d_max[0]:g}')" - ] - } - ], - "metadata": { - "celltoolbar": "Slideshow", - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/propagatorDHT.slides.html b/docs/propagatorDHT.slides.html deleted file mode 100644 index b4baf32..0000000 --- a/docs/propagatorDHT.slides.html +++ /dev/null @@ -1,15135 +0,0 @@ - - - - - - - - - -propagatorDHT slides - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - - - - - - - - diff --git a/docs/slides_axibeam.ipynb b/docs/slides_axibeam.ipynb deleted file mode 100644 index 211751e..0000000 --- a/docs/slides_axibeam.ipynb +++ /dev/null @@ -1,10882 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "449e9687", - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "# Axiparabola beam with axiprop\n", - "\n", - "_Igor A Andriyash_\n", - "\n", - "**Laboratoire d’Optique Appliquée**\n", - "\n", - "https://github.com/hightower8083/axiprop\n", - "\n", - "[K. Oubrerie, I.A. Andriyash et al, J. Opt. 24, 045503 (2022)]" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "8bb6d8ce", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "outputs": [], - "source": [ - "%matplotlib notebook \n", - "\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "\n", - "import h5py\n", - "\n", - "from scipy.constants import e, m_e, c, pi, epsilon_0\n", - "from scipy.ndimage import gaussian_filter1d, gaussian_filter\n", - "from scipy.signal import medfilt2d\n", - "from scipy.optimize import curve_fit\n", - "from scipy.integrate import solve_ivp\n", - "from openpmd_viewer.addons.pic import LpaDiagnostics\n", - "\n", - "def plot_colored(x, y, z, cmap=plt.cm.jet, steps=10, **kw_args):\n", - " z = np.asarray(z)\n", - " z -= z.min()\n", - " z /= z.max()\n", - " it=0\n", - " while it= 0.99 * Rmax)\n", - " profile_kz = np.exp( -( (kz-k0) * c * tau / 2 )**2 )\n", - " return profile_r * profile_kz" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "b75ee79d", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [], - "source": [ - "def mirror_axiparabola_num(kz, r, f0, d0, R, N_cut=4):\n", - " \"\"\"\n", - " Spectra-radial phase representing on-axis Axiparabola\n", - " [Smartsev et al Opt. Lett. 44, 3414 (2019)]\n", - " \"\"\"\n", - " s_ax = np.zeros_like(r)\n", - " r_loc = r[N_cut:]\n", - "\n", - " sag_equation = lambda r, s : (s - (f0 + d0 * r**2 / R**2) + \\\n", - " np.sqrt(r**2 + ((f0 + d0 * r**2 / R**2)-s)**2)) / r\n", - "\n", - " s_ax[N_cut:] = solve_ivp(sag_equation, (r_loc[0], r_loc[-1]), \n", - " [r_loc[0]/(4*f0),], t_eval=r_loc, method='DOP853', \n", - " rtol=1e-13, atol=1e-16).y.flatten()\n", - "\n", - " s_ax[:N_cut] = s_ax[N_cut]\n", - " s_ax -= s_ax[0]\n", - "\n", - " kz2d = ( kz * np.ones((*kz.shape, *r.shape)).T ).T\n", - " phi = -2 * s_ax[None,:] * kz2d\n", - "\n", - " print(f'Full sag {s_ax.ptp()/lambda0:g} wavelengths')\n", - " return np.exp(1j * phi)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "a1371a21", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Full sag 1188.46 wavelengths\n" - ] - } - ], - "source": [ - "A0 = laser_from_fu( fu_laser, prop.kz, prop.r,\n", - " normalize=True ).astype(np.complex128)\n", - "\n", - "A0 *= coefficient_A0\n", - "A0 = A0 * mirror_axiparabola_num(prop.kz, prop.r, \n", - " f0, d0, R_mirr, N_cut=2 )" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "2245f859", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'width: ' + width + 'px; height: ' + height + 'px;'\n", - " );\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.rubberband_canvas.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\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", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", - "mpl.findpos = function (e) {\n", - " //this section is from http://www.quirksmode.org/js/events_properties.html\n", - " var targ;\n", - " if (!e) {\n", - " e = window.event;\n", - " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", - " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", - " }\n", - "\n", - " // pageX,Y are the mouse positions relative to the document\n", - " var boundingRect = targ.getBoundingClientRect();\n", - " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", - " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", - "\n", - " return { x: x, y: y };\n", - "};\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " var canvas_pos = mpl.findpos(event);\n", - "\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " var x = canvas_pos.x * this.ratio;\n", - " var y = canvas_pos.y * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We want\n", - " * to control all of the cursor setting manually through the\n", - " * 'cursor' event from matplotlib */\n", - " event.preventDefault();\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\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", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure(figsize=(9,5), tight_layout=True)\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "c38b2d02", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "outputs": [], - "source": [ - "plt.imshow(np.abs(A0).T, aspect='auto', origin='lower', cmap=plt.cm.bone, \n", - " extent=[ prop.kz.min()/k0, prop.kz.max()/k0,\n", - " prop.r.min()*1e3, prop.r.max()*1e3], )\n", - "plt.title(r'$|\\hat{E}|$ (a.u.)')\n", - "plt.xlabel('$k_z/k_0$', fontsize=14)\n", - "plt.ylabel('R (mm)', fontsize=14);" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "9bcc7bfa", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'width: ' + width + 'px; height: ' + height + 'px;'\n", - " );\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.rubberband_canvas.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\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", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", - "mpl.findpos = function (e) {\n", - " //this section is from http://www.quirksmode.org/js/events_properties.html\n", - " var targ;\n", - " if (!e) {\n", - " e = window.event;\n", - " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", - " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", - " }\n", - "\n", - " // pageX,Y are the mouse positions relative to the document\n", - " var boundingRect = targ.getBoundingClientRect();\n", - " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", - " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", - "\n", - " return { x: x, y: y };\n", - "};\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " var canvas_pos = mpl.findpos(event);\n", - "\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " var x = canvas_pos.x * this.ratio;\n", - " var y = canvas_pos.y * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We want\n", - " * to control all of the cursor setting manually through the\n", - " * 'cursor' event from matplotlib */\n", - " event.preventDefault();\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\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", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Using `get_temporal_radial` method for reconstruction\n", - "\n", - "plt.figure(figsize=(9,5), tight_layout=True)\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "441a5f2a", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "outputs": [], - "source": [ - "dt = lambda0 / c / 32\n", - "dz = dt*c\n", - "z_loc = 0.0 \n", - "dNr = 16\n", - "\n", - "tt = np.arange(-60e-15, 60e-15, dt)\n", - "\n", - "r_loc = prop.r[::dNr]\n", - "dr_loc = r_loc[1:] - r_loc[:-1]\n", - "dr_loc = np.r_[dr_loc, dr_loc[-1]]\n", - "\n", - "Et = np.zeros((tt.size, r_loc.size))\n", - "Et = get_temporal_radial(A0[:,::dNr], Et, tt + z_loc , prop.kz)\n", - "\n", - "plt.imshow(Et.T, aspect='auto', origin='lower', cmap=plt.cm.seismic, \n", - " extent=[ tt.min()*1e15, tt.max()*1e15,\n", - " prop.r.min()*1e3, prop.r.max()*1e3], )\n", - "\n", - "plt.ylim(0, 7)\n", - "plt.title(r'$|\\hat{E}|$ (a.u.)')\n", - "plt.xlabel('t (fs)', fontsize=14)\n", - "plt.ylabel('R (mm)', fontsize=14);" - ] - }, - { - "cell_type": "markdown", - "id": "0c3531da", - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "# Running the multi-step propagation" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "0bfb26b2", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [], - "source": [ - "# Simulation parameters\n", - "\n", - "z_start = f0_corr - 1e-3\n", - "Distance = d0 + 2e-3\n", - "Nsteps = 512\n", - "\n", - "dz = Distance / Nsteps\n", - "zsteps = Nsteps * [dz,]\n", - "zsteps[0] = z_start\n", - "z_axis = np.cumsum(zsteps)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "5cb79d5d", - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "d7d3d223943040d4b154340e8ce64951", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - " 0%| | 00:00open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure(figsize=(9,5), tight_layout=True)\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "98f3a222", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "outputs": [], - "source": [ - "extent = [ (z_axis.min()-f0_corr)*1e3,\n", - " (z_axis.max()-f0_corr)*1e3,\n", - " 0,\n", - " prop.r_new.max()*1e6]\n", - "\n", - "plt.imshow(np.abs(A_multi**2).sum(1).T, \n", - " aspect='auto',\n", - " extent=extent,\n", - " origin='lower', \n", - " cmap=plt.cm.nipy_spectral)\n", - "\n", - "plt.colorbar()\n", - "plt.xlabel('Distance (mm)', fontsize=14)\n", - "plt.ylabel('R ($\\mu$m)', fontsize=14);" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "a521b296", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "outputs": [], - "source": [ - "dt = 0.8e-6 /c / 20\n", - "dz = dt * c\n", - "\n", - "dkz = prop.kz[1]-prop.kz[0]\n", - "upstream_delay = 60e-6/c\n", - "dt_window = 120e-6/c\n", - "\n", - "time_window = upstream_delay - np.array([ 0, dt_window ])\n", - "time_window.sort()\n", - "\n", - "tt = np.arange(*time_window, dt)\n", - "\n", - "dNr = 1\n", - "r_loc = prop.r_new[::dNr]\n", - "dr_loc = r_loc[1:] - r_loc[:-1]\n", - "dr_loc = np.r_[dr_loc, dr_loc[-1]]\n", - "\n", - "Et = np.zeros((tt.size))\n", - "\n", - "\n", - "a0s = np.zeros_like(z_axis)\n", - "Et_evol = np.zeros((z_axis.size, tt.size))\n", - "\n", - "for iz, z_loc in enumerate(z_axis):\n", - " tt_offset = tt + z_loc / c\n", - " Et = get_temporal_1d(A_multi[iz,:,0], Et, tt_offset, prop.kz)\n", - " a0s[iz] = ( e / (m_e * c * omega_0)) * np.abs(Et).max()\n", - " Et_evol[iz, :] = Et" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "9a3ecb65", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'width: ' + width + 'px; height: ' + height + 'px;'\n", - " );\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.rubberband_canvas.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\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", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", - "mpl.findpos = function (e) {\n", - " //this section is from http://www.quirksmode.org/js/events_properties.html\n", - " var targ;\n", - " if (!e) {\n", - " e = window.event;\n", - " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", - " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", - " }\n", - "\n", - " // pageX,Y are the mouse positions relative to the document\n", - " var boundingRect = targ.getBoundingClientRect();\n", - " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", - " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", - "\n", - " return { x: x, y: y };\n", - "};\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " var canvas_pos = mpl.findpos(event);\n", - "\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " var x = canvas_pos.x * this.ratio;\n", - " var y = canvas_pos.y * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We want\n", - " * to control all of the cursor setting manually through the\n", - " * 'cursor' event from matplotlib */\n", - " event.preventDefault();\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\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", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure(figsize=(9,5), tight_layout=True)\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "010c2e7e", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "Text(0, 0.5, '$a_0$')" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.plot((z_axis-f0_corr)*1e3, a0s)\n", - "plt.ylim(0,)\n", - "plt.xlabel('Distance (mm)')\n", - "plt.ylabel(r'$a_0$')" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "89bd9e20", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'width: ' + width + 'px; height: ' + height + 'px;'\n", - " );\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.rubberband_canvas.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\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", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", - "mpl.findpos = function (e) {\n", - " //this section is from http://www.quirksmode.org/js/events_properties.html\n", - " var targ;\n", - " if (!e) {\n", - " e = window.event;\n", - " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", - " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", - " }\n", - "\n", - " // pageX,Y are the mouse positions relative to the document\n", - " var boundingRect = targ.getBoundingClientRect();\n", - " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", - " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", - "\n", - " return { x: x, y: y };\n", - "};\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " var canvas_pos = mpl.findpos(event);\n", - "\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " var x = canvas_pos.x * this.ratio;\n", - " var y = canvas_pos.y * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We want\n", - " * to control all of the cursor setting manually through the\n", - " * 'cursor' event from matplotlib */\n", - " event.preventDefault();\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\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", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure(figsize=(9,5), tight_layout=True)\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "e0d0baee", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "outputs": [], - "source": [ - "val = gaussian_filter(Et_evol[:,::-1]**2, 4).T\n", - "\n", - "SS = z_axis - f0\n", - "xi_max = np.zeros_like(SS)\n", - "val1d_max = np.zeros_like(SS)\n", - "\n", - "xi_loc = - c * tt[::-1]\n", - "\n", - "for i_s in range(SS.size):\n", - " val1d = val[:, i_s]\n", - " val1d_max[i_s] = val1d.max()\n", - " \n", - " xi_max[i_s] = np.average(xi_loc, weights=val1d)\n", - "\n", - "\n", - "dS = SS[1] - SS[0]\n", - "beta_g = (c+np.gradient(xi_max, dS/c))/c\n", - " \n", - "plt.plot(xi_max*1e6, SS*1e3, c='b')\n", - "\n", - "plt.plot( SS**2/16/d0/(f0/2/R_las)**2*1e6, SS*1e3, '--', c='k' )\n", - "\n", - "\n", - "extent = [\n", - " -tt.max()*c*1e6, -tt.min()*c*1e6,\n", - " SS.min()*1e3,\n", - " SS.max()*1e3,\n", - " ]\n", - "\n", - "plt.imshow(val.T,\n", - " origin='lower',\n", - " aspect='auto',\n", - " cmap=plt.cm.nipy_spectral_r,\n", - " extent=extent\n", - " );\n", - "\n", - "plt.xlabel(r'$z-ct$ ($\\mu$m)')\n", - "plt.ylabel(r'S (mm)');" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "5e12069e", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'width: ' + width + 'px; height: ' + height + 'px;'\n", - " );\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.rubberband_canvas.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\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", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", - "mpl.findpos = function (e) {\n", - " //this section is from http://www.quirksmode.org/js/events_properties.html\n", - " var targ;\n", - " if (!e) {\n", - " e = window.event;\n", - " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", - " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", - " }\n", - "\n", - " // pageX,Y are the mouse positions relative to the document\n", - " var boundingRect = targ.getBoundingClientRect();\n", - " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", - " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", - "\n", - " return { x: x, y: y };\n", - "};\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " var canvas_pos = mpl.findpos(event);\n", - "\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " var x = canvas_pos.x * this.ratio;\n", - " var y = canvas_pos.y * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We want\n", - " * to control all of the cursor setting manually through the\n", - " * 'cursor' event from matplotlib */\n", - " event.preventDefault();\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\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", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure(figsize=(9,5), tight_layout=True)\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "0a986ca0", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "outputs": [], - "source": [ - "xi_max0 = SS**2/16/d0/(f0/2/R_las)**2 #*1e6\n", - "\n", - "beta_g0 = (c+np.gradient(gaussian_filter1d(xi_max0, 0.5), dS/c))/c\n", - "\n", - "trunc_filt = (val1d_max > 0.25 * val1d_max.max())\n", - "\n", - "plt.plot(SS[trunc_filt]*1e3, beta_g0[trunc_filt],'--', c='k' )\n", - "#plt.plot(SS[trunc_filt]*1e3, beta_g[trunc_filt], label='PFC=-30 fs/cm$^2$' )\n", - "\n", - "plot_colored(SS*1e3, beta_g, val1d_max, steps=2, cmap=plt.cm.Reds )\n", - "\n", - "plt.xlabel(r'S (mm)')\n", - "plt.ylabel(r'$v_g/c$')\n", - "\n", - "plt.ylim(0.995,);" - ] - }, - { - "cell_type": "markdown", - "id": "b48aad15", - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "# Check the smallest required radius" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "610c1c72", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Available backends are: NP, CL, CU\n", - "CU is chosen\n", - "Full sag 1188.46 wavelengths\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "b888fa0b3c18408abc57829b7a247ca7", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - " 0%| | 00:00open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure(figsize=(9,5), tight_layout=True)\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "id": "5a1344c4", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "outputs": [], - "source": [ - "extent = [ (z_axis.min()-f0_corr)*1e3,\n", - " (z_axis.max()-f0_corr)*1e3,\n", - " 0,\n", - " prop.r_new.max()*1e6]\n", - "\n", - "plt.imshow(np.log10((np.abs(A_multi[..., ::3])**2).sum(1)).T, \n", - " aspect='auto',\n", - " extent=extent,\n", - " origin='lower', \n", - " cmap=plt.cm.nipy_spectral)\n", - "\n", - "plt.colorbar()\n", - "plt.xlabel('Distance (mm)', fontsize=14)\n", - "plt.ylabel('R ($\\mu$m)', fontsize=14);" - ] - }, - { - "cell_type": "markdown", - "id": "3e5c65fc", - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "# Do a sigle step propagation to extraction" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "id": "42f77895", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Full sag 1188.46 wavelengths\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "ed57fd70000b4b3c85100e102fb85401", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - " 0%| | 00:00open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure(figsize=(9,5), tight_layout=True)\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "48872584", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "outputs": [], - "source": [ - "dt = 0.8e-6/c / 24\n", - "dz = dt*c\n", - "dNr = 4\n", - "\n", - "tt = np.arange(-100e-6/c, 25e-6/c, dt)\n", - "\n", - "r_loc = prop.r_new[::dNr]\n", - "dr_loc = r_loc[1:] - r_loc[:-1]\n", - "dr_loc = np.r_[dr_loc, dr_loc[-1]]\n", - "\n", - "Et = np.zeros((tt.size, r_loc.size))\n", - "Et = get_temporal_radial(Afin[:,::dNr], Et, tt + z_loc/c , prop.kz)" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "id": "536c8054", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "outputs": [], - "source": [ - "ext = [ tt.min()*c*1e6, tt.max()*c*1e6, \n", - " r_loc.min()*1e3, r_loc.max()*1e3 ]\n", - "\n", - "plt.imshow(np.abs(Et).T, \n", - " origin='lower', aspect='auto', \n", - " extent=ext, \n", - " cmap=plt.cm.nipy_spectral,\n", - " vmax=1e10,\n", - " )\n", - "\n", - "plt.xlabel(r'z ($\\mu$m)', fontsize=14)\n", - "plt.ylabel(r'R (mm)', fontsize=14);" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "id": "e1dd3cfe", - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "outputs": [], - "source": [ - "with h5py.File('./axibeam_demo.h5', mode='w') as f_out:\n", - " f_out['A0'] = Afin\n", - " f_out['kz'] = prop.kz\n", - " f_out['r'] = prop.r_new\n", - " f_out['time_offset'] = z_loc/c" - ] - }, - { - "cell_type": "markdown", - "id": "e8637ca7", - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "# Setup and run the FBPIC case" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f84a951c", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [], - "source": [ - "### FBPIC script laser input\n", - "\n", - "from axiprop.utils import AxipropLaser\n", - "\n", - "with h5py.File('../axibeam_demo.h5', mode='r') as f_in:\n", - " A0 = f_in['A0'][()]\n", - " kz = f_in['kz'][()]\n", - " rr = f_in['r'][()]\n", - " time_offset = f_in['time_offset'][()]\n", - "\n", - "laser_profile = AxipropLaser(1.0, A0, kz, rr,\n", - " time_offset=time_offset,\n", - " z0 = z0_axibeam)\n", - "\n", - "# Large steps in vacuum\n", - "Nz, Nr, Nm = 2624, 768, 2\n", - "\n", - "L_prop = 17e-3\n", - "num_diags = 100\n", - "dt = L_prop / num_diags / c\n", - "diag_period = 1\n", - "N_step = diag_period * num_diags\n", - "\n", - "sim = Simulation( ..., exchange_period=1)" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "eccf3e72", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "outputs": [], - "source": [ - "ts = LpaDiagnostics('./axibeam_demo/diags/hdf5/')" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "3df7f37a", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'width: ' + width + 'px; height: ' + height + 'px;'\n", - " );\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.rubberband_canvas.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\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", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", - "mpl.findpos = function (e) {\n", - " //this section is from http://www.quirksmode.org/js/events_properties.html\n", - " var targ;\n", - " if (!e) {\n", - " e = window.event;\n", - " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", - " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", - " }\n", - "\n", - " // pageX,Y are the mouse positions relative to the document\n", - " var boundingRect = targ.getBoundingClientRect();\n", - " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", - " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", - "\n", - " return { x: x, y: y };\n", - "};\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " var canvas_pos = mpl.findpos(event);\n", - "\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " var x = canvas_pos.x * this.ratio;\n", - " var y = canvas_pos.y * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We want\n", - " * to control all of the cursor setting manually through the\n", - " * 'cursor' event from matplotlib */\n", - " event.preventDefault();\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\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", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure(figsize=(9,5), tight_layout=True)\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "8db08fa6", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.plot(ts.t*c*1e3, [ts.get_a0(pol='x',t=t) for t in ts.t])" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "d100c60a", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.plot((z_axis-f0_corr)*1e3, a0s, '--')" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "0cb89198", - "metadata": { - "slideshow": { - "slide_type": "subslide" - } - }, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'width: ' + width + 'px; height: ' + height + 'px;'\n", - " );\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.rubberband_canvas.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\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", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", - "mpl.findpos = function (e) {\n", - " //this section is from http://www.quirksmode.org/js/events_properties.html\n", - " var targ;\n", - " if (!e) {\n", - " e = window.event;\n", - " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", - " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", - " }\n", - "\n", - " // pageX,Y are the mouse positions relative to the document\n", - " var boundingRect = targ.getBoundingClientRect();\n", - " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", - " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", - "\n", - " return { x: x, y: y };\n", - "};\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " var canvas_pos = mpl.findpos(event);\n", - "\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " var x = canvas_pos.x * this.ratio;\n", - " var y = canvas_pos.y * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We want\n", - " * to control all of the cursor setting manually through the\n", - " * 'cursor' event from matplotlib */\n", - " event.preventDefault();\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\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", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure(figsize=(9,5), tight_layout=True)\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "id": "06a994cc", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "outputs": [], - "source": [ - "ts.get_field('E','x', plot=True, cmap=plt.cm.seismic, t=ts.t[0]);" - ] - } - ], - "metadata": { - "celltoolbar": "Slideshow", - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/slides_axibeam.slides.html b/docs/slides_axibeam.slides.html deleted file mode 100644 index a9d9701..0000000 --- a/docs/slides_axibeam.slides.html +++ /dev/null @@ -1,25380 +0,0 @@ - - - - - - - - - -slides_axibeam slides - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-
-
-
-
-
-
- - - - - - - - - - - diff --git a/examples/example.ipynb b/examples/example.ipynb index 2e86ca5..b6efdb8 100644 --- a/examples/example.ipynb +++ b/examples/example.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -27,7 +27,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -59,7 +59,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -116,18 +116,9 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Available backends are: NP, CL, CU, NP_FFTW\n", - "CU is chosen\n" - ] - } - ], + "outputs": [], "source": [ "dr = w0/2 # estimate grid resolution\n", "Nr = int( Rmax / dr ) # total radial grid number\n", @@ -149,7 +140,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -161,20 +152,9 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjwAAAG1CAYAAAD9WC4XAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAA9hAAAPYQGoP6dpAABY5klEQVR4nO3dd3hUVeLG8e+kEyCBEAhEQgi9g4TeFJFgQEREQP2tgIIrrkpTV5FVV9cV17WgItjAsqsIioAFhSgISK9KbwmEEloCaYS0ub8/CFkjxQyZ5MxM3s/zzLPJnTszb2Zl8ubec8+xWZZlISIiIuLBvEwHEBERESltKjwiIiLi8VR4RERExOOp8IiIiIjHU+ERERERj6fCIyIiIh5PhUdEREQ8no/pACbY7XaOHj1K5cqVsdlspuOIiIhIMViWRXp6OuHh4Xh5OXbMplwWnqNHjxIREWE6hoiIiFyFQ4cOUbt2bYceUy4LT+XKlYHzb1hQUJDhNCIiIlIcaWlpREREFP4ed0S5LDwXTmMFBQWp8IiIiLiZqxmOokHLIiIi4vFUeERERMTjqfCIiIiIx1PhEREREY+nwiMiIiIeT4VHREREPJ4Kj4iIiHg8FR4RERHxeCo8IiIi4vFUeERERMTjGS88y5cvp3///oSHh2Oz2Zg/f/4fPmbZsmVER0cTEBBAvXr1ePvtt0s/qIiIiLgt44UnMzOT1q1bM3Xq1GLtn5CQQN++fenevTubN2/mySefZMyYMcydO7eUk4qIiIi7Mr54aGxsLLGxscXe/+2336ZOnTpMmTIFgKZNm7JhwwZefvllBg0aVEopRURExJ0ZP8LjqNWrVxMTE1NkW58+fdiwYQO5ubmXfEx2djZpaWlFbiLiYex2yM0terPbTacSERfhdoXn2LFjhIWFFdkWFhZGXl4ep06duuRjJk+eTHBwcOEtIiKiLKKKSFnZvBnq1wc/v6K3RYtMJxMRF+F2hQfAZrMV+d6yrEtuv2DixImkpqYW3g4dOlTqGUWkjOzcCTExcOCA6SQi4sLcrvDUrFmTY8eOFdl24sQJfHx8qFat2iUf4+/vT1BQUJGbiHiAc+cgNhZOnWKrvz/XAFV/c/Pr25euXbtydN8+ePxxyMgwm1dEjHG7wtO5c2fi4uKKbFu8eDHt2rXD19fXUCoRMSIggC0jRrDFy4ue2dkcBc785pYLrFq1iq2tWsFLL8GAAedLkoiUO8YLT0ZGBlu2bGHLli3A+cvOt2zZQmJiInD+dNSwYcMK9x89ejQHDx5kwoQJ7Ny5k5kzZzJjxgweffRRE/FFxKDZs2fT4YUXiLbbufbGG0lMTOTYsWOFt61bt9KwYUOeysoiw2aDJUtgyJDzA5pFpHyxDFu6dKkFXHQbPny4ZVmWNXz4cOu6664r8piffvrJuvbaay0/Pz+rbt261vTp0x16zdTUVAuwUlNTnfRTiEiZSUuzrNtvtz569lnLZrNZgDV06FDr3Llzl9z9+PHjVnR0tHUdWGfBssCy7rjDsuz2Mg4uIiVVkt/fNssqGPFbjqSlpREcHExqaqrG84i4GevJJ7FNnsxGoB3w4IMP8vrrr+Pt7X3Zx6SnpzNw4ED8fvyR+YAfwNy5cNttZZJZRJyjJL+/jZ/SEhEpttOnyX3tNQD+CTz77LO8+eabVyw7AJUrV+bbb7+l0uDBvFSw7ezf/nb+eI+IlAsqPCLiNvLfeAO/c+fYCrR66imefvrpy05H8Xv+/v7MmjWLXX36kAHk7d+vS9lFyhEVHhFxD+np5P773wC8Wbkyjz3+uMNP4e3tzaTXXuNmIDwnhy2pqU4OKSKuSoVHRNxC/rRpBGRmsgdo/Le/UbFixat6nqZNmxJ+551kAs8995xTM4qI69KgZQ1aFnF9WVlk1axJhbQ0Hq5cmReTkq668ADs3LmT5s2bY1kWe2bMoOG99zoxrIiUFg1aFhGPlpebyzQfH9YDUZMmlajswPmjPHcOHsxaoOHIkbBypVNyiojrUuEREZf33y+/5NGUFPqFhnL/Qw855TknPfMMvxZ8nXYV44FExL2o8IiIS8vLy+P5558H4K+PP17iozsXNGvWjK39+pEPBK1cCRs3OuV5RcQ1qfCIiOvKy+Nw584027+f6qGhPPDAA059+vtfeolPC74+89e/OvW5RcS1qPCIiMvK/+QT6m7YwPvAk+PHO+3ozgXNmjXjl9hY7ECVJUtg+3anPr+IuA4VHhFxWSdeOj8v8szAQO4bO7ZUXuPel19mQcHXJ19+uVReQ0TMU+EREdd04gQ1duwAIOiBB5x+dOeCZs2asa9TJwBSf/ihVF5DRMxT4RERl3Rm5ky8gXXAzWPGlOprNR43jvZAT8vCbreX6muJiBkqPCLiktJnzgRgbWQkderUKdXXihkwgD1BQRw+coTVq1eX6muJiBkqPCLieo4dI3zvXgAqDh9e6i8XEBDAgAEDAPj800+1irqIB1LhERGXc2zrVlYBq4E+f/5zmbzm0KFDeQ14Zvp08letKpPXFJGyo8IjIi7nk19/pQfwt65dueaaa8rkNXv37k1tX1+qWhZHX3+9TF5TRMqOCo+IuJzZs2cDcNudd5bZa/r5+XG0e3cAKn73HWjwsohHUeEREZdyaNEi4tevx8vLi9tvv71MX7vpuHGkASEZGeRpQVERj6LCIyKuZfRojgFPNWtGWFhYmb709TfdxPd+fgAcee21Mn1tESldKjwi4jqOHOGaAwfwARr+6U9l/vK+vr6c7NkTgMqLFum0logHUeEREZdxYvp0vICVQJ+RI41kaDZuHKlAyNmz5C5fbiSDiDifCo+IuIxz//kPAL82aUJoaKiRDD1692ZmxYo8D6w4cMBIBhFxPhUeEXENhw9TJzEROxBy333GYnh7e7N/xAieAj5autRYDhFxLhUeEXEJSVOnArDSZiPmnnuMZhk6dCgA8+fP59y5c0aziIhzqPCIiEvInjULgB3NmlG1alWjWbp27UrjWrW4Pi2NX//+d6NZRMQ5VHhExCXcX7EiI4BqBk9nXeDl5cXj117LAqDWu++ajiMiTqDCIyLGHT9+nMU7d/IR0KMMZ1e+kjrDhmEHIk6fxkpKMh1HREpIhUdEjPvxxx8BaN26NTVq1DCc5rzO/fuzxWYDIOmTTwynEZGSUuEREeNq/uMfjANuKVjLyhUEBgayOyICgNQvvjCcRkRKSoVHRIyykpK4YdcuXgN6ulDhAaBXLwCq//ILWJbhMCJSEio8ImLUhdNFm202Ot58s+E0RTW85x7OAaHnzpG3Y4fpOCJSAio8ImLUmYLTRXsiIggMDDScpqhru3RhrY8PAAf++1/DaUSkJFR4RMQcy6L6r7+e/7Lg9JEr8fb25pvrrqM+8GlAgOk4IlICKjwiYkzujh1Uz8oiG2h0772m41xSg8GDiQfifvjBdBQRKQEVHhExJnHmTADW+fjQunNnw2kurXfv3gCsWbOG9PR0w2lE5Gqp8IiIMYc3biQbONSkCd7e3qbjXFK9evUYXrMmc/LySJwwwXQcEblKKjwiYsykvDyqAjmjRpmOckW9GzZkIOD33Xemo4jIVVLhEREj0tLSWLNmDVnAdbfcYjrOFYUMHgxA3SNHIDPTcBoRuRoqPCJixLK4OPLz86lfvz5RUVGm41xRx7vu4gDgC5z88kvDaUTkaqjwiIgRjceNYwtwf8uWpqP8oZBq1fglNBSAE59+ajiNiFwNFR4RKXuZmdQ9coTWQCsXnH/nUrK6dgWg0tq1hpOIyNVQ4RGRMndy3jz8LIuDQIe77jIdp1hqDxsGQOTp01jHjxtOIyKOUuERkTJ3rGD9rF9CQ6kaEmI4TfG079ePjV5erAD2/Pyz6Tgi4iAVHhEpc5ULTgud69bNcJLi8/f35+nevekBfHvwoOk4IuIgFR4RKVPWmTPUOX0agNp/+pPhNI7pFRMDwI8//mg4iYg4SoVHRMpU0rx5eAHxQNt+/UzHcUiPHj0A2LpyJfazZw2nERFHqPCISJnafPAgHwOrwsMJcLMVyFu3bs2X3t4kpKZyuGAdMBFxDyo8IlKmvkpKYjjwi5tcnfVbvr6++NWogTeQ8s03puOIiANUeESkTK1cuRKArgXz2rib7OhoACps3mw4iYg4QoVHRMrMmT178Nq+HS+gS5cupuNcldABAwCoe/Ik5OQYTiMixaXCIyJl5siUKfwKLKpYkRo1apiOc1Va3347pwB/yyLlhx9MxxGRYlLhEZEyk7t8OQDpDRsaTnL1gqtUYVvlygAcnjPHcBoRKS4VHhEpM2H79gHg37On4SQlc7pZMwCsgvFIIuL6VHhEpEzkJCRQKzubfKC+G16h9Vv+ffvyX2Cu3W46iogUkwqPiJSJg7NmAbDd25uGbdsaTlMyTe++m7uByYmJnNUEhCJuQYVHRMpE2qJFAByqXRsvL/f+6Klbty61atUiLy+P9evXm44jIsXg3p86IuI2Km/dCkB+p06Gk5SczWajW5cuNAcOFqz8LiKuTYVHREqdZVlMBP4OhA0ZYjiNc9wdFMQ2oNtnn5mOIiLFoMIjIqUuPj6eL0+f5gVfX1rFxpqO4xQRgwcDUDc9HfuZM2bDiMgfconCM23aNKKioggICCA6OpoVK1Zccf9PPvmE1q1bExgYSK1atbjnnntITk4uo7Qi4qgLy0lER0dToUIFw2mco/mNN5Jgs+EFJGo+HhGXZ7zwzJ49m3HjxjFp0iQ2b95M9+7diY2NJTEx8ZL7//zzzwwbNoyRI0eyfft2Pv/8c9avX8+oUaPKOLmIFJc1YwYDgBvatTMdxWl8fX3ZWzBbdPLXXxtOIyJ/xHjhefXVVxk5ciSjRo2iadOmTJkyhYiICKZPn37J/desWUPdunUZM2YMUVFRdOvWjfvvv58NGzaUcXIRKRa7nQErVzIf6B0RYTqNU5279loA/DduNJxERP6I0cKTk5PDxo0biYmJKbI9JiaGVatWXfIxXbp04fDhwyxcuBDLsjh+/DhffPEF/fr1u+zrZGdnk5aWVuQmImUjdf16quTncxZo6uYTDv5eSP/+ANQ9dgzy8w2nEZErMVp4Tp06RX5+PmFhYUW2h4WFcezYsUs+pkuXLnzyyScMHToUPz8/atasSZUqVXjzzTcv+zqTJ08mODi48BbhYX9liriyg59+CsC2gADCatc2nMa5WgwdSipQybJI/ukn03FE5AqMn9KC83Na/JZlWRdtu2DHjh2MGTOGp59+mo0bN/L999+TkJDA6NGjL/v8EydOJDU1tfB26NAhp+YXkcvLWbYMgBMNGhhO4nxVqlXjpWuuoQ/w8/HjpuOIyBUYLTyhoaF4e3tfdDTnxIkTFx31uWDy5Ml07dqVxx57jFatWtGnTx+mTZvGzJkzSUpKuuRj/P39CQoKKnITkbJRfe9eAHyvv95skFKSfPPNLAaWaxyPiEszWnj8/PyIjo4mLi6uyPa4uDi6dOlyycecPXv2omnpvb29gfNHhkTEdeQeP05kwVpTde+803Ca0tG1a1fgf5fei4hrMn5Ka8KECbz//vvMnDmTnTt3Mn78eBITEwtPUU2cOJFhw4YV7t+/f3++/PJLpk+fTnx8PCtXrmTMmDF06NCB8PBwUz+GiFzCgblzAdjv5UVDD1hS4lK6dOnCLcDA9evJucxRZhExz8d0gKFDh5KcnMxzzz1HUlISLVq0YOHChURGRgKQlJRUZE6eESNGkJ6eztSpU3nkkUeoUqUKN9xwA//6179M/QgichlLvLzoC/SLjmaKmy8Yejn16tXjFS8vGtjt7Jkzh0Zjx5qOJCKXYLPK4XmgtLQ0goODSU1N1XgekVI0cuRIZs6cyZNPPsk///lP03FKzZLwcG5ISmJdv350+OYb03FEPFZJfn975p9cIuIS1q9fD0CHDh0MJyld51q2BMDvl18MJxGRy1HhEZFSkblvH3/bupWxQPv27U3HKVVBvXoBUDspCcrfQXMRt6DCIyKl4sCcOQwB7vfx8fgLChrcfjt5QGh+Phm7dpmOIyKXoMIjIqUifckSAI5cc43hJKWvZr167Pb1BeDA558bTiMil6LCIyKlosK2bQDktWljNkgZOVpQ7NIKZpYWEdeiwiMizmdZRJ48CUDITTcZDlM2EoYMoSHwWtWqpqOIyCWo8IiI0yWvW0cVu51zQOPbbzcdp0w0io1lH7Cu4Mo0EXEtKjwi4nSJBTMs7woIIDg01HCashEdHY3NZiMxMZHjWkhUxOWo8IiI053csoVc4GTBjOnlQeXKlZkQHs5nwMG33jIdR0R+R4VHRJzudV9fKgMJI0aYjlKmYoKCGArkL1pkOoqI/I4Kj4g4lWVZrFu3jmygdc+epuOUKa+CGaWD9uwxnEREfk+FR0Sc6uDBg5w6dQpfX19at25tOk6ZCrv5ZgCizpzBys01nEZEfkuFR0Sc6vjLL7MBeCEsjICAANNxylTjm28mFQgEDuu0lohLUeEREaey//wz0UDrcnJ11m/5BQSwp2AF56QFCwynEZHfUuEREacK2b8fAJ/OnQ0nMeN0gwYA5K9ZYziJiPyWCo+IOE1+Zib1MjIAuObWW82GMcSva1dygfRjx0xHEZHfUOEREac5sGABvsApoP4NN5iOY0StUaOoDNyamUleXp7pOCJSQIVHRJzmxLffArA3JARvHx/Dacxo2KIF/kFBZGVlsX37dtNxRKSACo+IOI1twwYAMpo0MZzEHC8vL9q1awfA+nXrDKcRkQtUeETEafacOUMCENCjh+koRv0pJIQNQJOXXzYdRUQKlM9jziLidOfOnWNkSgp5wIH77zcdx6hGjRsTDSQcPGg6iogU0BEeEXGKLVu2kJeXR/Xq1alTjhYNvZSoIUPO/292NmeTkgynERFQ4RERJ/l11SoA2rVrh81mM5zGrFotW3LI6/zH6wFNQCjiElR4RMQpWk6bRgpwbzm9Ouu3bDYbhwpmmj7944+G04gIqPCIiJPUOHKEqkB4q1amo7iEswVXqtm2bDEbREQAFR4RcYLslBTqnjsHQMSAAYbTuIbAbt0AqHH4sOEkIgIqPCLiBPHz5uENHLPZqF0wB015FzFgAPuAjdnZZBeUQRExR4VHREos5YcfADhQrVq5H7B8Qe327elQtSp3WBbbd+wwHUek3FPhEZGS27wZgMxGjQwHcR02m43o6GgANm7caDiNiKjwiEiJVU9MBMC/SxfDSVxL27ZtAdhdcMm+iJijwiMiJZKbm8sXOTksAmrfcovpOC4lpkIFTgP3zZljOopIuafCIyIlsmPHDibl5zM0OJjIgiuT5Lx6119PFaDe2bPkZmSYjiNSrjk8Q1hmZiY//fQTK1eu5MiRI2RlZREaGkqzZs3o2bMnzZs3L42cIuKiNm3aBMC1116rAcu/E9m9Oyk2GyGWxd5vvqHhHXeYjiRSbhW78Ozdu5dXXnmFTz/9lIyMDGw2G1WqVCEgIIDTp09z7tw5bDYbLVu2ZMyYMYwYMQIvLx1AEvF0h+PiqAaFA3Tlf7y8vYkPDibkzBlOLFqkwiNiULEayfjx42nRogWrVq3iqaeeYu3atWRnZ5OcnMyRI0c4e/YsR44c4fPPP6dVq1aMHTuWVq1asWHDhtLOLyKG3fb115wCbrHbTUdxSWkNGgBg6fNQxKhiHeHZtGkTcXFx9OjR47L71KpVi9tuu43bbruNtLQ0pkyZwsqVK2mnSchEPFb+uXPULxibck2fPobTuCbfjh1hwwZCDhwwHUWkXLNZlmWZDlHW0tLSCA4OJjU1laCgINNxRNzWvi+/pMGgQaQClXJy8Pb1NR3J5ez77jsa9O3LOcA3KwvvgADTkUTcVkl+f2uQjYhctePffw/A/uBglZ3LiLrxRr729uZVYN+2babjiJRbKjwictXy168HILVePcNJXJe3ry8vduzIJGDD7t2m44iUW04tPA0bNqR+/frOfEoRcWFV4uMB8G7f3nAS13ZhxuULl/CLSNlzauGxLAu7rtQQKRfsubnUS0sDoFa/fobTuLbo6GhCgayffjIdRaTccnjiwSvZt2+fM59ORFzY/t27eRFo5+3NfbpC64o6h4RwEsjYtAl7Xh5ePk796BWRYtAYHhG5Khu3bWMm8FG7dvj4+5uO49LqxcRwFqgEHFqyxHQckXJJhUdErsrGjRsBzbBcHL4BAeyrWBGAo99+aziNSPnk8HHVqKioK66XY7PZ2L9/f4lCiYjrq7BoER2Bdi1bmo7iFlLq1oXt28lZs8Z0FJFyyeHCc911111UeE6dOsWqVasICgriuuuuc1o4EXFNlt3OI1u38hywq0oV03Hcgi06GrZvJ2jvXtNRRMolhwvPhx9+eMntycnJ9O7dm366WkPE4x1avpw6QDZQr39/03HcQvU+feDjj6l35gyW3Y5NiyuLlCmn/YurVq0ajz32GM8++6yznlJEXNSRr78GYF9gIH4FY1Pkyur37082EGxZHF250nQckXLHqX9ihIaGEl8wEZmIeK7s1asBSK5Tx3AS9+FfuTLv1KrFvcDmhATTcUTKHacVntzcXN577z2ioqKc9ZQi4qIq7dkDgFUwg7AUz699+/IBsKbg/RORsuPwGJ4bbrjhom3Z2dns2bOHlJQUPvroI6cEExHXZNntRKakAFA9JsZwGvfStm1bZsyYoSUmRAxwuPDY7faLrtIKCgri9ttv5+6776ZLly5OCyciridpwwbCLYs8oN6AAabjuJW2rVrREWj6888auCxSxhwuPD9pLRiRcm3jwYPcCXSvXZvndUm6Q1o3a8bPgE96Osc2baJmu3amI4mUG/rzQkQcsn7rVpYDR3v3Nh3F7VQICSG+YBmOQwsWGE4jUr44tfAcOnSIxMREZz6liLiYC+NP2mrA8lU5Xrs2AJkrVhhOIlK+OHXJ3nr16mFZFnl5ec58WhFxIb2WLSMYaNesmekobim/VSvYv5/AXbtMRxEpV5xaeIYNG4bdbnfmU4qICzn+yy+Mz8jADmS1aGE6jluqeuONMG8eEadOmY4iUq449ZTWjBkz+OCDD5z5lCLiQg7Onw9Agp8fFWvUMBvGTdUbOBA7UCs/n5PbtpmOI1JuaNCyiBTbhXEnx8PDDSdxX5Vr1SLBzw/4X4EUkdJXosJz8uRJEhMTL7o5atq0aURFRREQEEB0dDQr/mAwX3Z2NpMmTSIyMhJ/f3/q16/PzJkzr/bHEJFiCtixA4C8Vq0MJ3Fvczt35jpgqcY7ipSZqxrD8/zzz/PGG2+QnJx8yfvz8/OL/VyzZ89m3LhxTJs2ja5du/LOO+8QGxvLjh07qHOZdXqGDBnC8ePHmTFjBg0aNODEiRMaKC1SBq45cQKA4J49DSdxb979+7N82TKq65SWSJlxuPDMnDmTF198kSeeeIKnn36aSZMmYVkW//nPf6hQoQKPP/64Q8/36quvMnLkSEaNGgXAlClTWLRoEdOnT2fy5MkX7f/999+zbNky4uPjCQkJAaBu3bqO/hgi4qBTe/ZQp+CPmajbbjOcxr1duKRfS0yIlB2HT2m99dZbPPnkk0ycOBGAgQMH8vzzz7Nr1y4qV67MKQeuPMjJyWHjxo3E/G49npiYGFatWnXJx3z11Ve0a9eOl156iWuuuYZGjRrx6KOPkpWVddnXyc7OJi0trchNRByTUDDeJNHXlyCtkl4i17Zpw13AQwkJnI6PNx1HpFxwuPDs27ePTp064VWwBkxOTg4AFSpU4JFHHuHdd98t9nOdOnWK/Px8wsLCimwPCwvj2LFjl3xMfHw8P//8M9u2bWPevHlMmTKFL774ggcffPCyrzN58mSCg4MLbxEREcXOKCLn/ZCXxzXAOzqdVWJVqlblBR8fJgAJc+eajiNSLjhceHx8zp8Fs9lsBAUFcfjw4cL7QkNDOXLkiMMhfr8YqWVZF2274MLipZ988gkdOnSgb9++vPrqq3z44YeXPcozceJEUlNTC2+HDh1yOKNIebdp82aOAlVuvNF0FI9wtGZNANK0PqFImXC48DRs2LCwMLRv35733nuP3Nxc8vPzeffddx0aTxMaGoq3t/dFR3NOnDhx0VGfC2rVqsU111xDcHBw4bamTZtiWVaR8vVb/v7+BAUFFbmJiGO0pIRzZTdvDoCfBi6LlAmHC0/fvn1Zvnw5cP7IyZIlS6hSpQohISHMnTvXoUHLfn5+REdHExcXV2R7XFwcXbp0ueRjunbtytGjR8nIyCjctmfPHry8vKhdsEaNiDjX6cREXo2P52mgbevWpuN4hMo9egBQMynJcBKR8sFmWZZVkidYv349n332GTabjX79+tHTwfP7s2fP5u677+btt9+mc+fOvPvuu7z33nts376dyMhIJk6cyJEjR/j4448ByMjIoGnTpnTq1Ilnn32WU6dOMWrUKK677jree++9Yr1mWloawcHBpKam6miPSDFsnDKF6PHjOertTbimgHCKUzt2EFpwlCft0CGC9AebyB8qye/vEq+l1b59e9q3b3/Vjx86dCjJyck899xzJCUl0aJFCxYuXEhkZCQASUlJRSYzrFSpEnFxcTz88MO0a9eOatWqMWTIEJ5//vmS/igichmpS5cCcLhGDTTHsnOENmt2vkDm5xM/bx5tHn7YdCQRj1biIzzuSEd4RByzPCqKHgcOsLxXL3r88IPpOB5jXa1adDh2jCWDBnHDF1+YjiPi8kry+7tYY3hatGjBvHnziv2kSUlJjBkzhhdffNGhMCLimsKOHgWgUsG4E3GO9UOGcA3wYYUKpqOIeLxiFZ4hQ4YwbNgw6tSpw8SJE1m0aBEnT57kwsGhrKwstm3bxvvvv0///v2JjIxk48aN3HLLLaUaXkRKX9qxYzQomG8rcuBAw2k8S92YGI4CGzXjskipK/YpraSkJKZMmcLMmTNJTk7GZrNhs9nw9fUtnHzQsiy6d+/O2LFjuc2Fp57XKS2R4ts8fTrX/uUvnPDyokZeHlxmjixxXFJSEuHh4Xh5eZGWlkbFihVNRxJxaSX5/e3wGJ7c3FzWrl3L6tWrOXr0KFlZWYSGhtKkSROuv/56t7g0XIVHpPi+GTGCnh99xK4aNYg+ftx0HI/zdHAw7dLSiPzgA1qPGGE6johLK9OrtHx9fenWrRvdunVz9KEi4obm2O0MAF685x6iTYfxQLf4+9MO+Om770CFR6TUODzxoIiUL5s2bcIONNUfOaUis1EjAGxbtpgNIuLhVHhE5LIyMzPZuXMnANHROr5TGip07QpAda3xJ1KqVHhE5LL2ff45v9rtzAgMpFatWqbjeKTaBVezNsjK4lxamuE0Ip5LhUdELis5Lo7mQFvNE1NqanXuzBmbDT9g/1dfmY4j4rFUeETk8grmh8koGGcizmfz8iKhalUATi5aZDiNiOdyuPAcO3asNHKIiAsKLVjHzr9zZ8NJPFt6w4ZkAif37jUdRcRjOVx46tSpw5133snKlStLI4+IuIhzGRk0PHsWgGv69zecxrOlPPQQQcCLubmmo4h4LIcLz9/+9jdWrFhBjx49aNOmDTNmzCArK6s0somIQfu++YYKQLrNRq3u3U3H8Witu3bFDmzdurVw5noRcS6HC8/TTz/NwYMHmTVrFkFBQdx3333Url2bRx99lP3795dGRhEx4ETBeJKEKlWweXsbTuPZ6tatS9WqVcnNzWXbtm2m44h4pKsatOzt7c2QIUNYvnw5W7ZsYdCgQbz99ts0btyYm2++mUUaeCfi9g4cPMg24EzDhqajeDybzcbLVauyHUibNs10HBGPVOKrtFq2bElsbCwtWrTAbrfz448/0rdvX9q1a8eePXuckVFEDJiWlkZL4MSjj5qOUi40qlqVZoB93TrTUUQ80lUXnlOnTjF58mSioqK4/fbb8fHxYfbs2aSlpTF//nzS09MZoXVhRNxSTk4OW7duBaCtZlguE74dOwJQ9cABs0FEPJTDi4euXbuWt956i88//xzLshg6dChjx46lbdu2hfv0798fHx8fbr31VmdmFZEysvOXX8jPySE4OJioqCjTccqFmn37wrRpNEhPJzc7G19/f9ORRDyKw4Wnc+fO1KxZkyeeeIIHHniAGjVqXHK/unXr0qVLlxIHFJGyl/L++6QBSwMDsdlspuOUCxG9e5MFVAZ2LVpEk4IlJ0TEORw+pfXxxx9z8OBBnnnmmcuWHYCmTZuydOnSEoUTETPy1q0jEKgaFmY6Srnh5edHQuXKABz/7jvDaUQ8j8OFJz4+npMnT17yvqSkJJ577rkShxIRs6rExwPg3b694STly+l69QDI0cBlEadzuPA8++yzHD58+JL3HT16lGeffbbEoUTEnLzcXOoXrNodFhtrOE354tWxI1uBPcnJpqOIeByHC49lWZe9LyMjA19f3xIFEhGz9v/4IyFADlBHhadMVR0/nlbAX0+eJD8/33QcEY9SrEHLv/76K1u2bCn8fuHChezatavIPllZWXzyySfUr1/fqQFFpGwlffstjYGESpVoHBBgOk650rBhQypWrEhmZia7d++mWbNmpiOJeIxiFZ558+YVnqqy2WyXHadToUIFPvjgA+elE5Eyl7N2LQApkZGGk5Q/3t7etGnThjUrV/LLypUqPCJOVKzC8+c//5mbb74Zy7Lo0KEDH3zwAS1atCiyj7+/P/Xr16dChQqlElREysaqtDTOAtW0YKgRT9jt9AJWvP8+3Hef6TgiHqNYhadWrVrUqlULgKVLl9K2bVsqF1w+KSKew2638/Lhw2QC2x56yHSccim0YUMqrF5N0N69pqOIeBSHBy1fd911KjsiHmrv3r1kZmZSoUIFGjdubDpOuVS9Tx8A6p05g10Dl0WcplhHeO69916eeuopoqKiuPfee6+4r81mY8aMGU4JJyJla8eSJdQGIlq3xsfH4YnYxQki+/cnD6hhWexftYr6OrUo4hTF+kRbunQpY8eOBWDJkiVXnGpe09CLuK/A//yHQ8CK9HTTUcotn8qV2V+hAvWzsjj81VcqPCJOUqzCk5CQUPj1Aa3kK+KxKu3ZA4Bvy5aGk5RvJ+vUof7u3ZxbudJ0FBGP4fAYHhHxTHa7nXopKQCE3nST4TTlXNu2wP8KqIiUnMOF5+jRo+zevbvw+7y8PF566SXuuOMOZs6c6dRwIlJ24n/+mVqWRT5Q99ZbTccp10IHDGA+8GV6umZcFnEShwvP/fffzxtvvFH4/fPPP88TTzzB4sWLue+++/jvf//r1IAiUjYOz5sHQEJgID7BwYbTlG91Bw3i/wIDeTUnhz06yiPiFA4Xnk2bNtGzZ8/C79977z3Gjx9PSkoKf/7zn3nrrbecGlBEykZ2wXiR5Lp1zQYRfHx8aFtwWmv9+vWG04h4BocLT3JyMjVr1gRg586dJCUlMWLECAAGDRpU5HSXiLiPwonu2rc3G0QAaBcdTQRwePFi01FEPILDhSc4OJgTJ04AsHz5ckJCQmhZcEWHzWYjJyfHuQlFpNTl5eXx6tmzvALUGDzYdBwBhp49SyJwwzffmI4i4hEcLjwdOnTgX//6F19//TWvv/46MTExhffFx8cTHh7u1IAiUvp27NjBFzk5PBcURGRsrOk4AtQqmHG5YWoqufpDUqTEHC48//jHP4iPj2fAgAEcP36cSZMmFd43f/58OnTo4NSAIlL6LowTiY6OxstLs1W4goh+/cgGqgF7dVpLpMQcnju+TZs2HDx4kF27dtGgQQOCgoIK7/vLX/5Cw4YNnRpQRErfmQULuB7o2qqV6ShSwCsggITKlWmSnk7SV1/R7OabTUcScWtXtVhOYGBg4RUEv9WvX78SBxKRstfjp594BFifnW06ivzG6QYNYPNm8teuNR1FxO1dVeGxLIv169dz8OBBsrKyLrp/2LBhJQ4mImUjOyuLRgVrZ4X37284jfyWT+fOsHkzVePjTUcRcXsOF549e/Zwyy23sHfvXizLuuh+m82mwiPiRvZ8+y0tgSwgvHdv03HkN6655RaYNo3GGRmcO3uWgMBA05FE3JbDhefBBx/k3LlzzJ49m1atWuHv718auUSkjBz75htaAglVqtDM19d0HPmNWjfcwNQKFfg5K4sJmzfToWtX05FE3JbDhWfdunW899573H777aWRR0TKWsEVWqm64MDl2Hx9WXj99Xz33Xd037JFhUekBBy+/rRSpUpFrswSEfdW7cABAPz1y9QltS+Y+VpLTIiUjMOF55577uHTTz8tjSwiUsYyU1NpcvYsALUHDjScRi6lQ8uWXA/U+uEH01FE3JrDp7RatGjBrFmzuOWWW+jfvz/VqlW7aJ/bbrvNKeFEpHRt/uUXxgO9goN5sVs303HkEtqHhbEUOHvkCBlnzlCpShXTkUTcksOF56677gIgISGBby6xxovNZiM/P7/kyUSk1G3YtIkNQPh114FmWHZJNbp2Jc1mI8iy2DRvHm3vucd0JBG35HDhWbp0aWnkEBEDLowLaa8V0l2XlxcHq1Wj5alTnPr+e1DhEbkqDhee6667rjRyiIgB7RYtIhDo3Lix6ShyBelNm8KKFXht2mQ6iojbuqqZlgFSU1NZs2YNp06dom/fvlStWtWZuUSklJ05fpwHk5PxA1KiokzHkSuo2KMHrFhB2KFDpqOIuK2rOmn/j3/8g/DwcGJjYxk2bBgJCQkA9OrVixdffNGpAUWkdOyZOxc/4LSXFyHR0abjyBXUGTQIgMbZ2Zw+dsxwGhH35HDhmTZtGs8++ywjR47k22+/LbK8xM0338y3337r1IAiUjpOx8UBcLB6dbDZDKeRK6napg0pXl74AXvnzjUdR8QtOVx4pk6dyoQJE3jjjTeIiYkpcl/Dhg3Zu3ev08KJSOnx2bIFgKxmzcwGkT9ms/Fely60B5ampJhOI+KWHC488fHx9OnT55L3Va5cmTNnzpQ0k4iUgVpHjgBQ8frrzQaRYvEeMIANwNrNm01HEXFLDhee4OBgjh8/fsn7Dhw4QI0aNUocSkRK17F9+2icmwtAvaFDDaeR4ujYsSMAa9asKTKUQESKx+HC06tXL1566SUyMzMLt9lsNvLy8pg+ffplj/6IiOvY/cUXeANJvr5U0iXpbiG6bVtG2Ww8m5TEke3bTccRcTsOF57nnnuOgwcP0qxZMx555BFsNhtTp06lQ4cO7Nu3j6eeeqo0coqIEy08fZoQ4L3+/U1HkWIKrFiRp/38uA/YP2uW6TgibsfhwtOgQQNWrlxJ06ZNmTZtGpZl8fHHHxMaGsqKFSuoU6dOaeQUESdas2YNp4Ha/fqZjiIOSCr4fM3SjPciDruqeXiaNWvG999/T3p6OocPHyYtLY3FixfTtGnTqwoxbdo0oqKiCAgIIDo6mhUrVhTrcStXrsTHx4c2bdpc1euKlEd5eXmFS0p06tTJcBpxSMH/X0E7dxoOIuJ+HC489957b+FEg/7+/oSHh1OhQgUADh48yL333uvQ882ePZtx48YxadIkNm/eTPfu3YmNjSUxMfGKj0tNTWXYsGH06tXL0R9BpFzbvWgR32ZlMdnfnyZNmpiOIw6oNXAgAE3OnCH73DnDaUTci8OF58MPP+TkyZOXvO/UqVN89NFHDj3fq6++ysiRIxk1ahRNmzZlypQpREREMH369Cs+7v777+euu+6ic+fODr2eSHl3dO5cegK3+vvjpRXS3Urtvn3JAkKA3V9/bTqOiFtx6qddSkoK/v7+xd4/JyeHjRs3XjSBYUxMDKtWrbrs4z744AP279/PM888U6zXyc7OJi0trchNpLyyVq8G4IyO7rgdm78/8QXrFh6bP99sGBE3U6zFQ5cvX85PP/1U+P3777/P999/X2SfrKwsFixYQDMHZm09deoU+fn5hIWFFdkeFhbGscusF7N3716eeOIJVqxYgY9P8dY+nTx5Ms8++2yxc4l4srADBwAI0ISDbimtWTNYuZKMgpmyRaR4itUYli5dWlgYbDYb77///iX3i4yM5K233nI4hO136/hYlnXRNoD8/Hzuuusunn32WRo1alTs5584cSITJkwo/D4tLY2IiAiHc4q4u+QjR2haMPaj7h13GE4jVyN37FiqrVxJ0Nmz3GY6jIgbKVbh+etf/8pDDz2EZVnUqFGDRYsW0bZt2yL7+Pv7U6lSJYdePDQ0FG9v74uO5pw4ceKioz4A6enpbNiwgc2bN/PQQw8BYLfbsSwLHx8fFi9ezA033HDR4/z9/R061SbiqXbPmkUX4KS3N9V1daNbatOnD6dtNlIOHODYsWPUrFnTdCQRt1CswlOhQoXCK7ESEhKoVasWfn5+JX5xPz8/oqOjiYuLY2DB1QcAcXFxDBgw4KL9g4KC2Lp1a5Ft06ZNY8mSJXzxxRdERUWVOJOIJ0tbvBiAQ+HhVNcK6W4pKCiI5s2bs23bNtauXXvJz0oRuVjxBsH8RmRkpFMDTJgwgbvvvpt27drRuXNn3n33XRITExk9ejRw/nTUkSNH+Pjjj/Hy8qJFixZFHl+jRg0CAgIu2i4iFzuakEAKkBMdbTqKlMDD1atTHzg7dSqo8IgUi8OFJzc3l3/96198+umnHDx4kHO/mwviwrpaxTV06FCSk5N57rnnSEpKokWLFixcuLCwWCUlJf3hnDwi8sfsdjvjT5xgJLBl4kTTcaQEWlevTkfgZ62cLlJsNsvBZXcfffRRXnvtNWJjY2nVqtUlx8YU93JxU9LS0ggODiY1NZWgoCDTcUTKxI4dO2jevDmBgYGkpqYW+ypHcT3x//0v9e6+m+NAtZwcfHx9TUcSKRMl+f3t8CfenDlzePrpp12+1IhIUWtXrgSgffv2Kjturu7AgeQAYcCOuDia9e1rOpKIy3N44sHTp0/To0eP0sgiIqUofOpUDgBjCi5AEPflVbEi8QV/3R6dO9dwGhH34HDh6dGjB1s04ZWI2wndt49IoK4Dc1iJ6zrTuDEA9oKZs0XkyhwuPG+88QYzZszgyy+/JCcnpzQyiYiTpSUn0+zsWQAiBg82nEacwb9gpuywgsWcReTKHC48bdq0Yd++fQwePJjAwECCgoKK3IKDg0sjp4iUwK45c6gAnPHyonrXrqbjiBPUveMOTgMHzp0j+dQp03FEXJ7DIxcHDRp0yWUfRMR1nV64EICEsDCu1b9fj1D12mtp3KABe/btY+H69cTGxpqOJOLSHC48H374YSnEEJHS5FcwX0u2lpPwHDYbnbp0Yc++faxZs0aFR+QPOHxKS0Tci2VZ1E1KAqDKTTcZTiPO1KlTJwB++flnw0lEXF+xjvBs2rTJoSf9/cKiImLO3l27WGi3c53NRrOhQ03HESe6vkYNEgDfpUvJz8vDW/MriVxWsf51tGvXrljjdizLwmazkZ+fX+JgIuIcy1euZDzQo3t3loWFmY4jTtQoJgY74GtZbPvuO1r07286kojLKlbh+eCDD0o7h4iUkhUrVgBowlAP5F25MnuqVKHpmTMc+ewzFR6RKyhW4Rk+fHhp5xCRUnImLo4AVHg8VWqrVrB8Od4FS4eIyKVp0LKIBzu8bRvzkpI4A3TWDMseKejmmwGIOnwYB9eCFilXVHhEPNi+jz/GCzju70+lyEjTcaQU1B82DDtQPz+ffbpaS+SyVHhEPNi5uDgAkho0MJxESot/WBjxFSsCcPC//zWcRsR1qfCIeLCw3bsB8L3hBsNJpDTt79SJqcCyQ4dMRxFxWSo8Ih7q1KFDNM/KAiBKFx54NK/HH+dh4D87dpiOIuKyVHhEPNSujz7CDzjm40NVTQbq0Tp37oy3tzcHDx4kMTHRdBwRl6TCI+KhMgoWDD1Uty5owVCPVqlSJTq2aUNXYMvnn5uOI+KSVHhEPNT7aWmMBzIHDTIdRcrAKzk5/Az4/+c/pqOIuCQVHhEPlJ6ezrydO5kCNHjoIdNxpAz4FQxMvzBQXUSKUuER8UCrVq3CbrcTFRVF7dq1TceRMhA1bBgAzc+d48SBA2bDiLggFR4RD5T04YcMA26JjjYdRcpI1Wuv5ZiPD77A7o8+Mh1HxOWo8Ih4oIaLF/MRcKeX/omXGzbb+QHqQOZ335nNIuKC9Gko4mHOnT1Ls5QUAGoOHmw4jZSpggViQzQfj8hFVHhEPMz2OXOoCmTabNQZMMB0HClDEXfdBUCL9HTSTp0ynEbEtajwiHiYU19+CcC+6tWx+foaTiNlqWbPnvwjJISewKq1a03HEXEpKjwiHiZg/XoAzrZvbziJlDkvL/b37886YMWqVabTiLgUFR4RD5KXm0vj48cBCB040HAaMaF79+4ALF++3HASEdeiwiPiQXYsWkQNyyIbqHfHHabjiAHXderE/wF3rVpFVkaG6TgiLkOFR8SDLNy2jRrAPzt3xrtiRdNxxID6jRrxls3GA3Y7v374oek4Ii5DhUfEg8TFxZEM1Ci4WkfKH5uvL/siIgBImTPHcBoR16HCI+Ihzp49y88//wxA7969DacRk+wF62pV37TJcBIR16HCI+Ihfpkxg0U5OTxdpQqNGjUyHUcMqnf//QC0yszkZEKC4TQirkGFR8RDnJk9m+uBW4KDsdlspuOIQdU6duSInx9+wPbp003HEXEJKjwiHqLGli0A2Hv1MhtEzLPZONSkCQA5335rOIyIa1DhEfEAJ/bvp1VmJgD1Ro82nEZcQYX+/QHIj4/HsizDaUTMU+ER8QA7pk/HFzjk50c1zbAsQKNx44jy86PvuXPs3r3bdBwR41R4RDxAzsKFABxp2tRwEnEVFUJDqdetG3B+ugKR8k6FR8TNWZZF1N69AFS45RbDacSVXJie4EcVHhF8TAcQkZLZ/euv7MnLozrQSON35Df6tm7NtUCjb74hNycHXz8/05FEjNERHhE3t3jZMgYAQ3v1okJ4uOk44kJaXH893YAoy2LbrFmm44gYpcIj4uYujM/oFRNjOIm4Gq8KFdhTsyYAJz75xHAaEbNUeETcWG52NvuXLAG0nIRcWnaPHgAEr19vOImIWSo8Im5s6yefsOPsWX718aF1q1am44gLqjNyJACtzpwh9fhxw2lEzFHhEXFjJz/9FIDcGjXw8vY2nEZcUXjv3hz39iYQ2PbOO6bjiBijwiPixqps2ABATsFpC5GL2GwcqF8fgMwFCwyHETFHhUfETZ1JSqJVaioAkaNGGU4jrsx2yy0sBhYfPWo6iogxKjwibmrb229TATjm40OtG24wHUdcWOO//Y2+3t68cuwYBw8eNB1HxAgVHhE3lfX55wAcbNQIbDbDacSVBQcH07lzZwC++eYbw2lEzFDhEXFD+Xl5NC5YEDLwzjsNpxF3MGDAAGoCh2fONB1FxAgVHhE3tHrVKh6y2/nIz48mDz9sOo64gdubNycJmLRpE6nHjpmOI1LmVHhE3NCCr7/mayBu8GB8g4NNxxE3UPemm0jy8aES8Murr5qOI1LmVHhE3IxlWSwouLx4wIABhtOI27DZSCiYnDJv7lzDYUTKngqPiJvZ99NPDN+7l04+Ptx0002m44gbqTJsGAAtEhLIycoynEakbKnwiLiZhNdeYxLwXuXKVK5c2XQccSNN7r+fNJuNGpbFFs26LOWMCo+Im6myfDkAaZp7RxzkFRDAznr1AEj9+GPDaUTKlgqPiBs5vns31xbMrlx//HjDacQd+QwaBEDk1q1YlmU4jUjZUeERcSPb//1vfIH4gADCunY1HUfcULMJExjl50fnvDw2b95sOo5ImVHhEXEjPgsXApDUsaPhJOKuKoSFkdKvHylQeLWfSHngEoVn2rRpREVFERAQQHR0NCtWrLjsvl9++SW9e/emevXqBAUF0blzZxYtWlSGaUXMyEhO5tqkJABq3n+/4TTizi5MZ6DCI+WJ8cIze/Zsxo0bx6RJk9i8eTPdu3cnNjaWxMTES+6/fPlyevfuzcKFC9m4cSM9e/akf//+OjQrHm/Nf/5DNnDc25t6Q4aYjiNurF/fvjxmszH1l184tH696TgiZcJmGR611rFjR9q2bcv06dMLtzVt2pRbb72VyZMnF+s5mjdvztChQ3n66acveX92djbZ2dmF36elpREREUFqaipBQUEl+wFEysjw4cP55OOPee6ee3hS6yFJCe0MCqJpejo/3nEHvWbNMh1HpFjS0tIIDg6+qt/fRo/w5OTksHHjRmJiYopsj4mJYdWqVcV6DrvdTnp6OiEhIZfdZ/LkyQQHBxfeIiIiSpRbpKzl5eXxzTffkA90HT7cdBzxAMndugFQMS7OcBKRsmG08Jw6dYr8/HzCwsKKbA8LC+NYMRe3e+WVV8jMzGTIFQ7xT5w4kdTU1MLboUOHSpRbpKytXrKElJQUQkJC6Kqrs8QJIgsWnW2TnMxpfSZKOWB8DA+AzWYr8r1lWRdtu5RZs2bx97//ndmzZ1OjRo3L7ufv709QUFCRm4g7OffkkyQC/2rcGB8fH9NxxANE3HQTh3x9CQB+/de/TMcRKXVGC09oaCje3t4XHc05ceLERUd9fm/27NmMHDmSOXPmcOONN5ZmTBGj8nJyaLJ5MxHAtd27m44jnsJmI7FgegPfOXMMhxEpfUYLj5+fH9HR0cT97hxyXFwcXbp0uezjZs2axYgRI/j000/p169faccUMWrjlClE2O2k2Wy0mjTJdBzxIHWefBKAdidPkrRtm+E0IqXL+CmtCRMm8P777zNz5kx27tzJ+PHjSUxMZPTo0cD58TfDClb4hfNlZ9iwYbzyyit06tSJY8eOcezYMVILptsX8TRn330XgO1Nm+Kr07HiRBGxsWyrVImvgIW6Uks8nPHCM3ToUKZMmcJzzz1HmzZtWL58OQsXLiQyMhKApKSkInPyvPPOO+Tl5fHggw9Sq1atwtvYsWNN/QgipSb95Ena7t8PQJWCQaYizrTixRcZDEwtmMVbxFMZn4fHhJJcxy9SlpY99BDXvfUWR3x8CD93Dpu3t+lI4mGSk5OpVasWubm5bN26lRYtWpiOJHJZbjsPj4hcmd/s2QAkdO6ssiOlolq1avTt25eGwOoXXjAdR6TUqPCIuKijR48yPjmZqUDkU0+ZjiMe7NGmTdkD9P78c+z5+abjiJQKFR4RFzVr1izWWhafde1KRO/epuOIB2v36KNkAHXz8tjy9tum44iUChUeERf13//+F4A//elPhpOIpwuoVo2tDRoAkDp1quE0IqVDhUfEBe359lv+smUL13l7M3jwYNNxpByoWDAVSOvdu8nSNB/igVR4RFzQoRde4D7gldBQqlWrZjqOlAMtxozhuLc3IZbFpuefNx1HxOlUeERcjD0/nwZr1wKQd+edhtNIeeHl68ue6GgAbAWnU0U8iQqPiIv5Zdo0IvPzSQda6+osKUPhjz8OQP1jxzh15IjhNCLOpcIj4mLSCgaNbm3YkICQEMNppDypP3AgY+vXJxKY9eWXpuOIOJUKj4gLSYmPp92ePQBU1lISUtZsNuqPGUM2MG3aNMrhRPziwVR4RFzIlocfpiKwNyCAFg8+aDqOlEPDhw+nUqVK7N61i590lEc8iAqPiIvIy8tj4erVJAIn77wTm5f+eUrZCw4O5oXevdkNBKh0iwfRJ6qIi5g/fz6vnD5Nx9BQ2r7+uuk4Uo71v+8+GgIdjx/nwNKlpuOIOIUKj4iLeOONNwAYNXo0AZUrG04j5Vnd2Fg2hobiBSQ88ojpOCJOocIj4gJ2zJ1L+IoVBHh788ADD5iOIwJjxgBw7ebNpCclGQ4jUnIqPCIu4NTEiXwGfFu3LuHh4abjiHDtxIkc8PWlCrBp7FjTcURKTIVHxLCTO3bQYe9eAGo89pjhNCLnefn4kDhgAAAR8+djz8sznEikZFR4RAzbNmYMAcDOwECa33ef6Tgiha59/XVSgXq5uax/9VXTcURKRIVHxKDcs2dpUnAVzOlhw3QpuriUyuHhfBsTQw/g70uWmI4jUiL6dBUxaP3jj1PLbueElxftXnrJdByRi3ScNo2fbTa+X7SI3bt3m44jctVUeEQMsex2gj/4AIAdPXrgp0vRxQXVr1+fm2++GYBp//634TQiV0+FR8SQRXPmcCwzk7NA8zffNB1H5LIeGTuWycCzM2ZweMUK03FErooKj4gBdrudxydP5kZg6v33U71FC9ORRC7rul696B0SQhXgwD33mI4jclVUeEQMmD17Nr/++itBQUGMeuEF03FE/lDAK68A0GX/fvZ/9ZXhNCKOU+ERKWO5mZkcf/BBqgGPPfYYISEhpiOJ/KHmI0awOjwcL+DU6NGm44g4TIVHpIyt+fOfGXf6NGu9vRlXMH2/iDsInT6dfKBjUhI7Cgbci7gLFR6RMpSVnEzDzz4DIPHWW6kUFGQ4kUjxNbzlFlbVrw9A9qOPGk4j4hgVHpEytH7YMGra7SR6e9NFfyGLG6r74YdkA01TUljzySem44gUmwqPSBlJS0yk5XffAXBgxAj8Ne+OuKGIbt34JCaGBsCEt97CsizTkUSKRYVHpIxs+dOfqGpZ7PHzo8tbb5mOI3LVYj/8kJQKFVi9ejXffPON6TgixaLCI1IGktasIbpgwraTY8bg4+9vOJHI1atVqxZjx44FYN5DD5F95ozZQCLFYLPK4fHItLQ0goODSU1NJUiDRqWUWZbFkNhYrl+0iM6VK9Pm9Gm8vL1NxxIpkdOnT/PJNdfwUFYWK7p0ofvKlaYjSTlQkt/fOsIjUso+/fRTvli0iAl+fgQsX66yIx6hatWqtHnwQQA6r1rF3oKrD0VclQqPSCk6mZBQONfOU089RbM2bcwGEnGiri+9xIprrsEHsO69l7yzZ01HErksFR6R0mJZHOzWjdkpKcQ2acLjjz9uOpGIU9lsNhp9/z3JNhuNsrJYfeutpiOJXJYKj0gp2fDYY7Q7epRuwMvPPouvr6/pSCJOF9aiBVvvuw+AjnFxHNBVW+KiNGhZg5alFKTu20de48ZUs9v5oVs3biy4QkvEE1l2O2tq1qTzyZPsqFSJJqdP4+XjYzqWeCANWhZxMTv79KGa3c5uPz+6ffut6Tgipcrm5UXtr75ij83GpIwMpr/zjulIIhdR4RFxsnV/+Qud4uPJB85Nm0aAjiJKORDRqROLp0xhPvDXv/6VX375xXQkkSJUeEScaNeMGbSZPh2AJV270nrkSMOJRMrOXx56iN69e3P27FnGxMZyassW05FECqnwiDhJUlIS906axF7g57Awbli61HQkkTLl5eXF7NmzuaN2beYlJXGqe3eyT582HUsEUOERcYpz584xcOBAVh8/zohGjWi5aRPeuipLyqGqVavy/AcfYLfZaJKRwS/R0Vh2u+lYIio8IiVl5efzwsCBrF27lqpVqzLr228JDg83HUvEmPo33sj+f/2LXKBDQgKrb77ZdCQRFR6RklodE8Mz33/POJuNzz//nAYNGpiOJGJcx8ce46chQwDo8t13bH7qKcOJpLxT4REpgXUjRtBlyRK8gX7/93/06tXLdCQRl3HjZ5/xQ7NmADR6/nl2TJ1qOJGUZyo8IldpzYABdPjoIwAWX3stvT7+2HAiEddis9novm4da0JCqAjsGjeOJUuWmI4l5ZQKj4iDLLud1dddR6evvgLg+/btuXH9emw2m+FkIq7Hv2JFWu7Zw0f16nFXfj59+/ZlwYIFpmNJOaTCI+IAy25nTXQ0nZcvB2DRjTfSZ+1avLy9DScTcV0Vq1Xjjh076DtwINnZ2Qy67TYWT5pkOpaUMyo8IsWUn5/P6AceYPGWLdiBxbffTp+4OB3ZESkGf39/5syZw/Bhw3jBbifmhRe0urqUKRUekWI4euQIsbGxvPvuuzwLLPjb34j5/HPTsUTcio+PDzNnzqRV+/YAdF6wgLUNG3I2KclwMikPVHhE/sCGCRM4FhnJqrg4KlSowOw5cxj4j3+YjiXilry8vemzdi2L+vQhD+i4bx8pkZHs+fBD09HEw6nwiFzG2WPHWNOoEe1ee422+fm8UKsWmzZtYvDgwaajibg1m81Gn++/Z/Prr3PQ25vaubnUu+ceVvXpgz0nx3Q88VAqPCKXsOOtt0iuU4dOe/eSByzq0oX79+6lSZMmpqOJeIz2Y8ZQae9efqpdGx+g9eLFjOjZk4SEBNPRxAOp8Ij8RvyXX7KpZk2aPfQQEbm5JHp7s3nKFPqsXIl/xYqm44l4nGpRUVyXmMiSe+9lnK8v/1m1isaNGzPm4Yc5sW2b6XjiQVR4RIBDhw4xatQolg0aRNvjx8kFfmzShIp79tB+7FjT8UQ8ms1m44YZM3jk11+JiYkhNzeX3VOnUrllS37u2pW0gwdNRxQPYLMsyzIdoqylpaURHBxMamoqQUFBpuOIKZbFnk8/5fOvvuIfCxaQnZ1NbeA/tWtzzXvv0fCmm0wnFCmXlixZwuk772TQiRMAnLHZ2Nq1K/UmT+aabt0MpxOTSvL7W0d4pNxJS0zk5zvvZE/FijT6059oMmcO2dnZ9OjRgzmrVnH9oUMqOyIG3XDDDdyWlMTKiRPZ7edHFcui+88/c0337mwODWXtI4+Qq8HN4iAd4dERnnIhZfdudr/xBtbChbQ5cIDAgu3ngDWRkeS99x69brxRkwiKuJi87GxWP/EE/h9/TLuUFLyAtcAtNWowePBgYmNj6dmpE4HVqpmOKmWgJL+/VXhUeDxSVkoKm3ftIi4uju+++44X167l+t/cv8fPj8OxsbT817+o3rixqZgi4oCEpUtJ+NvfmLV9O++npgIQBiQAO0NCSO/WjVp/+hP1+vfHJyDAaFYpHW5feKZNm8a///1vkpKSaN68OVOmTKF79+6X3X/ZsmVMmDCB7du3Ex4ezl//+ldGjx5d7NdT4fEspxMSOPzjj6T88ANemzZR49Ah6p87Rx3gwvytfwXuCQggqXVrQu69l1ajRmHz0hldEXeUm5vL999/z7fffov3F1/wVnJykfvPAvsrVSI5Kor0gQOJGDiQBg0aUKlSJTOBxWncuvDMnj2bu+++m2nTptG1a1feeecd3n//fXbs2EGdOnUu2j8hIYEWLVpw3333cf/997Ny5Ur+8pe/MGvWLAYNGlSs11ThcR85Z89ycvt2UnbsIHPvXnZVqcL+1FT2799Py1Wr+HNiItUu85/w3VWqkNWrF7GxsdzUpw/X1K5dxulFpLRZdjsJixaR+M47VPr5ZxomJxP8m/uHAnMKvh5StSpP5OeTHhZGXp06eEdEEBAVRVDjxoQ0b05o48Z4+/oa+CmkuNy68HTs2JG2bdsyffr0wm1Nmzbl1ltvZfLkyRft//jjj/PVV1+xc+fOwm2jR4/ml19+YfXq1cV6zQtv2IEDB86/Yenp2PLzudxbYQ/+3z8fW3o65OYCXHJ/e9WqRfctGFhnWRb8bn+rWjWs3+577txv7iy6r71aNayC8SW29HRsWVm/2fXiffH2xrKs8/tmZhZ93d/sb69WDXx9C/f1ysi47L751aqBn9/5b1JTsZKTyc/OJj87G3tODvbcXOw5OeRnZ5MeEUG2vz+5ubn4HDhAwM6d5GdkYM/MxH72LGRmQlYWnDvH0gYNOOjvT3p6Oq327mVIfDyVcnMJyssjmKIj6/sAiwu+vhv4uODr415eHAoJIbNJEwK6daPObbdRMzpaR3FEyhl7Xh6JS5Zw9KuvyF29mqk+PvwUH8+pU6eYALxyhcfeCiyvWpUqVapws5cXw06fJjswkPyAAPIDArD8/aFCBQgM5EB0NNkREQQGBhJy9iw1jh/Hu0IFbD4+ePn6FrnlRUZC1ap4e3vje+4c/qmphfd5+/nh7eeHl68vNi8vrIoVsRWcjrPl5mI7e7ZwbGHh59mF7wMDwc/v/P15eZCVddG+hf/r7w++vufvz8/HVvB7zGazgc1W+L8AeHuDj8/5ry3r/HNfjpfX+f2dva/NdskMaWlphNaqdVWFx8ehvZ0sJyeHjRs38sQTTxTZHhMTw6pVqy75mNWrVxMTE1NkW58+fZgxYwa5ubn4XqKdZ2dnk52dXfh9asG537p16wLwDXC5E2iZQPhvvv8ciLnMvkCRvyw+BAZeYd+awIXaMg34vyvsGwWkFHz9MnDfFfZtARwq+Po54EqzyHQAdhd8/QQw8Qr7Xg9sLvh6bMFzX85NwIX6eT/w0hX2nbxpEz8UfF0BiPjNfRlAPpBss3EmIIA2LVpQu2VLoqKiaFK9OpsDA6nVpQuB1avT6HfPm/678iYi5UNIp06EdOoEwIyCbWfOnOHIypX88NNP5Ozahc/hw/ifOUNQZiZVs7MJ4fzn5unTpzl9+jQ5cP4zJSXlkq8xefHiws+t/+P8Z/jl/An4uuDr24APrrDvffzviNRNwOwr7DuW879nAK4DvgIudwRj4m8ytgN+vMLz/oPzv2cAmvG/z/JLeYX//S6IArZcYd+3gccLvq4B7L3Cvh8BYwq+rgQcKfj6wu/MqzpWYxl05MgRC7BWrlxZZPs///lPq1GjRpd8TMOGDa1//vOfRbatXLnSAqyjR49e8jHPPPOMxfn/DnTTTTfddNNNNze/7d+/3+HOYfQIzwW/vxTYsqwrXh58qf0vtf2CiRMnMmHChMLvz5w5Q2RkJImJiQT/5nSVOC4tLY2IiAgOHTqk8VAlpPfSOfQ+Oo/eS+fRe+kcqamp1KlTh5CQEIcfa7TwhIaG4u3tzbFjx4psP3HiBGFhYZd8TM2aNS+5v4+PD9UuMw+Dv78//v7+F20PDg7Wf3hOEhQUpPfSSfReOofeR+fRe+k8ei+dw+sqxmcaHdHp5+dHdHQ0cXFxRbbHxcXRpUuXSz6mc+fOF+2/ePFi2rVrd8nxOyIiIiLGL2GZMGEC77//PjNnzmTnzp2MHz+exMTEwnl1Jk6cyLBhwwr3Hz16NAcPHmTChAns3LmTmTNnMmPGDB599FFTP4KIiIi4OONjeIYOHUpycjLPPfccSUlJtGjRgoULFxIZGQlAUlISiYmJhftHRUWxcOFCxo8fz1tvvUV4eDhvvPFGsefggfOnuJ555plLnuYSx+i9dB69l86h99F59F46j95L5yjJ+2h8Hh4RERGR0mb8lJaIiIhIaVPhEREREY+nwiMiIiIeT4VHREREPJ4KD3DLLbdQp04dAgICqFWrFnfffTdHjx41HcutHDhwgJEjRxIVFUWFChWoX78+zzzzDDkFi6eKY/75z3/SpUsXAgMDqVKliuk4bmXatGlERUUREBBAdHQ0K1asMB3J7Sxfvpz+/fsTHh6OzWZj/vz5piO5pcmTJ9O+fXsqV65MjRo1uPXWW9m9e/cfP1AuMn36dFq1alU4cWPnzp357rvvHHoOFR6gZ8+ezJkzh927dzN37lz279/P7bffbjqWW9m1axd2u5133nmH7du389prr/H222/z5JNPmo7mlnJychg8eDAPPPCA6ShuZfbs2YwbN45JkyaxefNmunfvTmxsbJGpLeSPZWZm0rp1a6ZOnWo6iltbtmwZDz74IGvWrCEuLo68vDxiYmLIzMw0Hc3t1K5dmxdffJENGzawYcMGbrjhBgYMGMD27duL/Ry6LP0SvvrqK2699Vays7M1e3MJ/Pvf/2b69OnEx8ebjuK2PvzwQ8aNG8eZM2dMR3ELHTt2pG3btkyfPr1wW9OmTbn11luZPHmywWTuy2azMW/ePG699VbTUdzeyZMnqVGjBsuWLaNHjx6m47i9kJAQ/v3vfzNy5Mhi7a8jPL+TkpLCJ598QpcuXVR2Sig1NfWqFngTuRo5OTls3LiRmJiYIttjYmJYtWqVoVQi/5Oamgqgz8USys/P57PPPiMzM5POnTsX+3EqPAUef/xxKlasSLVq1UhMTGTBggWmI7m1/fv38+abbxYuESJS2k6dOkV+fv5FCw+HhYVdtOCwSFmzLIsJEybQrVs3WrRoYTqOW9q6dSuVKlXC39+f0aNHM2/ePJo1a1bsx3ts4fn73/+OzWa74m3Dhg2F+z/22GNs3ryZxYsX4+3tzbBhw9DZPsffR4CjR49y0003MXjwYEaNGmUoueu5mvdSHGez2Yp8b1nWRdtEytpDDz3Er7/+yqxZs0xHcVuNGzdmy5YtrFmzhgceeIDhw4ezY8eOYj/e+FpapeWhhx7ijjvuuOI+devWLfw6NDSU0NBQGjVqRNOmTYmIiGDNmjUOHS7zRI6+j0ePHqVnz5507tyZd999t5TTuRdH30txTGhoKN7e3hcdzTlx4sRFR31EytLDDz/MV199xfLly6ldu7bpOG7Lz8+PBg0aANCuXTvWr1/P66+/zjvvvFOsx3ts4blQYK7GhSM72dnZzozklhx5H48cOULPnj2Jjo7mgw8+wMvLYw8gXpWS/Dcpf8zPz4/o6Gji4uIYOHBg4fa4uDgGDBhgMJmUV5Zl8fDDDzNv3jx++uknoqKiTEfyKJZlOfR72mMLT3GtW7eOdevW0a1bN6pWrUp8fDxPP/009evXL/dHdxxx9OhRrr/+eurUqcPLL7/MyZMnC++rWbOmwWTuKTExkZSUFBITE8nPz2fLli0ANGjQgEqVKpkN58ImTJjA3XffTbt27QqPMiYmJmosmYMyMjLYt29f4fcJCQls2bKFkJAQ6tSpYzCZe3nwwQf59NNPWbBgAZUrVy48+hgcHEyFChUMp3MvTz75JLGxsURERJCens5nn33GTz/9xPfff1/8J7HKuV9//dXq2bOnFRISYvn7+1t169a1Ro8ebR0+fNh0NLfywQcfWMAlb+K44cOHX/K9XLp0qeloLu+tt96yIiMjLT8/P6tt27bWsmXLTEdyO0uXLr3kf3/Dhw83Hc2tXO4z8YMPPjAdze3ce++9hf+uq1evbvXq1ctavHixQ8+heXhERETE42mQhYiIiHg8FR4RERHxeCo8IiIi4vFUeERERMTjqfCIiIiIx1PhEREREY+nwiMiIiIeT4VHREREPJ4Kj4iIiHg8FR4RERHxeCo8IuJyFi5ciM1mK7z5+PhQt25dJkyYQEZGxkX75+fnU6NGDV577TUDaUXEHZT71dJFxPVs2rQJgLlz5xIeHk5mZiaffPIJr732GmfOnGHmzJlF9l++fDknT57ktttuMxFXRNyAFg8VEZdz22238d1335GRkYG3tzcAdrud+vXrk5GRwcmTJ4vs/+CDD7Ju3TrWr19vIq6IuAGd0hIRl7Nx40aaNm1aWHYAvLy8qF69Oj4+RQ9MW5bFvHnzGDRoUOG2Rx99lBo1ahTZ75FHHsFms/Hyyy8Xbjt27Bj+/v68/fbbpfSTiIirUOEREZeSnJxMYmIiLVu2LLL9+PHjbN++ncGDBxfZvmrVKpKSkooUnpCQENLS0gq/P336NO+++y5BQUGkpKQUbp86dSpVqlRhxIgRpfPDiIjLUOEREZdyYfxOs2bNyMvLIysri7Vr1zJgwAD69OnDCy+8UGT/L774gpYtW9KwYcPCbVWrViU7O5ucnBwA3nzzTSIjI+nTp09h4cnKyuLtt9/m4YcfJiAggJMnT9KvXz8qVqxIo0aNiIuLK6OfWETKggqPiLiUjRs3AvDEE0/g6+tLYGAgnTp1IigoiNmzZ1OpUqUi+3/55ZdFju7A+cIDkJaWxtmzZ3nzzTf561//SpUqVTh9+jQAH374IefOneMvf/kLcH4cUM2aNTl58iQvv/wyQ4YMITk5ubR/XBEpIyo8IuJSNm3ahLe3N6tWrWL9+vV8//333HDDDcTFxfHee+8V2XfdunUkJiZeVHhCQkKA84XnvffeIzAwkLvuuosqVaqQkpKCZVlMmTKF++67j5CQEDIyMpg/fz5///vfCQwM5JZbbqF169YsWLCgzH5uESlduixdRFzKpk2baNasGZ07dy7c1rFjR2rXrs37779feEQGzl+23qhRI1q0aFHkOS4c4UlJSeHVV1/lkUcewcfHh+DgYFJSUvj666+Jj49n/PjxAOzdu5dKlSoRERFR+BwtW7Zk+/btpfmjikgZ0hEeEXEZqampxMfH0759+yLbq1Spwm233cbmzZuJj48v3D537tyLju7A/wrP9OnTyczMZNSoUYXPc/r0aV599VXuuOMO6tSpA0BGRgZBQUFFniMoKOiSkxyKiHtS4RERl7Fp0yYsy6JDhw4X3Xf77bcDMG/ePAC2bNnC/v37L1l4LpzS+uijj3j44YcJDAwEIDg4mMTERJYtW8Zjjz1WuH+lSpWKXNUF50+H/X68kIi4LxUeEXEZF67Q+v0RHoA+ffpQuXJl5s+fD5w/uhMZGUl0dPRF+1apUgWbzUZAQAAPP/xwke35+fncdNNNtGrVqnB7w4YNycjI4PDhw4Xbtm3bRvPmzZ31o4mIYZppWUTcUrNmzYiNjeWVV15xyvMNHjyY4OBg3nzzTX788Ufuvvtu9u7dS2hoqFOeX0TMUuEREQFOnjzJ8OHD+emnn7jmmmt46623iImJMR1LRJxEhUdEREQ8nsbwiIiIiMdT4RERERGPp8IjIiIiHk+FR0RERDyeCo+IiIh4PBUeERER8XgqPCIiIuLxVHhERETE46nwiIiIiMdT4RERERGPp8IjIiIiHu//AfuEXTD57xFqAAAAAElFTkSuQmCC\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "val = (np.abs(A0)**2).sum(0)\n", "val = np.r_[val[::-1], val]\n", @@ -204,24 +184,9 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "c17f5723f6a345ba84652baa9f0a6e48", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - " 0%| | 00:00" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "fig, ax = plt.subplots(1,1, figsize=(8,4), tight_layout=True, dpi=100)\n", "\n", diff --git a/examples/example_figure.png b/examples/example_figure.png deleted file mode 100644 index c4868e96685eb160763a7ddd3a8944f820164532..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55126 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
RI+Si@}~D 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" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "plt.figure(figsize=(8,4), tight_layout=True, dpi=100)\n", "\n", From c52645afdcd9e80526b69007e8fc369dbd1ec45b Mon Sep 17 00:00:00 2001 From: Igor Andriyash Date: Fri, 15 Sep 2023 16:24:26 +0200 Subject: [PATCH 04/12] fixed latex in README --- README.md | 4 ++-- docs/main_equations.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 520af98..1c6fb7a 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ field. sampling of radial axis [[K. Oubrerie, I.A. Andriyash et al, J. Opt. 24, 045503 (2022)](https://doi.org/10.1088/2040-8986/ac57d2)] - `PropagatorResamplingFresnel`: cylindical axisymmetric propagator based on the Fresnel approximation as given by `Eq. (4-17)` of [JW Goodman _Introduction to Fourier Optics_] and is suited for translations between far and near fields. - `PropagatorFFT2`: fully 3D FFT-based propagator -- `PropagatorFFT2Fresnel`: ully 3D FFT-based propagator based on the Fresnel approximation +- `PropagatorFFT2Fresnel`: fully 3D FFT-based propagator based on the Fresnel approximation ### Propagation with plasma models: - `Simulation` class includes a few algorithms (`'Euler'` `'Ralston'`, `'MP'`, `'RK4'`), method to provide adjustive steps, diagnostics @@ -35,7 +35,7 @@ Computations can be done using a number of backends: Documentation is organized in a few sections: - - [Equations of field propagation](./docs/main.md) + - [Equations of field propagation](https://github.com/hightower8083/axiprop/blob/new-docs/docs/main_equations.md) ## Installation diff --git a/docs/main_equations.md b/docs/main_equations.md index d32edbc..53b3d1d 100644 --- a/docs/main_equations.md +++ b/docs/main_equations.md @@ -83,4 +83,4 @@ dx' dy' \left[E(x', y', k, z=0) \exp\left(\frac{i k}{2 z} \left(x'^2+y'^2\right) \left(xx'+yy'\right)\right) $$ -# [Return](./../README.md) +# [Return](https://github.com/hightower8083/axiprop/blob/new-docs/README.md) From 5a993da57ac9859871e296f0c1642597bc40999a Mon Sep 17 00:00:00 2001 From: Igor Andriyash Date: Fri, 15 Sep 2023 16:26:31 +0200 Subject: [PATCH 05/12] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1c6fb7a..cfa77a0 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ sampling of radial axis [[K. Oubrerie, I.A. Andriyash et al, J. Opt. 24, 045503 ### Propagation with plasma models: - `Simulation` class includes a few algorithms (`'Euler'` `'Ralston'`, `'MP'`, `'RK4'`), method to provide adjustive steps, diagnostics -- Plasma models: `PlasmaSimple` (linear current, $n_{pe}(z)$ ), `PlasmaSimpleNonuniform` (linear current, $n_{pe}(z, r)$), `PlasmaRelativistic` (non-linear current, $n_{pe}(z, r)$), `PlasmaIonization` (non-linear current and ionization, $n_{g}(z, r)$) +- Plasma models: `PlasmaSimple` (linear current, $`n_{pe}(z)`$ ), `PlasmaSimpleNonuniform` (linear current, $`n_{pe}(z, r)`$), `PlasmaRelativistic` (non-linear current, $`n_{pe}(z, r)`$), `PlasmaIonization` (non-linear current and ionization, $`n_{g}(z, r)`$) ### Convenience tools include: - Container classes to create and handle time-frequency transformations for the **carrier-frequency-resolved** and **enveloped** fields. From cf978a77c5ee8e8272ec82ec53ed8384aa2771e3 Mon Sep 17 00:00:00 2001 From: Igor Andriyash Date: Fri, 15 Sep 2023 16:37:55 +0200 Subject: [PATCH 06/12] added files for representation and propagation --- README.md | 5 ++-- docs/field_representation.md | 25 ++++++++++++++++++++ docs/main_equations.md | 45 ++---------------------------------- docs/propagators_vacuum.md | 19 +++++++++++++++ 4 files changed, 49 insertions(+), 45 deletions(-) create mode 100644 docs/field_representation.md create mode 100644 docs/propagators_vacuum.md diff --git a/README.md b/README.md index cfa77a0..a5411b7 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,9 @@ Computations can be done using a number of backends: Documentation is organized in a few sections: - - [Equations of field propagation](https://github.com/hightower8083/axiprop/blob/new-docs/docs/main_equations.md) - + - [Main equations for optical field](https://github.com/hightower8083/axiprop/blob/new-docs/docs/main_equations.md) + - [Representation of optical field](https://github.com/hightower8083/axiprop/blob/new-docs/docs/field_representation.md) + - [Propagation of optical field](https://github.com/hightower8083/axiprop/blob/new-docs/docs/propagators_vacuum.md) ## Installation ### From PyPI diff --git a/docs/field_representation.md b/docs/field_representation.md new file mode 100644 index 0000000..fc0c511 --- /dev/null +++ b/docs/field_representation.md @@ -0,0 +1,25 @@ +### Field representation + +#### Temporal representation + +We assumed the field propagation along z-axis is and the temporal representation. The later means that the full field $E(t,x,y,z)$ is considered at a fixed $z=z_0$, and is measured on a finite $(x,y)$-plane over a time interval $t\in[t_{min},t_{max}]$, so the input as $E_0 = E(t,x,y,z=z_0)$. + +The field equation can be written as following: + +$$ \partial_z^2 E = \frac{1}{c^2} \partial_t^2 E - \nabla_{\perp}^2 E + \mu_0 \partial_t J $$ + +#### Geometries + +Two main geometries are usually considered +- cartesian $(x, y, t)$, where transverse Laplace operator is $\nabla_\perp^2 = \partial_x^2 + \partial_y^2$ +- cylindrical $(r, \theta, t)$, where $\nabla_{\perp}^2 = r^{-1} \partial_r (r \partial_r) + r^{-2} \partial_\theta^2$. + +#### Envelope + +If one considers the field around its central frequency $\omega_0$ as: + +$$ E(t) = \mathrm{Re}[\hat{E}(t) \exp(- i \omega_0 t) ], $$ + +in many practical cases the complex function $\hat{E}(t)$ can be assumed to be much slower than the actual $E(t)$. This presentation called envelope is often preferrable for analysis, and is also used in `Lasy` + +## [Return to README](https://github.com/hightower8083/axiprop/blob/new-docs/README.md#documentation) \ No newline at end of file diff --git a/docs/main_equations.md b/docs/main_equations.md index 53b3d1d..a35c579 100644 --- a/docs/main_equations.md +++ b/docs/main_equations.md @@ -40,47 +40,6 @@ and its spatio-temporal Fourier transform leads to the basic dispersion relation $$ \omega^2 = k^2 c^2 + \omega_{pe}^2 $$ -### Field representation -#### Temporal representation - -We assumed the field propagation along z-axis is and the temporal representation. The later means that the full field $E(t,x,y,z)$ is considered at a fixed $z=z_0$, and is measured on a finite $(x,y)$-plane over a time interval $t\in[t_{min},t_{max}]$, so the input as $E_0 = E(t,x,y,z=z_0)$. - -The field equation can be written as following: - -$$ \partial_z^2 E = \frac{1}{c^2} \partial_t^2 E - \nabla_{\perp}^2 E + \mu_0 \partial_t J $$ - -#### Geometries - -Two main geometries are usually considered -- cartesian $(x, y, t)$, where transverse Laplace operator is $\nabla_\perp^2 = \partial_x^2 + \partial_y^2$ -- cylindrical $(r, \theta, t)$, where $\nabla_{\perp}^2 = r^{-1} \partial_r (r \partial_r) + r^{-2} \partial_\theta^2$. - -#### Enelope - -If one considers the field around its central frequency $\omega_0$ as: - -$$ E(t) = \mathrm{Re}[\hat{E}(t) \exp(- i \omega_0 t) ], $$ - -in many practical cases the complex function $\hat{E}(t)$ can be assumed to be much slower than the actual $E(t)$. This presentation called envelope is often preferrable for analysis, and is also used in `Lasy` - -## Propagation - -Propagation calculations in `axiprop` are realized with spectral transformations in time and transverse spatial domains. - -### Non-paraxial propagator - -#### 3D - -#### RZ - -### Fresnel propagator - -For a mode $k=2\pi / \lambda$ - -$$ E(x, y, k, z) = \cfrac{ \exp\left(i k z \left(1 + \frac{x^2+y^2}{2 z^2}\right) \right) }{i \lambda z} \int \int_{-\infty}^{\infty} -dx' dy' \left[E(x', y', k, z=0) \exp\left(\frac{i k}{2 z} \left(x'^2+y'^2\right) \right) \right] \exp\left(-\frac{i k}{z} -\left(xx'+yy'\right)\right) $$ - - -# [Return](https://github.com/hightower8083/axiprop/blob/new-docs/README.md) +___________________________ +## [Return to README](https://github.com/hightower8083/axiprop/blob/new-docs/README.md#documentation) diff --git a/docs/propagators_vacuum.md b/docs/propagators_vacuum.md new file mode 100644 index 0000000..cd986eb --- /dev/null +++ b/docs/propagators_vacuum.md @@ -0,0 +1,19 @@ +## Propagation + +Propagation calculations in `axiprop` are realized with spectral transformations in time and transverse spatial domains. + +### Non-paraxial propagator + +#### 3D + +#### RZ + +### Fresnel propagator + +For a mode $k=2\pi / \lambda$ + +$$ E(x, y, k, z) = \cfrac{ \exp\left(i k z \left(1 + \frac{x^2+y^2}{2 z^2}\right) \right) }{i \lambda z} \int \int_{-\infty}^{\infty} +dx' dy' \left[E(x', y', k, z=0) \exp\left(\frac{i k}{2 z} \left(x'^2+y'^2\right) \right) \right] \exp\left(-\frac{i k}{z} +\left(xx'+yy'\right)\right) $$ + +## [Return to README](https://github.com/hightower8083/axiprop/blob/new-docs/README.md#documentation) \ No newline at end of file From 3ba83a0586e43d18186ea37ccb8da1196ba09064 Mon Sep 17 00:00:00 2001 From: Igor Andriyash Date: Mon, 18 Sep 2023 11:22:48 +0200 Subject: [PATCH 07/12] Update main_equations.md --- docs/main_equations.md | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/docs/main_equations.md b/docs/main_equations.md index a35c579..5022595 100644 --- a/docs/main_equations.md +++ b/docs/main_equations.md @@ -1,6 +1,34 @@ -## Basic model +For optical propagation we need to describe evolution of electromagnetic field from the state defined at some time and space region to the state that it has after some time and in a different space region. Assuming all charges of the system to be free, the distribution and evolution of electromagnetic field in space and time is described by the Maxwell equations written for electric field and the magnetic induction vectors: +```math +\begin{aligned} + &\nabla \times \mathbf{B} = \frac{1}{c^2} \partial_t \mathbf{E} + \mu_0 \mathbf{J}\\ + &\nabla \times \mathbf{E} = - \partial_t \mathbf{B}\,, \; \nabla E = \rho/\epsilon_0 +\end{aligned} +``` -For optical propagation we need to describe evolution of electromagnetic field from the state defined at some time and space region to the state that it has after some time and in a different space region. This computation follows from the Maxwell equations for electric and magnetic fields: +In most problems of the optical propagation of laser pulse, it is enough to describe evolution of its electric components and we can find the proper equation by combining the above ones: +```math +\begin{aligned} + & \nabla^2 \mathbf{E} = \frac{1}{c^2} \partial_t^2 \mathbf{E} + \mu_0 \partial_t\mathbf{J} + \nabla \rho/\epsilon_0 +\end{aligned} +``` + +The last term in the right hend side of this equation corresponds to the contribution of charge density perturbations (plasma waves), and may be neglected. Indeed, considering a single component of the laser field, e.g. `x`, and with the help of the continuity equation for the charge we may write the last two _source_ terms as: +```math +\begin{aligned} + & \mu_0 \partial_t J_x + \partial_x \rho/\epsilon_0 = \frac{1}{\epsilon_0 } \int_{-\infty}^{t} dt' (\frac{1}{c^2} \partial_t^2 J_x - \partial_x^2 J_x ) +\end{aligned} +``` +The terms under the integral in the Fourier space read, $`-\omega^2/c^2 J_x`$ and $`-k_x^2 J_x`$, and most optical problems for the directed pulse propagation $`\omega^2/c^2 \gg k_x^2`$ . + + +In optical problems the state of the field is usually described + +initial + +With proper initial and boundary conditions and knowledge of cahrges motion thi + + This computation follows from the Maxwell equations for electric and magnetic fields: $$ \nabla \times \mathbf{E} = - \partial_t \mathbf{B} $$ From 007b222af5d8a2c6abf0b45a484789511264d6d1 Mon Sep 17 00:00:00 2001 From: Igor Andriyash Date: Mon, 18 Sep 2023 18:33:03 +0200 Subject: [PATCH 08/12] Update main_equations.md --- docs/main_equations.md | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/docs/main_equations.md b/docs/main_equations.md index 5022595..9a3807f 100644 --- a/docs/main_equations.md +++ b/docs/main_equations.md @@ -1,25 +1,41 @@ -For optical propagation we need to describe evolution of electromagnetic field from the state defined at some time and space region to the state that it has after some time and in a different space region. Assuming all charges of the system to be free, the distribution and evolution of electromagnetic field in space and time is described by the Maxwell equations written for electric field and the magnetic induction vectors: +In the optical propagation simulation we describe evolution of electromagnetic field from a state defined at some time and space region to another state that it takes after some time and in a different space region. This problem can be described by the Maxwell equations: ```math \begin{aligned} - &\nabla \times \mathbf{B} = \frac{1}{c^2} \partial_t \mathbf{E} + \mu_0 \mathbf{J}\\ - &\nabla \times \mathbf{E} = - \partial_t \mathbf{B}\,, \; \nabla E = \rho/\epsilon_0 + &\nabla \times \mathbf{E} = - \partial_t \mathbf{B}\,,\\ + &\nabla \times \mathbf{H} = \partial_t \mathbf{D} + \mathbf{J}\,,\\ + & \nabla \mathbf{D} = \rho\,, \nabla \mathbf{B} =0\,,\\ + & \mathbf{D} = \epsilon \mathbf{E} \,,\; \mathbf{B} = \mu \mathbf{H} \,. \end{aligned} ``` -In most problems of the optical propagation of laser pulse, it is enough to describe evolution of its electric components and we can find the proper equation by combining the above ones: +Assuming all charges of the system to be free, i.e. $`\epsilon=\epsilon_0`$ and $`\mu=\mu_0`$, we can write a pair of separate equations for the fields: ```math \begin{aligned} - & \nabla^2 \mathbf{E} = \frac{1}{c^2} \partial_t^2 \mathbf{E} + \mu_0 \partial_t\mathbf{J} + \nabla \rho/\epsilon_0 + & \nabla^2 \mathbf{E} - \frac{1}{c^2} \partial_t^2 \mathbf{E} = \mu_0 \partial_t\mathbf{J} + \nabla \rho/\epsilon_0 \,, \\ + & \nabla^2 \mathbf{H} - \frac{1}{c^2} \partial_t^2 \mathbf{H} = - \nabla \times \mathbf{J}\,. \end{aligned} ``` -The last term in the right hend side of this equation corresponds to the contribution of charge density perturbations (plasma waves), and may be neglected. Indeed, considering a single component of the laser field, e.g. `x`, and with the help of the continuity equation for the charge we may write the last two _source_ terms as: +The terms in the last term in the right hand sides of these equations are the _sources_, and they generate the field of response of the media via the current and density modulations. For most cases it is practical to consider the electric field as it drives the current and is used for the calculations: ```math \begin{aligned} - & \mu_0 \partial_t J_x + \partial_x \rho/\epsilon_0 = \frac{1}{\epsilon_0 } \int_{-\infty}^{t} dt' (\frac{1}{c^2} \partial_t^2 J_x - \partial_x^2 J_x ) + & \nabla^2 \mathbf{E} - \frac{1}{c^2} \partial_t^2 \mathbf{E} = \mu_0 \partial_t\mathbf{J} \,. \end{aligned} ``` -The terms under the integral in the Fourier space read, $`-\omega^2/c^2 J_x`$ and $`-k_x^2 J_x`$, and most optical problems for the directed pulse propagation $`\omega^2/c^2 \gg k_x^2`$ . + +Note, that here we have dropped the last term $`\nabla \rho/\epsilon_0`$ as it is purely electrostatic ($`\nabla\times\nabla \rho \equiv 0`$), and it does not propagate with the electromagnetic field. + +Physically, the contribution of this term can be estimated by re-writing the full source term as: +```math +\begin{aligned} + & \mu_0 \partial_t\mathbf{J} + \nabla \rho/\epsilon_0 = \frac{1}{\epsilon_0 } \int_{-\infty}^{t} dt' (\frac{1}{c^2} \partial_t^2 \mathbf{J} - \nabla (\nabla \mathbf{J}) )\,, +\end{aligned} +``` +and comparing the terms under the intergral in the Fourier space, where we have them as $`\omega^2/c^2 \hat{\mathbf{J}}`$ and $`\mathbf{k}\cdot (\mathbf{k} \cdot \hat{\mathbf{J}})`$. Assuming the case of a linearly polarized laser field, we need to consider only one transverse current component (e.g. $`\mathbf{J} \parallel \mathbf{E} \parallel \mathbf{e}_x`$), which leads to the ratio between these terms $`k_x^2 c^2 / \omega^2`$. The optical field is typically contained in the spectral region, $`\omega\in [omega_0\pm \pi/\tau]`$ with $`k_x, k_y \in [\pm \pi/R]`$, where $`\omega_0`$, $`\tau`$ and $`R`$ are the central frequency, duration and the transverse size of the pulse or the field feature. + +In most practical situations (*except for few-cycle and/or diffraction-limit focused pulses*) we have $`omega_0 w_0/c>>\pi`$ and it is safe to + + In optical problems the state of the field is usually described From 633dbc7dc1988305059473e31cbcca53feb77392 Mon Sep 17 00:00:00 2001 From: Igor Andriyash Date: Tue, 12 Dec 2023 17:46:06 +0100 Subject: [PATCH 09/12] minor text modif for main equations --- docs/main_equations.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/main_equations.md b/docs/main_equations.md index a35c579..947b7e7 100644 --- a/docs/main_equations.md +++ b/docs/main_equations.md @@ -1,18 +1,18 @@ ## Basic model -For optical propagation we need to describe evolution of electromagnetic field from the state defined at some time and space region to the state that it has after some time and in a different space region. This computation follows from the Maxwell equations for electric and magnetic fields: +For optical propagation we calculate the electromagnetic field that evolves from the state defined at some time and space, to another state that it takes after some time, and typically in a different location. Formally, for this me need to consider the vectorial Maxwell equations for electric and magnetic fields, -$$ \nabla \times \mathbf{E} = - \partial_t \mathbf{B} $$ +$$ \nabla \times \mathbf{E} = - \partial_t \mathbf{B}, $$ -$$ \nabla \times \mathbf{B} = \frac{1}{c^2} \partial_t \mathbf{E} + \mu_0 \mathbf{J}$$ +$$ \nabla \times \mathbf{B} = \frac{1}{c^2} \partial_t \mathbf{E} + \mu_0 \mathbf{J},$$ -In most cases that concern laser pulse propagation, it is enough to describe electric components of the field, for which we can find the equation by combinng the above ones: +For the partical case of the optical field it is typically enough to describe the electric field, for which the equation can be written by combining the above equations: $$ \nabla \times \nabla \times \mathbf{E} = \nabla (\nabla \mathbf{E}) - \nabla^2 \mathbf{E} = - \partial_t \left( \frac{1}{c^2} \partial_t \mathbf{E} + \mu_0 \mathbf{J}\right) = - \frac{1}{c^2} \partial_t^2 \mathbf{E} - \mu_0 \partial_t\mathbf{J}$$ The term $\nabla (\nabla \mathbf{E})$ here describes contributions of charge density perturbations (plasma waves) which -we may neglect, and for the acccount of fast media resopnse we can use: +we may neglect, and to account for the fast media resopnse we can use: $$ \nabla^2 \mathbf{E} = \frac{1}{c^2} \partial_t^2 \mathbf{E} + \mu_0 \partial_t\mathbf{J} $$ From af44954bab3ef509e00c465e9f6b47353b17c92f Mon Sep 17 00:00:00 2001 From: Igor A Andriyash Date: Mon, 8 Jan 2024 21:34:06 +0100 Subject: [PATCH 10/12] revised main equations after a long pause --- docs/main_equations.md | 104 +++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 50 deletions(-) diff --git a/docs/main_equations.md b/docs/main_equations.md index 7c90d7e..5c7c328 100644 --- a/docs/main_equations.md +++ b/docs/main_equations.md @@ -1,89 +1,93 @@ -In the optical propagation simulation we describe evolution of electromagnetic field from a state defined at some time and space region to another state that it takes after some time and in a different space region. This problem can be described by the Maxwell equations: +## Main considerations + +In the optical propagation simulation we describe evolution of electromagnetic field from a state defined at some time and space region to another state that it takes after some time and in a different space region. + +This problem can be described by the Maxwell equations: + ```math \begin{aligned} - &\nabla \times \mathbf{E} = - \partial_t \mathbf{B}\,,\\ - &\nabla \times \mathbf{H} = \partial_t \mathbf{D} + \mathbf{J}\,,\\ - & \nabla \mathbf{D} = \rho\,, \nabla \mathbf{B} =0\,,\\ - & \mathbf{D} = \epsilon \mathbf{E} \,,\; \mathbf{B} = \mu \mathbf{H} \,. + & \nabla \times \mathbf{E} = - \partial_t \mathbf{B}\,,\\ + & \nabla \times \mathbf{H} = \partial_t \mathbf{D} + \mathbf{J}\,,\\ + & \nabla \mathbf{D} = \rho\,,\\ + & \nabla \mathbf{B} =0\,, \end{aligned} ``` -Assuming all charges of the system to be free, i.e. $`\epsilon=\epsilon_0`$ and $`\mu=\mu_0`$, we can write a pair of separate equations for the fields: +accompanied by the *constitutive* equations + ```math \begin{aligned} - & \nabla^2 \mathbf{E} - \frac{1}{c^2} \partial_t^2 \mathbf{E} = \mu_0 \partial_t\mathbf{J} + \nabla \rho/\epsilon_0 \,, \\ - & \nabla^2 \mathbf{H} - \frac{1}{c^2} \partial_t^2 \mathbf{H} = - \nabla \times \mathbf{J}\,. + & \mathbf{D} = \epsilon_0 \mathbf{E} + \mathbf{P} \,,\\ + & \mathbf{H} = \cfrac{1}{\mu_0} \mathbf{B} - \mathbf{M} \,. \end{aligned} ``` -The terms in the last term in the right hand sides of these equations are the _sources_, and they generate the field of response of the media via the current and density modulations. For most cases it is practical to consider the electric field as it drives the current and is used for the calculations: +In following we will assume that all charges of the system are be free, i.e. $\epsilon_0$ and $\mu_0$ are the electric permittivity and magnetic permeability of vacuum. Moreover, at the current stage of development we will only consider **plasma** processes and discard the polarization and magentization of the media $\mathbf{P}=0$ and $\mathbf{M}=0$. + +To describe the optical field in most partical situations it is enough to follow the electric field, and equation for it can be derived as: + ```math \begin{aligned} - & \nabla^2 \mathbf{E} - \frac{1}{c^2} \partial_t^2 \mathbf{E} = \mu_0 \partial_t\mathbf{J} \,. + & \nabla^2 \mathbf{E} - \frac{1}{c^2} \; \partial_t^2 \mathbf{E} = \mu_0\; \partial_t\mathbf{J} + \frac{1}{\epsilon_0}\nabla \rho\,. \end{aligned} ``` -Note, that here we have dropped the last term $`\nabla \rho/\epsilon_0`$ as it is purely electrostatic ($`\nabla\times\nabla \rho \equiv 0`$), and it does not propagate with the electromagnetic field. +Here the left hand side is the wave equation which describes propagation of the initial field in vacuum (the _optical beam_ whose dynamics we study). The terms in the right hand side are the currents and density modulations, which act as the _sources_ for the field generated by the media as a response to the optical field. + +The two source terms are essenatially different. The first one is excited _instantaneously_ as electrons move in the field and generate electric currents. The second term constitutes charge density modulations and it is typically slower and much weaker one. Let us demonstrate this by assuming the charge continuity (ionized plasma for simplicity) and re-writing the source terms as: -Physically, the contribution of this term can be estimated by re-writing the full source term as: ```math \begin{aligned} - & \mu_0 \partial_t\mathbf{J} + \nabla \rho/\epsilon_0 = \frac{1}{\epsilon_0 } \int_{-\infty}^{t} dt' (\frac{1}{c^2} \partial_t^2 \mathbf{J} - \nabla (\nabla \mathbf{J}) )\,, + & \mu_0 \; \partial_t\mathbf{J} + \frac{1}{\epsilon_0}\nabla \rho = \frac{1}{\epsilon_0 } \int_{-\infty}^{t} dt' \left(\frac{1}{c^2} \; \partial_t^2 \mathbf{J} - \nabla (\nabla \mathbf{J}) \right)\,, \end{aligned} ``` -and comparing the terms under the intergral in the Fourier space, where we have them as $`\omega^2/c^2 \hat{\mathbf{J}}`$ and $`\mathbf{k}\cdot (\mathbf{k} \cdot \hat{\mathbf{J}})`$. Assuming the case of a linearly polarized laser field, we need to consider only one transverse current component (e.g. $`\mathbf{J} \parallel \mathbf{E} \parallel \mathbf{e}_x`$), which leads to the ratio between these terms $`k_x^2 c^2 / \omega^2`$. The optical field is typically contained in the spectral region, $`\omega\in [omega_0\pm \pi/\tau]`$ with $`k_x, k_y \in [\pm \pi/R]`$, where $`\omega_0`$, $`\tau`$ and $`R`$ are the central frequency, duration and the transverse size of the pulse or the field feature. - -In most practical situations (*except for few-cycle and/or diffraction-limit focused pulses*) we have $`omega_0 w_0/c>>\pi`$ and it is safe to - - - - -In optical problems the state of the field is usually described - -initial - -With proper initial and boundary conditions and knowledge of cahrges motion thi - - This computation follows from the Maxwell equations for electric and magnetic fields: - -$$ \nabla \times \mathbf{E} = - \partial_t \mathbf{B}, $$ - -$$ \nabla \times \mathbf{B} = \frac{1}{c^2} \partial_t \mathbf{E} + \mu_0 \mathbf{J},$$ -For the partical case of the optical field it is typically enough to describe the electric field, for which the equation can be written by combining the above equations: +and comparing the terms under the intergral. In the Fourier space, these terms appear as $k^2 \hat{\mathbf{J}}$ and $\mathbf{k}\cdot (\mathbf{k} \cdot \hat{\mathbf{J}})$, where $k=\omega/c$, and for the polarized field, it is enough to consider a single transverse component (e.g. $\mathbf{J} \parallel \mathbf{E} \parallel \mathbf{e}_x$) and discard others. The ratio between source terms therefore reads, $k^2/k_x^2$, and for the field wavelength $\lambda_0$, and transverse size $R$, it scales as $\propto (R/\lambda_0)^2$. It is easy to see, that in most practical situations this indeed allows to assume $\mu_0 \; \partial_t\mathbf{J} \gg \frac{1}{\epsilon_0}\nabla \rho$, and discard contribution of the charge density modulations compared to the induced currents. -$$ \nabla \times \nabla \times \mathbf{E} = \nabla (\nabla \mathbf{E}) - \nabla^2 \mathbf{E} = - \partial_t \left( \frac{1}{c^2} -\partial_t \mathbf{E} + \mu_0 \mathbf{J}\right) = - \frac{1}{c^2} \partial_t^2 \mathbf{E} - \mu_0 \partial_t\mathbf{J}$$ +To conclude this part, in the calculations we will consider the equation for the electric field in the following form: -The term $\nabla (\nabla \mathbf{E})$ here describes contributions of charge density perturbations (plasma waves) which -we may neglect, and to account for the fast media resopnse we can use: +```math +\begin{aligned} + & \nabla^2 \mathbf{E} - \frac{1}{c^2} \partial_t^2 \mathbf{E} = \mu_0 \partial_t\mathbf{J} \,, +\end{aligned} +``` -$$ \nabla^2 \mathbf{E} = \frac{1}{c^2} \partial_t^2 \mathbf{E} + \mu_0 \partial_t\mathbf{J} $$ +and moreover we will use it as a scalar equation, for the field and current components along the laser field polarisation. -In the following we will always consider a scalar version of this equation meaning the component along the laser field polarisation. +## Particular cases #### Vacuum case -In a case when field propagates in vacuum, there is no current $J = 0$ and equation simplifies to - -$$ \nabla^2 E = \frac{1}{c^2} \partial_t^2 E $$ +In a case when no sources are present in the system, i.e. field propagates in vacuum, the equation simplifies down to the uniform wave eqaution -### Plasma dispersion +```math +\begin{aligned} +& \nabla^2 E = \frac{1}{c^2} \; \partial_t^2 E +\end{aligned} +``` -Simplest plasma response can be described with help of non-relativistic motion equation: +#### Plasma dispersion -$$ \mu_0 \partial_t J = -e \mu_0 n_{pe} \partial_t v = \omega_{pe}^2 / c^2 E $$ +A simplest linear plasma response can be described with the help of non-relativistic motion equation: -where $\omega_{pe} = \sqrt{\frac{e^2 n_{pe} }{\epsilon_0 m_e}}$ is a plasma frequency. +```math +\begin{aligned} +& \mu_0 \partial_t J = -e \; \mu_0 \;n_{pe} \; \partial_t v = \omega_{pe}^2 / c^2 E +\end{aligned} +``` -The resulting field equation is: +where $n_{pe}$ is a number density of plasma electrons, and $\omega_{pe} = \sqrt{\frac{e^2 n_{pe} }{\epsilon_0 m_e}}$ is a plasma frequency. Introducing this term in the optical equation leads to -$$ \nabla^2 E = \frac{1}{c^2} \partial_t^2 E + \frac{ \omega_{pe}^2 }{ c^2 } E $$ +```math +\nabla^2 E = \cfrac{1}{c^2} \; (\partial_t^2 \;+ \;\omega_{pe}^2) E +``` -and its spatio-temporal Fourier transform leads to the basic dispersion relation +And considering it in the spatio-temporal Fourier domain provides us the basic dispersion relation -$$ \omega^2 = k^2 c^2 + \omega_{pe}^2 $$ +```math +\omega^2 = k^2 c^2 + \omega_{pe}^2 +``` +--- -___________________________ ## [Return to README](https://github.com/hightower8083/axiprop/blob/new-docs/README.md#documentation) From e44deeec03c9f1a380f3a5afb9131548576ef888 Mon Sep 17 00:00:00 2001 From: Igor A Andriyash Date: Wed, 10 Jan 2024 21:54:30 +0100 Subject: [PATCH 11/12] revised main equations: added representations etc --- docs/main_equations.md | 70 +++++++++++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/docs/main_equations.md b/docs/main_equations.md index 5c7c328..5b75340 100644 --- a/docs/main_equations.md +++ b/docs/main_equations.md @@ -1,8 +1,8 @@ -## Main considerations +# Main considerations -In the optical propagation simulation we describe evolution of electromagnetic field from a state defined at some time and space region to another state that it takes after some time and in a different space region. +In the optical propagation calculations we describe evolution of electromagnetic field from a state defined at some time and space region to another state, that this field takes after some time and in a different space region. -This problem can be described by the Maxwell equations: +This problem can be described by the _Maxwell equations_: ```math \begin{aligned} @@ -13,7 +13,7 @@ This problem can be described by the Maxwell equations: \end{aligned} ``` -accompanied by the *constitutive* equations +accompanied by the _constitutive equations_ ```math \begin{aligned} @@ -22,9 +22,11 @@ accompanied by the *constitutive* equations \end{aligned} ``` -In following we will assume that all charges of the system are be free, i.e. $\epsilon_0$ and $\mu_0$ are the electric permittivity and magnetic permeability of vacuum. Moreover, at the current stage of development we will only consider **plasma** processes and discard the polarization and magentization of the media $\mathbf{P}=0$ and $\mathbf{M}=0$. +In the following we will assume that all charges of the system are free, i.e. $\epsilon_0$ and $\mu_0$ are the electric permittivity and magnetic permeability of vacuum. Moreover, at the current stage of development we will only consider **plasma** processes and discard the polarization and magentization of the media, thus setting $\mathbf{P}=0$ and $\mathbf{M}=0$. -To describe the optical field in most partical situations it is enough to follow the electric field, and equation for it can be derived as: +# Full equation + +In the optical field the electric and magnetic components are consistent with each other, and in most partical situations it is enough to follow the electric component, fot which the equation can be derived as: ```math \begin{aligned} @@ -34,35 +36,38 @@ To describe the optical field in most partical situations it is enough to follow Here the left hand side is the wave equation which describes propagation of the initial field in vacuum (the _optical beam_ whose dynamics we study). The terms in the right hand side are the currents and density modulations, which act as the _sources_ for the field generated by the media as a response to the optical field. -The two source terms are essenatially different. The first one is excited _instantaneously_ as electrons move in the field and generate electric currents. The second term constitutes charge density modulations and it is typically slower and much weaker one. Let us demonstrate this by assuming the charge continuity (ionized plasma for simplicity) and re-writing the source terms as: +#### Source terms + +The two source terms are essentially different in nature. The first one is excited _instantaneously_ as electrons generate electric currents being moved by the field. The second term constitutes the charge density modulations, and it presents a slower response and is typically considered to be much weaker. Let us demonstrate this by assuming the charge continuity in plasma and re-writing the source terms in the intergral form: ```math \begin{aligned} - & \mu_0 \; \partial_t\mathbf{J} + \frac{1}{\epsilon_0}\nabla \rho = \frac{1}{\epsilon_0 } \int_{-\infty}^{t} dt' \left(\frac{1}{c^2} \; \partial_t^2 \mathbf{J} - \nabla (\nabla \mathbf{J}) \right)\,, + & \mu_0 \; \partial_t\mathbf{J} + \frac{1}{\epsilon_0}\nabla \rho = \frac{1}{\epsilon_0 } \int_{-\infty}^{t} dt' \left(\frac{1}{c^2} \; \partial_t^2 \mathbf{J} - \nabla (\nabla \mathbf{J}) \right)\,. \end{aligned} ``` -and comparing the terms under the intergral. In the Fourier space, these terms appear as $k^2 \hat{\mathbf{J}}$ and $\mathbf{k}\cdot (\mathbf{k} \cdot \hat{\mathbf{J}})$, where $k=\omega/c$, and for the polarized field, it is enough to consider a single transverse component (e.g. $\mathbf{J} \parallel \mathbf{E} \parallel \mathbf{e}_x$) and discard others. The ratio between source terms therefore reads, $k^2/k_x^2$, and for the field wavelength $\lambda_0$, and transverse size $R$, it scales as $\propto (R/\lambda_0)^2$. It is easy to see, that in most practical situations this indeed allows to assume $\mu_0 \; \partial_t\mathbf{J} \gg \frac{1}{\epsilon_0}\nabla \rho$, and discard contribution of the charge density modulations compared to the induced currents. +In the Fourier space, the terms under the integral appear as $k^2 \hat{\mathbf{J}}$ and $\mathbf{k}\cdot (\mathbf{k} \cdot \hat{\mathbf{J}})$, where $k=\omega/c$, and for the polarized field, it is enough to consider a single transverse component (e.g. $\mathbf{J} \parallel \mathbf{E} \parallel \mathbf{e}_x$) and discard others. The ratio between source terms therefore reads, $k^2/k_x^2$, and for the field wavelength $\lambda_0$, and transverse size $R$, it scales as $\propto (R/\lambda_0)^2$. It is easy to see, that in most practical situations this indeed allows to assume $\mu_0 \; \partial_t\mathbf{J} \gg \frac{1}{\epsilon_0}\nabla \rho$, and discard contribution of the charge density modulations compared to the induced currents. + +# Working equation To conclude this part, in the calculations we will consider the equation for the electric field in the following form: ```math \begin{aligned} - & \nabla^2 \mathbf{E} - \frac{1}{c^2} \partial_t^2 \mathbf{E} = \mu_0 \partial_t\mathbf{J} \,, + & \nabla^2 \mathbf{E} - \frac{1}{c^2} \partial_t^2 \mathbf{E} = \mu_0 \partial_t\mathbf{J} \,, & +\qquad (1) \end{aligned} ``` and moreover we will use it as a scalar equation, for the field and current components along the laser field polarisation. -## Particular cases - #### Vacuum case -In a case when no sources are present in the system, i.e. field propagates in vacuum, the equation simplifies down to the uniform wave eqaution +In a case when no sources are present in the system, i.e. field propagates in vacuum, the equation simplifies down to the uniform wave equation ```math \begin{aligned} -& \nabla^2 E = \frac{1}{c^2} \; \partial_t^2 E +& \left(\nabla^2 - \frac{1}{c^2} \; \partial_t^2\right) E = 0 \end{aligned} ``` @@ -76,18 +81,47 @@ A simplest linear plasma response can be described with the help of non-relativi \end{aligned} ``` -where $n_{pe}$ is a number density of plasma electrons, and $\omega_{pe} = \sqrt{\frac{e^2 n_{pe} }{\epsilon_0 m_e}}$ is a plasma frequency. Introducing this term in the optical equation leads to +where $n_{pe}$ is a number density of plasma electrons, and $\omega_{pe} = \sqrt{\frac{e^2 n_{pe} }{\epsilon_0 m_e}}$ is a plasma frequency. + +Introducing this term in the optical equation leads to the following equation: ```math -\nabla^2 E = \cfrac{1}{c^2} \; (\partial_t^2 \;+ \;\omega_{pe}^2) E +\left(c^2 \nabla^2 - \partial_t^2 \; - \; \omega_{pe}^2 \right) \; E = 0\,, ``` -And considering it in the spatio-temporal Fourier domain provides us the basic dispersion relation +which if considered in the spatio-temporal Fourier domain leads to the well-known dispersion relation ```math \omega^2 = k^2 c^2 + \omega_{pe}^2 ``` ---- +# Field representations + +When approaching the computational problem of optical propagation we typically need to solve Eq. (1) with an initial condition that prepresents the initial beam state. There are two standard ways to define and consider the field. + +#### Spatial representation + +In so-called spatial form, the field is defined at a time $t_0$ in a full space as $E_0(x,y,z)=E(x,y,z, t_0)$, and we look for the state after some time pass, so we calculate, $E_1(x,y,z) = E(x,y,z, t_0+\Delta t)$. The spatial domain where $E_1$ is localized is usually adjusted to the propagated disctance, typically $z\to z+c\Delta t$ (we will always consider propagation along $z$-axis). This appropach is typical for the particle-in-cell (PIC) codes, where electromagnetic solver is couples with the charges particles motion, that can lead to the complex charge and current density structures in the spatial domain. + +#### Temporal representation + +Here the field is defined in the spatial plane located at $z_0$ as a function of time $E_0(x, y, t)=E(x, y, z_0, t)$, and we look at its state at a different location $E_1(x,y,t) = E(x,y,z_0+\Delta z, t)$ at a later time when the field arrives there, e.g. $t \to t+\Delta z/c$. In this approach, media is presented by an oscillating plane, and it is more convenient be used with the temporal spectral decompositions of the field, while resolving the longitudinal dynamics of the plasma on a scale of the pulse length $c\tau$, may be more challenging. + +While both approaches are mathematically equavalent, they would lead to different implementations, and usually serve different purposes. The spatial representation is used in PIC simulation as it is giving better description of the excited plasma structures and can be easilty extended to the more rigorous account of the source terms. **Temporal representation** is more common for the optical propagation problems, and in the following we will always be considering it as a **default** one. In vacuum without source terms, the conversion between representations can be easily done using propagation techniques. + +# Propagation equation with temporal representation + +Let us calculate the field $E_1(x,y,t) = E(x,y,z_0+\Delta z, t)$ for a known $E_0(x, y, t)=E(x, y, z_0, t)$, i.e. considering $z$ the propagation variable, and the field being defined in the temporal domain. For this we divide the Laplace operator in Eq(1) into longitudinal and transverse parts: + +```math +\begin{aligned} +& \partial_z^2 \; \mathbf{E} = \frac{1}{c^2} \;\partial_t^2 \;\mathbf{E} \;-\; \nabla_\perp^2 \;\mathbf{E} + \mu_0 \; \partial_t \; \mathbf{J} \,, +\end{aligned} +``` + +where $\nabla_\perp^2 = \partial_x^2 + \partial_y^2$ for the problem defined in the cartesian geometry $(x,y,t)$, and $\nabla_{\perp}^2 = \cfrac{1}{r}\; \partial_r (r \; \partial_r) + \cfrac{1}{r^2} \; \partial_\theta^2$ in the cylindrical coordiantes $(r, \theta, t)$. + +Let us consider the problem + ## [Return to README](https://github.com/hightower8083/axiprop/blob/new-docs/README.md#documentation) From a49aed85ee614eaf9e864e78bd5cf87553fa5f05 Mon Sep 17 00:00:00 2001 From: Igor A Andriyash Date: Sun, 4 Feb 2024 20:31:36 +0100 Subject: [PATCH 12/12] update docs, start section on spectral methods --- docs/main_equations.md | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/docs/main_equations.md b/docs/main_equations.md index 5b75340..82ed797 100644 --- a/docs/main_equations.md +++ b/docs/main_equations.md @@ -115,13 +115,38 @@ Let us calculate the field $E_1(x,y,t) = E(x,y,z_0+\Delta z, t)$ for a known $E_ ```math \begin{aligned} -& \partial_z^2 \; \mathbf{E} = \frac{1}{c^2} \;\partial_t^2 \;\mathbf{E} \;-\; \nabla_\perp^2 \;\mathbf{E} + \mu_0 \; \partial_t \; \mathbf{J} \,, +& \partial_z^2 \; \mathbf{E} = \frac{1}{c^2} \;\partial_t^2 \;\mathbf{E} \;-\; \nabla_\perp^2 \;\mathbf{E} + \mu_0 \; \partial_t \; \mathbf{J} \,, \qquad (2) \end{aligned} ``` where $\nabla_\perp^2 = \partial_x^2 + \partial_y^2$ for the problem defined in the cartesian geometry $(x,y,t)$, and $\nabla_{\perp}^2 = \cfrac{1}{r}\; \partial_r (r \; \partial_r) + \cfrac{1}{r^2} \; \partial_\theta^2$ in the cylindrical coordiantes $(r, \theta, t)$. -Let us consider the problem +# Spectral methods +All our computations will adopt the so-called *spectral* methods. In the optical problems this commonly involves presentation of the field and the source terms as the sums of the waves both temporally and in the transverse plane. + +For the **cartesian** geometry such decomposition is well-known as the spatio-temporal Fourier series: + +```math +\begin{aligned} +& A (x,y,t) = Re \left [ \sum_{ k_x, k_y, \omega} \; \hat{A}(k_x, k_y, \omega) \; \exp(ik_x x + ik_y y-i \omega t) \right ]\,, +\end{aligned} +``` + +and for the **cylindrical** coordiantes we define is as the Fourier-Bessel (or Fourier-Hankel) series: + +```math +\begin{aligned} +& A (r,\theta,t) = Re \left [ \sum_{k_r, m, \omega} \; \hat{A}(k_r, m, \omega) \; J_m(k_r r) \; \exp(-i m \theta-i \omega t) \right ] +\end{aligned} +``` + +The properties of such representations are defined by the sampling that we choose in the real and spectral spaces. For the case of spatio-temporal Fourier series, it is well known that uniform sampling in space + +Both these representations transform the first two terms in the right hand side of Eq(2) into: + +```math +\frac{1}{c^2} \;\partial_t^2 \;\mathbf{E} \;-\; \nabla_\perp^2 \;\mathbf{E} \to -(\omega^2 - k_r^2) \hat{E} +``` ## [Return to README](https://github.com/hightower8083/axiprop/blob/new-docs/README.md#documentation)