From 231e2fc6f719494c8ecdf6c70a6d7b695322d71b Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Fri, 17 May 2024 09:38:42 -0600 Subject: [PATCH 01/81] improve save_to_folder docstring --- src/spikeinterface/core/base.py | 71 ++++++++++++------- .../extractors/tests/common_tests.py | 1 - 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/spikeinterface/core/base.py b/src/spikeinterface/core/base.py index d9c39e6ebd..2f9cd90678 100644 --- a/src/spikeinterface/core/base.py +++ b/src/spikeinterface/core/base.py @@ -846,43 +846,63 @@ def save_to_memory(self, sharedmem=True, **save_kwargs) -> "BaseExtractor": return cached # TODO rename to saveto_binary_folder - def save_to_folder(self, name=None, folder=None, overwrite=False, verbose=True, **save_kwargs): + def save_to_folder( + self, + name: str = None, + folder: str | Path = None, + overwrite: str = False, + verbose: bool = True, + **save_kwargs, + ): """ - Save extractor to folder. + Save the extractor and its data to a folder. - The save consist of: - * extracting traces by calling get_trace() method in chunks - * saving data into file (memmap with BinaryRecordingExtractor) - * dumping to json/pickle the original extractor for provenance - * dumping to json/pickle the cached extractor (memmap with BinaryRecordingExtractor) + This method extracts trace data, saves it to a file (using a memory-mapped format + with BinaryRecordingExtractor), and stores both the original extractor's provenance + and the cached extractor's metadata in JSON format. - This replaces the use of the old CacheRecordingExtractor and CacheSortingExtractor. + The folder final location and name can be specified in a couple of ways ways: - There are 2 option for the "folder" argument: - * explicit folder: `extractor.save(folder="/path-for-saving/")` - * explicit sub-folder, implicit base-folder : `extractor.save(name="extarctor_name")` - * generated: `extractor.save()` + 1. Explicitly providing the full path: + ``` + extractor.save_to_folder(folder="/path/to/save/") + ``` - The second option saves to subfolder "extractor_name" in - "get_global_tmp_folder()". You can set the global tmp folder with: - "set_global_tmp_folder("path-to-global-folder")" + 2. Providing a subfolder name, with the base folder being determined automatically: + ``` + extractor.save_to_folder(name="my_extractor_data") + ``` + In this case, the data is saved in a subfolder named "my_extractor_data" + within the global temporary folder (set using `set_global_tmp_folder`). If no + global temporary folder is set, one will be generated automatically. - The folder must not exist. If it exists, remove it before. + 3. If neither `name` nor `folder` is provided, a random name will be generated + for the subfolder within the global temporary folder. Parameters ---------- - name: None str or Path - Name of the subfolder in get_global_tmp_folder() - If "name" is given, "folder" must be None. - folder: None str or Path - Name of the folder. - If "folder" is given, "name" must be None. - overwrite: bool, default: False - If True, the folder is removed if it already exists + name : str or Path, optional + The name of the subfolder within the global temporary folder. If `folder` + is provided, this argument must be None. + folder : str or Path, optional + The full path of the folder where the data should be saved. If `name` is + provided, this argument must be None. + overwrite : bool, default: False + If True, an existing folder at the specified path will be deleted before saving. + verbose : bool, default: True + If True, print information about the cache folder being used. + **save_kwargs + Additional keyword arguments to be passed to the underlying save method. Returns ------- - cached: saved copy of the extractor. + cached_extractor + A saved copy of the extractor in the specified format (e.g., BinaryRecordingExtractor). + + Raises + ------ + AssertionError + If the folder already exists and `overwrite` is False. """ if folder is None: @@ -925,7 +945,6 @@ def save_to_folder(self, name=None, folder=None, overwrite=False, verbose=True, self.copy_metadata(cached) # dump - # cached.dump(folder / f'cached.json', relative_to=folder, folder_metadata=folder) cached.dump(folder / f"si_folder.json", relative_to=folder) return cached diff --git a/src/spikeinterface/extractors/tests/common_tests.py b/src/spikeinterface/extractors/tests/common_tests.py index 4ae233f681..dcbd2304f1 100644 --- a/src/spikeinterface/extractors/tests/common_tests.py +++ b/src/spikeinterface/extractors/tests/common_tests.py @@ -6,7 +6,6 @@ from spikeinterface import download_dataset, get_global_dataset_folder from spikeinterface.extractors.neoextractors.neobaseextractor import NeoBaseRecordingExtractor -from spikeinterface.extractors import get_neo_streams, get_neo_num_blocks from spikeinterface.core.testing import check_recordings_equal, check_sortings_equal From 5d743469765f60ed5fbfaa819e45a5ae457d7722 Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Fri, 17 May 2024 09:46:54 -0600 Subject: [PATCH 02/81] remove extractor_name --- src/spikeinterface/core/baserecording.py | 10 ++++++---- src/spikeinterface/core/binaryfolder.py | 1 - src/spikeinterface/core/binaryrecordingextractor.py | 1 - src/spikeinterface/core/npyfoldersnippets.py | 1 - src/spikeinterface/core/npysnippetsextractor.py | 1 - src/spikeinterface/core/npzsortingextractor.py | 1 - src/spikeinterface/core/numpyextractors.py | 2 -- src/spikeinterface/core/old_api_utils.py | 2 -- src/spikeinterface/core/sortingfolder.py | 2 -- src/spikeinterface/core/zarrextractors.py | 2 -- src/spikeinterface/extractors/alfsortingextractor.py | 1 - src/spikeinterface/extractors/cbin_ibl.py | 1 - .../extractors/cellexplorersortingextractor.py | 1 - src/spikeinterface/extractors/combinatoextractors.py | 1 - src/spikeinterface/extractors/hdsortextractors.py | 1 - .../extractors/herdingspikesextractors.py | 1 - src/spikeinterface/extractors/iblextractors.py | 2 -- src/spikeinterface/extractors/klustaextractors.py | 1 - src/spikeinterface/extractors/matlabhelpers.py | 1 - src/spikeinterface/extractors/mclustextractors.py | 1 - src/spikeinterface/extractors/mcsh5extractors.py | 1 - src/spikeinterface/extractors/mdaextractors.py | 2 -- .../extractors/neoextractors/neuroscope.py | 1 - src/spikeinterface/extractors/nwbextractors.py | 2 -- src/spikeinterface/extractors/phykilosortextractors.py | 3 --- src/spikeinterface/extractors/shybridextractors.py | 2 -- .../extractors/spykingcircusextractors.py | 1 - src/spikeinterface/extractors/tridesclousextractors.py | 1 - .../extractors/waveclussnippetstextractors.py | 1 - src/spikeinterface/extractors/waveclustextractors.py | 1 - src/spikeinterface/extractors/yassextractors.py | 1 - 31 files changed, 6 insertions(+), 44 deletions(-) diff --git a/src/spikeinterface/core/baserecording.py b/src/spikeinterface/core/baserecording.py index 4da00bfe3b..00d0e6ca6c 100644 --- a/src/spikeinterface/core/baserecording.py +++ b/src/spikeinterface/core/baserecording.py @@ -46,7 +46,8 @@ def __init__(self, sampling_frequency: float, channel_ids: list, dtype): def __repr__(self): - extractor_name = self.__class__.__name__ + class_name = self.__class__.__name__ + name_to_display = class_name num_segments = self.get_num_segments() txt = self._repr_header() @@ -56,7 +57,7 @@ def __repr__(self): split_index = txt.rfind("-", 0, 100) # Find the last "-" before character 100 if split_index != -1: first_line = txt[:split_index] - recording_string_space = len(extractor_name) + 2 # Length of extractor_name plus ": " + recording_string_space = len(name_to_display) + 2 # Length of name_to_display plus ": " white_space_to_align_with_first_line = " " * recording_string_space second_line = white_space_to_align_with_first_line + txt[split_index + 1 :].lstrip() txt = first_line + "\n" + second_line @@ -96,7 +97,8 @@ def list_to_string(lst, max_size=6): return txt def _repr_header(self): - extractor_name = self.__class__.__name__ + class_name = self.__class__.__name__ + name_to_display = class_name num_segments = self.get_num_segments() num_channels = self.get_num_channels() sf_khz = self.get_sampling_frequency() / 1000.0 @@ -107,7 +109,7 @@ def _repr_header(self): total_memory_size = self.get_total_memory_size() txt = ( - f"{extractor_name}: " + f"{name_to_display}: " f"{num_channels} channels - " f"{sf_khz:0.1f}kHz - " f"{num_segments} segments - " diff --git a/src/spikeinterface/core/binaryfolder.py b/src/spikeinterface/core/binaryfolder.py index 5e8c371abd..709532da3a 100644 --- a/src/spikeinterface/core/binaryfolder.py +++ b/src/spikeinterface/core/binaryfolder.py @@ -25,7 +25,6 @@ class BinaryFolderRecording(BinaryRecordingExtractor): The recording """ - extractor_name = "BinaryFolder" mode = "folder" name = "binaryfolder" diff --git a/src/spikeinterface/core/binaryrecordingextractor.py b/src/spikeinterface/core/binaryrecordingextractor.py index eaf81708ea..d575297998 100644 --- a/src/spikeinterface/core/binaryrecordingextractor.py +++ b/src/spikeinterface/core/binaryrecordingextractor.py @@ -52,7 +52,6 @@ class BinaryRecordingExtractor(BaseRecording): The recording Extractor """ - extractor_name = "BinaryRecording" mode = "file" name = "binary" diff --git a/src/spikeinterface/core/npyfoldersnippets.py b/src/spikeinterface/core/npyfoldersnippets.py index 5c1078996c..a13de1e7f4 100644 --- a/src/spikeinterface/core/npyfoldersnippets.py +++ b/src/spikeinterface/core/npyfoldersnippets.py @@ -26,7 +26,6 @@ class NpyFolderSnippets(NpySnippetsExtractor): The snippets """ - extractor_name = "NpyFolderSnippets" mode = "folder" name = "npyfolder" diff --git a/src/spikeinterface/core/npysnippetsextractor.py b/src/spikeinterface/core/npysnippetsextractor.py index fe66252c28..a5fb12a397 100644 --- a/src/spikeinterface/core/npysnippetsextractor.py +++ b/src/spikeinterface/core/npysnippetsextractor.py @@ -15,7 +15,6 @@ class NpySnippetsExtractor(BaseSnippets): All spike are store in two columns maner index+labels """ - extractor_name = "NpySnippets" mode = "file" name = "npy" diff --git a/src/spikeinterface/core/npzsortingextractor.py b/src/spikeinterface/core/npzsortingextractor.py index 5a40e3ba55..f60dadd8ec 100644 --- a/src/spikeinterface/core/npzsortingextractor.py +++ b/src/spikeinterface/core/npzsortingextractor.py @@ -16,7 +16,6 @@ class NpzSortingExtractor(BaseSorting): All spike are store in two columns maner index+labels """ - extractor_name = "NpzSortingExtractor" mode = "file" name = "npz" diff --git a/src/spikeinterface/core/numpyextractors.py b/src/spikeinterface/core/numpyextractors.py index 00b4d9efff..4dd24f6387 100644 --- a/src/spikeinterface/core/numpyextractors.py +++ b/src/spikeinterface/core/numpyextractors.py @@ -37,7 +37,6 @@ class NumpyRecording(BaseRecording): An optional list of channel_ids. If None, linear channels are assumed """ - extractor_name = "Numpy" mode = "memory" name = "numpy" @@ -143,7 +142,6 @@ class SharedMemoryRecording(BaseRecording): If True, the main instance will unlink the sharedmem buffer when deleted """ - extractor_name = "SharedMemory" mode = "memory" name = "SharedMemory" diff --git a/src/spikeinterface/core/old_api_utils.py b/src/spikeinterface/core/old_api_utils.py index 65de8aedf6..ea2f20d631 100644 --- a/src/spikeinterface/core/old_api_utils.py +++ b/src/spikeinterface/core/old_api_utils.py @@ -59,8 +59,6 @@ class NewToOldSorting: * unique segment """ - extractor_name = "NewToOldSorting" - def __init__(self, sorting): assert sorting.get_num_segments() == 1 self._sorting = sorting diff --git a/src/spikeinterface/core/sortingfolder.py b/src/spikeinterface/core/sortingfolder.py index 567ad915c9..1255b79cc1 100644 --- a/src/spikeinterface/core/sortingfolder.py +++ b/src/spikeinterface/core/sortingfolder.py @@ -22,7 +22,6 @@ class NumpyFolderSorting(BaseSorting): """ - extractor_name = "NumpyFolderSorting" mode = "folder" name = "NumpyFolder" @@ -91,7 +90,6 @@ class NpzFolderSorting(NpzSortingExtractor): The sorting """ - extractor_name = "NpzFolder" mode = "folder" name = "npzfolder" diff --git a/src/spikeinterface/core/zarrextractors.py b/src/spikeinterface/core/zarrextractors.py index 1ba96defac..79d7602c0b 100644 --- a/src/spikeinterface/core/zarrextractors.py +++ b/src/spikeinterface/core/zarrextractors.py @@ -30,7 +30,6 @@ class ZarrRecordingExtractor(BaseRecording): The recording Extractor """ - extractor_name = "ZarrRecording" installed = True mode = "folder" installation_mesg = "" @@ -167,7 +166,6 @@ class ZarrSortingExtractor(BaseSorting): The sorting Extractor """ - extractor_name = "ZarrSorting" installed = True mode = "folder" installation_mesg = "" diff --git a/src/spikeinterface/extractors/alfsortingextractor.py b/src/spikeinterface/extractors/alfsortingextractor.py index f4287541da..fa6490135c 100644 --- a/src/spikeinterface/extractors/alfsortingextractor.py +++ b/src/spikeinterface/extractors/alfsortingextractor.py @@ -24,7 +24,6 @@ class ALFSortingExtractor(BaseSorting): The loaded data. """ - extractor_name = "ALFSorting" installation_mesg = "To use the ALF extractors, install ONE-api: \n\n pip install ONE-api\n\n" name = "alf" diff --git a/src/spikeinterface/extractors/cbin_ibl.py b/src/spikeinterface/extractors/cbin_ibl.py index 2d81444a99..6de4af350f 100644 --- a/src/spikeinterface/extractors/cbin_ibl.py +++ b/src/spikeinterface/extractors/cbin_ibl.py @@ -37,7 +37,6 @@ class CompressedBinaryIblExtractor(BaseRecording): The loaded data. """ - extractor_name = "CompressedBinaryIbl" mode = "folder" installation_mesg = "To use the CompressedBinaryIblExtractor, install mtscomp: \n\n pip install mtscomp\n\n" name = "cbin_ibl" diff --git a/src/spikeinterface/extractors/cellexplorersortingextractor.py b/src/spikeinterface/extractors/cellexplorersortingextractor.py index 3436313b4d..85d6874577 100644 --- a/src/spikeinterface/extractors/cellexplorersortingextractor.py +++ b/src/spikeinterface/extractors/cellexplorersortingextractor.py @@ -30,7 +30,6 @@ class CellExplorerSortingExtractor(BaseSorting): Path to the `sessionInfo.mat` file. If None, it will be inferred from the file_path. """ - extractor_name = "CellExplorerSortingExtractor" mode = "file" installation_mesg = "To use the CellExplorerSortingExtractor install pymatreader" diff --git a/src/spikeinterface/extractors/combinatoextractors.py b/src/spikeinterface/extractors/combinatoextractors.py index e0d01e10e5..8828ea8b64 100644 --- a/src/spikeinterface/extractors/combinatoextractors.py +++ b/src/spikeinterface/extractors/combinatoextractors.py @@ -37,7 +37,6 @@ class CombinatoSortingExtractor(BaseSorting): The loaded data. """ - extractor_name = "CombinatoSortingExtractor" installed = HAVE_H5PY installation_mesg = "To use the CombinatoSortingExtractor install h5py: \n\n pip install h5py\n\n" name = "combinato" diff --git a/src/spikeinterface/extractors/hdsortextractors.py b/src/spikeinterface/extractors/hdsortextractors.py index 1be49f70be..19038344ee 100644 --- a/src/spikeinterface/extractors/hdsortextractors.py +++ b/src/spikeinterface/extractors/hdsortextractors.py @@ -25,7 +25,6 @@ class HDSortSortingExtractor(MatlabHelper, BaseSorting): The loaded data. """ - extractor_name = "HDSortSortingExtractor" mode = "file" name = "hdsort" diff --git a/src/spikeinterface/extractors/herdingspikesextractors.py b/src/spikeinterface/extractors/herdingspikesextractors.py index 139d51d62e..5802874337 100644 --- a/src/spikeinterface/extractors/herdingspikesextractors.py +++ b/src/spikeinterface/extractors/herdingspikesextractors.py @@ -31,7 +31,6 @@ class HerdingspikesSortingExtractor(BaseSorting): The loaded data. """ - extractor_name = "HS2Sorting" installed = HAVE_HS2SX # check at class level if installed or not mode = "file" installation_mesg = ( diff --git a/src/spikeinterface/extractors/iblextractors.py b/src/spikeinterface/extractors/iblextractors.py index 14b065a680..fde84a8c03 100644 --- a/src/spikeinterface/extractors/iblextractors.py +++ b/src/spikeinterface/extractors/iblextractors.py @@ -65,7 +65,6 @@ class IblRecordingExtractor(BaseRecording): The recording extractor which allows access to the traces. """ - extractor_name = "IblRecording" mode = "folder" installation_mesg = "To use the IblRecordingSegment, install ibllib: \n\n pip install ONE-api\npip install ibllib\n" name = "ibl_recording" @@ -309,7 +308,6 @@ class IblSortingExtractor(BaseSorting): The loaded data. """ - extractor_name = "IBLSorting" name = "ibl" installation_mesg = "IBL extractors require ibllib as a dependency." " To install, run: \n\n pip install ibllib\n\n" diff --git a/src/spikeinterface/extractors/klustaextractors.py b/src/spikeinterface/extractors/klustaextractors.py index 896b0cf4f5..c58d25aca3 100644 --- a/src/spikeinterface/extractors/klustaextractors.py +++ b/src/spikeinterface/extractors/klustaextractors.py @@ -43,7 +43,6 @@ class KlustaSortingExtractor(BaseSorting): The loaded data. """ - extractor_name = "KlustaSortingExtractor" installed = HAVE_H5PY # check at class level if installed or not installation_mesg = ( "To use the KlustaSortingExtractor install h5py: \n\n pip install h5py\n\n" # error message when not installed diff --git a/src/spikeinterface/extractors/matlabhelpers.py b/src/spikeinterface/extractors/matlabhelpers.py index 1c2e1491c8..701eb74d7b 100644 --- a/src/spikeinterface/extractors/matlabhelpers.py +++ b/src/spikeinterface/extractors/matlabhelpers.py @@ -7,7 +7,6 @@ class MatlabHelper: - extractor_name = "MATSortingExtractor" mode = "file" installation_mesg = ( "To use the MATSortingExtractor install h5py and scipy: " "\n\n pip install h5py scipy\n\n" diff --git a/src/spikeinterface/extractors/mclustextractors.py b/src/spikeinterface/extractors/mclustextractors.py index ed0454f682..5cfa583054 100644 --- a/src/spikeinterface/extractors/mclustextractors.py +++ b/src/spikeinterface/extractors/mclustextractors.py @@ -29,7 +29,6 @@ class MClustSortingExtractor(BaseSorting): Loaded data. """ - extractor_name = "MClustSortingExtractor" name = "mclust" def __init__(self, folder_path, sampling_frequency, sampling_frequency_raw=None): diff --git a/src/spikeinterface/extractors/mcsh5extractors.py b/src/spikeinterface/extractors/mcsh5extractors.py index d44b7d17a8..187dc1cd29 100644 --- a/src/spikeinterface/extractors/mcsh5extractors.py +++ b/src/spikeinterface/extractors/mcsh5extractors.py @@ -31,7 +31,6 @@ class MCSH5RecordingExtractor(BaseRecording): The loaded data. """ - extractor_name = "MCSH5Recording" installed = HAVE_MCSH5 # check at class level if installed or not mode = "file" installation_mesg = ( diff --git a/src/spikeinterface/extractors/mdaextractors.py b/src/spikeinterface/extractors/mdaextractors.py index d2848f03d7..d247b52ca4 100644 --- a/src/spikeinterface/extractors/mdaextractors.py +++ b/src/spikeinterface/extractors/mdaextractors.py @@ -36,7 +36,6 @@ class MdaRecordingExtractor(BaseRecording): The loaded data. """ - extractor_name = "MdaRecording" mode = "folder" name = "mda" @@ -193,7 +192,6 @@ class MdaSortingExtractor(BaseSorting): The loaded data. """ - extractor_name = "MdaSorting" mode = "file" name = "mda" diff --git a/src/spikeinterface/extractors/neoextractors/neuroscope.py b/src/spikeinterface/extractors/neoextractors/neuroscope.py index e23ab70f7a..c7b3643e69 100644 --- a/src/spikeinterface/extractors/neoextractors/neuroscope.py +++ b/src/spikeinterface/extractors/neoextractors/neuroscope.py @@ -103,7 +103,6 @@ class NeuroScopeSortingExtractor(BaseSorting): Path to the .xml file referenced by this sorting. """ - extractor_name = "NeuroscopeSortingExtractor" name = "neuroscope" def __init__( diff --git a/src/spikeinterface/extractors/nwbextractors.py b/src/spikeinterface/extractors/nwbextractors.py index 995e95115a..167c9cd90d 100644 --- a/src/spikeinterface/extractors/nwbextractors.py +++ b/src/spikeinterface/extractors/nwbextractors.py @@ -474,7 +474,6 @@ class NwbRecordingExtractor(BaseRecording): >>> rec = NwbRecordingExtractor(s3_url, stream_mode="fsspec", stream_cache_path="cache") """ - extractor_name = "NwbRecording" mode = "file" name = "nwb" installation_mesg = "To use the Nwb extractors, install pynwb: \n\n pip install pynwb\n\n" @@ -952,7 +951,6 @@ class NwbSortingExtractor(BaseSorting): The sorting extractor for the NWB file. """ - extractor_name = "NwbSorting" mode = "file" installation_mesg = "To use the Nwb extractors, install pynwb: \n\n pip install pynwb\n\n" name = "nwb" diff --git a/src/spikeinterface/extractors/phykilosortextractors.py b/src/spikeinterface/extractors/phykilosortextractors.py index 05aee160f5..78eaa355d1 100644 --- a/src/spikeinterface/extractors/phykilosortextractors.py +++ b/src/spikeinterface/extractors/phykilosortextractors.py @@ -26,7 +26,6 @@ class BasePhyKilosortSortingExtractor(BaseSorting): If True, all cluster properties are loaded from the tsv/csv files. """ - extractor_name = "BasePhyKilosortSorting" installed = False # check at class level if installed or not mode = "folder" installation_mesg = ( @@ -213,7 +212,6 @@ class PhySortingExtractor(BasePhyKilosortSortingExtractor): The loaded Sorting object. """ - extractor_name = "PhySorting" name = "phy" def __init__( @@ -255,7 +253,6 @@ class KiloSortSortingExtractor(BasePhyKilosortSortingExtractor): The loaded Sorting object. """ - extractor_name = "KiloSortSorting" name = "kilosort" def __init__(self, folder_path: Path | str, keep_good_only: bool = False, remove_empty_units: bool = True): diff --git a/src/spikeinterface/extractors/shybridextractors.py b/src/spikeinterface/extractors/shybridextractors.py index 86a5276d62..b53b3b2056 100644 --- a/src/spikeinterface/extractors/shybridextractors.py +++ b/src/spikeinterface/extractors/shybridextractors.py @@ -30,7 +30,6 @@ class SHYBRIDRecordingExtractor(BinaryRecordingExtractor): Loaded data. """ - extractor_name = "SHYBRIDRecording" mode = "folder" installation_mesg = ( "To use the SHYBRID extractors, install SHYBRID and pyyaml: " "\n\n pip install shybrid pyyaml\n\n" @@ -159,7 +158,6 @@ class SHYBRIDSortingExtractor(BaseSorting): Loaded data. """ - extractor_name = "SHYBRIDSorting" installation_mesg = "To use the SHYBRID extractors, install SHYBRID: \n\n pip install shybrid\n\n" name = "shybrid" diff --git a/src/spikeinterface/extractors/spykingcircusextractors.py b/src/spikeinterface/extractors/spykingcircusextractors.py index af966cb823..7c3fb154fe 100644 --- a/src/spikeinterface/extractors/spykingcircusextractors.py +++ b/src/spikeinterface/extractors/spykingcircusextractors.py @@ -29,7 +29,6 @@ class SpykingCircusSortingExtractor(BaseSorting): Loaded data. """ - extractor_name = "SpykingCircusSortingExtractor" installed = HAVE_H5PY # check at class level if installed or not mode = "folder" installation_mesg = "To use the SpykingCircusSortingExtractor install h5py: \n\n pip install h5py\n\n" diff --git a/src/spikeinterface/extractors/tridesclousextractors.py b/src/spikeinterface/extractors/tridesclousextractors.py index 531af3d9da..8589f03fd4 100644 --- a/src/spikeinterface/extractors/tridesclousextractors.py +++ b/src/spikeinterface/extractors/tridesclousextractors.py @@ -22,7 +22,6 @@ class TridesclousSortingExtractor(BaseSorting): Loaded data. """ - extractor_name = "TridesclousSortingExtractor" mode = "folder" installation_mesg = "To use the TridesclousSortingExtractor install tridesclous: \n\n pip install tridesclous\n\n" # error message when not installed name = "tridesclous" diff --git a/src/spikeinterface/extractors/waveclussnippetstextractors.py b/src/spikeinterface/extractors/waveclussnippetstextractors.py index 56f66aec8a..7c26eee7bd 100644 --- a/src/spikeinterface/extractors/waveclussnippetstextractors.py +++ b/src/spikeinterface/extractors/waveclussnippetstextractors.py @@ -10,7 +10,6 @@ class WaveClusSnippetsExtractor(MatlabHelper, BaseSnippets): - extractor_name = "WaveClusSnippetsExtractor" name = "waveclus" def __init__(self, file_path): diff --git a/src/spikeinterface/extractors/waveclustextractors.py b/src/spikeinterface/extractors/waveclustextractors.py index 02c668a902..844b1cc7cf 100644 --- a/src/spikeinterface/extractors/waveclustextractors.py +++ b/src/spikeinterface/extractors/waveclustextractors.py @@ -25,7 +25,6 @@ class WaveClusSortingExtractor(MatlabHelper, BaseSorting): Loaded data. """ - extractor_name = "WaveClusSortingExtractor" name = "waveclus" def __init__(self, file_path, keep_good_only=True): diff --git a/src/spikeinterface/extractors/yassextractors.py b/src/spikeinterface/extractors/yassextractors.py index 729df81c65..61a49ccf01 100644 --- a/src/spikeinterface/extractors/yassextractors.py +++ b/src/spikeinterface/extractors/yassextractors.py @@ -29,7 +29,6 @@ class YassSortingExtractor(BaseSorting): Loaded data. """ - extractor_name = "YassExtractor" mode = "folder" installed = HAVE_YAML # check at class level if installed or not installation_mesg = ( From 162468c6613f1f89419e0571196c395c2eaa072b Mon Sep 17 00:00:00 2001 From: chrishalcrow <57948917+chrishalcrow@users.noreply.github.com> Date: Tue, 4 Jun 2024 17:29:17 +0100 Subject: [PATCH 03/81] Add test to check unit structure in qm output --- .../qualitymetrics/misc_metrics.py | 4 +- .../tests/test_metrics_functions.py | 55 +++++++++++++++++++ 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/spikeinterface/qualitymetrics/misc_metrics.py b/src/spikeinterface/qualitymetrics/misc_metrics.py index f1082386cc..fca521c90f 100644 --- a/src/spikeinterface/qualitymetrics/misc_metrics.py +++ b/src/spikeinterface/qualitymetrics/misc_metrics.py @@ -388,9 +388,7 @@ def compute_refrac_period_violations( nb_violations = {} rp_contamination = {} - for i, unit_id in enumerate(sorting.unit_ids): - if unit_id not in unit_ids: - continue + for i, unit_id in enumerate(unit_ids): nb_violations[unit_id] = n_v = nb_rp_violations[i] N = num_spikes[unit_id] diff --git a/src/spikeinterface/qualitymetrics/tests/test_metrics_functions.py b/src/spikeinterface/qualitymetrics/tests/test_metrics_functions.py index 5a7d43cbae..d0c2481741 100644 --- a/src/spikeinterface/qualitymetrics/tests/test_metrics_functions.py +++ b/src/spikeinterface/qualitymetrics/tests/test_metrics_functions.py @@ -12,8 +12,12 @@ from spikeinterface.qualitymetrics.utils import create_ground_truth_pc_distributions +from spikeinterface.qualitymetrics.quality_metric_list import ( + _misc_metric_name_to_func, +) from spikeinterface.qualitymetrics import ( + get_quality_metric_list, mahalanobis_metrics, lda_metrics, nearest_neighbors_metrics, @@ -47,6 +51,57 @@ job_kwargs = dict(n_jobs=2, progress_bar=True, chunk_duration="1s") +def _small_sorting_analyzer(): + recording, sorting = generate_ground_truth_recording( + durations=[2.0], + num_units=4, + seed=1205, + ) + + sorting = sorting.select_units([3, 2, 0], ["#3", "#9", "#4"]) + + sorting_analyzer = create_sorting_analyzer(recording=recording, sorting=sorting, format="memory") + + extensions_to_compute = { + "random_spikes": {"seed": 1205}, + "noise_levels": {"seed": 1205}, + "waveforms": {}, + "templates": {}, + "spike_amplitudes": {}, + "principal_components": {}, + } + + sorting_analyzer.compute(extensions_to_compute) + + return sorting_analyzer + + +@pytest.fixture(scope="module") +def small_sorting_analyzer(): + return _small_sorting_analyzer() + + +def test_unit_structure_in_output(small_sorting_analyzer): + for metric_name in get_quality_metric_list(): + result = _misc_metric_name_to_func[metric_name](sorting_analyzer=small_sorting_analyzer) + + if isinstance(result, dict): + assert list(result.keys()) == ["#3", "#9", "#4"] + else: + for one_result in result: + assert list(one_result.keys()) == ["#3", "#9", "#4"] + + for metric_name in get_quality_metric_list(): + result = _misc_metric_name_to_func[metric_name](sorting_analyzer=small_sorting_analyzer, unit_ids=["#9", "#3"]) + + if isinstance(result, dict): + assert list(result.keys()) == ["#9", "#3"] + else: + for one_result in result: + print(metric_name) + assert list(one_result.keys()) == ["#9", "#3"] + + def _sorting_analyzer_simple(): recording, sorting = generate_ground_truth_recording( durations=[ From 11ae9aa6227e01fd19908d510d142651b8da1c1f Mon Sep 17 00:00:00 2001 From: chrishalcrow <57948917+chrishalcrow@users.noreply.github.com> Date: Thu, 13 Jun 2024 09:59:00 +0100 Subject: [PATCH 04/81] Add test to check unit_id order independence --- .../tests/test_metrics_functions.py | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/spikeinterface/qualitymetrics/tests/test_metrics_functions.py b/src/spikeinterface/qualitymetrics/tests/test_metrics_functions.py index d0c2481741..6652ea6654 100644 --- a/src/spikeinterface/qualitymetrics/tests/test_metrics_functions.py +++ b/src/spikeinterface/qualitymetrics/tests/test_metrics_functions.py @@ -38,6 +38,7 @@ compute_amplitude_cv_metrics, compute_sd_ratio, get_synchrony_counts, + compute_quality_metrics, ) from spikeinterface.core.basesorting import minimum_spike_dtype @@ -68,6 +69,7 @@ def _small_sorting_analyzer(): "waveforms": {}, "templates": {}, "spike_amplitudes": {}, + "spike_locations": {}, "principal_components": {}, } @@ -102,6 +104,56 @@ def test_unit_structure_in_output(small_sorting_analyzer): assert list(one_result.keys()) == ["#9", "#3"] +def test_unit_id_order_independence(small_sorting_analyzer): + """ + Takes two almost-identical sorting_analyzers, whose unit_ids are in different orders and have different labels, + and checks that their calculated quality metrics are independent of the ordering and labelling. + """ + + recording, sorting = generate_ground_truth_recording( + durations=[2.0], + num_units=4, + seed=1205, + ) + sorting = sorting.select_units([0, 2, 3]) + small_sorting_analyzer_2 = create_sorting_analyzer(recording=recording, sorting=sorting, format="memory") + + extensions_to_compute = { + "random_spikes": {"seed": 1205}, + "noise_levels": {"seed": 1205}, + "waveforms": {}, + "templates": {}, + "spike_amplitudes": {}, + "spike_locations": {}, + "principal_components": {}, + } + + small_sorting_analyzer_2.compute(extensions_to_compute) + + # need special params to get non-nan results on a short recording + qm_params = { + "presence_ratio": {"bin_duration_s": 0.1}, + "amplitude_cutoff": {"num_histogram_bins": 3}, + "amplitude_cv": {"average_num_spikes_per_bin": 7, "min_num_bins": 3}, + "firing_range": {"bin_size_s": 1}, + "isi_violation": {"isi_threshold_ms": 10}, + "drift": {"interval_s": 1, "min_spikes_per_interval": 5}, + "sliding_rp_violation": {"max_ref_period_ms": 50, "bin_size_ms": 0.15}, + } + + quality_metrics_1 = compute_quality_metrics( + small_sorting_analyzer, metric_names=get_quality_metric_list(), qm_params=qm_params + ) + quality_metrics_2 = compute_quality_metrics( + small_sorting_analyzer_2, metric_names=get_quality_metric_list(), qm_params=qm_params + ) + + for metric, metric_1_data in quality_metrics_1.items(): + assert quality_metrics_2[metric][3] == metric_1_data["#3"] + assert quality_metrics_2[metric][2] == metric_1_data["#9"] + assert quality_metrics_2[metric][0] == metric_1_data["#4"] + + def _sorting_analyzer_simple(): recording, sorting = generate_ground_truth_recording( durations=[ From b8f8627186f72ab14bd79d5dc62830160c0daa55 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Tue, 11 Jun 2024 20:47:34 +0100 Subject: [PATCH 05/81] Add docstrings from other PR. --- .../postprocessing/correlograms.py | 186 ++++++++++++++++-- .../postprocessing/tests/test_correlograms.py | 67 ++++++- 2 files changed, 236 insertions(+), 17 deletions(-) diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index bc7d2578fa..08e579cb30 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -13,21 +13,58 @@ except ModuleNotFoundError as err: HAVE_NUMBA = False +# TODO: here the default is 50 ms but in the docs it says 100 ms? + +# _set_params, _select_extension_data, _run, _get_data I think are +# sorting analyzer things. Docstrings can be added here and propagated to +# all sorting analyer functions OR can be described in the class docstring. +# otherwise these are quite hard to understand where they are called in the +# code as not called internally on the class. + +# compute_autocorrelogram_from_spiketrain +# TODO: in another PR, coerce this input into `correlogram_for_one_segment()` +# to provide a numpy and numba version. Consider window_size and bin_size +# being taken as ms to match general API. + +# TODO: also make clear the output are always counts, not correlation / covariance matrices +# 'lags': TODO: come up with some standard terminology and way of describing this from within the module.# + class ComputeCorrelograms(AnalyzerExtension): """ Compute auto and cross correlograms. + In the extracellular electrophysiology context, a correlogram + is a visualisation of the results of a cross-correlation + between two spike trains. The cross-correlation slides one spike train + along another sample-by-sample, taking the correlation at each 'lag'. This results + in a plot with 'lag' (i.e. time offset) on the x-axis and 'correlation' + (i.e. how similar to two spike trains are) on the y-axis. In this + implementation, the y-axis result is the 'counts' of spike matches per + time bin (rather than a computer correlation or covariance). + + Correlograms are often used to determine whether a unit has + ISI violations. In this context, a 'window' around spikes is first + specified. For example, if a window of 100 ms is taken, we will + take the correlation at lags from -100 ms to +100 ms around the spike peak. + In theory, we can have as many lags as we have samples. Often, this + visualisation is too high resolution and instead the lags are binned + (e.g. 0-5 ms, 5-10 ms, ..., 95-100 ms bins). When using counts as output, + binning the lags involves adding up all counts across a range of lags. + Parameters ---------- sorting_analyzer: SortingAnalyzer A SortingAnalyzer object window_ms : float, default: 50.0 - The window in ms + The window around the spike to compute the correlation in ms. For example, TODO: check this! + if 50 ms, the correlations will be computed at tags -25 ms ... 25 ms. bin_ms : float, default: 1.0 - The bin size in ms + The bin size in ms. This determines the bin size over which to + combine lags. For example, with a window size of -25 ms to 25 ms, and + bin size 1 ms, the correlation will be binned as -25 ms, -24 ms, ... method : "auto" | "numpy" | "numba", default: "auto" - If "auto" and numba is installed, numba is used, otherwise numpy is used + If "auto" and numba is installed, numba is used, otherwise numpy is used. Returns ------- @@ -40,7 +77,7 @@ class ComputeCorrelograms(AnalyzerExtension): The bin edges in ms Returns - ------- + ------- isi_histograms : np.array 2D array with ISI histograms (num_units, num_bins) bins : np.array @@ -89,7 +126,11 @@ def compute_correlograms( bin_ms: float = 1.0, method: str = "auto", ): - + """ + Convenience entry function to handle computation of + correlograms based on the method used. See ComputeCorrelograms() + for parameters. + """ if isinstance(sorting_analyzer_or_sorting, MockWaveformExtractor): sorting_analyzer_or_sorting = sorting_analyzer_or_sorting.sorting @@ -107,6 +148,35 @@ def compute_correlograms( def _make_bins(sorting, window_ms, bin_ms): + """ + Create the bins for the autocorrelogram, in samples. + + The autocorrelogram bins are centered around zero but do not + include the results from zero lag. Each bin increases in + a positive / negative direction starting at zero. + + For example, given a window_ms of 50 ms and a bin_ms of + 5 ms, the bins in unit ms will be: + [-25 to -20, ..., -5 to 0, 0 to 5, ..., 20 to 25]. + + The window size will be clipped if not divisible by the bin size. + The bins are output in sample units, not seconds. + + Parameters + ---------- + See ComputeCorrelograms() for parameters. + + Returns + ------- + + bins : np.ndarray + The bins edges in ms + window_size : int + The window size in samples + bin_size : int + The bin size in samples + + """ fs = sorting.sampling_frequency window_size = int(round(fs * window_ms / 2 * 1e-3)) @@ -120,6 +190,16 @@ def _make_bins(sorting, window_ms, bin_ms): return bins, window_size, bin_size +def _compute_num_bins(window_size, bin_size): + """ + Internal function to compute number of bins, expects + window_size and bin_size are already divisible and + typically generated in `_make_bins()`. + """ + num_half_bins = int(window_size // bin_size) + num_bins = int(2 * num_half_bins) + + def compute_autocorrelogram_from_spiketrain(spike_times, window_size, bin_size): """ Computes the auto-correlogram from a given spike train. @@ -176,6 +256,19 @@ def compute_crosscorrelogram_from_spiketrain(spike_times1, spike_times2, window_ def compute_correlograms_on_sorting(sorting, window_ms, bin_ms, method="auto"): """ Computes several cross-correlogram in one course from several clusters. + + Entry function to compute correlograms across all units in a `Sorting` + object (i.e. spike trains at all determined offsets will be computed + for each unit against every other unit). + + Returns + ------- + correlograms : np.array + A (num_units, num_units, num_bins) array where unit x unit correlation + matrices are stacked at all determined time bins. Note the true + correlation is not returned but instead the count of number of matches. + bins : np.array + The bins edges in ms """ assert method in ("auto", "numba", "numpy") @@ -212,8 +305,7 @@ def compute_correlograms_numpy(sorting, window_size, bin_size): num_units = len(sorting.unit_ids) spikes = sorting.to_spike_vector(concatenated=False) - num_half_bins = int(window_size // bin_size) - num_bins = int(2 * num_half_bins) + num_bins, num_half_bins = _compute_num_bins(window_size, bin_size) correlograms = np.zeros((num_units, num_units, num_bins), dtype="int64") @@ -230,11 +322,40 @@ def compute_correlograms_numpy(sorting, window_size, bin_size): def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size): """ - Called by compute_correlograms_numpy - """ + A very well optimized algorithm for the cross-correlation of + spike trains, copied from phy package written by Cyrille Rossant. + + This method does not perform a cross-correlation in the typical + way (sliding and computing correlations, or via Fourier transform). + Instead the time difference between every other spike within the + window is directly computer and stored as a count in the relevant bin. + + Initially, the spike_times array is shifted by 1 position, and the difference + computed. This gives the time differences betwen the closest spikes + (skipping the zero-lag case). Next, the differences between + spikes times in samples are converted into units relative to + bin_size ('binarized'). Spikes in which the binarized difference to + their closest neighbouring spike is greater than half the bin-size are + masked and not compared in future. Finally, the indicies of the + (num_units, num_units, num_bins) correlogram in which there are + a match are found and iterated appropriated. This repeats + for all shifts long the spike_train until no spikes have a corepsponding + match within the window size. - num_half_bins = int(window_size // bin_size) - num_bins = int(2 * num_half_bins) + Parameters + ---------- + spike_times : np.ndarray + An array of spike times (in samples, not seconds). This contains + spikes from all units. + spike_labels : np.ndarray + An array of labels indicating the unit of the corresponding spike in + `spike_times`. + window_size : int + The window size over which to perform the cross-correlation, in samples + bin_size : int + The size of which to bin lags, in samples. + """ + num_bins, num_half_bins = _compute_num_bins(window_size, bin_size) num_units = len(np.unique(spike_labels)) correlograms = np.zeros((num_units, num_units, num_bins), dtype="int64") @@ -295,11 +416,11 @@ def compute_correlograms_numba(sorting, window_size, bin_size): Implementation: Aurélien Wyngaard """ - assert HAVE_NUMBA, "numba version of this function requires installation of numba" - num_bins = 2 * int(window_size / bin_size) + num_bins, _ = _compute_num_bins(window_size, bin_size) num_units = len(sorting.unit_ids) + spikes = sorting.to_spike_vector(concatenated=False) correlograms = np.zeros((num_units, num_units, num_bins), dtype=np.int64) @@ -307,7 +428,7 @@ def compute_correlograms_numba(sorting, window_size, bin_size): spike_times = spikes[seg_index]["sample_index"] spike_labels = spikes[seg_index]["unit_index"] - _compute_correlograms_numba( + _compute_correlograms_numba_new( correlograms, spike_times.astype(np.int64), spike_labels.astype(np.int32), window_size, bin_size ) @@ -316,6 +437,43 @@ def compute_correlograms_numba(sorting, window_size, bin_size): if HAVE_NUMBA: + @numba.jit( + nopython=True, + nogil=True, + cache=False, + ) + def _compute_correlograms_numba_new(correlograms, spike_times, spike_labels, window_size, bin_size): + """ + + TODO: + + """ + num_bins, num_half_bins = _compute_num_bins(window_size, bin_size) + + # TODO: final checks for optimisation + start_j = 0 + for i in range(spike_times.size): + for j in range(start_j, spike_times.size): + + if i == j: + continue + + diff = spike_times[i] - spike_times[j] + + if diff >= window_size: # j is too far behind + start_j += 1 + continue + if diff < -window_size: # j is too far ahead. i is done. + break + + bin = diff // bin_size + + correlograms[spike_labels[i], spike_labels[j], num_half_bins + bin] += 1 + + # ----------------------------------------------------------------------------- + # To Deprecate + # ----------------------------------------------------------------------------- + @numba.jit(nopython=True, nogil=True, cache=False) def _compute_autocorr_numba(spike_times, window_size, bin_size): num_half_bins = window_size // bin_size diff --git a/src/spikeinterface/postprocessing/tests/test_correlograms.py b/src/spikeinterface/postprocessing/tests/test_correlograms.py index eef4af10fc..08d1695a5f 100644 --- a/src/spikeinterface/postprocessing/tests/test_correlograms.py +++ b/src/spikeinterface/postprocessing/tests/test_correlograms.py @@ -11,10 +11,15 @@ from spikeinterface import NumpySorting, generate_sorting from spikeinterface.postprocessing.tests.common_extension_tests import AnalyzerExtensionCommonTestSuite from spikeinterface.postprocessing import ComputeCorrelograms -from spikeinterface.postprocessing.correlograms import compute_correlograms_on_sorting, _make_bins +from spikeinterface.postprocessing.correlograms import ( + compute_correlograms_on_sorting, + _make_bins, + _compute_correlograms_numba, + _compute_correlograms_numba_new, + correlogram_for_one_segment, +) import pytest - class TestComputeCorrelograms(AnalyzerExtensionCommonTestSuite): @pytest.mark.parametrize( @@ -52,7 +57,9 @@ def _test_correlograms(sorting, window_ms, bin_ms, methods): correlograms, bins = compute_correlograms_on_sorting(sorting, window_ms=window_ms, bin_ms=bin_ms, method=method) if method == "numpy": ref_bins = bins + ref_correlograms = correlograms else: + assert np.all(correlograms == ref_correlograms), f"Failed with method={method}" assert np.allclose(bins, ref_bins, atol=1e-10), f"Failed with method={method}" @@ -62,7 +69,7 @@ def test_equal_results_correlograms(): if HAVE_NUMBA: methods.append("numba") - sorting = generate_sorting(num_units=5, sampling_frequency=30000.0, durations=[10.325, 3.5], seed=0) + sorting = generate_sorting(num_units=5, sampling_frequency=30000.0, durations=[10.325, 3.5]) _test_correlograms(sorting, window_ms=60.0, bin_ms=2.0, methods=methods) _test_correlograms(sorting, window_ms=43.57, bin_ms=1.6421, methods=methods) @@ -163,3 +170,57 @@ def test_detect_injected_correlation(): sampling_period_ms = 1000.0 / sampling_frequency assert abs(peak_location_01_ms) - injected_delta_ms < sampling_period_ms assert abs(peak_location_02_ms) - injected_delta_ms < sampling_period_ms + +# do numpy and numba +def test_correlograms_unit(): + + sampling_rate = 30000 + + spike_times = np.repeat(np.arange(50), 2) * 0.0051 + spike_labels = np.zeros(100, dtype=int) + spike_labels[::2] = 1 + + spike_times *= sampling_rate + spike_times = spike_times.astype(int) + + window_size = int(0.3 * sampling_rate) + bin_size = int(0.005 * sampling_rate) + + # TODO: so now the window is -100 to + 100? weird, check docs + # TODO: actually calculuate! + # if method == "numba": + num_bins = 120 + result_orig = np.zeros((2, 2, num_bins), dtype=np.int64) + _compute_correlograms_numba(result_orig, spike_times, spike_labels, window_size, bin_size) + + result_test = np.zeros((2, 2, num_bins), dtype=np.int64) + _compute_correlograms_numba_new(result_test, spike_times, spike_labels, window_size, bin_size) + + # TODO: need to handle the expected result issue. It is different for + # autocorrelogram and cross-correlogram case. Needs to be discussed! + result_numpy = correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size) + + # they do not match for [1, 0] only so a backwards case issue! + # they shift slightly different to the left or right... + # tackle the 0.0051 case first, easier to interpret + for i in range(2): + for j in range(2): # use num units + assert np.array_equal(result_[i, j, :], result_test[i, j, :]), f"{i}, {j} index failed." + + # Okay, the problem, occurs when there is two spikes in + # different units at exactly the same time. Then these are counted! + # but the policy of these algorithms is not to count in this instance. + # but this is only done for the autocorrelogram and NOT the cross-correlogram + + # It seems they are both somehow adding in an extra bin in the + # backwards case. All array should be equal but [1, 0] is different, + # a whole in, with 50! it's like the zero-offset bin is added back :S + + if False: + empty_bins = np.zeros(10, dtype=int) + filled_bins = np.arange(1, 50) + expected_output = np.r_[empty_bins, filled_bins, 0, 0, np.flip(filled_bins), empty_bins] + + # TODO: check over all dims + assert np.array_equal(result[0, 0, :], expected_output) + From b0dab65788c19b74857155002b88eeaa9e2ee21c Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Wed, 12 Jun 2024 09:13:53 +0100 Subject: [PATCH 06/81] Make astype copy=False. --- .../postprocessing/correlograms.py | 163 ++++++++++++------ .../postprocessing/tests/test_correlograms.py | 3 +- 2 files changed, 116 insertions(+), 50 deletions(-) diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index 08e579cb30..3786de0168 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -68,21 +68,13 @@ class ComputeCorrelograms(AnalyzerExtension): Returns ------- - ccgs : np.array + correlogram : np.array Correlograms with shape (num_units, num_units, num_bins) The diagonal of ccgs is the auto correlogram. - ccgs[A, B, :] is the symetrie of ccgs[B, A, :] - ccgs[A, B, :] have to be read as the histogram of spiketimesA - spiketimesB + correlogram[A, B, :] is the symetrie of correlogram[B, A, :] + correlogram[A, B, :] have to be read as the histogram of spiketimesA - spiketimesB bins : np.array The bin edges in ms - - Returns - ------- - isi_histograms : np.array - 2D array with ISI histograms (num_units, num_bins) - bins : np.array - 1D array with bins in ms - """ extension_name = "correlograms" @@ -119,6 +111,9 @@ def _get_data(self): register_result_extension(ComputeCorrelograms) compute_correlograms_sorting_analyzer = ComputeCorrelograms.function_factory() +# TODO: Question: what is the main entry functions for this module? +# is it only the below? If so can all other functions be made private? + def compute_correlograms( sorting_analyzer_or_sorting, @@ -127,9 +122,8 @@ def compute_correlograms( method: str = "auto", ): """ - Convenience entry function to handle computation of - correlograms based on the method used. See ComputeCorrelograms() - for parameters. + Compute correlograms using Numba or Numpy. + See ComputeCorrelograms() for details. """ if isinstance(sorting_analyzer_or_sorting, MockWaveformExtractor): sorting_analyzer_or_sorting = sorting_analyzer_or_sorting.sorting @@ -195,10 +189,22 @@ def _compute_num_bins(window_size, bin_size): Internal function to compute number of bins, expects window_size and bin_size are already divisible and typically generated in `_make_bins()`. + + Returns + ------- + num_bins : int + The total number of bins to span the window, in samples + half_num_bins : int + Half the number of bins. The bins are an equal number + of bins that look forward and backwards from zero, e.g. + [..., -10 to -5, -5 to 0, 0 to 5, 5 to 10, ...] + """ num_half_bins = int(window_size // bin_size) num_bins = int(2 * num_half_bins) + return num_bins, num_half_bins + def compute_autocorrelogram_from_spiketrain(spike_times, window_size, bin_size): """ @@ -209,20 +215,20 @@ def compute_autocorrelogram_from_spiketrain(spike_times, window_size, bin_size): Parameters ---------- - spike_times: np.ndarray + spike_times : np.ndarray The ordered spike train to compute the auto-correlogram. - window_size: int + window_size : int Compute the auto-correlogram between -window_size and +window_size (in sampling time). - bin_size: int + bin_size : int Size of a bin (in sampling time). Returns ------- - tuple (auto_corr, bins) - auto_corr: np.ndarray[int64] + auto_corr : np.ndarray[int64] The computed auto-correlogram. + bins : """ assert HAVE_NUMBA - return _compute_autocorr_numba(spike_times.astype(np.int64), window_size, bin_size) + return _compute_correlograms_one_segment_numba(spike_times.astype(np.int64, copy=False), window_size, bin_size) def compute_crosscorrelogram_from_spiketrain(spike_times1, spike_times2, window_size, bin_size): @@ -250,7 +256,9 @@ def compute_crosscorrelogram_from_spiketrain(spike_times1, spike_times2, window_ The computed auto-correlogram. """ assert HAVE_NUMBA - return _compute_crosscorr_numba(spike_times1.astype(np.int64), spike_times2.astype(np.int64), window_size, bin_size) + return _compute_correlograms_one_segment_numba( + spike_times1.astype(np.int64), spike_times2.astype(np.int64, copy=False), window_size, bin_size + ) def compute_correlograms_on_sorting(sorting, window_ms, bin_ms, method="auto"): @@ -323,12 +331,11 @@ def compute_correlograms_numpy(sorting, window_size, bin_size): def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size): """ A very well optimized algorithm for the cross-correlation of - spike trains, copied from phy package written by Cyrille Rossant. + spike trains, copied from the Phy package, written by Cyrille Rossant. - This method does not perform a cross-correlation in the typical - way (sliding and computing correlations, or via Fourier transform). - Instead the time difference between every other spike within the - window is directly computer and stored as a count in the relevant bin. + For all spikes, time difference between this spike and + every other spike within the window is directly computed + and stored as a count in the relevant lag time bin. Initially, the spike_times array is shifted by 1 position, and the difference computed. This gives the time differences betwen the closest spikes @@ -336,20 +343,21 @@ def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size spikes times in samples are converted into units relative to bin_size ('binarized'). Spikes in which the binarized difference to their closest neighbouring spike is greater than half the bin-size are - masked and not compared in future. Finally, the indicies of the - (num_units, num_units, num_bins) correlogram in which there are - a match are found and iterated appropriated. This repeats - for all shifts long the spike_train until no spikes have a corepsponding + masked and not compared in future. + + Finally, the indicies of the (num_units, num_units, num_bins) correlogram + that need incrementing are done so with `ravel_multi_index()`. This repeats + for all shifts along the spike_train until no spikes have a corresponding match within the window size. Parameters ---------- spike_times : np.ndarray - An array of spike times (in samples, not seconds). This contains - spikes from all units. + An array of spike times (in samples, not seconds). + This contains spikes from all units. spike_labels : np.ndarray - An array of labels indicating the unit of the corresponding spike in - `spike_times`. + An array of labels indicating the unit of the corresponding + spike in `spike_times`. window_size : int The window size over which to perform the cross-correlation, in samples bin_size : int @@ -408,17 +416,32 @@ def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size def compute_correlograms_numba(sorting, window_size, bin_size): """ - Computes several cross-correlogram in one course - from several cluster. + Computes cross-correlograms between all units in `sorting`. This is a "brute force" method using compiled code (numba) - to accelerate the computation. + to accelerate the computation. See + `_compute_correlograms_one_segment_numba()` for details. + + Parameters + ---------- + sorting : Sorting + A SpikeInterface Sorting object + window_size : int + The wi ndow size over which to perform the cross-correlation, in samples + bin_size : int + The size of which to bin lags, in samples. + + Returns + ------- + correlograms: np.array + A (num_units, num_units, num_bins) array of correlograms + between all units at each lag time bin. Implementation: Aurélien Wyngaard """ assert HAVE_NUMBA, "numba version of this function requires installation of numba" - num_bins, _ = _compute_num_bins(window_size, bin_size) + num_bins, num_half_bins = _compute_num_bins(window_size, bin_size) num_units = len(sorting.unit_ids) spikes = sorting.to_spike_vector(concatenated=False) @@ -428,8 +451,14 @@ def compute_correlograms_numba(sorting, window_size, bin_size): spike_times = spikes[seg_index]["sample_index"] spike_labels = spikes[seg_index]["unit_index"] - _compute_correlograms_numba_new( - correlograms, spike_times.astype(np.int64), spike_labels.astype(np.int32), window_size, bin_size + _compute_correlograms_one_segment_numba( + correlograms, + spike_times.astype(np.int64, copy=False), + spike_labels.astype(np.int32, copy=False), + window_size, + bin_size, + num_bins, + num_half_bins, ) return correlograms @@ -442,15 +471,43 @@ def compute_correlograms_numba(sorting, window_size, bin_size): nogil=True, cache=False, ) - def _compute_correlograms_numba_new(correlograms, spike_times, spike_labels, window_size, bin_size): + def _compute_correlograms_one_segment_numba( + correlograms, spike_times, spike_labels, window_size, bin_size, num_bins, num_half_bins + ): """ - - TODO: - + Compute the correlograms using `numba` for speed. + + The algorithm works by brute-force iteration through all + pairs of spikes (skipping those when outside of the window). + The spike-time difference and its time bin are computed + and stored in a (num_units, num_units, num_bins) + correlogram. The correlogram must be passed as an + argument and is filled in-place. + + Paramters + --------- + + correlograms: np.array + A (num_units, num_units, num_bins) array of correlograms + between all units at each lag time bin. This is passed + as counts for all segments are added to it. + spike_times : np.ndarray + An array of spike times (in samples, not seconds). + This contains spikes from all units. + spike_labels : np.ndarray + An array of labels indicating the unit of the corresponding + spike in `spike_times`. + window_size : int + The window size over which to perform the cross-correlation, in samples + bin_size : int + The size of which to bin lags, in samples. + num_bins : int + The total number of bins to span the window, in samples + half_num_bins : int + Half the number of bins. The bins are an equal number + of bins that look forward and backwards from zero, e.g. + [..., -10 to -5, -5 to 0, 0 to 5, 5 to 10, ...] """ - num_bins, num_half_bins = _compute_num_bins(window_size, bin_size) - - # TODO: final checks for optimisation start_j = 0 for i in range(spike_times.size): for j in range(start_j, spike_times.size): @@ -460,10 +517,18 @@ def _compute_correlograms_numba_new(correlograms, spike_times, spike_labels, win diff = spike_times[i] - spike_times[j] - if diff >= window_size: # j is too far behind + # if the time of spike i is more than window size later than + # spike j, then spike i + 1 will also be more than a window size + # later than spike j. Iterate the start_j and check the next spike. + if diff >= window_size: start_j += 1 continue - if diff < -window_size: # j is too far ahead. i is done. + + # If the time of spike i is more than a window size earlier + # than spike j, then all following j spikes will be even later + # i spikes and so all more than a window size earlier. So move + # onto the next i. + if diff < -window_size: break bin = diff // bin_size diff --git a/src/spikeinterface/postprocessing/tests/test_correlograms.py b/src/spikeinterface/postprocessing/tests/test_correlograms.py index 08d1695a5f..ba3833296d 100644 --- a/src/spikeinterface/postprocessing/tests/test_correlograms.py +++ b/src/spikeinterface/postprocessing/tests/test_correlograms.py @@ -69,7 +69,7 @@ def test_equal_results_correlograms(): if HAVE_NUMBA: methods.append("numba") - sorting = generate_sorting(num_units=5, sampling_frequency=30000.0, durations=[10.325, 3.5]) + sorting = generate_sorting(num_units=5, sampling_frequency=30000.0, durations=[10.325, 3.5], seed=0) _test_correlograms(sorting, window_ms=60.0, bin_ms=2.0, methods=methods) _test_correlograms(sorting, window_ms=43.57, bin_ms=1.6421, methods=methods) @@ -172,6 +172,7 @@ def test_detect_injected_correlation(): assert abs(peak_location_02_ms) - injected_delta_ms < sampling_period_ms # do numpy and numba +# TOOD: also test the direct spiketrain functions def test_correlograms_unit(): sampling_rate = 30000 From f906020a931cf9b03dde50366d716de364c2dbe7 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Wed, 12 Jun 2024 09:20:02 +0100 Subject: [PATCH 07/81] Add a few more notes and thoughts. --- .../postprocessing/correlograms.py | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index 3786de0168..8da41522c0 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -26,9 +26,6 @@ # to provide a numpy and numba version. Consider window_size and bin_size # being taken as ms to match general API. -# TODO: also make clear the output are always counts, not correlation / covariance matrices -# 'lags': TODO: come up with some standard terminology and way of describing this from within the module.# - class ComputeCorrelograms(AnalyzerExtension): """ @@ -70,7 +67,8 @@ class ComputeCorrelograms(AnalyzerExtension): ------- correlogram : np.array Correlograms with shape (num_units, num_units, num_bins) - The diagonal of ccgs is the auto correlogram. + The diagonal of correlogram is the auto correlogram. The output + is in bin counts. correlogram[A, B, :] is the symetrie of correlogram[B, A, :] correlogram[A, B, :] have to be read as the histogram of spiketimesA - spiketimesB bins : np.array @@ -113,6 +111,7 @@ def _get_data(self): # TODO: Question: what is the main entry functions for this module? # is it only the below? If so can all other functions be made private? +# This would reduce some docstring duplication def compute_correlograms( @@ -206,6 +205,7 @@ def _compute_num_bins(window_size, bin_size): return num_bins, num_half_bins +# TODO: this can now be deprecated as there is no distinction at the Numba level. def compute_autocorrelogram_from_spiketrain(spike_times, window_size, bin_size): """ Computes the auto-correlogram from a given spike train. @@ -231,6 +231,10 @@ def compute_autocorrelogram_from_spiketrain(spike_times, window_size, bin_size): return _compute_correlograms_one_segment_numba(spike_times.astype(np.int64, copy=False), window_size, bin_size) +# TODO: expose a numpy option also. UNless we want to force users to use `Sorting` or `SortingAnalyzer`. +# I am not averse to this, is helps reduce the suface API and assist maintaince. If users +# want to directly computer cross-correlograms they can use a private internal function. +# Thoughts? def compute_crosscorrelogram_from_spiketrain(spike_times1, spike_times2, window_size, bin_size): """ Computes the cros-correlogram between two given spike trains. @@ -269,6 +273,18 @@ def compute_correlograms_on_sorting(sorting, window_ms, bin_ms, method="auto"): object (i.e. spike trains at all determined offsets will be computed for each unit against every other unit). + Parameters + ---------- + sorting : Sorting + A SpikeInterface Sorting object + window_ms : int + The window size over which to perform the cross-correlation, in ms + bin_ms : int + The size of which to bin lags, in ms. + method : str + To use "numpy" or "numba". "auto" will use numba if available, + otherwise numpy. + Returns ------- correlograms : np.array From 3de3d9a2eae9f1005d31f919367c59443a093ea3 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Wed, 19 Jun 2024 21:23:20 +0100 Subject: [PATCH 08/81] Continue playing with tests. --- .../postprocessing/correlograms.py | 13 +-- .../postprocessing/tests/test_correlograms.py | 96 +++++++++++-------- 2 files changed, 57 insertions(+), 52 deletions(-) diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index 8da41522c0..7038b09a48 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -473,7 +473,6 @@ def compute_correlograms_numba(sorting, window_size, bin_size): spike_labels.astype(np.int32, copy=False), window_size, bin_size, - num_bins, num_half_bins, ) @@ -488,7 +487,7 @@ def compute_correlograms_numba(sorting, window_size, bin_size): cache=False, ) def _compute_correlograms_one_segment_numba( - correlograms, spike_times, spike_labels, window_size, bin_size, num_bins, num_half_bins + correlograms, spike_times, spike_labels, window_size, bin_size, num_half_bins ): """ Compute the correlograms using `numba` for speed. @@ -517,12 +516,6 @@ def _compute_correlograms_one_segment_numba( The window size over which to perform the cross-correlation, in samples bin_size : int The size of which to bin lags, in samples. - num_bins : int - The total number of bins to span the window, in samples - half_num_bins : int - Half the number of bins. The bins are an equal number - of bins that look forward and backwards from zero, e.g. - [..., -10 to -5, -5 to 0, 0 to 5, 5 to 10, ...] """ start_j = 0 for i in range(spike_times.size): @@ -536,7 +529,7 @@ def _compute_correlograms_one_segment_numba( # if the time of spike i is more than window size later than # spike j, then spike i + 1 will also be more than a window size # later than spike j. Iterate the start_j and check the next spike. - if diff >= window_size: + if diff > window_size: start_j += 1 continue @@ -544,7 +537,7 @@ def _compute_correlograms_one_segment_numba( # than spike j, then all following j spikes will be even later # i spikes and so all more than a window size earlier. So move # onto the next i. - if diff < -window_size: + if diff <= -window_size: break bin = diff // bin_size diff --git a/src/spikeinterface/postprocessing/tests/test_correlograms.py b/src/spikeinterface/postprocessing/tests/test_correlograms.py index ba3833296d..a0863be117 100644 --- a/src/spikeinterface/postprocessing/tests/test_correlograms.py +++ b/src/spikeinterface/postprocessing/tests/test_correlograms.py @@ -14,12 +14,12 @@ from spikeinterface.postprocessing.correlograms import ( compute_correlograms_on_sorting, _make_bins, - _compute_correlograms_numba, - _compute_correlograms_numba_new, - correlogram_for_one_segment, + compute_correlograms, ) +from spikeinterface.core import NumpySorting import pytest + class TestComputeCorrelograms(AnalyzerExtensionCommonTestSuite): @pytest.mark.parametrize( @@ -51,7 +51,11 @@ def test_make_bins(): bins, window_size, bin_size = _make_bins(sorting, window_ms, bin_ms) assert bins.size == np.floor(window_ms / bin_ms) + 1 + breakpoint() + # TODO: add an exact test + +# TODO: remove in favour of below def _test_correlograms(sorting, window_ms, bin_ms, methods): for method in methods: correlograms, bins = compute_correlograms_on_sorting(sorting, window_ms=window_ms, bin_ms=bin_ms, method=method) @@ -63,6 +67,7 @@ def _test_correlograms(sorting, window_ms, bin_ms, methods): assert np.allclose(bins, ref_bins, atol=1e-10), f"Failed with method={method}" +# TODO: remove in favour of below def test_equal_results_correlograms(): # compare that the 2 methods have same results methods = ["numpy"] @@ -94,6 +99,8 @@ def test_flat_cross_correlogram(): assert np.all(cc < (m * 1.10)) +# TODO: maybe deprecate in favour of the new test as it does test +# similar thing, but check the border effects... def test_auto_equal_cross_correlograms(): """ check if cross correlogram is the same as autocorrelogram @@ -123,6 +130,8 @@ def test_auto_equal_cross_correlograms(): cc_corrected = cc.copy() cc_corrected[num_half_bins] -= num_spike + breakpoint() + if method == "numpy": # numpy method have some border effect on left assert np.array_equal(cc_corrected[1:num_half_bins], ac[1:num_half_bins]) @@ -131,6 +140,8 @@ def test_auto_equal_cross_correlograms(): else: assert np.array_equal(cc_corrected, ac) + breakpoint() + def test_detect_injected_correlation(): """ @@ -171,57 +182,58 @@ def test_detect_injected_correlation(): assert abs(peak_location_01_ms) - injected_delta_ms < sampling_period_ms assert abs(peak_location_02_ms) - injected_delta_ms < sampling_period_ms -# do numpy and numba -# TOOD: also test the direct spiketrain functions + +# TODO: test one segment, test multi-segment with / without set_times +# indeed, test with one segment here. + + +# parameterize over: +# 1) the multi-segment case (all counts should be doubled) +# 2) mutli-segment with set_times +# 3) some different window_ms and bin_ms. Instead, maybe core utils +# can be factored out and segment stuff is handled in a new test. +# otherwise, will be too much! def test_correlograms_unit(): + """ """ + sampling_frequency = 30000 - sampling_rate = 30000 + num_filled_bins = 20 - spike_times = np.repeat(np.arange(50), 2) * 0.0051 - spike_labels = np.zeros(100, dtype=int) + spike_times = np.repeat(np.arange(num_filled_bins), 2) * 0.0051 + spike_labels = np.zeros(num_filled_bins * 2, dtype=int) spike_labels[::2] = 1 - spike_times *= sampling_rate + spike_times *= sampling_frequency spike_times = spike_times.astype(int) - window_size = int(0.3 * sampling_rate) - bin_size = int(0.005 * sampling_rate) - - # TODO: so now the window is -100 to + 100? weird, check docs - # TODO: actually calculuate! - # if method == "numba": - num_bins = 120 - result_orig = np.zeros((2, 2, num_bins), dtype=np.int64) - _compute_correlograms_numba(result_orig, spike_times, spike_labels, window_size, bin_size) + window_ms = 300 + bin_ms = 5 - result_test = np.zeros((2, 2, num_bins), dtype=np.int64) - _compute_correlograms_numba_new(result_test, spike_times, spike_labels, window_size, bin_size) + num_bins, check_even_divide = np.divmod(window_ms, bin_ms) + assert check_even_divide == 0, "the test bin_ms must evenly divide the window_ms" - # TODO: need to handle the expected result issue. It is different for - # autocorrelogram and cross-correlogram case. Needs to be discussed! - result_numpy = correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size) + sorting = NumpySorting.from_times_labels( + times_list=[spike_times], labels_list=[spike_labels], sampling_frequency=sampling_frequency + ) - # they do not match for [1, 0] only so a backwards case issue! - # they shift slightly different to the left or right... - # tackle the 0.0051 case first, easier to interpret - for i in range(2): - for j in range(2): # use num units - assert np.array_equal(result_[i, j, :], result_test[i, j, :]), f"{i}, {j} index failed." + result_numba, bins_numba = compute_correlograms( # TODO: handle the case with set_times! + sorting, window_ms=window_ms, bin_ms=bin_ms, method="numba" + ) + result_numpy, bins_numpy = compute_correlograms(sorting, window_ms=window_ms, bin_ms=bin_ms, method="numpy") - # Okay, the problem, occurs when there is two spikes in - # different units at exactly the same time. Then these are counted! - # but the policy of these algorithms is not to count in this instance. - # but this is only done for the autocorrelogram and NOT the cross-correlogram + expected_bins = np.linspace(-150, 150, num_bins + 1) - # It seems they are both somehow adding in an extra bin in the - # backwards case. All array should be equal but [1, 0] is different, - # a whole in, with 50! it's like the zero-offset bin is added back :S + assert np.array_equal(expected_bins, bins_numpy) + assert np.array_equal(expected_bins, bins_numba) - if False: - empty_bins = np.zeros(10, dtype=int) - filled_bins = np.arange(1, 50) - expected_output = np.r_[empty_bins, filled_bins, 0, 0, np.flip(filled_bins), empty_bins] + expected_forward_bins = np.r_[np.zeros(int(num_bins / 2 - num_filled_bins - 1)), np.arange(num_filled_bins), 0] + expected_results = np.r_[expected_forward_bins, np.flip(expected_forward_bins)] - # TODO: check over all dims - assert np.array_equal(result[0, 0, :], expected_output) + for auto_idx in [(0, 0), (1, 1)]: + assert np.array_equal(expected_results, result_numpy[auto_idx]) # TODO: CHECK! + assert np.array_equal(expected_results, result_numba[auto_idx]) + expected_results[int(num_bins / 2)] = num_filled_bins + for auto_idx in [(1, 0), (0, 1)]: + assert np.array_equal(expected_results, result_numpy[auto_idx]) # TODO: CHECK! + assert np.array_equal(expected_results, result_numba[auto_idx]) From 73c7290a089f8d7d2c12e3305e8284e878554ee4 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Wed, 19 Jun 2024 22:07:53 +0100 Subject: [PATCH 09/81] Fix edge issue on numpy and numba. --- .../postprocessing/correlograms.py | 16 +++++---- .../postprocessing/tests/test_correlograms.py | 36 ++++++++++++------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index 7038b09a48..bea0f780fe 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -404,6 +404,7 @@ def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size if sign == -1: mask[:-shift][spike_diff_b < -num_half_bins] = False else: + # spike_diff_b[np.where(spike_diff_b == num_half_bins)] -= 1 mask[:-shift][spike_diff_b >= num_half_bins] = False m = mask[:-shift] @@ -481,11 +482,11 @@ def compute_correlograms_numba(sorting, window_size, bin_size): if HAVE_NUMBA: - @numba.jit( - nopython=True, - nogil=True, - cache=False, - ) + # @numba.jit( + # nopython=True, + # nogil=True, + # cache=False, + # ) def _compute_correlograms_one_segment_numba( correlograms, spike_times, spike_labels, window_size, bin_size, num_half_bins ): @@ -529,6 +530,9 @@ def _compute_correlograms_one_segment_numba( # if the time of spike i is more than window size later than # spike j, then spike i + 1 will also be more than a window size # later than spike j. Iterate the start_j and check the next spike. + if diff == window_size: + continue + if diff > window_size: start_j += 1 continue @@ -537,7 +541,7 @@ def _compute_correlograms_one_segment_numba( # than spike j, then all following j spikes will be even later # i spikes and so all more than a window size earlier. So move # onto the next i. - if diff <= -window_size: + if diff < -window_size: break bin = diff // bin_size diff --git a/src/spikeinterface/postprocessing/tests/test_correlograms.py b/src/spikeinterface/postprocessing/tests/test_correlograms.py index a0863be117..6f2e503f27 100644 --- a/src/spikeinterface/postprocessing/tests/test_correlograms.py +++ b/src/spikeinterface/postprocessing/tests/test_correlograms.py @@ -130,17 +130,21 @@ def test_auto_equal_cross_correlograms(): cc_corrected = cc.copy() cc_corrected[num_half_bins] -= num_spike - breakpoint() + # TODO: why is this bounds shifting behaviour changing now cc vs. ac are represented in + # negative max-lag time bin? - if method == "numpy": - # numpy method have some border effect on left - assert np.array_equal(cc_corrected[1:num_half_bins], ac[1:num_half_bins]) - # numpy method have some problem on center - assert np.array_equal(cc_corrected[num_half_bins + 1 :], ac[num_half_bins + 1 :]) - else: - assert np.array_equal(cc_corrected, ac) + # everything is the same, except - breakpoint() + assert np.array_equal(cc_corrected, ac) + + +# if method == "numpy": +# numpy method have some border effect on left +# assert np.array_equal(cc_corrected[1:], ac[1:]) # ac[1:num_half_bins] +# numpy method have some problem on center +# assert np.array_equal(cc_corrected[num_half_bins + 1 :], ac[num_half_bins + 1 :]) +# else: +# assert np.array_equal(cc_corrected, ac) def test_detect_injected_correlation(): @@ -197,9 +201,9 @@ def test_correlograms_unit(): """ """ sampling_frequency = 30000 - num_filled_bins = 20 + num_filled_bins = 60 - spike_times = np.repeat(np.arange(num_filled_bins), 2) * 0.0051 + spike_times = np.repeat(np.arange(num_filled_bins), 2) * 0.005 # 0.005, 0.0051!!! test both critical for edge case spike_labels = np.zeros(num_filled_bins * 2, dtype=int) spike_labels[::2] = 1 @@ -226,10 +230,18 @@ def test_correlograms_unit(): assert np.array_equal(expected_bins, bins_numpy) assert np.array_equal(expected_bins, bins_numba) - expected_forward_bins = np.r_[np.zeros(int(num_bins / 2 - num_filled_bins - 1)), np.arange(num_filled_bins), 0] + first_bin = np.abs(int(num_bins / 2 - num_filled_bins - 1)) + expected_forward_bins = np.r_[np.zeros(np.max([0, -first_bin])), np.arange(first_bin, num_filled_bins), 0] expected_results = np.r_[expected_forward_bins, np.flip(expected_forward_bins)] + # basically in the edge case of actly on bin, what do we do? we can push left or push right. + # this pushes right. But the new addition is definately a fix, previously it would + # disregard many cases in which the bin was exactly the bottom bin because of + # fencepost error. + + # TODO: tidy up this test, add multi-segment case. Decide which cases to test neatly. for auto_idx in [(0, 0), (1, 1)]: + breakpoint() assert np.array_equal(expected_results, result_numpy[auto_idx]) # TODO: CHECK! assert np.array_equal(expected_results, result_numba[auto_idx]) From 3784c3898ee521b057bc3962fb66e2eecc561cfe Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Wed, 19 Jun 2024 15:08:26 -0600 Subject: [PATCH 10/81] use the value instead of book --- src/spikeinterface/core/base.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/spikeinterface/core/base.py b/src/spikeinterface/core/base.py index 6fbc5ac289..05f59e5349 100644 --- a/src/spikeinterface/core/base.py +++ b/src/spikeinterface/core/base.py @@ -56,7 +56,7 @@ def __init__(self, main_ids: Sequence) -> None: # "main_ids" will either be channel_ids or units_ids # They are used for properties - self._main_ids = np.array(main_ids) + self._main_ids = np.asarray(main_ids) if len(self._main_ids) > 0: assert ( self._main_ids.dtype.kind in "uiSU" @@ -128,8 +128,18 @@ def ids_to_indices( indices = np.arange(len(self._main_ids)) else: assert isinstance(ids, (list, np.ndarray, tuple)), "'ids' must be a list, np.ndarray or tuple" + + non_existent_ids = [id for id in ids if id not in self._main_ids] + if non_existent_ids: + error_msg = ( + f"IDs {non_existent_ids} are not channel ids of the extractor. \n" + f"Available ids are {self._main_ids} with dtype {self._main_ids.dtype}" + ) + raise ValueError(error_msg) + _main_ids = self._main_ids.tolist() - indices = np.array([_main_ids.index(id) for id in ids], dtype=int) + indices = np.array([_main_ids.index(id) for id in ids], dtype=np.int) + if prefer_slice: if np.all(np.diff(indices) == 1): indices = slice(indices[0], indices[-1] + 1) From dd371e0a48d80de22c05b8407f497f49375a5941 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Wed, 19 Jun 2024 22:15:51 +0100 Subject: [PATCH 11/81] Playing a little bit more comparing against old numba version. --- src/spikeinterface/postprocessing/correlograms.py | 15 ++++++++++++--- .../postprocessing/tests/test_correlograms.py | 3 ++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index bea0f780fe..b8484ee44b 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -404,7 +404,7 @@ def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size if sign == -1: mask[:-shift][spike_diff_b < -num_half_bins] = False else: - # spike_diff_b[np.where(spike_diff_b == num_half_bins)] -= 1 + spike_diff_b[np.where(spike_diff_b == num_half_bins)] -= 1 mask[:-shift][spike_diff_b >= num_half_bins] = False m = mask[:-shift] @@ -468,15 +468,24 @@ def compute_correlograms_numba(sorting, window_size, bin_size): spike_times = spikes[seg_index]["sample_index"] spike_labels = spikes[seg_index]["unit_index"] - _compute_correlograms_one_segment_numba( + _compute_correlograms_numba( correlograms, spike_times.astype(np.int64, copy=False), spike_labels.astype(np.int32, copy=False), window_size, bin_size, - num_half_bins, ) + if False: + _compute_correlograms_one_segment_numba( + correlograms, + spike_times.astype(np.int64, copy=False), + spike_labels.astype(np.int32, copy=False), + window_size, + bin_size, + num_half_bins, + ) + return correlograms diff --git a/src/spikeinterface/postprocessing/tests/test_correlograms.py b/src/spikeinterface/postprocessing/tests/test_correlograms.py index 6f2e503f27..c4a15f9fcb 100644 --- a/src/spikeinterface/postprocessing/tests/test_correlograms.py +++ b/src/spikeinterface/postprocessing/tests/test_correlograms.py @@ -237,7 +237,8 @@ def test_correlograms_unit(): # basically in the edge case of actly on bin, what do we do? we can push left or push right. # this pushes right. But the new addition is definately a fix, previously it would # disregard many cases in which the bin was exactly the bottom bin because of - # fencepost error. + # fencepost error. OK both methods now have the same behaviour on the edges + # as the previous numba version. # TODO: tidy up this test, add multi-segment case. Decide which cases to test neatly. for auto_idx in [(0, 0), (1, 1)]: From e2b1a3b734245e696b8e83d73354a62161f8fcff Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Wed, 19 Jun 2024 15:22:41 -0600 Subject: [PATCH 12/81] int went flying --- src/spikeinterface/core/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spikeinterface/core/base.py b/src/spikeinterface/core/base.py index 05f59e5349..a7b250690f 100644 --- a/src/spikeinterface/core/base.py +++ b/src/spikeinterface/core/base.py @@ -138,7 +138,7 @@ def ids_to_indices( raise ValueError(error_msg) _main_ids = self._main_ids.tolist() - indices = np.array([_main_ids.index(id) for id in ids], dtype=np.int) + indices = np.array([_main_ids.index(id) for id in ids], dtype=int) if prefer_slice: if np.all(np.diff(indices) == 1): From 53913633fd9f2ac385e498fc245e25978860db85 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Wed, 19 Jun 2024 23:24:46 +0100 Subject: [PATCH 13/81] Continue hunting for solution to numpy left-bound. --- src/spikeinterface/postprocessing/correlograms.py | 7 ++++++- .../postprocessing/tests/test_correlograms.py | 11 ++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index b8484ee44b..9cb28b2746 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -404,8 +404,13 @@ def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size if sign == -1: mask[:-shift][spike_diff_b < -num_half_bins] = False else: - spike_diff_b[np.where(spike_diff_b == num_half_bins)] -= 1 + # spike_diff_b[np.where(spike_diff_b == num_half_bins)] -= 1 adds to the first AND last bin, which we dont want. mask[:-shift][spike_diff_b >= num_half_bins] = False + # spike_diff_b[spike_diff_b == num_half_bins] = 0 # fills the central bin + # the problem is that we need to mask specific pairs of comparisons + # but this is just masking the entire spike time. + # I still don't understand why removing the bound is leading to error at all, + # it is leading to extra counting. m = mask[:-shift] diff --git a/src/spikeinterface/postprocessing/tests/test_correlograms.py b/src/spikeinterface/postprocessing/tests/test_correlograms.py index c4a15f9fcb..7013ec2d6d 100644 --- a/src/spikeinterface/postprocessing/tests/test_correlograms.py +++ b/src/spikeinterface/postprocessing/tests/test_correlograms.py @@ -197,6 +197,9 @@ def test_detect_injected_correlation(): # 3) some different window_ms and bin_ms. Instead, maybe core utils # can be factored out and segment stuff is handled in a new test. # otherwise, will be too much! + + +# keep the window and bin fixed. test across num filled bins def test_correlograms_unit(): """ """ sampling_frequency = 30000 @@ -242,9 +245,11 @@ def test_correlograms_unit(): # TODO: tidy up this test, add multi-segment case. Decide which cases to test neatly. for auto_idx in [(0, 0), (1, 1)]: - breakpoint() - assert np.array_equal(expected_results, result_numpy[auto_idx]) # TODO: CHECK! - assert np.array_equal(expected_results, result_numba[auto_idx]) + try: + assert np.array_equal(expected_results, result_numpy[auto_idx]) # TODO: CHECK! + assert np.array_equal(expected_results, result_numba[auto_idx]) + except: + breakpoint() expected_results[int(num_bins / 2)] = num_filled_bins for auto_idx in [(1, 0), (0, 1)]: From 45be351223bc421925175b79ca7f23cc21a9d4db Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Thu, 20 Jun 2024 00:12:07 +0100 Subject: [PATCH 14/81] 99% sure numpy version is fixed next doc reasoning. --- .../postprocessing/correlograms.py | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index 9cb28b2746..158897de87 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -403,14 +403,20 @@ def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size # Spikes with no matching spikes are masked. if sign == -1: mask[:-shift][spike_diff_b < -num_half_bins] = False + # mask[:-shift][spike_diff_b == -num_half_bins] = True else: - # spike_diff_b[np.where(spike_diff_b == num_half_bins)] -= 1 adds to the first AND last bin, which we dont want. + # spike_diff_b[np.where(spike_diff_b == num_half_bins)] -= 1 # adds to the first AND last bin, which we dont want. mask[:-shift][spike_diff_b >= num_half_bins] = False - # spike_diff_b[spike_diff_b == num_half_bins] = 0 # fills the central bin - # the problem is that we need to mask specific pairs of comparisons - # but this is just masking the entire spike time. - # I still don't understand why removing the bound is leading to error at all, - # it is leading to extra counting. + + # if np.any(spike_diff_b == num_half_bins): + # breakpoint() + # mask[:-shift][np.where(spike_labels[:-shift][spike_diff_b == num_half_bins] >= num_units - 1)] = False # check indexing, and these are always indexed + # breakpoint() + # spike_diff_b[spike_diff_b == num_half_bins] = 0 # fills the central bin + # the problem is that we need to mask specific pairs of comparisons + # but this is just masking the entire spike time. + # I still don't understand why removing the bound is leading to error at all, + # it is leading to extra counting. m = mask[:-shift] @@ -431,6 +437,9 @@ def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size bbins = np.bincount(indices) correlograms.ravel()[: len(bbins)] += bbins + if sign == 1: + mask[:-shift][spike_diff_b == num_half_bins] = True + shift += 1 return correlograms @@ -473,24 +482,24 @@ def compute_correlograms_numba(sorting, window_size, bin_size): spike_times = spikes[seg_index]["sample_index"] spike_labels = spikes[seg_index]["unit_index"] - _compute_correlograms_numba( + # _compute_correlograms_numba( + # correlograms, + # spike_times.astype(np.int64, copy=False), + # spike_labels.astype(np.int32, copy=False), + # window_size, + # bin_size, + # ) + + # if False: + _compute_correlograms_one_segment_numba( correlograms, spike_times.astype(np.int64, copy=False), spike_labels.astype(np.int32, copy=False), window_size, bin_size, + num_half_bins, ) - if False: - _compute_correlograms_one_segment_numba( - correlograms, - spike_times.astype(np.int64, copy=False), - spike_labels.astype(np.int32, copy=False), - window_size, - bin_size, - num_half_bins, - ) - return correlograms From 4ecc16482ae8850be2a3f8fdebfade0d28eda7f2 Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Wed, 19 Jun 2024 18:04:26 -0600 Subject: [PATCH 15/81] add scale to microvolts --- src/spikeinterface/preprocessing/preprocessinglist.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/spikeinterface/preprocessing/preprocessinglist.py b/src/spikeinterface/preprocessing/preprocessinglist.py index 1b28be9752..0c2ca0cb9a 100644 --- a/src/spikeinterface/preprocessing/preprocessinglist.py +++ b/src/spikeinterface/preprocessing/preprocessinglist.py @@ -24,6 +24,8 @@ CenterRecording, center, ) +from .scale import ScaleTouV, scale_to_uV + from .whiten import WhitenRecording, whiten, compute_whitening_matrix from .rectify import RectifyRecording, rectify from .clip import BlankSaturationRecording, blank_staturation, ClipRecording, clip @@ -54,6 +56,7 @@ ScaleRecording, CenterRecording, ZScoreRecording, + ScaleTouV, # decorrelation stuff WhitenRecording, # re-reference From 3dbb8c104dfeb942bfb5ce17f65d3b3b8c1a962c Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Wed, 19 Jun 2024 18:11:43 -0600 Subject: [PATCH 16/81] added untracked files, ups --- src/spikeinterface/preprocessing/scale.py | 46 +++++++++++++++++++ .../preprocessing/tests/test_scaling.py | 35 ++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 src/spikeinterface/preprocessing/scale.py create mode 100644 src/spikeinterface/preprocessing/tests/test_scaling.py diff --git a/src/spikeinterface/preprocessing/scale.py b/src/spikeinterface/preprocessing/scale.py new file mode 100644 index 0000000000..a8837010ea --- /dev/null +++ b/src/spikeinterface/preprocessing/scale.py @@ -0,0 +1,46 @@ +from __future__ import annotations + +from spikeinterface.core import BaseRecording +from spikeinterface.preprocessing.basepreprocessor import BasePreprocessor + + +class ScaleTouV(BasePreprocessor): + """ + Scale raw traces to microvolts (µV). + + This preprocessor uses the channel-specific gain and offset information + stored in the recording extractor to convert the raw traces to µV units. + + Parameters + ---------- + recording : BaseRecording + The recording extractor to be scaled. The recording extractor must + have gains and offsets otherwise an error will be raised. + + Raises + ------ + AssertionError + If the recording extractor does not have scaleable traces. + """ + + name = "scale_to_uV" + + def __init__(self, recording: BaseRecording): + assert recording.has_scaleable_traces(), "Recording must have scaleable traces" + from spikeinterface.preprocessing.normalize_scale import ScaleRecordingSegment + + dtype = recording.get_dtype() + BasePreprocessor.__init__(self, recording, dtype=dtype) + + gain = recording.get_channel_gains()[None, :] + offset = recording.get_channel_offsets()[None, :] + for parent_segment in recording._recording_segments: + rec_segment = ScaleRecordingSegment(parent_segment, gain, offset, self._dtype) + self.add_recording_segment(rec_segment) + + self._kwargs = dict( + recording=recording, + ) + + +scale_to_uV = ScaleTouV diff --git a/src/spikeinterface/preprocessing/tests/test_scaling.py b/src/spikeinterface/preprocessing/tests/test_scaling.py new file mode 100644 index 0000000000..39fe3d0ddc --- /dev/null +++ b/src/spikeinterface/preprocessing/tests/test_scaling.py @@ -0,0 +1,35 @@ +import pytest +import numpy as np +from spikeinterface.core.testing_tools import generate_recording +from spikeinterface.preprocessing import ScaleTouV # Replace 'your_module' with your actual module name + + +def test_scale_to_uv(): + # Create a sample recording extractor with fake gains and offsets + num_channels = 4 + sampling_frequency = 30_000.0 + durations = [1] # seconds + recording = generate_recording( + num_channels=num_channels, + durations=durations, + sampling_frequency=sampling_frequency, + ) + + gains = np.ones(shape=(num_channels)) + offsets = np.zeros(shape=(num_channels)) + recording.set_channel_gains(gains) # Random gains + recording.set_channel_offsets(offsets) # Random offsets + + # Apply the preprocessor + scaled_recording = ScaleTouV(recording=recording) + + # Check if the traces are indeed scaled + expected_traces = recording.get_traces(return_scaled=True) + scaled_traces = scaled_recording.get_traces() + + np.testing.assert_allclose(scaled_traces, expected_traces) + + # Test for the error when recording doesn't have scaleable traces + recording.set_channel_gains(None) # Remove gains to make traces unscaleable + with pytest.raises(AssertionError): + ScaleTouV(recording) From be59dbe4413610f0212ded90dbde63b4da234e4d Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Wed, 19 Jun 2024 18:30:06 -0600 Subject: [PATCH 17/81] add more personality to the test --- src/spikeinterface/preprocessing/tests/test_scaling.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/spikeinterface/preprocessing/tests/test_scaling.py b/src/spikeinterface/preprocessing/tests/test_scaling.py index 39fe3d0ddc..6dbc66591f 100644 --- a/src/spikeinterface/preprocessing/tests/test_scaling.py +++ b/src/spikeinterface/preprocessing/tests/test_scaling.py @@ -15,10 +15,11 @@ def test_scale_to_uv(): sampling_frequency=sampling_frequency, ) - gains = np.ones(shape=(num_channels)) - offsets = np.zeros(shape=(num_channels)) - recording.set_channel_gains(gains) # Random gains - recording.set_channel_offsets(offsets) # Random offsets + rng = np.random.default_rng(0) + gains = rng.random(size=(num_channels)).astype(np.float32) + offsets = rng.random(size=(num_channels)).astype(np.float32) + recording.set_channel_gains(gains) + recording.set_channel_offsets(offsets) # Apply the preprocessor scaled_recording = ScaleTouV(recording=recording) From a98e81af11f06c0ee47338b42e3132964f558d76 Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Thu, 20 Jun 2024 07:59:59 -0600 Subject: [PATCH 18/81] name changing --- src/spikeinterface/preprocessing/preprocessinglist.py | 4 ++-- src/spikeinterface/preprocessing/scale.py | 4 ++-- src/spikeinterface/preprocessing/tests/test_scaling.py | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/spikeinterface/preprocessing/preprocessinglist.py b/src/spikeinterface/preprocessing/preprocessinglist.py index 0c2ca0cb9a..7fc3bc0685 100644 --- a/src/spikeinterface/preprocessing/preprocessinglist.py +++ b/src/spikeinterface/preprocessing/preprocessinglist.py @@ -24,7 +24,7 @@ CenterRecording, center, ) -from .scale import ScaleTouV, scale_to_uV +from .scale import ScaleTouVRecording, scale_to_uV from .whiten import WhitenRecording, whiten, compute_whitening_matrix from .rectify import RectifyRecording, rectify @@ -56,7 +56,7 @@ ScaleRecording, CenterRecording, ZScoreRecording, - ScaleTouV, + ScaleTouVRecording, # decorrelation stuff WhitenRecording, # re-reference diff --git a/src/spikeinterface/preprocessing/scale.py b/src/spikeinterface/preprocessing/scale.py index a8837010ea..99acd49981 100644 --- a/src/spikeinterface/preprocessing/scale.py +++ b/src/spikeinterface/preprocessing/scale.py @@ -4,7 +4,7 @@ from spikeinterface.preprocessing.basepreprocessor import BasePreprocessor -class ScaleTouV(BasePreprocessor): +class ScaleTouVRecording(BasePreprocessor): """ Scale raw traces to microvolts (µV). @@ -43,4 +43,4 @@ def __init__(self, recording: BaseRecording): ) -scale_to_uV = ScaleTouV +scale_to_uV = ScaleTouVRecording diff --git a/src/spikeinterface/preprocessing/tests/test_scaling.py b/src/spikeinterface/preprocessing/tests/test_scaling.py index 6dbc66591f..e66d36c613 100644 --- a/src/spikeinterface/preprocessing/tests/test_scaling.py +++ b/src/spikeinterface/preprocessing/tests/test_scaling.py @@ -1,7 +1,7 @@ import pytest import numpy as np from spikeinterface.core.testing_tools import generate_recording -from spikeinterface.preprocessing import ScaleTouV # Replace 'your_module' with your actual module name +from spikeinterface.preprocessing import ScaleTouVRecording # Replace 'your_module' with your actual module name def test_scale_to_uv(): @@ -22,7 +22,7 @@ def test_scale_to_uv(): recording.set_channel_offsets(offsets) # Apply the preprocessor - scaled_recording = ScaleTouV(recording=recording) + scaled_recording = ScaleTouVRecording(recording=recording) # Check if the traces are indeed scaled expected_traces = recording.get_traces(return_scaled=True) @@ -33,4 +33,4 @@ def test_scale_to_uv(): # Test for the error when recording doesn't have scaleable traces recording.set_channel_gains(None) # Remove gains to make traces unscaleable with pytest.raises(AssertionError): - ScaleTouV(recording) + ScaleTouVRecording(recording) From 763f26639a48cf6c6708a4583e6baf982edb8825 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Thu, 20 Jun 2024 15:31:08 +0100 Subject: [PATCH 19/81] Add fix for left bin edge problem in numpy implementation. --- .../postprocessing/correlograms.py | 20 ++++++++----------- .../postprocessing/tests/test_correlograms.py | 9 ++++++--- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index 158897de87..10b4fe3f19 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -403,21 +403,9 @@ def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size # Spikes with no matching spikes are masked. if sign == -1: mask[:-shift][spike_diff_b < -num_half_bins] = False - # mask[:-shift][spike_diff_b == -num_half_bins] = True else: - # spike_diff_b[np.where(spike_diff_b == num_half_bins)] -= 1 # adds to the first AND last bin, which we dont want. mask[:-shift][spike_diff_b >= num_half_bins] = False - # if np.any(spike_diff_b == num_half_bins): - # breakpoint() - # mask[:-shift][np.where(spike_labels[:-shift][spike_diff_b == num_half_bins] >= num_units - 1)] = False # check indexing, and these are always indexed - # breakpoint() - # spike_diff_b[spike_diff_b == num_half_bins] = 0 # fills the central bin - # the problem is that we need to mask specific pairs of comparisons - # but this is just masking the entire spike time. - # I still don't understand why removing the bound is leading to error at all, - # it is leading to extra counting. - m = mask[:-shift] # Find the indices in the raveled correlograms array that need @@ -438,6 +426,14 @@ def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size correlograms.ravel()[: len(bbins)] += bbins if sign == 1: + # For positive sign, the end bin is < num_half_bins (e.g. + # bin = 29, num_half_bins = 30, will go to index 59 (i.e. the + # last bin). For negative sign, the first bin is == num_half_bins + # e.g. bin = -30, with num_half_bins = 30 will go to bin 0. Therefore + # sign == 1 must mask spike_diff_b <= num_half_bins but sign == -1 + # must count all (possibly repeating across units) cases of + # spike_diff_b == num_half_bins. So we turn it back on here + # for the next loop that starts with the -1 case. mask[:-shift][spike_diff_b == num_half_bins] = True shift += 1 diff --git a/src/spikeinterface/postprocessing/tests/test_correlograms.py b/src/spikeinterface/postprocessing/tests/test_correlograms.py index 7013ec2d6d..a4329bd690 100644 --- a/src/spikeinterface/postprocessing/tests/test_correlograms.py +++ b/src/spikeinterface/postprocessing/tests/test_correlograms.py @@ -205,10 +205,13 @@ def test_correlograms_unit(): sampling_frequency = 30000 num_filled_bins = 60 + num_units = 3 - spike_times = np.repeat(np.arange(num_filled_bins), 2) * 0.005 # 0.005, 0.0051!!! test both critical for edge case - spike_labels = np.zeros(num_filled_bins * 2, dtype=int) - spike_labels[::2] = 1 + spike_times = ( + np.repeat(np.arange(num_filled_bins), num_units) * 0.005 + ) # 0.005, 0.0051!!! test both critical for edge case + # spike_labels = np.zeros(num_filled_bins * num_units, dtype=int) + spike_labels = np.tile(np.arange(num_units), int(spike_times.size / num_units)) spike_times *= sampling_frequency spike_times = spike_times.astype(int) From 0d252d805899994cb3a1e9fb7291b21350ffedee Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Thu, 20 Jun 2024 20:23:02 +0100 Subject: [PATCH 20/81] Fix up and add docstrings to final tests. --- .../postprocessing/correlograms.py | 27 +- .../tests/common_extension_tests.py | 1 + .../postprocessing/tests/test_correlograms.py | 384 +++++++++++------- 3 files changed, 261 insertions(+), 151 deletions(-) diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index 10b4fe3f19..4349d88152 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -277,9 +277,9 @@ def compute_correlograms_on_sorting(sorting, window_ms, bin_ms, method="auto"): ---------- sorting : Sorting A SpikeInterface Sorting object - window_ms : int + window_ms : float The window size over which to perform the cross-correlation, in ms - bin_ms : int + bin_ms : float The size of which to bin lags, in ms. method : str To use "numpy" or "numba". "auto" will use numba if available, @@ -388,8 +388,8 @@ def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size # within the correlogram time window. mask = np.ones_like(spike_times, dtype="bool") - # The loop continues as long as there is at least one spike with - # a matching spike. + # The loop continues as long as there is at least one + # spike with a matching spike. shift = 1 while mask[:-shift].any(): # Number of time samples between spike i and spike i+shift. @@ -501,11 +501,11 @@ def compute_correlograms_numba(sorting, window_size, bin_size): if HAVE_NUMBA: - # @numba.jit( - # nopython=True, - # nogil=True, - # cache=False, - # ) + @numba.jit( + nopython=True, + nogil=True, + cache=False, + ) def _compute_correlograms_one_segment_numba( correlograms, spike_times, spike_labels, window_size, bin_size, num_half_bins ): @@ -546,12 +546,15 @@ def _compute_correlograms_one_segment_numba( diff = spike_times[i] - spike_times[j] - # if the time of spike i is more than window size later than - # spike j, then spike i + 1 will also be more than a window size - # later than spike j. Iterate the start_j and check the next spike. + # When the diff is exactly the window size, keep going + # without iterating start_j in case this spike also has + # other diffs with other units that == window size. if diff == window_size: continue + # if the time of spike i is more than window size later than + # spike j, then spike i + 1 will also be more than a window size + # later than spike j. Iterate the start_j and check the next spike. if diff > window_size: start_j += 1 continue diff --git a/src/spikeinterface/postprocessing/tests/common_extension_tests.py b/src/spikeinterface/postprocessing/tests/common_extension_tests.py index c99b2d4f3b..15eea06ae2 100644 --- a/src/spikeinterface/postprocessing/tests/common_extension_tests.py +++ b/src/spikeinterface/postprocessing/tests/common_extension_tests.py @@ -77,6 +77,7 @@ class instance is used for each. In this case, we have to set ) self.__class__.cache_folder = create_cache_folder + # TODO: can delete this!!! def _prepare_sorting_analyzer(self, format, sparse, extension_class): """ Prepare a SortingAnalyzer object with dependencies already computed diff --git a/src/spikeinterface/postprocessing/tests/test_correlograms.py b/src/spikeinterface/postprocessing/tests/test_correlograms.py index a4329bd690..24b63a0535 100644 --- a/src/spikeinterface/postprocessing/tests/test_correlograms.py +++ b/src/spikeinterface/postprocessing/tests/test_correlograms.py @@ -7,7 +7,6 @@ except ModuleNotFoundError as err: HAVE_NUMBA = False - from spikeinterface import NumpySorting, generate_sorting from spikeinterface.postprocessing.tests.common_extension_tests import AnalyzerExtensionCommonTestSuite from spikeinterface.postprocessing import ComputeCorrelograms @@ -16,8 +15,10 @@ _make_bins, compute_correlograms, ) -from spikeinterface.core import NumpySorting import pytest +from pytest import param + +SKIP_NUMBA = pytest.mark.skipif(not HAVE_NUMBA, reason="Numba not available") class TestComputeCorrelograms(AnalyzerExtensionCommonTestSuite): @@ -27,17 +28,37 @@ class TestComputeCorrelograms(AnalyzerExtensionCommonTestSuite): [ dict(method="numpy"), dict(method="auto"), - pytest.param(dict(method="numba"), marks=pytest.mark.skipif(not HAVE_NUMBA, reason="Numba not available")), + param(dict(method="numba"), marks=SKIP_NUMBA), ], ) def test_extension(self, params): self.run_extension_tests(ComputeCorrelograms, params) + @pytest.mark.parametrize("method", ["numpy", param("numba", marks=SKIP_NUMBA)]) + def test_sortinganalyzer_correlograms(self, method): + """ + Test the outputs when using SortingAnalyzer against + the output passing sorting directly to `compute_correlograms`. + Sorting to `compute_correlograms` is tested extensively below + so if these match it means `SortingAnalyzer` is working. + """ + sorting_analyzer = self._prepare_sorting_analyzer("memory", sparse=False, extension_class=ComputeCorrelograms) + + params = dict(method=method, window_ms=100, bin_ms=6.5) + ext_numpy = sorting_analyzer.compute(ComputeCorrelograms.extension_name, **params) + + result_sorting, bins_sorting = compute_correlograms(self.sorting, **params) + assert np.array_equal(result_sorting, ext_numpy.data["ccgs"]) + assert np.array_equal(bins_sorting, ext_numpy.data["bins"]) + + +# Unit Tests +############ def test_make_bins(): """ Check the `_make_bins()` function that generates time bins (lags) for - the correllogram creates the expected number of bins. + the correlogram creates the expected number of bins. """ sorting = generate_sorting(num_units=5, sampling_frequency=30000.0, durations=[10.325, 3.5], seed=0) @@ -50,113 +71,78 @@ def test_make_bins(): bin_ms = 2.0 bins, window_size, bin_size = _make_bins(sorting, window_ms, bin_ms) assert bins.size == np.floor(window_ms / bin_ms) + 1 + assert np.array_equal(bins, np.linspace(-30, 30, bins.size)) - breakpoint() - # TODO: add an exact test - - -# TODO: remove in favour of below -def _test_correlograms(sorting, window_ms, bin_ms, methods): - for method in methods: - correlograms, bins = compute_correlograms_on_sorting(sorting, window_ms=window_ms, bin_ms=bin_ms, method=method) - if method == "numpy": - ref_bins = bins - ref_correlograms = correlograms - else: - assert np.all(correlograms == ref_correlograms), f"Failed with method={method}" - assert np.allclose(bins, ref_bins, atol=1e-10), f"Failed with method={method}" +@pytest.mark.skipif(not HAVE_NUMBA, reason="Numba not available") +@pytest.mark.parametrize("window_and_bin_ms", [(60.0, 2.0), (3.57, 1.6421)]) +def test_equal_results_correlograms(window_and_bin_ms): + """ + Test that the 2 methods have same results with some varied time bins + that are not tested in other tests. + """ -# TODO: remove in favour of below -def test_equal_results_correlograms(): - # compare that the 2 methods have same results - methods = ["numpy"] - if HAVE_NUMBA: - methods.append("numba") - + window_ms, bin_ms = window_and_bin_ms sorting = generate_sorting(num_units=5, sampling_frequency=30000.0, durations=[10.325, 3.5], seed=0) - _test_correlograms(sorting, window_ms=60.0, bin_ms=2.0, methods=methods) - _test_correlograms(sorting, window_ms=43.57, bin_ms=1.6421, methods=methods) + result_numpy, bins_numpy = compute_correlograms_on_sorting( + sorting, window_ms=window_ms, bin_ms=bin_ms, method="numpy" + ) + result_numba, bins_numba = compute_correlograms_on_sorting( + sorting, window_ms=window_ms, bin_ms=bin_ms, method="numba" + ) + + assert np.array_equal(result_numpy, result_numba) + assert np.array_equal(result_numpy, result_numba) -def test_flat_cross_correlogram(): +@pytest.mark.parametrize("method", ["numpy", param("numba", marks=SKIP_NUMBA)]) +def test_flat_cross_correlogram(method): """ Check that the correlogram (num_units x num_units x num_bins) does not vary too much across time bins (lags), for entries representing two different units. """ sorting = generate_sorting(num_units=2, sampling_frequency=10000.0, durations=[100000.0], seed=0) - methods = ["numpy"] - if HAVE_NUMBA: - methods.append("numba") + correlograms, bins = compute_correlograms_on_sorting(sorting, window_ms=50.0, bin_ms=1.0, method=method) + cc = correlograms[0, 1, :].copy() + m = np.mean(cc) - for method in methods: - correlograms, bins = compute_correlograms_on_sorting(sorting, window_ms=50.0, bin_ms=1.0, method=method) - cc = correlograms[0, 1, :].copy() - m = np.mean(cc) - assert np.all(cc > (m * 0.90)) - assert np.all(cc < (m * 1.10)) + assert np.all(cc > (m * 0.90)) + assert np.all(cc < (m * 1.10)) -# TODO: maybe deprecate in favour of the new test as it does test -# similar thing, but check the border effects... -def test_auto_equal_cross_correlograms(): +@pytest.mark.parametrize("method", ["numpy", param("numba", marks=SKIP_NUMBA)]) +def test_auto_equal_cross_correlograms(method): """ - check if cross correlogram is the same as autocorrelogram + Check if cross correlogram is the same as autocorrelogram by removing n spike in bin zeros - numpy method: - * have problem for the left bin - * have problem on center """ - - methods = ["numpy"] - if HAVE_NUMBA: - methods.append("numba") - num_spike = 2000 spike_times = np.sort(np.unique(np.random.randint(0, 100000, num_spike))) num_spike = spike_times.size units_dict = {"1": spike_times, "2": spike_times} sorting = NumpySorting.from_unit_dict([units_dict], sampling_frequency=10000.0) - for method in methods: - correlograms, bins = compute_correlograms_on_sorting(sorting, window_ms=10.0, bin_ms=0.1, method=method) - - num_half_bins = correlograms.shape[2] // 2 - - cc = correlograms[0, 1, :] - ac = correlograms[0, 0, :] - cc_corrected = cc.copy() - cc_corrected[num_half_bins] -= num_spike + correlograms, bins = compute_correlograms_on_sorting(sorting, window_ms=10.0, bin_ms=0.1, method=method) - # TODO: why is this bounds shifting behaviour changing now cc vs. ac are represented in - # negative max-lag time bin? + num_half_bins = correlograms.shape[2] // 2 - # everything is the same, except + cc = correlograms[0, 1, :] + ac = correlograms[0, 0, :] + cc_corrected = cc.copy() + cc_corrected[num_half_bins] -= num_spike - assert np.array_equal(cc_corrected, ac) + assert np.array_equal(cc_corrected, ac) -# if method == "numpy": -# numpy method have some border effect on left -# assert np.array_equal(cc_corrected[1:], ac[1:]) # ac[1:num_half_bins] -# numpy method have some problem on center -# assert np.array_equal(cc_corrected[num_half_bins + 1 :], ac[num_half_bins + 1 :]) -# else: -# assert np.array_equal(cc_corrected, ac) - - -def test_detect_injected_correlation(): +@pytest.mark.parametrize("method", ["numpy", param("numba", marks=SKIP_NUMBA)]) +def test_detect_injected_correlation(method): """ Inject 1.44 ms of correlation every 13 spikes and compute cross-correlation. Check that the time bin lag with the peak correlation lag is 1.44 ms (within tolerance of a sampling period). """ - methods = ["numpy"] - if HAVE_NUMBA: - methods.append("numba") - sampling_frequency = 10000.0 num_spike = 2000 rng = np.random.default_rng(seed=0) @@ -165,6 +151,7 @@ def test_detect_injected_correlation(): n = min(spike_times1.size, spike_times2.size) spike_times1 = spike_times1[:n] spike_times2 = spike_times2[:n] + # inject 1.44 ms correlation every 13 spikes injected_delta_ms = 1.44 spike_times2[::13] = spike_times1[::13] + int(injected_delta_ms / 1000 * sampling_frequency) @@ -173,88 +160,207 @@ def test_detect_injected_correlation(): units_dict = {"1": spike_times1, "2": spike_times2} sorting = NumpySorting.from_unit_dict([units_dict], sampling_frequency=sampling_frequency) - for method in methods: - correlograms, bins = compute_correlograms_on_sorting(sorting, window_ms=10.0, bin_ms=0.1, method=method) + correlograms, bins = compute_correlograms_on_sorting(sorting, window_ms=10.0, bin_ms=0.1, method=method) - cc_01 = correlograms[0, 1, :] - cc_10 = correlograms[1, 0, :] + cc_01 = correlograms[0, 1, :] + cc_10 = correlograms[1, 0, :] - peak_location_01_ms = bins[np.argmax(cc_01)] - peak_location_02_ms = bins[np.argmax(cc_10)] + peak_location_01_ms = bins[np.argmax(cc_01)] + peak_location_02_ms = bins[np.argmax(cc_10)] - sampling_period_ms = 1000.0 / sampling_frequency - assert abs(peak_location_01_ms) - injected_delta_ms < sampling_period_ms - assert abs(peak_location_02_ms) - injected_delta_ms < sampling_period_ms + sampling_period_ms = 1000.0 / sampling_frequency + assert abs(peak_location_01_ms) - injected_delta_ms < sampling_period_ms + assert abs(peak_location_02_ms) - injected_delta_ms < sampling_period_ms -# TODO: test one segment, test multi-segment with / without set_times -# indeed, test with one segment here. +# Functional Tests +################### +@pytest.mark.parametrize("overflow_edges", [True, False]) +@pytest.mark.parametrize("on_time_bin", [True, False]) +@pytest.mark.parametrize("multi_segment", [True, False]) +def test_compute_correlograms(overflow_edges, on_time_bin, multi_segment): + """ + Test the entry function `compute_correlograms` under a variety of conditions. + For specifics of `overflow_edges` and `on_time_bin` see `generate_correlogram_test_dataset()`. + This function tests numpy and numba in one go, to avoid over-parameterising the method. + It tests both a single-segment and multi-segment dataset. The way that segments are + handled for the correlogram is to combine counts across all segments, therefore the + counts should double when two segments with identical spike times / labels are used. + """ + sampling_frequency = 30000 + window_ms, bin_ms, spike_times, spike_labels, expected_bins, expected_result_auto, expected_result_corr = ( + generate_correlogram_test_dataset(sampling_frequency, overflow_edges, on_time_bin) + ) -# parameterize over: -# 1) the multi-segment case (all counts should be doubled) -# 2) mutli-segment with set_times -# 3) some different window_ms and bin_ms. Instead, maybe core utils -# can be factored out and segment stuff is handled in a new test. -# otherwise, will be too much! + if multi_segment: + sorting = NumpySorting.from_times_labels( + times_list=[spike_times], labels_list=[spike_labels], sampling_frequency=sampling_frequency + ) + else: + sorting = NumpySorting.from_times_labels( + times_list=[spike_times, spike_times], + labels_list=[spike_labels, spike_labels], + sampling_frequency=sampling_frequency, + ) + expected_result_auto *= 2 + expected_result_corr *= 2 + + result_numba, bins_numba = compute_correlograms(sorting, window_ms=window_ms, bin_ms=bin_ms, method="numba") + result_numpy, bins_numpy = compute_correlograms(sorting, window_ms=window_ms, bin_ms=bin_ms, method="numpy") + for auto_idx in [(0, 0), (1, 1), (2, 2)]: + assert np.array_equal(expected_result_auto, result_numpy[auto_idx]) + assert np.array_equal(expected_result_auto, result_numba[auto_idx]) -# keep the window and bin fixed. test across num filled bins -def test_correlograms_unit(): - """ """ - sampling_frequency = 30000 + for auto_idx in [(1, 0), (0, 1), (0, 2), (2, 0), (1, 2), (2, 1)]: + assert np.array_equal(expected_result_corr, result_numpy[auto_idx]) + assert np.array_equal(expected_result_corr, result_numba[auto_idx]) - num_filled_bins = 60 - num_units = 3 - spike_times = ( - np.repeat(np.arange(num_filled_bins), num_units) * 0.005 - ) # 0.005, 0.0051!!! test both critical for edge case - # spike_labels = np.zeros(num_filled_bins * num_units, dtype=int) - spike_labels = np.tile(np.arange(num_units), int(spike_times.size / num_units)) +@pytest.mark.parametrize("method", ["numpy", param("numba", marks=SKIP_NUMBA)]) +def test_compute_correlograms_different_units(method): + """ + Make a supplementary test to `test_compute_correlograms` in which all + units had the same spike train. Test here a simpler and accessible + test case with only two neurons with different spike time differences + within and across units. + + This case is simple enough to validate by hand, for example for the + result[1, 1] case we are looking at the autocorrelogram of the unit '1'. + The spike times are 4 and 16 s, therefore we expect to see a count in + the +/- 10 to 15 s bin. + """ + sampling_frequency = 30000 + spike_times = np.array([0, 4, 8, 16]) / 1000 * sampling_frequency + spike_times.astype(int) - spike_times *= sampling_frequency - spike_times = spike_times.astype(int) + spike_labels = np.array([0, 1, 0, 1]) - window_ms = 300 + window_ms = 40 bin_ms = 5 - num_bins, check_even_divide = np.divmod(window_ms, bin_ms) - assert check_even_divide == 0, "the test bin_ms must evenly divide the window_ms" - sorting = NumpySorting.from_times_labels( times_list=[spike_times], labels_list=[spike_labels], sampling_frequency=sampling_frequency ) - result_numba, bins_numba = compute_correlograms( # TODO: handle the case with set_times! - sorting, window_ms=window_ms, bin_ms=bin_ms, method="numba" - ) - result_numpy, bins_numpy = compute_correlograms(sorting, window_ms=window_ms, bin_ms=bin_ms, method="numpy") + result, bins = compute_correlograms(sorting, window_ms=window_ms, bin_ms=bin_ms, method=method) + + assert np.array_equal(result[0, 0], np.array([0, 0, 1, 0, 0, 1, 0, 0])) + + assert np.array_equal(result[1, 1], np.array([0, 1, 0, 0, 0, 0, 1, 0])) + + assert np.array_equal(result[1, 0], np.array([0, 0, 0, 1, 1, 1, 0, 1])) + + assert np.array_equal(result[0, 1], np.array([1, 0, 1, 1, 1, 0, 0, 0])) + + +def generate_correlogram_test_dataset(sampling_frequency, overflow_edges, on_time_bin): + """ + This generates a detailed correlogram test and expected outputs, for a number of + test cases: + + overflow edges : when there are counts expected in every measured bins, otherwise + counts are expected only in a (central) subset of bins. + on_time_bin : if `True`, the difference in spike times are created to land + exactly as multiples of the bin size, an edge case that caused + some problems in previous iterations of the algorithm. + + The approach used is to create a set of spike times which are + multiples of a 'base_diff_time'. When `on_time_bin` is `False` this is + set to 5.1 ms. So, we have spikes at: + 5.1 ms, 10.2 ms, 15.3 ms, ..., base_diff_time * num_filled_bins + + This means consecutive spike times are 5.1 ms apart. Then every two + spike times are 10.2 ms apart. This gives predictable bin counts, + that are maximal at the smaller bins (e.g. 5-10 s) and minimal at + the later bins (e.g. 100-105 s). When `on_time_bin` is `False`, + we expect that bin counts will increase from the edge of the bins + to the middle, maximum in the middle, 0 in the exact center (-5 to 0, 0 to 5) + and then decreasing until the end of the bin. For the autocorrelation, the zero-lag + case is not included and the two central bins will be zero. + + Different units are tested by repeating the spike times. This means all + results for all units autocorrelation and cross-correlation will be + identical, simplifying the tests. The only difference is that auto-correlation + does not count the zero-lag bins but cross-correlation does. Because the + spike times are identical, this means in the cross-correlation case we have + `num_filled_bins` in the central bin. By convention, this is always put + in the positive (i.e. 0-5 s) not negative (-5 to 0 s) bin. I guess it + could make sense to force it into both positive and negative bins? + + Finally, the case when the time differences are exactly the bin + size is tested. In this case the spike times are [0, 5, 10, 15, ...] + with all diffs 5 and the `bin_ms` set to 5. By convention, when spike + diffs hit the bin edge they are set into the 'right' (i.e. positive) + bin. For positive bins this does not change, but for negative bins + all entires are shifted one place to the right. + """ + num_units = 3 + + # These give us 61 bins, [-150, -145,...,0,...,145, 150] + window_ms = 300 + bin_ms = 5 + + # If overflow edges, we will have a diff at every possible + # bin e.g. the counts will be [31, 30, ..., 30, 31]. If not, + # test the case where there are zero bins e.g. [0, 0, 9, 8, ..., 8, 9, 0, 0]. + if overflow_edges: + num_filled_bins = 60 + else: + num_filled_bins = 10 + + # If we are on a time bin, make the time delays exactly + # the same as a time bin, testing this tricky edge case. + if on_time_bin: + base_diff_time = bin_ms / 1000 + else: + base_diff_time = bin_ms / 1000 + 0.0001 # i.e. 0.0051 s + + # Now, make a set of times that increase by `base_diff_time` e.g. + # if base_diff_time=0.0051 then our spike times are [`0.0051, 0.0102, ...]` + spike_times = np.repeat(np.arange(num_filled_bins), num_units) * base_diff_time + spike_labels = np.tile(np.arange(num_units), int(spike_times.size / num_units)) + + spike_times *= sampling_frequency + spike_times = spike_times.astype(int) + + # Here generate the expected results. This is done pretty much hard-coded + # to be as explicit as possible. + # Generate the expected bins + num_bins = int(window_ms / bin_ms) + assert window_ms == 300, "dont change the window_ms" + assert bin_ms == 5, "dont change the bin_ms" expected_bins = np.linspace(-150, 150, num_bins + 1) - assert np.array_equal(expected_bins, bins_numpy) - assert np.array_equal(expected_bins, bins_numba) - - first_bin = np.abs(int(num_bins / 2 - num_filled_bins - 1)) - expected_forward_bins = np.r_[np.zeros(np.max([0, -first_bin])), np.arange(first_bin, num_filled_bins), 0] - expected_results = np.r_[expected_forward_bins, np.flip(expected_forward_bins)] - - # basically in the edge case of actly on bin, what do we do? we can push left or push right. - # this pushes right. But the new addition is definately a fix, previously it would - # disregard many cases in which the bin was exactly the bottom bin because of - # fencepost error. OK both methods now have the same behaviour on the edges - # as the previous numba version. - - # TODO: tidy up this test, add multi-segment case. Decide which cases to test neatly. - for auto_idx in [(0, 0), (1, 1)]: - try: - assert np.array_equal(expected_results, result_numpy[auto_idx]) # TODO: CHECK! - assert np.array_equal(expected_results, result_numba[auto_idx]) - except: - breakpoint() - - expected_results[int(num_bins / 2)] = num_filled_bins - for auto_idx in [(1, 0), (0, 1)]: - assert np.array_equal(expected_results, result_numpy[auto_idx]) # TODO: CHECK! - assert np.array_equal(expected_results, result_numba[auto_idx]) + # In this case, all time bins are shifted to the right for the + # negative shift due to the diffs lying on the bin edge. + # [30, 31, ..., 59, 0, 59, ..., 30, 31] + if overflow_edges and on_time_bin: + expected_result_auto = np.r_[np.arange(30, 60), 0, np.flip(np.arange(31, 60))] + + # In this case there are no edge effects and the bin counts + # [31, 30, ..., 59, 0, 0, 59, ..., 30, 31] + # are symmetrical + elif overflow_edges and not on_time_bin: + forward = np.r_[np.arange(31, 60), 0] + expected_result_auto = np.r_[forward, np.flip(forward)] + + # Here we have many zero bins, but the existing bins are + # shifted left in the negative-bin base + # [0, 0, ..., 1, 2, 3, ..., 10, 0, 10, ..., 3, 2, 1, ..., 0] + elif not overflow_edges and on_time_bin: + forward = np.r_[np.zeros(19), np.arange(10)] + expected_result_auto = np.r_[0, forward, 0, np.flip(forward)] + + # Here we have many zero bins and they are symmetrical + # [0, 0, ..., 1, 2, 3, ..., 10, 0, 10, ..., 3, 2, 1, ..., 0, 0] + elif not overflow_edges and not on_time_bin: + forward = np.r_[np.zeros(19), np.arange(10), 0] + expected_result_auto = np.r_[forward, np.flip(forward)] + + expected_result_corr = expected_result_auto.copy() + expected_result_corr[int(num_bins / 2)] = num_filled_bins + + return window_ms, bin_ms, spike_times, spike_labels, expected_bins, expected_result_auto, expected_result_corr From f36d95b548194b821c10ea6310d5c6b798cace57 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Thu, 20 Jun 2024 20:24:56 +0100 Subject: [PATCH 21/81] Remove old numba implementation. --- .../postprocessing/correlograms.py | 86 ------------------- 1 file changed, 86 deletions(-) diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index 4349d88152..e371ebbf5a 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -478,15 +478,6 @@ def compute_correlograms_numba(sorting, window_size, bin_size): spike_times = spikes[seg_index]["sample_index"] spike_labels = spikes[seg_index]["unit_index"] - # _compute_correlograms_numba( - # correlograms, - # spike_times.astype(np.int64, copy=False), - # spike_labels.astype(np.int32, copy=False), - # window_size, - # bin_size, - # ) - - # if False: _compute_correlograms_one_segment_numba( correlograms, spike_times.astype(np.int64, copy=False), @@ -569,80 +560,3 @@ def _compute_correlograms_one_segment_numba( bin = diff // bin_size correlograms[spike_labels[i], spike_labels[j], num_half_bins + bin] += 1 - - # ----------------------------------------------------------------------------- - # To Deprecate - # ----------------------------------------------------------------------------- - - @numba.jit(nopython=True, nogil=True, cache=False) - def _compute_autocorr_numba(spike_times, window_size, bin_size): - num_half_bins = window_size // bin_size - num_bins = 2 * num_half_bins - - auto_corr = np.zeros(num_bins, dtype=np.int64) - - for i in range(len(spike_times)): - for j in range(i + 1, len(spike_times)): - diff = spike_times[j] - spike_times[i] - - if diff > window_size: - break - - bin = int(math.floor(diff / bin_size)) - # ~ auto_corr[num_bins//2 - bin - 1] += 1 - auto_corr[num_half_bins + bin] += 1 - # ~ print(diff, bin, num_half_bins + bin) - - bin = int(math.floor(-diff / bin_size)) - auto_corr[num_half_bins + bin] += 1 - # ~ print(diff, bin, num_half_bins + bin) - - return auto_corr - - @numba.jit(nopython=True, nogil=True, cache=False) - def _compute_crosscorr_numba(spike_times1, spike_times2, window_size, bin_size): - num_half_bins = window_size // bin_size - num_bins = 2 * num_half_bins - - cross_corr = np.zeros(num_bins, dtype=np.int64) - - start_j = 0 - for i in range(len(spike_times1)): - for j in range(start_j, len(spike_times2)): - diff = spike_times1[i] - spike_times2[j] - - if diff >= window_size: - start_j += 1 - continue - if diff < -window_size: - break - - bin = int(math.floor(diff / bin_size)) - # ~ bin = diff // bin_size - cross_corr[num_half_bins + bin] += 1 - # ~ print(diff, bin, num_half_bins + bin) - - return cross_corr - - @numba.jit( - nopython=True, - nogil=True, - cache=False, - parallel=True, - ) - def _compute_correlograms_numba(correlograms, spike_times, spike_labels, window_size, bin_size): - n_units = correlograms.shape[0] - - for i in numba.prange(n_units): - # ~ for i in range(n_units): - spike_times1 = spike_times[spike_labels == i] - - for j in range(i, n_units): - spike_times2 = spike_times[spike_labels == j] - - if i == j: - correlograms[i, j, :] += _compute_autocorr_numba(spike_times1, window_size, bin_size) - else: - cc = _compute_crosscorr_numba(spike_times1, spike_times2, window_size, bin_size) - correlograms[i, j, :] += cc - correlograms[j, i, :] += cc[::-1] From 67aa8725b77a8502160e9853c481b180c27ac310 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Thu, 20 Jun 2024 20:28:11 +0100 Subject: [PATCH 22/81] Tentatively remove the compute from spiketrain functions. --- src/spikeinterface/postprocessing/__init__.py | 2 - .../postprocessing/correlograms.py | 60 ------------------- 2 files changed, 62 deletions(-) diff --git a/src/spikeinterface/postprocessing/__init__.py b/src/spikeinterface/postprocessing/__init__.py index ae071a55e0..2279664e01 100644 --- a/src/spikeinterface/postprocessing/__init__.py +++ b/src/spikeinterface/postprocessing/__init__.py @@ -21,8 +21,6 @@ from .correlograms import ( ComputeCorrelograms, compute_correlograms, - compute_autocorrelogram_from_spiketrain, - compute_crosscorrelogram_from_spiketrain, correlogram_for_one_segment, compute_correlograms_numba, compute_correlograms_numpy, diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index e371ebbf5a..fcfc43d355 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -205,66 +205,6 @@ def _compute_num_bins(window_size, bin_size): return num_bins, num_half_bins -# TODO: this can now be deprecated as there is no distinction at the Numba level. -def compute_autocorrelogram_from_spiketrain(spike_times, window_size, bin_size): - """ - Computes the auto-correlogram from a given spike train. - - This implementation only works if you have numba installed, to accelerate the - computation time. - - Parameters - ---------- - spike_times : np.ndarray - The ordered spike train to compute the auto-correlogram. - window_size : int - Compute the auto-correlogram between -window_size and +window_size (in sampling time). - bin_size : int - Size of a bin (in sampling time). - Returns - ------- - auto_corr : np.ndarray[int64] - The computed auto-correlogram. - bins : - """ - assert HAVE_NUMBA - return _compute_correlograms_one_segment_numba(spike_times.astype(np.int64, copy=False), window_size, bin_size) - - -# TODO: expose a numpy option also. UNless we want to force users to use `Sorting` or `SortingAnalyzer`. -# I am not averse to this, is helps reduce the suface API and assist maintaince. If users -# want to directly computer cross-correlograms they can use a private internal function. -# Thoughts? -def compute_crosscorrelogram_from_spiketrain(spike_times1, spike_times2, window_size, bin_size): - """ - Computes the cros-correlogram between two given spike trains. - - This implementation only works if you have numba installed, to accelerate the - computation time. - - Parameters - ---------- - spike_times1: np.ndarray - The ordered spike train to compare against the second one. - spike_times2: np.ndarray - The ordered spike train that serves as a reference for the cross-correlogram. - window_size: int - Compute the auto-correlogram between -window_size and +window_size (in sampling time). - bin_size: int - Size of a bin (in sampling time). - - Returns - ------- - tuple (auto_corr, bins) - auto_corr: np.ndarray[int64] - The computed auto-correlogram. - """ - assert HAVE_NUMBA - return _compute_correlograms_one_segment_numba( - spike_times1.astype(np.int64), spike_times2.astype(np.int64, copy=False), window_size, bin_size - ) - - def compute_correlograms_on_sorting(sorting, window_ms, bin_ms, method="auto"): """ Computes several cross-correlogram in one course from several clusters. From 4d4c4cdef3577b0a43bf2f3aa50ecd963d40cfb8 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Thu, 20 Jun 2024 20:31:22 +0100 Subject: [PATCH 23/81] Tentatively make some functions private. --- src/spikeinterface/postprocessing/__init__.py | 3 --- src/spikeinterface/postprocessing/correlograms.py | 14 +++++++------- .../postprocessing/tests/test_correlograms.py | 12 ++++++------ 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/spikeinterface/postprocessing/__init__.py b/src/spikeinterface/postprocessing/__init__.py index 2279664e01..1f328d0777 100644 --- a/src/spikeinterface/postprocessing/__init__.py +++ b/src/spikeinterface/postprocessing/__init__.py @@ -21,9 +21,6 @@ from .correlograms import ( ComputeCorrelograms, compute_correlograms, - correlogram_for_one_segment, - compute_correlograms_numba, - compute_correlograms_numpy, ) from .isi import ( diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index fcfc43d355..8f74a6bace 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -98,7 +98,7 @@ def _select_extension_data(self, unit_ids): return new_data def _run(self, verbose=False): - ccgs, bins = compute_correlograms_on_sorting(self.sorting_analyzer.sorting, **self.params) + ccgs, bins = _compute_correlograms_on_sorting(self.sorting_analyzer.sorting, **self.params) self.data["ccgs"] = ccgs self.data["bins"] = bins @@ -132,7 +132,7 @@ def compute_correlograms( sorting_analyzer_or_sorting, window_ms=window_ms, bin_ms=bin_ms, method=method ) else: - return compute_correlograms_on_sorting( + return _compute_correlograms_on_sorting( sorting_analyzer_or_sorting, window_ms=window_ms, bin_ms=bin_ms, method=method ) @@ -205,7 +205,7 @@ def _compute_num_bins(window_size, bin_size): return num_bins, num_half_bins -def compute_correlograms_on_sorting(sorting, window_ms, bin_ms, method="auto"): +def _compute_correlograms_on_sorting(sorting, window_ms, bin_ms, method="auto"): """ Computes several cross-correlogram in one course from several clusters. @@ -242,15 +242,15 @@ def compute_correlograms_on_sorting(sorting, window_ms, bin_ms, method="auto"): bins, window_size, bin_size = _make_bins(sorting, window_ms, bin_ms) if method == "numpy": - correlograms = compute_correlograms_numpy(sorting, window_size, bin_size) + correlograms = _compute_correlograms_numpy(sorting, window_size, bin_size) if method == "numba": - correlograms = compute_correlograms_numba(sorting, window_size, bin_size) + correlograms = _compute_correlograms_numba(sorting, window_size, bin_size) return correlograms, bins # LOW-LEVEL IMPLEMENTATIONS -def compute_correlograms_numpy(sorting, window_size, bin_size): +def _compute_correlograms_numpy(sorting, window_size, bin_size): """ Computes cross-correlograms for all units in a sorting object. @@ -381,7 +381,7 @@ def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size return correlograms -def compute_correlograms_numba(sorting, window_size, bin_size): +def _compute_correlograms_numba(sorting, window_size, bin_size): """ Computes cross-correlograms between all units in `sorting`. diff --git a/src/spikeinterface/postprocessing/tests/test_correlograms.py b/src/spikeinterface/postprocessing/tests/test_correlograms.py index 24b63a0535..5338609a8f 100644 --- a/src/spikeinterface/postprocessing/tests/test_correlograms.py +++ b/src/spikeinterface/postprocessing/tests/test_correlograms.py @@ -11,7 +11,7 @@ from spikeinterface.postprocessing.tests.common_extension_tests import AnalyzerExtensionCommonTestSuite from spikeinterface.postprocessing import ComputeCorrelograms from spikeinterface.postprocessing.correlograms import ( - compute_correlograms_on_sorting, + _compute_correlograms_on_sorting, _make_bins, compute_correlograms, ) @@ -85,10 +85,10 @@ def test_equal_results_correlograms(window_and_bin_ms): window_ms, bin_ms = window_and_bin_ms sorting = generate_sorting(num_units=5, sampling_frequency=30000.0, durations=[10.325, 3.5], seed=0) - result_numpy, bins_numpy = compute_correlograms_on_sorting( + result_numpy, bins_numpy = _compute_correlograms_on_sorting( sorting, window_ms=window_ms, bin_ms=bin_ms, method="numpy" ) - result_numba, bins_numba = compute_correlograms_on_sorting( + result_numba, bins_numba = _compute_correlograms_on_sorting( sorting, window_ms=window_ms, bin_ms=bin_ms, method="numba" ) @@ -104,7 +104,7 @@ def test_flat_cross_correlogram(method): """ sorting = generate_sorting(num_units=2, sampling_frequency=10000.0, durations=[100000.0], seed=0) - correlograms, bins = compute_correlograms_on_sorting(sorting, window_ms=50.0, bin_ms=1.0, method=method) + correlograms, bins = _compute_correlograms_on_sorting(sorting, window_ms=50.0, bin_ms=1.0, method=method) cc = correlograms[0, 1, :].copy() m = np.mean(cc) @@ -124,7 +124,7 @@ def test_auto_equal_cross_correlograms(method): units_dict = {"1": spike_times, "2": spike_times} sorting = NumpySorting.from_unit_dict([units_dict], sampling_frequency=10000.0) - correlograms, bins = compute_correlograms_on_sorting(sorting, window_ms=10.0, bin_ms=0.1, method=method) + correlograms, bins = _compute_correlograms_on_sorting(sorting, window_ms=10.0, bin_ms=0.1, method=method) num_half_bins = correlograms.shape[2] // 2 @@ -160,7 +160,7 @@ def test_detect_injected_correlation(method): units_dict = {"1": spike_times1, "2": spike_times2} sorting = NumpySorting.from_unit_dict([units_dict], sampling_frequency=sampling_frequency) - correlograms, bins = compute_correlograms_on_sorting(sorting, window_ms=10.0, bin_ms=0.1, method=method) + correlograms, bins = _compute_correlograms_on_sorting(sorting, window_ms=10.0, bin_ms=0.1, method=method) cc_01 = correlograms[0, 1, :] cc_10 = correlograms[1, 0, :] From 2c3eeb9a387d64dc0e88be54f6f6fc70a7267358 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Thu, 20 Jun 2024 20:38:24 +0100 Subject: [PATCH 24/81] Remove some notes. --- .../postprocessing/correlograms.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index 8f74a6bace..67546c8a43 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -13,19 +13,6 @@ except ModuleNotFoundError as err: HAVE_NUMBA = False -# TODO: here the default is 50 ms but in the docs it says 100 ms? - -# _set_params, _select_extension_data, _run, _get_data I think are -# sorting analyzer things. Docstrings can be added here and propagated to -# all sorting analyer functions OR can be described in the class docstring. -# otherwise these are quite hard to understand where they are called in the -# code as not called internally on the class. - -# compute_autocorrelogram_from_spiketrain -# TODO: in another PR, coerce this input into `correlogram_for_one_segment()` -# to provide a numpy and numba version. Consider window_size and bin_size -# being taken as ms to match general API. - class ComputeCorrelograms(AnalyzerExtension): """ @@ -109,10 +96,6 @@ def _get_data(self): register_result_extension(ComputeCorrelograms) compute_correlograms_sorting_analyzer = ComputeCorrelograms.function_factory() -# TODO: Question: what is the main entry functions for this module? -# is it only the below? If so can all other functions be made private? -# This would reduce some docstring duplication - def compute_correlograms( sorting_analyzer_or_sorting, From 09d67ab3c9709844d706a9f684f7bd3999fc3873 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Thu, 20 Jun 2024 20:40:17 +0100 Subject: [PATCH 25/81] Add back 'correlogram_for_one_segment' to __init__.py --- src/spikeinterface/postprocessing/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/spikeinterface/postprocessing/__init__.py b/src/spikeinterface/postprocessing/__init__.py index 1f328d0777..68047a1ad5 100644 --- a/src/spikeinterface/postprocessing/__init__.py +++ b/src/spikeinterface/postprocessing/__init__.py @@ -21,6 +21,7 @@ from .correlograms import ( ComputeCorrelograms, compute_correlograms, + correlogram_for_one_segment, ) from .isi import ( From c86e4f01bcafeee454ab60b06eb67b7ced29c7f1 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Thu, 20 Jun 2024 21:19:15 +0100 Subject: [PATCH 26/81] Remove TODO --- .../postprocessing/tests/common_extension_tests.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/spikeinterface/postprocessing/tests/common_extension_tests.py b/src/spikeinterface/postprocessing/tests/common_extension_tests.py index 15eea06ae2..c99b2d4f3b 100644 --- a/src/spikeinterface/postprocessing/tests/common_extension_tests.py +++ b/src/spikeinterface/postprocessing/tests/common_extension_tests.py @@ -77,7 +77,6 @@ class instance is used for each. In this case, we have to set ) self.__class__.cache_folder = create_cache_folder - # TODO: can delete this!!! def _prepare_sorting_analyzer(self, format, sparse, extension_class): """ Prepare a SortingAnalyzer object with dependencies already computed From 6c2bb48d44487be91bc3e27b28a06f35fef56790 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Fri, 21 Jun 2024 10:06:24 +0100 Subject: [PATCH 27/81] Final tidy ups. --- .../postprocessing/correlograms.py | 44 +++++++++---------- .../postprocessing/tests/test_correlograms.py | 43 ++++++++++-------- 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index 67546c8a43..6d61deaa44 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -27,26 +27,26 @@ class ComputeCorrelograms(AnalyzerExtension): implementation, the y-axis result is the 'counts' of spike matches per time bin (rather than a computer correlation or covariance). - Correlograms are often used to determine whether a unit has - ISI violations. In this context, a 'window' around spikes is first + In the present implementation, a 'window' around spikes is first specified. For example, if a window of 100 ms is taken, we will - take the correlation at lags from -100 ms to +100 ms around the spike peak. + take the correlation at lags from -50 ms to +50 ms around the spike peak. In theory, we can have as many lags as we have samples. Often, this visualisation is too high resolution and instead the lags are binned - (e.g. 0-5 ms, 5-10 ms, ..., 95-100 ms bins). When using counts as output, - binning the lags involves adding up all counts across a range of lags. + (e.g. -50 to -45 ms, ..., -5 to 0 ms, 0 to 5 ms, ...., 45 to 50 ms). + When using counts as output, binning the lags involves adding up all counts across + a range of lags. Parameters ---------- sorting_analyzer: SortingAnalyzer A SortingAnalyzer object window_ms : float, default: 50.0 - The window around the spike to compute the correlation in ms. For example, TODO: check this! - if 50 ms, the correlations will be computed at tags -25 ms ... 25 ms. + The window around the spike to compute the correlation in ms. For example, + if 50 ms, the correlations will be computed at lags -25 ms ... 25 ms. bin_ms : float, default: 1.0 The bin size in ms. This determines the bin size over which to - combine lags. For example, with a window size of -25 ms to 25 ms, and - bin size 1 ms, the correlation will be binned as -25 ms, -24 ms, ... + combine lags. For example, with a window size of -25 ms to 25 ms, and + bin size 1 ms, the correlation will be binned as -25 ms, -24 ms, ... method : "auto" | "numpy" | "numba", default: "auto" If "auto" and numba is installed, numba is used, otherwise numpy is used. @@ -56,7 +56,7 @@ class ComputeCorrelograms(AnalyzerExtension): Correlograms with shape (num_units, num_units, num_bins) The diagonal of correlogram is the auto correlogram. The output is in bin counts. - correlogram[A, B, :] is the symetrie of correlogram[B, A, :] + correlogram[A, B, :] is the symmetry of correlogram[B, A, :] correlogram[A, B, :] have to be read as the histogram of spiketimesA - spiketimesB bins : np.array The bin edges in ms @@ -125,18 +125,16 @@ def compute_correlograms( def _make_bins(sorting, window_ms, bin_ms): """ - Create the bins for the autocorrelogram, in samples. + Create the bins for the correlogram, in samples. - The autocorrelogram bins are centered around zero but do not - include the results from zero lag. Each bin increases in - a positive / negative direction starting at zero. + The autocorrelogram bins are centered around zero. Each bin + increases in a positive / negative direction starting at zero. For example, given a window_ms of 50 ms and a bin_ms of 5 ms, the bins in unit ms will be: [-25 to -20, ..., -5 to 0, 0 to 5, ..., 20 to 25]. The window size will be clipped if not divisible by the bin size. - The bins are output in sample units, not seconds. Parameters ---------- @@ -169,7 +167,7 @@ def _make_bins(sorting, window_ms, bin_ms): def _compute_num_bins(window_size, bin_size): """ Internal function to compute number of bins, expects - window_size and bin_size are already divisible and + window_size and bin_size are already divisible. These are typically generated in `_make_bins()`. Returns @@ -235,13 +233,13 @@ def _compute_correlograms_on_sorting(sorting, window_ms, bin_ms, method="auto"): # LOW-LEVEL IMPLEMENTATIONS def _compute_correlograms_numpy(sorting, window_size, bin_size): """ - Computes cross-correlograms for all units in a sorting object. + Computes correlograms for all units in a sorting object. This very elegant implementation is copied from phy package written by Cyrille Rossant. https://github.com/cortex-lab/phylib/blob/master/phylib/stats/ccg.py - The main modification is way the positive and negative are handled explicitly - for rounding reasons. + The main modification is way the positive and negative are handled + explicitly for rounding reasons. Other slight modifications have been made to fit the SpikeInterface data model (e.g. adding the ability to handle multiple segments). @@ -277,14 +275,14 @@ def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size and stored as a count in the relevant lag time bin. Initially, the spike_times array is shifted by 1 position, and the difference - computed. This gives the time differences betwen the closest spikes + computed. This gives the time differences between the closest spikes (skipping the zero-lag case). Next, the differences between spikes times in samples are converted into units relative to bin_size ('binarized'). Spikes in which the binarized difference to their closest neighbouring spike is greater than half the bin-size are - masked and not compared in future. + masked. - Finally, the indicies of the (num_units, num_units, num_bins) correlogram + Finally, the indices of the (num_units, num_units, num_bins) correlogram that need incrementing are done so with `ravel_multi_index()`. This repeats for all shifts along the spike_train until no spikes have a corresponding match within the window size. @@ -433,7 +431,7 @@ def _compute_correlograms_one_segment_numba( correlogram. The correlogram must be passed as an argument and is filled in-place. - Paramters + Parameters --------- correlograms: np.array diff --git a/src/spikeinterface/postprocessing/tests/test_correlograms.py b/src/spikeinterface/postprocessing/tests/test_correlograms.py index 5338609a8f..3b43921a0b 100644 --- a/src/spikeinterface/postprocessing/tests/test_correlograms.py +++ b/src/spikeinterface/postprocessing/tests/test_correlograms.py @@ -175,13 +175,13 @@ def test_detect_injected_correlation(method): # Functional Tests ################### -@pytest.mark.parametrize("overflow_edges", [True, False]) +@pytest.mark.parametrize("fill_all_bins", [True, False]) @pytest.mark.parametrize("on_time_bin", [True, False]) @pytest.mark.parametrize("multi_segment", [True, False]) -def test_compute_correlograms(overflow_edges, on_time_bin, multi_segment): +def test_compute_correlograms(fill_all_bins, on_time_bin, multi_segment): """ Test the entry function `compute_correlograms` under a variety of conditions. - For specifics of `overflow_edges` and `on_time_bin` see `generate_correlogram_test_dataset()`. + For specifics of `fill_all_bins` and `on_time_bin` see `generate_correlogram_test_dataset()`. This function tests numpy and numba in one go, to avoid over-parameterising the method. It tests both a single-segment and multi-segment dataset. The way that segments are @@ -190,7 +190,7 @@ def test_compute_correlograms(overflow_edges, on_time_bin, multi_segment): """ sampling_frequency = 30000 window_ms, bin_ms, spike_times, spike_labels, expected_bins, expected_result_auto, expected_result_corr = ( - generate_correlogram_test_dataset(sampling_frequency, overflow_edges, on_time_bin) + generate_correlogram_test_dataset(sampling_frequency, fill_all_bins, on_time_bin) ) if multi_segment: @@ -255,30 +255,33 @@ def test_compute_correlograms_different_units(method): assert np.array_equal(result[0, 1], np.array([1, 0, 1, 1, 1, 0, 0, 0])) -def generate_correlogram_test_dataset(sampling_frequency, overflow_edges, on_time_bin): +def generate_correlogram_test_dataset(sampling_frequency, fill_all_bins, hit_bin_edge): """ This generates a detailed correlogram test and expected outputs, for a number of test cases: overflow edges : when there are counts expected in every measured bins, otherwise counts are expected only in a (central) subset of bins. - on_time_bin : if `True`, the difference in spike times are created to land + hit_bin_edge : if `True`, the difference in spike times are created to land exactly as multiples of the bin size, an edge case that caused some problems in previous iterations of the algorithm. The approach used is to create a set of spike times which are - multiples of a 'base_diff_time'. When `on_time_bin` is `False` this is + multiples of a 'base_diff_time'. When `hit_bin_edge` is `False` this is set to 5.1 ms. So, we have spikes at: 5.1 ms, 10.2 ms, 15.3 ms, ..., base_diff_time * num_filled_bins This means consecutive spike times are 5.1 ms apart. Then every two spike times are 10.2 ms apart. This gives predictable bin counts, that are maximal at the smaller bins (e.g. 5-10 s) and minimal at - the later bins (e.g. 100-105 s). When `on_time_bin` is `False`, - we expect that bin counts will increase from the edge of the bins - to the middle, maximum in the middle, 0 in the exact center (-5 to 0, 0 to 5) - and then decreasing until the end of the bin. For the autocorrelation, the zero-lag - case is not included and the two central bins will be zero. + the later bins (e.g. 100-105 s). Note at more than num_filled_bins the + the times will overflow to the next bin and test wont work. None of these + parameters should be changed. + + When `hit_bin_edge` is `False`, we expect that bin counts will increase from the + edge of the bins to the middle, maximum in the middle, 0 in the exact center + (-5 to 0, 0 to 5) and then decreasing until the end of the bin. For the autocorrelation, + the zero-lag case is not included and the two central bins will be zero. Different units are tested by repeating the spike times. This means all results for all units autocorrelation and cross-correlation will be @@ -294,7 +297,7 @@ def generate_correlogram_test_dataset(sampling_frequency, overflow_edges, on_tim with all diffs 5 and the `bin_ms` set to 5. By convention, when spike diffs hit the bin edge they are set into the 'right' (i.e. positive) bin. For positive bins this does not change, but for negative bins - all entires are shifted one place to the right. + all entries are shifted one place to the right. """ num_units = 3 @@ -305,14 +308,14 @@ def generate_correlogram_test_dataset(sampling_frequency, overflow_edges, on_tim # If overflow edges, we will have a diff at every possible # bin e.g. the counts will be [31, 30, ..., 30, 31]. If not, # test the case where there are zero bins e.g. [0, 0, 9, 8, ..., 8, 9, 0, 0]. - if overflow_edges: + if fill_all_bins: num_filled_bins = 60 else: num_filled_bins = 10 # If we are on a time bin, make the time delays exactly # the same as a time bin, testing this tricky edge case. - if on_time_bin: + if hit_bin_edge: base_diff_time = bin_ms / 1000 else: base_diff_time = bin_ms / 1000 + 0.0001 # i.e. 0.0051 s @@ -337,29 +340,31 @@ def generate_correlogram_test_dataset(sampling_frequency, overflow_edges, on_tim # In this case, all time bins are shifted to the right for the # negative shift due to the diffs lying on the bin edge. # [30, 31, ..., 59, 0, 59, ..., 30, 31] - if overflow_edges and on_time_bin: + if fill_all_bins and hit_bin_edge: expected_result_auto = np.r_[np.arange(30, 60), 0, np.flip(np.arange(31, 60))] # In this case there are no edge effects and the bin counts # [31, 30, ..., 59, 0, 0, 59, ..., 30, 31] # are symmetrical - elif overflow_edges and not on_time_bin: + elif fill_all_bins and not hit_bin_edge: forward = np.r_[np.arange(31, 60), 0] expected_result_auto = np.r_[forward, np.flip(forward)] # Here we have many zero bins, but the existing bins are # shifted left in the negative-bin base # [0, 0, ..., 1, 2, 3, ..., 10, 0, 10, ..., 3, 2, 1, ..., 0] - elif not overflow_edges and on_time_bin: + elif not fill_all_bins and hit_bin_edge: forward = np.r_[np.zeros(19), np.arange(10)] expected_result_auto = np.r_[0, forward, 0, np.flip(forward)] # Here we have many zero bins and they are symmetrical # [0, 0, ..., 1, 2, 3, ..., 10, 0, 10, ..., 3, 2, 1, ..., 0, 0] - elif not overflow_edges and not on_time_bin: + elif not fill_all_bins and not hit_bin_edge: forward = np.r_[np.zeros(19), np.arange(10), 0] expected_result_auto = np.r_[forward, np.flip(forward)] + # The zero-lag bins are only skipped in the autocorrelogram + # case. expected_result_corr = expected_result_auto.copy() expected_result_corr[int(num_bins / 2)] = num_filled_bins From 8b7ac1e2f6af923416acc67dd5bd016d87a80698 Mon Sep 17 00:00:00 2001 From: chrishalcrow <57948917+chrishalcrow@users.noreply.github.com> Date: Mon, 24 Jun 2024 17:24:02 +0100 Subject: [PATCH 28/81] Unify compute_isi_violation docs and add UMS citation --- doc/modules/qualitymetrics/isi_violations.rst | 47 +++++++++---------- doc/references.rst | 5 +- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/doc/modules/qualitymetrics/isi_violations.rst b/doc/modules/qualitymetrics/isi_violations.rst index e30a2334d5..dc347c614f 100644 --- a/doc/modules/qualitymetrics/isi_violations.rst +++ b/doc/modules/qualitymetrics/isi_violations.rst @@ -10,40 +10,37 @@ Calculation Neurons have a refractory period after a spiking event during which they cannot fire again. Inter-spike-interval (ISI) violations refers to the rate of refractory period violations (as described by [Hill]_). +We aim to calculate the contamination rate :math:`C`, measuring the ratio of isi violations in the spike-train of a unit. The calculation works under the assumption that the contaminant events happen randomly or come from another neuron that is not correlated with our unit. A correlation will lead to an overestimation of the contamination, whereas an anti-correlation will lead to an underestimation. -Different formulas have been developed over the years. +Different formulas have been developed, but all require: -Calculation from the [Hill]_ paper ----------------------------------- +- :math:`T` the duration of the recording. +- :math:`N` the number of spikes in the unit's spike train. +- :math:`t_r` the duration of the unit's refractory period. +- :math:`n_v` the number of violations of the refractory period. -The following quantities are required: +Calculation from the [UMS]_ package +----------------------------------- -- :math:`ISI_t` : biological threshold for ISI violation. -- :math:`ISI_{min}`: minimum ISI threshold enforced by the data recording system used. -- :math:`ISI_s` : the array of ISI violations which are observed in the unit's spike train. -- :math:`\#`: denotes count. +Here, the refactory period :math:`t_r` is adjusted to take account of the data recording system's minimum possible refactory +period. E.g. if a system has a sampling rate of :math:`f \text{ Hz}`, the closest that two spikes from the same unit can possibly +be is :math:`1/f \, \text{s}`. Hence the refactory period :math:`t_r` is the expected biological threshold minus this minimum possible +threshold. -The threshold for ISI violations is the biological ISI threshold, :math:`ISI_t`, minus the minimum ISI threshold, :math:`ISI_{min}` enforced by the data recording system used. -The array of inter-spike-intervals observed in the unit's spike train, :math:`ISI_s`, is used to identify the count (:math:`\#`) of observed ISI's below this threshold. -For a recording with a duration of :math:`T_r` seconds, and a unit with :math:`N_s` spikes, the rate of ISI violations is: +The contamination rate is calculated to be .. math:: - \textrm{ISI violations} = \frac{ \#( ISI_s < ISI_t) T_r }{ 2 N_s^2 (ISI_t - ISI_{min}) } + C = \frac{ n_v T }{ 2 N^2 t_r } Calculation from the [Llobet]_ paper ------------------------------------ -The following quantities are required: - -- :math:`T` the duration of the recording. -- :math:`N` the number of spikes in the unit's spike train. -- :math:`t_r` the duration of the unit's refractory period. -- :math:`n_v` the number of violations of the refractory period. - -The estimated contamination :math:`C` can be calculated with 2 extreme scenarios. In the first one, the contaminant spikes are completely random (or come from an infinite number of other neurons). In the second one, the contaminant spikes come from a single other neuron: +The estimated contamination :math:`C` is calculated in 2 extreme scenarios. In the first, the contaminant spikes + are completely random (or come from an infinite number of other neurons). In the second, the contaminant spikes + come from a single other neuron. In these scenarios, the contamination rate is .. math:: @@ -58,7 +55,9 @@ Expectation and use ------------------- ISI violations identifies unit contamination - a high value indicates a highly contaminated unit. -Despite being a ratio, ISI violations can exceed 1 (or become a complex number in the [Llobet]_ formula). This is usually due to the contaminant events being correlated with our neuron, and their number is greater than a purely random spike train. +Despite being a ratio, the contamination can exceed 1 (or become a complex number in the [Llobet]_ formula). +This is usually due to the contaminant events being correlated with our neuron, and their number is +greater than a purely random spike train. Example code ------------ @@ -86,8 +85,8 @@ With SpikeInterface: References ---------- -Hill implementation (:code:`isi_violation`) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +UMS implementation (:code:`isi_violation`) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. autofunction:: spikeinterface.qualitymetrics.misc_metrics.compute_isi_violations @@ -160,5 +159,5 @@ Links to original implementations Literature ---------- -Introduced by [Hill]_ (2011). +Introduced in UltraMegaSort2000 [UMS]_ (2011). Also described by [Llobet]_ (2022) diff --git a/doc/references.rst b/doc/references.rst index ace51db951..48b7cd44f6 100644 --- a/doc/references.rst +++ b/doc/references.rst @@ -50,9 +50,10 @@ If you use the :code:`qualitymetrics` module, i.e. you use the :code:`analyzer.c or :code:`compute_quality_metrics()` methods, please include the citations for the :code:`metric_names` that were particularly important for your research: -- :code:`amplitude_cutoff` or :code:`isi_violation` [Hill]_ +- :code:`amplitude_cutoff` [Hill]_ - :code:`amplitude_median` or :code:`sliding_rp_violation` [IBL]_ - :code:`drift` [Siegle]_ +- :code:`isi_violation` [UMS]_ - :code:`rp_violation` [Llobet]_ - :code:`sd_ratio` [Pouzat]_ - :code:`snr` [Lemon]_ [Jackson]_ @@ -122,6 +123,8 @@ References .. [Siegle] `Survey of Spiking in the Mouse Visual System Reveals Functional Hierarchy. 2021. `_ +.. [UMS] `UltraMegaSort2000 - Spike sorting and quality metrics for extracellular spike data. 2011. `_ + .. [Varol] `Decentralized Motion Inference and Registration of Neuropixel Data. 2021. `_ .. [Windolf] `Robust Online Multiband Drift Estimation in Electrophysiology Data. 2022. `_ From 364193cc32df16301bf5a902f2048033b2aef951 Mon Sep 17 00:00:00 2001 From: chrishalcrow <57948917+chrishalcrow@users.noreply.github.com> Date: Mon, 24 Jun 2024 17:42:46 +0100 Subject: [PATCH 29/81] Update compete_isi_violations docstring --- .../qualitymetrics/misc_metrics.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/spikeinterface/qualitymetrics/misc_metrics.py b/src/spikeinterface/qualitymetrics/misc_metrics.py index cbb55aeb8b..b3cf84cf9c 100644 --- a/src/spikeinterface/qualitymetrics/misc_metrics.py +++ b/src/spikeinterface/qualitymetrics/misc_metrics.py @@ -241,7 +241,7 @@ def compute_isi_violations(sorting_analyzer, isi_threshold_ms=1.5, min_isi_ms=0, It computes several metrics related to isi violations: * isi_violations_ratio: the relative firing rate of the hypothetical neurons that are - generating the ISI violations. Described in [Hill]_. See Notes. + generating the ISI violations. See Notes. * isi_violation_count: number of ISI violations Parameters @@ -261,22 +261,23 @@ def compute_isi_violations(sorting_analyzer, isi_threshold_ms=1.5, min_isi_ms=0, Returns ------- isi_violations_ratio : dict - The isi violation ratio described in [Hill]_. + The isi violation ratio. isi_violation_count : dict Number of violations. Notes ----- - You can interpret an ISI violations ratio value of 0.5 as meaning that contaminating spikes are - occurring at roughly half the rate of "true" spikes for that unit. - In cases of highly contaminated units, the ISI violations ratio can sometimes be greater than 1. + The returned ISI violations ratio measures the approximate fraction of spikes in each + unit which are contaminted. This interpretation is good when the ratio is small, and + becomes worse as it grows. In cases of highly contaminated units, the ISI violations + ratio can sometimes be greater than 1. References ---------- - Based on metrics described in [Hill]_ + Based on metrics originally implemented in [UMS]_ - Originally written in Matlab by Nick Steinmetz (https://github.com/cortex-lab/sortingQuality) - and converted to Python by Daniel Denman. + This implementation is based on one written in Matlab by Nick Steinmetz + (https://github.com/cortex-lab/sortingQuality) and converted to Python by Daniel Denman. """ res = namedtuple("isi_violation", ["isi_violations_ratio", "isi_violations_count"]) @@ -324,7 +325,7 @@ def compute_refrac_period_violations( Calculate the number of refractory period violations. This is similar (but slightly different) to the ISI violations. - The key difference being that the violations are not only computed on consecutive spikes. + The key differences being that the violations are not only computed on consecutive spikes. This is required for some formulas (e.g. the ones from Llobet & Wyngaard 2022). From 926afdbccafb3a6caf38aa411b4d80d4187afa56 Mon Sep 17 00:00:00 2001 From: Pierre Yger Date: Wed, 26 Jun 2024 22:56:15 +0200 Subject: [PATCH 30/81] Adding option to overwrite --- src/spikeinterface/preprocessing/motion.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/spikeinterface/preprocessing/motion.py b/src/spikeinterface/preprocessing/motion.py index 8023bd4367..a98bdc171a 100644 --- a/src/spikeinterface/preprocessing/motion.py +++ b/src/spikeinterface/preprocessing/motion.py @@ -204,6 +204,7 @@ def correct_motion( recording, preset="nonrigid_accurate", folder=None, + overwrite=False, output_motion_info=False, detect_kwargs={}, select_kwargs={}, @@ -253,6 +254,8 @@ def correct_motion( The preset name folder : Path str or None, default: None If not None then intermediate motion info are saved into a folder + overwrite : bool, default False + If folder is not None and already existing, should we overwrite output_motion_info : bool, default: False If True, then the function returns a `motion_info` dictionary that contains variables to check intermediate steps (motion_histogram, non_rigid_windows, pairwise_displacement) @@ -316,6 +319,13 @@ def correct_motion( if folder is not None: folder = Path(folder) + if overwrite: + if folder.exists(): + import shutil + shutil.rmtree(folder) + else: + assert not folder.exists(), f"Folder {folder} already exists" + folder.mkdir(exist_ok=True, parents=True) (folder / "parameters.json").write_text(json.dumps(parameters, indent=4, cls=SIJsonEncoder), encoding="utf8") From cb957b838e06cf719e0ebb68fbf1ff1c08a118e5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 20:59:44 +0000 Subject: [PATCH 31/81] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/spikeinterface/preprocessing/motion.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/spikeinterface/preprocessing/motion.py b/src/spikeinterface/preprocessing/motion.py index a98bdc171a..71ae3f3ebb 100644 --- a/src/spikeinterface/preprocessing/motion.py +++ b/src/spikeinterface/preprocessing/motion.py @@ -320,8 +320,9 @@ def correct_motion( if folder is not None: folder = Path(folder) if overwrite: - if folder.exists(): + if folder.exists(): import shutil + shutil.rmtree(folder) else: assert not folder.exists(), f"Folder {folder} already exists" From b37ee282d3009250be6890e3220dcff8930c3a43 Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Thu, 27 Jun 2024 12:37:04 +0200 Subject: [PATCH 32/81] exists() -> is_dir() --- src/spikeinterface/preprocessing/motion.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/spikeinterface/preprocessing/motion.py b/src/spikeinterface/preprocessing/motion.py index 71ae3f3ebb..ce6b9bb337 100644 --- a/src/spikeinterface/preprocessing/motion.py +++ b/src/spikeinterface/preprocessing/motion.py @@ -320,12 +320,12 @@ def correct_motion( if folder is not None: folder = Path(folder) if overwrite: - if folder.exists(): + if folder.is_dir(): import shutil shutil.rmtree(folder) else: - assert not folder.exists(), f"Folder {folder} already exists" + assert not folder.is_dir(), f"Folder {folder} already exists" folder.mkdir(exist_ok=True, parents=True) From 5ebb9845e1bba084a867afc9e6e01d8ca66c8071 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Thu, 27 Jun 2024 12:37:48 +0100 Subject: [PATCH 33/81] Move long docstrings to 'Notes' section. --- .../postprocessing/correlograms.py | 76 +++++++++++-------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index 6d61deaa44..f78dd8f9c7 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -16,25 +16,7 @@ class ComputeCorrelograms(AnalyzerExtension): """ - Compute auto and cross correlograms. - - In the extracellular electrophysiology context, a correlogram - is a visualisation of the results of a cross-correlation - between two spike trains. The cross-correlation slides one spike train - along another sample-by-sample, taking the correlation at each 'lag'. This results - in a plot with 'lag' (i.e. time offset) on the x-axis and 'correlation' - (i.e. how similar to two spike trains are) on the y-axis. In this - implementation, the y-axis result is the 'counts' of spike matches per - time bin (rather than a computer correlation or covariance). - - In the present implementation, a 'window' around spikes is first - specified. For example, if a window of 100 ms is taken, we will - take the correlation at lags from -50 ms to +50 ms around the spike peak. - In theory, we can have as many lags as we have samples. Often, this - visualisation is too high resolution and instead the lags are binned - (e.g. -50 to -45 ms, ..., -5 to 0 ms, 0 to 5 ms, ...., 45 to 50 ms). - When using counts as output, binning the lags involves adding up all counts across - a range of lags. + Compute auto and cross correlograms of unit spike times. Parameters ---------- @@ -60,6 +42,28 @@ class ComputeCorrelograms(AnalyzerExtension): correlogram[A, B, :] have to be read as the histogram of spiketimesA - spiketimesB bins : np.array The bin edges in ms + + Notes + ----- + In the extracellular electrophysiology context, a correlogram + is a visualisation of the results of a cross-correlation + between two spike trains. The cross-correlation slides one spike train + along another sample-by-sample, taking the correlation at each 'lag'. This results + in a plot with 'lag' (i.e. time offset) on the x-axis and 'correlation' + (i.e. how similar to two spike trains are) on the y-axis. In this + implementation, the y-axis result is the 'counts' of spike matches per + time bin (rather than a computer correlation or covariance). + + In the present implementation, a 'window' around spikes is first + specified. For example, if a window of 100 ms is taken, we will + take the correlation at lags from -50 ms to +50 ms around the spike peak. + In theory, we can have as many lags as we have samples. Often, this + visualisation is too high resolution and instead the lags are binned + (e.g. -50 to -45 ms, ..., -5 to 0 ms, 0 to 5 ms, ...., 45 to 50 ms). + When using counts as output, binning the lags involves adding up all counts across + a range of lags. + + """ extension_name = "correlograms" @@ -270,6 +274,27 @@ def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size A very well optimized algorithm for the cross-correlation of spike trains, copied from the Phy package, written by Cyrille Rossant. + Parameters + ---------- + spike_times : np.ndarray + An array of spike times (in samples, not seconds). + This contains spikes from all units. + spike_labels : np.ndarray + An array of labels indicating the unit of the corresponding + spike in `spike_times`. + window_size : int + The window size over which to perform the cross-correlation, in samples + bin_size : int + The size of which to bin lags, in samples. + + Returns + ------- + correlograms : np.array + A (num_units, num_units, num_bins) array of correlograms + between all units at each lag time bin. + + Notes + ----- For all spikes, time difference between this spike and every other spike within the window is directly computed and stored as a count in the relevant lag time bin. @@ -286,19 +311,6 @@ def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size that need incrementing are done so with `ravel_multi_index()`. This repeats for all shifts along the spike_train until no spikes have a corresponding match within the window size. - - Parameters - ---------- - spike_times : np.ndarray - An array of spike times (in samples, not seconds). - This contains spikes from all units. - spike_labels : np.ndarray - An array of labels indicating the unit of the corresponding - spike in `spike_times`. - window_size : int - The window size over which to perform the cross-correlation, in samples - bin_size : int - The size of which to bin lags, in samples. """ num_bins, num_half_bins = _compute_num_bins(window_size, bin_size) num_units = len(np.unique(spike_labels)) From 511ebd5d21badab3416b6fba0b7781caf6b86db1 Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Thu, 27 Jun 2024 10:54:12 -0600 Subject: [PATCH 34/81] first comments --- src/spikeinterface/preprocessing/scale.py | 10 ++++++++-- src/spikeinterface/preprocessing/tests/test_scaling.py | 10 +++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/spikeinterface/preprocessing/scale.py b/src/spikeinterface/preprocessing/scale.py index 99acd49981..03ccee757b 100644 --- a/src/spikeinterface/preprocessing/scale.py +++ b/src/spikeinterface/preprocessing/scale.py @@ -1,5 +1,7 @@ from __future__ import annotations +import numpy as np + from spikeinterface.core import BaseRecording from spikeinterface.preprocessing.basepreprocessor import BasePreprocessor @@ -26,12 +28,16 @@ class ScaleTouVRecording(BasePreprocessor): name = "scale_to_uV" def __init__(self, recording: BaseRecording): - assert recording.has_scaleable_traces(), "Recording must have scaleable traces" + # Importing inside to avoid a circular import from spikeinterface.preprocessing.normalize_scale import ScaleRecordingSegment - dtype = recording.get_dtype() + dtype = np.dtype("float32") BasePreprocessor.__init__(self, recording, dtype=dtype) + if not recording.has_scaleable_traces(): + error_msg = "Recording must have gains and offsets set to be scaled to µV" + raise RuntimeError(error_msg) + gain = recording.get_channel_gains()[None, :] offset = recording.get_channel_offsets()[None, :] for parent_segment in recording._recording_segments: diff --git a/src/spikeinterface/preprocessing/tests/test_scaling.py b/src/spikeinterface/preprocessing/tests/test_scaling.py index e66d36c613..7079e6f6ae 100644 --- a/src/spikeinterface/preprocessing/tests/test_scaling.py +++ b/src/spikeinterface/preprocessing/tests/test_scaling.py @@ -1,14 +1,14 @@ import pytest import numpy as np from spikeinterface.core.testing_tools import generate_recording -from spikeinterface.preprocessing import ScaleTouVRecording # Replace 'your_module' with your actual module name +from spikeinterface.preprocessing import ScaleTouVRecording def test_scale_to_uv(): # Create a sample recording extractor with fake gains and offsets num_channels = 4 sampling_frequency = 30_000.0 - durations = [1] # seconds + durations = [1.0, 1.0] # seconds recording = generate_recording( num_channels=num_channels, durations=durations, @@ -25,12 +25,12 @@ def test_scale_to_uv(): scaled_recording = ScaleTouVRecording(recording=recording) # Check if the traces are indeed scaled - expected_traces = recording.get_traces(return_scaled=True) - scaled_traces = scaled_recording.get_traces() + expected_traces = recording.get_traces(return_scaled=True, segment_index=0) + scaled_traces = scaled_recording.get_traces(segment_index=0) np.testing.assert_allclose(scaled_traces, expected_traces) # Test for the error when recording doesn't have scaleable traces recording.set_channel_gains(None) # Remove gains to make traces unscaleable - with pytest.raises(AssertionError): + with pytest.raises(RuntimeError): ScaleTouVRecording(recording) From 62485d5ee5c9dbb30085b3eaad9ea07a448d2ace Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Thu, 27 Jun 2024 11:05:50 -0600 Subject: [PATCH 35/81] add failing test --- .../preprocessing/tests/test_scaling.py | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/spikeinterface/preprocessing/tests/test_scaling.py b/src/spikeinterface/preprocessing/tests/test_scaling.py index 7079e6f6ae..098e77caad 100644 --- a/src/spikeinterface/preprocessing/tests/test_scaling.py +++ b/src/spikeinterface/preprocessing/tests/test_scaling.py @@ -1,7 +1,7 @@ import pytest import numpy as np from spikeinterface.core.testing_tools import generate_recording -from spikeinterface.preprocessing import ScaleTouVRecording +from spikeinterface.preprocessing import ScaleTouVRecording, CenterRecording def test_scale_to_uv(): @@ -34,3 +34,37 @@ def test_scale_to_uv(): recording.set_channel_gains(None) # Remove gains to make traces unscaleable with pytest.raises(RuntimeError): ScaleTouVRecording(recording) + + +def test_scaling_in_preprocessing_chain(): + + # Create a sample recording extractor with fake gains and offsets + num_channels = 4 + sampling_frequency = 30_000.0 + durations = [1.0] # seconds + recording = generate_recording( + num_channels=num_channels, + durations=durations, + sampling_frequency=sampling_frequency, + ) + + rng = np.random.default_rng(0) + gains = rng.random(size=(num_channels)).astype(np.float32) + offsets = rng.random(size=(num_channels)).astype(np.float32) + + recording.set_channel_gains(gains) + recording.set_channel_offsets(offsets) + + centered_recording = CenterRecording(ScaleTouVRecording(recording=recording)) + traces_scaled_with_argument = centered_recording.get_traces(return_scaled=True) + + # Chain preprocessors + centered_recording_scaled = CenterRecording(ScaleTouVRecording(recording=recording)) + traces_scaled_with_preprocessor = centered_recording_scaled.get_traces() + + np.testing.assert_allclose(traces_scaled_with_argument, traces_scaled_with_preprocessor) + + # Test if the scaling is not done twice + traces_scaled_with_preprocessor_and_argument = centered_recording_scaled.get_traces(return_scaled=True) + + np.testing.assert_allclose(traces_scaled_with_preprocessor, traces_scaled_with_preprocessor_and_argument) From 2a32b13882d891230c0f25fc734ac79fc4601481 Mon Sep 17 00:00:00 2001 From: Joe Ziminski <55797454+JoeZiminski@users.noreply.github.com> Date: Thu, 27 Jun 2024 18:43:45 +0100 Subject: [PATCH 36/81] Fix bad grammer in docstring Co-authored-by: Chris Halcrow <57948917+chrishalcrow@users.noreply.github.com> --- src/spikeinterface/postprocessing/correlograms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index f78dd8f9c7..b8973550a4 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -242,7 +242,7 @@ def _compute_correlograms_numpy(sorting, window_size, bin_size): This very elegant implementation is copied from phy package written by Cyrille Rossant. https://github.com/cortex-lab/phylib/blob/master/phylib/stats/ccg.py - The main modification is way the positive and negative are handled + The main modification is the way positive and negative are handled explicitly for rounding reasons. Other slight modifications have been made to fit the SpikeInterface From 503cf1a7e42ca9f667e92d196e4bd0749f5f570f Mon Sep 17 00:00:00 2001 From: Joe Ziminski <55797454+JoeZiminski@users.noreply.github.com> Date: Thu, 27 Jun 2024 18:44:02 +0100 Subject: [PATCH 37/81] Fix weird space in the word 'window' Co-authored-by: Chris Halcrow <57948917+chrishalcrow@users.noreply.github.com> --- src/spikeinterface/postprocessing/correlograms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index b8973550a4..b1e5cbd9c4 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -387,7 +387,7 @@ def _compute_correlograms_numba(sorting, window_size, bin_size): sorting : Sorting A SpikeInterface Sorting object window_size : int - The wi ndow size over which to perform the cross-correlation, in samples + The window size over which to perform the cross-correlation, in samples bin_size : int The size of which to bin lags, in samples. From 0108227c911d7a8e47bd445de6e5b1f1b27113f2 Mon Sep 17 00:00:00 2001 From: chrishalcrow <57948917+chrishalcrow@users.noreply.github.com> Date: Fri, 28 Jun 2024 13:47:29 +0100 Subject: [PATCH 38/81] Respond to review --- doc/modules/qualitymetrics/isi_violations.rst | 10 ++++++---- src/spikeinterface/qualitymetrics/misc_metrics.py | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/doc/modules/qualitymetrics/isi_violations.rst b/doc/modules/qualitymetrics/isi_violations.rst index dc347c614f..10e1934537 100644 --- a/doc/modules/qualitymetrics/isi_violations.rst +++ b/doc/modules/qualitymetrics/isi_violations.rst @@ -16,14 +16,16 @@ A correlation will lead to an overestimation of the contamination, whereas an an Different formulas have been developed, but all require: -- :math:`T` the duration of the recording. +- :math:`T` the duration of the recording in seconds. - :math:`N` the number of spikes in the unit's spike train. -- :math:`t_r` the duration of the unit's refractory period. +- :math:`t_r` the duration of the unit's refractory period in seconds. - :math:`n_v` the number of violations of the refractory period. Calculation from the [UMS]_ package ----------------------------------- +Originally implemented in the `rpv_contamination` calculation of the UltraMegaSort2000 package ``_. + Here, the refactory period :math:`t_r` is adjusted to take account of the data recording system's minimum possible refactory period. E.g. if a system has a sampling rate of :math:`f \text{ Hz}`, the closest that two spikes from the same unit can possibly be is :math:`1/f \, \text{s}`. Hence the refactory period :math:`t_r` is the expected biological threshold minus this minimum possible @@ -39,8 +41,8 @@ Calculation from the [Llobet]_ paper ------------------------------------ The estimated contamination :math:`C` is calculated in 2 extreme scenarios. In the first, the contaminant spikes - are completely random (or come from an infinite number of other neurons). In the second, the contaminant spikes - come from a single other neuron. In these scenarios, the contamination rate is +are completely random (or come from an infinite number of other neurons). In the second, the contaminant spikes +come from a single other neuron. In these scenarios, the contamination rate is .. math:: diff --git a/src/spikeinterface/qualitymetrics/misc_metrics.py b/src/spikeinterface/qualitymetrics/misc_metrics.py index b3cf84cf9c..f809ad11ec 100644 --- a/src/spikeinterface/qualitymetrics/misc_metrics.py +++ b/src/spikeinterface/qualitymetrics/misc_metrics.py @@ -272,9 +272,14 @@ def compute_isi_violations(sorting_analyzer, isi_threshold_ms=1.5, min_isi_ms=0, becomes worse as it grows. In cases of highly contaminated units, the ISI violations ratio can sometimes be greater than 1. + This method counts the number of spikes whose isi is violated. If there are three + spikes within `isi_threshold_ms`, the first and second are violated. Hence there are two + spikes which have been violated. This is is contrast to `compute_refrac_period_violations`, + which counts the number of violations. + References ---------- - Based on metrics originally implemented in [UMS]_ + Based on metrics originally implemented in Ultra Mega Sort [UMS]_. This implementation is based on one written in Matlab by Nick Steinmetz (https://github.com/cortex-lab/sortingQuality) and converted to Python by Daniel Denman. @@ -325,7 +330,6 @@ def compute_refrac_period_violations( Calculate the number of refractory period violations. This is similar (but slightly different) to the ISI violations. - The key differences being that the violations are not only computed on consecutive spikes. This is required for some formulas (e.g. the ones from Llobet & Wyngaard 2022). @@ -352,6 +356,12 @@ def compute_refrac_period_violations( ----- Requires "numba" package + This method counts the number of violations which occur during the refactory period. + If there are three spikes within `refractory_period_ms`, the second and third spikes + violate the first spikes and the third spike violates the second spike. Hence there + are three violations. This is in contrast to `compute_isi_violations`, which + computes the number of spikes which have been violated. + References ---------- Based on metrics described in [Llobet]_ From c590ed03c83cd8cc81dfe9b8c2b3a8964c0f6345 Mon Sep 17 00:00:00 2001 From: chrishalcrow <57948917+chrishalcrow@users.noreply.github.com> Date: Fri, 28 Jun 2024 13:52:16 +0100 Subject: [PATCH 39/81] add a colon --- doc/modules/qualitymetrics/isi_violations.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/modules/qualitymetrics/isi_violations.rst b/doc/modules/qualitymetrics/isi_violations.rst index 10e1934537..2002ec6582 100644 --- a/doc/modules/qualitymetrics/isi_violations.rst +++ b/doc/modules/qualitymetrics/isi_violations.rst @@ -24,7 +24,7 @@ Different formulas have been developed, but all require: Calculation from the [UMS]_ package ----------------------------------- -Originally implemented in the `rpv_contamination` calculation of the UltraMegaSort2000 package ``_. +Originally implemented in the `rpv_contamination` calculation of the UltraMegaSort2000 package: ``_. Here, the refactory period :math:`t_r` is adjusted to take account of the data recording system's minimum possible refactory period. E.g. if a system has a sampling rate of :math:`f \text{ Hz}`, the closest that two spikes from the same unit can possibly From 815f6053fb438ae7f5eb04462ac31aad17200aac Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Fri, 28 Jun 2024 15:27:28 -0600 Subject: [PATCH 40/81] accept paths in jsonification --- src/spikeinterface/core/core_tools.py | 3 ++ .../core/tests/test_jsonification.py | 29 ++++++++++++++----- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/spikeinterface/core/core_tools.py b/src/spikeinterface/core/core_tools.py index 066ab58d8c..d4701343af 100644 --- a/src/spikeinterface/core/core_tools.py +++ b/src/spikeinterface/core/core_tools.py @@ -98,6 +98,9 @@ def default(self, obj): if isinstance(obj, BaseExtractor): return obj.to_dict() + if isinstance(obj, Path): + return str(obj) + # The base-class handles the assertion return super().default(obj) diff --git a/src/spikeinterface/core/tests/test_jsonification.py b/src/spikeinterface/core/tests/test_jsonification.py index 4417ea342f..316dac3abc 100644 --- a/src/spikeinterface/core/tests/test_jsonification.py +++ b/src/spikeinterface/core/tests/test_jsonification.py @@ -7,11 +7,7 @@ from spikeinterface.core.core_tools import SIJsonEncoder from spikeinterface.core.generate import generate_recording, generate_sorting - -@pytest.fixture(scope="module") -def numpy_generated_recording(): - recording = generate_recording() - return recording +from pathlib import Path @pytest.fixture(scope="module") @@ -124,8 +120,25 @@ def test_numpy_dtype_alises_encoding(): json.dumps(np.float32, cls=SIJsonEncoder) -def test_recording_encoding(numpy_generated_recording): - recording = numpy_generated_recording +def test_path_encoding(tmp_path): + + temporary_path = tmp_path / "a_path_for_this_test" + + json.dumps(temporary_path, cls=SIJsonEncoder) + + +def test_path_as_annotation(tmp_path): + temporary_path = tmp_path / "a_path_for_this_test" + + recording = generate_recording() + recording.annotate(path=temporary_path) + + json.dumps(recording, cls=SIJsonEncoder) + + +def test_recording_encoding(): + recording = generate_recording() + json.dumps(recording, cls=SIJsonEncoder) @@ -200,4 +213,4 @@ def test_encoding_numpy_scalars_within_nested_extractors_dict(nested_extractor_d if __name__ == "__main__": nested_extractor = nested_extractor() - test_encoding_numpy_scalars_within_nested_extractors(nested_extractor_) + test_encoding_numpy_scalars_within_nested_extractors(nested_extractor) From 92b969e345199b9795937104844c58e200864556 Mon Sep 17 00:00:00 2001 From: zm711 <92116279+zm711@users.noreply.github.com> Date: Fri, 28 Jun 2024 17:56:56 -0400 Subject: [PATCH 41/81] use curation argument in gui --- src/spikeinterface/widgets/sorting_summary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spikeinterface/widgets/sorting_summary.py b/src/spikeinterface/widgets/sorting_summary.py index 24b4ca8022..6f60e9ab9a 100644 --- a/src/spikeinterface/widgets/sorting_summary.py +++ b/src/spikeinterface/widgets/sorting_summary.py @@ -188,6 +188,6 @@ def plot_spikeinterface_gui(self, data_plot, **backend_kwargs): import spikeinterface_gui app = spikeinterface_gui.mkQApp() - win = spikeinterface_gui.MainWindow(sorting_analyzer) + win = spikeinterface_gui.MainWindow(sorting_analyzer, curation=data_plot["curation"]) win.show() app.exec_() From bf3cc4b21faf0829521af29187df0cfb4fcfd445 Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Fri, 28 Jun 2024 16:08:40 -0600 Subject: [PATCH 42/81] tests are passing --- src/spikeinterface/preprocessing/scale.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/spikeinterface/preprocessing/scale.py b/src/spikeinterface/preprocessing/scale.py index 03ccee757b..45ffe383d4 100644 --- a/src/spikeinterface/preprocessing/scale.py +++ b/src/spikeinterface/preprocessing/scale.py @@ -38,10 +38,13 @@ def __init__(self, recording: BaseRecording): error_msg = "Recording must have gains and offsets set to be scaled to µV" raise RuntimeError(error_msg) + self.set_channel_gains(gains=1.0) + self.set_channel_offsets(offsets=0.0) + gain = recording.get_channel_gains()[None, :] offset = recording.get_channel_offsets()[None, :] for parent_segment in recording._recording_segments: - rec_segment = ScaleRecordingSegment(parent_segment, gain, offset, self._dtype) + rec_segment = ScaleRecordingSegment(parent_segment, gain, offset, dtype) self.add_recording_segment(rec_segment) self._kwargs = dict( From c6a521b8569ef062edf277a71b9aa74af0e7b1ea Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Fri, 28 Jun 2024 16:20:46 -0600 Subject: [PATCH 43/81] @alejo91 suggestion --- src/spikeinterface/preprocessing/scale.py | 38 +++++++------------ .../preprocessing/tests/test_scaling.py | 12 +++--- 2 files changed, 19 insertions(+), 31 deletions(-) diff --git a/src/spikeinterface/preprocessing/scale.py b/src/spikeinterface/preprocessing/scale.py index 45ffe383d4..bc77577ce0 100644 --- a/src/spikeinterface/preprocessing/scale.py +++ b/src/spikeinterface/preprocessing/scale.py @@ -6,7 +6,7 @@ from spikeinterface.preprocessing.basepreprocessor import BasePreprocessor -class ScaleTouVRecording(BasePreprocessor): +def scale_to_uV(recording: BasePreprocessor) -> BasePreprocessor: """ Scale raw traces to microvolts (µV). @@ -24,32 +24,20 @@ class ScaleTouVRecording(BasePreprocessor): AssertionError If the recording extractor does not have scaleable traces. """ + # To avoid a circular import + from spikeinterface.preprocessing import ScaleRecording - name = "scale_to_uV" + if not recording.has_scaleable_traces(): + error_msg = "Recording must have gains and offsets set to be scaled to µV" + raise RuntimeError(error_msg) - def __init__(self, recording: BaseRecording): - # Importing inside to avoid a circular import - from spikeinterface.preprocessing.normalize_scale import ScaleRecordingSegment + gain = recording.get_channel_gains() + offset = recording.get_channel_offsets() - dtype = np.dtype("float32") - BasePreprocessor.__init__(self, recording, dtype=dtype) + scaled_to_uV_recording = ScaleRecording(recording, gain=gain, offset=offset, dtype="float32") - if not recording.has_scaleable_traces(): - error_msg = "Recording must have gains and offsets set to be scaled to µV" - raise RuntimeError(error_msg) + # We do this so when get_traces(return_scaled=True) is called, the return is the same. + scaled_to_uV_recording.set_channel_gains(gains=1.0) + scaled_to_uV_recording.set_channel_offsets(offsets=0.0) - self.set_channel_gains(gains=1.0) - self.set_channel_offsets(offsets=0.0) - - gain = recording.get_channel_gains()[None, :] - offset = recording.get_channel_offsets()[None, :] - for parent_segment in recording._recording_segments: - rec_segment = ScaleRecordingSegment(parent_segment, gain, offset, dtype) - self.add_recording_segment(rec_segment) - - self._kwargs = dict( - recording=recording, - ) - - -scale_to_uV = ScaleTouVRecording + return scaled_to_uV_recording diff --git a/src/spikeinterface/preprocessing/tests/test_scaling.py b/src/spikeinterface/preprocessing/tests/test_scaling.py index 098e77caad..321d7c9df2 100644 --- a/src/spikeinterface/preprocessing/tests/test_scaling.py +++ b/src/spikeinterface/preprocessing/tests/test_scaling.py @@ -1,10 +1,10 @@ import pytest import numpy as np from spikeinterface.core.testing_tools import generate_recording -from spikeinterface.preprocessing import ScaleTouVRecording, CenterRecording +from spikeinterface.preprocessing import scale_to_uV, CenterRecording -def test_scale_to_uv(): +def test_scale_to_uV(): # Create a sample recording extractor with fake gains and offsets num_channels = 4 sampling_frequency = 30_000.0 @@ -22,7 +22,7 @@ def test_scale_to_uv(): recording.set_channel_offsets(offsets) # Apply the preprocessor - scaled_recording = ScaleTouVRecording(recording=recording) + scaled_recording = scale_to_uV(recording=recording) # Check if the traces are indeed scaled expected_traces = recording.get_traces(return_scaled=True, segment_index=0) @@ -33,7 +33,7 @@ def test_scale_to_uv(): # Test for the error when recording doesn't have scaleable traces recording.set_channel_gains(None) # Remove gains to make traces unscaleable with pytest.raises(RuntimeError): - ScaleTouVRecording(recording) + scale_to_uV(recording) def test_scaling_in_preprocessing_chain(): @@ -55,11 +55,11 @@ def test_scaling_in_preprocessing_chain(): recording.set_channel_gains(gains) recording.set_channel_offsets(offsets) - centered_recording = CenterRecording(ScaleTouVRecording(recording=recording)) + centered_recording = CenterRecording(scale_to_uV(recording=recording)) traces_scaled_with_argument = centered_recording.get_traces(return_scaled=True) # Chain preprocessors - centered_recording_scaled = CenterRecording(ScaleTouVRecording(recording=recording)) + centered_recording_scaled = CenterRecording(scale_to_uV(recording=recording)) traces_scaled_with_preprocessor = centered_recording_scaled.get_traces() np.testing.assert_allclose(traces_scaled_with_argument, traces_scaled_with_preprocessor) From 0b5c6358c674b4f5d3af3295bfbdb3bbfda10c13 Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Fri, 28 Jun 2024 16:23:56 -0600 Subject: [PATCH 44/81] fix imports --- src/spikeinterface/preprocessing/preprocessinglist.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/spikeinterface/preprocessing/preprocessinglist.py b/src/spikeinterface/preprocessing/preprocessinglist.py index 7fc3bc0685..8f3729b49b 100644 --- a/src/spikeinterface/preprocessing/preprocessinglist.py +++ b/src/spikeinterface/preprocessing/preprocessinglist.py @@ -24,7 +24,7 @@ CenterRecording, center, ) -from .scale import ScaleTouVRecording, scale_to_uV +from .scale import scale_to_uV from .whiten import WhitenRecording, whiten, compute_whitening_matrix from .rectify import RectifyRecording, rectify @@ -56,7 +56,6 @@ ScaleRecording, CenterRecording, ZScoreRecording, - ScaleTouVRecording, # decorrelation stuff WhitenRecording, # re-reference From 4539550f72883b3ed2339c8a73a52c6d811647f9 Mon Sep 17 00:00:00 2001 From: Pierre Yger Date: Sat, 29 Jun 2024 11:57:37 +0200 Subject: [PATCH 45/81] Tools for Generation of Hybrid recordings (#2436) Hybrid recording framework --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Alessio Buccino Co-authored-by: Heberto Mayorquin Co-authored-by: Charlie Windolf --- .../benchmark_with_hybrid_recordings.rst | 2552 +++++++++++++++++ .../benchmark_with_hybrid_recordings_20_0.png | Bin 0 -> 183377 bytes .../benchmark_with_hybrid_recordings_28_1.png | Bin 0 -> 393421 bytes .../benchmark_with_hybrid_recordings_37_1.png | Bin 0 -> 81662 bytes .../benchmark_with_hybrid_recordings_9_0.png | Bin 0 -> 212689 bytes doc/how_to/index.rst | 1 + examples/how_to/README.md | 12 +- ..._neuropixels.py => analyze_neuropixels.py} | 2 +- .../benchmark_with_hybrid_recordings.py | 293 ++ pyproject.toml | 3 + src/spikeinterface/core/core_tools.py | 4 + src/spikeinterface/core/generate.py | 3 +- src/spikeinterface/core/node_pipeline.py | 1 - src/spikeinterface/core/sortinganalyzer.py | 4 +- src/spikeinterface/core/template.py | 10 +- src/spikeinterface/core/template_tools.py | 3 +- src/spikeinterface/generation/__init__.py | 8 + src/spikeinterface/generation/drift_tools.py | 85 +- .../generation/drifting_generator.py | 102 +- src/spikeinterface/generation/hybrid_tools.py | 568 ++++ src/spikeinterface/generation/noise_tools.py | 15 +- .../generation/tests/test_drift_tools.py | 24 +- .../generation/tests/test_hybrid_tools.py | 83 + .../generation/tests/test_mock.py | 3 - src/spikeinterface/postprocessing/__init__.py | 1 - .../postprocessing/localization_tools.py | 623 ++++ .../postprocessing/unit_locations.py | 608 +--- src/spikeinterface/preprocessing/__init__.py | 2 +- src/spikeinterface/preprocessing/motion.py | 53 +- .../preprocessing/tests/test_motion.py | 12 +- .../sorters/internal/spyking_circus2.py | 43 +- .../benchmark/benchmark_peak_localization.py | 2 +- .../sortingcomponents/motion_utils.py | 14 +- .../sortingcomponents/peak_detection.py | 2 +- .../sortingcomponents/peak_localization.py | 7 +- src/spikeinterface/sortingcomponents/tools.py | 1 + src/spikeinterface/widgets/unit_waveforms.py | 4 +- 37 files changed, 4399 insertions(+), 749 deletions(-) create mode 100644 doc/how_to/benchmark_with_hybrid_recordings.rst create mode 100644 doc/how_to/benchmark_with_hybrid_recordings_files/benchmark_with_hybrid_recordings_20_0.png create mode 100644 doc/how_to/benchmark_with_hybrid_recordings_files/benchmark_with_hybrid_recordings_28_1.png create mode 100644 doc/how_to/benchmark_with_hybrid_recordings_files/benchmark_with_hybrid_recordings_37_1.png create mode 100644 doc/how_to/benchmark_with_hybrid_recordings_files/benchmark_with_hybrid_recordings_9_0.png rename examples/how_to/{analyse_neuropixels.py => analyze_neuropixels.py} (99%) create mode 100644 examples/how_to/benchmark_with_hybrid_recordings.py create mode 100644 src/spikeinterface/generation/hybrid_tools.py create mode 100644 src/spikeinterface/generation/tests/test_hybrid_tools.py delete mode 100644 src/spikeinterface/generation/tests/test_mock.py create mode 100644 src/spikeinterface/postprocessing/localization_tools.py diff --git a/doc/how_to/benchmark_with_hybrid_recordings.rst b/doc/how_to/benchmark_with_hybrid_recordings.rst new file mode 100644 index 0000000000..9e8c6c7d65 --- /dev/null +++ b/doc/how_to/benchmark_with_hybrid_recordings.rst @@ -0,0 +1,2552 @@ +Benchmark spike sorting with hybrid recordings +============================================== + +This example shows how to use the SpikeInterface hybrid recordings +framework to benchmark spike sorting results. + +Hybrid recordings are built from existing recordings by injecting units +with known spiking activity. The template (aka average waveforms) of the +injected units can be from previous spike sorted data. In this example, +we will be using an open database of templates that we have constructed +from the International Brain Laboratory - Brain Wide Map (available on +`DANDI `__). + +Importantly, recordings from long-shank probes, such as Neuropixels, +usually experience drifts. Such drifts have to be taken into account in +order to smoothly inject spikes into the recording. + +.. code:: ipython3 + + import spikeinterface as si + import spikeinterface.extractors as se + import spikeinterface.preprocessing as spre + import spikeinterface.comparison as sc + import spikeinterface.generation as sgen + import spikeinterface.widgets as sw + + from spikeinterface.sortingcomponents.motion_estimation import estimate_motion + + import numpy as np + import matplotlib.pyplot as plt + from pathlib import Path + +.. code:: ipython3 + + %matplotlib inline + +.. code:: ipython3 + + si.set_global_job_kwargs(n_jobs=16) + +For this notebook, we will use a drifting recording similar to the one +acquired by Nick Steinmetz and available +`here `__, where an +triangular motion was imposed to the recording by moving the probe up +and down with a micro-manipulator. + +.. code:: ipython3 + + workdir = Path("/ssd980/working/hybrid/steinmetz_imposed_motion") + workdir.mkdir(exist_ok=True) + +.. code:: ipython3 + + recording_np1_imposed = se.read_spikeglx("/hdd1/data/spikeglx/nick-steinmetz/dataset1/p1_g0_t0/") + recording_preproc = spre.highpass_filter(recording_np1_imposed) + recording_preproc = spre.common_reference(recording_preproc) + +To visualize the drift, we can estimate the motion and plot it: + +.. code:: ipython3 + + # to correct for drift, we need a float dtype + recording_preproc = spre.astype(recording_preproc, "float") + _, motion_info = spre.correct_motion( + recording_preproc, preset="nonrigid_fast_and_accurate", n_jobs=4, progress_bar=True, output_motion_info=True + ) + + + +.. parsed-literal:: + + detect and localize: 0%| | 0/1958 [00:00 {minimum_depth}") + len(templates_selected_info) + + + + +.. parsed-literal:: + + 31 + + + +We can now retrieve the selected templates as a ``Templates`` object: + +.. code:: ipython3 + + templates_selected = sgen.query_templates_from_database(templates_selected_info, verbose=True) + print(templates_selected) + + +.. parsed-literal:: + + Fetching templates from 2 datasets + Templates: 31 units - 240 samples - 384 channels + sampling_frequency=30.00 kHz - ms_before=3.00 ms - ms_after=5.00 ms + Probe - IMEC - Neuropixels 1.0 - 18194814141 - 384ch - 1shanks + + +While we selected templates from a target aread and at certain depths, +we can see that the template amplitudes are quite large. This will make +spike sorting easy… we can further manipulate the ``Templates`` by +rescaling, relocating, or further selections with the +``sgen.scale_template_to_range``, ``sgen.relocate_templates``, and +``sgen.select_templates`` functions. + +In our case, let’s rescale the amplitudes between 50 and 150 +:math:`\mu`\ V and relocate them towards the bottom half of the probe, +where the activity looks interesting! + +.. code:: ipython3 + + min_amplitude = 50 + max_amplitude = 150 + templates_scaled = sgen.scale_template_to_range( + templates=templates_selected, + min_amplitude=min_amplitude, + max_amplitude=max_amplitude + ) + + min_displacement = 1000 + max_displacement = 3000 + templates_relocated = sgen.relocate_templates( + templates=templates_scaled, + min_displacement=min_displacement, + max_displacement=max_displacement + ) + +Let’s plot the selected templates: + +.. code:: ipython3 + + sparsity_plot = si.compute_sparsity(templates_relocated) + fig = plt.figure(figsize=(10, 10)) + w = sw.plot_unit_templates(templates_relocated, sparsity=sparsity_plot, ncols=4, figure=fig) + w.figure.subplots_adjust(wspace=0.5, hspace=0.7) + + + +.. image:: benchmark_with_hybrid_recordings_files/benchmark_with_hybrid_recordings_20_0.png + + +Constructing hybrid recordings +------------------------------ + +We can construct now hybrid recordings with the selected templates. + +We will do this in two ways to show how important it is to account for +drifts when injecting hybrid spikes. + +- For the first recording we will not pass the estimated motion + (``recording_hybrid_ignore_drift``). +- For the second recording, we will pass and account for the estimated + motion (``recording_hybrid_with_drift``). + +.. code:: ipython3 + + recording_hybrid_ignore_drift, sorting_hybrid = sgen.generate_hybrid_recording( + recording=recording_preproc, templates=templates_relocated, seed=2308 + ) + recording_hybrid_ignore_drift + + + + +.. raw:: html + +
InjectTemplatesRecording: 384 channels - 30.0kHz - 1 segments - 58,715,724 samples - 1,957.19s (32.62 minutes) - float64 dtype - 167.99 GiB
Channel IDs
    ['imec0.ap#AP0' 'imec0.ap#AP1' 'imec0.ap#AP2' 'imec0.ap#AP3' + 'imec0.ap#AP4' 'imec0.ap#AP5' 'imec0.ap#AP6' 'imec0.ap#AP7' + 'imec0.ap#AP8' 'imec0.ap#AP9' 'imec0.ap#AP10' 'imec0.ap#AP11' + 'imec0.ap#AP12' 'imec0.ap#AP13' 'imec0.ap#AP14' 'imec0.ap#AP15' + 'imec0.ap#AP16' 'imec0.ap#AP17' 'imec0.ap#AP18' 'imec0.ap#AP19' + 'imec0.ap#AP20' 'imec0.ap#AP21' 'imec0.ap#AP22' 'imec0.ap#AP23' + 'imec0.ap#AP24' 'imec0.ap#AP25' 'imec0.ap#AP26' 'imec0.ap#AP27' + 'imec0.ap#AP28' 'imec0.ap#AP29' 'imec0.ap#AP30' 'imec0.ap#AP31' + 'imec0.ap#AP32' 'imec0.ap#AP33' 'imec0.ap#AP34' 'imec0.ap#AP35' + 'imec0.ap#AP36' 'imec0.ap#AP37' 'imec0.ap#AP38' 'imec0.ap#AP39' + 'imec0.ap#AP40' 'imec0.ap#AP41' 'imec0.ap#AP42' 'imec0.ap#AP43' + 'imec0.ap#AP44' 'imec0.ap#AP45' 'imec0.ap#AP46' 'imec0.ap#AP47' + 'imec0.ap#AP48' 'imec0.ap#AP49' 'imec0.ap#AP50' 'imec0.ap#AP51' + 'imec0.ap#AP52' 'imec0.ap#AP53' 'imec0.ap#AP54' 'imec0.ap#AP55' + 'imec0.ap#AP56' 'imec0.ap#AP57' 'imec0.ap#AP58' 'imec0.ap#AP59' + 'imec0.ap#AP60' 'imec0.ap#AP61' 'imec0.ap#AP62' 'imec0.ap#AP63' + 'imec0.ap#AP64' 'imec0.ap#AP65' 'imec0.ap#AP66' 'imec0.ap#AP67' + 'imec0.ap#AP68' 'imec0.ap#AP69' 'imec0.ap#AP70' 'imec0.ap#AP71' + 'imec0.ap#AP72' 'imec0.ap#AP73' 'imec0.ap#AP74' 'imec0.ap#AP75' + 'imec0.ap#AP76' 'imec0.ap#AP77' 'imec0.ap#AP78' 'imec0.ap#AP79' + 'imec0.ap#AP80' 'imec0.ap#AP81' 'imec0.ap#AP82' 'imec0.ap#AP83' + 'imec0.ap#AP84' 'imec0.ap#AP85' 'imec0.ap#AP86' 'imec0.ap#AP87' + 'imec0.ap#AP88' 'imec0.ap#AP89' 'imec0.ap#AP90' 'imec0.ap#AP91' + 'imec0.ap#AP92' 'imec0.ap#AP93' 'imec0.ap#AP94' 'imec0.ap#AP95' + 'imec0.ap#AP96' 'imec0.ap#AP97' 'imec0.ap#AP98' 'imec0.ap#AP99' + 'imec0.ap#AP100' 'imec0.ap#AP101' 'imec0.ap#AP102' 'imec0.ap#AP103' + 'imec0.ap#AP104' 'imec0.ap#AP105' 'imec0.ap#AP106' 'imec0.ap#AP107' + 'imec0.ap#AP108' 'imec0.ap#AP109' 'imec0.ap#AP110' 'imec0.ap#AP111' + 'imec0.ap#AP112' 'imec0.ap#AP113' 'imec0.ap#AP114' 'imec0.ap#AP115' + 'imec0.ap#AP116' 'imec0.ap#AP117' 'imec0.ap#AP118' 'imec0.ap#AP119' + 'imec0.ap#AP120' 'imec0.ap#AP121' 'imec0.ap#AP122' 'imec0.ap#AP123' + 'imec0.ap#AP124' 'imec0.ap#AP125' 'imec0.ap#AP126' 'imec0.ap#AP127' + 'imec0.ap#AP128' 'imec0.ap#AP129' 'imec0.ap#AP130' 'imec0.ap#AP131' + 'imec0.ap#AP132' 'imec0.ap#AP133' 'imec0.ap#AP134' 'imec0.ap#AP135' + 'imec0.ap#AP136' 'imec0.ap#AP137' 'imec0.ap#AP138' 'imec0.ap#AP139' + 'imec0.ap#AP140' 'imec0.ap#AP141' 'imec0.ap#AP142' 'imec0.ap#AP143' + 'imec0.ap#AP144' 'imec0.ap#AP145' 'imec0.ap#AP146' 'imec0.ap#AP147' + 'imec0.ap#AP148' 'imec0.ap#AP149' 'imec0.ap#AP150' 'imec0.ap#AP151' + 'imec0.ap#AP152' 'imec0.ap#AP153' 'imec0.ap#AP154' 'imec0.ap#AP155' + 'imec0.ap#AP156' 'imec0.ap#AP157' 'imec0.ap#AP158' 'imec0.ap#AP159' + 'imec0.ap#AP160' 'imec0.ap#AP161' 'imec0.ap#AP162' 'imec0.ap#AP163' + 'imec0.ap#AP164' 'imec0.ap#AP165' 'imec0.ap#AP166' 'imec0.ap#AP167' + 'imec0.ap#AP168' 'imec0.ap#AP169' 'imec0.ap#AP170' 'imec0.ap#AP171' + 'imec0.ap#AP172' 'imec0.ap#AP173' 'imec0.ap#AP174' 'imec0.ap#AP175' + 'imec0.ap#AP176' 'imec0.ap#AP177' 'imec0.ap#AP178' 'imec0.ap#AP179' + 'imec0.ap#AP180' 'imec0.ap#AP181' 'imec0.ap#AP182' 'imec0.ap#AP183' + 'imec0.ap#AP184' 'imec0.ap#AP185' 'imec0.ap#AP186' 'imec0.ap#AP187' + 'imec0.ap#AP188' 'imec0.ap#AP189' 'imec0.ap#AP190' 'imec0.ap#AP191' + 'imec0.ap#AP192' 'imec0.ap#AP193' 'imec0.ap#AP194' 'imec0.ap#AP195' + 'imec0.ap#AP196' 'imec0.ap#AP197' 'imec0.ap#AP198' 'imec0.ap#AP199' + 'imec0.ap#AP200' 'imec0.ap#AP201' 'imec0.ap#AP202' 'imec0.ap#AP203' + 'imec0.ap#AP204' 'imec0.ap#AP205' 'imec0.ap#AP206' 'imec0.ap#AP207' + 'imec0.ap#AP208' 'imec0.ap#AP209' 'imec0.ap#AP210' 'imec0.ap#AP211' + 'imec0.ap#AP212' 'imec0.ap#AP213' 'imec0.ap#AP214' 'imec0.ap#AP215' + 'imec0.ap#AP216' 'imec0.ap#AP217' 'imec0.ap#AP218' 'imec0.ap#AP219' + 'imec0.ap#AP220' 'imec0.ap#AP221' 'imec0.ap#AP222' 'imec0.ap#AP223' + 'imec0.ap#AP224' 'imec0.ap#AP225' 'imec0.ap#AP226' 'imec0.ap#AP227' + 'imec0.ap#AP228' 'imec0.ap#AP229' 'imec0.ap#AP230' 'imec0.ap#AP231' + 'imec0.ap#AP232' 'imec0.ap#AP233' 'imec0.ap#AP234' 'imec0.ap#AP235' + 'imec0.ap#AP236' 'imec0.ap#AP237' 'imec0.ap#AP238' 'imec0.ap#AP239' + 'imec0.ap#AP240' 'imec0.ap#AP241' 'imec0.ap#AP242' 'imec0.ap#AP243' + 'imec0.ap#AP244' 'imec0.ap#AP245' 'imec0.ap#AP246' 'imec0.ap#AP247' + 'imec0.ap#AP248' 'imec0.ap#AP249' 'imec0.ap#AP250' 'imec0.ap#AP251' + 'imec0.ap#AP252' 'imec0.ap#AP253' 'imec0.ap#AP254' 'imec0.ap#AP255' + 'imec0.ap#AP256' 'imec0.ap#AP257' 'imec0.ap#AP258' 'imec0.ap#AP259' + 'imec0.ap#AP260' 'imec0.ap#AP261' 'imec0.ap#AP262' 'imec0.ap#AP263' + 'imec0.ap#AP264' 'imec0.ap#AP265' 'imec0.ap#AP266' 'imec0.ap#AP267' + 'imec0.ap#AP268' 'imec0.ap#AP269' 'imec0.ap#AP270' 'imec0.ap#AP271' + 'imec0.ap#AP272' 'imec0.ap#AP273' 'imec0.ap#AP274' 'imec0.ap#AP275' + 'imec0.ap#AP276' 'imec0.ap#AP277' 'imec0.ap#AP278' 'imec0.ap#AP279' + 'imec0.ap#AP280' 'imec0.ap#AP281' 'imec0.ap#AP282' 'imec0.ap#AP283' + 'imec0.ap#AP284' 'imec0.ap#AP285' 'imec0.ap#AP286' 'imec0.ap#AP287' + 'imec0.ap#AP288' 'imec0.ap#AP289' 'imec0.ap#AP290' 'imec0.ap#AP291' + 'imec0.ap#AP292' 'imec0.ap#AP293' 'imec0.ap#AP294' 'imec0.ap#AP295' + 'imec0.ap#AP296' 'imec0.ap#AP297' 'imec0.ap#AP298' 'imec0.ap#AP299' + 'imec0.ap#AP300' 'imec0.ap#AP301' 'imec0.ap#AP302' 'imec0.ap#AP303' + 'imec0.ap#AP304' 'imec0.ap#AP305' 'imec0.ap#AP306' 'imec0.ap#AP307' + 'imec0.ap#AP308' 'imec0.ap#AP309' 'imec0.ap#AP310' 'imec0.ap#AP311' + 'imec0.ap#AP312' 'imec0.ap#AP313' 'imec0.ap#AP314' 'imec0.ap#AP315' + 'imec0.ap#AP316' 'imec0.ap#AP317' 'imec0.ap#AP318' 'imec0.ap#AP319' + 'imec0.ap#AP320' 'imec0.ap#AP321' 'imec0.ap#AP322' 'imec0.ap#AP323' + 'imec0.ap#AP324' 'imec0.ap#AP325' 'imec0.ap#AP326' 'imec0.ap#AP327' + 'imec0.ap#AP328' 'imec0.ap#AP329' 'imec0.ap#AP330' 'imec0.ap#AP331' + 'imec0.ap#AP332' 'imec0.ap#AP333' 'imec0.ap#AP334' 'imec0.ap#AP335' + 'imec0.ap#AP336' 'imec0.ap#AP337' 'imec0.ap#AP338' 'imec0.ap#AP339' + 'imec0.ap#AP340' 'imec0.ap#AP341' 'imec0.ap#AP342' 'imec0.ap#AP343' + 'imec0.ap#AP344' 'imec0.ap#AP345' 'imec0.ap#AP346' 'imec0.ap#AP347' + 'imec0.ap#AP348' 'imec0.ap#AP349' 'imec0.ap#AP350' 'imec0.ap#AP351' + 'imec0.ap#AP352' 'imec0.ap#AP353' 'imec0.ap#AP354' 'imec0.ap#AP355' + 'imec0.ap#AP356' 'imec0.ap#AP357' 'imec0.ap#AP358' 'imec0.ap#AP359' + 'imec0.ap#AP360' 'imec0.ap#AP361' 'imec0.ap#AP362' 'imec0.ap#AP363' + 'imec0.ap#AP364' 'imec0.ap#AP365' 'imec0.ap#AP366' 'imec0.ap#AP367' + 'imec0.ap#AP368' 'imec0.ap#AP369' 'imec0.ap#AP370' 'imec0.ap#AP371' + 'imec0.ap#AP372' 'imec0.ap#AP373' 'imec0.ap#AP374' 'imec0.ap#AP375' + 'imec0.ap#AP376' 'imec0.ap#AP377' 'imec0.ap#AP378' 'imec0.ap#AP379' + 'imec0.ap#AP380' 'imec0.ap#AP381' 'imec0.ap#AP382' 'imec0.ap#AP383']
Annotations
  • is_filtered : True
  • probe_0_planar_contour : [[ -11 9989] + [ -11 -11] + [ 24 -186] + [ 59 -11] + [ 59 9989]]
  • probes_info : [{'model_name': 'Neuropixels 1.0', 'manufacturer': 'IMEC', 'probe_type': '0', 'serial_number': '18408406612', 'part_number': 'PRB_1_4_0480_1_C', 'port': '1', 'slot': '2'}]
Channel Properties
    gain_to_uV [2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375]
    offset_to_uV [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
    channel_names ['AP0' 'AP1' 'AP2' 'AP3' 'AP4' 'AP5' 'AP6' 'AP7' 'AP8' 'AP9' 'AP10' 'AP11' + 'AP12' 'AP13' 'AP14' 'AP15' 'AP16' 'AP17' 'AP18' 'AP19' 'AP20' 'AP21' + 'AP22' 'AP23' 'AP24' 'AP25' 'AP26' 'AP27' 'AP28' 'AP29' 'AP30' 'AP31' + 'AP32' 'AP33' 'AP34' 'AP35' 'AP36' 'AP37' 'AP38' 'AP39' 'AP40' 'AP41' + 'AP42' 'AP43' 'AP44' 'AP45' 'AP46' 'AP47' 'AP48' 'AP49' 'AP50' 'AP51' + 'AP52' 'AP53' 'AP54' 'AP55' 'AP56' 'AP57' 'AP58' 'AP59' 'AP60' 'AP61' + 'AP62' 'AP63' 'AP64' 'AP65' 'AP66' 'AP67' 'AP68' 'AP69' 'AP70' 'AP71' + 'AP72' 'AP73' 'AP74' 'AP75' 'AP76' 'AP77' 'AP78' 'AP79' 'AP80' 'AP81' + 'AP82' 'AP83' 'AP84' 'AP85' 'AP86' 'AP87' 'AP88' 'AP89' 'AP90' 'AP91' + 'AP92' 'AP93' 'AP94' 'AP95' 'AP96' 'AP97' 'AP98' 'AP99' 'AP100' 'AP101' + 'AP102' 'AP103' 'AP104' 'AP105' 'AP106' 'AP107' 'AP108' 'AP109' 'AP110' + 'AP111' 'AP112' 'AP113' 'AP114' 'AP115' 'AP116' 'AP117' 'AP118' 'AP119' + 'AP120' 'AP121' 'AP122' 'AP123' 'AP124' 'AP125' 'AP126' 'AP127' 'AP128' + 'AP129' 'AP130' 'AP131' 'AP132' 'AP133' 'AP134' 'AP135' 'AP136' 'AP137' + 'AP138' 'AP139' 'AP140' 'AP141' 'AP142' 'AP143' 'AP144' 'AP145' 'AP146' + 'AP147' 'AP148' 'AP149' 'AP150' 'AP151' 'AP152' 'AP153' 'AP154' 'AP155' + 'AP156' 'AP157' 'AP158' 'AP159' 'AP160' 'AP161' 'AP162' 'AP163' 'AP164' + 'AP165' 'AP166' 'AP167' 'AP168' 'AP169' 'AP170' 'AP171' 'AP172' 'AP173' + 'AP174' 'AP175' 'AP176' 'AP177' 'AP178' 'AP179' 'AP180' 'AP181' 'AP182' + 'AP183' 'AP184' 'AP185' 'AP186' 'AP187' 'AP188' 'AP189' 'AP190' 'AP191' + 'AP192' 'AP193' 'AP194' 'AP195' 'AP196' 'AP197' 'AP198' 'AP199' 'AP200' + 'AP201' 'AP202' 'AP203' 'AP204' 'AP205' 'AP206' 'AP207' 'AP208' 'AP209' + 'AP210' 'AP211' 'AP212' 'AP213' 'AP214' 'AP215' 'AP216' 'AP217' 'AP218' + 'AP219' 'AP220' 'AP221' 'AP222' 'AP223' 'AP224' 'AP225' 'AP226' 'AP227' + 'AP228' 'AP229' 'AP230' 'AP231' 'AP232' 'AP233' 'AP234' 'AP235' 'AP236' + 'AP237' 'AP238' 'AP239' 'AP240' 'AP241' 'AP242' 'AP243' 'AP244' 'AP245' + 'AP246' 'AP247' 'AP248' 'AP249' 'AP250' 'AP251' 'AP252' 'AP253' 'AP254' + 'AP255' 'AP256' 'AP257' 'AP258' 'AP259' 'AP260' 'AP261' 'AP262' 'AP263' + 'AP264' 'AP265' 'AP266' 'AP267' 'AP268' 'AP269' 'AP270' 'AP271' 'AP272' + 'AP273' 'AP274' 'AP275' 'AP276' 'AP277' 'AP278' 'AP279' 'AP280' 'AP281' + 'AP282' 'AP283' 'AP284' 'AP285' 'AP286' 'AP287' 'AP288' 'AP289' 'AP290' + 'AP291' 'AP292' 'AP293' 'AP294' 'AP295' 'AP296' 'AP297' 'AP298' 'AP299' + 'AP300' 'AP301' 'AP302' 'AP303' 'AP304' 'AP305' 'AP306' 'AP307' 'AP308' + 'AP309' 'AP310' 'AP311' 'AP312' 'AP313' 'AP314' 'AP315' 'AP316' 'AP317' + 'AP318' 'AP319' 'AP320' 'AP321' 'AP322' 'AP323' 'AP324' 'AP325' 'AP326' + 'AP327' 'AP328' 'AP329' 'AP330' 'AP331' 'AP332' 'AP333' 'AP334' 'AP335' + 'AP336' 'AP337' 'AP338' 'AP339' 'AP340' 'AP341' 'AP342' 'AP343' 'AP344' + 'AP345' 'AP346' 'AP347' 'AP348' 'AP349' 'AP350' 'AP351' 'AP352' 'AP353' + 'AP354' 'AP355' 'AP356' 'AP357' 'AP358' 'AP359' 'AP360' 'AP361' 'AP362' + 'AP363' 'AP364' 'AP365' 'AP366' 'AP367' 'AP368' 'AP369' 'AP370' 'AP371' + 'AP372' 'AP373' 'AP374' 'AP375' 'AP376' 'AP377' 'AP378' 'AP379' 'AP380' + 'AP381' 'AP382' 'AP383']
    contact_vector [(0, 16., 0., 'square', 12., '', 'e0', 0, 'um', 1., 0., 0., 1., 0, 0, 0, 500, 250, 1) + (0, 48., 0., 'square', 12., '', 'e1', 1, 'um', 1., 0., 0., 1., 1, 0, 0, 500, 250, 1) + (0, 0., 20., 'square', 12., '', 'e2', 2, 'um', 1., 0., 0., 1., 2, 0, 0, 500, 250, 1) + (0, 32., 20., 'square', 12., '', 'e3', 3, 'um', 1., 0., 0., 1., 3, 0, 0, 500, 250, 1) + (0, 16., 40., 'square', 12., '', 'e4', 4, 'um', 1., 0., 0., 1., 4, 0, 0, 500, 250, 1) + (0, 48., 40., 'square', 12., '', 'e5', 5, 'um', 1., 0., 0., 1., 5, 0, 0, 500, 250, 1) + (0, 0., 60., 'square', 12., '', 'e6', 6, 'um', 1., 0., 0., 1., 6, 0, 0, 500, 250, 1) + (0, 32., 60., 'square', 12., '', 'e7', 7, 'um', 1., 0., 0., 1., 7, 0, 0, 500, 250, 1) + (0, 16., 80., 'square', 12., '', 'e8', 8, 'um', 1., 0., 0., 1., 8, 0, 0, 500, 250, 1) + (0, 48., 80., 'square', 12., '', 'e9', 9, 'um', 1., 0., 0., 1., 9, 0, 0, 500, 250, 1) + (0, 0., 100., 'square', 12., '', 'e10', 10, 'um', 1., 0., 0., 1., 10, 0, 0, 500, 250, 1) + (0, 32., 100., 'square', 12., '', 'e11', 11, 'um', 1., 0., 0., 1., 11, 0, 0, 500, 250, 1) + (0, 16., 120., 'square', 12., '', 'e12', 12, 'um', 1., 0., 0., 1., 12, 0, 0, 500, 250, 1) + (0, 48., 120., 'square', 12., '', 'e13', 13, 'um', 1., 0., 0., 1., 13, 0, 0, 500, 250, 1) + (0, 0., 140., 'square', 12., '', 'e14', 14, 'um', 1., 0., 0., 1., 14, 0, 0, 500, 250, 1) + (0, 32., 140., 'square', 12., '', 'e15', 15, 'um', 1., 0., 0., 1., 15, 0, 0, 500, 250, 1) + (0, 16., 160., 'square', 12., '', 'e16', 16, 'um', 1., 0., 0., 1., 16, 0, 0, 500, 250, 1) + (0, 48., 160., 'square', 12., '', 'e17', 17, 'um', 1., 0., 0., 1., 17, 0, 0, 500, 250, 1) + (0, 0., 180., 'square', 12., '', 'e18', 18, 'um', 1., 0., 0., 1., 18, 0, 0, 500, 250, 1) + (0, 32., 180., 'square', 12., '', 'e19', 19, 'um', 1., 0., 0., 1., 19, 0, 0, 500, 250, 1) + (0, 16., 200., 'square', 12., '', 'e20', 20, 'um', 1., 0., 0., 1., 20, 0, 0, 500, 250, 1) + (0, 48., 200., 'square', 12., '', 'e21', 21, 'um', 1., 0., 0., 1., 21, 0, 0, 500, 250, 1) + (0, 0., 220., 'square', 12., '', 'e22', 22, 'um', 1., 0., 0., 1., 22, 0, 0, 500, 250, 1) + (0, 32., 220., 'square', 12., '', 'e23', 23, 'um', 1., 0., 0., 1., 23, 0, 0, 500, 250, 1) + (0, 16., 240., 'square', 12., '', 'e24', 24, 'um', 1., 0., 0., 1., 24, 0, 0, 500, 250, 1) + (0, 48., 240., 'square', 12., '', 'e25', 25, 'um', 1., 0., 0., 1., 25, 0, 0, 500, 250, 1) + (0, 0., 260., 'square', 12., '', 'e26', 26, 'um', 1., 0., 0., 1., 26, 0, 0, 500, 250, 1) + (0, 32., 260., 'square', 12., '', 'e27', 27, 'um', 1., 0., 0., 1., 27, 0, 0, 500, 250, 1) + (0, 16., 280., 'square', 12., '', 'e28', 28, 'um', 1., 0., 0., 1., 28, 0, 0, 500, 250, 1) + (0, 48., 280., 'square', 12., '', 'e29', 29, 'um', 1., 0., 0., 1., 29, 0, 0, 500, 250, 1) + (0, 0., 300., 'square', 12., '', 'e30', 30, 'um', 1., 0., 0., 1., 30, 0, 0, 500, 250, 1) + (0, 32., 300., 'square', 12., '', 'e31', 31, 'um', 1., 0., 0., 1., 31, 0, 0, 500, 250, 1) + (0, 16., 320., 'square', 12., '', 'e32', 32, 'um', 1., 0., 0., 1., 32, 0, 0, 500, 250, 1) + (0, 48., 320., 'square', 12., '', 'e33', 33, 'um', 1., 0., 0., 1., 33, 0, 0, 500, 250, 1) + (0, 0., 340., 'square', 12., '', 'e34', 34, 'um', 1., 0., 0., 1., 34, 0, 0, 500, 250, 1) + (0, 32., 340., 'square', 12., '', 'e35', 35, 'um', 1., 0., 0., 1., 35, 0, 0, 500, 250, 1) + (0, 16., 360., 'square', 12., '', 'e36', 36, 'um', 1., 0., 0., 1., 36, 0, 0, 500, 250, 1) + (0, 48., 360., 'square', 12., '', 'e37', 37, 'um', 1., 0., 0., 1., 37, 0, 0, 500, 250, 1) + (0, 0., 380., 'square', 12., '', 'e38', 38, 'um', 1., 0., 0., 1., 38, 0, 0, 500, 250, 1) + (0, 32., 380., 'square', 12., '', 'e39', 39, 'um', 1., 0., 0., 1., 39, 0, 0, 500, 250, 1) + (0, 16., 400., 'square', 12., '', 'e40', 40, 'um', 1., 0., 0., 1., 40, 0, 0, 500, 250, 1) + (0, 48., 400., 'square', 12., '', 'e41', 41, 'um', 1., 0., 0., 1., 41, 0, 0, 500, 250, 1) + (0, 0., 420., 'square', 12., '', 'e42', 42, 'um', 1., 0., 0., 1., 42, 0, 0, 500, 250, 1) + (0, 32., 420., 'square', 12., '', 'e43', 43, 'um', 1., 0., 0., 1., 43, 0, 0, 500, 250, 1) + (0, 16., 440., 'square', 12., '', 'e44', 44, 'um', 1., 0., 0., 1., 44, 0, 0, 500, 250, 1) + (0, 48., 440., 'square', 12., '', 'e45', 45, 'um', 1., 0., 0., 1., 45, 0, 0, 500, 250, 1) + (0, 0., 460., 'square', 12., '', 'e46', 46, 'um', 1., 0., 0., 1., 46, 0, 0, 500, 250, 1) + (0, 32., 460., 'square', 12., '', 'e47', 47, 'um', 1., 0., 0., 1., 47, 0, 0, 500, 250, 1) + (0, 16., 480., 'square', 12., '', 'e48', 48, 'um', 1., 0., 0., 1., 48, 0, 0, 500, 250, 1) + (0, 48., 480., 'square', 12., '', 'e49', 49, 'um', 1., 0., 0., 1., 49, 0, 0, 500, 250, 1) + (0, 0., 500., 'square', 12., '', 'e50', 50, 'um', 1., 0., 0., 1., 50, 0, 0, 500, 250, 1) + (0, 32., 500., 'square', 12., '', 'e51', 51, 'um', 1., 0., 0., 1., 51, 0, 0, 500, 250, 1) + (0, 16., 520., 'square', 12., '', 'e52', 52, 'um', 1., 0., 0., 1., 52, 0, 0, 500, 250, 1) + (0, 48., 520., 'square', 12., '', 'e53', 53, 'um', 1., 0., 0., 1., 53, 0, 0, 500, 250, 1) + (0, 0., 540., 'square', 12., '', 'e54', 54, 'um', 1., 0., 0., 1., 54, 0, 0, 500, 250, 1) + (0, 32., 540., 'square', 12., '', 'e55', 55, 'um', 1., 0., 0., 1., 55, 0, 0, 500, 250, 1) + (0, 16., 560., 'square', 12., '', 'e56', 56, 'um', 1., 0., 0., 1., 56, 0, 0, 500, 250, 1) + (0, 48., 560., 'square', 12., '', 'e57', 57, 'um', 1., 0., 0., 1., 57, 0, 0, 500, 250, 1) + (0, 0., 580., 'square', 12., '', 'e58', 58, 'um', 1., 0., 0., 1., 58, 0, 0, 500, 250, 1) + (0, 32., 580., 'square', 12., '', 'e59', 59, 'um', 1., 0., 0., 1., 59, 0, 0, 500, 250, 1) + (0, 16., 600., 'square', 12., '', 'e60', 60, 'um', 1., 0., 0., 1., 60, 0, 0, 500, 250, 1) + (0, 48., 600., 'square', 12., '', 'e61', 61, 'um', 1., 0., 0., 1., 61, 0, 0, 500, 250, 1) + (0, 0., 620., 'square', 12., '', 'e62', 62, 'um', 1., 0., 0., 1., 62, 0, 0, 500, 250, 1) + (0, 32., 620., 'square', 12., '', 'e63', 63, 'um', 1., 0., 0., 1., 63, 0, 0, 500, 250, 1) + (0, 16., 640., 'square', 12., '', 'e64', 64, 'um', 1., 0., 0., 1., 64, 0, 0, 500, 250, 1) + (0, 48., 640., 'square', 12., '', 'e65', 65, 'um', 1., 0., 0., 1., 65, 0, 0, 500, 250, 1) + (0, 0., 660., 'square', 12., '', 'e66', 66, 'um', 1., 0., 0., 1., 66, 0, 0, 500, 250, 1) + (0, 32., 660., 'square', 12., '', 'e67', 67, 'um', 1., 0., 0., 1., 67, 0, 0, 500, 250, 1) + (0, 16., 680., 'square', 12., '', 'e68', 68, 'um', 1., 0., 0., 1., 68, 0, 0, 500, 250, 1) + (0, 48., 680., 'square', 12., '', 'e69', 69, 'um', 1., 0., 0., 1., 69, 0, 0, 500, 250, 1) + (0, 0., 700., 'square', 12., '', 'e70', 70, 'um', 1., 0., 0., 1., 70, 0, 0, 500, 250, 1) + (0, 32., 700., 'square', 12., '', 'e71', 71, 'um', 1., 0., 0., 1., 71, 0, 0, 500, 250, 1) + (0, 16., 720., 'square', 12., '', 'e72', 72, 'um', 1., 0., 0., 1., 72, 0, 0, 500, 250, 1) + (0, 48., 720., 'square', 12., '', 'e73', 73, 'um', 1., 0., 0., 1., 73, 0, 0, 500, 250, 1) + (0, 0., 740., 'square', 12., '', 'e74', 74, 'um', 1., 0., 0., 1., 74, 0, 0, 500, 250, 1) + (0, 32., 740., 'square', 12., '', 'e75', 75, 'um', 1., 0., 0., 1., 75, 0, 0, 500, 250, 1) + (0, 16., 760., 'square', 12., '', 'e76', 76, 'um', 1., 0., 0., 1., 76, 0, 0, 500, 250, 1) + (0, 48., 760., 'square', 12., '', 'e77', 77, 'um', 1., 0., 0., 1., 77, 0, 0, 500, 250, 1) + (0, 0., 780., 'square', 12., '', 'e78', 78, 'um', 1., 0., 0., 1., 78, 0, 0, 500, 250, 1) + (0, 32., 780., 'square', 12., '', 'e79', 79, 'um', 1., 0., 0., 1., 79, 0, 0, 500, 250, 1) + (0, 16., 800., 'square', 12., '', 'e80', 80, 'um', 1., 0., 0., 1., 80, 0, 0, 500, 250, 1) + (0, 48., 800., 'square', 12., '', 'e81', 81, 'um', 1., 0., 0., 1., 81, 0, 0, 500, 250, 1) + (0, 0., 820., 'square', 12., '', 'e82', 82, 'um', 1., 0., 0., 1., 82, 0, 0, 500, 250, 1) + (0, 32., 820., 'square', 12., '', 'e83', 83, 'um', 1., 0., 0., 1., 83, 0, 0, 500, 250, 1) + (0, 16., 840., 'square', 12., '', 'e84', 84, 'um', 1., 0., 0., 1., 84, 0, 0, 500, 250, 1) + (0, 48., 840., 'square', 12., '', 'e85', 85, 'um', 1., 0., 0., 1., 85, 0, 0, 500, 250, 1) + (0, 0., 860., 'square', 12., '', 'e86', 86, 'um', 1., 0., 0., 1., 86, 0, 0, 500, 250, 1) + (0, 32., 860., 'square', 12., '', 'e87', 87, 'um', 1., 0., 0., 1., 87, 0, 0, 500, 250, 1) + (0, 16., 880., 'square', 12., '', 'e88', 88, 'um', 1., 0., 0., 1., 88, 0, 0, 500, 250, 1) + (0, 48., 880., 'square', 12., '', 'e89', 89, 'um', 1., 0., 0., 1., 89, 0, 0, 500, 250, 1) + (0, 0., 900., 'square', 12., '', 'e90', 90, 'um', 1., 0., 0., 1., 90, 0, 0, 500, 250, 1) + (0, 32., 900., 'square', 12., '', 'e91', 91, 'um', 1., 0., 0., 1., 91, 0, 0, 500, 250, 1) + (0, 16., 920., 'square', 12., '', 'e92', 92, 'um', 1., 0., 0., 1., 92, 0, 0, 500, 250, 1) + (0, 48., 920., 'square', 12., '', 'e93', 93, 'um', 1., 0., 0., 1., 93, 0, 0, 500, 250, 1) + (0, 0., 940., 'square', 12., '', 'e94', 94, 'um', 1., 0., 0., 1., 94, 0, 0, 500, 250, 1) + (0, 32., 940., 'square', 12., '', 'e95', 95, 'um', 1., 0., 0., 1., 95, 0, 0, 500, 250, 1) + (0, 16., 960., 'square', 12., '', 'e96', 96, 'um', 1., 0., 0., 1., 96, 0, 0, 500, 250, 1) + (0, 48., 960., 'square', 12., '', 'e97', 97, 'um', 1., 0., 0., 1., 97, 0, 0, 500, 250, 1) + (0, 0., 980., 'square', 12., '', 'e98', 98, 'um', 1., 0., 0., 1., 98, 0, 0, 500, 250, 1) + (0, 32., 980., 'square', 12., '', 'e99', 99, 'um', 1., 0., 0., 1., 99, 0, 0, 500, 250, 1) + (0, 16., 1000., 'square', 12., '', 'e100', 100, 'um', 1., 0., 0., 1., 100, 0, 0, 500, 250, 1) + (0, 48., 1000., 'square', 12., '', 'e101', 101, 'um', 1., 0., 0., 1., 101, 0, 0, 500, 250, 1) + (0, 0., 1020., 'square', 12., '', 'e102', 102, 'um', 1., 0., 0., 1., 102, 0, 0, 500, 250, 1) + (0, 32., 1020., 'square', 12., '', 'e103', 103, 'um', 1., 0., 0., 1., 103, 0, 0, 500, 250, 1) + (0, 16., 1040., 'square', 12., '', 'e104', 104, 'um', 1., 0., 0., 1., 104, 0, 0, 500, 250, 1) + (0, 48., 1040., 'square', 12., '', 'e105', 105, 'um', 1., 0., 0., 1., 105, 0, 0, 500, 250, 1) + (0, 0., 1060., 'square', 12., '', 'e106', 106, 'um', 1., 0., 0., 1., 106, 0, 0, 500, 250, 1) + (0, 32., 1060., 'square', 12., '', 'e107', 107, 'um', 1., 0., 0., 1., 107, 0, 0, 500, 250, 1) + (0, 16., 1080., 'square', 12., '', 'e108', 108, 'um', 1., 0., 0., 1., 108, 0, 0, 500, 250, 1) + (0, 48., 1080., 'square', 12., '', 'e109', 109, 'um', 1., 0., 0., 1., 109, 0, 0, 500, 250, 1) + (0, 0., 1100., 'square', 12., '', 'e110', 110, 'um', 1., 0., 0., 1., 110, 0, 0, 500, 250, 1) + (0, 32., 1100., 'square', 12., '', 'e111', 111, 'um', 1., 0., 0., 1., 111, 0, 0, 500, 250, 1) + (0, 16., 1120., 'square', 12., '', 'e112', 112, 'um', 1., 0., 0., 1., 112, 0, 0, 500, 250, 1) + (0, 48., 1120., 'square', 12., '', 'e113', 113, 'um', 1., 0., 0., 1., 113, 0, 0, 500, 250, 1) + (0, 0., 1140., 'square', 12., '', 'e114', 114, 'um', 1., 0., 0., 1., 114, 0, 0, 500, 250, 1) + (0, 32., 1140., 'square', 12., '', 'e115', 115, 'um', 1., 0., 0., 1., 115, 0, 0, 500, 250, 1) + (0, 16., 1160., 'square', 12., '', 'e116', 116, 'um', 1., 0., 0., 1., 116, 0, 0, 500, 250, 1) + (0, 48., 1160., 'square', 12., '', 'e117', 117, 'um', 1., 0., 0., 1., 117, 0, 0, 500, 250, 1) + (0, 0., 1180., 'square', 12., '', 'e118', 118, 'um', 1., 0., 0., 1., 118, 0, 0, 500, 250, 1) + (0, 32., 1180., 'square', 12., '', 'e119', 119, 'um', 1., 0., 0., 1., 119, 0, 0, 500, 250, 1) + (0, 16., 1200., 'square', 12., '', 'e120', 120, 'um', 1., 0., 0., 1., 120, 0, 0, 500, 250, 1) + (0, 48., 1200., 'square', 12., '', 'e121', 121, 'um', 1., 0., 0., 1., 121, 0, 0, 500, 250, 1) + (0, 0., 1220., 'square', 12., '', 'e122', 122, 'um', 1., 0., 0., 1., 122, 0, 0, 500, 250, 1) + (0, 32., 1220., 'square', 12., '', 'e123', 123, 'um', 1., 0., 0., 1., 123, 0, 0, 500, 250, 1) + (0, 16., 1240., 'square', 12., '', 'e124', 124, 'um', 1., 0., 0., 1., 124, 0, 0, 500, 250, 1) + (0, 48., 1240., 'square', 12., '', 'e125', 125, 'um', 1., 0., 0., 1., 125, 0, 0, 500, 250, 1) + (0, 0., 1260., 'square', 12., '', 'e126', 126, 'um', 1., 0., 0., 1., 126, 0, 0, 500, 250, 1) + (0, 32., 1260., 'square', 12., '', 'e127', 127, 'um', 1., 0., 0., 1., 127, 0, 0, 500, 250, 1) + (0, 16., 1280., 'square', 12., '', 'e128', 128, 'um', 1., 0., 0., 1., 128, 0, 0, 500, 250, 1) + (0, 48., 1280., 'square', 12., '', 'e129', 129, 'um', 1., 0., 0., 1., 129, 0, 0, 500, 250, 1) + (0, 0., 1300., 'square', 12., '', 'e130', 130, 'um', 1., 0., 0., 1., 130, 0, 0, 500, 250, 1) + (0, 32., 1300., 'square', 12., '', 'e131', 131, 'um', 1., 0., 0., 1., 131, 0, 0, 500, 250, 1) + (0, 16., 1320., 'square', 12., '', 'e132', 132, 'um', 1., 0., 0., 1., 132, 0, 0, 500, 250, 1) + (0, 48., 1320., 'square', 12., '', 'e133', 133, 'um', 1., 0., 0., 1., 133, 0, 0, 500, 250, 1) + (0, 0., 1340., 'square', 12., '', 'e134', 134, 'um', 1., 0., 0., 1., 134, 0, 0, 500, 250, 1) + (0, 32., 1340., 'square', 12., '', 'e135', 135, 'um', 1., 0., 0., 1., 135, 0, 0, 500, 250, 1) + (0, 16., 1360., 'square', 12., '', 'e136', 136, 'um', 1., 0., 0., 1., 136, 0, 0, 500, 250, 1) + (0, 48., 1360., 'square', 12., '', 'e137', 137, 'um', 1., 0., 0., 1., 137, 0, 0, 500, 250, 1) + (0, 0., 1380., 'square', 12., '', 'e138', 138, 'um', 1., 0., 0., 1., 138, 0, 0, 500, 250, 1) + (0, 32., 1380., 'square', 12., '', 'e139', 139, 'um', 1., 0., 0., 1., 139, 0, 0, 500, 250, 1) + (0, 16., 1400., 'square', 12., '', 'e140', 140, 'um', 1., 0., 0., 1., 140, 0, 0, 500, 250, 1) + (0, 48., 1400., 'square', 12., '', 'e141', 141, 'um', 1., 0., 0., 1., 141, 0, 0, 500, 250, 1) + (0, 0., 1420., 'square', 12., '', 'e142', 142, 'um', 1., 0., 0., 1., 142, 0, 0, 500, 250, 1) + (0, 32., 1420., 'square', 12., '', 'e143', 143, 'um', 1., 0., 0., 1., 143, 0, 0, 500, 250, 1) + (0, 16., 1440., 'square', 12., '', 'e144', 144, 'um', 1., 0., 0., 1., 144, 0, 0, 500, 250, 1) + (0, 48., 1440., 'square', 12., '', 'e145', 145, 'um', 1., 0., 0., 1., 145, 0, 0, 500, 250, 1) + (0, 0., 1460., 'square', 12., '', 'e146', 146, 'um', 1., 0., 0., 1., 146, 0, 0, 500, 250, 1) + (0, 32., 1460., 'square', 12., '', 'e147', 147, 'um', 1., 0., 0., 1., 147, 0, 0, 500, 250, 1) + (0, 16., 1480., 'square', 12., '', 'e148', 148, 'um', 1., 0., 0., 1., 148, 0, 0, 500, 250, 1) + (0, 48., 1480., 'square', 12., '', 'e149', 149, 'um', 1., 0., 0., 1., 149, 0, 0, 500, 250, 1) + (0, 0., 1500., 'square', 12., '', 'e150', 150, 'um', 1., 0., 0., 1., 150, 0, 0, 500, 250, 1) + (0, 32., 1500., 'square', 12., '', 'e151', 151, 'um', 1., 0., 0., 1., 151, 0, 0, 500, 250, 1) + (0, 16., 1520., 'square', 12., '', 'e152', 152, 'um', 1., 0., 0., 1., 152, 0, 0, 500, 250, 1) + (0, 48., 1520., 'square', 12., '', 'e153', 153, 'um', 1., 0., 0., 1., 153, 0, 0, 500, 250, 1) + (0, 0., 1540., 'square', 12., '', 'e154', 154, 'um', 1., 0., 0., 1., 154, 0, 0, 500, 250, 1) + (0, 32., 1540., 'square', 12., '', 'e155', 155, 'um', 1., 0., 0., 1., 155, 0, 0, 500, 250, 1) + (0, 16., 1560., 'square', 12., '', 'e156', 156, 'um', 1., 0., 0., 1., 156, 0, 0, 500, 250, 1) + (0, 48., 1560., 'square', 12., '', 'e157', 157, 'um', 1., 0., 0., 1., 157, 0, 0, 500, 250, 1) + (0, 0., 1580., 'square', 12., '', 'e158', 158, 'um', 1., 0., 0., 1., 158, 0, 0, 500, 250, 1) + (0, 32., 1580., 'square', 12., '', 'e159', 159, 'um', 1., 0., 0., 1., 159, 0, 0, 500, 250, 1) + (0, 16., 1600., 'square', 12., '', 'e160', 160, 'um', 1., 0., 0., 1., 160, 0, 0, 500, 250, 1) + (0, 48., 1600., 'square', 12., '', 'e161', 161, 'um', 1., 0., 0., 1., 161, 0, 0, 500, 250, 1) + (0, 0., 1620., 'square', 12., '', 'e162', 162, 'um', 1., 0., 0., 1., 162, 0, 0, 500, 250, 1) + (0, 32., 1620., 'square', 12., '', 'e163', 163, 'um', 1., 0., 0., 1., 163, 0, 0, 500, 250, 1) + (0, 16., 1640., 'square', 12., '', 'e164', 164, 'um', 1., 0., 0., 1., 164, 0, 0, 500, 250, 1) + (0, 48., 1640., 'square', 12., '', 'e165', 165, 'um', 1., 0., 0., 1., 165, 0, 0, 500, 250, 1) + (0, 0., 1660., 'square', 12., '', 'e166', 166, 'um', 1., 0., 0., 1., 166, 0, 0, 500, 250, 1) + (0, 32., 1660., 'square', 12., '', 'e167', 167, 'um', 1., 0., 0., 1., 167, 0, 0, 500, 250, 1) + (0, 16., 1680., 'square', 12., '', 'e168', 168, 'um', 1., 0., 0., 1., 168, 0, 0, 500, 250, 1) + (0, 48., 1680., 'square', 12., '', 'e169', 169, 'um', 1., 0., 0., 1., 169, 0, 0, 500, 250, 1) + (0, 0., 1700., 'square', 12., '', 'e170', 170, 'um', 1., 0., 0., 1., 170, 0, 0, 500, 250, 1) + (0, 32., 1700., 'square', 12., '', 'e171', 171, 'um', 1., 0., 0., 1., 171, 0, 0, 500, 250, 1) + (0, 16., 1720., 'square', 12., '', 'e172', 172, 'um', 1., 0., 0., 1., 172, 0, 0, 500, 250, 1) + (0, 48., 1720., 'square', 12., '', 'e173', 173, 'um', 1., 0., 0., 1., 173, 0, 0, 500, 250, 1) + (0, 0., 1740., 'square', 12., '', 'e174', 174, 'um', 1., 0., 0., 1., 174, 0, 0, 500, 250, 1) + (0, 32., 1740., 'square', 12., '', 'e175', 175, 'um', 1., 0., 0., 1., 175, 0, 0, 500, 250, 1) + (0, 16., 1760., 'square', 12., '', 'e176', 176, 'um', 1., 0., 0., 1., 176, 0, 0, 500, 250, 1) + (0, 48., 1760., 'square', 12., '', 'e177', 177, 'um', 1., 0., 0., 1., 177, 0, 0, 500, 250, 1) + (0, 0., 1780., 'square', 12., '', 'e178', 178, 'um', 1., 0., 0., 1., 178, 0, 0, 500, 250, 1) + (0, 32., 1780., 'square', 12., '', 'e179', 179, 'um', 1., 0., 0., 1., 179, 0, 0, 500, 250, 1) + (0, 16., 1800., 'square', 12., '', 'e180', 180, 'um', 1., 0., 0., 1., 180, 0, 0, 500, 250, 1) + (0, 48., 1800., 'square', 12., '', 'e181', 181, 'um', 1., 0., 0., 1., 181, 0, 0, 500, 250, 1) + (0, 0., 1820., 'square', 12., '', 'e182', 182, 'um', 1., 0., 0., 1., 182, 0, 0, 500, 250, 1) + (0, 32., 1820., 'square', 12., '', 'e183', 183, 'um', 1., 0., 0., 1., 183, 0, 0, 500, 250, 1) + (0, 16., 1840., 'square', 12., '', 'e184', 184, 'um', 1., 0., 0., 1., 184, 0, 0, 500, 250, 1) + (0, 48., 1840., 'square', 12., '', 'e185', 185, 'um', 1., 0., 0., 1., 185, 0, 0, 500, 250, 1) + (0, 0., 1860., 'square', 12., '', 'e186', 186, 'um', 1., 0., 0., 1., 186, 0, 0, 500, 250, 1) + (0, 32., 1860., 'square', 12., '', 'e187', 187, 'um', 1., 0., 0., 1., 187, 0, 0, 500, 250, 1) + (0, 16., 1880., 'square', 12., '', 'e188', 188, 'um', 1., 0., 0., 1., 188, 0, 0, 500, 250, 1) + (0, 48., 1880., 'square', 12., '', 'e189', 189, 'um', 1., 0., 0., 1., 189, 0, 0, 500, 250, 1) + (0, 0., 1900., 'square', 12., '', 'e190', 190, 'um', 1., 0., 0., 1., 190, 0, 0, 500, 250, 1) + (0, 32., 1900., 'square', 12., '', 'e191', 191, 'um', 1., 0., 0., 1., 191, 0, 0, 500, 250, 1) + (0, 16., 1920., 'square', 12., '', 'e192', 192, 'um', 1., 0., 0., 1., 192, 0, 0, 500, 250, 1) + (0, 48., 1920., 'square', 12., '', 'e193', 193, 'um', 1., 0., 0., 1., 193, 0, 0, 500, 250, 1) + (0, 0., 1940., 'square', 12., '', 'e194', 194, 'um', 1., 0., 0., 1., 194, 0, 0, 500, 250, 1) + (0, 32., 1940., 'square', 12., '', 'e195', 195, 'um', 1., 0., 0., 1., 195, 0, 0, 500, 250, 1) + (0, 16., 1960., 'square', 12., '', 'e196', 196, 'um', 1., 0., 0., 1., 196, 0, 0, 500, 250, 1) + (0, 48., 1960., 'square', 12., '', 'e197', 197, 'um', 1., 0., 0., 1., 197, 0, 0, 500, 250, 1) + (0, 0., 1980., 'square', 12., '', 'e198', 198, 'um', 1., 0., 0., 1., 198, 0, 0, 500, 250, 1) + (0, 32., 1980., 'square', 12., '', 'e199', 199, 'um', 1., 0., 0., 1., 199, 0, 0, 500, 250, 1) + (0, 16., 2000., 'square', 12., '', 'e200', 200, 'um', 1., 0., 0., 1., 200, 0, 0, 500, 250, 1) + (0, 48., 2000., 'square', 12., '', 'e201', 201, 'um', 1., 0., 0., 1., 201, 0, 0, 500, 250, 1) + (0, 0., 2020., 'square', 12., '', 'e202', 202, 'um', 1., 0., 0., 1., 202, 0, 0, 500, 250, 1) + (0, 32., 2020., 'square', 12., '', 'e203', 203, 'um', 1., 0., 0., 1., 203, 0, 0, 500, 250, 1) + (0, 16., 2040., 'square', 12., '', 'e204', 204, 'um', 1., 0., 0., 1., 204, 0, 0, 500, 250, 1) + (0, 48., 2040., 'square', 12., '', 'e205', 205, 'um', 1., 0., 0., 1., 205, 0, 0, 500, 250, 1) + (0, 0., 2060., 'square', 12., '', 'e206', 206, 'um', 1., 0., 0., 1., 206, 0, 0, 500, 250, 1) + (0, 32., 2060., 'square', 12., '', 'e207', 207, 'um', 1., 0., 0., 1., 207, 0, 0, 500, 250, 1) + (0, 16., 2080., 'square', 12., '', 'e208', 208, 'um', 1., 0., 0., 1., 208, 0, 0, 500, 250, 1) + (0, 48., 2080., 'square', 12., '', 'e209', 209, 'um', 1., 0., 0., 1., 209, 0, 0, 500, 250, 1) + (0, 0., 2100., 'square', 12., '', 'e210', 210, 'um', 1., 0., 0., 1., 210, 0, 0, 500, 250, 1) + (0, 32., 2100., 'square', 12., '', 'e211', 211, 'um', 1., 0., 0., 1., 211, 0, 0, 500, 250, 1) + (0, 16., 2120., 'square', 12., '', 'e212', 212, 'um', 1., 0., 0., 1., 212, 0, 0, 500, 250, 1) + (0, 48., 2120., 'square', 12., '', 'e213', 213, 'um', 1., 0., 0., 1., 213, 0, 0, 500, 250, 1) + (0, 0., 2140., 'square', 12., '', 'e214', 214, 'um', 1., 0., 0., 1., 214, 0, 0, 500, 250, 1) + (0, 32., 2140., 'square', 12., '', 'e215', 215, 'um', 1., 0., 0., 1., 215, 0, 0, 500, 250, 1) + (0, 16., 2160., 'square', 12., '', 'e216', 216, 'um', 1., 0., 0., 1., 216, 0, 0, 500, 250, 1) + (0, 48., 2160., 'square', 12., '', 'e217', 217, 'um', 1., 0., 0., 1., 217, 0, 0, 500, 250, 1) + (0, 0., 2180., 'square', 12., '', 'e218', 218, 'um', 1., 0., 0., 1., 218, 0, 0, 500, 250, 1) + (0, 32., 2180., 'square', 12., '', 'e219', 219, 'um', 1., 0., 0., 1., 219, 0, 0, 500, 250, 1) + (0, 16., 2200., 'square', 12., '', 'e220', 220, 'um', 1., 0., 0., 1., 220, 0, 0, 500, 250, 1) + (0, 48., 2200., 'square', 12., '', 'e221', 221, 'um', 1., 0., 0., 1., 221, 0, 0, 500, 250, 1) + (0, 0., 2220., 'square', 12., '', 'e222', 222, 'um', 1., 0., 0., 1., 222, 0, 0, 500, 250, 1) + (0, 32., 2220., 'square', 12., '', 'e223', 223, 'um', 1., 0., 0., 1., 223, 0, 0, 500, 250, 1) + (0, 16., 2240., 'square', 12., '', 'e224', 224, 'um', 1., 0., 0., 1., 224, 0, 0, 500, 250, 1) + (0, 48., 2240., 'square', 12., '', 'e225', 225, 'um', 1., 0., 0., 1., 225, 0, 0, 500, 250, 1) + (0, 0., 2260., 'square', 12., '', 'e226', 226, 'um', 1., 0., 0., 1., 226, 0, 0, 500, 250, 1) + (0, 32., 2260., 'square', 12., '', 'e227', 227, 'um', 1., 0., 0., 1., 227, 0, 0, 500, 250, 1) + (0, 16., 2280., 'square', 12., '', 'e228', 228, 'um', 1., 0., 0., 1., 228, 0, 0, 500, 250, 1) + (0, 48., 2280., 'square', 12., '', 'e229', 229, 'um', 1., 0., 0., 1., 229, 0, 0, 500, 250, 1) + (0, 0., 2300., 'square', 12., '', 'e230', 230, 'um', 1., 0., 0., 1., 230, 0, 0, 500, 250, 1) + (0, 32., 2300., 'square', 12., '', 'e231', 231, 'um', 1., 0., 0., 1., 231, 0, 0, 500, 250, 1) + (0, 16., 2320., 'square', 12., '', 'e232', 232, 'um', 1., 0., 0., 1., 232, 0, 0, 500, 250, 1) + (0, 48., 2320., 'square', 12., '', 'e233', 233, 'um', 1., 0., 0., 1., 233, 0, 0, 500, 250, 1) + (0, 0., 2340., 'square', 12., '', 'e234', 234, 'um', 1., 0., 0., 1., 234, 0, 0, 500, 250, 1) + (0, 32., 2340., 'square', 12., '', 'e235', 235, 'um', 1., 0., 0., 1., 235, 0, 0, 500, 250, 1) + (0, 16., 2360., 'square', 12., '', 'e236', 236, 'um', 1., 0., 0., 1., 236, 0, 0, 500, 250, 1) + (0, 48., 2360., 'square', 12., '', 'e237', 237, 'um', 1., 0., 0., 1., 237, 0, 0, 500, 250, 1) + (0, 0., 2380., 'square', 12., '', 'e238', 238, 'um', 1., 0., 0., 1., 238, 0, 0, 500, 250, 1) + (0, 32., 2380., 'square', 12., '', 'e239', 239, 'um', 1., 0., 0., 1., 239, 0, 0, 500, 250, 1) + (0, 16., 2400., 'square', 12., '', 'e240', 240, 'um', 1., 0., 0., 1., 240, 0, 0, 500, 250, 1) + (0, 48., 2400., 'square', 12., '', 'e241', 241, 'um', 1., 0., 0., 1., 241, 0, 0, 500, 250, 1) + (0, 0., 2420., 'square', 12., '', 'e242', 242, 'um', 1., 0., 0., 1., 242, 0, 0, 500, 250, 1) + (0, 32., 2420., 'square', 12., '', 'e243', 243, 'um', 1., 0., 0., 1., 243, 0, 0, 500, 250, 1) + (0, 16., 2440., 'square', 12., '', 'e244', 244, 'um', 1., 0., 0., 1., 244, 0, 0, 500, 250, 1) + (0, 48., 2440., 'square', 12., '', 'e245', 245, 'um', 1., 0., 0., 1., 245, 0, 0, 500, 250, 1) + (0, 0., 2460., 'square', 12., '', 'e246', 246, 'um', 1., 0., 0., 1., 246, 0, 0, 500, 250, 1) + (0, 32., 2460., 'square', 12., '', 'e247', 247, 'um', 1., 0., 0., 1., 247, 0, 0, 500, 250, 1) + (0, 16., 2480., 'square', 12., '', 'e248', 248, 'um', 1., 0., 0., 1., 248, 0, 0, 500, 250, 1) + (0, 48., 2480., 'square', 12., '', 'e249', 249, 'um', 1., 0., 0., 1., 249, 0, 0, 500, 250, 1) + (0, 0., 2500., 'square', 12., '', 'e250', 250, 'um', 1., 0., 0., 1., 250, 0, 0, 500, 250, 1) + (0, 32., 2500., 'square', 12., '', 'e251', 251, 'um', 1., 0., 0., 1., 251, 0, 0, 500, 250, 1) + (0, 16., 2520., 'square', 12., '', 'e252', 252, 'um', 1., 0., 0., 1., 252, 0, 0, 500, 250, 1) + (0, 48., 2520., 'square', 12., '', 'e253', 253, 'um', 1., 0., 0., 1., 253, 0, 0, 500, 250, 1) + (0, 0., 2540., 'square', 12., '', 'e254', 254, 'um', 1., 0., 0., 1., 254, 0, 0, 500, 250, 1) + (0, 32., 2540., 'square', 12., '', 'e255', 255, 'um', 1., 0., 0., 1., 255, 0, 0, 500, 250, 1) + (0, 16., 2560., 'square', 12., '', 'e256', 256, 'um', 1., 0., 0., 1., 256, 0, 0, 500, 250, 1) + (0, 48., 2560., 'square', 12., '', 'e257', 257, 'um', 1., 0., 0., 1., 257, 0, 0, 500, 250, 1) + (0, 0., 2580., 'square', 12., '', 'e258', 258, 'um', 1., 0., 0., 1., 258, 0, 0, 500, 250, 1) + (0, 32., 2580., 'square', 12., '', 'e259', 259, 'um', 1., 0., 0., 1., 259, 0, 0, 500, 250, 1) + (0, 16., 2600., 'square', 12., '', 'e260', 260, 'um', 1., 0., 0., 1., 260, 0, 0, 500, 250, 1) + (0, 48., 2600., 'square', 12., '', 'e261', 261, 'um', 1., 0., 0., 1., 261, 0, 0, 500, 250, 1) + (0, 0., 2620., 'square', 12., '', 'e262', 262, 'um', 1., 0., 0., 1., 262, 0, 0, 500, 250, 1) + (0, 32., 2620., 'square', 12., '', 'e263', 263, 'um', 1., 0., 0., 1., 263, 0, 0, 500, 250, 1) + (0, 16., 2640., 'square', 12., '', 'e264', 264, 'um', 1., 0., 0., 1., 264, 0, 0, 500, 250, 1) + (0, 48., 2640., 'square', 12., '', 'e265', 265, 'um', 1., 0., 0., 1., 265, 0, 0, 500, 250, 1) + (0, 0., 2660., 'square', 12., '', 'e266', 266, 'um', 1., 0., 0., 1., 266, 0, 0, 500, 250, 1) + (0, 32., 2660., 'square', 12., '', 'e267', 267, 'um', 1., 0., 0., 1., 267, 0, 0, 500, 250, 1) + (0, 16., 2680., 'square', 12., '', 'e268', 268, 'um', 1., 0., 0., 1., 268, 0, 0, 500, 250, 1) + (0, 48., 2680., 'square', 12., '', 'e269', 269, 'um', 1., 0., 0., 1., 269, 0, 0, 500, 250, 1) + (0, 0., 2700., 'square', 12., '', 'e270', 270, 'um', 1., 0., 0., 1., 270, 0, 0, 500, 250, 1) + (0, 32., 2700., 'square', 12., '', 'e271', 271, 'um', 1., 0., 0., 1., 271, 0, 0, 500, 250, 1) + (0, 16., 2720., 'square', 12., '', 'e272', 272, 'um', 1., 0., 0., 1., 272, 0, 0, 500, 250, 1) + (0, 48., 2720., 'square', 12., '', 'e273', 273, 'um', 1., 0., 0., 1., 273, 0, 0, 500, 250, 1) + (0, 0., 2740., 'square', 12., '', 'e274', 274, 'um', 1., 0., 0., 1., 274, 0, 0, 500, 250, 1) + (0, 32., 2740., 'square', 12., '', 'e275', 275, 'um', 1., 0., 0., 1., 275, 0, 0, 500, 250, 1) + (0, 16., 2760., 'square', 12., '', 'e276', 276, 'um', 1., 0., 0., 1., 276, 0, 0, 500, 250, 1) + (0, 48., 2760., 'square', 12., '', 'e277', 277, 'um', 1., 0., 0., 1., 277, 0, 0, 500, 250, 1) + (0, 0., 2780., 'square', 12., '', 'e278', 278, 'um', 1., 0., 0., 1., 278, 0, 0, 500, 250, 1) + (0, 32., 2780., 'square', 12., '', 'e279', 279, 'um', 1., 0., 0., 1., 279, 0, 0, 500, 250, 1) + (0, 16., 2800., 'square', 12., '', 'e280', 280, 'um', 1., 0., 0., 1., 280, 0, 0, 500, 250, 1) + (0, 48., 2800., 'square', 12., '', 'e281', 281, 'um', 1., 0., 0., 1., 281, 0, 0, 500, 250, 1) + (0, 0., 2820., 'square', 12., '', 'e282', 282, 'um', 1., 0., 0., 1., 282, 0, 0, 500, 250, 1) + (0, 32., 2820., 'square', 12., '', 'e283', 283, 'um', 1., 0., 0., 1., 283, 0, 0, 500, 250, 1) + (0, 16., 2840., 'square', 12., '', 'e284', 284, 'um', 1., 0., 0., 1., 284, 0, 0, 500, 250, 1) + (0, 48., 2840., 'square', 12., '', 'e285', 285, 'um', 1., 0., 0., 1., 285, 0, 0, 500, 250, 1) + (0, 0., 2860., 'square', 12., '', 'e286', 286, 'um', 1., 0., 0., 1., 286, 0, 0, 500, 250, 1) + (0, 32., 2860., 'square', 12., '', 'e287', 287, 'um', 1., 0., 0., 1., 287, 0, 0, 500, 250, 1) + (0, 16., 2880., 'square', 12., '', 'e288', 288, 'um', 1., 0., 0., 1., 288, 0, 0, 500, 250, 1) + (0, 48., 2880., 'square', 12., '', 'e289', 289, 'um', 1., 0., 0., 1., 289, 0, 0, 500, 250, 1) + (0, 0., 2900., 'square', 12., '', 'e290', 290, 'um', 1., 0., 0., 1., 290, 0, 0, 500, 250, 1) + (0, 32., 2900., 'square', 12., '', 'e291', 291, 'um', 1., 0., 0., 1., 291, 0, 0, 500, 250, 1) + (0, 16., 2920., 'square', 12., '', 'e292', 292, 'um', 1., 0., 0., 1., 292, 0, 0, 500, 250, 1) + (0, 48., 2920., 'square', 12., '', 'e293', 293, 'um', 1., 0., 0., 1., 293, 0, 0, 500, 250, 1) + (0, 0., 2940., 'square', 12., '', 'e294', 294, 'um', 1., 0., 0., 1., 294, 0, 0, 500, 250, 1) + (0, 32., 2940., 'square', 12., '', 'e295', 295, 'um', 1., 0., 0., 1., 295, 0, 0, 500, 250, 1) + (0, 16., 2960., 'square', 12., '', 'e296', 296, 'um', 1., 0., 0., 1., 296, 0, 0, 500, 250, 1) + (0, 48., 2960., 'square', 12., '', 'e297', 297, 'um', 1., 0., 0., 1., 297, 0, 0, 500, 250, 1) + (0, 0., 2980., 'square', 12., '', 'e298', 298, 'um', 1., 0., 0., 1., 298, 0, 0, 500, 250, 1) + (0, 32., 2980., 'square', 12., '', 'e299', 299, 'um', 1., 0., 0., 1., 299, 0, 0, 500, 250, 1) + (0, 16., 3000., 'square', 12., '', 'e300', 300, 'um', 1., 0., 0., 1., 300, 0, 0, 500, 250, 1) + (0, 48., 3000., 'square', 12., '', 'e301', 301, 'um', 1., 0., 0., 1., 301, 0, 0, 500, 250, 1) + (0, 0., 3020., 'square', 12., '', 'e302', 302, 'um', 1., 0., 0., 1., 302, 0, 0, 500, 250, 1) + (0, 32., 3020., 'square', 12., '', 'e303', 303, 'um', 1., 0., 0., 1., 303, 0, 0, 500, 250, 1) + (0, 16., 3040., 'square', 12., '', 'e304', 304, 'um', 1., 0., 0., 1., 304, 0, 0, 500, 250, 1) + (0, 48., 3040., 'square', 12., '', 'e305', 305, 'um', 1., 0., 0., 1., 305, 0, 0, 500, 250, 1) + (0, 0., 3060., 'square', 12., '', 'e306', 306, 'um', 1., 0., 0., 1., 306, 0, 0, 500, 250, 1) + (0, 32., 3060., 'square', 12., '', 'e307', 307, 'um', 1., 0., 0., 1., 307, 0, 0, 500, 250, 1) + (0, 16., 3080., 'square', 12., '', 'e308', 308, 'um', 1., 0., 0., 1., 308, 0, 0, 500, 250, 1) + (0, 48., 3080., 'square', 12., '', 'e309', 309, 'um', 1., 0., 0., 1., 309, 0, 0, 500, 250, 1) + (0, 0., 3100., 'square', 12., '', 'e310', 310, 'um', 1., 0., 0., 1., 310, 0, 0, 500, 250, 1) + (0, 32., 3100., 'square', 12., '', 'e311', 311, 'um', 1., 0., 0., 1., 311, 0, 0, 500, 250, 1) + (0, 16., 3120., 'square', 12., '', 'e312', 312, 'um', 1., 0., 0., 1., 312, 0, 0, 500, 250, 1) + (0, 48., 3120., 'square', 12., '', 'e313', 313, 'um', 1., 0., 0., 1., 313, 0, 0, 500, 250, 1) + (0, 0., 3140., 'square', 12., '', 'e314', 314, 'um', 1., 0., 0., 1., 314, 0, 0, 500, 250, 1) + (0, 32., 3140., 'square', 12., '', 'e315', 315, 'um', 1., 0., 0., 1., 315, 0, 0, 500, 250, 1) + (0, 16., 3160., 'square', 12., '', 'e316', 316, 'um', 1., 0., 0., 1., 316, 0, 0, 500, 250, 1) + (0, 48., 3160., 'square', 12., '', 'e317', 317, 'um', 1., 0., 0., 1., 317, 0, 0, 500, 250, 1) + (0, 0., 3180., 'square', 12., '', 'e318', 318, 'um', 1., 0., 0., 1., 318, 0, 0, 500, 250, 1) + (0, 32., 3180., 'square', 12., '', 'e319', 319, 'um', 1., 0., 0., 1., 319, 0, 0, 500, 250, 1) + (0, 16., 3200., 'square', 12., '', 'e320', 320, 'um', 1., 0., 0., 1., 320, 0, 0, 500, 250, 1) + (0, 48., 3200., 'square', 12., '', 'e321', 321, 'um', 1., 0., 0., 1., 321, 0, 0, 500, 250, 1) + (0, 0., 3220., 'square', 12., '', 'e322', 322, 'um', 1., 0., 0., 1., 322, 0, 0, 500, 250, 1) + (0, 32., 3220., 'square', 12., '', 'e323', 323, 'um', 1., 0., 0., 1., 323, 0, 0, 500, 250, 1) + (0, 16., 3240., 'square', 12., '', 'e324', 324, 'um', 1., 0., 0., 1., 324, 0, 0, 500, 250, 1) + (0, 48., 3240., 'square', 12., '', 'e325', 325, 'um', 1., 0., 0., 1., 325, 0, 0, 500, 250, 1) + (0, 0., 3260., 'square', 12., '', 'e326', 326, 'um', 1., 0., 0., 1., 326, 0, 0, 500, 250, 1) + (0, 32., 3260., 'square', 12., '', 'e327', 327, 'um', 1., 0., 0., 1., 327, 0, 0, 500, 250, 1) + (0, 16., 3280., 'square', 12., '', 'e328', 328, 'um', 1., 0., 0., 1., 328, 0, 0, 500, 250, 1) + (0, 48., 3280., 'square', 12., '', 'e329', 329, 'um', 1., 0., 0., 1., 329, 0, 0, 500, 250, 1) + (0, 0., 3300., 'square', 12., '', 'e330', 330, 'um', 1., 0., 0., 1., 330, 0, 0, 500, 250, 1) + (0, 32., 3300., 'square', 12., '', 'e331', 331, 'um', 1., 0., 0., 1., 331, 0, 0, 500, 250, 1) + (0, 16., 3320., 'square', 12., '', 'e332', 332, 'um', 1., 0., 0., 1., 332, 0, 0, 500, 250, 1) + (0, 48., 3320., 'square', 12., '', 'e333', 333, 'um', 1., 0., 0., 1., 333, 0, 0, 500, 250, 1) + (0, 0., 3340., 'square', 12., '', 'e334', 334, 'um', 1., 0., 0., 1., 334, 0, 0, 500, 250, 1) + (0, 32., 3340., 'square', 12., '', 'e335', 335, 'um', 1., 0., 0., 1., 335, 0, 0, 500, 250, 1) + (0, 16., 3360., 'square', 12., '', 'e336', 336, 'um', 1., 0., 0., 1., 336, 0, 0, 500, 250, 1) + (0, 48., 3360., 'square', 12., '', 'e337', 337, 'um', 1., 0., 0., 1., 337, 0, 0, 500, 250, 1) + (0, 0., 3380., 'square', 12., '', 'e338', 338, 'um', 1., 0., 0., 1., 338, 0, 0, 500, 250, 1) + (0, 32., 3380., 'square', 12., '', 'e339', 339, 'um', 1., 0., 0., 1., 339, 0, 0, 500, 250, 1) + (0, 16., 3400., 'square', 12., '', 'e340', 340, 'um', 1., 0., 0., 1., 340, 0, 0, 500, 250, 1) + (0, 48., 3400., 'square', 12., '', 'e341', 341, 'um', 1., 0., 0., 1., 341, 0, 0, 500, 250, 1) + (0, 0., 3420., 'square', 12., '', 'e342', 342, 'um', 1., 0., 0., 1., 342, 0, 0, 500, 250, 1) + (0, 32., 3420., 'square', 12., '', 'e343', 343, 'um', 1., 0., 0., 1., 343, 0, 0, 500, 250, 1) + (0, 16., 3440., 'square', 12., '', 'e344', 344, 'um', 1., 0., 0., 1., 344, 0, 0, 500, 250, 1) + (0, 48., 3440., 'square', 12., '', 'e345', 345, 'um', 1., 0., 0., 1., 345, 0, 0, 500, 250, 1) + (0, 0., 3460., 'square', 12., '', 'e346', 346, 'um', 1., 0., 0., 1., 346, 0, 0, 500, 250, 1) + (0, 32., 3460., 'square', 12., '', 'e347', 347, 'um', 1., 0., 0., 1., 347, 0, 0, 500, 250, 1) + (0, 16., 3480., 'square', 12., '', 'e348', 348, 'um', 1., 0., 0., 1., 348, 0, 0, 500, 250, 1) + (0, 48., 3480., 'square', 12., '', 'e349', 349, 'um', 1., 0., 0., 1., 349, 0, 0, 500, 250, 1) + (0, 0., 3500., 'square', 12., '', 'e350', 350, 'um', 1., 0., 0., 1., 350, 0, 0, 500, 250, 1) + (0, 32., 3500., 'square', 12., '', 'e351', 351, 'um', 1., 0., 0., 1., 351, 0, 0, 500, 250, 1) + (0, 16., 3520., 'square', 12., '', 'e352', 352, 'um', 1., 0., 0., 1., 352, 0, 0, 500, 250, 1) + (0, 48., 3520., 'square', 12., '', 'e353', 353, 'um', 1., 0., 0., 1., 353, 0, 0, 500, 250, 1) + (0, 0., 3540., 'square', 12., '', 'e354', 354, 'um', 1., 0., 0., 1., 354, 0, 0, 500, 250, 1) + (0, 32., 3540., 'square', 12., '', 'e355', 355, 'um', 1., 0., 0., 1., 355, 0, 0, 500, 250, 1) + (0, 16., 3560., 'square', 12., '', 'e356', 356, 'um', 1., 0., 0., 1., 356, 0, 0, 500, 250, 1) + (0, 48., 3560., 'square', 12., '', 'e357', 357, 'um', 1., 0., 0., 1., 357, 0, 0, 500, 250, 1) + (0, 0., 3580., 'square', 12., '', 'e358', 358, 'um', 1., 0., 0., 1., 358, 0, 0, 500, 250, 1) + (0, 32., 3580., 'square', 12., '', 'e359', 359, 'um', 1., 0., 0., 1., 359, 0, 0, 500, 250, 1) + (0, 16., 3600., 'square', 12., '', 'e360', 360, 'um', 1., 0., 0., 1., 360, 0, 0, 500, 250, 1) + (0, 48., 3600., 'square', 12., '', 'e361', 361, 'um', 1., 0., 0., 1., 361, 0, 0, 500, 250, 1) + (0, 0., 3620., 'square', 12., '', 'e362', 362, 'um', 1., 0., 0., 1., 362, 0, 0, 500, 250, 1) + (0, 32., 3620., 'square', 12., '', 'e363', 363, 'um', 1., 0., 0., 1., 363, 0, 0, 500, 250, 1) + (0, 16., 3640., 'square', 12., '', 'e364', 364, 'um', 1., 0., 0., 1., 364, 0, 0, 500, 250, 1) + (0, 48., 3640., 'square', 12., '', 'e365', 365, 'um', 1., 0., 0., 1., 365, 0, 0, 500, 250, 1) + (0, 0., 3660., 'square', 12., '', 'e366', 366, 'um', 1., 0., 0., 1., 366, 0, 0, 500, 250, 1) + (0, 32., 3660., 'square', 12., '', 'e367', 367, 'um', 1., 0., 0., 1., 367, 0, 0, 500, 250, 1) + (0, 16., 3680., 'square', 12., '', 'e368', 368, 'um', 1., 0., 0., 1., 368, 0, 0, 500, 250, 1) + (0, 48., 3680., 'square', 12., '', 'e369', 369, 'um', 1., 0., 0., 1., 369, 0, 0, 500, 250, 1) + (0, 0., 3700., 'square', 12., '', 'e370', 370, 'um', 1., 0., 0., 1., 370, 0, 0, 500, 250, 1) + (0, 32., 3700., 'square', 12., '', 'e371', 371, 'um', 1., 0., 0., 1., 371, 0, 0, 500, 250, 1) + (0, 16., 3720., 'square', 12., '', 'e372', 372, 'um', 1., 0., 0., 1., 372, 0, 0, 500, 250, 1) + (0, 48., 3720., 'square', 12., '', 'e373', 373, 'um', 1., 0., 0., 1., 373, 0, 0, 500, 250, 1) + (0, 0., 3740., 'square', 12., '', 'e374', 374, 'um', 1., 0., 0., 1., 374, 0, 0, 500, 250, 1) + (0, 32., 3740., 'square', 12., '', 'e375', 375, 'um', 1., 0., 0., 1., 375, 0, 0, 500, 250, 1) + (0, 16., 3760., 'square', 12., '', 'e376', 376, 'um', 1., 0., 0., 1., 376, 0, 0, 500, 250, 1) + (0, 48., 3760., 'square', 12., '', 'e377', 377, 'um', 1., 0., 0., 1., 377, 0, 0, 500, 250, 1) + (0, 0., 3780., 'square', 12., '', 'e378', 378, 'um', 1., 0., 0., 1., 378, 0, 0, 500, 250, 1) + (0, 32., 3780., 'square', 12., '', 'e379', 379, 'um', 1., 0., 0., 1., 379, 0, 0, 500, 250, 1) + (0, 16., 3800., 'square', 12., '', 'e380', 380, 'um', 1., 0., 0., 1., 380, 0, 0, 500, 250, 1) + (0, 48., 3800., 'square', 12., '', 'e381', 381, 'um', 1., 0., 0., 1., 381, 0, 0, 500, 250, 1) + (0, 0., 3820., 'square', 12., '', 'e382', 382, 'um', 1., 0., 0., 1., 382, 0, 0, 500, 250, 1) + (0, 32., 3820., 'square', 12., '', 'e383', 383, 'um', 1., 0., 0., 1., 383, 0, 0, 500, 250, 1)]
    location [[ 16. 0.] + [ 48. 0.] + [ 0. 20.] + [ 32. 20.] + [ 16. 40.] + [ 48. 40.] + [ 0. 60.] + [ 32. 60.] + [ 16. 80.] + [ 48. 80.] + [ 0. 100.] + [ 32. 100.] + [ 16. 120.] + [ 48. 120.] + [ 0. 140.] + [ 32. 140.] + [ 16. 160.] + [ 48. 160.] + [ 0. 180.] + [ 32. 180.] + [ 16. 200.] + [ 48. 200.] + [ 0. 220.] + [ 32. 220.] + [ 16. 240.] + [ 48. 240.] + [ 0. 260.] + [ 32. 260.] + [ 16. 280.] + [ 48. 280.] + [ 0. 300.] + [ 32. 300.] + [ 16. 320.] + [ 48. 320.] + [ 0. 340.] + [ 32. 340.] + [ 16. 360.] + [ 48. 360.] + [ 0. 380.] + [ 32. 380.] + [ 16. 400.] + [ 48. 400.] + [ 0. 420.] + [ 32. 420.] + [ 16. 440.] + [ 48. 440.] + [ 0. 460.] + [ 32. 460.] + [ 16. 480.] + [ 48. 480.] + [ 0. 500.] + [ 32. 500.] + [ 16. 520.] + [ 48. 520.] + [ 0. 540.] + [ 32. 540.] + [ 16. 560.] + [ 48. 560.] + [ 0. 580.] + [ 32. 580.] + [ 16. 600.] + [ 48. 600.] + [ 0. 620.] + [ 32. 620.] + [ 16. 640.] + [ 48. 640.] + [ 0. 660.] + [ 32. 660.] + [ 16. 680.] + [ 48. 680.] + [ 0. 700.] + [ 32. 700.] + [ 16. 720.] + [ 48. 720.] + [ 0. 740.] + [ 32. 740.] + [ 16. 760.] + [ 48. 760.] + [ 0. 780.] + [ 32. 780.] + [ 16. 800.] + [ 48. 800.] + [ 0. 820.] + [ 32. 820.] + [ 16. 840.] + [ 48. 840.] + [ 0. 860.] + [ 32. 860.] + [ 16. 880.] + [ 48. 880.] + [ 0. 900.] + [ 32. 900.] + [ 16. 920.] + [ 48. 920.] + [ 0. 940.] + [ 32. 940.] + [ 16. 960.] + [ 48. 960.] + [ 0. 980.] + [ 32. 980.] + [ 16. 1000.] + [ 48. 1000.] + [ 0. 1020.] + [ 32. 1020.] + [ 16. 1040.] + [ 48. 1040.] + [ 0. 1060.] + [ 32. 1060.] + [ 16. 1080.] + [ 48. 1080.] + [ 0. 1100.] + [ 32. 1100.] + [ 16. 1120.] + [ 48. 1120.] + [ 0. 1140.] + [ 32. 1140.] + [ 16. 1160.] + [ 48. 1160.] + [ 0. 1180.] + [ 32. 1180.] + [ 16. 1200.] + [ 48. 1200.] + [ 0. 1220.] + [ 32. 1220.] + [ 16. 1240.] + [ 48. 1240.] + [ 0. 1260.] + [ 32. 1260.] + [ 16. 1280.] + [ 48. 1280.] + [ 0. 1300.] + [ 32. 1300.] + [ 16. 1320.] + [ 48. 1320.] + [ 0. 1340.] + [ 32. 1340.] + [ 16. 1360.] + [ 48. 1360.] + [ 0. 1380.] + [ 32. 1380.] + [ 16. 1400.] + [ 48. 1400.] + [ 0. 1420.] + [ 32. 1420.] + [ 16. 1440.] + [ 48. 1440.] + [ 0. 1460.] + [ 32. 1460.] + [ 16. 1480.] + [ 48. 1480.] + [ 0. 1500.] + [ 32. 1500.] + [ 16. 1520.] + [ 48. 1520.] + [ 0. 1540.] + [ 32. 1540.] + [ 16. 1560.] + [ 48. 1560.] + [ 0. 1580.] + [ 32. 1580.] + [ 16. 1600.] + [ 48. 1600.] + [ 0. 1620.] + [ 32. 1620.] + [ 16. 1640.] + [ 48. 1640.] + [ 0. 1660.] + [ 32. 1660.] + [ 16. 1680.] + [ 48. 1680.] + [ 0. 1700.] + [ 32. 1700.] + [ 16. 1720.] + [ 48. 1720.] + [ 0. 1740.] + [ 32. 1740.] + [ 16. 1760.] + [ 48. 1760.] + [ 0. 1780.] + [ 32. 1780.] + [ 16. 1800.] + [ 48. 1800.] + [ 0. 1820.] + [ 32. 1820.] + [ 16. 1840.] + [ 48. 1840.] + [ 0. 1860.] + [ 32. 1860.] + [ 16. 1880.] + [ 48. 1880.] + [ 0. 1900.] + [ 32. 1900.] + [ 16. 1920.] + [ 48. 1920.] + [ 0. 1940.] + [ 32. 1940.] + [ 16. 1960.] + [ 48. 1960.] + [ 0. 1980.] + [ 32. 1980.] + [ 16. 2000.] + [ 48. 2000.] + [ 0. 2020.] + [ 32. 2020.] + [ 16. 2040.] + [ 48. 2040.] + [ 0. 2060.] + [ 32. 2060.] + [ 16. 2080.] + [ 48. 2080.] + [ 0. 2100.] + [ 32. 2100.] + [ 16. 2120.] + [ 48. 2120.] + [ 0. 2140.] + [ 32. 2140.] + [ 16. 2160.] + [ 48. 2160.] + [ 0. 2180.] + [ 32. 2180.] + [ 16. 2200.] + [ 48. 2200.] + [ 0. 2220.] + [ 32. 2220.] + [ 16. 2240.] + [ 48. 2240.] + [ 0. 2260.] + [ 32. 2260.] + [ 16. 2280.] + [ 48. 2280.] + [ 0. 2300.] + [ 32. 2300.] + [ 16. 2320.] + [ 48. 2320.] + [ 0. 2340.] + [ 32. 2340.] + [ 16. 2360.] + [ 48. 2360.] + [ 0. 2380.] + [ 32. 2380.] + [ 16. 2400.] + [ 48. 2400.] + [ 0. 2420.] + [ 32. 2420.] + [ 16. 2440.] + [ 48. 2440.] + [ 0. 2460.] + [ 32. 2460.] + [ 16. 2480.] + [ 48. 2480.] + [ 0. 2500.] + [ 32. 2500.] + [ 16. 2520.] + [ 48. 2520.] + [ 0. 2540.] + [ 32. 2540.] + [ 16. 2560.] + [ 48. 2560.] + [ 0. 2580.] + [ 32. 2580.] + [ 16. 2600.] + [ 48. 2600.] + [ 0. 2620.] + [ 32. 2620.] + [ 16. 2640.] + [ 48. 2640.] + [ 0. 2660.] + [ 32. 2660.] + [ 16. 2680.] + [ 48. 2680.] + [ 0. 2700.] + [ 32. 2700.] + [ 16. 2720.] + [ 48. 2720.] + [ 0. 2740.] + [ 32. 2740.] + [ 16. 2760.] + [ 48. 2760.] + [ 0. 2780.] + [ 32. 2780.] + [ 16. 2800.] + [ 48. 2800.] + [ 0. 2820.] + [ 32. 2820.] + [ 16. 2840.] + [ 48. 2840.] + [ 0. 2860.] + [ 32. 2860.] + [ 16. 2880.] + [ 48. 2880.] + [ 0. 2900.] + [ 32. 2900.] + [ 16. 2920.] + [ 48. 2920.] + [ 0. 2940.] + [ 32. 2940.] + [ 16. 2960.] + [ 48. 2960.] + [ 0. 2980.] + [ 32. 2980.] + [ 16. 3000.] + [ 48. 3000.] + [ 0. 3020.] + [ 32. 3020.] + [ 16. 3040.] + [ 48. 3040.] + [ 0. 3060.] + [ 32. 3060.] + [ 16. 3080.] + [ 48. 3080.] + [ 0. 3100.] + [ 32. 3100.] + [ 16. 3120.] + [ 48. 3120.] + [ 0. 3140.] + [ 32. 3140.] + [ 16. 3160.] + [ 48. 3160.] + [ 0. 3180.] + [ 32. 3180.] + [ 16. 3200.] + [ 48. 3200.] + [ 0. 3220.] + [ 32. 3220.] + [ 16. 3240.] + [ 48. 3240.] + [ 0. 3260.] + [ 32. 3260.] + [ 16. 3280.] + [ 48. 3280.] + [ 0. 3300.] + [ 32. 3300.] + [ 16. 3320.] + [ 48. 3320.] + [ 0. 3340.] + [ 32. 3340.] + [ 16. 3360.] + [ 48. 3360.] + [ 0. 3380.] + [ 32. 3380.] + [ 16. 3400.] + [ 48. 3400.] + [ 0. 3420.] + [ 32. 3420.] + [ 16. 3440.] + [ 48. 3440.] + [ 0. 3460.] + [ 32. 3460.] + [ 16. 3480.] + [ 48. 3480.] + [ 0. 3500.] + [ 32. 3500.] + [ 16. 3520.] + [ 48. 3520.] + [ 0. 3540.] + [ 32. 3540.] + [ 16. 3560.] + [ 48. 3560.] + [ 0. 3580.] + [ 32. 3580.] + [ 16. 3600.] + [ 48. 3600.] + [ 0. 3620.] + [ 32. 3620.] + [ 16. 3640.] + [ 48. 3640.] + [ 0. 3660.] + [ 32. 3660.] + [ 16. 3680.] + [ 48. 3680.] + [ 0. 3700.] + [ 32. 3700.] + [ 16. 3720.] + [ 48. 3720.] + [ 0. 3740.] + [ 32. 3740.] + [ 16. 3760.] + [ 48. 3760.] + [ 0. 3780.] + [ 32. 3780.] + [ 16. 3800.] + [ 48. 3800.] + [ 0. 3820.] + [ 32. 3820.]]
    group [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
    inter_sample_shift [0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385]
+ + + +Note that the ``generate_hybrid_recording`` is warning us that we might +want to account for drift! + +.. code:: ipython3 + + # by passing the `sorting_hybrid` object, we make sure that injected spikes are the same + # this will take a bit more time because it's interpolating the templates to account for drifts + recording_hybrid_with_drift, sorting_hybrid = sgen.generate_hybrid_recording( + recording=recording_preproc, + templates=templates_relocated, + motion=motion_info["motion"], + sorting=sorting_hybrid, + seed=2308, + ) + recording_hybrid_with_drift + + + + +.. raw:: html + +
InjectDriftingTemplatesRecording: 384 channels - 30.0kHz - 1 segments - 58,715,724 samples - 1,957.19s (32.62 minutes) - float64 dtype - 167.99 GiB
Channel IDs
    ['imec0.ap#AP0' 'imec0.ap#AP1' 'imec0.ap#AP2' 'imec0.ap#AP3' + 'imec0.ap#AP4' 'imec0.ap#AP5' 'imec0.ap#AP6' 'imec0.ap#AP7' + 'imec0.ap#AP8' 'imec0.ap#AP9' 'imec0.ap#AP10' 'imec0.ap#AP11' + 'imec0.ap#AP12' 'imec0.ap#AP13' 'imec0.ap#AP14' 'imec0.ap#AP15' + 'imec0.ap#AP16' 'imec0.ap#AP17' 'imec0.ap#AP18' 'imec0.ap#AP19' + 'imec0.ap#AP20' 'imec0.ap#AP21' 'imec0.ap#AP22' 'imec0.ap#AP23' + 'imec0.ap#AP24' 'imec0.ap#AP25' 'imec0.ap#AP26' 'imec0.ap#AP27' + 'imec0.ap#AP28' 'imec0.ap#AP29' 'imec0.ap#AP30' 'imec0.ap#AP31' + 'imec0.ap#AP32' 'imec0.ap#AP33' 'imec0.ap#AP34' 'imec0.ap#AP35' + 'imec0.ap#AP36' 'imec0.ap#AP37' 'imec0.ap#AP38' 'imec0.ap#AP39' + 'imec0.ap#AP40' 'imec0.ap#AP41' 'imec0.ap#AP42' 'imec0.ap#AP43' + 'imec0.ap#AP44' 'imec0.ap#AP45' 'imec0.ap#AP46' 'imec0.ap#AP47' + 'imec0.ap#AP48' 'imec0.ap#AP49' 'imec0.ap#AP50' 'imec0.ap#AP51' + 'imec0.ap#AP52' 'imec0.ap#AP53' 'imec0.ap#AP54' 'imec0.ap#AP55' + 'imec0.ap#AP56' 'imec0.ap#AP57' 'imec0.ap#AP58' 'imec0.ap#AP59' + 'imec0.ap#AP60' 'imec0.ap#AP61' 'imec0.ap#AP62' 'imec0.ap#AP63' + 'imec0.ap#AP64' 'imec0.ap#AP65' 'imec0.ap#AP66' 'imec0.ap#AP67' + 'imec0.ap#AP68' 'imec0.ap#AP69' 'imec0.ap#AP70' 'imec0.ap#AP71' + 'imec0.ap#AP72' 'imec0.ap#AP73' 'imec0.ap#AP74' 'imec0.ap#AP75' + 'imec0.ap#AP76' 'imec0.ap#AP77' 'imec0.ap#AP78' 'imec0.ap#AP79' + 'imec0.ap#AP80' 'imec0.ap#AP81' 'imec0.ap#AP82' 'imec0.ap#AP83' + 'imec0.ap#AP84' 'imec0.ap#AP85' 'imec0.ap#AP86' 'imec0.ap#AP87' + 'imec0.ap#AP88' 'imec0.ap#AP89' 'imec0.ap#AP90' 'imec0.ap#AP91' + 'imec0.ap#AP92' 'imec0.ap#AP93' 'imec0.ap#AP94' 'imec0.ap#AP95' + 'imec0.ap#AP96' 'imec0.ap#AP97' 'imec0.ap#AP98' 'imec0.ap#AP99' + 'imec0.ap#AP100' 'imec0.ap#AP101' 'imec0.ap#AP102' 'imec0.ap#AP103' + 'imec0.ap#AP104' 'imec0.ap#AP105' 'imec0.ap#AP106' 'imec0.ap#AP107' + 'imec0.ap#AP108' 'imec0.ap#AP109' 'imec0.ap#AP110' 'imec0.ap#AP111' + 'imec0.ap#AP112' 'imec0.ap#AP113' 'imec0.ap#AP114' 'imec0.ap#AP115' + 'imec0.ap#AP116' 'imec0.ap#AP117' 'imec0.ap#AP118' 'imec0.ap#AP119' + 'imec0.ap#AP120' 'imec0.ap#AP121' 'imec0.ap#AP122' 'imec0.ap#AP123' + 'imec0.ap#AP124' 'imec0.ap#AP125' 'imec0.ap#AP126' 'imec0.ap#AP127' + 'imec0.ap#AP128' 'imec0.ap#AP129' 'imec0.ap#AP130' 'imec0.ap#AP131' + 'imec0.ap#AP132' 'imec0.ap#AP133' 'imec0.ap#AP134' 'imec0.ap#AP135' + 'imec0.ap#AP136' 'imec0.ap#AP137' 'imec0.ap#AP138' 'imec0.ap#AP139' + 'imec0.ap#AP140' 'imec0.ap#AP141' 'imec0.ap#AP142' 'imec0.ap#AP143' + 'imec0.ap#AP144' 'imec0.ap#AP145' 'imec0.ap#AP146' 'imec0.ap#AP147' + 'imec0.ap#AP148' 'imec0.ap#AP149' 'imec0.ap#AP150' 'imec0.ap#AP151' + 'imec0.ap#AP152' 'imec0.ap#AP153' 'imec0.ap#AP154' 'imec0.ap#AP155' + 'imec0.ap#AP156' 'imec0.ap#AP157' 'imec0.ap#AP158' 'imec0.ap#AP159' + 'imec0.ap#AP160' 'imec0.ap#AP161' 'imec0.ap#AP162' 'imec0.ap#AP163' + 'imec0.ap#AP164' 'imec0.ap#AP165' 'imec0.ap#AP166' 'imec0.ap#AP167' + 'imec0.ap#AP168' 'imec0.ap#AP169' 'imec0.ap#AP170' 'imec0.ap#AP171' + 'imec0.ap#AP172' 'imec0.ap#AP173' 'imec0.ap#AP174' 'imec0.ap#AP175' + 'imec0.ap#AP176' 'imec0.ap#AP177' 'imec0.ap#AP178' 'imec0.ap#AP179' + 'imec0.ap#AP180' 'imec0.ap#AP181' 'imec0.ap#AP182' 'imec0.ap#AP183' + 'imec0.ap#AP184' 'imec0.ap#AP185' 'imec0.ap#AP186' 'imec0.ap#AP187' + 'imec0.ap#AP188' 'imec0.ap#AP189' 'imec0.ap#AP190' 'imec0.ap#AP191' + 'imec0.ap#AP192' 'imec0.ap#AP193' 'imec0.ap#AP194' 'imec0.ap#AP195' + 'imec0.ap#AP196' 'imec0.ap#AP197' 'imec0.ap#AP198' 'imec0.ap#AP199' + 'imec0.ap#AP200' 'imec0.ap#AP201' 'imec0.ap#AP202' 'imec0.ap#AP203' + 'imec0.ap#AP204' 'imec0.ap#AP205' 'imec0.ap#AP206' 'imec0.ap#AP207' + 'imec0.ap#AP208' 'imec0.ap#AP209' 'imec0.ap#AP210' 'imec0.ap#AP211' + 'imec0.ap#AP212' 'imec0.ap#AP213' 'imec0.ap#AP214' 'imec0.ap#AP215' + 'imec0.ap#AP216' 'imec0.ap#AP217' 'imec0.ap#AP218' 'imec0.ap#AP219' + 'imec0.ap#AP220' 'imec0.ap#AP221' 'imec0.ap#AP222' 'imec0.ap#AP223' + 'imec0.ap#AP224' 'imec0.ap#AP225' 'imec0.ap#AP226' 'imec0.ap#AP227' + 'imec0.ap#AP228' 'imec0.ap#AP229' 'imec0.ap#AP230' 'imec0.ap#AP231' + 'imec0.ap#AP232' 'imec0.ap#AP233' 'imec0.ap#AP234' 'imec0.ap#AP235' + 'imec0.ap#AP236' 'imec0.ap#AP237' 'imec0.ap#AP238' 'imec0.ap#AP239' + 'imec0.ap#AP240' 'imec0.ap#AP241' 'imec0.ap#AP242' 'imec0.ap#AP243' + 'imec0.ap#AP244' 'imec0.ap#AP245' 'imec0.ap#AP246' 'imec0.ap#AP247' + 'imec0.ap#AP248' 'imec0.ap#AP249' 'imec0.ap#AP250' 'imec0.ap#AP251' + 'imec0.ap#AP252' 'imec0.ap#AP253' 'imec0.ap#AP254' 'imec0.ap#AP255' + 'imec0.ap#AP256' 'imec0.ap#AP257' 'imec0.ap#AP258' 'imec0.ap#AP259' + 'imec0.ap#AP260' 'imec0.ap#AP261' 'imec0.ap#AP262' 'imec0.ap#AP263' + 'imec0.ap#AP264' 'imec0.ap#AP265' 'imec0.ap#AP266' 'imec0.ap#AP267' + 'imec0.ap#AP268' 'imec0.ap#AP269' 'imec0.ap#AP270' 'imec0.ap#AP271' + 'imec0.ap#AP272' 'imec0.ap#AP273' 'imec0.ap#AP274' 'imec0.ap#AP275' + 'imec0.ap#AP276' 'imec0.ap#AP277' 'imec0.ap#AP278' 'imec0.ap#AP279' + 'imec0.ap#AP280' 'imec0.ap#AP281' 'imec0.ap#AP282' 'imec0.ap#AP283' + 'imec0.ap#AP284' 'imec0.ap#AP285' 'imec0.ap#AP286' 'imec0.ap#AP287' + 'imec0.ap#AP288' 'imec0.ap#AP289' 'imec0.ap#AP290' 'imec0.ap#AP291' + 'imec0.ap#AP292' 'imec0.ap#AP293' 'imec0.ap#AP294' 'imec0.ap#AP295' + 'imec0.ap#AP296' 'imec0.ap#AP297' 'imec0.ap#AP298' 'imec0.ap#AP299' + 'imec0.ap#AP300' 'imec0.ap#AP301' 'imec0.ap#AP302' 'imec0.ap#AP303' + 'imec0.ap#AP304' 'imec0.ap#AP305' 'imec0.ap#AP306' 'imec0.ap#AP307' + 'imec0.ap#AP308' 'imec0.ap#AP309' 'imec0.ap#AP310' 'imec0.ap#AP311' + 'imec0.ap#AP312' 'imec0.ap#AP313' 'imec0.ap#AP314' 'imec0.ap#AP315' + 'imec0.ap#AP316' 'imec0.ap#AP317' 'imec0.ap#AP318' 'imec0.ap#AP319' + 'imec0.ap#AP320' 'imec0.ap#AP321' 'imec0.ap#AP322' 'imec0.ap#AP323' + 'imec0.ap#AP324' 'imec0.ap#AP325' 'imec0.ap#AP326' 'imec0.ap#AP327' + 'imec0.ap#AP328' 'imec0.ap#AP329' 'imec0.ap#AP330' 'imec0.ap#AP331' + 'imec0.ap#AP332' 'imec0.ap#AP333' 'imec0.ap#AP334' 'imec0.ap#AP335' + 'imec0.ap#AP336' 'imec0.ap#AP337' 'imec0.ap#AP338' 'imec0.ap#AP339' + 'imec0.ap#AP340' 'imec0.ap#AP341' 'imec0.ap#AP342' 'imec0.ap#AP343' + 'imec0.ap#AP344' 'imec0.ap#AP345' 'imec0.ap#AP346' 'imec0.ap#AP347' + 'imec0.ap#AP348' 'imec0.ap#AP349' 'imec0.ap#AP350' 'imec0.ap#AP351' + 'imec0.ap#AP352' 'imec0.ap#AP353' 'imec0.ap#AP354' 'imec0.ap#AP355' + 'imec0.ap#AP356' 'imec0.ap#AP357' 'imec0.ap#AP358' 'imec0.ap#AP359' + 'imec0.ap#AP360' 'imec0.ap#AP361' 'imec0.ap#AP362' 'imec0.ap#AP363' + 'imec0.ap#AP364' 'imec0.ap#AP365' 'imec0.ap#AP366' 'imec0.ap#AP367' + 'imec0.ap#AP368' 'imec0.ap#AP369' 'imec0.ap#AP370' 'imec0.ap#AP371' + 'imec0.ap#AP372' 'imec0.ap#AP373' 'imec0.ap#AP374' 'imec0.ap#AP375' + 'imec0.ap#AP376' 'imec0.ap#AP377' 'imec0.ap#AP378' 'imec0.ap#AP379' + 'imec0.ap#AP380' 'imec0.ap#AP381' 'imec0.ap#AP382' 'imec0.ap#AP383']
Annotations
  • is_filtered : True
  • probe_0_planar_contour : [[ -11 9989] + [ -11 -11] + [ 24 -186] + [ 59 -11] + [ 59 9989]]
  • probes_info : [{'manufacturer': 'IMEC', 'model_name': 'Neuropixels 1.0', 'serial_number': '18194814141'}]
Channel Properties
    gain_to_uV [2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375 + 2.34375 2.34375 2.34375 2.34375 2.34375 2.34375]
    offset_to_uV [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
    channel_names ['AP0' 'AP1' 'AP2' 'AP3' 'AP4' 'AP5' 'AP6' 'AP7' 'AP8' 'AP9' 'AP10' 'AP11' + 'AP12' 'AP13' 'AP14' 'AP15' 'AP16' 'AP17' 'AP18' 'AP19' 'AP20' 'AP21' + 'AP22' 'AP23' 'AP24' 'AP25' 'AP26' 'AP27' 'AP28' 'AP29' 'AP30' 'AP31' + 'AP32' 'AP33' 'AP34' 'AP35' 'AP36' 'AP37' 'AP38' 'AP39' 'AP40' 'AP41' + 'AP42' 'AP43' 'AP44' 'AP45' 'AP46' 'AP47' 'AP48' 'AP49' 'AP50' 'AP51' + 'AP52' 'AP53' 'AP54' 'AP55' 'AP56' 'AP57' 'AP58' 'AP59' 'AP60' 'AP61' + 'AP62' 'AP63' 'AP64' 'AP65' 'AP66' 'AP67' 'AP68' 'AP69' 'AP70' 'AP71' + 'AP72' 'AP73' 'AP74' 'AP75' 'AP76' 'AP77' 'AP78' 'AP79' 'AP80' 'AP81' + 'AP82' 'AP83' 'AP84' 'AP85' 'AP86' 'AP87' 'AP88' 'AP89' 'AP90' 'AP91' + 'AP92' 'AP93' 'AP94' 'AP95' 'AP96' 'AP97' 'AP98' 'AP99' 'AP100' 'AP101' + 'AP102' 'AP103' 'AP104' 'AP105' 'AP106' 'AP107' 'AP108' 'AP109' 'AP110' + 'AP111' 'AP112' 'AP113' 'AP114' 'AP115' 'AP116' 'AP117' 'AP118' 'AP119' + 'AP120' 'AP121' 'AP122' 'AP123' 'AP124' 'AP125' 'AP126' 'AP127' 'AP128' + 'AP129' 'AP130' 'AP131' 'AP132' 'AP133' 'AP134' 'AP135' 'AP136' 'AP137' + 'AP138' 'AP139' 'AP140' 'AP141' 'AP142' 'AP143' 'AP144' 'AP145' 'AP146' + 'AP147' 'AP148' 'AP149' 'AP150' 'AP151' 'AP152' 'AP153' 'AP154' 'AP155' + 'AP156' 'AP157' 'AP158' 'AP159' 'AP160' 'AP161' 'AP162' 'AP163' 'AP164' + 'AP165' 'AP166' 'AP167' 'AP168' 'AP169' 'AP170' 'AP171' 'AP172' 'AP173' + 'AP174' 'AP175' 'AP176' 'AP177' 'AP178' 'AP179' 'AP180' 'AP181' 'AP182' + 'AP183' 'AP184' 'AP185' 'AP186' 'AP187' 'AP188' 'AP189' 'AP190' 'AP191' + 'AP192' 'AP193' 'AP194' 'AP195' 'AP196' 'AP197' 'AP198' 'AP199' 'AP200' + 'AP201' 'AP202' 'AP203' 'AP204' 'AP205' 'AP206' 'AP207' 'AP208' 'AP209' + 'AP210' 'AP211' 'AP212' 'AP213' 'AP214' 'AP215' 'AP216' 'AP217' 'AP218' + 'AP219' 'AP220' 'AP221' 'AP222' 'AP223' 'AP224' 'AP225' 'AP226' 'AP227' + 'AP228' 'AP229' 'AP230' 'AP231' 'AP232' 'AP233' 'AP234' 'AP235' 'AP236' + 'AP237' 'AP238' 'AP239' 'AP240' 'AP241' 'AP242' 'AP243' 'AP244' 'AP245' + 'AP246' 'AP247' 'AP248' 'AP249' 'AP250' 'AP251' 'AP252' 'AP253' 'AP254' + 'AP255' 'AP256' 'AP257' 'AP258' 'AP259' 'AP260' 'AP261' 'AP262' 'AP263' + 'AP264' 'AP265' 'AP266' 'AP267' 'AP268' 'AP269' 'AP270' 'AP271' 'AP272' + 'AP273' 'AP274' 'AP275' 'AP276' 'AP277' 'AP278' 'AP279' 'AP280' 'AP281' + 'AP282' 'AP283' 'AP284' 'AP285' 'AP286' 'AP287' 'AP288' 'AP289' 'AP290' + 'AP291' 'AP292' 'AP293' 'AP294' 'AP295' 'AP296' 'AP297' 'AP298' 'AP299' + 'AP300' 'AP301' 'AP302' 'AP303' 'AP304' 'AP305' 'AP306' 'AP307' 'AP308' + 'AP309' 'AP310' 'AP311' 'AP312' 'AP313' 'AP314' 'AP315' 'AP316' 'AP317' + 'AP318' 'AP319' 'AP320' 'AP321' 'AP322' 'AP323' 'AP324' 'AP325' 'AP326' + 'AP327' 'AP328' 'AP329' 'AP330' 'AP331' 'AP332' 'AP333' 'AP334' 'AP335' + 'AP336' 'AP337' 'AP338' 'AP339' 'AP340' 'AP341' 'AP342' 'AP343' 'AP344' + 'AP345' 'AP346' 'AP347' 'AP348' 'AP349' 'AP350' 'AP351' 'AP352' 'AP353' + 'AP354' 'AP355' 'AP356' 'AP357' 'AP358' 'AP359' 'AP360' 'AP361' 'AP362' + 'AP363' 'AP364' 'AP365' 'AP366' 'AP367' 'AP368' 'AP369' 'AP370' 'AP371' + 'AP372' 'AP373' 'AP374' 'AP375' 'AP376' 'AP377' 'AP378' 'AP379' 'AP380' + 'AP381' 'AP382' 'AP383']
    contact_vector [(0, 16., 0., 'circle', 1., '', '', 0, 'um', 1., 0., 0., 1.) + (0, 48., 0., 'circle', 1., '', '', 1, 'um', 1., 0., 0., 1.) + (0, 0., 20., 'circle', 1., '', '', 2, 'um', 1., 0., 0., 1.) + (0, 32., 20., 'circle', 1., '', '', 3, 'um', 1., 0., 0., 1.) + (0, 16., 40., 'circle', 1., '', '', 4, 'um', 1., 0., 0., 1.) + (0, 48., 40., 'circle', 1., '', '', 5, 'um', 1., 0., 0., 1.) + (0, 0., 60., 'circle', 1., '', '', 6, 'um', 1., 0., 0., 1.) + (0, 32., 60., 'circle', 1., '', '', 7, 'um', 1., 0., 0., 1.) + (0, 16., 80., 'circle', 1., '', '', 8, 'um', 1., 0., 0., 1.) + (0, 48., 80., 'circle', 1., '', '', 9, 'um', 1., 0., 0., 1.) + (0, 0., 100., 'circle', 1., '', '', 10, 'um', 1., 0., 0., 1.) + (0, 32., 100., 'circle', 1., '', '', 11, 'um', 1., 0., 0., 1.) + (0, 16., 120., 'circle', 1., '', '', 12, 'um', 1., 0., 0., 1.) + (0, 48., 120., 'circle', 1., '', '', 13, 'um', 1., 0., 0., 1.) + (0, 0., 140., 'circle', 1., '', '', 14, 'um', 1., 0., 0., 1.) + (0, 32., 140., 'circle', 1., '', '', 15, 'um', 1., 0., 0., 1.) + (0, 16., 160., 'circle', 1., '', '', 16, 'um', 1., 0., 0., 1.) + (0, 48., 160., 'circle', 1., '', '', 17, 'um', 1., 0., 0., 1.) + (0, 0., 180., 'circle', 1., '', '', 18, 'um', 1., 0., 0., 1.) + (0, 32., 180., 'circle', 1., '', '', 19, 'um', 1., 0., 0., 1.) + (0, 16., 200., 'circle', 1., '', '', 20, 'um', 1., 0., 0., 1.) + (0, 48., 200., 'circle', 1., '', '', 21, 'um', 1., 0., 0., 1.) + (0, 0., 220., 'circle', 1., '', '', 22, 'um', 1., 0., 0., 1.) + (0, 32., 220., 'circle', 1., '', '', 23, 'um', 1., 0., 0., 1.) + (0, 16., 240., 'circle', 1., '', '', 24, 'um', 1., 0., 0., 1.) + (0, 48., 240., 'circle', 1., '', '', 25, 'um', 1., 0., 0., 1.) + (0, 0., 260., 'circle', 1., '', '', 26, 'um', 1., 0., 0., 1.) + (0, 32., 260., 'circle', 1., '', '', 27, 'um', 1., 0., 0., 1.) + (0, 16., 280., 'circle', 1., '', '', 28, 'um', 1., 0., 0., 1.) + (0, 48., 280., 'circle', 1., '', '', 29, 'um', 1., 0., 0., 1.) + (0, 0., 300., 'circle', 1., '', '', 30, 'um', 1., 0., 0., 1.) + (0, 32., 300., 'circle', 1., '', '', 31, 'um', 1., 0., 0., 1.) + (0, 16., 320., 'circle', 1., '', '', 32, 'um', 1., 0., 0., 1.) + (0, 48., 320., 'circle', 1., '', '', 33, 'um', 1., 0., 0., 1.) + (0, 0., 340., 'circle', 1., '', '', 34, 'um', 1., 0., 0., 1.) + (0, 32., 340., 'circle', 1., '', '', 35, 'um', 1., 0., 0., 1.) + (0, 16., 360., 'circle', 1., '', '', 36, 'um', 1., 0., 0., 1.) + (0, 48., 360., 'circle', 1., '', '', 37, 'um', 1., 0., 0., 1.) + (0, 0., 380., 'circle', 1., '', '', 38, 'um', 1., 0., 0., 1.) + (0, 32., 380., 'circle', 1., '', '', 39, 'um', 1., 0., 0., 1.) + (0, 16., 400., 'circle', 1., '', '', 40, 'um', 1., 0., 0., 1.) + (0, 48., 400., 'circle', 1., '', '', 41, 'um', 1., 0., 0., 1.) + (0, 0., 420., 'circle', 1., '', '', 42, 'um', 1., 0., 0., 1.) + (0, 32., 420., 'circle', 1., '', '', 43, 'um', 1., 0., 0., 1.) + (0, 16., 440., 'circle', 1., '', '', 44, 'um', 1., 0., 0., 1.) + (0, 48., 440., 'circle', 1., '', '', 45, 'um', 1., 0., 0., 1.) + (0, 0., 460., 'circle', 1., '', '', 46, 'um', 1., 0., 0., 1.) + (0, 32., 460., 'circle', 1., '', '', 47, 'um', 1., 0., 0., 1.) + (0, 16., 480., 'circle', 1., '', '', 48, 'um', 1., 0., 0., 1.) + (0, 48., 480., 'circle', 1., '', '', 49, 'um', 1., 0., 0., 1.) + (0, 0., 500., 'circle', 1., '', '', 50, 'um', 1., 0., 0., 1.) + (0, 32., 500., 'circle', 1., '', '', 51, 'um', 1., 0., 0., 1.) + (0, 16., 520., 'circle', 1., '', '', 52, 'um', 1., 0., 0., 1.) + (0, 48., 520., 'circle', 1., '', '', 53, 'um', 1., 0., 0., 1.) + (0, 0., 540., 'circle', 1., '', '', 54, 'um', 1., 0., 0., 1.) + (0, 32., 540., 'circle', 1., '', '', 55, 'um', 1., 0., 0., 1.) + (0, 16., 560., 'circle', 1., '', '', 56, 'um', 1., 0., 0., 1.) + (0, 48., 560., 'circle', 1., '', '', 57, 'um', 1., 0., 0., 1.) + (0, 0., 580., 'circle', 1., '', '', 58, 'um', 1., 0., 0., 1.) + (0, 32., 580., 'circle', 1., '', '', 59, 'um', 1., 0., 0., 1.) + (0, 16., 600., 'circle', 1., '', '', 60, 'um', 1., 0., 0., 1.) + (0, 48., 600., 'circle', 1., '', '', 61, 'um', 1., 0., 0., 1.) + (0, 0., 620., 'circle', 1., '', '', 62, 'um', 1., 0., 0., 1.) + (0, 32., 620., 'circle', 1., '', '', 63, 'um', 1., 0., 0., 1.) + (0, 16., 640., 'circle', 1., '', '', 64, 'um', 1., 0., 0., 1.) + (0, 48., 640., 'circle', 1., '', '', 65, 'um', 1., 0., 0., 1.) + (0, 0., 660., 'circle', 1., '', '', 66, 'um', 1., 0., 0., 1.) + (0, 32., 660., 'circle', 1., '', '', 67, 'um', 1., 0., 0., 1.) + (0, 16., 680., 'circle', 1., '', '', 68, 'um', 1., 0., 0., 1.) + (0, 48., 680., 'circle', 1., '', '', 69, 'um', 1., 0., 0., 1.) + (0, 0., 700., 'circle', 1., '', '', 70, 'um', 1., 0., 0., 1.) + (0, 32., 700., 'circle', 1., '', '', 71, 'um', 1., 0., 0., 1.) + (0, 16., 720., 'circle', 1., '', '', 72, 'um', 1., 0., 0., 1.) + (0, 48., 720., 'circle', 1., '', '', 73, 'um', 1., 0., 0., 1.) + (0, 0., 740., 'circle', 1., '', '', 74, 'um', 1., 0., 0., 1.) + (0, 32., 740., 'circle', 1., '', '', 75, 'um', 1., 0., 0., 1.) + (0, 16., 760., 'circle', 1., '', '', 76, 'um', 1., 0., 0., 1.) + (0, 48., 760., 'circle', 1., '', '', 77, 'um', 1., 0., 0., 1.) + (0, 0., 780., 'circle', 1., '', '', 78, 'um', 1., 0., 0., 1.) + (0, 32., 780., 'circle', 1., '', '', 79, 'um', 1., 0., 0., 1.) + (0, 16., 800., 'circle', 1., '', '', 80, 'um', 1., 0., 0., 1.) + (0, 48., 800., 'circle', 1., '', '', 81, 'um', 1., 0., 0., 1.) + (0, 0., 820., 'circle', 1., '', '', 82, 'um', 1., 0., 0., 1.) + (0, 32., 820., 'circle', 1., '', '', 83, 'um', 1., 0., 0., 1.) + (0, 16., 840., 'circle', 1., '', '', 84, 'um', 1., 0., 0., 1.) + (0, 48., 840., 'circle', 1., '', '', 85, 'um', 1., 0., 0., 1.) + (0, 0., 860., 'circle', 1., '', '', 86, 'um', 1., 0., 0., 1.) + (0, 32., 860., 'circle', 1., '', '', 87, 'um', 1., 0., 0., 1.) + (0, 16., 880., 'circle', 1., '', '', 88, 'um', 1., 0., 0., 1.) + (0, 48., 880., 'circle', 1., '', '', 89, 'um', 1., 0., 0., 1.) + (0, 0., 900., 'circle', 1., '', '', 90, 'um', 1., 0., 0., 1.) + (0, 32., 900., 'circle', 1., '', '', 91, 'um', 1., 0., 0., 1.) + (0, 16., 920., 'circle', 1., '', '', 92, 'um', 1., 0., 0., 1.) + (0, 48., 920., 'circle', 1., '', '', 93, 'um', 1., 0., 0., 1.) + (0, 0., 940., 'circle', 1., '', '', 94, 'um', 1., 0., 0., 1.) + (0, 32., 940., 'circle', 1., '', '', 95, 'um', 1., 0., 0., 1.) + (0, 16., 960., 'circle', 1., '', '', 96, 'um', 1., 0., 0., 1.) + (0, 48., 960., 'circle', 1., '', '', 97, 'um', 1., 0., 0., 1.) + (0, 0., 980., 'circle', 1., '', '', 98, 'um', 1., 0., 0., 1.) + (0, 32., 980., 'circle', 1., '', '', 99, 'um', 1., 0., 0., 1.) + (0, 16., 1000., 'circle', 1., '', '', 100, 'um', 1., 0., 0., 1.) + (0, 48., 1000., 'circle', 1., '', '', 101, 'um', 1., 0., 0., 1.) + (0, 0., 1020., 'circle', 1., '', '', 102, 'um', 1., 0., 0., 1.) + (0, 32., 1020., 'circle', 1., '', '', 103, 'um', 1., 0., 0., 1.) + (0, 16., 1040., 'circle', 1., '', '', 104, 'um', 1., 0., 0., 1.) + (0, 48., 1040., 'circle', 1., '', '', 105, 'um', 1., 0., 0., 1.) + (0, 0., 1060., 'circle', 1., '', '', 106, 'um', 1., 0., 0., 1.) + (0, 32., 1060., 'circle', 1., '', '', 107, 'um', 1., 0., 0., 1.) + (0, 16., 1080., 'circle', 1., '', '', 108, 'um', 1., 0., 0., 1.) + (0, 48., 1080., 'circle', 1., '', '', 109, 'um', 1., 0., 0., 1.) + (0, 0., 1100., 'circle', 1., '', '', 110, 'um', 1., 0., 0., 1.) + (0, 32., 1100., 'circle', 1., '', '', 111, 'um', 1., 0., 0., 1.) + (0, 16., 1120., 'circle', 1., '', '', 112, 'um', 1., 0., 0., 1.) + (0, 48., 1120., 'circle', 1., '', '', 113, 'um', 1., 0., 0., 1.) + (0, 0., 1140., 'circle', 1., '', '', 114, 'um', 1., 0., 0., 1.) + (0, 32., 1140., 'circle', 1., '', '', 115, 'um', 1., 0., 0., 1.) + (0, 16., 1160., 'circle', 1., '', '', 116, 'um', 1., 0., 0., 1.) + (0, 48., 1160., 'circle', 1., '', '', 117, 'um', 1., 0., 0., 1.) + (0, 0., 1180., 'circle', 1., '', '', 118, 'um', 1., 0., 0., 1.) + (0, 32., 1180., 'circle', 1., '', '', 119, 'um', 1., 0., 0., 1.) + (0, 16., 1200., 'circle', 1., '', '', 120, 'um', 1., 0., 0., 1.) + (0, 48., 1200., 'circle', 1., '', '', 121, 'um', 1., 0., 0., 1.) + (0, 0., 1220., 'circle', 1., '', '', 122, 'um', 1., 0., 0., 1.) + (0, 32., 1220., 'circle', 1., '', '', 123, 'um', 1., 0., 0., 1.) + (0, 16., 1240., 'circle', 1., '', '', 124, 'um', 1., 0., 0., 1.) + (0, 48., 1240., 'circle', 1., '', '', 125, 'um', 1., 0., 0., 1.) + (0, 0., 1260., 'circle', 1., '', '', 126, 'um', 1., 0., 0., 1.) + (0, 32., 1260., 'circle', 1., '', '', 127, 'um', 1., 0., 0., 1.) + (0, 16., 1280., 'circle', 1., '', '', 128, 'um', 1., 0., 0., 1.) + (0, 48., 1280., 'circle', 1., '', '', 129, 'um', 1., 0., 0., 1.) + (0, 0., 1300., 'circle', 1., '', '', 130, 'um', 1., 0., 0., 1.) + (0, 32., 1300., 'circle', 1., '', '', 131, 'um', 1., 0., 0., 1.) + (0, 16., 1320., 'circle', 1., '', '', 132, 'um', 1., 0., 0., 1.) + (0, 48., 1320., 'circle', 1., '', '', 133, 'um', 1., 0., 0., 1.) + (0, 0., 1340., 'circle', 1., '', '', 134, 'um', 1., 0., 0., 1.) + (0, 32., 1340., 'circle', 1., '', '', 135, 'um', 1., 0., 0., 1.) + (0, 16., 1360., 'circle', 1., '', '', 136, 'um', 1., 0., 0., 1.) + (0, 48., 1360., 'circle', 1., '', '', 137, 'um', 1., 0., 0., 1.) + (0, 0., 1380., 'circle', 1., '', '', 138, 'um', 1., 0., 0., 1.) + (0, 32., 1380., 'circle', 1., '', '', 139, 'um', 1., 0., 0., 1.) + (0, 16., 1400., 'circle', 1., '', '', 140, 'um', 1., 0., 0., 1.) + (0, 48., 1400., 'circle', 1., '', '', 141, 'um', 1., 0., 0., 1.) + (0, 0., 1420., 'circle', 1., '', '', 142, 'um', 1., 0., 0., 1.) + (0, 32., 1420., 'circle', 1., '', '', 143, 'um', 1., 0., 0., 1.) + (0, 16., 1440., 'circle', 1., '', '', 144, 'um', 1., 0., 0., 1.) + (0, 48., 1440., 'circle', 1., '', '', 145, 'um', 1., 0., 0., 1.) + (0, 0., 1460., 'circle', 1., '', '', 146, 'um', 1., 0., 0., 1.) + (0, 32., 1460., 'circle', 1., '', '', 147, 'um', 1., 0., 0., 1.) + (0, 16., 1480., 'circle', 1., '', '', 148, 'um', 1., 0., 0., 1.) + (0, 48., 1480., 'circle', 1., '', '', 149, 'um', 1., 0., 0., 1.) + (0, 0., 1500., 'circle', 1., '', '', 150, 'um', 1., 0., 0., 1.) + (0, 32., 1500., 'circle', 1., '', '', 151, 'um', 1., 0., 0., 1.) + (0, 16., 1520., 'circle', 1., '', '', 152, 'um', 1., 0., 0., 1.) + (0, 48., 1520., 'circle', 1., '', '', 153, 'um', 1., 0., 0., 1.) + (0, 0., 1540., 'circle', 1., '', '', 154, 'um', 1., 0., 0., 1.) + (0, 32., 1540., 'circle', 1., '', '', 155, 'um', 1., 0., 0., 1.) + (0, 16., 1560., 'circle', 1., '', '', 156, 'um', 1., 0., 0., 1.) + (0, 48., 1560., 'circle', 1., '', '', 157, 'um', 1., 0., 0., 1.) + (0, 0., 1580., 'circle', 1., '', '', 158, 'um', 1., 0., 0., 1.) + (0, 32., 1580., 'circle', 1., '', '', 159, 'um', 1., 0., 0., 1.) + (0, 16., 1600., 'circle', 1., '', '', 160, 'um', 1., 0., 0., 1.) + (0, 48., 1600., 'circle', 1., '', '', 161, 'um', 1., 0., 0., 1.) + (0, 0., 1620., 'circle', 1., '', '', 162, 'um', 1., 0., 0., 1.) + (0, 32., 1620., 'circle', 1., '', '', 163, 'um', 1., 0., 0., 1.) + (0, 16., 1640., 'circle', 1., '', '', 164, 'um', 1., 0., 0., 1.) + (0, 48., 1640., 'circle', 1., '', '', 165, 'um', 1., 0., 0., 1.) + (0, 0., 1660., 'circle', 1., '', '', 166, 'um', 1., 0., 0., 1.) + (0, 32., 1660., 'circle', 1., '', '', 167, 'um', 1., 0., 0., 1.) + (0, 16., 1680., 'circle', 1., '', '', 168, 'um', 1., 0., 0., 1.) + (0, 48., 1680., 'circle', 1., '', '', 169, 'um', 1., 0., 0., 1.) + (0, 0., 1700., 'circle', 1., '', '', 170, 'um', 1., 0., 0., 1.) + (0, 32., 1700., 'circle', 1., '', '', 171, 'um', 1., 0., 0., 1.) + (0, 16., 1720., 'circle', 1., '', '', 172, 'um', 1., 0., 0., 1.) + (0, 48., 1720., 'circle', 1., '', '', 173, 'um', 1., 0., 0., 1.) + (0, 0., 1740., 'circle', 1., '', '', 174, 'um', 1., 0., 0., 1.) + (0, 32., 1740., 'circle', 1., '', '', 175, 'um', 1., 0., 0., 1.) + (0, 16., 1760., 'circle', 1., '', '', 176, 'um', 1., 0., 0., 1.) + (0, 48., 1760., 'circle', 1., '', '', 177, 'um', 1., 0., 0., 1.) + (0, 0., 1780., 'circle', 1., '', '', 178, 'um', 1., 0., 0., 1.) + (0, 32., 1780., 'circle', 1., '', '', 179, 'um', 1., 0., 0., 1.) + (0, 16., 1800., 'circle', 1., '', '', 180, 'um', 1., 0., 0., 1.) + (0, 48., 1800., 'circle', 1., '', '', 181, 'um', 1., 0., 0., 1.) + (0, 0., 1820., 'circle', 1., '', '', 182, 'um', 1., 0., 0., 1.) + (0, 32., 1820., 'circle', 1., '', '', 183, 'um', 1., 0., 0., 1.) + (0, 16., 1840., 'circle', 1., '', '', 184, 'um', 1., 0., 0., 1.) + (0, 48., 1840., 'circle', 1., '', '', 185, 'um', 1., 0., 0., 1.) + (0, 0., 1860., 'circle', 1., '', '', 186, 'um', 1., 0., 0., 1.) + (0, 32., 1860., 'circle', 1., '', '', 187, 'um', 1., 0., 0., 1.) + (0, 16., 1880., 'circle', 1., '', '', 188, 'um', 1., 0., 0., 1.) + (0, 48., 1880., 'circle', 1., '', '', 189, 'um', 1., 0., 0., 1.) + (0, 0., 1900., 'circle', 1., '', '', 190, 'um', 1., 0., 0., 1.) + (0, 32., 1900., 'circle', 1., '', '', 191, 'um', 1., 0., 0., 1.) + (0, 16., 1920., 'circle', 1., '', '', 192, 'um', 1., 0., 0., 1.) + (0, 48., 1920., 'circle', 1., '', '', 193, 'um', 1., 0., 0., 1.) + (0, 0., 1940., 'circle', 1., '', '', 194, 'um', 1., 0., 0., 1.) + (0, 32., 1940., 'circle', 1., '', '', 195, 'um', 1., 0., 0., 1.) + (0, 16., 1960., 'circle', 1., '', '', 196, 'um', 1., 0., 0., 1.) + (0, 48., 1960., 'circle', 1., '', '', 197, 'um', 1., 0., 0., 1.) + (0, 0., 1980., 'circle', 1., '', '', 198, 'um', 1., 0., 0., 1.) + (0, 32., 1980., 'circle', 1., '', '', 199, 'um', 1., 0., 0., 1.) + (0, 16., 2000., 'circle', 1., '', '', 200, 'um', 1., 0., 0., 1.) + (0, 48., 2000., 'circle', 1., '', '', 201, 'um', 1., 0., 0., 1.) + (0, 0., 2020., 'circle', 1., '', '', 202, 'um', 1., 0., 0., 1.) + (0, 32., 2020., 'circle', 1., '', '', 203, 'um', 1., 0., 0., 1.) + (0, 16., 2040., 'circle', 1., '', '', 204, 'um', 1., 0., 0., 1.) + (0, 48., 2040., 'circle', 1., '', '', 205, 'um', 1., 0., 0., 1.) + (0, 0., 2060., 'circle', 1., '', '', 206, 'um', 1., 0., 0., 1.) + (0, 32., 2060., 'circle', 1., '', '', 207, 'um', 1., 0., 0., 1.) + (0, 16., 2080., 'circle', 1., '', '', 208, 'um', 1., 0., 0., 1.) + (0, 48., 2080., 'circle', 1., '', '', 209, 'um', 1., 0., 0., 1.) + (0, 0., 2100., 'circle', 1., '', '', 210, 'um', 1., 0., 0., 1.) + (0, 32., 2100., 'circle', 1., '', '', 211, 'um', 1., 0., 0., 1.) + (0, 16., 2120., 'circle', 1., '', '', 212, 'um', 1., 0., 0., 1.) + (0, 48., 2120., 'circle', 1., '', '', 213, 'um', 1., 0., 0., 1.) + (0, 0., 2140., 'circle', 1., '', '', 214, 'um', 1., 0., 0., 1.) + (0, 32., 2140., 'circle', 1., '', '', 215, 'um', 1., 0., 0., 1.) + (0, 16., 2160., 'circle', 1., '', '', 216, 'um', 1., 0., 0., 1.) + (0, 48., 2160., 'circle', 1., '', '', 217, 'um', 1., 0., 0., 1.) + (0, 0., 2180., 'circle', 1., '', '', 218, 'um', 1., 0., 0., 1.) + (0, 32., 2180., 'circle', 1., '', '', 219, 'um', 1., 0., 0., 1.) + (0, 16., 2200., 'circle', 1., '', '', 220, 'um', 1., 0., 0., 1.) + (0, 48., 2200., 'circle', 1., '', '', 221, 'um', 1., 0., 0., 1.) + (0, 0., 2220., 'circle', 1., '', '', 222, 'um', 1., 0., 0., 1.) + (0, 32., 2220., 'circle', 1., '', '', 223, 'um', 1., 0., 0., 1.) + (0, 16., 2240., 'circle', 1., '', '', 224, 'um', 1., 0., 0., 1.) + (0, 48., 2240., 'circle', 1., '', '', 225, 'um', 1., 0., 0., 1.) + (0, 0., 2260., 'circle', 1., '', '', 226, 'um', 1., 0., 0., 1.) + (0, 32., 2260., 'circle', 1., '', '', 227, 'um', 1., 0., 0., 1.) + (0, 16., 2280., 'circle', 1., '', '', 228, 'um', 1., 0., 0., 1.) + (0, 48., 2280., 'circle', 1., '', '', 229, 'um', 1., 0., 0., 1.) + (0, 0., 2300., 'circle', 1., '', '', 230, 'um', 1., 0., 0., 1.) + (0, 32., 2300., 'circle', 1., '', '', 231, 'um', 1., 0., 0., 1.) + (0, 16., 2320., 'circle', 1., '', '', 232, 'um', 1., 0., 0., 1.) + (0, 48., 2320., 'circle', 1., '', '', 233, 'um', 1., 0., 0., 1.) + (0, 0., 2340., 'circle', 1., '', '', 234, 'um', 1., 0., 0., 1.) + (0, 32., 2340., 'circle', 1., '', '', 235, 'um', 1., 0., 0., 1.) + (0, 16., 2360., 'circle', 1., '', '', 236, 'um', 1., 0., 0., 1.) + (0, 48., 2360., 'circle', 1., '', '', 237, 'um', 1., 0., 0., 1.) + (0, 0., 2380., 'circle', 1., '', '', 238, 'um', 1., 0., 0., 1.) + (0, 32., 2380., 'circle', 1., '', '', 239, 'um', 1., 0., 0., 1.) + (0, 16., 2400., 'circle', 1., '', '', 240, 'um', 1., 0., 0., 1.) + (0, 48., 2400., 'circle', 1., '', '', 241, 'um', 1., 0., 0., 1.) + (0, 0., 2420., 'circle', 1., '', '', 242, 'um', 1., 0., 0., 1.) + (0, 32., 2420., 'circle', 1., '', '', 243, 'um', 1., 0., 0., 1.) + (0, 16., 2440., 'circle', 1., '', '', 244, 'um', 1., 0., 0., 1.) + (0, 48., 2440., 'circle', 1., '', '', 245, 'um', 1., 0., 0., 1.) + (0, 0., 2460., 'circle', 1., '', '', 246, 'um', 1., 0., 0., 1.) + (0, 32., 2460., 'circle', 1., '', '', 247, 'um', 1., 0., 0., 1.) + (0, 16., 2480., 'circle', 1., '', '', 248, 'um', 1., 0., 0., 1.) + (0, 48., 2480., 'circle', 1., '', '', 249, 'um', 1., 0., 0., 1.) + (0, 0., 2500., 'circle', 1., '', '', 250, 'um', 1., 0., 0., 1.) + (0, 32., 2500., 'circle', 1., '', '', 251, 'um', 1., 0., 0., 1.) + (0, 16., 2520., 'circle', 1., '', '', 252, 'um', 1., 0., 0., 1.) + (0, 48., 2520., 'circle', 1., '', '', 253, 'um', 1., 0., 0., 1.) + (0, 0., 2540., 'circle', 1., '', '', 254, 'um', 1., 0., 0., 1.) + (0, 32., 2540., 'circle', 1., '', '', 255, 'um', 1., 0., 0., 1.) + (0, 16., 2560., 'circle', 1., '', '', 256, 'um', 1., 0., 0., 1.) + (0, 48., 2560., 'circle', 1., '', '', 257, 'um', 1., 0., 0., 1.) + (0, 0., 2580., 'circle', 1., '', '', 258, 'um', 1., 0., 0., 1.) + (0, 32., 2580., 'circle', 1., '', '', 259, 'um', 1., 0., 0., 1.) + (0, 16., 2600., 'circle', 1., '', '', 260, 'um', 1., 0., 0., 1.) + (0, 48., 2600., 'circle', 1., '', '', 261, 'um', 1., 0., 0., 1.) + (0, 0., 2620., 'circle', 1., '', '', 262, 'um', 1., 0., 0., 1.) + (0, 32., 2620., 'circle', 1., '', '', 263, 'um', 1., 0., 0., 1.) + (0, 16., 2640., 'circle', 1., '', '', 264, 'um', 1., 0., 0., 1.) + (0, 48., 2640., 'circle', 1., '', '', 265, 'um', 1., 0., 0., 1.) + (0, 0., 2660., 'circle', 1., '', '', 266, 'um', 1., 0., 0., 1.) + (0, 32., 2660., 'circle', 1., '', '', 267, 'um', 1., 0., 0., 1.) + (0, 16., 2680., 'circle', 1., '', '', 268, 'um', 1., 0., 0., 1.) + (0, 48., 2680., 'circle', 1., '', '', 269, 'um', 1., 0., 0., 1.) + (0, 0., 2700., 'circle', 1., '', '', 270, 'um', 1., 0., 0., 1.) + (0, 32., 2700., 'circle', 1., '', '', 271, 'um', 1., 0., 0., 1.) + (0, 16., 2720., 'circle', 1., '', '', 272, 'um', 1., 0., 0., 1.) + (0, 48., 2720., 'circle', 1., '', '', 273, 'um', 1., 0., 0., 1.) + (0, 0., 2740., 'circle', 1., '', '', 274, 'um', 1., 0., 0., 1.) + (0, 32., 2740., 'circle', 1., '', '', 275, 'um', 1., 0., 0., 1.) + (0, 16., 2760., 'circle', 1., '', '', 276, 'um', 1., 0., 0., 1.) + (0, 48., 2760., 'circle', 1., '', '', 277, 'um', 1., 0., 0., 1.) + (0, 0., 2780., 'circle', 1., '', '', 278, 'um', 1., 0., 0., 1.) + (0, 32., 2780., 'circle', 1., '', '', 279, 'um', 1., 0., 0., 1.) + (0, 16., 2800., 'circle', 1., '', '', 280, 'um', 1., 0., 0., 1.) + (0, 48., 2800., 'circle', 1., '', '', 281, 'um', 1., 0., 0., 1.) + (0, 0., 2820., 'circle', 1., '', '', 282, 'um', 1., 0., 0., 1.) + (0, 32., 2820., 'circle', 1., '', '', 283, 'um', 1., 0., 0., 1.) + (0, 16., 2840., 'circle', 1., '', '', 284, 'um', 1., 0., 0., 1.) + (0, 48., 2840., 'circle', 1., '', '', 285, 'um', 1., 0., 0., 1.) + (0, 0., 2860., 'circle', 1., '', '', 286, 'um', 1., 0., 0., 1.) + (0, 32., 2860., 'circle', 1., '', '', 287, 'um', 1., 0., 0., 1.) + (0, 16., 2880., 'circle', 1., '', '', 288, 'um', 1., 0., 0., 1.) + (0, 48., 2880., 'circle', 1., '', '', 289, 'um', 1., 0., 0., 1.) + (0, 0., 2900., 'circle', 1., '', '', 290, 'um', 1., 0., 0., 1.) + (0, 32., 2900., 'circle', 1., '', '', 291, 'um', 1., 0., 0., 1.) + (0, 16., 2920., 'circle', 1., '', '', 292, 'um', 1., 0., 0., 1.) + (0, 48., 2920., 'circle', 1., '', '', 293, 'um', 1., 0., 0., 1.) + (0, 0., 2940., 'circle', 1., '', '', 294, 'um', 1., 0., 0., 1.) + (0, 32., 2940., 'circle', 1., '', '', 295, 'um', 1., 0., 0., 1.) + (0, 16., 2960., 'circle', 1., '', '', 296, 'um', 1., 0., 0., 1.) + (0, 48., 2960., 'circle', 1., '', '', 297, 'um', 1., 0., 0., 1.) + (0, 0., 2980., 'circle', 1., '', '', 298, 'um', 1., 0., 0., 1.) + (0, 32., 2980., 'circle', 1., '', '', 299, 'um', 1., 0., 0., 1.) + (0, 16., 3000., 'circle', 1., '', '', 300, 'um', 1., 0., 0., 1.) + (0, 48., 3000., 'circle', 1., '', '', 301, 'um', 1., 0., 0., 1.) + (0, 0., 3020., 'circle', 1., '', '', 302, 'um', 1., 0., 0., 1.) + (0, 32., 3020., 'circle', 1., '', '', 303, 'um', 1., 0., 0., 1.) + (0, 16., 3040., 'circle', 1., '', '', 304, 'um', 1., 0., 0., 1.) + (0, 48., 3040., 'circle', 1., '', '', 305, 'um', 1., 0., 0., 1.) + (0, 0., 3060., 'circle', 1., '', '', 306, 'um', 1., 0., 0., 1.) + (0, 32., 3060., 'circle', 1., '', '', 307, 'um', 1., 0., 0., 1.) + (0, 16., 3080., 'circle', 1., '', '', 308, 'um', 1., 0., 0., 1.) + (0, 48., 3080., 'circle', 1., '', '', 309, 'um', 1., 0., 0., 1.) + (0, 0., 3100., 'circle', 1., '', '', 310, 'um', 1., 0., 0., 1.) + (0, 32., 3100., 'circle', 1., '', '', 311, 'um', 1., 0., 0., 1.) + (0, 16., 3120., 'circle', 1., '', '', 312, 'um', 1., 0., 0., 1.) + (0, 48., 3120., 'circle', 1., '', '', 313, 'um', 1., 0., 0., 1.) + (0, 0., 3140., 'circle', 1., '', '', 314, 'um', 1., 0., 0., 1.) + (0, 32., 3140., 'circle', 1., '', '', 315, 'um', 1., 0., 0., 1.) + (0, 16., 3160., 'circle', 1., '', '', 316, 'um', 1., 0., 0., 1.) + (0, 48., 3160., 'circle', 1., '', '', 317, 'um', 1., 0., 0., 1.) + (0, 0., 3180., 'circle', 1., '', '', 318, 'um', 1., 0., 0., 1.) + (0, 32., 3180., 'circle', 1., '', '', 319, 'um', 1., 0., 0., 1.) + (0, 16., 3200., 'circle', 1., '', '', 320, 'um', 1., 0., 0., 1.) + (0, 48., 3200., 'circle', 1., '', '', 321, 'um', 1., 0., 0., 1.) + (0, 0., 3220., 'circle', 1., '', '', 322, 'um', 1., 0., 0., 1.) + (0, 32., 3220., 'circle', 1., '', '', 323, 'um', 1., 0., 0., 1.) + (0, 16., 3240., 'circle', 1., '', '', 324, 'um', 1., 0., 0., 1.) + (0, 48., 3240., 'circle', 1., '', '', 325, 'um', 1., 0., 0., 1.) + (0, 0., 3260., 'circle', 1., '', '', 326, 'um', 1., 0., 0., 1.) + (0, 32., 3260., 'circle', 1., '', '', 327, 'um', 1., 0., 0., 1.) + (0, 16., 3280., 'circle', 1., '', '', 328, 'um', 1., 0., 0., 1.) + (0, 48., 3280., 'circle', 1., '', '', 329, 'um', 1., 0., 0., 1.) + (0, 0., 3300., 'circle', 1., '', '', 330, 'um', 1., 0., 0., 1.) + (0, 32., 3300., 'circle', 1., '', '', 331, 'um', 1., 0., 0., 1.) + (0, 16., 3320., 'circle', 1., '', '', 332, 'um', 1., 0., 0., 1.) + (0, 48., 3320., 'circle', 1., '', '', 333, 'um', 1., 0., 0., 1.) + (0, 0., 3340., 'circle', 1., '', '', 334, 'um', 1., 0., 0., 1.) + (0, 32., 3340., 'circle', 1., '', '', 335, 'um', 1., 0., 0., 1.) + (0, 16., 3360., 'circle', 1., '', '', 336, 'um', 1., 0., 0., 1.) + (0, 48., 3360., 'circle', 1., '', '', 337, 'um', 1., 0., 0., 1.) + (0, 0., 3380., 'circle', 1., '', '', 338, 'um', 1., 0., 0., 1.) + (0, 32., 3380., 'circle', 1., '', '', 339, 'um', 1., 0., 0., 1.) + (0, 16., 3400., 'circle', 1., '', '', 340, 'um', 1., 0., 0., 1.) + (0, 48., 3400., 'circle', 1., '', '', 341, 'um', 1., 0., 0., 1.) + (0, 0., 3420., 'circle', 1., '', '', 342, 'um', 1., 0., 0., 1.) + (0, 32., 3420., 'circle', 1., '', '', 343, 'um', 1., 0., 0., 1.) + (0, 16., 3440., 'circle', 1., '', '', 344, 'um', 1., 0., 0., 1.) + (0, 48., 3440., 'circle', 1., '', '', 345, 'um', 1., 0., 0., 1.) + (0, 0., 3460., 'circle', 1., '', '', 346, 'um', 1., 0., 0., 1.) + (0, 32., 3460., 'circle', 1., '', '', 347, 'um', 1., 0., 0., 1.) + (0, 16., 3480., 'circle', 1., '', '', 348, 'um', 1., 0., 0., 1.) + (0, 48., 3480., 'circle', 1., '', '', 349, 'um', 1., 0., 0., 1.) + (0, 0., 3500., 'circle', 1., '', '', 350, 'um', 1., 0., 0., 1.) + (0, 32., 3500., 'circle', 1., '', '', 351, 'um', 1., 0., 0., 1.) + (0, 16., 3520., 'circle', 1., '', '', 352, 'um', 1., 0., 0., 1.) + (0, 48., 3520., 'circle', 1., '', '', 353, 'um', 1., 0., 0., 1.) + (0, 0., 3540., 'circle', 1., '', '', 354, 'um', 1., 0., 0., 1.) + (0, 32., 3540., 'circle', 1., '', '', 355, 'um', 1., 0., 0., 1.) + (0, 16., 3560., 'circle', 1., '', '', 356, 'um', 1., 0., 0., 1.) + (0, 48., 3560., 'circle', 1., '', '', 357, 'um', 1., 0., 0., 1.) + (0, 0., 3580., 'circle', 1., '', '', 358, 'um', 1., 0., 0., 1.) + (0, 32., 3580., 'circle', 1., '', '', 359, 'um', 1., 0., 0., 1.) + (0, 16., 3600., 'circle', 1., '', '', 360, 'um', 1., 0., 0., 1.) + (0, 48., 3600., 'circle', 1., '', '', 361, 'um', 1., 0., 0., 1.) + (0, 0., 3620., 'circle', 1., '', '', 362, 'um', 1., 0., 0., 1.) + (0, 32., 3620., 'circle', 1., '', '', 363, 'um', 1., 0., 0., 1.) + (0, 16., 3640., 'circle', 1., '', '', 364, 'um', 1., 0., 0., 1.) + (0, 48., 3640., 'circle', 1., '', '', 365, 'um', 1., 0., 0., 1.) + (0, 0., 3660., 'circle', 1., '', '', 366, 'um', 1., 0., 0., 1.) + (0, 32., 3660., 'circle', 1., '', '', 367, 'um', 1., 0., 0., 1.) + (0, 16., 3680., 'circle', 1., '', '', 368, 'um', 1., 0., 0., 1.) + (0, 48., 3680., 'circle', 1., '', '', 369, 'um', 1., 0., 0., 1.) + (0, 0., 3700., 'circle', 1., '', '', 370, 'um', 1., 0., 0., 1.) + (0, 32., 3700., 'circle', 1., '', '', 371, 'um', 1., 0., 0., 1.) + (0, 16., 3720., 'circle', 1., '', '', 372, 'um', 1., 0., 0., 1.) + (0, 48., 3720., 'circle', 1., '', '', 373, 'um', 1., 0., 0., 1.) + (0, 0., 3740., 'circle', 1., '', '', 374, 'um', 1., 0., 0., 1.) + (0, 32., 3740., 'circle', 1., '', '', 375, 'um', 1., 0., 0., 1.) + (0, 16., 3760., 'circle', 1., '', '', 376, 'um', 1., 0., 0., 1.) + (0, 48., 3760., 'circle', 1., '', '', 377, 'um', 1., 0., 0., 1.) + (0, 0., 3780., 'circle', 1., '', '', 378, 'um', 1., 0., 0., 1.) + (0, 32., 3780., 'circle', 1., '', '', 379, 'um', 1., 0., 0., 1.) + (0, 16., 3800., 'circle', 1., '', '', 380, 'um', 1., 0., 0., 1.) + (0, 48., 3800., 'circle', 1., '', '', 381, 'um', 1., 0., 0., 1.) + (0, 0., 3820., 'circle', 1., '', '', 382, 'um', 1., 0., 0., 1.) + (0, 32., 3820., 'circle', 1., '', '', 383, 'um', 1., 0., 0., 1.)]
    location [[ 16. 0.] + [ 48. 0.] + [ 0. 20.] + [ 32. 20.] + [ 16. 40.] + [ 48. 40.] + [ 0. 60.] + [ 32. 60.] + [ 16. 80.] + [ 48. 80.] + [ 0. 100.] + [ 32. 100.] + [ 16. 120.] + [ 48. 120.] + [ 0. 140.] + [ 32. 140.] + [ 16. 160.] + [ 48. 160.] + [ 0. 180.] + [ 32. 180.] + [ 16. 200.] + [ 48. 200.] + [ 0. 220.] + [ 32. 220.] + [ 16. 240.] + [ 48. 240.] + [ 0. 260.] + [ 32. 260.] + [ 16. 280.] + [ 48. 280.] + [ 0. 300.] + [ 32. 300.] + [ 16. 320.] + [ 48. 320.] + [ 0. 340.] + [ 32. 340.] + [ 16. 360.] + [ 48. 360.] + [ 0. 380.] + [ 32. 380.] + [ 16. 400.] + [ 48. 400.] + [ 0. 420.] + [ 32. 420.] + [ 16. 440.] + [ 48. 440.] + [ 0. 460.] + [ 32. 460.] + [ 16. 480.] + [ 48. 480.] + [ 0. 500.] + [ 32. 500.] + [ 16. 520.] + [ 48. 520.] + [ 0. 540.] + [ 32. 540.] + [ 16. 560.] + [ 48. 560.] + [ 0. 580.] + [ 32. 580.] + [ 16. 600.] + [ 48. 600.] + [ 0. 620.] + [ 32. 620.] + [ 16. 640.] + [ 48. 640.] + [ 0. 660.] + [ 32. 660.] + [ 16. 680.] + [ 48. 680.] + [ 0. 700.] + [ 32. 700.] + [ 16. 720.] + [ 48. 720.] + [ 0. 740.] + [ 32. 740.] + [ 16. 760.] + [ 48. 760.] + [ 0. 780.] + [ 32. 780.] + [ 16. 800.] + [ 48. 800.] + [ 0. 820.] + [ 32. 820.] + [ 16. 840.] + [ 48. 840.] + [ 0. 860.] + [ 32. 860.] + [ 16. 880.] + [ 48. 880.] + [ 0. 900.] + [ 32. 900.] + [ 16. 920.] + [ 48. 920.] + [ 0. 940.] + [ 32. 940.] + [ 16. 960.] + [ 48. 960.] + [ 0. 980.] + [ 32. 980.] + [ 16. 1000.] + [ 48. 1000.] + [ 0. 1020.] + [ 32. 1020.] + [ 16. 1040.] + [ 48. 1040.] + [ 0. 1060.] + [ 32. 1060.] + [ 16. 1080.] + [ 48. 1080.] + [ 0. 1100.] + [ 32. 1100.] + [ 16. 1120.] + [ 48. 1120.] + [ 0. 1140.] + [ 32. 1140.] + [ 16. 1160.] + [ 48. 1160.] + [ 0. 1180.] + [ 32. 1180.] + [ 16. 1200.] + [ 48. 1200.] + [ 0. 1220.] + [ 32. 1220.] + [ 16. 1240.] + [ 48. 1240.] + [ 0. 1260.] + [ 32. 1260.] + [ 16. 1280.] + [ 48. 1280.] + [ 0. 1300.] + [ 32. 1300.] + [ 16. 1320.] + [ 48. 1320.] + [ 0. 1340.] + [ 32. 1340.] + [ 16. 1360.] + [ 48. 1360.] + [ 0. 1380.] + [ 32. 1380.] + [ 16. 1400.] + [ 48. 1400.] + [ 0. 1420.] + [ 32. 1420.] + [ 16. 1440.] + [ 48. 1440.] + [ 0. 1460.] + [ 32. 1460.] + [ 16. 1480.] + [ 48. 1480.] + [ 0. 1500.] + [ 32. 1500.] + [ 16. 1520.] + [ 48. 1520.] + [ 0. 1540.] + [ 32. 1540.] + [ 16. 1560.] + [ 48. 1560.] + [ 0. 1580.] + [ 32. 1580.] + [ 16. 1600.] + [ 48. 1600.] + [ 0. 1620.] + [ 32. 1620.] + [ 16. 1640.] + [ 48. 1640.] + [ 0. 1660.] + [ 32. 1660.] + [ 16. 1680.] + [ 48. 1680.] + [ 0. 1700.] + [ 32. 1700.] + [ 16. 1720.] + [ 48. 1720.] + [ 0. 1740.] + [ 32. 1740.] + [ 16. 1760.] + [ 48. 1760.] + [ 0. 1780.] + [ 32. 1780.] + [ 16. 1800.] + [ 48. 1800.] + [ 0. 1820.] + [ 32. 1820.] + [ 16. 1840.] + [ 48. 1840.] + [ 0. 1860.] + [ 32. 1860.] + [ 16. 1880.] + [ 48. 1880.] + [ 0. 1900.] + [ 32. 1900.] + [ 16. 1920.] + [ 48. 1920.] + [ 0. 1940.] + [ 32. 1940.] + [ 16. 1960.] + [ 48. 1960.] + [ 0. 1980.] + [ 32. 1980.] + [ 16. 2000.] + [ 48. 2000.] + [ 0. 2020.] + [ 32. 2020.] + [ 16. 2040.] + [ 48. 2040.] + [ 0. 2060.] + [ 32. 2060.] + [ 16. 2080.] + [ 48. 2080.] + [ 0. 2100.] + [ 32. 2100.] + [ 16. 2120.] + [ 48. 2120.] + [ 0. 2140.] + [ 32. 2140.] + [ 16. 2160.] + [ 48. 2160.] + [ 0. 2180.] + [ 32. 2180.] + [ 16. 2200.] + [ 48. 2200.] + [ 0. 2220.] + [ 32. 2220.] + [ 16. 2240.] + [ 48. 2240.] + [ 0. 2260.] + [ 32. 2260.] + [ 16. 2280.] + [ 48. 2280.] + [ 0. 2300.] + [ 32. 2300.] + [ 16. 2320.] + [ 48. 2320.] + [ 0. 2340.] + [ 32. 2340.] + [ 16. 2360.] + [ 48. 2360.] + [ 0. 2380.] + [ 32. 2380.] + [ 16. 2400.] + [ 48. 2400.] + [ 0. 2420.] + [ 32. 2420.] + [ 16. 2440.] + [ 48. 2440.] + [ 0. 2460.] + [ 32. 2460.] + [ 16. 2480.] + [ 48. 2480.] + [ 0. 2500.] + [ 32. 2500.] + [ 16. 2520.] + [ 48. 2520.] + [ 0. 2540.] + [ 32. 2540.] + [ 16. 2560.] + [ 48. 2560.] + [ 0. 2580.] + [ 32. 2580.] + [ 16. 2600.] + [ 48. 2600.] + [ 0. 2620.] + [ 32. 2620.] + [ 16. 2640.] + [ 48. 2640.] + [ 0. 2660.] + [ 32. 2660.] + [ 16. 2680.] + [ 48. 2680.] + [ 0. 2700.] + [ 32. 2700.] + [ 16. 2720.] + [ 48. 2720.] + [ 0. 2740.] + [ 32. 2740.] + [ 16. 2760.] + [ 48. 2760.] + [ 0. 2780.] + [ 32. 2780.] + [ 16. 2800.] + [ 48. 2800.] + [ 0. 2820.] + [ 32. 2820.] + [ 16. 2840.] + [ 48. 2840.] + [ 0. 2860.] + [ 32. 2860.] + [ 16. 2880.] + [ 48. 2880.] + [ 0. 2900.] + [ 32. 2900.] + [ 16. 2920.] + [ 48. 2920.] + [ 0. 2940.] + [ 32. 2940.] + [ 16. 2960.] + [ 48. 2960.] + [ 0. 2980.] + [ 32. 2980.] + [ 16. 3000.] + [ 48. 3000.] + [ 0. 3020.] + [ 32. 3020.] + [ 16. 3040.] + [ 48. 3040.] + [ 0. 3060.] + [ 32. 3060.] + [ 16. 3080.] + [ 48. 3080.] + [ 0. 3100.] + [ 32. 3100.] + [ 16. 3120.] + [ 48. 3120.] + [ 0. 3140.] + [ 32. 3140.] + [ 16. 3160.] + [ 48. 3160.] + [ 0. 3180.] + [ 32. 3180.] + [ 16. 3200.] + [ 48. 3200.] + [ 0. 3220.] + [ 32. 3220.] + [ 16. 3240.] + [ 48. 3240.] + [ 0. 3260.] + [ 32. 3260.] + [ 16. 3280.] + [ 48. 3280.] + [ 0. 3300.] + [ 32. 3300.] + [ 16. 3320.] + [ 48. 3320.] + [ 0. 3340.] + [ 32. 3340.] + [ 16. 3360.] + [ 48. 3360.] + [ 0. 3380.] + [ 32. 3380.] + [ 16. 3400.] + [ 48. 3400.] + [ 0. 3420.] + [ 32. 3420.] + [ 16. 3440.] + [ 48. 3440.] + [ 0. 3460.] + [ 32. 3460.] + [ 16. 3480.] + [ 48. 3480.] + [ 0. 3500.] + [ 32. 3500.] + [ 16. 3520.] + [ 48. 3520.] + [ 0. 3540.] + [ 32. 3540.] + [ 16. 3560.] + [ 48. 3560.] + [ 0. 3580.] + [ 32. 3580.] + [ 16. 3600.] + [ 48. 3600.] + [ 0. 3620.] + [ 32. 3620.] + [ 16. 3640.] + [ 48. 3640.] + [ 0. 3660.] + [ 32. 3660.] + [ 16. 3680.] + [ 48. 3680.] + [ 0. 3700.] + [ 32. 3700.] + [ 16. 3720.] + [ 48. 3720.] + [ 0. 3740.] + [ 32. 3740.] + [ 16. 3760.] + [ 48. 3760.] + [ 0. 3780.] + [ 32. 3780.] + [ 16. 3800.] + [ 48. 3800.] + [ 0. 3820.] + [ 32. 3820.]]
    group [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
    inter_sample_shift [0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385 + 0. 0. 0.07692308 0.07692308 0.15384615 0.15384615 + 0.23076923 0.23076923 0.30769231 0.30769231 0.38461538 0.38461538 + 0.46153846 0.46153846 0.53846154 0.53846154 0.61538462 0.61538462 + 0.69230769 0.69230769 0.76923077 0.76923077 0.84615385 0.84615385]
+ + + +We can use the ``SortingAnalyzer`` to estimate spike locations and plot +them: + +.. code:: ipython3 + + # construct analyzers and compute spike locations + analyzer_hybrid_ignore_drift = si.create_sorting_analyzer(sorting_hybrid, recording_hybrid_ignore_drift) + analyzer_hybrid_ignore_drift.compute(["random_spikes", "templates"]) + analyzer_hybrid_ignore_drift.compute("spike_locations", method="grid_convolution") + + analyzer_hybrid_with_drift = si.create_sorting_analyzer(sorting_hybrid, recording_hybrid_with_drift) + analyzer_hybrid_with_drift.compute(["random_spikes", "templates"]) + analyzer_hybrid_with_drift.compute("spike_locations", method="grid_convolution") + + + +.. parsed-literal:: + + estimate_sparsity: 0%| | 0/1958 [00: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ы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�z5 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
&$i%K-C$5hV2;ZxbRFgql7!ECb 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%0DNI>`43rc-TL7e!hr1W$){+cAjwK4Ox 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⧁Y-*=g0oeMeH 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

mE4@fJUcDk0{1U=4BbIPuK5yTZAscPQ=_ zlc?XhI{pZ!OpaUi1Tz6vWMt$#xZV(fneT0X2?;NL_3g13=3!LtPz-Ha=d`eKl?A5F zmH|ltg(y2Mc|EP@q2JWCLofdt`L!mSLW$DZX9OG}E22+PUMjR$1t+?U!+2`vE+@%L zPQI4sc4T4=GI|WO9?|=idPmj~CpmOqzGPMnwkZ1icqTZyKmd_N`qutFjae{HcHoGx zh!RiiWI6lZ6MbyOx@RTP3xjN!CzIU6Ya>)VI`kTb?&86zW@Fs6EZ%E;=Qm4|LPlE- zTEEQnk#~Roi2rNCSfiJj*=iM^&qI}7W=UR~%jX|j^*Jgt5w)ON#+&bor>dGeEazin z`3Iy;LM^ujf_oxvrq|6UyVre|+k^y_&hLG3|$ zO+4yf;-O+AODA>=`f|-*`+mWplnG{abzBB0m4ve{V1&J^+G{!}Iexb|X1Ss+mG z(Nr5x$&Q}aX+Apz+Y}X!=W0i$6IXuqi46Yk1*L>Oy|HJ(LF$Yr8!y*4l#&r^tI(pA z;Eq%Fs(i0qKk?WMx4uT!l&$tdgAec zZ6&cSQV%iE{NDvAblzmTV|*FQ9X)S&nM9mG_b8r&iPV?Pu|M>I;f084}d4LR9(j^M1q!Z0{U2F{qT`z=nDXGJ}@MGh%M&K`j6wd2Veb5_Xw?T;>& zKO1g4yMV3#KhZt?ftK&a=eTNT8DGKc2?5xEHysMV;H_2>723pV(u6X^owrp*4~Vt2 zw18)j2yTOi0zQW&wX!6&%vndG^Qd6`2u>!}EOj^HPW0<BbzC<- zDGB&7Qrg<%JEbbbOb-ye3FtWps09Rq8~22S$iq9F(`-qRXIzE?&*LV(-be_o0e1*mcWfK*pkgI8iO(4r8}OyKFcHx|LC zk>CyB4r9&|{80yNP6YaJ1@VLgoDBmb;~&8ZR`?n`_RAu9dHFeTdR8dlPU(+J7EBtaF9t2gtod5aFmnj4$3o;%5=eHIj>BFz*cqr#D?l3Dc(a{Y2&JTWW{#!8o zgiMahdm>c$;E?R;W=wnqIKN47!Nb55LR{k6iyZ%ROB}JHJKuJg3eAiiX%QN_s$LnL zm;fO5fD^<(u&zsNn?Vk5)Ywf*!n6eM#$#NYqtg!Xpa=9FzeDY*yADGbJW#ve^$Gam zXYat^kJ^t*c;Hzrw4$64=p2l6e2?7n@|f@6Wv_tG<9Fb(xB6Y|QG)~Sztr(_>7aq-=U~bQ z4v3Ung=eNm=ND4rnd9Ts(VZg}x^OZSxONrbWB6RVg$M(Rt`xgkFgy@Dn!5&vaC^ZS zb+&Yw60eiy`zJt8&?+Ewf+g6dZ#(hpz)PApU{?^hI9CujS-%CHm{>Z{Bclro5!&x} zpjf`_;&E&EP**2-<}1#}$5&^-0qv3Bdf}xF#7LmW0pt}Z5ljS_h;Kf!FCCZ-y1?Wl zAtAYfV7Wo`Hhn<$9^6u4xMkMYrvOY2Ir9%T?AxAA$oK$D%aJnUmW5yS|FUy)5f@Q# zs}=(9M+HSioG;CADHa3i$^hJegTfakZ3zJc8`HJ;c_ZE6qZ?zM3>M{1-3&=U$nfpY zJ!8!;E&T&jrW?qJ1#n;B?yj@g#nE%XXn@Zkg`m^xpFf}CQHg}~E&-1c;m*NISQ}72 zfMLHB!SmxIoLL5o_eh9@c;OwA%F4I^T18;hH0VH*LT(QL6DXFosfF&`x#NDiS-W%W zZQ!w#05NK4bQE0zi1)N&mB6@QWo0FM@a)R!xF65(ueeHtt z7dWF1@Cqa3+5fkSSx$4olc`9Uw!G^hARNo1$O_M78vb!E}+2Mf4(3uT@v#f zOnzS->|ZeT5I{Bjutr!#Xm4*vJeJ|UV}FGgfIk63H3@EeWiS)DYN4K|#UL{YE&bZjL}kVgtI(=JEZGu3Z5e8xt54H^E6+H!&GN z)?r!5&4KlkQu37j^gyUL0Huat4*=45vZeMeWc~^AVue_F1qBm$FR)cjg5W`~VEXM1 z1|h~C)HJ|hYK22bRyH>CaBmk892L};!K4&k-cYlh!RdG~bAOkbs;Hqs1XIlJS6xg{ z&~{9o7bBi{zs^rD|{;*8P$ zVIl$^49h~IBou|14BG;0Ymhp^pzT?YR)_HUv}}9-cS=g3gDmJq7kdhbe-dZb8GCl9iIWHtW5IYgBgo zb#5*r^4S5(`ru9^6qHbJ``I_v{dNFfa#<(?GQ4-OuGB);2R*v}?E2aoLTgnch9coj z7W0&=>-mYX6p|$*e<$%h`+7x1^gt6bnrt>94LYP=8gy9V20{w-b>U0wh`IUz>=&6gKm5d1>J!vPXWboXu%`z?ps2E$W*6<+4BH}`u1?FwDj>&}Ht zFs4O178v)|-9Bcz$bcq`lr8B$DK~pS_WC2Yu>1Bibq$Rdf)tR}w_*IJmNlO|_R59N zfiwgV;SWEXBtq&HIo}^?gu}J>4eGXaK1!J7`yh1@5;lR0rr_qr4I zJYln(0R-?Y0W}1x&GR{NDy{1Ww7uNEEl?f21ut&674QjQD-7Z8S;oaa6Qm(!Lqker zegZ3{vw)$KG%U*sEpK3X;cvs%pEQ>rSKqjV{B~gC=TC${I07tKZ!v1f=7_6t?R4ar z4cJRur9nq}NWkRgg24mS{BiN|FGW(_+650rHGukdM|E^`6oJugo`5aAg0iyt_S`p^ zXce&20SuUBAhCsIK>&tY%5<{A9J&~C-9+fXhQ^u3*0l`{&l_;|ZcAEa#sQ@A5vG6V zf(dkci+}#y0>Vzeg_IgGJPbIG{>`-9YI8JL<9mDi+}?41QPFciFfoToK7URJOvpw6 zjUexg`QsQ6IS9AbT4x0Xv{NMHdjKWaZ%Ax~F0lRpHsy$0!aPReAVibc?Kn5T29q2~?LxYt?W+T}91M#>QDm1~(su84p0NR5kG_)WxdVSjvWA$z@;86yMdno_yO>sf)omS5_Y#N z%8QGN7Rvn2*LSO#maAdy^3~J8+-jdo{pbSy?%fR4-p8{QBFg83VzyTg#BpbAfPNc?HVc zw@?V?jXfNPRwt?D3`0ik{R5LXj2q{A%$%H-P~IUnQ&7O(y#Cgr{|7jBCz?Z+MBW7Q z0~2)RNxk6mo!$eRZNfVj9wnMb$kJ8Ze_sC7%FeF+*@I^f$ROoHDQWF>GZiAYUI~N- z2;o&tc}TGWwUJ)Y!M?jlPbf+oag>ifN$6h3q0VSzDM5a|XKoXg+AN2lk$$k~0^ zeNesQ{hi$M3Sx^7KxlXrH|DBFROrOTGoWyWh9tLSwa^5t%dZ1%x5MOq)}ie{YQKf@1q?YzL^igzPzqgnbGnF6 zC4%|24PRWz!os5H;64ir3JNJ2CZ=E*$2%d}7QXAQEO#V5(mn$v@E)0BDV`H1b_7Qf z4$^bZ7e4p`?COh?i570i7mP~pUk_O=s`{Ob?AWxHy@6b4TLmpoBU}^|hI4?8eR}`M zTMR}U1mXqIxxS;E=62kxFmAnhE1zf%ja4i?OycY4CA!*02X)n(^5sx9DqCx?zbw>Q z%#Iezs;|ETGZbqb5;qP??a&Cc)J*0u#+OAj!7!-+qM*bWS5xi_jSEu*+Ok`N8nFz~ z88R55xBm($MFprFlU3GnHF^Co8df)cJJf!sV>N~(Y;E)#%7#dB==F9yn-I|m(5h4w z!B6-;=JVQHS$%|z2`>W;2ftwj7=%uj=Z6|bMn3?X5G51|lo4qN@!)}fkDWadQU9P4 zw-I?>ISJ(*Ol=s(tAM-&4}F-c!mmolw;1C>fuvCBzGF%(gEWayM8Wk-ViL>H0D&GN z!aEpnP;Eg>di#wawp2*HtCk8lOJl{E;BjUFGrTj6UyXutlzI-nOX?rVb@L0m$ z^e#zaW_svp`A&hlmSp6~0!TRqQPB^Upn$paFTJ0KU8In!J~Cs&M}VFT+GrUiB_;Xx z5PF4T{n{v`56l?2?aWSqX(ibNSP(Vh{!>4ClSw8tFp9@UU$%DjRfa+m?j(};;jN%~ zg$xLoEt@?dAQjScaj9v{XmX|lq6?}JOmtAuKGxKbLKuUt9=;8EG){uR?HG#iclpz2 z0{a31R}urG7J;kX?}hORLnJH<#_wdc?QMdaONZ_vm^26pdC8fkw}M}wD7|0e-p4@v zH9FbRW5ZZ_dmk{*M>cW7^<2lN@_yQ}5U-)~D3%_2?x-)je-1pWL-G+`W6SISSYqUl zO|Bor#>Y!Tk?h-&fxHz8hsGUh{_1y~&~vAQb-&H@70o4W)o2K#k?91B3e^UDS-68! z)1=7GTxc?wSy)Vfzr%D^1N$ou*(5$VLDtdx{aX0Nyfma3U=KjlMH)arpaAoCxcGrh z{$q$r&_)2I5ulvOpg%zwe21iFXwTfBx(O z{t`Ai$!CC#MZi3?d8`BD2IeJ&i2FN)Gem_C$y`1*XVYE-mjVzyaJb+zIB3Cq5%v0K z2EYhjetu_=4-mX0^w`j$fh=fi^30+3F37XJO9(SLMH2Mq0seK64qn01_=_(FH_0B% zy&qu=8_%?`8}aJhhfW?qR{nq|;f4#k0z0k?7?$7BD`?EYR0S;>@U+RG>t5Z4Rt)L) z0pzeJK3412Kq;ff>sbEn+2HpC)|bK*crcv714`cuL7q<9nORs=K(T)2+d@i8Mom4y zUi<4!=K_s@z@cF6b{BAh%SvQ`yT}hJ{gPks~p1J`x zOzJmizI6k-He;GE}e=iTR0?YmTX20uQ z0kR#nzrVjQ*6t>SnTd4?JMwA3o)H3T6i8_gEc(b0r4qVecqiCaUI7hqr1o0CB(S~_ zovw3X=>B_X1BOW3K+3bRvB`&?0g811mIEcVZtgSD@3PRaFl=QtPBu2Ub&99P2VJh9 z;=pwJ0Gm5tF{n(}uHT~4V&fe>R>puFwAkh4<@@Us(Qzsd0s7TmJL?+`7UyeRg)XAe#+(B2bGa0e1+K zZS>!}{DnEFE9D>zUq%jDG@puD0x+W^_54BTHGW1ni$>z*LUUwMQ-2|6+#e*T(0 z$PG}%21CcS2W^nO;XBJAz=DL@oDTjKOPw#Ot1ybdDhTYRyQ zk=4cAR0mT4%@A(gefTmzkr`_+-WM(nDQjUh3!wB+znVNC1Cg`Cv>cKhlmt?k-$15A zB+N@oykTVp1=P12)DT$FL0fEaE8%AXK3HkP--igo12q@^l>e=!2`XZ)qOGM;e5v1LARH7BlqVnatQQZrV28ctA2h+C>;lAaUb?U}qW1?l%odcCEWz7;x8vU%l){H< zseF1<1R55JK?zM=-2zH#`d)4T)WMVTSpFafilGN8@OIV8oiQR^eSJk&S3X#?WCpgp zVUaBu?HRhmSABW(&ef$!>Wr`2gq`m0?zYY7!_^?rxG|e0nDKdVqaA+NtLf@?0}@P1 zODlo2#*{xb6b{W)RH%Dh_-%gHZ1}AL!nR`KeJHMsQa7$bZsjX7hJg(~>Nm|m(cfK2 z`Ob4+uR^4TqzZ{ok+Uhsg8?C{J=b1_c?iQ+4$j_07mRs8W`mX+)UW3Cc(VyjECL_3C_C{PK|+afIyicH+(!1~c71{x_%w@z8zY zt+$W8X=qx3>68YU^1fkxJjjbb#4o+s&1`|FtQVpHB)^q!AmBq&nU|II21XR53V3}4 z85i1X`0&s~R6C`E&~M+8Hoa*9x1|JG4yT5q+Juc~T!yt||q|F$q5Xn=I|x&w|MTn{E>K?FeRK^PTJOSF~ctDoM7m?w!-?IuV; z7=7vgF{TD&Dv*NX_V-_IGABVzPk_mY_ArsA1I$}3p@NB^6xLQOzfe>&HXeY92~Uzn zT%5XcvJZ0n>R{%zhF4pEpt5L%+MlKdDv00>(H}iMa28UM2dyBeQ$s}v5oLEEci8j{ z!%_)fThYiWqD}5^Ozzc@-570N9W6j~RhUvdz;=WC0iY^}t|lAi3b8lxzk73K*x|_bKuD%^YiXqMUd~Hg}wu77E~=(OQ6}EGKV=Ea6b;BgEAdb zFBODNgbhZUUAU`TX4HhN|3hS1Tv`g;NTvcayI6XeG;t_4q&z%?khdWru|B3z5n3Wv zdALe{#eS>dPED}|eXU*ztkIM^p;{MgyhRgX^|b{JSyTqya9wqt_s znZ?2Y%MQqP08Bm4Q6EF9=o@(>3NXY4X58tZN@0gdSp|ms##ui8{)q!fb)#!rj#gz!+n763D zkQoUKi2N)9@L)vcPwoHCR@QiHh_(@a#^%lH=N~Sno;`4a*%W-n4+$4;mP=O?$j?xS zu%kETP()9Y`SA zi|twUM4%k0vM@cZVHX}ip_!o=Ll(h6qwS|HWOcOBZ%q(@1_MerS$q2u3odFwr+bhj zpfPd=aCJEpO^`Nqzc@31wwMxJ3e6m>@_qoEHUQ|dPp4EQK*Vq!5IuB)IP~M;da+a~ z4h^!G!e8Qbrc`hRoDYQZ2iXYH8i1uIKLp8zD-|hpZ6qzA%Bq_WV*@ep8mvV>y`N|- zBCA3V;tZ9~zM4IU)`U5%=z!`Bt)pzBIdHD&O1mv8lM$^7DhZh9kKl`-6X?DFR3BYi zJvg52Pw?i|jK>X7V28JcvQK+yX;~>J-)2I35 zBn>ZDB~46dK-hyN8(G;PH@k4?3fb9lVO)bIUv*vsxdhoi0s!O`Rq^w9$Vck>`n~WN z>Od;MFGz)c1QupMb^0N)*Y{3n>nSYt(6qNf_4x&Of%sokVaJH$Oav6zl9Z>1TdMGp z5Q)i-9~y4Kt;W47OIS1MdPf5+!bj61lpxM+TEl`xn#Z4HLL#&RwOgI086Ri2I@b>_ zvf8Df>;b*Sc5(<5Ud{RWd1MLV|L}CyVO4EixIZ8bA`OB{m$Z~fDM%wJ-Hmier-Zbm zv~;I5h=7!Uh_pzDAfdE`6fXV4!&4+y8t!-CtUuUamZ7_bN*RQH|B3BKqu}rR zqr*|HaAa}57y4g-pAfwqG!WQ;TA;(4{^-RE7elu>Grelg{6TzrdSo68U^TX-L%29N z+U>qVu!g~HarJ%ZTm$UZkl}SW4AFJgz6n|4pv+PsK?)8P*tp@-Ad3ox$7~EP1;G5^l|lTv;(i;(vuDuXEf^;6lN^2PK-Uf&x8=Cdlgo zTZ5=|{u`XW2n|OjblQ(cx+g%7|6XM<*cFOZS_R5rlgWU_&PK)= zQFZtzZ$B`{LJA+a@8GC*5r*8*GepIQM~yHvjb6<s(g>XQWvavPYoYz<4UMWddy` zaE}Q7N0m=$&QT9g1@J?DlB)JW%1uz4*_VF*cXh2tyVfnke zn61Fs5&}*!;#NQb2YMV*;K8l-4mx;v(&4Sq`b2=ToCZ2JU{Y(K8#2KTv9)Cb^miY8 zW6ZQ26Dun=EgH}l(8gTlwe=@3z-gLVjgE`{ilX?il$t|j_gqWMjGF?4DCBvA4vi+n z7;0O{+CeKV3;Qv0xFW1EU@+_OYO_Xmy*KGDsjRes;(A7v0p3>ni31?U$ib@648nVC z=wS^^=6Hx44h@wp2I7X;9-dXh>p;S_@B_#v2TD7M)F@re^KQhif{I5Ps}qD+yiaf} zXe!@}1Of5b+q|#gY+qj2Uy6va0GySwuI`M<)DMKPsnlz_S~1rF{tSL7Gd-OWQJIZi zI#iYA+<;>H6_jggK)0+8B!WGOU<}6axNooQBPQ8$BUnsHNhILAA-43=r&k~Ujwv8} zA^0;KI5P9{3GwmHiW0}61mMslBqzIfg$T(&fr$;hs2L2#g)%~b0dEkL@CMz6uTNl$ zodb$x<_Od!Chm)-&2A&q1lSv(9e{?LZdK60z$z02Y#P!UgU$8{PA-nMMU8@U z)a8ijo>L-h$YT{9km^xu*=-ZQLVeK!6`bT3ZGcDMjRLI11FrYg;`Mm|=#Q9z&>f@5 zC1}Hj0dUkk5P>eX9Rtp#5^l9_q15)9X#CWZ|`$)#X?<%IQ4lf zh*ksb0aE$H3vLkAMbge7S`ebM$|d}-Iviof^7cJ}nhfeL=rrKq&=<*YL7AZdZHAk+ z;pX)1+qXf-yeg8>LNr`Z9=;3?Ht_Ji7-K*L&)9pSAn2wOK22cYaHT`LC8|aGkQ9V3 zbGYK${vF$;;JnX)3cs*E@ z^A1*^Y$6vH&KL(7pgW!4mQNRvTjB5PT-TNCB|mJjUKO(3zrPYnZU`RoKD3_DW4SAS ziJ`-S-8WHL4E8Z>*t@LyFLIiiXYB-_XW*-jAqb)lxQGXI0@ekIF#Nj|U`0|1*cn4n z4-X?X+}ai?2A_fW@=^TNHITS`eJM_Dm01%hb5HJ(olB+>G290Fen*o)FW!Ka1mLU9 zxfWiqU&r5!!72>TEHc|agaAR{~cj9ZN2uK12f}cv(MEdR;yAl6D3}5g zjH-qPLfi%BbaKI&4)F6}6C(Q++!k=Vh7j~AMqEQ92iOc59O!&;xf>u(n}7)+J+o-2 zj({Ql1Q-H}cB{L6KZ6~BJ5Zvra&SzVx*vH08VVM%uDf9VXi3Y;q$txT9wDt_fH**O zAcdplp)Y}l8nlny<|4kTs;ckb#{aEEaRnOdO}1HJ1V0hJg%-ZC_7QA%O6A z8})uT&?#U95yuR!o%PBIzga`of$bKt%Lsx%KYq9(qywrX95j*u>L(Pkm5ei~JZ2cM zH+@=j8HL48b1}DQG|bp@1bX2&i@R2^jp#$kn*P26I@P%P71%N1Q*#1?yXiyN)|3Pk zFhGl7Ps6lQgG%g-GrWAL3g(=;Zz8xDTrgzV18@+~c`)}ZWFn#@tQL3ko|i#I0m^1m znw{0=SRuP^z3kvl5zbFo_*ZKOIrE|Y0$a*fj#wA;H26bnA9oNE5X}{A$kyb2c3Rq3 zumrn~$uY-+9ImMNm5^EpI43XYWlO88*Wn22h#vw+nKIQ=3I+xS5TB5SYQPu%7HS-O zM^zJ(+|Phxbh{3_!R}=AE0T>8fB%QrxgE!_*lae+jr$vOUd(VQivYm$-Rr~z--?WV zqce)DtNT`WWz#)B?e~$eVjnIAi#k0_NE51K7WGjQtHQaHvt0;e0N?jYHshsFUSHG3 zRe7&&<6+nvJqW3K2LE8)u=~+4teVV+AB{*Is0NnSJi zAV5k+cJN)#QB}u_NBmkOJ&ZaTzjUhE`6mKV!biXewzSeX81M z7|zJXLL<&R+L_nO=;*jS*5g=frTmf&&v7@ZbTE zT6*E{7eUoY=Gs*>c$dbgAicMEjUg!?AouXH2Kj`cFcE^Lv+{LkxgPJ#N;w#m(Xh{% z@=+oy2?#(pg3f0_VcP9*TnnSdaNaCz#hO}to<%KoCz+Epn%XF$li-d5bYdTh%&QCy zK6Qmkw(NYsG4wP+U0YkzW%w4K2jUJwu|g+b1ryK1U1G|7%WNkiaz5P+koy&Yh4jCG z3a*3Sx4N3B{0mHyh*WEO9-esM(WEks;e7zY3iuTPIk^m21prvk!CwL_cyHVfT|-%X zD0|T}_#Q49=&3q7I(_`-G-w>`&@#i7)S{vRAs(ti5RE<|3S;;3{~$D8Ufz|gS8$N^ z{-+zaoc>3-!~ekIhKSJx_6MR+Z6ibhauRr~PewP0P(9E}zyodpCvAgw#vyV5wIUWR zf~Ua^xm;2AZES4Q2+p&=_%|Hz*|JU*dI#wC>0dv7Z3b<&Zf1M0Dfa#Z^vk0_J3_M~ ziH9G5tkQr^i-y3sAZ=}zsWU*Lpb}B0X0BvFRD^bL81e)B7Dl(A00l;;2W-%Y!8KF( zZg!p8g2{t-O2tJ>*EXplw;y>Ft>;N0Pv=Zm5qMfZ!C3qS!sFQS2Wj}6i`*aXiJr_! zIy={pS@OB8$~v?iY5wo)D{aA!{Mo)N9i@%nRvHr9}gzYEY!X!z-MLc9A3_X z-~tyYLUuEJS)V_Xe6PMWmIu3mkn68KC{N=7D}nt~0i5OVv{Vvup|49QSW13{a}L%BQg(Hwkmk%NB2M;@=)s;n>H z`F9uzXQ2j33$=ZH4x1{RHxBhLt}4@n-NH7QL8hP%q>o<85`q_FbaggxOdyQFR}@O#IL87?J6Xm#k`xCFh4svIXLN{j_!{FkosWI!Ns+g@bF|5 z)}`Uqvhu3PlAO0mNqbfF6~9(n|B_IqO~ViYO)gi zKU*eAQll-l=Sb?A3(^wyDv{+@wn0X zz6)3|oIrps4b>I@s+=&@_eIv3_2I*@H(#l*56Icq)*dD#@}wl&WYonnUma#&s~8$8 zfpQFPA&e=qulu+q_ZtvDXgFGu+qU4PK~=^HnkzICK=eZ8a@5?kW{so*K<}xqQ-MR$ z>+5@7l$Fd9&@?Rl;B7IK;s9li;WM-8!~tZe?i}Yxs0?~7f@qAA&O%?_4*u~Z){Dd*e5E=x9;d08Bx!( z6$i_wfFv|Tl~bEJqzT=$I3k6UNYo7^KAEQ*YbZCKfAnxygqhd!hv&I{#Cle+|7GUI zo@CrHxj}uhve<1|8e?=c8k2@catcw)qcUrfA`iCOi%u5mLOc_@!h+5M4M%(JP@nf**UECQ($kmP1_nm%h`M9J{E#^X`|Ucrxrdp%?YQ?k_WJ3S z5aV2cBL$c9$Cqa3RwQBt4mCaCgCNg?R^IC=LPV2(>m@!MF<=wq7HZta$a<=pG$L@J zc1vHc9y?4vYSrBHY*TVk7?Nd2NwJB_SIN-B{TibB6eFnVx>?AdKH~FT$147<1rSB% zx7o=;iw>y zG-WaD1tWlvz|Me@@U%BVUhML(I?@*Y2hh-@WP%IuL9iY6DrPUlWQqP}xi7!E-^VfM zf1WGxQNE6Mcy8dW7U!?^>}qMO8#K+UMB;GoPuFcz#EAKd(Q}BAJn{aJ5sVqkH+nMZ zwLZyfr6fXQ!u{!YHFXv_)DJL`dkSwQev86T+Q-u#>I$TJd#pls6WXk6zk7~tZwU_O z^c=CXyrh?x!#XW9x}cc>|7dl+qaT-xqNE~ZiLkuW9kcE}Cgh{E4-RdoTX+ev-ee4N z>h=7YmUMnp*dH=-CwH+-EMtMF+9mo8!O}Ls0n^Bgjyio;&M!ZYYi$I z#6JLK3D_tZkS-Ax2f%?j_gVX}`INs<^{A<;b~ewqwipj4)9c=ajuyrx@WYOKrSVP8 z2b6nm3OwD&CB#tzwybcFTmpDF?GFF8YyHa{i*4Lz?29KBb)KT z!NpAzu&2C%foBYy1kfEwATW<5(|zVeG$nszeSN*^goS76 ze7A!cDm)Mb!4?NA3XBe7cs&*cigI$J$6lN2q{f-_MWb7CWZ+{A=Qy{r{vd zX!QQeggzVbrJ>uk#c_RFuTD2x|AH8)_#svD5h}X>E;f||Y$l0oU~$?m2?1Lp2{<2) zBwMJfK;H#N2o_z$&N&T%)t`Rw0eIr@4Tw_&$qDe@fkTIPHx2DdBMNnpD(V)7A3y&g zC?I~PB;RFdW5~$KZLwWHzqwm}`zvJC%u8PWgF^)?w>eY?{Kub7_Vj3b9cfT?hjrIl zbXKXfiL|u559pvFh>NobZSzsM&67vp8LsfEm*~?^9#etyJ@1$jRI&`Sz}<*3akKa#<8hjtGmEkcw^3lK}${$oiZ{vgfQ794MF8Ni9y4<--Qf z=)T9d^}Sis)y(VAL$`it%PQbD&KqMb)Y;vBc;|_(+ZKc8YJ8JU^Bw~kJ4Kg8%J#1b z_27ZVMmwPx=In`GQQZ5d@z>HP0eelrD*kBUeG?KQO-Z@3@uMc8&1by+e8C&Hs(q#x z=H5l*v4HIt1jrhF2$))%C5_3DObdjC1tFvmYusLW5!66Lt?CZDwf==oMn#V*mI0lh z>#_9f40K%g!^;yd5U?;v82^*ytvaRzV~LKV(LhfhJ~THz=RiV<`iT&mb*e{mVYBI z)wptYaSc!Cs(E;n@Jl5Ky9izUq`p~U6d-^hiOSF4$>YT0hvw`In#;3vISEc^6sM1_0+Q7eJ1D_RTsg6^&KhIK2&Wi?j{9HpMqU(t2GbE}4rcKFkZaFY)w~iu za|O0K(gr;8*!iliEIQd9HlytYi@vbO4g)|Y0L=g-n+l5oWTqg_1@bOpZRO?yzz#fP z0Vo25^wJ2g4G2>JTpa}Ckj_^XPRIq{4uO%SRO1*TK0&BQ^jhQ~KbCIZeU`A{UrK#- zn~M6$J*X4G2iE6IaaT$Mv2HM#187+WxtUiJU`$PXWC7HT4xkB;Mc`%B*I5F#4kaDD zIS^wb^B|b=|6*IfZh1`sr&G2aU}tBy3PoohC?_>$GRPQ4F{md%&VK^9v?r(rdPfh3 zAPIx;Gr;h1Gi=I$m;dT9jk(b{bn5*e$wDX&8q87P#z2Td>KpK@Chgi__N+vV3-s3ktEC zFo(nS@ykIj*7jARGXZLYT+2`eMMZP?$bErC0ZIi-A9?6+pduj(uaiEqkuzoyFU&;*&qV0bbh}|?B$bkLr;ZKFLBRwU{U&JEk zcHAuyWr`c<#af2gD(Z)Livihi8OZmWI&@}4-?jfuNbI;AlBzbWgOAgbW76kzqT)Vh z*}6c?x>!)@)K6ZH5nL+H)=grw zF5Ug$7IvIg7XF*mMRZ7)%0=4jJ$s;BVvv01^qqpx0krCN900$bvupGcqw(+rspi}0 zw2QoYjS;LF5d4IeKqbaIKB-vXwCGnN7e4Hbdh5h-1Grd}JjOQMv z3i0+2rx;+kpX(MW4O#TZp_^L`!{##rNm@0vD)wESN&P)I>)&z zXGgpVUF9;i(m~0;YiiW$x_;>AO_=hf@v)wYx|N+>I8u=z@S4MBp_<1e)mGW$#v&*j9teD-O4@BK-kZa zK;^tc@gh1ofu2r;ARDeLRn6?O3W=1$%IHjcZ$6RRBEp1s@Y8+wGt?1#d);3*Cn7*F1^Bl4@^}`;GTfr}`%4HoKFIv5 zg7HY`9bOd(J~xK%S{{Cey8a)C54X9E1Ig6I0a$^C84=b%5(hQ_)*48Xb zazkvehv-2ii@<t02MbZlHK*a60T|E*xXJ5$;<6iXhXtmC}_cnK@ zL;d74SQ7mzn+d7fGC(#%P3f_Sj^3I>KuTh0YN~q`rt+%D4MjNN)9s7PXx{tNHS{rl z=lG-ricDMz$rV=HGo7?JtAQx*EuRhgSO}G{qj4;a5rz^mF|$p4|B^a{Z#is8m=O3R zo5W;>&rf)=5tB4&scB}R@uSo>A;auJV@S&F3t=ABxHy_RN2B*|o_N=@=;pd<&Jwa~ zY4p>F#zEE8dDWyFEFt{q@+2R-zV?o(!ebw|zDvC*9 zN-pm0T7Kz(tbu{ThS}^#nvIFl1k8J<(U|v|!D7!bsMGd^1+elDy}DA@CY{7b&7qEj zqIEriZfreE${xebaTLnE*{vf%GqJQRSgp!Gm0W-OxoYxse*Pz=QQSdFWQ$bqcUTWP9uP$9q`gbU_H`TH7?F*gHu^m{uIq$p# z0Gxu=w;SXjNjOp!&kNRb>O~;774hz}F z1ojEw(J;UOU=4zQX<^i2^&Rw|e(t}w8ou|;qy)NDScLv>HdvJ;bX5FW(f8TSwwLQQ zPq@=$q3MQaG##>tbuTcp$|4K%SRnT13W&WExN(VbagPBUg`hhE=tGac?c@l}ag8xb zv608!mPLQ6=L_jx&u_}9-ojH>QexuaAp}Vd=E=^K9W(;r2pTp089}Rj504pLOdkw$6clHK`(@%9}LQo^)DqOaua(9@mn#OIj>#FbGPf{4(v(uKM>^6X?9HkW%cCK20f?dPq+9H{hs=tez=Q>OdMhTDr5@ znMdS6Rs|cUqi>zp`I}I1%jGed1p`6gWVz&GIST=nZ2FW!crpXM#~fk$R}dG2aKfhV zeB617u`XUc^=&OByOfcqc?G9=TYyhDq>=YDcKT1Bu?o7eA6574U3`rn&#&>x@6Fz) zzc3(z8b(Zgs)$B3$m8V}$#cUAkA?~(j;ztu)trPfaT^M zu(W{zs>j0ZKOS%KJD;)!K_nj`a)H#6%u9OiUpuW!WQETdNeuWf6 zIjPXMvkt_d<;O9Aw)P}g_jA})Nj(Hyyia#J#7~7hxnJ|!GVSm8?YbNc_%&}g(!`2f z`;tF$|LSl&7M3sCo-4bZoN-eq^0;+?#7kc;A&8;$BgMtMDfV8mxIJ@Hm~Otk(?<;r zuZ9P{?a4eFPAo5Xd|BRQ`9FFrC56Y;{)1FX^<0NHcm~?Xo;KiYls!c-o z?5W?R;6JfuzIc(hpM6aNea=iJ1o?nq#2EDY%|V-x7)(7c3^`&L1+h!JJ>G!`ek(9C zry7Q-BqLIGC@;q|EP|`dJ2jBnM7~rF4LRGd&TM)7&R*77EIlTSW2h;0G~!vmI1FVI zHDFKYlLJ+Cdj;l!5kaLC4>;vp?9n zGgTfdy(GzkS24mb_6YBOq(=sK)j$jdvN=6aje!-I@f1qKax>%;KrB#Gz~W57G^<=F zmVr(*)nimDkCR80{pu%mZwKUk_d!>Ugoz3YzT(b#C33O^yu(5=Kx(Vo0dTzhrJtbp zmI%$U*g<%SvOLkEVk*s*uz7e%{dCAl!&H5ZJ5=E0V11baf3X6JB=Y~r`v)dQ@~4cE zd!u%ZX=sVhj?nVpH?qQj^9)FJkRoqTq3VNtb6suEm)}*yP)7dm3;44Ya2<)K^j%{R zP^Jfr`Cjm&*+5gQ-hU&^s}8uaHZXBfU~vIOS-l^`Mf=3AV^<7@aY#gPzepg!2v*_j z&_})neojyE-6IW_caN}9x=5+mM4X-TSOqlMoBur6hk#1>^v}Mit>%X{`^U4Pc`T48 z4u_O`R9@>Y+0Iu*RnI8{)5ZRHI+{VckQ%JDhn$<#!md*`)_@ku` zvQ!J7kwBH$Xzq)4_Hgb)Lj~6~S_kD08 zfNqjeO^-p2@CN4DtaTk7P0nR@^7oQ?HaQepxyXn0JNBc8Bkr#VYAd+d{+e+=y)QT- zZG>aO%>sk-27A_0n*3wgaZMhCHZsc2CJWrgyNdIsig~3uh`UaBd3~lV{kps*(@FPf z(PA#2L(KQEWX3_8+bD$O>xB6-DUpBdjQStk^$$p8ADI3ozZ=+Pe>LezIs((FAXm!ZcX;mriEK@c{!>Ez1 zP?SU!{m`bxx=)DuG;x&WPHAbn%TmW*wb7(B)~#>C%6t~);oHF&*jkE;Dy*q|a>V)* z4=%_Q2Cowsj>V5tOZ?AXEN_oI;cGuNeNQ*U8;vRv5kqPbD}L|!9btDnRXP}$y!QTw zwkr7TU9(^3aj?RA>D+Hob3S#bV!51M?8yqFCTss=N1HxdAXfZl>+zw?D`TjcCu{Qr z0@!k}UF7X5R7}l6xzj@E2J<%aqF|y)C4plb<3&V7-heT|t6wK*)~cB#1pHoJU1m+V zvGbf;-$b=M|G39|M$sY5YJT`^e{zdyFpr5#`Bd1Q#35gmZO~Q#w`21D1z8l6$m0YPGk9S z?f_GvNnZ6lt@(L%-ivG+?Wdm0jnh3l%iWTno8;Adjj_fUgj%G&a8o>;PUY$1lFNI< zsq~v#v>Jm!&U5Hj+?6A;dYGDq(8=X-iW~7+SlUQaipHXu>mWDbO0HyRlO(1pYyhS( zu+0?SIpu?$zZPsYH7iR$YT$BHKX7<{#+ty8luDucz~;HE=#j-AN&!V*9``@ABIQ@x zANIQ97U!4}S?-GJvS0*bt*&DA8WU(3wBj@kF`-K5mxL|8%)MyKk$P3`n8KZRjfTFJ zqe3s2+x5)%qgM1?AC-b)VJTnVlEC}0qFnpRq%O_4%$wU7jA9vO;TsLplhWNfdC?*+ zATU;k;`}RZytmoeC?X_8*LjfRcMnXU>8)(4awH=Q4UakuuV8PY;4gdH)6*QnE~BQe zyFdzS$$FL^8x2jgbd#(S{;@{2VGJGTx7jz1^~FZB#jEJW@4k~ljJh^_7y4e>>kLKt z@C1IR93zqAAO0qF{1K;~*&txx#E3s~{~G~mnTW579#1KCD*Y?j<#3eZIldU`eH>Y6 z7r*fHUhZgkfQQi$9^uT-R@S))zH84QS8E38Yvb$2zmf`GoyX|nUS9mV88R{V31O_r zTL=a<5zsaBl_~_Y<2sMY;S=iYKb+wqkn414o!`zkvDVqr9;ITN@F6C?F(hwi4M&LG zLu}_fNz7``ZT@O*3f-iIjw`p0{vlF2CZ^Mj$t@U!;VH32N>#qG;cNZQLWeM4dRtsk zFUj(TOjHf6SbNdUg{b>Z%p!krGEq%kudi}Z#qQ9R+}UXr9exooSX**Wkn^cCApzZ< zG||P=kXpJntrxLgb#IjmP8!xPmxmjfHX3x-ohTcA{_8#pMh*LGtG6qDM-;!*$j&Z& zrIbASEqCyzdtM7Qey%E;{b&a>&0rT5IrB#{g^Zt7qHd~+MaCUrG0Vr%8Q(WZm-C>|lH4{+qNH%MB7z@wq3TdOv@7dd_hg`Cj)%*o6Z(TG)#) zd_(8MA=_S1`Wcy?=`xs4le=WY+W$4R)-qOKbov`%eyH&7>#4e${vPVRDwPDeu=msk* zNoi?Jo8(VVNTlWu3gBR67Q!~P|K9w96JJ!E_8Ma?I-i=)~*!HU8KtHjz_Gb8E=2Jyo^@qMt z)#pl#$X{6BXGXm*e_8k~nPHvIsoTP&Q5Tm?-Vf>*ezWKM0|zGOjSb%ShFs&tDp`*! zM<2!|F~9~n!#}C+$9F+$Xk@fXac^5)25cELH~U9xNk=Py>@_tnzt*5*l_RXFL5WYL zAdr(Qv*J9(KFZucZwQ2Yk~Zs>&M|hz5Qid@-$S)QX3lSH35ma@o^%Qj692?e$G|78 zH=ky+6KDdU(!vy2h?TskIf-P__!O;q_6qc;YH9}kyc}7b{SwxLm$_XQaJ^~o)yWWwCw z5^r7``yEBTZO4o1rOxyG-0LNQw%YtKmO`*fmw^%8>%~aU-7Y)#@KlPF=EH9i&Qk^% zQg(KURbM~Ry2UX_eY~jEd$~1{ye_*d<&2$C$@)h(4pU8?s`th%5*Q9I_XI`1(p5?6 zvA%x`9o}oFSQ9-yoU6+FSZCe?waPwP5)zf3;1=`(?nYBvEC2EYEo5MIbjx*8L!qbE zV(_W7v;q}_9JN4c_z!JHhPfuj%=a7?tfw9>E^W;h2cd-46XcVekbBnfq#>hvr09(xlXfNZrHY}e%IpNfg7V)wO!Six?aDW z+Zgpn&+QmlWxs!`CKl3OHGyhvPXp% z_7tN&tYeaU`}-Er(I=_b9|QnCwq1eH0|C;dm6qb8lwq!os1!l>9BQZ?zZM7+^BU;* z8+fAs*z4@f){cb*P}_)7^I5mPpAK5K6v&{|WO-^+CJDp6DB}}W2vYP9f;~42Q_{P~ zb-(bXiO{i@8Ul=}UQob?)wV)2hysSsAwT6~Zgcw|?+ql9Z{*od-LJey7NvFg;Z>f_ zFJj`~J#noD8sDaz@ z6lRY#yq{e1xiE!ax>7qxhE+c4g%!idI#MAU+Rg^Ap`hSl&qywZeC*YfeNbVYQ?adz*Dt>y>41@f6+$u1mZ+1!+(5*q!Cavjx5*s63Ip`YxIr7K)@ z)7A0r>aruZa3G3Qm!&O{Wt|r62F{m9;!(*zcngYFUnh^M0OQw@&{d zeeoh@yKRG9h!l3F0O1(4Go`Zdxag>%#c4R6!okOxE?a?3UP#1FU+x)!OaDvg<4R#uyE3#U7bOy4(Wm|q^**w4Mbx<*=4kglGA1~2==ZihQx z@%^rg%a^AvF2NMMzj&Qz?WwvJNF#QGMF^;OiFtT940op1?0X_5Psnc*Hdu)@J`-O*eC+ zEpso>2?9aV2p0-Mv-V1#xD^<;CV8M4D*iJj%IqYLme7?Dot-QbK&dHTCgQxehbau7 z-X(N3sTVCp#CfSzntif<8eb58beu8Nc{2FGFr#u(UypWsqJhh}CP$VCC7);YDzMW@ zHj4)3p}N|h9y{$?>0ZWAGtAE$1{$+@~mT@m4M8js6Fo+EYkFbt)i=b zv|c+5a<(0D3?#v{1r>W&jvJ%Fk6~~y!wlBni6;Kc1skubiRZ`S2eQ^33S+d`z1?00 z*LOD!@`Myh{lDlP(w8ObvVKY?!KNI~a8Vl_SCH(54p-@P$a357 zocF=0`^9PU)va;`5_@PTs+R!AUwKW%Nzb)QQ(IxZIn4-_=PgTvM2pTWQPvXC7fn7b z%dd}Q6BN}G<5j*We28}BOJS6idtoOQayk<28}`keBa`E)LQA=(+xRzvmyd=R7(8W_ z+@1D&g&$u2tpq$J+qo0n0^kfjYPzcAQe!?0h|lr%_TGN3)kizn`G_(GMM=nl9G46) zS0>hG+n~2M0!Tk3^~#&&?=4nSWBA`kLwXLn_>fTw8qv0hZ|@XzT58!O`cHiyq!_ic zhHx?^raXQujg@wJKF*VISzm!iwEJ;9#bJKy<@QvGjGWvf!MQz5(8(yp{uKz~hu!X2 z49t?2s5gK2_uL|c`@OH16{MeGj-i-j*v^w=(r9V)z#rON)Bz$*LO$lWF~5IrKi8W5 z_iz1MG^NIZexGs2>e{5szqO+olQ9}u1>)zLpHbBgTeNZf&L&*f-ZGk-H}hoN&;=Eg zUM%}cpR2SbVA9_vjaB5{4gZeY{GqJ`U~}ObyuQh1yCW%=@|Nh&@qf~08)-Oi-`0?j zSsrec8>#EgpcjuvPT7J&!(;lC7P9<0$uRoW=GzJ@Xe0E{z36Mk$ta69BrSKJM#8nDu-4VeRCZQP{oMyKvZ2yT3w=&Dv24}B$1V1HWLBlm+g#j&Ex3@xikE9&%gfq zPavb%>nr-OL+e)A+6A!l+`gw`<~qxN#|QuIv~mKnKLkcT_hW9mABKP2x!hYZTj#?F zh$bhoC%(^s{u|+Y<)u~C;csv#@~Wym_vqLY5ATj=90-sWHa0G|TJQ7I5xwxLCDf@JZ`aJrM+@J52 zv z4))X6vn@7D-+zn&UZ*CM>T31pcw*F%476UewZ@teAGKHw1@9ckAEO~(-$avlJ zw9&}*W@yubyrddYd38tDql}xk!%M5aZ{^S#^VRMYWmqf9jgrut@Er`4SHEUqZ*P8R z>31ar-+Ir==Khi2c_T|I87>u9D|`PGxsl?4*ZQb=lP!*^?17=2X8ZGrV(pV8Ml3jhi5I2UEwc-Pe6}mj>mNYYhoBQ9? zm2zM18IuHIV0QEpnZ8un^e|qPefH!yRnb#JxBO>|*W9q^wQu{sJ;}(b4#VG=@H6L1 zqNKEge1A7`FL#ubt$-6DkX3vtr`U588$i>lFKfuvu4VY-^)b!E6s%WIRO8YMThDr)3e36S9>Qlo4*`od`p%yw zC(X`^)S~GhdY&HRQIVNuhUeL%y}bj&G+{y_6Hv6ZIxMgp;bf(t!^l^Z#DPWj_irH# zBo3?oTgB|Gu<;kPoZpJE$7?H`*5B#DIaU}eE51E_=gkLS)>hZGR`&U*PzrJ$5L8t( zIH0P~j&=mJ9G@?=u>x*9mFeSv4Ku{}ZE>K&jDUz2uG zU`s($6A^RsyCBc#GiPTEetu`W+2qLH70ge@1VAA$0`%nsco*G;{|)!nFiwLBZ_MAb z9RWh%(*x_CXH+SE{>L2S=1j!oR*$Lk1Iw?1nZ7QnbvdjrF@-U+RY}rnYkyd-u}mb< z$t^jhIz8gx6G&Gf9X6gtLr3qFEU9X9hcRZ)XzMRmqIh8Nr?!Co)?>Sh*yZj)*=KGp zn}x^(XIvp=4#wUmN=k1vvqN#~MushK-sAzY!QsP;jPHxW9-nRPxifCCM1K7>6af%E zj5XDAoigyL(G9k*)xLn4K1zyA8gc|MTp$Ksr5*l##WEM`2mjvdzU%4rx-C>2y=pFl zMQt~q{#8TkQqiU?(WLvBpDilrH3rN?toV(qp~?fJ!BU{}>onb`mkYWlS_YmcEnw}t z9m7A&QrN})nD&MXR zx}s2U=McrcpB0r&n6o>LD=DiTty`z7YOy2*k;Q5c+aC|Z4NsO`H>o#@YXQb{HOM9e zO;Q^F-EhHsy>ygHA->z*8h>zLljU9ZD)Ub0AXm!9gd9xcvNNNh$!B@+?3p{H%ETuo z(* z3lnz&D~|cRvI!FHj8@st08MDK95NlYNQrNLL7XOj86wOWn!06keDkiny9w>**BI%h zW`yp-HJGa+K#|4pc69_0hkwO@kJ(v&TN#F7I;gzH}NR0V}nWkvJ-B-Xz$sq<0$ z5!rv3n0Pc6FdY(RS%_zoi>z-_nBf9gWm9D^X)H^M{M? z#<%PxDEtt0xTAHosjN*&wf|$=&aghbKzJwT@XK2kGF(i6MS@{EefIv(8qMc9{SRvM z;6JuiZONi=D`Yb&Y>3!XG6r1GuaT0He9cydgHIUjr@J~G=4EGVf@^K7Oe7D}>>&h< zm%$g28jSfuR^AjohD@(%3++rLC~mS&J-@;XUgLdJfxf;(k3E{2$e_|(+7gC;zIPrT zJ-6{bDO&%URsrJ^*DlYHSr`~FAnVJkMbjt8-of{BQYlvdzH~S6X2n&06ak@Qh+Bk> zZx)=a^x~Z@W1>pFCTKOsPUs6ZeNc1qD?`UXATO+2Ov=dc_Dsk2 zCvX^)<o+)+!Iy@G0pg8oZf@qvX%d^0TH{W=q%a!?nNG^2sS$rTz)W$^kEHvqM?IhQf%%29 zXfOOA?NLo1Xs*N%q!L0{+2^W+>+A-R4067rp4>31hS_85InlfWp1(M1s?XKG%yt(> z9#T>?h6sy9Ce^Djaqd4yQv+9<#c?$&jnh8>1BF~Sz@dO~^#mMXdl~t@5~O_*w#aFZ7){hyTn> z#=m8A<;ft$xW#EP{{hZ^yPdBJ=X(hxrl$6XQM)gdmE*%yU>NboaL-o-nao7VhkK0$*CC~tI&2Z z`}4yT=-Wl##BQr>x8*-|f&^G-se+FGO&RKS>N&dgY(8JSU52L3?w^owk(8o`!cBq7 zz{szvVZki60D+u4c?1KsK|{a#mbvK%gVwV>Tn0IU{@AhMhhgg+(}ujdCz|ZQz`~s{-AX>0bf?`%IN(%LDlR>;i~5Qiw$#L`iY3>C0^@* ztq#nCDH+$mrd~V_FgZ+I-EFg4t{cYqd6EIeL-gJAyJmf4Ffz6DYpOF*zDzYt(hnJ%)8{mrhesmC#8?;)5osAXKcc3F5YnZw z;_g=8G85CFN4KntUb)WBVw^PfMMJ z?1q^)Wf_=-J+~XCVRjcX!UB^T5Bs*QoZQXT)jwwAMTXk!s7(VS^p@z>H8ML5jr7Oc^2)^*>9+k@4?_9P`Vs(D zpH@g28>yti?(LP045DWYB~>qe@b_RaqP#ShhcUEk|K}#Wo|}GW1V-AjM=+5Duz&k% zLk5QhMYq^{s}NU)Z^_2-oNcsyb^kl!pVPWb4?R`d2PUt#g#co;R*Pc)|9M|4Gb zK_5cU+WmfWASZvoY$MFRH;g|2horNPt8z`dFiJ~<(jlFKbVx{p($Xo?A>CafNSBCo ziGYN}p}V_96r`o31f=1+_k4fNZ_b=i*!z8-=Z>}3H9(lL+GnQMLhhNH*-ac z+zp-tn1nh0GjSt;J9=&S_9ittJK&X3fcOrL7ep;T+wX}Iw&}%Q`$(>2%vJt@bWq?m z-R1NPetqfjRa(s8Cj!KAb4pT1R7f$!#rBt7H2t@KpNk@+CmyfHk={q0n8#z=CL;1) z|MkDn%Gs6^;_zC#+#DqBGK4bhm`oz;?1#Q+S{ldY8j-o4<@AgWJ!EUcpfbCsv-yR} z^2QxxcnWwSXr2=^TlC;XfK)2*dqFa<1q5%B-X77Yn0yUE)-mdNKcym_$e{9MmoHJ` z5EF&NsigL*p4 ze>z%?%~`$B(gJaT=p3GyOk0@&D-Hj<#L>*H)AJ4RYI!U=ArGfiOh@od}O zCE;DZS5_lZgn5N6k&%=fY;?JSfv@nWyHnnW*EW*tsbeS*a*3Z(=GVQ>zf3im1c4aH z%%(1rR564y&tl{PD0#yjA-omb9tg}7&~}bSpTt4@nRbOSOseQ3p|Ilt&*caaQ~bqu zGtjG|sJ50BOWp~n-=w<>;ob;XNqIR~BmgD^H@%_zj21XO5MZ4lpv<{99Q5=Y?#k07 zT+LY>XFo~pfw<&TZ*K?>K|Kdf#@6}C>~w}3q0P^_>ce?gMZYssb3HllBW0H&<@~*G z28y>kCJDoq1y7&mzh!2R8p{f#4g$&p7dq!h`vspQ;341qC)oJAU zy2zmJT=eFQfBM^h$HhH_n$MbzS=Y##7NQ2syH_#U3{wrOvc8%{MZU((&EhR0GVz}Y z-Kmi1R~AHt6d$ZyrVna&_-Q3`Tg9zoR249sddVaJRK_frqgLrg0k<-RGIQ@iIa0Q1sVs?(|f|I^>T(krxXr&zDd3gbgt z?o?GZ`(1231H;gw|7;qVi+SJWK}qxR!9H=}<;Bh|4I(oJx&;_;^k1E$&UqLu-T{|PZ&&)=A*bwp{cfT0SuHsWy&&}(W z1(cNT{`d|kz%hujLj)m%=>=$k-p#iG#M0qsY2rrv1NYb}nUdO96Cz`@@IvtZTH4wY z!5|n)$7bWmkdTGrP4y1uZ0xD~9mXw<N2p)1M2yTEyRTNyLQQ<)RSi7N8LP0;7t< zy(WoqaC3s+15gSOE{{lphX7~@Y!!uO9|@6Y55E)qmfqXN6gJiho%Rk4_>c2gh%b&2 z3C44Ld<+R$zq&!IUI1~-fj6!X?Pfi?EK7Tq;a|ml$-^p?Nz9;V^RE{bMn6 z$wt*5MKVV?H}J{IBv_PWd))>9ZLeKLF3Mf|=080DGW-P~dN0Gd3rBZw2#+A+4Flw` z(2k_Pr9;s$%KV*hbiHE|VU=B2uERwb_3m@aI&mV*I9y$Y9ZFL|A%_Vp6rV2lq_yw+ zIXf$;Fo#=OSiQ&=S86+ug2;oo<}*5t>Vwa9N0j}8bXpi*o3sJjGf`j$g6xPcO zcAb@`O}ZN`wWr_-hGZ86S>hB<(0W&9LdkW{y|n=hS`fTGP;zr^J9DGd7hXv0~17v<9fP{1Bw{w^K2PK1LyA(GgGtYhYF)We7<(N z^EP|t*};BW=v*|jSY~M`8Uet%P};6|5;;~QV`Pc%N}J|3{@&^8JUhQWWo2WdTb?x` z^ID5od7LQ}TwEYy#D%lGd^OSX1R0lVrT6Tx{*y}K2tc7PgED=Bs|oqR=BuM@ zBriVlKOG&UnJU-<6gfifBoIASKw|vR`qJYh!c9i5%4UF2B|}IO*6xlRMkSW4g0O=) z6~E>SSYP*gWyUI8LdlT1*MM#$8LSay{g}mWM2Gjc2Yt{Fc!HW8X%q-g)YVap+hW7+ zGT%T{`v=GgMVXm?iG?GZKk<^4-A=&ds4tq9kMDk_%3F>hsH-4s2qL*2`f6+Yd47#%!OSQT-o~x<);i;P& z-!3|K`-;;NH~ECDtZB7wrD22A>z5CM-Q5*{Dth&YH{kk22WWhfPEL=Z3cGb)av)fo zo37nqy?0Mz!j_$tGnR?_YsjR=Z7;{TGET*m@Qe=wQjA=sPpypRG#*%D!Q`Rh@y`fE zX`#zqW8)<=4k{U&qvb{m&JEE*l-iwLJKonPF+l69R(!wx=_?WS-pl!VrLg$(Kh@eo zl%FhXS(%cC*(;_et2bCVjhp*v0&C2F{G@cWmPhDenSMdr=+ZU?L4At@!dyVnr|QgnrFQ|fUK+SuR>G&`}c?4gZ{tdAt519y77Qss|zSS0K3$$we5ir9*7mS0FazD zA35|5;k_YT0Ne$uK>Hi4YauTuBs>X28C_jcb{#eg%uuujAwS)fts<)CquAh;SCEfy z3<)E$5G<`Za#yr7q;{g2~->gb{YhWshkxvx1nxK!LSmOs^JA{{%d@_40QZ8{*9|PX*SQ?4g5lb_0 z^VYonNgM<)zeI>~0$(>GE)EFW3~X%gz}=*#p%H?AH%1OpD#d2)JuLq;s>ea9WX9rZd?1(%5{6|j0S<`2I z-)%>`J%yb%n%X}No%(YjL@wMH$U04A;I>o}P36=Zx4zHvY0Ty@M$)_>w2Frw8U6k8 zVZE@^LphxL5Y={bQw!8&{$J^-$8L`nnzGx$)XJC{28 zNJWm(d|Id>cMKxO?^sWL!a+qvMKFiP#Ca=yJ-I$9v(q!I89+il491_x$KiHv@h!QW z6FgXlbO}*FsBjdi;H*Ph+~0nBTqONE2W1%_GMhvzmxhEo|yPK z2c0f@g6Gu8)*ncTs3|ETXt<)Cz<$teHSAiAn|0co7ls`#b$VG(AZ7in3GpJW9x6)i zH0QOr?ftHRi(-Kn>W z)PC`M%qrt8UoHE0_v0Y^)f-zq@nG}hnYK)#(}$4{>0y`V?GAh{n|nMsJ(#)Fr3vr;}HY3l0TnWB-uRwbuMaqR@GA|vB7%K}5_*i*)y z5u%{8-@>^~8Bk4zRKXG27uvhpVfNU`>yNIA$Np$nMe8#KBdQZ7qQ+i@l1FUs#xp4G z>E)KLk5ohK?27TQ%obpVcwkpSVE7^*1$o%g;@VfVpNXi5S(ORq3ZEgjWy?jKgjz*G zo0#xf=7XTG1X;{?z=}~qfs8ttC#xAtqq_TdT_*704rG`OMMlT- zW*!qBZZY(j%Q*VKPiVOlOZ6Mn-5sIUHTp_DJ@+g(7d#2TzQ_^rFeEhPE(2QaQhK8F!o4EmGo@5uZNUhZHgVqm8bzlL+OT-Adi>^)8HnPhzMwkx)|p z_I2D=_+&HR?drm=C-`64lxf$&-r|^}m@kj*(ED2|Tv~ZdmUWTxLM8*CY@Tj`nC~hWzS^4X}1&a6ih=M0mc; zk=g%s37Kw$tv5dRpLmA9dfZ=7@V&vMr*pS1^=~H@3DO7A2Aaac-@Q*-Y%tJKG@&hL zde1fc*ux$T8Qqwc*-8kDm?aEbBva|-OR*P4?+?#6CLqIaV#{2V8naBB_WOYzx1=OL zOj$W81Zui>W=hGPBn>=Qi-)jpHlYAflo&Z_nXs5IUzX&$G=*(Ah)GTt0}~18U4#R! zgn%Id*+hs83+UQ__Lm3i2>73~J3D=aT+AOvkzA@9UXer7!dF{MYh4?XKu__#&BXF} zbEw{MKX=AH`LMf~XGg1?-Rcn6s^;5yK{O=0Z~YtwOkb@N!hm>j_(~8@G`?@Q&cyQQw_3n; zEqy2&6%YWEr;6SZ5HktVZrGG~qqO*LKq?61&a9^-#>k^l%&@Tby#=d=fNK%RaV&7( zQ7b7)z6J%8Vk{-M)0T$skGi)0rH&n-+aXvfpg*7ud&ndge7sQa912%56lNWezPSkj z#BkL>7%cF2t2m~BApnuvZ?#Jq>F7eh!VaOc!u}V0h*1K!da-bl1<;FyJ@+VqVNwXO zjRmuU-d&IUsVx?Eimv@O&-L0_C8f;m6&NKz zFtDjWx;HRik*vXAYi6|L{;m9taylV?URYI?*N-|+mz(C`-lS}FYN7UY$KIo{z?&o@ z=0-qrWkPb>{WX~2##Q_Kk{EK*r=$$(qxKIJqu#x}94)*hE+4v;AfnN7eIRIau`^;x zd*=Jme!omCi-VZW|lVz$U zkzro>Bi?1}#_=hMN0e;+O>0u&UtvYUjg4UfE1E#V?`7XCM|_RYx)wDCF3VS^cY5Y< zsc!yDd1_?+x&Ex1$kyzoqg05~ugQ%e&$2+-!<&lo1$=_s8vKaJ^VyMbW@W;>fz$Mu z7zRwwmrEwUj;`Nh=P?QC){}3X?^|!&dT>aZ|J!@C*6Wbjx?hisEE^Ee+HYL1#;42C zxwTO=Z?gLRO2_TMmZp5^B`qP*n-6@&dae$O7esZj(h3oOH@PP9{y2R?<}3bFz`BSv!|H&)2N(PN|w^h5Se#&X4$qovn3;KzBV$; zL9Cws(Z>~s?`D^qTvnwmV0%X(U)^67ZP{TGrFrXYT~;2;*Sr9Kp^4qh{A&dK9m&FH zCeba}d626^i;j*JH&9?)0Y8ELT$QY0vzIzTWQ_pYwSX<$>q^r+iPENXVQ2J!%^F*BwBPTJZTC61{CEZZW^bo0v(juBa#2==v zp+N_ECM+Br_jxUc@$cM8+2--zDXZ(I^0ar5t7|hKAp8o^dWR4O90_ZR;?wn}057i= zh-xjR6Zt{=o~weuu|1=!36-QHIq+;Ahu|idA3(@pE1ue2|cx&Go;Z z6V~z0V83ts(xz3KEH~Y11)(VT(6hb*BmIat`%o1ukh2bs*c~;s20i`cC(6tohW*vg z|A-$MDFuP}DWhTn-yXd(GaAWK-@=-0mJMoat5!U+Jm9@XR@QbDGd7=)pCo4SDEy2&i`Pt09615xQ9KcV6WM z7cTjwjKG4)U_C1OYy_x!t^YVP3vR!0`QNt{jC{-bXw^{-P;XAl+~R!=g8S(ZD~UnskfRUOcr7dNzR}197v@rCruMxiq}Lx!Twn6iv&CLXt<)ZBDLF zKadXy`^`>zwJ0cWxBJb$_Q?!u7ImMW_Yva^4BU>9bAiyRs|0#h8a{;vZ5!5Eas$54 zV`VdR$b6>lFU*R_ar73N7CR3Mn>XmmCms-&ppXP6IJU_;NSXa|qg)W7((w1Mw!7P} ztjl^`S~4ye{QOx?82{}Xj2zI4^4(rBpF|O}+I600;p?`Zg`BMqaSQUjtenG#|Ans@ z)Ar(ta<+o(mW~!o@BA)bSAQu%I`GOFXg&vCyVR=H%%Y?9)3C6I9K=cj6a=q-t^{82 z0o8tDU%7m%Dg0|aX$*%MEBlMZ%ck0A3K5CxP3sNQCk!YF-rget2CIiJ*;pGI1j)${ zn%-a%KV5Yr4A@RithJlx62$D3+;J1Q+4!BQ_*BW6JG<>hWWGLE)I=ItlB+qWoZIfI z;$P}MnKB9ILoKabccEmVEIDbtQtjxEf^i;!Hv<5yNt+yh`gbCKm>yzVye*7i-^69=f!shd{+Hc5 zJ%J~-DJw>eC#UJgvwfD^9=GeR%GpK5t)yw$aoVL?+iK)w0{&z|on7b8ony62ufE=% zR{3A6CKW!f?e6s<6|iRpN&P#kEa8q|+iCT@{J^!7SqWykS6GlE4$;ij z@R9^v9m;=FdBpg*@*SjF49=R+m~M_!T>X8{Oo@vnmmdWj?8mQUo`_#4fGrmdYUZa; zkpcn&z8F!+IDd^?4BUqVUt}1H@aE>`CMSD&pBmvsMpoLVW$nz0HDB1?7xVc8Sqtxs zTRdJE8I2^fzKyrwl9c3W@zvq=+*45cRMbECZu!$a5>o6C!9~sY@9+szx!yXBiKUX; zjApW-Lfe@XpY!xvvoY%Ll#f2Rr8AOHUM0}i@!EgSmXQ-75fp( zOiw$l_Tm7>>ABVn%De-;r7Ln0)B1RxELLwc>uOou9~9J?$3DjvKk6Lev+S|v(*Rnh z#EmH2wWAO{pk4qb^YpiN|Mu<1F(|6kAz?AlVM_pI4lfu zr?*5?+R(ENDi*1vMn*bwn}#U)HAfp)6xDz4KiRqIuaXG}_#m>VZHGEB!P)4RFmC&x z`|OL}GfVR+rgg|N=0}jXATYDhZ7YO>{Y;sb;g|nx-Zv6z5w{39nt)F>3<`%)I8?FW z_?8$-Wse`~i4p_+`0#MIWpzSI${TB!n|riQO$#-Sw?wqG?i~6I+^(ONx+6JoshbfX zXI4z{D>bJ--??#V#Fcy+t;3S z`1cE@ae=XX!K5Z!s0DN5>OEct#*XSS%fGt@w)YAWQX&A08Y&Q{>>14eIB01$)be*9jN3DTYOR=-0F@RkA3SG z%AhGv@!a_K>lGt~g<`lWrm zsZZWsXQofm1*qiSqpFH>ziaV*kp`o~P&6`|@)^b&eaUozbxILFhzEV@RQZr|6e9V5 z!n}f(-<@W)PXbu4RyMQcR3M>-+?9ayLV7JNLR|Fk_GrI+$6&X?jVG!$L}K#C>Ufh5 z%JhjXH>Grsj0E~8PRG_H`Zd;)5KacTLlhL0@!}WEh`<^|=5x8u;tk-D=^j6h2Z_Tk zz`%`WOCS*M5MvSw>?r~XTA^HcMe93RtpB-o3!E7NGn^FN3G4m^$*5nd9yuBaEy$DBexYv8y z_~X(e$J%QQ$_#zaOfzDxN2gCIGD$F(#%Y&6akGFKO}ku1zlA&@K4@<}wZUc4|NA52 zbx(3yPw^6`?0KJkA7HL;TKjQk=@hN5#Zp<9l=M>zU;}0J_6?STRF1olf=&0+%YY#} zp4?zdHSR@UbY_*ct2|i+<(h*sxqKAcY&N9a*{%Y`caqSN&w^UPx^^Vmt!U<5$FAH@ zjG^O}J#O*_kb1g9O00g_kIvjQuaDBj;0p`mi91s6)YsM0ib{hr1st4ru2tT=Yikdqdo9Z_3&O&F$9`Wt z{`g|nRslm(v$EDeaPW(^xrqTvW^6UD)lFIGngQ}?zk>Vg#$z9cu&|{R2Gp$iV`0Wf zm(mn2-;f@O6^lfH9fFY?cVN_3NKNiXK%N|u^ zw59$1#Xmkd?J9AM%z}0nOQmIY9*;6{`N%&AsecVf7fomL5woscV`ez$YY*OTZQ-xa zZT)>B@KZwEdFO-=XNS+#kRobQQB{5lqbHf4yZ}!;D2aJyzrHuRgNP#P;8X`dEd6co zZKfV_sSXt=@>c|l4=H3BlzfxqiRu!CFFt5*wt@W}9U zb9NH)^VECL{Da@9$@Vzx%^QHk;avO^>$^JNKl(dFkPM4(e_yMT(pnTW+j?;Gh1{ju z+8W${6ZTXset4%M)p=P8jn}fjWcg;09qmW$Ws>LO^}Cau!0s_sz1IN&FzrU=wfap+ zZ9F!fD=}5}^NHy3_>`u$?dI&hXqmzOa_y|Zcb{K!2yg;oB=DmNYrZuc835~!AW9_iOC!3Nd}=(;s_ zb(l%Tcan;OTm5fkN@p}oK#Z(}4MGLD&|%CHcyrDSC~O$-cSp{_t-85*iv%IsYiEb6 zkck@)k&5syA>v&D_1v}YatMU9q^w^d&7zO0ErVh2F~f%Le<4%tl>0V=5{Ts_G=2wn z;Ebn*AySd}*xrH)LIK$7PYo)CM+V2x113@kniF%4b}pLS<+HA>^!mD#Ag}UJ@t%9@ z`>{mDfd?JsKIz6=z6nS~VlHMlkqq%SbU=S^*qV|FIDzB`>?MTCsQ$xa&vanSc5 zs^q90xdD;9TG4j%5&n5Xh96-Wac^vj&CmZH0hJlZVf1007a&`E{z)bC8N^6#&Q&u* zes;5-z#Uju9&YCMAVxt>rmnl>`1tK%m>T(*^pJ&TG%z-MIQbkmFW;#7%7p+r=)1`1 z4)l*JKfdf_xpQ9 zL?9IBfq$`OV?nC`T2V!CzB=*Aro&@X&({&IP|%l zp27(h+)xfU4J}fTuqotr|LsBsrqs?3Ev;l^^yzM?_3D9BcO((geHmGTU8kJa=4-A^ z3tsLboFJ%Na~(U}_`n_Jcln4a@chlN^C|`w7QNrKk8XWDObVkxFX8`BkLN8m)TY7k z2!;-X@!1jkJS_hbz1tOD%y;@~&yb-)$3}3xJMEBcQlyST5rgpW(RskZ%RTYHtPI5@ zCy`7T#w5Vg<9dDJE&|@kY2W>2ClP`e+*~BXOp)A?QEhTRikRuJ@RC}M2cY|h(X}om zt}Iqjk+fc#K1I0kSglHC#Mp>zz@9KD$`oL%ULYHF#xG92ur>g3%=cZ@31%51iL?De zv`Y&w=ByAWWlP`n>=N=;2xOhNUad{a<{8seR#bxt&r{YXF^Mfe$n}31B zq-fZrK^{H#N-T$$%;TsjgA>LdTfa?)&3dmCV7<^z!jYp&dcx{}JmY_U}x+?G6b^x2ttDQFum|W2ckV zdTNYj($pLF$37O9vcLHKBb%aGGwb2C{=~4^#cXNtxJ=~91S8+Q3xTr`T<;7^LAZnT zE)M&w?QGj$<#vq4W&f=0;&*3LY03-;MK`maBcw&i!V`a5_X;&-st5ond6kK+2X{4m zL@qKYrDn@Qq5b%l;5gjqrv7cZ^9@9JugOMD6W{q&FSNZeA`Ki1kHA1FSJ#I3?|Wkc zuR_h<;;I|G==vN*f{D_@gMlf@z@Ro+#n>Sqmp8jp?0@48gQqiQMpiR4zqum3Ut3dT zz~J6`mm%6BvrmerM?&qXpd zbUwrf)z~EIvk!E>8I%Ihc)Cb=Rbu_TVL;#-0WJ#a#Oobxr5F_DBK^AFz-|ovGQ;BG zq=7KI0m9*^l*aIRk6nxgzqGRAVkA+wv&zIfjwMrmvxfEfhn-mUV$^Ke-r=A1s&l@E ztLSq0ar+7V%9SSjB_vTON6+_7_DcT77#hEo_0)ZEL9k1|{Rp#r4x^7lsuH!#5{uoj zRIdU5w9y+w0Ws@1v?vo36A=Du%994#MG9yVAx#SgVh)iU|? z-Zwa}q9Fm`5H$L^BUK7pTZoqL>`%2a%*X*)AnYbW1&<7{?O_@Y@LF`hG{Hi>H+taZ z&;M}eT~*N#p{KX4DI3`&^PVQGcw%da-F{9EO3@3c#DZRodKBvhKkxsom|-aZx|ih< z!Io&M^p3+-K@1F`A>Og4US2{cCku*@0Ss}g2(_E7t)>w<5s@^AXrZa)4Q@+NI*>$;7K`yRU32?LhqoYg^d`rZvqNb;(2uCU`#IebEP|`=_q@<*(8z7hV zCxo3Nk#HKmgjWiiQYbzs2nqPF3Q9^4A`k`(H$+eBbFwXKZOwupd|jQfwBEKpNMd@R zVQ8oXDRvstln=n)m$@~~8mCviGB7+`i@Pi3?s(1?=U_cHsXDdLr1R_IsC<;18bosPu_%c6XHeOxihCzF?c>rza&maM zKv;M^e8s;)^wk z{M;}iUW2WlRdEViRWUTh~;^gGN%Gc>JtS>%Y z8HhNv2i*Y~ZD>^$5B#6tQAW#wN2{WBTS_wcJs@JuSGsNCi-blOs7Ulff#VHFrqGqD zYQLu$6JtL5X7Iz(x0CtV%iQ4gAx2`3@s|QSGxRPuSI;1X8m&Eofc^}glAE&28wo}b zOWk-fic$H$eiS>d_E#?Y;ryZrtEm4P0iU<`@qA1A$7(BKQ4bC(T*`-6Q>wze_M{*( zf&u^v6?yk(_oQ82Fz(%xqDRpg&7j?leR7{PV*usBgY9+u7z#dc@&Xv@_i18s7>Xt; z%E9tk}8a*6ix(KDAYTBFyD=IEMP&;akYx26j$2V{W(A`k@ecydH9(s zb7dpBBiQCab2i=LyLC3ibv50{Zw1iWz3jkV?_F|Do%|Ww29P~ymp<72Gv`N0F_b_r zPwKQqn9pU>doaj;=6`T!`r8VG5L{$>0zlOU#4!NJMHmc(h0|aZATwL8pv-}8(p;jP zWNM3A`3e=@>DBFjyMuNh;{(uRF}K-gQo&ewjtD_j&}>6Q0s3jcDR6R#l3scm&<^T&U&Wg0kjWqi67k%{+`}Bfx{Nw&<0qy_{3ASUOJ%d%}1(K z$V1s-uJ?O8N78R=qwjOb-MtnU)Db|2a@!G0VQ^xTLv6+E^sBxDCfRp@%g#28gTR+> zp7?T>Fz@d*2?NyGxq0Ctgm+i&6$n$f!WdTri0T{tNmZq zAQS`+_6Q^-zTp@GDP}4Z4sh?*d+d?}xSow@sSEGtT*DF4?Uhv^&@!#(G#ZKky$q8+ zM5V&W$Oxq$IXOA>_0cpESwIj26dc6!1J-h~@Hq(_$OvRA9LmIxJRUn3q5@q`3zG$o zUvJn>A^Hz+uxpp;(<&0eeVhLUQ~HZ4X#-@<6iX&wSIw{LoY8MK41i!=BsYK+ZJIJ2jVyGS_ZeJ7~IQ^Zo4F-}chb%bLnJUZxYe&>CiizLb+CX+9po6Yo_TDPX`KzBdf7jdW^(d|j=d;SU zyFXWfq6L-#r$v8@u@sM!3<$PvIh9(UxpiJ=b1Nsob zI*N$EKwMbxVS_Feg1AY8V5WpmMg}^!PbO^vHI9o}a0nu-agh3`1dosRN+g8a7teV= z8sdQp(yPT7bi>(xe=*5p!h!IP02#n6^ycPfyYU9hVXJabUbI7ewO(6*7!rJAh_4T{ zC97^C&lmvcOk^M=SK0c2wt!q1wDn6n~&-&|t# z4-xsD8a;-}7tE_fFhclNmQZgfclWO7yzl-45YcvqaR|Kr8~^@4#H03EuNIb*PQQoA zV5+6~{JGh=3+Qs?jxWj!iYf|U|NIZ);{BnX1`4$de1jB%`U!7(_B1Ozxdc+l zhg+U3Bp@)3X5t;Kry_uf`BMvq6?%I7f98v?F5xL>n;Q&F{oi;w9>N%YaOwtmE=$#% zoXFgs(f<&3O|~Aa9?Jt)<2)9z({d;3)zuYC^9FTBocLg^^xMy30hFN~?UB9FdZ5b% zFOXa!gX|%f-rcP&IKA3`di8I)iNNCtJV1GHU1bP4-)&k@fg1U%e%Z78PsB1W&}q#7 zBICtpWGG!HslGC7NW5}h#g_tpSm=PchVK=OF<=ZdZd;on=KCH+7Egg8|?ENU#XRq_A$JKtXS7yqHER9 zLcbx%n)~~z096mN4ZCVejE~O|iqS8-hq(nn>Yx(CKJb_WhiIB5ujT7MK!ls}kq?ZH zBFb3+u3TMTLwCU>A(4I7hUvQPCL$M0IRI~zf`Y=!?g)Y!`?*9gupK))!-1h;WE9iz zDIBU9SD>{a%J?n0E)iu6H~;}YEA`$2J_m>c04yoM>Od~=G?4)cg4@)0zsz||Z4J#P zJKvy;ee9XepbUUCidSZ4tk!>YzKaW|{p{*=kh=GtOXmjZ>)aeXE+v{L(8_Tb)~jW9 z{Sf!peVtGh_{NSioX#PkFgKEDQj9 zB?M{G!qclDLe-F#mQ3;h;S7+KeM63ofsL(6-Z7Rn(r|MvT7k(G&rgqaz{$dz~DJFfXmCvgNDD?Am0mu6TF&@|G2xK3F=`%KcJr}@7|8qkw)hZ7BW#Fs4H6lg;S7dv zSqt#qc#nvq8mR$*h!{!(a4b3b{*Ss@UeEH7Z6~2-aN+Th<3NfYPU4FIV< z`~$7iWk5g6nwv8~lm^s$vb6LP&Yzi^gtpt8Cvcu=?!3aK z7XAFoRZkE0q?oWeRRzEm+%_MCobxV3+pfRiH7!8&hKJeJnTSK%^*!LtxcV+&pNulM$!qiE|Z4sgoi&?Vul2 zu(4rNhOQZ9F(LE6P6b}o_3|cG02A4OGRWkt+MBrW^0x+PHV%JIjSaWay z=XM&@UeH>)0EiDhXNa}StEx)O>%A$5(+J*N!sxe; z1c)c_UT*6JZcQ@68bWhno2c$*S?80t*kn>rb^+xFiWD%^Y4!CiE}BrC!U!J@(c$x> zYoWj!hpa$jfKTzm(4`2b;~?{i$N}B)^))mYA4W!~P%CCZ%X|D^XfL@}6slq(3p+bK zn5$s1?gAuY#7F`d(on6yfClaveE^DnP5tm8qH7sp8-PjQ4=uR&VD^{*K0LUb|NHNK z6baW|#Pzn<)`pcY*Fa(V)wKDhF{#|>^sCJjCg6QZ!0vZn)Tu$LfvNFUfULks3`e?2Vd(vxI)aWtRU+=dY}MF++F}vFRP4D z^+tp?$~1#r*_G4%@Y1FpYTsHHXbLDNMEm(v_($!PjcJ${%p$b(iFkl!?Lf zedwAE^xts|eTb3Ua}`4L<=oud06i>0Z-l1;&gaQV4KO>xw+P>$S>4Yx;JLwRC`k1d z%$Z8*;o9%Lw|~beJSS*y6Xti<(iQYE+Ju8Ch{1$mLda*{Mnrb zu%$!SOD7*o*#S=?Y#q5fme?#}uU(eY9Zk1Kzoe=%H`V)41MGO!HQbadWY z^L-A4b_CvQXd84gqc%6KpFw+@s8hBwf3TcfZWx)Jo&DpFQT~L}>4GPsz*NZ=SB5d* z;n9&@0fA1&eOeUgI2}cjl=rvZ`__Qt4YpIWJCU)my*np_6cnXuomhnv#ruwG|6YM@ z9}X+DTDkm=U5^)PYENO0mhx%l=4L+d_S*JXyJGgpNSE|q8n4Y_$pcRm)MB>|VBUZr z8TN~a=_f3yx*h7OLA(g{Yi}~^3(ZL^I9*_chXl84ZgX=+PEL+x%}i@U-JCrfw*YF? zEA*y=l4a4b!`rzIsxgXs#C2a*-DL=PUk z$<9Vl;1II5$1xDI#?JoS`5Q$j^}1PKRoUTq%;6CfnG^`KJgBAf^75eP=~{Mzr&wai zr6JA^bU@?)Eumf%XBIp6(g&<{&0NP|U-Bg%O1;P=1pi zPAqulvvYLU+dkmuwZtbS1!5+UjbHJkA$}YdmI%1-S|P6z5#R;29b!2Oe;)K2@c4ki zx#)9QnFY{=0_RMiqlIF;;q({MyQoB)j@TlZRN30`eWf;x#fdGQ$eOfTA!G#5^!1gKE6? zroiUl*<2LFlD>&p9nbwaSDA|k-&cG4Qz&K}TlG4AkBp5sol=AH2WCyf>CDx(DG7;$ zVz_-q!|8SDa0ua(ko0|4&sR`U(H@haA%g+g!uPMM^uLFTrAucBsi{YS>xl_(-HGOl z!%U+(OS7k2I{fh5)b8E8@ez0v7WNp3g9slbOv>TNgfpPh$&^i2Rs=E2t#^I^f&l)< z9y^YFDdXd6pl-Sw1Q*MQ{@1)Lty0n946^pK!*_sow~mO7wfxom90tnrdyPBTCVq(B zDp~(?E@c^vjxT!WN@-u z14t8$&Y(cir064gTvA>RI`l8K6?fVEt0H&A77-T ztwuh+88DZsn1yFZ%Rt%zn@1bCheJHU!NJzG`c+j`(_{DV-$z_UFrGvV+86y#sh}5N zW?%>dvFVCS19Z61&qGNCsAjEw39tn~sSkj8sG6XF2!2tdvJ6-G#v?HQ7EMKtSa#Xg z!gw)_TN(~yTdtfwvZ9I&k`fSPTUXEfJn@cr^eY@&Im9C|RFl&+4C4vqvc$n{#g#C&RvX z?wq*5Q4J?pPp<_3XvR9_cLXr#uCTxR_t%H zx6|!4e0U|{ub>@)an$?9fvKe$!(Mr6+6~lfFK58 zUw5Iylc|^$Y@%lI{gDcr*)w?XA*e7hGc#t!7A!6w83t@-^KB<-u ze&NL&L$+~b*;AW4FA%09coVnawS^@H$a`S73@;m;6OHaWa-a|d>nf9oh`zgv*{fGD zhyf}pw5{;)(Eyl`9}#~7cpbmv33=Fm+(k|?=0TW~0B{+Moi~jKzcbvsm2>t`tPAk! zwit5(tr+n@l5ZFl6oujsw!!E1ksnL%J)-b}?d7&35L_2XOHdI65uU*x z0N);TrV~3S+pT|h`DrprAW{&PbqKxA%ojbBa--)b!)Y=oXeFx<^$3R`;Nwyn8%3a{ z0RVan^wLG2KPxc0M?^@mX`dObgCgRv<*fC#Ltu1)~MJ)P>m;4ssBuh%d+dbw{u1E$Z?owI)iq!Px(dM*uyFi1=(u0mj70o9$meSZ5a9J(%WcSF|$$GGM2 zXY=)E^mt;L9buS6(@XF0^YkSC`&3u~pmQ>iv4IiczQBP#u{I#3`e%&P@GgJBH%ZE?_ug#hSGKv}oKQabI4sd**TNF;Bt5ul9b-Y|^y?oZN z->RYipZ&niwQ=qH7x@!>>7ZwmgkcE`kdBYrd;gR|GKnL---}TEN;lT~_c!O7h2PXI zzW2I0Cnx4ip0G9eyA(<;;7A-z!*w{L69Bp&3OsR^`cq>P&&5o6Pz%6T5q>b3qU2}I z!BvJBAzU31AV#}%bgi(yKZG}1Lqmh~$v^BQ=2-$#((nD6J6fmGP(8xIUkDabI2k7E z98K;bKL|;O>7V%3|B-anVO8#1^VpblhzQbQAS!~Sk`mG-Dkvo)f`FuiC>+U4s@bU7oMbTM9W-qb`xee(rr<2Ko}PD?O*fkoSZmVU;o=%d#N?(}x9})NS=3X+aPQt{eU`^O zck-OhK2--~3E>_X3j?k7ChD;gOg}0(OGrMTwnF#@NF)ce#gJ0RXWNtEjH07=3)IgW z?&Wh5WeghW{rPw8rM$HCp8w@D$=|;HTKAas(!_OYmg^hUtR8M_+|ugrK)~Vj!N&l~ zAQg^?U_xi3uBv(k1a;fv8Bu!(u@KPqugpk_%#WzwP<2N<1!x{PC3I~AoR8cU5dyEQEMSYYq~tDecl;&T zdymrv-JFzLn_KMw?;|i>~ew7B_ zO!8C7+rYzhzQ0G9LeE4f@SC{o`=po6i53d0O9vhb!fmxM-X0Vg@0!r_**1n==;aex z#w+P<)-X|^6>R-sc;$-w=er;zd;b-T@*4Ea}5Z!r3Gsj=$l^8|v-6 zzg-{?KOYrPBauy8 zohiS}=+^y?KB2_CVp|^dY$>80v_|VR5Y>zLcxAu|xj_CD!>aJ}cIKaSqwQ8^9Pv&d zcWwcr0PT9AI(bsVZ@kBHbdAN6S5Cz<6=LfWIR3TKA zPxrJH&6L&W-y(VQB7lD^55L)Ju$mmfE0Q3_P!c7xE&uk|8~%g$IfQNV!QaDFqq@dJ z*M24>De#MIzW3V4cveMAO9taXE$`Zpj!G`bAoMG<<=n%+mk6zaoBNFdEoSPn6mo<1$I6Z;>QmA*EAeTF+O_PBOklUQZqChe8W%iH5Gr^m8}hT_uoY`t1mqm z8byx>ZFm>nPXfq*ct+_0kAc<1uUr1%e1YJRv?L-Hhc^yT#K+h7TSG(k^%pQXiaI({ zoYbawoRzM;qf@Bj-(xW{)|L);S^AE&gaj69{{IeK$Od_f7DlrdCkd=encO^2?R)uQ z{@~(iCN7`k_eZ~9*ejuQA>tc9FhyHgY1i@RWHwRaz2#k&;|@#Ld0$tVeMmdp zCt$fZTf4u@at{Wzm7P8_efmVv>(=XsD1_PNWljjp08V&c2$MLvpA&dL>!U-tdE0Yb z9@F!dIK<#+2nC0PdI0b}*qW+trY0S3%%A^n(TNxefZ&WpI1kVblTlH5C?zKX8xyE( zBtF`4%dyouZu?BIRLggU?edBtYjR4;a?DtkA3R|C3iciA*?wscGT?tAf?E%9Is6Bg zYfom+v?z-c&DWwm8g0-R!}!qpbE;zZbcJ`-et!;N`|jOdh>Dt;VPmHpi}eVi$jVz zTj-N;w_5WP?Rx)7uC1xD@#}~C?Ha5%psSmlnQ_ zykZOoOzedv`7fhXG#0{00W%FsG&6>rpzEhyc>;-nh-%8v zN%`XzN1*9Rk1qcf@Avt~2JV8P9&*7;{nd^|3$nkBVEge02 z6f#QMAae*?>f#Qu^37j4Q@Fl@@Qu9w8r6)wE?Ba4>C$!4C+NxGg49^w-Gfc)9!TSz zpw(BIUm0k{?)0$}RMgb)p5mUGcNYeOi-T1Ia5Jc?9D|u{iZLz!%xQKk9DgK1(zc&Q zg5ZFG8s6lNMDiZ6PX~79@BDY3!uh&3)A_fMFj2j6oYOUle)l-ME0qRU zNWOuu-w(F5p&^JE7g(SA5(NAMUb!A!`+wNY${8Jea3!wYo(df9hv9PjLWPiuKgEwf zJ?z^Fz=^RLiF$eh7UYbhhizM}YiOwIdkBdqpvQuEPmA>$K*->PE_J#k7jib~T|!M= zA_td``i+ldxD?v1Ois~dppOA!m{`N_5{!`y5yYHDh#!o|A1Wkp4O)W^>{ z??KldfI3`v)!06O*0d`my$)+J>v(Z;j1>fr3A{^ax*EXX=<)nGshawE-=VsJW9y3C zA(31TYxfXK{B9rH-ow^&13?@{*Ri5j!6Iw!I-pNSLZ(uJxbVa z;sk);m1lcXce4SY5SR)0G3?rT@Nlr&Jc9#A;2ibyH?Ln`X5R_Hv&!fkAL1&*Pp9`K z20e`uZue?3y*(sPss4^?=I^t`v@Mi^znKMNIFVmT`(OAGl{o4}D)w-GsY@vCu@agS z`FGpj_VGKfXTH|XX29l!P$1M39zepz z7=0wM-XziX{;tYO85Y*#8TzIE=%@iNkMboPmzIX~`mHw10*zaPxaE~_eh<%%mBG+k zgs}yWaDV>~4K1Eq@XOWtvX;V8U07XTZ(Q!h z)%h{Ae`S`<==!s^u@e_ss}rPa3(s6#4<{F#iVw_gXtT4F z+`idz`QtRd{`f(;5Wz>IWbj;LhD#MG$H2j0uXy&q3R+Rb!K32Hw8Iy5qUmyG1{3=;V!$=6z5s(2bsR z+j0i5+@Y~MYWgTv-p@?r-!4!Hpl|#7J&^ID`PsRj!ZK@1n|L6eQ=kw*SWX%9sr2tr zjMc5J@a2bIq|n@QXX@rLE2}On4ftks?oE>^p;HJ5(84P&FYiY`s9&nraKrLm)WuAy z%q2=fGVfDr_tpy0HftaU8mCu5A{?Dr^s&dw6XKL!z(o<762frCcW6_c5y6 zd(sdqTs7Yy-T+%BDA0qiTlaQ5sjO^G8&Z7M3_o+Lb{vHyqFt1c6n^itJNu|U&3IehAkGT!Di|J|V+8L^ zN{Z9ub^ADhqFpd%g0ZTZGq?Qeh7yX3ZW@a``g9Y_Hh+nRgp03*Y3 zs-2X-lAUZL~W72EwSvS#g zU}PHVH_l}3`&Q@%(ZGzaPbZ$_`iil6ot(=qzuu9F;B&*B|I%mUHLSGTnEw3!)Sx=fv?}l%i0G$YbTk;ISfDje5LM(bS!5>+1s}Bi@+5 z&N~$v9Q@6 z`Ygnr(M8gJh?JC*pFa%!Ub?q3RA-dvMKUo#HDE$CnxKctmWCqe{QO>i3TE5co|WXh z_9zWb_}jRkW}8Ol<{7V;(f6<;lkl8OqUvcUf#~{rGt$eK7|>*3TnN+}|NXrO9-R~y z*Y|uOAL3Eow{ozB^Ys+BzRRxe9~3b{w(@~-&lxUJfaC!oaj-GqY}KS4yfZ+D$&en? zfpnVN^=<5apG`Y|9$N05uSp6EJ*7-R@l5b3!%4*gREgUU$pbT;M6X5?f)_?aukB;qYP2`{XXc0~lcwi$+8YGIQ1QZ-JG2Qa4m)evwcRU@4LWcVq~c(XK;iSAxWU zA>i97&Pg6dzfer-ahYF~j+pH24N^@!Fyllz(|KP~PMNgaLfgq~Xt*pvdhdjtanR;M zXn)bY3s3*GoYcwZcxhb6X7V!wDZ1|8Zkzr(pZc%k5!?vW)HB(6)+K+e{a)=y%%;`Y z^lIKY9Pd2i*}Ug_8XGTPGgLUtG@uW;;Pq>2=e25+{9Kc3|FN?>!EGrU!ZtVm0fI?= zB;N?wbx?odXEOVvEp?&L7cGX*6}7zkr1Mcx!LUH%Q-)>}gSv zo!LEf)oRa*@gp7Q>2-3xJ|&|#!GDls?dcgjX+Iv1w~u$^CLUyG=SSD&j^2uhEBN-> zs2M9QaQ)N7=40LS@6yixOC~>cGi9`B;SpG0zxrrhT<@AMCpDaLsKwr#lR~jaFtdtALQdHmlRzSCDd?BatK51p7;B#a*77Gx zL93nYt$AL4t_S0d)mp>S@6@DYoGqV&5+;CXdLAVg@mo&4bwVr!#`JhO3KlO}`J z!8gCyUGuD2JExDXUkf>l z9amL(Ju=^5h!8(Iv-?3{@f-uMo?>^p*IIILK_d1*itF&UA zNEGl#p6&Rr?abC;K+?0WbK3-2E7ddqTt=f8xD`c!0*4`T0K1;Zh@M>R!NRaQ6cU6cM;`)J`Cg9&{{aQ z(zDNoy(G)GN~F)7rA~r5keGSe*$Fxdl$@<)=`|Hydc>K<;4D=WEyN3;l#D^zUJV}b z`(^{U(F8;Hs~+OjM#)CV45R47(rqzVjR;H&BaJ#RHn?p37g!qZ3-X3A?SfCPsjepG zcHrs0eKDFZN)eQ%v)LI&jk$&}8wSHK2?q!|Efs&Y^0G2mXSXXT9R~Uv7skD_j1}08o`rDB%gMb# zBMy&A`UkJqTt0s-OWyPj)}X06#HD0{o)T~j4jmhq2yI!{zvri1n zmw$h@C2Z8-a34K-ue&~Ccy$;1W8&n6kL~faU;sH-EJJ)B;Oz@eb|$4Xov<{`AX zLF304cs{@;z-UKrQ*x*yGbA|p8!Xe&M-xk|6t7)lhuCd5*_o;`f|d+~6dZD2>&>ST zWT-(h@T>YN13Y*|&Y#S#c3buDcGuKg$<_;mV}Q9y%;6pB0a`M$*JXF$VM+U$4hJCf z6+Ru1#avumDt+g~lIsOV#O}66eA-9sPC!KBQF+ z51V7obFpLaybtHKw7%uuY^&|f16?`1<2P^K3~2c`I1t3&{n(Nob%2Oj#MUNeas8?^ zO&Qoct3CE#$GRaoiiNSH%X%oeBnQ`@f4wXq!F80HnQg-E1)F;%OX0K_DFSffTrNgm zd6t#u{K>0GPPk_3S?c9ED)SgBUm^=KUc~0c(SP_}8Az z1kati?_tCUE9&TovdY8^)NoF+u~q+wpC*_y5P%mgx~r?0_Ju|y-+uVlHbbXFs4mw5fuA8}9Qye(IJkqD6O}+#F>! zCe6BakcdNgY=0kAdZLMf-NdMbagunvE4>`>8@z&A`xOYeawx*V>&S!p(I(J5kFic= z5BH<(%_Q?KJ9j?AT8tkl#b-$*uX_*-B{kvlu;?yyC(C<9zCOz8tCjik>#xBY@BN1| zOd4M&zQ3pLo_%u2mvS$tn9ecNU#AKmrMhEx^z3|SlUXsA*F}npzXA~DC;M!ya3ArN z&TIGHI!%4}HTuH(xK% zn?gc<*;s2gc2=o;4;=qC*5)$n@WaD{gz<4k43y;$j12`1zp_b*1SGG+s@JBn|MkjO z{cKc;`mH0N?|M&joRgB$SkGDYFEVj!qRyv77I|A(7)gCni@=4sR*9YwdI#R7$tS#% zsZ!wOJ|b_CRe@&edcF(?x7>;%9Y)y}+haAfa5?)oQdl|U9!++J!MX>$e)#n{H`Krn zim7-)AZFX(1;;5!%d7VmUQ}s+w*G#RZkOdtP|hF~t`iv^)YR12ALlnaun)7O3>)2- zRuDd^_xFmo4rgwXAyQ|{`a zz0b^6R>vNKH70W5@s2<+AawPM5|hnI{!V9cum-}PX;JDNRhV63;MQBRpi>%$X`v5} zqsPbFTjnbEC#hQAK4JSc*nQW()qlwcu2;X}$B|b5@%i!GYjKLDuA3U=z1q&y|%@aU6STmJ?NPf(rx+l;_wTb;9y(qVAWEiTtfv)3)k^6TX4$ zkEiuMRDXeE!Zrq-(<^CBdrULJ41&oHuyTAh!-^lyoW}UIWy$JZ=H0vyf%T<5oBvxK zRSnx)2+PD10}@$jX)IV_Y)RAn4YB4aqJ9ki;!^YPoMcUVVZ7&+foTstw}7_Qu(eIJ zXavqVq|H>p;ego$BC+)?&1q)`%Icq5?H$maGbIM#*}%vN3ff=1sXN6t$Wn9Z2C)b_ z5zX;~tCJW3DZrfR%7VJcL7JHcnWx^6<aT8@;lM?9EyvljDoOcpe)0cT&|?>^+Xagt z9}FtF2rb!h|Ch@8$^bIBvzMIbu7pA}*!LBds;&U@*Z=5w5LU9iwQ2Un18isdw6>O3 z8ryOB;2`b%Z)2lUY$x4fLzP7VWx<1E-!#cuE1Vj|f6(#!p?)kmce%sN#=(-8hx2r2tdQ+mDWimA z`pVCD=!N;are+;Yx=7-!iSi*0p@o z;EI8uUXQ%POs;z~wW=cYzgu-Z*a!TicQpiiz&J1^st|D;cBSVGpJJ6_$7-s5UcZxp zA*7e1;e&q!Zm^H8OKy+g6kd)?zS{$6*=U;awGw%>c8zZ-g7lc^Nz+qUwi#3ZvC zujvf1egg>8lOb^jlLOA`{rd|tfn!&#axofv_D) z6cK?j48HC9yuYSpmEOnvG>d=5A(xYnTpYuw%SPSNlxi{0ZC?Fkw)I~~Giag_91 z2)iwD4WE6xjG?;a-rg|a#Vc289W~Wi`CVnLN~!`W8AMVpeDS+71!vhqy+Jih^%!Mk*lmDFN8Fk~_F_sYWiPWM z<~D&&V7fsF$jM3u^Gv!kM-Z|^A1bd zMr=^{X`&BiOG>7M7K=`OR=@a_m*adj{Y6;O>I><@JR3m{CU| zd2@@E$RZUMOr#pse|%8BJ{&zLK;K#Hw5T@j_Gk8W7HE@xfe^B`G+BqeY0$$%)JA6N1zyDc zY`XI7cSj_14EO+qE`V1@Ag??>69a={N8=lhsm{tUrP!6JlJ&@8JIZ`3)(`o2SxtT# zVaeKph^=4T7yI%uPkAr%8j7*uAK&19g8?Q>zw{?6j^_7zbj|1^?jbutUC&Y4U5SH( zh5w@*5%htWXo8rBz4e^+)Xkk~X*r%=#O@>yvPYtJ0aG^$`j;FEAvRD2GG6;4zRhO$ zPmS&RyNiO6i@c=-?!g=bupWG>Raj71x7>Tus+3)Ui(d2yEj4#5pJh)7m~`oQ{`geKFMf4|8x zHJOZS4UWVOoJ73u*ciSlB=x4*zgKiEJD&E1Y3GPp8dGR~Vt8IC``O zA|^c5Z0FBY!k_qIUrdv!#;YRzV)^XzcS&@=gqL|U_Sb%Ohi$vXto_VWyn@|wp{9}N zq$dl8{(tB0z$_RYZZ579@X>>XX?;>R0zV~GGv(4{#&7)mFCwpQR{CSmf+D*9-LE^} zD=Sm^i{OGJ$mAx`<3h0IG{BklX|kEU`J?3s@^Yj~*3$f5%ouOs^?>0PaakT{BA$yu zU07SOg3{d1)p=yy@LsB3?#E7)E{Uf@(wlt=~$&X#5 zT>@UsYD}!DCr;Ow2Oj&oSc}lQ7ZJ2FrLKD>dXCkBn{Zrza15+zMPH-(jdb-`y3ka{ z7xbz-`+2=$^rpW}{$iCA`zYlbNhc7>IWk+rc?S~_yKII>TXm!Hl58jaX~(P)hA%x2 zW;zu6iTU}@H|H9jF5PCVSed1;EDFA2mD?W)75oaj#^=e84&a|Fs_F)Z&92I;1^g`( z}-@JF2JF(8vXwWm9C0fkT63|9x{NFCjC zHp#TMP|)+urX_{nzTe|x7pn6- z*lI}L2f#nbD#8uCoIr>)p=FvFafFM4wJB-*!S4dKIshl74ddv@)EXN)$!8i+*3zLBIBK|k7BLA#?D3=Nk|kaMr(cl zQ+#gUkqU!z`-gwj82tTu67tnqhliX9&0jBX_{`^%Q$i1d-O!^|3P7$@YfPb*sJlj!6Nw;}XbfG&oy0>+n8+ z?#@7j{sx)E_2fHuE`EPrZ`AWyiD&l5?0_-m0n&VZK`>h*HtuKKWci2t%lW`qjg9qK zNFaXrFo&jFWkq2}0k3yT3RlTSb5Ny!IyV=|mZfmSmaGJq3pv_b*TSgzaAX{dLvE)w zS%M>p54{>v^`J6p!AVo>3U#kdxDTT$nWABRRq*Wq}Cr%%-^TWmcbXR4>kc_X(|5?bGZQhnDeA;!&F zw+w&(Yl#Fy4OJAgnar4PLjUDSZ~ynQtLwC=wKpl}#FuG0kdTk`KZWQ~a&Wo)#Ez;h zUH8i%iaB_Lo|kSUhy?`!<|iZ^-AKde=#zuAjn(JmU^$wOwI{jp;Q+S)?Lcjq#+mD7 z>KNCbF6bpmNh{l!`r;FH{!`9_W7o^Q`WS?19tlxY1>J?SzR9hg{&V0_$yQSF|H!uM zc&k5rDBQKPI_@k~9e0?O(Whes3x_!zPp{8%??*DBe^4?!v}mtmf88ixLAaf12JiVO zMJd;%qiTtg`mNPeAl0N`daVrz|L7w8Zp|rRad8w&KMSw7b9%fk|M*}U~7w#T`Z!Jk$o{a3&4WMn92vL1pKG}vY7=-hFRer!BAFW=X3;4u797`FJ|uA!J$>|W7c zD>L}X*iFtKy^5V%@NX0sKW4pu;i?|*8!TqOeEWo&(vcspDj`s{R?oN%PFI38S?c;W zI4qx`LoQM3x*p6HADmroX8YHgd+`?~r%7TP5BW4_oJyx$(X0%&t?lbJr`e;rcYlti zWVWg6Tf&^gfUNbumroH;4Hz#*q{FvajZ&f-W7+QRwpT*}TJC-8%Tc+N`E6j9;@J2% zbFB*?r4`qg+ILi*n3L`-FDoiq)S}ST+>vqfXx5U5XQ>JKWh*>zU$dJWDW71j@8`c3 zER6QuwXcXs_%V&IQ84y?^~8pt&!RNJ?PusDQDmQ9w09v`2ejIe{)Ov zz1~02qxd*NBhq-pX?QKX>xLj-39IOs!UT02HODv!o0-sBAFn8he z+>V0m@81vYdj09yQzn~EqN%AIVjD9i;cKDF7}9u9K#iDMZ@p|I5=D+E?1SM@EW|oY zPr5@EmpLweghu*pbNOVWrl+$+LLLQ}_kqo2x8Yz}*O5MNeQ1f#o;1@ZAZ%qM?#mVP zjA&AED#)E!6fd+iIi9$bH_@|xXt}3A!S>hO9M#CRklmAA`W2=NEOJk`HXnf0mwoi! z|NZ;>9v-ddEcKrGt*orxt#sV=EmYZLw$Gcw-M!Y{_I?i8o<}(;~IvXU;SUuVl`|05u zaZcr>+h3n}$Oxu3{L^B%Qg9>T&5lERX~mL%4mIzfSX`9J(p!`zIjom$5Z*O;qVAQ< z-7624t?Ts)Xn{Hi~jO*Q~I*Fm)WU{||`S;>WfYe_|BxyosCa zYH2MVc_dFoGv+v7&!rT1NRnj#vnw-|w7C<%-@Mm*b?JQ2ix)!QgG%>nFB<>n`36BBu{zG9}&er~qv!3$&KI6SUFVh1osyf+~s zrm#oI=z6(j>1tw&BYifv&ikw7?fUlSkG%FMi*ceoB z9k(p$pt-)3(Ef#wt_XY$j0F+3u0n=hKWO!1wz8?`x9^c}?=l9Tzmp8c?gvXw78Y3u zKzM?Fog9uD5C>`^>l69d5%;cR1eUr=>|FEgFsFfnYOuAjS~h97-PN9rjWSOlFTNne z6=Eq;q4kho%KjrXJ3UUHLJnlnb?2pyyLeJHT0K4Y?;uug!SQhFfWD*j1t}>XL-l08 zw6B+$FIS&1lB0+!cEY^avLBM25x2n#Lm1CQaB%J23-qeOW-n)U?>%6D`3V=Jh)y+q zAlZrT+}!?&iH@m|HPi<;~N z{zt^dDJxLE#FC|1B#-;!;P8i~aqECc$p& zlV#+`PcMniJkj}J76$W!x1ilbBvjk<6{N>h!pc^GzNF1+>7v+|lNYsGPwAgwz*4SD zCIK&=J@aH>IF%NDh8h)+JmSnP3JDUluUNcM0_Qb3e_i-~%ZE8LyZ88hR!#KaJfl>& zbEn73cFyvjKC5u;KihYm+J2LnwOFMEW9c<_qey3lJM&#+GC^Fr%n*~Ms|?X`A1Dl%|lD?KkgM^igpelZ$DXd}`W zc$J?|?_+X4(b?H4b@y)ajObbliIIul$9;@slcXXi;@MwBal?ITuwg$zcEw+MMUkWF zqmeI(@m>GFA0Mz}HL*>d7rudHasPz;eDz26_Wrlea$(mO-B!CBb>CYyavMRZ(cCJJ zx*>|wr%xvo7vDmFmR5ks!V90lVZX8Mc{dPwG+54so(Ih z2_M|GEav(9_+W^+xQI@J(Uv)LE>jvK7E?|BwV_Fi~NYUvy0jqoz3vsqK$+R--VGUi&AO3*R1KDxP*&pqw!b-| zgv}X?t{#@}CFkX$EBHRZqiJxc-lVCslSe5|gj@H<4QWfu?3C5H2uj1p~I zinWQoRd7EwwYIXstQHa(?Y4E7{6{Ut@w#wd6}yk4t6R&JslwAQ$Jd`JyT})+t4Wo& zm!28h`WNrP%PJ{#*sG%RV^?LRKW!z*eJlte0+o@d?Ok^Qq^+ zhTt<7w9aZS7${u0>u`N4akKSq`Yfk9b?Yf0wa>>4ChiLAl%B zwZtb%(f87^Hul=yqI>rYK&KkqzI}ONanbkBAHAlQ7FNvXA-{qec1xw@tWeGSy^YAIy$(CThqU1Pr~f6-WO}PO--*(bbe4MLdS+%>Fd*TX3ceG*K9RwkdLL? zdY1vr@VJhZ+5jIo)-ET4X1J(6+$B8aD@(#m02*+xVX5mkdgSz zk2Lu2V>Bf$>TmNqR&}TMVfSS$j8^TH@S$)LvqQ6xjQ#aDSWZnW`7qev@;>?;`J}MX z%&`A)?>G%{iZz)b(aIQVJfHs1UUKr>dCL3jyu8Hyq&s?)9O#h@ zjXU_js)}+_Vd=AUR3??fF|m~LyU^;YAOoLc??C&vw#B_x zAVp~G9&4C>P~E}DXY8kKWW2|-hw*5>g~!eI$;n9;h9mxE62{%xjMor?XaEQG`T(pOi{@Ag~U8L`QUs4r-8e=7n z)go+CfDwJ5f4OwKxNv(*D>#&r=6?Iq{x2?4SmPs?qLFK5(qr5H$y4_@WnF~557XwT zY?;wqVAf(G2F=Sx=4(W?bhs)=T^l(|R_i%}!>Fkg!r#~MHUBGAxf5w87ms$qW1Tl2_MK{E=m%-rU?wNKKVn*r+SLx=SES&G(^Nh~VSpp8nM2IEtT5 z;|k?8QbqxZDRi!PqOVmba*!*@Q*0r(t9SS(wFHS(f5raUjrj)uI-6l1d}z^)k3KMS zD3qVM_{&u5kPX>kn-M>}^M1&M(FBj;i+|{k(Tk?_&1ue<0&gaopWaO2%Z&APp-M_z zoU+8ff-aRf5v!LA#Alw&yi4})^Jb(dUGJH$_;$mBJh(`tFFS?IDp1BDSt-mbuE@f* zgbrCJg8q8hFa}fN4kaWf%PuS})sCo$4LA*w_m$$;s;5d_O{V;yzv@Ta8q<}v_9VmC zA~vVQ^`#P3`Ocm_@rw2|1>XnV_r@k1F&v4i9-#;p*j)D4ImJ;X(8Jcx6Xru7SmuIr z7=i7T^{C(ZcY_3-7E%Nq z=ibuM(UBDw7Zc_G(AKCd%gfl)La5qJ&CM)(-4<9;jY6Ma;S#=qsCa+W&6|>ZiK@rP44k8TKfdd$p9$IZ17{UntWD9YsMO?$t;T( z!x8mRFeDnVdGq1gBjU?1*M=pOl;}ad@B{m0HGXZiBu9yJf1mZ2c^)L{261Rx->Or$esmM4iui>$ zcj0;y6h0jD`kLp2?R*MlLg~~$=pNFy2^4f*$r*KnM&AIc$v5O>@y02z7 z7Lv<0t65nhV^0&e;TWy4CBA_#JdQpve%!)+_p5z8MSdlnpO4hA%I!i51s|PMi$Ezi zVl>#5dTk>J@U+FWr2^+|Q+qon@`j`v4TA4qxz1U8lONEJ#KhP)<(yJSNB_dV7Gkw} z!kaf&5D2HdB6GZosKB_16Tfaq-%KRm@;lIXO@Y$oe!CxDj-pRiiKZLh1v~^qZ!KhA zXLV|6-pblHv`wS>ljGSP9n%kd|Jb;{CmYNhJ4B8Hq~htGYt50Wsr`w2^XT{kvgws@ z@cwv3O;c0D*Y~i(qraJ}$JooMch?S*1ah3= zP+lTIq0~tG?VZK?wrP=oK;7NdbcUzSY-iIw4H6rpCjNZ-M1G0G%(nm4F@Yog*gUWF z`>mW3am3>9zJo@|E8cD?6sU>`>FEj^gPdoAUsBOHx%9`M+lwkIbdUa88FOA&Vp*S$ z%c$#swS~1!dA~sEYT(LZw%cj!0^lV8A_Qr+l7%FNGLvI8?KkJcQ!+BB5CZ2R!AvwW zdJcViX6NI#Z#pl3>80*nRr0Q`+3yeRn^qa*dV%Y}!OF;Kh3*!ejjkk=H(`RMp^{xjjCr@&f(t2E#v#MLZk;&ZmP)fZ22j}qo*!^0D=Pp4_ zbks72=G~pS9c2kwSxOKaRt*+}tAsbWxeb2Ub8J}_$X34OW_+W@KK$>Ew--?Ak$^8j z61k;+v_m06A}2lkqf&Z`&jbKK%RScV4Bi#iX(E9_jn{({+kJYp1mF zS=IBGpDSG3oL=^ciOE^{X)h!N>ooCTkcv-WbL$SP<(|9J>gu7ywIkpj@rOV#$|AEK z$dW8_7>>F-sH1Otp-MPc!pG|IkiUKr*C8(-=eTUQO+P#;b;~?X#8hto*7^;M-l}Bi zi=VKzE-N$G|9ombvbuW4KihRNkB*TseE9`11rAwUo)h1*K6H2IRM+`euYXye%AY%L zxNNDVr9xyYWZdjv9~q2$%=5q7WNpKWgKggb=T9XJjIo2pJb?)xwvyREnPA)+;^|s= z6u&Yo5MAN2%pY{ryO4kaL?SBjuM;>N9`(N6QG%f!n^kQ!&%*pBa1qV)eaVk+Mc}vRt+ryS8 zmYVv%W5ncwyrCAKyrFKU&oiHYk9`DD-Z<>h<69VDI@qA>_UfVY zbg6#PT`$C`pReb8^qQ9lxzPub1e%ah?OMP@X+Qonr;v^>`W_n5E@6R@ z*`s%wHoIuf&!NwgwgQrGmPz6Tdh+$QY^lMB(w9ds4J}%UA01E}8N9knFfQiQw1Qb@ z)3Pw+Sbu{Gk^&v9m7s+!wvV^h{=Z^v8;Fj?fStXK;3|0pu%_&aFGLj?DDR=5J zNwJ>KabYPgZn-~Iqui^(j>neOGihRDV-03x#VPu_yFCnJV@?@xg!&u}WHBr7f79IT zQJ${F$uPLFVHH(ar@xtIy85d?%3*@B&2%ts?cuL8Sz7+jjq9>ZiXI7(*VI$@q-(K1 zg(jL(x~$iBO@zWc+}VPS<@pg-;?;_fI@&`0p^`AAKp|`%Zdvz zT##7bMM|>Wn(A9DVxQ$xX)y3e@dOzeV#@k4IF&FU+$$Hb{_fhqFD2lEK6={&l9w)( zZRf`mE$<<+z}RCW<)r>oQx-&6K+{T~C5fAim!R!PY}xtGrAc~?rr!gvaZypk#cwT` zy}OPA6u+qml}d*AW731Vijw)Qf>AToW4!ZzQvR_IUD9WTZxDorpzYX8C~yI$=H`k< zhh?YvGur(hD*co_?i40J(U~VLGV^uUoRifD-NL`qPAXfL=K;azMpODYw4119OIs`(K=4edgcTm`anQa z?)6eMJlb%vZ+d41uas6&kRdIfN_?&9wR2Xk%ws)04T6nv-d-1F3O!sj_MV2SqLMYJ zP}<3Y6=)#Dxq(!PikX?2Li5J9Q$MSW=_n1?XUg~AJ$tEx`@|U(LLYBN`rso^ zm1t?wwHAE>4wdQ@SX@T)QfXh(!mQ`?kDY+$R+t#fwd@sZ>gqZvBrIHs?Vu;(+_oH5 z)zw*JkE4_h+}A~)R9HAAWPHt8@R?&<3ic+X%&c!(Po}i(Pu#)^kmiTVO3(d?d2rO5 zQZivX2Ab4V3#;|XstQb!BTdHJ0iI)Gk@d=$HZP(=dE1AJ91r&|bp`q2YyD8V#K4CR zn7UnmI;`Ops)wIpy3rxcw3X5PfYQ5RJi)e`5pMs;^|G}q4ESbS;+>?dtql%^gjQt- zeX{Xf8RBIfU^wT`E_kN=;sf2ktcDkslFP}dgJ4Sf-{-;ykGszgg4IxbCv|z0sKEs#Z7f77%8wW2)^nbfwi?g$ zmcoObq1(n9ysLN9A_B3I1r<=#q_14*F9BQ`*tv6iqan86eILb@r|9`6N{yNggWfRC-;_w)@oYy}FYh$%i7d6i$NCzXGL%6B*W|v9 zSn|KulwA{G`*RXZj;o`y5M9mE4bDar<I{p#8+PE%g#^aQYbnlW4Dzk)#AHL!FW@lctA@vhz1T-xB@Q`c(PW-)E*0%>8?JJ zEoGN`dV|5)*S=CJRRa}mX03^f!4gRcOA7i4Gf5FSM-G!?*}!~DJjXz4vLLM42$rHM z**G`yEBkI|9k1a=qZ4J~@`do!m#wW*K_V27HFQqVIXx!7?7U>&DkX^(}$k$q_@ByFSJiCV1Y7tO>Mxshk! zukW;9^OQ`Z!4=9QiN_zfzYd7E-i*{z=r)oVm<_n`_}dS~KP$^_RpuA-SDM)~N;lXe zEDPPok`z8+242Pf5m`;m8@GO`Jn@w$m(6(Iy)Qf7S^l&DM|O6@mJYT-2PnWxmdh>IjIa!$P?wOiehZF9lMpjimi>c^%&$!V?T&? zYPNn&>DK*=xseCLc)q{lFW1oSI!i|}$YyNpIyQESD>*{6wOm*4y&FgSE zgV5j!1}$~nv4qqb8Ii2-<}@A>FG5>n_4RrBa%eKOZs(HZ$babxLv=uK3VL8M_*sXzpSPTG70G` z-^g4`HACLNedkoT{D(|@{rUmd(#z?Ac~-0p;#vJ4yE>69B2lC#$`f|GBkzo^t~Ex1 zYNIX3WU6kxZm$A|n4!-!GAMVrF8sJ*U)lVBa9c$Ktc8Sy@%Uc<9+St$wZN*A`Bd2@ z?HT|5tZLnF_=m{K+XaX3D;-5;JG+-tQ&PoYbH#67m@F)>n8uE2&XEtTfgLX4JzbAo zU74r!ZhCcPN+(gk*XxZuk9?aElgroC)FQR@MNg!TJh*raftq_MeteU!w|czJQSyH@ zeRm+1{oB4&LXuQMvZ549R>;a@&x~XxdncnrM1@55Oh{G;$x2FD$&9Qd*_&jOgx_(! z@B4fIdcV)}ba&s^_4%CRIFIu<*45HDq?J^b7QPuC0pex8_M75YzeJSJ-%OI^ztI8c z&1t9u0%h5~e!JS!GZre#tK|u+3qH-V)UxBMiyX4BBJ&stam5;@vDdjk1r}b;i@|JP z?RMY4XC}n?G*}^xG)JiI2GuS)mC56|@#gj;?d{^lC7jwuzbtGNnC;ED?Bah0Cnl%b(zG~p zW!Pv-tdPkFLyF92jf401==|%gnBw>kun|TT)ZRX3zkaQXoVk+f-ReM>o>_BujRG*D z&5bMOMRKouyCAGQ*vxRu+vmZ3L5V)t?W%!rAIsBVYEmh4=Uv$5MuM%K9l%Dp$j+I` zHp?d>uO3VUj50_CTmK2EISVGPk}C#0SkRpvUeI2v_& zYdKTP@m)4UR73q)?{iAR5#2V$%PR~GEz|{Wv-+#Q;zR1pnUcCcNuK6mGI1ASVEaU$ zw9BrBEmx z7-!`&g5;-~T3JfRM(l1?SMH>eyf!?Mp^`TCEp69{1^4RjT{fQ?TJ*18{kh#Y=kn#_ z-4Uh>x5PsY*41Aznuvu3{5KQOIgYP)^sPG5yk}bI3y*!645cf`0P8R-M_J{pKH??)z*=Z3h&? zjnDD?9ent41-?IClOK%7%a>^nvUu_gQBmASeQmZh(KHumFF5)oQE9>FpTdJHZp%Xc z%hIA{{xqM84g8e-o2-sb@Y%@k^PZXK`?nZ3GQrO%caSP|&AlF$jcQze%H&$Bzf6A= zm=}iW`}j!7%~iBsVet$uyHS4Mz`0+(+xJeVhxU$_?o4WYk3NrFoLe#8Jj3QBC~P)4 zn=$x_q6LbtO;A7qc9Hkm#y+w0($}l8ag}gBB`OS1QFzKgcreaWXD zU--wRN3RWdeUHgxR7b__k)dguu}zRlzSqNZte~Od@8P={8Gc1YWrcSyWLIoUd`n>) zpB>QH+I#l->@SNS-1*O0j!k44YkW0hOYJz&F-2n~Q1DTb-R(kw;f-T=ziZ0#hwZuQ zQ&E2Y*5$)5-w2xxYzd<~qKC2RPX>V}Wj9YPe3X1(C9rdSoxJ3!^c^voG`5!=DQkDy zKAF+qmDI5l>hIJ!)9G)gQkdU8q^)kA;~t z(@P%|AGrqD)tsoDt_(_<<VHbcY9ZZtXY`5xLv>Zg@oc_slvM(Lz=!<|GOL$apUd`#qalXVW^QS z+PY8PrVzUt?QZlXUf>S4na?GBfmRDOvk_NPsi^ByMU6FqTXy?!l_*~84TBIb`Nt%X zW9U(BYVI|kCkRT{wp@;V_^_Zkq1N-|^y;h%+oAUGSUQuHX}aaVB=Twd^MvJjUZm!5 z`#S0E$$BK;mDP3Hdvm7fSMO~o?3 z>zJ32xv%vd1d{5~d;Kxjncr-uP6c-{j<5E%&TkAzHJ$bG2m)*rhs9UAfSTG!P6hqq zNm7!OaI)mq%A+?Xr>5GLh9B?#dH1$}t*xZwMvuV15h>;&!+|>wO6-$|dk21hcD!Ba z?z~4yiS1R{IM+!HJA_o%!AkM!AwHCta5#*FX|LM(z;jDjB6+FfEY8d;A#n#wtI}`W zAesR_DBPdeQ#E(WWTh{C=F(Rc$z@pcOr5%eKA5qgnaX8z#hYKim!2wcPAg}`;ky%c z#XzgnzyFRhstvn_NjZ-FS+JBgJLb^iBEK5R!^6V?EtS& zxIgIAG~IKE{bCn*5`pqxFrF{}W45C)`(Pm7kDFW5Q&xgOn(Zeo_gBSL{8Ug^-<5Rc zz-YVOZbaR-RNaqDNj}z2d{tDUg6U%eTeD%R@ryh9`uYlwb$kvvf;JjNpq*Ir2j7nw z>nQf!!i!0B|DJKG&^EtZa8JanEy4bkM`-fquQ;!fqnBOI)|s6HKN1i1{{0=gxgr-` z3LnqB$}zRD@Eh3D#b!v6=-oTQnd)Dv=dS1(cX6ra7d#0fl3C!%U(3sr>-}rRRQnZP z_oPCY!u^kFwkS!=&3=;3Y4ZFJZn5i2IYa>?Y`7~-K}8|pp?Te|f$c2;0M3DliR9;h zewDs+M+_o+IJ2SAhxT_Hxke~*Jm{Xm!v5|OgAj;1_TA>5ocs!jFWsK;&tS!2Pt@wm zQ#mYM+m$@M#O2pzR|`do$Fr7H8(8XLlE; zq4bBnLuuJqtibo#D@t(kY+rD{`9xKdj)$J1D-k1Z}w*(lg9?55Gq{^}_{ zDZ#AdnqSyM|F>%YsQX^p$A$nX64Top%#AXJe_p+PPRk&O1!m^=YE$5LJFJ092 zQ#$wFxpJ$PgrR8t7WU-Zb0X;Tga&vheRGAFlNwep- z;-h(E;2amzAViy+#hTiE@^h`l@M3ekd)+0;rV_q)R%88)Nxk8p7pswbFud9(bbkA|3e%1XZf-8mYloS!iHQ=hrWVS<#yt@LIodsJc<`e4jrny)5bg z*Y}zgtBh3p53=-aG(OvUeVq1jtvgmFl-6f&w0VjLwg%MrQIS!diEFM*x^VaD-J|D+ zH8kq?85XIp``~DDeew~u&hN9%2$Rjp10g+35%PV{ zB#HuS&7xzDS^WNK)j2J4@Z<^lM|;S~>Khx)mc~`m)7`(nTe%CdhsS-tEjIt2#s=XN z;p>bj?*a5b#9YR8BIz>9>OG)v7!SE7U#QG0W#;6p{WAWgOMFR{?o8ayJmH6ZztfA0 z<2N@Z3LLL;j*SKA6^#qV$6x&R>aK5|;lRn`$17ub*)V(X8W-p*Umv%4aB=UQyHCz~ z7d-y=kDgn1xrt{l$G4I%R!1|cZhvh{kq|H~XRX#UJ*Z&CfpUNjjsdp~1d4 zOSdkbFXb`z^Qf7gwAMdL8XtG~xRRH=IGNTO9<@Xb)cB^GTO@V@rn|0Szk5ROV|nb} zBWIqI?9_QFa`cj%w219a4X)iaNiE(K8jl_SqJv z;}uhNDNLB{O|Yn_k2Agl4{I{-za5U#Gx@JQim(a8=W6AL2xzr*S-3_~wn^n|54iYj z5TSeD*K+Lk^79UV&Fo!MQ#(4R|4hE+kT$^xskmFWn&D@mB}@0!HU90zvl>g;8Xur% zywjmqSLhw}YSB$wAtJUK>9>A4?{n{qaP>-e_hNkOa(L|c*bn;w>#cvM-@Shir$GoP z?1Xag_?HC2u@%h$+}P$@E*y^BG2e9UV{>W6<_#W0-6mvRY>~;b9{@vK-q7&qjSoWc zDQw&ut6yrdUWC7``|6ed?ClqAK3_Rke=$GIyy(Y|pG_)qtd!>ny~Q_b-`D3zoL-6EcA#!VHQy~KPd3O(2^--`s*QXpfdJ3nrg z2`~3knD?@1=&=NOR+_<<3rCeS)|UF_9_qa|*@15c@_p>t{IR{)-2F~zhknIvvd@nh zy!m5&ghj<;dsF|d5o7cCr=s{T7stQYv-5swdU-ih?;T-bgyDaiux!qX>#|Ma8)5QY zuk1XFME#Tx*O@%xceOg(ZKT~Y5~k2LwY4+toY>PTRgo3g%%-MFl&}6^7;lkKVWlBt z0`m+#dp>@MfX~PLH^UyV#tMNZZ_NitUAlCsa<=p~xF5q0kDh^^4h%IpI5|yA4B|zc z*`eK;4kG@uXUt&D#EX0IgE^52Lshn2o@*^tQ^l_HgQTf#TnWOr=A)9!Wwf>FyelFU zWgmCjn{01+{Mqy#|B^GhP;svw4*`cyewx)AzI_*fy%AU+j+dL6^eD`*LL+5@;la~Gu%ZCm}^tC@YbEtZB z?V!3cJ9Ajt+B(PRRO8Pw3n3v>Muw_<3k99i)33@NI*Bw#mkykGXR_msN}NsqyBM6o zcJFOZvBjl^yzGlds8WOE51csoYUB5a#?+M8^o4XlT^>{o z)`i9mSRK#L3rQa`)j555Pw5S7d=EiuYk`#a3D77K$S#eeIH^I~F(Z0&wxpBC@bjmQ zxj2SoKx3Ek6*9Dj4BpZxsO{T?@#1uMMT>tZbkgZ5s<(Drl+)ljeKKQ0r^rM&P zPPFXh-V&f)!Iy+zoVow))Cnu8Wtwrc85;*RzG@q(y15GAQ7BCt-Y~6j@qa7-U$?d7 zPH7RQ6Nf0MU1GFC8dC!eU-)Vzf7r+rZKaj3v(o2^$e7aJulS7 z@tRk4XpCT>=;E_!e<@p}#O^Tk;*LM2E3oQ5bF+=B3vkh`4z=&h9=i^Nx!TMcz`>B% z^nCY@@!s|HFXQ+a${qU(F1sT3~^_h$QCaaF{BNgEsDF}snfi3=bw&_K)JL;{i28E!Bi08 z^7Zvi{QhQNN2X*glz!oqg(%!;)r&nD6F!k2e}vk4^C~KmFL8YuKVodM2yH?O>k;yR zHZouOa^rvU$Ilfpba!Tdx3d!|^_JL6&HSmeTLIbsc}L3Q+OK{!S$?cm{0o0W&KC~; z6s2Pplf5cWrmucdhCIl{l{4DS>9-NAUt-t#Yh1qwiEpEs&eOGvmvkIN^AF}%O+YBr`!e6rK30~2%{lxye9 zJ@lYkX_Nthu)@{*$i%iQ zr!_HU=-RjUz8-i`2YHmpPEVf(&6QS+O@{e2mzVa-?C$J$ zJKA#8QF>)#AdUHpk$uIyzu)iEJhDQ9e)Wy)D;EaXM42)xqn zeD_nIG5^!$UVU+5_>P2T3FC2^`sVbRj^r1Er4@3AsU9fHsX}*I?fgPrr_S%~_13zo zQmKfA$Y;!>?`F=puJviYxt`$PYF+6-ZBmpCO~SBCT(TleFYO*+U4OUO^$D1Jnr=sHtj9>3BpC zW{#j*`Qs%?&0<_1%ew-$VB(zDg!Wq_VYlCjEd zJmVw+b?J#}e>s?Vy-82?na-vXc68vR4TNO!=c9X`h^_3zw?YAv^l8Ly`HobrS zy4NoGr*<~hA9TKL#zB~MAm?YjE%G9pAzjKKIG2k9mzV&y8 z$MB8n8y!u_fp6bFLmBUYjMK00TJrMEzXqh@T78&>Z?ueBOLZUvp9^Kqt1&D1+SjKB zs{s(9K=g)iT~$f9E;fm@*E=)CkkrLDZ<6KcqWnwp`MW zCSRkNQ_J9htso=TP$;G4joPcs%Q>q>R$mTd z4pX&8>Py>Z=RlIQBXXq=H}UW-b~Dk?pzCHbZdOdQcMwQ1M3_yI9s z#oq-$Fna_!{)fAGOYp&yPfC5H0*>&e-WrjA;XS|O@Z878GkdQ+x9Z`CHTmno!Hc21 z*ILTfmyotpJyAJW=#pl|95VIaSGI2~lEKP(Kv^se zX;f-+N<$Uu2mW&(_g0Se-k7M5KDCQ<2V@Zl;Y!jSJ-=LSY#yD`enIoN781=07dd_IzKu{>3d zrAzU1clW>V2;>%xpYZJ+N8#+N9}}_raxg?bJ1587#N-}?Qt)W&TU$@A$6V2a z1FKN?HI1%v4;MVh8`aLu&CwE@tOvSyd3e$@GvVE91p|RV;A<00DO%ZjPQRJ72kyq* zfB)MINy65~h80%Q&<+MskEAk^Q)P5V_Oj_w?uBdHPl-xoUSchL{p|JwzRsfy z*cwluA}W?^J`z|P(0k??dKrF;ZnFmO@++PJAW+;{o|;MuW0JOwxuVH=Q!zM0pn#k! zO3uj751YDhTdTxd;)p^WAy9q!cAtM)1NJ$*xw`I`(){yj`z4PJKGIq6qt8O zlOuJR19L@>-QL+LNLiE+Gbte^@<=_i2L1%X2|Z;+_l_&j6*-T1Kn*%JRPoA{BPo~2 zao&08Mk?>O;$0~#1wO92C^XZ31;0rS-vXWO(2yx~ZlR6^4M0DdL@6KU55{3M1XA(O zyW;12Fmq0-si_fFWK4`40uho)mcjvElvNp66o=Mm=rI)$S=8N%95P5>kY0pF1ze-P z2FJ2u!x}T&g>|pyC+B=aL#f5Y#9$?lf&_9r+4=d_bN#f`#|$c8sKx2Me-q&@uFgYe zUiDx%cv+zl5eHfl<7+(U)bLMyKbdK^JiFQi2*~04*9TbHE-E@0)c~fUb$hxJ5ul+f zdmyY1TEH3jHwZf-OrNK2D)*)1SiX1TB{t=uR11+yXsL|4c6WC2@$ucm!JBmxfPMqi zaexS9=>(4dJ}T@`IkJE+jdF_E?}TtXA=0#q6e2hH_Si4PY!|Kk?v1rp^Ofli0y?R$ zC&%tNe$|62R;+1=b;DxW~7}7}Mbn)U2ybk0a#BA?v>pwlM%U-kgrjBKnegm7oZ<7#qgocLP8+T7{ znE(D+Mt}i6+p^x9_D9zS_9t)u>yp?UetZ_W!MA3J6$0C(ynKK~}&< zV0huB0|iGHiDTec3Vi85*!>VXe{*ZDL)E(xN~i;N;_!$tjsIDgViMsCLxDvc8`AqE z0sA$^=ZEBY4Beu64QZ)UAj{c>GEgEy(GRYeJZxYOBr?%scOs5Wbp-6i}Qb0ZKvW%_5P)We}a9=h|-+op^Dh z)_@Sft%jix;m8tDgZBZG7_2to#a_DlA$lUY)x0)nBv-#fk%N|v?(sSMZ#<6guOHal zw9?Z4fNkBngd4F%9!s2XxZB4ibCc##(|q{kt}KmxN6@Vm5ibYxXj_M&tKS@|haThL){E?(X-EGd+4 zuJ+;~J2KImjQ{Q{p8Z}GFY0)v(Vt@CrM|Q z#2V~B=C~$*IF~Yqne)d#fx)SFMY1&Of!ahsI$*uxgZTvnAk`PWJA;#xlPDMAA`7?; z)0^^g@rMr|VtmGS;lfcEB4}vr$0f%<)iS;tQ>zf_WV>Yb^jn^}lM{`!e8;tQf{&U4j)1bkl` z8=L1JJ{&`J%tJ@qOUPV|4FW26VAupnawL}Fq4fb)i0w_Oo|7fn|rRGL6{92Gg;y8U-1|6rgj zA((>FhTrT8Vma8zJD!}s@hq3u{qIyJgliCjoUoA6bW4nnuM&&~0)~da8IBKbs|+~- zq0x}<;(}$>bZ0gS>cZP|#@VA+I=jwIt#oG_m4=RVWTt6l*SEA-L3+6DNuLSgL-@02 zXF|k*yF%vy*)r}x1xT2c}NKoeaLF075<>3ukEpuLKvTzUi=gmJz?o-XRq78GjOu-T7> z1h*TNItqu*P90<{I9B0c;J9e!bU`ErgUelI-wq?Jq0AFKLW0~4K=#l*Jes(3APH-Dhu`!R0>z%r20`*h3WHc~#X#2BSkVUweD;Ijks@L*#u8@=h>OkGQ=@ z4y&EI2`5y-*!cSO>i~Tqpn`9KpalO7C0y6c4uaVY$rISmW7~TtxWlpF@}S*yL{x`i zQA&0;1&$u>K1yyN^+aopi#0Vjmx*c~VW%v=JO3JSMiDU}gGH<``QExOElsAlk8CHd zH>XN0;Zg`@5c2t_kp;!f)6mIr7e8|=cVG_F6<;)pK){GGYQp*bdAiWD{2)tUDu_Lg zmmiG$dS!hc`ZT2xqw%O4T1)v^HT zfTj{+{eLH)bqiCx=8m^s>-;!Pg!3OF7`U9^!eh^C35!OgukE@{gY+PJYx>aty17Hx z9Zw0wJzEx>L&(RY4T%2RKDX9Hg1#Q8h&FuLu|sAVTaP2dACG9vPqGhEcQ9Q<>+xJG zd(;Ri85@q6ccealPQtb;BqRh?I&7rX5ZY2xWxUVwJ@vmsR5HRh`XMS+hqHxBlEBu_ znLiY_j~4h{!!IcK3IB$Hp8h$?P$V_Hk}qGrz>UQpM^Nea4vI_z{XHbGOrhGh4`uTc z91U=>Uc5MAdtrLzj_Qeyw?*9(OQ>ctI(j=gc1q(dfisN@H}y#UsbC<*!4va%L@I{O z@a^fcLs1#AG8H>+jmy$rX29NqG9yf>kNAqpiQc1vI`( zs9=Fxx+L~Fo+rW%B$eU8qeRMtn})oM+yQ58%t`}gvHgeNPl~BH{KKLyW=~IZim&L9 zVTjYznavU&8~d=&F;2J-Jp^#4l;Yw;2#H_6(%k;(TsJUl^mmuc`gujfow+q!A5m-& z>8xJ8dR2>!tC5W{BvmW>wH^=ZN?Iy14-nV!t-StrB*&^>k(2Y+`PXqJm!yPosgmRr z@H_aT-@aX{BS|S}>f{s-NBAPs8nTvTsk6sI0M`%N`N`jZfcplUqi>pzGEwzNNF-tA z0i$r$r6Y$9DUyHs`ZZjzJ$eEm_atp#eX85Ngc~2@2mXzpN0t3FA%Vf@!&8t@K@0hQ z`858RUpSaFDAjgAat#KB5s8V-YaiDn(8Hoy*NT5rS}Nc?EQ`947+s>C0<~5J`Jl^q z;6zlQ9*<`Ic6_VX!#8h)(fb57SU{HKP=5F0DiaeFnc&2bP2`p0Ogv!@F)J}>vnwI~ zQk#+=vg5ZuQ`yd=uTrv{TUt*~vnlNb)&nM?B7F$|0I~-tnSL}#-7Yoz&JV6_tal`D zL5{)<5~pzC;KOr#`I2_!Jl$it&>=l|tx~&=H%Cx|!raD&92VtuBN6KMw{OF*BMLhN zc$-tx(~-43K|?8%q3+_LHA9sa{0+fx&FX*5x^P}t%h0Ic z$DmwC@luOKYin;$)HsT=F?%T~KTAxYoVIS^cti#m3~pq*!vhMGGa~a5Mlj%(=A)Md z!EiK6Lpe?QTsl6A_*@JwKm;ZH|BlF;#uMJRz#!2j_j^nnL(zpw0i6WYSFo2J$TKkA zMZga+%5uMLOd70;U`HE310XW2&BnsSgaoGpTC?S08lxlV!P)#OQM><{H^tw54@F(>GwN(Zbus4;2-$gZ_3(L!?qJcNXp6rxPSvuykMlZRme z(E~sR>H?Ii0@f|*rKLxttrSS`k9BimD!E)`IcVXb0abdx)`{bYAn5*(ZeVK9FOp@E ziPll@FQzmo8BoZBJcL>Z8T7`Dvyk|kK^n)F?J?le|0|CfRYkJfE;DfoKFHPOON)y( z*RNaF1|3GTtU@+}!~w`P;mgBXGeRgA9k@!J1G+vOFgR=~qMAWR5!b}&s}Zy_J245~ z@Gv~UEjYR2?dkbm+!tjEF|tM`#p^_HAEVz#MHL<$&5>-F+0hXEF*RY+TM7osk!Bd; zU@h0eM7d`TiIrF$60<>JNkVwVwAs|x*PAp(pK7Ovl@`-c%cziAGgMaeis7+b!pKaY zxhzTvybF&DJ!JSy7c8YvSMu;!V2u)kRMdWma0m@Bu(hl#&dv@*MneaKj7I3}UA-!C zhFj$N4?%`WEq;5vBP552xVV!I=b}r}C$CGBU5%-nEB9DJ0Lw)62DP;3x;gr2ZSjPW zj=(D>B9&cLcoeTJ@Mq8-f}hDOLEV5oZ+T_;@_g zvexJoQ$fafv0E?8pEZrK(^J7K)dFv<@{XNA~@`CpEqRh&V-d@WSRJ0FeaDZX_oR*bkWAsuI7Ig6T zAyhwq^#qdo>|TtBiQzn)6uIyFo9n1}!DS%|pIlLpKKK{Av3S$ta6(Av^65e7+2F1b zWiOx+RIUdp{W(<0!@I$gj8^}!*nIw{(@w&r1Hu5zx|kinA@do^h^Aje{eV}2h)b;Q zfP4{tXkKqTPgaJ3RyQ8#vD+r4y|xYx zs9I5=$n()hQ~M|@V>^Ncz@f1*GXfAwCB4X=p^6wH zPqB-X0G2>TT>H0*;c34oA?EiQ$9H>i3kO6PH9lGfTR$#OtpjX+&09jk!pbAozf8r@ z7vspHEe_Y5!f#UH@qu|4-YqJ5%(vWO075i;c*r&Q>rv;U{6)OM#2B*%gW^X>;wWTr z02**)FN!l0Z3Dy}iR8jCiOfW#U90o!o|W{d`sq4)v}mmu<8+RMB1F&Y%KqGV)bdc`&e@NV$yp@apC zM2r;xxTP1xK7C5ij_U4)$q19om$lxdMvm`uJjocc`1snt2YNgYduPY-CD5Zoa_!LI{E-Z|YVUEC;4jyvHBt3#-<^;( zqnpjaa|8Pxc>elgH%M^%z=aAa-`?6-?2i_5$MwK_0ticBtQY`cULDT0_tNqYJB5WgU3wJ027#5kF#n_N2(Mt$W^S5@GT z0w+p8c94n;FaTOKbEE{^5g_9-XuJ#zl#vncOOqsg`HWYE^{Ly0q2`}|SnNXoEN-~P zU1;@%arJj!Q!bX`tqhz;4{O>f=79ThFAWyJKPV0Ibj5rKS<#9L7CaV+$HS*M1(^_Q z&Qp_w#bnd9tw=?VYAl8~0g%Oo!cjxv0cewrHa8S-b&L%Y=i`r{O`#z}PNJOEC z5X2SVLTtCjTH;_6$Odk0g79@SL=XT5+Eyy~`t$2vD7HdygGuk-yV-(XH{Dzc!3KpM zu4pQ#S@>6Y*)rs!8jWHa%E|;b1t=u+-8*7ArW;sh3Pu|MRpFh3jEb+~Ae(iLa~Lr4FWv=k2O=FFMEfP&PyYY1D^)%3 z+<9$~haY(k4#Wtu(7Py9fq-ex!_Wfp-`A4b9UR7+}G4|QKwSFF_0eH-q00#QD zd^dg+2SU~|tWpWwko5cCfBXTPM1ej6_m9HDzf!M00=T>l^e zzyl|Se(%Rv7^0*2ICW~O)!Q1K$dNNfmFQ36<4+09Glwb2|H)L1moYU>`KJoybt+?A z9eiW9AwxV-Kxa;al{-)XSXd08H?}@4DjJV>1V9OS5m?eqv16I)NvY-KObF?C>wsf0 z_ALUa1~8ORO@_V?y73np$yTrh?8(52qLpTIp-PejRTB2Ji=_F7IU!$Z-_jg5Ae6i1vo;6HW+0E0-5 z#PkdeM*;BkexL2Tx_Jhi0%tE@rns{Wgu#Ps`!)#N(U>`+h9pW6jC^1S_q<~Y$OeWa zU;F#dXi_4g{rXBhfybo_@@opMQWYX(s2`}dwdJyyOM z-q=AgaT{?Pa~R^L0}Vu+jMEnksJV#t2do4Ffya45&_@@F>axJHi4G47$7tkRK5h8_ z??8Ziu;JvPyhY5dK`2d+$dpZuuKopqNJ7OZohb7chM?eV4_wzew6m}li^_OX>@dS z)ZnlBY9r{-Q@A@%w+UkQUr>AtST!q#o2ouxg$vPB<^MsqAtxFvPg3|9N|KMzc@8dc zJiU9mJ$%;Y=#!0!Vz*br%PE|8@hT47;y(6l)(q>6H$Gr(X;L=B8pu!syNDc zD@w(?Z5%8HKHgnkUUq^b;!daO&QlD$!t_*y^al48Neh4Pr44=5Wf$Xc8EJM58ZBt} zdswWHd!*T?#nEvBg3`27q<6K{$5v_-!O z2{t-pKOp!Z<5=7c@1Ds3*nk49tS*d6R0d3XqVq7}gXjBpY88U{nYyJK{#(;Jc(9VB z+M3hzsCqN1E{Kb(q9!8qy;xm<-Ws+HFQ6}L)tCSNw-}Bm*ds^6oestP*FEdzil<@A zblQIyB{%yH#O*Wq1k0}%BVanJefhE+2kph2E}*;^siOr#Fs)cuOAVaGia`4P`3X{^ zWJMWN?n<~>*g%FHVH|S3vafbSGxK2)2Xm6NuQiN8;xJwz}t1&=@xMM{=+gKqK&#K2qu~X)UI9*`=Z$al!Bb9siOlg_CbhABkw5b6u{3>zvX$SP>6p_K#l1c zqqowi&QZwVS`4|p2MSC3w+nr+eg20NJ44W(q(Nqm_BLk3DQ!02VIYf%K;4)NhF+XX zA=QrW+!xHCXG8EkacW|nx{xK1!a!qc|4qbtOnk}N-ePo3%$BJGhr@T~8h?07^q`1- zeCTUYIwOSrPe1&_KHm}`N8u-8euZJ$O#5L^S^YXdSN!ks-BE>vo4+=xB1KXExO;{Z zg%=jfk%i!-3f_y(=@?mBuGC8t+*ENgn)6}eLuH9X^42-hd*fWo(YF*|2<=vfq9&Y@8N@FY<^gVn!~wzdK=%!d0?`eC zvn54q_s3NsnUt>ztgrDZz^L6zEBP|I5F<=vTz8=T@N)JVD#+acb((n_^Rwli|VQ=qDmesPJ|Q9l0=| zBhpn{8{5nvQov`-TOk)56Yv{@DbSrAe!kU|AAbM-J^rK##@=Am+17JA6{7tG@Qi^d z1TvXRQc}sSVJVdc1!lX^D@Dh} zg$cI=tN8wcNkyUe876A;q8>CrG4Y+j!BoHjn(I%g@8@8@16Hav(eaW8)VO?E_mZTT zxkP{JFs9doP_1=I>;?F?JddcO`c#l2tS-vt?2t=J#}tP9;qy#mPUuGoiBGW`%D!JA zC2B8mxTXlIx8MGp3a8yoOBGm&O|`IKo&Xs(ira80UKY`d(aotHb147~95)sTH+n4! z8)}d~LIXw+ObJ&c>t`MhQ6=F@)*;2%I67KY`%#dyxvz9xfyxG&Q1##c$$=z+i5JT` zk;9s-*B}igoOn4K`p+jZ&_myeM{HnVz|rZF8%m5Zy(_NC3kN)WNU$kTsiBKuLiXl5 z6d8Z`E#oL~pz->M*A!5T*s?89kBElFR3&u^428b{!9&C>rs_r!Gz1 z6hliz)K6%K7zC^oC-p#mKy3#u3FrubHZb#I2$4U&VhmV1_wWToFys6<^vI2kjRfx! zVcXak?w}*+KVpTFFc@b;NG~*p#p>`Hv4!`qM(Uq$^Dbk247dlV;yL|j!!=iMG6A@O zJOY@HPLcj6l3%QKNTCMXflqnj3BysNU z-ylHh%!@2iGqmzaLd8$ zqer#u^=ldcRzOP;$`-w2oP%r4P*Y>e&>OjM^7ro-FJCH)MN*0e%M61`!LHBDOSczj ztOe?}b|uUcAs0@32W?|xN$TsbJ(jGn_kRulOC1H1>qJWoPc`nmR{m)|SI*aauB`9C zi?b`aW3-Ae8;`II6IEUYX$<+f*cQQPjto{9+AHGyPvpugqaifX2r7|4s2d8IDE+z4 zocWCLFr`1re%i*D77g0k+Q8KjK)?#JpsB`0VN%4LD} zdo?ZFjs_jOSs&@nPys}RqG6ky<1Mx#oBLegoS@Gt4r&qt2$6x&>metDgp2b#R#3+rb#oIJpfF_uZ9m81x9H<- z1Zk-Q#_nf#&!FTP0__yFrqae)KNC#Gp$h4bUL3ItnT2_xH5t5M7pP#NEJWXK!uP1n zW)!^`(9!nr&El%Epg${%jyUBp^`x1i*~Ag{SvziC2zqnQ)Dz-5DCflmXhp6 z9WI7QS>N_-7KSubcF@DwRHv&2WkH{u+fO>JZP4vK=dB$1v?2TrUaR2b0_ni6MxcZ) z<;TO{l~K2##Azq#wktulP<)et2i5Q-tMU&z2y9Vqa|y&jkT4Us60{KX;vBmRNO!9$ zDS?ZS(q&iBI}6WDkRlX3hYmG~CGEfPfaRoQau`5p48hOQQ?^h53#q?>0(UO6#KLW4SZgS^kNtR7FuN`3EUV}1!J#d+t}Jh z@K_=s5#1`Pj7y+Jg9C?ljVnXTJX==x@Pim^8GzZ22AMV*R0WD;oo~#nG0vp_i#Zrrr%6wk2Caa0aZUqr-oC1_%dKKOu1RL?|@t+<$FNr1!wwun&lbRIAbRX;qD#!w7 zv5ALcwGnn5m0&iC!Y%Wy@Q%h!uKUWnpJviL0*(SaRtf9*j-_C7;U2k*Ge4+$-u%5{ zxm|^5{Lpy(U75M>*U{0{#W{4HfN!WS-v4+?c!#u#%45G9@@Z`ql;h{IU4RiL!X-pg z0x^K=`1+OgsJbB!9U*rt@COf_u||3D%6$$p(j7`%Y4l|XWKX_~Yd*bO(U}wel^1{$ zx({&Qi077TdFAF!AYz09$o?nQFP{M2ts7xD!t~GemMw<8g%ybps{gpI*rWTx@r%N; z9LiMAQ>w5dp!#tZ{1wE}BEUF3TGBaP?QLy4I2_n52at(ylz;(5KD|g<`M^b@xS^Y0YtOv;*Zh9wYPQWof z`QG{*Cp0~Le7Wvw9#S4g zpReSP+5>GO+ygM3J#*YMXdw$6GOKTh&|-Q92B#Owf`+*L2!ao0kb(VW6I*jz&5j@Y!aFqi?gxBcoJNDbU|eQ0QJCO4ZPI${(g0k z$gllvj~jh}c!hJU6k}i11BzDUce#cqT>h!bj31#{Z*`jWK!lXb=p!9kWgX=dJzbN- zLB1Ix*+E>p$WKI3fYE^urg{vRCc=E;rkKZK!%6)DGyihy-6x_^*MsN=T0delg$E9D zCQM-pZ7=KS1gDv^a0B>?B*SRT*n8a)g&_z4INu1L8pg)Ynk&%`P&jKP>essCk>Ou} z{fLQUEgb3qk%3f_Xmd$InIS*C#i8#VVekvV(3`Y}PRJ<^wjQ=t2$Y`~8zW2r(mJN# zj2B5G=^tx&|HB!**V2V0r^xg%oPe->)N3ZiOT*io@Q%hxKWAQ2AF~v(gBWXFSyLUhD|s^G#?j(0JfBr0@E2;P+(I9;6ExHe2-tc z%0rrd{2E#ffUc-|+x2w5Zyq`>fMy1<4bT|EB>%`(OupA{KoY>`K#<^n-~mvE*ux^b zjsy(S06|RybG^zW9CcdL-z4-ftft|I4;=zAfkQxxa%bOn@{EqD=+J)wa_1gk+&GDv z@IGm6&soHG27CW-f(wr-f2h2X3Bo%Ke%VZqlsh**to26;i4rXcymJ8vD(!L31@|%x zjV3@U*wVi8+j|6DTmX;^efjzMnMFlQb1kbY6>1n85WGkxYLsPac<3BlI5UO9EoKE? z4oTTs0pm;S$a-uTC}U!V(gE9O08Wnk5pHw*kD_fzUd5Jl5j_Oo3I8fxTb8uRZH!i6 z^j0?U44Ws74;#@aAq*=%Ng-`L3KSm%@<>(8XO$Z_oJ4r+o737RMOLMDf4q&&Gxmr_ z;!#UWOPEWwJ6~2j8|`+4va6gO=r6=#70r#NPQJ8wcc|VI)>D4JLi{)E1R1HwdT{=0=9MHa$0JLL8z;Dp5{yI{08q4xJos54dwEZU`iwp^i2Xo7v8JH{ z$^nubv6v>DfR0+LVoS6>L5mS$>$i7O99zSQ*Vfd;-mq_ZH$lBqjjsk51{@UrM+tFp zb>Ks%$Dd~m!IYX1HUi}ZdVa&m^2AsXy9gd0Ww{i(q_-MxMK@nX3gP&@!@@+Tz%rWg zHOA^aZgRG#G7_u6S&smL?M_lB_`=|2`2Je6 zFEJn{gQ%|n6E%7U$)^$cI%+N3Qm%`GdOY$zJ{85HlB%&8k0K8fQ%iXBkWn1codbyh z^Q8xv@_~yNP{YO$eb_HR>o=cpR?7EEO8e!Fxe9Cvn4{5j`2PC79?xe~3LHCH^k`!U zQW&lZ$P9#TxP{VZjGp7q|ELoJa73W3hqnI@9>JGFg^WguQ{R8sM4GfZ9BF0&3IRI{ z9|@m4sUUNF<&FfJeF1~KRdY`T9{oZ;%vh20Ew_c`qP;b8bn}L>+ri)QTz1!Cxr9l# z{J7okgV=JwsMFQZzlUHjIyR;xTo2MFP#=qqqlPATfCK{_9UUSpJ{Xb@l^4>^YVpej z4Sn!hcX@VqRbQVQkQx?w_7WWqtmP4WteT(PSB|lvdns}mp(L`$352#qX-&OGP(vmG z*pOv_NDalX$QxXvEFdd^p%1Bk9Xt6n=i-GahL%Lp{}6=;LNA#LoJJkWh_w+^Mg+i& z*B_|{j>YhTJ2cjATQ0bA&_?*N0v5u3v-QNL4Cao2nBsZ06`cqOd!hyOKMxgNX7=aQgOPqO|Jn?p}m&k>e(v_@Lw10tT68vc1(x2=p2KUnW zuRJo0zLh6i6=SlOgZ|T@;~E)S1$fCQkwG^{Q;s_6B1W!80q`h|i4P_k?EG8mE3O15{ zb5FB{54oBlADb#n`!iY;FAj38?V&jI8EaG`?(?jGx#KnmKt>j$rpuT9auUU}YpXDWj+YDs{vS)<9na<7 z|8LLinPjEN3Q@92MhOjjl_VKOR@r-0Mk#4XQb{(6jBHxMv9ecEwh)=$=XL*n=a2hw zpL05VKG*erzs7UCUJxq+uMGdWRrw=PdvKfK)T5VMKSb0tUY^z~jd;$D+$vmQhp2=) z0%ZL|B_AnZO9W1hf&=gZTpB2>;=@S%pNM8FBF*qBxDi`~p?fbG@P2%@10fC^8?mZ| zK8vF?@$?1hcb6|nbJx$Uz$?nEsjCoG>z^Tg42%MsuDuGu7N>gca!J>({zGnfns;cw&xIA>$Uhk7)xR13!>fSjdV(8FGQ! z6`-E9PtS-OJYs#%i*mu>8Ck|zp;#i_^mv0H1K&XqJx-l(why&;M!~XoqDeRADJnOB zkUvIt#b^;L%L%C?_dmK3dVxJw$Ah#QG>jSF z5>3jJBVlNq0@eT@0$BniztE(%#R7)~ZWH{#+&bfyC@-KnYrMVlj~9*uA|7_XkU$-n z_(OdAq3Gm%%bk8e>$tmwjwUh^$pBEw;{)aAygzJnpgh{o~7Og{mm}p=RC#cLkm|A>P1cV-WUL64MgqPr|_l zZiOj}`cD*2b)6MGdBgCjGVx=P5WwL74lWo2+in|cF5EvCiHyW}>-bAMMDqXcJVcN~yxj|1QDg^QNK??e z4`6Um5+JG*0~++G^09~Xp&maE&)s_c;|ba!HTyNlaj(roIg+#^6#Y@C+%-gk$G%W| z?>2i`=#Rd?y-cvc_}1o+K^T~0l#jDB%(xe!FPckU(#qkHWuQ0t6{rQ*RAIL+%EeR|xcPUj5EGxn83k(5+6Je*50dWb)!=7q6_V8eW zu=(fp`;R(+=v_mf3{=tboeSYAMk5i&ry^FwMknW47s)_qi$RFcE}VTNq=Q{z%!n|l zhys|hjzSeRjk&WQDkB(mL1e&SeSz0%y9$xoT@+O=!Ki#c~cO-)b#KuHH!4WM6k zN!M@B!psV!3ETu^CNOEb&``nLi2mksx2TaB!Zf7ZK$9s@2SH`AvQ3318)OEqEVlF# z-3U~E7}P3c&aB#{5SgXY#J=+c%hm&}%SLoD*>FfcP;k}dRmZAG9(+bZCJZ~#PC*LD z9YNH@qJW1uS$wJ+C_f+`)c&$S@E;qAWsYHi?`Ks}0FOjIgr*xQOD-SAyH~lf+Ud6~ z8ti1y5fW;5AnAy%D1|mzdPksZM5Cj2I#n8$9u$y->j5VZDHxi%k65ZCj>-by`@gIm zf536+{gT01)%&KRm3!z097Ug!51B%!qp4X^#DkZzUH4nz2; zdtB(CnzY^T2;`YPEwx)kwEd-QDX^~xQ4zn_X-cyfxJl@iF>!Mfw`PKFGL8Z1Zc zpDuCf2?cMubN8_=tC^RYjnDF*?BDr$TfcTB|EoaY6J(lCJV#7`RHI&o2;U7=IMHao zs&+Zl4#~trO9<>>+DVeXK(~0mkdwWZCxW&(D+{KTy)o8}-#WMNf$GxNyo{d!MrsT= z0GvoboA+M+6vg!8`Sa)T($-?;D+nEgxd&o3uyg+fpML)PxLk)_!N(+aI>FZO?@zCp zGVa*XIyBUR`uJkk97?-W%v_&U(P|PxO>j9djR@=ePn*BUuhxA2ZSugek4-n59TFQq z6IxW91vOUvQ)?81-hHmD?@A#605C$#Re|=eD-AlkJ@;ASQqikPKV_IP(B`+1==BghL>HBL9u9$5+Z?aMM6N zAMyK}ZB@{6X z=-p1x6cCoOYPY~Y;*a2DLxVG6|noRpNbdp*)XrNtIv$`5> z#V>e0v;m8tD!$_po&9we6%m*}ig*pjr%e;i z9zXd5CivKviFKNYP5ExCJ&#j@lJk$knG&?M5wDCP$8j!;*FaWR^@h+#)$#W^Y2K-= zt#y}FB+)zcO5Fi|jJ^6hS(noa%=B}&(W+u6_r+bw1}38^g_VgmZDy_~%v zPx`mYgs=k>o))O{hgKU8CoB2nehrOnz8ME}>R@g_oX}0{jJIy3@W}wgMg{}Xu=gMI ziiwrh_gT4K3hS98^BDeBH2Ij+IN4ei^*=@j4mo%w(}5;w))3lx6rb5ayOc(@&%i5H zk1Wzy$$6^*Qg9)jSYr4HP9-RhvBAShcXub4jS!=NKog;J{MZjW1yn+C;o;)=J%xJY zcrA!Owu6BGAbO0g1^#XK{($|(4hags04E6D z&t*Ne?yLm|*q-_kH_VG9nP(xR)a_sc^>rFpdfyDxH%I;>IrX6(;JS%PWSe8Xy(|V$ zX<+-!*K=Z&IVhzd)+|D^D<&>}8ALI7LaU(7O(dj6M2ZZWPDE2N|St54{+__=$d@d*pP$coUKo&}2Hg7ue=`*i*4HdkuNanP{ zvZDkvB;5HIFfDM<2HWKn$YEe$-K}0LedWrPS5SR|PqH)=eLG3#B8TP)XA3n48f5tO zjj+EdMgRw6TSDfW$lV0!G$Bs5KR`$hAHJ88l1fTws@i9{WQz$574b`&le4o)j*&>> zkU2o@H8yFhHZ6gsmB{-&H28)<>Ih#Y_)opllxU6)o;)5<+A@)jvJ5{G-vORkqz<^N z?OQRuV)6Thc#vZ6$KsTP%VEPBABo~`oLDRf++2%)QuH}6B5QsLa@`n3?h_k}51?cE z?9M~)u_Yb*9u*aY>R(foO#dFwe*HSZJL12q?REva6zaIk;GJX>b4;?(qX5XUtStx7 z)dMvV?m_IX!=L%i-LyIV?R5deyZi6x+Z>nn%&%5GxZSM2U)n&uOA0r{oJ$pAA)@yq z_lro-{v^B~K9?qIP=C--3GXf}2p8h#j0k{~Zpa?;Y5um(a_<=el__iv5qf<1>Q6!n zku0sz6}GjP@CIW?o*Za3j4f;4ez_p~zY#J&TT)w&GO2_^TeNrYvAdP~11>^I;%|K< z@&7pp@6R{k++yg>{*+9n6@kq;LhXljh7QQA0EO)Phu9CDxfplr)~$b7r$ti@b!ZFh zh-jxokP5wLdgJfuZyed#w|xbJpz8|SZ!w4&vX~X1i2*|R zBU83sAH~cWhSef2h&@ku319@8Eoi6+c@A36V-DTyr|y}8p@yXxwHVUA!Z(_;TBrQ! zgm>h=dc<+cmumm=Nq$VIB+4|vggq5Eiadw6dXN685)-@cWYvLjRDaMw+(CNyG@O~g zzW-r6h;V!b7@bZph~A{)?pEK-yF-W}&q?dr*bJsd7RD<^WzGDD9j^2&Rf>T{;P4CPgq($~I zuee^|(!Z9fck$xO>^2xv{wkOh;-4qN$dOV~@Z9K-xI_+kb_w_kfP+H91yBQWkck7V zT_l9y7-mo|fX`Sv+U(BgWp3V+8Zm%)19{0ekVzM9n;@q7ndkd++w>TX2EpY0xxIG@ zzMI2D^M}H0=Y-a#{B!C29NVg`ye{Vp-3_+%;)NDD5dY~m61JnB>>F6aPV(Q!v){_W z|3JFgNIBK``Frr~(751*OJ@*@H#SiN^1BbSqiQ2&j)I6WUndU=tlG+X4v}X;X8$(- z_NvaqnWt(&A9(2-PR;vP5~v0|H$W>Ik0@7{22TdKAagzqe)I>W^@)=Gzb&rp@ylmr5b6cW8wu48Rcyw+_Yf`G6xA8h4=LA=v0}?w}me z8GmB_p|9r?a*^-^dlw8NT%YD_%DBnF%5gBFdCg_>ja|}8u==$VJ5-i zS*2u%hM-M;0aYDZs`Jv^!qlPHwyyS&)@&W=NvfWWWzD~V2@6mZeIol(SoSi__xjPx4nC?zF;$c zEbqR(Ueb?!hpRc-{g^7lZ8YZu)iw15UJS8cYxkSjCzqI@=_t75ikXjZ*4}7X zff2gJi<Voi#dmK)(w7u!jtPt{6gWm&`-z)tN6M6;wiCVonK%zY(QiB4i zkgftQEiw}sNw|0Xr5EQejxa5u8fZfnF!4?Z{1vn~)ld<(y*jzebE=EM-Q8V&^1o<} z`3P#>sLW?x5(f@6VFnV-L;XlJJ{_MF;E2b9h@+WjiS@KD3h8b(HKG>KPDm zm^8dD8?X;8EiGzS_%AR%?1Hl`Z{EHKUsyOfeY{Lg;ba+@#Mu>UbIPcVWT(THiIVra+2sD9M8Hcxvrs zkEBqCo})gSdWwk*!&0D?Y(lv+K<5VDc41+`vEwyMmJTN$UmO$_8X4`K3XefKJWo$Y z{0#*RcI3TXL}Vo4AT#K?^ZK=@+?9TA$ghTP@IgAeU%A7{tMVu-YG!FviM-f7gh1}_ zDI0o(sAtavPz-kICI}E_OoxT?8;kqeJ8Y{0cjMR6(9+hFx{pn=Q-%N7hfjjPe&H-J zOkH#p2vs_p3lpo}CpVAa#+K!~8)TA)wZT_w5^n;r1{>IU%vvI(Dq{*-7^{2U8jvn(M!Q zu(8Ha#H;+}W@Te@p637^eBq{-28+P-eGLtb9YM-1W2hh;2g>Bh$jFRNoeBY?DBb-P zQl%p9Eb0`)5i21fNQ`AdM2;NU2@>$qN=)M1Ww}Qdls!%SLA+aATR_R`!1%Y8x?i}> zul7_0*5XhU zhQ`MKTuslO#dJ2><1blVd*5P?J*(!?qirzmm<%1Aer~jj#=@70i3z`{F-QKS^kMRI zneHc!A8*Ytan4avG+ZWkr>2V_gG2l%>I$^O2?+@##TGMXTcM;a_ma(5@|mqi$~J5D1qut) zVY0X&`j!=4!+C3KD+=b*Pv~>0$Y>fGBTA1J_1rEkRZ!kq9lP={7Nz-UMrt5o{SRFG zEkcaKU75*ft+J`~Es)#J&4=70Nw?ZKn5~eOuBWt~?1?mI&7Wk2wSo@jzo~Oxm+&Bqdjev;kbEofR7y83~zq>cV=2@ z^H5xLG%-L4t;f0V`R9paWM^lGM-uEl)|dt%5CRf`%gDQ0<&f@H@~#Kk>h$%Zb!-0l zqyDQSQSyN$JuVWTB1rIij^eT7j4ohot#o$>Vl^2_KCoqx6W0SM2B90M{qluABqT&v zSJ&<4d$xn7THy$(#D)c=Oz&%(haT!@dw$;YdN)E&P4Z8~zVj_lRcM%)EXSl&4j z2Rk&{tZQ^Vq~;vve1vp5<;Zu95rO*FE%GLJLJ#J#&Q>`7o(S1lkG|`Q8^sQymMzvbTkcjY$MO-A#m-l1eB2#7;ep{DEYvA251&D zsOCHm$vd`^pzLjRDu%NX4~>{tf)rwYYHqC>n2h`4&y#?h?=+mDmtPCde(hDmW~e;E z$%P;zamCEYX11?{2}OpMx;hE5au?rn4Em;0zZEHv4RwV9bbQBAp`9Pxg?N$8LN!LX z&Y)ny&KVW9HI$mMV0h~5>(zzsJj2A(D;E|?qAuP**MbB?O#gv@0_`v`=3pFp9zcgF zCvmGl%Ml~vKJ(bx+J;9&i~!YHHjyBUEAyOP6D~b;bK)AHM^LzUP<5dGjK(l2dD>0! z@$AG-G7=D9O$b|Ug%?kNCMU%g`Fir~4p^FR1kva@Q^5IL18vEa{9qOR|AGgGHbtV~ zkQwq3wD!kcKH;~9zHkIQ0Z}gy5g#?%6Gbn&w6wGKpSq>QQB z{W}AX+(%d2h%lp%wf7!9qI-GT{OB;7lSV^*y?~4i3+i|8|0G-o%I;qlrI<++U{1P! zA8W3Z-eWP!nrvDY?g%~=X_Gtl#4FPWdUf6gjNYZ4sv1B;B*feId}$Ue+A2{9(A zdC|P6e5>R=jO&#YrLX{+9De26_YM#9QM;E=Eu?#Q@Cn{qePbLW>_2d}A9~E7wlPos z<+I4&%J`TV4M2>cp`opnem>s$;2cyvW3vh_G<8khWMO3ug(x#$sLZa6ZpRKSm?GSM z|F_qw+?xTz;4bYjLefAKK!5D(59XZUOrb*)c<`kS*BE^@A;MBuL#7|6yI-C1|HW{lDeLYg2e4f`s(`xX8q`xJcjT!XR=%h z?RmgE%dEr5VrH(T@De=3hm~iQ0J%qn!-cU$Um3ihTO#4*B$$#yMQ^e#(x_ckm>Y+O z)%xD!(%w zgNE3BVmiP$J@6hgOo9ZD3WnG6=r4Zd>(aoIT3_g~y?Vy(^pUoq34qDBLKC8PfMIHZ z_QQt{L`_Pp9yie;j#^Fr`MQ1!r=p^wg{izMGPn7Cp`)@wLZR;|7nPX~95_&-XGaos z`snM08#BG~n4lvdFV7KN=lcjl&qkdhg#P5dbPWIgyO$6$>gwy)gK2V_zlx^@sm#~^ z9w#T$ygVI)?_8*ogESc(AD`FB=Cbsw4X?cJLcB^O6$4Ml7t6Z7zFnvqo6s(wLf7mh zm1k2)jGMg>)BEnqz-KFWLimsJikSt`6ytNhu8Te2zH(i-dXthsU`ZyP2eGiQ{OTc9(d&(H{#lOi_$L+}^Wq9~JTk z))i>t2SVIVJ+B;(a%aa*Sqfw-;vgV2gyWh@uN)A3R)(3ij)N6Ph_6B19~@r;)iqSE zM4?p`xS0=29}!yk`1n>j3s1uEgLC27Q@9uHOEelR#Rye*o_}B@3T|sbVF^J6Ey+3P zx#w3_qR_#1t-F1gq`GEaP32|{kGjwI3EaLfdp^P89VCAg_ zUe~`bk7#@1<6Fot3CMBp_!>~xDW5pTOPNJkq9%AEg(URL?S%2E%#5dY-9*KP5@;9) z7p7VB*cBTz0SHy(!_4drwOSCfk?8!)LZlNsbcl1eqGvT85DPbVG@J*N$}P|(?k3?4 zwX(9}B_k)7acmU;H$Ddcpbn9IeJA(7qe7Va?8Hqs=Ggv<;Y*-MJ%yIGwh+W(M3~Jj zMeI3-fQmyBh0G2Ll^lugl4db;y%lP4l+~j+gv1QhGv6`Y?#abXSsrXL@5DTl?-e%= zBAXFY^)O76DCkk*;hr`^ylh?=jE{M6g=pm|k!j8&unB%TZ=^3Gj@NnWq$Oq=pN7JBrYJ?pznZ#9^ z8~pH1+rWR6SF1J;K_7%(uF=Z3zUv2ipX)bnAZ93by8BYdYgm!%De$lTouQ8#Gs04Y zQFn@;5@^m5!Z4XY5X4`<#TI~so7L6oN$hpIiB28$>ioh&4P?MQbHy@;FlHXA#87Nt zKv>ELmjsfS1t*CZo`YTiNhjg)<6A?4>#=*u$bum^NNPTe+l+z)MB9uwP8vdKJ$f9s zm04>OIp6u=8X{x^gCyY8!f8B&onYdL`w>lpxy+FkIgL2+7*jd_NhI|dHb>#%6tXQs z=q&BKa+#Uc-Hf=katfCQTjZ1*?HAm`~;0mLL9l>8)!YC&c+A!{0CX z%=AVK51%8nGPn^av`Pck4`uDyU)s6}*8?%e=tQDaM-hAP^3swP8VF?-l{G(loSShWCTU&^VZDjBuzUjP<@A^Z%4?~H!C)iASM(y zltipWlQm~{I$(S9sM`Fy>wl@j zmWAYtG}GA!66p8;e~R*`_ec45&zc1%!Cjve7o)6-K9dTXNdm2>T7M}35E z_F2M_yrQylpwVAf_%2U@Fz5rqVvGa%Ftz;IDOS!0%???Kj;S|(?o28;;kI{7fe}+C z&WGd>&wik7Xejk!IR=B-(=vw(-PLsEN0Yk&MZCit%cLEK)*LKp0Bue*O?cMCag;e% zP2vx}2rU_k@KT>SKDbP8Az&Pw8beNXVkqQ0a!r^=&M`PTI(nT>R#V2Dl)AVEjj0<( z$64WopxUj57PUo|sLGxd7T%@(NZdlaQUVTX;`6)R@QIekLQt>~LII-AB<>kcEKw_< zGq1rxop00OFF4{>TuK{pqU6fJP2A9;t+}BpAQ=nP_~r}0Gg4I(4#6UlMzk6hC0Ay; zR9@q~V1#@~e7qsU$r}iTgeC9ikPS@Vd@8=rQ2F6{YC#`STUUpnr@w_)FJ8K|M^W+7 zd)s%8ZMAyIzlN&Req1{Oo(ru}%UwH?bH(lKbdDh3jL%l(eLq*3GhRaNz3Me9%mDI)3;Xh6NHsr9I~c zH$z6fr^pGQ5&)h+;wQ68VT~yRE&NIyWX<8Bj?} zp-$Rg60ZN@{Q2{%c_(smf#8KS&djxwchtEPJ$--C{z3{0`&E8Wi``OS^oR2BzPUqv?kXp??RMg*Sev zU41kQ$`GA%=LAmB+nSg({yivE+m^0V00Y)5b*^wO(#ClHcw{|cVc}}0Voj+B2WxbU z;%Jmpjd&{o!vF|h#Yb?TAJ*uv^y5Mds0k(|H!HWXv5~KMLE&tP@}cdGu{gvI|69Sc z*wc}1eh|-KkC+%Cg^t32At0_PvSjpRgbnS4R+Bp~4(dEctP+I*BA3R+i+cmNH+@id z)HxIh9yq{+S|uVil^^K)r>Dg5Ta=`Y+08A=i#x!kI+f0f0CNNk?f5-k@G(=|nA3I1 zPxi7zj{!LM%6*Q}qD+{TZpfo{WkO~IJ*b1u-I-&MkCT|;1o0eZbm8J1Y)~4W|HV?_ z5}w=$k3vzgVB#lYwrzc5qblq0R`)q*-U-Qww2+Z&155HdBnV_O_{sSXd{`BFBzKwY zz=1rA7^Bx?LNp@CmggQuKRV?4SsxPMoll=WB|6pMvZ8-_FHiq`1LR7FV5RQUCwv)4 zX;+I62ehOWkB-Q-L{SQ36S6!eq>td@fC2iC*5_AiNCOLPxa5N`C=<+Po~0 zl&?gjgbIfE(!h(Ss|n2)QGy8`jqFh5e0lm`i7+F$NOerrAW(2(_-JO9j~G*P;6jmtFQk1mxi*IkcDk*ZVv1lf6YMA=#3Kt z<&k&cIR<`J-b&wP=$JH+8A&?w{}L8{qBum3XvKSCW`QAsjGv!>X}X6E^%q{3orSTG zT|^YxHbwxa5C{=n?r?Po5h_xwKHWRMSLq%G$|Ihjw2LFghA!?$_5}=7+_-ZGj~op- z)ebl3e~$g7GN{_(ft-N`iF*Hpu0TO^;YSr4Y?9_XvRgl#6}u=^fKyCBsV9aZ<40r; zVc2y@KtX|U|)+h=HK2-v>X zrehv1_MtP<|EAH?7GAZS5;_v+rkhx)hgApKwZ zTnYk%;3>gt5LZ*&-{!&8wR7jrRoc}}k)?5$K;Cy{0>VcDA)@~yIvtFTPJXWYI%a%q zEDX#)shj9ITfi+O)quy`kh2a^hqC^IF@ZTG_ z_3sjap2A9cTlIpS9pOk#YO}y2!&N1s5>h%*q7eL6_*E2zUr#E_$lTehyI)*9tl1$9 z^*q>4d)b|A(-Dgn^R;gd&^VumTnnG>X(HL|a<}az+HVvkh6_C%uTSk+n(5<0S@x?t zj~{0R65LqyGH`e^P=cYykqZzLp3%rDJ<2} zI6|yun4fn8%~#$W-t5k6bA5!;fz&&KKyvUo5$KxGX(vCfls=3eGsy39E(9p(pO0pB z7BaH|5r+1h7-tDorU9}hlx5WWo}pYJ^3|`wN+nc0&4sbh0ue3OTHl(t+W(q)FgfS+ zRhrzPgs4Sp)&?RGx2*9A$g1RqCo#@XNY7EqQSz_eyh-Pey&aej;1IY$lqdj1aWE-> zvm#U>L-=EkDj?xi#QsT+w~{1H?$gz$#qJZRJ_ZLyVj+->>1X^e(Wn}#{u9PDw_7LJ zCI@JKUyNXYF(nPv7It?;>F+y=*G7B}B6cFg8+2(P8AH}yLSKM$v@90BW}1fCQ-GtW zhtC~H(M%N3_yh?2;O~dgYf=m=7)AW!I4yGt3twl(K-#%uQYs1K$l2%+R#~t2RN>_E zOfO-Mdbc0x#txAST3l9i59Fw65M4$R4OK%BLI4A8cWFLc4nY@#u|=$?`MsW>uTj|p zV8@&h?1(!MnnqsQF)oS}{4^Z7JxCx32kJ=4Uu=+HV~~z9)MzI#KW(UGPFY#)NN=Ml z>e&GY<1ZCq;THyJOM%04b90AwhMh~p)j0%m-no8&fm^y-FH6y>Lo}ma0u1QaPA{+^ z0Nbk(x*z6W#2T806R#W0c0u#VND!H3X53J%NMaXJ;k{A7!?|bJ%pa(IV7|o0!4Uya zrOsY94IR~Y%whpaxwWxqNPr%|Ks@ZeI)?$R7DQhPBl_za7Zw)P_34A?B2h3P%oI+S zXg(yOqwL8kAXh{~i}C10uTH{EPS%k(UB5lmnrp2DpeJ%aDHEUyv`v$y*f%?+jrH&?CnPl9bi@j^O(GMx`E493y3T-#`mWm-Fa2F zR{0KH+0pbJ)KmUQ4P77I@m)0$zk7?Fv3Qjpf=Yspc=|LB-$@WdU>Z`UJQdO0%lNJ= zFJJt8M$lVPR`%|GBGyDgd_`dI1Zt`nkCe6WO=(V{^A-EB#(%Th97I8@ufKz27!7r} zMUF#34VHT%ED{+eng+f6JX&86NZ=JbdN?cWDN3YCZXed}8jZp+VXO z*wG=tzx9tsuD~}J(O>}=QpOQWw={NJA1{soY~1Pb!Et+UMI^TTd}+jVj0jg=?l|*R zaeuCgWna%*Cyx0Bu5eCC#yzrsNC1U?I=&7Bs4#gk>d504r}r<)(lanLz!f-*PZ|^y zMAV5W0~(mrHiBWXf?loUo5auHJ)ZVpu)yaN{Cez*V1iIaWm)6S3xy)aMX>Pj+(h*v zAo?*aoB3}!zRUU6XBtGP0^m(dXTbd!MFV(gX0!cL`ySHS1L{D|h+~Lglyuij>H#qs zjFO(5F*bkzWuX&bFY-chV!ydQbX{maZC8tGSktWo1eFF}hJ#eidzyP|F?Cy7Z4#5$ zpir)BYNE!pZZrwV_-}mH&XZC|KCU^Zj!Xc0nwY1Gd7`8suF>v?o)tTW`$T~MKoPN( z0O+smi6;qyH^&s9>lj0nMW?0jMs8GRYO^D#BxzeieP5ys!xL;U!%TQ)F0LrFV4)K? zICW2GA#fAyfG{g!67`d3a$+`o6P8oe4RDJeKL$KJR5 zQQWj4M-xm5m?(9G#F4o<+XD`3Rg_38#2jL?^WLOc3vOj zD4BsAeUd%K$<7`eZKkbUEvPjICy$_@;IH-!CM>rAvUwU^!MPtF@1Stf#(^#K{QXD$ z^UW$Up4i4p+4G%Z-&Hr+8z0z4cJI2{QA#j@a7}5Z8C7?8muOF30>(`6w#fL!4qeLI zOYOgcW_dNK87Ve4q4A@AZ#8=_U}27V6!(pATad&ZL8o#l=_v9A#6bNIe!|&&!o(eh zi;~`JkDIB4G#wp93Cjp^`s#8~a1wRNiOJStXVae!lC7V@8vVDb7zq#`&$hM9%Q-we zJU`oeboDUF^{Jc^#DZ_xtyw0dwt=+loEGP$MHdGBI1poMONN`DBWdQWD!9$^tMA;HYf;;#7}l+j1zP}$wy^ZHh97nk zo`dx)4gKx=Tfix#BhnK@wRF4lFkl-%)T@eY$vzir&ZFHQRG}XV9zG;_M;D&r(@7udQ&rk9Aq(JgqPoJhtbhtJ;rL4w$wF*xv!J#3n@hm%f0EAogejkW$~!Afrrse5nBr*rdo}KH|z*{`D<(2^`0-3`K3B5ZxQkxCECL81^xd%Khw)}@CPBAO;RtqJZMzy1PzXkLE_xdnlP<6}aJ z+RRhzKgkf(w11V0=(UJljPS%DFi|sUW1<5(@Z@TKUf$cN@@pK5M!=xg62v!(+=}(t zaw1bFBqovzVM(zE5w$^#r=uoX$r<@$820kio{x)vjI!IRP44T~a1eeu@J}`1nT7&Z zcGuOQgT<^LX@{@eCU>91^4QP=l$C%99F=_KHpIoxUuh)~>B>HD-iqm6v2YxAW^$jO zXOH7ZZD? z_ZN^WJ4iJk9w|=TXI?tg)D*?>CXj-WdH&C5@w|NQSmZ?PEm6-rYlk_r1~R$1!lQFc z_wJDdhedx1PQjV`q7fF}Qu^hD*PIySGrA1==^g2PB!YtKSEO1q*^JD7InJf{ z@XGDY7u5>ZBGXTy<5i})cb`;wuDWNmA?~m5GTFBj4>c}?;O#Z8b8?D5hs);7X zwB9^BS!yaoYLfkWKLr=Z!?bSk;Th|jg|fCK{=|ZS0*6@E%a;@9|4j@c(vR3wUTWbZ zLIE6mUt6J(3qkK2rmM@GL|3fHxUg_k;Lhsv3agv>(tPVHN`?DZ@G4EXT+-qzeUCH> zeN<(oZGC?*;STA&Btd8#yv09R(?=ie777IXCr#A z=k9;(#jQ%ENdne%xoxU8{wpwfc^YY{fLrYY$9b{oy_Ivkq<&U!AT-CNJX1FI42;Jz7r|=CoG&QxC36`f)9j#UzBa@szO#G2@9T7X_Aksme6cTz4J-7vEUrCIvKxnU?9l)}cy~S4z z55?{AXo|CEqEEjkW&OH#C^h>_Qo(xQ`pjXAit93!i{F%%`z}ltX!F_kGj&G3W+MEF z%`lCA`1f;H$qGOB;W!(=8Tm<{mN#2VTO8g{|Op4b%@zLoM4(p}`Muf!pUtls+|O z+*4i8{$Eyr2#=@SFq!B6XBib<(@pD*5rwDE)3fH7n0z+)_-s6Gl0H?*=)BwRq1k8Q z+N|3B;0ITQ!lS=2@9+p3!#1zbT}|0b4z^p_1>pknOTr#rUy#`WYZ$65oDJMo5@?E&o>O6}?a zP3D^;&dLXdjg`0C+KNj?eATKG^&Os*l5f3Uz7094lKYe9%z&#`(WX*8lKV|F<_`K= z((>JHd)b42sb@d8V@1|UjNP$!c5I+iV&MOfSW$TbADb`zJSpEjhppWBD4pdsw!8x) zdHE*0S4&RK4Nf^itYc7mGj1OpLvdScTHj^V8`CZ~9sLTi7qt)WBQ#Emtm^Bjp+hbDkLFw)4oJk#&hB%dEZW7ALD# zru8uJ#OrG@_hiwP`u-<`21^lM--gD$m-pSM;Z~XLUWW>{JM6);lJo){k zq(Z+I3|;yACNZ4Lfc>zi8|Eew*DB?yOnRW_y7ZFdu=ZD1gVfm%DZRa1W2T-hrnUjc zAP>$!#iCSl%Ii&UT`fd#F-a2UnuNa@^AEdvn{~*Z_%Y8H+Up(Bds&fa^sG}cnI|S( zS1M0!4?Bw>=YLPsPG2rIGEI%w(kzy}KC64u-*r@r?ceG>qcEz6!guC73NP|5&y!AjF{`D&Pftw#t^jjqqo>D{ zbX(S#qEL-2FNd-Ll_|#SPcvFuokAi$rqQT@&4}HsE7;xnggRKn&`{}^jw$_jCXu(a z3SKGOlm9sL&YV|K)?H_fNkQx=HQ}M9EilQU9Mm%>VaAQS+$*P~_fo6<)dKtO-6vK2 zwhT^Z-cg9l^BVX(&MD%{(zRMQlJWD>+LBYnt@U*Q{*c`8?FP*Q>Mz>Z+p4xx^jKKp zd}25(K78;-Q@)D=^5sRkU2wE_ddR&Os>Cr9l)G07?1FH<8FIUe%R%e3*e z)AD!I>}M#zS5|1}NxnY8mWaAi_xckrJqz^M9$}Eh?xzZE3l&*!40eoiNZz*H2(sSH z3dNrvjc8ZT?#(89+^miD4{t7;ySM+WG*r!WxP2s!*rrU_kidDoLPgrC+{xei{F7<( zo&(c#vlL_t`^_Iz3rrhWmv>Dcb(aevU%y)@JL6II z_(b^ zB2$~{*}gt6KvJ#p0yy6z1$mqj7!wE@CUz&=(ef4!eeEXFWanj!d*7EGR`FbiMnKy z^5DpwgJF|mMx{aV0%yPLrtkN(<96QTC-a`Jsyxo{+@o^uobA>6>!&lXXKcN{py|Bp zM03@*Qr05o(U+gxJ1y_zPw%#*Z3)*rZ&iCp>b{9(W4(#yg7>oYqWP}CHxo%2d@5ZD z`VRJE6{*7_OWgzVJ}qUT`Fp))CjBeA-bvD3;F=$G(%8uIw2eKmM^D&0W2@t>qf(LY z=#2{glXRQx*@?BQ4WS8HZlbr%EA~c3_KHeNhbeqRQhA^-()Exr<+n+{L4c!91yw{~ zhc|mi*KC-XUxTMwfZ{2$vqEOCB zYuEa6`e}atLMcn_#o1i+M(|X>?g|xVkQV?Fai<@Yw8u`CAi* z6?=OO8za*5eSVJ)uI*boTAgv+c(Y2}m9E=r;@dL&wE_NmkpwgDtP_r$d9J2uh80QS z|JZCjj9p?bpP3#z9rgT~mC!#OrqA0P@IO%RIi*DIq1I@wA3FQ)m`wT}X=}Se5B~{0 z7uVs^-gu?%nYV{tSzk}psy);Gs=@eC(1*sh$w^M`-PX;+w65KrY99NnN31*NCiF5p z+CSf~u-yIP+{|fF&mD%LxyR12)Vm&8n|93da^CI!Bvwd>PE;uLl1|}wF&c$~6S+-e zo7_Kp!Y|WvP0(SnI%tWUSBR(iJLbU;14yalTgPJ5R(VtAXng zGa0!nx72bijjfX|jFjs;TgmrN>HV%oTCdX{Mt6_bbfru3_K9pcX3Ng{fb7`8`r7m<`JArGU4O%ZS9RHo&gR~v zKF{ZrJJu`NGJB8f^yQP3(bu=HIjBLOZ<(+}+JMQ+V{deW8=~nF{h~$-Q=+k!B|jZ1D5hY-T&& zUnDVqV?sWcdw_+7s9_&LVugA6Uj$#2&L-Q9oXyts;QBElW_GLdTJFl5v-T@X*_Bs| zhqEFtYJBau?~dFWX{dd`jx*GwxIymwxCQ(A&G!+`0Bctb%rN z=9+J>Lfq}KCZ*J++_`Jxx%En_yyYKK#%9&1$qo-s9z6A6@Avy>a-3tMH?t=Twdp-9 z`+g4}Kg=5A!9O(_wyNrr@v`;l_eZ~c2aMZ{9&~=|w3BEo;+~uRW$kj(C*vo3*3AYv zVJeoAvy82KNOSj<(z%7|Gbv25TR*s&#WxqYcF0Gzd@6vI)>hv7K0B|Ar_&oD0d z_QGT+UGV6;_bIzfwTq;7M`UfKzZIbN1_lN*x;JRttbOc6cuc1X+@?$WW-0gHoZ_5%)52vbJ}^UHOxrlyb$^v+ zo35+dLss)|XqoqBu(=IlpDCoii47YP|k_JzDaNrc$nlgs*9i>p+X* zq}cGy9LrJF{;SRJi>%7%1V_E=GqRkOiW_*kIF&yWetCj}}iWO1XDYq%n>9 zy*bJE%{_!EbeCz?BXz^vE!olK{Xee^&{T~F1}^CaXVKR72;aF^&Y@f1H@~^GbGEuO zv-WMV|3 zldxRaxFvbVZeNA!Cf6`#z9K}V{s(@VkA^z8OwN?FkAutWy+v8zk83iP7X)$+#X5QT zaTHOE&e_%I{2Bw>X?FJ(G#x|yN0>-Py?mKJ9e7{b#jW_ofA*HNq$LD^_-m~lmwRo=R8+3YqJ6x=*kv8i_24<9N{Z?bSC>L=jQlG z{-JUUm#JbtD|Z1JJ-Y}LPE|@TqlVW{J?1#I!D2Z?$$zhxefR9>RDWiwbytk#R7O^( zt%Uu}3Dakiri;g|IaN%*JS-3R)|sl?Z)++w6VS%u#u7NuG4GElA+(h6U+t9@L#eG6k2lR@#pKi2F2^1qIQ zfKtZ@f)`jbr(#9UM4GE#bWpq|k!bk5Pwy%cQ$?$^_MUDmH|bSSsEp6yOJvazJAD|{ zYfC2;8N(&_N_;hdb}Sv6HNDGzUXd)dFxc(FZ#Y+xcoLxZ9_%6#H_3ixsJ40UBHvc| zGpVV&JDs4L0ENz+X2%9x{RA#_0Qz9T8KWim4V16+C z@8quW111+^nod2I78u-XHBsFlpA-2^c(5|UZ@@gH{$|vg76rXXU_g__BOvA6XZyEVhF=Mmk!D^wUg_H_* z*g5wGvDJI-DGiB=>T@2h9#AIkCUy0U@cZ1r0`9qQKZB|U^q7~d#?Dx6s#{re&rOg> zNE_vLh+4RtoF!*E*DS4D zO3zrb7>{X5D3^_Dd{w_C89F-9X8b*GX3tMm3c+{I-H$}FOinmFye+{RQ|HOm7n-{LVJE8Ss&Q>pYPjiLBmiwCL^JfAo3_A;Fu5t`p znHR5zOchM{cErrFbj9TV^bc@duC3cPrtb?XVgg#+QMsP?!h{PyxnO1BK{QdKu?>6Q z?N5=dy*$cedxoFd-?Xu5ci7%{0{!u!&K~?8Djd$Y47gTC0<*Lw`jtN#Ecs}-iu|h! z{=RongQBK))}x_ZJl9HXG+EZi=!9Pc55xWPH{Jcq&G#d%en0!5S(tU;mN>%zwOY?y z#Zdqn=FK0=|5F_n?K4XKmwm!|dX|s0-b1i4CM#d+-Py9iJ%938B+~BFQDURr$krz3 zO3m)WGmNRl`{SJI-nT|7`E;(g#bjOlDnD|wmA`;ltoC5bVrOXf>r_Gky4hQ)bbtL{ z=PcX!pQi*`v05(Swk_NrA3oKqX&pPcvP&l*A~q^y%|&TDcBRwn?DoJ+x7X0-yS{vB zB_I<|;Y&IJe@wP1|D=-ba?Q%-l238XlOqpwbEIAX?GgY?x|H4N^b+g&jKFtSHl9gU z9Ww0RdN#w-$vf9=`yf&Kj8>&zUOEWY^}n6FKWsgA&ir76A6FYSg(ZL5$}LI*7!~PQ z6G};rQR+X6zc29TwYYU*4;H!prj_iMM#{> zRu-D%!zsfuM2sDa;}%NaPFxw=>|3{dpm@eV{)=Kso|#62jg6$ zRHZ4g8S)Z)6+vzM^K1ylZeFNKw=_tnl!S^qlD*gR_sV_2(YOjEX0 zQTgBv(x?7oBSCja0!hxQP53G3>F)r>Kzr)yVwe96^q?GJbN~1U`K|-;#}7@9tAZY8 zxx8sY9vYa3I{`lfKzJqopY)kie<>{}Io^3zF)g8InOj@u0*uufAmjT3=&IjJSZdA~ z#&|GpJ7yXJctj9tQ~vg8zBV=fo!hr_0Yfp0;K_pQi&{$Sa2|GDeKY(k`MXhWNP)yl zePm>Zv4I(z$)MJl7!VhnvE6!y%Fo$8b)y>z?3%Sall}_mV{bGx@l^}31_mtX1Mppl zG|Sdy`9Axfn?NFA=mW`9D)Ew zKt}oOXv9+AvdQl$aPVMAdHGt{T<46erXBE>;vX;N2>}hP4|~#mKI5CSJUpR5@IvN3 zUo&OXz$X1L?fgU|*ozq5B9)&fC@H^KI~oS4_#(rvczOZ7uM#wHa`_aGdFO~UXwAd7 z)d8THGp=<}qb~mp8E57NW?{U@D=1iQSYN6W)QufzY_9;h9uybvXXg|?wQUzYJV)pK*L6lgLGU&h-<9uc0oPPjU40CYTyu3i zMbuBr6GN91D=IR7J`)X7R(Yg-Pw+VNw6TW_-V)|go?i;i=8iB^RGAu*$&ADCraMdrX7+It=2BSt{ zZAwa-Df8q7ki0cvs`Wvfav#HtAum6MnD{!Vvt3L{-oy@yIxfNo zaeW302*6`(Ipd}Pz#?yb-SI_2g8lbQ;0TFsW$;vArPzZxvS-b;f zS+Kc<&9VwooguQ0NKF8@@>N!rh1XD-%e5DQpI|El+j~>cH31ye#Yz=~rrEGyYIPZx z(;qo)a`<>w4~{9ph6E90L`uMwfk*GJrF>DmyiC!~`qbgIGx>tAp1dyn=*p(&B)gL9 z!tf%FC5hkkl?ME^Emr9knFh03-+9>{%Ps<`Mx=G{7|S2ki*)VqYc0)MkdhJ=9?`oM z=)+hGS=x+mDx*iEV;sYjxT0~$qiDX~Bh1Fu7B*_-YONsT#lyuF3D|=5^WD40by@O+ zvlZ7uE}uVhh4J$I2rR)|791}DIg*f2WEpfZ@#sxUOF~tEUxw3PPqS;Yc*&R+7WV#^ ze_fC!TXT}X=M75Y%?Gu(pYto)X3QjsH?Cjr?e~N#SwIHxC(UQh_z@8^JTOk$&@dkd zw=0WdSxZXoZ)4*n2@cPm|K@l(gS&8B@YC>roY-eaV{EXr867Q5^{)yn_qu0fq&6}# zQUiod(}()YKQwa4SZp}TvdcMTY7M(2-uXT-XxZ5Es7tTB& zoqtRpQkn{Ye(W&F;5b1*MxOXv38t#>)aL=P5oDv7ASLjEx?0v6unk74Y>5P#WU+t+ znA^#AsKbN432F+8u*yWXX5U+$%RZ=g&yCCpfW-^IY8heoo&eZfql@kTIQh3Y(d-DW z6{e@tXa-z7S-SWaU1N&O2GtW7a^WAj{_V@@0HmV;C~H%^3#K0?&nH6~nSqh43#uOQ z|Kx`BeSCasUDPN3xWWO4jr9fsj1v@w)9ej&DI~zs5@I7=GY(m+C+B??W$v}Pr%u46 z_Xd?e834Wk>URvdkn70A1;AFrutjtN_(%;12AV>==j7lRM!?zb>2KZ)gnx$ROv5Lx zt81DJU?wzGVfl2c;{b`j$5m|&&dq3fNhEwoYym(SSb}a=#LSyB22@Y|S2JQMNOJObTgEPy{UwdxC9Yc3>sVEa(}^B$ zK8ce0rp-%f>F_ySIB+U|qm`#`qK@#vJT2p0C<~SJix~1jv*)no5n}Ry{L1WVuMAei zmosARyv35Uvok+`9u#w#lupIuU<)n2yzoM%hT(WzoAV0DJ7;D2yuLZNAE)PZotc^b z@822PIoLBo3!eza#fqTiQ?%#qkURhQ6WnVFN^0t>!bim|hq`8QucefHG@>JrKnfua zERk#IzKQ?*X@nj@yDh{|E83!QTp1kh zbi{Ywda%C5BPM_!Q%x;W<(^i;g)|>uY~~I09TnyGVtxnr4i5Q>brb~h)*bU;<=VWj zCL`|ZSWY(Wd;QL9gD?8d&b$v=o@M-&Mi&fk)hwLbc&+&`2ez@lem`Oj=9Zf7>-pv( z*L-SG{=-9#Fkrn=^4V!-7HFJgQg$8wh-9>dU?9A~=;+#v>}+Bb zg3Sk}TP5t=fkiVpBMzAkB$z$h?fNMdD#6S;8#E`v#_C?w7fkA4JCjp<$NegTRP z!uzQ*aZY$L!CSmGr~G^eP4O1Oa3PAL$8piXh3A=_l@$$$&>+qPcORgp%0Pa2Ohgk* z?lNf=pi2VaZxGG`;sNkqP$;#0(({fEcc)4I^a*G9-I9QXNptg=RENS9Lw~Uj`^K-^ z6gpXiFZ(gG)e>KlUJ zn-id9B{zhD0(?PoN(vURbO0NN03`3_t0BPe|Hmm(=6cx<{xy=4)KLD_pSRK_b*x>L2|q2zI9~fEeTi@O5}e=2bvRgs zhlBCR-|ro-EH2yj#?j8OupyXx;LkKYRRBmO9vhJ!kM&yN$C0G#=a#BQuZo8kC|6I;E_~`N#tx6*;9YBI8N9vz;+o0UJ%!a^2yD^xTzxB&5holpAi z{VUrab=oxIyritGMn{|7i-Q>?d!I3T69X2GHX>R6Yjb>MHO8gvRD#L%5_4rm4_tUO zIOMi{h}>EqL9rX6p~D;sAaZcxlrFyU{L=46qxXJqIG)<8w8LR%yozRfC2$%izw%aa z?~bAAsyUi*AbJ~kLc7;V%q4dvmpG`!B4Ol9ZGGn58`${NjTz?DC;aeeIJYE(0v9>PKHJkF05|;y zhCL>bgCSyL<-DF;{U*@W@?8F&>1MoJ%YJup_V=Wh?A@=$uK_*&2__cpei!*|8j*sy zT7hJgP|LgSclSPw6x^mo?SCdk5y7px#UPcCGh)K>(r;ns0Wk?0T|8D{p&o#{sM1Xz zLA~HnX~b$ISKb}VxJzEqe!hs|Ug--*)bZC=1t%Z`dmz7Hm*4mv$;l1ptAhZa zI|@4t&8Up>UKCO8VXn$Tz)ASUky95jZD>t<7&Ifqz*kfRSrUM(B3dP&WCz>{kUqdq z(Zm8m0c1x);BzA)b+Gjy)Ry8wA>e%|#F1z7m*?O4*f_&7tMem$a~fe(sxMBLI%Dl7aGML<*Sd>IO&^%1O)(uAaSfGC!zYMEZHBg z>&`OCPyjCp`T^uhA&L@~7`yw#{@i8B}DkbsxOHZ zmyoavK(N5RCWcf3SZYih9CjWaJci!fnUVZ;I45=&XCdF-DxLl6*Pxe6$729gGy*<^ z+iZ0WFQj*_X&497>U6YlZ*MOc?CrPoi-&F2w0}Vw!2aaM4z1vb{fr1uho-6M@KpnE z0vxyt=;dH)3rvbXZZn~eWuGeBRHJ!H|5v1=K2zi5`)|KDGntll!-U$%6zCOU*Kr)?8g8fh{R)nj1;Exn%?^)9(sZB?J(%QCaDAq+NvPlJvHI_fisGACX9 z6Wv=$<9;hk9iXhtlA^h|wMD?DJPzuLjSmU*dJ@$q`;tLb6L`)5Yetm0#I~lwuKsxy z#4#t%j^v}EK#~b0N`vPfaRPnR8w~6=fCYmJ2J{N+bktF+ zchZzQ4u!F?Sa<*VA(RJTJgxuuB!o~kfsyqyCMHSf{*uqvaZQ|9YT3QfGHTaio#oZ( zD(<&ZqzIu{iwgsV$VCA(EFC-wZHZ4#%A0>*^(sD-sCCChK_}&E+MU?+T?fiU^gfo+ztvJ0^GpH(kqoVt1m=1Cxyi3P24G zy;mtQyR0>jTsksk^`?J|`1*U&NW^uvhbi8t4Ox@^^JjW-i%-dlC5q2DSUWSgL)qbD z$)h_Twq7e5nLgtDmh}};z?*4KNl{F(z~-g25q!vL^;mX&|KJC% zP^+u5cMY+p*FzE-&EUPwvXbaTV{q0~LrFyvpmceEo78Pf0zZD7_nGYSHI}2_Z^B}! zFWNlX*0Q~Pe~Z_S`J#GHPe5D5Et^hGNXhXX6hgdIw3ZW;GjK@7XgV>!os38&`;M$8Rw8N1hc0+~=kcGzc4)&;8^#?Q4FX`T&~p3?0$ zi!5n}G|~qUUORy?ZY})ITI4osGHO21<<{D_H1{J%eSWh^5;gXAn`DE<*^yLb>#$Fs zu$Fs^7go|J5db%N=Fz61e$_pCM!Y|~d>FnzbIsF53eWx~D%7zE=@2C>v!;-_O7OhW zlucl22Fg=HGP_xRr7l)54hx#%`kXAi!%*Z6y3)%5BMPa6DD%fa%7Mg4rlyZRhhl(N zg@$qV4gSiRAlvp~vKNI)P)=U@*$HhF76F5;@8Mlw%@Hv%$*m6F?j=^J=_oa9BM_2W zHJxVPl=;sM6h=XcG#J=HsoLGW%(4{2wms%;MRyZL%|Ul9{cCXd5?TVgn3G=QkvDVS zik$tBcDNQ-_xD->>srrB6FXN|vKU(hTznCmFRuvSn~c!iO89%Uw_sh1e~u49jb6sP zuXkl2-m3NsOUgmzOaY<7#o1hU(=Jy&2)+H;Ec5(#aA%Fzzh-HD1e1_vm=YTUCjrB# z{C$?&)PB>YP~6DlPm3kRk2`<^MK2Lvb-^K3kBfyBay8py-4YW(s;Ldl@LBOI47^#K}(oOId|pgwdVitY`lrHuo?XC;}!VNGGKso`81c9WQTxC_<(V zKt6Y>-8+*wpAc^rK*k_{C zsFBVanV$g1ax0$ z6pxL-3)Tk*GYSX@3ue(U-ifdTi};@uh$tw0Y#bLIhYJSYBQUF%TWZ*PYF+MeWv!Lu z!gTVQqb9Igwl_S@-r>5&TQv((k*H7J(Va z6b=~%LC*#)4A~0Uurye!;Cz!RZ#4106|RqmTc)f;)$kU1pEn}i&oi(+;;W-^VORtN zRW+`cF%Zs>Nf0!q>nCPz$?an=C(yc(i@{tWB};VAjifrD3gf zO++{e^xBnxg;)r^w)W-k5bKnN22qxA@?OJv*bi<>-s$K`E7&4jq-WsH^ zfq^k&BH$@~9~QGNVnpURII`t~mgx&uY244A9ij$e9ni%7meaS`qd& zhSP{B+2r6SGa?_OA{tIv$$PJ(cb)%DhOImN!@X}!yLzJpLb`>m3f)?-kNP4;uSMG~ zgpY;?26h+?jR7tt+3deg@s0i7-H)NQQ1GvQ#3Jcmq0%e6yB$>fUBkIHh610Dha$DK z)#%`)PQFOw%61KaoL*UMs!LXo6TpStl9 z%MV!wLtuJSq+L5vzq9hN2qw^DZ`|y4J0tBSEO3Yzz4r%%T6J3k0WvZTm|%8~x0w|9 zW#kv`3_1g;_f^Z?<^G-_4F;l1&yL=sI5mG zwemd13wYW{9X`R>E_G?%Z+mB1x%Rs=1O7uvmwell7mod8>gJBEfzljlX3@*ObTT#3 z2s+7Y&4R1;`z_7F`0ht|QY7DFU-0I&DK?M2UY5!_JNe26WmaEFPvrdr%$zn2WX~-P{(>&9LtP~>o^D>$M0a%hy%uiQh^M>1 zJ|HyEH{YsUb3Og-WNsx9=68}Nd2H-Wxa_qC_$2rpuF)ic*(A3AVg!c_IEi(}sM!`l z>pliwlAF7)E$i^K!fs3db5Hn_kB;})EZ8Ut^pOYjk3;qcs_D|5>N_0o@5=U8?b^pjB2gBHh#?1pUmw>?Qp@AGz0VJhTK_!F zT4v}Ne?i&hQrlH#FmZw1M@41CIK}aE1+&=2ohARuDl{sls*i0Bk3VEgDC_Rw z+DDMirnV;e}!ua%w zNO&kFd2`hq2ejcKHBY?Z`S1)CmBc5UW%C(VYVWk-y-iPyod`WB@eYHqkkjg5wO0K# z!g10z0LyaLfD9x)?mLbu-ThgweL^AFw*0%`%TP3U?mE6r-==@M<3vGGP(hyEab521 z^$&HgM@|mCI6~d8Z@V+V*o9n*HZI@|qgm zCt8Du{QNQ?NL7=4Ub+zzaS$f4nQHL9>tt8a(BT|n2V7ukN)8GqR zg#uj@jr<#91VS7@l!<|jRzaGDW)Z?3YY)RI>nYBUAgDl!mJ6u*_#f-Bc?{lG3{C(X zA$d3s(V(p@0q*d~`}=F9KOa5}NHbX{ABwN2P`SrHSjaLRli0rQSgN`G>#^l>f7LFc z0i}ac-4Njvo+VBA!P)JI>BJ6J6(M0q`NgHLSgE( z>C*nCW{K6F)yK&2;W;#nzSZSr{`Zcx;`nz79>HVu(Tm}sq^kzh8$GTQ;(-?9l3B~^ zptxClsH1Qf3f7MXCFq%F-#qNfZKUQNG>JKA-)%SKvQ5>v!R`#zahaQ?h`6Kf*Q3Vv zc)t9dkNL98${ZwzWO$^cz__b;68KfJ` z^o?OO2Gg*#Bfnk;JPEYXQ?}B(Y-@Qa?8-W#6q$Vz*xzXNP+VU+eI@p2GxaCd3bqHs z{m;!C5IPM+p4Eq4K5%R+FcMWVSTDZI`|x65^T($~{#z4noNV8z2y8sSX>I$npB)*G z93}&O*?XJvW%okA>NM&MF}jc36x$a2qMsfAwf;MZ)t|>q4F2x!S^U&(6bnmRf9XyUu8LV0#1b znDq!JP?uew}NYV zWzD#U-xbb&ai9i=53(W?bF<(_Y8ufY^8(~}!+{1_P3+$wA(g-&tqfZ*QS#LADopH6 zM`VWwN=E+6@!t4^<74oMfSe)gYXyab&`?4OTE9ei60k6(-s3@(yXRgR@>)WmO3?g6(S zKV-yy}rIs_>&Cv9~%p_FTeil{Q&Cp(5{g@1OId{(^V!Y z0NI^_VY|)Hy^`H&4qyxa3#hP8TYXgLG{%+OX4=ez2>$->c0)-EU>FtTb}I%iGb*Dq zDoNLZR^a9cdl>xA#~Uwi$J0}PtdmM8hEH<(`Prmcd_`k;`40kj(UE@=DJN$xPaCc? zqu?(nuW5528M2T&NXmN95wVGjO0c!~#(=V5Q|bU~1pqOaH@}W(?YLN)|K%_5e~s}) zWRp)w8U7%}d~ZxvZU0IViS)%PLyGR415xn!WA%k(_N0|nwuM>g_pnAYdH$SHdp?+* zyKQJ_v3>`g?9DYYw(wsoN`@wY%ieCWWa$0rcCXC3LURF)twt)4;rGc-MB_W$(bB4Y zk^8mAQluP)F(Tm-v_E5p?RPD74WAKuF!;t`zWs`gH`IAuobq9EvT(@+OF~%q8ma%8 z7{%YeiWALbC}nTyPU<1qs1f|BLcQS^lx;^F6TV_JRxbzI?{HMsJR;B!!%n~yW0N~% zz$pU-9Mfz60pa?+XTw;)xT-3yd=OLC=}x->Csu3A)lCX6aw(MOOT4DQKWGkAg0~LR zZ#a4%aD3L(B=I@n=P>~x56dtN}&}^y6Hd!opAk+az+YljLzKm z_^o=?w3~Tsw?K3BOMc$lJ%J)?GeiEuLFWkbVy{LVBR;7&Up-peQC&Tu)j!bkM`Eb3 z%n6=He|AS>qKZ9yk`Ol6iD3Z~`lbIWqd)}TVMWs$6wxCQk}y!{@(1>S1G^ znIU=XaH+*aUcTLUGb%nP#`l+bsb zg6{5m5eFjQgs=ikUckU&tL( z${lN8TES}4+h|iV48nZ7$AFVD5}kToJEy>qZ_n_z-RX8rbS(A#bJgVJ_d_DpwAaYU z_STFo+jkZh9S5!4-#$mR9lrBjV|?rMWAa81?{|komVdQV3dx=9EZ)0WXz@KD?Trq5 zIC5Qc^U#U1rwbd!LMmk+y533~4>vt!^VxlTt=R&NnVCT1v0QXAd$q8$fkdj{T>SNH zEj7hpCI%b|s?thZbpk?0fBe8e%5-T_EUH-c9c~uIL>_$+P&yU%w4*Yr_zC;$^7i>w zGEoPvg$xH9Qj(lbh|xWbPs}Q<+G&q=GBIMpqf8$~R*Lqm7-_xrC7h}V=y<&5eqg6U z$l!~IK7sFHe)Fbl8AdOfUdi(8!Cs|Op@>TKU3&R5bU8U!!t3}E*Isflc1q5>c5hDn zfL?72It?@qGNya?3inQ@K(6b@bkipR6pM_%!r9Sn^dZ?L)khMtAe;jm0^h9OBvy~T z6G7FnB4ZNxZsa=VQLU{(hOX;R_|58Y^ovuK*^;e>a}3^_(}un04}$HWs%pZYx=}sp zRH6B(Q1sp_wS0;)*Ov%Zry1W8=N8TK}e-?2%UQl9Y zT?bVRhi`kns~J*`VpJv{7yy9b`12o87hllo;9)wb<$!TAKNW30UF~*jyX&Xh|GV1=9uzK`r`=3%!w!Zgq$IzmG*+^h%F?I11Q@O5X9a7zfC z;kSLhIkHStq$M2@jFMj+jOlzqStjhYiWWzcj7s@}xt2MzuVrUPI_?aTj3I9scoLW< zq!tTYro_O!oB*syFhMj21kXb?&>Lp46P9yzr%5SO!s6lx%^OB3ZjtTD;ncp4(pp6W zIXaKLFrqAfUbL+#=C(wI$DlKI?y+TrdhudBI>spx_LAE_=WweXPBBQW=NiY>XAbGI zeA#f$Pad?T3iN`=4q1_Q^H-ZL30K_Cvtw&+euKry4=C4JUy`892I6M_he~XV`_s0x zG}0pUOiU-Geqymb-xhnW349rlrx66SAE>NaeKN~*{}m@nRMA2g>()9KY0+F>Rkz|v zFY}}^T00Y;HFPhb??|Mk)#XTm7&>FyZZG@P=DPAnZ8?epv~#E=bhY6F8|@XhVQ(Ayu>w#RhX z%bvRRv{^pe{p0|S)c zzm9%y9leK``fS3Bfq{^}omA}(L+^KrGXW~L0xAOVZE$xQW{Dy}1t%urXlk~ROXG1W zGk1l4|6BSC_xzUpfh zYZJ8-i(?TkHr+1lh>0Pu8naC=Z%bl1)WKlcj0Y=3XGY%x}pe%OCqxXu~tKMnU!I?S-%fwh0l zbX8}`^UT(uC$hJa_T=hIPxrF2hB-MGe}>~}FpFRYJ-d_+)zfb$4Ox>i5u>v^+3xQd zy2BC8EJJbdQKa}O4ENK=o$Y*fi2^9&i+y$o%c7#je1ul~KK-d4SkeAHw=;rK<+a)d zF~8dMw|6{hc4Gu%Yw~@2hQ~5Ps87mprxydig+*VwC{A*kkV?lPu0l}Oh?#SmVExZe zLOVWNJ&q<8_cz9G;usM8W{9fCBeyavn|TsuL=dZnQIu$3NUWHXGI|_Ya3M zF-P;L1W5dM7&vZK@=*-`JzxGZoU5@phErD>c!-a6goeiLI!UOPPYR#nV`=&88co}( zkxjKUrbfz_+&EkUjN66WbRw8pDJet@KYlNiPBuo(5XR&fBoA1BAX^`#yY}8$oWfuJ z`|f;V&L3Y5l!-VUNArcm$AA;eA&<)b6^#!aVW?Y};D%StuKqEQ6xC#a|I#!*+`4mk z^VjV@mwq`OZeAv(2a38SS`hlJC*Koj+#yi&sKQPYl2p4LLruiAjhnT0!`l(N<)0@x zk_||$|Lg&rX&p4Q@BuL7n-$e>7Yc&RNvs>u2|p9>S3gG3GWYVyMyl5gpPg;^d;g{* zc=I)~mnjxJwj}cM&6X9eHn2+!@Yy;R+MWLFH2tO#&b25f*FJO-~+x*Y>bu24ON-?{>mvnbfS)A8j`fGC!-t#=xEphwBBQRzLzkJcKR4eS1gH zfXb4uhQJ3}ytn|}06!x@O$6Wi!UZCVH8m`_vOGg~bS=uezN9GRel|ygIzdNA{^lPm z+U*lc-{orr0FXf?US164JB_g?^~Zq$=I{mu{1VEL7fCQPTAo)_pZ2d1ne$QjfM+e$ z*3>Ro8kHnz`1Y+xtRLfVPmiGIt8sSBTSiS;J{6vXd;*$-RIyNCV8N~&)R95*3DM~9 zMP#`cdaW1Q%s^BtAK+l%7(uZ!OG^a52Ygr1_aS6_9U|>j4w8w%G35GaDCCFPo_-_c z{Z90?q)@o&qfpaF9q;c`?`>CKM^a}h{|pgaKRBb}uMIs_EY?l~>G6cIQaDk%C4-=- z#05J7Ozj@$6eSH2boct_O{{R=K;r~LGg?-fBHQ8(r%^x0TI}?%BChj08cal ziOFZSskkFMNCF#0NaId!8PtpgqKgRP4P+8QgOW?D9xLcdGmgfC66E;J>cjv=$m{x( zq5Hog4+fm3xo;okPk+COqqeAz$zkbjd?Vamg?(My+s<@VifFerh}^7hyX$Z$8*J0M zU-3*KFsH4_nWX-06o_vc#WDC%c1Aw1wiV#(Mt;9EaRY9XJF4AJcT-~o;nK^3S1oSlS*23J8rLGEPQ7I`GLrn0*uua!*K zIMG`K2oM3v0Z=d?BaWbK;2{Llg(^48fc0a|cN0dK*mR&rCjhe5Pz%ths?v3J)u@=H z+cN$+-$IJXh4wUSi8mlAjS=62%SJ>k7!C}SXP1A~ptJ_JN~DJ0TB6z05PI zrJls7dxhwvO7>!T?+p1|Ek9x!bKUh6_94H%^bZnLiGi?-7)!<=>nnGLdR{IXcj5Bu zMOy8N^UtH+Fv^CmNlmYK9+}h;K04iQ|9bM6S)c=LwSR0k(5aR}iFXxPJS?lvclOGkn z##-@_2^D;k1vM(vqPVy+AXV+oDws%*!&6%KBN$~D&k%FqG*)@2aHV9lHMzh^_Uh!f z*`pPV1w*~iqyi4RlT9oOw)V^{dD8UP_z~JTkecPkiWUdQOQ6fFyu-ngprYBEAa&DE zgq-QUCa2(&9YR18a77X4Ki4AEhUWMob6|9td_dk>40#esNScQGlP+9)G;~y9d$7-q z8>rx;@&_5gzYX=4Dt{U-zDmFZXul>E?{oy6A2mSMsJv9UYAc`};}bse@wO zf;5q2>0a^SY43jjOOMALm{B$=h05D+rR(>WVgVyXBWqOAa|Va$c1m}JFdKU7Qf%(ZfeyDC7DDZ|OSoa>(s= zZIky(Q!t^S!Pz3{$zhoV`EQ8tC_`le97RLZ7X=$*?S26&_QJs!RtKlOmjY()cD+Qd z=lkjf*O=n^FmM0@3wr0?Ti7p6ujOk-KyC0gU6@F*IvlgWXJe_LxZ2OR((m)!2YTp< zAeg}o6}+1fivNLXAKX`a^d^{uK&-VVUV~8#m!X%{`oL}-1EW3YLcD%ZE1ZK%xnwHr zm*?A`RTzP`J#9rso#h6g{Hj=n1wu(gd{2z1>Q@Fxlm0`$oqdz#L+brb%*B_7N0_R& zat=C)liiQFcYZcTq}RH59F`PY?H`0jjr4`fu_=Qnf5OlkoaSt1IVipoW7?Z5g}Dkc z>BaF;?$tp-cF}verzbs|LM?46J98t)eWbmC?0IE*yekRQZx%?$u^F_uu+$Ph1Bh8B zH%}QYT&}(mXcoLZTH^dQ(bU`1mqhc=MEVL5)Q=d z_4zAoqxaKMH*9xgG*d7!!7Wkhvrx4Ail&!6&ypV#L~1}6>y^A}9&;3f_G&Rv;d@@a z2}Z0c{)alUFl=c|CBV}qECcpyr11&w*v{_HIs62Jr38aZxm~Nq?r*o`h8E9vpDyk9 z>I?fF82{u<|%;XgRo*dOC6k$^j} z0xGG9Ljm-hdHF#-tyj$iSy@DAFii7Fm)h4fR1gHukG$LDQ4fXL@<@Qzvp%)UFlaB@ zlhBL?7pD@{Bl;F!>r-(tZL|M_FsLn-6D`Awi%Fep@j9cf=X^HD3s!kpNJbSK@vt#d zYy%yx#!f_5JIfUd3_c|1wb}so1ZvUCkg7WSlBWPSDFEh$5}(gXuY-Vc3}Er92&a_K z{;g#*$IQ--Ab>zftsIE#GU68l42@`TmjOIJHw6Xv{#Qvd$UtlY0@uK0LJ?STk;JWG z*?}@~*R%SRz>)?sP&Cr26?75w_k)AbUtY-LaM<~7*nsI!P*A|DSH6pTi-K@Rz&a|_ zoh&kfQZcu(%}SSzt4KbQD87PhJ#KxJlM+B^GEZ9~U~9vrtraoi7!H`~zGP!aMZGmn z4#QAFsKsmEf(eOAWEc2AEOb*3Ex*)h>FP^XUtBW|8Og8cgkF$0MLBHT3lPet{;os+r8B{J^(szvl6ZxYy-m#6pENQ%H8X)Cn+|u zc4s)=DWFa7LSpOETlwKC0pK(oOYWDs#uYAL6`_#ynhrCz8^iPik>#^0usJHs4Z3=R zOTcI4o2*%wG|=6FgTqF2xMrzjmBU2N)m0U@0SAAsv3s$s;u4;drvt zE&WD6EbY41NBY4X27$f;Dn9C7{zvd@lGb`{5C>Z3V2FVMW;H-m;=D7z3(h$p3kq>c z>SO)sdI;FJv4SQy$o7IdJ>tq84RU~pjX3DUcLRhFy4dE*pdcv_%LZ)Qc*&wMU#uL)Q219#FYj+20p)sz=p$>9{*2?D;aqM0 zfhVnj{U%jQI$G%@Q3sw_RDxPPd8%u`t|R^T?{dadGVu$p942nb>sULHcPpOmWOx)Z znVkz0;4QRW1#$zPz&ySsd+n?d;y{#bWD}N zY(mDe5%cWe&Ys(6G=38lXc9w71rIA=l5#H6Z|n&QV42(IXE~#+Lj~pRwf40_ny*mbk}yookDYJ#LSt*aH}3PDHrO2POWu&nq@~>L3o2* z%K2GG+2>i-S144k((W40ll!!fpKe8lu6`X6-cp5H&4 zqnRZL^ot$);U34+istzKeHad^wgv&GOOLZ}){|33o*0HE6cu1% zSzGtbe*9k$S$J30sj8}!kxl%cX8YA12Cu^)l&leYC74t7H|!c3_&FOcs)yPrDV1zQ zU}PCF*LsP30l+Ok_VCy8b;qvzZBi^n z5w>qgJX%;@4wH6k!P5ytQ%k|;yLpBS=Ml8&df<$(dW>^(oNh%?^(N*IEOz!KzEIZn zmw^{5?W~UgrZ;_m^p5WOF;pE(p;(n)-$a2E%@Ly{5q>ihB)_h^>A?v&M2g4zy-5JP zNA+?&FfoY+bww6FJ_2Ya1Waq%0RNDHd=Na80CQbGxi}p*!lUL$Vf*`c%>xX3`c^!F zuhZcu2BV$7h!q52pQk_1bav$Q4XHO|GY1B)G4i8w{tN{rN%)D-mEXt6{wM+^m`REz z2O)F9kIqO|-(I4l5B^gdi=89OU3k7}sd=+g)MfL2z5Se_%Th-TfsDy-Bo@!ebreAx z>dU}@2QcFXeNP|wroGD1E9*YfQBZ|y23#-zw;XyemP#ort=F--V~98^@C*+qpDFaevL_Pp@#^aV3 z*rVI7sp@aIbg;i=IzV-~{h)CdLxloyAgXN>)pT?;w_8LhyHu(84o3CyrFe?y& zW_QAJj!_xN7z1!Oq8xl8YXjw>eD-Z%=z026X=A(u{4uam2(bvHwiEtNI=82!cEHgp zAiq8wI7rjy>2+^sD>lGuHD?CwhFkuLoT%SoVPQc%?@5R#cu$C3NamA*4+{VmR7OY$ z?)!J{j#CPMF`ZNJ{~X+zp7+HFGHQ02<*Se~FMcTEyC+AeBNsw`xTaD(#>&ry{oB@t zM8OVMhFJ!);y^gi-YWKh74s|leZFBHlNMchgcMAFIrUF zJDNXyIDv!7@?_~&&4X%e|7zNnHV}UhWO;j+!T80u%w1MdQJ5YR5q!v(FcVQr7_>Rs zU0g&106LIMnS>nK=pMVNkw1osZ40Ai3vMfahunJlQXMnGs{1OG+nl;LCxeHLbX_>k#nv9hd^7%|2=kwF(z33KL|PX~aOsz(7L*Y8^3-MLde&FpM}Nqzf2r0LU6R0YE^gz7Q4_ zB?ruOOiT=7mXnu{cYgY`4RXVcz-MR&hld_}R<^L6r?RicIr8U(?iHEO7#XQ^@50ft z5~D->9S4NMpjs34UQY`3J4~pm`m*8)-bWC7z(9gZ%D0j{l2}J^D9d<83OtK{KJ&td z?+Xaxh0}SRT=0tlz6=peW@ZKm_81`dUiqxyn&q>0+rA`U?+s5{fa4>U70}_ffO!X~B_m!1FvNfs zoB6pxu(%7|!hWw1XnAMB+$P6bg<$f7Y&_7$|D2zLw|Byz@}Ftj{Xf4ywby$VN`J4r z+w}%!Br#HSdfK)YnPM5@@r)Ukq!rL1n^!FPX^7xQ26O# z<^xj)kX5bnEM$BmA>K3F5V3bUj}APb%)=IP)44c4@R+GYu|0>8dKp^LJ_R>?4JiaxcP{#=tdC{Nt(6Y zd%*%OtPH(3{K254S9W($@qPv|8(T2>^&N!e01)4f5RBwMtMoknCvq{=7D>4^H57o+ z@B8{S0_-Lb2f`b+JvnfWMMPmJ$JcV{e`g|aAqI?cVVl8-hu10WW^vi_plpA8#6h>5<9@qkM44gonHhEOj&bZ-U9#gGO)bU2-Z@7&3wR7UC@| zChJe}l8kJDhr;uIW!rO7;zh|4ihrYp_0uJ=d?J9W#)9+>#~CK0Ebt7DPLz%8x1r5G znx$!Xa;gVU5=UnG*oAG^Jw2WRpQcVaL&K}vtBYufv*re8=gWhQPY~~o8dCuftigb} z4?=YU6tx;8Zq|XX5e-ThNb-Od3n)0D{&O-wom5ImSaM6mlE`C*yw_q%ZJQHqOWiQbtkY5G&U6|}lJwyRWoZ-&vEQM{@i87O-2615#{*LQ z5MTDk^>vh5?eGlTS~j9bMxCwiag!*x(kwOlU@efO!!sR?Yhhsl+{;_x4)cNZnqg>N z9#T^FgrjAft2Aox|F$NSQul3N{y+>!2x0!3S>=I zo2x*vA9dH(&Q8_!c7MX#5>WA54K{!^DO`9Z*v86b{TCVtY+R5TmV!+;1Ocf8jG;rM z9(%fst+qW!fJge}*)#XkS!wX@fYuA#T#3Nf$8k6Z4Kb8)&cmzyW`jc<>2czE6m;g~ zZYcK9@3;6gkXVbrUgXhFImEpYZ1n({-vxO443fFUe}3LKy>Yt*%#;I`vC9eRBfWnA zP{|)b2)K^&o`|-7fFn0P_~AlG&@1U`W>p~xyp-DkE8nltq`E?8*!`_n*S2OGG=PF1 z{%9KIHC4XX>PJ2!YR~c~j5rAk0G|JK!HFq;g?W!6FTuwIZ0}0)FIutwhRmmfKPWqa4-rC)x(c}6A1DR+}oCC$7pD1 zfRhEDFrfus9vt-*++O$mBfJzvqzc{}iVgPH{ssOceF{coP4tp1tf4S9i!Hv3LAqF$ z9TfT9HPWJ_3lxfOtPZnkMC-x|2Q>^HZ(Rcf&?vO5tZ<(mcdu5o`i%DhC+p_ONRk=9 z?i;Oz&JL?PcRB(5$cXOx=`m2W!%mrlSPl{u+F<8V4v`0t<9VRrK=U>gd#9`-xH~p^ zI3EY3(@{X?0yAZ;Hxh_hIWA0ILcrUZ0(*J&Ygknt`b}^oYY6@0>O7K%<+F{erlloB z6Q7VbySNzs<5T8bF5+5ZR0j9T17Zd=&4?KtFgw_R_vj7+7xuXuGu79@>viTFm@Lqb zflCxpeSjV`Ojfm^Jpy_C2DhMy4}T|&?>dgH5{8C`BF%P& z8pjcI3>*nH?F2xEsDW)JF>eY!w8d7n6BdCpxUmm;zGb>3=BqPD8Sr+Gm&7=ZJ4%8_ z_2?)zm`wNp(TGW?Wj%T$E-^8x-3l5xCwM-iLzn|xE9_2x z0zO{_fGmCe$;xG%eRf=g^i+vEbL8nRWnb+vdOZ;Ky|@Y(E<3$S^=Ai=L(qi_GN>M@ zv{s3umn4ET4rXfI-QDo$gXU0ze3J?em@bi!8daozY`L56P7FFZ8h4-6i)2Z8pd*(G zW+Y%Rv^tp4xhYCTMa6dG1}QvE>ZaeV-YU#9H~VKQZ%r2GlpfH0G;Bzcgd7YdJG?n? z4~1#$7kim6Dy@`gP3z=Bpx(;^WfEj4@?#3c0`CL0dj0bNn#uQ0ZF|?bv1Pp1ks|}# zs>-u;;|hz1p_C}|#&Nv!lUnucn-0Q`y1X#?17q2HCQ_t)#{SD-<|7=`()oO3YATKL zo`P>BJC(qw^&~$Ata^b}i(&WB0~rRK?_NcM%c`PjwHX10zuz0rd2?3DjRiFw%v;k5ykFQ*IKX;b#j`m(j zf4VN&utBM@F0Y77qAZka>_JL;&v?q>UgfrN)qA!^iOF&o2Z5Yuv1AMM+bpaRKk-N~ z@HQH5KhB(IKK-eJ-hN;<^}z1tkXP31TL?CT0jq=OE&6zbgasg93Jgjy5oSPcF??9$~scodbToinxd?E*$1-pjQ7YjQEJ(Vm7k>B{7)DvX+*X zzAGuYM=uW6)Z9E7AS6KBE`K_{H`N*m(Da;@hV(3jRu(%up#fs)@2AhW*-QpMF^GVJVFWl&q?eZJE-hio zK21eDcy={H+qVJs2Ll;63&A9z2*C#2L_Ajq?QUL5y-;U9-Y)#)y`cw!K~<(7z-K2( z@IfO~HarB>bqi-(Ixo}HH|FkCOHWKJj)t6D_7rm*9vpxp3*vJ676faycABa0s$zvl zc6bf3t`4pB(m%G+xw-_HWdZ=6m%U~Ff`-?)Q7Xt1z|>>>nm3%;Z(x!;4O}32S|DtE zMC`&zC@3ix-2okbT3lBLYE6xMZ5YH0o(*y-?~M8CnFG`3F3y+TrJ^6y#ic_p{I}t& zH~oUQ%nZQjLAPbO6o>hirAaiqFbO)w$Thm~|FVb@Z*IuQNy+}zQyDSS;#6Kv^G<&d7G-J2SC(Rb&zH8>i=elmQVF*8!*viVZt!@9+jx2Ka-n~O)B*w?bS;ARv-ptx6Zz4K1bIWbG3ZzJjeUZa* zxxWy`!O3|8{IF&pOM=oxR#so&1zj_};j;N&5a>GrOA1gWWHdB=;D;-mp@kB2`}wxC zlo#BSRE>;Mzvo@-fvJ@F{o4)Q9sgu^V15X<(Y=eFH5DjjCdqQ_jfG&@|L&v(ciRbmdtW9w}%s@hVW&Dokj}|wVB<4zi9N{ zLeB+F7|Fg$--{5_%Ypprwn)4TJoTg7HDZkg(*NZF{8w@-p zK}P|ZBd#b;+Wg{BiM$20+&?KJpBhcs3c0C&6z6IZn+Sn_Y%iRVVI9(1WK1AoA3kPS zE3{+2sI>jOY%|(#dgbV;rza1N3u9)rkr)D}U*QRrW;mjyW8M0oBU3_~R9J`&b6(8v zVEKuRK_&&B7+^(B!ejjt29Ny}R{9fZX-V8R4@8X_om6sDgnjWm*dxNrU9TMBXjxQf zz?Y8$7a;^VJ*NJ3l*=(;fEQV#*~p*x8?GAkSqF1QzmMiGOgA?+5E~Fk@6FB48S~IDdP(r;w5>%>Q<;Xe zoMv|&LEFS8Chi3Bqnd+an%x0O$C7hkQ*@@~<_5ss1P2cfVOIs3ccnZ}bKu&5C}cen zpd3J$Py(Z~5WG$hBuF^uz+Hm919+)hT;?B89UPJ?&Q`FsT!wXV*`0gY+1Vkykna-g zp~W_6BmCyyml`*0*;@S@6NAr)wFRUCV4=1Co4Sqra(aC3Y8N5Sw{NMqxCTSWSmeXQ z!%(_aN-9Tl@M#EtWwY0OKvV?(5V*BH@oOdW6G1^j zHvSA5;$4TNf98z^TulZ;C2tnml2{t&Uy$ z2f}G^;vG-6{k3+~P#34|9>=+9L9jWxTxOO*SS@ufQ^H;bOI8GDS6UkF7O*E$W#a`v znY2+s*1^-K#H{Z2SEJktgsTw9&AfGVTTngaTdW|Ye^%jCF zsB|QPG6hr^xxqbO#J~m|)N*LSlN0hTn`Ibu10_LuE=RpYFnidtmw%DlMO{)O1~ft) zA(VRu2BvHB)=XTxtOdn}Yh}&nlri#M=0{gp8D;)?M8j4b<+SZ^zihI*Czijxi$ub5 zUj!SwRF@-qc-{{trmJ8QmgSBXhefDY6xr1!RBA>JQvu%f33mU933a%;f)_Nha`tbq zp@pfY40QU@z1|M5&-FV%8MNUn0WB)nvEVfe9z~H5%s+5Mj|1%)nya8PG-q3-q(43y zG?f`be(xS8{_4uGO85fAD4tjde0zCrSH6{%JOVe)WIulJKqk9)@6{^1WG1aP_hQeoZ+*57h>?juHNr(QB?YYNseK)>I$xmV6J%ew=3pn65S(` z@~Gx!sTi4bbv@uNi;9V%LQerKZ~rJ~>wAPHVZuoSi&7{NK9A-K7|#m)yp2@KqAP+1 zzHT&(jDC4_*F?f{Ydgax@G?;;Ae`c_r@>Mnn8gqbLAgyn)^+#MtCQ4JB?g8cKPdh? zS28<_&rIZRRGX(ysLHhJpfyztI$S=Dx>FQO;|vXf0rZm)sI0lx`T_(K>Tbn7X+ z$KKf71a&**_pj2z!Uk-XB{)vDI@1D330d_XK^gD|I7~r7m_W2ncRhqf7EbQZw_KJ0 z_CY5YE8qC;uUl4d9q%?ZyPiL5DVq{BwPXPulVZ&>^p)Q9%i~FhzmqI>O=z4!zkY$u z_g)w6o#FLAIXTokJW-%J7RIbC19QVM@VRxd-TG*tM?-vmNReZt0#)LAg)RzJVbOTZ zFF}YN$(EL4#4m1v0ZqqBcM2N8YdE#grGz#DQ@C%mY2|%kIXJILX=$EdDqnlP!4M-u zi|9yzaVa#X`ZE=1@tC#zCbyKGNEPiRs9BRUGcBT;RFyv6ql33f{hNlE-O3RJ0L*$z1_vX ziI#+|NqEvm8M8nWO-)k0A~ly2Xr;k^)F~Q2-E`W)QrDD*B-?p1lTEJ{Uob~3@ffxd zlq2iI+4%6DjDau+DFd=Tx6KCbEyTD>uLvxkg}^zB>W9Pp$-7rZcxTU^AyUyCbDiRI z&%Bxk^iQ6Ag_paaoI`n7b27$nO0x3Lxbokmmt=a=ocTMwg57g>jE`lLSc0Gf14riY z@81uIcN7xR4j2KL{WN?4vsMLVWzTVA<<*%}&vFRfC53?y5K>Zvlpf4Qn$2bZ&CbdK zK@{k;X4mAY=Y;+JD+ceTY|8Q>tX!zT35lnQR^q?XN!ZxG;leyoW`8tgHv=gY9!y7lf6%DDN+hnrt?6 z;8RfE4QZ)r=iT(VqYy?#ikp0-4EDmX+Gci}e_lomy&{NP!^%ptWegrLCc+{h5QAz* zCOrhwfz8i=Jgjwa9yKHcl^57!fL6;q%0&>$-Ox#SQab8Q%UCU!{)#l^GPNLHC^Wnv z9`K#cxx>?gE*UBsn()DlQz-wzBOPJkfp1k`B{yi8L0CZt?jTUal^EgsB-uNe#4SL} z?ZmIS&v3X9J>N)$d|(hIB&Ir;jGqP2PaAfd#3R~rat-~-RH|j$^sn7p7UpU%;@+S( zXxdE+LpTO5?`zaVbOm|bAKX?eFw~_v-k$CRX8ihW-3@bxKI9V+B52kt0(#y<$gc?7 zK5duBjhAPAS;K+UFpXE1vClejszxXjrx!$eX3-Fe7{8QbXw50+YsE-Gh~Y>H`^6Dv?iv$)d=RoWWnx z5-iRNq2bMl=c_JjSfY;L{rloQe~0^nx%L!q23UDnn5vl7 z9EI@+*>r~WK<(pqeN{G4v>G7NbO5oNM`~0z$cZE_B_(!fco}j?yN$7-p{F>+n}E)khM|iS3~v&Xl46RB zzd=&*hpz&c%EqRqXUxnh_@?8f&%bp?i{2tzO}5)Hh9-*B3HqnOG%Qq#wZ8egUg#xv z6SV7;9+6eYZ)_NrY(uPiM{MMBKBdnIzXhWH-pNVZ?5y^%CMdl@+1*#|U0xY^n_S^`j+v;yaP4dM{Q zHE7?2fYbw25TJ(zS4FKnTHY$o@o}oPaVs>prz9l2wxPLAWQrbqYUTYMSbuf2?}9I9}vTb z$?nF>jhVA#naP*u{b+;%q&3faY-~5&Z~7*UBQ`gcP+mTHlF%On;V3g#1{ZK3!-m4B zy)5;B2BYQR2m^b?ATXrW%1ehX5I*5NbpIi@A_EAtX+A+k84pt3{r+{nrkjPub`Yrr zN#gV4t?bfLXboE&uF1jG9=bWoix+Ui<+5JG6hs|Vhqa^8`*c&< z1)xF?ySu5`8GLiDE<#31vN!HtoSi|uhZgsS`C~{*BFQ?y#j8FXkc10M0^I{B6U(Pf zp}jZ`WyW0QscRPXRs78*E$|INT-8JEAzlK2(NWP-B~a0&;=0DOb19(;16ByYZExZ1 zRAJODeEdU$!%-9G-`=j+8}SC3C~ylG2K{Xa&x2;wiRd>@3q8F3n@5Hi1Lrd}<4Yzs z$K7T>{rpnO%T;ZpqBzZDK7UR%w1)3v4n~@AH6A8YouxMtX#0Dj`91yK#K!^{RKaJc zf%lIn#5bxD_oAfH&1Z~^Df#(9;3>cRK0l$LXk@5QAMrX!cy0a2A|oG-RsLq@cly^0$ZG*-2PEw3aj{0>u}mGunN|HLOMLa@fijW;I4(ZFK3XguO(Sj9tGNyq=^ocAWg z>U$S62l;Qk2+H&^vazwnHYb$WYoSNye!QbEq>R^DWv!zx|BFZ5b!cz#aJKTd5@1;S z4G3bRJ3R$l{;u`EWfz2QC=3IH4y0WU{c@ZEHY0azEM89|I~s;j6gi z?x_A$Nqq20Z}0A2_NI*sLZ7;)kr53Y3B2dujdH;<*J`ivA#*~%0sJOqV)I)t9YWxh z;pM^jGd6~M@Q!clov#z>tTO4h&65YY`_^Ng(lWPwVhIj@>9NxNkjt_7`O%T<>4@;) zx^Y+B6)rco3qlLi<@^urOA9Za>Z$YtXR9yugXS!tN(v%-e(j$q`S~^3$Cy9Cf+8-K z5OJXP5<~@MR)_s|;u`*k-veLG2!Xjg%*&N*5*t2z08Twf^-0;-s+S%fzEEXc=DYYO z2$#1UqUMs45*R2$lNt)8>g#g_)f|y}>D8X9@iOLyX#K!%(>ap@$QZ7He|hHbf3sS{u7lMw#Z`K^ z>xIL3!*+X09I_ec`%XD-=D=AOxajKgWj3^5!h+i1%g;dk7`{wQZ26W+GdB>FwQxSs zqy-!o2aJ2ky~A!la9TgP&USpdg{RdO-_)y7GScw0iYs+k#qu-w%;R!E~$syjck- zj*UiTklE;be7}B`Kt`7W#6yvTmG=43q=fu{O#NatC^<*{`jrhsL5%dlzzKC(vvs)f zjaPI3h~pm(iiv3|>J@NmH)|={YB7XfyXCMFio^ApeeDI4XWjL%w5BG1jgyn3?M}^T z2OJaCno5+d$?%|HtiZ_}Oaj#olQRCi;{|YhChrVGYug%0>Mu91a(T~!3d&qM11Whh zHxSLtdLY-!IW;9NcUSN$eDyrUv>$nEB8QeC8~@9fWI5a)<>g4Yk4p|+Hz^ECm_+1-9(a_$tE6HEK#)b-#D^Xg92IP?exJy(<%=zKuL|@l1 zOaF7s*5ortDtNTAg}Exs`||Qb-eXV`%T@ikfc^`lQ7$ZE$@G28;~yS<`)%YF0*9Ev zR;wHxo!f0>i>Fk9FU%)7I1bmF`nse9v$Odn(SCTmJ2_pf-Zsyud6Ekb=eYN}eVGf> z^koa3PFBcb1Nu&8fSs6cHqi_r*#fQ`x1gK(&fkdQE}#S9f*R1yYxmKTr~knlQ!jKb zO(sV&?#A`MVqMA%n@&fRtS_-@wDO32;dbf9_})|7;-zUqkAcvtrH(a^1=2$W`M>*2 zK2QTdv%h(EmOP}r+2cMAo$CtWxyf`#N3Q1hPyrQOx<7%A^H=?`MiA(YJlU=?U|;|V z*mvq3K93oObco>uAI{c9%b3-Ai=f7IN9}D~ohZo54`igQ)xngKq#Wr~r zl}O^lKw$0n@0N&aKIN0OhEk8aaMZ4#*C!}~jN0(+)LuQ7yD7`#uC*h7Ca+y#wUJ6G z?NfVC_XRmqq?7H>f_gMW!W7Ijp0+J5|D>c-3zNRLfBCW&D))EDoVmPIqwV97(JjrWm9FVS}ij*FjLbmF0&FWO19U<@4QCQyCOB1 z*036%U83bJ@^)-*k*+?lpg>41XDutcVJoet7b88MoVskPF;~Ea3smj-Sy%{4UHQ?| zL-L#sKPa>X08j=C3kv~q;>=Y8W@++LsgbA`4(*FcA@P zXz50;D*m7R%uK7tmnZ|!~l9P{WQRZ=C9zev-sIR5eeB3i`rp7z8VZ;uA3?qOTG!u#vJ45{ppEia>{@rl^Q8GQ@qo zowk?PNJnR5N;J-?XRujK8v`IZL_c_t{{`>@@Rb>%WXtS)^mtyGVHxis^RyKPlxVFm zr0#aw366^GZWVArbv=}W%CFfyuTDnQhFuBni7tcEP=A|FR!455VEmd+L(`uqp|V*N znG(z|R$)GVL{Pt&S0nPZ+jH1psY<|w;CDz<={KbDiPVR(wbwkiIbh~-CkF=gTkOv`UD~dQ}_&Takuz~5BI651s3l!&9omhk{wGDD#Xnq zySvw2+mQ9XdPN-F?U(nMpWTMtv@E)-E7AI&YU?*7isojL^!$A4>udHH{z;OWnf9(o zhZs4>D3w(Pletor@<`a#CU4V z>y7(B#fcU_4lR0<=_u0oxeuH*PHs?u5+bgYnP13BDMBO$L$k4eRLfJWO%Pd-o98776em!1L^JqmnxxP9c zvx3_yLNOGgdnfa&-R(B&cer9=`N8pKicNMqT7X%1%B^U{*-R1+ia@3x9)C9`3v7IGnOyWSqrRr7e7I{oJDx_Ya_5Ulr1$bjzZvj|R>P z(+9`RE3Au+)q2K@bcRO0YhgIn2)fkhzh64Fw?F9q?R=j3YSwj<-0Q7Zzp7XF%8rZP zdqS_}sy6l~pS{dobpYeQE`JBsD*^DDH zIEaM(+n=(im*EYIBxej73YYZL{h+g>vfL7M+MMOQWQ+{<(M!f5Mg&3Bb*(IgZMBfcE%~koP#F zUQf(3Eys0g3r1>Ts0J+PX+%QR7#rt*$MQZEg1c7%SR?I;*SRLKy?D0-ZTbw7^6%~~ z$Hb^Cygn{xw5iQ79)M$-oGXSYAyu;Dq3nn0)GWl zwSbCTRH$f^6}4Vb#4ESjjM4R>osAZJZCqP3p1VJN=05DnSr%sOg;CAgDeAI#%lis1 z(LO~y-h!f(pZT}^^`pj#CuXKKT4Q(acuarTjZwg*I6Oa?eQ%Jlx*JAH;Ss@U7B@Ch zm}>sboWTF%S-Hi+pzN#1zMg0}zY`Nb&VRkV06i!?m?2c2!VRzm;O0!WrAD+GAXsfS zDx-K8#g{r+#M{#B>YZW1&yD;SN0IFF^9!3pLkBirm9wvNF;Fo(hIxNHB)0$yO^rLF%hRA=~Y3IkN$4Paz+^J3z z-u>9zS~)IZiwChiD_2{}y_%;|{;kW>*_aj2 z$XD$UD$)y(OdB@N#i3E~UmJUQp}(|fifgubV2brv=?R(Bzn5587S-Rnn5ai3uLRtL zgj9vi%`52B!=9JjFRIY$u4`AMVhm%^VR0D1!Ct@+Qrkw3<9Fs_uM^HC@^Dtk-dKkVN~=OZa3M1nJi&7a@ zPg%_@OTQgF<0SYem~4S+{xCLIhpVhC;EROoHqFAp<<7JC9!U=qo>-p+yn~hB-q1wC z!n3uw<`?~O%727i*Qwx273aJ!-d~@J_Z48s?v6FNxiV8Wqnea#Y>F`Jdil8n*8)&S zA{Jnl^Aq}m51_vTWgZ1s{XQo_Z_AVLk`)ir{!sjYuQj3fWi|(qlCEOkSR$tVBjIQ* z<|!Xa`tR;P9(rgdW7#Il4Mle+pT%(VA&`eRh~Hs*C4SV?L|Su?raTs zym|+TxP|&PJWL}VF#~!}6g4`z03+B?C@q#JG7|9=2MU~LAkG=_a`t?G=;F3AZh_%~ z(0_s%|H%x4;nkIJ>^LL(Q)+JrBqh!j>_owCqne-qkos}B*&9Fgjg2*~@R+}d&fq#M z+?P)tDxRKM=%VNToIU_QC;*#HAz|};RUXIUjiHPk?QD}z1{Wm9597xHU1lG@j$BZu zFI!-LYA&Z&@bmeoChdr9>;zqGt)&M1w>xMR(!Z5%ci8kJ{0N*&-~EIq1?v+=Ehyy9 z|2bs^mW_Aiurd4o-nLk@P$yccgG86EtNUZ~P6Zbu-uxkVo)4wW;m+*e+nJ;5MBGdG z9J#2NrC-1L&X~O=WVd8|EX-B2GrX}%i^zWk&Qs+gh0ib^U}w|H;z5KGtatDlaWZS4 zy-wrd-f((BAk^^nc4I1CW7?=MReO7*=?hd&)N~oU;Kk_|{G#WFST=e^5Fq2KHG)LT z%J@{JX@*~xL`f|mLh;B?)FT&CGz@$hVXS-o{YjPIibnGrQgwKY9cvkg*Mt5(Z#mpDR8%@Fd}85MwCKJ*DoVPH>V}Gg zQR_;_mpY9Pfmml@^*B|QH{TkX)}pdbn8 zrI{kRpI-7eG&}}UCprH7Jo^makoSR1-uvd}7;K1yFQPZAdt?SZ)04P<)Vak%EyW9G zG73-w@vi=@)R&ih0Uj+M@%#IaJ|6$0S{TYypkyf=ajI3ki#$QxV!|@~6P>gWA|6dr z^24Z5{_>ih>9ZSN+o{yFrW2LCGKb~4V}U#==bNjO1ut?}%(tGnSq?j6FW>Wluh zUAp<*EV1Cgh=si?ul$KAg%phul2>-7h`%o>x3)ce(L={*`gqTs!Pz>Qh;Exk1HPN> zt1F|HaBbITFnneVV^pK0q$1|+)zKMlG|n|b#ABM=8e0YTonr8dB{0D8_P$^iOW&C+ zavIz)RODPg;sE8WJa1TERSmmoy~M#`hr!twvvKDqCj*k<(;_o4;ZDrR5aS;h7#K1F z@czfM{bfe2>Im>#I)Kd20zvqw((KF;bRA%Vf3_4N3!wVINHEK~QBij$?tai?XNba0 zvR1RG3T4{Ms6VvM68Wer=7e1JGm6hdE-2AS5rCK!x;URC~rU}!7(+Ul)Lr1@olDjI(EYDxX+ksA-zZsQj zEP7)9u5O;zpPlJwfzGhR(9pRD4;sG|BxGhcnY>^lxO>ag-_xB{zi>!3pd*x-CsUkj{Aek+ncM}a*tm@MXM*O z!CmhA_l)gP+25a=>=JG}=Dhcs{iDXXHRQeLbo|0_Q@JrK+k)61)!(x*f*?y!FvI22 z0NcZ)8Nno{HeA!PFdSU_?_^* zOf@wFqCe+KJ3GA%Roe^y@^#ADiF#7gEcYun^T9)fHJbah9_iDJJr&0eeVC!ciA;U2 z;cVQ`w_d>I*4@;P$HKvRJ1|ia1JsqA{wHiijfRE>HoH%VU!DJqSZpKyO~DxioI9Ch zIsQ?nb@>TKEh+QQ)JXWxDOaj?z*k0R%oELHbSS}s%lu0TYQhT|Q~Ua!Qk3wYMy+ z6t7}7ops_KEubKI`xcmyMey7#`^S<$|=ItqHw><*fpo2rXH4pCVO>4)vO*Es?^?aD%II8cA zeQP&tNgXX(k2cGA@W61$(H6*>PO1^B(Z{9&W|-f_g@s7~pZ?yOtqt^i#VGn7yg69- zhsS+8|C+YOiJY3N{FfIQkEik`A!Rz9X`1w8^H>2fDn{P?N^}uO zy6F>gZhx65=5}v0GyVB}TthUR=?lp#vd%N+#-?GFRZKF|mfpPD2KIZxSbpSnSRw7+ zlQ}Ab>pR+kGOHD{>i`Dz#Gw_$5`2^WSd~%6nb?8TIY4V?VKa}jz<8WvyM{A%(ri}x z(4xRp?UiM{wlCU{Q4pU--51;4#|AzBilp%^P7O(1?&?V)xV90e$u7hubc9 zg)RE4POw&bu7V~_C%gI*XE8}M+P~gT-#y4~nym|Xsmn*4qV2SGUr>;~e_i9N=g*%! zarO)1+f`;1v#wRYy~rHN(pmjlmA^5|K6vwn-H$w8Mt$NnP}~UE44{lxK6DH;Nu>L( z)5Ld>gmmX$SCkUCNVs;|j4Bm?sR1^Q8(d4;{swcGYsehM-N#Y3*vtvESdlWy$`Yhw zGPUS;+WVUp)<%9q>sZrtQRh2eWCs^*FK?eLTJ{pZj0{J|BT&Mqj-z<%gNji$kUh!+ z_##9@KUj3%;pPeh28hJ%?Kitp_t)yYz>*?vxl?7&?WQbnX^CXJV)faK{UQ}4axN0& zf3`Rk75y9e(!v%NO=xFyK8+c2+(N>`A-^oKeOpvUpOtGo5DgHr+|0Q++sMvySPFI~ zb76~z8*6Lv7vAc#{iU5muK*TT=aTb)X;T=n#eV;;2Yw}~fUB2^b4E_?517oM<*UXE zY0s@qx80&Izdk3Laac7nt>X{>`BNPk{qh&24d43LvQd|pG0uA}mbF*5gq*Y00b7$e z_RGI7KthTjw<_1iDAxfj+!8y^D>t1((bw~a*H8+m|IE=fO-!5h|m)Cn-Bd}c&w$`&IvXBMmvzp~F(eg7r-uxePbB5d1 z2dK#+r0Hr!3nH^Y7!*t-u4^H&`eJG0#*62hCpbigO)6~$Y^LYO;3}9D#=HG@b;76& z6Z1oxajyPcz2HY((kW*vG5}UCUY)!GAidje1B$lAYOK>wzdx`Rx_9p>nI8>T*`G|C z*>C2^R_uV*(A`iLgFYez76!rp*UDSn$PWC#G1<3C3Z+dX%Q7bT)abIPy^P+Be5p(P z5YM^3D^gjnyW`_v8rx9~fj<)^)n@r>94jtfYxdcIfyP&2VGBwRvXJ(MniGNgwf@;` z7E7+f%cHz93jm&)){egs`#Jd@|69v~P_o5=lhrskOaKGGS@&pHS}6C=A3*gB%>7o; z(izLwL4XeXMadDn6+AF*Ax7Z{&E5INA0TVs4jjPUvO4fvoOM>v^j;b5>#Nwi8kyWG zKXimZ*gB#9eScq7z!0|t3v0>xpO~~NflMBZV%GbdR>KWEp46MBpH$iuJKwl;t@dC+ z-`Fl$M2`G%%Se03+3~PSI}FLT6w;nJ2Si}P4ecX`nFzyOQcEjw^(wr#Htg!*4~0=R ze7?8N*Q+YteXS&hiXL*mWh>3Wkw>@GO6iNbJ3~I#rg#sAvK(o^c`^Cy>aw!J@bv)u?zLO7eJLXi?!$`&I!>pfBoed zX&4g%AucCi7^+T6CMLDitsggkF{Ie>9IvO;;9H*o2zhHw8!>;{QkT;2#f}d1bQ8b- z9FM7a*;42JqZG)-fFf`OQO-)|y?aD?#-u!?kH3A(YFc~|%{`TdX5;Fr>Mw#@Mfz46 zO~%W;1_?!;%Zf(E_g>MY^lrGeBZq1{Uu0zlT`3xgSVK-3C2ouEu2IP!v(bP{QL_0+ z+PJy7sR{&U{U5uLn0CP(H#axz(LeLeC8L&?Veb`br%(J<(Mc))qu#7+f z%8aBtzTK@wvI5?dn_WbIlv`)*snXvUC%_f@IW32qn*a&NqpB85*YiS5lIjh5B|W4v z6RM|Ag<`GN`V8_No7(Um>tyA&8nR_APb}M7CA{aHB0^)5Ufg(xRDOB&ERyBNuV}N@ zoc;`l{t4r9DH?V+Id*oE_jPe@Gq%L!Zo9XmmH&L$ss9!e^D4eq;5s7Y>Vng9K+};w z>UgVwbFAVR-!j~tPnXfj&1*{= zU35GCLnL|-LhB6$(Y$%S{<-x=x1I(OnxLFHq5s;J?XPO$B?+b2pV@=Eg_zTfxCLDQRKYglcUu+_V)(BX^RLO#q`Phm3ZPC5*LZ9d}Pc z%WZmIQ+589ZYwT0m(BhPPF$YiW|a&pZu{^eC|tjF6&DZ|$pA;uu#zU^oGuQ@&nIdP znEo0c|2SS}G-uL+Ms{09L*usWEB-(fvN3TfDZkNYU2`kZ@i1i<1{F3*zJsp!fb-ey z;SB`*O;dIr({knJF$mO%n&gDB8>!2ws)_*$3&JHppg(djXn!vF&KvTxL*ners z|Bw2xe^wS|7~_}TqF#>Gs-69c^NlUQUHB0x^_(Bg4~<4=X7(R+Fz7fRNZ$p_cW7uR z=(v4BlpyPa3>DYsNRY0e6%;$=RtLhJv@FJBGL4N{gxrPSf1)x_iNsLxO-YRAI^9Rh zNz#7R8)r|3f(!J)B%`bIftyp&XE Ea)VtsVU9z{7#J32R(*7b~Azi#Ro)% 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 CcPh#N literal 0 HcmV?d00001 diff --git a/doc/how_to/benchmark_with_hybrid_recordings_files/benchmark_with_hybrid_recordings_37_1.png b/doc/how_to/benchmark_with_hybrid_recordings_files/benchmark_with_hybrid_recordings_37_1.png new file mode 100644 index 0000000000000000000000000000000000000000..63a61d7cfeaf9262c754c2819baeb85bfcb3a3f7 GIT binary patch literal 81662 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 Snd=S-uj9uwRdSA+`u{J$F4uzq literal 0 HcmV?d00001 diff --git a/doc/how_to/benchmark_with_hybrid_recordings_files/benchmark_with_hybrid_recordings_9_0.png b/doc/how_to/benchmark_with_hybrid_recordings_files/benchmark_with_hybrid_recordings_9_0.png new file mode 100644 index 0000000000000000000000000000000000000000..8133cb4cff995d619f07f08bb2ea95d28b1f4591 GIT binary patch literal 212689 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%0AUytuGHj_;R2=j5HAt#(LVxsFa3{@}qU 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 z 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 z zgP80Y@5gdrDN!*|NdZVX;Q9k_1?8^mvVHsZp!*9>59^_>THD*sZs&>Qq-kUDm$DaB zx^;8&F!VDnb$^&VQ?G-r)`sD;9BzPziw%krm_!2~szKj+QW;&Q4B}A(ae~kCrhMng zNpLSQv1k~S)1GavraG!?$CzxNb^mm_S>a=)!mOn!!uBdgc-%R+Vo`CVzOJt8t<4k_ z+6=}i6OnzeiE9NeV9^+@q-36lHoz$`(40B9kN0z`inKPA1Z|S4Fc92EoyXtg1%b{? zdTEh2iPkF2(yeygqXBNSM}pFc#(}MzGxc;wS}V?lM*EIXBFdFL7Ro|x5DL_A zP7ekqQ$xFD&va#qE^q=SI0&?x##7I74NBuk7-fzecxF_aDD@XPCvH1g#-ib0>5N3! z{PghPvYA4UZGDuHMJhXKFgZ;#H9S`*NK{ zP(nhstn3_kOhfv7ymy6P%9NRrFYjYm=~uo+Yk?rs3vp+$6|qWgMu*54DB%%LztK6V z*q`MFaB_Nfeah+5L8-^)f_L{9p2q!Tz#T|x#D8FrhS}i3-R9rU2}7CyO?@-qb5gI1(YebC zJSKpZp$iL%`(1-`b===CFm(ID?N)$#DZAXh*kkR%vfiW4hW)|glJMR{?X+*5h1zM| zX#*Bfsfm7rS4TpS_p94Sg%cz)YU&U~m4F3KNFap#>VZx3&IXy(t4d zxd$OmQ|Tru0kL0VDqlgMpP0h=w|mGsZGHfM(q+(xaC)Zt!n1ra{;w!_E72DT5#r}* z?9girtKc${>k(V@<=%XHLwC#7Xpw?Q%@#!=&fS}DLRj?EKI(y4<9fJ^UbuX^p;hXC zY8&Cs_T<%E3Rq)JK!%vd!$~WX3BY!J&>7_c7~88iiA{EeNj_IN6wtITVN}egI$KC?&;0E7!EVNBU%- z)B1H&nWM*W9m9V8b~zd%9(crXWHb&BLjL}4xV8R*Hsh+qpfs>B@Syk|JN{FKp$-6Q zl*mV~AC+RGPmDn)Xjh!yKQ3k8ooNaGk-q%8?Sxz4Xe7Ce?(=_$kP4&;PE(fjZVkAYj(JEsrr-SLUrgl z8f=&IO9!P)s=hUK3x)D^)lh}wwL39|Xd(s}-tBR=$K?1wg0X zGPj&&ObF8t7)H-|5@HW&E9Rd68KgVe|NRLa>vwYUrbQI|Qc5|eL90Xr(f?Elbh0l_ zqRA0B4)>f$msZZQvQoK9qaC{M9bGV*lEPVZ5R@-B{cMw6`Mv*zxniAM>!~g5`uvwL z#5OfamNF2DApnAvv#*hN0tiSq8G+<*_G+}n7K$CX3sCECjt~1xF5M@j}Ol0-b;mAeh+=PSv?OS;ZhlI-N>hz&xBp44J z8gj|+G?nD($Lk07R~OP+Let8+$yylRtH3fPFaQ+b_^~?ld$aVTXV64Bw*<+MU++f< zZ8uy8@Z`5;-L`7kjkU4`;C2 z=+WNZOT0_8v-{+|8hp=^%3mdDic|HFTqr!N_Z*-08LBI7Jv$e>9@avw^5Un?JejF< z1tQit%t6@7*iP_`qLr&W>zWeb*2_{)zap3tMCh`)-ekO27Tgp1z`VRT)%ME=Js7PUBFIcIh=q+S($a8DsdRtFPd!-ENwZw38LpC2=)7E_3RT=yTp*H8HVd(fiMwuifQPNh-S$5TyErC7|Mrj)6WN97hU;PTS3cin zpl9X&b}i9BFy=GPYa-1Rh5$so1y6)vc=b9Vm%g;{^lYLazA?@#5*(5nS%`*SeU|qO z=3!dNl4mmvog@`b{Jwo5S6lPZOPp^j*U8xX`s+{F8OA(kJ%l{uA8gKu=b$#5KCgyQ z-w0wT^sNB&T-D#;FQn0?GLV6eAEfvEx8|)hF5$cqDk$U_FYcI=O7g^I|#IzTG~3QI39P+>r0Gx)rnFIc(~Fg2x~sC8>Z(W-Pb~X{AGS zBtn@2l18zLs7;?~Pt@dt4|o#kXeO9hsQCxl%VX{=zA9^fbW$&B`8;xd4Zj|y{9t&6 z_#jIMfCQsIsV(PwNv~x zske7;pL@fLiwpLoq$uV#j8RJ$CyAA1!{f)>E?pWfG)%-=5g1GRXmeeKyeU-JGMWbQ zT{See?_W---fDBa_zFsIM6kSfJoi24uz!%go*y{UNX12#Gap(T@{R+U?eilVwIw&9 zxQdihEPQMd9!FM$>!59;JC`vuA;#4WIyH2qXd53P$GZqRXMp+)&9ph@1i z$cW-+l0inREJTo-9eK+}6IY&^oVR8yJtf@!tAOBufxE}#$nzk3p?yJ#H~(cFK{TRU!6+e^jd{JgvD?_r z9J-#zedI*U23HSSD8TIq`dU|f9F>9ZF{9ajGd#LFC zo8^3s>NXkq6WNie?`MfnO;Om*`BUe$4XpM=BRPwZ{RCDHo_)3>o?H==MP++0DV z4ofLj5XS5o*x?RM0^NN)ct4+s%$epxLw}o1m+|)gh_O54r6^9QksM356D3JGQ2q2k z;9l(86x_l~!=%{OY3;VoVnlC81q-?S|$E8Z$w+Z_zTS9LwC?r0;XdMwV zMz4+$2`#`MKPv+5CdQS9_XTt=xT{1V%+CpZsm3sy^wHhU?IPc(>PQ*h0@HsuId)YG z(jwm3(Q6>jn8i*$5g{^q%dO|Wxz2SBDXV&Gj+Fky^?ql)0u$zV$bU)By|@iZ#^u*e zIhVjox1WEUg&dg&xQS*7Foqg}BFaAxlEKH>p-g%Smj(dFhj+fUJDEs?@P7;a@h|cY z(${R0n;*E^jf@r4qx^0b6e}ORnPz|KqPu~12zuCR+$tptPj4H&4>`t&oS7VlBBm6w zY1$IaCfeUJnEsLT--t_*liPLQkZ!`tOW#JFO7y6R-zBq!)uNVo`Q6t}$G?(8jL%Va zTZKrLf&mA8$XZt$zKZNaH|J)8J#o$#g9-A%v?#RhEpsrz$ZXUxpY(h}Dh-su%q*7IE!ou8Ma-zyxq+QQO z{t4hgqu}LBH^A^9I-2nCaEL5PLKQ3$gre+)8J+k)c#o8E^eD552o&I}*HP2v#WQB; zvEI-p`7a*Lj1Gpog2i&1^61b;&^n3G5y3=q=#yN9mq=g_aP_D%ILojN3d?Dz)aRD$ z3#Cb86)ncgqYN6!H;Ezzmt~@Gzv}!H*}M1dDS|?IWKW8jdS^$>%lxYsxD7aH&>jof zq}jtw8#gi~Jt0pgyQiq?yL3Uw)10z*4ryybj>j{sZ{=~H^SiCxwQE1W>AR_HVeTgw zSm~}1N=}v@;#jF+dbGEAk3~v1$oT}@xldO+Y50ZpxnCxj?_TrrwhskVt@C$;PG%h= z5%k}(9KrX}cX_j=WIE)#_dNK8%DQy@z6k4uMUOjiQz6>?(J?vs_l|8%WhHDzC~9y=qy4o*zCDWC zx>e+60RTVT>bfgRZU~E<6uwS}i;rJ1k%-y=x>S(J9_u_i?7Yymq*DzIeR{!N#W<)HQWPD?#s^U(QyjK+_ojnI8c#ODf zJG*2^_E_pF@$}nw-FlfFC-tnh_~g3rfA1#+*1Adhef*>=5j99zmbaE^wO70B)A{=f z3=}n2zJEqcVwlFcRmmTEPaF;UYqL6gLKYR>Jk@_l6AGLrzi7zoNz6bxaR;F%wa$cS zED7ONzS3|xNWr|Jc1qtYpSWsw?-zk>OV2(0WWj+ScF`ONvvr-n ze@VQv3D^KPQrf&SD(ZkN3~M_&cQ)S zKCNs;Fp3h>{Jzsy8XLQ;&8$e-xMda7zf%wKjmnf~U-*%v85NA`o zbC3DT9Xpx|p;{MpHqls%jM0pYMq%ei^#rj@`PT`>44wsqVELE$EdnlDa6O`z zEFWP5PL0tAhhyi*e}mSR=haE6sg&kAp}D_Bu}ebrQ-b972mc|N^YE>gv-&-u*rdSp z_4S1i5~w2iTS&3_hhCW2R8BwNfj2Nrph524-?S2El%-FveJ9WLk1fSeEW%x=!Qb^T zH{UR=PsO;99}`90>T9*Xpa8LwG*Wl6JC+a!GNw6%WFY;-qN%cCq`i>gUg&E>2GwqTt9W z2_@O~GCOxTXas~PkQb34OFQKU_+#wj`Ui=O|IWdlNl>Ke*T^>S{J~$l$V^<%zTiaY z;NOm(az7*isSpmZn8;;0yN69N?EubXs}*JyKScgiTL)Qb3PJ|^rG^`N8?5Qur;q9O zy`v9?bHH%Yy-t~Ng=!zfz1jp3fgV9n{Q4B zr4tYDEajnTFaDJs;Zfe*cUlI;fKkkv3y(t6%-EHuA1=Qi^;`qtM23|(E@=zJMT^R} z=P{%B7fZUlol`4H1=@nPIV47k)lcow`Do##pE??*5RNnb}RGn^Ld;}tOg;KwV`WD0R`UuOyd#jk1 z$5sDt7h7!R+iS9W?R@<+vC6lf`;exO!f>EgLQF`=pXVXy8E~NZ7tE28>J>c6-F2h0$}oXRE2? zzKlcy0ZPhI?2zO`X=v2d>ZupMLIXW2CCHC~po+0HkY>)z4(7z?n6>e%X=!_3uFz_7>#PFVpJ}evPF1<^0 zIkd}8YW9Ug-7^^!NkoQzz03Li@AT<0)U0B{YRg`)=%}dT!CxORS7D@XDnG)935|jg zp$!lU$9Wk5cPbx5jr6_-#4oR|f>54Iy~Z zMf-Bn|JX(jLvuPTU71BR&&ZM~SQXnKE%TJiH+d*}Q6r+tYoZA!D#?4@sQ(MNjzp3Rqi zj^tZxH(v6{?}^V&Ig7ciLLfjB$Dv&~F!0HqV5y{O7oE}-u3u@zQ;iC--u>J|J?|M+ z!MZ04IYvHz1^CscUKLo=xV+msI^EvBeQTOK?8{I12P#sEf36W<4h&Xr=? zZ76jarbVto3NDK3%De(VXEK05HXNhpbQ!$-5f>DjO_iQoB!JL%(lgLU4f@s?(J~`R z&>Vyw{kwJP``?$nR#Ptz{du=`VU&6)0s@hL1zP|IJ0S7_Yxm*-%_Pp!sKy zJw>mZZ_mD5EXT(%}c`&)X@NnKQ?l~rBWHapQc%M$HsT1gt)Ez9FGx1za z>vQOfhIQneVGK9NLD$`_Pq4Om!~RD9w(>D#Rk8FTRplHb6fVKb6X7D%@I5TdhqRaE$?viwv&{<$cyd288jtsGGziE)a6qN!V%>u4mhtcO1t z<6S%?vaJIUE;=)LkX!OVTEPEKC|Kt|rX;6#-T<+ortfUf`TCBj+&}!4z!QS%g8JZu zmZ3)i7&IC?2^kYa5#hOR-F4_N2D+Y zIYCIUH=`V`W#%GT1U`#FwSfIRAz(Qy_sQNO$fE_wKuBH?v~oYqyHEYQ^O_m@2cEEv zTP1=QLRoWWTo_;wbkghS%2!8EGg<;zZL|6>M9UF9rz0`A@*Xrn2+2fgr>EDEa(vs6 zAMN?W-Idq8*uUw$00HUpxfE%}J&{muIB^P^=t^~UFu@jJC~3?cIo8JW7`1fEzOv8U zF&JENfvsG)@?sJa%em|f0`!$}g=kxjc z{zY}pkwY^4K@ngH^{CMF1E-d*^W;f|dKVX^g04|d2p8T5>ne!k4eKebg&UNutvNA` z0-pIt1;lrt9#`wK#;?`jVpHEIojU2nRf80dq>b`sx1i9bTRTNNO-NT4Mf)<+B61dE0U<;MqcVRo=c})M`3)<+ z@W$5p3<#-3#kN}vXV%`Dk)V|t0oK+$_ZyPw$jzdtB` zXZ5g%(xWT?|NnQERYrir{JQ`5ejKOG7wg2Atsb@ug@Pcb!*YTD{;|*2G2(asovu9p z!6nS4eEKKh)^qIGvKMMI{`&`?Fi@0$m?M}+9c=v9XbUFR|He_dLw0Bri_%+`829?j z&n^%0xmr)}BPHu<@%xj3nwQ6&sbU$4&fy7yvo4jnrpR@lP}1 z+KLE;dr==YzL!Kk9NT7rATnb5HzDt2=#DA_o=|%q!}Oyo8N%0iTpsu3!IUN0QElRP z3V|tLa1E-q+F_&B#O5l7Rky`J{KSb9t8)Kx$i-qDpZ5=rg(m4qEF~R7c@Q+-O) zoU2%&?cdgKJN|cgh5I_p{iWZ5uLlrI)q+9;ooqfL7p#Q>ro6^I=?x@;VmQG&x!PGT zKla<)rmsNDDD0@_o%wTorklcO!=fjLg-&%``p)*R=ePB*Y}DZmy>MWVmdxRnh=kpY z;z$7WFf|}x-8j*%GGajPulpL?JI#X}pg6vMp;vY%p&h@_?vBHUP&1Hl`x$#4&EHdF zf>K=QXE=QpIDZAb-lqHX#+K2j@x2+Ow6)bw$V+!Y!t&vD-T+~d081nxy>+QT6_iJ_ zS)KWxIKSZWcsS+`8h#z5irQe0&6Nq53=^+hs7VC-1g}5}pu9`-%#QfCbm8ZtD-fHQ z--L}nWc4B?;W4LDGxw(G4gaGT5}tSSxbVG&&(agFGt`>(k6+KUw9K!}{WeO1EPrRz z>otTWfp$?AcQO+uIu?Z-aA7jQkOUvHWaRJ7pmUT4-6Cq}GouhHBcYLyphRO( zAt^!p96jUf>YSyEVy!gltipFUZazRwNt}Z!vpe=Lj(OV_=@^R}^Gl2yK0yTn31B!w zX$r)`*>HLFxi~WvZPptMsFL0{ELJ293vi884IXSUp-<@41cYty1r4|U`f|VNj|zms z5F~6Dv$8S45VklJt}dL%lcy{rUT$+wqEuS7w{y<)XH!R{s6EYsWg*HS^umf7g1= z^N(9?uigA481*m=V1NI%3nz+WlqbB}SkoPx11w&Qo0D_@;hwNMch~c#B4C)^Nl8gv z^7M;+fN=3_E9T=eD*DejF<;`7N0#wPb}=~Us@ZMFQjF*8vfz=hQDoZ64}5_|N6nb! zpsEyppFe*#e7TKe@B{X}w8W3QYXa8Z%F+6bTLn}>=&`7UL?0v8QvGO?JpD;%Z z1)-_uC0^S9YtNf*nX`ZLe?o=#$Amu(Gj(cTj2ACDY`a}rPQykWq=Ybr^FcM`2MlPR zcH~}`(8G%PI;JpRSO?YV*eny*Oq#Tfz{hZOislw(R(Vncc%1bmfp<7P5PiOh`K`;P zg6V|UD~$~tnY};efZF8!e)$Ojp${|-yHP7OdFaAeYlQn92?M#1Lo9X%fla>R-oHm@ z+&oE|!GJ3GnKT{fHM93^9?q{;2iibt0>-$Ut98r<39#_25l^stg^i9qB$kfs%b>Ag z9LZOZuo2J?`m~V0zyn3>WWl?kZ>8zhL|$ribw7D-x;ea^?-G#oy`9Js5w&p`+pwV&aZMd)o3r=C(ZQ- z#qO-OG0=6McnBbJOt{}BEacdUvfY=PduI_wfYHCOKt*^e_ zh4sYp2!@80P6Uz?2@?z!W*bw&LJF8>Ca7W~H}rclg(cEy3~ZSEbvV6-U@9EZVb4V_ zKZDa29XS*JB~?dPf_sV7XYBbj5J}nc+m#Tw-wtU1(K&GY(CW+29xd^+G0}W+X{90; za=jFpB<4p8S_fsSA?@m>ZHmGz3RH&@CG6h4d+on|zaGq^5N0=oa@yA4POomQ7+Fo@ zc?p(}QZ)t_Q;{R6kpeTdtco+lH}anHd4tdQU*wRl@gtredo@Y6SscU?H`^Ugp3 z6T(WYyrGMsOBSIWY*p5DA8q@fxZWHGd?9vCHavb|2q6XXx|>_w`bPI`Cq1!2_xaT| z!G+G*=`MRaLne`IAJ7FA$-KNOblO|J>O+H*oz(cghx9Fb0ho zv)QRwfbX=v*-oQBEP%Jh#boO0t;$F*oWl!#AiP0&(f|<%?QXBntK=ZjkaoeK8Q}pS z&SXu6WB5&qDQc?^j!Apan?7y&7HHg;AWv;AIttQQU`>`!T86$;mK>Rpk{47rLnDMsf0=BJvJD?q>0|z5vz~@pQ&h{x(Hfs0qpy4A5t@_ZhMvjkXJ4Gr8b&?2RdY z9I}1uf^=-w%(F?5`HKNqH7f|%vDJU_`GhL!(#!Dnu$YeVOOj+1}i8d!% z9B~GDw^4(h4|_0n_Juoh)T3;EY!Td0Fn}P4ZNe_KMm@*R&yOUz_i53xrR8_NUXpA7 zQ9J>s>2AV9kYhUGFXaab7t}r)SmG)y+2Wy!yPE5GIBpH1*=s3EkG7 zG*2v&*tbb7EZnTmS8Bk96}r@hQOr_AH&xlF)pVNkp`oGS@*=i3{~{t+rxwf

4n* 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�JwQuBXV$xqBXApJeaT_#_s%O0XxD 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 Wk4<|G(>)4a6UR*(8#-p;mj43S2F&mP literal 0 HcmV?d00001 diff --git a/doc/how_to/index.rst b/doc/how_to/index.rst index 54fd404848..66dd9b417c 100644 --- a/doc/how_to/index.rst +++ b/doc/how_to/index.rst @@ -13,3 +13,4 @@ Guides on how to solve specific, short problems in SpikeInterface. Learn how to. combine_recordings process_by_channel_group load_your_data_into_sorting + benchmark_with_hybrid_recordings diff --git a/examples/how_to/README.md b/examples/how_to/README.md index af17859ca7..01f11a7a28 100644 --- a/examples/how_to/README.md +++ b/examples/how_to/README.md @@ -14,17 +14,21 @@ with `nbconvert`. Here are the steps (in this example for the `get_started`): ``` >>> jupytext --to notebook get_started.py +>>> jupytext --set-formats ipynb,py get_started.ipynb ``` 2. Run the notebook +3. Sync the run notebook to the .py file: -3. Convert the notebook to .rst +``` +>>> jupytext --sync get_started.ipynb +``` + +4. Convert the notebook to .rst ``` >>> jupyter nbconvert get_started.ipynb --to rst ->>> jupyter nbconvert analyse_neuropixels.ipynb --to rst ``` - -4. Move the .rst and associated folder (e.g. `get_started.rst` and `get_started_files` folder) to the `doc/how_to`. +5. Move the .rst and associated folder (e.g. `get_started.rst` and `get_started_files` folder) to the `doc/how_to`. diff --git a/examples/how_to/analyse_neuropixels.py b/examples/how_to/analyze_neuropixels.py similarity index 99% rename from examples/how_to/analyse_neuropixels.py rename to examples/how_to/analyze_neuropixels.py index ce5bacdda0..aeee8b15b4 100644 --- a/examples/how_to/analyse_neuropixels.py +++ b/examples/how_to/analyze_neuropixels.py @@ -14,7 +14,7 @@ # name: python3 # --- -# # Analyse Neuropixels datasets +# # Analyze Neuropixels datasets # # This example shows how to perform Neuropixels-specific analysis, including custom pre- and post-processing. diff --git a/examples/how_to/benchmark_with_hybrid_recordings.py b/examples/how_to/benchmark_with_hybrid_recordings.py new file mode 100644 index 0000000000..5507ab7a7f --- /dev/null +++ b/examples/how_to/benchmark_with_hybrid_recordings.py @@ -0,0 +1,293 @@ +# --- +# jupyter: +# jupytext: +# cell_metadata_filter: -all +# formats: ipynb,py +# text_representation: +# extension: .py +# format_name: light +# format_version: '1.5' +# jupytext_version: 1.16.2 +# kernelspec: +# display_name: Python 3 (ipykernel) +# language: python +# name: python3 +# --- + +# # Benchmark spike sorting with hybrid recordings +# +# This example shows how to use the SpikeInterface hybrid recordings framework to benchmark spike sorting results. +# +# Hybrid recordings are built from existing recordings by injecting units with known spiking activity. +# The template (aka average waveforms) of the injected units can be from previous spike sorted data. +# In this example, we will be using an open database of templates that we have constructed from the International Brain Laboratory - Brain Wide Map (available on [DANDI](https://dandiarchive.org/dandiset/000409?search=IBL&page=2&sortOption=0&sortDir=-1&showDrafts=true&showEmpty=false&pos=9)). +# +# Importantly, recordings from long-shank probes, such as Neuropixels, usually experience drifts. Such drifts have to be taken into account in order to smoothly inject spikes into the recording. + +# + +import spikeinterface as si +import spikeinterface.extractors as se +import spikeinterface.preprocessing as spre +import spikeinterface.comparison as sc +import spikeinterface.generation as sgen +import spikeinterface.widgets as sw + +from spikeinterface.sortingcomponents.motion_estimation import estimate_motion + +import numpy as np +import matplotlib.pyplot as plt +from pathlib import Path +# - + +# %matplotlib inline + +si.set_global_job_kwargs(n_jobs=16) + +# For this notebook, we will use a drifting recording similar to the one acquired by Nick Steinmetz and available [here](https://doi.org/10.6084/m9.figshare.14024495.v1), where an triangular motion was imposed to the recording by moving the probe up and down with a micro-manipulator. + +workdir = Path("/ssd980/working/hybrid/steinmetz_imposed_motion") +workdir.mkdir(exist_ok=True) + +recording_np1_imposed = se.read_spikeglx("/hdd1/data/spikeglx/nick-steinmetz/dataset1/p1_g0_t0/") +recording_preproc = spre.highpass_filter(recording_np1_imposed) +recording_preproc = spre.common_reference(recording_preproc) + +# To visualize the drift, we can estimate the motion and plot it: + +# to correct for drift, we need a float dtype +recording_preproc = spre.astype(recording_preproc, "float") +_, motion_info = spre.correct_motion( + recording_preproc, preset="nonrigid_fast_and_accurate", n_jobs=4, progress_bar=True, output_motion_info=True +) + +ax = sw.plot_drift_raster_map( + peaks=motion_info["peaks"], + peak_locations=motion_info["peak_locations"], + recording=recording_preproc, + cmap="Greys_r", + scatter_decimate=10, + depth_lim=(-10, 3000) +) + +# ## Retrieve templates from database + +# + +templates_info = sgen.fetch_templates_database_info() + +print(f"Number of templates in database: {len(templates_info)}") +print(f"Template database columns: {templates_info.columns}") +# - + +available_brain_areas = np.unique(templates_info.brain_area) +print(f"Available brain areas: {available_brain_areas}") + +# Let's perform a query: templates from visual brain regions and at the "top" of the probe + +target_area = ["VISa5", "VISa6a", "VISp5", "VISp6a", "VISrl6b"] +minimum_depth = 1500 +templates_selected_info = templates_info.query(f"brain_area in {target_area} and depth_along_probe > {minimum_depth}") +len(templates_selected_info) + +# We can now retrieve the selected templates as a `Templates` object: + +templates_selected = sgen.query_templates_from_database(templates_selected_info, verbose=True) +print(templates_selected) + +# While we selected templates from a target aread and at certain depths, we can see that the template amplitudes are quite large. This will make spike sorting easy... we can further manipulate the `Templates` by rescaling, relocating, or further selections with the `sgen.scale_template_to_range`, `sgen.relocate_templates`, and `sgen.select_templates` functions. +# +# In our case, let's rescale the amplitudes between 50 and 150 $\mu$V and relocate them towards the bottom half of the probe, where the activity looks interesting! + +# + +min_amplitude = 50 +max_amplitude = 150 +templates_scaled = sgen.scale_template_to_range( + templates=templates_selected, + min_amplitude=min_amplitude, + max_amplitude=max_amplitude +) + +min_displacement = 1000 +max_displacement = 3000 +templates_relocated = sgen.relocate_templates( + templates=templates_scaled, + min_displacement=min_displacement, + max_displacement=max_displacement +) +# - + +# Let's plot the selected templates: + +sparsity_plot = si.compute_sparsity(templates_relocated) +fig = plt.figure(figsize=(10, 10)) +w = sw.plot_unit_templates(templates_relocated, sparsity=sparsity_plot, ncols=4, figure=fig) +w.figure.subplots_adjust(wspace=0.5, hspace=0.7) + +# ## Constructing hybrid recordings +# +# We can construct now hybrid recordings with the selected templates. +# +# We will do this in two ways to show how important it is to account for drifts when injecting hybrid spikes. +# +# - For the first recording we will not pass the estimated motion (`recording_hybrid_ignore_drift`). +# - For the second recording, we will pass and account for the estimated motion (`recording_hybrid_with_drift`). + +recording_hybrid_ignore_drift, sorting_hybrid = sgen.generate_hybrid_recording( + recording=recording_preproc, templates=templates_relocated, seed=2308 +) +recording_hybrid_ignore_drift + +# Note that the `generate_hybrid_recording` is warning us that we might want to account for drift! + +# by passing the `sorting_hybrid` object, we make sure that injected spikes are the same +# this will take a bit more time because it's interpolating the templates to account for drifts +recording_hybrid_with_drift, sorting_hybrid = sgen.generate_hybrid_recording( + recording=recording_preproc, + templates=templates_relocated, + motion=motion_info["motion"], + sorting=sorting_hybrid, + seed=2308, +) +recording_hybrid_with_drift + +# We can use the `SortingAnalyzer` to estimate spike locations and plot them: + +# + +# construct analyzers and compute spike locations +analyzer_hybrid_ignore_drift = si.create_sorting_analyzer(sorting_hybrid, recording_hybrid_ignore_drift) +analyzer_hybrid_ignore_drift.compute(["random_spikes", "templates"]) +analyzer_hybrid_ignore_drift.compute("spike_locations", method="grid_convolution") + +analyzer_hybrid_with_drift = si.create_sorting_analyzer(sorting_hybrid, recording_hybrid_with_drift) +analyzer_hybrid_with_drift.compute(["random_spikes", "templates"]) +analyzer_hybrid_with_drift.compute("spike_locations", method="grid_convolution") +# - + +# Let's plot the added hybrid spikes using the drift maps: + +fig, axs = plt.subplots(ncols=2, figsize=(10, 7), sharex=True, sharey=True) +_ = sw.plot_drift_raster_map( + peaks=motion_info["peaks"], + peak_locations=motion_info["peak_locations"], + recording=recording_preproc, + cmap="Greys_r", + scatter_decimate=10, + ax=axs[0], +) +_ = sw.plot_drift_raster_map( + sorting_analyzer=analyzer_hybrid_ignore_drift, + color_amplitude=False, + color="r", + scatter_decimate=10, + ax=axs[0] +) +_ = sw.plot_drift_raster_map( + peaks=motion_info["peaks"], + peak_locations=motion_info["peak_locations"], + recording=recording_preproc, + cmap="Greys_r", + scatter_decimate=10, + ax=axs[1], +) +_ = sw.plot_drift_raster_map( + sorting_analyzer=analyzer_hybrid_with_drift, + color_amplitude=False, + color="b", + scatter_decimate=10, + ax=axs[1] +) +axs[0].set_title("Hybrid spikes\nIgnoring drift") +axs[1].set_title("Hybrid spikes\nAccounting for drift") +axs[0].set_xlim(1000, 1500) +axs[0].set_ylim(500, 2500) + +# We can see that clearly following drift is essential in order to properly blend the hybrid spikes into the recording! + +# ## Ground-truth study +# +# In this section we will use the hybrid recording to benchmark a few spike sorters: +# +# - `Kilosort2.5` +# - `Kilosort3` +# - `Kilosort4` +# - `Spyking-CIRCUS 2` + +# to speed up computations, let's first dump the recording to binary +recording_hybrid_bin = recording_hybrid_with_drift.save( + folder=workdir / "hybrid_bin", + overwrite=True +) + +# + +datasets = { + "hybrid": (recording_hybrid_bin, sorting_hybrid), +} + +cases = { + ("kilosort2.5", "hybrid"): { + "label": "KS2.5", + "dataset": "hybrid", + "run_sorter_params": { + "sorter_name": "kilosort2_5", + }, + }, + ("kilosort3", "hybrid"): { + "label": "KS3", + "dataset": "hybrid", + "run_sorter_params": { + "sorter_name": "kilosort3", + }, + }, + ("kilosort4", "hybrid"): { + "label": "KS4", + "dataset": "hybrid", + "run_sorter_params": {"sorter_name": "kilosort4", "nblocks": 5}, + }, + ("sc2", "hybrid"): { + "label": "spykingcircus2", + "dataset": "hybrid", + "run_sorter_params": { + "sorter_name": "spykingcircus2", + }, + }, +} + +# + +study_folder = workdir / "gt_study" + +gtstudy = sc.GroundTruthStudy(study_folder) + +# - + +# run the spike sorting jobs +gtstudy.run_sorters(verbose=False, keep=True) + +# run the comparisons +gtstudy.run_comparisons(exhaustive_gt=False) + +# ## Plot performances +# +# Given that we know the exactly where we injected the hybrid spikes, we can now compute and plot performance metrics: accuracy, precision, and recall. +# +# In the following plot, the x axis is the unit index, while the y axis is the performance metric. The units are sorted by performance. + +w_perf = sw.plot_study_performances(gtstudy, figsize=(12, 7)) +w_perf.axes[0, 0].legend(loc=4) + +# From the performance plots, we can see that there is no clear "winner", but `Kilosort3` definitely performs worse than the other options. +# +# Although non of the sorters find all units perfectly, `Kilosort2.5`, `Kilosort4`, and `SpyKING CIRCUS 2` all find around 10-12 hybrid units with accuracy greater than 80%. +# `Kilosort4` has a better overall curve, being able to find almost all units with an accuracy above 50%. `Kilosort2.5` performs well when looking at precision (finding all spikes in a hybrid unit), at the cost of lower recall (finding spikes when it shouldn't). +# +# +# In this example, we showed how to: +# +# - Access and fetch templates from the SpikeInterface template database +# - Manipulate templates (scaling/relocating) +# - Construct hybrid recordings accounting for drifts +# - Use the `GroundTruthStudy` to benchmark different sorters +# +# The hybrid framework can be extended to target multiple recordings from different brain regions and species and creating recordings of increasing complexity to challenge the existing sorters! +# +# In addition, hybrid studies can also be used to fine-tune spike sorting parameters on specific datasets. +# +# **Are you ready to try it on your data?** diff --git a/pyproject.toml b/pyproject.toml index 69f4067d13..644d52608e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -139,6 +139,9 @@ test = [ # preprocessing "ibllib>=2.36.0", # for IBL + # streaming templates + "s3fs", + # tridesclous "numba", "hdbscan>=0.8.33", # Previous version had a broken wheel diff --git a/src/spikeinterface/core/core_tools.py b/src/spikeinterface/core/core_tools.py index 066ab58d8c..4a40d8e425 100644 --- a/src/spikeinterface/core/core_tools.py +++ b/src/spikeinterface/core/core_tools.py @@ -75,6 +75,7 @@ class SIJsonEncoder(json.JSONEncoder): def default(self, obj): from spikeinterface.core.base import BaseExtractor + from spikeinterface.sortingcomponents.motion_utils import Motion # Over-write behaviors for datetime object if isinstance(obj, datetime.datetime): @@ -98,6 +99,9 @@ def default(self, obj): if isinstance(obj, BaseExtractor): return obj.to_dict() + if isinstance(obj, Motion): + return obj.to_dict() + # The base-class handles the assertion return super().default(obj) diff --git a/src/spikeinterface/core/generate.py b/src/spikeinterface/core/generate.py index 9924a22403..af6664b886 100644 --- a/src/spikeinterface/core/generate.py +++ b/src/spikeinterface/core/generate.py @@ -3,7 +3,6 @@ import warnings import numpy as np from typing import Union, Optional, List, Literal -import warnings from math import ceil from .basesorting import SpikeVectorSortingSegment @@ -1858,7 +1857,7 @@ def get_traces( wf = template[start_template:end_template] if self.amplitude_vector is not None: wf = wf * self.amplitude_vector[i] - traces[start_traces:end_traces] += wf + traces[start_traces:end_traces] += wf.astype(traces.dtype, copy=False) return traces.astype(self.dtype, copy=False) diff --git a/src/spikeinterface/core/node_pipeline.py b/src/spikeinterface/core/node_pipeline.py index 0722ede23f..ceff8577d3 100644 --- a/src/spikeinterface/core/node_pipeline.py +++ b/src/spikeinterface/core/node_pipeline.py @@ -516,7 +516,6 @@ def _init_peak_pipeline(recording, nodes): worker_ctx["recording"] = recording worker_ctx["nodes"] = nodes worker_ctx["max_margin"] = max(node.get_trace_margin() for node in nodes) - return worker_ctx diff --git a/src/spikeinterface/core/sortinganalyzer.py b/src/spikeinterface/core/sortinganalyzer.py index d790308b76..fc20029ce6 100644 --- a/src/spikeinterface/core/sortinganalyzer.py +++ b/src/spikeinterface/core/sortinganalyzer.py @@ -970,7 +970,9 @@ def compute_one_extension(self, extension_name, save=True, verbose=False, **kwar extension_class = get_extension_class(extension_name) for child in _get_children_dependencies(extension_name): - self.delete_extension(child) + if self.has_extension(child): + print(f"Deleting {child}") + self.delete_extension(child) if extension_class.need_job_kwargs: params, job_kwargs = split_job_kwargs(kwargs) diff --git a/src/spikeinterface/core/template.py b/src/spikeinterface/core/template.py index 066d79b6b4..b64f0610ea 100644 --- a/src/spikeinterface/core/template.py +++ b/src/spikeinterface/core/template.py @@ -353,9 +353,9 @@ def from_zarr_group(cls, zarr_group: "zarr.Group") -> "Templates": the `add_templates_to_zarr_group` method. """ - templates_array = zarr_group["templates_array"] - channel_ids = zarr_group["channel_ids"] - unit_ids = zarr_group["unit_ids"] + templates_array = zarr_group["templates_array"][:] + channel_ids = zarr_group["channel_ids"][:] + unit_ids = zarr_group["unit_ids"][:] sampling_frequency = zarr_group.attrs["sampling_frequency"] nbefore = zarr_group.attrs["nbefore"] @@ -364,7 +364,7 @@ def from_zarr_group(cls, zarr_group: "zarr.Group") -> "Templates": sparsity_mask = None if "sparsity_mask" in zarr_group: - sparsity_mask = zarr_group["sparsity_mask"] + sparsity_mask = zarr_group["sparsity_mask"][:] probe = None if "probe" in zarr_group: @@ -449,7 +449,7 @@ def __eq__(self, other): return True - def get_channel_locations(self): + def get_channel_locations(self) -> np.ndarray: assert self.probe is not None, "Templates.get_channel_locations() needs a probe to be set" channel_locations = self.probe.contact_positions return channel_locations diff --git a/src/spikeinterface/core/template_tools.py b/src/spikeinterface/core/template_tools.py index 1ba9372322..934b18ed49 100644 --- a/src/spikeinterface/core/template_tools.py +++ b/src/spikeinterface/core/template_tools.py @@ -3,7 +3,6 @@ import warnings from .template import Templates -from .sparsity import _sparsity_doc from .sortinganalyzer import SortingAnalyzer @@ -50,7 +49,7 @@ def _get_nbefore(one_object): raise ValueError("SortingAnalyzer need extension 'templates' to be computed") return ext.nbefore else: - raise ValueError("Input should be Templates or SortingAnalyzer or SortingAnalyzer") + raise ValueError("Input should be Templates or SortingAnalyzer") def get_template_amplitudes( diff --git a/src/spikeinterface/generation/__init__.py b/src/spikeinterface/generation/__init__.py index eae6320e8d..7a2291d932 100644 --- a/src/spikeinterface/generation/__init__.py +++ b/src/spikeinterface/generation/__init__.py @@ -5,6 +5,14 @@ InjectDriftingTemplatesRecording, make_linear_displacement, ) + +from .hybrid_tools import ( + generate_hybrid_recording, + estimate_templates_from_recording, + select_templates, + scale_template_to_range, + relocate_templates, +) from .noise_tools import generate_noise from .drifting_generator import ( make_one_displacement_vector, diff --git a/src/spikeinterface/generation/drift_tools.py b/src/spikeinterface/generation/drift_tools.py index 99e4f4d36e..1f410f4330 100644 --- a/src/spikeinterface/generation/drift_tools.py +++ b/src/spikeinterface/generation/drift_tools.py @@ -1,10 +1,12 @@ from __future__ import annotations + +import math from typing import Optional import numpy as np from numpy.typing import ArrayLike -from spikeinterface.core import Templates, BaseRecording, BaseSorting, BaseRecordingSegment -import math +from probeinterface import Probe +from spikeinterface.core import BaseRecording, BaseRecordingSegment, BaseSorting, Templates def interpolate_templates(templates_array, source_locations, dest_locations, interpolation_method="cubic"): @@ -116,22 +118,80 @@ class DriftingTemplates(Templates): This is the same strategy used by MEArec. """ - def __init__(self, **kwargs): - Templates.__init__(self, **kwargs) + def __init__(self, templates_array_moved=None, displacements=None, **static_kwargs): + Templates.__init__(self, **static_kwargs) assert self.probe is not None, "DriftingTemplates need a Probe in the init" - - self.templates_array_moved = None - self.displacements = None + if templates_array_moved is not None: + if displacements is None: + raise ValueError( + "Please pass both template_array_moved and displacements to DriftingTemplates " + "if you are using precomputed displaced templates." + ) + self.templates_array_moved = templates_array_moved + self.displacements = displacements @classmethod - def from_static(cls, templates): - drifting_teplates = cls( + def from_static_templates(cls, templates: Templates): + """ + Construct a DriftingTemplates object given static templates. + The drifting templates can be then computed using the `precompute_displacements` method. + + Parameters + ---------- + templates : Templates + The static templates. + + Returns + ------- + drifting_templates : DriftingTemplates + The drifting templates object. + + """ + drifting_templates = cls( templates_array=templates.templates_array, sampling_frequency=templates.sampling_frequency, nbefore=templates.nbefore, probe=templates.probe, ) - return drifting_teplates + return drifting_templates + + @classmethod + def from_precomputed_templates( + cls, + templates_array_moved: ArrayLike, + displacements: ArrayLike, + sampling_frequency: float, + nbefore: int, + probe: Probe, + ): + """Construct a DriftingTemplates object given precomputed drifting templates + + Parameters + ---------- + templates_array_moved : np.array + Shape is (num_displacement, num_templates, num_samples, num_channels) + displacements : np.array + Shape is (num_displacement, 2). Last axis is xy, as in make_linear_displacement below. + sampling_frequency : float + nbefore : int + probe : probeinterface.Probe + + Returns + ------- + drifting_templates : DriftingTemplates + The drifting templates object. + """ + # take the central templates as representatives, just to make the super() + # constructor happy. they won't be used as drifting templates. + templates_static = templates_array_moved[templates_array_moved.shape[0] // 2] + return cls( + templates_array=templates_static, + sampling_frequency=sampling_frequency, + nbefore=nbefore, + probe=probe, + templates_array_moved=templates_array_moved, + displacements=displacements, + ) def move_one_template(self, unit_index, displacement, **interpolation_kwargs): """ @@ -442,7 +502,8 @@ def __init__( # TODO: self.upsample_vector = upsample_vector self.upsample_vector = None self.parent_recording = parent_recording_segment - self.num_samples = parent_recording_segment.get_num_frames() if num_samples is None else num_samples + self.num_samples = parent_recording_segment.get_num_samples() if num_samples is None else num_samples + self.num_samples = int(num_samples) self.displacement_indices = displacement_indices self.templates_array_moved = templates_array_moved @@ -507,7 +568,7 @@ def get_traces( wf = template[start_template:end_template] if self.amplitude_vector is not None: wf *= self.amplitude_vector[i] - traces[start_traces:end_traces] += wf + traces[start_traces:end_traces] += wf.astype(self.dtype, copy=False) return traces.astype(self.dtype) diff --git a/src/spikeinterface/generation/drifting_generator.py b/src/spikeinterface/generation/drifting_generator.py index 7f617c3ade..a0e8ece37e 100644 --- a/src/spikeinterface/generation/drifting_generator.py +++ b/src/spikeinterface/generation/drifting_generator.py @@ -25,12 +25,18 @@ # this should be moved in probeinterface but later _toy_probes = { + "Neuropixel-384": dict( + num_columns=4, + num_contact_per_column=[96] * 4, + xpitch=16, + ypitch=40, + y_shift_per_column=[20, 0, 20, 0], + contact_shapes="square", + contact_shape_params={"width": 12}, + ), "Neuropixel-128": dict( num_columns=4, - num_contact_per_column=[ - 32, - ] - * 4, + num_contact_per_column=[32] * 4, xpitch=16, ypitch=40, y_shift_per_column=[20, 0, 20, 0], @@ -66,22 +72,24 @@ def make_one_displacement_vector( Parameters ---------- - drift_mode: "zigzag" | "bumps", default: "zigzag" - The drift mode - duration: float, default: 600 + drift_mode : "zigzag" | "bumps", default: "zigzag" + The drift mode. + duration : float, default: 600 Duration in seconds - displacement_sampling_frequency: float, default: 5 - Sample rate of the vector - t_start_drift: float | None, default: None - Time in s when drift starts - t_end_drift: float | None, default: None - Time in s when drift ends - period_s: float, default: 200. + amplitude_factor : float, default: 1 + The amplitude factor of the drift. + displacement_sampling_frequency : float, default: 5 + Sample rate of the vector. + t_start_drift : float | None, default: None + Time in s when drift starts. + t_end_drift : float | None, default: None + Time in s when drift ends. + period_s : float, default: 200. Period of the zigzag in seconds - bump_interval_s: tuple, default: (30, 90.) - Range interval between random bumps in seconds - seed: None | int - The seed for the random bumps + bump_interval_s : tuple, default: (30, 90.) + Range interval between random bumps in seconds. + seed : None | int + The seed for the random bumps. Returns ------- @@ -170,34 +178,34 @@ def generate_displacement_vector( Parameters ---------- - duration: float + duration : float Duration of the displacement vector in seconds - unit_locations: np.array + unit_locations : np.array The unit location with shape (num_units, 3) - displacement_sampling_frequency: float, default: 5. + displacement_sampling_frequency : float, default: 5. The sampling frequency of the displacement vector - drift_start_um: list of float, default: [0, 20.] - The start boundary of the motion - drift_stop_um: list of float, default: [0, -20.] - The stop boundary of the motion - drift_step_um: float, default: 1 + drift_start_um : list of float, default: [0, 20.] + The start boundary of the motion in the x and y direction. + drift_stop_um : list of float, default: [0, -20.] + The stop boundary of the motion in the x and y direction. + drift_step_um : float, default: 1 Use to create the displacements_steps array. This ensures an odd number of steps - motion_list: list of dict + motion_list : list of dict List of dicts containing individual motion vector parameters. len(motion_list) == displacement_vectors.shape[2] Returns ------- - displacement_vectors: numpy.ndarray + displacement_vectors : numpy.ndarray The drift vector is a numpy array with shape (num_times, 2, num_motions) num_motions is generally 1, but can be > 1 in case of combining several drift vectors - displacement_unit_factor: numpy array | None, default: None + displacement_unit_factor : numpy array | None, default: None A array containing the factor per unit of each drift (num_units, num_motions). This is used to create non-rigid drift with a factor gradient of depending on the unit positions - displacement_sampling_frequency: float + displacement_sampling_frequency : float The sampling frequency of drift vector - displacements_steps: numpy array + displacements_steps : numpy array Position of the motion steps (from start to step) with shape (num_step, 2) """ @@ -295,38 +303,38 @@ def generate_drifting_recording( Parameters ---------- - num_units: int, default: 250 + num_units : int, default: 250 Number of units. - duration: float, default: 600. + duration : float, default: 600. The duration in seconds. - sampling_frequency: float, dfault: 30000. + sampling_frequency : float, dfault: 30000. The sampling frequency. - probe_name: str, default: "Neuropixel-128" + probe_name : str, default: "Neuropixel-128" The probe type if generate_probe_kwargs is None. - generate_probe_kwargs: None or dict + generate_probe_kwargs : None or dict A dict to generate the probe, this supersede probe_name when not None. - generate_unit_locations_kwargs: dict + generate_unit_locations_kwargs : dict Parameters given to generate_unit_locations(). - generate_displacement_vector_kwargs: dict + generate_displacement_vector_kwargs : dict Parameters given to generate_displacement_vector(). - generate_templates_kwargs: dict + generate_templates_kwargs : dict Parameters given to generate_templates() - generate_sorting_kwargs: dict + generate_sorting_kwargs : dict Parameters given to generate_sorting(). - generate_noise_kwargs: dict + generate_noise_kwargs : dict Parameters given to generate_noise(). - extra_outputs: bool, default False + extra_outputs : bool, default False Return optionaly a dict with more variables. - seed: None ot int + seed : None ot int A unique seed for all steps. Returns ------- - static_recording: Recording + static_recording : Recording A generated recording with no motion. - drifting_recording: Recording + drifting_recording : Recording A generated recording with motion. - sorting: Sorting + sorting : Sorting The ground trith soring object. Same for both recordings. extra_infos: @@ -407,7 +415,7 @@ def generate_drifting_recording( is_scaled=True, ) - drifting_templates = DriftingTemplates.from_static(templates) + drifting_templates = DriftingTemplates.from_static_templates(templates) sorting = generate_sorting( num_units=num_units, diff --git a/src/spikeinterface/generation/hybrid_tools.py b/src/spikeinterface/generation/hybrid_tools.py new file mode 100644 index 0000000000..a57e090f5f --- /dev/null +++ b/src/spikeinterface/generation/hybrid_tools.py @@ -0,0 +1,568 @@ +from __future__ import annotations + +import warnings +from typing import Literal +import numpy as np + +from spikeinterface.core import BaseRecording, BaseSorting, Templates + +from spikeinterface.core.generate import ( + generate_templates, + generate_unit_locations, + generate_sorting, + InjectTemplatesRecording, + _ensure_seed, +) +from spikeinterface.core.template_tools import get_template_extremum_channel + +from spikeinterface.sortingcomponents.motion_utils import Motion + +from spikeinterface.generation.drift_tools import ( + InjectDriftingTemplatesRecording, + DriftingTemplates, + make_linear_displacement, + interpolate_templates, + move_dense_templates, +) + + +def estimate_templates_from_recording( + recording: BaseRecording, + ms_before: float = 2, + ms_after: float = 2, + sorter_name: str = "spykingcircus2", + run_sorter_kwargs: dict | None = None, + job_kwargs: dict | None = None, +): + """ + Get dense templates from a recording. Internally, SpyKING CIRCUS 2 is used by default + with the only twist that the template matching step is not launched. Instead, a Template + object is returned based on the results of the clustering. Other sorters can be invoked + with the `sorter_name` and `run_sorter_kwargs` parameters. + + Parameters + ---------- + ms_before : float + The time before peaks of templates. + ms_after : float + The time after peaks of templates. + sorter_name : str + The sorter to be used in order to get some fast clustering. + run_sorter_kwargs : dict + The parameters to provide to the run_sorter function of spikeinterface. + job_kwargs : dict + The jobe keyword arguments to be used in the estimation of the templates. + + Returns + ------- + templates: Templates + The estimated templates + """ + from spikeinterface.core.waveform_tools import estimate_templates + from spikeinterface.sorters.runsorter import run_sorter + + if sorter_name == "spykingcircus2": + if "matching" not in run_sorter_kwargs: + run_sorter_kwargs["matching"] = {"method": None} + + run_sorter_kwargs = run_sorter_kwargs or {} + sorting = run_sorter(sorter_name, recording, **run_sorter_kwargs) + + spikes = sorting.to_spike_vector() + unit_ids = sorting.unit_ids + sampling_frequency = recording.get_sampling_frequency() + nbefore = int(ms_before * sampling_frequency / 1000.0) + nafter = int(ms_after * sampling_frequency / 1000.0) + + job_kwargs = job_kwargs or {} + templates_array = estimate_templates(recording, spikes, unit_ids, nbefore, nafter, **job_kwargs) + + sparsity_mask = None + channel_ids = recording.channel_ids + probe = recording.get_probe() + + templates = Templates( + templates_array, sampling_frequency, nbefore, True, sparsity_mask, channel_ids, unit_ids, probe=probe + ) + + return templates + + +def select_templates( + templates: Templates, + min_amplitude: float | None = None, + max_amplitude: float | None = None, + min_depth: float | None = None, + max_depth: float | None = None, + amplitude_function: Literal["ptp", "min", "max"] = "ptp", + depth_direction: Literal["x", "y"] = "y", +): + """ + Select templates from an existing Templates object based on amplitude and depth. + + Parameters + ---------- + templates : Templates + The input templates. + min_amplitude : float | None, default: None + The minimum amplitude of the templates. + max_amplitude : float | None, default: None + The maximum amplitude of the templates. + min_depth : float | None, default: None + The minimum depth of the templates. + max_depth : float | None, default: None + The maximum depth of the templates. + amplitude_function : "ptp" | "min" | "max", default: "ptp" + The function to use to compute the amplitude of the templates. Can be "ptp", "min" or "max". + depth_direction : "x" | "y", default: "y" + The direction in which to move the templates. Can be "x" or "y". + + Returns + ------- + Templates + The selected templates + """ + assert ( + min_amplitude is not None or max_amplitude is not None or min_depth is not None or max_depth is not None + ), "At least one of min_amplitude, max_amplitude, min_depth, max_depth should be provided" + # get template amplitudes and depth + extremum_channel_indices = list(get_template_extremum_channel(templates, outputs="index").values()) + extremum_channel_indices = np.array(extremum_channel_indices, dtype=int) + + mask = np.ones(templates.num_units, dtype=bool) + if min_amplitude is not None or max_amplitude is not None: + # filter amplitudes + if amplitude_function == "ptp": + amp_fun = np.ptp + elif amplitude_function == "min": + amp_fun = np.min + elif amplitude_function == "max": + amp_fun = np.max + amplitudes = np.zeros(templates.num_units) + templates_array = templates.templates_array + for i in range(templates.num_units): + amplitudes[i] = amp_fun(templates_array[i, :, extremum_channel_indices[i]]) + if min_amplitude is not None: + mask &= amplitudes >= min_amplitude + if max_amplitude is not None: + mask &= amplitudes <= max_amplitude + if min_depth is not None or max_depth is not None: + assert templates.probe is not None, "Templates should have a probe to filter based on depth" + depth_dimension = ["x", "y"].index(depth_direction) + channel_depths = templates.get_channel_locations()[:, depth_dimension] + unit_depths = channel_depths[extremum_channel_indices] + if min_depth is not None: + mask &= unit_depths >= min_depth + if max_depth is not None: + mask &= unit_depths <= max_depth + if np.sum(mask) == 0: + warnings.warn("No templates left after filtering") + return None + filtered_unit_ids = templates.unit_ids[mask] + filtered_templates = templates.select_units(filtered_unit_ids) + + return filtered_templates + + +def scale_template_to_range( + templates: Templates, + min_amplitude: float, + max_amplitude: float, + amplitude_function: Literal["ptp", "min", "max"] = "ptp", +): + """ + Scale templates to have a range with the provided minimum and maximum amplitudes. + + Parameters + ---------- + templates : Templates + The input templates. + min_amplitude : float + The minimum amplitude of the output templates after scaling. + max_amplitude : float + The maximum amplitude of the output templates after scaling. + + Returns + ------- + Templates + The scaled templates. + """ + extremum_channel_indices = list(get_template_extremum_channel(templates, outputs="index").values()) + extremum_channel_indices = np.array(extremum_channel_indices, dtype=int) + + # get amplitudes + if amplitude_function == "ptp": + amp_fun = np.ptp + elif amplitude_function == "min": + amp_fun = np.min + elif amplitude_function == "max": + amp_fun = np.max + amplitudes = np.zeros(templates.num_units) + templates_array = templates.templates_array + for i in range(templates.num_units): + amplitudes[i] = amp_fun(templates_array[i, :, extremum_channel_indices[i]]) + + # scale templates to meet min_amplitude and max_amplitude range + min_scale = np.min(amplitudes) / min_amplitude + max_scale = np.max(amplitudes) / max_amplitude + m = (max_scale - min_scale) / (np.max(amplitudes) - np.min(amplitudes)) + scales = m * (amplitudes - np.min(amplitudes)) + min_scale + + scaled_templates_array = templates.templates_array / scales[:, None, None] + + return Templates( + templates_array=scaled_templates_array, + sampling_frequency=templates.sampling_frequency, + nbefore=templates.nbefore, + sparsity_mask=templates.sparsity_mask, + channel_ids=templates.channel_ids, + unit_ids=templates.unit_ids, + probe=templates.probe, + ) + + +def relocate_templates( + templates: Templates, + min_displacement: float, + max_displacement: float, + margin: float = 0.0, + favor_borders: bool = True, + depth_direction: Literal["x", "y"] = "y", + seed: int | None = None, +): + """ + Relocates templates to have a minimum and maximum displacement. + + Parameters + ---------- + templates : Templates + The input templates + min_displacement : float + The minimum displacement of the templates + max_displacement : float + The maximum displacement of the templates + margin : float, default: 0.0 + The margin to keep between the templates and the borders of the probe. + If greater than 0, the templates are allowed to go beyond the borders of the probe. + favor_borders : bool, default: True + If True, the templates are always moved to the borders of the probe if this is + possoble based on the min_displacement and max_displacement constraints. + This avoids a bias in moving templates towards the center of the probe. + depth_direction : "x" | "y", default: "y" + The direction in which to move the templates. Can be "x" or "y" + seed : int or None, default: None + Seed for random initialization. + + + Returns + ------- + Templates + The relocated templates. + """ + seed = _ensure_seed(seed) + + extremum_channel_indices = list(get_template_extremum_channel(templates, outputs="index").values()) + extremum_channel_indices = np.array(extremum_channel_indices, dtype=int) + depth_dimension = ["x", "y"].index(depth_direction) + channel_depths = templates.get_channel_locations()[:, depth_dimension] + unit_depths = channel_depths[extremum_channel_indices] + + assert margin >= 0, "margin should be positive" + top_margin = np.max(channel_depths) + margin + bottom_margin = np.min(channel_depths) - margin + + templates_array_moved = np.zeros_like(templates.templates_array, dtype=templates.templates_array.dtype) + + rng = np.random.default_rng(seed) + displacements = rng.uniform(low=min_displacement, high=max_displacement, size=templates.num_units) + for i in range(templates.num_units): + # by default, displacement is positive + displacement = displacements[i] + unit_depth = unit_depths[i] + if not favor_borders: + displacement *= rng.choice([-1.0, 1.0]) + if unit_depth + displacement > top_margin: + displacement = -displacement + elif unit_depth - displacement < bottom_margin: + displacement = -displacement + else: + # check if depth is closer to top or bottom + if unit_depth > (top_margin - bottom_margin) / 2: + # if over top margin, move down + if unit_depth + displacement > top_margin: + displacement = -displacement + else: + # if within bottom margin, move down + if unit_depth - displacement >= bottom_margin: + displacement = -displacement + displacement_vector = np.zeros(2) + displacement_vector[depth_dimension] = displacement + templates_array_moved[i] = move_dense_templates( + templates.templates_array[i][None], + displacements=displacement_vector[None], + source_probe=templates.probe, + )[0] + + return Templates( + templates_array=templates_array_moved, + sampling_frequency=templates.sampling_frequency, + nbefore=templates.nbefore, + sparsity_mask=templates.sparsity_mask, + channel_ids=templates.channel_ids, + unit_ids=templates.unit_ids, + probe=templates.probe, + ) + + +def generate_hybrid_recording( + recording: BaseRecording, + sorting: BaseSorting | None = None, + templates: Templates | None = None, + motion: Motion | None = None, + are_templates_scaled: bool = True, + unit_locations: np.ndarray | None = None, + drift_step_um: float = 1.0, + upsample_factor: int | None = None, + upsample_vector: np.ndarray | None = None, + amplitude_std: float = 0.05, + generate_sorting_kwargs: dict = dict(num_units=10, firing_rates=15, refractory_period_ms=4.0, seed=2205), + generate_unit_locations_kwargs: dict = dict(margin_um=10.0, minimum_z=5.0, maximum_z=50.0, minimum_distance=20), + generate_templates_kwargs: dict = dict(ms_before=1.0, ms_after=3.0), + seed: int | None = None, +) -> tuple[BaseRecording, BaseSorting]: + """ + Generate an hybrid recording with spike given sorting+templates. + + The function starts from an existing recording and injects hybrid units in it. + The templates can be provided or generated. If the templates are not provided, + they are generated (using the `spikeinterface.core.generate.generate_templates()` function + and with arguments provided in `generate_templates_kwargs`). + The sorting can be provided or generated. If the sorting is not provided, it is generated + (using the `spikeinterface.core.generate.generate_sorting` function and with arguments + provided in `generate_sorting_kwargs`). + The injected spikes can optionally follow a motion pattern provided by a Motion object. + + Parameters + ---------- + recording : BaseRecording + The recording to inject units in. + sorting : Sorting | None, default: None + An external sorting object. If not provide, one is generated. + templates : Templates | None, default: None + The templates of units. + If None they are generated. + motion : Motion | None, default: None + The motion object to use for the drifting templates. + are_templates_scaled : bool, default: True + If True, the templates are assumed to be in uV, otherwise in the same unit as the recording. + In case the recording has scaling, the templates are "unscaled" before injection. + ms_before : float, default: 1.5 + Cut out in ms before spike peak. + ms_after : float, default: 3 + Cut out in ms after spike peak. + unit_locations : np.array, default: None + The locations at which the templates should be injected. If not provided, generated (see + generate_unit_location_kwargs). + drift_step_um : float, default: 1.0 + The step in um to use for the drifting templates. + upsample_factor : None or int, default: None + A upsampling factor used only when templates are not provided. + upsample_vector : np.array or None + Optional the upsample_vector can given. This has the same shape as spike_vector + amplitude_std : float, default: 0.05 + The standard deviation of the modulation to apply to the spikes when injecting them + into the recording. + generate_sorting_kwargs : dict + When sorting is not provide, this dict is used to generated a Sorting. + generate_unit_locations_kwargs : dict + Dict used to generated template when template not provided. + generate_templates_kwargs : dict + Dict used to generated template when template not provided. + seed : int or None + Seed for random initialization. + If None a diffrent Recording is generated at every call. + Note: even with None a generated recording keep internaly a seed to regenerate the same signal after dump/load. + + Returns + ------- + recording: BaseRecording + The generated hybrid recording extractor. + sorting: Sorting + The generated sorting extractor for the injected units. + """ + + # if None so the same seed will be used for all steps + seed = _ensure_seed(seed) + rng = np.random.default_rng(seed) + + sampling_frequency = recording.sampling_frequency + probe = recording.get_probe() + num_segments = recording.get_num_segments() + dtype = recording.dtype + durations = np.array([recording.get_duration(segment_index) for segment_index in range(num_segments)]) + channel_locations = probe.contact_positions + + assert ( + templates is not None or sorting is not None or generate_sorting_kwargs is not None + ), "Provide templates or sorting or generate_sorting_kwargs" + + # check num_units + num_units = None + if templates is not None: + assert isinstance(templates, Templates), "templates should be a Templates object" + num_units = templates.num_units + if sorting is not None: + assert isinstance(sorting, BaseSorting), "sorting should be a Sorting object" + if num_units is not None: + assert num_units == sorting.get_num_units(), "num_units should be the same in templates and sorting" + else: + num_units = sorting.get_num_units() + if num_units is None: + assert "num_units" in generate_sorting_kwargs, "num_units should be provided in generate_sorting_kwargs" + num_units = generate_sorting_kwargs["num_units"] + else: + generate_sorting_kwargs["num_units"] = num_units + + if templates is None: + if unit_locations is None: + unit_locations = generate_unit_locations(num_units, channel_locations, **generate_unit_locations_kwargs) + else: + assert len(unit_locations) == num_units, "unit_locations and num_units should have the same length" + templates_array = generate_templates( + channel_locations, + unit_locations, + sampling_frequency, + upsample_factor=upsample_factor, + seed=seed, + dtype=dtype, + **generate_templates_kwargs, + ) + ms_before = generate_templates_kwargs["ms_before"] + ms_after = generate_templates_kwargs["ms_after"] + nbefore = int(ms_before * sampling_frequency / 1000.0) + nafter = int(ms_after * sampling_frequency / 1000.0) + templates_ = Templates(templates_array, sampling_frequency, nbefore, True, None, None, None, probe) + else: + from spikeinterface.postprocessing.localization_tools import compute_monopolar_triangulation + + assert isinstance(templates, Templates), "templates should be a Templates object" + assert ( + templates.num_channels == recording.get_num_channels() + ), "templates and recording should have the same number of channels" + nbefore = templates.nbefore + nafter = templates.nafter + unit_locations = compute_monopolar_triangulation(templates) + + channel_locations_rel = channel_locations - channel_locations[0] + templates_locations = templates.get_channel_locations() + templates_locations_rel = templates_locations - templates_locations[0] + + if not np.allclose(channel_locations_rel, templates_locations_rel): + warnings.warn("Channel locations are different between recording and templates. Interpolating templates.") + templates_array = np.zeros(templates.templates_array.shape, dtype=dtype) + for i in range(len(templates_array)): + src_template = templates.templates_array[i][np.newaxis, :, :] + templates_array[i] = interpolate_templates(src_template, templates_locations_rel, channel_locations_rel) + else: + templates_array = templates.templates_array + + # manage scaling of templates + templates_ = templates + if recording.has_scaleable_traces(): + if are_templates_scaled: + templates_array = (templates_array - recording.get_channel_offsets()) / recording.get_channel_gains() + # make a copy of the templates and reset templates_array (might have scaled templates) + templates_ = templates.select_units(templates.unit_ids) + templates_.templates_array = templates_array + + if sorting is None: + generate_sorting_kwargs = generate_sorting_kwargs.copy() + generate_sorting_kwargs["durations"] = durations + generate_sorting_kwargs["sampling_frequency"] = sampling_frequency + generate_sorting_kwargs["seed"] = seed + sorting = generate_sorting(**generate_sorting_kwargs) + else: + assert sorting.sampling_frequency == sampling_frequency + + num_spikes = sorting.to_spike_vector().size + sorting.set_property("gt_unit_locations", unit_locations) + + assert (nbefore + nafter) == templates_array.shape[ + 1 + ], "templates and ms_before, ms_after should have the same length" + + if templates_array.ndim == 3: + upsample_vector = None + else: + if upsample_vector is None: + upsample_factor = templates_array.shape[3] + upsample_vector = rng.integers(0, upsample_factor, size=num_spikes) + + if amplitude_std is not None: + amplitude_factor = rng.normal(loc=1, scale=amplitude_std, size=num_spikes) + else: + amplitude_factor = None + + if motion is not None: + assert num_segments == motion.num_segments, "recording and motion should have the same number of segments" + dim = motion.dim + motion_array_concat = np.concatenate(motion.displacement) + if dim == 0: + start = np.array([np.min(motion_array_concat), 0]) + stop = np.array([np.max(motion_array_concat), 0]) + elif dim == 1: + start = np.array([0, np.min(motion_array_concat)]) + stop = np.array([0, np.max(motion_array_concat)]) + elif dim == 2: + raise NotImplementedError("3D motion not implemented yet") + num_step = int((stop - start)[dim] / drift_step_um) + displacements = make_linear_displacement(start, stop, num_step=num_step) + + # use templates_, because templates_array might have been scaled + drifting_templates = DriftingTemplates.from_static_templates(templates_) + drifting_templates.precompute_displacements(displacements) + + # calculate displacement vectors for each segment and unit + # for each unit, we interpolate the motion at its location + displacement_sampling_frequency = 1.0 / np.diff(motion.temporal_bins_s[0])[0] + displacement_vectors = [] + for segment_index in range(motion.num_segments): + temporal_bins_segment = motion.temporal_bins_s[segment_index] + displacement_vector = np.zeros((len(temporal_bins_segment), 2, num_units)) + for unit_index in range(num_units): + motion_for_unit = motion.get_displacement_at_time_and_depth( + times_s=temporal_bins_segment, + locations_um=unit_locations[unit_index], + segment_index=segment_index, + grid=True, + ) + displacement_vector[:, motion.dim, unit_index] = motion_for_unit[motion.dim, :] + displacement_vectors.append(displacement_vector) + # since displacement is estimated by interpolation for each unit, the unit factor is an eye + displacement_unit_factor = np.eye(num_units) + + hybrid_recording = InjectDriftingTemplatesRecording( + sorting=sorting, + parent_recording=recording, + drifting_templates=drifting_templates, + displacement_vectors=displacement_vectors, + displacement_sampling_frequency=displacement_sampling_frequency, + displacement_unit_factor=displacement_unit_factor, + num_samples=(np.array(durations) * sampling_frequency).astype("int64"), + amplitude_factor=amplitude_factor, + ) + + else: + warnings.warn( + "No Motion is provided! Please check that your recording is drift-free, otherwise the hybrid recording " + "will have stationary units over a drifting recording..." + ) + hybrid_recording = InjectTemplatesRecording( + sorting, + templates_array, + nbefore=nbefore, + parent_recording=recording, + upsample_vector=upsample_vector, + ) + + return hybrid_recording, sorting diff --git a/src/spikeinterface/generation/noise_tools.py b/src/spikeinterface/generation/noise_tools.py index 48555b3062..11f30e352f 100644 --- a/src/spikeinterface/generation/noise_tools.py +++ b/src/spikeinterface/generation/noise_tools.py @@ -10,25 +10,24 @@ def generate_noise( Parameters ---------- - probe: Probe + probe : Probe A probe object. - sampling_frequency: float + sampling_frequency : float Sampling frequency - durations: list of float + durations : list of float Durations - dtype: np.dtype + dtype : np.dtype Dtype - noise_levels: float | np.array | tuple + noise_levels : float | np.array | tuple If scalar same noises on all channels. If array then per channels noise level. If tuple, then this represent the range. - - seed: None | int + seed : None | int The seed for random generator. Returns ------- - noise: NoiseGeneratorRecording + noise : NoiseGeneratorRecording A lazy noise generator recording. """ diff --git a/src/spikeinterface/generation/tests/test_drift_tools.py b/src/spikeinterface/generation/tests/test_drift_tools.py index 8a4837100e..5647b33930 100644 --- a/src/spikeinterface/generation/tests/test_drift_tools.py +++ b/src/spikeinterface/generation/tests/test_drift_tools.py @@ -94,11 +94,12 @@ def test_move_dense_templates(): def test_DriftingTemplates(): static_templates = make_some_templates() - drifting_templates = DriftingTemplates.from_static(static_templates) + drifting_templates = DriftingTemplates.from_static_templates(static_templates) displacement = np.array([[5.0, 10.0]]) unit_index = 0 moved_template_array = drifting_templates.move_one_template(unit_index, displacement) + assert not np.array_equal(moved_template_array, static_templates.templates_array[unit_index]) num_move = 5 amplitude_motion_um = 20 @@ -112,6 +113,25 @@ def test_DriftingTemplates(): static_templates.num_channels, ) + # test from precomputed + drifting_templates_from_precomputed = DriftingTemplates.from_precomputed_templates( + templates_array_moved=drifting_templates.templates_array_moved, + displacements=drifting_templates.displacements, + sampling_frequency=drifting_templates.sampling_frequency, + probe=drifting_templates.probe, + nbefore=drifting_templates.nbefore, + ) + assert drifting_templates_from_precomputed.templates_array_moved.shape == ( + num_move, + static_templates.num_units, + static_templates.num_samples, + static_templates.num_channels, + ) + assert np.array_equal( + drifting_templates_from_precomputed.templates_array_moved, drifting_templates.templates_array_moved + ) + assert np.array_equal(drifting_templates_from_precomputed.displacements, drifting_templates.displacements) + def test_InjectDriftingTemplatesRecording(create_cache_folder): cache_folder = create_cache_folder @@ -119,7 +139,7 @@ def test_InjectDriftingTemplatesRecording(create_cache_folder): probe = templates.probe # drifting templates - drifting_templates = DriftingTemplates.from_static(templates) + drifting_templates = DriftingTemplates.from_static_templates(templates) channel_locations = probe.contact_positions num_units = templates.unit_ids.size diff --git a/src/spikeinterface/generation/tests/test_hybrid_tools.py b/src/spikeinterface/generation/tests/test_hybrid_tools.py new file mode 100644 index 0000000000..d31a0ec81d --- /dev/null +++ b/src/spikeinterface/generation/tests/test_hybrid_tools.py @@ -0,0 +1,83 @@ +import numpy as np + +from spikeinterface.core import Templates +from spikeinterface.core.generate import ( + generate_ground_truth_recording, + generate_sorting, + generate_templates, + generate_unit_locations, +) +from spikeinterface.preprocessing.motion import correct_motion, load_motion_info +from spikeinterface.generation.hybrid_tools import ( + estimate_templates_from_recording, + generate_hybrid_recording, +) + + +def test_generate_hybrid_no_motion(): + rec, _ = generate_ground_truth_recording(sampling_frequency=20000, seed=0) + hybrid, _ = generate_hybrid_recording(rec, seed=0) + assert rec.get_num_channels() == hybrid.get_num_channels() + assert rec.get_num_frames() == hybrid.get_num_frames() + assert rec.get_num_segments() == hybrid.get_num_segments() + assert np.array_equal(rec.get_channel_locations(), hybrid.get_channel_locations()) + + +def test_generate_hybrid_with_sorting(): + gt_sorting = generate_sorting(durations=[10], num_units=20, sampling_frequency=20000, seed=0) + rec, _ = generate_ground_truth_recording(durations=[10], sampling_frequency=20000, sorting=gt_sorting, seed=0) + hybrid, sorting_hybrid = generate_hybrid_recording(rec, sorting=gt_sorting) + assert rec.get_num_channels() == hybrid.get_num_channels() + assert rec.get_num_frames() == hybrid.get_num_frames() + assert rec.get_num_segments() == hybrid.get_num_segments() + assert np.array_equal(rec.get_channel_locations(), hybrid.get_channel_locations()) + assert sorting_hybrid.get_num_units() == len(hybrid.templates) + + +def test_generate_hybrid_motion(): + rec, _ = generate_ground_truth_recording(sampling_frequency=20000, durations=[10], seed=0) + _, motion_info = correct_motion(rec, output_motion_info=True) + motion = motion_info["motion"] + hybrid, sorting_hybrid = generate_hybrid_recording(rec, motion=motion, seed=0) + assert rec.get_num_channels() == hybrid.get_num_channels() + assert rec.get_num_frames() == hybrid.get_num_frames() + assert rec.get_num_segments() == hybrid.get_num_segments() + assert np.array_equal(rec.get_channel_locations(), hybrid.get_channel_locations()) + assert sorting_hybrid.get_num_units() == len(hybrid.drifting_templates.unit_ids) + + +def test_generate_hybrid_from_templates(): + num_units = 10 + ms_before = 2 + ms_after = 4 + rec, _ = generate_ground_truth_recording(sampling_frequency=20000, seed=0) + channel_locations = rec.get_channel_locations() + unit_locations = generate_unit_locations(num_units, channel_locations=channel_locations, seed=0) + templates_array = generate_templates( + channel_locations, unit_locations, rec.sampling_frequency, ms_before, ms_after, seed=0 + ) + nbefore = int(ms_before * rec.sampling_frequency / 1000) + templates = Templates(templates_array, rec.sampling_frequency, nbefore, True, None, None, None, rec.get_probe()) + hybrid, sorting_hybrid = generate_hybrid_recording(rec, templates=templates, seed=0) + assert np.array_equal(hybrid.templates, templates.templates_array) + assert rec.get_num_channels() == hybrid.get_num_channels() + assert rec.get_num_frames() == hybrid.get_num_frames() + assert rec.get_num_segments() == hybrid.get_num_segments() + assert np.array_equal(rec.get_channel_locations(), hybrid.get_channel_locations()) + assert sorting_hybrid.get_num_units() == num_units + + +def test_estimate_templates(create_cache_folder): + cache_folder = create_cache_folder + rec, _ = generate_ground_truth_recording(num_units=10, sampling_frequency=20000, seed=0) + templates = estimate_templates_from_recording( + rec, run_sorter_kwargs=dict(folder=cache_folder / "sc", remove_existing_folder=True) + ) + assert len(templates.templates_array) > 0 + + +if __name__ == "__main__": + test_generate_hybrid_no_motion() + test_generate_hybrid_motion() + test_estimate_templates() + test_generate_hybrid_with_sorting() diff --git a/src/spikeinterface/generation/tests/test_mock.py b/src/spikeinterface/generation/tests/test_mock.py deleted file mode 100644 index 37c6bde47e..0000000000 --- a/src/spikeinterface/generation/tests/test_mock.py +++ /dev/null @@ -1,3 +0,0 @@ -def test_mock(): - # TODO: Add test logic here - pass diff --git a/src/spikeinterface/postprocessing/__init__.py b/src/spikeinterface/postprocessing/__init__.py index ae071a55e0..34a0bfab9a 100644 --- a/src/spikeinterface/postprocessing/__init__.py +++ b/src/spikeinterface/postprocessing/__init__.py @@ -40,7 +40,6 @@ from .unit_locations import ( compute_unit_locations, ComputeUnitLocations, - compute_center_of_mass, ) from .amplitude_scalings import compute_amplitude_scalings, ComputeAmplitudeScalings diff --git a/src/spikeinterface/postprocessing/localization_tools.py b/src/spikeinterface/postprocessing/localization_tools.py new file mode 100644 index 0000000000..b7571a6f3e --- /dev/null +++ b/src/spikeinterface/postprocessing/localization_tools.py @@ -0,0 +1,623 @@ +from __future__ import annotations + +import warnings + +import numpy as np + +try: + import numba + + HAVE_NUMBA = True +except ImportError: + HAVE_NUMBA = False + + +from spikeinterface.core import compute_sparsity, SortingAnalyzer, Templates +from spikeinterface.core.template_tools import get_template_extremum_channel, _get_nbefore, get_dense_templates_array + + +def compute_monopolar_triangulation( + sorting_analyzer_or_templates: SortingAnalyzer | Templates, + optimizer: str = "least_square", + radius_um: float = 75, + max_distance_um: float = 1000, + return_alpha: bool = False, + enforce_decrease: bool = False, + feature: str = "ptp", +) -> np.ndarray: + """ + Localize unit with monopolar triangulation. + This method is from Julien Boussard, Erdem Varol and Charlie Windolf + https://www.biorxiv.org/content/10.1101/2021.11.05.467503v1 + + There are 2 implementations of the 2 optimizer variants: + * https://github.com/int-brain-lab/spikes_localization_registration/blob/main/localization_pipeline/localizer.py + * https://github.com/cwindolf/spike-psvae/blob/main/spike_psvae/localization.py + + Important note about axis: + * x/y are dimmension on the probe plane (dim0, dim1) + * y is the depth by convention + * z it the orthogonal axis to the probe plan (dim2) + + Code from Erdem, Julien and Charlie do not use the same convention!!! + + + Parameters + ---------- + sorting_analyzer_or_templates : SortingAnalyzer | Templates + A SortingAnalyzer or Templates object + method : "least_square" | "minimize_with_log_penality", default: "least_square" + The optimizer to use + radius_um : float, default: 75 + For channel sparsity + max_distance_um : float, default: 1000 + to make bounddary in x, y, z and also for alpha + return_alpha : bool, default: False + Return or not the alpha value + enforce_decrease : bool, default: False + Enforce spatial decreasingness for PTP vectors + feature : "ptp" | "energy" | "peak_voltage", default: "ptp" + The available features to consider for estimating the position via + monopolar triangulation are peak-to-peak amplitudes ("ptp", default), + energy ("energy", as L2 norm) or voltages at the center of the waveform + ("peak_voltage") + + Returns + ------- + unit_location: np.ndarray + 3d or 4d, x, y, z, alpha + alpha is the amplitude at source estimation + """ + assert optimizer in ("least_square", "minimize_with_log_penality") + + assert feature in ["ptp", "energy", "peak_voltage"], f"{feature} is not a valid feature" + unit_ids = sorting_analyzer_or_templates.unit_ids + + contact_locations = sorting_analyzer_or_templates.get_channel_locations() + + sparsity = compute_sparsity(sorting_analyzer_or_templates, method="radius", radius_um=radius_um) + templates = get_dense_templates_array( + sorting_analyzer_or_templates, return_scaled=get_return_scaled(sorting_analyzer_or_templates) + ) + nbefore = _get_nbefore(sorting_analyzer_or_templates) + + if enforce_decrease: + neighbours_mask = np.zeros((templates.shape[0], templates.shape[2]), dtype=bool) + for i, unit_id in enumerate(unit_ids): + chan_inds = sparsity.unit_id_to_channel_indices[unit_id] + neighbours_mask[i, chan_inds] = True + enforce_decrease_radial_parents = make_radial_order_parents(contact_locations, neighbours_mask) + best_channels = get_template_extremum_channel(sorting_analyzer_or_templates, outputs="index") + + unit_location = np.zeros((unit_ids.size, 4), dtype="float64") + for i, unit_id in enumerate(unit_ids): + chan_inds = sparsity.unit_id_to_channel_indices[unit_id] + local_contact_locations = contact_locations[chan_inds, :] + + # wf is (nsample, nchan) - chann is only nieghboor + wf = templates[i, :, :][:, chan_inds] + if feature == "ptp": + wf_data = wf.ptp(axis=0) + elif feature == "energy": + wf_data = np.linalg.norm(wf, axis=0) + elif feature == "peak_voltage": + wf_data = np.abs(wf[nbefore]) + + # if enforce_decrease: + # enforce_decrease_shells_data( + # wf_data, best_channels[unit_id], enforce_decrease_radial_parents, in_place=True + # ) + + unit_location[i] = solve_monopolar_triangulation(wf_data, local_contact_locations, max_distance_um, optimizer) + + if not return_alpha: + unit_location = unit_location[:, :3] + + return unit_location + + +def compute_center_of_mass( + sorting_analyzer_or_templates: SortingAnalyzer | Templates, + peak_sign: str = "neg", + radius_um: float = 75, + feature: str = "ptp", +) -> np.ndarray: + """ + Computes the center of mass (COM) of a unit based on the template amplitudes. + + Parameters + ---------- + sorting_analyzer_or_templates : SortingAnalyzer | Templates + A SortingAnalyzer or Templates object + peak_sign : "neg" | "pos" | "both", default: "neg" + Sign of the template to compute best channels + radius_um : float + Radius to consider in order to estimate the COM + feature : "ptp" | "mean" | "energy" | "peak_voltage", default: "ptp" + Feature to consider for computation + + Returns + ------- + unit_location: np.array + """ + unit_ids = sorting_analyzer_or_templates.unit_ids + + contact_locations = sorting_analyzer_or_templates.get_channel_locations() + + assert feature in ["ptp", "mean", "energy", "peak_voltage"], f"{feature} is not a valid feature" + + sparsity = compute_sparsity( + sorting_analyzer_or_templates, peak_sign=peak_sign, method="radius", radius_um=radius_um + ) + templates = get_dense_templates_array( + sorting_analyzer_or_templates, return_scaled=get_return_scaled(sorting_analyzer_or_templates) + ) + nbefore = _get_nbefore(sorting_analyzer_or_templates) + + unit_location = np.zeros((unit_ids.size, 2), dtype="float64") + for i, unit_id in enumerate(unit_ids): + chan_inds = sparsity.unit_id_to_channel_indices[unit_id] + local_contact_locations = contact_locations[chan_inds, :] + + wf = templates[i, :, :] + + if feature == "ptp": + wf_data = (wf[:, chan_inds]).ptp(axis=0) + elif feature == "mean": + wf_data = (wf[:, chan_inds]).mean(axis=0) + elif feature == "energy": + wf_data = np.linalg.norm(wf[:, chan_inds], axis=0) + elif feature == "peak_voltage": + wf_data = wf[nbefore, chan_inds] + + # center of mass + com = np.sum(wf_data[:, np.newaxis] * local_contact_locations, axis=0) / np.sum(wf_data) + unit_location[i, :] = com + + return unit_location + + +def compute_grid_convolution( + sorting_analyzer_or_templates: SortingAnalyzer | Templates, + peak_sign: str = "neg", + radius_um: float = 40.0, + upsampling_um: float = 5, + sigma_ms: float = 0.25, + margin_um: float = 50, + prototype: np.ndarray | None = None, + percentile: float = 5, + weight_method: dict = {}, +) -> np.ndarray: + """ + Estimate the positions of the templates from a large grid of fake templates + + Parameters + ---------- + sorting_analyzer_or_templates : SortingAnalyzer | Templates + A SortingAnalyzer or Templates object + peak_sign : "neg" | "pos" | "both", default: "neg" + Sign of the template to compute best channels + radius_um : float, default: 40.0 + Radius to consider for the fake templates + upsampling_um : float, default: 5 + Upsampling resolution for the grid of templates + sigma_ms : float, default: 0.25 + The temporal decay of the fake templates + margin_um : float, default: 50 + The margin for the grid of fake templates + prototype : np.array or None, default: None + Fake waveforms for the templates. If None, generated as Gaussian + percentile : float, default: 5 + The percentage in [0, 100] of the best scalar products kept to + estimate the position + weight_method : dict + Parameter that should be provided to the get_convolution_weights() function + in order to know how to estimate the positions. One argument is mode that could + be either gaussian_2d (KS like) or exponential_3d (default) + Returns + ------- + unit_location: np.array + """ + + contact_locations = sorting_analyzer_or_templates.get_channel_locations() + unit_ids = sorting_analyzer_or_templates.unit_ids + + templates = get_dense_templates_array( + sorting_analyzer_or_templates, return_scaled=get_return_scaled(sorting_analyzer_or_templates) + ) + nbefore = _get_nbefore(sorting_analyzer_or_templates) + nafter = templates.shape[1] - nbefore + + fs = sorting_analyzer_or_templates.sampling_frequency + percentile = 100 - percentile + assert 0 <= percentile <= 100, "Percentile should be in [0, 100]" + + time_axis = np.arange(-nbefore, nafter) * 1000 / fs + if prototype is None: + prototype = np.exp(-(time_axis**2) / (2 * (sigma_ms**2))) + if peak_sign == "neg": + prototype *= -1 + + prototype = prototype[:, np.newaxis] + + template_positions, weights, nearest_template_mask, z_factors = get_grid_convolution_templates_and_weights( + contact_locations, radius_um, upsampling_um, margin_um, weight_method + ) + + peak_channels = get_template_extremum_channel(sorting_analyzer_or_templates, peak_sign, outputs="index") + + weights_sparsity_mask = weights > 0 + + nb_weights = weights.shape[0] + unit_location = np.zeros((unit_ids.size, 3), dtype="float64") + + for i, unit_id in enumerate(unit_ids): + main_chan = peak_channels[unit_id] + wf = templates[i, :, :] + nearest_mask = nearest_template_mask[main_chan, :] + channel_mask = np.sum(weights_sparsity_mask[:, :, nearest_mask], axis=(0, 2)) > 0 + num_templates = np.sum(nearest_mask) + sub_w = weights[:, channel_mask, :][:, :, nearest_mask] + global_products = (wf[:, channel_mask] * prototype).sum(axis=0) + + dot_products = np.zeros((nb_weights, num_templates), dtype=np.float32) + for count in range(nb_weights): + dot_products[count] = np.dot(global_products, sub_w[count]) + + mask = dot_products < 0 + if percentile > 0: + dot_products[mask] = np.nan + ## We need to catch warnings because some line can have only NaN, and + ## if so the nanpercentile function throws a warning + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + thresholds = np.nanpercentile(dot_products, percentile) + thresholds = np.nan_to_num(thresholds) + dot_products[dot_products < thresholds] = 0 + dot_products[mask] = 0 + + nearest_templates = template_positions[nearest_mask] + for count in range(nb_weights): + unit_location[i, :2] += np.dot(dot_products[count], nearest_templates) + + scalar_products = dot_products.sum(1) + unit_location[i, 2] = np.dot(z_factors, scalar_products) + with np.errstate(divide="ignore", invalid="ignore"): + unit_location[i] /= scalar_products.sum() + unit_location = np.nan_to_num(unit_location) + + return unit_location + + +def get_return_scaled(sorting_analyzer_or_templates): + if isinstance(sorting_analyzer_or_templates, Templates): + return_scaled = sorting_analyzer_or_templates.is_scaled + else: + return_scaled = sorting_analyzer_or_templates.return_scaled + return return_scaled + + +def make_initial_guess_and_bounds(wf_data, local_contact_locations, max_distance_um, initial_z=20): + # constant for initial guess and bounds + ind_max = np.argmax(wf_data) + max_ptp = wf_data[ind_max] + max_alpha = max_ptp * max_distance_um + + # initial guess is the center of mass + com = np.sum(wf_data[:, np.newaxis] * local_contact_locations, axis=0) / np.sum(wf_data) + x0 = np.zeros(4, dtype="float32") + x0[:2] = com + x0[2] = initial_z + initial_alpha = np.sqrt(np.sum((com - local_contact_locations[ind_max, :]) ** 2) + initial_z**2) * max_ptp + x0[3] = initial_alpha + + # bounds depend on initial guess + bounds = ( + [x0[0] - max_distance_um, x0[1] - max_distance_um, 1, 0], + [x0[0] + max_distance_um, x0[1] + max_distance_um, max_distance_um * 10, max_alpha], + ) + + return x0, bounds + + +def solve_monopolar_triangulation(wf_data, local_contact_locations, max_distance_um, optimizer): + import scipy.optimize + + x0, bounds = make_initial_guess_and_bounds(wf_data, local_contact_locations, max_distance_um) + + if optimizer == "least_square": + args = (wf_data, local_contact_locations) + try: + output = scipy.optimize.least_squares(estimate_distance_error, x0=x0, bounds=bounds, args=args) + return tuple(output["x"]) + except Exception as e: + print(f"scipy.optimize.least_squares error: {e}") + return (np.nan, np.nan, np.nan, np.nan) + + if optimizer == "minimize_with_log_penality": + x0 = x0[:3] + bounds = [(bounds[0][0], bounds[1][0]), (bounds[0][1], bounds[1][1]), (bounds[0][2], bounds[1][2])] + max_data = wf_data.max() + args = (wf_data, local_contact_locations, max_data) + try: + output = scipy.optimize.minimize(estimate_distance_error_with_log, x0=x0, bounds=bounds, args=args) + # final alpha + q = data_at(*output["x"], 1.0, local_contact_locations) + alpha = (wf_data * q).sum() / np.square(q).sum() + return (*output["x"], alpha) + except Exception as e: + print(f"scipy.optimize.minimize error: {e}") + return (np.nan, np.nan, np.nan, np.nan) + + +# ---- +# optimizer "least_square" + + +def estimate_distance_error(vec, wf_data, local_contact_locations): + # vec dims ar (x, y, z amplitude_factor) + # given that for contact_location x=dim0 + z=dim1 and y is orthogonal to probe + dist = np.sqrt(((local_contact_locations - vec[np.newaxis, :2]) ** 2).sum(axis=1) + vec[2] ** 2) + data_estimated = vec[3] / dist + err = wf_data - data_estimated + return err + + +# ---- +# optimizer "minimize_with_log_penality" + + +def data_at(x, y, z, alpha, local_contact_locations): + return alpha / np.sqrt( + np.square(x - local_contact_locations[:, 0]) + np.square(y - local_contact_locations[:, 1]) + np.square(z) + ) + + +def estimate_distance_error_with_log(vec, wf_data, local_contact_locations, max_data): + x, y, z = vec + q = data_at(x, y, z, 1.0, local_contact_locations) + alpha = (q * wf_data / max_data).sum() / (q * q).sum() + err = ( + np.square(wf_data / max_data - data_at(x, y, z, alpha, local_contact_locations)).mean() + - np.log1p(10.0 * z) / 10000.0 + ) + return err + + +# --- +# waveform cleaning for localization. could be moved to another file + + +def make_shell(channel, geom, n_jumps=1): + """See make_shells""" + from scipy.spatial.distance import cdist + + pt = geom[channel] + dists = cdist([pt], geom).ravel() + radius = np.unique(dists)[1 : n_jumps + 1][-1] + return np.setdiff1d(np.flatnonzero(dists <= radius + 1e-8), [channel]) + + +def make_shells(geom, n_jumps=1): + """Get the neighbors of a channel within a radius + + That radius is found by figuring out the distance to the closest channel, + then the channel which is the next closest (but farther than the closest), + etc... for n_jumps. + + So, if n_jumps is 1, it will return the indices of channels which are + as close as the closest channel. If n_jumps is 2, it will include those + and also the indices of the next-closest channels. And so on... + + Returns + ------- + shell_neighbors : list + List of length geom.shape[0] (aka, the number of channels) + The ith entry in the list is an array with the indices of the neighbors + of the ith channel. + i is not included in these arrays (a channel is not in its own shell). + """ + return [make_shell(c, geom, n_jumps=n_jumps) for c in range(geom.shape[0])] + + +def make_radial_order_parents(geom, neighbours_mask, n_jumps_per_growth=1, n_jumps_parent=3): + """Pre-computes a helper data structure for enforce_decrease_shells""" + n_channels = len(geom) + + # which channels should we consider as possible parents for each channel? + shells = make_shells(geom, n_jumps=n_jumps_parent) + + radial_parents = [] + for channel, neighbors in enumerate(neighbours_mask): + channel_parents = [] + + # convert from boolean mask to list of indices + neighbors = np.flatnonzero(neighbors) + + # the closest shell will do nothing + already_seen = [channel] + shell0 = make_shell(channel, geom, n_jumps=n_jumps_per_growth) + already_seen += sorted(c for c in shell0 if c not in already_seen) + + # so we start at the second jump + jumps = 2 + while len(already_seen) < (neighbors < n_channels).sum(): + # grow our search -- what are the next-closest channels? + new_shell = make_shell(channel, geom, n_jumps=jumps * n_jumps_per_growth) + new_shell = list(sorted(c for c in new_shell if (c not in already_seen) and (c in neighbors))) + + # for each new channel, find the intersection of the channels + # from previous shells and that channel's shell in `shells` + for new_chan in new_shell: + parents = np.intersect1d(shells[new_chan], already_seen) + parents_rel = np.flatnonzero(np.isin(neighbors, parents)) + if not len(parents_rel): + # this can happen for some strange geometries. in that case, bail. + continue + channel_parents.append((np.flatnonzero(neighbors == new_chan).item(), parents_rel)) + + # add this shell to what we have seen + already_seen += new_shell + jumps += 1 + + radial_parents.append(channel_parents) + + return radial_parents + + +def enforce_decrease_shells_data(wf_data, maxchan, radial_parents, in_place=False): + """Radial enforce decrease""" + (C,) = wf_data.shape + + # allocate storage for decreasing version of data + decreasing_data = wf_data if in_place else wf_data.copy() + + # loop to enforce data decrease from parent shells + for c, parents_rel in radial_parents[maxchan]: + if decreasing_data[c] > decreasing_data[parents_rel].max(): + decreasing_data[c] *= decreasing_data[parents_rel].max() / decreasing_data[c] + + return decreasing_data + + +def get_grid_convolution_templates_and_weights( + contact_locations, radius_um=40, upsampling_um=5, margin_um=50, weight_method={"mode": "exponential_3d"} +): + """Get a upsampled grid of artificial templates given a particular probe layout + + Parameters + ---------- + contact_locations: array + The positions of the channels + radius_um: float + Radius in um for channel sparsity. + upsampling_um: float + Upsampling resolution for the grid of templates + margin_um: float + The margin for the grid of fake templates + weight_method: dict + Parameter that should be provided to the get_convolution_weights() function + in order to know how to estimate the positions. One argument is mode that could + be either gaussian_2d (KS like) or exponential_3d (default) + + Returns + ------- + template_positions: array + The positions of the upsampled templates + weights: + The weights of the templates, on a per channel basis + nearest_template_mask: array + A sparsity mask to to know which template is close to the contact locations, given + the radius_um parameter + z_factors: array + The z_factors that have been used to generate the weights along the third dimension + """ + + import sklearn.metrics + + x_min, x_max = contact_locations[:, 0].min(), contact_locations[:, 0].max() + y_min, y_max = contact_locations[:, 1].min(), contact_locations[:, 1].max() + + x_min -= margin_um + x_max += margin_um + y_min -= margin_um + y_max += margin_um + + eps = upsampling_um / 10 + + all_x, all_y = np.meshgrid( + np.arange(x_min, x_max + eps, upsampling_um), np.arange(y_min, y_max + eps, upsampling_um) + ) + + nb_templates = all_x.size + + template_positions = np.zeros((nb_templates, 2)) + template_positions[:, 0] = all_x.flatten() + template_positions[:, 1] = all_y.flatten() + + # mask to get nearest template given a channel + dist = sklearn.metrics.pairwise_distances(contact_locations, template_positions) + nearest_template_mask = dist <= radius_um + weights, z_factors = get_convolution_weights(dist, **weight_method) + + return template_positions, weights, nearest_template_mask, z_factors + + +def get_convolution_weights( + distances, + z_list_um=np.linspace(0, 120.0, 5), + sigma_list_um=np.linspace(5, 25, 5), + sparsity_threshold=None, + sigma_3d=2.5, + mode="exponential_3d", +): + """Get normalized weights for creating artificial templates, given some precomputed distances + + Parameters + ---------- + distances: 2D array + The distances between the source channels (real ones) and the upsampled one (virual ones) + sparsity_threshold: float, default None + The sparsity_threshold below which weights are set to 0 (speeding up computations). If None, + then a default value of 0.5/sqrt(distances.shape[0]) is set + mode: exponential_3d | gaussian_2d + The inference scheme to be used to get the convolution weights + Keyword arguments for the chosen method: + "gaussian_2d" (similar to KiloSort): + * sigma_list_um: array, default np.linspace(5, 25, 5) + The list of sigma to consider for decaying exponentials + "exponential_3d" (default): + * z_list_um: array, default np.linspace(0, 120.0, 5) + The list of z to consider for putative depth of the sources + * sigma_3d: float, default 2.5 + The scaling factor controling the decay of the exponential + + Returns + ------- + weights: + The weights of the templates, on a per channel basis + z_factors: array + The z_factors that have been used to generate the weights along the third dimension + """ + + if sparsity_threshold is not None: + assert 0 <= sparsity_threshold <= 1, "sparsity_threshold should be in [0, 1]" + + if mode == "exponential_3d": + weights = np.zeros((len(z_list_um), distances.shape[0], distances.shape[1]), dtype=np.float32) + for count, z in enumerate(z_list_um): + dist_3d = np.sqrt(distances**2 + z**2) + weights[count] = np.exp(-dist_3d / sigma_3d) + z_factors = z_list_um + elif mode == "gaussian_2d": + weights = np.zeros((len(sigma_list_um), distances.shape[0], distances.shape[1]), dtype=np.float32) + for count, sigma in enumerate(sigma_list_um): + alpha = 2 * (sigma**2) + weights[count] = np.exp(-(distances**2) / alpha) + z_factors = sigma_list_um + + # normalize to get normalized values in [0, 1] + with np.errstate(divide="ignore", invalid="ignore"): + norm = np.linalg.norm(weights, axis=1)[:, np.newaxis, :] + weights /= norm + + weights[~np.isfinite(weights)] = 0.0 + + # If sparsity is None or non zero, we are pruning weights that are below the + # sparsification factor. This will speed up furter computations + if sparsity_threshold is None: + sparsity_threshold = 0.5 / np.sqrt(distances.shape[0]) + weights[weights < sparsity_threshold] = 0 + + # re normalize to ensure we have unitary norms + with np.errstate(divide="ignore", invalid="ignore"): + norm = np.linalg.norm(weights, axis=1)[:, np.newaxis, :] + weights /= norm + + weights[~np.isfinite(weights)] = 0.0 + + return weights, z_factors + + +if HAVE_NUMBA: + enforce_decrease_shells = numba.jit(enforce_decrease_shells_data, nopython=True) diff --git a/src/spikeinterface/postprocessing/unit_locations.py b/src/spikeinterface/postprocessing/unit_locations.py index 16d9955e58..9435030775 100644 --- a/src/spikeinterface/postprocessing/unit_locations.py +++ b/src/spikeinterface/postprocessing/unit_locations.py @@ -1,21 +1,14 @@ from __future__ import annotations -import warnings - import numpy as np - - -try: - import numba - - HAVE_NUMBA = True -except ImportError: - HAVE_NUMBA = False +import warnings from ..core.sortinganalyzer import register_result_extension, AnalyzerExtension -from ..core import compute_sparsity -from ..core.template_tools import get_template_extremum_channel, _get_nbefore, get_dense_templates_array - +from .localization_tools import ( + compute_center_of_mass, + compute_grid_convolution, + compute_monopolar_triangulation, +) dtype_localize_by_method = { "center_of_mass": [("x", "float64"), ("y", "float64")], @@ -90,592 +83,3 @@ def get_data(self, outputs="numpy"): register_result_extension(ComputeUnitLocations) compute_unit_locations = ComputeUnitLocations.function_factory() - - -def make_initial_guess_and_bounds(wf_data, local_contact_locations, max_distance_um, initial_z=20): - # constant for initial guess and bounds - ind_max = np.argmax(wf_data) - max_ptp = wf_data[ind_max] - max_alpha = max_ptp * max_distance_um - - # initial guess is the center of mass - com = np.sum(wf_data[:, np.newaxis] * local_contact_locations, axis=0) / np.sum(wf_data) - x0 = np.zeros(4, dtype="float32") - x0[:2] = com - x0[2] = initial_z - initial_alpha = np.sqrt(np.sum((com - local_contact_locations[ind_max, :]) ** 2) + initial_z**2) * max_ptp - x0[3] = initial_alpha - - # bounds depend on initial guess - bounds = ( - [x0[0] - max_distance_um, x0[1] - max_distance_um, 1, 0], - [x0[0] + max_distance_um, x0[1] + max_distance_um, max_distance_um * 10, max_alpha], - ) - - return x0, bounds - - -def solve_monopolar_triangulation(wf_data, local_contact_locations, max_distance_um, optimizer): - import scipy.optimize - - x0, bounds = make_initial_guess_and_bounds(wf_data, local_contact_locations, max_distance_um) - - if optimizer == "least_square": - args = (wf_data, local_contact_locations) - try: - output = scipy.optimize.least_squares(estimate_distance_error, x0=x0, bounds=bounds, args=args) - return tuple(output["x"]) - except Exception as e: - print(f"scipy.optimize.least_squares error: {e}") - return (np.nan, np.nan, np.nan, np.nan) - - if optimizer == "minimize_with_log_penality": - x0 = x0[:3] - bounds = [(bounds[0][0], bounds[1][0]), (bounds[0][1], bounds[1][1]), (bounds[0][2], bounds[1][2])] - max_data = wf_data.max() - args = (wf_data, local_contact_locations, max_data) - try: - output = scipy.optimize.minimize(estimate_distance_error_with_log, x0=x0, bounds=bounds, args=args) - # final alpha - q = data_at(*output["x"], 1.0, local_contact_locations) - alpha = (wf_data * q).sum() / np.square(q).sum() - return (*output["x"], alpha) - except Exception as e: - print(f"scipy.optimize.minimize error: {e}") - return (np.nan, np.nan, np.nan, np.nan) - - -# ---- -# optimizer "least_square" - - -def estimate_distance_error(vec, wf_data, local_contact_locations): - # vec dims ar (x, y, z amplitude_factor) - # given that for contact_location x=dim0 + z=dim1 and y is orthogonal to probe - dist = np.sqrt(((local_contact_locations - vec[np.newaxis, :2]) ** 2).sum(axis=1) + vec[2] ** 2) - data_estimated = vec[3] / dist - err = wf_data - data_estimated - return err - - -# ---- -# optimizer "minimize_with_log_penality" - - -def data_at(x, y, z, alpha, local_contact_locations): - return alpha / np.sqrt( - np.square(x - local_contact_locations[:, 0]) + np.square(y - local_contact_locations[:, 1]) + np.square(z) - ) - - -def estimate_distance_error_with_log(vec, wf_data, local_contact_locations, max_data): - x, y, z = vec - q = data_at(x, y, z, 1.0, local_contact_locations) - alpha = (q * wf_data / max_data).sum() / (q * q).sum() - err = ( - np.square(wf_data / max_data - data_at(x, y, z, alpha, local_contact_locations)).mean() - - np.log1p(10.0 * z) / 10000.0 - ) - return err - - -def compute_monopolar_triangulation( - sorting_analyzer, - optimizer="minimize_with_log_penality", - radius_um=75, - max_distance_um=1000, - return_alpha=False, - enforce_decrease=False, - feature="ptp", -): - """ - Localize unit with monopolar triangulation. - This method is from Julien Boussard, Erdem Varol and Charlie Windolf - https://www.biorxiv.org/content/10.1101/2021.11.05.467503v1 - - There are 2 implementations of the 2 optimizer variants: - * https://github.com/int-brain-lab/spikes_localization_registration/blob/main/localization_pipeline/localizer.py - * https://github.com/cwindolf/spike-psvae/blob/main/spike_psvae/localization.py - - Important note about axis: - * x/y are dimmension on the probe plane (dim0, dim1) - * y is the depth by convention - * z it the orthogonal axis to the probe plan (dim2) - - Code from Erdem, Julien and Charlie do not use the same convention!!! - - - Parameters - ---------- - sorting_analyzer: SortingAnalyzer - A SortingAnalyzer object - method: "least_square" | "minimize_with_log_penality", default: "least_square" - The optimizer to use - radius_um: float, default: 75 - For channel sparsity - max_distance_um: float, default: 1000 - to make bounddary in x, y, z and also for alpha - return_alpha: bool, default: False - Return or not the alpha value - enforce_decrease : bool, default: False - Enforce spatial decreasingness for PTP vectors - feature: "ptp" | "energy" | "peak_voltage", default: "ptp" - The available features to consider for estimating the position via - monopolar triangulation are peak-to-peak amplitudes ("ptp", default), - energy ("energy", as L2 norm) or voltages at the center of the waveform - ("peak_voltage") - - Returns - ------- - unit_location: np.array - 3d or 4d, x, y, z, alpha - alpha is the amplitude at source estimation - """ - assert optimizer in ("least_square", "minimize_with_log_penality") - - assert feature in ["ptp", "energy", "peak_voltage"], f"{feature} is not a valid feature" - unit_ids = sorting_analyzer.unit_ids - - contact_locations = sorting_analyzer.get_channel_locations() - - sparsity = compute_sparsity(sorting_analyzer, method="radius", radius_um=radius_um) - templates = get_dense_templates_array(sorting_analyzer, return_scaled=sorting_analyzer.return_scaled) - nbefore = _get_nbefore(sorting_analyzer) - - if enforce_decrease: - neighbours_mask = np.zeros((templates.shape[0], templates.shape[2]), dtype=bool) - for i, unit_id in enumerate(unit_ids): - chan_inds = sparsity.unit_id_to_channel_indices[unit_id] - neighbours_mask[i, chan_inds] = True - enforce_decrease_radial_parents = make_radial_order_parents(contact_locations, neighbours_mask) - best_channels = get_template_extremum_channel(sorting_analyzer, outputs="index") - - unit_location = np.zeros((unit_ids.size, 4), dtype="float64") - for i, unit_id in enumerate(unit_ids): - chan_inds = sparsity.unit_id_to_channel_indices[unit_id] - local_contact_locations = contact_locations[chan_inds, :] - - # wf is (nsample, nchan) - chann is only nieghboor - wf = templates[i, :, :][:, chan_inds] - if feature == "ptp": - wf_data = wf.ptp(axis=0) - elif feature == "energy": - wf_data = np.linalg.norm(wf, axis=0) - elif feature == "peak_voltage": - wf_data = np.abs(wf[nbefore]) - - # if enforce_decrease: - # enforce_decrease_shells_data( - # wf_data, best_channels[unit_id], enforce_decrease_radial_parents, in_place=True - # ) - - unit_location[i] = solve_monopolar_triangulation(wf_data, local_contact_locations, max_distance_um, optimizer) - - if not return_alpha: - unit_location = unit_location[:, :3] - - return unit_location - - -def compute_center_of_mass(sorting_analyzer, peak_sign="neg", radius_um=75, feature="ptp"): - """ - Computes the center of mass (COM) of a unit based on the template amplitudes. - - Parameters - ---------- - sorting_analyzer: SortingAnalyzer - A SortingAnalyzer object - peak_sign: "neg" | "pos" | "both", default: "neg" - Sign of the template to compute best channels - radius_um: float - Radius to consider in order to estimate the COM - feature: "ptp" | "mean" | "energy" | "peak_voltage", default: "ptp" - Feature to consider for computation - - Returns - ------- - unit_location: np.array - """ - unit_ids = sorting_analyzer.unit_ids - - contact_locations = sorting_analyzer.get_channel_locations() - - assert feature in ["ptp", "mean", "energy", "peak_voltage"], f"{feature} is not a valid feature" - - sparsity = compute_sparsity(sorting_analyzer, peak_sign=peak_sign, method="radius", radius_um=radius_um) - templates = get_dense_templates_array(sorting_analyzer, return_scaled=sorting_analyzer.return_scaled) - nbefore = _get_nbefore(sorting_analyzer) - - unit_location = np.zeros((unit_ids.size, 2), dtype="float64") - for i, unit_id in enumerate(unit_ids): - chan_inds = sparsity.unit_id_to_channel_indices[unit_id] - local_contact_locations = contact_locations[chan_inds, :] - - wf = templates[i, :, :] - - if feature == "ptp": - wf_data = (wf[:, chan_inds]).ptp(axis=0) - elif feature == "mean": - wf_data = (wf[:, chan_inds]).mean(axis=0) - elif feature == "energy": - wf_data = np.linalg.norm(wf[:, chan_inds], axis=0) - elif feature == "peak_voltage": - wf_data = wf[nbefore, chan_inds] - - # center of mass - com = np.sum(wf_data[:, np.newaxis] * local_contact_locations, axis=0) / np.sum(wf_data) - unit_location[i, :] = com - - return unit_location - - -def compute_grid_convolution( - sorting_analyzer, - peak_sign="neg", - radius_um=40.0, - upsampling_um=5, - sigma_ms=0.25, - margin_um=50, - prototype=None, - percentile=5, - weight_method={}, -): - """ - Estimate the positions of the templates from a large grid of fake templates - - Parameters - ---------- - sorting_analyzer: SortingAnalyzer - A SortingAnalyzer object - peak_sign: "neg" | "pos" | "both", default: "neg" - Sign of the template to compute best channels - radius_um: float, default: 40.0 - Radius to consider for the fake templates - upsampling_um: float, default: 5 - Upsampling resolution for the grid of templates - sigma_ms: float, default: 0.25 - The temporal decay of the fake templates - margin_um: float, default: 50 - The margin for the grid of fake templates - prototype: np.array or None, default: None - Fake waveforms for the templates. If None, generated as Gaussian - percentile: float, default: 5 - The percentage in [0, 100] of the best scalar products kept to - estimate the position - weight_method: dict - Parameter that should be provided to the get_convolution_weights() function - in order to know how to estimate the positions. One argument is mode that could - be either gaussian_2d (KS like) or exponential_3d (default) - Returns - ------- - unit_location: np.array - """ - - contact_locations = sorting_analyzer.get_channel_locations() - unit_ids = sorting_analyzer.unit_ids - - templates = get_dense_templates_array(sorting_analyzer, return_scaled=sorting_analyzer.return_scaled) - nbefore = _get_nbefore(sorting_analyzer) - nafter = templates.shape[1] - nbefore - - fs = sorting_analyzer.sampling_frequency - percentile = 100 - percentile - assert 0 <= percentile <= 100, "Percentile should be in [0, 100]" - - time_axis = np.arange(-nbefore, nafter) * 1000 / fs - if prototype is None: - prototype = np.exp(-(time_axis**2) / (2 * (sigma_ms**2))) - if peak_sign == "neg": - prototype *= -1 - - prototype = prototype[:, np.newaxis] - - template_positions, weights, nearest_template_mask, z_factors = get_grid_convolution_templates_and_weights( - contact_locations, radius_um, upsampling_um, margin_um, weight_method - ) - - peak_channels = get_template_extremum_channel(sorting_analyzer, peak_sign, outputs="index") - - weights_sparsity_mask = weights > 0 - - nb_weights = weights.shape[0] - unit_location = np.zeros((unit_ids.size, 3), dtype="float64") - - for i, unit_id in enumerate(unit_ids): - main_chan = peak_channels[unit_id] - wf = templates[i, :, :] - nearest_mask = nearest_template_mask[main_chan, :] - channel_mask = np.sum(weights_sparsity_mask[:, :, nearest_mask], axis=(0, 2)) > 0 - num_templates = np.sum(nearest_mask) - sub_w = weights[:, channel_mask, :][:, :, nearest_mask] - global_products = (wf[:, channel_mask] * prototype).sum(axis=0) - - dot_products = np.zeros((nb_weights, num_templates), dtype=np.float32) - for count in range(nb_weights): - dot_products[count] = np.dot(global_products, sub_w[count]) - - mask = dot_products < 0 - if percentile > 0: - dot_products[mask] = np.nan - ## We need to catch warnings because some line can have only NaN, and - ## if so the nanpercentile function throws a warning - with warnings.catch_warnings(): - warnings.filterwarnings("ignore") - thresholds = np.nanpercentile(dot_products, percentile) - thresholds = np.nan_to_num(thresholds) - dot_products[dot_products < thresholds] = 0 - dot_products[mask] = 0 - - nearest_templates = template_positions[nearest_mask] - for count in range(nb_weights): - unit_location[i, :2] += np.dot(dot_products[count], nearest_templates) - - scalar_products = dot_products.sum(1) - unit_location[i, 2] = np.dot(z_factors, scalar_products) - with np.errstate(divide="ignore", invalid="ignore"): - unit_location[i] /= scalar_products.sum() - unit_location = np.nan_to_num(unit_location) - - return unit_location - - -# --- -# waveform cleaning for localization. could be moved to another file - - -def make_shell(channel, geom, n_jumps=1): - """See make_shells""" - from scipy.spatial.distance import cdist - - pt = geom[channel] - dists = cdist([pt], geom).ravel() - radius = np.unique(dists)[1 : n_jumps + 1][-1] - return np.setdiff1d(np.flatnonzero(dists <= radius + 1e-8), [channel]) - - -def make_shells(geom, n_jumps=1): - """Get the neighbors of a channel within a radius - - That radius is found by figuring out the distance to the closest channel, - then the channel which is the next closest (but farther than the closest), - etc... for n_jumps. - - So, if n_jumps is 1, it will return the indices of channels which are - as close as the closest channel. If n_jumps is 2, it will include those - and also the indices of the next-closest channels. And so on... - - Returns - ------- - shell_neighbors : list - List of length geom.shape[0] (aka, the number of channels) - The ith entry in the list is an array with the indices of the neighbors - of the ith channel. - i is not included in these arrays (a channel is not in its own shell). - """ - return [make_shell(c, geom, n_jumps=n_jumps) for c in range(geom.shape[0])] - - -def make_radial_order_parents(geom, neighbours_mask, n_jumps_per_growth=1, n_jumps_parent=3): - """Pre-computes a helper data structure for enforce_decrease_shells""" - n_channels = len(geom) - - # which channels should we consider as possible parents for each channel? - shells = make_shells(geom, n_jumps=n_jumps_parent) - - radial_parents = [] - for channel, neighbors in enumerate(neighbours_mask): - channel_parents = [] - - # convert from boolean mask to list of indices - neighbors = np.flatnonzero(neighbors) - - # the closest shell will do nothing - already_seen = [channel] - shell0 = make_shell(channel, geom, n_jumps=n_jumps_per_growth) - already_seen += sorted(c for c in shell0 if c not in already_seen) - - # so we start at the second jump - jumps = 2 - while len(already_seen) < (neighbors < n_channels).sum(): - # grow our search -- what are the next-closest channels? - new_shell = make_shell(channel, geom, n_jumps=jumps * n_jumps_per_growth) - new_shell = list(sorted(c for c in new_shell if (c not in already_seen) and (c in neighbors))) - - # for each new channel, find the intersection of the channels - # from previous shells and that channel's shell in `shells` - for new_chan in new_shell: - parents = np.intersect1d(shells[new_chan], already_seen) - parents_rel = np.flatnonzero(np.isin(neighbors, parents)) - if not len(parents_rel): - # this can happen for some strange geometries. in that case, bail. - continue - channel_parents.append((np.flatnonzero(neighbors == new_chan).item(), parents_rel)) - - # add this shell to what we have seen - already_seen += new_shell - jumps += 1 - - radial_parents.append(channel_parents) - - return radial_parents - - -def enforce_decrease_shells_data(wf_data, maxchan, radial_parents, in_place=False): - """Radial enforce decrease""" - (C,) = wf_data.shape - - # allocate storage for decreasing version of data - decreasing_data = wf_data if in_place else wf_data.copy() - - # loop to enforce data decrease from parent shells - for c, parents_rel in radial_parents[maxchan]: - if decreasing_data[c] > decreasing_data[parents_rel].max(): - decreasing_data[c] *= decreasing_data[parents_rel].max() / decreasing_data[c] - - return decreasing_data - - -def get_grid_convolution_templates_and_weights( - contact_locations, radius_um=40, upsampling_um=5, margin_um=50, weight_method={"mode": "exponential_3d"} -): - """Get a upsampled grid of artificial templates given a particular probe layout - - Parameters - ---------- - contact_locations: array - The positions of the channels - radius_um: float - Radius in um for channel sparsity. - upsampling_um: float - Upsampling resolution for the grid of templates - margin_um: float - The margin for the grid of fake templates - weight_method: dict - Parameter that should be provided to the get_convolution_weights() function - in order to know how to estimate the positions. One argument is mode that could - be either gaussian_2d (KS like) or exponential_3d (default) - - Returns - ------- - template_positions: array - The positions of the upsampled templates - weights: - The weights of the templates, on a per channel basis - nearest_template_mask: array - A sparsity mask to to know which template is close to the contact locations, given - the radius_um parameter - z_factors: array - The z_factors that have been used to generate the weights along the third dimension - """ - - import sklearn.metrics - - x_min, x_max = contact_locations[:, 0].min(), contact_locations[:, 0].max() - y_min, y_max = contact_locations[:, 1].min(), contact_locations[:, 1].max() - - x_min -= margin_um - x_max += margin_um - y_min -= margin_um - y_max += margin_um - - dx = np.abs(x_max - x_min) - dy = np.abs(y_max - y_min) - - eps = upsampling_um / 10 - - all_x, all_y = np.meshgrid( - np.arange(x_min, x_max + eps, upsampling_um), np.arange(y_min, y_max + eps, upsampling_um) - ) - - nb_templates = all_x.size - - template_positions = np.zeros((nb_templates, 2)) - template_positions[:, 0] = all_x.flatten() - template_positions[:, 1] = all_y.flatten() - - # mask to get nearest template given a channel - dist = sklearn.metrics.pairwise_distances(contact_locations, template_positions) - nearest_template_mask = dist <= radius_um - weights, z_factors = get_convolution_weights(dist, **weight_method) - - return template_positions, weights, nearest_template_mask, z_factors - - -def get_convolution_weights( - distances, - z_list_um=np.linspace(0, 120.0, 5), - sigma_list_um=np.linspace(5, 25, 5), - sparsity_threshold=None, - sigma_3d=2.5, - mode="exponential_3d", -): - """Get normalized weights for creating artificial templates, given some precomputed distances - - Parameters - ---------- - distances: 2D array - The distances between the source channels (real ones) and the upsampled one (virual ones) - sparsity_threshold: float, default None - The sparsity_threshold below which weights are set to 0 (speeding up computations). If None, - then a default value of 0.5/sqrt(distances.shape[0]) is set - mode: exponential_3d | gaussian_2d - The inference scheme to be used to get the convolution weights - Keyword arguments for the chosen method: - "gaussian_2d" (similar to KiloSort): - * sigma_list_um: array, default np.linspace(5, 25, 5) - The list of sigma to consider for decaying exponentials - "exponential_3d" (default): - * z_list_um: array, default np.linspace(0, 120.0, 5) - The list of z to consider for putative depth of the sources - * sigma_3d: float, default 2.5 - The scaling factor controling the decay of the exponential - - Returns - ------- - weights: - The weights of the templates, on a per channel basis - z_factors: array - The z_factors that have been used to generate the weights along the third dimension - """ - - if sparsity_threshold is not None: - assert 0 <= sparsity_threshold <= 1, "sparsity_threshold should be in [0, 1]" - - if mode == "exponential_3d": - weights = np.zeros((len(z_list_um), distances.shape[0], distances.shape[1]), dtype=np.float32) - for count, z in enumerate(z_list_um): - dist_3d = np.sqrt(distances**2 + z**2) - weights[count] = np.exp(-dist_3d / sigma_3d) - z_factors = z_list_um - elif mode == "gaussian_2d": - weights = np.zeros((len(sigma_list_um), distances.shape[0], distances.shape[1]), dtype=np.float32) - for count, sigma in enumerate(sigma_list_um): - alpha = 2 * (sigma**2) - weights[count] = np.exp(-(distances**2) / alpha) - z_factors = sigma_list_um - - # normalize to get normalized values in [0, 1] - with np.errstate(divide="ignore", invalid="ignore"): - norm = np.linalg.norm(weights, axis=1)[:, np.newaxis, :] - weights /= norm - - weights[~np.isfinite(weights)] = 0.0 - - # If sparsity is None or non zero, we are pruning weights that are below the - # sparsification factor. This will speed up furter computations - if sparsity_threshold is None: - sparsity_threshold = 0.5 / np.sqrt(distances.shape[0]) - weights[weights < sparsity_threshold] = 0 - - # re normalize to ensure we have unitary norms - with np.errstate(divide="ignore", invalid="ignore"): - norm = np.linalg.norm(weights, axis=1)[:, np.newaxis, :] - weights /= norm - - weights[~np.isfinite(weights)] = 0.0 - - return weights, z_factors - - -if HAVE_NUMBA: - enforce_decrease_shells = numba.jit(enforce_decrease_shells_data, nopython=True) diff --git a/src/spikeinterface/preprocessing/__init__.py b/src/spikeinterface/preprocessing/__init__.py index 38343f8804..5f9ac046e1 100644 --- a/src/spikeinterface/preprocessing/__init__.py +++ b/src/spikeinterface/preprocessing/__init__.py @@ -1,6 +1,6 @@ from .preprocessinglist import * -from .motion import correct_motion, load_motion_info +from .motion import correct_motion, load_motion_info, save_motion_info from .preprocessing_tools import get_spatial_interpolation_kernel from .detect_bad_channels import detect_bad_channels diff --git a/src/spikeinterface/preprocessing/motion.py b/src/spikeinterface/preprocessing/motion.py index 8023bd4367..0d65b1936a 100644 --- a/src/spikeinterface/preprocessing/motion.py +++ b/src/spikeinterface/preprocessing/motion.py @@ -2,6 +2,7 @@ import numpy as np import json +import shutil from pathlib import Path import time @@ -205,6 +206,7 @@ def correct_motion( preset="nonrigid_accurate", folder=None, output_motion_info=False, + overwrite=False, detect_kwargs={}, select_kwargs={}, localize_peaks_kwargs={}, @@ -257,6 +259,8 @@ def correct_motion( If True, then the function returns a `motion_info` dictionary that contains variables to check intermediate steps (motion_histogram, non_rigid_windows, pairwise_displacement) This dictionary is the same when reloaded from the folder + overwrite : bool, default: False + If True and folder is given, overwrite the folder if it already exists detect_kwargs : dict Optional parameters to overwrite the ones in the preset for "detect" step. select_kwargs : dict @@ -314,14 +318,6 @@ def correct_motion( job_kwargs = fix_job_kwargs(job_kwargs) noise_levels = get_noise_levels(recording, return_scaled=False) - if folder is not None: - folder = Path(folder) - folder.mkdir(exist_ok=True, parents=True) - - (folder / "parameters.json").write_text(json.dumps(parameters, indent=4, cls=SIJsonEncoder), encoding="utf8") - if recording.check_serializability("json"): - recording.dump_to_json(folder / "recording.json") - if not do_selection: # maybe do this directly in the folder when not None, but might be slow on external storage gather_mode = "memory" @@ -332,7 +328,7 @@ def correct_motion( node1 = ExtractDenseWaveforms(recording, parents=[node0], ms_before=0.1, ms_after=0.3) - # node nolcalize + # node detect + localize method = localize_peaks_kwargs.pop("method", "center_of_mass") method_class = localize_peak_methods[method] node2 = method_class(recording, parents=[node0, node1], return_output=True, **localize_peaks_kwargs) @@ -371,9 +367,6 @@ def correct_motion( select_peaks=t2 - t1, localize_peaks=t3 - t2, ) - if folder is not None: - np.save(folder / "peaks.npy", peaks) - np.save(folder / "peak_locations.npy", peak_locations) t0 = time.perf_counter() motion = estimate_motion(recording, peaks, peak_locations, **estimate_motion_kwargs) @@ -382,18 +375,17 @@ def correct_motion( recording_corrected = InterpolateMotionRecording(recording, motion, **interpolate_motion_kwargs) + motion_info = dict( + parameters=parameters, + run_times=run_times, + peaks=peaks, + peak_locations=peak_locations, + motion=motion, + ) if folder is not None: - (folder / "run_times.json").write_text(json.dumps(run_times, indent=4), encoding="utf8") - motion.save(folder / "motion") + save_motion_info(motion_info, folder, overwrite=overwrite) if output_motion_info: - motion_info = dict( - parameters=parameters, - run_times=run_times, - peaks=peaks, - peak_locations=peak_locations, - motion=motion, - ) return recording_corrected, motion_info else: return recording_corrected @@ -409,6 +401,25 @@ def correct_motion( correct_motion.__doc__ = correct_motion.__doc__.format(_doc_presets, _shared_job_kwargs_doc) +def save_motion_info(motion_info, folder, overwrite=False): + folder = Path(folder) + if folder.is_dir(): + if not overwrite: + raise FileExistsError(f"Folder {folder} already exists. Use `overwrite=True` to overwrite.") + else: + shutil.rmtree(folder) + folder.mkdir(exist_ok=True, parents=True) + + (folder / "parameters.json").write_text( + json.dumps(motion_info["parameters"], indent=4, cls=SIJsonEncoder), encoding="utf8" + ) + (folder / "run_times.json").write_text(json.dumps(motion_info["run_times"], indent=4), encoding="utf8") + + np.save(folder / "peaks.npy", motion_info["peaks"]) + np.save(folder / "peak_locations.npy", motion_info["peak_locations"]) + motion_info["motion"].save(folder / "motion") + + def load_motion_info(folder): from spikeinterface.sortingcomponents.motion_utils import Motion diff --git a/src/spikeinterface/preprocessing/tests/test_motion.py b/src/spikeinterface/preprocessing/tests/test_motion.py index a298b41d8f..baa7235263 100644 --- a/src/spikeinterface/preprocessing/tests/test_motion.py +++ b/src/spikeinterface/preprocessing/tests/test_motion.py @@ -1,10 +1,7 @@ import shutil -from pathlib import Path -import numpy as np -import pytest from spikeinterface.core import generate_recording -from spikeinterface.preprocessing import correct_motion, load_motion_info +from spikeinterface.preprocessing import correct_motion, load_motion_info, save_motion_info def test_estimate_and_correct_motion(create_cache_folder): @@ -19,9 +16,16 @@ def test_estimate_and_correct_motion(create_cache_folder): rec_corrected = correct_motion(rec, folder=folder) print(rec_corrected) + # test reloading motion info motion_info = load_motion_info(folder) print(motion_info.keys()) + # test saving motion info + save_folder = folder / "motion_info" + save_motion_info(motion_info=motion_info, folder=save_folder) + motion_info_loaded = load_motion_info(save_folder) + assert motion_info_loaded["motion"] == motion_info["motion"] + if __name__ == "__main__": # print(correct_motion.__doc__) diff --git a/src/spikeinterface/sorters/internal/spyking_circus2.py b/src/spikeinterface/sorters/internal/spyking_circus2.py index b5df0f1059..45cc93d0b6 100644 --- a/src/spikeinterface/sorters/internal/spyking_circus2.py +++ b/src/spikeinterface/sorters/internal/spyking_circus2.py @@ -278,29 +278,30 @@ def _run_from_folder(cls, sorter_output_folder, params, verbose): matching_params["templates"] = templates matching_job_params = job_kwargs.copy() - for value in ["chunk_size", "chunk_memory", "total_memory", "chunk_duration"]: - if value in matching_job_params: - matching_job_params[value] = None - matching_job_params["chunk_duration"] = "100ms" + if matching_method is not None: + for value in ["chunk_size", "chunk_memory", "total_memory", "chunk_duration"]: + if value in matching_job_params: + matching_job_params[value] = None + matching_job_params["chunk_duration"] = "100ms" + + spikes = find_spikes_from_templates( + recording_w, matching_method, method_kwargs=matching_params, **matching_job_params + ) - spikes = find_spikes_from_templates( - recording_w, matching_method, method_kwargs=matching_params, **matching_job_params - ) + if params["debug"]: + fitting_folder = sorter_output_folder / "fitting" + fitting_folder.mkdir(parents=True, exist_ok=True) + np.save(fitting_folder / "spikes", spikes) - if params["debug"]: - fitting_folder = sorter_output_folder / "fitting" - fitting_folder.mkdir(parents=True, exist_ok=True) - np.save(fitting_folder / "spikes", spikes) - - if verbose: - print("We found %d spikes" % len(spikes)) - - ## And this is it! We have a spyking circus - sorting = np.zeros(spikes.size, dtype=minimum_spike_dtype) - sorting["sample_index"] = spikes["sample_index"] - sorting["unit_index"] = spikes["cluster_index"] - sorting["segment_index"] = spikes["segment_index"] - sorting = NumpySorting(sorting, sampling_frequency, unit_ids) + if verbose: + print("We found %d spikes" % len(spikes)) + + ## And this is it! We have a spyking circus + sorting = np.zeros(spikes.size, dtype=minimum_spike_dtype) + sorting["sample_index"] = spikes["sample_index"] + sorting["unit_index"] = spikes["cluster_index"] + sorting["segment_index"] = spikes["segment_index"] + sorting = NumpySorting(sorting, sampling_frequency, unit_ids) sorting_folder = sorter_output_folder / "sorting" if sorting_folder.exists(): diff --git a/src/spikeinterface/sortingcomponents/benchmark/benchmark_peak_localization.py b/src/spikeinterface/sortingcomponents/benchmark/benchmark_peak_localization.py index 3eda5db3b6..05d142113b 100644 --- a/src/spikeinterface/sortingcomponents/benchmark/benchmark_peak_localization.py +++ b/src/spikeinterface/sortingcomponents/benchmark/benchmark_peak_localization.py @@ -1,6 +1,6 @@ from __future__ import annotations -from spikeinterface.postprocessing.unit_locations import ( +from spikeinterface.postprocessing.localization_tools import ( compute_center_of_mass, compute_monopolar_triangulation, compute_grid_convolution, diff --git a/src/spikeinterface/sortingcomponents/motion_utils.py b/src/spikeinterface/sortingcomponents/motion_utils.py index 26d4b35b1a..a8de3f6d13 100644 --- a/src/spikeinterface/sortingcomponents/motion_utils.py +++ b/src/spikeinterface/sortingcomponents/motion_utils.py @@ -90,11 +90,13 @@ def get_displacement_at_time_and_depth(self, times_s, locations_um, segment_inde Parameters ---------- times_s: np.array + The time points at which to evaluate the displacement. locations_um: np.array Either this is a one-dimensional array (a vector of positions along self.dimension), or else a 2d array with the 2 or 3 spatial dimensions indexed along axis=1. - segment_index: int, optional - grid : bool + segment_index: int, default: None + The index of the segment to evaluate. If None, and there is only one segment, then that segment is used. + grid : bool, default: False If grid=False, the default, then times_s and locations_um should have the same one-dimensional shape, and the returned displacement[i] is the displacement at time times_s[i] and location locations_um[i]. @@ -153,6 +155,7 @@ def to_dict(self): displacement=self.displacement, temporal_bins_s=self.temporal_bins_s, spatial_bins_um=self.spatial_bins_um, + direction=self.direction, interpolation_method=self.interpolation_method, ) @@ -223,8 +226,9 @@ def __eq__(self, other): def copy(self): return Motion( - self.displacement.copy(), - self.temporal_bins_s.copy(), - self.spatial_bins_um.copy(), + [d.copy() for d in self.displacement], + [t.copy() for t in self.temporal_bins_s], + [s.copy() for s in self.spatial_bins_um], + direction=self.direction, interpolation_method=self.interpolation_method, ) diff --git a/src/spikeinterface/sortingcomponents/peak_detection.py b/src/spikeinterface/sortingcomponents/peak_detection.py index b6f7709d27..0d5c92ff28 100644 --- a/src/spikeinterface/sortingcomponents/peak_detection.py +++ b/src/spikeinterface/sortingcomponents/peak_detection.py @@ -23,7 +23,7 @@ base_peak_dtype, ) -from spikeinterface.postprocessing.unit_locations import get_convolution_weights +from spikeinterface.postprocessing.localization_tools import get_convolution_weights from .tools import make_multi_method_doc diff --git a/src/spikeinterface/sortingcomponents/peak_localization.py b/src/spikeinterface/sortingcomponents/peak_localization.py index 23faea2d79..6d2ad09239 100644 --- a/src/spikeinterface/sortingcomponents/peak_localization.py +++ b/src/spikeinterface/sortingcomponents/peak_localization.py @@ -24,8 +24,11 @@ from ..postprocessing.unit_locations import ( dtype_localize_by_method, possible_localization_methods, - solve_monopolar_triangulation, +) + +from ..postprocessing.localization_tools import ( make_radial_order_parents, + solve_monopolar_triangulation, enforce_decrease_shells_data, get_grid_convolution_templates_and_weights, ) @@ -66,6 +69,8 @@ def get_localization_pipeline_nodes( elif method == "grid_convolution": if "prototype" not in method_kwargs: assert isinstance(peak_source, (PeakRetriever, SpikeRetriever)) + # extract prototypes silently + job_kwargs["progress_bar"] = False method_kwargs["prototype"] = get_prototype_spike( recording, peak_source.peaks, ms_before=ms_before, ms_after=ms_after, **job_kwargs ) diff --git a/src/spikeinterface/sortingcomponents/tools.py b/src/spikeinterface/sortingcomponents/tools.py index cc45dd3e40..8ee36cc9e5 100644 --- a/src/spikeinterface/sortingcomponents/tools.py +++ b/src/spikeinterface/sortingcomponents/tools.py @@ -62,6 +62,7 @@ def extract_waveform_at_max_channel(rec, peaks, ms_before=0.5, ms_after=1.5, **j return_scaled=False, sparsity_mask=sparsity_mask, copy=True, + verbose=False, **job_kwargs, ) diff --git a/src/spikeinterface/widgets/unit_waveforms.py b/src/spikeinterface/widgets/unit_waveforms.py index b046e55fbf..59f91306ea 100644 --- a/src/spikeinterface/widgets/unit_waveforms.py +++ b/src/spikeinterface/widgets/unit_waveforms.py @@ -540,9 +540,7 @@ def _update_plot(self, change): if self.sorting_analyzer is not None: templates = self.templates_ext.get_templates(unit_ids=unit_ids, operator="average") - templates_shadings = self._get_template_shadings( - unit_ids, self.next_data_plot["templates_percentile_shading"] - ) + templates_shadings = self._get_template_shadings(unit_ids, data_plot["templates_percentile_shading"]) channel_locations = self.sorting_analyzer.get_channel_locations() else: unit_indices = [list(self.templates.unit_ids).index(unit_id) for unit_id in unit_ids] From ec79fb4b951d9b87dffb2d2a6429afca36220fa8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 29 Jun 2024 18:19:11 +0000 Subject: [PATCH 46/81] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/spikeinterface/core/core_tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spikeinterface/core/core_tools.py b/src/spikeinterface/core/core_tools.py index 4cd902eff9..1f2e644be6 100644 --- a/src/spikeinterface/core/core_tools.py +++ b/src/spikeinterface/core/core_tools.py @@ -101,7 +101,7 @@ def default(self, obj): if isinstance(obj, Path): return str(obj) - + if isinstance(obj, Motion): return obj.to_dict() From 4e543010a7ff58dbc8ffa1c4f0aa5e2e7867725c Mon Sep 17 00:00:00 2001 From: Chris Halcrow <57948917+chrishalcrow@users.noreply.github.com> Date: Mon, 1 Jul 2024 09:04:19 +0200 Subject: [PATCH 47/81] Apply suggestions from code review Co-authored-by: Joe Ziminski <55797454+JoeZiminski@users.noreply.github.com> --- src/spikeinterface/qualitymetrics/misc_metrics.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/spikeinterface/qualitymetrics/misc_metrics.py b/src/spikeinterface/qualitymetrics/misc_metrics.py index f809ad11ec..c2dff554e3 100644 --- a/src/spikeinterface/qualitymetrics/misc_metrics.py +++ b/src/spikeinterface/qualitymetrics/misc_metrics.py @@ -357,8 +357,8 @@ def compute_refrac_period_violations( Requires "numba" package This method counts the number of violations which occur during the refactory period. - If there are three spikes within `refractory_period_ms`, the second and third spikes - violate the first spikes and the third spike violates the second spike. Hence there + For example, if there are three spikes within `refractory_period_ms`, the second and third spikes + violate the first spike and the third spike violates the second spike. Hence there are three violations. This is in contrast to `compute_isi_violations`, which computes the number of spikes which have been violated. From 2bd0633071e3fd34c61b14554f6c4c9b8d1d0733 Mon Sep 17 00:00:00 2001 From: Chris Halcrow <57948917+chrishalcrow@users.noreply.github.com> Date: Mon, 1 Jul 2024 14:42:03 +0100 Subject: [PATCH 48/81] Update src/spikeinterface/qualitymetrics/misc_metrics.py Co-authored-by: Zach McKenzie <92116279+zm711@users.noreply.github.com> --- src/spikeinterface/qualitymetrics/misc_metrics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spikeinterface/qualitymetrics/misc_metrics.py b/src/spikeinterface/qualitymetrics/misc_metrics.py index c2dff554e3..9e4685b5bd 100644 --- a/src/spikeinterface/qualitymetrics/misc_metrics.py +++ b/src/spikeinterface/qualitymetrics/misc_metrics.py @@ -281,7 +281,7 @@ def compute_isi_violations(sorting_analyzer, isi_threshold_ms=1.5, min_isi_ms=0, ---------- Based on metrics originally implemented in Ultra Mega Sort [UMS]_. - This implementation is based on one written in Matlab by Nick Steinmetz + This implementation is based on one of the original implementations written in Matlab by Nick Steinmetz (https://github.com/cortex-lab/sortingQuality) and converted to Python by Daniel Denman. """ res = namedtuple("isi_violation", ["isi_violations_ratio", "isi_violations_count"]) From be96f5e89371bafd2471d5357fac8300c037e2e3 Mon Sep 17 00:00:00 2001 From: Pierre Yger Date: Mon, 1 Jul 2024 16:38:05 +0200 Subject: [PATCH 49/81] Bringin back the commit --- src/spikeinterface/preprocessing/motion.py | 61 ++++++++++------------ 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/src/spikeinterface/preprocessing/motion.py b/src/spikeinterface/preprocessing/motion.py index 8c7bb1f489..a98bdc171a 100644 --- a/src/spikeinterface/preprocessing/motion.py +++ b/src/spikeinterface/preprocessing/motion.py @@ -2,7 +2,6 @@ import numpy as np import json -import shutil from pathlib import Path import time @@ -205,8 +204,8 @@ def correct_motion( recording, preset="nonrigid_accurate", folder=None, - output_motion_info=False, overwrite=False, + output_motion_info=False, detect_kwargs={}, select_kwargs={}, localize_peaks_kwargs={}, @@ -261,8 +260,6 @@ def correct_motion( If True, then the function returns a `motion_info` dictionary that contains variables to check intermediate steps (motion_histogram, non_rigid_windows, pairwise_displacement) This dictionary is the same when reloaded from the folder - overwrite : bool, default: False - If True and folder is given, overwrite the folder if it already exists detect_kwargs : dict Optional parameters to overwrite the ones in the preset for "detect" step. select_kwargs : dict @@ -320,6 +317,21 @@ def correct_motion( job_kwargs = fix_job_kwargs(job_kwargs) noise_levels = get_noise_levels(recording, return_scaled=False) + if folder is not None: + folder = Path(folder) + if overwrite: + if folder.exists(): + import shutil + shutil.rmtree(folder) + else: + assert not folder.exists(), f"Folder {folder} already exists" + + folder.mkdir(exist_ok=True, parents=True) + + (folder / "parameters.json").write_text(json.dumps(parameters, indent=4, cls=SIJsonEncoder), encoding="utf8") + if recording.check_serializability("json"): + recording.dump_to_json(folder / "recording.json") + if not do_selection: # maybe do this directly in the folder when not None, but might be slow on external storage gather_mode = "memory" @@ -330,7 +342,7 @@ def correct_motion( node1 = ExtractDenseWaveforms(recording, parents=[node0], ms_before=0.1, ms_after=0.3) - # node detect + localize + # node nolcalize method = localize_peaks_kwargs.pop("method", "center_of_mass") method_class = localize_peak_methods[method] node2 = method_class(recording, parents=[node0, node1], return_output=True, **localize_peaks_kwargs) @@ -369,6 +381,9 @@ def correct_motion( select_peaks=t2 - t1, localize_peaks=t3 - t2, ) + if folder is not None: + np.save(folder / "peaks.npy", peaks) + np.save(folder / "peak_locations.npy", peak_locations) t0 = time.perf_counter() motion = estimate_motion(recording, peaks, peak_locations, **estimate_motion_kwargs) @@ -377,17 +392,18 @@ def correct_motion( recording_corrected = InterpolateMotionRecording(recording, motion, **interpolate_motion_kwargs) - motion_info = dict( - parameters=parameters, - run_times=run_times, - peaks=peaks, - peak_locations=peak_locations, - motion=motion, - ) if folder is not None: - save_motion_info(motion_info, folder, overwrite=overwrite) + (folder / "run_times.json").write_text(json.dumps(run_times, indent=4), encoding="utf8") + motion.save(folder / "motion") if output_motion_info: + motion_info = dict( + parameters=parameters, + run_times=run_times, + peaks=peaks, + peak_locations=peak_locations, + motion=motion, + ) return recording_corrected, motion_info else: return recording_corrected @@ -403,25 +419,6 @@ def correct_motion( correct_motion.__doc__ = correct_motion.__doc__.format(_doc_presets, _shared_job_kwargs_doc) -def save_motion_info(motion_info, folder, overwrite=False): - folder = Path(folder) - if folder.is_dir(): - if not overwrite: - raise FileExistsError(f"Folder {folder} already exists. Use `overwrite=True` to overwrite.") - else: - shutil.rmtree(folder) - folder.mkdir(exist_ok=True, parents=True) - - (folder / "parameters.json").write_text( - json.dumps(motion_info["parameters"], indent=4, cls=SIJsonEncoder), encoding="utf8" - ) - (folder / "run_times.json").write_text(json.dumps(motion_info["run_times"], indent=4), encoding="utf8") - - np.save(folder / "peaks.npy", motion_info["peaks"]) - np.save(folder / "peak_locations.npy", motion_info["peak_locations"]) - motion_info["motion"].save(folder / "motion") - - def load_motion_info(folder): from spikeinterface.sortingcomponents.motion_utils import Motion From f8ea231a7a1d3573fb3d0bf26a636183cb8d6a21 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 14:39:22 +0000 Subject: [PATCH 50/81] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/spikeinterface/preprocessing/motion.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/spikeinterface/preprocessing/motion.py b/src/spikeinterface/preprocessing/motion.py index a98bdc171a..71ae3f3ebb 100644 --- a/src/spikeinterface/preprocessing/motion.py +++ b/src/spikeinterface/preprocessing/motion.py @@ -320,8 +320,9 @@ def correct_motion( if folder is not None: folder = Path(folder) if overwrite: - if folder.exists(): + if folder.exists(): import shutil + shutil.rmtree(folder) else: assert not folder.exists(), f"Folder {folder} already exists" From e052f047c4ea7d8b7c57a19b811251aa5ff3fd58 Mon Sep 17 00:00:00 2001 From: Pierre Yger Date: Mon, 1 Jul 2024 16:42:53 +0200 Subject: [PATCH 51/81] Confused in the git... --- src/spikeinterface/preprocessing/motion.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/spikeinterface/preprocessing/motion.py b/src/spikeinterface/preprocessing/motion.py index a98bdc171a..c9bc2a2207 100644 --- a/src/spikeinterface/preprocessing/motion.py +++ b/src/spikeinterface/preprocessing/motion.py @@ -320,12 +320,11 @@ def correct_motion( if folder is not None: folder = Path(folder) if overwrite: - if folder.exists(): + if folder.is_dir(): import shutil shutil.rmtree(folder) else: assert not folder.exists(), f"Folder {folder} already exists" - folder.mkdir(exist_ok=True, parents=True) (folder / "parameters.json").write_text(json.dumps(parameters, indent=4, cls=SIJsonEncoder), encoding="utf8") From 684307073726bfdb41713adb50706c141f8f7b8d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 14:43:48 +0000 Subject: [PATCH 52/81] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/spikeinterface/preprocessing/motion.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spikeinterface/preprocessing/motion.py b/src/spikeinterface/preprocessing/motion.py index 7ac08bb3cc..c36fc026a7 100644 --- a/src/spikeinterface/preprocessing/motion.py +++ b/src/spikeinterface/preprocessing/motion.py @@ -320,7 +320,7 @@ def correct_motion( if folder is not None: folder = Path(folder) if overwrite: - if folder.is_dir(): + if folder.is_dir(): import shutil shutil.rmtree(folder) From 9049596a943b96febbfe6d21d25af569167e638f Mon Sep 17 00:00:00 2001 From: Pierre Yger Date: Mon, 1 Jul 2024 16:46:27 +0200 Subject: [PATCH 53/81] Lost --- src/spikeinterface/preprocessing/motion.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spikeinterface/preprocessing/motion.py b/src/spikeinterface/preprocessing/motion.py index c36fc026a7..c04c392bac 100644 --- a/src/spikeinterface/preprocessing/motion.py +++ b/src/spikeinterface/preprocessing/motion.py @@ -320,7 +320,7 @@ def correct_motion( if folder is not None: folder = Path(folder) if overwrite: - if folder.is_dir(): + if folder.exists(): import shutil shutil.rmtree(folder) From 7b26657717aefc2660a29a19529884a404a0e7f7 Mon Sep 17 00:00:00 2001 From: Pierre Yger Date: Mon, 1 Jul 2024 16:53:42 +0200 Subject: [PATCH 54/81] Fixing git history --- src/spikeinterface/preprocessing/motion.py | 57 +++++++++++++--------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/src/spikeinterface/preprocessing/motion.py b/src/spikeinterface/preprocessing/motion.py index c04c392bac..57fe609e91 100644 --- a/src/spikeinterface/preprocessing/motion.py +++ b/src/spikeinterface/preprocessing/motion.py @@ -2,6 +2,7 @@ import numpy as np import json +import shutil from pathlib import Path import time @@ -204,8 +205,8 @@ def correct_motion( recording, preset="nonrigid_accurate", folder=None, - overwrite=False, output_motion_info=False, + overwrite=False, detect_kwargs={}, select_kwargs={}, localize_peaks_kwargs={}, @@ -254,12 +255,12 @@ def correct_motion( The preset name folder : Path str or None, default: None If not None then intermediate motion info are saved into a folder - overwrite : bool, default False - If folder is not None and already existing, should we overwrite output_motion_info : bool, default: False If True, then the function returns a `motion_info` dictionary that contains variables to check intermediate steps (motion_histogram, non_rigid_windows, pairwise_displacement) This dictionary is the same when reloaded from the folder + overwrite : bool, default: False + If True and folder is given, overwrite the folder if it already exists detect_kwargs : dict Optional parameters to overwrite the ones in the preset for "detect" step. select_kwargs : dict @@ -320,17 +321,12 @@ def correct_motion( if folder is not None: folder = Path(folder) if overwrite: - if folder.exists(): + if folder.is_dir(): import shutil shutil.rmtree(folder) else: - assert not folder.exists(), f"Folder {folder} already exists" - folder.mkdir(exist_ok=True, parents=True) - - (folder / "parameters.json").write_text(json.dumps(parameters, indent=4, cls=SIJsonEncoder), encoding="utf8") - if recording.check_serializability("json"): - recording.dump_to_json(folder / "recording.json") + assert not folder.is_dir(), f"Folder {folder} already exists" if not do_selection: # maybe do this directly in the folder when not None, but might be slow on external storage @@ -342,7 +338,7 @@ def correct_motion( node1 = ExtractDenseWaveforms(recording, parents=[node0], ms_before=0.1, ms_after=0.3) - # node nolcalize + # node detect + localize method = localize_peaks_kwargs.pop("method", "center_of_mass") method_class = localize_peak_methods[method] node2 = method_class(recording, parents=[node0, node1], return_output=True, **localize_peaks_kwargs) @@ -381,9 +377,6 @@ def correct_motion( select_peaks=t2 - t1, localize_peaks=t3 - t2, ) - if folder is not None: - np.save(folder / "peaks.npy", peaks) - np.save(folder / "peak_locations.npy", peak_locations) t0 = time.perf_counter() motion = estimate_motion(recording, peaks, peak_locations, **estimate_motion_kwargs) @@ -392,18 +385,17 @@ def correct_motion( recording_corrected = InterpolateMotionRecording(recording, motion, **interpolate_motion_kwargs) + motion_info = dict( + parameters=parameters, + run_times=run_times, + peaks=peaks, + peak_locations=peak_locations, + motion=motion, + ) if folder is not None: - (folder / "run_times.json").write_text(json.dumps(run_times, indent=4), encoding="utf8") - motion.save(folder / "motion") + save_motion_info(motion_info, folder, overwrite=overwrite) if output_motion_info: - motion_info = dict( - parameters=parameters, - run_times=run_times, - peaks=peaks, - peak_locations=peak_locations, - motion=motion, - ) return recording_corrected, motion_info else: return recording_corrected @@ -419,6 +411,25 @@ def correct_motion( correct_motion.__doc__ = correct_motion.__doc__.format(_doc_presets, _shared_job_kwargs_doc) +def save_motion_info(motion_info, folder, overwrite=False): + folder = Path(folder) + if folder.is_dir(): + if not overwrite: + raise FileExistsError(f"Folder {folder} already exists. Use `overwrite=True` to overwrite.") + else: + shutil.rmtree(folder) + folder.mkdir(exist_ok=True, parents=True) + + (folder / "parameters.json").write_text( + json.dumps(motion_info["parameters"], indent=4, cls=SIJsonEncoder), encoding="utf8" + ) + (folder / "run_times.json").write_text(json.dumps(motion_info["run_times"], indent=4), encoding="utf8") + + np.save(folder / "peaks.npy", motion_info["peaks"]) + np.save(folder / "peak_locations.npy", motion_info["peak_locations"]) + motion_info["motion"].save(folder / "motion") + + def load_motion_info(folder): from spikeinterface.sortingcomponents.motion_utils import Motion From 790011ae3c1baf0ebc911001465443c08e73243b Mon Sep 17 00:00:00 2001 From: Charlie Windolf Date: Mon, 1 Jul 2024 13:51:27 -0700 Subject: [PATCH 55/81] Needs out-of-place mul --- src/spikeinterface/generation/drift_tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spikeinterface/generation/drift_tools.py b/src/spikeinterface/generation/drift_tools.py index 1f410f4330..cce2e08b58 100644 --- a/src/spikeinterface/generation/drift_tools.py +++ b/src/spikeinterface/generation/drift_tools.py @@ -567,7 +567,7 @@ def get_traces( wf = template[start_template:end_template] if self.amplitude_vector is not None: - wf *= self.amplitude_vector[i] + wf = wf * self.amplitude_vector[i] traces[start_traces:end_traces] += wf.astype(self.dtype, copy=False) return traces.astype(self.dtype) From ee60fc0fea60ce6221f47af8758daf2ac8372ed1 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Mon, 1 Jul 2024 21:08:18 +0100 Subject: [PATCH 56/81] Round instead of int for 'time_to_sample_index'. --- src/spikeinterface/core/baserecording.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/spikeinterface/core/baserecording.py b/src/spikeinterface/core/baserecording.py index aab7577b31..773e62ffa1 100644 --- a/src/spikeinterface/core/baserecording.py +++ b/src/spikeinterface/core/baserecording.py @@ -848,8 +848,10 @@ def time_to_sample_index(self, time_s): sample_index = time_s * self.sampling_frequency else: sample_index = (time_s - self.t_start) * self.sampling_frequency + sample_index = round(sample_index) else: sample_index = np.searchsorted(self.time_vector, time_s, side="right") - 1 + return int(sample_index) def get_num_samples(self) -> int: From d1ea2158dc8bd2de5f2d69b69ed0c1b0ed8adc87 Mon Sep 17 00:00:00 2001 From: chrishalcrow <57948917+chrishalcrow@users.noreply.github.com> Date: Tue, 2 Jul 2024 09:50:34 +0100 Subject: [PATCH 57/81] Respond to review --- doc/modules/qualitymetrics/isi_violations.rst | 9 ++++++--- doc/references.rst | 3 ++- src/spikeinterface/qualitymetrics/misc_metrics.py | 9 +++++---- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/doc/modules/qualitymetrics/isi_violations.rst b/doc/modules/qualitymetrics/isi_violations.rst index 2002ec6582..4527cdffe9 100644 --- a/doc/modules/qualitymetrics/isi_violations.rst +++ b/doc/modules/qualitymetrics/isi_violations.rst @@ -19,13 +19,14 @@ Different formulas have been developed, but all require: - :math:`T` the duration of the recording in seconds. - :math:`N` the number of spikes in the unit's spike train. - :math:`t_r` the duration of the unit's refractory period in seconds. -- :math:`n_v` the number of violations of the refractory period. Calculation from the [UMS]_ package ----------------------------------- Originally implemented in the `rpv_contamination` calculation of the UltraMegaSort2000 package: ``_. +In this method the number of spikes whose refractory period are violated, denoted :math:`n_v`, is used. + Here, the refactory period :math:`t_r` is adjusted to take account of the data recording system's minimum possible refactory period. E.g. if a system has a sampling rate of :math:`f \text{ Hz}`, the closest that two spikes from the same unit can possibly be is :math:`1/f \, \text{s}`. Hence the refactory period :math:`t_r` is the expected biological threshold minus this minimum possible @@ -40,6 +41,8 @@ The contamination rate is calculated to be Calculation from the [Llobet]_ paper ------------------------------------ +In this method the number spikes which violate other spikes' refractory periods, denoted :math:`\tilde{n}_v`, is used. + The estimated contamination :math:`C` is calculated in 2 extreme scenarios. In the first, the contaminant spikes are completely random (or come from an infinite number of other neurons). In the second, the contaminant spikes come from a single other neuron. In these scenarios, the contamination rate is @@ -47,8 +50,8 @@ come from a single other neuron. In these scenarios, the contamination rate is .. math:: C = \frac{FP}{TP + FP} \approx \begin{cases} - 1 - \sqrt{1 - \frac{n_v T}{N^2 t_r}} \text{ for the case of random contamination} \\ - \frac{1}{2} \left( 1 - \sqrt{1 - \frac{2 n_v T}{N^2 t_r}} \right) \text{ for the case of 1 contaminant neuron} + 1 - \sqrt{1 - \frac{\tilde{n}_v T}{N^2 t_r}} \text{ for the case of random contamination} \\ + \frac{1}{2} \left( 1 - \sqrt{1 - \frac{2 \tilde{n}_v T}{N^2 t_r}} \right) \text{ for the case of 1 contaminant neuron} \end{cases} Where :math:`TP` is the number of true positives (detected spikes that come from the neuron) and :math:`FP` is the number of false positives (detected spikes that don't come from the neuron). diff --git a/doc/references.rst b/doc/references.rst index 48b7cd44f6..5fbcbecb63 100644 --- a/doc/references.rst +++ b/doc/references.rst @@ -51,7 +51,8 @@ or :code:`compute_quality_metrics()` methods, please include the citations for t important for your research: - :code:`amplitude_cutoff` [Hill]_ -- :code:`amplitude_median` or :code:`sliding_rp_violation` [IBL]_ +- :code:`amplitude_median` [IBL]_ +- :code:`sliding_rp_violation` [IBL]_ - :code:`drift` [Siegle]_ - :code:`isi_violation` [UMS]_ - :code:`rp_violation` [Llobet]_ diff --git a/src/spikeinterface/qualitymetrics/misc_metrics.py b/src/spikeinterface/qualitymetrics/misc_metrics.py index 9e4685b5bd..31a3efb2b6 100644 --- a/src/spikeinterface/qualitymetrics/misc_metrics.py +++ b/src/spikeinterface/qualitymetrics/misc_metrics.py @@ -267,10 +267,11 @@ def compute_isi_violations(sorting_analyzer, isi_threshold_ms=1.5, min_isi_ms=0, Notes ----- - The returned ISI violations ratio measures the approximate fraction of spikes in each - unit which are contaminted. This interpretation is good when the ratio is small, and - becomes worse as it grows. In cases of highly contaminated units, the ISI violations - ratio can sometimes be greater than 1. + The returned ISI violations ratio approximates the fraction of spikes in each + unit which are contaminted. The formulation assumes that the contaminating spikes + are statistically independent from the other spikes in that cluster. This + approximation can break down in reality, especially for highly contaminated units. + See the discussion in Section 4.1 of [Llobet]_ for more details. This method counts the number of spikes whose isi is violated. If there are three spikes within `isi_threshold_ms`, the first and second are violated. Hence there are two From 91c8ac6c424db83c547035e20cdb046afe2283f4 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Tue, 2 Jul 2024 09:55:52 +0100 Subject: [PATCH 58/81] Remove unit_params_range from generate.py --- src/spikeinterface/core/generate.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/spikeinterface/core/generate.py b/src/spikeinterface/core/generate.py index af6664b886..11909bce0e 100644 --- a/src/spikeinterface/core/generate.py +++ b/src/spikeinterface/core/generate.py @@ -1440,7 +1440,6 @@ def generate_templates( dtype="float32", upsample_factor=None, unit_params=None, - unit_params_range=None, mode="ellipsoid", ): """ @@ -1497,9 +1496,7 @@ def generate_templates( * (num_units, num_samples, num_channels, upsample_factor) if upsample_factor is not None """ - unit_params = unit_params or dict() - unit_params_range = unit_params_range or dict() rng = np.random.default_rng(seed=seed) # neuron location must be 3D From b1392edfe7ad4e348df343b47b7e76138a441106 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Tue, 2 Jul 2024 11:19:39 +0100 Subject: [PATCH 59/81] Rename clusters to units. --- src/spikeinterface/postprocessing/correlograms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index b1e5cbd9c4..fd820719ab 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -192,7 +192,7 @@ def _compute_num_bins(window_size, bin_size): def _compute_correlograms_on_sorting(sorting, window_ms, bin_ms, method="auto"): """ - Computes several cross-correlogram in one course from several clusters. + Computes cross-correlograms from multiple units. Entry function to compute correlograms across all units in a `Sorting` object (i.e. spike trains at all determined offsets will be computed @@ -342,7 +342,7 @@ def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size m = mask[:-shift] # Find the indices in the raveled correlograms array that need - # to be incremented, taking into account the spike clusters. + # to be incremented, taking into account the spike unit labels. if sign == 1: indices = np.ravel_multi_index( (spike_labels[+shift:][m], spike_labels[:-shift][m], spike_diff_b[m] + num_half_bins), From 274127342142946d9cf2468ca34ddfa8bd798289 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Tue, 2 Jul 2024 11:32:21 +0100 Subject: [PATCH 60/81] Add formula to correlogram docstring description. --- src/spikeinterface/postprocessing/correlograms.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index fd820719ab..e96fcb570c 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -36,10 +36,12 @@ class ComputeCorrelograms(AnalyzerExtension): ------- correlogram : np.array Correlograms with shape (num_units, num_units, num_bins) - The diagonal of correlogram is the auto correlogram. The output - is in bin counts. - correlogram[A, B, :] is the symmetry of correlogram[B, A, :] - correlogram[A, B, :] have to be read as the histogram of spiketimesA - spiketimesB + The diagonal of the correlogram (e.g. correlogram[A, A, :]) + holds the unit auto correlograms. The off-diagonal elements + are the cross-correlograms between units, where correlogram[A, B, :] + and correlogram[B, A, :] represent cross-correlation between + the same pair of units, applied in opposite directions, + correlogram[A, B, :] = correlogram[B, A, ::-1]. bins : np.array The bin edges in ms From a96821cb15c6262de505bbed04bc2e6a5aa5b1c2 Mon Sep 17 00:00:00 2001 From: JoeZiminski Date: Tue, 2 Jul 2024 11:37:47 +0100 Subject: [PATCH 61/81] Rename spike_labels -> spike_unit_indices --- .../postprocessing/correlograms.py | 24 +++++++++---------- .../postprocessing/tests/test_correlograms.py | 14 +++++------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/spikeinterface/postprocessing/correlograms.py b/src/spikeinterface/postprocessing/correlograms.py index e96fcb570c..7c22260dbe 100644 --- a/src/spikeinterface/postprocessing/correlograms.py +++ b/src/spikeinterface/postprocessing/correlograms.py @@ -262,16 +262,16 @@ def _compute_correlograms_numpy(sorting, window_size, bin_size): for seg_index in range(num_seg): spike_times = spikes[seg_index]["sample_index"] - spike_labels = spikes[seg_index]["unit_index"] + spike_unit_indices = spikes[seg_index]["unit_index"] - c0 = correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size) + c0 = correlogram_for_one_segment(spike_times, spike_unit_indices, window_size, bin_size) correlograms += c0 return correlograms -def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size): +def correlogram_for_one_segment(spike_times, spike_unit_indices, window_size, bin_size): """ A very well optimized algorithm for the cross-correlation of spike trains, copied from the Phy package, written by Cyrille Rossant. @@ -281,7 +281,7 @@ def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size spike_times : np.ndarray An array of spike times (in samples, not seconds). This contains spikes from all units. - spike_labels : np.ndarray + spike_unit_indices : np.ndarray An array of labels indicating the unit of the corresponding spike in `spike_times`. window_size : int @@ -315,7 +315,7 @@ def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size match within the window size. """ num_bins, num_half_bins = _compute_num_bins(window_size, bin_size) - num_units = len(np.unique(spike_labels)) + num_units = len(np.unique(spike_unit_indices)) correlograms = np.zeros((num_units, num_units, num_bins), dtype="int64") @@ -347,12 +347,12 @@ def correlogram_for_one_segment(spike_times, spike_labels, window_size, bin_size # to be incremented, taking into account the spike unit labels. if sign == 1: indices = np.ravel_multi_index( - (spike_labels[+shift:][m], spike_labels[:-shift][m], spike_diff_b[m] + num_half_bins), + (spike_unit_indices[+shift:][m], spike_unit_indices[:-shift][m], spike_diff_b[m] + num_half_bins), correlograms.shape, ) else: indices = np.ravel_multi_index( - (spike_labels[:-shift][m], spike_labels[+shift:][m], spike_diff_b[m] + num_half_bins), + (spike_unit_indices[:-shift][m], spike_unit_indices[+shift:][m], spike_diff_b[m] + num_half_bins), correlograms.shape, ) @@ -411,12 +411,12 @@ def _compute_correlograms_numba(sorting, window_size, bin_size): for seg_index in range(sorting.get_num_segments()): spike_times = spikes[seg_index]["sample_index"] - spike_labels = spikes[seg_index]["unit_index"] + spike_unit_indices = spikes[seg_index]["unit_index"] _compute_correlograms_one_segment_numba( correlograms, spike_times.astype(np.int64, copy=False), - spike_labels.astype(np.int32, copy=False), + spike_unit_indices.astype(np.int32, copy=False), window_size, bin_size, num_half_bins, @@ -433,7 +433,7 @@ def _compute_correlograms_numba(sorting, window_size, bin_size): cache=False, ) def _compute_correlograms_one_segment_numba( - correlograms, spike_times, spike_labels, window_size, bin_size, num_half_bins + correlograms, spike_times, spike_unit_indices, window_size, bin_size, num_half_bins ): """ Compute the correlograms using `numba` for speed. @@ -455,7 +455,7 @@ def _compute_correlograms_one_segment_numba( spike_times : np.ndarray An array of spike times (in samples, not seconds). This contains spikes from all units. - spike_labels : np.ndarray + spike_unit_indices : np.ndarray An array of labels indicating the unit of the corresponding spike in `spike_times`. window_size : int @@ -494,4 +494,4 @@ def _compute_correlograms_one_segment_numba( bin = diff // bin_size - correlograms[spike_labels[i], spike_labels[j], num_half_bins + bin] += 1 + correlograms[spike_unit_indices[i], spike_unit_indices[j], num_half_bins + bin] += 1 diff --git a/src/spikeinterface/postprocessing/tests/test_correlograms.py b/src/spikeinterface/postprocessing/tests/test_correlograms.py index 3b43921a0b..66d84c9565 100644 --- a/src/spikeinterface/postprocessing/tests/test_correlograms.py +++ b/src/spikeinterface/postprocessing/tests/test_correlograms.py @@ -189,18 +189,18 @@ def test_compute_correlograms(fill_all_bins, on_time_bin, multi_segment): counts should double when two segments with identical spike times / labels are used. """ sampling_frequency = 30000 - window_ms, bin_ms, spike_times, spike_labels, expected_bins, expected_result_auto, expected_result_corr = ( + window_ms, bin_ms, spike_times, spike_unit_indices, expected_bins, expected_result_auto, expected_result_corr = ( generate_correlogram_test_dataset(sampling_frequency, fill_all_bins, on_time_bin) ) if multi_segment: sorting = NumpySorting.from_times_labels( - times_list=[spike_times], labels_list=[spike_labels], sampling_frequency=sampling_frequency + times_list=[spike_times], labels_list=[spike_unit_indices], sampling_frequency=sampling_frequency ) else: sorting = NumpySorting.from_times_labels( times_list=[spike_times, spike_times], - labels_list=[spike_labels, spike_labels], + labels_list=[spike_unit_indices, spike_unit_indices], sampling_frequency=sampling_frequency, ) expected_result_auto *= 2 @@ -235,13 +235,13 @@ def test_compute_correlograms_different_units(method): spike_times = np.array([0, 4, 8, 16]) / 1000 * sampling_frequency spike_times.astype(int) - spike_labels = np.array([0, 1, 0, 1]) + spike_unit_indices = np.array([0, 1, 0, 1]) window_ms = 40 bin_ms = 5 sorting = NumpySorting.from_times_labels( - times_list=[spike_times], labels_list=[spike_labels], sampling_frequency=sampling_frequency + times_list=[spike_times], labels_list=[spike_unit_indices], sampling_frequency=sampling_frequency ) result, bins = compute_correlograms(sorting, window_ms=window_ms, bin_ms=bin_ms, method=method) @@ -323,7 +323,7 @@ def generate_correlogram_test_dataset(sampling_frequency, fill_all_bins, hit_bin # Now, make a set of times that increase by `base_diff_time` e.g. # if base_diff_time=0.0051 then our spike times are [`0.0051, 0.0102, ...]` spike_times = np.repeat(np.arange(num_filled_bins), num_units) * base_diff_time - spike_labels = np.tile(np.arange(num_units), int(spike_times.size / num_units)) + spike_unit_indices = np.tile(np.arange(num_units), int(spike_times.size / num_units)) spike_times *= sampling_frequency spike_times = spike_times.astype(int) @@ -368,4 +368,4 @@ def generate_correlogram_test_dataset(sampling_frequency, fill_all_bins, hit_bin expected_result_corr = expected_result_auto.copy() expected_result_corr[int(num_bins / 2)] = num_filled_bins - return window_ms, bin_ms, spike_times, spike_labels, expected_bins, expected_result_auto, expected_result_corr + return window_ms, bin_ms, spike_times, spike_unit_indices, expected_bins, expected_result_auto, expected_result_corr From 6529bd3983a7e9ed01ae7f74e9242d60ea066ea2 Mon Sep 17 00:00:00 2001 From: chrishalcrow <57948917+chrishalcrow@users.noreply.github.com> Date: Tue, 2 Jul 2024 11:56:23 +0100 Subject: [PATCH 62/81] Update test and fix the failings: rp_violation and drift --- .../qualitymetrics/misc_metrics.py | 12 ++-- .../tests/test_metrics_functions.py | 55 ++++++++++++------- 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/src/spikeinterface/qualitymetrics/misc_metrics.py b/src/spikeinterface/qualitymetrics/misc_metrics.py index fca521c90f..79e6d1c8e3 100644 --- a/src/spikeinterface/qualitymetrics/misc_metrics.py +++ b/src/spikeinterface/qualitymetrics/misc_metrics.py @@ -388,9 +388,11 @@ def compute_refrac_period_violations( nb_violations = {} rp_contamination = {} - for i, unit_id in enumerate(unit_ids): + for unit_index, unit_id in enumerate(sorting.unit_ids): + if unit_id not in unit_ids: + continue - nb_violations[unit_id] = n_v = nb_rp_violations[i] + nb_violations[unit_id] = n_v = nb_rp_violations[unit_index] N = num_spikes[unit_id] if N == 0: rp_contamination[unit_id] = np.nan @@ -1083,10 +1085,10 @@ def compute_drift_metrics( spikes_in_bin = spikes_in_segment[i0:i1] spike_locations_in_bin = spike_locations_in_segment[i0:i1][direction] - for unit_ind in np.arange(len(unit_ids)): - mask = spikes_in_bin["unit_index"] == unit_ind + for unit_index, unit_id in enumerate(unit_ids): + mask = spikes_in_bin["unit_index"] == sorting.id_to_index(unit_id) if np.sum(mask) >= min_spikes_per_interval: - median_positions[unit_ind, bin_index] = np.median(spike_locations_in_bin[mask]) + median_positions[unit_index, bin_index] = np.median(spike_locations_in_bin[mask]) if median_position_segments is None: median_position_segments = median_positions else: diff --git a/src/spikeinterface/qualitymetrics/tests/test_metrics_functions.py b/src/spikeinterface/qualitymetrics/tests/test_metrics_functions.py index 6652ea6654..9175748a4a 100644 --- a/src/spikeinterface/qualitymetrics/tests/test_metrics_functions.py +++ b/src/spikeinterface/qualitymetrics/tests/test_metrics_functions.py @@ -84,24 +84,44 @@ def small_sorting_analyzer(): def test_unit_structure_in_output(small_sorting_analyzer): - for metric_name in get_quality_metric_list(): - result = _misc_metric_name_to_func[metric_name](sorting_analyzer=small_sorting_analyzer) - if isinstance(result, dict): - assert list(result.keys()) == ["#3", "#9", "#4"] - else: - for one_result in result: - assert list(one_result.keys()) == ["#3", "#9", "#4"] + qm_params = { + "presence_ratio": {"bin_duration_s": 0.1}, + "amplitude_cutoff": {"num_histogram_bins": 3}, + "amplitude_cv": {"average_num_spikes_per_bin": 7, "min_num_bins": 3}, + "firing_range": {"bin_size_s": 1}, + "isi_violation": {"isi_threshold_ms": 10}, + "drift": {"interval_s": 1, "min_spikes_per_interval": 5}, + "sliding_rp_violation": {"max_ref_period_ms": 50, "bin_size_ms": 0.15}, + "rp_violation": {"refractory_period_ms": 10.0, "censored_period_ms": 0.0}, + } for metric_name in get_quality_metric_list(): - result = _misc_metric_name_to_func[metric_name](sorting_analyzer=small_sorting_analyzer, unit_ids=["#9", "#3"]) - if isinstance(result, dict): - assert list(result.keys()) == ["#9", "#3"] + try: + qm_param = qm_params[metric_name] + except: + qm_param = {} + + result_all = _misc_metric_name_to_func[metric_name](sorting_analyzer=small_sorting_analyzer, **qm_param) + result_sub = _misc_metric_name_to_func[metric_name]( + sorting_analyzer=small_sorting_analyzer, unit_ids=["#4", "#9"], **qm_param + ) + + if isinstance(result_all, dict): + assert list(result_all.keys()) == ["#3", "#9", "#4"] + assert list(result_sub.keys()) == ["#4", "#9"] + assert result_sub["#9"] == result_all["#9"] + assert result_sub["#4"] == result_all["#4"] + else: - for one_result in result: - print(metric_name) - assert list(one_result.keys()) == ["#9", "#3"] + for result_ind, result in enumerate(result_sub): + + assert list(result_all[result_ind].keys()) == ["#3", "#9", "#4"] + assert result_sub[result_ind].keys() == set(["#4", "#9"]) + + assert result_sub[result_ind]["#9"] == result_all[result_ind]["#9"] + assert result_sub[result_ind]["#4"] == result_all[result_ind]["#4"] def test_unit_id_order_independence(small_sorting_analyzer): @@ -110,12 +130,9 @@ def test_unit_id_order_independence(small_sorting_analyzer): and checks that their calculated quality metrics are independent of the ordering and labelling. """ - recording, sorting = generate_ground_truth_recording( - durations=[2.0], - num_units=4, - seed=1205, - ) - sorting = sorting.select_units([0, 2, 3]) + recording = small_sorting_analyzer.recording + sorting = small_sorting_analyzer.sorting.select_units(["#4", "#9", "#3"], [0, 2, 3]) + small_sorting_analyzer_2 = create_sorting_analyzer(recording=recording, sorting=sorting, format="memory") extensions_to_compute = { From c95c4357126eab2619cdffe5826409689638df0c Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Tue, 2 Jul 2024 07:12:51 -0600 Subject: [PATCH 63/81] Update src/spikeinterface/core/base.py --- src/spikeinterface/core/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spikeinterface/core/base.py b/src/spikeinterface/core/base.py index a7b250690f..dcb80d2a67 100644 --- a/src/spikeinterface/core/base.py +++ b/src/spikeinterface/core/base.py @@ -56,7 +56,7 @@ def __init__(self, main_ids: Sequence) -> None: # "main_ids" will either be channel_ids or units_ids # They are used for properties - self._main_ids = np.asarray(main_ids) + self._main_ids = np.array(main_ids) if len(self._main_ids) > 0: assert ( self._main_ids.dtype.kind in "uiSU" From 451a1d4efb21fbb3f8b9515dbe0bb023f35aec4a Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Tue, 2 Jul 2024 15:23:31 +0200 Subject: [PATCH 64/81] Improve export to Phy property handling --- .../exporters/tests/test_export_to_phy.py | 63 +++++++++++++++++++ src/spikeinterface/exporters/to_phy.py | 27 ++++++-- 2 files changed, 86 insertions(+), 4 deletions(-) diff --git a/src/spikeinterface/exporters/tests/test_export_to_phy.py b/src/spikeinterface/exporters/tests/test_export_to_phy.py index 47294b3cf7..0d4ab76c67 100644 --- a/src/spikeinterface/exporters/tests/test_export_to_phy.py +++ b/src/spikeinterface/exporters/tests/test_export_to_phy.py @@ -91,6 +91,69 @@ def test_export_to_phy_by_property(sorting_analyzer_with_group_for_export, creat assert template_inds.shape == (sorting_analyzer.unit_ids.size, 4) +def test_export_to_phy_metrics(sorting_analyzer_sparse_for_export, create_cache_folder): + cache_folder = create_cache_folder + + sorting_analyzer = sorting_analyzer_sparse_for_export + + # quality metrics are computed already + qm = sorting_analyzer.get_extension("quality_metrics").get_data() + output_folder = cache_folder / "phy_output_qm" + export_to_phy( + sorting_analyzer, + output_folder, + compute_pc_features=True, + compute_amplitudes=True, + n_jobs=1, + chunk_size=10000, + progress_bar=True, + add_quality_metrics=True, + ) + for col_name in qm.columns: + assert (output_folder / f"cluster_{col_name}.tsv").is_file() + + # quality metrics are computed already + tm_ext = sorting_analyzer.compute("template_metrics") + tm = tm_ext.get_data() + output_folder = cache_folder / "phy_output_tm_not_qm" + export_to_phy( + sorting_analyzer, + output_folder, + compute_pc_features=True, + compute_amplitudes=True, + n_jobs=1, + chunk_size=10000, + progress_bar=True, + add_quality_metrics=False, + add_template_metrics=True, + ) + for col_name in tm.columns: + assert (output_folder / f"cluster_{col_name}.tsv").is_file() + for col_name in qm.columns: + assert not (output_folder / f"cluster_{col_name}.tsv").is_file() + + # custom metrics + sorting_analyzer.sorting.set_property("custom_metric", np.random.rand(sorting_analyzer.unit_ids.size)) + output_folder = cache_folder / "phy_output_custom" + export_to_phy( + sorting_analyzer, + output_folder, + compute_pc_features=True, + compute_amplitudes=True, + n_jobs=1, + chunk_size=10000, + progress_bar=True, + add_quality_metrics=False, + add_template_metrics=False, + additional_properties=["custom_metric"], + ) + assert (output_folder / "cluster_custom_metric.tsv").is_file() + for col_name in tm.columns: + assert not (output_folder / f"cluster_{col_name}.tsv").is_file() + for col_name in qm.columns: + assert not (output_folder / f"cluster_{col_name}.tsv").is_file() + + if __name__ == "__main__": sorting_analyzer_sparse = make_sorting_analyzer(sparse=True) sorting_analyzer_group = make_sorting_analyzer(sparse=False, with_group=True) diff --git a/src/spikeinterface/exporters/to_phy.py b/src/spikeinterface/exporters/to_phy.py index d7be6c1ba3..7b3c7daab0 100644 --- a/src/spikeinterface/exporters/to_phy.py +++ b/src/spikeinterface/exporters/to_phy.py @@ -25,8 +25,10 @@ def export_to_phy( sparsity: Optional[ChannelSparsity] = None, copy_binary: bool = True, remove_if_exists: bool = False, - peak_sign: Literal["both", "neg", "pos"] = "neg", template_mode: str = "average", + add_quality_metrics: bool = True, + add_template_metrics: bool = True, + additional_properties: list | None = None, dtype: Optional[npt.DTypeLike] = None, verbose: bool = True, use_relative_path: bool = False, @@ -51,10 +53,14 @@ def export_to_phy( If True, the recording is copied and saved in the phy "output_folder" remove_if_exists : bool, default: False If True and "output_folder" exists, it is removed and overwritten - peak_sign : "neg" | "pos" | "both", default: "neg" - Used by compute_spike_amplitudes template_mode : str, default: "average" Parameter "mode" to be given to SortingAnalyzer.get_template() + add_quality_metrics : bool, default: True + If True, quality metrics (if computed) are saved as Phy tsv and will appear in the ClusterView. + add_template_metrics : bool, default: True + If True, template metrics (if computed) are saved as Phy tsv and will appear in the ClusterView. + additional_properties : list | None, default: None + List of additional properties to be saved as Phy tsv and will appear in the ClusterView. dtype : dtype or None, default: None Dtype to save binary data verbose : bool, default: True @@ -244,7 +250,7 @@ def export_to_phy( channel_group = pd.DataFrame({"cluster_id": [i for i in range(len(unit_ids))], "channel_group": unit_groups}) channel_group.to_csv(output_folder / "cluster_channel_group.tsv", sep="\t", index=False) - if sorting_analyzer.has_extension("quality_metrics"): + if sorting_analyzer.has_extension("quality_metrics") and add_quality_metrics: qm_data = sorting_analyzer.get_extension("quality_metrics").get_data() for column_name in qm_data.columns: # already computed by phy @@ -253,6 +259,19 @@ def export_to_phy( {"cluster_id": [i for i in range(len(unit_ids))], column_name: qm_data[column_name].values} ) metric.to_csv(output_folder / f"cluster_{column_name}.tsv", sep="\t", index=False) + if sorting_analyzer.has_extension("template_metrics") and add_template_metrics: + tm_data = sorting_analyzer.get_extension("template_metrics").get_data() + for column_name in tm_data.columns: + metric = pd.DataFrame( + {"cluster_id": [i for i in range(len(unit_ids))], column_name: tm_data[column_name].values} + ) + metric.to_csv(output_folder / f"cluster_{column_name}.tsv", sep="\t", index=False) + if additional_properties is not None: + for prop_name in additional_properties: + prop_data = sorting.get_property(prop_name) + if prop_data is not None: + prop = pd.DataFrame({"cluster_id": [i for i in range(len(unit_ids))], prop_name: prop_data}) + prop.to_csv(output_folder / f"cluster_{prop_name}.tsv", sep="\t", index=False) if verbose: print("Run:\nphy template-gui ", str(output_folder / "params.py")) From d1744590ec11b65ed4cb43fc13051924ac880ebe Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Tue, 2 Jul 2024 16:20:32 +0200 Subject: [PATCH 65/81] Add pooch to docs extra --- pyproject.toml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 644d52608e..f40aa93140 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -175,13 +175,16 @@ docs = [ "ipython", # for notebooks in the gallery - "MEArec", # Use as an example - "datalad==0.16.2", # Download mearec data, not sure if needed as is installed with conda as well because of git-annex + "MEArec", # Use as an example "pandas", # in the modules gallery comparison tutorial "hdbscan>=0.8.33", # For sorters spykingcircus2 + tridesclous "numba", # For many postprocessing functions "xarray", # For use of SortingAnalyzer zarr format "networkx", + # Download data + "pooch>=1.8.2", + "datalad>=1.0.2", + # for release we need pypi, so this needs to be commented # "probeinterface @ git+https://github.com/SpikeInterface/probeinterface.git", # We always build from the latest version # "neo @ git+https://github.com/NeuralEnsemble/python-neo.git", # We always build from the latest version From a178b7e1a9428c4af1aff76134f498e85fa546aa Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Tue, 2 Jul 2024 08:27:33 -0600 Subject: [PATCH 66/81] Add plexon2 tests action for install wine and drop full (linux only) tests (#3101) * add plexon tests and drop full (linux only) tests --- .github/actions/install-wine/action.yml | 19 +- .github/determine_testing_environment.py | 77 ++++---- .github/workflows/all-tests.yml | 16 +- .github/workflows/full-test.yml | 167 ------------------ pyproject.toml | 22 ++- .../extractors/neoextractors/plexon2.py | 6 +- 6 files changed, 83 insertions(+), 224 deletions(-) delete mode 100644 .github/workflows/full-test.yml diff --git a/.github/actions/install-wine/action.yml b/.github/actions/install-wine/action.yml index 3ae08ecd34..85e70b471d 100644 --- a/.github/actions/install-wine/action.yml +++ b/.github/actions/install-wine/action.yml @@ -2,20 +2,29 @@ name: Install packages description: This action installs the package and its dependencies for testing inputs: - python-version: - description: 'Python version to set up' - required: false os: description: 'Operating system to set up' - required: false + required: true runs: using: "composite" steps: - - name: Install wine (needed for Plexon2) + - name: Install wine on Linux + if: runner.os == 'Linux' run: | sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list sudo dpkg --add-architecture i386 sudo apt-get update -qq sudo apt-get install -yqq --allow-downgrades libc6:i386 libgcc-s1:i386 libstdc++6:i386 wine shell: bash + - name: Install wine on macOS + if: runner.os == 'macOS' + run: | + brew install --cask xquartz + brew install --cask wine-stable + shell: bash + + - name: Skip installation on Windows + if: ${{ inputs.os == 'Windows' }} + run: echo "Skipping Wine installation on Windows. Not necessary." + shell: bash diff --git a/.github/determine_testing_environment.py b/.github/determine_testing_environment.py index 4945ccc807..0c0c5ef95b 100644 --- a/.github/determine_testing_environment.py +++ b/.github/determine_testing_environment.py @@ -36,50 +36,47 @@ file_is_in_src = changed_file.parts[0] == "src" - if not file_is_in_src: - - if changed_file.name == "pyproject.toml": - pyproject_toml_changed = True - - else: - if changed_file.name == "neobaseextractor.py": - neobaseextractor_changed = True - elif changed_file.name == "plexon2.py": - extractors_changed = True - elif "core" in changed_file.parts: - conditions_changed = True - elif "extractors" in changed_file.parts: - extractors_changed = True - elif "preprocessing" in changed_file.parts: - preprocessing_changed = True - elif "postprocessing" in changed_file.parts: - postprocessing_changed = True - elif "qualitymetrics" in changed_file.parts: - qualitymetrics_changed = True - elif "comparison" in changed_file.parts: - comparison_changed = True - elif "curation" in changed_file.parts: - curation_changed = True - elif "widgets" in changed_file.parts: - widgets_changed = True - elif "exporters" in changed_file.parts: - exporters_changed = True - elif "sortingcomponents" in changed_file.parts: - sortingcomponents_changed = True - elif "generation" in changed_file.parts: - generation_changed = True - elif "sorters" in changed_file.parts: - if "external" in changed_file.parts: - sorters_external_changed = True - elif "internal" in changed_file.parts: - sorters_internal_changed = True - else: - sorters_changed = True + + if changed_file.name == "pyproject.toml": + pyproject_toml_changed = True + elif changed_file.name == "neobaseextractor.py": + neobaseextractor_changed = True + elif changed_file.name == "plexon2.py": + plexon2_changed = True + elif "core" in changed_file.parts: + core_changed = True + elif "extractors" in changed_file.parts: + extractors_changed = True + elif "preprocessing" in changed_file.parts: + preprocessing_changed = True + elif "postprocessing" in changed_file.parts: + postprocessing_changed = True + elif "qualitymetrics" in changed_file.parts: + qualitymetrics_changed = True + elif "comparison" in changed_file.parts: + comparison_changed = True + elif "curation" in changed_file.parts: + curation_changed = True + elif "widgets" in changed_file.parts: + widgets_changed = True + elif "exporters" in changed_file.parts: + exporters_changed = True + elif "sortingcomponents" in changed_file.parts: + sortingcomponents_changed = True + elif "generation" in changed_file.parts: + generation_changed = True + elif "sorters" in changed_file.parts: + if "external" in changed_file.parts: + sorters_external_changed = True + elif "internal" in changed_file.parts: + sorters_internal_changed = True + else: + sorters_changed = True run_everything = core_changed or pyproject_toml_changed or neobaseextractor_changed run_generation_tests = run_everything or generation_changed -run_extractor_tests = run_everything or extractors_changed +run_extractor_tests = run_everything or extractors_changed or plexon2_changed run_preprocessing_tests = run_everything or preprocessing_changed run_postprocessing_tests = run_everything or postprocessing_changed run_qualitymetrics_tests = run_everything or qualitymetrics_changed diff --git a/.github/workflows/all-tests.yml b/.github/workflows/all-tests.yml index cce73a9008..8dfea50faf 100644 --- a/.github/workflows/all-tests.yml +++ b/.github/workflows/all-tests.yml @@ -78,9 +78,8 @@ jobs: run: pytest -m "core" shell: bash - - name: Install Other Testing Dependencies + - name: Install Dependencies for Timing Display run: | - pip install -e .[test] pip install tabulate pip install pandas shell: bash @@ -91,6 +90,7 @@ jobs: run: echo "dataset_hash=$(git ls-remote https://gin.g-node.org/NeuralEnsemble/ephy_testing_data.git HEAD | cut -f1)" >> $GITHUB_OUTPUT - name: Cache datasets + if: env.RUN_EXTRACTORS_TESTS == 'true' id: cache-datasets uses: actions/cache/restore@v4 with: @@ -119,6 +119,9 @@ jobs: fi git config --global filter.annex.process "git-annex filter-process" # recommended for efficiency + - name : Install Plexon dependencies + if: env.INSTALL_PLEXON_DEPENDENCIES == 'true' + uses: ./.github/actions/install-wine - name: Set execute permissions on run_tests.sh shell: bash @@ -130,16 +133,21 @@ jobs: HDF5_PLUGIN_PATH: ${{ github.workspace }}/hdf5_plugin_path_maxwell if: env.RUN_EXTRACTORS_TESTS == 'true' run: | - pip install -e .[extractors,streaming_extractors] + pip install -e .[extractors,streaming_extractors,test_extractors] ./.github/run_tests.sh "extractors and not streaming_extractors" --no-virtual-env - name: Test preprocessing shell: bash if: env.RUN_PREPROCESSING_TESTS == 'true' run: | - pip install -e .[preprocessing] + pip install -e .[preprocessing,test_preprocessing] ./.github/run_tests.sh "preprocessing and not deepinterpolation" --no-virtual-env + - name: Install remaining testing dependencies # TODO: Remove this step once we have better modularization + shell: bash + run: | + pip install -e .[test] + - name: Test postprocessing shell: bash if: env.RUN_POSTPROCESSING_TESTS == 'true' diff --git a/.github/workflows/full-test.yml b/.github/workflows/full-test.yml deleted file mode 100644 index ed2f28dc23..0000000000 --- a/.github/workflows/full-test.yml +++ /dev/null @@ -1,167 +0,0 @@ -name: Full spikeinterface tests - -on: - pull_request: - types: [synchronize, opened, reopened] - branches: - - main - -concurrency: # Cancel previous workflows on the same pull request - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -env: # For the sortingview backend - KACHERY_CLOUD_CLIENT_ID: ${{ secrets.KACHERY_CLOUD_CLIENT_ID }} - KACHERY_CLOUD_PRIVATE_KEY: ${{ secrets.KACHERY_CLOUD_PRIVATE_KEY }} - -jobs: - full-tests-depending-on-changed-files: - name: Test on (${{ matrix.os }}) - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - # "macos-latest", "windows-latest" - os: ["ubuntu-latest", ] - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: '3.10' - - name: Get current year-month - id: date - run: echo "date=$(date +'%Y-%m')" >> $GITHUB_OUTPUT - - name: Get ephy_testing_data current head hash - # the key depends on the last comit repo https://gin.g-node.org/NeuralEnsemble/ephy_testing_data.git - id: vars - run: | - echo "HASH_EPHY_DATASET=$(git ls-remote https://gin.g-node.org/NeuralEnsemble/ephy_testing_data.git HEAD | cut -f1)" >> $GITHUB_OUTPUT - - name: Restore cached gin data for extractors tests - uses: actions/cache/restore@v4 - id: cache-datasets - env: - # the key depends on the last comit repo https://gin.g-node.org/NeuralEnsemble/ephy_testing_data.git - HASH_EPHY_DATASET: git ls-remote https://gin.g-node.org/NeuralEnsemble/ephy_testing_data.git HEAD | cut -f1 - with: - path: ~/spikeinterface_datasets - key: ${{ runner.os }}-datasets-${{ steps.vars.outputs.HASH_EPHY_DATASET }} - restore-keys: ${{ runner.os }}-datasets - - name: Install packages - uses: ./.github/actions/build-test-environment - - name: Get changed files - id: changed-files - uses: tj-actions/changed-files@v41 - - name: Module changes - id: modules-changed - run: | - for file in ${{ steps.changed-files.outputs.all_changed_files }}; do - if [[ $file == *"pyproject.toml" ]]; then - echo "pyproject.toml changed" - echo "CORE_CHANGED=true" >> $GITHUB_OUTPUT - fi - if [[ $file == *"/core/"* || $file == *"/extractors/neoextractors/neobaseextractor.py" ]]; then - echo "Core changed" - echo "CORE_CHANGED=true" >> $GITHUB_OUTPUT - fi - if [[ $file == *"/extractors/"* ]]; then - echo "Extractors changed" - echo "EXTRACTORS_CHANGED=true" >> $GITHUB_OUTPUT - fi - if [[ $file == *"plexon2"* ]]; then - echo "Plexon2 changed" - echo "PLEXON2_CHANGED=true" >> $GITHUB_OUTPUT - fi - if [[ $file == *"/preprocessing/"* ]]; then - echo "Preprocessing changed" - echo "PREPROCESSING_CHANGED=true" >> $GITHUB_OUTPUT - fi - if [[ $file == *"/postprocessing/"* ]]; then - echo "Postprocessing changed" - echo "POSTPROCESSING_CHANGED=true" >> $GITHUB_OUTPUT - fi - if [[ $file == *"/qualitymetrics/"* ]]; then - echo "Quality metrics changed" - echo "QUALITYMETRICS_CHANGED=true" >> $GITHUB_OUTPUT - fi - if [[ $file == *"/sorters/"* && $file != *"/sorters/internal/"* && $file != *"/sorters/external/"* ]]; then - echo "Sorters changed" - echo "SORTERS_CHANGED=true" >> $GITHUB_OUTPUT - fi - if [[ $file == *"/sorters/external"* ]]; then - echo "External sorters changed" - echo "SORTERS_EXTERNAL_CHANGED=true" >> $GITHUB_OUTPUT - fi - if [[ $file == *"/sorters/internal"* ]]; then - echo "Internal sorters changed" - echo "SORTERS_INTERNAL_CHANGED=true" >> $GITHUB_OUTPUT - fi - if [[ $file == *"/comparison/"* ]]; then - echo "Comparison changed" - echo "COMPARISON_CHANGED=true" >> $GITHUB_OUTPUT - fi - if [[ $file == *"/curation/"* ]]; then - echo "Curation changed" - echo "CURATION_CHANGED=true" >> $GITHUB_OUTPUT - fi - if [[ $file == *"/widgets/"* ]]; then - echo "Widgets changed" - echo "WIDGETS_CHANGED=true" >> $GITHUB_OUTPUT - fi - if [[ $file == *"/exporters/"* ]]; then - echo "Exporters changed" - echo "EXPORTERS_CHANGED=true" >> $GITHUB_OUTPUT - fi - if [[ $file == *"/sortingcomponents/"* ]]; then - echo "Sortingcomponents changed" - echo "SORTINGCOMPONENTS_CHANGED=true" >> $GITHUB_OUTPUT - fi - if [[ $file == *"/generation/"* ]]; then - echo "Generation changed" - echo "GENERATION_CHANGED=true" >> $GITHUB_OUTPUT - fi - done - - name: Set execute permissions on run_tests.sh - run: chmod +x .github/run_tests.sh - - name: Install Wine (Plexon2) - if: ${{ steps.modules-changed.outputs.PLEXON2_CHANGED == 'true' }} - uses: ./.github/actions/install-wine - - name: Test core - run: ./.github/run_tests.sh core - - name: Test extractors - env: - HDF5_PLUGIN_PATH: ${{ github.workspace }}/hdf5_plugin_path_maxwell - if: ${{ steps.modules-changed.outputs.EXTRACTORS_CHANGED == 'true' || steps.modules-changed.outputs.CORE_CHANGED == 'true' }} - run: ./.github/run_tests.sh "extractors and not streaming_extractors" - - name: Test preprocessing - if: ${{ steps.modules-changed.outputs.PREPROCESSING_CHANGED == 'true' || steps.modules-changed.outputs.CORE_CHANGED == 'true' }} - run: ./.github/run_tests.sh "preprocessing and not deepinterpolation" - - name: Test postprocessing - if: ${{ steps.modules-changed.outputs.POSTPROCESSING_CHANGED == 'true' || steps.modules-changed.outputs.CORE_CHANGED == 'true' }} - run: ./.github/run_tests.sh postprocessing - - name: Test quality metrics - if: ${{ steps.modules-changed.outputs.QUALITYMETRICS_CHANGED == 'true' || steps.modules-changed.outputs.CORE_CHANGED == 'true' }} - run: ./.github/run_tests.sh qualitymetrics - - name: Test core sorters - if: ${{ steps.modules-changed.outputs.SORTERS_CHANGED == 'true' || steps.modules-changed.outputs.CORE_CHANGED == 'true' }} - run: ./.github/run_tests.sh sorters - - name: Test comparison - if: ${{ steps.modules-changed.outputs.COMPARISON_CHANGED == 'true' || steps.modules-changed.outputs.GENERATION_CHANGED == 'true' || steps.modules-changed.outputs.CORE_CHANGED == 'true' }} - run: ./.github/run_tests.sh comparison - - name: Test curation - if: ${{ steps.modules-changed.outputs.CURATION_CHANGED == 'true' || steps.modules-changed.outputs.CORE_CHANGED == 'true' }} - run: ./.github/run_tests.sh curation - - name: Test widgets - if: ${{ steps.modules-changed.outputs.WIDGETS_CHANGED == 'true' || steps.modules-changed.outputs.CORE_CHANGED == 'true' || steps.modules-changed.outputs.QUALITYMETRICS_CHANGED == 'true' || steps.modules-changed.outputs.PREPROCESSING_CHANGED == 'true'}} - run: ./.github/run_tests.sh widgets - - name: Test exporters - if: ${{ steps.modules-changed.outputs.EXPORTERS_CHANGED == 'true' || steps.modules-changed.outputs.CORE_CHANGED == 'true' || steps.modules-changed.outputs.WIDGETS_CHANGED == 'true' }} - run: ./.github/run_tests.sh exporters - - name: Test sortingcomponents - if: ${{ steps.modules-changed.outputs.SORTINGCOMPONENTS_CHANGED == 'true' || steps.modules-changed.outputs.CORE_CHANGED == 'true' }} - run: ./.github/run_tests.sh sortingcomponents - - name: Test internal sorters - if: ${{ steps.modules-changed.outputs.SORTERS_INTERNAL_CHANGED == 'true' || steps.modules-changed.outputs.SORTINGCOMPONENTS_CHANGED || steps.modules-changed.outputs.CORE_CHANGED == 'true' }} - run: ./.github/run_tests.sh sorters_internal - - name: Test generation - if: ${{ steps.modules-changed.outputs.GENERATION_CHANGED == 'true' || steps.modules-changed.outputs.CORE_CHANGED == 'true' }} - run: ./.github/run_tests.sh generation diff --git a/pyproject.toml b/pyproject.toml index 644d52608e..0e1d0a2cba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,6 +85,7 @@ streaming_extractors = [ "s3fs" ] + preprocessing = [ "scipy", ] @@ -124,10 +125,23 @@ test_core = [ # for github test : probeinterface and neo from master # for release we need pypi, so this need to be commented - # "probeinterface @ git+https://github.com/SpikeInterface/probeinterface.git", - # "neo @ git+https://github.com/NeuralEnsemble/python-neo.git", + "probeinterface @ git+https://github.com/SpikeInterface/probeinterface.git", + "neo @ git+https://github.com/NeuralEnsemble/python-neo.git", +] + +test_extractors = [ + # Functions to download data in neo test suite + "pooch>=1.8.2", + "datalad>=1.0.2", + "probeinterface @ git+https://github.com/SpikeInterface/probeinterface.git", + "neo @ git+https://github.com/NeuralEnsemble/python-neo.git", ] +test_preprocessing = [ + "ibllib>=2.36.0", # for IBL +] + + test = [ "pytest", "pytest-dependency", @@ -148,9 +162,7 @@ test = [ # for sortingview backend "sortingview", - # Download data - "pooch>=1.8.2", - "datalad>=1.0.2", + ## install tridesclous for testing ## "tridesclous>=1.6.8", diff --git a/src/spikeinterface/extractors/neoextractors/plexon2.py b/src/spikeinterface/extractors/neoextractors/plexon2.py index c7351a308b..6c9160f13b 100644 --- a/src/spikeinterface/extractors/neoextractors/plexon2.py +++ b/src/spikeinterface/extractors/neoextractors/plexon2.py @@ -13,8 +13,8 @@ class Plexon2RecordingExtractor(NeoBaseRecordingExtractor): Parameters ---------- - file_path : str - The file path to load the recordings from. + file_path : str | Path + The file path of the plexon2 file. It should have the .pl2 extension. stream_id : str, default: None If there are several streams, specify the stream id you want to load. stream_name : str, default: None @@ -23,7 +23,7 @@ class Plexon2RecordingExtractor(NeoBaseRecordingExtractor): If True, the names of the signals are used as channel ids. If False, the channel ids are a combination of the source id and the channel index. - Example for widegain signals: + Example for wideband signals: names: ["WB01", "WB02", "WB03", "WB04"] ids: ["source3.1" , "source3.2", "source3.3", "source3.4"] all_annotations : bool, default: False From efc10c6ae3ee15bd9120eb598c2575273269acf3 Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Tue, 2 Jul 2024 16:56:22 -0600 Subject: [PATCH 67/81] clean gitignore --- .gitignore | 73 +++++++----------------------------------------------- 1 file changed, 9 insertions(+), 64 deletions(-) diff --git a/.gitignore b/.gitignore index 6c9fa6869f..7b85c7101c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,52 +1,8 @@ **/cache_folder/** -spikeinterface/core/tests/*.raw -spikeinterface/core/tests/*.json -spikeinterface/core/tests/*.pkl -spikeinterface/core/tests/*.npz - -spikeinterface/core/tests/*/*.json -spikeinterface/core/tests/*/*.raw -spikeinterface/core/tests/*/*.npy - -spikeinterface/core/tests/*/*/*.json -spikeinterface/core/tests/*/*/*.raw -spikeinterface/core/tests/*/*/*.npy - - -spikeinterface/extractors/tests/*/*/*.json -spikeinterface/extractors/tests/*/*/*.raw -spikeinterface/extractors/tests/*.npz -spikeinterface/extractors/tests/*.npy -spikeinterface/extractors/tests/extractor_testing_files/* - -spikeinterface/toolkit/*/tests/*/*.json -spikeinterface/toolkit/*/tests/*/*.raw -spikeinterface/toolkit/*/tests/*/*.npy -spikeinterface/toolkit/*/tests/*/*.npz -spikeinterface/toolkit/*/tests/*/*/*.json -spikeinterface/toolkit/*/tests/*/*/*.raw -spikeinterface/toolkit/*/tests/*/*/*.npy -spikeinterface/toolkit/*/tests/*/*/*.npz - -spikeinterface/toolkit/*/tests/*_output/* - -spikeinterface/exporters/tests/*/* - -spikeinterface/sorters/tests/*/* - - spikeinterface/widgets/tests/mearec_test/* -examples/modules_gallery/**/*.raw -examples/modules_gallery/**/*.npy -examples/modules_gallery/**/*.json -examples/modules_gallery/**/*.pkl -examples/modules_gallery/**/*.npz -examples/modules_gallery/**/*.csv -examples/modules_gallery/**/*.zarr - - +# Vscode .vscode/* # MauroToro: My absolute mess of envs @@ -107,21 +63,6 @@ coverage.xml .hypothesis/ .pytest_cache/ -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy # PyBuilder target/ @@ -135,11 +76,7 @@ target/ # pyenv .python-version -# celery beat schedule file -celerybeat-schedule -# SageMath parsed files -*.sage.py # Environments .env @@ -195,6 +132,14 @@ examples/modules/comparison/a_study_folder/* examples/modules/toolkit/phy/* examples/modules/toolkit/tmp_* +examples/modules_gallery/**/*.raw +examples/modules_gallery/**/*.npy +examples/modules_gallery/**/*.json +examples/modules_gallery/**/*.pkl +examples/modules_gallery/**/*.npz +examples/modules_gallery/**/*.csv +examples/modules_gallery/**/*.zarr + # Files and folders generated during tests test_folder/ From 697006394f32a14051e017a5110c14d0cb3c534f Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Tue, 2 Jul 2024 17:27:25 -0600 Subject: [PATCH 68/81] add streaming extractor tests to main script --- .github/determine_testing_environment.py | 11 ++++- .github/workflows/all-tests.yml | 7 +++ .../workflows/streaming-extractor-test.yml | 49 ------------------- conftest.py | 12 ----- .../extractors/iblextractors.py | 2 +- 5 files changed, 18 insertions(+), 63 deletions(-) delete mode 100644 .github/workflows/streaming-extractor-test.yml diff --git a/.github/determine_testing_environment.py b/.github/determine_testing_environment.py index 0c0c5ef95b..e392895aa4 100644 --- a/.github/determine_testing_environment.py +++ b/.github/determine_testing_environment.py @@ -36,13 +36,18 @@ file_is_in_src = changed_file.parts[0] == "src" - if changed_file.name == "pyproject.toml": pyproject_toml_changed = True elif changed_file.name == "neobaseextractor.py": neobaseextractor_changed = True + extractors_changed = True elif changed_file.name == "plexon2.py": plexon2_changed = True + elif changed_file.filename == "nwbextractors.py": + stream_extractors_changed = True + extractors_changed = True + elif changed_file.filename == "iblstreamingrecording.py": + stream_extractors_changed = True elif "core" in changed_file.parts: core_changed = True elif "extractors" in changed_file.parts: @@ -90,8 +95,11 @@ run_sorters_test = run_everything or sorters_changed run_internal_sorters_test = run_everything or run_sortingcomponents_tests or sorters_internal_changed +run_streaming_extractors_test = stream_extractors_changed + install_plexon_dependencies = plexon2_changed + environment_varaiables_to_add = { "RUN_EXTRACTORS_TESTS": run_extractor_tests, "RUN_PREPROCESSING_TESTS": run_preprocessing_tests, @@ -106,6 +114,7 @@ "RUN_SORTERS_TESTS": run_sorters_test, "RUN_INTERNAL_SORTERS_TESTS": run_internal_sorters_test, "INSTALL_PLEXON_DEPENDENCIES": install_plexon_dependencies, + "RUN_STREAMING_EXTRACTORS_TESTS": run_streaming_extractors_test, } # Write the conditions to the GITHUB_ENV file diff --git a/.github/workflows/all-tests.yml b/.github/workflows/all-tests.yml index 8dfea50faf..b44c56fbae 100644 --- a/.github/workflows/all-tests.yml +++ b/.github/workflows/all-tests.yml @@ -136,6 +136,13 @@ jobs: pip install -e .[extractors,streaming_extractors,test_extractors] ./.github/run_tests.sh "extractors and not streaming_extractors" --no-virtual-env + - name: Test streaming extracotors + shell: bash + if: env.RUN_STREAMING_EXTRACTORS_TESTS + run: | + pip install -e .[streaming_extractors,test_extractors] + ./.github/run_tests.sh "streaming_extractors" --no-virtual-env + - name: Test preprocessing shell: bash if: env.RUN_PREPROCESSING_TESTS == 'true' diff --git a/.github/workflows/streaming-extractor-test.yml b/.github/workflows/streaming-extractor-test.yml deleted file mode 100644 index 0cb88c3077..0000000000 --- a/.github/workflows/streaming-extractor-test.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Test streaming extractors - -on: - pull_request: - types: [synchronize, opened, reopened] - branches: - - main - -concurrency: # Cancel previous workflows on the same pull request - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - test-streaming-extractors: - name: Testing using ${{ matrix.os }} with ${{ matrix.python-version }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: ["ubuntu-latest"] - python-version: ["3.10"] - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - uses: s-weigand/setup-conda@v1 - with: - update-conda: true - python-version: ${{ matrix.python-version }} - conda-channels: conda-forge - - name: Get changed files - id: changed-files - uses: tj-actions/changed-files@v41 - - name: Module changes - id: modules-changed - run: | - for file in ${{ steps.changed-files.outputs.all_changed_files }}; do - if [[ $file == *"/nwbextractors.py" || $file == *"/iblstreamingrecording.py"* ]]; then - echo "Streaming files changed changed" - echo "STREAMING_CHANGED=true" >> $GITHUB_OUTPUT - fi - done - - name: Install package and streaming extractor dependencies - if: ${{ steps.modules-changed.outputs.STREAMING_CHANGED == 'true' }} - run: pip install -e .[test_core,streaming_extractors] - - name: run tests - if: steps.modules-changed.outputs.STREAMING_CHANGED == 'true' - run: pytest -m "streaming_extractors" -vv -ra diff --git a/conftest.py b/conftest.py index c4bac6628a..ce5e07b47b 100644 --- a/conftest.py +++ b/conftest.py @@ -1,19 +1,7 @@ import pytest -import shutil -import os from pathlib import Path -ON_GITHUB = bool(os.getenv('GITHUB_ACTIONS')) - - -# define marks -mark_names = ["core", "extractors", "preprocessing", "postprocessing", - "sorters_external", "sorters_internal", "sorters", - "qualitymetrics", "comparison", "curation", - "widgets", "exporters", "sortingcomponents", "generation"] - - @pytest.fixture(scope="module") def create_cache_folder(tmp_path_factory): cache_folder = tmp_path_factory.mktemp("cache_folder") diff --git a/src/spikeinterface/extractors/iblextractors.py b/src/spikeinterface/extractors/iblextractors.py index 27bb95854f..24dc96b10c 100644 --- a/src/spikeinterface/extractors/iblextractors.py +++ b/src/spikeinterface/extractors/iblextractors.py @@ -309,7 +309,7 @@ class IblSortingExtractor(BaseSorting): name = "ibl" installation_mesg = "IBL extractors require ibllib as a dependency." " To install, run: \n\n pip install ibllib\n\n" - def __init__(self, pid, good_clusters_only=False, load_unit_properties=True, one=None): + def __init__(self, pid: str, good_clusters_only: bool = False, load_unit_properties: bool = True, one=None): try: from one.api import ONE from brainbox.io.one import SpikeSortingLoader From 0dc4faf022d5e8740583fe8895da56f476aa92bc Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Tue, 2 Jul 2024 17:31:20 -0600 Subject: [PATCH 69/81] wrong use of pathlib --- .github/determine_testing_environment.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/determine_testing_environment.py b/.github/determine_testing_environment.py index e392895aa4..0adb2d4b52 100644 --- a/.github/determine_testing_environment.py +++ b/.github/determine_testing_environment.py @@ -43,10 +43,10 @@ extractors_changed = True elif changed_file.name == "plexon2.py": plexon2_changed = True - elif changed_file.filename == "nwbextractors.py": + elif changed_file.name == "nwbextractors.py": stream_extractors_changed = True extractors_changed = True - elif changed_file.filename == "iblstreamingrecording.py": + elif changed_file.name == "iblstreamingrecording.py": stream_extractors_changed = True elif "core" in changed_file.parts: core_changed = True From 578a7de1077bf5a80ddb8cfe1aa2b75c18101a29 Mon Sep 17 00:00:00 2001 From: Heberto Mayorquin Date: Tue, 2 Jul 2024 17:39:00 -0600 Subject: [PATCH 70/81] another correction --- .github/determine_testing_environment.py | 5 +++-- .github/workflows/all-tests.yml | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/determine_testing_environment.py b/.github/determine_testing_environment.py index 0adb2d4b52..95ad0afc49 100644 --- a/.github/determine_testing_environment.py +++ b/.github/determine_testing_environment.py @@ -30,6 +30,7 @@ exporters_changed = False sortingcomponents_changed = False generation_changed = False +stream_extractors_changed = False for changed_file in changed_files_in_the_pull_request_paths: @@ -44,9 +45,9 @@ elif changed_file.name == "plexon2.py": plexon2_changed = True elif changed_file.name == "nwbextractors.py": + extractors_changed = True # There are NWB tests that are not streaming stream_extractors_changed = True - extractors_changed = True - elif changed_file.name == "iblstreamingrecording.py": + elif changed_file.name == "iblextractors.py": stream_extractors_changed = True elif "core" in changed_file.parts: core_changed = True diff --git a/.github/workflows/all-tests.yml b/.github/workflows/all-tests.yml index b44c56fbae..855fd072de 100644 --- a/.github/workflows/all-tests.yml +++ b/.github/workflows/all-tests.yml @@ -68,6 +68,7 @@ jobs: echo "RUN_SORTERS_TESTS=${RUN_SORTERS_TESTS}" echo "RUN_INTERNAL_SORTERS_TESTS=${RUN_INTERNAL_SORTERS_TESTS}" echo "INSTALL_PLEXON_DEPENDENCIES=${INSTALL_PLEXON_DEPENDENCIES}" + echo "RUN_STREAMING_EXTRACTORS_TESTS=${RUN_STREAMING_EXTRACTORS_TESTS}" - name: Install packages run: | From aa314cdba68d583a4bc551b3e957efd809d0c919 Mon Sep 17 00:00:00 2001 From: Garcia Samuel Date: Wed, 3 Jul 2024 10:50:14 +0200 Subject: [PATCH 71/81] not use unit_index Co-authored-by: Alessio Buccino --- src/spikeinterface/qualitymetrics/misc_metrics.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/spikeinterface/qualitymetrics/misc_metrics.py b/src/spikeinterface/qualitymetrics/misc_metrics.py index 04c604edcb..a7d51ad330 100644 --- a/src/spikeinterface/qualitymetrics/misc_metrics.py +++ b/src/spikeinterface/qualitymetrics/misc_metrics.py @@ -1085,10 +1085,10 @@ def compute_drift_metrics( spikes_in_bin = spikes_in_segment[i0:i1] spike_locations_in_bin = spike_locations_in_segment[i0:i1][direction] - for unit_index, unit_id in enumerate(unit_ids): + for i, unit_id in enumerate(unit_ids): mask = spikes_in_bin["unit_index"] == sorting.id_to_index(unit_id) if np.sum(mask) >= min_spikes_per_interval: - median_positions[unit_index, bin_index] = np.median(spike_locations_in_bin[mask]) + median_positions[i, bin_index] = np.median(spike_locations_in_bin[mask]) if median_position_segments is None: median_position_segments = median_positions else: From 26c84ea0f58c7002987403e95ac8ad81b4b287f8 Mon Sep 17 00:00:00 2001 From: Pierre Yger Date: Wed, 3 Jul 2024 10:58:11 +0200 Subject: [PATCH 72/81] get_spike_prototype can have NaN sometimes (#2980) avoid get_spike_prototype can have NaN sometimes with margin in select_peaks --- .../sorters/internal/simplesorter.py | 5 +++- .../sortingcomponents/clustering/circus.py | 2 +- .../sortingcomponents/clustering/tdc.py | 5 +++- .../sortingcomponents/peak_selection.py | 26 ++++++++++++++++++- .../tests/test_peak_selection.py | 5 ++++ src/spikeinterface/sortingcomponents/tools.py | 16 ++++++------ 6 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/spikeinterface/sorters/internal/simplesorter.py b/src/spikeinterface/sorters/internal/simplesorter.py index 199352ab73..0f44e4079a 100644 --- a/src/spikeinterface/sorters/internal/simplesorter.py +++ b/src/spikeinterface/sorters/internal/simplesorter.py @@ -112,9 +112,12 @@ def _run_from_folder(cls, sorter_output_folder, params, verbose): ms_before = params["waveforms"]["ms_before"] ms_after = params["waveforms"]["ms_after"] + nbefore = int(ms_before * sampling_frequency / 1000.0) + nafter = int(ms_after * sampling_frequency / 1000.0) # SVD for time compression - few_peaks = select_peaks(peaks, method="uniform", n_peaks=5000) + + few_peaks = select_peaks(peaks, recording=recording, method="uniform", n_peaks=5000, margin=(nbefore, nafter)) few_wfs = extract_waveform_at_max_channel( recording, few_peaks, ms_before=ms_before, ms_after=ms_after, **job_kwargs ) diff --git a/src/spikeinterface/sortingcomponents/clustering/circus.py b/src/spikeinterface/sortingcomponents/clustering/circus.py index 65a89702c7..2bacf36ac9 100644 --- a/src/spikeinterface/sortingcomponents/clustering/circus.py +++ b/src/spikeinterface/sortingcomponents/clustering/circus.py @@ -90,7 +90,7 @@ def main_function(cls, recording, peaks, params): tmp_folder.mkdir(parents=True, exist_ok=True) # SVD for time compression - few_peaks = select_peaks(peaks, method="uniform", n_peaks=10000) + few_peaks = select_peaks(peaks, recording=recording, method="uniform", n_peaks=10000, margin=(nbefore, nafter)) few_wfs = extract_waveform_at_max_channel( recording, few_peaks, ms_before=ms_before, ms_after=ms_after, **params["job_kwargs"] ) diff --git a/src/spikeinterface/sortingcomponents/clustering/tdc.py b/src/spikeinterface/sortingcomponents/clustering/tdc.py index 46a9f1d18a..13af5b0fab 100644 --- a/src/spikeinterface/sortingcomponents/clustering/tdc.py +++ b/src/spikeinterface/sortingcomponents/clustering/tdc.py @@ -73,8 +73,11 @@ def main_function(cls, recording, peaks, params): ms_before = params["waveforms"]["ms_before"] ms_after = params["waveforms"]["ms_after"] + nbefore = int(ms_before * sampling_frequency / 1000.0) + nafter = int(ms_after * sampling_frequency / 1000.0) + # SVD for time compression - few_peaks = select_peaks(peaks, method="uniform", n_peaks=5000) + few_peaks = select_peaks(peaks, recording=recording, method="uniform", n_peaks=5000, margin=(nbefore, nafter)) few_wfs = extract_waveform_at_max_channel( recording, few_peaks, ms_before=ms_before, ms_after=ms_after, **job_kwargs ) diff --git a/src/spikeinterface/sortingcomponents/peak_selection.py b/src/spikeinterface/sortingcomponents/peak_selection.py index 397f59dbd9..1ccfbc4d22 100644 --- a/src/spikeinterface/sortingcomponents/peak_selection.py +++ b/src/spikeinterface/sortingcomponents/peak_selection.py @@ -6,7 +6,9 @@ import numpy as np -def select_peaks(peaks, method="uniform", seed=None, return_indices=False, **method_kwargs): +def select_peaks( + peaks, recording=None, method="uniform", seed=None, return_indices=False, margin=None, **method_kwargs +): """ Method to select a subset of peaks from a set of peaks. Usually use for reducing computational foorptint of downstream methods. @@ -28,6 +30,9 @@ def select_peaks(peaks, method="uniform", seed=None, return_indices=False, **met The seed for random generations return_indices: bool If True, return the indices of selection such that selected_peaks = peaks[selected_indices] + margin : Margin in timesteps. default: None. Otherwise should be a tuple (nbefore, nafter) + preventing peaks to be selected at the borders of the segments. A recording should be provided to get the duration + of the segments method_kwargs: dict of kwargs method Keyword arguments for the chosen method: @@ -66,8 +71,27 @@ def select_peaks(peaks, method="uniform", seed=None, return_indices=False, **met return_indices is True. """ + if margin is not None: + assert recording is not None, "recording should be provided if margin is not None" + selected_indices = select_peak_indices(peaks, method=method, seed=seed, **method_kwargs) selected_peaks = peaks[selected_indices] + + if margin is not None: + to_keep = np.zeros(len(selected_peaks), dtype=bool) + offset = 0 + for segment_index in range(recording.get_num_segments()): + duration = recording.get_num_frames(segment_index) + i0, i1 = np.searchsorted(selected_peaks["segment_index"], [segment_index, segment_index + 1]) + while selected_peaks["sample_index"][i0] <= margin[0] + offset: + i0 += 1 + while selected_peaks["sample_index"][i1 - 1] >= (duration - margin[1]) + offset: + i1 -= 1 + to_keep[i0:i1] = True + offset += duration + selected_indices = selected_indices[to_keep] + selected_peaks = peaks[selected_indices] + if return_indices: return selected_peaks, selected_indices else: diff --git a/src/spikeinterface/sortingcomponents/tests/test_peak_selection.py b/src/spikeinterface/sortingcomponents/tests/test_peak_selection.py index d133a0f9d2..83469a4017 100644 --- a/src/spikeinterface/sortingcomponents/tests/test_peak_selection.py +++ b/src/spikeinterface/sortingcomponents/tests/test_peak_selection.py @@ -45,6 +45,11 @@ def test_select_peaks(): selected_peaks.size <= n_peaks ), "selected_peaks is not the right size when return_indices=False, select_per_channel=False" + selected_peaks = select_peaks(peaks, recording=recording, method=method, margin=(10, 10), **select_kwargs) + assert ( + selected_peaks.size <= n_peaks + ), "selected_peaks is not the right size when return_indices=False, select_per_channel=False" + selected_peaks = select_peaks(peaks, method=method, select_per_channel=True, **select_kwargs) assert selected_peaks.size <= ( n_peaks * recording.get_num_channels() diff --git a/src/spikeinterface/sortingcomponents/tools.py b/src/spikeinterface/sortingcomponents/tools.py index 8ee36cc9e5..0872a6066c 100644 --- a/src/spikeinterface/sortingcomponents/tools.py +++ b/src/spikeinterface/sortingcomponents/tools.py @@ -70,18 +70,18 @@ def extract_waveform_at_max_channel(rec, peaks, ms_before=0.5, ms_after=1.5, **j def get_prototype_spike(recording, peaks, ms_before=0.5, ms_after=0.5, nb_peaks=1000, **job_kwargs): - if peaks.size > nb_peaks: - idx = np.sort(np.random.choice(len(peaks), nb_peaks, replace=False)) - some_peaks = peaks[idx] - else: - some_peaks = peaks - nbefore = int(ms_before * recording.sampling_frequency / 1000.0) + nafter = int(ms_after * recording.sampling_frequency / 1000.0) + + from spikeinterface.sortingcomponents.peak_selection import select_peaks + + few_peaks = select_peaks(peaks, recording=recording, method="uniform", n_peaks=nb_peaks, margin=(nbefore, nafter)) waveforms = extract_waveform_at_max_channel( - recording, some_peaks, ms_before=ms_before, ms_after=ms_after, **job_kwargs + recording, few_peaks, ms_before=ms_before, ms_after=ms_after, **job_kwargs ) - prototype = np.nanmedian(waveforms[:, :, 0] / (np.abs(waveforms[:, nbefore, 0][:, np.newaxis])), axis=0) + with np.errstate(divide="ignore", invalid="ignore"): + prototype = np.median(waveforms[:, :, 0] / (np.abs(waveforms[:, nbefore, 0][:, np.newaxis])), axis=0) return prototype From 42a6215483b6f1c3358f387fd262fff397235b7d Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Wed, 3 Jul 2024 11:15:55 +0200 Subject: [PATCH 73/81] Set compute_amplitudes/pc_features to False in tests --- .../exporters/tests/test_export_to_phy.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/spikeinterface/exporters/tests/test_export_to_phy.py b/src/spikeinterface/exporters/tests/test_export_to_phy.py index 0d4ab76c67..a54dbf7290 100644 --- a/src/spikeinterface/exporters/tests/test_export_to_phy.py +++ b/src/spikeinterface/exporters/tests/test_export_to_phy.py @@ -102,8 +102,8 @@ def test_export_to_phy_metrics(sorting_analyzer_sparse_for_export, create_cache_ export_to_phy( sorting_analyzer, output_folder, - compute_pc_features=True, - compute_amplitudes=True, + compute_pc_features=False, + compute_amplitudes=False, n_jobs=1, chunk_size=10000, progress_bar=True, @@ -119,8 +119,8 @@ def test_export_to_phy_metrics(sorting_analyzer_sparse_for_export, create_cache_ export_to_phy( sorting_analyzer, output_folder, - compute_pc_features=True, - compute_amplitudes=True, + compute_pc_features=False, + compute_amplitudes=False, n_jobs=1, chunk_size=10000, progress_bar=True, @@ -138,8 +138,8 @@ def test_export_to_phy_metrics(sorting_analyzer_sparse_for_export, create_cache_ export_to_phy( sorting_analyzer, output_folder, - compute_pc_features=True, - compute_amplitudes=True, + compute_pc_features=False, + compute_amplitudes=False, n_jobs=1, chunk_size=10000, progress_bar=True, From 21065a5cc22d55d25e2a1819b853c234b3396a66 Mon Sep 17 00:00:00 2001 From: Garcia Samuel Date: Wed, 3 Jul 2024 11:35:47 +0200 Subject: [PATCH 74/81] Update .gitignore --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index 7b85c7101c..9c4dda937c 100644 --- a/.gitignore +++ b/.gitignore @@ -129,8 +129,6 @@ examples/modules/extractors/firings_true.mda examples/modules/extractors/circular_layout.csv examples/modules/comparison/tmp_* examples/modules/comparison/a_study_folder/* -examples/modules/toolkit/phy/* -examples/modules/toolkit/tmp_* examples/modules_gallery/**/*.raw examples/modules_gallery/**/*.npy From 719643e119971b345be597af86c3fef24799b8c5 Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Wed, 3 Jul 2024 12:55:58 +0200 Subject: [PATCH 75/81] Fix select peaks --- .../sortingcomponents/peak_selection.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/spikeinterface/sortingcomponents/peak_selection.py b/src/spikeinterface/sortingcomponents/peak_selection.py index 1ccfbc4d22..fed026b6a7 100644 --- a/src/spikeinterface/sortingcomponents/peak_selection.py +++ b/src/spikeinterface/sortingcomponents/peak_selection.py @@ -76,19 +76,18 @@ def select_peaks( selected_indices = select_peak_indices(peaks, method=method, seed=seed, **method_kwargs) selected_peaks = peaks[selected_indices] + num_segments = len(np.unique(selected_peaks["segment_index"])) if margin is not None: to_keep = np.zeros(len(selected_peaks), dtype=bool) - offset = 0 - for segment_index in range(recording.get_num_segments()): - duration = recording.get_num_frames(segment_index) + for segment_index in range(num_segments): + num_samples_in_segment = recording.get_num_samples(segment_index) i0, i1 = np.searchsorted(selected_peaks["segment_index"], [segment_index, segment_index + 1]) - while selected_peaks["sample_index"][i0] <= margin[0] + offset: + while selected_peaks["sample_index"][i0] <= margin[0]: i0 += 1 - while selected_peaks["sample_index"][i1 - 1] >= (duration - margin[1]) + offset: + while selected_peaks["sample_index"][i1 - 1] >= (num_samples_in_segment - margin[1]): i1 -= 1 to_keep[i0:i1] = True - offset += duration selected_indices = selected_indices[to_keep] selected_peaks = peaks[selected_indices] @@ -284,7 +283,9 @@ def select_peak_indices(peaks, method, seed, **method_kwargs): ) selected_indices = np.concatenate(selected_indices) - selected_indices = selected_indices[np.argsort(peaks[selected_indices]["sample_index"])] + selected_indices = selected_indices[ + np.lexsort((peaks[selected_indices]["sample_index"], peaks[selected_indices]["segment_index"])) + ] return selected_indices From aac7a4b1ceb510da2f4f2af4f755ad91d0f8a0f2 Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Thu, 4 Jul 2024 15:12:59 +0200 Subject: [PATCH 76/81] add test_extractors to full test with codecov --- .github/actions/build-test-environment/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build-test-environment/action.yml b/.github/actions/build-test-environment/action.yml index 53fcd37f45..723e8a702f 100644 --- a/.github/actions/build-test-environment/action.yml +++ b/.github/actions/build-test-environment/action.yml @@ -21,7 +21,7 @@ runs: python -m pip install -U pip # Official recommended way source ${{ github.workspace }}/test_env/bin/activate pip install tabulate # This produces summaries at the end - pip install -e .[test,extractors,streaming_extractors,full] + pip install -e .[test,extractors,streaming_extractors,test_extractors,full] shell: bash - name: Force installation of latest dev from key-packages when running dev (not release) run: | From de3153179bb385a0a40cec4b2a983fb34da6f3ec Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Thu, 4 Jul 2024 17:49:31 +0200 Subject: [PATCH 77/81] analyse -> analyze neuropixels docs --- ...se_neuropixels.rst => analyze_neuropixels.rst} | 14 +++++++------- .../analyze_neuropixels_13_0.png} | Bin .../analyze_neuropixels_14_1.png} | Bin .../analyze_neuropixels_21_1.png} | Bin .../analyze_neuropixels_26_1.png} | Bin .../analyze_neuropixels_27_1.png} | Bin .../analyze_neuropixels_8_1.png} | Bin 7 files changed, 7 insertions(+), 7 deletions(-) rename doc/how_to/{analyse_neuropixels.rst => analyze_neuropixels.rst} (98%) rename doc/how_to/{analyse_neuropixels_files/analyse_neuropixels_13_0.png => analyze_neuropixels_files/analyze_neuropixels_13_0.png} (100%) rename doc/how_to/{analyse_neuropixels_files/analyse_neuropixels_14_1.png => analyze_neuropixels_files/analyze_neuropixels_14_1.png} (100%) rename doc/how_to/{analyse_neuropixels_files/analyse_neuropixels_21_1.png => analyze_neuropixels_files/analyze_neuropixels_21_1.png} (100%) rename doc/how_to/{analyse_neuropixels_files/analyse_neuropixels_26_1.png => analyze_neuropixels_files/analyze_neuropixels_26_1.png} (100%) rename doc/how_to/{analyse_neuropixels_files/analyse_neuropixels_27_1.png => analyze_neuropixels_files/analyze_neuropixels_27_1.png} (100%) rename doc/how_to/{analyse_neuropixels_files/analyse_neuropixels_8_1.png => analyze_neuropixels_files/analyze_neuropixels_8_1.png} (100%) diff --git a/doc/how_to/analyse_neuropixels.rst b/doc/how_to/analyze_neuropixels.rst similarity index 98% rename from doc/how_to/analyse_neuropixels.rst rename to doc/how_to/analyze_neuropixels.rst index 02e497b0fe..1fe741ea48 100644 --- a/doc/how_to/analyse_neuropixels.rst +++ b/doc/how_to/analyze_neuropixels.rst @@ -1,4 +1,4 @@ -Analyse Neuropixels datasets +Analyze Neuropixels datasets ============================ This example shows how to perform Neuropixels-specific analysis, @@ -218,7 +218,7 @@ We need to specify which one to read: -.. image:: analyse_neuropixels_files/analyse_neuropixels_8_1.png +.. image:: analyze_neuropixels_files/analyze_neuropixels_8_1.png Preprocess the recording @@ -286,7 +286,7 @@ is lazy, so you can change the previsous cell (parameters, step order, -.. image:: analyse_neuropixels_files/analyse_neuropixels_13_0.png +.. image:: analyze_neuropixels_files/analyze_neuropixels_13_0.png .. code:: ipython3 @@ -306,7 +306,7 @@ is lazy, so you can change the previsous cell (parameters, step order, -.. image:: analyse_neuropixels_files/analyse_neuropixels_14_1.png +.. image:: analyze_neuropixels_files/analyze_neuropixels_14_1.png Should we save the preprocessed data to a binary file? @@ -389,7 +389,7 @@ Noise levels can be estimated on the scaled traces or on the raw -.. image:: analyse_neuropixels_files/analyse_neuropixels_21_1.png +.. image:: analyze_neuropixels_files/analyze_neuropixels_21_1.png Detect and localize peaks @@ -480,7 +480,7 @@ documentation for motion estimation and correction for more details. -.. image:: analyse_neuropixels_files/analyse_neuropixels_26_1.png +.. image:: analyze_neuropixels_files/analyze_neuropixels_26_1.png .. code:: ipython3 @@ -502,7 +502,7 @@ documentation for motion estimation and correction for more details. -.. image:: analyse_neuropixels_files/analyse_neuropixels_27_1.png +.. image:: analyze_neuropixels_files/analyze_neuropixels_27_1.png Run a spike sorter diff --git a/doc/how_to/analyse_neuropixels_files/analyse_neuropixels_13_0.png b/doc/how_to/analyze_neuropixels_files/analyze_neuropixels_13_0.png similarity index 100% rename from doc/how_to/analyse_neuropixels_files/analyse_neuropixels_13_0.png rename to doc/how_to/analyze_neuropixels_files/analyze_neuropixels_13_0.png diff --git a/doc/how_to/analyse_neuropixels_files/analyse_neuropixels_14_1.png b/doc/how_to/analyze_neuropixels_files/analyze_neuropixels_14_1.png similarity index 100% rename from doc/how_to/analyse_neuropixels_files/analyse_neuropixels_14_1.png rename to doc/how_to/analyze_neuropixels_files/analyze_neuropixels_14_1.png diff --git a/doc/how_to/analyse_neuropixels_files/analyse_neuropixels_21_1.png b/doc/how_to/analyze_neuropixels_files/analyze_neuropixels_21_1.png similarity index 100% rename from doc/how_to/analyse_neuropixels_files/analyse_neuropixels_21_1.png rename to doc/how_to/analyze_neuropixels_files/analyze_neuropixels_21_1.png diff --git a/doc/how_to/analyse_neuropixels_files/analyse_neuropixels_26_1.png b/doc/how_to/analyze_neuropixels_files/analyze_neuropixels_26_1.png similarity index 100% rename from doc/how_to/analyse_neuropixels_files/analyse_neuropixels_26_1.png rename to doc/how_to/analyze_neuropixels_files/analyze_neuropixels_26_1.png diff --git a/doc/how_to/analyse_neuropixels_files/analyse_neuropixels_27_1.png b/doc/how_to/analyze_neuropixels_files/analyze_neuropixels_27_1.png similarity index 100% rename from doc/how_to/analyse_neuropixels_files/analyse_neuropixels_27_1.png rename to doc/how_to/analyze_neuropixels_files/analyze_neuropixels_27_1.png diff --git a/doc/how_to/analyse_neuropixels_files/analyse_neuropixels_8_1.png b/doc/how_to/analyze_neuropixels_files/analyze_neuropixels_8_1.png similarity index 100% rename from doc/how_to/analyse_neuropixels_files/analyse_neuropixels_8_1.png rename to doc/how_to/analyze_neuropixels_files/analyze_neuropixels_8_1.png From 6f462505ea7c6ec6d6e0f2a7bd4051fe554c097a Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Thu, 4 Jul 2024 17:54:53 +0200 Subject: [PATCH 78/81] and index.rst --- doc/how_to/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/how_to/index.rst b/doc/how_to/index.rst index 66dd9b417c..7127c4faf0 100644 --- a/doc/how_to/index.rst +++ b/doc/how_to/index.rst @@ -8,7 +8,7 @@ Guides on how to solve specific, short problems in SpikeInterface. Learn how to. viewers handle_drift - analyse_neuropixels + analyze_neuropixels load_matlab_data combine_recordings process_by_channel_group From 9703af1c94174d8f0159ed97b91b2c2d9fcd970a Mon Sep 17 00:00:00 2001 From: Pierre Yger Date: Fri, 5 Jul 2024 14:30:23 +0200 Subject: [PATCH 79/81] Regularize whitening (#2744) Regularize whitening --- .../preprocessing/tests/test_whiten.py | 12 +++-- src/spikeinterface/preprocessing/whiten.py | 48 ++++++++++++++++--- .../sorters/internal/spyking_circus2.py | 2 +- 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/src/spikeinterface/preprocessing/tests/test_whiten.py b/src/spikeinterface/preprocessing/tests/test_whiten.py index c3d1544869..04b731de4f 100644 --- a/src/spikeinterface/preprocessing/tests/test_whiten.py +++ b/src/spikeinterface/preprocessing/tests/test_whiten.py @@ -8,13 +8,13 @@ def test_whiten(create_cache_folder): cache_folder = create_cache_folder - rec = generate_recording(num_channels=4) + rec = generate_recording(num_channels=4, seed=2205) print(rec.get_channel_locations()) random_chunk_kwargs = {} - W, M = compute_whitening_matrix(rec, "global", random_chunk_kwargs, apply_mean=False, radius_um=None) - print(W) - print(M) + W1, M = compute_whitening_matrix(rec, "global", random_chunk_kwargs, apply_mean=False, radius_um=None) + # print(W) + # print(M) with pytest.raises(AssertionError): W, M = compute_whitening_matrix(rec, "local", random_chunk_kwargs, apply_mean=False, radius_um=None) @@ -41,6 +41,10 @@ def test_whiten(create_cache_folder): assert rec4.get_dtype() == "int16" assert rec4._kwargs["M"] is None + # test regularization : norm should be smaller + W2, M = compute_whitening_matrix(rec, "global", random_chunk_kwargs, apply_mean=False, regularize=True) + assert np.linalg.norm(W1) > np.linalg.norm(W2) + if __name__ == "__main__": test_whiten() diff --git a/src/spikeinterface/preprocessing/whiten.py b/src/spikeinterface/preprocessing/whiten.py index 874d4304e3..96cf5e028f 100644 --- a/src/spikeinterface/preprocessing/whiten.py +++ b/src/spikeinterface/preprocessing/whiten.py @@ -7,6 +7,7 @@ from ..core import get_random_data_chunks, get_channel_distances from .filter import fix_dtype +from ..core.globals import get_global_job_kwargs class WhitenRecording(BasePreprocessor): @@ -40,6 +41,12 @@ class WhitenRecording(BasePreprocessor): M : 1d np.array or None, default: None Pre-computed means. M can be None when previously computed with apply_mean=False + regularize : bool, default: False + Boolean to decide if we want to regularize the covariance matrix, using a chosen method + of sklearn, specified in regularize_kwargs. Default is GraphicalLassoCV + regularize_kwargs : {'method' : 'GraphicalLassoCV'} + Dictionary of the parameters that could be provided to the method of sklearn, if + the covariance matrix needs to be regularized. **random_chunk_kwargs : Keyword arguments for `spikeinterface.core.get_random_data_chunk()` function Returns @@ -55,6 +62,8 @@ def __init__( recording, dtype=None, apply_mean=False, + regularize=False, + regularize_kwargs=None, mode="global", radius_um=100.0, int_scale=None, @@ -75,7 +84,14 @@ def __init__( M = np.asarray(M) else: W, M = compute_whitening_matrix( - recording, mode, random_chunk_kwargs, apply_mean, radius_um=radius_um, eps=eps + recording, + mode, + random_chunk_kwargs, + apply_mean, + radius_um=radius_um, + eps=eps, + regularize=regularize, + regularize_kwargs=regularize_kwargs, ) BasePreprocessor.__init__(self, recording, dtype=dtype_) @@ -90,6 +106,8 @@ def __init__( mode=mode, radius_um=radius_um, apply_mean=apply_mean, + regularize=regularize, + regularize_kwargs=regularize_kwargs, int_scale=float(int_scale) if int_scale is not None else None, M=M.tolist() if M is not None else None, W=W.tolist(), @@ -129,7 +147,9 @@ def get_traces(self, start_frame, end_frame, channel_indices): whiten = define_function_from_class(source_class=WhitenRecording, name="whiten") -def compute_whitening_matrix(recording, mode, random_chunk_kwargs, apply_mean, radius_um=None, eps=None): +def compute_whitening_matrix( + recording, mode, random_chunk_kwargs, apply_mean, radius_um=None, eps=None, regularize=False, regularize_kwargs=None +): """ Compute whitening matrix @@ -152,7 +172,12 @@ def compute_whitening_matrix(recording, mode, random_chunk_kwargs, apply_mean, r eps : float or None, default: None Small epsilon to regularize SVD. If None, the default is set to 1e-8, but if the data is float type and scaled down to very small values, eps is automatically set to a small fraction (1e-3) of the median of the squared data. - + regularize : bool, default: False + Boolean to decide if we want to regularize the covariance matrix, using a chosen method + of sklearn, specified in regularize_kwargs. Default is GraphicalLassoCV + regularize_kwargs : {'method' : 'GraphicalLassoCV'} + Dictionary of the parameters that could be provided to the method of sklearn, if + the covariance matrix needs to be regularized. Returns ------- W : 2D array @@ -162,7 +187,8 @@ def compute_whitening_matrix(recording, mode, random_chunk_kwargs, apply_mean, r """ random_data = get_random_data_chunks(recording, concatenated=True, return_scaled=False, **random_chunk_kwargs) - random_data = random_data.astype("float32") + + regularize_kwargs = regularize_kwargs if regularize_kwargs is not None else {"method": "GraphicalLassoCV"} if apply_mean: M = np.mean(random_data, axis=0) @@ -172,8 +198,18 @@ def compute_whitening_matrix(recording, mode, random_chunk_kwargs, apply_mean, r M = None data = random_data - cov = data.T @ data - cov = cov / data.shape[0] + if not regularize: + cov = data.T @ data + cov = cov / data.shape[0] + else: + import sklearn.covariance + + method = regularize_kwargs.pop("method") + regularize_kwargs["assume_centered"] = True + estimator_class = getattr(sklearn.covariance, method) + estimator = estimator_class(**regularize_kwargs) + estimator.fit(data) + cov = estimator.covariance_ # Here we determine eps used below to avoid division by zero. # Typically we can assume that data is either unscaled integers or in units of diff --git a/src/spikeinterface/sorters/internal/spyking_circus2.py b/src/spikeinterface/sorters/internal/spyking_circus2.py index 45cc93d0b6..be75877f02 100644 --- a/src/spikeinterface/sorters/internal/spyking_circus2.py +++ b/src/spikeinterface/sorters/internal/spyking_circus2.py @@ -147,7 +147,7 @@ def _run_from_folder(cls, sorter_output_folder, params, verbose): ## We need to whiten before the template matching step, to boost the results # TODO add , regularize=True chen ready - recording_w = whiten(recording_f, mode="local", radius_um=radius_um, dtype="float32") + recording_w = whiten(recording_f, mode="local", radius_um=radius_um, dtype="float32", regularize=True) noise_levels = get_noise_levels(recording_w, return_scaled=False) From f8a43318bdac09535535cf600c6231707f4dd0a3 Mon Sep 17 00:00:00 2001 From: Pierre Yger Date: Fri, 5 Jul 2024 14:30:54 +0200 Subject: [PATCH 80/81] Benchmarks components: plotting utils (#2959) Benchmarks components: plotting utils --- .../comparison/groundtruthstudy.py | 20 +++- .../benchmark/benchmark_clustering.py | 98 +++++++++++-------- .../benchmark/benchmark_matching.py | 38 ++++--- .../benchmark/benchmark_peak_detection.py | 2 + .../benchmark/benchmark_tools.py | 4 +- src/spikeinterface/sortingcomponents/tools.py | 11 +++ src/spikeinterface/widgets/gtstudy.py | 14 +-- 7 files changed, 120 insertions(+), 67 deletions(-) diff --git a/src/spikeinterface/comparison/groundtruthstudy.py b/src/spikeinterface/comparison/groundtruthstudy.py index 6682252349..ba7268b4f0 100644 --- a/src/spikeinterface/comparison/groundtruthstudy.py +++ b/src/spikeinterface/comparison/groundtruthstudy.py @@ -9,9 +9,6 @@ import numpy as np from spikeinterface.core import load_extractor, create_sorting_analyzer, load_sorting_analyzer -from spikeinterface.core.core_tools import SIJsonEncoder -from spikeinterface.core.job_tools import split_job_kwargs - from spikeinterface.sorters import run_sorter_jobs, read_sorter_folder from spikeinterface.qualitymetrics import compute_quality_metrics @@ -54,6 +51,7 @@ def __init__(self, study_folder): self.cases = {} self.sortings = {} self.comparisons = {} + self.colors = None self.scan_folder() @@ -175,6 +173,22 @@ def remove_sorting(self, key): if f.exists(): f.unlink() + def set_colors(self, colors=None, map_name="tab20"): + from spikeinterface.widgets import get_some_colors + + if colors is None: + case_keys = list(self.cases.keys()) + self.colors = get_some_colors( + case_keys, map_name=map_name, color_engine="matplotlib", shuffle=False, margin=0 + ) + else: + self.colors = colors + + def get_colors(self): + if self.colors is None: + self.set_colors() + return self.colors + def run_sorters(self, case_keys=None, engine="loop", engine_kwargs={}, keep=True, verbose=False): if case_keys is None: case_keys = self.cases.keys() diff --git a/src/spikeinterface/sortingcomponents/benchmark/benchmark_clustering.py b/src/spikeinterface/sortingcomponents/benchmark/benchmark_clustering.py index 2da950ceda..92fcda35d9 100644 --- a/src/spikeinterface/sortingcomponents/benchmark/benchmark_clustering.py +++ b/src/spikeinterface/sortingcomponents/benchmark/benchmark_clustering.py @@ -185,11 +185,11 @@ def plot_performances_vs_snr(self, case_keys=None, figsize=(15, 15)): case_keys = list(self.cases.keys()) import pylab as plt - fig, axs = plt.subplots(ncols=1, nrows=3, figsize=figsize) + fig, axes = plt.subplots(ncols=1, nrows=3, figsize=figsize) for count, k in enumerate(("accuracy", "recall", "precision")): - ax = axs[count] + ax = axes[count] for key in case_keys: label = self.cases[key]["label"] @@ -211,7 +211,7 @@ def plot_error_metrics(self, metric="cosine", case_keys=None, figsize=(15, 5)): case_keys = list(self.cases.keys()) import pylab as plt - fig, axs = plt.subplots(ncols=len(case_keys), nrows=1, figsize=figsize, squeeze=False) + fig, axes = plt.subplots(ncols=len(case_keys), nrows=1, figsize=figsize, squeeze=False) for count, key in enumerate(case_keys): @@ -234,21 +234,25 @@ def plot_error_metrics(self, metric="cosine", case_keys=None, figsize=(15, 5)): else: distances = sklearn.metrics.pairwise_distances(a, b, metric) - im = axs[0, count].imshow(distances, aspect="auto") - axs[0, count].set_title(metric) - fig.colorbar(im, ax=axs[0, count]) + im = axes[0, count].imshow(distances, aspect="auto") + axes[0, count].set_title(metric) + fig.colorbar(im, ax=axes[0, count]) label = self.cases[key]["label"] - axs[0, count].set_title(label) + axes[0, count].set_title(label) return fig - def plot_metrics_vs_snr(self, metric="agreement", case_keys=None, figsize=(15, 5)): + def plot_metrics_vs_snr(self, metric="agreement", case_keys=None, figsize=(15, 5), axes=None): if case_keys is None: case_keys = list(self.cases.keys()) import pylab as plt - fig, axs = plt.subplots(ncols=len(case_keys), nrows=1, figsize=figsize, squeeze=False) + if axes is None: + fig, axes = plt.subplots(ncols=len(case_keys), nrows=1, figsize=figsize, squeeze=False) + axes = axes.flatten() + else: + fig = None for count, key in enumerate(case_keys): @@ -287,13 +291,13 @@ def plot_metrics_vs_snr(self, metric="agreement", case_keys=None, figsize=(15, 5 elif metric == "agreement": for found, real in zip(matched_ids2[mask], unit_ids1[mask]): to_plot += [scores.at[real, found]] - axs[0, count].plot(snr_matched, to_plot, ".", label="matched") - axs[0, count].plot(snr_missed, np.zeros(len(snr_missed)), ".", c="r", label="missed") - axs[0, count].set_xlabel("snr") - axs[0, count].set_ylabel(metric) + axes[count].plot(snr_matched, to_plot, ".", label="matched") + axes[count].plot(snr_missed, np.zeros(len(snr_missed)), ".", c="r", label="missed") + axes[count].set_xlabel("snr") + axes[count].set_ylabel(metric) label = self.cases[key]["label"] - axs[0, count].set_title(label) - axs[0, count].legend() + axes[count].set_title(label) + axes[count].legend() return fig @@ -303,7 +307,7 @@ def plot_metrics_vs_depth_and_snr(self, metric="agreement", case_keys=None, figs case_keys = list(self.cases.keys()) import pylab as plt - fig, axs = plt.subplots(ncols=len(case_keys), nrows=1, figsize=figsize, squeeze=False) + fig, axes = plt.subplots(ncols=len(case_keys), nrows=1, figsize=figsize, squeeze=False) for count, key in enumerate(case_keys): @@ -348,47 +352,61 @@ def plot_metrics_vs_depth_and_snr(self, metric="agreement", case_keys=None, figs elif metric == "agreement": for found, real in zip(matched_ids2[mask], unit_ids1[mask]): to_plot += [scores.at[real, found]] - axs[0, count].scatter(depth_matched, snr_matched, c=to_plot, label="matched") - axs[0, count].scatter(depth_missed, snr_missed, c=np.zeros(len(snr_missed)), label="missed") - axs[0, count].set_xlabel("depth") - axs[0, count].set_ylabel("snr") + elif metric in ["recall", "precision", "accuracy"]: + to_plot = result["gt_comparison"].get_performance()[metric].values + depth_matched = depth + snr_matched = metrics["snr"] + + im = axes[0, count].scatter(depth_matched, snr_matched, c=to_plot, label="matched") + im.set_clim(0, 1) + axes[0, count].scatter(depth_missed, snr_missed, c=np.zeros(len(snr_missed)), label="missed") + axes[0, count].set_xlabel("depth") + axes[0, count].set_ylabel("snr") label = self.cases[key]["label"] - axs[0, count].set_title(label) + axes[0, count].set_title(label) + if count > 0: + axes[0, count].set_ylabel("") + axes[0, count].set_yticks([], []) # axs[0, count].legend() + fig.subplots_adjust(right=0.85) + cbar_ax = fig.add_axes([0.9, 0.1, 0.025, 0.75]) + fig.colorbar(im, cax=cbar_ax, label=metric) + return fig - def plot_unit_losses(self, case_before, case_after, metric="agreement", figsize=None): - import pylab as plt + def plot_unit_losses(self, cases_before, cases_after, metric="agreement", figsize=None): - fig, axs = plt.subplots(ncols=1, nrows=3, figsize=figsize) + fig, axs = plt.subplots(ncols=len(cases_before), nrows=1, figsize=figsize) - for count, k in enumerate(("accuracy", "recall", "precision")): + for count, (case_before, case_after) in enumerate(zip(cases_before, cases_after)): ax = axs[count] - - # label = self.cases[case_after]["label"] - - # positions = self.get_result(case_before)["gt_comparison"].sorting1.get_property("gt_unit_locations") - dataset_key = self.cases[case_before]["dataset"] - rec, gt_sorting1 = self.datasets[dataset_key] + _, gt_sorting1 = self.datasets[dataset_key] positions = gt_sorting1.get_property("gt_unit_locations") analyzer = self.get_sorting_analyzer(case_before) metrics_before = analyzer.get_extension("quality_metrics").get_data() x = metrics_before["snr"].values - y_before = self.get_result(case_before)["gt_comparison"].get_performance()[k].values - y_after = self.get_result(case_after)["gt_comparison"].get_performance()[k].values - if count < 2: - ax.set_xticks([], []) - elif count == 2: - ax.set_xlabel("depth (um)") - im = ax.scatter(positions[:, 1], x, c=(y_after - y_before), marker=".", s=50, cmap="copper") - fig.colorbar(im, ax=ax) - ax.set_title(k) + y_before = self.get_result(case_before)["gt_comparison"].get_performance()[metric].values + y_after = self.get_result(case_after)["gt_comparison"].get_performance()[metric].values + ax.set_ylabel("depth (um)") ax.set_ylabel("snr") + if count > 0: + ax.set_ylabel("") + ax.set_yticks([], []) + im = ax.scatter(positions[:, 1], x, c=(y_after - y_before), cmap="coolwarm") + im.set_clim(-1, 1) + # fig.colorbar(im, ax=ax) + # ax.set_title(k) + + fig.subplots_adjust(right=0.85) + cbar_ax = fig.add_axes([0.9, 0.1, 0.025, 0.75]) + cbar = fig.colorbar(im, cax=cbar_ax, label=metric) + # cbar.set_clim(-1, 1) + return fig def plot_comparison_clustering( diff --git a/src/spikeinterface/sortingcomponents/benchmark/benchmark_matching.py b/src/spikeinterface/sortingcomponents/benchmark/benchmark_matching.py index cf91c8b873..ab1523d13a 100644 --- a/src/spikeinterface/sortingcomponents/benchmark/benchmark_matching.py +++ b/src/spikeinterface/sortingcomponents/benchmark/benchmark_matching.py @@ -11,6 +11,9 @@ import numpy as np from spikeinterface.sortingcomponents.benchmark.benchmark_tools import Benchmark, BenchmarkStudy from spikeinterface.core.basesorting import minimum_spike_dtype +from spikeinterface.sortingcomponents.tools import remove_empty_templates +from spikeinterface.core.recording_tools import get_noise_levels +from spikeinterface.core.sparsity import compute_sparsity class MatchingBenchmark(Benchmark): @@ -73,17 +76,15 @@ def plot_agreements(self, case_keys=None, figsize=None): ax.set_title(self.cases[key]["label"]) plot_agreement_matrix(self.get_result(key)["gt_comparison"], ax=ax) - return fig - - def plot_performances_vs_snr(self, case_keys=None, figsize=None): + def plot_performances_vs_snr(self, case_keys=None, figsize=None, metrics=["accuracy", "recall", "precision"]): if case_keys is None: case_keys = list(self.cases.keys()) - fig, axs = plt.subplots(ncols=1, nrows=3, figsize=figsize) + fig, axs = plt.subplots(ncols=1, nrows=len(metrics), figsize=figsize, squeeze=False) - for count, k in enumerate(("accuracy", "recall", "precision")): + for count, k in enumerate(metrics): - ax = axs[count] + ax = axs[count, 0] for key in case_keys: label = self.cases[key]["label"] @@ -223,13 +224,13 @@ def plot_unit_counts(self, case_keys=None, figsize=None): plot_study_unit_counts(self, case_keys, figsize=figsize) - def plot_unit_losses(self, before, after, figsize=None): + def plot_unit_losses(self, before, after, metric=["precision"], figsize=None): - fig, axs = plt.subplots(ncols=1, nrows=3, figsize=figsize) + fig, axs = plt.subplots(ncols=1, nrows=len(metric), figsize=figsize, squeeze=False) - for count, k in enumerate(("accuracy", "recall", "precision")): + for count, k in enumerate(metric): - ax = axs[count] + ax = axs[0, count] label = self.cases[after]["label"] @@ -241,15 +242,20 @@ def plot_unit_losses(self, before, after, figsize=None): y_before = self.get_result(before)["gt_comparison"].get_performance()[k].values y_after = self.get_result(after)["gt_comparison"].get_performance()[k].values - if count < 2: - ax.set_xticks([], []) - elif count == 2: - ax.set_xlabel("depth (um)") - im = ax.scatter(positions[:, 1], x, c=(y_after - y_before), marker=".", s=50, cmap="copper") - fig.colorbar(im, ax=ax) + # if count < 2: + # ax.set_xticks([], []) + # elif count == 2: + ax.set_xlabel("depth (um)") + im = ax.scatter(positions[:, 1], x, c=(y_after - y_before), cmap="coolwarm") + fig.colorbar(im, ax=ax, label=k) + im.set_clim(-1, 1) ax.set_title(k) ax.set_ylabel("snr") + # fig.subplots_adjust(right=0.85) + # cbar_ax = fig.add_axes([0.9, 0.1, 0.025, 0.75]) + # cbar = fig.colorbar(im, cax=cbar_ax, label=metric) + # if count == 2: # ax.legend() return fig diff --git a/src/spikeinterface/sortingcomponents/benchmark/benchmark_peak_detection.py b/src/spikeinterface/sortingcomponents/benchmark/benchmark_peak_detection.py index 062309b581..7d862343d2 100644 --- a/src/spikeinterface/sortingcomponents/benchmark/benchmark_peak_detection.py +++ b/src/spikeinterface/sortingcomponents/benchmark/benchmark_peak_detection.py @@ -196,6 +196,8 @@ def plot_detected_amplitudes(self, case_keys=None, figsize=(15, 5), detect_thres abs_threshold = -detect_threshold * noise_levels ax.plot([abs_threshold, abs_threshold], [ymin, ymax], "k--") + return fig + def plot_deltas_per_cells(self, case_keys=None, figsize=(15, 5)): if case_keys is None: diff --git a/src/spikeinterface/sortingcomponents/benchmark/benchmark_tools.py b/src/spikeinterface/sortingcomponents/benchmark/benchmark_tools.py index e9f128993d..aaa67e3aeb 100644 --- a/src/spikeinterface/sortingcomponents/benchmark/benchmark_tools.py +++ b/src/spikeinterface/sortingcomponents/benchmark/benchmark_tools.py @@ -10,9 +10,11 @@ from spikeinterface.core import SortingAnalyzer -from spikeinterface import load_extractor, split_job_kwargs, create_sorting_analyzer, load_sorting_analyzer + +from spikeinterface import load_extractor, create_sorting_analyzer, load_sorting_analyzer from spikeinterface.widgets import get_some_colors + import pickle _key_separator = "_-°°-_" diff --git a/src/spikeinterface/sortingcomponents/tools.py b/src/spikeinterface/sortingcomponents/tools.py index 0872a6066c..facefac4c5 100644 --- a/src/spikeinterface/sortingcomponents/tools.py +++ b/src/spikeinterface/sortingcomponents/tools.py @@ -140,3 +140,14 @@ def remove_empty_templates(templates): probe=templates.probe, is_scaled=templates.is_scaled, ) + + +def sigmoid(x, x0, k, b): + return (1 / (1 + np.exp(-k * (x - x0)))) + b + + +def fit_sigmoid(xdata, ydata, p0=None): + from scipy.optimize import curve_fit + + popt, pcov = curve_fit(sigmoid, xdata, ydata, p0) + return popt diff --git a/src/spikeinterface/widgets/gtstudy.py b/src/spikeinterface/widgets/gtstudy.py index a2c366851b..85043d0d12 100644 --- a/src/spikeinterface/widgets/gtstudy.py +++ b/src/spikeinterface/widgets/gtstudy.py @@ -30,9 +30,7 @@ def __init__( case_keys = list(study.cases.keys()) plot_data = dict( - study=study, - run_times=study.get_run_times(case_keys), - case_keys=case_keys, + study=study, run_times=study.get_run_times(case_keys), case_keys=case_keys, colors=study.get_colors() ) BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs) @@ -48,8 +46,8 @@ def plot_matplotlib(self, data_plot, **backend_kwargs): for i, key in enumerate(dp.case_keys): label = dp.study.cases[key]["label"] rt = dp.run_times.loc[key] - self.ax.bar(i, rt, width=0.8, label=label) - + self.ax.bar(i, rt, width=0.8, label=label, facecolor=dp.colors[key]) + self.ax.set_ylabel("run time (s)") self.ax.legend() @@ -167,6 +165,8 @@ def __init__( case_keys=case_keys, ) + self.colors = study.get_colors() + BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs) def plot_matplotlib(self, data_plot, **backend_kwargs): @@ -192,7 +192,7 @@ def plot_matplotlib(self, data_plot, **backend_kwargs): label = study.cases[key]["label"] val = perfs.xs(key).loc[:, performance_name].values val = np.sort(val)[::-1] - ax.plot(val, label=label) + ax.plot(val, label=label, c=self.colors[key]) ax.set_title(performance_name) if count == len(dp.performance_names) - 1: ax.legend(bbox_to_anchor=(0.05, 0.05), loc="lower left", framealpha=0.8) @@ -207,7 +207,7 @@ def plot_matplotlib(self, data_plot, **backend_kwargs): x = study.get_metrics(key).loc[:, metric_name].values y = perfs.xs(key).loc[:, performance_name].values label = study.cases[key]["label"] - ax.scatter(x, y, s=10, label=label) + ax.scatter(x, y, s=10, label=label, color=self.colors[key]) max_metric = max(max_metric, np.max(x)) ax.set_title(performance_name) ax.set_xlim(0, max_metric * 1.05) From 0422cfbab1692c57eea3743bdac7b88ee0d4a7dc Mon Sep 17 00:00:00 2001 From: Pierre Yger Date: Fri, 5 Jul 2024 14:31:18 +0200 Subject: [PATCH 81/81] Mcsh5 offsets and proper scaling in uV for return_scaled (#2988) Mcsh5 offsets and proper scaling in uV for return_scaled --- src/spikeinterface/extractors/mcsh5extractors.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/spikeinterface/extractors/mcsh5extractors.py b/src/spikeinterface/extractors/mcsh5extractors.py index f419b7e64d..9485536d97 100644 --- a/src/spikeinterface/extractors/mcsh5extractors.py +++ b/src/spikeinterface/extractors/mcsh5extractors.py @@ -61,6 +61,9 @@ def __init__(self, file_path, stream_id=0): # set gain self.set_channel_gains(mcs_info["gain"]) + # set offsets + self.set_channel_offsets(mcs_info["offset"]) + # set other properties self.set_property("electrode_labels", mcs_info["electrode_labels"]) @@ -100,7 +103,11 @@ def get_traces(self, start_frame=None, end_frame=None, channel_indices=None): def openMCSH5File(filename, stream_id): - """Open an MCS hdf5 file, read and return the recording info.""" + """Open an MCS hdf5 file, read and return the recording info. + Specs can be found online + https://www.multichannelsystems.com/downloads/documentation?page=3 + """ + import h5py rf = h5py.File(filename, "r") @@ -121,7 +128,8 @@ def openMCSH5File(filename, stream_id): Tick = info["Tick"][0] / 1e6 exponent = info["Exponent"][0] convFact = info["ConversionFactor"][0] - gain = convFact.astype(float) * (10.0**exponent) + gain_uV = 1e6 * (convFact.astype(float) * (10.0**exponent)) + offset_uV = -1e6 * (info["ADZero"].astype(float) * (10.0**exponent)) * gain_uV nRecCh, nFrames = data.shape channel_ids = [f"Ch{ch}" for ch in info["ChannelID"]] @@ -149,8 +157,9 @@ def openMCSH5File(filename, stream_id): "num_channels": nRecCh, "channel_ids": channel_ids, "electrode_labels": electrodeLabels, - "gain": gain, + "gain": gain_uV, "dtype": dtype, + "offset": offset_uV, } return mcs_info