From 60399fabdd1fc59c1851189fdfc2f12fd136efb4 Mon Sep 17 00:00:00 2001 From: Damian Persico Date: Wed, 13 Mar 2024 13:57:04 -0300 Subject: [PATCH 01/10] feat(xml_files): add pnsSet.xml parser --- mffpy/xml_files.py | 125 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/mffpy/xml_files.py b/mffpy/xml_files.py index 9cf7a06..ced5333 100644 --- a/mffpy/xml_files.py +++ b/mffpy/xml_files.py @@ -1266,6 +1266,131 @@ def get_serializable_content(self): return content +class PNSSet(XML): + """Parser for 'pnsSet.xml' file + + These files have the following structure: + ``` + + + Physio 16 set 60hz 1.0 + 400 + + + ECG + 0 + uV + 0 + 1 + 0 + ECG + 0.3000000119 + 70 + 60 + 1 + 1 + 7.5 + 0.3000000119 + 70 + 60 + 0.0000,0.0000,0.0000,1.0000 + false + + + EMG + 1 + uV + 0 + 2 + 0 + EMG + 10 + 100 + 60 + 1 + 1 + 7.5 + 10 + 100 + 60 + 0.0000,0.0000,0.0000,1.0000 + false + ... + ``` + """ + + _xmlns = r'{http://www.egi.com/pnsSet_mff}' + _xmlroottag = r'PNSSet' + _default_filename = 'pnsSet.xml' + + _type_converter = { + 'name': str, + 'number': int, + 'unit': str, + 'psgType': int, + 'mapping': int, + 'samplingRate': int, + 'sensorType': str, + 'highpass': np.float32, + 'lowpass': np.float32, + 'notch': int, + 'groupNumber': int, + 'gain': int, + 'defaultDisplayAmplitude': np.float32, + 'highpassDisplay': np.float32, + 'lowpassDisplay': np.float32, + 'notchDisplay': int, + 'color': list, + 'positiveUp': str, + } + + @cached_property + def sensors(self) -> Dict[int, Any]: + return dict([ + self._parse_sensor(sensor) + for sensor in self.find('sensors') + ]) + + def _parse_sensor(self, el) -> Tuple[int, Any]: + assert self.nsstrip(el.tag) == 'sensor', f""" + Unknown sensor with tag '{self.nsstrip(el.tag)}'""" + ans = {} + for e in el: + tag = self.nsstrip(e.tag) + ans[tag] = self._type_converter[tag](e.text) + return ans['number'], ans + + @cached_property + def name(self) -> str: + """return value of the name tag""" + return self.find('name').text + + @cached_property + def amp_series(self) -> str: + """return value of the ampSeries tag""" + return self.find('ampSeries').text + + def get_content(self) -> Dict[str, Any]: + """return properties of the sensor + set read from the .xml""" + return { + 'name': self.name, + 'ampSeries': self.amp_series, + 'sensors': self.sensors + } + + def get_serializable_content(self) -> Dict[str, Any]: + """return a serializable object containing the + properties of the dipole set read from the .xml""" + content = copy.deepcopy(self.get_content()) + content['sensors'] = { + key: value.tolist() + for key, value in content['sensors'].items() + } + return content + + class History(XML): """Parser for 'history.xml' files From d01865e1416903b053c547ec5fc18b864d78ab61 Mon Sep 17 00:00:00 2001 From: Damian Persico Date: Wed, 13 Mar 2024 14:21:59 -0300 Subject: [PATCH 02/10] test: add unit test for PNSSet parser --- mffpy/tests/test_xml_files.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/mffpy/tests/test_xml_files.py b/mffpy/tests/test_xml_files.py index d584b27..6581ce6 100644 --- a/mffpy/tests/test_xml_files.py +++ b/mffpy/tests/test_xml_files.py @@ -30,6 +30,7 @@ examples_path = join(dirname(__file__), '..', '..', 'examples') mff_path = join(examples_path, 'example_1.mff') +mffpath_3 = join(examples_path, 'example_3.mff') """ Here are several fixtures that parse example xml files @@ -109,6 +110,13 @@ def dipoleSet(): return XML.from_file(ans) +@pytest.fixture +def pnsSet(): + ans = join(mffpath_3, 'pnsSet.xml') + assert exists(ans), f"Not found: '{ans}'" + return XML.from_file(ans) + + @pytest.fixture def history(): ans = join(examples_path, 'example_2.mff', 'history.xml') @@ -516,6 +524,31 @@ def test_dipoleSet_w_different_order(dipoleSet): ], dtype=np.float32)) +def test_pnsSet(pnsSet): + """test parsing of `pnsSet.xml`""" + assert pnsSet.name == 'Physio 16 set 60hz 1.0' + assert pnsSet.amp_series == '400' + expected = { + 0: { + 'name': 'ECG', + 'number': 0, + 'unit': 'uV', + 'sensorType': 'ECG', + }, + 1: { + 'name': 'EMG', + 'number': 1, + 'unit': 'uV', + 'sensorType': 'EMG', + } + } + for key, val in pnsSet.sensors.items(): + assert val['name'] == expected[key]['name'] + assert val['number'] == expected[key]['number'] + assert val['unit'] == expected[key]['unit'] + assert val['sensorType'] == expected[key]['sensorType'] + + @pytest.mark.parametrize("idx,expected", [ ('name', 'Noise_30Seconds'), ('method', 'Segmentation'), From 234d462079b5d894478a7ce08c8cae2e879b0eb7 Mon Sep 17 00:00:00 2001 From: Damian Persico Date: Wed, 13 Mar 2024 15:30:07 -0300 Subject: [PATCH 03/10] chg(GHAs): update Ubuntu version to 20.04 --- .github/workflows/lint_and_test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint_and_test.yaml b/.github/workflows/lint_and_test.yaml index 1a244cb..d995d59 100644 --- a/.github/workflows/lint_and_test.yaml +++ b/.github/workflows/lint_and_test.yaml @@ -15,7 +15,7 @@ jobs: # Name the job name: Lint and Test # Set the type of machine to run on - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 steps: # Check out the latest commit from the current branch - name: Checkout Current Branch From 144d3b1740438216ca194ac7c1d74f3247e8de8a Mon Sep 17 00:00:00 2001 From: Damian Persico Date: Wed, 13 Mar 2024 15:37:37 -0300 Subject: [PATCH 04/10] chg(examples): update example_2.json file --- examples/example_2.json | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/example_2.json b/examples/example_2.json index e39318d..31738da 100644 --- a/examples/example_2.json +++ b/examples/example_2.json @@ -8112,6 +8112,7 @@ } }, "dipoleSet": {}, + "PNSSet": {}, "historyEntries": [ { "name": "Noise_30Seconds", From 236e2516fd300f9b6ac849ff35ed3bf55b7a3976 Mon Sep 17 00:00:00 2001 From: Damian Persico Date: Tue, 19 Mar 2024 15:24:49 -0300 Subject: [PATCH 05/10] test: update unit tests --- mffpy/tests/test_xml_files.py | 34 ++++++++++++++++++++++++++++++---- mffpy/xml_files.py | 2 +- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/mffpy/tests/test_xml_files.py b/mffpy/tests/test_xml_files.py index 6581ce6..0a3acd8 100644 --- a/mffpy/tests/test_xml_files.py +++ b/mffpy/tests/test_xml_files.py @@ -533,20 +533,46 @@ def test_pnsSet(pnsSet): 'name': 'ECG', 'number': 0, 'unit': 'uV', + 'psgType': 0, + 'mapping': 1, + 'samplingRate': 0, 'sensorType': 'ECG', + 'highpass': 0.3, + 'lowpass': 70, + 'notch': 60, + 'groupNumber': 1, + 'gain': 1, + 'defaultDisplayAmplitude': 7.5, + 'highpassDisplay': 0.3, + 'lowpassDisplay': 70, + 'notchDisplay': 60, + 'color': [0.0000, 0.0000, 0.0000, 1.0000], + 'positiveUp': 'false', }, 1: { 'name': 'EMG', 'number': 1, 'unit': 'uV', + 'psgType': 0, + 'mapping': 2, + 'samplingRate': 0, 'sensorType': 'EMG', + 'highpass': 10, + 'lowpass': 100, + 'notch': 60, + 'groupNumber': 1, + 'gain': 1, + 'defaultDisplayAmplitude': 7.5, + 'highpassDisplay': 10, + 'lowpassDisplay': 100, + 'notchDisplay': 60, + 'color': [0.0000, 0.0000, 0.0000, 1.0000], + 'positiveUp': 'false', } } for key, val in pnsSet.sensors.items(): - assert val['name'] == expected[key]['name'] - assert val['number'] == expected[key]['number'] - assert val['unit'] == expected[key]['unit'] - assert val['sensorType'] == expected[key]['sensorType'] + for k, v in val.items(): + assert v == pytest.approx(expected[key][k]) @pytest.mark.parametrize("idx,expected", [ diff --git a/mffpy/xml_files.py b/mffpy/xml_files.py index ced5333..1c8d4ba 100644 --- a/mffpy/xml_files.py +++ b/mffpy/xml_files.py @@ -1341,7 +1341,7 @@ class PNSSet(XML): 'highpassDisplay': np.float32, 'lowpassDisplay': np.float32, 'notchDisplay': int, - 'color': list, + 'color': lambda s: list(map(float, s.split(","))), 'positiveUp': str, } From 53b3d3d6dd2064bdb4928107b326c8ca15aedc98 Mon Sep 17 00:00:00 2001 From: Damian Persico Date: Thu, 21 Mar 2024 18:39:05 -0300 Subject: [PATCH 06/10] feat(xml_files): add ability to write pnsSet.xml files --- mffpy/xml_files.py | 88 +++++++++++++++++++++++++++++++++------------- 1 file changed, 64 insertions(+), 24 deletions(-) diff --git a/mffpy/xml_files.py b/mffpy/xml_files.py index 1c8d4ba..bb2a06d 100644 --- a/mffpy/xml_files.py +++ b/mffpy/xml_files.py @@ -1323,28 +1323,52 @@ class PNSSet(XML): _xmlns = r'{http://www.egi.com/pnsSet_mff}' _xmlroottag = r'PNSSet' _default_filename = 'pnsSet.xml' - - _type_converter = { + _sensor_type_reverter = { 'name': str, - 'number': int, + 'number': str, 'unit': str, - 'psgType': int, - 'mapping': int, - 'samplingRate': int, + 'psgType': str, + 'mapping': str, + 'samplingRate': str, 'sensorType': str, - 'highpass': np.float32, - 'lowpass': np.float32, - 'notch': int, - 'groupNumber': int, - 'gain': int, - 'defaultDisplayAmplitude': np.float32, - 'highpassDisplay': np.float32, - 'lowpassDisplay': np.float32, - 'notchDisplay': int, - 'color': lambda s: list(map(float, s.split(","))), - 'positiveUp': str, + 'highpass': str, + 'lowpass': str, + 'notch': str, + 'groupNumber': str, + 'gain': str, + 'defaultDisplayAmplitude': str, + 'highpassDisplay': str, + 'lowpassDisplay': str, + 'notchDisplay': str, + 'color': lambda color: ','.join( + ["{:.4f}".format(c) for c in color] + ), + 'positiveUp': str } + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._sensor_type_converter = { + 'name': str, + 'number': int, + 'unit': str, + 'psgType': int, + 'mapping': int, + 'samplingRate': int, + 'sensorType': str, + 'highpass': np.float32, + 'lowpass': np.float32, + 'notch': int, + 'groupNumber': int, + 'gain': int, + 'defaultDisplayAmplitude': np.float32, + 'highpassDisplay': np.float32, + 'lowpassDisplay': np.float32, + 'notchDisplay': int, + 'color': lambda s: list(map(float, s.split(","))), + 'positiveUp': str, + } + @cached_property def sensors(self) -> Dict[int, Any]: return dict([ @@ -1358,7 +1382,7 @@ def _parse_sensor(self, el) -> Tuple[int, Any]: ans = {} for e in el: tag = self.nsstrip(e.tag) - ans[tag] = self._type_converter[tag](e.text) + ans[tag] = self._sensor_type_converter[tag](e.text) return ans['number'], ans @cached_property @@ -1382,13 +1406,29 @@ def get_content(self) -> Dict[str, Any]: def get_serializable_content(self) -> Dict[str, Any]: """return a serializable object containing the - properties of the dipole set read from the .xml""" - content = copy.deepcopy(self.get_content()) - content['sensors'] = { - key: value.tolist() - for key, value in content['sensors'].items() + properties of the sensor set read from the .xml""" + return copy.deepcopy(self.get_content()) + + @classmethod + def content(cls, name: str, amp_series: str, + sensors: Dict[int, Any]) -> Dict[str, Any]: + """return content in xml-convertible json format""" + formatted_sensors = [] + for sensor in sensors.values(): + formatted = {} + for k, v in sensor.items(): + assert k in cls._sensor_type_reverter, "sensor property " + f"'{k}' not serializable. Needs to be on of " + "{list(cls._sensor_type_reverter.keys())}" + formatted[k] = { + TEXT: cls._sensor_type_reverter[k](v) # type: ignore + } + formatted_sensors.append({TEXT: formatted}) + return { + 'name': {TEXT: name}, + 'ampSeries': {TEXT: amp_series}, + 'sensors': {TEXT: {'sensor': formatted_sensors}}, } - return content class History(XML): From 3875ed349e202611b3b3179a0638d74dd68f228a Mon Sep 17 00:00:00 2001 From: Damian Persico Date: Thu, 21 Mar 2024 19:32:16 -0300 Subject: [PATCH 07/10] test: add unit test --- mffpy/tests/conftest.py | 47 ++++++++++++++++++++++++++++++ mffpy/tests/test_writer.py | 18 ++++++++++-- mffpy/tests/test_xml_files.py | 54 ++++------------------------------- 3 files changed, 69 insertions(+), 50 deletions(-) diff --git a/mffpy/tests/conftest.py b/mffpy/tests/conftest.py index cc72371..a65532f 100644 --- a/mffpy/tests/conftest.py +++ b/mffpy/tests/conftest.py @@ -13,6 +13,7 @@ ANY KIND, either express or implied. """ +from typing import Any, Dict from glob import glob import os.path as op from zipfile import ZipFile, ZIP_STORED @@ -30,3 +31,49 @@ def ensure_mfz(): for content_filename in glob(op.join(fname[:-3] + 'mff', '*')): arc_filename = op.basename(content_filename) zf.write(content_filename, arcname=arc_filename) + + +@pytest.fixture +def sensors() -> Dict[int, Any]: + return { + 0: { + 'name': 'ECG', + 'number': 0, + 'unit': 'uV', + 'psgType': 0, + 'mapping': 1, + 'samplingRate': 0, + 'sensorType': 'ECG', + 'highpass': 0.3, + 'lowpass': 70, + 'notch': 60, + 'groupNumber': 1, + 'gain': 1, + 'defaultDisplayAmplitude': 7.5, + 'highpassDisplay': 0.3, + 'lowpassDisplay': 70, + 'notchDisplay': 60, + 'color': [0.0000, 0.0000, 0.0000, 1.0000], + 'positiveUp': 'false', + }, + 1: { + 'name': 'EMG', + 'number': 1, + 'unit': 'uV', + 'psgType': 0, + 'mapping': 2, + 'samplingRate': 0, + 'sensorType': 'EMG', + 'highpass': 10, + 'lowpass': 100, + 'notch': 60, + 'groupNumber': 1, + 'gain': 1, + 'defaultDisplayAmplitude': 7.5, + 'highpassDisplay': 10, + 'lowpassDisplay': 100, + 'notchDisplay': 60, + 'color': [0.0000, 0.0000, 0.0000, 1.0000], + 'positiveUp': 'false', + } + } diff --git a/mffpy/tests/test_writer.py b/mffpy/tests/test_writer.py index 7a4c06b..303c6e5 100644 --- a/mffpy/tests/test_writer.py +++ b/mffpy/tests/test_writer.py @@ -165,7 +165,7 @@ def test_overwrite_mfz(tmpdir): assert R2.startdatetime == time2 -def test_writer_writes_multple_bins(tmpdir): +def test_writer_writes_multple_bins(tmpdir, sensors): """test that `mffpy.Writer` can write multiple binary files""" dirname = join(str(tmpdir), 'multiple_bins.mff') device = 'HydroCel GSN 256 1.0' @@ -174,7 +174,7 @@ def test_writer_writes_multple_bins(tmpdir): sampling_rate = 128 num_channels_dict = { 'EEG': 256, - 'PNSData': 16 + 'PNSData': 2 } data = { dtype: np.random.randn( @@ -192,6 +192,12 @@ def test_writer_writes_multple_bins(tmpdir): startdatetime = datetime.strptime( '1984-02-18T14:00:10.000000+0100', XML._time_format) W.addxml('fileInfo', recordTime=startdatetime) + W.addxml( + 'PNSSet', + name='Physio 16 set 60hz 1.0', + amp_series='400', + sensors=sensors, + ) W.add_coordinates_and_sensor_layout(device) for b in bin_writers.values(): W.addbin(b) @@ -212,6 +218,14 @@ def test_writer_writes_multple_bins(tmpdir): layout = XML.from_file(layout) assert layout.name == device + pns_set = R.directory.filepointer('pnsSet') + pns_set = XML.from_file(pns_set) + assert pns_set.name == 'Physio 16 set 60hz 1.0' + assert pns_set.amp_series == '400' + for key, val in pns_set.sensors.items(): + for k, v in val.items(): + assert v == pytest.approx(sensors[key][k]) + def test_write_multiple_blocks(): """check that BinWriter correctly handles adding multiple blocks""" diff --git a/mffpy/tests/test_xml_files.py b/mffpy/tests/test_xml_files.py index 0a3acd8..1c4c7fc 100644 --- a/mffpy/tests/test_xml_files.py +++ b/mffpy/tests/test_xml_files.py @@ -111,7 +111,7 @@ def dipoleSet(): @pytest.fixture -def pnsSet(): +def pns_set(): ans = join(mffpath_3, 'pnsSet.xml') assert exists(ans), f"Not found: '{ans}'" return XML.from_file(ans) @@ -524,55 +524,13 @@ def test_dipoleSet_w_different_order(dipoleSet): ], dtype=np.float32)) -def test_pnsSet(pnsSet): +def test_pnsSet(pns_set, sensors): """test parsing of `pnsSet.xml`""" - assert pnsSet.name == 'Physio 16 set 60hz 1.0' - assert pnsSet.amp_series == '400' - expected = { - 0: { - 'name': 'ECG', - 'number': 0, - 'unit': 'uV', - 'psgType': 0, - 'mapping': 1, - 'samplingRate': 0, - 'sensorType': 'ECG', - 'highpass': 0.3, - 'lowpass': 70, - 'notch': 60, - 'groupNumber': 1, - 'gain': 1, - 'defaultDisplayAmplitude': 7.5, - 'highpassDisplay': 0.3, - 'lowpassDisplay': 70, - 'notchDisplay': 60, - 'color': [0.0000, 0.0000, 0.0000, 1.0000], - 'positiveUp': 'false', - }, - 1: { - 'name': 'EMG', - 'number': 1, - 'unit': 'uV', - 'psgType': 0, - 'mapping': 2, - 'samplingRate': 0, - 'sensorType': 'EMG', - 'highpass': 10, - 'lowpass': 100, - 'notch': 60, - 'groupNumber': 1, - 'gain': 1, - 'defaultDisplayAmplitude': 7.5, - 'highpassDisplay': 10, - 'lowpassDisplay': 100, - 'notchDisplay': 60, - 'color': [0.0000, 0.0000, 0.0000, 1.0000], - 'positiveUp': 'false', - } - } - for key, val in pnsSet.sensors.items(): + assert pns_set.name == 'Physio 16 set 60hz 1.0' + assert pns_set.amp_series == '400' + for key, val in pns_set.sensors.items(): for k, v in val.items(): - assert v == pytest.approx(expected[key][k]) + assert v == pytest.approx(sensors[key][k]) @pytest.mark.parametrize("idx,expected", [ From a5f17309548144a108252400c10e4df1f1e88abc Mon Sep 17 00:00:00 2001 From: Damian Persico Date: Thu, 21 Mar 2024 19:39:36 -0300 Subject: [PATCH 08/10] test: update unit tests --- mffpy/tests/test_xml_files.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/mffpy/tests/test_xml_files.py b/mffpy/tests/test_xml_files.py index 1c4c7fc..9bb74a5 100644 --- a/mffpy/tests/test_xml_files.py +++ b/mffpy/tests/test_xml_files.py @@ -110,13 +110,6 @@ def dipoleSet(): return XML.from_file(ans) -@pytest.fixture -def pns_set(): - ans = join(mffpath_3, 'pnsSet.xml') - assert exists(ans), f"Not found: '{ans}'" - return XML.from_file(ans) - - @pytest.fixture def history(): ans = join(examples_path, 'example_2.mff', 'history.xml') @@ -524,8 +517,11 @@ def test_dipoleSet_w_different_order(dipoleSet): ], dtype=np.float32)) -def test_pnsSet(pns_set, sensors): +def test_pnsSet(sensors): """test parsing of `pnsSet.xml`""" + filepath = join(mffpath_3, 'pnsSet.xml') + assert exists(filepath), f"Not found: '{filepath}'" + pns_set = XML.from_file(filepath) assert pns_set.name == 'Physio 16 set 60hz 1.0' assert pns_set.amp_series == '400' for key, val in pns_set.sensors.items(): From 1a9e4035fd8f35266800f2e547fbf0e859fc0801 Mon Sep 17 00:00:00 2001 From: Damian Persico Date: Thu, 21 Mar 2024 19:46:24 -0300 Subject: [PATCH 09/10] style: fix type annotation issue --- mffpy/xml_files.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mffpy/xml_files.py b/mffpy/xml_files.py index bb2a06d..b37aacd 100644 --- a/mffpy/xml_files.py +++ b/mffpy/xml_files.py @@ -1410,7 +1410,7 @@ def get_serializable_content(self) -> Dict[str, Any]: return copy.deepcopy(self.get_content()) @classmethod - def content(cls, name: str, amp_series: str, + def content(cls, name: str, amp_series: str, # type: ignore sensors: Dict[int, Any]) -> Dict[str, Any]: """return content in xml-convertible json format""" formatted_sensors = [] From 38282c32e14fe6ca323832961f9c7f093f2ebbb6 Mon Sep 17 00:00:00 2001 From: Damian Persico Date: Fri, 22 Mar 2024 15:04:13 -0300 Subject: [PATCH 10/10] test: update unit tests --- mffpy/tests/conftest.py | 4 ++-- mffpy/tests/test_writer.py | 2 +- mffpy/tests/test_xml_files.py | 2 +- mffpy/xml_files.py | 10 +++++----- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mffpy/tests/conftest.py b/mffpy/tests/conftest.py index a65532f..4a2705b 100644 --- a/mffpy/tests/conftest.py +++ b/mffpy/tests/conftest.py @@ -44,13 +44,13 @@ def sensors() -> Dict[int, Any]: 'mapping': 1, 'samplingRate': 0, 'sensorType': 'ECG', - 'highpass': 0.3, + 'highpass': 0.3000000119, 'lowpass': 70, 'notch': 60, 'groupNumber': 1, 'gain': 1, 'defaultDisplayAmplitude': 7.5, - 'highpassDisplay': 0.3, + 'highpassDisplay': 0.3000000119, 'lowpassDisplay': 70, 'notchDisplay': 60, 'color': [0.0000, 0.0000, 0.0000, 1.0000], diff --git a/mffpy/tests/test_writer.py b/mffpy/tests/test_writer.py index 303c6e5..781cc6a 100644 --- a/mffpy/tests/test_writer.py +++ b/mffpy/tests/test_writer.py @@ -224,7 +224,7 @@ def test_writer_writes_multple_bins(tmpdir, sensors): assert pns_set.amp_series == '400' for key, val in pns_set.sensors.items(): for k, v in val.items(): - assert v == pytest.approx(sensors[key][k]) + assert v == sensors[key][k] def test_write_multiple_blocks(): diff --git a/mffpy/tests/test_xml_files.py b/mffpy/tests/test_xml_files.py index 9bb74a5..5c4aef1 100644 --- a/mffpy/tests/test_xml_files.py +++ b/mffpy/tests/test_xml_files.py @@ -526,7 +526,7 @@ def test_pnsSet(sensors): assert pns_set.amp_series == '400' for key, val in pns_set.sensors.items(): for k, v in val.items(): - assert v == pytest.approx(sensors[key][k]) + assert v == sensors[key][k] @pytest.mark.parametrize("idx,expected", [ diff --git a/mffpy/xml_files.py b/mffpy/xml_files.py index b37aacd..8691064 100644 --- a/mffpy/xml_files.py +++ b/mffpy/xml_files.py @@ -1356,14 +1356,14 @@ def __init__(self, *args, **kwargs): 'mapping': int, 'samplingRate': int, 'sensorType': str, - 'highpass': np.float32, - 'lowpass': np.float32, + 'highpass': float, + 'lowpass': float, 'notch': int, 'groupNumber': int, 'gain': int, - 'defaultDisplayAmplitude': np.float32, - 'highpassDisplay': np.float32, - 'lowpassDisplay': np.float32, + 'defaultDisplayAmplitude': float, + 'highpassDisplay': float, + 'lowpassDisplay': float, 'notchDisplay': int, 'color': lambda s: list(map(float, s.split(","))), 'positiveUp': str,