diff --git a/.github/workflows/core-test.yml b/.github/workflows/core-test.yml index d5c1efa82..f654dcdc1 100644 --- a/.github/workflows/core-test.yml +++ b/.github/workflows/core-test.yml @@ -26,17 +26,32 @@ jobs: matrix: os: ["ubuntu-latest", "windows-latest"] # "macos-latest", - python-version: ['3.8', '3.9', '3.10', '3.11'] - numpy-version: ['1.20.3', '1.21.6', '1.22.4', '1.23.5', '1.24.1', '1.25.1'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] + numpy-version: ['1.20.3', '1.21.6', '1.22.4', '1.23.5', '1.24.1', '1.25.1', '1.26.4'] exclude: - python-version: '3.8' numpy-version: '1.25.1' + - python-version: '3.8' + numpy-version: '1.26.4' - python-version: '3.10' numpy-version: '1.20.3' - python-version: '3.11' numpy-version: '1.20.3' - python-version: '3.11' numpy-version: '1.21.6' + - python-version: '3.12' + numpy-version: '1.20.3' + # python 3.12 only works on latest numpy + - python-version: '3.12' + numpy-version: '1.21.6' + - python-version: '3.12' + numpy-version: '1.22.4' + - python-version: '3.12' + numpy-version: '1.23.5' + - python-version: '3.12' + numpy-version: '1.24.1' + - python-version: '3.12' + numpy-version: '1.25.1' steps: - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 diff --git a/.github/workflows/io-test.yml b/.github/workflows/io-test.yml index 3688562da..8522e7e4e 100644 --- a/.github/workflows/io-test.yml +++ b/.github/workflows/io-test.yml @@ -13,12 +13,12 @@ concurrency: # Cancel previous workflows on the same pull request jobs: build-and-test: - name: Test on (${{ inputs.os }}) + name: Test on (${{ inputs.os }}) (${{ matrix.python-version}}) runs-on: ${{ inputs.os }} strategy: fail-fast: true matrix: - python-version: ['3.9', ] + python-version: ['3.9', '3.11'] defaults: # by default run in bash mode (required for conda usage) run: @@ -75,6 +75,7 @@ jobs: if: steps.cache-conda-env.outputs.cache-hit != 'true' run: | conda env update --name neo-test-env --file environment_testing.yml --prune + conda install python=${{ matrix.python-version }} - name: Configure git run: | diff --git a/environment_testing.yml b/environment_testing.yml index 7e5aee66a..8ff8bd984 100644 --- a/environment_testing.yml +++ b/environment_testing.yml @@ -2,6 +2,5 @@ name: neo-test-env channels: - conda-forge dependencies: - - python=3.9 - datalad - pip diff --git a/neo/rawio/intanrawio.py b/neo/rawio/intanrawio.py index 67052be7c..81b23f8b4 100644 --- a/neo/rawio/intanrawio.py +++ b/neo/rawio/intanrawio.py @@ -20,8 +20,6 @@ """ from pathlib import Path -import os -from collections import OrderedDict from packaging.version import Version import warnings @@ -44,8 +42,12 @@ class IntanRawIO(BaseRawIO): Parameters ---------- filename: str, default: '' - name of the 'rhd' or 'rhs' data/header file - + name of the 'rhd' or 'rhs' data/header file + ignore_integrity_checks: bool, default: False + If True, data that violates integrity assumptions will be loaded. At the moment the only integrity + check we perform is that timestamps are continuous. Setting this to True will ignore this check and set + the attribute `discontinuous_timestamps` to True if the timestamps are not continous. This attribute can be checked + after parsing the header to see if the timestamps are continuous or not. Notes ----- * The Intan reader can handle two file formats 'rhd' and 'rhs'. It will automatically @@ -99,10 +101,13 @@ class IntanRawIO(BaseRawIO): extensions = ["rhd", "rhs", "dat"] rawmode = "one-file" - def __init__(self, filename=""): + def __init__(self, filename="", ignore_integrity_checks=False): BaseRawIO.__init__(self) self.filename = filename + self.ignore_integrity_checks = ignore_integrity_checks + self.discontinuous_timestamps = False + def _source_name(self): return self.filename @@ -202,11 +207,18 @@ def _parse_header(self): elif self.file_format == "one-file-per-channel": time_stream_index = max(self._raw_data.keys()) timestamp = self._raw_data[time_stream_index][0] - - if not np.all(np.diff(timestamp) == 1): - raise NeoReadWriteError( - f"Timestamp have gaps, this could be due to a corrupted file or an inappropriate file merge" - ) + + discontinuous_timestamps = np.diff(timestamp) != 1 + timestamps_are_not_contiguous = np.any(discontinuous_timestamps) + if timestamps_are_not_contiguous: + self.discontinuous_timestamps = True + if not self.ignore_integrity_checks: + error_msg = ( + "Timestamps are not continuous, this could be due to a corrupted file or an inappropriate file merge. " + "Initialize the reader with `ignore_integrity_checks=True` to ignore this error and open the file. \n" + f"Timestamps around discontinuities: {timestamp[discontinuous_timestamps]}" + ) + raise NeoReadWriteError(error_msg) # signals signal_channels = []