From 168794fdbfeefcae74bf9f82fab6ede62421604c Mon Sep 17 00:00:00 2001 From: Andy Maloney Date: Mon, 29 Aug 2022 12:17:37 -0500 Subject: [PATCH 1/7] Add diagnostic visualization tools This commit adds the feature to run diagnostic tools using ArviZ and Bokeh in a Jupyter environment. - Added a `tools` sub-package in the `diagnostics` package. This new sub-package adds the following files, each for a specific tool that runs ArviZ model diagnostics. - autocorrelation - effective_sample_size - marginal1d - marginal2d - trace - The listed tools above also have two corresponding files, one for types and the other for methods used in the tool. Resolves #1490 --- src/beanmachine/ppl/__init__.py | 1 + .../ppl/diagnostics/tools/__init__.py | 0 .../ppl/diagnostics/tools/accessor.py | 75 + .../ppl/diagnostics/tools/autocorrelation.py | 96 + .../tools/effective_sample_size.py | 87 + .../ppl/diagnostics/tools/helpers/__init__.py | 0 .../tools/helpers/autocorrelation.py | 450 +++ .../tools/helpers/effective_sample_size.py | 527 ++++ .../diagnostics/tools/helpers/marginal1d.py | 635 ++++ .../diagnostics/tools/helpers/marginal2d.py | 1000 ++++++ .../ppl/diagnostics/tools/helpers/plotting.py | 122 + .../ppl/diagnostics/tools/helpers/trace.py | 816 +++++ .../ppl/diagnostics/tools/marginal1d.py | 133 + .../ppl/diagnostics/tools/marginal2d.py | 217 ++ .../ppl/diagnostics/tools/trace.py | 136 + .../ppl/diagnostics/tools/typing/__init__.py | 0 .../tools/typing/autocorrelation.py | 78 + .../tools/typing/effective_sample_size.py | 147 + .../diagnostics/tools/typing/marginal1d.py | 157 + .../diagnostics/tools/typing/marginal2d.py | 304 ++ .../ppl/diagnostics/tools/typing/trace.py | 233 ++ src/beanmachine/ppl/diagnostics/tools/viz.py | 47 + tutorials/Coin_flipping.ipynb | 2727 +++++++++++++++-- 23 files changed, 7803 insertions(+), 185 deletions(-) create mode 100644 src/beanmachine/ppl/diagnostics/tools/__init__.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/accessor.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/autocorrelation.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/effective_sample_size.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/helpers/__init__.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/helpers/autocorrelation.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/helpers/effective_sample_size.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/helpers/marginal1d.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/helpers/plotting.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/helpers/trace.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/marginal1d.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/marginal2d.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/trace.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/typing/__init__.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/typing/autocorrelation.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/typing/effective_sample_size.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/typing/marginal1d.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/typing/marginal2d.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/typing/trace.py create mode 100644 src/beanmachine/ppl/diagnostics/tools/viz.py diff --git a/src/beanmachine/ppl/__init__.py b/src/beanmachine/ppl/__init__.py index 739973024c..542377c5ac 100644 --- a/src/beanmachine/ppl/__init__.py +++ b/src/beanmachine/ppl/__init__.py @@ -3,6 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. +from beanmachine.ppl.diagnostics.tools import viz from torch.distributions import Distribution from . import experimental diff --git a/src/beanmachine/ppl/diagnostics/tools/__init__.py b/src/beanmachine/ppl/diagnostics/tools/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/beanmachine/ppl/diagnostics/tools/accessor.py b/src/beanmachine/ppl/diagnostics/tools/accessor.py new file mode 100644 index 0000000000..309140c692 --- /dev/null +++ b/src/beanmachine/ppl/diagnostics/tools/accessor.py @@ -0,0 +1,75 @@ +"""Accessor definition for extending Bean Machine `MonteCarloSamples` objects.""" +from __future__ import annotations + +import contextlib +import warnings +from typing import Callable, TypeVar + +from beanmachine.ppl.inference.monte_carlo_samples import MonteCarloSamples + + +T = TypeVar("T", bound="CachedAccessor") + + +class CachedAccessor: + """A descriptor for caching accessors. + + Parameters + ---------- + name : str + Namespace that will be accessed under, e.g. ``samples.accessor_name``. + accessor : cls + Class with the extension methods. + """ + + def __init__(self: T, name: str, accessor: object) -> None: + """Initialize.""" + self._name = name + self._accessor = accessor + + def __get__(self: T, obj: object, cls: object) -> object: + """Access the accessor object.""" + if obj is None: + return self._accessor + + try: + cache = obj._cache # type: ignore + except AttributeError: + cache = obj._cache = {} + + try: + return cache[self._name] + except KeyError: + contextlib.suppress(KeyError) + + try: + accessor_obj = self._accessor(obj) # type: ignore + except Exception as error: + msg = f"error initializing {self._name!r} accessor." + raise RuntimeError(msg) from error + + cache[self._name] = accessor_obj + return accessor_obj # noqa: R504 + + +def _register_accessor(name: str, cls: object) -> Callable: + """Register the accessor to the object.""" + + def decorator(accessor: object) -> object: + if hasattr(cls, name): + warnings.warn( + f"registration of accessor {repr(accessor)} under name " + f"{repr(name)} for type {repr(cls)} is overriding a preexisting " + f"attribute with the same name.", + UserWarning, + stacklevel=2, + ) + setattr(cls, name, CachedAccessor(name, accessor)) + return accessor + + return decorator + + +def register_mcs_accessor(name: str) -> Callable: + """Register the accessor to object.""" + return _register_accessor(name, MonteCarloSamples) diff --git a/src/beanmachine/ppl/diagnostics/tools/autocorrelation.py b/src/beanmachine/ppl/diagnostics/tools/autocorrelation.py new file mode 100644 index 0000000000..62961cf77f --- /dev/null +++ b/src/beanmachine/ppl/diagnostics/tools/autocorrelation.py @@ -0,0 +1,96 @@ +"""Autocorrelation diagnostic tool for a Bean Machine model.""" +from __future__ import annotations + +from typing import Any, TypeVar + +import arviz as az + +import beanmachine.ppl.diagnostics.tools.helpers.autocorrelation as tool +from bokeh.models.callbacks import CustomJS +from bokeh.plotting import show + +T = TypeVar("T", bound="Autocorrelation") + + +class Autocorrelation: + """Autocorrelation diagnostic tool.""" + + def __init__(self: T, idata: az.InferenceData) -> None: + """Initialize.""" + self.idata = idata + self.rv_identifiers = list(self.idata["posterior"].data_vars) + self.rv_names = sorted( + [str(rv_identifier) for rv_identifier in self.rv_identifiers], + ) + self.num_chains = self.idata["posterior"].dims["chain"] + self.num_draws = self.idata["posterior"].dims["draw"] + + def modify_doc(self: T, doc: Any) -> None: + """Modify the Jupyter document in order to display the tool.""" + # Initialize the widgets. + rv_name = self.rv_names[0] + rv_identifier = self.rv_identifiers[self.rv_names.index(rv_name)] + + # Compute the initial data displayed in the tool. + rv_data = self.idata["posterior"][rv_identifier].values + computed_data = tool.compute_data(rv_data) + + # Create the Bokeh source(s). + sources = tool.create_sources(computed_data) + + # Create the figure(s). + figures = tool.create_figures(self.num_chains) + + # Create the glyph(s) and attach them to the figure(s). + glyphs = tool.create_glyphs(self.num_chains) + tool.add_glyphs(figures, glyphs, sources) + + # Create the annotation(s) and attache them to the figure(s). + annotations = tool.create_annotations(computed_data) + tool.add_annotations(figures, annotations) + + # Create the tool tip(s) and attach them to the figure(s). + tooltips = tool.create_tooltips(figures) + tool.add_tooltips(figures, tooltips) + + # Create the widget(s) for the tool. + widgets = tool.create_widgets(rv_name, self.rv_names, self.num_draws) + + # Create the callback(s) for the widget(s). + def update_rv_select(attr: Any, old: str, new: str) -> None: + rv_name = new + rv_identifier = self.rv_identifiers[self.rv_names.index(rv_name)] + rv_data = self.idata["posterior"][rv_identifier].values + tool.update(rv_data, sources) + end = 10 if self.num_draws <= 2 * 100 else 100 + widgets["range_slider"].value = (0, end) + + def update_range_slider( + attr: Any, + old: tuple[int, int], + new: tuple[int, int], + ) -> None: + fig = figures[list(figures.keys())[0]] + fig.x_range.start, fig.x_range.end = new + + widgets["rv_select"].on_change("value", update_rv_select) + # NOTE: We are using Bokeh's CustomJS model in order to reset the ranges of the + # figures. + widgets["rv_select"].js_on_change( + "value", + CustomJS(args={"p": list(figures.values())[0]}, code="p.reset.emit()"), + ) + widgets["range_slider"].on_change("value", update_range_slider) + + tool_view = tool.create_view(widgets, figures) + doc.add_root(tool_view) + + def show_tool(self: T) -> None: + """Show the diagnostic tool. + + Returns + ------- + None + Directly displays the tool in Jupyter. + """ + show(self.modify_doc) diff --git a/src/beanmachine/ppl/diagnostics/tools/effective_sample_size.py b/src/beanmachine/ppl/diagnostics/tools/effective_sample_size.py new file mode 100644 index 0000000000..48f1a0bdf4 --- /dev/null +++ b/src/beanmachine/ppl/diagnostics/tools/effective_sample_size.py @@ -0,0 +1,87 @@ +"""Effective Sample Size (ESS) diagnostic tool for a Bean Machine model.""" +from __future__ import annotations + +from typing import Any, TypeVar + +import arviz as az + +import beanmachine.ppl.diagnostics.tools.helpers.effective_sample_size as tool +from bokeh.core.enums import LegendClickPolicy +from bokeh.models.callbacks import CustomJS +from bokeh.plotting import show + + +T = TypeVar("T", bound="EffectiveSampleSize") + + +class EffectiveSampleSize: + """Effective Sample Size (ESS) diagnostic tool.""" + + def __init__(self: T, idata: az.InferenceData) -> None: + """Initialize.""" + self.idata = idata + self.rv_identifiers = list(self.idata["posterior"].data_vars) + self.rv_names = sorted( + [str(rv_identifier) for rv_identifier in self.rv_identifiers], + ) + self.num_chains = self.idata["posterior"].dims["chain"] + + def modify_doc(self: T, doc: Any) -> None: + """Modify the Jupyter document in order to display the tool.""" + # Initialize the widgets. + rv_name = self.rv_names[0] + rv_identifier = self.rv_identifiers[self.rv_names.index(rv_name)] + + # Compute the initial data displayed in the tool. + rv_data = self.idata["posterior"][rv_identifier].values + computed_data = tool.compute_data(rv_data) + + # Create the Bokeh source(s). + sources = tool.create_sources(computed_data) + + # Create the figure(s). + figures = tool.create_figures() + + # Create the glyph(s) and attach them to the figure(s). + glyphs = tool.create_glyphs() + tool.add_glyphs(figures, glyphs, sources) + + # Create the annotation(s) and attache them to the figure(s). + annotations = tool.create_annotations(figures) + annotations["ess"]["legend"].click_policy = LegendClickPolicy.hide + tool.add_annotations(figures, annotations) + + # Create the tool tip(s) and attach them to the figure(s). + tooltips = tool.create_tooltips(figures) + tool.add_tooltips(figures, tooltips) + + # Create the widget(s) for the tool. + widgets = tool.create_widgets(rv_name, self.rv_names) + + # Create the callback(s) for the widget(s). + def update_rv_select(attr: Any, old: str, new: str) -> None: + rv_name = new + rv_identifier = self.rv_identifiers[self.rv_names.index(rv_name)] + rv_data = self.idata["posterior"][rv_identifier].values + tool.update(rv_data, sources) + + widgets["rv_select"].on_change("value", update_rv_select) + # NOTE: We are using Bokeh's CustomJS model in order to reset the ranges of the + # figures. + widgets["rv_select"].js_on_change( + "value", + CustomJS(args={"p": list(figures.values())[0]}, code="p.reset.emit()"), + ) + + tool_view = tool.create_view(widgets, figures) + doc.add_root(tool_view) + + def show_tool(self: T) -> None: + """Show the diagnostic tool. + + Returns + ------- + None + Directly displays the tool in Jupyter. + """ + show(self.modify_doc) diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/__init__.py b/src/beanmachine/ppl/diagnostics/tools/helpers/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/autocorrelation.py b/src/beanmachine/ppl/diagnostics/tools/helpers/autocorrelation.py new file mode 100644 index 0000000000..6dcdbc92b4 --- /dev/null +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/autocorrelation.py @@ -0,0 +1,450 @@ +"""Methods used to generate the diagnostic tool.""" +from __future__ import annotations + +import arviz as az + +import beanmachine.ppl.diagnostics.tools.typing.autocorrelation as typing +import numpy as np +import numpy.typing as npt +from beanmachine.ppl.diagnostics.tools.helpers.plotting import ( + choose_palette, + create_toolbar, + style_figure, +) +from bokeh.models.annotations import BoxAnnotation +from bokeh.models.glyphs import Quad +from bokeh.models.layouts import Column, Row +from bokeh.models.ranges import DataRange1d +from bokeh.models.sources import ColumnDataSource +from bokeh.models.tools import HoverTool +from bokeh.models.widgets.inputs import Select +from bokeh.models.widgets.markups import Div +from bokeh.models.widgets.panels import Panel, Tabs +from bokeh.models.widgets.sliders import RangeSlider +from bokeh.plotting.figure import figure + + +FIGURE_NAMES: typing.Figure_names = None +PLOT_WIDTH = 500 +PLOT_HEIGHT = 300 +N_DISPLAY_COLUMNS = 2 + + +def compute_data(data: npt.NDArray) -> typing.Data: + """Compute autocorrelation data using the given data. + + Parameters + ---------- + data : npt.NDArray + A 2D NumPy array where the length of the first dimension is the number of chains + of the model, and the length of the second dimension is the number of draws of + the model. + + Returns + ------- + typing.Data + A dictionary of data used for the tool. + """ + num_chains, num_draws = data.shape + # Standard error of a Normal distribution within 95% of the density. + confidence_interval = (1.96 / num_draws) ** 0.5 + autocorr = az.stats.stats_utils.autocorr(data) + figure_names = [] + output = {} + for chain in range(num_chains): + chain_index = chain + 1 + figure_name = f"chain{chain_index}" + figure_names.append(figure_name) + chain_data = autocorr[chain, :] + bins = np.arange(len(chain_data) + 1) + left = bins[:-1] + top = chain_data + right = bins[1:] + bottom = np.zeros(len(chain_data)) + output[figure_name] = { + "quad": { + "left": left.tolist(), + "top": top.tolist(), + "right": right.tolist(), + "bottom": bottom.tolist(), + }, + "box": {"bottom": -1 * confidence_interval, "top": confidence_interval}, + } + # Here we set the figure names, which will be used in the other methods of the tool. + global FIGURE_NAMES + if FIGURE_NAMES is None: + FIGURE_NAMES = figure_names + return output + + +def create_sources(data: typing.Data) -> typing.Sources: + """Create Bokeh sources from the given data that will be bound to glyphs. + + Parameters + ---------- + data : typing.Data + Computed data for the tool. + + Returns + ------- + typing.Sources + A dictionary of Bokeh ColumnDataSource objects. + """ + num_chains = len(data) + output = {} + for chain in range(num_chains): + chain_index = chain + 1 + figure_name = f"chain{chain_index}" + output[figure_name] = {} + chain_data = data[figure_name]["quad"] + output[figure_name]["quad"] = ColumnDataSource(data=chain_data) + return output + + +def create_figures(num_chains: int) -> typing.Figures: + """Create the Bokeh figures used for the tool. + + Parameters + ---------- + num_chains : int + The number of chains of the model. + + Returns + ------- + typing.Figures + A dictionary of Bokeh figures. + """ + output = {} + for chain in range(num_chains): + chain_index = chain + 1 + figure_name = f"chain{chain_index}" + fig = figure( + plot_width=PLOT_WIDTH, + plot_height=PLOT_HEIGHT, + outline_line_color="black", + title=f"Chain {chain_index}", + x_range=DataRange1d(start=-1, end=100), + y_range=DataRange1d(start=-1.2, end=1.2), + x_axis_label="Draw", + y_axis_label="Autocorrelation", + ) + style_figure(fig) + output[figure_name] = fig + figure_names = list(output.keys()) + first_fig = output[figure_names[0]] + x_range = first_fig.x_range + y_range = first_fig.y_range + for _, fig in output.items(): + fig.x_range = x_range + fig.y_range = y_range + return output + + +def create_glyphs(num_chains: int) -> typing.Glyphs: + """Create the glyphs used for the figures of the tool. + + Parameters + ---------- + num_chains : int + The number of chains of the model. + + Returns + ------- + typing.Glyphs + A dictionary of Bokeh Glyphs objects. + """ + palette = choose_palette(num_chains) + output = {} + for chain in range(num_chains): + chain_index = chain + 1 + figure_name = f"chain{chain_index}" + output[figure_name] = {} + color = palette[chain] + glyph = Quad( + left="left", + top="top", + right="right", + bottom="bottom", + fill_color=color, + line_color="white", + fill_alpha=1.0, + name=f"autocorrelationGlyphChain{chain_index}", + ) + hover_glyph = Quad( + left="left", + top="top", + right="right", + bottom="bottom", + fill_color=color, + line_color="black", + fill_alpha=1.0, + name=f"autocorrelationGlyphChain{chain_index}", + ) + output[figure_name]["quad"] = {"glyph": glyph, "hover_glyph": hover_glyph} + return output + + +def add_glyphs( + figures: typing.Figures, + glyphs: typing.Glyphs, + sources: typing.Sources, +) -> None: + """Bind source data to glyphs and add the glyphs to the given figures. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + glyphs : typing.Glyphs + A dictionary of Bokeh Glyphs objects. + sources : typing.Sources + A dictionary of Bokeh ColumnDataSource objects. + + Returns + ------- + None + Adds data bound glyphs to the given figures directly. + """ + for figure_name, fig in figures.items(): + glyph = glyphs[figure_name]["quad"]["glyph"] + hover_glyph = glyphs[figure_name]["quad"]["hover_glyph"] + glyph_name = glyph.name + source = sources[figure_name]["quad"] + fig.add_glyph( + source_or_glyph=source, + glyph=glyph, + hover_glyph=hover_glyph, + name=glyph_name, + ) + + +def create_annotations(data: typing.Data) -> typing.Annotations: + """Create any annotations for the figures of the tool. + + Parameters + ---------- + data : typing.Data + Computed data for the tool. + + Returns + ------- + typing.Annotations + A dictionary of Bokeh Annotation objects. + """ + figure_names = data.keys() + palette = choose_palette(len(figure_names)) + output = {} + for i, (figure_name, figure_data) in enumerate(data.items()): + color = palette[i] + output[figure_name] = BoxAnnotation( + bottom=figure_data["box"]["bottom"], + top=figure_data["box"]["top"], + fill_color=color, + fill_alpha=0.2, + ) + return output + + +def add_annotations(figures: typing.Figures, annotations: typing.Annotations) -> None: + """Add the given annotations to the given figures of the tool. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + annotations : typing.Annotations + A dictionary of Bokeh Annotation objects. + + Returns + ------- + None + Adds annotations directly to the given figures. + """ + for figure_name, fig in figures.items(): + fig.add_layout(annotations[figure_name]) + + +def create_tooltips(figures: typing.Figures) -> typing.Tooltips: + """Create hover tools for the glyphs used in the figures of the tool. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + + Returns + ------- + typing.Tooltips + A dictionary of Bokeh HoverTools objects. + """ + output = {} + for figure_name, fig in figures.items(): + output[figure_name] = HoverTool( + renderers=fig.renderers, + tooltips=[("Autocorrelation", "@top")], + ) + return output + + +def add_tooltips(figures: typing.Figures, tooltips: typing.Tooltips) -> None: + """Add the given tools to the figures. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + tooltips : typing.Tooltips + A dictionary of Bokeh HoverTools objects. + + Returns + ------- + None + Adds the tooltips directly to the given figures. + """ + for figure_name, fig in figures.items(): + fig.add_tools(tooltips[figure_name]) + + +def create_widgets(rv_name: str, rv_names: list[str], num_draws: int) -> typing.Widgets: + """Create the widgets used in the tool. + + Parameters + ---------- + rv_name : str + The string representation of the random variable data. + rv_names : list[str] + A list of all available random variable names. + num_draws : int + The number of draws used in the model for a single chain. + + Returns + ------- + typing.Widgets + A dictionary of Bokeh widget objects. + """ + end = 10 if num_draws <= 2 * 100 else 100 + rv_select = Select( + value=rv_name, + options=rv_names, + title="Query", + name="autocorrelationRVSelect", + ) + range_slider = RangeSlider( + start=0, + end=num_draws, + value=(0, end), + step=end, + title="Autocorrelation range", + name="autocorrelationRangeSlider", + ) + return {"rv_select": rv_select, "range_slider": range_slider} + + +def help_page() -> Div: + """Help tab for the tool. + + Returns + ------- + Div + Bokeh Div widget containing the help tab information. + """ + text = """ +

+ Autocorrelation plots +

+

+ Autocorrelation plots measure how predictive the last several samples are + of the current sample. Autocorrelation may vary between -1.0 + (deterministically anticorrelated) and 1.0 (deterministically correlated). + We compute autocorrelation approximately, so it may sometimes exceed these + bounds. In an ideal world, the current sample is chosen independently of + the previous samples: an autocorrelation of zero. This is not possible in + practice, due to stochastic noise and the mechanics of how inference + works. +

+ """ + return Div(text=text, disable_math=False, min_width=800) + + +def create_figure_grid(figures: typing.Figures) -> Row: + """Layout the given figures in a grid, and make one toolbar. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + + Returns + ------- + Row + A Bokeh layout object. + """ + toolbar = create_toolbar(figures) + figure_values = list(figures.values()) + figure_rows = [] + while len(figure_values): + figs = figure_values[:N_DISPLAY_COLUMNS] + for i, fig in enumerate(figs): + if i != 0: + fig.yaxis.axis_label = None + figure_rows.append(figs) + for fig in figs: + figure_values.pop(figure_values.index(fig)) + for i, figure_row in enumerate(figure_rows): + if i != len(figure_rows) - 1: + for fig in figure_row: + fig.xaxis.axis_label = None + figure_layout = [] + for i in range(len(figure_rows)): + figure_layout.append(Row(children=figure_rows[i])) + return Row(children=[Column(children=figure_layout), toolbar]) + + +def create_view(widgets: typing.Widgets, figures: typing.Figures) -> Tabs: + """Create the tool view. + + Parameters + ---------- + widgets : typing.Widgets + A dictionary of Bokeh widget objects. + figures : typing.Figures + A dictionary of Bokeh Figure objects. + + Returns + ------- + Tabs + Bokeh Tabs object. + """ + help_panel = Panel(child=help_page(), title="Help", name="helpPanel") + figure_layout = create_figure_grid(figures) + tool_panel = Panel( + child=Column( + children=[widgets["rv_select"], figure_layout, widgets["range_slider"]], + ), + title="Autocorrelation", + name="toolPanel", + ) + return Tabs(tabs=[tool_panel, help_panel]) + + +def update(data: npt.NDArray, sources: typing.Sources) -> None: + """Update the tool based on user interaction. + + Parameters + ---------- + data : npt.NDArray + A 2D NumPy array where the length of the first dimension is the number of chains + of the model, and the length of the second dimension is the number of draws of + the model. + sources : typing.Sources + A dictionary of Bokeh ColumnDataSource objects. + + Returns + ------- + None + When Bokeh sources are updated with new data, the figures of the tool will be + redrawn. + """ + computed_data = compute_data(data) + for figure_name, figure_data in computed_data.items(): + sources[figure_name]["quad"].data = dict(**figure_data["quad"]) diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/effective_sample_size.py b/src/beanmachine/ppl/diagnostics/tools/helpers/effective_sample_size.py new file mode 100644 index 0000000000..ddf6416efa --- /dev/null +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/effective_sample_size.py @@ -0,0 +1,527 @@ +"""Methods used to generate the diagnostic tool.""" +from __future__ import annotations + +from numbers import Number + +import arviz as az + +import beanmachine.ppl.diagnostics.tools.typing.effective_sample_size as typing +import numpy as np +import numpy.typing as npt +from beanmachine.ppl.diagnostics.tools.helpers.plotting import ( + choose_palette, + create_toolbar, + filter_renderers, + style_figure, +) +from bokeh.models.annotations import Legend, LegendItem +from bokeh.models.glyphs import Circle, Line +from bokeh.models.layouts import Column, Row +from bokeh.models.sources import ColumnDataSource +from bokeh.models.tools import HoverTool +from bokeh.models.widgets import Div +from bokeh.models.widgets.inputs import Select +from bokeh.models.widgets.panels import Panel, Tabs +from bokeh.plotting.figure import figure + + +PLOT_WIDTH = 1000 +PLOT_HEIGHT = 500 +FIGURE_NAMES = ["ess"] + + +def compute_data( + data: npt.NDArray, + first_draw: Number = 0, + num_points: int = 20, +) -> typing.Data: + """Compute effective sample size estimates using the given data. + + Parameters + ---------- + data : npt.NDArray + A 2D NumPy array where the length of the first dimension is the number of chains + of the model, and the length of the second dimension is the number of draws of + the model. + first_draw : Number, optional default is 0 + The first draw index. + num_points : int, optional default is 20 + The number of divisions in the model samples to compute the effective sample + size for. + + Returns + ------- + typing.Data + A dictionary of data used for the tool. + """ + num_chains, num_draws = data.shape + num_samples = num_chains * num_draws + rule_of_thumb = 100 * num_chains + ess_x = np.linspace( + start=num_samples / num_points, + stop=num_samples, + num=num_points, + ) + draw_divisions = np.linspace( + start=num_draws // num_points, + stop=num_draws, + num=num_points, + dtype=np.integer, + ) + ess_bulk_y = [ + az.stats.diagnostics._ess_bulk(data[:, first_draw:draw_division]) + for draw_division in draw_divisions + ] + ess_tail_y = [ + az.stats.diagnostics._ess_tail(data[:, first_draw:draw_division]) + for draw_division in draw_divisions + ] + rule_of_thumb_x = np.linspace(start=0, stop=num_samples, num=num_points) + rule_of_thumb_y = rule_of_thumb * np.ones(num_points) + rule_of_thumb_label = [rule_of_thumb] * len(ess_x) + return { + "ess": { + "bulk": {"x": ess_x.tolist(), "y": ess_bulk_y}, + "tail": {"x": ess_x.tolist(), "y": ess_tail_y}, + "rule_of_thumb": { + "x": rule_of_thumb_x.tolist(), + "y": rule_of_thumb_y.tolist(), + "label": rule_of_thumb_label, + }, + }, + } + + +def create_sources(data: typing.Data) -> typing.Sources: + """Create Bokeh sources from the given data that will be bound to glyphs. + + Parameters + ---------- + data : typing.Data + A dictionary of data used for the tool. + + Returns + ------- + typing.Sources + A dictionary of Bokeh ColumnDataSource objects. + """ + return { + "ess": { + "bulk": { + "line": ColumnDataSource(data=data["ess"]["bulk"]), + "circle": ColumnDataSource(data=data["ess"]["bulk"]), + }, + "tail": { + "line": ColumnDataSource(data=data["ess"]["tail"]), + "circle": ColumnDataSource(data=data["ess"]["tail"]), + }, + "rule_of_thumb": { + "line": ColumnDataSource(data=data["ess"]["rule_of_thumb"]), + }, + }, + } + + +def create_figures() -> typing.Figures: + """Create the Bokeh figures used for the tool. + + Returns + ------- + typing.Figures + A dictionary of Bokeh Figure objects. + """ + fig = figure( + plot_width=PLOT_WIDTH, + plot_height=PLOT_HEIGHT, + outline_line_color="black", + title="Effective Sample Size", + ) + style_figure(fig) + return {"ess": fig} + + +def create_glyphs() -> typing.Glyphs: + """Create the glyphs used for the figures of the tool. + + Returns + ------- + typing.Glyphs + A dictionary of Bokeh Glyphs objects. + """ + palette = choose_palette(4) + bulk_glyph_color = palette[0] + tail_glyph_color = palette[1] + rule_of_thumb_color = palette[3] + output = {"ess": {}} + for glyph_name in ["bulk", "tail", "rule_of_thumb"]: + glyph_token = "".join([token.title() for token in glyph_name.split("_")]) + if glyph_name in ["bulk", "tail"]: + color = bulk_glyph_color if glyph_name == "bulk" else tail_glyph_color + output["ess"][glyph_name] = { + "line": { + "glyph": Line( + x="x", + y="y", + line_color=color, + line_alpha=1.0, + line_width=2.0, + name=f"ess{glyph_token}LineGlyph", + ), + "hover_glyph": Line( + x="x", + y="y", + line_color=color, + line_alpha=1.0, + line_width=2.0, + name=f"ess{glyph_token}LineHoverGlyph", + ), + }, + "circle": { + "glyph": Circle( + x="x", + y="y", + size=10, + fill_color=color, + line_color="white", + fill_alpha=1.0, + name=f"ess{glyph_token}CircleGlyph", + ), + "hover_glyph": Circle( + x="x", + y="y", + size=10, + fill_color=color, + line_color="black", + fill_alpha=1.0, + name=f"ess{glyph_token}CircleHoverGlyph", + ), + }, + } + elif glyph_name == "rule_of_thumb": + output["ess"][glyph_name] = { + "line": { + "glyph": Line( + x="x", + y="y", + line_color=rule_of_thumb_color, + line_alpha=0.7, + line_width=4.0, + line_dash="dashed", + name=f"ess{glyph_token}LineGlyph", + ), + "hover_glyph": Line( + x="x", + y="y", + line_color=rule_of_thumb_color, + line_alpha=0.7, + line_width=4.0, + line_dash="solid", + name=f"ess{glyph_token}LineHoverGlyph", + ), + }, + } + return output + + +def add_glyphs( + figures: typing.Figures, + glyphs: typing.Glyphs, + sources: typing.Sources, +) -> None: + """Bind source data to glyphs and add the glyphs to the given figures. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + glyphs : typing.Glyphs + A dictionary of Bokeh Glyphs objects. + sources : typing.Sources + A dictionary of Bokeh ColumnDataSource objects. + + Returns + ------- + None + Adds data bound glyphs to the given figures directly. + """ + fig = figures["ess"] + figure_glyphs = glyphs["ess"] + figure_sources = sources["ess"] + for glyph_name, glyphs in figure_glyphs.items(): + glyph_sources = figure_sources[glyph_name] + for glyph_type, glyph in glyphs.items(): + glyph_source = glyph_sources[glyph_type] + fig.add_glyph( + source_or_glyph=glyph_source, + glyph=glyph["glyph"], + hover_glyph=glyph["hover_glyph"], + name=glyph["glyph"].name, + ) + + +def create_annotations(figures: typing.Figures) -> typing.Annotations: + """Create any annotations for the figures of the tool. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + + Returns + ------- + typing.Annotations + A dictionary of Bokeh Annotation objects. + """ + legend_items = [] + fig = figures["ess"] + output = {} + for glyph_name in ["bulk", "tail", "rule_of_thumb"]: + glyph_token = "".join([token.title() for token in glyph_name.split("_")]) + search = f"ess{glyph_token}" + if glyph_name in ["bulk", "tail"]: + label = glyph_name.title() + else: + label = "Rule-of-thumb" + filtered_renderers = filter_renderers(fig, search, "GlyphRenderer", True) + legend_items.append( + LegendItem( + label=label, + renderers=filtered_renderers, + name=f"ess{glyph_token}LegendItem", + ), + ) + output["ess"] = { + "legend": Legend( + items=legend_items, + orientation="horizontal", + border_line_color="black", + background_fill_alpha=1.0, + name="essLegend", + ), + } + return output + + +def add_annotations(figures: typing.Figures, annotations: typing.Annotations) -> None: + """Add the given annotations to the given figures of the tool. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + annotations : typing.Annotations + A dictionary of Bokeh Annotation objects. + + Returns + ------- + None + Adds annotations directly to the given figures. + """ + figures["ess"].add_layout(annotations["ess"]["legend"], "below") + + +def create_tooltips(figures: typing.Figures) -> typing.Tooltips: + """Create hover tools for the glyphs used in the figures of the tool. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + + Returns + ------- + typing.Tooltips + A dictionary of Bokeh HoverTools objects. + """ + output = {"ess": {}} + fig = figures["ess"] + tooltips = [] + for glyph_name in ["bulk", "tail", "rule_of_thumb"]: + glyph_token = "".join([token.title() for token in glyph_name.split("_")]) + if glyph_name in ["bulk", "tail"]: + tooltips = [("Total draws", "@x{0,}"), ("ESS", "@y{0,}")] + elif glyph_name == "rule_of_thumb": + tooltips = [("Rule-of-thumb", "@label")] + filtered_renderers = filter_renderers( + fig, + f"ess{glyph_token}", + "GlyphRenderer", + True, + ) + tips_name = "".join( + [c.lower() if i == 0 else c for i, c in enumerate(list(glyph_token))], + ) + tips = HoverTool( + renderers=filtered_renderers, + tooltips=tooltips, + name=f"{tips_name}Tips", + ) + output["ess"][glyph_name] = tips + return output + + +def add_tooltips(figures: typing.Figures, tooltips: typing.Tooltips) -> None: + """Add the given tools to the figures. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + tooltips : typing.Tooltips + A dictionary of Bokeh HoverTools objects. + + Returns + ------- + None + Adds the tooltips directly to the given figures. + """ + fig = figures["ess"] + figure_tooltips = tooltips["ess"] + for _, tips in figure_tooltips.items(): + fig.add_tools(tips) + + +def create_widgets(rv_name: str, rv_names: list[str]) -> typing.Widgets: + """Create the widgets used in the tool. + + Parameters + ---------- + rv_name : str + The string representation of the random variable data. + rv_names : list[str] + A list of all available random variable names. + + Returns + ------- + typing.Widgets + A dictionary of Bokeh widget objects. + """ + return {"rv_select": Select(value=rv_name, options=rv_names, title="Query")} + + +def help_page() -> Div: + """Help tab for the tool. + + Returns + ------- + Div + Bokeh Div widget containing the help tab information. + """ + text = """ +

+ Effective sample size diagnostic +

+

+ MCMC samplers do not draw truly independent samples from the target + distribution, which means that our samples are correlated. In an ideal + situation all samples would be independent, but we do not have that + luxury. We can, however, measure the number of effectively + independent samples we draw, which is called the effective sample + size. You can read more about how this value is calculated in the Vehtari + et al paper. In brief, it is a measure that combines information + from the \\(\\hat{R}\\) value with the autocorrelation estimates within the + chains. +

+

+ ESS estimates come in two variants, ess_bulk and + ess_tail. The former is the default, but the latter can be useful + if you need good estimates of the tails of your posterior distribution. + The rule of thumb for ess_bulk is for this value to be greater + than 100 per chain on average. The ess_tail is an estimate for + effectively independent samples considering the more extreme values of the + posterior. This is not the number of samples that landed in the tails of + the posterior, but rather a measure of the number of effectively + independent samples if we sampled the tails of the posterior. The rule of + thumb for this value is also to be greater than 100 per chain on average. +

+

+ When the model is converging properly, both the bulk and tail lines should + be roughly linear. +

+ + """ + return Div(text=text, disable_math=False, min_width=PLOT_WIDTH) + + +def create_figure_grid(figures: typing.Figures) -> Row: + """Layout the given figures in a grid, and make one toolbar. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + + Returns + ------- + Row + A Bokeh layout object. + """ + toolbar = create_toolbar(figures) + return Row(children=[figures["ess"], toolbar]) + + +def create_view(widgets: typing.Widgets, figures: typing.Figures) -> Tabs: + """Create the tool view. + + Parameters + ---------- + widgets : typing.Widgets + A dictionary of Bokeh widget objects. + figures : typing.Figures + A dictionary of Bokeh Figure objects. + + Returns + ------- + Tabs + Bokeh Tabs objects. + """ + help_panel = Panel(child=help_page(), title="Help", name="helpPanel") + figure_layout = create_figure_grid(figures) + tool_panel = Panel( + child=Column( + children=[widgets["rv_select"], figure_layout], + ), + title="Effective Sample Size", + name="toolPanel", + ) + return Tabs(tabs=[tool_panel, help_panel]) + + +def update(data: npt.NDArray, sources: typing.Sources) -> None: + """Update the tool based on user interaction. + + Parameters + ---------- + data : npt.NDArray + A 2D NumPy array where the length of the first dimension is the number of chains + of the model, and the length of the second dimension is the number of draws of + the model. + sources : typing.Sources + A dictionary of Bokeh ColumnDataSource objects. + + Returns + ------- + None + When Bokeh sources are updated with new data, the figures of the tool will be + redrawn. + """ + computed_data = compute_data(data) + figure_data = computed_data["ess"] + figure_sources = sources["ess"] + for glyph_name, glyph_sources in figure_sources.items(): + glyph_data = figure_data[glyph_name] + for _, glyph_source in glyph_sources.items(): + glyph_source.data = dict(**glyph_data) diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/marginal1d.py b/src/beanmachine/ppl/diagnostics/tools/helpers/marginal1d.py new file mode 100644 index 0000000000..c1184f7b9a --- /dev/null +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/marginal1d.py @@ -0,0 +1,635 @@ +"""Methods used to generate the diagnostic tool.""" +from __future__ import annotations + +from typing import Optional + +import arviz as az + +import beanmachine.ppl.diagnostics.tools.typing.marginal1d as typing +import numpy as np +import numpy.typing as npt +from beanmachine.ppl.diagnostics.tools.helpers.plotting import ( + choose_palette, + create_toolbar, + filter_renderers, + style_figure, +) +from bokeh.models.annotations import Band, LabelSet +from bokeh.models.glyphs import Circle, Line +from bokeh.models.layouts import Column, Row +from bokeh.models.sources import ColumnDataSource +from bokeh.models.tools import HoverTool +from bokeh.models.widgets.inputs import Select +from bokeh.models.widgets.markups import Div +from bokeh.models.widgets.panels import Panel, Tabs +from bokeh.models.widgets.sliders import Slider +from bokeh.plotting.figure import figure + + +PLOT_WIDTH = 500 +PLOT_HEIGHT = 500 +FIGURE_NAMES = ["marginal", "cumulative"] + + +def compute_stats( + data: npt.NDArray, + kde_x: npt.NDArray, + kde_y: npt.NDArray, + hdi_probability: float, + text_align: Optional[list[str]] = None, + x_offset: Optional[list[int]] = None, + y_offset: Optional[list[int]] = None, + return_labels: bool = False, +) -> typing.StatsAndLabelsData: + """Compute statistics for the given data, and its KDE. + + Parameters + ---------- + data : npt.NDArray + A 2D NumPy array where the length of the first dimension is the number of chains + of the model, and the length of the second dimension is the number of draws of + the model. + kde_x : npt.NDArray + The x-axis KDE estimate of the random variable data. + kde_y : npt.NDArray + The y-axis KDE estimate of the random variable data. + hdi_probability : float + The HDI probability to use when calculating the HDI bounds. + text_align : list[str] | None, optional default is ``None`` + How to display label justifications for the statistics in Bokeh. + x_offset : list[int] | None, optional default is ``None`` + x-axis offsets for the labels. + y_offset : list[int] | None, optional default is ``None`` + y-axis offsets for the labels. + return_labels : bool, optional default is ``False`` + ``True`` returns labels to be used in the Bokeh figure. + + Returns + ------- + typing.StatsAndLabelsData + A dictionary for statistics and labels for the Bokeh figures. + """ + if text_align is None: + text_align = ["right", "center", "left"] + if x_offset is None: + x_offset = [-5, 0, 5] + if y_offset is None: + y_offset = [0, 10, 0] + + mean = np.mean(kde_x) + hdi = az.stats.hdi(data, hdi_prob=hdi_probability) + x = [hdi[0], mean, hdi[1]] + y = np.interp(x=np.array(x), xp=kde_x, fp=kde_y) + text = [ + f"Lower HDI: {hdi[0]:.4}", + f"Mean: {mean:.4}", + f"Upper HDI: {hdi[1]:.4}", + ] + stats = {"x": x, "y": y.tolist(), "text": text} + labels = {} + if return_labels: + labels = { + "x": x, + "y": y.tolist(), + "text": text, + "text_align": text_align, + "x_offset": x_offset, + "y_offset": y_offset, + } + return {"stats": stats, "labels": labels} + + +def hdi_data( + data: npt.NDArray, + kde_x: npt.NDArray, + kde_y: npt.NDArray, + hdi_probability: float, +) -> typing.HDIData: + """Calculate the HDI arrays needed for the Bokeh annotation. + + Parameters + ---------- + data : npt.NDArray + A 2D NumPy array where the length of the first dimension is the number of chains + of the model, and the length of the second dimension is the number of draws of + the model. + kde_x : npt.NDArray + The x-axis KDE estimate of the random variable data. + kde_y : npt.NDArray + The y-axis KDE estimate of the random variable data. + hdi_probability : float + The HDI probability to use when calculating the HDI bounds. + + Returns + ------- + typing.HDIData + Arrays used to create the Bokeh annotation for the HDI. + """ + hdi = az.stats.hdi(data, hdi_prob=hdi_probability) + mask = np.ix_(np.logical_and(kde_x >= hdi[0], kde_x <= hdi[1]))[0] + base = kde_x[mask] + lower = np.zeros((len(mask))) + upper = kde_y[mask] + return {"base": base.tolist(), "lower": lower.tolist(), "upper": upper.tolist()} + + +def compute_data( + data: npt.NDArray, + bw_factor: float, + hdi_probability: float, +) -> typing.Data: + """Compute effective sample size estimates using the given data. + + Parameters + ---------- + data : npt.NDArray + A 2D NumPy array where the length of the first dimension is the number of chains + of the model, and the length of the second dimension is the number of draws of + the model. + bw_factor : float + Multiplicative factor used when calculating the kernel density estimate. + hdi_probability : float + The HDI probability to use when calculating the HDI bounds. + + Returns + ------- + typing.Data + A dictionary of data used for the tool. + """ + data = data.reshape(-1) + output = {} + for figure_name in FIGURE_NAMES: + output[figure_name] = {} + x, y, bandwidth = az.stats.density_utils._kde_linear( + data, + bw_return=True, + bw_fct=bw_factor, + ) + if figure_name == "cumulative": + y = np.cumsum(y) + y /= y.max() + stats_and_labels = compute_stats( + data, + x, + y, + hdi_probability, + return_labels=True, + ) + output[figure_name] = { + "distribution": { + "x": x.tolist(), + "y": y.tolist(), + "bandwidth": [bandwidth], + }, + "hdi": hdi_data(data, x, y, hdi_probability), + "stats": stats_and_labels["stats"], + "labels": stats_and_labels["labels"], + } + return output + + +def create_sources(data: typing.Data) -> typing.Sources: + """Create Bokeh sources from the given data that will be bound to glyphs. + + Parameters + ---------- + data : typing.Data + A dictionary of data used for the tool. + + Returns + ------- + typing.Sources + A dictionary of Bokeh ColumnDataSource objects. + """ + output = {} + for figure_name, figure_data in data.items(): + output[figure_name] = {} + for glyph_name, glyph_data in figure_data.items(): + if "bandwidth" in list(glyph_data.keys()): + glyph_data.pop("bandwidth") + output[figure_name][glyph_name] = ColumnDataSource(data=glyph_data) + return output + + +def create_figures(rv_name: str) -> typing.Figures: + """Create the Bokeh figures used for the tool. + + Parameters + ---------- + rv_name : str + The string representation of the random variable data. + + Returns + ------- + typing.Figures + A dictionary of Bokeh Figure objects. + """ + output = {} + for figure_name in FIGURE_NAMES: + fig = figure( + width=PLOT_WIDTH, + height=PLOT_HEIGHT, + outline_line_color="black", + title=f"{figure_name} distribution", + x_axis_label=rv_name, + y_axis_label=None, + ) + fig.yaxis.visible = False + style_figure(fig) + output[figure_name] = fig + output[FIGURE_NAMES[0]].x_range = output[FIGURE_NAMES[1]].x_range + output[FIGURE_NAMES[0]].y_range = output[FIGURE_NAMES[1]].y_range + return output + + +def create_glyphs(data: typing.Data) -> typing.Glyphs: + """Create the glyphs used for the figures of the tool. + + Parameters + ---------- + data : typing.Data + A dictionary of data used for the tool. + + Returns + ------- + typing.Glyphs + A dictionary of Bokeh Glyphs objects. + """ + palette = choose_palette(2) + output = {} + for figure_name, figure_data in data.items(): + output[figure_name] = {} + for glyph_name, _ in figure_data.items(): + if glyph_name in ["distribution", "stats"]: + if glyph_name == "distribution": + output[figure_name][glyph_name] = { + "glyph": Line( + x="x", + y="y", + line_color=palette[0], + line_alpha=0.7, + line_width=2.0, + name=f"{figure_name}DistributionGlyph", + ), + "hover_glyph": Line( + x="x", + y="y", + line_color=palette[1], + line_alpha=1.0, + line_width=2.0, + name=f"{figure_name}DistributionHoverGlyph", + ), + } + if glyph_name == "stats": + output[figure_name][glyph_name] = { + "glyph": Circle( + x="x", + y="y", + size=10, + fill_color=palette[0], + line_color="white", + fill_alpha=1.0, + name=f"{figure_name}StatsGlyph", + ), + "hover_glyph": Circle( + x="x", + y="y", + size=10, + fill_color=palette[1], + line_color="black", + fill_alpha=1.0, + name=f"{figure_name}StatsHoverGlyph", + ), + } + return output + + +def add_glyphs( + figures: typing.Figures, + glyphs: typing.Glyphs, + sources: typing.Sources, +) -> None: + """Bind source data to glyphs and add the glyphs to the given figures. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + glyphs : typing.Glyphs + A dictionary of Bokeh Glyphs objects. + sources : typing.Sources + A dictionary of Bokeh ColumnDataSource objects. + + Returns + ------- + None + Adds data bound glyphs to the given figures directly. + """ + for figure_name, figure_glyphs in glyphs.items(): + fig = figures[figure_name] + figure_sources = sources[figure_name] + for glyph_name, glyphs in figure_glyphs.items(): + glyph_source = figure_sources[glyph_name] + fig.add_glyph( + source_or_glyph=glyph_source, + glyph=glyphs["glyph"], + hover_glyph=glyphs["hover_glyph"], + name=glyphs["glyph"].name, + ) + + +def create_annotations(sources: typing.Sources) -> typing.Annotations: + """Create any annotations for the figures of the tool. + + Parameters + ---------- + source : typing.Sources + A dictionary of Bokeh ColumnDataSource objects. + + Returns + ------- + typing.Annotations + A dictionary of Bokeh Annotation objects. + """ + palette = choose_palette(1) + output = {} + for figure_name, figure_sources in sources.items(): + output[figure_name] = {} + for glyph_name, glyph_source in figure_sources.items(): + if glyph_name == "hdi": + output[figure_name][glyph_name] = Band( + base="base", + lower="lower", + upper="upper", + source=glyph_source, + level="underlay", + fill_color=palette[0], + fill_alpha=0.2, + line_width=1.0, + line_color="white", + name=f"{figure_name}HdiAnnotation", + ) + elif glyph_name == "labels": + output[figure_name][glyph_name] = LabelSet( + x="x", + y="y", + text="text", + x_offset="x_offset", + y_offset="y_offset", + text_align="text_align", + source=glyph_source, + background_fill_color="white", + background_fill_alpha=0.8, + name=f"{figure_name}LabelAnnotation", + ) + return output + + +def add_annotations(figures: typing.Figures, annotations: typing.Annotations) -> None: + """Add the given annotations to the given figures of the tool. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + annotations : typing.Annotations + A dictionary of Bokeh Annotation objects. + + Returns + ------- + None + Adds annotations directly to the given figures. + """ + for figure_name, annotation_sources in annotations.items(): + fig = figures[figure_name] + for _, annotation in annotation_sources.items(): + fig.add_layout(annotation) + + +def create_tooltips(rv_name: str, figures: typing.Figures) -> typing.Tooltips: + """Create hover tools for the glyphs used in the figures of the tool. + + Parameters + ---------- + rv_name : str + The string representation of the random variable data. + figures : typing.Figures + A dictionary of Bokeh Figure objects. + + Returns + ------- + typing.Tooltips + A dictionary of Bokeh HoverTools objects. + """ + output = {} + for figure_name, fig in figures.items(): + output[figure_name] = { + "distribution": HoverTool( + renderers=filter_renderers( + fig, + "DistributionGlyph", + "GlyphRenderer", + True, + ), + tooltips=[(rv_name, "@x")], + ), + "stats": HoverTool( + renderers=filter_renderers(fig, "StatsGlyph", "GlyphRenderer", True), + tooltips=[("", "@text")], + ), + } + return output + + +def add_tooltips(figures: typing.Figures, tooltips: typing.Tooltips) -> None: + """Add the given tools to the figures. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + tooltips : typing.Tooltips + A dictionary of Bokeh HoverTools objects. + + Returns + ------- + None + Adds the tooltips directly to the given figures. + """ + for figure_name, figure_tooltips in tooltips.items(): + fig = figures[figure_name] + for _, tooltip in figure_tooltips.items(): + fig.add_tools(tooltip) + + +def create_widgets( + rv_name: str, + rv_names: list[str], + bw_factor: float, + bandwidth: float, +) -> typing.Widgets: + """Create the widgets used in the tool. + + Parameters + ---------- + rv_name : str + The string representation of the random variable data. + rv_names : list[str] + A list of all available random variable names. + bw_factor : float + Multiplicative factor used when calculating the kernel density estimate. + bandwidth : float + The bandwidth used to calculate the KDE. + + Returns + ------- + typing.Widgets + A dictionary of Bokeh widget objects. + """ + return { + "rv_select": Select(value=rv_name, options=rv_names, title="Query"), + "bw_factor_slider": Slider( + title="Bandwidth factor", + start=0.01, + end=2.00, + value=1.00, + step=0.01, + ), + "bw_div": Div(text=f"Bandwidth: {bw_factor * bandwidth}"), + "hdi_slider": Slider(start=1, end=99, step=1, value=89, title="HDI"), + } + + +def help_page() -> Div: + """Help tab for the tool. + + Returns + ------- + Div + Bokeh Div widget containing the help tab information. + """ + text = """ +

+ Highest density interval +

+

+ The highest density interval region is not equal tailed like a typical + equal tailed interval of 2.5%. Thus it will include the mode(s) of the + posterior distribution. +

+

+ There is nothing particularly specific about having a default HDI of 89%. + If fact, the only remarkable thing about defaulting to 89% is that it is + the highest prime number that does not exceed the unstable 95% threshold. + See the link to McElreath's book below for further discussion. +

+ + """ + return Div(text=text, disable_math=False, min_width=PLOT_WIDTH) + + +def create_figure_grid(figures: typing.Figures) -> Row: + """Layout the given figures in a grid, and make one toolbar. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + + Returns + ------- + Row + A Bokeh layout object. + """ + toolbar = create_toolbar(figures) + return Row(children=[*list(figures.values()), toolbar]) + + +def create_view(widgets: typing.Widgets, figures: typing.Figures) -> Tabs: + """Create the tool view. + + Parameters + ---------- + widgets : typing.Widgets + A dictionary of Bokeh widget objects. + figures : typing.Figures + A dictionary of Bokeh Figure objects. + + Returns + ------- + Tabs + Bokeh Tabs objects. + """ + help_panel = Panel(child=help_page(), title="Help", name="helpPanel") + tool_panel = Panel( + child=Column( + children=[ + widgets["rv_select"], + create_figure_grid(figures), + widgets["bw_factor_slider"], + widgets["bw_div"], + widgets["hdi_slider"], + ], + ), + title="Marginal 1D", + name="toolPanel", + ) + return Tabs(tabs=[tool_panel, help_panel]) + + +def update( + data: npt.NDArray, + sources: typing.Sources, + figures: typing.Figures, + rv_name: str, + bw_factor: float, + hdi_probability: float, +) -> float: + """Update the tool based on user interaction. + + Parameters + ---------- + data : npt.NDArray + A 2D NumPy array where the length of the first dimension is the number of chains + of the model, and the length of the second dimension is the number of draws of + the model. + sources : typing.Sources + A dictionary of Bokeh ColumnDataSource objects. + figures : typing.Figures + A dictionary of Bokeh Figure objects. + rv_name : str + The string representation of the random variable data. + rv_names : list[str] + A list of all available random variable names. + hdi_probability : float + The HDI probability to use when calculating the HDI bounds. + + Returns + ------- + float + Returns the bandwidth used to calculate the KDE. + """ + computed_data = compute_data(data, bw_factor, hdi_probability) + bw = computed_data["marginal"]["distribution"]["bandwidth"][0] + for figure_name, figure_sources in sources.items(): + fig = figures[figure_name] + fig.xaxis.axis_label = rv_name + figure_data = computed_data[figure_name] + for glyph_name, glyph_source in figure_sources.items(): + glyph_data = figure_data[glyph_name] + if "bandwidth" in list(glyph_data.keys()): + glyph_data.pop("bandwidth") + glyph_source.data = dict(**glyph_data) + return float(bw) diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py b/src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py new file mode 100644 index 0000000000..0866d2fd86 --- /dev/null +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py @@ -0,0 +1,1000 @@ +"""Methods used to generate the diagnostic tool.""" +from __future__ import annotations + +from typing import Optional + +import arviz as az +import beanmachine.ppl.diagnostics.tools.typing.marginal2d as typing +import numpy as np +import numpy.typing as npt + +from beanmachine.ppl.diagnostics.tools.helpers.marginal1d import ( + compute_data as m1d_data, + compute_stats, + hdi_data as compute_hdi_data, +) +from beanmachine.ppl.diagnostics.tools.helpers.plotting import ( + choose_palette, + create_toolbar, + filter_renderers, + style_figure, +) +from bokeh.models.annotations import Band +from bokeh.models.glyphs import Circle, Image, Line +from bokeh.models.layouts import Column, GridBox, Row +from bokeh.models.mappers import LinearColorMapper +from bokeh.models.sources import ColumnDataSource +from bokeh.models.tools import HoverTool +from bokeh.models.widgets import Div +from bokeh.models.widgets.inputs import Select +from bokeh.models.widgets.panels import Panel, Tabs +from bokeh.models.widgets.sliders import Slider +from bokeh.plotting.figure import figure + + +MARGINAL1D_PLOT_WIDTH = 500 +MARGINAL1D_PLOT_HEIGHT = 100 +MARGINAL2D_PLOT_WIDTH = 500 +MARGINAL2D_PLOT_HEIGHT = 500 +FIGURE_NAMES = ["x", "y", "xy"] + + +def compute_xy_data( + x: npt.NDArray, + y: npt.NDArray, + x_label: str, + y_label: str, + x_stats: list[float], + y_stats: list[float], +) -> typing.XYData: + """Compute the two-dimensional marginal. + + Parameters + ---------- + x : npt.NDArray + The random variable data for the x-axis. + y : npt.NDArray + The random variable data for the y-axis. + x_label : str + The label for the x-axis. + y_label : str + The label for the y-axis. + x_hdi_probability : float + The HDI probability to use when calculating the HDI bounds for the x-axis. + y_hdi_probability : float + The HDI probability to use when calculating the HDI bounds for the y-axis. + x_stats : list[float] + Statistics for the x-axis; HDI bounds and the mean. + y_stats : list[float] + Statistics for the y-axis; HDI bounds and the mean. + + Returns + ------- + typing.XYData + The x-y joint marginal data object. + """ + density, xmin, xmax, ymin, ymax = az.stats.density_utils._fast_kde_2d(x=x, y=y) + distribution = { + "image": [density.T.tolist()], + "x": [xmin], + "y": [ymin], + "ymax": [ymax], + "dw": [xmax - xmin], + "dh": [ymax - ymin], + } + x = np.linspace(start=xmin, stop=xmax) + y = np.linspace(start=ymin, stop=ymax) + hdi = { + "x": { + "lower": {"x": [x_stats[0]] * len(y), "y": y.tolist()}, + "upper": {"x": [x_stats[2]] * len(y), "y": y.tolist()}, + }, + "y": { + "lower": {"x": x.tolist(), "y": [y_stats[0]] * len(x)}, + "upper": {"x": x.tolist(), "y": [y_stats[2]] * len(x)}, + }, + } + stats = {"x": [x_stats[1]], "y": [y_stats[1]]} + labels = {"mean": [f"{x_label}/{y_label}"]} + return {"distribution": distribution, "hdi": hdi, "stats": stats, "labels": labels} + + +def compute_y_data( + data: npt.NDArray, + bw_factor: float, + hdi_probability: float, +) -> typing.YData: + """Compute the marginal for the y-axis. + + In order to correctly display the HDI region in the figure, we need to separate it + into a top and bottom Bokeh annotation. This is why the y data is handled + differently than the x-axis data. + + Parameters + ---------- + data : npt.NDArray + Random variable data for the y-axis. + bw_factor : float + Multiplicative factor used when calculating the kernel density estimate. + hdi_probability : float + The HDI probability to use when calculating the HDI bounds. + + Returns + ------- + typing.YData + The data for the y-axis. This data looks very similar to the x-axis data, except + where we need to split the HDI into a top and bottom portion. + """ + hdi_bounds = az.stats.hdi(data, hdi_prob=hdi_probability) + kde_x, kde_y, bandwidth = az.stats.density_utils._kde_linear( + data, + bw_return=True, + bw_fct=bw_factor, + ) + kde_y /= kde_y.max() + hdi_data = compute_hdi_data(data, kde_x, kde_y, hdi_probability) + hdi_x = hdi_data["base"] + n = len(hdi_x) + half_index = n // 2 + x_at_half_index = hdi_x[half_index] + bottom_base = [0] + bottom_lower = [hdi_bounds[0]] + for i in range(len(kde_x)): + if kde_x[i] <= x_at_half_index and kde_x[i] >= hdi_bounds[0]: + bottom_base.append(kde_y[i]) + bottom_lower.append(kde_x[i]) + bottom_upper = [x_at_half_index] * len(bottom_base) + top_base = [0] + top_upper = [hdi_bounds[1]] + for i in range(len(kde_x))[::-1]: + if kde_x[i] >= x_at_half_index and kde_x[i] <= hdi_bounds[1]: + top_base.append(kde_y[i]) + top_upper.append(kde_x[i]) + top_lower = [x_at_half_index] * len(top_base) + stats_and_labels = compute_stats( + data, + kde_x, + kde_y, + hdi_probability, + return_labels=True, + ) + stats = stats_and_labels["stats"] + stats = {"x": stats["y"], "y": stats["x"], "text": stats["text"]} + labels = stats_and_labels["labels"] + labels = { + "x": labels["y"], + "y": labels["x"], + "text": labels["text"], + "text_align": labels["text_align"], + "x_offset": labels["y_offset"], + "y_offset": labels["x_offset"], + } + return { + "distribution": { + "x": kde_y.tolist(), + "y": kde_x.tolist(), + "bandwidth": bandwidth, + }, + "hdi": { + "top": {"base": top_base, "lower": top_lower, "upper": top_upper}, + "bottom": { + "base": bottom_base, + "lower": bottom_lower, + "upper": bottom_upper, + }, + }, + "stats": stats, + "labels": stats_and_labels["labels"], + } + + +def compute_data( + x_data: npt.NDArray, + y_data: npt.NDArray, + x_label: str, + y_label: str, + x_hdi_probability: float, + y_hdi_probability: float, + bw_factor: Optional[float] = None, + bins: Optional[list[int]] = None, +) -> typing.Data: + """Compute effective sample size estimates using the given data. + + Parameters + ---------- + x_data : npt.NDArray + The random variable data for the x-axis. + y_data : npt.NDArray + The random variable data for the y-axis. + x_label : str + The label for the x-axis. + y_label : str + The label for the y-axis. + x_hdi_probability : float + The HDI probability to use when calculating the HDI bounds for the x-axis. + y_hdi_probability : float + The HDI probability to use when calculating the HDI bounds for the y-axis. + bw_factor : float, optional, default is 1.0 if None is given + Multiplicative factor used when calculating the kernel density estimate. + bins : list[int], optional, default is [128, 128] if None is given + The grid points to use when calculating the two-dimensional KDE. + + Returns + ------- + typing.Data + A dictionary of data used for the tool. + """ + if bw_factor is None: + bw_factor = 1.0 + if bins is None: + bins = [128, 128] + + x_data = x_data.reshape(-1) + y_data = y_data.reshape(-1) + + x = m1d_data(x_data, bw_factor, x_hdi_probability)["marginal"] + x_stats = [float(value) for value in x["stats"]["x"]] + y = compute_y_data(y_data, bw_factor, y_hdi_probability) + y_stats = [float(value) for value in y["stats"]["y"]] + xy = compute_xy_data( + x=x_data, + y=y_data, + x_label=x_label, + y_label=y_label, + x_stats=x_stats, + y_stats=y_stats, + ) + return {"x": x, "y": y, "xy": xy} + + +def create_sources(data: typing.Data) -> typing.Sources: + """Create Bokeh sources from the given data that will be bound to glyphs. + + Parameters + ---------- + data : typing.Data + A dictionary of data used for the tool. + + Returns + ------- + typing.Sources + A dictionary of Bokeh ColumnDataSource objects. + """ + output = {} + for figure_name, figure_data in data.items(): + output[figure_name] = {} + for glyph_name, glyph_data in figure_data.items(): + # Remove the bandwidth key so we can use the data directly in a source. + if figure_name in ["x", "y"] and glyph_name == "distribution": + glyph_data.pop("bandwidth") + output[figure_name][glyph_name] = ColumnDataSource(data=glyph_data) + elif figure_name == "y" and glyph_name == "hdi": + output[figure_name][glyph_name] = {} + for glyph_type in ["top", "bottom"]: + output[figure_name][glyph_name].update( + {glyph_type: ColumnDataSource(data=glyph_data[glyph_type])}, + ) + elif figure_name == "xy" and glyph_name == "hdi": + output[figure_name][glyph_name] = {} + for axis in ["x", "y"]: + output[figure_name][glyph_name][axis] = {} + for glyph_type in ["lower", "upper"]: + output[figure_name][glyph_name][axis].update( + { + glyph_type: ColumnDataSource( + data=glyph_data[axis][glyph_type], + ), + }, + ) + else: + output[figure_name][glyph_name] = ColumnDataSource(data=glyph_data) + return output + + +def create_figures(x_rv_name: str, y_rv_name: str) -> typing.Figures: + """Create the Bokeh figures used for the tool. + + Parameters + ---------- + x_rv_name : str + The x-axis label. + y_rv_name : str + The y-axis label. + + Returns + ------- + typing.Figures + A dictionary of Bokeh Figure objects. + """ + output = {} + for figure_name in FIGURE_NAMES: + fig = figure() + if figure_name == "x": + fig = figure( + width=MARGINAL1D_PLOT_WIDTH, + height=MARGINAL1D_PLOT_HEIGHT, + outline_line_color=None, + min_border=None, + ) + fig.yaxis.visible = False + fig.xaxis.visible = False + fig.grid.visible = False + elif figure_name == "y": + fig = figure( + width=MARGINAL1D_PLOT_HEIGHT, + height=MARGINAL1D_PLOT_WIDTH, + outline_line_color=None, + min_border=None, + ) + fig.yaxis.visible = False + fig.xaxis.visible = False + fig.grid.visible = False + elif figure_name == "xy": + fig = figure( + width=MARGINAL2D_PLOT_WIDTH, + height=MARGINAL2D_PLOT_HEIGHT, + outline_line_color="black", + min_border=0, + x_axis_label=x_rv_name, + y_axis_label=y_rv_name, + match_aspect=True, + background_fill_color="#440154", + ) + style_figure(fig) + fig.grid.visible = False + output[figure_name] = fig + output["x"].x_range = output["xy"].x_range + output["y"].y_range = output["xy"].y_range + return output + + +def create_glyphs(data: typing.Data) -> typing.Glyphs: + """Create the glyphs used for the figures of the tool. + + Parameters + ---------- + data : typing.Data + A dictionary of data used for the tool. + + Returns + ------- + typing.Glyphs + A dictionary of Bokeh Glyphs objects. + """ + palette = choose_palette(4) + glyph_color = palette[0] + hover_glyph_color = palette[1] + mean_color = palette[3] + output = {} + for figure_name, _ in data.items(): + output[figure_name] = {} + if figure_name in ["x", "y"]: + output[figure_name] = { + "distribution": { + "glyph": Line( + x="x", + y="y", + line_color=glyph_color, + line_alpha=1.0, + line_width=2.0, + name=f"{figure_name}DistributionGlyph", + ), + "hover_glyph": Line( + x="x", + y="y", + line_color=hover_glyph_color, + line_alpha=1.0, + line_width=2.0, + name=f"{figure_name}DistributionHoverGlyph", + ), + }, + "stats": { + "glyph": Circle( + x="x", + y="y", + size=10, + line_color="white", + fill_color=glyph_color, + fill_alpha=1.0, + name=f"{figure_name}StatsGlyph", + ), + "hover_glyph": Circle( + x="x", + y="y", + size=10, + line_color="white", + fill_color=hover_glyph_color, + fill_alpha=1.0, + name=f"{figure_name}StatsHoverGlyph", + ), + }, + } + if figure_name == "xy": + output[figure_name] = { + "distribution": Image( + image="image", + x="x", + y="y", + dw="dw", + dw_units="data", + dh="dh", + dh_units="data", + color_mapper=LinearColorMapper(palette="Viridis256"), + name=f"{figure_name}Glyph", + ), + "hdi": { + "x": { + "lower": { + "glyph": Line( + x="x", + y="y", + line_color="white", + line_alpha=0.7, + name=f"{figure_name}XLowerBoundHDIGlyph", + ), + "hover_glyph": Line( + x="x", + y="y", + line_color="white", + line_alpha=1.0, + name=f"{figure_name}XLowerBoundHDIHoverGlyph", + ), + }, + "upper": { + "glyph": Line( + x="x", + y="y", + line_color="white", + line_alpha=0.7, + name=f"{figure_name}XUpperBoundHDIGlyph", + ), + "hover_glyph": Line( + x="x", + y="y", + line_color="white", + line_alpha=1.0, + name=f"{figure_name}XUpperBoundHDIHoverGlyph", + ), + }, + }, + "y": { + "lower": { + "glyph": Line( + x="x", + y="y", + line_color="white", + line_alpha=0.7, + name=f"{figure_name}YLowerBoundHDIGlyph", + ), + "hover_glyph": Line( + x="x", + y="y", + line_color="white", + line_alpha=1.0, + name=f"{figure_name}YLowerBoundHDIHoverGlyph", + ), + }, + "upper": { + "glyph": Line( + x="x", + y="y", + line_color="white", + line_alpha=0.7, + name=f"{figure_name}YUpperBoundHDIGlyph", + ), + "hover_glyph": Line( + x="x", + y="y", + line_color="white", + line_alpha=1.0, + name=f"{figure_name}YUpperBoundHDIHoverGlyph", + ), + }, + }, + }, + "stats": { + "glyph": Circle( + x="x", + y="y", + size=10, + line_color="red", + fill_color=mean_color, + fill_alpha=1.0, + name=f"{figure_name}MeanGlyph", + ), + "hover_glyph": Circle( + x="x", + y="y", + size=10, + line_color="white", + fill_color=mean_color, + fill_alpha=1.0, + name=f"{figure_name}MeanHoverGlyph", + ), + }, + } + return output + + +def add_glyphs( + figures: typing.Figures, + glyphs: typing.Glyphs, + sources: typing.Sources, +) -> None: + """Bind source data to glyphs and add the glyphs to the given figures. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + glyphs : typing.Glyphs + A dictionary of Bokeh Glyphs objects. + sources : typing.Sources + A dictionary of Bokeh ColumnDataSource objects. + + Returns + ------- + None + Adds data bound glyphs to the given figures directly. + """ + for figure_name, fig in figures.items(): + figure_source = sources[figure_name] + figure_glyphs = glyphs[figure_name] + if figure_name in ["x", "y"]: + for glyph_type in ["distribution", "stats"]: + glyph_source = figure_source[glyph_type] + figure_glyph = figure_glyphs[glyph_type] + fig.add_glyph( + source_or_glyph=glyph_source, + glyph=figure_glyph["glyph"], + hover_glyph=figure_glyph["hover_glyph"], + name=figure_glyph["glyph"].name, + ) + if figure_name == "xy": + fig.add_glyph( + source_or_glyph=figure_source["distribution"], + glyph=figure_glyphs["distribution"], + name=figure_glyphs["distribution"].name, + ) + fig.add_glyph( + source_or_glyph=figure_source["hdi"]["x"]["lower"], + glyph=figure_glyphs["hdi"]["x"]["lower"]["glyph"], + hover_glyph=figure_glyphs["hdi"]["x"]["lower"]["hover_glyph"], + name=figure_glyphs["hdi"]["x"]["lower"]["glyph"].name, + ) + fig.add_glyph( + source_or_glyph=figure_source["hdi"]["x"]["upper"], + glyph=figure_glyphs["hdi"]["x"]["upper"]["glyph"], + hover_glyph=figure_glyphs["hdi"]["x"]["upper"]["hover_glyph"], + name=figure_glyphs["hdi"]["x"]["upper"]["glyph"].name, + ) + fig.add_glyph( + source_or_glyph=figure_source["hdi"]["y"]["lower"], + glyph=figure_glyphs["hdi"]["y"]["lower"]["glyph"], + hover_glyph=figure_glyphs["hdi"]["y"]["lower"]["hover_glyph"], + name=figure_glyphs["hdi"]["y"]["lower"]["glyph"].name, + ) + fig.add_glyph( + source_or_glyph=figure_source["hdi"]["y"]["upper"], + glyph=figure_glyphs["hdi"]["y"]["upper"]["glyph"], + hover_glyph=figure_glyphs["hdi"]["y"]["upper"]["hover_glyph"], + name=figure_glyphs["hdi"]["y"]["upper"]["glyph"].name, + ) + fig.add_glyph( + source_or_glyph=figure_source["stats"], + glyph=figure_glyphs["stats"]["glyph"], + hover_glyph=figure_glyphs["stats"]["hover_glyph"], + name=figure_glyphs["stats"]["glyph"].name, + ) + + +def create_annotations(sources: typing.Sources) -> typing.Annotations: + """Create any annotations for the figures of the tool. + + Parameters + ---------- + source : typing.Sources + A dictionary of Bokeh ColumnDataSource objects. + + Returns + ------- + typing.Annotations + A dictionary of Bokeh Annotation objects. + """ + palette = choose_palette(1) + color = palette[0] + return { + "x": Band( + base="base", + lower="lower", + upper="upper", + source=sources["x"]["hdi"], + level="underlay", + fill_color=color, + fill_alpha=0.2, + line_color=None, + name="xHDIAnnotation", + ), + "y": { + "top": Band( + base="base", + lower="lower", + upper="upper", + source=sources["y"]["hdi"]["top"], + level="underlay", + fill_color=color, + fill_alpha=0.2, + line_color=None, + name="yTopHDIAnnotation", + ), + "bottom": Band( + base="base", + lower="lower", + upper="upper", + source=sources["y"]["hdi"]["bottom"], + level="underlay", + fill_color=color, + fill_alpha=0.2, + line_color=None, + name="yBottomHDIAnnotation", + ), + }, + } + + +def add_annotations(figures: typing.Figures, annotations: typing.Annotations) -> None: + """Add the given annotations to the given figures of the tool. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + annotations : typing.Annotations + A dictionary of Bokeh Annotation objects. + + Returns + ------- + None + Adds annotations directly to the given figures. + """ + figures["x"].add_layout(annotations["x"]) + figures["y"].add_layout(annotations["y"]["top"]) + figures["y"].add_layout(annotations["y"]["bottom"]) + + +def create_tooltips( + x_rv_name: str, + y_rv_name: str, + figures: typing.Figures, +) -> typing.Tooltips: + """Create hover tools for the glyphs used in the figures of the tool. + + Parameters + ---------- + x_rv_name : str + The name of the random variable along the x-axis. + y_rv_name : str + The name of the random variable along the y-axis. + figures : typing.Figures + A dictionary of Bokeh Figure objects. + + Returns + ------- + typing.Tooltips + A dictionary of Bokeh HoverTools objects. + """ + output = {} + for figure_name, fig in figures.items(): + output[figure_name] = {} + distribution_tips = [] + stats_tips = [] + distribution_renderers = None + stats_renderers = None + if figure_name in ["x", "y"]: + distribution_renderers = filter_renderers( + figure=fig, + search="DistributionGlyph", + substring=True, + ) + stats_renderers = filter_renderers( + figure=fig, + search="StatsGlyph", + substring=True, + ) + if figure_name == "x": + distribution_tips = [(x_rv_name, "@x")] + stats_tips = [("", "@text")] + if figure_name == "y": + distribution_tips = [(y_rv_name, "@y")] + stats_tips = [("", "@text")] + output[figure_name] = { + "distribution": HoverTool( + renderers=distribution_renderers, + tooltips=distribution_tips, + ), + "stats": HoverTool(renderers=stats_renderers, tooltips=stats_tips), + } + if figure_name == "xy": + stats_renderers = filter_renderers( + figure=fig, + search="MeanGlyph", + substring=True, + ) + x_lower = filter_renderers(figure=fig, search="XLowerBound", substring=True) + x_upper = filter_renderers(figure=fig, search="XUpperBound", substring=True) + y_lower = filter_renderers(figure=fig, search="YLowerBound", substring=True) + y_upper = filter_renderers(figure=fig, search="YUpperBound", substring=True) + output[figure_name]["mean"] = HoverTool( + renderers=stats_renderers, + tooltips=[(x_rv_name, "@x"), (y_rv_name, "@y")], + ) + output[figure_name]["hdi"] = { + "x": { + "lower": HoverTool(renderers=x_lower, tooltips=[(x_rv_name, "@x")]), + "upper": HoverTool(renderers=x_upper, tooltips=[(x_rv_name, "@x")]), + }, + "y": { + "lower": HoverTool(renderers=y_lower, tooltips=[(y_rv_name, "@y")]), + "upper": HoverTool(renderers=y_upper, tooltips=[(y_rv_name, "@y")]), + }, + } + return output + + +def add_tooltips(figures: typing.Figures, tooltips: typing.Tooltips) -> None: + """Add the given tools to the figures. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + tooltips : typing.Tooltips + A dictionary of Bokeh HoverTools objects. + + Returns + ------- + None + Adds the tooltips directly to the given figures. + """ + figures["xy"].add_tools(tooltips["xy"]["mean"]) + figures["xy"].add_tools(tooltips["xy"]["hdi"]["x"]["lower"]) + figures["xy"].add_tools(tooltips["xy"]["hdi"]["x"]["upper"]) + figures["xy"].add_tools(tooltips["xy"]["hdi"]["y"]["lower"]) + figures["xy"].add_tools(tooltips["xy"]["hdi"]["y"]["upper"]) + figures["x"].add_tools(tooltips["x"]["distribution"]) + figures["x"].add_tools(tooltips["x"]["stats"]) + figures["y"].add_tools(tooltips["y"]["distribution"]) + figures["y"].add_tools(tooltips["y"]["stats"]) + + +def create_widgets( + x_rv_name: str, + y_rv_name: str, + rv_names: list[str], + bw_factor: float, + x_bw: float, + y_bw: float, +) -> typing.Widgets: + """Create the widgets used in the tool. + + Parameters + ---------- + x_rv_name : str + The name of the random variable along the x-axis. + y_rv_name : str + The name of the random variable along the y-axis. + rv_names : list[str] + A list of all available random variable names. + bw_factor : float + Multiplicative factor used when calculating the kernel density estimate. + x_bw : float + The bandwidth used to calculate the KDE along the x-axis. + y_bw : float + The bandwidth used to calculate the KDE along the y-axis. + + Returns + ------- + typing.Widgets + A dictionary of Bokeh widget objects. + """ + return { + "x_rv_select": Select(value=x_rv_name, options=rv_names, title="Query (x)"), + "y_rv_select": Select(value=y_rv_name, options=rv_names, title="Query (y)"), + "x_hdi_slider": Slider(start=1, end=99, step=1, value=89, title="HDI (x)"), + "y_hdi_slider": Slider(start=1, end=99, step=1, value=89, title="HDI (y)"), + "x_bw_div": Div(text=f"Bandwidth {x_rv_name}: {bw_factor * x_bw}"), + "y_bw_div": Div(text=f"Bandwidth {y_rv_name}: {bw_factor * y_bw}"), + } + + +def help_page() -> Div: + """Help tab for the tool. + + Returns + ------- + Div + Bokeh Div widget containing the help tab information. + """ + text = """ +

+ Joint plot +

+

+ A joint plot shows univariate marginals along the x and y axes. The + central figure shows the bivariate marginal of both random variables. +

+ """ + return Div( + text=text, + disable_math=False, + min_width=MARGINAL1D_PLOT_WIDTH + MARGINAL2D_PLOT_WIDTH, + ) + + +def create_figure_grid(figures: typing.Figures) -> Row: + """Layout the given figures in a grid, and make one toolbar. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + + Returns + ------- + Row + A Bokeh layout object. + """ + toolbar = create_toolbar(figures) + grid_box = GridBox( + children=[ + [figures["x"], 0, 0], + [figures["xy"], 1, 0], + [figures["y"], 1, 1], + ], + sizing_mode=None, + ) + return Row(children=[grid_box, toolbar]) + + +def create_view(widgets: typing.Widgets, figures: typing.Figures) -> Tabs: + """Create the tool view. + + Parameters + ---------- + widgets : typing.Widgets + A dictionary of Bokeh widget objects. + figures : typing.Figures + A dictionary of Bokeh Figure objects. + + Returns + ------- + Tabs + Bokeh Tabs objects. + """ + help_panel = Panel(child=help_page(), title="Help", name="helpPanel") + figure_grid = create_figure_grid(figures) + tool_panel = Panel( + child=Row( + children=[ + Column( + children=[ + Row( + children=[ + widgets["x_rv_select"], + widgets["y_rv_select"], + ], + ), + figure_grid, + ], + ), + Column( + children=[ + widgets["x_hdi_slider"], + widgets["y_hdi_slider"], + widgets["x_bw_div"], + widgets["y_bw_div"], + ], + ), + ], + ), + title="Marginal 2D", + name="marginalToolPanel", + ) + return Tabs(tabs=[tool_panel, help_panel]) + + +def update( + x_rv_data: npt.NDArray, + y_rv_data: npt.NDArray, + x_rv_name: str, + y_rv_name: str, + sources: typing.Sources, + figures: typing.Figures, + tooltips: typing.Tooltips, + x_hdi_probability: float, + y_hdi_probability: float, + bw_factor: float, +) -> tuple[float, float]: + """Update the tool based on user interaction. + + Parameters + ---------- + x_rv_data : npt.NDArray + A 2D NumPy array where the length of the first dimension is the number of chains + of the model, and the length of the second dimension is the number of draws of + the model. + y_rv_data : npt.NDArray + A 2D NumPy array where the length of the first dimension is the number of chains + of the model, and the length of the second dimension is the number of draws of + the model. + x_rv_name : str + The name of the random variable along the x-axis. + y_rv_name : str + The name of the random variable along the y-axis. + sources : typing.Sources + A dictionary of Bokeh ColumnDataSource objects. + figures : typing.Figures + A dictionary of Bokeh Figure objects. + tooltips : typing.Tooltips + A dictionary of Bokeh HoverTools objects. + x_hdi_probability : float + The HDI probability to use when calculating the HDI bounds for the x-axis. + y_hdi_probability : float + The HDI probability to use when calculating the HDI bounds for the y-axis. + bw_factor : float + Multiplicative factor used when calculating the kernel density estimate. + + Returns + ------- + None + Updates Bokeh ColumnDataSource objects. + """ + computed_data = compute_data( + x_rv_data, + y_rv_data, + x_rv_name, + y_rv_name, + x_hdi_probability, + y_hdi_probability, + bw_factor, + ) + x_bw = computed_data["x"]["distribution"].pop("bandwidth") + y_bw = computed_data["y"]["distribution"].pop("bandwidth") + for figure_name, figure_data in computed_data.items(): + figure_sources = sources[figure_name] + if figure_name == "x": + dist = figure_sources["distribution"] + dist.data = figure_data["distribution"] + figure_sources["hdi"].data = figure_data["hdi"] + figure_sources["stats"].data = figure_data["stats"] + if figure_name == "y": + dist = figure_sources["distribution"] + hdi_top = figure_sources["hdi"]["top"] + hdi_bottom = figure_sources["hdi"]["bottom"] + dist.data = figure_data["distribution"] + hdi_top.data = figure_data["hdi"]["top"] + hdi_bottom.data = figure_data["hdi"]["bottom"] + figure_sources["stats"].data = figure_data["stats"] + if figure_name == "xy": + dist = figure_sources["distribution"] + hdi_x_lower = figure_sources["hdi"]["x"]["lower"] + hdi_x_upper = figure_sources["hdi"]["x"]["upper"] + hdi_y_lower = figure_sources["hdi"]["y"]["lower"] + hdi_y_upper = figure_sources["hdi"]["y"]["upper"] + dist.data = figure_data["distribution"] + hdi_x_lower.data = figure_data["hdi"]["x"]["lower"] + hdi_x_upper.data = figure_data["hdi"]["x"]["upper"] + hdi_y_lower.data = figure_data["hdi"]["y"]["lower"] + hdi_y_upper.data = figure_data["hdi"]["y"]["upper"] + figure_sources["stats"].data = figure_data["stats"] + figures["xy"].xaxis.axis_label = x_rv_name + figures["xy"].yaxis.axis_label = y_rv_name + tooltips["xy"]["mean"].tooltips = [ + (x_rv_name, "@x"), + (y_rv_name, "@y"), + ] + tooltips["xy"]["hdi"]["x"]["lower"].tooltips = [(x_rv_name, "@x")] + tooltips["xy"]["hdi"]["x"]["upper"].tooltips = [(x_rv_name, "@x")] + tooltips["xy"]["hdi"]["y"]["lower"].tooltips = [(y_rv_name, "@y")] + tooltips["xy"]["hdi"]["y"]["upper"].tooltips = [(y_rv_name, "@y")] + return (x_bw, y_bw) diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/plotting.py b/src/beanmachine/ppl/diagnostics/tools/helpers/plotting.py new file mode 100644 index 0000000000..ab151a3ba3 --- /dev/null +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/plotting.py @@ -0,0 +1,122 @@ +"""Plotting utilities for the diagnostics tools.""" +from __future__ import annotations + +from bokeh.core.property.nullable import Nullable +from bokeh.core.property.primitive import Null +from bokeh.core.property.wrappers import PropertyValueList +from bokeh.models.renderers import GlyphRenderer +from bokeh.models.tools import ProxyToolbar, ResetTool, SaveTool, ToolbarBox +from bokeh.palettes import Colorblind +from bokeh.plotting.figure import Figure + + +def style_figure(figure: Figure) -> None: + """Give the given figure a uniform style. + + Parameters + ---------- + fig : Figure + Bokeh Figure object. + + Returns + ------- + None + Directly applies a uniform styling to the given figure. + """ + figure.grid.grid_line_alpha = 0.3 + figure.grid.grid_line_color = "grey" + figure.grid.grid_line_width = 0.3 + figure.xaxis.minor_tick_line_color = "grey" + figure.yaxis.minor_tick_line_color = "grey" + + +def choose_palette(n: int) -> tuple: + """Choose an appropriate palette from Bokeh's Colorblind palette. + + Parameters + ---------- + n : int + The number of colors to choose from the Colorblind palette. + + Returns + ------- + tuple + A tuple object that contains color information. + """ + palette_indices = [key for key in Colorblind.keys() if n <= key] + if not palette_indices: + palette_index = max(Colorblind.keys()) + else: + palette_index = min(palette_indices) + return Colorblind[palette_index] + + +def create_toolbar(figures: dict[str, Figure]) -> ToolbarBox: + """Create a single toolbar for multiple figures. + + This will also remove any ``HoverTool`` tools on the figures. These are removed from + figure groupings as there are sometimes many different hover tools for a single + figure. Aggregating all the hover tools into a single toolbar will make the toolbar + look like it only has hover tools in it, and nothing else. + + Parameters + ---------- + figures : dict[str, Figure] + A dictionary of Bokeh figures. + + Returns + ------- + ToolbarBox + A single toolbar for the given Bokeh figures. + """ + toolbars = [] + for _, figure in figures.items(): + toolbars.append(figure.toolbar) + figure.toolbar_location = Nullable(Null)._default + tools = [] + for toolbar in toolbars: + tools.extend(toolbar.tools) + tools = [tool for tool in tools if type(tool).__name__ != "HoverTool"] + if len(tools) == 0: + tools = [SaveTool(), ResetTool()] + return ToolbarBox( + toolbar=ProxyToolbar(toolbars=toolbars, tools=tools), + toolbar_location="right", + ) + + +def filter_renderers( + figure: Figure, + search: str, + glyph_type: str = "GlyphRenderer", + substring: bool = False, +) -> list[GlyphRenderer]: + """Filter Bokeh figure renderers given the search string. + + Parameters + ---------- + figure : Figure + A Bokeh figure to filter renderers from. + search : str + The search string to filter for. + glyph_type : str, optional default is "GlyphRenderer" + The glyph type. + substring : bool, optional default is ``False`` + Flag to indicate if we should use the search term as a substring search. + - ``False`` indicates the name of the glyph == search. + - ``True`` indicates the search is a substring of the glyph name. + + Returns + ------- + list[GlyphRenderer] + A list of Bokeh glyph renderer objects. + """ + output = [] + renderers = PropertyValueList(figure.renderers) + for renderer in renderers: + if renderer.name is not None and type(renderer).__name__ == glyph_type: + if substring and search in renderer.name: + output.append(renderer) + if not substring and renderer.name == search: + output.append(renderer) + return output diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/trace.py b/src/beanmachine/ppl/diagnostics/tools/helpers/trace.py new file mode 100644 index 0000000000..95d8a975ea --- /dev/null +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/trace.py @@ -0,0 +1,816 @@ +"""Methods used to generate the diagnostic tool.""" +from __future__ import annotations + +import arviz as az +import beanmachine.ppl.diagnostics.tools.typing.trace as typing +import numpy as np +import numpy.typing as npt + +from beanmachine.ppl.diagnostics.tools.helpers import marginal1d as m1d +from beanmachine.ppl.diagnostics.tools.helpers.plotting import ( + choose_palette, + create_toolbar, + filter_renderers, + style_figure, +) +from bokeh.core.property.wrappers import PropertyValueList +from bokeh.models.annotations import Legend, LegendItem +from bokeh.models.glyphs import Circle, Line, Quad +from bokeh.models.layouts import Column, Row + +from bokeh.models.ranges import Range1d +from bokeh.models.sources import ColumnDataSource +from bokeh.models.tools import HoverTool +from bokeh.models.widgets import Div +from bokeh.models.widgets.inputs import Select +from bokeh.models.widgets.panels import Panel, Tabs +from bokeh.models.widgets.sliders import Slider +from bokeh.plotting.figure import figure + + +PLOT_WIDTH = 400 +PLOT_HEIGHT = 500 +TRACE_PLOT_WIDTH = 600 +FIGURE_NAMES = ["marginals", "forests", "traces", "ranks"] + + +def compute_data( + data: npt.NDArray, + bw_factor: float, + hdi_probability: float, +) -> typing.Data: + """Compute effective sample size estimates using the given data. + + Parameters + ---------- + data : npt.NDArray + A 2D NumPy array where the length of the first dimension is the number of chains + of the model, and the length of the second dimension is the number of draws of + the model. + bw_factor : float + Multiplicative factor used when calculating the kernel density estimate. + hdi_probability : float + The HDI probability to use when calculating the HDI bounds. + + Returns + ------- + typing.Data + A dictionary of data used for the tool. + """ + num_chains, num_draws = data.shape + num_samples = num_chains * num_draws + rank_data = az.plots.plot_utils.compute_ranks(data) + n_bins = int(np.ceil(2 * np.log2(rank_data.shape[1])) + 1) + bins = np.histogram_bin_edges(rank_data, bins=n_bins, range=(0, rank_data.size)) + hist_bins = len(bins) + output = {} + for figure_name in FIGURE_NAMES: + output[figure_name] = {} + for chain in range(num_chains): + chain_index = chain + 1 + chain_name = f"chain{chain_index}" + output[figure_name][chain_name] = {} + chain_data = data[chain] + marginal = m1d.compute_data(chain_data, bw_factor, hdi_probability) + marginal = marginal["marginal"]["distribution"] + mean = float(np.array(marginal["x"]).mean()) + if figure_name == "marginals": + output[figure_name][chain_name] = { + "line": {"x": marginal["x"], "y": marginal["y"]}, + "chain": chain_index, + "mean": mean, + "bandwidth": marginal["bandwidth"], + } + if figure_name == "forests": + hdi = az.stats.hdi(chain_data, hdi_probability) + output[figure_name][chain_name] = { + "line": {"x": hdi, "y": [chain_index] * 2}, + "circle": {"x": [mean], "y": [chain_index]}, + "chain": chain_index, + "mean": mean, + } + if figure_name == "traces": + output[figure_name][chain_name] = { + "line": {"x": np.arange(0, num_draws, 1), "y": chain_data}, + "chain": chain_index, + "mean": mean, + "bandwidth": marginal["bandwidth"], + } + if figure_name == "ranks": + _, histogram, _ = az.stats.density_utils.histogram( + rank_data[chain, :], + bins=n_bins, + ) + normed_hist = histogram / histogram.max() + chain_rank_mean = normed_hist.mean() + left = bins[:-1] + top = normed_hist + chain + right = bins[1:] + bottom = np.zeros(hist_bins - 1) + chain + draws = [f"{int(b[0]):0,}-{int(b[1]):0,}" for b in zip(left, right)] + quad = { + "left": left.tolist(), + "right": right.tolist(), + "top": top.tolist(), + "bottom": bottom.tolist(), + "draws": draws, + "rank": normed_hist.tolist(), + } + x = np.arange(0, num_samples, 1) + line = {"x": x.tolist(), "y": [chain_rank_mean + chain] * len(x)} + output[figure_name][chain_name] = { + "quad": quad, + "line": line, + "chain": chain_index, + "rank_mean": chain_index - chain_rank_mean, + "mean": histogram.mean(), + } + return output + + +def create_sources(data: typing.Data) -> typing.Sources: + """Create Bokeh sources from the given data that will be bound to glyphs. + + Parameters + ---------- + data : typing.Data + A dictionary of data used for the tool. + + Returns + ------- + typing.Sources + A dictionary of Bokeh ColumnDataSource objects. + """ + output = {} + for figure_name, figure_data in data.items(): + output[figure_name] = {} + for i, (chain_name, chain_data) in enumerate(figure_data.items()): + output[figure_name][chain_name] = {} + n = len(chain_data["line"]["x"]) + chain_index_list = [chain_data["chain"]] * n + chain_mean_list = [chain_data["mean"]] * n + if figure_name == "marginals": + output[figure_name][chain_name]["line"] = ColumnDataSource( + { + "x": chain_data["line"]["x"], + "y": chain_data["line"]["y"], + "chain": chain_index_list, + "mean": chain_mean_list, + }, + ) + if figure_name == "forests": + output[figure_name][chain_name]["line"] = ColumnDataSource( + { + "x": chain_data["line"]["x"], + "y": chain_data["line"]["y"], + "chain": chain_index_list, + }, + ) + output[figure_name][chain_name]["circle"] = ColumnDataSource( + { + "x": chain_data["circle"]["x"], + "y": chain_data["circle"]["y"], + "chain": [chain_data["chain"]], + }, + ) + if figure_name == "traces": + output[figure_name][chain_name]["line"] = ColumnDataSource( + { + "x": chain_data["line"]["x"], + "y": chain_data["line"]["y"], + "chain": chain_index_list, + "mean": ([chain_data["mean"]] * len(chain_data["line"]["x"])), + }, + ) + if figure_name == "ranks": + output[figure_name][chain_name]["line"] = ColumnDataSource( + { + "x": chain_data["line"]["x"], + "y": chain_data["line"]["y"], + "chain": chain_index_list, + "rank_mean": ( + [chain_data["rank_mean"]] * len(chain_data["line"]["x"]) + ), + }, + ) + output[figure_name][chain_name]["quad"] = ColumnDataSource( + { + "left": chain_data["quad"]["left"], + "top": chain_data["quad"]["top"], + "right": chain_data["quad"]["right"], + "bottom": chain_data["quad"]["bottom"], + "chain": [i + 1] * len(chain_data["quad"]["left"]), + "draws": chain_data["quad"]["draws"], + "rank": chain_data["quad"]["rank"], + }, + ) + return output + + +def create_figures(rv_name: str, num_chains: int) -> typing.Figures: + """Create the Bokeh figures used for the tool. + + Parameters + ---------- + rv_name : str + The string representation of the random variable data. + num_chains : int + The number of chains of the model. + + Returns + ------- + typing.Figures + A dictionary of Bokeh Figure objects. + """ + output = {} + for figure_name in FIGURE_NAMES: + fig = figure() + if figure_name == "marginals": + fig = figure( + plot_width=PLOT_WIDTH, + plot_height=PLOT_HEIGHT, + outline_line_color="black", + title="Marginal", + x_axis_label=rv_name, + x_range=Range1d(), + ) + style_figure(fig) + if figure_name == "forests": + fig = figure( + plot_width=PLOT_WIDTH, + plot_height=PLOT_HEIGHT, + outline_line_color="black", + title="Forest", + x_axis_label=rv_name, + y_axis_label="Chain", + x_range=Range1d(), + ) + style_figure(fig) + fig.yaxis.minor_tick_line_color = None + fig.yaxis.ticker = list(range(1, num_chains + 1)) + if figure_name == "traces": + fig = figure( + plot_width=TRACE_PLOT_WIDTH, + plot_height=PLOT_HEIGHT, + outline_line_color="black", + title="Trace", + x_axis_label="Draw from single chain", + y_axis_label=rv_name, + y_range=Range1d(), + ) + style_figure(fig) + fig.yaxis.minor_tick_line_color = "grey" + if figure_name == "ranks": + fig = figure( + plot_width=TRACE_PLOT_WIDTH, + plot_height=PLOT_HEIGHT, + outline_line_color="black", + title="Rank", + x_axis_label="Rank from all chains", + y_axis_label="Chain", + ) + style_figure(fig) + fig.yaxis.minor_tick_line_color = None + fig.yaxis.ticker = list(range(1, num_chains + 1)) + output[figure_name] = fig + return output + + +def create_glyphs(data: typing.Data, num_chains: int) -> typing.Glyphs: + """Create the glyphs used for the figures of the tool. + + Parameters + ---------- + data : typing.Data + A dictionary of data used for the tool. + num_chains : int + The number of chains of the model. + + Returns + ------- + typing.Glyphs + A dictionary of Bokeh Glyphs objects. + """ + palette = choose_palette(num_chains) + output = {} + for figure_name, figure_data in data.items(): + output[figure_name] = {} + for i, (chain_name, _) in enumerate(figure_data.items()): + output[figure_name][chain_name] = {} + color = palette[i] + if figure_name == "marginals": + output[figure_name][chain_name]["line"] = { + "glyph": Line( + x="x", + y="y", + line_color=color, + line_alpha=0.7, + line_width=2.0, + name=f"{figure_name}{chain_name.title()}LineGlyph", + ), + "hover_glyph": Line( + x="x", + y="y", + line_color=color, + line_alpha=1.0, + line_width=2.0, + name=f"{figure_name}{chain_name.title()}LineHoverGlyph", + ), + } + if figure_name == "forests": + output[figure_name][chain_name] = { + "line": { + "glyph": Line( + x="x", + y="y", + line_color=color, + line_alpha=0.7, + line_width=2.0, + name=f"{figure_name}{chain_name.title()}LineGlyph", + ), + "hover_glyph": Line( + x="x", + y="y", + line_color=color, + line_alpha=1.0, + line_width=2.0, + name=f"{figure_name}{chain_name.title()}LineHoverGlyph", + ), + }, + "circle": { + "glyph": Circle( + x="x", + y="y", + size=10, + fill_color=color, + fill_alpha=0.7, + line_color="white", + name=f"{figure_name}{chain_name.title()}CircleGlyph", + ), + "hover_glyph": Circle( + x="x", + y="y", + size=10, + fill_color=color, + fill_alpha=1.0, + line_color="black", + name=f"{figure_name}{chain_name.title()}CircleHoverGlyph", + ), + }, + } + if figure_name == "traces": + output[figure_name][chain_name]["line"] = { + "glyph": Line( + x="x", + y="y", + line_color=color, + line_alpha=0.6, + line_width=0.6, + name=f"{figure_name}{chain_name.title()}LineGlyph", + ), + "hover_glyph": Line( + x="x", + y="y", + line_color=color, + line_alpha=0.6, + line_width=1.0, + name=f"{figure_name}{chain_name.title()}LineHoverGlyph", + ), + } + if figure_name == "ranks": + output[figure_name][chain_name] = { + "quad": { + "glyph": Quad( + left="left", + top="top", + right="right", + bottom="bottom", + fill_color=color, + fill_alpha=0.7, + line_color="white", + name=f"{figure_name}{chain_name.title()}QuadGlyph", + ), + "hover_glyph": Quad( + left="left", + top="top", + right="right", + bottom="bottom", + fill_color=color, + fill_alpha=1.0, + line_color="black", + name=f"{figure_name}{chain_name.title()}QuadHoverGlyph", + ), + }, + "line": { + "glyph": Line( + x="x", + y="y", + line_color="grey", + line_alpha=0.7, + line_width=3.0, + line_dash="dashed", + name=f"{figure_name}{chain_name.title()}LineGlyph", + ), + "hover_glyph": Line( + x="x", + y="y", + line_color="grey", + line_alpha=1.0, + line_width=3.0, + line_dash="solid", + name=f"{figure_name}{chain_name.title()}LineGlyph", + ), + }, + } + return output + + +def add_glyphs( + figures: typing.Figures, + glyphs: typing.Glyphs, + sources: typing.Sources, + num_chains: int, +) -> None: + """Bind source data to glyphs and add the glyphs to the given figures. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + glyphs : typing.Glyphs + A dictionary of Bokeh Glyphs objects. + sources : typing.Sources + A dictionary of Bokeh ColumnDataSource objects. + num_chains : int + The number of chains of the model. + + Returns + ------- + None + Adds data bound glyphs to the given figures directly. + """ + range_min = [] + range_max = [] + for figure_name, figure_sources in sources.items(): + fig = figures[figure_name] + for chain_name, source in figure_sources.items(): + chain_glyphs = glyphs[figure_name][chain_name] + fig.add_glyph( + source_or_glyph=source["line"], + glyph=chain_glyphs["line"]["glyph"], + hover_glyph=chain_glyphs["line"]["hover_glyph"], + name=chain_glyphs["line"]["glyph"].name, + ) + if figure_name == "marginals": + range_min.append(min(source["line"].data["x"])) + range_max.append(max(source["line"].data["x"])) + if figure_name == "forests": + fig.add_glyph( + source_or_glyph=source["circle"], + glyph=chain_glyphs["circle"]["glyph"], + hover_glyph=chain_glyphs["circle"]["hover_glyph"], + name=chain_glyphs["circle"]["glyph"].name, + ) + if figure_name == "ranks": + fig.add_glyph( + source_or_glyph=source["quad"], + glyph=chain_glyphs["quad"]["glyph"], + hover_glyph=chain_glyphs["quad"]["hover_glyph"], + name=chain_glyphs["quad"]["glyph"].name, + ) + range_ = Range1d(start=min(range_min), end=max(range_max)) + figures["marginals"].x_range = range_ + figures["forests"].x_range = range_ + figures["traces"].y_range = range_ + + +def create_annotations(figures: typing.Figures, num_chains: int) -> typing.Annotations: + """Create any annotations for the figures of the tool. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + num_chains : int + The number of chains of the model. + + Returns + ------- + typing.Annotations + A dictionary of Bokeh Annotation objects. + """ + renderers = [] + for _, fig in figures.items(): + renderers.extend(PropertyValueList(fig.renderers)) + legend_items = [] + for chain in range(num_chains): + chain_index = chain + 1 + chain_name = f"chain{chain_index}" + legend_items.append( + LegendItem( + renderers=[ + renderer + for renderer in renderers + if chain_name in renderer.name.lower() + ], + label=chain_name, + ), + ) + legend = Legend( + items=legend_items, + orientation="horizontal", + border_line_color="black", + click_policy="hide", + ) + return {"traces": {"legend": legend}, "ranks": {"legend": legend}} + + +def add_annotations(figures: typing.Figures, annotations: typing.Annotations) -> None: + """Add the given annotations to the given figures of the tool. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + annotations : typing.Annotations + A dictionary of Bokeh Annotation objects. + + Returns + ------- + None + Adds annotations directly to the given figures. + """ + for figure_name, figure_annotations in annotations.items(): + fig = figures[figure_name] + for _, annotation in figure_annotations.items(): + fig.add_layout(annotation, "below") + + +def create_tooltips( + rv_name: str, + figures: typing.Figures, + num_chains: int, +) -> typing.Tooltips: + """Create hover tools for the glyphs used in the figures of the tool. + + Parameters + ---------- + rv_name : str + The string representation of the random variable data. + figures : typing.Figures + A dictionary of Bokeh Figure objects. + num_chains : int + The number of chains of the model. + + Returns + ------- + typing.Tooltips + A dictionary of Bokeh HoverTools objects. + """ + output = {} + for figure_name, fig in figures.items(): + output[figure_name] = [] + for chain in range(num_chains): + chain_index = chain + 1 + chain_name = f"chain{chain_index}" + if figure_name == "marginals": + glyph_name = f"{figure_name}{chain_name.title()}LineGlyph" + output[figure_name].append( + HoverTool( + renderers=filter_renderers(fig, glyph_name), + tooltips=[ + ("Chain", "@chain"), + ("Mean", "@mean"), + (rv_name, "@x"), + ], + ), + ) + if figure_name == "forests": + glyph_name = f"{figure_name}{chain_name.title()}CircleGlyph" + output[figure_name].append( + HoverTool( + renderers=filter_renderers(fig, glyph_name), + tooltips=[("Chain", "@chain"), ("Mean", "@x")], + ), + ) + if figure_name == "traces": + glyph_name = f"{figure_name}{chain_name.title()}LineGlyph" + output[figure_name].append( + HoverTool( + renderers=filter_renderers(fig, glyph_name), + tooltips=[ + ("Chain", "@chain"), + ("Mean", "@mean"), + (rv_name, "@y"), + ], + ), + ) + if figure_name == "ranks": + glyph_name = f"{figure_name}{chain_name.title()}LineGlyph" + output[figure_name].append( + HoverTool( + renderers=filter_renderers(fig, glyph_name), + tooltips=[("Chain", "@chain"), ("Rank mean", "@rank_mean")], + ), + ) + glyph_name = f"{figure_name}{chain_name.title()}QuadGlyph" + output[figure_name].append( + HoverTool( + renderers=filter_renderers(fig, glyph_name), + tooltips=[ + ("Chain", "@chain"), + ("Draws", "@draws"), + ("Rank", "@rank"), + ], + ), + ) + return output + + +def add_tooltips(figures: typing.Figures, tooltips: typing.Tooltips) -> None: + """Add the given tools to the figures. + + Parameters + ---------- + figures : typing.Figures + A dictionary of Bokeh Figure objects. + tooltips : typing.Tooltips + A dictionary of Bokeh HoverTools objects. + + Returns + ------- + None + Adds the tooltips directly to the given figures. + """ + for figure_name, fig in figures.items(): + for tips in tooltips[figure_name]: + fig.add_tools(tips) + + +def create_widgets(rv_name: str, rv_names: list[str]) -> typing.Widgets: + """Create the widgets used in the tool. + + Parameters + ---------- + rv_name : str + The string representation of the random variable data. + rv_names : list[str] + A list of all available random variable names. + + Returns + ------- + typing.Widgets + A dictionary of Bokeh widget objects. + """ + return { + "rv_select": Select(value=rv_name, options=rv_names, title="Query"), + "bw_factor_slider": Slider( + start=0.01, + end=2.00, + step=0.01, + value=1.0, + title="Bandwidth factor", + ), + "hdi_slider": Slider(start=1, end=99, step=1, value=89, title="HDI"), + } + + +def help_page() -> Div: + """Help tab for the tool. + + Returns + ------- + Div + Bokeh Div widget containing the help tab information. + """ + text = """ +

Rank plots

+

+ Rank plots are a histogram of the samples over time. All samples across + all chains are ranked and then we plot the average rank for each chain on + regular intervals. If the chains are mixing well this histogram should + look roughly uniform. If it looks highly irregular that suggests chains + might be getting stuck and not adequately exploring the sample space. + See the paper by Vehtari et al for more information. +

+

Trace plots

+

+ The more familiar trace plots are also included in this widget. You can + click on the legend to show/hide different chains and compare them to the + rank plots. +

+ + """ + return Div(text=text, disable_math=False, min_width=PLOT_WIDTH) + + +def create_view(widgets: typing.Widgets, figures: typing.Figures) -> Tabs: + """Create the tool view. + + Parameters + ---------- + widgets : typing.Widgets + A dictionary of Bokeh widget objects. + figures : typing.Figures + A dictionary of Bokeh Figure objects. + + Returns + ------- + Tabs + Bokeh Tabs objects. + """ + toolbar = create_toolbar(figures) + help_panel = Panel(child=help_page(), title="Help", name="helpPanel") + marginal_panel = Panel( + child=Column(children=[figures["marginals"], widgets["bw_factor_slider"]]), + title="Marginal 1D", + ) + forest_panel = Panel( + child=Column(children=[figures["forests"], widgets["hdi_slider"]]), + title="Forest", + ) + left_panels = Tabs(tabs=[marginal_panel, forest_panel]) + trace_panel = Panel(child=Column(children=[figures["traces"]]), title="Trace") + rank_panel = Panel(child=Column(children=[figures["ranks"]]), title="Rank") + right_panels = Tabs(tabs=[trace_panel, rank_panel]) + tool_panel = Panel( + child=Column( + children=[ + widgets["rv_select"], + Row(children=[left_panels, right_panels, toolbar]), + ], + ), + title="Trace tool", + ) + return Tabs(tabs=[tool_panel, help_panel]) + + +def update( + data: npt.NDArray, + rv_name: str, + sources: typing.Sources, + figures: typing.Figures, + hdi_probability: float, + bw_factor: float, +) -> None: + """Update the tool based on user interaction. + + Parameters + ---------- + data : npt.NDArray + A 2D NumPy array where the length of the first dimension is the number of chains + of the model, and the length of the second dimension is the number of draws of + the model. + rv_name : str + The string representation of the random variable data. + sources : typing.Sources + A dictionary of Bokeh ColumnDataSource objects. + figures : typing.Figures + A dictionary of Bokeh Figure objects. + hdi_probability : float + The HDI probability to use when calculating the HDI bounds. + bw_factor : float + Multiplicative factor used when calculating the kernel density estimate. + + Returns + ------- + None + Updates Bokeh ColumnDataSource objects. + """ + range_min = [] + range_max = [] + computed_data = compute_data(data, bw_factor, hdi_probability) + for figure_name, figure_sources in sources.items(): + figure_data = computed_data[figure_name] + fig = figures[figure_name] + for chain_name, chain_sources in figure_sources.items(): + chain_data = figure_data[chain_name] + for glyph_name, source in chain_sources.items(): + glyph_data = chain_data[glyph_name] + source.data = glyph_data + if figure_name == "marginals" and glyph_name == "line": + range_min.append(min(glyph_data["x"])) + range_max.append(max(glyph_data["x"])) + if figure_name in ["marginals", "forests"]: + fig.xaxis.axis_label = rv_name + if figure_name == "traces": + fig.yaxis.axis_label = rv_name + figures["marginals"].x_range.start = min(range_min) + figures["marginals"].x_range.end = max(range_max) + figures["forests"].x_range.start = min(range_min) + figures["forests"].x_range.end = max(range_max) + figures["traces"].y_range.start = min(range_min) + figures["traces"].y_range.end = max(range_max) diff --git a/src/beanmachine/ppl/diagnostics/tools/marginal1d.py b/src/beanmachine/ppl/diagnostics/tools/marginal1d.py new file mode 100644 index 0000000000..12e38865bb --- /dev/null +++ b/src/beanmachine/ppl/diagnostics/tools/marginal1d.py @@ -0,0 +1,133 @@ +"""Marginal 1D diagnostic tool for a Bean Machine model.""" +from __future__ import annotations + +from typing import Any, TypeVar + +import arviz as az + +import beanmachine.ppl.diagnostics.tools.helpers.marginal1d as tool +from bokeh.models.callbacks import CustomJS +from bokeh.plotting import show + + +T = TypeVar("T", bound="Marginal1d") + + +class Marginal1d: + """Marginal1d diagnostic tool.""" + + bw_cache = {} + + def __init__(self: T, idata: az.InferenceData) -> None: + """Initialize.""" + self.idata = idata + self.rv_identifiers = list(self.idata["posterior"].data_vars) + self.rv_names = sorted( + [str(rv_identifier) for rv_identifier in self.rv_identifiers], + ) + + def modify_doc(self: T, doc: Any) -> None: + """Modify the Jupyter document in order to display the tool.""" + # Initialize the widgets. + rv_name = self.rv_names[0] + hdi_probability = 0.89 # az.rcParams["stats.hdi_prob"] + bw_factor = 1.0 + rv_identifier = self.rv_identifiers[self.rv_names.index(rv_name)] + + # Compute the initial data displayed in the tool. + rv_data = self.idata["posterior"][rv_identifier].values + computed_data = tool.compute_data(rv_data, bw_factor, hdi_probability) + bw = float(computed_data["marginal"]["distribution"]["bandwidth"][0]) + + # Create the Bokeh source(s). + sources = tool.create_sources(computed_data) + + # Create the figure(s). + figures = tool.create_figures(rv_name) + + # Create the glyph(s) and attach them to the figure(s). + glyphs = tool.create_glyphs(computed_data) + tool.add_glyphs(figures, glyphs, sources) + + # Create the annotation(s) and attache them to the figure(s). + annotations = tool.create_annotations(sources) + tool.add_annotations(figures, annotations) + + # Create the tool tip(s) and attach them to the figure(s). + tooltips = tool.create_tooltips(rv_name, figures) + tool.add_tooltips(figures, tooltips) + + # Create the widget(s) for the tool. + widgets = tool.create_widgets(rv_name, self.rv_names, bw_factor, bw) + + # Create the callback(s) for the widget(s). + def update_rv_select(attr: Any, old: str, new: str) -> None: + rv_name = new + bw_factor = 1.0 + hdi_probability = 0.89 + rv_identifier = self.rv_identifiers[self.rv_names.index(rv_name)] + rv_data = self.idata["posterior"][rv_identifier].values + bw = tool.update( + rv_data, + sources, + figures, + rv_name, + bw_factor, + hdi_probability, + ) + widgets["bw_factor_slider"].value = bw_factor + widgets["hdi_slider"].value = 100 * hdi_probability + widgets["bw_div"].text = f"Bandwidth: {bw_factor * bw}" + + def update_bw_factor_slider(attr: Any, old: float, new: float) -> None: + rv_name = widgets["rv_select"].value + bw_factor = new + hdi_probability = widgets["hdi_slider"].value / 100 + rv_identifier = self.rv_identifiers[self.rv_names.index(rv_name)] + rv_data = self.idata["posterior"][rv_identifier].values + bw = tool.update( + rv_data, + sources, + figures, + rv_name, + bw_factor, + hdi_probability, + ) + widgets["bw_div"].text = f"Bandwidth: {bw_factor * bw}" + + def update_hdi_slider(attr: Any, old: int, new: int) -> None: + rv_name = widgets["rv_select"].value + bw_factor = widgets["bw_factor_slider"].value + hdi_probability = new / 100 + rv_identifier = self.rv_identifiers[self.rv_names.index(rv_name)] + rv_data = self.idata["posterior"][rv_identifier].values + bw = tool.update( + rv_data, + sources, + figures, + rv_name, + bw_factor, + hdi_probability, + ) + widgets["bw_div"].text = f"Bandwidth: {bw_factor * bw}" + + widgets["rv_select"].on_change("value", update_rv_select) + # NOTE: We are using Bokeh's CustomJS model in order to reset the ranges of the + # figures. + cjs = CustomJS(args={"p": list(figures.values())[0]}, code="p.reset.emit()") + widgets["rv_select"].js_on_change("value", cjs) + widgets["bw_factor_slider"].on_change("value", update_bw_factor_slider) + widgets["hdi_slider"].on_change("value", update_hdi_slider) + + tool_view = tool.create_view(widgets, figures) + doc.add_root(tool_view) + + def show_tool(self: T) -> None: + """Show the diagnostic tool. + + Returns + ------- + None + Directly displays the tool in Jupyter. + """ + show(self.modify_doc) diff --git a/src/beanmachine/ppl/diagnostics/tools/marginal2d.py b/src/beanmachine/ppl/diagnostics/tools/marginal2d.py new file mode 100644 index 0000000000..0b623c3253 --- /dev/null +++ b/src/beanmachine/ppl/diagnostics/tools/marginal2d.py @@ -0,0 +1,217 @@ +"""Marginal 2D diagnostic tool for a Bean Machine model.""" +from __future__ import annotations + +from typing import Any, TypeVar + +import arviz as az + +import beanmachine.ppl.diagnostics.tools.helpers.marginal2d as tool +from bokeh.models.callbacks import CustomJS +from bokeh.plotting import show + + +T = TypeVar("T", bound="Marginal2d") + + +class Marginal2d: + """Marginal2d diagnostic tool.""" + + bw_cache = {} + + def __init__(self: T, idata: az.InferenceData) -> None: + """Initialize.""" + self.idata = idata + self.rv_identifiers = list(self.idata["posterior"].data_vars) + self.rv_names = sorted( + [str(rv_identifier) for rv_identifier in self.rv_identifiers], + ) + + def modify_doc(self: T, doc: Any) -> None: + """Modify the Jupyter document in order to display the tool.""" + # Initialize the widgets. + x_rv_name = self.rv_names[0] + y_rv_name = self.rv_names[1] + x_hdi_probability = 0.89 # az.rcParams["stats.hdi_prob"] + y_hdi_probability = 0.89 # az.rcParams["stats.hdi_prob"] + bw_factor = 1.0 + x_rv_identifier = self.rv_identifiers[self.rv_names.index(x_rv_name)] + y_rv_identifier = self.rv_identifiers[self.rv_names.index(y_rv_name)] + + # Compute the initial data displayed in the tool. + x_rv_data = self.idata["posterior"][x_rv_identifier].values + y_rv_data = self.idata["posterior"][y_rv_identifier].values + computed_data = tool.compute_data( + x_data=x_rv_data, + y_data=y_rv_data, + x_label=x_rv_name, + y_label=y_rv_name, + x_hdi_probability=x_hdi_probability, + y_hdi_probability=y_hdi_probability, + bw_factor=bw_factor, + ) + x_bw = computed_data["x"]["distribution"]["bandwidth"] + y_bw = float(computed_data["y"]["distribution"]["bandwidth"]) + + # Create the Bokeh source(s). + sources = tool.create_sources(computed_data) + + # Create the figure(s). + figures = tool.create_figures(x_rv_name, y_rv_name) + + # Create the glyph(s) and attach them to the figure(s). + glyphs = tool.create_glyphs(computed_data) + tool.add_glyphs(figures, glyphs, sources) + + # Create the annotation(s) and attache them to the figure(s). + annotations = tool.create_annotations(sources) + tool.add_annotations(figures, annotations) + + # Create the tool tip(s) and attach them to the figure(s). + tooltips = tool.create_tooltips(x_rv_name, y_rv_name, figures) + tool.add_tooltips(figures, tooltips) + + # Create the widget(s) for the tool. + widgets = tool.create_widgets( + x_rv_name, + y_rv_name, + self.rv_names, + bw_factor, + x_bw, + y_bw, + ) + + # Create the callback(s) for the widget(s). + def update_x_rv_select(attr: Any, old: str, new: str) -> None: + x_rv_name = new + y_rv_name = widgets["y_rv_select"].value + bw_factor = 1.0 + x_hdi_probability = 0.89 + y_hdi_probability = 0.89 + x_rv_identifier = self.rv_identifiers[self.rv_names.index(x_rv_name)] + y_rv_identifier = self.rv_identifiers[self.rv_names.index(y_rv_name)] + x_rv_data = self.idata["posterior"][x_rv_identifier].values + y_rv_data = self.idata["posterior"][y_rv_identifier].values + x_bw, y_bw = tool.update( + x_rv_data=x_rv_data, + y_rv_data=y_rv_data, + x_rv_name=x_rv_name, + y_rv_name=y_rv_name, + sources=sources, + figures=figures, + tooltips=tooltips, + x_hdi_probability=x_hdi_probability, + y_hdi_probability=y_hdi_probability, + bw_factor=bw_factor, + ) + widgets["x_hdi_probability"] = 100 * x_hdi_probability + widgets["y_hdi_probability"] = 100 * y_hdi_probability + widgets["bw_factor"] = bw_factor + widgets["x_bw_div"].text = f"Bandwidth {x_rv_name}: {x_bw * bw_factor}" + widgets["y_bw_div"].text = f"Bandwidth {y_rv_name}: {y_bw * bw_factor}" + + def update_y_rv_select(attr: Any, old: str, new: str) -> None: + x_rv_name = widgets["x_rv_select"].value + y_rv_name = new + bw_factor = 1.0 + x_hdi_probability = 0.89 + y_hdi_probability = 0.89 + x_rv_identifier = self.rv_identifiers[self.rv_names.index(x_rv_name)] + y_rv_identifier = self.rv_identifiers[self.rv_names.index(y_rv_name)] + x_rv_data = self.idata["posterior"][x_rv_identifier].values + y_rv_data = self.idata["posterior"][y_rv_identifier].values + x_bw, y_bw = tool.update( + x_rv_data=x_rv_data, + y_rv_data=y_rv_data, + x_rv_name=x_rv_name, + y_rv_name=y_rv_name, + sources=sources, + figures=figures, + tooltips=tooltips, + x_hdi_probability=x_hdi_probability, + y_hdi_probability=y_hdi_probability, + bw_factor=bw_factor, + ) + widgets["x_hdi_probability"] = 100 * x_hdi_probability + widgets["y_hdi_probability"] = 100 * y_hdi_probability + widgets["bw_factor"] = bw_factor + widgets["x_bw_div"].text = f"Bandwidth {x_rv_name}: {x_bw * bw_factor}" + widgets["y_bw_div"].text = f"Bandwidth {y_rv_name}: {y_bw * bw_factor}" + + def update_x_hdi_slider(attr: Any, old: int, new: int) -> None: + x_rv_name = widgets["x_rv_select"].value + y_rv_name = widgets["y_rv_select"].value + bw_factor = 1.0 + x_hdi_probability = new + y_hdi_probability = widgets["y_hdi_slider"].value + x_rv_identifier = self.rv_identifiers[self.rv_names.index(x_rv_name)] + y_rv_identifier = self.rv_identifiers[self.rv_names.index(y_rv_name)] + x_rv_data = self.idata["posterior"][x_rv_identifier].values + y_rv_data = self.idata["posterior"][y_rv_identifier].values + x_bw, y_bw = tool.update( + x_rv_data=x_rv_data, + y_rv_data=y_rv_data, + x_rv_name=x_rv_name, + y_rv_name=y_rv_name, + sources=sources, + figures=figures, + tooltips=tooltips, + x_hdi_probability=x_hdi_probability / 100, + y_hdi_probability=y_hdi_probability / 100, + bw_factor=bw_factor, + ) + widgets["x_hdi_probability"] = x_hdi_probability + widgets["y_hdi_probability"] = y_hdi_probability + widgets["bw_factor"] = bw_factor + widgets["x_bw_div"].text = f"Bandwidth {x_rv_name}: {x_bw * bw_factor}" + widgets["y_bw_div"].text = f"Bandwidth {y_rv_name}: {y_bw * bw_factor}" + + def update_y_hdi_slider(attr: Any, old: int, new: int) -> None: + x_rv_name = widgets["x_rv_select"].value + y_rv_name = widgets["y_rv_select"].value + bw_factor = 1.0 + x_hdi_probability = widgets["x_hdi_slider"].value + y_hdi_probability = new + x_rv_identifier = self.rv_identifiers[self.rv_names.index(x_rv_name)] + y_rv_identifier = self.rv_identifiers[self.rv_names.index(y_rv_name)] + x_rv_data = self.idata["posterior"][x_rv_identifier].values + y_rv_data = self.idata["posterior"][y_rv_identifier].values + x_bw, y_bw = tool.update( + x_rv_data=x_rv_data, + y_rv_data=y_rv_data, + x_rv_name=x_rv_name, + y_rv_name=y_rv_name, + sources=sources, + figures=figures, + tooltips=tooltips, + x_hdi_probability=x_hdi_probability / 100, + y_hdi_probability=y_hdi_probability / 100, + bw_factor=bw_factor, + ) + widgets["x_hdi_probability"] = x_hdi_probability + widgets["y_hdi_probability"] = y_hdi_probability + widgets["bw_factor"] = bw_factor + widgets["x_bw_div"].text = f"Bandwidth {x_rv_name}: {x_bw * bw_factor}" + widgets["y_bw_div"].text = f"Bandwidth {y_rv_name}: {y_bw * bw_factor}" + + widgets["x_rv_select"].on_change("value", update_x_rv_select) + widgets["y_rv_select"].on_change("value", update_y_rv_select) + # NOTE: We are using Bokeh's CustomJS model in order to reset the ranges of the + # figures. + cjs = CustomJS(args={"p": list(figures.values())[0]}, code="p.reset.emit()") + widgets["x_rv_select"].js_on_change("value", cjs) + widgets["y_rv_select"].js_on_change("value", cjs) + widgets["x_hdi_slider"].on_change("value", update_x_hdi_slider) + widgets["y_hdi_slider"].on_change("value", update_y_hdi_slider) + + tool_view = tool.create_view(widgets, figures) + doc.add_root(tool_view) + + def show_tool(self: T) -> None: + """Show the diagnostic tool. + + Returns + ------- + None + Directly displays the tool in Jupyter. + """ + show(self.modify_doc) diff --git a/src/beanmachine/ppl/diagnostics/tools/trace.py b/src/beanmachine/ppl/diagnostics/tools/trace.py new file mode 100644 index 0000000000..84099cbd43 --- /dev/null +++ b/src/beanmachine/ppl/diagnostics/tools/trace.py @@ -0,0 +1,136 @@ +"""Trace diagnostic tool for a Bean Machine model.""" +from __future__ import annotations + +from typing import Any, TypeVar + +import arviz as az + +import beanmachine.ppl.diagnostics.tools.helpers.trace as tool +from bokeh.models.callbacks import CustomJS +from bokeh.plotting import show + + +T = TypeVar("T", bound="Trace") + + +class Trace: + """Trace diagnostic tool.""" + + def __init__(self: T, idata: az.InferenceData) -> None: + """Initialize.""" + self.idata = idata + self.rv_identifiers = list(self.idata["posterior"].data_vars) + self.rv_names = sorted( + [str(rv_identifier) for rv_identifier in self.rv_identifiers], + ) + + def modify_doc(self: T, doc: Any) -> None: + """Modify the Jupyter document in order to display the tool.""" + # Initialize the widgets. + rv_name = self.rv_names[0] + hdi_probability = 0.89 + bw_factor = 1.0 + rv_identifier = self.rv_identifiers[self.rv_names.index(rv_name)] + + # Compute the initial data displayed in the tool. + rv_data = self.idata["posterior"][rv_identifier].values + num_chains, num_draws = rv_data.shape + computed_data = tool.compute_data( + data=rv_data, + bw_factor=bw_factor, + hdi_probability=hdi_probability, + ) + + # Create the Bokeh source(s). + sources = tool.create_sources(computed_data) + + # Create the figure(s). + figures = tool.create_figures(rv_name, num_chains) + + # Create the glyph(s) and attach them to the figure(s). + glyphs = tool.create_glyphs(computed_data, num_chains) + tool.add_glyphs(figures, glyphs, sources, num_chains) + + # Create the annotation(s) and attache them to the figure(s). + annotations = tool.create_annotations(figures, num_chains) + tool.add_annotations(figures, annotations) + + # Create the tool tip(s) and attach them to the figure(s). + tooltips = tool.create_tooltips(rv_name, figures, num_chains) + tool.add_tooltips(figures, tooltips) + + # Create the widget(s) for the tool. + widgets = tool.create_widgets(rv_name, self.rv_names) + + # Create the callback(s) for the widget(s). + def update_rv_select(attr: Any, old: str, new: str) -> None: + rv_name = new + bw_factor = 1.0 + hdi_probability = 0.89 + rv_identifier = self.rv_identifiers[self.rv_names.index(rv_name)] + rv_data = self.idata["posterior"][rv_identifier].values + tool.update( + data=rv_data, + rv_name=rv_name, + sources=sources, + figures=figures, + hdi_probability=hdi_probability, + bw_factor=bw_factor, + ) + widgets["hdi_probability"] = 100 * hdi_probability + widgets["bw_factor"] = bw_factor + + def update_hdi_slider(attr: Any, old: int, new: int) -> None: + rv_name = widgets["rv_select"].value + bw_factor = 1.0 + hdi_probability = new + rv_identifier = self.rv_identifiers[self.rv_names.index(rv_name)] + rv_data = self.idata["posterior"][rv_identifier].values + tool.update( + data=rv_data, + rv_name=rv_name, + sources=sources, + figures=figures, + hdi_probability=hdi_probability / 100, + bw_factor=bw_factor, + ) + widgets["hdi_probability"] = hdi_probability + widgets["bw_factor"] = bw_factor + + def update_bw_factor_slider(attr: Any, old: float, new: float) -> None: + rv_name = widgets["rv_select"].value + bw_factor = new + hdi_probability = widgets["hdi_slider"].value + rv_identifier = self.rv_identifiers[self.rv_names.index(rv_name)] + rv_data = self.idata["posterior"][rv_identifier].values + tool.update( + data=rv_data, + rv_name=rv_name, + sources=sources, + figures=figures, + hdi_probability=hdi_probability / 100, + bw_factor=bw_factor, + ) + widgets["hdi_probability"] = hdi_probability + widgets["bw_factor"] = bw_factor + + widgets["rv_select"].on_change("value", update_rv_select) + # NOTE: We are using Bokeh's CustomJS model in order to reset the ranges of the + # figures. + cjs = CustomJS(args={"p": list(figures.values())[0]}, code="p.reset.emit()") + widgets["rv_select"].js_on_change("value", cjs) + widgets["hdi_slider"].on_change("value", update_hdi_slider) + widgets["bw_factor_slider"].on_change("value", update_bw_factor_slider) + + tool_view = tool.create_view(widgets, figures) + doc.add_root(tool_view) + + def show_tool(self: T) -> None: + """Show the diagnostic tool. + + Returns + ------- + None + Directly displays the tool in Jupyter. + """ + show(self.modify_doc) diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/__init__.py b/src/beanmachine/ppl/diagnostics/tools/typing/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/autocorrelation.py b/src/beanmachine/ppl/diagnostics/tools/typing/autocorrelation.py new file mode 100644 index 0000000000..1f23508362 --- /dev/null +++ b/src/beanmachine/ppl/diagnostics/tools/typing/autocorrelation.py @@ -0,0 +1,78 @@ +"""Autocorrelation diagnostic tool types for a Bean Machine model.""" +from __future__ import annotations + +from typing import Any, TypedDict + +from bokeh.models.annotations import BoxAnnotation +from bokeh.models.glyphs import Quad +from bokeh.models.sources import ColumnDataSource +from bokeh.models.tools import HoverTool +from bokeh.models.widgets.inputs import Select +from bokeh.models.widgets.sliders import RangeSlider +from bokeh.plotting.figure import Figure + + +Figure_names = None | list[str] + +# NOTE: These are the types pyre gives us when using `reveal_type(...)` on the outputs +# of the methods. +Data = dict[Any, Any] +Sources = dict[Any, Any] +Figures = dict[Any, Any] +Glyphs = dict[Any, Any] +Annotations = dict[Any, Any] +Tooltips = dict[Any, Any] +Widgets = dict[str, RangeSlider | Select] + +# NOTE: TypedDict objects are for reference only. Due to the way pyre accesses keys in +# dictionaries, and how NumPy casts arrays when using tolist(), we are unable to +# use them, but they provide semantic information for the different types. + + +class _QuadData(TypedDict): + left: list[float] + top: list[float] + right: list[float] + bottom: list[float] + + +class _BoxData(TypedDict): + bottom: float + top: float + + +class _FigureData(TypedDict): + quad: _QuadData + box: _BoxData + + +class _FigureSources(TypedDict): + quad: ColumnDataSource + + +class _FigureGlyphs(TypedDict): + quad: Quad + + +class _FigureAnnotations(TypedDict): + box: BoxAnnotation + + +class _FigureTooltips(TypedDict): + quad: HoverTool + + +class _Widgets(TypedDict): + rv_select: Select + range_slider: RangeSlider + + +# NOTE: We do not have a priori information about the number of chains in the output +# data. This is why we are not creating a TypedDict object for the Data type with +# named keys like chain1, chain2, etc.. +_Data = dict[str, _FigureData] +_Sources = dict[str, _FigureSources] +_Figures = dict[str, Figure] +_Glyphs = dict[str, _FigureGlyphs] +_Annotations = dict[str, _FigureAnnotations] +_Tooltips = dict[str, _FigureTooltips] diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/effective_sample_size.py b/src/beanmachine/ppl/diagnostics/tools/typing/effective_sample_size.py new file mode 100644 index 0000000000..e5f902098c --- /dev/null +++ b/src/beanmachine/ppl/diagnostics/tools/typing/effective_sample_size.py @@ -0,0 +1,147 @@ +"""Effective Sample Size diagnostic tool types for a Bean Machine model.""" +from __future__ import annotations + +from typing import Any, TypedDict + +from bokeh.models.annotations import Legend +from bokeh.models.glyphs import Circle, Line +from bokeh.models.sources import ColumnDataSource +from bokeh.models.tools import HoverTool +from bokeh.models.widgets.inputs import Select +from bokeh.plotting.figure import Figure + + +# NOTE: These are the types pyre gives us when using `reveal_type(...)` on the outputs +# of the methods. +Data = dict[str, dict[str, dict[str, Any]]] +Sources = dict[str, dict[str, dict[str, ColumnDataSource]]] +Figures = dict[str, Figure] +Glyphs = dict[str, dict[Any, Any]] +Annotations = dict[Any, Any] +Tooltips = dict[str, dict[Any, Any]] +Widgets = dict[str, Select] + +# NOTE: TypedDict objects are for reference only. Due to the way pyre accesses keys in +# dictionaries, and how NumPy casts arrays when using tolist(), we are unable to +# use them, but they provide semantic information for the different types. + + +class _BulkData(TypedDict): + x: list[float] + y: list[float] + + +class _TailData(TypedDict): + x: list[float] + y: list[float] + + +class _RuleOfThumbData(TypedDict): + x: list[float] + y: list[float] + label: list[str] + + +class _GlyphData(TypedDict): + bulk: _BulkData + tail: _TailData + rule_of_thumb: _RuleOfThumbData + + +class _Data(TypedDict): + ess: _GlyphData + + +class _BulkSource(TypedDict): + line: ColumnDataSource + circle: ColumnDataSource + + +class _TailSource(TypedDict): + line: ColumnDataSource + circle: ColumnDataSource + + +class _RuleOfThumbSource(TypedDict): + line: ColumnDataSource + + +class _GlyphSources(TypedDict): + bulk: _BulkSource + tail: _TailSource + rule_of_thumb: _RuleOfThumbSource + + +class _Sources(TypedDict): + ess: _GlyphSources + + +class _Figures(TypedDict): + ess: Figure + + +class _BulkLineGlyphs(TypedDict): + glyph: Line + hover_glyph: Line + + +class _BulkCircleGlyphs(TypedDict): + glyph: Circle + hover_glyph: Circle + + +class _BulkGlyphs(TypedDict): + line: _BulkLineGlyphs + circle: _BulkCircleGlyphs + + +class _TailLineGlyphs(TypedDict): + glyph: Line + hover_glyph: Line + + +class _TailCircleGlyphs(TypedDict): + glyph: Circle + hover_glyph: Circle + + +class _TailGlyphs(TypedDict): + line: _TailLineGlyphs + circle: _TailCircleGlyphs + + +class _RuleOfThumbGlyphs(TypedDict): + glyph: Line + hover_glyph: Line + + +class _FigureGlyphs(TypedDict): + bulk: _BulkGlyphs + tail: _TailGlyphs + rule_of_thumb: _RuleOfThumbGlyphs + + +class _Glyphs(TypedDict): + ess: _FigureGlyphs + + +class _FigureAnnotations(TypedDict): + legend: Legend + + +class _Annotations(TypedDict): + ess: _FigureGlyphs + + +class _FigureTooltips(TypedDict): + bulk: HoverTool + tail: HoverTool + rule_of_thumb: HoverTool + + +class _Tooltips(TypedDict): + ess: _FigureTooltips + + +class _Widgets(TypedDict): + rv_select: Select diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/marginal1d.py b/src/beanmachine/ppl/diagnostics/tools/typing/marginal1d.py new file mode 100644 index 0000000000..372350de31 --- /dev/null +++ b/src/beanmachine/ppl/diagnostics/tools/typing/marginal1d.py @@ -0,0 +1,157 @@ +"""Marginal 1D diagnostic tool types for a Bean Machine model.""" +from __future__ import annotations + +from typing import Any, TypedDict + +from bokeh.models.annotations import Band, LabelSet +from bokeh.models.glyphs import Circle, Line +from bokeh.models.sources import ColumnDataSource +from bokeh.models.tools import HoverTool +from bokeh.models.widgets.inputs import Select +from bokeh.models.widgets.markups import Div +from bokeh.models.widgets.sliders import Slider +from bokeh.plotting.figure import Figure + + +# NOTE: These are the types pyre gives us when using `reveal_type(...)` on the outputs +# of the methods. +StatsAndLabelsData = dict[str, dict[str, Any]] +HDIData = dict[str, Any] +Data = dict[Any, Any] +Sources = dict[Any, Any] +Figures = dict[Any, Any] +Glyphs = dict[Any, Any] +Annotations = dict[Any, Any] +Tooltips = dict[Any, Any] +Widgets = dict[str, Div | Select | Slider] + +# NOTE: TypedDict objects are for reference only. Due to the way pyre accesses keys in +# dictionaries, and how NumPy casts arrays when using tolist(), we are unable to +# use them, but they provide semantic information for the different types. + + +class _DistributionData(TypedDict): + x: list[float] + y: list[float] + bandwidth: list[float] + + +class _HDIData(TypedDict): + base: list[float] + lower: list[float] + upper: list[float] + + +class _StatsData(TypedDict): + x: list[float] + y: list[float] + text: list[str] + + +class _LabelsData(TypedDict): + x: list[float] + y: list[float] + text: list[str] + text_align: list[str] + x_offset: list[int] + y_offset: list[int] + + +class _StatsAndLabelsData(TypedDict): + x: list[float] + y: list[float] + text: list[str] + text_align: list[str] + x_offset: list[int] + y_offset: list[int] + + +class _GlyphData(TypedDict): + distribtution: _DistributionData + hdi: _HDIData + stats: _StatsData + labels: _LabelsData + + +class _Data(TypedDict): + marginal: _GlyphData + cumulative: _GlyphData + + +class _GlyphSources(TypedDict): + distribution: ColumnDataSource + hdi: ColumnDataSource + stats: ColumnDataSource + labels: ColumnDataSource + + +class _Sources(TypedDict): + marginal: _GlyphSources + cumulative: _GlyphSources + + +class _Figures(TypedDict): + marginal: Figure + cumulative: Figure + + +class _DistributionGlyph(TypedDict): + glyph: Line + hover_glyph: Line + + +class _StatsGlyph(TypedDict): + glyph: Circle + hover_glyph: Circle + + +class _MarginalFigureGlyphs(TypedDict): + distribution: _DistributionGlyph + stats: _StatsGlyph + + +class _CumulativeFigureGlyphs(TypedDict): + distribution: _DistributionGlyph + stats: _StatsGlyph + + +class _Glyphs(TypedDict): + marginal: _MarginalFigureGlyphs + cumulative: _CumulativeFigureGlyphs + + +class _MarginalFigureAnnotations(TypedDict): + hdi: Band + labels: LabelSet + + +class _CumulativeFigureAnnotations(TypedDict): + hdi: Band + labels: LabelSet + + +class _Annotations(TypedDict): + marginal: _MarginalFigureAnnotations + cumulative: _CumulativeFigureAnnotations + + +class _MarginalFigureTooltips(TypedDict): + distribution: HoverTool + stats: HoverTool + + +class _CumulativeFigureTooltips(TypedDict): + distribution: HoverTool + stats: HoverTool + + +class _Tooltips(TypedDict): + marginal: _MarginalFigureTooltips + cumulative: _CumulativeFigureTooltips + + +class _Widgets(TypedDict): + rv_select: Select + bw_factor_slider: Slider + bw_div: Div + hdi_slider: Slider diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/marginal2d.py b/src/beanmachine/ppl/diagnostics/tools/typing/marginal2d.py new file mode 100644 index 0000000000..19e341dd55 --- /dev/null +++ b/src/beanmachine/ppl/diagnostics/tools/typing/marginal2d.py @@ -0,0 +1,304 @@ +"""Marginal 2D diagnostic tool types for a Bean Machine model.""" +from __future__ import annotations + +from typing import Any, TypedDict + +from beanmachine.ppl.diagnostics.tools.typing import marginal1d as m1d + +from bokeh.models.annotations import Band +from bokeh.models.glyphs import Circle, Image, Line +from bokeh.models.sources import ColumnDataSource +from bokeh.models.tools import HoverTool +from bokeh.models.widgets.inputs import Select +from bokeh.models.widgets.markups import Div +from bokeh.models.widgets.sliders import Slider +from bokeh.plotting.figure import Figure + + +# NOTE: These are the types pyre gives us when using `reveal_type(...)` on the outputs +# of the methods. +XYData = dict[ + str, + dict[str, dict[str, dict[str, Any]]] | dict[str, list[Any]], +] +YData = dict[str, dict[str, Any]] +Data = dict[str, Any] +Sources = dict[Any, Any] +Figures = dict[Any, Any] +Glyphs = dict[Any, Any] +Annotations = dict[str, dict[str, Band] | Band] +Tooltips = dict[Any, Any] +Widgets = dict[str, Div | Select | Slider] + +# NOTE: TypedDict objects are for reference only. Due to the way pyre accesses keys in +# dictionaries, and how NumPy casts arrays when using tolist(), we are unable to +# use them, but they provide semantic information for the different types. + + +class _DistributionData(TypedDict): + x: list[float] + y: list[float] + bandwidth: list[float] + + +class _StatsData(TypedDict): + x: list[float] + y: list[float] + text: list[str] + + +class _LabelsData(TypedDict): + x: list[float] + y: list[float] + text: list[str] + text_align: list[str] + x_offset: list[int] + y_offset: list[int] + + +class _XData(TypedDict): + distribution: _DistributionData + hdi: m1d.HDIData + stats: _StatsData + labels: _LabelsData + + +class _YHDIData(TypedDict): + top: m1d.HDIData + bottom: m1d.HDIData + + +class _YData(TypedDict): + distribution: _DistributionData + hdi: _YHDIData + stats: _StatsData + labels: _LabelsData + + +class _XYDistributionData(TypedDict): + image: list[list[float]] + xmin: list[float] + xmax: list[float] + ymin: list[float] + ymax: list[float] + dw: list[float] + dh: list[float] + + +class _XYHDIDatum(TypedDict): + x: list[float] + y: list[float] + + +class _XYHDIDataLowerUpper(TypedDict): + lower: _XYHDIDatum + upper: _XYHDIDatum + + +class _XYHDIData(TypedDict): + x: _XYHDIDataLowerUpper + y: _XYHDIDataLowerUpper + + +class _XYStatsData(TypedDict): + x: list[float] + y: list[float] + + +class _XYLabelsData(TypedDict): + mean: list[str] + + +class _XYData(TypedDict): + distribution: _XYDistributionData + hdi: _XYHDIData + stats: _XYStatsData + labels: _XYLabelsData + + +class _Data(TypedDict): + x: _XData + y: _YData + xy: _XYData + + +class _XSource(TypedDict): + distribution: ColumnDataSource + hdi: ColumnDataSource + stats: ColumnDataSource + + +class _YSource(TypedDict): + distribution: ColumnDataSource + hdi: ColumnDataSource + stats: ColumnDataSource + + +class _XYSourceX(TypedDict): + lower: ColumnDataSource + upper: ColumnDataSource + + +class _XYSourceY(TypedDict): + lower: ColumnDataSource + upper: ColumnDataSource + + +class _XYSourceXAndY(TypedDict): + x: _XYSourceX + y: _XYSourceY + + +class _XYSource(TypedDict): + distribution: ColumnDataSource + hdi: _XYSourceXAndY + stats: ColumnDataSource + + +class _Sources(TypedDict): + x: _XSource + y: _YSource + xy: _XYSource + + +class _Figures(TypedDict): + x: Figure + y: Figure + xy: Figure + + +class _XDistributionGlyph(TypedDict): + glyph: Line + hover_glyph: Line + + +class _XStatsGlyph(TypedDict): + glyph: Circle + hover_glyph: Circle + + +class _XGlyphs(TypedDict): + distribution: _XDistributionGlyph + stats: _XStatsGlyph + + +class _YDistributionGlyph(TypedDict): + glyph: Line + hover_glyph: Line + + +class _YStatsGlyph(TypedDict): + glyph: Circle + hover_glyph: Circle + + +class _YGlyphs(TypedDict): + distribution: _YDistributionGlyph + stats: _YStatsGlyph + + +class _XYHDIGlyphsXLower(TypedDict): + glyph: Line + hover_glyph: Line + + +class _XYHDIGlyphsXUpper(TypedDict): + glyph: Line + hover_glyph: Line + + +class _XYHDIGlyphsX(TypedDict): + lower: _XYHDIGlyphsXLower + upper: _XYHDIGlyphsXUpper + + +class _XYHDIGlyphsYLower(TypedDict): + glyph: Line + hover_glyph: Line + + +class _XYHDIGlyphsYUpper(TypedDict): + glyph: Line + hover_glyph: Line + + +class _XYHDIGlyphsY(TypedDict): + lower: _XYHDIGlyphsYLower + upper: _XYHDIGlyphsYUpper + + +class _XYHDIGlyphs(TypedDict): + x: _XYHDIGlyphsX + y: _XYHDIGlyphsY + + +class _XYStatsGlyph(TypedDict): + glyph: Circle + hover_glyph: Circle + + +class _XYGlyphs(TypedDict): + distribution: Image + hdi: _XYHDIGlyphs + stats: _XYStatsGlyph + + +class _Glyphs(TypedDict): + x: _XGlyphs + y: _YGlyphs + xy: _XYGlyphs + + +class _YAnnotations(TypedDict): + top: Band + bottom: Band + + +class _Annotations(TypedDict): + x: Band + y: _YAnnotations + + +class _XTooltips(TypedDict): + distribution: HoverTool + stats: HoverTool + + +class _XYHDITooltipsX(TypedDict): + lower: HoverTool + upper: HoverTool + + +class _XYHDITooltipsY(TypedDict): + lower: HoverTool + upper: HoverTool + + +class _XYHDITooltips(TypedDict): + x: _XYHDITooltipsX + y: _XYHDITooltipsY + + +class _XYTooltips(TypedDict): + hdi: _XYHDITooltips + mean: HoverTool + + +class _YTooltips(TypedDict): + distribution: HoverTool + stats: HoverTool + + +class _Tooltips(TypedDict): + x: _XTooltips + y: _YTooltips + xy: _XYTooltips + + +class _Widgets(TypedDict): + x_rv_select: Select + y_rv_select: Select + x_hdi_slider: Slider + y_hdi_slider: Slider + x_bw_div: Div + y_bw_div: Div diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/trace.py b/src/beanmachine/ppl/diagnostics/tools/typing/trace.py new file mode 100644 index 0000000000..9a6318b6d9 --- /dev/null +++ b/src/beanmachine/ppl/diagnostics/tools/typing/trace.py @@ -0,0 +1,233 @@ +"""Marginal 2D diagnostic tool types for a Bean Machine model.""" +from __future__ import annotations + +from typing import Any, TypedDict + +from beanmachine.ppl.diagnostics.tools.typing import marginal1d as m1d + +from bokeh.models.annotations import Legend +from bokeh.models.glyphs import Circle, Line, Quad +from bokeh.models.sources import ColumnDataSource +from bokeh.models.widgets.inputs import Select +from bokeh.models.widgets.sliders import Slider +from bokeh.plotting.figure import Figure + + +# NOTE: These are the types pyre gives us when using `reveal_type(...)` on the outputs +# of the methods. +Data = dict[Any, Any] +Sources = dict[Any, Any] +Figures = dict[Any, Any] +Glyphs = dict[Any, Any] +Annotations = dict[str, dict[str, Legend]] +Tooltips = dict[Any, Any] +Widgets = dict[str, Select | Slider] + +# NOTE: TypedDict objects are for reference only. Due to the way pyre accesses keys in +# dictionaries, and how NumPy casts arrays when using tolist(), we are unable to +# use them, but they provide semantic information for the different types. + + +class _DistributionData(TypedDict): + x: list[float] + y: list[float] + bandwidth: list[float] + + +class _StatsData(TypedDict): + x: list[float] + y: list[float] + text: list[str] + + +class _LabelsData(TypedDict): + x: list[float] + y: list[float] + text: list[str] + text_align: list[str] + x_offset: list[int] + y_offset: list[int] + + +class _MarginalDataSingleChain(TypedDict): + distribution: _DistributionData + hdi: m1d.HDIData + stats: _StatsData + labels: _LabelsData + + +class _ForestLineData(TypedDict): + x: list[float] + y: list[float] + + +class _ForestCircleData(TypedDict): + x: list[float] + y: list[float] + + +class _ForestDataSingleChain(TypedDict): + line: _ForestLineData + circle: _ForestCircleData + chain: int + mean: float + + +class _TraceLineData(TypedDict): + x: list[float] + y: list[float] + + +class _TraceDataSingleChain(TypedDict): + line: _TraceLineData + chain: int + mean: float + + +class _RankQuadData(TypedDict): + left: list[float] + top: list[float] + right: list[float] + bottom: list[float] + draws: list[str] + rank: list[float] + + +class _RankLineData(TypedDict): + x: list[float] + y: list[float] + + +class _RankDataSingleChain(TypedDict): + quad: _RankQuadData + line: _RankLineData + chain: int + rank_mean: float + mean: float + + +MarginalData = dict[str, _MarginalDataSingleChain] +ForestData = dict[str, _ForestDataSingleChain] +TraceData = dict[str, _TraceDataSingleChain] +RankData = dict[str, _RankDataSingleChain] + + +class _Data(TypedDict): + marginals: MarginalData + forests: ForestData + traces: TraceData + ranks: RankData + + +class _MarginalSourceSingleChain(TypedDict): + line: ColumnDataSource + + +class _ForestSourceSingleChain(TypedDict): + line: ColumnDataSource + circle: ColumnDataSource + + +class _TraceSourceSingleChain(TypedDict): + line: ColumnDataSource + + +class _RankSourceSingleChain(TypedDict): + quad: ColumnDataSource + line: ColumnDataSource + + +MarginalSources = dict[str, _MarginalSourceSingleChain] +ForestSources = dict[str, _ForestSourceSingleChain] +TraceSources = dict[str, _TraceSourceSingleChain] +RankSources = dict[str, _RankSourceSingleChain] + + +class _FigureSources(TypedDict): + marginals: MarginalSources + forests: ForestSources + traces: TraceSources + ranks: RankSources + + +_Sources = dict[str, _FigureSources] + + +class _Figures(TypedDict): + marginals: Figure + forests: Figure + traces: Figure + ranks: Figure + + +class _MarginalLineGlyph(TypedDict): + glyph: Line + hover_glyph: Line + + +class _MarginalGlyphSingleChain(TypedDict): + line: _MarginalLineGlyph + + +class _ForestLineGlyph(TypedDict): + glyph: Line + hover_glyph: Line + + +class _ForestCircleGlyph(TypedDict): + glyph: Circle + hover_glyph: Circle + + +class _ForestGlyphSingleChain(TypedDict): + line: _ForestLineGlyph + circle: _ForestCircleGlyph + + +class _TraceLineGlyph(TypedDict): + glyph: Line + hover_glyph: Line + + +class _TraceGlyphSingleChain(TypedDict): + line: _TraceLineGlyph + + +class _RankQuadGlyph(TypedDict): + glyph: Quad + hover_glyph: Quad + + +class _RankLineGlyph(TypedDict): + glyph: Line + hover_glyph: Line + + +class _RankGlyphSingleChain(TypedDict): + quad: _RankQuadGlyph + line: _RankLineGlyph + + +MarginalGlyphs = dict[str, _MarginalGlyphSingleChain] +ForestGlyphs = dict[str, _ForestGlyphSingleChain] +TraceGlyphs = dict[str, _TraceGlyphSingleChain] +RankGlyphs = dict[str, _RankGlyphSingleChain] + + +class _FigureGlyphs(TypedDict): + marginals: MarginalGlyphs + forests: ForestGlyphs + traces: TraceGlyphs + ranks: RankGlyphs + + +_Glyphs = dict[str, _FigureGlyphs] + +_FigureAnnotations = dict[str, Legend] +_Annotations = dict[str, _FigureAnnotations] + + +class _Widgets(TypedDict): + rv_select: Select + bw_factor_slider: Slider + hdi_slider: Slider diff --git a/src/beanmachine/ppl/diagnostics/tools/viz.py b/src/beanmachine/ppl/diagnostics/tools/viz.py new file mode 100644 index 0000000000..d539b8b91e --- /dev/null +++ b/src/beanmachine/ppl/diagnostics/tools/viz.py @@ -0,0 +1,47 @@ +"""Visual diagnostics tools for Bean Machine models.""" +from typing import TypeVar + +from beanmachine.ppl.diagnostics.tools.accessor import register_mcs_accessor +from beanmachine.ppl.diagnostics.tools.autocorrelation import Autocorrelation +from beanmachine.ppl.diagnostics.tools.effective_sample_size import EffectiveSampleSize +from beanmachine.ppl.diagnostics.tools.marginal1d import Marginal1d +from beanmachine.ppl.diagnostics.tools.marginal2d import Marginal2d +from beanmachine.ppl.diagnostics.tools.trace import Trace +from beanmachine.ppl.inference.monte_carlo_samples import MonteCarloSamples + + +T = TypeVar("T", bound="DiagnosticsTools") + + +@register_mcs_accessor("diagnostics") +class DiagnosticsTools: + """Accessor object for the visual diagnostics tools.""" + + def __init__(self: T, mcs: MonteCarloSamples) -> None: + """Initialize.""" + self.mcs = mcs + self.idata = self.mcs.to_inference_data() + + def autocorrelation(self: T) -> None: + """Autocorrelation tool.""" + Autocorrelation(self.idata).show_tool() + + def ess(self: T) -> None: + """Effective Sample Size tool.""" + EffectiveSampleSize(self.idata).show_tool() + + def marginal1d(self: T) -> None: + """Marginal 1D tool.""" + Marginal1d(self.idata).show_tool() + + def marginal2d(self: T) -> None: + """Marginal 2D tool.""" + Marginal2d(self.idata).show_tool() + + def trace(self: T) -> None: + """Trace tool.""" + Trace(self.idata).show_tool() + + def display_idata(self: T) -> None: + """Display the ArviZ InferenceData object.""" + return self.idata diff --git a/tutorials/Coin_flipping.ipynb b/tutorials/Coin_flipping.ipynb index 04a303a3ca..8e45c2a821 100644 --- a/tutorials/Coin_flipping.ipynb +++ b/tutorials/Coin_flipping.ipynb @@ -102,7 +102,8 @@ "from bokeh.palettes import Colorblind3\n", "from bokeh.plotting import gridplot, show\n", "from IPython.display import Markdown\n", - "from torch import tensor" + "from torch import tensor\n", + "from tqdm.notebook import tqdm" ] }, { @@ -193,14 +194,12 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAsMAAAIXCAYAAAB5I1N7AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB0DUlEQVR4nO3deVxU5f4H8M+wDYsw7IiCICouKIj7gimaWqZlZbZYaWWWlfdmdevnNVOvlt5udbtGq5pWZqbZYrmmhoq5I+4oKvs+AsO+zMz5/WGcmRFEwBnOLJ/36zWvfM6Zc/jSiHzmmWeRCYIggIiIiIjIBtlJXQARERERkVQYhomIiIjIZjEMExEREZHNYhgmIiIiIpvFMExERERENothmIiIiIhsFsMwEREREdkshmEiIiIislkOUhdgabRaLXJycuDu7g6ZTCZ1OURERER0A0EQUFZWhg4dOsDOrum+X4bhFsrJyUFwcLDUZRARERHRLWRmZiIoKKjJ5zAMt5C7uzuA6/9zPTw8JK6GiIiIiG5UWlqK4OBgMbc1hWG4heqHRnh4eDAMExEREZmx5gxp5QQ6IiIiIrJZDMNEREREZLMYhomIiIjIZjEMExEREZHNYhgmIiIiIpvFMExERERENothmIiIiIhsFsMwEREREdkshmEiIiIislkMw0RERERksxiGiYiIiMhmMQwTERERkc1iGCYiIiIim8UwTEREREQ2i2GYiIiIiGwWwzAREYkEQYBWK0hdBhFRm3GQugAiIjKNylo10pSVSL9WgYKyGlwrr0FheS2ulddAWV6Dkso6VNdpUKvRoqZOixqNFrVqLQDA0V4GJ3s7yB3tIXewg5ODHTycHeHbzgk+7eTwbSeHbzsn+LnLEeztijBfN3i6Okn8HRMRtRzDMBGRhauu0+BcTinOZJUgpaAcqcoKpCorkKuqbvU96zQC6jQaVNRqmn2Nl6sjOvu6IdTXDV382qFPRwUigxQMyURk1hiGiYgsiCAIuFxQjmNpxTidVYJTWSpcyi+DxgyGNhRX1qE4owSJGSUGxzt5uyIySIGoIE/0C/FEZJAnHO05So+IzAPDMBGRmcsvrcbBy0okpCiRcFmJgrKaVt3H0V4GHzc5fNo5wbedHN5uTnBxsv9rOIQd5H8NiwCAWrUWNWrtX//VoEatRUllHZR/DbFQlteguk7brK+bUVSJjKJK/HY6FwDQTu6AIWHeGN7VFzFdfdHVvx1kMlmrviciotvFMExEZGYEQcDpLBW2n83Dngv5SCkob/a1nq6OCPN1Q2ffdgjzc7s+bMHHDR09XeDh4mDU0FlRo0Z+aTXSrlXgauH1oRn1f25qiEZ5jRq7LxRg94UCAIC/uxyx3f1xV5/2GN7FF04O7DUmorYjEwRB+s/WLEhpaSkUCgVUKhU8PDykLoeIrIRWK+BERjG2n8nDznN5yC6puuU17nIH9AlSIDLIE5FB18fndvR0MYte1uKKWpzOVuHMX0M5TmeVIL/01j3a7s4OuLNnAO7q3R4jw/3g/FdPNRFRS7QkrzEMtxDDMBEZ05XCcmw6noWfTmbdMiy6OdljaBcfDO/qi+FdfdHVrx3s7KQPvs2Vq6rCn5evXR/y0YzhHq5O9ri7dyCmDgjCoM7eZhHyicgyMAybEMMwEd2uiho1tp7JxcZjmTieXtzkc/t0VGB0D3+M6OaLqGDrmXhWPxEw4bISf1wsxJ+XlVA3MQkw1McVDw0IxoP9gtBe4dyGlRKRJWIYNiGGYSJqrUv5ZVhzMBW/JOWgsokly/qHeOHu3u0xPqI9gr1d27BC6agq67D7Qj62n83D/pRCcb3jG9nJgFHd/TFjWChGdPNlbzERNYph2IQYhomoJQRBwL5LhVidkIoDKcqbPi+igwem9A/ChD6BCPCw7Z7P8ho19iYX4MfELOy/VIibdRiHB7TD08M7Y3J0R44tJiIDDMMmxDBMRM1RXafBTyez8WVC6k1Xg1C4OOL+6I6Y0j8IvTsq2rhCy5CrqsKPidnYeDwT6dcqG32Oj5sTpg0JwRNDQuDnLm/jConIHDEMmxDDMBE1pbpOg++OZuDT+Cs3nSA2uLM3Hh8SgrG9Atij2UyCIOBoahHWH83A1tO5jY4vdna0w+ODQzBrZBj83W27d53I1jEMmxDDMBE1prpOgw1HM/DJTUKwg50M90Z1wNMxndkLfJvyVNX4+lAavj2SAVVVXYPz9aH4uZFd2FNMZKMYhk2IYZiI9NWoNdhwNBOfxF9udGk0T1dHTBvcCU8ODbX5scDGVlmrxubEbKxJSMVVZUWD886OdnhiSAieH9kFPu0YiolsCcOwCTEMExFw/WP77WfzsHx7MjKKGo5l9XFzwnMjw/D4kBC4OnGzT1PSagXsOJeH/+1OwcX8sgbn3eUOeCG2K54aHsphKUQ2gmHYhBiGiSgpswRLfzvf6BrB3m5OeO6OMDwxlCG4rWm119+g/G/PJVzKbzhpsaOnC964uwcmRQZySTYiK8cwbEIMw0S2K7ukCu/uSMYvSTkNznm5OuK5kV3wxJAQuMkZgqWk1QrYdjYX/9ud0uhKHtGdPPHmPb3QP8RLguqIqC0wDJsQwzCR7alVa7HywFWs2JOCmhs2g3Cyt8NTMaF4MbYrPJwdJaqQGqPWaLHpRBbe33URyvLaBucf6NcR8yf05HhiIivEMGxCDMNEtuVoahHm/3Sm0R7GiZGBeOOuHjazS5ylKq9R49P4y1h1ILXBmxlPV0fMu7sHHuofDDs7Dp0gshYMwybEMExkG4oqarFs2wVsOpHV4Bw/ZrdM2SVV+M+OZPzcyDCXgaFeePv+PggPcJegMiIyNoZhE2IYJrJugiDgx8RsLN16HsWVhmvYerk64p8TemJK/yBOwLJgJ9KL8M8fzzZYecLBToZn7wjD38d046oTRBaOYdiEGIaJrFdBWTX++eMZ7L5Q0ODc1AFBmHd3T3i5OUlQGRlbnUaL1Qmp+HD3JVTXGQ6d6ObfDu9PjUJkkKc0xRHRbWMYNiGGYSLr9OupHCz45SxKbugN7ubfDm/f3weDOntLVBmZUmZRJRZtOYc9yYZvgOztZHgxtiteiu0KJwc7iaojotZqSV4z65/wdevW4bnnnsOAAQMgl8shk8mwdu3a27pnXV0d+vbtC5lMhh49ehinUCKyWEUVtXhxfSLmfHfSIAg72dvhH+O7Y+vfRjAIW7Fgb1esmj4Anz3eD756q0potAJW7EnB/Z8cRHJeqYQVEpGpmfVimG+++SbS09Ph6+uLwMBApKen3/Y9lyxZgsuXLxuhOiKydH8kF+AfP5yGstxwG+WIDh54f2oUerTnpz+2QCaT4a7egRjU2Qdv/XIWv53OFc+dyynFvR8dxCvjwjFrRBhXnCCyQmbdM7xq1SqkpaWhsLAQzz///G3fLzExEcuWLcOyZcuMUB0RWapatRZvbz2Pp9YeMwjC9nYy/G1MN/z0wnAGYRvk7eaEuMf64aNHo+HpqlszulajxfLtyZi+5igKy2qauAMRWSKzDsN33nknQkJCjHKv2tpazJgxA0OGDMFLL71klHsSkeXJuFaJhz77EysPpBoc7+bfDj+9MAyvjA3nGFEbNymqA3bNvQN39vQ3OH4gRYkJKw7g4GWlRJURkSnYzL/4ixYtQkpKClavXs0lkYhs1K+ncnDPigM4laUyOP7U8FD8OieGqweQyN/dGSufHIB3H4yEi94ya4VlNXh89RG8t/Mi1BptE3cgIkth1mOGjeXYsWN499138c477yA8PFzqcoiojVXXabD41/P47miGwXFPV0e8NyUKd/YKkKgyMmcymQxTBwajX4gnXlp/Esl519clFgQg7o/LOHz1GlY8Go0Oni4SV0pEt8Pqe4ZramowY8YMREdH49VXX23V9aWlpQYPIrIc2SVVeOizQw2C8KBQb2z/+wgGYbqlrv7u+PnF4Xh8SCeD48fTizHpowQcvnpNosqIyBisPgwvWLAAKSkp+PLLL2Fv3/IdhZYtWwaFQiE+goODTVAlEZnCoSvXMOmjBJzJ1g2LkMmAv43uivXPDkaggj161DzOjvZYOrkPPpnWD+7Oug9Vr1XUYtqqI1hzMBVctp/IMll1GE5MTMQHH3yA+fPno0+fPq26x7x586BSqcRHZmamkaskImMTBAFfJqTi8dVHUFRRKx73cXPCt88MxivjusPB3qr/+SMTmdAnENv+NgJ9OirEYxqtgMW/nserG0+huk4jYXVE1BpW/dvg9OnT0Gg0WLRoEWQymcEDAC5evAiZTAZPT8+b3kMul8PDw8PgQUTmq6pWg1c2nsK/fjsPjVbXUxcVpMCvc2IwrKuvhNWRNQj2dsWm54fiwX5BBsd/PJmNKZ/9iaziSokqI6LWsOoJdOHh4XjmmWcaPbd69WooFApMmTIFrq6ubVwZEZlCnqoaM78+hrPZhmP7H+ofhCWTe8PZseVDpYga4+xoj/ceikRUsAL/+vU81H+98TqbXYp74w7is8f7c+dCIgthNWFYqVRCqVTC19cXvr7Xe36GDRuGYcOGNfr81atXo3379li1alVblklEJnIuR4Vn1h5HXmm1eMzBToaF90bg8cGduKQiGZ1MJsOTQ0PRo70HXvj2BJTl14fkFFXU4vFVR/DulEhMju4ocZVEdCtmPUxi1apVmDFjBmbMmIFNmzY1OPbzzz+Lz42Li0PPnj0RFxcnUbVEJJU9F/Lx0GeHDIKwbzs5vps1BE8MCWEQJpMa1Nkbv86JQVSwp3isVqPFy98n4cPdlzixjsjMmXXPcEJCAr766iuDYwcPHsTBgwcBAKGhoZg8ebIElRGRuVhzMBVLfjsPveHB6NHeHV/OGMj1X6nNBCpc8P2sIXj9h9PYcipHPP7h7hSkX6vE8gf7QO7AYTpE5kgm8C1ri5SWlkKhUEClUnEyHZGE1Botlvx2Hl8dSjc4HtvdDx891g/t5Gb9Xp+slCAI+O/vl7Bi72WD44NCvfH5E/3h5eYkUWVEtqUlec2sh0kQETWmqlaD59edaBCEpw8NwconBzAIk2RkMhleGdcd7z8UBUd73fCco2lFeODTP5FZxJUmiMwNwzARWRRVZR2e/PIIdl8oEI/JZMDCSb2w+L7eXD+YzMKD/YPwzTODoXBxFI+lKivw4Kd/IjmPO5kSmRP+1iAii5FfWo2HvziEY2nF4jEXR3usfGIAnhreWcLKiBoaEuaDn14YhhAf3fKdBWU1mPrZIRxLK5KwMiLSxzBMRBZB16tWJh7zcnXE+mcH485eARJWRnRzYX7tsHn2MER00I1ZLK1W4/FVR7D7fL6ElRFRPYZhIjJ7Z7NVmPLpn8gqrhKPdVA4Y9PzQxHdyUvCyohuzbedHBtmDcHQMB/xWI1ai+fWncAPJ7IkrIyIAIZhIjJzh69ewyNfHMa1ilrxWFf/dvhh9jB09XeXsDKi5nN3dsSapwbiroj24jGNVsBrm05h1YGrElZGRAzDRGS2ElKUmLHmKMpr1OKxvsGe2PTcUK4hTBbH2dEeH0/rh0cHdTI4vnTrBXz8x+WbXEVEpsYwTERm6Y+LBXj6q2OortOKx+4I98P6ZwdzrVayWPZ2Mrxzf2/MGd3V4Ph/dl7kbnVEEmEYJiKz8/v5fDz39QnUqnVBeHxEAFY9OQCuTlxDmCybTCbDq+O64//u7mFw/MPdKfjPzosMxERtjGGYiMzKtjO5mL3uBGo1uiA8MTIQcY/1g5MD/8ki6/H8yC5YMLGXwbFP4q/g7a0XGIiJ2hB/sxCR2fglKRtzvjsJtVYXBB6I7ogPH+4LR26mQVbomZjOWDK5t8GxVQmpWLTlHLRaBmKitsDfLkRkFn5Jysbc75Og0QsAUwcE4T8PRXFXObJqTwwJwb8f7AOZbvdmfHUoHYt+PcceYqI2wN8wRCS5HWdz8crGU9DvCHt8SCcsfyAS9naym19IZCUeHtgJ7z8UBf2/7l8fSsc72zhkgsjUGIaJSFJ7k/Mx57uTBj3CM4aFYsl9vWHHIEw25IF+QfjwkWiDQLzyQCo++P2SdEUR2QCGYSKSzIGUQjy/LhF1Gl0QfmxwJyyc1AsyGYMw2Z57ozrgvYeiDIZMfLT3Mj7akyJdUURWjmGYiCRx+Oo1PPv1cYPl06b0D8LS+3ozCJNNe6BfEN65v4/Bsfd/v4SV+7lTHZEpMAwTUZs7kV6MZ9YabqgxKaoD/v1gJIdGEAF4dFAnLL43wuDY29su4Ks/06QpiMiKMQwTUZu6kFuKGWuOoqJWIx67K6I9PpgaxclyRHqmDwvF/Ak9DY4t3HIOPyZmSVQRkXViGCaiNpNZVInpXx5FWbVaPDa6hz9WPBrNdYSJGvHsHWF4bVy4wbF//HAae5PzJaqIyPrwtw8RtYnCsho8sfoICspqxGNDw3zwyTTuLEfUlJdGd8MLo7qIbY1WwAvfJuJ4WpGEVRFZD/4GIiKTK62uw4w1R5F2rVI81rujB754sj+cHe0lrIzIMvxjfHc8OihYbFfXafH02mNIziuVsCoi68AwTEQmVV2nwbNfHce5HN0v7c6+blj71CC4OztKWBmR5ZDJZFg6uQ/uimgvHiutVuPJ1UeRWVTZxJVEdCsMw0RkMmqNFn/77iSOpOo+zg3wkOPrpwfBt51cwsqILI+9nQwfPtIXQ8K8xWMFfw0/UpbXNHElETWFYZiITEIQBLy15Rx2nddN9PFwdsDXTw9GsLerhJURWS5nR3usfHIAIjp4iMfSrlXiqTXHUFGjbuJKIroZhmEiMonP9l3F+iMZYtvZ0Q5rnhqI7u3dJayKyPK5Ozti7VODEOqje1N5JluFv313EmqNtokriagxDMNEZHS/nsrBv3cki217Oxk+mdYP/UO8m7iKiJrLz12Ob54ZbDDcaE9yARb/eh6CIDRxJRHdiGGYiIzqWFoRXt10yuDYkvt6Y3SPAIkqIrJOwd6u+HLGALjorcjyzeF0rE5IlbAqIsvDMExERnO1sBzPfn0ctWrdR7XPj+yCxwZ3krAqIusVGeSJjx6Nhv7mjW9vu4DtZ3KlK4rIwjAME5FRXCuvwVNrj6Gksk48NjEyEK+P7y5hVUTW785eAVh0b4TYFgTg5e+TcCK9WMKqiCwHwzAR3bbqOg2e/fo40vU21RgY6oX3HoqCnX6XFRGZxJNDQzEzprPYrlFr8ezXx5GmrJCwKiLLwDBMRLdFEAS8/sNpJGaUiMc6+7rhiycGcHc5ojb0zwk9cXdv3aYcRRW1eOarYyitrmviKiJiGCai2/JJ/BVsOZUjtr3dnLD2qYHwcnOSsCoi22NnJ8N/H+6L6E6e4rErhRX423cnodFyhQmim2EYJqJW23UuD//ZeVFsO9rL8MUT/RHi4yZhVUS2q35Tjo6eLuKx+IuFWL79goRVEZk3hmEiapULuaV4+fskg2Nv398HA0K5ljCRlHzbybHyyQFwddINU1p5IBWbjmdKWBWR+WIYJqIWu1Zeg5lfHUdlrUY8NjOmM6YOCJawKiKq16uDBz6Y2tfg2PyfzuJ4WpE0BRGZMYZhImqRWrUWs9clIrukSjw2MtwP8yb0lLAqIrrRXb3b47Vx4WK7VqPF8+tOGPzsEhHDMBG1gCAIeOuXsziq17sU5ueGFY9Gw55LqBGZnRdju2JSVAexrSyv/etTHbWEVRGZF4ZhImq29UczsOGYbtyhwsURq6cPhMLFUcKqiOhmZDIZ/jMlEpFBCvHYhdxS/N/mMxAErjBBBDAME1EzJWYUY9GWc2Lb3k6Gjx/rh86+XDmCyJw5O9rjiycGwN9dLh7bcioHXx5Mk64oIjPCMExEt1RYVoPZ606gTqPrSZp3dw/EdPOVsCoiaq72Cmd8+nh/ONrrhjO9s+0CDl+9JmFVROaBYZiImlSn0eLF9YnIL60Rj02MDMQzelu/EpH56x/ihbcmRYhtjVbAS+sTkavihDqybWYdhtetW4fnnnsOAwYMgFwuh0wmw9q1a1t0j4SEBLz66qvo378/fHx84OzsjB49euCNN95ASUmJSeomsibLtiXjaKpuwlz3AHe8OyUSMhknzBFZmscHd8KU/kFiW1lei9nrElGj1jRxFZF1kwlmPII+NDQU6enp8PX1hZubG9LT07FmzRrMmDGj2fdo3749lEolYmJiEB0dDZlMhvj4eJw8eRJdunTBn3/+CX9//2bfr7S0FAqFAiqVCh4eHq34rogsxy9J2fj7hiSx7e7sgC0vxXCcMJEFq67TYMpnf+Jsdql4bNrgTnj7/j4SVkVkXC3Ja2bdM7xq1SqkpaWhsLAQzz//fKvuMXfuXGRmZiI+Ph7//e9/8cEHH+DEiROYPXs2rly5gsWLFxu5aiLrkJx3fca5vg8f7ssgTGThnB3t8em0/vB01a0C8+2RDGw8xh3qyDaZdRi+8847ERISclv3eOONNxAYGGhwTCaTYcGCBQCAffv23db9iaxRWXUdnv/mBKrqdB+d/n1MN4zpGSBhVURkLMHervjo0WjoLw/+5i9ncS5HJV1RRBIx6zBsSo6O198ROzg4SFwJkXkRBAHzfjyDtGuV4rHY7n74+5huElZFRMY2opsfXhvfXWzXqrV4af1JlFXXSVgVUduz2TD85ZdfAgDGjRsncSVE5mXdkQz8djpXbHf0dMGHD0fDjjvMEVmd2SO74M6eunkzqcoKzPuRG3KQbbHJMJyUlITFixfD398fr7/+epPPrampQWlpqcGDyFqdzVZhya/nxbajvQwfT+sHhSt3mCOyRjKZDO89FIWOni7isd9O52LdkQwJqyJqWzYXhlNTUzFx4kRoNBps2LABvr5NbxqwbNkyKBQK8REcHNxGlRK1rdLqOrzwbSJqNVrx2Ly7e6JvsKd0RRGRyXm6OiHusWiDDTmW/HoeZ7M5fphsg02F4fT0dMTGxqKwsBA//PADYmNjb3nNvHnzoFKpxEdmJmfbkvURBAH/t/k0Mop044THRwTgqeGh0hVFRG0mupMX/u/unmK79q/Ndko5fphsgM2E4bS0NIwaNQo5OTnYuHEjJk6c2Kzr5HI5PDw8DB5E1ubrQ+nYdiZPbAd7u+DdKVHcWIPIhjw9PBTjeulWjEm/Von/23ya44fJ6tlEGK4PwtnZ2fj+++9x3333SV0Skdk4k6XC21sviG1Hexk+fqwfFC4cJ0xkS2QyGf4zJQpBXrrxw9vO5OGbw+kSVkVkelYThpVKJZKTk6FUKg2O6wfhDRs24P7775eoQiLzU1Gjxt82nDQYJzx/Qk9EBnlKVxQRSUbh6oiPH+tnMH546dYLuJDLyeNkvcx6kd1Vq1YhISEBAHDmzBnxWHx8PABg8uTJmDx5MgAgLi4OixcvxsKFC7Fo0SLxHqNGjUJ6ejqGDBmC06dP4/Tp0w2+jv7ziWzJoi3nkKqsENt3926P6cNCpSuIiCQXFeyJ+RN6YtFfK8vUqrX423cn8eucGDg72ktcHZHxmXUYTkhIwFdffWVw7ODBgzh48CAAIDQ0VAzDN5Oefv3jncOHD+Pw4cONPodhmGzRr6dysOlEltjuoHDG8gciOU6YiDB9WCgOpCixJ7kAAJBSUI6lW89j6eQ+EldGZHwygSPjW6S0tBQKhQIqlYqT6chiZRZVYsL/DqCsRg0AsJMBG2YNxaDO3hJXRkTm4lp5De7+3wEUlNWIxz5/oj/GR7SXsCqi5mlJXrOaMcNE1DxqjRYvf58kBmEAeGl0NwZhIjLg006OD6b2NTj2xubTyFNVS1MQkYkwDBPZmBV7L+NEerHYHhDihb+N7iphRURkrmK6+eK5O8LEdkllHeZ+nwSNlh8qk/VgGCayIUdTixC3N0Vsuzs74MNH+sLBnv8UEFHjXh3XHZFBCrF96Oo1fL7/ioQVERkXfwMS2QhV1fUeHf0OnXfu74MgL1fpiiIis+fkYIf/PRINVyfdShIf7LqEpMwS6YoiMiKGYSIbsWjLOWSXVInth/oHYVJUBwkrIiJL0dnXDYvvjRDbaq2AV75PQlWtRsKqiIyDYZjIBmw7k4ufTmaL7VAfVyzS+8VGRHQrU/oHYWJkoNi+qqzA8u0XmriCyDIwDBNZuYLSavzzpzNi204GfPBwX7jJzXqZcSIyMzKZDEsn90aAh1w89tWhdBxIKZSwKqLbxzBMZMUEQcDrm0+jpLJOPPbCqK7o18lLwqqIyFJ5ujrhP1OiDI79Y9NpqPT+jSGyNAzDRFZs/dEMxF/U9dpEdPDA38Z0k7AiIrJ0d4T74cmhIWI7r7QaC345K2FFRLeHYZjISqUpK7D0N914PicHO3z4cF84OfDHnohuz7y7eyLM101sbzmVg19P5UhYEVHr8bcikRVSa7R4ZWMSqup0M71fH98d3QLcJayKiKyFi5M9Pni4L+ztZOKxN38+y93pyCIxDBNZoc/3X0ViRonYHhrmg6eHd5auICKyOn2DPfFirG73SlVVHf7xwykIAnenI8vCMExkZZLzSvHh7kti213ugPemRsFOrweHiMgY5ozuarA73YEUJTYcy5SwIqKWYxgmsiJ1Gi1e23QKdRpdz8yieyPQ0dNFwqqIyFo52tvhg6l9Idebi/D21gsGG/wQmTuGYSIr8sX+qzibXSq27+zpjwf6dZSwIiKydl392+G1cd3FdnmNGv+3+TSHS5DFYBgmshIX88oMhkd4ODvg7fv7QCbj8AgiMq2nYzojupOn2D6QosTG4xwuQZaBYZjICqg1WvzjB8PhEQsnRSDAw1nCqojIVtjbyfCfKVEGSzcu/e0CcjhcgiwAwzCRFfjiwFWczlKJ7TE9ODyCiNrW9eES4WK7rEaNeT+e4XAJMnsMw0QWLiW/DB/+niK2PZwd8M4DHB5BRG3vmZgwg+ES+y4VYtOJLOkKImoGhmEiC6bWaPHaD6dRq9GKx97i8Agiksj14RKRBsMllvx2HrkqDpcg88UwTGTBViek4lRmidiO7e6HBzk8gogk1NXfHa+M1RsuUa3G/J/OcrgEmS2GYSILlaaswAe/622u4eyAZQ9EcngEEUluZkxnRAV7iu29yQX49XSudAURNYFhmMgCCYKAf/50BjVq3fCI+RN6or2CwyOISHoO9nb4z5RIONrr3pwv3nIOxRW1ElZF1DiGYSILtOlEFv68ck1sDw3zwcMDgyWsiIjIUHiAO14Y1VVsX6uoxdvbLkhYEVHjGIaJLExhWQ3e3qr7hSJ3sOPqEURkll6I7YKu/u3E9g8nspCQopSwIqKGGIaJLMziX89BVVUntl++Mxydfd0krIiIqHFyB3ssf6CPwbF//nQGVbUaiSoiaohhmMiC7D6fj9/0JqH0DPTAzBGdJayIiKhpA0K98cSQELGdUVRpsHU8kdQYhoksRFl1HRb8clZs28mAfz/YB472/DEmIvP2+l3d0V5v/fOVB67ibLaqiSuI2g5/ixJZiP/svIhcVbXYfiamMyKDPKUriIiomdydHbFkcm+xrRWANzafhlpvwyAiqTAME1mAxIxifHM4XWwHe7tgrt6i9kRE5m5srwDc0ydQbJ/LKcWXB1MlrIjoOoZhIjOn1mj/2r1Jd+yd+/vA1clBuqKIiFph4b294OGs+7frv7+nILuEWzWTtBiGiczc2j/TcCG3VGxP7tsBI7r5SVgREVHr+Ls7Y96EnmK7qk6DRVvOSVgREcMwkVnLKaky2HLZw9kB8+/pJWFFRES35+EBwejXyVNs/34+H7+fz5euILJ5DMNEZuxfv55Hpd56nK/f1QN+7nIJKyIiuj12djK8fX8f2NvpNgpatOUcKmvVElZFtoxhmMhM7U3Ox45zeWK7b7AnHhvUScKKiIiMo2egB54eHiq2s0uq8L89KdIVRDaNYZjIDFXVavDWL7pxdHYyYOnk3rCz45bLRGQdXr4zHIEK3drDqw+k4mJemYQVka1iGCYyQx/tTUFWsW6G9YxhndG7o0LCioiIjMtN7oBF90aIbbVWwJs/n4FWKzRxFZHxMQwTmZmU/DKsPHBVbLf3cMYr47imMBFZn3G9AnBnT3+xfSytGD+cyJKwIrJFDMNEZkQQBLz581nUaXQ9I29N6oV2cq4pTETWRyaTYeGkCDg76uLIO9svoKiiVsKqyNYwDBOZkS2ncnAktUhsj+ruh7t7t5ewIiIi0wr2dsXfx+g+/SqprMN7uy5KWBHZGoZhIjNRXqPGO9suiG0nBzssvjcCMhknzRGRdZs5ojO6+rcT298dzcDprBLpCiKbYtZheN26dXjuuecwYMAAyOVyyGQyrF27tsX30Wq1iIuLQ2RkJFxcXODn54epU6ciJYXLuJD5+GhPCvJLa8T28yO7IMTHTcKKiIjahqP99Tf/9QQBeOuXc5xMR23CrMPwm2++iS+++ALp6ekIDAxs9X2ef/55zJkzBxqNBnPmzMGECROwZcsWDBw4EOfPnzdixUStc7mgHKsTUsV2R08XzB7ZRcKKiIja1vCuvrinj+53fVJmCX5I5GQ6Mj2zDsOrVq1CWloaCgsL8fzzz7fqHn/88QdWrlyJESNGIDExEe+++y6++uorbN26FaWlpZg9e7aRqyZqGUEQsGjLOai1hpPmXJzsJayKiKjtzb+nJ1wcdf/2/Xt7MlRVdRJWRLbArMPwnXfeiZCQkNu6x8qVKwEAS5cuhVyu28Z2zJgxGD9+PPbv349Lly7d1tcguh07zuYh4bJSbN8R7odxvQIkrIiISBodPF3w0uiuYvtaRS3++zt/R5NpmXUYNob4+Hi4ublh+PDhDc6NHz8eALBv3762LosIwPWd5pb8phuq42gvw8JJvThpjohs1swRnRHq4yq2vz6Uhgu5pRJWRNbOqsNwRUUFcnNz0blzZ9jbN/zIuVu3bgDAiXQkmU/iLyNHVS22n4kJQxe/dk1cQURk3eQO9lioN5lOKwALfzkHQeBkOjINqw7DKpUKAKBQNL6NrYeHh8HzGlNTU4PS0lKDB5ExpCkr8Pk+3U5zAR5yzNH7eJCIyFbFdvfHnT11w8WOphVhy6kcCSsia2bVYdgYli1bBoVCIT6Cg4OlLomsxNKt51Gr0Yrt+ff0ght3miMiAgC8NbEXnBx0MeXtrRdQUaOWsCKyVlYdhut7hG/W81vfy3uznmMAmDdvHlQqlfjIzMw0fqFkcw6kFGL3hQKxPSTMG5MiW798IBGRtenk42qwxGRBWQ0+jb8iYUVkraw6DLu5uSEwMBCpqanQaDQNztePFa4fO9wYuVwODw8PgwfR7VBrtAaT5uxkwMJJ3GmOiOhGz4/sgg4KZ7H9xYGryCyqlLAiskZWHYYBYOTIkaioqMDBgwcbnNu5c6f4HKK2sv5oBi7ll4vtRwZ1Qs9AvskiIrqRi5M93ri7h9iuVWuxfHuyhBWRNbKaMKxUKpGcnAylUmlwfNasWQCu72ZXW1srHt+zZw927tyJO+64A+Hh4W1aK9mukspafKC3Zqa7swNeHcu/f0REN3NvVAf0D/ES21vP5OLI1WsSVkTWxqzD8KpVqzBjxgzMmDEDmzZtanDs559/Fp8bFxeHnj17Ii4uzuAesbGxmDlzJg4cOIDo6Gi8/vrrmD59Ou655x54eHjg008/bctviWzch7tTUFKp203p72O6waedvIkriIhsm0wmw1sTexkc+9dv56HRcqk1Mg6znrqekJCAr776yuDYwYMHxSEPoaGhmDx58i3v8/nnnyMyMhKff/45VqxYgXbt2mHSpEl4++232StMbSYlvwzfHE4X22G+bnhyaKh0BRERWYioYE882C8ImxOzAADnckrxw4lMPDywk8SVkTWQCVzFukVKS0uhUCigUqk4mY6aTRAETF9zDPsvFYrHvpwxAKN7cNtlIqLmyC+tRux78aisvT4h3redE/54bRTcnR0lrozMUUvymlkPkyCyFn9cLDAIwneE+yG2u7+EFRERWZYAD2e8GKvbmEhZXou4Py5LWBFZC4ZhIhOrVWux9LcLYtveToYF9/TkUmpERC30TExnBHm5iO01CWlIv1YhYUVkDRiGiUzs2yPpuKrU/WP9xJAQdAtwl7AiIiLL5Oxoj39O6Cm2azVaLNvGpdbo9jAME5mQqqoO/9uTIrYVLo54+c6bb/JCRERNu7t3ewzu7C22d5zLw7G0IgkrIkvHMExkQh//cbnBUmqerk4SVkREZNlkMhnevMdwqbWlWy+A6wFQazEME5lIZlEl1h5ME9uhPq54fEiIdAUREVmJPkEK3B/dUWyfyizBb6dzJayILBnDMJGJvLvzImo1WrH9f3f3gJMDf+SIiIzhtfHdIdf7N/XfO5JRo9ZIWBFZKv5mJjKBkxnF+PVUjtgeEOKF8RHtJayIiMi6dPR0wTMxncV2VnEVvvozTbqCyGIxDBMZmSAIeGfbBYNj87mUGhGR0c0e1QU+brp5GB/tvYziiloJKyJLxDBMZGQ7z+XjWFqx2J4YGYjoTl4SVkREZJ3cnR3x8thwsV1WrcaKvSlNXEHUEMMwkRHVqrVYvl3XK+xkb4c37uohYUVERNbtkYHB6OLnJra/OZSOVCU34qDmYxgmMqJvj6Qj7Vql2J4+LATB3q4SVkREZN0c7e0w727dRhxqrYB/b+dGHNR8DMNERlJaXYcVehtseLo64qVYbrBBRGRqY3r6Y0iY4UYcx7kRBzUTwzCRkXy+7wqK9TbY+NvoblC4OkpYERGRbWhsI47l25O5EQc1C8MwkRHkl1ZjdUKq2A72duEGG0REbah3RwUm9+0gto+nF2P3hQIJKyJLwTBMZAT/25OC6jrdBhuvjevODTaIiNrYq+O6w9Fet4zluzuSodGyd5iaxt/WRLfpSmE5vj+WKbZ7BXpgUmSHJq4gIiJTCPZ2xbTBuk/lUgrKsTkxS8KKyBIwDBPdpvd2XjToefi/u3vAzo4bbBARSWHO6K5oJ3cQ2//9/RKq67hNM90cwzDRbTiZUYztZ/PE9vCuPhjRzVfCioiIbJtPOzlm3REmtnNV1fj6UJp0BZHZYxgmaiVBELD8hrUs37irB7ddJiKS2DMxneHbTi62P/7jClR6q/0Q6WMYJmql+EuFOJKqW8fynshARAZ5SlcQEREBANzkDvj7mK5iW1VVh0/3XZGwIjJnDMNEraC9YYcjBzsZXhvXXcKKiIhI3yODOiHUR7cD6JqDqchTVUtYEZkrhmGiVvjlVDaS88rE9qODOqGzr5uEFRERkT5Hezu8Nl7XSVGj1uK/v1+SsCIyVwzDRC1Uq9biA71/UF0c7TFH7+M4IiIyDxN6B6JPR4XY/iExC1cKyyWsiMwRwzBRC31/PBOZRVVie+aIzvB3d5awIiIiaoydnQxv3NVDbGu0AnuHqQGGYaIWqK7T4KM9KWJb4eKIZ/WW8CEiIvMS080Xw7r4iO3fTufifE6phBWRuWEYJmqBrw+loaCsRmw/P7ILPJwdJayIiIhuRX/sMAC8v+uiRJWQOWIYJmqmsuo6fBqvW5rHz12O6cNCmriCiIjMQb9OXhjTw19s70kuwIn0YgkrInPCMEzUTKsTUlGst2j7S7Fd4erk0MQVRERkLl69YfnL93ayd5iuYxgmaobiilqsOpAqtjt6uuCRQcESVkRERC3Rq4MHJkYGiu1DV6/h4GWlhBWRuWAYJmqGz/ZfQXmNWmz//c5ukDvYS1gRERG11Ctjw2FvJxPb/9l5EYIgSFgRmQOGYaJbKCitxld/pontMD83PBDdUbqCiIioVcL82uHBfrp/v5MyS7D7QoGEFZE5YBgmuoW4Py6juk4rtl8ZGw4He/7oEBFZor+N6QZHe13v8Pu7LkKrZe+wLeNvdKImZBZV4rujGWK7Z6AHJvQObOIKIiIyZ0Ferpg2WLcSUHJeGX49nSNhRSQ1hmGiJny0NwV1Gl2PwT/Gh8NOb7wZERFZnhdiu8DZUReB/rc7BWqNtokryJoxDBPdRPq1CmxOzBbb/Tp5Ira7fxNXEBGRJfB3d8aMYZ3F9lVlBbacYu+wrWIYJrqJFXsuQ6M3juyVsd0hk7FXmIjIGsy6IwxuTrpVgVbsYe+wrWIYJmpEqrICP53MEtsDQ70wvKtPE1cQEZEl8XZzwlPDdb3Dadcq8dPJ7CauIGvFMEzUiBV7UqA/uXju2HD2ChMRWZmZIzrDXa7bSXTF3hTUsXfY5jAME93gckE5fknS9Q4M7uyNYV18JayIiIhMwdPVCU/F6HqHM4uq8GNiVhNXkDViGCa6QWO9wkREZJ2eiekMd2e93uE9l1GrZu+wLTH7MHzs2DFMmDABXl5ecHNzw6BBg7B+/foW3aOkpARvvfUWIiMj4e7uDl9fXwwcOBBxcXGorq42UeVkiVLyDdebHNbFB0PCOFaYiMhaKVwcMTMmTGxnl1ThhxPsHbYlZh2G4+PjERMTgwMHDmDKlCmYPXs2lEolpk2bhnfeeadZ9ygpKUH//v2xZMkSKBQKPPfcc3j00UdRXFyMOXPm4J577oFWy3eAdN2He1IgsFeYiMimPBUTCoWLo9iO25uCGrVGwoqoLZltGFar1Zg5cyZkMhn279+PlStX4r333sOpU6cQERGBhQsXIiUl5Zb3+eKLL3D16lXMnTsXBw4cwHvvvYePPvoI58+fx8CBA7F3714kJCS0wXdE5i45rxTbzuSK7RHdfDEw1FvCioiIqC14ODvi2RG6scM5qmpsPM7eYVtxW2F4z549mD9/PmJjY9GtWzd4eXmhY8eO6Nu3L5544gmsWrUKeXl5rbr33r17ceXKFTz22GOIjo4Wj7u7u2PBggVQq9VYs2bNLe9z9epVAMCECRMMjjs5OWHs2LEAgIKCglbVSNblf7sNe4VfvpO9wkREtmLG8M7wdNX1Dn+89zKq69g7bAtaHIbLy8vxzjvvoHPnzhg3bhyWLVuGffv2ITs7G25ubqiursbZs2fx7bffYtasWejUqROmTJmCgwcPtujrxMfHAwDGjRvX4Fz9sX379t3yPhEREQCAHTt2GByvq6vD7t274eLigqFDh7aoNrI+F3JLsf2s7o3byHA/9A/xkrAiIiJqS+3kDph1h27scF5pNb4/lilhRdRWWhSGP/vsM3Tt2hVvvvkmPD09sXTpUuzduxelpaWorKxEVlYWrl27hrq6OiQnJ+Orr77Cww8/jF27duGOO+7AAw88gNTU1GZ9rfohEN26dWtwzsvLC76+vs0aJjFz5kwMHDgQ77//PkaNGoV//OMf+Nvf/oaIiAhcvXoV69evR8eOHVvyv4GsUNzeywZtjhUmIrI904eGwtvNSWx/tu8Kxw7bAIdbP0Vnzpw5mDZtGv7xj3+IPa6NkclkCA8PR3h4OJ544glUVVXhu+++w7Jly/DNN9/grbfeuuXXUqlUAACFQtHoeQ8PD2Rl3Xo8j4uLC+Lj4/Hcc89h3bp1Ym+ynZ0dXnrpJcTExDR5fU1NDWpqasR2aWnpLb8mWZaU/DJsO6sbKzyqux/6BntKVxAREUnCTe6AZ0eE4d87kgEAuapqbD6RjccGd5K4MjKlFvUMJycnY+3atU0G4ca4uLjg6aefRnJyMqZPn96ia2+XUqnE2LFjcfjwYWzduhUlJSXIy8vDZ599hjVr1mDw4MEoLi6+6fXLli2DQqEQH8HBwW1YPbWFuD8uG4wVnjO64acRRERkG54YGmI4dviPy9yVzsq1KAx36dLltr6Yvb09QkJCmvXc+h7h+h7iG5WWlt6011jfK6+8gj///BObN2/GhAkToFAoEBAQgGeffRbvvvsurl69ig8//PCm18+bNw8qlUp8ZGZy/JA1uVJYjl9P6dYVjunqy7HCREQ2rJ3cAc8M160skV1ShZ8Ss5u4gixdq1eTUKvVyM3NxbVr14xZj6h+rHBj44KLi4uhVCobHU98o61bt8Lb2xuRkZENzo0ePRoAcOLEiZteL5fL4eHhYfAg6/HxH5cNdpv72xj2ChMR2brpw0MNdqWL++My1OwdtlotDsPbtm1DTEwMnJ2dERQUBH9/f7i5uaFfv36YM2cOtm3bBo3m9gebjxw5EgCwa9euBufqj9U/pym1tbUoLS1FbW1tg3OFhYUArgdesj3p1yrwS5KuV3hwZ28M6sx1hYmIbJ2HsyOe0usdziiqxBa9TxHJurQoDG/YsAGTJk3CoUOH0LNnT4wYMQIDBw6Em5sbkpKS8PHHH2PSpEkIDg7GihUrbmtntzFjxiAsLAzr169HUlKSeLysrAxLliyBg4MDZsyYIR5XKpVITk6GUqk0uM/w4cOhVquxZMkSg+M1NTXisdjY2FbXSZbrkz+uQKPXLfx39goTEdFfnh4einZyvd7hvZcNfmeQ9WhRGH777bfh6+uLxMREnDlzBvHx8Th8+DBefPFFyGQybN26FS+++CIEQcDLL7+MmJiYVm9o4eDggFWrVkGr1WLEiBGYNWsWXnvtNURFReHcuXNYtGgRwsN1y1/FxcWhZ8+eiIuLM7jP8uXL4e7ujqVLl2Lw4MF45ZVX8MILL6BXr17YuXMn+vfvj5kzZ7aqRrJcmUWV2JyoW41kQIgXhnbxkbAiIiIyJ56uTpg+TDfP6aqyAr+dZu+wNWpRGL58+TIef/xxREVFNXr+7rvvxooVK5CRkYEVK1bgzJkzGDNmDKqqqlpVXGxsLBISEhATE4ONGzfik08+gY+PD9atW4f58+c36x59+/bFiRMn8NRTTyEvLw9xcXFYu3Yt3NzcsHjxYuzfvx/Ozs6tqo8s16f7rkCt9w7/b2O6QSaTSVgRERGZm2diwuDqZC+24/Zehpa9w1anResMBwQENGudXUdHR7z00ksYMGAARo0aheXLl2Px4sWtKnDQoEHYvn37LZ+3aNEiLFq0qNFz3bp1w5dfftmqr0/WJ6ekCpuO61YFiQr2xIhuvhJWRERE5sjbzQlPDAnB5/uvAgBSCsqx41weJvQJlLgyMqYW9QxPnjwZGzduxNWrV5v1/CFDhmDq1KlYv359q4ojMoXP911BnUZ/rHBX9goTEVGjZo4Ig7OjLi6t2JPC3mEr06IwvHDhQri7u2PEiBHYtm1bs65p3759s3aKI2oLBWXV+E5vr/neHT0Q291fwoqIiMic+bnLMW2wbuxwcl4Z9ia3bj4UmacWhWEvLy/s3bsXrq6umDRpEvr164cPP/wQ2dmNL0adnZ2NDRs2oFMnbmNI5mF1Qipq1bpVTl6K5VhhIiJq2nN3hMHJXheZru9cyt5ha9GiMcMAEB4ejqSkJCxevBgff/wxXnnlFTFMjB49GoGBgZDL5cjPz8e+fftQWVmJTz/91OiFE7WUqrIO6w6li+1u/u0wrleAhBUREZEl8PdwxkMDgvDtkQwAQFJmCQ5duYZhXTnfxBrIhNt4a6NSqbBx40bs2LEDBw8ebLCMWpcuXTBv3jw8/fTTt12ouajfBlqlUnE3OguzYk8KPvj9ktj+78NRuD86SMKKiIjIUmRcq0Ts+/HiWsPDu/rg25lDJK6KbqYlee22wvCNiouLkZ2djbq6OgQEBKBDhw7GurXZYBi2TBU1agz/916UVNYBAIK8XBD/2ig42Ld6R3IiIrIxc79Pwk8ndUNDf3phGKI7eUlYEd1MS/KaUZOAl5cXevfujejoaKsMwmS5vjuaIQZhAHh+ZBcGYSIiapHZo7oYtD+JvyJRJWRMLUoDEydOxIkTJ1r1haqqqvDee+9x/DC1uRq1BisP6JYD9HOXY0p/Do8gIqKWCQ9wN5hr8vv5fFzMK5OwIjKGFoXhzMxMDBo0CGPGjMHatWubtQHH8ePH8fLLLyMkJARvvfUWfH052Jza1uYT2cgvrRHbz47oDGdH+yauICIiatyLsV0N2p/GX5aoEjKWFo0ZFgQBa9aswb/+9S9kZGTAzs4OPXr0QL9+/RAQEAAvLy9UVVWhqKgIKSkpOH78OFQqFezs7DB16lS8/fbbCA0NNeG3Y3ocM2xZ1BotRr+/DxlFlQAAhYsj/vy/0XCTt3ghFSIiIgDAE6uP4ECKEgBgJwPiX4tFJx9XiasifSafQKfVarF161asXbsW+/btQ1FRUYPn2NnZITIyEpMnT8bMmTOtZgwxw7Bl+SUpG3/fkCS2X76zG16+M1y6goiIyOIdunINj648LLYfHdQJyx7oI2FFdKOW5LVWdY/Z2dlh0qRJmDRpEgDgwoULyMrKwrVr1+Di4gI/Pz9ERERAoVC05vZERqHVCvj4D93HV65O9pgxLFS6goiIyCoMCfNGv06eSMwoAQBsPpGFv4/phvYKZ2kLo1a5rc+KExMTkZWVhZCQEIwdO9ZYNREZxe4L+biUXy62Hx8SAk9XJwkrIiIiayCTyfBibFc889VxAECtRotVB67izYm9JK6MWqNVa0tVVFRg6tSp+OWXX5CZmYm4uDjExMTgwoULxq6PqFUEQcCn+3RL3jjZ22FmTGcJKyIiImsyuoc/erR3F9vrj2agpLJWwoqotVoVht99910UFxejY8eOuOeee7By5Up89913mDNnDvLz841dI1GLHUsrxsm/Pr4CgCkDguDvwY+viIjIOGQymcG6w5W1GnxzKF3Ciqi1WhWGjxw5gjVr1qBr1674+OOPcf/992P58uUYMGAA3nvvPWPXSNRin+n1CtvJgFkjwiSshoiIrNE9fQIR7O0ittf+mYbqOo2EFVFrtGrMcGlpKYKCghAUFITRo0cDALKzs7F9+3asXLnSqAUStdTFvDLsTS4Q23f3DkSor5uEFRERkTVysLfDsyPC8NYv5wAA1ypqselEFp4YEiJxZdQSRtuPtmPHjpg5cyYcHR2NdUuiVvl8n+H2mM+NZK8wERGZxkP9g+HtppucvXL/Vag1WgkropYyWhiup9XyLwBJJ7ukCltO5YjtYV18EBnkKV1BRERk1Vyc7DF9aKjYziiqxPazedIVRC3WqjAsCAJWrlyJjIwMY9dDdFtWH0iFWqvbR+b5kV2aeDYREdHte3JoCFwc7cX2Z/uuoBV7mpFEWt0zrFAosHTpUtx1112YO3cuduzYgaqqKmPWRtQiJZW12HBM9wYtooMHRnTzlbAiIiKyBV5uTnhkULDYPpdTioTLSgkropZodRju378/vvjiC+zYsQMvvvgiUlNT8cwzzyA9PR3Lly/HkSNHOGSC2tTXh9JRWaubxfvcyC6QyWQSVkRERLZi5ogwONjpfud8dsP8FTJfMqEV/fjbt2/HTz/9hCtXrqBr164YO3YsRo8eDW9vb2i1Whw7dgy///47Dh8+DCcnJ8TExOCVV14xRf1triV7XVPbqarVYPi/96Ko4vqC58HeLvjj1VFwsDf6sHgiIqJGvfJ9En48mS22f30pBn2CFBJWZLtaktdaFYb1Xb16Fbt378bevXuhUqkQHR2NsWPHYvjw4XByckJFRQWGDx+OpKSk2/kyZoNh2Dx9fShNXNoGAJbcF4En9CY0EBERmdrFvDKM/3C/2L6nTyA+ntZPwopsV0vyWqvWGdYXFhaGWbNmYdasWRAEASdPnsTu3bvxv//9D3Z2dhg+fDhqa7k9IZmOWqPFygNXxbaPmxMeGhDcxBVERETG1729O0b38BfXut9+NhdpygqudW/mbjsM65PJZOjXrx/69bv+Lqi2thYJCQm4//77jflliAzsOJeHzCLd5M0Zw0LhrDerl4iIqK08P7KLGIa1ArA6IRVLJveWuCpqikkHVDo5OWH06NF4++23TfllyIYJgoCV+3W9wq5O9nhiKHf+ISIiaQwM9UJ0J0+xvelEpjifhcwTZxeRRTuaWoRTWSqxPXVAMDxdnZq4goiIyHRkMhlmjdDtfFpdp8W6w+kSVkS3wjBMFm3lgVTxz3Yy4OnhnSWshoiICBgX0R6dvF3F9teH0lBdp2niCpISwzBZrCuF5dh9IV9s3907EJ18XJu4goiIyPTs7WR4JkbXOaMsr8XPekuukXlhGCaLtUqvVxgAZo5grzAREZmHhwYEQeHiKLZXHrgKrZZbNJsjhmGySMryGvyYmCW2r09Y8JKwIiIiIh1XJwc8MUQ3oftKYQXiLxVIWBHdDMMwWaRvDqWjRq3b7vtZvckKRERE5uDJYSFw0tsJ9Qu91Y/IfDAMk8WprtPgG72ZuZ193XBnzwAJKyIiImrI390Zk6M7iO3DV4twRm8FJDIPDMNkcTYnZhms2fhMTGfY2ckkrIiIiKhxM2/45FJ/x1QyDwzDZFG0WsFg4py3mxMe7BckYUVEREQ3Fx7gjlHd/cT21jO5yCqulLAiuhHDMFmU3RfykaqsENtPDAmBixO3XiYiIvOlvwmHRitgzcE06YqhBhiGyaLo9wrLHey49TIREZm9oV18ENHBQ2xvOJoBVVWdhBWRPoZhshins0pwNK1IbD/QLwi+7eQSVkRERHRrMpnMYNWjiloNNh7LlLAi0scwTBbjywTDTTb0d/chIiIyZ/dEBqK9h7PYXvtnGtQabRNXUFthGCaLkKeqxm+nc8X2qO5+6OrfTsKKiIiIms/R3g5PDtMN7csuqcKu8/kSVkT1zD4MHzt2DBMmTICXlxfc3NwwaNAgrF+/vsX3KSsrw8KFC9G7d2+4urrC09MT/fr1w+LFi01QNRnb14fSoNbbxpK9wkREZGkeG9QJzo666HXjJ54kDbMOw/Hx8YiJicGBAwcwZcoUzJ49G0qlEtOmTcM777zT7PtkZGQgOjoaS5YsQYcOHTBnzhzMmDEDHTp0wObNm034HZAxVNVqsP5ohtgOD2iHmK6+ElZERETUcp6uhsuBHk8vxqnMEukKIgCATBAE4dZPa3tqtRo9evRAVlYWDh06hOjoaADXe3iHDh2Kixcv4vz58+jWrVuT99FoNBg6dCjOnj2LrVu3IjY2tsHXcXBwaHZdpaWlUCgUUKlU8PDwuPUFdNu+PZKO+T+dFdvLH+iDRwZ1krAiIiKi1rlSWI4x7+8T2/dGdcCKR6MlrMg6tSSvmW3P8N69e3HlyhU89thjYhAGAHd3dyxYsABqtRpr1qy55X1++OEHHDt2DK+99lqDIAygRUGY2p5WKxh8jOTt5oTJ0R0lrIiIiKj1uvi1Q6zeJhzbzuQiV1UlYUVktmE4Pj4eADBu3LgG5+qP7du3r8G5G33//fcAgIceegiZmZn47LPPsHz5cmzatAnl5eXGK5hMYl9KIa4U6jbZmDa4E5wduckGERFZrqf15r2otQK+PpQuYTVktt2iKSkpANDoMAgvLy/4+vqKz2nK8ePHAQAJCQmYO3cuampqxHN+fn7YuHEjRo0aZZyiyej0e4Ud7WV4Ygg32SAiIssW09UX3QPccTG/DACw/kgG5ozuClcns41lVs1se4ZVKhUAQKFQNHrew8NDfE5TCgoKAABz5szByy+/jMzMTBQWFmLFihVQqVSYPHkycnNzb3p9TU0NSktLDR7UNi7ll+FAilJsT4rsAH+9NRqJiIgskUwmw9MxoWJbVVWHHxOzpSvIxpltGDYWrfb6gtYTJ07E8uXLERQUBF9fX8yZMwdz586FSqXC6tWrb3r9smXLoFAoxEdwcHBblW7zblxy5mkup0ZERFbivr4d4e3mJLa/PJgKrdYs1zSwemYbhut7hG/W+1s/S7C597n33nsbnJs0aRIA3VCKxsybNw8qlUp8ZGZy+8S2cK28Bj+e1L1LHtTZG7073vr1JiIisgTOjvZ4fLBuZaSrhRXYd6lQwopsl9mG4fqxwo2NCy4uLoZSqbzlsmoA0L17dwCAp6dng3P1x6qqbj6LUy6Xw8PDw+BBprf+SAZq1bptKrnJBhERWZvHh4bA0V4mtr88yE04pGC2YXjkyJEAgF27djU4V3+s/jlNGT16NADg/PnzDc7VHwsNDW1tmWQCdRotvjmsm1kb7O2CO3sGSFgRERGR8fm7O2NSVAexfSBFiZS/JtVR2zHbMDxmzBiEhYVh/fr1SEpKEo+XlZVhyZIlcHBwwIwZM8TjSqUSycnJUCqVBvd56qmnIJfL8dFHHyE7O9vgPvW72E2dOtWk3wu1zPazeSgo0636MWNYZ9jbyZq4goiIyDI9Pdzwk8+vDqVJU4gNM9sw7ODggFWrVkGr1WLEiBGYNWsWXnvtNURFReHcuXNYtGgRwsPDxefHxcWhZ8+eiIuLM7hP586d8Z///AcFBQWIiorCs88+i5deegmRkZFISkrCrFmzMGbMmLb+9qgJa/U+JnJ1ssdDA4KaeDYREZHl6t1RgYGhXmJ784lsqKrqJKzI9phtGAaA2NhYJCQkICYmBhs3bsQnn3wCHx8frFu3DvPnz2/2febMmYMtW7agV69e2LBhA1avXg0fHx988cUX+Pzzz034HVBLnc4qQWJGidh+sF8QPJwdpSuIiIjIxKYPCxX/XFWnwabjnKzflmSCIHAdjxZoyV7X1HKvbEwyWGtx9yt3oKu/u4QVERERmVadRosR//4DeaXVAIBO3q7447VRHCJ4G1qS18y6Z5hsS2FZDX47pdsAZUQ3XwZhIiKyeo72dnhiqG6H1YyiSvyRXCBhRbaFYZjMxndHM1Cr0S2n9tTwUOmKISIiakOPDAyGk4Mulq39M026YmwMwzCZhVq1Fuv0llML8XHFqHB/CSsiIiJqOz7t5LhPb5m1hMtcZq2tMAyTWdh+NtdgObXpQ0Nhx7FSRERkQ/Qn0gHsHW4rDMNkFr7S+4F3dbLHFC6nRkRENubGZdZ+TOQya22BYZgkdyrTcDm1Kf25nBoREdmmGcN0m3BwmbW2wTBMkvvqho+BnhwaKkkdREREUhsXEYBAhbPY/upQGjRaroJrSgzDJKnCshr8ejpHbN8R7oeu/u0krIiIiEg6jvZ2eHyIbpm1zKIq7LmQL2FF1o9hmCS14WgG6jS6d7xP3TB5gIiIyNY8OqiTwTJr3+ittkTGxzBMklFrtFh/NENsh/i4YmS4n4QVERERSc/bzQn36i2zdiBFiauF5RJWZN0Yhkkyuy/kI1dVLbYfHxzC5dSIiIgAPKm3Ix3A3mFTYhgmyXx9SPeDLXeww0NcTo2IiAgAEBnkiahgT7H9w4ksVNSopSvIijEMkyRS8svw55VrYnty347wdHWSsCIiIiLzMl2vd7isWo2fk7IlrMZ6MQyTJG78uOeJGz4OIiIisnUT+gTC203XUfTNoXQIApdZMzaGYWpz5TVq/Jioe3fbr5MnendUSFgRERGR+XF2tMfDA4PFdnJeGY6lFUtYkXViGKY291NiFsr1xj1xkw0iIqLGTRvcCfpzy78+lCZZLdaKYZjalCAIBhPnfNyccHef9hJWREREZL6CvFwxukeA2N5xNg8FpdVNXEEtxTBMberw1SKkFOjWSnxkUDDkDvYSVkRERGTe9JdZU2sFfHc0U8JqrA/DMLWpbw6niX+2kwGPDebEOSIioqbEdPVFZ183sb3+aDrqNFoJK7IuDMPUZvJU1dh5Tre/+p09A9DR00XCioiIiMyfnZ0Mjw/RdR7ll9bg9/P5TVxBLcEwTG1m/dEMaLS6JWE4cY6IiKh5pvQPgoujblghJ9IZD8MwtYk6jRbfHc0Q22F+bhje1UfCioiIiCyHwsURk6M7iu3DV4twKb9MwoqsB8MwtYld5/JRWFYjtp8YEgKZTNbEFURERKTvyRs2qPr2hg2sqHUYhqlNfHtE9wPr4miPB/sHSVgNERGR5ekZ6IH+IV5i+8fEbFTWqpu4gpqDYZhM7kphOf68ck1s39e3AzycHSWsiIiIyDI9PqST+OeyGjW2JOVIWI11YBgmk1t/JMOgPY3LqREREbXK3b0D4eWq61D69obfsdRyDMNkUtV1GvxwIktsRwUp0CdIIWFFRERElsvZ0R4PDQgW22eyVTiVWSJdQVaAYZhM6rfTuVBV1Ylt9goTERHdnkcHdTJo68/LoZZjGCaTWqc309Xd2QGTojpIWA0REZHl6+zrhhHdfMX2llM5UFXWNXEFNYVhmEzmbLYKSXof3TzYLwguTvY3v4CIiIiaZdpgXe9wdZ0WP57MauLZ1BSGYTKZGwf168+AJSIiotYb0zMAAR5ysf3tkQwIgtDEFXQzDMNkEmXVdfglKVtsD+7sja7+7hJWREREZD0c7e3w8EBdJ9PlgnIcSS2SsCLLxTBMJvHzyWxU1mrE9uNDOHGOiIjImB4dFAw7vc1c13FHulZhGCajEwTBYIiEbzsnjI9oL2FFRERE1idQ4YIxPQPE9s5zeSgsq5GwIsvEMExGdyK9GMl5ZWJ76oBgODnwrxoREZGx6X/yWqcRsPF4poTVWCYmFDI6/V5hmazheohERERkHCO6+qKTt6vYXn8kA1otJ9K1BMMwGVVJZS22nskV2yPD/RCs90NKRERExmNnJ8NjesusZZdU4cBlpYQVWR6GYTKqHxOzUavWim3uOEdERGRaU/oHwdFeN5PuuxuWNqWmMQyT0QiCgO+O6n4AAzzkiO3uJ2FFRERE1s+3nRzj9Caq776Qj4LSagkrsiwMw2Q0J9KLkVJQLrYfHhAMB3v+FSMiIjK1x/Tm56i1Ajad4I50zcWkQkaz/qjhxLmpA4MlrIaIiMh2DA3zQYiPbo7OhmOcSNdcZh+Gjx07hgkTJsDLywtubm4YNGgQ1q9f3+r71dXVoW/fvpDJZOjRo4cRK7Vtqso6bD1tOHEuyIsT54iIiNqCnZ0Mj+jtSJdZVIUETqRrFrMOw/Hx8YiJicGBAwcwZcoUzJ49G0qlEtOmTcM777zTqnsuWbIEly9fNnKl9NPJLNToTZzjcmpERERta0r/IDjobUmnP4+Hbs5sw7BarcbMmTMhk8mwf/9+rFy5Eu+99x5OnTqFiIgILFy4ECkpKS26Z2JiIpYtW4Zly5aZqGrbdH3inG6Rb393OUb38JewIiIiItvj5y7HuAjdjnS/n89HQRkn0t2K2YbhvXv34sqVK3jssccQHR0tHnd3d8eCBQugVquxZs2aZt+vtrYWM2bMwJAhQ/DSSy+ZomSblZhRgov5hjvOOXLiHBERUZt79IaJdD9wIt0tmW1iiY+PBwCMGzeuwbn6Y/v27Wv2/RYtWoSUlBSsXr0aMpns1hdQs313w8S5hzlxjoiISBLDu/gi2NtFbG84msmJdLdgtmG4fghEt27dGpzz8vKCr69vs4dJHDt2DO+++y4WL16M8PBwo9Zp61RVdfjtdI7YHtGNO84RERFJ5caJdBlFlfjzyjUJKzJ/ZhuGVSoVAEChUDR63sPDQ3xOU2pqajBjxgxER0fj1VdfbXEdNTU1KC0tNXiQzi9J2aiu002ce2wQe4WJiIik9NAATqRrCbMNw8ayYMECpKSk4Msvv4S9vX2Lr1+2bBkUCoX4CA5m2KsnCALW62356NtOjjE9A5q4goiIiEzN390Zd+r9Pt55Lg+FZTUSVmTezDYM1/cI36z3t7S09Ka9xvUSExPxwQcfYP78+ejTp0+r6pg3bx5UKpX4yMzMvPVFNiIpswTJefoT54I4cY6IiMgMPDqYE+may2yTS/1Y4cbGBRcXF0OpVDY6nljf6dOnodFosGjRIshkMoMHAFy8eBEymQyenp43vYdcLoeHh4fBg67bcNTwjYH+GCUiIiKSzoiuvgjy0k2k23g8E4LAiXSNcZC6gJsZOXIkli1bhl27duGRRx4xOLdr1y7xOU0JDw/HM8880+i51atXQ6FQYMqUKXB15YSvliqvUeNXvYlzMV190cmH/x+JiIjMgZ2dDA8PCMb7v18CAKQqK3A0tQiDw3wkrsz8yAQzfZugVqvRvXt3ZGdn4/Dhw+jbty8AoKysDEOHDsXFixdx7tw5cXUIpVIJpVIJX19f+Pr63vL+MpkM3bt3R3Jycovqqh+eoVKpbLqX+PtjGXhj8xmx/dGj0ZgU1UHCioiIiEhfrqoKw5fvRf3Kag9Ed8QHD/eVtKa20pK8ZrbDJBwcHLBq1SpotVqMGDECs2bNwmuvvYaoqCicO3cOixYtMlgmLS4uDj179kRcXJyEVduODcd0QyQ8XR0NdrwhIiIi6QUqXDAy3E9sbz2TC1VVnYQVmSezDcMAEBsbi4SEBMTExGDjxo345JNP4OPjg3Xr1mH+/PlSl2ezLuWX4WRGidi+P7oj5A4tX6mDiIiITOthvfk8NWottpzKaeLZtslsh0mYKw6TAJb8dh6rE1LF9o6XR6BHe9v8f0FERGTO6jRaDF22B8ryWgBA744e+G3OCImrMj2rGCZB5qlGrcGPibrlWfoGezIIExERmSlHezs82D9IbJ/NLsXZ7FtvWmZLGIapRX4/n4/iSt14o0cGchMSIiIiczZ1gOHv6u+Pcc8EfQzD1CL6P0CuTvaYyBUkiIiIzFoXv3YYFOottn9OykZ1nUbCiswLwzA1W2ZRJRIuK8X2xMhAtJOb7VLVRERE9JeH9T7JLatWY/vZXAmrMS8Mw9Rsm05kQX+65cPccY6IiMgiTOgTCHe9Dqwbd5G1ZQzD1CwarYBNx3U/ON3826FfJ0/pCiIiIqJmc3Gyx719dUMbj6QWIVVZIWFF5oNhmJrlQEohclXVYvvhgcGQyWQSVkREREQt8cgNn+huPM7eYYBhmJpJf+Kco70MD/QLauLZREREZG56d/RAr0Ddcqg/nMhCnUYrYUXmgWGYbulaeQ1+P58vtsf1ag9vNycJKyIiIqKWkslkBhPpCstq8EdygYQVmQeGYbqln05mQ63VzZybyrWFiYiILNLkvh3h5KCLf5tOZDXxbNvAMExNEgQBm47rflA6KJwR09VXwoqIiIiotRSujrgror3Y3ptcgMKyGgkrkh7DMDXpTLYKF/PLxPaD/YNgb8eJc0RERJbqoQG6eT8arYCfT2ZLWI30GIapSTfONJ3SnxPniIiILNmwLr7o6Okitjcez4Sgv5GAjWEYppuqrtNgS1KO2B7c2RshPm4SVkRERES3y95Ohgf7dRTbKQXlOJWlkrAiaTEM003tPJeH0mq12H5oACfOERERWYMp/Q1/p9vymsMMw3RTP+jNMHVzsseEPu2beDYRERFZik4+rhgS5i22f03KQVWtRsKKpMMwTI3KLqlCwmWl2J4Y2QGuTg5NXEFERESWZKreJ75lNWrsPJcnYTXSYRimRm0+kQX9sfRTB3LiHBERkTW5u3cg2sl1HV2bTtjmUAmGYWpAqxUMfiDC/NzQr5OXhBURERGRsbk42WNSVKDYPnj5GjKLKiWsSBoMw9TAkdQiZBZVie2H+gdDJuPawkRERNbmxol0mxNtb0c6hmFqYJPejFI7GfCA3vIrREREZD36dfJEFz/dsqmbjmdBq7WtNYcZhslAWXUdtp3NFdsjw/0Q4OEsYUVERERkKjKZzGDp1OySKhy+ek3CitoewzAZ+O10LqrrtGJ7KtcWJiIismoPRHeEvZ1uOKStrTnMMEwG9IdIeLk6YkzPAAmrISIiIlPz93DGqHA/sb39bB5Kq+skrKhtMQyT6GphORIzSsT2fX07wsmBf0WIiIisnf5QiRq1FttO5zbxbOvCpEOiG2eQTunPtYWJiIhswege/vBydRTb+rvQWjuGYQJwfW3hnxKzxXaP9u6I6OAhYUVERETUVpwc7HBvVAexfTy9GGnKCgkrajsMwwQAOHT1GnJU1WJ7Sv8gri1MRERkQ25cc/hHG1lzmGGYABh+HGJvJ8N9fbm2MBERkS3p3dED4QHtxPbmxGybWHOYYZhQXqPGjrN5YntkuB/83OUSVkRERERtTSaT4cF+uvlC2SVVOJxq/WsOMwwTtp3JRVWdRmxz4hwREZFtuj+6I/SWHMbmE9k3f7KVYBgmbNYbIqFwccSYnv4SVkNERERS8fdwxh0Gaw7noqJGLWFFpscwbOMyiypxJLVIbE+KCoTcwV7CioiIiEhK+kMlKms12K43lNIaMQzbuIZrC3P7ZSIiIls2tlcA3J0dxPZmK19zmGHYhmm1gkEY7uLnhqgghYQVERERkdScHe0xSW/N4UNXryGruFLCikyLYdiGHUsrQmZRldh+kGsLExEREQyHSgDAj4nWO5GOYdiG6fcK28mAB6K5igQREREB/Tp5IszXTWz/mJgFQbDONYcZhm1UVa0G287oBsQP7+qL9gpnCSsiIiIicyGTyfCg3lKradcqcSK9WMKKTIdh2EbtPJeHcr2lUri2MBEREem7P7oj9EdP/mClE+kYhm2U/hCJdnIHjOvVXsJqiIiIyNx08HTB8C6+YnvrmVxU623SZS0Yhm1Qfmk1Dl5Wiu17+gTCxYlrCxMREZGhB/p1FP9cVq3GngsFElZjGmYfho8dO4YJEybAy8sLbm5uGDRoENavX9/s6xMSEvDqq6+if//+8PHxgbOzM3r06IE33ngDJSUlpivcjP2SlA2t3hj4+/X+ohMRERHVGx/RHi6Oug6zHxOtb6iEWYfh+Ph4xMTE4MCBA5gyZQpmz54NpVKJadOm4Z133mnWPaZMmYL//e9/cHd3x5NPPokXXngBrq6uePfddzFgwAAUFFjfO5xb0V8epaOnCwaFektYDREREZkrN7kD7uqtG0q571IhrpXXSFiR8ZltGFar1Zg5cyZkMhn279+PlStX4r333sOpU6cQERGBhQsXIiUl5Zb3mTt3LjIzMxEfH4///ve/+OCDD3DixAnMnj0bV65cweLFi9vguzEfF3JLkZxXJrbvj+4IOzuuLUxERESNuz9a9wmyWivg11M5ElZjfGYbhvfu3YsrV67gscceQ3R0tHjc3d0dCxYsgFqtxpo1a255nzfeeAOBgYEGx2QyGRYsWAAA2Ldvn3ELN3M/nTRcNJtDJIiIiKgpw7v6wt9dLrZvzBKWzmzDcHx8PABg3LhxDc7VH7udIOvo6AgAcHBwuMUzrYdGK+Bnvb/AUUEKdPFrJ2FFREREZO7s7WSYrNc7fCpLhcsF5RJWZFxmG4brh0B069atwTkvLy/4+vo2a5jEzXz55ZcAGg/b1urgZSUKynTjfB7ox7WFiYiI6Nb0h0oAwE8nrWcindmGYZVKBQBQKBSNnvfw8BCf01JJSUlYvHgx/P398frrrzf53JqaGpSWlho8LJX+xxoOdjJMiuogYTVERERkKXoGeqBHe3ex/fPJHGi11rE9s9mGYVNJTU3FxIkTodFosGHDBvj6+jb5/GXLlkGhUIiP4ODgNqrUuCpq1NhxVrf98qjufvB2c5KwIiIiIrIkD+p9opxdUoUjqUUSVmM8ZhuG63uEb9b7W1paetNe45tJT09HbGwsCgsL8cMPPyA2NvaW18ybNw8qlUp8ZGZmtuhrmosdZ/NQpbdrDIdIEBERUUvc17cD9BegspahEmYbhuvHCjc2Lri4uBhKpbLR8cQ3k5aWhlGjRiEnJwcbN27ExIkTm3WdXC6Hh4eHwcMS6Q+RcHd2wOge/hJWQ0RERJbG38MZw7vqPlHfdibPKrZnNtswPHLkSADArl27GpyrP1b/nFupD8LZ2dn4/vvvcd999xmvUAuQq6rCwSu67ZcnRgbC2ZHbLxMREVHL6G/PXF6jxq7z+RJWYxxmG4bHjBmDsLAwrF+/HklJSeLxsrIyLFmyBA4ODpgxY4Z4XKlUIjk5GUql0uA++kF4w4YNuP/++9voOzAfvyTlQNDffjmaQySIiIio5cZHtIerk65D7Scr2J7ZbBfZdXBwwKpVqzB+/HiMGDECjz76KDw8PPDjjz8iNTUVS5cuRXh4uPj8uLg4LF68GAsXLsSiRYvE46NGjUJ6ejqGDBmC06dP4/Tp0w2+lv7zrY0gCAb7iAd7u2BAiJeEFREREZGlcnW6vj3zj4nXh1/uT1GisKwGfnqbclgasw3DABAbG4uEhAQsXLgQGzduRG1tLSIiIrBkyRJMmzatWfdIT08HABw+fBiHDx9u9DnWHIbP55biUr5uYez7+3L7ZSIiImq9B6KDxDCs+Wt75qdjOktcVevJBEGwjkXi2kj9KhYqlcoiJtO9s+0Cvth/VWzvfXUkwrjrHBEREbWSRitg2PI9yC+9vpFXVJACv7wUI3FVhlqS18x2zDDdPo1WwC9JetsvB3syCBMREdFtsbeT4b6+htszXy203O2ZGYat2JGr18R3bQAwuS93nCMiIqLbd98NmeLnpByJKrl9DMNW7Ge9XmF7OxkmRjIMExER0e3rFeiBbv66T5t/ScqGpY68ZRi2UtV1Gmw/o9t+eXhXX4ue6UlERETmQyaTYXK0bqhE+rVKnMwska6g28AwbKX2JhegrEYttu+PZq8wERERGc+NQyV+0dvt1pIwDFupn/X+Qro42mNcr/YSVkNERETWJsjLFQNDdXsX/HY6F3UarYQVtQ7DsBUqqaxF/MVCsT22VwDc5Ga9pDQRERFZIP2hEtcqapFwWdnEs80Tw7AV2nYmD7V678zu1/uLSkRERGQs9/QJhKO9bjOvny1wqATDsBXSX0XC280JMd18JayGiIiIrJWnqxNGhvuL7V3n8lGhN2fJEjAMW5nskiocTS0S2xMjA+Foz5eZiIiITEP/E+iqOg1+P58vYTUtx5RkZfR3nANgsEMMERERkbGN6emPdnpzk36ysKESDMNW5peTuh1gOnm7ol8nT+mKISIiIqvn7GiPu3vrVq1KuKyEsrymiSvMC8OwFbmQW4qL+WVie3LfDpDJZE1cQURERHT79FeV0GgF/HbKcrZnZhi2IjfO4LyPq0gQERFRGxgS5gN/vZ1uf0piGKY2ptUK2KL3LiwySIEufu2auIKIiIjIOOztZAY70p3KLEGaskLCipqPYdhKHEsrQq6qWmzfG8Xtl4mIiKjt3Dhpf4uFDJVgGLYS+n/hZDJgEsMwERERtaGIDh4I83MT278kZUMQBAkrah6GYStQp9Fi25lcsT00zAcBHs4SVkRERES2RiaT4b4oXe/wlcIKnM8tlbCi5mEYtgIJKUoUV9aJbQ6RICIiIinc29cwg1jCUAmGYSugv9GGo70Md/cOlLAaIiIislWdfd0QGaQQ278m5UCrNe+hEgzDFq6qVoNdetsejgz3h8LVUcKKiIiIyJbpf0Kdo6rGiYxiCau5NYZhC7f7Qj4qazVi+76+HCJBRERE0pkY2QH6e35tMfM1hxmGLZz+WBxXJ3vc2TNAwmqIiIjI1rVXOGNwZ2+xvfVMLuo0WgkrahrDsAVTVdZh38VCsT2uVwBcnOwlrIiIiIgIuFdvVYmiilocvKyUsJqmMQxbsB3nclGr907rxhmcRERERFK4u3d7ONrrxkqY81AJhmELpj9EwtPVETFd/SSshoiIiOg6Lzcn3NFNl0t2nstDdZ2miSukwzBsoQpKq/HnlWtie0KfQDg58OUkIiIi86D/iXVFrQZ7LhRIWM3NMT1ZqN9O50J/h0NutEFERETmZGyvALg46uYybTmV3cSzpcMwbKF+0Rsi0d7DGYNCvZt4NhEREVHbcnVywNheulWu/kguhKqqrokrpMEwbIHSr1XgVGaJ2J4UFQg7O9nNLyAiIiKSgP4n17UaLXaey5OwmsYxDFugX2/Y5/u+vh1v8kwiIiIi6dwR7geFi25nXHNcVYJh2AL9eipX/HOYrxsiOnhIWA0RERFR45wc7DChT3ux/ecVJQrKqiWsqCGGYQtzMa8MF/PLxPbEqA6QyThEgoiIiMxT/QYcUcGemH9PL8gdzGuDMAepC6CW+e204ccLkyIDJaqEiIiI6NYGdfZG/GujEOrrJnUpjWLPsAURBAG/ndYNkejR3h3dAtwlrIiIiIioafZ2MrMNwgDDsEU5l1OKVGWF2J7EtYWJiIiIbgvDsAW5cRWJiRwiQURERHRbGIYtxI1DJCKDFAjxMd+PHIiIiIgsAcOwhUjMKEF2SZXYnhTJIRJEREREt4th2ELcuIrEPRwiQURERHTbGIYtgEYrYKveEIkBIV7o4OkiYUVERERE1oFh2AIcTS1CQVmN2OYqEkRERETGYfZh+NixY5gwYQK8vLzg5uaGQYMGYf369S26h1arRVxcHCIjI+Hi4gI/Pz9MnToVKSkpJqrauPSHSNjJgLv1tjUkIiIiotYz6zAcHx+PmJgYHDhwAFOmTMHs2bOhVCoxbdo0vPPOO82+z/PPP485c+ZAo9Fgzpw5mDBhArZs2YKBAwfi/PnzJvwObl+dRovtZ/PE9pAwH/i7O0tYEREREZH1kAmCIEhdRGPUajV69OiBrKwsHDp0CNHR0QCAsrIyDB06FBcvXsT58+fRrVu3Ju/zxx9/YPTo0RgxYgR+//13yOVyAMCePXswduxYjBgxAvv27Wt2XaWlpVAoFFCpVPDw8Gj9N9hM+y4VYvqXR8X2sgf64NFBnUz+dYmIiIgsVUvymtn2DO/duxdXrlzBY489JgZhAHB3d8eCBQugVquxZs2aW95n5cqVAIClS5eKQRgAxowZg/Hjx2P//v24dOmS8b8BI/lNb6MNBzsZ7orgEAkiIiIiYzHbMBwfHw8AGDduXINz9cea06MbHx8PNzc3DB8+vMG58ePHN/s+UqhRa7DjnG6IREw3X3i5OUlYEREREZF1cZC6gJupn9zW2DAILy8v+Pr63nICXEVFBXJzc9G7d2/Y29s3OF9/76buU1NTg5oa3UoOpaWlzarfGPZfUqKsWi22udEGERERkXGZbc+wSqUCACgUikbPe3h4iM+5nXvoP68xy5Ytg0KhEB/BwcG3rN1Y9l8qFP/sZG+HsREBbfa1iYiIiGyB2fYMm4t58+bhlVdeEdulpaVtFogX3xuBydEd8OupXNSotfBwdmyTr0tERERkK8w2DNf35t6s17Z+luDt3kP/eY2Ry+UGE+/akp2dDP1DvNE/xFuSr09ERERk7cx2mERT43mLi4uhVCpvuayam5sbAgMDkZqaCo1G0+B8U+OSiYiIiMj6mW0YHjlyJABg165dDc7VH6t/zq3uU1FRgYMHDzY4t3Pnzmbfh4iIiIisj9mG4TFjxiAsLAzr169HUlKSeLysrAxLliyBg4MDZsyYIR5XKpVITk6GUqk0uM+sWbMAAG+++SZqa2vF43v27MHOnTtxxx13IDw83KTfCxERERGZJ7MNww4ODli1ahW0Wi1GjBiBWbNm4bXXXkNUVBTOnTuHRYsWGYTYuLg49OzZE3FxcQb3iY2NxcyZM3HgwAFER0fj9ddfx/Tp03HPPffAw8MDn376aVt/a0RERERkJsw2DAPXg2xCQgJiYmKwceNGfPLJJ/Dx8cG6deswf/78Zt/n888/x4oVKyCTybBixQps3boVkyZNwtGjR9GrVy8TfgdEREREZM5kgiAIUhdhSVqy1zURERERtb2W5DWz7hkmIiIiIjIlhmEiIiIislkMw0RERERksxiGiYiIiMhmMQwTERERkc1iGCYiIiIim8UwTEREREQ2i2GYiIiIiGwWwzARERER2SyGYSIiIiKyWQzDRERERGSzHKQuwNIIggDg+p7XRERERGR+6nNafW5rCsNwC5WVlQEAgoODJa6EiIiIiJpSVlYGhULR5HNkQnMiM4m0Wi1ycnLg7u4OmUxm8q9XWlqK4OBgZGZmwsPDw+Rfj0yDr6N14OtoHfg6Wge+jtbBVK+jIAgoKytDhw4dYGfX9Khg9gy3kJ2dHYKCgtr863p4ePCH3QrwdbQOfB2tA19H68DX0TqY4nW8VY9wPU6gIyIiIiKbxTBMRERERDaLYdjMyeVyLFy4EHK5XOpS6DbwdbQOfB2tA19H68DX0TqYw+vICXREREREZLPYM0xERERENothmIiIiIhsFsMwEREREdkshmEiIiIislkMwxI4duwYJkyYAC8vL7i5uWHQoEFYv359i+6h1WoRFxeHyMhIuLi4wM/PD1OnTkVKSoqJqqYb3e7rmJCQgFdffRX9+/eHj48PnJ2d0aNHD7zxxhsoKSkxXeFkwBg/j/rq6urQt29fyGQy9OjRw4iVUlOM9TqWlZVh4cKF6N27N1xdXeHp6Yl+/fph8eLFJqiabmSM17GkpARvvfUWIiMj4e7uDl9fXwwcOBBxcXGorq42UeUEAOvWrcNzzz2HAQMGQC6XQyaTYe3atS2+T5tnHIHa1B9//CE4OTkJ7dq1E2bOnCm8+uqrQufOnQUAwttvv93s+zz77LMCAKFXr17CP/7xD+HJJ58U5HK5oFAohHPnzpnwOyBBMM7rGBAQINjb2wsjR44UXn75ZWHu3LlCdHS0AEDo0qWLkJ+fb+Lvgoz186hvwYIFgpubmwBA6N69u5ErpsYY63VMT08XunTpIshkMmHs2LHC66+/Lvz9738X7rnnHqFPnz4m/A5IEIzzOhYXFwthYWECACEmJkZ49dVXhZdeekno0qWLAEAYPXq0oNFoTPyd2K6QkBABgODr6yv+ec2aNS2+T1tnHIbhNlRXVyd06dJFkMvlQmJioni8tLRUiIiIEBwcHIRLly7d8j579+4VAAgjRowQqqurxeO7d+8WZDKZcMcdd5ikfrrOWK/j8uXLhZycHINjWq1WmD17tgBAeOGFF4xeO+kY63XUd+LECcHBwUFYsWIFw3AbMdbrqFarhYEDBwouLi7C3r17G/06ZDrGeh3//e9/CwCEuXPnGhyvqakRBg4cKAAQ9u3bZ/T66brff/9dSEtLEwRBEJYtW9aqMCxFxmEYbkM7d+4UAAhPPfVUg3MbNmwQAAjz5s275X0effTRm/5A33XXXQIA4eLFi0apmRoy1ut4Mzk5OQIAISIi4nbKpFsw9utYU1Mj9OnTR4iJiRG0Wi3DcBsx1utY/9wFCxaYoky6BWO9js8995wAQPj9998bnPvnP/8pABA2bdpklJqpaa0Nw1JkHI4ZbkPx8fEAgHHjxjU4V39s3759zbqPm5sbhg8f3uDc+PHjm30fah1jvY434+joCABwcHBo9T3o1oz9Oi5atAgpKSlYvXo1ZDKZUWqkWzPW6/j9998DAB566CFkZmbis88+w/Lly7Fp0yaUl5cbr2BqlLFex4iICADAjh07DI7X1dVh9+7dcHFxwdChQ2+zWjIlKTIOf9u2ofqB3926dWtwzsvLC76+vrccHF5RUYHc3Fz07t0b9vb2Dc7X35sT6UzHGK9jU7788ksAjf9SIOMx5ut47NgxvPvuu3jnnXcQHh5u1DqpacZ6HY8fPw7g+sTWuXPnoqamRjzn5+eHjRs3YtSoUcYpmhow1us4c+ZMfPPNN3j//fdx/PhxDBw4EDU1NdixYweKi4uxfv16dOzY0ej1k3FIlXHYM9yGVCoVAEChUDR63sPDQ3zO7dxD/3lkfMZ4HW8mKSkJixcvhr+/P15//fVW10i3ZqzXsaamBjNmzEB0dDReffVVo9ZIt2as17GgoAAAMGfOHLz88svIzMxEYWEhVqxYAZVKhcmTJyM3N9d4hZMBY72OLi4uiI+Px+OPP459+/bhvffew0cffYQrV67gscceQ0xMjFHrJuOSKuMwDBOZidTUVEycOBEajQYbNmyAr6+v1CVRMyxYsAApKSn48ssvG+3JIMug1WoBABMnTsTy5csRFBQEX19fzJkzB3PnzoVKpcLq1aslrpJuRalUYuzYsTh8+DC2bt2KkpIS5OXl4bPPPsOaNWswePBgFBcXS10mmRmG4TZU/07nZu9oSktLb/puqCX30H8eGZ8xXscbpaenIzY2FoWFhfjhhx8QGxt723VS04zxOiYmJuKDDz7A/Pnz0adPH6PXSLdmrJ/H+ufce++9Dc5NmjQJgG4oBRmfsV7HV155BX/++Sc2b96MCRMmQKFQICAgAM8++yzeffddXL16FR9++KExSycjkirjMAy3oabGuhQXF0OpVDY6Xkqfm5sbAgMDkZqaCo1G0+B8U+OuyDiM8TrqS0tLw6hRo5CTk4ONGzdi4sSJRquVbs4Yr+Pp06eh0WiwaNEiyGQygwcAXLx4ETKZDJ6enkavn64z1s9j9+7dAaDR16r+WFVVVesLpSYZ63XcunUrvL29ERkZ2eDc6NGjAQAnTpy4zWrJVKTKOAzDbWjkyJEAgF27djU4V3+s/jm3uk9FRQUOHjzY4NzOnTubfR9qHWO9joAuCGdnZ+P777/HfffdZ7xCqUnGeB3Dw8PxzDPPNPoArvdePPPMM3jyySeNXD3VM9bPY31QOn/+fINz9cdCQ0NbWybdgrFex9raWpSWlqK2trbBucLCQgCAXC6/nVLJxCTJOEZdqI2aVFdXJ4SFhQlyuVw4efKkeFx/UXH9tfMKCwuFCxcuCIWFhQb30V+QuqamRjzOTTfahrFex9TUVCEkJERwcHAQNm/e3Fbl01+M9TreDLjOcJsw1ut49epVQS6XC/7+/kJWVpbBffr27SsAEHbv3m3y78dWGet1HD9+vABAePPNNw2OV1dXi+c++ugjk34vdN2t1hk2p4zDMNzG9u7dKzg6Ogrt2rUTnn32WYPtJpcuXWrw3IULFwoAhIULFza4z8yZM7kds4SM8TrWb1U5ZMgQYeHChY0+yLSM9fPYGIbhtmOs17F+50AfHx9h5syZwosvviiEhoYKAIRZs2a10Xdju4zxOp48eVJwd3cXAAiDBg0S5s6dK8yePVvcorl///5CVVVVG35XtmXlypXC9OnThenTpwv9+vUTAAjDhw8Xj/3000/ic80p4zAMS+DIkSPCXXfdJSgUCsHFxUUYMGCAsG7dugbPa+ovikajEVasWCFEREQIcrlc8PHxEaZMmcKd59rQ7b6OAG75INMzxs9jYxiG25axXsctW7YII0aMENq1ayc4OzsL/fv3F7744gsTV0/1jPE6Xrp0SXjqqaeETp06CY6OjoKLi4vQp08fYfHixUJFRUUbfBe2a/r06U3+TtN/vcwp48gEQRCMO/CCiIiIiMgycAIdEREREdkshmEiIiIislkMw0RERERksxiGiYiIiMhmMQwTERERkc1iGCYiIiIim8UwTEREREQ2i2GYiIiIiGwWwzARkY0rKirCyy+/jJCQEDg7O6N379747rvvpC6LiKhNcAc6IiIbdunSJYwePRoqlQpTp06Fh4cH1q1bB6VSiV9//RUTJ06UukQiIpNiGCYislHl5eWIjo5GeXk59u/fj27dugEAkpKS0K9fPwwZMgR//vmnxFUSEZmWg9QFEBGRNP71r3/h8uXL2LJlixiEAaBv377o1asXDh8+jNraWjg5OUlYJRGRaXHMMBGRDSopKUFcXBwiIyMxadKkBud9fHwgCAIKCwslqI6IqO0wDBMR2aBNmzahqqoK06dPb/R8dXU1ALBXmIisHodJEBHZoO3btwMALly4gEWLFjU4f/XqVTg7O8PHx6eNKyMialucQEdEZIMCAgJQUFDQ5HOioqKQlJTUNgUREUmEwySIiGxMUVERCgoKMHLkSAiC0OCxdetWAMDw4cMlrpSIyPQYhomIbEx2djYAIDAwsNHzO3bsAADcfffdbVYTEZFUGIaJiGxMXV0dAEAulzc4V1tbi40bNyIgIADjx49v69KIiNocJ9AREdmYgIAAAEB+fn6Dc1988QXy8/PxwQcfwNHRsa1LIyJqc5xAR0Rkg7p27YqcnBxcvHgRwcHBAIDDhw/jzjvvREREBA4ePAgHB/aXEJH1YxgmIrJBq1evxsyZMxEUFIRHHnkEeXl52LhxI7p06YK9e/eiffv2UpdIRNQmGIaJiGzUp59+ig8++AAZGRkICgrCo48+innz5sHNzU3q0oiI2gzDMBERERHZLK4mQUREREQ2i2GYiIiIiGwWwzARERER2SyGYSIiIiKyWQzDRERERGSzGIaJiIiIyGYxDBMRERGRzWIYJiIiIiKbxTBMRERERDaLYZiIiIiIbBbDMBERERHZLIZhIiIiIrJZDMNEREREZLP+H0RoNKhx1z5SAAAAAElFTkSuQmCC\n", "text/plain": [ - "
" + "
" ] }, - "metadata": { - "needs_background": "light" - }, + "metadata": {}, "output_type": "display_data" } ], @@ -444,14 +443,12 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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69atlZiYqDZt2igqKsoZWbvpppv09ddf+/15lmT/l0S1atWcf18oDB85csSn/cUkJydr586datq0qWbMmJHvyvAaNWooJSVFq1ev1pYtW/S3v/1NY8aMkXT2AQUBAQHyer3WawLKGsESKGfyRmguNC88PLxMask73JqZmVnkPnmP8JswYYL+8Ic/+MwvjZHK4qhcubICAwN15swZrV27tsDTEgrzwQcfyOPxqH379nr//fed4JqnsG3M+9yK8hkXpGHDhnr33Xedmr/++mt98skn+vLLL/XMM884t+2xZeXKldq0aZNCQ0O1aNEiRUVF+bQp7udZkv1fEjExMXK73fJ4PNq2bZs6derk0+bUqVPKyMiQJDVp0qTIy867N2X37t0LvN1QSEiIunfvri1btmjlypXO9ODgYMXGxmr79u0XvGXU9u3b/a4JKGvcxxIoZzZv3qwzZ84UOG/jxo2SpGbNmpVJLS1atJAkffPNN0Xuk3fItEuXLgXO92dZpcnlcjmnB/h7b828bezUqZNPqJQK38a8+xPu3LnTOax5vrzP+EICAwPVpk0bPfHEE1q8eLEmT54sSXrjjTeKVH9R5W1ns2bNCg2Vhd1b9dzR+8LmF3f/l0RgYKDi4uIkyecm5XlWrFihU6dOKTQ0VK1atSrysvNG+C8k79zU8z//jh07XrCmPXv2OOeU5rUFyiOCJVDO/Pzzz85FDef69ddf9Y9//EOSdMstt5RJLQMGDJB09iKLot58O+/8r3379vnM+/HHH7Vw4UJ7BZbQPffcI+nsOX7n3uT9Yi60jcYYTZgwocB+nTt3Vnh4uI4dO6aZM2f6zD/3M/bHTTfdJOnsyLLNCzvytnP//v0F3mD+r3/9a6F/BOX1PffClPMVd/+XVN56P/744wJHXN98801J0m233ebX+Yx5I4lLliwp8NSAU6dO6auvvpLk+8dhXk2pqanOubgF1RQXF6fY2Ngi1wSUNYIlUM4EBwfrj3/8o7799ltn2tGjR3XvvffqyJEjqlOnzkWv4rWlb9++6tatm06ePKnevXvr66+/zjf/6NGjev3117V7925nWteuXSVJCQkJ2rt3rzN97dq1uv322/0+B7A0Pf7442rYsKG2bdumm2++2edcP2OMvv/+e40ePVqrVq1ypudt4+zZs7VgwQJnek5OjoYPH67vvvuuwPWFhYVp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\n", "text/plain": [ - "
" + "
" ] }, - "metadata": { - "needs_background": "light" - }, + "metadata": {}, "output_type": "display_data" } ], @@ -537,8 +534,25 @@ "outputs": [ { "data": { + "application/json": { + "ascii": false, + "bar_format": null, + "colour": null, + "elapsed": 0.07808947563171387, + "initial": 0, + "n": 0, + "ncols": null, + "nrows": 1, + "postfix": null, + "prefix": "Samples collected", + "rate": null, + "total": 1000, + "unit": "it", + "unit_divisor": 1000, + "unit_scale": false + }, "application/vnd.jupyter.widget-view+json": { - "model_id": "705db67137ab444eb81bbc377b28695f", + "model_id": "b4cdad4be9c14bf6a5caaed9e9740c9f", "version_major": 2, "version_minor": 0 }, @@ -551,8 +565,25 @@ }, { "data": { + "application/json": { + "ascii": false, + "bar_format": null, + "colour": null, + "elapsed": 0.01014399528503418, + "initial": 0, + "n": 0, + "ncols": null, + "nrows": 1, + "postfix": null, + "prefix": "Samples collected", + "rate": null, + "total": 1000, + "unit": "it", + "unit_divisor": 1000, + "unit_scale": false + }, "application/vnd.jupyter.widget-view+json": { - "model_id": "6dd72777e3204d32b6549543bc382451", + "model_id": "52198ae3485846b7b9572f6071960a56", "version_major": 2, "version_minor": 0 }, @@ -565,8 +596,25 @@ }, { "data": { + "application/json": { + "ascii": false, + "bar_format": null, + "colour": null, + "elapsed": 0.010380983352661133, + "initial": 0, + "n": 0, + "ncols": null, + "nrows": 1, + "postfix": null, + "prefix": "Samples collected", + "rate": null, + "total": 1000, + "unit": "it", + "unit_divisor": 1000, + "unit_scale": false + }, "application/vnd.jupyter.widget-view+json": { - "model_id": "f96b7d6222f944099e2fc7b5a1757940", + "model_id": "a9ce1fe62aa54904961080293f8906df", "version_major": 2, "version_minor": 0 }, @@ -579,8 +627,25 @@ }, { "data": { + "application/json": { + "ascii": false, + "bar_format": null, + "colour": null, + "elapsed": 0.01077890396118164, + "initial": 0, + "n": 0, + "ncols": null, + "nrows": 1, + "postfix": null, + "prefix": "Samples collected", + "rate": null, + "total": 1000, + "unit": "it", + "unit_divisor": 1000, + "unit_scale": false + }, "application/vnd.jupyter.widget-view+json": { - "model_id": "9c6d1fa0090d4dcd91c1b3ca7f51bae7", + "model_id": "bb3b8b5f9e42481ca56f7b0f847e1766", "version_major": 2, "version_minor": 0 }, @@ -666,14 +731,12 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAfgAAAFpCAYAAABwEjqZAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAA7xklEQVR4nO3deVyU5f7/8dclIAguiQuLiGZuiUXuaaWZR091NCszt7TU7JSmlZWGbUrlUqmVhZplaeWvRa0sO1p5vpoZLkeMdrMjiprielxAAeH+/THDxLAoy8Dgzfv5eMwDue/rvu7rMzPynnsdY1kWIiIiYi9VvD0AERER8TwFvIiIiA0p4EVERGxIAS8iImJDCngREREbUsCLiIjYkK+3B1AUa9eutfz9/fNNP336NNWqVfPCiLyvstZeWesG1X6+2tPOZnPWAl8Dgb6e2XapsmMH5tQprOrVyW7WzCN9FtVxjnOWs/jiSy1qleu6K4LK/n63LOtwjx496pWmnwsi4P39/WnZsmW+6QkJCQVOrwwqa+2VtW5Q7eerfduxdFIzLS7yM7SsnX+DoCSqP/oofhs2kHnVVZz67DOP9FlUq1lNCimEEEInOpXruiuCyv5+B3aXth/tohcREbEhBbyIiIgNKeBFRERsSAEvIiJiQwp4ERERG7ogzqI/n/T0dM6cOYMxxttDKTe1a9fmxIkT3h5GuausdYNqz127ZVkEBARQ0OWzIuJwwQd8amoqADVr1qxUAe/j40NQUJC3h1HuKmvdoNpz125ZFmlpaZw9e7bSPici53PB76LPysoiKCioUoW7SGVnjCEoKIisrCxvD0WkwrrgA15ERETyU8CLiIjYkAJeRETEhhTwkk+fPn2YMGGCt4chIiKloIAvZ8HBwed8jBkzptzG8u233xIcHMyRI0cuqL5L4pdffqF3796Eh4cTFRXF888/j2VZhbbPGX9Bj08++cTVLjo6Ot/8KVOmuPW1d+9eBg0aREREBE2bNuWxxx4jIyOjrEoVEQFscJnchebXX391/Xv16tU8+OCDbtPyfj1iZmYmfn5+5TY+Ozpx4gS33nornTt35uuvv2bHjh2MHTuWwMBA7r///gKX6dixo9vrAvD666+zYMEC/va3v7lNf/TRRxkxYoTr99yXbWVlZTFgwACCg4NZuXIlR48eZcyYMViWxYwZMzxYZeW0ZsdR5m77LwCDu0TSqG4QiftPMXHZLx7pf97+U7QDfth/invf2FaiPr68u41HxiJSXNqCL2chISGuR61atdympaen07hxY5YtW0bfvn0JDw/n7bffZsmSJTRs2NCtn/j4+HxbyJs2baJ37940aNCAqKgoHn744UJvjJKcnMxNN90EQLNmzfLtPcjOzuaZZ56hadOmNG/enCeffJLs7GzX/IyMDCZPnkxUVBQNGjSgR48erFmz5rx9f/3119x4441cfPHFNGnShH79+rF9+/bSPq3ntHTpUtLS0oiLi6NVq1b07duXcePGMXfu3EK34qtWrer2WoWEhLBixQpuvfVWqlev7ta2evXqbu1yz//3v//Nb7/9xty5c4mOjqZ79+5MnjyZxYsXV9qb1ohI+bDdFny1mBh8fvqp3Neb1bo1p6dN80hfsbGxxMbG8sorr+Dr68u6devOu8wvv/zCbbfdxsSJE3n55Zc5duwYkyZNYuzYsSxatChf+wYNGrBo0SLuvPNOvvvuO2rXru229+Cjjz7in//8J6tWreLHH3/knnvu4YorrqBfv34A3H///SQlJbFgwQLCw8P56quvGDx4MGvWrOHSSy8ttO+0tDTuvfdeoqKiOHPmDC+++CKDBw8mPj6eqlWrFljbRx99xPjx4wHHDU4KuufBrFmz6N+/f4HLb9myhc6dO7vVd9111zF16lSSk5Np1KjReZ/fb7/9lv/+97+8/vrr+ea99tprvPTSSzRo0IC+ffsyduxYVy1btmyhefPmREREuK07PT2dxMRErrnmmvOuW0SkJGwX8D4//YTfhg3eHkapjBo1ir59+xZrmTlz5nDzzTe77XKeOXMm3bp149ChQ9SrV8+tvY+PD7Vr1wagXr161KlTx21+ixYtmDRpEgBNmzZl8eLFrFu3jn79+pGUlMSyZctITEx0BdeoUaNYt24db7/9Ni+++GKhfeds2ed49dVXadSoEQkJCVx55ZUF1nb99dfTrl07wPEBITAwMF+bvPXllpKSQnh4uNu0+vXru+YVJeAXLVrEZZddRps27rtb77nnHi6//HKCg4PZunUrsbGx7N69m1deeQWAgwcPutaVo06dOvj4+HDw4MHzrldEpKRsF/BZrVtf8OvNGyJF8f3335OUlOR2AljO7uekpKRzBmBBoqKi3H4PCwvj8OHDACQmJmJZFp07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qF+/foHzT506xdy5c5k6dSp33HEHAE2aNKFjx46uNo8++qjr35GRkYwfP55XX3212AE/YMAAbr/9dsCx23b+/Pl899133H777Sxfvty1JyHnw8rs2bNp3rw5q1ev5pZbbqF169a0bv3XDqaHH36YVatWsWLFCh555BH++OMPvv76a7744gvXcxQXF0ebNn/9gdu7dy+BgYFcf/311KhRg4YNG7r1WZhRo0bRt29ft2njxo1z/fuuu+5i/fr1LFu2jG7dulGzZk2qVq1KYGAgISEhrnYLFy6kdevWbu+FuXPn0qRJE7Zt20a7du0KXP+HH354zkMDfn5+hc5LSXH8n8n7HqhXrx779+8vdLl+/fpx7NgxevfujWVZnD17lgEDBrjGfuTIEbKysgrsd926dQAcPHgQHx8f13s4R/369ct0r4WI3RVlCz6vGjh27R9z/n4xEAp8mdPAsqzTxphvgC7AfKAzcAr4Llc/G4BUZxuPBXwwwZ7qqkzX26VLF2bPnu02Le8x76iov45y5PyBbNWqlWtazrH0Q4cOuf44VqlSxS0AGjZsSGhoKNu3by804MPDwwsNd4Dt27eTnp5O165dC23z6aefMm/ePJKSkkhNTSUrK6tEx09z1+zr60udOnU4dOgQAImJiezZs4fIyEi3ZdLS0lyHIVJTU3n++edZvXo1KSkpnD17ljNnzrj6/f333wt9jnJce+21NGzYkDZt2nDdddfRvXt3evfuTY0aNc459twfEgCysrJ46aWX+Pjjj9m/fz8ZGRlkZGRw1VVXnbOfxMREvvvuuwKvOti1a1ehAV+UqyM8bcOGDbz44ou88MILtG/fnp07dxITE8O0adOYNGlSuY9HRP5SkoB/GfgeyNnXl/OXMe9mcwrQIFebQ5ZlWTkzLcuyjDEHcy3vxhhzD3APwLJly0hLS8vXJi0tjSNHjuDj4+Oa1opW+dqVl1RSi9QuMzOTqlWrum21ufpI/auPrKws1++nT592m5adne06xp2amkpqairp6emA43nx9f3rpbUsi4yMDFcby7Jc/WZmZhIQEOC23pzpOevKWffp06fztQNISEjg7rvv5sEHH+SJJ56gVq1afPnllzz77LOu9nnXW5jcNec4c+aMa+ytWrXitddey7fcRRddRGpqKjExMaxbt44nnniCiy++mICAAB566CHS0tJITU11PWcFPUeZmZmkpqZSpUoVVq5cyaZNm1i/fj2zZs0iNjaWzz//3O2DQI6c96Yxxm3scXFxxMXFMWXKFFq2bElgYCDPP/88hw8fdrXLyspyrTf3c3/dddfxxBNPuK3Hsizq169f6HPYo0eP8+6iX7NmTYHzcj687N692+1ckAMHDlCnTp1C1xkbG0ufPn1ce5oaNWrEhAkTmDBhAmPGjCEgIAAfHx/27Nnj1seff/7p6rdmzZpkZWWxZ88et634lJQU2rVr53q/FzSGS4LOMiLSMb12QDYAYQHZrmmlFeqf5frpqT6LKtM/C6uc1l2UK2vKW1paWoUcV3lIS0sjMDCw1P0UK+CNMbOAq3Hsai/T01sty3odeB0gPj7eatmyZb42CQkJ1KlTh6CgoLIcisf5+fnh4+Nz3nH7+/u72uQEU0BAAEFBQaSmplKtWjXAcaw0KCgIf39/srOz+e233+jUqRPg2N2ckpJC69atXW2MMa5+/fz8qFKlSr6x5B5jdHQ0/v7+bNmypcBd1YmJiYSFhbntjs85cS2n37zrLUrN4AjNqlWrEhQURLt27VixYgUNGzYs9Az/rVu3MnDgQPr37+963pKTk2nevDlBQUFcdtllhT5Hfn5+buvu1asXvXr14sknn6R58+asX7++wGPROf8Rc16HHAkJCdxwww0MGzYMcAT0rl27qFWrlqtdQEBAvue/bdu2fPLJJ7Ro0cJtt3pqauo5n7+PPvrovLvoC1v+0ksvJSQkhE2bNrn2MJw5c4bNmzcTGxtb6HIZGRmu92Tu58OyLIKCgvD19SU6Opr4+HgGDBjgarNhwwb69OlDUFAQV155JX5+fmzevJnbbrsNgH379rFjxw6uuuoq1/u9oDH8N9WXhcmO6YMjqtCoOuw/U4UlyZ75m9Ax3YcGwIF0H9d6ykvPy3wIca77qzJe95e9Kt4x+ISEBNq2bevtYXiFpz7YFDngjTGzgYFAd8uyduaadcD5MwRIzjU9JNe8A0A9Y4zJ2Yp3Hruvn6tNpZKenu467pnDx8eHunXrlqpfX19fHn/8caZOnUq1atV4/PHHadmyZaG754uiRo0a/POf/yQ2NpaqVavSpUsXjh49SmJiIiNGjKBp06bs37+fjz76iA4dOvDvf//7nGdel1T//v2ZM2cOQ4YMISYmhoiICPbt28cXX3zB8OHDueSSS7jkkktYuXIlN954I35+fsyYMcPtbP5mzZrRo0cPxo8fz+zZs6lWrRpPPPGE68MSwOrVq0lKSqJLly7Url2b9evXc+rUKVq0aFGs8V5yySV8/PHHbNy4keDgYBYsWMDu3bu5/PLLXW0iIyNJSEggOTmZoKAgateuzciRI1m8eDEjR45k3Lhx1K1bl127drF06VKmTZtW6KGC0uyiN8Zw7733MmvWLJo1a8Yll1zCzJkzqV69umvrHODmm2+mbdu2PPXUUwD8/e9/Jy4ujiuuuMK1i37q1Kn06tXLtYdk9OjR3HfffbRt25ZOnTrx1ltvceDAAYYPHw5AzZo1ueOOO3j66aepW7cuwcHBPPHEE0RFRZXqfStS2RUp4I0xLwMDcIT7b3lmJ+EI6Z44zrTHGBMAXAPknHkVD1THcSw+5zh8ZyAI9+Pylca6deu49NJL3aaFhYXx888/l6pff39/xo8fz+jRo9m7dy/t27dn8eLFhZ5BX1RPPfUUF110ES+++CJ//vkn9erVc11Gd/311zN27FgmTZrEmTNn6N69OzExMTzyyCOlWmdegYGBLF26lBdeeIHhw4dz4sQJQkNDufrqq7nooosAeO655xg3bhz/+Mc/qFWrFvfee6/r0EWO1157jQcffJCbb76Z4OBgJkyY4DrOD45zIb744gteeOEFTp8+TePGjXn55Zfp3Llzscb7yCOPkJyczO23305AQACDBg2if//+bN/+1ykn999/P6NHj6Zz586cPn2a77//nsjISP71r38RGxtL//79SU9PJyIigquvvhp/f/+SP4HnMW7cOE6fPs2ECRP43//+R7t27Vi6dKnbB4qkpCQaNGjg+v2RRx7BGMO0adP4888/CQ4O5vrrr3c7vHDrrbdy7NgxZs6cSUpKCpdeeikffPCB2weSqVOn4uvry8iRIzlz5gxdu3YlLi7O7fCbiBSPyXVYvOAGxrwGDAVuBn7JNeuUZVmnnG0mApOA4cDvwBNAV8B1mZwx5l9ABM7j6jh2v++yLOu8l8mdaxd906ZNqVmz5vm6sJ2CdlkuWbKEiRMnul3yZTfn201tZ6o9f+0fb93F3G2O830Hd4mkUd0gdh9OZcl3yfnalsS8eeNptzORrU2iuffeWR7ps6h6/mMnIWGppOwP4quVTcp0XRXxMjntomdrjx492pemn6JswY92/sx7ds4UYLLz388D1YDXgNrAJqBXrmvgwXHJ3Bwg564jKwD3i2NFRETEI4pyHfx59+06j6tP5q/AL6jNMeCOYoxNRERESkj3oreRwYMH23r3vIiIFJ0CXkRExIYU8CIiIjakgBcREbEhBbyIiIgNKeBFRERsSAEvIiJiQwp4Oa/o6GjmzJnj7WGIiEgxKOC9YMyYMQQHBxMcHEz9+vVp06YNTz755Hm/SrWoPB3Ia9asYeTIkR7rr7J78803ueKKKwgLC6N79+7Ex8efs33O+6Vhw4au901wcDARERGuNgcOHGDUqFF06tSJunXrMmbMmHz99OnTx235nEdx77EvIheGknwfvHhAt27dmDdvHpmZmWzcuJEHHniAtLQ0Zs6c6e2huWRkZFC1atVSf8Pd2bNn8fHxKfUX3tjB8uXLiYmJ4YUXXuDKK69k4cKF3H777cTHx7sFdm7Tpk3jqaeecvuO6BtuuMEtmDMyMqhTpw4PPPAAixYtKrCfxYsXk5GR4bbMVVddxc033+y5AkWkwtAWvJf4+/sTEhJCREQEt912G7fddhtffPEF4Pgq2ZiYGFq0aEFYWBg9e/Zk48aNrmUzMzN56qmnaNWqFaGhobRu3ZopU6YAjq20PXv28PTTT7u20HJs2rSJ3r1706BBA6Kionj44Yc5ceKEa36fPn14+OGHefLJJ2nWrBk33HADkH+PwN69exk6dCiRkZFERkYybNgw9u3b55o/ffp0unTpwpIlS2jbti2hoaEF7p349ttvCQ4O5quvvqJ79+6Eh4dz4403sm/fPjZs2MA111xDw4YNGThwIEePHnVb9r333uPKK68kLCyMDh06EBcXR3Z2tmv+a6+9xtVXX01ERARRUVGMGzeO48ePu+YvWbKEhg0bsm7dOrp06UJERAQ33XQTu3fvLt4LWUxxcXEMGjSIO++8kxYtWjBjxgxCQkJYuHBhocvUrFmTkJAQ6tevT0hICElJSezatcv1PfPg+NrZ6dOnM3jwYGrXrl1gP7Vr1yYkJMT12LhxI6dPn2bIkCEer1NEvM92W/A7TmZy6mz2+Rt6WHXfKjSr4Vfi5atVq0ZmZiYATz/9NJ9++ilz5syhUaNGxMXF0b9/f7Zs2UJoaCjz589n1apVvPHGG0RGRrJv3z7++OMPwLGVds011zBkyBBGjBjh6v+XX37htttuY+LEibz88sscO3aMSZMmMXbsWLctvo8++ohhw4axcuVKCvqmwezsbIYMGUJAQACffvopABMmTGDo0KGsWbPGtZWenJzM0qVLeeutt/Dz8yMgIKDQ2mfMmMHUqVOpWbMmo0aNYuTIkQQEBDB79mx8fHwYPnw4M2bMYMaMGQAsWrSI6dOnM336dK644gp+/fVXHnzwQfz8/Bg1ahQAVapUYerUqTRu3Jg9e/YwceJEJk6cyLx581zrTU9P56WXXmLOnDkEBAQwevRoxo8ff87vsu/fv7/bh62CFHa74IyMDBITE7n/fvfvWOrevTubN28+Z5+5vfPOO7Rs2ZJOnToVeZmCLF68mB49ehS650BELmy2C/hTZ7P5X+a5vwK3bJT8Q8XWrVtZunQpXbt2JTU1lbfeeouXX36ZXr16ATBr1izWr1/Pm2++yeOPP87evXtp0qQJnTt3xhhDRESE64997dq18fHxoXr16oSEhLjWMWfOHG6++Wa3cJk5cybdunXj0KFD1KtXD3BsCT777LOFjnXdunX8/PPPJCQkEBkZCcCCBQto164d69at49prrwUcYTZv3jzq169/3vpjYmJcu5uHDx/OxIkT+b//+z+io6MBGDhwICtWrHC1f/HFF5k8eTJ9+/YFoFGjRjzwwAO8+eabroC/7777XO0jIyOZPHkyd9xxB3FxcVSp4thxdfbsWZ5//nmaNWsGOL6bfezYsViWVejhhJdffpkzZ86ct6aCHDlyhKysrHzPSb169Vi3bl2R+jhx4gSffPIJTz75ZInGkOOPP/5gw4YNvPvuu6XqR0QqLtsFfHXfKpQmbEu33qJbs2YNDRs25OzZs2RmZnLjjTcyY8YMdu3aRWZmptvWmY+PDx06dGD79u0ADBo0iFtuuYUOHTrQvXt3evbsyd/+9jdXcBXk+++/JykpiU8++cQ1LWcLPSkpyRXwOaFamN9//53Q0FBXuAM0btyY0NBQtm/f7gr48PDwIoU7QFRUlOvfOeNo1aqVa1r9+vU5fPgw4AjJffv2MX78eB555BFXm7Nnz7rtcfjmm2+YPXs2v//+OydPniQrK4uMjAxSUlIICwsDHIdJcsIdIDQ0lIyMDP73v/8Vups7PDy8SDWVlQ8//JDs7GwGDBhQqn4WL15MaGio60OkiNiP7QK+NLvJy1OXLl2YPXs2fn5+hIaG4ufnGPfBgwfPu2x0dDTx8fFs3LiRb775htGjR9O6dWuWL19eaMhnZ2czdOhQty3bHDmBBxAUFFTCinDb6s05GawocmrP3UfeaTnH13N+zpw5k44dOxbY3549exg4cCDDhg0jJiaG4OBgEhMTGTVqlOswCICvr/vbP2fduY/l51WaXfR16tTBx8cn32t86NChIn8YWrx4MX369Cn0A0hRZGRk8P777zNs2LB8z4GI2If+d3tJtWrVaNKkSb7pjRs3pmrVqmzatImLL74YgKysLLZs2UK/fv1c7apXr07fvn3p27cvgwYNolevXuzcuZOmTZtStWrVfCEVHR3Nb7/9VuA6i6N58+YcOHCA5ORk11b8rl27OHDgAC1atChV30VRr149wsLCSEpKYuDAgQW22bZtGxkZGTz33HP4+PgAsHr1ao+svzS76KtWrUp0dDRr1651O3N97dq19OnT57zLb9u2jZ9++ompU6eWaP05Vq5cyZEjR7jjjjtK1Y+IVGwK+AomKCiI4cOHM2XKFOrUqUNkZCRz587l0KFDrmvRX3vtNS666CLat2+Pn58fS5cupUaNGq7dxw0bNiQ+Pp7+/fvj7+/vunyqV69ejB8/nrvuuovq1auzY8cOVq1axezZs4s8vmuvvZaoqCjuuecepk2bBsDEiROJjo6ma9eunn9CCjBx4kQee+wxatWqRc+ePcnMzOSHH35g//79PPTQQ1xyySVkZ2czd+5c+vTpw3/+8x+3k+tKo7S76EePHs19991H27Zt6dSpE2+99RYHDhxg+PDhrjY5e1nmzp3rtuySJUu45JJLuPrqqwvs+8cffwTg5MmTVKlShR9//BE/Pz9atmzp1m7x4sV07dqVxo0bl6oWEanYFPAV0OTJkwHHSV/Hjx/nsssu46OPPiI0NBRwbL3Pnz+fmJgYAC6//HI+/PBD127xmJgYxo8fT7t27UhPT+fo0aNERUXx+eef89xzz9G7d2+ys7Np1KgR//jHP4o1NmMM7733Ho899pjrJLdu3boxffr0crvOfdiwYQQFBTFnzhyeeeYZAgICaNmyJXfffTfgOKY/bdo0XnnlFaZOnUrHjh2JjY2tEDfrufXWWzl27BgzZ84kJSWFSy+9lA8++ICGDRu62uzduzffcidPnmTFihVMmDCh0L67devm9vuqVato2LAhiYmJrmm7du3im2++4Y033vBANSJS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\n", + "image/png": "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pVovXLig7777TkWKFNFTTz2VpddK18NrXFycw/xdSQoODtbWrVu1evVq9enTx2HdqlWr7G0AALDhOrxwGV9fX1WpUkWbN2/WoUOH7MsvXbqkESNGOLUvWbKkunTpoi1btuiDDz5I9zqv//3vf51G+NJTpEgRSdLJkyfv4AiyX9et9m+bm3vz9XvHjx+vffv2Zam2Y8eOyTCMTD8ycyMHi8Wi0NBQXb582enKG2PHjlVcXJxCQ0MdRvZTUlJ04MABe5hPz1dffaWrV6+qV69e6V5eTLr+3ti7d6/T8ri4OD333HOSpO7duzus69+/vzw9PfXee+85fHOwf/9+ffnll6pYsaJatWp12+MGANw/GOGFSw0dOlQDBw7Uww8/rM6dOystLU0rVqxQ/fr1023/ySef6ODBgxo+fLi++uorPfzww/Lz89OJEyf0888/KyYmRqdPn1aBAgVuud9WrVrpww8/1IABA9S5c2d5e3urXLly6tGjR7aOI6t1tWrVSgsXLlTnzp31+OOPK1++fKpRo4batWungQMHKjIyUk8//bS6du2qokWLatu2bdq5c6fatWun5cuXZ6tGVxo+fLiWLl2qiIgI7dq1S/Xq1dOePXu0YsUK1a5dW8OHD3doHxsbq3/84x8qX758hifSZWY6w4ULF1SrVi3Vr19fNWrUUPHixRUbG6sVK1bowoULatOmjYYMGeLwmipVqig8PFyjRo1SzZo11alTJyUmJmrevHlKSUnR9OnTucsaAMABvxXgUgMGDFBKSoomT56sGTNmqFSpUurXr59GjRqV7pUdihQpoi1btmjq1KlasGCB5syZo7S0NJUsWVK1atXSW2+9JX9//9vu97HHHlNERISmT5+u8ePHKyUlRcHBwdkOvFmt6/nnn9exY8c0f/58vffee0pNTVXfvn3Vrl071alTR6tXr9aoUaO0ePFieXh4qHHjxoqOjtbSpUvvicDr7e2tqKgojR49WgsXLlRUVJRKliypIUOGKCwszOmGFLfz008/ad++fQoKClKNW5xMWaRIEb388svatm2bvv/+e128eFHe3t6qUaOGevXqpdDQ0HQvZTZy5EgFBgZq0qRJ+vTTT+Xl5aXGjRtrzJgxatCgQZaPHwBgbhbjTu4XmgskJCTYz+q2nYyUnqSkJB09elQVKlS45U0OAADuY/ssDl18XLGX/jcn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MDL9yOzNXV544QVJ0qhRo+yhVbp+neZVq1apefPmTnOkDx8+rAMHDjhMG2rUqJE8PDy0cOFC7d2716H9/v37NW/ePFmtVj388MPZ3nfr1q31wAMPaO7cuQ6j3ZcuXdI777wjT09Ppzu5AcDdckcjvGlpaXr22We1ceNGPf/88+rdu7er6sq2ESNGaOjQofbnCQkJhN4suNVlySS59S5szZo108cff6xt27apQYMG+v333/Xtt9/Kz89PU6dOddt+x4wZo23btumrr77Stm3b9Nhjj8lqterIkSNauXKlNm/erNq1a6tDhw4KDAxURESE9u3bp4ceekgHDx7UsmXL1LFjRy1atMhtNaanWLFimjdvnjp37qxatWqpbdu2qlatmpKSknT8+HFt2LBBjRs3tp+EOHDgQEVGRurpp59W165dVbRoUW3btk07d+5Uu3bttHy54wk0LVq0UP/+/RUZGakaNWroqaeeUnJyshYsWKBGjRpp2bJlDu3nzJmjTz75RC1atFClSpXk6+urX3/9VT/88IP8/f0zfeWMjOTJk0cvvfSSPvroI9WqVUsdOnRQQkKCVqxYofLlyysgIMDpNa1atdKHH36oAQMGqHPnzvL29la5cuXUo0cPWa1WLVy4UI899piCg4PVunVr+0j5H3/8oU2bNqlo0aI6cODAHdV9J1q2bKnQ0FDNmDFDderUUbt27ey39/X19dWnn37q9JrWrVvr+PHjOnr0qP1SbKVLl9aIESP07rvvqkGDBurYsaMCAwP1xx9/6Ntvv1VycrI++OADh/naWd23p6enZsyYoZCQEDVr1kzdu3eXr6+vFi9erKNHj+rdd9/N1gmMAOAK2Q68hmHo+eef1+zZs9WrVy9NmzbNYX12T3q40xM0rFarw9dyyJpbXZZMcm/gfeCBB/Tvf/9bw4cP19SpU2UYhh577DGNHz8+0zedyI58+fJpzZo1mjp1qmbPnq3p06fLw8PDfmk8W2jw8fHRunXrNGzYMG3cuFFRUVGqXr265syZoxIlStz1wCtJ7dq1065du/TBBx9o7dq1WrNmjby9vVWmTBn1799fvXr977TtOnXqaPXq1Ro1apQWL14sDw8PNW7cWNHR0Vq6dKlT4JWu322rSpUqmj59uqZOnaoyZcpo6NCh6tKli1Pg7d69u5KSkhQdHa3t27crOTlZZcqU0csvv6x//etf9itN3ImxY8eqSJEimjlzpj755BOVKFFC3bp10+jRo9Od1vHYY48pIiJC06dP1/jx45WSkqLg4GD16NFDktSgQQPt2bNHH3zwgX744Qdt3rxZVqtVpUuXVseOHdW9e/c7rvlOffbZZ6pZs6Y+++wzffzxx/Lx8VGHDh303nvvZSlAvvPOO/btrFmzxn4SWXBwsAYNGpTutI6s7rtly5bavHmzwsLC9PXXX+vq1auqXr263nnnHad54wBwN1kMwzCy+qK0tDSFhoYqMjJS3bt311dffeV0UsPvv/+uqlWrZniZq44dO+q7777T77//bp+f27hxY23dulWnT592mse7ZMkSPfXUU3rzzTf13nvvZbpW24d6fHz8La+lmZSUpKNHj9pviYq759ixY6pQoYL69u17z1/aCYB72T6LQxcfV+yl/00xqlDcW4PaVbU/n7L8oI6edd8VNOqf3K+Fc163P+/Uc7x2lKnutv3dqeuXJfvfybcLZpfmsmTIVTKb17Iry3N4bwy7Xbt2TTfsStdPMgsICFB0dLTTZX2SkpK0ceNGBQQEqFKlSvblthMabCc43CgrJ2gAAAAANlkKvGlpaXruuecUGRlpv1tPemFXun6pm9DQUF2+fFljxoxxWDd27FjFxcUpNDTU4fJD/fv3l6enp9577z2HqQ379+/Xl19+qYoVK6pVq1ZZKRkAAAD3uSzN4R0zZoxmzpwpHx8fValSRe+++65Tm44dO6p27dqSpOHDh2vp0qWKiIjQrl27VK9ePe3Zs0crVqxQ7dq1NXz4cIfXVqlSReHh4Ro1apRq1qypTp06KTExUfPmzVNKSoqmT5/OXdYAAACQJVlKj8eOHZMkXb58OcN5tIGBgfbA6+3traioKI0ePVoLFy5UVFSUSpYsqSFDhigsLMzpequSNHLkSAUGBmrSpEn69NNP5eXlpcaNG2vMmDFq0KBB1o4OuUJgYKCyMZUcAAAgU7IUeLNzv3g/Pz9NmDAhS/do79mzJ2f0AgAAwCXu+MYTAAAAwL2MwAsAAABTI/ACAADA1Ai8AAAAMDUCLwAAAEyNwAsAAABTI/ACAADA1Ai8AAAAMDUCL+5bM2fOlMViyfLNVAAAQO5C4IWk67eNtlgsDg8vLy+VLVtWPXr00N69e91eQ1RUlCwWi8LDw92+L5jTqlWr1KJFC/n6+qpgwYJq0aKFVq1alaVtBAYGOv1buPmxadMmh9dMmTJF/fv3V82aNeXp6SmLxaKoqKh0t5/ev7WbHx4eHtntAgBAOrJ0a2GYX8WKFdWrVy9J0uXLl7Vt2zbNmzdPixcv1rp169S4ceMcrtB1nnrqKTVq1EilSpXK6VLgAnPmzFGvXr3k7++vvn37ymKx6Ouvv1bbtm01e/bsTN+ufPDgwbp48aLT8vPnz+vf//63ChcurAYNGjise/XVVyVJpUqVUrFixXTmzJkMt1+oUCGFhYWlu27Hjh1avny5QkJCMlUrACBzCLxwUKlSJacR1lGjRum9997TyJEjtX79+pwpzA38/Pzk5+eX02XABeLi4vTKK6/I399fO3fuVNmyZSVJI0aMUN26dfXKK6/o8ccfV+HChW+7rcGDB6e7/KOPPpIk9erVS/ny5XNYt2zZMtWrV08lS5bUwIED9dlnn2W4/UKFCmX4LUaHDh0kSaGhobetEwCQeUxpwG0NGjRIkrR9+3b7stTUVE2cOFG1atVS/vz55efnp5YtW2r58uVOr09LS9OMGTMUFBSkIkWKqECBAgoMDFTHjh21ceNGSVJ4eLhatmwpSRo9erTD17vHjh2zb+vq1auaMGGC6tatK29vbxUsWFDNmjXT0qVLnfbbr18/WSwWHTlyRBMnTlT16tVltVrVr18/Sbeew7tlyxa1a9dORYoUUb58+VStWjWFh4fr77//dmprsVjUokULxcbGql+/fipZsqTy5MmT4VfaNi1atJDFYlFycrLefPNNlStXTvnz51e9evW0du1aSdKlS5f06quvqnTp0sqXL58efvhh7dixI93tnT17VkOGDFGlSpVktVrl7++vZ555Rvv27XNqu379ej377LOqWrWqfHx85OPjo/r16+s///lPutu2HeO5c+f07LPPqnjx4sqfP78aNWp02+O8G7755htdvHhRgwYNsodd6fqIq23E9ptvvrmjfXz++eeSpOeee85pXbt27VSyZMk72v6pU6e0YsUKFS9e3B58AQCuwQjvbaRcS1N8cmpOl5EpflZP5fVw/d8wFovF4blhGOratasWL16sKlWq6OWXX1ZiYqK+/vprtW/fXpMnT7Z/xStdH2WLiIhQxYoV1aNHDxUsWFCxsbHatGmT1q1bp+bNm6tFixY6duyYZs2apeDgYLVo0cL++kKFCkmSkpOT1bZtW0VFRalOnTp67rnnlJKSouXLl+vJJ5/UlClT9MorrzjVP2jQIG3btk3t2rVT+/btVaJEiVse76JFi9StWzd5eXmpa9euKl68uNauXavRo0dr9erVWr9+vaxWq8NrLly4oIcfflhFihRR165ddfXqVfn6+maqf7t27apffvlFTzzxhK5cuaI5c+aoffv22rJliwYMGKCkpCR16tRJ586d04IFCxQSEqKjR486bP/w4cP20P3oo4+qY8eOOnv2rBYtWqRVq1bpxx9/VMOGDe3tx48fr0OHDqlRo0Z66qmndPHiRa1cuVIDBgzQwYMH7aOZN7p48aKaNGkiX19f9ezZU2fPnrXX8/PPP+uhhx7K1PG6gy10P/roo07rQkJC9MYbb2jDhg164YUXsrX9LVu26LffflP9+vVVq1atOyk1QzNnztS1a9fUp08f5c2b1y37AID7FYH3NuKTU7XxxIWcLiNTmpctKv8CXi7f7scffyxJ9nmLs2fP1uLFixUcHKzVq1fLy+v6PkeOHKl69erpX//6lzp06KAKFSpIkmbMmKHSpUtr7969KlCggH27hmEoLi5OkuwBd9asWWrRokW6X/mOGTNGUVFRCg8P19tvv20P4pcuXVKrVq30z3/+U08//bQCAgIcXrd3717t2rVL5cqVu+2xXrp0SaGhofLw8NDWrVtVs2ZNe629evXS3Llz9cEHH2jUqFEOr9u3b5/69++v6dOnZ/mEo/Pnz2vv3r3y9vaWdD20devWTa1bt1abNm00d+5ceXpe/6dau3Ztvf766/r88881ZMgQ+zb69OmjM2fOaNWqVWrTpo19+ahRo1S/fn09//zzDicefvrpp/afj01qaqoef/xxTZ48Wa+99ppTf+3Zs0cvvfSSpkyZojx5rv9h1apVK4WGhmrq1KmaNm3abY919+7dWrJkSab7JjAw0D4ifysxMTGSpMqVKzutsy2ztckO2+iuu6YaGIahL774QlL6I8gAgDtD4IWDQ4cO2cOm7aS16Oho5cuXT++//74k2acARERE2MOuJJUpU0ZDhgzRiBEjNGfOHIdQ6OXlZQ9tNhaLRUWKFMlUXWlpafr0009VqVIlh7ArSQULFtTbb7+tJ554QosXL3Ya5R02bFimwq4kLVmyRBcvXtSLL75oD7u2WseNG6evv/5aM2fOdAq8Xl5eioiIyNbZ9e+995497EpSp06dlDdvXl28eFEffvihQ791795dr7/+uvbs2WNftmvXLm3ZskXPPfecQ9iVpCpVquj555/XhAkTtG/fPvso7M1hV5I8PT01cOBArVmzRuvXr1ffvn0d1nt7e2v8+PH2sCtJffv21cCBAx2mu9zK7t27NXr06Ey1laTg4OBMBd74+HhJSndOtre3tzw8POxtsury5cv6+uuvVaBAAXXv3j1b27idDRs26PDhw2ratKmqVavmln0AwP2MwAsHhw8ftgeSvHnzqkSJEurRo4feeOMN1ahRQ9L1gJU/f34FBQU5vd42Urt79277si5dumjatGl66KGH1LVrVwUHB+vhhx92CHm3c/DgQcXFxSkgICDdwHTu3DlJ0oEDB5zWpVdnRnbt2uVwHDcqW7asKlasqIMHD+rSpUsqWLCgfV2FChXk7++f6f3cqE6dOg7PPTw8VLx4cSUmJjoFddsVJWJjY+3Ltm3bJkk6c+ZMuiPjtj45cOCAPfBeunRJH374oZYsWaLDhw8rMTHR4TWnTp1y2k7lypXl4+PjsMzT01MlSpRI96oG6enXr1+mAuy9ZMGCBbp8+bL69u2b6WkqWXWr+cEAgDtH4L0NP6unmpctmtNlZIqf9c5/nCEhIVq5cuUt2yQkJDicGHQj24k7N46mffzxx3rggQc0c+ZMvfvuu3r33XeVL18+denSRR999FGmguJff/0lSdq/f7/279+fYbubg5uk287ZvVFCQsItX1OyZEkdPHhQCQkJDoE3K/u4WXohytPTM93RSttob0pKin2ZrW+WL1+e7kmDNra+uXr1qlq0aKGdO3eqTp066t27t4oWLSpPT0/7POrk5GSn12d0RQtPT09du3btFkfofrba4uPjVbSo47/XxMREXbt2LdtX5JgxY4Yk901nuHjxohYtWiRfX1916dLFLfsAgPsdgfc28nrkccu82NzM19dXf/75Z7rrbMtvDHF58+bVsGHDNGzYMJ06dUobNmxQZGSkvvzyS/u808zsU5KeeeYZLVy4MEv13nzSXWb2k5Xjy+o+XM1WS0Yn7d3su+++086dOxUaGqrp06c7rJs/f75mzZrlljol983hrVy5snbs2KGYmBinwHur+b238+uvv2rbtm2qVq2amjZtmuXXZ8bcuXN15coV9enTx2GOOwDAdQi8yLI6depo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zpx523a+vr6aOnVqdmpSz5491bNnz2y9FgAAALhRjpy0BgAAANwtBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYGoEXAAAApkbgBQAAgKkReAEAAGBqBF4AAACYWpYD7+zZszVgwADVr19fVqtVFotFM2fOzLB9QkKChg4dqvLly8tqtap8+fIaOnSoEhISMnzN3LlzFRQUJG9vbxUuXFiPP/64duzYkdVSAQAAgKwH3lGjRuk///mPjh8/rlKlSt2ybWJiooKDgzVx4kRVrVpVQ4YM0YMPPqiJEycqODhYiYmJTq95//331bNnT/35558aOHCgunTpoujoaDVp0kRRUVFZLRcAAAD3uSwH3hkzZujYsWM6d+6cBg4ceMu2ERER2r17t4YPH67Vq1dr3LhxWrFihd5++23t3r1bERERDu1jYmIUFhamKlWqaO/evfroo4/02WefacuWLfL09FRoaKhSU1OzWjIAAADuY1kOvI888ojKly9/23aG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oqIkSY8++qjTOtuyDRs2ZHv7W7duVVxcnB566KFsbyO3cnXfhoeHKyYmRp9//rksFotLaszNXN2/MTEx+vjjjzVu3DjNmzdP58+fd0mduZGr+nbBggWSpM6dO+vEiROaNm2axo0bp2+++UaXL192XcG5iDs/c0+ePKnVq1erZMmSateuXbZrzK1c1bfVq1eXJK1cudJheUpKitauXav8+fPr4YcfvsNqcxdX9O2FCxeUmpqq8uXLp/s7rEKFCpKu30gLWRcVFSVvb281adLEaV1ISIikrH+2mGoOr20ic+XKlZ3WFS5cWP7+/lma7BwVFaWoqCglJycrJiZGy5Ytk7+/vyZOnOiymnMLV/bt9u3bFRERoffff59bRP8/V793586d63DyRf78+TV69GgNGzbszovNZVzVtzt27JAkbd68WUOGDFFycrJ9XbFixfT111+nOw/VzFz9vr1RZGSk0tLS1K9fP3l6mupXVaa4qm9DQ0P11Vdf6aOPPtKOHTvUoEEDJScna+XKlYqLi9PcuXNVunRpl9d/L3NF3xYuXFgeHh46fvy4DMNwCr1Hjx6VJP3+++8uqvr+kZiYqNOnT+uhhx6Sh4eH03rbzy2rny2mGuGNj4+XJPn5+aW73tfX194mM6KiojR69GiNGzdOixYtUtmyZbVy5UrVr1/fJfXmJq7q2+TkZPXr10916tTRP//5T5fWmJu5qn+LFSumDz74QL/99psSExMVGxur2bNnq0iRIho+fLg+++wzl9adG7iqb8+ePStJGjRokAYPHqwTJ07o3Llz+vjjjxUfH6+OHTvq9OnTris8F3D1Z66NYRiKjIyUJD333HPZLzAXc1Xf5s+fX1FRUerVq5c2bNigDz/8UFOmTNHhw4fVo0cPNW3a1KV15wau6NsCBQooODhYf/75pz755BOHdYsXL9bu3bslXT9pEFmTmZ/Pje0yy1SB19XCw8NlGIYuX76sn376SdWqVVOTJk3u6DJc97u33npLMTEx+uKLL9L9yw13pnr16vrXv/6latWqqUCBAgoICFDPnj21cuVKeXl5KSwsTGlpaTldZq5k67f27dtr3LhxKlOmjPz9/TVo0CANGTJE8fHx+vzzz3O4SnNYt26djh49quDgYFWqVCmny8nVzp8/rzZt2mjbtm1avny5Ll68qDNnzmjatGmKjIxUw4YNFRcX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\n", "text/plain": [ - "
" + "
" ] }, - "metadata": { - "needs_background": "light" - }, + "metadata": {}, "output_type": "display_data" } ], @@ -794,7 +857,6 @@ { "data": { "application/javascript": [ - "\n", "(function(root) {\n", " function now() {\n", " return new Date();\n", @@ -807,7 +869,7 @@ " root._bokeh_is_loading = undefined;\n", " }\n", "\n", - " const JS_MIME_TYPE = 'application/javascript';\n", + "const JS_MIME_TYPE = 'application/javascript';\n", " const HTML_MIME_TYPE = 'text/html';\n", " const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", " const CLASS_NAME = 'output_bokeh rendered_html';\n", @@ -930,8 +992,6 @@ " register_renderer(events, OutputArea);\n", " }\n", " }\n", - "\n", - " \n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", @@ -967,7 +1027,6 @@ " }\n", " }\n", "\n", - "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) {\n", @@ -1038,29 +1097,22 @@ " document.body.appendChild(element);\n", " }\n", "\n", - " \n", - " const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.2.min.js\"];\n", + " const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\"];\n", " const css_urls = [];\n", - " \n", "\n", - " const inline_js = [\n", - " function(Bokeh) {\n", + " const inline_js = [ function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", - " function(Bokeh) {\n", - " \n", - " \n", + "function(Bokeh) {\n", " }\n", " ];\n", "\n", " function run_inline_js() {\n", - " \n", " if (root.Bokeh !== undefined || force === true) {\n", - " \n", - " for (let i = 0; i < inline_js.length; i++) {\n", + " for (let i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }\n", - " } else if (Date.now() < root._bokeh_timeout) {\n", + "} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", @@ -1069,7 +1121,6 @@ " const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n", " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", " }\n", - "\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", @@ -1083,7 +1134,7 @@ " }\n", "}(window));" ], - "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n const el = document.getElementById(null);\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n \n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.2.min.js\"];\n const css_urls = [];\n \n\n const inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n function(Bokeh) {\n \n \n }\n ];\n\n function run_inline_js() {\n \n if (root.Bokeh !== undefined || force === true) {\n \n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + "application/vnd.bokehjs_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n const el = document.getElementById(null);\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {}, "output_type": "display_data" @@ -1092,12 +1143,7 @@ "data": { "text/html": [ "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n" + "
\n" ] }, "metadata": {}, @@ -1108,11 +1154,9 @@ "application/javascript": [ "(function(root) {\n", " function embed_document(root) {\n", - " \n", - " const docs_json = {\"4b864502-40f5-4e59-8146-2f4039ed6673\":{\"defs\":[],\"roots\":{\"references\":[{\"attributes\":{\"children\":[{\"id\":\"1400\"},{\"id\":\"1398\"}]},\"id\":\"1401\",\"type\":\"Column\"},{\"attributes\":{\"callback\":null},\"id\":\"1282\",\"type\":\"HoverTool\"},{\"attributes\":{\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"syncable\":false,\"xs_units\":\"screen\",\"ys_units\":\"screen\"},\"id\":\"1182\",\"type\":\"PolyAnnotation\"},{\"attributes\":{},\"id\":\"1344\",\"type\":\"Selection\"},{\"attributes\":{\"bounds\":\"auto\",\"min_interval\":0.1},\"id\":\"1155\",\"type\":\"DataRange1d\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1324\"},\"glyph\":{\"id\":\"1325\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1327\"},\"nonselection_glyph\":{\"id\":\"1326\"},\"view\":{\"id\":\"1329\"}},\"id\":\"1328\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"syncable\":false,\"xs_units\":\"screen\",\"ys_units\":\"screen\"},\"id\":\"1284\",\"type\":\"PolyAnnotation\"},{\"attributes\":{\"source\":{\"id\":\"1075\"}},\"id\":\"1101\",\"type\":\"CDSView\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1075\"},\"glyph\":{\"id\":\"1097\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1099\"},\"nonselection_glyph\":{\"id\":\"1098\"},\"view\":{\"id\":\"1101\"}},\"id\":\"1100\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"bottom_units\":\"screen\",\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"right_units\":\"screen\",\"syncable\":false,\"top_units\":\"screen\"},\"id\":\"1283\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_dash\":[6],\"line_width\":1.7857142857142858,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1116\",\"type\":\"Line\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#1f77b4\",\"line_dash\":[6],\"line_width\":1.7857142857142858,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1117\",\"type\":\"Line\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1076\"},\"glyph\":{\"id\":\"1115\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1117\"},\"nonselection_glyph\":{\"id\":\"1116\"},\"view\":{\"id\":\"1119\"}},\"id\":\"1118\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"line_alpha\":{\"value\":0.2},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1327\",\"type\":\"Segment\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1297\"},\"glyph\":{\"id\":\"1298\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1300\"},\"nonselection_glyph\":{\"id\":\"1299\"},\"view\":{\"id\":\"1302\"}},\"id\":\"1301\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"source\":{\"id\":\"1076\"}},\"id\":\"1119\",\"type\":\"CDSView\"},{\"attributes\":{\"source\":{\"id\":\"1324\"}},\"id\":\"1329\",\"type\":\"CDSView\"},{\"attributes\":{\"bounds\":[0,1000],\"end\":100,\"min_interval\":5,\"start\":0},\"id\":\"1294\",\"type\":\"DataRange1d\"},{\"attributes\":{},\"id\":\"1394\",\"type\":\"Selection\"},{\"attributes\":{\"coordinates\":null,\"group\":null,\"text\":\"theta()\\nautocorrelation chain 3\"},\"id\":\"1330\",\"type\":\"Title\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1337\"},\"group\":null,\"major_label_policy\":{\"id\":\"1338\"},\"ticker\":{\"id\":\"1048\"}},\"id\":\"1047\",\"type\":\"LinearAxis\"},{\"attributes\":{\"coordinates\":null,\"group\":null,\"text\":\"theta()\\nautocorrelation chain 0\"},\"id\":\"1303\",\"type\":\"Title\"},{\"attributes\":{},\"id\":\"1263\",\"type\":\"LinearScale\"},{\"attributes\":{\"axis\":{\"id\":\"1203\"},\"coordinates\":null,\"dimension\":1,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1206\",\"type\":\"Grid\"},{\"attributes\":{\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"syncable\":false,\"xs_units\":\"screen\",\"ys_units\":\"screen\"},\"id\":\"1064\",\"type\":\"PolyAnnotation\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1391\"},\"group\":null,\"major_label_policy\":{\"id\":\"1392\"},\"ticker\":{\"id\":\"1268\"}},\"id\":\"1267\",\"type\":\"LinearAxis\"},{\"attributes\":{\"data\":{\"draw\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"theta()\":{\"__ndarray__\":\"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\",\"dtype\":\"float32\",\"order\":\"little\",\"shape\":[1000]}},\"selected\":{\"id\":\"1340\"},\"selection_policy\":{\"id\":\"1339\"}},\"id\":\"1074\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1337\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1076\"},\"glyph\":{\"id\":\"1121\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1123\"},\"nonselection_glyph\":{\"id\":\"1122\"},\"view\":{\"id\":\"1125\"}},\"id\":\"1124\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"axis\":{\"id\":\"1199\"},\"coordinates\":null,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1202\",\"type\":\"Grid\"},{\"attributes\":{\"line_alpha\":{\"value\":0.2},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1300\",\"type\":\"Segment\"},{\"attributes\":{},\"id\":\"1346\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1265\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"1353\",\"type\":\"AllLabels\"},{\"attributes\":{},\"id\":\"1043\",\"type\":\"LinearScale\"},{\"attributes\":{\"below\":[{\"id\":\"1165\"}],\"center\":[{\"id\":\"1168\"},{\"id\":\"1172\"},{\"id\":\"1296\"}],\"height\":300,\"left\":[{\"id\":\"1169\"}],\"outline_line_color\":\"black\",\"output_backend\":\"webgl\",\"renderers\":[{\"id\":\"1301\"}],\"title\":{\"id\":\"1303\"},\"toolbar\":{\"id\":\"1183\"},\"toolbar_location\":null,\"width\":300,\"x_range\":{\"id\":\"1294\"},\"x_scale\":{\"id\":\"1161\"},\"y_range\":{\"id\":\"1295\"},\"y_scale\":{\"id\":\"1163\"}},\"id\":\"1156\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{},\"id\":\"1355\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1204\",\"type\":\"BasicTicker\"},{\"attributes\":{},\"id\":\"1061\",\"type\":\"SaveTool\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_dash\":[6,4,2,4],\"line_width\":1.7857142857142858,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1134\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1343\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1364\"},\"group\":null,\"major_label_policy\":{\"id\":\"1365\"},\"minor_tick_line_color\":null,\"ticker\":{\"id\":\"1204\"}},\"id\":\"1203\",\"type\":\"LinearAxis\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.6},\"fill_color\":{\"value\":\"#2a2eec\"},\"hatch_alpha\":{\"value\":0.5},\"line_alpha\":{\"value\":0.5},\"line_color\":{\"value\":\"#2a2eec\"},\"line_dash\":{\"value\":\"solid\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1085\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"1352\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1340\",\"type\":\"Selection\"},{\"attributes\":{\"bottom\":-0.061980642139300234,\"coordinates\":null,\"fill_color\":\"gray\",\"group\":null,\"top\":0.061980642139300234},\"id\":\"1305\",\"type\":\"BoxAnnotation\"},{\"attributes\":{},\"id\":\"1161\",\"type\":\"LinearScale\"},{\"attributes\":{\"source\":{\"id\":\"1297\"}},\"id\":\"1302\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1356\",\"type\":\"AllLabels\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1379\"},\"group\":null,\"major_label_policy\":{\"id\":\"1380\"},\"ticker\":{\"id\":\"1234\"}},\"id\":\"1233\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"1231\",\"type\":\"LinearScale\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_dash\":[2,4],\"line_width\":1.7857142857142858,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1098\",\"type\":\"Line\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"hatch_alpha\":{\"value\":0.1},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"line_dash\":{\"value\":\"dashed\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1122\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"1357\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"source\":{\"id\":\"1074\"}},\"id\":\"1083\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1358\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1163\",\"type\":\"LinearScale\"},{\"attributes\":{\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"syncable\":false,\"xs_units\":\"screen\",\"ys_units\":\"screen\"},\"id\":\"1216\",\"type\":\"PolyAnnotation\"},{\"attributes\":{\"line_alpha\":0.6,\"line_color\":\"#328c06\",\"line_dash\":[],\"line_width\":2,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1115\",\"type\":\"Line\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.6},\"fill_color\":{\"value\":\"#328c06\"},\"hatch_alpha\":{\"value\":0.5},\"line_alpha\":{\"value\":0.5},\"line_color\":{\"value\":\"#328c06\"},\"line_dash\":{\"value\":\"dashed\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1121\",\"type\":\"Circle\"},{\"attributes\":{\"source\":{\"id\":\"1076\"}},\"id\":\"1125\",\"type\":\"CDSView\"},{\"attributes\":{\"data\":{\"x0\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"x1\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"y1\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[1000]}},\"selected\":{\"id\":\"1370\"},\"selection_policy\":{\"id\":\"1369\"}},\"id\":\"1306\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1365\",\"type\":\"AllLabels\"},{\"attributes\":{\"callback\":null},\"id\":\"1062\",\"type\":\"HoverTool\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1355\"},\"group\":null,\"major_label_policy\":{\"id\":\"1356\"},\"ticker\":{\"id\":\"1166\"}},\"id\":\"1165\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"1229\",\"type\":\"LinearScale\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.2},\"fill_color\":{\"value\":\"#1f77b4\"},\"hatch_alpha\":{\"value\":0.2},\"line_alpha\":{\"value\":0.2},\"line_color\":{\"value\":\"#1f77b4\"},\"line_dash\":{\"value\":\"dashed\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1123\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"1058\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#1f77b4\",\"line_dash\":[2,4],\"line_width\":1.7857142857142858,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1099\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1170\",\"type\":\"BasicTicker\"},{\"attributes\":{\"line_alpha\":{\"value\":0.1},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1308\",\"type\":\"Segment\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#1f77b4\",\"line_dash\":[6,4,2,4],\"line_width\":1.7857142857142858,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1135\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1166\",\"type\":\"BasicTicker\"},{\"attributes\":{\"line_color\":{\"value\":\"#fa7c17\"},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1307\",\"type\":\"Segment\"},{\"attributes\":{\"line_alpha\":{\"value\":0.2},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1309\",\"type\":\"Segment\"},{\"attributes\":{},\"id\":\"1056\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"1207\",\"type\":\"ResetTool\"},{\"attributes\":{\"coordinates\":null,\"group\":null,\"text\":\"theta() trace plot\"},\"id\":\"1153\",\"type\":\"Title\"},{\"attributes\":{\"bottom\":-0.061980642139300234,\"coordinates\":null,\"fill_color\":\"gray\",\"group\":null,\"top\":0.061980642139300234},\"id\":\"1314\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"axis\":{\"id\":\"1165\"},\"coordinates\":null,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1168\",\"type\":\"Grid\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1306\"},\"glyph\":{\"id\":\"1307\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1309\"},\"nonselection_glyph\":{\"id\":\"1308\"},\"view\":{\"id\":\"1311\"}},\"id\":\"1310\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1364\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1367\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1077\"},\"glyph\":{\"id\":\"1133\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1135\"},\"nonselection_glyph\":{\"id\":\"1134\"},\"view\":{\"id\":\"1137\"}},\"id\":\"1136\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1208\",\"type\":\"PanTool\"},{\"attributes\":{\"source\":{\"id\":\"1306\"}},\"id\":\"1311\",\"type\":\"CDSView\"},{\"attributes\":{\"axis\":{\"id\":\"1169\"},\"coordinates\":null,\"dimension\":1,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1172\",\"type\":\"Grid\"},{\"attributes\":{\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"syncable\":false,\"xs_units\":\"screen\",\"ys_units\":\"screen\"},\"id\":\"1250\",\"type\":\"PolyAnnotation\"},{\"attributes\":{\"source\":{\"id\":\"1077\"}},\"id\":\"1137\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1368\",\"type\":\"AllLabels\"},{\"attributes\":{\"overlay\":{\"id\":\"1215\"}},\"id\":\"1209\",\"type\":\"BoxZoomTool\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1074\"},\"glyph\":{\"id\":\"1085\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1087\"},\"nonselection_glyph\":{\"id\":\"1086\"},\"view\":{\"id\":\"1089\"}},\"id\":\"1088\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1352\"},\"group\":null,\"major_label_policy\":{\"id\":\"1353\"},\"minor_tick_line_color\":null,\"ticker\":{\"id\":\"1170\"}},\"id\":\"1169\",\"type\":\"LinearAxis\"},{\"attributes\":{\"coordinates\":null,\"group\":null,\"text\":\"theta()\\nautocorrelation chain 1\"},\"id\":\"1312\",\"type\":\"Title\"},{\"attributes\":{},\"id\":\"1212\",\"type\":\"UndoTool\"},{\"attributes\":{},\"id\":\"1369\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1210\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1367\"},\"group\":null,\"major_label_policy\":{\"id\":\"1368\"},\"ticker\":{\"id\":\"1200\"}},\"id\":\"1199\",\"type\":\"LinearAxis\"},{\"attributes\":{\"source\":{\"id\":\"1074\"}},\"id\":\"1089\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1345\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"toolbars\":[{\"id\":\"1065\"},{\"id\":\"1183\"},{\"id\":\"1217\"},{\"id\":\"1251\"},{\"id\":\"1285\"}],\"tools\":[{\"id\":\"1055\"},{\"id\":\"1056\"},{\"id\":\"1057\"},{\"id\":\"1058\"},{\"id\":\"1059\"},{\"id\":\"1060\"},{\"id\":\"1061\"},{\"id\":\"1062\"},{\"id\":\"1173\"},{\"id\":\"1174\"},{\"id\":\"1175\"},{\"id\":\"1176\"},{\"id\":\"1177\"},{\"id\":\"1178\"},{\"id\":\"1179\"},{\"id\":\"1180\"},{\"id\":\"1207\"},{\"id\":\"1208\"},{\"id\":\"1209\"},{\"id\":\"1210\"},{\"id\":\"1211\"},{\"id\":\"1212\"},{\"id\":\"1213\"},{\"id\":\"1214\"},{\"id\":\"1241\"},{\"id\":\"1242\"},{\"id\":\"1243\"},{\"id\":\"1244\"},{\"id\":\"1245\"},{\"id\":\"1246\"},{\"id\":\"1247\"},{\"id\":\"1248\"},{\"id\":\"1275\"},{\"id\":\"1276\"},{\"id\":\"1277\"},{\"id\":\"1278\"},{\"id\":\"1279\"},{\"id\":\"1280\"},{\"id\":\"1281\"},{\"id\":\"1282\"}]},\"id\":\"1399\",\"type\":\"ProxyToolbar\"},{\"attributes\":{},\"id\":\"1370\",\"type\":\"Selection\"},{\"attributes\":{\"overlay\":{\"id\":\"1216\"}},\"id\":\"1211\",\"type\":\"LassoSelectTool\"},{\"attributes\":{},\"id\":\"1197\",\"type\":\"LinearScale\"},{\"attributes\":{\"tools\":[{\"id\":\"1207\"},{\"id\":\"1208\"},{\"id\":\"1209\"},{\"id\":\"1210\"},{\"id\":\"1211\"},{\"id\":\"1212\"},{\"id\":\"1213\"},{\"id\":\"1214\"}]},\"id\":\"1217\",\"type\":\"Toolbar\"},{\"attributes\":{},\"id\":\"1200\",\"type\":\"BasicTicker\"},{\"attributes\":{\"bottom_units\":\"screen\",\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"right_units\":\"screen\",\"syncable\":false,\"top_units\":\"screen\"},\"id\":\"1181\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1077\"},\"glyph\":{\"id\":\"1139\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1141\"},\"nonselection_glyph\":{\"id\":\"1140\"},\"view\":{\"id\":\"1143\"}},\"id\":\"1142\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1195\",\"type\":\"LinearScale\"},{\"attributes\":{\"below\":[{\"id\":\"1233\"}],\"center\":[{\"id\":\"1236\"},{\"id\":\"1240\"},{\"id\":\"1314\"}],\"height\":300,\"left\":[{\"id\":\"1237\"}],\"outline_line_color\":\"black\",\"output_backend\":\"webgl\",\"renderers\":[{\"id\":\"1319\"}],\"title\":{\"id\":\"1321\"},\"toolbar\":{\"id\":\"1251\"},\"toolbar_location\":null,\"width\":300,\"x_range\":{\"id\":\"1294\"},\"x_scale\":{\"id\":\"1229\"},\"y_range\":{\"id\":\"1295\"},\"y_scale\":{\"id\":\"1231\"}},\"id\":\"1226\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"overlay\":{\"id\":\"1064\"}},\"id\":\"1059\",\"type\":\"LassoSelectTool\"},{\"attributes\":{},\"id\":\"1213\",\"type\":\"SaveTool\"},{\"attributes\":{\"callback\":null},\"id\":\"1214\",\"type\":\"HoverTool\"},{\"attributes\":{\"data\":{\"x0\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"x1\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"y1\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[1000]}},\"selected\":{\"id\":\"1382\"},\"selection_policy\":{\"id\":\"1381\"}},\"id\":\"1315\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"toolbar\":{\"id\":\"1399\"},\"toolbar_location\":\"above\"},\"id\":\"1400\",\"type\":\"ToolbarBox\"},{\"attributes\":{},\"id\":\"1055\",\"type\":\"ResetTool\"},{\"attributes\":{},\"id\":\"1173\",\"type\":\"ResetTool\"},{\"attributes\":{\"line_alpha\":{\"value\":0.1},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1317\",\"type\":\"Segment\"},{\"attributes\":{\"axis\":{\"id\":\"1233\"},\"coordinates\":null,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1236\",\"type\":\"Grid\"},{\"attributes\":{\"line_alpha\":{\"value\":0.2},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1318\",\"type\":\"Segment\"},{\"attributes\":{},\"id\":\"1174\",\"type\":\"PanTool\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"hatch_alpha\":{\"value\":0.1},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"line_dash\":{\"value\":\"solid\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1086\",\"type\":\"Circle\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"hatch_alpha\":{\"value\":0.1},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"line_dash\":{\"value\":\"dashdot\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1140\",\"type\":\"Circle\"},{\"attributes\":{\"line_color\":{\"value\":\"#328c06\"},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1316\",\"type\":\"Segment\"},{\"attributes\":{\"bottom\":-0.061980642139300234,\"coordinates\":null,\"fill_color\":\"gray\",\"group\":null,\"top\":0.061980642139300234},\"id\":\"1323\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"bottom_units\":\"screen\",\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"right_units\":\"screen\",\"syncable\":false,\"top_units\":\"screen\"},\"id\":\"1215\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_width\":1.7857142857142858,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1080\",\"type\":\"Line\"},{\"attributes\":{\"overlay\":{\"id\":\"1181\"}},\"id\":\"1175\",\"type\":\"BoxZoomTool\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1315\"},\"glyph\":{\"id\":\"1316\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1318\"},\"nonselection_glyph\":{\"id\":\"1317\"},\"view\":{\"id\":\"1320\"}},\"id\":\"1319\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.2},\"fill_color\":{\"value\":\"#1f77b4\"},\"hatch_alpha\":{\"value\":0.2},\"line_alpha\":{\"value\":0.2},\"line_color\":{\"value\":\"#1f77b4\"},\"line_dash\":{\"value\":\"dotted\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1105\",\"type\":\"Circle\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.6},\"fill_color\":{\"value\":\"#c10c90\"},\"hatch_alpha\":{\"value\":0.5},\"line_alpha\":{\"value\":0.5},\"line_color\":{\"value\":\"#c10c90\"},\"line_dash\":{\"value\":\"dashdot\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1139\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"1178\",\"type\":\"UndoTool\"},{\"attributes\":{\"source\":{\"id\":\"1077\"}},\"id\":\"1143\",\"type\":\"CDSView\"},{\"attributes\":{\"source\":{\"id\":\"1315\"}},\"id\":\"1320\",\"type\":\"CDSView\"},{\"attributes\":{\"overlay\":{\"id\":\"1063\"}},\"id\":\"1057\",\"type\":\"BoxZoomTool\"},{\"attributes\":{},\"id\":\"1176\",\"type\":\"WheelZoomTool\"},{\"attributes\":{},\"id\":\"1039\",\"type\":\"DataRange1d\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.2},\"fill_color\":{\"value\":\"#1f77b4\"},\"hatch_alpha\":{\"value\":0.2},\"line_alpha\":{\"value\":0.2},\"line_color\":{\"value\":\"#1f77b4\"},\"line_dash\":{\"value\":\"dashdot\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1141\",\"type\":\"Circle\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1074\"},\"glyph\":{\"id\":\"1079\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1081\"},\"nonselection_glyph\":{\"id\":\"1080\"},\"view\":{\"id\":\"1083\"}},\"id\":\"1082\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"coordinates\":null,\"group\":null,\"text\":\"theta()\\nautocorrelation chain 2\"},\"id\":\"1321\",\"type\":\"Title\"},{\"attributes\":{},\"id\":\"1238\",\"type\":\"BasicTicker\"},{\"attributes\":{\"below\":[{\"id\":\"1047\"}],\"center\":[{\"id\":\"1050\"},{\"id\":\"1054\"}],\"height\":300,\"left\":[{\"id\":\"1051\"}],\"outline_line_color\":\"black\",\"output_backend\":\"webgl\",\"renderers\":[{\"id\":\"1082\"},{\"id\":\"1088\"},{\"id\":\"1100\"},{\"id\":\"1106\"},{\"id\":\"1118\"},{\"id\":\"1124\"},{\"id\":\"1136\"},{\"id\":\"1142\"}],\"title\":{\"id\":\"1153\"},\"toolbar\":{\"id\":\"1065\"},\"toolbar_location\":null,\"width\":300,\"x_range\":{\"id\":\"1039\"},\"x_scale\":{\"id\":\"1043\"},\"y_range\":{\"id\":\"1155\"},\"y_scale\":{\"id\":\"1045\"}},\"id\":\"1038\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"overlay\":{\"id\":\"1182\"}},\"id\":\"1177\",\"type\":\"LassoSelectTool\"},{\"attributes\":{\"line_alpha\":0.6,\"line_color\":\"#fa7c17\",\"line_dash\":[],\"line_width\":2,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1097\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1234\",\"type\":\"BasicTicker\"},{\"attributes\":{},\"id\":\"1060\",\"type\":\"UndoTool\"},{\"attributes\":{},\"id\":\"1338\",\"type\":\"AllLabels\"},{\"attributes\":{},\"id\":\"1377\",\"type\":\"AllLabels\"},{\"attributes\":{\"tools\":[{\"id\":\"1055\"},{\"id\":\"1056\"},{\"id\":\"1057\"},{\"id\":\"1058\"},{\"id\":\"1059\"},{\"id\":\"1060\"},{\"id\":\"1061\"},{\"id\":\"1062\"}]},\"id\":\"1065\",\"type\":\"Toolbar\"},{\"attributes\":{\"source\":{\"id\":\"1075\"}},\"id\":\"1107\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1335\",\"type\":\"AllLabels\"},{\"attributes\":{\"below\":[{\"id\":\"1267\"}],\"center\":[{\"id\":\"1270\"},{\"id\":\"1274\"},{\"id\":\"1323\"}],\"height\":300,\"left\":[{\"id\":\"1271\"}],\"outline_line_color\":\"black\",\"output_backend\":\"webgl\",\"renderers\":[{\"id\":\"1328\"}],\"title\":{\"id\":\"1330\"},\"toolbar\":{\"id\":\"1285\"},\"toolbar_location\":null,\"width\":300,\"x_range\":{\"id\":\"1294\"},\"x_scale\":{\"id\":\"1263\"},\"y_range\":{\"id\":\"1295\"},\"y_scale\":{\"id\":\"1265\"}},\"id\":\"1260\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{},\"id\":\"1045\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"1179\",\"type\":\"SaveTool\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1075\"},\"glyph\":{\"id\":\"1103\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1105\"},\"nonselection_glyph\":{\"id\":\"1104\"},\"view\":{\"id\":\"1107\"}},\"id\":\"1106\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"bottom_units\":\"screen\",\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"right_units\":\"screen\",\"syncable\":false,\"top_units\":\"screen\"},\"id\":\"1063\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"line_alpha\":{\"value\":0.1},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1326\",\"type\":\"Segment\"},{\"attributes\":{\"axis\":{\"id\":\"1237\"},\"coordinates\":null,\"dimension\":1,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1240\",\"type\":\"Grid\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#1f77b4\",\"line_width\":1.7857142857142858,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1081\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1334\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"data\":{\"x0\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"x1\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"y1\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[1000]}},\"selected\":{\"id\":\"1394\"},\"selection_policy\":{\"id\":\"1393\"}},\"id\":\"1324\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null},\"id\":\"1180\",\"type\":\"HoverTool\"},{\"attributes\":{},\"id\":\"1376\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"line_alpha\":0.6,\"line_color\":\"#c10c90\",\"line_dash\":[],\"line_width\":2,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1133\",\"type\":\"Line\"},{\"attributes\":{\"tools\":[{\"id\":\"1173\"},{\"id\":\"1174\"},{\"id\":\"1175\"},{\"id\":\"1176\"},{\"id\":\"1177\"},{\"id\":\"1178\"},{\"id\":\"1179\"},{\"id\":\"1180\"}]},\"id\":\"1183\",\"type\":\"Toolbar\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.6},\"fill_color\":{\"value\":\"#fa7c17\"},\"hatch_alpha\":{\"value\":0.5},\"line_alpha\":{\"value\":0.5},\"line_color\":{\"value\":\"#fa7c17\"},\"line_dash\":{\"value\":\"dotted\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1103\",\"type\":\"Circle\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1376\"},\"group\":null,\"major_label_policy\":{\"id\":\"1377\"},\"minor_tick_line_color\":null,\"ticker\":{\"id\":\"1238\"}},\"id\":\"1237\",\"type\":\"LinearAxis\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.2},\"fill_color\":{\"value\":\"#1f77b4\"},\"hatch_alpha\":{\"value\":0.2},\"line_alpha\":{\"value\":0.2},\"line_color\":{\"value\":\"#1f77b4\"},\"line_dash\":{\"value\":\"solid\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1087\",\"type\":\"Circle\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"hatch_alpha\":{\"value\":0.1},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"line_dash\":{\"value\":\"dotted\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1104\",\"type\":\"Circle\"},{\"attributes\":{\"line_color\":{\"value\":\"#c10c90\"},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1325\",\"type\":\"Segment\"},{\"attributes\":{\"tools\":[{\"id\":\"1241\"},{\"id\":\"1242\"},{\"id\":\"1243\"},{\"id\":\"1244\"},{\"id\":\"1245\"},{\"id\":\"1246\"},{\"id\":\"1247\"},{\"id\":\"1248\"}]},\"id\":\"1251\",\"type\":\"Toolbar\"},{\"attributes\":{},\"id\":\"1241\",\"type\":\"ResetTool\"},{\"attributes\":{},\"id\":\"1052\",\"type\":\"BasicTicker\"},{\"attributes\":{\"line_alpha\":0.6,\"line_color\":\"#2a2eec\",\"line_width\":2,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1079\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1242\",\"type\":\"PanTool\"},{\"attributes\":{\"overlay\":{\"id\":\"1249\"}},\"id\":\"1243\",\"type\":\"BoxZoomTool\"},{\"attributes\":{},\"id\":\"1339\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1246\",\"type\":\"UndoTool\"},{\"attributes\":{},\"id\":\"1244\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"data\":{\"draw\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"theta()\":{\"__ndarray__\":\"ZhmSPmYZkj6QVz8/R0pCP0dKQj9HSkI/R0pCPyobPT+2mls/4HRYP+B0WD8Z0CM/GdAjP8fzHT/H8x0/x/MdP8fzHT8pJUI/KSVCPyklQj+kvCE/Ko4XPyqOFz8/vQg/0IDAPpL9GD9DMTs/QzE7P6xnQD+sZ0A/rGdAP6xnQD8F/Ug/Bf1IPwX9SD8F/Ug/ShNIPxBCBT+ullQ/rpZUPxe5Lj8XuS4/HglmP5R+Lj/VVDk/Jz9PPyc/Tz96jAo/eowKP3qMCj9ppFY/aaRWP+fHbT++PEM/ffMNP9l+Iz/ZfiM/2X4jP9l+Iz9JnDw/SZw8P0mcPD9JnDw/U2AIP/DsYD/w7GA/WDw/P1g8Pz9YPD8/g/4/P4P+Pz+D/j8/g/4/P4P+Pz8Snyw/D7ZSP8WqRD/FqkQ/wYBSP8GAUj/BgFI/R/W5PgwqTT+Hz1E//rg1P/64NT8yJiU/ZtcpP2bXKT9m1yk/ZtcpP+xuKD/tRTY//q8nP5bxRz+W8Uc/lvFHP5bxRz+W8Uc/lvFHP5bxRz+W8Uc/lvFHP5bxRz/zA0U/ef8yP3n/Mj95/zI/ef8yP6OtQj+jrUI/o61CP6OtQj9vqTs/b6k7P2+pOz9vqTs/b6k7P2+pOz9vqTs/b6k7P2+pOz9vqTs/4etZP+HrWT/h61k/4etZP+HrWT/dhl4/3YZeP7+FUj+/hVI/v4VSP7+FUj+II/8+iCP/Pogj/z6II/8+3IDsPn/SQT9mgB0/+fcJP7j/Az+VbNU+lWzVPoBASz+AQEs/gEBLPxfDOD8Xwzg/pLL5PmNEJD9jRCQ/Y0QkP/WeET+fCUQ/nwlEP58JRD8elww/HpcMPx6XDD8elww/ef5JP3n+ST8Tqlk/E6pZPxOqWT8Tqlk/E6pZPxOqWT8Tqlk/1ZpPPyfGzj5MkmM/TJJjP4SuVj+ErlY/hK5WP1GySD9Rskg/UbJIP1GySD9Rskg/BX4xPwV+MT8FfjE/GPxJPxj8ST8Y/Ek/NYZEPzWGRD81hkQ/NYZEPzWGRD81hkQ/NYZEPzWGRD8y4U4/MuFOPzLhTj8y4U4/+qxOP20FWD83MFo/NzBaPz8EMT8/BDE/syFXP7MhVz9B1j8/QdY/P6moKD+pqCg/qagoP6moKD+pqCg/qagoP87GOj/Oxjo/n1k4P59ZOD+fWTg/n1k4P59ZOD/UqVg/RmxSP0ZsUj9GbFI/KngvP0RxLD8SVTI/ElUyPxJVMj/CDxs/wg8bP8IPGz+YYCM/mGAjP5hgIz//ZDk/cjBDP0igRD9IoEQ/Ldg1Py3YNT8t2DU/etYUP3rWFD961hQ/etYUP5qEFz9k5BY/xPcuP7nrJj+56yY/uesmP7nrJj+56yY/uesmP7nrJj9CZyI/tnZSP33XOz991zs/VyxDP1csQz9apB8/mds8P5nbPD+Z2zw/mds8PwEjNj8BIzY/ASM2Px8TMT8fEzE/P4tYP1KtLz9SrS8/Uq0vP1KtLz9SrS8/Uq0vP3nZJD952SQ/edkkP9O8ST8P7U0/D+1NP73sNT+97DU/vew1P/28FD/9vBQ//bwUP/28FD/hTSc/4U0nP+FNJz/XkE4/15BOP6hFKj+oRSo/qEUqP0llKD85k0k/OZNJP5t4Vj+beFY/PUBnPz1AZz89QGc/AMISP/6bQz/+m0M/7FZ1P9eGCT/4GRE/+BkRP/gZET/08A8/TNoOP4i2Uz9wfw0/pcEOP6XBDj8Mzlc/DM5XPwzOVz/5tfg++bX4Pvm1+D5iCVc/YglXP2IJVz9iCVc/YglXP2IJVz9iCVc/YglXP2IJVz9iCVc/71bWPlNPFj9TTxY/U08WPzKhZj8nBSA/JwUgP9OtGD/hxDY/4cQ2PyzFMD+m49Y+puPWPr3MOz+9zDs/vcw7P73MOz/IjCU/yIwlP8iMJT9bRV4/IoZRPyKGUT8ihlE/uq44P7auMj8URwI/FEcCP2xuRD9sbkQ/9IRRP/SEUT8IlQQ/CJUEPwiVBD8IlQQ/CJUEP788GD+/PBg/vzwYP788GD8sPyQ/LD8kPyw/JD8sPyQ/YqMlP2KjJT9ioyU/YqMlPwsRQD8LEUA/CxFAPwsRQD8LEUA/CxFAPwsRQD8LEUA/01T3PkRdHT9EXR0/RF0dP0RdHT9EXR0/jH8cP1fjZT9X42U/V+NlP1fjZT9nLi8/2aYSP9mmEj9m7DY/Zuw2P/HMZj/xzGY/8cxmP/HMZj/xzGY/AEMQPwBDED+LuSI/VtBkPx1iIT/GzTI/9NwkP/TcJD/03CQ/9NwkP/TcJD/viR4/74keP++JHj/9c0U//XNFPw/4ID/ckQc/3JEHP/F6Yj/xemI/8XpiP/F6Yj/xemI/FpdTPxaXUz8Wl1M/x0ggP8dIID/HSCA/x0ggPyveCD8r3gg/K94IPyveCD8n2h8/J9ofPyfaHz8n2h8/J9ofPyfaHz8n2h8/LwBiPy8AYj8vAGI/LwBiPy8AYj+V1DM/dFJEP3RSRD90UkQ/YJ8xP+krST/pK0k/6StJP+krST/pK0k/6StJP+krST/pK0k/6StJP+krST/pK0k/6StJPyzIbT9XlxA/zoPUPsQ2Fj9070s/dO9LP3TvSz/0rF4/9KxeP/SsXj/0rF4/Wm1BP1ptQT8ioDQ/IqA0PyKgND8ioDQ/hc5GP4XORj+FzkY/hc5GP4XORj+FzkY/hc5GP4XORj+FzkY/Dzk3PzpfMz86XzM/0yEaP9MhGj+o01A/qNNQP6jTUD/6Dhg/+g4YPxGLZj8Ri2Y/EYtmPxGLZj8Ri2Y/EYtmPwi5OD8IuTg/CLk4P31EHj99RB4/LFEXP1lsRT/p/xo/87tuP/O7bj8oeCc/KHgnP/gTWz/4E1s/oa89Pz3bPj892z4/Pds+Pwh2CD8E4NA+TTUoP001KD8Muz8/kltPP5JbTz+gF2Q/oBdkPwJanj6sqYE+BzTQPp4xKD8MOUo/DDlKPww5Sj8MOUo/WDHMPhgcZT8YHGU/GBxlPxgcZT/GqT4/xqk+P8apPj/GqT4/xqk+P8apPj/GqT4/xqk+P/p4WD/6eFg/+nhYP50FSj9Aewc/QHsHP21Lwj5ja9E+Y2vRPh0Yvz4yews/iGEqP8MHTj/DB04/wwdOPxdkFT+N1uw+ppjOPq6APz+ugD8/roA/P66APz+ugD8/roA/P66APz+aTyU/mk8lP5pPJT+aTyU/mk8lP5pPJT+4dhg/uHYYP8jfPD/I3zw/yN88P8jfPD/I3zw/yN88P8jfPD/I3zw/yN88P8jfPD/I3zw/g3xPP/DuQT/w7kE/o68iP6OvIj8tESA/LREgPy0RID91MBo/x2sfP04ETj9OBE4/TgROP/JgPD+RiyI/Pe8HP/ndLz/53S8/+d0vP/ndLz8eJ2s/HidrPwkjED8JIxA/CSMQP6QAIT+kACE/pAAhPxnMDj+lTw8/6fktP1XMGj8cxR8/HMUfPxzFHz+C3yY/gt8mP2AGIj+T8jI/MvqTPnABNT9wATU/unZhP7p2YT+6dmE/unZhP7p2YT+X6A8/l+gPP5KXAj+SlwI/mBMoP5gTKD+YEyg/UJsQP1CbED+r6kE/q+pBP4KKKD+Ciig/5FQ+P+UnNz/lJzc/5Sc3PwCwKj8AsCo/tpdaP6amFD+mphQ/pqYUP6amFD+mphQ/z34MP3u2Oz97tjs//2RJP7tnVz898FQ/PfBUP67GOD8Y5zg/GOc4PxjnOD8Y5zg/GOc4P46bQD+Om0A/YkS/Pu8XxD5Ize8+SM3vPi4NEz+MC/s+jAv7PowL+z6h+hk/ofoZP6H6GT83hE8/5w5AP+cOQD/nDkA/eK0XP3itFz94rRc/EppHPxKaRz8Smkc/EppHP/SXUT/0l1E/0YxBP9GMQT/RjEE/JEwxP/ebEz/3mxM/95sTPzwVSz88FUs/PBVLP5deNz9zhho/c4YaP3OGGj/WtzY/1rc2P2zBRj9swUY/qhlxP6oZcT+Z4yE/6n5LP+p+Sz/qfks/6n5LP+p+Sz/qfks/6n5LP2GpMD9hqTA/YakwP1uL+D4gr+k+ZUpSP2VKUj9qJf0+lWnhPtXBQj/VwUI/1cFCP9XBQj+7Jh0/UTh1P6r5ID+q+SA/07oWP2UFaT9lBWk/sLIwP46NED+OjRA/jo0QPzXHHT+P/x4/jX8yP41/Mj+NfzI/jX8yP499RD+PfUQ/j31EP499RD8Sb0M/Em9DPxJvQz8Sb0M/Em9DPzQTWD80E1g/ICRSPyAkUj8gJFI/ICRSP+9uTD8EzlA/BM5QPwTOUD/3IkI/9yJCP2X3RD9l90Q/ZfdEP96YGj/emBo/g8k2P4PJNj9GFDI/ZEkfP2RJHz9kSR8/g6RkP4OkZD+DpGQ/g6RkP4OkZD/enBk/3pwZPxZfAz8WXwM/Fl8DPxZfAz8WXwM/Fl8DPxZfAz99Fhk/fRYZP30WGT/H+Fg/x/hYP8f4WD/H+Fg/x/hYP9+QYz/fkGM/35BjP9+QYz/fkGM/35BjP63yOD8amiM/UkQ6P5iNCD/qP/c+jX7JPo1+yT6Nfsk+2hPYPtoT2D7SiAU/0ogFPwYfSz8GH0s/citaP3IrWj9yK1o/citaP3IrWj9yK1o/citaP5DhKz/32Do/99g6PyMlQT8jJUE/tABaP8DiFz9L3DU/S9w1P3P5KD9z+Sg/SO8eP73ZMz+92TM/vdkzPwGTND8BkzQ/kZoFP5GaBT+RmgU/kZoFP5GaBT+hMgg/aBggP9DjZj/oZzg/6Gc4P+hnOD/oZzg/8K5lP/CuZT/wrmU/8K5lP7OECT9Sp0g/qYZVP6mGVT+phlU/KLjuPii47j5PBi8/i0c0PxspHD8bKRw/FmwVP404QD+NOEA/jThAP404QD+NOEA/pMU1P6DEPD+62lU/1WosP9VqLD/Vaiw/vN5qP7zeaj+0M0g/tDNIP7QzSD8yfBo/MnwaPyIMDT8iDA0/ugXmProF5j66BeY+ugXmPj6c3z4350M/N+dDPzfnQz8350M/N+dDP62LMz+tizM/Yf9MP2H/TD9ptQ0/gYMCP4GDAj89fxM/PX8TPzhPVT84T1U/zOoaP8zqGj/WDTs/1g07P9YNOz/s21g/7NtYP+zbWD8gIGE/ICBhP0coNT9gPGA/YDxgP2A8YD9gPGA/F3cCP3kN9T494Cc/PckVPzPcPD+JDw4/NPcOPzT3Dj809w4/NPcOPzT3Dj+4+wI/FCjhPhQo4T5PNt0+h1bXPpQKvT45+Sk/ikMiP1FqOT9Rajk/UWo5P1FqOT9Rajk/UWo5P1FqOT9Rajk/UWo5P1FqOT9Rajk/hFhJPw==\",\"dtype\":\"float32\",\"order\":\"little\",\"shape\":[1000]}},\"selected\":{\"id\":\"1342\"},\"selection_policy\":{\"id\":\"1341\"}},\"id\":\"1075\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"overlay\":{\"id\":\"1250\"}},\"id\":\"1245\",\"type\":\"LassoSelectTool\"},{\"attributes\":{\"axis\":{\"id\":\"1051\"},\"coordinates\":null,\"dimension\":1,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1054\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"1247\",\"type\":\"SaveTool\"},{\"attributes\":{\"callback\":null},\"id\":\"1248\",\"type\":\"HoverTool\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1334\"},\"group\":null,\"major_label_policy\":{\"id\":\"1335\"},\"minor_tick_line_color\":null,\"ticker\":{\"id\":\"1052\"}},\"id\":\"1051\",\"type\":\"LinearAxis\"},{\"attributes\":{\"bottom\":-0.061980642139300234,\"coordinates\":null,\"fill_color\":\"gray\",\"group\":null,\"top\":0.061980642139300234},\"id\":\"1296\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"bottom_units\":\"screen\",\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"right_units\":\"screen\",\"syncable\":false,\"top_units\":\"screen\"},\"id\":\"1249\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"axis\":{\"id\":\"1267\"},\"coordinates\":null,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1270\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"1048\",\"type\":\"BasicTicker\"},{\"attributes\":{},\"id\":\"1272\",\"type\":\"BasicTicker\"},{\"attributes\":{\"data\":{\"x0\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"x1\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"y1\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[1000]}},\"selected\":{\"id\":\"1358\"},\"selection_policy\":{\"id\":\"1357\"}},\"id\":\"1297\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1388\"},\"group\":null,\"major_label_policy\":{\"id\":\"1389\"},\"minor_tick_line_color\":null,\"ticker\":{\"id\":\"1272\"}},\"id\":\"1271\",\"type\":\"LinearAxis\"},{\"attributes\":{\"line_color\":{\"value\":\"#2a2eec\"},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1298\",\"type\":\"Segment\"},{\"attributes\":{},\"id\":\"1268\",\"type\":\"BasicTicker\"},{\"attributes\":{},\"id\":\"1341\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"axis\":{\"id\":\"1047\"},\"coordinates\":null,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1050\",\"type\":\"Grid\"},{\"attributes\":{\"axis\":{\"id\":\"1271\"},\"coordinates\":null,\"dimension\":1,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1274\",\"type\":\"Grid\"},{\"attributes\":{\"below\":[{\"id\":\"1199\"}],\"center\":[{\"id\":\"1202\"},{\"id\":\"1206\"},{\"id\":\"1305\"}],\"height\":300,\"left\":[{\"id\":\"1203\"}],\"outline_line_color\":\"black\",\"output_backend\":\"webgl\",\"renderers\":[{\"id\":\"1310\"}],\"title\":{\"id\":\"1312\"},\"toolbar\":{\"id\":\"1217\"},\"toolbar_location\":null,\"width\":300,\"x_range\":{\"id\":\"1294\"},\"x_scale\":{\"id\":\"1195\"},\"y_range\":{\"id\":\"1295\"},\"y_scale\":{\"id\":\"1197\"}},\"id\":\"1192\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"data\":{\"draw\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"theta()\":{\"__ndarray__\":\"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\",\"dtype\":\"float32\",\"order\":\"little\",\"shape\":[1000]}},\"selected\":{\"id\":\"1346\"},\"selection_policy\":{\"id\":\"1345\"}},\"id\":\"1077\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1342\",\"type\":\"Selection\"},{\"attributes\":{\"tools\":[{\"id\":\"1275\"},{\"id\":\"1276\"},{\"id\":\"1277\"},{\"id\":\"1278\"},{\"id\":\"1279\"},{\"id\":\"1280\"},{\"id\":\"1281\"},{\"id\":\"1282\"}]},\"id\":\"1285\",\"type\":\"Toolbar\"},{\"attributes\":{},\"id\":\"1392\",\"type\":\"AllLabels\"},{\"attributes\":{\"bounds\":\"auto\",\"end\":1,\"min_interval\":0.1,\"start\":-1},\"id\":\"1295\",\"type\":\"DataRange1d\"},{\"attributes\":{},\"id\":\"1380\",\"type\":\"AllLabels\"},{\"attributes\":{},\"id\":\"1381\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1275\",\"type\":\"ResetTool\"},{\"attributes\":{\"data\":{\"draw\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"theta()\":{\"__ndarray__\":\"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\",\"dtype\":\"float32\",\"order\":\"little\",\"shape\":[1000]}},\"selected\":{\"id\":\"1344\"},\"selection_policy\":{\"id\":\"1343\"}},\"id\":\"1076\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1388\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1276\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"1379\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"overlay\":{\"id\":\"1283\"}},\"id\":\"1277\",\"type\":\"BoxZoomTool\"},{\"attributes\":{\"children\":[[{\"id\":\"1038\"},0,0],[{\"id\":\"1156\"},0,1],[{\"id\":\"1192\"},0,2],[{\"id\":\"1226\"},0,3],[{\"id\":\"1260\"},0,4]]},\"id\":\"1398\",\"type\":\"GridBox\"},{\"attributes\":{},\"id\":\"1280\",\"type\":\"UndoTool\"},{\"attributes\":{},\"id\":\"1382\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1278\",\"type\":\"WheelZoomTool\"},{\"attributes\":{},\"id\":\"1391\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"overlay\":{\"id\":\"1284\"}},\"id\":\"1279\",\"type\":\"LassoSelectTool\"},{\"attributes\":{},\"id\":\"1393\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"line_alpha\":{\"value\":0.1},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1299\",\"type\":\"Segment\"},{\"attributes\":{},\"id\":\"1389\",\"type\":\"AllLabels\"},{\"attributes\":{},\"id\":\"1281\",\"type\":\"SaveTool\"}],\"root_ids\":[\"1401\"]},\"title\":\"Bokeh Application\",\"version\":\"2.4.2\"}};\n", - " const render_items = [{\"docid\":\"4b864502-40f5-4e59-8146-2f4039ed6673\",\"root_ids\":[\"1401\"],\"roots\":{\"1401\":\"a6007911-5845-4220-9921-286d50db33c2\"}}];\n", + " const docs_json = {\"5db92c7d-eb7d-4718-86f6-617cb0457ec2\":{\"defs\":[],\"roots\":{\"references\":[{\"attributes\":{\"children\":[{\"id\":\"1400\"},{\"id\":\"1398\"}]},\"id\":\"1401\",\"type\":\"Column\"},{\"attributes\":{\"line_alpha\":0.6,\"line_color\":\"#2a2eec\",\"line_width\":2,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1079\",\"type\":\"Line\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1297\"},\"glyph\":{\"id\":\"1298\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1300\"},\"nonselection_glyph\":{\"id\":\"1299\"},\"view\":{\"id\":\"1302\"}},\"id\":\"1301\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"syncable\":false,\"xs_units\":\"screen\",\"ys_units\":\"screen\"},\"id\":\"1064\",\"type\":\"PolyAnnotation\"},{\"attributes\":{\"bottom_units\":\"screen\",\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"right_units\":\"screen\",\"syncable\":false,\"top_units\":\"screen\"},\"id\":\"1283\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"bottom_units\":\"screen\",\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"right_units\":\"screen\",\"syncable\":false,\"top_units\":\"screen\"},\"id\":\"1181\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"line_alpha\":{\"value\":0.1},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1299\",\"type\":\"Segment\"},{\"attributes\":{\"axis\":{\"id\":\"1199\"},\"coordinates\":null,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1202\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"1341\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"syncable\":false,\"xs_units\":\"screen\",\"ys_units\":\"screen\"},\"id\":\"1182\",\"type\":\"PolyAnnotation\"},{\"attributes\":{\"coordinates\":null,\"group\":null,\"text\":\"theta()\\nautocorrelation chain 0\"},\"id\":\"1303\",\"type\":\"Title\"},{\"attributes\":{\"bottom_units\":\"screen\",\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"right_units\":\"screen\",\"syncable\":false,\"top_units\":\"screen\"},\"id\":\"1063\",\"type\":\"BoxAnnotation\"},{\"attributes\":{},\"id\":\"1268\",\"type\":\"BasicTicker\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_width\":1.7857142857142858,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1080\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1342\",\"type\":\"Selection\"},{\"attributes\":{\"callback\":null},\"id\":\"1214\",\"type\":\"HoverTool\"},{\"attributes\":{\"line_alpha\":{\"value\":0.2},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1309\",\"type\":\"Segment\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.2},\"fill_color\":{\"value\":\"#1f77b4\"},\"hatch_alpha\":{\"value\":0.2},\"line_alpha\":{\"value\":0.2},\"line_color\":{\"value\":\"#1f77b4\"},\"line_dash\":{\"value\":\"solid\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1087\",\"type\":\"Circle\"},{\"attributes\":{\"line_alpha\":0.6,\"line_color\":\"#fa7c17\",\"line_dash\":[],\"line_width\":2,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1097\",\"type\":\"Line\"},{\"attributes\":{\"source\":{\"id\":\"1297\"}},\"id\":\"1302\",\"type\":\"CDSView\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1074\"},\"glyph\":{\"id\":\"1085\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1087\"},\"nonselection_glyph\":{\"id\":\"1086\"},\"view\":{\"id\":\"1089\"}},\"id\":\"1088\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1352\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"data\":{\"x0\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"x1\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"y1\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[1000]}},\"selected\":{\"id\":\"1358\"},\"selection_policy\":{\"id\":\"1357\"}},\"id\":\"1297\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"tools\":[{\"id\":\"1173\"},{\"id\":\"1174\"},{\"id\":\"1175\"},{\"id\":\"1176\"},{\"id\":\"1177\"},{\"id\":\"1178\"},{\"id\":\"1179\"},{\"id\":\"1180\"}]},\"id\":\"1183\",\"type\":\"Toolbar\"},{\"attributes\":{\"source\":{\"id\":\"1074\"}},\"id\":\"1083\",\"type\":\"CDSView\"},{\"attributes\":{\"line_alpha\":{\"value\":0.2},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1300\",\"type\":\"Segment\"},{\"attributes\":{},\"id\":\"1353\",\"type\":\"AllLabels\"},{\"attributes\":{\"data\":{\"draw\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"theta()\":{\"__ndarray__\":\"F+kqPw2kPT9q3jE/at4xP2reMT9q3jE/at4xP+XvWD/l71g/5e9YPyIwLz8iMC8/IjAvPyIwLz8iMC8/k05lP5NOZT9Tgzg/U4M4P1ODOD9B+V4/jkU8P4MCJT+pXUc/0QNSP9EDUj+vjFU/r4xVP0VaGz9FWhs/KzEbPysxGz8rMRs/KzEbPx0ZbT8dGW0/HRltP8h1LT/IdS0//Hk5P/x5OT9kKyw/ZCssP2QrLD9kKyw/ZCssPyqlPz8Fymk/GolBP9zicD9Qbho/UG4aP1BuGj9Sjlg/Uo5YPz3fNj893zY/UbkbP6azKT+msyk/GOApP1H4Nz/QVD8/0FQ/Pzlr6z7eLUA/3i1AP+FzNz+5SB0/E+9OP55URz+eVEc/nlRHP55URz+eVEc/nlRHP9b9Qz+EEms/hBJrP4QSaz/MYDc/rYJlP62CZT+tgmU/rYJlP62CZT+nEF4/j2kqP49pKj/Uzhk/1M4ZP9TOGT/Uzhk/1M4ZPwRTRz8EU0c/BFNHPwRTRz8EU0c/BFNHPwRTRz/4WlE/+FpRP8c7PD/HOzw/xzs8P8c7PD/HOzw/xzs8P+tGWD/rRlg/60ZYP8E0Jz/Smz0/0ps9P9KbPT/Smz0/0ps9P9KbPT/Smz0/3EY1P9xGNT/cRjU/SYFGP0mBRj9JgUY/qtkcP6rZHD+q2Rw/qtkcP2g9Mj+m7Aw/puwMP41NBz8hu08/IbtPP3aoMD92qDA/iwMXPxniJD8Z4iQ/GeIkPyS6XD8kulw/JLpcPyS6XD8kulw/JLpcPyS6XD8kulw/JLpcPyS6XD8kulw/JLpcPwiuGz+T1v4+k9b+PvDRID/w0SA/8NEgP3qPRD96j0Q/eo9EP3qPRD96j0Q/eo9EP3qPRD96j0Q/eo9EP3qPRD96j0Q/eo9EP5R+Mj+UfjI/lH4yP1FrQz9Ra0M/UWtDP1FrQz9Ra0M/UWtDP1FrQz9Ra0M/UWtDPymyFT/sSDA/7EgwP+xIMD8NoR4/c4/ePn4iPT9+Ij0/PHxVPzx8VT9Hs1U/+q1WP1oBRT9aAUU/WgFFP1oBRT+yxCY/OAVjP/jqNj/46jY/i0E1Pw3LZT9S6Dw/o/wcP6P8HD8iV2o/TZIeP842bD/ONmw/zjZsP842bD9yqyc/erVKP3q1Sj96tUo/erVKP3q1Sj96tUo/rzbvPpGPaD+Rj2g/zxsJP42HCz81cS0/NXEtP9jbYD/Y22A/HFQvPxxULz9+5CM/ZwbzPmcG8z6Sxu0+ksbtPi4sZj8uLGY/LixmPyBeMz8gXjM/zAUSP7JrMz+yazM/smszP7JrMz9tQDg/BSEdPyxOPT+Z5S8/meUvP5nlLz/R2Vg/0dlYP9HZWD/R2Vg/sHLxPki7bT9Iu20/eh0RP7Eh/D6xIfw+oNM9PzgLPD9/lRk/f5UZP3+VGT8+OC8/RlU7P0ZVOz9GVTs/RlU7P0ZVOz/IFSc/yBUnP8gVJz/pTk0/6U5NP+lOTT/pTk0/6U5NP+lOTT/pTk0/B/89Pwf/PT8H/z0/WZJuPz0j9j6wd+g+REU3P0RFNz9ERTc/REU3P/SCGj/0gho/9IIaP/yTZD/rmzA/65swP+ubMD9AESY/UJhSP1CYUj9QmFI/wz5dPxirYD8Yq2A/GKtgPyYY9j4mGPY+xHQYP+c+bD+pFQ4/22k9P9tpPT/baT0/22k9P9tpPT862QM/OtkDP1tVHz9bVR8/W1UfP1tVHz9bVR8/u+UYP7vlGD+75Rg/qRNFP6kTRT9bQ1M/W0NTPzU5Fz8b2Dc/G9g3Pwo5OT8KOTk/Cjk5Pwo5OT8KOTk/Cjk5Pwo5OT8KOTk/Cjk5Pwo5OT8KOTk/Cjk5Pwo5OT8KOTk/Cjk5Pwo5OT8KOTk/Cjk5Pwo5OT8KOTk/se8wP7HvMD+x7zA/se8wPy7UTj8u1E4/LtROPy7UTj9R7lM/Ue5TP1HuUz9R7lM/Ue5TP1HuUz9R7lM/Ue5TP1HuUz8Rr1k/5LI6P3ecVD93nFQ/d5xUP3ecVD93nFQ/d5xUP3ecVD93nFQ/d5xUP3ecVD93nFQ/d5xUP3ecVD86Ccw+OgnMPjoJzD6j0AY/o9AGP6PQBj+4mBk/uJgZPy4oJD8uKCQ/LigkPy4oJD8uKCQ/LigkP0I7Yj+H4z8/h+M/P4fjPz+NM8M+m8XdPgZ+Tz8Gfk8/Bn5PP4kQID/P7jA/z+4wPw06Uj8NOlI/DTpSPw06Uj8NOlI/DTpSPw06Uj8NOlI/V2hDP43dET+N3RE/jd0RP43dET+N3RE/jd0RP0zz9j7ET00/wIVzP8NbYz/DW2M/w1tjP8NbYz/DW2M/w1tjP8NbYz/DW2M/w1tjP8NbYz/DW2M/w1tjP5KRLz+SkS8/QlQ1P0JUNT8MC1E/DAtRPwwLUT8MC1E/DAtRPwwLUT/HRVQ/x0VUP8dFVD9b8DY/W/A2P1vwNj+CrFM/MhkxPzIZMT8yGTE/MhkxPzvvSj8770o/O+9KP2UtNT9DfDY/ItI5PyLSOT91tTc/b3MwP29zMD+bJyE/mychPwaJ5j4GieY+hhVEP4YVRD/7eDw/+ZsOPx7S/D4e0vw+h00bP4dNGz+HTRs/h00bP4dNGz+bpOM+06LVPtOi1T7TotU+sGWjPrBloz5K1xI/gWsJP4zZAj8eFTk/HhU5Px4VOT8eFTk/HhU5Px4VOT8eFTk/OKVfP3CDWD8puBw/KbgcPym4HD8puBw/KbgcPym4HD8puBw/KbgcP3eWDD93lgw/d5YMP3eWDD93lgw/d5YMPy3uVj/Bjws/wY8LP8GPCz9t7VA/be1QP23tUD9t7VA/s7AuPxOFUD8ThVA/DrcMP78z5j60pxE/tKcRP7SnET8HviU/2c0vP9nNLz/ZzS8/xkMBP8ZDAT/GQwE/BLs8PwS7PD8Euzw/jBMUP4wTFD/hyU0/4clNP+HJTT/hyU0/4zwwP+M8MD/jPDA/4zwwPztX2D4y1TQ/MtU0PzLVND8y1TQ/MtU0P/ZqNT/G1j4/xtY+P8bWPj/6niA/+p4gP/qeID/6niA/OBYkPzgWJD++/Q8/Ou1HPzrtRz867Uc/Ou1HP3kgOT95IDk/eSA5P3kgOT9Njx8/+2hHP7q3Qz+6t0M/urdDP7q3Qz+6t0M/0TrhPjBibD8wYmw/MXIBPzFyAT//LCk/QCv8PnlvZj95b2Y/eW9mP3lvZj+GDFw/pl8vP3kvMT95LzE/eS8xP8rlQz/K5UM/yuVDP8rlQz/K5UM/yuVDP411OT+NdTk/jXU5P411OT+NdTk/jXU5P411OT8HHGQ/BxxkPwccZD8HHGQ/QOUiP0DlIj9A5SI/QOUiP1arNj8u0Sc/LtEnP2xpJj9saSY/nbNfP52zXz+ds18/nbNfP52zXz+ds18/nbNfP52zXz+ds18/nbNfP05bND++DCc/vgwnP74MJz8EYyI/1gffPs8azj6p8wo/9us2P/brNj8He0w/B3tMPykoUj/gWQM/4FkDP+BZAz/gWQM/YNweP2DcHj9g3B4/YNweP2DcHj/sNWo/gsRYP4LEWD+CxFg/gsRYP4LEWD+CxFg/gsRYP4LEWD+CxFg/gsRYP4LEWD+CxFg/SlY6P41OLj+NTi4/jU4uP41OLj+NTi4/jU4uP41OLj+NTi4/S1dIP0tXSD9LV0g/S1dIP0tXSD9LV0g/S1dIP0tXSD9LV0g/S1dIP0tXSD9LV0g/S1dIP0tXSD9LV0g/S1dIP0tXSD9LV0g/S1dIP0tXSD+n4mA/KeEhPynhIT9kwFM/ZMBTP2TAUz8skko/LJJKPyySSj8skko/LJJKPyySSj8skko/LJJKP8fzaz8NlRg/DZUYPw2VGD8NlRg/DZUYP9yCBz9FD1w/RQ9cP0UPXD9FD1w/RQ9cP0E0Rj8i8gg/B6UFP6F2UD+hdlA/oXZQP6F2UD+hdlA/oXZQP6F2UD89I2Q/PSNkPz0jZD9g7Ek/YOxJP92DQT+nmEk/p5hJP6eYST+nmEk/p5hJP0qKTD9Kikw/s0QeP7NEHj+zRB4/+KUsP/ilLD/4pSw/+KUsP/ilLD/4pSw/+KUsP/ilLD/4pSw/+KUsP/ilLD/4pSw/SOwjP0jsIz8T9UY/E/VGP+L/QD/i/0A/1J1TP1bpNz9W6Tc/Vuk3P6iPID+ojyA/Xg0eP14NHj9eDR4/Xg0ePwqMST8KjEk/x3JLP8dySz/Hcks/7fEKP+3xCj/t8Qo/7fEKP+3xCj/t8Qo/M0wQP9qqIj/aqiI/2qoiP9qqIj/aqiI/hSHePoUh3j4Lg94+C4PePptc5j6bXOY+m1zmPqbXLD9ZiDw/WYg8P050Hz8ljRc/JY0XPznbJj+vmkk/w5cZP9sjIz/bIyM/2yMjP9c7Oz9vsFc/cdZhP3HWYT9x1mE/S6ZLPwB/Tj8Af04/6bJUP+myVD+o4RY/BII9PwSCPT8Egj0/BII9P0SdOD9EnTg/RJ04P0SdOD9EnTg/RJ04P/q/TT8W3fo+sdwiP6i3YT+ot2E/Lg0mP8wJXj8UPEU/FDxFPxQ8RT8UPEU/FDxFP2RdJj8//Bk/lfsiP/acND8zsyk/M7MpPzOzKT/2oUE/9qFBP/ahQT/2oUE/9qFBPz4WHT8+Fh0/71cvP+9XLz/vVy8/71cvP0a5ZT9tVGI/bVRiP5tBOz+bQTs/m0E7P5tBOz+6JBs/Wg0vP4YNTD+GDUw/hg1MP4h7Fj+IexY/iHsWP4h7Fj+IexY/iHsWP0h3Vz9Id1c/JE4dP1ppEj/bN0c/2zdHPwsvED/tHBU/JuUjP34nHD+z5hU/s+YVPyROBD8kTgQ/J2sqPydrKj+ObCs/jmwrP52JFj+diRY/nYkWP7PiGz+SWBc/V6dbP1enWz9Xp1s/V6dbPyRlST8kZUk/JGVJPyRlST9mdzY/Znc2P2Z3Nj9mdzY/RL4iP+0VFD/8MUs//DFLP/wxSz/8MUs/qbxFP30qGD99Khg/fSoYPwNCKz8DQis/A0IrP4QiZz+EImc/hCJnPywBVD8sAVQ/LAFUPywBVD8sAVQ/LAFUPywBVD8sAVQ/7AwsP+wMLD/sDCw/jWM+P41jPj+NYz4/jWM+P41jPj+NYz4/jWM+P41jPj9glCs/YJQrP2CUKz9WlVs/VpVbP1aVWz9WlVs//RxFP06dET9OnRE/vv0vP779Lz++/S8/k+xGP5PsRj+T7EY/LN0lPyzdJT8BtBM/AbQTP2RH8j5kR/I+ZEfyPhoyFD8QIxc/ECMXPxAjFz92HTg/dh04P3YdOD8XYCg/F2AoPxdgKD8XYCg//MpDP/zKQz/8ykM//MpDPw==\",\"dtype\":\"float32\",\"order\":\"little\",\"shape\":[1000]}},\"selected\":{\"id\":\"1346\"},\"selection_policy\":{\"id\":\"1345\"}},\"id\":\"1077\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1364\"},\"group\":null,\"major_label_policy\":{\"id\":\"1365\"},\"minor_tick_line_color\":null,\"ticker\":{\"id\":\"1204\"}},\"id\":\"1203\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"1355\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1367\"},\"group\":null,\"major_label_policy\":{\"id\":\"1368\"},\"ticker\":{\"id\":\"1200\"}},\"id\":\"1199\",\"type\":\"LinearAxis\"},{\"attributes\":{\"line_color\":{\"value\":\"#2a2eec\"},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1298\",\"type\":\"Segment\"},{\"attributes\":{},\"id\":\"1356\",\"type\":\"AllLabels\"},{\"attributes\":{\"tools\":[{\"id\":\"1055\"},{\"id\":\"1056\"},{\"id\":\"1057\"},{\"id\":\"1058\"},{\"id\":\"1059\"},{\"id\":\"1060\"},{\"id\":\"1061\"},{\"id\":\"1062\"}]},\"id\":\"1065\",\"type\":\"Toolbar\"},{\"attributes\":{\"bottom\":-0.061980642139300234,\"coordinates\":null,\"fill_color\":\"gray\",\"group\":null,\"top\":0.061980642139300234},\"id\":\"1314\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"axis\":{\"id\":\"1203\"},\"coordinates\":null,\"dimension\":1,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1206\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"1204\",\"type\":\"BasicTicker\"},{\"attributes\":{\"tools\":[{\"id\":\"1275\"},{\"id\":\"1276\"},{\"id\":\"1277\"},{\"id\":\"1278\"},{\"id\":\"1279\"},{\"id\":\"1280\"},{\"id\":\"1281\"},{\"id\":\"1282\"}]},\"id\":\"1285\",\"type\":\"Toolbar\"},{\"attributes\":{},\"id\":\"1229\",\"type\":\"LinearScale\"},{\"attributes\":{\"overlay\":{\"id\":\"1215\"}},\"id\":\"1209\",\"type\":\"BoxZoomTool\"},{\"attributes\":{},\"id\":\"1208\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"1207\",\"type\":\"ResetTool\"},{\"attributes\":{},\"id\":\"1213\",\"type\":\"SaveTool\"},{\"attributes\":{\"data\":{\"x0\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"x1\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"y1\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[1000]}},\"selected\":{\"id\":\"1370\"},\"selection_policy\":{\"id\":\"1369\"}},\"id\":\"1306\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1210\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"overlay\":{\"id\":\"1216\"}},\"id\":\"1211\",\"type\":\"LassoSelectTool\"},{\"attributes\":{\"bottom\":-0.061980642139300234,\"coordinates\":null,\"fill_color\":\"gray\",\"group\":null,\"top\":0.061980642139300234},\"id\":\"1305\",\"type\":\"BoxAnnotation\"},{\"attributes\":{},\"id\":\"1212\",\"type\":\"UndoTool\"},{\"attributes\":{},\"id\":\"1343\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"source\":{\"id\":\"1074\"}},\"id\":\"1089\",\"type\":\"CDSView\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1388\"},\"group\":null,\"major_label_policy\":{\"id\":\"1389\"},\"minor_tick_line_color\":null,\"ticker\":{\"id\":\"1272\"}},\"id\":\"1271\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"1369\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1388\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1344\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1246\",\"type\":\"UndoTool\"},{\"attributes\":{},\"id\":\"1043\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"1370\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1389\",\"type\":\"AllLabels\"},{\"attributes\":{},\"id\":\"1265\",\"type\":\"LinearScale\"},{\"attributes\":{\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"syncable\":false,\"xs_units\":\"screen\",\"ys_units\":\"screen\"},\"id\":\"1216\",\"type\":\"PolyAnnotation\"},{\"attributes\":{\"children\":[[{\"id\":\"1038\"},0,0],[{\"id\":\"1156\"},0,1],[{\"id\":\"1192\"},0,2],[{\"id\":\"1226\"},0,3],[{\"id\":\"1260\"},0,4]]},\"id\":\"1398\",\"type\":\"GridBox\"},{\"attributes\":{},\"id\":\"1391\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"line_color\":{\"value\":\"#328c06\"},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1316\",\"type\":\"Segment\"},{\"attributes\":{\"data\":{\"draw\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"theta()\":{\"__ndarray__\":\"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\",\"dtype\":\"float32\",\"order\":\"little\",\"shape\":[1000]}},\"selected\":{\"id\":\"1342\"},\"selection_policy\":{\"id\":\"1341\"}},\"id\":\"1075\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"data\":{\"x0\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"x1\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"y1\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[1000]}},\"selected\":{\"id\":\"1382\"},\"selection_policy\":{\"id\":\"1381\"}},\"id\":\"1315\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"overlay\":{\"id\":\"1250\"}},\"id\":\"1245\",\"type\":\"LassoSelectTool\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.6},\"fill_color\":{\"value\":\"#fa7c17\"},\"hatch_alpha\":{\"value\":0.5},\"line_alpha\":{\"value\":0.5},\"line_color\":{\"value\":\"#fa7c17\"},\"line_dash\":{\"value\":\"dotted\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1103\",\"type\":\"Circle\"},{\"attributes\":{\"source\":{\"id\":\"1315\"}},\"id\":\"1320\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1392\",\"type\":\"AllLabels\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1315\"},\"glyph\":{\"id\":\"1316\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1318\"},\"nonselection_glyph\":{\"id\":\"1317\"},\"view\":{\"id\":\"1320\"}},\"id\":\"1319\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"bottom_units\":\"screen\",\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"right_units\":\"screen\",\"syncable\":false,\"top_units\":\"screen\"},\"id\":\"1215\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"source\":{\"id\":\"1075\"}},\"id\":\"1101\",\"type\":\"CDSView\"},{\"attributes\":{\"line_alpha\":{\"value\":0.2},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1327\",\"type\":\"Segment\"},{\"attributes\":{},\"id\":\"1242\",\"type\":\"PanTool\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1075\"},\"glyph\":{\"id\":\"1097\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1099\"},\"nonselection_glyph\":{\"id\":\"1098\"},\"view\":{\"id\":\"1101\"}},\"id\":\"1100\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"bottom\":-0.061980642139300234,\"coordinates\":null,\"fill_color\":\"gray\",\"group\":null,\"top\":0.061980642139300234},\"id\":\"1323\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"hatch_alpha\":{\"value\":0.1},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"line_dash\":{\"value\":\"dashed\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1122\",\"type\":\"Circle\"},{\"attributes\":{\"line_color\":{\"value\":\"#c10c90\"},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1325\",\"type\":\"Segment\"},{\"attributes\":{\"data\":{\"x0\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"x1\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"y1\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[1000]}},\"selected\":{\"id\":\"1394\"},\"selection_policy\":{\"id\":\"1393\"}},\"id\":\"1324\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1075\"},\"glyph\":{\"id\":\"1103\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1105\"},\"nonselection_glyph\":{\"id\":\"1104\"},\"view\":{\"id\":\"1107\"}},\"id\":\"1106\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"line_alpha\":{\"value\":0.1},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1317\",\"type\":\"Segment\"},{\"attributes\":{\"coordinates\":null,\"group\":null,\"text\":\"theta()\\nautocorrelation chain 2\"},\"id\":\"1321\",\"type\":\"Title\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.2},\"fill_color\":{\"value\":\"#1f77b4\"},\"hatch_alpha\":{\"value\":0.2},\"line_alpha\":{\"value\":0.2},\"line_color\":{\"value\":\"#1f77b4\"},\"line_dash\":{\"value\":\"dotted\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1105\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"1244\",\"type\":\"WheelZoomTool\"},{\"attributes\":{},\"id\":\"1393\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"axis\":{\"id\":\"1237\"},\"coordinates\":null,\"dimension\":1,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1240\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"1263\",\"type\":\"LinearScale\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#1f77b4\",\"line_dash\":[2,4],\"line_width\":1.7857142857142858,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1099\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1238\",\"type\":\"BasicTicker\"},{\"attributes\":{\"line_alpha\":0.6,\"line_color\":\"#c10c90\",\"line_dash\":[],\"line_width\":2,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1133\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1394\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1247\",\"type\":\"SaveTool\"},{\"attributes\":{},\"id\":\"1364\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1241\",\"type\":\"ResetTool\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1076\"},\"glyph\":{\"id\":\"1121\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1123\"},\"nonselection_glyph\":{\"id\":\"1122\"},\"view\":{\"id\":\"1125\"}},\"id\":\"1124\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"hatch_alpha\":{\"value\":0.1},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"line_dash\":{\"value\":\"dotted\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1104\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"1345\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null},\"id\":\"1248\",\"type\":\"HoverTool\"},{\"attributes\":{},\"id\":\"1346\",\"type\":\"Selection\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.2},\"fill_color\":{\"value\":\"#1f77b4\"},\"hatch_alpha\":{\"value\":0.2},\"line_alpha\":{\"value\":0.2},\"line_color\":{\"value\":\"#1f77b4\"},\"line_dash\":{\"value\":\"dashed\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1123\",\"type\":\"Circle\"},{\"attributes\":{\"source\":{\"id\":\"1077\"}},\"id\":\"1143\",\"type\":\"CDSView\"},{\"attributes\":{\"source\":{\"id\":\"1306\"}},\"id\":\"1311\",\"type\":\"CDSView\"},{\"attributes\":{\"source\":{\"id\":\"1076\"}},\"id\":\"1125\",\"type\":\"CDSView\"},{\"attributes\":{\"line_alpha\":{\"value\":0.2},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1318\",\"type\":\"Segment\"},{\"attributes\":{\"overlay\":{\"id\":\"1249\"}},\"id\":\"1243\",\"type\":\"BoxZoomTool\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1306\"},\"glyph\":{\"id\":\"1307\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1309\"},\"nonselection_glyph\":{\"id\":\"1308\"},\"view\":{\"id\":\"1311\"}},\"id\":\"1310\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#1f77b4\",\"line_dash\":[6],\"line_width\":1.7857142857142858,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1117\",\"type\":\"Line\"},{\"attributes\":{\"tools\":[{\"id\":\"1207\"},{\"id\":\"1208\"},{\"id\":\"1209\"},{\"id\":\"1210\"},{\"id\":\"1211\"},{\"id\":\"1212\"},{\"id\":\"1213\"},{\"id\":\"1214\"}]},\"id\":\"1217\",\"type\":\"Toolbar\"},{\"attributes\":{\"coordinates\":null,\"group\":null,\"text\":\"theta() trace plot\"},\"id\":\"1153\",\"type\":\"Title\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1074\"},\"glyph\":{\"id\":\"1079\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1081\"},\"nonselection_glyph\":{\"id\":\"1080\"},\"view\":{\"id\":\"1083\"}},\"id\":\"1082\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"hatch_alpha\":{\"value\":0.1},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"line_dash\":{\"value\":\"solid\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1086\",\"type\":\"Circle\"},{\"attributes\":{\"source\":{\"id\":\"1076\"}},\"id\":\"1119\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1234\",\"type\":\"BasicTicker\"},{\"attributes\":{\"below\":[{\"id\":\"1047\"}],\"center\":[{\"id\":\"1050\"},{\"id\":\"1054\"}],\"height\":300,\"left\":[{\"id\":\"1051\"}],\"outline_line_color\":\"black\",\"output_backend\":\"webgl\",\"renderers\":[{\"id\":\"1082\"},{\"id\":\"1088\"},{\"id\":\"1100\"},{\"id\":\"1106\"},{\"id\":\"1118\"},{\"id\":\"1124\"},{\"id\":\"1136\"},{\"id\":\"1142\"}],\"title\":{\"id\":\"1153\"},\"toolbar\":{\"id\":\"1065\"},\"toolbar_location\":null,\"width\":300,\"x_range\":{\"id\":\"1039\"},\"x_scale\":{\"id\":\"1043\"},\"y_range\":{\"id\":\"1155\"},\"y_scale\":{\"id\":\"1045\"}},\"id\":\"1038\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"bottom_units\":\"screen\",\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"right_units\":\"screen\",\"syncable\":false,\"top_units\":\"screen\"},\"id\":\"1249\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"line_alpha\":{\"value\":0.1},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1308\",\"type\":\"Segment\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.6},\"fill_color\":{\"value\":\"#328c06\"},\"hatch_alpha\":{\"value\":0.5},\"line_alpha\":{\"value\":0.5},\"line_color\":{\"value\":\"#328c06\"},\"line_dash\":{\"value\":\"dashed\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1121\",\"type\":\"Circle\"},{\"attributes\":{\"source\":{\"id\":\"1324\"}},\"id\":\"1329\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1197\",\"type\":\"LinearScale\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1324\"},\"glyph\":{\"id\":\"1325\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1327\"},\"nonselection_glyph\":{\"id\":\"1326\"},\"view\":{\"id\":\"1329\"}},\"id\":\"1328\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.6},\"fill_color\":{\"value\":\"#2a2eec\"},\"hatch_alpha\":{\"value\":0.5},\"line_alpha\":{\"value\":0.5},\"line_color\":{\"value\":\"#2a2eec\"},\"line_dash\":{\"value\":\"solid\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1085\",\"type\":\"Circle\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1076\"},\"glyph\":{\"id\":\"1115\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1117\"},\"nonselection_glyph\":{\"id\":\"1116\"},\"view\":{\"id\":\"1119\"}},\"id\":\"1118\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"line_alpha\":{\"value\":0.1},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1326\",\"type\":\"Segment\"},{\"attributes\":{\"bounds\":\"auto\",\"min_interval\":0.1},\"id\":\"1155\",\"type\":\"DataRange1d\"},{\"attributes\":{\"coordinates\":null,\"group\":null,\"text\":\"theta()\\nautocorrelation chain 3\"},\"id\":\"1330\",\"type\":\"Title\"},{\"attributes\":{\"line_alpha\":0.6,\"line_color\":\"#328c06\",\"line_dash\":[],\"line_width\":2,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1115\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1200\",\"type\":\"BasicTicker\"},{\"attributes\":{\"source\":{\"id\":\"1075\"}},\"id\":\"1107\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1358\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1368\",\"type\":\"AllLabels\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_dash\":[6],\"line_width\":1.7857142857142858,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1116\",\"type\":\"Line\"},{\"attributes\":{\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"syncable\":false,\"xs_units\":\"screen\",\"ys_units\":\"screen\"},\"id\":\"1250\",\"type\":\"PolyAnnotation\"},{\"attributes\":{\"bottom\":-0.061980642139300234,\"coordinates\":null,\"fill_color\":\"gray\",\"group\":null,\"top\":0.061980642139300234},\"id\":\"1296\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_dash\":[6,4,2,4],\"line_width\":1.7857142857142858,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1134\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1278\",\"type\":\"WheelZoomTool\"},{\"attributes\":{},\"id\":\"1367\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1039\",\"type\":\"DataRange1d\"},{\"attributes\":{\"tools\":[{\"id\":\"1241\"},{\"id\":\"1242\"},{\"id\":\"1243\"},{\"id\":\"1244\"},{\"id\":\"1245\"},{\"id\":\"1246\"},{\"id\":\"1247\"},{\"id\":\"1248\"}]},\"id\":\"1251\",\"type\":\"Toolbar\"},{\"attributes\":{},\"id\":\"1376\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1281\",\"type\":\"SaveTool\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1077\"},\"glyph\":{\"id\":\"1133\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1135\"},\"nonselection_glyph\":{\"id\":\"1134\"},\"view\":{\"id\":\"1137\"}},\"id\":\"1136\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1377\",\"type\":\"AllLabels\"},{\"attributes\":{},\"id\":\"1280\",\"type\":\"UndoTool\"},{\"attributes\":{},\"id\":\"1334\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1379\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"coordinates\":null,\"group\":null,\"text\":\"theta()\\nautocorrelation chain 1\"},\"id\":\"1312\",\"type\":\"Title\"},{\"attributes\":{\"source\":{\"id\":\"1077\"}},\"id\":\"1137\",\"type\":\"CDSView\"},{\"attributes\":{\"overlay\":{\"id\":\"1284\"}},\"id\":\"1279\",\"type\":\"LassoSelectTool\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.6},\"fill_color\":{\"value\":\"#c10c90\"},\"hatch_alpha\":{\"value\":0.5},\"line_alpha\":{\"value\":0.5},\"line_color\":{\"value\":\"#c10c90\"},\"line_dash\":{\"value\":\"dashdot\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1139\",\"type\":\"Circle\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#1f77b4\",\"line_dash\":[6,4,2,4],\"line_width\":1.7857142857142858,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1135\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1335\",\"type\":\"AllLabels\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1334\"},\"group\":null,\"major_label_policy\":{\"id\":\"1335\"},\"minor_tick_line_color\":null,\"ticker\":{\"id\":\"1052\"}},\"id\":\"1051\",\"type\":\"LinearAxis\"},{\"attributes\":{\"below\":[{\"id\":\"1233\"}],\"center\":[{\"id\":\"1236\"},{\"id\":\"1240\"},{\"id\":\"1314\"}],\"height\":300,\"left\":[{\"id\":\"1237\"}],\"outline_line_color\":\"black\",\"output_backend\":\"webgl\",\"renderers\":[{\"id\":\"1319\"}],\"title\":{\"id\":\"1321\"},\"toolbar\":{\"id\":\"1251\"},\"toolbar_location\":null,\"width\":300,\"x_range\":{\"id\":\"1294\"},\"x_scale\":{\"id\":\"1229\"},\"y_range\":{\"id\":\"1295\"},\"y_scale\":{\"id\":\"1231\"}},\"id\":\"1226\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{},\"id\":\"1380\",\"type\":\"AllLabels\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1077\"},\"glyph\":{\"id\":\"1139\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1141\"},\"nonselection_glyph\":{\"id\":\"1140\"},\"view\":{\"id\":\"1143\"}},\"id\":\"1142\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1337\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1357\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"hatch_alpha\":{\"value\":0.1},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"line_dash\":{\"value\":\"dashdot\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1140\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"1338\",\"type\":\"AllLabels\"},{\"attributes\":{},\"id\":\"1365\",\"type\":\"AllLabels\"},{\"attributes\":{},\"id\":\"1275\",\"type\":\"ResetTool\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.2},\"fill_color\":{\"value\":\"#1f77b4\"},\"hatch_alpha\":{\"value\":0.2},\"line_alpha\":{\"value\":0.2},\"line_color\":{\"value\":\"#1f77b4\"},\"line_dash\":{\"value\":\"dashdot\"},\"radius\":{\"value\":0.3},\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1141\",\"type\":\"Circle\"},{\"attributes\":{\"axis\":{\"id\":\"1233\"},\"coordinates\":null,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1236\",\"type\":\"Grid\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1379\"},\"group\":null,\"major_label_policy\":{\"id\":\"1380\"},\"ticker\":{\"id\":\"1234\"}},\"id\":\"1233\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"1276\",\"type\":\"PanTool\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#1f77b4\",\"line_width\":1.7857142857142858,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1081\",\"type\":\"Line\"},{\"attributes\":{\"overlay\":{\"id\":\"1283\"}},\"id\":\"1277\",\"type\":\"BoxZoomTool\"},{\"attributes\":{},\"id\":\"1381\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"toolbar\":{\"id\":\"1399\"},\"toolbar_location\":\"above\"},\"id\":\"1400\",\"type\":\"ToolbarBox\"},{\"attributes\":{\"callback\":null},\"id\":\"1062\",\"type\":\"HoverTool\"},{\"attributes\":{\"toolbars\":[{\"id\":\"1065\"},{\"id\":\"1183\"},{\"id\":\"1217\"},{\"id\":\"1251\"},{\"id\":\"1285\"}],\"tools\":[{\"id\":\"1055\"},{\"id\":\"1056\"},{\"id\":\"1057\"},{\"id\":\"1058\"},{\"id\":\"1059\"},{\"id\":\"1060\"},{\"id\":\"1061\"},{\"id\":\"1062\"},{\"id\":\"1173\"},{\"id\":\"1174\"},{\"id\":\"1175\"},{\"id\":\"1176\"},{\"id\":\"1177\"},{\"id\":\"1178\"},{\"id\":\"1179\"},{\"id\":\"1180\"},{\"id\":\"1207\"},{\"id\":\"1208\"},{\"id\":\"1209\"},{\"id\":\"1210\"},{\"id\":\"1211\"},{\"id\":\"1212\"},{\"id\":\"1213\"},{\"id\":\"1214\"},{\"id\":\"1241\"},{\"id\":\"1242\"},{\"id\":\"1243\"},{\"id\":\"1244\"},{\"id\":\"1245\"},{\"id\":\"1246\"},{\"id\":\"1247\"},{\"id\":\"1248\"},{\"id\":\"1275\"},{\"id\":\"1276\"},{\"id\":\"1277\"},{\"id\":\"1278\"},{\"id\":\"1279\"},{\"id\":\"1280\"},{\"id\":\"1281\"},{\"id\":\"1282\"}]},\"id\":\"1399\",\"type\":\"ProxyToolbar\"},{\"attributes\":{\"below\":[{\"id\":\"1165\"}],\"center\":[{\"id\":\"1168\"},{\"id\":\"1172\"},{\"id\":\"1296\"}],\"height\":300,\"left\":[{\"id\":\"1169\"}],\"outline_line_color\":\"black\",\"output_backend\":\"webgl\",\"renderers\":[{\"id\":\"1301\"}],\"title\":{\"id\":\"1303\"},\"toolbar\":{\"id\":\"1183\"},\"toolbar_location\":null,\"width\":300,\"x_range\":{\"id\":\"1294\"},\"x_scale\":{\"id\":\"1161\"},\"y_range\":{\"id\":\"1295\"},\"y_scale\":{\"id\":\"1163\"}},\"id\":\"1156\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1337\"},\"group\":null,\"major_label_policy\":{\"id\":\"1338\"},\"ticker\":{\"id\":\"1048\"}},\"id\":\"1047\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"1272\",\"type\":\"BasicTicker\"},{\"attributes\":{},\"id\":\"1339\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1045\",\"type\":\"LinearScale\"},{\"attributes\":{\"axis\":{\"id\":\"1271\"},\"coordinates\":null,\"dimension\":1,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1274\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"1382\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1048\",\"type\":\"BasicTicker\"},{\"attributes\":{},\"id\":\"1340\",\"type\":\"Selection\"},{\"attributes\":{\"axis\":{\"id\":\"1047\"},\"coordinates\":null,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1050\",\"type\":\"Grid\"},{\"attributes\":{\"line_color\":{\"value\":\"#fa7c17\"},\"line_width\":{\"value\":2.5},\"x0\":{\"field\":\"x0\"},\"x1\":{\"field\":\"x1\"},\"y0\":{\"value\":0},\"y1\":{\"field\":\"y1\"}},\"id\":\"1307\",\"type\":\"Segment\"},{\"attributes\":{\"callback\":null},\"id\":\"1180\",\"type\":\"HoverTool\"},{\"attributes\":{\"callback\":null},\"id\":\"1282\",\"type\":\"HoverTool\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1352\"},\"group\":null,\"major_label_policy\":{\"id\":\"1353\"},\"minor_tick_line_color\":null,\"ticker\":{\"id\":\"1170\"}},\"id\":\"1169\",\"type\":\"LinearAxis\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_dash\":[2,4],\"line_width\":1.7857142857142858,\"x\":{\"field\":\"draw\"},\"y\":{\"field\":\"theta()\"}},\"id\":\"1098\",\"type\":\"Line\"},{\"attributes\":{\"axis\":{\"id\":\"1267\"},\"coordinates\":null,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1270\",\"type\":\"Grid\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1355\"},\"group\":null,\"major_label_policy\":{\"id\":\"1356\"},\"ticker\":{\"id\":\"1166\"}},\"id\":\"1165\",\"type\":\"LinearAxis\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1391\"},\"group\":null,\"major_label_policy\":{\"id\":\"1392\"},\"ticker\":{\"id\":\"1268\"}},\"id\":\"1267\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"1161\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"1163\",\"type\":\"LinearScale\"},{\"attributes\":{\"axis\":{\"id\":\"1051\"},\"coordinates\":null,\"dimension\":1,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1054\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"1166\",\"type\":\"BasicTicker\"},{\"attributes\":{},\"id\":\"1052\",\"type\":\"BasicTicker\"},{\"attributes\":{\"axis\":{\"id\":\"1165\"},\"coordinates\":null,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1168\",\"type\":\"Grid\"},{\"attributes\":{\"data\":{\"draw\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"theta()\":{\"__ndarray__\":\"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\",\"dtype\":\"float32\",\"order\":\"little\",\"shape\":[1000]}},\"selected\":{\"id\":\"1344\"},\"selection_policy\":{\"id\":\"1343\"}},\"id\":\"1076\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"overlay\":{\"id\":\"1063\"}},\"id\":\"1057\",\"type\":\"BoxZoomTool\"},{\"attributes\":{},\"id\":\"1056\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"1055\",\"type\":\"ResetTool\"},{\"attributes\":{\"axis\":{\"id\":\"1169\"},\"coordinates\":null,\"dimension\":1,\"grid_line_alpha\":0.2,\"grid_line_color\":\"gray\",\"grid_line_width\":0.3,\"group\":null,\"ticker\":null},\"id\":\"1172\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"1061\",\"type\":\"SaveTool\"},{\"attributes\":{},\"id\":\"1170\",\"type\":\"BasicTicker\"},{\"attributes\":{},\"id\":\"1058\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"below\":[{\"id\":\"1199\"}],\"center\":[{\"id\":\"1202\"},{\"id\":\"1206\"},{\"id\":\"1305\"}],\"height\":300,\"left\":[{\"id\":\"1203\"}],\"outline_line_color\":\"black\",\"output_backend\":\"webgl\",\"renderers\":[{\"id\":\"1310\"}],\"title\":{\"id\":\"1312\"},\"toolbar\":{\"id\":\"1217\"},\"toolbar_location\":null,\"width\":300,\"x_range\":{\"id\":\"1294\"},\"x_scale\":{\"id\":\"1195\"},\"y_range\":{\"id\":\"1295\"},\"y_scale\":{\"id\":\"1197\"}},\"id\":\"1192\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"below\":[{\"id\":\"1267\"}],\"center\":[{\"id\":\"1270\"},{\"id\":\"1274\"},{\"id\":\"1323\"}],\"height\":300,\"left\":[{\"id\":\"1271\"}],\"outline_line_color\":\"black\",\"output_backend\":\"webgl\",\"renderers\":[{\"id\":\"1328\"}],\"title\":{\"id\":\"1330\"},\"toolbar\":{\"id\":\"1285\"},\"toolbar_location\":null,\"width\":300,\"x_range\":{\"id\":\"1294\"},\"x_scale\":{\"id\":\"1263\"},\"y_range\":{\"id\":\"1295\"},\"y_scale\":{\"id\":\"1265\"}},\"id\":\"1260\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"overlay\":{\"id\":\"1064\"}},\"id\":\"1059\",\"type\":\"LassoSelectTool\"},{\"attributes\":{\"overlay\":{\"id\":\"1181\"}},\"id\":\"1175\",\"type\":\"BoxZoomTool\"},{\"attributes\":{},\"id\":\"1195\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"1060\",\"type\":\"UndoTool\"},{\"attributes\":{},\"id\":\"1174\",\"type\":\"PanTool\"},{\"attributes\":{\"coordinates\":null,\"formatter\":{\"id\":\"1376\"},\"group\":null,\"major_label_policy\":{\"id\":\"1377\"},\"minor_tick_line_color\":null,\"ticker\":{\"id\":\"1238\"}},\"id\":\"1237\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"1173\",\"type\":\"ResetTool\"},{\"attributes\":{\"data\":{\"draw\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999],\"theta()\":{\"__ndarray__\":\"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\",\"dtype\":\"float32\",\"order\":\"little\",\"shape\":[1000]}},\"selected\":{\"id\":\"1340\"},\"selection_policy\":{\"id\":\"1339\"}},\"id\":\"1074\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1179\",\"type\":\"SaveTool\"},{\"attributes\":{\"bounds\":[0,1000],\"end\":100,\"min_interval\":5,\"start\":0},\"id\":\"1294\",\"type\":\"DataRange1d\"},{\"attributes\":{},\"id\":\"1176\",\"type\":\"WheelZoomTool\"},{\"attributes\":{},\"id\":\"1231\",\"type\":\"LinearScale\"},{\"attributes\":{\"overlay\":{\"id\":\"1182\"}},\"id\":\"1177\",\"type\":\"LassoSelectTool\"},{\"attributes\":{\"bounds\":\"auto\",\"end\":1,\"min_interval\":0.1,\"start\":-1},\"id\":\"1295\",\"type\":\"DataRange1d\"},{\"attributes\":{},\"id\":\"1178\",\"type\":\"UndoTool\"},{\"attributes\":{\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"syncable\":false,\"xs_units\":\"screen\",\"ys_units\":\"screen\"},\"id\":\"1284\",\"type\":\"PolyAnnotation\"}],\"root_ids\":[\"1401\"]},\"title\":\"Bokeh Application\",\"version\":\"2.4.3\"}};\n", + " const render_items = [{\"docid\":\"5db92c7d-eb7d-4718-86f6-617cb0457ec2\",\"root_ids\":[\"1401\"],\"roots\":{\"1401\":\"1e8698f6-7761-440b-ad0b-540e276927d7\"}}];\n", " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", - "\n", " }\n", " if (root.Bokeh !== undefined) {\n", " embed_document(root);\n", @@ -1151,56 +1195,6 @@ "show(samples_diagnostic_plots)" ] }, - { - "cell_type": "markdown", - "metadata": { - "originalKey": "a41335ba-40bf-49fd-bdf6-5c2075c44b5e", - "showInput": false - }, - "source": [ - "The diagnostics output shows two diagnostic plots for individual random variables: trace\n", - "plots and autocorrelation plots.\n", - "\n", - "* Trace plots are simply a time series of values assigned to random variables over each\n", - " iteration of inference. The concrete values assigned are usually problem-specific.\n", - " However, it's important that these values are \"mixing\" well over time. This means that\n", - " they don't tend to get stuck in one region for large periods of time, and that each of\n", - " the chains ends up exploring the same space as the other chains throughout the course\n", - " of inference.\n", - "* Autocorrelation plots measure how predictive the last several samples are of the\n", - " current sample. Autocorrelation may vary between -1.0 (deterministically\n", - " anticorrelated) and 1.0 (deterministically correlated). (We compute autocorrelation\n", - " approximately, so it may sometimes exceed these bounds.) In an ideal world, the\n", - " current sample is chosen independently of the previous samples: an autocorrelation of\n", - " zero. This is not possible in practice, due to stochastic noise and the mechanics of\n", - " how inference works.\n", - "\n", - "From the trace plots, we see each of the chains are healthy: they don't get stuck, and\n", - "do not explore a chain-specific subset of the space. From the autocorrelation plots, we\n", - "see the absolute magnitude of autocorrelation to be very small, often around 0.1,\n", - "indicating a healthy exploration of the space." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## BMGInference" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Bean Machine Graph (BMG) Inference is an experimental feature of the Bean Machine\n", - "framework that aims to deliver higher performance for specialized models. The model used\n", - "in this tutorial represents a static probabilistic graph model and happens to use only\n", - "features within the language subset supported by `BMGInference`. Currently, however,\n", - "only Newtonian Monte Carlo (NMC) inference is supported by `BMGInference`. So, as a\n", - "reference point, the following code reports the time it takes for our basic\n", - "implementation of NMC to compute the posterior:" - ] - }, { "cell_type": "code", "execution_count": 18, @@ -1208,89 +1202,2452 @@ "outputs": [ { "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "078b5060c21c4eb7808209807a13fabc", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Samples collected: 0%| | 0/1000 [00:00\\n\"+\n", + " \"

\\n\"+\n", + " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", + " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", + " \"

\\n\"+\n", + " \"
    \\n\"+\n", + " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", + " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", + " \"
\\n\"+\n", + " \"\\n\"+\n", + " \"from bokeh.resources import INLINE\\n\"+\n", + " \"output_notebook(resources=INLINE)\\n\"+\n", + " \"\\n\"+\n", + " \"\"}};\n", + "\n", + " function display_loaded() {\n", + " const el = document.getElementById(null);\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS is loading...\";\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", + " }\n", + " } else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(display_loaded, 100)\n", + " }\n", + " }\n", + "\n", + " function run_callbacks() {\n", + " try {\n", + " root._bokeh_onload_callbacks.forEach(function(callback) {\n", + " if (callback != null)\n", + " callback();\n", + " });\n", + " } finally {\n", + " delete root._bokeh_onload_callbacks\n", + " }\n", + " console.debug(\"Bokeh: all callbacks have finished\");\n", + " }\n", + "\n", + " function load_libs(css_urls, js_urls, callback) {\n", + " if (css_urls == null) css_urls = [];\n", + " if (js_urls == null) js_urls = [];\n", + "\n", + " root._bokeh_onload_callbacks.push(callback);\n", + " if (root._bokeh_is_loading > 0) {\n", + " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", + " return null;\n", + " }\n", + " if (js_urls == null || js_urls.length === 0) {\n", + " run_callbacks();\n", + " return null;\n", + " }\n", + " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", + " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", + "\n", + " function on_load() {\n", + " root._bokeh_is_loading--;\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", + " run_callbacks()\n", + " }\n", + " }\n", + "\n", + " function on_error(url) {\n", + " console.error(\"failed to load \" + url);\n", + " }\n", + "\n", + " for (let i = 0; i < css_urls.length; i++) {\n", + " const url = css_urls[i];\n", + " const element = document.createElement(\"link\");\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.rel = \"stylesheet\";\n", + " element.type = \"text/css\";\n", + " element.href = url;\n", + " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " for (let i = 0; i < js_urls.length; i++) {\n", + " const url = js_urls[i];\n", + " const element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.async = false;\n", + " element.src = url;\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " };\n", + "\n", + " function inject_raw_css(css) {\n", + " const element = document.createElement(\"style\");\n", + " element.appendChild(document.createTextNode(css));\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\"];\n", + " const css_urls = [];\n", + "\n", + " const inline_js = [ function(Bokeh) {\n", + " Bokeh.set_log_level(\"info\");\n", + " },\n", + "function(Bokeh) {\n", + " }\n", + " ];\n", + "\n", + " function run_inline_js() {\n", + " if (root.Bokeh !== undefined || force === true) {\n", + " for (let i = 0; i < inline_js.length; i++) {\n", + " inline_js[i].call(root, root.Bokeh);\n", + " }\n", + "} else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(run_inline_js, 100);\n", + " } else if (!root._bokeh_failed_load) {\n", + " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", + " root._bokeh_failed_load = true;\n", + " } else if (force !== true) {\n", + " const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n", + " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", + " }\n", + " }\n", + "\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", + " run_inline_js();\n", + " } else {\n", + " load_libs(css_urls, js_urls, function() {\n", + " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", + " run_inline_js();\n", + " });\n", + " }\n", + "}(window));" + ], + "application/vnd.bokehjs_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n const el = document.getElementById(null);\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.bokehjs_exec.v0+json": "", + "text/html": [ + "" + ] + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "server_id": "a8e9950830714c049098f1056ace9fff" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "# Required for visualizing in Colab.\n", + "output_notebook(hide_banner=True)\n", + "\n", + "samples.diagnostics.autocorrelation()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function now() {\n", + " return new Date();\n", + " }\n", + "\n", + " const force = true;\n", + "\n", + " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", + " root._bokeh_onload_callbacks = [];\n", + " root._bokeh_is_loading = undefined;\n", + " }\n", + "\n", + "const JS_MIME_TYPE = 'application/javascript';\n", + " const HTML_MIME_TYPE = 'text/html';\n", + " const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", + " const CLASS_NAME = 'output_bokeh rendered_html';\n", + "\n", + " /**\n", + " * Render data to the DOM node\n", + " */\n", + " function render(props, node) {\n", + " const script = document.createElement(\"script\");\n", + " node.appendChild(script);\n", + " }\n", + "\n", + " /**\n", + " * Handle when an output is cleared or removed\n", + " */\n", + " function handleClearOutput(event, handle) {\n", + " const cell = handle.cell;\n", + "\n", + " const id = cell.output_area._bokeh_element_id;\n", + " const server_id = cell.output_area._bokeh_server_id;\n", + " // Clean up Bokeh references\n", + " if (id != null && id in Bokeh.index) {\n", + " Bokeh.index[id].model.document.clear();\n", + " delete Bokeh.index[id];\n", + " }\n", + "\n", + " if (server_id !== undefined) {\n", + " // Clean up Bokeh references\n", + " const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", + " cell.notebook.kernel.execute(cmd_clean, {\n", + " iopub: {\n", + " output: function(msg) {\n", + " const id = msg.content.text.trim();\n", + " if (id in Bokeh.index) {\n", + " Bokeh.index[id].model.document.clear();\n", + " delete Bokeh.index[id];\n", + " }\n", + " }\n", + " }\n", + " });\n", + " // Destroy server and session\n", + " const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", + " cell.notebook.kernel.execute(cmd_destroy);\n", + " }\n", + " }\n", + "\n", + " /**\n", + " * Handle when a new output is added\n", + " */\n", + " function handleAddOutput(event, handle) {\n", + " const output_area = handle.output_area;\n", + " const output = handle.output;\n", + "\n", + " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", + " if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n", + " return\n", + " }\n", + "\n", + " const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", + "\n", + " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", + " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", + " // store reference to embed id on output_area\n", + " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", + " }\n", + " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", + " const bk_div = document.createElement(\"div\");\n", + " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", + " const script_attrs = bk_div.children[0].attributes;\n", + " for (let i = 0; i < script_attrs.length; i++) {\n", + " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", + " toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n", + " }\n", + " // store reference to server id on output_area\n", + " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", + " }\n", + " }\n", + "\n", + " function register_renderer(events, OutputArea) {\n", + "\n", + " function append_mime(data, metadata, element) {\n", + " // create a DOM node to render to\n", + " const toinsert = this.create_output_subarea(\n", + " metadata,\n", + " CLASS_NAME,\n", + " EXEC_MIME_TYPE\n", + " );\n", + " this.keyboard_manager.register_events(toinsert);\n", + " // Render to node\n", + " const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", + " render(props, toinsert[toinsert.length - 1]);\n", + " element.append(toinsert);\n", + " return toinsert\n", + " }\n", + "\n", + " /* Handle when an output is cleared or removed */\n", + " events.on('clear_output.CodeCell', handleClearOutput);\n", + " events.on('delete.Cell', handleClearOutput);\n", + "\n", + " /* Handle when a new output is added */\n", + " events.on('output_added.OutputArea', handleAddOutput);\n", + "\n", + " /**\n", + " * Register the mime type and append_mime function with output_area\n", + " */\n", + " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", + " /* Is output safe? */\n", + " safe: true,\n", + " /* Index of renderer in `output_area.display_order` */\n", + " index: 0\n", + " });\n", + " }\n", + "\n", + " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", + " if (root.Jupyter !== undefined) {\n", + " const events = require('base/js/events');\n", + " const OutputArea = require('notebook/js/outputarea').OutputArea;\n", + "\n", + " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", + " register_renderer(events, OutputArea);\n", + " }\n", + " }\n", + " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_failed_load = false;\n", + " }\n", + "\n", + " const NB_LOAD_WARNING = {'data': {'text/html':\n", + " \"
\\n\"+\n", + " \"

\\n\"+\n", + " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", + " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", + " \"

\\n\"+\n", + " \"
    \\n\"+\n", + " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", + " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", + " \"
\\n\"+\n", + " \"\\n\"+\n", + " \"from bokeh.resources import INLINE\\n\"+\n", + " \"output_notebook(resources=INLINE)\\n\"+\n", + " \"\\n\"+\n", + " \"
\"}};\n", + "\n", + " function display_loaded() {\n", + " const el = document.getElementById(null);\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS is loading...\";\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", + " }\n", + " } else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(display_loaded, 100)\n", + " }\n", + " }\n", + "\n", + " function run_callbacks() {\n", + " try {\n", + " root._bokeh_onload_callbacks.forEach(function(callback) {\n", + " if (callback != null)\n", + " callback();\n", + " });\n", + " } finally {\n", + " delete root._bokeh_onload_callbacks\n", + " }\n", + " console.debug(\"Bokeh: all callbacks have finished\");\n", + " }\n", + "\n", + " function load_libs(css_urls, js_urls, callback) {\n", + " if (css_urls == null) css_urls = [];\n", + " if (js_urls == null) js_urls = [];\n", + "\n", + " root._bokeh_onload_callbacks.push(callback);\n", + " if (root._bokeh_is_loading > 0) {\n", + " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", + " return null;\n", + " }\n", + " if (js_urls == null || js_urls.length === 0) {\n", + " run_callbacks();\n", + " return null;\n", + " }\n", + " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", + " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", + "\n", + " function on_load() {\n", + " root._bokeh_is_loading--;\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", + " run_callbacks()\n", + " }\n", + " }\n", + "\n", + " function on_error(url) {\n", + " console.error(\"failed to load \" + url);\n", + " }\n", + "\n", + " for (let i = 0; i < css_urls.length; i++) {\n", + " const url = css_urls[i];\n", + " const element = document.createElement(\"link\");\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.rel = \"stylesheet\";\n", + " element.type = \"text/css\";\n", + " element.href = url;\n", + " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " for (let i = 0; i < js_urls.length; i++) {\n", + " const url = js_urls[i];\n", + " const element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.async = false;\n", + " element.src = url;\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " };\n", + "\n", + " function inject_raw_css(css) {\n", + " const element = document.createElement(\"style\");\n", + " element.appendChild(document.createTextNode(css));\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\"];\n", + " const css_urls = [];\n", + "\n", + " const inline_js = [ function(Bokeh) {\n", + " Bokeh.set_log_level(\"info\");\n", + " },\n", + "function(Bokeh) {\n", + " }\n", + " ];\n", + "\n", + " function run_inline_js() {\n", + " if (root.Bokeh !== undefined || force === true) {\n", + " for (let i = 0; i < inline_js.length; i++) {\n", + " inline_js[i].call(root, root.Bokeh);\n", + " }\n", + "} else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(run_inline_js, 100);\n", + " } else if (!root._bokeh_failed_load) {\n", + " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", + " root._bokeh_failed_load = true;\n", + " } else if (force !== true) {\n", + " const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n", + " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", + " }\n", + " }\n", + "\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", + " run_inline_js();\n", + " } else {\n", + " load_libs(css_urls, js_urls, function() {\n", + " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", + " run_inline_js();\n", + " });\n", + " }\n", + "}(window));" + ], + "application/vnd.bokehjs_load.v0+json": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n const el = document.getElementById(null);\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(null)).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.bokehjs_exec.v0+json": "", + "text/html": [ + "" + ] + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "server_id": "b1c55cada36847e693be50b5a60b8fc7" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "# Required for visualizing in Colab.\n", + "output_notebook(hide_banner=True)\n", + "\n", + "samples.diagnostics.trace()" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n", + "
\n", + "
arviz.InferenceData
\n", + "
\n", + "
    \n", + " \n", + "
  • \n", + " \n", + " \n", + "
    \n", + "
    \n", + "
      \n", + "
      \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
      <xarray.Dataset>\n",
      +       "Dimensions:  (chain: 4, draw: 1000)\n",
      +       "Coordinates:\n",
      +       "  * chain    (chain) int64 0 1 2 3\n",
      +       "  * draw     (draw) int64 0 1 2 3 4 5 6 7 8 ... 992 993 994 995 996 997 998 999\n",
      +       "Data variables:\n",
      +       "    theta()  (chain, draw) float32 0.771 0.771 0.771 ... 0.7648 0.7648 0.7648\n",
      +       "Attributes:\n",
      +       "    created_at:     2022-08-29T17:14:03.748882\n",
      +       "    arviz_version:  0.12.1

      \n", + "
    \n", + "
    \n", + "
  • \n", + " \n", + "
  • \n", + " \n", + " \n", + "
    \n", + "
    \n", + "
      \n", + "
      \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
      <xarray.Dataset>\n",
      +       "Dimensions:  (chain: 4, draw: 1000)\n",
      +       "Coordinates:\n",
      +       "  * chain    (chain) int64 0 1 2 3\n",
      +       "  * draw     (draw) int64 0 1 2 3 4 5 6 7 8 ... 992 993 994 995 996 997 998 999\n",
      +       "Data variables:\n",
      +       "    y(4,)    (chain, draw) float32 -0.26 -0.26 -0.26 ... -0.2681 -0.2681 -0.2681\n",
      +       "    y(2,)    (chain, draw) float32 -1.474 -1.474 -1.474 ... -1.447 -1.447 -1.447\n",
      +       "    y(8,)    (chain, draw) float32 -0.26 -0.26 -0.26 ... -0.2681 -0.2681 -0.2681\n",
      +       "    y(6,)    (chain, draw) float32 -0.26 -0.26 -0.26 ... -0.2681 -0.2681 -0.2681\n",
      +       "    y(3,)    (chain, draw) float32 -0.26 -0.26 -0.26 ... -0.2681 -0.2681 -0.2681\n",
      +       "    y(5,)    (chain, draw) float32 -0.26 -0.26 -0.26 ... -0.2681 -0.2681 -0.2681\n",
      +       "    y(1,)    (chain, draw) float32 -0.26 -0.26 -0.26 ... -0.2681 -0.2681 -0.2681\n",
      +       "    y(7,)    (chain, draw) float32 -0.26 -0.26 -0.26 ... -0.2681 -0.2681 -0.2681\n",
      +       "    y(9,)    (chain, draw) float32 -1.474 -1.474 -1.474 ... -1.447 -1.447 -1.447\n",
      +       "    y(0,)    (chain, draw) float32 -0.26 -0.26 -0.26 ... -0.2681 -0.2681 -0.2681\n",
      +       "Attributes:\n",
      +       "    created_at:     2022-08-29T17:14:03.751523\n",
      +       "    arviz_version:  0.12.1

      \n", + "
    \n", + "
    \n", + "
  • \n", + " \n", + "
  • \n", + " \n", + " \n", + "
    \n", + "
    \n", + "
      \n", + "
      \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
      <xarray.Dataset>\n",
      +       "Dimensions:      (y(0,)_dim_0: 1, y(1,)_dim_0: 1, y(2,)_dim_0: 1,\n",
      +       "                  y(3,)_dim_0: 1, y(4,)_dim_0: 1, y(5,)_dim_0: 1,\n",
      +       "                  y(6,)_dim_0: 1, y(7,)_dim_0: 1, y(8,)_dim_0: 1, y(9,)_dim_0: 1)\n",
      +       "Coordinates:\n",
      +       "  * y(0,)_dim_0  (y(0,)_dim_0) int64 0\n",
      +       "  * y(1,)_dim_0  (y(1,)_dim_0) int64 0\n",
      +       "  * y(2,)_dim_0  (y(2,)_dim_0) int64 0\n",
      +       "  * y(3,)_dim_0  (y(3,)_dim_0) int64 0\n",
      +       "  * y(4,)_dim_0  (y(4,)_dim_0) int64 0\n",
      +       "  * y(5,)_dim_0  (y(5,)_dim_0) int64 0\n",
      +       "  * y(6,)_dim_0  (y(6,)_dim_0) int64 0\n",
      +       "  * y(7,)_dim_0  (y(7,)_dim_0) int64 0\n",
      +       "  * y(8,)_dim_0  (y(8,)_dim_0) int64 0\n",
      +       "  * y(9,)_dim_0  (y(9,)_dim_0) int64 0\n",
      +       "Data variables:\n",
      +       "    y(0,)        (y(0,)_dim_0) float32 1.0\n",
      +       "    y(1,)        (y(1,)_dim_0) float32 1.0\n",
      +       "    y(2,)        (y(2,)_dim_0) float32 0.0\n",
      +       "    y(3,)        (y(3,)_dim_0) float32 1.0\n",
      +       "    y(4,)        (y(4,)_dim_0) float32 1.0\n",
      +       "    y(5,)        (y(5,)_dim_0) float32 1.0\n",
      +       "    y(6,)        (y(6,)_dim_0) float32 1.0\n",
      +       "    y(7,)        (y(7,)_dim_0) float32 1.0\n",
      +       "    y(8,)        (y(8,)_dim_0) float32 1.0\n",
      +       "    y(9,)        (y(9,)_dim_0) float32 0.0\n",
      +       "Attributes:\n",
      +       "    created_at:     2022-08-29T17:14:03.754606\n",
      +       "    arviz_version:  0.12.1

      \n", + "
    \n", + "
    \n", + "
  • \n", + " \n", + "
\n", + "
\n", + " " + ], + "text/plain": [ + "Inference data with groups:\n", + "\t> posterior\n", + "\t> log_likelihood\n", + "\t> observed_data" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "samples.diagnostics.display_idata()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "originalKey": "a41335ba-40bf-49fd-bdf6-5c2075c44b5e", + "showInput": false + }, + "source": [ + "The diagnostics output shows two diagnostic plots for individual random variables: trace\n", + "plots and autocorrelation plots.\n", + "\n", + "* Trace plots are simply a time series of values assigned to random variables over each\n", + " iteration of inference. The concrete values assigned are usually problem-specific.\n", + " However, it's important that these values are \"mixing\" well over time. This means that\n", + " they don't tend to get stuck in one region for large periods of time, and that each of\n", + " the chains ends up exploring the same space as the other chains throughout the course\n", + " of inference.\n", + "* Autocorrelation plots measure how predictive the last several samples are of the\n", + " current sample. Autocorrelation may vary between -1.0 (deterministically\n", + " anticorrelated) and 1.0 (deterministically correlated). (We compute autocorrelation\n", + " approximately, so it may sometimes exceed these bounds.) In an ideal world, the\n", + " current sample is chosen independently of the previous samples: an autocorrelation of\n", + " zero. This is not possible in practice, due to stochastic noise and the mechanics of\n", + " how inference works.\n", + "\n", + "From the trace plots, we see each of the chains are healthy: they don't get stuck, and\n", + "do not explore a chain-specific subset of the space. From the autocorrelation plots, we\n", + "see the absolute magnitude of autocorrelation to be very small, often around 0.1,\n", + "indicating a healthy exploration of the space." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## BMGInference" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Bean Machine Graph (BMG) Inference is an experimental feature of the Bean Machine\n", + "framework that aims to deliver higher performance for specialized models. The model used\n", + "in this tutorial represents a static probabilistic graph model and happens to use only\n", + "features within the language subset supported by `BMGInference`. Currently, however,\n", + "only Newtonian Monte Carlo (NMC) inference is supported by `BMGInference`. So, as a\n", + "reference point, the following code reports the time it takes for our basic\n", + "implementation of NMC to compute the posterior:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "application/json": { + "ascii": false, + "bar_format": null, + "colour": null, + "elapsed": 0.010705232620239258, + "initial": 0, + "n": 0, + "ncols": null, + "nrows": 1, + "postfix": null, + "prefix": "Samples collected", + "rate": null, + "total": 1000, + "unit": "it", + "unit_divisor": 1000, + "unit_scale": false + }, + "application/vnd.jupyter.widget-view+json": { + "model_id": "3224fd6fa65545c98c50d909acdfd033", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Samples collected: 0%| | 0/1000 [00:00 Date: Mon, 29 Aug 2022 16:16:00 -0500 Subject: [PATCH 2/7] Revert typing --- .../ppl/diagnostics/tools/accessor.py | 2 - .../ppl/diagnostics/tools/autocorrelation.py | 8 +- .../tools/effective_sample_size.py | 2 - .../tools/helpers/autocorrelation.py | 6 +- .../tools/helpers/effective_sample_size.py | 12 +-- .../diagnostics/tools/helpers/marginal1d.py | 22 ++-- .../diagnostics/tools/helpers/marginal2d.py | 20 ++-- .../ppl/diagnostics/tools/helpers/plotting.py | 10 +- .../ppl/diagnostics/tools/helpers/trace.py | 6 +- .../ppl/diagnostics/tools/marginal1d.py | 2 - .../ppl/diagnostics/tools/marginal2d.py | 2 - .../ppl/diagnostics/tools/trace.py | 4 +- .../tools/typing/autocorrelation.py | 40 ++++--- .../tools/typing/effective_sample_size.py | 32 +++--- .../diagnostics/tools/typing/marginal1d.py | 64 ++++++----- .../diagnostics/tools/typing/marginal2d.py | 72 ++++++------- .../ppl/diagnostics/tools/typing/trace.py | 102 +++++++++--------- 17 files changed, 189 insertions(+), 217 deletions(-) diff --git a/src/beanmachine/ppl/diagnostics/tools/accessor.py b/src/beanmachine/ppl/diagnostics/tools/accessor.py index 309140c692..0f2517582e 100644 --- a/src/beanmachine/ppl/diagnostics/tools/accessor.py +++ b/src/beanmachine/ppl/diagnostics/tools/accessor.py @@ -1,6 +1,4 @@ """Accessor definition for extending Bean Machine `MonteCarloSamples` objects.""" -from __future__ import annotations - import contextlib import warnings from typing import Callable, TypeVar diff --git a/src/beanmachine/ppl/diagnostics/tools/autocorrelation.py b/src/beanmachine/ppl/diagnostics/tools/autocorrelation.py index 62961cf77f..ab42908365 100644 --- a/src/beanmachine/ppl/diagnostics/tools/autocorrelation.py +++ b/src/beanmachine/ppl/diagnostics/tools/autocorrelation.py @@ -1,7 +1,5 @@ """Autocorrelation diagnostic tool for a Bean Machine model.""" -from __future__ import annotations - -from typing import Any, TypeVar +from typing import Any, Tuple, TypeVar import arviz as az @@ -67,8 +65,8 @@ def update_rv_select(attr: Any, old: str, new: str) -> None: def update_range_slider( attr: Any, - old: tuple[int, int], - new: tuple[int, int], + old: Tuple[int, int], + new: Tuple[int, int], ) -> None: fig = figures[list(figures.keys())[0]] fig.x_range.start, fig.x_range.end = new diff --git a/src/beanmachine/ppl/diagnostics/tools/effective_sample_size.py b/src/beanmachine/ppl/diagnostics/tools/effective_sample_size.py index 48f1a0bdf4..b608133d05 100644 --- a/src/beanmachine/ppl/diagnostics/tools/effective_sample_size.py +++ b/src/beanmachine/ppl/diagnostics/tools/effective_sample_size.py @@ -1,6 +1,4 @@ """Effective Sample Size (ESS) diagnostic tool for a Bean Machine model.""" -from __future__ import annotations - from typing import Any, TypeVar import arviz as az diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/autocorrelation.py b/src/beanmachine/ppl/diagnostics/tools/helpers/autocorrelation.py index 6dcdbc92b4..76c8de6a05 100644 --- a/src/beanmachine/ppl/diagnostics/tools/helpers/autocorrelation.py +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/autocorrelation.py @@ -1,5 +1,5 @@ """Methods used to generate the diagnostic tool.""" -from __future__ import annotations +from typing import List import arviz as az @@ -305,14 +305,14 @@ def add_tooltips(figures: typing.Figures, tooltips: typing.Tooltips) -> None: fig.add_tools(tooltips[figure_name]) -def create_widgets(rv_name: str, rv_names: list[str], num_draws: int) -> typing.Widgets: +def create_widgets(rv_name: str, rv_names: List[str], num_draws: int) -> typing.Widgets: """Create the widgets used in the tool. Parameters ---------- rv_name : str The string representation of the random variable data. - rv_names : list[str] + rv_names : List[str] A list of all available random variable names. num_draws : int The number of draws used in the model for a single chain. diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/effective_sample_size.py b/src/beanmachine/ppl/diagnostics/tools/helpers/effective_sample_size.py index ddf6416efa..4bace8cbe9 100644 --- a/src/beanmachine/ppl/diagnostics/tools/helpers/effective_sample_size.py +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/effective_sample_size.py @@ -1,7 +1,5 @@ """Methods used to generate the diagnostic tool.""" -from __future__ import annotations - -from numbers import Number +from typing import List import arviz as az @@ -32,7 +30,7 @@ def compute_data( data: npt.NDArray, - first_draw: Number = 0, + first_draw: float = 0.0, num_points: int = 20, ) -> typing.Data: """Compute effective sample size estimates using the given data. @@ -43,7 +41,7 @@ def compute_data( A 2D NumPy array where the length of the first dimension is the number of chains of the model, and the length of the second dimension is the number of draws of the model. - first_draw : Number, optional default is 0 + first_draw : float, optional default is 0 The first draw index. num_points : int, optional default is 20 The number of divisions in the model samples to compute the effective sample @@ -381,14 +379,14 @@ def add_tooltips(figures: typing.Figures, tooltips: typing.Tooltips) -> None: fig.add_tools(tips) -def create_widgets(rv_name: str, rv_names: list[str]) -> typing.Widgets: +def create_widgets(rv_name: str, rv_names: List[str]) -> typing.Widgets: """Create the widgets used in the tool. Parameters ---------- rv_name : str The string representation of the random variable data. - rv_names : list[str] + rv_names : List[str] A list of all available random variable names. Returns diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/marginal1d.py b/src/beanmachine/ppl/diagnostics/tools/helpers/marginal1d.py index c1184f7b9a..60062bde24 100644 --- a/src/beanmachine/ppl/diagnostics/tools/helpers/marginal1d.py +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/marginal1d.py @@ -1,7 +1,5 @@ """Methods used to generate the diagnostic tool.""" -from __future__ import annotations - -from typing import Optional +from typing import List, Optional import arviz as az @@ -36,9 +34,9 @@ def compute_stats( kde_x: npt.NDArray, kde_y: npt.NDArray, hdi_probability: float, - text_align: Optional[list[str]] = None, - x_offset: Optional[list[int]] = None, - y_offset: Optional[list[int]] = None, + text_align: Optional[List[str]] = None, + x_offset: Optional[List[int]] = None, + y_offset: Optional[List[int]] = None, return_labels: bool = False, ) -> typing.StatsAndLabelsData: """Compute statistics for the given data, and its KDE. @@ -55,11 +53,11 @@ def compute_stats( The y-axis KDE estimate of the random variable data. hdi_probability : float The HDI probability to use when calculating the HDI bounds. - text_align : list[str] | None, optional default is ``None`` + text_align : List[str] | None, optional default is ``None`` How to display label justifications for the statistics in Bokeh. - x_offset : list[int] | None, optional default is ``None`` + x_offset : List[int] | None, optional default is ``None`` x-axis offsets for the labels. - y_offset : list[int] | None, optional default is ``None`` + y_offset : List[int] | None, optional default is ``None`` y-axis offsets for the labels. return_labels : bool, optional default is ``False`` ``True`` returns labels to be used in the Bokeh figure. @@ -464,7 +462,7 @@ def add_tooltips(figures: typing.Figures, tooltips: typing.Tooltips) -> None: def create_widgets( rv_name: str, - rv_names: list[str], + rv_names: List[str], bw_factor: float, bandwidth: float, ) -> typing.Widgets: @@ -474,7 +472,7 @@ def create_widgets( ---------- rv_name : str The string representation of the random variable data. - rv_names : list[str] + rv_names : List[str] A list of all available random variable names. bw_factor : float Multiplicative factor used when calculating the kernel density estimate. @@ -611,7 +609,7 @@ def update( A dictionary of Bokeh Figure objects. rv_name : str The string representation of the random variable data. - rv_names : list[str] + rv_names : List[str] A list of all available random variable names. hdi_probability : float The HDI probability to use when calculating the HDI bounds. diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py b/src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py index 0866d2fd86..194deb423e 100644 --- a/src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py @@ -1,7 +1,5 @@ """Methods used to generate the diagnostic tool.""" -from __future__ import annotations - -from typing import Optional +from typing import List, Optional import arviz as az import beanmachine.ppl.diagnostics.tools.typing.marginal2d as typing @@ -44,8 +42,8 @@ def compute_xy_data( y: npt.NDArray, x_label: str, y_label: str, - x_stats: list[float], - y_stats: list[float], + x_stats: List[float], + y_stats: List[float], ) -> typing.XYData: """Compute the two-dimensional marginal. @@ -63,9 +61,9 @@ def compute_xy_data( The HDI probability to use when calculating the HDI bounds for the x-axis. y_hdi_probability : float The HDI probability to use when calculating the HDI bounds for the y-axis. - x_stats : list[float] + x_stats : List[float] Statistics for the x-axis; HDI bounds and the mean. - y_stats : list[float] + y_stats : List[float] Statistics for the y-axis; HDI bounds and the mean. Returns @@ -196,7 +194,7 @@ def compute_data( x_hdi_probability: float, y_hdi_probability: float, bw_factor: Optional[float] = None, - bins: Optional[list[int]] = None, + bins: Optional[List[int]] = None, ) -> typing.Data: """Compute effective sample size estimates using the given data. @@ -216,7 +214,7 @@ def compute_data( The HDI probability to use when calculating the HDI bounds for the y-axis. bw_factor : float, optional, default is 1.0 if None is given Multiplicative factor used when calculating the kernel density estimate. - bins : list[int], optional, default is [128, 128] if None is given + bins : List[int], optional, default is [128, 128] if None is given The grid points to use when calculating the two-dimensional KDE. Returns @@ -770,7 +768,7 @@ def add_tooltips(figures: typing.Figures, tooltips: typing.Tooltips) -> None: def create_widgets( x_rv_name: str, y_rv_name: str, - rv_names: list[str], + rv_names: List[str], bw_factor: float, x_bw: float, y_bw: float, @@ -783,7 +781,7 @@ def create_widgets( The name of the random variable along the x-axis. y_rv_name : str The name of the random variable along the y-axis. - rv_names : list[str] + rv_names : List[str] A list of all available random variable names. bw_factor : float Multiplicative factor used when calculating the kernel density estimate. diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/plotting.py b/src/beanmachine/ppl/diagnostics/tools/helpers/plotting.py index ab151a3ba3..99d47377fb 100644 --- a/src/beanmachine/ppl/diagnostics/tools/helpers/plotting.py +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/plotting.py @@ -1,5 +1,5 @@ """Plotting utilities for the diagnostics tools.""" -from __future__ import annotations +from typing import Dict, List from bokeh.core.property.nullable import Nullable from bokeh.core.property.primitive import Null @@ -51,7 +51,7 @@ def choose_palette(n: int) -> tuple: return Colorblind[palette_index] -def create_toolbar(figures: dict[str, Figure]) -> ToolbarBox: +def create_toolbar(figures: Dict[str, Figure]) -> ToolbarBox: """Create a single toolbar for multiple figures. This will also remove any ``HoverTool`` tools on the figures. These are removed from @@ -61,7 +61,7 @@ def create_toolbar(figures: dict[str, Figure]) -> ToolbarBox: Parameters ---------- - figures : dict[str, Figure] + figures : Dict[str, Figure] A dictionary of Bokeh figures. Returns @@ -90,7 +90,7 @@ def filter_renderers( search: str, glyph_type: str = "GlyphRenderer", substring: bool = False, -) -> list[GlyphRenderer]: +) -> List[GlyphRenderer]: """Filter Bokeh figure renderers given the search string. Parameters @@ -108,7 +108,7 @@ def filter_renderers( Returns ------- - list[GlyphRenderer] + List[GlyphRenderer] A list of Bokeh glyph renderer objects. """ output = [] diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/trace.py b/src/beanmachine/ppl/diagnostics/tools/helpers/trace.py index 95d8a975ea..59fc035bf9 100644 --- a/src/beanmachine/ppl/diagnostics/tools/helpers/trace.py +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/trace.py @@ -1,5 +1,5 @@ """Methods used to generate the diagnostic tool.""" -from __future__ import annotations +from typing import List import arviz as az import beanmachine.ppl.diagnostics.tools.typing.trace as typing @@ -647,14 +647,14 @@ def add_tooltips(figures: typing.Figures, tooltips: typing.Tooltips) -> None: fig.add_tools(tips) -def create_widgets(rv_name: str, rv_names: list[str]) -> typing.Widgets: +def create_widgets(rv_name: str, rv_names: List[str]) -> typing.Widgets: """Create the widgets used in the tool. Parameters ---------- rv_name : str The string representation of the random variable data. - rv_names : list[str] + rv_names : List[str] A list of all available random variable names. Returns diff --git a/src/beanmachine/ppl/diagnostics/tools/marginal1d.py b/src/beanmachine/ppl/diagnostics/tools/marginal1d.py index 12e38865bb..0b5acd4528 100644 --- a/src/beanmachine/ppl/diagnostics/tools/marginal1d.py +++ b/src/beanmachine/ppl/diagnostics/tools/marginal1d.py @@ -1,6 +1,4 @@ """Marginal 1D diagnostic tool for a Bean Machine model.""" -from __future__ import annotations - from typing import Any, TypeVar import arviz as az diff --git a/src/beanmachine/ppl/diagnostics/tools/marginal2d.py b/src/beanmachine/ppl/diagnostics/tools/marginal2d.py index 0b623c3253..74ea84d73a 100644 --- a/src/beanmachine/ppl/diagnostics/tools/marginal2d.py +++ b/src/beanmachine/ppl/diagnostics/tools/marginal2d.py @@ -1,6 +1,4 @@ """Marginal 2D diagnostic tool for a Bean Machine model.""" -from __future__ import annotations - from typing import Any, TypeVar import arviz as az diff --git a/src/beanmachine/ppl/diagnostics/tools/trace.py b/src/beanmachine/ppl/diagnostics/tools/trace.py index 84099cbd43..b0821b7bf3 100644 --- a/src/beanmachine/ppl/diagnostics/tools/trace.py +++ b/src/beanmachine/ppl/diagnostics/tools/trace.py @@ -1,6 +1,4 @@ """Trace diagnostic tool for a Bean Machine model.""" -from __future__ import annotations - from typing import Any, TypeVar import arviz as az @@ -34,7 +32,7 @@ def modify_doc(self: T, doc: Any) -> None: # Compute the initial data displayed in the tool. rv_data = self.idata["posterior"][rv_identifier].values - num_chains, num_draws = rv_data.shape + num_chains, _ = rv_data.shape computed_data = tool.compute_data( data=rv_data, bw_factor=bw_factor, diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/autocorrelation.py b/src/beanmachine/ppl/diagnostics/tools/typing/autocorrelation.py index 1f23508362..968bf5adde 100644 --- a/src/beanmachine/ppl/diagnostics/tools/typing/autocorrelation.py +++ b/src/beanmachine/ppl/diagnostics/tools/typing/autocorrelation.py @@ -1,7 +1,5 @@ """Autocorrelation diagnostic tool types for a Bean Machine model.""" -from __future__ import annotations - -from typing import Any, TypedDict +from typing import Any, Dict, List, TypedDict from bokeh.models.annotations import BoxAnnotation from bokeh.models.glyphs import Quad @@ -12,17 +10,17 @@ from bokeh.plotting.figure import Figure -Figure_names = None | list[str] +Figure_names = None | List[str] # NOTE: These are the types pyre gives us when using `reveal_type(...)` on the outputs # of the methods. -Data = dict[Any, Any] -Sources = dict[Any, Any] -Figures = dict[Any, Any] -Glyphs = dict[Any, Any] -Annotations = dict[Any, Any] -Tooltips = dict[Any, Any] -Widgets = dict[str, RangeSlider | Select] +Data = Dict[Any, Any] +Sources = Dict[Any, Any] +Figures = Dict[Any, Any] +Glyphs = Dict[Any, Any] +Annotations = Dict[Any, Any] +Tooltips = Dict[Any, Any] +Widgets = Dict[str, RangeSlider | Select] # NOTE: TypedDict objects are for reference only. Due to the way pyre accesses keys in # dictionaries, and how NumPy casts arrays when using tolist(), we are unable to @@ -30,10 +28,10 @@ class _QuadData(TypedDict): - left: list[float] - top: list[float] - right: list[float] - bottom: list[float] + left: List[float] + top: List[float] + right: List[float] + bottom: List[float] class _BoxData(TypedDict): @@ -70,9 +68,9 @@ class _Widgets(TypedDict): # NOTE: We do not have a priori information about the number of chains in the output # data. This is why we are not creating a TypedDict object for the Data type with # named keys like chain1, chain2, etc.. -_Data = dict[str, _FigureData] -_Sources = dict[str, _FigureSources] -_Figures = dict[str, Figure] -_Glyphs = dict[str, _FigureGlyphs] -_Annotations = dict[str, _FigureAnnotations] -_Tooltips = dict[str, _FigureTooltips] +_Data = Dict[str, _FigureData] +_Sources = Dict[str, _FigureSources] +_Figures = Dict[str, Figure] +_Glyphs = Dict[str, _FigureGlyphs] +_Annotations = Dict[str, _FigureAnnotations] +_Tooltips = Dict[str, _FigureTooltips] diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/effective_sample_size.py b/src/beanmachine/ppl/diagnostics/tools/typing/effective_sample_size.py index e5f902098c..bf0dcd6bd5 100644 --- a/src/beanmachine/ppl/diagnostics/tools/typing/effective_sample_size.py +++ b/src/beanmachine/ppl/diagnostics/tools/typing/effective_sample_size.py @@ -1,7 +1,5 @@ """Effective Sample Size diagnostic tool types for a Bean Machine model.""" -from __future__ import annotations - -from typing import Any, TypedDict +from typing import Any, Dict, List, TypedDict from bokeh.models.annotations import Legend from bokeh.models.glyphs import Circle, Line @@ -13,13 +11,13 @@ # NOTE: These are the types pyre gives us when using `reveal_type(...)` on the outputs # of the methods. -Data = dict[str, dict[str, dict[str, Any]]] -Sources = dict[str, dict[str, dict[str, ColumnDataSource]]] -Figures = dict[str, Figure] -Glyphs = dict[str, dict[Any, Any]] -Annotations = dict[Any, Any] -Tooltips = dict[str, dict[Any, Any]] -Widgets = dict[str, Select] +Data = Dict[str, Dict[str, Dict[str, Any]]] +Sources = Dict[str, Dict[str, Dict[str, ColumnDataSource]]] +Figures = Dict[str, Figure] +Glyphs = Dict[str, Dict[Any, Any]] +Annotations = Dict[Any, Any] +Tooltips = Dict[str, Dict[Any, Any]] +Widgets = Dict[str, Select] # NOTE: TypedDict objects are for reference only. Due to the way pyre accesses keys in # dictionaries, and how NumPy casts arrays when using tolist(), we are unable to @@ -27,19 +25,19 @@ class _BulkData(TypedDict): - x: list[float] - y: list[float] + x: List[float] + y: List[float] class _TailData(TypedDict): - x: list[float] - y: list[float] + x: List[float] + y: List[float] class _RuleOfThumbData(TypedDict): - x: list[float] - y: list[float] - label: list[str] + x: List[float] + y: List[float] + label: List[str] class _GlyphData(TypedDict): diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/marginal1d.py b/src/beanmachine/ppl/diagnostics/tools/typing/marginal1d.py index 372350de31..70ffb364d0 100644 --- a/src/beanmachine/ppl/diagnostics/tools/typing/marginal1d.py +++ b/src/beanmachine/ppl/diagnostics/tools/typing/marginal1d.py @@ -1,7 +1,5 @@ """Marginal 1D diagnostic tool types for a Bean Machine model.""" -from __future__ import annotations - -from typing import Any, TypedDict +from typing import Any, Dict, List, TypedDict from bokeh.models.annotations import Band, LabelSet from bokeh.models.glyphs import Circle, Line @@ -15,15 +13,15 @@ # NOTE: These are the types pyre gives us when using `reveal_type(...)` on the outputs # of the methods. -StatsAndLabelsData = dict[str, dict[str, Any]] -HDIData = dict[str, Any] -Data = dict[Any, Any] -Sources = dict[Any, Any] -Figures = dict[Any, Any] -Glyphs = dict[Any, Any] -Annotations = dict[Any, Any] -Tooltips = dict[Any, Any] -Widgets = dict[str, Div | Select | Slider] +StatsAndLabelsData = Dict[str, Dict[str, Any]] +HDIData = Dict[str, Any] +Data = Dict[Any, Any] +Sources = Dict[Any, Any] +Figures = Dict[Any, Any] +Glyphs = Dict[Any, Any] +Annotations = Dict[Any, Any] +Tooltips = Dict[Any, Any] +Widgets = Dict[str, Div | Select | Slider] # NOTE: TypedDict objects are for reference only. Due to the way pyre accesses keys in # dictionaries, and how NumPy casts arrays when using tolist(), we are unable to @@ -31,39 +29,39 @@ class _DistributionData(TypedDict): - x: list[float] - y: list[float] - bandwidth: list[float] + x: List[float] + y: List[float] + bandwidth: List[float] class _HDIData(TypedDict): - base: list[float] - lower: list[float] - upper: list[float] + base: List[float] + lower: List[float] + upper: List[float] class _StatsData(TypedDict): - x: list[float] - y: list[float] - text: list[str] + x: List[float] + y: List[float] + text: List[str] class _LabelsData(TypedDict): - x: list[float] - y: list[float] - text: list[str] - text_align: list[str] - x_offset: list[int] - y_offset: list[int] + x: List[float] + y: List[float] + text: List[str] + text_align: List[str] + x_offset: List[int] + y_offset: List[int] class _StatsAndLabelsData(TypedDict): - x: list[float] - y: list[float] - text: list[str] - text_align: list[str] - x_offset: list[int] - y_offset: list[int] + x: List[float] + y: List[float] + text: List[str] + text_align: List[str] + x_offset: List[int] + y_offset: List[int] class _GlyphData(TypedDict): diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/marginal2d.py b/src/beanmachine/ppl/diagnostics/tools/typing/marginal2d.py index 19e341dd55..a3a9a83463 100644 --- a/src/beanmachine/ppl/diagnostics/tools/typing/marginal2d.py +++ b/src/beanmachine/ppl/diagnostics/tools/typing/marginal2d.py @@ -1,7 +1,5 @@ """Marginal 2D diagnostic tool types for a Bean Machine model.""" -from __future__ import annotations - -from typing import Any, TypedDict +from typing import Any, Dict, List, TypedDict from beanmachine.ppl.diagnostics.tools.typing import marginal1d as m1d @@ -17,18 +15,18 @@ # NOTE: These are the types pyre gives us when using `reveal_type(...)` on the outputs # of the methods. -XYData = dict[ +XYData = Dict[ str, - dict[str, dict[str, dict[str, Any]]] | dict[str, list[Any]], + Dict[str, Dict[str, Dict[str, Any]]] | Dict[str, List[Any]], ] -YData = dict[str, dict[str, Any]] -Data = dict[str, Any] -Sources = dict[Any, Any] -Figures = dict[Any, Any] -Glyphs = dict[Any, Any] -Annotations = dict[str, dict[str, Band] | Band] -Tooltips = dict[Any, Any] -Widgets = dict[str, Div | Select | Slider] +YData = Dict[str, Dict[str, Any]] +Data = Dict[str, Any] +Sources = Dict[Any, Any] +Figures = Dict[Any, Any] +Glyphs = Dict[Any, Any] +Annotations = Dict[str, Dict[str, Band] | Band] +Tooltips = Dict[Any, Any] +Widgets = Dict[str, Div | Select | Slider] # NOTE: TypedDict objects are for reference only. Due to the way pyre accesses keys in # dictionaries, and how NumPy casts arrays when using tolist(), we are unable to @@ -36,24 +34,24 @@ class _DistributionData(TypedDict): - x: list[float] - y: list[float] - bandwidth: list[float] + x: List[float] + y: List[float] + bandwidth: List[float] class _StatsData(TypedDict): - x: list[float] - y: list[float] - text: list[str] + x: List[float] + y: List[float] + text: List[str] class _LabelsData(TypedDict): - x: list[float] - y: list[float] - text: list[str] - text_align: list[str] - x_offset: list[int] - y_offset: list[int] + x: List[float] + y: List[float] + text: List[str] + text_align: List[str] + x_offset: List[int] + y_offset: List[int] class _XData(TypedDict): @@ -76,18 +74,18 @@ class _YData(TypedDict): class _XYDistributionData(TypedDict): - image: list[list[float]] - xmin: list[float] - xmax: list[float] - ymin: list[float] - ymax: list[float] - dw: list[float] - dh: list[float] + image: List[List[float]] + xmin: List[float] + xmax: List[float] + ymin: List[float] + ymax: List[float] + dw: List[float] + dh: List[float] class _XYHDIDatum(TypedDict): - x: list[float] - y: list[float] + x: List[float] + y: List[float] class _XYHDIDataLowerUpper(TypedDict): @@ -101,12 +99,12 @@ class _XYHDIData(TypedDict): class _XYStatsData(TypedDict): - x: list[float] - y: list[float] + x: List[float] + y: List[float] class _XYLabelsData(TypedDict): - mean: list[str] + mean: List[str] class _XYData(TypedDict): diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/trace.py b/src/beanmachine/ppl/diagnostics/tools/typing/trace.py index 9a6318b6d9..a81a6db5e3 100644 --- a/src/beanmachine/ppl/diagnostics/tools/typing/trace.py +++ b/src/beanmachine/ppl/diagnostics/tools/typing/trace.py @@ -1,7 +1,5 @@ """Marginal 2D diagnostic tool types for a Bean Machine model.""" -from __future__ import annotations - -from typing import Any, TypedDict +from typing import Any, Dict, List, TypedDict from beanmachine.ppl.diagnostics.tools.typing import marginal1d as m1d @@ -15,13 +13,13 @@ # NOTE: These are the types pyre gives us when using `reveal_type(...)` on the outputs # of the methods. -Data = dict[Any, Any] -Sources = dict[Any, Any] -Figures = dict[Any, Any] -Glyphs = dict[Any, Any] -Annotations = dict[str, dict[str, Legend]] -Tooltips = dict[Any, Any] -Widgets = dict[str, Select | Slider] +Data = Dict[Any, Any] +Sources = Dict[Any, Any] +Figures = Dict[Any, Any] +Glyphs = Dict[Any, Any] +Annotations = Dict[str, Dict[str, Legend]] +Tooltips = Dict[Any, Any] +Widgets = Dict[str, Select | Slider] # NOTE: TypedDict objects are for reference only. Due to the way pyre accesses keys in # dictionaries, and how NumPy casts arrays when using tolist(), we are unable to @@ -29,24 +27,24 @@ class _DistributionData(TypedDict): - x: list[float] - y: list[float] - bandwidth: list[float] + x: List[float] + y: List[float] + bandwidth: List[float] class _StatsData(TypedDict): - x: list[float] - y: list[float] - text: list[str] + x: List[float] + y: List[float] + text: List[str] class _LabelsData(TypedDict): - x: list[float] - y: list[float] - text: list[str] - text_align: list[str] - x_offset: list[int] - y_offset: list[int] + x: List[float] + y: List[float] + text: List[str] + text_align: List[str] + x_offset: List[int] + y_offset: List[int] class _MarginalDataSingleChain(TypedDict): @@ -57,13 +55,13 @@ class _MarginalDataSingleChain(TypedDict): class _ForestLineData(TypedDict): - x: list[float] - y: list[float] + x: List[float] + y: List[float] class _ForestCircleData(TypedDict): - x: list[float] - y: list[float] + x: List[float] + y: List[float] class _ForestDataSingleChain(TypedDict): @@ -74,8 +72,8 @@ class _ForestDataSingleChain(TypedDict): class _TraceLineData(TypedDict): - x: list[float] - y: list[float] + x: List[float] + y: List[float] class _TraceDataSingleChain(TypedDict): @@ -85,17 +83,17 @@ class _TraceDataSingleChain(TypedDict): class _RankQuadData(TypedDict): - left: list[float] - top: list[float] - right: list[float] - bottom: list[float] - draws: list[str] - rank: list[float] + left: List[float] + top: List[float] + right: List[float] + bottom: List[float] + draws: List[str] + rank: List[float] class _RankLineData(TypedDict): - x: list[float] - y: list[float] + x: List[float] + y: List[float] class _RankDataSingleChain(TypedDict): @@ -106,10 +104,10 @@ class _RankDataSingleChain(TypedDict): mean: float -MarginalData = dict[str, _MarginalDataSingleChain] -ForestData = dict[str, _ForestDataSingleChain] -TraceData = dict[str, _TraceDataSingleChain] -RankData = dict[str, _RankDataSingleChain] +MarginalData = Dict[str, _MarginalDataSingleChain] +ForestData = Dict[str, _ForestDataSingleChain] +TraceData = Dict[str, _TraceDataSingleChain] +RankData = Dict[str, _RankDataSingleChain] class _Data(TypedDict): @@ -137,10 +135,10 @@ class _RankSourceSingleChain(TypedDict): line: ColumnDataSource -MarginalSources = dict[str, _MarginalSourceSingleChain] -ForestSources = dict[str, _ForestSourceSingleChain] -TraceSources = dict[str, _TraceSourceSingleChain] -RankSources = dict[str, _RankSourceSingleChain] +MarginalSources = Dict[str, _MarginalSourceSingleChain] +ForestSources = Dict[str, _ForestSourceSingleChain] +TraceSources = Dict[str, _TraceSourceSingleChain] +RankSources = Dict[str, _RankSourceSingleChain] class _FigureSources(TypedDict): @@ -150,7 +148,7 @@ class _FigureSources(TypedDict): ranks: RankSources -_Sources = dict[str, _FigureSources] +_Sources = Dict[str, _FigureSources] class _Figures(TypedDict): @@ -208,10 +206,10 @@ class _RankGlyphSingleChain(TypedDict): line: _RankLineGlyph -MarginalGlyphs = dict[str, _MarginalGlyphSingleChain] -ForestGlyphs = dict[str, _ForestGlyphSingleChain] -TraceGlyphs = dict[str, _TraceGlyphSingleChain] -RankGlyphs = dict[str, _RankGlyphSingleChain] +MarginalGlyphs = Dict[str, _MarginalGlyphSingleChain] +ForestGlyphs = Dict[str, _ForestGlyphSingleChain] +TraceGlyphs = Dict[str, _TraceGlyphSingleChain] +RankGlyphs = Dict[str, _RankGlyphSingleChain] class _FigureGlyphs(TypedDict): @@ -221,10 +219,10 @@ class _FigureGlyphs(TypedDict): ranks: RankGlyphs -_Glyphs = dict[str, _FigureGlyphs] +_Glyphs = Dict[str, _FigureGlyphs] -_FigureAnnotations = dict[str, Legend] -_Annotations = dict[str, _FigureAnnotations] +_FigureAnnotations = Dict[str, Legend] +_Annotations = Dict[str, _FigureAnnotations] class _Widgets(TypedDict): From 58799d62b2e170ec9295e5f647ff08a540746700 Mon Sep 17 00:00:00 2001 From: Andy Maloney Date: Mon, 29 Aug 2022 16:26:57 -0500 Subject: [PATCH 3/7] Add copyright notice --- src/beanmachine/ppl/diagnostics/tools/__init__.py | 6 ++++++ src/beanmachine/ppl/diagnostics/tools/accessor.py | 5 +++++ src/beanmachine/ppl/diagnostics/tools/autocorrelation.py | 5 +++++ .../ppl/diagnostics/tools/effective_sample_size.py | 5 +++++ src/beanmachine/ppl/diagnostics/tools/helpers/__init__.py | 6 ++++++ .../ppl/diagnostics/tools/helpers/autocorrelation.py | 5 +++++ .../ppl/diagnostics/tools/helpers/effective_sample_size.py | 5 +++++ src/beanmachine/ppl/diagnostics/tools/helpers/marginal1d.py | 5 +++++ src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py | 5 +++++ src/beanmachine/ppl/diagnostics/tools/helpers/plotting.py | 5 +++++ src/beanmachine/ppl/diagnostics/tools/helpers/trace.py | 5 +++++ src/beanmachine/ppl/diagnostics/tools/marginal1d.py | 5 +++++ src/beanmachine/ppl/diagnostics/tools/marginal2d.py | 5 +++++ src/beanmachine/ppl/diagnostics/tools/trace.py | 5 +++++ src/beanmachine/ppl/diagnostics/tools/typing/__init__.py | 6 ++++++ .../ppl/diagnostics/tools/typing/autocorrelation.py | 5 +++++ .../ppl/diagnostics/tools/typing/effective_sample_size.py | 5 +++++ src/beanmachine/ppl/diagnostics/tools/typing/marginal1d.py | 5 +++++ src/beanmachine/ppl/diagnostics/tools/typing/marginal2d.py | 5 +++++ src/beanmachine/ppl/diagnostics/tools/typing/trace.py | 5 +++++ src/beanmachine/ppl/diagnostics/tools/viz.py | 5 +++++ 21 files changed, 108 insertions(+) diff --git a/src/beanmachine/ppl/diagnostics/tools/__init__.py b/src/beanmachine/ppl/diagnostics/tools/__init__.py index e69de29bb2..d74a9f5ab5 100644 --- a/src/beanmachine/ppl/diagnostics/tools/__init__.py +++ b/src/beanmachine/ppl/diagnostics/tools/__init__.py @@ -0,0 +1,6 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +"""Visual diagnostic tools for Bean Machine models.""" diff --git a/src/beanmachine/ppl/diagnostics/tools/accessor.py b/src/beanmachine/ppl/diagnostics/tools/accessor.py index 0f2517582e..bb1baaca55 100644 --- a/src/beanmachine/ppl/diagnostics/tools/accessor.py +++ b/src/beanmachine/ppl/diagnostics/tools/accessor.py @@ -1,3 +1,8 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + """Accessor definition for extending Bean Machine `MonteCarloSamples` objects.""" import contextlib import warnings diff --git a/src/beanmachine/ppl/diagnostics/tools/autocorrelation.py b/src/beanmachine/ppl/diagnostics/tools/autocorrelation.py index ab42908365..fe75a606cf 100644 --- a/src/beanmachine/ppl/diagnostics/tools/autocorrelation.py +++ b/src/beanmachine/ppl/diagnostics/tools/autocorrelation.py @@ -1,3 +1,8 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + """Autocorrelation diagnostic tool for a Bean Machine model.""" from typing import Any, Tuple, TypeVar diff --git a/src/beanmachine/ppl/diagnostics/tools/effective_sample_size.py b/src/beanmachine/ppl/diagnostics/tools/effective_sample_size.py index b608133d05..0dcceb2b40 100644 --- a/src/beanmachine/ppl/diagnostics/tools/effective_sample_size.py +++ b/src/beanmachine/ppl/diagnostics/tools/effective_sample_size.py @@ -1,3 +1,8 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + """Effective Sample Size (ESS) diagnostic tool for a Bean Machine model.""" from typing import Any, TypeVar diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/__init__.py b/src/beanmachine/ppl/diagnostics/tools/helpers/__init__.py index e69de29bb2..a81500160a 100644 --- a/src/beanmachine/ppl/diagnostics/tools/helpers/__init__.py +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/__init__.py @@ -0,0 +1,6 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +"""Visual diagnostics tool methods.""" diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/autocorrelation.py b/src/beanmachine/ppl/diagnostics/tools/helpers/autocorrelation.py index 76c8de6a05..e901008128 100644 --- a/src/beanmachine/ppl/diagnostics/tools/helpers/autocorrelation.py +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/autocorrelation.py @@ -1,3 +1,8 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + """Methods used to generate the diagnostic tool.""" from typing import List diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/effective_sample_size.py b/src/beanmachine/ppl/diagnostics/tools/helpers/effective_sample_size.py index 4bace8cbe9..67660d4d96 100644 --- a/src/beanmachine/ppl/diagnostics/tools/helpers/effective_sample_size.py +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/effective_sample_size.py @@ -1,3 +1,8 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + """Methods used to generate the diagnostic tool.""" from typing import List diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/marginal1d.py b/src/beanmachine/ppl/diagnostics/tools/helpers/marginal1d.py index 60062bde24..bc3cc825d0 100644 --- a/src/beanmachine/ppl/diagnostics/tools/helpers/marginal1d.py +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/marginal1d.py @@ -1,3 +1,8 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + """Methods used to generate the diagnostic tool.""" from typing import List, Optional diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py b/src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py index 194deb423e..a02ab6a0ad 100644 --- a/src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py @@ -1,3 +1,8 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + """Methods used to generate the diagnostic tool.""" from typing import List, Optional diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/plotting.py b/src/beanmachine/ppl/diagnostics/tools/helpers/plotting.py index 99d47377fb..5c2644da84 100644 --- a/src/beanmachine/ppl/diagnostics/tools/helpers/plotting.py +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/plotting.py @@ -1,3 +1,8 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + """Plotting utilities for the diagnostics tools.""" from typing import Dict, List diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/trace.py b/src/beanmachine/ppl/diagnostics/tools/helpers/trace.py index 59fc035bf9..31c45d956a 100644 --- a/src/beanmachine/ppl/diagnostics/tools/helpers/trace.py +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/trace.py @@ -1,3 +1,8 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + """Methods used to generate the diagnostic tool.""" from typing import List diff --git a/src/beanmachine/ppl/diagnostics/tools/marginal1d.py b/src/beanmachine/ppl/diagnostics/tools/marginal1d.py index 0b5acd4528..cc316daead 100644 --- a/src/beanmachine/ppl/diagnostics/tools/marginal1d.py +++ b/src/beanmachine/ppl/diagnostics/tools/marginal1d.py @@ -1,3 +1,8 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + """Marginal 1D diagnostic tool for a Bean Machine model.""" from typing import Any, TypeVar diff --git a/src/beanmachine/ppl/diagnostics/tools/marginal2d.py b/src/beanmachine/ppl/diagnostics/tools/marginal2d.py index 74ea84d73a..f917b784a6 100644 --- a/src/beanmachine/ppl/diagnostics/tools/marginal2d.py +++ b/src/beanmachine/ppl/diagnostics/tools/marginal2d.py @@ -1,3 +1,8 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + """Marginal 2D diagnostic tool for a Bean Machine model.""" from typing import Any, TypeVar diff --git a/src/beanmachine/ppl/diagnostics/tools/trace.py b/src/beanmachine/ppl/diagnostics/tools/trace.py index b0821b7bf3..a2b9ceebae 100644 --- a/src/beanmachine/ppl/diagnostics/tools/trace.py +++ b/src/beanmachine/ppl/diagnostics/tools/trace.py @@ -1,3 +1,8 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + """Trace diagnostic tool for a Bean Machine model.""" from typing import Any, TypeVar diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/__init__.py b/src/beanmachine/ppl/diagnostics/tools/typing/__init__.py index e69de29bb2..b610255e09 100644 --- a/src/beanmachine/ppl/diagnostics/tools/typing/__init__.py +++ b/src/beanmachine/ppl/diagnostics/tools/typing/__init__.py @@ -0,0 +1,6 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +"""Types for the visual diagnostics tools.""" diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/autocorrelation.py b/src/beanmachine/ppl/diagnostics/tools/typing/autocorrelation.py index 968bf5adde..85704a45b8 100644 --- a/src/beanmachine/ppl/diagnostics/tools/typing/autocorrelation.py +++ b/src/beanmachine/ppl/diagnostics/tools/typing/autocorrelation.py @@ -1,3 +1,8 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + """Autocorrelation diagnostic tool types for a Bean Machine model.""" from typing import Any, Dict, List, TypedDict diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/effective_sample_size.py b/src/beanmachine/ppl/diagnostics/tools/typing/effective_sample_size.py index bf0dcd6bd5..82cfcb7073 100644 --- a/src/beanmachine/ppl/diagnostics/tools/typing/effective_sample_size.py +++ b/src/beanmachine/ppl/diagnostics/tools/typing/effective_sample_size.py @@ -1,3 +1,8 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + """Effective Sample Size diagnostic tool types for a Bean Machine model.""" from typing import Any, Dict, List, TypedDict diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/marginal1d.py b/src/beanmachine/ppl/diagnostics/tools/typing/marginal1d.py index 70ffb364d0..fecd81ee29 100644 --- a/src/beanmachine/ppl/diagnostics/tools/typing/marginal1d.py +++ b/src/beanmachine/ppl/diagnostics/tools/typing/marginal1d.py @@ -1,3 +1,8 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + """Marginal 1D diagnostic tool types for a Bean Machine model.""" from typing import Any, Dict, List, TypedDict diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/marginal2d.py b/src/beanmachine/ppl/diagnostics/tools/typing/marginal2d.py index a3a9a83463..53677e5c92 100644 --- a/src/beanmachine/ppl/diagnostics/tools/typing/marginal2d.py +++ b/src/beanmachine/ppl/diagnostics/tools/typing/marginal2d.py @@ -1,3 +1,8 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + """Marginal 2D diagnostic tool types for a Bean Machine model.""" from typing import Any, Dict, List, TypedDict diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/trace.py b/src/beanmachine/ppl/diagnostics/tools/typing/trace.py index a81a6db5e3..8eae08b9ef 100644 --- a/src/beanmachine/ppl/diagnostics/tools/typing/trace.py +++ b/src/beanmachine/ppl/diagnostics/tools/typing/trace.py @@ -1,3 +1,8 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + """Marginal 2D diagnostic tool types for a Bean Machine model.""" from typing import Any, Dict, List, TypedDict diff --git a/src/beanmachine/ppl/diagnostics/tools/viz.py b/src/beanmachine/ppl/diagnostics/tools/viz.py index d539b8b91e..0876d1bf11 100644 --- a/src/beanmachine/ppl/diagnostics/tools/viz.py +++ b/src/beanmachine/ppl/diagnostics/tools/viz.py @@ -1,3 +1,8 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + """Visual diagnostics tools for Bean Machine models.""" from typing import TypeVar From 51c1719da6187dcbb467ef4749d8f90b28a3d382 Mon Sep 17 00:00:00 2001 From: Andy Maloney Date: Mon, 29 Aug 2022 16:44:06 -0500 Subject: [PATCH 4/7] Fix linting errors --- src/beanmachine/ppl/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/beanmachine/ppl/__init__.py b/src/beanmachine/ppl/__init__.py index 542377c5ac..a505ab9729 100644 --- a/src/beanmachine/ppl/__init__.py +++ b/src/beanmachine/ppl/__init__.py @@ -61,4 +61,5 @@ "random_variable", "simulate", "split_r_hat", + "viz", ] From 421fe45cbaa5da8db24fe54c537f40f8664fd329 Mon Sep 17 00:00:00 2001 From: Andy Maloney Date: Mon, 29 Aug 2022 16:52:20 -0500 Subject: [PATCH 5/7] Fix bug associated with reverted types --- .../ppl/diagnostics/tools/helpers/effective_sample_size.py | 2 +- src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py | 2 +- src/beanmachine/ppl/diagnostics/tools/marginal2d.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/effective_sample_size.py b/src/beanmachine/ppl/diagnostics/tools/helpers/effective_sample_size.py index 67660d4d96..ddde815253 100644 --- a/src/beanmachine/ppl/diagnostics/tools/helpers/effective_sample_size.py +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/effective_sample_size.py @@ -35,7 +35,7 @@ def compute_data( data: npt.NDArray, - first_draw: float = 0.0, + first_draw: int = 0, num_points: int = 20, ) -> typing.Data: """Compute effective sample size estimates using the given data. diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py b/src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py index a02ab6a0ad..204c02bb5b 100644 --- a/src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py @@ -176,7 +176,7 @@ def compute_y_data( "distribution": { "x": kde_y.tolist(), "y": kde_x.tolist(), - "bandwidth": bandwidth, + "bandwidth": [bandwidth], }, "hdi": { "top": {"base": top_base, "lower": top_lower, "upper": top_upper}, diff --git a/src/beanmachine/ppl/diagnostics/tools/marginal2d.py b/src/beanmachine/ppl/diagnostics/tools/marginal2d.py index f917b784a6..ef6859b4a0 100644 --- a/src/beanmachine/ppl/diagnostics/tools/marginal2d.py +++ b/src/beanmachine/ppl/diagnostics/tools/marginal2d.py @@ -52,8 +52,8 @@ def modify_doc(self: T, doc: Any) -> None: y_hdi_probability=y_hdi_probability, bw_factor=bw_factor, ) - x_bw = computed_data["x"]["distribution"]["bandwidth"] - y_bw = float(computed_data["y"]["distribution"]["bandwidth"]) + x_bw = computed_data["x"]["distribution"]["bandwidth"][0] + y_bw = computed_data["y"]["distribution"]["bandwidth"][0] # Create the Bokeh source(s). sources = tool.create_sources(computed_data) From 17e95b74923a2ab4a29a50d96fe99de11382b68b Mon Sep 17 00:00:00 2001 From: Andy Maloney Date: Tue, 30 Aug 2022 16:59:30 -0500 Subject: [PATCH 6/7] Rebase and fix more type bugs --- .../ppl/diagnostics/tools/helpers/marginal1d.py | 6 +++--- .../ppl/diagnostics/tools/helpers/marginal2d.py | 8 ++++---- .../ppl/diagnostics/tools/typing/__init__.py | 7 +++++++ .../ppl/diagnostics/tools/typing/autocorrelation.py | 8 +++++--- .../diagnostics/tools/typing/effective_sample_size.py | 4 +++- .../ppl/diagnostics/tools/typing/marginal1d.py | 6 ++++-- .../ppl/diagnostics/tools/typing/marginal2d.py | 10 +++++----- src/beanmachine/ppl/diagnostics/tools/typing/trace.py | 6 +++--- 8 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/marginal1d.py b/src/beanmachine/ppl/diagnostics/tools/helpers/marginal1d.py index bc3cc825d0..fbf6ce9b47 100644 --- a/src/beanmachine/ppl/diagnostics/tools/helpers/marginal1d.py +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/marginal1d.py @@ -58,11 +58,11 @@ def compute_stats( The y-axis KDE estimate of the random variable data. hdi_probability : float The HDI probability to use when calculating the HDI bounds. - text_align : List[str] | None, optional default is ``None`` + text_align : Optional[List[str]], optional default is ``None`` How to display label justifications for the statistics in Bokeh. - x_offset : List[int] | None, optional default is ``None`` + x_offset : Optional[List[int]], optional default is ``None`` x-axis offsets for the labels. - y_offset : List[int] | None, optional default is ``None`` + y_offset : Optional[List[int]], optional default is ``None`` y-axis offsets for the labels. return_labels : bool, optional default is ``False`` ``True`` returns labels to be used in the Bokeh figure. diff --git a/src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py b/src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py index 204c02bb5b..2b2f4fea8d 100644 --- a/src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py +++ b/src/beanmachine/ppl/diagnostics/tools/helpers/marginal2d.py @@ -4,7 +4,7 @@ # LICENSE file in the root directory of this source tree. """Methods used to generate the diagnostic tool.""" -from typing import List, Optional +from typing import List, Optional, Tuple import arviz as az import beanmachine.ppl.diagnostics.tools.typing.marginal2d as typing @@ -917,7 +917,7 @@ def update( x_hdi_probability: float, y_hdi_probability: float, bw_factor: float, -) -> tuple[float, float]: +) -> Tuple[float, float]: """Update the tool based on user interaction. Parameters @@ -949,8 +949,8 @@ def update( Returns ------- - None - Updates Bokeh ColumnDataSource objects. + Tuple[float, float] + Returns the bandwidth for both the axes. """ computed_data = compute_data( x_rv_data, diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/__init__.py b/src/beanmachine/ppl/diagnostics/tools/typing/__init__.py index b610255e09..8c828d07c5 100644 --- a/src/beanmachine/ppl/diagnostics/tools/typing/__init__.py +++ b/src/beanmachine/ppl/diagnostics/tools/typing/__init__.py @@ -4,3 +4,10 @@ # LICENSE file in the root directory of this source tree. """Types for the visual diagnostics tools.""" + +import sys + +if sys.version_info >= (3, 8): + from typing import TypedDict +else: + from typing_extensions import TypedDict diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/autocorrelation.py b/src/beanmachine/ppl/diagnostics/tools/typing/autocorrelation.py index 85704a45b8..0766cff0cd 100644 --- a/src/beanmachine/ppl/diagnostics/tools/typing/autocorrelation.py +++ b/src/beanmachine/ppl/diagnostics/tools/typing/autocorrelation.py @@ -4,7 +4,9 @@ # LICENSE file in the root directory of this source tree. """Autocorrelation diagnostic tool types for a Bean Machine model.""" -from typing import Any, Dict, List, TypedDict +from typing import Any, Dict, List, Union + +from beanmachine.ppl.diagnostics.tools.typing import TypedDict from bokeh.models.annotations import BoxAnnotation from bokeh.models.glyphs import Quad @@ -15,7 +17,7 @@ from bokeh.plotting.figure import Figure -Figure_names = None | List[str] +Figure_names = Union[None, List[str]] # NOTE: These are the types pyre gives us when using `reveal_type(...)` on the outputs # of the methods. @@ -25,7 +27,7 @@ Glyphs = Dict[Any, Any] Annotations = Dict[Any, Any] Tooltips = Dict[Any, Any] -Widgets = Dict[str, RangeSlider | Select] +Widgets = Dict[str, Union[RangeSlider, Select]] # NOTE: TypedDict objects are for reference only. Due to the way pyre accesses keys in # dictionaries, and how NumPy casts arrays when using tolist(), we are unable to diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/effective_sample_size.py b/src/beanmachine/ppl/diagnostics/tools/typing/effective_sample_size.py index 82cfcb7073..117a1fed91 100644 --- a/src/beanmachine/ppl/diagnostics/tools/typing/effective_sample_size.py +++ b/src/beanmachine/ppl/diagnostics/tools/typing/effective_sample_size.py @@ -4,7 +4,9 @@ # LICENSE file in the root directory of this source tree. """Effective Sample Size diagnostic tool types for a Bean Machine model.""" -from typing import Any, Dict, List, TypedDict +from typing import Any, Dict, List + +from beanmachine.ppl.diagnostics.tools.typing import TypedDict from bokeh.models.annotations import Legend from bokeh.models.glyphs import Circle, Line diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/marginal1d.py b/src/beanmachine/ppl/diagnostics/tools/typing/marginal1d.py index fecd81ee29..bb9c9ae31a 100644 --- a/src/beanmachine/ppl/diagnostics/tools/typing/marginal1d.py +++ b/src/beanmachine/ppl/diagnostics/tools/typing/marginal1d.py @@ -4,7 +4,9 @@ # LICENSE file in the root directory of this source tree. """Marginal 1D diagnostic tool types for a Bean Machine model.""" -from typing import Any, Dict, List, TypedDict +from typing import Any, Dict, List, Union + +from beanmachine.ppl.diagnostics.tools.typing import TypedDict from bokeh.models.annotations import Band, LabelSet from bokeh.models.glyphs import Circle, Line @@ -26,7 +28,7 @@ Glyphs = Dict[Any, Any] Annotations = Dict[Any, Any] Tooltips = Dict[Any, Any] -Widgets = Dict[str, Div | Select | Slider] +Widgets = Dict[str, Union[Div, Select, Slider]] # NOTE: TypedDict objects are for reference only. Due to the way pyre accesses keys in # dictionaries, and how NumPy casts arrays when using tolist(), we are unable to diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/marginal2d.py b/src/beanmachine/ppl/diagnostics/tools/typing/marginal2d.py index 53677e5c92..4f0cf1c55e 100644 --- a/src/beanmachine/ppl/diagnostics/tools/typing/marginal2d.py +++ b/src/beanmachine/ppl/diagnostics/tools/typing/marginal2d.py @@ -4,9 +4,9 @@ # LICENSE file in the root directory of this source tree. """Marginal 2D diagnostic tool types for a Bean Machine model.""" -from typing import Any, Dict, List, TypedDict +from typing import Any, Dict, List, Union -from beanmachine.ppl.diagnostics.tools.typing import marginal1d as m1d +from beanmachine.ppl.diagnostics.tools.typing import marginal1d as m1d, TypedDict from bokeh.models.annotations import Band from bokeh.models.glyphs import Circle, Image, Line @@ -22,16 +22,16 @@ # of the methods. XYData = Dict[ str, - Dict[str, Dict[str, Dict[str, Any]]] | Dict[str, List[Any]], + Union[Dict[str, Dict[str, Dict[str, Any]]], Dict[str, List[Any]]], ] YData = Dict[str, Dict[str, Any]] Data = Dict[str, Any] Sources = Dict[Any, Any] Figures = Dict[Any, Any] Glyphs = Dict[Any, Any] -Annotations = Dict[str, Dict[str, Band] | Band] +Annotations = Dict[str, Union[Dict[str, Band], Band]] Tooltips = Dict[Any, Any] -Widgets = Dict[str, Div | Select | Slider] +Widgets = Dict[str, Union[Div, Select, Slider]] # NOTE: TypedDict objects are for reference only. Due to the way pyre accesses keys in # dictionaries, and how NumPy casts arrays when using tolist(), we are unable to diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/trace.py b/src/beanmachine/ppl/diagnostics/tools/typing/trace.py index 8eae08b9ef..a731b18b0f 100644 --- a/src/beanmachine/ppl/diagnostics/tools/typing/trace.py +++ b/src/beanmachine/ppl/diagnostics/tools/typing/trace.py @@ -4,9 +4,9 @@ # LICENSE file in the root directory of this source tree. """Marginal 2D diagnostic tool types for a Bean Machine model.""" -from typing import Any, Dict, List, TypedDict +from typing import Any, Dict, List, Union -from beanmachine.ppl.diagnostics.tools.typing import marginal1d as m1d +from beanmachine.ppl.diagnostics.tools.typing import marginal1d as m1d, TypedDict from bokeh.models.annotations import Legend from bokeh.models.glyphs import Circle, Line, Quad @@ -24,7 +24,7 @@ Glyphs = Dict[Any, Any] Annotations = Dict[str, Dict[str, Legend]] Tooltips = Dict[Any, Any] -Widgets = Dict[str, Select | Slider] +Widgets = Dict[str, Union[Select, Slider]] # NOTE: TypedDict objects are for reference only. Due to the way pyre accesses keys in # dictionaries, and how NumPy casts arrays when using tolist(), we are unable to From 3d4aa71bc90a4e26351d6450b690681c5090dec7 Mon Sep 17 00:00:00 2001 From: Andy Maloney Date: Tue, 30 Aug 2022 17:03:30 -0500 Subject: [PATCH 7/7] Make flake8 ignore py37 TypedDict unused import --- src/beanmachine/ppl/diagnostics/tools/typing/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/beanmachine/ppl/diagnostics/tools/typing/__init__.py b/src/beanmachine/ppl/diagnostics/tools/typing/__init__.py index 8c828d07c5..a11a2ad021 100644 --- a/src/beanmachine/ppl/diagnostics/tools/typing/__init__.py +++ b/src/beanmachine/ppl/diagnostics/tools/typing/__init__.py @@ -10,4 +10,4 @@ if sys.version_info >= (3, 8): from typing import TypedDict else: - from typing_extensions import TypedDict + from typing_extensions import TypedDict # noqa: F401