methplotlib 0.23.2__tar.gz → 0.23.3__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.
Files changed (28) hide show
  1. {methplotlib-0.23.2/methplotlib.egg-info → methplotlib-0.23.3}/PKG-INFO +1 -1
  2. {methplotlib-0.23.2 → methplotlib-0.23.3}/methplotlib/import_methylation.py +30 -7
  3. methplotlib-0.23.3/methplotlib/version.py +1 -0
  4. {methplotlib-0.23.2 → methplotlib-0.23.3/methplotlib.egg-info}/PKG-INFO +1 -1
  5. {methplotlib-0.23.2 → methplotlib-0.23.3}/methplotlib.egg-info/SOURCES.txt +2 -1
  6. methplotlib-0.23.3/tests/test_import_methylation.py +78 -0
  7. methplotlib-0.23.2/methplotlib/version.py +0 -1
  8. {methplotlib-0.23.2 → methplotlib-0.23.3}/LICENSE +0 -0
  9. {methplotlib-0.23.2 → methplotlib-0.23.3}/MANIFEST.in +0 -0
  10. {methplotlib-0.23.2 → methplotlib-0.23.3}/README.md +0 -0
  11. {methplotlib-0.23.2 → methplotlib-0.23.3}/methplotlib/__init__.py +0 -0
  12. {methplotlib-0.23.2 → methplotlib-0.23.3}/methplotlib/annotation.py +0 -0
  13. {methplotlib-0.23.2 → methplotlib-0.23.3}/methplotlib/differential/__init__.py +0 -0
  14. {methplotlib-0.23.2 → methplotlib-0.23.3}/methplotlib/differential/differential.py +0 -0
  15. {methplotlib-0.23.2 → methplotlib-0.23.3}/methplotlib/helpers.py +0 -0
  16. {methplotlib-0.23.2 → methplotlib-0.23.3}/methplotlib/methplotlib.py +0 -0
  17. {methplotlib-0.23.2 → methplotlib-0.23.3}/methplotlib/plots.py +0 -0
  18. {methplotlib-0.23.2 → methplotlib-0.23.3}/methplotlib/qc.py +0 -0
  19. {methplotlib-0.23.2 → methplotlib-0.23.3}/methplotlib/utils.py +0 -0
  20. {methplotlib-0.23.2 → methplotlib-0.23.3}/methplotlib.egg-info/dependency_links.txt +0 -0
  21. {methplotlib-0.23.2 → methplotlib-0.23.3}/methplotlib.egg-info/entry_points.txt +0 -0
  22. {methplotlib-0.23.2 → methplotlib-0.23.3}/methplotlib.egg-info/requires.txt +0 -0
  23. {methplotlib-0.23.2 → methplotlib-0.23.3}/methplotlib.egg-info/top_level.txt +0 -0
  24. {methplotlib-0.23.2 → methplotlib-0.23.3}/scripts/allele_specific_modification +0 -0
  25. {methplotlib-0.23.2 → methplotlib-0.23.3}/scripts/differential_modification +0 -0
  26. {methplotlib-0.23.2 → methplotlib-0.23.3}/setup.cfg +0 -0
  27. {methplotlib-0.23.2 → methplotlib-0.23.3}/setup.py +0 -0
  28. {methplotlib-0.23.2 → methplotlib-0.23.3}/tests/test_differential.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: methplotlib
3
- Version: 0.23.2
3
+ Version: 0.23.3
4
4
  Summary: Plot nucleotide modification data from nanopore sequencing
5
5
  Home-page: https://github.com/wdecoster/methplotlib
6
6
  Author: Wouter De Coster
@@ -91,6 +91,7 @@ def parse_nanopolish(filename, file_type, name, window, smoothen=5):
91
91
  raise
92
92
  header = gzip.open(filename, "rt").readline().rstrip().split("\t")
93
93
  table = pd.read_csv(tabix_stream.stdout, sep="\t", header=None, names=header)
