diff --git a/doc/source/authors.rst b/doc/source/authors.rst index f48515458..bddb41844 100644 --- a/doc/source/authors.rst +++ b/doc/source/authors.rst @@ -52,6 +52,7 @@ and may not be the current affiliation of a contributor. * rishidhingra@github * Hugo van Kemenade * Aitor Morales-Gregorio [13] +* Peter N Steinmetz [22] 1. Centre de Recherche en Neuroscience de Lyon, CNRS UMR5292 - INSERM U1028 - Universite Claude Bernard Lyon 1 2. Unité de Neuroscience, Information et Complexité, CNRS UPR 3293, Gif-sur-Yvette, France @@ -74,6 +75,7 @@ and may not be the current affiliation of a contributor. 19. IAL Developmental Neurobiology, Kazan Federal University, Kazan, Russia 20. Harden Technologies, LLC 21. Institut des Neurosciences Paris-Saclay, CNRS UMR 9197 - Université Paris-Sud, Gif-sur-Yvette, France +22. Neurtex Brain Research Institute, Dallas, TX, USAs If we've somehow missed you off the list we're very sorry - please let us know. diff --git a/neo/rawio/neuralynxrawio.py b/neo/rawio/neuralynxrawio.py index 0df584cb7..818a4c270 100644 --- a/neo/rawio/neuralynxrawio.py +++ b/neo/rawio/neuralynxrawio.py @@ -108,7 +108,7 @@ def _parse_header(self): continue # All file have more or less the same header structure - info = NlxHeader.buildForFile(filename) + info = NlxHeader.build_for_file(filename) chan_names = info['channel_names'] chan_ids = info['channel_ids'] @@ -227,7 +227,7 @@ def _parse_header(self): self._timestamp_limits = None self._nb_segment = 1 - # Read ncs files for gaps detection and nb_segment computation. + # Read ncs files for gap detection and nb_segment computation. # :TODO: current algorithm depends on side-effect of read_ncs_files on # self._sigs_memmap, self._sigs_t_start, self._sigs_t_stop, # self._sigs_length, self._nb_segment, self._timestamp_limits @@ -661,6 +661,7 @@ def _to_bool(txt): ('ApplicationName', '', None), # also include version number when present ('AcquisitionSystem', '', None), ('ReferenceChannel', '', None), + ('NLX_Base_Class_Type', '', None) # in version 4 and earlier versions of Cheetah ] # Filename and datetime may appear in header lines starting with # at @@ -694,7 +695,7 @@ def _to_bool(txt): datetimeformat='%Y/%m/%d %H:%M:%S') } - def buildForFile(filename): + def build_for_file(filename): """ Factory function to build NlxHeader for a given file. """ @@ -809,6 +810,48 @@ def buildForFile(filename): return info + def type_of_recording(self): + """ + Determines type of recording in Ncs file with this header. + + RETURN: + one of 'PRE4','BML','DIGITALLYNX','DIGITALLYNXSX','UNKNOWN' + """ + + if 'NLX_Base_Class_Type' in self: + + # older style standard neuralynx acquisition with rounded sampling frequency + if self['NLX_Base_Class_Type'] == 'CscAcqEnt': + return 'PRE4' + + # BML style with fractional frequency and microsPerSamp + elif self['NLX_Base_Class_Type'] == 'BmlAcq': + return 'BML' + + else: + return 'UNKNOWN' + + elif 'HardwareSubSystemType' in self: + + # DigitalLynx + if self['HardwareSubSystemType'] == 'DigitalLynx': + return 'DIGITALLYNX' + + # DigitalLynxSX + elif self['HardwareSubSystemType'] == 'DigitalLynxSX': + return 'DIGITALLYNXSX' + + elif 'FileType' in self: + + if self['FileVersion'] in ['3.3', '3.4']: + return self['AcquisitionSystem'].split()[1].upper() + + else: + return 'UNKNOWN' + + else: + return 'UNKNOWN' + class NcsHeader(): """ diff --git a/neo/test/iotest/test_neuralynxio.py b/neo/test/iotest/test_neuralynxio.py index 0cd078746..df9f0b986 100644 --- a/neo/test/iotest/test_neuralynxio.py +++ b/neo/test/iotest/test_neuralynxio.py @@ -22,12 +22,14 @@ class CommonNeuralynxIOTest(BaseTestIO, unittest.TestCase, ): ioclass = NeuralynxIO files_to_test = [ + # 'Cheetah_v4.0.2/original_data', 'Cheetah_v5.5.1/original_data', 'Cheetah_v5.6.3/original_data', 'Cheetah_v5.7.4/original_data', 'Pegasus_v2.1.1', 'Cheetah_v6.3.2/incomplete_blocks'] files_to_download = [ + 'Cheetah_v4.0.2/original_data/CSC14_trunc.Ncs', 'Cheetah_v5.5.1/original_data/CheetahLogFile.txt', 'Cheetah_v5.5.1/original_data/CheetahLostADRecords.txt', 'Cheetah_v5.5.1/original_data/Events.nev', diff --git a/neo/test/rawiotest/test_neuralynxrawio.py b/neo/test/rawiotest/test_neuralynxrawio.py index 1c5a1aa92..4e0bc40cb 100644 --- a/neo/test/rawiotest/test_neuralynxrawio.py +++ b/neo/test/rawiotest/test_neuralynxrawio.py @@ -2,6 +2,7 @@ from neo.rawio.neuralynxrawio import NeuralynxRawIO from neo.test.rawiotest.common_rawio_test import BaseTestRawIO +from neo.rawio.neuralynxrawio import NlxHeader import logging @@ -11,12 +12,13 @@ class TestNeuralynxRawIO(BaseTestRawIO, unittest.TestCase, ): rawioclass = NeuralynxRawIO entities_to_test = [ + # 'Cheetah_v4.0.2/original_data', 'Cheetah_v5.5.1/original_data', 'Cheetah_v5.6.3/original_data', 'Cheetah_v5.7.4/original_data', - 'Cheetah_v6.3.2/incomplete_blocks' - ] + 'Cheetah_v6.3.2/incomplete_blocks'] files_to_download = [ + 'Cheetah_v4.0.2/original_data/CSC14_trunc.Ncs', 'Cheetah_v5.5.1/original_data/CheetahLogFile.txt', 'Cheetah_v5.5.1/original_data/CheetahLostADRecords.txt', 'Cheetah_v5.5.1/original_data/Events.nev', @@ -61,5 +63,28 @@ class TestNeuralynxRawIO(BaseTestRawIO, unittest.TestCase, ): 'Cheetah_v6.3.2/incomplete_blocks/README.txt'] +class TestNcsRecordingType(TestNeuralynxRawIO, unittest.TestCase): + """ + Test of decoding of NlxHeader for type of recording. + """ + + ncsTypeTestFiles = [ + ('Cheetah_v4.0.2/original_data/CSC14_trunc.Ncs', 'PRE4'), + ('Cheetah_v5.5.1/original_data/STet3a.nse', 'DIGITALLYNXSX'), + ('Cheetah_v5.5.1/original_data/Tet3a.ncs', 'DIGITALLYNXSX'), + ('Cheetah_v5.6.3/original_data/CSC1.ncs', 'DIGITALLYNXSX'), + ('Cheetah_v5.6.3/original_data/TT1.ntt', 'DIGITALLYNXSX'), + ('Cheetah_v5.7.4/original_data/CSC1.ncs', 'DIGITALLYNXSX'), + ('Cheetah_v6.3.2/incomplete_blocks/CSC1_reduced.ncs', 'DIGITALLYNXSX')] + + def test_recording_types(self): + + for typeTest in self.ncsTypeTestFiles: + + filename = self.get_filename_path(typeTest[0]) + hdr = NlxHeader.build_for_file(filename) + self.assertEqual(hdr.type_of_recording(), typeTest[1]) + + if __name__ == "__main__": unittest.main()