Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Converted assert of phys_min and phys_max into warnings #266

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions pyedflib/highlevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,13 +530,23 @@ def write_edf(
'for channel {}'.format(dmax, sig.max(), label)
assert pmin != pmax, \
f'physical_min {pmin} should be different from physical_max {pmax}'
else: # only warning, as this will not lead to clipping
assert pmin<=sig.min(), \
'phys_min is {}, but signal_min is {} ' \
'for channel {}'.format(pmin, sig.min(), label)
assert pmax>=sig.max(), \
'phys_max is {}, but signal_max is {} ' \
'for channel {}'.format(pmax, sig.max(), label)
else: # only warning if difference is larger than the rounding error (which is quite large as edf scales data between phys_min and phys_max using -dig_min and +dig_max)
edf_accuracy = min([sig.max()/dmax, sig.min()/dmin])
if abs(pmin - sig.min()) < edf_accuracy:
warnings.warn(f'phys_min is {pmin}, but signal_min is {sig.min()} ' \
'for channel {label}', category=UserWarning)
else: # difference is > edf_accuracy
assert pmin<=sig.min(), \
'phys_min is {}, but signal_min is {} ' \
'for channel {}'.format(pmin, sig.min(), label)
if abs(sig.max() - pmax) < edf_accuracy:
warnings.warn(f'phys_max is {pmax}, but signal_max is {sig.max()} ' \
'for channel {label}', category=UserWarning)
else:
assert pmax>=sig.max(), \
'phys_max is {}, but signal_max is {} ' \
'for channel {}'.format(pmax, sig.max(), label)


# get annotations, in format [[timepoint, duration, description], [...]]
annotations = header.get('annotations', [])
Expand Down
22 changes: 19 additions & 3 deletions pyedflib/tests/test_highlevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,20 +222,36 @@ def test_read_write_diff_sfreq(self):
def test_assertion_dmindmax(self):

# test digital and dmin wrong
signals =[np.random.randint(-2048, 2048, 256*60).astype(np.int32)]
signals =[np.random.randint(-2048, 2048, 256*60).astype(np.int16)]
sheaders = [highlevel.make_signal_header('ch1', sample_frequency=256)]
sheaders[0]['digital_min'] = -128
sheaders[0]['digital_max'] = 128
with self.assertRaises(AssertionError):
highlevel.write_edf(self.edfplus_data_file, signals, sheaders, digital=True)

# test pmin wrong
signals = [np.random.randint(-2048, 2048, 256*60)]
# test physical min and max wrong
signals = [np.random.randint(-2048, 2048, 256*60).astype(np.int16)]
sheaders = [highlevel.make_signal_header('ch1', sample_frequency=256)]
sheaders[0]['physical_min'] = -200
sheaders[0]['physical_max'] = 200

# a large difference between phys min and values should result in error
with self.assertRaises(AssertionError):
highlevel.write_edf(self.edfplus_data_file, signals, sheaders, digital=False)

# A small roundoff difference between phys min and values should result in warning
# edf_accuracy is calculated as: max_signals / digital_max or min_signals / digital_min
# (whichever is smallest). digital_max = 2^16 / 2
edf_accuracy = min([max(signals[0])/sheaders[0]['digital_max'], min(signals[0])/sheaders[0]['digital_min']]).astype(np.float16)

sheaders[0]['physical_min'] = min(signals[0]) + 0.999 * edf_accuracy
sheaders[0]['physical_max'] = max(signals[0]) - 0.999 * edf_accuracy

with self.assertWarnsRegex(expected_warning=UserWarning, expected_regex="phys_min is.*"):
highlevel.write_edf(self.edfplus_data_file, signals, sheaders, digital=False)

# It would be nice to doublecheck the written data in the files here.
# However, the (rather inaccurate) data rescaling of EDF files makes this tricky.


def test_read_write_accented(self):
Expand Down
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import os
import subprocess
import sys
from distutils.sysconfig import get_python_inc
import sysconfig
from functools import partial

import setuptools
Expand Down Expand Up @@ -219,7 +219,7 @@ def write_version_py(filename='pyedflib/version.py'):
# C files must be built once only for coverage to work
c_lib = ('c_edf',{'sources': sources,
'depends': headers,
'include_dirs': [make_ext_path("c"), get_python_inc()],
'include_dirs': [make_ext_path("c"), sysconfig.get_path('include')],
'macros': c_macros,})

ext_modules = [
Expand Down Expand Up @@ -270,7 +270,7 @@ def install_for_development(self):
setuptools.bootstrap_install_from = None

# create an .egg-link in the installation dir, pointing to our egg
from distutils import log
from setuptools import log
log.info("Creating %s (link to %s)", self.egg_link, self.egg_base)
if not self.dry_run:
with open(self.egg_link, "w") as f:
Expand Down