Skip to content

Commit b75168f

Browse files
committed
improve readability
1 parent 4c6eef1 commit b75168f

File tree

2 files changed

+98
-63
lines changed

2 files changed

+98
-63
lines changed

wfdb/io/_signal.py

Lines changed: 83 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,7 @@ def smooth_frames(self, sigtype='physical'):
737737

738738
#------------------- Reading Signals -------------------#
739739

740-
def rd_segment(file_name, dirname, pb_dir, n_sig, fmt, sig_len, byte_offset,
740+
def rd_segment(file_name, dir_name, pb_dir, n_sig, fmt, sig_len, byte_offset,
741741
samps_per_frame, skew, sampfrom, sampto, channels,
742742
smooth_frames, ignore_skew):
743743
"""
@@ -809,7 +809,7 @@ def rd_segment(file_name, dirname, pb_dir, n_sig, fmt, sig_len, byte_offset,
809809

810810
# Read each wanted dat file and store signals
811811
for fn in w_file_name:
812-
signals[:, out_datchannel[fn]] = rddat(fn, dirname, pb_dir, w_fmt[fn], len(datchannel[fn]),
812+
signals[:, out_datchannel[fn]] = rddat(fn, dir_name, pb_dir, w_fmt[fn], len(datchannel[fn]),
813813
sig_len, w_byte_offset[fn], w_samps_per_frame[fn], w_skew[fn], sampfrom, sampto, smooth_frames)[:, r_w_channel[fn]]
814814

815815
# Return each sample in signals with multiple samples/frame, without smoothing.
@@ -819,7 +819,7 @@ def rd_segment(file_name, dirname, pb_dir, n_sig, fmt, sig_len, byte_offset,
819819

820820
for fn in w_file_name:
821821
# Get the list of all signals contained in the dat file
822-
datsignals = rddat(fn, dirname, pb_dir, w_fmt[fn], len(datchannel[fn]),
822+
datsignals = rddat(fn, dir_name, pb_dir, w_fmt[fn], len(datchannel[fn]),
823823
sig_len, w_byte_offset[fn], w_samps_per_frame[fn], w_skew[fn], sampfrom, sampto, smooth_frames)
824824

825825
# Copy over the wanted signals
@@ -829,35 +829,58 @@ def rd_segment(file_name, dirname, pb_dir, n_sig, fmt, sig_len, byte_offset,
829829
return signals
830830

831831

832-
def rddat(file_name, dirname, pb_dir, fmt, n_sig,
832+
def rddat(file_name, dir_name, pb_dir, fmt, n_sig,
833833
sig_len, byte_offset, samps_per_frame,
834834
skew, sampfrom, sampto, smooth_frames):
835835
"""
836-
Get samples from a WFDB dat file.
837-
'sampfrom', 'sampto', and smooth_frames are user desired
836+
Read samples from a WFDB dat file. Returns all channels
837+
838+
839+
Parameters
840+
----------
841+
file_name : str
842+
The name of the dat file.
843+
dir_name : str
844+
The full directory where the dat file is located, if the dat
845+
file is local.
846+
pb_dir : str
847+
The physiobank directory where the dat file is located, if the
848+
dat file is remote.
849+
fmt : str
850+
The format of the dat file
851+
n_sig : int
852+
The number of signals contained in the dat file
853+
sig_len : int
854+
The signal length (per channel) of the dat file
855+
byte_offset : list
856+
The byte offset of the dat file
857+
samps_per_frame : list
858+
The samples/frame for each signal of the dat file
859+
skew : list
860+
The skew for the signals of the dat file
861+
sampfrom : int
862+
The starting sample number to be read from the signals
863+
sampto : int
864+
The final sample number to be read from the signals
865+
smooth_frames : bool
866+
Whether to smooth channels with multiple samples/frame
867+
868+
Returns
869+
-------
870+
signal : numpy array
871+
The read signal
872+
873+
Notes
874+
-----
875+
`sampfrom`, `sampto`, and `smooth_frames` are user desired
838876
input fields. All other fields specify the file parameters.
839877
840-
Returns all channels
841-
842-
Input arguments:
843-
- file_name: The name of the dat file.
844-
- dirname: The full directory where the dat file is located, if the dat file is local.
845-
- pb_dir: The physiobank directory where the dat file is located, if the dat file is remote.
846-
- fmt: The format of the dat file
847-
- n_sig: The number of signals contained in the dat file
848-
- sig_len : The signal length (per channel) of the dat file
849-
- byte_offset: The byte offsets of the dat file
850-
- samps_per_frame: The samples/frame for the signals of the dat file
851-
- skew: The skew for the signals of the dat file
852-
- sampfrom: The starting sample number to be read from the signals
853-
- sampto: The final sample number to be read from the signals
854-
- smooth_frames: Whether to smooth channels with multiple samples/frame
855878
"""
856879

857880
# Total number of samples per frame
858881
tsamps_per_frame = sum(samps_per_frame)
859882
# The signal length to read (per channel)
860-
readlen = sampto - sampfrom
883+
read_len = sampto - sampfrom
861884

862885
# Calculate parameters used to read and process the dat file
863886
start_byte, n_read_samples, block_floor_samples, extra_flat_samples, nanreplace = calc_read_params(fmt, sig_len, byte_offset,
@@ -882,13 +905,13 @@ def rddat(file_name, dirname, pb_dir, fmt, n_sig,
882905
# Extra number of bytes to append onto the bytes read from the dat file.
883906
n_extra_bytes = total_process_bytes - total_read_bytes
884907

885-
sig_bytes = np.concatenate((getdatbytes(file_name, dirname, pb_dir, fmt, start_byte, n_read_samples),
908+
sig_bytes = np.concatenate((get_dat_bytes(file_name, dir_name, pb_dir, fmt, start_byte, n_read_samples),
886909
np.zeros(n_extra_bytes, dtype=np.dtype(DATA_LOAD_TYPES[fmt]))))
887910
else:
888-
sig_bytes = np.concatenate((getdatbytes(file_name, dirname, pb_dir, fmt, start_byte, n_read_samples),
911+
sig_bytes = np.concatenate((get_dat_bytes(file_name, dir_name, pb_dir, fmt, start_byte, n_read_samples),
889912
np.zeros(extra_flat_samples, dtype=np.dtype(DATA_LOAD_TYPES[fmt]))))
890913
else:
891-
sig_bytes = getdatbytes(file_name, dirname, pb_dir, fmt, start_byte, n_read_samples)
914+
sig_bytes = get_dat_bytes(file_name, dir_name, pb_dir, fmt, start_byte, n_read_samples)
892915

893916
# Continue to process the read values into proper samples
894917

@@ -912,7 +935,7 @@ def rddat(file_name, dirname, pb_dir, fmt, n_sig,
912935
# Reshape into multiple channels
913936
sig = sig_bytes.reshape(-1, n_sig)
914937
# Skew the signal
915-
sig = skewsig(sig, skew, n_sig, readlen, fmt, nanreplace)
938+
sig = skew_sig(sig, skew, n_sig, read_len, fmt, nanreplace)
916939

917940
# Extra frames present to be smoothed. Obtain averaged uniform numpy array
918941
elif smooth_frames:
@@ -931,7 +954,7 @@ def rddat(file_name, dirname, pb_dir, fmt, n_sig,
931954
startind = np.sum(samps_per_frame[:ch])
932955
sig[:,ch] = [np.average(sig_bytes[ind:ind+samps_per_frame[ch]]) for ind in range(startind,len(sig_bytes),tsamps_per_frame)]
933956
# Skew the signal
934-
sig = skewsig(sig, skew, n_sig, readlen, fmt, nanreplace)
957+
sig = skew_sig(sig, skew, n_sig, read_len, fmt, nanreplace)
935958

936959
# Extra frames present without wanting smoothing. Return all expanded samples.
937960
else:
@@ -943,10 +966,10 @@ def rddat(file_name, dirname, pb_dir, fmt, n_sig,
943966
ch_indices = np.concatenate([np.array(range(samps_per_frame[ch])) + sum([0]+samps_per_frame[:ch]) + tsamps_per_frame*framenum for framenum in range(int(len(sig_bytes)/tsamps_per_frame))])
944967
sig.append(sig_bytes[ch_indices])
945968
# Skew the signal
946-
sig = skewsig(sig, skew, n_sig, readlen, fmt, nanreplace, samps_per_frame)
969+
sig = skew_sig(sig, skew, n_sig, read_len, fmt, nanreplace, samps_per_frame)
947970

948971
# Integrity check of signal shape after reading
949-
checksigdims(sig, readlen, n_sig, samps_per_frame)
972+
checksigdims(sig, read_len, n_sig, samps_per_frame)
950973

951974
return sig
952975

@@ -974,10 +997,10 @@ def calc_read_params(fmt, sig_len, byte_offset, skew, tsamps_per_frame, sampfrom
974997
Examples
975998
--------
976999
sig_len=100, t = 4 (total samples/frame), skew = [0, 2, 4, 5]
977-
sampfrom=0, sampto=100 --> readlen = 100, n_sampread = 100*t, extralen = 5, nanreplace = [0, 2, 4, 5]
978-
sampfrom=50, sampto=100 --> readlen = 50, n_sampread = 50*t, extralen = 5, nanreplace = [0, 2, 4, 5]
979-
sampfrom=0, sampto=50 --> readlen = 50, n_sampread = 55*t, extralen = 0, nanreplace = [0, 0, 0, 0]
980-
sampfrom=95, sampto=99 --> readlen = 4, n_sampread = 5*t, extralen = 4, nanreplace = [0, 1, 3, 4]
1000+
sampfrom=0, sampto=100 --> read_len = 100, n_sampread = 100*t, extralen = 5, nanreplace = [0, 2, 4, 5]
1001+
sampfrom=50, sampto=100 --> read_len = 50, n_sampread = 50*t, extralen = 5, nanreplace = [0, 2, 4, 5]
1002+
sampfrom=0, sampto=50 --> read_len = 50, n_sampread = 55*t, extralen = 0, nanreplace = [0, 0, 0, 0]
1003+
sampfrom=95, sampto=99 --> read_len = 4, n_sampread = 5*t, extralen = 4, nanreplace = [0, 1, 3, 4]
9811004
"""
9821005

9831006
# First flat sample number to read (if all channels were flattened)
@@ -1021,18 +1044,24 @@ def calc_read_params(fmt, sig_len, byte_offset, skew, tsamps_per_frame, sampfrom
10211044

10221045
return (start_byte, n_read_samples, block_floor_samples, extra_flat_samples, nanreplace)
10231046

1047+
10241048
def requiredbytenum(mode, fmt, n_samp):
10251049
"""
1026-
Determine how many signal bytes are needed to read a file, or now many
1027-
should be written to a file, for special formats.
1028-
1029-
Input arguments:
1030-
- mode: 'read' or 'write'
1031-
- fmt: format
1032-
- n_samp: number of samples
1050+
Determine how many signal bytes are needed to read a file, or how
1051+
many should be written to a file, for special formats.
10331052
10341053
It would be nice if read and write were the same, but fmt 311 for
10351054
n_extra == 2 ruins it.
1055+
1056+
Parameters
1057+
----------
1058+
mode : str
1059+
'read' or 'write'
1060+
fmt:
1061+
The wfdb format
1062+
n_samp : int
1063+
The number of samples
1064+
10361065
"""
10371066

10381067
if fmt == '212':
@@ -1059,15 +1088,17 @@ def requiredbytenum(mode, fmt, n_samp):
10591088
return int(nbytes)
10601089

10611090

1062-
def getdatbytes(file_name, dirname, pb_dir, fmt, start_byte, n_samp):
1091+
def get_dat_bytes(file_name, dir_name, pb_dir, fmt, start_byte, n_samp):
10631092
"""
10641093
Read bytes from a dat file, either local or remote, into a numpy array.
10651094
Slightly misleading function name. Does not return bytes object.
10661095
Output argument dtype varies depending on fmt. Non-special fmts are
10671096
read in their final required format. Special format are read as uint8.
10681097
1069-
Input arguments:
1070-
- n_samp: The total number of samples to read. Does NOT need to create whole blocks
1098+
Parameters
1099+
----------
1100+
n_samp : int
1101+
The total number of samples to read. Does NOT need to create whole blocks
10711102
for special format. Any number of samples should be readable. But see below*.
10721103
- start_byte: The starting byte to read from. * See below.
10731104
@@ -1091,7 +1122,7 @@ def getdatbytes(file_name, dirname, pb_dir, fmt, start_byte, n_samp):
10911122

10921123
# Local dat file
10931124
if pb_dir is None:
1094-
fp = open(os.path.join(dirname, file_name), 'rb')
1125+
fp = open(os.path.join(dir_name, file_name), 'rb')
10951126
fp.seek(start_byte)
10961127

10971128
# Read file using corresponding dtype
@@ -1202,7 +1233,7 @@ def bytes_to_samples(sig_bytes, n_samp, fmt):
12021233
return sig
12031234

12041235

1205-
def skewsig(sig, skew, n_sig, readlen, fmt, nanreplace, samps_per_frame=None):
1236+
def skew_sig(sig, skew, n_sig, read_len, fmt, nanreplace, samps_per_frame=None):
12061237
"""
12071238
Skew the signal, insert nans and shave off end of array if needed.
12081239
@@ -1216,11 +1247,11 @@ def skewsig(sig, skew, n_sig, readlen, fmt, nanreplace, samps_per_frame=None):
12161247
# Shift the channel samples
12171248
for ch in range(n_sig):
12181249
if skew[ch]>0:
1219-
sig[ch][:readlen*samps_per_frame[ch]] = sig[ch][skew[ch]*samps_per_frame[ch]:]
1250+
sig[ch][:read_len*samps_per_frame[ch]] = sig[ch][skew[ch]*samps_per_frame[ch]:]
12201251

12211252
# Shave off the extra signal length at the end
12221253
for ch in range(n_sig):
1223-
sig[ch] = sig[ch][:readlen*samps_per_frame[ch]]
1254+
sig[ch] = sig[ch][:read_len*samps_per_frame[ch]]
12241255

12251256
# Insert nans where skewed signal overran dat file
12261257
for ch in range(n_sig):
@@ -1231,9 +1262,9 @@ def skewsig(sig, skew, n_sig, readlen, fmt, nanreplace, samps_per_frame=None):
12311262
# Shift the channel samples
12321263
for ch in range(n_sig):
12331264
if skew[ch]>0:
1234-
sig[:readlen, ch] = sig[skew[ch]:, ch]
1265+
sig[:read_len, ch] = sig[skew[ch]:, ch]
12351266
# Shave off the extra signal length at the end
1236-
sig = sig[:readlen, :]
1267+
sig = sig[:read_len, :]
12371268

12381269
# Insert nans where skewed signal overran dat file
12391270
for ch in range(n_sig):
@@ -1244,15 +1275,15 @@ def skewsig(sig, skew, n_sig, readlen, fmt, nanreplace, samps_per_frame=None):
12441275

12451276

12461277
# Integrity check of signal shape after reading
1247-
def checksigdims(sig, readlen, n_sig, samps_per_frame):
1278+
def checksigdims(sig, read_len, n_sig, samps_per_frame):
12481279
if isinstance(sig, np.ndarray):
1249-
if sig.shape != (readlen, n_sig):
1280+
if sig.shape != (read_len, n_sig):
12501281
raise ValueError('Samples were not loaded correctly')
12511282
else:
12521283
if len(sig) != n_sig:
12531284
raise ValueError('Samples were not loaded correctly')
12541285
for ch in range(n_sig):
1255-
if len(sig[ch]) != samps_per_frame[ch] * readlen:
1286+
if len(sig[ch]) != samps_per_frame[ch] * read_len:
12561287
raise ValueError('Samples were not loaded correctly')
12571288

12581289

wfdb/io/download.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,32 +48,36 @@ def stream_header(record_name, pb_dir):
4848
return (header_lines, comment_lines)
4949

5050

51-
# Read certain bytes from a dat file from physiobank
52-
def stream_dat(file_name, pb_dir, fmt, bytecount, startbyte, datatypes):
51+
def stream_dat(file_name, pb_dir, fmt, byte_count, start_byte, datatypes):
52+
"""
53+
Read certain bytes from a dat file from physiobank
54+
55+
"""
5356

5457
# Full url of dat file
5558
url = posixpath.join(db_index_url, pb_dir, file_name)
5659

5760
# Specify the byte range
58-
endbyte = startbyte + bytecount-1
59-
headers = {"Range": "bytes="+str(startbyte)+"-"+str(endbyte),
61+
end_byte = start_byte + byte_count - 1
62+
headers = {"Range":"bytes=" + str(start_byte)+"-"+str(end_byte),
6063
'Accept-Encoding': '*/*'}
6164

6265
# Get the content
63-
r = requests.get(url, headers=headers, stream=True)
66+
response = requests.get(url, headers=headers, stream=True)
6467

6568
# Raise HTTPError if invalid url
66-
r.raise_for_status()
67-
68-
sigbytes = r.content
69+
response.raise_for_status()
6970

7071
# Convert to numpy array
71-
sigbytes = np.fromstring(sigbytes, dtype = np.dtype(datatypes[fmt]))
72+
sig_bytes = np.fromstring(response.content, dtype=np.dtype(datatypes[fmt]))
73+
74+
return sig_bytes
7275

73-
return sigbytes
7476

75-
# Read an entire annotation file from physiobank
7677
def stream_annotation(file_name, pb_dir):
78+
"""
79+
Read an entire annotation file from physiobank
80+
"""
7781

7882
# Full url of annotation file
7983
url = posixpath.join(db_index_url, pb_dir, file_name)

0 commit comments

Comments
 (0)