diff --git a/README.md b/README.md index 9e6394a..a5411b7 100644 --- a/README.md +++ b/README.md @@ -1,91 +1,64 @@ # 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`: fully 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 -``` - -and some focusing optics, -```python -f_N = 40 # f-number f/40 -f0 = 2 * R_las * f_N # focal length -``` +### 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)`$) -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 ) -``` +### 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 -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) -``` +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) -Plot the results using your favorite tools +## Documentation -![example_image](https://github.com/hightower8083/axiprop/blob/main/examples/example_figure.png) +Documentation is organized in a few sections: -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. + - [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 +## 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/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 new file mode 100644 index 0000000..82ed797 --- /dev/null +++ b/docs/main_equations.md @@ -0,0 +1,152 @@ +# Main considerations + +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_: + +```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\,, +\end{aligned} +``` + +accompanied by the _constitutive equations_ + +```math +\begin{aligned} + & \mathbf{D} = \epsilon_0 \mathbf{E} + \mathbf{P} \,,\\ + & \mathbf{H} = \cfrac{1}{\mu_0} \mathbf{B} - \mathbf{M} \,. +\end{aligned} +``` + +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$. + +# 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} + & \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} +``` + +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. + +#### 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)\,. +\end{aligned} +``` + +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} \,, & +\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. + +#### 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 equation + +```math +\begin{aligned} +& \left(\nabla^2 - \frac{1}{c^2} \; \partial_t^2\right) E = 0 +\end{aligned} +``` + +#### Plasma dispersion + +A simplest linear plasma response can be described with the help of non-relativistic motion equation: + +```math +\begin{aligned} +& \mu_0 \partial_t J = -e \; \mu_0 \;n_{pe} \; \partial_t v = \omega_{pe}^2 / c^2 E +\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 the following equation: + +```math +\left(c^2 \nabla^2 - \partial_t^2 \; - \; \omega_{pe}^2 \right) \; E = 0\,, +``` + +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} \,, \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)$. + +# 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) 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 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": "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\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 c4868e9..0000000 Binary files a/examples/example_figure.png and /dev/null differ diff --git a/examples/test2d.ipynb b/examples/test2d.ipynb index 5b4c17e..6d063a6 100644 --- a/examples/test2d.ipynb +++ b/examples/test2d.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -19,7 +19,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -44,7 +44,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -56,18 +56,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": [ "Lx = 5 * R_las # total radius [m]\n", "Ly = 5 * R_las # total radius [m]\n", @@ -93,7 +84,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -104,24 +95,9 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "1043172217e14d4caa0987e9509a3eb6", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - " 0%| | 00:00" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "plt.figure(figsize=(8,4), tight_layout=True, dpi=100)\n", "\n", diff --git a/somedocs/propagatorDHT.ipynb b/somedocs/propagatorDHT.ipynb deleted file mode 100644 index acbc3eb..0000000 --- a/somedocs/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": "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\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": "iVBORw0KGgoAAAANSUhEUgAAAz4AAAFzCAYAAAD/ktxDAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAABJ0AAASdAHeZh94AABS1klEQVR4nO3dd1hUZ/7+8XsKTVBAERS7QVFARAFbLJCNJmqKibpppnfTdHd/6UXS1v3uuskmG930ZrombtzEJBoVe6GpGI1iFwuKASlS5/z+GGV11URmBoYZ36/rmsvhlOd8GI54bp/nPMdkGIYhAAAAAPBiZncXAAAAAAANjeADAAAAwOsRfAAAAAB4PYIPAAAAAK9H8AEAAADg9Qg+AAAAALwewQcAAACA1yP4AAAAAPB6BB8AAAAAXo/gAwAAAMDrEXwAAAAAeD2CjwNKSkr08MMPa8SIEWrdurVMJpOmTJnilloWLVqk4cOHKzw8XEFBQYqPj9crr7yi2tpat9QDAAAANEUEHwcUFhbqjTfeUGVlpcaMGeO2OhYsWKCLL75YNTU1evPNNzVnzhylpKTooYce0h/+8Ae31QUAAAA0NSbDMAx3F+FpTnxkJpNJhw8fVuvWrfXMM880eq/PhAkTNGvWLBUWFiowMLBu+SWXXKJVq1apuLi4UesBAAAAmip6fBxgMplkMpnOadvPPvtMAwcOVGBgoIKCgnTJJZcoOzvbJXX4+PjI19dXAQEBpywPCQmRv7+/S44BAAAAeAOCTwN68cUXdd111ykmJkaff/65PvzwQ5WUlGjIkCH66aefnG7/nnvuUVVVlR588EHt27dPRUVF+vDDD/XVV1/p4YcfdsF3AAAAAHgHhro56WxD3fbs2aOuXbvq3nvv1SuvvFK3vLS0VN26ddPQoUP12WefOX38FStWaPz48dq3b58kyWKx6M9//rP+3//7f063DQAAAHgLenwayPfff6+amhrddNNNqqmpqXv5+/tr2LBhWrx4cd227733Xt3wud96FRUV1e2XmZmpq666SomJiZo7d64WLlyoxx57TE8++aSee+65xv+mAQAAgCbK6u4CvNXBgwclScnJyWdcbzb/N3NeeOGFevPNN8+p3WbNmtW9v++++xQREaGvvvpKFotFkpSamiqz2awpU6bohhtuUNeuXR39FgAAAACvQfBpIGFhYZKkWbNmqVOnTr+6bbdu3dStW7d6HyMnJ0fXXXddXeg5ITk5WTabTZs2bSL4AAAAACL4NJhLLrlEVqtV27Zt09ixYxvkGJGRkcrIyFBtbe0p4WflypWSpPbt2zfIcQEAAABPQ/Bx0Lx581RWVqaSkhJJ0k8//aRZs2ZJkkaNGqXOnTvr2Wef1RNPPKHt27fr0ksvVWhoqA4ePKg1a9YoMDBQaWlpTtUwefJkPfjgg7r88st19913q1mzZvrxxx81bdo0XXzxxerdu7fT3ycAAADgDZjVzUGdO3fWrl27zrhux44d6ty5syTp3//+t/7xj38oMzNTlZWVatOmjZKTk3XPPffod7/7ndN1fPnll3rppZe0efNmHTt2TJ07d9a1116ryZMnn/JQUwAAAOB8RvABAAAA4PWYzhoAAACA1yP4AAAAAPB6TG5wjoqKipSenq4OHTrIz8/P3eUAAAAA57XKykrt2bNHw4YNU0hIyG9uT/A5R+np6RozZoy7ywAAAABwkjlz5ujKK6/8ze0IPueoQ4cOkuwfbFRUlJurAQAAAM5veXl5GjNmTN11+m8h+JyjE8PboqKiFBsb6+ZqAAAAAEg659tQmNwAAAAAgNcj+AAAAADwegQfAAAAAF6P4AMAAADA6xF8AAAAAHg9gg8AAAAAr0fwAQAAAOD1CD4AAAAAvB7Bp742b5b27nV3FQAAAADqgeBTX+PGqfYvf3F3FQAAAADqgeDjgG1btri7BAAAAAD1QPBxQHVlpbtLAAAAAFAPBB8AAAAAXo/g4wCTYbi7BAAAAAD1QPBxgMlmc3cJAAAAAOqB4OMAenwAAAAAz0LwcQDBBwAAAPAsBB9HEHwAAAAAj0LwcQA9PgAAAIBnIfg4gskNAAAAAI/i9cFn2bJlGjVqlEJDQxUQEKBu3brpueeec65RenwAAAAAj2J1dwEN6eOPP9aNN96o3//+9/rggw8UFBSkbdu2ad++fU61y3TWAAAAgGfx2uCTn5+vu+66S3fffbemT59etzw1NdX5xgk+AAAAgEfx2qFub731lsrKyvTII4+4vnGGugEAAAAexWuDz5IlS9SyZUtt3rxZCQkJslqtCg8P1z333KOjR4861TZD3QAAAADP4tVD3crLyzV+/Hg99thjevnll7V27Vo988wzys3N1dKlS2Uymc64b0FBgQ4dOnTKsry8vP9+QY8PAAAA4FG8NvjYbDZVVFTomWee0aOPPipJSklJka+vryZNmqQff/xRF1988Rn3nT59utLS0s7euGHIMIyzBicAAAAATYvXDnVr1aqVJOmSSy45ZfnIkSMlSVlZWWfdd+LEicrNzT3lNWfOnLr1JptNNoa7AQAAAB7Da3t84uPjtWrVqtOWG8eHqZnNZ8984eHhCg8PP3vjhiGbzSaLxeJ0nQAAAAAantf2+IwdO1aSNG/evFOWf/vtt5KkAQMGONy2yWZTbW2t48UBAAAAaFRe2+MzYsQIXX755Xr22Wdls9k0YMAAZWRkKC0tTZdddpkGDx7seOPHe3wAAAAAeAav7fGRpM8++0yTJk3SG2+8oZEjR2rGjBmaPHmyZs2a5VS73OMDAAAAeBav7fGRpICAAE2dOlVTp051bcP0+AAAAAAexat7fBoK9/gAAAAAnoXg4yB6fAAAAADPQfBxAD0+AAAAgGch+DiCe3wAAAAAj0LwcYCJ4AMAAAB4FIKPA5jOGgAAAPAsBB9HGAb3+AAAAAAehODjAIa6AQAAAJ6F4OMIgg8AAADgUQg+DjAx1A0AAADwKAQfBzDUDQAAAPAsBB8HMKsbAAAA4FkIPg6gxwcAAADwLAQfR3CPDwAAAOBRCD4OoMcHAAAA8CwEHweYJIIPAAAA4EEIPg4w2WwMdQMAAAA8CMHHAQx1AwAAADwLwccBBB8AAADAsxB8HEDwAQAAADwLwccBJqazBgAAADwKwccB9PgAAAAAnoXg4yCCDwAAAOA5CD4OYKgbAAAA4FnOq+Dz1ltvyWQyKSgoyKl2GOoGAAAAeBarsw0sWrRIL730knbv3q3g4GDFxMSob9++SkxMVK9eveTj4+OKOp2Wn5+vP/3pT4qMjFRxcbFTbRF8AAAAAM/iVPBZs2aNRowYccqwr2XLltW99/HxUVxcnBITE5WYmKi77rrLmcM55Z577tHQoUPVsmVLzZo1y6m2CD4AAACAZ3FqqNuLL76o2tpaTZs2TUeOHNFVV10lSbr77rvVsmVLVVVVKTs7W2+++abuvfdelxTsiJkzZyo9PV3Tp093SXtm7vEBAAAAPIpTPT7Z2dnq2bOnJk+eLElq0aKFJGn69Ol65ZVX9Pzzz+v555/XxIkT1axZM+erdUBBQYEmTZqkqVOnqn379ue8z6FDh05ZlpeXV/feJGZ1AwAAADyJU8GnoKBAAwYMqPvaZDL9t2GrVVOmTFGrVq2UlpamjRs3OnMoh02cOFHR0dH16nGaPn260tLSzrqeoW4AAACAZ3FqqFtYWJiqq6vrvvb395cklZeX1y27//771aJFC02dOtWZQzlk9uzZmjt3rt58881TQtlvmThxonJzc095zZkz578bMNQNAAAA8ChO9fh06tRJe/bsqfs6IiJCkrRr1y717NlTkr0XqF+/fpo7d65eeuklZw5XL6Wlpbrvvvv0wAMPKDIyUkVFRZKkqqoqSVJRUZF8fHwUGBh42r7h4eEKDw8/a9tmSTU1NQ1RNgAAAIAG4FSPz7Bhw5Sbm6uSkhJJUmJiogzD0MKFC0/ZrqSkRPv27XPmUPV2+PBhHTx4UNOmTVNoaGjd65NPPlFZWZlCQ0N1ww03ONQ2DzAFAAAAPItTPT7jx49Xenq6fvzxR40ZM0YjRoxQWFiYXnjhBaWmpiomJkbLli3TggUL1LFjR1fVfE7atGmjRYsWnbZ86tSpSk9P17x58xQWFuZQ2ybDoMcHAAAA8CBOBZ+EhIRTntvj6+uradOm6eabb1Z8fLyaN2+uo0ePSpJuueUWpwqtL39/f6WkpJy2/L333pPFYjnjunPFUDcAAADAszg11O1MbrzxRr3zzjtq27atiouL5e/vr0mTJunRRx919aHcxkyPDwAAAOBRXB58JHvvzp49e3T48GGVlJRo2rRpslgsDXGoenvvvfdUWlrqdDu1BB8AAADAY9RrqFufPn2UlJSkxMREJSYmqnfv3vL19T3r9i1btnS6wKaq5qRpvAEAAAA0bfUKPuvWrdO6dev0zjvv2He2WhUbG1sXhpKSkhQfHy8fH58GKbZJsdlks9lkNjdIpxkAAAAAF6pX8Nm2bZsyMzOVmZmpjIwMZWVlKScnRzk5OXr77bclST4+PoqLi6sLQomJiYqPj5fV6tQ8Ck2OUVur2tpagg8AAADgAeqVRrp06aIuXbpo3Lhxdct27NhRF4QyMzOVlZVV93rrrbck2cNQfHy81qxZ49rq3ai2ulpVVVXnR+8WAAAA4OGc7oY5Wxg6EYROfnmT2upqVVZWKjAw0N2lAAAAAPgNDTL+7EQYGj9+fN2yHTt2NMSh3OZEjw8AAACApq/RblDp0qVLYx2qUdhqalRZWenuMgAAAACcA6d6fK699lr16dNHffr0UUJCgsLDw11VV5NXc3yoGwAAAICmz6ng8/nnn+uLL76o+7pt27Z1QejEq3Pnzs7W2CTZamoY6gYAAAB4CKeCzzfffHPK9Nb5+fnat2+fvvnmG5lMJklScHCwEhIS1KdPH02bNs0lRTcFtfT4AAAAAB7DqeAzcuRIjRw5su7rgoICZWZmauXKlfriiy/0888/q6ioSIsXL1Z6erpXBR/u8QEAAAA8h0snNwgPD9fIkSP17LPPatOmTXrrrbfUrFkzPf3003r99dddeSi3q6mqIvgAAAAAHqJBprM+4bbbblNgYKDuuOMObdiwoSEP1fhsNoIPAAAA4CEafDrra665Rm3atNHUqVMb+lCNymQYTG4AAAAAeIhGeY5PTEyM5s2b1xiHajyGoYqKCndXAQAAAOAcODXUbcyYMUpMTKx7RUREnHG7Xbt26fDhw84cqsnxsVhUXl7u7jIAAAAAnAOngs/XX3+tuXPn1n3dtm3buhCUkJCgsLAwff3111q/fr169uzpdLFNiY/ForKyMneXAQAAAOAcOBV8fvzxR2VlZSkrK0uZmZnaunWr5s6dq7lz59Y9x8cwDEnSQw895Hy1TYjVbFZlZaVqa2tlsVjcXQ4AAACAX+FU8ElNTVVqamrd16WlpcrOzlZWVpZycnK0e/duhYeHa9y4cRo7dqzTxTYlPhaLqo8/xLRZs2buLgcAAADAr3DpdNZBQUEaMmSIhgwZ4spmmySr2ayK4w8xJfgAAAAATVujzOrmjXwsFtXW1vIsHwAAAMADON3jk5ubqy+//FL79u1TeHi44uPj1bdvX3Xt2tUV9TVZoeXlMvbv51k+AAAAgAdwela3cePGqba2tm4SgxOTGgQHB6tPnz7q27dv3Ss6Otr5ipuIG99/X5K0+9JLpY4d3VwNAAAAgF/jVPB5+umnVVNTo7Fjx2r06NEqKirS+vXrlZWVpU2bNmnRokVatGiRTCaTTCaTampqXFV3kxH8yivSlVe6uwwAAAAAv8Kp4JOXl6fevXvriy++OG1dVVWVcnNz66a7zsnJceZQ9bZw4ULNnDlTK1as0J49exQSEqKkpCQ9/fTTSkxMdNlxaqqrXdYWAAAAgIbhVPBp3bq1YmJizrjO19e3boibO8yYMUOFhYV66KGHFBMTo0OHDmnatGkaMGCAvv/+e1100UUuOQ7BBwAAAGj6nAo+l19+uRYuXOiqWlzqtddeU3h4+CnLLr30UkVFRenFF18k+AAAAADnEaems37sscd04MABvf32266qx2X+N/RI9ucMxcTEaM+ePS47TjXTWQMAAABNnlM9Pm3bttWcOXN01VVXac+ePXrkkUcUEBDgqtpcrri4WFlZWb/Z21NQUKBDhw6dsiwvL++M29bW1Ki8vJyHmAIAAABNmFPBp7a2Vv/5z39kMpn03HPPadq0aRo+fLj69++vpKQk9e3bV6Ghoa6q1Wn33XefysrK9MQTT/zqdtOnT1daWto5tWmrrVVJSQnBBwAAAGjCnAo+jzzyiF566aW6Z/iUlZVpzpw5+ve//123TefOnZWYmKikpCQ9/PDDzlXrhKeeekofffSRXn311d+c1W3ixIkaP378Kcvy8vI0ZsyY07Y1ampUUlKiiIgIV5YLAAAAwIWcCj6ffPKJLBaL3n//fV1++eUqLi5WTk5O3RTWWVlZ2rFjh3bs2KHZs2e7LfikpaXp+eef1wsvvKD777//N7cPDw8/4z1CZ2Kz2VR69KizJQIAAABoQE4Fn6KiIo0YMULXXXedJPvkAe3atdPo0aPrtjly5IgyMzOVnZ3tXKUOSktL05QpUzRlyhQ9/vjjLm/fqK3VUYIPAAAA0KQ5FXx69OghPz+/X92mZcuWGj58uIYPH+7MoRzy3HPPacqUKXryySf1zDPPNMxBbDaVlJQ0TNsAAAAAXMKp4HPrrbdqypQpKisrU2BgoKtqcolp06bp6aef1qWXXqrRo0dr1apVp6wfMGCAS45jNpm0b98+GYYhk8nkkjYBAAAAuJZTwefee+/Vl19+qdtvv10ffPCBfH19XVWX0+bOnStJ+u677/Tdd9+dtv7EhAzOslosKiwsVHFxsUJCQlzSJgAAAADXcuoBpuHh4SotLdUXX3yhgQMH6ssvv1RFRYWranPK4sWLZRjGWV+uYjWbVVJSooMHD7qsTQAAAACu5VSPT3FxsTIyMiRJ2dnZGj9+vHx9fRUXF6ekpCQlJiYqMTFRvXr1ktXq1KGaLKvFopKSEhUUFCg6Otrd5QAAAAA4A6fSSFlZmdavX6+srCxlZ2crOztbGzZsUGZmpjIzM+vuefH19VWvXr20Zs0alxTdlFgkReflqXzNGmnIEHeXAwAAAOAMTIYrx31Jqq2t1aZNm5SdnX1KICotLVVtba0rD9WoNm7cqLi4OOVKij3D+kp/f5kPHJBPcHBjlwYAAACcd+quz3NzFRt7piv0UznV4xMWFqbLLrtM7733Xt0yi8WiuLg4xcXF6cYbb6xbvn37dmcO1eT5VVQoPzdX7S680N2lAAAAAPgfTk1ucOzYsXOezKBr167OHMoj5G/b5u4SAAAAAJyBU8Gne/fuKisrc1UtHm/vtm2y2WzuLgMAAADA/3Aq+Nx4441avHixDh8+7Kp6PNqR/fu1b98+d5cBAAAA4H84FXweeOABxcXF6dprr1VxcbGravJYpYcPKy8vz91lAAAAAPgfTgWftm3bqrq6WgsXLlSvXr30/vvvq6ioyEWleR5LTY02rl2r8vJyd5cCAAAA4CROzepWVFSkrKwsSdLevXt12223yWq1qnfv3nUPL/X2B5ieLGXvXsU8+qgOZWSo2WefubscAAAAAMc1yANMMzIylJGRcV48wPRkPXNzZbHZFPTDDzp27JgCAgLcXRIAAAAAORl8/Pz8lJycrOTk5LplZ3uAaWZmptPFNnXW6mpJkvnYMa1evVopKSnuLQgAAACAJCeDz5mcrw8wPZlPTY3WrFmj7t26KbJdO3eXAwAAAJz3nJrc4GSbNm3SsmXL9NNPP6m2tva09efDA0xP8KmtVfcvvlDLHj1UMXu2u8sBAAAAzntOB59FixapW7duiouL07Bhw9SrVy8FBwfr6quvVnp6uitq9EgXb9ok/9JSHXrpJVVVVbm7HAAAAOC85lTwycrK0siRI7Vt2zaFh4erf//+6tWrl2w2m+bMmaOLLrpI999/vwzDcFW9HiPw+JTWJfv2Kf2dd1T9ww/Sefg5AAAAAE2BU8Hn2WefVVVVlf7xj39o//79WrFihXJycnT06FHNmjVL3bt314wZM3T33Xe7ql6PYToecoIqKjRw8mT5XHKJyv79bzdXBQAAAJyfnAo+S5cuVVJSkh544IFTllutVl199dXKzs5WSkqK3n77bf3www9OFeqpwouLFVRRIUla98EHOpCWJs2a5eaqAAAAgPOLU8Hn2LFjioqKOut6f39/ffzxx/Lz89Prr7/uzKE8lv/xIW+SFLZypdpMmSLj97/X4exsadcu6fgU2AAAAAAajlPBp127dtqxY8evbhMREaFhw4Zp9erVzhzKK3QuKpJkHwa38/77pc6dVfG738mw2aR9+9xbHAAAAODFnAo+I0aM0Jo1a7R27dpf3a558+Y6fPiwM4fyCr7Hh7xJUrd16+zLli/X5ssuk9q107GnnrIHoMWLJZvNTVUCAAAA3sep4DNp0iT5+/tr3Lhxys3NPeM2NTU1yszMVFhYmDOH8jrBZWWSJLPNprbHp/0+/OGHKk1IkFJTdXjGDNU+8YT01FP22eCOHJHO8HwkAAAAAL/NqeDTrVs3TZ8+Xfn5+UpMTNRNN92k9PR0FRUVqby8XOvXr9d1112nnTt3atSoUa6q2euEHL8PqNXBgwo6dEiSVD51qiwvvig9/7y23323jPBwVQ0apOqcHOmuu6SMDKm0VMrKYppsAAAA4DeYDBc8ZOfLL7/UnXfeqV9++UUmk+mUdYZhqF27dlq7dq3atGnj7KHcZuPGjYqLi1OupNhGOF6t2SzL8eFuxc2aKfh4ONrbpYva79ihI7GxsppMapGbq8MvvKAWS5bIeviwzN9+K02bJsXFSePHSz/8IA0aJLVqJR0+LLVu3QjVAwAAAA2r7vo8N1exsb99he5Uj88JV199tfLy8vTXv/5VQ4cOVWhoqCwWi9q1a6e7777bbaGntLRUkyZNUmRkpPz9/ZWQkKBPP/200etwhOWke3yCT5oZLnLnTklSwJYtanF8eKH5r3+V7/ffy5yZqfwhQ6T/+z/ZbrlF+ePGSVdeqZLLLlPxuHFSeLiO/v3vqh43TrbYWGnHDun22+3D6Y4ckaZMkVaulAoKpA8/lIqKpMJCKTvb3qt09Ki9l0li2B0AAAA8ikt6fJqqESNGaO3atZo6daq6d++ujz/+WG+99ZY++ugjXX/99fVqq7F7fBxl03/TbLXFIp/aWtVYLLKZzfKtrlZRcLBCioslSYciI9X6+GxyB/r2VZusLFW2bKnS7t3VatUqHb7sMjVft05+e/aoYMoUhU2bJpnNKn71VQVPnKja3/1OtnHj5PvUUzKeekrm0lLpyy+l11+XZs60h6mpU6W0NCkhQbroImnGDGncOKl5c+nHH6Ubb5S2bJEOHpSGD5cyM6UWLaSoKCknR7rgAsnf3x7SuneXKiqkY8ekli2lqir7N+rr29gfMwAAANysvj0+MurhzjvvNObPn1+fXdzmm2++MSQZH3/88SnLhw8fbkRGRho1NTX1ai83N9eQZOTa+z68+lVrMhmGZFRbLHXLKnx86t6XBwTUvS9p3twwJONocLBRYzYbhmQciYysW3+4WzfDkAyb2Wwc7tXLvk+HDkZJly6GIRkHhw83qgMDDUMy9t10k2Ezm43q5s2Ng3ffbRiSUZaYaBRdfbW93QceMCri4w2b1WocfvVVoyYiwqhp39745b33DFtAgFE5erRR9vLLhq15c+PY3/5mVN51l1HboYNRsWCBUTtqlGEbOtSozsoybAMHGraJEw1j2TLD6N/fMGbONIx33zWM1FTD2LDBMJ56yjAmTDCMAwcM4667DOO55wxj1y7DuPFGw/j6a8NYvtwwbrvNMLZuNYxPPjGMhx82jNJSw5g2zTBmzLC/f+YZw1i40DB27DCMJ580jJ07DWPFCsP4618N49gxw/jqK8P49FPDqKkxjDfftK8rLjaM6dMNY+9ew9i+3V5TZaVhrF5tGN98Yz8R580zjKwsw6iuNozZsw1j/37DOHLE3l5lpWFs22YY6en2bXNyDGPTJsOw2QxjyRLDKCgwjIoKw1i0yDCqqgzj0CHDyMy0b7tzp/2YhmEYP/1kGIWF9v1ycuzblpUZxubN9vWHD9trNAz7n0VF9vc7dti3ramxf16GYd+voMD+vrjY/rVh2JdVVdmPcfiwfVl1tWEcPWp/X1FhfxmGYZSX29s80Z5h2PerrLS/r6mx73vifW2t/f2JPwEAgFequz7PzT2n7evV42M2m3XLLbfonXfecTiZNZY777xTn376qX755RdZrda65Z988omuv/56LV++XIMGDTrn9jylx8cbnejFsplMMh8/XU++B6rGYpH1+NC7aqtVPjU1qvLxke/xh8NW+vnJr7JSklQRECD/Y8ckSceaNVNAebmq/P1lrqmRtaZG5cHBana8R6wsNFSBv/wiSSoNC1PQ4cOq8fNTTUCA/IuKVNq2rQIPHJDJMFTSvr2a790rSTraubNa7NypWl9fHQsPV9DevSrt2FH+BQWyVlSoKCZGIT/9JEkqio9XyPr1svn6qqR7dwXn5qq8c2dZjh2T38GDKkpOVovsbJlranRk6FC1XLJENl9fHe3XTyHLlqmiY0fVNmumwM2bVTxkiAJzcmQtKdGRyy5T6LffyrBaVXzJJQqdO1dV7dqpsksXNV+2TCUpKfLbulW++fn65dprFTxnjmSzqfjaaxX6wQeqbtdOx5KT1WLOHJWlpspSWCj/9etVfMstCvr6a5lLS1V8550KfuMN1bZqpfLRo9Xi7bd1bMgQGX5+arZggUruuEP+CxbIum+fjk6erObTp8sIDFTZhAlqPm2aqpKTVdO9uwJnzlTZXXfJJyNDPhs2qPTxx9XsX/+SbDYde/BBBb7wgmp69VL14MFq9tJLqrj9dpnz8+Xz448qnzJF/u+8I1NxsY49/rgC0tJk69xZ1ePGyX/KFFVdd51MFot8PvpIlWlpss6ZI/P27ap8/nn5/fnPMkJDVX3HHfJ78knVXHKJjE6d5PPaa6p+/HFZli+XOTNTVS++KJ+XX5ZMJtX88Y/yeeIJ2fr1k23oUFlfflm199wj0+7dMs2fr9qnnpLlo4+k4mLVTp4sy5//LCM6WsYll8jyf/8n2/XXSzabzLNmyXj0Uembb2Tavl22xx6Tedo0KTxcxrXXyvTnP0sjR0oRETK98470xz/ah6FmZUlPPmnvOfXxsU908sIL0sCBUny89M9/SnffLW3bJi1caN/244+lkhLpwQelv/xFiomRhg2z3wt4/fX2XtQ5c6RHHpG+/VbavVv605+kl16S2raVrrpK+utf7fWEhNh7cx96yF7Phg32/f71L3vP7M0327cdNEiKjpbeeEO6804pL09atsy+7UcfSeXl0r33Sn/7mxQba6//1Vela6+1r5s3T/rDH6T//Mc+xf9DD0kvvyy1ayddfrm9tpEjpcBA6bPPpAcekFavljZtkiZPttfTrJn9+/v73+31dOkivfeefXjvli327f/4R+nTT+29x7fdZt82Lk5KTrb3XF9zjX3I74IF9hr+8x/7UOCJE6VXXpE6drT3VL/6qjR6tP0z+PJL+/e2YoW0dau9tjfftPdkjxsn/eMf0uDBUocO9s/yttvsdWdm2o/xySf2xxnceKP9GL162XvM337bXk9hof2RB/ffb6+nsNB+HsyYYa9n2DD79z96tGSx2Le5805p+XJ7z/m999rbCg62/2xnzJAuvFAKD5c+/1y65Rbpp5+kdevs3+enn0omk/1nM3261Lu31KOH9P770u9/b793dPly6Z577OdPcbH9PPjXv+yf+aBB9uONGmX/77Dvv5fuuMO+z+7d9vfvvWfvxb/kEvvnPnSoFBYmzZ5t/xw2brS/7r7bXo/FIo0daz+/EhLsowE++sh+X+v+/dKqVfZtv/7aPjz75pult96yjyBISrIfb9Qo+899wQL7ObFsmZSfL916q31969b2n+3bb9vrad5cmjtXmjDB/tls2mT/3D//3P53ccwY+zH69pU6d7afl+PHS3v32icjuuMO+8+ivNx+Xr77rr2e3r3tQ8tHj7aPZli82F7DkiX2kRA33yx98IEUEWGv49137T/jZs2kb76x17Nhg/1cu/VWadYs+3k4cqS99sRE+7k2a5b9/Nuzx/575Lbb7D+vqir7Z/nee1K3bvbz7eOP7fWUltrruOUW+5+HDtmPN3Om1KaN/Wf7/vtSaqrk52f/2d5wg320xvbt0k03SV98Yf97OmKE/RhJSfbfK3Pm2OvZvl1av95e+zff2IfRX3mlfdsePey/rz79VLrsMvtw+xUr7O0uWmQfVXL99fZ6IiOl/v3t71NTJavV/rO9/nr797trl/1c+vxz+8/y4ovttScn28/9uXPt9eTlSbm59u/5P/+xn7OXX27/GcTE2D+jWbPsn8+RI/bfIzfdZP99W1xs/zsxc6b9M09Otp+Xv/ud/WJm4UJ7PWvX2n8OEybY6wkOttf8wQfSgAH2e7L/8x/7+bNli/3v4803289nk8n+WXzwgf13Vdeu9nquuML+u2ntWvu28+fbf37jx9vr6dRJ6tPH/rMdPlyqqbF/hhMm2P++7N9v/9l98on97+KwYfZjDBpk/931n/9I111n/2x+/tn++6dtW9dc5Dmpvj0+Lgs+Y8eO1c0336wrrriifhU3kIEDB6q2tlZr1qw5ZfmJD+j111/XXXfddcZ9CwoKdOj47Gon5OXlacyYMQQfAAAAnLeqAwN14A9/UIcpUySzS6YLcFh9g4/1N7c4R1999ZWCg4ObTPApLCxU165dT1vesmXLuvVnM336dKWlpTVYbQAAAIAn8ikrU5u//MXe69m+vbvLqReXBZ+m6H+n1j7XdRMnTtT48eNPWXaixwdNk2EyyXS88/KsQ+LMZllttrpJHySpymqVb02NJKnSx0d+x4fHVfj6yr+qSsd8fRVwfBKFMn9/BVZUSJJK/P3V/Pj74oAABR87pnJfX1lra+VbW6sjgYFqefwhtYeDghR2fDa8Q82bq3VJiSp8fFRltarFsWM6GBys1sXFMkvaFxKiyKIiSdLeli3V/sgRVVosKgoMVMTRozoQHKzQsjL51dRoZ+vW6ny8Z3J7RIS6HjyoaotF+1q2VKdDh3QwJET+VVUKLi/X1shIdd2/XxbD0KaOHdVz927VmM3a1q6dovfs0eEWLVRttartkSPa0qGDOh44IP/qaq2PilJ8Xp5qzWZt7NpV8Xl5KgoK0pHgYHXNz9eWjh0VUVio4LIyZfXsqfiff5ZJUnbPnkrauFFHAwO1p21bxeblaVuHDgoqL1dEYaEy4+IUu2WLfKqrtTYhQf2ys1UeEKAtF1ygvrm52h0ZqVqLRV327FFmfLy6bd+uoLIyrUxOVr/MTFX7+mpdXJwGrl2rfW3aqCg4WDE//6ycXr0UuX+/wgoLtXzAACVlZUmS1iYl6cIVK3Q4LEx7OnRQUlaWNsTFKbi4WB327NGyCy9U7/Xr5VdZqRWDBmnwsmUqDg7Wlu7dNWjlSv0cHS3DZFKPzZu1fMgQXbB1q5ofPaqVF16o/qtWqcLfXxt79dKFS5dqR9euOtqihRKys7VmwABF5ucr4sABLR82TH3XrpVhMik7KUmD0tO1v317HWzTRkmrVik7OVnBxcXquH27VqSkKC4nR36VlVo7aJAGLlmiwrAw7YyKUv+lS/VT796y1tSo+8aNWjVsmC74+We1KCrS6mHDlLx0qcqDgrQ5Lk4D09O1PTpa5YGBisvKUsaFFypyzx613r9fq1JS1GfVKtVaLNqQnKwBixcrv1MnFUZEqPeqVVrfv79CCgvVfscOrU5JUUx2tnyqqpQ9aJD6paerMDxcezt3VuKyZdqckCBrTY26btqkjKFD1XXzZgUVFytz6FD1XbpUZS1aaFvPnkpaskQ7e/RQZUCAonNylHPhhYrcuVOtDh5URmqq4lesULWvrzb37avE9HTt69xZRa1aKW7NGuX266fQw4fVdtcuZaakKDo7W9bqam0YOFB909NV2KaNDnTsqN7Ll+vnPn3kV1GhTps3K2vYMHXZtEnNSkq0bvBg9VmyRCUhIdrZo4f6LF2qnT17qtbXVxesW6f1gwer7Y4dallQoJzUVMWuWKFqPz9t7dNHCYsXa3/XrioJCVGPtWv104ABCi0oUPju3VqXkqLuGRky22zaNGCAeqen60hkpA61b6+YFSuU17ev/EpL1X7LFm1ISVGnn36Sf2mpNg4erF7p6Spp2VL50dGKW7JEu+LiZJhM6rx+vX4aOlQRO3eqxeHD2jh0qHouX64qf3/tTEhQ3KJFOhAVpdKQEEVlZGjLwIEK3b9frfbs0caUFEWtWSOTzaYtAwcqdskSHWnfXr+0a6duK1ZoR2Ki/IuL1XbLFm266CJ12LhRvuXl2nLhheqRnq6yVq10oHt3RS9Zor29ekmGofYbNmjL0KGK2LpVQYcPa1NqqrotX66qwEDlx8cretEiHezWTVXNm6tjRobyBg1SyP79Ct27Vz+npqrL6tUyzGbt6tdP0QsX6kj79ipu105dV63SrqQk+RcXK3zbNm1JSVH77Gz5VFRo2+DB6r54sUrCw1XYtasuWLpU+fHxMtlsiszN1dZhwxTx889q9ssvyktJ0QVLl6qyeXPtj4lRt0WLdLBHD1UGBqpjZqZ2DB6skPx8tcjPV95FF6nT6tUyLBbt7ttX3Rcu1JFOnVQSEaHOq1ZpV79+CigqUti2bdqWmqp2OTmyVlZq56BBumDRIpW0aaPCTp10wbJl2peQIHNNjSJ++knbhw1T+M8/y/+XX7R92DB1WbpUlS1aqCAmRl0XL1ZBjx6q9vdXu+xs7Ro8WCF79qj5vn3alpqqjqtWyebrq/yEBF2waJGOdOmi8rAwdVi9Wnv69VOzoiK13L5d21NT1S4zU+aqKu0aOFAXLF6skrZtVdSpkzotX679x/8uhm3apF3DhiksN1f+xcXaOXSoOi9ZooqQEB2KiVHn9HQdjolRra+v2uTkaPfgwQrZsUNBBw5ox0UXqcOKFar19dW+Pn3UdfFi/dK1q46FhqrdmjXaO2CAmh0+rJCdO7UzNVVtMzNlrqnR3gED1GXRIpVERupox47qsHy59vftK59jx9Rq82btSklR640b5VtSoj2DB6vjkiWqaNlShd27q+OSJToUGyvDYlHEunXaPWSIQrZtU+ChQ9qVkqL2K1eqxt9fB3v3VufFi3UkKkqVzZsrMiNDewcMUGBBgYJ379aulBS1ycyUyWbTvn791Ck9XSXt2qk0MlLtVq7UgcRE+ZaWquWWLdo1bJha5+bKt7xcewYNUselS3WsZUsdiYpSx6VLVRAXJ5lMCt+wQXuGDFHI9u1qdviwdg8dqvYrV6q6WTMdio1Vx/R0/RIVpcoWLdQ2I0P5Awcq8MABtdizR7tTUtQ2I0OStD8pSR3T03W0fXuVtWmjditXan9SkvxKShS6dat2Dxum8A0bZD12TPkXXqgOS5boWFiYfunSRR2WLlVBfLxMhqHWubnaM3SoWm7dKv/CQu0eOlQdli9XVVBQXT1HunVTdVCQ2mRmau+gQWqen6/m+fnanZKiyDVrZDOZdCApSZ0WL1Zxx44qi4hQ+5UrlZ+cLP+iIoVu26Zdw4YpYt06WSsqtGfgQHVevFhl4eH6pXNn9Xn/fR249lp19bDQI7lwqFtTu//HmaFuZ3I+3+NjM5tlttlkO96dabbZVOXrK9/jgaA8IEDNjt83czQwUC3KylRjNqs0IEAhZWU6GBKi1kVFMkvaGRamzocPS5I2RUaq5759qvDx0c6wMPXYv19b2rZVWEmJWpaWakVMjJJ+/llWm00/JiVp+Nq1Kg4KUk7Pnhq2dq1yu3eX2WZTTF6evrvoIiXl5KjF0aP69xVX6LJvvlFp8+ZaOmyYxnz5pdb36aOjISG6MD1d344Zo+6bNqnt3r2ae+21Sp03T7VWq5aMGqVLZs3Szuho7evaVRfOm6eVl16q0EOH1GXTJi2+9lr1WbzYfrF+1VUaOGuWCjt1Un5Cgvp89ZW2XHSRfGpq1Hn1aq2//np1yMhQs8JC/fT736vnl1/qWOvW2jdokHp88YX2DxqkmsBAdVi0SNuuvlohW7eqxa5d2j5unDrOn69af38dTElRp6++0i+9eqkyIkLtvv9e+SNHyr+wUMGbN2vfFVcobPVqmWtqdCglRW2//15lXbroWKdOipg/X4VDhshSVaXg7GwduvRSBW3ZIp/iYhUNHqzQFStUFRamiqgotVy8WCV9+kg+PmqekaHilBT57d8v3wMHVDpggJrl5soICFBFVJSar1qlim7dZGveXEFr16p0wABZjx6V3969Ku/TR367dslks6kqKkr+ubmqjoiQrVUrNVu3ThW9eslcVSXfnTtVERcna0GBzBUVqunSRT47dsjWooVsrVrJd/NmVXftKpnN8t25U9Xdu8t89KgspaWqad9eloICyddXttBQ+ezZo5rwcMnXV9Zdu1TbpYtMFRUyFxfL1ratTEVFMplMMkJCZD50SLbmzWUKCJDlwAHZ2rSRqbZWpqIiGa1bS+XlMtXWSi1ayHT0qAw/P8nPT6bCQhktW8psNst09Kj9PhfDkKm62j6uvarKPp7cbLbfL+PvL0kyVVXZ10v2bX19pdpamcxmyWy2H+vE/Yc1NXXvTTabZLHIJNnHl5vN9ns+jv/9M0n2cd6SZLPJZLHY3xuGZDLJJKnul7ph2I/3v/sd37Zun+PLT/4PIZPJpBP/PJy83jCMMz6v7X/b+LX/XPrf9Sf/M2Q6qZ5z2ffX2vutdgAADigpkQIC/vtvmBu57R6fphZ87rrrLn3yySenTW7w6aef6rrrrnN4coP1kno1QL0NpdZqleV4j0aFv7/8T/RSNG+u4JISFbZooebl5fKtqdGWtm3Vff9+SdLqCy5Q/23bVGm1ak3PnhqyYYO2dOyoGh8fxWzbpu9TU5WwcaNaHjmizydM0Og5c1QaHGwPD7Nna3NioorbtVOfxYuVffXVanXggNps3ap1d96pzunpMvn4aPeoUYr6+msVx8bqWKdOart4sQ6npsqnqkot8vJUdPHFCty+XZbqah3r3VtBmzfL1rq1atu0UbMtW1R9wQUyWyzyKSiQrWtXmY8ds3+vLVvKUlkpWSwyBwTIbBgyWSwyWyx1F1Vms/mc/uTCCQAAoGlq8OAzaNAgPfXUU4qNjVX7k7q4mlrwmTdvnkaNGqVPP/1U11xzTd3ykSNHav369dq9e7csJ/6n9Byc+GDXmUyKd/Ojj070wEinzlJ2JCRELYuKtDMiQpGFhfKtqdGSHj00+OefJUlzfvc7jVmwQPsiI7V20CAN/+47rRgxQmYfH0Vv3Kjs225Th59/VrPSUu2+4Qa1X7RIVZ07q7JXL7XMzlZlnz4yt2ihZvn5Mnr2lNVkkk9trawhIbKYzbL6+MhqtcpqtcpyPGQAAAAADaHBJzdYuXKlRo0aJUlq3ry5YmJi6g509OhRVVdXy8fHp77NutzIkSM1fPhw3XvvvTp69KiioqL0ySef6LvvvtPMmTPrFXpOcWJ4SCOpsVplranR0dBQtTg+tfLW4/dlSNLCXr00as0a7ejYUeuTkjRkyRLlXnGFdgYEqN2uXaq55RZtOHhQvv7+ik5K0u7SUvlERGhIUJDk769UP7+6n1eHk44bLdmnwzxhyJD/vu/du2G/aQAAAMDF6tXj8/LLLys7O1vZ2dnavHmzao4PoaprzGSSj4+PYmNjlZSUpMTERCUlJalXr15uCUOlpaV64okn9Pnnn+vIkSPq0aOHHnvsMV177bX1butEosyxWNT7+I3xrnTyDfmlISEKKipSaUCACoOC1OnQIaX37q3I4mK1PXRIX0yapIRt22SJjFTp2LFqdfiw/KKjFdSqlYKCguR//B4DAAAAwFs16FC3k1VWVmr9+vV1QSgrK0sbNmxQxfF7SKT/3ljq4+Oj+Pj40yYa8CQnPthsq1UJ/xP4HFVrschyPEQVtmmjVgcOSJL+nZysK9euVXZioraMHq34XbtUds01Co6KUquQEAW3bOl4jxUAAADgBRrtOT5+fn5KTk5WcnJy3TKbzaZNmzbVBaHs7Gzl5OSouLhYmZmZjh7Kq5zcs/NL27YK27tXkvRDjx4a6Oenkq5dFfDoo9ocFKSO3bsroVUr7pUBAAAAnOTSeejMZrNiY2MVGxurCRMm1C3fsWOHsrOzXXkotzGcDCGVQUGyVlbKp6pKG1q0kLV/f7WprVW7xx6TuUcPxbRrp1705gAAAAAu1SgTcHfp0kVdunRpjEM1OEeDT5W/v3wrKlTm46NVUVG6cMcOVV93ndqMHavOUVHq1gQmhAAAAAC8lfufPORpHAw+B9u1U4dt21QYEqLiP/5RRwYM0PCuXRnGBgAAADQCgk891afH58RU1JL0Tp8+SunZUyG3365rLrvslIeqAgAAAGhYXH3XU32Cz9HWrdVy/35VWa3qPGKEelxxhSIiIhqwOgAAAABnQvCpp/rM/b26Tx8FtWola0qKxl53nYKCghqsLgAAAABnR/Cpr3r0+OyqrVXzRx/VVVddpWbNmjVgUQAAAAB+jdmVjV188cW64IILXNlk0/MbwefYSb06kT16aPTo0YQeAAAAwM1c2uOTn5+vnTt3urLJJscw/3pW3BcdrdqCAvlZLIq5806FhIQ0TmEAAAAAzsqlPT7ng9+a3KDMbNarV16pTTNmKCo2tpGqAgAAAPBrCD719FuTGxwpL1f37t01aNCgRqkHAAAAwG8j+LiYzc9Pffr0UYsWLdxdCgAAAIDjmNWtnn5rqFtAaKhievVqpGoAAAAAnAt6fFyksE0bSZL/4MEKDg52czUAAAAATkaPTz2ZjDPf5fP6TTcppKhIo26+uZErAgAAAPBb6PFxkb0lJVLv3mrfoYO7SwEAAADwPwg+9fRrd/h0795dViudaAAAAEBTQ/Cpp7MNdWvVqpW6dOnSyNUAAAAAOBcEn3oy2WxnXB4SEqL27ds3cjUAAAAAzgXBx0XatWsnPz8/d5cBAAAA4AxcekPK7373O/Xo0cOVTTY9Zxnq1ub4dNYAAAAAmh6XBp9//vOfrmyuaTpL8AkPD2/kQgAAAACcK68c6rZw4ULddttt6tGjhwIDA9WuXTtdeeWVyszMdLrts83qFhER4XTbAAAAABqGVwafGTNmaOfOnXrooYf07bff6h//+IcKCgo0YMAALVy4sEGOGRoa2iDtAgAAAHCeVz505rXXXjtt6Nmll16qqKgovfjii7roooscbvvk6ax3JCTId9cu7b73Xg00e2WGBAAAALyCVwafM91vExQUpJiYGO3Zs8eptk8OPlsTE/Vl//665uKLnWoTAAAAQMOqVzfF448/rtWrVzdULQ2quLhYWVlZio2Nda6hk4JPZU2NAgIC1Lx5cyerAwAAANCQ6tXjM3XqVB04cED9+/dvqHoazH333aeysjI98cQTv7ltQUGBDh06dMqyvLw8Saf2+FTW1srf318tWrRwbbEAAAAAXKrJD3VbvHixUlNTz2nb7OxsJSQknLb8qaee0kcffaRXX31ViYmJv9nO9OnTlZaWdsZ1J8/qVllTI39/f3p8AAAAgCauyQef6Ohovfnmm+e0bceOHU9blpaWpueff14vvPCC7r///nNqZ+LEiRo/fvwpy/Ly8jRmzJjThroRfAAAAICmr8kHn7Zt2+qOO+5waN+0tDRNmTJFU6ZM0eOPP37O+4WHh5/TA0mPVVerWbNmCgwMdKg+AAAAAI3Da+dgfu655zRlyhQ9+eSTeuaZZ1zWrul/enzCwsJkMp3tsaYAAAAAmoJ69/gsW7ZMaWlpSkhIUJ8+fc44vMzdpk2bpqefflqXXnqpRo8erVWrVp2yfsCAAS45js1kUnBwsEvaAgAAANBw6h18tm3bpmeffbbu65CQECUkJNQFoYSEBPXs2VMWi8WlhdbH3LlzJUnfffedvvvuu9PWGyf12tTXyT0+Zl9fZnQDAAAAPEC9g0+vXr0UExOjnJwcbd26Vb/88osWLVqkxYsX123j6+uruLi4U8JQ7969G+1emJNrcbWTg4/F15eJDQAAAAAPUO/g07dvX73zzjuSpIqKCq1fv145OTl1r/Xr16u8vFyZmZnKzMysu//FbDarurratdW7w0nBx+rnp4CAADcWAwAAAOBcODWrm7+/v/r166d+/frVLTMMQ1u2bDklDGVnZ6ugoMDpYpuCk6cxMPn4yM/Pz221AAAAADg3Lp/O2mQyKTo6WtHR0brmmmvqlntl8LFaCT4AAACAB2i06azP5bk4nsbs4yNfX193lwEAAADgN9Qr+MTExLh1tramxsxQNwAAAMAj1GuoW25urlNTQXsbs68vwQcAAADwAPUKPnfccYf69u2rPn36qHfv3mrWrFlD1eURrH5+slpdfpsUAAAAABer11X7O++8o3fffVeSfXrqbt26qU+fPnVhqE+fPgoNDW2QQpsi/0Z6LhEAAAAA59Qr+Dz88MPasGGD1q9fr/z8fG3evFmbN2/Wp59+WrdNx44d64LQiT/btm3r8sKbAv+gIHeXAAAAAOAc1Cv4TJ06te79L7/8onXr1mn9+vVat25dXU/Qrl27tGvXLs2ZM6du2/DwcPXt21fffPONa6puIvzO86F+AAAAgKdw+AaV0NBQpaSkKCUlRZL07rvvKjk5Wf/617+UkZFR98rNzdXBgwf13XffuarmJsPKxAYAAACAR3DpnfkWi6XuXp8777xTklRVVaV169YpIyPDlYdqEnzp8QEAAAA8QoNPSebr66vk5GQlJyc39KEanW9AgLtLAAAAAHAO6vUAU5yK4AMAAAB4BoKPE3wIPgAAAIBHIPg4gR4fAAAAwDPU6x6fUaNGKT4+XvHx8erdu7d69Oghi8XSULU1eX4EHwAAAMAj1Cv4fPfdd/r+++/rvvb19VWPHj0UHx8vSSovL1dpaamCzpMHe/r5+7u7BAAAAADnoF7BZ9q0acrJyVF2drY2b96syspKrVu3TuvWrZMkbdiwQSEhIYqKilJSUlLdq2/fvmrmhVM/+/EcHwAAAMAj1Cv4TJ48ue59ZWWl1q9fr+zsbGVnZysrK0sbNmxQRUWFtmzZoi1btuiTTz6RJJnNZvXo0UMbNmxwbfVu5uvr6+4SAAAAAJwDh5/j4+fnd9rzeWw2mzZt2lQXhLKzs5WTk6Pi4mL99NNPLinY3VYNH67Y+fP1S1iYgujxAQAAADyCSx9gajabFRsbq9jYWE2YMKFu+Y4dO5Sdne3KQ7nNloQEPWM2K3zoUN17Hk/sAAAAAHgSh4PPjh07NHfuXOXl5amiokKtW7dWVFSUhg8frvbt25+ybZcuXdSlSxeni20STCZtCwtTaLNmMpuZDRwAAADwBPUOPoZh6A9/+INee+011dbWnnGbQYMG6YknntCll17qdIFN1fk8jTcAAADgaerdZfHAAw/olVdeUU1NjaKjozV+/HhNmDBBo0ePVnR0tCRp+fLlGj16tG666SYdO3bM5UXX11tvvSWTyeTSabatVpeOEgQAAADQgOp19b5u3TrNmDFDoaGh+vjjjzVixIjTtjl8+LDeeOMN/f3vf9dHH32kgwcP6rvvvpPJZHJZ0fWRn5+vP/3pT4qMjFRxcbHL2qXHBwAAAPAc9erxeffddyVJM2bMOGPokaSwsDA9/vjjys7OVkJCghYsWKBnn33W+UoddM8992jo0KEaPny4S9ulxwcAAADwHPUKPitXrlTr1q01bty439y2Q4cOmjdvntq0aaOXXnpJJSUlDhfpqJkzZyo9PV3Tp093edsEHwAAAMBz1Cv4bN++XX369DnnYWvh4eFKS0vT0aNH9dlnnzlUoKMKCgo0adIkTZ069bRZ5lyB4AMAAAB4jnoFn+LiYoWFhdXrADfccIP8/PyUnp5er/2cNXHiREVHR+vee++t974FBQXauHHjKa+8vLxTtiH4AAAAAJ6jXlfvNTU18vHxqdcBAgIClJiY6PADTBcvXqzU1NRz2vbEfUWzZ8/W3LlzlZ2d7dCkCtOnT1daWtpZ15vNZp7hAwAAAHiQRum2aNu27Wk9JucqOjpab7755jlt27FjR5WWluq+++7TAw88oMjISBUVFUmSqqqqJElFRUXy8fFRYGDgWduZOHGixo8ff8qyvLw8jRkzRpJkMpmY1Q0AAADwIPUOPps3b9b333+v3r17q02bNue0T1BQUF0Aqa+2bdvqjjvuOOftd+7cqYMHD2ratGmaNm3aaetDQ0N15ZVXas6cOWdtIzw8XOHh4WddbzKZ6PEBAAAAPEi9g8/q1as1atQoSVLr1q3Vu3dvJSQk1L2io6PPGAqqq6udr/YctGnTRosWLTpt+dSpU5Wenq558+bV+z6l/0XwAQAAADxLvYLP3//+d2VnZys7O1ubN29WQUGB5s+frwULFtRt4+fnp7i4OCUkJNSFovLycpcXfjb+/v5KSUk5bfl7770ni8VyxnX1ZTabGeoGAAAAeJB6BZ9JkybVva+srNT69evrglBWVpY2bNigiooKZWRkKCMjw6GJBTwBPT4AAACAZ3F4cgM/Pz8lJycrOTm5bpnNZtOmTZvqglB2drZycnJUXFzs9hD03nvv6b333nNJWwQfAAAAwLO4dFY3s9ms2NhYxcbGasKECXXLd+zY4fB01k0R01kDAAAAnqVRprPu0qWLunTp0hiHahRMZw0AAAB4FrotHECPDwAAAOBZuHp3APf4AAAAAJ6Fq3cHMJ01AAAA4FkIPg6gxwcAAADwLFy9O4DgAwAAAHgWrt4dwOQGAAAAgGfh6t0BTGcNAAAAeBaCjwMY6gYAAAB4Fq7eHUDwAQAAADwLV+8OYDprAAAAwLMQfBxAjw8AAADgWbh6dwCzugEAAACehat3B9DjAwAAAHgWrt4dwD0+AAAAgGch+DiAHh8AAADAs3D17gCCDwAAAOBZuHp3AEPdAAAAAM9C8HEAPT4AAACAZ+Hq3QEEHwAAAMCzcPXuAJ7jAwAAAHgWrt4dYDKZuMcHAAAA8CAEHwcw1A0AAADwLF599b5s2TKNGjVKoaGhCggIULdu3fTcc8853S6zugEAAACexeruAhrKxx9/rBtvvFG///3v9cEHHygoKEjbtm3Tvn37nG6bHh8AAADAs3hl8MnPz9ddd92lu+++W9OnT69bnpqa6pL2mdwAAAAA8CxeefX+1ltvqaysTI888kiDtE+PDwAAAOBZvPLqfcmSJWrZsqU2b96shIQEWa1WhYeH65577tHRo0edbp8eHwAAAMCzeO1Qt/Lyco0fP16PPfaYXn75Za1du1bPPPOMcnNztXTpUplMprPuX1BQoEOHDp2yLC8vr+4901kDAAAAnqXJB5/Fixef87052dnZSkhIkM1mU0VFhZ555hk9+uijkqSUlBT5+vpq0qRJ+vHHH3XxxReftZ3p06crLS3trOtNJtOvBicAAAAATUuTDz7R0dF68803z2nbjh07SpJatWqlrVu36pJLLjll/ciRIzVp0iRlZWX9avCZOHGixo8ff8qyvLw8jRkzRpIIPQAAAICHafLBp23btrrjjjvqtU98fLxWrVp12nLDMCTpN+/PCQ8PV3h4+FnXc38PAAAA4Fm88gp+7NixkqR58+adsvzbb7+VJA0YMMCp9unxAQAAADxLk+/xccSIESN0+eWX69lnn5XNZtOAAQOUkZGhtLQ0XXbZZRo8eLBT7RN8AAAAAM/ilT0+kvTZZ59p0qRJeuONNzRy5EjNmDFDkydP1qxZs5xum6FuAAAAgGfxyh4fSQoICNDUqVM1depUl7dNjw8AAADgWei6cAA9PgAAAIBn4QoeAAAAgNcj+NQTw9wAAAAAz0PwqSeCDwAAAOB5CD71xP09AAAAgOfhKr6e6PEBAAAAPA/Bp54IPgAAAIDnIfjUE8EHAAAA8DwEn3oym82EHwAAAMDDWN1dgKdJTU1VUlKSu8sAAAAAUA/0+NRTWFiYAgMD3V0GAAAAgHog+AAAAADwegQfAAAAAF6P4AMAAADA6xF8AAAAAHg9gg8AAAAAr0fwAQAAAOD1CD4AAAAAvB7BBwAAAIDXI/gAAAAA8HpWdxfgKSorKyVJeXl5bq4EAAAAwInr8hPX6b+F4HOONmzYIEkaM2aMewsBAAAAUGfPnj3q27fvb25H8DlH3bt3lyR9/vnniomJcXM18BR5eXkaM2aM5syZo6ioKHeXAw/AOQNHcN7AEZw3cERTOm8qKyu1Z88eDRs27Jy2J/icoxYtWkiSYmJiFBsb6+Zq4GmioqI4b1AvnDNwBOcNHMF5A0c0lfPmXHp6TmByAwAAAABej+ADAAAAwOsRfAAAAAB4PYLPOWrdurWeeeYZtW7d2t2lwINw3qC+OGfgCM4bOILzBo7w5PPGZBiG4e4iAAAAAKAh0eMDAAAAwOsRfAAAAAB4PYIPAAAAAK9H8AEAAADg9c774FNaWqpJkyYpMjJS/v7+SkhI0KeffnpO+xYUFOiWW25RWFiYmjVrpoEDB+rHH39s4IrRFDh63nz55Ze67rrrFBUVpYCAAHXu3Fk33HCDtm7d2ghVw52c+V1zsieffFImk0lxcXENUCWaGmfPm3//+98aNmyYWrRoocDAQMXGxuqNN95owIrRFDhz3ixatEjDhw9XeHi4goKCFB8fr1deeUW1tbUNXDXcqaSkRA8//LBGjBih1q1by2QyacqUKee8v8dcExvnueHDhxshISHGv/71L2PhwoXGHXfcYUgyPvroo1/dr6KiwoiLizPat29vzJw50/jhhx+MK6+80rBarcbixYsbqXq4i6PnTb9+/YwrrrjCeOedd4zFixcbH374odGzZ08jKCjIyM3NbaTq4Q6OnjMny87ONvz8/IyIiAgjNja2AatFU+HMefPnP//ZMJvNxsSJE4158+YZCxYsMP75z38ar776aiNUDndy9LyZP3++YTabjZSUFGPOnDnG/PnzjQceeMCQZDz44IONVD3cYceOHUZwcLAxdOjQuvPlmWeeOad9Pema+LwOPt98840hyfj4449PWT58+HAjMjLSqKmpOeu+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/LxwZPuDktE3KilvVVPt2zZMrKzs1m2bBm9e/dmwoQJrFy5khUrVvDUU0+d93X6oUVEROTSuW1Iy/Lly0lKSuLPf/4zgYGBrF69GoD77ruPKVOmMGXKFHr16sXixYsZN24cdrudiRMnOsfHBgQEsGLFCqZOnYrNZmPw4MHO9zCbzaSkpDB37lyqqqqIjo52JjgudG8RkYu5Z2w8vcL8mPfyTmat3s7Pv9uPH1/b+4JD7ESk8zm9x6jFYjlvb1URERFxH5PRkp8j5KJiYmLIzs52dxgi0kYyCyu5/x/bOXSyjClDo3h02hB8PD3cHZaIW3XmujAhIYENGzYwaNAg57EJEyaQlJREUlIS69at44knnmDz5s1tEk9nLmsREZGLaWk96JYhLSIiHV1cqC//euBqvjswgrf2nOD25V9yorjK3WGJiIvNmzfP2ai6/vrr6dOnj/Pc8uXLWb58OYmJiTzyyCOsXLnSjZGKiIjImdTDw0X0S4tI12S3G/zlo1T+8lEqYf6ePHf3SK5MCHF3WCJuobqw7aisRUSkK1MPDxGRNmA2m/jZtxNZdvcIKmvr+eHfN/P8p8daNHmhiIiIiIi0HiU8RERc4IZBkbwxbxzxob786d2vmf3PHZRU1rk7LBERERGRLksJDxERF0mMCOCt+eO5ZVgU/zlwku/97TP2Zpe4OywRERERkS7JbY+lFRHpjPy8LDz9g2GM7hnC4rcOMO25L3noe1dw99h4PbpWROQiDMPAZtiosdVQXV9NTX2NY7E51nX2OuexuvrTtu111NXXUWevo9ZeS11909pm2LDZbdTZ67DZm7br7fWOfcPm3K436qmz12E37NgNO/VGfdPa7lgbGM7zjUvjMcMwaPzH8e+FhzeaMOH4t+EfU9PabDJjxty03bhgxmw242HycCxmx9pschyzmq3OYxazBQ+zB1aTFYvZgtXcsPawNm2bHdtWDyueZk+sZiueHp54ejRte3l4OY6Zm7a9PLzwtnjj5eHlXDzMelqZiLQvSniIiLiYyWTirjHxDI0J5oGXdvLQm/vZml7Ew98fjL+X/toVkY7NMAxq7bVU1FVQWVdJRV0FVbYqKusqqbQ1LA3bVbYqquqqHOvGpb6Kalt101JfTZWtyrltN+ytGr/ZZMZismAxNy3O5MBpCQSL2YK32duZSDh9bTY1JCJwbGPCmZxo/Of0RMb52LE7EyMGRlPCpGF9rsTK6cmXxoSMzW5zJmYakzqN241JHJvd1qrlCjjKzMMbb4u3c+1j8Tlr38fig6/F17ntY/HB1+rrOGb1wc/qh6/F13nMz+qHp4dnq8cvIp2PWt4iIq1kUHQQb/9kPIvW7eHtPSfYk1XMUz8Yysh4PcVFRNqPzTmbya3Ipby2nPK68qZ1w1JRW0GFraLZ2mZc/pfnxi+4jV+Ag7yCiPCNcPYW8Pbwxsvi1aznQGNvgsZeBo09DLw8vJp6JzT2SDB7OnsweHp4YjE5ejRYzBYsJkuX7YVgGEaz5Mfpa2ePmMbt+lpq7bXN1/W11NTXNFtX11c3741z2na1zZHIyq/Kb5bculwWswU/qx/+Vn98rb74Wfzw83TsNy5+nn4EWAPws/oR4BmAv6c/AZ4BBFgDnPtWs9WFpSoi7Z0SHiIirSjIx8qyu0fyz80Z/Omdr7l92SbmX9eHn0zqi9VD0yiJiPv9dddf+Sr/q3Oe87H4OL9kBnsHE22Nxs/q51gsjrWP1Qc/i5/z13hfq2/zX/CtPs2SHBre5x4mk8nZs8Vd7IbdmQipslU19QJq6CHUeKyyrqmXUGVdJeV15Y7eRLYKKuocS1F1kbN30aXwsfgQYA0g0CuQQM9AAjwDCPQMdO4HeQU510FeQQR5OtYBngFuLTsRuTz6v1ZEpJWZTCZmXJXA1b1D+ekru3nm4yN8cjifp34wjF7d/d0dnoh0cQuGL6DaVo2/Z8Mv5Q1rP6ufvuCJS5lNZkdizOrrsve02W1U1FU0651UUVdBWW0Z5bXllNWVUVZ72lJXRllNGaW1paSXplNaW9ri4T4B1gCCvIII9gomyNuxbly6eXUj2Nux7ubtWIK8gtSjRMTNTIZhXHg2JWmRmJgYsrOz3R2GiLRztTY7T314mGWfHMXb4sFD3xvAD0fH6hdP6RRUF7YdlbWIaxiGQZWtitLaUsdS41iX1JQ41yU1JRTXFFNS69guqi6ipKakRUN0AjwDCPEOIcQ7hG5e3QjxcaxDfUIJ8Q4h1Lth7RNKkFeQY04YEbmoltaDStuLiLQhT4uZX9zQnwmJ3Uleu4dfvb6Xj74+yZ+/P5iIQG93hyciItKlmEwmZ6+THn49Lum11bZqimuKKa4ppqi6qNn6VPUp5/6p6lNklGawp2bPBSfl9TB50M27G6HeoYT5hBHqE0qoTyhh3mGE+YQ5j4X5hBHoGagfS0RaQD08XES/tIjIpSqtruO3b+7n9V3HCfC28KvJVzD9SvX2kI5LdWHbUVmLdDx2w+7sIVJYXcip6lMUVjWsqws5VeVYF1YVUlhdeMH5Sbw8vAjzCaO7T3e6+3YnzCeMcN9wuvt0J9w33LHt250Aa4DaFdIptbQeVMLDRdTwEJHL9eGBk/z6jX3kllZzVa9QHv7+YBLC/NwdlsglU13YdlTWIp1fZV0lBVUFzqWwupD8ynwKqgrIr2pYV+ZzqvoUBuf+Sudj8XEmQSL8Ihxr3wh6+PZwHgv1Du2yTy+SjksJjzamhoeIfBOl1XU88t5BXt6SiZfFzP98J5F7x/XEoie5SAeiurDtqKxFpJHNbuNU9SnyK/PJq8wjvyqfk5UnHftVeeRVOpaSmpJzvt5isjiTHz18e9DDr4dj268HUX5RRPpFEuQVpJ4i0q4o4dHG1PAQEVfYfKyQX67/ivTCSgZHB/Hw9wczKDrI3WGJtIjqwrajshaRS1Vlq3ImP3IrcjlZeZKTFSfJrcx1rCtyKaopOudrfSw+9PDrQaRfpHOJ8o8i2j+aKP8ouvt0Vy8RaVNKeLQxNTxExFWq6+p5+sNUnv/sGIZhcOeYOP7n2/3o5ufp7tBELkh1YdtRWYtIa6i2VTsTIjkVOeRU5DTbzinPOefTaSwmCxF+Ec4ESLR/NNH+0cQExBDtH02YT5ieQCMu1e4THqmpqcycOZOCggKCg4NZtWoVAwYMOOu6lStX8sgjj2C325k0aRJLly7FYnE8XGbDhg0sXLgQm83G0KFDWb16Nf7+/gBs2bKFOXPmUFlZSWxsLCkpKURGRl703vfeey9ffPEFPj4+BAYG8swzzzBs2LCLfh41PETE1Q6cKOW3b+1jW3oRwb5WFn6nHz8cHYeHWV1KpX1SXdh2VNYi4g6GYVBUU0RORQ4nyk9wovwEORU5HC8/Tk65Y11eV37W6zzNnkQHRBPjH0NMQAyxAbHO7ZiAGHwsPm74NNKRtfuEx8SJE5kxYwZJSUmsW7eOJ598kk2bNjW7Ji0tjXHjxrFr1y7Cw8O55ZZbuOmmm5gzZw7l5eX07t2bTz75hP79+zN//nwCAgJ4+OGHMQyDvn37smLFCiZMmMATTzzBjh07WLNmzUXv/dZbbzF58mQsFgsbNmwgOTmZw4cPX/TzqOEhIq3BMAze2nOCP7/7NSdLaxgYFcjiKQMZlRDi7tBEzqK6sO2orEWkvSqpKeF4+XHHUnac7PJsjpcfJ7ssmxPlJ6i11571mu4+3YkNiCU2IJa4wDjHOiCO2MBYAj0D3fAppL1r1wmPvLw8EhMTKSgowGKxYBgGkZGRbN68mYSEBOd1jz/+OOnp6Tz77LMAvPvuuzz22GNs3LiR1157jVWrVvHOO+8AcODAASZPnkx6ejrbtm0jKSmJ/fv3A1BWVkZ4eDilpaUUFRW16N4ABQUFREdHU1VVhdl84S5YaniISGsqr7Hxt4+PsPLzY9TVG9w6PJqF3+1HdLB+EZH2Q3Vh21FZi0hHZDfs5FXmkV2WTXZ5NlllWWSVZXG87DiZZZkU1xSf9Zpgr2DiA+OJD4wnLiCO+KB44gMc+75W37b/ENIutLQetLRBLGfJysoiKirKOTTFZDIRFxdHZmZms6RDZmYm8fHxzv2EhAQyMzPPe+748ePY7fazzgUEBBAQEEBOTg75+fktujfAX/7yFyZPnnzRZIeISGvz97Lwyxv7c8eoGH6/4QCv7zrOO3tzmHlVPA9M6KP5PURERKTdM5vM9PBzPAlmFKPOOl9SU0J2WTaZZZlklWWRUZpBZmkmmWWZ7Mnfc9b14T7hJAQlkBCY0Gwd5RelSVQFcFPCAzjrsUbn62hy+nVnXnOhRyNd6P1bcu+UlBTWrl3LZ599ds73X7JkCUuWLHHul5efPVZNRMTVenX358WkK/k0tYBH3zvI85+l8crWLOZc24t7x/fE19Ntf62LiIiIfCNBXkEEeQUxMGzgWedKa0vJKs0ivTSdzNJM0kvTySjNYF/BPrbmbm12rafZk/igeHoG9qRXcC96BfWiZ1BPEgIT8LZ4t9XHkXbALS3j2NhYsrOzsdlszmElWVlZxMXFNbsuLi6O9PR0535GRobzmri4OD7++GPnufT0dKKjozGbzWe9rqysjLKyMiIjI/H29r7ovV999VUWL17MRx99RHh4+Dk/Q3JyMsnJyc79mJiYb1IkIiItZjKZuDaxO9/qE8bbX53gyQ8O88QHh1m9KYMFk/oy/cpYrB7qmSYiIiKdR6BnIAPDBp6VDDEMg/yqfNJL0kkvTSetJM25/k/GfzAyTvvhGxNR/lH0Du7tWIIc615BvTQ8ppNyS8IjPDyc4cOHk5KSQlJSEuvXrychIeGsISXTpk1j/Pjx/OY3vyE8PJxly5Yxffp0AG644QbmzZvHwYMH6d+/P0uXLnWeGzlyJNXV1WzcuJEJEyawfPlypk6ditVqvei9165dy69//Ws+/PDDsxIwIiLtidls4pZh0dw4KJJXtmXyzEepPPTGPp7/9Bhzr+3NtJHReFnUnVNEREQ6L5PJRLhvOOG+4YyOHN3sXJWtiozSDNJK0kgrSeNYyTGOFh/lyxNf8mn2p82ujfJzJEL6dutLn+A+9O3Wl55BPfHy8GrLjyMu5rantBw6dIikpCQKCwsJDAxk9erVDBw4kPvuu48pU6YwZcoUAJ5//nkeffRR7HY7EydO5LnnnsNqtQKOJ6osWrQIm83G4MGDWb16NYGBjll8N23axNy5c6mqqiI6OpqUlBSio6MveG8Aq9VKjx49CA0Ndcb60UcfNds/F00eJiLuVlFj44XP01jxeRolVXX0CPRm9jW9+OHoOHw8lfiQ1qe68MKKiopYuHAhH3zwAVlZWQCcOHGCH//4x0RERFBcXMyLL76In5/fRd9LZS0icvlsdhtZZVkcLT7qWEqOcqT4COkl6dTZ65zXmU1m4gLi6NutL3279SWxWyKJ3RKJ9o/GbFJvWndq109p6YzU8BCR9qK8xsZLmzN4/rM0CsprCPXzZNa3enLP2HgCvK3uDk86sc5YFy5YsIC33nqLjIwM9u7dy6BBg5znUlNTmTlzJgUFBQQHB7Nq1SoGDBhw0fe8/vrr+fDDDwH4z3/+w969e0lOTuZnP/sZP/rRjxgyZMhF36MzlrWIiLvV2evIKs0itTiVI8VHOFJ0hCPFR8gsy8Ru2J3X+Vp8nQmQft360S+kH4ndEjUspg0p4dHG1PAQkfamuq6eV7dlsfyTo5woqSbQ28JdY+O5Z2w8UXqcrbSCzlgXfvrpp/Tq1Yvx48ezYcOGZgmPiRMnMmPGDJKSkli3bh1PPvkkmzZtIjc31znMttGwYcN4+umngeYJj+LiYqZPn46npyfe3t6sWbMGD4+L98jqjGUtItJeVdmqOFZ8jMNFh53LoaJDlNSUOK8xYSI+MJ5+If3oH9LfuYT5hLkx8s5LCY82poaHiLRXtTY7r+/KZtknx0grqMDDbOK7AyNIuronVyZ0u+ATr0QuRWeuCxMSEpolPPLy8khMTKSgoMA5CXpkZCSbN28+a06yM52e8FiyZAm9evVi6tSpLFmyhN69e3PLLbdcNJ7OXNYiIh2BYRjkVeY5kx8HTx3k4KmDZJZmYtD0FTvcJ5wBoQO4IvQKrgi5ggGhAwj3DVf76xtqaT2o5xeKiHRynhYzP7gyjttHxvJJaj6rvkjn3b25vLs3l4FRgSRdncDNQ6PwtmqeD5GWysrKIioqCovF0ZQymUzExcWRmZl5wYTH3LlzOXjwIHPnzuXnP/85kydP5le/+hX/+c9/OH78OHfeeec5X7dkyRKWLFni3C8vL3fp5xERkUtjMpmI8Isgwi+Cb8V8y3m8oq6C1KJUvj71NQdPHeTrwq/5/PjnbMze6LwmxDuEgaEDGRQ2iEFhgxgYOpBQnwvPGSmXRz08XES/tIhIR3I0v5zVX6azbkc2lbX1dPO1cuvwGO64Mob+PQLdHZ50UJ25Ljyzh8eOHTuYMWMG+/fvd15z5ZVX8uSTT3LNNde0ejyduaxFRDqb2vpaUotT+brwaw4UHuBA4QEOFR3CZrc5r4n0i3QmQIaEDWFA6ADNCXIB6uEhIiLn1bu7P7+/ZRALv9uPtduyeHlrJi98kcYLX6QxJCaI20fGMGVoNEG+muRU5FxiY2PJzs7GZrM5h7RkZWXpkfYiInIWTw9PBoYOZGDoQOex2vpaDhcdZl/BPvYV7GN/4X4+zPiQ/2T8BwAPkwd9u/VlSNgQhnR3LPGB8Xo6zCVSDw8X0S8tItKRGYbBzsxiXtuexdt7TlBRW4+nxcwNA3tw64hoxvcJw+qhClYurDPXhWf28ACYMGECSUlJzklLn3jiCTZv3twm8XTmshYR6aoq6yrZX7ifr/K/ciwFX1FQVeA8H+QVxLDuwxgWPoxh3YcxKGwQ3hZvN0bsPpq0tI2p4SEinUVlrY139+aydnsWW9NOARDsa+W7A3pw05BIru4dikXJDzmHzlgXzps3jzfffJPc3FzCwsLw9/fnyJEjABw6dIikpCQKCwsJDAxk9erVDBw48CLv6BqdsaxFRKQ5wzDIrchlT8Eevsr/ij15ezhw6oBzKIzFbGFAyACGhQ9jZMRIRkaMJMgryM1Rtw0lPNqYGh4i0hllFFaw4ascNnyVw9c5pQB087Vyw6BIbhocyZheIer5IU6qC9uOylpEpGuqtlWzr2Afu/N3sytvF7vzdlNa62ijmTDRt1tfRkWMciZAOutkqEp4tDE1PESkszuaX847X+Xwzlc5HDpZBkCAt4VrErszsV84E/p1J9Tfy81RijupLmw7KmsREQGwG3aOFR9jx8kdbD+5ne0ntzcbBtM7qDdjIscwJnIMV/a4kgDPADdG6zpKeLQxNTxEpCtJPVnGe/ty+fhgHnuyizEMMJlgWGxwQ/IjnAFRgXiY9Yz5rkR1YdtRWYuIyLkYhkFGaYYz+bEtZxt5VXkAmE1mBoUNYkyPMVwVdRVDuw/F08PTzRFfHiU82pgaHiLSVRWU17DxUD7/PZjHp4fzKatxjCsN8rEypmcIV/UO5ereYSRG+GMyKQHSmakubDsqaxERaQnDMEgrTWNLzhY2n9jMttxtlNU5eur6WHwYEzmGb0V/i/HR44nyj3JztC2nhEcbU8NDRATq6u1sSz/F56kFfHm0kL3HS6i3O6qZUD9PxvYO5cr4bgyP68YVkYF4WjT/R2eiurDtqKxFRORy2Ow2vi78ms05m/nixBfszttNvVEPOIa/fCvGkfwYET4Cq4fVzdGenxIebUwNDxGRs5VV17Et/RRfHilk07FCDuSU0ljreFnMDI4OYkR8N4bHBjM8rhsRgV7qBdKBqS5sOyprERFxhdLaUjaf2Mxnxz/j8+OfO+f/CPAMYELMBCbFT+LqqKvxsfi4OdLmlPBoY2p4iIhcXEllHbuyitiZWcyuzCJ2ZxVTVm1zng/182RAVKBjiQxkYFQgPcP8NRdIB6G6sO2orEVExNXshp1Dpw7x2fHP+DjzY/YX7gccQ1/GR49nUtwkrom5pl1MfKqERxtTw0NE5NLZ7QZH88vZmVnE7qwSDuSUcjCnlBqb3XmNt9VM3/AA+oT70yfcn97dHev4UF89EredUV3YdlTWIiLS2k6Un+DjzI/5MPNDdp7ciYGBxWzh2phrubn3zVwTfY3bhr0o4dHG1PAQEXENW72d9MIK9p8o5cCJUvafKOXwyTLyymqaXWf1MBEf6kdCqC9xIX7EhfgQH+pHbIgvsSE+eFk83PQJui7VhW1HZS0iIm2poKqAjVkb+Xf6v9mSswUDg2CvYG7seSNTek9hYOjANh2W3O4THqmpqcycOZOCggKCg4NZtWoVAwYMOOu6lStX8sgjj2C325k0aRJLly7FYrEAsGHDBhYuXIjNZmPo0KGsXr0af39/ALZs2cKcOXOorKwkNjaWlJQUIiMjL3rvvLw8ZsyYwdGjR/Hy8mLZsmWMHz/+op9HDQ8RkdZVUlXH0fxyjuaVc6RhfTS/guyiSurqm1dlJhNEBHgTGexNZJA3kUE+TetgbyICvQnz91RSxMVUF7YdlbWIiLhLbkUu7xx7h7eOvsWxkmMA9AzqyS29b+G2xNsI8gpq9RjafcJj4sSJzJgxg6SkJNatW8eTTz7Jpk2bml2TlpbGuHHj2LVrF+Hh4dxyyy3cdNNNzJkzh/Lycnr37s0nn3xC//79mT9/PgEBATz88MMYhkHfvn1ZsWIFEyZM4IknnmDHjh2sWbPmove+9957iYuL43e/+x3btm3jtttu4+jRo84ky/mo4SEi4h71doOckioyCyvJOFVJ5qlKMgsryS6q5ERJNQXlNZyvpgv0ttA9wKthcSRBQnw9CfbzpJuv1bHt60mInydBPla8rWZNqnoBqgvbjspaRETczTAMDpw6wFtH3uLdtHcprinGx+LD9/t+n7uvuJuYgJhWu3e7Tnjk5eWRmJhIQUEBFosFwzCIjIxk8+bNJCQkOK97/PHHSU9P59lnnwXg3Xff5bHHHmPjxo289tprrFq1infeeQeAAwcOMHnyZNLT09m2bRtJSUns3++YZKWsrIzw8HBKS0spKiq64L39/f1JS0uje/fuAIwePZrHHnuMCRMmXPAzqeEhItI+1drsnCytJqekmpySKk4UV5NfVkN+eQ0FDev8shpKquou+l5WDxOB3lYCfawEeFsati34eVrw87Lg5+XhWDfue3rg7emBj7Vhadj2tnrgZTXjZTHj6dF5kiiqC9uOylpERNqTuvo6Psj4gFX7V3Hw1EHMJjPfjv82SQOTGBQ2yOX3a2k9eOFuC60kKyuLqKgoZ68Jk8lEXFwcmZmZzRIemZmZxMfHO/cTEhLIzMw877njx49jt9vPOhcQEEBAQAA5OTnk5+ef994BAQHY7XZnsuPMe4qISMfjaTE3zOvhe8Hramz1FJbXUlRZS3FlHacqaimurOVURR1FlbWUVtVRWl1HaZWN0uo6CstrScuvoKzGdsH3bQkvixlPixkvi4dz2+phwuphxurhSIpYLSYsZsdxD7MJi4cZi9lxzGI24eFhwsPkONdsMZkwmxz1nYe5+XZciC+TB0d+4/hFRESka7N6WLmp101M7jmZLblbWLV/Ff9O/zf/Tv83IyNGkjQwiWtirsFsatsJ592S8ADO+jXrfB1NTr/uzGsu9IvYhd7/cs+dbsmSJSxZssS5X15eft5YRESk/fOyeBAV7ENU8KU9Z77eblBZa6Oytp7yGhsVNTbKa2xU1tRTUWujuq6eqtp6qursVNXVO/drbPXU2OzU2uzU2OyO/TrHdl29Y6muszm36+oN6urt2OwGtno7dhf0z7w2sbsSHiIiIuIyJpOJsZFjGRs5lsNFh/nH/n/wTto7PL3jaa6NubbN43FLwiM2Npbs7GxsNptzWElWVhZxcXHNrouLiyM9Pd25n5GR4bwmLi6Ojz/+2HkuPT2d6OhozGbzWa8rKyujrKyMyMhIvL29z3vv0NBQAPLz8529PE6/5+mSk5NJTk527sfEtN74JBERab88zCYCvK0EeFuJaMP72u2GI/lhdyRD7HaDesNwHq+3G9gNx7ZhGNgNnMeMhm0/L7f97iEiIiKdXGK3RP44/o8sGLGAvMo8twzhbdv+JA3Cw8MZPnw4KSkpAKxfv56EhIRmw1kApk2bxuuvv87JkycxDINly5Yxffp0AG644Qa2bdvGwYMHAVi6dKnz3MiRI6murmbjxo0ALF++nKlTp2K1Wi9679tvv905Z8i2bdvIzc1t0VNaRERE2pLZbMLTYsbX00KQj5Vufp6E+XsRHuhNVLAPsSG+xIf60bu7P33CA0iMCOCKyEAGRgUxKDqIobHB9An3d/fHEBERkU4u3De8VebxaAm3PaXl0KFDJCUlUVhYSGBgIKtXr2bgwIHcd999TJkyhSlTpgDw/PPP8+ijj2K325k4cSLPPfccVqsVgLfeeotFixZhs9kYPHgwq1evJjAwEIBNmzYxd+5cqqqqiI6OJiUlhejo6AveG+DkyZPcc889pKWl4enpydKlS7n22ot3vdHkYSIi0tWpLmw7KmsREenK2vVTWjojNTxERKSrU13YdlTWIiLSlbW0HnTLkBYRERERERERkdakhIeIiIiIiIiIdDpKeIiIiIiIiIhIp6OEh4iIiIiIiIh0Opq01EW8vLzo3r27S9+zvLwcf389MtAVVJaupfJ0HZWl66gsXedyyzI/P5+amppWiEjO5Op2h/7/cT2VqWupPF1PZep6KlPXulB5trTNoYRHO6YZ2F1HZelaKk/XUVm6jsrSdVSWXY/+m7ueytS1VJ6upzJ1PZWpa7miPDWkRUREREREREQ6HSU8RERERERERKTTUcKjHUtOTnZ3CJ2GytK1VJ6uo7J0HZWl66gsux79N3c9lalrqTxdT2XqeipT13JFeWoODxERERERERHpdNTDQ0REREREREQ6HSU8RERERERERKTTUcLDzVJTU7n66qtJTExk9OjRHDhw4JzXrVy5kr59+9K7d29mz56NzWZr40jbv5aU5ccff8yYMWMYMGAAgwYN4v/+7//QqK6ztfTPJUB1dTUDBgxg1KhRbRhhx9LS8ty7dy8TJkzgiiuuoF+/fvzrX/9q40jbv5aUpWEY/PznP2fgwIEMGTKE6667jiNHjrgh2vZtwYIFJCQkYDKZ2Ldv33mvU/3TeajN4Xpqe7iW2h+upzaI66kt4lqt3h4xxK2uu+4648UXXzQMwzBee+01Y+zYsWddc+zYMSMyMtLIzc017Ha7cfPNNxvLli1r40jbv5aU5c6dO42jR48ahmEYVVVVxrhx44yXXnqpLcPsEFpSlo2Sk5ONe++91xg5cmQbRdfxtKQ8KyoqjF69ehmfffaZYRiGUVdXZ+Tl5bVlmB1CS8ryjTfeMEaPHm3U1tYahmEYf/jDH4zbb7+9LcPsED755BMjKyvLiI+PN/bu3XvOa1T/dC5qc7ie2h6upfaH66kN4npqi7hWa7dHlPBwo5MnTxpBQUFGXV2dYRiGYbfbjYiICCMtLa3ZdY899pjxwAMPOPffeecd49prr23DSNu/lpblmebNm2f84Q9/aIMIO45LKctPP/3UuPnmm43//ve/anCcR0vL8/nnnzfuuusuN0TYcbS0LN944w1j6NChRmlpqWG3242f//znxs9+9jM3RNwxXKiBofqn81Cbw/XU9nAttT9cT20Q11NbpPW0VntEQ1rcKCsri6ioKCwWCwAmk4m4uDgyMzObXZeZmUl8fLxzPyEh4axrurqWluXpcnNzWbduHZMnT26rMDuElpZlRUUFDz74IM8995w7wuwwWlqeBw4cwNvbm+9973sMGzaMGTNmkJ+f746Q262WluXNN9/MddddR48ePYiMjOSjjz7i97//vTtC7vBU/3QeanO4ntoerqX2h+upDeJ6aou4xzepm5TwcDOTydRs3zjPmM7TrzvfNV1dS8sSoLS0lJtvvplFixYxYsSI1g6tw2lJWf785z9n3rx5REdHt1VYHVZLyrOuro5///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/somedocs/propagatorDHT.slides.html b/somedocs/propagatorDHT.slides.html deleted file mode 100644 index b4baf32..0000000 --- a/somedocs/propagatorDHT.slides.html +++ /dev/null @@ -1,15135 +0,0 @@ - - - - - - - - - -propagatorDHT slides - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - - - - - - - - diff --git a/somedocs/slides_axibeam.ipynb b/somedocs/slides_axibeam.ipynb deleted file mode 100644 index 211751e..0000000 --- a/somedocs/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/somedocs/slides_axibeam.slides.html b/somedocs/slides_axibeam.slides.html deleted file mode 100644 index a9d9701..0000000 --- a/somedocs/slides_axibeam.slides.html +++ /dev/null @@ -1,25380 +0,0 @@ - - - - - - - - - -slides_axibeam slides - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-
-
-
-
-
-
- - - - - - - - - - -