ModDotPlot 0.9.0__tar.gz → 0.9.1__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.
- moddotplot-0.9.1/PKG-INFO +48 -0
- {moddotplot-0.9.0 → moddotplot-0.9.1}/README.md +4 -4
- {moddotplot-0.9.0 → moddotplot-0.9.1}/pyproject.toml +5 -12
- moddotplot-0.9.1/src/ModDotPlot.egg-info/PKG-INFO +48 -0
- {moddotplot-0.9.0 → moddotplot-0.9.1}/src/ModDotPlot.egg-info/requires.txt +2 -1
- {moddotplot-0.9.0 → moddotplot-0.9.1}/src/moddotplot/const.py +1 -1
- {moddotplot-0.9.0 → moddotplot-0.9.1}/src/moddotplot/moddotplot.py +169 -130
- {moddotplot-0.9.0 → moddotplot-0.9.1}/src/moddotplot/parse_fasta.py +7 -2
- {moddotplot-0.9.0 → moddotplot-0.9.1}/src/moddotplot/static_plots.py +663 -372
- moddotplot-0.9.0/PKG-INFO +0 -421
- moddotplot-0.9.0/src/ModDotPlot.egg-info/PKG-INFO +0 -421
- {moddotplot-0.9.0 → moddotplot-0.9.1}/LICENSE +0 -0
- {moddotplot-0.9.0 → moddotplot-0.9.1}/setup.cfg +0 -0
- {moddotplot-0.9.0 → moddotplot-0.9.1}/src/ModDotPlot.egg-info/SOURCES.txt +0 -0
- {moddotplot-0.9.0 → moddotplot-0.9.1}/src/ModDotPlot.egg-info/dependency_links.txt +0 -0
- {moddotplot-0.9.0 → moddotplot-0.9.1}/src/ModDotPlot.egg-info/entry_points.txt +0 -0
- {moddotplot-0.9.0 → moddotplot-0.9.1}/src/ModDotPlot.egg-info/top_level.txt +0 -0
- {moddotplot-0.9.0 → moddotplot-0.9.1}/src/moddotplot/__init__.py +0 -0
- {moddotplot-0.9.0 → moddotplot-0.9.1}/src/moddotplot/__main__.py +0 -0
- {moddotplot-0.9.0 → moddotplot-0.9.1}/src/moddotplot/estimate_identity.py +0 -0
- {moddotplot-0.9.0 → moddotplot-0.9.1}/src/moddotplot/interactive.py +0 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: ModDotPlot
|
|
3
|
+
Version: 0.9.1
|
|
4
|
+
Author: Michael Schatz, Adam Phillippy
|
|
5
|
+
Author-email: Alex Sweeten <alex.sweeten@nih.gov>
|
|
6
|
+
Maintainer-email: Alex Sweeten <alex.sweeten@nih.gov>
|
|
7
|
+
License: MIT License
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2024 MarBL
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
in the Software without restriction, including without limitation the rights
|
|
14
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright notice and this permission notice shall be included in all
|
|
19
|
+
copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
+
SOFTWARE.
|
|
28
|
+
|
|
29
|
+
Keywords: dotplot,sketching,modimizer,heatmap
|
|
30
|
+
Requires-Python: >=3.7
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
License-File: LICENSE
|
|
33
|
+
Requires-Dist: pysam
|
|
34
|
+
Requires-Dist: pandas
|
|
35
|
+
Requires-Dist: plotly
|
|
36
|
+
Requires-Dist: dash
|
|
37
|
+
Requires-Dist: plotnine==0.12.4
|
|
38
|
+
Requires-Dist: palettable
|
|
39
|
+
Requires-Dist: mmh3
|
|
40
|
+
Requires-Dist: tk
|
|
41
|
+
Requires-Dist: setproctitle
|
|
42
|
+
Requires-Dist: numpy
|
|
43
|
+
Requires-Dist: pillow
|
|
44
|
+
Requires-Dist: patchworklib==0.6.3
|
|
45
|
+
Requires-Dist: cairosvg
|
|
46
|
+
Provides-Extra: test
|
|
47
|
+
Requires-Dist: pytest; extra == "test"
|
|
48
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
## Cite
|
|
21
21
|
|
|
22
|
-
Alexander P Sweeten, Michael C Schatz, Adam M Phillippy, ModDotPlot—rapid and interactive visualization of tandem repeats, Bioinformatics, Volume 40, Issue 8, August 2024, btae493, https://doi.org/10.1093/bioinformatics/btae493
|
|
22
|
+
Alexander P Sweeten, Michael C Schatz, Adam M Phillippy, ModDotPlot—rapid and interactive visualization of tandem repeats, Bioinformatics, Volume 40, Issue 8, August 2024, btae493, [https://doi.org/10.1093/bioinformatics/btae493](https://pmc.ncbi.nlm.nih.gov/articles/PMC11321072/)
|
|
23
23
|
|
|
24
24
|
If you use ModDotPlot for your research, please cite our software!
|
|
25
25
|
|
|
@@ -386,10 +386,10 @@ For bug reports or general usage questions, please raise a GitHub issue, or emai
|
|
|
386
386
|
|
|
387
387
|
## Known Issues
|
|
388
388
|
|
|
389
|
-
-
|
|
389
|
+
-
|
|
390
390
|
|
|
391
391
|
- Mac users might encounter the following unexpected command line output: `/bin/sh: lscpu: command not found`. This is a known issue with Plotnine, the Python plotting library used by ModDotPlot. This can be safely ignored.
|
|
392
392
|
|
|
393
|
-
- If you encounter an error with the following traceback: `rv = reductor(4) TypeError: cannot pickle 'generator' object`,
|
|
393
|
+
- If you encounter an error with the following traceback: `rv = reductor(4) TypeError: cannot pickle 'generator' object`, this means that you have a newer version of Plotnine that is incompatible with ModDotPlot. Please uninstall plotnine and reinstall version 0.12.4 `pip install plotnine==0.12.4`.
|
|
394
394
|
|
|
395
|
-
-
|
|
395
|
+
- There are a number of errors
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ModDotPlot"
|
|
7
|
-
version = "0.9.
|
|
7
|
+
version = "0.9.1"
|
|
8
8
|
requires-python = ">= 3.7"
|
|
9
9
|
dependencies = [
|
|
10
10
|
"pysam",
|
|
@@ -18,7 +18,8 @@ dependencies = [
|
|
|
18
18
|
"setproctitle",
|
|
19
19
|
"numpy",
|
|
20
20
|
"pillow",
|
|
21
|
-
"patchworklib"
|
|
21
|
+
"patchworklib==0.6.3",
|
|
22
|
+
"cairosvg"
|
|
22
23
|
]
|
|
23
24
|
authors = [
|
|
24
25
|
{name = "Alex Sweeten", email = "alex.sweeten@nih.gov"},
|
|
@@ -28,7 +29,8 @@ authors = [
|
|
|
28
29
|
maintainers = [
|
|
29
30
|
{name = "Alex Sweeten", email = "alex.sweeten@nih.gov"}
|
|
30
31
|
]
|
|
31
|
-
readme = {file = "README.
|
|
32
|
+
readme = {file = "README.txt", content-type = "text/markdown"}
|
|
33
|
+
license = {file = "LICENSE"}
|
|
32
34
|
keywords = ["dotplot", "sketching", "modimizer", "heatmap"]
|
|
33
35
|
|
|
34
36
|
[project.scripts]
|
|
@@ -40,12 +42,3 @@ test = [
|
|
|
40
42
|
"pytest",
|
|
41
43
|
"pytest-cov"
|
|
42
44
|
]
|
|
43
|
-
|
|
44
|
-
[tool.hatch.build.targets.sdist]
|
|
45
|
-
exclude = [
|
|
46
|
-
"/.github",
|
|
47
|
-
"/docs",
|
|
48
|
-
]
|
|
49
|
-
|
|
50
|
-
[tool.hatch.build.targets.wheel]
|
|
51
|
-
packages = ["src/moddotplot"]
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: ModDotPlot
|
|
3
|
+
Version: 0.9.1
|
|
4
|
+
Author: Michael Schatz, Adam Phillippy
|
|
5
|
+
Author-email: Alex Sweeten <alex.sweeten@nih.gov>
|
|
6
|
+
Maintainer-email: Alex Sweeten <alex.sweeten@nih.gov>
|
|
7
|
+
License: MIT License
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2024 MarBL
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
in the Software without restriction, including without limitation the rights
|
|
14
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright notice and this permission notice shall be included in all
|
|
19
|
+
copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
+
SOFTWARE.
|
|
28
|
+
|
|
29
|
+
Keywords: dotplot,sketching,modimizer,heatmap
|
|
30
|
+
Requires-Python: >=3.7
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
License-File: LICENSE
|
|
33
|
+
Requires-Dist: pysam
|
|
34
|
+
Requires-Dist: pandas
|
|
35
|
+
Requires-Dist: plotly
|
|
36
|
+
Requires-Dist: dash
|
|
37
|
+
Requires-Dist: plotnine==0.12.4
|
|
38
|
+
Requires-Dist: palettable
|
|
39
|
+
Requires-Dist: mmh3
|
|
40
|
+
Requires-Dist: tk
|
|
41
|
+
Requires-Dist: setproctitle
|
|
42
|
+
Requires-Dist: numpy
|
|
43
|
+
Requires-Dist: pillow
|
|
44
|
+
Requires-Dist: patchworklib==0.6.3
|
|
45
|
+
Requires-Dist: cairosvg
|
|
46
|
+
Provides-Extra: test
|
|
47
|
+
Requires-Dist: pytest; extra == "test"
|
|
48
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
@@ -179,7 +179,7 @@ def get_parser():
|
|
|
179
179
|
"-b",
|
|
180
180
|
"--bed",
|
|
181
181
|
default=argparse.SUPPRESS,
|
|
182
|
-
help="Path to input bed file(s). Exclusively used in static mode.",
|
|
182
|
+
help="Path to input paired-end bed file(s). Exclusively used in static mode.",
|
|
183
183
|
nargs="+",
|
|
184
184
|
)
|
|
185
185
|
|
|
@@ -273,7 +273,7 @@ def get_parser():
|
|
|
273
273
|
)
|
|
274
274
|
|
|
275
275
|
static_parser.add_argument(
|
|
276
|
-
"--width", default=
|
|
276
|
+
"--width", default=18, type=float, help="Plot width (also height for _FULL)."
|
|
277
277
|
)
|
|
278
278
|
|
|
279
279
|
static_parser.add_argument("--dpi", default=600, type=int, help="Plot dpi.")
|
|
@@ -321,8 +321,15 @@ def get_parser():
|
|
|
321
321
|
"--axes-ticks",
|
|
322
322
|
default=None,
|
|
323
323
|
nargs="+",
|
|
324
|
+
type=int,
|
|
324
325
|
help="Tick labels to include in x and y axis for custom plots.",
|
|
325
326
|
)
|
|
327
|
+
# CURRENTLY NOT WORKING
|
|
328
|
+
static_parser.add_argument(
|
|
329
|
+
"--axes-number",
|
|
330
|
+
default=7,
|
|
331
|
+
help="Number of axis ticks labels to include in x and y axis for custom plots, including 0 and seq_length. A minimum of 2 is required, maximum 25.",
|
|
332
|
+
)
|
|
326
333
|
|
|
327
334
|
static_parser.add_argument(
|
|
328
335
|
"--bin-freq",
|
|
@@ -345,10 +352,21 @@ def get_parser():
|
|
|
345
352
|
static_parser.add_argument(
|
|
346
353
|
"--grid-only",
|
|
347
354
|
action="store_true",
|
|
348
|
-
help="Plot comparative plots in an NxN grid like format, skipping individual plots",
|
|
355
|
+
help="Plot comparative plots in an NxN grid like format, skipping individual plots.",
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
static_parser.add_argument(
|
|
359
|
+
"--vector",
|
|
360
|
+
choices=["svg", "pdf", "ps"],
|
|
361
|
+
default="svg",
|
|
362
|
+
help="Output format for vector format.",
|
|
349
363
|
)
|
|
350
364
|
|
|
351
|
-
|
|
365
|
+
static_parser.add_argument(
|
|
366
|
+
"--deraster",
|
|
367
|
+
action="store_true",
|
|
368
|
+
help="De-rasterize dotplot in vector format. Note this can lead to large image sizes and make it unusable in image editing software.",
|
|
369
|
+
)
|
|
352
370
|
|
|
353
371
|
return parser
|
|
354
372
|
|
|
@@ -433,14 +451,13 @@ def main():
|
|
|
433
451
|
args.breakpoints = config.get("breakpoints", args.breakpoints)
|
|
434
452
|
args.bin_freq = config.get("bin_freq", args.bin_freq)
|
|
435
453
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
if args.grid or args.grid_only:
|
|
454
|
+
#
|
|
455
|
+
"""if args.grid or args.grid_only:
|
|
439
456
|
if not (args.compare or args.compare_only) and not args.bed:
|
|
440
457
|
print(
|
|
441
458
|
f"Option --grid was selected, but no comparative plots will be produced. Please rerun ModDotPlot with the `--compare` or `--compare-only` option.\n"
|
|
442
459
|
)
|
|
443
|
-
sys.exit(10)
|
|
460
|
+
sys.exit(10)"""
|
|
444
461
|
|
|
445
462
|
# -----------INPUT COMMAND VALIDATION-----------
|
|
446
463
|
# TODO: More tests!
|
|
@@ -465,118 +482,140 @@ def main():
|
|
|
465
482
|
double_vals = []
|
|
466
483
|
single_val_name = []
|
|
467
484
|
double_val_name = []
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
485
|
+
xlim_val_grid = 0
|
|
486
|
+
for bed in args.bed:
|
|
487
|
+
# If args.bed is provided as input, run static mode directly from the bed file. Skip counting input k-mers.
|
|
488
|
+
df = read_df_from_file(bed)
|
|
489
|
+
|
|
490
|
+
unique_query_names = df["#query_name"].unique()
|
|
491
|
+
unique_reference_names = df["reference_name"].unique()
|
|
492
|
+
assert len(unique_query_names) == len(unique_reference_names)
|
|
493
|
+
assert len(unique_reference_names) == 1
|
|
494
|
+
self_id_scores = df[df["#query_name"] == df["reference_name"]]
|
|
495
|
+
pairwise_id_scores = df[df["#query_name"] != df["reference_name"]]
|
|
496
|
+
if not args.grid_only:
|
|
497
|
+
print(f"Input bed file {bed} read successfully! Creating plots: \n")
|
|
498
|
+
# Create directory
|
|
499
|
+
if not args.output_dir:
|
|
500
|
+
args.output_dir = os.getcwd()
|
|
501
|
+
if not os.path.exists(args.output_dir):
|
|
502
|
+
os.makedirs(args.output_dir)
|
|
503
|
+
if len(self_id_scores) > 1:
|
|
480
504
|
if not args.grid_only:
|
|
481
|
-
|
|
482
|
-
|
|
505
|
+
create_plots(
|
|
506
|
+
sdf=None,
|
|
507
|
+
directory=args.output_dir if args.output_dir else ".",
|
|
508
|
+
name_x=unique_query_names[0],
|
|
509
|
+
name_y=unique_query_names[0],
|
|
510
|
+
palette=args.palette,
|
|
511
|
+
palette_orientation=args.palette_orientation,
|
|
512
|
+
no_hist=args.no_hist,
|
|
513
|
+
width=args.width,
|
|
514
|
+
dpi=args.dpi,
|
|
515
|
+
is_freq=args.bin_freq,
|
|
516
|
+
xlim=args.axes_limits,
|
|
517
|
+
custom_colors=args.colors,
|
|
518
|
+
custom_breakpoints=args.breakpoints,
|
|
519
|
+
from_file=df,
|
|
520
|
+
is_pairwise=False,
|
|
521
|
+
axes_labels=args.axes_ticks,
|
|
522
|
+
axes_tick_number=args.axes_number,
|
|
523
|
+
vector_format=args.vector,
|
|
524
|
+
deraster=args.deraster,
|
|
483
525
|
)
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
if not args.grid_only:
|
|
491
|
-
create_plots(
|
|
492
|
-
sdf=None,
|
|
493
|
-
directory=args.output_dir if args.output_dir else ".",
|
|
494
|
-
name_x=unique_query_names[0],
|
|
495
|
-
name_y=unique_query_names[0],
|
|
496
|
-
palette=args.palette,
|
|
497
|
-
palette_orientation=args.palette_orientation,
|
|
498
|
-
no_hist=args.no_hist,
|
|
499
|
-
width=args.width,
|
|
500
|
-
dpi=args.dpi,
|
|
501
|
-
is_freq=args.bin_freq,
|
|
502
|
-
xlim=args.axes_limits,
|
|
503
|
-
custom_colors=args.colors,
|
|
504
|
-
custom_breakpoints=args.breakpoints,
|
|
505
|
-
from_file=df,
|
|
506
|
-
is_pairwise=False,
|
|
507
|
-
axes_labels=args.axes_ticks,
|
|
526
|
+
if args.grid or args.grid_only:
|
|
527
|
+
single_vals.append(df)
|
|
528
|
+
single_val_name.append(unique_query_names[0])
|
|
529
|
+
try:
|
|
530
|
+
max_so_far = max(
|
|
531
|
+
df["query_end"].max(), df["reference_end"].max()
|
|
508
532
|
)
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
533
|
+
except KeyError:
|
|
534
|
+
max_so_far = max(df["q_en"].max(), df["r_en"].max())
|
|
535
|
+
xlim_val_grid = (
|
|
536
|
+
max_so_far if max_so_far > xlim_val_grid else xlim_val_grid
|
|
537
|
+
)
|
|
538
|
+
# Case 2: Pairwise bed file
|
|
539
|
+
if len(pairwise_id_scores) > 1:
|
|
540
|
+
if not args.grid_only:
|
|
541
|
+
# Potentially sort
|
|
542
|
+
create_plots(
|
|
543
|
+
sdf=None,
|
|
544
|
+
directory=args.output_dir if args.output_dir else ".",
|
|
545
|
+
name_x=unique_query_names[0],
|
|
546
|
+
name_y=unique_reference_names[0],
|
|
547
|
+
palette=args.palette,
|
|
548
|
+
palette_orientation=args.palette_orientation,
|
|
549
|
+
no_hist=args.no_hist,
|
|
550
|
+
width=args.width,
|
|
551
|
+
dpi=args.dpi,
|
|
552
|
+
is_freq=args.bin_freq,
|
|
553
|
+
xlim=args.axes_limits,
|
|
554
|
+
custom_colors=args.colors,
|
|
555
|
+
custom_breakpoints=args.axes_ticks,
|
|
556
|
+
from_file=df,
|
|
557
|
+
is_pairwise=True,
|
|
558
|
+
axes_labels=args.axes_ticks,
|
|
559
|
+
axes_tick_number=args.axes_number,
|
|
560
|
+
vector_format=args.vector,
|
|
561
|
+
deraster=args.deraster,
|
|
562
|
+
)
|
|
563
|
+
if args.grid or args.grid_only:
|
|
564
|
+
double_vals.append(df)
|
|
565
|
+
double_val_name.append(
|
|
566
|
+
[unique_query_names[0], unique_reference_names[0]]
|
|
567
|
+
)
|
|
568
|
+
# Exit once all bed files have been iterated through
|
|
569
|
+
if args.grid or args.grid_only:
|
|
570
|
+
# Determine the number of sequences
|
|
571
|
+
if args.axes_limits:
|
|
572
|
+
xlim_val_grid = args.axes_limits
|
|
573
|
+
print(
|
|
574
|
+
f"Creating a {len(single_val_name)}x{len(single_val_name)} grid.\n"
|
|
575
|
+
)
|
|
576
|
+
create_grid(
|
|
577
|
+
singles=single_vals,
|
|
578
|
+
doubles=double_vals,
|
|
579
|
+
directory=args.output_dir if args.output_dir else ".",
|
|
580
|
+
palette=args.palette,
|
|
581
|
+
palette_orientation=args.palette_orientation,
|
|
582
|
+
single_names=single_val_name,
|
|
583
|
+
double_names=double_val_name,
|
|
584
|
+
is_freq=args.bin_freq,
|
|
585
|
+
xlim=xlim_val_grid,
|
|
586
|
+
custom_colors=args.colors,
|
|
587
|
+
custom_breakpoints=args.axes_ticks,
|
|
588
|
+
axes_label=args.axes_ticks,
|
|
589
|
+
is_bed=True,
|
|
590
|
+
width=args.width,
|
|
591
|
+
breaks=args.axes_ticks,
|
|
592
|
+
deraster=args.deraster,
|
|
593
|
+
vector_format=args.vector,
|
|
594
|
+
)
|
|
595
|
+
sys.exit(0)
|
|
563
596
|
|
|
564
597
|
# -----------INPUT SEQUENCE VALIDATION-----------
|
|
565
598
|
seq_list = []
|
|
599
|
+
fasta_list = args.fasta.copy()
|
|
566
600
|
for i in args.fasta:
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
601
|
+
try:
|
|
602
|
+
isValidFasta(i)
|
|
603
|
+
headers = getInputHeaders(i)
|
|
604
|
+
|
|
605
|
+
if len(headers) > 1:
|
|
606
|
+
print(f"File {i} contains multiple fasta entries.\n")
|
|
607
|
+
|
|
608
|
+
seq_list.extend(headers) # Add all headers to seq_list
|
|
609
|
+
|
|
610
|
+
except Exception as e:
|
|
611
|
+
print(
|
|
612
|
+
f"\nUnable to open {i}. Please check it is correctly formatted or compressed...\n"
|
|
613
|
+
)
|
|
614
|
+
fasta_list.remove(i)
|
|
576
615
|
|
|
577
616
|
# -----------LOAD SEQUENCES INTO MEMORY-----------
|
|
578
617
|
kmer_list = []
|
|
579
|
-
for i in
|
|
618
|
+
for i in fasta_list:
|
|
580
619
|
kmer_list.append(readKmersFromFile(i, args.kmer, False))
|
|
581
620
|
k_list = [item for sublist in kmer_list for item in sublist]
|
|
582
621
|
# Throw error if compare only selected with one sequence.
|
|
@@ -901,18 +940,6 @@ def main():
|
|
|
901
940
|
else:
|
|
902
941
|
seq_sparsity = 2 ** (int(math.log2(seq_sparsity - 1)) + 1)
|
|
903
942
|
expectation = round(win / seq_sparsity)
|
|
904
|
-
xaxis = 0
|
|
905
|
-
width = 0
|
|
906
|
-
"""if isinstance(args.xaxis, int) or args.xaxis == None:
|
|
907
|
-
xaxis = args.xaxis
|
|
908
|
-
else:
|
|
909
|
-
assert len(args.xaxis) == len(sequences)
|
|
910
|
-
xaxis = args.xaxis[i]"""
|
|
911
|
-
if isinstance(args.width, int):
|
|
912
|
-
width = args.width
|
|
913
|
-
else:
|
|
914
|
-
assert len(args.width) == len(sequences)
|
|
915
|
-
width = args.width[i]
|
|
916
943
|
|
|
917
944
|
print(f"Computing self identity matrix for {sequences[i][0]}... \n")
|
|
918
945
|
# TODO: Logging here
|
|
@@ -952,7 +979,7 @@ def main():
|
|
|
952
979
|
bedfile.write("\t".join(map(str, row)) + "\n")
|
|
953
980
|
print(f"Saved bed file to {bedfile_output}\n")
|
|
954
981
|
|
|
955
|
-
if not args.no_plot:
|
|
982
|
+
if (not args.no_plot) and (not args.grid_only):
|
|
956
983
|
create_plots(
|
|
957
984
|
sdf=[bed],
|
|
958
985
|
directory=args.output_dir if args.output_dir else ".",
|
|
@@ -961,7 +988,7 @@ def main():
|
|
|
961
988
|
palette=args.palette,
|
|
962
989
|
palette_orientation=args.palette_orientation,
|
|
963
990
|
no_hist=args.no_hist,
|
|
964
|
-
width=width,
|
|
991
|
+
width=args.width,
|
|
965
992
|
dpi=args.dpi,
|
|
966
993
|
is_freq=args.bin_freq,
|
|
967
994
|
xlim=args.axes_limits,
|
|
@@ -970,16 +997,22 @@ def main():
|
|
|
970
997
|
from_file=None,
|
|
971
998
|
is_pairwise=False,
|
|
972
999
|
axes_labels=args.axes_ticks,
|
|
1000
|
+
axes_tick_number=args.axes_number,
|
|
1001
|
+
vector_format=args.vector,
|
|
1002
|
+
deraster=args.deraster,
|
|
973
1003
|
)
|
|
974
1004
|
|
|
975
1005
|
# -----------COMPUTE COMPARATIVE PLOTS-----------
|
|
976
1006
|
# TODO: Optimize computations so that largest sequence doesn't need to be redone all the time
|
|
977
|
-
if (args.compare or args.compare_only) and len(
|
|
1007
|
+
if (args.compare or args.compare_only or args.grid or args.grid_only) and len(
|
|
1008
|
+
sequences
|
|
1009
|
+
) > 1:
|
|
978
1010
|
# Set window size to args.window. Otherwise, set it to n/resolution
|
|
979
1011
|
|
|
980
1012
|
if args.grid or args.grid_only:
|
|
981
1013
|
grid_val_doubles = []
|
|
982
1014
|
grid_val_double_names = []
|
|
1015
|
+
xlim_val_grid = 0
|
|
983
1016
|
|
|
984
1017
|
for i in range(len(sequences)):
|
|
985
1018
|
for j in range(i + 1, len(sequences)):
|
|
@@ -1060,7 +1093,7 @@ def main():
|
|
|
1060
1093
|
grid_val_double_names.append(
|
|
1061
1094
|
[larger_seq_name, smaller_seq_name]
|
|
1062
1095
|
)
|
|
1063
|
-
|
|
1096
|
+
xlim_val_grid = max(larger_length, xlim_val_grid)
|
|
1064
1097
|
if not args.no_bed:
|
|
1065
1098
|
# Log saving bed file
|
|
1066
1099
|
if not args.output_dir:
|
|
@@ -1083,7 +1116,7 @@ def main():
|
|
|
1083
1116
|
bedfile.write("\t".join(map(str, row)) + "\n")
|
|
1084
1117
|
print(f"Saved bed file to {bedfile_output}\n")
|
|
1085
1118
|
|
|
1086
|
-
if not args.no_plot:
|
|
1119
|
+
if (not args.no_plot) and (not args.grid_only):
|
|
1087
1120
|
create_plots(
|
|
1088
1121
|
sdf=[bed],
|
|
1089
1122
|
directory=args.output_dir if args.output_dir else ".",
|
|
@@ -1092,7 +1125,7 @@ def main():
|
|
|
1092
1125
|
palette=args.palette,
|
|
1093
1126
|
palette_orientation=args.palette_orientation,
|
|
1094
1127
|
no_hist=args.no_hist,
|
|
1095
|
-
width=
|
|
1128
|
+
width=args.width,
|
|
1096
1129
|
dpi=args.dpi,
|
|
1097
1130
|
is_freq=args.bin_freq,
|
|
1098
1131
|
xlim=args.axes_limits,
|
|
@@ -1101,6 +1134,9 @@ def main():
|
|
|
1101
1134
|
from_file=None,
|
|
1102
1135
|
is_pairwise=True,
|
|
1103
1136
|
axes_labels=args.axes_ticks,
|
|
1137
|
+
axes_tick_number=args.axes_number,
|
|
1138
|
+
vector_format=args.vector,
|
|
1139
|
+
deraster=args.deraster,
|
|
1104
1140
|
)
|
|
1105
1141
|
|
|
1106
1142
|
if args.grid or args.grid_only:
|
|
@@ -1111,15 +1147,18 @@ def main():
|
|
|
1111
1147
|
directory=args.output_dir if args.output_dir else ".",
|
|
1112
1148
|
palette=args.palette,
|
|
1113
1149
|
palette_orientation=args.palette_orientation,
|
|
1114
|
-
no_hist=args.no_hist,
|
|
1115
1150
|
single_names=grid_val_single_names,
|
|
1116
1151
|
double_names=grid_val_double_names,
|
|
1117
1152
|
is_freq=args.bin_freq,
|
|
1118
|
-
xlim=
|
|
1153
|
+
xlim=xlim_val_grid,
|
|
1119
1154
|
custom_colors=args.colors,
|
|
1120
1155
|
custom_breakpoints=args.axes_ticks,
|
|
1121
1156
|
axes_label=args.axes_ticks,
|
|
1122
1157
|
is_bed=False,
|
|
1158
|
+
width=args.width,
|
|
1159
|
+
breaks=args.axes_ticks,
|
|
1160
|
+
deraster=args.deraster,
|
|
1161
|
+
vector_format=args.vector,
|
|
1123
1162
|
)
|
|
1124
1163
|
|
|
1125
1164
|
|
|
@@ -7,6 +7,7 @@ import os
|
|
|
7
7
|
import pickle
|
|
8
8
|
import re
|
|
9
9
|
import numpy as np
|
|
10
|
+
import gzip
|
|
10
11
|
|
|
11
12
|
tab_b = bytes.maketrans(b"ACTG", b"TGAC")
|
|
12
13
|
|
|
@@ -43,7 +44,8 @@ def generateKmersFromFasta(seq: Sequence[str], k: int, quiet: bool) -> Iterable[
|
|
|
43
44
|
|
|
44
45
|
def isValidFasta(file_path):
|
|
45
46
|
try:
|
|
46
|
-
|
|
47
|
+
open_func = gzip.open if file_path.endswith(".gz") else open
|
|
48
|
+
with open_func(file_path, "rt") as file:
|
|
47
49
|
in_sequence = False
|
|
48
50
|
for line in file:
|
|
49
51
|
line = line.strip()
|
|
@@ -144,7 +146,10 @@ def readKmersFromFile(filename: str, ksize: int, quiet: bool) -> List[List[int]]
|
|
|
144
146
|
|
|
145
147
|
def getInputHeaders(filename: str) -> List[str]:
|
|
146
148
|
header_list = []
|
|
147
|
-
|
|
149
|
+
try:
|
|
150
|
+
seq = pysam.FastaFile(filename)
|
|
151
|
+
except OSError:
|
|
152
|
+
seq = None
|
|
148
153
|
for seq_id in seq.references:
|
|
149
154
|
header_list.append(seq_id)
|
|
150
155
|
|