Skip to content

Commit a16ee56

Browse files
committed
gz bed/gtf and test
1 parent 4aa0a34 commit a16ee56

7 files changed

Lines changed: 91 additions & 8 deletions

File tree

pydeeptools/deeptools/test/test_computeMatrix_referencepoint.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
REGIONS_IN1 = ROOT + "input_computeMatrix_regions1.bed"
1414
REGIONS_IN2 = ROOT + "input_computeMatrix_regions2.bed"
1515
REGIONS_GTF = ROOT + "input_computeMatrix_regions3.gtf"
16+
REGIONS_IN1_GZ = ROOT + "input_computeMatrix_regions1.bed.gz"
17+
REGIONS_GTF_GZ = ROOT + "input_computeMatrix_regions3.gtf.gz"
1618
REGIONS_BED12 = ROOT + "input_computeMatrix_regions4bed12.bed"
1719
BL = ROOT + "input_computeMatrix_blacklist.bed"
1820
BIGWIG_IN1 = ROOT + "input_computeMatrix_bw1.bw"
@@ -246,6 +248,28 @@ def test_compute_matrix_refpoint():
246248
mat_match, mat_diffs = _compare_tab_files(outfile_mat, exp_mat)
247249
assert mat_match, f"matrix mismatch: {mat_diffs}"
248250

251+
def test_compute_matrix_refpoint_bed_gz():
252+
exp_npz = ROOT + "mat.gz"
253+
exp_mat = ROOT + "mat.tab"
254+
255+
_, outfile_npz = tempfile.mkstemp(suffix='.gz')
256+
_, outfile_mat = tempfile.mkstemp(suffix='.tab')
257+
args = f"""
258+
reference-point
259+
--regionsFileName {REGIONS_IN1_GZ}
260+
--scoreFileName {BIGWIG_IN1}
261+
-b 20 -a 20
262+
-o {outfile_npz} --outFileNameMatrix {outfile_mat}
263+
""".split()
264+
cm.main(args)
265+
266+
header_differences, data_differences, rowdiffdic = _compare_mat_gz(outfile_npz, exp_npz)
267+
assert not header_differences, f"header mismatch: {header_differences}"
268+
assert not data_differences, f"data mismatch: {data_differences}\nrowdiffdict: {rowdiffdic}"
269+
270+
mat_match, mat_diffs = _compare_tab_files(outfile_mat, exp_mat)
271+
assert mat_match, f"matrix mismatch: {mat_diffs}"
272+
249273
def test_compute_matrix_refpoint2():
250274
exp_npz = ROOT + "mat2.gz"
251275
exp_mat = ROOT + "mat2.tab"
@@ -958,6 +982,28 @@ def test_compute_matrix_refpoint_gtf():
958982
mat_match, mat_diffs = _compare_tab_files(outfile_mat, exp_mat)
959983
assert mat_match, f"matrix mismatch: {mat_diffs}"
960984

985+
def test_compute_matrix_refpoint_gtf_gz():
986+
exp_npz = ROOT + "mat_gtf.gz"
987+
exp_mat = ROOT + "mat_gtf.tab"
988+
989+
_, outfile_npz = tempfile.mkstemp(suffix='.gz')
990+
_, outfile_mat = tempfile.mkstemp(suffix='.tab')
991+
args = f"""
992+
reference-point
993+
--regionsFileName {REGIONS_GTF_GZ}
994+
--scoreFileName {BIGWIG_IN1} {BIGWIG_IN2} {BIGWIG_IN3}
995+
-b 30 -a 30 --binSize 30
996+
-o {outfile_npz} --outFileNameMatrix {outfile_mat}
997+
""".split()
998+
cm.main(args)
999+
1000+
header_differences, data_differences, rowdiffdic = _compare_mat_gz(outfile_npz, exp_npz)
1001+
assert not header_differences, f"header mismatch: {header_differences}"
1002+
assert not data_differences, f"data mismatch: {data_differences}\nrowdiffdict: {rowdiffdic}"
1003+
1004+
mat_match, mat_diffs = _compare_tab_files(outfile_mat, exp_mat)
1005+
assert mat_match, f"matrix mismatch: {mat_diffs}"
1006+
9611007
def test_compute_matrix_refpoint_bed12mg():
9621008
exp_npz = ROOT + "mat_bed12mg.gz"
9631009
exp_mat = ROOT + "mat_bed12mg.tab"
Binary file not shown.
Binary file not shown.
74 Bytes
Binary file not shown.
169 Bytes
Binary file not shown.

pydeeptools/deeptools/test/test_multiBamSummary.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
BAMB = ROOT + "testB"
1919
BLACKLIST = ROOT + "blacklist.bed"
2020
GTF2 = ROOT + "test_customids.gtf"
21+
BED_GZ = ROOT + "test.bed.gz"
22+
GTF_GZ = ROOT + "test.gtf.gz"
2123

2224
def compare_tsv(exp_tsv, obs_tsv, delta=1.0):
2325
with open(exp_tsv) as e, open(obs_tsv) as o:
@@ -63,6 +65,32 @@ def test_multiBamSummary_bedmode_bed():
6365
)
6466
)
6567

