bed-reader 1.0.2__tar.gz → 1.0.3b1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/CHANGELOG.md +7 -1
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/Cargo.lock +1 -1
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/Cargo.toml +1 -1
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/PKG-INFO +2 -2
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/__init__.py +2 -1
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/_open_bed.py +106 -30
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/_sample_data.py +1 -1
- bed_reader-1.0.3b1/bed_reader/_to_bed.py +592 -0
- bed_reader-1.0.3b1/bed_reader/tests/benchmark/bench2.ipynb +251 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/benchmark/benchmark.py +29 -11
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/test_open_bed.py +538 -16
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/pyproject.toml +1 -1
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/requirements-dev.txt +1 -1
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/src/lib.rs +227 -21
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/src/python_module.rs +62 -1
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/src/tests.rs +20 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/useful.md +18 -0
- bed_reader-1.0.2/bed_reader/_to_bed.py +0 -235
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/.flake8 +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/.github/workflows/ci.yml +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/.gitignore +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/.isort.cfg +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/AUTHORS.txt +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/LICENSE.md +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/README-rust.md +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/README.md +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/_sphinx_javascript_frameworks_compat.js +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/basic.css +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/doctools.js +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/documentation_options.js +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/file.png +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/jquery-3.4.1.js +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/jquery-3.5.1.js +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/jquery-3.6.0.js +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/jquery.js +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/js/badge_only.js +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/js/html5shiv-printshiv.min.js +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/js/html5shiv.min.js +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/js/modernizr.min.js +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/js/theme.js +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/language_data.js +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/minus.png +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/plus.png +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/pygments.css +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/searchtools.js +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/sphinx_highlight.js +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/underscore-1.12.0.js +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/underscore-1.13.1.js +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/underscore-1.3.1.js +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/_static/underscore.js +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/__init__.py +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/500x400_o640_array.memmap +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/badfile.bed +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/empty.bed +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/plink_sim_10s_100v_10pmiss.bed +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/plink_sim_10s_100v_10pmiss.bim +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/plink_sim_10s_100v_10pmiss.fam +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/small.bad_bim +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/small.bed +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/small.bim +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/small.bim_bad_positions.bim +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/small.deb +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/small.fam +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/small.fam_bad +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/small.maf +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/small.mib +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/small2_array.memmap +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/small_array.memmap +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/small_no_bim.bed +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/small_no_bim.fam +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/small_no_fam.bed +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/small_no_fam.bim +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/small_too_short.bed +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/small_too_short.bim +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/small_too_short.fam +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/smallmode0.bed +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/smallmode0.bim +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/smallmode0.fam +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/smallmodebad.bed +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/some_missing.bed +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/some_missing.bim +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/some_missing.fam +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/some_missing.properties.npz +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/some_missing.val.npy +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/sparse.bed +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/sparse.bim +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/sparse.fam +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/toydata.5chrom.bed +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/toydata.5chrom.bim +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/data/toydata.5chrom.fam +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/registry.txt +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/test_file_dot.py +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/test_open_bed_cloud.py +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/bed_reader/tests/test_opt_dep.py +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/build.rs +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/examples/cloud.rs +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/examples/no_cloud.rs +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/pytest.ini +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/requirements-min-dev.txt +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/requirements.txt +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/setpath.bat +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/src/bed_cloud.rs +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/src/supplemental_documents/cloud_urls_etc.md +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/src/supplemental_documents/options_etc.md +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/tests/tests_api.rs +0 -0
- {bed_reader-1.0.2 → bed_reader-1.0.3b1}/tests/tests_api_cloud.rs +0 -0
|
@@ -5,7 +5,13 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [1.0.
|
|
8
|
+
## [1.0.2] - 2024-4-17
|
|
9
|
+
|
|
10
|
+
- On the Python file, add `create-bed`, a method for writing large
|
|
11
|
+
bed files SNP-by-SNP (or individual-by-individual).
|
|
12
|
+
Also, add full support for the less common individual-major files.
|
|
13
|
+
|
|
14
|
+
## [1.0.1] - 2024-3-16
|
|
9
15
|
|
|
10
16
|
- Add support for cloud files to both Rust and Python.
|
|
11
17
|
|
|
@@ -7,9 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
from bed_reader._open_bed import get_num_threads, open_bed
|
|
9
9
|
from bed_reader._sample_data import sample_file, sample_url, tmp_path
|
|
10
|
-
from bed_reader._to_bed import to_bed
|
|
10
|
+
from bed_reader._to_bed import create_bed, to_bed
|
|
11
11
|
|
|
12
12
|
from .bed_reader import (
|
|
13
|
+
encode1_i8,
|
|
13
14
|
file_aat_piece_f32_orderf,
|
|
14
15
|
file_aat_piece_f64_orderf,
|
|
15
16
|
file_ata_piece_f32_orderf,
|
|
@@ -301,7 +301,7 @@ class open_bed:
|
|
|
301
301
|
check_file_cloud(self.location.geturl(), self.cloud_options)
|
|
302
302
|
else:
|
|
303
303
|
with open(self.location, "rb") as filepointer:
|
|
304
|
-
self._check_file(filepointer)
|
|
304
|
+
self._mode = self._check_file(filepointer)
|
|
305
305
|
|
|
306
306
|
# # its an error to set both location and filepath
|
|
307
307
|
# location = self._combined(location, filepath, "location", "filepath")
|
|
@@ -547,6 +547,7 @@ class open_bed:
|
|
|
547
547
|
)
|
|
548
548
|
|
|
549
549
|
else:
|
|
550
|
+
|
|
550
551
|
if not self.count_A1:
|
|
551
552
|
byteZero = 0
|
|
552
553
|
byteThree = 2
|
|
@@ -563,45 +564,77 @@ class open_bed:
|
|
|
563
564
|
# Also, note that reading with python will often result in
|
|
564
565
|
# non-contiguous memory
|
|
565
566
|
# logging.warn("using pure python plink parser (might be much slower!!)")
|
|
567
|
+
|
|
568
|
+
if self.major == "SNP":
|
|
569
|
+
minor_count = self.iid_count
|
|
570
|
+
minor_index = iid_index
|
|
571
|
+
major_index = sid_index
|
|
572
|
+
else:
|
|
573
|
+
minor_count = self.sid_count
|
|
574
|
+
minor_index = sid_index
|
|
575
|
+
major_index = iid_index
|
|
576
|
+
|
|
566
577
|
val = np.zeros(
|
|
567
|
-
((int(np.ceil(0.25 *
|
|
578
|
+
((int(np.ceil(0.25 * minor_count)) * 4), len(major_index)),
|
|
568
579
|
order=order,
|
|
569
580
|
dtype=dtype,
|
|
570
581
|
) # allocate it a little big
|
|
571
582
|
|
|
572
|
-
nbyte = int(np.ceil(0.25 *
|
|
583
|
+
nbyte = int(np.ceil(0.25 * minor_count))
|
|
573
584
|
with open(self.location, "rb") as filepointer:
|
|
574
|
-
for
|
|
575
|
-
startbit = int(np.ceil(0.25 *
|
|
585
|
+
for major_index_value, major_index_index in enumerate(major_index):
|
|
586
|
+
startbit = int(np.ceil(0.25 * minor_count) * major_index_index + 3)
|
|
576
587
|
filepointer.seek(startbit)
|
|
577
588
|
bytes = np.array(bytearray(filepointer.read(nbyte))).reshape(
|
|
578
|
-
(int(np.ceil(0.25 *
|
|
589
|
+
(int(np.ceil(0.25 * minor_count)), 1), order="F"
|
|
579
590
|
)
|
|
580
591
|
|
|
581
|
-
val[3::4,
|
|
582
|
-
val[3::4,
|
|
583
|
-
|
|
584
|
-
|
|
592
|
+
val[3::4, major_index_value : major_index_value + 1] = byteZero
|
|
593
|
+
val[3::4, major_index_value : major_index_value + 1][
|
|
594
|
+
bytes >= 64
|
|
595
|
+
] = missing
|
|
596
|
+
val[3::4, major_index_value : major_index_value + 1][
|
|
597
|
+
bytes >= 128
|
|
598
|
+
] = 1
|
|
599
|
+
val[3::4, major_index_value : major_index_value + 1][
|
|
600
|
+
bytes >= 192
|
|
601
|
+
] = byteThree
|
|
585
602
|
bytes = np.mod(bytes, 64)
|
|
586
|
-
val[2::4,
|
|
587
|
-
val[2::4,
|
|
588
|
-
|
|
589
|
-
|
|
603
|
+
val[2::4, major_index_value : major_index_value + 1] = byteZero
|
|
604
|
+
val[2::4, major_index_value : major_index_value + 1][
|
|
605
|
+
bytes >= 16
|
|
606
|
+
] = missing
|
|
607
|
+
val[2::4, major_index_value : major_index_value + 1][
|
|
608
|
+
bytes >= 32
|
|
609
|
+
] = 1
|
|
610
|
+
val[2::4, major_index_value : major_index_value + 1][
|
|
611
|
+
bytes >= 48
|
|
612
|
+
] = byteThree
|
|
590
613
|
bytes = np.mod(bytes, 16)
|
|
591
|
-
val[1::4,
|
|
592
|
-
val[1::4,
|
|
593
|
-
|
|
594
|
-
|
|
614
|
+
val[1::4, major_index_value : major_index_value + 1] = byteZero
|
|
615
|
+
val[1::4, major_index_value : major_index_value + 1][
|
|
616
|
+
bytes >= 4
|
|
617
|
+
] = missing
|
|
618
|
+
val[1::4, major_index_value : major_index_value + 1][bytes >= 8] = 1
|
|
619
|
+
val[1::4, major_index_value : major_index_value + 1][
|
|
620
|
+
bytes >= 12
|
|
621
|
+
] = byteThree
|
|
595
622
|
bytes = np.mod(bytes, 4)
|
|
596
|
-
val[0::4,
|
|
597
|
-
val[0::4,
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
623
|
+
val[0::4, major_index_value : major_index_value + 1] = byteZero
|
|
624
|
+
val[0::4, major_index_value : major_index_value + 1][
|
|
625
|
+
bytes >= 1
|
|
626
|
+
] = missing
|
|
627
|
+
val[0::4, major_index_value : major_index_value + 1][bytes >= 2] = 1
|
|
628
|
+
val[0::4, major_index_value : major_index_value + 1][
|
|
629
|
+
bytes >= 3
|
|
630
|
+
] = byteThree
|
|
631
|
+
val = val[minor_index, :] # reorder or trim any extra allocation
|
|
601
632
|
assert val.dtype == np.dtype(dtype) # real assert
|
|
602
633
|
if not open_bed._array_properties_are_ok(val, order):
|
|
603
634
|
val = val.copy(order=order)
|
|
604
|
-
|
|
635
|
+
# if in force python mode, and individual-major mode, then we need to transpose
|
|
636
|
+
if self.major == "individual":
|
|
637
|
+
val = val.T
|
|
605
638
|
return val
|
|
606
639
|
|
|
607
640
|
def _pick_reader(self, dtype):
|
|
@@ -633,6 +666,47 @@ class open_bed:
|
|
|
633
666
|
def __str__(self) -> str:
|
|
634
667
|
return f"{self.__class__.__name__}('{self.location}',...)"
|
|
635
668
|
|
|
669
|
+
@property
|
|
670
|
+
def major(self) -> str:
|
|
671
|
+
"""
|
|
672
|
+
Major mode of a local .bed file.
|
|
673
|
+
|
|
674
|
+
Returns
|
|
675
|
+
-------
|
|
676
|
+
str
|
|
677
|
+
'SNP' or 'individual'
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
Almost all PLINK 1.9 .bed files are 'SNP' major. This makes
|
|
681
|
+
reading the data by SNP(s) fast.
|
|
682
|
+
|
|
683
|
+
Errors
|
|
684
|
+
------
|
|
685
|
+
ValueError
|
|
686
|
+
If the file is a cloud file.
|
|
687
|
+
|
|
688
|
+
Example
|
|
689
|
+
-------
|
|
690
|
+
|
|
691
|
+
.. doctest::
|
|
692
|
+
|
|
693
|
+
>>> from bed_reader import open_bed, sample_file
|
|
694
|
+
>>>
|
|
695
|
+
>>> file_name = sample_file("small.bed")
|
|
696
|
+
>>> with open_bed(file_name) as bed:
|
|
697
|
+
... print(bed.major)
|
|
698
|
+
SNP
|
|
699
|
+
|
|
700
|
+
"""
|
|
701
|
+
if self._is_url(self.location):
|
|
702
|
+
raise ValueError("Cannot determine major mode for cloud files")
|
|
703
|
+
# if self._mode is not set, set it
|
|
704
|
+
if not hasattr(self, "mode"):
|
|
705
|
+
with open(self.location, "rb") as filepointer:
|
|
706
|
+
self._mode = self._check_file(filepointer)
|
|
707
|
+
|
|
708
|
+
return "individual" if self._mode == b"\x00" else "SNP"
|
|
709
|
+
|
|
636
710
|
@property
|
|
637
711
|
def fid(self) -> np.ndarray:
|
|
638
712
|
"""
|
|
@@ -1158,12 +1232,14 @@ class open_bed:
|
|
|
1158
1232
|
|
|
1159
1233
|
@staticmethod
|
|
1160
1234
|
def _check_file(filepointer):
|
|
1161
|
-
|
|
1162
|
-
if
|
|
1235
|
+
magic_number = filepointer.read(2)
|
|
1236
|
+
if magic_number != b"l\x1b":
|
|
1237
|
+
raise ValueError("Not a valid .bed file")
|
|
1238
|
+
mode = filepointer.read(1)
|
|
1239
|
+
# Check if mode is either individual-major or SNP-major
|
|
1240
|
+
if mode not in (b"\x00", b"\x01"):
|
|
1163
1241
|
raise ValueError("Not a valid .bed file")
|
|
1164
|
-
mode
|
|
1165
|
-
if mode != b"\x01":
|
|
1166
|
-
raise ValueError("only SNP-major is implemented")
|
|
1242
|
+
return mode
|
|
1167
1243
|
|
|
1168
1244
|
def __del__(self):
|
|
1169
1245
|
self.__exit__()
|
|
@@ -1389,7 +1465,7 @@ class open_bed:
|
|
|
1389
1465
|
num_threads=None,
|
|
1390
1466
|
max_concurrent_requests=None,
|
|
1391
1467
|
max_chunk_bytes=None,
|
|
1392
|
-
) -> (Union[sparse.csc_matrix, sparse.csr_matrix]) if sparse is not None else None:
|
|
1468
|
+
) -> (Union[sparse.csc_matrix, sparse.csr_matrix]) if sparse is not None else None: # type: ignore
|
|
1393
1469
|
"""
|
|
1394
1470
|
Read genotype information into a :mod:`scipy.sparse` matrix. Sparse matrices
|
|
1395
1471
|
may be useful when the data is mostly zeros.
|
|
@@ -71,7 +71,7 @@ def sample_file(filepath: Union[str, Path]) -> str:
|
|
|
71
71
|
if pooch is None:
|
|
72
72
|
raise ImportError(
|
|
73
73
|
"The function sample_file() requires pooch. "
|
|
74
|
-
+ "Install it with 'pip install --upgrade bed-reader[
|
|
74
|
+
+ "Install it with 'pip install --upgrade bed-reader[samples]'."
|
|
75
75
|
)
|
|
76
76
|
|
|
77
77
|
filepath = Path(filepath)
|