From ccd587a4a580252a746e6064a84aae4987eaa602 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 18 Apr 2024 15:55:03 +0200 Subject: [PATCH 01/84] initial draft for caching action --- .github/workflows/cache_elephant_data.yml | 54 +++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 .github/workflows/cache_elephant_data.yml diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml new file mode 100644 index 000000000..c55307099 --- /dev/null +++ b/.github/workflows/cache_elephant_data.yml @@ -0,0 +1,54 @@ +name: Create caches for elephant_data + +on: + workflow_dispatch: # Workflow can be triggered manually via GH actions webinterface + push: # When something is pushed into master this checks if caches need to re-created + branches: + - master + schedule: + - cron: "0 12 * * *" # Daily at noon UTC + +jobs: + create-data-cache-if-missing: + name: Caching data env + runs-on: "macos-latest" + steps: + + - name: Get current hash (SHA) of the elephant_data repo + id: elephant-data + run: | + echo "dataset_hash=$(git ls-remote https://gin.g-node.org/NeuralEnsemble/elephant-data.git HEAD | cut -f1)" >> $GITHUB_OUTPUT + + - uses: actions/cache@v3 + # Loading cache of elephant-data + id: cache-datasets + with: + path: ~/elephant-data + key: ${{ runner.os }}-datasets-${{ steps.elephant-data.outputs.dataset_hash }} + + - name: Cache found? + run: echo "Cache-hit == ${{steps.cache-datasets.outputs.cache-hit == 'true'}}" + + - name: Installing gin + if: steps.cache-datasets.outputs.cache-hit != 'true' + run: | + git config --global user.email "elephant_ci@fake_mail.com" + git config --global user.name "elephant CI" + git config --global filter.annex.process "git-annex filter-process" # recommended for efficiency + + brew tap g-node/pkg + brew install g-node/pkg/gin-cli + + - name: Download dataset + if: steps.cache-datasets.outputs.cache-hit != 'true' + # Download repository and also fetch data + run: | + gin --version + + - name: Show size of the cache to assert data is downloaded + run: | + cd ~ + pwd + du -hs elephant-data + cd elephant-data + pwd \ No newline at end of file From ee366df7b17471e7c2eb53c0313243ae5923bf1d Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 18 Apr 2024 15:58:07 +0200 Subject: [PATCH 02/84] add trigger for workflow --- .github/workflows/cache_elephant_data.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index c55307099..c108f6076 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -8,6 +8,14 @@ on: schedule: - cron: "0 12 * * *" # Daily at noon UTC + pull_request: + branches: + - master + types: + - opened + - reopened + - synchronize + jobs: create-data-cache-if-missing: name: Caching data env From 20665d4b0c87c98a55f5b4b70b4bf852ee752fe1 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 18 Apr 2024 16:03:17 +0200 Subject: [PATCH 03/84] get content with gin --- .github/workflows/cache_elephant_data.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index c108f6076..acdeb2c65 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -52,6 +52,9 @@ jobs: # Download repository and also fetch data run: | gin --version + gin get NeuralEnsemble/elephant-data + cd ~/elephant-data + gin getc . - name: Show size of the cache to assert data is downloaded run: | From 532303939666e69e0143fbef4a43a87a6df5ef8e Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 18 Apr 2024 16:06:09 +0200 Subject: [PATCH 04/84] use git clone --- .github/workflows/cache_elephant_data.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index acdeb2c65..da7b6881d 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -52,10 +52,10 @@ jobs: # Download repository and also fetch data run: | gin --version - gin get NeuralEnsemble/elephant-data + git clone git@gin.g-node.org:/NeuralEnsemble/elephant-data.git cd ~/elephant-data gin getc . - + - name: Show size of the cache to assert data is downloaded run: | cd ~ From 9fa145c98967b94fe71c50b969692fd56dc71461 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 18 Apr 2024 16:08:10 +0200 Subject: [PATCH 05/84] use https --- .github/workflows/cache_elephant_data.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index da7b6881d..ff2c86785 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -25,7 +25,7 @@ jobs: - name: Get current hash (SHA) of the elephant_data repo id: elephant-data run: | - echo "dataset_hash=$(git ls-remote https://gin.g-node.org/NeuralEnsemble/elephant-data.git HEAD | cut -f1)" >> $GITHUB_OUTPUT + echo "dataset_hash=$(git ls-remote https://gin.g-node.org/NeuralEnsemble/elephant-data.git HEAD | cut -f1)" >> $GITHUB_OUTPUT - uses: actions/cache@v3 # Loading cache of elephant-data @@ -51,15 +51,15 @@ jobs: if: steps.cache-datasets.outputs.cache-hit != 'true' # Download repository and also fetch data run: | - gin --version - git clone git@gin.g-node.org:/NeuralEnsemble/elephant-data.git - cd ~/elephant-data - gin getc . + gin --version + git clone https://gin.g-node.org/NeuralEnsemble/elephant-data.git + cd ~/elephant-data + gin getc . - name: Show size of the cache to assert data is downloaded run: | - cd ~ - pwd - du -hs elephant-data - cd elephant-data - pwd \ No newline at end of file + cd ~ + pwd + du -hs elephant-data + cd elephant-data + pwd \ No newline at end of file From 2f4b8d0f44dfcd9ba6e74ac04b231c897b2b2d79 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 18 Apr 2024 16:55:13 +0200 Subject: [PATCH 06/84] add depth command to clone --- .github/workflows/cache_elephant_data.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index ff2c86785..75f3b3f37 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -52,9 +52,10 @@ jobs: # Download repository and also fetch data run: | gin --version - git clone https://gin.g-node.org/NeuralEnsemble/elephant-data.git - cd ~/elephant-data + git clone --depth 1 https://gin.g-node.org/NeuralEnsemble/elephant-data.git + cd elephant-data gin getc . + pwd - name: Show size of the cache to assert data is downloaded run: | @@ -62,4 +63,5 @@ jobs: pwd du -hs elephant-data cd elephant-data - pwd \ No newline at end of file + pwd + ls -lh \ No newline at end of file From e6a34fd6768ad52b6ab3474b87a62c46f7e8d175 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 18 Apr 2024 17:06:58 +0200 Subject: [PATCH 07/84] change path --- .github/workflows/cache_elephant_data.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index 75f3b3f37..0f6652fe4 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -48,6 +48,7 @@ jobs: brew install g-node/pkg/gin-cli - name: Download dataset + id: download-dataset if: steps.cache-datasets.outputs.cache-hit != 'true' # Download repository and also fetch data run: | @@ -55,13 +56,12 @@ jobs: git clone --depth 1 https://gin.g-node.org/NeuralEnsemble/elephant-data.git cd elephant-data gin getc . - pwd + echo "dataset-path =$(pwd)"" >> $GITHUB_OUTPUT - name: Show size of the cache to assert data is downloaded run: | - cd ~ pwd - du -hs elephant-data - cd elephant-data + du -hs ${{steps.download-dataset.outputs.dataset-path}} + cd ${{steps.download-dataset.outputs.dataset-path}} pwd ls -lh \ No newline at end of file From ded079354645eee8eedbc2ca3649740caa52097b Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 18 Apr 2024 17:18:46 +0200 Subject: [PATCH 08/84] update gin commands --- .github/workflows/cache_elephant_data.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index 0f6652fe4..4015f3494 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -55,6 +55,7 @@ jobs: gin --version git clone --depth 1 https://gin.g-node.org/NeuralEnsemble/elephant-data.git cd elephant-data + gin add-remote primary gin:NeuralEnsemble/elephant-data gin getc . echo "dataset-path =$(pwd)"" >> $GITHUB_OUTPUT From 22786b53dcd486202e6b55b536ece6fbbcfbe9b8 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 19 Apr 2024 10:45:43 +0200 Subject: [PATCH 09/84] handle prompt --- .github/workflows/cache_elephant_data.yml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index 4015f3494..03d69b13a 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -55,7 +55,22 @@ jobs: gin --version git clone --depth 1 https://gin.g-node.org/NeuralEnsemble/elephant-data.git cd elephant-data - gin add-remote primary gin:NeuralEnsemble/elephant-data + set timeout 10 + spawn gin add-remote primary gin:NeuralEnsemble/elephant-data + expect { + "Remote ssh://git@gin.g-node.org:22/NeuralEnsemble/elephant-data does not exist. Would you like to create it?" { + send "yes\r" + expect eof + } + timeout { + puts "Timeout occurred. Exiting." + exit 1 + } + eof { + puts "Command executed successfully." + exit 0 + } + } gin getc . echo "dataset-path =$(pwd)"" >> $GITHUB_OUTPUT From 66a17959a33a2de9f3dee0595cecc695d3996f11 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 19 Apr 2024 12:59:38 +0200 Subject: [PATCH 10/84] use datalad --- .github/workflows/cache_elephant_data.yml | 29 +++++------------------ 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index 03d69b13a..d0b09ccb2 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -44,40 +44,23 @@ jobs: git config --global user.name "elephant CI" git config --global filter.annex.process "git-annex filter-process" # recommended for efficiency - brew tap g-node/pkg - brew install g-node/pkg/gin-cli + brew install datalad - name: Download dataset id: download-dataset if: steps.cache-datasets.outputs.cache-hit != 'true' # Download repository and also fetch data run: | - gin --version - git clone --depth 1 https://gin.g-node.org/NeuralEnsemble/elephant-data.git + cd ~ + datalad install --recursive --get-data https://gin.g-node.org/NeuralEnsemble/elephant-data cd elephant-data - set timeout 10 - spawn gin add-remote primary gin:NeuralEnsemble/elephant-data - expect { - "Remote ssh://git@gin.g-node.org:22/NeuralEnsemble/elephant-data does not exist. Would you like to create it?" { - send "yes\r" - expect eof - } - timeout { - puts "Timeout occurred. Exiting." - exit 1 - } - eof { - puts "Command executed successfully." - exit 0 - } - } - gin getc . echo "dataset-path =$(pwd)"" >> $GITHUB_OUTPUT - name: Show size of the cache to assert data is downloaded run: | - pwd + cd ~ du -hs ${{steps.download-dataset.outputs.dataset-path}} cd ${{steps.download-dataset.outputs.dataset-path}} pwd - ls -lh \ No newline at end of file + ls -lh + cd elephant \ No newline at end of file From 91f4a5a63afc4be46f84de1a2c96e8f06cee7fe0 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 19 Apr 2024 13:17:55 +0200 Subject: [PATCH 11/84] remove typo --- .github/workflows/cache_elephant_data.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index d0b09ccb2..66f79d670 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -37,7 +37,7 @@ jobs: - name: Cache found? run: echo "Cache-hit == ${{steps.cache-datasets.outputs.cache-hit == 'true'}}" - - name: Installing gin + - name: Installing datalad if: steps.cache-datasets.outputs.cache-hit != 'true' run: | git config --global user.email "elephant_ci@fake_mail.com" @@ -52,9 +52,10 @@ jobs: # Download repository and also fetch data run: | cd ~ + datalad --version datalad install --recursive --get-data https://gin.g-node.org/NeuralEnsemble/elephant-data cd elephant-data - echo "dataset-path =$(pwd)"" >> $GITHUB_OUTPUT + echo "dataset-path =$(pwd)" >> $GITHUB_OUTPUT - name: Show size of the cache to assert data is downloaded run: | From 669d80d303ce62b15e42859bcd66994dace30793 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 19 Apr 2024 13:33:29 +0200 Subject: [PATCH 12/84] change paths --- .github/workflows/cache_elephant_data.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index 66f79d670..627ffe450 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -54,14 +54,10 @@ jobs: cd ~ datalad --version datalad install --recursive --get-data https://gin.g-node.org/NeuralEnsemble/elephant-data - cd elephant-data echo "dataset-path =$(pwd)" >> $GITHUB_OUTPUT - name: Show size of the cache to assert data is downloaded run: | cd ~ - du -hs ${{steps.download-dataset.outputs.dataset-path}} - cd ${{steps.download-dataset.outputs.dataset-path}} - pwd - ls -lh - cd elephant \ No newline at end of file + du -hs ~/elephant-data + ls -lh ~/elephant-data \ No newline at end of file From 0215b91ee4c510a4dc9ab46204ed08522e00ff6e Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 19 Apr 2024 14:29:31 +0200 Subject: [PATCH 13/84] remove no longer needed var --- .github/workflows/cache_elephant_data.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index 627ffe450..f680c1419 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -54,7 +54,6 @@ jobs: cd ~ datalad --version datalad install --recursive --get-data https://gin.g-node.org/NeuralEnsemble/elephant-data - echo "dataset-path =$(pwd)" >> $GITHUB_OUTPUT - name: Show size of the cache to assert data is downloaded run: | From c30d02266f9923453de461ac60a8deeef660ca1d Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 19 Apr 2024 15:47:08 +0200 Subject: [PATCH 14/84] add environment variable ELEPHANT_DATA_PATH --- elephant/datasets.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/elephant/datasets.py b/elephant/datasets.py index 58d52d31f..ad88d0a54 100644 --- a/elephant/datasets.py +++ b/elephant/datasets.py @@ -80,7 +80,7 @@ def download_datasets(repo_path, filepath=None, checksum=None, elephant-data. Different versions of the elephant package may require different versions of elephant-data. - e.g. the follwoing URLs: + e.g. the following URLs: - https://web.gin.g-node.org/NeuralEnsemble/elephant-data/raw/0.0.1 points to release v0.0.1. - https://web.gin.g-node.org/NeuralEnsemble/elephant-data/raw/master @@ -96,15 +96,18 @@ def download_datasets(repo_path, filepath=None, checksum=None, `ELEPHANT_DATA_URL` to https://web.gin.g-node.org/NeuralEnsemble/elephant-data/raw/multitaper. For a complete example, see Examples section. - + + To use a local copy of elephant-data, use the environment variable + `ELEPHANT_DATA_PATH`, e.g. set to /home/user/elephant-data. + Parameters ---------- repo_path : str String denoting the path relative to elephant-data repository root filepath : str, optional Path to temporary folder where the downloaded files will be stored - checksum : str, otpional - Checksum to verify dara integrity after download + checksum : str, optional + Checksum to verify data integrity after download verbose : bool, optional Whether to disable the entire progressbar wrapper []. If set to None, disable on non-TTY. @@ -134,6 +137,9 @@ def download_datasets(repo_path, filepath=None, checksum=None, PosixPath('/tmp/elephant/time_series.npy') """ + if 'ELEPHANT_DATA_PATH' in environ: # user did set local path + return Path(f"{getenv('ELEPHANT_DATA_PATH')}/{repo_path}") + # this url redirects to the current location of elephant-data url_to_root = "https://datasets.python-elephant.org/" @@ -149,7 +155,7 @@ def download_datasets(repo_path, filepath=None, checksum=None, except HTTPError as error: # if corresponding elephant-data version is not found, # use latest commit of elephant-data - default_url = url_to_root + f"raw/master" + default_url = url_to_root + "raw/master" warnings.warn(f"No corresponding version of elephant-data found.\n" f"Elephant version: {_get_version()}. " @@ -164,7 +170,7 @@ def download_datasets(repo_path, filepath=None, checksum=None, ctx.check_hostname = True urlopen(default_url + '/README.md') except HTTPError: # e.g. 404 - default_url = url_to_root + f"raw/master" + default_url = url_to_root + "raw/master" warnings.warn(f"Data URL:{default_url}, error: {error}." f"{error.reason}") From 4dd82d6b3994a705087fd3e0d36199533a2752de Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 19 Apr 2024 15:47:36 +0200 Subject: [PATCH 15/84] fix causality tests --- elephant/test/test_causality.py | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/elephant/test/test_causality.py b/elephant/test/test_causality.py index 552fe2f05..5ac519961 100644 --- a/elephant/test/test_causality.py +++ b/elephant/test/test_causality.py @@ -16,7 +16,7 @@ from elephant.spectral import multitaper_cross_spectrum, multitaper_coherence import elephant.causality.granger -from elephant.datasets import download_datasets, ELEPHANT_TMP_DIR +from elephant.datasets import download_datasets class PairwiseGrangerTestCase(unittest.TestCase): @@ -453,12 +453,16 @@ def test_pairwise_spectral_granger_against_ground_truth(self): ("noise_covariance.npy", "6f80ccff2b2aa9485dc9c01d81570bf5") ] + downloaded_files = {} for filename, checksum in files_to_download: - download_datasets(repo_path=f"{repo_path}/{filename}", - checksum=checksum) - signals = np.load(ELEPHANT_TMP_DIR / 'time_series.npy') - weights = np.load(ELEPHANT_TMP_DIR / 'weights.npy') - cov = np.load(ELEPHANT_TMP_DIR / 'noise_covariance.npy') + downloaded_files[filename] = { + 'filename': filename, + 'path': download_datasets(repo_path=f"{repo_path}/{filename}", + checksum=checksum)} + + signals = np.load(downloaded_files['time_series.npy']['path']) + weights = np.load(downloaded_files['weights.npy']['path']) + cov = np.load(downloaded_files['noise_covariance.npy']['path']) # Estimate spectral Granger Causality f, spectral_causality = \ @@ -531,12 +535,16 @@ def test_pairwise_spectral_granger_against_r_grangers(self): ("time_series_small.npy", "b33dc12d4291db7c2087dd8429f15ab4"), ("gc_matrix.npy", "c57262145e74a178588ff0a1004879e2") ] - + + downloaded_files = {} for filename, checksum in files_to_download: - download_datasets(repo_path=f"{repo_path}/{filename}", - checksum=checksum) - signal = np.load(ELEPHANT_TMP_DIR / 'time_series_small.npy') - gc_matrix = np.load(ELEPHANT_TMP_DIR / 'gc_matrix.npy') + downloaded_files[filename] = { + 'filename': filename, + 'path': download_datasets(repo_path=f"{repo_path}/{filename}", + checksum=checksum)} + + signal = np.load(downloaded_files['time_series_small.npy']['path']) + gc_matrix = np.load(downloaded_files['gc_matrix.npy']['path']) denom = 20 f, spectral_causality = \ From 2d41c1a782603951204f1edceaed031eae8e5c04 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 19 Apr 2024 16:30:30 +0200 Subject: [PATCH 16/84] fix tests for phase analysis --- elephant/test/test_phase_analysis.py | 37 +++++++++++++++------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/elephant/test/test_phase_analysis.py b/elephant/test/test_phase_analysis.py index 6b8218c99..c17059c5a 100644 --- a/elephant/test/test_phase_analysis.py +++ b/elephant/test/test_phase_analysis.py @@ -384,6 +384,7 @@ def setUpClass(cls): # downloaded once into a local temporary directory # and then loaded/ read for each test function individually. + cls.tmp_path = {} # REAL DATA real_data_path = "unittest/phase_analysis/weighted_phase_lag_index/" \ "data/wpli_real_data" @@ -398,8 +399,10 @@ def setUpClass(cls): ) for filename, checksum in cls.files_to_download_real: # files will be downloaded to ELEPHANT_TMP_DIR - cls.tmp_path = download_datasets( - f"{real_data_path}/{filename}", checksum=checksum) + cls.tmp_path[filename] = { + 'filename':filename, + 'path':download_datasets( + f"{real_data_path}/{filename}", checksum=checksum)} # ARTIFICIAL DATA artificial_data_path = "unittest/phase_analysis/" \ "weighted_phase_lag_index/data/wpli_specific_artificial_dataset" @@ -409,8 +412,10 @@ def setUpClass(cls): ) for filename, checksum in cls.files_to_download_artificial: # files will be downloaded to ELEPHANT_TMP_DIR - cls.tmp_path = download_datasets( - f"{artificial_data_path}/{filename}", checksum=checksum) + cls.tmp_path[filename] = { + 'filename':filename, + 'path':download_datasets( + f"{artificial_data_path}/{filename}", checksum=checksum)} # GROUND TRUTH DATA ground_truth_data_path = "unittest/phase_analysis/" \ "weighted_phase_lag_index/data/wpli_ground_truth" @@ -422,8 +427,10 @@ def setUpClass(cls): ) for filename, checksum in cls.files_to_download_ground_truth: # files will be downloaded into ELEPHANT_TMP_DIR - cls.tmp_path = download_datasets( - f"{ground_truth_data_path}/{filename}", checksum=checksum) + cls.tmp_path[filename] = { + 'filename':filename, + 'path':download_datasets( + f"{ground_truth_data_path}/{filename}", checksum=checksum)} def setUp(self): self.tolerance = 1e-15 @@ -431,10 +438,10 @@ def setUp(self): # load real/artificial LFP-dataset for ground-truth consistency checks # real LFP-dataset dataset1_real = scipy.io.loadmat( - f"{self.tmp_path.parent}/{self.files_to_download_real[0][0]}", + f"{self.tmp_path[self.files_to_download_real[0][0]]['path']}", squeeze_me=True) dataset2_real = scipy.io.loadmat( - f"{self.tmp_path.parent}/{self.files_to_download_real[1][0]}", + f"{self.tmp_path[self.files_to_download_real[1][0]]['path']}", squeeze_me=True) # get relevant values @@ -450,11 +457,9 @@ def setUp(self): # artificial LFP-dataset dataset1_artificial = scipy.io.loadmat( - f"{self.tmp_path.parent}/" - f"{self.files_to_download_artificial[0][0]}", squeeze_me=True) + f"{self.tmp_path[self.files_to_download_artificial[0][0]]['path']}", squeeze_me=True) dataset2_artificial = scipy.io.loadmat( - f"{self.tmp_path.parent}/" - f"{self.files_to_download_artificial[1][0]}", squeeze_me=True) + f"{self.tmp_path[self.files_to_download_artificial[1][0]]['path']}", squeeze_me=True) # get relevant values self.lfps1_artificial = dataset1_artificial['lfp_matrix'] * pq.uV self.sf1_artificial = dataset1_artificial['sf'] * pq.Hz @@ -469,12 +474,10 @@ def setUp(self): # load ground-truth reference calculated by: # Matlab package 'FieldTrip': ft_connectivity_wpli() self.wpli_ground_truth_ft_connectivity_wpli_real = np.loadtxt( - f"{self.tmp_path.parent}/" - f"{self.files_to_download_ground_truth[0][0]}", + f"{self.tmp_path[self.files_to_download_ground_truth[0][0]]['path']}", delimiter=',', dtype=np.float64) self.wpli_ground_truth_ft_connectivity_artificial = np.loadtxt( - f"{self.tmp_path.parent}/" - f"{self.files_to_download_ground_truth[1][0]}", + f"{self.tmp_path[self.files_to_download_ground_truth[1][0]]['path']}", delimiter=',', dtype=np.float64) def test_WPLI_ground_truth_consistency_real_LFP_dataset(self): @@ -700,7 +703,7 @@ def test_WPLI_raises_error_if_AnalogSignals_have_diff_sampling_rate(): def test_WPLI_raises_error_if_sampling_rate_not_given(self): """ Test if WPLI raises a ValueError, when the sampling rate is not given - for np.array() or Quanitity input. + for np.array() or Quantity input. """ signal_x = np.random.random([40, 2100]) * pq.mV signal_y = np.random.random([40, 2100]) * pq.mV From 5227f1dcf38690e39655c68c1bc11343d3409b96 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 19 Apr 2024 16:47:51 +0200 Subject: [PATCH 17/84] fix tests causality --- elephant/test/test_causality.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elephant/test/test_causality.py b/elephant/test/test_causality.py index 5ac519961..648af2a04 100644 --- a/elephant/test/test_causality.py +++ b/elephant/test/test_causality.py @@ -535,7 +535,7 @@ def test_pairwise_spectral_granger_against_r_grangers(self): ("time_series_small.npy", "b33dc12d4291db7c2087dd8429f15ab4"), ("gc_matrix.npy", "c57262145e74a178588ff0a1004879e2") ] - + downloaded_files = {} for filename, checksum in files_to_download: downloaded_files[filename] = { From bc0252bec92c22c5b76106e7dbb69d170363b8d5 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 19 Apr 2024 16:48:04 +0200 Subject: [PATCH 18/84] fix tests spectral --- elephant/test/test_spectral.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/elephant/test/test_spectral.py b/elephant/test/test_spectral.py index 41244fb66..e11a55225 100644 --- a/elephant/test/test_spectral.py +++ b/elephant/test/test_spectral.py @@ -20,7 +20,7 @@ from packaging import version import elephant.spectral -from elephant.datasets import download_datasets, ELEPHANT_TMP_DIR +from elephant.datasets import download_datasets class WelchPSDTestCase(unittest.TestCase): @@ -277,13 +277,16 @@ def test_multitaper_psd_against_nitime(self): ("time_series.npy", "ff43797e2ac94613f510b20a31e2e80e"), ("psd_nitime.npy", "89d1f53957e66c786049ea425b53c0e8") ] - + + downloaded_files = {} for filename, checksum in files_to_download: - download_datasets(repo_path=f"{repo_path}/{filename}", - checksum=checksum) + downloaded_files[filename] = { + 'filename': filename, + 'path': download_datasets(repo_path=f"{repo_path}/{filename}", + checksum=checksum)} - time_series = np.load(ELEPHANT_TMP_DIR / 'time_series.npy') - psd_nitime = np.load(ELEPHANT_TMP_DIR / 'psd_nitime.npy') + time_series = np.load(downloaded_files['time_series.npy']['path']) + psd_nitime = np.load(downloaded_files['psd_nitime.npy']['path']) freqs, psd_multitaper = elephant.spectral.multitaper_psd( signal=time_series, fs=0.1, nw=4, num_tapers=8) From 2f29dbea49f5ebe6bb09de519a4154077595d5d8 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 19 Apr 2024 16:48:16 +0200 Subject: [PATCH 19/84] fix tests spiketrain correlation --- elephant/test/test_spike_train_correlation.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/elephant/test/test_spike_train_correlation.py b/elephant/test/test_spike_train_correlation.py index cae01e479..90de65ea1 100644 --- a/elephant/test/test_spike_train_correlation.py +++ b/elephant/test/test_spike_train_correlation.py @@ -20,7 +20,7 @@ from elephant.spike_train_generation import StationaryPoissonProcess, \ StationaryGammaProcess import math -from elephant.datasets import download_datasets, ELEPHANT_TMP_DIR +from elephant.datasets import download_datasets from elephant.spike_train_generation import homogeneous_poisson_process, \ homogeneous_gamma_process @@ -852,11 +852,15 @@ def test_sttc_validation_test(self): files_to_download = [("spike_time_tiling_coefficient_results.nix", "e3749d79046622494660a03e89950f51")] + downloaded_files = {} for filename, checksum in files_to_download: - filepath = download_datasets(repo_path=f"{repo_path}/{filename}", - checksum=checksum) + downloaded_files[filename] = { + 'filename': filename, + 'path': download_datasets(repo_path=f"{repo_path}/{filename}", + checksum=checksum)} - reader = NixIO(filepath, mode='ro') + reader = NixIO(downloaded_files[ + 'spike_time_tiling_coefficient_results.nix']['path'], mode='ro') test_data_block = reader.read() for segment in test_data_block[0].segments: From 247e951312e41eb3e31c1cdad854170d700260dc Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 19 Apr 2024 16:48:36 +0200 Subject: [PATCH 20/84] fix tests spike train dissimilarity --- .../test/test_spike_train_dissimilarity.py | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/elephant/test/test_spike_train_dissimilarity.py b/elephant/test/test_spike_train_dissimilarity.py index 6cab2858b..5cff9e987 100644 --- a/elephant/test/test_spike_train_dissimilarity.py +++ b/elephant/test/test_spike_train_dissimilarity.py @@ -15,7 +15,7 @@ from elephant.spike_train_generation import StationaryPoissonProcess import elephant.spike_train_dissimilarity as stds -from elephant.datasets import download_datasets, ELEPHANT_TMP_DIR +from elephant.datasets import download_datasets class TimeScaleDependSpikeTrainDissimMeasuresTestCase(unittest.TestCase): @@ -398,12 +398,16 @@ def test_victor_purpura_matlab_comparison_float(self): ("times_float.npy", "ed1ff4d2c0eeed4a2b50a456803656be"), ("matlab_results_float.npy", "a17f049e7ad0ddf7ca812e86fdb92646")] + downloaded_files = {} for filename, checksum in files_to_download: - download_datasets(repo_path=f"{repo_path}/{filename}", - checksum=checksum) + downloaded_files[filename] = { + 'filename': filename, + 'path': download_datasets(repo_path=f"{repo_path}/{filename}", + checksum=checksum)} - times_float = np.load(ELEPHANT_TMP_DIR / 'times_float.npy') - mat_res_float = np.load(ELEPHANT_TMP_DIR / 'matlab_results_float.npy') + times_float = np.load(downloaded_files['times_float.npy']['path']) + mat_res_float = np.load(downloaded_files[ + 'matlab_results_float.npy']['path']) r_float = SpikeTrain(times_float[0], units='ms', t_start=0, t_stop=1000 * ms) @@ -428,12 +432,15 @@ def test_victor_purpura_matlab_comparison_int(self): ("times_int.npy", "aa1411c04da3f58d8b8913ae2f935057"), ("matlab_results_int.npy", "7edd32e50edde12dc1ef4aa5f57f70fb")] + downloaded_files = {} for filename, checksum in files_to_download: - download_datasets(repo_path=f"{repo_path}/{filename}", - checksum=checksum) + downloaded_files[filename] = { + 'filename': filename, + 'path': download_datasets(repo_path=f"{repo_path}/{filename}", + checksum=checksum)} - times_int = np.load(ELEPHANT_TMP_DIR / 'times_int.npy') - mat_res_int = np.load(ELEPHANT_TMP_DIR / 'matlab_results_int.npy') + times_int = np.load(downloaded_files['times_int.npy']['path']) + mat_res_int = np.load(downloaded_files['matlab_results_int.npy']['path']) r_int = SpikeTrain(times_int[0], units='ms', t_start=0, t_stop=1000 * ms) From 6b1e55ff35814fab65de974f4218ada71c7cb142 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 19 Apr 2024 16:48:48 +0200 Subject: [PATCH 21/84] fix tests spike train synchrony --- elephant/test/test_spike_train_synchrony.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elephant/test/test_spike_train_synchrony.py b/elephant/test/test_spike_train_synchrony.py index 58be525eb..d3455b115 100644 --- a/elephant/test/test_spike_train_synchrony.py +++ b/elephant/test/test_spike_train_synchrony.py @@ -168,7 +168,7 @@ def test_spike_contrast_with_Izhikevich_network_auto(self): checksum = "70e848500c1d9c6403b66de8c741d849" filepath_zip = download_datasets(repo_path=izhikevich_gin, checksum=checksum) - unzip(filepath_zip) + unzip(filepath_zip, outdir=filepath_zip.parent) filepath_json = filepath_zip.with_suffix(".json") with open(filepath_json) as read_file: data = json.load(read_file) From f71ced6e59c768bd76392df84074d422583156ed Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 25 Apr 2024 14:56:07 +0200 Subject: [PATCH 22/84] fix pep8 --- elephant/test/test_phase_analysis.py | 571 ++++++++++++++++++--------- 1 file changed, 379 insertions(+), 192 deletions(-) diff --git a/elephant/test/test_phase_analysis.py b/elephant/test/test_phase_analysis.py index c17059c5a..be42f0245 100644 --- a/elephant/test/test_phase_analysis.py +++ b/elephant/test/test_phase_analysis.py @@ -20,31 +20,41 @@ class SpikeTriggeredPhaseTestCase(unittest.TestCase): - def setUp(self): tlen0 = 100 * pq.s - f0 = 20. * pq.Hz + f0 = 20.0 * pq.Hz fs0 = 1 * pq.ms - t0 = np.arange( - 0, tlen0.rescale(pq.s).magnitude, - fs0.rescale(pq.s).magnitude) * pq.s + t0 = ( + np.arange( + 0, tlen0.rescale(pq.s).magnitude, fs0.rescale(pq.s).magnitude + ) + * pq.s + ) self.anasig0 = AnalogSignal( np.sin(2 * np.pi * (f0 * t0).simplified.magnitude), - units=pq.mV, t_start=0 * pq.ms, sampling_period=fs0) + units=pq.mV, + t_start=0 * pq.ms, + sampling_period=fs0, + ) self.st0 = SpikeTrain( np.arange(50, tlen0.rescale(pq.ms).magnitude - 50, 50) * pq.ms, - t_start=0 * pq.ms, t_stop=tlen0) + t_start=0 * pq.ms, + t_stop=tlen0, + ) self.st1 = SpikeTrain( - [100., 100.1, 100.2, 100.3, 100.9, 101.] * pq.ms, - t_start=0 * pq.ms, t_stop=tlen0) + [100.0, 100.1, 100.2, 100.3, 100.9, 101.0] * pq.ms, + t_start=0 * pq.ms, + t_stop=tlen0, + ) def test_perfect_locking_one_spiketrain_one_signal(self): phases, amps, times = elephant.phase_analysis.spike_triggered_phase( elephant.signal_processing.hilbert(self.anasig0), self.st0, - interpolate=True) + interpolate=True, + ) - assert_allclose(phases[0], - np.pi / 2.) + assert_allclose(phases[0], -np.pi / 2.0) assert_allclose(amps[0], 1, atol=0.1) assert_allclose(times[0].magnitude, self.st0.magnitude) self.assertEqual(len(phases[0]), len(self.st0)) @@ -55,11 +65,13 @@ def test_perfect_locking_many_spiketrains_many_signals(self): phases, amps, times = elephant.phase_analysis.spike_triggered_phase( [ elephant.signal_processing.hilbert(self.anasig0), - elephant.signal_processing.hilbert(self.anasig0)], + elephant.signal_processing.hilbert(self.anasig0), + ], [self.st0, self.st0], - interpolate=True) + interpolate=True, + ) - assert_allclose(phases[0], -np.pi / 2.) + assert_allclose(phases[0], -np.pi / 2.0) assert_allclose(amps[0], 1, atol=0.1) assert_allclose(times[0].magnitude, self.st0.magnitude) self.assertEqual(len(phases[0]), len(self.st0)) @@ -70,11 +82,13 @@ def test_perfect_locking_one_spiketrains_many_signals(self): phases, amps, times = elephant.phase_analysis.spike_triggered_phase( [ elephant.signal_processing.hilbert(self.anasig0), - elephant.signal_processing.hilbert(self.anasig0)], + elephant.signal_processing.hilbert(self.anasig0), + ], [self.st0], - interpolate=True) + interpolate=True, + ) - assert_allclose(phases[0], -np.pi / 2.) + assert_allclose(phases[0], -np.pi / 2.0) assert_allclose(amps[0], 1, atol=0.1) assert_allclose(times[0].magnitude, self.st0.magnitude) self.assertEqual(len(phases[0]), len(self.st0)) @@ -85,9 +99,10 @@ def test_perfect_locking_many_spiketrains_one_signal(self): phases, amps, times = elephant.phase_analysis.spike_triggered_phase( elephant.signal_processing.hilbert(self.anasig0), [self.st0, self.st0], - interpolate=True) + interpolate=True, + ) - assert_allclose(phases[0], -np.pi / 2.) + assert_allclose(phases[0], -np.pi / 2.0) assert_allclose(amps[0], 1, atol=0.1) assert_allclose(times[0].magnitude, self.st0.magnitude) self.assertEqual(len(phases[0]), len(self.st0)) @@ -98,7 +113,8 @@ def test_interpolate(self): phases_int, _, _ = elephant.phase_analysis.spike_triggered_phase( elephant.signal_processing.hilbert(self.anasig0), self.st1, - interpolate=True) + interpolate=True, + ) self.assertLess(phases_int[0][0], phases_int[0][1]) self.assertLess(phases_int[0][1], phases_int[0][2]) @@ -109,7 +125,8 @@ def test_interpolate(self): phases_noint, _, _ = elephant.phase_analysis.spike_triggered_phase( elephant.signal_processing.hilbert(self.anasig0), self.st1, - interpolate=False) + interpolate=False, + ) self.assertEqual(phases_noint[0][0], phases_noint[0][1]) self.assertEqual(phases_noint[0][1], phases_noint[0][2]) @@ -125,28 +142,37 @@ def test_interpolate(self): def test_inconsistent_numbers_spiketrains_hilbert(self): self.assertRaises( - ValueError, elephant.phase_analysis.spike_triggered_phase, + ValueError, + elephant.phase_analysis.spike_triggered_phase, [ elephant.signal_processing.hilbert(self.anasig0), - elephant.signal_processing.hilbert(self.anasig0)], - [self.st0, self.st0, self.st0], False) + elephant.signal_processing.hilbert(self.anasig0), + ], + [self.st0, self.st0, self.st0], + False, + ) self.assertRaises( - ValueError, elephant.phase_analysis.spike_triggered_phase, + ValueError, + elephant.phase_analysis.spike_triggered_phase, [ elephant.signal_processing.hilbert(self.anasig0), - elephant.signal_processing.hilbert(self.anasig0)], - [self.st0, self.st0, self.st0], False) + elephant.signal_processing.hilbert(self.anasig0), + ], + [self.st0, self.st0, self.st0], + False, + ) def test_spike_earlier_than_hilbert(self): # This is a spike clearly outside the bounds st = SpikeTrain( - [-50, 50], - units='s', t_start=-100 * pq.s, t_stop=100 * pq.s) + [-50, 50], units="s", t_start=-100 * pq.s, t_stop=100 * pq.s + ) phases_noint, _, _ = elephant.phase_analysis.spike_triggered_phase( elephant.signal_processing.hilbert(self.anasig0), st, - interpolate=False) + interpolate=False, + ) self.assertEqual(len(phases_noint[0]), 1) # This is a spike right on the border (start of the signal is at 0s, @@ -154,23 +180,25 @@ def test_spike_earlier_than_hilbert(self): # Elephant (left borders inclusive, right borders exclusive), this # spike is to be considered. st = SpikeTrain( - [0, 50], - units='s', t_start=-100 * pq.s, t_stop=100 * pq.s) + [0, 50], units="s", t_start=-100 * pq.s, t_stop=100 * pq.s + ) phases_noint, _, _ = elephant.phase_analysis.spike_triggered_phase( elephant.signal_processing.hilbert(self.anasig0), st, - interpolate=False) + interpolate=False, + ) self.assertEqual(len(phases_noint[0]), 2) def test_spike_later_than_hilbert(self): # This is a spike clearly outside the bounds st = SpikeTrain( - [1, 250], - units='s', t_start=-1 * pq.s, t_stop=300 * pq.s) + [1, 250], units="s", t_start=-1 * pq.s, t_stop=300 * pq.s + ) phases_noint, _, _ = elephant.phase_analysis.spike_triggered_phase( elephant.signal_processing.hilbert(self.anasig0), st, - interpolate=False) + interpolate=False, + ) self.assertEqual(len(phases_noint[0]), 1) # This is a spike right on the border (length of the signal is 100s, @@ -178,12 +206,13 @@ def test_spike_later_than_hilbert(self): # Elephant (left borders inclusive, right borders exclusive), this # spike is not to be considered. st = SpikeTrain( - [1, 100], - units='s', t_start=-1 * pq.s, t_stop=200 * pq.s) + [1, 100], units="s", t_start=-1 * pq.s, t_stop=200 * pq.s + ) phases_noint, _, _ = elephant.phase_analysis.spike_triggered_phase( elephant.signal_processing.hilbert(self.anasig0), st, - interpolate=False) + interpolate=False, + ) self.assertEqual(len(phases_noint[0]), 1) # This test handles the correct dealing with input signals that have @@ -193,13 +222,16 @@ def test_regression_269(self): # before the end of the signal cu = pq.CompoundUnit("1/30000.*s") st = SpikeTrain( - [30000., (self.anasig0.t_stop - 1 * pq.s).rescale(cu).magnitude], + [30000.0, (self.anasig0.t_stop - 1 * pq.s).rescale(cu).magnitude], units=pq.CompoundUnit("1/30000.*s"), - t_start=-1 * pq.s, t_stop=300 * pq.s) + t_start=-1 * pq.s, + t_stop=300 * pq.s, + ) phases_noint, _, _ = elephant.phase_analysis.spike_triggered_phase( elephant.signal_processing.hilbert(self.anasig0), st, - interpolate=False) + interpolate=False, + ) self.assertEqual(len(phases_noint[0]), 2) @@ -222,10 +254,12 @@ def testMeanVector_direction_is_phi_and_length_is_1(self): """ theta_bar_1, r_1 = elephant.phase_analysis.mean_phase_vector( - self.dataset1) + self.dataset1 + ) # mean direction must be phi - self.assertAlmostEqual(theta_bar_1, self.lock_value_phi, - delta=self.tolerance) + self.assertAlmostEqual( + theta_bar_1, self.lock_value_phi, delta=self.tolerance + ) # mean vector length must be almost equal 1 self.assertAlmostEqual(r_1, 1, delta=self.tolerance) @@ -235,7 +269,8 @@ def testMeanVector_length_is_0(self): on the unit circle. """ theta_bar_2, r_2 = elephant.phase_analysis.mean_phase_vector( - self.dataset2) + self.dataset2 + ) # mean vector length must be almost equal 0 self.assertAlmostEqual(r_2, 0, delta=self.tolerance) @@ -246,7 +281,8 @@ def testMeanVector_ranges_of_direction_and_length(self): Test if the range of the mean vector length is within [0, 1]. """ theta_bar_3, r_3 = elephant.phase_analysis.mean_phase_vector( - self.dataset3) + self.dataset3 + ) # mean vector direction self.assertTrue(-np.pi < theta_bar_3 <= np.pi) # mean vector length @@ -267,8 +303,9 @@ def testPhaseDifference_in_range_minus_pi_to_pi(self): beta = np.random.uniform(-np.pi, np.pi, self.n_samples) phase_diff = elephant.phase_analysis.phase_difference(alpha, beta) - self.assertTrue((-np.pi <= phase_diff).all() - and (phase_diff <= np.pi).all()) + self.assertTrue( + (-np.pi <= phase_diff).all() and (phase_diff <= np.pi).all() + ) def testPhaseDifference_is_delta(self): """ @@ -292,18 +329,22 @@ def setUp(self): self.num_trials = 100 # create two random uniform distributions (all trials are identical) - self.signal_x = \ - np.full([self.num_trials, self.num_time_points], - np.random.uniform(-np.pi, np.pi, self.num_time_points)) - self.signal_y = \ - np.full([self.num_trials, self.num_time_points], - np.random.uniform(-np.pi, np.pi, self.num_time_points)) + self.signal_x = np.full( + [self.num_trials, self.num_time_points], + np.random.uniform(-np.pi, np.pi, self.num_time_points), + ) + self.signal_y = np.full( + [self.num_trials, self.num_time_points], + np.random.uniform(-np.pi, np.pi, self.num_time_points), + ) # create two random uniform distributions, where all trails are random self.random_x = np.random.uniform( - -np.pi, np.pi, (1000, self.num_time_points)) + -np.pi, np.pi, (1000, self.num_time_points) + ) self.random_y = np.random.uniform( - -np.pi, np.pi, (1000, self.num_time_points)) + -np.pi, np.pi, (1000, self.num_time_points) + ) # simple samples of different shapes to assert ErrorRaising self.simple_x = np.array([[0, -np.pi, np.pi], [0, -np.pi, np.pi]]) @@ -316,12 +357,13 @@ def testPhaseLockingValue_identical_signals_both_identical_trials(self): trials are passed. PLV's needed to be 1, due to the constant phase difference of 0 across trials at each time-point. """ - list1_plv_t = \ - elephant.phase_analysis.phase_locking_value(self.signal_x, - self.signal_x) + list1_plv_t = elephant.phase_analysis.phase_locking_value( + self.signal_x, self.signal_x + ) target_plv_r_is_one = np.ones_like(list1_plv_t) - np.testing.assert_allclose(list1_plv_t, target_plv_r_is_one, - self.tolerance) + np.testing.assert_allclose( + list1_plv_t, target_plv_r_is_one, self.tolerance + ) def testPhaseLockingValue_different_signals_both_identical_trials(self): """ @@ -331,10 +373,12 @@ def testPhaseLockingValue_different_signals_both_identical_trials(self): different time-points. """ list2_plv_t = elephant.phase_analysis.phase_locking_value( - self.signal_x, self.signal_y) + self.signal_x, self.signal_y + ) target_plv_r_is_one = np.ones_like(list2_plv_t) - np.testing.assert_allclose(list2_plv_t, target_plv_r_is_one, - atol=3e-15) + np.testing.assert_allclose( + list2_plv_t, target_plv_r_is_one, atol=3e-15 + ) def testPhaseLockingValue_different_signals_both_different_trials(self): """ @@ -344,11 +388,13 @@ def testPhaseLockingValue_different_signals_both_different_trials(self): phase difference across trials for each time-point. """ list3_plv_t = elephant.phase_analysis.phase_locking_value( - self.random_x, self.random_y) + self.random_x, self.random_y + ) target_plv_is_zero = np.zeros_like(list3_plv_t) # use default value from np.allclose() for atol=1e-8 to prevent failure - np.testing.assert_allclose(list3_plv_t, target_plv_is_zero, - rtol=1e-2, atol=1.1e-1) + np.testing.assert_allclose( + list3_plv_t, target_plv_is_zero, rtol=1e-2, atol=1.1e-1 + ) def testPhaseLockingValue_raise_Error_if_trial_number_is_different(self): """ @@ -357,8 +403,11 @@ def testPhaseLockingValue_raise_Error_if_trial_number_is_different(self): """ # different numbers of trails np.testing.assert_raises( - ValueError, elephant.phase_analysis.phase_locking_value, - self.simple_x, self.simple_y) + ValueError, + elephant.phase_analysis.phase_locking_value, + self.simple_x, + self.simple_y, + ) def testPhaseLockingValue_raise_Error_if_trial_lengths_are_different(self): """ @@ -367,8 +416,11 @@ def testPhaseLockingValue_raise_Error_if_trial_lengths_are_different(self): """ # different lengths in a trail pair np.testing.assert_raises( - ValueError, elephant.phase_analysis.phase_locking_value, - self.simple_y, self.simple_z) + ValueError, + elephant.phase_analysis.phase_locking_value, + self.simple_y, + self.simple_z, + ) class WeightedPhaseLagIndexTestCase(unittest.TestCase): @@ -386,26 +438,38 @@ def setUpClass(cls): cls.tmp_path = {} # REAL DATA - real_data_path = "unittest/phase_analysis/weighted_phase_lag_index/" \ - "data/wpli_real_data" + real_data_path = ( + "unittest/phase_analysis/weighted_phase_lag_index/" + "data/wpli_real_data" + ) cls.files_to_download_real = ( - ("i140703-001_ch01_slice_TS_ON_to_GO_ON_correct_trials.mat", - "0e76454c58208cab710e672d04de5168"), - ("i140703-001_ch02_slice_TS_ON_to_GO_ON_correct_trials.mat", - "b06059e5222e91eb640caad0aba15b7f"), - ("i140703-001_cross_spectrum_of_channel_1_and_2_of_slice_" - "TS_ON_to_GO_ON_corect_trials.mat", - "2687ef63a4a456971a5dcc621b02e9a9") + ( + "i140703-001_ch01_slice_TS_ON_to_GO_ON_correct_trials.mat", + "0e76454c58208cab710e672d04de5168", + ), + ( + "i140703-001_ch02_slice_TS_ON_to_GO_ON_correct_trials.mat", + "b06059e5222e91eb640caad0aba15b7f", + ), + ( + "i140703-001_cross_spectrum_of_channel_1_and_2_of_slice_" + "TS_ON_to_GO_ON_corect_trials.mat", + "2687ef63a4a456971a5dcc621b02e9a9", + ), ) for filename, checksum in cls.files_to_download_real: # files will be downloaded to ELEPHANT_TMP_DIR cls.tmp_path[filename] = { - 'filename':filename, - 'path':download_datasets( - f"{real_data_path}/{filename}", checksum=checksum)} + "filename": filename, + "path": download_datasets( + f"{real_data_path}/{filename}", checksum=checksum + ), + } # ARTIFICIAL DATA - artificial_data_path = "unittest/phase_analysis/" \ + artificial_data_path = ( + "unittest/phase_analysis/" "weighted_phase_lag_index/data/wpli_specific_artificial_dataset" + ) cls.files_to_download_artificial = ( ("artificial_LFPs_1.mat", "4b99b15f89c0b9a0eb6fc14e9009436f"), ("artificial_LFPs_2.mat", "7144976b5f871fa62f4a831f530deee4"), @@ -413,24 +477,36 @@ def setUpClass(cls): for filename, checksum in cls.files_to_download_artificial: # files will be downloaded to ELEPHANT_TMP_DIR cls.tmp_path[filename] = { - 'filename':filename, - 'path':download_datasets( - f"{artificial_data_path}/{filename}", checksum=checksum)} + "filename": filename, + "path": download_datasets( + f"{artificial_data_path}/{filename}", checksum=checksum + ), + } # GROUND TRUTH DATA - ground_truth_data_path = "unittest/phase_analysis/" \ - "weighted_phase_lag_index/data/wpli_ground_truth" + ground_truth_data_path = ( + "unittest/phase_analysis/" + "weighted_phase_lag_index/data/wpli_ground_truth" + ) cls.files_to_download_ground_truth = ( - ("ground_truth_WPLI_from_ft_connectivity_wpli_" - "with_real_LFPs_R2G.csv", "4d9a7b7afab7d107023956077ab11fef"), - ("ground_truth_WPLI_from_ft_connectivity_wpli_" - "with_artificial_LFPs.csv", "92988f475333d7badbe06b3f23abe494"), + ( + "ground_truth_WPLI_from_ft_connectivity_wpli_" + "with_real_LFPs_R2G.csv", + "4d9a7b7afab7d107023956077ab11fef", + ), + ( + "ground_truth_WPLI_from_ft_connectivity_wpli_" + "with_artificial_LFPs.csv", + "92988f475333d7badbe06b3f23abe494", + ), ) for filename, checksum in cls.files_to_download_ground_truth: # files will be downloaded into ELEPHANT_TMP_DIR cls.tmp_path[filename] = { - 'filename':filename, - 'path':download_datasets( - f"{ground_truth_data_path}/{filename}", checksum=checksum)} + "filename": filename, + "path": download_datasets( + f"{ground_truth_data_path}/{filename}", checksum=checksum + ), + } def setUp(self): self.tolerance = 1e-15 @@ -439,46 +515,60 @@ def setUp(self): # real LFP-dataset dataset1_real = scipy.io.loadmat( f"{self.tmp_path[self.files_to_download_real[0][0]]['path']}", - squeeze_me=True) + squeeze_me=True, + ) dataset2_real = scipy.io.loadmat( f"{self.tmp_path[self.files_to_download_real[1][0]]['path']}", - squeeze_me=True) + squeeze_me=True, + ) # get relevant values - self.lfps1_real = dataset1_real['lfp_matrix'] * pq.uV - self.sf1_real = dataset1_real['sf'] * pq.Hz - self.lfps2_real = dataset2_real['lfp_matrix'] * pq.uV - self.sf2_real = dataset2_real['sf'] * pq.Hz + self.lfps1_real = dataset1_real["lfp_matrix"] * pq.uV + self.sf1_real = dataset1_real["sf"] * pq.Hz + self.lfps2_real = dataset2_real["lfp_matrix"] * pq.uV + self.sf2_real = dataset2_real["sf"] * pq.Hz # create AnalogSignals from the real dataset self.lfps1_real_AnalogSignal = AnalogSignal( - signal=self.lfps1_real, sampling_rate=self.sf1_real) + signal=self.lfps1_real, sampling_rate=self.sf1_real + ) self.lfps2_real_AnalogSignal = AnalogSignal( - signal=self.lfps2_real, sampling_rate=self.sf2_real) + signal=self.lfps2_real, sampling_rate=self.sf2_real + ) # artificial LFP-dataset dataset1_artificial = scipy.io.loadmat( - f"{self.tmp_path[self.files_to_download_artificial[0][0]]['path']}", squeeze_me=True) + f"{self.tmp_path[self.files_to_download_artificial[0][0]]['path']}", + squeeze_me=True, + ) dataset2_artificial = scipy.io.loadmat( - f"{self.tmp_path[self.files_to_download_artificial[1][0]]['path']}", squeeze_me=True) + f"{self.tmp_path[self.files_to_download_artificial[1][0]]['path']}", + squeeze_me=True, + ) # get relevant values - self.lfps1_artificial = dataset1_artificial['lfp_matrix'] * pq.uV - self.sf1_artificial = dataset1_artificial['sf'] * pq.Hz - self.lfps2_artificial = dataset2_artificial['lfp_matrix'] * pq.uV - self.sf2_artificial = dataset2_artificial['sf'] * pq.Hz + self.lfps1_artificial = dataset1_artificial["lfp_matrix"] * pq.uV + self.sf1_artificial = dataset1_artificial["sf"] * pq.Hz + self.lfps2_artificial = dataset2_artificial["lfp_matrix"] * pq.uV + self.sf2_artificial = dataset2_artificial["sf"] * pq.Hz # create AnalogSignals from the artificial dataset self.lfps1_artificial_AnalogSignal = AnalogSignal( - signal=self.lfps1_artificial, sampling_rate=self.sf1_artificial) + signal=self.lfps1_artificial, sampling_rate=self.sf1_artificial + ) self.lfps2_artificial_AnalogSignal = AnalogSignal( - signal=self.lfps2_artificial, sampling_rate=self.sf2_artificial) + signal=self.lfps2_artificial, sampling_rate=self.sf2_artificial + ) # load ground-truth reference calculated by: # Matlab package 'FieldTrip': ft_connectivity_wpli() self.wpli_ground_truth_ft_connectivity_wpli_real = np.loadtxt( f"{self.tmp_path[self.files_to_download_ground_truth[0][0]]['path']}", - delimiter=',', dtype=np.float64) + delimiter=",", + dtype=np.float64, + ) self.wpli_ground_truth_ft_connectivity_artificial = np.loadtxt( f"{self.tmp_path[self.files_to_download_ground_truth[1][0]]['path']}", - delimiter=',', dtype=np.float64) + delimiter=",", + dtype=np.float64, + ) def test_WPLI_ground_truth_consistency_real_LFP_dataset(self): """ @@ -496,25 +586,35 @@ def test_WPLI_ground_truth_consistency_real_LFP_dataset(self): # Quantity-input with self.subTest(msg="Quantity input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( - self.lfps1_real, self.lfps2_real, self.sf1_real) + self.lfps1_real, self.lfps2_real, self.sf1_real + ) np.testing.assert_allclose( - wpli, self.wpli_ground_truth_ft_connectivity_wpli_real, - equal_nan=True) + wpli, + self.wpli_ground_truth_ft_connectivity_wpli_real, + equal_nan=True, + ) # np.array-input with self.subTest(msg="np.array input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( - self.lfps1_real.magnitude, self.lfps2_real.magnitude, - self.sf1_real) + self.lfps1_real.magnitude, + self.lfps2_real.magnitude, + self.sf1_real, + ) np.testing.assert_allclose( - wpli, self.wpli_ground_truth_ft_connectivity_wpli_real, - equal_nan=True) + wpli, + self.wpli_ground_truth_ft_connectivity_wpli_real, + equal_nan=True, + ) # neo.AnalogSignal-input with self.subTest(msg="neo.AnalogSignal input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( - self.lfps1_real_AnalogSignal, self.lfps2_real_AnalogSignal) + self.lfps1_real_AnalogSignal, self.lfps2_real_AnalogSignal + ) np.testing.assert_allclose( - wpli, self.wpli_ground_truth_ft_connectivity_wpli_real, - equal_nan=True) + wpli, + self.wpli_ground_truth_ft_connectivity_wpli_real, + equal_nan=True, + ) def test_WPLI_ground_truth_consistency_artificial_LFP_dataset(self): """ @@ -529,28 +629,47 @@ def test_WPLI_ground_truth_consistency_artificial_LFP_dataset(self): # Quantity-input with self.subTest(msg="Quantity input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( - self.lfps1_artificial, self.lfps2_artificial, - self.sf1_artificial, absolute_value=False) + self.lfps1_artificial, + self.lfps2_artificial, + self.sf1_artificial, + absolute_value=False, + ) np.testing.assert_allclose( - wpli, self.wpli_ground_truth_ft_connectivity_artificial, - atol=1e-14, rtol=1e-12, equal_nan=True) + wpli, + self.wpli_ground_truth_ft_connectivity_artificial, + atol=1e-14, + rtol=1e-12, + equal_nan=True, + ) # np.array-input with self.subTest(msg="np.array input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( self.lfps1_artificial.magnitude, - self.lfps2_artificial.magnitude, self.sf1_artificial, - absolute_value=False) + self.lfps2_artificial.magnitude, + self.sf1_artificial, + absolute_value=False, + ) np.testing.assert_allclose( - wpli, self.wpli_ground_truth_ft_connectivity_artificial, - atol=1e-14, rtol=1e-12, equal_nan=True) + wpli, + self.wpli_ground_truth_ft_connectivity_artificial, + atol=1e-14, + rtol=1e-12, + equal_nan=True, + ) # neo.AnalogSignal-input with self.subTest(msg="neo.AnalogSignal input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( self.lfps1_artificial_AnalogSignal, - self.lfps2_artificial_AnalogSignal, absolute_value=False) + self.lfps2_artificial_AnalogSignal, + absolute_value=False, + ) np.testing.assert_allclose( - wpli, self.wpli_ground_truth_ft_connectivity_artificial, - atol=1e-14, rtol=1e-12, equal_nan=True) + wpli, + self.wpli_ground_truth_ft_connectivity_artificial, + atol=1e-14, + rtol=1e-12, + equal_nan=True, + ) def test_WPLI_is_zero(self): """ @@ -560,25 +679,35 @@ def test_WPLI_is_zero(self): # Quantity-input with self.subTest(msg="Quantity input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( - self.lfps1_artificial, self.lfps2_artificial, - self.sf1_artificial, absolute_value=False) + self.lfps1_artificial, + self.lfps2_artificial, + self.sf1_artificial, + absolute_value=False, + ) np.testing.assert_allclose( - wpli[freq == 70], 0, atol=0.004, rtol=self.tolerance) + wpli[freq == 70], 0, atol=0.004, rtol=self.tolerance + ) # np.array-input with self.subTest(msg="np.array input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( self.lfps1_artificial.magnitude, - self.lfps2_artificial.magnitude, self.sf1_artificial, - absolute_value=False) + self.lfps2_artificial.magnitude, + self.sf1_artificial, + absolute_value=False, + ) np.testing.assert_allclose( - wpli[freq == 70], 0, atol=0.004, rtol=self.tolerance) + wpli[freq == 70], 0, atol=0.004, rtol=self.tolerance + ) # neo.AnalogSignal-input with self.subTest(msg="neo.AnalogSignal input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( self.lfps1_artificial_AnalogSignal, - self.lfps2_artificial_AnalogSignal, absolute_value=False) + self.lfps2_artificial_AnalogSignal, + absolute_value=False, + ) np.testing.assert_allclose( - wpli[freq == 70], 0, atol=0.004, rtol=self.tolerance) + wpli[freq == 70], 0, atol=0.004, rtol=self.tolerance + ) def test_WPLI_is_one(self): """ @@ -588,28 +717,38 @@ def test_WPLI_is_one(self): # Quantity-input with self.subTest(msg="Quantity input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( - self.lfps1_artificial, self.lfps2_artificial, - self.sf1_artificial, absolute_value=False) - mask = ((freq == 16) | (freq == 36)) + self.lfps1_artificial, + self.lfps2_artificial, + self.sf1_artificial, + absolute_value=False, + ) + mask = (freq == 16) | (freq == 36) np.testing.assert_allclose( - wpli[mask], 1, atol=self.tolerance, rtol=self.tolerance) + wpli[mask], 1, atol=self.tolerance, rtol=self.tolerance + ) # np.array-input with self.subTest(msg="np.array input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( self.lfps1_artificial.magnitude, - self.lfps2_artificial.magnitude, self.sf1_artificial, - absolute_value=False) - mask = ((freq == 16) | (freq == 36)) + self.lfps2_artificial.magnitude, + self.sf1_artificial, + absolute_value=False, + ) + mask = (freq == 16) | (freq == 36) np.testing.assert_allclose( - wpli[mask], 1, atol=self.tolerance, rtol=self.tolerance) + wpli[mask], 1, atol=self.tolerance, rtol=self.tolerance + ) # neo.AnalogSignal-input with self.subTest(msg="neo.AnalogSignal input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( self.lfps1_artificial_AnalogSignal, - self.lfps2_artificial_AnalogSignal, absolute_value=False) - mask = ((freq == 16) | (freq == 36)) + self.lfps2_artificial_AnalogSignal, + absolute_value=False, + ) + mask = (freq == 16) | (freq == 36) np.testing.assert_allclose( - wpli[mask], 1, atol=self.tolerance, rtol=self.tolerance) + wpli[mask], 1, atol=self.tolerance, rtol=self.tolerance + ) def test_WPLI_is_minus_one(self): """ @@ -619,26 +758,36 @@ def test_WPLI_is_minus_one(self): # Quantity-input with self.subTest(msg="Quantity input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( - self.lfps1_artificial, self.lfps2_artificial, - self.sf1_artificial, absolute_value=False) - mask = ((freq == 52) | (freq == 100)) + self.lfps1_artificial, + self.lfps2_artificial, + self.sf1_artificial, + absolute_value=False, + ) + mask = (freq == 52) | (freq == 100) np.testing.assert_allclose( - wpli[mask], -1, atol=self.tolerance, rtol=self.tolerance) + wpli[mask], -1, atol=self.tolerance, rtol=self.tolerance + ) # np.array-input with self.subTest(msg="np.array input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( self.lfps1_artificial.magnitude, - self.lfps2_artificial.magnitude, self.sf1_artificial, - absolute_value=False) + self.lfps2_artificial.magnitude, + self.sf1_artificial, + absolute_value=False, + ) np.testing.assert_allclose( - wpli[mask], -1, atol=self.tolerance, rtol=self.tolerance) + wpli[mask], -1, atol=self.tolerance, rtol=self.tolerance + ) # neo.AnalogSignal-input with self.subTest(msg="neo.AnalogSignal input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( self.lfps1_artificial_AnalogSignal, - self.lfps2_artificial_AnalogSignal, absolute_value=False) + self.lfps2_artificial_AnalogSignal, + absolute_value=False, + ) np.testing.assert_allclose( - wpli[mask], -1, atol=self.tolerance, rtol=self.tolerance) + wpli[mask], -1, atol=self.tolerance, rtol=self.tolerance + ) def test_WPLI_raises_error_if_signals_have_different_shapes(self): """ @@ -651,40 +800,63 @@ def test_WPLI_raises_error_if_signals_have_different_shapes(self): trials1_length4 = np.array([[0, 1, 1 / 2, -1]]) * pq.uV sampling_frequency = 250 * pq.Hz trials2_length3_analogsignal = AnalogSignal( - signal=trials2_length3, sampling_rate=sampling_frequency) + signal=trials2_length3, sampling_rate=sampling_frequency + ) trials1_length3_analogsignal = AnalogSignal( - signal=trials1_length3, sampling_rate=sampling_frequency) + signal=trials1_length3, sampling_rate=sampling_frequency + ) trials1_length4_analogsignal = AnalogSignal( - signal=trials1_length4, sampling_rate=sampling_frequency) + signal=trials1_length4, sampling_rate=sampling_frequency + ) # different numbers of trails with self.subTest(msg="diff. trial numbers & Quantity input"): np.testing.assert_raises( - ValueError, elephant.phase_analysis.weighted_phase_lag_index, - trials2_length3, trials1_length3, sampling_frequency) + ValueError, + elephant.phase_analysis.weighted_phase_lag_index, + trials2_length3, + trials1_length3, + sampling_frequency, + ) with self.subTest(msg="diff. trial numbers & np.array input"): np.testing.assert_raises( - ValueError, elephant.phase_analysis.weighted_phase_lag_index, - trials2_length3.magnitude, trials1_length3.magnitude, - sampling_frequency) + ValueError, + elephant.phase_analysis.weighted_phase_lag_index, + trials2_length3.magnitude, + trials1_length3.magnitude, + sampling_frequency, + ) with self.subTest(msg="diff. trial numbers & neo.AnalogSignal input"): np.testing.assert_raises( - ValueError, elephant.phase_analysis.weighted_phase_lag_index, - trials2_length3_analogsignal, trials1_length3_analogsignal) + ValueError, + elephant.phase_analysis.weighted_phase_lag_index, + trials2_length3_analogsignal, + trials1_length3_analogsignal, + ) # different lengths in a trail pair with self.subTest(msg="diff. trial lengths & Quantity input"): np.testing.assert_raises( - ValueError, elephant.phase_analysis.weighted_phase_lag_index, - trials1_length3, trials1_length4, sampling_frequency) + ValueError, + elephant.phase_analysis.weighted_phase_lag_index, + trials1_length3, + trials1_length4, + sampling_frequency, + ) with self.subTest(msg="diff. trial lengths & np.array input"): np.testing.assert_raises( - ValueError, elephant.phase_analysis.weighted_phase_lag_index, - trials1_length3.magnitude, trials1_length4.magnitude, - sampling_frequency) + ValueError, + elephant.phase_analysis.weighted_phase_lag_index, + trials1_length3.magnitude, + trials1_length4.magnitude, + sampling_frequency, + ) with self.subTest(msg="diff. trial lengths & neo.AnalogSignal input"): np.testing.assert_raises( - ValueError, elephant.phase_analysis.weighted_phase_lag_index, - trials1_length3_analogsignal, trials1_length4_analogsignal) + ValueError, + elephant.phase_analysis.weighted_phase_lag_index, + trials1_length3_analogsignal, + trials1_length4_analogsignal, + ) @staticmethod def test_WPLI_raises_error_if_AnalogSignals_have_diff_sampling_rate(): @@ -692,13 +864,22 @@ def test_WPLI_raises_error_if_AnalogSignals_have_diff_sampling_rate(): Test if WPLI raises a ValueError, when the AnalogSignals have different sampling rates. """ - signal_x_250_hz = AnalogSignal(signal=np.random.random([40, 2100]), - units=pq.mV, sampling_rate=0.25*pq.kHz) - signal_y_1000_hz = AnalogSignal(signal=np.random.random([40, 2100]), - units=pq.mV, sampling_rate=1000*pq.Hz) + signal_x_250_hz = AnalogSignal( + signal=np.random.random([40, 2100]), + units=pq.mV, + sampling_rate=0.25 * pq.kHz, + ) + signal_y_1000_hz = AnalogSignal( + signal=np.random.random([40, 2100]), + units=pq.mV, + sampling_rate=1000 * pq.Hz, + ) np.testing.assert_raises( - ValueError, elephant.phase_analysis.weighted_phase_lag_index, - signal_x_250_hz, signal_y_1000_hz) + ValueError, + elephant.phase_analysis.weighted_phase_lag_index, + signal_x_250_hz, + signal_y_1000_hz, + ) def test_WPLI_raises_error_if_sampling_rate_not_given(self): """ @@ -709,13 +890,19 @@ def test_WPLI_raises_error_if_sampling_rate_not_given(self): signal_y = np.random.random([40, 2100]) * pq.mV with self.subTest(msg="Quantity-input"): np.testing.assert_raises( - ValueError, elephant.phase_analysis.weighted_phase_lag_index, - signal_x, signal_y) + ValueError, + elephant.phase_analysis.weighted_phase_lag_index, + signal_x, + signal_y, + ) with self.subTest(msg="np.array-input"): np.testing.assert_raises( - ValueError, elephant.phase_analysis.weighted_phase_lag_index, - signal_x.magnitude, signal_y.magnitude) + ValueError, + elephant.phase_analysis.weighted_phase_lag_index, + signal_x.magnitude, + signal_y.magnitude, + ) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() From e2382e6dc658b50249ac9e6063b60850bb1e4f0c Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 25 Apr 2024 14:56:58 +0200 Subject: [PATCH 23/84] fix pep8 test_spectral --- elephant/test/test_spectral.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elephant/test/test_spectral.py b/elephant/test/test_spectral.py index e11a55225..00cdd6941 100644 --- a/elephant/test/test_spectral.py +++ b/elephant/test/test_spectral.py @@ -277,7 +277,7 @@ def test_multitaper_psd_against_nitime(self): ("time_series.npy", "ff43797e2ac94613f510b20a31e2e80e"), ("psd_nitime.npy", "89d1f53957e66c786049ea425b53c0e8") ] - + downloaded_files = {} for filename, checksum in files_to_download: downloaded_files[filename] = { From 7791e5226378b0d77e83374357c31af91833ba95 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 25 Apr 2024 14:57:45 +0200 Subject: [PATCH 24/84] fix pep8 test_spike_train_dissimilarity --- .../test/test_spike_train_dissimilarity.py | 1243 +++++++++++------ 1 file changed, 818 insertions(+), 425 deletions(-) diff --git a/elephant/test/test_spike_train_dissimilarity.py b/elephant/test/test_spike_train_dissimilarity.py index 5cff9e987..a378f08d0 100644 --- a/elephant/test/test_spike_train_dissimilarity.py +++ b/elephant/test/test_spike_train_dissimilarity.py @@ -20,38 +20,39 @@ class TimeScaleDependSpikeTrainDissimMeasuresTestCase(unittest.TestCase): def setUp(self): - self.st00 = SpikeTrain([], units='ms', t_stop=1000.0) - self.st01 = SpikeTrain([1], units='ms', t_stop=1000.0) - self.st02 = SpikeTrain([2], units='ms', t_stop=1000.0) - self.st03 = SpikeTrain([2.9], units='ms', t_stop=1000.0) - self.st04 = SpikeTrain([3.1], units='ms', t_stop=1000.0) - self.st05 = SpikeTrain([5], units='ms', t_stop=1000.0) - self.st06 = SpikeTrain([500], units='ms', t_stop=1000.0) - self.st07 = SpikeTrain([12, 32], units='ms', t_stop=1000.0) - self.st08 = SpikeTrain([32, 52], units='ms', t_stop=1000.0) - self.st09 = SpikeTrain([42], units='ms', t_stop=1000.0) - self.st10 = SpikeTrain([18, 60], units='ms', t_stop=1000.0) - self.st11 = SpikeTrain([10, 20, 30, 40], units='ms', t_stop=1000.0) - self.st12 = SpikeTrain([40, 30, 20, 10], units='ms', t_stop=1000.0) - self.st13 = SpikeTrain([15, 25, 35, 45], units='ms', t_stop=1000.0) - self.st14 = SpikeTrain([10, 20, 30, 40, 50], units='ms', t_stop=1000.0) - self.st15 = SpikeTrain([0.01, 0.02, 0.03, 0.04, 0.05], - units='s', t_stop=1000.0) - self.st16 = SpikeTrain([12, 16, 28, 30, 42], units='ms', t_stop=1000.0) - self.st21 = StationaryPoissonProcess(rate=50 * Hz, t_start=0 * ms, - t_stop=1000 * ms - ).generate_spiketrain() - self.st22 = StationaryPoissonProcess(rate=40 * Hz, t_start=0 * ms, - t_stop=1000 * ms - ).generate_spiketrain() - self.st23 = StationaryPoissonProcess(rate=30 * Hz, t_start=0 * ms, - t_stop=1000 * ms - ).generate_spiketrain() + self.st00 = SpikeTrain([], units="ms", t_stop=1000.0) + self.st01 = SpikeTrain([1], units="ms", t_stop=1000.0) + self.st02 = SpikeTrain([2], units="ms", t_stop=1000.0) + self.st03 = SpikeTrain([2.9], units="ms", t_stop=1000.0) + self.st04 = SpikeTrain([3.1], units="ms", t_stop=1000.0) + self.st05 = SpikeTrain([5], units="ms", t_stop=1000.0) + self.st06 = SpikeTrain([500], units="ms", t_stop=1000.0) + self.st07 = SpikeTrain([12, 32], units="ms", t_stop=1000.0) + self.st08 = SpikeTrain([32, 52], units="ms", t_stop=1000.0) + self.st09 = SpikeTrain([42], units="ms", t_stop=1000.0) + self.st10 = SpikeTrain([18, 60], units="ms", t_stop=1000.0) + self.st11 = SpikeTrain([10, 20, 30, 40], units="ms", t_stop=1000.0) + self.st12 = SpikeTrain([40, 30, 20, 10], units="ms", t_stop=1000.0) + self.st13 = SpikeTrain([15, 25, 35, 45], units="ms", t_stop=1000.0) + self.st14 = SpikeTrain([10, 20, 30, 40, 50], units="ms", t_stop=1000.0) + self.st15 = SpikeTrain( + [0.01, 0.02, 0.03, 0.04, 0.05], units="s", t_stop=1000.0 + ) + self.st16 = SpikeTrain([12, 16, 28, 30, 42], units="ms", t_stop=1000.0) + self.st21 = StationaryPoissonProcess( + rate=50 * Hz, t_start=0 * ms, t_stop=1000 * ms + ).generate_spiketrain() + self.st22 = StationaryPoissonProcess( + rate=40 * Hz, t_start=0 * ms, t_stop=1000 * ms + ).generate_spiketrain() + self.st23 = StationaryPoissonProcess( + rate=30 * Hz, t_start=0 * ms, t_stop=1000 * ms + ).generate_spiketrain() self.rd_st_list = [self.st21, self.st22, self.st23] - self.st31 = SpikeTrain([12.0], units='ms', t_stop=1000.0) - self.st32 = SpikeTrain([12.0, 12.0], units='ms', t_stop=1000.0) - self.st33 = SpikeTrain([20.0], units='ms', t_stop=1000.0) - self.st34 = SpikeTrain([20.0, 20.0], units='ms', t_stop=1000.0) + self.st31 = SpikeTrain([12.0], units="ms", t_stop=1000.0) + self.st32 = SpikeTrain([12.0, 12.0], units="ms", t_stop=1000.0) + self.st33 = SpikeTrain([20.0], units="ms", t_stop=1000.0) + self.st34 = SpikeTrain([20.0, 20.0], units="ms", t_stop=1000.0) self.array1 = np.arange(1, 10) self.array2 = np.arange(1.2, 10) self.qarray1 = self.array1 * Hz @@ -75,479 +76,855 @@ def setUp(self): self.t = np.linspace(0, 200, 20000001) * ms def test_wrong_input(self): - self.assertRaises(TypeError, stds.victor_purpura_distance, - [self.array1, self.array2], self.q3) - self.assertRaises(TypeError, stds.victor_purpura_distance, - [self.qarray1, self.qarray2], self.q3) - self.assertRaises(TypeError, stds.victor_purpura_distance, - [self.qarray1, self.qarray2], 5.0 * ms) - - self.assertRaises(TypeError, stds.victor_purpura_distance, - [self.array1, self.array2], self.q3, - algorithm='intuitive') - self.assertRaises(TypeError, stds.victor_purpura_distance, - [self.qarray1, self.qarray2], self.q3, - algorithm='intuitive') - self.assertRaises(TypeError, stds.victor_purpura_distance, - [self.qarray1, self.qarray2], 5.0 * ms, - algorithm='intuitive') - - self.assertRaises(TypeError, stds.van_rossum_distance, - [self.array1, self.array2], self.tau3) - self.assertRaises(TypeError, stds.van_rossum_distance, - [self.qarray1, self.qarray2], self.tau3) - self.assertRaises(TypeError, stds.van_rossum_distance, - [self.qarray1, self.qarray2], 5.0 * Hz) - - self.assertRaises(TypeError, stds.victor_purpura_distance, - [self.st11, self.st13], self.tau2) - self.assertRaises(TypeError, stds.victor_purpura_distance, - [self.st11, self.st13], 5.0) - self.assertRaises(TypeError, stds.victor_purpura_distance, - [self.st11, self.st13], self.tau2, - algorithm='intuitive') - self.assertRaises(TypeError, stds.victor_purpura_distance, - [self.st11, self.st13], 5.0, - algorithm='intuitive') - self.assertRaises(TypeError, stds.van_rossum_distance, - [self.st11, self.st13], self.q4) - self.assertRaises(TypeError, stds.van_rossum_distance, - [self.st11, self.st13], 5.0) - - self.assertRaises(NotImplementedError, stds.victor_purpura_distance, - [self.st01, self.st02], self.q3, - kernel=kernels.Kernel(2.0 / self.q3)) - self.assertRaises(NotImplementedError, stds.victor_purpura_distance, - [self.st01, self.st02], self.q3, - kernel=kernels.SymmetricKernel(2.0 / self.q3)) - self.assertEqual(stds.victor_purpura_distance( - [self.st01, self.st02], self.q1, - kernel=kernels.TriangularKernel( - 2.0 / (np.sqrt(6.0) * self.q2)))[0, 1], - stds.victor_purpura_distance( - [self.st01, self.st02], self.q3, - kernel=kernels.TriangularKernel( - 2.0 / (np.sqrt(6.0) * self.q2)))[0, 1]) - self.assertEqual(stds.victor_purpura_distance( + self.assertRaises( + TypeError, + stds.victor_purpura_distance, + [self.array1, self.array2], + self.q3, + ) + self.assertRaises( + TypeError, + stds.victor_purpura_distance, + [self.qarray1, self.qarray2], + self.q3, + ) + self.assertRaises( + TypeError, + stds.victor_purpura_distance, + [self.qarray1, self.qarray2], + 5.0 * ms, + ) + + self.assertRaises( + TypeError, + stds.victor_purpura_distance, + [self.array1, self.array2], + self.q3, + algorithm="intuitive", + ) + self.assertRaises( + TypeError, + stds.victor_purpura_distance, + [self.qarray1, self.qarray2], + self.q3, + algorithm="intuitive", + ) + self.assertRaises( + TypeError, + stds.victor_purpura_distance, + [self.qarray1, self.qarray2], + 5.0 * ms, + algorithm="intuitive", + ) + + self.assertRaises( + TypeError, + stds.van_rossum_distance, + [self.array1, self.array2], + self.tau3, + ) + self.assertRaises( + TypeError, + stds.van_rossum_distance, + [self.qarray1, self.qarray2], + self.tau3, + ) + self.assertRaises( + TypeError, + stds.van_rossum_distance, + [self.qarray1, self.qarray2], + 5.0 * Hz, + ) + + self.assertRaises( + TypeError, + stds.victor_purpura_distance, + [self.st11, self.st13], + self.tau2, + ) + self.assertRaises( + TypeError, + stds.victor_purpura_distance, + [self.st11, self.st13], + 5.0, + ) + self.assertRaises( + TypeError, + stds.victor_purpura_distance, + [self.st11, self.st13], + self.tau2, + algorithm="intuitive", + ) + self.assertRaises( + TypeError, + stds.victor_purpura_distance, + [self.st11, self.st13], + 5.0, + algorithm="intuitive", + ) + self.assertRaises( + TypeError, + stds.van_rossum_distance, + [self.st11, self.st13], + self.q4, + ) + self.assertRaises( + TypeError, stds.van_rossum_distance, [self.st11, self.st13], 5.0 + ) + + self.assertRaises( + NotImplementedError, + stds.victor_purpura_distance, [self.st01, self.st02], - kernel=kernels.TriangularKernel( - 2.0 / (np.sqrt(6.0) * self.q2)))[0, 1], 1.0) - self.assertNotEqual(stds.victor_purpura_distance( + self.q3, + kernel=kernels.Kernel(2.0 / self.q3), + ) + self.assertRaises( + NotImplementedError, + stds.victor_purpura_distance, [self.st01, self.st02], - kernel=kernels.AlphaKernel( - 2.0 / (np.sqrt(6.0) * self.q2)))[0, 1], 1.0) - - self.assertRaises(NameError, stds.victor_purpura_distance, - [self.st11, self.st13], self.q2, algorithm='slow') + self.q3, + kernel=kernels.SymmetricKernel(2.0 / self.q3), + ) + self.assertEqual( + stds.victor_purpura_distance( + [self.st01, self.st02], + self.q1, + kernel=kernels.TriangularKernel( + 2.0 / (np.sqrt(6.0) * self.q2) + ), + )[0, 1], + stds.victor_purpura_distance( + [self.st01, self.st02], + self.q3, + kernel=kernels.TriangularKernel( + 2.0 / (np.sqrt(6.0) * self.q2) + ), + )[0, 1], + ) + self.assertEqual( + stds.victor_purpura_distance( + [self.st01, self.st02], + kernel=kernels.TriangularKernel( + 2.0 / (np.sqrt(6.0) * self.q2) + ), + )[0, 1], + 1.0, + ) + self.assertNotEqual( + stds.victor_purpura_distance( + [self.st01, self.st02], + kernel=kernels.AlphaKernel(2.0 / (np.sqrt(6.0) * self.q2)), + )[0, 1], + 1.0, + ) + + self.assertRaises( + NameError, + stds.victor_purpura_distance, + [self.st11, self.st13], + self.q2, + algorithm="slow", + ) def test_victor_purpura_distance_fast(self): # Tests of distances of simplest spike trains: - self.assertEqual(stds.victor_purpura_distance( - [self.st00, self.st00], self.q2)[0, 1], 0.0) - self.assertEqual(stds.victor_purpura_distance( - [self.st00, self.st01], self.q2)[0, 1], 1.0) - self.assertEqual(stds.victor_purpura_distance( - [self.st01, self.st00], self.q2)[0, 1], 1.0) - self.assertEqual(stds.victor_purpura_distance( - [self.st01, self.st01], self.q2)[0, 1], 0.0) + self.assertEqual( + stds.victor_purpura_distance([self.st00, self.st00], self.q2)[ + 0, 1 + ], + 0.0, + ) + self.assertEqual( + stds.victor_purpura_distance([self.st00, self.st01], self.q2)[ + 0, 1 + ], + 1.0, + ) + self.assertEqual( + stds.victor_purpura_distance([self.st01, self.st00], self.q2)[ + 0, 1 + ], + 1.0, + ) + self.assertEqual( + stds.victor_purpura_distance([self.st01, self.st01], self.q2)[ + 0, 1 + ], + 0.0, + ) # Tests of distances under elementary spike operations - self.assertEqual(stds.victor_purpura_distance( - [self.st01, self.st02], self.q2)[0, 1], 1.0) - self.assertEqual(stds.victor_purpura_distance( - [self.st01, self.st03], self.q2)[0, 1], 1.9) - self.assertEqual(stds.victor_purpura_distance( - [self.st01, self.st04], self.q2)[0, 1], 2.0) - self.assertEqual(stds.victor_purpura_distance( - [self.st01, self.st05], self.q2)[0, 1], 2.0) - self.assertEqual(stds.victor_purpura_distance( - [self.st00, self.st07], self.q2)[0, 1], 2.0) - self.assertAlmostEqual(stds.victor_purpura_distance( - [self.st07, self.st08], self.q4)[0, 1], 0.4) - self.assertAlmostEqual(stds.victor_purpura_distance( - [self.st07, self.st10], self.q3)[0, 1], 0.6 + 2) - self.assertEqual(stds.victor_purpura_distance( - [self.st11, self.st14], self.q2)[0, 1], 1) + self.assertEqual( + stds.victor_purpura_distance([self.st01, self.st02], self.q2)[ + 0, 1 + ], + 1.0, + ) + self.assertEqual( + stds.victor_purpura_distance([self.st01, self.st03], self.q2)[ + 0, 1 + ], + 1.9, + ) + self.assertEqual( + stds.victor_purpura_distance([self.st01, self.st04], self.q2)[ + 0, 1 + ], + 2.0, + ) + self.assertEqual( + stds.victor_purpura_distance([self.st01, self.st05], self.q2)[ + 0, 1 + ], + 2.0, + ) + self.assertEqual( + stds.victor_purpura_distance([self.st00, self.st07], self.q2)[ + 0, 1 + ], + 2.0, + ) + self.assertAlmostEqual( + stds.victor_purpura_distance([self.st07, self.st08], self.q4)[ + 0, 1 + ], + 0.4, + ) + self.assertAlmostEqual( + stds.victor_purpura_distance([self.st07, self.st10], self.q3)[ + 0, 1 + ], + 0.6 + 2, + ) + self.assertEqual( + stds.victor_purpura_distance([self.st11, self.st14], self.q2)[ + 0, 1 + ], + 1, + ) # Tests on timescales - self.assertEqual(stds.victor_purpura_distance( - [self.st11, self.st14], self.q1)[0, 1], - stds.victor_purpura_distance( - [self.st11, self.st14], self.q5)[0, 1]) - self.assertEqual(stds.victor_purpura_distance( - [self.st07, self.st11], self.q0)[0, 1], 6.0) - self.assertEqual(stds.victor_purpura_distance( - [self.st07, self.st11], self.q1)[0, 1], 6.0) - self.assertAlmostEqual(stds.victor_purpura_distance( - [self.st07, self.st11], self.q5)[0, 1], 2.0, 5) - self.assertEqual(stds.victor_purpura_distance( - [self.st07, self.st11], self.q6)[0, 1], 2.0) + self.assertEqual( + stds.victor_purpura_distance([self.st11, self.st14], self.q1)[ + 0, 1 + ], + stds.victor_purpura_distance([self.st11, self.st14], self.q5)[ + 0, 1 + ], + ) + self.assertEqual( + stds.victor_purpura_distance([self.st07, self.st11], self.q0)[ + 0, 1 + ], + 6.0, + ) + self.assertEqual( + stds.victor_purpura_distance([self.st07, self.st11], self.q1)[ + 0, 1 + ], + 6.0, + ) + self.assertAlmostEqual( + stds.victor_purpura_distance([self.st07, self.st11], self.q5)[ + 0, 1 + ], + 2.0, + 5, + ) + self.assertEqual( + stds.victor_purpura_distance([self.st07, self.st11], self.q6)[ + 0, 1 + ], + 2.0, + ) # Tests on unordered spiketrains - self.assertEqual(stds.victor_purpura_distance( - [self.st11, self.st13], self.q4)[0, 1], - stds.victor_purpura_distance( - [self.st12, self.st13], self.q4)[0, 1]) - self.assertNotEqual(stds.victor_purpura_distance( - [self.st11, self.st13], self.q4, - sort=False)[0, 1], - stds.victor_purpura_distance( - [self.st12, self.st13], self.q4, - sort=False)[0, 1]) + self.assertEqual( + stds.victor_purpura_distance([self.st11, self.st13], self.q4)[ + 0, 1 + ], + stds.victor_purpura_distance([self.st12, self.st13], self.q4)[ + 0, 1 + ], + ) + self.assertNotEqual( + stds.victor_purpura_distance( + [self.st11, self.st13], self.q4, sort=False + )[0, 1], + stds.victor_purpura_distance( + [self.st12, self.st13], self.q4, sort=False + )[0, 1], + ) # Tests on metric properties with random spiketrains # (explicit calculation of second metric axiom in particular case, # because from dist_matrix it is trivial) dist_matrix = stds.victor_purpura_distance( - [self.st21, self.st22, self.st23], self.q3) + [self.st21, self.st22, self.st23], self.q3 + ) for i in range(3): for j in range(3): self.assertGreaterEqual(dist_matrix[i, j], 0) if dist_matrix[i, j] == 0: assert_array_equal(self.rd_st_list[i], self.rd_st_list[j]) - assert_array_equal(stds.victor_purpura_distance( - [self.st21, self.st22], self.q3), - stds.victor_purpura_distance( - [self.st22, self.st21], self.q3)) - self.assertLessEqual(dist_matrix[0, 1], - dist_matrix[0, 2] + dist_matrix[1, 2]) - self.assertLessEqual(dist_matrix[0, 2], - dist_matrix[1, 2] + dist_matrix[0, 1]) - self.assertLessEqual(dist_matrix[1, 2], - dist_matrix[0, 1] + dist_matrix[0, 2]) + assert_array_equal( + stds.victor_purpura_distance([self.st21, self.st22], self.q3), + stds.victor_purpura_distance([self.st22, self.st21], self.q3), + ) + self.assertLessEqual( + dist_matrix[0, 1], dist_matrix[0, 2] + dist_matrix[1, 2] + ) + self.assertLessEqual( + dist_matrix[0, 2], dist_matrix[1, 2] + dist_matrix[0, 1] + ) + self.assertLessEqual( + dist_matrix[1, 2], dist_matrix[0, 1] + dist_matrix[0, 2] + ) # Tests on proper unit conversion self.assertAlmostEqual( - stds.victor_purpura_distance([self.st14, self.st16], - self.q3)[0, 1], - stds.victor_purpura_distance([self.st15, self.st16], - self.q3)[0, 1]) + stds.victor_purpura_distance([self.st14, self.st16], self.q3)[ + 0, 1 + ], + stds.victor_purpura_distance([self.st15, self.st16], self.q3)[ + 0, 1 + ], + ) self.assertAlmostEqual( - stds.victor_purpura_distance([self.st16, self.st14], - self.q3)[0, 1], - stds.victor_purpura_distance([self.st16, self.st15], - self.q3)[0, 1]) + stds.victor_purpura_distance([self.st16, self.st14], self.q3)[ + 0, 1 + ], + stds.victor_purpura_distance([self.st16, self.st15], self.q3)[ + 0, 1 + ], + ) self.assertAlmostEqual( - stds.victor_purpura_distance([self.st01, self.st05], - self.q3)[0, 1], - stds.victor_purpura_distance([self.st01, self.st05], - self.q7)[0, 1]) + stds.victor_purpura_distance([self.st01, self.st05], self.q3)[ + 0, 1 + ], + stds.victor_purpura_distance([self.st01, self.st05], self.q7)[ + 0, 1 + ], + ) # Tests on algorithmic behaviour for equal spike times - self.assertAlmostEqual(stds.victor_purpura_distance( - [self.st31, self.st34], self.q3)[0, 1], 0.8 + 1.0) self.assertAlmostEqual( - stds.victor_purpura_distance([self.st31, self.st34], - self.q3)[0, 1], - stds.victor_purpura_distance([self.st32, self.st33], - self.q3)[0, 1]) + stds.victor_purpura_distance([self.st31, self.st34], self.q3)[ + 0, 1 + ], + 0.8 + 1.0, + ) self.assertAlmostEqual( - stds.victor_purpura_distance( - [self.st31, self.st33], self.q3)[0, 1] * 2.0, - stds.victor_purpura_distance( - [self.st32, self.st34], self.q3)[0, 1]) + stds.victor_purpura_distance([self.st31, self.st34], self.q3)[ + 0, 1 + ], + stds.victor_purpura_distance([self.st32, self.st33], self.q3)[ + 0, 1 + ], + ) + self.assertAlmostEqual( + stds.victor_purpura_distance([self.st31, self.st33], self.q3)[0, 1] + * 2.0, + stds.victor_purpura_distance([self.st32, self.st34], self.q3)[ + 0, 1 + ], + ) # Tests on spike train list lengthes smaller than 2 - self.assertEqual(stds.victor_purpura_distance( - [self.st21], self.q3)[0, 0], 0) + self.assertEqual( + stds.victor_purpura_distance([self.st21], self.q3)[0, 0], 0 + ) self.assertEqual(len(stds.victor_purpura_distance([], self.q3)), 0) def test_victor_purpura_distance_intuitive(self): # Tests of distances of simplest spike trains - self.assertEqual(stds.victor_purpura_distance( - [self.st00, self.st00], self.q2, - algorithm='intuitive')[0, 1], 0.0) - self.assertEqual(stds.victor_purpura_distance( - [self.st00, self.st01], self.q2, - algorithm='intuitive')[0, 1], 1.0) - self.assertEqual(stds.victor_purpura_distance( - [self.st01, self.st00], self.q2, - algorithm='intuitive')[0, 1], 1.0) - self.assertEqual(stds.victor_purpura_distance( - [self.st01, self.st01], self.q2, - algorithm='intuitive')[0, 1], 0.0) + self.assertEqual( + stds.victor_purpura_distance( + [self.st00, self.st00], self.q2, algorithm="intuitive" + )[0, 1], + 0.0, + ) + self.assertEqual( + stds.victor_purpura_distance( + [self.st00, self.st01], self.q2, algorithm="intuitive" + )[0, 1], + 1.0, + ) + self.assertEqual( + stds.victor_purpura_distance( + [self.st01, self.st00], self.q2, algorithm="intuitive" + )[0, 1], + 1.0, + ) + self.assertEqual( + stds.victor_purpura_distance( + [self.st01, self.st01], self.q2, algorithm="intuitive" + )[0, 1], + 0.0, + ) # Tests of distances under elementary spike operations - self.assertEqual(stds.victor_purpura_distance( - [self.st01, self.st02], self.q2, - algorithm='intuitive')[0, 1], 1.0) - self.assertEqual(stds.victor_purpura_distance( - [self.st01, self.st03], self.q2, - algorithm='intuitive')[0, 1], 1.9) - self.assertEqual(stds.victor_purpura_distance( - [self.st01, self.st04], self.q2, - algorithm='intuitive')[0, 1], 2.0) - self.assertEqual(stds.victor_purpura_distance( - [self.st01, self.st05], self.q2, - algorithm='intuitive')[0, 1], 2.0) - self.assertEqual(stds.victor_purpura_distance( - [self.st00, self.st07], self.q2, - algorithm='intuitive')[0, 1], 2.0) - self.assertAlmostEqual(stds.victor_purpura_distance( - [self.st07, self.st08], self.q4, - algorithm='intuitive')[0, 1], 0.4) - self.assertAlmostEqual(stds.victor_purpura_distance( - [self.st07, self.st10], self.q3, - algorithm='intuitive')[0, 1], 2.6) - self.assertEqual(stds.victor_purpura_distance( - [self.st11, self.st14], self.q2, - algorithm='intuitive')[0, 1], 1) + self.assertEqual( + stds.victor_purpura_distance( + [self.st01, self.st02], self.q2, algorithm="intuitive" + )[0, 1], + 1.0, + ) + self.assertEqual( + stds.victor_purpura_distance( + [self.st01, self.st03], self.q2, algorithm="intuitive" + )[0, 1], + 1.9, + ) + self.assertEqual( + stds.victor_purpura_distance( + [self.st01, self.st04], self.q2, algorithm="intuitive" + )[0, 1], + 2.0, + ) + self.assertEqual( + stds.victor_purpura_distance( + [self.st01, self.st05], self.q2, algorithm="intuitive" + )[0, 1], + 2.0, + ) + self.assertEqual( + stds.victor_purpura_distance( + [self.st00, self.st07], self.q2, algorithm="intuitive" + )[0, 1], + 2.0, + ) + self.assertAlmostEqual( + stds.victor_purpura_distance( + [self.st07, self.st08], self.q4, algorithm="intuitive" + )[0, 1], + 0.4, + ) + self.assertAlmostEqual( + stds.victor_purpura_distance( + [self.st07, self.st10], self.q3, algorithm="intuitive" + )[0, 1], + 2.6, + ) + self.assertEqual( + stds.victor_purpura_distance( + [self.st11, self.st14], self.q2, algorithm="intuitive" + )[0, 1], + 1, + ) # Tests on timescales - self.assertEqual(stds.victor_purpura_distance( - [self.st11, self.st14], self.q1, - algorithm='intuitive')[0, 1], - stds.victor_purpura_distance( - [self.st11, self.st14], self.q5, - algorithm='intuitive')[0, 1]) - self.assertEqual(stds.victor_purpura_distance( - [self.st07, self.st11], self.q0, - algorithm='intuitive')[0, 1], 6.0) - self.assertEqual(stds.victor_purpura_distance( - [self.st07, self.st11], self.q1, - algorithm='intuitive')[0, 1], 6.0) - self.assertAlmostEqual(stds.victor_purpura_distance( - [self.st07, self.st11], self.q5, - algorithm='intuitive')[0, 1], 2.0, 5) - self.assertEqual(stds.victor_purpura_distance( - [self.st07, self.st11], self.q6, - algorithm='intuitive')[0, 1], 2.0) + self.assertEqual( + stds.victor_purpura_distance( + [self.st11, self.st14], self.q1, algorithm="intuitive" + )[0, 1], + stds.victor_purpura_distance( + [self.st11, self.st14], self.q5, algorithm="intuitive" + )[0, 1], + ) + self.assertEqual( + stds.victor_purpura_distance( + [self.st07, self.st11], self.q0, algorithm="intuitive" + )[0, 1], + 6.0, + ) + self.assertEqual( + stds.victor_purpura_distance( + [self.st07, self.st11], self.q1, algorithm="intuitive" + )[0, 1], + 6.0, + ) + self.assertAlmostEqual( + stds.victor_purpura_distance( + [self.st07, self.st11], self.q5, algorithm="intuitive" + )[0, 1], + 2.0, + 5, + ) + self.assertEqual( + stds.victor_purpura_distance( + [self.st07, self.st11], self.q6, algorithm="intuitive" + )[0, 1], + 2.0, + ) # Tests on unordered spiketrains - self.assertEqual(stds.victor_purpura_distance( - [self.st11, self.st13], self.q4, - algorithm='intuitive')[0, 1], - stds.victor_purpura_distance( - [self.st12, self.st13], self.q4, - algorithm='intuitive')[0, 1]) - self.assertNotEqual(stds.victor_purpura_distance( - [self.st11, self.st13], self.q4, - sort=False, algorithm='intuitive')[0, 1], - stds.victor_purpura_distance( - [self.st12, self.st13], self.q4, - sort=False, algorithm='intuitive')[0, 1]) + self.assertEqual( + stds.victor_purpura_distance( + [self.st11, self.st13], self.q4, algorithm="intuitive" + )[0, 1], + stds.victor_purpura_distance( + [self.st12, self.st13], self.q4, algorithm="intuitive" + )[0, 1], + ) + self.assertNotEqual( + stds.victor_purpura_distance( + [self.st11, self.st13], + self.q4, + sort=False, + algorithm="intuitive", + )[0, 1], + stds.victor_purpura_distance( + [self.st12, self.st13], + self.q4, + sort=False, + algorithm="intuitive", + )[0, 1], + ) # Tests on metric properties with random spiketrains # (explicit calculation of second metric axiom in particular case, # because from dist_matrix it is trivial) dist_matrix = stds.victor_purpura_distance( - [self.st21, self.st22, self.st23], - self.q3, algorithm='intuitive') + [self.st21, self.st22, self.st23], self.q3, algorithm="intuitive" + ) for i in range(3): for j in range(3): self.assertGreaterEqual(dist_matrix[i, j], 0) if dist_matrix[i, j] == 0: assert_array_equal(self.rd_st_list[i], self.rd_st_list[j]) - assert_array_equal(stds.victor_purpura_distance( - [self.st21, self.st22], self.q3, - algorithm='intuitive'), - stds.victor_purpura_distance( - [self.st22, self.st21], self.q3, - algorithm='intuitive')) - self.assertLessEqual(dist_matrix[0, 1], - dist_matrix[0, 2] + dist_matrix[1, 2]) - self.assertLessEqual(dist_matrix[0, 2], - dist_matrix[1, 2] + dist_matrix[0, 1]) - self.assertLessEqual(dist_matrix[1, 2], - dist_matrix[0, 1] + dist_matrix[0, 2]) + assert_array_equal( + stds.victor_purpura_distance( + [self.st21, self.st22], self.q3, algorithm="intuitive" + ), + stds.victor_purpura_distance( + [self.st22, self.st21], self.q3, algorithm="intuitive" + ), + ) + self.assertLessEqual( + dist_matrix[0, 1], dist_matrix[0, 2] + dist_matrix[1, 2] + ) + self.assertLessEqual( + dist_matrix[0, 2], dist_matrix[1, 2] + dist_matrix[0, 1] + ) + self.assertLessEqual( + dist_matrix[1, 2], dist_matrix[0, 1] + dist_matrix[0, 2] + ) # Tests on proper unit conversion - self.assertAlmostEqual(stds.victor_purpura_distance( - [self.st14, self.st16], self.q3, - algorithm='intuitive')[0, 1], - stds.victor_purpura_distance( - [self.st15, self.st16], self.q3, - algorithm='intuitive')[0, 1]) - self.assertAlmostEqual(stds.victor_purpura_distance( - [self.st16, self.st14], self.q3, - algorithm='intuitive')[0, 1], - stds.victor_purpura_distance( - [self.st16, self.st15], self.q3, - algorithm='intuitive')[0, 1]) - self.assertEqual(stds.victor_purpura_distance( - [self.st01, self.st05], self.q3, - algorithm='intuitive')[0, 1], - stds.victor_purpura_distance( - [self.st01, self.st05], self.q7, - algorithm='intuitive')[0, 1]) + self.assertAlmostEqual( + stds.victor_purpura_distance( + [self.st14, self.st16], self.q3, algorithm="intuitive" + )[0, 1], + stds.victor_purpura_distance( + [self.st15, self.st16], self.q3, algorithm="intuitive" + )[0, 1], + ) + self.assertAlmostEqual( + stds.victor_purpura_distance( + [self.st16, self.st14], self.q3, algorithm="intuitive" + )[0, 1], + stds.victor_purpura_distance( + [self.st16, self.st15], self.q3, algorithm="intuitive" + )[0, 1], + ) + self.assertEqual( + stds.victor_purpura_distance( + [self.st01, self.st05], self.q3, algorithm="intuitive" + )[0, 1], + stds.victor_purpura_distance( + [self.st01, self.st05], self.q7, algorithm="intuitive" + )[0, 1], + ) # Tests on algorithmic behaviour for equal spike times - self.assertEqual(stds.victor_purpura_distance( - [self.st31, self.st34], self.q3, - algorithm='intuitive')[0, 1], - 0.8 + 1.0) - self.assertEqual(stds.victor_purpura_distance( - [self.st31, self.st34], self.q3, - algorithm='intuitive')[0, 1], - stds.victor_purpura_distance( - [self.st32, self.st33], self.q3, - algorithm='intuitive')[0, 1]) - self.assertEqual(stds.victor_purpura_distance( - [self.st31, self.st33], self.q3, - algorithm='intuitive')[0, 1] * 2.0, - stds.victor_purpura_distance( - [self.st32, self.st34], self.q3, - algorithm='intuitive')[0, 1]) + self.assertEqual( + stds.victor_purpura_distance( + [self.st31, self.st34], self.q3, algorithm="intuitive" + )[0, 1], + 0.8 + 1.0, + ) + self.assertEqual( + stds.victor_purpura_distance( + [self.st31, self.st34], self.q3, algorithm="intuitive" + )[0, 1], + stds.victor_purpura_distance( + [self.st32, self.st33], self.q3, algorithm="intuitive" + )[0, 1], + ) + self.assertEqual( + stds.victor_purpura_distance( + [self.st31, self.st33], self.q3, algorithm="intuitive" + )[0, 1] + * 2.0, + stds.victor_purpura_distance( + [self.st32, self.st34], self.q3, algorithm="intuitive" + )[0, 1], + ) # Tests on spike train list lengthes smaller than 2 - self.assertEqual(stds.victor_purpura_distance( - [self.st21], self.q3, - algorithm='intuitive')[0, 0], 0) - self.assertEqual(len(stds.victor_purpura_distance( - [], self.q3, algorithm='intuitive')), 0) + self.assertEqual( + stds.victor_purpura_distance( + [self.st21], self.q3, algorithm="intuitive" + )[0, 0], + 0, + ) + self.assertEqual( + len( + stds.victor_purpura_distance( + [], self.q3, algorithm="intuitive" + ) + ), + 0, + ) def test_victor_purpura_algorithm_comparison(self): assert_array_almost_equal( - stds.victor_purpura_distance([self.st21, self.st22, self.st23], - self.q3), - stds.victor_purpura_distance([self.st21, self.st22, self.st23], - self.q3, algorithm='intuitive')) + stds.victor_purpura_distance( + [self.st21, self.st22, self.st23], self.q3 + ), + stds.victor_purpura_distance( + [self.st21, self.st22, self.st23], + self.q3, + algorithm="intuitive", + ), + ) def test_victor_purpura_matlab_comparison_float(self): - repo_path =\ + repo_path = ( r"unittest/spike_train_dissimilarity/victor_purpura_distance/data" + ) files_to_download = [ ("times_float.npy", "ed1ff4d2c0eeed4a2b50a456803656be"), - ("matlab_results_float.npy", "a17f049e7ad0ddf7ca812e86fdb92646")] + ("matlab_results_float.npy", "a17f049e7ad0ddf7ca812e86fdb92646"), + ] downloaded_files = {} for filename, checksum in files_to_download: downloaded_files[filename] = { - 'filename': filename, - 'path': download_datasets(repo_path=f"{repo_path}/{filename}", - checksum=checksum)} - - times_float = np.load(downloaded_files['times_float.npy']['path']) - mat_res_float = np.load(downloaded_files[ - 'matlab_results_float.npy']['path']) - - r_float = SpikeTrain(times_float[0], units='ms', t_start=0, - t_stop=1000 * ms) - s_float = SpikeTrain(times_float[1], units='ms', t_start=0, - t_stop=1000 * ms) - t_float = SpikeTrain(times_float[2], units='ms', t_start=0, - t_stop=1000 * ms) + "filename": filename, + "path": download_datasets( + repo_path=f"{repo_path}/{filename}", checksum=checksum + ), + } + + times_float = np.load(downloaded_files["times_float.npy"]["path"]) + mat_res_float = np.load( + downloaded_files["matlab_results_float.npy"]["path"] + ) + + r_float = SpikeTrain( + times_float[0], units="ms", t_start=0, t_stop=1000 * ms + ) + s_float = SpikeTrain( + times_float[1], units="ms", t_start=0, t_stop=1000 * ms + ) + t_float = SpikeTrain( + times_float[2], units="ms", t_start=0, t_stop=1000 * ms + ) vic_pur_result_float = stds.victor_purpura_distance( [r_float, s_float, t_float], - cost_factor=1.0 / ms, kernel=None, - sort=True, algorithm='intuitive') + cost_factor=1.0 / ms, + kernel=None, + sort=True, + algorithm="intuitive", + ) assert_array_almost_equal(vic_pur_result_float, mat_res_float) def test_victor_purpura_matlab_comparison_int(self): - repo_path =\ + repo_path = ( r"unittest/spike_train_dissimilarity/victor_purpura_distance/data" + ) files_to_download = [ ("times_int.npy", "aa1411c04da3f58d8b8913ae2f935057"), - ("matlab_results_int.npy", "7edd32e50edde12dc1ef4aa5f57f70fb")] + ("matlab_results_int.npy", "7edd32e50edde12dc1ef4aa5f57f70fb"), + ] downloaded_files = {} for filename, checksum in files_to_download: downloaded_files[filename] = { - 'filename': filename, - 'path': download_datasets(repo_path=f"{repo_path}/{filename}", - checksum=checksum)} - - times_int = np.load(downloaded_files['times_int.npy']['path']) - mat_res_int = np.load(downloaded_files['matlab_results_int.npy']['path']) - - r_int = SpikeTrain(times_int[0], units='ms', t_start=0, - t_stop=1000 * ms) - s_int = SpikeTrain(times_int[1], units='ms', t_start=0, - t_stop=1000 * ms) - t_int = SpikeTrain(times_int[2], units='ms', t_start=0, - t_stop=1000 * ms) + "filename": filename, + "path": download_datasets( + repo_path=f"{repo_path}/{filename}", checksum=checksum + ), + } + + times_int = np.load(downloaded_files["times_int.npy"]["path"]) + mat_res_int = np.load( + downloaded_files["matlab_results_int.npy"]["path"] + ) + + r_int = SpikeTrain( + times_int[0], units="ms", t_start=0, t_stop=1000 * ms + ) + s_int = SpikeTrain( + times_int[1], units="ms", t_start=0, t_stop=1000 * ms + ) + t_int = SpikeTrain( + times_int[2], units="ms", t_start=0, t_stop=1000 * ms + ) vic_pur_result_int = stds.victor_purpura_distance( [r_int, s_int, t_int], - cost_factor=1.0 / ms, kernel=None, - sort=True, algorithm='intuitive') + cost_factor=1.0 / ms, + kernel=None, + sort=True, + algorithm="intuitive", + ) assert_array_equal(vic_pur_result_int, mat_res_int) def test_van_rossum_distance(self): # Tests of distances of simplest spike trains - self.assertEqual(stds.van_rossum_distance( - [self.st00, self.st00], self.tau2)[0, 1], 0.0) - self.assertEqual(stds.van_rossum_distance( - [self.st00, self.st01], self.tau2)[0, 1], 1.0) - self.assertEqual(stds.van_rossum_distance( - [self.st01, self.st00], self.tau2)[0, 1], 1.0) - self.assertEqual(stds.van_rossum_distance( - [self.st01, self.st01], self.tau2)[0, 1], 0.0) + self.assertEqual( + stds.van_rossum_distance([self.st00, self.st00], self.tau2)[0, 1], + 0.0, + ) + self.assertEqual( + stds.van_rossum_distance([self.st00, self.st01], self.tau2)[0, 1], + 1.0, + ) + self.assertEqual( + stds.van_rossum_distance([self.st01, self.st00], self.tau2)[0, 1], + 1.0, + ) + self.assertEqual( + stds.van_rossum_distance([self.st01, self.st01], self.tau2)[0, 1], + 0.0, + ) # Tests of distances under elementary spike operations - self.assertAlmostEqual(stds.van_rossum_distance( - [self.st01, self.st02], self.tau2)[0, 1], - float(np.sqrt(2 * (1.0 - np.exp(-np.absolute( - ((self.st01[0] - self.st02[0]) / - self.tau2).simplified)))))) - self.assertAlmostEqual(stds.van_rossum_distance( - [self.st01, self.st05], self.tau2)[0, 1], - float(np.sqrt(2 * (1.0 - np.exp(-np.absolute( - ((self.st01[0] - self.st05[0]) / - self.tau2).simplified)))))) - self.assertAlmostEqual(stds.van_rossum_distance( - [self.st01, self.st05], self.tau2)[0, 1], - np.sqrt(2.0), 1) - self.assertAlmostEqual(stds.van_rossum_distance( - [self.st01, self.st06], self.tau2)[0, 1], - np.sqrt(2.0), 20) - self.assertAlmostEqual(stds.van_rossum_distance( - [self.st00, self.st07], self.tau1)[0, 1], - np.sqrt(0 + 2)) - self.assertAlmostEqual(stds.van_rossum_distance( - [self.st07, self.st08], self.tau4)[0, 1], - float(np.sqrt(2 * (1.0 - np.exp(-np.absolute( - ((self.st07[0] - self.st08[-1]) / - self.tau4).simplified)))))) + self.assertAlmostEqual( + stds.van_rossum_distance([self.st01, self.st02], self.tau2)[0, 1], + float( + np.sqrt( + 2 + * ( + 1.0 + - np.exp( + -np.absolute( + ( + (self.st01[0] - self.st02[0]) / self.tau2 + ).simplified + ) + ) + ) + ) + ), + ) + self.assertAlmostEqual( + stds.van_rossum_distance([self.st01, self.st05], self.tau2)[0, 1], + float( + np.sqrt( + 2 + * ( + 1.0 + - np.exp( + -np.absolute( + ( + (self.st01[0] - self.st05[0]) / self.tau2 + ).simplified + ) + ) + ) + ) + ), + ) + self.assertAlmostEqual( + stds.van_rossum_distance([self.st01, self.st05], self.tau2)[0, 1], + np.sqrt(2.0), + 1, + ) + self.assertAlmostEqual( + stds.van_rossum_distance([self.st01, self.st06], self.tau2)[0, 1], + np.sqrt(2.0), + 20, + ) + self.assertAlmostEqual( + stds.van_rossum_distance([self.st00, self.st07], self.tau1)[0, 1], + np.sqrt(0 + 2), + ) + self.assertAlmostEqual( + stds.van_rossum_distance([self.st07, self.st08], self.tau4)[0, 1], + float( + np.sqrt( + 2 + * ( + 1.0 + - np.exp( + -np.absolute( + ( + (self.st07[0] - self.st08[-1]) / self.tau4 + ).simplified + ) + ) + ) + ) + ), + ) f_minus_g_squared = ( - (self.t > self.st08[0]) * np.exp( - -((self.t - self.st08[0]) / self.tau3).simplified) + - (self.t > self.st08[1]) * np.exp( - -((self.t - self.st08[1]) / self.tau3).simplified) - - (self.t > self.st09[0]) * np.exp( - -((self.t - self.st09[0]) / self.tau3).simplified)) ** 2 - distance = np.sqrt(2.0 * spint.cumulative_trapezoid( - y=f_minus_g_squared, x=self.t.magnitude)[-1] / - self.tau3.rescale(self.t.units).magnitude) - self.assertAlmostEqual(stds.van_rossum_distance( - [self.st08, self.st09], self.tau3)[0, 1], distance, 5) - self.assertAlmostEqual(stds.van_rossum_distance( - [self.st11, self.st14], self.tau2)[0, 1], 1) + (self.t > self.st08[0]) + * np.exp(-((self.t - self.st08[0]) / self.tau3).simplified) + + (self.t > self.st08[1]) + * np.exp(-((self.t - self.st08[1]) / self.tau3).simplified) + - (self.t > self.st09[0]) + * np.exp(-((self.t - self.st09[0]) / self.tau3).simplified) + ) ** 2 + distance = np.sqrt( + 2.0 + * spint.cumulative_trapezoid( + y=f_minus_g_squared, x=self.t.magnitude + )[-1] + / self.tau3.rescale(self.t.units).magnitude + ) + self.assertAlmostEqual( + stds.van_rossum_distance([self.st08, self.st09], self.tau3)[0, 1], + distance, + 5, + ) + self.assertAlmostEqual( + stds.van_rossum_distance([self.st11, self.st14], self.tau2)[0, 1], + 1, + ) # Tests on timescales self.assertAlmostEqual( stds.van_rossum_distance([self.st11, self.st14], self.tau1)[0, 1], - stds.van_rossum_distance([self.st11, self.st14], self.tau5)[0, 1]) + stds.van_rossum_distance([self.st11, self.st14], self.tau5)[0, 1], + ) self.assertAlmostEqual( stds.van_rossum_distance([self.st07, self.st11], self.tau0)[0, 1], - np.sqrt(len(self.st07) + len(self.st11))) + np.sqrt(len(self.st07) + len(self.st11)), + ) self.assertAlmostEqual( stds.van_rossum_distance([self.st07, self.st14], self.tau0)[0, 1], - np.sqrt(len(self.st07) + len(self.st14))) + np.sqrt(len(self.st07) + len(self.st14)), + ) self.assertAlmostEqual( stds.van_rossum_distance([self.st07, self.st11], self.tau1)[0, 1], - np.sqrt(len(self.st07) + len(self.st11))) + np.sqrt(len(self.st07) + len(self.st11)), + ) self.assertAlmostEqual( stds.van_rossum_distance([self.st07, self.st14], self.tau1)[0, 1], - np.sqrt(len(self.st07) + len(self.st14))) + np.sqrt(len(self.st07) + len(self.st14)), + ) self.assertAlmostEqual( stds.van_rossum_distance([self.st07, self.st11], self.tau5)[0, 1], - np.absolute(len(self.st07) - len(self.st11))) + np.absolute(len(self.st07) - len(self.st11)), + ) self.assertAlmostEqual( stds.van_rossum_distance([self.st07, self.st14], self.tau5)[0, 1], - np.absolute(len(self.st07) - len(self.st14))) + np.absolute(len(self.st07) - len(self.st14)), + ) self.assertAlmostEqual( stds.van_rossum_distance([self.st07, self.st11], self.tau6)[0, 1], - np.absolute(len(self.st07) - len(self.st11))) + np.absolute(len(self.st07) - len(self.st11)), + ) self.assertAlmostEqual( stds.van_rossum_distance([self.st07, self.st14], self.tau6)[0, 1], - np.absolute(len(self.st07) - len(self.st14))) + np.absolute(len(self.st07) - len(self.st14)), + ) # Tests on unordered spiketrains self.assertEqual( stds.van_rossum_distance([self.st11, self.st13], self.tau4)[0, 1], - stds.van_rossum_distance([self.st12, self.st13], self.tau4)[0, 1]) + stds.van_rossum_distance([self.st12, self.st13], self.tau4)[0, 1], + ) self.assertNotEqual( - stds.van_rossum_distance([self.st11, self.st13], - self.tau4, sort=False)[0, 1], - stds.van_rossum_distance([self.st12, self.st13], - self.tau4, sort=False)[0, 1]) + stds.van_rossum_distance( + [self.st11, self.st13], self.tau4, sort=False + )[0, 1], + stds.van_rossum_distance( + [self.st12, self.st13], self.tau4, sort=False + )[0, 1], + ) # Tests on metric properties with random spiketrains # (explicit calculation of second metric axiom in particular case, # because from dist_matrix it is trivial) dist_matrix = stds.van_rossum_distance( - [self.st21, self.st22, self.st23], self.tau3) + [self.st21, self.st22, self.st23], self.tau3 + ) for i in range(3): for j in range(3): self.assertGreaterEqual(dist_matrix[i, j], 0) @@ -555,50 +932,66 @@ def test_van_rossum_distance(self): assert_array_equal(self.rd_st_list[i], self.rd_st_list[j]) assert_array_equal( stds.van_rossum_distance([self.st21, self.st22], self.tau3), - stds.van_rossum_distance([self.st22, self.st21], self.tau3)) - self.assertLessEqual(dist_matrix[0, 1], - dist_matrix[0, 2] + dist_matrix[1, 2]) - self.assertLessEqual(dist_matrix[0, 2], - dist_matrix[1, 2] + dist_matrix[0, 1]) - self.assertLessEqual(dist_matrix[1, 2], - dist_matrix[0, 1] + dist_matrix[0, 2]) + stds.van_rossum_distance([self.st22, self.st21], self.tau3), + ) + self.assertLessEqual( + dist_matrix[0, 1], dist_matrix[0, 2] + dist_matrix[1, 2] + ) + self.assertLessEqual( + dist_matrix[0, 2], dist_matrix[1, 2] + dist_matrix[0, 1] + ) + self.assertLessEqual( + dist_matrix[1, 2], dist_matrix[0, 1] + dist_matrix[0, 2] + ) # Tests on proper unit conversion self.assertAlmostEqual( stds.van_rossum_distance([self.st14, self.st16], self.tau3)[0, 1], - stds.van_rossum_distance([self.st15, self.st16], self.tau3)[0, 1]) + stds.van_rossum_distance([self.st15, self.st16], self.tau3)[0, 1], + ) self.assertAlmostEqual( stds.van_rossum_distance([self.st16, self.st14], self.tau3)[0, 1], - stds.van_rossum_distance([self.st16, self.st15], self.tau3)[0, 1]) + stds.van_rossum_distance([self.st16, self.st15], self.tau3)[0, 1], + ) self.assertEqual( stds.van_rossum_distance([self.st01, self.st05], self.tau3)[0, 1], - stds.van_rossum_distance([self.st01, self.st05], self.tau7)[0, 1]) + stds.van_rossum_distance([self.st01, self.st05], self.tau7)[0, 1], + ) # Tests on algorithmic behaviour for equal spike times f_minus_g_squared = ( - (self.t > self.st31[0]) * np.exp( - -((self.t - self.st31[0]) / self.tau3).simplified) - - (self.t > self.st34[0]) * np.exp( - -((self.t - self.st34[0]) / self.tau3).simplified) - - (self.t > self.st34[1]) * np.exp( - -((self.t - self.st34[1]) / self.tau3).simplified)) ** 2 - distance = np.sqrt(2.0 * spint.cumulative_trapezoid( - y=f_minus_g_squared, x=self.t.magnitude)[-1] / - self.tau3.rescale(self.t.units).magnitude) - self.assertAlmostEqual(stds.van_rossum_distance([self.st31, self.st34], - self.tau3)[0, 1], - distance, 5) - self.assertEqual(stds.van_rossum_distance([self.st31, self.st34], - self.tau3)[0, 1], - stds.van_rossum_distance([self.st32, self.st33], - self.tau3)[0, 1]) - self.assertEqual(stds.van_rossum_distance([self.st31, self.st33], - self.tau3)[0, 1] * 2.0, - stds.van_rossum_distance([self.st32, self.st34], - self.tau3)[0, 1]) + (self.t > self.st31[0]) + * np.exp(-((self.t - self.st31[0]) / self.tau3).simplified) + - (self.t > self.st34[0]) + * np.exp(-((self.t - self.st34[0]) / self.tau3).simplified) + - (self.t > self.st34[1]) + * np.exp(-((self.t - self.st34[1]) / self.tau3).simplified) + ) ** 2 + distance = np.sqrt( + 2.0 + * spint.cumulative_trapezoid( + y=f_minus_g_squared, x=self.t.magnitude + )[-1] + / self.tau3.rescale(self.t.units).magnitude + ) + self.assertAlmostEqual( + stds.van_rossum_distance([self.st31, self.st34], self.tau3)[0, 1], + distance, + 5, + ) + self.assertEqual( + stds.van_rossum_distance([self.st31, self.st34], self.tau3)[0, 1], + stds.van_rossum_distance([self.st32, self.st33], self.tau3)[0, 1], + ) + self.assertEqual( + stds.van_rossum_distance([self.st31, self.st33], self.tau3)[0, 1] + * 2.0, + stds.van_rossum_distance([self.st32, self.st34], self.tau3)[0, 1], + ) # Tests on spike train list lengthes smaller than 2 - self.assertEqual(stds.van_rossum_distance( - [self.st21], self.tau3)[0, 0], 0) + self.assertEqual( + stds.van_rossum_distance([self.st21], self.tau3)[0, 0], 0 + ) self.assertEqual(len(stds.van_rossum_distance([], self.tau3)), 0) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() From 2f28e2a69606a4967a5355f1b64c8bd8e8c7bf55 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 25 Apr 2024 15:03:42 +0200 Subject: [PATCH 25/84] use local data for elephant-data in macOS runner --- .github/workflows/CI.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index b22fc56ed..785343522 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -146,6 +146,19 @@ jobs: path: ~/conda_pkgs_dir key: ${{ runner.os }}-conda-${{hashFiles('requirements/environment.yml') }}-${{ hashFiles('**/CI.yml') }}-${{ steps.date.outputs.date }} + - name: Get current hash (SHA) of the elephant_data repo + id: elephant-data + run: | + echo "dataset_hash=$(git ls-remote https://gin.g-node.org/NeuralEnsemble/elephant-data.git HEAD | cut -f1)" >> $GITHUB_OUTPUT + + - uses: actions/cache/restore@v3 + # Loading cache of ephys_testing_dataset + id: cache-datasets + with: + path: ~/elephant-data + key: ${{ runner.os }}-datasets-${{ steps.elephant-data.outputs.dataset_hash }} + restore-keys: ${{ runner.os }}-datasets- + - uses: conda-incubator/setup-miniconda@030178870c779d9e5e1b4e563269f3aa69b04081 # corresponds to v3.0.3 with: auto-update-conda: true @@ -173,6 +186,7 @@ jobs: - name: Test with pytest shell: bash -l {0} run: | + export ELEPHANT_DATA_PATH=~/elephant-data pytest --cov=elephant # __ ___ _ From fc500e29c1902a72650acd61ba5fd72f4c7cb5f2 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 25 Apr 2024 15:24:23 +0200 Subject: [PATCH 26/84] update elephant-data path --- .github/workflows/CI.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 785343522..b7e4a3d02 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -152,7 +152,7 @@ jobs: echo "dataset_hash=$(git ls-remote https://gin.g-node.org/NeuralEnsemble/elephant-data.git HEAD | cut -f1)" >> $GITHUB_OUTPUT - uses: actions/cache/restore@v3 - # Loading cache of ephys_testing_dataset + # Loading cache of elephant-data id: cache-datasets with: path: ~/elephant-data @@ -186,7 +186,10 @@ jobs: - name: Test with pytest shell: bash -l {0} run: | - export ELEPHANT_DATA_PATH=~/elephant-data + du ~/elephant-data + full_path=$(realpath "~/elephant-data") + echo "$full_path" + export ELEPHANT_DATA_PATH="$full_path" pytest --cov=elephant # __ ___ _ From 983fc2c95a074a8d56100996da992dd0b729f2a4 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 25 Apr 2024 15:29:59 +0200 Subject: [PATCH 27/84] update path --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index b7e4a3d02..0f7d7d77a 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -187,7 +187,7 @@ jobs: shell: bash -l {0} run: | du ~/elephant-data - full_path=$(realpath "~/elephant-data") + full_path=~/elephant-data echo "$full_path" export ELEPHANT_DATA_PATH="$full_path" pytest --cov=elephant From 3421fc3e07c0038c66cd2d4a929645fe1553f3fd Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 25 Apr 2024 16:03:46 +0200 Subject: [PATCH 28/84] add caching to pip runner --- .github/workflows/CI.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 0f7d7d77a..7e9bbdfff 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -99,6 +99,19 @@ jobs: -${{ hashFiles('**/requirements-extras.txt') }}-${{ hashFiles('**/CI.yml') }}-${{ hashFiles('setup.py') }} -${{ steps.date.outputs.date }} + - name: Get current hash (SHA) of the elephant_data repo + id: elephant-data + run: | + echo "dataset_hash=$(git ls-remote https://gin.g-node.org/NeuralEnsemble/elephant-data.git HEAD | cut -f1)" >> $GITHUB_OUTPUT + + - uses: actions/cache/restore@v3 + # Loading cache of elephant-data + id: cache-datasets + with: + path: ~/elephant-data + key: ${{ runner.os }}-datasets-${{ steps.elephant-data.outputs.dataset_hash }} + restore-keys: ${{ runner.os }}-datasets- + - name: Install dependencies run: | python -m pip install --upgrade pip From 3930826a928e2a1db70f13586a0c725c0aa1767c Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 25 Apr 2024 16:05:47 +0200 Subject: [PATCH 29/84] try cache macos for ubuntu --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 7e9bbdfff..a061961ff 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -109,7 +109,7 @@ jobs: id: cache-datasets with: path: ~/elephant-data - key: ${{ runner.os }}-datasets-${{ steps.elephant-data.outputs.dataset_hash }} + key: macos-latest-datasets-${{ steps.elephant-data.outputs.dataset_hash }} restore-keys: ${{ runner.os }}-datasets- - name: Install dependencies From 05d96e95782a1ee071a42260c9eef0fc6aaa7b83 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 25 Apr 2024 16:08:04 +0200 Subject: [PATCH 30/84] add local elephant-data to runner --- .github/workflows/CI.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index a061961ff..2204972e5 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -125,6 +125,10 @@ jobs: - name: Test with pytest run: | + du ~/elephant-data + full_path=~/elephant-data + echo "$full_path" + export ELEPHANT_DATA_PATH="$full_path" coverage run --source=elephant -m pytest coveralls --service=github || echo "Coveralls submission failed" env: From be2f9d4b6e7cc8400b88524109fdd3f1cf97afe4 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 25 Apr 2024 16:09:31 +0200 Subject: [PATCH 31/84] update restore key --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 2204972e5..d516eb7f2 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -110,7 +110,7 @@ jobs: with: path: ~/elephant-data key: macos-latest-datasets-${{ steps.elephant-data.outputs.dataset_hash }} - restore-keys: ${{ runner.os }}-datasets- + restore-keys: macos-latest-datasets- - name: Install dependencies run: | From 98ea592dd6144472fccf9c06feb37c1711015e2e Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 25 Apr 2024 16:17:49 +0200 Subject: [PATCH 32/84] add ubuntu runner for caching --- .github/workflows/CI.yml | 4 ++-- .github/workflows/cache_elephant_data.yml | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index d516eb7f2..d0cc505d4 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -109,8 +109,8 @@ jobs: id: cache-datasets with: path: ~/elephant-data - key: macos-latest-datasets-${{ steps.elephant-data.outputs.dataset_hash }} - restore-keys: macos-latest-datasets- + key: ${{ runner.os }}-datasets-${{ steps.elephant-data.outputs.dataset_hash }} + restore-keys: ${{ runner.os }}-datasets- - name: Install dependencies run: | diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index f680c1419..e6ec7167f 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -19,7 +19,13 @@ on: jobs: create-data-cache-if-missing: name: Caching data env - runs-on: "macos-latest" + runs-on: ${{ matrix.os }} + strategy: + # do not cancel all in-progress jobs if any matrix job fails + fail-fast: false + matrix: + # OS [ubuntu-latest, macos-latest, windows-latest] + os: [macos-latest,ubuntu-latest] steps: - name: Get current hash (SHA) of the elephant_data repo @@ -43,8 +49,14 @@ jobs: git config --global user.email "elephant_ci@fake_mail.com" git config --global user.name "elephant CI" git config --global filter.annex.process "git-annex filter-process" # recommended for efficiency - - brew install datalad + if [[ "$OSTYPE" == "darwin"* ]]; then + brew install datalad + elif [[ "$OSTYPE" == "linux-gnu"* ]]; then + apt-get install datalad + else + echo "Unsupported operating system." + exit 1 + fi - name: Download dataset id: download-dataset From 33510ff6c401604dbf0583c4d840f4f65cbf171e Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 25 Apr 2024 16:18:36 +0200 Subject: [PATCH 33/84] change permissions --- .github/workflows/cache_elephant_data.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index e6ec7167f..764f299ff 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -52,7 +52,7 @@ jobs: if [[ "$OSTYPE" == "darwin"* ]]; then brew install datalad elif [[ "$OSTYPE" == "linux-gnu"* ]]; then - apt-get install datalad + sudo apt-get install datalad else echo "Unsupported operating system." exit 1 From 5b6f3f69590dfd7f9d1dedbe8def460f3e2fca39 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 25 Apr 2024 16:30:20 +0200 Subject: [PATCH 34/84] update datalad install for ubuntu --- .github/workflows/cache_elephant_data.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index 764f299ff..e622ae760 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -52,7 +52,10 @@ jobs: if [[ "$OSTYPE" == "darwin"* ]]; then brew install datalad elif [[ "$OSTYPE" == "linux-gnu"* ]]; then - sudo apt-get install datalad + python -m pip install -U pip # Official recommended way + pip install datalad-installer + datalad-installer --sudo ok git-annex --method datalad/packages + pip install datalad else echo "Unsupported operating system." exit 1 From b357e19d381827a6d4bb088c57260dab6ca5b660 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Thu, 25 Apr 2024 16:42:05 +0200 Subject: [PATCH 35/84] caches created --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index d0cc505d4..05b07d86c 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -94,7 +94,7 @@ jobs: with: path: ${{ steps.pip-cache.outputs.dir }} # Look to see if there is a cache hit for the corresponding requirements files - # cache will be reset on changes to any requirements or every month + # cache will be reset on changes to any requirements or every month. key: ${{ runner.os }}-venv-${{ hashFiles('**/requirements.txt') }}-${{ hashFiles('**/requirements-tests.txt') }} -${{ hashFiles('**/requirements-extras.txt') }}-${{ hashFiles('**/CI.yml') }}-${{ hashFiles('setup.py') }} -${{ steps.date.outputs.date }} From 617e09b3454a4b096709b41fe074bfb3d7b2b917 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 10:27:17 +0200 Subject: [PATCH 36/84] add cache only on hit --- .github/workflows/CI.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 05b07d86c..d3c48f350 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -125,10 +125,11 @@ jobs: - name: Test with pytest run: | - du ~/elephant-data - full_path=~/elephant-data - echo "$full_path" - export ELEPHANT_DATA_PATH="$full_path" + if [ -d ~/elephant-data ]; then + export ELEPHANT_DATA_PATH=~/elephant-data + echo $ELEPHANT_DATA_PATH + fi + coverage run --source=elephant -m pytest coveralls --service=github || echo "Coveralls submission failed" env: @@ -203,10 +204,8 @@ jobs: - name: Test with pytest shell: bash -l {0} run: | - du ~/elephant-data - full_path=~/elephant-data - echo "$full_path" - export ELEPHANT_DATA_PATH="$full_path" + export ELEPHANT_DATA_PATH=~/elephant-data + echo $ELEPHANT_DATA_PATH pytest --cov=elephant # __ ___ _ From 9863b88a4d408d48ee500ebd012780cbb728c4c4 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 10:40:15 +0200 Subject: [PATCH 37/84] use latest packages --- .github/workflows/CI.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index d3c48f350..e15fd1106 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -86,6 +86,7 @@ jobs: uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} + check-latest: true cache: 'pip' cache-dependency-path: '**/requirements.txt' From d5b427978591aa67a72b9f8ade67532c76f25c53 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 10:47:32 +0200 Subject: [PATCH 38/84] handle caching with setup-python --- .github/workflows/CI.yml | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e15fd1106..270a01c42 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -70,16 +70,6 @@ jobs: fail-fast: false steps: - # used to reset cache every month - - name: Get current year-month - id: date - run: echo "date=$(date +'%Y-%m')" >> $GITHUB_OUTPUT - - - name: Get pip cache dir - id: pip-cache - run: | - echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT - - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} @@ -88,17 +78,10 @@ jobs: python-version: ${{ matrix.python-version }} check-latest: true cache: 'pip' - cache-dependency-path: '**/requirements.txt' - - - name: Cache test_env - uses: actions/cache@v3 - with: - path: ${{ steps.pip-cache.outputs.dir }} - # Look to see if there is a cache hit for the corresponding requirements files - # cache will be reset on changes to any requirements or every month. - key: ${{ runner.os }}-venv-${{ hashFiles('**/requirements.txt') }}-${{ hashFiles('**/requirements-tests.txt') }} - -${{ hashFiles('**/requirements-extras.txt') }}-${{ hashFiles('**/CI.yml') }}-${{ hashFiles('setup.py') }} - -${{ steps.date.outputs.date }} + cache-dependency-path: | + '**/requirements.txt' + '**/requirements-extras.txt' + '**/requirements-tests.txt' - name: Get current hash (SHA) of the elephant_data repo id: elephant-data From f8dad2a23f75753ccd626c47b3c0810cfc3727d6 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 10:48:49 +0200 Subject: [PATCH 39/84] fix typo --- .github/workflows/CI.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 270a01c42..66a760e65 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -79,9 +79,9 @@ jobs: check-latest: true cache: 'pip' cache-dependency-path: | - '**/requirements.txt' - '**/requirements-extras.txt' - '**/requirements-tests.txt' + **/requirements.txt + **/requirements-extras.txt + **/requirements-tests.txt - name: Get current hash (SHA) of the elephant_data repo id: elephant-data From 9d46b34cd8ecce4dc468cf17e40e7046a4d787be Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 10:58:58 +0200 Subject: [PATCH 40/84] add caching to toher runners --- .github/workflows/CI.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 66a760e65..984022ee7 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -188,8 +188,10 @@ jobs: - name: Test with pytest shell: bash -l {0} run: | + if [ -d ~/elephant-data ]; then export ELEPHANT_DATA_PATH=~/elephant-data echo $ELEPHANT_DATA_PATH + fi pytest --cov=elephant # __ ___ _ @@ -287,6 +289,19 @@ jobs: key: ${{ runner.os }}-venv-${{ hashFiles('**/requirements.txt') }}-${{ hashFiles('**/requirements-tests.txt') }} -${{ hashFiles('**/requirements-extras.txt') }}-${{ hashFiles('setup.py') }} -${{ hashFiles('**/CI.yml') }}-${{ steps.date.outputs.date }} + - name: Get current hash (SHA) of the elephant_data repo + id: elephant-data + run: | + echo "dataset_hash=$(git ls-remote https://gin.g-node.org/NeuralEnsemble/elephant-data.git HEAD | cut -f1)" >> $GITHUB_OUTPUT + + - uses: actions/cache/restore@v3 + # Loading cache of elephant-data + id: cache-datasets + with: + path: ~/elephant-data + key: ${{ runner.os }}-datasets-${{ steps.elephant-data.outputs.dataset_hash }} + restore-keys: ${{ runner.os }}-datasets- + - name: Setup environment run: | sudo apt-get update @@ -304,6 +319,10 @@ jobs: - name: Test with pytest run: | + if [ -d ~/elephant-data ]; then + export ELEPHANT_DATA_PATH=~/elephant-data + echo $ELEPHANT_DATA_PATH + fi mpiexec -n 1 python -m mpi4py -m coverage run --source=elephant -m pytest coveralls --service=github || echo "Coveralls submission failed" env: @@ -347,6 +366,19 @@ jobs: key: ${{ runner.os }}-pip-${{hashFiles('requirements/environment-tests.yml') }}-${{ hashFiles('**/CI.yml') }}-${{ steps.date.outputs.date }} + - name: Get current hash (SHA) of the elephant_data repo + id: elephant-data + run: | + echo "dataset_hash=$(git ls-remote https://gin.g-node.org/NeuralEnsemble/elephant-data.git HEAD | cut -f1)" >> $GITHUB_OUTPUT + + - uses: actions/cache/restore@v3 + # Loading cache of elephant-data + id: cache-datasets + with: + path: ~/elephant-data + key: ${{ runner.os }}-datasets-${{ steps.elephant-data.outputs.dataset_hash }} + restore-keys: ${{ runner.os }}-datasets- + - uses: conda-incubator/setup-miniconda@030178870c779d9e5e1b4e563269f3aa69b04081 # corresponds to v3.0.3 with: auto-update-conda: true @@ -375,6 +407,10 @@ jobs: - name: Test with pytest shell: bash -el {0} run: | + if [ -d ~/elephant-data ]; then + export ELEPHANT_DATA_PATH=~/elephant-data + echo $ELEPHANT_DATA_PATH + fi pytest --cov=elephant # ____ From f332fa6c1e108843cf9c806bb1733745b9a60fa1 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 11:29:10 +0200 Subject: [PATCH 41/84] add cache for windows --- .github/workflows/cache_elephant_data.yml | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index e622ae760..642e073c9 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -25,7 +25,7 @@ jobs: fail-fast: false matrix: # OS [ubuntu-latest, macos-latest, windows-latest] - os: [macos-latest,ubuntu-latest] + os: [macos-latest,ubuntu-latest,windows-latest] steps: - name: Get current hash (SHA) of the elephant_data repo @@ -49,9 +49,15 @@ jobs: git config --global user.email "elephant_ci@fake_mail.com" git config --global user.name "elephant CI" git config --global filter.annex.process "git-annex filter-process" # recommended for efficiency - if [[ "$OSTYPE" == "darwin"* ]]; then + + if [[ "${{ runner.os }}" == "macOS"* ]]; then brew install datalad - elif [[ "$OSTYPE" == "linux-gnu"* ]]; then + elif [[ "${{ runner.os }}" == "Linux"* ]]; then + python -m pip install -U pip # Official recommended way + pip install datalad-installer + datalad-installer --sudo ok git-annex --method datalad/packages + pip install datalad + elif [[ "${{ runner.os }}" == "Windows"* ]]; then python -m pip install -U pip # Official recommended way pip install datalad-installer datalad-installer --sudo ok git-annex --method datalad/packages @@ -73,5 +79,11 @@ jobs: - name: Show size of the cache to assert data is downloaded run: | cd ~ - du -hs ~/elephant-data - ls -lh ~/elephant-data \ No newline at end of file + if [[ "${{ runner.os }}" == "macOS"* ]]; then + du -hs ~/elephant-data + ls -lh ~/elephant-data + elif [[ "${{ runner.os }}" == "Linux"* ]]; then + du -hs ~/elephant-data + ls -lh ~/elephant-data + elif [[ "${{ runner.os }}" == "Windows"* ]]; then + dir ~\elephant-data \ No newline at end of file From fa98ff86ca90cf5104642531513c0253ea47fcdb Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 11:30:50 +0200 Subject: [PATCH 42/84] fix if cond --- .github/workflows/cache_elephant_data.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index 642e073c9..acd2ea20b 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -86,4 +86,5 @@ jobs: du -hs ~/elephant-data ls -lh ~/elephant-data elif [[ "${{ runner.os }}" == "Windows"* ]]; then - dir ~\elephant-data \ No newline at end of file + dir ~\elephant-data + fi \ No newline at end of file From 8a895145c94b21d468c4227b6160bbff1f67df16 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 11:47:09 +0200 Subject: [PATCH 43/84] add windows runner --- .github/workflows/cache_elephant_data.yml | 60 +++++++++++------------ 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index acd2ea20b..89adc1984 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -43,48 +43,44 @@ jobs: - name: Cache found? run: echo "Cache-hit == ${{steps.cache-datasets.outputs.cache-hit == 'true'}}" - - name: Installing datalad + - name: Configuring git if: steps.cache-datasets.outputs.cache-hit != 'true' run: | git config --global user.email "elephant_ci@fake_mail.com" git config --global user.name "elephant CI" git config --global filter.annex.process "git-annex filter-process" # recommended for efficiency + + - name: Install Datalad macOS + if: steps.cache-datasets.outputs.cache-hit != 'true' && ${{ runner.os }}" == "macOS" + run: | + brew install datalad - if [[ "${{ runner.os }}" == "macOS"* ]]; then - brew install datalad - elif [[ "${{ runner.os }}" == "Linux"* ]]; then - python -m pip install -U pip # Official recommended way - pip install datalad-installer - datalad-installer --sudo ok git-annex --method datalad/packages - pip install datalad - elif [[ "${{ runner.os }}" == "Windows"* ]]; then - python -m pip install -U pip # Official recommended way - pip install datalad-installer - datalad-installer --sudo ok git-annex --method datalad/packages - pip install datalad - else - echo "Unsupported operating system." - exit 1 - fi - + - name: Install Datalad Linux/ Windows + if: steps.cache-datasets.outputs.cache-hit != 'true' && ${{ runner.os }}" == "Linux" || ${{ runner.os }}" == "Windows" + run: | + python -m pip install -U pip # Official recommended way + pip install datalad-installer + datalad-installer --sudo ok git-annex --method datalad/packages + pip install datalad + - name: Download dataset id: download-dataset if: steps.cache-datasets.outputs.cache-hit != 'true' # Download repository and also fetch data run: | - cd ~ - datalad --version - datalad install --recursive --get-data https://gin.g-node.org/NeuralEnsemble/elephant-data + cd ~ + datalad --version + datalad install --recursive --get-data https://gin.g-node.org/NeuralEnsemble/elephant-data + + - name: Show size of the cache to assert data is downloaded macOS, Linux + if: ${{ runner.os }}" == "Linux" || ${{ runner.os }}" == "macOS" + run: | + cd ~ + du -hs ~/elephant-data + ls -lh ~/elephant-data - - name: Show size of the cache to assert data is downloaded + - name: Show size of the cache to assert data is downloaded Windows + if: ${{ runner.os }}" == "Windows" run: | - cd ~ - if [[ "${{ runner.os }}" == "macOS"* ]]; then - du -hs ~/elephant-data - ls -lh ~/elephant-data - elif [[ "${{ runner.os }}" == "Linux"* ]]; then - du -hs ~/elephant-data - ls -lh ~/elephant-data - elif [[ "${{ runner.os }}" == "Windows"* ]]; then - dir ~\elephant-data - fi \ No newline at end of file + cd ~ + dir ~\elephant-data From c12ea49f30d1ee6978cd1d488b1bb76d60aea79b Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 11:50:00 +0200 Subject: [PATCH 44/84] fix typo --- .github/workflows/cache_elephant_data.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index 89adc1984..64382000d 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -51,12 +51,12 @@ jobs: git config --global filter.annex.process "git-annex filter-process" # recommended for efficiency - name: Install Datalad macOS - if: steps.cache-datasets.outputs.cache-hit != 'true' && ${{ runner.os }}" == "macOS" + if: steps.cache-datasets.outputs.cache-hit != 'true' && ${{ runner.os }} == 'macOS' run: | brew install datalad - name: Install Datalad Linux/ Windows - if: steps.cache-datasets.outputs.cache-hit != 'true' && ${{ runner.os }}" == "Linux" || ${{ runner.os }}" == "Windows" + if: steps.cache-datasets.outputs.cache-hit != 'true' && ${{ runner.os }} == 'Linux' || ${{ runner.os }}" == 'Windows' run: | python -m pip install -U pip # Official recommended way pip install datalad-installer @@ -73,14 +73,14 @@ jobs: datalad install --recursive --get-data https://gin.g-node.org/NeuralEnsemble/elephant-data - name: Show size of the cache to assert data is downloaded macOS, Linux - if: ${{ runner.os }}" == "Linux" || ${{ runner.os }}" == "macOS" + if: ${{ runner.os }} == 'Linux' || ${{ runner.os }} == 'macOS' run: | cd ~ du -hs ~/elephant-data ls -lh ~/elephant-data - name: Show size of the cache to assert data is downloaded Windows - if: ${{ runner.os }}" == "Windows" + if: ${{ runner.os }} == 'Windows' run: | cd ~ dir ~\elephant-data From d9bee5483437410f7da40da75490607ffa86eeac Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 11:55:30 +0200 Subject: [PATCH 45/84] change conditions --- .github/workflows/cache_elephant_data.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index 64382000d..d3af4b542 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -51,12 +51,12 @@ jobs: git config --global filter.annex.process "git-annex filter-process" # recommended for efficiency - name: Install Datalad macOS - if: steps.cache-datasets.outputs.cache-hit != 'true' && ${{ runner.os }} == 'macOS' + if: steps.cache-datasets.outputs.cache-hit != 'true' && runner.os == 'macOS' run: | brew install datalad - name: Install Datalad Linux/ Windows - if: steps.cache-datasets.outputs.cache-hit != 'true' && ${{ runner.os }} == 'Linux' || ${{ runner.os }}" == 'Windows' + if: steps.cache-datasets.outputs.cache-hit != 'true' && runner.os == 'Linux' || runner.os == 'Windows' run: | python -m pip install -U pip # Official recommended way pip install datalad-installer @@ -73,14 +73,14 @@ jobs: datalad install --recursive --get-data https://gin.g-node.org/NeuralEnsemble/elephant-data - name: Show size of the cache to assert data is downloaded macOS, Linux - if: ${{ runner.os }} == 'Linux' || ${{ runner.os }} == 'macOS' + if: runner.os == 'Linux' || runner.os == 'macOS' run: | cd ~ du -hs ~/elephant-data ls -lh ~/elephant-data - name: Show size of the cache to assert data is downloaded Windows - if: ${{ runner.os }} == 'Windows' + if: runner.os == 'Windows' run: | cd ~ dir ~\elephant-data From 168002d602f3ca90d8b0d9463d8ff82f2a6153cc Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 12:06:57 +0200 Subject: [PATCH 46/84] fix formatting, cleanup --- .github/workflows/cache_elephant_data.yml | 126 +++++++++++----------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index d3af4b542..9574a0e72 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -17,70 +17,70 @@ on: - synchronize jobs: - create-data-cache-if-missing: - name: Caching data env - runs-on: ${{ matrix.os }} - strategy: - # do not cancel all in-progress jobs if any matrix job fails - fail-fast: false - matrix: - # OS [ubuntu-latest, macos-latest, windows-latest] - os: [macos-latest,ubuntu-latest,windows-latest] - steps: - - - name: Get current hash (SHA) of the elephant_data repo - id: elephant-data - run: | - echo "dataset_hash=$(git ls-remote https://gin.g-node.org/NeuralEnsemble/elephant-data.git HEAD | cut -f1)" >> $GITHUB_OUTPUT - - - uses: actions/cache@v3 - # Loading cache of elephant-data - id: cache-datasets - with: - path: ~/elephant-data - key: ${{ runner.os }}-datasets-${{ steps.elephant-data.outputs.dataset_hash }} - - - name: Cache found? - run: echo "Cache-hit == ${{steps.cache-datasets.outputs.cache-hit == 'true'}}" - - - name: Configuring git - if: steps.cache-datasets.outputs.cache-hit != 'true' - run: | - git config --global user.email "elephant_ci@fake_mail.com" - git config --global user.name "elephant CI" - git config --global filter.annex.process "git-annex filter-process" # recommended for efficiency - - - name: Install Datalad macOS - if: steps.cache-datasets.outputs.cache-hit != 'true' && runner.os == 'macOS' - run: | - brew install datalad + create-data-cache-if-missing: + name: Caching data env + runs-on: ${{ matrix.os }} + strategy: + # do not cancel all in-progress jobs if any matrix job fails + fail-fast: false + matrix: + # OS [ubuntu-latest, macos-latest, windows-latest] + os: [macos-latest,ubuntu-latest,windows-latest] + + steps: + - name: Get current hash (SHA) of the elephant_data repo + id: elephant-data + run: | + echo "dataset_hash=$(git ls-remote https://gin.g-node.org/NeuralEnsemble/elephant-data.git HEAD | cut -f1)" >> $GITHUB_OUTPUT + + - uses: actions/cache@v3 + # Loading cache of elephant-data + id: cache-datasets + with: + path: ~/elephant-data + key: ${{ runner.os }}-datasets-${{ steps.elephant-data.outputs.dataset_hash }} + + - name: Cache found? + run: echo "Cache-hit == ${{steps.cache-datasets.outputs.cache-hit == 'true'}}" + + - name: Configuring git + if: steps.cache-datasets.outputs.cache-hit != 'true' + run: | + git config --global user.email "elephant_ci@fake_mail.com" + git config --global user.name "elephant CI" + git config --global filter.annex.process "git-annex filter-process" # recommended for efficiency + + - name: Install Datalad macOS + if: steps.cache-datasets.outputs.cache-hit != 'true' && runner.os == 'macOS' + run: | + brew install datalad - - name: Install Datalad Linux/ Windows - if: steps.cache-datasets.outputs.cache-hit != 'true' && runner.os == 'Linux' || runner.os == 'Windows' - run: | - python -m pip install -U pip # Official recommended way - pip install datalad-installer - datalad-installer --sudo ok git-annex --method datalad/packages - pip install datalad + - name: Install Datalad Linux/ Windows + if: steps.cache-datasets.outputs.cache-hit != 'true' && runner.os == 'Linux' || runner.os == 'Windows' + run: | + python -m pip install -U pip # Official recommended way + pip install datalad-installer + datalad-installer --sudo ok git-annex --method datalad/packages + pip install datalad - - name: Download dataset - id: download-dataset - if: steps.cache-datasets.outputs.cache-hit != 'true' - # Download repository and also fetch data - run: | - cd ~ - datalad --version - datalad install --recursive --get-data https://gin.g-node.org/NeuralEnsemble/elephant-data + - name: Download dataset + id: download-dataset + if: steps.cache-datasets.outputs.cache-hit != 'true' + # Download repository and also fetch data + run: | + cd ~ + datalad --version + datalad install --recursive --get-data https://gin.g-node.org/NeuralEnsemble/elephant-data - - name: Show size of the cache to assert data is downloaded macOS, Linux - if: runner.os == 'Linux' || runner.os == 'macOS' - run: | - cd ~ - du -hs ~/elephant-data - ls -lh ~/elephant-data + - name: Show size of the cache to assert data is downloaded macOS, Linux + if: runner.os == 'Linux' || runner.os == 'macOS' + run: | + cd ~ + du -hs ~/elephant-data + ls -lh ~/elephant-data - - name: Show size of the cache to assert data is downloaded Windows - if: runner.os == 'Windows' - run: | - cd ~ - dir ~\elephant-data + - name: Show size of the cache to assert data is downloaded Windows + if: runner.os == 'Windows' + run: | + cd ~ + dir ~\elephant-data From 7ae479a7b3052ae4198242d9e189edcc215aecf8 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 12:10:28 +0200 Subject: [PATCH 47/84] add caching for windows runner --- .github/workflows/CI.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 984022ee7..061166c5c 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -230,6 +230,19 @@ jobs: key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}-${{ hashFiles('**/requirements-tests.txt') }} -${{ hashFiles('**/requirements-extras.txt') }}-${{ hashFiles('setup.py') }} -${{ hashFiles('**/CI.yml') }}-${{ steps.date.outputs.date }} + - name: Get current hash (SHA) of the elephant_data repo + id: elephant-data + run: | + echo "dataset_hash=$(git ls-remote https://gin.g-node.org/NeuralEnsemble/elephant-data.git HEAD | cut -f1)" >> $GITHUB_OUTPUT + + - uses: actions/cache/restore@v3 + # Loading cache of elephant-data + id: cache-datasets + with: + path: ~/elephant-data + key: ${{ runner.os }}-datasets-${{ steps.elephant-data.outputs.dataset_hash }} + restore-keys: ${{ runner.os }}-datasets- + - name: Install dependencies run: | python -m pip install --upgrade pip @@ -243,6 +256,10 @@ jobs: - name: Test with pytest run: | + if (Test-Path "$env:~\elephant-data") { + $env:ELEPHANT_DATA_PATH = "$env:~\elephant-data" + Write-Output $env:ELEPHANT_DATA_PATH + } pytest --cov=elephant # __ __ ____ ___ From 41b72467e7d1cce9d63370ba49e3bed223e9f504 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 12:17:09 +0200 Subject: [PATCH 48/84] update path for winows --- .github/workflows/CI.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 061166c5c..b75451d4b 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -256,8 +256,8 @@ jobs: - name: Test with pytest run: | - if (Test-Path "$env:~\elephant-data") { - $env:ELEPHANT_DATA_PATH = "$env:~\elephant-data" + if (Test-Path "$env:USERPROFILE\elephant-data") { + $env:ELEPHANT_DATA_PATH = "$env:USERPROFILE\elephant-data" Write-Output $env:ELEPHANT_DATA_PATH } pytest --cov=elephant From bf4e03da0375c536e7351af716099e20c5dc2daf Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 12:19:14 +0200 Subject: [PATCH 49/84] update setup python for windows --- .github/workflows/CI.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index b75451d4b..da5d78076 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -221,6 +221,12 @@ jobs: uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} + check-latest: true + cache: 'pip' + cache-dependency-path: | + **/requirements.txt + **/requirements-extras.txt + **/requirements-tests.txt - name: Cache pip uses: actions/cache@v3 From fe20f4e47a5f6cfa3745a3280a9456df9052ae31 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 12:28:11 +0200 Subject: [PATCH 50/84] caching on windows runner with setup Python --- .github/workflows/CI.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index da5d78076..04d33f622 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -211,10 +211,6 @@ jobs: os: [windows-latest] steps: - - name: Get current year-month - id: date - run: echo "date=$(date +'%Y-%m')" >> $GITHUB_OUTPUT - - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} @@ -228,14 +224,6 @@ jobs: **/requirements-extras.txt **/requirements-tests.txt - - name: Cache pip - uses: actions/cache@v3 - with: - path: ~\AppData\Local\pip\Cache - # Look to see if there is a cache hit for the corresponding requirements files - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}-${{ hashFiles('**/requirements-tests.txt') }} - -${{ hashFiles('**/requirements-extras.txt') }}-${{ hashFiles('setup.py') }} -${{ hashFiles('**/CI.yml') }}-${{ steps.date.outputs.date }} - - name: Get current hash (SHA) of the elephant_data repo id: elephant-data run: | From c45ca7080b42ffbd7fa68df6cf411252f6eda2c3 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 12:37:27 +0200 Subject: [PATCH 51/84] update caching for MPI --- .github/workflows/CI.yml | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 04d33f622..03a320d24 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -276,29 +276,18 @@ jobs: fail-fast: false steps: - - name: Get current year-month - id: date - run: echo "date=$(date +'%Y-%m')" >> $GITHUB_OUTPUT - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - - - name: Get pip cache dir - id: pip-cache - run: | - echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT - - - name: Cache test_env - uses: actions/cache@v3 - with: - path: ${{ steps.pip-cache.outputs.dir }} - # look to see if there is a cache hit for the corresponding requirements files - # cache will be reset on changes to any requirements or every month - key: ${{ runner.os }}-venv-${{ hashFiles('**/requirements.txt') }}-${{ hashFiles('**/requirements-tests.txt') }} - -${{ hashFiles('**/requirements-extras.txt') }}-${{ hashFiles('setup.py') }} -${{ hashFiles('**/CI.yml') }}-${{ steps.date.outputs.date }} + check-latest: true + cache: 'pip' + cache-dependency-path: | + **/requirements.txt + **/requirements-extras.txt + **/requirements-tests.txt - name: Get current hash (SHA) of the elephant_data repo id: elephant-data From c98440d924270eec6d6096e3a3330077d29de7a7 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 12:40:42 +0200 Subject: [PATCH 52/84] change if cond in caching --- .github/workflows/cache_elephant_data.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index 9574a0e72..91e0ad3c3 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -56,7 +56,7 @@ jobs: brew install datalad - name: Install Datalad Linux/ Windows - if: steps.cache-datasets.outputs.cache-hit != 'true' && runner.os == 'Linux' || runner.os == 'Windows' + if: steps.cache-datasets.outputs.cache-hit != 'true' && (runner.os == 'Linux' || runner.os == 'Windows') run: | python -m pip install -U pip # Official recommended way pip install datalad-installer From 93d13c8e4283cdd0d0c3e0926375b091d2db468c Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 13:56:05 +0200 Subject: [PATCH 53/84] remove PR trigger from caching action --- .github/workflows/cache_elephant_data.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index 91e0ad3c3..48fbee443 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -8,14 +8,6 @@ on: schedule: - cron: "0 12 * * *" # Daily at noon UTC - pull_request: - branches: - - master - types: - - opened - - reopened - - synchronize - jobs: create-data-cache-if-missing: name: Caching data env From cca7bae9045b4481e3de8f25e9112ac659f9df05 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 14:04:05 +0200 Subject: [PATCH 54/84] revert formatting for phase analysis --- elephant/test/test_phase_analysis.py | 571 +++++++++------------------ 1 file changed, 192 insertions(+), 379 deletions(-) diff --git a/elephant/test/test_phase_analysis.py b/elephant/test/test_phase_analysis.py index be42f0245..c17059c5a 100644 --- a/elephant/test/test_phase_analysis.py +++ b/elephant/test/test_phase_analysis.py @@ -20,41 +20,31 @@ class SpikeTriggeredPhaseTestCase(unittest.TestCase): + def setUp(self): tlen0 = 100 * pq.s - f0 = 20.0 * pq.Hz + f0 = 20. * pq.Hz fs0 = 1 * pq.ms - t0 = ( - np.arange( - 0, tlen0.rescale(pq.s).magnitude, fs0.rescale(pq.s).magnitude - ) - * pq.s - ) + t0 = np.arange( + 0, tlen0.rescale(pq.s).magnitude, + fs0.rescale(pq.s).magnitude) * pq.s self.anasig0 = AnalogSignal( np.sin(2 * np.pi * (f0 * t0).simplified.magnitude), - units=pq.mV, - t_start=0 * pq.ms, - sampling_period=fs0, - ) + units=pq.mV, t_start=0 * pq.ms, sampling_period=fs0) self.st0 = SpikeTrain( np.arange(50, tlen0.rescale(pq.ms).magnitude - 50, 50) * pq.ms, - t_start=0 * pq.ms, - t_stop=tlen0, - ) + t_start=0 * pq.ms, t_stop=tlen0) self.st1 = SpikeTrain( - [100.0, 100.1, 100.2, 100.3, 100.9, 101.0] * pq.ms, - t_start=0 * pq.ms, - t_stop=tlen0, - ) + [100., 100.1, 100.2, 100.3, 100.9, 101.] * pq.ms, + t_start=0 * pq.ms, t_stop=tlen0) def test_perfect_locking_one_spiketrain_one_signal(self): phases, amps, times = elephant.phase_analysis.spike_triggered_phase( elephant.signal_processing.hilbert(self.anasig0), self.st0, - interpolate=True, - ) + interpolate=True) - assert_allclose(phases[0], -np.pi / 2.0) + assert_allclose(phases[0], - np.pi / 2.) assert_allclose(amps[0], 1, atol=0.1) assert_allclose(times[0].magnitude, self.st0.magnitude) self.assertEqual(len(phases[0]), len(self.st0)) @@ -65,13 +55,11 @@ def test_perfect_locking_many_spiketrains_many_signals(self): phases, amps, times = elephant.phase_analysis.spike_triggered_phase( [ elephant.signal_processing.hilbert(self.anasig0), - elephant.signal_processing.hilbert(self.anasig0), - ], + elephant.signal_processing.hilbert(self.anasig0)], [self.st0, self.st0], - interpolate=True, - ) + interpolate=True) - assert_allclose(phases[0], -np.pi / 2.0) + assert_allclose(phases[0], -np.pi / 2.) assert_allclose(amps[0], 1, atol=0.1) assert_allclose(times[0].magnitude, self.st0.magnitude) self.assertEqual(len(phases[0]), len(self.st0)) @@ -82,13 +70,11 @@ def test_perfect_locking_one_spiketrains_many_signals(self): phases, amps, times = elephant.phase_analysis.spike_triggered_phase( [ elephant.signal_processing.hilbert(self.anasig0), - elephant.signal_processing.hilbert(self.anasig0), - ], + elephant.signal_processing.hilbert(self.anasig0)], [self.st0], - interpolate=True, - ) + interpolate=True) - assert_allclose(phases[0], -np.pi / 2.0) + assert_allclose(phases[0], -np.pi / 2.) assert_allclose(amps[0], 1, atol=0.1) assert_allclose(times[0].magnitude, self.st0.magnitude) self.assertEqual(len(phases[0]), len(self.st0)) @@ -99,10 +85,9 @@ def test_perfect_locking_many_spiketrains_one_signal(self): phases, amps, times = elephant.phase_analysis.spike_triggered_phase( elephant.signal_processing.hilbert(self.anasig0), [self.st0, self.st0], - interpolate=True, - ) + interpolate=True) - assert_allclose(phases[0], -np.pi / 2.0) + assert_allclose(phases[0], -np.pi / 2.) assert_allclose(amps[0], 1, atol=0.1) assert_allclose(times[0].magnitude, self.st0.magnitude) self.assertEqual(len(phases[0]), len(self.st0)) @@ -113,8 +98,7 @@ def test_interpolate(self): phases_int, _, _ = elephant.phase_analysis.spike_triggered_phase( elephant.signal_processing.hilbert(self.anasig0), self.st1, - interpolate=True, - ) + interpolate=True) self.assertLess(phases_int[0][0], phases_int[0][1]) self.assertLess(phases_int[0][1], phases_int[0][2]) @@ -125,8 +109,7 @@ def test_interpolate(self): phases_noint, _, _ = elephant.phase_analysis.spike_triggered_phase( elephant.signal_processing.hilbert(self.anasig0), self.st1, - interpolate=False, - ) + interpolate=False) self.assertEqual(phases_noint[0][0], phases_noint[0][1]) self.assertEqual(phases_noint[0][1], phases_noint[0][2]) @@ -142,37 +125,28 @@ def test_interpolate(self): def test_inconsistent_numbers_spiketrains_hilbert(self): self.assertRaises( - ValueError, - elephant.phase_analysis.spike_triggered_phase, + ValueError, elephant.phase_analysis.spike_triggered_phase, [ elephant.signal_processing.hilbert(self.anasig0), - elephant.signal_processing.hilbert(self.anasig0), - ], - [self.st0, self.st0, self.st0], - False, - ) + elephant.signal_processing.hilbert(self.anasig0)], + [self.st0, self.st0, self.st0], False) self.assertRaises( - ValueError, - elephant.phase_analysis.spike_triggered_phase, + ValueError, elephant.phase_analysis.spike_triggered_phase, [ elephant.signal_processing.hilbert(self.anasig0), - elephant.signal_processing.hilbert(self.anasig0), - ], - [self.st0, self.st0, self.st0], - False, - ) + elephant.signal_processing.hilbert(self.anasig0)], + [self.st0, self.st0, self.st0], False) def test_spike_earlier_than_hilbert(self): # This is a spike clearly outside the bounds st = SpikeTrain( - [-50, 50], units="s", t_start=-100 * pq.s, t_stop=100 * pq.s - ) + [-50, 50], + units='s', t_start=-100 * pq.s, t_stop=100 * pq.s) phases_noint, _, _ = elephant.phase_analysis.spike_triggered_phase( elephant.signal_processing.hilbert(self.anasig0), st, - interpolate=False, - ) + interpolate=False) self.assertEqual(len(phases_noint[0]), 1) # This is a spike right on the border (start of the signal is at 0s, @@ -180,25 +154,23 @@ def test_spike_earlier_than_hilbert(self): # Elephant (left borders inclusive, right borders exclusive), this # spike is to be considered. st = SpikeTrain( - [0, 50], units="s", t_start=-100 * pq.s, t_stop=100 * pq.s - ) + [0, 50], + units='s', t_start=-100 * pq.s, t_stop=100 * pq.s) phases_noint, _, _ = elephant.phase_analysis.spike_triggered_phase( elephant.signal_processing.hilbert(self.anasig0), st, - interpolate=False, - ) + interpolate=False) self.assertEqual(len(phases_noint[0]), 2) def test_spike_later_than_hilbert(self): # This is a spike clearly outside the bounds st = SpikeTrain( - [1, 250], units="s", t_start=-1 * pq.s, t_stop=300 * pq.s - ) + [1, 250], + units='s', t_start=-1 * pq.s, t_stop=300 * pq.s) phases_noint, _, _ = elephant.phase_analysis.spike_triggered_phase( elephant.signal_processing.hilbert(self.anasig0), st, - interpolate=False, - ) + interpolate=False) self.assertEqual(len(phases_noint[0]), 1) # This is a spike right on the border (length of the signal is 100s, @@ -206,13 +178,12 @@ def test_spike_later_than_hilbert(self): # Elephant (left borders inclusive, right borders exclusive), this # spike is not to be considered. st = SpikeTrain( - [1, 100], units="s", t_start=-1 * pq.s, t_stop=200 * pq.s - ) + [1, 100], + units='s', t_start=-1 * pq.s, t_stop=200 * pq.s) phases_noint, _, _ = elephant.phase_analysis.spike_triggered_phase( elephant.signal_processing.hilbert(self.anasig0), st, - interpolate=False, - ) + interpolate=False) self.assertEqual(len(phases_noint[0]), 1) # This test handles the correct dealing with input signals that have @@ -222,16 +193,13 @@ def test_regression_269(self): # before the end of the signal cu = pq.CompoundUnit("1/30000.*s") st = SpikeTrain( - [30000.0, (self.anasig0.t_stop - 1 * pq.s).rescale(cu).magnitude], + [30000., (self.anasig0.t_stop - 1 * pq.s).rescale(cu).magnitude], units=pq.CompoundUnit("1/30000.*s"), - t_start=-1 * pq.s, - t_stop=300 * pq.s, - ) + t_start=-1 * pq.s, t_stop=300 * pq.s) phases_noint, _, _ = elephant.phase_analysis.spike_triggered_phase( elephant.signal_processing.hilbert(self.anasig0), st, - interpolate=False, - ) + interpolate=False) self.assertEqual(len(phases_noint[0]), 2) @@ -254,12 +222,10 @@ def testMeanVector_direction_is_phi_and_length_is_1(self): """ theta_bar_1, r_1 = elephant.phase_analysis.mean_phase_vector( - self.dataset1 - ) + self.dataset1) # mean direction must be phi - self.assertAlmostEqual( - theta_bar_1, self.lock_value_phi, delta=self.tolerance - ) + self.assertAlmostEqual(theta_bar_1, self.lock_value_phi, + delta=self.tolerance) # mean vector length must be almost equal 1 self.assertAlmostEqual(r_1, 1, delta=self.tolerance) @@ -269,8 +235,7 @@ def testMeanVector_length_is_0(self): on the unit circle. """ theta_bar_2, r_2 = elephant.phase_analysis.mean_phase_vector( - self.dataset2 - ) + self.dataset2) # mean vector length must be almost equal 0 self.assertAlmostEqual(r_2, 0, delta=self.tolerance) @@ -281,8 +246,7 @@ def testMeanVector_ranges_of_direction_and_length(self): Test if the range of the mean vector length is within [0, 1]. """ theta_bar_3, r_3 = elephant.phase_analysis.mean_phase_vector( - self.dataset3 - ) + self.dataset3) # mean vector direction self.assertTrue(-np.pi < theta_bar_3 <= np.pi) # mean vector length @@ -303,9 +267,8 @@ def testPhaseDifference_in_range_minus_pi_to_pi(self): beta = np.random.uniform(-np.pi, np.pi, self.n_samples) phase_diff = elephant.phase_analysis.phase_difference(alpha, beta) - self.assertTrue( - (-np.pi <= phase_diff).all() and (phase_diff <= np.pi).all() - ) + self.assertTrue((-np.pi <= phase_diff).all() + and (phase_diff <= np.pi).all()) def testPhaseDifference_is_delta(self): """ @@ -329,22 +292,18 @@ def setUp(self): self.num_trials = 100 # create two random uniform distributions (all trials are identical) - self.signal_x = np.full( - [self.num_trials, self.num_time_points], - np.random.uniform(-np.pi, np.pi, self.num_time_points), - ) - self.signal_y = np.full( - [self.num_trials, self.num_time_points], - np.random.uniform(-np.pi, np.pi, self.num_time_points), - ) + self.signal_x = \ + np.full([self.num_trials, self.num_time_points], + np.random.uniform(-np.pi, np.pi, self.num_time_points)) + self.signal_y = \ + np.full([self.num_trials, self.num_time_points], + np.random.uniform(-np.pi, np.pi, self.num_time_points)) # create two random uniform distributions, where all trails are random self.random_x = np.random.uniform( - -np.pi, np.pi, (1000, self.num_time_points) - ) + -np.pi, np.pi, (1000, self.num_time_points)) self.random_y = np.random.uniform( - -np.pi, np.pi, (1000, self.num_time_points) - ) + -np.pi, np.pi, (1000, self.num_time_points)) # simple samples of different shapes to assert ErrorRaising self.simple_x = np.array([[0, -np.pi, np.pi], [0, -np.pi, np.pi]]) @@ -357,13 +316,12 @@ def testPhaseLockingValue_identical_signals_both_identical_trials(self): trials are passed. PLV's needed to be 1, due to the constant phase difference of 0 across trials at each time-point. """ - list1_plv_t = elephant.phase_analysis.phase_locking_value( - self.signal_x, self.signal_x - ) + list1_plv_t = \ + elephant.phase_analysis.phase_locking_value(self.signal_x, + self.signal_x) target_plv_r_is_one = np.ones_like(list1_plv_t) - np.testing.assert_allclose( - list1_plv_t, target_plv_r_is_one, self.tolerance - ) + np.testing.assert_allclose(list1_plv_t, target_plv_r_is_one, + self.tolerance) def testPhaseLockingValue_different_signals_both_identical_trials(self): """ @@ -373,12 +331,10 @@ def testPhaseLockingValue_different_signals_both_identical_trials(self): different time-points. """ list2_plv_t = elephant.phase_analysis.phase_locking_value( - self.signal_x, self.signal_y - ) + self.signal_x, self.signal_y) target_plv_r_is_one = np.ones_like(list2_plv_t) - np.testing.assert_allclose( - list2_plv_t, target_plv_r_is_one, atol=3e-15 - ) + np.testing.assert_allclose(list2_plv_t, target_plv_r_is_one, + atol=3e-15) def testPhaseLockingValue_different_signals_both_different_trials(self): """ @@ -388,13 +344,11 @@ def testPhaseLockingValue_different_signals_both_different_trials(self): phase difference across trials for each time-point. """ list3_plv_t = elephant.phase_analysis.phase_locking_value( - self.random_x, self.random_y - ) + self.random_x, self.random_y) target_plv_is_zero = np.zeros_like(list3_plv_t) # use default value from np.allclose() for atol=1e-8 to prevent failure - np.testing.assert_allclose( - list3_plv_t, target_plv_is_zero, rtol=1e-2, atol=1.1e-1 - ) + np.testing.assert_allclose(list3_plv_t, target_plv_is_zero, + rtol=1e-2, atol=1.1e-1) def testPhaseLockingValue_raise_Error_if_trial_number_is_different(self): """ @@ -403,11 +357,8 @@ def testPhaseLockingValue_raise_Error_if_trial_number_is_different(self): """ # different numbers of trails np.testing.assert_raises( - ValueError, - elephant.phase_analysis.phase_locking_value, - self.simple_x, - self.simple_y, - ) + ValueError, elephant.phase_analysis.phase_locking_value, + self.simple_x, self.simple_y) def testPhaseLockingValue_raise_Error_if_trial_lengths_are_different(self): """ @@ -416,11 +367,8 @@ def testPhaseLockingValue_raise_Error_if_trial_lengths_are_different(self): """ # different lengths in a trail pair np.testing.assert_raises( - ValueError, - elephant.phase_analysis.phase_locking_value, - self.simple_y, - self.simple_z, - ) + ValueError, elephant.phase_analysis.phase_locking_value, + self.simple_y, self.simple_z) class WeightedPhaseLagIndexTestCase(unittest.TestCase): @@ -438,38 +386,26 @@ def setUpClass(cls): cls.tmp_path = {} # REAL DATA - real_data_path = ( - "unittest/phase_analysis/weighted_phase_lag_index/" - "data/wpli_real_data" - ) + real_data_path = "unittest/phase_analysis/weighted_phase_lag_index/" \ + "data/wpli_real_data" cls.files_to_download_real = ( - ( - "i140703-001_ch01_slice_TS_ON_to_GO_ON_correct_trials.mat", - "0e76454c58208cab710e672d04de5168", - ), - ( - "i140703-001_ch02_slice_TS_ON_to_GO_ON_correct_trials.mat", - "b06059e5222e91eb640caad0aba15b7f", - ), - ( - "i140703-001_cross_spectrum_of_channel_1_and_2_of_slice_" - "TS_ON_to_GO_ON_corect_trials.mat", - "2687ef63a4a456971a5dcc621b02e9a9", - ), + ("i140703-001_ch01_slice_TS_ON_to_GO_ON_correct_trials.mat", + "0e76454c58208cab710e672d04de5168"), + ("i140703-001_ch02_slice_TS_ON_to_GO_ON_correct_trials.mat", + "b06059e5222e91eb640caad0aba15b7f"), + ("i140703-001_cross_spectrum_of_channel_1_and_2_of_slice_" + "TS_ON_to_GO_ON_corect_trials.mat", + "2687ef63a4a456971a5dcc621b02e9a9") ) for filename, checksum in cls.files_to_download_real: # files will be downloaded to ELEPHANT_TMP_DIR cls.tmp_path[filename] = { - "filename": filename, - "path": download_datasets( - f"{real_data_path}/{filename}", checksum=checksum - ), - } + 'filename':filename, + 'path':download_datasets( + f"{real_data_path}/{filename}", checksum=checksum)} # ARTIFICIAL DATA - artificial_data_path = ( - "unittest/phase_analysis/" + artificial_data_path = "unittest/phase_analysis/" \ "weighted_phase_lag_index/data/wpli_specific_artificial_dataset" - ) cls.files_to_download_artificial = ( ("artificial_LFPs_1.mat", "4b99b15f89c0b9a0eb6fc14e9009436f"), ("artificial_LFPs_2.mat", "7144976b5f871fa62f4a831f530deee4"), @@ -477,36 +413,24 @@ def setUpClass(cls): for filename, checksum in cls.files_to_download_artificial: # files will be downloaded to ELEPHANT_TMP_DIR cls.tmp_path[filename] = { - "filename": filename, - "path": download_datasets( - f"{artificial_data_path}/{filename}", checksum=checksum - ), - } + 'filename':filename, + 'path':download_datasets( + f"{artificial_data_path}/{filename}", checksum=checksum)} # GROUND TRUTH DATA - ground_truth_data_path = ( - "unittest/phase_analysis/" - "weighted_phase_lag_index/data/wpli_ground_truth" - ) + ground_truth_data_path = "unittest/phase_analysis/" \ + "weighted_phase_lag_index/data/wpli_ground_truth" cls.files_to_download_ground_truth = ( - ( - "ground_truth_WPLI_from_ft_connectivity_wpli_" - "with_real_LFPs_R2G.csv", - "4d9a7b7afab7d107023956077ab11fef", - ), - ( - "ground_truth_WPLI_from_ft_connectivity_wpli_" - "with_artificial_LFPs.csv", - "92988f475333d7badbe06b3f23abe494", - ), + ("ground_truth_WPLI_from_ft_connectivity_wpli_" + "with_real_LFPs_R2G.csv", "4d9a7b7afab7d107023956077ab11fef"), + ("ground_truth_WPLI_from_ft_connectivity_wpli_" + "with_artificial_LFPs.csv", "92988f475333d7badbe06b3f23abe494"), ) for filename, checksum in cls.files_to_download_ground_truth: # files will be downloaded into ELEPHANT_TMP_DIR cls.tmp_path[filename] = { - "filename": filename, - "path": download_datasets( - f"{ground_truth_data_path}/{filename}", checksum=checksum - ), - } + 'filename':filename, + 'path':download_datasets( + f"{ground_truth_data_path}/{filename}", checksum=checksum)} def setUp(self): self.tolerance = 1e-15 @@ -515,60 +439,46 @@ def setUp(self): # real LFP-dataset dataset1_real = scipy.io.loadmat( f"{self.tmp_path[self.files_to_download_real[0][0]]['path']}", - squeeze_me=True, - ) + squeeze_me=True) dataset2_real = scipy.io.loadmat( f"{self.tmp_path[self.files_to_download_real[1][0]]['path']}", - squeeze_me=True, - ) + squeeze_me=True) # get relevant values - self.lfps1_real = dataset1_real["lfp_matrix"] * pq.uV - self.sf1_real = dataset1_real["sf"] * pq.Hz - self.lfps2_real = dataset2_real["lfp_matrix"] * pq.uV - self.sf2_real = dataset2_real["sf"] * pq.Hz + self.lfps1_real = dataset1_real['lfp_matrix'] * pq.uV + self.sf1_real = dataset1_real['sf'] * pq.Hz + self.lfps2_real = dataset2_real['lfp_matrix'] * pq.uV + self.sf2_real = dataset2_real['sf'] * pq.Hz # create AnalogSignals from the real dataset self.lfps1_real_AnalogSignal = AnalogSignal( - signal=self.lfps1_real, sampling_rate=self.sf1_real - ) + signal=self.lfps1_real, sampling_rate=self.sf1_real) self.lfps2_real_AnalogSignal = AnalogSignal( - signal=self.lfps2_real, sampling_rate=self.sf2_real - ) + signal=self.lfps2_real, sampling_rate=self.sf2_real) # artificial LFP-dataset dataset1_artificial = scipy.io.loadmat( - f"{self.tmp_path[self.files_to_download_artificial[0][0]]['path']}", - squeeze_me=True, - ) + f"{self.tmp_path[self.files_to_download_artificial[0][0]]['path']}", squeeze_me=True) dataset2_artificial = scipy.io.loadmat( - f"{self.tmp_path[self.files_to_download_artificial[1][0]]['path']}", - squeeze_me=True, - ) + f"{self.tmp_path[self.files_to_download_artificial[1][0]]['path']}", squeeze_me=True) # get relevant values - self.lfps1_artificial = dataset1_artificial["lfp_matrix"] * pq.uV - self.sf1_artificial = dataset1_artificial["sf"] * pq.Hz - self.lfps2_artificial = dataset2_artificial["lfp_matrix"] * pq.uV - self.sf2_artificial = dataset2_artificial["sf"] * pq.Hz + self.lfps1_artificial = dataset1_artificial['lfp_matrix'] * pq.uV + self.sf1_artificial = dataset1_artificial['sf'] * pq.Hz + self.lfps2_artificial = dataset2_artificial['lfp_matrix'] * pq.uV + self.sf2_artificial = dataset2_artificial['sf'] * pq.Hz # create AnalogSignals from the artificial dataset self.lfps1_artificial_AnalogSignal = AnalogSignal( - signal=self.lfps1_artificial, sampling_rate=self.sf1_artificial - ) + signal=self.lfps1_artificial, sampling_rate=self.sf1_artificial) self.lfps2_artificial_AnalogSignal = AnalogSignal( - signal=self.lfps2_artificial, sampling_rate=self.sf2_artificial - ) + signal=self.lfps2_artificial, sampling_rate=self.sf2_artificial) # load ground-truth reference calculated by: # Matlab package 'FieldTrip': ft_connectivity_wpli() self.wpli_ground_truth_ft_connectivity_wpli_real = np.loadtxt( f"{self.tmp_path[self.files_to_download_ground_truth[0][0]]['path']}", - delimiter=",", - dtype=np.float64, - ) + delimiter=',', dtype=np.float64) self.wpli_ground_truth_ft_connectivity_artificial = np.loadtxt( f"{self.tmp_path[self.files_to_download_ground_truth[1][0]]['path']}", - delimiter=",", - dtype=np.float64, - ) + delimiter=',', dtype=np.float64) def test_WPLI_ground_truth_consistency_real_LFP_dataset(self): """ @@ -586,35 +496,25 @@ def test_WPLI_ground_truth_consistency_real_LFP_dataset(self): # Quantity-input with self.subTest(msg="Quantity input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( - self.lfps1_real, self.lfps2_real, self.sf1_real - ) + self.lfps1_real, self.lfps2_real, self.sf1_real) np.testing.assert_allclose( - wpli, - self.wpli_ground_truth_ft_connectivity_wpli_real, - equal_nan=True, - ) + wpli, self.wpli_ground_truth_ft_connectivity_wpli_real, + equal_nan=True) # np.array-input with self.subTest(msg="np.array input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( - self.lfps1_real.magnitude, - self.lfps2_real.magnitude, - self.sf1_real, - ) + self.lfps1_real.magnitude, self.lfps2_real.magnitude, + self.sf1_real) np.testing.assert_allclose( - wpli, - self.wpli_ground_truth_ft_connectivity_wpli_real, - equal_nan=True, - ) + wpli, self.wpli_ground_truth_ft_connectivity_wpli_real, + equal_nan=True) # neo.AnalogSignal-input with self.subTest(msg="neo.AnalogSignal input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( - self.lfps1_real_AnalogSignal, self.lfps2_real_AnalogSignal - ) + self.lfps1_real_AnalogSignal, self.lfps2_real_AnalogSignal) np.testing.assert_allclose( - wpli, - self.wpli_ground_truth_ft_connectivity_wpli_real, - equal_nan=True, - ) + wpli, self.wpli_ground_truth_ft_connectivity_wpli_real, + equal_nan=True) def test_WPLI_ground_truth_consistency_artificial_LFP_dataset(self): """ @@ -629,47 +529,28 @@ def test_WPLI_ground_truth_consistency_artificial_LFP_dataset(self): # Quantity-input with self.subTest(msg="Quantity input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( - self.lfps1_artificial, - self.lfps2_artificial, - self.sf1_artificial, - absolute_value=False, - ) + self.lfps1_artificial, self.lfps2_artificial, + self.sf1_artificial, absolute_value=False) np.testing.assert_allclose( - wpli, - self.wpli_ground_truth_ft_connectivity_artificial, - atol=1e-14, - rtol=1e-12, - equal_nan=True, - ) + wpli, self.wpli_ground_truth_ft_connectivity_artificial, + atol=1e-14, rtol=1e-12, equal_nan=True) # np.array-input with self.subTest(msg="np.array input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( self.lfps1_artificial.magnitude, - self.lfps2_artificial.magnitude, - self.sf1_artificial, - absolute_value=False, - ) + self.lfps2_artificial.magnitude, self.sf1_artificial, + absolute_value=False) np.testing.assert_allclose( - wpli, - self.wpli_ground_truth_ft_connectivity_artificial, - atol=1e-14, - rtol=1e-12, - equal_nan=True, - ) + wpli, self.wpli_ground_truth_ft_connectivity_artificial, + atol=1e-14, rtol=1e-12, equal_nan=True) # neo.AnalogSignal-input with self.subTest(msg="neo.AnalogSignal input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( self.lfps1_artificial_AnalogSignal, - self.lfps2_artificial_AnalogSignal, - absolute_value=False, - ) + self.lfps2_artificial_AnalogSignal, absolute_value=False) np.testing.assert_allclose( - wpli, - self.wpli_ground_truth_ft_connectivity_artificial, - atol=1e-14, - rtol=1e-12, - equal_nan=True, - ) + wpli, self.wpli_ground_truth_ft_connectivity_artificial, + atol=1e-14, rtol=1e-12, equal_nan=True) def test_WPLI_is_zero(self): """ @@ -679,35 +560,25 @@ def test_WPLI_is_zero(self): # Quantity-input with self.subTest(msg="Quantity input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( - self.lfps1_artificial, - self.lfps2_artificial, - self.sf1_artificial, - absolute_value=False, - ) + self.lfps1_artificial, self.lfps2_artificial, + self.sf1_artificial, absolute_value=False) np.testing.assert_allclose( - wpli[freq == 70], 0, atol=0.004, rtol=self.tolerance - ) + wpli[freq == 70], 0, atol=0.004, rtol=self.tolerance) # np.array-input with self.subTest(msg="np.array input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( self.lfps1_artificial.magnitude, - self.lfps2_artificial.magnitude, - self.sf1_artificial, - absolute_value=False, - ) + self.lfps2_artificial.magnitude, self.sf1_artificial, + absolute_value=False) np.testing.assert_allclose( - wpli[freq == 70], 0, atol=0.004, rtol=self.tolerance - ) + wpli[freq == 70], 0, atol=0.004, rtol=self.tolerance) # neo.AnalogSignal-input with self.subTest(msg="neo.AnalogSignal input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( self.lfps1_artificial_AnalogSignal, - self.lfps2_artificial_AnalogSignal, - absolute_value=False, - ) + self.lfps2_artificial_AnalogSignal, absolute_value=False) np.testing.assert_allclose( - wpli[freq == 70], 0, atol=0.004, rtol=self.tolerance - ) + wpli[freq == 70], 0, atol=0.004, rtol=self.tolerance) def test_WPLI_is_one(self): """ @@ -717,38 +588,28 @@ def test_WPLI_is_one(self): # Quantity-input with self.subTest(msg="Quantity input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( - self.lfps1_artificial, - self.lfps2_artificial, - self.sf1_artificial, - absolute_value=False, - ) - mask = (freq == 16) | (freq == 36) + self.lfps1_artificial, self.lfps2_artificial, + self.sf1_artificial, absolute_value=False) + mask = ((freq == 16) | (freq == 36)) np.testing.assert_allclose( - wpli[mask], 1, atol=self.tolerance, rtol=self.tolerance - ) + wpli[mask], 1, atol=self.tolerance, rtol=self.tolerance) # np.array-input with self.subTest(msg="np.array input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( self.lfps1_artificial.magnitude, - self.lfps2_artificial.magnitude, - self.sf1_artificial, - absolute_value=False, - ) - mask = (freq == 16) | (freq == 36) + self.lfps2_artificial.magnitude, self.sf1_artificial, + absolute_value=False) + mask = ((freq == 16) | (freq == 36)) np.testing.assert_allclose( - wpli[mask], 1, atol=self.tolerance, rtol=self.tolerance - ) + wpli[mask], 1, atol=self.tolerance, rtol=self.tolerance) # neo.AnalogSignal-input with self.subTest(msg="neo.AnalogSignal input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( self.lfps1_artificial_AnalogSignal, - self.lfps2_artificial_AnalogSignal, - absolute_value=False, - ) - mask = (freq == 16) | (freq == 36) + self.lfps2_artificial_AnalogSignal, absolute_value=False) + mask = ((freq == 16) | (freq == 36)) np.testing.assert_allclose( - wpli[mask], 1, atol=self.tolerance, rtol=self.tolerance - ) + wpli[mask], 1, atol=self.tolerance, rtol=self.tolerance) def test_WPLI_is_minus_one(self): """ @@ -758,36 +619,26 @@ def test_WPLI_is_minus_one(self): # Quantity-input with self.subTest(msg="Quantity input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( - self.lfps1_artificial, - self.lfps2_artificial, - self.sf1_artificial, - absolute_value=False, - ) - mask = (freq == 52) | (freq == 100) + self.lfps1_artificial, self.lfps2_artificial, + self.sf1_artificial, absolute_value=False) + mask = ((freq == 52) | (freq == 100)) np.testing.assert_allclose( - wpli[mask], -1, atol=self.tolerance, rtol=self.tolerance - ) + wpli[mask], -1, atol=self.tolerance, rtol=self.tolerance) # np.array-input with self.subTest(msg="np.array input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( self.lfps1_artificial.magnitude, - self.lfps2_artificial.magnitude, - self.sf1_artificial, - absolute_value=False, - ) + self.lfps2_artificial.magnitude, self.sf1_artificial, + absolute_value=False) np.testing.assert_allclose( - wpli[mask], -1, atol=self.tolerance, rtol=self.tolerance - ) + wpli[mask], -1, atol=self.tolerance, rtol=self.tolerance) # neo.AnalogSignal-input with self.subTest(msg="neo.AnalogSignal input"): freq, wpli = elephant.phase_analysis.weighted_phase_lag_index( self.lfps1_artificial_AnalogSignal, - self.lfps2_artificial_AnalogSignal, - absolute_value=False, - ) + self.lfps2_artificial_AnalogSignal, absolute_value=False) np.testing.assert_allclose( - wpli[mask], -1, atol=self.tolerance, rtol=self.tolerance - ) + wpli[mask], -1, atol=self.tolerance, rtol=self.tolerance) def test_WPLI_raises_error_if_signals_have_different_shapes(self): """ @@ -800,63 +651,40 @@ def test_WPLI_raises_error_if_signals_have_different_shapes(self): trials1_length4 = np.array([[0, 1, 1 / 2, -1]]) * pq.uV sampling_frequency = 250 * pq.Hz trials2_length3_analogsignal = AnalogSignal( - signal=trials2_length3, sampling_rate=sampling_frequency - ) + signal=trials2_length3, sampling_rate=sampling_frequency) trials1_length3_analogsignal = AnalogSignal( - signal=trials1_length3, sampling_rate=sampling_frequency - ) + signal=trials1_length3, sampling_rate=sampling_frequency) trials1_length4_analogsignal = AnalogSignal( - signal=trials1_length4, sampling_rate=sampling_frequency - ) + signal=trials1_length4, sampling_rate=sampling_frequency) # different numbers of trails with self.subTest(msg="diff. trial numbers & Quantity input"): np.testing.assert_raises( - ValueError, - elephant.phase_analysis.weighted_phase_lag_index, - trials2_length3, - trials1_length3, - sampling_frequency, - ) + ValueError, elephant.phase_analysis.weighted_phase_lag_index, + trials2_length3, trials1_length3, sampling_frequency) with self.subTest(msg="diff. trial numbers & np.array input"): np.testing.assert_raises( - ValueError, - elephant.phase_analysis.weighted_phase_lag_index, - trials2_length3.magnitude, - trials1_length3.magnitude, - sampling_frequency, - ) + ValueError, elephant.phase_analysis.weighted_phase_lag_index, + trials2_length3.magnitude, trials1_length3.magnitude, + sampling_frequency) with self.subTest(msg="diff. trial numbers & neo.AnalogSignal input"): np.testing.assert_raises( - ValueError, - elephant.phase_analysis.weighted_phase_lag_index, - trials2_length3_analogsignal, - trials1_length3_analogsignal, - ) + ValueError, elephant.phase_analysis.weighted_phase_lag_index, + trials2_length3_analogsignal, trials1_length3_analogsignal) # different lengths in a trail pair with self.subTest(msg="diff. trial lengths & Quantity input"): np.testing.assert_raises( - ValueError, - elephant.phase_analysis.weighted_phase_lag_index, - trials1_length3, - trials1_length4, - sampling_frequency, - ) + ValueError, elephant.phase_analysis.weighted_phase_lag_index, + trials1_length3, trials1_length4, sampling_frequency) with self.subTest(msg="diff. trial lengths & np.array input"): np.testing.assert_raises( - ValueError, - elephant.phase_analysis.weighted_phase_lag_index, - trials1_length3.magnitude, - trials1_length4.magnitude, - sampling_frequency, - ) + ValueError, elephant.phase_analysis.weighted_phase_lag_index, + trials1_length3.magnitude, trials1_length4.magnitude, + sampling_frequency) with self.subTest(msg="diff. trial lengths & neo.AnalogSignal input"): np.testing.assert_raises( - ValueError, - elephant.phase_analysis.weighted_phase_lag_index, - trials1_length3_analogsignal, - trials1_length4_analogsignal, - ) + ValueError, elephant.phase_analysis.weighted_phase_lag_index, + trials1_length3_analogsignal, trials1_length4_analogsignal) @staticmethod def test_WPLI_raises_error_if_AnalogSignals_have_diff_sampling_rate(): @@ -864,22 +692,13 @@ def test_WPLI_raises_error_if_AnalogSignals_have_diff_sampling_rate(): Test if WPLI raises a ValueError, when the AnalogSignals have different sampling rates. """ - signal_x_250_hz = AnalogSignal( - signal=np.random.random([40, 2100]), - units=pq.mV, - sampling_rate=0.25 * pq.kHz, - ) - signal_y_1000_hz = AnalogSignal( - signal=np.random.random([40, 2100]), - units=pq.mV, - sampling_rate=1000 * pq.Hz, - ) + signal_x_250_hz = AnalogSignal(signal=np.random.random([40, 2100]), + units=pq.mV, sampling_rate=0.25*pq.kHz) + signal_y_1000_hz = AnalogSignal(signal=np.random.random([40, 2100]), + units=pq.mV, sampling_rate=1000*pq.Hz) np.testing.assert_raises( - ValueError, - elephant.phase_analysis.weighted_phase_lag_index, - signal_x_250_hz, - signal_y_1000_hz, - ) + ValueError, elephant.phase_analysis.weighted_phase_lag_index, + signal_x_250_hz, signal_y_1000_hz) def test_WPLI_raises_error_if_sampling_rate_not_given(self): """ @@ -890,19 +709,13 @@ def test_WPLI_raises_error_if_sampling_rate_not_given(self): signal_y = np.random.random([40, 2100]) * pq.mV with self.subTest(msg="Quantity-input"): np.testing.assert_raises( - ValueError, - elephant.phase_analysis.weighted_phase_lag_index, - signal_x, - signal_y, - ) + ValueError, elephant.phase_analysis.weighted_phase_lag_index, + signal_x, signal_y) with self.subTest(msg="np.array-input"): np.testing.assert_raises( - ValueError, - elephant.phase_analysis.weighted_phase_lag_index, - signal_x.magnitude, - signal_y.magnitude, - ) + ValueError, elephant.phase_analysis.weighted_phase_lag_index, + signal_x.magnitude, signal_y.magnitude) -if __name__ == "__main__": +if __name__ == '__main__': unittest.main() From 24389c9d48e2b4752de7bc03b3fb987efab047fa Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 14:19:03 +0200 Subject: [PATCH 55/84] fix pep8 phase analysis --- elephant/test/test_phase_analysis.py | 34 +++++++++++++++------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/elephant/test/test_phase_analysis.py b/elephant/test/test_phase_analysis.py index c17059c5a..e7c8ecb65 100644 --- a/elephant/test/test_phase_analysis.py +++ b/elephant/test/test_phase_analysis.py @@ -400,9 +400,9 @@ def setUpClass(cls): for filename, checksum in cls.files_to_download_real: # files will be downloaded to ELEPHANT_TMP_DIR cls.tmp_path[filename] = { - 'filename':filename, - 'path':download_datasets( - f"{real_data_path}/{filename}", checksum=checksum)} + 'filename': filename, + 'path': download_datasets( + f"{real_data_path}/{filename}", checksum=checksum)} # ARTIFICIAL DATA artificial_data_path = "unittest/phase_analysis/" \ "weighted_phase_lag_index/data/wpli_specific_artificial_dataset" @@ -413,12 +413,12 @@ def setUpClass(cls): for filename, checksum in cls.files_to_download_artificial: # files will be downloaded to ELEPHANT_TMP_DIR cls.tmp_path[filename] = { - 'filename':filename, - 'path':download_datasets( - f"{artificial_data_path}/{filename}", checksum=checksum)} + 'filename': filename, + 'path': download_datasets( + f"{artificial_data_path}/{filename}", checksum=checksum)} # GROUND TRUTH DATA ground_truth_data_path = "unittest/phase_analysis/" \ - "weighted_phase_lag_index/data/wpli_ground_truth" + "weighted_phase_lag_index/data/wpli_ground_truth" cls.files_to_download_ground_truth = ( ("ground_truth_WPLI_from_ft_connectivity_wpli_" "with_real_LFPs_R2G.csv", "4d9a7b7afab7d107023956077ab11fef"), @@ -428,9 +428,9 @@ def setUpClass(cls): for filename, checksum in cls.files_to_download_ground_truth: # files will be downloaded into ELEPHANT_TMP_DIR cls.tmp_path[filename] = { - 'filename':filename, - 'path':download_datasets( - f"{ground_truth_data_path}/{filename}", checksum=checksum)} + 'filename': filename, + 'path': download_datasets( + f"{ground_truth_data_path}/{filename}", checksum=checksum)} def setUp(self): self.tolerance = 1e-15 @@ -456,10 +456,12 @@ def setUp(self): signal=self.lfps2_real, sampling_rate=self.sf2_real) # artificial LFP-dataset - dataset1_artificial = scipy.io.loadmat( - f"{self.tmp_path[self.files_to_download_artificial[0][0]]['path']}", squeeze_me=True) - dataset2_artificial = scipy.io.loadmat( - f"{self.tmp_path[self.files_to_download_artificial[1][0]]['path']}", squeeze_me=True) + dataset1_path = \ + f"{self.tmp_path[self.files_to_download_artificial[0][0]]['path']}" + dataset1_artificial = scipy.io.loadmat(dataset1_path, squeeze_me=True) + dataset2_path = \ + f"{self.tmp_path[self.files_to_download_artificial[1][0]]['path']}" + dataset2_artificial = scipy.io.loadmat(dataset2_path, squeeze_me=True) # get relevant values self.lfps1_artificial = dataset1_artificial['lfp_matrix'] * pq.uV self.sf1_artificial = dataset1_artificial['sf'] * pq.Hz @@ -474,10 +476,10 @@ def setUp(self): # load ground-truth reference calculated by: # Matlab package 'FieldTrip': ft_connectivity_wpli() self.wpli_ground_truth_ft_connectivity_wpli_real = np.loadtxt( - f"{self.tmp_path[self.files_to_download_ground_truth[0][0]]['path']}", + f"{self.tmp_path[self.files_to_download_ground_truth[0][0]]['path']}", # noqa delimiter=',', dtype=np.float64) self.wpli_ground_truth_ft_connectivity_artificial = np.loadtxt( - f"{self.tmp_path[self.files_to_download_ground_truth[1][0]]['path']}", + f"{self.tmp_path[self.files_to_download_ground_truth[1][0]]['path']}", # noqa delimiter=',', dtype=np.float64) def test_WPLI_ground_truth_consistency_real_LFP_dataset(self): From 4a4137944e86136b02c0abad0505fdc39b6eac64 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 14:25:40 +0200 Subject: [PATCH 56/84] pep8 --- elephant/test/test_phase_analysis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elephant/test/test_phase_analysis.py b/elephant/test/test_phase_analysis.py index e7c8ecb65..c328681ec 100644 --- a/elephant/test/test_phase_analysis.py +++ b/elephant/test/test_phase_analysis.py @@ -476,10 +476,10 @@ def setUp(self): # load ground-truth reference calculated by: # Matlab package 'FieldTrip': ft_connectivity_wpli() self.wpli_ground_truth_ft_connectivity_wpli_real = np.loadtxt( - f"{self.tmp_path[self.files_to_download_ground_truth[0][0]]['path']}", # noqa + f"{self.tmp_path[self.files_to_download_ground_truth[0][0]]['path']}", # noqa delimiter=',', dtype=np.float64) self.wpli_ground_truth_ft_connectivity_artificial = np.loadtxt( - f"{self.tmp_path[self.files_to_download_ground_truth[1][0]]['path']}", # noqa + f"{self.tmp_path[self.files_to_download_ground_truth[1][0]]['path']}", # noqa delimiter=',', dtype=np.float64) def test_WPLI_ground_truth_consistency_real_LFP_dataset(self): From 767d8a96a3546ddb746c9146f1b0821839804866 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 26 Apr 2024 14:29:25 +0200 Subject: [PATCH 57/84] reverse formatting, fix pep8 --- .../test/test_spike_train_dissimilarity.py | 1240 ++++++----------- 1 file changed, 424 insertions(+), 816 deletions(-) diff --git a/elephant/test/test_spike_train_dissimilarity.py b/elephant/test/test_spike_train_dissimilarity.py index a378f08d0..4619d4bba 100644 --- a/elephant/test/test_spike_train_dissimilarity.py +++ b/elephant/test/test_spike_train_dissimilarity.py @@ -20,39 +20,38 @@ class TimeScaleDependSpikeTrainDissimMeasuresTestCase(unittest.TestCase): def setUp(self): - self.st00 = SpikeTrain([], units="ms", t_stop=1000.0) - self.st01 = SpikeTrain([1], units="ms", t_stop=1000.0) - self.st02 = SpikeTrain([2], units="ms", t_stop=1000.0) - self.st03 = SpikeTrain([2.9], units="ms", t_stop=1000.0) - self.st04 = SpikeTrain([3.1], units="ms", t_stop=1000.0) - self.st05 = SpikeTrain([5], units="ms", t_stop=1000.0) - self.st06 = SpikeTrain([500], units="ms", t_stop=1000.0) - self.st07 = SpikeTrain([12, 32], units="ms", t_stop=1000.0) - self.st08 = SpikeTrain([32, 52], units="ms", t_stop=1000.0) - self.st09 = SpikeTrain([42], units="ms", t_stop=1000.0) - self.st10 = SpikeTrain([18, 60], units="ms", t_stop=1000.0) - self.st11 = SpikeTrain([10, 20, 30, 40], units="ms", t_stop=1000.0) - self.st12 = SpikeTrain([40, 30, 20, 10], units="ms", t_stop=1000.0) - self.st13 = SpikeTrain([15, 25, 35, 45], units="ms", t_stop=1000.0) - self.st14 = SpikeTrain([10, 20, 30, 40, 50], units="ms", t_stop=1000.0) - self.st15 = SpikeTrain( - [0.01, 0.02, 0.03, 0.04, 0.05], units="s", t_stop=1000.0 - ) - self.st16 = SpikeTrain([12, 16, 28, 30, 42], units="ms", t_stop=1000.0) - self.st21 = StationaryPoissonProcess( - rate=50 * Hz, t_start=0 * ms, t_stop=1000 * ms - ).generate_spiketrain() - self.st22 = StationaryPoissonProcess( - rate=40 * Hz, t_start=0 * ms, t_stop=1000 * ms - ).generate_spiketrain() - self.st23 = StationaryPoissonProcess( - rate=30 * Hz, t_start=0 * ms, t_stop=1000 * ms - ).generate_spiketrain() + self.st00 = SpikeTrain([], units='ms', t_stop=1000.0) + self.st01 = SpikeTrain([1], units='ms', t_stop=1000.0) + self.st02 = SpikeTrain([2], units='ms', t_stop=1000.0) + self.st03 = SpikeTrain([2.9], units='ms', t_stop=1000.0) + self.st04 = SpikeTrain([3.1], units='ms', t_stop=1000.0) + self.st05 = SpikeTrain([5], units='ms', t_stop=1000.0) + self.st06 = SpikeTrain([500], units='ms', t_stop=1000.0) + self.st07 = SpikeTrain([12, 32], units='ms', t_stop=1000.0) + self.st08 = SpikeTrain([32, 52], units='ms', t_stop=1000.0) + self.st09 = SpikeTrain([42], units='ms', t_stop=1000.0) + self.st10 = SpikeTrain([18, 60], units='ms', t_stop=1000.0) + self.st11 = SpikeTrain([10, 20, 30, 40], units='ms', t_stop=1000.0) + self.st12 = SpikeTrain([40, 30, 20, 10], units='ms', t_stop=1000.0) + self.st13 = SpikeTrain([15, 25, 35, 45], units='ms', t_stop=1000.0) + self.st14 = SpikeTrain([10, 20, 30, 40, 50], units='ms', t_stop=1000.0) + self.st15 = SpikeTrain([0.01, 0.02, 0.03, 0.04, 0.05], + units='s', t_stop=1000.0) + self.st16 = SpikeTrain([12, 16, 28, 30, 42], units='ms', t_stop=1000.0) + self.st21 = StationaryPoissonProcess(rate=50 * Hz, t_start=0 * ms, + t_stop=1000 * ms + ).generate_spiketrain() + self.st22 = StationaryPoissonProcess(rate=40 * Hz, t_start=0 * ms, + t_stop=1000 * ms + ).generate_spiketrain() + self.st23 = StationaryPoissonProcess(rate=30 * Hz, t_start=0 * ms, + t_stop=1000 * ms + ).generate_spiketrain() self.rd_st_list = [self.st21, self.st22, self.st23] - self.st31 = SpikeTrain([12.0], units="ms", t_stop=1000.0) - self.st32 = SpikeTrain([12.0, 12.0], units="ms", t_stop=1000.0) - self.st33 = SpikeTrain([20.0], units="ms", t_stop=1000.0) - self.st34 = SpikeTrain([20.0, 20.0], units="ms", t_stop=1000.0) + self.st31 = SpikeTrain([12.0], units='ms', t_stop=1000.0) + self.st32 = SpikeTrain([12.0, 12.0], units='ms', t_stop=1000.0) + self.st33 = SpikeTrain([20.0], units='ms', t_stop=1000.0) + self.st34 = SpikeTrain([20.0, 20.0], units='ms', t_stop=1000.0) self.array1 = np.arange(1, 10) self.array2 = np.arange(1.2, 10) self.qarray1 = self.array1 * Hz @@ -76,855 +75,480 @@ def setUp(self): self.t = np.linspace(0, 200, 20000001) * ms def test_wrong_input(self): - self.assertRaises( - TypeError, - stds.victor_purpura_distance, - [self.array1, self.array2], - self.q3, - ) - self.assertRaises( - TypeError, - stds.victor_purpura_distance, - [self.qarray1, self.qarray2], - self.q3, - ) - self.assertRaises( - TypeError, - stds.victor_purpura_distance, - [self.qarray1, self.qarray2], - 5.0 * ms, - ) - - self.assertRaises( - TypeError, - stds.victor_purpura_distance, - [self.array1, self.array2], - self.q3, - algorithm="intuitive", - ) - self.assertRaises( - TypeError, - stds.victor_purpura_distance, - [self.qarray1, self.qarray2], - self.q3, - algorithm="intuitive", - ) - self.assertRaises( - TypeError, - stds.victor_purpura_distance, - [self.qarray1, self.qarray2], - 5.0 * ms, - algorithm="intuitive", - ) - - self.assertRaises( - TypeError, - stds.van_rossum_distance, - [self.array1, self.array2], - self.tau3, - ) - self.assertRaises( - TypeError, - stds.van_rossum_distance, - [self.qarray1, self.qarray2], - self.tau3, - ) - self.assertRaises( - TypeError, - stds.van_rossum_distance, - [self.qarray1, self.qarray2], - 5.0 * Hz, - ) - - self.assertRaises( - TypeError, - stds.victor_purpura_distance, - [self.st11, self.st13], - self.tau2, - ) - self.assertRaises( - TypeError, - stds.victor_purpura_distance, - [self.st11, self.st13], - 5.0, - ) - self.assertRaises( - TypeError, - stds.victor_purpura_distance, - [self.st11, self.st13], - self.tau2, - algorithm="intuitive", - ) - self.assertRaises( - TypeError, - stds.victor_purpura_distance, - [self.st11, self.st13], - 5.0, - algorithm="intuitive", - ) - self.assertRaises( - TypeError, - stds.van_rossum_distance, - [self.st11, self.st13], - self.q4, - ) - self.assertRaises( - TypeError, stds.van_rossum_distance, [self.st11, self.st13], 5.0 - ) - - self.assertRaises( - NotImplementedError, - stds.victor_purpura_distance, + self.assertRaises(TypeError, stds.victor_purpura_distance, + [self.array1, self.array2], self.q3) + self.assertRaises(TypeError, stds.victor_purpura_distance, + [self.qarray1, self.qarray2], self.q3) + self.assertRaises(TypeError, stds.victor_purpura_distance, + [self.qarray1, self.qarray2], 5.0 * ms) + + self.assertRaises(TypeError, stds.victor_purpura_distance, + [self.array1, self.array2], self.q3, + algorithm='intuitive') + self.assertRaises(TypeError, stds.victor_purpura_distance, + [self.qarray1, self.qarray2], self.q3, + algorithm='intuitive') + self.assertRaises(TypeError, stds.victor_purpura_distance, + [self.qarray1, self.qarray2], 5.0 * ms, + algorithm='intuitive') + + self.assertRaises(TypeError, stds.van_rossum_distance, + [self.array1, self.array2], self.tau3) + self.assertRaises(TypeError, stds.van_rossum_distance, + [self.qarray1, self.qarray2], self.tau3) + self.assertRaises(TypeError, stds.van_rossum_distance, + [self.qarray1, self.qarray2], 5.0 * Hz) + + self.assertRaises(TypeError, stds.victor_purpura_distance, + [self.st11, self.st13], self.tau2) + self.assertRaises(TypeError, stds.victor_purpura_distance, + [self.st11, self.st13], 5.0) + self.assertRaises(TypeError, stds.victor_purpura_distance, + [self.st11, self.st13], self.tau2, + algorithm='intuitive') + self.assertRaises(TypeError, stds.victor_purpura_distance, + [self.st11, self.st13], 5.0, + algorithm='intuitive') + self.assertRaises(TypeError, stds.van_rossum_distance, + [self.st11, self.st13], self.q4) + self.assertRaises(TypeError, stds.van_rossum_distance, + [self.st11, self.st13], 5.0) + + self.assertRaises(NotImplementedError, stds.victor_purpura_distance, + [self.st01, self.st02], self.q3, + kernel=kernels.Kernel(2.0 / self.q3)) + self.assertRaises(NotImplementedError, stds.victor_purpura_distance, + [self.st01, self.st02], self.q3, + kernel=kernels.SymmetricKernel(2.0 / self.q3)) + self.assertEqual(stds.victor_purpura_distance( + [self.st01, self.st02], self.q1, + kernel=kernels.TriangularKernel( + 2.0 / (np.sqrt(6.0) * self.q2)))[0, 1], + stds.victor_purpura_distance( + [self.st01, self.st02], self.q3, + kernel=kernels.TriangularKernel( + 2.0 / (np.sqrt(6.0) * self.q2)))[0, 1]) + self.assertEqual(stds.victor_purpura_distance( [self.st01, self.st02], - self.q3, - kernel=kernels.Kernel(2.0 / self.q3), - ) - self.assertRaises( - NotImplementedError, - stds.victor_purpura_distance, + kernel=kernels.TriangularKernel( + 2.0 / (np.sqrt(6.0) * self.q2)))[0, 1], 1.0) + self.assertNotEqual(stds.victor_purpura_distance( [self.st01, self.st02], - self.q3, - kernel=kernels.SymmetricKernel(2.0 / self.q3), - ) - self.assertEqual( - stds.victor_purpura_distance( - [self.st01, self.st02], - self.q1, - kernel=kernels.TriangularKernel( - 2.0 / (np.sqrt(6.0) * self.q2) - ), - )[0, 1], - stds.victor_purpura_distance( - [self.st01, self.st02], - self.q3, - kernel=kernels.TriangularKernel( - 2.0 / (np.sqrt(6.0) * self.q2) - ), - )[0, 1], - ) - self.assertEqual( - stds.victor_purpura_distance( - [self.st01, self.st02], - kernel=kernels.TriangularKernel( - 2.0 / (np.sqrt(6.0) * self.q2) - ), - )[0, 1], - 1.0, - ) - self.assertNotEqual( - stds.victor_purpura_distance( - [self.st01, self.st02], - kernel=kernels.AlphaKernel(2.0 / (np.sqrt(6.0) * self.q2)), - )[0, 1], - 1.0, - ) - - self.assertRaises( - NameError, - stds.victor_purpura_distance, - [self.st11, self.st13], - self.q2, - algorithm="slow", - ) + kernel=kernels.AlphaKernel( + 2.0 / (np.sqrt(6.0) * self.q2)))[0, 1], 1.0) + + self.assertRaises(NameError, stds.victor_purpura_distance, + [self.st11, self.st13], self.q2, algorithm='slow') def test_victor_purpura_distance_fast(self): # Tests of distances of simplest spike trains: - self.assertEqual( - stds.victor_purpura_distance([self.st00, self.st00], self.q2)[ - 0, 1 - ], - 0.0, - ) - self.assertEqual( - stds.victor_purpura_distance([self.st00, self.st01], self.q2)[ - 0, 1 - ], - 1.0, - ) - self.assertEqual( - stds.victor_purpura_distance([self.st01, self.st00], self.q2)[ - 0, 1 - ], - 1.0, - ) - self.assertEqual( - stds.victor_purpura_distance([self.st01, self.st01], self.q2)[ - 0, 1 - ], - 0.0, - ) + self.assertEqual(stds.victor_purpura_distance( + [self.st00, self.st00], self.q2)[0, 1], 0.0) + self.assertEqual(stds.victor_purpura_distance( + [self.st00, self.st01], self.q2)[0, 1], 1.0) + self.assertEqual(stds.victor_purpura_distance( + [self.st01, self.st00], self.q2)[0, 1], 1.0) + self.assertEqual(stds.victor_purpura_distance( + [self.st01, self.st01], self.q2)[0, 1], 0.0) # Tests of distances under elementary spike operations - self.assertEqual( - stds.victor_purpura_distance([self.st01, self.st02], self.q2)[ - 0, 1 - ], - 1.0, - ) - self.assertEqual( - stds.victor_purpura_distance([self.st01, self.st03], self.q2)[ - 0, 1 - ], - 1.9, - ) - self.assertEqual( - stds.victor_purpura_distance([self.st01, self.st04], self.q2)[ - 0, 1 - ], - 2.0, - ) - self.assertEqual( - stds.victor_purpura_distance([self.st01, self.st05], self.q2)[ - 0, 1 - ], - 2.0, - ) - self.assertEqual( - stds.victor_purpura_distance([self.st00, self.st07], self.q2)[ - 0, 1 - ], - 2.0, - ) - self.assertAlmostEqual( - stds.victor_purpura_distance([self.st07, self.st08], self.q4)[ - 0, 1 - ], - 0.4, - ) - self.assertAlmostEqual( - stds.victor_purpura_distance([self.st07, self.st10], self.q3)[ - 0, 1 - ], - 0.6 + 2, - ) - self.assertEqual( - stds.victor_purpura_distance([self.st11, self.st14], self.q2)[ - 0, 1 - ], - 1, - ) + self.assertEqual(stds.victor_purpura_distance( + [self.st01, self.st02], self.q2)[0, 1], 1.0) + self.assertEqual(stds.victor_purpura_distance( + [self.st01, self.st03], self.q2)[0, 1], 1.9) + self.assertEqual(stds.victor_purpura_distance( + [self.st01, self.st04], self.q2)[0, 1], 2.0) + self.assertEqual(stds.victor_purpura_distance( + [self.st01, self.st05], self.q2)[0, 1], 2.0) + self.assertEqual(stds.victor_purpura_distance( + [self.st00, self.st07], self.q2)[0, 1], 2.0) + self.assertAlmostEqual(stds.victor_purpura_distance( + [self.st07, self.st08], self.q4)[0, 1], 0.4) + self.assertAlmostEqual(stds.victor_purpura_distance( + [self.st07, self.st10], self.q3)[0, 1], 0.6 + 2) + self.assertEqual(stds.victor_purpura_distance( + [self.st11, self.st14], self.q2)[0, 1], 1) # Tests on timescales - self.assertEqual( - stds.victor_purpura_distance([self.st11, self.st14], self.q1)[ - 0, 1 - ], - stds.victor_purpura_distance([self.st11, self.st14], self.q5)[ - 0, 1 - ], - ) - self.assertEqual( - stds.victor_purpura_distance([self.st07, self.st11], self.q0)[ - 0, 1 - ], - 6.0, - ) - self.assertEqual( - stds.victor_purpura_distance([self.st07, self.st11], self.q1)[ - 0, 1 - ], - 6.0, - ) - self.assertAlmostEqual( - stds.victor_purpura_distance([self.st07, self.st11], self.q5)[ - 0, 1 - ], - 2.0, - 5, - ) - self.assertEqual( - stds.victor_purpura_distance([self.st07, self.st11], self.q6)[ - 0, 1 - ], - 2.0, - ) + self.assertEqual(stds.victor_purpura_distance( + [self.st11, self.st14], self.q1)[0, 1], + stds.victor_purpura_distance( + [self.st11, self.st14], self.q5)[0, 1]) + self.assertEqual(stds.victor_purpura_distance( + [self.st07, self.st11], self.q0)[0, 1], 6.0) + self.assertEqual(stds.victor_purpura_distance( + [self.st07, self.st11], self.q1)[0, 1], 6.0) + self.assertAlmostEqual(stds.victor_purpura_distance( + [self.st07, self.st11], self.q5)[0, 1], 2.0, 5) + self.assertEqual(stds.victor_purpura_distance( + [self.st07, self.st11], self.q6)[0, 1], 2.0) # Tests on unordered spiketrains - self.assertEqual( - stds.victor_purpura_distance([self.st11, self.st13], self.q4)[ - 0, 1 - ], - stds.victor_purpura_distance([self.st12, self.st13], self.q4)[ - 0, 1 - ], - ) - self.assertNotEqual( - stds.victor_purpura_distance( - [self.st11, self.st13], self.q4, sort=False - )[0, 1], - stds.victor_purpura_distance( - [self.st12, self.st13], self.q4, sort=False - )[0, 1], - ) + self.assertEqual(stds.victor_purpura_distance( + [self.st11, self.st13], self.q4)[0, 1], + stds.victor_purpura_distance( + [self.st12, self.st13], self.q4)[0, 1]) + self.assertNotEqual(stds.victor_purpura_distance( + [self.st11, self.st13], self.q4, + sort=False)[0, 1], + stds.victor_purpura_distance( + [self.st12, self.st13], self.q4, + sort=False)[0, 1]) # Tests on metric properties with random spiketrains # (explicit calculation of second metric axiom in particular case, # because from dist_matrix it is trivial) dist_matrix = stds.victor_purpura_distance( - [self.st21, self.st22, self.st23], self.q3 - ) + [self.st21, self.st22, self.st23], self.q3) for i in range(3): for j in range(3): self.assertGreaterEqual(dist_matrix[i, j], 0) if dist_matrix[i, j] == 0: assert_array_equal(self.rd_st_list[i], self.rd_st_list[j]) - assert_array_equal( - stds.victor_purpura_distance([self.st21, self.st22], self.q3), - stds.victor_purpura_distance([self.st22, self.st21], self.q3), - ) - self.assertLessEqual( - dist_matrix[0, 1], dist_matrix[0, 2] + dist_matrix[1, 2] - ) - self.assertLessEqual( - dist_matrix[0, 2], dist_matrix[1, 2] + dist_matrix[0, 1] - ) - self.assertLessEqual( - dist_matrix[1, 2], dist_matrix[0, 1] + dist_matrix[0, 2] - ) + assert_array_equal(stds.victor_purpura_distance( + [self.st21, self.st22], self.q3), + stds.victor_purpura_distance( + [self.st22, self.st21], self.q3)) + self.assertLessEqual(dist_matrix[0, 1], + dist_matrix[0, 2] + dist_matrix[1, 2]) + self.assertLessEqual(dist_matrix[0, 2], + dist_matrix[1, 2] + dist_matrix[0, 1]) + self.assertLessEqual(dist_matrix[1, 2], + dist_matrix[0, 1] + dist_matrix[0, 2]) # Tests on proper unit conversion self.assertAlmostEqual( - stds.victor_purpura_distance([self.st14, self.st16], self.q3)[ - 0, 1 - ], - stds.victor_purpura_distance([self.st15, self.st16], self.q3)[ - 0, 1 - ], - ) + stds.victor_purpura_distance([self.st14, self.st16], + self.q3)[0, 1], + stds.victor_purpura_distance([self.st15, self.st16], + self.q3)[0, 1]) self.assertAlmostEqual( - stds.victor_purpura_distance([self.st16, self.st14], self.q3)[ - 0, 1 - ], - stds.victor_purpura_distance([self.st16, self.st15], self.q3)[ - 0, 1 - ], - ) + stds.victor_purpura_distance([self.st16, self.st14], + self.q3)[0, 1], + stds.victor_purpura_distance([self.st16, self.st15], + self.q3)[0, 1]) self.assertAlmostEqual( - stds.victor_purpura_distance([self.st01, self.st05], self.q3)[ - 0, 1 - ], - stds.victor_purpura_distance([self.st01, self.st05], self.q7)[ - 0, 1 - ], - ) + stds.victor_purpura_distance([self.st01, self.st05], + self.q3)[0, 1], + stds.victor_purpura_distance([self.st01, self.st05], + self.q7)[0, 1]) # Tests on algorithmic behaviour for equal spike times + self.assertAlmostEqual(stds.victor_purpura_distance( + [self.st31, self.st34], self.q3)[0, 1], 0.8 + 1.0) self.assertAlmostEqual( - stds.victor_purpura_distance([self.st31, self.st34], self.q3)[ - 0, 1 - ], - 0.8 + 1.0, - ) + stds.victor_purpura_distance([self.st31, self.st34], + self.q3)[0, 1], + stds.victor_purpura_distance([self.st32, self.st33], + self.q3)[0, 1]) self.assertAlmostEqual( - stds.victor_purpura_distance([self.st31, self.st34], self.q3)[ - 0, 1 - ], - stds.victor_purpura_distance([self.st32, self.st33], self.q3)[ - 0, 1 - ], - ) - self.assertAlmostEqual( - stds.victor_purpura_distance([self.st31, self.st33], self.q3)[0, 1] - * 2.0, - stds.victor_purpura_distance([self.st32, self.st34], self.q3)[ - 0, 1 - ], - ) + stds.victor_purpura_distance( + [self.st31, self.st33], self.q3)[0, 1] * 2.0, + stds.victor_purpura_distance( + [self.st32, self.st34], self.q3)[0, 1]) # Tests on spike train list lengthes smaller than 2 - self.assertEqual( - stds.victor_purpura_distance([self.st21], self.q3)[0, 0], 0 - ) + self.assertEqual(stds.victor_purpura_distance( + [self.st21], self.q3)[0, 0], 0) self.assertEqual(len(stds.victor_purpura_distance([], self.q3)), 0) def test_victor_purpura_distance_intuitive(self): # Tests of distances of simplest spike trains - self.assertEqual( - stds.victor_purpura_distance( - [self.st00, self.st00], self.q2, algorithm="intuitive" - )[0, 1], - 0.0, - ) - self.assertEqual( - stds.victor_purpura_distance( - [self.st00, self.st01], self.q2, algorithm="intuitive" - )[0, 1], - 1.0, - ) - self.assertEqual( - stds.victor_purpura_distance( - [self.st01, self.st00], self.q2, algorithm="intuitive" - )[0, 1], - 1.0, - ) - self.assertEqual( - stds.victor_purpura_distance( - [self.st01, self.st01], self.q2, algorithm="intuitive" - )[0, 1], - 0.0, - ) + self.assertEqual(stds.victor_purpura_distance( + [self.st00, self.st00], self.q2, + algorithm='intuitive')[0, 1], 0.0) + self.assertEqual(stds.victor_purpura_distance( + [self.st00, self.st01], self.q2, + algorithm='intuitive')[0, 1], 1.0) + self.assertEqual(stds.victor_purpura_distance( + [self.st01, self.st00], self.q2, + algorithm='intuitive')[0, 1], 1.0) + self.assertEqual(stds.victor_purpura_distance( + [self.st01, self.st01], self.q2, + algorithm='intuitive')[0, 1], 0.0) # Tests of distances under elementary spike operations - self.assertEqual( - stds.victor_purpura_distance( - [self.st01, self.st02], self.q2, algorithm="intuitive" - )[0, 1], - 1.0, - ) - self.assertEqual( - stds.victor_purpura_distance( - [self.st01, self.st03], self.q2, algorithm="intuitive" - )[0, 1], - 1.9, - ) - self.assertEqual( - stds.victor_purpura_distance( - [self.st01, self.st04], self.q2, algorithm="intuitive" - )[0, 1], - 2.0, - ) - self.assertEqual( - stds.victor_purpura_distance( - [self.st01, self.st05], self.q2, algorithm="intuitive" - )[0, 1], - 2.0, - ) - self.assertEqual( - stds.victor_purpura_distance( - [self.st00, self.st07], self.q2, algorithm="intuitive" - )[0, 1], - 2.0, - ) - self.assertAlmostEqual( - stds.victor_purpura_distance( - [self.st07, self.st08], self.q4, algorithm="intuitive" - )[0, 1], - 0.4, - ) - self.assertAlmostEqual( - stds.victor_purpura_distance( - [self.st07, self.st10], self.q3, algorithm="intuitive" - )[0, 1], - 2.6, - ) - self.assertEqual( - stds.victor_purpura_distance( - [self.st11, self.st14], self.q2, algorithm="intuitive" - )[0, 1], - 1, - ) + self.assertEqual(stds.victor_purpura_distance( + [self.st01, self.st02], self.q2, + algorithm='intuitive')[0, 1], 1.0) + self.assertEqual(stds.victor_purpura_distance( + [self.st01, self.st03], self.q2, + algorithm='intuitive')[0, 1], 1.9) + self.assertEqual(stds.victor_purpura_distance( + [self.st01, self.st04], self.q2, + algorithm='intuitive')[0, 1], 2.0) + self.assertEqual(stds.victor_purpura_distance( + [self.st01, self.st05], self.q2, + algorithm='intuitive')[0, 1], 2.0) + self.assertEqual(stds.victor_purpura_distance( + [self.st00, self.st07], self.q2, + algorithm='intuitive')[0, 1], 2.0) + self.assertAlmostEqual(stds.victor_purpura_distance( + [self.st07, self.st08], self.q4, + algorithm='intuitive')[0, 1], 0.4) + self.assertAlmostEqual(stds.victor_purpura_distance( + [self.st07, self.st10], self.q3, + algorithm='intuitive')[0, 1], 2.6) + self.assertEqual(stds.victor_purpura_distance( + [self.st11, self.st14], self.q2, + algorithm='intuitive')[0, 1], 1) # Tests on timescales - self.assertEqual( - stds.victor_purpura_distance( - [self.st11, self.st14], self.q1, algorithm="intuitive" - )[0, 1], - stds.victor_purpura_distance( - [self.st11, self.st14], self.q5, algorithm="intuitive" - )[0, 1], - ) - self.assertEqual( - stds.victor_purpura_distance( - [self.st07, self.st11], self.q0, algorithm="intuitive" - )[0, 1], - 6.0, - ) - self.assertEqual( - stds.victor_purpura_distance( - [self.st07, self.st11], self.q1, algorithm="intuitive" - )[0, 1], - 6.0, - ) - self.assertAlmostEqual( - stds.victor_purpura_distance( - [self.st07, self.st11], self.q5, algorithm="intuitive" - )[0, 1], - 2.0, - 5, - ) - self.assertEqual( - stds.victor_purpura_distance( - [self.st07, self.st11], self.q6, algorithm="intuitive" - )[0, 1], - 2.0, - ) + self.assertEqual(stds.victor_purpura_distance( + [self.st11, self.st14], self.q1, + algorithm='intuitive')[0, 1], + stds.victor_purpura_distance( + [self.st11, self.st14], self.q5, + algorithm='intuitive')[0, 1]) + self.assertEqual(stds.victor_purpura_distance( + [self.st07, self.st11], self.q0, + algorithm='intuitive')[0, 1], 6.0) + self.assertEqual(stds.victor_purpura_distance( + [self.st07, self.st11], self.q1, + algorithm='intuitive')[0, 1], 6.0) + self.assertAlmostEqual(stds.victor_purpura_distance( + [self.st07, self.st11], self.q5, + algorithm='intuitive')[0, 1], 2.0, 5) + self.assertEqual(stds.victor_purpura_distance( + [self.st07, self.st11], self.q6, + algorithm='intuitive')[0, 1], 2.0) # Tests on unordered spiketrains - self.assertEqual( - stds.victor_purpura_distance( - [self.st11, self.st13], self.q4, algorithm="intuitive" - )[0, 1], - stds.victor_purpura_distance( - [self.st12, self.st13], self.q4, algorithm="intuitive" - )[0, 1], - ) - self.assertNotEqual( - stds.victor_purpura_distance( - [self.st11, self.st13], - self.q4, - sort=False, - algorithm="intuitive", - )[0, 1], - stds.victor_purpura_distance( - [self.st12, self.st13], - self.q4, - sort=False, - algorithm="intuitive", - )[0, 1], - ) + self.assertEqual(stds.victor_purpura_distance( + [self.st11, self.st13], self.q4, + algorithm='intuitive')[0, 1], + stds.victor_purpura_distance( + [self.st12, self.st13], self.q4, + algorithm='intuitive')[0, 1]) + self.assertNotEqual(stds.victor_purpura_distance( + [self.st11, self.st13], self.q4, + sort=False, algorithm='intuitive')[0, 1], + stds.victor_purpura_distance( + [self.st12, self.st13], self.q4, + sort=False, algorithm='intuitive')[0, 1]) # Tests on metric properties with random spiketrains # (explicit calculation of second metric axiom in particular case, # because from dist_matrix it is trivial) dist_matrix = stds.victor_purpura_distance( - [self.st21, self.st22, self.st23], self.q3, algorithm="intuitive" - ) + [self.st21, self.st22, self.st23], + self.q3, algorithm='intuitive') for i in range(3): for j in range(3): self.assertGreaterEqual(dist_matrix[i, j], 0) if dist_matrix[i, j] == 0: assert_array_equal(self.rd_st_list[i], self.rd_st_list[j]) - assert_array_equal( - stds.victor_purpura_distance( - [self.st21, self.st22], self.q3, algorithm="intuitive" - ), - stds.victor_purpura_distance( - [self.st22, self.st21], self.q3, algorithm="intuitive" - ), - ) - self.assertLessEqual( - dist_matrix[0, 1], dist_matrix[0, 2] + dist_matrix[1, 2] - ) - self.assertLessEqual( - dist_matrix[0, 2], dist_matrix[1, 2] + dist_matrix[0, 1] - ) - self.assertLessEqual( - dist_matrix[1, 2], dist_matrix[0, 1] + dist_matrix[0, 2] - ) + assert_array_equal(stds.victor_purpura_distance( + [self.st21, self.st22], self.q3, + algorithm='intuitive'), + stds.victor_purpura_distance( + [self.st22, self.st21], self.q3, + algorithm='intuitive')) + self.assertLessEqual(dist_matrix[0, 1], + dist_matrix[0, 2] + dist_matrix[1, 2]) + self.assertLessEqual(dist_matrix[0, 2], + dist_matrix[1, 2] + dist_matrix[0, 1]) + self.assertLessEqual(dist_matrix[1, 2], + dist_matrix[0, 1] + dist_matrix[0, 2]) # Tests on proper unit conversion - self.assertAlmostEqual( - stds.victor_purpura_distance( - [self.st14, self.st16], self.q3, algorithm="intuitive" - )[0, 1], - stds.victor_purpura_distance( - [self.st15, self.st16], self.q3, algorithm="intuitive" - )[0, 1], - ) - self.assertAlmostEqual( - stds.victor_purpura_distance( - [self.st16, self.st14], self.q3, algorithm="intuitive" - )[0, 1], - stds.victor_purpura_distance( - [self.st16, self.st15], self.q3, algorithm="intuitive" - )[0, 1], - ) - self.assertEqual( - stds.victor_purpura_distance( - [self.st01, self.st05], self.q3, algorithm="intuitive" - )[0, 1], - stds.victor_purpura_distance( - [self.st01, self.st05], self.q7, algorithm="intuitive" - )[0, 1], - ) + self.assertAlmostEqual(stds.victor_purpura_distance( + [self.st14, self.st16], self.q3, + algorithm='intuitive')[0, 1], + stds.victor_purpura_distance( + [self.st15, self.st16], self.q3, + algorithm='intuitive')[0, 1]) + self.assertAlmostEqual(stds.victor_purpura_distance( + [self.st16, self.st14], self.q3, + algorithm='intuitive')[0, 1], + stds.victor_purpura_distance( + [self.st16, self.st15], self.q3, + algorithm='intuitive')[0, 1]) + self.assertEqual(stds.victor_purpura_distance( + [self.st01, self.st05], self.q3, + algorithm='intuitive')[0, 1], + stds.victor_purpura_distance( + [self.st01, self.st05], self.q7, + algorithm='intuitive')[0, 1]) # Tests on algorithmic behaviour for equal spike times - self.assertEqual( - stds.victor_purpura_distance( - [self.st31, self.st34], self.q3, algorithm="intuitive" - )[0, 1], - 0.8 + 1.0, - ) - self.assertEqual( - stds.victor_purpura_distance( - [self.st31, self.st34], self.q3, algorithm="intuitive" - )[0, 1], - stds.victor_purpura_distance( - [self.st32, self.st33], self.q3, algorithm="intuitive" - )[0, 1], - ) - self.assertEqual( - stds.victor_purpura_distance( - [self.st31, self.st33], self.q3, algorithm="intuitive" - )[0, 1] - * 2.0, - stds.victor_purpura_distance( - [self.st32, self.st34], self.q3, algorithm="intuitive" - )[0, 1], - ) + self.assertEqual(stds.victor_purpura_distance( + [self.st31, self.st34], self.q3, + algorithm='intuitive')[0, 1], + 0.8 + 1.0) + self.assertEqual(stds.victor_purpura_distance( + [self.st31, self.st34], self.q3, + algorithm='intuitive')[0, 1], + stds.victor_purpura_distance( + [self.st32, self.st33], self.q3, + algorithm='intuitive')[0, 1]) + self.assertEqual(stds.victor_purpura_distance( + [self.st31, self.st33], self.q3, + algorithm='intuitive')[0, 1] * 2.0, + stds.victor_purpura_distance( + [self.st32, self.st34], self.q3, + algorithm='intuitive')[0, 1]) # Tests on spike train list lengthes smaller than 2 - self.assertEqual( - stds.victor_purpura_distance( - [self.st21], self.q3, algorithm="intuitive" - )[0, 0], - 0, - ) - self.assertEqual( - len( - stds.victor_purpura_distance( - [], self.q3, algorithm="intuitive" - ) - ), - 0, - ) + self.assertEqual(stds.victor_purpura_distance( + [self.st21], self.q3, + algorithm='intuitive')[0, 0], 0) + self.assertEqual(len(stds.victor_purpura_distance( + [], self.q3, algorithm='intuitive')), 0) def test_victor_purpura_algorithm_comparison(self): assert_array_almost_equal( - stds.victor_purpura_distance( - [self.st21, self.st22, self.st23], self.q3 - ), - stds.victor_purpura_distance( - [self.st21, self.st22, self.st23], - self.q3, - algorithm="intuitive", - ), - ) + stds.victor_purpura_distance([self.st21, self.st22, self.st23], + self.q3), + stds.victor_purpura_distance([self.st21, self.st22, self.st23], + self.q3, algorithm='intuitive')) def test_victor_purpura_matlab_comparison_float(self): - repo_path = ( + repo_path =\ r"unittest/spike_train_dissimilarity/victor_purpura_distance/data" - ) files_to_download = [ ("times_float.npy", "ed1ff4d2c0eeed4a2b50a456803656be"), - ("matlab_results_float.npy", "a17f049e7ad0ddf7ca812e86fdb92646"), - ] + ("matlab_results_float.npy", "a17f049e7ad0ddf7ca812e86fdb92646")] downloaded_files = {} for filename, checksum in files_to_download: downloaded_files[filename] = { - "filename": filename, - "path": download_datasets( - repo_path=f"{repo_path}/{filename}", checksum=checksum - ), - } - - times_float = np.load(downloaded_files["times_float.npy"]["path"]) - mat_res_float = np.load( - downloaded_files["matlab_results_float.npy"]["path"] - ) - - r_float = SpikeTrain( - times_float[0], units="ms", t_start=0, t_stop=1000 * ms - ) - s_float = SpikeTrain( - times_float[1], units="ms", t_start=0, t_stop=1000 * ms - ) - t_float = SpikeTrain( - times_float[2], units="ms", t_start=0, t_stop=1000 * ms - ) + 'filename': filename, + 'path': download_datasets(repo_path=f"{repo_path}/{filename}", + checksum=checksum)} + + times_float = np.load(downloaded_files['times_float.npy']['path']) + mat_res_float = np.load(downloaded_files[ + 'matlab_results_float.npy']['path']) + + r_float = SpikeTrain(times_float[0], units='ms', t_start=0, + t_stop=1000 * ms) + s_float = SpikeTrain(times_float[1], units='ms', t_start=0, + t_stop=1000 * ms) + t_float = SpikeTrain(times_float[2], units='ms', t_start=0, + t_stop=1000 * ms) vic_pur_result_float = stds.victor_purpura_distance( [r_float, s_float, t_float], - cost_factor=1.0 / ms, - kernel=None, - sort=True, - algorithm="intuitive", - ) + cost_factor=1.0 / ms, kernel=None, + sort=True, algorithm='intuitive') assert_array_almost_equal(vic_pur_result_float, mat_res_float) def test_victor_purpura_matlab_comparison_int(self): - repo_path = ( + repo_path =\ r"unittest/spike_train_dissimilarity/victor_purpura_distance/data" - ) files_to_download = [ ("times_int.npy", "aa1411c04da3f58d8b8913ae2f935057"), - ("matlab_results_int.npy", "7edd32e50edde12dc1ef4aa5f57f70fb"), - ] + ("matlab_results_int.npy", "7edd32e50edde12dc1ef4aa5f57f70fb")] downloaded_files = {} for filename, checksum in files_to_download: downloaded_files[filename] = { - "filename": filename, - "path": download_datasets( - repo_path=f"{repo_path}/{filename}", checksum=checksum - ), - } + 'filename': filename, + 'path': download_datasets(repo_path=f"{repo_path}/{filename}", + checksum=checksum)} - times_int = np.load(downloaded_files["times_int.npy"]["path"]) + times_int = np.load(downloaded_files['times_int.npy']['path']) mat_res_int = np.load( - downloaded_files["matlab_results_int.npy"]["path"] - ) - - r_int = SpikeTrain( - times_int[0], units="ms", t_start=0, t_stop=1000 * ms - ) - s_int = SpikeTrain( - times_int[1], units="ms", t_start=0, t_stop=1000 * ms - ) - t_int = SpikeTrain( - times_int[2], units="ms", t_start=0, t_stop=1000 * ms - ) + downloaded_files['matlab_results_int.npy']['path']) + + r_int = SpikeTrain(times_int[0], units='ms', t_start=0, + t_stop=1000 * ms) + s_int = SpikeTrain(times_int[1], units='ms', t_start=0, + t_stop=1000 * ms) + t_int = SpikeTrain(times_int[2], units='ms', t_start=0, + t_stop=1000 * ms) vic_pur_result_int = stds.victor_purpura_distance( [r_int, s_int, t_int], - cost_factor=1.0 / ms, - kernel=None, - sort=True, - algorithm="intuitive", - ) + cost_factor=1.0 / ms, kernel=None, + sort=True, algorithm='intuitive') assert_array_equal(vic_pur_result_int, mat_res_int) def test_van_rossum_distance(self): # Tests of distances of simplest spike trains - self.assertEqual( - stds.van_rossum_distance([self.st00, self.st00], self.tau2)[0, 1], - 0.0, - ) - self.assertEqual( - stds.van_rossum_distance([self.st00, self.st01], self.tau2)[0, 1], - 1.0, - ) - self.assertEqual( - stds.van_rossum_distance([self.st01, self.st00], self.tau2)[0, 1], - 1.0, - ) - self.assertEqual( - stds.van_rossum_distance([self.st01, self.st01], self.tau2)[0, 1], - 0.0, - ) + self.assertEqual(stds.van_rossum_distance( + [self.st00, self.st00], self.tau2)[0, 1], 0.0) + self.assertEqual(stds.van_rossum_distance( + [self.st00, self.st01], self.tau2)[0, 1], 1.0) + self.assertEqual(stds.van_rossum_distance( + [self.st01, self.st00], self.tau2)[0, 1], 1.0) + self.assertEqual(stds.van_rossum_distance( + [self.st01, self.st01], self.tau2)[0, 1], 0.0) # Tests of distances under elementary spike operations - self.assertAlmostEqual( - stds.van_rossum_distance([self.st01, self.st02], self.tau2)[0, 1], - float( - np.sqrt( - 2 - * ( - 1.0 - - np.exp( - -np.absolute( - ( - (self.st01[0] - self.st02[0]) / self.tau2 - ).simplified - ) - ) - ) - ) - ), - ) - self.assertAlmostEqual( - stds.van_rossum_distance([self.st01, self.st05], self.tau2)[0, 1], - float( - np.sqrt( - 2 - * ( - 1.0 - - np.exp( - -np.absolute( - ( - (self.st01[0] - self.st05[0]) / self.tau2 - ).simplified - ) - ) - ) - ) - ), - ) - self.assertAlmostEqual( - stds.van_rossum_distance([self.st01, self.st05], self.tau2)[0, 1], - np.sqrt(2.0), - 1, - ) - self.assertAlmostEqual( - stds.van_rossum_distance([self.st01, self.st06], self.tau2)[0, 1], - np.sqrt(2.0), - 20, - ) - self.assertAlmostEqual( - stds.van_rossum_distance([self.st00, self.st07], self.tau1)[0, 1], - np.sqrt(0 + 2), - ) - self.assertAlmostEqual( - stds.van_rossum_distance([self.st07, self.st08], self.tau4)[0, 1], - float( - np.sqrt( - 2 - * ( - 1.0 - - np.exp( - -np.absolute( - ( - (self.st07[0] - self.st08[-1]) / self.tau4 - ).simplified - ) - ) - ) - ) - ), - ) + self.assertAlmostEqual(stds.van_rossum_distance( + [self.st01, self.st02], self.tau2)[0, 1], + float(np.sqrt(2 * (1.0 - np.exp(-np.absolute( + ((self.st01[0] - self.st02[0]) / + self.tau2).simplified)))))) + self.assertAlmostEqual(stds.van_rossum_distance( + [self.st01, self.st05], self.tau2)[0, 1], + float(np.sqrt(2 * (1.0 - np.exp(-np.absolute( + ((self.st01[0] - self.st05[0]) / + self.tau2).simplified)))))) + self.assertAlmostEqual(stds.van_rossum_distance( + [self.st01, self.st05], self.tau2)[0, 1], + np.sqrt(2.0), 1) + self.assertAlmostEqual(stds.van_rossum_distance( + [self.st01, self.st06], self.tau2)[0, 1], + np.sqrt(2.0), 20) + self.assertAlmostEqual(stds.van_rossum_distance( + [self.st00, self.st07], self.tau1)[0, 1], + np.sqrt(0 + 2)) + self.assertAlmostEqual(stds.van_rossum_distance( + [self.st07, self.st08], self.tau4)[0, 1], + float(np.sqrt(2 * (1.0 - np.exp(-np.absolute( + ((self.st07[0] - self.st08[-1]) / + self.tau4).simplified)))))) f_minus_g_squared = ( - (self.t > self.st08[0]) - * np.exp(-((self.t - self.st08[0]) / self.tau3).simplified) - + (self.t > self.st08[1]) - * np.exp(-((self.t - self.st08[1]) / self.tau3).simplified) - - (self.t > self.st09[0]) - * np.exp(-((self.t - self.st09[0]) / self.tau3).simplified) - ) ** 2 - distance = np.sqrt( - 2.0 - * spint.cumulative_trapezoid( - y=f_minus_g_squared, x=self.t.magnitude - )[-1] - / self.tau3.rescale(self.t.units).magnitude - ) - self.assertAlmostEqual( - stds.van_rossum_distance([self.st08, self.st09], self.tau3)[0, 1], - distance, - 5, - ) - self.assertAlmostEqual( - stds.van_rossum_distance([self.st11, self.st14], self.tau2)[0, 1], - 1, - ) + (self.t > self.st08[0]) * np.exp( + -((self.t - self.st08[0]) / self.tau3).simplified) + + (self.t > self.st08[1]) * np.exp( + -((self.t - self.st08[1]) / self.tau3).simplified) - + (self.t > self.st09[0]) * np.exp( + -((self.t - self.st09[0]) / self.tau3).simplified)) ** 2 + distance = np.sqrt(2.0 * spint.cumulative_trapezoid( + y=f_minus_g_squared, x=self.t.magnitude)[-1] / + self.tau3.rescale(self.t.units).magnitude) + self.assertAlmostEqual(stds.van_rossum_distance( + [self.st08, self.st09], self.tau3)[0, 1], distance, 5) + self.assertAlmostEqual(stds.van_rossum_distance( + [self.st11, self.st14], self.tau2)[0, 1], 1) # Tests on timescales self.assertAlmostEqual( stds.van_rossum_distance([self.st11, self.st14], self.tau1)[0, 1], - stds.van_rossum_distance([self.st11, self.st14], self.tau5)[0, 1], - ) + stds.van_rossum_distance([self.st11, self.st14], self.tau5)[0, 1]) self.assertAlmostEqual( stds.van_rossum_distance([self.st07, self.st11], self.tau0)[0, 1], - np.sqrt(len(self.st07) + len(self.st11)), - ) + np.sqrt(len(self.st07) + len(self.st11))) self.assertAlmostEqual( stds.van_rossum_distance([self.st07, self.st14], self.tau0)[0, 1], - np.sqrt(len(self.st07) + len(self.st14)), - ) + np.sqrt(len(self.st07) + len(self.st14))) self.assertAlmostEqual( stds.van_rossum_distance([self.st07, self.st11], self.tau1)[0, 1], - np.sqrt(len(self.st07) + len(self.st11)), - ) + np.sqrt(len(self.st07) + len(self.st11))) self.assertAlmostEqual( stds.van_rossum_distance([self.st07, self.st14], self.tau1)[0, 1], - np.sqrt(len(self.st07) + len(self.st14)), - ) + np.sqrt(len(self.st07) + len(self.st14))) self.assertAlmostEqual( stds.van_rossum_distance([self.st07, self.st11], self.tau5)[0, 1], - np.absolute(len(self.st07) - len(self.st11)), - ) + np.absolute(len(self.st07) - len(self.st11))) self.assertAlmostEqual( stds.van_rossum_distance([self.st07, self.st14], self.tau5)[0, 1], - np.absolute(len(self.st07) - len(self.st14)), - ) + np.absolute(len(self.st07) - len(self.st14))) self.assertAlmostEqual( stds.van_rossum_distance([self.st07, self.st11], self.tau6)[0, 1], - np.absolute(len(self.st07) - len(self.st11)), - ) + np.absolute(len(self.st07) - len(self.st11))) self.assertAlmostEqual( stds.van_rossum_distance([self.st07, self.st14], self.tau6)[0, 1], - np.absolute(len(self.st07) - len(self.st14)), - ) + np.absolute(len(self.st07) - len(self.st14))) # Tests on unordered spiketrains self.assertEqual( stds.van_rossum_distance([self.st11, self.st13], self.tau4)[0, 1], - stds.van_rossum_distance([self.st12, self.st13], self.tau4)[0, 1], - ) + stds.van_rossum_distance([self.st12, self.st13], self.tau4)[0, 1]) self.assertNotEqual( - stds.van_rossum_distance( - [self.st11, self.st13], self.tau4, sort=False - )[0, 1], - stds.van_rossum_distance( - [self.st12, self.st13], self.tau4, sort=False - )[0, 1], - ) + stds.van_rossum_distance([self.st11, self.st13], + self.tau4, sort=False)[0, 1], + stds.van_rossum_distance([self.st12, self.st13], + self.tau4, sort=False)[0, 1]) # Tests on metric properties with random spiketrains # (explicit calculation of second metric axiom in particular case, # because from dist_matrix it is trivial) dist_matrix = stds.van_rossum_distance( - [self.st21, self.st22, self.st23], self.tau3 - ) + [self.st21, self.st22, self.st23], self.tau3) for i in range(3): for j in range(3): self.assertGreaterEqual(dist_matrix[i, j], 0) @@ -932,66 +556,50 @@ def test_van_rossum_distance(self): assert_array_equal(self.rd_st_list[i], self.rd_st_list[j]) assert_array_equal( stds.van_rossum_distance([self.st21, self.st22], self.tau3), - stds.van_rossum_distance([self.st22, self.st21], self.tau3), - ) - self.assertLessEqual( - dist_matrix[0, 1], dist_matrix[0, 2] + dist_matrix[1, 2] - ) - self.assertLessEqual( - dist_matrix[0, 2], dist_matrix[1, 2] + dist_matrix[0, 1] - ) - self.assertLessEqual( - dist_matrix[1, 2], dist_matrix[0, 1] + dist_matrix[0, 2] - ) + stds.van_rossum_distance([self.st22, self.st21], self.tau3)) + self.assertLessEqual(dist_matrix[0, 1], + dist_matrix[0, 2] + dist_matrix[1, 2]) + self.assertLessEqual(dist_matrix[0, 2], + dist_matrix[1, 2] + dist_matrix[0, 1]) + self.assertLessEqual(dist_matrix[1, 2], + dist_matrix[0, 1] + dist_matrix[0, 2]) # Tests on proper unit conversion self.assertAlmostEqual( stds.van_rossum_distance([self.st14, self.st16], self.tau3)[0, 1], - stds.van_rossum_distance([self.st15, self.st16], self.tau3)[0, 1], - ) + stds.van_rossum_distance([self.st15, self.st16], self.tau3)[0, 1]) self.assertAlmostEqual( stds.van_rossum_distance([self.st16, self.st14], self.tau3)[0, 1], - stds.van_rossum_distance([self.st16, self.st15], self.tau3)[0, 1], - ) + stds.van_rossum_distance([self.st16, self.st15], self.tau3)[0, 1]) self.assertEqual( stds.van_rossum_distance([self.st01, self.st05], self.tau3)[0, 1], - stds.van_rossum_distance([self.st01, self.st05], self.tau7)[0, 1], - ) + stds.van_rossum_distance([self.st01, self.st05], self.tau7)[0, 1]) # Tests on algorithmic behaviour for equal spike times f_minus_g_squared = ( - (self.t > self.st31[0]) - * np.exp(-((self.t - self.st31[0]) / self.tau3).simplified) - - (self.t > self.st34[0]) - * np.exp(-((self.t - self.st34[0]) / self.tau3).simplified) - - (self.t > self.st34[1]) - * np.exp(-((self.t - self.st34[1]) / self.tau3).simplified) - ) ** 2 - distance = np.sqrt( - 2.0 - * spint.cumulative_trapezoid( - y=f_minus_g_squared, x=self.t.magnitude - )[-1] - / self.tau3.rescale(self.t.units).magnitude - ) - self.assertAlmostEqual( - stds.van_rossum_distance([self.st31, self.st34], self.tau3)[0, 1], - distance, - 5, - ) - self.assertEqual( - stds.van_rossum_distance([self.st31, self.st34], self.tau3)[0, 1], - stds.van_rossum_distance([self.st32, self.st33], self.tau3)[0, 1], - ) - self.assertEqual( - stds.van_rossum_distance([self.st31, self.st33], self.tau3)[0, 1] - * 2.0, - stds.van_rossum_distance([self.st32, self.st34], self.tau3)[0, 1], - ) + (self.t > self.st31[0]) * np.exp( + -((self.t - self.st31[0]) / self.tau3).simplified) - + (self.t > self.st34[0]) * np.exp( + -((self.t - self.st34[0]) / self.tau3).simplified) - + (self.t > self.st34[1]) * np.exp( + -((self.t - self.st34[1]) / self.tau3).simplified)) ** 2 + distance = np.sqrt(2.0 * spint.cumulative_trapezoid( + y=f_minus_g_squared, x=self.t.magnitude)[-1] / + self.tau3.rescale(self.t.units).magnitude) + self.assertAlmostEqual(stds.van_rossum_distance([self.st31, self.st34], + self.tau3)[0, 1], + distance, 5) + self.assertEqual(stds.van_rossum_distance([self.st31, self.st34], + self.tau3)[0, 1], + stds.van_rossum_distance([self.st32, self.st33], + self.tau3)[0, 1]) + self.assertEqual(stds.van_rossum_distance([self.st31, self.st33], + self.tau3)[0, 1] * 2.0, + stds.van_rossum_distance([self.st32, self.st34], + self.tau3)[0, 1]) # Tests on spike train list lengthes smaller than 2 - self.assertEqual( - stds.van_rossum_distance([self.st21], self.tau3)[0, 0], 0 - ) + self.assertEqual(stds.van_rossum_distance( + [self.st21], self.tau3)[0, 0], 0) self.assertEqual(len(stds.van_rossum_distance([], self.tau3)), 0) -if __name__ == "__main__": +if __name__ == '__main__': unittest.main() From 0dd56d4ce50dba21dcfc1765dc791a4af10f090a Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Mon, 3 Jun 2024 10:15:40 +0200 Subject: [PATCH 58/84] use one os for caching --- .github/workflows/cache_elephant_data.yml | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index 48fbee443..9307737cd 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -17,7 +17,7 @@ jobs: fail-fast: false matrix: # OS [ubuntu-latest, macos-latest, windows-latest] - os: [macos-latest,ubuntu-latest,windows-latest] + os: [macos-latest] steps: - name: Get current hash (SHA) of the elephant_data repo @@ -25,12 +25,12 @@ jobs: run: | echo "dataset_hash=$(git ls-remote https://gin.g-node.org/NeuralEnsemble/elephant-data.git HEAD | cut -f1)" >> $GITHUB_OUTPUT - - uses: actions/cache@v3 + - uses: actions/cache@v4.0.2 # Loading cache of elephant-data id: cache-datasets with: path: ~/elephant-data - key: ${{ runner.os }}-datasets-${{ steps.elephant-data.outputs.dataset_hash }} + key: datasets-${{ steps.elephant-data.outputs.dataset_hash }} - name: Cache found? run: echo "Cache-hit == ${{steps.cache-datasets.outputs.cache-hit == 'true'}}" @@ -46,14 +46,6 @@ jobs: if: steps.cache-datasets.outputs.cache-hit != 'true' && runner.os == 'macOS' run: | brew install datalad - - - name: Install Datalad Linux/ Windows - if: steps.cache-datasets.outputs.cache-hit != 'true' && (runner.os == 'Linux' || runner.os == 'Windows') - run: | - python -m pip install -U pip # Official recommended way - pip install datalad-installer - datalad-installer --sudo ok git-annex --method datalad/packages - pip install datalad - name: Download dataset id: download-dataset @@ -64,15 +56,9 @@ jobs: datalad --version datalad install --recursive --get-data https://gin.g-node.org/NeuralEnsemble/elephant-data - - name: Show size of the cache to assert data is downloaded macOS, Linux - if: runner.os == 'Linux' || runner.os == 'macOS' + - name: Show size of the cache to assert data is downloaded macOS run: | cd ~ du -hs ~/elephant-data ls -lh ~/elephant-data - - name: Show size of the cache to assert data is downloaded Windows - if: runner.os == 'Windows' - run: | - cd ~ - dir ~\elephant-data From 2b37f8360a955eb19e7ff13fb9c6ae47afb5e400 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Mon, 3 Jun 2024 10:18:27 +0200 Subject: [PATCH 59/84] add trigger for workflow --- .github/workflows/cache_elephant_data.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index 9307737cd..dd75ded27 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -8,6 +8,14 @@ on: schedule: - cron: "0 12 * * *" # Daily at noon UTC + pull_request: + branches: + - master + types: + - opened + - reopened + - synchronize + jobs: create-data-cache-if-missing: name: Caching data env From 992d27dedd9e7f12c821949522d8c453b4e05260 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Mon, 3 Jun 2024 10:41:27 +0200 Subject: [PATCH 60/84] use macos cache with win --- .github/workflows/CI.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 03a320d24..03d2966c5 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -229,13 +229,13 @@ jobs: run: | echo "dataset_hash=$(git ls-remote https://gin.g-node.org/NeuralEnsemble/elephant-data.git HEAD | cut -f1)" >> $GITHUB_OUTPUT - - uses: actions/cache/restore@v3 + - uses: actions/cache/restore@v4.0.2 # Loading cache of elephant-data id: cache-datasets with: path: ~/elephant-data - key: ${{ runner.os }}-datasets-${{ steps.elephant-data.outputs.dataset_hash }} - restore-keys: ${{ runner.os }}-datasets- + key: datasets-${{ steps.elephant-data.outputs.dataset_hash }} + restore-keys: datasets- - name: Install dependencies run: | From c5f7e3ac9a529e08cbcff19223767a602d6ef358 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Mon, 3 Jun 2024 10:46:47 +0200 Subject: [PATCH 61/84] update cross os archive --- .github/workflows/CI.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 03d2966c5..826eedfb8 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -235,7 +235,8 @@ jobs: with: path: ~/elephant-data key: datasets-${{ steps.elephant-data.outputs.dataset_hash }} - restore-keys: datasets- + restore-keys: datasets- + enableCrossOsArchive: true - name: Install dependencies run: | From 8253369ea711900585a4443655396cbeae518ddd Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Mon, 3 Jun 2024 10:57:55 +0200 Subject: [PATCH 62/84] use caching for pip ubuntu runner --- .github/workflows/CI.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 826eedfb8..a6ed2822d 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -93,8 +93,9 @@ jobs: id: cache-datasets with: path: ~/elephant-data - key: ${{ runner.os }}-datasets-${{ steps.elephant-data.outputs.dataset_hash }} - restore-keys: ${{ runner.os }}-datasets- + key: datasets-${{ steps.elephant-data.outputs.dataset_hash }} + restore-keys: datasets- + enableCrossOsArchive: true - name: Install dependencies run: | From 8633409fb2b3010bf6e4081140a9f3e3765829cb Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Mon, 3 Jun 2024 10:58:51 +0200 Subject: [PATCH 63/84] add new caching for macOS --- .github/workflows/CI.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index a6ed2822d..c1ccfee4b 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -88,7 +88,7 @@ jobs: run: | echo "dataset_hash=$(git ls-remote https://gin.g-node.org/NeuralEnsemble/elephant-data.git HEAD | cut -f1)" >> $GITHUB_OUTPUT - - uses: actions/cache/restore@v3 + - uses: actions/cache/restore@v4.0.2 # Loading cache of elephant-data id: cache-datasets with: @@ -154,13 +154,13 @@ jobs: run: | echo "dataset_hash=$(git ls-remote https://gin.g-node.org/NeuralEnsemble/elephant-data.git HEAD | cut -f1)" >> $GITHUB_OUTPUT - - uses: actions/cache/restore@v3 + - uses: actions/cache/restore@v4.0.2 # Loading cache of elephant-data id: cache-datasets with: path: ~/elephant-data - key: ${{ runner.os }}-datasets-${{ steps.elephant-data.outputs.dataset_hash }} - restore-keys: ${{ runner.os }}-datasets- + key: datasets-${{ steps.elephant-data.outputs.dataset_hash }} + restore-keys: datasets- - uses: conda-incubator/setup-miniconda@030178870c779d9e5e1b4e563269f3aa69b04081 # corresponds to v3.0.3 with: From a715ded2f7c09cbe12e3577feec8241b4588db0d Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Mon, 3 Jun 2024 10:59:47 +0200 Subject: [PATCH 64/84] add caching for MPI runner --- .github/workflows/CI.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c1ccfee4b..fe56c41ec 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -296,13 +296,14 @@ jobs: run: | echo "dataset_hash=$(git ls-remote https://gin.g-node.org/NeuralEnsemble/elephant-data.git HEAD | cut -f1)" >> $GITHUB_OUTPUT - - uses: actions/cache/restore@v3 + - uses: actions/cache/restore@v4.0.2 # Loading cache of elephant-data id: cache-datasets with: path: ~/elephant-data - key: ${{ runner.os }}-datasets-${{ steps.elephant-data.outputs.dataset_hash }} - restore-keys: ${{ runner.os }}-datasets- + key: datasets-${{ steps.elephant-data.outputs.dataset_hash }} + restore-keys: datasets- + enableCrossOsArchive: true - name: Setup environment run: | From a31e25a4f8be42f312b45f7b62dfa64a3b707e04 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Mon, 3 Jun 2024 11:00:50 +0200 Subject: [PATCH 65/84] add caching for Conda runners --- .github/workflows/CI.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index fe56c41ec..afcbdc339 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -374,13 +374,14 @@ jobs: run: | echo "dataset_hash=$(git ls-remote https://gin.g-node.org/NeuralEnsemble/elephant-data.git HEAD | cut -f1)" >> $GITHUB_OUTPUT - - uses: actions/cache/restore@v3 + - uses: actions/cache/restore@v4.0.2 # Loading cache of elephant-data id: cache-datasets with: path: ~/elephant-data - key: ${{ runner.os }}-datasets-${{ steps.elephant-data.outputs.dataset_hash }} - restore-keys: ${{ runner.os }}-datasets- + key: datasets-${{ steps.elephant-data.outputs.dataset_hash }} + restore-keys: datasets- + enableCrossOsArchive: true - uses: conda-incubator/setup-miniconda@030178870c779d9e5e1b4e563269f3aa69b04081 # corresponds to v3.0.3 with: From 3631eaa1a8ad91177c3fbdda7da7e9013aeab455 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Mon, 3 Jun 2024 13:29:41 +0200 Subject: [PATCH 66/84] update setup python --- .github/workflows/CI.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index afcbdc339..9c1dd56f3 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -73,7 +73,7 @@ jobs: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5.1.0 with: python-version: ${{ matrix.python-version }} check-latest: true @@ -215,7 +215,7 @@ jobs: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5.1.0 with: python-version: ${{ matrix.python-version }} check-latest: true @@ -281,7 +281,7 @@ jobs: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5.1.0 with: python-version: ${{ matrix.python-version }} check-latest: true @@ -508,7 +508,7 @@ jobs: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5.1.0 with: python-version: ${{ matrix.python-version }} From bd49d5a7182371ce43d99a340fb8aa82beda638d Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Mon, 3 Jun 2024 13:34:38 +0200 Subject: [PATCH 67/84] update checkout action --- .github/workflows/CI.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 9c1dd56f3..df25f792a 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -70,7 +70,7 @@ jobs: fail-fast: false steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4.1.6 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5.1.0 @@ -141,7 +141,7 @@ jobs: id: date run: echo "date=$(date +'%Y-%m')" >> $GITHUB_OUTPUT - - uses: actions/checkout@v3 + - uses: actions/checkout@v4.1.6 - name: Cache conda uses: actions/cache@v3 @@ -212,7 +212,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4.1.6 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5.1.0 @@ -278,7 +278,7 @@ jobs: fail-fast: false steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4.1.6 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5.1.0 @@ -355,7 +355,7 @@ jobs: id: date run: echo "date=$(date +'%Y-%m')" >> $GITHUB_OUTPUT - - uses: actions/checkout@v3 + - uses: actions/checkout@v4.1.6 - name: Get pip cache dir id: pip-cache @@ -440,7 +440,7 @@ jobs: id: date run: echo "date=$(date +'%Y-%m')" >> $GITHUB_OUTPUT - - uses: actions/checkout@v3 + - uses: actions/checkout@v4.1.6 - name: Get pip cache dir id: pip-cache @@ -505,7 +505,7 @@ jobs: - name: Get current year-month id: date run: echo "::set-output name=date::$(date +'%Y-%m')" - - uses: actions/checkout@v3 + - uses: actions/checkout@v4.1.6 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5.1.0 From 95efb0b576fa2be133fa23b912c1f1d54fe47a0f Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Mon, 3 Jun 2024 13:42:04 +0200 Subject: [PATCH 68/84] update macOS runner --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index df25f792a..65b48c3c0 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -134,7 +134,7 @@ jobs: fail-fast: false matrix: # OS [ubuntu-latest, macos-latest, windows-latest] - os: [macos-11,macos-12] + os: [macos-12,macos-13] python-version: [3.11] steps: - name: Get current year-month From 5fb913b58278645f2070f9630abe4cd4b516e377 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Mon, 3 Jun 2024 13:44:18 +0200 Subject: [PATCH 69/84] update miniconda setup --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 65b48c3c0..a1164a708 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -162,7 +162,7 @@ jobs: key: datasets-${{ steps.elephant-data.outputs.dataset_hash }} restore-keys: datasets- - - uses: conda-incubator/setup-miniconda@030178870c779d9e5e1b4e563269f3aa69b04081 # corresponds to v3.0.3 + - uses: conda-incubator/setup-miniconda@a4260408e20b96e80095f42ff7f1a15b27dd94ca # corresponds to v3.0.4 with: auto-update-conda: true python-version: ${{ matrix.python-version }} From 936302ef95e09218b6531d72648a3c9fd4974829 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Mon, 3 Jun 2024 13:50:08 +0200 Subject: [PATCH 70/84] add version cap for neo --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index b3b9d6f98..eb216c448 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,4 +1,4 @@ -neo>=0.10.0 +neo>=0.10.0 < 0.13.1 numpy>=1.19.5, <2 quantities>=0.14.1 scipy>=1.10.0 From 29c3f88efef4fa5534b0c335e6386f1c0c1ae9a1 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Mon, 3 Jun 2024 13:50:24 +0200 Subject: [PATCH 71/84] fix typo --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index eb216c448..0843141cf 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,4 +1,4 @@ -neo>=0.10.0 < 0.13.1 +neo>=0.10.0, < 0.13.1 numpy>=1.19.5, <2 quantities>=0.14.1 scipy>=1.10.0 From d78037ffb91f2e387317262ed44f24047b8bb22f Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Mon, 3 Jun 2024 14:10:20 +0200 Subject: [PATCH 72/84] add version cap for matplotlib --- requirements/requirements-docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements-docs.txt b/requirements/requirements-docs.txt index 72c42b6c3..e05df77a8 100644 --- a/requirements/requirements-docs.txt +++ b/requirements/requirements-docs.txt @@ -5,5 +5,5 @@ sphinx>=3.3.0 nbsphinx>=0.8.0 sphinxcontrib-bibtex>1.0.0 sphinx-tabs>=1.3.0 -matplotlib>=3.3.2 +matplotlib>=3.3.2, <3.9.0 # conda install -c conda-forge pandoc From c73431bd21d52b5616d358c191eb3b028ce91037 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Mon, 3 Jun 2024 14:13:21 +0200 Subject: [PATCH 73/84] add version cap for matplotlib --- requirements/requirements-tutorials.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements-tutorials.txt b/requirements/requirements-tutorials.txt index 3ee70c3cd..5c142ab15 100644 --- a/requirements/requirements-tutorials.txt +++ b/requirements/requirements-tutorials.txt @@ -1,4 +1,4 @@ # Packages required to execute jupyter notebook tutorials -matplotlib>=3.3.2 +matplotlib>=3.3.2, <3.9.0 h5py>=3.1.0 nixio>=1.5.0 \ No newline at end of file From c34b89337a1e5d18dc0507f57ba2234309b9a8e4 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Mon, 3 Jun 2024 15:32:55 +0200 Subject: [PATCH 74/84] update name of env variable --- .github/workflows/CI.yml | 20 ++++++++++---------- elephant/datasets.py | 33 ++++++++++++++++++++++++--------- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index a1164a708..d01bba6be 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -111,8 +111,8 @@ jobs: - name: Test with pytest run: | if [ -d ~/elephant-data ]; then - export ELEPHANT_DATA_PATH=~/elephant-data - echo $ELEPHANT_DATA_PATH + export ELEPHANT_DATA_LOCATION=~/elephant-data + echo $ELEPHANT_DATA_LOCATION fi coverage run --source=elephant -m pytest @@ -190,8 +190,8 @@ jobs: shell: bash -l {0} run: | if [ -d ~/elephant-data ]; then - export ELEPHANT_DATA_PATH=~/elephant-data - echo $ELEPHANT_DATA_PATH + export ELEPHANT_DATA_LOCATION=~/elephant-data + echo $ELEPHANT_DATA_LOCATION fi pytest --cov=elephant @@ -253,8 +253,8 @@ jobs: - name: Test with pytest run: | if (Test-Path "$env:USERPROFILE\elephant-data") { - $env:ELEPHANT_DATA_PATH = "$env:USERPROFILE\elephant-data" - Write-Output $env:ELEPHANT_DATA_PATH + $env:ELEPHANT_DATA_LOCATION = "$env:USERPROFILE\elephant-data" + Write-Output $env:ELEPHANT_DATA_LOCATION } pytest --cov=elephant @@ -323,8 +323,8 @@ jobs: - name: Test with pytest run: | if [ -d ~/elephant-data ]; then - export ELEPHANT_DATA_PATH=~/elephant-data - echo $ELEPHANT_DATA_PATH + export ELEPHANT_DATA_LOCATION=~/elephant-data + echo $ELEPHANT_DATA_LOCATION fi mpiexec -n 1 python -m mpi4py -m coverage run --source=elephant -m pytest coveralls --service=github || echo "Coveralls submission failed" @@ -412,8 +412,8 @@ jobs: shell: bash -el {0} run: | if [ -d ~/elephant-data ]; then - export ELEPHANT_DATA_PATH=~/elephant-data - echo $ELEPHANT_DATA_PATH + export ELEPHANT_DATA_LOCATION=~/elephant-data + echo $ELEPHANT_DATA_LOCATION fi pytest --cov=elephant diff --git a/elephant/datasets.py b/elephant/datasets.py index ad88d0a54..28f2eac62 100644 --- a/elephant/datasets.py +++ b/elephant/datasets.py @@ -7,9 +7,13 @@ from pathlib import Path from urllib.request import urlretrieve, urlopen from urllib.error import HTTPError, URLError +from urllib.parse import urlparse from zipfile import ZipFile +import os from os import environ, getenv + + from tqdm import tqdm ELEPHANT_TMP_DIR = Path(tempfile.gettempdir()) / "elephant" @@ -71,6 +75,16 @@ def download(url, filepath=None, checksum=None, verbose=True): return filepath +def is_path(path_or_url: str) -> bool: + try: + # Attempt to create a Path object + path = Path(path_or_url) + # Check if the path has at least one part + return bool(path.drive or path.root or path.parts) + except Exception: + return False + + def download_datasets(repo_path, filepath=None, checksum=None, verbose=True): r""" @@ -88,17 +102,17 @@ def download_datasets(repo_path, filepath=None, checksum=None, - https://datasets.python-elephant.org/ points to the root of elephant data - To change this URL, use the environment variable `ELEPHANT_DATA_URL`. + To change this URL, use the environment variable `ELEPHANT_DATA_LOCATION`. When using data, which is not yet contained in the master branch or a release of elephant data, e.g. during development, this variable can be used to change the default URL. For example to use data on branch `multitaper`, change the - `ELEPHANT_DATA_URL` to + `ELEPHANT_DATA_LOCATION` to https://web.gin.g-node.org/NeuralEnsemble/elephant-data/raw/multitaper. For a complete example, see Examples section. To use a local copy of elephant-data, use the environment variable - `ELEPHANT_DATA_PATH`, e.g. set to /home/user/elephant-data. + `ELEPHANT_DATA_LOCATION`, e.g. set to /home/user/elephant-data. Parameters ---------- @@ -123,7 +137,7 @@ def download_datasets(repo_path, filepath=None, checksum=None, ----- The default URL always points to elephant-data. Please do not change its value. For development purposes use the environment - variable 'ELEPHANT_DATA_URL'. + variable 'ELEPHANT_DATA_LOCATION'. Examples -------- @@ -132,13 +146,14 @@ def download_datasets(repo_path, filepath=None, checksum=None, >>> import os >>> from elephant.datasets import download_datasets - >>> os.environ["ELEPHANT_DATA_URL"] = "https://web.gin.g-node.org/NeuralEnsemble/elephant-data/raw/multitaper" # noqa + >>> os.environ["ELEPHANT_DATA_LOCATION"] = "https://web.gin.g-node.org/NeuralEnsemble/elephant-data/raw/multitaper" # noqa >>> download_datasets("unittest/spectral/multitaper_psd/data/time_series.npy") # doctest: +SKIP PosixPath('/tmp/elephant/time_series.npy') """ - if 'ELEPHANT_DATA_PATH' in environ: # user did set local path - return Path(f"{getenv('ELEPHANT_DATA_PATH')}/{repo_path}") + if 'ELEPHANT_DATA_LOCATION' in environ: # user did set local path + if is_path(getenv('ELEPHANT_DATA_LOCATION')): + return Path(f"{getenv('ELEPHANT_DATA_LOCATION')}/{repo_path}") # this url redirects to the current location of elephant-data url_to_root = "https://datasets.python-elephant.org/" @@ -147,7 +162,7 @@ def download_datasets(repo_path, filepath=None, checksum=None, # (version elephant is equal to version elephant-data) default_url = url_to_root + f"raw/v{_get_version()}" - if 'ELEPHANT_DATA_URL' not in environ: # user did not set URL + if 'ELEPHANT_DATA_LOCATION' not in environ: # user did not set URL # is 'version-URL' available? (not for elephant development version) try: urlopen(default_url+'/README.md') @@ -175,7 +190,7 @@ def download_datasets(repo_path, filepath=None, checksum=None, warnings.warn(f"Data URL:{default_url}, error: {error}." f"{error.reason}") - url = f"{getenv('ELEPHANT_DATA_URL', default_url)}/{repo_path}" + url = f"{getenv('ELEPHANT_DATA_LOCATION', default_url)}/{repo_path}" return download(url, filepath, checksum, verbose) From 0b180a8a4a991b73486210430cf1122482ab9ab8 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Mon, 3 Jun 2024 15:43:36 +0200 Subject: [PATCH 75/84] do some clean up, change time of cron job --- .github/workflows/cache_elephant_data.yml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index dd75ded27..87e682020 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -6,7 +6,7 @@ on: branches: - master schedule: - - cron: "0 12 * * *" # Daily at noon UTC + - cron: "11 23 * * *" # Daily at 23:11 UTC pull_request: branches: @@ -19,13 +19,10 @@ on: jobs: create-data-cache-if-missing: name: Caching data env - runs-on: ${{ matrix.os }} + runs-on: macos-latest strategy: # do not cancel all in-progress jobs if any matrix job fails fail-fast: false - matrix: - # OS [ubuntu-latest, macos-latest, windows-latest] - os: [macos-latest] steps: - name: Get current hash (SHA) of the elephant_data repo @@ -50,8 +47,8 @@ jobs: git config --global user.name "elephant CI" git config --global filter.annex.process "git-annex filter-process" # recommended for efficiency - - name: Install Datalad macOS - if: steps.cache-datasets.outputs.cache-hit != 'true' && runner.os == 'macOS' + - name: Install Datalad + if: steps.cache-datasets.outputs.cache-hit != 'true' run: | brew install datalad @@ -64,7 +61,7 @@ jobs: datalad --version datalad install --recursive --get-data https://gin.g-node.org/NeuralEnsemble/elephant-data - - name: Show size of the cache to assert data is downloaded macOS + - name: Show size of the cache to assert data is downloaded run: | cd ~ du -hs ~/elephant-data From 512bcb4b210317ddd3365ce35efe617f3ec6269d Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Mon, 3 Jun 2024 15:50:51 +0200 Subject: [PATCH 76/84] clean up --- elephant/datasets.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/elephant/datasets.py b/elephant/datasets.py index 28f2eac62..317f243bd 100644 --- a/elephant/datasets.py +++ b/elephant/datasets.py @@ -1,21 +1,17 @@ import hashlib +import ssl import tempfile import warnings -import ssl - -from elephant import _get_version +from os import environ, getenv from pathlib import Path -from urllib.request import urlretrieve, urlopen from urllib.error import HTTPError, URLError -from urllib.parse import urlparse +from urllib.request import urlopen, urlretrieve from zipfile import ZipFile -import os -from os import environ, getenv - - from tqdm import tqdm +from elephant import _get_version + ELEPHANT_TMP_DIR = Path(tempfile.gettempdir()) / "elephant" From 21020573aefbe57b4d4bfbd2c03a2409da14f583 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Tue, 11 Jun 2024 09:38:05 +0200 Subject: [PATCH 77/84] runner to create caches set to ubuntu --- .github/workflows/cache_elephant_data.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index 87e682020..a179099eb 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -19,7 +19,7 @@ on: jobs: create-data-cache-if-missing: name: Caching data env - runs-on: macos-latest + runs-on: ubuntu-latest strategy: # do not cancel all in-progress jobs if any matrix job fails fail-fast: false @@ -46,11 +46,14 @@ jobs: git config --global user.email "elephant_ci@fake_mail.com" git config --global user.name "elephant CI" git config --global filter.annex.process "git-annex filter-process" # recommended for efficiency - - - name: Install Datalad + + - name: Install Datalad Linux if: steps.cache-datasets.outputs.cache-hit != 'true' run: | - brew install datalad + python -m pip install -U pip # Official recommended way + pip install datalad-installer + datalad-installer --sudo ok git-annex --method datalad/packages + pip install datalad - name: Download dataset id: download-dataset From ae5d4c4dae13a09f964662f8c5b0a819ba8328a2 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 14 Jun 2024 13:12:10 +0200 Subject: [PATCH 78/84] add test if path exists --- elephant/datasets.py | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/elephant/datasets.py b/elephant/datasets.py index 317f243bd..7ceacddae 100644 --- a/elephant/datasets.py +++ b/elephant/datasets.py @@ -1,4 +1,5 @@ import hashlib +import os import ssl import tempfile import warnings @@ -71,16 +72,6 @@ def download(url, filepath=None, checksum=None, verbose=True): return filepath -def is_path(path_or_url: str) -> bool: - try: - # Attempt to create a Path object - path = Path(path_or_url) - # Check if the path has at least one part - return bool(path.drive or path.root or path.parts) - except Exception: - return False - - def download_datasets(repo_path, filepath=None, checksum=None, verbose=True): r""" @@ -147,8 +138,8 @@ def download_datasets(repo_path, filepath=None, checksum=None, PosixPath('/tmp/elephant/time_series.npy') """ - if 'ELEPHANT_DATA_LOCATION' in environ: # user did set local path - if is_path(getenv('ELEPHANT_DATA_LOCATION')): + if 'ELEPHANT_DATA_LOCATION' in environ: # user did set path or URL + if os.path.exists(getenv('ELEPHANT_DATA_LOCATION')): return Path(f"{getenv('ELEPHANT_DATA_LOCATION')}/{repo_path}") # this url redirects to the current location of elephant-data From 7de88532e0fd1257d6aa931b76058c3961c9f98b Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:01:54 +0200 Subject: [PATCH 79/84] add error for invalid data locations --- elephant/datasets.py | 135 ++++++++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 65 deletions(-) diff --git a/elephant/datasets.py b/elephant/datasets.py index 7ceacddae..39ed56911 100644 --- a/elephant/datasets.py +++ b/elephant/datasets.py @@ -2,6 +2,7 @@ import os import ssl import tempfile +from urllib.parse import urlparse import warnings from os import environ, getenv from pathlib import Path @@ -75,72 +76,76 @@ def download(url, filepath=None, checksum=None, verbose=True): def download_datasets(repo_path, filepath=None, checksum=None, verbose=True): r""" - This function can be used to download files from elephant-data using - only the path relative to the root of the elephant-data repository. - The default URL used, points to elephants corresponding release of - elephant-data. - Different versions of the elephant package may require different - versions of elephant-data. - e.g. the following URLs: - - https://web.gin.g-node.org/NeuralEnsemble/elephant-data/raw/0.0.1 - points to release v0.0.1. - - https://web.gin.g-node.org/NeuralEnsemble/elephant-data/raw/master - always points to the latest state of elephant-data. - - https://datasets.python-elephant.org/ - points to the root of elephant data - - To change this URL, use the environment variable `ELEPHANT_DATA_LOCATION`. - When using data, which is not yet contained in the master branch or a - release of elephant data, e.g. during development, this variable can - be used to change the default URL. - For example to use data on branch `multitaper`, change the - `ELEPHANT_DATA_LOCATION` to - https://web.gin.g-node.org/NeuralEnsemble/elephant-data/raw/multitaper. - For a complete example, see Examples section. + This function can be used to download files from elephant-data using + only the path relative to the root of the elephant-data repository. + The default URL used, points to elephants corresponding release of + elephant-data. + Different versions of the elephant package may require different + versions of elephant-data. + e.g. the following URLs: + - https://web.gin.g-node.org/NeuralEnsemble/elephant-data/raw/0.0.1 + points to release v0.0.1. + - https://web.gin.g-node.org/NeuralEnsemble/elephant-data/raw/master + always points to the latest state of elephant-data. + - https://datasets.python-elephant.org/ + points to the root of elephant data + + To change this URL, use the environment variable `ELEPHANT_DATA_LOCATION`. + When using data, which is not yet contained in the master branch or a + release of elephant data, e.g. during development, this variable can + be used to change the default URL. + For example to use data on branch `multitaper`, change the + `ELEPHANT_DATA_LOCATION` to + https://web.gin.g-node.org/NeuralEnsemble/elephant-data/raw/multitaper. + For a complete example, see Examples section. - To use a local copy of elephant-data, use the environment variable - `ELEPHANT_DATA_LOCATION`, e.g. set to /home/user/elephant-data. + To use a local copy of elephant-data, use the environment variable + `ELEPHANT_DATA_LOCATION`, e.g. set to /home/user/elephant-data. - Parameters - ---------- - repo_path : str - String denoting the path relative to elephant-data repository root - filepath : str, optional - Path to temporary folder where the downloaded files will be stored - checksum : str, optional - Checksum to verify data integrity after download - verbose : bool, optional - Whether to disable the entire progressbar wrapper []. - If set to None, disable on non-TTY. - Default: True - - Returns - ------- - filepath : pathlib.Path - Path to downloaded files. - - - Notes - ----- - The default URL always points to elephant-data. Please - do not change its value. For development purposes use the environment - variable 'ELEPHANT_DATA_LOCATION'. - - Examples - -------- - The following example downloads a file from elephant-data branch - 'multitaper', by setting the environment variable to the branch URL: - - >>> import os - >>> from elephant.datasets import download_datasets - >>> os.environ["ELEPHANT_DATA_LOCATION"] = "https://web.gin.g-node.org/NeuralEnsemble/elephant-data/raw/multitaper" # noqa - >>> download_datasets("unittest/spectral/multitaper_psd/data/time_series.npy") # doctest: +SKIP - PosixPath('/tmp/elephant/time_series.npy') - """ + Parameters + ---------- + repo_path : str + String denoting the path relative to elephant-data repository root + filepath : str, optional + Path to temporary folder where the downloaded files will be stored + checksum : str, optional + Checksum to verify data integrity after download + verbose : bool, optional + Whether to disable the entire progressbar wrapper []. + If set to None, disable on non-TTY. + Default: True + + Returns + ------- + filepath : pathlib.Path + Path to downloaded files. + + + Notes + ----- + The default URL always points to elephant-data. Please + do not change its value. For development purposes use the environment + variable 'ELEPHANT_DATA_LOCATION'. + + Examples + -------- + The following example downloads a file from elephant-data branch + 'multitaper', by setting the environment variable to the branch URL: + + >>> import os + >>> from elephant.datasets import download_datasets + >>> os.environ["ELEPHANT_DATA_LOCATION"] = "https://web.gin.g-node.org/NeuralEnsemble/elephant-data/raw/multitaper" # noqa + >>> download_datasets("unittest/spectral/multitaper_psd/data/time_series.npy") # doctest: +SKIP + PosixPath('/tmp/elephant/time_series.npy') + """ - if 'ELEPHANT_DATA_LOCATION' in environ: # user did set path or URL - if os.path.exists(getenv('ELEPHANT_DATA_LOCATION')): - return Path(f"{getenv('ELEPHANT_DATA_LOCATION')}/{repo_path}") + env_var = 'ELEPHANT_DATA_LOCATION' + if env_var in os.environ: # user did set path or URL + if os.path.exists(getenv(env_var)): + return Path(f"{getenv(env_var)}/{repo_path}") + elif urlparse(getenv(env_var)).scheme not in ('http', 'https'): + raise ValueError(f"The environment variable {env_var} must be set to either an existing file system path " + f"or a valid URL. Given value: '{getenv(env_var)}' is neither.") # this url redirects to the current location of elephant-data url_to_root = "https://datasets.python-elephant.org/" @@ -149,7 +154,7 @@ def download_datasets(repo_path, filepath=None, checksum=None, # (version elephant is equal to version elephant-data) default_url = url_to_root + f"raw/v{_get_version()}" - if 'ELEPHANT_DATA_LOCATION' not in environ: # user did not set URL + if env_var not in environ: # user did not set URL # is 'version-URL' available? (not for elephant development version) try: urlopen(default_url+'/README.md') @@ -177,7 +182,7 @@ def download_datasets(repo_path, filepath=None, checksum=None, warnings.warn(f"Data URL:{default_url}, error: {error}." f"{error.reason}") - url = f"{getenv('ELEPHANT_DATA_LOCATION', default_url)}/{repo_path}" + url = f"{getenv(env_var, default_url)}/{repo_path}" return download(url, filepath, checksum, verbose) From a1833c69446a8226fe4939e11637c0562be2c69a Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 14 Jun 2024 16:21:47 +0200 Subject: [PATCH 80/84] add tests for download_datasets function --- elephant/test/test_datasets.py | 35 ++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 elephant/test/test_datasets.py diff --git a/elephant/test/test_datasets.py b/elephant/test/test_datasets.py new file mode 100644 index 000000000..24334e2f6 --- /dev/null +++ b/elephant/test/test_datasets.py @@ -0,0 +1,35 @@ +import unittest +import os +from unittest.mock import patch +from pathlib import Path +import urllib + +from elephant.datasets import download_datasets + + +class TestDownloadDatasets(unittest.TestCase): + @patch.dict(os.environ, {'ELEPHANT_DATA_LOCATION': '/valid/path'}, clear=True) + @patch('os.path.exists', return_value=True) + def test_valid_path(self, mock_exists): + repo_path = 'some/repo/path' + expected = Path('/valid/path/some/repo/path') + result = download_datasets(repo_path) + self.assertEqual(result, expected) + + @patch.dict(os.environ, {'ELEPHANT_DATA_LOCATION': 'http://valid.url'}, clear=True) + @patch('os.path.exists', return_value=False) + def test_valid_url(self, mock_exists): + repo_path = 'some/repo/path' + self.assertRaises(urllib.error.URLError, download_datasets, repo_path) + + @patch.dict(os.environ, {'ELEPHANT_DATA_LOCATION': 'invalid_path_or_url'}, clear=True) + @patch('os.path.exists', return_value=False) + def test_invalid_value(self, mock_exists): + repo_path = 'some/repo/path' + with self.assertRaises(ValueError) as cm: + download_datasets(repo_path) + self.assertIn("invalid_path_or_url", str(cm.exception)) + + +if __name__ == '__main__': + unittest.main() From 5774b20e466813b76f9ae4d03aa6b7451b1aad73 Mon Sep 17 00:00:00 2001 From: Moritz Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 28 Jun 2024 09:05:40 +0200 Subject: [PATCH 81/84] Update requirements.txt remove neo version cap --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 0843141cf..b3b9d6f98 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,4 +1,4 @@ -neo>=0.10.0, < 0.13.1 +neo>=0.10.0 numpy>=1.19.5, <2 quantities>=0.14.1 scipy>=1.10.0 From ae8c63642c8dfc4bcf46e81877f2f8ddec35f0b9 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 28 Jun 2024 09:10:22 +0200 Subject: [PATCH 82/84] remove trigger from caching action --- .github/workflows/cache_elephant_data.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/cache_elephant_data.yml b/.github/workflows/cache_elephant_data.yml index a179099eb..ab17af4f9 100644 --- a/.github/workflows/cache_elephant_data.yml +++ b/.github/workflows/cache_elephant_data.yml @@ -8,13 +8,6 @@ on: schedule: - cron: "11 23 * * *" # Daily at 23:11 UTC - pull_request: - branches: - - master - types: - - opened - - reopened - - synchronize jobs: create-data-cache-if-missing: From 2fffb43690c0f85210a50830185f4d9421cf5bb4 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Fri, 28 Jun 2024 09:16:57 +0200 Subject: [PATCH 83/84] add version cap for scipy --- requirements/environment.yml | 2 +- requirements/requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements/environment.yml b/requirements/environment.yml index fa8fb6e1d..547ff1ce7 100644 --- a/requirements/environment.yml +++ b/requirements/environment.yml @@ -7,7 +7,7 @@ dependencies: - python>=3.8 - mpi4py - numpy>=1.19.5, <2 - - scipy>=1.10.0 + - scipy>=1.10.0, <1.14.0 - tqdm - scikit-learn - statsmodels diff --git a/requirements/requirements.txt b/requirements/requirements.txt index b3b9d6f98..790fcd440 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,6 +1,6 @@ neo>=0.10.0 numpy>=1.19.5, <2 quantities>=0.14.1 -scipy>=1.10.0 +scipy>=1.10.0, <1.14.0 six>=1.10.0 tqdm From 9cb7109c33e87bad57d466e8675cdeb9561eb455 Mon Sep 17 00:00:00 2001 From: Moritz-Alexander-Kern <92092328+Moritz-Alexander-Kern@users.noreply.github.com> Date: Tue, 23 Jul 2024 14:25:12 +0200 Subject: [PATCH 84/84] remove scipy version caps --- requirements/environment.yml | 2 +- requirements/requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements/environment.yml b/requirements/environment.yml index 547ff1ce7..fa8fb6e1d 100644 --- a/requirements/environment.yml +++ b/requirements/environment.yml @@ -7,7 +7,7 @@ dependencies: - python>=3.8 - mpi4py - numpy>=1.19.5, <2 - - scipy>=1.10.0, <1.14.0 + - scipy>=1.10.0 - tqdm - scikit-learn - statsmodels diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 790fcd440..b3b9d6f98 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,6 +1,6 @@ neo>=0.10.0 numpy>=1.19.5, <2 quantities>=0.14.1 -scipy>=1.10.0, <1.14.0 +scipy>=1.10.0 six>=1.10.0 tqdm