From 7a6b97dd01db95e2b5f8a773fe170e065b6e6c1e Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Tue, 1 Jul 2025 17:54:13 +0200 Subject: [PATCH 01/42] Added recipoe for simple descriptors calculation. --- docs/source/descr_from_trj.rst | 91 ++++++++++++++++++++++++++++++++++ docs/source/index.rst | 7 +++ 2 files changed, 98 insertions(+) create mode 100644 docs/source/descr_from_trj.rst diff --git a/docs/source/descr_from_trj.rst b/docs/source/descr_from_trj.rst new file mode 100644 index 00000000..9c208fb8 --- /dev/null +++ b/docs/source/descr_from_trj.rst @@ -0,0 +1,91 @@ +Descriptors from a :class:`.trajectory.Trj` +=========================================== + +This recipe explains how to compute descriptors directly from a +:class:`.trajectory.Trj` object. + +SOAP +---- + +Computing SOAP for every particle and frame of the trajectory is easy, since +it's directly calculated by the :class:`.trajectory.Trj.get_soap()` method. + +Please consider that the SOAP dataset can be very large, due to the high +dimensionality, thus calculations can be expensive, and saving to/loading from +file quite slow. + +.. testcode:: recipe1-test + + from pathlib import Path + from dynsight.trajectory import Trj + + # Loading an example trajectory + files_path = Path("../tests/systems/") + trj = Trj.init_from_xtc( + traj_file=files_path / "balls_7_nvt.xtc", + topo_file=files_path / "balls_7_nvt.gro", + ) + + soap = trj.get_soap( + r_cut=2.0, # cutoff radius for neighbors list + n_max=4, # n_max SOAP parameter + l_max=4, # l_max SOAP parameter + selection="all", # compute on a selection of particles + centers="all", # compute for a selection of centers + respect_pbc=False, # consider PBC + n_core=1, # use multiprocessing to speed up calculations + ) + +Number of neighbors and LENS +---------------------------- + +Similarly to SOAP, computing number of neighbors or LENS can be done with the +respective methods of the :class:`.trajectory.Trj` class. + +Since both calculations need to compute the list of neighbors for each +particle at each frame, this list is also returned, and can be passed as an +optional parameter, so that when computing both quantities the second +calculation can be sped up significantly. + +.. testcode:: recipe1-test + + from pathlib import Path + from dynsight.trajectory import Trj + + # Loading an example trajectory + files_path = Path("../tests/systems/") + trj = Trj.init_from_xtc( + traj_file=files_path / "balls_7_nvt.xtc", + topo_file=files_path / "balls_7_nvt.gro", + ) + + # Computing number of neighbors from scratch + neigcounts, n_neig = trj.get_coord_number( + r_cut=2.0, # cutoff radius for neighbors list + selection="all", # compute on a selection of particles + neigcounts=None, # it will be computed and returned + ) + + # Now for LENS we already have neigcounts + _, lens = trj.get_lens( + r_cut=2.0, # cutoff radius for neighbors list + selection="all", # compute on a selection of particles + neigcounts=neigcounts, # no need to compute it again + ) + +Notice that, differently from SOAP - which is computed for every frame, LENS +is computed for every pair of frames. Thus, the LENS dataset has shape +``(n_particles, n_frames - 1)``. Consequently, if you need to match the LENS +values with the particles along the trajectory, you will need to use a sliced +trajectory (removing the last frame). The easiest way to do this is: + +.. testcode:: recipe1-test + + trajslice = slice(0, -1, 1) + shorter_trj = trj.with_slice(trajslice=trajslice) + +.. testcode:: recipe1-test + :hide: + + assert soap.dataset.shape == (7, 201, 50) + assert lens.dataset.shape == (7, 200) diff --git a/docs/source/index.rst b/docs/source/index.rst index 31c71c99..911e7727 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -13,6 +13,13 @@ data processing HDF5er +.. toctree:: + :hidden: + :maxdepth: 2 + :caption: Recipes: + + Descriptors from a Trj + .. toctree:: :hidden: :maxdepth: 2 From 80bc4a01ece644df0d01d8596c9799788c8b80fb Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Wed, 2 Jul 2025 10:14:59 +0200 Subject: [PATCH 02/42] Added recipe on PCA. --- docs/source/index.rst | 1 + docs/source/soap_dim_red.rst | 120 +++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 docs/source/soap_dim_red.rst diff --git a/docs/source/index.rst b/docs/source/index.rst index 911e7727..25f42415 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -19,6 +19,7 @@ :caption: Recipes: Descriptors from a Trj + Dimensionality reduction methods .. toctree:: :hidden: diff --git a/docs/source/soap_dim_red.rst b/docs/source/soap_dim_red.rst new file mode 100644 index 00000000..97a1cd71 --- /dev/null +++ b/docs/source/soap_dim_red.rst @@ -0,0 +1,120 @@ +Dimensionality reduction methods +================================ + +This recipe explains how to compute descriptors via dimensionality reduction +of a multivariated descriptor. These example use SOAP, but the same approaches +can be applied to a variety of other quantities. The newly computed +descriptors are always stored in an :class:`.trajectory.Insight` variable. + +All the functions take as optional parameters one or more file paths; if these +paths are passed, the function, before computing some quantity from scratch, +tries to load it from file, in case it has already been previously computed +and saved. + +Please remember that the SOAP dataset can be very large, due to the high +dimensionality, thus calculations can be expensive, and saving to/loading from +file quite slow. + +Let's start by creating a :class:`.trajectory.Trj` object to use as a +starting point for the examples: + +.. testcode:: recipe2-test + + from pathlib import Path + from dynsight.trajectory import Trj + + # Loading an example trajectory + files_path = Path("../tests/systems/") + trj = Trj.init_from_xtc( + traj_file=files_path / "balls_7_nvt.xtc", + topo_file=files_path / "balls_7_nvt.gro", + ) + +Principal Component Analysis (PCA) +---------------------------------- + +Principal Component Analysis is a dimensionality reduction method that finds +the combinations of components that maximize the data variance. More details +on the algorithm here https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html. + +This function takes as input a :class:`.trajectory.Trj` and all the relevant +parameters, and performs the PCA of the corresponding SOAP dataset. + +.. testcode:: recipe2-test + + from pathlib import Path + from dynsight.trajectory import Trj, Insight + from sklearn.decomposition import PCA + + def compute_soap_pca( + trj: Trj, + r_cut: float, + n_max: int, + l_max: int, + n_components: int, + soap_path: Path | None = None, + pca_path: Path | None = None, + selection: str = "all", + centers: str = "all", + respect_pbc: bool = True, + n_core: int = 1, + ) -> Insight: + if pca_path is not None and pca_path.exists(): + soap_pca = Insight.load_from_json(pca_path) + else: + if soap_path is not None and soap_path.exists(): + soap = Insight.load_from_json(soap_path) + else: + soap = trj.get_soap( + r_cut=r_cut, + n_max=n_max, + l_max=l_max, + selection=selection, + centers=centers, + respect_pbc=respect_pbc, + n_core=n_core, + ) + if soap_path is not None: + soap.dump_to_json(soap_path) + + n_atom, n_frames, n_dims = soap.dataset.shape + reshaped_soap = soap.dataset.reshape(n_atom * n_frames, n_dims) + pca = PCA(n_components=n_components) + transformed_soap = pca.fit_transform(reshaped_soap) + pca_ds = transformed_soap.reshape(n_atom, n_frames, -1) + soap_pca = Insight(pca_ds) + + if pca_path is not None: + soap_pca.dump_to_json(pca_path) + + return soap_pca + + # Example of how to use + soap_pc1 = compute_soap_pca( + trj=trj, + r_cut=2.0, + n_max=4, + l_max=4, + n_components=1, + ) + + + +Other +----- + +Notice that, differently from SOAP - which is computed for every frame, tSOAP +is computed for every pair of frames. Thus, the tSOAP dataset has shape +``(n_particles, n_frames - 1)``. Consequently, if you need to match the tSOAP +values with the particles along the trajectory, you will need to use a sliced +trajectory (removing the last frame). The easiest way to do this is: + +.. testcode:: recipe2-test + + trajslice = slice(0, -1, 1) + shorter_trj = trj.with_slice(trajslice=trajslice) + +.. testcode:: recipe2-test + :hide: + + assert soap_pc1.dataset.shape == (7, 201, 1) From 237baa9fe69878752feccf1fd508f0fd48b0fbdf Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Wed, 2 Jul 2025 10:38:27 +0200 Subject: [PATCH 03/42] Added recipe for TICA. --- docs/source/soap_dim_red.rst | 88 +++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/docs/source/soap_dim_red.rst b/docs/source/soap_dim_red.rst index 97a1cd71..da8b653e 100644 --- a/docs/source/soap_dim_red.rst +++ b/docs/source/soap_dim_red.rst @@ -40,9 +40,12 @@ on the algorithm here https://scikit-learn.org/stable/modules/generated/sklearn. This function takes as input a :class:`.trajectory.Trj` and all the relevant parameters, and performs the PCA of the corresponding SOAP dataset. +``n_components`` is the number of PCs that the function stores in the output. + .. testcode:: recipe2-test from pathlib import Path + import dynsight from dynsight.trajectory import Trj, Insight from sklearn.decomposition import PCA @@ -82,7 +85,9 @@ parameters, and performs the PCA of the corresponding SOAP dataset. pca = PCA(n_components=n_components) transformed_soap = pca.fit_transform(reshaped_soap) pca_ds = transformed_soap.reshape(n_atom, n_frames, -1) - soap_pca = Insight(pca_ds) + + meta = soap.meta.copy() + soap_pca = Insight(pca_ds, meta=meta) if pca_path is not None: soap_pca.dump_to_json(pca_path) @@ -98,6 +103,86 @@ parameters, and performs the PCA of the corresponding SOAP dataset. n_components=1, ) +The output :class:`.trajectory.Insight` stores the SOAP information in its +"meta" attribute. + +Time-lagged Independent Component Analysis (TICA) +------------------------------------------------- + +More details on the algorithm here https://deeptime-ml.github.io/latest/notebooks/tica.html. + +This function takes as input a :class:`.trajectory.Trj` and all the relevant +parameters, and performs the TICA of the corresponding SOAP dataset. + +``lag_time`` is the time lag used to perform TICA. +``tica_dim`` is the number of TICs that the function stores in the output. + +.. testcode:: recipe2-test + + from pathlib import Path + from dynsight.trajectory import Trj, Insight + + def compute_soap_tica( + trj: Trj, + r_cut: float, + n_max: int, + l_max: int, + lag_time: int, + tica_dim: int, + soap_path: Path | None = None, + tica_path: Path | None = None, + selection: str = "all", + centers: str = "all", + respect_pbc: bool = True, + n_core: int = 1, + ) -> Insight: + if tica_path is not None and tica_path.exists(): + soap_pca = Insight.load_from_json(tica_path) + else: + if soap_path is not None and soap_path.exists(): + soap = Insight.load_from_json(soap_path) + else: + soap = trj.get_soap( + r_cut=r_cut, + n_max=n_max, + l_max=l_max, + selection=selection, + centers=centers, + respect_pbc=respect_pbc, + n_core=n_core, + ) + if soap_path is not None: + soap.dump_to_json(soap_path) + + rel_times, _, tica_ds = dynsight.tica.many_body_tica( + soap.dataset, + lag_time=lag_time, + tica_dim=tica_dim, + ) + + meta = soap.meta.copy() + meta.update({"lag_time": lag_time}) + meta.update({"rel_times": rel_times}) + soap_tica = Insight(tica_ds, meta=meta) + + if tica_path is not None: + soap_tica.dump_to_json(tica_path) + + return soap_tica + + # Example of how to use + soap_tic1 = compute_soap_tica( + trj=trj, + r_cut=10.0, + n_max=4, + l_max=4, + lag_time=10, + tica_dim=1, + ) + +The output :class:`.trajectory.Insight` stores the SOAP information in its +"meta" attribute, together with the ``lag_time`` parameter and ``rel_times``, +the relaxation times of the computed TICs. Other @@ -118,3 +203,4 @@ trajectory (removing the last frame). The easiest way to do this is: :hide: assert soap_pc1.dataset.shape == (7, 201, 1) + assert soap_tic1.dataset.shape == (7, 201, 1) From 64b0eb5a1e3e12598fe2dea5f0d5717da02a31d2 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Wed, 2 Jul 2025 10:53:51 +0200 Subject: [PATCH 04/42] Added recipe for tSOAP. --- docs/source/soap_dim_red.rst | 80 ++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 4 deletions(-) diff --git a/docs/source/soap_dim_red.rst b/docs/source/soap_dim_red.rst index da8b653e..3e8a7f94 100644 --- a/docs/source/soap_dim_red.rst +++ b/docs/source/soap_dim_red.rst @@ -109,7 +109,12 @@ The output :class:`.trajectory.Insight` stores the SOAP information in its Time-lagged Independent Component Analysis (TICA) ------------------------------------------------- -More details on the algorithm here https://deeptime-ml.github.io/latest/notebooks/tica.html. +More details on the algorithm here: + +.. toctree:: + :maxdepth: 1 + + many_body_tica <_autosummary/dynsight.tica.many_body_tica> This function takes as input a :class:`.trajectory.Trj` and all the relevant parameters, and performs the TICA of the corresponding SOAP dataset. @@ -137,7 +142,7 @@ parameters, and performs the TICA of the corresponding SOAP dataset. n_core: int = 1, ) -> Insight: if tica_path is not None and tica_path.exists(): - soap_pca = Insight.load_from_json(tica_path) + soap_tica = Insight.load_from_json(tica_path) else: if soap_path is not None and soap_path.exists(): soap = Insight.load_from_json(soap_path) @@ -185,8 +190,74 @@ The output :class:`.trajectory.Insight` stores the SOAP information in its the relaxation times of the computed TICs. -Other ------ +timeSOAP (tSOAP) +---------------- + +More details on the algorithm here: + +.. toctree:: + :maxdepth: 1 + + timesoap <_autosummary/dynsight.soap.timesoap> + +This function takes as input a :class:`.trajectory.Trj` and all the relevant +parameters, and computes the corresponding timeSOAP dataset. + +``delay`` is the time lag used to perform timeSOAP. + +.. testcode:: recipe2-test + + from pathlib import Path + from dynsight.trajectory import Trj, Insight + + def compute_timesoap( + trj: Trj, + r_cut: float, + n_max: int, + l_max: int, + delay: int = 1, + soap_path: Path | None = None, + tsoap_path: Path | None = None, + selection: str = "all", + centers: str = "all", + respect_pbc: bool = True, + n_core: int = 1, + ) -> Insight: + if tsoap_path is not None and tsoap_path.exists(): + tsoap = Insight.load_from_json(tsoap_path) + else: + if soap_path is not None and soap_path.exists(): + soap = Insight.load_from_json(soap_path) + else: + soap = trj.get_soap( + r_cut=r_cut, + n_max=n_max, + l_max=l_max, + selection=selection, + centers=centers, + respect_pbc=respect_pbc, + n_core=n_core, + ) + if soap_path is not None: + soap.dump_to_json(soap_path) + + tsoap = soap.get_angular_velocity(delay=delay) + + if tsoap_path is not None: + tsoap.dump_to_json(tsoap_path) + + return tsoap + + # Example of how to use + tsoap = compute_timesoap( + trj=trj, + r_cut=10.0, + n_max=4, + l_max=4, + ) + +The output :class:`.trajectory.Insight` stores the SOAP information in its +"meta" attribute, together with the ``delay`` parameter. Notice that, differently from SOAP - which is computed for every frame, tSOAP is computed for every pair of frames. Thus, the tSOAP dataset has shape @@ -204,3 +275,4 @@ trajectory (removing the last frame). The easiest way to do this is: assert soap_pc1.dataset.shape == (7, 201, 1) assert soap_tic1.dataset.shape == (7, 201, 1) + assert tsoap.dataset.shape == (7, 200) From a7b1aad718a510b6ee569dd5340653669d9b7254 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Wed, 2 Jul 2025 11:23:36 +0200 Subject: [PATCH 05/42] Code improved; added function to compute or load soap in utilities. --- docs/source/soap_dim_red.rst | 155 +++++++++--------- src/dynsight/_internal/utilities/utilities.py | 44 ++++- src/dynsight/utilities.py | 2 + 3 files changed, 119 insertions(+), 82 deletions(-) diff --git a/docs/source/soap_dim_red.rst b/docs/source/soap_dim_red.rst index 3e8a7f94..4c49e860 100644 --- a/docs/source/soap_dim_red.rst +++ b/docs/source/soap_dim_red.rst @@ -45,7 +45,7 @@ parameters, and performs the PCA of the corresponding SOAP dataset. .. testcode:: recipe2-test from pathlib import Path - import dynsight + from dynsight.utilities import load_or_compute_soap from dynsight.trajectory import Trj, Insight from sklearn.decomposition import PCA @@ -62,35 +62,31 @@ parameters, and performs the PCA of the corresponding SOAP dataset. respect_pbc: bool = True, n_core: int = 1, ) -> Insight: - if pca_path is not None and pca_path.exists(): - soap_pca = Insight.load_from_json(pca_path) - else: - if soap_path is not None and soap_path.exists(): - soap = Insight.load_from_json(soap_path) - else: - soap = trj.get_soap( - r_cut=r_cut, - n_max=n_max, - l_max=l_max, - selection=selection, - centers=centers, - respect_pbc=respect_pbc, - n_core=n_core, - ) - if soap_path is not None: - soap.dump_to_json(soap_path) - - n_atom, n_frames, n_dims = soap.dataset.shape - reshaped_soap = soap.dataset.reshape(n_atom * n_frames, n_dims) - pca = PCA(n_components=n_components) - transformed_soap = pca.fit_transform(reshaped_soap) - pca_ds = transformed_soap.reshape(n_atom, n_frames, -1) - - meta = soap.meta.copy() - soap_pca = Insight(pca_ds, meta=meta) - - if pca_path is not None: - soap_pca.dump_to_json(pca_path) + if pca_path and pca_path.exists(): + return Insight.load_from_json(pca_path) + + soap = load_or_compute_soap( + trj=trj, + r_cut=r_cut, + n_max=n_max, + l_max=l_max, + selection=selection, + centers=centers, + respect_pbc=respect_pbc, + n_core=n_core, + soap_path=soap_path, + ) + + n_atom, n_frames, n_dims = soap.dataset.shape + reshaped_soap = soap.dataset.reshape(n_atom * n_frames, n_dims) + pca = PCA(n_components=n_components) + transformed_soap = pca.fit_transform(reshaped_soap) + pca_ds = transformed_soap.reshape(n_atom, n_frames, -1) + + soap_pca = Insight(pca_ds, meta=soap.meta.copy()) + + if pca_path: + soap_pca.dump_to_json(pca_path) return soap_pca @@ -125,6 +121,7 @@ parameters, and performs the TICA of the corresponding SOAP dataset. .. testcode:: recipe2-test from pathlib import Path + import dynsight from dynsight.trajectory import Trj, Insight def compute_soap_tica( @@ -142,36 +139,35 @@ parameters, and performs the TICA of the corresponding SOAP dataset. n_core: int = 1, ) -> Insight: if tica_path is not None and tica_path.exists(): - soap_tica = Insight.load_from_json(tica_path) - else: - if soap_path is not None and soap_path.exists(): - soap = Insight.load_from_json(soap_path) - else: - soap = trj.get_soap( - r_cut=r_cut, - n_max=n_max, - l_max=l_max, - selection=selection, - centers=centers, - respect_pbc=respect_pbc, - n_core=n_core, - ) - if soap_path is not None: - soap.dump_to_json(soap_path) - - rel_times, _, tica_ds = dynsight.tica.many_body_tica( - soap.dataset, - lag_time=lag_time, - tica_dim=tica_dim, - ) - - meta = soap.meta.copy() - meta.update({"lag_time": lag_time}) - meta.update({"rel_times": rel_times}) - soap_tica = Insight(tica_ds, meta=meta) - - if tica_path is not None: - soap_tica.dump_to_json(tica_path) + return Insight.load_from_json(tica_path) + + soap = load_or_compute_soap( + trj=trj, + r_cut=r_cut, + n_max=n_max, + l_max=l_max, + selection=selection, + centers=centers, + respect_pbc=respect_pbc, + n_core=n_core, + soap_path=soap_path, + ) + + rel_times, _, tica_ds = dynsight.tica.many_body_tica( + soap.dataset, + lag_time=lag_time, + tica_dim=tica_dim, + ) + + meta = soap.meta.copy() + meta.update({ + "lag_time": lag_time, + "rel_times": rel_times, + }) + soap_tica = Insight(tica_ds, meta=meta) + + if tica_path: + soap_tica.dump_to_json(tica_path) return soap_tica @@ -224,27 +220,24 @@ parameters, and computes the corresponding timeSOAP dataset. n_core: int = 1, ) -> Insight: if tsoap_path is not None and tsoap_path.exists(): - tsoap = Insight.load_from_json(tsoap_path) - else: - if soap_path is not None and soap_path.exists(): - soap = Insight.load_from_json(soap_path) - else: - soap = trj.get_soap( - r_cut=r_cut, - n_max=n_max, - l_max=l_max, - selection=selection, - centers=centers, - respect_pbc=respect_pbc, - n_core=n_core, - ) - if soap_path is not None: - soap.dump_to_json(soap_path) - - tsoap = soap.get_angular_velocity(delay=delay) - - if tsoap_path is not None: - tsoap.dump_to_json(tsoap_path) + return Insight.load_from_json(tsoap_path) + + soap = load_or_compute_soap( + trj=trj, + r_cut=r_cut, + n_max=n_max, + l_max=l_max, + selection=selection, + centers=centers, + respect_pbc=respect_pbc, + n_core=n_core, + soap_path=soap_path, + ) + + tsoap = soap.get_angular_velocity(delay=delay) + + if tsoap_path: + tsoap.dump_to_json(tsoap_path) return tsoap diff --git a/src/dynsight/_internal/utilities/utilities.py b/src/dynsight/_internal/utilities/utilities.py index 442f5125..1b3bd278 100644 --- a/src/dynsight/_internal/utilities/utilities.py +++ b/src/dynsight/_internal/utilities/utilities.py @@ -1,9 +1,16 @@ -from typing import Literal +from __future__ import annotations + +from typing import TYPE_CHECKING, Literal + +if TYPE_CHECKING: + from pathlib import Path import numpy as np import numpy.typing as npt from scipy.signal import find_peaks +from dynsight.trajectory import Insight, Trj + def normalize_array(x: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]: """Normalizes the further axis of the given array. @@ -56,3 +63,38 @@ def find_extrema_points( minima_xcoord = x_axis[peaks] minima_ycoord = y_axis[peaks] return np.column_stack((minima_xcoord, minima_ycoord)) + + +def load_or_compute_soap( + trj: Trj, + r_cut: float, + n_max: int, + l_max: int, + selection: str = "all", + centers: str = "all", + respect_pbc: bool = True, + n_core: int = 1, + soap_path: Path | None = None, +) -> Insight: + """Load SOAP descriptors from file if available, otherwise compute it. + + Returns: + Insight object containing SOAP descriptors. + """ + if soap_path and soap_path.exists(): + return Insight.load_from_json(soap_path) + + soap = trj.get_soap( + r_cut=r_cut, + n_max=n_max, + l_max=l_max, + selection=selection, + centers=centers, + respect_pbc=respect_pbc, + n_core=n_core, + ) + + if soap_path: + soap.dump_to_json(soap_path) + + return soap diff --git a/src/dynsight/utilities.py b/src/dynsight/utilities.py index 081bdea1..b1315855 100644 --- a/src/dynsight/utilities.py +++ b/src/dynsight/utilities.py @@ -2,10 +2,12 @@ from dynsight._internal.utilities.utilities import ( find_extrema_points, + load_or_compute_soap, normalize_array, ) __all__ = [ "find_extrema_points", + "load_or_compute_soap", "normalize_array", ] From a8cbf3e6b11b8b5b44cc421a385924a413dc0a4c Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Wed, 2 Jul 2025 11:32:20 +0200 Subject: [PATCH 06/42] Some improvements in docs. --- docs/source/soap_dim_red.rst | 3 ++- src/dynsight/_internal/utilities/utilities.py | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/source/soap_dim_red.rst b/docs/source/soap_dim_red.rst index 4c49e860..525bd59a 100644 --- a/docs/source/soap_dim_red.rst +++ b/docs/source/soap_dim_red.rst @@ -9,7 +9,8 @@ descriptors are always stored in an :class:`.trajectory.Insight` variable. All the functions take as optional parameters one or more file paths; if these paths are passed, the function, before computing some quantity from scratch, tries to load it from file, in case it has already been previously computed -and saved. +and saved. For SOAP, whic is required in all the examples, we use a function +from dynsight.utilities. Please remember that the SOAP dataset can be very large, due to the high dimensionality, thus calculations can be expensive, and saving to/loading from diff --git a/src/dynsight/_internal/utilities/utilities.py b/src/dynsight/_internal/utilities/utilities.py index 1b3bd278..877c4ea0 100644 --- a/src/dynsight/_internal/utilities/utilities.py +++ b/src/dynsight/_internal/utilities/utilities.py @@ -76,7 +76,11 @@ def load_or_compute_soap( n_core: int = 1, soap_path: Path | None = None, ) -> Insight: - """Load SOAP descriptors from file if available, otherwise compute it. + """Load or compute SOAP. + + If a valid path to a .json file with a SOAP Insight is provided, that + Insight is loaded and returned. Otherwise, the Insight is computed from + the Trj. Returns: Insight object containing SOAP descriptors. From 5d92f8761e7b6f027e17872544ea3cea628f0281 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Wed, 2 Jul 2025 11:34:47 +0200 Subject: [PATCH 07/42] Improved code readibility. --- docs/source/soap_dim_red.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/soap_dim_red.rst b/docs/source/soap_dim_red.rst index 525bd59a..714ca4a7 100644 --- a/docs/source/soap_dim_red.rst +++ b/docs/source/soap_dim_red.rst @@ -139,7 +139,7 @@ parameters, and performs the TICA of the corresponding SOAP dataset. respect_pbc: bool = True, n_core: int = 1, ) -> Insight: - if tica_path is not None and tica_path.exists(): + if tica_path and tica_path.exists(): return Insight.load_from_json(tica_path) soap = load_or_compute_soap( @@ -220,7 +220,7 @@ parameters, and computes the corresponding timeSOAP dataset. respect_pbc: bool = True, n_core: int = 1, ) -> Insight: - if tsoap_path is not None and tsoap_path.exists(): + if tsoap_path and tsoap_path.exists(): return Insight.load_from_json(tsoap_path) soap = load_or_compute_soap( From 10f3960e5816c5a0833b1239fdb2652b98d7f594 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Thu, 3 Jul 2025 10:36:22 +0200 Subject: [PATCH 08/42] WIP on the third recipe. --- docs/source/index.rst | 1 + docs/source/tmp_info_gain.rst | 268 ++++++++++++++++++++++++++++++++++ 2 files changed, 269 insertions(+) create mode 100644 docs/source/tmp_info_gain.rst diff --git a/docs/source/index.rst b/docs/source/index.rst index 25f42415..1b098029 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -20,6 +20,7 @@ Descriptors from a Trj Dimensionality reduction methods + Information gain analysis .. toctree:: :hidden: diff --git a/docs/source/tmp_info_gain.rst b/docs/source/tmp_info_gain.rst new file mode 100644 index 00000000..dbda64aa --- /dev/null +++ b/docs/source/tmp_info_gain.rst @@ -0,0 +1,268 @@ +Information gain analysis +========================= + +For the theoretical aspects of this work, see INSERT REF. + +This recipe explains how to compute the information gain through clustering +analysis. The LENS descriptor is computed on a many-body trajectory, and then +onion clustering is run on a broad range of time resolutions ∆t. The +information gain and the Shannon entropy of the environments is computed for +each value of ∆t. The analysis is implemented using both onion 1.0.13 and +2.0.0 ("onion smooth"). + +Let's start by creating a :class:`.trajectory.Trj` and computing LENS: + +.. testcode:: recipe3-test + + from pathlib import Path + from dynsight.trajectory import Trj + + # Loading an example trajectory + files_path = Path("../tests/systems/") + trj = Trj.init_from_xtc( + traj_file=files_path / "balls_7_nvt.xtc", + topo_file=files_path / "balls_7_nvt.gro", + ) + + _, lens = trj.get_lens( + r_cut=10.0, # cutoff radius for neighbors list + selection="all", # compute on a selection of particles + neigcounts=neigcounts, # no need to compute it again + ) + + + +Now, we want to simulate the Langevin Dynamics. We start defining the potential energy landscapes, with two and four minima. + +.. code-block:: python + + def energy_landscape_1(x: float, y: float) -> float: + """A potential energy landscape with 2 minima.""" + sigma = 0.12 # Width of the Gaussian wells + gauss1 = np.exp(-(x**2 + y**2) / (2 * sigma**2)) + gauss2 = np.exp(-(x**2 + (y - 1) ** 2) / (2 * sigma**2)) + return -np.log(gauss1 + gauss2 + 1e-6) + + + def energy_landscape_2(x: float, y: float) -> float: + """A potential energy landscape with 4 minima.""" + sigma = 0.12 # Width of the Gaussian wells + gauss1 = np.exp(-(x**2 + y**2) / (2 * sigma**2)) + gauss2 = np.exp(-((x - 1) ** 2 + y**2) / (2 * sigma**2)) + gauss3 = np.exp(-(x**2 + (y - 1) ** 2) / (2 * sigma**2)) + gauss4 = np.exp(-((x - 1) ** 2 + (y - 1) ** 2) / (2 * sigma**2)) + return -np.log(gauss1 + gauss2 + gauss3 + gauss4 + 1e-6) + + +To compute the force acting on the particle, we need to compute the potential energy gradient. + +.. code-block:: python + + def numerical_gradient( + f: Callable[[float, float], float], x: float, y: float, h: float = 1e-5 + ) -> tuple[float, float]: + """Compute numerical gradient using finite differences.""" + grad_x = (f(x + h, y) - f(x - h, y)) / (2 * h) + grad_y = (f(x, y + h) - f(x, y - h)) / (2 * h) + return -grad_x, -grad_y + + +This function simulates, for both energy landscapes, the dynamics of 100 particles for 10000 timesteps. Particles are initialized close to the minima. + +.. code-block:: python + + def create_trajectory( + energy_landscape: Callable[[float, float], float], file_name: Path + ) -> np.ndarray: + """Simulate Langevin Dynamics on a given energy landscape.""" + rng = np.random.default_rng(0) + n_atoms = 100 + time_steps = 10000 + dt = 0.01 # Time step + diffusion_coeff = 0.6 # Diffusion coefficient (random noise strength) + + if energy_landscape == energy_landscape_1: + particles = rng.standard_normal((n_atoms, 2)) * 0.2 + particles[n_atoms // 2 :, 1] += 1.0 + else: + particles = rng.standard_normal((n_atoms, 2)) * 0.2 + n_group = n_atoms // 4 + particles[n_group : 2 * n_group, 1] += 1 # (0, 1) + particles[2 * n_group : 3 * n_group, 0] += 1 # (1, 0) + particles[3 * n_group :, 0] += 1 # (1, 1) + particles[3 * n_group :, 1] += 1 + + trajectory = np.zeros((time_steps, n_atoms, 2)) + for t in range(time_steps): + for i in range(n_atoms): + x, y = particles[i] + fx, fy = numerical_gradient(energy_landscape, x, y) + noise_x = np.sqrt(2 * diffusion_coeff * dt) * rng.standard_normal() + noise_y = np.sqrt(2 * diffusion_coeff * dt) * rng.standard_normal() + + # Update position with deterministic force and stochastic term + particles[i, 0] += fx * dt + noise_x + particles[i, 1] += fy * dt + noise_y + + trajectory[t, i] = particles[i] + + plt.figure() + plt.plot(trajectory[:, :, 0], trajectory[:, :, 1]) + plt.show() + + dataset = np.transpose(trajectory, (1, 0, 2)) + np.save(filename, dataset) + return dataset + + +Let's simulate the trajectories and store them in two variables. We also save them as .npy files so that we don't have to simulate them every time. + +.. code-block:: python + + file_1 = folder_path / "trj_2.npy" # With 2 minima + file_2 = folder_path / "trj_4.npy" # With 4 minima + + if not file_1.exists(): + dataset_1 = create_trajectory(energy_landscape_1, file_1) + + dataset_1 = np.load(file_1) + + if not file_2.exists(): + dataset_2 = create_trajectory(energy_landscape_2, file_2) + + dataset_2 = np.load(file_2) + + +Now that we have the trajectories, we can, for each one, perform Onion clustering and computing the corresponding information gain, using either + +- only the y coordinate, or +- both x and y coordinates + +For each case, we do the analysis for a range of values of the Onion clustering time resolution ∆t. The information gain for each analysis is saved in the variable "results". +To check if the clustering is working in a meaningful way, we also plot the results of Onion clustering for one specific value of ∆t. + + +.. code-block:: python + + delta_t_list = np.unique(np.geomspace(2, 1000, 45, dtype=int)) + results = np.zeros((4, delta_t_list.size)) + example_delta_t = 4 # Choosing a ∆t which works well to plot results + + for i, dataset in enumerate([dataset_1, dataset_2]): + n_atoms, n_frames, n_dims = dataset.shape + + # We can do clustering using only the y variable: + y_positions = dataset[:, :, 1] + info_gain_y = np.zeros(delta_t_list.size) + + for j, delta_t in enumerate(delta_t_list): + reshaped_data = dynsight.onion.helpers.reshape_from_nt( + y_positions, delta_t + ) + state_list, labels = dynsight.onion.onion_uni(reshaped_data) + + if j == example_delta_t: + dynsight.onion.plot.plot_output_uni( + f"Example_{i}_1D.png", + reshaped_data, + n_atoms, + state_list, + ) + + # and compute the information gain: + info_gain_y[j], *_ = dynsight.analysis.compute_entropy_gain( + reshaped_data, labels, n_bins=40 + ) + results.append(info_gain_y) + + # Or we can do clustering using both (x, y) variables: + info_gain_xy = np.zeros(delta_t_list.size) + tmp1_dataset = np.transpose(dataset, (2, 0, 1)) + for j, delta_t in enumerate(delta_t_list): + reshaped_data = dynsight.onion.helpers.reshape_from_dnt( + tmp1_dataset, delta_t + ) + state_list, labels = dynsight.onion.onion_multi(reshaped_data) + + if j == example_delta_t: + dynsight.onion.plot.plot_output_multi( + f"Example_{i}_2D.png", + tmp1_dataset, + state_list, + labels, + delta_t, + ) + + # and compute the information gain: + # We need an array (n_samples, n_dims), and labels (n_samples,) + n_sequences = int(n_frames / delta_t) + long_labels = np.repeat(labels, delta_t) + tmp = dataset[:, : n_sequences * delta_t, :] + ds_reshaped = tmp.reshape((-1, n_dims)) + + info_gain_xy[j], *_ = dynsight.analysis.compute_entropy_gain_multi( + ds_reshaped, long_labels, n_bins=[40, 40] + ) + # Need to multiply by two because it's 2 dimensional, and the output + # of the info_gain functions is normalized by the log volume of the + # phase space, which is 2D is doubled + info_gain_xy *= 2 + results.append(info_gain_xy) + + +Here are the plots of the two datasets, with the different clusters identified when clustering the full, bi-dimensional data, using ∆t = 4 frames: + +.. list-table:: + :widths: auto + :align: center + + * - .. image:: _static/info_gain_clusters_1d.png + - .. image:: _static/info_gain_clusters_2d.png + + +As can be seen, all the clusters are correctly identified at this time resolution ∆t. When we are using only the y-coordinate instead, as expected in both cases just two clusters can be identified (the two plots look the same but they are actually from the two different systems): + +.. list-table:: + :widths: auto + :align: center + + * - .. image:: _static/info_gain_clusters_1d_y.png + - .. image:: _static/info_gain_clusters_2d_y.png + + +We can now plot, for every case and for every choice of ∆t, the corresponding information gain. + +.. code-block:: python + + colorlist = ["C0", "C2", "C1", "C3"] + markerlist = ["s", "o", "d", "o"] + labellist = [ + "2 peaks - 1D clustering", + "2 peaks - 2D clustering", + "4 peaks - 1D clustering", + "4 peaks - 2D clustering", + ] + + fig, ax = plt.subplots() + for i, system in enumerate(results): + ax.plot( + delta_t_list, + system, + label=labellist[i], + c=colorlist[i], + marker=markerlist[i], + ) + + ax.set_xlabel(r"Time resolution $\Delta t$ [frame]") + ax.set_ylabel(r"Information gain $\Delta H$ [bit]") + ax.set_xscale("log") + ax.legend() + plt.show() + +As can be seen in the plot below, clustering both datasets using only the y coordinate gives the same information gain, because only two clusters can be distinguished. + +Clustering the trajectories in the energy potential with two minima using both variables gives once again the same information gain for small values of ∆t; then, the clustering performance degrades because the fraction of classifiable data points starts to decreases. + +Finally, clustering the trajectories in the energy potential with four minima using both variables gives an information gain which is double the previous ones (at least for small ∆t), which makes sense, because 4 clusters are discovered instead of 2. For larger ∆t, we see the same degrading in performance that always affects clustering on multivariate distributions. + +.. image:: _static/Information_gains.png From 8a6c3547db7be95fdbde8a52e58275e357f66354 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Thu, 3 Jul 2025 14:02:18 +0200 Subject: [PATCH 09/42] WIP for info_gain recipe. --- docs/source/tmp_info_gain.rst | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/source/tmp_info_gain.rst b/docs/source/tmp_info_gain.rst index dbda64aa..603b9f6a 100644 --- a/docs/source/tmp_info_gain.rst +++ b/docs/source/tmp_info_gain.rst @@ -24,11 +24,7 @@ Let's start by creating a :class:`.trajectory.Trj` and computing LENS: topo_file=files_path / "balls_7_nvt.gro", ) - _, lens = trj.get_lens( - r_cut=10.0, # cutoff radius for neighbors list - selection="all", # compute on a selection of particles - neigcounts=neigcounts, # no need to compute it again - ) + _, lens = trj.get_lens(r_cut=10.0) From 91f645052aaf49e15da01258ade9112cfd5f7a3e Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Thu, 3 Jul 2025 14:36:29 +0200 Subject: [PATCH 10/42] Logging class implemented. --- src/dynsight/__init__.py | 2 ++ src/dynsight/_internal/logs.py | 29 +++++++++++++++++++ .../_internal/trajectory/trajectory.py | 2 ++ src/dynsight/logs.py | 7 +++++ tests/trajectory/test_trj.py | 2 ++ 5 files changed, 42 insertions(+) create mode 100644 src/dynsight/_internal/logs.py create mode 100644 src/dynsight/logs.py diff --git a/src/dynsight/__init__.py b/src/dynsight/__init__.py index 36bc1232..0d970042 100644 --- a/src/dynsight/__init__.py +++ b/src/dynsight/__init__.py @@ -5,6 +5,7 @@ data_processing, hdf5er, lens, + logs, onion, soap, tica, @@ -18,6 +19,7 @@ "data_processing", "hdf5er", "lens", + "logs", "onion", "soap", "tica", diff --git a/src/dynsight/_internal/logs.py b/src/dynsight/_internal/logs.py new file mode 100644 index 00000000..6bf9afe6 --- /dev/null +++ b/src/dynsight/_internal/logs.py @@ -0,0 +1,29 @@ +"""logging package.""" + +from datetime import datetime, timezone +from pathlib import Path + + +class Logger: + """Creates and save human-readible log.""" + + def __init__(self) -> None: + self._log: list[str] = [] + + def log(self, msg: str) -> None: + timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S") + entry = f"[{timestamp}] {msg}" + self._log.append(entry) + + def save(self, filename: Path) -> None: + with filename.open("w", encoding="utf-8") as f: + f.write("\n".join(self._log)) + + def clear(self) -> None: + self._log = [] + + def get(self) -> str: + return "\n".join(self._log) + + +logger = Logger() diff --git a/src/dynsight/_internal/trajectory/trajectory.py b/src/dynsight/_internal/trajectory/trajectory.py index 58156fcf..82c9ae5d 100644 --- a/src/dynsight/_internal/trajectory/trajectory.py +++ b/src/dynsight/_internal/trajectory/trajectory.py @@ -15,6 +15,7 @@ from MDAnalysis.coordinates.memory import MemoryReader import dynsight +from dynsight.logs import logger from dynsight.trajectory import Insight UNIVAR_DIM = 2 @@ -42,6 +43,7 @@ def init_from_universe(cls, universe: MDAnalysis.Universe) -> Trj: See https://docs.mdanalysis.org/2.9.0/documentation_pages/core/universe.html#MDAnalysis.core.universe.Universe. """ + logger.log("Created Trj from MDAnalysis.Universe.") return Trj(universe) @classmethod diff --git a/src/dynsight/logs.py b/src/dynsight/logs.py new file mode 100644 index 00000000..00128318 --- /dev/null +++ b/src/dynsight/logs.py @@ -0,0 +1,7 @@ +"""logging package.""" + +from dynsight._internal.logs import logger + +__all__ = [ + "logger", +] diff --git a/tests/trajectory/test_trj.py b/tests/trajectory/test_trj.py index 1b504037..341d7d82 100644 --- a/tests/trajectory/test_trj.py +++ b/tests/trajectory/test_trj.py @@ -8,6 +8,7 @@ import numpy as np import pytest +from dynsight.logs import logger from dynsight.trajectory import ( ClusterInsight, Insight, @@ -53,6 +54,7 @@ def test_trj_inits( assert len(trj_1.universe.trajectory) == n_frames_xyz trj_2 = Trj.init_from_universe(universe) + logger.get() assert len(trj_2.universe.trajectory) == n_frames_xyz trj_3 = Trj.init_from_xyz(file_paths["xyz"], dt=1) From 05d6fdcb6e2da38fd2c78a9bf766e469999f1b7b Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Thu, 3 Jul 2025 14:50:30 +0200 Subject: [PATCH 11/42] Added logging to Trj class. --- src/dynsight/_internal/trajectory/trajectory.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/dynsight/_internal/trajectory/trajectory.py b/src/dynsight/_internal/trajectory/trajectory.py index 82c9ae5d..eb15deca 100644 --- a/src/dynsight/_internal/trajectory/trajectory.py +++ b/src/dynsight/_internal/trajectory/trajectory.py @@ -55,6 +55,7 @@ def init_from_xyz(cls, traj_file: Path, dt: float) -> Trj: Parameters: dt: the trajectory's time-step. """ + logger.log(f"Created Trj from {traj_file} with dt = {dt}.") universe = MDAnalysis.Universe(traj_file, dt=dt) return Trj(universe) @@ -64,6 +65,7 @@ def init_from_xtc(cls, traj_file: Path, topo_file: Path) -> Trj: See https://docs.mdanalysis.org/2.9.0/documentation_pages/core/universe.html#MDAnalysis.core.universe.Universe. """ + logger.log(f"Created Trj from {traj_file}, {topo_file}.") universe = MDAnalysis.Universe(topo_file, traj_file) return Trj(universe) @@ -72,6 +74,7 @@ def get_coordinates(self, selection: str) -> NDArray[np.float64]: The array has shape (n_frames, n_atoms, n_coordinates). """ + logger.log(f"Extracted coordinates array for {selection} atoms.") atoms = self.universe.select_atoms(selection) trajslice = slice(None) if self.trajslice is None else self.trajslice @@ -84,6 +87,7 @@ def get_coordinates(self, selection: str) -> NDArray[np.float64]: def with_slice(self, trajslice: slice | None) -> Trj: """Returns a Trj with a different frames' slice.""" + logger.log(f"Created a sliced Trj with {trajslice}.") return Trj(self.universe, trajslice=trajslice) def get_slice(self, start: int, stop: int, step: int) -> Trj: @@ -106,6 +110,7 @@ def get_slice(self, start: int, stop: int, step: int) -> Trj: u_new = MDAnalysis.Universe(topology=self.universe._topology) # noqa: SLF001 u_new.trajectory = mem_reader + logger.log(f"Created a sliced Trj with ({start}, {stop}, {step}).") return Trj(u_new) def get_coord_number( @@ -130,6 +135,10 @@ def get_coord_number( trajslice=self.trajslice, ) _, nn, *_ = dynsight.lens.neighbour_change_in_time(neigcounts) + logger.log( + f"Computed coord_number using cutoff {r_cut} for " + f"{selection} atoms." + ) return neigcounts, Insight( dataset=nn.astype(np.float64), meta={"r_cut": r_cut, "selection": selection}, @@ -157,6 +166,9 @@ def get_lens( trajslice=self.trajslice, ) lens, *_ = dynsight.lens.neighbour_change_in_time(neigcounts) + logger.log( + f"Computed LENS using cutoff {r_cut} for {selection} atoms." + ) return neigcounts, Insight( dataset=lens[:, 1:], meta={"r_cut": r_cut, "selection": selection}, @@ -196,6 +208,7 @@ def get_soap( "selection": selection, "centers": centers, } + logger.log(f"Computed SOAP with parameters {attr_dict}.") return Insight(dataset=soap, meta=attr_dict) def get_rdf( @@ -236,4 +249,5 @@ def get_rdf( "nbins": nbins, "norm": norm, } + logger.log(f"Computed g(r) with parameters {attr_dict}.") return Insight(dataset=dataset, meta=attr_dict) From 27d0e81ce44bec5e0b6d8942af00741f6e842277 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Thu, 3 Jul 2025 15:07:30 +0200 Subject: [PATCH 12/42] Added deeptime dependecies. --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b1949aee..180ec4cf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ maintainers = [ { name = "Simone Martino", email = "s.martino0898@gmail.com" }, ] -dependencies = ["numpy", "dscribe", "tropea-clustering", "MDAnalysis"] +dependencies = ["numpy", "dscribe", "tropea-clustering", "MDAnalysis", "deeptime"] # Set by cpctools. requires-python = ">=3.8" dynamic = ["version"] @@ -111,5 +111,6 @@ module = [ 'ultralytics.*', 'opencv-python.*', 'cv2.*', + 'deeptime.*', ] ignore_missing_imports = true From aee3046cf29a6fe1149c73d00fd89d1ffbd3401f Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Fri, 4 Jul 2025 14:58:24 +0200 Subject: [PATCH 13/42] Logging added to Insight methods. --- src/dynsight/_internal/trajectory/insight.py | 47 ++++++++++++++------ 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/src/dynsight/_internal/trajectory/insight.py b/src/dynsight/_internal/trajectory/insight.py index 27bbbb3f..aa8325f9 100644 --- a/src/dynsight/_internal/trajectory/insight.py +++ b/src/dynsight/_internal/trajectory/insight.py @@ -14,6 +14,7 @@ from dynsight.trajectory import Trj import dynsight +from dynsight.logs import logger from dynsight.trajectory import OnionInsight, OnionSmoothInsight UNIVAR_DIM = 2 @@ -37,6 +38,7 @@ def dump_to_json(self, file_path: Path) -> None: data["dataset"] = data["dataset"].tolist() with file_path.open("w") as file: json.dump(data, file, indent=4) + logger.log(f"Insight saved to {file_path}.") @classmethod def load_from_json(cls, file_path: Path) -> Insight: @@ -52,6 +54,7 @@ def load_from_json(cls, file_path: Path) -> Insight: msg = "'dataset' key not found in JSON file." raise ValueError(msg) + logger.log(f"Insight loaded from {file_path}.") return cls( dataset=np.array(data.get("dataset"), dtype=np.float64), meta=data.get("meta"), @@ -77,9 +80,12 @@ def spatial_average( trajslice=trj.trajslice, num_processes=num_processes, ) + attr_dict = {"sp_av_r_cut": r_cut, "selection": selection} + + logger.log(f"Computed spatial average with args {attr_dict}.") return Insight( dataset=averaged_dataset, - meta={"sp_av_r_cut": r_cut, "selection": selection}, + meta=attr_dict, ) def get_time_correlation( @@ -87,6 +93,9 @@ def get_time_correlation( max_delay: int | None = None, ) -> tuple[NDArray[np.float64], NDArray[np.float64]]: """Self time correlation function of the time-series signal.""" + logger.log( + f"Computed time corrleation function with max_delay = {max_delay}." + ) return dynsight.analysis.self_time_correlation( self.dataset, max_delay, @@ -104,6 +113,8 @@ def get_angular_velocity(self, delay: int = 1) -> Insight: theta = dynsight.soap.timesoap(self.dataset, delay=delay) attr_dict = self.meta.copy() attr_dict.update({"delay": delay}) + + logger.log(f"Computed angular velocity with delay {delay}.") return Insight(dataset=theta, meta=attr_dict) def get_onion( @@ -136,16 +147,18 @@ def get_onion( ) onion_clust.fit(reshaped_data) + attr_dict = { + "delta_t": delta_t, + "bins": bins, + "number_of_sigmas": number_of_sigmas, + } + logger.log(f"Performed onion clustering with args {attr_dict}.") return OnionInsight( labels=onion_clust.labels_, state_list=onion_clust.state_list_, reshaped_data=reshaped_data, - meta={ - "delta_t": delta_t, - "bins": bins, - "number_of_sigmas": number_of_sigmas, - }, + meta=attr_dict, ) def get_onion_smooth( @@ -175,16 +188,18 @@ def get_onion_smooth( ) onion_clust.fit(self.dataset) - + attr_dict = { + "delta_t": delta_t, + "bins": bins, + "number_of_sigmas": number_of_sigmas, + "max_area_overlap": max_area_overlap, + } + + logger.log(f"Performed onion clustering smooth with args {attr_dict}.") return OnionSmoothInsight( labels=onion_clust.labels_, state_list=onion_clust.state_list_, - meta={ - "delta_t": delta_t, - "bins": bins, - "number_of_sigmas": number_of_sigmas, - "max_area_overlap": max_area_overlap, - }, + meta=attr_dict, ) def get_onion_analysis( @@ -264,4 +279,10 @@ def get_onion_analysis( fig2_path, list_of_pop, tra ) + logger.log( + f"Performed full onion clustering analysis with args " + f"{delta_t_min}, {delta_t_max}, {delta_t_num}, " + f"{fig1_path}, {fig2_path}, {bins}, {number_of_sigmas}, " + f"{max_area_overlap}." + ) return delta_t_list, n_clust, unclass_frac From 2b3ead352c3c96766a76e14d6635078875fdc8f1 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Fri, 4 Jul 2025 15:01:35 +0200 Subject: [PATCH 14/42] Added pytests for logging. --- tests/trajectory/test_trj.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/trajectory/test_trj.py b/tests/trajectory/test_trj.py index 341d7d82..0f673e29 100644 --- a/tests/trajectory/test_trj.py +++ b/tests/trajectory/test_trj.py @@ -54,7 +54,6 @@ def test_trj_inits( assert len(trj_1.universe.trajectory) == n_frames_xyz trj_2 = Trj.init_from_universe(universe) - logger.get() assert len(trj_2.universe.trajectory) == n_frames_xyz trj_3 = Trj.init_from_xyz(file_paths["xyz"], dt=1) @@ -63,6 +62,8 @@ def test_trj_inits( trj_4 = Trj.init_from_xtc(file_paths["xtc"], file_paths["gro"]) assert len(trj_4.universe.trajectory) == n_frames_xtc + logger.get() + def test_insight( tmp_path: Path, file_paths: dict[str, Path], universe: MDAnalysis.Universe @@ -105,6 +106,8 @@ def test_insight( loaded_onion_smooth = OnionSmoothInsight.load_from_json(onion_smooth_json) assert loaded_onion_smooth is not None + logger.get() + def test_onion_analysis(universe: MDAnalysis.Universe) -> None: """Test the onion clustering complete analysis tool.""" @@ -134,3 +137,5 @@ def test_insight_load_errors(file_paths: dict[str, Path]) -> None: _ = OnionInsight.load_from_json( file_paths["files_dir"] / "cl_ins_test.json" ) + + logger.get() From b34f93b99967539c115f3d8f8079695acafefc00 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Fri, 4 Jul 2025 15:04:41 +0200 Subject: [PATCH 15/42] deeptime dependecies is now automatically installed. --- README.rst | 9 --------- 1 file changed, 9 deletions(-) diff --git a/README.rst b/README.rst index 97d3920d..43464534 100644 --- a/README.rst +++ b/README.rst @@ -34,15 +34,6 @@ you are using Python 3.10 and below, you can use ``cpctools`` to access $ pip install cpctools -If you want to use the ``dynsight.tica`` module you will need to install the -deeptime package. This can be done with with pip:: - - $ pip install deeptime - -or with conda:: - - $ conda install -c conda-forge deeptime - If you want to use the ``dynsight.vision`` and ``dynsight.track`` modules you will need to install a series of packages. This can be done with with pip:: From e2395a9745bca22a8742510ca6d408f870799653 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Fri, 4 Jul 2025 15:06:27 +0200 Subject: [PATCH 16/42] deeptime dependecies is now automatically installed. --- docs/source/index.rst | 9 --------- 1 file changed, 9 deletions(-) diff --git a/docs/source/index.rst b/docs/source/index.rst index 1b098029..f30955d0 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -72,15 +72,6 @@ you are using Python 3.10 and below, you can use :mod:`cpctools` to access $ pip install cpctools -If you want to use the :mod:`dynsight.tica` module you will need to install the -deeptime package. This can be done with with pip:: - - $ pip install deeptime - -or with conda:: - - $ conda install -c conda-forge deeptime - If you want to use the :mod:`dynsight.vision` and :mod:`dynsight.track` modules you will need to install a series of packages. This can be done with with pip:: From d470bf807baa4eb5437d2071f8bcdddf91b3dcc8 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Mon, 7 Jul 2025 15:05:46 +0200 Subject: [PATCH 17/42] Explicitly saing 'is not None' for file paths. --- docs/source/soap_dim_red.rst | 12 ++++++------ src/dynsight/_internal/utilities/utilities.py | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/source/soap_dim_red.rst b/docs/source/soap_dim_red.rst index 714ca4a7..eac5aa42 100644 --- a/docs/source/soap_dim_red.rst +++ b/docs/source/soap_dim_red.rst @@ -63,7 +63,7 @@ parameters, and performs the PCA of the corresponding SOAP dataset. respect_pbc: bool = True, n_core: int = 1, ) -> Insight: - if pca_path and pca_path.exists(): + if pca_path is not None and pca_path.exists(): return Insight.load_from_json(pca_path) soap = load_or_compute_soap( @@ -86,7 +86,7 @@ parameters, and performs the PCA of the corresponding SOAP dataset. soap_pca = Insight(pca_ds, meta=soap.meta.copy()) - if pca_path: + if pca_path is not None: soap_pca.dump_to_json(pca_path) return soap_pca @@ -139,7 +139,7 @@ parameters, and performs the TICA of the corresponding SOAP dataset. respect_pbc: bool = True, n_core: int = 1, ) -> Insight: - if tica_path and tica_path.exists(): + if tica_path is not None and tica_path.exists(): return Insight.load_from_json(tica_path) soap = load_or_compute_soap( @@ -167,7 +167,7 @@ parameters, and performs the TICA of the corresponding SOAP dataset. }) soap_tica = Insight(tica_ds, meta=meta) - if tica_path: + if tica_path is not None: soap_tica.dump_to_json(tica_path) return soap_tica @@ -220,7 +220,7 @@ parameters, and computes the corresponding timeSOAP dataset. respect_pbc: bool = True, n_core: int = 1, ) -> Insight: - if tsoap_path and tsoap_path.exists(): + if tsoap_path is not None and tsoap_path.exists(): return Insight.load_from_json(tsoap_path) soap = load_or_compute_soap( @@ -237,7 +237,7 @@ parameters, and computes the corresponding timeSOAP dataset. tsoap = soap.get_angular_velocity(delay=delay) - if tsoap_path: + if tsoap_path is not None: tsoap.dump_to_json(tsoap_path) return tsoap diff --git a/src/dynsight/_internal/utilities/utilities.py b/src/dynsight/_internal/utilities/utilities.py index 877c4ea0..8d521bfc 100644 --- a/src/dynsight/_internal/utilities/utilities.py +++ b/src/dynsight/_internal/utilities/utilities.py @@ -85,7 +85,7 @@ def load_or_compute_soap( Returns: Insight object containing SOAP descriptors. """ - if soap_path and soap_path.exists(): + if soap_path is not None and soap_path.exists(): return Insight.load_from_json(soap_path) soap = trj.get_soap( @@ -98,7 +98,7 @@ def load_or_compute_soap( n_core=n_core, ) - if soap_path: + if soap_path is not None: soap.dump_to_json(soap_path) return soap From e929dfee165e7c9f0f5f793d375bad1d7b164025 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Mon, 7 Jul 2025 15:17:38 +0200 Subject: [PATCH 18/42] Using standard dictionary for logging args in method calls. --- src/dynsight/_internal/trajectory/insight.py | 21 +++++++++---- .../_internal/trajectory/trajectory.py | 31 ++++++++++--------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/dynsight/_internal/trajectory/insight.py b/src/dynsight/_internal/trajectory/insight.py index aa8325f9..360d1b9d 100644 --- a/src/dynsight/_internal/trajectory/insight.py +++ b/src/dynsight/_internal/trajectory/insight.py @@ -93,8 +93,9 @@ def get_time_correlation( max_delay: int | None = None, ) -> tuple[NDArray[np.float64], NDArray[np.float64]]: """Self time correlation function of the time-series signal.""" + attr_dict = {"max_delay": max_delay} logger.log( - f"Computed time corrleation function with max_delay = {max_delay}." + f"Computed time corrleation function with args {attr_dict}." ) return dynsight.analysis.self_time_correlation( self.dataset, @@ -114,7 +115,7 @@ def get_angular_velocity(self, delay: int = 1) -> Insight: attr_dict = self.meta.copy() attr_dict.update({"delay": delay}) - logger.log(f"Computed angular velocity with delay {delay}.") + logger.log(f"Computed angular velocity with args {attr_dict}.") return Insight(dataset=theta, meta=attr_dict) def get_onion( @@ -279,10 +280,18 @@ def get_onion_analysis( fig2_path, list_of_pop, tra ) + attr_dict = { + "delta_t_min": delta_t_min, + "delta_t_max": delta_t_max, + "delta_t_num": delta_t_num, + "fig1_path": fig1_path, + "fig2_path": fig2_path, + "bins": bins, + "number_of_sigmas": number_of_sigmas, + "max_area_overlap": max_area_overlap, + } + logger.log( - f"Performed full onion clustering analysis with args " - f"{delta_t_min}, {delta_t_max}, {delta_t_num}, " - f"{fig1_path}, {fig2_path}, {bins}, {number_of_sigmas}, " - f"{max_area_overlap}." + f"Performed full onion clustering analysis with args {attr_dict}." ) return delta_t_list, n_clust, unclass_frac diff --git a/src/dynsight/_internal/trajectory/trajectory.py b/src/dynsight/_internal/trajectory/trajectory.py index eb15deca..a5467bcf 100644 --- a/src/dynsight/_internal/trajectory/trajectory.py +++ b/src/dynsight/_internal/trajectory/trajectory.py @@ -74,10 +74,11 @@ def get_coordinates(self, selection: str) -> NDArray[np.float64]: The array has shape (n_frames, n_atoms, n_coordinates). """ - logger.log(f"Extracted coordinates array for {selection} atoms.") atoms = self.universe.select_atoms(selection) trajslice = slice(None) if self.trajslice is None else self.trajslice + attr_dict = {"selection": selection} + logger.log(f"Extracted coordinates array with args {attr_dict}.") return np.array( [ atoms.positions.copy() @@ -87,7 +88,8 @@ def get_coordinates(self, selection: str) -> NDArray[np.float64]: def with_slice(self, trajslice: slice | None) -> Trj: """Returns a Trj with a different frames' slice.""" - logger.log(f"Created a sliced Trj with {trajslice}.") + attr_dict = {"trajslice": trajslice} + logger.log(f"Created a sliced Trj with args {attr_dict}.") return Trj(self.universe, trajslice=trajslice) def get_slice(self, start: int, stop: int, step: int) -> Trj: @@ -110,7 +112,8 @@ def get_slice(self, start: int, stop: int, step: int) -> Trj: u_new = MDAnalysis.Universe(topology=self.universe._topology) # noqa: SLF001 u_new.trajectory = mem_reader - logger.log(f"Created a sliced Trj with ({start}, {stop}, {step}).") + attr_dict = {"start": start, "stop": stop, "step": step} + logger.log(f"Created a sliced Trj with args {attr_dict}.") return Trj(u_new) def get_coord_number( @@ -135,13 +138,12 @@ def get_coord_number( trajslice=self.trajslice, ) _, nn, *_ = dynsight.lens.neighbour_change_in_time(neigcounts) - logger.log( - f"Computed coord_number using cutoff {r_cut} for " - f"{selection} atoms." - ) + + attr_dict = {"r_cut": r_cut, "selection": selection} + logger.log(f"Computed coord_number using args {attr_dict}.") return neigcounts, Insight( dataset=nn.astype(np.float64), - meta={"r_cut": r_cut, "selection": selection}, + meta=attr_dict, ) def get_lens( @@ -166,12 +168,13 @@ def get_lens( trajslice=self.trajslice, ) lens, *_ = dynsight.lens.neighbour_change_in_time(neigcounts) - logger.log( - f"Computed LENS using cutoff {r_cut} for {selection} atoms." - ) + + attr_dict = {"r_cut": r_cut, "selection": selection} + logger.log(f"Computed LENS using args {attr_dict}.") + return neigcounts, Insight( dataset=lens[:, 1:], - meta={"r_cut": r_cut, "selection": selection}, + meta=attr_dict, ) def get_soap( @@ -208,7 +211,7 @@ def get_soap( "selection": selection, "centers": centers, } - logger.log(f"Computed SOAP with parameters {attr_dict}.") + logger.log(f"Computed SOAP with args {attr_dict}.") return Insight(dataset=soap, meta=attr_dict) def get_rdf( @@ -249,5 +252,5 @@ def get_rdf( "nbins": nbins, "norm": norm, } - logger.log(f"Computed g(r) with parameters {attr_dict}.") + logger.log(f"Computed g(r) with args {attr_dict}.") return Insight(dataset=dataset, meta=attr_dict) From ff2c3bb645791b5653742ba67e2fe14bc1f28242 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Mon, 7 Jul 2025 15:30:04 +0200 Subject: [PATCH 19/42] Logging added to the ClusterInsight classes. --- .../_internal/trajectory/cluster_insight.py | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/dynsight/_internal/trajectory/cluster_insight.py b/src/dynsight/_internal/trajectory/cluster_insight.py index db4cce55..f1870e14 100644 --- a/src/dynsight/_internal/trajectory/cluster_insight.py +++ b/src/dynsight/_internal/trajectory/cluster_insight.py @@ -16,6 +16,7 @@ import dynsight +from dynsight.logs import logger UNIVAR_DIM = 2 @@ -36,6 +37,7 @@ def dump_to_json(self, file_path: Path) -> None: data["labels"] = data["labels"].tolist() with file_path.open("w") as file: json.dump(data, file, indent=4) + logger.log(f"ClusterInsight saved to {file_path}.") @classmethod def load_from_json(cls, file_path: Path) -> ClusterInsight: @@ -49,6 +51,8 @@ def load_from_json(cls, file_path: Path) -> ClusterInsight: if "labels" not in data: msg = "'labels' key not found in JSON file." raise ValueError(msg) + + logger.log(f"ClusterInsight loaded from {file_path}.") return cls(labels=np.array(data.get("labels"), dtype=np.int64)) @@ -89,6 +93,7 @@ def dump_to_json(self, file_path: Path) -> None: data["state_list"] = new_state_list with file_path.open("w") as file: json.dump(data, file, indent=4) + logger.log(f"OnionInsight saved to {file_path}.") @classmethod def load_from_json(cls, file_path: Path) -> OnionInsight: @@ -102,6 +107,8 @@ def load_from_json(cls, file_path: Path) -> OnionInsight: if "state_list" not in data: msg = "'state_list' key not found in JSON file." raise ValueError(msg) + + logger.log(f"OnionInsight loaded from {file_path}.") return cls( labels=np.array(data.get("labels")), state_list=data.get("state_list"), @@ -126,6 +133,8 @@ def plot_output(self, file_path: Path, data_insight: Insight) -> None: self.labels, self.meta["delta_t"], ) + attr_dict = {"file_path": file_path} + logger.log(f"plot_output() with args {attr_dict}.") def plot_one_trj( self, @@ -151,6 +160,9 @@ def plot_one_trj( self.labels, ) + attr_dict = {"file_path": file_path, "particle_id": particle_id} + logger.log(f"plot_one_trj() with args {attr_dict}.") + def plot_medoids(self, file_path: Path, data_insight: Insight) -> None: """Plot the average sequence of each onion cluster.""" if data_insight.dataset.ndim == UNIVAR_DIM: @@ -166,6 +178,8 @@ def plot_medoids(self, file_path: Path, data_insight: Insight) -> None: data_insight.dataset, self.labels, ) + attr_dict = {"file_path": file_path} + logger.log(f"plot_medoids() with args {attr_dict}.") def plot_state_populations( self, @@ -179,6 +193,8 @@ def plot_state_populations( self.meta["delta_t"], self.labels, ) + attr_dict = {"file_path": file_path} + logger.log(f"plot_state_populations() with args {attr_dict}.") def plot_sankey( self, @@ -194,6 +210,9 @@ def plot_sankey( frame_list, ) + attr_dict = {"file_path": file_path, "frame_list": frame_list} + logger.log(f"plot_state_populations() with args {attr_dict}.") + @dataclass(frozen=True) class OnionSmoothInsight(ClusterInsight): @@ -229,6 +248,7 @@ def dump_to_json(self, file_path: Path) -> None: data["state_list"] = new_state_list with file_path.open("w") as file: json.dump(data, file, indent=4) + logger.log(f"OnionSmoothInsight saved to {file_path}.") @classmethod def load_from_json(cls, file_path: Path) -> OnionSmoothInsight: @@ -242,6 +262,8 @@ def load_from_json(cls, file_path: Path) -> OnionSmoothInsight: if "state_list" not in data: msg = "'state_list' key not found in JSON file." raise ValueError(msg) + + logger.log(f"OnionSmoothInsight loaded from {file_path}.") return cls( labels=np.array(data.get("labels")), state_list=data.get("state_list"), @@ -263,6 +285,8 @@ def plot_output(self, file_path: Path, data_insight: Insight) -> None: self.state_list, self.labels, ) + attr_dict = {"file_path": file_path} + logger.log(f"plot_output() with args {attr_dict}.") def plot_one_trj( self, @@ -285,6 +309,8 @@ def plot_one_trj( data_insight.dataset, self.labels, ) + attr_dict = {"file_path": file_path, "particle_id": particle_id} + logger.log(f"plot_one_trj() with args {attr_dict}.") def plot_state_populations( self, @@ -295,6 +321,8 @@ def plot_state_populations( file_path, self.labels, ) + attr_dict = {"file_path": file_path} + logger.log(f"plot_state_populations() with args {attr_dict}.") def plot_sankey( self, @@ -307,6 +335,8 @@ def plot_sankey( self.labels, frame_list, ) + attr_dict = {"file_path": file_path, "frame_list": frame_list} + logger.log(f"plot_state_populations() with args {attr_dict}.") def dump_colored_trj(self, trj: Trj, file_path: Path) -> None: """Save an .xyz file with the clustering labels for each atom.""" @@ -335,3 +365,4 @@ def dump_colored_trj(self, trj: Trj, file_path: Path) -> None: f"{trj.universe.atoms[atom_idx].name} {x:.5f}" f" {y:.5f} {z:.5f} {label}\n" ) + logger.log(f"Colored trj saved to {file_path}.") From aba2279c668e9e545afa3ed35631921a0a972aa2 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Mon, 7 Jul 2025 15:32:18 +0200 Subject: [PATCH 20/42] Error raising added to logging. --- src/dynsight/_internal/trajectory/cluster_insight.py | 4 ++++ src/dynsight/_internal/trajectory/insight.py | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/dynsight/_internal/trajectory/cluster_insight.py b/src/dynsight/_internal/trajectory/cluster_insight.py index f1870e14..70d641cb 100644 --- a/src/dynsight/_internal/trajectory/cluster_insight.py +++ b/src/dynsight/_internal/trajectory/cluster_insight.py @@ -50,6 +50,7 @@ def load_from_json(cls, file_path: Path) -> ClusterInsight: data = json.load(file) if "labels" not in data: msg = "'labels' key not found in JSON file." + logger.log(msg) raise ValueError(msg) logger.log(f"ClusterInsight loaded from {file_path}.") @@ -106,6 +107,7 @@ def load_from_json(cls, file_path: Path) -> OnionInsight: data = json.load(file) if "state_list" not in data: msg = "'state_list' key not found in JSON file." + logger.log(msg) raise ValueError(msg) logger.log(f"OnionInsight loaded from {file_path}.") @@ -261,6 +263,7 @@ def load_from_json(cls, file_path: Path) -> OnionSmoothInsight: data = json.load(file) if "state_list" not in data: msg = "'state_list' key not found in JSON file." + logger.log(msg) raise ValueError(msg) logger.log(f"OnionSmoothInsight loaded from {file_path}.") @@ -352,6 +355,7 @@ def dump_colored_trj(self, trj: Trj, file_path: Path) -> None: f"atoms, {self.labels.shape[0]} frames, but has {n_atoms} " f"atoms, {n_frames} frames." ) + logger.log(msg) raise ValueError(msg) with file_path.open("w") as f: diff --git a/src/dynsight/_internal/trajectory/insight.py b/src/dynsight/_internal/trajectory/insight.py index 360d1b9d..181b30d9 100644 --- a/src/dynsight/_internal/trajectory/insight.py +++ b/src/dynsight/_internal/trajectory/insight.py @@ -52,6 +52,7 @@ def load_from_json(cls, file_path: Path) -> Insight: if "dataset" not in data: msg = "'dataset' key not found in JSON file." + logger.log(msg) raise ValueError(msg) logger.log(f"Insight loaded from {file_path}.") @@ -110,6 +111,7 @@ def get_angular_velocity(self, delay: int = 1) -> Insight: """ if self.dataset.ndim != UNIVAR_DIM + 1: msg = "dataset.ndim != 3." + logger.log(msg) raise ValueError(msg) theta = dynsight.soap.timesoap(self.dataset, delay=delay) attr_dict = self.meta.copy() From e597fb4ac32190a29d192e1ef5a17f84cb695a95 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Tue, 8 Jul 2025 10:15:24 +0200 Subject: [PATCH 21/42] WIP on third recipe. --- docs/source/tmp_info_gain.rst | 206 ++++------------------------------ 1 file changed, 21 insertions(+), 185 deletions(-) diff --git a/docs/source/tmp_info_gain.rst b/docs/source/tmp_info_gain.rst index 603b9f6a..4ccc4ffb 100644 --- a/docs/source/tmp_info_gain.rst +++ b/docs/source/tmp_info_gain.rst @@ -27,143 +27,37 @@ Let's start by creating a :class:`.trajectory.Trj` and computing LENS: _, lens = trj.get_lens(r_cut=10.0) +The following functions take as input the LENS dataset, and a list of values +of time resolutions ∆t, and for each of these perform Onion clustering, and +compute the information gain achieved through clustering with that ∆t. -Now, we want to simulate the Langevin Dynamics. We start defining the potential energy landscapes, with two and four minima. +DESCRIBE THE OUTPUT -.. code-block:: python +In this first function, the clustering is performed with the "old" onion +algorithm (time-series segmentation in consecutive windows): - def energy_landscape_1(x: float, y: float) -> float: - """A potential energy landscape with 2 minima.""" - sigma = 0.12 # Width of the Gaussian wells - gauss1 = np.exp(-(x**2 + y**2) / (2 * sigma**2)) - gauss2 = np.exp(-(x**2 + (y - 1) ** 2) / (2 * sigma**2)) - return -np.log(gauss1 + gauss2 + 1e-6) - - - def energy_landscape_2(x: float, y: float) -> float: - """A potential energy landscape with 4 minima.""" - sigma = 0.12 # Width of the Gaussian wells - gauss1 = np.exp(-(x**2 + y**2) / (2 * sigma**2)) - gauss2 = np.exp(-((x - 1) ** 2 + y**2) / (2 * sigma**2)) - gauss3 = np.exp(-(x**2 + (y - 1) ** 2) / (2 * sigma**2)) - gauss4 = np.exp(-((x - 1) ** 2 + (y - 1) ** 2) / (2 * sigma**2)) - return -np.log(gauss1 + gauss2 + gauss3 + gauss4 + 1e-6) - - -To compute the force acting on the particle, we need to compute the potential energy gradient. - -.. code-block:: python - - def numerical_gradient( - f: Callable[[float, float], float], x: float, y: float, h: float = 1e-5 - ) -> tuple[float, float]: - """Compute numerical gradient using finite differences.""" - grad_x = (f(x + h, y) - f(x - h, y)) / (2 * h) - grad_y = (f(x, y + h) - f(x, y - h)) / (2 * h) - return -grad_x, -grad_y - - -This function simulates, for both energy landscapes, the dynamics of 100 particles for 10000 timesteps. Particles are initialized close to the minima. - -.. code-block:: python - - def create_trajectory( - energy_landscape: Callable[[float, float], float], file_name: Path - ) -> np.ndarray: - """Simulate Langevin Dynamics on a given energy landscape.""" - rng = np.random.default_rng(0) - n_atoms = 100 - time_steps = 10000 - dt = 0.01 # Time step - diffusion_coeff = 0.6 # Diffusion coefficient (random noise strength) - - if energy_landscape == energy_landscape_1: - particles = rng.standard_normal((n_atoms, 2)) * 0.2 - particles[n_atoms // 2 :, 1] += 1.0 - else: - particles = rng.standard_normal((n_atoms, 2)) * 0.2 - n_group = n_atoms // 4 - particles[n_group : 2 * n_group, 1] += 1 # (0, 1) - particles[2 * n_group : 3 * n_group, 0] += 1 # (1, 0) - particles[3 * n_group :, 0] += 1 # (1, 1) - particles[3 * n_group :, 1] += 1 - - trajectory = np.zeros((time_steps, n_atoms, 2)) - for t in range(time_steps): - for i in range(n_atoms): - x, y = particles[i] - fx, fy = numerical_gradient(energy_landscape, x, y) - noise_x = np.sqrt(2 * diffusion_coeff * dt) * rng.standard_normal() - noise_y = np.sqrt(2 * diffusion_coeff * dt) * rng.standard_normal() - - # Update position with deterministic force and stochastic term - particles[i, 0] += fx * dt + noise_x - particles[i, 1] += fy * dt + noise_y - - trajectory[t, i] = particles[i] - - plt.figure() - plt.plot(trajectory[:, :, 0], trajectory[:, :, 1]) - plt.show() - - dataset = np.transpose(trajectory, (1, 0, 2)) - np.save(filename, dataset) - return dataset - - -Let's simulate the trajectories and store them in two variables. We also save them as .npy files so that we don't have to simulate them every time. - -.. code-block:: python - - file_1 = folder_path / "trj_2.npy" # With 2 minima - file_2 = folder_path / "trj_4.npy" # With 4 minima - - if not file_1.exists(): - dataset_1 = create_trajectory(energy_landscape_1, file_1) - - dataset_1 = np.load(file_1) - - if not file_2.exists(): - dataset_2 = create_trajectory(energy_landscape_2, file_2) - - dataset_2 = np.load(file_2) - - -Now that we have the trajectories, we can, for each one, perform Onion clustering and computing the corresponding information gain, using either - -- only the y coordinate, or -- both x and y coordinates - -For each case, we do the analysis for a range of values of the Onion clustering time resolution ∆t. The information gain for each analysis is saved in the variable "results". -To check if the clustering is working in a meaningful way, we also plot the results of Onion clustering for one specific value of ∆t. - - -.. code-block:: python - - delta_t_list = np.unique(np.geomspace(2, 1000, 45, dtype=int)) - results = np.zeros((4, delta_t_list.size)) - example_delta_t = 4 # Choosing a ∆t which works well to plot results +.. testcode:: recipe3-test - for i, dataset in enumerate([dataset_1, dataset_2]): - n_atoms, n_frames, n_dims = dataset.shape + delta_t_list = np.unique(np.geomspace(1, 1000, 20, dtype=int)) - # We can do clustering using only the y variable: - y_positions = dataset[:, :, 1] - info_gain_y = np.zeros(delta_t_list.size) + def info_gain_with_onion(delta_t_list: np.ndarray | list[int]): + n_clusters = np.zeros(delta_t_list.size) + clusters_frac = [] + info_gain = np.zeros(delta_t_list.size) + clusters_entr = [] - for j, delta_t in enumerate(delta_t_list): + for i, delta_t in enumerate(delta_t_list): reshaped_data = dynsight.onion.helpers.reshape_from_nt( - y_positions, delta_t + lens.dataset, delta_t ) state_list, labels = dynsight.onion.onion_uni(reshaped_data) - if j == example_delta_t: - dynsight.onion.plot.plot_output_uni( - f"Example_{i}_1D.png", - reshaped_data, - n_atoms, - state_list, - ) + n_clusters[i] = len(state_list) + tmp_frac = [0.0] + for state in state_list: + tmp_frac.append(state.perc) + tmp_frac[0] = 1.0 - np.sum(tmp_frac) + clusters_frac.append(tmp_frac) # and compute the information gain: info_gain_y[j], *_ = dynsight.analysis.compute_entropy_gain( @@ -204,61 +98,3 @@ To check if the clustering is working in a meaningful way, we also plot the resu # phase space, which is 2D is doubled info_gain_xy *= 2 results.append(info_gain_xy) - - -Here are the plots of the two datasets, with the different clusters identified when clustering the full, bi-dimensional data, using ∆t = 4 frames: - -.. list-table:: - :widths: auto - :align: center - - * - .. image:: _static/info_gain_clusters_1d.png - - .. image:: _static/info_gain_clusters_2d.png - - -As can be seen, all the clusters are correctly identified at this time resolution ∆t. When we are using only the y-coordinate instead, as expected in both cases just two clusters can be identified (the two plots look the same but they are actually from the two different systems): - -.. list-table:: - :widths: auto - :align: center - - * - .. image:: _static/info_gain_clusters_1d_y.png - - .. image:: _static/info_gain_clusters_2d_y.png - - -We can now plot, for every case and for every choice of ∆t, the corresponding information gain. - -.. code-block:: python - - colorlist = ["C0", "C2", "C1", "C3"] - markerlist = ["s", "o", "d", "o"] - labellist = [ - "2 peaks - 1D clustering", - "2 peaks - 2D clustering", - "4 peaks - 1D clustering", - "4 peaks - 2D clustering", - ] - - fig, ax = plt.subplots() - for i, system in enumerate(results): - ax.plot( - delta_t_list, - system, - label=labellist[i], - c=colorlist[i], - marker=markerlist[i], - ) - - ax.set_xlabel(r"Time resolution $\Delta t$ [frame]") - ax.set_ylabel(r"Information gain $\Delta H$ [bit]") - ax.set_xscale("log") - ax.legend() - plt.show() - -As can be seen in the plot below, clustering both datasets using only the y coordinate gives the same information gain, because only two clusters can be distinguished. - -Clustering the trajectories in the energy potential with two minima using both variables gives once again the same information gain for small values of ∆t; then, the clustering performance degrades because the fraction of classifiable data points starts to decreases. - -Finally, clustering the trajectories in the energy potential with four minima using both variables gives an information gain which is double the previous ones (at least for small ∆t), which makes sense, because 4 clusters are discovered instead of 2. For larger ∆t, we see the same degrading in performance that always affects clustering on multivariate distributions. - -.. image:: _static/Information_gains.png From 818fe5435472686b991ed1144f03cf028ce67e99 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Wed, 9 Jul 2025 10:08:37 +0200 Subject: [PATCH 22/42] Adding a page of documentation for dynsight.trajectory. --- docs/source/index.rst | 1 + docs/source/trajectory.rst | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 docs/source/trajectory.rst diff --git a/docs/source/index.rst b/docs/source/index.rst index f30955d0..7082cc32 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -3,6 +3,7 @@ :caption: dynsight :maxdepth: 2 + trajectory SOAP timeSOAP LENS diff --git a/docs/source/trajectory.rst b/docs/source/trajectory.rst new file mode 100644 index 00000000..3ad456de --- /dev/null +++ b/docs/source/trajectory.rst @@ -0,0 +1,29 @@ +trajectory +========== + +This module offers an object-oriented implementation of the dynsight +utilities, to facilitate the workflow of any analysis. +Moreover, the ``trajectory`` classes make it easier to save and share results, +and have a built-in logging module. + +The :class:`.trajectory.Trj` class is a container for a MDAnalysis.Universe, +which allows for the computation of all the descriptors implemented in dynsight. + +These descriptors, as well as the output of subsequent analyses, are stored in +:class:`.trajectory.Insight` or :class:`.trajectory.ClusterInsight` objects. + +We reccomand the users, when possible, to write code using this module. + +Complete examples can be found in the recipes section of this documentation. + +Classes +------- + +.. toctree:: + :maxdepth: 1 + + Trj <_autosummary/dynsight.trajectory.Trj> + Insight <_autosummary/dynsight.trajectory.Insight> + ClusterInsight <_autosummary/dynsight.trajectory.ClusterInsight> + OnionInsight <_autosummary/dynsight.trajectory.OnionInsight> + OnionSmoothInsight <_autosummary/dynsight.trajectory.OnionSmoothInsight> From 93bf48363c0f27dadaf1d673795b0d3ac3427215 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Wed, 9 Jul 2025 10:20:31 +0200 Subject: [PATCH 23/42] WIP on the third recipe. --- docs/source/tmp_info_gain.rst | 67 +++++++++++------------------------ 1 file changed, 21 insertions(+), 46 deletions(-) diff --git a/docs/source/tmp_info_gain.rst b/docs/source/tmp_info_gain.rst index 4ccc4ffb..fd50dc47 100644 --- a/docs/source/tmp_info_gain.rst +++ b/docs/source/tmp_info_gain.rst @@ -31,26 +31,33 @@ The following functions take as input the LENS dataset, and a list of values of time resolutions ∆t, and for each of these perform Onion clustering, and compute the information gain achieved through clustering with that ∆t. -DESCRIBE THE OUTPUT +Notice that, for now, this only works with univariate datasets. -In this first function, the clustering is performed with the "old" onion -algorithm (time-series segmentation in consecutive windows): +DESCRIBE THE OUTPUT .. testcode:: recipe3-test - delta_t_list = np.unique(np.geomspace(1, 1000, 20, dtype=int)) + import numpy as np + from dynsight.trajectory import Insight - def info_gain_with_onion(delta_t_list: np.ndarray | list[int]): + n_atoms, n_frames = lens.dataset.shape + delta_t_list = np.unique(np.geomspace(1, n_frames, 10, dtype=int)) + + def info_gain_with_onion( + delta_t_list: np.ndarray | list[int], + data: Insight, + n_bins: int = 40, + ): n_clusters = np.zeros(delta_t_list.size) clusters_frac = [] info_gain = np.zeros(delta_t_list.size) clusters_entr = [] for i, delta_t in enumerate(delta_t_list): - reshaped_data = dynsight.onion.helpers.reshape_from_nt( - lens.dataset, delta_t + state_list, labels = dynsight.onion.onion_smooth_uni( + data.dataset, + delta_t=delta_t, ) - state_list, labels = dynsight.onion.onion_uni(reshaped_data) n_clusters[i] = len(state_list) tmp_frac = [0.0] @@ -59,42 +66,10 @@ algorithm (time-series segmentation in consecutive windows): tmp_frac[0] = 1.0 - np.sum(tmp_frac) clusters_frac.append(tmp_frac) - # and compute the information gain: - info_gain_y[j], *_ = dynsight.analysis.compute_entropy_gain( - reshaped_data, labels, n_bins=40 - ) - results.append(info_gain_y) - - # Or we can do clustering using both (x, y) variables: - info_gain_xy = np.zeros(delta_t_list.size) - tmp1_dataset = np.transpose(dataset, (2, 0, 1)) - for j, delta_t in enumerate(delta_t_list): - reshaped_data = dynsight.onion.helpers.reshape_from_dnt( - tmp1_dataset, delta_t + flat_data = data.dataset.flatten() + flat_labels = labels.flatten() + info_gain[i], *_ = dynsight.analysis.compute_entropy_gain( + flat_data, flat_labels, n_bins=n_bins, ) - state_list, labels = dynsight.onion.onion_multi(reshaped_data) - - if j == example_delta_t: - dynsight.onion.plot.plot_output_multi( - f"Example_{i}_2D.png", - tmp1_dataset, - state_list, - labels, - delta_t, - ) - - # and compute the information gain: - # We need an array (n_samples, n_dims), and labels (n_samples,) - n_sequences = int(n_frames / delta_t) - long_labels = np.repeat(labels, delta_t) - tmp = dataset[:, : n_sequences * delta_t, :] - ds_reshaped = tmp.reshape((-1, n_dims)) - - info_gain_xy[j], *_ = dynsight.analysis.compute_entropy_gain_multi( - ds_reshaped, long_labels, n_bins=[40, 40] - ) - # Need to multiply by two because it's 2 dimensional, and the output - # of the info_gain functions is normalized by the log volume of the - # phase space, which is 2D is doubled - info_gain_xy *= 2 - results.append(info_gain_xy) + + From 99631469f7c38e3dfc9a03c71837167b0d550dc6 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Wed, 9 Jul 2025 10:39:52 +0200 Subject: [PATCH 24/42] v1 of third recipe working; cleaned file names. --- ...flow.rst => example_analysis_workflow.rst} | 0 docs/source/example_info_gain.rst | 257 ++++++++++++++ ...entropy.rst => example_sample_entropy.rst} | 0 docs/source/index.rst | 8 +- docs/source/info_gain.rst | 314 +++++------------- docs/source/tmp_info_gain.rst | 75 ----- 6 files changed, 342 insertions(+), 312 deletions(-) rename docs/source/{analysis_workflow.rst => example_analysis_workflow.rst} (100%) create mode 100644 docs/source/example_info_gain.rst rename docs/source/{sample_entropy.rst => example_sample_entropy.rst} (100%) delete mode 100644 docs/source/tmp_info_gain.rst diff --git a/docs/source/analysis_workflow.rst b/docs/source/example_analysis_workflow.rst similarity index 100% rename from docs/source/analysis_workflow.rst rename to docs/source/example_analysis_workflow.rst diff --git a/docs/source/example_info_gain.rst b/docs/source/example_info_gain.rst new file mode 100644 index 00000000..9fac3187 --- /dev/null +++ b/docs/source/example_info_gain.rst @@ -0,0 +1,257 @@ +Information gain computation +============================ + +For the theoretical aspects of this work, see INSERT REF. + +Here we show how to compute the information gain through clustering. To this end, we create two datasets by simulating the Langevin Dynamics of particles moving in two different bidimensional potential energy landscapes, one with two and one with four minima. We compare the information gain after clustering the particles' trajectories, using either one or both variables. + +To start, let's import the packages we will need and create a folder in the cwd to save the results in. + +.. code-block:: python + + from pathlib import Path + from typing import Callable + import numpy as np + import matplotlib.pyplot as plt + + cwd = Path.cwd() + folder_name = "info_gain" + folder_path = cwd / folder_name + if not folder_path.exists(): + folder_path.mkdir() + + +Now, we want to simulate the Langevin Dynamics. We start defining the potential energy landscapes, with two and four minima. + +.. code-block:: python + + def energy_landscape_1(x: float, y: float) -> float: + """A potential energy landscape with 2 minima.""" + sigma = 0.12 # Width of the Gaussian wells + gauss1 = np.exp(-(x**2 + y**2) / (2 * sigma**2)) + gauss2 = np.exp(-(x**2 + (y - 1) ** 2) / (2 * sigma**2)) + return -np.log(gauss1 + gauss2 + 1e-6) + + + def energy_landscape_2(x: float, y: float) -> float: + """A potential energy landscape with 4 minima.""" + sigma = 0.12 # Width of the Gaussian wells + gauss1 = np.exp(-(x**2 + y**2) / (2 * sigma**2)) + gauss2 = np.exp(-((x - 1) ** 2 + y**2) / (2 * sigma**2)) + gauss3 = np.exp(-(x**2 + (y - 1) ** 2) / (2 * sigma**2)) + gauss4 = np.exp(-((x - 1) ** 2 + (y - 1) ** 2) / (2 * sigma**2)) + return -np.log(gauss1 + gauss2 + gauss3 + gauss4 + 1e-6) + + +To compute the force acting on the particle, we need to compute the potential energy gradient. + +.. code-block:: python + + def numerical_gradient( + f: Callable[[float, float], float], x: float, y: float, h: float = 1e-5 + ) -> tuple[float, float]: + """Compute numerical gradient using finite differences.""" + grad_x = (f(x + h, y) - f(x - h, y)) / (2 * h) + grad_y = (f(x, y + h) - f(x, y - h)) / (2 * h) + return -grad_x, -grad_y + + +This function simulates, for both energy landscapes, the dynamics of 100 particles for 10000 timesteps. Particles are initialized close to the minima. + +.. code-block:: python + + def create_trajectory( + energy_landscape: Callable[[float, float], float], file_name: Path + ) -> np.ndarray: + """Simulate Langevin Dynamics on a given energy landscape.""" + rng = np.random.default_rng(0) + n_atoms = 100 + time_steps = 10000 + dt = 0.01 # Time step + diffusion_coeff = 0.6 # Diffusion coefficient (random noise strength) + + if energy_landscape == energy_landscape_1: + particles = rng.standard_normal((n_atoms, 2)) * 0.2 + particles[n_atoms // 2 :, 1] += 1.0 + else: + particles = rng.standard_normal((n_atoms, 2)) * 0.2 + n_group = n_atoms // 4 + particles[n_group : 2 * n_group, 1] += 1 # (0, 1) + particles[2 * n_group : 3 * n_group, 0] += 1 # (1, 0) + particles[3 * n_group :, 0] += 1 # (1, 1) + particles[3 * n_group :, 1] += 1 + + trajectory = np.zeros((time_steps, n_atoms, 2)) + for t in range(time_steps): + for i in range(n_atoms): + x, y = particles[i] + fx, fy = numerical_gradient(energy_landscape, x, y) + noise_x = np.sqrt(2 * diffusion_coeff * dt) * rng.standard_normal() + noise_y = np.sqrt(2 * diffusion_coeff * dt) * rng.standard_normal() + + # Update position with deterministic force and stochastic term + particles[i, 0] += fx * dt + noise_x + particles[i, 1] += fy * dt + noise_y + + trajectory[t, i] = particles[i] + + plt.figure() + plt.plot(trajectory[:, :, 0], trajectory[:, :, 1]) + plt.show() + + dataset = np.transpose(trajectory, (1, 0, 2)) + np.save(filename, dataset) + return dataset + + +Let's simulate the trajectories and store them in two variables. We also save them as .npy files so that we don't have to simulate them every time. + +.. code-block:: python + + file_1 = folder_path / "trj_2.npy" # With 2 minima + file_2 = folder_path / "trj_4.npy" # With 4 minima + + if not file_1.exists(): + dataset_1 = create_trajectory(energy_landscape_1, file_1) + + dataset_1 = np.load(file_1) + + if not file_2.exists(): + dataset_2 = create_trajectory(energy_landscape_2, file_2) + + dataset_2 = np.load(file_2) + + +Now that we have the trajectories, we can, for each one, perform Onion clustering and computing the corresponding information gain, using either + +- only the y coordinate, or +- both x and y coordinates + +For each case, we do the analysis for a range of values of the Onion clustering time resolution ∆t. The information gain for each analysis is saved in the variable "results". +To check if the clustering is working in a meaningful way, we also plot the results of Onion clustering for one specific value of ∆t. + + +.. code-block:: python + + delta_t_list = np.unique(np.geomspace(2, 1000, 45, dtype=int)) + results = np.zeros((4, delta_t_list.size)) + example_delta_t = 4 # Choosing a ∆t which works well to plot results + + for i, dataset in enumerate([dataset_1, dataset_2]): + n_atoms, n_frames, n_dims = dataset.shape + + # We can do clustering using only the y variable: + y_positions = dataset[:, :, 1] + info_gain_y = np.zeros(delta_t_list.size) + + for j, delta_t in enumerate(delta_t_list): + reshaped_data = dynsight.onion.helpers.reshape_from_nt( + y_positions, delta_t + ) + state_list, labels = dynsight.onion.onion_uni(reshaped_data) + + if j == example_delta_t: + dynsight.onion.plot.plot_output_uni( + f"Example_{i}_1D.png", + reshaped_data, + n_atoms, + state_list, + ) + + # and compute the information gain: + info_gain_y[j], *_ = dynsight.analysis.compute_entropy_gain( + reshaped_data, labels, n_bins=40 + ) + results.append(info_gain_y) + + # Or we can do clustering using both (x, y) variables: + info_gain_xy = np.zeros(delta_t_list.size) + tmp1_dataset = np.transpose(dataset, (2, 0, 1)) + for j, delta_t in enumerate(delta_t_list): + reshaped_data = dynsight.onion.helpers.reshape_from_dnt( + tmp1_dataset, delta_t + ) + state_list, labels = dynsight.onion.onion_multi(reshaped_data) + + if j == example_delta_t: + dynsight.onion.plot.plot_output_multi( + f"Example_{i}_2D.png", + tmp1_dataset, + state_list, + labels, + delta_t, + ) + + # and compute the information gain: + # We need an array (n_samples, n_dims), and labels (n_samples,) + n_sequences = int(n_frames / delta_t) + long_labels = np.repeat(labels, delta_t) + tmp = dataset[:, : n_sequences * delta_t, :] + ds_reshaped = tmp.reshape((-1, n_dims)) + + info_gain_xy[j], *_ = dynsight.analysis.compute_entropy_gain_multi( + ds_reshaped, long_labels, n_bins=[40, 40] + ) + # Need to multiply by two because it's 2 dimensional, and the output + # of the info_gain functions is normalized by the log volume of the + # phase space, which is 2D is doubled + info_gain_xy *= 2 + results.append(info_gain_xy) + + +Here are the plots of the two datasets, with the different clusters identified when clustering the full, bi-dimensional data, using ∆t = 4 frames: + +.. list-table:: + :widths: auto + :align: center + + * - .. image:: _static/info_gain_clusters_1d.png + - .. image:: _static/info_gain_clusters_2d.png + + +As can be seen, all the clusters are correctly identified at this time resolution ∆t. When we are using only the y-coordinate instead, as expected in both cases just two clusters can be identified (the two plots look the same but they are actually from the two different systems): + +.. list-table:: + :widths: auto + :align: center + + * - .. image:: _static/info_gain_clusters_1d_y.png + - .. image:: _static/info_gain_clusters_2d_y.png + + +We can now plot, for every case and for every choice of ∆t, the corresponding information gain. + +.. code-block:: python + + colorlist = ["C0", "C2", "C1", "C3"] + markerlist = ["s", "o", "d", "o"] + labellist = [ + "2 peaks - 1D clustering", + "2 peaks - 2D clustering", + "4 peaks - 1D clustering", + "4 peaks - 2D clustering", + ] + + fig, ax = plt.subplots() + for i, system in enumerate(results): + ax.plot( + delta_t_list, + system, + label=labellist[i], + c=colorlist[i], + marker=markerlist[i], + ) + + ax.set_xlabel(r"Time resolution $\Delta t$ [frame]") + ax.set_ylabel(r"Information gain $\Delta H$ [bit]") + ax.set_xscale("log") + ax.legend() + plt.show() + +As can be seen in the plot below, clustering both datasets using only the y coordinate gives the same information gain, because only two clusters can be distinguished. + +Clustering the trajectories in the energy potential with two minima using both variables gives once again the same information gain for small values of ∆t; then, the clustering performance degrades because the fraction of classifiable data points starts to decreases. + +Finally, clustering the trajectories in the energy potential with four minima using both variables gives an information gain which is double the previous ones (at least for small ∆t), which makes sense, because 4 clusters are discovered instead of 2. For larger ∆t, we see the same degrading in performance that always affects clustering on multivariate distributions. + +.. image:: _static/Information_gains.png diff --git a/docs/source/sample_entropy.rst b/docs/source/example_sample_entropy.rst similarity index 100% rename from docs/source/sample_entropy.rst rename to docs/source/example_sample_entropy.rst diff --git a/docs/source/index.rst b/docs/source/index.rst index 7082cc32..0ea0ae12 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -21,16 +21,16 @@ Descriptors from a Trj Dimensionality reduction methods - Information gain analysis + Information gain analysis .. toctree:: :hidden: :maxdepth: 2 :caption: Examples: - Typical analysis workflow - Information gain - Sample Entropy + Typical analysis workflow + Information gain + Sample Entropy .. toctree:: :hidden: diff --git a/docs/source/info_gain.rst b/docs/source/info_gain.rst index 9fac3187..68e09035 100644 --- a/docs/source/info_gain.rst +++ b/docs/source/info_gain.rst @@ -1,257 +1,105 @@ -Information gain computation -============================ +Information gain analysis +========================= For the theoretical aspects of this work, see INSERT REF. -Here we show how to compute the information gain through clustering. To this end, we create two datasets by simulating the Langevin Dynamics of particles moving in two different bidimensional potential energy landscapes, one with two and one with four minima. We compare the information gain after clustering the particles' trajectories, using either one or both variables. +This recipe explains how to compute the information gain through clustering +analysis. The LENS descriptor is computed on a many-body trajectory, and then +onion clustering is run on a broad range of time resolutions ∆t. The +information gain and the Shannon entropy of the environments is computed for +each value of ∆t. The analysis is implemented using both onion 1.0.13 and +2.0.0 ("onion smooth"). -To start, let's import the packages we will need and create a folder in the cwd to save the results in. +Let's start by creating a :class:`.trajectory.Trj` and computing LENS: -.. code-block:: python +.. testcode:: recipe3-test from pathlib import Path - from typing import Callable - import numpy as np - import matplotlib.pyplot as plt - - cwd = Path.cwd() - folder_name = "info_gain" - folder_path = cwd / folder_name - if not folder_path.exists(): - folder_path.mkdir() - - -Now, we want to simulate the Langevin Dynamics. We start defining the potential energy landscapes, with two and four minima. - -.. code-block:: python - - def energy_landscape_1(x: float, y: float) -> float: - """A potential energy landscape with 2 minima.""" - sigma = 0.12 # Width of the Gaussian wells - gauss1 = np.exp(-(x**2 + y**2) / (2 * sigma**2)) - gauss2 = np.exp(-(x**2 + (y - 1) ** 2) / (2 * sigma**2)) - return -np.log(gauss1 + gauss2 + 1e-6) - - - def energy_landscape_2(x: float, y: float) -> float: - """A potential energy landscape with 4 minima.""" - sigma = 0.12 # Width of the Gaussian wells - gauss1 = np.exp(-(x**2 + y**2) / (2 * sigma**2)) - gauss2 = np.exp(-((x - 1) ** 2 + y**2) / (2 * sigma**2)) - gauss3 = np.exp(-(x**2 + (y - 1) ** 2) / (2 * sigma**2)) - gauss4 = np.exp(-((x - 1) ** 2 + (y - 1) ** 2) / (2 * sigma**2)) - return -np.log(gauss1 + gauss2 + gauss3 + gauss4 + 1e-6) - - -To compute the force acting on the particle, we need to compute the potential energy gradient. - -.. code-block:: python - - def numerical_gradient( - f: Callable[[float, float], float], x: float, y: float, h: float = 1e-5 - ) -> tuple[float, float]: - """Compute numerical gradient using finite differences.""" - grad_x = (f(x + h, y) - f(x - h, y)) / (2 * h) - grad_y = (f(x, y + h) - f(x, y - h)) / (2 * h) - return -grad_x, -grad_y - - -This function simulates, for both energy landscapes, the dynamics of 100 particles for 10000 timesteps. Particles are initialized close to the minima. - -.. code-block:: python - - def create_trajectory( - energy_landscape: Callable[[float, float], float], file_name: Path - ) -> np.ndarray: - """Simulate Langevin Dynamics on a given energy landscape.""" - rng = np.random.default_rng(0) - n_atoms = 100 - time_steps = 10000 - dt = 0.01 # Time step - diffusion_coeff = 0.6 # Diffusion coefficient (random noise strength) - - if energy_landscape == energy_landscape_1: - particles = rng.standard_normal((n_atoms, 2)) * 0.2 - particles[n_atoms // 2 :, 1] += 1.0 - else: - particles = rng.standard_normal((n_atoms, 2)) * 0.2 - n_group = n_atoms // 4 - particles[n_group : 2 * n_group, 1] += 1 # (0, 1) - particles[2 * n_group : 3 * n_group, 0] += 1 # (1, 0) - particles[3 * n_group :, 0] += 1 # (1, 1) - particles[3 * n_group :, 1] += 1 - - trajectory = np.zeros((time_steps, n_atoms, 2)) - for t in range(time_steps): - for i in range(n_atoms): - x, y = particles[i] - fx, fy = numerical_gradient(energy_landscape, x, y) - noise_x = np.sqrt(2 * diffusion_coeff * dt) * rng.standard_normal() - noise_y = np.sqrt(2 * diffusion_coeff * dt) * rng.standard_normal() - - # Update position with deterministic force and stochastic term - particles[i, 0] += fx * dt + noise_x - particles[i, 1] += fy * dt + noise_y - - trajectory[t, i] = particles[i] - - plt.figure() - plt.plot(trajectory[:, :, 0], trajectory[:, :, 1]) - plt.show() - - dataset = np.transpose(trajectory, (1, 0, 2)) - np.save(filename, dataset) - return dataset - - -Let's simulate the trajectories and store them in two variables. We also save them as .npy files so that we don't have to simulate them every time. - -.. code-block:: python - - file_1 = folder_path / "trj_2.npy" # With 2 minima - file_2 = folder_path / "trj_4.npy" # With 4 minima - - if not file_1.exists(): - dataset_1 = create_trajectory(energy_landscape_1, file_1) + from dynsight.trajectory import Trj - dataset_1 = np.load(file_1) + # Loading an example trajectory + files_path = Path("../tests/systems/") + trj = Trj.init_from_xtc( + traj_file=files_path / "balls_7_nvt.xtc", + topo_file=files_path / "balls_7_nvt.gro", + ) - if not file_2.exists(): - dataset_2 = create_trajectory(energy_landscape_2, file_2) + _, lens = trj.get_lens(r_cut=10.0) - dataset_2 = np.load(file_2) +The following functions take as input the LENS dataset, and a list of values +of time resolutions ∆t, and for each of these perform Onion clustering, and +compute the information gain achieved through clustering with that ∆t. -Now that we have the trajectories, we can, for each one, perform Onion clustering and computing the corresponding information gain, using either +Notice that, for now, this only works with univariate datasets. -- only the y coordinate, or -- both x and y coordinates +DESCRIBE THE OUTPUT -For each case, we do the analysis for a range of values of the Onion clustering time resolution ∆t. The information gain for each analysis is saved in the variable "results". -To check if the clustering is working in a meaningful way, we also plot the results of Onion clustering for one specific value of ∆t. +.. testcode:: recipe3-test - -.. code-block:: python - - delta_t_list = np.unique(np.geomspace(2, 1000, 45, dtype=int)) - results = np.zeros((4, delta_t_list.size)) - example_delta_t = 4 # Choosing a ∆t which works well to plot results - - for i, dataset in enumerate([dataset_1, dataset_2]): - n_atoms, n_frames, n_dims = dataset.shape - - # We can do clustering using only the y variable: - y_positions = dataset[:, :, 1] - info_gain_y = np.zeros(delta_t_list.size) - - for j, delta_t in enumerate(delta_t_list): - reshaped_data = dynsight.onion.helpers.reshape_from_nt( - y_positions, delta_t - ) - state_list, labels = dynsight.onion.onion_uni(reshaped_data) - - if j == example_delta_t: - dynsight.onion.plot.plot_output_uni( - f"Example_{i}_1D.png", - reshaped_data, - n_atoms, - state_list, - ) - - # and compute the information gain: - info_gain_y[j], *_ = dynsight.analysis.compute_entropy_gain( - reshaped_data, labels, n_bins=40 + import numpy as np + import dynsight + from dynsight.trajectory import Insight + + n_atoms, n_frames = lens.dataset.shape + delta_t_list = np.unique(np.geomspace(1, n_frames, 10, dtype=int)) + + def info_gain_with_onion( + delta_t_list: np.ndarray | list[int], + data: Insight, + n_bins: int = 40, + ): + data_range = (np.min(data.dataset), np.max(data.dataset)) + + n_clusters = np.zeros(delta_t_list.size) + clusters_frac = [] + info_gain = np.zeros(delta_t_list.size) + clusters_entr = [] + + for i, delta_t in enumerate(delta_t_list): + state_list, labels = dynsight.onion.onion_uni_smooth( + data.dataset, + delta_t=delta_t, ) - results.append(info_gain_y) - # Or we can do clustering using both (x, y) variables: - info_gain_xy = np.zeros(delta_t_list.size) - tmp1_dataset = np.transpose(dataset, (2, 0, 1)) - for j, delta_t in enumerate(delta_t_list): - reshaped_data = dynsight.onion.helpers.reshape_from_dnt( - tmp1_dataset, delta_t + n_clusters[i] = len(state_list) + tmp_frac = [0.0] + for state in state_list: + tmp_frac.append(state.perc) + tmp_frac[0] = 1.0 - np.sum(tmp_frac) + clusters_frac.append(tmp_frac) + + flat_data = data.dataset.flatten() + flat_labels = labels.flatten() + info_gain[i], *_ = dynsight.analysis.compute_entropy_gain( + flat_data, flat_labels, n_bins=n_bins, ) - state_list, labels = dynsight.onion.onion_multi(reshaped_data) - if j == example_delta_t: - dynsight.onion.plot.plot_output_multi( - f"Example_{i}_2D.png", - tmp1_dataset, - state_list, - labels, - delta_t, + tmp_entr = [] + label_list = np.unique(labels) + if label_list[0] != -1: + tmp_entr.append(-1.0) + + for _, lab in enumerate(label_list): + mask = labels == lab + selected_points = data.dataset[mask] + tmp_entr.append( + dynsight.analysis.compute_shannon( + selected_points, + data_range, + n_bins=n_bins, + ) ) + clusters_entr.append(tmp_entr) - # and compute the information gain: - # We need an array (n_samples, n_dims), and labels (n_samples,) - n_sequences = int(n_frames / delta_t) - long_labels = np.repeat(labels, delta_t) - tmp = dataset[:, : n_sequences * delta_t, :] - ds_reshaped = tmp.reshape((-1, n_dims)) - - info_gain_xy[j], *_ = dynsight.analysis.compute_entropy_gain_multi( - ds_reshaped, long_labels, n_bins=[40, 40] - ) - # Need to multiply by two because it's 2 dimensional, and the output - # of the info_gain functions is normalized by the log volume of the - # phase space, which is 2D is doubled - info_gain_xy *= 2 - results.append(info_gain_xy) - - -Here are the plots of the two datasets, with the different clusters identified when clustering the full, bi-dimensional data, using ∆t = 4 frames: - -.. list-table:: - :widths: auto - :align: center - - * - .. image:: _static/info_gain_clusters_1d.png - - .. image:: _static/info_gain_clusters_2d.png - - -As can be seen, all the clusters are correctly identified at this time resolution ∆t. When we are using only the y-coordinate instead, as expected in both cases just two clusters can be identified (the two plots look the same but they are actually from the two different systems): - -.. list-table:: - :widths: auto - :align: center - - * - .. image:: _static/info_gain_clusters_1d_y.png - - .. image:: _static/info_gain_clusters_2d_y.png - - -We can now plot, for every case and for every choice of ∆t, the corresponding information gain. - -.. code-block:: python - - colorlist = ["C0", "C2", "C1", "C3"] - markerlist = ["s", "o", "d", "o"] - labellist = [ - "2 peaks - 1D clustering", - "2 peaks - 2D clustering", - "4 peaks - 1D clustering", - "4 peaks - 2D clustering", - ] - - fig, ax = plt.subplots() - for i, system in enumerate(results): - ax.plot( - delta_t_list, - system, - label=labellist[i], - c=colorlist[i], - marker=markerlist[i], - ) - - ax.set_xlabel(r"Time resolution $\Delta t$ [frame]") - ax.set_ylabel(r"Information gain $\Delta H$ [bit]") - ax.set_xscale("log") - ax.legend() - plt.show() - -As can be seen in the plot below, clustering both datasets using only the y coordinate gives the same information gain, because only two clusters can be distinguished. + return n_clusters, clusters_frac, info_gain, clusters_entr -Clustering the trajectories in the energy potential with two minima using both variables gives once again the same information gain for small values of ∆t; then, the clustering performance degrades because the fraction of classifiable data points starts to decreases. + n_cl, cl_frac, info_gain, cl_entr = info_gain_with_onion( + delta_t_list, + lens, + ) -Finally, clustering the trajectories in the energy potential with four minima using both variables gives an information gain which is double the previous ones (at least for small ∆t), which makes sense, because 4 clusters are discovered instead of 2. For larger ∆t, we see the same degrading in performance that always affects clustering on multivariate distributions. +.. testcode:: recipe3-test + :hide: -.. image:: _static/Information_gains.png + assert np.isclose(info_gain[0], 0.08020785756017804) diff --git a/docs/source/tmp_info_gain.rst b/docs/source/tmp_info_gain.rst deleted file mode 100644 index fd50dc47..00000000 --- a/docs/source/tmp_info_gain.rst +++ /dev/null @@ -1,75 +0,0 @@ -Information gain analysis -========================= - -For the theoretical aspects of this work, see INSERT REF. - -This recipe explains how to compute the information gain through clustering -analysis. The LENS descriptor is computed on a many-body trajectory, and then -onion clustering is run on a broad range of time resolutions ∆t. The -information gain and the Shannon entropy of the environments is computed for -each value of ∆t. The analysis is implemented using both onion 1.0.13 and -2.0.0 ("onion smooth"). - -Let's start by creating a :class:`.trajectory.Trj` and computing LENS: - -.. testcode:: recipe3-test - - from pathlib import Path - from dynsight.trajectory import Trj - - # Loading an example trajectory - files_path = Path("../tests/systems/") - trj = Trj.init_from_xtc( - traj_file=files_path / "balls_7_nvt.xtc", - topo_file=files_path / "balls_7_nvt.gro", - ) - - _, lens = trj.get_lens(r_cut=10.0) - - -The following functions take as input the LENS dataset, and a list of values -of time resolutions ∆t, and for each of these perform Onion clustering, and -compute the information gain achieved through clustering with that ∆t. - -Notice that, for now, this only works with univariate datasets. - -DESCRIBE THE OUTPUT - -.. testcode:: recipe3-test - - import numpy as np - from dynsight.trajectory import Insight - - n_atoms, n_frames = lens.dataset.shape - delta_t_list = np.unique(np.geomspace(1, n_frames, 10, dtype=int)) - - def info_gain_with_onion( - delta_t_list: np.ndarray | list[int], - data: Insight, - n_bins: int = 40, - ): - n_clusters = np.zeros(delta_t_list.size) - clusters_frac = [] - info_gain = np.zeros(delta_t_list.size) - clusters_entr = [] - - for i, delta_t in enumerate(delta_t_list): - state_list, labels = dynsight.onion.onion_smooth_uni( - data.dataset, - delta_t=delta_t, - ) - - n_clusters[i] = len(state_list) - tmp_frac = [0.0] - for state in state_list: - tmp_frac.append(state.perc) - tmp_frac[0] = 1.0 - np.sum(tmp_frac) - clusters_frac.append(tmp_frac) - - flat_data = data.dataset.flatten() - flat_labels = labels.flatten() - info_gain[i], *_ = dynsight.analysis.compute_entropy_gain( - flat_data, flat_labels, n_bins=n_bins, - ) - - From a67438832b10967499db2d6af15e99189d60792f Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Wed, 9 Jul 2025 11:26:52 +0200 Subject: [PATCH 25/42] Added info_plot function to third recipe. --- docs/source/_static/info_plot.png | Bin 0 -> 120719 bytes docs/source/info_gain.rst | 98 ++++++++++++++++++++++++++++-- 2 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 docs/source/_static/info_plot.png diff --git a/docs/source/_static/info_plot.png b/docs/source/_static/info_plot.png new file mode 100644 index 0000000000000000000000000000000000000000..358bf2fc94a955e42650d155f58212142535f7e1 GIT binary patch literal 120719 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 z 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 literal 0 HcmV?d00001 diff --git a/docs/source/info_gain.rst b/docs/source/info_gain.rst index 68e09035..ae132663 100644 --- a/docs/source/info_gain.rst +++ b/docs/source/info_gain.rst @@ -33,7 +33,15 @@ compute the information gain achieved through clustering with that ∆t. Notice that, for now, this only works with univariate datasets. -DESCRIBE THE OUTPUT +The function's output is a tuple of np.ndarray, which for each value of ∆t +contain: + +* the number of identified clusters - shape (delta_t_list.size,); +* the population fraction of each cluster - shape (delta_t_list.size, n_clust); +* the information gain - shape (delta_t_list.size,); +* the Shannon entropy of each cluster - shape (delta_t_list.size, n_clust) + +Additionally, the (float) dataset Shannon entropy h_0 is returned. .. testcode:: recipe3-test @@ -48,7 +56,8 @@ DESCRIBE THE OUTPUT delta_t_list: np.ndarray | list[int], data: Insight, n_bins: int = 40, - ): + ) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, float]: + """Performs full information gain analysis with Onion clustering.""" data_range = (np.min(data.dataset), np.max(data.dataset)) n_clusters = np.zeros(delta_t_list.size) @@ -71,7 +80,7 @@ DESCRIBE THE OUTPUT flat_data = data.dataset.flatten() flat_labels = labels.flatten() - info_gain[i], *_ = dynsight.analysis.compute_entropy_gain( + info_gain[i], _, h_0, _ = dynsight.analysis.compute_entropy_gain( flat_data, flat_labels, n_bins=n_bins, ) @@ -92,13 +101,92 @@ DESCRIBE THE OUTPUT ) clusters_entr.append(tmp_entr) - return n_clusters, clusters_frac, info_gain, clusters_entr + max_n_envs = np.max([len(elem) for elem in clusters_entr]) + for i, elem in enumerate(clusters_entr): + while len(elem) < max_n_envs: + elem.append(-1.0) + clusters_frac[i].append(0.0) + + cl_frac = np.array(clusters_frac) + cl_entr = np.array(clusters_entr) + + return n_clusters, cl_frac, info_gain, cl_entr, h_0 - n_cl, cl_frac, info_gain, cl_entr = info_gain_with_onion( + n_cl, cl_frac, info_gain, cl_entr, h_0 = info_gain_with_onion( delta_t_list, lens, ) +A default visualization of the results of this analysis can be obtained with +the following function. Be aware that this could require some tweaking to ensure +that clusters identified at different ∆t are matched in the way the user want +them to. + +DESCRIBE THE FIGURE + +.. testcode:: recipe3-test + + from pathlib import Path + import matplotlib.pyplot as plt + + def plot_info_results( + delta_t_list: np.ndarray | list[int], + cl_frac: np.ndarray, + cl_entr: np.ndarray, + h_0: float, + file_path: Path, + ) -> None: + frac = cl_frac.T + entr = cl_entr.T + s_list = [] + for i, st_fr in enumerate(frac): + s_list.append(st_fr * entr[i]) + s_cumul = [s_list[0]] + for i, tmp_s in enumerate(s_list[1:]): + s_cumul.append(s_cumul[-1] + tmp_s) + + fig, ax = plt.subplots() + + i_0 = (1 - h_0) * np.ones(len(delta_t_list)) + ax.plot(delta_t_list, i_0, ls="--", c="black", marker="") # I_0 + ax.fill_between( + delta_t_list, + 1, + 1 - s_cumul[0], + alpha=0.5, + ) + for i, tmp_s in enumerate(s_cumul[1:]): + ax.fill_between( + delta_t_list, + 1 - s_cumul[i], + 1 - tmp_s, + alpha=0.5, + ) + ax.fill_between( + delta_t_list, 1 - s_cumul[-1], 1 - h_0, color="gainsboro", + ) + ax.plot( + delta_t_list, 1 - s_cumul[-1], c="black", marker="", + ) # I_clust + + ax.set_ylim(0.0, 1.0) + ax.set_xlabel(r"Time resolution $\Delta t$") + ax.set_ylabel(r"Information $I$") + ax.set_xscale("log") + + fig.savefig(file_path, dpi=600) + plt.show() + plt.close() + + plot_info_results( + delta_t_list, + cl_frac, + cl_entr, + h_0, + Path("./source/_static/info_plot.png"), + ) + + .. testcode:: recipe3-test :hide: From bf2bbb4e0625f755f809898a0673663d9736712d Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Wed, 9 Jul 2025 11:29:40 +0200 Subject: [PATCH 26/42] Minor adjustments. --- docs/source/info_gain.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/source/info_gain.rst b/docs/source/info_gain.rst index ae132663..173bc45b 100644 --- a/docs/source/info_gain.rst +++ b/docs/source/info_gain.rst @@ -49,9 +49,6 @@ Additionally, the (float) dataset Shannon entropy h_0 is returned. import dynsight from dynsight.trajectory import Insight - n_atoms, n_frames = lens.dataset.shape - delta_t_list = np.unique(np.geomspace(1, n_frames, 10, dtype=int)) - def info_gain_with_onion( delta_t_list: np.ndarray | list[int], data: Insight, @@ -112,6 +109,10 @@ Additionally, the (float) dataset Shannon entropy h_0 is returned. return n_clusters, cl_frac, info_gain, cl_entr, h_0 + # Example usage + _, n_frames = lens.dataset.shape + delta_t_list = np.unique(np.geomspace(1, n_frames, 10, dtype=int)) + n_cl, cl_frac, info_gain, cl_entr, h_0 = info_gain_with_onion( delta_t_list, lens, @@ -175,9 +176,9 @@ DESCRIBE THE FIGURE ax.set_xscale("log") fig.savefig(file_path, dpi=600) - plt.show() plt.close() + # Example usage plot_info_results( delta_t_list, cl_frac, From 9c2778ff1eb07113d2541bbf5bac8c77eba6b74f Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Wed, 9 Jul 2025 11:46:01 +0200 Subject: [PATCH 27/42] Dataset changed for maningful results. --- docs/source/_static/info_plot.png | Bin 120719 -> 143272 bytes docs/source/info_gain.rst | 56 +++++++++++++++++------------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/docs/source/_static/info_plot.png b/docs/source/_static/info_plot.png index 358bf2fc94a955e42650d155f58212142535f7e1..327716dc5559793b765a744c1f9850d0745c68ab 100644 GIT binary patch literal 143272 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

AJ)@zSs>f-%X(@r z(QN$-VMmA=PJ3^F4n*L8IX47nVo~Kw6aje{?xs!L;54A`ve&JpKbPFx9w0c!@g2!w zQsaDo@XB?-IzcfTz~l3)cN4~v#BEpNyPqF4Kn*ZQ8!U&%e%YT{^wk2vJB_1~jLVRl zf@&l7pF>09E74DJ%zgLeB)YxdH)+kaN$gX}dbyOxhoS}_BTY)L32IX~YQ98rymaBv zy@C|Kji-QDgBl(Z=n8>|{o+cSZT`4BvmlHb-_m`->0`#xeZB8pU*US*_;G{gUHdZO zafqgio;`cULC9xO`0*~8NE#u4qm%sWs_k@i` zk2heH<-4=6q~uW1r0Wy9FiaubX9Mm>Gv;%@70c8d9{JF#{@!^GAI}FLDQ-S&iIwMI z8IoQ%xwPNx?>~T@H-3-+XFtSpfq3Q$0n$4x=2xd}(dFMjNfcT^@vH4;# z9{>1>6A!_5Jto=>MCb(Q&@q0;!E903?|7fhxI3ZtF?d0kFA#7LcX3Q>Jw7j=IMPSq zEHBI}%tu$I&A~T-w&vj;kN*1WYsGJfdQna$51``&J)fq>awXdLSIc1@7VLu|JsW}$ zv~boM2M5k~vm|JL4A+WXKWRvqya$4~4n#6|i1Q-|m1ogJ&Jh=o5lATxA#}{cYaeB9t`R@IOzsK5H>u}9X5Gnu>$GieZ}$M8 zx6(~Q3p$h_&UoN~bu_xAV~kEMK-0B^Suv#aOT?x_RaI5QAP_c2QglF`aJm241`d)y z?)P^3ZOWPu$Z&^4S1J$*8Nese$R^qnL2Uw_Y15-iuTe_q z(L4lrVQh2}4i|35JR)Kl{P=7=QA){6Cry|zs9UGG&+7dP@`QqF24eOQR402lviy8f z1=N|GrpO5Kv~ipSji}?^=6RfcgC;OCEt>c^u*`W7AjUs1Ky5%4kbO-Su7NyShX0-n z7}cjXZrf-XMu;O?XV?-u30)jL-7jR~0G1wAZ}2MCS(!_c6zFRyKO`4Xm|#DW;4b{K zqd9RgMDl0^KK|j?bN=Xa3Q5HC!y8&!7%jY(BTq4#<5+kGI^m^@y1TmR4<1y>XpQGt z{P8#3ZOS$QPglv}tv_ipo{CxyQF^H`JTUd`W?;IUpVZ7bU=uqFy*O?Q4&PcFy~J>z zdQY&-`8Yt4$z4bm9EnJ~oXND>c$im*Q8oGO`SX=US)Dgi{9YMNnsk_VF(B#KO8#Gi zh75`DO+-#@25iUX;=ai>&~R?`-Nna&FMC^p1sn@dgOm}B&&w4J@jG_`=5fYNWoFtG z<@tX6}jxsH%W`D%$FTOS;1u1R=PXqM6zz=4ia97BWF@nRLGiI=iJqdvUFXQEGgw$cCuB9QI0_pGXzuMRC z8k)E%JbP5;#aG1xH1I&DSAe@W+Su5*U!|=Bs%t0suQ<7qhMLx*&m*5#%=Sjp)~M7m zIWtOD4vNVMEcaxbBH~TwpM#JZjjO*pHmO^|J-5f|4&B!rpeF+CLd67S?l=cQY(6vG z@xp33e*ua-qj0!|S$jC_EVFg<`EZ2BF-_*kzffnc@qr*no1+H`Pz2Yg#2P=20fz70 zT5iTM!YJ7eiGe7yBKQKxMVRk}Gbqd{ALg6Jgw%w4Hy@zuYim9dFpL8xK=hiil9}S3 zsbOO0I9(nen*r%)`vnC_kd9H!PoGV?ed8CM6?h`T$_ZqqBPdHP5huv~Q-DXCFG7JO z$Yhg_j~_QYshFM4jJeK79@d#Xe?G;kjKiUly1F_cwV{#@1{hO7Jyow760t@bAvQ2Z z2K~Wje+cLNTm7L39WfX67G8cynLX`c7xIAevRVM%)^RTtRNnRL6vOE`(sWYjmQ(nJ$a~2_!!-QVo z#&M9wU8pCapptg2Qy;CX=*HQ9i|cJVyPp$`48d*ppZ5Nt`=3Yu)3OxYOO*8f&2I3Wkjw?8U=+|J{16-T>A6Z*KqR7Q+AjK)nw~_~(D0(7!zn t(SOg-zdw)v-m-sx9{(TW&~42Jx7zxJzxCM#Gc*Rq&s$=VIOm6-{ue~m!&d+R literal 120719 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 z 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 diff --git a/docs/source/info_gain.rst b/docs/source/info_gain.rst index 173bc45b..03e4bfc5 100644 --- a/docs/source/info_gain.rst +++ b/docs/source/info_gain.rst @@ -4,30 +4,35 @@ Information gain analysis For the theoretical aspects of this work, see INSERT REF. This recipe explains how to compute the information gain through clustering -analysis. The LENS descriptor is computed on a many-body trajectory, and then -onion clustering is run on a broad range of time resolutions ∆t. The -information gain and the Shannon entropy of the environments is computed for -each value of ∆t. The analysis is implemented using both onion 1.0.13 and -2.0.0 ("onion smooth"). +analysis. We use a syntetic dataset containing a signal that oscillates +between 0 and 1, with Gaussian noise. Onion clustering is run on a broad +range of time resolutions ∆t. The information gain and the Shannon entropy of +the environments is computed for each value of ∆t. The analysis is implemented +using onion 2.0.0 ("onion smooth"). -Let's start by creating a :class:`.trajectory.Trj` and computing LENS: +Let's start by creating a the synthetic dataset: .. testcode:: recipe3-test - from pathlib import Path - from dynsight.trajectory import Trj + import numpy as np - # Loading an example trajectory - files_path = Path("../tests/systems/") - trj = Trj.init_from_xtc( - traj_file=files_path / "balls_7_nvt.xtc", - topo_file=files_path / "balls_7_nvt.gro", - ) + # Parameters + n_atoms = 10 + num_blocks = 10 + block_size = 100 + sigma = 0.1 - _, lens = trj.get_lens(r_cut=10.0) + # Generate the array + tmp_data = [] + for _ in range(n_atoms): + tmp_data.append(np.concatenate([ + np.random.normal(loc=(i % 2), scale=sigma, size=block_size) + for i in range(num_blocks) + ])) + data = np.array(tmp_data) -The following functions take as input the LENS dataset, and a list of values +The following functions take as input the dataset, and a list of values of time resolutions ∆t, and for each of these perform Onion clustering, and compute the information gain achieved through clustering with that ∆t. @@ -51,11 +56,11 @@ Additionally, the (float) dataset Shannon entropy h_0 is returned. def info_gain_with_onion( delta_t_list: np.ndarray | list[int], - data: Insight, + data: np.array, n_bins: int = 40, ) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, float]: """Performs full information gain analysis with Onion clustering.""" - data_range = (np.min(data.dataset), np.max(data.dataset)) + data_range = (np.min(data), np.max(data)) n_clusters = np.zeros(delta_t_list.size) clusters_frac = [] @@ -64,7 +69,7 @@ Additionally, the (float) dataset Shannon entropy h_0 is returned. for i, delta_t in enumerate(delta_t_list): state_list, labels = dynsight.onion.onion_uni_smooth( - data.dataset, + data, delta_t=delta_t, ) @@ -75,7 +80,7 @@ Additionally, the (float) dataset Shannon entropy h_0 is returned. tmp_frac[0] = 1.0 - np.sum(tmp_frac) clusters_frac.append(tmp_frac) - flat_data = data.dataset.flatten() + flat_data = data.flatten() flat_labels = labels.flatten() info_gain[i], _, h_0, _ = dynsight.analysis.compute_entropy_gain( flat_data, flat_labels, n_bins=n_bins, @@ -88,7 +93,7 @@ Additionally, the (float) dataset Shannon entropy h_0 is returned. for _, lab in enumerate(label_list): mask = labels == lab - selected_points = data.dataset[mask] + selected_points = data[mask] tmp_entr.append( dynsight.analysis.compute_shannon( selected_points, @@ -110,14 +115,15 @@ Additionally, the (float) dataset Shannon entropy h_0 is returned. return n_clusters, cl_frac, info_gain, cl_entr, h_0 # Example usage - _, n_frames = lens.dataset.shape - delta_t_list = np.unique(np.geomspace(1, n_frames, 10, dtype=int)) + _, n_frames = data.shape + delta_t_list = np.unique(np.geomspace(2, n_frames, 10, dtype=int)) n_cl, cl_frac, info_gain, cl_entr, h_0 = info_gain_with_onion( delta_t_list, - lens, + data, ) + A default visualization of the results of this analysis can be obtained with the following function. Be aware that this could require some tweaking to ensure that clusters identified at different ∆t are matched in the way the user want @@ -191,4 +197,4 @@ DESCRIBE THE FIGURE .. testcode:: recipe3-test :hide: - assert np.isclose(info_gain[0], 0.08020785756017804) + assert np.isclose(info_gain[0], 0.1899727144974609) From 14b21dd08b29d6350a56b9a1c4cbccd874192b73 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Wed, 9 Jul 2025 11:54:37 +0200 Subject: [PATCH 28/42] Added description of fig. --- docs/source/info_gain.rst | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/docs/source/info_gain.rst b/docs/source/info_gain.rst index 03e4bfc5..e9978711 100644 --- a/docs/source/info_gain.rst +++ b/docs/source/info_gain.rst @@ -1,7 +1,7 @@ Information gain analysis ========================= -For the theoretical aspects of this work, see INSERT REF. +For the theoretical aspects of this work, see https://doi.org/10.48550/arXiv.2504.12990. This recipe explains how to compute the information gain through clustering analysis. We use a syntetic dataset containing a signal that oscillates @@ -44,7 +44,7 @@ contain: * the number of identified clusters - shape (delta_t_list.size,); * the population fraction of each cluster - shape (delta_t_list.size, n_clust); * the information gain - shape (delta_t_list.size,); -* the Shannon entropy of each cluster - shape (delta_t_list.size, n_clust) +* the Shannon entropy of each cluster - shape (delta_t_list.size, n_clust). Additionally, the (float) dataset Shannon entropy h_0 is returned. @@ -129,8 +129,6 @@ the following function. Be aware that this could require some tweaking to ensure that clusters identified at different ∆t are matched in the way the user want them to. -DESCRIBE THE FIGURE - .. testcode:: recipe3-test from pathlib import Path @@ -193,6 +191,19 @@ DESCRIBE THE FIGURE Path("./source/_static/info_plot.png"), ) +The figure obtained (see below) shows, for each value of ∆t: + +* The initial information (1 - H) of the entire dataset: dashed line; +* The information after clustering: solid line; +* The information gained through clustering ∆I: gray area; +* The Shannon entropy of each of the discovered clusters: colored bands. + +In this case, 2 states are correctly identified for ∆t <= 100 (green and orange), +with an information gain of around 0.2. +For ∆t > 100 all the data points remain unclassified (blue), and the information +gain goes to 0. + +.. image:: _static/info_plot.png .. testcode:: recipe3-test :hide: From e0e197c3f0a0507a1bc7154be8ae79a1b1cbdc29 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Wed, 9 Jul 2025 12:16:06 +0200 Subject: [PATCH 29/42] Added Trj.n_atoms, Trj.n_frames. --- src/dynsight/_internal/trajectory/trajectory.py | 11 +++++++++++ tests/trajectory/test_trj.py | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/src/dynsight/_internal/trajectory/trajectory.py b/src/dynsight/_internal/trajectory/trajectory.py index a5467bcf..bc80e888 100644 --- a/src/dynsight/_internal/trajectory/trajectory.py +++ b/src/dynsight/_internal/trajectory/trajectory.py @@ -36,6 +36,17 @@ class Trj: universe: MDAnalysis.Universe = field() trajslice: slice | None = None + n_atoms: int = field(init=False) + n_frames: int = field(init=False) + + def __post_init__(self) -> None: + n_atoms = len(self.universe.atoms) + if self.trajslice is None: + n_frames = len(self.universe.trajectory) + else: + n_frames = sum(1 for _ in self.universe.trajectory[self.trajslice]) + object.__setattr__(self, "n_atoms", n_atoms) + object.__setattr__(self, "n_frames", n_frames) @classmethod def init_from_universe(cls, universe: MDAnalysis.Universe) -> Trj: diff --git a/tests/trajectory/test_trj.py b/tests/trajectory/test_trj.py index 0f673e29..a845fd7e 100644 --- a/tests/trajectory/test_trj.py +++ b/tests/trajectory/test_trj.py @@ -17,6 +17,8 @@ Trj, ) +TRJ_SHAPE = (2, 21) + # ---------------- Fixtures ---------------- @@ -62,6 +64,8 @@ def test_trj_inits( trj_4 = Trj.init_from_xtc(file_paths["xtc"], file_paths["gro"]) assert len(trj_4.universe.trajectory) == n_frames_xtc + assert trj_1.n_atoms, trj_1.n_frames == TRJ_SHAPE + logger.get() From 7de80406f866aa09c24e91f56b7967149b8a366b Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Thu, 17 Jul 2025 11:16:41 +0200 Subject: [PATCH 30/42] Added warnings on directories. --- docs/source/descr_from_trj.rst | 8 +++++++- docs/source/info_gain.rst | 6 ++++++ docs/source/soap_dim_red.rst | 6 ++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/docs/source/descr_from_trj.rst b/docs/source/descr_from_trj.rst index 9c208fb8..f9844ab8 100644 --- a/docs/source/descr_from_trj.rst +++ b/docs/source/descr_from_trj.rst @@ -4,6 +4,12 @@ Descriptors from a :class:`.trajectory.Trj` This recipe explains how to compute descriptors directly from a :class:`.trajectory.Trj` object. +.. warning:: + + This code works when run from the ``/docs`` directory of the ``dynsight`` + repo. To use it elsewhere, you have to change the ``Path`` variables + accordingly. + SOAP ---- @@ -63,7 +69,7 @@ calculation can be sped up significantly. neigcounts, n_neig = trj.get_coord_number( r_cut=2.0, # cutoff radius for neighbors list selection="all", # compute on a selection of particles - neigcounts=None, # it will be computed and returned + neigcounts=None, # it will be computed and returned ) # Now for LENS we already have neigcounts diff --git a/docs/source/info_gain.rst b/docs/source/info_gain.rst index e9978711..0c2be1ec 100644 --- a/docs/source/info_gain.rst +++ b/docs/source/info_gain.rst @@ -10,6 +10,12 @@ range of time resolutions ∆t. The information gain and the Shannon entropy of the environments is computed for each value of ∆t. The analysis is implemented using onion 2.0.0 ("onion smooth"). +.. warning:: + + This code works when run from the ``/docs`` directory of the ``dynsight`` + repo. To use it elsewhere, you have to change the ``Path`` variables + accordingly. + Let's start by creating a the synthetic dataset: .. testcode:: recipe3-test diff --git a/docs/source/soap_dim_red.rst b/docs/source/soap_dim_red.rst index eac5aa42..be51b820 100644 --- a/docs/source/soap_dim_red.rst +++ b/docs/source/soap_dim_red.rst @@ -16,6 +16,12 @@ Please remember that the SOAP dataset can be very large, due to the high dimensionality, thus calculations can be expensive, and saving to/loading from file quite slow. +.. warning:: + + This code works when run from the ``/docs`` directory of the ``dynsight`` + repo. To use it elsewhere, you have to change the ``Path`` variables + accordingly. + Let's start by creating a :class:`.trajectory.Trj` object to use as a starting point for the examples: From d710b02bdc0a41f5004e21108554760cf2596f72 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Thu, 17 Jul 2025 11:19:39 +0200 Subject: [PATCH 31/42] Minor improvements. --- docs/source/descr_from_trj.rst | 8 +++++--- docs/source/soap_dim_red.rst | 10 ++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/docs/source/descr_from_trj.rst b/docs/source/descr_from_trj.rst index f9844ab8..da116253 100644 --- a/docs/source/descr_from_trj.rst +++ b/docs/source/descr_from_trj.rst @@ -16,9 +16,11 @@ SOAP Computing SOAP for every particle and frame of the trajectory is easy, since it's directly calculated by the :class:`.trajectory.Trj.get_soap()` method. -Please consider that the SOAP dataset can be very large, due to the high -dimensionality, thus calculations can be expensive, and saving to/loading from -file quite slow. +.. warning:: + + Please consider that the SOAP dataset can be very large, due to the high + dimensionality, thus calculations can be expensive, and saving to/loading + from file quite slow. .. testcode:: recipe1-test diff --git a/docs/source/soap_dim_red.rst b/docs/source/soap_dim_red.rst index be51b820..e8c1648a 100644 --- a/docs/source/soap_dim_red.rst +++ b/docs/source/soap_dim_red.rst @@ -9,12 +9,14 @@ descriptors are always stored in an :class:`.trajectory.Insight` variable. All the functions take as optional parameters one or more file paths; if these paths are passed, the function, before computing some quantity from scratch, tries to load it from file, in case it has already been previously computed -and saved. For SOAP, whic is required in all the examples, we use a function +and saved. For SOAP, which is required in all the examples, we use a function from dynsight.utilities. -Please remember that the SOAP dataset can be very large, due to the high -dimensionality, thus calculations can be expensive, and saving to/loading from -file quite slow. +.. warning:: + + Please consider that the SOAP dataset can be very large, due to the high + dimensionality, thus calculations can be expensive, and saving to/loading + from file quite slow. .. warning:: From af0b8289681765cf0258eb336067dbf32c6f5112 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Thu, 17 Jul 2025 11:26:51 +0200 Subject: [PATCH 32/42] All the imports at the top. --- docs/source/descr_from_trj.rst | 13 +++++++------ docs/source/info_gain.rst | 18 ++++++++++-------- docs/source/soap_dim_red.rst | 25 ++++++++++--------------- 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/docs/source/descr_from_trj.rst b/docs/source/descr_from_trj.rst index da116253..51532a2d 100644 --- a/docs/source/descr_from_trj.rst +++ b/docs/source/descr_from_trj.rst @@ -10,6 +10,13 @@ This recipe explains how to compute descriptors directly from a repo. To use it elsewhere, you have to change the ``Path`` variables accordingly. +First of all, we import all the packages and objects we'll need: + +.. testcode:: recipe1-test + + from pathlib import Path + from dynsight.trajectory import Trj + SOAP ---- @@ -24,9 +31,6 @@ it's directly calculated by the :class:`.trajectory.Trj.get_soap()` method. .. testcode:: recipe1-test - from pathlib import Path - from dynsight.trajectory import Trj - # Loading an example trajectory files_path = Path("../tests/systems/") trj = Trj.init_from_xtc( @@ -57,9 +61,6 @@ calculation can be sped up significantly. .. testcode:: recipe1-test - from pathlib import Path - from dynsight.trajectory import Trj - # Loading an example trajectory files_path = Path("../tests/systems/") trj = Trj.init_from_xtc( diff --git a/docs/source/info_gain.rst b/docs/source/info_gain.rst index 0c2be1ec..b7daeed4 100644 --- a/docs/source/info_gain.rst +++ b/docs/source/info_gain.rst @@ -16,11 +16,20 @@ using onion 2.0.0 ("onion smooth"). repo. To use it elsewhere, you have to change the ``Path`` variables accordingly. -Let's start by creating a the synthetic dataset: +First of all, we import all the packages and objects we'll need: .. testcode:: recipe3-test + from pathlib import Path import numpy as np + import dynsight + from dynsight.trajectory import Insight + import matplotlib.pyplot as plt + + +Let's start by creating a the synthetic dataset: + +.. testcode:: recipe3-test # Parameters n_atoms = 10 @@ -56,10 +65,6 @@ Additionally, the (float) dataset Shannon entropy h_0 is returned. .. testcode:: recipe3-test - import numpy as np - import dynsight - from dynsight.trajectory import Insight - def info_gain_with_onion( delta_t_list: np.ndarray | list[int], data: np.array, @@ -137,9 +142,6 @@ them to. .. testcode:: recipe3-test - from pathlib import Path - import matplotlib.pyplot as plt - def plot_info_results( delta_t_list: np.ndarray | list[int], cl_frac: np.ndarray, diff --git a/docs/source/soap_dim_red.rst b/docs/source/soap_dim_red.rst index e8c1648a..8f1c3cc0 100644 --- a/docs/source/soap_dim_red.rst +++ b/docs/source/soap_dim_red.rst @@ -24,13 +24,20 @@ from dynsight.utilities. repo. To use it elsewhere, you have to change the ``Path`` variables accordingly. -Let's start by creating a :class:`.trajectory.Trj` object to use as a -starting point for the examples: +First of all, we import all the packages and objects we'll need: .. testcode:: recipe2-test from pathlib import Path - from dynsight.trajectory import Trj + import dynsight + from dynsight.trajectory import Trj, Insight + from dynsight.utilities import load_or_compute_soap + from sklearn.decomposition import PCA + +Let's start by creating a :class:`.trajectory.Trj` object to use as a +starting point for the examples: + +.. testcode:: recipe2-test # Loading an example trajectory files_path = Path("../tests/systems/") @@ -53,11 +60,6 @@ parameters, and performs the PCA of the corresponding SOAP dataset. .. testcode:: recipe2-test - from pathlib import Path - from dynsight.utilities import load_or_compute_soap - from dynsight.trajectory import Trj, Insight - from sklearn.decomposition import PCA - def compute_soap_pca( trj: Trj, r_cut: float, @@ -129,10 +131,6 @@ parameters, and performs the TICA of the corresponding SOAP dataset. .. testcode:: recipe2-test - from pathlib import Path - import dynsight - from dynsight.trajectory import Trj, Insight - def compute_soap_tica( trj: Trj, r_cut: float, @@ -212,9 +210,6 @@ parameters, and computes the corresponding timeSOAP dataset. .. testcode:: recipe2-test - from pathlib import Path - from dynsight.trajectory import Trj, Insight - def compute_timesoap( trj: Trj, r_cut: float, From 14886f9dedc43f189f2cbaa1de08faab93089057 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Thu, 17 Jul 2025 11:29:42 +0200 Subject: [PATCH 33/42] Solving typos. --- docs/source/info_gain.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/source/info_gain.rst b/docs/source/info_gain.rst index b7daeed4..6e1345b0 100644 --- a/docs/source/info_gain.rst +++ b/docs/source/info_gain.rst @@ -4,7 +4,7 @@ Information gain analysis For the theoretical aspects of this work, see https://doi.org/10.48550/arXiv.2504.12990. This recipe explains how to compute the information gain through clustering -analysis. We use a syntetic dataset containing a signal that oscillates +analysis. We use a synthetic dataset containing a signal that oscillates between 0 and 1, with Gaussian noise. Onion clustering is run on a broad range of time resolutions ∆t. The information gain and the Shannon entropy of the environments is computed for each value of ∆t. The analysis is implemented @@ -47,13 +47,13 @@ Let's start by creating a the synthetic dataset: data = np.array(tmp_data) -The following functions take as input the dataset, and a list of values -of time resolutions ∆t, and for each of these perform Onion clustering, and -compute the information gain achieved through clustering with that ∆t. +The following function takes as input the dataset, and a list of values +of time resolutions ∆t, and for each of these it performs Onion clustering, and +computes the information gain achieved through clustering with that ∆t. Notice that, for now, this only works with univariate datasets. -The function's output is a tuple of np.ndarray, which for each value of ∆t +The function's output is a tuple of ``np.ndarray``, which for each value of ∆t contain: * the number of identified clusters - shape (delta_t_list.size,); From dd284c4e0f77771acaf86a9b18428c1dacb37c50 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Thu, 17 Jul 2025 11:32:23 +0200 Subject: [PATCH 34/42] Minor improvements. --- docs/source/example_info_gain.rst | 2 +- docs/source/index.rst | 16 ++++++++-------- docs/source/info_gain.rst | 2 +- docs/source/trajectory.rst | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/source/example_info_gain.rst b/docs/source/example_info_gain.rst index 9fac3187..884f9c6d 100644 --- a/docs/source/example_info_gain.rst +++ b/docs/source/example_info_gain.rst @@ -1,7 +1,7 @@ Information gain computation ============================ -For the theoretical aspects of this work, see INSERT REF. +For the theoretical aspects of this work, see see https://doi.org/10.48550/arXiv.2504.12990. Here we show how to compute the information gain through clustering. To this end, we create two datasets by simulating the Langevin Dynamics of particles moving in two different bidimensional potential energy landscapes, one with two and one with four minima. We compare the information gain after clustering the particles' trajectories, using either one or both variables. diff --git a/docs/source/index.rst b/docs/source/index.rst index 0ea0ae12..7c32364a 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -17,20 +17,20 @@ .. toctree:: :hidden: :maxdepth: 2 - :caption: Recipes: + :caption: Examples: - Descriptors from a Trj - Dimensionality reduction methods - Information gain analysis + Typical analysis workflow + Information gain + Sample Entropy .. toctree:: :hidden: :maxdepth: 2 - :caption: Examples: + :caption: Recipes: - Typical analysis workflow - Information gain - Sample Entropy + Descriptors from a Trj + Dimensionality reduction methods + Information gain analysis .. toctree:: :hidden: diff --git a/docs/source/info_gain.rst b/docs/source/info_gain.rst index 6e1345b0..ba35c88c 100644 --- a/docs/source/info_gain.rst +++ b/docs/source/info_gain.rst @@ -61,7 +61,7 @@ contain: * the information gain - shape (delta_t_list.size,); * the Shannon entropy of each cluster - shape (delta_t_list.size, n_clust). -Additionally, the (float) dataset Shannon entropy h_0 is returned. +Additionally, the (float) dataset Shannon entropy is returned. .. testcode:: recipe3-test diff --git a/docs/source/trajectory.rst b/docs/source/trajectory.rst index 3ad456de..92adba11 100644 --- a/docs/source/trajectory.rst +++ b/docs/source/trajectory.rst @@ -1,13 +1,13 @@ trajectory ========== -This module offers an object-oriented implementation of the dynsight +This module offers an object-oriented implementation of the ``dynsight`` utilities, to facilitate the workflow of any analysis. Moreover, the ``trajectory`` classes make it easier to save and share results, and have a built-in logging module. The :class:`.trajectory.Trj` class is a container for a MDAnalysis.Universe, -which allows for the computation of all the descriptors implemented in dynsight. +which allows for the computation of all the descriptors implemented in ``dynsight``. These descriptors, as well as the output of subsequent analyses, are stored in :class:`.trajectory.Insight` or :class:`.trajectory.ClusterInsight` objects. From d08fc47a133756741fa57d5f148ad71fb2b88f8b Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Thu, 17 Jul 2025 11:36:18 +0200 Subject: [PATCH 35/42] Improved code explanation. --- docs/source/info_gain.rst | 3 ++- docs/source/trajectory.rst | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/source/info_gain.rst b/docs/source/info_gain.rst index ba35c88c..f9015f94 100644 --- a/docs/source/info_gain.rst +++ b/docs/source/info_gain.rst @@ -138,7 +138,8 @@ Additionally, the (float) dataset Shannon entropy is returned. A default visualization of the results of this analysis can be obtained with the following function. Be aware that this could require some tweaking to ensure that clusters identified at different ∆t are matched in the way the user want -them to. +them to, expecially when different number of clusters are found for different ∆t +values. .. testcode:: recipe3-test diff --git a/docs/source/trajectory.rst b/docs/source/trajectory.rst index 92adba11..07a3f4df 100644 --- a/docs/source/trajectory.rst +++ b/docs/source/trajectory.rst @@ -12,7 +12,7 @@ which allows for the computation of all the descriptors implemented in ``dynsigh These descriptors, as well as the output of subsequent analyses, are stored in :class:`.trajectory.Insight` or :class:`.trajectory.ClusterInsight` objects. -We reccomand the users, when possible, to write code using this module. +We recommend the users, when possible, to write code using this module. Complete examples can be found in the recipes section of this documentation. From 51724ad80c0ac43db77350e7e824174266791b5f Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Thu, 17 Jul 2025 11:37:24 +0200 Subject: [PATCH 36/42] Improved code explanation. --- docs/source/info_gain.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/source/info_gain.rst b/docs/source/info_gain.rst index f9015f94..442a0a8d 100644 --- a/docs/source/info_gain.rst +++ b/docs/source/info_gain.rst @@ -51,7 +51,9 @@ The following function takes as input the dataset, and a list of values of time resolutions ∆t, and for each of these it performs Onion clustering, and computes the information gain achieved through clustering with that ∆t. -Notice that, for now, this only works with univariate datasets. +.. warning:: + + For now, this only works with univariate datasets. The function's output is a tuple of ``np.ndarray``, which for each value of ∆t contain: From 6f3e64701d380ccb0a76f18e4b79f9354bb63c91 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Thu, 17 Jul 2025 11:43:44 +0200 Subject: [PATCH 37/42] Added how to get started section in docs. --- README.rst | 7 +++++++ docs/source/index.rst | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/README.rst b/README.rst index 43464534..d909b678 100644 --- a/README.rst +++ b/README.rst @@ -39,6 +39,13 @@ you will need to install a series of packages. This can be done with with pip:: $ pip install ultralytics PyYAML +How to get started +------------------ + +We suggest you give a read to the ``dynsight.trajectory`` module documentation, +which offers a compact and easy way of using most of the ``dynsight`` tools. +Also, the documentation offers some copiable Recipes and Examples for the most +common analyses. How to contribute ----------------- diff --git a/docs/source/index.rst b/docs/source/index.rst index 7c32364a..e68865ab 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -78,6 +78,13 @@ you will need to install a series of packages. This can be done with with pip:: $ pip install ultralytics PyYAML +How to get started +------------------ + +We suggest you give a read to the ``dynsight.trajectory`` module documentation, +which offers a compact and easy way of using most of the ``dynsight`` tools. +Also, the documentation offers some copiable Recipes and Examples for the most +common analyses. How to contribute ----------------- From 82a1e6faa5c05ed0550e9173b7b9772268406033 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Thu, 17 Jul 2025 14:54:04 +0200 Subject: [PATCH 38/42] Solving mypy problems. --- justfile | 2 +- pyproject.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/justfile b/justfile index 9269edd3..4a1b28f9 100644 --- a/justfile +++ b/justfile @@ -26,7 +26,7 @@ check: ( set -x; ruff format --check . ) echo - ( set -x; mypy . ) + ( set -x; mypy . --exclude 'docs/build' ) echo ( set -x; pytest --cov=src --cov-report term-missing ) diff --git a/pyproject.toml b/pyproject.toml index 180ec4cf..c9f7f3ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -112,5 +112,6 @@ module = [ 'opencv-python.*', 'cv2.*', 'deeptime.*', + 'sklearn.decomposition.*' ] ignore_missing_imports = true From e54563535f509146052c1feba4a4ab9cd2c7c724 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Thu, 17 Jul 2025 15:14:52 +0200 Subject: [PATCH 39/42] Added downloadable script from recipes. --- docs/source/_static/info_plot.png | Bin 143272 -> 145924 bytes docs/source/_static/recipes/__init__.py | 1 + docs/source/_static/recipes/descr_from_trj.py | 50 +++++ docs/source/_static/recipes/info_gain.py | 179 ++++++++++++++++++ docs/source/_static/recipes/soap_dim_red.py | 179 ++++++++++++++++++ docs/source/descr_from_trj.rst | 4 + docs/source/info_gain.rst | 30 +-- docs/source/soap_dim_red.rst | 4 + 8 files changed, 436 insertions(+), 11 deletions(-) create mode 100644 docs/source/_static/recipes/__init__.py create mode 100644 docs/source/_static/recipes/descr_from_trj.py create mode 100644 docs/source/_static/recipes/info_gain.py create mode 100644 docs/source/_static/recipes/soap_dim_red.py diff --git a/docs/source/_static/info_plot.png b/docs/source/_static/info_plot.png index 327716dc5559793b765a744c1f9850d0745c68ab..96c9d0af45b6a6f784cea59d2c07cc313cb0b9a5 100644 GIT binary patch literal 145924 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 F`hQ#mDr^7% literal 143272 zcmeEP_ghrQ*IzYiVmC^Wst`r#1Q4YgL5zri6e%JIQY?T-@2F9cYNJRO1ObuWyHP*^ zSx|};K|y+1=^fs=?A|+r&-V{_e+Wn5g6Bob-s-zVkH zl1SUZubX9m-2na*%iH)D_>Z`ayq1lcrHPIG#T&*XrHeM#uUXn$yKK1E&iID)WlIZT zej!1AVcxxFHa6F-#RUY+i6{6iZMFL z2UrO5vv=QG1LRNe>q*c5hM{ugKi=S)@t@w{oFM&YQ#dRB0}7lI{{aQgiT{8C=frPW%TH1SkFj3Y-=H0R_&9|9}GL#D73RaN<9pz*+GhP~e>S z4=8X>{09^SC;s09#aRJo66s^Qb#F~BrFh=3w?@Jp%eF48*nw(s9Bwb^`9vKs#&R$-p=h2CFg$)RbHlate`=4kKR^$h2C zSh~-*cI9^YNyt53iw>ZETywX)>eLQW(T}gUx0i?8w;x@$ZPK$Z>+3UXBCF3Td{tAH zqKjM{GVPihO!3z%uw$(kzI*p>XE?>h)Me%kyI)Y@_x(~4JJ3O+LVhVNz1T0aJWIAV z>{wo;xNlqtOI-SOVZ^?KnSJ5w#;*5Vkwfptv2g}oruZqlbnZ$sEc1$x+_h?$#9vBf z$08g$@6U9xFXt-%n18!VdE$Gs#{AABqM~%{Go>3lTRWEQ^dsDRo|={`yNx~moNHyI zAA#)$5I-vG*Bb0~d=YM^)8*+92r_j}AP4-=0=#_Dm*^Itmu;Vw6HQZm1 zv(Kq4bTX7^-RP(c;OY88akF3OQ;_j;U!Ly}5)#@;mK;AVIrffobUbodGP!teK&!-U z@e$dv@7cZ1VM}-C)5^-zhA!y99;e=WMIWqWTN@Sn>5K&5NYQkAv1Gv}nYHdy8IfhW z?PG!ar}b{U-#^++b~}9d+UHu^jtD8|&X%hwzRIoxYC^)opKK`_=k(}+bib_mu!?9E zTZ~5=cab8m|NGl0Ap3~hY?Z#<7qLE>wOj`dbUsl#b6SFDKx1^^T#0yN zvR*+4nU9Oa_MQEvg#C!mhfuMK@87>iJM$OMbk2O+?mkmkGy5+?@s4vB9F3c#F!k;7 zwRGtk7hg3&6gQ@p#j_tQ%jYHsjj96qtlF$9_~xxOwtJ-H^@PlP=aR|mn|t@}QN2c4X3r1#v-mnO`&sI6#U_)15y0@x|jpWfj-!0(YEV?As z>B(u>nr$v6VL90N%4)9vh5eUtV2>rHy{o3)^5+`CQj!jLc2Qrnx8dYKgOt?xSd{=J zf9W>+f`NhM`BfW8efz=F9+z`kt*ZEPY`%;q+ZVm;?Je$NrFc3O75B}(*)GH4KKCio z$&G&%ZBaW(>$U_-Pzr@lC@3)K>8BaWhdGbrNy*rM2obdcHf;CBdhk`w)WUi6HIHMQ zqz#OMIbZB_nyP>}Pb~BOA znJ$0I;1&U=I`8~s0Z~qLT-gSI8XMlN+b&say9iLuN9R>z)1JUh9zh{H(dVKDFmk`Y z-pD?bUkp&In4DU_XZ6;d$H>Yfbqegm`EEclCtdHx)@WS;dzkRYBN4cbEf2ya?CtdQ zb1d{aOac73HciHw`~n{$k>bTMt!M_UXqt@i6HlZF^V*i56<+N?^ooYokov-3L^vf5 zVoDFj8t{4l{(W#rh!-7?=7eit_gv+<;@|aw{?EJBEKYZ@1MB7BxRRw)e``ucq`hzvd6kb!G!<|JMB{BFFR zBufzq{g6C3>9oAucCR}utv(E807>HjCc&Q={3a6Umq%vnaPnZ5&MUx_ULVbu4b!Xr z#UIcU1*%P2C7-S*#5B)_{Sst&mYgZN#DC~YNwDHxYYYAiRAI*lIo?5l!x+i za-&HUhT?N_)o#Wak@t%z4D(C*Qu8#0G)NV_;>a?&d`Ws}GR1w7CoV27V!U{B9x3sS z`ySGk2eC`Xi<_@ax!!#vL~74A*S*%7{fg2X<}{En3NU{7C?(S717T(DV3?+fLDJ+dvdgBOM!oMwE1+jId!z9Orq&u^%aWk@(uRWsjhZ4_BEq-Jk1d9 z`XOE+BfP?J`>7q+N=J3D(8SkFUdkk0r&`W+>LtCfHea0g8JjlVv0y)^(+XUNBe=z{ zev)TXlP}uElrtWDrRkS)ToxsxA|$=uwT3^* zd6DiJFTXo0PuGW8=y5|d>!ewChU(}w8_DU#)74+jpZD*Nw_V%S9P0JLyT-g+O`b2V zb+$d!r!~t=zP+^>SC6PmE862UIgmUU6B7gUCqX!H1qwV~r+4W3=t?*eUZ{6vOwe92SUb8av1#5XY$_RaoYbJRM$CmK)Fz6W$OL zAQ~Oe5KR~U&cTFVB*NE6SDTAFg8zz;Faw$Cv#XM9$*{L=x86wa20nAqbw3JQQJckh* z4Et#SQe)i973p$g%hs*(8O`Ty$QaO?hFP7^uMzO#up9bZXG>0a5z!KqfvwwP?9xMd zz82N1%ELgi=S&3XEt=@t4ck1Qu75UqS~GIHPp^fDMU6svczmw*cOkuci4;};emgeu z?r>&biDzlLG;<|+*sM6j+FBJ1EUbVN)QY$b?D~NZ>CNC zI-9~*PM(;0E#&My>SA!-TeHzq^DqNlQ%pdEk<-%QuDo1_!-D+c6tS3HyOkCALWXNz ztr&_|;jTY`@@`O5l?$}xmnUa%q&Lf)*&Dj(MoHmJj}HFwNt?_$<)*(ogJRpr={-B0 z?pZV6+~)r(uXjYs$nEYyj;W{nrbe23=S>%#+#>R(Ba3o^rR*v5j`U>LlHk??O5V=- zrL3pRgPOY^$~#k*qCJD%OES2;iiAzdhBCaSq_0|&$zIL9WHdI8p2Rk;k z;gHfJwq>{8{mH`-xs^^r)iiDIUf&`s)58oR{0;(M@5axtFllF7USb+9`ewRw=jL1W zlC8`}CY#q)t?%WPbax{!47T^#SpLYf{Qgv-?x^+1bhdJ?cJc2JZU9_g}->l$B`zhhFTZ_&AlFQo34=lK;KH3|$t7D-@j6rW1_@FO289A06?Y4_y);0aD%@|uq z2~{zkg~5JiO4C!XwdLwLymW+|Z(9L_Tmez5#`}J~#gR`-@^ahr(sKLSuC;~vdQaPj z_GNU{yR{t9Li-RIKpZR=uX>rRkCiPJhYYLl2t|%r=+IHKgPxN7}bLO3AEb zryhQHau^j(+qPc|5dWRLZ}*+!<{D`QL$omMYt%|qVOjKby?`f{8tY9jfY^OxHqXAp z)n4*P={oOZQ|;_aVOywE7m0ji;&Y}&T}KXLs6XLnUl=nux83c>?TE;{dSU(fmZtK2 z+d(3l=8das-}S~ZV>N$k_XnN-XuCLFvh3RC*c%QaenUf!;>lN*QYlZVb44|!zcV~; z6#dhChhBvJZW?Z@*(4P?TW#uO*WOe-mE|yy@Pb}X24tvRo!$Z?&5qO|QqK>LrKKxS z|L|CcMMo;<^j&S6CL@<7UZlCsPxZRifLg^K?9YOcyrJ|e!-hl+@;oo~l_M%IGe%dv zf8=dC@8H~I#B|{cuHHgGuCLmeqp^b#iULI8DLdMmKVmm(kj?= zr>tMZ#dU%V%Kg0k7hAn)^UtaKq^HvS`R4Pe6xCk!or++r2{rbo4Y%?6g((uL%Bq6Z z{;kZ?sQ

Y8wgpf>9_Tg6y@@TRy9U+n^ctMpfLK=+{jvQwB{%jHq<0e^n4eaXCD z;X=27zrWi=j8(I7P}#e8@7$(8fb>vF?8|QU*>?(^OY;oCX-9h?prIE8!IVG-I>r0u%EPN=g6z9<% zv67=L!&A}oAO@uayw-5}&dGis#D0@l{#XHW-Wbi7WgwaEB)czJU+X9?x_Yv(_MXhb zH;hZpldaVGJZ@+6vwO2zoo+Uweo&geQW*gmwUJ8~bBAXYe*v#obYH$bIYJ6cB(V(t zMs2U2Q-ADe0w`HT$KnS%y-^p zw(#VwnseGloshRFk&y?!2W)Fo-ojW_SEH__ukB#t#rV)RO>}G`e|#O$|NpBlEBAI_;z)Svq(eVQgNvOc}` zwRq(xQndJqR~O5(0=vqYEq$0R3)6;#oWOC=bcJC1vG-gRK_v^_GoTp74uW;duBlc_ zfAE2TRfp?z8BjJO7Z*vLSDHRPK5s!<$ckm4o%L$UzScEIxoTvV7jAF5NAqG^2Co>U zarzx{roodI{Te}1otcOss2-#No~0{LAM_~J3il0?qGf`-x|oX7eipM4u4^3z?^AyS zf1J=!4j^6u+DQ9?(cveHseR>AXU7aFy=sc8aj|j z>i;JGML@+dF(U6DTNuc&do#MG7 zltv9IK~f4w?T^ z)6~e=pUM@|{0^v!cBk>T_wpf+-))WgpN}7|5Ag|r!Hz)$Two?|`sey!UL34~xuBw2 znoDcqiYllKnbDSis1Vf&2iu%fRZ&F?#?V)IQ^leAai1a9mRbsF%0q_n$+Rat z6dhCzErWQ`ojlM-t6YQxuLoh15e$&y1tC8&lBy#4@nC`*S0WPW2k*;_FSz2$-XU<0 z6k)6(M5v%Th$(3+|EhhW#eyc|C`mZC>7FY}Zz~H4)lr9d_*MHSx(-6R+>$;Zbe)1+ zVZWLV>4JDnnleJ^f|D4?+|?z7D7)$fdFMYhdkAokx&@g$zgn$i*TePGryX|B$AKY! zFQk~G@lpXH-%SuNc@0s*9uN#O*!kvF9UhLMlY48`MWE0S&xlO&6UX3JvJ6+pUl8+q zL145=JHSrBJNF5KleJ}uQzOLuhH&wETXIhP?}4JF_MjRDn`=Dyf1+y#B>DHo9%ZPo zFb2~4H^e20U?lp2W)`C1=nL1c5)n=Osuwc3x;$O-@dPmbS7dfTm|9mq?xv#G;48Bpqlad>O6b|ug<&D3Av%1tf{o;xkIX2qaAW zgxbj`Q*ja0sb$geRe$Cd#FT1Pz^yCnkXy(y@4e18B)Ebgs^o;}oqF0q1Tz>-dN}rl z($oBx3NzFb$G)dbf8)wPkB*=G(E%0WW`wNcKauqZ;q-%Fyq-!Uray+vGvHtMzdsM< ze@?IknL~|Sf09@qg1?fs0p&3g_JWhNY(~ciYDxq^0gZWwfju;3fv{P+Hpz^KV81tn zP2N&j&6C9XLG7FRDoM+u_%bfM2FMmIkBEea#5#oF`quYx`zqLv7!Y$Kz_s?$Ljb~~ z^}^J#%@9CcuT!T<*djdwf>Ae<9yqO~zQ6}I0%&BV%DR5SCrtzeBjRHzHO>Ss>R+{g zL6F~EufgO$()OB|8^NvhAc)ZzCLp2~!Ayr;e*iYI8L(2F^bmnCQ_t)TzAbD`_d50Ub7DNcyfC(jELg<^3DgH*4 z3xxD2o%Nqp@G_W3GqU>6vKAt^9}j_j*iq%%BKZkxM90yxy!^-i zd?Ejo(L=Hl5l1|R7F@3dK;jy^BEd-nTW&ui%61tDgKyt#Gb4oZ8x#sFi?kjA!3WTB zB0drxNCbW1yW%Rcb|GY8*oBgXVAtc<1X%$%SdmBrm*f#{!BjQs%qngnQ~a%ra0`85 zY_$+yBa{5GT8Ot1Y1J7JLL7rCZ!3bRJo>n5M<&hRdZ3TjtHCH@1B~h7V_Yutj^({4 z+>Zg&UU2|i0mDXkgj!pQ%zpSYUbQnYLEd0S^!+BXyd+BR;6LfqI*2lV zJdmg7X{|VmhplUHDoCW?_gupz`J)O_dVk9$7y`<|$>rvv38%glLgIsy$_QM+P)n9$ z_M_H!>&JwI43H^6NK@$tLmELi%Rd{ep^skmc{+4DFfx<<%k>)rEnc2+M22xXMPwII zuOT4)UKv!*fnewc7&M*4u*%Mdh~n2ltoq|{Fbw}zef|JK=uKpnK_XiIv5YW$5Q&!2 znR)e@yj?8*#Jvg=%qRDz@uo9cz!-i5L>My?3hX=J+BXOyR2_pvTJ?Ofx=->oNEQMYYkra-37KA~9yp@4RIjxaCWy6rHy9Gg&V-D0Y(j~Fa71em zdgaJZ^l2eAGK}C@tf7rDp;r%JQWbS081T7wO(oC04Q@TKTHQI2Swub`CM1Y>bEaA^7-9Vm%|j## z3E)q{bfeb837^k9kjS&5)^sbD^;Ht_!d_S_kX?tNI;=Z9K(%CRwr?z+>LI0y4OtxL z2$uYU&j+r@NwmB|sN3&2nvzH&@oY5sEschmr>%nnkTKpOX zTp%5RGiRWrlnnMl35p|Xb(2VB*xx3y4dDR8LfR7bINr)_ntcHS5 z;sKvHq7V0xQb_$xNbcWTzHh=2KxHH3?twZnJ{l@%Z9!HMjfBUxFmf~d{U;eB;PV)i z*}g$P7>|6lYtI#CMO;ys5Jh>2WI0z5fRmexTVG0L^(zFITo*yj~R1l(R&2#zPaa+OtxKz9V4y zcz}NuxN{={NmwmH^sBUI*=cy%8xL9^Xyz%q3&h8Sc~&B9OtN$$fHV=&xVK0&s$z_& zR-k~d{JFzK{;Ywl#W2qkRV{8r>+(>#I3Qh*QM$Ykx{^`45U2VbrAr>6E9fV>5S6&` z6I~F6GCfebeus2z?jsZVzRG?$4Sgyv45v;(dikPW!2DSQnR^WglxrKSZt3IDV3d?j*Np<9kMd-s-PvMBU z9!e_H^Ss;^dp|r-E?o;fgU-9_u-r|L$mFj%+@Z>5KsC*LV5~~`ZghqRNNGk3$tgC! z4=RrqK85ELsYuvK|H#|(TMdy@Xd!hu?>!bo_+GjeS>tJU++~{~K@nHI5!@~qtx6F>YLRPIB zrX5zXg1Hd&1ep%PD#7iDhCTtTf^H{xBYex7=?W-|tXaVX4@YE;@km8^9KkGASKKq3 zoj_)2kPszmMXMg4eQ${9dJm!^(KmJqwFyPwT(m~Gc=0&M^l9~JK_t+jKMXS+1HTrv z?WFjC#rf$9sp+;|*qQg;-etkT!JhjS1Lc&Jm07Ib?i_v2C3Q$#LPCvv?TEkR*h$Hm zueZ~#HYFdV_fE6yD1MjDJ2vYwF){HLYg~NC>F;y%=FNIF8b7rA@GT?R3;+;(-GRCm z_rW>9@wCgI;;leEtA9}*3eFolyjQ$%_D!ts#pR_%tI39Q z6#?fi>;XMl!A)Xzly+8d%GV1taIG{@f<}Q|o!I%r!XaaU@v2Jd?9{yG#G!3+x&w!( zA61{_pCozQ$sJ5C=$!bZ?2olXT6?)~H^!Rmz@gE%8K7e}cYdVcWoGIqc2G3UY%FMJ1*2U-0@bUtkveU=MouHA=rJ&tPp9Asm2HSoqmHjj~WGcg~3>xaX zbUWrWHA?0IiJTErnJ>z)4#`9}u`I(hMuzj(kAdUH0{1~HWvU5fs4Y+U!bCJf8IS&K zB~XC)W(g|kr9)e@Krxc`2g|P>H{&uvBbmdfw?2!JQP!;DKw4Vb%5hh$g;l9o-?G4- z;%6!~sEr-UOti4PVB4TE8rCbxH8s?%mLo>fi{s4ih)7WoM2b=U=fQJU{jovi6B9N{ z9Zw@7{IK)Ym;{<8!gY9dZ?bCCHZ7YPZXE<2Tj1E@k=`)th2Lqe_>V>gnk9Ld05=g* z`6{QKDaG-_RTH}92&^mV^>#Nw(1S|vJT-Lx_QvhySgWf<$LtxGuj|-7u@l6dVsS5C zbcv=og3C42W0}Su=VG0W6@IK4`2{xpA05hgF6?BV|6I|T-D=^@zVzeXC^)5A_V%ru zO?O+SuEZ2SRnTuieKEfo`6q9l;`Pu1B@snhSUVKQJMHtJo7ZaQ+dc9?tH1P|*?GtA0IS*Vpo*L8HgdNwgDzdhl1beX z(U+DviCI^hu-@%i#pQV;f2qSGz!HD)HanTKtoSx!Y}uW9Al4u`j-&I^N3^XMmuCSmVyjgsVlvT|0Uxx)@GMxTotHYR%6(-Q!#1bESEG$N#kP&0hgZ(s-Mw%; zoZ_>*KwkF2dI&ogbHJf=AyHA$K??0KP{ZTZSPZ&LYj=+T*uc8En33*ycAX({t>gn+~uYDs`fo>Y<|oZx%>PiMsgiX z#_L~5i(2G+5&;*dO5H>LM=F3plxe?Nfsvi zw_MVy0ZP<)WX-pHC!!@mMPMV}zPK+hjy@&3#0`amv)*5r~?~hBjuQ}4?b7Z_)_~lejUT*|5*{Lz3vVC^0spLY|G<7PE zy#7!&!cS`h#N2AxRqm_G9bh7mAYA( z;0^+CVqUpfBE@a;<;x|D*ky^KmMk7O(Ce?cs7DGzC^Wziz{(>&PnWx^sPl<{V~Vx4hb`M#3hahMMkOQ36;&6e(i4jv>*N{a zO-*}!dbi6gT*r=;#}9-yWZP5P(|dW&C1b8Du|(p?5k}BBXiQn4EH7C$bgZWi%3US@ z7D-#GZ(+*-N3eq`BO*apa^0s-Y7JuZb90@JWakUb5&?Fx+3w3r>AhK=?#q#&v-OFT z`%qfNm8q4M9ui5VU1eSi-yWe3Cf4p?)I1J4gL4j0H0MUJzKW1SUA}wlZVt`kZ?;J! znOL5iv$M3c{LoI@XRAa4eFJ&`{%=}9_pJ-KG(f<)w_2E-^u85q)o30Eip>d{0@xeA z4`1n{Pz0QpKs#dN(D12_YuqXoT>DQAD{tEb<*Avcs@qf@YxPVw`!pZ^(`-H z-lOF`C|m4_#Wy+PK`<|pG~AjKBqg&n({**uEtVp7gT%6P6dZ9c8JaCwY%S4P{E*_( z&0|a^18Ybup`C82zOc%FMyY9Gbso?JNY>0Qf(9_G}MXpk!ezcW&S%!$OUM^w`6hR=|lp z*}CDuXW;rPBc`XO z8jTfzDf#&NesH*O*)-+|rEt76F4V$na}8Qe!1u)df)diOu5v=~IJgz9X| z)~V9&loe-6DsB7C zZA+Fvo^UdO+P~RJ5JvDgyM4ZRufezi<9o!pmS(d#fL)b5DLyi@k7e%jq!j)sz1Xi@ z0qzaa&7$^mW1T*3fEuwIdFLC7b+2OC0MpIJuvvuoW-aw?EJswP z3X6)QmzQpxqNukt$7{aQp`$odNOTraTrI;~#@=sUYX6NZYzJ7E;U(tbE{6 z1~&ago}VfylsI}+JBT%)y}z$7zRK@T{%lWZ7r5ZT-`{VlLCa$K@$FLT zQ_h$NO47~Y$6P09Ks%qcbW$S+yGdZ`v(eS18rSJBm?oyo(vU-t`Hgv*gP;?>Rr+-Y za6!itC#v!@?rXn%*1Ya3Xk&8I9HoG6HU>-Q*49pYw_babg~@Kr;CCvp?Boi&{?~b% zI(ea^NB2a66s%KVc}xJi7A9=86;rP;tMWZopOnNJ_NRyYV?AY~AZ{t{p(N=QWDmJ( zQn{|849-z$h&&pmv)A2dK>JbqGS4IIPUjnY4Eu3vm)b?)4`YrsC+r;Dcp zia>McbQ$~dC_8zcmAZzgd?!U>`_*6ri1zkPPEQ9(vG3WFP~}%wSC`%!U>BDTZobG} znj5TY&ztzDh}|}0)X=^VBQqC6#ok$PXAo1z;)wmrsRPt;1>Hd{9jUb3Tk%MxrLxWA z0JfVX*S3S;jpfMosG;x^TRnIdnJ6g>l__sK7Cv;SFMa{U770m8o}a40g66~$TH0By z2i&GO*J`mlwRN$b8?71nQgAi@;^B_S4>eA$AQ-vUl9@0RF0=Sa#@9t!e=;YCSNnHM zaJv*(!c@!E!KuwPR6=DPfiB@i)+4{HaF$D1F3ZCD;#u5gzKJ@Qq@)O7m>*O${>swzr3s#bWaRMTl|)}q zj}b`%300s}2|(SI;Nx6NP$lT6*Pp_!7)hSJizS#tv%s5ZjMIWGSz`oolb!{jtlMj43XlwDIzND>dE)2=(e(SlGvl_gFz>2rfTJn7w<- zl2<$ZIUK8>OjHYgY{oD~VlXMAG6K8G>ec%Kta-R9BGPrLS=2Fy>F&LIRS_~ED;Mp+ z?kEEgz{Hd|OAD9{>;mu5)*e-dt#u0I#koVXAS~?!?Uu;{p&j$>(^%dw9AT=hX?5} zPk|Yh9YBWllG{=WEOPX{vRnF4I94OmaD1tGMryL&%f20~p>b%jWNEMj#BqnA!pOfh z=p{B97q$Q+`*C4uEC_@&UwwLa?b?MU;#u65McsUs_klz|I7o|#?8dH*dO4=~O0xTq z@_o^(jR4phG|n}AKewW3O&6TanOwCPFFc$`?#q5S-O`iUCQehTu5^yP7^T5!w~Gizfq7f76Q z+~;$QE?v5GjIxjfyxSj`uLE}maXV9PZRU?}38l_0Yl|GknE_WFMI9>aSF-d14f=pf z-u(Fov7E-ybs4KeVpn|`Q<5$euGn_m3Pv2BtrCCQZu+yMU?~^wyI5 zTd|r%C$@ADa|RS)&?=B$P|!OutiEC6MpHT-cdXYMSX{Bqps+}O6Cp(ye+5~n@S#D3r)lTgCDsX9_CtVY4rVxockdg2tz z=b08?@@KFzEY>@1*ir17F=q-&mkii_7G0pqY@%`4#?G!BT=v0$IU9}QjZ|f-F9(}J zYaYX^iTz)W)}km;j`j>41yvys@rz>CyYj>cdUu8#iw3 zN_?4&Rm(y7OJAe7`5<-^+vm*7YA#FTk^Y!>GogfGHwgACyNj==dy$jvhjyBZC%&|Y zr%~L%k$90J%zj5omY1+XABILxo5cL2rarIyiB%ZA&J{*iZf33mISB)(^LvBK_?TDj z^3zPxO8aU#H9cJcFq8#c5#@^B@WEUm_A5rec)^9O5DS*OK!wAr7i>6SmHd2j zDR7yKp_5a-1?9tcYy$w?c_@Wl15xJ3D$$9-H0E)z+i>1uci~|b^!xYke=c!%my@%x zwJigK8=9FN#L^~EmbeeLP52{5eN5kiTRu3d(%-ssP}g9vZzajxxt+D|Zz*bsYETCf zdcIz)&?*V!a#||p@+EEh3U+rF7T|9ZUQk~o-QSu+*YynFyLuj|NCP);^G`W)G;S{* z^pHpkZ`1L|ML^YrHV)`1trLd8gzs~aNME_~SFu-X0uCkjc6m|Y(H8sD&uM3#Q~U62 zl|-6J_y*fc>s-w$KM&c$`S`(Eli< z?Kzc%Z`q7mC-92X zBne0`$&_56wL{1jL5>HjB3&)sevnstej+O#k`=6q`4=|)9KC@mJT{@ycwHCo#_*7b z7g5M+FKXirajQSCdV`-}tcSbd9_iq4Dt1nJ_>zNN~Ja zZV`TnxilJiC3*=z*rFl;S;dVMYv{K^0n$yLAr14&r`muwYoT!5^r2w9o%1^`k9vg^KTEOWw%Uct{}fnskGU>4rE zQHz}VuhyBqw67)OEPkqr4}GWGQ2cHyk;$1|hD_-X>og!p4{MiZXb%Y;Yl zN!IB^dYc8$6d0UwQjEdR6s&suqaL@MvnGDk+vrCxVGhG{IJ#P$MY5Mn30K-FPVQpZL|*b?nhKBYCl48 z&}(?uO9$*#(ICjfQ5$v+u71Jz6J!fA$@oWI9MtQ$TY+vvxy?Y=+EIN3d-DPt5ugGK=@*Pt3v%9B9gG zlvyAPr173ae+^-lF=UojYBzCIC~DQ`$i^ifyj-R9mTk}`Bw9544Vi;?H9jap*ixap zZBCrZ$pkenoGuNa2gGr!+TYU?seJ&3>xI6+OZbflpI`5r;SBpcCfGP1^ znavh^qFJMM0-5H6N-MD!sRa8FWgCz!Xb~xd-V9!%AhYUoYX_oN$|DYjUr|?Zx;&QO zw1+D+Yd1M|F1N)#(n(i&P#L}B*ey@hn|tGJ3V7l(H?NEF@tml$dSl#@-5RlH(U#|n zRK*_M0^PUWEV{=|WXhX2X+AjiAUpQhW6!Osf9%!VfAgQ%>^}ldeVJcaGCTP4QKD{Z z(X{hmd(&W;c!E=L$Gl4i`BiGzc-!>&N>FT|szy7E3@$FZGWM{nCA%oWh$;%+E1ODj zp{O^6MAN)}>0bwF5fs?C)p&X1b^_=BcwWOEe~R}XynB*F(#VQ#ixgkG@_cD@9MKpl zt6}T6^~AnPVrm^^Y7Oaht=4QYTj~*A4|zpe*CPnX6Lr^69`Z?{7QXhmZp>(kdxI(TPUTHN| z$MG=%ep&oPl^H@+14@+=LX{3dRlFSXvG`fqA5k3890#t*_dmq#lqm#RM8na;jCT&c zpn*YcDzcK7z#Q|<^>K6DiojRCt}e?dnifZaeOYQ^3ar8Y`_LI?-x=Dr7S{_=HG=68T+H7|eA{Aano|1! zuH>Yl24RYbh5k{;iqoP7Y2AB2pnHj66*{_&4~q06ERfzu0BSXJh81yozdmpBd}%0h_JV5wZiW} z=1$(xt@R~a0C$>qqu}(%wbU5T;N0H_mtVWXX%iIJFHj|z{<1#|`H0}@zNCZG1mls} z&3+9xx~=MY12?z#Q0HrRY*O`WFegy!B(BY1op;mX1aZeGOV}Q0tn-P0Xoij@n4du~ z@)3eT7ZJK1gh63#jag-jdk-ON1c48V5Pu^it2FMui>vp^Q&8>ietgW1>(Q#QPT3PE z|KJHSy)hCk?-7A^$f$ zXXdQEtd+J1l{s2Jt_f9|SxS@Px)f|fx2wnG9yvVhV&~wC+^Iup*SwmHcQt-c z(h>{J9r@PldhG^(=Yza^7n=XsA|&+Y8|A}W$_pt=yBPtCxx8InXJ#%gEK0eIJRkg^ z6ejUykSj@|d;a$6QF_w3aXbrB^it2QLXLC(ML27pn4&n=~pPPJ6Hrf4}1l zcNY6$$q&;RkrMrdY74f(>e7)~Ns$+`_B4gZ@v=Ye={ZnjV%MR3?qf>W#kiqQLCf34 zf;O_B=KiKU=^W{h{CD?w!k^XS-!?yH`$h1BDC-zch?dRr7bi7ViSGgp&o{ELEIE^v zq|3eyem@Xt)MC4B{<2q6^Mv+`;`ZbJvd)FPar1k#q(gR*`c%aAsl+nxvb*~y^8Ge- zimJMs@&WzIi%oxai>q}956o>_%=^nPp@(H|bLbq)J(H&{Ep6&0smFUyKb@={J)U0k zgIuF7!?t99*koy5{7qOwg{e;OgV96Fvl0_)ZwQxg3G0!cb+HA4Sd;In(#4ZBWi$JG zMZ0Q$y`k3ly4<+rYR`vn&#i+chX36x!ADo!EfrZcbM16f%*%7jB}{{TYir(2#I`k; zm`D%Goj%8!d`&v#SwE}JrsN-69v|{v`b5{kRb*nZozZOn-_D=!FE4WjO-x5DxfeeQ z__5tNN^UW0Y~8PMF5nC``S+)D&tyyH6U4VSK5cc3{&!{~<^6|QQMHt#Wmn^zI!v5? ze0 zR~DFk;kD*2f7arf?;Xk(AFpmFA6}e1Jt-LecgoWV!PILX)9yd!l4ddf=veN~uVTQwR$}5_ZU8K~Cdh98>76T=>)m};UuQATN1?)~PNeTCyBQz7! zVma_cGTqZlukBjmR8?U_x?tp(%i}BG6fGTJEfiRGUyXcs`)1;cc1rhowk6?K{_gV^ zT6Zs2-&wfTGj=H^&LLyK@@)T+14X|6bdhA~VDGM}sU|T7jRw}+xNrUAp)&2%4p8_S zU{&Y&)6XwdoLd-q88+{q(!O8u_j{L~AztLw6mrMAR6*F3~C{lr+;rw6NcQ7-nY^IhyRMA$DsI z4QNG(Z`fQ5!9OaQKvR#nrh?~Ew!hFvNf04XJP+hU|73Sn0%t0Tr*a)Gz4`#ihY2=r zcAv#Nh69Y%YQ3LjzyEcgx?gHWgm)y_PgOT|x`tP&RTxA7=O9|8NJjI^C=awCWzF+5rzVo?( zU#mZPjmhF6lP&ZenLh2&{-<~~!;RKG^d{l}+i%JARD~hc{%Ln9hWoj<`cFEA%usH2 zDXqZB5wPM@OJ_SC#ttB=d#FgUMNPpV!fA{!h59>?2WRItCF~N^|AL2JnHwMjV%s8p z%gx#q4$#NYb>Acg|Mv?ojlihbOFPptjO4-e$1zDjjrssJitmNx`$zRVgYN++qhv*- z7osnSXe%?UJxuQs!%NY!B0}CUBB{N>cF4c{I%ZsT0}BQ?BhmLG&hyWS2gaUxEopO) zwzS#>L{9Zhnx|QBI%=u1;i-635BfEO(TZJFtFB&z60(TP`kG$%S_;lq82J69P%wC@ zO`qHC!4QisW7U_Nq{Y)1U)5~Ka~2h~5kqRl0&^v%c6-ZjV1q5Uu#`|^ze>6BE?e?MxUrMP2dz%xO1=~q?1UguE2Q7 z?6PxZjL;*2=YFqQUL6`y!Xsc4gp9y$4m%ruW!BqAb;60zE((33sVVyp+h2O(B{txR zar_>rRo#<4r!XRTDrtntj>8IuCRbD2`nOr${@k_Ex67DB=Ok z{`!t6;6xoD_&{Q7$jKB2t2BVJI0N7JAK-a@ru6*kC8$F%FO9JaQ0OwKsW?RMz1l7` zdj05V=2aR~ndhmuf@0eM7~@3|6fJmAX+Y+b+ToNhx-40Y%-N=2N4_yNDQb#z&X^zaH)inzMo$8_E&l--EpX`)pq zwQ&GM9ZcIV#aQj7bkTVqLmas1hzbq@r#ZbnS;KjN*P_=9BnrLpOmLZ-=2`-u`<3$A z1a9DDAd>Awi1$&q+Rq=d{l(P`leBxL2i@ft=7DSb7#dtQ9bi;Xjh1|XSJiL9 zthZWKUjYOv>a`k7p67{LeXtlp!2sXPJ9$o?)v_qeV!*MPGO6zERhd#%sGNE-gBVHYqRSHa6F; zL@JkU0)Rph=G}9e$V3d*%o*~g^D465KJ=49)j)308xX+?6S|J4P-WIm9wLb)HLRye z*kBX_p;lD;U;MVe#MOlpwkv1~&2n=l53?@_|F3iEsA|%-4d~gSrmSc3=4I={qJOnM zZq$KS!&ObBv5&g#@$4!6ub-0!u?r|&G(_pKHDvEwU5u? zWH2BPyt}beLOck>5xf0-h}g9UR?eeN0Vs|0E8VU6gpRt8=1~UAnNg>ltc`%Xxs&`6 z32RG}ps>~76OqckP1=Vv89_n#Tb9@Or$OCrnjw0K7tP_l`duH7se6tC{tV%3SVdXhn@pXsP zEMflW6C0dbF=p@c^LdSX_6#=7fw9(jw@mNTGHs;t`{pkSn*#%H_bz=}@oUitqU zf@6*_P*K^OcYeZ-S2_IFZ$KJOEhq3TpWugt*30@%WYMW9eBE(%^Krts@%jzemN_w( zo(68lz-D>B9S>6kIiWb1nweuAE?oxfK3xkd3)RRFcjv@+doaJRgf((u7~IA`Td^$a z8i>GF{W*a?D#s-<>JG+kdz}j+5RI~jcr3+@j&b{8**XxBRT$i|EhD6XK9N=&I}B9! zn6ew8a9&Vlt|SRWf&~9Jq|S+cJ9KkMmgU`i@QE0$r-c2hJd{wR#iS(BK>4?RH311m zKjM?qmXKKLGPI5QWBR(f1HVcp0-V*b`oos0bsnppu&nXR@V%r5jRO6a8loryg;GVr z!MIq+sqL7!`GL3xxxWN#L&bfU&f??K0+7EPeV@JlZ|6M3{XAJf`){LIeMT>MxpUinFcK%bp&lB$2 ze-+$RDstyW9t&s~Oz8rBJ$_j4cUJ}II_?|&^M_IQSM0$4Z;xp)eW`n&FIEl%1@d}T zotDaLd+}|gHwQ_dcC!`i2{CSd-c?joRM*tR&@tDTQ|^y7aAVCje@m=qw{Nqu{XlDt zBfU}ex)~d8^|o&bjHR=}$p2&OO~9$z-}dp{>3f<_9Sx!k=TM0VA(C)PlrltQ$Pk&6 zB$=Z+m06P^87i5lWGERcLlG)t5+Xxn*hyyo&$ISgTj%}%y59F(*B5*3wLa@JJkR~y z_x*6_e$iB7+%8)@?Xc#ZzQkA8LN0NG%;70$;5wUa(mCaF&URHub=}t7GO%_UI>LX@ zL{u36B_y`~-2Que31iGnYIH36wlaRxxz@{S!!=e9-r1NxW$tR60rQNObG0g{mki+U z|Mty4UT)^=t@Fz+^l3(KD1G30it#a8LSUhZY*dK!|1#2~sL(-tt%_oJ^IqlWAZHHH zKb^bzbZ%D&-4uke8DRGUPZf7-!@{$@1qE3cMsk<;4 z|9P>BZqWU9+KAOg3CciLR-Z(faptCF#e%M&{4Ogi+roL*_WqOibmg8fsUi^Vftv|C zQvQ?E3tgwjft)Xy_-8)Mm)@^m?~FQE6}{om^v24_;|UCm?8%w#zh_^Z|ZfRC_c0i~Vx90XxQ@GpCEA6Q30DZ3M znKNhJ+t}zXi?W^tO@K*HbtFA<$lYSP>4*}igyE74-)jEYxbv{*b87H|r!wEMRrQ!2 z%#Dy%t`vY^T8qPHk7;CL4C5~p0KiZY0OO0YfQ_c$sZnRW!j(jLzMz3pLv|JlL&8w4fi!F0EjS9xzgU4pM`1r-Hq!%?ZjPpf&4!qBw5 zLEpl{LN;)b0+kyWf>;O|70RFhNs3;w#`N{g&55Su-k@NV79qX2vOn-56>Pxle!14w z)s>KHgS^Xax~aIh7-lk#Dz<-pa6HO=&H0=wt;*#+t}8F}pwx^|qJY|67_D};1}oQA z3$0y-E6W+AI$Y_l^~oK&HLlv6w{{kSa|60vb>PR0X8Mkyf~)lMDp@JRI75&}q4hwB zkUpW;LP>{zXONt%>aMQa&fQ|s?8(}x${wV-#Uo1@4X%LC9XEA$?hJ=XqIZWnRs*2g zZEn?75sU^Ia#3^BJweZfXm)J}a5E#kobp(Z2U zRhbu5z&;Dt2Z~DxzakVxO@lv#72yo4?KahK2@K(myPKds}E_hV923 z`rhI0s=Fw*5|xsY`kJl$++hUT9q-v*INrg=#g*3QVh1`vP?Sco5cP(h z|HpaiV;dKoN)q~}=gx_vzgFf5W6ha{c7$fHF8TciLrJ>3T%DbzK$4%2_Cze9$Il*A zX*ggDCM_s4E#s4$cwKjdF#ulPO`*XZ_kX78I2s%EZ56W7y0Dc;n@VQjP4RPr>d1bY zUS94wTQlb}tpmPDCt}+XYK&qd=4{xD+TY7`p zrffJRo!|Kxt_3%UIobY3nXd=ce4#1tF5LZ;I316oYU|aj13$*bl;Bi`rnh@?PJi0q z;o%{1cqL=3s?wia_tVt4W_e;;CUbA$0rZXaN>o&o)YP}kPVjgCX23f`0BA9Q=u7@(2p2=^!+eDx9dYD|0FwiEJux8{5lE&Z|Qo zf&@{izcdca?f@}RC|CUMG0Xo*Xb`NP@RX(sNs-ykapso zxLY)FcN`?in)cN;u&+Ix`T3DBDs1^J+7cD<=s@C*Dpc6jEE;0TNXydE11n~hcu-PV zB0yz+FRy`33){wxch66wVIpBu0*)RokwwYL+d#>kj@}re0}-%iJ_VnL9>>`_90>05 z;>7~hU@z6W27RZ%mt&ol5n3ML37Xp1!w8_f%i=C_XTbmM(TKmHJ7K8=%?vYBl$cHSwHa zqJpk;$IMb)bNiB#JD|IAPH<7nZ z%CQ>m;MxH1J z>&tI$u5CNqmg`{A;@laaWss?j(r&O38p`S~D`He6`5`8c#7r6c0bSqWeCIa*f^mK$S@{N!mavi|Z1 zofU$Bb;X!Lf=CtqvZQ`DzIWfib7pj1IZAlLQ+C(7c*3HpJNe1F8T7n(rZ>~^tg?T9 zkgs0&PsaF)@Ocav;Nxq#kf6k0LU5%M1F)*lqszV;5908YnVX^c4?D&=omyDN+B`i~ z8qz|9J-!}VS8g=+tg)VXbKC``d;69M_0MBV#7Mq;Hrk-SEsz_gnmssp)twwbyFu7# zj@eh+KKZ15D?7Oh94D1a>2l+j^J5z-2Ndh^Hu@uVkgTk~@}#^Y4( zT0ff=0}-rmCj{$>UniFnVGs2cFk7>*0T2_X&92 zFPkARDWzkwBw^qgHzIjlV=B93V*3;*bMFP`IzFe{2*8oCBkpG`KH%4EIbz$M`8HwF|xXuXUiCAR6$zeXG89 z*%ffV^2OaA6~pu(Pj|>btrZqAzA)~szPFT+qc>}In$%jiGHEK?)`LRu+v~7CajCBB zd2{rwLBgGCInBb`=FNL@-)GN&5v9LPTJDy@sZT>?XtmV%Z@aJzpVA9`3^yi9Et#n_=eeC|}A>;bleMTRF zN}%_iBct znj1ADjHYbT3v!a!!Kl)%G%-GELmOC>Cc7FkM%Qw`#{@8bgc2Q6 z#N-nDGbF+OLb_5k53+)hLGML z`@m;_0a>^?e`qD)=mt)Vgr%)Yqn>xAaFL8GcwjZSM}l0w(Vg_J30Efyxt%5V%ktzt zeB(OC;k&qeetKTV>8YqFAh$m^IXQXzE=X3i?cL)d_*bl0ag;+iw9-Tzz8$D_`8ocbBxguJM>SQv2?50Q5Gz@9niLrJH2P&P|3} zMcz3Z_sDZ@*0&S=Auxm7l>-h?n0yGv zM5^dITT0)1UpRQaz3N-4f|O80NqG@L^X^WB1wI@yep<%5e;w zYNW}x=qr$ zdeIjTBlq8jlBUtq1mjKZ2=pL92d(v4WW1Y|RCp=KrA}XTTWL}b1xI_aW%N(&zO@9MmjNHp(w)MPVxwKYC>KCxRz1ho|v;m8u#)fE@+;;7J%QCYGdE_c@Wr&i71RWKPei!-g8mC&|XLhvEPTZ6W3WV_AU5 z;`UuvuL`tDMZ@AZFfhoBngTPyg1-JDa6*l+SNiNZ+vAxw`HZpF-!7XB(JoxCG&+w| z%QGf6tZ`j?_cM=VC3P(HEMT?0*;zX|+D`81-e0;4=U9Cs87gYO?Z3t4 z=%m05u-;y3Vf}5xdjOrZ?DLC?ini}sv`C=sRV3V8X4SdwI~EOsFAw(=LilS6Gr_!{ z9OcYr1FnFDF5F`Y@&7$vMF*EG_`|9`No!sCDzE_@Sv`yf7ck!Idc;i@ILD0*ilQH_ zb;xJ1wKXrLqr)NKU)DLYj0YA^Cc;272m@oopaSqq90g^@4e#L*Eh0w1Jh@K%<*919 zyAh*1KORd zT?mL!mO5hVbYbNgHJ+Qv8!F6$AiytY6ax9j2uj);3N0^&4MIEZxUPLQ7U`LAJVfn4KU^kww#TOSsyuLvj#^010VrtmY<92AXrfvGnpv;wId|?{o%lW_B_)~f zuXt+%g8~BT&v`IL$x;srB#wf9@f=X`KUk@w%cQAnsv)VWn`>x<)s=Eu(Ha4vY04Co~wC_=AH1Y=jFWa);hQX2! zlXi(p5fSx?Mb4?qUoqdC?-gfd0976)*Kyx4V-Y%6!$th+0H}&qX21qME;rXRR{|zR zI}6>cVjtM;S)R+kteoE#oaZ{mA=r#LDzN{)dctHg*qPzL<#$9VZl}q0ve$&!t3rBS z)gb3QZ2aw09^|WVgY~DV2S4xe;W@Ys$8zyRYB2UK=QD3EGYXqtlds}e(gMC*-FVs? ztZYQL7yNkd4DQ?DUPa#+SL<|3PJUmYZN`PFg`$g z=@YSS-fY4P<0q~6Bc_TLt&r%Uaqa8oMk7y;QhJX}&#rZquM_ux#cWW(MoH}m2T088 zPtBlznpm|i7(y|pwD#MNrzM+RftE+HRW1KsR{ST!0v%mDZ&!9%9V%L*)y(o#+bFef zv#`s-QaYY961ro_Ml;r>^vr7M2)Oo0q`g zR<{pkp{0D_e3X5Uo~ZGZZH1Jw9BhMF^R>Z~ z2|f2=l6(e`_EKYF=-i~yoXzy>=;_y4ozZZ=ooJ~GSxQo>3p}3|hcK%jVXWp1WuZY(Kf)WY+ph3JkQI|jzXC2Tq#_-#+B&>I~Nd6K^w9Mj@C z(H_zL3omzKv#VswnSJgs15%`V02&QI%Xn)WMvO1Nt-sPjOzna7FWfXeD2oX717-;} z_D_leyxH1jBtt6$h8DE|Hj8LGVOa$xcMtuWzc+vU*jY65WDb(y^@YP%#^d3}e@`6& z1Zs0y;bfn$!)$NR>{hV+dUnqdfWuM*uKoGdo|QsRO3;!SK(66``QGR# zoL0b5*P|C~f^ZllRYoQS0N6p&%t89?`l8tntK zbLGrT$q%YMW}JF!Jx=ws9pAnlt>1BRs@?WaL|?OV0E>Jbu3o*`k&;>MI|PjY9Hhq( zXhT@j6k?u^{2+kf0k#*7caXf4mXT@t7)O)&Xf-$OeMI8+^ttB0QVkepfI)Can z1lR%2nS4Ol{Fe*oi{JsO9lb{3RmZyDUzx?E&1(e>aC5oQsGwmJuN4 z3ENo-wApAN5PB#Cm;1BNA|{M=>s?)BDsSFE(!z!A!x{FufbrwLdm!+7 z_!vCT=|g<17u7Hs`hF`qf@gK+FhoOJ;59^-;yqdQfM?e+BM(Oex9s~8 z?|=9L6(BpH2_vatiMjP5+(I-5lx`V%2R3 zP{C_$?N5d54}S-xpAY#p@3!LFgWcZ{Ozeci>H`bVm=JC442PesH#m1>dZ2A~;8G2l zv>Z-%vI_m}OeBbSw~>NkiBQn!XuO6JNGJNJJFM>RL!`3>T54eZq48WK)Kg3TkZk!A z{eZtpkJi=Ju92Jmyb7@2>V!&H#AG>+8M>H#8JTq;zb3ox*g3T{L+zex%tON~PcAD3 z9Pw3M^5f&$G)_brGNJAJOCsPRZ8fm^0g|HQ3FN+J94&fG>6yY%1 zSC4^K8JbHXMv-*3S}_Zq3!$aOI>}GxG|_BZYqy=gzJ5M{6#-Bz*oJE(DRMpI?IxTO zf86v5bU*$fkLDLu6mFVW3Kpzfxw{Z*AOEw`@kUS>>m^vVMZ3H3#$8e0Z^xH(g&J`o zvX5Tu31?rFjkfg2N+NvSHc{==VJ7UR3l5Jikv-5qC18#&H>*UH)zJbF{Oz>59+KPP zVS>Z?b~T=Sn(nQPpWX}aZv1g+%bD-5`N|~==>abT+dSuHMpwPO%GcKUVG0!?GL0FL=15z!%=L&J#N z0l6UV3}j3kl+()ORl{&PqWfhJJsQhvjq+Y^YFj!VU7@#DuGS zd%hkdS}-~K@5hoYf!;x~87fVZ!9|qDEMi2%Yszn)-Q{>Y?nw@l(@}R+7DAdXG#rG- zoqPm`*?=8B!P3=aJ->L`j3pxmRX0NS`Q&bseBQTTfLLOM+cpHVF9VGrN?7`y@d9YY zFMbH=-UJv_Y6la72nU6Y&;SMt=yBUA*K;-(xNovBT;*Wrx@HTxe7th|D}$jLvUFP| z#Tu{$rpSA2{D7@>R(|~58N)BkC44lPcSsbm9~gMqq{7~5|H^_yp^^^5F5?8OhEf;| zNyFbRoLb+Gs3%4^e5#Dhj7D>~P85&p_`?nV3p{KAYBdWT$~J$4%jr3trI6asp20eZ z^r>sc^zMw0zA$-WbNeCT0&znycU6Rts^d2K zVUf&2sosAY9e?4yTbe8@9!`Lnvje-!0N_1-`K59(u`IEwhbFif%x+SpX#TYyxx1Vb zKsw?d=X8?k?sCs(o#tY%+ZV990+{z`k=;S2w_tplAO zr(1_+46)RS2IswlgMoMp5Vq)rw&3Phi85pSC#VX-h>X5skn@B$S1?5!@@q7K+rjDf zEdvi#&giFWhD)N+WEwd!7(!;Ra)BseJ!DsoM&v%?RT}f;dJvX3&l;8P2sK0 z%tF7q;{;SC$bSg|&rb<13dxEOd{_629#rKQuBp#xwo`22+q!us=e?yASp*CLGLTsO zZ`^qWrZLZdf6e*f`PTTA?@E9$&w?sP;)~z@qInN*y12DG>Sr2EEN#(^elfnh6dI;7 zuNb@cdNju=4(_5M`wxmTD?YFG^4ikavxY~aeqIM^x#Kj|lZhstJ5?EDF9Lkj7^`2v zv0L+Gbj!0{$4jaMfo>|E$~$lW^6L%!{v%uHAm@E6N8rpOd6#&Odp>Jnxs{#$9#c;ZHrdIl zv`(qxzJ?M>;FG_lPP@8mDm8F50fhD$EW%)wLo zJECy7@eq7L?7D_|78F!G^3nPmVwj_1JIU!YtxCcD*EIR8lz~L+-OH?gt6Dc*8-Ga`-;b`XEq!j;*^ou_F`|mCZg&@@xrqu^3s$qRD#c5LAL8CJc<< zGhjtO<~e!{j$@5Nl1E4rzhB6`nLlT3hrP|uv?zllrWDVeU{(F`@!#4vE_8i;A zVCOdEZ{EoncT3pkG!pr>U%htSMLVFaK;t1Xq-A6mSdv4lr)=kD(YHh;F)X0;2$Q4j zwFMMbLC>IEMermbcrneN-e~VkcS_njbU$xWbxh(@|0;u?j82H5iK&5{w`cj(nI~QZ zNV{KM#j~8x2f;Op9#br%J@3PT4WJVzU29bMJ1(j=g(trBd>Dn z&!Lqyb~E|Bp0O>^}a4Uv^EHdj;j4vLi9ya@a(BaVHV6N-m2EV+051fG-6_@FZ_XF6)&v`7b&ESa) z2H5D|%{}Lm6zPQwx&|SJQ96xQ#b3GqTd&RyX+=%Fk2@)EnYaIgJJ*F^nO*~Zm2N5L ztZ|z40BCQc=lC^Gow4JH8g}9j#sf>PnFFV+a6SC7V-2~Ec6G?eS(!^mxfQCj3X=5&fEA6NBIQ76t8sjyNsuBUOnHX6C+q za*Jqj^cbSo*jfAxDd^g}_vWGlEDK`UShjA_PO!9d706EAV?2n_^uLF( zylHv*w5s}OSa)~#cyiHXvQ<1SC=YtRBp)X^#>FPJM(jQpyBq4*{Z!Rjqoo-qz0Utu zcv>n%K^HmyhK3)}XIh$@H&{TE$1F{+5t--)=4Bo{(K!(L zsCVrMC}u$+&4}_69PqJ#*LQfgt|U)~m71I0rSLnpP`RyW>@0wGst0b6SwS&RrUZB7 z&*ya$y*#@}NC|N6rb#ne&ZS;`LZnopY{d7a9{UtbLe`R{IE8QRexxaLOIcJ$XJ> z!|FdbW?Q3VDn7z`bE0ln!}=RNiDJYDy`;PAH*RQvbCxIib7>A1wEwAk^V61n2zFyz zUq&!Uqp{vU`-N@{GA#f7v0*`_zTm{bPJCXTQ;ZgO0;6!v!fNQbD?=1Sq3p9-YtIRw zE@Dc7jL%WQ$~fjAeeSijQh}F~a+*t-oN#rbI7F}cqGjk~ulW`P1qKon&b0?M-9aYc z3#AHgZ!5laasyUshi*_ajz`Nn=^+e*wgfwguUxC9g=sIaMPv1O|pXOOlfZdzhT@az1;&iUo-HJ)PGT5|UCJHTdZ#k(B8j>#^->x=R5_H16_^nHo*^dz3HNOR)t$k23cOgG}j5)(A_P;hc`0*p;bp#=E( zC7pQRs^-#wGF9Vh(cmMlnsOx z92`dO&s`!P?#!QxJVDo*rA$bboVbe2rxE4=Jc5VssRD*s|SaLOi>blk()h88kEV(Ic9#W`w}45dFnQ-p3QDY@Qa!?;`m+ zU+>d5aWmpEj0f{iE}X*j1bO!KRdd6ukS#T{@*;1C7vJ3AR8wQ&%QisoOOeA7J=N0l zAT!h9geUV2mtUSZ;4kiS=(W4<2Ws@$iDIk)UGJzfF##U?5jS>rT?K(3k%nL+ zGdPA``twazi+_u>-I@oAm7uUu^}OFR4b~TCeM~P22dcZy9^Y7 z5@hT{#f~V#6FlkcM#GKRxeIR`O7O1gV^&sHK3En;LO3qx=`y=%MJ#YHKTbtU4z+i+ zH24HJM4EcAxNyOQ=$6csb zOY-mlUkhr?dw@m2ZUe1BpmL>fU;V%x>N^(K9b@;oZ*u5dV8BDwM7L6R!4S!z0HyL~ z&3MLhI+oDbR%+f?_r}IUkiKe=KZlN^uO4sBb}I9^92B=*cP)sgSCHD~T~^8@Qca`D z4}2AxJU%h;_^}mp3$h^p5WXNRZf(qs9v9f}Pq?gjNbUFj^G4FO-+Yv(9~AJyF821; zSnU7fFT@10w;zmrwDnxz=zb{`#@h~CxX_q!`_P-APJg)J=7jp2aub)4`NNVfK&Hqv znpksGP>D`RY_$$Pg$5tvllb7|HN4mZ_H(Vual*gQ-btNsi)-fpKsQ+LBfP3*m8O4D z8?DkWPpM@W60fSW*7bW~9fPea&nZd@$-%2bJLssQi5fUJ#0)yZLwqT#BfhuzIlXU% z<5yr{)%`QmGB?gWXKFa8X|wW&8+lw7yT8taDQ#fi^0vB;-!T=!f$!Y~^j;mezO}>^ z?yY2_X@<`JP@5BfEV#S9hSPGZ+oQ2WiABZ4uW7WSnu)o)0uOO!EJ@*C$$YL-TG+FY zo{5yUyOob1cSw{NmC_+m>U)L3kI(k~yZ?k)Em*4^j%3_P-GYV2ea)v#n{rpW_M08m zSKG(f1t3}py67%Aso(s-;-p>Q?PobMiQc^>2>>zK-Pct#~ zC2d?}^os{`cYk-A!XRm0&5ink4^R{)msl0(LdD|S7 z4fHiRc93sr|;b#`1TkJo<=*PE}&bI^E0ZB z-7(cPMVO~X(}Ho+64mpQ@Uph`>4TB#jo~BjbXxNz9U1RTy>osdN?8`DKz`w9r((}s zjsN*|khY@9v5Z}giU#`3ZTDOB{Bm3@j5$H%vj=HHK^LjH93VD7msOR4=l$=qhFfD) z^oAo%4lvC@!#CsAh>WA+r#`lRzu`8<2sH(n^wAD{1vN_)eG-e(kphi}M?p&| zguEH6#!Nv!?74ebos2kXK_Aw2IcKHvYOfeljnoJwpP7pj&NfEaUbhwE*k&aCL)6>R zFH-}x3T);X{-{qBI-5pkQ?Ey3TQ5B{XuH5A92gD!U z3KP#J8Ejd}G-QK0R0$+JlTN3Ok&E)Jb57SwuzNaE9s=cX@=ac4r|qkoU7DBOx|ne- z`A+r#ne$n&qa^76^2Xusm~Z@mt3GTgb*X_Fg-f`XtRz17=EeNm-ly@s`qsXNh@di9 z^i%-3q05Zgv}h||?+d=ccKZ9zTl=z~iQFc$z=R`)7cXv*fCPm;CRn*;w)M*uP4fAy z6{7Z^vW4M1@T~1CCn#i36B6as5|0>7BR5wH=7w8Vyi}uJm^8Vla#Yk8mY?tVX$;fxHqt@gi zxVJwhkwMS|4M!DZ?7t5^#o%i{DJP)4Nx~de{fYMatJMA^@ruS~eIQoD2T9JYfCs5z zx?&X{sof<&eqU2j>O^nWs;AxUDbzk;t`1@7NEZ~QTk}8lL&z7^I8}9$A--F)aN$B! zIX@k#-VKbKaYg9)Ee2_tV5Pac{SOqCt{_Mtk%hPItKe@=KQ`1_Z7Ck z6aU&`kA#zFnNrTJxqR&P`u>n`WMg4&)?u!>z_~pz*C%VExlrm>pGV$ryS#Ghz@p-7 z_xOg?sATW2g~qIrcT}rX?1T2%-&-(pWxb(JEHx})cQyX@vv?Sou#b}nLF|`syD}!C zpy8roL1~9wzdPsLAG#m0Nycc4WPlT}5U^iw{x>t>L%}3ELz~Lp!yWK0g+F{m8J^@l zW4``+NL^*4W%kyMEG@nj5ac-`0|{p!(Y~+r!CWOdi`4H{+yIW7fqmWJESz)}jwj&l z5Kk5MfZvfe90ob93=h}FIgEYio^wNU0SJp*EhMLFJB_iJVuQg{ggk)*>?5}NRgXLW zG=6jb{m}72(daE>$W6g6h?p&yetjQ%(3KoIwhE`3wln+H2S-jl5N z=*9>O2_1;w62P$xka>bY1A4T8TF)!%d4q2>8Eh@P`CSLc;g<~(!W}Lb99=XVYN^*$tI< z$I4<%2ND?@g4c#$PusZ@6-DxV3;z&Bf2BHF1*#%r|V2bn_LKFSK>u`3gK8536Y<>EVx7Z6b1FGzkl z?M?EHSDp8Bs^M8;cX0=FRlQ_xpC_2EAI16om?x<_X|G>IeTBp?+po*9?`gMp>FcsF zag!y&+0-|P3~{|tGI{t~U$fg}KX9iRqn*HFXhx1Z&A7FTB_q3FH=MLz6PZYd^}q9H z~x4(8s-cuR;^OXJ#IMMV+fcN(x8qH_mH>j^)kfl-N)8- zYV6bdVUA@y7Fo-(jS542*l92SAynxghI4g?%5&hy(|JO`skoVq&K!%1$)TwW(8%~x z?I7n7CGC^*OUanFA`@h!PC&Wj4%n9Vlm`nIKK(9Hd@1A(;5Dh?`wk9doNF5ET?Lql z{|5N17=bSkoxxE~n)N(={U-9R+uH{i2}EF1-foELdLiz3HL_$#jkq7Lt8jkbLjDG7 zf?@sM@bOf7PS92rpj_3H~nWKLsm zMp(7wSl@ApQe&Up&_>>N@%?@w@zPqDyEi0C|5<2Ee5>UdTo0EoU#9C9jq1~HMNea<;O}49*Z| z9!Q(I|7W~GFRF(QTu!r!Mix!AnE_x$q0X4Vq{74FPIvRowVVQj1?;B@6jq|2atA^T zygaDKrQZm0--Ln_=Px&u;{30bmz8xG47na7Cly+d*$Ujs+4Okbq@{K=n=dLZ{>f-t$n6y2nXg{?YaCf+jYI4nNC?V}gD- zOaHI|kv?J(sw-^EyIi<{L4-0TsoC+)~^xcM8#JpET7MviTmvbrNHMbo6ddh$MQSYE%oJcc(IhP z1na&0!p`Qp@S*bk>kZbT(Bd&wik9NI?6PZ--bV-?uf*n(d#U&i1hj#2x3hn2_KVu= zL*LD{1rVb6K~rJJ=6J3lP)DG6d2@~2gRx;HEh7e=gU-!nB z0h~k4t3@tRaMB~ozp8Qurs>N5wxZts!oCnV9L_5Q;nz%*Az4hMWvAQ@QrzsQ5UEou zL&fq3N&sW8Z)=n597Pt`VvnHL3p+f3s%cZLaw|J0rwq7jJT)U$ZByWB;ixl4t~;-z ziVs$=%65u_LEmCmCdl(vl; zkX!3t!5TJhuzDZO2dBg(%%ycDO-?Ut2R94dqA{or*W_9m!SmidFH|$~6z1)!saA4? zt}DOZt-Z41Jq6Bh2oBY>)B%-~m|^-+0eGIl!9lnNbZM`KYjARM5~U3u9`H(VZJK`^ zt`z?gOU)4Jm~Kb^0e`4eRTH=9Rayn(Bk|GsNm0?u*@Z0Qk_ptRJO2J?EmKqxFf3 zgD+sYpgGf`#jA$)Kizox>4}O*&MkmjuIw+Q#=JQO0#U6~kmild=Wl;4z(rEHuwAec zW(?XFz%`)@u}8#Y?<-!_BQ&}*C&YJQMa%%e#Cs~S=%*%ysDC=+r6_=dtZ5hZ>$zk?;p0>3- z1}Y?C)~$UV>J$=y7q^^RX;rS2=fDm%cdWa>q#kka*whZ?ErRwy(9Gdz&1@wo*%4qF zfwBsoimvY^9$TEubXif~+ZhV=?VdUkP@rWe)qxZC-YR`9W}tUemk6mbGQmSwN#XE{ zQ@lJ}uD$oMs?!O6LJj|X>VblV{d85^v zxLmhh0QZ0r@YC8g(Dvp_s+~vw=h zC}yo^kt=NS-i@(ac$L<`-ZBQ}2b*|In*RbadjU@9ld5CSu+|0j?B*<%;V)A`t31X$ z4qq7b4%@+c+S=L|JuZ-~`}NEPE$S-{76_##uCdm0Fxv#tB^3{79R(;MG4gz~72#{M zXz}8Bk0J09i>xh>-o2Y>5>I5A$PTYn{Vi&`XBJX_R=-jr7zX0%=LkLW8}1q24(F*p zzB{ngDOclf*x5gU|Ne4$n>!VUzRW)gU2Bt@jX8vc{kTk{lSZlwgTb*!lVL z2Z@RNusWUJocuo4n5w@X2`|${pjGkrBwwk{4~Sm$F?tFA1u540@;_r8d7#p|f=8c` z&th(Ok=ahUSzf})2C)=4l!L$n2g!C&*F_l?VYh=l)Gv%kdWu!cjJ&b5eq2K?m3#KL z_4GQL3=+3lADf>yfc7UD13jJ?Y{Q9)V{s%>O!Eq_Blh2{>a$phJE=>d>&rMqsTflJ z>`d@GHp|m0kw-GaxAA7AK(`7;)ReG#p)vUyXzwc@_u38}HaJoX?|}lEv`naNlqRpT zb=`893C$HRjHwMnc^p%Z{lK8#l67mn>f7SVGJpZU`UVEI~#|*rc8Ih0tI_FaID1x!b z*u(Af?v1{lIdn~=;*f;j(nE-A!GF}n7*Gu?n1){-W7#h^!C#Py^S!~BiH0Bj2TNzk z%CV~fBNLU8;Q)pml!fY}rg~$7(wZHpC7&Jq7&6}Q`db?rIH^3Z2<_@Z)V!kjn;=ai zK@45EWFUeCH^yW2?}nZVR+@kqxvz#o*Xq9?Fxzx~y>G_DZ=-Y%$B-$W?=s-L5YKo9 z5SFr;6K;2q@vs=dRCrKSU|6r9>nt#dTjsxEWpHNeV z72@r0os<3PL6QYuRqRKqB$Z0uTy7J57vH;qn+&GkZdIV_>$du%6>f+y=_RKz>=l2c0i2gQMTsQv_F(sdadhud4XB9ki?7 zO~Aqf|E68|3^h{Ij^DSF_kFZ6EuRCx8IupMqU!i10DXxgmozI4_j9*6Hu>9!lX6Zk?ET9ZWLHop~hA=0=s&V*eNt=gKk?KM!%g}dBWNfcBub3lAo4WP)Ou|QGQYnNtLXGG&K-YP6YW8jVX)L>%SEaS%ar!(S_Q)$=dhbi*WXAhn;5F&^(Ka_) zGfrgvOxIR*A8N(GEj+4uRTcKC3wN>>p>+V zqPyaNpwPJuSj^A}gfNc# z$g6wJ^d80hAx7CLiDJurdH$M2&N{l1VYKbrcDJS2o?P7LAT(lg~r5B zbyD!k$;Z+IWoqIL+5pA6#0VFmwCYKeqrx-i0S4mA4dB3Io?mEM9yovH#Q-p|%k}2n z!2Mual6VrY{jYHTBslm1_pcc-nt-8~fY4Yo4G;u`QcQvL z?vq4*(Cf~RoUAz21b%|B5Jetj!LvsQ%3a1h| znE1NM@$r9WS~o=13MJ7qAEF6Ril4V#rlu1uBSE8H289sM&D*K>!o$Or=wA}GSJY8a z1^TfBlgKOH!|>BFV967>QuC5=z&nc2tS_i&=3`L+ns?Z5CLcpQN5-$IxiwfiCJu(0 zA|>EW96pOIHmodI+SvsW6-94v3_F|(`VH)Vyi+QV26Z&y`-oPy9aQ{fc{sMa8}r1MJ^-HBrUf)+!@MFY)FrSQYinv zc6a({<3%bNF#%H%wH00`ZXzaT|M|-LGF%wm zVX}jt#`^CpdcOR16IH$B(iGTPnhvF>zmxs)s2R*6O1oMP26aY$Xj6rLm|Z1pGXbZQ zcfCsOeoKAS+JK)sfKdiuNnWtzRyf+i6yG=ql)D^jY>Ipzl422gRizMywM-QPlnmk=x70_b)t>x|J7@^Lgi9AWo) z7bh6LZQ`P*^9>saRo-`;`4Rk)3U)?{U2j~~N<7*D4mxt}<6{sv_!Ld$75T-3d%!_* z`Ov)XXg&6}9oS?4Can+xhZBzWp=6>fxEhfNFjbaDvN}!$cr?$CU=oFJa3@^u;2jF< z`=(@f=nzNdHpl(8I$CVrc_#bGl-rmKPaw1-Q=M@AKK=x(eNbLo^1&iH@*V|%N$JF< zKt04!l!(;rTHKHT(o8lS73ee~A3k9rlg^;h`+AD1;*20_<_L-twTQ{x zvla>pnwpv@7q(3jBtK}p{js1jxWR3+-g_)pZk}v0QVgHWcIc_*HwucLbt_}HD5(hE zwnmFO^&GSWSOKW{x4YuZF9&7!McAZmAVCx}^aKY(-T6%#dZh@Sd1QcE*G4lh)&;b~3p5OZElff_74qo8}c=$Z4inxvb@y;OF zxZ({w0Rv}N*l5>4j2Ek#uyme^z__j|Pzc%6hng~CDyZGD_%pDjp!>VRAH4!&N^gcQ z_7a08?|~stBp6hP8G>;DP^(EW6}YbNUUfdl4Em-`+KO_Re&kzk7XifkQ510h%5H8x zwB;Al^7+A*JCB&}eQj(=18kl!>5h>}5#y8SL>4RTVfDpDw#zm5cpzlF%jeIceOljD z!@Rv=qES#a#};9?w{K^$q`K_Ni;~99cv?{>=a4tpmu?ZHHm>fz`xOVi*$QxsFJ7P9 z1Vjj?kzVNBj*bg z0deNpcjhlDkG;|I%bYv`X;wL5&D$9uiKud%KXCkm(22nw-Eq+Y^C>7*R)fUIXpR4U6Ae56=UInRHmJP7l;yVh!C}tXRdDD}+J4JuvVq^0r{FFbh@{~eHl_v1b zk^ym=Ke%=X0H2l>Krz3DhCcU8!vKUB1T#yMu15t}J08}t_{_7Cis7E)?xSk})NMwm zZm9u6GOBjr`>m&-rRV@X-S`WoK{y8?c}$)hA#Yp0U@K6@e7xi8{$4uzg;`^KiLm2F z?oqB@i!!x^TyvAgvsA%F-Q(pEAEjn#lloSJM9rIDVNHB-DY+oa#`uE-0}OsXsM1=U z+ILU%&qQv>zwRGM?icOtxAi`5bfvW%XAg|(IPfD>pCVmeE2goT48Ck$yRYSFj43%y z5|j$A2u9tI=E;yK{d=J?@zVrN6>#t){}~tBrUMY(&}0{&`^&WF;iK)7G9Y!gG}gPy ztn~JqgHqPVjQVb$41oZF__%sHMA6Pri6JvW;O@!ecAX8|we+4~inv((H%5^j)1BN@ zUl)ezBd;GN_DWvRMKVwk5hYwRp-^fek5Fj!`#U4^zH9or$+GYErtobq-)VCA z%$~I&F%{!LU|x}rLo2?73{%Irv;)@jdBm9|^GJeDma>pg;+mU!zdY@43yrDIv!=GP z1;_wZZd0ZVNm281rO3n(=RU~ZCah%Cf3uGL^^c>I6dr?PPhP=mf9jJ|UdO#V47z5$ z7s)PQ;30j%tQErRYAYH)rYRTf;$d!u~cfI)_NjWLX$ z_PRx#X&|R!Oo6b=z$v_50j2YekV3eLOG=hkf}?qz3-zrs0@*pSst3$<#k+^eXMs!q z(GTTNA7Iez!Q=zveu*R0^Sji2EFQY48_p!&b|+jkYQFbw02(4xG(z=Cp#(B1jW6Wi z)0SI;H6pJ{z=Zalw6mTiokM<%-}LP>ElgU#0_`DWJ4exiXZ|?ZTgeLrOQ$}6Vlo)8 z9i(D4JT;Sn6t3DxE*G!KhL6CA`1?-wybOpKEo`*`z~Xri08aj)SiO(lD(h~BSC_nu z8Nm^MjJueaAzJhXAEF-9x))MV;|x)?1%|APiiw}9L!4@*!xwq(y?-P4_G>T?)_VeE zY;aR2oC$<bQHe3m`E)#hJctp&Hy_v zp!v}uCc{xMOT%BW)oWi9Z0qOND^l<(@j0!nYtfYAgTHW}0lF{v5;qMC>`D%w0Nw9r zU>*Cx6sr$Z{v&k&mm*eTk8E8_owTHN{VG1@;m4|+m@T@vSZU`URMxZdCcK3KbmG7d z*QzeS<_yOQ`n2W`+ADSXQo}WZij^iJB=z~sb=*qO9>Ns7r`JHN^xHHX)cmc`7$t5w zwOz561ZBbG7jQDBSKdSJOn;LD%tDS-1WVw zwbikm`}oOc6~K|FQcfv=H2-9Qm&Z{5LJ`r&rjxgQTYCNujA+KoBnxjm`jZ^8Ftyl_ zoVul2jj#(3zBoVyCx5ZgUUnjKJdS!put5l#rmN*~axXwb5&G_;k=^!_U*o}od8SPX zY#o|)$jh}qx*fh@WK)ZTP#(3TECy;fO~Vxoa^u`Tfr|`w8R!H(rUTmbfOZFHb1ZQ4 z<>=_~v@1lP&{cmHI%D>YDHW^=v&S#V55d_r^xXvHW>p@ z^XFRMcZOU*k%vxH7=FGc=q4AQ@0w;cl^GVpBW477uWM*U+c56Fj)=(Ws%m zBGQt5qfN?sZgR~T7k25EGyt*eG!V;fC+V>=7t>|NnK;4qrsgo$@}QuL%vDl`kO08vvPxdSpsUbZCdl$$8@V~% zSRhi;axI(x>eGN9CcNYaj=uagJ+;Oo#DLA`qB8Rck^AKckrybijZ9pVblP!*D#5kW zB4{ffX&}+J|~g;zvtmFNil)QU^Ruq&~3Xfd5X32CJvZcQ^Kwm=aH# z0H-ne$TaaRW!8+;0zOAYElypMF6N~NR4DQfYo3zvi2Ik1=i_;=u61Z+ zmP%SK%+u1|4s)gYm!z3E^!X=2IP?q7NbRlgE!WMCSPv;19FeFB{@lCW{~?Jfn$Pp^ zXe>vpPe-hQ97bDm6;(w4@9!&=2tuNk!^!95k!}6U(X3EHDl&!C3uA87N}B+o!pD!A-XDJCIF|T+hIA&$#EPk{ z4ZE^Hfmaut7=on0<-GJolpgM*POJqPX>4(m0Q2<1hg2QG^;_DMkUeI!7 z2=1b!A1F&#qT1(%8O6f%fQ{%M46Zv&xu0R?!^-Ghb;l{I>wXz{M>Y;3A+>URqq*V zA$%CXsLmLr?pU-tseArF(Cabh;pdAxQDld1x&(+~KU6RlH=9ik&%G07lC?<;4h-*8gbwNx>7MLX)@XFl=f3{N%e>fcC)~5 z+lYQ!@HD1|o|5D=Z!dP;*vl!gjbe3LA6Zy%e8J-LHG9TN(r5e9%K{`@rTT}RjHaTx z-R_kans5Bg$Za5-j-qRP?Csx#sc7Rc{S0irJJ)Gg94&p%B&mulTxjgvf_M|*Xa;aw zB-@9I%ovrbHs;v>!~%b>v&ha{`<|C9t;&xyKP(7~6THFJo@(UHC| z?D_xE_0@4zW#8LOs53T-qDVN1ARqz)DkV6ANF%AVAPpjdbUDrtQVJ>^f^>;=tCS!i z-JrCjNJ-vz?Q`$t-ueFKoj?4{j2zC{wf2fNMiw+5d^$O@$+5_W3egX2!sq(eB$> zBax42>q=%HWTvV&p=E?vxQ3-H>MIlSklvUI6DH%+2dPzKWkm_)E3o;7<_{1!vrHka zu+Qw?JuYwvGi8r=%UxczL%oiO{8DAk5jt!z6&)5irh$A6I|-%v6g$F}7L7aZkGk@o z3h2MfRrZK0z7$3bUa+hjf*^kTb`OR&G*^IFtDugubxuVc&9fCS7l>CLt{AkcsHm`- z$?Z&#B8=GGL(x^^Z$o1VI)hQGOCZ7I~O180}B6A zFZ6MRact#xrTzAcF7`{3PW#~6e-EjGlbPTw?7B9Gs2PDA-8&`f(|;2tob`p<*+mji z5Igcobt@T^4nqAkIYAFjF-9%tB%V$R?S|+Je(OLnRI;e>1E-+)^hAo|tH^cdmr%$e zx}ZTQ!3u==e8Wq?nV<@!1kel$_&4(z>?0u<-e5OynEZQ3r{Zz{43ZaY1#V*+wEQ2> z1fdf(cntLZc(kL_i6ahi3sCmZw}Xzc>c5~}j+kl_Le2kty`S=5$aVHZe$BVj=)_Lq z_S}QobUJ`n;$1o$!EF#tM^Wzs8=HFj&4;__lkV3}OT|OvWn@N71{}R+`Ef|(CwuXK zJpr5#%qa5P1d$k71)gjdjcO;TNQN^KAEQxatu}Oyey8__G?UoJJwQBus{$Y20G{G5 z2xuKUcI>+H(%(p14X9KZp*{jFXW`ql5NFf09QfDNgI_h?REQkiPKH4590ZBc&fkGi z!|l&G5D#z$f=-#Iyj3WDj>OB1 zzePbj9bJIS`MDq8?D~K!eFzCzrQ~46A5`)2s*%G*3jI1eF|pk#;Qnjg=qYGg%X+JN zgpgi|If}LnV%bDcqGw;`eso;`I2BU(LafUv14}?gcn0BSWlx+A$d3fPL32lk>e4yF zhBCInXDXoIy6y3{kBOY+Vqk(w&6)LCuxP z<->0Ns51#+vC+-6r-OLCPV3Auy5-BNIT#W0$|s?lT<08MP)CqL7bb=R#`BSD2HKWLss!ar zF$zhL^F!=?v6|=PPvB;IzlC*{Fr#m+SSNOvxK{*9RCb&eM)M!GjXyNDht!n99t=y4 z0O|;kpXhgwCBVHVa}cmz^FVqm%t$X7ZwHY(W^hSCrTzj>@_UZt@b1Q+fI)89H?K1%ZobOq5DNt61sgQ z-HUhvK7B)-o9Q=89UovGF+j#;PHbEg;$Dl~D6I{s9gO~J730Qp_xq0(R6Ij`kcd=t z2}dkIzpYs|Trx6C*KvE-efox~mS8!nWiR$qp+W=8wZe5EGtle!GP^~;zMj8+ zSsoy*sKw9%8*$W7p-02}{S>4siu4Lm4WIhkMWSimug1y{I{)Y`wGRoK z@aYqbT?Fw5AbGJN1hzxCgsj^Y9>?VuBTc#ldll@Vmk0@hI`{+o!K;nugcIie=ru7L zwZ~B9HnBCHHwQH!?E+OBFZ3NimVg+m9GnqDHVEZhxLZ7vhqCl~Ha3efv#l*Hhd>He z5AAy_ALBRp!|&4CL>zSianWx6R+=t7hG|uww)a z?R`va4~msYEoZtrn*~J(l$3C>L3)xNQ9%GlLM1ey#VVY6RlmKPC6k|2u_m87dR>0@ zS6yrguGjv5m=P#cayS_Lvd;SGK{h?qPHPl05ZDtjFZts46PAy{-BHaURM7{HXW-X}WBRnV?$CjH@b)$HfA`G^@>gBPsoZCkWQi?^3NcjQK z0YXhI82}ZAHlyED36Hv8YwcC`_JdJ;c>2%7A11`R6dazmTmXJEChUE9paU66Oatcl zoC8ET^tMEN{Occ^vFB-=c2^m52E@a_*x&EU!gh`*8*&rCRNaz4L^OeyjyW8K1~+#9 z6CjFZFt9X2gagOihDmU*usXwnYh?O(zJge-{rqI{!bM<7IHE%cv^*^*Z8!CG2}qo;u8{T zwi3e)x}Qw}rd^!47@t1lxoj$*ZbR(R?@g8lM~z3D;n=aH`@|x)s918rr9qEu#u94$ zsZqQckty_gVrg-)-X6qaXGj%WFH}sDq|2h%CWpHI4i+c};)M?j&OJ*Q#S<}t{4_yq z$_TL|n*r=AP(+dF90~014)mZSriFs??XKrf9~?D$lvwJE$G%6A-!%FZGFm;rV}i)O zeigcK;V5F6f67Q4hw;7mKPUfM4HiF|>T{J)e2Dpi_#)8liaN6|TkZaa_-}s1L7ngi zz_r7Yi1TGECJ0s%5f+5lNgO4{Num|35SLy>s!mD`+IqXSp6#GYO!JSIg~!Td$3$` zlkhZ!sT!+>bLNcQbE2CqS^-7yyBu0YyhuON`^Iz`y45~In9u*ITzYByx!$0V4_^;d{0Jy|vH4)-DCrrgC50 zg4-6#63d_XS?~%mC76^qFb2&O4*4l2#2h^@6*PYTgQ>ltbO$1=0afShs3@n`k3M(r ztW2g4BDRgY_ozP3GMT%TWG8WF`w+i8TNZF4{&qTaB4d&fK#Mqw>AN6)#6H_z3rx>D zOJ8E|zI`Bc`r%5ySyt(9L~E+tG+RO&KuDx1jmd7quz{$pKDM>5j}|m67f>hlfUDbV z9Xqh`pDQ?t8MVZXTcF;kyoWHEXRnp|m{atr%n~!I`{GdpK%l`bf=>q^z^80Sj&`me z`k$%x*xm*d_1PA{HpCHofTfAi2TUpkRk`BIhK;y8>VrK2K%Src1PquB z+15G(XG{}F|p6k%8*^P|jv9tNF@QFQlanz{L4$Ntg z;US!J$OVe0we=m6m!jjAfAc}_fz_FvA3qX`&u?RmDE6LJM=>_+3^7o02E&e;b3ucP zsi>$(5A-6fz^@XM_K`nLu=cuNo*`Nohg{fTu7D83#`5~pUiXLMqlixmwHI40wW|T~ zRv+c)_i4^oM|b~&gm09f-Cp(E!ou4^PpOytC&P_V-~m>gQk_9o=1lQfVdFoq&_hCnL3bKMnqGyRa` zkGR0B%(J`TbKj6D3ugoH@Z$(78D(7}W|hSJ1@yO6@Yh?n-c{VOPLSC@Q1d;TAXbi6lZ zkA`iB1R|;t;u30^d)9=YIE7Sge}GCrZcLNX6o7^4kyJ9VmPyf;JJ4}D`S4gnN&?Xp ze?0*#4R|U@6F?;@^{5MOeGqwT zxR@;`OQ5yW{vH@y378W-2uTnu96TC~Mg!vXAy5OhLHMurQVEzeq#KAj&Ms{(wvJDA zCb1)xJ^=5F5UOAlqFU@n80BPP*Q?$k+oiXUf@FaoLX!GniD{HcMyiJz3{5Vx)`>1idjzA&MSBv&Y21!N8_mTbpfc{8 zOL7D)?5%a6rNDTcp^@;w`brWDwhxfb53#aK(N;PGj4cgevHY2@o0m&tBFY?vN&H>H7it7F5E*!q!DA zE%DOBNXvC&5|Zm+))ApT#)RBjI@OJ6e^6hc@8CLYTJ=#Hyd`j7Q!@pEN-j=hyt7S+ z2#d3(2+xaK6~P&8j9G3OK9hb|%j=}Xj-$+O?Brh&Km!R~uYny#y(kWMh#+yY{O5%g=vMhg*-F%pqA+H?h^99kaj zs8rQbuvflFkh*#fNey{JH}jiqjEaxg3-M%-7N{z@`INv0^!86wcz6av@`uN9Zp*WR zjTuFa47l~auR+JpKe_go@)0UQ+qT>^z0DN%qO>D>(!9>;-4g%P^3Rjr2HjeAZtM?r z5B_u`%biirE{>Oy@~J@3pVzOSKW$(*D-3d;2CPAn_s9C2W+NRgGXx0L*YnRctv?sM z!4OdI(!l@ygJ(2Ycm2yVD_POemt7ob@4fwr+huJLkqm-B5G(H4fGLQSB4$xvrzX^t zX>4j*XP^W5UW9!^IJLVAQ3ykgbUWf(M%It-hB$U^7-XU77J87Hao^((!Ud$HVkvDs ztz+XwyC~+?Oo{zpT}34dLn$aFt>+^#Bu2?VE1z-*5atmP;Q(ltR3n|FE{I?sdkLNf zQ}-atv^~W_8)`e)WmGsTwDGNC7^KEz!0-h)xS)w!e zm+*t8css)L?1jEdZ%(Yf%uQ(nYn$iQTkm@CZ?9yf;4#>Q;rk;!R>q+(i8yA-@84S8 zHK4%`NpiwDtB&Bee(Wm{uLYH}VQn`gHTJx;S8xT`-fyTZA00)ko2Zew-VE6+RQcnR zBUJpj96)v8DBbP%f!Fo!epG12Lk4tP6e$erir`|d-f#{}c*-P+iUXKrPIa>VD^!L7 ziqy-q!U#8+`evOEE`fqhOUNmptdNQ=^_QeL|Hm(1W|ecVBhvsFh#SLVgmn*6(^(j? z|JXRKxV`EvVYGv??t4LmWGg8Ew>C1!Bsm0CBeN1{D&{4^C ze=PTFYa*5?>)A=DYJ~jkamtU6u3x++jnR8|d`2avEO-ZZrV9{z2SDPewA!06V+kGudCRej(1%if9H`yzSFOAP9s_0C%Tm`=-2OOHg&GD{xS&K5)y`0xV1x zNIh|90-&AqF#?H^-r-*+`7I;zMcvp0+dgVS7aViEEu+8gsc)8?HCPlRcF0=8 zBhL+gs$RF!tQY^r^;2u2Jj22Q^!le*9jgA0$UUHlQ(bB_P~xD{@Va!t6BL6$Sz4t* zfdkQAp+l#yy^b1=k+P#{#Bca1(lwPlr6)e#HK%3Flr6m}E`j}TcS+EvVKuAvJ+ANS z3f#tga_?_KlC7}c$re1y6vM8k3wBIKrMJqQ9gu_p{X!4gSV%S7?=Zn6$jG{IaEMEU zygptlx^1J-;cx_^W*U>Q%d-o9Yhs{rkgF2O&La-!?v1j@v?P2v}p{m0B+^l&mi3Oq2~*4Wb323Yb^zM#rZK zCbYmjhIpvCGozu9&y6-@VhRINCEI|O)UyQ56AG>!OL@HFr^>JX;mtI5;XqYn#qPJ* z+n*#VHvbfJ9qAk~%C^?HxB~syj#povdU$%)ln(T1hDYnXE(L3Sixc4AnU%S4E+mxWITSp z=ZX@%C_D@43=0p({Iq9MTXWc_QBcJErV)E+N}%YmKldLzfe*KDpSby|XC3|hbUsHp z9Q)*3`b!+FQ334inIn{FL-kDoYcyYNR;lpl{X%Ab<{^ljjLrKBz}Taa!pAd&*Q> zar$$1(`7+*4GpAQ_L#|J+A@zX4ERi}GCNZ!gg|$4c4=nxYztIhhoZN>M&~(fq6~9m zVz&(tJ-_A6RE18I8c2_7?mN1z?SQiz9*j6ByDoSU-;q@HQnhTroa#Y zBirrooLj*+A;dI4d%T}wNe`%teIOx!4xIFh;%nt1H&!xFe?~Bjd35VsUVM1~Xwe7M z@3kbqM22MwLNvZwZZ0k^Y@X^+ml)E{tSQNZ<*N*aokzn$xSw=|T+(O2h&}0U7Iu1%Q^wtTjSQ>PNdQdm}jqhqfU1d;oKx8U`X507e>WPKR3QA)tuyFJ10o zw*>@27jXR`OUGQe(qonxHqF`s6@?44OIuq#8*QMg+pXQm2sh2?Ed&<%!nm#<3DQ^G zmIEa;iQ6Al8ZT8+FmdoO*D0EXuT|LcDP*Ek1Z*17a4m;-G60HF!qpk_u~n#&0+)Qc z>xY`_flScOWmcBoVOSr+J-Y;bk8Mmf0QRaWEh~)>zXaSR!w@0SF7%*=WK_m5BiO?UkL z$4gIo#LjOumz@9eH%O`;f}3^VU&lF-(4`hL@Jdol$H=ak`}|aj`5A($n+%(}u8c## z*`>?hJN1S0+>6r-O}E0NfZHi^W&lZOEAv(ON0gu9H;dOiR|9uORs)L|cm@mssA7=2 zk5HI;yMM~;E~~(whUufS%_=lFPjh^pTu|<(V|vqx6m!#?QETCu;IhwL)>;9?bE>Ha zFpt>vO=TN3`2**Q3SUJdR{untS|Oe2{b<@q^Ay<}?0aF_=~v_yE|AZaEn6hCSla>0ieBNl?nBf0m8CUPy{r0UQWNg=Pgfc`2^lq z;4(qyOC8iL`8$%o&!%wWt2ni<>?&guI z!>~ioLChC>ipziIh&xgh0v`S5wzg;Mvk2@9=;G>934-<+g?mZ*b&1$Reyd8G#cU@Y z`{S)tkO$m@J%EbTw)wRhlMh0GNQh|lwHW~Y4WvSUAi>U&GAD?x5lId{#2E)Qn8G>2 zCeSrK;V+f;b>eaV#REs_3=(r+TohL`xwMl#U0edYj@>;vy+qDZg)kz70fGs^!#Rrp+_E zgfdbp-A=2c!2wR2XyNO$33hkFj7{K*ZFbns?J@rKGbHyAttrIN_U&MN?b99AiB#Ui0COVaxVy z3;W_>(J~+&`Z^Tv$UgmO#1t(V!EZR^-K8$ZQJbVL|*$V`RVSVloxoA3+`86Uba` z8qoJtSV1d=`lbq2kn{wm*KXW|LP{jbTChS3c_To8TzDyr5_wFL=VvoP%E91ILBbjs zn@_Po4nXpU8P+~| zg42yo&Rt5pr$#|>|0z>eYS zSz(lHM(LJ$_?3ci{fYQF%^~z0q+Wk`+9Np2=H{^5!aRz>k=5cJMy8{;ghjR$p@oqaZq!1=cqO)9AT+iC0aHjp!W0S5 zLtD>z$VI=P>sfu4D0F%Y$((135H2r@=_j%#{2jUSKA{>HkHFz0+ZJdgKPf;Ke+cQN zq28?K-rnN=b!21^edqbPUO0c)UxI$okfiv&6K-WfFX$$=~q?@f+#GiE8Q2tAsCY;bl^9)wg#X4V*mv}sh}kq{B=d4Kz;3$-!6e7{Qy~r*}7SIf~xEA2W}|=M*TrLEJ10AI>7G7 z7f%dIfnq1bl+|EU4G^|t=s(d~)s+*zwC(vo2L#H~IZ?_4`^)?u%r$SqdnNZH?)ery zIVKo|0CYCefpZ^?eIrI|gHjh+dg6$t6izV+W$-`>c^JtE(gN_+>eH27Rj2_IX+vvf zr-5y0di6s+3Nk6f+H+sOCd(4wGVYQYnQiui`m>}fpO<%sF0)^)LK1D0@|jEH2HSWLSpDf|m`|xpxH64zf@AmU%kPDRAANhLy|aZz{;WWyTv$8rLA&aVZKE*q z`&;7gQy6y)y5CG`+vEF+cu{_OE%Z}}M?UN?hc!;Z&v7L$sa@04mv)k2=vIV}%ri?N zbTr%o!Od?7w?sJD@PM*fpqNfgjt3is9m#0YsFDw2dFcWipWBH!aCaG*6cG2+6DqvS z1^kkjpVHv|RJ8Ge-mXJVya$dDQWG?RgbNvdhSxp)hIj6amUvAU+MUD;XrCnU5~iS_ z5wp~gfbrFljgR~-R~Gq>MCy)Dhq2)c!J%n zkx(FYC@Tf55A=HZq>AbVqo$F95cCBCTj&voI1He9e1@gL>WJ*1u{W$ zP3*fHgUEMvCfrJ)r-R| zpn9M`_wq*Wv`}L%cavj%VLfq?k)EaHBSuXV49Jd_q8Qw}0yl-JtzU8(VW-(sAYgp^V+}z0WmJ`=l^txM< zb(uD2(uZnfeQ(K1mRsKZdH>vTZicyUrM(Vxwi5$% zAIcgs8|*W?muKnpI}SX9fw=cf%GQZXz`{yxS{W@;5tsilw)~WoxP?34aW0n}Xad}% z_$j87B3U)z*9{*D$hV%;pF6SAH$(NZrePyw>YwLr*7gn65&hmy`Nej-d^QDx9E{2u zdj+ja>I2r)sb0Qa`X_jEvwM%Gj;4F^Mo(u&w6Hf*U<+>ZTZqKg+gOP$g;0sjt<05Y z^j1weIHBGU7kjnuBJ1?4^A$YtIKgo%5iaA{V*2?<_SKPoUW&b&5F`ye81(wj+1QFT-8xW8-zM>BuVF_C+=*S0+! z<4gFBD4Nl-_$B(xd^zsRE@=u18C5~Wv4Oic9Cp=JQwFf=isVt1M*eKuT+HZw=5&0` z9L>~%!*q{ox1e5e)%O|~+3ceq^YhIlbZ}j+UtLPd)n>G2xQ*ucn|lV-<8Z2?kU(6t zwW;~(mjg#4?|5#Xg13!|_?uW&#eddbFiFyW`|Fn>S&4GiWtXus@tTKy zi@CftKZ$#GUD0~JkC=S(P+}9nb|U;CnhQxLx3xKuDhJPKYLW7daqOw83Eaj>kDZ^u z)J4XBiPgt`T=eP<;!7zK{?3eET`KtEc@Y-=J~uH-KK+C#uq)0$iIA?2d3k0VzM)k8 zrZu>#==l^}euWceb7uwK?+;g*e@ewM-EGjuG{RbUyPrzImr{PpWxMPQxkH(4974S zP;6NU#(?XOQ%|eI{E?M@GF#_Cbb81~7$H@7NP3LZyWvqdT=|DvdONgj{-$gB_mos9 zkf!9-1NM$8gKQ ziBNT-+FR?zIJ#YBBX8{orlQnrs6LE5w7Hb`LaJF6Tv>x+!{D7moLOeX<@f_F2i529 zCRbZAvBi~@nnwpN-!wl)VXWKBu0yTTcDM4crJJ33ONADZtrOY$k=#$audP~#_s@5i z;QVFo3dJRc6KMovfLEtu>a& z-O?^+)M2U4bGT=%Y5)Eot7$j-6Y&X(%~raJOSw6fu5b>1+Kv~e&k#3U%t6s+1>9LjGDp`H zP3~X*YCAtvWi|2Avl>eLa!sytgXPq_O1`;wtsGxh{o}ZDQ+3_Fy}bF?RwnK>->7cK z@2M_j6AprIeOqbmYQGTiJV*%upWiT|%}D4*o6=wB5G3qJB6g>om5j|qkwEWru|o^$ z9@~E971FL(Mitd+6!6Pro2_?L8|*pvk)Kjo$I@B}uH6sQExLphbPTpT@b3(g0_e+* zJx42nXEMxW>*C<5Y~Qzv6ZhqIw6_QQi-je?jh=D5wtD;Akd6U!B)|1oCG?~{ci0N# zIp^)ED*Q~JF)4$C=m}&*%8r z%(mmo*9bl?#ho^2wTA5NW8mMDSr}YjnX4*wE4VnQpl}+@$T8W#Sbbl1$W-UZ%m{clTW&hUe{NVfCN*XnXSodLUu!8g>0yE zR~gn6Xq~^k3pHezcHugwbI+mCJ4V1!qu0m(wH8mHAJJ47L3l`bp^Rg^BJ0t!HxB}! zAau-ab4I7ePo#(&zIKO8yi_w~UMkBB(U`UgljcXN3lQbQY1xf+Lgmwo23f94YqW>2 zY;}M*g0+%$Gk0~n*8H!!*h{+TNsrZC8hLVc=yk>Zk7TRSi94(sTGYaXZMtK_rW^;z zoI{09(g;}%wl-F?pipcWR=VIJINY-*vw@#-BsH@ze&V-bDMoJxj_nY*D1kIaR-ir1 zvY#I^HmOw&ESVh4c)WhMm~&kDNi?uo@XGr5b7$O&e@EPPS`eZVW+x#6lLAM~Fs=R@a5NNz-OX{6=z{b$ej4@uilVt<73Cz83#8weh5>bwFi02#+p@8sav3MQQ># z*R0AOp4?T6GSJ65(@1vUE=k;8X&}d>Rj)Z#yt%J0!elFDA@lJ%&fcvtSyyi@?6DkI zS!n!r!k~ZKB>|a8gq=mG1H&+mfEUAm4Rd;>hv$!-*v+i_K!CO)e$B;6LEb>0I6-&Y z=gPkkC#bCpYvTpd-17|?g_g3KRs%=)S^k=a%cDC>8ctPmYROCDsUpn}#g-aySw#Tu z6#*k;7RooqIETlk?lxYek`dK0(|{9_oc@M904RF3Jv-ligDyTFM4G#>@uu}fl?UI6 z?|Xhd{3-ky97tJ7ChkmwBti_N5WKx46!b{m^eQTbH}MMQSe-d1Fdv(w%*LPiS7d(K zdD=$}>0l=l$agGhj*eA$vqT+3$=`%-!54#+om$RXjov38p*megtdeXUtK9Pl0=J*RmL^c$oTR&_MzeF{cd z^5N>TmD7nl>K=4mPkS5O5Hm~i7R_r)92O8qVUrLpx3%o(i4OA*oCl|04J5pp_^p>W zmG>qgJWmoNeW>7PKTBu*k{JujkFXrK&%B7r;bnU+1-rE-P0CZBH@WH1H&U3XU`JX= z+fR}#kyHo`l+Z1*xe`6ZqO&g9=&f7hdyVFRjSV%OzD#ifXzv%EPV60 zKS#W|d}c-h=7obpj9EtoHL`&!!XY`US-=HZ6rKj$#+&GxxlEi3Op&w6p{!V*-ob8D z5Z=VwRd)%}cKx6mAiV5_KOvoRo9gDy_w@a}b=TL_AtA<PUhnU!MH zCx&5keO$++<+W+R!5UQH@*jAmY4bPtOc+}Qe$$*HZ5o-kz!ye~UyNQi7bi`(+NIT< ze_1W!GaSv_^oe8^fNXHgF@T>(yA3L@p=0HnRhANibS|*PEv^SnOii!}R1G8ZDq-@9 zI5QVXGs8R)^JxF$0GDa~P(ulcYnaXY!hsG**3yN}K@AV6xRCADyKRHzV?>k18v}Iy zr{=*Cx!5{AS*%v`T&LjtxENR7k+0X4AMfY(=#D4WjYa!OuF{7q0L;J^qp0Y718%w{ zx+-0ym~UM9o4rQdp#ypH>;l!p_1D+7k25KlImv?Rph#BuqmbJ?D|JnE?g?v|U-hTV zrXa8yo~9w3if?M9$l?bVcxknly z-*>dX{V%Ug$YjS=#96%?Kj-x{{S<$qUdj{}&c~5WD(ET_U9+T@=upj18;JnP=M`z35Mfqp2E!ab>c9nc6vomXTN1TCPgDy%WX$o~Qpct1n55vHJ;=WCVy6 zpgOwDg4>T(h9RTDAGaElLsHfzr?teg!*>zS@INWpZbiGWb3#E8B47)+p_>KwZahS=2+z8+P9Tsi*c}GALf$-Jdf|Lm z($}00TwWzv8cKG7L^xQtg-y2YvI1!-cL31l@==h$$Oadyz*^jS{o`OGKc&(Q9ceQ- zQXN{|L_dIhe%`68t0P~Ka5z?brDMD_=6ouWsU8cYv>zS_=z* z?EmdG*~F5+@jSSXm*z?q0OJZ#q2^-4O_!C)2qkWn#rRVX7O1|G!dC_I#}?jGmvJGi zvrP6W4T+)D=yg-yy#XU|vUH`D^(>s!nz%_so*wW_N+yrpxP<;PyOoaQ*5nt$%M**WWv2w`%+;?!dO1-p7V~`-t__-8UF; zio~P&He^2_-t7CQw1Z7-hkN|yk$Ywm1}3C74FEN>aLry56RVfmzP0`#U3f|Ql7R@c zMhQ3tr-ao(9o+hlsw3qe_>Tl>S(-UDQ^E`pD}=hHBm z05~>Xh>GsCn z8l8i2r{ZA0p1<{UzeN1!z4-0=8DA+;&>)+cX+*@AC_G~lYUpG+=Qp=CWoIo{dFMRr zIg>fqb7ZyfHZr6B3u2M2@}Y+A2Z@ALGtQC=vo~EO;A>?Zd*5vK*R|FY>s3lVWK+{? zS-zVv{%nSW6Zl5v$e1l{gts5>WgoKxf8EunjZzwk5b0R^oEhm9LbLDRGG z;yu+i;#est-ZI?>IxB=^dTL^8|MA}0)xN-EbjKU`kN9P9A{YeO`8T~r`qIEv#DcMl z-d;DMdmY+r%2q4~A)n}X*9B~OxR1;3ZxFY>#G`a#UXTtGb13i?-7K-U%E`}%d`WX4 zLshif`gnv=^QS6a5%Oy53&YkQ+5o#V3hRGucvbU$^=a(dFjjWqR-YL3%=@lj z^X%I0Uc6PyC1nD*Bu`5o0;wxipdJxy-H`1Zpeo;5&a{>jkL!Udht_(|`(@-^8Oq0F z4vwxV*~eBw?`Qta*Sc56RzDuqJZd(p5v0#Zb4%ypj?Z3Rw`70W{!~&R7&4;0))HKe zr2S;FE5beXYd22cpl5}pzt-0KjH<}ZFuD8_zUx+jopc%vlfj3$YQqzD{d112Usk3>zZ?#wu4eq!fud1C5bzV8# zP_O&3O{PGW15m0&?CMCRgs=|wx6LO9pINif$m*Cm-7fB}yNaS!a}n&xHhd8f{rg+0 z@2Cj~x;)ej!nDdAT{Q2H5tf38#L(=R27$Ter)JJp~TE?H7Y*jN194jxJ zyvUyz`&0;vbQ9h$H{GQUWUe6G)zB{tKSUF{)5G(s16QSEg%lfMuf^ua=f3V2P9`)XbFGq{z8eS% zI?O8XAO#0v>z#cL-?%?6IM^S+Fw13oBbZ4bYo8S)u|h-#w&2-uY_YpKIQ`H$a@{}dq&6J1UEt~u^Ju4}UH!JS7BunV-mlnzv%l&i~j93(JbZVftR>ep5b5Kw-^j#%T!hK(0}!;&DjzI-KDMK@pMU~ zL<|Kzh8aP`=&k1JlEd#;sjCwn%EAVvR|)h|p=;gKEu3f)L;To1q|+ImIZzcJUCuiw+Lk`>!d%`bDhW2|pUW7cNtA=^TLHR`WC7@S4C_De;))qI&b@H6 z1dldJ0xAH1I3*@V;S-u~M@V_!w;_g&5yw$S!q}>`h?_~;j7GRV<79IYKw3=iCa(@? z)lHd|;VC*y#kcLeyM-fs9maNazTxii9;_1j-I#w|x$QZV_kjOwSf&O00dXgjoG~Z- z!XG6q{IO1y{_S$ZZSph>EUY^XP2%PzBM#rNTvHD-E91ey{~gYpcvAsjMC@PSk6}~j z7DIP6NJAv7GHi?=7@7^Ag9Etqijxk~|7K-&azy7hi1;t?T+4P{<;TNU%P|H zBD@@1dYf-8M7Fj*44cE+lHAovR$kYWN%9by(CNJ1yAYeMZw^*}pW|$T&y3AXUbYnP zi7$CMh6gytkj+ZhZ3K=-*!qPHwB8*VH_=K|p?H>Wpj(yRce%yb56_n;xe8kuPe@7?>;LhP81WHTjF19Qa z%vjAdyDujuJYi;*x!TAtOW2e$mr1*GItO%`pf$JbAgJBI0KY|xctO=%a9o)xJrfSZ zczsJXab8SGasJ65j29EhwzQhZYkFhL@D44*^#iXopw}qRQZg)Rf13^7{b?gx_)t36 zA7AF7Tb8$Vy6DK%& z5XqgSDExtHln5XQ2jW4imQ{mVW-UMEKUi8a&t-i)f+se=@xvw?PRk_{#bh}5EUZUfafN8=heOU_?Mr| zGw%tsW;2BxWO8@L@^{^w;A>`ico#H$J9A zw?hpt9x(UcBVWM9HVU^e zhQFUhBwsh0%phU>)+C$EHf2a~AcqNC1Dz#HwJMkV{$Ojilw=51WtVe;cg2&)AvtHmX=f-+b6}9j>9ceot%;km9Y9Anf`qrDcRzX31^s6! zP>}kS#QmCV-mUn%8aEsryWU*#- zC!-z0@}E<|%}C+TxT*_&S1J>&8T_Ju!Y^2;qjLZ`a-Iga@r}94O}7$}ape)P)6eNz zQ_EPeoBh9@eeea^La!l|JO-91`21s!-qcw7st2Q5X*vgAH%~EP`@2_@*}wiv-#?r} z6pXh~VLqKum>)^zOm4f=RR5}+8J`P{Q74Tr=>*h%FwMioudQH-zK56lqHuapVZ;!N zP&HD^5?P2VXHHtVw&xBDV^xrwdg|cXZSqmCB5dF44n`5lLoRe$DmtyOEtlx<+md{9 zMRt~NEn&QYt<#^XUlvSM`otXD9986>QC?6&72swDv8_WA(q zZ{&5V`7StABkdMp&G`Kj^(lx`RqU9+hkx-hWfps-J6S3$=A3N!1&*Vf+O!P~4Uh|4 z3r-!{>YW4c<8Ur3M@`YPiOL{PG4J-*a*z!%9jnTNF8v);mDjJGmqv>K*_YV09>LTy zeaJ2m2TA@|E+&?Mv@u(!e_6SFa8UCH)El{Pl*+cd^(x8}K{(bh%Zv2WaLJ}R3nD8{Y&E#a_OYxO| zLm?K7bZSvtsn9WS<+o>s6c@$(Q8Mpm>3j8nFnAH4JYL>(Y-z!Y@rI7 zituZZLgwpwSPglzRD%HBbCYFx+-73I?9ddPbk)-MoJm1|(4~|So*~6V?jDGZ1%ZbW z5)vRyy!zcPcEx`nLg{H$4+4uDtP9L0g-W`q;DvYHP07CVr4Tgr`lG(`P{WULqXnO> zsVl#YeTh)Y%5GuO6F0I`v0MC`5Ndu3A?ON&-XBnO znlf$|+^M$YjO`cH;g0j-3?)3Z;nWoZ^m0n%+Zy?u9iRzUSUnTvyw;fsC8o@(qZ5&85bJo zpGQ2{SiM)jcKiil6;9<{J56sMt(v<~%zh%p_5wB^%4F_b(0fEkjks@k8Zyd^9-uNB z1+e%x`i||5XjW&;u`wo*e`_SFp`oTE zne2Sr)jCqNf@wui(E5xE5FWFXOjs!waG(2GFhT(NkmmNXHjB#b(#7yPV z#B+9P7gYc2P4SQR3!J&U)*JvJ0lMRU$Wg*dypJuQClq0?Rrrfbg$`QO8mlz!L?7x- zmeSH~5r96@VW{2L@fJ^JsLZExIZw_8aXM-7)!pkA>?k8>Sguj*K zh53NGCO{_JZDW*SI8g^@(&&9m+ET(urEz8(59vn&2Dr1nL?8%4g|{B7@K!~F<5H!+ z#HTXOAv-hr&{+Cf>V5pShBk9NNCak;br^_N@6x&~Hp7YVl)&zXJ5x|Bv48da>%C{G z_wJ(5=y=NeT5PvG5h44~Xa8H{g))EP*q7#OjHrz$_5Sj7!n>3R{LUtyO(~PRcm1J& zRRuUR$bkA}c)D?3}bD&CWqe1YtweHKF6dVC8qx z(|q8jbZKZPjPBkBmQF^KZk3HpOkxxDPQp>>*jHJVs7;INho+O0(w^3CK=bfR^9$cG zN9O-sbwKz9GFc%hYCuqeZ}-K>%_~}Gc_BhcRtqQ^%zBIO3!~&x-rmvwc$oe+_~cpl zzP!iERu`#VcvJxvGOnzoX6Ym`YXs9-zbS)XJ~F3Qs2XckpG=A)ECLv(YaSB!<@orP z_zc+f0*q9Xx2Hv(G%Z{ni0=wP?jY+uKYnB$0rkeklv=SE)p>BNO{qI%%HjX4!?CN< z($WYL1Uw}?4LWx753JxGY~pWkQ}Ra%`f*3Ye8OBlfSz*fdH5smHX;cKk`rJh)D5S0 zS8nIzpS+$)3Pw%_e*%ONbQ1y}g8$ayO@RqD}JLEZj7mC-Lx;gcoIsr#lx= zX!KDb!w7HAqDY5Hm-b(ETn#rzvyGweIwKLLrnm4xYGD+Aacxj2wq25RNb~ZV4v1v} z{@Fu)4PVK%Ayje`fS=?@WPc$&e`;GaabC!_b=OabczPJoru|PPH^F~k?1g62RI+*f zlFp6XmC=CLKJreJ0Igkog?vaaRCENmAeP?ie#gTam+gJ-*a4Bw`W)?TcUN%X#JEva( z#sQ$jz5uzu6NcMdDi6?cT?j@`slKYXQ9EA(nPggd%ow_Fkgg-qo#gd&PLa9qH(izoNKr9vX&)Tg~TYO0C*g)kY(X?@zJE7e=(f@ev^+p~f$x9-XpM*2dOYR#WWOe_6sbk89tPpaBB zh?GGAeFh5Xrr#$l>c(f}i=SN_xxXKK)d(r_qewAE>@Lvgawn?X{GCD8SQ#HbbC{57 zJZh^xd^r*CcJ9aXeVt?=t-FE&rZa{5I1;)6M~#prVh*n&tW&Bl(jXK})Hi+<9(`2! zuZMp@q+=MX64VRzCR28va6}ZNZk~EfDG9!)xeg^J@sP?iL@Lj&|mUB9e|1|cr`!w07>Jm$aMve8nZWRYCy+#MMqF|S{_73pBT*c36 zB7RPvM3TI;wuk>wyuC5}_2ZX*1?w=v3(k<*p(xtC5z)u|)=IfZ>vV^#1`)?_BIRKk zC|_S^4gGYSNBV>{LAI!yY|-gf$KAHZFMW3Z<$S|{(^TpFBizQ7MsFI4)803`xn2G= zT70$1ACKQ=eB|4;UWUDH;G;#dsB@zkVe%2 zvq>403qA5GF&Kk-BfpBv6r$naU2vA~iPpz+%>L^W$1g)(sv0ydqD_{g1_uwT;oQ{5 zBa+JYiSyH&M!#?b5$P@Vm1HzdK)BlTFK&k~x<- zpK@UPg*^7B6we_57&P$T*i;YQFX8a>f_2zV>yP-OBuL6i0@pww6IP`Hjx2EOmeW+xBP#-?;(&)@qk)fMEydr>sHInVm%9g?@2Ws4T-Vt?JItW z%mhAi7-iQv4j<_RD2C&Gho~FNx$5FZVN#+86vG_y&{Uqp*6wu>*|>gkSyi=OGb;-(lROb^qiJH?%&&_F&b*UAXy21?ywQ z)^aL3D63d=F4Rz(5?x4T53y%;caa^zM~-z$QHK!kB_30PZixeT(VqEgX3-!dm}tUP z!-W6bVY1JCh}CW11ecyAuiGxgUrfFe6?qE+L3}-W`V#5*8S4_-7!hbKVRdv+gT8$I z-Q0aS6_E?79&zRI9IfW^Mcm_rMb{^L+dJT!WG5^_!~;ou(e?oow7|x(w;J0yTrI=9 zFXSV8%k=-)d-HHC^Y?H3p6S!{nVM=^v@p`9q|idLYbI?eGLPdnimSt+DLTE}U zgrTxCl8~(_OOY)hdy!1c<5d| z;uq4N;vKAXrm>(*$Nhs_6XN8C56OOrnl@L(XVwgBvlYJir|e_bEpJ_`xl(|`mnHoP zH)W-7gG$;HC@UqrcI^zm@i>Dq&F7BJ`i~xx3 zwtFw(uSe$lbid>I53+sOd)?FvqUNfUjq*mC&G6$pRPJ+PF0=ISZ+trRy&D0Xjx&WB zGyI&wx^5*Oe|-Gg)veB+O*hZJ`=;r-U;u~D^|SZeqphvI=f?VF-^^a3TRd_Q-0_>( zK{roCcJ`TA9FHzIIof#OROOv#T$5tfr1K;ujutorAd}SnFw)yq+F1KLd)19_N8=R> zJ&v_Kl-0a?+$-|wf@K`uUUR=m13f^jW&w5$Zc__lkLmLq%-!qxz+4A2v+pPMQ@*Bo z%MIHi-@SdpyrJTfN$1G}9ki64D(d{@xF;bKH{t9 ztU}*H1A!>bXq7GMl1~qZ#6O75H#%peJ?Am=`A2srom_zv)I}R+y;gC%%uIIH@p%@? zTlV)KS@&9US%tChDgn+ibbkuLy2=MfN3UD8=f?NvzL_a}Wb9dL(50KRpYPeMCVAvi z`O_wAJ->)&n|G)m_VD3sw9S(|E2pdvZ=NtMlmG51&E4lMXeqjD{r(n-9hUks0V;lj>uNFZ@6`9%zLf5nQRhH>%;hvc*MaA$CW_-*xddJ@31gV+X2A zPg;ar;x~>*iq!(~;nwGxjeoD1y(%F5KJVJRRM|}{OVxhkN~KBWU~z75TZP!Fy?*nr zUAs25V7&8TeKwy>-OerQE$g1fxW$gmYWzDsO^7QiCJUI^4q)FGpw{!c#pXI@I=U_; zeen)Wt-l?-wq5ycLyX^7n40_y&D&hzv~1D>hGu|fFBi(wpt!wyre$u&Jd1r>_P2Fvvko(9k}avN{zz_W;Z7sKNY z?e|&7Oy>vhNy2b;R9u`l)kRG$+9#kOSEtjff7Wfc(f(M$LwOHBc0~+z-(AkNnI`2D zDGJzv@HVR}R{+DzYg%j6DtItdr26`a$c8+ntg}_W>iI3c!VOggi+_5Y>mo@DT_iWp znp%)Cq!5?$lccQAiI4`f=*ZR=W0=jITr1h>)6ywUtO5@Y&(wnYo*u^rPbtfl0g=hP z8})``vQJg^yZdl9XZfepdDgaVS<~b{{7QZ2X80X9JMOV&;XXHssB&Crcl|-)HXEg8 zml-EG6PmS+nU~^82K_+lrXtx*Xn~P=)}(%@O~-0jJ!y47_{EJkk3{nqw{#fK*>8{% zVrS1>_}X&P8)mLuyVfHr_Mz~DSB4&E-w9;)blG*jX}&U3ecMbP9=$39gA%pd+}-B& zNxu9Q2=Y(qSTv+N+Z;A};?O!Lv!m9(x`%Hl-!AIg);qRrF?Y4yKgI4@uO5+#rxecV zetPldN_)}|AA>O~7$9sP6(Uj>(^20tdd|>(PAM}?MVU_<=I2nNR9qxweHbc2c67Jw znZ_sIt`_#nX?4C;C$oN7f6mqaa?MabTj1*IeO~VF?q}bz2P+&K;>5-z-l#n@6Jn3# zh9A3Eu%D-L`CZ1uW_^0tQt#Plpg?sOJmUVx3vzrs!m|9-&E~3HiP|Gq@|m6JfUFo2Ir9hEP1T0PZIZe?`GT^isVBe;X8vnVJex@=(I+AgrP;u@Uw zx16onYdq;dgw0&Ee(9=xfj{6KaUz@wYD+#G_~~)Pl@cxO$_OXU)=d6|naTI1lip9X zl0r^s!m{?r=4wCBHn9x(LmG)I1CI4bm`IQ7I9<>bU&uAJoF@5j#m2-t%V4Hk6Fizl zyku6@{&6CtAW61@H$Uab*v_ zf6<${%72PDv4mcsCp8s8uQ_r$`vs5HlYYyKa3+2`$P>FEX|wdzyPV1F<>0!#lQJ(J znGC|!6u>!m+L|CHH+VqSp(hjvL09>Hc6H(u=^D)ibNa5Wb?4YhuJWI=~vtXT=#rMqG4XvAWgyx`iOobuPdAwptnvzxXKK7n1 z`+r%Gn3z>{Z_kC{Z+_>>lI%Y}fuAcw($ZvCsRS&-NQI7!c_)o+Fd6^lG>n#5k$Lfd zo%Wd3Kl8b$2pZ4R*U-vI&)ZOKk$QXt1^esl#_lRxx--kL{}^z?HEA~HMP^pmUc=u-*S+i;)+iO9m_2$D$2uc-skQNu3Fc%Bl^6ixbISqW98)bX$e*5`s$t5HV2+L zwV=@HjD_sx(fGqtPCfQdx&HL@U#3U25AM3hJfPTi(lQ9{*VJ4{NB!Qt$MO$)tAj>2 zFGzd1^o`nJ32cL6mgUx_UA8(WYE4U6^oQBP9S*ULn{4alVNzWe491teQRAz){Op~c zfRB#Gl^>Xu=$(|Rp_sII%ZZ=&1Z>%mmp6S_sPxuV_9aZvjT4bGMa*>g^4CU5rpT{P zz5jkObLo4TN$+RDlyV~Mq*rWirfjC`($yD#x}fT}gQMs6tl~9m+nl1yOzpVNS9Zk{bE7)?Kg3@1T>MINs`UYbTui{haitVD_Xd5B&1>=^s`tcYGJfx-`zVxO7)= z@3W~x)1pE}>SFo-de*n>W|NW(Cm@tD=`8N_q~*x*;@2rQFHPNRRcb8RG%Awr9~J-b z^i{KS+zbfU!;`jX#2?QNH(XE{`NbUe!PJ7x54j5)GA)PMza5Mz)e5Y9TZK&;a*GKc zDb|0=&12opgZ05skkYBB>-FE2>Gpe^$eu0gsggEkM#oJWQ;yx+3zI2?lhN?`#f6~t z=40}1&YD!jYV#cw^_y#^Q@$!dcsXB+mYPmdNg^Xo{}{N*Olz;)Bg%$pR{fbZw@!qdo>^Arugj-jqU*znz`xg-w1R4p(b1Pkl#Y*$&hT@2`))@=_G*2M zcAL@N<5$go+L%92fl0M;&6uRGcgE}w-JVU|Y|l1Z4vft#!505}+Z^`&#H_q-chA_F zUWbbq2rbxhk`_GB0d4I@T^E8Yo7n5T{l!wHAe^j!B?CLA`u&SX?T*iGF{eT?Xp(Du z`_QVZZe5MJxgeOd2nNBFOHUQ~(`+r4g|(W=yvdSTrKbDl(LtUApJ?KmA&vYo~fx=u}O*T$vI_4M=v z{r7z8YwJ8Zq=c3gBp`GrDYf9;q2;N6R7^9euWmPGc6V_S zW>2o1XxABfBNBsW2wW5xc|EP9s_KxB4R?B8k4sb8&eIj%>yDhRl*w;^MP1jPsch+{o2I9e z^mm&?<=ybABN7|~P#VYj{U5Q=s^n6Jq}caldfFNxO}mk5rqR=-S;^ix-ibKC(M&qz z$ensmvwK%< zO#QVU7vHF_mE=-T_v(Rx-h0!j)|Xq*LBvDfqM*r|Ofxx)9W zzEWklUENseHNjiYF{lS~raLt2mw3Drsfzy2(|_P!8cz15CUOgDB3v_KLQ>V`{9Hlp?OwR@)f>6G$b}wlzPyk&4xG1J7g`u`ft}75!Nja$Ta(=Y2aew z8aM-PdzDu2Kcs)UFw2u^l>xr-S7@LSipzo4HNvL!ptDESC@^f^_gd-(Du7+1VP4S1 zus{dl^Ror?-}Z7>r`MQ5NC9Y^L1g6j@)OK7;}`>I#$EmIuc=>~dMi_?Vy=j>@&2;% z2X$=_z$*;>&jxaAHkz^cGlShsb3n6-*n(6`7;bJ%??vP;pFEfN_ql1gH#Qg^2hr1QnqhqMJ?o ziMt4lEkQcpjrG6$DBD~76Mv@*`m;BX1P8H!_kMl-z-{K-cX}00Te)kX(K{F1;Kfaq z=Y4q_Y!$}!&W!m7iM?;v-L@{A9~{bB59`{_8QE_w;#fWxFW&2%#VXdW2PeM~dPCXw zQ%Oh{a#GCikECwc@q^Viz-c46#k@c! zu!%Y^t6Xzgv0PYKxZ%T-+1`+G>uL0_O#Hnv?+gI5@`jSLu$UO})2PTuVS@P*6BDNv zD2Vs{Y1b0rJ6%3AKGNY_#WyCt3r0A8BWw?c-@pQrlUSkeZ(9V6P5?q)(>y+Vfu6%h z+KLdVZeU52WM`mN83M;$*`jhXGie}1vV*zbOnmp*lmrO6FaN&hl)T-A1deP3u!`T* zkz&I;BxpA?_7wuzJ5FPR5oiV}qHFz=xY%*gBM+8ct$m$HsxJF{97jc(!dj7gjOJ7e z(6Yr}x86Emq!A?rr+}Ts1vmFY@>`_$l`j%MQoO4F{(}cOP!amYJ*ht_DJe1A41q*n1~StJK=pe4eI<8||JpzWP(;5lwLsL-QG3tuoBM?K z2I^In&n@6lZ%fyJI*rs=;KSiHM=OVyjySo1Upt?snvM)~#iJXPWx3Rf9bT8H7ZE!U z-lhmDdNQ?}eIBEa{h-~O-xoF@5^PLhp^}VgzDUv~M0(cZjP-Q-OP?Z`i${c$|HJ~= zcX;E?MGDSmz7vp7gMX#a-E22fm^(vi3-7VE&35)}-FMGgGlO^idi`YwFrFVjoKU$p zmJO%Ms$APt(7K%JVX4G%RYgLjxi0$bxdo{2p&T=Ge{d3%GDC|RPb&0d2cAEF{)U8^ z#;$JeY!oNWTq3(AHe;yu>EVsQW1P!6;_b#7M2jRed@MgyU4GtucH=+KJ_f~jcVAGT zZ4tDaKvNUnnBbvhv_bgl2e#MAp@&&dwfXqpNf~`Hv-)KLEM?E;#2;C#Iq~CT!?~L1 zTy@q&MTBBLf5W#}NDOIpa;Rh!-Oq_AuvkaNf9wJ$RA_KzX2w9pKy8sr z#hsh#B@5W)9}U=vzaGz@F3qX9z|yLvLV|S1dh^R{Zf$LyD`!(2ywwWKa!s|R`(rcS z8wm_+)j_Jdq;KPZyP%p5p%VuHOF}||d*YgIYCaS%)vC2j4>CLCyF+P}PVpc!X}!lG z=pw-s^OJo=E{t{`8ySaAq8s+HalAJ)G?dl`6Gvo%o}V?~kM>&|&?-o?*j&`tBck!{ z_MR8-REorXOv{H;7-xCGNqOeZPROpkdkrnJTw=3MIJd%b7 zNQm&F&E{HLdy3>nbY;7$R|6ZAu#OLZV3A&N-sJkilN^Q1c^gy)=cQ(#lf=Tl5vPxp ztJy=?vpO$(9R09s)7s8Wn=Sh3CF-y1SS%)!?eCtXy~!dAGUJmEI`T!9kDqP-n+qZ- zR=_%m=!1l6(i=xHq1MYD8HbFoKMY9=o3lY0C%AiJck(gZ!ql2}YXV>t!@TT+A*YU; zU2x>fw{9Di{p+~)R!;sWWAH@uLE^mCqjq}k4r3sJ39ub4(=-ri9h7^9t}2G;=x5)b zhQ^{||7^)u$!KS+Kz;qrnv6^L$62v6YpdU6*j61fRJYHrcZof!w}j`W`NUIfY2ZHj zO+>z8-+xlAxK@{6E;ICu(=#--T!MmREI5dB1-W@7EEb=po*qAe+pq!v+Xr<2oYt){ zm{}}K?!8Wbe^CDNkPK_%tsK!@%-sJzC}yc4W}RHMdBWcPn@;wQ@T}Fy(y>fefBBu< zR%}2@O0e%IzmY(rxtz=zSR{L^Vc0b`c!-G}*$n&QrPV>B?0Y=+{cvMq`)!=;4}Sg} zq#Mube_2tnP~s=k!1|j3>9u5T=qmtVA2omj_yHJ z$2z5ERloS*Llrs#K*Nf)IVVf6N=s2V9Tv8I#k5&JEGjE2Qz|HqGss-D{%6HHIsT^h z4vlE7In-68P7b&UgOzddDcHA0*qqM2p#o$Ss~3+X%$DQZS2y~0RfWHGrIxoN-NZd-@6){TB32atq;{vG zMGvBnxe*REBQ|qs-r9UgElcG;T$-hIi1Nz2BhkaM( zx_&hUJS9E}Nr%ARLfPzpSxQ55<>@yz^8U#uveDY7wm!y$FMP zIb$#sWo&5nOzvOUpM%B=l{3qEAyY(_=Z$^L9Ll>^^6G$}m@K3Af}0sHhOZQ98n)>n zA>#E0#U)Z$HBZ#GHo*S!MuD;nJA+B%2cK!^wg~R~2Cv6bZ#eqmb~udIBV)fB$bBDI zc;?i(3LV6ZBK7*S8~d8}PBmp#BAAUR-ho|TZAs4ZuPDc{0kECp_LO zSAp(;q08z!e(C$cgW9v7yN7k!A4{)TkQn2Z=(6^!ibRp>_Dh`6^AGZ!X4T$?{$e{s zOn=1K-F5p5>l$DUdc(bNI%g?7wu2sE^!T@L1$SQyhTl;Pv^gL`*z+c;xgM`JQAajB5``8*lUA%)?XJd9?9RfF1mL4_E;_6iG8PQf8`I3 zR=GnPul2oT+k^Y}eO6xh`UEwlB#XS|Lpm{TQ{nJ_jq)Dnlo9IGOf(ZEMV0U>4LfU6 zloYszlj~zJDhe=s#W0~?G*wEht;m8bY783h2?|ZSm;Sz5Rh?&r<~AR~@A8hAM<{RR zK=l^)(GDT;P0g99dU8??BdVWDlXYvhtPC zP#fvI%B!&bm65!>BMZu+yL0%_H2LpQd2SFV_7h_d1Bs#M<=);h)^qd+$$u5|ckXo-xC(AhF3Xum5gV-rZ|+Ztf8;FIU=@_4?_!6i1p3pm0G^ zcqYHJIC}_vlHB#b*1van*ZuqV-`1A$&3HuA6I5+V`Kq?{Pybla$aEoma^cf_`IHlt zEmg{IO<;>Sh*_jGT*m<@(b_*}&YV*)k(lW^iFoqm-7B_VdVit_RKgy9e{L#b?)#xbOh|YAKr(B%5%Q29-@#Y>~`=)DCUA7K9A2!V??U(2GEaAmTKBhy~ znE#30%tswoO#ON3wQs&#RQ$#uFdgmmlnU0njE$tVJvl$q0}>GWX^n{Xy_K^RMm`XL z($iT@z674;b?bCh#I|SL2L=y+w|L`9UuWArI@R z?N`{X(}%VuAPL5cMEW34*&KxK>wFG#axWa#;Dr(?X(p|WfAnruL0L(UOkTx7anOcR zY?r8t>YU)Lbq&{#%TpQSTtV&@bL|}{w9S}D`Da@bdQ6HuqQ-kNvBi#XSm|U=#FK>eN>XmoUajch=(%e8sL!@r9$sITS1HE;JoOB9Ok~lWl@Og zE-(*>181D>H{RzmB09F-(fK{G3!2(5EO8KG4}rzkCn+Gn1a1`3fF{Fw>FJCL55K5mks?T-{->#PCIbcSys|DY z`)Rsg(AbBd#4;ihK6XLC*{-gye&n5`k`!s?qEu%{mHACIhWSm_j70zu zg=wRFvs=;n}L}uX&s~tA;}!LB4yFUJ#tc zG#CJGfrEt5qD7iyO5n4@($BAHP)xVsJfFqW)YVs?Wr?{A=2O9svd;v-i3;6$)D8BN{&RT1cJ5D&haZmQK9|mfuHyS`b2;tf6)oWh+^!=w z1KZJ|wm5I}HQ)3{0xut5Bl>j>M$Yb&Gu_EVxovN2lgY zQ<7ny`@4yKTuS>GX-fdYX&8_pG|w z@8YZP&|-3{E0ZAD%V#3*Kbu&bh zm*#j27<_t78RVm7|Mu-X!}eG4@rR#X5iKe@Gtg;Qf5SWHg8XTQG6lb1);Uh%snofK5|iOLV_*@Ft)pUig-ID6`$ybBUZZyl>xEJ>Vg! zHp&bL4y|8RuMX?hFr;YhHLJ#)?Dr+1^Bn62x*CmOinz(esd)iupd6Zcj)5{Ew`2_Y zZMVsAzq6z}FP@(GK2vPgVWBQOHe;Hc~?=xc5T72b@EWLS_ zH2(7hz0&*(GKRMThvb>pb$`Miud>fcfSH8sH(pv{VHvZT*=abjBf9ip{WNCUtdduh zw?wdix?&5qnl3j&57PR|b=>6U(Lr&|Kn~0M{my`Xv!37F)CefB?ros1=t3L-4>Y39 zrt}m-#|e4c@be?rBgc-p6Q>Com}uT$6INJ*Nudyka;vxMNwM_a1JQb^51u$-ZVYCO zmB0B>4wdv=lLP^!V=zd#VcVY*XcOkaXk_eVs@F$&MY?9ZJ)tOvkctoX`0z!b;tH@a zR6k637p@th(b3VVE0}{`JYyiP0MP>Lw@)c>WQc<#+$sgw)J7Kdgc}UAE`|hhMKtqy z7HixW4LetKAn}O+OaDFehG``u2j(NG8pNwp9 z+i{dBXaSLzx=7C9B&D+u?3N8j?7+R~(Cwb?x}uu*n}eK(TC4y+E$kRnycZc26^fLg zdzI$4JGkoND>p%gZ_EL=NFmPTtxS7`Ty~*fM zpGU`oYSB8BZVQQtu{*a+eRg=Gn+Y46Z(C7e;O*}2?rrrRkfN^=c1IvtxTOD2{26b0 z?F#Mc0J&ZN9Bl{dk1PK<&n?d?ufFv<(oEl4VXIB|T_L$ZqT#vj@4k5j#J^v}54;|dzWyIfA>(ak>{Z%DfAe@-;SVOQ_V{=d1;-!D5M9!Ns$ zn~(_HOD>=bGxR1uczxoJl|{l$a0@gDC*pLNXjfnL5RW5pLQKk?dk_n`)bJ=PFbNP- zGHlg(j{0k;mAjifyMBDMex8$l1S7{PP5iS0Q9(8;T6d%C4D|Pr=!J zUw*@xhcC17WhZ>u313dZms9ZN6nr@aUrxc7Q}E>!d^rVQPQjN`@Z}VIIR#%%!Ix9; z++HDb3xmrSkZI8+T8<+s^9EY3%KyZ`dy0aLtkv{6Did<*yLXj z5p=QY-$#Bdym5E#x!>NfHbw*o|NGx(x2#|C?#;;95%mS_&3hb!Mgwf*gA#RPKAvI^ zKm3?rd%;4ozGu>;Uta$8qe=h7U%&ij@_c-mjW4sonSn1m;mc0=vJ?K_JOzo}axBGI z^ZE=qBGsfCQFPYGzAmB@f?ClMl$ISSi&Q_^{%S+(%ZRJ&4F_9Ly>JoT$#Nf_YBOxi z@kCqRWUIy_<R~jT4H1KhGwi z$xl<1P*qh^Q}bajW97A>`_sW1P9vbUPksBALaQjSgo9dFmw)50(ut7oHjSF zOH0|~hzg^nsBv3@dJm`j$I68B=V^%OrJnW#Q*&pZov)~#;ooPc+TWPSy~TrF#k>29 zz6$??{S_;(5s5hN$T5~D5+vWXBYbl@L|Mpj4mX)QA$J0&Q=w zTZ)w++iw6V+BW5%B`O39&%?cL#T(`3pc-~DinF9T4yvimCss8|m?%0Lc!bQTz>hf4UJ{jB2 zONnL`IY_JIrHr2+Y@Tn(?%a=OQT~N?f{C%wNE)yF8N27VWRhN;!iM&wD$hV925H3` zDw)?llz3oXIT!hg`XlHg;zfBeCCIil?7xX*7OIG?T*PT}!=0z#Lu-Wc`b5OPx_1~` zz9dE`Nejug4G)Q-w-d4HEl8r_W|k~cC>lyHTzgv}u)aj{HY zQ!sXokkCbeqy@?|HuYA>*@vp0=@Q-ARyT8w5Rfr5u>uU^LL$yjxakFm#d zBGsdIZ{iezapyxZaTV)3wdpe!ieAFj5sYm?shRBH+p9E*2RdqzuTI6M4evv}RdgjO z)1{|CQaRC6>kA}_MJM%*N=YfLZ0NR*fs0cT|(-~gO`q#(MAuB5fIz% z*6l%3-ReSx@sW-Fl<-WcUn;trz?4LV+IcmfJt|llC*lB`3cPcdIIgoQ*oQ34Bef4t zr3~FaUcH$LYqKP1g4XFgh}LxyenHuH*z1eij#oeM6c``KZR+fyl-EOv$F9ZeV^31* zSqi7(f;)XIwP|>tR!?3D;nVE8Tk+1wFU_vV_?Q^o`>?@%Ez>($s~!UK5IK z*MFBFL;X@8zs%_@)YV=|oXEK5JWBl<3rVO4!&In7-!!@+N>l9ocZ;u-1yVXSHrL_k zxI>A;clY{VFAGfhK5d%8kZ(K0?C6d0Ljp8#~i!6O`{zZ&CX&o4RLS>Vx#9 zdeVft&t;`B?F=)_e%CvH%T=+9QD~&%5QHijw?1%ZXCYDM^3}S^^|*DGLu{c zBg&Hup;M&VI8BBo#!<OFiLJ>D$epAx=* zMUQ|O_Qpjh!FSOL|Ev`LqG-Gt3AW`()}Pl#{E{le0uJy0bnBziov_jT$mF*22gj?! zu|o=nDk2W9K9po}D|uB+1(P5@aUM?bs6pytfry^}33Fq3gQ zyBy|Au9)~d{Zu>!`E&aPsu2vU9~^fxnpQh}m$$gSBzEL%FIuG_lhjl&tY#ZMG9mixh z&gfpcKKaLYLb3a-Y~KCE8>?rWW-;*?=I7D2Hmsf*~ zVOO-K8p{qZ;MUjh?)e1>q?Ltwb1Gu*=_L`(R|&LYK)?3=BPE%g#k!D4NN@f2pSB4fHG+d)AyZ)D;+ZuK&+=-Bgz-(TWh^^uoM>Ljk3~=7nz@OZ$Ca z&p$VnspzbaETx+!Zp>I^Pdo&o&JT6&7w=BZPsI?BBpzq|kDz;~Jobv+|JOMJZB`Yp?v4yoO#&|YkyToJ3c z$@$qs*lYiHUXiu*D(~PD*3Sl<&A4tI_Q2-jRX+dh%S->8)DwZ!Q#*!H8#=+B;@P;v z%E{e-lfeJyZlUJjSwql~YY%(joUSbQ;C$M>?T?(ciP}YG<6K?VD;?Y-beK6UY zWuHF8E&wCnjs`#RZ?rv9PYay+u(i-sD0T;L97D)7vELLA{Tt%^CH9M91u|S$LFgPF zzw%tW#NB^QMMca?xvB@p{d*>g#yD3Aucf_=x7KRcGxQZR2rOL;U+cP-Wl4wqkBB z3OrzlG~e#Wg;db&X7+-YTx(^5=}XuYM(OZmOt+Tb++>=A zx!PFXRu;8z2mdKG6$jHN@wrRJQ(Hv|M&!f@Uhy$}8rl;EqwQ}CP$X* zN*pQcJvTQB8jTVm2cJdqvNk6HuykY%QKd&;VC73p))CaNn8Usg>I36PE{YK-DZ21j zJ<_&UJ+P?ti?73IwjkR)p=w^FJ5@2%uTV_+uSf8j{tQLGL3?H6cRf0zc15Ls538Pz zt<6;THQRqp-&EZ}gmv^?v&gkuMJM_i<%$&8TPssek89kDRZ@3|QEy3PvF6W54Rn*^ zzg_oSU#C46)ksGg{9u@(6HNP!#6ZimuI*>gXRAm{48935z(A|`CI+UQcqZtZMYT}z z@<)n;$zs=Vob>~Mbol0%n93H^Ltyx@ID6Z04SF`6h|B%VV^MXI3d52pKHL&Dg?01g z(|#6fm-NZ^-={nF!v=+O5dAT&EjD#-o73>ey-ov?%MD?7y7iIqjT*CSiO%Gvk#o`H z_wD2j#`@~#;JE{Nni*HL1du=;t)DKvHl2z#?J8<6y3}Mp*hrP&_bqCrjhvtatYGS! z#MG0uj`PJa{KzfWZu=}bTveS+BgvERi{Y*-HIo4xv1a>rEVc8BUZ7DUKp&TLs#uj4aeD+3bA@!BCU_*|;O6aVB9!MlB@vf(AdT z7YGEGk9D8@z?%z3HOW?PX2i!4u9IYuG6Xkc-Sp|x=Z+7)neCz#yJWmKG0sWEPtr0l zJ_BcS(Z<6&QAiW|T<(Eo{Sp-9?n)cB#EEMp7O$I*pFLP@HRDC~m1*vP^*OJC^5cm^ZZ>wkiOoWC*V?9$wE}b}FF;INelPx?9&4WfM8nads}7)ANY?l8kkI zEr&?!z)YZ`n?P3)?1BB%1-1&oSUq@z-|>nI70UJ37@ms*pM)3clY(Dv3foEx3HtDh z4t=eHv5shj8UlljNDp2;IIfd(3QOThEUIu!C#siX@G3JG{Wj`p=3hznyOz5cX zU{JNABSRILUXWtBAxa(_W7ojMr3xavS_o#bB+0V=2!IuuX{f&W#C1m9M$oTG`DFrZ zW-E|I7`F+&&4!6Shqz|Iw!1P`hf2(VP*|Z_F6-OX0pIUfVt@DtXfJ|41YAa}o(Cx? z+*P@Cs6l3`_YYDV<-sCg+9>$>M&P53@B;1^v3gPy5MnJetSG{wqVP%Qo%8Xk`)n$J(KkSSfMuD69A*AC(irt^j|6GfY3pv9U7PN#_fM!V7yyVwdPd)q<5a_`+Dw0y&yU~FyTtuw!s|<0hnV2sYTNs>M}lN z_4wP>K5Mp2)G#wULDA$tjiZ zIdm9Dd#L=B_`EhM)brEGmdb#uk)Pl^*^v)Vh!oDcqbzJ+P%;c#V#R*;;v@|;omli# zq?&wQ-7{9!_}B*Trv?S{Bu1m#r?J#`d7j~b9GABXjuvF$62(p`-lowfqf#iJf6Viu z9SB!Ls8$`oNDj==d+V3sgKA>%wDJy-?LnoI?eV$j7Yc$0AaLa$r@BTevi`xRcizz* zIU7s38sUPpjyRI5+ZYG@4x!y7s6kyf{JS3O!IZ^DAqw*!T1 zytJwCB3J+#``fw@GE;#h-A$UccooW(DlML0WJez=o`+nVAu)awT4W*bOjsld^( z4C`*0iw7-`IQH`Ci~G1t^%O|Cth&Ggaee5_*ikb5(?H-+f=WliwZ}sr;6x2P+vhwN z956!7w^^!#gGuGMki{A<#y+Ov;NM+nqk97r=0Wpg%La-RK^|Q>8d^AUNh(_~Z5qkOd%Q zGG{*ox;6XMhrg%gf-WJcs0!$ncIPO@;QFEk2Pfck)lo;e4B*+B(KA>-e%jvQtAOC% zE6Rnbld1V(CGM%Xt$h>ghdEvF^5_?rz})-^W* z)rok$i?!5=yPfbKuE!dIx7D<5aEYMf)E%mFOM3WB8kUD(s@wZwxaapTs8p>qJF95j zl#OH<={zuZgJ9f2>IQnS1WNgm!4TesRjFQ9)BM42${ZwJQ-pEY?y|3 zS=t;>I)2cvuqE3b;;I2==ZL;{5JuVsYC*x-#MPjxU)VApvGG=^Cb+I{NuP2D0y&b~ z$ffpgIx5WCIop=OKV5yaQ>>fx4OE=r_zy0Lsv!t*00!z3#BRj;^>K#00H|j}q%I^f z8VdQ&n1@k3stYLf(7ajLLfo$Xg9D&{)cE@6zU;Rw8@-!5CHVa1bSmTU5{PnG4bhIPJU zM#LqHo~Zq^PcQEvW&^T`>y6&Rq6%#Qb=#$okdT0O11+sZ3w2LyB`pG@Q1k6=5)x(S zY#avf3qpQOeH99r{Bq(s$s zpOO!AfnB!&b>vPNA0foI6$Q%mtmmN_(x(3emS5Wd3O+YXz>M*)AISp?!+)~0li=e} z%)1?yidF3|7x)(tdj@$n)c5^8q>s2+`8t&L^5E!sFh>Do2Sm4H)R5&yPD0iwg)t~f zZ(ftU!Jnz#7EWwEqf(z@V@mWI@$k~pkAbSi16*|yvx(?M^_F_G%}^MyDH#d|9Dx`8 zGJILxzgWW!`*zZ}!Vly97ls8`@6O2G*?Uf4WGM)y{gO={xqe0OO%dGP_nV2?g&bZ& z2He_+f?8qZ&1_|9VcfyT!^YuZQ41*_;-_+y(+7}1kcjxPmqN@SF0UNfK9I!(<1`lpXdhnaQ*7s;iLVo=kSQJYV^enjS8H%{Aa(WD20vm5K2{!m^O`dmX_hX- z)ox~BPDv`t{6L_Ly51?-uyJr;dy-Cpq5UzEDE$dg5fT!5%0R_WZ%YT3Du*D5X$5}V z_Jq?wf=Ikim>7y0L|O#Rek)!dLXVIxfRDheC=)3@0}_Oo!!;bCqZEx*YYQm}!5cn< z7?7|G%?=_q0XM)tvV{VA0inA#s3qAr90g(g@~R}u%!qCXOV8vqgt>?wbGv&fLvlPWIY@o9)oC?s{;u1>_ehTzNF50S{= z#jaN(RhoNWL}HQ9=R*pX7PggLSN6i5^>bLaFR&OAy30I}iz>{Mq*`=pGGPAY?J~d< zb|$o1s{|ntg{-uAq&TG?BO5#{$XOau$Dp!6d`9(9SyO<%25go3=0*ZYr|$cj)q+SL z{*UET4REm$2YQe0CNQ7`^a97eISkaj=JhZyn?fHT>Z0>aSc+awjV9IP!Dc`pRQ;2u!qjkqXa{c)0{) zZvv!Iali&w5vjjq=I|251_Aj*r|kwK+ENqAS^I{8ALt@;vreFZ)^Ug67#f1m(F&%tuRR4g zo<4{?qf&I8=*EJ)1;Fyn7_T0jHC43$kGD#6^N?~1QR2mqft0KHz5*`0y-Qt=(Wq80 zcCF5SaYq^R4RN&r$pT04@;5)y2Gxy-Z0-d$oUyVjvgDv(uyqaD`ronCZ*lK03TrnW zpU9HPcKTC`6DP;rRn^tXY=&TrH_)zE@>tNJKK$HNo_MPY2itH!Twg@et%r~f!wYM- zwykU4KG_Xm54n87jkQ#6V!i=Y>@}}`AYxSjmn)!jv3s=(uw-(5-kqf5vGZJ{ok~5S zxk#nzsxph~P>1f+rWJ+zd7xE_c2-4Xm6Q{}bHXIdFY(NoL)mGRhBqAT1Us(ikN_(@ zn!+gb6>P18aB{pE(c>e6e`Qn?ymG)hgvv4qTwQ07A!}7YuIk_b^$b9M;+``W1So>M z><$wUxT2P5GlXr(FwWowFeGeXY9T{LH)uOknurrD1? zWw_-b!NI{B6S+JG3uBK9w75isz(v6T%8O?6ew3Y1>HmLnK;8o`Gr z+HqttKSDcB;Qv|tfz+zryTNoiLyP#6!!?3uyciz5URjkU}`S2ArL)Yza{{8Q03Xe#G4$p zge{B%xJjmc7Wl&9g1^p8p2EmpRZ%3g?2N96RNpYpdoNi&yC6jj5X9O>axN|ls1F7Z zEOBiwCV+UOFT!rgMn2L!$Y^)WeE9QC{IF`QC^&{L9E5t<-R#HUkXnN4SVF#$AAcvv zUCjhmd#A4rj)m$?tiJ&(rp@VtqG3+rN^VR}f$Uu$EF;DM|?OyhsLx|xu( zo!*hoD(vDve?m}e8IzjYGRRWANAY+13a@b=-upLB0h4TU5Pz9|ldO~OXPgCjf*(S& zIlf%5F6myaxNxy`AQiibXuS&EVR}F*9eg?baP8)%+vMFzuK!n>QLfkYn@<*A$ERL1 zb9%G^KYX|BrnKSJMyPKqL z{Q}AE)(0eK8&Dl2Uf`_&AquC zgC#EpV%Dt>GQa7*i`DQ#Nz#sLf|Djt8xc+Xj@48Sct4AiDdqw;F1J4H6s~r1n=}lK ziDB^c|K5Z-C&xvqB^{3;Kc#`!Knub{_0~V9YzoVGLe%Jx--5%kxD8T~lAi;513^Iw zg(YZ|j^8uH`nM%9nA?B+wsPIzWZ$!#Snc5jL8F2llU*MrELWo zyVd0geRT!&A_TunQglblr6odm2P z#VQ;8&WuK7!sy)wI2$2Dp2Zd9{8BRnbVE8B(eDB`o}m;3#C^#O`7eCbp`aZJfp_X? zWA4tEswJ^PPq9^*<{J5!9esKl)*9^HTL48pvW<=|wpwrvTMA-!@LkHkY&Z*kU0 zF>t1Uyez0&{n;D9o=b}I%)p1}c6ESDglS=iT|4506BG)kqy&3~!sQfxBWwXJb}kO~ zH2WU$1{9hNOEm-`>!!stKgXU+jlu%M%I=)f-0Olhaczyz_y^)a*e8b)N^FlVgY{FwOw(VpIrGFw(p^mQ1>QxmtPDzf_p;HNr1~51}>c>$}UfUt|^pKPSm~#VYor^9X2i^ zB%Au3qMpDLwv37KK8)xyLA!^0Zl-U7@V0{sZv^131g&c}c2LsZBG?V2DkZil`ckh<_7k6)VI!Me3Yl{Wj4Od z2F<|#=}zcA3~Oq?s_NygAjC)CI&O14R#4QEm+Q#DIMCo+ZU1Su*Kj?#NxwNj>DJ8G znJU6efT$~HEhDSuz zN@u+PkU;c>jNqlq$L6$)v>@Ay`EYpMBykbkO}V{LKZi$50Wb|NnbX}04egDrrZ~Yv z!^E_Wh9lOp`zy)nZyYZaOZ)Knj5i12S3l2D?{wR@uSl^Y*-*5k3QpIeO(uIRrU{>e ziq4{>Bg)y-|CNc$LFyxEo*4@MkkY79WJ3%a!D35UeD@M{cgXrafqUb_-jkkCOo>kv zkc$XRfX=@mYj5qfO4y%C37zT+DT&2&{B*3BUZ8#ve-`CmgTyw8=C^zODP)n3}Yzc$%WaJZDSHW8vq|MefDMSq6qEPis`JfYYIBMLMeyx$!rDP zyUi*$)-NlMGhotwI#rE*PEPyTcAPwCpqbXwex|?B*HbX%+OM2GW5%X(xTdc!CBk1M zEZJs*Mg*l%)S-FHrBmG1c`C~N3v(e7VN9cWU>r~%7Gy^oJ2)#*OB8YqjPy889_t?J z8kq;-59^q04@=voO9vx*K7uT-st?2rOFoGLQu83Wm3?+%wYP`(6ur3J;qlJ1`#z`(#g@|e{qJ%+sGP!UrzbChWid)J1F^;h`b{t3cFE3H16L3b5 z3FY5%GH7CusZ4cd$g-GEXb&c72RT)cNK%1A3ddo!PB9`+vKa1)Ns(qOY7mobPs1~>t+0`*pdF#Bm`^zP0dcbLI;u*?^>^k z58?5e0C#q1s4E9BRyw^lgzDvi+~`?4XFoRG&vF6lo58r0Wh9_c$hAr(FwK^G*7~&TJlt9A+0#CmvPVj z+P1a40oZ-o>L++7d5ff)C!c+r%cn=?TQFd78!rhUsuG~# zIQsaz72D9~Py}mHa9FPv4BP~dwrg32wQ7nMv3GT-AXcIg+P~CCe1WB0#x+-5AGa12@CMeAS=13=0{{o`I0?^k-==Ny!nCHJhKfX!-YvBF&L+&Gcyd857p5`G zm#=ru!airyTGAPD`12gY$BmqP@H8+QO2DDnmUC9Yp6h0vk$WVdAzcqz6n3byP2pnve zonk&DTDzgm-@>hf_K$rLJ3Jn_UCcvFh|AM#TM*IkssaM}MWpG8kA}8K=`imnbN(g!XY=Ep%by%X8!uOD1Kvt}bnrp%crrKq@gxB^C&11O^@9H=?qK zAd@&Ez`ma^Cl*Y~X{+%@!)BV8(bb`-t(0}`s)=g0QgDSdcsGN1->z%uuNgp{p&p!} zKx)LU94Zs_2)Hg$Kf4defUP-|wx25O?PX$`rQs?W3h8EHp})>nKq$gS7zlLrfN0&Z zkAczi?|W2Ddi39v?zwT%_JE|7u~XQsjIUkNkVBI{_mWWmzJ8}Hl}tSIlCFYVkYGh| zkGV?V2pT<;*}L%;7>qq7>BjuA2oD(ex_V-li_J!oM@ZB?Ju&#lSjuU*gOwLms;Wl* zcR)r^_nklz`v^D5D9lEW!hO?XWc0kE!sfvd;Oyi7ux>(4cm`3$*5t46;A$v zyHgVqlrqHNTCRlzuHDD}RD#oGSa)+??KkEI@#P~sIW`@uqjRj?Zr!sPUiLI)Es~t; zX^;6%N3Uk(;LPPeyK}-TEg)ym?ucsOD+baxJBK{M!>?N}8w24|ol#cr+w2uZibOi@ z07keEdVQ996NOlC;czdO1(HJTz7Ib?2+|@S;QAL_R1J}cQC@Z9c3yiz`k~`jbhSK0 zJy#3a*1Y^W#w^xdoL50jA~J@U`^spbAOO$?{dADuR*qb7*l~BB2f!ws>uKj0S*F7s z>;w~0`vG||=sTlv&@E@6;u+!V7W6LViF&|9sk0}F%G*P(X`m{hSSjNW3hssuUR#du z#U(nm+!)s@;sgbJ7Zd(3LHtHR%(N{J2QW?3eMq6APzFHy#IJ2qvhp;GCGMz*+Fd>V zZU>5J%b3}Ig5v;H4P_Rr6S%&K_YHF-vMrQPaij-ui3sTk?jjFYx!hQX*moUD72dLw zKymY@(iLF5_vvS>=jY>oP+CbXeI9!!Y=kwws}~#$GcF{T}uML~0^gBWE<8@Bum z5o5I=i^afB+~zOwDr1VK1U%Y{t?!j}YQ9iG>&5bdXq(3o6qE%cP~qoFUYOfHSGnW7 zctHAKkmv@IN644hcQ~3f(GUiLb_YQ#lKRAm^~+iLUnF2 zuJz(&o{yYb^g#LB&z~FKe{=H4_VN+}lCt$X%j4Qw!if*|^(`?zK}=RnW{$IP7G z#6Ff21Ok67FMLKd#k>9bM2DH~0)2vtRjN#ahK}pf z`U*+HFTVrXhR?+1kuP_Nh!q}P?R5n}HY3uvK@29(`Ro-UC+KqcY?E=rvse=RxZkaK|>b6_Gmn%sp8WeE{!_iK%MsV*nTj$hVW zDL@yt$1prD@8gc0Isqi2+a9KD><%*0s(61;ngb2Dqw~p*O070#T1hV4&F-VXvjhO z_o}d=T4*?G^=@hE8OLC{jJHwG9b49(;)ex{d4x0?ST_m?lScd}RU81?4He$8%}`;C z>H6t7M~Sp0W>XPa^Z3O@m^F}p#Jw#G|O-bzNFm)H&y(-8J4V%;F_7frx{w%B_B3v9HGSko{sf61It73PPd_= zcKUgBUMx}}SsEHVTpZq@Zz{mX$D%TWt=QXhrA=-e5P9N>wXL@XzQV}lT_ngM9$6RH zX?2!dn}3rrHaD$8Ra$e3e##v9Y$Gx(Ed&;w2fOAJ8xl^m@of1qATBYc5#-!tZhHz< zxVCWnDNK7y9Nqwu3-!^Yri18phV@8S!F^*Tb-hY@E4W&S_)vIe%!h!@ajcRay&Mqcao*e>j+d?0=E_q!~A?21LK% zn=bRVoBc_M>MCUFY88gHB#wL2r8a?$mHQk`q)IH7%Kc%P%RS`U?4O=i*i^{G)JG#j zno1?8x0Xxnv}U83YlAp0D*Xc5faa8#&Iv}HiJ1*?+?=FcPUBe9U%t<k$u&X>Vx0XRlW6RshkOgU?N5~rx!tG)TbB`q8-L)F>{ z^F}*yhpph~_CrN(ueP^rvDGuLByPp-NRShD@>=H3d<2cpMA(9&!q&CFy0^$!|Kls@ zbsZWUtG8p}{XEowrqT!)nW0ZJluWob@h<1J2+Q&S>l}yuGr>_b;!7 z1xUQQ1#kZ0)DQc79s-nS!(~_e2({e%E?E3yRTB&it@`d^#wwkyez{z^=1Vlzw^#iN z+?K8M#ZIqAJkgShYFl|{C6GgHg-gF{b@za^1ouSi?u`1y zWp-=LE9qyJs$N2L=ww#^d8S($I&G(bo41e=3R6`Om}o0-Up5XJJUHA2gxOm|h=g{hK&>Cx*H(t-$Yu=BfDXw3Dcw4!&< z3cwVHn-t$cpok~2WY3Bg+X6`|F)})6r7C3pt+dZM`+?WCSK4b0hnRr4j-bre)@)gD z4`l&a@ca(cs@y?4>3+5Tu|cBJvbt_5OR;GTb0^ z5yW*e1?6_&3@p0pXg>@RLe|q866n6IGksRbsXNsBl(r^WDP<_Hqmo-;TF9jlb-5&b z5nB)^vxu9@gEh+I_Eme2F5LNU3sGl;Iq4n-zBKF zf{M*w4S#HnUVAHG&vkcJq0j2H+HtXV3t`#(M}UFWjWm5WC-K%C+xkwUro1#H%v$y9o5Wg8J*-AXFTG*iPd@74P_4W0q=Z~WqhsqW5dfZu zP2zLcQ+72x7!O?UWYR;<2no3g-{s2NeKU?KMB8omXkdRDD3tf6P-afYMm`!!j^IHS zK!N5EHzUOb>4t7{mxLjM23g>Mdww$)pPMzRt^##o`~ywpNb@*_>vgDv>>n%dANTjL zbkh_s`57Ry1s+^J+QP@Q9LXE#oHeM{>5B1Mzh=28eN;efHyUnZ_b)xN@%RNc!wKmE zFh2LE@7M}JGJ&c`zY0OdsADpB(lZmAm1WgpeDplKoY!HD z(m`uyqL4i~+iwrcDt4wE4M*1@s#k5aB*x8EE>{U8!()-Z2Nl9VWk=*h-1Q@|D=uzG zFoqD*RUEP}E;iFY&8x+Am&I%2rg0@P6>b=}I0)ftvBQe$>zc0n2m{=&tE*7S0s;j8 zN`rCcNw}f%AAyh21$a@sntBS6=!f@?-!kjOpUiMZV;gj}0(Z;R?kH~-BuHRbo*(kX zvYJj$7sS-|;lCGq>W0P#b@$7p2-u_PujWVs)LirF59P*O3qThF_y>SRKyv7cB>w55 zXLc4nw7wKx(|;zYsvN|u66|SRDADtQ#e|3XYu(u`YQi~@cJQ;k(o|l5^Tbf02zYW}>d^sz<}CDZ zTQ+Lmw7Y+q^zzY1mp{FF<>9V4scxQh@Q_PUkED;|Mu&Ve>HcryMs2fB{mo^-M>ZQh zz8kP?u>GJ9KAJqhzC?8-rcv_E^E-<@-P3OHqog0}UyDU%e|W{TR(>V9N&| zery4i@;#GyTmbnmzD1Q6N1==kZOiWfhIn!7VByDlRnp53K3SBPm#6mK9}0KJ=71z? zx5&Pt5eX_gph@%`vVn4o6hr%(E)QQ*^FP{44#J`|b{jU$8fsn^em2$hb+tGy>*%u| zhef+;UTs+sPErrU;i9}Zz`^7eH3OAcZU;W26Yip0khL<;#6nARNZ|)7impTN*iqatZ+TAMUH09%+TH-ng_B~t&yEqBlJ=%(jfyXDf zFKzoqGR=jZsdj+!nOvR+-YZNR$r^REI3*zUJaKW|mXBP(+1A3feU^ueG6E?ibY`~M}p*)HG-M5mfbg zgp$a$v5{x1m64HQ+m!9yT=N3r(g~|mFU@g8v6`LR0f>BM*wy7w5T)hr@$vn$+$XJl zEJeQBFa_f;-PVd^{Q_XBIBy4{emtw=KTwZ%@WCBM>&gCwqlKn=2A)j zXCkk0)s9q_;VL(y>oX;Qfdb(Wsf8uxop0eCxnv{ZD}QqHXZn!F2Q0?_{_ES2oy)pL ze(f7D3NgnjC?per2iL;Nq*=6*A_9flb9Po(M|YX8qY_HS#Q|&lbq&D9BZvjIFZ$gf6c;=xbDaDQ80w`7u8S62L90`C#d2CD z@@Ln&r~7Iuo-10L9uLJ}y6rWQbf|!52|Lyfhw(uO01cv{k+yU~NgNhUO})M}8_PHO zE3QW;D-!LE1zZ!@f|O!=f2_?fYPBOiMhFgK0kH1j9PfYuwljtUTbT~8$BK>)`t68h z-K&5K+dyiU=n%O)CT=yTTBqzRv-lN|JryS425i{U)ZH%h87-OSsNyDDP`ug_HhpJj zhL#KZf7Hr0nHpfng$b~$eGOv6roLME3BPUlzl)7F=PA0KTkcqGG?K>s0lBs##QKrMGHpsAc&&2 zdjZuaSBIlq{Y2t2Srw6qx6j_4(I&7Cpi0W+t+loF2Auw_y1yz+tv#Z*cF{7Kj5uzh;9)||WLq?e+*-}Axu`OR!e5ZEUB>%T z7-m$I0QUd#pJsw$V_)I>Q=h~+Nltzs7t2yV347XQ_?#Fi-1B3jEB^S$T&rvjUC8a= zXxHj^lfut3qhS8fjdEN@n?_0+<~4+rl&oLHN-L0~GuLm~H5MV^2;Azs|Och5xempb7fS^K>|NJbxjKI{v`G#4q64y22+bS)kHSc&+Y zfh|xKOg}$c{!t*?Kl0{rn{997$P#~EI%~zc=~?kJ;A}05fYYGG{;lkGCzg`2by9!#5{d>Yyeg1|y7}mf0cb|3n z`-pAFE|w$pOceO}D5l+1buegqfDY%t<#r%wFK_TdamTSJ+7g=W#w%^LXh3;cc`d1U z5BLo_4Rs^e+7}G-`rfG%w|I%VnDkhqnb^?W+&sAp`bd`@{ujK{0>^2#W}-q{`mXcD zCuEB=Vy*|}eB_Nb#YGA+#~Jk8It|^@Ae;Y7aV6;V2P%ji;AgsUD(&|(RgQU~s$XQF z_d|WdRMQICbT_(NA+l_(0=*OH%F)+&cuN#jaSdn(ojTEcELLQZZ~{Jh|Ir%-=T5D1 z1g|^4&h@yf`k!ft&YtGxB!UQ-oSN1VK&1%hP|Y%hdi&FCKVKX=7ipn7q&wQy_h`jM zB1bQvZv|i~3KLNGo6-3lDhsh{@eI&OVcPCkW~mqEnS>(79GjR669QnMBYHdE&CRXQ ztjG&eW6OmL7e=Y)RILJ9KQ{$#cqQiicktzQj1~sbEN5ye*bWP7dOy2oEu!+ zfyW(nw;jh|b}C2CHUrc^{(_;pWx|S^8MtP_@QxeG{TE6cJUl!KDU5~0D6Ut1v(J4y zv`z-E&!Z0)im5rk+Eh-9dV2Mc1eVJme$ zs1ZVag|Hy9?GgKmM6xGTPdI8i$^%_5ER7jXdI(7HOx;Rn^uUCB3kd9@tI!fHx%;Dk z0O?T9_258qpo@1FZ1hA7B0s??!;!8_uw0z1!~TwSel2Bmwd9%#gAwrN6Rc%PzPK

AJ)@zSs>f-%X(@r z(QN$-VMmA=PJ3^F4n*L8IX47nVo~Kw6aje{?xs!L;54A`ve&JpKbPFx9w0c!@g2!w zQsaDo@XB?-IzcfTz~l3)cN4~v#BEpNyPqF4Kn*ZQ8!U&%e%YT{^wk2vJB_1~jLVRl zf@&l7pF>09E74DJ%zgLeB)YxdH)+kaN$gX}dbyOxhoS}_BTY)L32IX~YQ98rymaBv zy@C|Kji-QDgBl(Z=n8>|{o+cSZT`4BvmlHb-_m`->0`#xeZB8pU*US*_;G{gUHdZO zafqgio;`cULC9xO`0*~8NE#u4qm%sWs_k@i` zk2heH<-4=6q~uW1r0Wy9FiaubX9Mm>Gv;%@70c8d9{JF#{@!^GAI}FLDQ-S&iIwMI z8IoQ%xwPNx?>~T@H-3-+XFtSpfq3Q$0n$4x=2xd}(dFMjNfcT^@vH4;# z9{>1>6A!_5Jto=>MCb(Q&@q0;!E903?|7fhxI3ZtF?d0kFA#7LcX3Q>Jw7j=IMPSq zEHBI}%tu$I&A~T-w&vj;kN*1WYsGJfdQna$51``&J)fq>awXdLSIc1@7VLu|JsW}$ zv~boM2M5k~vm|JL4A+WXKWRvqya$4~4n#6|i1Q-|m1ogJ&Jh=o5lATxA#}{cYaeB9t`R@IOzsK5H>u}9X5Gnu>$GieZ}$M8 zx6(~Q3p$h_&UoN~bu_xAV~kEMK-0B^Suv#aOT?x_RaI5QAP_c2QglF`aJm241`d)y z?)P^3ZOWPu$Z&^4S1J$*8Nese$R^qnL2Uw_Y15-iuTe_q z(L4lrVQh2}4i|35JR)Kl{P=7=QA){6Cry|zs9UGG&+7dP@`QqF24eOQR402lviy8f z1=N|GrpO5Kv~ipSji}?^=6RfcgC;OCEt>c^u*`W7AjUs1Ky5%4kbO-Su7NyShX0-n z7}cjXZrf-XMu;O?XV?-u30)jL-7jR~0G1wAZ}2MCS(!_c6zFRyKO`4Xm|#DW;4b{K zqd9RgMDl0^KK|j?bN=Xa3Q5HC!y8&!7%jY(BTq4#<5+kGI^m^@y1TmR4<1y>XpQGt z{P8#3ZOS$QPglv}tv_ipo{CxyQF^H`JTUd`W?;IUpVZ7bU=uqFy*O?Q4&PcFy~J>z zdQY&-`8Yt4$z4bm9EnJ~oXND>c$im*Q8oGO`SX=US)Dgi{9YMNnsk_VF(B#KO8#Gi zh75`DO+-#@25iUX;=ai>&~R?`-Nna&FMC^p1sn@dgOm}B&&w4J@jG_`=5fYNWoFtG z<@tX6}jxsH%W`D%$FTOS;1u1R=PXqM6zz=4ia97BWF@nRLGiI=iJqdvUFXQEGgw$cCuB9QI0_pGXzuMRC z8k)E%JbP5;#aG1xH1I&DSAe@W+Su5*U!|=Bs%t0suQ<7qhMLx*&m*5#%=Sjp)~M7m zIWtOD4vNVMEcaxbBH~TwpM#JZjjO*pHmO^|J-5f|4&B!rpeF+CLd67S?l=cQY(6vG z@xp33e*ua-qj0!|S$jC_EVFg<`EZ2BF-_*kzffnc@qr*no1+H`Pz2Yg#2P=20fz70 zT5iTM!YJ7eiGe7yBKQKxMVRk}Gbqd{ALg6Jgw%w4Hy@zuYim9dFpL8xK=hiil9}S3 zsbOO0I9(nen*r%)`vnC_kd9H!PoGV?ed8CM6?h`T$_ZqqBPdHP5huv~Q-DXCFG7JO z$Yhg_j~_QYshFM4jJeK79@d#Xe?G;kjKiUly1F_cwV{#@1{hO7Jyow760t@bAvQ2Z z2K~Wje+cLNTm7L39WfX67G8cynLX`c7xIAevRVM%)^RTtRNnRL6vOE`(sWYjmQ(nJ$a~2_!!-QVo z#&M9wU8pCapptg2Qy;CX=*HQ9i|cJVyPp$`48d*ppZ5Nt`=3Yu)3OxYOO*8f&2I3Wkjw?8U=+|J{16-T>A6Z*KqR7Q+AjK)nw~_~(D0(7!zn t(SOg-zdw)v-m-sx9{(TW&~42Jx7zxJzxCM#Gc*Rq&s$=VIOm6-{ue~m!&d+R diff --git a/docs/source/_static/recipes/__init__.py b/docs/source/_static/recipes/__init__.py new file mode 100644 index 00000000..f64af63c --- /dev/null +++ b/docs/source/_static/recipes/__init__.py @@ -0,0 +1 @@ +"""Copiable code for recipes.""" diff --git a/docs/source/_static/recipes/descr_from_trj.py b/docs/source/_static/recipes/descr_from_trj.py new file mode 100644 index 00000000..01cba368 --- /dev/null +++ b/docs/source/_static/recipes/descr_from_trj.py @@ -0,0 +1,50 @@ +"""Copiable code from Recipe #1.""" + +from pathlib import Path + +from dynsight.trajectory import Trj + + +def main() -> None: + """Code from the Recipe #1.""" + # Loading an example trajectory + files_path = Path("../tests/systems/") + trj = Trj.init_from_xtc( + traj_file=files_path / "balls_7_nvt.xtc", + topo_file=files_path / "balls_7_nvt.gro", + ) + + _ = trj.get_soap( + r_cut=2.0, # cutoff radius for neighbors list + n_max=4, # n_max SOAP parameter + l_max=4, # l_max SOAP parameter + selection="all", # compute on a selection of particles + centers="all", # compute for a selection of centers + respect_pbc=False, # consider PBC + n_core=1, # use multiprocessing to speed up calculations + ) + + # Loading an example trajectory + files_path = Path("../tests/systems/") + trj = Trj.init_from_xtc( + traj_file=files_path / "balls_7_nvt.xtc", + topo_file=files_path / "balls_7_nvt.gro", + ) + + # Computing number of neighbors from scratch + neigcounts, n_neig = trj.get_coord_number( + r_cut=2.0, # cutoff radius for neighbors list + selection="all", # compute on a selection of particles + neigcounts=None, # it will be computed and returned + ) + + # Now for LENS we already have neigcounts + _, lens = trj.get_lens( + r_cut=2.0, # cutoff radius for neighbors list + selection="all", # compute on a selection of particles + neigcounts=neigcounts, # no need to compute it again + ) + + +if __name__ == "__main__": + main() diff --git a/docs/source/_static/recipes/info_gain.py b/docs/source/_static/recipes/info_gain.py new file mode 100644 index 00000000..873839a0 --- /dev/null +++ b/docs/source/_static/recipes/info_gain.py @@ -0,0 +1,179 @@ +"""Copiable code from Recipe #3.""" + +from __future__ import annotations + +from pathlib import Path +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from numpy.typing import NDArray + +import matplotlib.pyplot as plt +import numpy as np + +import dynsight + + +def info_gain_with_onion( + delta_t_list: NDArray[np.int64] | list[int], + data: NDArray[np.float64], + n_bins: int = 40, +) -> tuple[ + NDArray[np.int64], + NDArray[np.float64], + NDArray[np.float64], + NDArray[np.float64], + float, +]: + """Performs full information gain analysis with Onion clustering.""" + data_range = (np.min(data), np.max(data)) + + n_clusters = np.zeros(len(delta_t_list), dtype=int) + clusters_frac = [] + info_gain = np.zeros(len(delta_t_list)) + clusters_entr = [] + + for i, delta_t in enumerate(delta_t_list): + state_list, labels = dynsight.onion.onion_uni_smooth( + data, + delta_t=delta_t, + ) + + n_clusters[i] = len(state_list) + tmp_frac = [0.0] + [state.perc for state in state_list] + tmp_frac[0] = 1.0 - np.sum(tmp_frac) + clusters_frac.append(tmp_frac) + + flat_data = data.flatten() + flat_labels = labels.flatten() + info_gain[i], _, h_0, _ = dynsight.analysis.compute_entropy_gain( + flat_data, + flat_labels, + n_bins=n_bins, + ) + + tmp_entr = [] + label_list = np.unique(labels) + if label_list[0] != -1: + tmp_entr.append(-1.0) + + for _, lab in enumerate(label_list): + mask = labels == lab + selected_points = data[mask] + tmp_entr.append( + dynsight.analysis.compute_shannon( + selected_points, + data_range, + n_bins=n_bins, + ) + ) + clusters_entr.append(tmp_entr) + + max_n_envs = np.max([len(elem) for elem in clusters_entr]) + for i, elem in enumerate(clusters_entr): + while len(elem) < max_n_envs: + elem.append(-1.0) + clusters_frac[i].append(0.0) + + cl_frac = np.array(clusters_frac, dtype=float) + cl_entr = np.array(clusters_entr) + + return n_clusters, cl_frac, info_gain, cl_entr, h_0 + + +def plot_info_results( + delta_t_list: NDArray[np.int64] | list[int], + cl_frac: NDArray[np.float64], + cl_entr: NDArray[np.float64], + h_0: float, + file_path: Path, +) -> None: + """Plot information gain as a function of ∆t.""" + frac = cl_frac.T + entr = cl_entr.T + s_list = [] + for i, st_fr in enumerate(frac): + s_list.append(st_fr * entr[i]) + s_cumul = [s_list[0]] + for _, tmp_s in enumerate(s_list[1:]): + s_cumul.append(s_cumul[-1] + tmp_s) + + fig, ax = plt.subplots() + + i_0 = (1 - h_0) * np.ones(len(delta_t_list)) + ax.plot(delta_t_list, i_0, ls="--", c="black", marker="") # I_0 + ax.fill_between( + delta_t_list, + 1, + 1 - s_cumul[0], + alpha=0.5, + ) + for i, tmp_s in enumerate(s_cumul[1:]): + ax.fill_between( + delta_t_list, + 1 - s_cumul[i], + 1 - tmp_s, + alpha=0.5, + ) + ax.fill_between( + delta_t_list, + 1 - s_cumul[-1], + 1 - h_0, + color="gainsboro", + ) + ax.plot( + delta_t_list, + 1 - s_cumul[-1], + c="black", + marker="", + ) # I_clust + + ax.set_ylim(0.0, 1.0) + ax.set_xlabel(r"Time resolution $\Delta t$") + ax.set_ylabel(r"Information $I$") + ax.set_xscale("log") + + fig.savefig(file_path, dpi=600) + plt.close() + + +def main() -> None: + """Copiable code from Recipe #3.""" + rng = np.random.default_rng(1234) + + n_atoms = 10 + num_blocks = 10 + block_size = 100 + sigma = 0.1 + + # Generate the array + tmp_data = [ + np.concatenate( + [ + rng.normal(loc=(i % 2), scale=sigma, size=block_size) + for i in range(num_blocks) + ] + ) + for _ in range(n_atoms) + ] + data = np.array(tmp_data) + + _, n_frames = data.shape + delta_t_list = np.unique(np.geomspace(2, n_frames, 10, dtype=int)) + + n_cl, cl_frac, info_gain, cl_entr, h_0 = info_gain_with_onion( + delta_t_list, + data, + ) + + plot_info_results( + delta_t_list, + cl_frac, + cl_entr, + h_0, + Path("./source/_static/info_plot.png"), + ) + + +if __name__ == "__main__": + main() diff --git a/docs/source/_static/recipes/soap_dim_red.py b/docs/source/_static/recipes/soap_dim_red.py new file mode 100644 index 00000000..b93d6314 --- /dev/null +++ b/docs/source/_static/recipes/soap_dim_red.py @@ -0,0 +1,179 @@ +"""Copiable code from Recipe #2.""" + +from __future__ import annotations + +from pathlib import Path + +from sklearn.decomposition import PCA + +import dynsight +from dynsight.trajectory import Insight, Trj +from dynsight.utilities import load_or_compute_soap + + +def compute_soap_pca( + trj: Trj, + r_cut: float, + n_max: int, + l_max: int, + n_components: int, + soap_path: Path | None = None, + pca_path: Path | None = None, + selection: str = "all", + centers: str = "all", + respect_pbc: bool = True, + n_core: int = 1, +) -> Insight: + """Computes the PCA of SOAP on a Trajectory.""" + if pca_path is not None and pca_path.exists(): + return Insight.load_from_json(pca_path) + + soap = load_or_compute_soap( + trj=trj, + r_cut=r_cut, + n_max=n_max, + l_max=l_max, + selection=selection, + centers=centers, + respect_pbc=respect_pbc, + n_core=n_core, + soap_path=soap_path, + ) + + n_atom, n_frames, n_dims = soap.dataset.shape + reshaped_soap = soap.dataset.reshape(n_atom * n_frames, n_dims) + pca = PCA(n_components=n_components) + transformed_soap = pca.fit_transform(reshaped_soap) + pca_ds = transformed_soap.reshape(n_atom, n_frames, -1) + + soap_pca = Insight(pca_ds, meta=soap.meta.copy()) + + if pca_path is not None: + soap_pca.dump_to_json(pca_path) + + return soap_pca + + +def compute_soap_tica( + trj: Trj, + r_cut: float, + n_max: int, + l_max: int, + lag_time: int, + tica_dim: int, + soap_path: Path | None = None, + tica_path: Path | None = None, + selection: str = "all", + centers: str = "all", + respect_pbc: bool = True, + n_core: int = 1, +) -> Insight: + """Computes the tICA of SOAP on a Trajectory.""" + if tica_path is not None and tica_path.exists(): + return Insight.load_from_json(tica_path) + + soap = load_or_compute_soap( + trj=trj, + r_cut=r_cut, + n_max=n_max, + l_max=l_max, + selection=selection, + centers=centers, + respect_pbc=respect_pbc, + n_core=n_core, + soap_path=soap_path, + ) + + rel_times, _, tica_ds = dynsight.tica.many_body_tica( + soap.dataset, + lag_time=lag_time, + tica_dim=tica_dim, + ) + + meta = soap.meta.copy() + meta.update( + { + "lag_time": lag_time, + "rel_times": rel_times, + } + ) + soap_tica = Insight(tica_ds, meta=meta) + + if tica_path is not None: + soap_tica.dump_to_json(tica_path) + + return soap_tica + + +def compute_timesoap( + trj: Trj, + r_cut: float, + n_max: int, + l_max: int, + delay: int = 1, + soap_path: Path | None = None, + tsoap_path: Path | None = None, + selection: str = "all", + centers: str = "all", + respect_pbc: bool = True, + n_core: int = 1, +) -> Insight: + """Computes timeSOAP on a Trajectory.""" + if tsoap_path is not None and tsoap_path.exists(): + return Insight.load_from_json(tsoap_path) + + soap = load_or_compute_soap( + trj=trj, + r_cut=r_cut, + n_max=n_max, + l_max=l_max, + selection=selection, + centers=centers, + respect_pbc=respect_pbc, + n_core=n_core, + soap_path=soap_path, + ) + + tsoap = soap.get_angular_velocity(delay=delay) + + if tsoap_path is not None: + tsoap.dump_to_json(tsoap_path) + + return tsoap + + +def main() -> None: + """Copiable code from Recipe #2.""" + files_path = Path("../tests/systems/") + trj = Trj.init_from_xtc( + traj_file=files_path / "balls_7_nvt.xtc", + topo_file=files_path / "balls_7_nvt.gro", + ) + + _ = compute_soap_pca( + trj=trj, + r_cut=2.0, + n_max=4, + l_max=4, + n_components=1, + ) + + _ = compute_soap_tica( + trj=trj, + r_cut=10.0, + n_max=4, + l_max=4, + lag_time=10, + tica_dim=1, + ) + + _ = compute_timesoap( + trj=trj, + r_cut=10.0, + n_max=4, + l_max=4, + ) + + +if __name__ == "__main__": + main() diff --git a/docs/source/descr_from_trj.rst b/docs/source/descr_from_trj.rst index 51532a2d..b7d21716 100644 --- a/docs/source/descr_from_trj.rst +++ b/docs/source/descr_from_trj.rst @@ -93,6 +93,10 @@ trajectory (removing the last frame). The easiest way to do this is: trajslice = slice(0, -1, 1) shorter_trj = trj.with_slice(trajslice=trajslice) +.. raw:: html + + ⬇️ Download Python Script + .. testcode:: recipe1-test :hide: diff --git a/docs/source/info_gain.rst b/docs/source/info_gain.rst index 442a0a8d..44b1d2f2 100644 --- a/docs/source/info_gain.rst +++ b/docs/source/info_gain.rst @@ -31,6 +31,8 @@ Let's start by creating a the synthetic dataset: .. testcode:: recipe3-test + rng = np.random.default_rng(1234) + # Parameters n_atoms = 10 num_blocks = 10 @@ -38,12 +40,15 @@ Let's start by creating a the synthetic dataset: sigma = 0.1 # Generate the array - tmp_data = [] - for _ in range(n_atoms): - tmp_data.append(np.concatenate([ - np.random.normal(loc=(i % 2), scale=sigma, size=block_size) - for i in range(num_blocks) - ])) + tmp_data = [ + np.concatenate( + [ + rng.normal(loc=(i % 2), scale=sigma, size=block_size) + for i in range(num_blocks) + ] + ) + for _ in range(n_atoms) + ] data = np.array(tmp_data) @@ -87,9 +92,7 @@ Additionally, the (float) dataset Shannon entropy is returned. ) n_clusters[i] = len(state_list) - tmp_frac = [0.0] - for state in state_list: - tmp_frac.append(state.perc) + tmp_frac = [0.0] + [state.perc for state in state_list] tmp_frac[0] = 1.0 - np.sum(tmp_frac) clusters_frac.append(tmp_frac) @@ -158,7 +161,7 @@ values. for i, st_fr in enumerate(frac): s_list.append(st_fr * entr[i]) s_cumul = [s_list[0]] - for i, tmp_s in enumerate(s_list[1:]): + for _, tmp_s in enumerate(s_list[1:]): s_cumul.append(s_cumul[-1] + tmp_s) fig, ax = plt.subplots() @@ -216,7 +219,12 @@ gain goes to 0. .. image:: _static/info_plot.png + +.. raw:: html + + ⬇️ Download Python Script + .. testcode:: recipe3-test :hide: - assert np.isclose(info_gain[0], 0.1899727144974609) + assert np.isclose(info_gain[0], 0.19043795503255656) diff --git a/docs/source/soap_dim_red.rst b/docs/source/soap_dim_red.rst index 8f1c3cc0..c230b678 100644 --- a/docs/source/soap_dim_red.rst +++ b/docs/source/soap_dim_red.rst @@ -267,6 +267,10 @@ trajectory (removing the last frame). The easiest way to do this is: trajslice = slice(0, -1, 1) shorter_trj = trj.with_slice(trajslice=trajslice) +.. raw:: html + + ⬇️ Download Python Script + .. testcode:: recipe2-test :hide: From 1a439e8b7dd0adbd3bb5146e2916dc7d2536fc93 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Thu, 17 Jul 2025 15:39:33 +0200 Subject: [PATCH 40/42] Removing useless mypy stuff. --- docs/source/_static/recipes/__init__.py | 1 - examples/{info_gain.py => info_gain_example.py} | 0 justfile | 2 +- 3 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 docs/source/_static/recipes/__init__.py rename examples/{info_gain.py => info_gain_example.py} (100%) diff --git a/docs/source/_static/recipes/__init__.py b/docs/source/_static/recipes/__init__.py deleted file mode 100644 index f64af63c..00000000 --- a/docs/source/_static/recipes/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Copiable code for recipes.""" diff --git a/examples/info_gain.py b/examples/info_gain_example.py similarity index 100% rename from examples/info_gain.py rename to examples/info_gain_example.py diff --git a/justfile b/justfile index 4a1b28f9..9269edd3 100644 --- a/justfile +++ b/justfile @@ -26,7 +26,7 @@ check: ( set -x; ruff format --check . ) echo - ( set -x; mypy . --exclude 'docs/build' ) + ( set -x; mypy . ) echo ( set -x; pytest --cov=src --cov-report term-missing ) From d41e46f17ffc748214b01d9f5aa0072131937dc4 Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Thu, 17 Jul 2025 15:48:08 +0200 Subject: [PATCH 41/42] Solving mypy issue. --- docs/source/_static/recipe_scripts/__init__.py | 1 + .../source/_static/{recipes => recipe_scripts}/descr_from_trj.py | 0 docs/source/_static/{recipes => recipe_scripts}/info_gain.py | 0 docs/source/_static/{recipes => recipe_scripts}/soap_dim_red.py | 0 4 files changed, 1 insertion(+) create mode 100644 docs/source/_static/recipe_scripts/__init__.py rename docs/source/_static/{recipes => recipe_scripts}/descr_from_trj.py (100%) rename docs/source/_static/{recipes => recipe_scripts}/info_gain.py (100%) rename docs/source/_static/{recipes => recipe_scripts}/soap_dim_red.py (100%) diff --git a/docs/source/_static/recipe_scripts/__init__.py b/docs/source/_static/recipe_scripts/__init__.py new file mode 100644 index 00000000..4121ce73 --- /dev/null +++ b/docs/source/_static/recipe_scripts/__init__.py @@ -0,0 +1 @@ +"""Copyable code for the recipes.""" diff --git a/docs/source/_static/recipes/descr_from_trj.py b/docs/source/_static/recipe_scripts/descr_from_trj.py similarity index 100% rename from docs/source/_static/recipes/descr_from_trj.py rename to docs/source/_static/recipe_scripts/descr_from_trj.py diff --git a/docs/source/_static/recipes/info_gain.py b/docs/source/_static/recipe_scripts/info_gain.py similarity index 100% rename from docs/source/_static/recipes/info_gain.py rename to docs/source/_static/recipe_scripts/info_gain.py diff --git a/docs/source/_static/recipes/soap_dim_red.py b/docs/source/_static/recipe_scripts/soap_dim_red.py similarity index 100% rename from docs/source/_static/recipes/soap_dim_red.py rename to docs/source/_static/recipe_scripts/soap_dim_red.py From 36f52f2663f23b373b7a785c011ccf3c0f6177fe Mon Sep 17 00:00:00 2001 From: Matteo Becchi Date: Thu, 17 Jul 2025 15:55:38 +0200 Subject: [PATCH 42/42] Solving mypy issue for real. --- docs/source/_static/{recipe_scripts => recipes}/__init__.py | 0 .../source/_static/{recipe_scripts => recipes}/descr_from_trj.py | 0 docs/source/_static/{recipe_scripts => recipes}/info_gain.py | 0 docs/source/_static/{recipe_scripts => recipes}/soap_dim_red.py | 0 pyproject.toml | 1 + 5 files changed, 1 insertion(+) rename docs/source/_static/{recipe_scripts => recipes}/__init__.py (100%) rename docs/source/_static/{recipe_scripts => recipes}/descr_from_trj.py (100%) rename docs/source/_static/{recipe_scripts => recipes}/info_gain.py (100%) rename docs/source/_static/{recipe_scripts => recipes}/soap_dim_red.py (100%) diff --git a/docs/source/_static/recipe_scripts/__init__.py b/docs/source/_static/recipes/__init__.py similarity index 100% rename from docs/source/_static/recipe_scripts/__init__.py rename to docs/source/_static/recipes/__init__.py diff --git a/docs/source/_static/recipe_scripts/descr_from_trj.py b/docs/source/_static/recipes/descr_from_trj.py similarity index 100% rename from docs/source/_static/recipe_scripts/descr_from_trj.py rename to docs/source/_static/recipes/descr_from_trj.py diff --git a/docs/source/_static/recipe_scripts/info_gain.py b/docs/source/_static/recipes/info_gain.py similarity index 100% rename from docs/source/_static/recipe_scripts/info_gain.py rename to docs/source/_static/recipes/info_gain.py diff --git a/docs/source/_static/recipe_scripts/soap_dim_red.py b/docs/source/_static/recipes/soap_dim_red.py similarity index 100% rename from docs/source/_static/recipe_scripts/soap_dim_red.py rename to docs/source/_static/recipes/soap_dim_red.py diff --git a/pyproject.toml b/pyproject.toml index c9f7f3ba..801d3f0d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -92,6 +92,7 @@ check_untyped_defs = true disallow_untyped_decorators = true warn_unreachable = true disallow_any_generics = true +exclude = 'docs/build/html/_static' [[tool.mypy.overrides]] module = [