Skip to content

Commit e180259

Browse files
committed
add alternative to numpy fromfile for fsspec
1 parent de65d8b commit e180259

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

wfdb/io/_signal.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1688,14 +1688,15 @@ def _rd_dat_file(file_name, dir_name, pn_dir, fmt, start_byte, n_samp):
16881688
element_count = n_samp
16891689
byte_count = n_samp * BYTES_PER_SAMPLE[fmt]
16901690

1691-
# Local dat file
1691+
# Local or cloud dat file
16921692
if pn_dir is None:
16931693
with fsspec.open(os.path.join(dir_name, file_name), "rb") as fp:
16941694
fp.seek(start_byte)
1695-
sig_data = np.fromfile(
1695+
sig_data = util.fromfile(
16961696
fp, dtype=np.dtype(DATA_LOAD_TYPES[fmt]), count=element_count
16971697
)
1698-
# Stream dat file from Physionet
1698+
1699+
# Stream dat file from PhysioNet
16991700
else:
17001701
dtype_in = np.dtype(DATA_LOAD_TYPES[fmt])
17011702
sig_data = download._stream_dat(

wfdb/io/util.py

+27
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
A module for general utility functions
33
"""
44

5+
import io
56
import math
67
import os
78

9+
import numpy as np
10+
811
from typing import List, Sequence, Tuple
912

1013

@@ -121,3 +124,27 @@ def overlapping_ranges(
121124
for second in ranges_2
122125
if max(first[0], second[0]) < min(first[1], second[1])
123126
]
127+
128+
129+
def fromfile(fileobj, dtype, count=-1):
130+
"""
131+
Detect if the object will work with numpy.fromfile - if so, use it. If not, read the object into a numpy array and
132+
calculate the number of elements (if not provided) - this is needed for fsspec objects.
133+
"""
134+
if isinstance(fileobj, io.FileIO) or (
135+
isinstance(fileobj, (io.BufferedReader, io.BufferedRandom))
136+
and isinstance(fileobj.raw, io.FileIO)
137+
):
138+
return np.fromfile(fileobj, dtype=dtype, count=count)
139+
else:
140+
dtype = np.dtype(dtype)
141+
if count < 0:
142+
start = fileobj.tell()
143+
fileobj.seek(0, os.SEEK_END)
144+
end = fileobj.tell()
145+
fileobj.seek(start, os.SEEK_SET)
146+
count = (end - start) // dtype.itemsize
147+
array = np.empty(count, dtype)
148+
size = fileobj.readinto(array)
149+
array.resize(size // dtype.itemsize)
150+
return array

0 commit comments

Comments
 (0)