Skip to content

Commit d38918f

Browse files
authored
Merge pull request #21 from marbl/dev_alt
0.8.1 release
2 parents ed190c7 + a73459a commit d38918f

File tree

7 files changed

+75
-32
lines changed

7 files changed

+75
-32
lines changed

README.md

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
[![Documentation Status](https://readthedocs.org/projects/moddotplot/badge/?version=latest)](https://moddotplot.readthedocs.io/en/latest/?badge=latest)
12
![](images/logo.png)
23

34
- [About](#about)
@@ -6,6 +7,7 @@
67
- [Interactive Mode](#interactive-mode)
78
- [Static Mode](#static-mode)
89
- [Standard arguments](#standard-arguments)
10+
- [Save matrix to file, but don't render plots. In interactive mode, this must be utlized with the `--save` flag.](#save-matrix-to-file-but-dont-render-plots-in-interactive-mode-this-must-be-utlized-with-the---save-flag)
911
- [Interactive Mode Commands](#interactive-mode-commands)
1012
- [Static Mode Commands](#static-mode-commands)
1113
- [Sample run - Interactive Mode](#sample-run---interactive-mode)
@@ -141,6 +143,8 @@ If set when 2 or more sequences are input into ModDotPlot, this will show an a v
141143
`--ambiguous <bool>`
142144
By default, k-mers that are homopolymers of ambiguous IUPAC codes (eg. NNNNNNNNNNN’s) are excluded from identity estimation. This results in gaps along the central diagonal for these regions. If desired, these can be kept by setting the `—-ambiguous` flag in both interactive and static mode.
143145

146+
`--no-plot <bool>`
147+
Save matrix to file, but don't render plots. In interactive mode, this must be utlized with the `--save` flag.
144148
---
145149

146150
### Interactive Mode Commands
@@ -151,7 +155,7 @@ Port to display ModDotPlot on. Default is 8050, this can be changed to any accep
151155

152156
`-w / --window <int>`
153157

154-
Minimum window size. By default, interactive mode sets a minimum window size based on the sequence length `n/2000` (eg. a 3Mbp sequence will have a 1500bp window). The maximum window size will always be set to `n/1000` (3000bp under the same example). This means that 2 matrices will be created. Creating more matrices will mean
158+
Minimum window size. By default, interactive mode sets a minimum window size based on the sequence length `n/2000` (eg. a 3Mbp sequence will have a 1500bp window). The maximum window size will always be set to `n/1000` (3000bp under the same example). This means that 2 matrices will be created.
155159

156160
`-q / --quick <bool>`
157161

@@ -185,10 +189,6 @@ Window size. Unlike interactive mode, only one matrix will be created, so this r
185189

186190
Skip output of bed file.
187191

188-
`--no-plot <bool>`
189-
190-
Skip output of pdf and png image files.
191-
192192
`--no-hist <bool>`
193193

194194
Skip output of histogram legend.
@@ -209,6 +209,10 @@ List of accepted palettes can be found [here](https://jiffyclub.github.io/palett
209209

210210
Flip sequential order of color palette. Set to `-` by default for divergent palettes.
211211

212+
`--color <list of hexcodes>`
213+
214+
List of custom colors in hexcode format can be entered sequentially, mapped from low to high identity.
215+
212216
`--breakpoints <list of ints>`
213217

214218
Add custom identity threshold breakpoints. Note that the number of breakpoints must be equal to the number of colors + 1.
@@ -278,7 +282,7 @@ ssh -N -f -L <LOCAL_PORT_NUMBER>:127.0.0.1:<HPC_PORT_NUMBER> [email protected]
278282

279283
You should now be able to view interactive mode using `http://127.0.0.1:<LOCAL_PORT_NUMBER>`. Note that your own HPC environment may have specific instructions and/or restrictions for setting up port forwarding.
280284

281-
VSCode now has automatic port forwarding built into the terminal menu. See [VSCode documentation](https://code.visualstudio.com/docs/editor/port-forwarding) for fruther details
285+
VSCode now has automatic port forwarding built into the terminal menu. See [VSCode documentation](https://code.visualstudio.com/docs/editor/port-forwarding) for further details
282286

283287
![](images/portforwarding.png)
284288

@@ -319,7 +323,7 @@ $ moddotplot static -c config/config.json
319323
| | | | (_) | (_| | | |__| | (_) | |_ | | | | (_) | |_
320324
|_| |_|\___/ \__,_| |_____/ \___/ \__| |_| |_|\___/ \__|
321325
322-
v0.8.0
326+
v0.8.1
323327
324328
Running ModDotPlot in static mode
325329
@@ -371,18 +375,17 @@ For bug reports or general usage questions, please raise a GitHub issue, or emai
371375

372376
## Known Issues
373377

374-
Plot width and xlim (limiting the x axis to a different amount) currently do not work. I plan to have those working in v0.9.0.
375-
376-
Mac users might encounter the following unexpected command line output:
378+
- Plot width and xlim (limiting the x axis to a different amount) currently do not work. I plan to have those working in v0.9.0.
377379

378-
`/bin/sh: lscpu: command not found`
379-
380-
This is a known issue with Plotnine, the Python plotting library used by ModDotPlot. This can be safely ignored.
380+
- 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.
381381

382+
- If you encounter an error with the following traceback: `rv = reductor(4) TypeError: cannot pickle 'generator' object`, ths 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`.
382383

384+
- In interactive mode, comparing sequences of two sizes will lead to errors in zooming for the larger sequence. I plan to fix this in v0.9.0.
385+
383386
---
384387

385388

386389
## Cite
387390

388-
Publication in progress!
391+
Publication in progress! (almost there :D)

images/logo.png

322 KB
Loading

pyproject.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@ dependencies = [
1111
"pandas",
1212
"plotly",
1313
"dash",
14-
"plotnine",
14+
"plotnine==0.12.4",
1515
"palettable",
1616
"mmh3",
1717
"tk",
18-
"setproctitle"
18+
"setproctitle",
19+
"sphinx_rtd_theme",
20+
"numpy==1.26.4"
1921
]
2022
authors = [
2123
{name = "Alex Sweeten", email = "[email protected]"},

src/moddotplot/const.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
VERSION = "0.8.0"
1+
VERSION = "0.8.1"
22
COLS = [
33
"#query_name",
44
"query_start",

src/moddotplot/estimate_identity.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,7 @@ def findValueInRange(integer: int, range_dict: dict) -> int:
510510
if key[0] >= integer >= key[1]:
511511
return value
512512
return highest_value
513+
513514

514515

515516
def setZoomLevels(axis_length, sparsity_layers):

src/moddotplot/interactive.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,29 @@ def run_dash(matrices, metadata, axes, sparsity, identity, port_number, output_d
7777
for i in range(len(metadata)):
7878
titles.append(metadata[i]["title"])
7979
# Get zooming thresholds, adjust sparsity respectively.
80-
mod_ranges = verifyModimizers(sparsity, len(image_pyramid))
81-
# TODO: This is probably wrong, look into it later
82-
mod_thresholds_list = setZoomLevels(round(metadata[0]["x_size"]), mod_ranges)
83-
80+
def halving_sequence(size, start):
81+
sequence = [start]
82+
for _ in range(1, size):
83+
start /= 2
84+
sequence.append(start)
85+
return sequence
86+
#print(current_metadata)
87+
mod_thresholds_list = halving_sequence(len(current_metadata["sparsities"]), current_metadata["x_size"])
88+
#print(mod_thresholds_list)
89+
90+
#print(current_metadata["min_window_size"]* current_metadata["resolution"])
91+
#print(current_metadata["max_window_size"])
92+
numo = round(math.log2(current_metadata['max_window_size']/current_metadata['min_window_size']) + 1)
93+
#print(numo)
8494
important = generateDictionaryFromList(mod_thresholds_list)
95+
#print(f"this is imprtant: {important}")
8596

8697
main_level = image_pyramid[0]
8798
main_x_axis = axes[0][0]
8899
main_y_axis = axes[0][1]
89100
main_x_axis_np = np.array(main_x_axis)
90101

102+
#TODO: modify value here
91103
main_x_axis_np += 3000
92104

93105
# Modify text so that hover shows interval format
@@ -1529,7 +1541,10 @@ def update_dotplot(
15291541
amount = x_end - x_begin
15301542

15311543
# This function finds the correct level in the image pyramid
1532-
zoom_factor = findValueInRange(amount, important)
1544+
try:
1545+
zoom_factor = findValueInRange(amount, important)
1546+
except ValueError as err:
1547+
zoom_factor = 0
15331548
# If zoom_factor is less than current_zoom, base tmp factors on the older amount
15341549

15351550
if zoom_factor > len(image_pyramid) - 1:

src/moddotplot/moddotplot.py

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@ def get_parser():
159159
help="Launch a quick, non-interactive version of interactive mode.",
160160
)
161161

162+
interactive_parser.add_argument(
163+
"--no-plot",
164+
action="store_true",
165+
help="Prevent launching dash after saving. Must be used in combination with --save.",
166+
)
167+
162168
# -----------STATIC MODE SUBCOMMANDS-----------
163169
static_input_group = static_parser.add_mutually_exclusive_group(required=True)
164170
static_input_group.add_argument(
@@ -533,7 +539,15 @@ def main():
533539
if args.window and args.quick:
534540
print(f"Conflict with `--quick` argument.")
535541
max_window_size = math.ceil(hgi / args.resolution)
536-
542+
# If only sequence is too small, throw an error.
543+
if max_window_size < 10:
544+
print(
545+
f"Error: sequence too small for analysis.\n"
546+
)
547+
print(
548+
f"ModDotPlot requires a minimum window size of 10. Sequences less than 10Kbp will not work with ModDotPlot under normal resolution. We recommend rerunning ModDotPlot with --r {math.ceil(hgi / 10)}.\n"
549+
)
550+
sys.exit(0)
537551
while min_window_size <= max_window_size:
538552
window_lengths.append(min_window_size)
539553
min_window_size = min_window_size * 2
@@ -553,18 +567,20 @@ def main():
553567

554568
# Set sparsity to be the closest power of 2
555569
sparsities = []
556-
if window_lengths[0] < args.modimizer:
557-
raise ValueError(
558-
"Minimum window size must be greater than or equal to the modimizer sketch size"
559-
)
560-
sparsities.append(round(window_lengths[0] / args.modimizer))
570+
if window_lengths[0] < 1000:
571+
sparsities.append(1)
572+
else:
573+
sparsities.append(round(window_lengths[0] / args.modimizer))
561574
if sparsities[0] <= args.modimizer:
562575
sparsities[0] = 2 ** int(math.log2(sparsities[0]))
563576
else:
564577
sparsities[0] = 2 ** (int(math.log2(sparsities[0] - 1)) + 1)
565578
# expectation = round(win/seq_sparsity)
566579
for i in range(1, len(window_lengths)):
567-
sparsities.append(sparsities[-1] * 2)
580+
if window_lengths[i] > 1000:
581+
sparsities.append(sparsities[-1] * 2)
582+
else:
583+
sparsities.append(1)
568584
expectation = round(window_lengths[-1] / sparsities[-1])
569585
matrices = []
570586
metadata = []
@@ -632,6 +648,7 @@ def main():
632648
"resolution": args.resolution,
633649
"kmer_length": args.kmer,
634650
"title": f"{seq_list[j]}",
651+
"sparsities": sparsities,
635652
}
636653
)
637654
# -----------BUILD IMAGE PYRAMID FOR COMPARATIVE MATRICES-----------
@@ -653,11 +670,11 @@ def main():
653670
smaller_seq = k_list[0]
654671
if args.quick:
655672
print(
656-
f"Quickly building pairwise matrices for {seq_list[i]} and {seq_list[j]}, using a window size of {window_lengths[0]}.... \n"
673+
f"Quickly building pairwise matrices for {seq_list[0]} and {seq_list[1]}, using a window size of {window_lengths[0]}.... \n"
657674
)
658675
else:
659676
print(
660-
f"Building pairwise matrices for {seq_list[i]} and {seq_list[j]}, using a minimum window size of {window_lengths[0]}.... \n"
677+
f"Building pairwise matrices for {seq_list[0]} and {seq_list[1]}, using a minimum window size of {window_lengths[0]}.... \n"
661678
)
662679
image_pyramid = []
663680
for i in range(len(window_lengths)):
@@ -725,6 +742,7 @@ def main():
725742
"resolution": args.resolution,
726743
"kmer_length": args.kmer,
727744
"title": f"{larger_name}-{smaller_name}",
745+
"sparsities": sparsities,
728746
}
729747
)
730748

@@ -752,7 +770,11 @@ def main():
752770
# Save the dictionary as a pickle file
753771
with open(pickle_path, "wb") as f:
754772
pickle.dump(metadata, f)
755-
# Finally gzip the folder
773+
# Check if no plot arg is used
774+
if args.no_plot:
775+
print(f"Saved matrices to {folder_path}. Thank you for using ModDotPlot!\n")
776+
sys.exit(0)
777+
756778

757779
# Before running dash, change into intervals...
758780
axes = []

0 commit comments

Comments
 (0)