94
+ check_tabix(tabix_stream, filename, window)
94
95
  else:
95
96
  logging.info(f"Reading {filename} slowly by splitting the file in chunks.")
96
97
  sys.stderr.write(f"\nReading {filename} would be faster with bgzip and tabix.\n")
@@ -235,6 +236,19 @@ def no_records_warning(filename, window):
235
236
  sys.stderr.write(f"\nWARNING: {message}\nThis dataset is skipped.\n")
236
237
 
237
238
 
239
+ def check_tabix(tabix_stream, filename, window):
240
+ """
241
+ Exit if tabix failed, as a failing tabix also writes nothing to stdout,
242
+ which would otherwise be reported as a window without records.
243
+ Only call this after its stdout has been read.
244
+ """
245
+ if tabix_stream.wait() != 0:
246
+ sys.exit(
247
+ f"\n\nERROR: tabix failed to read {window.chromosome}:{window.begin}-{window.end} "
248
+ f"from {filename}:\n{tabix_stream.stderr.read().decode()}"
249
+ )
250
+
251
+
238
252
  def read_in_chunks(filename, window, sep, usecols, index_suggestion):
239
253
  """
240
254
  Read a headerless file in chunks, keeping only the lines of the chromosome of interest.
@@ -303,6 +317,7 @@ def parse_bedgraph(filename, name, window):
303
317
  names=colnames,
304
318
  dtype={0: str},
305
319
  )
320
+ check_tabix(tabix_stream, filename, window)
306
321
  else:
307
322
  table = read_in_chunks(
308
323
  filename,
@@ -380,13 +395,21 @@ def parse_bedmethyl(filename, name, window, smoothen=5, flavor="modkit", mods_of
380
395
  sys.stderr.write("\n\nERROR when opening a tabix stream.\n")
381
396
  sys.stderr.write("Is tabix installed and on the PATH?.")
382
397
  raise
383
- table = pd.read_csv(
384
- tabix_stream.stdout,
385
- sep=sep,
386
- header=None,
387
- usecols=usecols,
388
- dtype={0: str},
389
- ).rename(columns=colnames)
398
+ try:
399
+ table = pd.read_csv(
400
+ tabix_stream.stdout,
401
+ sep=sep,
402
+ header=None,
403
+ usecols=usecols,
404
+ dtype={0: str},
405
+ ).rename(columns=colnames)
406
+ except pd.errors.EmptyDataError:
407
+ table = None
408
+ check_tabix(tabix_stream, filename, window)
409
+ # tabix writes nothing if the window has no records or the chromosome is not in the index
410
+ if table is None:
411
+ no_records_warning(filename, window)
412
+ return []
390
413
  else:
391
414
  table = read_in_chunks(
392
415
  filename,
@@ -0,0 +1 @@
1
+ __version__ = "0.23.3"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: methplotlib
3
- Version: 0.23.2
3
+ Version: 0.23.3
4
4
  Summary: Plot nucleotide modification data from nanopore sequencing
5
5
  Home-page: https://github.com/wdecoster/methplotlib
6
6
  Author: Wouter De Coster
@@ -21,4 +21,5 @@ methplotlib/differential/__init__.py
21
21
  methplotlib/differential/differential.py
22
22
  scripts/allele_specific_modification
23
23
  scripts/differential_modification
24
- tests/test_differential.py
24
+ tests/test_differential.py
25
+ tests/test_import_methylation.py
@@ -0,0 +1,78 @@
1
+ import shutil
2
+
3
+ import pysam
4
+ import pytest
5
+
6
+ from methplotlib.import_methylation import parse_bedgraph, parse_bedmethyl, parse_nanopolish
7
+ from methplotlib.utils import Region
8
+
9
+ pytestmark = pytest.mark.skipif(shutil.which("tabix") is None, reason="tabix not on the PATH")
10
+
11
+ # `modkit pileup --only-tabs` records, as shared in issue #52
12
+ BEDMETHYL = """\
13
+ 1\t10468\t10469\th\t1\t+\t10468\t10469\t255,0,0\t1\t0.00\t0\t0\t1\t1\t0\t0\t0
14
+ 1\t10468\t10469\tm\t1\t+\t10468\t10469\t255,0,0\t1\t100.00\t1\t0\t0\t1\t0\t0\t0
15
+ 1\t10469\t10470\th\t2\t-\t10469\t10470\t255,0,0\t2\t0.00\t0\t1\t1\t0\t0\t0\t0
16
+ 1\t10469\t10470\tm\t2\t-\t10469\t10470\t255,0,0\t2\t50.00\t1\t1\t0\t0\t0\t0\t0
17
+ """
18
+
19
+ BEDGRAPH = """\
20
+ 1\t10468\t10469\t0.5
21
+ 1\t10469\t10470\t1.0
22
+ """
23
+
24
+ NANOPOLISH_FREQ = """\
25
+ chromosome\tstart\tend\tnum_motifs_in_group\tcalled_sites\tcalled_sites_methylated\tmethylated_frequency\tgroup_sequence
26
+ 1\t10468\t10468\t1\t10\t5\t0.5\tACGTA
27
+ 1\t10470\t10470\t1\t10\t10\t1.0\tACGTA
28
+ """
29
+
30
+
31
+ def indexed(tmp_path, name, content, **index_args):
32
+ path = tmp_path / name
33
+ path.write_text(content)
34
+ # bgzips the file and creates the .tbi index next to it
35
+ return pysam.tabix_index(str(path), **index_args)
36
+
37
+
38
+ @pytest.fixture
39
+ def indexed_bedmethyl(tmp_path):
40
+ return indexed(tmp_path, "test.bed", BEDMETHYL, preset="bed")
41
+
42
+
43
+ def corrupt_index(filename):
44
+ with open(filename + ".tbi", "w") as index:
45
+ index.write("not an index")
46
+
47
+
48
+ def test_indexed_bedmethyl_with_records(indexed_bedmethyl):
49
+ mods = parse_bedmethyl(indexed_bedmethyl, "test", Region("1:10000-11000"))
50
+ assert sorted(m.name for m in mods) == ["test_h", "test_m"]
51
+
52
+
53
+ @pytest.mark.parametrize("window", ["chrX:146,991,437-147,034,645", "1:500000-600000"])
54
+ def test_indexed_bedmethyl_without_records(indexed_bedmethyl, window):
55
+ assert parse_bedmethyl(indexed_bedmethyl, "test", Region(window)) == []
56
+
57
+
58
+ @pytest.mark.parametrize(
59
+ "name, content, index_args, parse",
60
+ [
61
+ ("test.bed", BEDMETHYL, {"preset": "bed"}, parse_bedmethyl),
62
+ ("test.bedgraph", BEDGRAPH, {"preset": "bed"}, parse_bedgraph),
63
+ (
64
+ "freq.tsv",
65
+ NANOPOLISH_FREQ,
66
+ {"seq_col": 0, "start_col": 1, "end_col": 2, "line_skip": 1},
67
+ lambda f, n, w: parse_nanopolish(f, "nanopolish_freq", n, w),
68
+ ),
69
+ ],
70
+ ids=["bedmethyl", "bedgraph", "nanopolish_freq"],
71
+ )
72
+ def test_tabix_failure(tmp_path, name, content, index_args, parse):
73
+ # a corrupt index makes tabix exit with an error and no output,
74
+ # which should not be reported as a window without records
75
+ filename = indexed(tmp_path, name, content, **index_args)
76
+ corrupt_index(filename)
77
+ with pytest.raises(SystemExit, match="tabix failed"):
78
+ parse(filename, "test", Region("1:10000-11000"))
@@ -1 +0,0 @@
1
- __version__ = "0.23.2"
File without changes
File without changes
File without changes
File without changes
File without changes