44
55from . import download
66import pdb
7+
8+ MAX_I32 = 2147483647
9+ MIN_I32 = - 2147483648
710# WFDB dat formats - https://www.physionet.org/physiotools/wag/signal-5.htm
811SIMPLE_FMTS = ['80' , '16' , '24' , '32' ]
912SPECIAL_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+
12361251def 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).
12551273def 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-
13371351def 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-
14001413def np_dtype (res , discrete ):
14011414 """
14021415 Given the resolution of a signal, return the minimum
0 commit comments