Skip to content

Commit b308ca1

Browse files
committed
remap adc range if baseline exceeds limits
1 parent bf49bec commit b308ca1

File tree

1 file changed

+26
-13
lines changed

1 file changed

+26
-13
lines changed

wfdb/io/_signal.py

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
from . import download
66
import pdb
7+
8+
MAX_I32 = 2147483647
9+
MIN_I32 = -2147483648
710
# WFDB dat formats - https://www.physionet.org/physiotools/wag/signal-5.htm
811
SIMPLE_FMTS = ['80', '16', '24', '32']
912
SPECIAL_FMTS = ['212', '310', '311']
@@ -548,10 +551,13 @@ def calc_adc_params(self):
548551
# Regular varied signal case.
549552
else:
550553
# The equation is: p = (d - b) / g
554+
551555
# Approximately, pmax maps to dmax, and pmin maps to
552556
# dmin. Gradient will be equal to, or close to
553557
# delta(d) / delta(p), since intercept baseline has
554558
# to be an integer.
559+
560+
# Constraint: baseline must be between +/- 2**31
555561
adc_gain = (dmax-dmin) / (pmax-pmin)
556562
baseline = dmin - adc_gain*pmin
557563
# Make adjustments for baseline to be an integer
@@ -571,9 +577,18 @@ def calc_adc_params(self):
571577
if dmin != baseline:
572578
adc_gain = (dmin - baseline) / pmin
573579

574-
# Safety check for WFDB library limit.
575-
if abs(baseline)>2147483648:
576-
raise Exception('baseline must have magnitude < 2147483648')
580+
# Remap signal if baseline exceeds boundaries.
581+
# This may happen if pmax < 0
582+
if baseline > MAX_I32:
583+
# pmin maps to dmin, baseline maps to 2**31 - 1
584+
# pmax will map to a lower value than before
585+
adc_gain = (MAX_I32) - dmin / abs(pmin)
586+
baseline = MAX_I32
587+
# This may happen if pmin > 0
588+
elif baseline < MIN_I32:
589+
# pmax maps to dmax, baseline maps to -2**31 + 1
590+
adc_gain = (dmax - MIN_I32) / pmax
591+
baseline = MIN_I32
577592

578593
adc_gains.append(adc_gain)
579594
baselines.append(baseline)
@@ -1232,13 +1247,16 @@ def checksigdims(sig, readlen, n_sig, samps_per_frame):
12321247
#------------------- /Reading Signals -------------------#
12331248

12341249

1235-
# Return min and max digital values for each format type. Accepts lists.
1250+
12361251
def digi_bounds(fmt):
1252+
"""
1253+
Return min and max digital values for each format type.
1254+
Accepts lists.
1255+
1256+
"""
12371257
if isinstance(fmt, list):
12381258
digibounds = []
1239-
for f in fmt:
1240-
digibounds.append(digi_bounds(f))
1241-
return digibounds
1259+
return [digi_bounds(f) for f in fmt]
12421260

12431261
if fmt == '80':
12441262
return (-128, 127)
@@ -1254,10 +1272,7 @@ def digi_bounds(fmt):
12541272
# Return nan value for the format type(s).
12551273
def digi_nan(fmt):
12561274
if isinstance(fmt, list):
1257-
diginans = []
1258-
for f in fmt:
1259-
diginans.append(digi_nan(f))
1260-
return diginans
1275+
return [digi_nan(f) for f in fmt]
12611276

12621277
if fmt == '80':
12631278
return -128
@@ -1333,7 +1348,6 @@ def est_res(signals):
13331348
return res
13341349

13351350

1336-
13371351
def wfdbfmt(res, single_fmt=True):
13381352
"""
13391353
Return the most suitable wfdb format(s) to use given signal
@@ -1396,7 +1410,6 @@ def fmt_res(fmt, max_res=False):
13961410
raise ValueError('Invalid WFDB format.')
13971411

13981412

1399-
14001413
def np_dtype(res, discrete):
14011414
"""
14021415
Given the resolution of a signal, return the minimum

0 commit comments

Comments
 (0)