diff --git a/neo/rawio/axonrawio.py b/neo/rawio/axonrawio.py index 166446a90..ea8232bc4 100644 --- a/neo/rawio/axonrawio.py +++ b/neo/rawio/axonrawio.py @@ -673,7 +673,13 @@ def _parse_abf_v1(f, header_description): ss = header["lFileStartTime"] - hh * 3600 - mm * 60 ms = int(np.mod(ss, 1) * 1e6) ss = int(ss) - header["rec_datetime"] = datetime.datetime(YY, MM, DD, hh, mm, ss, ms) + try: + header["rec_datetime"] = datetime.datetime(YY, MM, DD, hh, mm, ss, ms) + except (ValueError, OverflowError): + # Date/time header fields hold an out-of-range or "no date" sentinel + # (e.g. 0xFFFFFFFF). The acquisition date is non-essential annotation, + # so fall back to None rather than blocking the read of the signal. + header["rec_datetime"] = None return header @@ -1025,7 +1031,13 @@ def _parse_abf_v2(f, header_description): ss = header["uFileStartTimeMS"] / 1000.0 - hh * 3600 - mm * 60 ms = int(np.mod(ss, 1) * 1e6) ss = int(ss) - header["rec_datetime"] = datetime.datetime(YY, MM, DD, hh, mm, ss, ms) + try: + header["rec_datetime"] = datetime.datetime(YY, MM, DD, hh, mm, ss, ms) + except (ValueError, OverflowError): + # Date/time header fields hold an out-of-range or "no date" sentinel + # (e.g. 0xFFFFFFFF). The acquisition date is non-essential annotation, + # so fall back to None rather than blocking the read of the signal. + header["rec_datetime"] = None return header diff --git a/neo/test/rawiotest/test_axonrawio.py b/neo/test/rawiotest/test_axonrawio.py index a1cb7dd2b..75e603b79 100644 --- a/neo/test/rawiotest/test_axonrawio.py +++ b/neo/test/rawiotest/test_axonrawio.py @@ -1,6 +1,6 @@ import unittest -from neo.rawio.axonrawio import AxonRawIO +from neo.rawio.axonrawio import AxonRawIO, parse_axon_soup from neo.test.rawiotest.common_rawio_test import BaseTestRawIO @@ -28,6 +28,18 @@ def test_read_raw_protocol(self): reader.read_raw_protocol() + def test_invalid_date_falls_back_to_none(self): + # Some ABF files store an out-of-range / "no date" sentinel (e.g. 0xFFFFFFFF) + # in the acquisition date header fields. The date is non-essential annotation, + # so parsing must fall back to rec_datetime=None rather than raising and + # blocking access to the signal. + for fixture in [ + "axon/intracellular_data/files_with_errors/invalid_date_abf1.abf", # ABF v1 + "axon/intracellular_data/files_with_errors/invalid_date_abf2.abf", # ABF v2 + ]: + header = parse_axon_soup(self.get_local_path(fixture)) + self.assertIsNone(header["rec_datetime"]) + if __name__ == "__main__": unittest.main()