68+
def test_multiBamSummary_bedmode_gtf_gz():
69+
_, outfile = tempfile.mkstemp(suffix=".npz")
70+
for fname in ['.bam', '.cram']:
71+
fname = BAM + fname
72+
args = f"BED-file --BED {GTF_GZ} -b {fname} {fname} -o {outfile}".split()
73+
mbs.main(args)
74+
resp = np.load(outfile)
75+
matrix = resp['matrix']
76+
77+
nt.assert_allclose(matrix, np.array([[144.0, 144.0],[143.0, 143.0]]))
78+
79+
def test_multiBamSummary_bedmode_bed_gz():
80+
_, outfile = tempfile.mkstemp(suffix=".npz")
81+
for fname in ['.bam', '.cram']:
82+
fname = BAM + fname
83+
args = f"BED-file --BED {BED_GZ} -b {fname} {fname} -o {outfile}".split()
84+
mbs.main(args)
85+
resp = np.load(outfile)
86+
matrix = resp['matrix']
87+
88+
nt.assert_allclose(matrix,
89+
np.array(
90+
[[1.0, 1.0], [144.0, 144.0], [144.0, 144.0], [6.0, 6.0], [143.0, 143.0], [22.0, 22.0], [25.0, 25.0], [1.0, 1.0], [0.0, 0.0]]
91+
)
92+
)
93+
6694
def test_multiBamSummary_bedmode_multibed():
6795
_, outfile = tempfile.mkstemp(suffix=".npz")
6896
for fname in ['.bam', '.cram']:

src/filehandler.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::covcalc::{Bin, Gtfparse, Region, Revalue, Scalingregions};
33
use bigtools::beddata::BedParserStreamingIterator;
44
use bigtools::{BigWigRead, BigWigWrite, Value};
55
use flate2::Compression;
6+
use flate2::read::MultiGzDecoder;
67
use flate2::write::GzEncoder;
78
use itertools::Itertools;
89
use rust_htslib::bam::{IndexedReader, Read, Reader};
@@ -55,10 +56,22 @@ where
5556
}
5657
}
5758

59+
fn open_bed_or_gtf_reader(fp: &str) -> BufReader<Box<dyn std::io::Read>> {
60+
let mut file = File::open(fp).expect(format!("Failed to open file: {}", fp).as_str());
61+
let mut magic = [0u8; 2];
62+
let n = std::io::Read::read(&mut file, &mut magic).unwrap_or(0);
63+
std::io::Seek::seek(&mut file, std::io::SeekFrom::Start(0))
64+
.expect(format!("Failed to seek in file: {}", fp).as_str());
65+
if n == 2 && magic[0] == 0x1f && magic[1] == 0x8b {
66+
BufReader::new(Box::new(MultiGzDecoder::new(file)) as Box<dyn std::io::Read>)
67+
} else {
68+
BufReader::new(Box::new(file) as Box<dyn std::io::Read>)
69+
}
70+
}
71+
5872
pub fn is_bed_or_gtf(fp: &str) -> String {
5973
// Check if file is a bed or gtf file.
60-
let file = File::open(fp).expect(format!("Failed to open file: {}", fp).as_str());
61-
let reader = BufReader::new(file);
74+
let reader = open_bed_or_gtf_reader(fp);
6275
// Get the first line that doesn't start with #
6376
for line in reader.lines() {
6477
let line = line.unwrap();
@@ -85,7 +98,7 @@ pub fn read_gtffile(
8598
let mut entries: u32 = 0;
8699
let mut txnids: Vec<String> = Vec::new();
87100

88-
let gtffile = BufReader::new(File::open(gtf_file).unwrap());
101+
let gtffile = open_bed_or_gtf_reader(gtf_file);
89102

90103
if gtfparse.metagene {
91104
// metagene implementation - more work here.
@@ -157,9 +170,6 @@ pub fn read_gtffile(
157170
let has_exons = txn_hash.contains_key(&txnid);
158171
let has_transcript = txn_transcript.contains_key(&txnid);
159172

160-
// Only keep entries that have a 'transcript' feature line.
161-
// This mirrors Python behavior: the transcript must exist in the
162-
// interval tree for exons to be returned by findOverlaps().
163173
if has_exons && !has_transcript {
164174
continue;
165175
}
@@ -266,7 +276,7 @@ pub fn read_bedfile(
266276
let mut nonbed12: bool = false;
267277
let mut entries: u32 = 0;
268278

269-
let bedfile = BufReader::new(File::open(bed_file).unwrap());
279+
let bedfile = open_bed_or_gtf_reader(bed_file);
270280

271281
for line in bedfile.lines() {
272282
let line = line.unwrap();
@@ -1011,7 +1021,6 @@ pub fn write_sorted_regions_bed(
10111021
group_boundaries.push(cumsum);
10121022
}
10131023
for (idx, region) in regions.iter().enumerate() {
1014-
// Find label_idx: last boundary <= idx, matching Python: np.flatnonzero(boundaries <= idx)[-1]
10151024
let label_idx = group_boundaries
10161025
.iter()
10171026
.take_while(|&&b| b <= idx as u32)

0 commit comments

Comments
 (0)