ModDotPlot 0.9.7__tar.gz → 0.9.9__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ModDotPlot
3
- Version: 0.9.7
3
+ Version: 0.9.9
4
4
  Author: Michael Schatz, Adam Phillippy
5
5
  Author-email: Alex Sweeten <alex.sweeten@nih.gov>
6
6
  Maintainer-email: Alex Sweeten <alex.sweeten@nih.gov>
@@ -87,11 +87,11 @@ If you use ModDotPlot for your research, please cite our software!
87
87
 
88
88
  ## About
89
89
 
90
- _ModDotPlot_ is a dot plot visualization tool designed for large sequences and whole genomes. _ModDotPlot_ is the spiritual successor to [StainedGlass](https://mrvollger.github.io/StainedGlass/). The core algorithm breaks an input sequence down into intervals of sketched *k*-mers called **mod**imizers, and rapidly approximating the Average Nucleotide Identity between pairwise combinations of these intervals. This significantly reduces the computational time required to produce these plots, enough to view multiple layers of resolution in real time!
90
+ _ModDotPlot_ is a dot plot visualization tool designed to be used at scale, both for smaller sequences and whole genomes. _ModDotPlot_ is the spiritual successor to [StainedGlass](https://mrvollger.github.io/StainedGlass/). The core algorithm breaks an input sequence down into intervals of sketched *k*-mers called **mod**imizers. This enables the rapid approximation of the Average Nucleotide Identity between combinations of intervals!
91
91
 
92
92
  ![](images/demo.gif)
93
93
 
94
- If you're interested in learning more about ModDotPlot and tandem repeats, you can watch my in-depth [YouTube video tutorial](https://www.youtube.com/watch?v=_7sQaljB_ys&t=2321s&pp=ygUXYWxleCBzd2VldGVuIG1vZGRvdHBsb3Q%3D) from the [BioDiversity Genomics Academy](https://thebgacademy.org).
94
+ If you're interested in learning more about _ModDotPlot_ and how to visualize tandem repeats, we have an in-depth [YouTube video tutorial](https://www.youtube.com/watch?v=_7sQaljB_ys&t=2321s&pp=ygUXYWxleCBzd2VldGVuIG1vZGRvdHBsb3Q%3D) hosted by the [BioDiversity Genomics Academy](https://thebgacademy.org).
95
95
 
96
96
  ---
97
97
 
@@ -126,11 +126,11 @@ Finally, confirm that the installation was installed correctly and that your ver
126
126
  | | | | (_) | (_| | | |__| | (_) | |_ | | | | (_) | |_
127
127
  |_| |_|\___/ \__,_| |_____/ \___/ \__| |_| |_|\___/ \__|
128
128
 
129
- v0.9.7
129
+ v0.9.8
130
130
 
131
131
  usage: moddotplot [-h] {interactive,static} ...
132
132
 
133
- ModDotPlot: Visualization of Complex Repeat Structures
133
+ ModDotPlot: Visualization of Tandem Repeats
134
134
 
135
135
  positional arguments:
136
136
  {interactive,static} Choose mode: interactive or static
@@ -138,8 +138,11 @@ positional arguments:
138
138
  static Static mode commands
139
139
 
140
140
  options:
141
- -h, --help show this help message and exit`
141
+ -h, --help show this help message and exit
142
142
  ```
143
+
144
+ Note that running `moddotplot -h` might take a while at first! This is because the Python interpreter is compiling source code into the __pycache__ directory. Subsequent runs will use the pre-compiled code and load much faster!
145
+
143
146
  ---
144
147
 
145
148
  ## Usage
@@ -171,7 +174,7 @@ _ModDotPlot_ supports highly customizable plotting features in static mode. See
171
174
  moddotplot interactive <ARGS>
172
175
  ```
173
176
 
174
- Running _ModDotPlot_ in interactive mode will launch a [Dash application](https://plotly.com/dash/) on your machine's localhost. Open any web browser and go to `http://127.0.0.1:<PORT_NUMBER>` to view the interactive plot (this should happen automatically, but depending on your environment you might need to copy and paste this URL into your web browser). Running `Ctrl+C` on the command line will exit the Dash application. The default port number used by Dash is `8050`, but this can be customized using the `--port` command (see [interactive mode commands](#interactive-mode-commands) for further info).
177
+ Running _ModDotPlot_ in interactive mode will launch a [Dash application](https://plotly.com/dash/) on your machine's localhost. Open any web browser and go to `http://127.0.0.1:<PORT_NUMBER>` to view the interactive plot (this should happen automatically, but depending on your environment you might need to copy and paste this URL into your web browser). Running `Ctrl+C` on the command line will exit the Dash application. The default port number used by Dash is `8050`, but this can be customized using the `--port` command (see [interactive mode commands](#interactive-mode-commands) for further info, and [Sample run - Port Forwarding](#sample-run---port-forwarding) for tips on running interactive mode on an HPC environment).
175
178
 
176
179
  ---
177
180
 
@@ -207,6 +210,10 @@ Each partition takes into account a fraction of its neighboring partitions k-mer
207
210
 
208
211
  Modimizer sketch size. Must be lower than window size `w`. A lower sketch size means less k-mers to compare (and faster runtime), at the expense of lower accuracy. Recommended to be kept >= 1000.
209
212
 
213
+ `--forward <bool>`
214
+
215
+ Use forward k-mers only, instead of the default of canonical k-mers. Warning: this will give strand specific output.
216
+
210
217
  `-r / --resolution <int>`
211
218
 
212
219
  Dotplot resolution. This corresponds to the number of windows each input sequence is partitioned into. Default is 1000. Overrides the `--window` parameter.
@@ -275,9 +282,17 @@ By default, vectorized outputs rasterize the actual dotplot (not the axis). This
275
282
 
276
283
  Window size. Unlike interactive mode, only one matrix will be created, so this represents the *only* window size. Default is set to `n/1000` (eg. 3000bp for a 3Mbp sequence).
277
284
 
285
+ `--region <list of strs>`
286
+
287
+ Plot only a particular range for a given sequence. Syntax is UCSC style (chr:start-end).
288
+
278
289
  `--palette <str>`
279
290
 
280
- List of accepted palettes can be found [here](https://jiffyclub.github.io/palettable/colorbrewer/). The syntax is to have the name of the palette, followed by an underscore with the number of colors, eg. `OrRd_8`. Default is `Spectral_11`.
291
+ List of accepted palettes can be found [here](https://jiffyclub.github.io/palettable/colorbrewer/). Palettes are segregated into 3 types: _Diverging_, _Qualitative_, and _Sequential_. Syntax is the name of the palette, followed by an underscore and the number of colors, eg. `OrRd_8`. Default is `Spectral_11`.
292
+
293
+ `--breakpoints <list of ints>`
294
+
295
+ Add custom identity threshold breakpoints. Note that the number of breakpoints must be equal to the number of colors + 1, otherwise an error will occur.
281
296
 
282
297
  `--palette-orientation <bool>`
283
298
 
@@ -287,10 +302,6 @@ Flip sequential order of color palette. Set to `-` by default for divergent pale
287
302
 
288
303
  List of custom colors in hexcode format can be entered sequentially, mapped from low to high identity.
289
304
 
290
- `--breakpoints <list of ints>`
291
-
292
- Add custom identity threshold breakpoints. Note that the number of breakpoints must be equal to the number of colors + 1.
293
-
294
305
  `-t / --axes-ticks <list of ints>`
295
306
 
296
307
  Custom tickmarks for x and y axis. Values outside of the `--axes-limits` will not be shown.
@@ -515,3 +526,5 @@ For bug reports or general usage questions, please raise a GitHub issue, or emai
515
526
  - 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.
516
527
 
517
528
  - 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`.
529
+
530
+ - The error ` UserWarning: h5py is running against HDF5 1.xx.x when it was built against 1.xx.x, this may cause problems` is due to the h5py library used by cooler having conflicting versions in the dependency tree. This can also be safely ignored, but if you want to remove this message run `pip uninstall -y h5py` `pip install --no-binary=h5py h5py`
@@ -35,11 +35,11 @@ If you use ModDotPlot for your research, please cite our software!
35
35
 
36
36
  ## About
37
37
 
38
- _ModDotPlot_ is a dot plot visualization tool designed for large sequences and whole genomes. _ModDotPlot_ is the spiritual successor to [StainedGlass](https://mrvollger.github.io/StainedGlass/). The core algorithm breaks an input sequence down into intervals of sketched *k*-mers called **mod**imizers, and rapidly approximating the Average Nucleotide Identity between pairwise combinations of these intervals. This significantly reduces the computational time required to produce these plots, enough to view multiple layers of resolution in real time!
38
+ _ModDotPlot_ is a dot plot visualization tool designed to be used at scale, both for smaller sequences and whole genomes. _ModDotPlot_ is the spiritual successor to [StainedGlass](https://mrvollger.github.io/StainedGlass/). The core algorithm breaks an input sequence down into intervals of sketched *k*-mers called **mod**imizers. This enables the rapid approximation of the Average Nucleotide Identity between combinations of intervals!
39
39
 
40
40
  ![](images/demo.gif)
41
41
 
42
- If you're interested in learning more about ModDotPlot and tandem repeats, you can watch my in-depth [YouTube video tutorial](https://www.youtube.com/watch?v=_7sQaljB_ys&t=2321s&pp=ygUXYWxleCBzd2VldGVuIG1vZGRvdHBsb3Q%3D) from the [BioDiversity Genomics Academy](https://thebgacademy.org).
42
+ If you're interested in learning more about _ModDotPlot_ and how to visualize tandem repeats, we have an in-depth [YouTube video tutorial](https://www.youtube.com/watch?v=_7sQaljB_ys&t=2321s&pp=ygUXYWxleCBzd2VldGVuIG1vZGRvdHBsb3Q%3D) hosted by the [BioDiversity Genomics Academy](https://thebgacademy.org).
43
43
 
44
44
  ---
45
45
 
@@ -74,11 +74,11 @@ Finally, confirm that the installation was installed correctly and that your ver
74
74
  | | | | (_) | (_| | | |__| | (_) | |_ | | | | (_) | |_
75
75
  |_| |_|\___/ \__,_| |_____/ \___/ \__| |_| |_|\___/ \__|
76
76
 
77
- v0.9.7
77
+ v0.9.8
78
78
 
79
79
  usage: moddotplot [-h] {interactive,static} ...
80
80
 
81
- ModDotPlot: Visualization of Complex Repeat Structures
81
+ ModDotPlot: Visualization of Tandem Repeats
82
82
 
83
83
  positional arguments:
84
84
  {interactive,static} Choose mode: interactive or static
@@ -86,8 +86,11 @@ positional arguments:
86
86
  static Static mode commands
87
87
 
88
88
  options:
89
- -h, --help show this help message and exit`
89
+ -h, --help show this help message and exit
90
90
  ```
91
+
92
+ Note that running `moddotplot -h` might take a while at first! This is because the Python interpreter is compiling source code into the __pycache__ directory. Subsequent runs will use the pre-compiled code and load much faster!
93
+
91
94
  ---
92
95
 
93
96
  ## Usage
@@ -119,7 +122,7 @@ _ModDotPlot_ supports highly customizable plotting features in static mode. See
119
122
  moddotplot interactive <ARGS>
120
123
  ```
121
124
 
122
- Running _ModDotPlot_ in interactive mode will launch a [Dash application](https://plotly.com/dash/) on your machine's localhost. Open any web browser and go to `http://127.0.0.1:<PORT_NUMBER>` to view the interactive plot (this should happen automatically, but depending on your environment you might need to copy and paste this URL into your web browser). Running `Ctrl+C` on the command line will exit the Dash application. The default port number used by Dash is `8050`, but this can be customized using the `--port` command (see [interactive mode commands](#interactive-mode-commands) for further info).
125
+ Running _ModDotPlot_ in interactive mode will launch a [Dash application](https://plotly.com/dash/) on your machine's localhost. Open any web browser and go to `http://127.0.0.1:<PORT_NUMBER>` to view the interactive plot (this should happen automatically, but depending on your environment you might need to copy and paste this URL into your web browser). Running `Ctrl+C` on the command line will exit the Dash application. The default port number used by Dash is `8050`, but this can be customized using the `--port` command (see [interactive mode commands](#interactive-mode-commands) for further info, and [Sample run - Port Forwarding](#sample-run---port-forwarding) for tips on running interactive mode on an HPC environment).
123
126
 
124
127
  ---
125
128
 
@@ -155,6 +158,10 @@ Each partition takes into account a fraction of its neighboring partitions k-mer
155
158
 
156
159
  Modimizer sketch size. Must be lower than window size `w`. A lower sketch size means less k-mers to compare (and faster runtime), at the expense of lower accuracy. Recommended to be kept >= 1000.
157
160
 
161
+ `--forward <bool>`
162
+
163
+ Use forward k-mers only, instead of the default of canonical k-mers. Warning: this will give strand specific output.
164
+
158
165
  `-r / --resolution <int>`
159
166
 
160
167
  Dotplot resolution. This corresponds to the number of windows each input sequence is partitioned into. Default is 1000. Overrides the `--window` parameter.
@@ -223,9 +230,17 @@ By default, vectorized outputs rasterize the actual dotplot (not the axis). This
223
230
 
224
231
  Window size. Unlike interactive mode, only one matrix will be created, so this represents the *only* window size. Default is set to `n/1000` (eg. 3000bp for a 3Mbp sequence).
225
232
 
233
+ `--region <list of strs>`
234
+
235
+ Plot only a particular range for a given sequence. Syntax is UCSC style (chr:start-end).
236
+
226
237
  `--palette <str>`
227
238
 
228
- List of accepted palettes can be found [here](https://jiffyclub.github.io/palettable/colorbrewer/). The syntax is to have the name of the palette, followed by an underscore with the number of colors, eg. `OrRd_8`. Default is `Spectral_11`.
239
+ List of accepted palettes can be found [here](https://jiffyclub.github.io/palettable/colorbrewer/). Palettes are segregated into 3 types: _Diverging_, _Qualitative_, and _Sequential_. Syntax is the name of the palette, followed by an underscore and the number of colors, eg. `OrRd_8`. Default is `Spectral_11`.
240
+
241
+ `--breakpoints <list of ints>`
242
+
243
+ Add custom identity threshold breakpoints. Note that the number of breakpoints must be equal to the number of colors + 1, otherwise an error will occur.
229
244
 
230
245
  `--palette-orientation <bool>`
231
246
 
@@ -235,10 +250,6 @@ Flip sequential order of color palette. Set to `-` by default for divergent pale
235
250
 
236
251
  List of custom colors in hexcode format can be entered sequentially, mapped from low to high identity.
237
252
 
238
- `--breakpoints <list of ints>`
239
-
240
- Add custom identity threshold breakpoints. Note that the number of breakpoints must be equal to the number of colors + 1.
241
-
242
253
  `-t / --axes-ticks <list of ints>`
243
254
 
244
255
  Custom tickmarks for x and y axis. Values outside of the `--axes-limits` will not be shown.
@@ -463,3 +474,5 @@ For bug reports or general usage questions, please raise a GitHub issue, or emai
463
474
  - 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.
464
475
 
465
476
  - 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`.
477
+
478
+ - The error ` UserWarning: h5py is running against HDF5 1.xx.x when it was built against 1.xx.x, this may cause problems` is due to the h5py library used by cooler having conflicting versions in the dependency tree. This can also be safely ignored, but if you want to remove this message run `pip uninstall -y h5py` `pip install --no-binary=h5py h5py`
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ModDotPlot"
7
- version = "0.9.7"
7
+ version = "0.9.9"
8
8
  requires-python = ">= 3.7"
9
9
  dependencies = [
10
10
  "pysam",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ModDotPlot
3
- Version: 0.9.7
3
+ Version: 0.9.9
4
4
  Author: Michael Schatz, Adam Phillippy
5
5
  Author-email: Alex Sweeten <alex.sweeten@nih.gov>
6
6
  Maintainer-email: Alex Sweeten <alex.sweeten@nih.gov>
@@ -87,11 +87,11 @@ If you use ModDotPlot for your research, please cite our software!
87
87
 
88
88
  ## About
89
89
 
90
- _ModDotPlot_ is a dot plot visualization tool designed for large sequences and whole genomes. _ModDotPlot_ is the spiritual successor to [StainedGlass](https://mrvollger.github.io/StainedGlass/). The core algorithm breaks an input sequence down into intervals of sketched *k*-mers called **mod**imizers, and rapidly approximating the Average Nucleotide Identity between pairwise combinations of these intervals. This significantly reduces the computational time required to produce these plots, enough to view multiple layers of resolution in real time!
90
+ _ModDotPlot_ is a dot plot visualization tool designed to be used at scale, both for smaller sequences and whole genomes. _ModDotPlot_ is the spiritual successor to [StainedGlass](https://mrvollger.github.io/StainedGlass/). The core algorithm breaks an input sequence down into intervals of sketched *k*-mers called **mod**imizers. This enables the rapid approximation of the Average Nucleotide Identity between combinations of intervals!
91
91
 
92
92
  ![](images/demo.gif)
93
93
 
94
- If you're interested in learning more about ModDotPlot and tandem repeats, you can watch my in-depth [YouTube video tutorial](https://www.youtube.com/watch?v=_7sQaljB_ys&t=2321s&pp=ygUXYWxleCBzd2VldGVuIG1vZGRvdHBsb3Q%3D) from the [BioDiversity Genomics Academy](https://thebgacademy.org).
94
+ If you're interested in learning more about _ModDotPlot_ and how to visualize tandem repeats, we have an in-depth [YouTube video tutorial](https://www.youtube.com/watch?v=_7sQaljB_ys&t=2321s&pp=ygUXYWxleCBzd2VldGVuIG1vZGRvdHBsb3Q%3D) hosted by the [BioDiversity Genomics Academy](https://thebgacademy.org).
95
95
 
96
96
  ---
97
97
 
@@ -126,11 +126,11 @@ Finally, confirm that the installation was installed correctly and that your ver
126
126
  | | | | (_) | (_| | | |__| | (_) | |_ | | | | (_) | |_
127
127
  |_| |_|\___/ \__,_| |_____/ \___/ \__| |_| |_|\___/ \__|
128
128
 
129
- v0.9.7
129
+ v0.9.8
130
130
 
131
131
  usage: moddotplot [-h] {interactive,static} ...
132
132
 
133
- ModDotPlot: Visualization of Complex Repeat Structures
133
+ ModDotPlot: Visualization of Tandem Repeats
134
134
 
135
135
  positional arguments:
136
136
  {interactive,static} Choose mode: interactive or static
@@ -138,8 +138,11 @@ positional arguments:
138
138
  static Static mode commands
139
139
 
140
140
  options:
141
- -h, --help show this help message and exit`
141
+ -h, --help show this help message and exit
142
142
  ```
143
+
144
+ Note that running `moddotplot -h` might take a while at first! This is because the Python interpreter is compiling source code into the __pycache__ directory. Subsequent runs will use the pre-compiled code and load much faster!
145
+
143
146
  ---
144
147
 
145
148
  ## Usage
@@ -171,7 +174,7 @@ _ModDotPlot_ supports highly customizable plotting features in static mode. See
171
174
  moddotplot interactive <ARGS>
172
175
  ```
173
176
 
174
- Running _ModDotPlot_ in interactive mode will launch a [Dash application](https://plotly.com/dash/) on your machine's localhost. Open any web browser and go to `http://127.0.0.1:<PORT_NUMBER>` to view the interactive plot (this should happen automatically, but depending on your environment you might need to copy and paste this URL into your web browser). Running `Ctrl+C` on the command line will exit the Dash application. The default port number used by Dash is `8050`, but this can be customized using the `--port` command (see [interactive mode commands](#interactive-mode-commands) for further info).
177
+ Running _ModDotPlot_ in interactive mode will launch a [Dash application](https://plotly.com/dash/) on your machine's localhost. Open any web browser and go to `http://127.0.0.1:<PORT_NUMBER>` to view the interactive plot (this should happen automatically, but depending on your environment you might need to copy and paste this URL into your web browser). Running `Ctrl+C` on the command line will exit the Dash application. The default port number used by Dash is `8050`, but this can be customized using the `--port` command (see [interactive mode commands](#interactive-mode-commands) for further info, and [Sample run - Port Forwarding](#sample-run---port-forwarding) for tips on running interactive mode on an HPC environment).
175
178
 
176
179
  ---
177
180
 
@@ -207,6 +210,10 @@ Each partition takes into account a fraction of its neighboring partitions k-mer
207
210
 
208
211
  Modimizer sketch size. Must be lower than window size `w`. A lower sketch size means less k-mers to compare (and faster runtime), at the expense of lower accuracy. Recommended to be kept >= 1000.
209
212
 
213
+ `--forward <bool>`
214
+
215
+ Use forward k-mers only, instead of the default of canonical k-mers. Warning: this will give strand specific output.
216
+
210
217
  `-r / --resolution <int>`
211
218
 
212
219
  Dotplot resolution. This corresponds to the number of windows each input sequence is partitioned into. Default is 1000. Overrides the `--window` parameter.
@@ -275,9 +282,17 @@ By default, vectorized outputs rasterize the actual dotplot (not the axis). This
275
282
 
276
283
  Window size. Unlike interactive mode, only one matrix will be created, so this represents the *only* window size. Default is set to `n/1000` (eg. 3000bp for a 3Mbp sequence).
277
284
 
285
+ `--region <list of strs>`
286
+
287
+ Plot only a particular range for a given sequence. Syntax is UCSC style (chr:start-end).
288
+
278
289
  `--palette <str>`
279
290
 
280
- List of accepted palettes can be found [here](https://jiffyclub.github.io/palettable/colorbrewer/). The syntax is to have the name of the palette, followed by an underscore with the number of colors, eg. `OrRd_8`. Default is `Spectral_11`.
291
+ List of accepted palettes can be found [here](https://jiffyclub.github.io/palettable/colorbrewer/). Palettes are segregated into 3 types: _Diverging_, _Qualitative_, and _Sequential_. Syntax is the name of the palette, followed by an underscore and the number of colors, eg. `OrRd_8`. Default is `Spectral_11`.
292
+
293
+ `--breakpoints <list of ints>`
294
+
295
+ Add custom identity threshold breakpoints. Note that the number of breakpoints must be equal to the number of colors + 1, otherwise an error will occur.
281
296
 
282
297
  `--palette-orientation <bool>`
283
298
 
@@ -287,10 +302,6 @@ Flip sequential order of color palette. Set to `-` by default for divergent pale
287
302
 
288
303
  List of custom colors in hexcode format can be entered sequentially, mapped from low to high identity.
289
304
 
290
- `--breakpoints <list of ints>`
291
-
292
- Add custom identity threshold breakpoints. Note that the number of breakpoints must be equal to the number of colors + 1.
293
-
294
305
  `-t / --axes-ticks <list of ints>`
295
306
 
296
307
  Custom tickmarks for x and y axis. Values outside of the `--axes-limits` will not be shown.
@@ -515,3 +526,5 @@ For bug reports or general usage questions, please raise a GitHub issue, or emai
515
526
  - 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.
516
527
 
517
528
  - 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`.
529
+
530
+ - The error ` UserWarning: h5py is running against HDF5 1.xx.x when it was built against 1.xx.x, this may cause problems` is due to the h5py library used by cooler having conflicting versions in the dependency tree. This can also be safely ignored, but if you want to remove this message run `pip uninstall -y h5py` `pip install --no-binary=h5py h5py`
@@ -1,4 +1,4 @@
1
- VERSION = "0.9.7"
1
+ VERSION = "0.9.9"
2
2
  COLS = [
3
3
  "#query_name",
4
4
  "query_start",
@@ -141,8 +141,10 @@ def partitionOverlaps(
141
141
  kmer_list.append(lst[final_start_index:seq_len])
142
142
 
143
143
  # Test that last value was added on correctly
144
-
145
- assert kmer_list[-1][-1] == lst[-1]
144
+ try:
145
+ assert kmer_list[-1][-1] == lst[-1]
146
+ except (AssertionError, IndexError) as e:
147
+ print(f"Error: Last k-mer does not match original sequence: {e}\n")
146
148
  return kmer_list
147
149
 
148
150
 
@@ -352,6 +354,9 @@ def selfContainmentMatrix(
352
354
  n = len(mod_set)
353
355
  progress_thresholds = round(n / 77)
354
356
 
357
+ if progress_thresholds == 0:
358
+ progress_thresholds = 1
359
+
355
360
  printProgressBar(0, n, prefix="Progress:", suffix="Complete", length=40)
356
361
  containment_matrix = np.empty((n, n))
357
362
 
@@ -410,6 +415,8 @@ def pairwiseContainmentMatrix(
410
415
  """
411
416
  n = max(len(mod_set_y), len(mod_set_x))
412
417
  progress_thresholds = round(n / 77)
418
+ if progress_thresholds == 0:
419
+ progress_thresholds = 1
413
420
 
414
421
  if not supress_progress:
415
422
  printProgressBar(0, n, prefix="Progress:", suffix="Complete", length=40)
@@ -28,7 +28,6 @@ import json
28
28
  import numpy as np
29
29
  import pickle
30
30
  import os
31
- import cooler
32
31
 
33
32
 
34
33
  def get_parser():
@@ -230,6 +229,13 @@ def get_parser():
230
229
  help="Window size, or the length in genomic coordinates of each interval. Default is set to (genome length)/(resolution)",
231
230
  )
232
231
 
232
+ static_parser.add_argument(
233
+ "--region",
234
+ default=None,
235
+ help="Genomic region to analyze. Syntax is seq_id:start-end (e.g. chr1:100000-200000).",
236
+ nargs="+",
237
+ )
238
+
233
239
  static_parser.add_argument(
234
240
  "-id",
235
241
  "--identity",
@@ -310,6 +316,18 @@ def get_parser():
310
316
  type=str,
311
317
  )
312
318
 
319
+ static_parser.add_argument(
320
+ "--forward",
321
+ action="store_true",
322
+ help="Enforce forward only k-mers instead of canonical k-mers. Warning: only use if you want strand-specific output!",
323
+ )
324
+
325
+ static_parser.add_argument(
326
+ "--plot-direction",
327
+ action="store_true",
328
+ help="Create a plot containing the direction of each k-mer array (relative to the first array). Arrays with inversions will be highlighted in blue (forward) and pink (reverse).",
329
+ )
330
+
313
331
  static_parser.add_argument(
314
332
  "--colors",
315
333
  default=None,
@@ -405,7 +423,6 @@ def main():
405
423
  axes = []
406
424
  for i in range(len(matrices)):
407
425
  matrix_axes = []
408
- counter = 0
409
426
  for matrix in matrices[i]:
410
427
  x_axis = [
411
428
  j * round(metadata[i]["x_size"] / matrix.shape[0])
@@ -630,7 +647,10 @@ def main():
630
647
  # -----------LOAD SEQUENCES INTO MEMORY-----------
631
648
  kmer_list = []
632
649
  for i in fasta_list:
633
- kmer_list.append(readKmersFromFile(i, args.kmer, False))
650
+ if args.forward:
651
+ kmer_list.append(readKmersFromFile(i, args.kmer, False, True))
652
+ else:
653
+ kmer_list.append(readKmersFromFile(i, args.kmer, False, False))
634
654
  k_list = [item for sublist in kmer_list for item in sublist]
635
655
  # Throw error if compare only selected with one sequence.
636
656
  if len(k_list) < 2 and args.compare_only:
@@ -937,6 +957,48 @@ def main():
937
957
  seq_length = len(sequences[i][1])
938
958
  seq_name = sequences[i][0]
939
959
  seq_range = extractRegion(seq_name)
960
+ if seq_range:
961
+ seq_name = seq_range[0]
962
+ # If region, then I only want to use the subsequence.
963
+ try:
964
+ if args.region:
965
+ subseq_start_pos = None
966
+ subseq_end_pos = None
967
+ for region in args.region:
968
+ chrom, lower_bound, upper_bound = extractRegion(region)
969
+ if chrom == seq_name:
970
+ subseq_start_pos = lower_bound
971
+ subseq_end_pos = upper_bound
972
+ seq_start_pos = lower_bound
973
+ # Validate bounds
974
+ if subseq_start_pos < 1 or subseq_end_pos > seq_length:
975
+ print(
976
+ f"Error: region {region} is out of bounds for {seq_name}. Will use entire sequence.\n"
977
+ )
978
+ subseq_start_pos = 1
979
+ subseq_end_pos = seq_length
980
+ seq_name = sequences[i][0]
981
+ break
982
+ print(
983
+ f"Using region {seq_name}:{subseq_start_pos}-{subseq_end_pos}\n"
984
+ )
985
+ # Change sequence length, and use a subsequence instead.
986
+ seq_length = (
987
+ subseq_end_pos - subseq_start_pos + 1 - args.kmer
988
+ )
989
+ seq_range = seq_name, subseq_start_pos, subseq_end_pos
990
+ seq_name = (
991
+ f"{seq_name}:{subseq_start_pos}-{subseq_end_pos}"
992
+ )
993
+ if not subseq_end_pos or not subseq_start_pos:
994
+ print(
995
+ f"Error: region {args.region} not found in {seq_name}. Will use entire sequence.\n"
996
+ )
997
+ seq_range = None
998
+ except Exception as e:
999
+ print(
1000
+ f"Error obtaining region for {seq_name}. Will use entire sequence: {e}\n"
1001
+ )
940
1002
  if not seq_range:
941
1003
  seq_start_pos = 1
942
1004
  else:
@@ -972,17 +1034,33 @@ def main():
972
1034
  print(f"\tWindow size w: {win}\n")
973
1035
  print(f"\tModimizer sketch size: {expectation}\n")
974
1036
  print(f"\tPlot Resolution r: {res}\n")
975
- self_mat = createSelfMatrix(
976
- seq_length,
977
- sequences[i][1],
978
- win,
979
- seq_sparsity,
980
- args.delta,
981
- args.kmer,
982
- args.identity,
983
- args.ambiguous,
984
- expectation,
985
- )
1037
+ if args.region and seq_range:
1038
+ subseq = sequences[i][1][
1039
+ subseq_start_pos : (subseq_end_pos - args.kmer + 1)
1040
+ ]
1041
+ self_mat = createSelfMatrix(
1042
+ seq_length,
1043
+ subseq,
1044
+ win,
1045
+ seq_sparsity,
1046
+ args.delta,
1047
+ args.kmer,
1048
+ args.identity,
1049
+ args.ambiguous,
1050
+ expectation,
1051
+ )
1052
+ else:
1053
+ self_mat = createSelfMatrix(
1054
+ seq_length,
1055
+ sequences[i][1],
1056
+ win,
1057
+ seq_sparsity,
1058
+ args.delta,
1059
+ args.kmer,
1060
+ args.identity,
1061
+ args.ambiguous,
1062
+ expectation,
1063
+ )
986
1064
  bed = convertMatrixToBed(
987
1065
  self_mat,
988
1066
  win,
@@ -1093,11 +1171,96 @@ def main():
1093
1171
  larger_seq_start_pos = 1
1094
1172
  else:
1095
1173
  larger_seq_start_pos = int(larger_seq_range[1])
1174
+ larger_seq_name = larger_seq_range[0]
1096
1175
  smaller_seq_range = extractRegion(smaller_seq_name)
1097
- if not larger_seq_range:
1176
+ if not smaller_seq_range:
1098
1177
  smaller_seq_start_pos = 1
1099
1178
  else:
1100
1179
  smaller_seq_start_pos = int(smaller_seq_range[1])
1180
+ smaller_seq_name = smaller_seq_range[0]
1181
+
1182
+ try:
1183
+ if args.region:
1184
+ subseq_start_pos = None
1185
+ subseq_end_pos = None
1186
+ for region in args.region:
1187
+ chrom, lower_bound, upper_bound = extractRegion(region)
1188
+ if chrom == larger_seq_name:
1189
+ larger_subseq_start_pos = lower_bound
1190
+ larger_subseq_end_pos = upper_bound
1191
+ larger_seq_start_pos = lower_bound
1192
+ # Validate bounds
1193
+ if (
1194
+ larger_seq_start_pos < 1
1195
+ or larger_subseq_end_pos > larger_length
1196
+ ):
1197
+ print(
1198
+ f"Error: region {region} is out of bounds for {larger_seq_name}. Will use entire sequence.\n"
1199
+ )
1200
+ larger_subseq_start_pos = 1
1201
+ larger_subseq_end_pos = larger_length
1202
+ larger_seq_name = sequences[i][0]
1203
+ break
1204
+ print(
1205
+ f"Using region {larger_seq_name}:{larger_subseq_start_pos}-{larger_subseq_end_pos}\n"
1206
+ )
1207
+ # Change sequence length, and use a subsequence instead.
1208
+ larger_length = (
1209
+ larger_subseq_end_pos
1210
+ - larger_subseq_start_pos
1211
+ + 1
1212
+ - args.kmer
1213
+ )
1214
+ larger_seq_range = (
1215
+ larger_seq_name,
1216
+ larger_subseq_start_pos,
1217
+ larger_subseq_end_pos,
1218
+ )
1219
+ larger_seq_name = f"{larger_seq_name}:{larger_subseq_start_pos}-{larger_subseq_end_pos}"
1220
+
1221
+ if chrom == smaller_seq_name:
1222
+ smaller_subseq_start_pos = lower_bound
1223
+ smaller_subseq_end_pos = upper_bound
1224
+ smaller_seq_start_pos = lower_bound
1225
+ # Validate bounds
1226
+ if (
1227
+ smaller_seq_start_pos < 1
1228
+ or smaller_subseq_end_pos > smaller_length
1229
+ ):
1230
+ print(
1231
+ f"Error: region {region} is out of bounds for {smaller_seq_name}. Will use entire sequence.\n"
1232
+ )
1233
+ smaller_subseq_start_pos = 1
1234
+ smaller_subseq_end_pos = smaller_length
1235
+ smaller_seq_name = sequences[j][0]
1236
+ break
1237
+ print(
1238
+ f"Using region {smaller_seq_name}:{smaller_subseq_start_pos}-{smaller_subseq_end_pos}\n"
1239
+ )
1240
+ # Change sequence length, and use a subsequence instead.
1241
+ smaller_length = (
1242
+ smaller_subseq_end_pos
1243
+ - smaller_subseq_start_pos
1244
+ + 1
1245
+ - args.kmer
1246
+ )
1247
+ smaller_seq_range = (
1248
+ smaller_seq_name,
1249
+ smaller_subseq_start_pos,
1250
+ smaller_subseq_end_pos,
1251
+ )
1252
+ smaller_seq_name = f"{smaller_seq_name}:{smaller_subseq_start_pos}-{smaller_subseq_end_pos}"
1253
+ # This is wrong. Might be fine to leave alone
1254
+ if not larger_subseq_end_pos or not larger_subseq_start_pos:
1255
+ print(
1256
+ f"Error: region {args.region} not found in {seq_name}. Will use entire sequence.\n"
1257
+ )
1258
+ seq_range = None
1259
+ except Exception as e:
1260
+ print(
1261
+ f"Error obtaining region for {seq_name}. Will use entire sequence: {e}\n"
1262
+ )
1263
+
1101
1264
  win = args.window
1102
1265
  res = args.resolution
1103
1266
  if args.window:
@@ -1117,7 +1280,6 @@ def main():
1117
1280
  f"Computing pairwise identity matrix for {larger_seq_name} and {smaller_seq_name}... \n"
1118
1281
  )
1119
1282
  # TODO: Logging here
1120
- # print(f"\tSparsity value s: {seq_sparsity}\n")
1121
1283
  print(
1122
1284
  f"\tSequence length {larger_seq_name}: {larger_length + args.kmer - 1}\n"
1123
1285
  )
@@ -1128,19 +1290,52 @@ def main():
1128
1290
  print(f"\tModimizer sketch size: {expectation}\n")
1129
1291
  print(f"\tPlot Resolution r: {res}\n")
1130
1292
 
1131
- pair_mat = createPairwiseMatrix(
1132
- smaller_length,
1133
- larger_length,
1134
- smaller_seq,
1135
- larger_seq,
1136
- win,
1137
- seq_sparsity,
1138
- args.delta,
1139
- args.kmer,
1140
- args.identity,
1141
- args.ambiguous,
1142
- expectation,
1143
- )
1293
+ if args.region and (larger_seq_range or smaller_seq_range):
1294
+ if larger_seq_range:
1295
+ larger_subseq = larger_seq[
1296
+ larger_subseq_start_pos : (
1297
+ larger_subseq_end_pos - args.kmer + 1
1298
+ )
1299
+ ]
1300
+ else:
1301
+ larger_subseq = larger_seq
1302
+
1303
+ if smaller_seq_range:
1304
+ smaller_subseq = smaller_seq[
1305
+ smaller_subseq_start_pos : (
1306
+ smaller_subseq_end_pos - args.kmer + 1
1307
+ )
1308
+ ]
1309
+ else:
1310
+ smaller_subseq = smaller_seq
1311
+
1312
+ pair_mat = createPairwiseMatrix(
1313
+ smaller_length,
1314
+ larger_length,
1315
+ smaller_subseq,
1316
+ larger_subseq,
1317
+ win,
1318
+ seq_sparsity,
1319
+ args.delta,
1320
+ args.kmer,
1321
+ args.identity,
1322
+ args.ambiguous,
1323
+ expectation,
1324
+ )
1325
+ else:
1326
+ pair_mat = createPairwiseMatrix(
1327
+ smaller_length,
1328
+ larger_length,
1329
+ smaller_seq,
1330
+ larger_seq,
1331
+ win,
1332
+ seq_sparsity,
1333
+ args.delta,
1334
+ args.kmer,
1335
+ args.identity,
1336
+ args.ambiguous,
1337
+ expectation,
1338
+ )
1144
1339
  # Throw error if the matrix is empty
1145
1340
  if np.all(pair_mat == 0) and (not (args.grid or args.grid_only)):
1146
1341
  print(
@@ -13,24 +13,33 @@ tab_b = bytes.maketrans(b"ACTG", b"TGAC")
13
13
 
14
14
 
15
15
  def extractRegion(seq_name):
16
- """Check if seq_name contains a region and extract the bounds."""
17
- # Define the regular expression to match the format "chrY:50-3000"
18
- region_pattern = r"([a-zA-Z0-9]+):(\d+)-(\d+)"
16
+ """Extract chromosome and region from seq_name.
17
+
18
+ Supports:
19
+ - Standard format: "chrY:50-3000"
20
+ - Extended format: "HG002_chr13_MATERNAL:1-4000000:1000000-3000000"
21
+ (keeps the last range).
22
+ """
23
+ # Match chromosome + one or more ranges separated by colons
24
+ region_pattern = r"^([a-zA-Z0-9_]+)(?::(\d+-\d+))+"
19
25
 
20
26
  match = re.match(region_pattern, seq_name)
21
27
  if match:
22
- # Extract chromosome, lower bound, and upper bound
23
28
  chrom = match.group(1)
24
- lower_bound = int(match.group(2))
25
- upper_bound = int(match.group(3))
29
+ # Get all ranges (everything after the chrom)
30
+ ranges = re.findall(r"(\d+)-(\d+)", seq_name)
31
+ if ranges:
32
+ # Take the last range
33
+ lower_bound, upper_bound = map(int, ranges[-1])
34
+ return chrom, lower_bound, upper_bound
26
35
 
27
- return chrom, lower_bound, upper_bound
28
- else:
29
- # No region found
30
- return None
36
+ # No match
37
+ return None
31
38
 
32
39
 
33
- def generateKmersFromFasta(seq: Sequence[str], k: int, quiet: bool) -> Iterable[int]:
40
+ def generateKmersFromFasta(
41
+ seq: Sequence[str], k: int, quiet: bool, fw_only: bool
42
+ ) -> Iterable[int]:
34
43
  n = len(seq)
35
44
  if not quiet:
36
45
  progress_thresholds = round(n / 77)
@@ -53,11 +62,12 @@ def generateKmersFromFasta(seq: Sequence[str], k: int, quiet: bool) -> Iterable[
53
62
  # Remove case sensitivity
54
63
  kmer = seq[i : i + k].upper()
55
64
  fh = mmh3.hash(kmer)
56
-
57
- # Calculate reverse complement hash directly without the need for translation
58
- rc = mmh3.hash(kmer[::-1].translate(tab_b))
59
-
60
- yield fh if fh < rc else rc
65
+ if fw_only:
66
+ yield fh
67
+ else:
68
+ # Calculate reverse complement hash directly without the need for translation
69
+ rc = mmh3.hash(kmer[::-1].translate(tab_b))
70
+ yield fh if fh < rc else rc
61
71
 
62
72
 
63
73
  def isValidFasta(file_path):
@@ -144,7 +154,9 @@ def printProgressBar(
144
154
  print()
145
155
 
146
156
 
147
- def readKmersFromFile(filename: str, ksize: int, quiet: bool) -> List[List[int]]:
157
+ def readKmersFromFile(
158
+ filename: str, ksize: int, quiet: bool, fw_only: bool
159
+ ) -> List[List[int]]:
148
160
  """
149
161
  Given a filename and an integer k, returns a list of all k-mers found in the sequences in the file.
150
162
  """
@@ -154,7 +166,9 @@ def readKmersFromFile(filename: str, ksize: int, quiet: bool) -> List[List[int]]
154
166
  for seq_id in seq.references:
155
167
  print(f"Retrieving k-mers from {seq_id}.... \n")
156
168
  kmers_for_seq = []
157
- for kmer_hash in generateKmersFromFasta(seq.fetch(seq_id), ksize, quiet):
169
+ for kmer_hash in generateKmersFromFasta(
170
+ seq.fetch(seq_id), ksize, quiet, fw_only
171
+ ):
158
172
  kmers_for_seq.append(kmer_hash)
159
173
  all_kmers.append(kmers_for_seq)
160
174
  print(f"\n{seq_id} k-mers retrieved! \n")
@@ -1980,6 +1980,11 @@ def create_plots(
1980
1980
  )
1981
1981
  if os.path.exists(f"{anno_prefix}.svg"):
1982
1982
  os.remove(f"{anno_prefix}.svg")
1983
+ cairosvg.svg2png(
1984
+ url=f"{tri_prefix}_ANNOTATED.svg",
1985
+ write_to=f"{tri_prefix}_ANNOTATED.png",
1986
+ dpi=dpi,
1987
+ )
1983
1988
  try:
1984
1989
  if vector_format != "svg":
1985
1990
  if vector_format == "pdf":
File without changes
File without changes